fix: normalize tool execute args

This commit is contained in:
Peter Steinberger
2026-02-02 02:41:21 -08:00
parent 9ae1b732ef
commit bcb0ed0866

View File

@@ -13,10 +13,30 @@ import { jsonResult } from "./tools/common.js";
// oxlint-disable-next-line typescript/no-explicit-any
type AnyAgentTool = AgentTool<any, unknown>;
type ToolExecuteArgs = Parameters<ToolDefinition["execute"]>;
type ToolExecuteArgsLegacy = [
string,
unknown,
AbortSignal | undefined,
AgentToolUpdateCallback<unknown> | undefined,
unknown,
];
type ToolExecuteArgsAny = ToolExecuteArgs | ToolExecuteArgsLegacy;
function isPlainObject(value: unknown): value is Record<string, unknown> {
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<unknown> | 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<unknown> | undefined,
_ctx,
signal?: AbortSignal,
): Promise<AgentToolResult<unknown>> => {
execute: async (...args: ToolExecuteArgs): Promise<AgentToolResult<unknown>> => {
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<unknown> | undefined,
_ctx,
_signal?: AbortSignal,
): Promise<AgentToolResult<unknown>> => {
execute: async (...args: ToolExecuteArgs): Promise<AgentToolResult<unknown>> => {
const { toolCallId, params } = splitToolExecuteArgs(args);
const outcome = await runBeforeToolCallHook({
toolName: func.name,
params,