@caupulican/pi-agent-core 0.96.0 → 0.96.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAmC7D,OAAO,EAAE,uBAAuB,EAAsC,MAAM,iCAAiC,CAAC;AAE9G,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAGZ,aAAa,EAGb,QAAQ,EACR,kBAAkB,EAElB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACN,0BAA0B,EAC1B,sBAAsB,EACtB,gCAAgC,GAChC,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAKzE,gGAAgG;AAChG,MAAM,WAAW,0BAA0B;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB,EAAE,uBAAuB,CAAC;CACjD;AAED,wBAAgB,gCAAgC,IAAI,0BAA0B,CAE7E;AAED;;;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,CAEzC;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,CAIzC;AAuBD,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,EACnB,iBAAiB,GAAE,0BAA+D,GAChF,OAAO,CAAC,YAAY,EAAE,CAAC,CAwBzB;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,EACnB,iBAAiB,GAAE,0BAA+D,GAChF,OAAO,CAAC,YAAY,EAAE,CAAC,CAezB;AAsWD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAExC;AA6lCD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,kBAAkB,GAAG,SAAS,CAO7F"}
1
+ {"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../src/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAmC7D,OAAO,EAAE,uBAAuB,EAAsC,MAAM,iCAAiC,CAAC;AAE9G,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAGZ,aAAa,EAGb,QAAQ,EACR,kBAAkB,EAElB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACN,0BAA0B,EAC1B,sBAAsB,EACtB,gCAAgC,GAChC,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAKzE,gGAAgG;AAChG,MAAM,WAAW,0BAA0B;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,uBAAuB,EAAE,uBAAuB,CAAC;CACjD;AAED,wBAAgB,gCAAgC,IAAI,0BAA0B,CAE7E;AAED;;;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,CAEzC;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,CAIzC;AAuBD,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,EACnB,iBAAiB,GAAE,0BAA+D,GAChF,OAAO,CAAC,YAAY,EAAE,CAAC,CAwBzB;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,EACnB,iBAAiB,GAAE,0BAA+D,GAChF,OAAO,CAAC,YAAY,EAAE,CAAC,CAezB;AAyXD;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,WAAW,GAAG,SAAS,EAC/B,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAExC;AA6lCD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,kBAAkB,GAAG,SAAS,CAO7F"}
@@ -125,12 +125,30 @@ async function emitProviderTurnLimitStop(config, continuationState, newMessages,
125
125
  await emit({ type: "agent_end", messages: newMessages });
126
126
  }
127
127
  /**
128
- * How many `stallLimit`-length periods the runaway-loop window spans. A window of `stallLimit * P`
129
- * turns lets the count-based detector catch oscillating cycles of period up to `P` (each signature in a
130
- * period-k cycle recurs ~window/k times), not just back-to-back repeats. Beyond this the cycle is loose
131
- * enough that it's indistinguishable from legitimate varied work, so we don't chase it.
128
+ * Maximum exact cycle width inspected by the runaway-loop backstop. Detection requires the complete
129
+ * suffix pattern to repeat `stallLimit` times; recurring housekeeping calls among distinct productive
130
+ * operations therefore never look like a loop merely because one signature is frequent.
132
131
  */
133
132
  const STALL_WINDOW_PERIODS = 4;
