agentfootprint 11.2.0 → 11.3.0
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/AGENTS.md +1 -1
- package/CAPABILITIES.md +2 -0
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/adapters/identity/verify/claims.js +3 -3
- package/dist/adapters/mcp/agentcoreRuntime/invoke.js +3 -2
- package/dist/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
- package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js +6 -5
- package/dist/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
- package/dist/adapters/mcp/agentcoreRuntime/transport.js +8 -6
- package/dist/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
- package/dist/core/agent/buildToolRegistry.js +1 -1
- package/dist/core/agent/buildToolRegistry.js.map +1 -1
- package/dist/core/agent/evidence/evidenceIndex.js +30 -2
- package/dist/core/agent/evidence/evidenceIndex.js.map +1 -1
- package/dist/core/agent/evidence/extract.js +34 -5
- package/dist/core/agent/evidence/extract.js.map +1 -1
- package/dist/core/agent/evidence/figures.js +31 -3
- package/dist/core/agent/evidence/figures.js.map +1 -1
- package/dist/core/agent/evidence/numberPrecision.js +58 -2
- package/dist/core/agent/evidence/numberPrecision.js.map +1 -1
- package/dist/core/agent/stages/route.js +2 -1
- package/dist/core/agent/stages/route.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +14 -1
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/slots/buildToolsSlot.js +1 -1
- package/dist/core/slots/buildToolsSlot.js.map +1 -1
- package/dist/esm/adapters/identity/jwks.d.ts +2 -2
- package/dist/esm/adapters/identity/verify/claims.d.ts +3 -3
- package/dist/esm/adapters/identity/verify/claims.js +3 -3
- package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.d.ts +3 -2
- package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js +3 -2
- package/dist/esm/adapters/mcp/agentcoreRuntime/invoke.js.map +1 -1
- package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +6 -5
- package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js +6 -5
- package/dist/esm/adapters/mcp/agentcoreRuntime/sessionBusy.js.map +1 -1
- package/dist/esm/adapters/mcp/agentcoreRuntime/transport.d.ts +3 -1
- package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js +9 -7
- package/dist/esm/adapters/mcp/agentcoreRuntime/transport.js.map +1 -1
- package/dist/esm/core/agent/buildToolRegistry.js +1 -1
- package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
- package/dist/esm/core/agent/evidence/evidenceIndex.d.ts +12 -2
- package/dist/esm/core/agent/evidence/evidenceIndex.js +30 -2
- package/dist/esm/core/agent/evidence/evidenceIndex.js.map +1 -1
- package/dist/esm/core/agent/evidence/extract.js +35 -6
- package/dist/esm/core/agent/evidence/extract.js.map +1 -1
- package/dist/esm/core/agent/evidence/figures.d.ts +6 -0
- package/dist/esm/core/agent/evidence/figures.js +32 -4
- package/dist/esm/core/agent/evidence/figures.js.map +1 -1
- package/dist/esm/core/agent/evidence/numberPrecision.d.ts +28 -1
- package/dist/esm/core/agent/evidence/numberPrecision.js +56 -1
- package/dist/esm/core/agent/evidence/numberPrecision.js.map +1 -1
- package/dist/esm/core/agent/stages/route.js +2 -1
- package/dist/esm/core/agent/stages/route.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.js +14 -1
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/slots/buildToolsSlot.js +1 -1
- package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +185 -0
- package/dist/esm/events/registry.d.ts +3 -1
- package/dist/esm/events/registry.js +2 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/hosting/doorGuard.d.ts +3 -3
- package/dist/esm/hosting/doorGuard.js +2 -2
- package/dist/esm/hosting/nodeHost.d.ts +1 -1
- package/dist/esm/mcp/callLifetime.d.ts +49 -0
- package/dist/esm/mcp/callLifetime.js +99 -0
- package/dist/esm/mcp/callLifetime.js.map +1 -0
- package/dist/esm/mcp/mcpClient.d.ts +4 -1
- package/dist/esm/mcp/mcpClient.js +70 -28
- package/dist/esm/mcp/mcpClient.js.map +1 -1
- package/dist/esm/mcp/requestLedger.d.ts +97 -0
- package/dist/esm/mcp/requestLedger.js +192 -0
- package/dist/esm/mcp/requestLedger.js.map +1 -0
- package/dist/esm/mcp/seriesEvidence.d.ts +102 -0
- package/dist/esm/mcp/seriesEvidence.js +246 -0
- package/dist/esm/mcp/seriesEvidence.js.map +1 -0
- package/dist/esm/mcp/throttleRetry.d.ts +70 -35
- package/dist/esm/mcp/throttleRetry.js +181 -54
- package/dist/esm/mcp/throttleRetry.js.map +1 -1
- package/dist/esm/mcp/types.d.ts +12 -7
- package/dist/esm/redaction/knownStrings.js +29 -0
- package/dist/esm/redaction/knownStrings.js.map +1 -1
- package/dist/esm/security/PermissionPolicy.d.ts +1 -1
- package/dist/esm/security/PermissionPolicy.js +1 -1
- package/dist/esm/strategies/defaults/chatBubbleLiveStatus.d.ts +1 -1
- package/dist/esm/strategies/defaults/chatBubbleLiveStatus.js +1 -1
- package/dist/esm/tool-lint/analyze.d.ts +1 -1
- package/dist/esm/tool-lint/analyze.js +1 -1
- package/dist/esm/tool-lint/rules.d.ts +3 -3
- package/dist/esm/tool-lint/rules.js +3 -3
- package/dist/esm/tools/requestEvidence.d.ts +78 -0
- package/dist/esm/tools/requestEvidence.js +331 -0
- package/dist/esm/tools/requestEvidence.js.map +1 -0
- package/dist/events/registry.js +2 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/hosting/doorGuard.js +2 -2
- package/dist/mcp/callLifetime.js +103 -0
- package/dist/mcp/callLifetime.js.map +1 -0
- package/dist/mcp/mcpClient.js +69 -27
- package/dist/mcp/mcpClient.js.map +1 -1
- package/dist/mcp/requestLedger.js +196 -0
- package/dist/mcp/requestLedger.js.map +1 -0
- package/dist/mcp/seriesEvidence.js +251 -0
- package/dist/mcp/seriesEvidence.js.map +1 -0
- package/dist/mcp/throttleRetry.js +184 -55
- package/dist/mcp/throttleRetry.js.map +1 -1
- package/dist/redaction/knownStrings.js +29 -0
- package/dist/redaction/knownStrings.js.map +1 -1
- package/dist/security/PermissionPolicy.js +1 -1
- package/dist/strategies/defaults/chatBubbleLiveStatus.js +1 -1
- package/dist/tool-lint/analyze.js +1 -1
- package/dist/tool-lint/rules.js +3 -3
- package/dist/tools/requestEvidence.js +337 -0
- package/dist/tools/requestEvidence.js.map +1 -0
- package/dist/types/adapters/identity/jwks.d.ts +2 -2
- package/dist/types/adapters/identity/verify/claims.d.ts +3 -3
- package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts +3 -2
- package/dist/types/adapters/mcp/agentcoreRuntime/invoke.d.ts.map +1 -1
- package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts +6 -5
- package/dist/types/adapters/mcp/agentcoreRuntime/sessionBusy.d.ts.map +1 -1
- package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts +3 -1
- package/dist/types/adapters/mcp/agentcoreRuntime/transport.d.ts.map +1 -1
- package/dist/types/core/agent/evidence/evidenceIndex.d.ts +12 -2
- package/dist/types/core/agent/evidence/evidenceIndex.d.ts.map +1 -1
- package/dist/types/core/agent/evidence/extract.d.ts.map +1 -1
- package/dist/types/core/agent/evidence/figures.d.ts +6 -0
- package/dist/types/core/agent/evidence/figures.d.ts.map +1 -1
- package/dist/types/core/agent/evidence/numberPrecision.d.ts +28 -1
- package/dist/types/core/agent/evidence/numberPrecision.d.ts.map +1 -1
- package/dist/types/core/agent/stages/route.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +185 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +3 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/hosting/doorGuard.d.ts +3 -3
- package/dist/types/hosting/nodeHost.d.ts +1 -1
- package/dist/types/mcp/callLifetime.d.ts +50 -0
- package/dist/types/mcp/callLifetime.d.ts.map +1 -0
- package/dist/types/mcp/mcpClient.d.ts +4 -1
- package/dist/types/mcp/mcpClient.d.ts.map +1 -1
- package/dist/types/mcp/requestLedger.d.ts +98 -0
- package/dist/types/mcp/requestLedger.d.ts.map +1 -0
- package/dist/types/mcp/seriesEvidence.d.ts +103 -0
- package/dist/types/mcp/seriesEvidence.d.ts.map +1 -0
- package/dist/types/mcp/throttleRetry.d.ts +70 -35
- package/dist/types/mcp/throttleRetry.d.ts.map +1 -1
- package/dist/types/mcp/types.d.ts +12 -7
- package/dist/types/mcp/types.d.ts.map +1 -1
- package/dist/types/redaction/knownStrings.d.ts.map +1 -1
- package/dist/types/security/PermissionPolicy.d.ts +1 -1
- package/dist/types/strategies/defaults/chatBubbleLiveStatus.d.ts +1 -1
- package/dist/types/tool-lint/analyze.d.ts +1 -1
- package/dist/types/tool-lint/rules.d.ts +3 -3
- package/dist/types/tools/requestEvidence.d.ts +79 -0
- package/dist/types/tools/requestEvidence.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* seriesEvidence — one MCP request's retry series, written down for its run.
|
|
3
|
+
*
|
|
4
|
+
* Pattern: a collector over footprintjs's attempt records, filed once.
|
|
5
|
+
* Role: The series (`throttleRetry.ts` · `Series`) is the one retry owner and
|
|
6
|
+
* the attempt runner makes one record per try; this turns each record
|
|
7
|
+
* into an allow-listed row and files the request's whole story — its
|
|
8
|
+
* rows, how many were not listed, and how it ended — to the call's sink
|
|
9
|
+
* (`tools/requestEvidence.ts`) exactly ONCE.
|
|
10
|
+
*
|
|
11
|
+
* WHAT A ROW MAY SAY. Numbers and the library's own words; never the server's
|
|
12
|
+
* answer, the call's arguments or an error's text. A failure is a fixed sentence
|
|
13
|
+
* and its category — a network or SDK error message can carry a URL with a token
|
|
14
|
+
* in it, a host's internal name or a server's reply.
|
|
15
|
+
*
|
|
16
|
+
* A RESPONSE IS NOT A SUCCESS. The runner records an attempt that returned a
|
|
17
|
+
* response as `ok` with the reason `succeeded`; here it is `answered`, with the
|
|
18
|
+
* status the server sent — a 503 delivered is `answered` + `503`, never success.
|
|
19
|
+
*
|
|
20
|
+
* EVERY REQUEST SENT IS COUNTED. Each attempt the series started is a row — or,
|
|
21
|
+
* past the cap, one more in `omitted` — so `rows + omitted` is the number of
|
|
22
|
+
* requests the series sent. An attempt a cancellation cuts in flight is a row
|
|
23
|
+
* too (`cut`), exactly as an attempt the deadline cuts is (`timed-out`). A
|
|
24
|
+
* request the series never sent — the next one after a cancelled wait — has no
|
|
25
|
+
* row.
|
|
26
|
+
*
|
|
27
|
+
* A CUT IS NOT A "NOT RUN". An attempt that ended without an answer — cut,
|
|
28
|
+
* timed out, or failed — was sent, and the server may have received it and run
|
|
29
|
+
* it. Its row says so (`remote: 'unknown'`); nothing here records it as not run.
|
|
30
|
+
*
|
|
31
|
+
* WHEN IT FILES. When the series ends — and, for a cancellation, at the moment the
|
|
32
|
+
* signal fires: a cancelled run stops waiting for its stage at once, so a record
|
|
33
|
+
* filed when the series later unwinds would land after the run was saved. The
|
|
34
|
+
* runner makes no record for an attempt it abandons at that moment or for a wait
|
|
35
|
+
* it was cut out of, so those are written here: the cut attempt's row and
|
|
36
|
+
* `during: 'request'`, or `during: 'wait'`. Anything the series reports after it
|
|
37
|
+
* has filed is not part of the request's story any more and is ignored.
|
|
38
|
+
*/
|
|
39
|
+
import { MAX_REQUEST_ATTEMPT_ROWS, } from '../tools/requestEvidence.js';
|
|
40
|
+
const FAILED = 'The request failed before an answer arrived. Its error is not kept.';
|
|
41
|
+
const OUT_OF_TIME = 'The call ran out of time before an answer arrived.';
|
|
42
|
+
/** One request's evidence, collected as its series runs and filed once. */
|
|
43
|
+
export class SeriesEvidence {
|
|
44
|
+
sink;
|
|
45
|
+
where;
|
|
46
|
+
rows = [];
|
|
47
|
+
omitted = 0;
|
|
48
|
+
last;
|
|
49
|
+
filed = false;
|
|
50
|
+
constructor(sink, where) {
|
|
51
|
+
this.sink = sink;
|
|
52
|
+
this.where = where;
|
|
53
|
+
}
|
|
54
|
+
/** One attempt as the runner recorded it. */
|
|
55
|
+
attempt(record, seen, declined) {
|
|
56
|
+
if (this.filed)
|
|
57
|
+
return;
|
|
58
|
+
this.add(rowOf(record, seen, declined));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The caller's cancellation cut attempt `n` in flight. It was sent — the
|
|
62
|
+
* server may have it, and may have run it — so it is a row, `cut`, with the
|
|
63
|
+
* remote outcome `unknown`; then the request's end says the same.
|
|
64
|
+
*/
|
|
65
|
+
cutInFlight(n) {
|
|
66
|
+
if (this.filed)
|
|
67
|
+
return;
|
|
68
|
+
this.add({ attempt: n, outcome: 'cut', reason: 'cancelled', remote: 'unknown' });
|
|
69
|
+
this.file({ outcome: 'cut', reason: 'cancelled', during: 'request', remote: 'unknown' });
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The caller's cancellation landed with NO request in flight: between two —
|
|
73
|
+
* `during: 'wait'`, the next request never sent — or before the first, when
|
|
74
|
+
* nothing was sent and there is no `during`. No row is added: there is no
|
|
75
|
+
* request to account for. A request that had already ended keeps its end.
|
|
76
|
+
*/
|
|
77
|
+
cancelled() {
|
|
78
|
+
const last = this.last;
|
|
79
|
+
if (last !== undefined && last.reason !== 'retryable') {
|
|
80
|
+
this.file(endOf(last));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.file({
|
|
84
|
+
outcome: 'cancelled',
|
|
85
|
+
reason: 'cancelled',
|
|
86
|
+
...(last !== undefined && { during: 'wait' }),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The series delivered a response. It is the last attempt's — an answer, or a
|
|
91
|
+
* refusal it will not ask again after. A refusal it MEANT to ask again after
|
|
92
|
+
* is delivered when the deadline lands inside the wait: the runner's wait
|
|
93
|
+
* ends early, the series stops, and the end says so (`no-time-left`, during
|
|
94
|
+
* the `wait`).
|
|
95
|
+
*/
|
|
96
|
+
delivered() {
|
|
97
|
+
const last = this.last;
|
|
98
|
+
if (last === undefined) {
|
|
99
|
+
this.file(UNACCOUNTED);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.file(last.reason === 'retryable'
|
|
103
|
+
? { ...endOf(last), reason: 'no-time-left', during: 'wait' }
|
|
104
|
+
: endOf(last));
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The series threw. The end is the last attempt's when that attempt ended it
|
|
108
|
+
* (a failure, a timed-out request). The rest is defensive — footprintjs 10.6's
|
|
109
|
+
* runner never throws without a record but for a cancellation, which is filed
|
|
110
|
+
* as one: a deadline that had passed before the first request (`timed-out`,
|
|
111
|
+
* no `during`, nothing sent) or one a future runner reports from inside a wait
|
|
112
|
+
* (`during: 'wait'`); anything else is filed as a failure the record cannot
|
|
113
|
+
* account for, so a request is never left unfiled.
|
|
114
|
+
*/
|
|
115
|
+
threw(outOfTime) {
|
|
116
|
+
const last = this.last;
|
|
117
|
+
if (last !== undefined && last.reason !== 'retryable') {
|
|
118
|
+
this.file(endOf(last));
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (!outOfTime) {
|
|
122
|
+
this.file(UNACCOUNTED);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
this.file({
|
|
126
|
+
outcome: 'timed-out',
|
|
127
|
+
reason: 'no-time-left',
|
|
128
|
+
failure: 'timeout',
|
|
129
|
+
...(last !== undefined && { during: 'wait' }),
|
|
130
|
+
error: { message: OUT_OF_TIME, code: 'timeout' },
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
add(row) {
|
|
134
|
+
this.last = row;
|
|
135
|
+
if (this.rows.length < MAX_REQUEST_ATTEMPT_ROWS)
|
|
136
|
+
this.rows.push(row);
|
|
137
|
+
else
|
|
138
|
+
this.omitted += 1;
|
|
139
|
+
}
|
|
140
|
+
file(end) {
|
|
141
|
+
if (this.filed)
|
|
142
|
+
return;
|
|
143
|
+
this.filed = true;
|
|
144
|
+
try {
|
|
145
|
+
this.sink.file({ ...this.where, attempts: [...this.rows], omitted: this.omitted, end });
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// The library's sink never throws; one that does must not fail the call.
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* An end no attempt accounts for — never seen; kept so a request is never left
|
|
154
|
+
* unfiled, and never claiming more than is known.
|
|
155
|
+
*/
|
|
156
|
+
const UNACCOUNTED = {
|
|
157
|
+
outcome: 'failed',
|
|
158
|
+
reason: 'not-retryable',
|
|
159
|
+
failure: 'unknown',
|
|
160
|
+
error: { message: FAILED, code: 'unknown' },
|
|
161
|
+
remote: 'unknown',
|
|
162
|
+
};
|
|
163
|
+
/** One record as a row — see the module note for what a row may say. */
|
|
164
|
+
export function rowOf(record, seen, declined) {
|
|
165
|
+
const outcome = outcomeOf(record, seen);
|
|
166
|
+
const reason = reasonOf(record, declined);
|
|
167
|
+
const refusal = outcome === 'refused' ? seen?.refusal : undefined;
|
|
168
|
+
return {
|
|
169
|
+
attempt: record.attempt,
|
|
170
|
+
outcome,
|
|
171
|
+
reason,
|
|
172
|
+
...((outcome === 'answered' || outcome === 'refused') &&
|
|
173
|
+
seen?.status !== undefined && { status: seen.status }),
|
|
174
|
+
...(refusal !== undefined && { kind: refusal.kind }),
|
|
175
|
+
...(outcome !== 'answered' &&
|
|
176
|
+
outcome !== 'cut' &&
|
|
177
|
+
record.category !== undefined && { failure: record.category }),
|
|
178
|
+
...(reason === 'retryable' && { waitMs: record.delayMs ?? 0 }),
|
|
179
|
+
...(refusal?.retryAfterMs !== undefined && { retryAfterMs: refusal.retryAfterMs }),
|
|
180
|
+
...((outcome === 'failed' || outcome === 'timed-out') && {
|
|
181
|
+
error: errorOf(outcome, record.category),
|
|
182
|
+
}),
|
|
183
|
+
...(noAnswer(outcome) && { remote: 'unknown' }),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/** An attempt that ended without an answer — the server may have run it, or not. */
|
|
187
|
+
function noAnswer(outcome) {
|
|
188
|
+
return outcome === 'failed' || outcome === 'timed-out' || outcome === 'cut';
|
|
189
|
+
}
|
|
190
|
+
function outcomeOf(record, seen) {
|
|
191
|
+
switch (record.outcome) {
|
|
192
|
+
case 'ok':
|
|
193
|
+
return 'answered';
|
|
194
|
+
case 'timeout':
|
|
195
|
+
return 'timed-out';
|
|
196
|
+
case 'failed':
|
|
197
|
+
return seen?.refusal !== undefined ? 'refused' : 'failed';
|
|
198
|
+
case 'aborted':
|
|
199
|
+
// Cut in flight by the series' cancellation. The cancellation itself files
|
|
200
|
+
// this row first (`cutInFlight`), so the record is seen only if it did not.
|
|
201
|
+
return 'cut';
|
|
202
|
+
default:
|
|
203
|
+
// `paused` cannot happen inside a fetch.
|
|
204
|
+
return 'failed';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function reasonOf(record, declined) {
|
|
208
|
+
if (record.outcome === 'ok')
|
|
209
|
+
return 'answered';
|
|
210
|
+
if (record.next === 'retry')
|
|
211
|
+
return 'retryable';
|
|
212
|
+
if (record.outcome === 'timeout')
|
|
213
|
+
return 'no-time-left';
|
|
214
|
+
switch (record.reason) {
|
|
215
|
+
case 'exhausted':
|
|
216
|
+
return 'exhausted';
|
|
217
|
+
case 'no-time-left':
|
|
218
|
+
return 'no-time-left';
|
|
219
|
+
case 'aborted':
|
|
220
|
+
return 'cancelled';
|
|
221
|
+
case 'declined':
|
|
222
|
+
return declined ?? 'not-retryable';
|
|
223
|
+
default:
|
|
224
|
+
return 'not-retryable';
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
function errorOf(outcome, category) {
|
|
228
|
+
return outcome === 'timed-out'
|
|
229
|
+
? { message: OUT_OF_TIME, code: category ?? 'timeout' }
|
|
230
|
+
: { message: FAILED, code: category ?? 'unknown' };
|
|
231
|
+
}
|
|
232
|
+
/** How a request ended, when it ended with its last attempt. */
|
|
233
|
+
function endOf(last) {
|
|
234
|
+
const { outcome, reason, status, kind, failure, error, remote } = last;
|
|
235
|
+
return {
|
|
236
|
+
outcome,
|
|
237
|
+
reason,
|
|
238
|
+
...(status !== undefined && { status }),
|
|
239
|
+
...(kind !== undefined && { kind }),
|
|
240
|
+
...(failure !== undefined && { failure }),
|
|
241
|
+
...((outcome === 'timed-out' || outcome === 'cut') && { during: 'request' }),
|
|
242
|
+
...(error !== undefined && { error }),
|
|
243
|
+
...(remote !== undefined && { remote }),
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=seriesEvidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seriesEvidence.js","sourceRoot":"","sources":["../../../src/mcp/seriesEvidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* throttleRetry — when an MCP server refuses a request
|
|
3
|
-
* and ask again.
|
|
2
|
+
* throttleRetry — when an MCP server refuses a request with a response the
|
|
3
|
+
* retry policy recognises (HTTP 429), wait and ask again.
|
|
4
4
|
*
|
|
5
5
|
* ── Why this exists ──────────────────────────────────────────────────────────
|
|
6
6
|
* Managed MCP gateways enforce per-principal rate limits. A throttled
|
|
@@ -10,20 +10,24 @@
|
|
|
10
10
|
* tool, or invents an answer. A designed, transient, self-clearing condition
|
|
11
11
|
* was being turned into a wrong answer.
|
|
12
12
|
*
|
|
13
|
-
* ──
|
|
14
|
-
* **
|
|
15
|
-
* at the edge
|
|
16
|
-
*
|
|
13
|
+
* ── What retrying a 429 assumes, and why the policy is 429-ONLY ─────────────
|
|
14
|
+
* **Automatic 429 retries assume the server rejected the request before
|
|
15
|
+
* executing it.** A rate limiter that refuses at the edge has not run the tool —
|
|
16
|
+
* but HTTP 429 says only that the request was rate-limited (RFC 6585 §4), so the
|
|
17
|
+
* saved response records the assumption's basis (the server's 429), not proof
|
|
18
|
+
* that nothing ran. There is no side-effect guard here: a tool with side
|
|
19
|
+
* effects is retried on 429 like any other today, and `retryOnThrottle: false`
|
|
20
|
+
* turns that off per server. What is certain is the contrast with a 500 or a
|
|
17
21
|
* timeout, where the call may have half-run and a retry could charge a card
|
|
18
22
|
* twice.
|
|
19
23
|
*
|
|
20
|
-
* That
|
|
21
|
-
* widen. Only HTTP 429 retries here. Not 5xx, not network errors, not timeouts
|
|
24
|
+
* That assumption is the whole license for this module, so the policy must
|
|
25
|
+
* never widen. Only HTTP 429 retries here. Not 5xx, not network errors, not timeouts
|
|
22
26
|
* — those belong to a caller who knows whether the specific tool is idempotent,
|
|
23
27
|
* and this seam does not. A property test pins the boundary.
|
|
24
28
|
*
|
|
25
29
|
* The loop takes its question as a {@link RetryDecision}, so the one other
|
|
26
|
-
* refusal a service
|
|
30
|
+
* refusal a service documents as one to retry — AgentCore Runtime's "session
|
|
27
31
|
* operation in progress" — reuses this loop rather than growing a second one.
|
|
28
32
|
* That decision is applied only by that vendor's own transport; what
|
|
29
33
|
* `mcpClient` and `retryingFetch` retry is still a 429 and nothing else.
|
|
@@ -46,10 +50,13 @@
|
|
|
46
50
|
*
|
|
47
51
|
* ── The loop is footprintjs's attempt runner, one series per call ────────────
|
|
48
52
|
* Each call runs ONE `attempt()` series (footprintjs, used as it ships). Its
|
|
49
|
-
* runner makes an attempt record per try
|
|
50
|
-
*
|
|
51
|
-
* the
|
|
52
|
-
*
|
|
53
|
+
* runner makes an attempt record per try. `onRetry`, before each wait, is what
|
|
54
|
+
* reaches a caller; the RUN gets the records: for a call the agent dispatched,
|
|
55
|
+
* the series files every attempt and how the request ended into that call's
|
|
56
|
+
* run (`seriesEvidence.ts`, through the connection's `requestLedger.ts`). An
|
|
57
|
+
* attempt sends the request once, and an attempt that got a RESPONSE is not an
|
|
58
|
+
* operation that succeeded: a 503 is delivered as the answer it was, never
|
|
59
|
+
* retried — and written down as `answered` with its status, never success.
|
|
53
60
|
* A response a rule's decision recognises is thrown as a refusal that names
|
|
54
61
|
* its kind, and the policy's `retryOn` accepts those refusals and nothing
|
|
55
62
|
* else — so a 5xx, a dropped connection or a timeout ends the series on the
|
|
@@ -83,6 +90,7 @@
|
|
|
83
90
|
*
|
|
84
91
|
* Pattern: Decorator over `fetch`. Role: Layer-3 tool transport.
|
|
85
92
|
*/
|
|
93
|
+
import type { RequestLedger } from './requestLedger.js';
|
|
86
94
|
/**
|
|
87
95
|
* The fetch shape the MCP SDK's `fetch` hook uses — deliberately NARROWER
|
|
88
96
|
* than `gatewayTransport`'s `FetchLike` (no `Request` input), because that is
|
|
@@ -184,21 +192,24 @@ export interface ThrottleRetryOptions {
|
|
|
184
192
|
/**
|
|
185
193
|
* A name for this endpoint, declared by you, that `onRetry` reports as
|
|
186
194
|
* `endpoint` — so a log line can say which server was retried without
|
|
187
|
-
* carrying any part of its URL past the origin.
|
|
188
|
-
*
|
|
189
|
-
*
|
|
195
|
+
* carrying any part of its URL past the origin. A dispatched call's saved
|
|
196
|
+
* attempts name the endpoint by it too, in place of the origin. 1–128
|
|
197
|
+
* characters, none of them control characters. Absent, `onRetry` has no
|
|
198
|
+
* `endpoint` field; the library never makes one up from the URL.
|
|
190
199
|
*/
|
|
191
200
|
readonly endpointLabel?: string;
|
|
192
201
|
/**
|
|
193
|
-
* A notification before each wait
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
+
* A notification before each wait. It is told the refusal's kind, the
|
|
203
|
+
* attempt about to start, the wait, the endpoint's origin and the label you
|
|
204
|
+
* declared for it (`endpointLabel`) — never the URL's path, the request's
|
|
205
|
+
* arguments or the server's answer. It is not told how the call ended. The
|
|
206
|
+
* contract matches what `withRetry` and `withCredentialRetry` already use: a
|
|
207
|
+
* decorator at a transport boundary reports to its consumer.
|
|
208
|
+
*
|
|
209
|
+
* What the RUN keeps is separate and needs no hook: for a call the agent
|
|
210
|
+
* dispatched, the series files every attempt — its outcome, its reason, its
|
|
211
|
+
* wait — and how the request ended, as `agentfootprint.tools.request_attempts`
|
|
212
|
+
* (the label is reported there as `endpoint`).
|
|
202
213
|
*
|
|
203
214
|
* A retried call is not invisible without this: the wait lands inside the
|
|
204
215
|
* tool's `stream.tool_end` `durationMs`, and an exhausted retry still
|
|
@@ -229,9 +240,10 @@ export interface RetryVerdict {
|
|
|
229
240
|
* The one question the loop asks of each response.
|
|
230
241
|
*
|
|
231
242
|
* ── The license every decision must hold ─────────────────────────────────────
|
|
232
|
-
* A decision may answer "again" ONLY for a
|
|
233
|
-
*
|
|
234
|
-
* note). A response that could be
|
|
243
|
+
* A decision may answer "again" ONLY for a response the library treats as a
|
|
244
|
+
* refusal made before anything ran — the assumption a 429 retry rests on (see
|
|
245
|
+
* the module note: the 429 is its basis, not proof). A response that could be
|
|
246
|
+
* the record of half-done work is never one.
|
|
235
247
|
* The library holds exactly two such decisions: {@link throttled} below, and
|
|
236
248
|
* AgentCore Runtime's documented "session operation in progress" refusal,
|
|
237
249
|
* which lives with that vendor's adapter (`adapters/mcp/agentcoreRuntime/`).
|
|
@@ -333,20 +345,43 @@ export declare function retryRule(kind: RetryKind, decide: RetryDecision, config
|
|
|
333
345
|
* is built, never at the first call.
|
|
334
346
|
*/
|
|
335
347
|
export declare function retryingFetch(inner: ThrottleFetch | undefined, config: RetryOnThrottle | undefined): ThrottleFetch | undefined;
|
|
348
|
+
/**
|
|
349
|
+
* @internal What one call's series is built from: the rules it asks, in order,
|
|
350
|
+
* and the connection's ledger — which tool call each request belongs to, so the
|
|
351
|
+
* series can file its attempts into that call's run (`requestLedger.ts`).
|
|
352
|
+
*/
|
|
353
|
+
export interface SeriesSpec {
|
|
354
|
+
readonly rules: readonly RetryRule[];
|
|
355
|
+
readonly ledger?: RequestLedger;
|
|
356
|
+
}
|
|
357
|
+
/** @internal What a joinable fetch's series can be rebuilt with: one more rule, or a ledger. */
|
|
358
|
+
export type SeriesJoin = {
|
|
359
|
+
readonly rule: RetryRule;
|
|
360
|
+
} | {
|
|
361
|
+
readonly ledger: RequestLedger;
|
|
362
|
+
};
|
|
363
|
+
/** @internal `spec` with `join` in it. */
|
|
364
|
+
export declare function joinedSpec(spec: SeriesSpec, join: SeriesJoin): SeriesSpec;
|
|
336
365
|
/**
|
|
337
366
|
* @internal Declare that `fetch` runs its retries in ONE series, and how to
|
|
338
|
-
* rebuild it with one more rule in that same series.
|
|
339
|
-
* a fetch instead of wrapping it. A transport whose
|
|
340
|
-
* series (a session applied around it, its answers
|
|
341
|
-
* this so the rule lands INSIDE that wrapping.
|
|
367
|
+
* rebuild it with one more rule — or with a ledger — in that same series.
|
|
368
|
+
* `retryingFetch` joins such a fetch instead of wrapping it. A transport whose
|
|
369
|
+
* public fetch wraps its series (a session applied around it, its answers
|
|
370
|
+
* rewritten after it) uses this so the rule lands INSIDE that wrapping.
|
|
371
|
+
*/
|
|
372
|
+
export declare function joinableRetry(fetch: ThrottleFetch, rebuild: (join: SeriesJoin) => ThrottleFetch): ThrottleFetch;
|
|
373
|
+
/**
|
|
374
|
+
* @internal `fetch` rebuilt so its series files each request's attempts through
|
|
375
|
+
* `ledger` — or `undefined` when `fetch` runs no series (retry off), so there
|
|
376
|
+
* is nothing to file and the caller keeps `fetch` as it is.
|
|
342
377
|
*/
|
|
343
|
-
export declare function
|
|
378
|
+
export declare function ledgeredFetch(fetch: ThrottleFetch, ledger: RequestLedger): ThrottleFetch | undefined;
|
|
344
379
|
/**
|
|
345
|
-
* @internal The one series per call over `inner`, asking `rules` in order —
|
|
380
|
+
* @internal The one series per call over `inner`, asking `spec.rules` in order —
|
|
346
381
|
* `inner` itself when there are none. The first rule holds the call's budget;
|
|
347
382
|
* see the module note. The result is joinable.
|
|
348
383
|
*/
|
|
349
|
-
export declare function retryingFetchFor(inner: ThrottleFetch,
|
|
384
|
+
export declare function retryingFetchFor(inner: ThrottleFetch, spec: SeriesSpec): ThrottleFetch;
|
|
350
385
|
/**
|
|
351
386
|
* `Retry-After` in either legal form: delta-seconds (`"2"`) or an HTTP-date
|
|
352
387
|
* (`"Wed, 21 Oct 2026 07:28:00 GMT"`). Anything else is treated as absent so a
|