@caupulican/pi-agent-core 0.93.3 → 0.93.5

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.
@@ -19,6 +19,8 @@ export interface ToolFailureMemoryRecord {
19
19
  phase: ToolFailurePhase;
20
20
  failureCode: string;
21
21
  diagnostic?: string;
22
+ /** Bounded tool-owned source evidence needed to construct a changed operation. */
23
+ evidence?: string;
22
24
  correction: string;
23
25
  attemptMemory?: "discard";
24
26
  }
@@ -37,6 +39,8 @@ export interface ToolFailureDirectiveDetails {
37
39
  }
38
40
  export type ToolFailureResultDetails = ToolFailureMemoryDetails | ToolFailureDirectiveDetails;
39
41
  export type ToolFailureMemoryTracker = Map<string, ToolFailureMemoryRecord>;
42
+ /** Normalize and bound tool-owned evidence at every live and persisted ingress. */
43
+ export declare function sanitizeToolFailureEvidence(value: unknown): string | undefined;
40
44
  export declare function normalizeToolSignature(pairs: Array<[string, unknown]>): string;
41
45
  export declare function getToolExecutionKey(tool: string, args: unknown): string;
42
46
  /** Read the four hash words already encoded by this module's exact execution-key owner. */
@@ -62,7 +66,11 @@ export interface ToolFailureAssessment {
62
66
  failureCode: string;
63
67
  phase: ToolFailurePhase;
64
68
  diagnostic?: string;
69
+ /** Bounded raw-output tail of an executed process-exit failure. */
70
+ evidence?: string;
65
71
  guidance: string;
72
+ /** Catalogued per-error guidance; set only when a registry policy matched the failure message. */
73
+ policyGuidance?: string;
66
74
  attemptMemory?: "discard";
67
75
  }
68
76
  export declare function assessToolFailure(message: string, state: ToolFailureState, errorClass?: string): ToolFailureAssessment;
