@caupulican/pi-agent-core 0.90.6 → 0.90.11

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.
Files changed (41) hide show
  1. package/dist/agent-loop.d.ts +10 -3
  2. package/dist/agent-loop.d.ts.map +1 -1
  3. package/dist/agent-loop.js +16 -24
  4. package/dist/agent-loop.js.map +1 -1
  5. package/dist/agent.d.ts +4 -0
  6. package/dist/agent.d.ts.map +1 -1
  7. package/dist/agent.js +12 -3
  8. package/dist/agent.js.map +1 -1
  9. package/dist/compaction/compaction.d.ts.map +1 -1
  10. package/dist/compaction/compaction.js +1 -34
  11. package/dist/compaction/compaction.js.map +1 -1
  12. package/dist/compaction/extraction.d.ts +1 -0
  13. package/dist/compaction/extraction.d.ts.map +1 -1
  14. package/dist/compaction/extraction.js +1 -1
  15. package/dist/compaction/extraction.js.map +1 -1
  16. package/dist/compaction/utils.d.ts +13 -1
  17. package/dist/compaction/utils.d.ts.map +1 -1
  18. package/dist/compaction/utils.js +49 -1
  19. package/dist/compaction/utils.js.map +1 -1
  20. package/dist/compaction/verification.d.ts.map +1 -1
  21. package/dist/compaction/verification.js +154 -6
  22. package/dist/compaction/verification.js.map +1 -1
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -0
  26. package/dist/index.js.map +1 -1
  27. package/dist/provider-request-planner.d.ts +8 -0
  28. package/dist/provider-request-planner.d.ts.map +1 -1
  29. package/dist/provider-request-planner.js +8 -1
  30. package/dist/provider-request-planner.js.map +1 -1
  31. package/dist/provider-tool-projection.d.ts.map +1 -1
  32. package/dist/provider-tool-projection.js +4 -11
  33. package/dist/provider-tool-projection.js.map +1 -1
  34. package/dist/tool-failure-memory.d.ts.map +1 -1
  35. package/dist/tool-failure-memory.js +27 -3
  36. package/dist/tool-failure-memory.js.map +1 -1
  37. package/dist/tool-protocol-residue.d.ts +10 -0
  38. package/dist/tool-protocol-residue.d.ts.map +1 -0
  39. package/dist/tool-protocol-residue.js +105 -0
  40. package/dist/tool-protocol-residue.js.map +1 -0
  41. package/package.json +2 -2
@@ -3,9 +3,16 @@
3
3
  * Transforms to Message[] only at the LLM call boundary.
4
4
  */
5
5
  import { EventStream } from "@caupulican/pi-ai/event-stream";
6
+ import { ToolFailureRecoveryGate } from "./tool-failure-recovery-gate.ts";
6
7
  import type { AgentContext, AgentEvent, AgentLoopConfig, AgentMessage, AgentToolCall, StreamFn, ToolCallRepairInfo } from "./types.ts";
7
- export { resolveRequestPreflightMaxTokens } from "./provider-request-planner.ts";
8
+ export { narrowRequestMaxTokens, resolveRequestPreflightMaxTokens } from "./provider-request-planner.ts";
8
9
  export type AgentEventSink = (event: AgentEvent) => Promise<void> | void;
10
+ /** Bounded no-progress state retained across host-owned continuations of one logical prompt. */
11
+ export interface AgentLoopContinuationState {
12
+ stallWindow: string[];
13
+ toolFailureRecoveryGate: ToolFailureRecoveryGate;
14
+ }
15
+ export declare function createAgentLoopContinuationState(): AgentLoopContinuationState;
9
16
  /**
10
17
  * Start an agent loop with a new prompt message.
11
18
  * The prompt is added to the context and events are emitted for it.
@@ -20,8 +27,8 @@ export declare function agentLoop(prompts: AgentMessage[], context: AgentContext
20
27
  * This cannot be validated here since `convertToLlm` is only called once per turn.
21
28
  */
22
29
  export declare function agentLoopContinue(context: AgentContext, config: AgentLoopConfig, signal?: AbortSignal, streamFn?: StreamFn): EventStream<AgentEvent, AgentMessage[]>;
