diff --git a/src/headless.ts b/src/headless.ts index 6300d4e..8af5bdd 100644 --- a/src/headless.ts +++ b/src/headless.ts @@ -41,9 +41,9 @@ import { import { SYSTEM_REMINDER_CLOSE, SYSTEM_REMINDER_OPEN } from "./constants"; import { settingsManager } from "./settings-manager"; import { + type ExternalToolDefinition, registerExternalTools, setExternalToolExecutor, - type ExternalToolDefinition, } from "./tools/manager"; import type { AutoApprovalMessage, @@ -2108,11 +2108,13 @@ async function runBidirectionalMode( console.log(JSON.stringify(interruptResponse)); } else if (subtype === "register_external_tools") { // Register external tools from SDK - const toolsRequest = message.request as { tools?: ExternalToolDefinition[] }; + const toolsRequest = message.request as { + tools?: ExternalToolDefinition[]; + }; const tools = toolsRequest.tools ?? []; - + registerExternalTools(tools); - + // Set up the external tool executor to send requests back to SDK setExternalToolExecutor(async (toolCallId, toolName, input) => { // Send execute_external_tool request to SDK @@ -2127,15 +2129,18 @@ async function runBidirectionalMode( } as unknown as CanUseToolControlRequest, // Type cast for compatibility }; console.log(JSON.stringify(execRequest)); - + // Wait for external_tool_result response while (true) { const line = await getNextLine(); if (line === null) { - return { content: [{ type: "text", text: "stdin closed" }], isError: true }; + return { + content: [{ type: "text", text: "stdin closed" }], + isError: true, + }; } if (!line.trim()) continue; - + try { const msg = JSON.parse(line); if ( @@ -2153,7 +2158,7 @@ async function runBidirectionalMode( } } }); - + const registerResponse: ControlResponse = { type: "control_response", response: { diff --git a/src/tools/manager.ts b/src/tools/manager.ts index 8f0a627..7ea9172 100644 --- a/src/tools/manager.ts +++ b/src/tools/manager.ts @@ -382,7 +382,12 @@ export type ExternalToolExecutor = ( toolName: string, input: Record, ) => Promise<{ - content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>; + content: Array<{ + type: string; + text?: string; + data?: string; + mimeType?: string; + }>; isError: boolean; }>; @@ -438,7 +443,9 @@ export function isExternalTool(name: string): boolean { /** * Get external tool definition */ -export function getExternalToolDefinition(name: string): ExternalToolDefinition | undefined { +export function getExternalToolDefinition( + name: string, +): ExternalToolDefinition | undefined { return getExternalToolsRegistry().get(name); } @@ -461,7 +468,9 @@ export async function executeExternalTool( toolName: string, input: Record, ): Promise { - const executor = (globalThis as GlobalWithExternalTools)[EXTERNAL_EXECUTOR_KEY]; + const executor = (globalThis as GlobalWithExternalTools)[ + EXTERNAL_EXECUTOR_KEY + ]; if (!executor) { return { toolReturn: `External tool executor not set for tool: ${toolName}`, @@ -471,13 +480,13 @@ export async function executeExternalTool( try { const result = await executor(toolCallId, toolName, input); - + // Convert external tool result to ToolExecutionResult format const textContent = result.content .filter((c) => c.type === "text" && c.text) .map((c) => c.text) .join("\n"); - + return { toolReturn: textContent || JSON.stringify(result.content), status: result.isError ? "error" : "success", @@ -498,14 +507,16 @@ export async function executeExternalTool( */ export function getClientToolsFromRegistry(): ClientTool[] { // Get built-in tools - const builtInTools = Array.from(toolRegistry.entries()).map(([name, tool]) => { - const serverName = getServerToolName(name); - return { - name: serverName, - description: tool.schema.description, - parameters: tool.schema.input_schema, - }; - }); + const builtInTools = Array.from(toolRegistry.entries()).map( + ([name, tool]) => { + const serverName = getServerToolName(name); + return { + name: serverName, + description: tool.schema.description, + parameters: tool.schema.input_schema, + }; + }, + ); // Add external tools const externalTools = getExternalToolsAsClientTools(); diff --git a/src/types/protocol.ts b/src/types/protocol.ts index b217f8b..9015e1f 100644 --- a/src/types/protocol.ts +++ b/src/types/protocol.ts @@ -307,8 +307,8 @@ export interface ExecuteExternalToolRequest { input: Record; } -export type CliToSdkControlRequest = - | CanUseToolControlRequest +export type CliToSdkControlRequest = + | CanUseToolControlRequest | ExecuteExternalToolRequest; // Combined for parsing @@ -357,7 +357,7 @@ export type CanUseToolResponse = export interface ExternalToolResultContent { type: "text" | "image"; text?: string; - data?: string; // base64 for images + data?: string; // base64 for images mimeType?: string; }