@@ -76,7 +84,7 @@ export interface ToolFailureTelemetry {
76
84
  /** Read only bounded failure identity and guidance; operation arguments never cross this telemetry boundary. */
77
85
  export declare function readToolFailureTelemetry(details: unknown): ToolFailureTelemetry | undefined;
78
86
  export declare function createToolFailureMemoryTracker(messages: AgentMessage[]): ToolFailureMemoryTracker;
79
- export declare function rememberToolFailure(tracker: ToolFailureMemoryTracker, tool: string, args: unknown, state: ToolFailureState, failureCode: string, correction: string, diagnostic?: string, phase?: ToolFailurePhase): ToolFailureMemoryRecord;
87
+ export declare function rememberToolFailure(tracker: ToolFailureMemoryTracker, tool: string, args: unknown, state: ToolFailureState, failureCode: string, correction: string, diagnostic?: string, phase?: ToolFailurePhase, evidence?: string): ToolFailureMemoryRecord;
80
88
  export declare function clearToolFailure(tracker: ToolFailureMemoryTracker, tool: string, args: unknown): void;
81
89
  export declare function createToolFailureResult(record: ToolFailureMemoryRecord, terminate?: boolean): AgentToolResult<ToolFailureResultDetails>;
82
90
  export declare function createRepeatedToolFailureResult(record: ToolFailureMemoryRecord): AgentToolResult<ToolFailureMemoryDetails>;
@@ -1 +1 @@
1
- {"version":3,"file":"tool-failure-memory.d.ts","sourceRoot":"","sources":["../src/tool-failure-memory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-failure-memory.d.ts","sourceRoot":"","sources":["../src/tool-failure-memory.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,9 @@ const TOOL_FAILURE_EXECUTION_KEY = Symbol("ToolFailureExecutionKey");
7
7
  const MAX_OPERATION_CHARS = 240;
8
8
  const MAX_FAILURE_CODE_CHARS = 48;
9
9
  const MAX_DIAGNOSTIC_CHARS = 240;
10
- const MAX_CORRECTION_CHARS = 320;
10
+ const MAX_CORRECTION_CHARS = 480;
11
+ const MAX_TOOL_FAILURE_EVIDENCE_CHARS = 1_600;
12
+ const MAX_ACTIVE_FAILURE_EVIDENCE_CHARS = 2_400;
11
13
  const MAX_TOOL_NAME_CHARS = 64;
12
14
  const TOOL_SIGNATURE_HEX_CHARS = 32;
13
15
  const MAX_ACTIVE_FAILURES = 8;
@@ -25,6 +27,13 @@ function truncate(value, maxChars) {
25
27
  end--;
26
28
  return `${value.slice(0, end)}…`;
27
29
  }
30
+ /** Normalize and bound tool-owned evidence at every live and persisted ingress. */
31
+ export function sanitizeToolFailureEvidence(value) {
32
+ if (typeof value !== "string")
33
+ return undefined;
34
+ const sanitized = sanitizeBinaryOutput(value).trim();
35
+ return sanitized ? truncate(sanitized, MAX_TOOL_FAILURE_EVIDENCE_CHARS) : undefined;
36
+ }
28
37
  function truncateMiddle(value, maxChars) {
29
38
  if (value.length <= maxChars)
30
39
  return value;
@@ -429,6 +438,19 @@ function boundedFailureCode(value) {
429
438
  * always the last line it appends — outranks any earlier, non-authoritative line that matches.
430
439
  */
431
440
  const EXIT_STATUS_LINE_PATTERN = /^(?:\S+\s+)?(?:exit(?:ed)?(?:\s+with)?(?:\s+code)?|exitcode)\s*[:=]?\s*(-?\d+)\b/i;
441
+ /**
442
+ * bash.ts appends `cwd: <dir>` after its exit trailer on failures. The line is harness status, not
443
+ * a cause: it must never displace a real diagnostic (a path may contain words like "error"), and it
444
+ * reaches the model through the process-exit evidence tail instead.
445
+ */
446
+ const CWD_STATUS_LINE_PATTERN = /^cwd:\s/i;
447
+ /** Tool-owned status/marker lines that carry no cause and never belong in diagnostic or evidence. */
448
+ function isFailureStatusLine(line) {
449
+ return (/^command (?:exited with code|timed out after|aborted|killed after)\b/i.test(line) ||
450
+ /^outcome:\s*(?:failed|aborted|timeout|output_limit)\b/i.test(line) ||
451
+ /^exitcode:\s*-?\d+\b/i.test(line) ||
452
+ /^(?:stdout|stderr):(?:\s*\(empty\))?$/i.test(line));
453
+ }
432
454
  function processExitFailureCode(message) {
433
455
  const lines = message.split(/\r\n|\n/);
434
456
  for (let index = lines.length - 1; index >= 0; index--) {
@@ -513,7 +535,9 @@ function extractFailureDiagnostic(message, allowUnclassifiedFallback, requireStr
513
535
  const stderrLines = rawLines
514
536
  .slice(stderrMarkerIndex + 1)
515
537
  .map((line) => line.trim())
516
- .filter((line) => line.length > 0 && !/^command (?:exited with code|timed out after|aborted|killed after)\b/i.test(line));
538
+ .filter((line) => line.length > 0 &&
539
+ !/^command (?:exited with code|timed out after|aborted|killed after)\b/i.test(line) &&
540
+ !CWD_STATUS_LINE_PATTERN.test(line));
517
541
  if (stderrLines.length > 0) {
518
542
  const classified = stderrLines.find((line) => strongDiagnosticPattern.test(line));
519
543
  if (classified)
@@ -530,11 +554,7 @@ function extractFailureDiagnostic(message, allowUnclassifiedFallback, requireStr
530
554
  }
531
555
  const lines = rawLines
532
556
  .map((line) => line.trim())
533
- .filter((line) => line.length > 0 &&
534
- !/^command (?:exited with code|timed out after|aborted|killed after)\b/i.test(line) &&
535
- !/^outcome:\s*(?:failed|aborted|timeout|output_limit)\b/i.test(line) &&
536
- !/^exitcode:\s*-?\d+\b/i.test(line) &&
537
- !/^(?:stdout|stderr):(?:\s*\(empty\))?$/i.test(line));
557
+ .filter((line) => line.length > 0 && !isFailureStatusLine(line) && !CWD_STATUS_LINE_PATTERN.test(line));
538
558
  if (lines.length === 0)
539
559
  return undefined;
540
560
  const diagnosticPattern = requireStrongSignal
@@ -546,6 +566,35 @@ function extractFailureDiagnostic(message, allowUnclassifiedFallback, requireStr
546
566
  const diagnostic = classified ?? (allowUnclassifiedFallback ? lines.at(-1) : undefined);
547
567
  return diagnostic ? truncateMiddle(diagnostic, MAX_DIAGNOSTIC_CHARS) : undefined;
548
568
  }
569
+ /**
570
+ * Bounded raw-output tail of an executed process-exit failure. Evidence is the raw-data channel:
571
+ * it keeps the trailing lines that strong-signal diagnostic classification refuses to promote, so
572
+ * strictness never destroys the output needed to construct a changed operation.
573
+ */
574
+ function extractProcessExitEvidence(message) {
575
+ const lines = sanitizeBinaryOutput(message)
576
+ .replaceAll("\r\n", "\n")
577
+ .split("\n")
578
+ .map((line) => line.trim())
579
+ .filter((line) => line.length > 0 && !isFailureStatusLine(line));
580
+ if (lines.length === 0)
581
+ return undefined;
582
+ let start = lines.length - 1;
583
+ let retainedChars = lines[start].length;
584
+ while (start > 0 && retainedChars + 1 + lines[start - 1].length <= MAX_TOOL_FAILURE_EVIDENCE_CHARS) {
585
+ start--;
586
+ retainedChars += 1 + lines[start].length;
587
+ }
588
+ let tail = lines.slice(start).join("\n");
589
+ if (tail.length > MAX_TOOL_FAILURE_EVIDENCE_CHARS) {
590
+ let tailStart = tail.length - MAX_TOOL_FAILURE_EVIDENCE_CHARS;
591
+ const firstCode = tail.charCodeAt(tailStart);
592
+ if (firstCode >= 0xdc00 && firstCode <= 0xdfff)
593
+ tailStart++;
594
+ tail = tail.slice(tailStart);
595
+ }
596
+ return sanitizeToolFailureEvidence(tail);
597
+ }
549
598
  export function assessToolFailure(message, state, errorClass) {
550
599
  const policy = getToolExecutionErrorPolicy(message);
551
600
  const exitFailureCode = processExitFailureCode(message);
@@ -553,14 +602,17 @@ export function assessToolFailure(message, state, errorClass) {
553
602
  const diagnostic = state === "failed" && (!policy || policy.retainDiagnostic)
554
603
  ? extractFailureDiagnostic(message, exitFailureCode === undefined && (errorClass !== undefined || retainPolicyDiagnostic), exitFailureCode !== undefined && !retainPolicyDiagnostic)
555
604
  : undefined;
605
+ const evidence = state === "failed" && exitFailureCode !== undefined ? extractProcessExitEvidence(message) : undefined;
556
606
  const failureCode = policy?.failureCode ?? classifyToolFailure(message, errorClass);
557
607
  return {
558
608
  failureCode,
559
609
  phase: policy?.phase ?? inferToolFailurePhase(state, failureCode),
560
610
  ...(diagnostic ? { diagnostic } : {}),
611
+ ...(evidence ? { evidence } : {}),
561
612
  guidance: policy
562
613
  ? truncate(policy.guidance, MAX_CORRECTION_CHARS)
563
614
  : fallbackFailureGuidance(state, diagnostic !== undefined, inferToolFailurePhase(state, failureCode)),
615
+ ...(policy ? { policyGuidance: truncate(policy.guidance, MAX_CORRECTION_CHARS) } : {}),
564
616
  ...(policy?.attemptMemory === "discard" ? { attemptMemory: "discard" } : {}),
565
617
  };
566
618
  }
@@ -583,6 +635,7 @@ function readFailureRecord(details) {
583
635
  return undefined;
584
636
  }
585
637
  const diagnostic = typeof candidate.diagnostic === "string" ? truncate(candidate.diagnostic, MAX_DIAGNOSTIC_CHARS) : undefined;
638
+ const evidence = sanitizeToolFailureEvidence(candidate.evidence);
586
639
  const retainedCorrection = typeof candidate.correction === "string" ? truncate(candidate.correction, MAX_CORRECTION_CHARS) : undefined;
587
640
  const correction = candidate.state === "failed" && retainedCorrection === LEGACY_GENERIC_EXECUTION_CORRECTION
588
641
  ? fallbackFailureGuidance("failed", diagnostic !== undefined, "execution")
@@ -606,6 +659,7 @@ function readFailureRecord(details) {
606
659
  phase,
607
660
  failureCode: boundedFailureCode(candidate.failureCode),
608
661
  diagnostic,
662
+ evidence,
609
663
  correction,
610
664
  };
611
665
  }
@@ -750,6 +804,7 @@ function analyzeToolFailureContext(messages) {
750
804
  phase: retained?.phase ?? assessment?.phase ?? inferToolFailurePhase(state, "tool_error"),
751
805
  failureCode: retained?.failureCode ?? assessment?.failureCode ?? "tool_error",
752
806
  diagnostic: retained?.diagnostic ?? assessment?.diagnostic,
807
+ evidence: retained?.evidence,
753
808
  correction: retained?.correction ??
754
809
  assessment?.guidance ??
755
810
  fallbackFailureGuidance(state, false, inferToolFailurePhase(state, "tool_error")),
@@ -840,59 +895,50 @@ function analyzeToolFailureContext(messages) {
840
895
  export function createToolFailureMemoryTracker(messages) {
841
896
  return new Map(analyzeToolFailureContext(messages).activeRecords.map((record) => [record.failureKey, record]));
842
897
  }
843
- export function rememberToolFailure(tracker, tool, args, state, failureCode, correction, diagnostic, phase = inferToolFailurePhase(state, failureCode)) {
898
+ export function rememberToolFailure(tracker, tool, args, state, failureCode, correction, diagnostic, phase = inferToolFailurePhase(state, failureCode), evidence) {
844
899
  let kindCount = 1;
845
900
  for (const previous of tracker.values()) {
846
901
  if (previous.tool === tool) {
847
902
  kindCount = Math.max(kindCount, (previous.kindMistakes ?? previous.occurrence) + 1);
848
903
  }
849
904
  }
850
- if (getToolExecutionAttemptMemory(failureCode) === "discard") {
905
+ const isDiscard = getToolExecutionAttemptMemory(failureCode) === "discard";
906
+ if (isDiscard) {
851
907
  for (const [failureKey, previous] of tracker) {
852
908
  if (previous.tool === tool && previous.failureCode === failureCode)
853
909
  tracker.delete(failureKey);
854
910
  }
855
- return {
856
- version: TOOL_FAILURE_MEMORY_VERSION,
857
- failureKey: `directive:${boundedFailureCode(failureCode)}`,
858
- [TOOL_FAILURE_EXECUTION_KEY]: getToolExecutionKey(tool, args),
859
- tool: truncate(tool, MAX_TOOL_NAME_CHARS),
860
- operation: "[discarded]",
861
- occurrence: 1,
862
- kindMistakes: kindCount,
863
- mistakeKind: tool,
864
- state,
865
- phase,
866
- failureCode: boundedFailureCode(failureCode),
867
- diagnostic: diagnostic ? truncate(diagnostic, MAX_DIAGNOSTIC_CHARS) : undefined,
868
- correction: truncate(correction, MAX_CORRECTION_CHARS),
869
- attemptMemory: "discard",
870
- };
871
911
  }
872
- const identity = operationIdentity(tool, args);
873
- const previous = tracker.get(identity.failureKey);
912
+ const identity = isDiscard ? undefined : operationIdentity(tool, args);
913
+ const previous = identity ? tracker.get(identity.failureKey) : undefined;
874
914
  const record = {
875
915
  version: TOOL_FAILURE_MEMORY_VERSION,
876
- failureKey: identity.failureKey,
877
- [TOOL_FAILURE_EXECUTION_KEY]: identity.executionKey,
878
- tool: identity.tool,
879
- operation: identity.operation,
880
- occurrence: (previous?.occurrence ?? 0) + 1,
916
+ failureKey: identity ? identity.failureKey : `directive:${boundedFailureCode(failureCode)}`,
917
+ [TOOL_FAILURE_EXECUTION_KEY]: identity ? identity.executionKey : getToolExecutionKey(tool, args),
918
+ tool: identity ? identity.tool : truncate(tool, MAX_TOOL_NAME_CHARS),
919
+ operation: identity ? identity.operation : "[discarded]",
920
+ occurrence: isDiscard ? 1 : (previous?.occurrence ?? 0) + 1,
881
921
  kindMistakes: kindCount,
882
922
  mistakeKind: tool,
883
923
  state,
884
924
  phase,
885
925
  failureCode: boundedFailureCode(failureCode),
886
926
  diagnostic: diagnostic ? truncate(diagnostic, MAX_DIAGNOSTIC_CHARS) : undefined,
927
+ evidence: sanitizeToolFailureEvidence(evidence),
887
928
  correction: truncate(correction, MAX_CORRECTION_CHARS),
929
+ ...(isDiscard ? { attemptMemory: "discard" } : {}),
888
930
  };
889
- tracker.delete(identity.failureKey);
890
- tracker.set(identity.failureKey, record);
891
- while (tracker.size > MAX_TRACKED_FAILURES) {
892
- const oldest = tracker.keys().next().value;
893
- if (oldest === undefined)
894
- break;
895
- tracker.delete(oldest);
931
+ if (isDiscard)
932
+ return record;
933
+ if (identity) {
934
+ tracker.delete(identity.failureKey);
935
+ tracker.set(identity.failureKey, record);
936
+ while (tracker.size > MAX_TRACKED_FAILURES) {
937
+ const oldest = tracker.keys().next().value;
938
+ if (oldest === undefined)
939
+ break;
940
+ tracker.delete(oldest);
941
+ }
896
942
  }
897
943
  return record;
898
944
  }
@@ -908,7 +954,7 @@ function failureGuidance(record) {
908
954
  ? { repair: record.correction }
909
955
  : { next_action: record.correction };
910
956
  }
911
- function formatRecordJson(record, includeOperation = false) {
957
+ function formatRecordJson(record, includeOperation = false, evidence = record.evidence) {
912
958
  const guidance = failureGuidance(record);
913
959
  return JSON.stringify({
914
960
  ...mandatoryToolFailureRecoveryMetadata(),
@@ -922,6 +968,7 @@ function formatRecordJson(record, includeOperation = false) {
922
968
  ...(includeOperation ? { operation: record.operation } : {}),
923
969
  failure_code: record.failureCode,
924
970
  ...(record.diagnostic ? { diagnostic: record.diagnostic } : {}),
971
+ ...(evidence ? { evidence } : {}),
925
972
  ...guidance,
926
973
  ...(record.attemptMemory === "discard" ? { attempt_memory: "discarded" } : {}),
927
974
  });
@@ -1020,7 +1067,17 @@ export function sanitizeToolFailureContext(messages, systemPrompt) {
1020
1067
  const kindSummary = Object.entries(analysis.kindMistakesSummary)
1021
1068
  .map(([kind, count]) => `${kind}:${count}`)
1022
1069
  .join(", ");
1023
- const lines = records.map((record) => escapePromptData(formatRecordJson(record, true)));
1070
+ let remainingEvidenceChars = MAX_ACTIVE_FAILURE_EVIDENCE_CHARS;
1071
+ const evidenceByFailureKey = new Map();
1072
+ for (let index = records.length - 1; index >= 0 && remainingEvidenceChars > 1; index--) {
1073
+ const record = records[index];
1074
+ if (!record.evidence)
1075
+ continue;
1076
+ const retained = truncate(record.evidence, remainingEvidenceChars);
1077
+ evidenceByFailureKey.set(record.failureKey, retained);
1078
+ remainingEvidenceChars -= retained.length;
1079
+ }
1080
+ const lines = records.map((record) => escapePromptData(formatRecordJson(record, true, evidenceByFailureKey.get(record.failureKey) ?? null)));
1024
1081
  for (const directive of analysis.activeDirectives) {
1025
1082
  lines.push(escapePromptData(JSON.stringify({
1026
1083
  ...mandatoryToolFailureRecoveryMetadata(),