23
- export declare function runAgentLoop(prompts: AgentMessage[], context: AgentContext, config: AgentLoopConfig, emit: AgentEventSink, signal?: AbortSignal, streamFn?: StreamFn): Promise<AgentMessage[]>;
24
- export declare function runAgentLoopContinue(context: AgentContext, config: AgentLoopConfig, emit: AgentEventSink, signal?: AbortSignal, streamFn?: StreamFn): Promise<AgentMessage[]>;
30
+ export declare function runAgentLoop(prompts: AgentMessage[], context: AgentContext, config: AgentLoopConfig, emit: AgentEventSink, signal?: AbortSignal, streamFn?: StreamFn, continuationState?: AgentLoopContinuationState): Promise<AgentMessage[]>;
31
+ export declare function runAgentLoopContinue(context: AgentContext, config: AgentLoopConfig, emit: AgentEventSink, signal?: AbortSignal, streamFn?: StreamFn, continuationState?: AgentLoopContinuationState): Promise<AgentMessage[]>;
25
32
  /**
26
33
  * Start one provider request through the canonical agent-loop boundary.
27
34
  *
@@ -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;AAoC7D,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAEZ,aAAa,EAEb,QAAQ,EACR,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,gCAAgC,EAAE,MAAM,+BAA+B,CAAC;AAEjF,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE;;;GAGG;AACH,wBAAgB,SAAS,CACxB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,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,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC,YAAY,EAAE,CAAC,CAWzB;AAmVD;;;;;;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;AAwiCD,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;AA4B7D,OAAO,EAGN,uBAAuB,EAGvB,MAAM,iCAAiC,CAAC;AAGzC,OAAO,KAAK,EACX,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EAEZ,aAAa,EAEb,QAAQ,EACR,kBAAkB,EAClB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,sBAAsB,EAAE,gCAAgC,EAAE,MAAM,+BAA+B,CAAC;AAEzG,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAEzE,gGAAgG;AAChG,MAAM,WAAW,0BAA0B;IAC1C,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,CAgBzB;AAED,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,EACnB,iBAAiB,GAAE,0BAA+D,GAChF,OAAO,CAAC,YAAY,EAAE,CAAC,CAWzB;AAoVD;;;;;;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;AAiiCD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,GAAG,kBAAkB,GAAG,SAAS,CAO7F"}
@@ -9,9 +9,13 @@ import { startPlannedAgentProviderRequest } from "./provider-request-planner.js"
9
9
  import { assessToolFailure, clearToolFailure, createRepeatedToolFailureResult, createToolFailureMemoryTracker, createToolFailureOperationExhaustedResult, createToolFailureRecoveryExhaustedResult, createToolFailureResult, getUnresolvedToolFailure, normalizeToolSignature, rememberToolFailure, toolFailureCorrection, } from "./tool-failure-memory.js";
10
10
  import { TOOL_FAILURE_RECOVERY_ACCOUNTING_WAVE_SIZE, ToolFailureRecoveryGate, } from "./tool-failure-recovery-gate.js";
11
11
  import { appendMandatoryToolFailureDeliveryPrompt } from "./tool-failure-recovery-protocol.js";
12
+ import { rejectNativeToolProtocolResidue } from "./tool-protocol-residue.js";
12
13
  import { DEFAULT_MAX_STALL_TURNS } from "./types.js";
13
14
  import { createEmptyUsage } from "./usage.js";
14
- export { resolveRequestPreflightMaxTokens } from "./provider-request-planner.js";
15
+ export { narrowRequestMaxTokens, resolveRequestPreflightMaxTokens } from "./provider-request-planner.js";
16
+ export function createAgentLoopContinuationState() {
17
+ return { stallWindow: [], toolFailureRecoveryGate: new ToolFailureRecoveryGate() };
18
+ }
15
19
  /**
16
20
  * Start an agent loop with a new prompt message.
17
21
  * The prompt is added to the context and events are emitted for it.
@@ -46,7 +50,7 @@ function streamAgentLoop(config, signal, run) {
46
50
  });
47
51
  return stream;
48
52
  }
49
- export async function runAgentLoop(prompts, context, config, emit, signal, streamFn) {
53
+ export async function runAgentLoop(prompts, context, config, emit, signal, streamFn, continuationState = createAgentLoopContinuationState()) {
50
54
  const newMessages = [...prompts];
51
55
  const currentContext = {
52
56
  ...context,
@@ -58,16 +62,16 @@ export async function runAgentLoop(prompts, context, config, emit, signal, strea
58
62
  await emit({ type: "message_start", message: prompt });
59
63
  await emit({ type: "message_end", message: prompt });
60
64
  }
61
- await runLoop(currentContext, newMessages, config, signal, emit, streamFn);
65
+ await runLoop(currentContext, newMessages, config, signal, emit, streamFn, continuationState);
62
66
  return newMessages;
63
67
  }
64
- export async function runAgentLoopContinue(context, config, emit, signal, streamFn) {
68
+ export async function runAgentLoopContinue(context, config, emit, signal, streamFn, continuationState = createAgentLoopContinuationState()) {
65
69
  assertContinuableContext(context);
66
70
  const newMessages = [];
67
71
  const currentContext = { ...context, messages: [...context.messages] };
68
72
  await emit({ type: "agent_start" });
69
73
  await emit({ type: "turn_start" });
70
- await runLoop(currentContext, newMessages, config, signal, emit, streamFn);
74
+ await runLoop(currentContext, newMessages, config, signal, emit, streamFn, continuationState);
71
75
  return newMessages;
72
76
  }
73
77
  function assertContinuableContext(context) {
@@ -167,7 +171,7 @@ function repeatsSuccessfulTextProtocolBatch(incomingSignature, toolCalls, previo
167
171
  /**
168
172
  * Main loop logic shared by agentLoop and agentLoopContinue.
169
173
  */
