@caupulican/pi-agent-core 0.93.2 → 0.93.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +10 -8
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +2 -2
- package/dist/agent.js.map +1 -1
- package/dist/tool-failure-memory.d.ts +2 -0
- package/dist/tool-failure-memory.d.ts.map +1 -1
- package/dist/tool-failure-memory.js +14 -0
- package/dist/tool-failure-memory.js.map +1 -1
- package/dist/tool-failure-recovery-gate.d.ts +17 -8
- package/dist/tool-failure-recovery-gate.d.ts.map +1 -1
- package/dist/tool-failure-recovery-gate.js +162 -121
- package/dist/tool-failure-recovery-gate.js.map +1 -1
- package/dist/types.d.ts +12 -9
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -2
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { getToolExecutionUnchangedRetryLimit } from "@caupulican/pi-ai/tool-repair-registry";
|
|
2
|
-
import { forEachPairedToolResult, getToolExecutionKey, getToolFailureRecordExecutionKey, isClosedOperationFailureCode, isPromptScopedFailureCode, readVisibleToolFailureCode, restoreToolFailureRecord, } from "./tool-failure-memory.js";
|
|
2
|
+
import { forEachPairedToolResult, getToolExecutionKey, getToolExecutionKeyHashParts, getToolFailureRecordExecutionKey, isClosedOperationFailureCode, isPromptScopedFailureCode, readVisibleToolFailureCode, restoreToolFailureRecord, } from "./tool-failure-memory.js";
|
|
3
3
|
import { isAgentToolFailureRecoveryAuthority } from "./types.js";
|
|
4
4
|
const MAX_BLOCKED_REPLAYS_PER_FAILURE = 2;
|
|
5
5
|
const BASE_FAILURE_EXECUTIONS_PER_OPERATION = 1;
|
|
6
6
|
const MAX_RECOVERY_PROBES_PER_OPERATION = 1;
|
|
7
7
|
const MAX_REJECTIONS_PER_OPERATION = 4;
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
const MAX_FAILURES_PER_RUN = 12;
|
|
11
|
-
const MAX_RECOVERY_STATES = 64;
|
|
8
|
+
const MAX_HOT_RECOVERY_STATES = 64;
|
|
9
|
+
const SEEN_EXECUTION_FILTER_BYTES = 64 * 1024;
|
|
12
10
|
const MAX_RECOVERY_TARGETS = 8;
|
|
13
11
|
const MAX_RECOVERY_ACTIONS = 8;
|
|
14
12
|
const MAX_TARGET_KIND_CHARS = 64;
|
|
@@ -16,6 +14,38 @@ const MAX_TARGET_SCOPE_CHARS = 32_768;
|
|
|
16
14
|
const MAX_ACTION_INSTRUCTION_CHARS = 160;
|
|
17
15
|
const MAX_RECOVERY_GUIDANCE_CHARS = 320;
|
|
18
16
|
const TARGET_KIND_PATTERN = /^[a-z0-9][a-z0-9._:-]*$/;
|
|
17
|
+
/**
|
|
18
|
+
* Bounded negative lookup for exact execution identities.
|
|
19
|
+
*
|
|
20
|
+
* A miss proves the operation has not failed while this gate has been alive. A hit only means
|
|
21
|
+
* "possibly seen" and must be verified against the transcript, so collisions can cost a scan but
|
|
22
|
+
* can never deny an execution. Keeping this separate from the hot state cache lets old exact
|
|
23
|
+
* circuits survive eviction without retaining one live object graph per historical operation.
|
|
24
|
+
*/
|
|
25
|
+
class SeenExecutionFilter {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.bits = new Uint8Array(SEEN_EXECUTION_FILTER_BYTES);
|
|
28
|
+
}
|
|
29
|
+
add(executionKey) {
|
|
30
|
+
for (const hash of getToolExecutionKeyHashParts(executionKey))
|
|
31
|
+
this.set(hash);
|
|
32
|
+
}
|
|
33
|
+
mightContain(executionKey) {
|
|
34
|
+
for (const hash of getToolExecutionKeyHashParts(executionKey)) {
|
|
35
|
+
if (!this.has(hash))
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
set(hash) {
|
|
41
|
+
const bit = (hash >>> 0) % (SEEN_EXECUTION_FILTER_BYTES * 8);
|
|
42
|
+
this.bits[bit >>> 3] |= 1 << (bit & 7);
|
|
43
|
+
}
|
|
44
|
+
has(hash) {
|
|
45
|
+
const bit = (hash >>> 0) % (SEEN_EXECUTION_FILTER_BYTES * 8);
|
|
46
|
+
return (this.bits[bit >>> 3] & (1 << (bit & 7))) !== 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
19
49
|
/**
|
|
20
50
|
* Owns execution admission and bounded unresolved-failure budgets.
|
|
21
51
|
*
|
|
@@ -24,49 +54,39 @@ const TARGET_KIND_PATTERN = /^[a-z0-9][a-z0-9._:-]*$/;
|
|
|
24
54
|
* successful repair evidence with byte-exact scope can reopen one probe. Argument text and hooks have
|
|
25
55
|
* no recovery authority.
|
|
26
56
|
*
|
|
27
|
-
* Run-level halt
|
|
28
|
-
*
|
|
29
|
-
*
|
|
57
|
+
* Run-level halt stays on the current run, but admission is never denied because unrelated operations
|
|
58
|
+
* happened to fail. A bounded hot cache carries active per-operation state. A fixed-size negative
|
|
59
|
+
* lookup sends an evicted exact replay back to the transcript for authoritative reconstruction, so
|
|
60
|
+
* cache pressure cannot either stop new work or reopen an already-exhausted operation.
|
|
30
61
|
*/
|
|
31
62
|
export class ToolFailureRecoveryGate {
|
|
32
63
|
constructor() {
|
|
33
64
|
this.statesByExecutionKey = new Map();
|
|
34
|
-
this.
|
|
35
|
-
|
|
65
|
+
this.seenFailedExecutions = new SeenExecutionFilter();
|
|
66
|
+
/** Exact successes not yet present in the transcript snapshot consulted by admission. */
|
|
67
|
+
this.resolvedBeforeTranscriptCommit = new Set();
|
|
68
|
+
this.transcriptMessages = [];
|
|
69
|
+
this.transcriptLength = 0;
|
|
70
|
+
this.restoredFromTranscript = false;
|
|
36
71
|
}
|
|
37
72
|
isEmpty() {
|
|
38
|
-
return this.statesByExecutionKey.size === 0 && this.halted === undefined
|
|
73
|
+
return this.statesByExecutionKey.size === 0 && this.halted === undefined;
|
|
39
74
|
}
|
|
40
75
|
restoreFromMessages(messages) {
|
|
41
|
-
|
|
76
|
+
this.trackTranscript(messages);
|
|
77
|
+
if (this.restoredFromTranscript || !this.isEmpty())
|
|
42
78
|
return;
|
|
79
|
+
this.restoredFromTranscript = true;
|
|
43
80
|
forEachPairedToolResult(messages, ({ tool, args, executionKey, result }) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.clearResolvedState(executionKey, existing);
|
|
81
|
+
const reduction = this.reduceTranscriptResult(this.statesByExecutionKey.get(executionKey), tool, args, result);
|
|
82
|
+
if (reduction.kind === "resolved") {
|
|
83
|
+
this.clearResolvedState(executionKey);
|
|
48
84
|
return;
|
|
49
85
|
}
|
|
50
|
-
|
|
51
|
-
const visibleCode = readVisibleToolFailureCode(result);
|
|
52
|
-
if (isPromptScopedFailureCode(visibleCode) || isPromptScopedFailureCode(restored.failureCode)) {
|
|
86
|
+
if (reduction.kind === "ignored")
|
|
53
87
|
return;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if (!state)
|
|
57
|
-
return false;
|
|
58
|
-
if (isClosedOperationFailureCode(visibleCode)) {
|
|
59
|
-
state.operationCircuitOpen = true;
|
|
60
|
-
state.blockedReplays = MAX_BLOCKED_REPLAYS_PER_FAILURE;
|
|
61
|
-
state.recoveryAvailable = false;
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (visibleCode === "repeated_failed_operation") {
|
|
65
|
-
state.blockedReplays++;
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
state.reservedExecutions++;
|
|
69
|
-
state.failures++;
|
|
88
|
+
this.seenFailedExecutions.add(executionKey);
|
|
89
|
+
this.retainHotState(executionKey, reduction.state);
|
|
70
90
|
});
|
|
71
91
|
}
|
|
72
92
|
planFailure(failedTool, args, failureCode, availableTools, reservation) {
|
|
@@ -78,34 +98,31 @@ export class ToolFailureRecoveryGate {
|
|
|
78
98
|
guidance: formatRecoveryGuidance(failureCode, actions, unchangedRetryRemaining),
|
|
79
99
|
};
|
|
80
100
|
}
|
|
81
|
-
admit(tool, args, record) {
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
admit(tool, args, record, messages = this.transcriptMessages) {
|
|
102
|
+
this.trackTranscript(messages);
|
|
103
|
+
const runHalt = this.halted;
|
|
104
|
+
if (runHalt) {
|
|
84
105
|
return {
|
|
85
106
|
kind: "blocked",
|
|
86
|
-
record:
|
|
107
|
+
record: runHalt.record,
|
|
87
108
|
exhausted: true,
|
|
88
109
|
scope: "run",
|
|
89
|
-
diagnostic:
|
|
110
|
+
diagnostic: runHalt.diagnostic,
|
|
90
111
|
};
|
|
91
112
|
}
|
|
92
113
|
const executionKey = getToolExecutionKey(tool.name, args);
|
|
93
|
-
|
|
114
|
+
if (this.resolvedBeforeTranscriptCommit.has(executionKey))
|
|
115
|
+
return { kind: "allowed" };
|
|
116
|
+
let state = this.getHotState(executionKey);
|
|
117
|
+
if (!state && this.seenFailedExecutions.mightContain(executionKey)) {
|
|
118
|
+
state = this.restoreOperationFromTranscript(executionKey);
|
|
119
|
+
}
|
|
94
120
|
if (!state && record && getToolFailureRecordExecutionKey(record) === executionKey) {
|
|
95
121
|
state = this.getOrCreateState(executionKey, record, readFailureTargets(tool, args, record.failureCode));
|
|
96
122
|
}
|
|
97
|
-
if (this.halted) {
|
|
98
|
-
return {
|
|
99
|
-
kind: "blocked",
|
|
100
|
-
record: this.halted.record,
|
|
101
|
-
exhausted: true,
|
|
102
|
-
scope: "run",
|
|
103
|
-
diagnostic: this.halted.diagnostic,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
123
|
if (!state)
|
|
107
124
|
return { kind: "allowed" };
|
|
108
|
-
if (record)
|
|
125
|
+
if (record && getToolFailureRecordExecutionKey(record) === executionKey)
|
|
109
126
|
state.record = record;
|
|
110
127
|
if (state.operationCircuitOpen) {
|
|
111
128
|
if (state.recoveryAvailable && state.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION) {
|
|
@@ -168,55 +185,18 @@ export class ToolFailureRecoveryGate {
|
|
|
168
185
|
: 1;
|
|
169
186
|
return executionsIncludingCurrent < BASE_FAILURE_EXECUTIONS_PER_OPERATION + retryLimit;
|
|
170
187
|
}
|
|
171
|
-
ensureRestoredState(executionKey, record) {
|
|
172
|
-
const existing = this.statesByExecutionKey.get(executionKey);
|
|
173
|
-
if (existing) {
|
|
174
|
-
existing.record = record;
|
|
175
|
-
return existing;
|
|
176
|
-
}
|
|
177
|
-
if (this.statesByExecutionKey.size >= MAX_RECOVERY_STATES)
|
|
178
|
-
return undefined;
|
|
179
|
-
const state = {
|
|
180
|
-
record,
|
|
181
|
-
recoveryTargets: [],
|
|
182
|
-
reservedExecutions: 0,
|
|
183
|
-
failures: 0,
|
|
184
|
-
failureFamilyCounts: new Map(),
|
|
185
|
-
recoveryProbes: 0,
|
|
186
|
-
blockedReplays: 0,
|
|
187
|
-
recoveryAvailable: false,
|
|
188
|
-
operationCircuitOpen: false,
|
|
189
|
-
};
|
|
190
|
-
this.statesByExecutionKey.set(executionKey, state);
|
|
191
|
-
return state;
|
|
192
|
-
}
|
|
193
188
|
getOrCreateState(executionKey, record, targets) {
|
|
194
|
-
const existing = this.
|
|
189
|
+
const existing = this.getHotState(executionKey);
|
|
195
190
|
if (existing)
|
|
196
191
|
return existing;
|
|
197
|
-
const state =
|
|
198
|
-
|
|
199
|
-
recoveryTargets: targets,
|
|
200
|
-
reservedExecutions: 0,
|
|
201
|
-
failures: 0,
|
|
202
|
-
failureFamilyCounts: new Map(),
|
|
203
|
-
recoveryProbes: 0,
|
|
204
|
-
blockedReplays: 0,
|
|
205
|
-
recoveryAvailable: false,
|
|
206
|
-
operationCircuitOpen: false,
|
|
207
|
-
};
|
|
208
|
-
if (this.statesByExecutionKey.size >= MAX_RECOVERY_STATES) {
|
|
209
|
-
this.halted = {
|
|
210
|
-
record,
|
|
211
|
-
diagnostic: `Recovery circuit opened at the ${MAX_RECOVERY_STATES}-operation state bound.`,
|
|
212
|
-
};
|
|
213
|
-
return state;
|
|
214
|
-
}
|
|
215
|
-
this.statesByExecutionKey.set(executionKey, state);
|
|
192
|
+
const state = createFailureRecoveryState(record, targets);
|
|
193
|
+
this.retainHotState(executionKey, state);
|
|
216
194
|
return state;
|
|
217
195
|
}
|
|
218
196
|
observeFailure(record, args, targets, reservation) {
|
|
219
197
|
const executionKey = getToolExecutionKey(record.tool, args);
|
|
198
|
+
this.resolvedBeforeTranscriptCommit.delete(executionKey);
|
|
199
|
+
this.seenFailedExecutions.add(executionKey);
|
|
220
200
|
const state = this.getOrCreateState(executionKey, record, targets);
|
|
221
201
|
if (this.halted)
|
|
222
202
|
return;
|
|
@@ -227,11 +207,6 @@ export class ToolFailureRecoveryGate {
|
|
|
227
207
|
if (reservation?.executionKey !== executionKey)
|
|
228
208
|
state.reservedExecutions++;
|
|
229
209
|
state.failures++;
|
|
230
|
-
this.totalFailures++;
|
|
231
|
-
const familyKey = `${record.tool}\0${record.failureCode}`;
|
|
232
|
-
const familyFailures = (this.failuresByFamily.get(familyKey) ?? 0) + 1;
|
|
233
|
-
this.failuresByFamily.set(familyKey, familyFailures);
|
|
234
|
-
state.failureFamilyCounts.set(familyKey, (state.failureFamilyCounts.get(familyKey) ?? 0) + 1);
|
|
235
210
|
const operationFailureLimit = record.state === "failed"
|
|
236
211
|
? BASE_FAILURE_EXECUTIONS_PER_OPERATION +
|
|
237
212
|
getToolExecutionUnchangedRetryLimit(record.failureCode) +
|
|
@@ -242,28 +217,18 @@ export class ToolFailureRecoveryGate {
|
|
|
242
217
|
record,
|
|
243
218
|
diagnostic: `Recovery circuit opened after ${state.failures} failed outcomes for one operation.`,
|
|
244
219
|
};
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
if (familyFailures >= MAX_FAILURES_PER_FAMILY) {
|
|
248
|
-
this.halted = {
|
|
249
|
-
record,
|
|
250
|
-
diagnostic: `Recovery circuit opened after ${familyFailures} failures in one tool failure family.`,
|
|
251
|
-
};
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
if (this.totalFailures >= MAX_FAILURES_PER_RUN) {
|
|
255
|
-
this.halted = {
|
|
256
|
-
record,
|
|
257
|
-
diagnostic: `Recovery circuit opened after ${this.totalFailures} tool failures in one run.`,
|
|
258
|
-
};
|
|
259
220
|
}
|
|
260
221
|
}
|
|
261
222
|
observeSuccess(tool, args, result) {
|
|
262
223
|
const successfulExecutionKey = getToolExecutionKey(tool.name, args);
|
|
224
|
+
// Tool results are appended to the transcript after the current execution batch completes.
|
|
225
|
+
// Until then the last persisted failure is stale authority: remember the exact success so a
|
|
226
|
+
// later sequential call in this same batch cannot resurrect that failure from the transcript.
|
|
227
|
+
this.resolvedBeforeTranscriptCommit.add(successfulExecutionKey);
|
|
263
228
|
const evidenceTargets = readRecoveryEvidenceTargets(tool, args, result);
|
|
264
229
|
for (const [executionKey, state] of this.statesByExecutionKey) {
|
|
265
230
|
if (executionKey === successfulExecutionKey) {
|
|
266
|
-
this.clearResolvedState(executionKey
|
|
231
|
+
this.clearResolvedState(executionKey);
|
|
267
232
|
continue;
|
|
268
233
|
}
|
|
269
234
|
if (state.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION &&
|
|
@@ -273,17 +238,93 @@ export class ToolFailureRecoveryGate {
|
|
|
273
238
|
}
|
|
274
239
|
}
|
|
275
240
|
}
|
|
276
|
-
clearResolvedState(executionKey
|
|
241
|
+
clearResolvedState(executionKey) {
|
|
277
242
|
this.statesByExecutionKey.delete(executionKey);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
243
|
+
}
|
|
244
|
+
trackTranscript(messages) {
|
|
245
|
+
const tail = messages[messages.length - 1];
|
|
246
|
+
if (messages !== this.transcriptMessages ||
|
|
247
|
+
messages.length !== this.transcriptLength ||
|
|
248
|
+
tail !== this.transcriptTail) {
|
|
249
|
+
// An advanced transcript now authoritatively records completed results. The temporary
|
|
250
|
+
// exact-success overlay is bounded to one uncommitted execution batch.
|
|
251
|
+
this.resolvedBeforeTranscriptCommit.clear();
|
|
285
252
|
}
|
|
253
|
+
this.transcriptMessages = messages;
|
|
254
|
+
this.transcriptLength = messages.length;
|
|
255
|
+
this.transcriptTail = tail;
|
|
286
256
|
}
|
|
257
|
+
getHotState(executionKey) {
|
|
258
|
+
const state = this.statesByExecutionKey.get(executionKey);
|
|
259
|
+
if (!state)
|
|
260
|
+
return undefined;
|
|
261
|
+
this.statesByExecutionKey.delete(executionKey);
|
|
262
|
+
this.statesByExecutionKey.set(executionKey, state);
|
|
263
|
+
return state;
|
|
264
|
+
}
|
|
265
|
+
retainHotState(executionKey, state) {
|
|
266
|
+
this.statesByExecutionKey.delete(executionKey);
|
|
267
|
+
this.statesByExecutionKey.set(executionKey, state);
|
|
268
|
+
while (this.statesByExecutionKey.size > MAX_HOT_RECOVERY_STATES) {
|
|
269
|
+
const oldest = this.statesByExecutionKey.keys().next().value;
|
|
270
|
+
if (oldest === undefined)
|
|
271
|
+
break;
|
|
272
|
+
this.statesByExecutionKey.delete(oldest);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
restoreOperationFromTranscript(executionKey) {
|
|
276
|
+
let restoredState;
|
|
277
|
+
forEachPairedToolResult(this.transcriptMessages, ({ tool, args, executionKey: candidateKey, result }) => {
|
|
278
|
+
if (candidateKey !== executionKey)
|
|
279
|
+
return;
|
|
280
|
+
const reduction = this.reduceTranscriptResult(restoredState, tool, args, result);
|
|
281
|
+
if (reduction.kind === "resolved") {
|
|
282
|
+
restoredState = undefined;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
if (reduction.kind === "failed")
|
|
286
|
+
restoredState = reduction.state;
|
|
287
|
+
});
|
|
288
|
+
if (restoredState)
|
|
289
|
+
this.retainHotState(executionKey, restoredState);
|
|
290
|
+
return restoredState;
|
|
291
|
+
}
|
|
292
|
+
reduceTranscriptResult(state, tool, args, result) {
|
|
293
|
+
if (!result.isError)
|
|
294
|
+
return { kind: "resolved" };
|
|
295
|
+
const record = restoreToolFailureRecord(result, tool, args);
|
|
296
|
+
const visibleCode = readVisibleToolFailureCode(result);
|
|
297
|
+
if (isPromptScopedFailureCode(visibleCode) || isPromptScopedFailureCode(record.failureCode)) {
|
|
298
|
+
return { kind: "ignored", state };
|
|
299
|
+
}
|
|
300
|
+
const next = state ?? createFailureRecoveryState(record, []);
|
|
301
|
+
next.record = record;
|
|
302
|
+
if (isClosedOperationFailureCode(visibleCode)) {
|
|
303
|
+
next.operationCircuitOpen = true;
|
|
304
|
+
next.blockedReplays = MAX_BLOCKED_REPLAYS_PER_FAILURE;
|
|
305
|
+
next.recoveryAvailable = false;
|
|
306
|
+
return { kind: "failed", state: next };
|
|
307
|
+
}
|
|
308
|
+
if (visibleCode === "repeated_failed_operation") {
|
|
309
|
+
next.blockedReplays++;
|
|
310
|
+
return { kind: "failed", state: next };
|
|
311
|
+
}
|
|
312
|
+
next.reservedExecutions++;
|
|
313
|
+
next.failures++;
|
|
314
|
+
return { kind: "failed", state: next };
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function createFailureRecoveryState(record, recoveryTargets) {
|
|
318
|
+
return {
|
|
319
|
+
record,
|
|
320
|
+
recoveryTargets,
|
|
321
|
+
reservedExecutions: 0,
|
|
322
|
+
failures: 0,
|
|
323
|
+
recoveryProbes: 0,
|
|
324
|
+
blockedReplays: 0,
|
|
325
|
+
recoveryAvailable: false,
|
|
326
|
+
operationCircuitOpen: false,
|
|
327
|
+
};
|
|
287
328
|
}
|
|
288
329
|
function readFailureTargets(tool, args, failureCode) {
|
|
289
330
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-failure-recovery-gate.js","sourceRoot":"","sources":["../src/tool-failure-recovery-gate.ts"],"names":[],"mappings":"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","sourcesContent":["import { getToolExecutionUnchangedRetryLimit } from \"@caupulican/pi-ai/tool-repair-registry\";\nimport {\n\tforEachPairedToolResult,\n\tgetToolExecutionKey,\n\tgetToolFailureRecordExecutionKey,\n\tisClosedOperationFailureCode,\n\tisPromptScopedFailureCode,\n\treadVisibleToolFailureCode,\n\trestoreToolFailureRecord,\n\ttype ToolFailureMemoryRecord,\n} from \"./tool-failure-memory.ts\";\nimport type {\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolFailureRecoveryAuthority,\n\tAgentToolFailureRecoveryTarget,\n\tAgentToolResult,\n} from \"./types.ts\";\nimport { isAgentToolFailureRecoveryAuthority } from \"./types.ts\";\n\nconst MAX_BLOCKED_REPLAYS_PER_FAILURE = 2;\nconst BASE_FAILURE_EXECUTIONS_PER_OPERATION = 1;\nconst MAX_RECOVERY_PROBES_PER_OPERATION = 1;\nconst MAX_REJECTIONS_PER_OPERATION = 4;\nexport const TOOL_FAILURE_RECOVERY_ACCOUNTING_WAVE_SIZE = 4;\nconst MAX_FAILURES_PER_FAMILY = TOOL_FAILURE_RECOVERY_ACCOUNTING_WAVE_SIZE;\nconst MAX_FAILURES_PER_RUN = 12;\nconst MAX_RECOVERY_STATES = 64;\nconst MAX_RECOVERY_TARGETS = 8;\nconst MAX_RECOVERY_ACTIONS = 8;\nconst MAX_TARGET_KIND_CHARS = 64;\nconst MAX_TARGET_SCOPE_CHARS = 32_768;\nconst MAX_ACTION_INSTRUCTION_CHARS = 160;\nconst MAX_RECOVERY_GUIDANCE_CHARS = 320;\nconst TARGET_KIND_PATTERN = /^[a-z0-9][a-z0-9._:-]*$/;\n\nexport interface ToolFailureExecutionReservation {\n\texecutionKey: string;\n}\n\nexport interface ToolFailureRecoveryPlan {\n\ttargets: readonly AgentToolFailureRecoveryTarget[];\n\tguidance: string;\n}\n\nexport type ToolFailureRecoveryGateEffect =\n\t| {\n\t\t\tkind: \"failure\";\n\t\t\trecord: ToolFailureMemoryRecord;\n\t\t\targs: unknown;\n\t\t\ttargets?: readonly AgentToolFailureRecoveryTarget[];\n\t\t\treservation?: ToolFailureExecutionReservation;\n\t }\n\t| { kind: \"success\"; tool: AgentTool<any>; args: unknown; evidenceResult: AgentToolResult<any> };\n\nexport type ToolFailureRecoveryAdmission =\n\t| { kind: \"allowed\"; reservation?: ToolFailureExecutionReservation }\n\t| { kind: \"blocked\"; record: ToolFailureMemoryRecord; exhausted: false; diagnostic?: string }\n\t| {\n\t\t\tkind: \"blocked\";\n\t\t\trecord: ToolFailureMemoryRecord;\n\t\t\texhausted: true;\n\t\t\tscope: \"operation\" | \"run\";\n\t\t\tdiagnostic?: string;\n\t };\n\ninterface FailureRecoveryState {\n\trecord: ToolFailureMemoryRecord;\n\trecoveryTargets: readonly AgentToolFailureRecoveryTarget[];\n\treservedExecutions: number;\n\tfailures: number;\n\tfailureFamilyCounts: Map<string, number>;\n\trecoveryProbes: number;\n\tblockedReplays: number;\n\trecoveryAvailable: boolean;\n\toperationCircuitOpen: boolean;\n}\n\ninterface AvailableRecoveryAction {\n\ttoolName: string;\n\tkind: \"correct\" | \"repair\";\n\tinstruction: string;\n}\n\ninterface ParsedRecoveryAction {\n\tkind: \"correct\" | \"repair\";\n\tauthority: AgentToolFailureRecoveryAuthority;\n\ttargetKind: string;\n\tinstruction: string;\n\tgetEvidence?: (params: unknown, result: AgentToolResult<unknown>) => unknown;\n}\n\nexport interface ToolFailureRecoveryHalt {\n\trecord: ToolFailureMemoryRecord;\n\tdiagnostic: string;\n}\n\n/**\n * Owns execution admission and bounded unresolved-failure budgets.\n *\n * Recovery authority is exact and tool-owned. A failed tool declares opaque backend-specific targets;\n * a loaded recovery tool may teach actions only for the same authority and target kind. Only raw\n * successful repair evidence with byte-exact scope can reopen one probe. Argument text and hooks have\n * no recovery authority.\n *\n * Run-level halt and family/run counters stay on the current run. Per-operation execution budget and\n * circuit are reconstructed from the transcript when a new run starts with an empty gate, so an\n * already-exhausted identical operation is not re-executed after a user turn or session resume.\n */\nexport class ToolFailureRecoveryGate {\n\tprivate readonly statesByExecutionKey = new Map<string, FailureRecoveryState>();\n\tprivate readonly failuresByFamily = new Map<string, number>();\n\tprivate totalFailures = 0;\n\tprivate halted: ToolFailureRecoveryHalt | undefined;\n\n\tisEmpty(): boolean {\n\t\treturn this.statesByExecutionKey.size === 0 && this.halted === undefined && this.totalFailures === 0;\n\t}\n\n\trestoreFromMessages(messages: readonly AgentMessage[]): void {\n\t\tif (!this.isEmpty()) return;\n\t\tforEachPairedToolResult(messages, ({ tool, args, executionKey, result }) => {\n\t\t\tif (!result.isError) {\n\t\t\t\tconst existing = this.statesByExecutionKey.get(executionKey);\n\t\t\t\tif (existing) this.clearResolvedState(executionKey, existing);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst restored = restoreToolFailureRecord(result, tool, args);\n\t\t\tconst visibleCode = readVisibleToolFailureCode(result);\n\t\t\tif (isPromptScopedFailureCode(visibleCode) || isPromptScopedFailureCode(restored.failureCode)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst state = this.ensureRestoredState(executionKey, restored);\n\t\t\tif (!state) return false;\n\t\t\tif (isClosedOperationFailureCode(visibleCode)) {\n\t\t\t\tstate.operationCircuitOpen = true;\n\t\t\t\tstate.blockedReplays = MAX_BLOCKED_REPLAYS_PER_FAILURE;\n\t\t\t\tstate.recoveryAvailable = false;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (visibleCode === \"repeated_failed_operation\") {\n\t\t\t\tstate.blockedReplays++;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate.reservedExecutions++;\n\t\t\tstate.failures++;\n\t\t});\n\t}\n\n\tplanFailure(\n\t\tfailedTool: AgentTool<any>,\n\t\targs: unknown,\n\t\tfailureCode: string,\n\t\tavailableTools: readonly AgentTool<any>[],\n\t\treservation: ToolFailureExecutionReservation | undefined,\n\t): ToolFailureRecoveryPlan {\n\t\tconst targets = readFailureTargets(failedTool, args, failureCode);\n\t\tconst actions = readAvailableRecoveryActions(availableTools, targets);\n\t\tconst unchangedRetryRemaining = this.hasUnchangedRetryRemaining(failedTool, args, failureCode, reservation);\n\t\treturn {\n\t\t\ttargets,\n\t\t\tguidance: formatRecoveryGuidance(failureCode, actions, unchangedRetryRemaining),\n\t\t};\n\t}\n\n\tadmit(\n\t\ttool: AgentTool<any>,\n\t\targs: unknown,\n\t\trecord: ToolFailureMemoryRecord | undefined,\n\t): ToolFailureRecoveryAdmission {\n\t\tconst stateCapacityHalt = this.halted;\n\t\tif (stateCapacityHalt) {\n\t\t\treturn {\n\t\t\t\tkind: \"blocked\",\n\t\t\t\trecord: stateCapacityHalt.record,\n\t\t\t\texhausted: true,\n\t\t\t\tscope: \"run\",\n\t\t\t\tdiagnostic: stateCapacityHalt.diagnostic,\n\t\t\t};\n\t\t}\n\n\t\tconst executionKey = getToolExecutionKey(tool.name, args);\n\t\tlet state = this.statesByExecutionKey.get(executionKey);\n\t\tif (!state && record && getToolFailureRecordExecutionKey(record) === executionKey) {\n\t\t\tstate = this.getOrCreateState(executionKey, record, readFailureTargets(tool, args, record.failureCode));\n\t\t}\n\t\tif (this.halted) {\n\t\t\treturn {\n\t\t\t\tkind: \"blocked\",\n\t\t\t\trecord: this.halted.record,\n\t\t\t\texhausted: true,\n\t\t\t\tscope: \"run\",\n\t\t\t\tdiagnostic: this.halted.diagnostic,\n\t\t\t};\n\t\t}\n\t\tif (!state) return { kind: \"allowed\" };\n\n\t\tif (record) state.record = record;\n\t\tif (state.operationCircuitOpen) {\n\t\t\tif (state.recoveryAvailable && state.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION) {\n\t\t\t\tstate.operationCircuitOpen = false;\n\t\t\t\tstate.recoveryAvailable = false;\n\t\t\t\tstate.recoveryProbes++;\n\t\t\t\tstate.reservedExecutions++;\n\t\t\t\tstate.blockedReplays = 0;\n\t\t\t\treturn { kind: \"allowed\", reservation: { executionKey } };\n\t\t\t}\n\t\t\tconst diagnostic = `Run recovery circuit opened after replay of an operation whose local circuit was already open for ${state.record.failureCode}.`;\n\t\t\tthis.halted = { record: state.record, diagnostic };\n\t\t\treturn { kind: \"blocked\", record: state.record, exhausted: true, scope: \"run\", diagnostic };\n\t\t}\n\t\tconst automaticExecutionLimit =\n\t\t\tBASE_FAILURE_EXECUTIONS_PER_OPERATION + getToolExecutionUnchangedRetryLimit(state.record.failureCode);\n\t\tif (state.reservedExecutions < automaticExecutionLimit) {\n\t\t\tstate.reservedExecutions++;\n\t\t\tstate.blockedReplays = 0;\n\t\t\treturn { kind: \"allowed\", reservation: { executionKey } };\n\t\t}\n\t\tif (state.recoveryAvailable && state.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION) {\n\t\t\tstate.recoveryAvailable = false;\n\t\t\tstate.recoveryProbes++;\n\t\t\tstate.reservedExecutions++;\n\t\t\tstate.blockedReplays = 0;\n\t\t\treturn { kind: \"allowed\", reservation: { executionKey } };\n\t\t}\n\n\t\tstate.blockedReplays++;\n\t\tif (state.blockedReplays >= MAX_BLOCKED_REPLAYS_PER_FAILURE) {\n\t\t\tstate.operationCircuitOpen = true;\n\t\t\tconst diagnostic = `Operation recovery circuit opened after ${state.blockedReplays} blocked replays of ${state.record.failureCode}.`;\n\t\t\treturn { kind: \"blocked\", record: state.record, exhausted: true, scope: \"operation\", diagnostic };\n\t\t}\n\t\treturn { kind: \"blocked\", record: state.record, exhausted: false };\n\t}\n\n\tapply(effect: ToolFailureRecoveryGateEffect | undefined): ToolFailureRecoveryHalt | undefined {\n\t\tif (!effect || this.halted) return undefined;\n\t\tif (effect.kind === \"success\") {\n\t\t\tthis.observeSuccess(effect.tool, effect.args, effect.evidenceResult);\n\t\t\treturn undefined;\n\t\t}\n\t\tthis.observeFailure(effect.record, effect.args, effect.targets ?? [], effect.reservation);\n\t\treturn this.halted;\n\t}\n\n\tisHalted(): boolean {\n\t\treturn this.halted !== undefined;\n\t}\n\n\tgetHalt(): ToolFailureRecoveryHalt | undefined {\n\t\treturn this.halted;\n\t}\n\n\tprivate hasUnchangedRetryRemaining(\n\t\ttool: AgentTool<any>,\n\t\targs: unknown,\n\t\tfailureCode: string,\n\t\treservation: ToolFailureExecutionReservation | undefined,\n\t): boolean {\n\t\tconst retryLimit = getToolExecutionUnchangedRetryLimit(failureCode);\n\t\tif (retryLimit === 0) return false;\n\t\tconst executionKey = getToolExecutionKey(tool.name, args);\n\t\tconst state = this.statesByExecutionKey.get(executionKey);\n\t\tconst executionsIncludingCurrent = state\n\t\t\t? state.reservedExecutions + (reservation?.executionKey === executionKey ? 0 : 1)\n\t\t\t: 1;\n\t\treturn executionsIncludingCurrent < BASE_FAILURE_EXECUTIONS_PER_OPERATION + retryLimit;\n\t}\n\n\tprivate ensureRestoredState(\n\t\texecutionKey: string,\n\t\trecord: ToolFailureMemoryRecord,\n\t): FailureRecoveryState | undefined {\n\t\tconst existing = this.statesByExecutionKey.get(executionKey);\n\t\tif (existing) {\n\t\t\texisting.record = record;\n\t\t\treturn existing;\n\t\t}\n\t\tif (this.statesByExecutionKey.size >= MAX_RECOVERY_STATES) return undefined;\n\t\tconst state: FailureRecoveryState = {\n\t\t\trecord,\n\t\t\trecoveryTargets: [],\n\t\t\treservedExecutions: 0,\n\t\t\tfailures: 0,\n\t\t\tfailureFamilyCounts: new Map(),\n\t\t\trecoveryProbes: 0,\n\t\t\tblockedReplays: 0,\n\t\t\trecoveryAvailable: false,\n\t\t\toperationCircuitOpen: false,\n\t\t};\n\t\tthis.statesByExecutionKey.set(executionKey, state);\n\t\treturn state;\n\t}\n\n\tprivate getOrCreateState(\n\t\texecutionKey: string,\n\t\trecord: ToolFailureMemoryRecord,\n\t\ttargets: readonly AgentToolFailureRecoveryTarget[],\n\t): FailureRecoveryState {\n\t\tconst existing = this.statesByExecutionKey.get(executionKey);\n\t\tif (existing) return existing;\n\t\tconst state: FailureRecoveryState = {\n\t\t\trecord,\n\t\t\trecoveryTargets: targets,\n\t\t\treservedExecutions: 0,\n\t\t\tfailures: 0,\n\t\t\tfailureFamilyCounts: new Map(),\n\t\t\trecoveryProbes: 0,\n\t\t\tblockedReplays: 0,\n\t\t\trecoveryAvailable: false,\n\t\t\toperationCircuitOpen: false,\n\t\t};\n\t\tif (this.statesByExecutionKey.size >= MAX_RECOVERY_STATES) {\n\t\t\tthis.halted = {\n\t\t\t\trecord,\n\t\t\t\tdiagnostic: `Recovery circuit opened at the ${MAX_RECOVERY_STATES}-operation state bound.`,\n\t\t\t};\n\t\t\treturn state;\n\t\t}\n\t\tthis.statesByExecutionKey.set(executionKey, state);\n\t\treturn state;\n\t}\n\n\tprivate observeFailure(\n\t\trecord: ToolFailureMemoryRecord,\n\t\targs: unknown,\n\t\ttargets: readonly AgentToolFailureRecoveryTarget[],\n\t\treservation: ToolFailureExecutionReservation | undefined,\n\t): void {\n\t\tconst executionKey = getToolExecutionKey(record.tool, args);\n\t\tconst state = this.getOrCreateState(executionKey, record, targets);\n\t\tif (this.halted) return;\n\t\tstate.record = record;\n\t\tstate.recoveryTargets = targets;\n\t\tstate.recoveryAvailable = false;\n\t\tstate.blockedReplays = 0;\n\t\tif (reservation?.executionKey !== executionKey) state.reservedExecutions++;\n\n\t\tstate.failures++;\n\t\tthis.totalFailures++;\n\t\tconst familyKey = `${record.tool}\\0${record.failureCode}`;\n\t\tconst familyFailures = (this.failuresByFamily.get(familyKey) ?? 0) + 1;\n\t\tthis.failuresByFamily.set(familyKey, familyFailures);\n\t\tstate.failureFamilyCounts.set(familyKey, (state.failureFamilyCounts.get(familyKey) ?? 0) + 1);\n\n\t\tconst operationFailureLimit =\n\t\t\trecord.state === \"failed\"\n\t\t\t\t? BASE_FAILURE_EXECUTIONS_PER_OPERATION +\n\t\t\t\t\tgetToolExecutionUnchangedRetryLimit(record.failureCode) +\n\t\t\t\t\tMAX_RECOVERY_PROBES_PER_OPERATION\n\t\t\t\t: MAX_REJECTIONS_PER_OPERATION;\n\t\tif (state.failures >= operationFailureLimit) {\n\t\t\tthis.halted = {\n\t\t\t\trecord,\n\t\t\t\tdiagnostic: `Recovery circuit opened after ${state.failures} failed outcomes for one operation.`,\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\t\tif (familyFailures >= MAX_FAILURES_PER_FAMILY) {\n\t\t\tthis.halted = {\n\t\t\t\trecord,\n\t\t\t\tdiagnostic: `Recovery circuit opened after ${familyFailures} failures in one tool failure family.`,\n\t\t\t};\n\t\t\treturn;\n\t\t}\n\t\tif (this.totalFailures >= MAX_FAILURES_PER_RUN) {\n\t\t\tthis.halted = {\n\t\t\t\trecord,\n\t\t\t\tdiagnostic: `Recovery circuit opened after ${this.totalFailures} tool failures in one run.`,\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate observeSuccess(tool: AgentTool<any>, args: unknown, result: AgentToolResult<any>): void {\n\t\tconst successfulExecutionKey = getToolExecutionKey(tool.name, args);\n\t\tconst evidenceTargets = readRecoveryEvidenceTargets(tool, args, result);\n\t\tfor (const [executionKey, state] of this.statesByExecutionKey) {\n\t\t\tif (executionKey === successfulExecutionKey) {\n\t\t\t\tthis.clearResolvedState(executionKey, state);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tstate.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION &&\n\t\t\t\thasSharedRecoveryTarget(state.recoveryTargets, evidenceTargets)\n\t\t\t) {\n\t\t\t\tstate.recoveryAvailable = true;\n\t\t\t\tstate.blockedReplays = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate clearResolvedState(executionKey: string, state: FailureRecoveryState): void {\n\t\tthis.statesByExecutionKey.delete(executionKey);\n\t\tthis.totalFailures = Math.max(0, this.totalFailures - state.failures);\n\t\tfor (const [familyKey, stateFailures] of state.failureFamilyCounts) {\n\t\t\tconst remaining = (this.failuresByFamily.get(familyKey) ?? 0) - stateFailures;\n\t\t\tif (remaining > 0) this.failuresByFamily.set(familyKey, remaining);\n\t\t\telse this.failuresByFamily.delete(familyKey);\n\t\t}\n\t}\n}\n\nfunction readFailureTargets(\n\ttool: AgentTool<any>,\n\targs: unknown,\n\tfailureCode: string,\n): readonly AgentToolFailureRecoveryTarget[] {\n\ttry {\n\t\tconst contract = tool.failureRecovery;\n\t\tconst getTargets = contract?.getFailureTargets;\n\t\tif (!getTargets) return [];\n\t\tconst targets = Reflect.apply(getTargets, contract, [args, { failureCode }]);\n\t\treturn sanitizeRecoveryTargets(targets);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction sanitizeRecoveryTargets(value: unknown): readonly AgentToolFailureRecoveryTarget[] {\n\tif (!Array.isArray(value)) return [];\n\tconst targets: AgentToolFailureRecoveryTarget[] = [];\n\tfor (const candidate of value) {\n\t\tif (targets.length >= MAX_RECOVERY_TARGETS) break;\n\t\tif (!candidate || typeof candidate !== \"object\" || Array.isArray(candidate)) continue;\n\t\tconst { authority, kind, scope } = candidate as { authority?: unknown; kind?: unknown; scope?: unknown };\n\t\tif (!isAgentToolFailureRecoveryAuthority(authority) || !validTargetKind(kind) || !validTargetScope(scope)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (targets.some((target) => sameRecoveryTarget(target, { authority, kind, scope }))) continue;\n\t\ttargets.push({ authority, kind, scope });\n\t}\n\treturn targets;\n}\n\nfunction validTargetKind(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tvalue.length > 0 &&\n\t\tvalue.length <= MAX_TARGET_KIND_CHARS &&\n\t\tTARGET_KIND_PATTERN.test(value)\n\t);\n}\n\nfunction validTargetScope(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" && value.length > 0 && value.length <= MAX_TARGET_SCOPE_CHARS && !value.includes(\"\\0\")\n\t);\n}\n\nfunction readAvailableRecoveryActions(\n\ttools: readonly AgentTool<any>[],\n\ttargets: readonly AgentToolFailureRecoveryTarget[],\n): readonly AvailableRecoveryAction[] {\n\tif (targets.length === 0) return [];\n\tconst actions: AvailableRecoveryAction[] = [];\n\tconst seen = new Set<string>();\n\tfor (const tool of tools) {\n\t\tfor (const candidate of readDeclaredRecoveryActions(tool)) {\n\t\t\tif (actions.length >= MAX_RECOVERY_ACTIONS) return actions;\n\t\t\tconst action = parseRecoveryAction(candidate);\n\t\t\tif (\n\t\t\t\t!action ||\n\t\t\t\t!targets.some((target) => target.authority === action.authority && target.kind === action.targetKind)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst instruction = truncate(action.instruction.trim(), MAX_ACTION_INSTRUCTION_CHARS);\n\t\t\tif (!instruction) continue;\n\t\t\tconst key = `${tool.name}\\0${action.kind}\\0${instruction}`;\n\t\t\tif (seen.has(key)) continue;\n\t\t\tseen.add(key);\n\t\t\tactions.push({ toolName: tool.name, kind: action.kind, instruction });\n\t\t}\n\t}\n\treturn actions;\n}\n\nfunction readDeclaredRecoveryActions(tool: AgentTool<any>): readonly unknown[] {\n\ttry {\n\t\tconst declared = tool.failureRecovery?.actions;\n\t\tif (!Array.isArray(declared)) return [];\n\t\tconst actions: unknown[] = [];\n\t\tconst count = Math.min(declared.length, MAX_RECOVERY_ACTIONS);\n\t\tfor (let index = 0; index < count; index++) actions.push(declared[index]);\n\t\treturn actions;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction parseRecoveryAction(value: unknown): ParsedRecoveryAction | undefined {\n\ttry {\n\t\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined;\n\t\tconst candidate = value as {\n\t\t\tkind?: unknown;\n\t\t\tauthority?: unknown;\n\t\t\ttargetKind?: unknown;\n\t\t\tinstruction?: unknown;\n\t\t\tgetEvidence?: unknown;\n\t\t};\n\t\tif (\n\t\t\t!isAgentToolFailureRecoveryAuthority(candidate.authority) ||\n\t\t\t!validTargetKind(candidate.targetKind) ||\n\t\t\ttypeof candidate.instruction !== \"string\"\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (candidate.kind === \"correct\") {\n\t\t\treturn {\n\t\t\t\tkind: candidate.kind,\n\t\t\t\tauthority: candidate.authority,\n\t\t\t\ttargetKind: candidate.targetKind,\n\t\t\t\tinstruction: candidate.instruction,\n\t\t\t};\n\t\t}\n\t\tif (candidate.kind !== \"repair\" || typeof candidate.getEvidence !== \"function\") return undefined;\n\t\tconst getEvidence = candidate.getEvidence;\n\t\treturn {\n\t\t\tkind: candidate.kind,\n\t\t\tauthority: candidate.authority,\n\t\t\ttargetKind: candidate.targetKind,\n\t\t\tinstruction: candidate.instruction,\n\t\t\tgetEvidence: (params, result) => Reflect.apply(getEvidence, value, [params, result]),\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction readRecoveryEvidenceTargets(\n\ttool: AgentTool<any>,\n\targs: unknown,\n\tresult: AgentToolResult<any>,\n): readonly AgentToolFailureRecoveryTarget[] {\n\tconst targets: AgentToolFailureRecoveryTarget[] = [];\n\tfor (const candidate of readDeclaredRecoveryActions(tool)) {\n\t\tconst action = parseRecoveryAction(candidate);\n\t\tif (targets.length >= MAX_RECOVERY_TARGETS || !action || action.kind !== \"repair\" || !action.getEvidence) {\n\t\t\tcontinue;\n\t\t}\n\t\tlet scopes: unknown;\n\t\ttry {\n\t\t\tscopes = action.getEvidence(args, result);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!Array.isArray(scopes)) continue;\n\t\tfor (const scope of scopes) {\n\t\t\tif (targets.length >= MAX_RECOVERY_TARGETS) break;\n\t\t\tif (!validTargetScope(scope)) continue;\n\t\t\tconst target = { authority: action.authority, kind: action.targetKind, scope };\n\t\t\tif (!targets.some((candidate) => sameRecoveryTarget(candidate, target))) targets.push(target);\n\t\t}\n\t}\n\treturn targets;\n}\n\nfunction formatRecoveryGuidance(\n\tfailureCode: string,\n\tactions: readonly AvailableRecoveryAction[],\n\tunchangedRetryRemaining: boolean,\n): string {\n\tconst hasTimeoutRetryPolicy = getToolExecutionUnchangedRetryLimit(failureCode) > 0;\n\tconst timeoutPolicy = hasTimeoutRetryPolicy\n\t\t? unchangedRetryRemaining\n\t\t\t? \"Timeout policy allows 1 unchanged retry; if it fails, never retry unchanged.\"\n\t\t\t: \"Timeout unchanged retry exhausted; never retry unchanged.\"\n\t\t: undefined;\n\tif (actions.length === 0) {\n\t\tif (timeoutPolicy) return `${timeoutPolicy} Change/narrow operation, or report blocker.`;\n\t\treturn \"No loaded tool declares recovery. Never retry unchanged. Use materially different operation justified by diagnostic/schema, or report blocker.\";\n\t}\n\tconst available = actions.map((action) => `${action.toolName} ${action.kind}: ${action.instruction}`).join(\" \");\n\tconst hasRepair = actions.some((action) => action.kind === \"repair\");\n\tconst authority = hasRepair\n\t\t? \"Only exact matching repair evidence grants 1 probe; else change operation.\"\n\t\t: \"Actions require changed operation; unchanged remains blocked.\";\n\treturn truncate(\n\t\t`${timeoutPolicy ? `${timeoutPolicy} ` : \"\"}Loaded actions: ${available} ${authority}`,\n\t\tMAX_RECOVERY_GUIDANCE_CHARS,\n\t);\n}\n\nfunction truncate(value: string, maxChars: number): string {\n\tif (value.length <= maxChars) return value;\n\treturn `${value.slice(0, maxChars - 1)}…`;\n}\n\nfunction sameRecoveryTarget(left: AgentToolFailureRecoveryTarget, right: AgentToolFailureRecoveryTarget): boolean {\n\treturn left.authority === right.authority && left.kind === right.kind && left.scope === right.scope;\n}\n\nfunction hasSharedRecoveryTarget(\n\tleft: readonly AgentToolFailureRecoveryTarget[],\n\tright: readonly AgentToolFailureRecoveryTarget[],\n): boolean {\n\tif (left.length > right.length) return hasSharedRecoveryTarget(right, left);\n\treturn left.some((target) => right.some((candidate) => sameRecoveryTarget(target, candidate)));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tool-failure-recovery-gate.js","sourceRoot":"","sources":["../src/tool-failure-recovery-gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,wCAAwC,CAAC;AAE7F,OAAO,EACN,uBAAuB,EACvB,mBAAmB,EACnB,4BAA4B,EAC5B,gCAAgC,EAChC,4BAA4B,EAC5B,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,GAExB,MAAM,0BAA0B,CAAC;AAQlC,OAAO,EAAE,mCAAmC,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,+BAA+B,GAAG,CAAC,CAAC;AAC1C,MAAM,qCAAqC,GAAG,CAAC,CAAC;AAChD,MAAM,iCAAiC,GAAG,CAAC,CAAC;AAC5C,MAAM,4BAA4B,GAAG,CAAC,CAAC;AACvC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AACnC,MAAM,2BAA2B,GAAG,EAAE,GAAG,IAAI,CAAC;AAC9C,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACjC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AACtC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AACzC,MAAM,2BAA2B,GAAG,GAAG,CAAC;AACxC,MAAM,mBAAmB,GAAG,yBAAyB,CAAC;AAmEtD;;;;;;;GAOG;AACH,MAAM,mBAAmB;IAAzB;QACkB,SAAI,GAAG,IAAI,UAAU,CAAC,2BAA2B,CAAC,CAAC;IAsBrE,CAAC;IApBA,GAAG,CAAC,YAAoB;QACvB,KAAK,MAAM,IAAI,IAAI,4BAA4B,CAAC,YAAY,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/E,CAAC;IAED,YAAY,CAAC,YAAoB;QAChC,KAAK,MAAM,IAAI,IAAI,4BAA4B,CAAC,YAAY,CAAC,EAAE,CAAC;YAC/D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,OAAO,KAAK,CAAC;QACnC,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,GAAG,CAAC,IAAY;QACvB,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAEO,GAAG,CAAC,IAAY;QACvB,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC;CACD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,uBAAuB;IAApC;QACkB,yBAAoB,GAAG,IAAI,GAAG,EAAgC,CAAC;QAC/D,yBAAoB,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAClE,yFAAyF;QACxE,mCAA8B,GAAG,IAAI,GAAG,EAAU,CAAC;QAC5D,uBAAkB,GAA4B,EAAE,CAAC;QACjD,qBAAgB,GAAG,CAAC,CAAC;QAErB,2BAAsB,GAAG,KAAK,CAAC;IAgSxC,CAAC;IA7RA,OAAO;QACN,OAAO,IAAI,CAAC,oBAAoB,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;IAC1E,CAAC;IAED,mBAAmB,CAAC,QAAiC;QACpD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC/B,IAAI,IAAI,CAAC,sBAAsB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAAE,OAAO;QAC3D,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC;QACnC,uBAAuB,CAAC,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE;YAC1E,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YAC/G,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACnC,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;gBACtC,OAAO;YACR,CAAC;YACD,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO;YACzC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YAC5C,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,WAAW,CACV,UAA0B,EAC1B,IAAa,EACb,WAAmB,EACnB,cAAyC,EACzC,WAAwD;QAExD,MAAM,OAAO,GAAG,kBAAkB,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QAClE,MAAM,OAAO,GAAG,4BAA4B,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACtE,MAAM,uBAAuB,GAAG,IAAI,CAAC,0BAA0B,CAAC,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAC5G,OAAO;YACN,OAAO;YACP,QAAQ,EAAE,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,uBAAuB,CAAC;SAC/E,CAAC;IACH,CAAC;IAED,KAAK,CACJ,IAAoB,EACpB,IAAa,EACb,MAA2C,EAC3C,QAAQ,GAA4B,IAAI,CAAC,kBAAkB;QAE3D,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC;QAC5B,IAAI,OAAO,EAAE,CAAC;YACb,OAAO;gBACN,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,KAAK;gBACZ,UAAU,EAAE,OAAO,CAAC,UAAU;aAC9B,CAAC;QACH,CAAC;QAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1D,IAAI,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,YAAY,CAAC;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACtF,IAAI,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,oBAAoB,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,CAAC;YACpE,KAAK,GAAG,IAAI,CAAC,8BAA8B,CAAC,YAAY,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,KAAK,IAAI,MAAM,IAAI,gCAAgC,CAAC,MAAM,CAAC,KAAK,YAAY,EAAE,CAAC;YACnF,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QACzG,CAAC;QACD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QAEvC,IAAI,MAAM,IAAI,gCAAgC,CAAC,MAAM,CAAC,KAAK,YAAY;YAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QAC/F,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,cAAc,GAAG,iCAAiC,EAAE,CAAC;gBACzF,KAAK,CAAC,oBAAoB,GAAG,KAAK,CAAC;gBACnC,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAC;gBAChC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,kBAAkB,EAAE,CAAC;gBAC3B,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;gBACzB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE,EAAE,CAAC;YAC3D,CAAC;YACD,MAAM,UAAU,GAAG,qGAAqG,KAAK,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC;YACpJ,IAAI,CAAC,MAAM,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;YACnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAC7F,CAAC;QACD,MAAM,uBAAuB,GAC5B,qCAAqC,GAAG,mCAAmC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACvG,IAAI,KAAK,CAAC,kBAAkB,GAAG,uBAAuB,EAAE,CAAC;YACxD,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC3B,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE,EAAE,CAAC;QAC3D,CAAC;QACD,IAAI,KAAK,CAAC,iBAAiB,IAAI,KAAK,CAAC,cAAc,GAAG,iCAAiC,EAAE,CAAC;YACzF,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAChC,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,KAAK,CAAC,kBAAkB,EAAE,CAAC;YAC3B,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;YACzB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE,EAAE,CAAC;QAC3D,CAAC;QAED,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,KAAK,CAAC,cAAc,IAAI,+BAA+B,EAAE,CAAC;YAC7D,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC;YAClC,MAAM,UAAU,GAAG,2CAA2C,KAAK,CAAC,cAAc,uBAAuB,KAAK,CAAC,MAAM,CAAC,WAAW,GAAG,CAAC;YACrI,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;QACnG,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,MAAiD;QACtD,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,SAAS,CAAC;QAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;YACrE,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC1F,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAED,QAAQ;QACP,OAAO,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;IAClC,CAAC;IAED,OAAO;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAEO,0BAA0B,CACjC,IAAoB,EACpB,IAAa,EACb,WAAmB,EACnB,WAAwD;QAExD,MAAM,UAAU,GAAG,mCAAmC,CAAC,WAAW,CAAC,CAAC;QACpE,IAAI,UAAU,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACnC,MAAM,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1D,MAAM,KAAK,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1D,MAAM,0BAA0B,GAAG,KAAK;YACvC,CAAC,CAAC,KAAK,CAAC,kBAAkB,GAAG,CAAC,WAAW,EAAE,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACjF,CAAC,CAAC,CAAC,CAAC;QACL,OAAO,0BAA0B,GAAG,qCAAqC,GAAG,UAAU,CAAC;IACxF,CAAC;IAEO,gBAAgB,CACvB,YAAoB,EACpB,MAA+B,EAC/B,OAAkD;QAElD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QAChD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,MAAM,KAAK,GAAG,0BAA0B,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,cAAc,CACrB,MAA+B,EAC/B,IAAa,EACb,OAAkD,EAClD,WAAwD;QAExD,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5D,IAAI,CAAC,8BAA8B,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACzD,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QACnE,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACtB,KAAK,CAAC,eAAe,GAAG,OAAO,CAAC;QAChC,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAChC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;QACzB,IAAI,WAAW,EAAE,YAAY,KAAK,YAAY;YAAE,KAAK,CAAC,kBAAkB,EAAE,CAAC;QAE3E,KAAK,CAAC,QAAQ,EAAE,CAAC;QAEjB,MAAM,qBAAqB,GAC1B,MAAM,CAAC,KAAK,KAAK,QAAQ;YACxB,CAAC,CAAC,qCAAqC;gBACtC,mCAAmC,CAAC,MAAM,CAAC,WAAW,CAAC;gBACvD,iCAAiC;YAClC,CAAC,CAAC,4BAA4B,CAAC;QACjC,IAAI,KAAK,CAAC,QAAQ,IAAI,qBAAqB,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,GAAG;gBACb,MAAM;gBACN,UAAU,EAAE,iCAAiC,KAAK,CAAC,QAAQ,qCAAqC;aAChG,CAAC;QACH,CAAC;IACF,CAAC;IAEO,cAAc,CAAC,IAAoB,EAAE,IAAa,EAAE,MAA4B;QACvF,MAAM,sBAAsB,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACpE,2FAA2F;QAC3F,4FAA4F;QAC5F,8FAA8F;QAC9F,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QAChE,MAAM,eAAe,GAAG,2BAA2B,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACxE,KAAK,MAAM,CAAC,YAAY,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC/D,IAAI,YAAY,KAAK,sBAAsB,EAAE,CAAC;gBAC7C,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC;gBACtC,SAAS;YACV,CAAC;YACD,IACC,KAAK,CAAC,cAAc,GAAG,iCAAiC;gBACxD,uBAAuB,CAAC,KAAK,CAAC,eAAe,EAAE,eAAe,CAAC,EAC9D,CAAC;gBACF,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC/B,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC;YAC1B,CAAC;QACF,CAAC;IACF,CAAC;IAEO,kBAAkB,CAAC,YAAoB;QAC9C,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IAEO,eAAe,CAAC,QAAiC;QACxD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3C,IACC,QAAQ,KAAK,IAAI,CAAC,kBAAkB;YACpC,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,gBAAgB;YACzC,IAAI,KAAK,IAAI,CAAC,cAAc,EAC3B,CAAC;YACF,sFAAsF;YACtF,uEAAuE;YACvE,IAAI,CAAC,8BAA8B,CAAC,KAAK,EAAE,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,QAAQ,CAAC;QACnC,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC;QACxC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC5B,CAAC;IAEO,WAAW,CAAC,YAAoB;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,KAAK,CAAC;IACd,CAAC;IAEO,cAAc,CAAC,YAAoB,EAAE,KAA2B;QACvE,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,oBAAoB,CAAC,IAAI,GAAG,uBAAuB,EAAE,CAAC;YACjE,MAAM,MAAM,GAAG,IAAI,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC7D,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM;YAChC,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC1C,CAAC;IACF,CAAC;IAEO,8BAA8B,CAAC,YAAoB;QAC1D,IAAI,aAA+C,CAAC;QACpD,uBAAuB,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,EAAE;YACvG,IAAI,YAAY,KAAK,YAAY;gBAAE,OAAO;YAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;YACjF,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACnC,aAAa,GAAG,SAAS,CAAC;gBAC1B,OAAO;YACR,CAAC;YACD,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ;gBAAE,aAAa,GAAG,SAAS,CAAC,KAAK,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,aAAa;YAAE,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACpE,OAAO,aAAa,CAAC;IACtB,CAAC;IAEO,sBAAsB,CAC7B,KAAuC,EACvC,IAAY,EACZ,IAAa,EACb,MAAyB;QAEzB,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,wBAAwB,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;QACvD,IAAI,yBAAyB,CAAC,WAAW,CAAC,IAAI,yBAAyB,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7F,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;QACnC,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,IAAI,0BAA0B,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,4BAA4B,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/C,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;YACjC,IAAI,CAAC,cAAc,GAAG,+BAA+B,CAAC;YACtD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAC/B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACxC,CAAC;QACD,IAAI,WAAW,KAAK,2BAA2B,EAAE,CAAC;YACjD,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;CACD;AAED,SAAS,0BAA0B,CAClC,MAA+B,EAC/B,eAA0D;IAE1D,OAAO;QACN,MAAM;QACN,eAAe;QACf,kBAAkB,EAAE,CAAC;QACrB,QAAQ,EAAE,CAAC;QACX,cAAc,EAAE,CAAC;QACjB,cAAc,EAAE,CAAC;QACjB,iBAAiB,EAAE,KAAK;QACxB,oBAAoB,EAAE,KAAK;KAC3B,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAC1B,IAAoB,EACpB,IAAa,EACb,WAAmB;IAEnB,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC;QACtC,MAAM,UAAU,GAAG,QAAQ,EAAE,iBAAiB,CAAC;QAC/C,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QAC7E,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED,SAAS,uBAAuB,CAAC,KAAc;IAC9C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,OAAO,GAAqC,EAAE,CAAC;IACrD,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,MAAM,IAAI,oBAAoB;YAAE,MAAM;QAClD,IAAI,CAAC,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE,SAAS;QACtF,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,SAAqE,CAAC;QACzG,IAAI,CAAC,mCAAmC,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3G,SAAS;QACV,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAAE,SAAS;QAC/F,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,eAAe,CAAC,KAAc;IACtC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,MAAM,GAAG,CAAC;QAChB,KAAK,CAAC,MAAM,IAAI,qBAAqB;QACrC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAC/B,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACvC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,sBAAsB,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAChH,CAAC;AACH,CAAC;AAED,SAAS,4BAA4B,CACpC,KAAgC,EAChC,OAAkD;IAElD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,MAAM,OAAO,GAA8B,EAAE,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,MAAM,SAAS,IAAI,2BAA2B,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3D,IAAI,OAAO,CAAC,MAAM,IAAI,oBAAoB;gBAAE,OAAO,OAAO,CAAC;YAC3D,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;YAC9C,IACC,CAAC,MAAM;gBACP,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,UAAU,CAAC,EACpG,CAAC;gBACF,SAAS;YACV,CAAC;YACD,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,EAAE,4BAA4B,CAAC,CAAC;YACtF,IAAI,CAAC,WAAW;gBAAE,SAAS;YAC3B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC3D,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACvE,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,2BAA2B,CAAC,IAAoB;IACxD,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QACxC,MAAM,OAAO,GAAc,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;QAC9D,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,EAAE,KAAK,EAAE;YAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1E,OAAO,OAAO,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,EAAE,CAAC;IACX,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc;IAC1C,IAAI,CAAC;QACJ,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAClF,MAAM,SAAS,GAAG,KAMjB,CAAC;QACF,IACC,CAAC,mCAAmC,CAAC,SAAS,CAAC,SAAS,CAAC;YACzD,CAAC,eAAe,CAAC,SAAS,CAAC,UAAU,CAAC;YACtC,OAAO,SAAS,CAAC,WAAW,KAAK,QAAQ,EACxC,CAAC;YACF,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAClC,OAAO;gBACN,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,SAAS,EAAE,SAAS,CAAC,SAAS;gBAC9B,UAAU,EAAE,SAAS,CAAC,UAAU;gBAChC,WAAW,EAAE,SAAS,CAAC,WAAW;aAClC,CAAC;QACH,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,SAAS,CAAC,WAAW,KAAK,UAAU;YAAE,OAAO,SAAS,CAAC;QACjG,MAAM,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;QAC1C,OAAO;YACN,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,UAAU,EAAE,SAAS,CAAC,UAAU;YAChC,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SACpF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,2BAA2B,CACnC,IAAoB,EACpB,IAAa,EACb,MAA4B;IAE5B,MAAM,OAAO,GAAqC,EAAE,CAAC;IACrD,KAAK,MAAM,SAAS,IAAI,2BAA2B,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;QAC9C,IAAI,OAAO,CAAC,MAAM,IAAI,oBAAoB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC1G,SAAS;QACV,CAAC;QACD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACJ,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC;YACR,SAAS;QACV,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,SAAS;QACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,IAAI,OAAO,CAAC,MAAM,IAAI,oBAAoB;gBAAE,MAAM;YAClD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;gBAAE,SAAS;YACvC,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,CAAC;YAC/E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/F,CAAC;IACF,CAAC;IACD,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAC9B,WAAmB,EACnB,OAA2C,EAC3C,uBAAgC;IAEhC,MAAM,qBAAqB,GAAG,mCAAmC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACnF,MAAM,aAAa,GAAG,qBAAqB;QAC1C,CAAC,CAAC,uBAAuB;YACxB,CAAC,CAAC,8EAA8E;YAChF,CAAC,CAAC,2DAA2D;QAC9D,CAAC,CAAC,SAAS,CAAC;IACb,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,IAAI,aAAa;YAAE,OAAO,GAAG,aAAa,8CAA8C,CAAC;QACzF,OAAO,gJAAgJ,CAAC;IACzJ,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChH,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,SAAS;QAC1B,CAAC,CAAC,4EAA4E;QAC9E,CAAC,CAAC,+DAA+D,CAAC;IACnE,OAAO,QAAQ,CACd,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,mBAAmB,SAAS,IAAI,SAAS,EAAE,EACtF,2BAA2B,CAC3B,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,QAAgB;IAChD,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3C,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC;AAC3C,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAoC,EAAE,KAAqC;IACtG,OAAO,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC;AACrG,CAAC;AAED,SAAS,uBAAuB,CAC/B,IAA+C,EAC/C,KAAgD;IAEhD,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;QAAE,OAAO,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5E,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC","sourcesContent":["import { getToolExecutionUnchangedRetryLimit } from \"@caupulican/pi-ai/tool-repair-registry\";\nimport type { ToolResultMessage } from \"@caupulican/pi-ai/types\";\nimport {\n\tforEachPairedToolResult,\n\tgetToolExecutionKey,\n\tgetToolExecutionKeyHashParts,\n\tgetToolFailureRecordExecutionKey,\n\tisClosedOperationFailureCode,\n\tisPromptScopedFailureCode,\n\treadVisibleToolFailureCode,\n\trestoreToolFailureRecord,\n\ttype ToolFailureMemoryRecord,\n} from \"./tool-failure-memory.ts\";\nimport type {\n\tAgentMessage,\n\tAgentTool,\n\tAgentToolFailureRecoveryAuthority,\n\tAgentToolFailureRecoveryTarget,\n\tAgentToolResult,\n} from \"./types.ts\";\nimport { isAgentToolFailureRecoveryAuthority } from \"./types.ts\";\n\nconst MAX_BLOCKED_REPLAYS_PER_FAILURE = 2;\nconst BASE_FAILURE_EXECUTIONS_PER_OPERATION = 1;\nconst MAX_RECOVERY_PROBES_PER_OPERATION = 1;\nconst MAX_REJECTIONS_PER_OPERATION = 4;\nconst MAX_HOT_RECOVERY_STATES = 64;\nconst SEEN_EXECUTION_FILTER_BYTES = 64 * 1024;\nconst MAX_RECOVERY_TARGETS = 8;\nconst MAX_RECOVERY_ACTIONS = 8;\nconst MAX_TARGET_KIND_CHARS = 64;\nconst MAX_TARGET_SCOPE_CHARS = 32_768;\nconst MAX_ACTION_INSTRUCTION_CHARS = 160;\nconst MAX_RECOVERY_GUIDANCE_CHARS = 320;\nconst TARGET_KIND_PATTERN = /^[a-z0-9][a-z0-9._:-]*$/;\n\nexport interface ToolFailureExecutionReservation {\n\texecutionKey: string;\n}\n\nexport interface ToolFailureRecoveryPlan {\n\ttargets: readonly AgentToolFailureRecoveryTarget[];\n\tguidance: string;\n}\n\nexport type ToolFailureRecoveryGateEffect =\n\t| {\n\t\t\tkind: \"failure\";\n\t\t\trecord: ToolFailureMemoryRecord;\n\t\t\targs: unknown;\n\t\t\ttargets?: readonly AgentToolFailureRecoveryTarget[];\n\t\t\treservation?: ToolFailureExecutionReservation;\n\t }\n\t| { kind: \"success\"; tool: AgentTool<any>; args: unknown; evidenceResult: AgentToolResult<any> };\n\nexport type ToolFailureRecoveryAdmission =\n\t| { kind: \"allowed\"; reservation?: ToolFailureExecutionReservation }\n\t| { kind: \"blocked\"; record: ToolFailureMemoryRecord; exhausted: false; diagnostic?: string }\n\t| {\n\t\t\tkind: \"blocked\";\n\t\t\trecord: ToolFailureMemoryRecord;\n\t\t\texhausted: true;\n\t\t\tscope: \"operation\" | \"run\";\n\t\t\tdiagnostic?: string;\n\t };\n\ninterface FailureRecoveryState {\n\trecord: ToolFailureMemoryRecord;\n\trecoveryTargets: readonly AgentToolFailureRecoveryTarget[];\n\treservedExecutions: number;\n\tfailures: number;\n\trecoveryProbes: number;\n\tblockedReplays: number;\n\trecoveryAvailable: boolean;\n\toperationCircuitOpen: boolean;\n}\n\ntype TranscriptRecoveryReduction =\n\t| { kind: \"resolved\" }\n\t| { kind: \"ignored\"; state: FailureRecoveryState | undefined }\n\t| { kind: \"failed\"; state: FailureRecoveryState };\n\ninterface AvailableRecoveryAction {\n\ttoolName: string;\n\tkind: \"correct\" | \"repair\";\n\tinstruction: string;\n}\n\ninterface ParsedRecoveryAction {\n\tkind: \"correct\" | \"repair\";\n\tauthority: AgentToolFailureRecoveryAuthority;\n\ttargetKind: string;\n\tinstruction: string;\n\tgetEvidence?: (params: unknown, result: AgentToolResult<unknown>) => unknown;\n}\n\nexport interface ToolFailureRecoveryHalt {\n\trecord: ToolFailureMemoryRecord;\n\tdiagnostic: string;\n}\n\n/**\n * Bounded negative lookup for exact execution identities.\n *\n * A miss proves the operation has not failed while this gate has been alive. A hit only means\n * \"possibly seen\" and must be verified against the transcript, so collisions can cost a scan but\n * can never deny an execution. Keeping this separate from the hot state cache lets old exact\n * circuits survive eviction without retaining one live object graph per historical operation.\n */\nclass SeenExecutionFilter {\n\tprivate readonly bits = new Uint8Array(SEEN_EXECUTION_FILTER_BYTES);\n\n\tadd(executionKey: string): void {\n\t\tfor (const hash of getToolExecutionKeyHashParts(executionKey)) this.set(hash);\n\t}\n\n\tmightContain(executionKey: string): boolean {\n\t\tfor (const hash of getToolExecutionKeyHashParts(executionKey)) {\n\t\t\tif (!this.has(hash)) return false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate set(hash: number): void {\n\t\tconst bit = (hash >>> 0) % (SEEN_EXECUTION_FILTER_BYTES * 8);\n\t\tthis.bits[bit >>> 3] |= 1 << (bit & 7);\n\t}\n\n\tprivate has(hash: number): boolean {\n\t\tconst bit = (hash >>> 0) % (SEEN_EXECUTION_FILTER_BYTES * 8);\n\t\treturn (this.bits[bit >>> 3] & (1 << (bit & 7))) !== 0;\n\t}\n}\n\n/**\n * Owns execution admission and bounded unresolved-failure budgets.\n *\n * Recovery authority is exact and tool-owned. A failed tool declares opaque backend-specific targets;\n * a loaded recovery tool may teach actions only for the same authority and target kind. Only raw\n * successful repair evidence with byte-exact scope can reopen one probe. Argument text and hooks have\n * no recovery authority.\n *\n * Run-level halt stays on the current run, but admission is never denied because unrelated operations\n * happened to fail. A bounded hot cache carries active per-operation state. A fixed-size negative\n * lookup sends an evicted exact replay back to the transcript for authoritative reconstruction, so\n * cache pressure cannot either stop new work or reopen an already-exhausted operation.\n */\nexport class ToolFailureRecoveryGate {\n\tprivate readonly statesByExecutionKey = new Map<string, FailureRecoveryState>();\n\tprivate readonly seenFailedExecutions = new SeenExecutionFilter();\n\t/** Exact successes not yet present in the transcript snapshot consulted by admission. */\n\tprivate readonly resolvedBeforeTranscriptCommit = new Set<string>();\n\tprivate transcriptMessages: readonly AgentMessage[] = [];\n\tprivate transcriptLength = 0;\n\tprivate transcriptTail: AgentMessage | undefined;\n\tprivate restoredFromTranscript = false;\n\tprivate halted: ToolFailureRecoveryHalt | undefined;\n\n\tisEmpty(): boolean {\n\t\treturn this.statesByExecutionKey.size === 0 && this.halted === undefined;\n\t}\n\n\trestoreFromMessages(messages: readonly AgentMessage[]): void {\n\t\tthis.trackTranscript(messages);\n\t\tif (this.restoredFromTranscript || !this.isEmpty()) return;\n\t\tthis.restoredFromTranscript = true;\n\t\tforEachPairedToolResult(messages, ({ tool, args, executionKey, result }) => {\n\t\t\tconst reduction = this.reduceTranscriptResult(this.statesByExecutionKey.get(executionKey), tool, args, result);\n\t\t\tif (reduction.kind === \"resolved\") {\n\t\t\t\tthis.clearResolvedState(executionKey);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (reduction.kind === \"ignored\") return;\n\t\t\tthis.seenFailedExecutions.add(executionKey);\n\t\t\tthis.retainHotState(executionKey, reduction.state);\n\t\t});\n\t}\n\n\tplanFailure(\n\t\tfailedTool: AgentTool<any>,\n\t\targs: unknown,\n\t\tfailureCode: string,\n\t\tavailableTools: readonly AgentTool<any>[],\n\t\treservation: ToolFailureExecutionReservation | undefined,\n\t): ToolFailureRecoveryPlan {\n\t\tconst targets = readFailureTargets(failedTool, args, failureCode);\n\t\tconst actions = readAvailableRecoveryActions(availableTools, targets);\n\t\tconst unchangedRetryRemaining = this.hasUnchangedRetryRemaining(failedTool, args, failureCode, reservation);\n\t\treturn {\n\t\t\ttargets,\n\t\t\tguidance: formatRecoveryGuidance(failureCode, actions, unchangedRetryRemaining),\n\t\t};\n\t}\n\n\tadmit(\n\t\ttool: AgentTool<any>,\n\t\targs: unknown,\n\t\trecord: ToolFailureMemoryRecord | undefined,\n\t\tmessages: readonly AgentMessage[] = this.transcriptMessages,\n\t): ToolFailureRecoveryAdmission {\n\t\tthis.trackTranscript(messages);\n\t\tconst runHalt = this.halted;\n\t\tif (runHalt) {\n\t\t\treturn {\n\t\t\t\tkind: \"blocked\",\n\t\t\t\trecord: runHalt.record,\n\t\t\t\texhausted: true,\n\t\t\t\tscope: \"run\",\n\t\t\t\tdiagnostic: runHalt.diagnostic,\n\t\t\t};\n\t\t}\n\n\t\tconst executionKey = getToolExecutionKey(tool.name, args);\n\t\tif (this.resolvedBeforeTranscriptCommit.has(executionKey)) return { kind: \"allowed\" };\n\t\tlet state = this.getHotState(executionKey);\n\t\tif (!state && this.seenFailedExecutions.mightContain(executionKey)) {\n\t\t\tstate = this.restoreOperationFromTranscript(executionKey);\n\t\t}\n\t\tif (!state && record && getToolFailureRecordExecutionKey(record) === executionKey) {\n\t\t\tstate = this.getOrCreateState(executionKey, record, readFailureTargets(tool, args, record.failureCode));\n\t\t}\n\t\tif (!state) return { kind: \"allowed\" };\n\n\t\tif (record && getToolFailureRecordExecutionKey(record) === executionKey) state.record = record;\n\t\tif (state.operationCircuitOpen) {\n\t\t\tif (state.recoveryAvailable && state.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION) {\n\t\t\t\tstate.operationCircuitOpen = false;\n\t\t\t\tstate.recoveryAvailable = false;\n\t\t\t\tstate.recoveryProbes++;\n\t\t\t\tstate.reservedExecutions++;\n\t\t\t\tstate.blockedReplays = 0;\n\t\t\t\treturn { kind: \"allowed\", reservation: { executionKey } };\n\t\t\t}\n\t\t\tconst diagnostic = `Run recovery circuit opened after replay of an operation whose local circuit was already open for ${state.record.failureCode}.`;\n\t\t\tthis.halted = { record: state.record, diagnostic };\n\t\t\treturn { kind: \"blocked\", record: state.record, exhausted: true, scope: \"run\", diagnostic };\n\t\t}\n\t\tconst automaticExecutionLimit =\n\t\t\tBASE_FAILURE_EXECUTIONS_PER_OPERATION + getToolExecutionUnchangedRetryLimit(state.record.failureCode);\n\t\tif (state.reservedExecutions < automaticExecutionLimit) {\n\t\t\tstate.reservedExecutions++;\n\t\t\tstate.blockedReplays = 0;\n\t\t\treturn { kind: \"allowed\", reservation: { executionKey } };\n\t\t}\n\t\tif (state.recoveryAvailable && state.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION) {\n\t\t\tstate.recoveryAvailable = false;\n\t\t\tstate.recoveryProbes++;\n\t\t\tstate.reservedExecutions++;\n\t\t\tstate.blockedReplays = 0;\n\t\t\treturn { kind: \"allowed\", reservation: { executionKey } };\n\t\t}\n\n\t\tstate.blockedReplays++;\n\t\tif (state.blockedReplays >= MAX_BLOCKED_REPLAYS_PER_FAILURE) {\n\t\t\tstate.operationCircuitOpen = true;\n\t\t\tconst diagnostic = `Operation recovery circuit opened after ${state.blockedReplays} blocked replays of ${state.record.failureCode}.`;\n\t\t\treturn { kind: \"blocked\", record: state.record, exhausted: true, scope: \"operation\", diagnostic };\n\t\t}\n\t\treturn { kind: \"blocked\", record: state.record, exhausted: false };\n\t}\n\n\tapply(effect: ToolFailureRecoveryGateEffect | undefined): ToolFailureRecoveryHalt | undefined {\n\t\tif (!effect || this.halted) return undefined;\n\t\tif (effect.kind === \"success\") {\n\t\t\tthis.observeSuccess(effect.tool, effect.args, effect.evidenceResult);\n\t\t\treturn undefined;\n\t\t}\n\t\tthis.observeFailure(effect.record, effect.args, effect.targets ?? [], effect.reservation);\n\t\treturn this.halted;\n\t}\n\n\tisHalted(): boolean {\n\t\treturn this.halted !== undefined;\n\t}\n\n\tgetHalt(): ToolFailureRecoveryHalt | undefined {\n\t\treturn this.halted;\n\t}\n\n\tprivate hasUnchangedRetryRemaining(\n\t\ttool: AgentTool<any>,\n\t\targs: unknown,\n\t\tfailureCode: string,\n\t\treservation: ToolFailureExecutionReservation | undefined,\n\t): boolean {\n\t\tconst retryLimit = getToolExecutionUnchangedRetryLimit(failureCode);\n\t\tif (retryLimit === 0) return false;\n\t\tconst executionKey = getToolExecutionKey(tool.name, args);\n\t\tconst state = this.statesByExecutionKey.get(executionKey);\n\t\tconst executionsIncludingCurrent = state\n\t\t\t? state.reservedExecutions + (reservation?.executionKey === executionKey ? 0 : 1)\n\t\t\t: 1;\n\t\treturn executionsIncludingCurrent < BASE_FAILURE_EXECUTIONS_PER_OPERATION + retryLimit;\n\t}\n\n\tprivate getOrCreateState(\n\t\texecutionKey: string,\n\t\trecord: ToolFailureMemoryRecord,\n\t\ttargets: readonly AgentToolFailureRecoveryTarget[],\n\t): FailureRecoveryState {\n\t\tconst existing = this.getHotState(executionKey);\n\t\tif (existing) return existing;\n\t\tconst state = createFailureRecoveryState(record, targets);\n\t\tthis.retainHotState(executionKey, state);\n\t\treturn state;\n\t}\n\n\tprivate observeFailure(\n\t\trecord: ToolFailureMemoryRecord,\n\t\targs: unknown,\n\t\ttargets: readonly AgentToolFailureRecoveryTarget[],\n\t\treservation: ToolFailureExecutionReservation | undefined,\n\t): void {\n\t\tconst executionKey = getToolExecutionKey(record.tool, args);\n\t\tthis.resolvedBeforeTranscriptCommit.delete(executionKey);\n\t\tthis.seenFailedExecutions.add(executionKey);\n\t\tconst state = this.getOrCreateState(executionKey, record, targets);\n\t\tif (this.halted) return;\n\t\tstate.record = record;\n\t\tstate.recoveryTargets = targets;\n\t\tstate.recoveryAvailable = false;\n\t\tstate.blockedReplays = 0;\n\t\tif (reservation?.executionKey !== executionKey) state.reservedExecutions++;\n\n\t\tstate.failures++;\n\n\t\tconst operationFailureLimit =\n\t\t\trecord.state === \"failed\"\n\t\t\t\t? BASE_FAILURE_EXECUTIONS_PER_OPERATION +\n\t\t\t\t\tgetToolExecutionUnchangedRetryLimit(record.failureCode) +\n\t\t\t\t\tMAX_RECOVERY_PROBES_PER_OPERATION\n\t\t\t\t: MAX_REJECTIONS_PER_OPERATION;\n\t\tif (state.failures >= operationFailureLimit) {\n\t\t\tthis.halted = {\n\t\t\t\trecord,\n\t\t\t\tdiagnostic: `Recovery circuit opened after ${state.failures} failed outcomes for one operation.`,\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate observeSuccess(tool: AgentTool<any>, args: unknown, result: AgentToolResult<any>): void {\n\t\tconst successfulExecutionKey = getToolExecutionKey(tool.name, args);\n\t\t// Tool results are appended to the transcript after the current execution batch completes.\n\t\t// Until then the last persisted failure is stale authority: remember the exact success so a\n\t\t// later sequential call in this same batch cannot resurrect that failure from the transcript.\n\t\tthis.resolvedBeforeTranscriptCommit.add(successfulExecutionKey);\n\t\tconst evidenceTargets = readRecoveryEvidenceTargets(tool, args, result);\n\t\tfor (const [executionKey, state] of this.statesByExecutionKey) {\n\t\t\tif (executionKey === successfulExecutionKey) {\n\t\t\t\tthis.clearResolvedState(executionKey);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tstate.recoveryProbes < MAX_RECOVERY_PROBES_PER_OPERATION &&\n\t\t\t\thasSharedRecoveryTarget(state.recoveryTargets, evidenceTargets)\n\t\t\t) {\n\t\t\t\tstate.recoveryAvailable = true;\n\t\t\t\tstate.blockedReplays = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate clearResolvedState(executionKey: string): void {\n\t\tthis.statesByExecutionKey.delete(executionKey);\n\t}\n\n\tprivate trackTranscript(messages: readonly AgentMessage[]): void {\n\t\tconst tail = messages[messages.length - 1];\n\t\tif (\n\t\t\tmessages !== this.transcriptMessages ||\n\t\t\tmessages.length !== this.transcriptLength ||\n\t\t\ttail !== this.transcriptTail\n\t\t) {\n\t\t\t// An advanced transcript now authoritatively records completed results. The temporary\n\t\t\t// exact-success overlay is bounded to one uncommitted execution batch.\n\t\t\tthis.resolvedBeforeTranscriptCommit.clear();\n\t\t}\n\t\tthis.transcriptMessages = messages;\n\t\tthis.transcriptLength = messages.length;\n\t\tthis.transcriptTail = tail;\n\t}\n\n\tprivate getHotState(executionKey: string): FailureRecoveryState | undefined {\n\t\tconst state = this.statesByExecutionKey.get(executionKey);\n\t\tif (!state) return undefined;\n\t\tthis.statesByExecutionKey.delete(executionKey);\n\t\tthis.statesByExecutionKey.set(executionKey, state);\n\t\treturn state;\n\t}\n\n\tprivate retainHotState(executionKey: string, state: FailureRecoveryState): void {\n\t\tthis.statesByExecutionKey.delete(executionKey);\n\t\tthis.statesByExecutionKey.set(executionKey, state);\n\t\twhile (this.statesByExecutionKey.size > MAX_HOT_RECOVERY_STATES) {\n\t\t\tconst oldest = this.statesByExecutionKey.keys().next().value;\n\t\t\tif (oldest === undefined) break;\n\t\t\tthis.statesByExecutionKey.delete(oldest);\n\t\t}\n\t}\n\n\tprivate restoreOperationFromTranscript(executionKey: string): FailureRecoveryState | undefined {\n\t\tlet restoredState: FailureRecoveryState | undefined;\n\t\tforEachPairedToolResult(this.transcriptMessages, ({ tool, args, executionKey: candidateKey, result }) => {\n\t\t\tif (candidateKey !== executionKey) return;\n\t\t\tconst reduction = this.reduceTranscriptResult(restoredState, tool, args, result);\n\t\t\tif (reduction.kind === \"resolved\") {\n\t\t\t\trestoredState = undefined;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (reduction.kind === \"failed\") restoredState = reduction.state;\n\t\t});\n\t\tif (restoredState) this.retainHotState(executionKey, restoredState);\n\t\treturn restoredState;\n\t}\n\n\tprivate reduceTranscriptResult(\n\t\tstate: FailureRecoveryState | undefined,\n\t\ttool: string,\n\t\targs: unknown,\n\t\tresult: ToolResultMessage,\n\t): TranscriptRecoveryReduction {\n\t\tif (!result.isError) return { kind: \"resolved\" };\n\t\tconst record = restoreToolFailureRecord(result, tool, args);\n\t\tconst visibleCode = readVisibleToolFailureCode(result);\n\t\tif (isPromptScopedFailureCode(visibleCode) || isPromptScopedFailureCode(record.failureCode)) {\n\t\t\treturn { kind: \"ignored\", state };\n\t\t}\n\t\tconst next = state ?? createFailureRecoveryState(record, []);\n\t\tnext.record = record;\n\t\tif (isClosedOperationFailureCode(visibleCode)) {\n\t\t\tnext.operationCircuitOpen = true;\n\t\t\tnext.blockedReplays = MAX_BLOCKED_REPLAYS_PER_FAILURE;\n\t\t\tnext.recoveryAvailable = false;\n\t\t\treturn { kind: \"failed\", state: next };\n\t\t}\n\t\tif (visibleCode === \"repeated_failed_operation\") {\n\t\t\tnext.blockedReplays++;\n\t\t\treturn { kind: \"failed\", state: next };\n\t\t}\n\t\tnext.reservedExecutions++;\n\t\tnext.failures++;\n\t\treturn { kind: \"failed\", state: next };\n\t}\n}\n\nfunction createFailureRecoveryState(\n\trecord: ToolFailureMemoryRecord,\n\trecoveryTargets: readonly AgentToolFailureRecoveryTarget[],\n): FailureRecoveryState {\n\treturn {\n\t\trecord,\n\t\trecoveryTargets,\n\t\treservedExecutions: 0,\n\t\tfailures: 0,\n\t\trecoveryProbes: 0,\n\t\tblockedReplays: 0,\n\t\trecoveryAvailable: false,\n\t\toperationCircuitOpen: false,\n\t};\n}\n\nfunction readFailureTargets(\n\ttool: AgentTool<any>,\n\targs: unknown,\n\tfailureCode: string,\n): readonly AgentToolFailureRecoveryTarget[] {\n\ttry {\n\t\tconst contract = tool.failureRecovery;\n\t\tconst getTargets = contract?.getFailureTargets;\n\t\tif (!getTargets) return [];\n\t\tconst targets = Reflect.apply(getTargets, contract, [args, { failureCode }]);\n\t\treturn sanitizeRecoveryTargets(targets);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction sanitizeRecoveryTargets(value: unknown): readonly AgentToolFailureRecoveryTarget[] {\n\tif (!Array.isArray(value)) return [];\n\tconst targets: AgentToolFailureRecoveryTarget[] = [];\n\tfor (const candidate of value) {\n\t\tif (targets.length >= MAX_RECOVERY_TARGETS) break;\n\t\tif (!candidate || typeof candidate !== \"object\" || Array.isArray(candidate)) continue;\n\t\tconst { authority, kind, scope } = candidate as { authority?: unknown; kind?: unknown; scope?: unknown };\n\t\tif (!isAgentToolFailureRecoveryAuthority(authority) || !validTargetKind(kind) || !validTargetScope(scope)) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (targets.some((target) => sameRecoveryTarget(target, { authority, kind, scope }))) continue;\n\t\ttargets.push({ authority, kind, scope });\n\t}\n\treturn targets;\n}\n\nfunction validTargetKind(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" &&\n\t\tvalue.length > 0 &&\n\t\tvalue.length <= MAX_TARGET_KIND_CHARS &&\n\t\tTARGET_KIND_PATTERN.test(value)\n\t);\n}\n\nfunction validTargetScope(value: unknown): value is string {\n\treturn (\n\t\ttypeof value === \"string\" && value.length > 0 && value.length <= MAX_TARGET_SCOPE_CHARS && !value.includes(\"\\0\")\n\t);\n}\n\nfunction readAvailableRecoveryActions(\n\ttools: readonly AgentTool<any>[],\n\ttargets: readonly AgentToolFailureRecoveryTarget[],\n): readonly AvailableRecoveryAction[] {\n\tif (targets.length === 0) return [];\n\tconst actions: AvailableRecoveryAction[] = [];\n\tconst seen = new Set<string>();\n\tfor (const tool of tools) {\n\t\tfor (const candidate of readDeclaredRecoveryActions(tool)) {\n\t\t\tif (actions.length >= MAX_RECOVERY_ACTIONS) return actions;\n\t\t\tconst action = parseRecoveryAction(candidate);\n\t\t\tif (\n\t\t\t\t!action ||\n\t\t\t\t!targets.some((target) => target.authority === action.authority && target.kind === action.targetKind)\n\t\t\t) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst instruction = truncate(action.instruction.trim(), MAX_ACTION_INSTRUCTION_CHARS);\n\t\t\tif (!instruction) continue;\n\t\t\tconst key = `${tool.name}\\0${action.kind}\\0${instruction}`;\n\t\t\tif (seen.has(key)) continue;\n\t\t\tseen.add(key);\n\t\t\tactions.push({ toolName: tool.name, kind: action.kind, instruction });\n\t\t}\n\t}\n\treturn actions;\n}\n\nfunction readDeclaredRecoveryActions(tool: AgentTool<any>): readonly unknown[] {\n\ttry {\n\t\tconst declared = tool.failureRecovery?.actions;\n\t\tif (!Array.isArray(declared)) return [];\n\t\tconst actions: unknown[] = [];\n\t\tconst count = Math.min(declared.length, MAX_RECOVERY_ACTIONS);\n\t\tfor (let index = 0; index < count; index++) actions.push(declared[index]);\n\t\treturn actions;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction parseRecoveryAction(value: unknown): ParsedRecoveryAction | undefined {\n\ttry {\n\t\tif (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined;\n\t\tconst candidate = value as {\n\t\t\tkind?: unknown;\n\t\t\tauthority?: unknown;\n\t\t\ttargetKind?: unknown;\n\t\t\tinstruction?: unknown;\n\t\t\tgetEvidence?: unknown;\n\t\t};\n\t\tif (\n\t\t\t!isAgentToolFailureRecoveryAuthority(candidate.authority) ||\n\t\t\t!validTargetKind(candidate.targetKind) ||\n\t\t\ttypeof candidate.instruction !== \"string\"\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (candidate.kind === \"correct\") {\n\t\t\treturn {\n\t\t\t\tkind: candidate.kind,\n\t\t\t\tauthority: candidate.authority,\n\t\t\t\ttargetKind: candidate.targetKind,\n\t\t\t\tinstruction: candidate.instruction,\n\t\t\t};\n\t\t}\n\t\tif (candidate.kind !== \"repair\" || typeof candidate.getEvidence !== \"function\") return undefined;\n\t\tconst getEvidence = candidate.getEvidence;\n\t\treturn {\n\t\t\tkind: candidate.kind,\n\t\t\tauthority: candidate.authority,\n\t\t\ttargetKind: candidate.targetKind,\n\t\t\tinstruction: candidate.instruction,\n\t\t\tgetEvidence: (params, result) => Reflect.apply(getEvidence, value, [params, result]),\n\t\t};\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction readRecoveryEvidenceTargets(\n\ttool: AgentTool<any>,\n\targs: unknown,\n\tresult: AgentToolResult<any>,\n): readonly AgentToolFailureRecoveryTarget[] {\n\tconst targets: AgentToolFailureRecoveryTarget[] = [];\n\tfor (const candidate of readDeclaredRecoveryActions(tool)) {\n\t\tconst action = parseRecoveryAction(candidate);\n\t\tif (targets.length >= MAX_RECOVERY_TARGETS || !action || action.kind !== \"repair\" || !action.getEvidence) {\n\t\t\tcontinue;\n\t\t}\n\t\tlet scopes: unknown;\n\t\ttry {\n\t\t\tscopes = action.getEvidence(args, result);\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tif (!Array.isArray(scopes)) continue;\n\t\tfor (const scope of scopes) {\n\t\t\tif (targets.length >= MAX_RECOVERY_TARGETS) break;\n\t\t\tif (!validTargetScope(scope)) continue;\n\t\t\tconst target = { authority: action.authority, kind: action.targetKind, scope };\n\t\t\tif (!targets.some((candidate) => sameRecoveryTarget(candidate, target))) targets.push(target);\n\t\t}\n\t}\n\treturn targets;\n}\n\nfunction formatRecoveryGuidance(\n\tfailureCode: string,\n\tactions: readonly AvailableRecoveryAction[],\n\tunchangedRetryRemaining: boolean,\n): string {\n\tconst hasTimeoutRetryPolicy = getToolExecutionUnchangedRetryLimit(failureCode) > 0;\n\tconst timeoutPolicy = hasTimeoutRetryPolicy\n\t\t? unchangedRetryRemaining\n\t\t\t? \"Timeout policy allows 1 unchanged retry; if it fails, never retry unchanged.\"\n\t\t\t: \"Timeout unchanged retry exhausted; never retry unchanged.\"\n\t\t: undefined;\n\tif (actions.length === 0) {\n\t\tif (timeoutPolicy) return `${timeoutPolicy} Change/narrow operation, or report blocker.`;\n\t\treturn \"No loaded tool declares recovery. Never retry unchanged. Use materially different operation justified by diagnostic/schema, or report blocker.\";\n\t}\n\tconst available = actions.map((action) => `${action.toolName} ${action.kind}: ${action.instruction}`).join(\" \");\n\tconst hasRepair = actions.some((action) => action.kind === \"repair\");\n\tconst authority = hasRepair\n\t\t? \"Only exact matching repair evidence grants 1 probe; else change operation.\"\n\t\t: \"Actions require changed operation; unchanged remains blocked.\";\n\treturn truncate(\n\t\t`${timeoutPolicy ? `${timeoutPolicy} ` : \"\"}Loaded actions: ${available} ${authority}`,\n\t\tMAX_RECOVERY_GUIDANCE_CHARS,\n\t);\n}\n\nfunction truncate(value: string, maxChars: number): string {\n\tif (value.length <= maxChars) return value;\n\treturn `${value.slice(0, maxChars - 1)}…`;\n}\n\nfunction sameRecoveryTarget(left: AgentToolFailureRecoveryTarget, right: AgentToolFailureRecoveryTarget): boolean {\n\treturn left.authority === right.authority && left.kind === right.kind && left.scope === right.scope;\n}\n\nfunction hasSharedRecoveryTarget(\n\tleft: readonly AgentToolFailureRecoveryTarget[],\n\tright: readonly AgentToolFailureRecoveryTarget[],\n): boolean {\n\tif (left.length > right.length) return hasSharedRecoveryTarget(right, left);\n\treturn left.some((target) => right.some((candidate) => sameRecoveryTarget(target, candidate)));\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -216,8 +216,8 @@ export type ProviderRequestAdmissionResult = {
|
|
|
216
216
|
* trips it, but bounds the cost of a model wedged repeating one failing call forever.
|
|
217
217
|
*/
|
|
218
218
|
export declare const DEFAULT_MAX_STALL_TURNS = 12;
|
|
219
|
-
/**
|
|
220
|
-
export declare const DEFAULT_MAX_PROVIDER_TURNS =
|
|
219
|
+
/** Provider-turn fuse is opt-in; varied productive work has no implicit request-count ceiling. */
|
|
220
|
+
export declare const DEFAULT_MAX_PROVIDER_TURNS = 0;
|
|
221
221
|
export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
222
222
|
model: Model<any>;
|
|
223
223
|
/**
|
|
@@ -326,14 +326,14 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
326
326
|
*/
|
|
327
327
|
maxStallTurns?: number;
|
|
328
328
|
/**
|
|
329
|
-
*
|
|
329
|
+
* Optional provider-request fuse for one logical prompt, including host continuations.
|
|
330
330
|
* Unlike {@link maxStallTurns}, this also catches varied tool churn that never repeats an exact
|
|
331
|
-
* signature. The loop emits a local terminal diagnostic before another provider request.
|
|
332
|
-
*
|
|
331
|
+
* signature. The loop emits a local terminal diagnostic before another provider request. Positive
|
|
332
|
+
* values explicitly enable the fuse; `0` disables it. Default: {@link DEFAULT_MAX_PROVIDER_TURNS}.
|
|
333
333
|
*/
|
|
334
334
|
maxProviderTurns?: number;
|
|
335
335
|
/**
|
|
336
|
-
* Observability hook fired once if either the repeated-call backstop or provider-turn
|
|
336
|
+
* Observability hook fired once if either the repeated-call backstop or explicit provider-turn fuse trips,
|
|
337
337
|
* just before the loop stops. Lets the host surface/log the exact cause. Must not throw.
|
|
338
338
|
*/
|
|
339
339
|
onRunawayStop?: (info: AgentRunawayStopInfo) => void;
|
|
@@ -434,9 +434,8 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
|
|
|
434
434
|
/**
|
|
435
435
|
* Thinking/reasoning level for models that support it.
|
|
436
436
|
* Note: "xhigh", "max", and "ultra" are only supported by selected model families. "ultra" maps
|
|
437
|
-
* to the model's maximum provider effort
|
|
438
|
-
*
|
|
439
|
-
* @caupulican/pi-ai to detect support for a concrete model.
|
|
437
|
+
* to the model's maximum provider effort. Delegation policy is provider- and reasoning-independent.
|
|
438
|
+
* Use model thinking-level metadata from @caupulican/pi-ai to detect support for a concrete model.
|
|
440
439
|
*/
|
|
441
440
|
export type ThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" | "ultra";
|
|
442
441
|
/**
|
|
@@ -493,6 +492,8 @@ export interface AgentState {
|
|
|
493
492
|
/** Error message from the most recent failed or aborted assistant turn, if any. */
|
|
494
493
|
readonly errorMessage?: string;
|
|
495
494
|
}
|
|
495
|
+
/** Provenance marker for messages synthesized by the host instead of a provider transport. */
|
|
496
|
+
export type AgentMessageOrigin = "local";
|
|
496
497
|
/** Final or partial result produced by a tool. */
|
|
497
498
|
export interface AgentToolResult<T> {
|
|
498
499
|
/** Text or image content returned to the model. */
|
|
@@ -627,6 +628,7 @@ export type AgentEvent = {
|
|
|
627
628
|
} | {
|
|
628
629
|
type: "message_start";
|
|
629
630
|
message: AgentMessage;
|
|
631
|
+
origin?: AgentMessageOrigin;
|
|
630
632
|
} | {
|
|
631
633
|
type: "message_update";
|
|
632
634
|
message: AgentMessage;
|
|
@@ -634,6 +636,7 @@ export type AgentEvent = {
|
|
|
634
636
|
} | {
|
|
635
637
|
type: "message_end";
|
|
636
638
|
message: AgentMessage;
|
|
639
|
+
origin?: AgentMessageOrigin;
|
|
637
640
|
} | {
|
|
638
641
|
type: "tool_execution_start";
|
|
639
642
|
toolCallId: string;
|