Something went wrong. Try again.
fork of prime agent with changes i want but are not upstreamable probqbly (and some fixes)
Something went wrong. Try again.
3.8 kB · 141 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142/** * Tools Extension * * Provides a /tools command to enable/disable tools interactively. * Tool selection persists across session reloads and respects branch navigation. * * Usage: * 1. Copy this file to ~/.pi/agent/extensions/ or your project's .pi/extensions/ * 2. Use /tools to open the tool selector */
import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@earendil-works/pi-coding-agent";import { getSettingsListTheme } from "@earendil-works/pi-coding-agent";import { Container, type SettingItem, SettingsList } from "@earendil-works/pi-tui";
// State persisted to sessioninterface ToolsState { enabledTools: string[];}
export default function toolsExtension(pi: ExtensionAPI) { // Track enabled tools let enabledTools: Set<string> = new Set(); let allTools: ToolInfo[] = [];
// Persist current state function persistState() { pi.appendEntry<ToolsState>("tools-config", { enabledTools: Array.from(enabledTools), }); }
// Apply current tool selection function applyTools() { pi.setActiveTools(Array.from(enabledTools)); }
// Find the last tools-config entry in the current branch function restoreFromBranch(ctx: ExtensionContext) { allTools = pi.getAllTools();
// Get entries in current branch only const branchEntries = ctx.sessionManager.getBranch(); let savedTools: string[] | undefined;
for (const entry of branchEntries) { if (entry.type === "custom" && entry.customType === "tools-config") { const data = entry.data as ToolsState | undefined; if (data?.enabledTools) { savedTools = data.enabledTools; } } }
if (savedTools) { // Restore saved tool selection (filter to only tools that still exist) const allToolNames = allTools.map((t) => t.name); enabledTools = new Set(savedTools.filter((t: string) => allToolNames.includes(t))); applyTools(); } else { // No saved state - sync with currently active tools enabledTools = new Set(pi.getActiveTools()); } }
// Register /tools command pi.registerCommand("tools", { description: "Enable/disable tools", handler: async (_args, ctx) => { // Refresh tool list allTools = pi.getAllTools();
await ctx.ui.custom((tui, theme, _kb, done) => { // Build settings items for each tool const items: SettingItem[] = allTools.map((tool) => ({ id: tool.name, label: tool.name, currentValue: enabledTools.has(tool.name) ? "enabled" : "disabled", values: ["enabled", "disabled"], }));
const container = new Container(); container.addChild( new (class { render(_width: number) { return [theme.fg("accent", theme.bold("Tool Configuration")), ""]; } invalidate() {} })(), );
const settingsList = new SettingsList( items, Math.min(items.length + 2, 15), getSettingsListTheme(), (id, newValue) => { // Update enabled state and apply immediately if (newValue === "enabled") { enabledTools.add(id); } else { enabledTools.delete(id); } applyTools(); persistState(); }, () => { // Close dialog done(undefined); }, );
container.addChild(settingsList);
const component = { render(width: number) { return container.render(width); }, invalidate() { container.invalidate(); }, handleInput(data: string) { settingsList.handleInput?.(data); tui.requestRender(); }, };
return component; }); }, });
// Restore state on session start pi.on("session_start", async (_event, ctx) => { restoreFromBranch(ctx); });
// Restore state when navigating the session tree pi.on("session_tree", async (_event, ctx) => { restoreFromBranch(ctx); });}