170
- async function runLoop(initialContext, newMessages, initialConfig, signal, emit, streamFn) {
174
+ async function runLoop(initialContext, newMessages, initialConfig, signal, emit, streamFn, continuationState = createAgentLoopContinuationState()) {
171
175
  let currentContext = initialContext;
172
176
  let config = initialConfig;
173
177
  let firstTurn = true;
@@ -181,11 +185,11 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
181
185
  // window slides past it. Counts only turns that issued tool calls, so varied/long work never trips
182
186
  // it. `0` disables.
183
187
  const stallLimit = config.maxStallTurns ?? DEFAULT_MAX_STALL_TURNS;
184
- const stallWindow = [];
188
+ const stallWindow = continuationState.stallWindow;
185
189
  const validationFailureTracker = { repeats: 0 };
186
190
  const repairTeachTracker = new Map();
187
191
  let toolFailureMemory = createToolFailureMemoryTracker(currentContext.messages);
188
- const toolFailureRecoveryGate = new ToolFailureRecoveryGate();
192
+ const toolFailureRecoveryGate = continuationState.toolFailureRecoveryGate;
189
193
  let mandatoryRecoveryDeliveryPending = false;
190
194
  let lastSuccessfulTextProtocolBatch;
191
195
  // Check for steering messages at start (user may have typed while waiting)
@@ -376,7 +380,7 @@ async function streamAssistantResponse(context, config, signal, emit, streamFn)
376
380
  const response = await startAgentProviderRequest(context, config, signal, streamFn);
377
381
  let partialMessage = null;
378
382
  let addedPartial = false;
379
- for await (const event of response) {
383
+ responseEvents: for await (const event of response) {
380
384
  switch (event.type) {
381
385
  case "start":
382
386
  partialMessage = event.partial;
@@ -404,23 +408,11 @@ async function streamAssistantResponse(context, config, signal, emit, streamFn)
404
408
  }
405
409
  break;
406
410
  case "done":
407
- case "error": {
408
- const finalMessage = await response.result();
409
- if (addedPartial) {
410
- context.messages[context.messages.length - 1] = finalMessage;
411
- }
412
- else {
413
- context.messages.push(finalMessage);
414
- }
415
- if (!addedPartial) {
416
- await emit({ type: "message_start", message: { ...finalMessage } });
417
- }
418
- await emit({ type: "message_end", message: finalMessage });
419
- return finalMessage;
420
- }
411
+ case "error":
412
+ break responseEvents;
421
413
  }
422
414
  }
423
- const finalMessage = await response.result();
415
+ const finalMessage = rejectNativeToolProtocolResidue(await response.result(), context.tools ?? [], Boolean(config.textToolCallProtocol));
424
416
  if (addedPartial) {
425
417
  context.messages[context.messages.length - 1] = finalMessage;
426
418
  }