@caupulican/pi-agent-core 0.81.21 → 0.81.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +8 -1
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent.d.ts +0 -2
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +0 -3
- package/dist/agent.js.map +1 -1
- package/dist/session/session-manager.d.ts +6 -0
- package/dist/session/session-manager.d.ts.map +1 -1
- package/dist/session/session-manager.js +35 -0
- package/dist/session/session-manager.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/dist/agent-loop.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGN,WAAW,EAQX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAIZ,QAAQ,EAER,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAuBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CA8BzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tgetToolExecutionErrorGuidance,\n\tstreamSimple,\n\ttype ToolArgumentExecutionOutcome,\n\tToolArgumentValidationError,\n\ttype ToolArgumentValidationTelemetryEvent,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@caupulican/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n\tToolCallRepairInfo,\n} from \"./types.ts\";\nimport { DEFAULT_MAX_STALL_TURNS } from \"./types.ts\";\nimport { createEmptyUsage } from \"./usage.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createLoopFailureMessage(error: unknown, config: AgentLoopConfig, aborted: boolean): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [{ type: \"text\", text: \"\" }],\n\t\tapi: config.model.api,\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: aborted ? \"aborted\" : \"error\",\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * How many `stallLimit`-length periods the runaway-loop window spans. A window of `stallLimit * P`\n * turns lets the count-based detector catch oscillating cycles of period up to `P` (each signature in a\n * period-k cycle recurs ~window/k times), not just back-to-back repeats. Beyond this the cycle is loose\n * enough that it's indistinguishable from legitimate varied work, so we don't chase it.\n */\nconst STALL_WINDOW_PERIODS = 4;\n\n/**\n * Normalize a tool-call batch into a stable signature for runaway-loop detection. Volatile argument\n * tokens — epoch/timestamps, UUIDs, long hashes/nonces — are masked so a model retrying the SAME call\n * with a fresh timestamp/id each turn still collapses to one signature and is detected (bug #28). Only\n * clearly-volatile patterns are masked: short numbers (`file2.ts`, `line 42`, `count: 3`) are kept so\n * genuinely-distinct calls (reading numbered files, different line ranges) are NOT falsely merged.\n */\nfunction normalizeToolSignature(pairs: Array<[string, unknown]>): string {\n\treturn JSON.stringify(pairs)\n\t\t.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, \"<uuid>\")\n\t\t.replace(/\\d{4}-\\d{2}-\\d{2}[tT][0-9:.]+(?:z|[+-]\\d{2}:?\\d{2})?/gi, \"<ts>\")\n\t\t.replace(/\\b[0-9a-f]{16,}\\b/gi, \"<hex>\")\n\t\t.replace(/\\d{10,}/g, \"<num>\");\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Runaway-loop backstop state: a sliding window of recent NORMALIZED tool-call signatures. A model\n\t// wedged repeating the same action makes no progress but keeps spending tokens; if one signature\n\t// recurs `stallLimit` times within the window we stop gracefully. Signatures are normalized so\n\t// volatile args (timestamps/UUIDs/nonces that change every call) can't disguise an otherwise-\n\t// identical call (bug #28). The window spans `stallLimit * STALL_WINDOW_PERIODS` turns so periodic\n\t// oscillation is caught too, not just back-to-back repeats: a cycle of period P repeats each\n\t// signature ~window/P times, so any P up to STALL_WINDOW_PERIODS reaches the threshold before the\n\t// window slides past it. Counts only turns that issued tool calls, so varied/long work never trips\n\t// it. `0` disables.\n\tconst stallLimit = config.maxStallTurns ?? DEFAULT_MAX_STALL_TURNS;\n\tconst stallWindow: string[] = [];\n\tconst validationFailureTracker: ToolValidationFailureTracker = { repeats: 0 };\n\tconst repairTeachTracker: ToolRepairTeachTracker = new Map();\n\tconst executionFailureTracker: ToolExecutionFailureTracker = { repeats: 0 };\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(\n\t\t\t\t\tcurrentContext,\n\t\t\t\t\tmessage,\n\t\t\t\t\tconfig,\n\t\t\t\t\tvalidationFailureTracker,\n\t\t\t\t\trepairTeachTracker,\n\t\t\t\t\texecutionFailureTracker,\n\t\t\t\t\tsignal,\n\t\t\t\t\temit,\n\t\t\t\t);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\t// Runaway-loop backstop (cost guard): detect a model stuck repeating one action.\n\t\t\tif (stallLimit > 0 && toolCalls.length > 0) {\n\t\t\t\tconst signature = normalizeToolSignature(toolCalls.map((c) => [c.name, c.arguments ?? null]));\n\t\t\t\tstallWindow.push(signature);\n\t\t\t\tif (stallWindow.length > stallLimit * STALL_WINDOW_PERIODS) stallWindow.shift();\n\t\t\t\tconst repeats = stallWindow.reduce((n, s) => (s === signature ? n + 1 : n), 0);\n\t\t\t\tif (repeats >= stallLimit) {\n\t\t\t\t\tconfig.onRunawayStop?.({ signature, repeats });\n\t\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCalls,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\trepairTeachTracker,\n\t\t\texecutionFailureTracker,\n\t\t\tsignal,\n\t\t\temit,\n\t\t);\n\t}\n\treturn executeToolCallsParallel(\n\t\tcurrentContext,\n\t\tassistantMessage,\n\t\ttoolCalls,\n\t\tconfig,\n\t\tvalidationFailureTracker,\n\t\trepairTeachTracker,\n\t\texecutionFailureTracker,\n\t\tsignal,\n\t\temit,\n\t);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\terrorClass?: string;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\ntype ToolValidationFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\tescalatedSignature?: string;\n};\n\ntype ToolRepairTeachTracker = Map<string, number>;\n\ntype ToolExecutionFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\ttaughtSignature?: string;\n};\n\nconst DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD = 3;\nconst TOOL_REPAIR_TEACH_EVERY = 5;\nconst TOOL_EXECUTION_FAILURE_TEACH_AT = 2;\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nfunction createValidationBounceTelemetry(\n\tconfig: AgentLoopConfig,\n\ttoolCall: AgentToolCall,\n\terrorKeyword: string,\n): ToolArgumentValidationTelemetryEvent {\n\treturn {\n\t\toutcome: \"bounced\",\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\ttool: toolCall.name,\n\t\tsource: toolCall.source,\n\t\tfailureModes: [\"other\"],\n\t\trepairsApplied: [],\n\t\terrorKeywords: [errorKeyword],\n\t\ttaught: \"none\",\n\t\texecutionOutcome: \"not_run\",\n\t};\n}\n\nfunction resetValidationFailureTracker(tracker: ToolValidationFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction emitToolArgumentValidationTelemetry(\n\tconfig: AgentLoopConfig,\n\tevent: ToolArgumentValidationTelemetryEvent | undefined,\n\texecutionOutcome: ToolArgumentExecutionOutcome,\n\ttaught: ToolArgumentValidationTelemetryEvent[\"taught\"],\n): void {\n\tif (!event) return;\n\tconfig.onToolArgumentValidation?.({ ...event, executionOutcome, taught });\n}\n\nfunction toolValidationEscalationThreshold(config: AgentLoopConfig): number {\n\treturn config.toolValidationEscalationThreshold ?? DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD;\n}\n\nfunction isToolArgumentValidationError(error: unknown): error is ToolArgumentValidationError {\n\treturn (\n\t\terror instanceof ToolArgumentValidationError ||\n\t\t(error instanceof Error &&\n\t\t\terror.name === \"ToolArgumentValidationError\" &&\n\t\t\ttypeof (error as { toolName?: unknown }).toolName === \"string\" &&\n\t\t\ttypeof (error as { signature?: unknown }).signature === \"string\" &&\n\t\t\ttypeof (error as { enrichment?: unknown }).enrichment === \"string\")\n\t);\n}\n\nfunction handleValidationFailure(\n\terror: ToolArgumentValidationError,\n\tconfig: AgentLoopConfig,\n\ttracker: ToolValidationFailureTracker,\n): string {\n\tif (tracker.signature === error.signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = error.signature;\n\t\ttracker.repeats = 1;\n\t\ttracker.escalatedSignature = undefined;\n\t}\n\n\tconst threshold = toolValidationEscalationThreshold(config);\n\tif (threshold <= 0 || tracker.repeats < threshold || tracker.escalatedSignature === error.signature) {\n\t\treturn error.message;\n\t}\n\n\ttracker.escalatedSignature = error.signature;\n\tconfig.onToolValidationEscalation?.({\n\t\ttool: error.toolName,\n\t\tsignature: error.signature,\n\t\trepeats: tracker.repeats,\n\t\tmodel: config.model.id,\n\t\tprovider: config.model.provider,\n\t});\n\treturn `${error.message}\\n\\nRepeated validation failure (${tracker.repeats} identical attempts). Use this full schema and example before retrying:\\n${error.enrichment}`;\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tif (toolCall.errorMessage) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(toolCall.errorMessage),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tlet validationEvent: ToolArgumentValidationTelemetryEvent | undefined;\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall, {\n\t\t\tmodel: config.model.id,\n\t\t\tprovider: config.model.provider,\n\t\t\trepairEnabled: config.toolArgumentRepairEnabled !== false,\n\t\t\ttelemetry: (event) => {\n\t\t\t\tvalidationEvent = event;\n\t\t\t},\n\t\t});\n\t\tresetValidationFailureTracker(validationFailureTracker);\n\t\tif (preparedToolCall.repairNotes) {\n\t\t\ttoolCall.repairNotes = preparedToolCall.repairNotes;\n\t\t}\n\t\tif (validatedArgs !== toolCall.arguments) {\n\t\t\ttoolCall.rawArguments ??= toolCall.arguments;\n\t\t\ttoolCall.arguments = validatedArgs;\n\t\t}\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t\tvalidationEvent,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t\tvalidationEvent,\n\t\t};\n\t} catch (error) {\n\t\tconst message = isToolArgumentValidationError(error)\n\t\t\t? handleValidationFailure(error, config, validationFailureTracker)\n\t\t\t: error instanceof Error\n\t\t\t\t? error.message\n\t\t\t\t: String(error);\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(message),\n\t\t\tisError: true,\n\t\t\tvalidationEvent,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tresult: createErrorToolResultWithGuidance(message),\n\t\t\tisError: true,\n\t\t\terrorClass: error instanceof Error ? error.name : typeof error,\n\t\t};\n\t}\n}\n\nfunction repairTeachKey(toolName: string, note: string): string {\n\tconst repairName = /^\\[harness\\] ([^:]+):/.exec(note)?.[1] ?? note;\n\treturn `${toolName}\\0${repairName}`;\n}\n\nfunction shouldEmitRepairTeachNote(toolName: string, note: string, tracker: ToolRepairTeachTracker): boolean {\n\tconst key = repairTeachKey(toolName, note);\n\tconst count = (tracker.get(key) ?? 0) + 1;\n\ttracker.set(key, count);\n\treturn count === 1 || count % TOOL_REPAIR_TEACH_EVERY === 0;\n}\n\nfunction appendRepairTeachNotes(\n\tresult: AgentToolResult<any>,\n\ttoolCall: AgentToolCall,\n\ttracker: ToolRepairTeachTracker,\n\tconfig: AgentLoopConfig,\n): { result: AgentToolResult<any>; taught: boolean } {\n\tif (config.toolArgumentTeachEnabled === false) return { result, taught: false };\n\tconst notes = (toolCall.repairNotes ?? []).filter((note) => shouldEmitRepairTeachNote(toolCall.name, note, tracker));\n\tif (notes.length === 0) return { result, taught: false };\n\treturn {\n\t\tresult: {\n\t\t\t...result,\n\t\t\tcontent: [...result.content, { type: \"text\", text: notes.join(\"\\n\") }],\n\t\t},\n\t\ttaught: true,\n\t};\n}\n\nfunction resetExecutionFailureTracker(tracker: ToolExecutionFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction executionFailureSignature(prepared: PreparedToolCall, errorClass: string): string {\n\treturn `${normalizeToolSignature([[prepared.toolCall.name, prepared.args]])}\\0${errorClass}`;\n}\n\nfunction appendExecutionFailureTeachNote(\n\tresult: AgentToolResult<any>,\n\tprepared: PreparedToolCall,\n\terrorClass: string | undefined,\n\ttracker: ToolExecutionFailureTracker,\n): AgentToolResult<any> {\n\tconst signature = executionFailureSignature(prepared, errorClass ?? \"tool-error\");\n\tif (tracker.signature === signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = signature;\n\t\ttracker.repeats = 1;\n\t}\n\tif (tracker.repeats !== TOOL_EXECUTION_FAILURE_TEACH_AT || tracker.taughtSignature === signature) return result;\n\ttracker.taughtSignature = signature;\n\treturn {\n\t\t...result,\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `[harness] This exact ${prepared.toolCall.name} call failed twice with the same ${errorClass ?? \"tool\"} error. Change the arguments or approach; do not resend the identical call.`,\n\t\t\t},\n\t\t\t...result.content,\n\t\t],\n\t};\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\tif (isError) {\n\t\tresult = appendExecutionFailureTeachNote(result, prepared, executed.errorClass, executionFailureTracker);\n\t} else {\n\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t}\n\n\tconst repaired = appendRepairTeachNotes(result, prepared.toolCall, repairTeachTracker, config);\n\temitToolArgumentValidationTelemetry(\n\t\tconfig,\n\t\tprepared.validationEvent,\n\t\tisError ? \"failed\" : \"succeeded\",\n\t\trepaired.taught ? \"note\" : \"none\",\n\t);\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult: repaired.result,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nfunction createErrorToolResultWithGuidance(message: string): AgentToolResult<any> {\n\tconst guidance = getToolExecutionErrorGuidance(message);\n\tif (!guidance) return createErrorToolResult(message);\n\treturn {\n\t\tcontent: [\n\t\t\t{ type: \"text\", text: message },\n\t\t\t{ type: \"text\", text: `[harness] ${guidance}` },\n\t\t],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionStart(toolCall: AgentToolCall, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t\trepair: getToolCallRepairInfo(toolCall),\n\t});\n}\n\nfunction getToolCallRepairInfo(toolCall: AgentToolCall): ToolCallRepairInfo | undefined {\n\tif (!toolCall.rawArguments && !toolCall.repairNotes?.length) return undefined;\n\treturn {\n\t\trepaired: true,\n\t\t...(toolCall.rawArguments ? { rawArguments: toolCall.rawArguments } : {}),\n\t\t...(toolCall.repairNotes?.length ? { notes: toolCall.repairNotes } : {}),\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t\trepair: getToolCallRepairInfo(finalized.toolCall),\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGN,WAAW,EAQX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAIZ,QAAQ,EAER,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAuBzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CA8BzC;AAED,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tgetToolExecutionErrorGuidance,\n\tstreamSimple,\n\ttype ToolArgumentExecutionOutcome,\n\tToolArgumentValidationError,\n\ttype ToolArgumentValidationTelemetryEvent,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@caupulican/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n\tToolCallRepairInfo,\n} from \"./types.ts\";\nimport { DEFAULT_MAX_STALL_TURNS } from \"./types.ts\";\nimport { createEmptyUsage } from \"./usage.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createLoopFailureMessage(error: unknown, config: AgentLoopConfig, aborted: boolean): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [{ type: \"text\", text: \"\" }],\n\t\tapi: config.model.api,\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: aborted ? \"aborted\" : \"error\",\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * How many `stallLimit`-length periods the runaway-loop window spans. A window of `stallLimit * P`\n * turns lets the count-based detector catch oscillating cycles of period up to `P` (each signature in a\n * period-k cycle recurs ~window/k times), not just back-to-back repeats. Beyond this the cycle is loose\n * enough that it's indistinguishable from legitimate varied work, so we don't chase it.\n */\nconst STALL_WINDOW_PERIODS = 4;\n\n/**\n * Normalize a tool-call batch into a stable signature for runaway-loop detection. Volatile argument\n * tokens — epoch/timestamps, UUIDs, long hashes/nonces — are masked so a model retrying the SAME call\n * with a fresh timestamp/id each turn still collapses to one signature and is detected (bug #28). Only\n * clearly-volatile patterns are masked: short numbers (`file2.ts`, `line 42`, `count: 3`) are kept so\n * genuinely-distinct calls (reading numbered files, different line ranges) are NOT falsely merged.\n */\nfunction normalizeToolSignature(pairs: Array<[string, unknown]>): string {\n\treturn JSON.stringify(pairs)\n\t\t.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, \"<uuid>\")\n\t\t.replace(/\\d{4}-\\d{2}-\\d{2}[tT][0-9:.]+(?:z|[+-]\\d{2}:?\\d{2})?/gi, \"<ts>\")\n\t\t.replace(/\\b[0-9a-f]{16,}\\b/gi, \"<hex>\")\n\t\t.replace(/\\d{10,}/g, \"<num>\");\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Runaway-loop backstop state: a sliding window of recent NORMALIZED tool-call signatures. A model\n\t// wedged repeating the same action makes no progress but keeps spending tokens; if one signature\n\t// recurs `stallLimit` times within the window we stop gracefully. Signatures are normalized so\n\t// volatile args (timestamps/UUIDs/nonces that change every call) can't disguise an otherwise-\n\t// identical call (bug #28). The window spans `stallLimit * STALL_WINDOW_PERIODS` turns so periodic\n\t// oscillation is caught too, not just back-to-back repeats: a cycle of period P repeats each\n\t// signature ~window/P times, so any P up to STALL_WINDOW_PERIODS reaches the threshold before the\n\t// window slides past it. Counts only turns that issued tool calls, so varied/long work never trips\n\t// it. `0` disables.\n\tconst stallLimit = config.maxStallTurns ?? DEFAULT_MAX_STALL_TURNS;\n\tconst stallWindow: string[] = [];\n\tconst validationFailureTracker: ToolValidationFailureTracker = { repeats: 0 };\n\tconst repairTeachTracker: ToolRepairTeachTracker = new Map();\n\tconst executionFailureTracker: ToolExecutionFailureTracker = { repeats: 0 };\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(\n\t\t\t\t\tcurrentContext,\n\t\t\t\t\tmessage,\n\t\t\t\t\tconfig,\n\t\t\t\t\tvalidationFailureTracker,\n\t\t\t\t\trepairTeachTracker,\n\t\t\t\t\texecutionFailureTracker,\n\t\t\t\t\tsignal,\n\t\t\t\t\temit,\n\t\t\t\t);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\t// Runaway-loop backstop (cost guard): detect a model stuck repeating one action.\n\t\t\tif (stallLimit > 0 && toolCalls.length > 0) {\n\t\t\t\tconst signature = normalizeToolSignature(toolCalls.map((c) => [c.name, c.arguments ?? null]));\n\t\t\t\tstallWindow.push(signature);\n\t\t\t\tif (stallWindow.length > stallLimit * STALL_WINDOW_PERIODS) stallWindow.shift();\n\t\t\t\tconst repeats = stallWindow.reduce((n, s) => (s === signature ? n + 1 : n), 0);\n\t\t\t\tif (repeats >= stallLimit) {\n\t\t\t\t\tconfig.onRunawayStop?.({ signature, repeats });\n\t\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCalls,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\trepairTeachTracker,\n\t\t\texecutionFailureTracker,\n\t\t\tsignal,\n\t\t\temit,\n\t\t);\n\t}\n\treturn executeToolCallsParallel(\n\t\tcurrentContext,\n\t\tassistantMessage,\n\t\ttoolCalls,\n\t\tconfig,\n\t\tvalidationFailureTracker,\n\t\trepairTeachTracker,\n\t\texecutionFailureTracker,\n\t\tsignal,\n\t\temit,\n\t);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\terrorClass?: string;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\ntype ToolValidationFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\tescalatedSignature?: string;\n};\n\ntype ToolRepairTeachTracker = Map<string, number>;\n\ntype ToolExecutionFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\ttaughtSignature?: string;\n};\n\nconst DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD = 3;\nconst TOOL_REPAIR_TEACH_EVERY = 5;\nconst TOOL_EXECUTION_FAILURE_TEACH_AT = 2;\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nfunction createValidationBounceTelemetry(\n\tconfig: AgentLoopConfig,\n\ttoolCall: AgentToolCall,\n\terrorKeyword: string,\n): ToolArgumentValidationTelemetryEvent {\n\treturn {\n\t\toutcome: \"bounced\",\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\ttool: toolCall.name,\n\t\tsource: toolCall.source,\n\t\tfailureModes: [\"other\"],\n\t\trepairsApplied: [],\n\t\terrorKeywords: [errorKeyword],\n\t\ttaught: \"none\",\n\t\texecutionOutcome: \"not_run\",\n\t};\n}\n\nfunction resetValidationFailureTracker(tracker: ToolValidationFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction emitToolArgumentValidationTelemetry(\n\tconfig: AgentLoopConfig,\n\tevent: ToolArgumentValidationTelemetryEvent | undefined,\n\texecutionOutcome: ToolArgumentExecutionOutcome,\n\ttaught: ToolArgumentValidationTelemetryEvent[\"taught\"],\n): void {\n\tif (!event) return;\n\tconfig.onToolArgumentValidation?.({ ...event, executionOutcome, taught });\n}\n\nfunction toolValidationEscalationThreshold(config: AgentLoopConfig): number {\n\treturn config.toolValidationEscalationThreshold ?? DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD;\n}\n\nfunction isToolArgumentRepairEmergencyDisabled(): boolean {\n\tconst env = typeof process === \"object\" && process ? process.env : undefined;\n\tconst value = env?.PI_TOOL_REPAIR_DISABLED;\n\tif (!value) return false;\n\treturn [\"1\", \"true\", \"yes\", \"on\"].includes(value.trim().toLowerCase());\n}\n\nfunction isToolArgumentValidationError(error: unknown): error is ToolArgumentValidationError {\n\treturn (\n\t\terror instanceof ToolArgumentValidationError ||\n\t\t(error instanceof Error &&\n\t\t\terror.name === \"ToolArgumentValidationError\" &&\n\t\t\ttypeof (error as { toolName?: unknown }).toolName === \"string\" &&\n\t\t\ttypeof (error as { signature?: unknown }).signature === \"string\" &&\n\t\t\ttypeof (error as { enrichment?: unknown }).enrichment === \"string\")\n\t);\n}\n\nfunction handleValidationFailure(\n\terror: ToolArgumentValidationError,\n\tconfig: AgentLoopConfig,\n\ttracker: ToolValidationFailureTracker,\n): string {\n\tif (tracker.signature === error.signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = error.signature;\n\t\ttracker.repeats = 1;\n\t\ttracker.escalatedSignature = undefined;\n\t}\n\n\tconst threshold = toolValidationEscalationThreshold(config);\n\tif (threshold <= 0 || tracker.repeats < threshold || tracker.escalatedSignature === error.signature) {\n\t\treturn error.message;\n\t}\n\n\ttracker.escalatedSignature = error.signature;\n\tconfig.onToolValidationEscalation?.({\n\t\ttool: error.toolName,\n\t\tsignature: error.signature,\n\t\trepeats: tracker.repeats,\n\t\tmodel: config.model.id,\n\t\tprovider: config.model.provider,\n\t});\n\treturn `${error.message}\\n\\nRepeated validation failure (${tracker.repeats} identical attempts). Use this full schema and example before retrying:\\n${error.enrichment}`;\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tif (toolCall.errorMessage) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(toolCall.errorMessage),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tlet validationEvent: ToolArgumentValidationTelemetryEvent | undefined;\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall, {\n\t\t\tmodel: config.model.id,\n\t\t\tprovider: config.model.provider,\n\t\t\trepairEnabled: !isToolArgumentRepairEmergencyDisabled(),\n\t\t\ttelemetry: (event) => {\n\t\t\t\tvalidationEvent = event;\n\t\t\t},\n\t\t});\n\t\tresetValidationFailureTracker(validationFailureTracker);\n\t\tif (preparedToolCall.repairNotes) {\n\t\t\ttoolCall.repairNotes = preparedToolCall.repairNotes;\n\t\t}\n\t\tif (validatedArgs !== toolCall.arguments) {\n\t\t\ttoolCall.rawArguments ??= toolCall.arguments;\n\t\t\ttoolCall.arguments = validatedArgs;\n\t\t}\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t\tvalidationEvent,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t\tvalidationEvent,\n\t\t};\n\t} catch (error) {\n\t\tconst message = isToolArgumentValidationError(error)\n\t\t\t? handleValidationFailure(error, config, validationFailureTracker)\n\t\t\t: error instanceof Error\n\t\t\t\t? error.message\n\t\t\t\t: String(error);\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(message),\n\t\t\tisError: true,\n\t\t\tvalidationEvent,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tresult: createErrorToolResultWithGuidance(message),\n\t\t\tisError: true,\n\t\t\terrorClass: error instanceof Error ? error.name : typeof error,\n\t\t};\n\t}\n}\n\nfunction repairTeachKey(toolName: string, note: string): string {\n\tconst repairName = /^\\[harness\\] ([^:]+):/.exec(note)?.[1] ?? note;\n\treturn `${toolName}\\0${repairName}`;\n}\n\nfunction shouldEmitRepairTeachNote(toolName: string, note: string, tracker: ToolRepairTeachTracker): boolean {\n\tconst key = repairTeachKey(toolName, note);\n\tconst count = (tracker.get(key) ?? 0) + 1;\n\ttracker.set(key, count);\n\treturn count === 1 || count % TOOL_REPAIR_TEACH_EVERY === 0;\n}\n\nfunction appendRepairTeachNotes(\n\tresult: AgentToolResult<any>,\n\ttoolCall: AgentToolCall,\n\ttracker: ToolRepairTeachTracker,\n\tconfig: AgentLoopConfig,\n): { result: AgentToolResult<any>; taught: boolean } {\n\tif (config.toolArgumentTeachEnabled === false) return { result, taught: false };\n\tconst notes = (toolCall.repairNotes ?? []).filter((note) => shouldEmitRepairTeachNote(toolCall.name, note, tracker));\n\tif (notes.length === 0) return { result, taught: false };\n\treturn {\n\t\tresult: {\n\t\t\t...result,\n\t\t\tcontent: [...result.content, { type: \"text\", text: notes.join(\"\\n\") }],\n\t\t},\n\t\ttaught: true,\n\t};\n}\n\nfunction resetExecutionFailureTracker(tracker: ToolExecutionFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction executionFailureSignature(prepared: PreparedToolCall, errorClass: string): string {\n\treturn `${normalizeToolSignature([[prepared.toolCall.name, prepared.args]])}\\0${errorClass}`;\n}\n\nfunction appendExecutionFailureTeachNote(\n\tresult: AgentToolResult<any>,\n\tprepared: PreparedToolCall,\n\terrorClass: string | undefined,\n\ttracker: ToolExecutionFailureTracker,\n): AgentToolResult<any> {\n\tconst signature = executionFailureSignature(prepared, errorClass ?? \"tool-error\");\n\tif (tracker.signature === signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = signature;\n\t\ttracker.repeats = 1;\n\t}\n\tif (tracker.repeats !== TOOL_EXECUTION_FAILURE_TEACH_AT || tracker.taughtSignature === signature) return result;\n\ttracker.taughtSignature = signature;\n\treturn {\n\t\t...result,\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `[harness] This exact ${prepared.toolCall.name} call failed twice with the same ${errorClass ?? \"tool\"} error. Change the arguments or approach; do not resend the identical call.`,\n\t\t\t},\n\t\t\t...result.content,\n\t\t],\n\t};\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\tif (isError) {\n\t\tresult = appendExecutionFailureTeachNote(result, prepared, executed.errorClass, executionFailureTracker);\n\t} else {\n\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t}\n\n\tconst repaired = appendRepairTeachNotes(result, prepared.toolCall, repairTeachTracker, config);\n\temitToolArgumentValidationTelemetry(\n\t\tconfig,\n\t\tprepared.validationEvent,\n\t\tisError ? \"failed\" : \"succeeded\",\n\t\trepaired.taught ? \"note\" : \"none\",\n\t);\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult: repaired.result,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nfunction createErrorToolResultWithGuidance(message: string): AgentToolResult<any> {\n\tconst guidance = getToolExecutionErrorGuidance(message);\n\tif (!guidance) return createErrorToolResult(message);\n\treturn {\n\t\tcontent: [\n\t\t\t{ type: \"text\", text: message },\n\t\t\t{ type: \"text\", text: `[harness] ${guidance}` },\n\t\t],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionStart(toolCall: AgentToolCall, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t\trepair: getToolCallRepairInfo(toolCall),\n\t});\n}\n\nfunction getToolCallRepairInfo(toolCall: AgentToolCall): ToolCallRepairInfo | undefined {\n\tif (!toolCall.rawArguments && !toolCall.repairNotes?.length) return undefined;\n\treturn {\n\t\trepaired: true,\n\t\t...(toolCall.rawArguments ? { rawArguments: toolCall.rawArguments } : {}),\n\t\t...(toolCall.repairNotes?.length ? { notes: toolCall.repairNotes } : {}),\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t\trepair: getToolCallRepairInfo(finalized.toolCall),\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
package/dist/agent-loop.js
CHANGED
|
@@ -455,6 +455,13 @@ function emitToolArgumentValidationTelemetry(config, event, executionOutcome, ta
|
|
|
455
455
|
function toolValidationEscalationThreshold(config) {
|
|
456
456
|
return config.toolValidationEscalationThreshold ?? DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD;
|
|
457
457
|
}
|
|
458
|
+
function isToolArgumentRepairEmergencyDisabled() {
|
|
459
|
+
const env = typeof process === "object" && process ? process.env : undefined;
|
|
460
|
+
const value = env?.PI_TOOL_REPAIR_DISABLED;
|
|
461
|
+
if (!value)
|
|
462
|
+
return false;
|
|
463
|
+
return ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
|
|
464
|
+
}
|
|
458
465
|
function isToolArgumentValidationError(error) {
|
|
459
466
|
return (error instanceof ToolArgumentValidationError ||
|
|
460
467
|
(error instanceof Error &&
|
|
@@ -510,7 +517,7 @@ async function prepareToolCall(currentContext, assistantMessage, toolCall, confi
|
|
|
510
517
|
const validatedArgs = validateToolArguments(tool, preparedToolCall, {
|
|
511
518
|
model: config.model.id,
|
|
512
519
|
provider: config.model.provider,
|
|
513
|
-
repairEnabled:
|
|
520
|
+
repairEnabled: !isToolArgumentRepairEmergencyDisabled(),
|
|
514
521
|
telemetry: (event) => {
|
|
515
522
|
validationEvent = event;
|
|
516
523
|
},
|
package/dist/agent-loop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tgetToolExecutionErrorGuidance,\n\tstreamSimple,\n\ttype ToolArgumentExecutionOutcome,\n\tToolArgumentValidationError,\n\ttype ToolArgumentValidationTelemetryEvent,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@caupulican/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n\tToolCallRepairInfo,\n} from \"./types.ts\";\nimport { DEFAULT_MAX_STALL_TURNS } from \"./types.ts\";\nimport { createEmptyUsage } from \"./usage.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createLoopFailureMessage(error: unknown, config: AgentLoopConfig, aborted: boolean): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [{ type: \"text\", text: \"\" }],\n\t\tapi: config.model.api,\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: aborted ? \"aborted\" : \"error\",\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * How many `stallLimit`-length periods the runaway-loop window spans. A window of `stallLimit * P`\n * turns lets the count-based detector catch oscillating cycles of period up to `P` (each signature in a\n * period-k cycle recurs ~window/k times), not just back-to-back repeats. Beyond this the cycle is loose\n * enough that it's indistinguishable from legitimate varied work, so we don't chase it.\n */\nconst STALL_WINDOW_PERIODS = 4;\n\n/**\n * Normalize a tool-call batch into a stable signature for runaway-loop detection. Volatile argument\n * tokens — epoch/timestamps, UUIDs, long hashes/nonces — are masked so a model retrying the SAME call\n * with a fresh timestamp/id each turn still collapses to one signature and is detected (bug #28). Only\n * clearly-volatile patterns are masked: short numbers (`file2.ts`, `line 42`, `count: 3`) are kept so\n * genuinely-distinct calls (reading numbered files, different line ranges) are NOT falsely merged.\n */\nfunction normalizeToolSignature(pairs: Array<[string, unknown]>): string {\n\treturn JSON.stringify(pairs)\n\t\t.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, \"<uuid>\")\n\t\t.replace(/\\d{4}-\\d{2}-\\d{2}[tT][0-9:.]+(?:z|[+-]\\d{2}:?\\d{2})?/gi, \"<ts>\")\n\t\t.replace(/\\b[0-9a-f]{16,}\\b/gi, \"<hex>\")\n\t\t.replace(/\\d{10,}/g, \"<num>\");\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Runaway-loop backstop state: a sliding window of recent NORMALIZED tool-call signatures. A model\n\t// wedged repeating the same action makes no progress but keeps spending tokens; if one signature\n\t// recurs `stallLimit` times within the window we stop gracefully. Signatures are normalized so\n\t// volatile args (timestamps/UUIDs/nonces that change every call) can't disguise an otherwise-\n\t// identical call (bug #28). The window spans `stallLimit * STALL_WINDOW_PERIODS` turns so periodic\n\t// oscillation is caught too, not just back-to-back repeats: a cycle of period P repeats each\n\t// signature ~window/P times, so any P up to STALL_WINDOW_PERIODS reaches the threshold before the\n\t// window slides past it. Counts only turns that issued tool calls, so varied/long work never trips\n\t// it. `0` disables.\n\tconst stallLimit = config.maxStallTurns ?? DEFAULT_MAX_STALL_TURNS;\n\tconst stallWindow: string[] = [];\n\tconst validationFailureTracker: ToolValidationFailureTracker = { repeats: 0 };\n\tconst repairTeachTracker: ToolRepairTeachTracker = new Map();\n\tconst executionFailureTracker: ToolExecutionFailureTracker = { repeats: 0 };\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(\n\t\t\t\t\tcurrentContext,\n\t\t\t\t\tmessage,\n\t\t\t\t\tconfig,\n\t\t\t\t\tvalidationFailureTracker,\n\t\t\t\t\trepairTeachTracker,\n\t\t\t\t\texecutionFailureTracker,\n\t\t\t\t\tsignal,\n\t\t\t\t\temit,\n\t\t\t\t);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\t// Runaway-loop backstop (cost guard): detect a model stuck repeating one action.\n\t\t\tif (stallLimit > 0 && toolCalls.length > 0) {\n\t\t\t\tconst signature = normalizeToolSignature(toolCalls.map((c) => [c.name, c.arguments ?? null]));\n\t\t\t\tstallWindow.push(signature);\n\t\t\t\tif (stallWindow.length > stallLimit * STALL_WINDOW_PERIODS) stallWindow.shift();\n\t\t\t\tconst repeats = stallWindow.reduce((n, s) => (s === signature ? n + 1 : n), 0);\n\t\t\t\tif (repeats >= stallLimit) {\n\t\t\t\t\tconfig.onRunawayStop?.({ signature, repeats });\n\t\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCalls,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\trepairTeachTracker,\n\t\t\texecutionFailureTracker,\n\t\t\tsignal,\n\t\t\temit,\n\t\t);\n\t}\n\treturn executeToolCallsParallel(\n\t\tcurrentContext,\n\t\tassistantMessage,\n\t\ttoolCalls,\n\t\tconfig,\n\t\tvalidationFailureTracker,\n\t\trepairTeachTracker,\n\t\texecutionFailureTracker,\n\t\tsignal,\n\t\temit,\n\t);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\terrorClass?: string;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\ntype ToolValidationFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\tescalatedSignature?: string;\n};\n\ntype ToolRepairTeachTracker = Map<string, number>;\n\ntype ToolExecutionFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\ttaughtSignature?: string;\n};\n\nconst DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD = 3;\nconst TOOL_REPAIR_TEACH_EVERY = 5;\nconst TOOL_EXECUTION_FAILURE_TEACH_AT = 2;\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nfunction createValidationBounceTelemetry(\n\tconfig: AgentLoopConfig,\n\ttoolCall: AgentToolCall,\n\terrorKeyword: string,\n): ToolArgumentValidationTelemetryEvent {\n\treturn {\n\t\toutcome: \"bounced\",\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\ttool: toolCall.name,\n\t\tsource: toolCall.source,\n\t\tfailureModes: [\"other\"],\n\t\trepairsApplied: [],\n\t\terrorKeywords: [errorKeyword],\n\t\ttaught: \"none\",\n\t\texecutionOutcome: \"not_run\",\n\t};\n}\n\nfunction resetValidationFailureTracker(tracker: ToolValidationFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction emitToolArgumentValidationTelemetry(\n\tconfig: AgentLoopConfig,\n\tevent: ToolArgumentValidationTelemetryEvent | undefined,\n\texecutionOutcome: ToolArgumentExecutionOutcome,\n\ttaught: ToolArgumentValidationTelemetryEvent[\"taught\"],\n): void {\n\tif (!event) return;\n\tconfig.onToolArgumentValidation?.({ ...event, executionOutcome, taught });\n}\n\nfunction toolValidationEscalationThreshold(config: AgentLoopConfig): number {\n\treturn config.toolValidationEscalationThreshold ?? DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD;\n}\n\nfunction isToolArgumentValidationError(error: unknown): error is ToolArgumentValidationError {\n\treturn (\n\t\terror instanceof ToolArgumentValidationError ||\n\t\t(error instanceof Error &&\n\t\t\terror.name === \"ToolArgumentValidationError\" &&\n\t\t\ttypeof (error as { toolName?: unknown }).toolName === \"string\" &&\n\t\t\ttypeof (error as { signature?: unknown }).signature === \"string\" &&\n\t\t\ttypeof (error as { enrichment?: unknown }).enrichment === \"string\")\n\t);\n}\n\nfunction handleValidationFailure(\n\terror: ToolArgumentValidationError,\n\tconfig: AgentLoopConfig,\n\ttracker: ToolValidationFailureTracker,\n): string {\n\tif (tracker.signature === error.signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = error.signature;\n\t\ttracker.repeats = 1;\n\t\ttracker.escalatedSignature = undefined;\n\t}\n\n\tconst threshold = toolValidationEscalationThreshold(config);\n\tif (threshold <= 0 || tracker.repeats < threshold || tracker.escalatedSignature === error.signature) {\n\t\treturn error.message;\n\t}\n\n\ttracker.escalatedSignature = error.signature;\n\tconfig.onToolValidationEscalation?.({\n\t\ttool: error.toolName,\n\t\tsignature: error.signature,\n\t\trepeats: tracker.repeats,\n\t\tmodel: config.model.id,\n\t\tprovider: config.model.provider,\n\t});\n\treturn `${error.message}\\n\\nRepeated validation failure (${tracker.repeats} identical attempts). Use this full schema and example before retrying:\\n${error.enrichment}`;\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tif (toolCall.errorMessage) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(toolCall.errorMessage),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tlet validationEvent: ToolArgumentValidationTelemetryEvent | undefined;\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall, {\n\t\t\tmodel: config.model.id,\n\t\t\tprovider: config.model.provider,\n\t\t\trepairEnabled: config.toolArgumentRepairEnabled !== false,\n\t\t\ttelemetry: (event) => {\n\t\t\t\tvalidationEvent = event;\n\t\t\t},\n\t\t});\n\t\tresetValidationFailureTracker(validationFailureTracker);\n\t\tif (preparedToolCall.repairNotes) {\n\t\t\ttoolCall.repairNotes = preparedToolCall.repairNotes;\n\t\t}\n\t\tif (validatedArgs !== toolCall.arguments) {\n\t\t\ttoolCall.rawArguments ??= toolCall.arguments;\n\t\t\ttoolCall.arguments = validatedArgs;\n\t\t}\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t\tvalidationEvent,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t\tvalidationEvent,\n\t\t};\n\t} catch (error) {\n\t\tconst message = isToolArgumentValidationError(error)\n\t\t\t? handleValidationFailure(error, config, validationFailureTracker)\n\t\t\t: error instanceof Error\n\t\t\t\t? error.message\n\t\t\t\t: String(error);\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(message),\n\t\t\tisError: true,\n\t\t\tvalidationEvent,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tresult: createErrorToolResultWithGuidance(message),\n\t\t\tisError: true,\n\t\t\terrorClass: error instanceof Error ? error.name : typeof error,\n\t\t};\n\t}\n}\n\nfunction repairTeachKey(toolName: string, note: string): string {\n\tconst repairName = /^\\[harness\\] ([^:]+):/.exec(note)?.[1] ?? note;\n\treturn `${toolName}\\0${repairName}`;\n}\n\nfunction shouldEmitRepairTeachNote(toolName: string, note: string, tracker: ToolRepairTeachTracker): boolean {\n\tconst key = repairTeachKey(toolName, note);\n\tconst count = (tracker.get(key) ?? 0) + 1;\n\ttracker.set(key, count);\n\treturn count === 1 || count % TOOL_REPAIR_TEACH_EVERY === 0;\n}\n\nfunction appendRepairTeachNotes(\n\tresult: AgentToolResult<any>,\n\ttoolCall: AgentToolCall,\n\ttracker: ToolRepairTeachTracker,\n\tconfig: AgentLoopConfig,\n): { result: AgentToolResult<any>; taught: boolean } {\n\tif (config.toolArgumentTeachEnabled === false) return { result, taught: false };\n\tconst notes = (toolCall.repairNotes ?? []).filter((note) => shouldEmitRepairTeachNote(toolCall.name, note, tracker));\n\tif (notes.length === 0) return { result, taught: false };\n\treturn {\n\t\tresult: {\n\t\t\t...result,\n\t\t\tcontent: [...result.content, { type: \"text\", text: notes.join(\"\\n\") }],\n\t\t},\n\t\ttaught: true,\n\t};\n}\n\nfunction resetExecutionFailureTracker(tracker: ToolExecutionFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction executionFailureSignature(prepared: PreparedToolCall, errorClass: string): string {\n\treturn `${normalizeToolSignature([[prepared.toolCall.name, prepared.args]])}\\0${errorClass}`;\n}\n\nfunction appendExecutionFailureTeachNote(\n\tresult: AgentToolResult<any>,\n\tprepared: PreparedToolCall,\n\terrorClass: string | undefined,\n\ttracker: ToolExecutionFailureTracker,\n): AgentToolResult<any> {\n\tconst signature = executionFailureSignature(prepared, errorClass ?? \"tool-error\");\n\tif (tracker.signature === signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = signature;\n\t\ttracker.repeats = 1;\n\t}\n\tif (tracker.repeats !== TOOL_EXECUTION_FAILURE_TEACH_AT || tracker.taughtSignature === signature) return result;\n\ttracker.taughtSignature = signature;\n\treturn {\n\t\t...result,\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `[harness] This exact ${prepared.toolCall.name} call failed twice with the same ${errorClass ?? \"tool\"} error. Change the arguments or approach; do not resend the identical call.`,\n\t\t\t},\n\t\t\t...result.content,\n\t\t],\n\t};\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\tif (isError) {\n\t\tresult = appendExecutionFailureTeachNote(result, prepared, executed.errorClass, executionFailureTracker);\n\t} else {\n\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t}\n\n\tconst repaired = appendRepairTeachNotes(result, prepared.toolCall, repairTeachTracker, config);\n\temitToolArgumentValidationTelemetry(\n\t\tconfig,\n\t\tprepared.validationEvent,\n\t\tisError ? \"failed\" : \"succeeded\",\n\t\trepaired.taught ? \"note\" : \"none\",\n\t);\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult: repaired.result,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nfunction createErrorToolResultWithGuidance(message: string): AgentToolResult<any> {\n\tconst guidance = getToolExecutionErrorGuidance(message);\n\tif (!guidance) return createErrorToolResult(message);\n\treturn {\n\t\tcontent: [\n\t\t\t{ type: \"text\", text: message },\n\t\t\t{ type: \"text\", text: `[harness] ${guidance}` },\n\t\t],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionStart(toolCall: AgentToolCall, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t\trepair: getToolCallRepairInfo(toolCall),\n\t});\n}\n\nfunction getToolCallRepairInfo(toolCall: AgentToolCall): ToolCallRepairInfo | undefined {\n\tif (!toolCall.rawArguments && !toolCall.repairNotes?.length) return undefined;\n\treturn {\n\t\trepaired: true,\n\t\t...(toolCall.rawArguments ? { rawArguments: toolCall.rawArguments } : {}),\n\t\t...(toolCall.repairNotes?.length ? { notes: toolCall.repairNotes } : {}),\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t\trepair: getToolCallRepairInfo(finalized.toolCall),\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agent-loop.js","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent loop that works with AgentMessage throughout.\n * Transforms to Message[] only at the LLM call boundary.\n */\n\nimport {\n\ttype AssistantMessage,\n\ttype Context,\n\tEventStream,\n\tgetToolExecutionErrorGuidance,\n\tstreamSimple,\n\ttype ToolArgumentExecutionOutcome,\n\tToolArgumentValidationError,\n\ttype ToolArgumentValidationTelemetryEvent,\n\ttype ToolResultMessage,\n\tvalidateToolArguments,\n} from \"@caupulican/pi-ai\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolResult,\n\tStreamFn,\n\tToolCallRepairInfo,\n} from \"./types.ts\";\nimport { DEFAULT_MAX_STALL_TURNS } from \"./types.ts\";\nimport { createEmptyUsage } from \"./usage.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/**\n * Start an agent loop with a new prompt message.\n * The prompt is added to the context and events are emitted for it.\n */\nexport function agentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoop(\n\t\tprompts,\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\n/**\n * Continue an agent loop from the current context without adding a new message.\n * Used for retries - context already has user message or tool results.\n *\n * **Important:** The last message in context must convert to a `user` or `toolResult` message\n * via `convertToLlm`. If it doesn't, the LLM provider will reject the request.\n * This cannot be validated here since `convertToLlm` is only called once per turn.\n */\nexport function agentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst stream = createAgentStream();\n\n\tvoid runAgentLoopContinue(\n\t\tcontext,\n\t\tconfig,\n\t\tasync (event) => {\n\t\t\tstream.push(event);\n\t\t},\n\t\tsignal,\n\t\tstreamFn,\n\t)\n\t\t.catch(async (error) => {\n\t\t\tconst messages = [createLoopFailureMessage(error, config, signal?.aborted ?? false)];\n\t\t\tstream.push({ type: \"agent_end\", messages });\n\t\t\treturn messages;\n\t\t})\n\t\t.then((messages) => {\n\t\t\tstream.end(messages);\n\t\t});\n\n\treturn stream;\n}\n\nexport async function runAgentLoop(\n\tprompts: AgentMessage[],\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tconst newMessages: AgentMessage[] = [...prompts];\n\tconst currentContext: AgentContext = {\n\t\t...context,\n\t\tmessages: [...context.messages, ...prompts],\n\t};\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\tfor (const prompt of prompts) {\n\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\tawait emit({ type: \"message_end\", message: prompt });\n\t}\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nexport async function runAgentLoopContinue(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\temit: AgentEventSink,\n\tsignal?: AbortSignal,\n\tstreamFn?: StreamFn,\n): Promise<AgentMessage[]> {\n\tif (context.messages.length === 0) {\n\t\tthrow new Error(\"Cannot continue: no messages in context\");\n\t}\n\n\tif (context.messages[context.messages.length - 1].role === \"assistant\") {\n\t\tthrow new Error(\"Cannot continue from message role: assistant\");\n\t}\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context };\n\n\tawait emit({ type: \"agent_start\" });\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn);\n\treturn newMessages;\n}\n\nfunction createLoopFailureMessage(error: unknown, config: AgentLoopConfig, aborted: boolean): AssistantMessage {\n\treturn {\n\t\trole: \"assistant\",\n\t\tcontent: [{ type: \"text\", text: \"\" }],\n\t\tapi: config.model.api,\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\tusage: createEmptyUsage(),\n\t\tstopReason: aborted ? \"aborted\" : \"error\",\n\t\terrorMessage: error instanceof Error ? error.message : String(error),\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nfunction createAgentStream(): EventStream<AgentEvent, AgentMessage[]> {\n\treturn new EventStream<AgentEvent, AgentMessage[]>(\n\t\t(event: AgentEvent) => event.type === \"agent_end\",\n\t\t(event: AgentEvent) => (event.type === \"agent_end\" ? event.messages : []),\n\t);\n}\n\n/**\n * How many `stallLimit`-length periods the runaway-loop window spans. A window of `stallLimit * P`\n * turns lets the count-based detector catch oscillating cycles of period up to `P` (each signature in a\n * period-k cycle recurs ~window/k times), not just back-to-back repeats. Beyond this the cycle is loose\n * enough that it's indistinguishable from legitimate varied work, so we don't chase it.\n */\nconst STALL_WINDOW_PERIODS = 4;\n\n/**\n * Normalize a tool-call batch into a stable signature for runaway-loop detection. Volatile argument\n * tokens — epoch/timestamps, UUIDs, long hashes/nonces — are masked so a model retrying the SAME call\n * with a fresh timestamp/id each turn still collapses to one signature and is detected (bug #28). Only\n * clearly-volatile patterns are masked: short numbers (`file2.ts`, `line 42`, `count: 3`) are kept so\n * genuinely-distinct calls (reading numbered files, different line ranges) are NOT falsely merged.\n */\nfunction normalizeToolSignature(pairs: Array<[string, unknown]>): string {\n\treturn JSON.stringify(pairs)\n\t\t.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, \"<uuid>\")\n\t\t.replace(/\\d{4}-\\d{2}-\\d{2}[tT][0-9:.]+(?:z|[+-]\\d{2}:?\\d{2})?/gi, \"<ts>\")\n\t\t.replace(/\\b[0-9a-f]{16,}\\b/gi, \"<hex>\")\n\t\t.replace(/\\d{10,}/g, \"<num>\");\n}\n\n/**\n * Main loop logic shared by agentLoop and agentLoopContinue.\n */\nasync function runLoop(\n\tinitialContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tinitialConfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tlet currentContext = initialContext;\n\tlet config = initialConfig;\n\tlet firstTurn = true;\n\t// Runaway-loop backstop state: a sliding window of recent NORMALIZED tool-call signatures. A model\n\t// wedged repeating the same action makes no progress but keeps spending tokens; if one signature\n\t// recurs `stallLimit` times within the window we stop gracefully. Signatures are normalized so\n\t// volatile args (timestamps/UUIDs/nonces that change every call) can't disguise an otherwise-\n\t// identical call (bug #28). The window spans `stallLimit * STALL_WINDOW_PERIODS` turns so periodic\n\t// oscillation is caught too, not just back-to-back repeats: a cycle of period P repeats each\n\t// signature ~window/P times, so any P up to STALL_WINDOW_PERIODS reaches the threshold before the\n\t// window slides past it. Counts only turns that issued tool calls, so varied/long work never trips\n\t// it. `0` disables.\n\tconst stallLimit = config.maxStallTurns ?? DEFAULT_MAX_STALL_TURNS;\n\tconst stallWindow: string[] = [];\n\tconst validationFailureTracker: ToolValidationFailureTracker = { repeats: 0 };\n\tconst repairTeachTracker: ToolRepairTeachTracker = new Map();\n\tconst executionFailureTracker: ToolExecutionFailureTracker = { repeats: 0 };\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\n\t// Outer loop: continues when queued follow-up messages arrive after agent would stop\n\twhile (true) {\n\t\tlet hasMoreToolCalls = true;\n\n\t\t// Inner loop: process tool calls and steering messages\n\t\twhile (hasMoreToolCalls || pendingMessages.length > 0) {\n\t\t\tif (!firstTurn) {\n\t\t\t\tawait emit({ type: \"turn_start\" });\n\t\t\t} else {\n\t\t\t\tfirstTurn = false;\n\t\t\t}\n\n\t\t\t// Process pending messages (inject before next assistant response)\n\t\t\tif (pendingMessages.length > 0) {\n\t\t\t\tfor (const message of pendingMessages) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\t\t\tcurrentContext.messages.push(message);\n\t\t\t\t\tnewMessages.push(message);\n\t\t\t\t}\n\t\t\t\tpendingMessages = [];\n\t\t\t}\n\n\t\t\t// Stream assistant response\n\t\t\tconst message = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tnewMessages.push(message);\n\n\t\t\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\t\t\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check for tool calls\n\t\t\tconst toolCalls = message.content.filter((c) => c.type === \"toolCall\");\n\n\t\t\tconst toolResults: ToolResultMessage[] = [];\n\t\t\thasMoreToolCalls = false;\n\t\t\tif (toolCalls.length > 0) {\n\t\t\t\tconst executedToolBatch = await executeToolCalls(\n\t\t\t\t\tcurrentContext,\n\t\t\t\t\tmessage,\n\t\t\t\t\tconfig,\n\t\t\t\t\tvalidationFailureTracker,\n\t\t\t\t\trepairTeachTracker,\n\t\t\t\t\texecutionFailureTracker,\n\t\t\t\t\tsignal,\n\t\t\t\t\temit,\n\t\t\t\t);\n\t\t\t\ttoolResults.push(...executedToolBatch.messages);\n\t\t\t\thasMoreToolCalls = !executedToolBatch.terminate;\n\n\t\t\t\tfor (const result of toolResults) {\n\t\t\t\t\tcurrentContext.messages.push(result);\n\t\t\t\t\tnewMessages.push(result);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tawait emit({ type: \"turn_end\", message, toolResults });\n\n\t\t\t// Runaway-loop backstop (cost guard): detect a model stuck repeating one action.\n\t\t\tif (stallLimit > 0 && toolCalls.length > 0) {\n\t\t\t\tconst signature = normalizeToolSignature(toolCalls.map((c) => [c.name, c.arguments ?? null]));\n\t\t\t\tstallWindow.push(signature);\n\t\t\t\tif (stallWindow.length > stallLimit * STALL_WINDOW_PERIODS) stallWindow.shift();\n\t\t\t\tconst repeats = stallWindow.reduce((n, s) => (s === signature ? n + 1 : n), 0);\n\t\t\t\tif (repeats >= stallLimit) {\n\t\t\t\t\tconfig.onRunawayStop?.({ signature, repeats });\n\t\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst nextTurnContext = {\n\t\t\t\tmessage,\n\t\t\t\ttoolResults,\n\t\t\t\tcontext: currentContext,\n\t\t\t\tnewMessages,\n\t\t\t};\n\t\t\tconst nextTurnSnapshot = await config.prepareNextTurn?.(nextTurnContext);\n\t\t\tif (nextTurnSnapshot) {\n\t\t\t\tcurrentContext = nextTurnSnapshot.context ?? currentContext;\n\t\t\t\tconfig = {\n\t\t\t\t\t...config,\n\t\t\t\t\tmodel: nextTurnSnapshot.model ?? config.model,\n\t\t\t\t\treasoning:\n\t\t\t\t\t\tnextTurnSnapshot.thinkingLevel === undefined\n\t\t\t\t\t\t\t? config.reasoning\n\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel === \"off\"\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: nextTurnSnapshot.thinkingLevel,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tawait config.shouldStopAfterTurn?.({\n\t\t\t\t\tmessage,\n\t\t\t\t\ttoolResults,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t\tnewMessages,\n\t\t\t\t})\n\t\t\t) {\n\t\t\t\tawait emit({ type: \"agent_end\", messages: newMessages });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tpendingMessages = (await config.getSteeringMessages?.()) || [];\n\t\t}\n\n\t\t// Agent would stop here. Check for follow-up messages.\n\t\tconst followUpMessages = (await config.getFollowUpMessages?.()) || [];\n\t\tif (followUpMessages.length > 0) {\n\t\t\t// Set as pending so inner loop processes them\n\t\t\tpendingMessages = followUpMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// No more messages, exit\n\t\tbreak;\n\t}\n\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Stream an assistant response from the LLM.\n * This is where AgentMessage[] gets transformed to Message[] for the LLM.\n */\nasync function streamAssistantResponse(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\t// Apply context transform if configured (AgentMessage[] → AgentMessage[])\n\tlet messages = context.messages;\n\tif (config.transformContext) {\n\t\tmessages = await config.transformContext(messages, signal);\n\t}\n\n\t// Convert to LLM-compatible messages (AgentMessage[] → Message[])\n\tconst llmMessages = await config.convertToLlm(messages);\n\n\t// Build LLM context\n\tconst llmContext: Context = {\n\t\tsystemPrompt: context.systemPrompt,\n\t\tmessages: llmMessages,\n\t\ttools: context.tools,\n\t};\n\n\tconst streamFunction = streamFn || streamSimple;\n\n\t// Resolve API key (important for expiring tokens)\n\tconst resolvedApiKey =\n\t\t(config.getApiKey ? await config.getApiKey(config.model.provider) : undefined) || config.apiKey;\n\n\tconst response = await streamFunction(config.model, llmContext, {\n\t\t...config,\n\t\tapiKey: resolvedApiKey,\n\t\tsignal,\n\t});\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\n\tfor await (const event of response) {\n\t\tswitch (event.type) {\n\t\t\tcase \"start\":\n\t\t\t\tpartialMessage = event.partial;\n\t\t\t\tcontext.messages.push(partialMessage);\n\t\t\t\taddedPartial = true;\n\t\t\t\tawait emit({ type: \"message_start\", message: { ...partialMessage } });\n\t\t\t\tbreak;\n\n\t\t\tcase \"text_start\":\n\t\t\tcase \"text_delta\":\n\t\t\tcase \"text_end\":\n\t\t\tcase \"thinking_start\":\n\t\t\tcase \"thinking_delta\":\n\t\t\tcase \"thinking_end\":\n\t\t\tcase \"toolcall_start\":\n\t\t\tcase \"toolcall_delta\":\n\t\t\tcase \"toolcall_end\":\n\t\t\t\tif (partialMessage) {\n\t\t\t\t\tpartialMessage = event.partial;\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = partialMessage;\n\t\t\t\t\tawait emit({\n\t\t\t\t\t\ttype: \"message_update\",\n\t\t\t\t\t\tassistantMessageEvent: event,\n\t\t\t\t\t\tmessage: { ...partialMessage },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"done\":\n\t\t\tcase \"error\": {\n\t\t\t\tconst finalMessage = await response.result();\n\t\t\t\tif (addedPartial) {\n\t\t\t\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t\t\t\t} else {\n\t\t\t\t\tcontext.messages.push(finalMessage);\n\t\t\t\t}\n\t\t\t\tif (!addedPartial) {\n\t\t\t\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t\t\t\t}\n\t\t\t\tawait emit({ type: \"message_end\", message: finalMessage });\n\t\t\t\treturn finalMessage;\n\t\t\t}\n\t\t}\n\t}\n\n\tconst finalMessage = await response.result();\n\tif (addedPartial) {\n\t\tcontext.messages[context.messages.length - 1] = finalMessage;\n\t} else {\n\t\tcontext.messages.push(finalMessage);\n\t\tawait emit({ type: \"message_start\", message: { ...finalMessage } });\n\t}\n\tawait emit({ type: \"message_end\", message: finalMessage });\n\treturn finalMessage;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\tconst hasSequentialToolCall = toolCalls.some(\n\t\t(tc) => currentContext.tools?.find((t) => t.name === tc.name)?.executionMode === \"sequential\",\n\t);\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCalls,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\trepairTeachTracker,\n\t\t\texecutionFailureTracker,\n\t\t\tsignal,\n\t\t\temit,\n\t\t);\n\t}\n\treturn executeToolCallsParallel(\n\t\tcurrentContext,\n\t\tassistantMessage,\n\t\ttoolCalls,\n\t\tconfig,\n\t\tvalidationFailureTracker,\n\t\trepairTeachTracker,\n\t\texecutionFailureTracker,\n\t\tsignal,\n\t\temit,\n\t);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\nasync function executeToolCallsSequential(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tlet finalized: FinalizedToolCallOutcome;\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tfinalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t};\n\t\t} else {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tfinalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t}\n\n\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(finalizedCalls),\n\t};\n}\n\nasync function executeToolCallsParallel(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCalls: AgentToolCall[],\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallEntry[] = [];\n\n\tfor (const toolCall of toolCalls) {\n\t\tconst preparation = await prepareToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\ttoolCall,\n\t\t\tconfig,\n\t\t\tvalidationFailureTracker,\n\t\t\tsignal,\n\t\t);\n\t\tawait emitToolExecutionStart(toolCall, emit);\n\t\tif (preparation.kind === \"immediate\") {\n\t\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t\t\temitToolArgumentValidationTelemetry(config, preparation.validationEvent, \"not_run\", \"none\");\n\t\t\tconst finalized = {\n\t\t\t\ttoolCall,\n\t\t\t\tresult: preparation.result,\n\t\t\t\tisError: preparation.isError,\n\t\t\t} satisfies FinalizedToolCallOutcome;\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\tfinalizedCalls.push(finalized);\n\t\t\tif (signal?.aborted) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tfinalizedCalls.push(async () => {\n\t\t\tconst executed = await executePreparedToolCall(preparation, signal, emit);\n\t\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\t\tcurrentContext,\n\t\t\t\tassistantMessage,\n\t\t\t\tpreparation,\n\t\t\t\texecuted,\n\t\t\t\tconfig,\n\t\t\t\trepairTeachTracker,\n\t\t\t\texecutionFailureTracker,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tawait emitToolExecutionEnd(finalized, emit);\n\t\t\treturn finalized;\n\t\t});\n\t\tif (signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tconst orderedFinalizedCalls = await Promise.all(\n\t\tfinalizedCalls.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t);\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn {\n\t\tmessages,\n\t\tterminate: shouldTerminateToolBatch(orderedFinalizedCalls),\n\t};\n}\n\ntype PreparedToolCall = {\n\tkind: \"prepared\";\n\ttoolCall: AgentToolCall;\n\ttool: AgentTool<any>;\n\targs: unknown;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ImmediateToolCallOutcome = {\n\tkind: \"immediate\";\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\terrorClass?: string;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n};\n\ntype FinalizedToolCallEntry = FinalizedToolCallOutcome | (() => Promise<FinalizedToolCallOutcome>);\n\ntype ToolValidationFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\tescalatedSignature?: string;\n};\n\ntype ToolRepairTeachTracker = Map<string, number>;\n\ntype ToolExecutionFailureTracker = {\n\tsignature?: string;\n\trepeats: number;\n\ttaughtSignature?: string;\n};\n\nconst DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD = 3;\nconst TOOL_REPAIR_TEACH_EVERY = 5;\nconst TOOL_EXECUTION_FAILURE_TEACH_AT = 2;\n\nfunction shouldTerminateToolBatch(finalizedCalls: FinalizedToolCallOutcome[]): boolean {\n\treturn finalizedCalls.length > 0 && finalizedCalls.every((finalized) => finalized.result.terminate === true);\n}\n\nfunction prepareToolCallArguments(tool: AgentTool<any>, toolCall: AgentToolCall): AgentToolCall {\n\tif (!tool.prepareArguments) {\n\t\treturn toolCall;\n\t}\n\tconst preparedArguments = tool.prepareArguments(toolCall.arguments);\n\tif (preparedArguments === toolCall.arguments) {\n\t\treturn toolCall;\n\t}\n\treturn {\n\t\t...toolCall,\n\t\targuments: preparedArguments as Record<string, any>,\n\t};\n}\n\nfunction createValidationBounceTelemetry(\n\tconfig: AgentLoopConfig,\n\ttoolCall: AgentToolCall,\n\terrorKeyword: string,\n): ToolArgumentValidationTelemetryEvent {\n\treturn {\n\t\toutcome: \"bounced\",\n\t\tprovider: config.model.provider,\n\t\tmodel: config.model.id,\n\t\ttool: toolCall.name,\n\t\tsource: toolCall.source,\n\t\tfailureModes: [\"other\"],\n\t\trepairsApplied: [],\n\t\terrorKeywords: [errorKeyword],\n\t\ttaught: \"none\",\n\t\texecutionOutcome: \"not_run\",\n\t};\n}\n\nfunction resetValidationFailureTracker(tracker: ToolValidationFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction emitToolArgumentValidationTelemetry(\n\tconfig: AgentLoopConfig,\n\tevent: ToolArgumentValidationTelemetryEvent | undefined,\n\texecutionOutcome: ToolArgumentExecutionOutcome,\n\ttaught: ToolArgumentValidationTelemetryEvent[\"taught\"],\n): void {\n\tif (!event) return;\n\tconfig.onToolArgumentValidation?.({ ...event, executionOutcome, taught });\n}\n\nfunction toolValidationEscalationThreshold(config: AgentLoopConfig): number {\n\treturn config.toolValidationEscalationThreshold ?? DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD;\n}\n\nfunction isToolArgumentRepairEmergencyDisabled(): boolean {\n\tconst env = typeof process === \"object\" && process ? process.env : undefined;\n\tconst value = env?.PI_TOOL_REPAIR_DISABLED;\n\tif (!value) return false;\n\treturn [\"1\", \"true\", \"yes\", \"on\"].includes(value.trim().toLowerCase());\n}\n\nfunction isToolArgumentValidationError(error: unknown): error is ToolArgumentValidationError {\n\treturn (\n\t\terror instanceof ToolArgumentValidationError ||\n\t\t(error instanceof Error &&\n\t\t\terror.name === \"ToolArgumentValidationError\" &&\n\t\t\ttypeof (error as { toolName?: unknown }).toolName === \"string\" &&\n\t\t\ttypeof (error as { signature?: unknown }).signature === \"string\" &&\n\t\t\ttypeof (error as { enrichment?: unknown }).enrichment === \"string\")\n\t);\n}\n\nfunction handleValidationFailure(\n\terror: ToolArgumentValidationError,\n\tconfig: AgentLoopConfig,\n\ttracker: ToolValidationFailureTracker,\n): string {\n\tif (tracker.signature === error.signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = error.signature;\n\t\ttracker.repeats = 1;\n\t\ttracker.escalatedSignature = undefined;\n\t}\n\n\tconst threshold = toolValidationEscalationThreshold(config);\n\tif (threshold <= 0 || tracker.repeats < threshold || tracker.escalatedSignature === error.signature) {\n\t\treturn error.message;\n\t}\n\n\ttracker.escalatedSignature = error.signature;\n\tconfig.onToolValidationEscalation?.({\n\t\ttool: error.toolName,\n\t\tsignature: error.signature,\n\t\trepeats: tracker.repeats,\n\t\tmodel: config.model.id,\n\t\tprovider: config.model.provider,\n\t});\n\treturn `${error.message}\\n\\nRepeated validation failure (${tracker.repeats} identical attempts). Use this full schema and example before retrying:\\n${error.enrichment}`;\n}\n\nasync function prepareToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\ttoolCall: AgentToolCall,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tif (toolCall.errorMessage) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(toolCall.errorMessage),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tconst tool = currentContext.tools?.find((t) => t.name === toolCall.name);\n\tif (!tool) {\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(`Tool ${toolCall.name} not found`),\n\t\t\tisError: true,\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\n\tlet validationEvent: ToolArgumentValidationTelemetryEvent | undefined;\n\ttry {\n\t\tconst preparedToolCall = prepareToolCallArguments(tool, toolCall);\n\t\tconst validatedArgs = validateToolArguments(tool, preparedToolCall, {\n\t\t\tmodel: config.model.id,\n\t\t\tprovider: config.model.provider,\n\t\t\trepairEnabled: !isToolArgumentRepairEmergencyDisabled(),\n\t\t\ttelemetry: (event) => {\n\t\t\t\tvalidationEvent = event;\n\t\t\t},\n\t\t});\n\t\tresetValidationFailureTracker(validationFailureTracker);\n\t\tif (preparedToolCall.repairNotes) {\n\t\t\ttoolCall.repairNotes = preparedToolCall.repairNotes;\n\t\t}\n\t\tif (validatedArgs !== toolCall.arguments) {\n\t\t\ttoolCall.rawArguments ??= toolCall.arguments;\n\t\t\ttoolCall.arguments = validatedArgs;\n\t\t}\n\t\tif (config.beforeToolCall) {\n\t\t\tconst beforeResult = await config.beforeToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall,\n\t\t\t\t\targs: validatedArgs,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(beforeResult.reason || \"Tool execution was blocked\"),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tvalidationEvent,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (signal?.aborted) {\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\t\t\tisError: true,\n\t\t\t\tvalidationEvent,\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"prepared\",\n\t\t\ttoolCall,\n\t\t\ttool,\n\t\t\targs: validatedArgs,\n\t\t\tvalidationEvent,\n\t\t};\n\t} catch (error) {\n\t\tconst message = isToolArgumentValidationError(error)\n\t\t\t? handleValidationFailure(error, config, validationFailureTracker)\n\t\t\t: error instanceof Error\n\t\t\t\t? error.message\n\t\t\t\t: String(error);\n\t\treturn {\n\t\t\tkind: \"immediate\",\n\t\t\tresult: createErrorToolResult(message),\n\t\t\tisError: true,\n\t\t\tvalidationEvent,\n\t\t};\n\t}\n}\n\nasync function executePreparedToolCall(\n\tprepared: PreparedToolCall,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<ExecutedToolCallOutcome> {\n\tconst updateEvents: Promise<void>[] = [];\n\n\ttry {\n\t\tconst result = await prepared.tool.execute(\n\t\t\tprepared.toolCall.id,\n\t\t\tprepared.args as never,\n\t\t\tsignal,\n\t\t\t(partialResult) => {\n\t\t\t\tupdateEvents.push(\n\t\t\t\t\tPromise.resolve(\n\t\t\t\t\t\temit({\n\t\t\t\t\t\t\ttype: \"tool_execution_update\",\n\t\t\t\t\t\t\ttoolCallId: prepared.toolCall.id,\n\t\t\t\t\t\t\ttoolName: prepared.toolCall.name,\n\t\t\t\t\t\t\targs: prepared.toolCall.arguments,\n\t\t\t\t\t\t\tpartialResult,\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t},\n\t\t);\n\t\tawait Promise.all(updateEvents);\n\t\treturn { result, isError: false };\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\treturn {\n\t\t\tresult: createErrorToolResultWithGuidance(message),\n\t\t\tisError: true,\n\t\t\terrorClass: error instanceof Error ? error.name : typeof error,\n\t\t};\n\t}\n}\n\nfunction repairTeachKey(toolName: string, note: string): string {\n\tconst repairName = /^\\[harness\\] ([^:]+):/.exec(note)?.[1] ?? note;\n\treturn `${toolName}\\0${repairName}`;\n}\n\nfunction shouldEmitRepairTeachNote(toolName: string, note: string, tracker: ToolRepairTeachTracker): boolean {\n\tconst key = repairTeachKey(toolName, note);\n\tconst count = (tracker.get(key) ?? 0) + 1;\n\ttracker.set(key, count);\n\treturn count === 1 || count % TOOL_REPAIR_TEACH_EVERY === 0;\n}\n\nfunction appendRepairTeachNotes(\n\tresult: AgentToolResult<any>,\n\ttoolCall: AgentToolCall,\n\ttracker: ToolRepairTeachTracker,\n\tconfig: AgentLoopConfig,\n): { result: AgentToolResult<any>; taught: boolean } {\n\tif (config.toolArgumentTeachEnabled === false) return { result, taught: false };\n\tconst notes = (toolCall.repairNotes ?? []).filter((note) => shouldEmitRepairTeachNote(toolCall.name, note, tracker));\n\tif (notes.length === 0) return { result, taught: false };\n\treturn {\n\t\tresult: {\n\t\t\t...result,\n\t\t\tcontent: [...result.content, { type: \"text\", text: notes.join(\"\\n\") }],\n\t\t},\n\t\ttaught: true,\n\t};\n}\n\nfunction resetExecutionFailureTracker(tracker: ToolExecutionFailureTracker): void {\n\ttracker.signature = undefined;\n\ttracker.repeats = 0;\n}\n\nfunction executionFailureSignature(prepared: PreparedToolCall, errorClass: string): string {\n\treturn `${normalizeToolSignature([[prepared.toolCall.name, prepared.args]])}\\0${errorClass}`;\n}\n\nfunction appendExecutionFailureTeachNote(\n\tresult: AgentToolResult<any>,\n\tprepared: PreparedToolCall,\n\terrorClass: string | undefined,\n\ttracker: ToolExecutionFailureTracker,\n): AgentToolResult<any> {\n\tconst signature = executionFailureSignature(prepared, errorClass ?? \"tool-error\");\n\tif (tracker.signature === signature) {\n\t\ttracker.repeats++;\n\t} else {\n\t\ttracker.signature = signature;\n\t\ttracker.repeats = 1;\n\t}\n\tif (tracker.repeats !== TOOL_EXECUTION_FAILURE_TEACH_AT || tracker.taughtSignature === signature) return result;\n\ttracker.taughtSignature = signature;\n\treturn {\n\t\t...result,\n\t\tcontent: [\n\t\t\t{\n\t\t\t\ttype: \"text\",\n\t\t\t\ttext: `[harness] This exact ${prepared.toolCall.name} call failed twice with the same ${errorClass ?? \"tool\"} error. Change the arguments or approach; do not resend the identical call.`,\n\t\t\t},\n\t\t\t...result.content,\n\t\t],\n\t};\n}\n\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\texecutionFailureTracker: ToolExecutionFailureTracker,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\n\tif (config.afterToolCall) {\n\t\ttry {\n\t\t\tconst afterResult = await config.afterToolCall(\n\t\t\t\t{\n\t\t\t\t\tassistantMessage,\n\t\t\t\t\ttoolCall: prepared.toolCall,\n\t\t\t\t\targs: prepared.args,\n\t\t\t\t\tresult,\n\t\t\t\t\tisError,\n\t\t\t\t\tcontext: currentContext,\n\t\t\t\t},\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (afterResult) {\n\t\t\t\tresult = {\n\t\t\t\t\tcontent: afterResult.content ?? result.content,\n\t\t\t\t\tdetails: afterResult.details ?? result.details,\n\t\t\t\t\tterminate: afterResult.terminate ?? result.terminate,\n\t\t\t\t};\n\t\t\t\tisError = afterResult.isError ?? isError;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tresult = createErrorToolResult(error instanceof Error ? error.message : String(error));\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\tif (isError) {\n\t\tresult = appendExecutionFailureTeachNote(result, prepared, executed.errorClass, executionFailureTracker);\n\t} else {\n\t\tresetExecutionFailureTracker(executionFailureTracker);\n\t}\n\n\tconst repaired = appendRepairTeachNotes(result, prepared.toolCall, repairTeachTracker, config);\n\temitToolArgumentValidationTelemetry(\n\t\tconfig,\n\t\tprepared.validationEvent,\n\t\tisError ? \"failed\" : \"succeeded\",\n\t\trepaired.taught ? \"note\" : \"none\",\n\t);\n\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult: repaired.result,\n\t\tisError,\n\t};\n}\n\nfunction createErrorToolResult(message: string): AgentToolResult<any> {\n\treturn {\n\t\tcontent: [{ type: \"text\", text: message }],\n\t\tdetails: {},\n\t};\n}\n\nfunction createErrorToolResultWithGuidance(message: string): AgentToolResult<any> {\n\tconst guidance = getToolExecutionErrorGuidance(message);\n\tif (!guidance) return createErrorToolResult(message);\n\treturn {\n\t\tcontent: [\n\t\t\t{ type: \"text\", text: message },\n\t\t\t{ type: \"text\", text: `[harness] ${guidance}` },\n\t\t],\n\t\tdetails: {},\n\t};\n}\n\nasync function emitToolExecutionStart(toolCall: AgentToolCall, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_start\",\n\t\ttoolCallId: toolCall.id,\n\t\ttoolName: toolCall.name,\n\t\targs: toolCall.arguments,\n\t\trepair: getToolCallRepairInfo(toolCall),\n\t});\n}\n\nfunction getToolCallRepairInfo(toolCall: AgentToolCall): ToolCallRepairInfo | undefined {\n\tif (!toolCall.rawArguments && !toolCall.repairNotes?.length) return undefined;\n\treturn {\n\t\trepaired: true,\n\t\t...(toolCall.rawArguments ? { rawArguments: toolCall.rawArguments } : {}),\n\t\t...(toolCall.repairNotes?.length ? { notes: toolCall.repairNotes } : {}),\n\t};\n}\n\nasync function emitToolExecutionEnd(finalized: FinalizedToolCallOutcome, emit: AgentEventSink): Promise<void> {\n\tawait emit({\n\t\ttype: \"tool_execution_end\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tresult: finalized.result,\n\t\tisError: finalized.isError,\n\t\trepair: getToolCallRepairInfo(finalized.toolCall),\n\t});\n}\n\nfunction createToolResultMessage(finalized: FinalizedToolCallOutcome): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: finalized.toolCall.id,\n\t\ttoolName: finalized.toolCall.name,\n\t\tcontent: finalized.result.content,\n\t\tdetails: finalized.result.details,\n\t\tisError: finalized.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\n\nasync function emitToolResultMessage(toolResultMessage: ToolResultMessage, emit: AgentEventSink): Promise<void> {\n\tawait emit({ type: \"message_start\", message: toolResultMessage });\n\tawait emit({ type: \"message_end\", message: toolResultMessage });\n}\n"]}
|
package/dist/agent.d.ts
CHANGED
|
@@ -15,7 +15,6 @@ export interface AgentOptions {
|
|
|
15
15
|
beforeToolCall?: (context: BeforeToolCallContext, signal?: AbortSignal) => Promise<BeforeToolCallResult | undefined>;
|
|
16
16
|
afterToolCall?: (context: AfterToolCallContext, signal?: AbortSignal) => Promise<AfterToolCallResult | undefined>;
|
|
17
17
|
onToolArgumentValidation?: (event: ToolArgumentValidationTelemetryEvent) => void;
|
|
18
|
-
toolArgumentRepairEnabled?: boolean;
|
|
19
18
|
toolArgumentTeachEnabled?: boolean;
|
|
20
19
|
toolValidationEscalationThreshold?: number;
|
|
21
20
|
onToolValidationEscalation?: AgentLoopConfig["onToolValidationEscalation"];
|
|
@@ -51,7 +50,6 @@ export declare class Agent {
|
|
|
51
50
|
beforeToolCall?: (context: BeforeToolCallContext, signal?: AbortSignal) => Promise<BeforeToolCallResult | undefined>;
|
|
52
51
|
afterToolCall?: (context: AfterToolCallContext, signal?: AbortSignal) => Promise<AfterToolCallResult | undefined>;
|
|
53
52
|
onToolArgumentValidation?: (event: ToolArgumentValidationTelemetryEvent) => void;
|
|
54
|
-
toolArgumentRepairEnabled?: boolean;
|
|
55
53
|
toolArgumentTeachEnabled?: boolean;
|
|
56
54
|
toolValidationEscalationThreshold?: number;
|
|
57
55
|
onToolValidationEscalation?: AgentLoopConfig["onToolValidationEscalation"];
|