diff --git a/src/agents/pi-tool-definition-adapter.ts b/src/agents/pi-tool-definition-adapter.ts index eb867fa07..649f99f87 100644 --- a/src/agents/pi-tool-definition-adapter.ts +++ b/src/agents/pi-tool-definition-adapter.ts @@ -13,10 +13,30 @@ import { jsonResult } from "./tools/common.js"; // oxlint-disable-next-line typescript/no-explicit-any type AnyAgentTool = AgentTool; +type ToolExecuteArgs = Parameters; +type ToolExecuteArgsLegacy = [ + string, + unknown, + AbortSignal | undefined, + AgentToolUpdateCallback | undefined, + unknown, +]; +type ToolExecuteArgsAny = ToolExecuteArgs | ToolExecuteArgsLegacy; + function isPlainObject(value: unknown): value is Record { return typeof value === "object" && value !== null && !Array.isArray(value); } +function isAbortSignal(value: unknown): value is AbortSignal { + return typeof value === "object" && value !== null && "aborted" in value; +} + +function isLegacyToolExecuteArgs(args: ToolExecuteArgsAny): args is ToolExecuteArgsLegacy { + const third = args[2]; + const fourth = args[3]; + return isAbortSignal(third) || typeof fourth === "function"; +} + function describeToolExecutionError(err: unknown): { message: string; stack?: string; @@ -28,6 +48,30 @@ function describeToolExecutionError(err: unknown): { return { message: String(err) }; } +function splitToolExecuteArgs(args: ToolExecuteArgsAny): { + toolCallId: string; + params: unknown; + onUpdate: AgentToolUpdateCallback | undefined; + signal: AbortSignal | undefined; +} { + if (isLegacyToolExecuteArgs(args)) { + const [toolCallId, params, signal, onUpdate] = args; + return { + toolCallId, + params, + onUpdate, + signal, + }; + } + const [toolCallId, params, onUpdate, _ctx, signal] = args; + return { + toolCallId, + params, + onUpdate, + signal, + }; +} + export function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] { return tools.map((tool) => { const name = tool.name || "tool"; @@ -37,13 +81,8 @@ export function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] { label: tool.label ?? name, description: tool.description ?? "", parameters: tool.parameters, - execute: async ( - toolCallId, - params, - onUpdate: AgentToolUpdateCallback | undefined, - _ctx, - signal?: AbortSignal, - ): Promise> => { + execute: async (...args: ToolExecuteArgs): Promise> => { + const { toolCallId, params, onUpdate, signal } = splitToolExecuteArgs(args); try { return await tool.execute(toolCallId, params, signal, onUpdate); } catch (err) { @@ -88,13 +127,8 @@ export function toClientToolDefinitions( description: func.description ?? "", // oxlint-disable-next-line typescript/no-explicit-any parameters: func.parameters as any, - execute: async ( - toolCallId, - params, - _onUpdate: AgentToolUpdateCallback | undefined, - _ctx, - _signal?: AbortSignal, - ): Promise> => { + execute: async (...args: ToolExecuteArgs): Promise> => { + const { toolCallId, params } = splitToolExecuteArgs(args); const outcome = await runBeforeToolCallHook({ toolName: func.name, params,