diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 392e71b8..cfc02c5b 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Breaking Changes + +- `pi.getAllTools()` now returns `ToolInfo[]` (with `name` and `description`) instead of `string[]`. Extensions that only need names can use `.map(t => t.name)`. ([#648](https://github.com/badlogic/pi-mono/pull/648) by [@carsonfarmer](https://github.com/carsonfarmer)) + ### Added - Session naming: `/name ` command sets a display name shown in the session selector instead of the first message. Useful for distinguishing forked sessions. Extensions can use `pi.setSessionName()` and `pi.getSessionName()`. ([#650](https://github.com/badlogic/pi-mono/pull/650) by [@scutifer](https://github.com/scutifer)) diff --git a/packages/coding-agent/docs/extensions.md b/packages/coding-agent/docs/extensions.md index 7bad92cc..e7a13e36 100644 --- a/packages/coding-agent/docs/extensions.md +++ b/packages/coding-agent/docs/extensions.md @@ -887,6 +887,8 @@ Manage active tools. ```typescript const active = pi.getActiveTools(); // ["read", "bash", "edit", "write"] +const all = pi.getAllTools(); // [{ name: "read", description: "Read file contents..." }, ...] +const names = all.map(t => t.name); // Just names if needed pi.setActiveTools(["read", "bash"]); // Switch to read-only ``` diff --git a/packages/coding-agent/examples/extensions/preset.ts b/packages/coding-agent/examples/extensions/preset.ts index c6964cc6..3cc2a17b 100644 --- a/packages/coding-agent/examples/extensions/preset.ts +++ b/packages/coding-agent/examples/extensions/preset.ts @@ -133,9 +133,9 @@ export default function presetExtension(pi: ExtensionAPI) { // Apply tools if specified if (preset.tools && preset.tools.length > 0) { - const allTools = pi.getAllTools(); - const validTools = preset.tools.filter((t) => allTools.includes(t)); - const invalidTools = preset.tools.filter((t) => !allTools.includes(t)); + const allToolNames = pi.getAllTools().map((t) => t.name); + const validTools = preset.tools.filter((t) => allToolNames.includes(t)); + const invalidTools = preset.tools.filter((t) => !allToolNames.includes(t)); if (invalidTools.length > 0) { ctx.ui.notify(`Preset "${name}": Unknown tools: ${invalidTools.join(", ")}`, "warning"); diff --git a/packages/coding-agent/examples/extensions/tools.ts b/packages/coding-agent/examples/extensions/tools.ts index 7ba83dc5..e10fb96d 100644 --- a/packages/coding-agent/examples/extensions/tools.ts +++ b/packages/coding-agent/examples/extensions/tools.ts @@ -9,7 +9,7 @@ * 2. Use /tools to open the tool selector */ -import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent"; +import type { ExtensionAPI, ExtensionContext, ToolInfo } from "@mariozechner/pi-coding-agent"; import { getSettingsListTheme } from "@mariozechner/pi-coding-agent"; import { Container, type SettingItem, SettingsList } from "@mariozechner/pi-tui"; @@ -21,7 +21,7 @@ interface ToolsState { export default function toolsExtension(pi: ExtensionAPI) { // Track enabled tools let enabledTools: Set = new Set(); - let allTools: string[] = []; + let allTools: ToolInfo[] = []; // Persist current state function persistState() { @@ -54,7 +54,8 @@ export default function toolsExtension(pi: ExtensionAPI) { if (savedTools) { // Restore saved tool selection (filter to only tools that still exist) - enabledTools = new Set(savedTools.filter((t: string) => allTools.includes(t))); + 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 @@ -72,9 +73,9 @@ export default function toolsExtension(pi: ExtensionAPI) { await ctx.ui.custom((tui, theme, _kb, done) => { // Build settings items for each tool const items: SettingItem[] = allTools.map((tool) => ({ - id: tool, - label: tool, - currentValue: enabledTools.has(tool) ? "enabled" : "disabled", + id: tool.name, + label: tool.name, + currentValue: enabledTools.has(tool.name) ? "enabled" : "disabled", values: ["enabled", "disabled"], })); diff --git a/packages/coding-agent/src/core/agent-session.ts b/packages/coding-agent/src/core/agent-session.ts index d01d917f..d6003e65 100644 --- a/packages/coding-agent/src/core/agent-session.ts +++ b/packages/coding-agent/src/core/agent-session.ts @@ -459,10 +459,13 @@ export class AgentSession { } /** - * Get all configured tool names (built-in via --tools or default, plus custom tools). + * Get all configured tools with name and description. */ - getAllToolNames(): string[] { - return Array.from(this._toolRegistry.keys()); + getAllTools(): Array<{ name: string; description: string }> { + return Array.from(this._toolRegistry.values()).map((t) => ({ + name: t.name, + description: t.description, + })); } /** diff --git a/packages/coding-agent/src/core/extensions/index.ts b/packages/coding-agent/src/core/extensions/index.ts index 4b320a9a..0929c99c 100644 --- a/packages/coding-agent/src/core/extensions/index.ts +++ b/packages/coding-agent/src/core/extensions/index.ts @@ -99,6 +99,7 @@ export type { ToolCallEventResult, // Tools ToolDefinition, + ToolInfo, ToolRenderResultOptions, ToolResultEvent, ToolResultEventResult, diff --git a/packages/coding-agent/src/core/extensions/loader.ts b/packages/coding-agent/src/core/extensions/loader.ts index 1e91f553..2ff07ceb 100644 --- a/packages/coding-agent/src/core/extensions/loader.ts +++ b/packages/coding-agent/src/core/extensions/loader.ts @@ -187,7 +187,7 @@ function createExtensionAPI( return runtime.getActiveTools(); }, - getAllTools(): string[] { + getAllTools() { return runtime.getAllTools(); }, diff --git a/packages/coding-agent/src/core/extensions/types.ts b/packages/coding-agent/src/core/extensions/types.ts index 6ae880fd..a17e4699 100644 --- a/packages/coding-agent/src/core/extensions/types.ts +++ b/packages/coding-agent/src/core/extensions/types.ts @@ -743,8 +743,8 @@ export interface ExtensionAPI { /** Get the list of currently active tool names. */ getActiveTools(): string[]; - /** Get all configured tools (built-in + extension tools). */ - getAllTools(): string[]; + /** Get all configured tools with name and description. */ + getAllTools(): ToolInfo[]; /** Set the active tools by name. */ setActiveTools(toolNames: string[]): void; @@ -813,7 +813,10 @@ export type GetSessionNameHandler = () => string | undefined; export type GetActiveToolsHandler = () => string[]; -export type GetAllToolsHandler = () => string[]; +/** Tool info with name and description */ +export type ToolInfo = Pick; + +export type GetAllToolsHandler = () => ToolInfo[]; export type SetActiveToolsHandler = (toolNames: string[]) => void; diff --git a/packages/coding-agent/src/index.ts b/packages/coding-agent/src/index.ts index 92de873d..4335da4f 100644 --- a/packages/coding-agent/src/index.ts +++ b/packages/coding-agent/src/index.ts @@ -79,6 +79,7 @@ export type { SessionTreeEvent, ToolCallEvent, ToolDefinition, + ToolInfo, ToolRenderResultOptions, ToolResultEvent, TurnEndEvent, diff --git a/packages/coding-agent/src/modes/interactive/interactive-mode.ts b/packages/coding-agent/src/modes/interactive/interactive-mode.ts index 3c470377..5f84555b 100644 --- a/packages/coding-agent/src/modes/interactive/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive/interactive-mode.ts @@ -685,7 +685,7 @@ export class InteractiveMode { return this.sessionManager.getSessionName(); }, getActiveTools: () => this.session.getActiveToolNames(), - getAllTools: () => this.session.getAllToolNames(), + getAllTools: () => this.session.getAllTools(), setActiveTools: (toolNames) => this.session.setActiveToolsByName(toolNames), setModel: async (model) => { const key = await this.session.modelRegistry.getApiKey(model); diff --git a/packages/coding-agent/src/modes/print-mode.ts b/packages/coding-agent/src/modes/print-mode.ts index 460c5ebb..c03f60f0 100644 --- a/packages/coding-agent/src/modes/print-mode.ts +++ b/packages/coding-agent/src/modes/print-mode.ts @@ -55,7 +55,7 @@ export async function runPrintMode(session: AgentSession, options: PrintModeOpti return session.sessionManager.getSessionName(); }, getActiveTools: () => session.getActiveToolNames(), - getAllTools: () => session.getAllToolNames(), + getAllTools: () => session.getAllTools(), setActiveTools: (toolNames: string[]) => session.setActiveToolsByName(toolNames), setModel: async (model) => { const key = await session.modelRegistry.getApiKey(model); diff --git a/packages/coding-agent/src/modes/rpc/rpc-mode.ts b/packages/coding-agent/src/modes/rpc/rpc-mode.ts index b4487bbf..6741631d 100644 --- a/packages/coding-agent/src/modes/rpc/rpc-mode.ts +++ b/packages/coding-agent/src/modes/rpc/rpc-mode.ts @@ -274,7 +274,7 @@ export async function runRpcMode(session: AgentSession): Promise { return session.sessionManager.getSessionName(); }, getActiveTools: () => session.getActiveToolNames(), - getAllTools: () => session.getAllToolNames(), + getAllTools: () => session.getAllTools(), setActiveTools: (toolNames: string[]) => session.setActiveToolsByName(toolNames), setModel: async (model) => { const key = await session.modelRegistry.getApiKey(model);