133
+ function repeatsToolCallPattern(stallWindow, stallLimit) {
134
+ if (stallLimit <= 0)
135
+ return false;
136
+ const maxPeriod = Math.min(STALL_WINDOW_PERIODS, Math.floor(stallWindow.length / stallLimit));
137
+ for (let period = 1; period <= maxPeriod; period++) {
138
+ const requiredTurns = period * stallLimit;
139
+ const start = stallWindow.length - requiredTurns;
140
+ let matches = true;
141
+ for (let offset = period; offset < requiredTurns; offset++) {
142
+ if (stallWindow[start + offset] !== stallWindow[start + (offset % period)]) {
143
+ matches = false;
144
+ break;
145
+ }
146
+ }
147
+ if (matches)
148
+ return true;
149
+ }
150
+ return false;
151
+ }
134
152
  function textProtocolOperationArguments(toolCall) {
135
153
  const args = toolCall.arguments;
136
154
  if (!args || typeof args !== "object" || Array.isArray(args))
@@ -207,10 +225,12 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
207
225
  if (pendingMessages.length === 0)
208
226
  return;
209
227
  lastSuccessfulTextProtocolBatch = undefined;
210
- // A new user turn can change authority, intent, or the workspace itself, so every
211
- // operation that was blocked as an unproductive replay becomes worth attempting again.
212
- toolFailureRecoveryGate.noteWorldAdvance();
228
+ // Only an owner/user turn can change authority or intent. Internal custom steering and
229
+ // follow-up messages must not re-admit a known-bad unchanged operation. Count every owner
230
+ // message so live admission stays byte-for-byte aligned with transcript restoration.
213
231
  for (const message of pendingMessages) {
232
+ if (message.role === "user")
233
+ toolFailureRecoveryGate.noteWorldAdvance();
214
234
  await emit({ type: "message_start", message });
215
235
  await emit({ type: "message_end", message });
216
236
  currentContext.messages.push(message);
@@ -282,15 +302,16 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
282
302
  lastSuccessfulTextProtocolBatch = undefined;
283
303
  }
284
304
  await emit({ type: "turn_end", message, toolResults });
285
- // Runaway-loop backstop (cost guard): detect a model stuck repeating one action.
305
+ // Runaway-loop backstop (cost guard): detect only a repeated suffix cycle. Counting
306
+ // signatures anywhere in the window falsely stopped progressing workflows whose status
307
+ // checks recurred among distinct edits, reads, and verification operations.
286
308
  if (stallLimit > 0 && toolCalls.length > 0) {
287
309
  const signature = normalizeToolSignature(toolCalls.map((c) => [c.name, c.arguments ?? null]));
288
310
  stallWindow.push(signature);
289
311
  if (stallWindow.length > stallLimit * STALL_WINDOW_PERIODS)
290
312
  stallWindow.shift();
291
- const repeats = stallWindow.reduce((n, s) => (s === signature ? n + 1 : n), 0);
292
- if (repeats >= stallLimit) {
293
- config.onRunawayStop?.({ reason: "repeated_tool_call", signature, repeats });
313
+ if (repeatsToolCallPattern(stallWindow, stallLimit)) {
314
+ config.onRunawayStop?.({ reason: "repeated_tool_call", signature, repeats: stallLimit });
294
315
  await streamToollessClosingTurn(currentContext, newMessages, config, continuationState, providerTurnLimit, signal, emit, streamFn);
295
316
  await emit({ type: "agent_end", messages: newMessages });
296
317
  return;
@@ -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 { EventStream } from \"@caupulican/pi-ai/event-stream\";\nimport {\n\tformatToolRepairStandingRule,\n\tREPEATED_SUCCESSFUL_TOOL_CALL_FAILURE,\n\ttype ToolFailurePhase,\n} from \"@caupulican/pi-ai/tool-repair-registry\";\nimport type { AssistantMessage, ToolResultMessage } from \"@caupulican/pi-ai/types\";\nimport {\n\ttype ToolArgumentExecutionOutcome,\n\tToolArgumentValidationError,\n\ttype ToolArgumentValidationTelemetryEvent,\n\tvalidateToolArguments,\n} from \"@caupulican/pi-ai/validation\";\nimport {\n\tassistantMessageText,\n\tcollapseDegenerateAssistantMessage,\n\tshouldAbortDegenerateStream,\n} from \"./degenerate-assistant-text.ts\";\nimport {\n\tstartPlannedAgentProviderRequest,\n\tstartPlannedAgentProviderRequestWithId,\n} from \"./provider-request-planner.ts\";\nimport {\n\tassessToolFailure,\n\tclearToolFailure,\n\tcreateRepeatedToolFailureResult,\n\tcreateToolFailureMemoryTracker,\n\tcreateToolFailureResult,\n\tdescribeOperationOutcome,\n\tgetUnresolvedToolFailure,\n\tnormalizeToolSignature,\n\trememberToolFailure,\n\ttype ToolFailureMemoryTracker,\n\ttoolFailureCorrection,\n} from \"./tool-failure-memory.ts\";\nimport { ToolFailureRecoveryGate, type ToolFailureRecoveryGateEffect } from \"./tool-failure-recovery-gate.ts\";\nimport { rejectNativeToolProtocolResidue, rejectToolCallsFromToolFreeResponse } from \"./tool-protocol-residue.ts\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentRequestId,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolErrorKind,\n\tAgentToolResult,\n\tStreamFn,\n\tToolCallRepairInfo,\n\tToolCallStartContext,\n} from \"./types.ts\";\nimport { AgentToolExecutionError, DEFAULT_MAX_PROVIDER_TURNS, DEFAULT_MAX_STALL_TURNS } from \"./types.ts\";\nimport { createEmptyUsage } from \"./usage.ts\";\n\nexport {\n\tcomposeRequestSystemPrompt,\n\tnarrowRequestMaxTokens,\n\tresolveRequestPreflightMaxTokens,\n} from \"./provider-request-planner.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/** Bound simultaneous tool starts without imposing a failure-count or operation-count stop. */\nconst TOOL_EXECUTION_WAVE_SIZE = 4;\n\n/** Bounded no-progress state retained across host-owned continuations of one logical prompt. */\nexport interface AgentLoopContinuationState {\n\tproviderTurns: number;\n\tstallWindow: string[];\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate;\n}\n\nexport function createAgentLoopContinuationState(): AgentLoopContinuationState {\n\treturn { providerTurns: 0, stallWindow: [], toolFailureRecoveryGate: new ToolFailureRecoveryGate() };\n}\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\treturn streamAgentLoop(config, signal, (emit) => runAgentLoop(prompts, context, config, emit, signal, streamFn));\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\tassertContinuableContext(context);\n\n\treturn streamAgentLoop(config, signal, (emit) => runAgentLoopContinue(context, config, emit, signal, streamFn));\n}\n\nfunction streamAgentLoop(\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\trun: (emit: AgentEventSink) => Promise<AgentMessage[]>,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\tvoid run(async (event) => {\n\t\tstream.push(event);\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\tcontinuationState: AgentLoopContinuationState = createAgentLoopContinuationState(),\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\tif (providerTurnLimitReached(config, continuationState)) {\n\t\tfor (const prompt of prompts) {\n\t\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\t\tawait emit({ type: \"message_end\", message: prompt });\n\t\t}\n\t\tawait emitProviderTurnLimitStop(config, continuationState, newMessages, emit);\n\t\treturn newMessages;\n\t}\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, continuationState);\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\tcontinuationState: AgentLoopContinuationState = createAgentLoopContinuationState(),\n): Promise<AgentMessage[]> {\n\tassertContinuableContext(context);\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context, messages: [...context.messages] };\n\n\tawait emit({ type: \"agent_start\" });\n\tif (providerTurnLimitReached(config, continuationState)) {\n\t\tawait emitProviderTurnLimitStop(config, continuationState, newMessages, emit);\n\t\treturn newMessages;\n\t}\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn, continuationState);\n\treturn newMessages;\n}\n\nfunction assertContinuableContext(context: AgentContext): void {\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\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\nfunction providerTurnLimitReached(config: AgentLoopConfig, continuationState: AgentLoopContinuationState): boolean {\n\tconst limit = config.maxProviderTurns ?? DEFAULT_MAX_PROVIDER_TURNS;\n\treturn limit > 0 && continuationState.providerTurns >= limit;\n}\n\nasync function emitProviderTurnLimitStop(\n\tconfig: AgentLoopConfig,\n\tcontinuationState: AgentLoopContinuationState,\n\tnewMessages: AgentMessage[],\n\temit: AgentEventSink,\n): Promise<void> {\n\tconfig.onRunawayStop?.({\n\t\treason: \"provider_turn_limit\",\n\t\tsignature: \"provider_turn_limit\",\n\t\trepeats: continuationState.providerTurns,\n\t});\n\tawait emit({ type: \"agent_end\", messages: newMessages });\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\nfunction textProtocolOperationArguments(toolCall: AgentToolCall): unknown {\n\tconst args: unknown = toolCall.arguments;\n\tif (!args || typeof args !== \"object\" || Array.isArray(args)) return args ?? null;\n\tconst record = args as Record<string, unknown>;\n\tif ((toolCall.name === \"write\" || toolCall.name === \"edit\") && typeof record.path === \"string\") {\n\t\treturn { path: record.path };\n\t}\n\treturn args;\n}\n\nfunction textProtocolBatchSignature(toolCalls: readonly AgentToolCall[]): string {\n\treturn normalizeToolSignature(\n\t\ttoolCalls.map((toolCall) => [toolCall.name, textProtocolOperationArguments(toolCall)]),\n\t);\n}\n\nfunction toolCallRecord(toolCall: AgentToolCall): Record<string, unknown> | undefined {\n\tconst args: unknown = toolCall.arguments;\n\treturn args && typeof args === \"object\" && !Array.isArray(args) ? (args as Record<string, unknown>) : undefined;\n}\n\nfunction toolResultPhase(result: ToolResultMessage): string | undefined {\n\tif (!result.details || typeof result.details !== \"object\" || Array.isArray(result.details)) return undefined;\n\tconst phase = (result.details as Record<string, unknown>).phase;\n\treturn typeof phase === \"string\" ? phase : undefined;\n}\n\nfunction repeatsSuccessfulTextProtocolBatch(\n\tincomingSignature: string,\n\ttoolCalls: readonly AgentToolCall[],\n\tprevious: SuccessfulTextProtocolBatch | undefined,\n): boolean {\n\tif (!previous) return false;\n\tif (incomingSignature === previous.signature) return true;\n\tif (toolCalls.length !== previous.calls.length || toolCalls.length !== previous.messages.length) return false;\n\treturn toolCalls.every((toolCall, index) => {\n\t\tconst previousCall = previous.calls[index];\n\t\tconst previousResult = previous.messages[index];\n\t\tif (!previousCall || !previousResult) return false;\n\t\tconst currentArgs = toolCallRecord(toolCall);\n\t\tconst previousArgs = toolCallRecord(previousCall);\n\t\tif (currentArgs?.path !== previousArgs?.path) return false;\n\t\tconst phase = toolResultPhase(previousResult);\n\t\tif (phase === \"written\") return toolCall.name === \"write\" && previousCall.name === \"write\";\n\t\treturn phase === \"edited\" && toolCall.name === \"edit\" && previousCall.name === \"edit\";\n\t});\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\tcontinuationState: AgentLoopContinuationState = createAgentLoopContinuationState(),\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 providerTurnLimit = config.maxProviderTurns ?? DEFAULT_MAX_PROVIDER_TURNS;\n\tconst stallWindow = continuationState.stallWindow;\n\tconst validationFailureTracker: ToolValidationFailureTracker = { repeats: 0 };\n\tconst repairTeachTracker: ToolRepairTeachTracker = new Map();\n\tlet toolFailureMemory = createToolFailureMemoryTracker(currentContext.messages);\n\tconst toolFailureRecoveryGate = continuationState.toolFailureRecoveryGate;\n\ttoolFailureRecoveryGate.restoreFromMessages(currentContext.messages);\n\tlet lastSuccessfulTextProtocolBatch: SuccessfulTextProtocolBatch | undefined;\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\tconst processPendingMessages = async (): Promise<void> => {\n\t\tif (pendingMessages.length === 0) return;\n\t\tlastSuccessfulTextProtocolBatch = undefined;\n\t\t// A new user turn can change authority, intent, or the workspace itself, so every\n\t\t// operation that was blocked as an unproductive replay becomes worth attempting again.\n\t\ttoolFailureRecoveryGate.noteWorldAdvance();\n\t\tfor (const message of pendingMessages) {\n\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\tcurrentContext.messages.push(message);\n\t\t\tnewMessages.push(message);\n\t\t}\n\t\tpendingMessages = [];\n\t};\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 (providerTurnLimit > 0 && continuationState.providerTurns >= providerTurnLimit) {\n\t\t\t\t// Preserve already-dequeued steering, but do not announce an assistant turn that will\n\t\t\t\t// never start. A turn is one provider response plus its tools/results.\n\t\t\t\tawait processPendingMessages();\n\t\t\t\tawait emitProviderTurnLimitStop(config, continuationState, newMessages, emit);\n\t\t\t\treturn;\n\t\t\t}\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\tawait processPendingMessages();\n\t\t\tcontinuationState.providerTurns++;\n\t\t\tconst response = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tconst message = response.message;\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 textProtocolBatch = toolCalls.every((toolCall) => toolCall.source === \"text-protocol\");\n\t\t\t\tconst incomingBatchSignature = textProtocolBatchSignature(toolCalls);\n\t\t\t\tconst previousSuccessfulTextProtocolResults =\n\t\t\t\t\ttextProtocolBatch &&\n\t\t\t\t\trepeatsSuccessfulTextProtocolBatch(incomingBatchSignature, toolCalls, lastSuccessfulTextProtocolBatch)\n\t\t\t\t\t\t? lastSuccessfulTextProtocolBatch?.messages\n\t\t\t\t\t\t: undefined;\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\tresponse.requestId,\n\t\t\t\t\tconfig,\n\t\t\t\t\tvalidationFailureTracker,\n\t\t\t\t\trepairTeachTracker,\n\t\t\t\t\ttoolFailureMemory,\n\t\t\t\t\ttoolFailureRecoveryGate,\n\t\t\t\t\tpreviousSuccessfulTextProtocolResults,\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\tif (!previousSuccessfulTextProtocolResults) {\n\t\t\t\t\tlastSuccessfulTextProtocolBatch =\n\t\t\t\t\t\ttextProtocolBatch &&\n\t\t\t\t\t\ttoolResults.length === toolCalls.length &&\n\t\t\t\t\t\ttoolResults.every((result) => !result.isError)\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tsignature: textProtocolBatchSignature(toolCalls),\n\t\t\t\t\t\t\t\t\tmessages: toolResults,\n\t\t\t\t\t\t\t\t\tcalls: toolCalls,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlastSuccessfulTextProtocolBatch = undefined;\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?.({ reason: \"repeated_tool_call\", signature, repeats });\n\t\t\t\t\tawait streamToollessClosingTurn(\n\t\t\t\t\t\tcurrentContext,\n\t\t\t\t\t\tnewMessages,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tcontinuationState,\n\t\t\t\t\t\tproviderTurnLimit,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\temit,\n\t\t\t\t\t\tstreamFn,\n\t\t\t\t\t);\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\tif (nextTurnSnapshot.context) {\n\t\t\t\t\ttoolFailureMemory = createToolFailureMemoryTracker(currentContext.messages);\n\t\t\t\t}\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: nextTurnSnapshot.thinkingLevel ?? config.reasoning,\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\nconst RUNAWAY_STOP_CLOSING_SYSTEM_PROMPT = [\n\t\"RUNAWAY STOP CLOSING TURN\",\n\t\"The host stopped a repeated tool-call loop. No tools are available in this final request.\",\n\t\"Write one concise factual closing message for the user: completed work, the unresolved operation or blocker, and the safest next action.\",\n\t\"Do not claim unperformed work. Do not emit a tool call or tool-call markup.\",\n].join(\"\\n\");\n\n/**\n * Spend one final provider request, with no tools, so a stopped run closes in the model's own words.\n *\n * The harness never writes that message itself. Tools are removed from the request, so this request\n * cannot open another tool batch and cannot re-enter the loop; it runs through the same planned\n * provider boundary as every other request. If the run is aborted, or the configured provider-turn\n * limit leaves no budget, the run ends with no closing message rather than a fabricated one — and a\n * provider error keeps its own error message for the same reason.\n */\nasync function streamToollessClosingTurn(\n\tcurrentContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tconfig: AgentLoopConfig,\n\tcontinuationState: AgentLoopContinuationState,\n\tproviderTurnLimit: number,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tif (signal?.aborted) return;\n\tif (providerTurnLimit > 0 && continuationState.providerTurns >= providerTurnLimit) return;\n\tcontinuationState.providerTurns++;\n\tawait emit({ type: \"turn_start\" });\n\tconst closingContext: AgentContext = {\n\t\t...currentContext,\n\t\tsystemPrompt: currentContext.systemPrompt\n\t\t\t? `${currentContext.systemPrompt}\\n\\n${RUNAWAY_STOP_CLOSING_SYSTEM_PROMPT}`\n\t\t\t: RUNAWAY_STOP_CLOSING_SYSTEM_PROMPT,\n\t\ttools: [],\n\t};\n\tconst response = await streamAssistantResponse(closingContext, config, signal, emit, streamFn, {\n\t\trejectToolCalls: true,\n\t});\n\tconst message = response.message;\n\tnewMessages.push(message);\n\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n}\n\n/**\n * Start one provider request through the canonical agent-loop boundary.\n *\n * All callers, including host-owned tool-free finalization, receive the same failure-context\n * sanitization, context transformation/conversion, dynamic authentication, request-local reasoning,\n * and request preflight immediately before transport.\n */\nexport async function startAgentProviderRequest(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstreamFn?: StreamFn,\n): Promise<Awaited<ReturnType<StreamFn>>> {\n\treturn startPlannedAgentProviderRequest(context, config, signal, streamFn);\n}\n\ntype StartedAssistantResponse = {\n\tmessage: AssistantMessage;\n\trequestId: AgentRequestId;\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\tpolicy?: { rejectToolCalls: boolean },\n): Promise<StartedAssistantResponse> {\n\tconst degenerationAbort = new AbortController();\n\tconst onOuterAbort = (): void => degenerationAbort.abort();\n\tif (signal?.aborted) degenerationAbort.abort();\n\telse signal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\tconst response = await startPlannedAgentProviderRequestWithId(context, config, degenerationAbort.signal, streamFn);\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\tlet abortedForDegeneration = false;\n\n\tresponseEvents: for await (const event of response.stream) {\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\tif (\n\t\t\t\t\t\t!abortedForDegeneration &&\n\t\t\t\t\t\t!signal?.aborted &&\n\t\t\t\t\t\t!partialMessage.content.some((block) => block.type === \"toolCall\") &&\n\t\t\t\t\t\tshouldAbortDegenerateStream(assistantMessageText(partialMessage))\n\t\t\t\t\t) {\n\t\t\t\t\t\tabortedForDegeneration = true;\n\t\t\t\t\t\tdegenerationAbort.abort();\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\tbreak responseEvents;\n\t\t}\n\t}\n\n\tsignal?.removeEventListener(\"abort\", onOuterAbort);\n\tconst providerMessage = await response.stream.result();\n\tlet finalMessage = policy?.rejectToolCalls\n\t\t? rejectToolCallsFromToolFreeResponse(providerMessage)\n\t\t: rejectNativeToolProtocolResidue(providerMessage, context.tools ?? [], Boolean(config.textToolCallProtocol));\n\tif (abortedForDegeneration && !signal?.aborted && finalMessage.stopReason === \"aborted\") {\n\t\tfinalMessage = { ...finalMessage, stopReason: \"stop\" };\n\t\tdelete finalMessage.errorMessage;\n\t}\n\tfinalMessage = collapseDegenerateAssistantMessage(finalMessage);\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 { message: finalMessage, requestId: response.requestId };\n}\n\ninterface ToolExecutionContext {\n\tcontext: AgentContext;\n\tassistantMessage: AssistantMessage;\n\trequestId: AgentRequestId;\n\tconfig: AgentLoopConfig;\n\tvalidationFailureTracker: ToolValidationFailureTracker;\n\trepairTeachTracker: ToolRepairTeachTracker;\n\ttoolFailureMemory: ToolFailureMemoryTracker;\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate;\n\tpreviousSuccessfulResults?: readonly ToolResultMessage[];\n\tsignal?: AbortSignal;\n\temit: AgentEventSink;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\trequestId: AgentRequestId,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tpreviousSuccessfulTextProtocolResults: readonly ToolResultMessage[] | undefined,\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\tconst execCtx: ToolExecutionContext = {\n\t\tcontext: currentContext,\n\t\tassistantMessage,\n\t\trequestId,\n\t\tconfig,\n\t\tvalidationFailureTracker,\n\t\trepairTeachTracker,\n\t\ttoolFailureMemory,\n\t\ttoolFailureRecoveryGate,\n\t\tpreviousSuccessfulResults: previousSuccessfulTextProtocolResults,\n\t\tsignal,\n\t\temit,\n\t};\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(execCtx, toolCalls);\n\t}\n\treturn executeToolCallsParallel(execCtx, toolCalls);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\ntype SuccessfulTextProtocolBatch = {\n\tsignature: string;\n\tmessages: readonly ToolResultMessage[];\n\tcalls: readonly AgentToolCall[];\n};\n\ntype StartedToolCall =\n\t| { kind: \"finalized\"; finalized: FinalizedToolCallOutcome }\n\t| { kind: \"prepared\"; preparation: PreparedToolCall };\n\nasync function prepareAndStartToolCall(\n\texecCtx: ToolExecutionContext,\n\ttoolCall: AgentToolCall,\n\tindex: number,\n): Promise<StartedToolCall> {\n\tconst preparation = execCtx.previousSuccessfulResults\n\t\t? createRepeatedSuccessfulToolCallOutcome(execCtx.previousSuccessfulResults[index])\n\t\t: await prepareToolCall(\n\t\t\t\texecCtx.context,\n\t\t\t\texecCtx.assistantMessage,\n\t\t\t\ttoolCall,\n\t\t\t\texecCtx.config,\n\t\t\t\texecCtx.validationFailureTracker,\n\t\t\t\texecCtx.toolFailureMemory,\n\t\t\t\texecCtx.toolFailureRecoveryGate,\n\t\t\t\texecCtx.signal,\n\t\t\t\texecCtx.requestId,\n\t\t\t);\n\tif (preparation.kind === \"immediate\") {\n\t\tawait emitToolExecutionStart(toolCall, execCtx.emit);\n\t\temitToolArgumentValidationTelemetry(execCtx.config, preparation.validationEvent, \"not_run\", \"none\");\n\t\treturn {\n\t\t\tkind: \"finalized\",\n\t\t\tfinalized: finalizeRejectedToolCall(\n\t\t\t\ttoolCall,\n\t\t\t\texecCtx.context.tools?.find((tool) => tool.name === toolCall.name),\n\t\t\t\tpreparation,\n\t\t\t\texecCtx.toolFailureMemory,\n\t\t\t),\n\t\t};\n\t}\n\treturn { kind: \"prepared\", preparation };\n}\n\nasync function finalizeStartedToolCall(\n\texecCtx: ToolExecutionContext,\n\tstarted: StartedToolCall,\n): Promise<FinalizedToolCallOutcome> {\n\tif (started.kind === \"finalized\") return started.finalized;\n\treturn executeAndFinalizePreparedToolCall(\n\t\texecCtx.context,\n\t\texecCtx.assistantMessage,\n\t\tstarted.preparation,\n\t\texecCtx.requestId,\n\t\texecCtx.config,\n\t\texecCtx.repairTeachTracker,\n\t\texecCtx.toolFailureMemory,\n\t\texecCtx.toolFailureRecoveryGate,\n\t\texecCtx.signal,\n\t\texecCtx.emit,\n\t);\n}\n\nasync function reservePreparedToolCalls(\n\texecCtx: ToolExecutionContext,\n\tpreparedCalls: readonly PreparedToolCall[],\n): Promise<void> {\n\tif (preparedCalls.length === 0) return;\n\texecCtx.signal?.throwIfAborted();\n\tif (execCtx.config.onToolCallStart) {\n\t\tconst calls: ToolCallStartContext[] = preparedCalls.map((prepared) => ({\n\t\t\trequestId: execCtx.requestId,\n\t\t\tcallId: prepared.toolCall.id,\n\t\t\ttoolName: prepared.toolCall.name,\n\t\t\tassistantMessage: execCtx.assistantMessage,\n\t\t\ttoolCall: prepared.toolCall,\n\t\t\targs: prepared.args,\n\t\t\tcontext: execCtx.context,\n\t\t}));\n\t\tawait execCtx.config.onToolCallStart(calls, execCtx.signal);\n\t}\n\texecCtx.signal?.throwIfAborted();\n\tfor (const prepared of preparedCalls) {\n\t\tawait emitToolExecutionStart(prepared.toolCall, execCtx.emit);\n\t}\n}\n\nasync function executeToolCallsSequential(\n\texecCtx: ToolExecutionContext,\n\ttoolCalls: AgentToolCall[],\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const [index, toolCall] of toolCalls.entries()) {\n\t\tconst started = await prepareAndStartToolCall(execCtx, toolCall, index);\n\t\tif (started.kind === \"prepared\") {\n\t\t\tawait reservePreparedToolCalls(execCtx, [started.preparation]);\n\t\t}\n\t\tconst finalized = await finalizeStartedToolCall(execCtx, started);\n\t\texecCtx.toolFailureRecoveryGate.apply(finalized.executionGateEffect);\n\n\t\tawait emitToolExecutionEnd(finalized, execCtx.emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, execCtx.emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (execCtx.signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn { messages, terminate: shouldTerminateToolBatch(finalizedCalls) };\n}\n\nasync function executeToolCallsParallel(\n\texecCtx: ToolExecutionContext,\n\ttoolCalls: AgentToolCall[],\n): Promise<ExecutedToolCallBatch> {\n\tconst orderedFinalizedCalls: FinalizedToolCallOutcome[] = [];\n\tlet nextIndex = 0;\n\t// Account each bounded concurrent wave before launching more calls. This controls concurrency;\n\t// admission remains operation-specific and does not stop unrelated work after failures.\n\twhile (nextIndex < toolCalls.length && !execCtx.signal?.aborted) {\n\t\tconst waveEnd = Math.min(nextIndex + TOOL_EXECUTION_WAVE_SIZE, toolCalls.length);\n\t\tconst wave: FinalizedToolCallEntry[] = [];\n\t\tconst preparedWave: PreparedToolCall[] = [];\n\t\tconst completionOrder: FinalizedToolCallOutcome[] = [];\n\t\tfor (; nextIndex < waveEnd; nextIndex++) {\n\t\t\tconst toolCall = toolCalls[nextIndex];\n\t\t\tconst started = await prepareAndStartToolCall(execCtx, toolCall, nextIndex);\n\t\t\tif (started.kind === \"finalized\") {\n\t\t\t\tawait emitToolExecutionEnd(started.finalized, execCtx.emit);\n\t\t\t\twave.push(started.finalized);\n\t\t\t} else {\n\t\t\t\tpreparedWave.push(started.preparation);\n\t\t\t\twave.push(async () => {\n\t\t\t\t\tconst finalized = await finalizeStartedToolCall(execCtx, started);\n\t\t\t\t\tcompletionOrder.push(finalized);\n\t\t\t\t\treturn finalized;\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (execCtx.signal?.aborted) {\n\t\t\t\tnextIndex++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tawait reservePreparedToolCalls(execCtx, preparedWave);\n\n\t\tconst finalizedWave = await Promise.all(\n\t\t\twave.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t\t);\n\t\tfor (const finalized of finalizedWave) execCtx.toolFailureRecoveryGate.apply(finalized.executionGateEffect);\n\t\tfor (const finalized of completionOrder) {\n\t\t\tawait emitToolExecutionEnd(finalized, execCtx.emit);\n\t\t}\n\t\torderedFinalizedCalls.push(...finalizedWave);\n\t}\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, execCtx.emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn { messages, terminate: shouldTerminateToolBatch(orderedFinalizedCalls) };\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\tphase: ToolFailurePhase;\n\tfailureCode: string;\n\tcorrection: string;\n\tdiagnostic?: string;\n\trepeatedSuccessfulCall?: { previousToolCallId: string };\n\trepeatedToolFailure?: boolean;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\terrorClass?: string;\n\tfailureMessage?: string;\n\tfailureCode?: string;\n\toutputSignature?: string;\n\terrorKind?: AgentToolErrorKind;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\texecutionGateEffect?: ToolFailureRecoveryGateEffect;\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\nconst DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD = 3;\nconst TOOL_REPAIR_TEACH_EVERY = 5;\nconst REPEATED_SUCCESS_RESULT_MAX_CHARS = 2_048;\n\nfunction createRepeatedSuccessfulToolCallOutcome(\n\tpreviousResult: ToolResultMessage | undefined,\n): ImmediateToolCallOutcome {\n\tconst previousText = previousResult?.content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\")\n\t\t.slice(0, REPEATED_SUCCESS_RESULT_MAX_CHARS);\n\tconst diagnostic = previousText\n\t\t? `${REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.diagnostic} Previous successful result: ${previousText}`\n\t\t: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.diagnostic;\n\treturn {\n\t\tkind: \"immediate\",\n\t\tresult: createErrorToolResult(diagnostic),\n\t\tisError: true,\n\t\tphase: \"execution\",\n\t\tfailureCode: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.failureCode,\n\t\tcorrection: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.guidance,\n\t\tdiagnostic,\n\t\t...(previousResult ? { repeatedSuccessfulCall: { previousToolCallId: previousResult.toolCallId } } : {}),\n\t};\n}\n\nfunction createAbortedToolCallOutcome(\n\tvalidationEvent: ToolArgumentValidationTelemetryEvent | undefined,\n): ImmediateToolCallOutcome {\n\treturn {\n\t\tkind: \"immediate\",\n\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\tisError: true,\n\t\tphase: \"cancelled\",\n\t\tfailureCode: \"aborted\",\n\t\tcorrection: \"Retry only if the operation is still required.\",\n\t\tvalidationEvent,\n\t};\n}\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 validationFailureCorrection(\n\tevent: ToolArgumentValidationTelemetryEvent | undefined,\n\ttoolName: string,\n): string {\n\tconst shape = event?.failureShape\n\t\t?.slice(0, 3)\n\t\t.map((entry) => `${entry.path}: expected ${entry.expectedType}, received ${entry.receivedType}`)\n\t\t.join(\"; \");\n\tconst rules = [\n\t\t...new Set(\n\t\t\t(event?.failureModes ?? [])\n\t\t\t\t.filter((mode) => mode !== \"other\")\n\t\t\t\t.map((mode) => formatToolRepairStandingRule(mode)),\n\t\t),\n\t];\n\treturn [`Match ${toolName} arguments to its current schema.`, shape ? `Fix ${shape}.` : undefined, ...rules]\n\t\t.filter((part): part is string => part !== undefined)\n\t\t.join(\" \");\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\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tsignal: AbortSignal | undefined,\n\trequestId: AgentRequestId,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tconst tool = currentContext.tools?.find((candidate) => candidate.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\tphase: \"validation\",\n\t\t\tfailureCode: \"unknown_tool\",\n\t\t\tcorrection: \"Choose a tool from the currently available tool list.\",\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\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\tphase: \"validation\",\n\t\t\tfailureCode: \"malformed_call\",\n\t\t\tcorrection: \"Resend one complete JSON argument object matching the current tool schema.\",\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"malformed_call\"),\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\tconst unresolvedRecord = getUnresolvedToolFailure(toolFailureMemory, toolCall.name, validatedArgs);\n\t\tconst admission = toolFailureRecoveryGate.admit(tool, validatedArgs, unresolvedRecord, currentContext.messages);\n\t\tif (admission.kind === \"blocked\") {\n\t\t\tconst result = createRepeatedToolFailureResult(admission.record);\n\t\t\tconst memoryRecord = result.details.piToolFailureMemory;\n\t\t\ttoolFailureMemory.set(admission.record.failureKey, memoryRecord);\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult,\n\t\t\t\tisError: true,\n\t\t\t\tphase: admission.record.phase,\n\t\t\t\tfailureCode: \"repeated_failed_operation\",\n\t\t\t\tcorrection: memoryRecord.correction,\n\t\t\t\tdiagnostic: memoryRecord.diagnostic,\n\t\t\t\trepeatedToolFailure: true,\n\t\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"repeated_failed_operation\"),\n\t\t\t};\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\trequestId,\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 createAbortedToolCallOutcome(validationEvent);\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\tconst reason = beforeResult.reason || \"Tool execution was blocked\";\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(reason),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tphase: \"policy\",\n\t\t\t\t\tfailureCode: \"blocked\",\n\t\t\t\t\tcorrection: \"Choose an allowed approach or request the required authority before retrying.\",\n\t\t\t\t\tdiagnostic: reason,\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 createAbortedToolCallOutcome(validationEvent);\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\tphase: isToolArgumentValidationError(error) ? \"validation\" : \"preflight\",\n\t\t\tfailureCode: isToolArgumentValidationError(error) ? \"invalid_arguments\" : \"preflight_error\",\n\t\t\tcorrection: isToolArgumentValidationError(error)\n\t\t\t\t? validationFailureCorrection(validationEvent, toolCall.name)\n\t\t\t\t: toolFailureCorrection(message, \"rejected\", \"preflight\"),\n\t\t\tdiagnostic: isToolArgumentValidationError(error) ? undefined : message,\n\t\t\tvalidationEvent,\n\t\t};\n\t}\n}\n\nfunction finalizeRejectedToolCall(\n\ttoolCall: AgentToolCall,\n\ttool: AgentTool<any> | undefined,\n\toutcome: ImmediateToolCallOutcome,\n\ttracker: ToolFailureMemoryTracker,\n): FinalizedToolCallOutcome {\n\tif (outcome.repeatedToolFailure) {\n\t\treturn {\n\t\t\ttoolCall,\n\t\t\tresult: outcome.result,\n\t\t\tisError: true,\n\t\t};\n\t}\n\tconst record = rememberToolFailure(\n\t\ttracker,\n\t\ttoolCall.name,\n\t\ttoolCall.arguments,\n\t\t\"rejected\",\n\t\toutcome.failureCode,\n\t\toutcome.correction,\n\t\toutcome.diagnostic,\n\t\toutcome.phase,\n\t\tundefined,\n\t\t{\n\t\t\toutput: outcome.result.content\n\t\t\t\t.filter((block) => block.type === \"text\")\n\t\t\t\t.map((block) => block.text)\n\t\t\t\t.join(\"\\n\"),\n\t\t},\n\t);\n\tconst failureResult = createToolFailureResult(record, outcome.result.terminate);\n\treturn {\n\t\ttoolCall,\n\t\tresult: outcome.repeatedSuccessfulCall\n\t\t\t? {\n\t\t\t\t\t...failureResult,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\t...failureResult.details,\n\t\t\t\t\t\tpiRepeatedSuccessfulCall: outcome.repeatedSuccessfulCall,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: failureResult,\n\t\tisError: true,\n\t\texecutionGateEffect: {\n\t\t\tkind: \"unproductive\",\n\t\t\t...(tool ? { tool } : {}),\n\t\t\trecord,\n\t\t\targs: toolCall.arguments,\n\t\t},\n\t};\n}\n\ntype LinkedToolAbort = {\n\tsignal: AbortSignal;\n\tdetachForeground(): void;\n\tcancel(): void;\n};\n\nfunction createLinkedToolAbort(foregroundSignal: AbortSignal | undefined): LinkedToolAbort {\n\tconst controller = new AbortController();\n\tconst abortFromForeground = (): void => controller.abort(foregroundSignal?.reason);\n\tlet linked = false;\n\tif (foregroundSignal?.aborted) {\n\t\tabortFromForeground();\n\t} else if (foregroundSignal) {\n\t\tforegroundSignal.addEventListener(\"abort\", abortFromForeground, { once: true });\n\t\tlinked = true;\n\t}\n\treturn {\n\t\tsignal: controller.signal,\n\t\tdetachForeground: () => {\n\t\t\tif (!linked || !foregroundSignal) return;\n\t\t\tforegroundSignal.removeEventListener(\"abort\", abortFromForeground);\n\t\t\tlinked = false;\n\t\t},\n\t\tcancel: () => controller.abort(),\n\t};\n}\n\nfunction getBackgroundToolCallDelay(config: AgentLoopConfig): number | undefined {\n\tconst delay = config.backgroundToolCallAfterMs;\n\tif (delay === undefined || !Number.isFinite(delay) || delay <= 0) return undefined;\n\treturn delay;\n}\n\nasync function executeAndFinalizePreparedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\trequestId: AgentRequestId,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tforegroundSignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<FinalizedToolCallOutcome> {\n\tconst backgroundDelay = getBackgroundToolCallDelay(config);\n\tif (\n\t\t!config.handoffToolCall ||\n\t\t(backgroundDelay === undefined && config.subscribeToolCallHandoffRequest === undefined)\n\t) {\n\t\tconst executed = await executePreparedToolCall(prepared, foregroundSignal, emit);\n\t\treturn finalizeExecutedToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\tprepared,\n\t\t\trequestId,\n\t\t\texecuted,\n\t\t\tconfig,\n\t\t\trepairTeachTracker,\n\t\t\ttoolFailureMemory,\n\t\t\ttoolFailureRecoveryGate,\n\t\t\tforegroundSignal,\n\t\t);\n\t}\n\n\tconst executionAbort = createLinkedToolAbort(foregroundSignal);\n\tconst startedAt = Date.now();\n\tlet emitForegroundUpdates = true;\n\tconst completion = (async (): Promise<FinalizedToolCallOutcome> => {\n\t\tconst executed = await executePreparedToolCall(prepared, executionAbort.signal, (event) => {\n\t\t\tif (emitForegroundUpdates) return emit(event);\n\t\t});\n\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\tprepared,\n\t\t\trequestId,\n\t\t\texecuted,\n\t\t\tconfig,\n\t\t\trepairTeachTracker,\n\t\t\ttoolFailureMemory,\n\t\t\ttoolFailureRecoveryGate,\n\t\t\texecutionAbort.signal,\n\t\t);\n\t\treturn finalized;\n\t})();\n\tcompletion.then(executionAbort.detachForeground, executionAbort.detachForeground);\n\n\tlet deadlineTimer: ReturnType<typeof setTimeout> | undefined;\n\tconst triggers: Array<Promise<{ kind: \"deadline\" | \"manual\" }>> = [];\n\tif (backgroundDelay !== undefined) {\n\t\ttriggers.push(\n\t\t\tnew Promise<{ kind: \"deadline\" }>((resolve) => {\n\t\t\t\tdeadlineTimer = setTimeout(() => resolve({ kind: \"deadline\" }), backgroundDelay);\n\t\t\t\t(deadlineTimer as { unref?: () => void }).unref?.();\n\t\t\t}),\n\t\t);\n\t}\n\tlet unsubscribeHandoffRequest: (() => void) | undefined;\n\tif (config.subscribeToolCallHandoffRequest) {\n\t\tconst manual = new Promise<{ kind: \"manual\" }>((resolve) => {\n\t\t\ttry {\n\t\t\t\tunsubscribeHandoffRequest = config.subscribeToolCallHandoffRequest?.(prepared.toolCall.id, () =>\n\t\t\t\t\tresolve({ kind: \"manual\" }),\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\tunsubscribeHandoffRequest = undefined;\n\t\t\t}\n\t\t});\n\t\ttriggers.push(manual);\n\t}\n\tlet outcome: { kind: \"completed\"; value: FinalizedToolCallOutcome } | { kind: \"deadline\" | \"manual\" };\n\ttry {\n\t\toutcome = await Promise.race([completion.then((value) => ({ kind: \"completed\" as const, value })), ...triggers]);\n\t} finally {\n\t\tif (deadlineTimer !== undefined) clearTimeout(deadlineTimer);\n\t\tunsubscribeHandoffRequest?.();\n\t}\n\tif (outcome.kind === \"completed\") return outcome.value;\n\tif (executionAbort.signal.aborted) return completion;\n\n\tlet handoffAccepted = false;\n\t// A handed-off call leaves the batch, so the batch never applies its effect: the background\n\t// completion is the only place left that can tell the governor what this operation did.\n\tconst handedOffCompletion = completion.then((finalized) => {\n\t\tif (handoffAccepted) toolFailureRecoveryGate.apply(finalized.executionGateEffect);\n\t\treturn finalized;\n\t});\n\tvoid handedOffCompletion.catch(() => undefined);\n\tlet handoff: ReturnType<NonNullable<AgentLoopConfig[\"handoffToolCall\"]>>;\n\ttry {\n\t\thandoff = config.handoffToolCall({\n\t\t\trequestId,\n\t\t\tassistantMessage,\n\t\t\ttoolCall: prepared.toolCall,\n\t\t\targs: prepared.args,\n\t\t\tcontext: currentContext,\n\t\t\telapsedMs: Math.max(0, Date.now() - startedAt),\n\t\t\tcompletion: handedOffCompletion,\n\t\t\tcancel: executionAbort.cancel,\n\t\t});\n\t} catch {\n\t\treturn completion;\n\t}\n\thandoffAccepted = handoff !== undefined;\n\tif (!handoff) return completion;\n\n\temitForegroundUpdates = false;\n\texecutionAbort.detachForeground();\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult: handoff.result,\n\t\tisError: handoff.isError ?? handoff.result.isError === true,\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 {\n\t\t\tresult,\n\t\t\t// Tool definitions can report an expected operation failure without\n\t\t\t// throwing. Keep the returned result intact through afterToolCall so\n\t\t\t// policy hooks can inspect its bounded diagnostics and metadata.\n\t\t\tisError: result.isError === true,\n\t\t\t...(result.isError === true\n\t\t\t\t? { errorClass: \"tool_result_error\", errorKind: result.errorKind ?? \"tool_failure\" }\n\t\t\t\t: {}),\n\t\t};\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst toolFailure = error instanceof AgentToolExecutionError ? error : undefined;\n\t\treturn {\n\t\t\tresult: createErrorToolResult(message),\n\t\t\tisError: true,\n\t\t\terrorClass: error instanceof Error ? error.name : typeof error,\n\t\t\tfailureMessage: message,\n\t\t\terrorKind: toolFailure?.errorKind ?? \"tool_failure\",\n\t\t\t...(toolFailure ? { failureCode: toolFailure.failureCode, outputSignature: toolFailure.outputSignature } : {}),\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\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\trequestId: AgentRequestId,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\tlet failureMessage = executed.failureMessage ?? \"\";\n\tlet errorClass = executed.errorClass;\n\tlet failureCode = executed.failureCode;\n\tlet outputSignature = executed.outputSignature;\n\tlet errorKind = executed.errorKind;\n\tlet executionGateEffect: ToolFailureRecoveryGateEffect | undefined;\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\trequestId,\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\tusage: afterResult.usage ?? result.usage,\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\t// The hook itself failed, so nothing about the tool's own completed operation survives.\n\t\t\tfailureMessage = error instanceof Error ? error.message : String(error);\n\t\t\terrorClass = error instanceof Error ? error.name : typeof error;\n\t\t\tfailureCode = undefined;\n\t\t\toutputSignature = undefined;\n\t\t\terrorKind = \"tool_failure\";\n\t\t\tresult = { ...createErrorToolResult(failureMessage), usage: result.usage };\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\tif (isError) {\n\t\tconst usage = result.usage;\n\t\tconst failureOutput =\n\t\t\tfailureMessage ||\n\t\t\tresult.content\n\t\t\t\t.filter((block) => block.type === \"text\")\n\t\t\t\t.map((block) => block.text)\n\t\t\t\t.join(\"\\n\") ||\n\t\t\t\"Tool execution failed\";\n\t\tconst effectiveFailureMessage =\n\t\t\tfailureMessage || result.content.find((block) => block.type === \"text\")?.text || \"Tool execution failed\";\n\t\tconst assessment = assessToolFailure(effectiveFailureMessage, \"failed\", errorClass);\n\t\tconst effectiveFailureCode = failureCode ?? assessment.failureCode;\n\t\tif (errorKind === \"operation_outcome\") {\n\t\t\t// The tool ran the operation to completion; the non-zero status is the observation the\n\t\t\t// agent asked for. Nothing here is a mistake, so no failure record is remembered and the\n\t\t\t// tool's own output stands exactly as written. The governor still notes that repeating\n\t\t\t// this identical operation cannot say anything new until something else changes.\n\t\t\tclearToolFailure(toolFailureMemory, prepared.toolCall.name, prepared.args);\n\t\t\tresult = { ...result, errorKind: \"operation_outcome\", usage };\n\t\t\texecutionGateEffect = {\n\t\t\t\tkind: \"unproductive\",\n\t\t\t\ttool: prepared.tool,\n\t\t\t\trecord: describeOperationOutcome(\n\t\t\t\t\tprepared.toolCall.name,\n\t\t\t\t\tprepared.args,\n\t\t\t\t\teffectiveFailureCode,\n\t\t\t\t\tassessment.diagnostic,\n\t\t\t\t),\n\t\t\t\targs: prepared.args,\n\t\t\t};\n\t\t} else {\n\t\t\tconst recoveryPlan = toolFailureRecoveryGate.planFailure(\n\t\t\t\tprepared.tool,\n\t\t\t\tprepared.args,\n\t\t\t\t{ failureCode: effectiveFailureCode, message: effectiveFailureMessage },\n\t\t\t\tcurrentContext.tools ?? [],\n\t\t\t);\n\t\t\tconst correction = assessment.policyGuidance\n\t\t\t\t? `${assessment.policyGuidance} ${recoveryPlan.guidance}`\n\t\t\t\t: recoveryPlan.guidance;\n\t\t\tconst record = rememberToolFailure(\n\t\t\t\ttoolFailureMemory,\n\t\t\t\tprepared.toolCall.name,\n\t\t\t\tprepared.args,\n\t\t\t\t\"failed\",\n\t\t\t\teffectiveFailureCode,\n\t\t\t\tcorrection,\n\t\t\t\tassessment.diagnostic,\n\t\t\t\tassessment.phase,\n\t\t\t\trecoveryPlan.evidence ?? assessment.evidence,\n\t\t\t\t{ output: failureOutput, outputSignature },\n\t\t\t);\n\t\t\texecutionGateEffect = {\n\t\t\t\tkind: \"unproductive\",\n\t\t\t\ttool: prepared.tool,\n\t\t\t\trecord,\n\t\t\t\targs: prepared.args,\n\t\t\t};\n\t\t\tresult = { ...createToolFailureResult(record, result.terminate), usage };\n\t\t}\n\t} else {\n\t\tclearToolFailure(toolFailureMemory, prepared.toolCall.name, prepared.args);\n\t\tif (!executed.isError) {\n\t\t\texecutionGateEffect = {\n\t\t\t\tkind: \"success\",\n\t\t\t\ttool: prepared.tool,\n\t\t\t\targs: prepared.args,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst repaired = isError\n\t\t? { result, taught: false }\n\t\t: 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\texecutionGateEffect,\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\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\nexport function 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\tusage: finalized.result.usage,\n\t\tisError: finalized.isError,\n\t\t// Persisted so a reloaded transcript still separates a completed operation's own status from a\n\t\t// tool that could not run at all.\n\t\t...(finalized.isError && finalized.result.errorKind ? { errorKind: finalized.result.errorKind } : {}),\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 { EventStream } from \"@caupulican/pi-ai/event-stream\";\nimport {\n\tformatToolRepairStandingRule,\n\tREPEATED_SUCCESSFUL_TOOL_CALL_FAILURE,\n\ttype ToolFailurePhase,\n} from \"@caupulican/pi-ai/tool-repair-registry\";\nimport type { AssistantMessage, ToolResultMessage } from \"@caupulican/pi-ai/types\";\nimport {\n\ttype ToolArgumentExecutionOutcome,\n\tToolArgumentValidationError,\n\ttype ToolArgumentValidationTelemetryEvent,\n\tvalidateToolArguments,\n} from \"@caupulican/pi-ai/validation\";\nimport {\n\tassistantMessageText,\n\tcollapseDegenerateAssistantMessage,\n\tshouldAbortDegenerateStream,\n} from \"./degenerate-assistant-text.ts\";\nimport {\n\tstartPlannedAgentProviderRequest,\n\tstartPlannedAgentProviderRequestWithId,\n} from \"./provider-request-planner.ts\";\nimport {\n\tassessToolFailure,\n\tclearToolFailure,\n\tcreateRepeatedToolFailureResult,\n\tcreateToolFailureMemoryTracker,\n\tcreateToolFailureResult,\n\tdescribeOperationOutcome,\n\tgetUnresolvedToolFailure,\n\tnormalizeToolSignature,\n\trememberToolFailure,\n\ttype ToolFailureMemoryTracker,\n\ttoolFailureCorrection,\n} from \"./tool-failure-memory.ts\";\nimport { ToolFailureRecoveryGate, type ToolFailureRecoveryGateEffect } from \"./tool-failure-recovery-gate.ts\";\nimport { rejectNativeToolProtocolResidue, rejectToolCallsFromToolFreeResponse } from \"./tool-protocol-residue.ts\";\nimport type {\n\tAgentContext,\n\tAgentEvent,\n\tAgentLoopConfig,\n\tAgentMessage,\n\tAgentRequestId,\n\tAgentTool,\n\tAgentToolCall,\n\tAgentToolErrorKind,\n\tAgentToolResult,\n\tStreamFn,\n\tToolCallRepairInfo,\n\tToolCallStartContext,\n} from \"./types.ts\";\nimport { AgentToolExecutionError, DEFAULT_MAX_PROVIDER_TURNS, DEFAULT_MAX_STALL_TURNS } from \"./types.ts\";\nimport { createEmptyUsage } from \"./usage.ts\";\n\nexport {\n\tcomposeRequestSystemPrompt,\n\tnarrowRequestMaxTokens,\n\tresolveRequestPreflightMaxTokens,\n} from \"./provider-request-planner.ts\";\n\nexport type AgentEventSink = (event: AgentEvent) => Promise<void> | void;\n\n/** Bound simultaneous tool starts without imposing a failure-count or operation-count stop. */\nconst TOOL_EXECUTION_WAVE_SIZE = 4;\n\n/** Bounded no-progress state retained across host-owned continuations of one logical prompt. */\nexport interface AgentLoopContinuationState {\n\tproviderTurns: number;\n\tstallWindow: string[];\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate;\n}\n\nexport function createAgentLoopContinuationState(): AgentLoopContinuationState {\n\treturn { providerTurns: 0, stallWindow: [], toolFailureRecoveryGate: new ToolFailureRecoveryGate() };\n}\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\treturn streamAgentLoop(config, signal, (emit) => runAgentLoop(prompts, context, config, emit, signal, streamFn));\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\tassertContinuableContext(context);\n\n\treturn streamAgentLoop(config, signal, (emit) => runAgentLoopContinue(context, config, emit, signal, streamFn));\n}\n\nfunction streamAgentLoop(\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\trun: (emit: AgentEventSink) => Promise<AgentMessage[]>,\n): EventStream<AgentEvent, AgentMessage[]> {\n\tconst stream = createAgentStream();\n\tvoid run(async (event) => {\n\t\tstream.push(event);\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\tcontinuationState: AgentLoopContinuationState = createAgentLoopContinuationState(),\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\tif (providerTurnLimitReached(config, continuationState)) {\n\t\tfor (const prompt of prompts) {\n\t\t\tawait emit({ type: \"message_start\", message: prompt });\n\t\t\tawait emit({ type: \"message_end\", message: prompt });\n\t\t}\n\t\tawait emitProviderTurnLimitStop(config, continuationState, newMessages, emit);\n\t\treturn newMessages;\n\t}\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, continuationState);\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\tcontinuationState: AgentLoopContinuationState = createAgentLoopContinuationState(),\n): Promise<AgentMessage[]> {\n\tassertContinuableContext(context);\n\n\tconst newMessages: AgentMessage[] = [];\n\tconst currentContext: AgentContext = { ...context, messages: [...context.messages] };\n\n\tawait emit({ type: \"agent_start\" });\n\tif (providerTurnLimitReached(config, continuationState)) {\n\t\tawait emitProviderTurnLimitStop(config, continuationState, newMessages, emit);\n\t\treturn newMessages;\n\t}\n\tawait emit({ type: \"turn_start\" });\n\n\tawait runLoop(currentContext, newMessages, config, signal, emit, streamFn, continuationState);\n\treturn newMessages;\n}\n\nfunction assertContinuableContext(context: AgentContext): void {\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\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\nfunction providerTurnLimitReached(config: AgentLoopConfig, continuationState: AgentLoopContinuationState): boolean {\n\tconst limit = config.maxProviderTurns ?? DEFAULT_MAX_PROVIDER_TURNS;\n\treturn limit > 0 && continuationState.providerTurns >= limit;\n}\n\nasync function emitProviderTurnLimitStop(\n\tconfig: AgentLoopConfig,\n\tcontinuationState: AgentLoopContinuationState,\n\tnewMessages: AgentMessage[],\n\temit: AgentEventSink,\n): Promise<void> {\n\tconfig.onRunawayStop?.({\n\t\treason: \"provider_turn_limit\",\n\t\tsignature: \"provider_turn_limit\",\n\t\trepeats: continuationState.providerTurns,\n\t});\n\tawait emit({ type: \"agent_end\", messages: newMessages });\n}\n\n/**\n * Maximum exact cycle width inspected by the runaway-loop backstop. Detection requires the complete\n * suffix pattern to repeat `stallLimit` times; recurring housekeeping calls among distinct productive\n * operations therefore never look like a loop merely because one signature is frequent.\n */\nconst STALL_WINDOW_PERIODS = 4;\n\nfunction repeatsToolCallPattern(stallWindow: readonly string[], stallLimit: number): boolean {\n\tif (stallLimit <= 0) return false;\n\tconst maxPeriod = Math.min(STALL_WINDOW_PERIODS, Math.floor(stallWindow.length / stallLimit));\n\tfor (let period = 1; period <= maxPeriod; period++) {\n\t\tconst requiredTurns = period * stallLimit;\n\t\tconst start = stallWindow.length - requiredTurns;\n\t\tlet matches = true;\n\t\tfor (let offset = period; offset < requiredTurns; offset++) {\n\t\t\tif (stallWindow[start + offset] !== stallWindow[start + (offset % period)]) {\n\t\t\t\tmatches = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (matches) return true;\n\t}\n\treturn false;\n}\n\nfunction textProtocolOperationArguments(toolCall: AgentToolCall): unknown {\n\tconst args: unknown = toolCall.arguments;\n\tif (!args || typeof args !== \"object\" || Array.isArray(args)) return args ?? null;\n\tconst record = args as Record<string, unknown>;\n\tif ((toolCall.name === \"write\" || toolCall.name === \"edit\") && typeof record.path === \"string\") {\n\t\treturn { path: record.path };\n\t}\n\treturn args;\n}\n\nfunction textProtocolBatchSignature(toolCalls: readonly AgentToolCall[]): string {\n\treturn normalizeToolSignature(\n\t\ttoolCalls.map((toolCall) => [toolCall.name, textProtocolOperationArguments(toolCall)]),\n\t);\n}\n\nfunction toolCallRecord(toolCall: AgentToolCall): Record<string, unknown> | undefined {\n\tconst args: unknown = toolCall.arguments;\n\treturn args && typeof args === \"object\" && !Array.isArray(args) ? (args as Record<string, unknown>) : undefined;\n}\n\nfunction toolResultPhase(result: ToolResultMessage): string | undefined {\n\tif (!result.details || typeof result.details !== \"object\" || Array.isArray(result.details)) return undefined;\n\tconst phase = (result.details as Record<string, unknown>).phase;\n\treturn typeof phase === \"string\" ? phase : undefined;\n}\n\nfunction repeatsSuccessfulTextProtocolBatch(\n\tincomingSignature: string,\n\ttoolCalls: readonly AgentToolCall[],\n\tprevious: SuccessfulTextProtocolBatch | undefined,\n): boolean {\n\tif (!previous) return false;\n\tif (incomingSignature === previous.signature) return true;\n\tif (toolCalls.length !== previous.calls.length || toolCalls.length !== previous.messages.length) return false;\n\treturn toolCalls.every((toolCall, index) => {\n\t\tconst previousCall = previous.calls[index];\n\t\tconst previousResult = previous.messages[index];\n\t\tif (!previousCall || !previousResult) return false;\n\t\tconst currentArgs = toolCallRecord(toolCall);\n\t\tconst previousArgs = toolCallRecord(previousCall);\n\t\tif (currentArgs?.path !== previousArgs?.path) return false;\n\t\tconst phase = toolResultPhase(previousResult);\n\t\tif (phase === \"written\") return toolCall.name === \"write\" && previousCall.name === \"write\";\n\t\treturn phase === \"edited\" && toolCall.name === \"edit\" && previousCall.name === \"edit\";\n\t});\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\tcontinuationState: AgentLoopContinuationState = createAgentLoopContinuationState(),\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 providerTurnLimit = config.maxProviderTurns ?? DEFAULT_MAX_PROVIDER_TURNS;\n\tconst stallWindow = continuationState.stallWindow;\n\tconst validationFailureTracker: ToolValidationFailureTracker = { repeats: 0 };\n\tconst repairTeachTracker: ToolRepairTeachTracker = new Map();\n\tlet toolFailureMemory = createToolFailureMemoryTracker(currentContext.messages);\n\tconst toolFailureRecoveryGate = continuationState.toolFailureRecoveryGate;\n\ttoolFailureRecoveryGate.restoreFromMessages(currentContext.messages);\n\tlet lastSuccessfulTextProtocolBatch: SuccessfulTextProtocolBatch | undefined;\n\t// Check for steering messages at start (user may have typed while waiting)\n\tlet pendingMessages: AgentMessage[] = (await config.getSteeringMessages?.()) || [];\n\tconst processPendingMessages = async (): Promise<void> => {\n\t\tif (pendingMessages.length === 0) return;\n\t\tlastSuccessfulTextProtocolBatch = undefined;\n\t\t// Only an owner/user turn can change authority or intent. Internal custom steering and\n\t\t// follow-up messages must not re-admit a known-bad unchanged operation. Count every owner\n\t\t// message so live admission stays byte-for-byte aligned with transcript restoration.\n\t\tfor (const message of pendingMessages) {\n\t\t\tif (message.role === \"user\") toolFailureRecoveryGate.noteWorldAdvance();\n\t\t\tawait emit({ type: \"message_start\", message });\n\t\t\tawait emit({ type: \"message_end\", message });\n\t\t\tcurrentContext.messages.push(message);\n\t\t\tnewMessages.push(message);\n\t\t}\n\t\tpendingMessages = [];\n\t};\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 (providerTurnLimit > 0 && continuationState.providerTurns >= providerTurnLimit) {\n\t\t\t\t// Preserve already-dequeued steering, but do not announce an assistant turn that will\n\t\t\t\t// never start. A turn is one provider response plus its tools/results.\n\t\t\t\tawait processPendingMessages();\n\t\t\t\tawait emitProviderTurnLimitStop(config, continuationState, newMessages, emit);\n\t\t\t\treturn;\n\t\t\t}\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\tawait processPendingMessages();\n\t\t\tcontinuationState.providerTurns++;\n\t\t\tconst response = await streamAssistantResponse(currentContext, config, signal, emit, streamFn);\n\t\t\tconst message = response.message;\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 textProtocolBatch = toolCalls.every((toolCall) => toolCall.source === \"text-protocol\");\n\t\t\t\tconst incomingBatchSignature = textProtocolBatchSignature(toolCalls);\n\t\t\t\tconst previousSuccessfulTextProtocolResults =\n\t\t\t\t\ttextProtocolBatch &&\n\t\t\t\t\trepeatsSuccessfulTextProtocolBatch(incomingBatchSignature, toolCalls, lastSuccessfulTextProtocolBatch)\n\t\t\t\t\t\t? lastSuccessfulTextProtocolBatch?.messages\n\t\t\t\t\t\t: undefined;\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\tresponse.requestId,\n\t\t\t\t\tconfig,\n\t\t\t\t\tvalidationFailureTracker,\n\t\t\t\t\trepairTeachTracker,\n\t\t\t\t\ttoolFailureMemory,\n\t\t\t\t\ttoolFailureRecoveryGate,\n\t\t\t\t\tpreviousSuccessfulTextProtocolResults,\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\tif (!previousSuccessfulTextProtocolResults) {\n\t\t\t\t\tlastSuccessfulTextProtocolBatch =\n\t\t\t\t\t\ttextProtocolBatch &&\n\t\t\t\t\t\ttoolResults.length === toolCalls.length &&\n\t\t\t\t\t\ttoolResults.every((result) => !result.isError)\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tsignature: textProtocolBatchSignature(toolCalls),\n\t\t\t\t\t\t\t\t\tmessages: toolResults,\n\t\t\t\t\t\t\t\t\tcalls: toolCalls,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: undefined;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlastSuccessfulTextProtocolBatch = undefined;\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 only a repeated suffix cycle. Counting\n\t\t\t// signatures anywhere in the window falsely stopped progressing workflows whose status\n\t\t\t// checks recurred among distinct edits, reads, and verification operations.\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\tif (repeatsToolCallPattern(stallWindow, stallLimit)) {\n\t\t\t\t\tconfig.onRunawayStop?.({ reason: \"repeated_tool_call\", signature, repeats: stallLimit });\n\t\t\t\t\tawait streamToollessClosingTurn(\n\t\t\t\t\t\tcurrentContext,\n\t\t\t\t\t\tnewMessages,\n\t\t\t\t\t\tconfig,\n\t\t\t\t\t\tcontinuationState,\n\t\t\t\t\t\tproviderTurnLimit,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t\temit,\n\t\t\t\t\t\tstreamFn,\n\t\t\t\t\t);\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\tif (nextTurnSnapshot.context) {\n\t\t\t\t\ttoolFailureMemory = createToolFailureMemoryTracker(currentContext.messages);\n\t\t\t\t}\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: nextTurnSnapshot.thinkingLevel ?? config.reasoning,\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\nconst RUNAWAY_STOP_CLOSING_SYSTEM_PROMPT = [\n\t\"RUNAWAY STOP CLOSING TURN\",\n\t\"The host stopped a repeated tool-call loop. No tools are available in this final request.\",\n\t\"Write one concise factual closing message for the user: completed work, the unresolved operation or blocker, and the safest next action.\",\n\t\"Do not claim unperformed work. Do not emit a tool call or tool-call markup.\",\n].join(\"\\n\");\n\n/**\n * Spend one final provider request, with no tools, so a stopped run closes in the model's own words.\n *\n * The harness never writes that message itself. Tools are removed from the request, so this request\n * cannot open another tool batch and cannot re-enter the loop; it runs through the same planned\n * provider boundary as every other request. If the run is aborted, or the configured provider-turn\n * limit leaves no budget, the run ends with no closing message rather than a fabricated one — and a\n * provider error keeps its own error message for the same reason.\n */\nasync function streamToollessClosingTurn(\n\tcurrentContext: AgentContext,\n\tnewMessages: AgentMessage[],\n\tconfig: AgentLoopConfig,\n\tcontinuationState: AgentLoopContinuationState,\n\tproviderTurnLimit: number,\n\tsignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n\tstreamFn?: StreamFn,\n): Promise<void> {\n\tif (signal?.aborted) return;\n\tif (providerTurnLimit > 0 && continuationState.providerTurns >= providerTurnLimit) return;\n\tcontinuationState.providerTurns++;\n\tawait emit({ type: \"turn_start\" });\n\tconst closingContext: AgentContext = {\n\t\t...currentContext,\n\t\tsystemPrompt: currentContext.systemPrompt\n\t\t\t? `${currentContext.systemPrompt}\\n\\n${RUNAWAY_STOP_CLOSING_SYSTEM_PROMPT}`\n\t\t\t: RUNAWAY_STOP_CLOSING_SYSTEM_PROMPT,\n\t\ttools: [],\n\t};\n\tconst response = await streamAssistantResponse(closingContext, config, signal, emit, streamFn, {\n\t\trejectToolCalls: true,\n\t});\n\tconst message = response.message;\n\tnewMessages.push(message);\n\tawait emit({ type: \"turn_end\", message, toolResults: [] });\n}\n\n/**\n * Start one provider request through the canonical agent-loop boundary.\n *\n * All callers, including host-owned tool-free finalization, receive the same failure-context\n * sanitization, context transformation/conversion, dynamic authentication, request-local reasoning,\n * and request preflight immediately before transport.\n */\nexport async function startAgentProviderRequest(\n\tcontext: AgentContext,\n\tconfig: AgentLoopConfig,\n\tsignal: AbortSignal | undefined,\n\tstreamFn?: StreamFn,\n): Promise<Awaited<ReturnType<StreamFn>>> {\n\treturn startPlannedAgentProviderRequest(context, config, signal, streamFn);\n}\n\ntype StartedAssistantResponse = {\n\tmessage: AssistantMessage;\n\trequestId: AgentRequestId;\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\tpolicy?: { rejectToolCalls: boolean },\n): Promise<StartedAssistantResponse> {\n\tconst degenerationAbort = new AbortController();\n\tconst onOuterAbort = (): void => degenerationAbort.abort();\n\tif (signal?.aborted) degenerationAbort.abort();\n\telse signal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\tconst response = await startPlannedAgentProviderRequestWithId(context, config, degenerationAbort.signal, streamFn);\n\n\tlet partialMessage: AssistantMessage | null = null;\n\tlet addedPartial = false;\n\tlet abortedForDegeneration = false;\n\n\tresponseEvents: for await (const event of response.stream) {\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\tif (\n\t\t\t\t\t\t!abortedForDegeneration &&\n\t\t\t\t\t\t!signal?.aborted &&\n\t\t\t\t\t\t!partialMessage.content.some((block) => block.type === \"toolCall\") &&\n\t\t\t\t\t\tshouldAbortDegenerateStream(assistantMessageText(partialMessage))\n\t\t\t\t\t) {\n\t\t\t\t\t\tabortedForDegeneration = true;\n\t\t\t\t\t\tdegenerationAbort.abort();\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\tbreak responseEvents;\n\t\t}\n\t}\n\n\tsignal?.removeEventListener(\"abort\", onOuterAbort);\n\tconst providerMessage = await response.stream.result();\n\tlet finalMessage = policy?.rejectToolCalls\n\t\t? rejectToolCallsFromToolFreeResponse(providerMessage)\n\t\t: rejectNativeToolProtocolResidue(providerMessage, context.tools ?? [], Boolean(config.textToolCallProtocol));\n\tif (abortedForDegeneration && !signal?.aborted && finalMessage.stopReason === \"aborted\") {\n\t\tfinalMessage = { ...finalMessage, stopReason: \"stop\" };\n\t\tdelete finalMessage.errorMessage;\n\t}\n\tfinalMessage = collapseDegenerateAssistantMessage(finalMessage);\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 { message: finalMessage, requestId: response.requestId };\n}\n\ninterface ToolExecutionContext {\n\tcontext: AgentContext;\n\tassistantMessage: AssistantMessage;\n\trequestId: AgentRequestId;\n\tconfig: AgentLoopConfig;\n\tvalidationFailureTracker: ToolValidationFailureTracker;\n\trepairTeachTracker: ToolRepairTeachTracker;\n\ttoolFailureMemory: ToolFailureMemoryTracker;\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate;\n\tpreviousSuccessfulResults?: readonly ToolResultMessage[];\n\tsignal?: AbortSignal;\n\temit: AgentEventSink;\n}\n\n/**\n * Execute tool calls from an assistant message.\n */\nasync function executeToolCalls(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\trequestId: AgentRequestId,\n\tconfig: AgentLoopConfig,\n\tvalidationFailureTracker: ToolValidationFailureTracker,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tpreviousSuccessfulTextProtocolResults: readonly ToolResultMessage[] | undefined,\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\tconst execCtx: ToolExecutionContext = {\n\t\tcontext: currentContext,\n\t\tassistantMessage,\n\t\trequestId,\n\t\tconfig,\n\t\tvalidationFailureTracker,\n\t\trepairTeachTracker,\n\t\ttoolFailureMemory,\n\t\ttoolFailureRecoveryGate,\n\t\tpreviousSuccessfulResults: previousSuccessfulTextProtocolResults,\n\t\tsignal,\n\t\temit,\n\t};\n\tif (config.toolExecution === \"sequential\" || hasSequentialToolCall) {\n\t\treturn executeToolCallsSequential(execCtx, toolCalls);\n\t}\n\treturn executeToolCallsParallel(execCtx, toolCalls);\n}\n\ntype ExecutedToolCallBatch = {\n\tmessages: ToolResultMessage[];\n\tterminate: boolean;\n};\n\ntype SuccessfulTextProtocolBatch = {\n\tsignature: string;\n\tmessages: readonly ToolResultMessage[];\n\tcalls: readonly AgentToolCall[];\n};\n\ntype StartedToolCall =\n\t| { kind: \"finalized\"; finalized: FinalizedToolCallOutcome }\n\t| { kind: \"prepared\"; preparation: PreparedToolCall };\n\nasync function prepareAndStartToolCall(\n\texecCtx: ToolExecutionContext,\n\ttoolCall: AgentToolCall,\n\tindex: number,\n): Promise<StartedToolCall> {\n\tconst preparation = execCtx.previousSuccessfulResults\n\t\t? createRepeatedSuccessfulToolCallOutcome(execCtx.previousSuccessfulResults[index])\n\t\t: await prepareToolCall(\n\t\t\t\texecCtx.context,\n\t\t\t\texecCtx.assistantMessage,\n\t\t\t\ttoolCall,\n\t\t\t\texecCtx.config,\n\t\t\t\texecCtx.validationFailureTracker,\n\t\t\t\texecCtx.toolFailureMemory,\n\t\t\t\texecCtx.toolFailureRecoveryGate,\n\t\t\t\texecCtx.signal,\n\t\t\t\texecCtx.requestId,\n\t\t\t);\n\tif (preparation.kind === \"immediate\") {\n\t\tawait emitToolExecutionStart(toolCall, execCtx.emit);\n\t\temitToolArgumentValidationTelemetry(execCtx.config, preparation.validationEvent, \"not_run\", \"none\");\n\t\treturn {\n\t\t\tkind: \"finalized\",\n\t\t\tfinalized: finalizeRejectedToolCall(\n\t\t\t\ttoolCall,\n\t\t\t\texecCtx.context.tools?.find((tool) => tool.name === toolCall.name),\n\t\t\t\tpreparation,\n\t\t\t\texecCtx.toolFailureMemory,\n\t\t\t),\n\t\t};\n\t}\n\treturn { kind: \"prepared\", preparation };\n}\n\nasync function finalizeStartedToolCall(\n\texecCtx: ToolExecutionContext,\n\tstarted: StartedToolCall,\n): Promise<FinalizedToolCallOutcome> {\n\tif (started.kind === \"finalized\") return started.finalized;\n\treturn executeAndFinalizePreparedToolCall(\n\t\texecCtx.context,\n\t\texecCtx.assistantMessage,\n\t\tstarted.preparation,\n\t\texecCtx.requestId,\n\t\texecCtx.config,\n\t\texecCtx.repairTeachTracker,\n\t\texecCtx.toolFailureMemory,\n\t\texecCtx.toolFailureRecoveryGate,\n\t\texecCtx.signal,\n\t\texecCtx.emit,\n\t);\n}\n\nasync function reservePreparedToolCalls(\n\texecCtx: ToolExecutionContext,\n\tpreparedCalls: readonly PreparedToolCall[],\n): Promise<void> {\n\tif (preparedCalls.length === 0) return;\n\texecCtx.signal?.throwIfAborted();\n\tif (execCtx.config.onToolCallStart) {\n\t\tconst calls: ToolCallStartContext[] = preparedCalls.map((prepared) => ({\n\t\t\trequestId: execCtx.requestId,\n\t\t\tcallId: prepared.toolCall.id,\n\t\t\ttoolName: prepared.toolCall.name,\n\t\t\tassistantMessage: execCtx.assistantMessage,\n\t\t\ttoolCall: prepared.toolCall,\n\t\t\targs: prepared.args,\n\t\t\tcontext: execCtx.context,\n\t\t}));\n\t\tawait execCtx.config.onToolCallStart(calls, execCtx.signal);\n\t}\n\texecCtx.signal?.throwIfAborted();\n\tfor (const prepared of preparedCalls) {\n\t\tawait emitToolExecutionStart(prepared.toolCall, execCtx.emit);\n\t}\n}\n\nasync function executeToolCallsSequential(\n\texecCtx: ToolExecutionContext,\n\ttoolCalls: AgentToolCall[],\n): Promise<ExecutedToolCallBatch> {\n\tconst finalizedCalls: FinalizedToolCallOutcome[] = [];\n\tconst messages: ToolResultMessage[] = [];\n\n\tfor (const [index, toolCall] of toolCalls.entries()) {\n\t\tconst started = await prepareAndStartToolCall(execCtx, toolCall, index);\n\t\tif (started.kind === \"prepared\") {\n\t\t\tawait reservePreparedToolCalls(execCtx, [started.preparation]);\n\t\t}\n\t\tconst finalized = await finalizeStartedToolCall(execCtx, started);\n\t\texecCtx.toolFailureRecoveryGate.apply(finalized.executionGateEffect);\n\n\t\tawait emitToolExecutionEnd(finalized, execCtx.emit);\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, execCtx.emit);\n\t\tfinalizedCalls.push(finalized);\n\t\tmessages.push(toolResultMessage);\n\n\t\tif (execCtx.signal?.aborted) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn { messages, terminate: shouldTerminateToolBatch(finalizedCalls) };\n}\n\nasync function executeToolCallsParallel(\n\texecCtx: ToolExecutionContext,\n\ttoolCalls: AgentToolCall[],\n): Promise<ExecutedToolCallBatch> {\n\tconst orderedFinalizedCalls: FinalizedToolCallOutcome[] = [];\n\tlet nextIndex = 0;\n\t// Account each bounded concurrent wave before launching more calls. This controls concurrency;\n\t// admission remains operation-specific and does not stop unrelated work after failures.\n\twhile (nextIndex < toolCalls.length && !execCtx.signal?.aborted) {\n\t\tconst waveEnd = Math.min(nextIndex + TOOL_EXECUTION_WAVE_SIZE, toolCalls.length);\n\t\tconst wave: FinalizedToolCallEntry[] = [];\n\t\tconst preparedWave: PreparedToolCall[] = [];\n\t\tconst completionOrder: FinalizedToolCallOutcome[] = [];\n\t\tfor (; nextIndex < waveEnd; nextIndex++) {\n\t\t\tconst toolCall = toolCalls[nextIndex];\n\t\t\tconst started = await prepareAndStartToolCall(execCtx, toolCall, nextIndex);\n\t\t\tif (started.kind === \"finalized\") {\n\t\t\t\tawait emitToolExecutionEnd(started.finalized, execCtx.emit);\n\t\t\t\twave.push(started.finalized);\n\t\t\t} else {\n\t\t\t\tpreparedWave.push(started.preparation);\n\t\t\t\twave.push(async () => {\n\t\t\t\t\tconst finalized = await finalizeStartedToolCall(execCtx, started);\n\t\t\t\t\tcompletionOrder.push(finalized);\n\t\t\t\t\treturn finalized;\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (execCtx.signal?.aborted) {\n\t\t\t\tnextIndex++;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tawait reservePreparedToolCalls(execCtx, preparedWave);\n\n\t\tconst finalizedWave = await Promise.all(\n\t\t\twave.map((entry) => (typeof entry === \"function\" ? entry() : Promise.resolve(entry))),\n\t\t);\n\t\tfor (const finalized of finalizedWave) execCtx.toolFailureRecoveryGate.apply(finalized.executionGateEffect);\n\t\tfor (const finalized of completionOrder) {\n\t\t\tawait emitToolExecutionEnd(finalized, execCtx.emit);\n\t\t}\n\t\torderedFinalizedCalls.push(...finalizedWave);\n\t}\n\tconst messages: ToolResultMessage[] = [];\n\tfor (const finalized of orderedFinalizedCalls) {\n\t\tconst toolResultMessage = createToolResultMessage(finalized);\n\t\tawait emitToolResultMessage(toolResultMessage, execCtx.emit);\n\t\tmessages.push(toolResultMessage);\n\t}\n\n\treturn { messages, terminate: shouldTerminateToolBatch(orderedFinalizedCalls) };\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\tphase: ToolFailurePhase;\n\tfailureCode: string;\n\tcorrection: string;\n\tdiagnostic?: string;\n\trepeatedSuccessfulCall?: { previousToolCallId: string };\n\trepeatedToolFailure?: boolean;\n\tvalidationEvent?: ToolArgumentValidationTelemetryEvent;\n};\n\ntype ExecutedToolCallOutcome = {\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\terrorClass?: string;\n\tfailureMessage?: string;\n\tfailureCode?: string;\n\toutputSignature?: string;\n\terrorKind?: AgentToolErrorKind;\n};\n\ntype FinalizedToolCallOutcome = {\n\ttoolCall: AgentToolCall;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\texecutionGateEffect?: ToolFailureRecoveryGateEffect;\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\nconst DEFAULT_TOOL_VALIDATION_ESCALATION_THRESHOLD = 3;\nconst TOOL_REPAIR_TEACH_EVERY = 5;\nconst REPEATED_SUCCESS_RESULT_MAX_CHARS = 2_048;\n\nfunction createRepeatedSuccessfulToolCallOutcome(\n\tpreviousResult: ToolResultMessage | undefined,\n): ImmediateToolCallOutcome {\n\tconst previousText = previousResult?.content\n\t\t.filter((block) => block.type === \"text\")\n\t\t.map((block) => block.text)\n\t\t.join(\"\\n\")\n\t\t.slice(0, REPEATED_SUCCESS_RESULT_MAX_CHARS);\n\tconst diagnostic = previousText\n\t\t? `${REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.diagnostic} Previous successful result: ${previousText}`\n\t\t: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.diagnostic;\n\treturn {\n\t\tkind: \"immediate\",\n\t\tresult: createErrorToolResult(diagnostic),\n\t\tisError: true,\n\t\tphase: \"execution\",\n\t\tfailureCode: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.failureCode,\n\t\tcorrection: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.guidance,\n\t\tdiagnostic,\n\t\t...(previousResult ? { repeatedSuccessfulCall: { previousToolCallId: previousResult.toolCallId } } : {}),\n\t};\n}\n\nfunction createAbortedToolCallOutcome(\n\tvalidationEvent: ToolArgumentValidationTelemetryEvent | undefined,\n): ImmediateToolCallOutcome {\n\treturn {\n\t\tkind: \"immediate\",\n\t\tresult: createErrorToolResult(\"Operation aborted\"),\n\t\tisError: true,\n\t\tphase: \"cancelled\",\n\t\tfailureCode: \"aborted\",\n\t\tcorrection: \"Retry only if the operation is still required.\",\n\t\tvalidationEvent,\n\t};\n}\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 validationFailureCorrection(\n\tevent: ToolArgumentValidationTelemetryEvent | undefined,\n\ttoolName: string,\n): string {\n\tconst shape = event?.failureShape\n\t\t?.slice(0, 3)\n\t\t.map((entry) => `${entry.path}: expected ${entry.expectedType}, received ${entry.receivedType}`)\n\t\t.join(\"; \");\n\tconst rules = [\n\t\t...new Set(\n\t\t\t(event?.failureModes ?? [])\n\t\t\t\t.filter((mode) => mode !== \"other\")\n\t\t\t\t.map((mode) => formatToolRepairStandingRule(mode)),\n\t\t),\n\t];\n\treturn [`Match ${toolName} arguments to its current schema.`, shape ? `Fix ${shape}.` : undefined, ...rules]\n\t\t.filter((part): part is string => part !== undefined)\n\t\t.join(\" \");\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\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tsignal: AbortSignal | undefined,\n\trequestId: AgentRequestId,\n): Promise<PreparedToolCall | ImmediateToolCallOutcome> {\n\tconst tool = currentContext.tools?.find((candidate) => candidate.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\tphase: \"validation\",\n\t\t\tfailureCode: \"unknown_tool\",\n\t\t\tcorrection: \"Choose a tool from the currently available tool list.\",\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"unknown_tool\"),\n\t\t};\n\t}\n\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\tphase: \"validation\",\n\t\t\tfailureCode: \"malformed_call\",\n\t\t\tcorrection: \"Resend one complete JSON argument object matching the current tool schema.\",\n\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"malformed_call\"),\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\tconst unresolvedRecord = getUnresolvedToolFailure(toolFailureMemory, toolCall.name, validatedArgs);\n\t\tconst admission = toolFailureRecoveryGate.admit(tool, validatedArgs, unresolvedRecord, currentContext.messages);\n\t\tif (admission.kind === \"blocked\") {\n\t\t\tconst result = createRepeatedToolFailureResult(admission.record);\n\t\t\tconst memoryRecord = result.details.piToolFailureMemory;\n\t\t\ttoolFailureMemory.set(admission.record.failureKey, memoryRecord);\n\t\t\treturn {\n\t\t\t\tkind: \"immediate\",\n\t\t\t\tresult,\n\t\t\t\tisError: true,\n\t\t\t\tphase: admission.record.phase,\n\t\t\t\tfailureCode: \"repeated_failed_operation\",\n\t\t\t\tcorrection: memoryRecord.correction,\n\t\t\t\tdiagnostic: memoryRecord.diagnostic,\n\t\t\t\trepeatedToolFailure: true,\n\t\t\t\tvalidationEvent: createValidationBounceTelemetry(config, toolCall, \"repeated_failed_operation\"),\n\t\t\t};\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\trequestId,\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 createAbortedToolCallOutcome(validationEvent);\n\t\t\t}\n\t\t\tif (beforeResult?.block) {\n\t\t\t\tconst reason = beforeResult.reason || \"Tool execution was blocked\";\n\t\t\t\treturn {\n\t\t\t\t\tkind: \"immediate\",\n\t\t\t\t\tresult: createErrorToolResult(reason),\n\t\t\t\t\tisError: true,\n\t\t\t\t\tphase: \"policy\",\n\t\t\t\t\tfailureCode: \"blocked\",\n\t\t\t\t\tcorrection: \"Choose an allowed approach or request the required authority before retrying.\",\n\t\t\t\t\tdiagnostic: reason,\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 createAbortedToolCallOutcome(validationEvent);\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\tphase: isToolArgumentValidationError(error) ? \"validation\" : \"preflight\",\n\t\t\tfailureCode: isToolArgumentValidationError(error) ? \"invalid_arguments\" : \"preflight_error\",\n\t\t\tcorrection: isToolArgumentValidationError(error)\n\t\t\t\t? validationFailureCorrection(validationEvent, toolCall.name)\n\t\t\t\t: toolFailureCorrection(message, \"rejected\", \"preflight\"),\n\t\t\tdiagnostic: isToolArgumentValidationError(error) ? undefined : message,\n\t\t\tvalidationEvent,\n\t\t};\n\t}\n}\n\nfunction finalizeRejectedToolCall(\n\ttoolCall: AgentToolCall,\n\ttool: AgentTool<any> | undefined,\n\toutcome: ImmediateToolCallOutcome,\n\ttracker: ToolFailureMemoryTracker,\n): FinalizedToolCallOutcome {\n\tif (outcome.repeatedToolFailure) {\n\t\treturn {\n\t\t\ttoolCall,\n\t\t\tresult: outcome.result,\n\t\t\tisError: true,\n\t\t};\n\t}\n\tconst record = rememberToolFailure(\n\t\ttracker,\n\t\ttoolCall.name,\n\t\ttoolCall.arguments,\n\t\t\"rejected\",\n\t\toutcome.failureCode,\n\t\toutcome.correction,\n\t\toutcome.diagnostic,\n\t\toutcome.phase,\n\t\tundefined,\n\t\t{\n\t\t\toutput: outcome.result.content\n\t\t\t\t.filter((block) => block.type === \"text\")\n\t\t\t\t.map((block) => block.text)\n\t\t\t\t.join(\"\\n\"),\n\t\t},\n\t);\n\tconst failureResult = createToolFailureResult(record, outcome.result.terminate);\n\treturn {\n\t\ttoolCall,\n\t\tresult: outcome.repeatedSuccessfulCall\n\t\t\t? {\n\t\t\t\t\t...failureResult,\n\t\t\t\t\tdetails: {\n\t\t\t\t\t\t...failureResult.details,\n\t\t\t\t\t\tpiRepeatedSuccessfulCall: outcome.repeatedSuccessfulCall,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t: failureResult,\n\t\tisError: true,\n\t\texecutionGateEffect: {\n\t\t\tkind: \"unproductive\",\n\t\t\t...(tool ? { tool } : {}),\n\t\t\trecord,\n\t\t\targs: toolCall.arguments,\n\t\t},\n\t};\n}\n\ntype LinkedToolAbort = {\n\tsignal: AbortSignal;\n\tdetachForeground(): void;\n\tcancel(): void;\n};\n\nfunction createLinkedToolAbort(foregroundSignal: AbortSignal | undefined): LinkedToolAbort {\n\tconst controller = new AbortController();\n\tconst abortFromForeground = (): void => controller.abort(foregroundSignal?.reason);\n\tlet linked = false;\n\tif (foregroundSignal?.aborted) {\n\t\tabortFromForeground();\n\t} else if (foregroundSignal) {\n\t\tforegroundSignal.addEventListener(\"abort\", abortFromForeground, { once: true });\n\t\tlinked = true;\n\t}\n\treturn {\n\t\tsignal: controller.signal,\n\t\tdetachForeground: () => {\n\t\t\tif (!linked || !foregroundSignal) return;\n\t\t\tforegroundSignal.removeEventListener(\"abort\", abortFromForeground);\n\t\t\tlinked = false;\n\t\t},\n\t\tcancel: () => controller.abort(),\n\t};\n}\n\nfunction getBackgroundToolCallDelay(config: AgentLoopConfig): number | undefined {\n\tconst delay = config.backgroundToolCallAfterMs;\n\tif (delay === undefined || !Number.isFinite(delay) || delay <= 0) return undefined;\n\treturn delay;\n}\n\nasync function executeAndFinalizePreparedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\trequestId: AgentRequestId,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tforegroundSignal: AbortSignal | undefined,\n\temit: AgentEventSink,\n): Promise<FinalizedToolCallOutcome> {\n\tconst backgroundDelay = getBackgroundToolCallDelay(config);\n\tif (\n\t\t!config.handoffToolCall ||\n\t\t(backgroundDelay === undefined && config.subscribeToolCallHandoffRequest === undefined)\n\t) {\n\t\tconst executed = await executePreparedToolCall(prepared, foregroundSignal, emit);\n\t\treturn finalizeExecutedToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\tprepared,\n\t\t\trequestId,\n\t\t\texecuted,\n\t\t\tconfig,\n\t\t\trepairTeachTracker,\n\t\t\ttoolFailureMemory,\n\t\t\ttoolFailureRecoveryGate,\n\t\t\tforegroundSignal,\n\t\t);\n\t}\n\n\tconst executionAbort = createLinkedToolAbort(foregroundSignal);\n\tconst startedAt = Date.now();\n\tlet emitForegroundUpdates = true;\n\tconst completion = (async (): Promise<FinalizedToolCallOutcome> => {\n\t\tconst executed = await executePreparedToolCall(prepared, executionAbort.signal, (event) => {\n\t\t\tif (emitForegroundUpdates) return emit(event);\n\t\t});\n\t\tconst finalized = await finalizeExecutedToolCall(\n\t\t\tcurrentContext,\n\t\t\tassistantMessage,\n\t\t\tprepared,\n\t\t\trequestId,\n\t\t\texecuted,\n\t\t\tconfig,\n\t\t\trepairTeachTracker,\n\t\t\ttoolFailureMemory,\n\t\t\ttoolFailureRecoveryGate,\n\t\t\texecutionAbort.signal,\n\t\t);\n\t\treturn finalized;\n\t})();\n\tcompletion.then(executionAbort.detachForeground, executionAbort.detachForeground);\n\n\tlet deadlineTimer: ReturnType<typeof setTimeout> | undefined;\n\tconst triggers: Array<Promise<{ kind: \"deadline\" | \"manual\" }>> = [];\n\tif (backgroundDelay !== undefined) {\n\t\ttriggers.push(\n\t\t\tnew Promise<{ kind: \"deadline\" }>((resolve) => {\n\t\t\t\tdeadlineTimer = setTimeout(() => resolve({ kind: \"deadline\" }), backgroundDelay);\n\t\t\t\t(deadlineTimer as { unref?: () => void }).unref?.();\n\t\t\t}),\n\t\t);\n\t}\n\tlet unsubscribeHandoffRequest: (() => void) | undefined;\n\tif (config.subscribeToolCallHandoffRequest) {\n\t\tconst manual = new Promise<{ kind: \"manual\" }>((resolve) => {\n\t\t\ttry {\n\t\t\t\tunsubscribeHandoffRequest = config.subscribeToolCallHandoffRequest?.(prepared.toolCall.id, () =>\n\t\t\t\t\tresolve({ kind: \"manual\" }),\n\t\t\t\t);\n\t\t\t} catch {\n\t\t\t\tunsubscribeHandoffRequest = undefined;\n\t\t\t}\n\t\t});\n\t\ttriggers.push(manual);\n\t}\n\tlet outcome: { kind: \"completed\"; value: FinalizedToolCallOutcome } | { kind: \"deadline\" | \"manual\" };\n\ttry {\n\t\toutcome = await Promise.race([completion.then((value) => ({ kind: \"completed\" as const, value })), ...triggers]);\n\t} finally {\n\t\tif (deadlineTimer !== undefined) clearTimeout(deadlineTimer);\n\t\tunsubscribeHandoffRequest?.();\n\t}\n\tif (outcome.kind === \"completed\") return outcome.value;\n\tif (executionAbort.signal.aborted) return completion;\n\n\tlet handoffAccepted = false;\n\t// A handed-off call leaves the batch, so the batch never applies its effect: the background\n\t// completion is the only place left that can tell the governor what this operation did.\n\tconst handedOffCompletion = completion.then((finalized) => {\n\t\tif (handoffAccepted) toolFailureRecoveryGate.apply(finalized.executionGateEffect);\n\t\treturn finalized;\n\t});\n\tvoid handedOffCompletion.catch(() => undefined);\n\tlet handoff: ReturnType<NonNullable<AgentLoopConfig[\"handoffToolCall\"]>>;\n\ttry {\n\t\thandoff = config.handoffToolCall({\n\t\t\trequestId,\n\t\t\tassistantMessage,\n\t\t\ttoolCall: prepared.toolCall,\n\t\t\targs: prepared.args,\n\t\t\tcontext: currentContext,\n\t\t\telapsedMs: Math.max(0, Date.now() - startedAt),\n\t\t\tcompletion: handedOffCompletion,\n\t\t\tcancel: executionAbort.cancel,\n\t\t});\n\t} catch {\n\t\treturn completion;\n\t}\n\thandoffAccepted = handoff !== undefined;\n\tif (!handoff) return completion;\n\n\temitForegroundUpdates = false;\n\texecutionAbort.detachForeground();\n\treturn {\n\t\ttoolCall: prepared.toolCall,\n\t\tresult: handoff.result,\n\t\tisError: handoff.isError ?? handoff.result.isError === true,\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 {\n\t\t\tresult,\n\t\t\t// Tool definitions can report an expected operation failure without\n\t\t\t// throwing. Keep the returned result intact through afterToolCall so\n\t\t\t// policy hooks can inspect its bounded diagnostics and metadata.\n\t\t\tisError: result.isError === true,\n\t\t\t...(result.isError === true\n\t\t\t\t? { errorClass: \"tool_result_error\", errorKind: result.errorKind ?? \"tool_failure\" }\n\t\t\t\t: {}),\n\t\t};\n\t} catch (error) {\n\t\tawait Promise.all(updateEvents);\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tconst toolFailure = error instanceof AgentToolExecutionError ? error : undefined;\n\t\treturn {\n\t\t\tresult: createErrorToolResult(message),\n\t\t\tisError: true,\n\t\t\terrorClass: error instanceof Error ? error.name : typeof error,\n\t\t\tfailureMessage: message,\n\t\t\terrorKind: toolFailure?.errorKind ?? \"tool_failure\",\n\t\t\t...(toolFailure ? { failureCode: toolFailure.failureCode, outputSignature: toolFailure.outputSignature } : {}),\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\nasync function finalizeExecutedToolCall(\n\tcurrentContext: AgentContext,\n\tassistantMessage: AssistantMessage,\n\tprepared: PreparedToolCall,\n\trequestId: AgentRequestId,\n\texecuted: ExecutedToolCallOutcome,\n\tconfig: AgentLoopConfig,\n\trepairTeachTracker: ToolRepairTeachTracker,\n\ttoolFailureMemory: ToolFailureMemoryTracker,\n\ttoolFailureRecoveryGate: ToolFailureRecoveryGate,\n\tsignal: AbortSignal | undefined,\n): Promise<FinalizedToolCallOutcome> {\n\tlet result = executed.result;\n\tlet isError = executed.isError;\n\tlet failureMessage = executed.failureMessage ?? \"\";\n\tlet errorClass = executed.errorClass;\n\tlet failureCode = executed.failureCode;\n\tlet outputSignature = executed.outputSignature;\n\tlet errorKind = executed.errorKind;\n\tlet executionGateEffect: ToolFailureRecoveryGateEffect | undefined;\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\trequestId,\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\tusage: afterResult.usage ?? result.usage,\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\t// The hook itself failed, so nothing about the tool's own completed operation survives.\n\t\t\tfailureMessage = error instanceof Error ? error.message : String(error);\n\t\t\terrorClass = error instanceof Error ? error.name : typeof error;\n\t\t\tfailureCode = undefined;\n\t\t\toutputSignature = undefined;\n\t\t\terrorKind = \"tool_failure\";\n\t\t\tresult = { ...createErrorToolResult(failureMessage), usage: result.usage };\n\t\t\tisError = true;\n\t\t}\n\t}\n\n\tif (isError) {\n\t\tconst usage = result.usage;\n\t\tconst failureOutput =\n\t\t\tfailureMessage ||\n\t\t\tresult.content\n\t\t\t\t.filter((block) => block.type === \"text\")\n\t\t\t\t.map((block) => block.text)\n\t\t\t\t.join(\"\\n\") ||\n\t\t\t\"Tool execution failed\";\n\t\tconst effectiveFailureMessage =\n\t\t\tfailureMessage || result.content.find((block) => block.type === \"text\")?.text || \"Tool execution failed\";\n\t\tconst assessment = assessToolFailure(effectiveFailureMessage, \"failed\", errorClass);\n\t\tconst effectiveFailureCode = failureCode ?? assessment.failureCode;\n\t\tif (errorKind === \"operation_outcome\") {\n\t\t\t// The tool ran the operation to completion; the non-zero status is the observation the\n\t\t\t// agent asked for. Nothing here is a mistake, so no failure record is remembered and the\n\t\t\t// tool's own output stands exactly as written. The governor still notes that repeating\n\t\t\t// this identical operation cannot say anything new until something else changes.\n\t\t\tclearToolFailure(toolFailureMemory, prepared.toolCall.name, prepared.args);\n\t\t\tresult = { ...result, errorKind: \"operation_outcome\", usage };\n\t\t\texecutionGateEffect = {\n\t\t\t\tkind: \"unproductive\",\n\t\t\t\ttool: prepared.tool,\n\t\t\t\trecord: describeOperationOutcome(\n\t\t\t\t\tprepared.toolCall.name,\n\t\t\t\t\tprepared.args,\n\t\t\t\t\teffectiveFailureCode,\n\t\t\t\t\tassessment.diagnostic,\n\t\t\t\t),\n\t\t\t\targs: prepared.args,\n\t\t\t};\n\t\t} else {\n\t\t\tconst recoveryPlan = toolFailureRecoveryGate.planFailure(\n\t\t\t\tprepared.tool,\n\t\t\t\tprepared.args,\n\t\t\t\t{ failureCode: effectiveFailureCode, message: effectiveFailureMessage },\n\t\t\t\tcurrentContext.tools ?? [],\n\t\t\t);\n\t\t\tconst correction = assessment.policyGuidance\n\t\t\t\t? `${assessment.policyGuidance} ${recoveryPlan.guidance}`\n\t\t\t\t: recoveryPlan.guidance;\n\t\t\tconst record = rememberToolFailure(\n\t\t\t\ttoolFailureMemory,\n\t\t\t\tprepared.toolCall.name,\n\t\t\t\tprepared.args,\n\t\t\t\t\"failed\",\n\t\t\t\teffectiveFailureCode,\n\t\t\t\tcorrection,\n\t\t\t\tassessment.diagnostic,\n\t\t\t\tassessment.phase,\n\t\t\t\trecoveryPlan.evidence ?? assessment.evidence,\n\t\t\t\t{ output: failureOutput, outputSignature },\n\t\t\t);\n\t\t\texecutionGateEffect = {\n\t\t\t\tkind: \"unproductive\",\n\t\t\t\ttool: prepared.tool,\n\t\t\t\trecord,\n\t\t\t\targs: prepared.args,\n\t\t\t};\n\t\t\tresult = { ...createToolFailureResult(record, result.terminate), usage };\n\t\t}\n\t} else {\n\t\tclearToolFailure(toolFailureMemory, prepared.toolCall.name, prepared.args);\n\t\tif (!executed.isError) {\n\t\t\texecutionGateEffect = {\n\t\t\t\tkind: \"success\",\n\t\t\t\ttool: prepared.tool,\n\t\t\t\targs: prepared.args,\n\t\t\t};\n\t\t}\n\t}\n\n\tconst repaired = isError\n\t\t? { result, taught: false }\n\t\t: 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\texecutionGateEffect,\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\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\nexport function 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\tusage: finalized.result.usage,\n\t\tisError: finalized.isError,\n\t\t// Persisted so a reloaded transcript still separates a completed operation's own status from a\n\t\t// tool that could not run at all.\n\t\t...(finalized.isError && finalized.result.errorKind ? { errorKind: finalized.result.errorKind } : {}),\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 +1 @@
1
- {"version":3,"file":"branch-summarization.d.ts","sourceRoot":"","sources":["../../src/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAA6B,KAAK,EAAuB,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAQ5G,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EAKN,KAAK,cAAc,EAInB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,mEAAmE;IACnE,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gDAAgD;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC5C,qCAAqC;IACrC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oCAAoC;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACpB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACd,oBAAoB,CAkCtB;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,iBAAiB,CA6CxG;AAqDD,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CA0F9B"}
1
+ {"version":3,"file":"branch-summarization.d.ts","sourceRoot":"","sources":["../../src/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAA6B,KAAK,EAAuB,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAc5G,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EAKN,KAAK,cAAc,EAInB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,qEAAqE;AACrE,MAAM,WAAW,oBAAoB;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IACjC,mEAAmE;IACnE,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,gDAAgD;IAChD,OAAO,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACpC,mDAAmD;IACnD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,2DAA2D;IAC3D,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,4BAA4B;IAC5C,qCAAqC;IACrC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oCAAoC;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,qDAAqD;IACrD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACpB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,QAAQ,EAAE,MAAM,GACd,oBAAoB,CAkCtB;AAoCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,WAAW,GAAE,MAAU,GAAG,iBAAiB,CA6CxG;AAqDD,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,4BAA4B,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAuG9B"}
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { completeSimple } from "@caupulican/pi-ai/stream";
8
8
  import { convertToLlm, createBranchSummaryMessage, createCompactionSummaryMessage, createCustomMessage, } from "../messages.js";
9
- import { classifyFailure } from "../reliability/classifier.js";
9
+ import { classifyFailure, computeRetryDelayMs, DEFAULT_RETRY_POLICY, RetryDelayExceededError, sleepAbortable, } from "../reliability/index.js";
10
10
  import { addUsage, createEmptyUsage } from "../usage.js";
11
11
  import { estimateTokens } from "./compaction.js";
12
12
  import { addPersistedFileOperations, computeFileLists, createFileOps, extractFileOpsFromMessage, formatFileOperations, SUMMARIZATION_SYSTEM_PROMPT, serializeConversation, } from "./utils.js";
@@ -216,14 +216,29 @@ export async function generateBranchSummary(entries, options) {
216
216
  // use the same reliability doctrine as compaction instead of bypassing the host stream wrapper.
217
217
  let response;
218
218
  const usage = createEmptyUsage();
219
- for (let attempt = 0; attempt < 3; attempt++) {
219
+ for (let attempt = 1; attempt <= DEFAULT_RETRY_POLICY.maxAttempts; attempt++) {
220
220
  response = await completeBranchSummary(model, { systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages }, { apiKey, headers, signal, maxTokens: 2048 }, streamFn);
221
221
  addUsage(usage, response.usage);
222
222
  if (response.stopReason !== "error")
223
223
  break;
224
224
  const classified = classifyFailure({ message: response.errorMessage ?? "", provider: response.provider });
225
- if (!classified.retryable || signal.aborted)
225
+ if (!classified.retryable || signal.aborted || attempt >= DEFAULT_RETRY_POLICY.maxAttempts)
226
226
  break;
227
+ try {
228
+ const delayMs = computeRetryDelayMs(DEFAULT_RETRY_POLICY, attempt, {
229
+ retryAfterMs: classified.retryAfterMs,
230
+ });
231
+ await sleepAbortable(delayMs, signal);
232
+ }
233
+ catch (error) {
234
+ if (signal.aborted)
235
+ return { aborted: true };
236
+ if (error instanceof RetryDelayExceededError) {
237
+ response.errorMessage = `${response.errorMessage || "Summarization failed"}\n${error.message}`;
238
+ break;
239
+ }
240
+ throw error;
241
+ }
227
242
  }
228
243
  if (!response)
229
244
  return { error: "Summarization failed" };
@@ -1 +1 @@
1
- {"version":3,"file":"branch-summarization.js","sourceRoot":"","sources":["../../src/compaction/branch-summarization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EACN,YAAY,EACZ,0BAA0B,EAC1B,8BAA8B,EAC9B,mBAAmB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAG/D,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EACN,0BAA0B,EAC1B,gBAAgB,EAChB,aAAa,EACb,yBAAyB,EAEzB,oBAAoB,EACpB,2BAA2B,EAC3B,qBAAqB,GACrB,MAAM,YAAY,CAAC;AA2DpB,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,8BAA8B,CAC7C,OAA+B,EAC/B,SAAwB,EACxB,QAAgB;IAEhB,2CAA2C;IAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;IAChD,CAAC;IAED,2DAA2D;IAC3D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAE/C,iFAAiF;IACjF,IAAI,gBAAgB,GAAkB,IAAI,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACjD,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;YACnC,gBAAgB,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACpC,MAAM;QACP,CAAC;IACF,CAAC;IAED,wDAAwD;IACxD,MAAM,OAAO,GAAmB,EAAE,CAAC;IACnC,IAAI,OAAO,GAAkB,SAAS,CAAC;IAEvC,OAAO,OAAO,IAAI,OAAO,KAAK,gBAAgB,EAAE,CAAC;QAChD,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK;YAAE,MAAM;QAClB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,OAAO,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC1B,CAAC;IAED,qCAAqC;IACrC,OAAO,CAAC,OAAO,EAAE,CAAC;IAElB,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AACtC,CAAC;AAED,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E;;;GAGG;AACH,SAAS,mBAAmB,CAAC,KAAmB;IAC/C,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,SAAS;YACb,0DAA0D;YAC1D,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY;gBAAE,OAAO,SAAS,CAAC;YAC1D,OAAO,KAAK,CAAC,OAAO,CAAC;QAEtB,KAAK,gBAAgB;YACpB,OAAO,mBAAmB,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAE5G,KAAK,gBAAgB;YACpB,OAAO,0BAA0B,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAEjF,KAAK,YAAY;YAChB,OAAO,8BAA8B,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;QAE3F,iDAAiD;QACjD,KAAK,uBAAuB,CAAC;QAC7B,KAAK,cAAc,CAAC;QACpB,KAAK,QAAQ,CAAC;QACd,KAAK,OAAO,CAAC;QACb,KAAK,cAAc;YAClB,OAAO,SAAS,CAAC;IACnB,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAuB,EAAE,WAAW,GAAW,CAAC;IACpF,MAAM,QAAQ,GAAmB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;IAChC,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,yFAAyF;IACzF,gFAAgF;IAChF,6FAA6F;IAC7F,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACzE,0BAA0B,CAAC,OAAO,EAAE,KAAK,CAAC,OAA+B,CAAC,CAAC;QAC5E,CAAC;IACF,CAAC;IAED,+EAA+E;IAC/E,+EAA+E;IAC/E,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO;YAAE,SAAS;QAEvB,wDAAwD;QACxD,yBAAyB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAE5C,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QAEvC,6BAA6B;QAC7B,IAAI,WAAW,GAAG,CAAC,IAAI,WAAW,GAAG,MAAM,GAAG,WAAW,EAAE,CAAC;YAC3D,6EAA6E;YAC7E,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACpE,IAAI,WAAW,GAAG,WAAW,GAAG,GAAG,EAAE,CAAC;oBACrC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACvB,WAAW,IAAI,MAAM,CAAC;gBACvB,CAAC;YACF,CAAC;YACD,8BAA8B;YAC9B,MAAM;QACP,CAAC;QAED,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,WAAW,IAAI,MAAM,CAAC;IACvB,CAAC;IAED,QAAQ,CAAC,OAAO,EAAE,CAAC;IACnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAC3C,CAAC;AAED,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,MAAM,uBAAuB,GAAG;;CAE/B,CAAC;AAEF,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;qDAwBuB,CAAC;AAEtD;;;;;GAKG;AACH,KAAK,UAAU,qBAAqB,CACnC,KAAiB,EACjB,OAAgB,EAChB,OAA4B,EAC5B,QAAmB;IAEnB,IAAI,CAAC,QAAQ;QAAE,OAAO,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAC1C,OAAuB,EACvB,OAAqC;IAErC,MAAM,EACL,KAAK,EACL,MAAM,EACN,OAAO,EACP,MAAM,EACN,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,GAAG,KAAK,EACrB,QAAQ,GACR,GAAG,OAAO,CAAC;IAEZ,2EAA2E;IAC3E,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,IAAI,MAAM,CAAC;IACpD,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;IAElD,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,oBAAoB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEzE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC;IAC/C,CAAC;IAED,+DAA+D;IAC/D,kFAAkF;IAClF,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAE5D,eAAe;IACf,IAAI,YAAoB,CAAC;IACzB,IAAI,mBAAmB,IAAI,kBAAkB,EAAE,CAAC;QAC/C,YAAY,GAAG,kBAAkB,CAAC;IACnC,CAAC;SAAM,IAAI,kBAAkB,EAAE,CAAC;QAC/B,YAAY,GAAG,GAAG,qBAAqB,yBAAyB,kBAAkB,EAAE,CAAC;IACtF,CAAC;SAAM,CAAC;QACP,YAAY,GAAG,qBAAqB,CAAC;IACtC,CAAC;IACD,MAAM,UAAU,GAAG,SAAS,gBAAgB,aAAa,YAAY,EAAE,CAAC;IAExE,MAAM,qBAAqB,GAAG;QAC7B;YACC,IAAI,EAAE,MAAe;YACrB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;YACtD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACrB;KACD,CAAC;IAEF,6FAA6F;IAC7F,gGAAgG;IAChG,IAAI,QAAsC,CAAC;IAC3C,MAAM,KAAK,GAAG,gBAAgB,EAAE,CAAC;IACjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC9C,QAAQ,GAAG,MAAM,qBAAqB,CACrC,KAAK,EACL,EAAE,YAAY,EAAE,2BAA2B,EAAE,QAAQ,EAAE,qBAAqB,EAAE,EAC9E,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EAC5C,QAAQ,CACR,CAAC;QACF,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,QAAQ,CAAC,UAAU,KAAK,OAAO;YAAE,MAAM;QAC3C,MAAM,UAAU,GAAG,eAAe,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,YAAY,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1G,IAAI,CAAC,UAAU,CAAC,SAAS,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM;IACpD,CAAC;IACD,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAExD,8BAA8B;IAC9B,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,YAAY,IAAI,sBAAsB,EAAE,CAAC;IACnE,CAAC;IAED,IAAI,OAAO,GAAG,QAAQ,CAAC,OAAO;SAC5B,MAAM,CAAC,CAAC,CAAC,EAAuC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;SACrE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,+DAA+D;IAC/D,OAAO,GAAG,uBAAuB,GAAG,OAAO,CAAC;IAE5C,2CAA2C;IAC3C,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,IAAI,oBAAoB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAE1D,OAAO;QACN,OAAO,EAAE,OAAO,IAAI,sBAAsB;QAC1C,SAAS;QACT,aAAa;QACb,KAAK;KACL,CAAC;AACH,CAAC","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { completeSimple } from \"@caupulican/pi-ai/stream\";\nimport type { AssistantMessage, Context, Model, SimpleStreamOptions, Usage } from \"@caupulican/pi-ai/types\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport { classifyFailure } from \"../reliability/classifier.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session/session-manager.ts\";\nimport type { AgentMessage, StreamFn } from \"../types.ts\";\nimport { addUsage, createEmptyUsage } from \"../usage.ts\";\nimport { estimateTokens } from \"./compaction.ts\";\nimport {\n\taddPersistedFileOperations,\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tSUMMARIZATION_SYSTEM_PROMPT,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\t/** Provider usage spent generating the summary, including retry attempts. */\n\tusage?: Usage;\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Model to use for summarization */\n\tmodel: Model<any>;\n\t/** API key for the model */\n\tapiKey: string | undefined;\n\t/** Request headers for the model */\n\theaders?: Record<string, string>;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved for prompt + LLM response (default 16384) */\n\treserveTokens?: number;\n\t/** Optional wrapped stream function (watchdog/retry-capable host path). */\n\tstreamFn?: StreamFn;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\taddPersistedFileOperations(fileOps, entry.details as BranchSummaryDetails);\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget.\n\t// Append in reverse chronology and reverse once so large branches stay linear.\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.push(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.push(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\tmessages.reverse();\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `Prior branch explored, then returned here. Summary:\n\n`;\n\nconst BRANCH_SUMMARY_PROMPT = `Summarize branch for later return. Exact format:\n\n## Goal\n[User goal]\n\n## Constraints & Preferences\n- [Constraints/preferences, or \"(none)\"]\n\n## Progress\n### Done\n- [x] [Completed work]\n\n### In Progress\n- [ ] [Started, unfinished work]\n\n### Blocked\n- [Blockers, if any]\n\n## Key Decisions\n- **[Decision]**: [Rationale]\n\n## Next Steps\n1. [Next action]\n\nConcise. Preserve exact paths/function names/errors.`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nasync function completeBranchSummary(\n\tmodel: Model<any>,\n\tcontext: Context,\n\toptions: SimpleStreamOptions,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\tif (!streamFn) return completeSimple(model, context, options);\n\tconst stream = await streamFn(model, context, options);\n\treturn stream.result();\n}\n\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst {\n\t\tmodel,\n\t\tapiKey,\n\t\theaders,\n\t\tsignal,\n\t\tcustomInstructions,\n\t\treplaceInstructions,\n\t\treserveTokens = 16384,\n\t\tstreamFn,\n\t} = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `CHAT\\n${conversationText}\\n\\nTASK\\n${instructions}`;\n\n\tconst summarizationMessages = [\n\t\t{\n\t\t\trole: \"user\" as const,\n\t\t\tcontent: [{ type: \"text\" as const, text: promptText }],\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t];\n\n\t// Call LLM for summarization. Retry transient provider/watchdog failures so branch summaries\n\t// use the same reliability doctrine as compaction instead of bypassing the host stream wrapper.\n\tlet response: AssistantMessage | undefined;\n\tconst usage = createEmptyUsage();\n\tfor (let attempt = 0; attempt < 3; attempt++) {\n\t\tresponse = await completeBranchSummary(\n\t\t\tmodel,\n\t\t\t{ systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n\t\t\t{ apiKey, headers, signal, maxTokens: 2048 },\n\t\t\tstreamFn,\n\t\t);\n\t\taddUsage(usage, response.usage);\n\t\tif (response.stopReason !== \"error\") break;\n\t\tconst classified = classifyFailure({ message: response.errorMessage ?? \"\", provider: response.provider });\n\t\tif (!classified.retryable || signal.aborted) break;\n\t}\n\tif (!response) return { error: \"Summarization failed\" };\n\n\t// Check if aborted or errored\n\tif (response.stopReason === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (response.stopReason === \"error\") {\n\t\treturn { error: response.errorMessage || \"Summarization failed\" };\n\t}\n\n\tlet summary = response.content\n\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t.map((c) => c.text)\n\t\t.join(\"\\n\");\n\n\t// Prepend preamble to provide context about the branch summary\n\tsummary = BRANCH_SUMMARY_PREAMBLE + summary;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t\tusage,\n\t};\n}\n"]}
1
+ {"version":3,"file":"branch-summarization.js","sourceRoot":"","sources":["../../src/compaction/branch-summarization.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Branch summarization for tree navigation.\n *\n * When navigating to a different point in the session tree, this generates\n * a summary of the branch being left so context isn't lost.\n */\n\nimport { completeSimple } from \"@caupulican/pi-ai/stream\";\nimport type { AssistantMessage, Context, Model, SimpleStreamOptions, Usage } from \"@caupulican/pi-ai/types\";\nimport {\n\tconvertToLlm,\n\tcreateBranchSummaryMessage,\n\tcreateCompactionSummaryMessage,\n\tcreateCustomMessage,\n} from \"../messages.ts\";\nimport {\n\tclassifyFailure,\n\tcomputeRetryDelayMs,\n\tDEFAULT_RETRY_POLICY,\n\tRetryDelayExceededError,\n\tsleepAbortable,\n} from \"../reliability/index.ts\";\nimport type { ReadonlySessionManager, SessionEntry } from \"../session/session-manager.ts\";\nimport type { AgentMessage, StreamFn } from \"../types.ts\";\nimport { addUsage, createEmptyUsage } from \"../usage.ts\";\nimport { estimateTokens } from \"./compaction.ts\";\nimport {\n\taddPersistedFileOperations,\n\tcomputeFileLists,\n\tcreateFileOps,\n\textractFileOpsFromMessage,\n\ttype FileOperations,\n\tformatFileOperations,\n\tSUMMARIZATION_SYSTEM_PROMPT,\n\tserializeConversation,\n} from \"./utils.ts\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BranchSummaryResult {\n\tsummary?: string;\n\treadFiles?: string[];\n\tmodifiedFiles?: string[];\n\t/** Provider usage spent generating the summary, including retry attempts. */\n\tusage?: Usage;\n\taborted?: boolean;\n\terror?: string;\n}\n\n/** Details stored in BranchSummaryEntry.details for file tracking */\nexport interface BranchSummaryDetails {\n\treadFiles: string[];\n\tmodifiedFiles: string[];\n}\n\nexport type { FileOperations } from \"./utils.ts\";\n\nexport interface BranchPreparation {\n\t/** Messages extracted for summarization, in chronological order */\n\tmessages: AgentMessage[];\n\t/** File operations extracted from tool calls */\n\tfileOps: FileOperations;\n\t/** Total estimated tokens in messages */\n\ttotalTokens: number;\n}\n\nexport interface CollectEntriesResult {\n\t/** Entries to summarize, in chronological order */\n\tentries: SessionEntry[];\n\t/** Common ancestor between old and new position, if any */\n\tcommonAncestorId: string | null;\n}\n\nexport interface GenerateBranchSummaryOptions {\n\t/** Model to use for summarization */\n\tmodel: Model<any>;\n\t/** API key for the model */\n\tapiKey: string | undefined;\n\t/** Request headers for the model */\n\theaders?: Record<string, string>;\n\t/** Abort signal for cancellation */\n\tsignal: AbortSignal;\n\t/** Optional custom instructions for summarization */\n\tcustomInstructions?: string;\n\t/** If true, customInstructions replaces the default prompt instead of being appended */\n\treplaceInstructions?: boolean;\n\t/** Tokens reserved for prompt + LLM response (default 16384) */\n\treserveTokens?: number;\n\t/** Optional wrapped stream function (watchdog/retry-capable host path). */\n\tstreamFn?: StreamFn;\n}\n\n// ============================================================================\n// Entry Collection\n// ============================================================================\n\n/**\n * Collect entries that should be summarized when navigating from one position to another.\n *\n * Walks from oldLeafId back to the common ancestor with targetId, collecting entries\n * along the way. Does NOT stop at compaction boundaries - those are included and their\n * summaries become context.\n *\n * @param session - Session manager (read-only access)\n * @param oldLeafId - Current position (where we're navigating from)\n * @param targetId - Target position (where we're navigating to)\n * @returns Entries to summarize and the common ancestor\n */\nexport function collectEntriesForBranchSummary(\n\tsession: ReadonlySessionManager,\n\toldLeafId: string | null,\n\ttargetId: string,\n): CollectEntriesResult {\n\t// If no old position, nothing to summarize\n\tif (!oldLeafId) {\n\t\treturn { entries: [], commonAncestorId: null };\n\t}\n\n\t// Find common ancestor (deepest node that's on both paths)\n\tconst oldPath = new Set(session.getBranch(oldLeafId).map((e) => e.id));\n\tconst targetPath = session.getBranch(targetId);\n\n\t// targetPath is root-first, so iterate backwards to find deepest common ancestor\n\tlet commonAncestorId: string | null = null;\n\tfor (let i = targetPath.length - 1; i >= 0; i--) {\n\t\tif (oldPath.has(targetPath[i].id)) {\n\t\t\tcommonAncestorId = targetPath[i].id;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Collect entries from old leaf back to common ancestor\n\tconst entries: SessionEntry[] = [];\n\tlet current: string | null = oldLeafId;\n\n\twhile (current && current !== commonAncestorId) {\n\t\tconst entry = session.getEntry(current);\n\t\tif (!entry) break;\n\t\tentries.push(entry);\n\t\tcurrent = entry.parentId;\n\t}\n\n\t// Reverse to get chronological order\n\tentries.reverse();\n\n\treturn { entries, commonAncestorId };\n}\n\n// ============================================================================\n// Entry to Message Conversion\n// ============================================================================\n\n/**\n * Extract AgentMessage from a session entry.\n * Similar to getMessageFromEntry in compaction.ts but also handles compaction entries.\n */\nfunction getMessageFromEntry(entry: SessionEntry): AgentMessage | undefined {\n\tswitch (entry.type) {\n\t\tcase \"message\":\n\t\t\t// Skip tool results - context is in assistant's tool call\n\t\t\tif (entry.message.role === \"toolResult\") return undefined;\n\t\t\treturn entry.message;\n\n\t\tcase \"custom_message\":\n\t\t\treturn createCustomMessage(entry.customType, entry.content, entry.display, entry.details, entry.timestamp);\n\n\t\tcase \"branch_summary\":\n\t\t\treturn createBranchSummaryMessage(entry.summary, entry.fromId, entry.timestamp);\n\n\t\tcase \"compaction\":\n\t\t\treturn createCompactionSummaryMessage(entry.summary, entry.tokensBefore, entry.timestamp);\n\n\t\t// These don't contribute to conversation content\n\t\tcase \"thinking_level_change\":\n\t\tcase \"model_change\":\n\t\tcase \"custom\":\n\t\tcase \"label\":\n\t\tcase \"session_info\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Prepare entries for summarization with token budget.\n *\n * Walks entries from NEWEST to OLDEST, adding messages until we hit the token budget.\n * This ensures we keep the most recent context when the branch is too long.\n *\n * Also collects file operations from:\n * - Tool calls in assistant messages\n * - Existing branch_summary entries' details (for cumulative tracking)\n *\n * @param entries - Entries in chronological order\n * @param tokenBudget - Maximum tokens to include (0 = no limit)\n */\nexport function prepareBranchEntries(entries: SessionEntry[], tokenBudget: number = 0): BranchPreparation {\n\tconst messages: AgentMessage[] = [];\n\tconst fileOps = createFileOps();\n\tlet totalTokens = 0;\n\n\t// First pass: collect file ops from ALL entries (even if they don't fit in token budget)\n\t// This ensures we capture cumulative file tracking from nested branch summaries\n\t// Only extract from pi-generated summaries (fromHook !== true), not extension-generated ones\n\tfor (const entry of entries) {\n\t\tif (entry.type === \"branch_summary\" && !entry.fromHook && entry.details) {\n\t\t\taddPersistedFileOperations(fileOps, entry.details as BranchSummaryDetails);\n\t\t}\n\t}\n\n\t// Second pass: walk from newest to oldest, adding messages until token budget.\n\t// Append in reverse chronology and reverse once so large branches stay linear.\n\tfor (let i = entries.length - 1; i >= 0; i--) {\n\t\tconst entry = entries[i];\n\t\tconst message = getMessageFromEntry(entry);\n\t\tif (!message) continue;\n\n\t\t// Extract file ops from assistant messages (tool calls)\n\t\textractFileOpsFromMessage(message, fileOps);\n\n\t\tconst tokens = estimateTokens(message);\n\n\t\t// Check budget before adding\n\t\tif (tokenBudget > 0 && totalTokens + tokens > tokenBudget) {\n\t\t\t// If this is a summary entry, try to fit it anyway as it's important context\n\t\t\tif (entry.type === \"compaction\" || entry.type === \"branch_summary\") {\n\t\t\t\tif (totalTokens < tokenBudget * 0.9) {\n\t\t\t\t\tmessages.push(message);\n\t\t\t\t\ttotalTokens += tokens;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Stop - we've hit the budget\n\t\t\tbreak;\n\t\t}\n\n\t\tmessages.push(message);\n\t\ttotalTokens += tokens;\n\t}\n\n\tmessages.reverse();\n\treturn { messages, fileOps, totalTokens };\n}\n\n// ============================================================================\n// Summary Generation\n// ============================================================================\n\nconst BRANCH_SUMMARY_PREAMBLE = `Prior branch explored, then returned here. Summary:\n\n`;\n\nconst BRANCH_SUMMARY_PROMPT = `Summarize branch for later return. Exact format:\n\n## Goal\n[User goal]\n\n## Constraints & Preferences\n- [Constraints/preferences, or \"(none)\"]\n\n## Progress\n### Done\n- [x] [Completed work]\n\n### In Progress\n- [ ] [Started, unfinished work]\n\n### Blocked\n- [Blockers, if any]\n\n## Key Decisions\n- **[Decision]**: [Rationale]\n\n## Next Steps\n1. [Next action]\n\nConcise. Preserve exact paths/function names/errors.`;\n\n/**\n * Generate a summary of abandoned branch entries.\n *\n * @param entries - Session entries to summarize (chronological order)\n * @param options - Generation options\n */\nasync function completeBranchSummary(\n\tmodel: Model<any>,\n\tcontext: Context,\n\toptions: SimpleStreamOptions,\n\tstreamFn?: StreamFn,\n): Promise<AssistantMessage> {\n\tif (!streamFn) return completeSimple(model, context, options);\n\tconst stream = await streamFn(model, context, options);\n\treturn stream.result();\n}\n\nexport async function generateBranchSummary(\n\tentries: SessionEntry[],\n\toptions: GenerateBranchSummaryOptions,\n): Promise<BranchSummaryResult> {\n\tconst {\n\t\tmodel,\n\t\tapiKey,\n\t\theaders,\n\t\tsignal,\n\t\tcustomInstructions,\n\t\treplaceInstructions,\n\t\treserveTokens = 16384,\n\t\tstreamFn,\n\t} = options;\n\n\t// Token budget = context window minus reserved space for prompt + response\n\tconst contextWindow = model.contextWindow || 128000;\n\tconst tokenBudget = contextWindow - reserveTokens;\n\n\tconst { messages, fileOps } = prepareBranchEntries(entries, tokenBudget);\n\n\tif (messages.length === 0) {\n\t\treturn { summary: \"No content to summarize\" };\n\t}\n\n\t// Transform to LLM-compatible messages, then serialize to text\n\t// Serialization prevents the model from treating it as a conversation to continue\n\tconst llmMessages = convertToLlm(messages);\n\tconst conversationText = serializeConversation(llmMessages);\n\n\t// Build prompt\n\tlet instructions: string;\n\tif (replaceInstructions && customInstructions) {\n\t\tinstructions = customInstructions;\n\t} else if (customInstructions) {\n\t\tinstructions = `${BRANCH_SUMMARY_PROMPT}\\n\\nAdditional focus: ${customInstructions}`;\n\t} else {\n\t\tinstructions = BRANCH_SUMMARY_PROMPT;\n\t}\n\tconst promptText = `CHAT\\n${conversationText}\\n\\nTASK\\n${instructions}`;\n\n\tconst summarizationMessages = [\n\t\t{\n\t\t\trole: \"user\" as const,\n\t\t\tcontent: [{ type: \"text\" as const, text: promptText }],\n\t\t\ttimestamp: Date.now(),\n\t\t},\n\t];\n\n\t// Call LLM for summarization. Retry transient provider/watchdog failures so branch summaries\n\t// use the same reliability doctrine as compaction instead of bypassing the host stream wrapper.\n\tlet response: AssistantMessage | undefined;\n\tconst usage = createEmptyUsage();\n\tfor (let attempt = 1; attempt <= DEFAULT_RETRY_POLICY.maxAttempts; attempt++) {\n\t\tresponse = await completeBranchSummary(\n\t\t\tmodel,\n\t\t\t{ systemPrompt: SUMMARIZATION_SYSTEM_PROMPT, messages: summarizationMessages },\n\t\t\t{ apiKey, headers, signal, maxTokens: 2048 },\n\t\t\tstreamFn,\n\t\t);\n\t\taddUsage(usage, response.usage);\n\t\tif (response.stopReason !== \"error\") break;\n\t\tconst classified = classifyFailure({ message: response.errorMessage ?? \"\", provider: response.provider });\n\t\tif (!classified.retryable || signal.aborted || attempt >= DEFAULT_RETRY_POLICY.maxAttempts) break;\n\t\ttry {\n\t\t\tconst delayMs = computeRetryDelayMs(DEFAULT_RETRY_POLICY, attempt, {\n\t\t\t\tretryAfterMs: classified.retryAfterMs,\n\t\t\t});\n\t\t\tawait sleepAbortable(delayMs, signal);\n\t\t} catch (error) {\n\t\t\tif (signal.aborted) return { aborted: true };\n\t\t\tif (error instanceof RetryDelayExceededError) {\n\t\t\t\tresponse.errorMessage = `${response.errorMessage || \"Summarization failed\"}\\n${error.message}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\tif (!response) return { error: \"Summarization failed\" };\n\n\t// Check if aborted or errored\n\tif (response.stopReason === \"aborted\") {\n\t\treturn { aborted: true };\n\t}\n\tif (response.stopReason === \"error\") {\n\t\treturn { error: response.errorMessage || \"Summarization failed\" };\n\t}\n\n\tlet summary = response.content\n\t\t.filter((c): c is { type: \"text\"; text: string } => c.type === \"text\")\n\t\t.map((c) => c.text)\n\t\t.join(\"\\n\");\n\n\t// Prepend preamble to provide context about the branch summary\n\tsummary = BRANCH_SUMMARY_PREAMBLE + summary;\n\n\t// Compute file lists and append to summary\n\tconst { readFiles, modifiedFiles } = computeFileLists(fileOps);\n\tsummary += formatFileOperations(readFiles, modifiedFiles);\n\n\treturn {\n\t\tsummary: summary || \"No summary generated\",\n\t\treadFiles,\n\t\tmodifiedFiles,\n\t\tusage,\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../src/reliability/classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,aAAa,GACtB,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,SAAS,GACT,cAAc,GACd,kBAAkB,GAClB,MAAM,GACN,kBAAkB,GAClB,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,cAAc,EAAE,OAAO,CAAC;IACxB,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAyBD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,eAAe,CAwD5E"}
1
+ {"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../../src/reliability/classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,MAAM,MAAM,aAAa,GACtB,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,SAAS,GACT,cAAc,GACd,kBAAkB,GAClB,MAAM,GACN,kBAAkB,GAClB,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,WAAW,eAAe;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,cAAc,EAAE,OAAO,CAAC;IACxB,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAqDD,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,eAAe,CA2D5E"}
@@ -17,22 +17,47 @@ const AUTH = /\b401\b|unauthorized|invalid.?api.?key|authentication.?error|forbi
17
17
  const RATE_LIMIT = /rate.?limit|too many requests|(?<![A-Za-z0-9])429(?![A-Za-z0-9])/i;
18
18
  const OVERLOADED = /overloaded/i;
19
19
  const STREAM_STALL = /stream stalled|ended without|stream ended before message_stop|stream ended before a terminal response event|reset before headers/i;
20
- const SERVER_ERROR = /(?<![A-Za-z0-9])(?:500|502|503|504)(?![A-Za-z0-9])|service.?unavailable|server.?error|internal.?error|provider.?returned.?error|upstream.?connect|http2 request did not get a response|ResourceExhausted|retry delay|you can retry your request|try your request again|please retry your request/i;
20
+ const SERVER_ERROR = /(?<![A-Za-z0-9])(?:500|502|503|504)(?![A-Za-z0-9])|service.?unavailable|server.?error|internal.?error|provider.?returned.?error|upstream.?connect|http2 request did not get a response|ResourceExhausted|retry delay|provider retry directive:\s*retry|you can retry your request|try your request again|please retry your request/i;
21
21
  const NETWORK = /network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|getaddrinfo|ENOTFOUND|EAI_AGAIN|socket hang up|socket connection was closed|timed? out|timeout|terminated/i;
22
- const RETRY_AFTER_S = /retry.?(?:after|in)\s+(\d+(?:\.\d+)?)\s*s\b|"retryDelay"\s*:\s*"(\d+(?:\.\d+)?)s"/i;
23
- const RETRY_AFTER_MS = /retry.?(?:after|in)\s+(\d+)\s*ms\b/i;
22
+ const PROVIDER_NO_RETRY = /Provider retry directive:\s*do not retry\./i;
23
+ const RETRY_DELAY_TEXT = /(?:retry(?:\s+your\s+request)?|try(?:\s+your\s+request)?\s+again)\s+(?:after|in)\s+((?:\d+(?:\.\d+)?\s*(?:milliseconds?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)\s*)+)/gi;
24
+ const RETRY_DELAY_JSON = /"retryDelay"\s*:\s*"([^"]+)"/gi;
25
+ const RETRY_DURATION_COMPONENT = /(\d+(?:\.\d+)?)\s*(milliseconds?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)(?![A-Za-z])/gi;
26
+ function parseRetryDurationMs(value) {
27
+ let totalMs = 0;
28
+ let components = 0;
29
+ for (const match of value.matchAll(RETRY_DURATION_COMPONENT)) {
30
+ const amount = Number(match[1]);
31
+ if (!Number.isFinite(amount))
32
+ return undefined;
33
+ const unit = match[2].toLowerCase();
34
+ const multiplier = unit === "ms" || unit.startsWith("millisecond")
35
+ ? 1
36
+ : unit === "s" || unit.startsWith("sec")
37
+ ? 1000
38
+ : unit === "m" || unit.startsWith("min")
39
+ ? 60_000
40
+ : 3_600_000;
41
+ totalMs += amount * multiplier;
42
+ components++;
43
+ }
44
+ return components > 0 && Number.isFinite(totalMs) ? Math.round(totalMs) : undefined;
45
+ }
24
46
  function parseRetryAfterMs(message) {
25
- const ms = RETRY_AFTER_MS.exec(message);
26
- if (ms)
27
- return Number(ms[1]);
28
- const s = RETRY_AFTER_S.exec(message);
29
- if (s)
30
- return Math.round(Number(s[1] ?? s[2]) * 1000);
31
- return undefined;
47
+ let longestDelayMs;
48
+ for (const pattern of [RETRY_DELAY_TEXT, RETRY_DELAY_JSON]) {
49
+ for (const match of message.matchAll(pattern)) {
50
+ const delayMs = parseRetryDurationMs(match[1]);
51
+ if (delayMs !== undefined)
52
+ longestDelayMs = Math.max(longestDelayMs ?? 0, delayMs);
53
+ }
54
+ }
55
+ return longestDelayMs;
32
56
  }
33
57
  export function classifyFailure(input) {
34
58
  const message = input.message;
35
59
  const retryAfterMs = parseRetryAfterMs(message);
60
+ const providerForbidsRetry = PROVIDER_NO_RETRY.test(message);
36
61
  const base = {
37
62
  retryable: false,
38
63
  shouldCompact: false,
@@ -40,7 +65,10 @@ export function classifyFailure(input) {
40
65
  shouldFallback: false,
41
66
  message,
42
67
  };
43
- const withRetry = (obj) => retryAfterMs !== undefined ? { ...obj, retryAfterMs } : obj;
68
+ const withRetry = (result) => {
69
+ const withDelay = retryAfterMs !== undefined ? { ...result, retryAfterMs } : result;
70
+ return providerForbidsRetry && withDelay.retryable ? { ...withDelay, retryable: false } : withDelay;
71
+ };
44
72
  if (input.aborted)
45
73
  return withRetry({ ...base, reason: "aborted" });
46
74
  if (input.contextOverflow)
@@ -1 +1 @@
1
- {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/reliability/classifier.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure provider-failure classifier.\n *\n * One classification produces four independent action booleans (hermes-derived design):\n * the retry loop, compaction, credential rotation, and provider failover each read their\n * own flag, so one pipeline can route a 429 to rotation, an overflow to compaction, and a\n * billing error to failover without re-parsing error text at each site.\n *\n * Pattern sources: AgentSession._isRetryableError / _isNonRetryableProviderLimitError\n * (the live, battle-tested regexes), split by reason so each maps to distinct actions.\n * Detection of context overflow stays in @caupulican/pi-ai (needs model state); hosts pass\n * `contextOverflow` in.\n */\n\nimport { PROVIDER_FAILURE_SIGNATURES } from \"./provider-signatures.ts\";\n\nexport type FailureReason =\n\t| \"overloaded\"\n\t| \"rate_limit\"\n\t| \"server_error\"\n\t| \"network\"\n\t| \"stream_stall\"\n\t| \"context_overflow\"\n\t| \"auth\"\n\t| \"billing_or_quota\"\n\t| \"aborted\"\n\t| \"unknown\";\n\nexport interface ClassifiedError {\n\treason: FailureReason;\n\tretryable: boolean;\n\tshouldCompact: boolean;\n\tshouldRotateCredential: boolean;\n\tshouldFallback: boolean;\n\t/** Provider-suggested delay parsed from the message, capped by the retry policy at use site. */\n\tretryAfterMs?: number;\n\tmessage: string;\n}\n\nexport interface ClassifyFailureInput {\n\tmessage: string;\n\t/** Host-computed via pi-ai isContextOverflow(message, contextWindow). */\n\tcontextOverflow?: boolean;\n\t/** True when the failure came from an intentional abort (stopReason \"aborted\"). */\n\taborted?: boolean;\n\t/** Provider id; provider-specific signatures are checked before generic patterns. */\n\tprovider?: string;\n}\n\nconst BILLING_OR_QUOTA =\n\t/GoUsageLimitError|FreeUsageLimitError|Monthly usage limit reached|available balance|insufficient_quota|out of budget|quota exceeded|billing|usage.?limit(?:s)?\\s*(?:reached|exceeded|hit)|usage_limit_reached|hit your usage limit|hit your ChatGPT usage limit/i;\nconst AUTH = /\\b401\\b|unauthorized|invalid.?api.?key|authentication.?error|forbidden|permission.?denied/i;\nconst RATE_LIMIT = /rate.?limit|too many requests|(?<![A-Za-z0-9])429(?![A-Za-z0-9])/i;\nconst OVERLOADED = /overloaded/i;\nconst STREAM_STALL =\n\t/stream stalled|ended without|stream ended before message_stop|stream ended before a terminal response event|reset before headers/i;\nconst SERVER_ERROR =\n\t/(?<![A-Za-z0-9])(?:500|502|503|504)(?![A-Za-z0-9])|service.?unavailable|server.?error|internal.?error|provider.?returned.?error|upstream.?connect|http2 request did not get a response|ResourceExhausted|retry delay|you can retry your request|try your request again|please retry your request/i;\nconst NETWORK =\n\t/network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|getaddrinfo|ENOTFOUND|EAI_AGAIN|socket hang up|socket connection was closed|timed? out|timeout|terminated/i;\n\nconst RETRY_AFTER_S = /retry.?(?:after|in)\\s+(\\d+(?:\\.\\d+)?)\\s*s\\b|\"retryDelay\"\\s*:\\s*\"(\\d+(?:\\.\\d+)?)s\"/i;\nconst RETRY_AFTER_MS = /retry.?(?:after|in)\\s+(\\d+)\\s*ms\\b/i;\n\nfunction parseRetryAfterMs(message: string): number | undefined {\n\tconst ms = RETRY_AFTER_MS.exec(message);\n\tif (ms) return Number(ms[1]);\n\tconst s = RETRY_AFTER_S.exec(message);\n\tif (s) return Math.round(Number(s[1] ?? s[2]) * 1000);\n\treturn undefined;\n}\n\nexport function classifyFailure(input: ClassifyFailureInput): ClassifiedError {\n\tconst message = input.message;\n\tconst retryAfterMs = parseRetryAfterMs(message);\n\n\tconst base = {\n\t\tretryable: false,\n\t\tshouldCompact: false,\n\t\tshouldRotateCredential: false,\n\t\tshouldFallback: false,\n\t\tmessage,\n\t};\n\n\tconst withRetry = <T extends { reason: FailureReason }>(obj: T): T | (T & { retryAfterMs: number }) =>\n\t\tretryAfterMs !== undefined ? { ...obj, retryAfterMs } : obj;\n\n\tif (input.aborted) return withRetry({ ...base, reason: \"aborted\" });\n\tif (input.contextOverflow) return withRetry({ ...base, reason: \"context_overflow\", shouldCompact: true });\n\tconst providerSignatures = input.provider ? (PROVIDER_FAILURE_SIGNATURES[input.provider] ?? []) : [];\n\tfor (const signature of providerSignatures) {\n\t\tif (signature.pattern.test(message)) {\n\t\t\treturn withRetry({\n\t\t\t\t...base,\n\t\t\t\treason: signature.reason,\n\t\t\t\tshouldCompact: signature.shouldCompact ?? false,\n\t\t\t\tshouldFallback: signature.reason === \"billing_or_quota\" || signature.reason === \"auth\",\n\t\t\t\tshouldRotateCredential: signature.reason === \"auth\",\n\t\t\t\tretryable:\n\t\t\t\t\tsignature.reason === \"rate_limit\" ||\n\t\t\t\t\tsignature.reason === \"overloaded\" ||\n\t\t\t\t\tsignature.reason === \"server_error\" ||\n\t\t\t\t\tsignature.reason === \"network\" ||\n\t\t\t\t\tsignature.reason === \"stream_stall\",\n\t\t\t});\n\t\t}\n\t}\n\tif (BILLING_OR_QUOTA.test(message)) return withRetry({ ...base, reason: \"billing_or_quota\", shouldFallback: true });\n\tif (AUTH.test(message))\n\t\treturn withRetry({ ...base, reason: \"auth\", shouldRotateCredential: true, shouldFallback: true });\n\n\tconst isRateLimit = RATE_LIMIT.test(message);\n\tif (isRateLimit || OVERLOADED.test(message)) {\n\t\treturn withRetry({\n\t\t\t...base,\n\t\t\treason: isRateLimit ? \"rate_limit\" : \"overloaded\",\n\t\t\tretryable: true,\n\t\t\tshouldRotateCredential: true,\n\t\t\tshouldFallback: true,\n\t\t});\n\t}\n\tif (STREAM_STALL.test(message))\n\t\treturn withRetry({ ...base, reason: \"stream_stall\", retryable: true, shouldFallback: true });\n\tif (SERVER_ERROR.test(message))\n\t\treturn withRetry({ ...base, reason: \"server_error\", retryable: true, shouldFallback: true });\n\tif (NETWORK.test(message)) return withRetry({ ...base, reason: \"network\", retryable: true, shouldFallback: true });\n\n\treturn withRetry({ ...base, reason: \"unknown\" });\n}\n"]}
1
+ {"version":3,"file":"classifier.js","sourceRoot":"","sources":["../../src/reliability/classifier.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Pure provider-failure classifier.\n *\n * One classification produces four independent action booleans (hermes-derived design):\n * the retry loop, compaction, credential rotation, and provider failover each read their\n * own flag, so one pipeline can route a 429 to rotation, an overflow to compaction, and a\n * billing error to failover without re-parsing error text at each site.\n *\n * Pattern sources: AgentSession._isRetryableError / _isNonRetryableProviderLimitError\n * (the live, battle-tested regexes), split by reason so each maps to distinct actions.\n * Detection of context overflow stays in @caupulican/pi-ai (needs model state); hosts pass\n * `contextOverflow` in.\n */\n\nimport { PROVIDER_FAILURE_SIGNATURES } from \"./provider-signatures.ts\";\n\nexport type FailureReason =\n\t| \"overloaded\"\n\t| \"rate_limit\"\n\t| \"server_error\"\n\t| \"network\"\n\t| \"stream_stall\"\n\t| \"context_overflow\"\n\t| \"auth\"\n\t| \"billing_or_quota\"\n\t| \"aborted\"\n\t| \"unknown\";\n\nexport interface ClassifiedError {\n\treason: FailureReason;\n\tretryable: boolean;\n\tshouldCompact: boolean;\n\tshouldRotateCredential: boolean;\n\tshouldFallback: boolean;\n\t/** Provider-suggested delay parsed from the message, capped by the retry policy at use site. */\n\tretryAfterMs?: number;\n\tmessage: string;\n}\n\nexport interface ClassifyFailureInput {\n\tmessage: string;\n\t/** Host-computed via pi-ai isContextOverflow(message, contextWindow). */\n\tcontextOverflow?: boolean;\n\t/** True when the failure came from an intentional abort (stopReason \"aborted\"). */\n\taborted?: boolean;\n\t/** Provider id; provider-specific signatures are checked before generic patterns. */\n\tprovider?: string;\n}\n\nconst BILLING_OR_QUOTA =\n\t/GoUsageLimitError|FreeUsageLimitError|Monthly usage limit reached|available balance|insufficient_quota|out of budget|quota exceeded|billing|usage.?limit(?:s)?\\s*(?:reached|exceeded|hit)|usage_limit_reached|hit your usage limit|hit your ChatGPT usage limit/i;\nconst AUTH = /\\b401\\b|unauthorized|invalid.?api.?key|authentication.?error|forbidden|permission.?denied/i;\nconst RATE_LIMIT = /rate.?limit|too many requests|(?<![A-Za-z0-9])429(?![A-Za-z0-9])/i;\nconst OVERLOADED = /overloaded/i;\nconst STREAM_STALL =\n\t/stream stalled|ended without|stream ended before message_stop|stream ended before a terminal response event|reset before headers/i;\nconst SERVER_ERROR =\n\t/(?<![A-Za-z0-9])(?:500|502|503|504)(?![A-Za-z0-9])|service.?unavailable|server.?error|internal.?error|provider.?returned.?error|upstream.?connect|http2 request did not get a response|ResourceExhausted|retry delay|provider retry directive:\\s*retry|you can retry your request|try your request again|please retry your request/i;\nconst NETWORK =\n\t/network.?error|connection.?error|connection.?refused|connection.?lost|websocket.?closed|websocket.?error|other side closed|fetch failed|getaddrinfo|ENOTFOUND|EAI_AGAIN|socket hang up|socket connection was closed|timed? out|timeout|terminated/i;\nconst PROVIDER_NO_RETRY = /Provider retry directive:\\s*do not retry\\./i;\n\nconst RETRY_DELAY_TEXT =\n\t/(?:retry(?:\\s+your\\s+request)?|try(?:\\s+your\\s+request)?\\s+again)\\s+(?:after|in)\\s+((?:\\d+(?:\\.\\d+)?\\s*(?:milliseconds?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)\\s*)+)/gi;\nconst RETRY_DELAY_JSON = /\"retryDelay\"\\s*:\\s*\"([^\"]+)\"/gi;\nconst RETRY_DURATION_COMPONENT =\n\t/(\\d+(?:\\.\\d+)?)\\s*(milliseconds?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)(?![A-Za-z])/gi;\n\nfunction parseRetryDurationMs(value: string): number | undefined {\n\tlet totalMs = 0;\n\tlet components = 0;\n\tfor (const match of value.matchAll(RETRY_DURATION_COMPONENT)) {\n\t\tconst amount = Number(match[1]);\n\t\tif (!Number.isFinite(amount)) return undefined;\n\t\tconst unit = match[2].toLowerCase();\n\t\tconst multiplier =\n\t\t\tunit === \"ms\" || unit.startsWith(\"millisecond\")\n\t\t\t\t? 1\n\t\t\t\t: unit === \"s\" || unit.startsWith(\"sec\")\n\t\t\t\t\t? 1000\n\t\t\t\t\t: unit === \"m\" || unit.startsWith(\"min\")\n\t\t\t\t\t\t? 60_000\n\t\t\t\t\t\t: 3_600_000;\n\t\ttotalMs += amount * multiplier;\n\t\tcomponents++;\n\t}\n\treturn components > 0 && Number.isFinite(totalMs) ? Math.round(totalMs) : undefined;\n}\n\nfunction parseRetryAfterMs(message: string): number | undefined {\n\tlet longestDelayMs: number | undefined;\n\tfor (const pattern of [RETRY_DELAY_TEXT, RETRY_DELAY_JSON]) {\n\t\tfor (const match of message.matchAll(pattern)) {\n\t\t\tconst delayMs = parseRetryDurationMs(match[1]);\n\t\t\tif (delayMs !== undefined) longestDelayMs = Math.max(longestDelayMs ?? 0, delayMs);\n\t\t}\n\t}\n\treturn longestDelayMs;\n}\n\nexport function classifyFailure(input: ClassifyFailureInput): ClassifiedError {\n\tconst message = input.message;\n\tconst retryAfterMs = parseRetryAfterMs(message);\n\tconst providerForbidsRetry = PROVIDER_NO_RETRY.test(message);\n\n\tconst base = {\n\t\tretryable: false,\n\t\tshouldCompact: false,\n\t\tshouldRotateCredential: false,\n\t\tshouldFallback: false,\n\t\tmessage,\n\t};\n\n\tconst withRetry = (result: ClassifiedError): ClassifiedError => {\n\t\tconst withDelay = retryAfterMs !== undefined ? { ...result, retryAfterMs } : result;\n\t\treturn providerForbidsRetry && withDelay.retryable ? { ...withDelay, retryable: false } : withDelay;\n\t};\n\n\tif (input.aborted) return withRetry({ ...base, reason: \"aborted\" });\n\tif (input.contextOverflow) return withRetry({ ...base, reason: \"context_overflow\", shouldCompact: true });\n\tconst providerSignatures = input.provider ? (PROVIDER_FAILURE_SIGNATURES[input.provider] ?? []) : [];\n\tfor (const signature of providerSignatures) {\n\t\tif (signature.pattern.test(message)) {\n\t\t\treturn withRetry({\n\t\t\t\t...base,\n\t\t\t\treason: signature.reason,\n\t\t\t\tshouldCompact: signature.shouldCompact ?? false,\n\t\t\t\tshouldFallback: signature.reason === \"billing_or_quota\" || signature.reason === \"auth\",\n\t\t\t\tshouldRotateCredential: signature.reason === \"auth\",\n\t\t\t\tretryable:\n\t\t\t\t\tsignature.reason === \"rate_limit\" ||\n\t\t\t\t\tsignature.reason === \"overloaded\" ||\n\t\t\t\t\tsignature.reason === \"server_error\" ||\n\t\t\t\t\tsignature.reason === \"network\" ||\n\t\t\t\t\tsignature.reason === \"stream_stall\",\n\t\t\t});\n\t\t}\n\t}\n\tif (BILLING_OR_QUOTA.test(message)) return withRetry({ ...base, reason: \"billing_or_quota\", shouldFallback: true });\n\tif (AUTH.test(message))\n\t\treturn withRetry({ ...base, reason: \"auth\", shouldRotateCredential: true, shouldFallback: true });\n\n\tconst isRateLimit = RATE_LIMIT.test(message);\n\tif (isRateLimit || OVERLOADED.test(message)) {\n\t\treturn withRetry({\n\t\t\t...base,\n\t\t\treason: isRateLimit ? \"rate_limit\" : \"overloaded\",\n\t\t\tretryable: true,\n\t\t\tshouldRotateCredential: true,\n\t\t\tshouldFallback: true,\n\t\t});\n\t}\n\tif (STREAM_STALL.test(message))\n\t\treturn withRetry({ ...base, reason: \"stream_stall\", retryable: true, shouldFallback: true });\n\tif (SERVER_ERROR.test(message))\n\t\treturn withRetry({ ...base, reason: \"server_error\", retryable: true, shouldFallback: true });\n\tif (NETWORK.test(message)) return withRetry({ ...base, reason: \"network\", retryable: true, shouldFallback: true });\n\n\treturn withRetry({ ...base, reason: \"unknown\" });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"retry-controller.d.ts","sourceRoot":"","sources":["../../src/reliability/retry-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAuB,KAAK,WAAW,EAAkB,MAAM,YAAY,CAAC;AAEnF,0FAA0F;AAC1F,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC3B,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CACrC;AAED,iGAAiG;AACjG,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AA4BvE,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAEhD,YACC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,qBAAqB,EACtC,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,MAAM,EAM9B;IAED,0EAA0E;IAC1E,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,+FAA+F;IAC/F,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,kGAAkG;IAClG,KAAK,IAAI,IAAI,CAEZ;IAED,8EAA8E;IAC9E,KAAK,IAAI,IAAI,CAEZ;IAED;;;;OAIG;IACG,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CA0D9D;CACD"}
1
+ {"version":3,"file":"retry-controller.d.ts","sourceRoot":"","sources":["../../src/reliability/retry-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAgD,KAAK,WAAW,EAAkB,MAAM,YAAY,CAAC;AAE5G,0FAA0F;AAC1F,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC3B,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IACzC,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;CACrC;AAED,iGAAiG;AACjG,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AA4BvE,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAEhD,YACC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,qBAAqB,EACtC,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,MAAM,EAM9B;IAED,0EAA0E;IAC1E,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,+FAA+F;IAC/F,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,kGAAkG;IAClG,KAAK,IAAI,IAAI,CAEZ;IAED,8EAA8E;IAC9E,KAAK,IAAI,IAAI,CAEZ;IAED;;;;OAIG;IACG,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CA6D9D;CACD"}
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { isContextOverflow } from "@caupulican/pi-ai/overflow";
16
16
  import { classifyFailure } from "./classifier.js";
17
- import { computeRetryDelayMs, sleepAbortable } from "./retry.js";
17
+ import { computeRetryDelayMs, RetryDelayExceededError, sleepAbortable } from "./retry.js";
18
18
  function hasMeaningfulAssistantProgress(message) {
19
19
  return message.content.some((block) => {
20
20
  if (block.type === "text")
@@ -82,13 +82,19 @@ export class RetryController {
82
82
  return false;
83
83
  }
84
84
  const maxAttempts = effectiveMaxAttempts(message, classified.reason, policy.maxAttempts);
85
- this._attempt++;
86
- if (this._attempt > maxAttempts) {
87
- // Preserve the completed attempt count so the host can emit the final failure.
88
- this._attempt--;
85
+ const nextAttempt = this._attempt + 1;
86
+ if (nextAttempt > maxAttempts)
89
87
  return false;
88
+ let delayMs;
89
+ try {
90
+ delayMs = computeRetryDelayMs(policy, nextAttempt, { retryAfterMs: classified.retryAfterMs });
91
+ }
92
+ catch (error) {
93
+ if (error instanceof RetryDelayExceededError)
94
+ return false;
95
+ throw error;
90
96
  }
91
- const delayMs = computeRetryDelayMs(policy, this._attempt, { retryAfterMs: classified.retryAfterMs });
97
+ this._attempt = nextAttempt;
92
98
  // The retry window counts as active work from the instant listeners hear about it:
93
99
  // isRetrying must already be true inside onRetryStart handlers so prompts arriving there
94
100
  // queue as steering instead of racing the retry continuation.
@@ -1 +1 @@
1
- {"version":3,"file":"retry-controller.js","sourceRoot":"","sources":["../../src/reliability/retry-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-agnostic auto-retry driver.\n *\n * Owns the retry attempt counter and the abortable backoff for one agent run. It reads the\n * failure verdict from {@link classifyFailure} (fed a host-computed context-overflow flag), so\n * billing/auth are terminal and overflow routes to compaction — never to a pointless retry.\n * The controller only ever touches `agent.state.messages` (it drops the trailing assistant error\n * before retrying); durable history stays the host session's responsibility.\n *\n * Ported from AgentSession._prepareRetry / _isRetryableError so the exact event ordering and\n * exhaustion semantics carry over: the retry window is marked active (isRetrying) before the\n * start event fires, so prompts arriving inside start handlers queue as steering instead of\n * racing the retry continuation.\n */\n\nimport { isContextOverflow } from \"@caupulican/pi-ai/overflow\";\nimport type { AssistantMessage } from \"@caupulican/pi-ai/types\";\nimport type { AgentMessage } from \"../types.ts\";\nimport { classifyFailure } from \"./classifier.ts\";\nimport { computeRetryDelayMs, type RetryPolicy, sleepAbortable } from \"./retry.ts\";\n\n/** The slice of an Agent the retry driver reads and mutates: just the live transcript. */\nexport interface RetryAgent {\n\treadonly state: { messages: AgentMessage[] };\n}\n\nexport interface RetryStartInfo {\n\tattempt: number;\n\tmaxAttempts: number;\n\tdelayMs: number;\n\terrorMessage: string;\n}\n\nexport interface RetryEndInfo {\n\tsuccess: boolean;\n\tattempt: number;\n\tfinalError?: string;\n}\n\nexport interface RetryEvents {\n\tonRetryStart(info: RetryStartInfo): void;\n\tonRetryEnd(info: RetryEndInfo): void;\n}\n\n/** Runtime retry policy: the backoff shape plus the on/off switch the host resolves per call. */\nexport type RetryControllerPolicy = RetryPolicy & { enabled: boolean };\n\nfunction hasMeaningfulAssistantProgress(message: AssistantMessage): boolean {\n\treturn message.content.some((block) => {\n\t\tif (block.type === \"text\") return block.text.trim().length > 0;\n\t\tif (block.type === \"thinking\") return block.thinking.trim().length > 0;\n\t\treturn block.type === \"toolCall\";\n\t});\n}\n\n/**\n * xAI can accept a subscription request, allocate a response id, emit an empty reasoning item,\n * and then remain silent until the quiet watchdog fires. Repeating that exact zero-progress wait\n * through every configured retry held one observed foreground run for four consecutive 10-minute\n * windows. Preserve one recovery attempt, but require real generated content before granting the\n * ordinary retry allowance. Capacity responses and stalls after real progress remain unchanged.\n */\nfunction effectiveMaxAttempts(\n\tmessage: AssistantMessage,\n\treason: ReturnType<typeof classifyFailure>[\"reason\"],\n\tconfiguredMaxAttempts: number,\n): number {\n\tif (message.provider === \"xai\" && reason === \"stream_stall\" && !hasMeaningfulAssistantProgress(message)) {\n\t\treturn Math.min(configuredMaxAttempts, 1);\n\t}\n\treturn configuredMaxAttempts;\n}\n\nexport class RetryController {\n\tprivate _attempt = 0;\n\tprivate _abortController: AbortController | undefined;\n\tprivate readonly agent: RetryAgent;\n\tprivate readonly getPolicy: () => RetryControllerPolicy;\n\tprivate readonly events: RetryEvents;\n\tprivate readonly getContextWindow: () => number;\n\n\tconstructor(\n\t\tagent: RetryAgent,\n\t\tgetPolicy: () => RetryControllerPolicy,\n\t\tevents: RetryEvents,\n\t\tgetContextWindow: () => number,\n\t) {\n\t\tthis.agent = agent;\n\t\tthis.getPolicy = getPolicy;\n\t\tthis.events = events;\n\t\tthis.getContextWindow = getContextWindow;\n\t}\n\n\t/** Completed retry attempts for the current run (0 when not retrying). */\n\tget attempt(): number {\n\t\treturn this._attempt;\n\t}\n\n\t/** True from the instant onRetryStart fires until the backoff sleep resolves or is aborted. */\n\tget isRetrying(): boolean {\n\t\treturn this._abortController !== undefined;\n\t}\n\n\t/** Clear the attempt counter — the host calls this after a successful turn or a final failure. */\n\treset(): void {\n\t\tthis._attempt = 0;\n\t}\n\n\t/** Cancel an in-progress backoff; the pending prepareRetry resolves false. */\n\tabort(): void {\n\t\tthis._abortController?.abort();\n\t}\n\n\t/**\n\t * Classify `message`; if it is retryable and attempts remain, drop the trailing assistant\n\t * error from agent state, emit the start event, and wait out the backoff (abortable).\n\t * @returns true if the caller should continue the agent, false otherwise.\n\t */\n\tasync prepareRetry(message: AssistantMessage): Promise<boolean> {\n\t\tconst policy = this.getPolicy();\n\t\tif (!policy.enabled) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// The classifier is the single source of the retry verdict: context overflow (host-computed\n\t\t// from the live window) routes to compaction, billing/auth are terminal, transient failures retry.\n\t\tconst classified = classifyFailure({\n\t\t\tmessage: message.errorMessage ?? \"\",\n\t\t\tcontextOverflow: isContextOverflow(message, this.getContextWindow()),\n\t\t\tprovider: message.provider,\n\t\t});\n\t\tif (!classified.retryable) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst maxAttempts = effectiveMaxAttempts(message, classified.reason, policy.maxAttempts);\n\t\tthis._attempt++;\n\t\tif (this._attempt > maxAttempts) {\n\t\t\t// Preserve the completed attempt count so the host can emit the final failure.\n\t\t\tthis._attempt--;\n\t\t\treturn false;\n\t\t}\n\n\t\tconst delayMs = computeRetryDelayMs(policy, this._attempt, { retryAfterMs: classified.retryAfterMs });\n\n\t\t// The retry window counts as active work from the instant listeners hear about it:\n\t\t// isRetrying must already be true inside onRetryStart handlers so prompts arriving there\n\t\t// queue as steering instead of racing the retry continuation.\n\t\tthis._abortController = new AbortController();\n\n\t\tthis.events.onRetryStart({\n\t\t\tattempt: this._attempt,\n\t\t\tmaxAttempts,\n\t\t\tdelayMs,\n\t\t\terrorMessage: message.errorMessage || \"Unknown error\",\n\t\t});\n\n\t\t// Remove the trailing assistant error from live agent state (the host session keeps it in history).\n\t\tconst messages = this.agent.state.messages;\n\t\tif (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n\t\t\tthis.agent.state.messages = messages.slice(0, -1);\n\t\t}\n\n\t\ttry {\n\t\t\tawait sleepAbortable(delayMs, this._abortController.signal);\n\t\t} catch {\n\t\t\t// Aborted mid-backoff: report the cancellation and reset so the next turn starts clean.\n\t\t\tconst attempt = this._attempt;\n\t\t\tthis._attempt = 0;\n\t\t\tthis.events.onRetryEnd({ success: false, attempt, finalError: \"Retry cancelled\" });\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tthis._abortController = undefined;\n\t\t}\n\n\t\treturn true;\n\t}\n}\n"]}
1
+ {"version":3,"file":"retry-controller.js","sourceRoot":"","sources":["../../src/reliability/retry-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Host-agnostic auto-retry driver.\n *\n * Owns the retry attempt counter and the abortable backoff for one agent run. It reads the\n * failure verdict from {@link classifyFailure} (fed a host-computed context-overflow flag), so\n * billing/auth are terminal and overflow routes to compaction — never to a pointless retry.\n * The controller only ever touches `agent.state.messages` (it drops the trailing assistant error\n * before retrying); durable history stays the host session's responsibility.\n *\n * Ported from AgentSession._prepareRetry / _isRetryableError so the exact event ordering and\n * exhaustion semantics carry over: the retry window is marked active (isRetrying) before the\n * start event fires, so prompts arriving inside start handlers queue as steering instead of\n * racing the retry continuation.\n */\n\nimport { isContextOverflow } from \"@caupulican/pi-ai/overflow\";\nimport type { AssistantMessage } from \"@caupulican/pi-ai/types\";\nimport type { AgentMessage } from \"../types.ts\";\nimport { classifyFailure } from \"./classifier.ts\";\nimport { computeRetryDelayMs, RetryDelayExceededError, type RetryPolicy, sleepAbortable } from \"./retry.ts\";\n\n/** The slice of an Agent the retry driver reads and mutates: just the live transcript. */\nexport interface RetryAgent {\n\treadonly state: { messages: AgentMessage[] };\n}\n\nexport interface RetryStartInfo {\n\tattempt: number;\n\tmaxAttempts: number;\n\tdelayMs: number;\n\terrorMessage: string;\n}\n\nexport interface RetryEndInfo {\n\tsuccess: boolean;\n\tattempt: number;\n\tfinalError?: string;\n}\n\nexport interface RetryEvents {\n\tonRetryStart(info: RetryStartInfo): void;\n\tonRetryEnd(info: RetryEndInfo): void;\n}\n\n/** Runtime retry policy: the backoff shape plus the on/off switch the host resolves per call. */\nexport type RetryControllerPolicy = RetryPolicy & { enabled: boolean };\n\nfunction hasMeaningfulAssistantProgress(message: AssistantMessage): boolean {\n\treturn message.content.some((block) => {\n\t\tif (block.type === \"text\") return block.text.trim().length > 0;\n\t\tif (block.type === \"thinking\") return block.thinking.trim().length > 0;\n\t\treturn block.type === \"toolCall\";\n\t});\n}\n\n/**\n * xAI can accept a subscription request, allocate a response id, emit an empty reasoning item,\n * and then remain silent until the quiet watchdog fires. Repeating that exact zero-progress wait\n * through every configured retry held one observed foreground run for four consecutive 10-minute\n * windows. Preserve one recovery attempt, but require real generated content before granting the\n * ordinary retry allowance. Capacity responses and stalls after real progress remain unchanged.\n */\nfunction effectiveMaxAttempts(\n\tmessage: AssistantMessage,\n\treason: ReturnType<typeof classifyFailure>[\"reason\"],\n\tconfiguredMaxAttempts: number,\n): number {\n\tif (message.provider === \"xai\" && reason === \"stream_stall\" && !hasMeaningfulAssistantProgress(message)) {\n\t\treturn Math.min(configuredMaxAttempts, 1);\n\t}\n\treturn configuredMaxAttempts;\n}\n\nexport class RetryController {\n\tprivate _attempt = 0;\n\tprivate _abortController: AbortController | undefined;\n\tprivate readonly agent: RetryAgent;\n\tprivate readonly getPolicy: () => RetryControllerPolicy;\n\tprivate readonly events: RetryEvents;\n\tprivate readonly getContextWindow: () => number;\n\n\tconstructor(\n\t\tagent: RetryAgent,\n\t\tgetPolicy: () => RetryControllerPolicy,\n\t\tevents: RetryEvents,\n\t\tgetContextWindow: () => number,\n\t) {\n\t\tthis.agent = agent;\n\t\tthis.getPolicy = getPolicy;\n\t\tthis.events = events;\n\t\tthis.getContextWindow = getContextWindow;\n\t}\n\n\t/** Completed retry attempts for the current run (0 when not retrying). */\n\tget attempt(): number {\n\t\treturn this._attempt;\n\t}\n\n\t/** True from the instant onRetryStart fires until the backoff sleep resolves or is aborted. */\n\tget isRetrying(): boolean {\n\t\treturn this._abortController !== undefined;\n\t}\n\n\t/** Clear the attempt counter — the host calls this after a successful turn or a final failure. */\n\treset(): void {\n\t\tthis._attempt = 0;\n\t}\n\n\t/** Cancel an in-progress backoff; the pending prepareRetry resolves false. */\n\tabort(): void {\n\t\tthis._abortController?.abort();\n\t}\n\n\t/**\n\t * Classify `message`; if it is retryable and attempts remain, drop the trailing assistant\n\t * error from agent state, emit the start event, and wait out the backoff (abortable).\n\t * @returns true if the caller should continue the agent, false otherwise.\n\t */\n\tasync prepareRetry(message: AssistantMessage): Promise<boolean> {\n\t\tconst policy = this.getPolicy();\n\t\tif (!policy.enabled) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// The classifier is the single source of the retry verdict: context overflow (host-computed\n\t\t// from the live window) routes to compaction, billing/auth are terminal, transient failures retry.\n\t\tconst classified = classifyFailure({\n\t\t\tmessage: message.errorMessage ?? \"\",\n\t\t\tcontextOverflow: isContextOverflow(message, this.getContextWindow()),\n\t\t\tprovider: message.provider,\n\t\t});\n\t\tif (!classified.retryable) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst maxAttempts = effectiveMaxAttempts(message, classified.reason, policy.maxAttempts);\n\t\tconst nextAttempt = this._attempt + 1;\n\t\tif (nextAttempt > maxAttempts) return false;\n\n\t\tlet delayMs: number;\n\t\ttry {\n\t\t\tdelayMs = computeRetryDelayMs(policy, nextAttempt, { retryAfterMs: classified.retryAfterMs });\n\t\t} catch (error) {\n\t\t\tif (error instanceof RetryDelayExceededError) return false;\n\t\t\tthrow error;\n\t\t}\n\t\tthis._attempt = nextAttempt;\n\n\t\t// The retry window counts as active work from the instant listeners hear about it:\n\t\t// isRetrying must already be true inside onRetryStart handlers so prompts arriving there\n\t\t// queue as steering instead of racing the retry continuation.\n\t\tthis._abortController = new AbortController();\n\n\t\tthis.events.onRetryStart({\n\t\t\tattempt: this._attempt,\n\t\t\tmaxAttempts,\n\t\t\tdelayMs,\n\t\t\terrorMessage: message.errorMessage || \"Unknown error\",\n\t\t});\n\n\t\t// Remove the trailing assistant error from live agent state (the host session keeps it in history).\n\t\tconst messages = this.agent.state.messages;\n\t\tif (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n\t\t\tthis.agent.state.messages = messages.slice(0, -1);\n\t\t}\n\n\t\ttry {\n\t\t\tawait sleepAbortable(delayMs, this._abortController.signal);\n\t\t} catch {\n\t\t\t// Aborted mid-backoff: report the cancellation and reset so the next turn starts clean.\n\t\t\tconst attempt = this._attempt;\n\t\t\tthis._attempt = 0;\n\t\t\tthis.events.onRetryEnd({ success: false, attempt, finalError: \"Retry cancelled\" });\n\t\t\treturn false;\n\t\t} finally {\n\t\t\tthis._abortController = undefined;\n\t\t}\n\n\t\treturn true;\n\t}\n}\n"]}
@@ -2,17 +2,25 @@
2
2
  export interface RetryPolicy {
3
3
  maxAttempts: number;
4
4
  baseDelayMs: number;
5
+ /** Cap for locally computed exponential backoff. */
5
6
  maxDelayMs: number;
7
+ /** Longest provider-requested wait accepted; 0 disables this bound. Defaults to maxDelayMs. */
8
+ maxRetryAfterMs?: number;
6
9
  /** Fraction of the computed delay added as uniform random jitter (0..1). */
7
10
  jitterRatio: number;
8
11
  }
9
12
  export declare const DEFAULT_RETRY_POLICY: RetryPolicy;
10
13
  export interface ComputeRetryDelayOptions {
11
- /** Provider-suggested delay (e.g. from Retry-After); wins over backoff but is capped. */
14
+ /** Provider-suggested minimum delay (e.g. from Retry-After); wins over local backoff. */
12
15
  retryAfterMs?: number;
13
16
  /** Injectable RNG for deterministic tests. Defaults to Math.random. */
14
17
  random?: () => number;
15
18
  }
19
+ export declare class RetryDelayExceededError extends Error {
20
+ readonly retryAfterMs: number;
21
+ readonly maxRetryAfterMs: number;
22
+ constructor(retryAfterMs: number, maxRetryAfterMs: number);
23
+ }
16
24
  export declare function computeRetryDelayMs(policy: RetryPolicy, attempt: number, opts?: ComputeRetryDelayOptions): number;
17
25
  /** Abortable sleep: resolves after ms, rejects with the abort reason if the signal fires. */
18
26
  export declare function sleepAbortable(ms: number, signal?: AbortSignal): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/reliability/retry.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,oBAAoB,EAAE,WAKlC,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACxC,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,MAAM,CAQjH;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9E"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/reliability/retry.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,+FAA+F;IAC/F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,oBAAoB,EAAE,WAKlC,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACxC,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED,qBAAa,uBAAwB,SAAQ,KAAK;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,YAAY,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAOxD;CACD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,wBAAwB,GAAG,MAAM,CAcjH;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9E"}
@@ -4,9 +4,24 @@ export const DEFAULT_RETRY_POLICY = {
4
4
  maxDelayMs: 120_000,
5
5
  jitterRatio: 0,
6
6
  };
7
+ export class RetryDelayExceededError extends Error {
8
+ constructor(retryAfterMs, maxRetryAfterMs) {
9
+ super(`Provider requested ${Math.ceil(retryAfterMs / 1000)}s retry delay (max: ${Math.ceil(maxRetryAfterMs / 1000)}s).\nProvider retry directive: do not retry.`);
10
+ this.name = "RetryDelayExceededError";
11
+ this.retryAfterMs = retryAfterMs;
12
+ this.maxRetryAfterMs = maxRetryAfterMs;
13
+ }
14
+ }
7
15
  export function computeRetryDelayMs(policy, attempt, opts) {
8
16
  if (opts?.retryAfterMs !== undefined) {
9
- return Math.min(opts.retryAfterMs, policy.maxDelayMs);
17
+ const retryAfterMs = Math.max(0, opts.retryAfterMs);
18
+ if (!Number.isFinite(retryAfterMs))
19
+ throw new TypeError("Provider retry delay must be finite");
20
+ const maxRetryAfterMs = policy.maxRetryAfterMs ?? policy.maxDelayMs;
21
+ if (maxRetryAfterMs > 0 && retryAfterMs > maxRetryAfterMs) {
22
+ throw new RetryDelayExceededError(retryAfterMs, maxRetryAfterMs);
23
+ }
24
+ return retryAfterMs;
10
25
  }
11
26
  const exponential = Math.min(policy.baseDelayMs * 2 ** (Math.max(1, attempt) - 1), policy.maxDelayMs);
12
27
  if (policy.jitterRatio <= 0)
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/reliability/retry.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,oBAAoB,GAAgB;IAChD,WAAW,EAAE,CAAC;IACd,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,OAAO;IACnB,WAAW,EAAE,CAAC;CACd,CAAC;AASF,MAAM,UAAU,mBAAmB,CAAC,MAAmB,EAAE,OAAe,EAAE,IAA+B;IACxG,IAAI,IAAI,EAAE,YAAY,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACvD,CAAC;IACD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IACtG,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,GAAG,WAAW,GAAG,MAAM,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,cAAc,CAAC,EAAU,EAAE,MAAoB;IAC9D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YACrB,MAAM,CAAC,MAAM,CAAC,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YAC9E,OAAO;QACR,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7B,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,OAAO,EAAE,CAAC;QACX,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,MAAM,OAAO,GAAG,GAAG,EAAE;YACpB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,MAAM,EAAE,MAAM,YAAY,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;QAChF,CAAC,CAAC;QACF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/** Retry backoff policy. jitterRatio 0 reproduces legacy fixed 2s/4s/8s behavior. */\nexport interface RetryPolicy {\n\tmaxAttempts: number;\n\tbaseDelayMs: number;\n\tmaxDelayMs: number;\n\t/** Fraction of the computed delay added as uniform random jitter (0..1). */\n\tjitterRatio: number;\n}\n\nexport const DEFAULT_RETRY_POLICY: RetryPolicy = {\n\tmaxAttempts: 3,\n\tbaseDelayMs: 2000,\n\tmaxDelayMs: 120_000,\n\tjitterRatio: 0,\n};\n\nexport interface ComputeRetryDelayOptions {\n\t/** Provider-suggested delay (e.g. from Retry-After); wins over backoff but is capped. */\n\tretryAfterMs?: number;\n\t/** Injectable RNG for deterministic tests. Defaults to Math.random. */\n\trandom?: () => number;\n}\n\nexport function computeRetryDelayMs(policy: RetryPolicy, attempt: number, opts?: ComputeRetryDelayOptions): number {\n\tif (opts?.retryAfterMs !== undefined) {\n\t\treturn Math.min(opts.retryAfterMs, policy.maxDelayMs);\n\t}\n\tconst exponential = Math.min(policy.baseDelayMs * 2 ** (Math.max(1, attempt) - 1), policy.maxDelayMs);\n\tif (policy.jitterRatio <= 0) return exponential;\n\tconst random = opts?.random ?? Math.random;\n\treturn Math.round(exponential + policy.jitterRatio * exponential * random());\n}\n\n/** Abortable sleep: resolves after ms, rejects with the abort reason if the signal fires. */\nexport function sleepAbortable(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(signal.reason instanceof Error ? signal.reason : new Error(\"Aborted\"));\n\t\t\treturn;\n\t\t}\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst onAbort = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal?.reason instanceof Error ? signal.reason : new Error(\"Aborted\"));\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n}\n"]}
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/reliability/retry.ts"],"names":[],"mappings":"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","sourcesContent":["/** Retry backoff policy. jitterRatio 0 reproduces legacy fixed 2s/4s/8s behavior. */\nexport interface RetryPolicy {\n\tmaxAttempts: number;\n\tbaseDelayMs: number;\n\t/** Cap for locally computed exponential backoff. */\n\tmaxDelayMs: number;\n\t/** Longest provider-requested wait accepted; 0 disables this bound. Defaults to maxDelayMs. */\n\tmaxRetryAfterMs?: number;\n\t/** Fraction of the computed delay added as uniform random jitter (0..1). */\n\tjitterRatio: number;\n}\n\nexport const DEFAULT_RETRY_POLICY: RetryPolicy = {\n\tmaxAttempts: 3,\n\tbaseDelayMs: 2000,\n\tmaxDelayMs: 120_000,\n\tjitterRatio: 0,\n};\n\nexport interface ComputeRetryDelayOptions {\n\t/** Provider-suggested minimum delay (e.g. from Retry-After); wins over local backoff. */\n\tretryAfterMs?: number;\n\t/** Injectable RNG for deterministic tests. Defaults to Math.random. */\n\trandom?: () => number;\n}\n\nexport class RetryDelayExceededError extends Error {\n\treadonly retryAfterMs: number;\n\treadonly maxRetryAfterMs: number;\n\n\tconstructor(retryAfterMs: number, maxRetryAfterMs: number) {\n\t\tsuper(\n\t\t\t`Provider requested ${Math.ceil(retryAfterMs / 1000)}s retry delay (max: ${Math.ceil(maxRetryAfterMs / 1000)}s).\\nProvider retry directive: do not retry.`,\n\t\t);\n\t\tthis.name = \"RetryDelayExceededError\";\n\t\tthis.retryAfterMs = retryAfterMs;\n\t\tthis.maxRetryAfterMs = maxRetryAfterMs;\n\t}\n}\n\nexport function computeRetryDelayMs(policy: RetryPolicy, attempt: number, opts?: ComputeRetryDelayOptions): number {\n\tif (opts?.retryAfterMs !== undefined) {\n\t\tconst retryAfterMs = Math.max(0, opts.retryAfterMs);\n\t\tif (!Number.isFinite(retryAfterMs)) throw new TypeError(\"Provider retry delay must be finite\");\n\t\tconst maxRetryAfterMs = policy.maxRetryAfterMs ?? policy.maxDelayMs;\n\t\tif (maxRetryAfterMs > 0 && retryAfterMs > maxRetryAfterMs) {\n\t\t\tthrow new RetryDelayExceededError(retryAfterMs, maxRetryAfterMs);\n\t\t}\n\t\treturn retryAfterMs;\n\t}\n\tconst exponential = Math.min(policy.baseDelayMs * 2 ** (Math.max(1, attempt) - 1), policy.maxDelayMs);\n\tif (policy.jitterRatio <= 0) return exponential;\n\tconst random = opts?.random ?? Math.random;\n\treturn Math.round(exponential + policy.jitterRatio * exponential * random());\n}\n\n/** Abortable sleep: resolves after ms, rejects with the abort reason if the signal fires. */\nexport function sleepAbortable(ms: number, signal?: AbortSignal): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (signal?.aborted) {\n\t\t\treject(signal.reason instanceof Error ? signal.reason : new Error(\"Aborted\"));\n\t\t\treturn;\n\t\t}\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst onAbort = () => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(signal?.reason instanceof Error ? signal.reason : new Error(\"Aborted\"));\n\t\t};\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t});\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caupulican/pi-agent-core",
3
- "version": "0.96.0",
3
+ "version": "0.96.2",
4
4
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -146,7 +146,7 @@
146
146
  "prepublishOnly": "npm run clean && npm run build"
147
147
  },
148
148
  "dependencies": {
149
- "@caupulican/pi-ai": "^0.96.0",
149
+ "@caupulican/pi-ai": "^0.96.2",
150
150
  "ignore": "7.0.5",
151
151
  "typebox": "1.1.38",
152
152
  "yaml": "2.9.0"