agentfootprint 9.5.1 → 9.7.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/CLAUDE.md +1 -1
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/adapters/code/agentcore.js +294 -0
- package/dist/adapters/code/agentcore.js.map +1 -0
- package/dist/adapters/code/local.js +200 -0
- package/dist/adapters/code/local.js.map +1 -0
- package/dist/adapters/llm/AnthropicProvider.js +6 -0
- package/dist/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/adapters/llm/BedrockProvider.js +7 -0
- package/dist/adapters/llm/BedrockProvider.js.map +1 -1
- package/dist/adapters/llm/BrowserAnthropicProvider.js +13 -0
- package/dist/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/adapters/llm/BrowserOpenAIProvider.js +14 -0
- package/dist/adapters/llm/BrowserOpenAIProvider.js.map +1 -1
- package/dist/adapters/llm/OpenAIProvider.js +7 -0
- package/dist/adapters/llm/OpenAIProvider.js.map +1 -1
- package/dist/adapters/llm/contextWindow.js +284 -0
- package/dist/adapters/llm/contextWindow.js.map +1 -0
- package/dist/core/Agent.js +145 -0
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/RunnerBase.js +67 -0
- package/dist/core/RunnerBase.js.map +1 -1
- package/dist/core/agent/stages/seed.js +67 -11
- package/dist/core/agent/stages/seed.js.map +1 -1
- package/dist/core/agent/stages/toolCalls.js +90 -0
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/codeRunnerTool.js +252 -0
- package/dist/core/codeRunnerTool.js.map +1 -0
- package/dist/core/runCheckpoint.js +102 -2
- package/dist/core/runCheckpoint.js.map +1 -1
- package/dist/core/toolSessions.js +396 -0
- package/dist/core/toolSessions.js.map +1 -0
- package/dist/core/tools.js.map +1 -1
- package/dist/doors/providers.js +13 -0
- package/dist/doors/providers.js.map +1 -1
- package/dist/esm/adapters/code/agentcore.d.ts +133 -0
- package/dist/esm/adapters/code/agentcore.js +290 -0
- package/dist/esm/adapters/code/agentcore.js.map +1 -0
- package/dist/esm/adapters/code/local.d.ts +99 -0
- package/dist/esm/adapters/code/local.js +196 -0
- package/dist/esm/adapters/code/local.js.map +1 -0
- package/dist/esm/adapters/llm/AnthropicProvider.js +6 -0
- package/dist/esm/adapters/llm/AnthropicProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BedrockProvider.js +7 -0
- package/dist/esm/adapters/llm/BedrockProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js +13 -0
- package/dist/esm/adapters/llm/BrowserAnthropicProvider.js.map +1 -1
- package/dist/esm/adapters/llm/BrowserOpenAIProvider.js +14 -0
- package/dist/esm/adapters/llm/BrowserOpenAIProvider.js.map +1 -1
- package/dist/esm/adapters/llm/OpenAIProvider.js +7 -0
- package/dist/esm/adapters/llm/OpenAIProvider.js.map +1 -1
- package/dist/esm/adapters/llm/contextWindow.d.ts +111 -0
- package/dist/esm/adapters/llm/contextWindow.js +277 -0
- package/dist/esm/adapters/llm/contextWindow.js.map +1 -0
- package/dist/esm/adapters/types.d.ts +87 -0
- package/dist/esm/core/Agent.d.ts +65 -0
- package/dist/esm/core/Agent.js +146 -1
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/RunnerBase.d.ts +51 -0
- package/dist/esm/core/RunnerBase.js +67 -0
- package/dist/esm/core/RunnerBase.js.map +1 -1
- package/dist/esm/core/agent/stages/seed.d.ts +12 -0
- package/dist/esm/core/agent/stages/seed.js +67 -11
- package/dist/esm/core/agent/stages/seed.js.map +1 -1
- package/dist/esm/core/agent/stages/toolCalls.d.ts +31 -0
- package/dist/esm/core/agent/stages/toolCalls.js +90 -0
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +23 -2
- package/dist/esm/core/codeRunnerTool.d.ts +120 -0
- package/dist/esm/core/codeRunnerTool.js +247 -0
- package/dist/esm/core/codeRunnerTool.js.map +1 -0
- package/dist/esm/core/runCheckpoint.d.ts +25 -0
- package/dist/esm/core/runCheckpoint.js +100 -1
- package/dist/esm/core/runCheckpoint.js.map +1 -1
- package/dist/esm/core/toolSessions.d.ts +318 -0
- package/dist/esm/core/toolSessions.js +389 -0
- package/dist/esm/core/toolSessions.js.map +1 -0
- package/dist/esm/core/tools.d.ts +60 -0
- package/dist/esm/core/tools.js.map +1 -1
- package/dist/esm/doors/providers.d.ts +7 -0
- package/dist/esm/doors/providers.js +10 -0
- package/dist/esm/doors/providers.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +50 -0
- package/dist/esm/events/registry.d.ts +9 -1
- package/dist/esm/events/registry.js +8 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/index.d.ts +4 -1
- package/dist/esm/index.js +11 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/mcp/mcpServe.js +37 -1
- package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
- package/dist/esm/lib/trace-toolpack/traceToolpack.js +15 -1
- package/dist/esm/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/esm/memory/causal/writeSnapshot.d.ts +17 -4
- package/dist/esm/memory/causal/writeSnapshot.js +31 -27
- package/dist/esm/memory/causal/writeSnapshot.js.map +1 -1
- package/dist/esm/memory/define.js +4 -0
- package/dist/esm/memory/define.js.map +1 -1
- package/dist/esm/memory/define.types.d.ts +17 -0
- package/dist/esm/memory/define.types.js.map +1 -1
- package/dist/esm/memory/index.d.ts +1 -0
- package/dist/esm/memory/index.js +1 -0
- package/dist/esm/memory/index.js.map +1 -1
- package/dist/esm/memory/stages/types.d.ts +13 -3
- package/dist/esm/memory/turn/index.d.ts +7 -0
- package/dist/esm/memory/turn/index.js +11 -0
- package/dist/esm/memory/turn/index.js.map +1 -0
- package/dist/esm/memory/turn/resolveTurnNumber.d.ts +94 -0
- package/dist/esm/memory/turn/resolveTurnNumber.js +75 -0
- package/dist/esm/memory/turn/resolveTurnNumber.js.map +1 -0
- package/dist/events/registry.js +8 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/index.js +23 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/mcp/mcpServe.js +37 -1
- package/dist/lib/mcp/mcpServe.js.map +1 -1
- package/dist/lib/trace-toolpack/traceToolpack.js +15 -1
- package/dist/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/memory/causal/writeSnapshot.js +31 -27
- package/dist/memory/causal/writeSnapshot.js.map +1 -1
- package/dist/memory/define.js +4 -0
- package/dist/memory/define.js.map +1 -1
- package/dist/memory/define.types.js.map +1 -1
- package/dist/memory/index.js +1 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/memory/turn/index.js +16 -0
- package/dist/memory/turn/index.js.map +1 -0
- package/dist/memory/turn/resolveTurnNumber.js +81 -0
- package/dist/memory/turn/resolveTurnNumber.js.map +1 -0
- package/dist/types/adapters/code/agentcore.d.ts +134 -0
- package/dist/types/adapters/code/agentcore.d.ts.map +1 -0
- package/dist/types/adapters/code/local.d.ts +100 -0
- package/dist/types/adapters/code/local.d.ts.map +1 -0
- package/dist/types/adapters/llm/AnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BedrockProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BrowserAnthropicProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/BrowserOpenAIProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/OpenAIProvider.d.ts.map +1 -1
- package/dist/types/adapters/llm/contextWindow.d.ts +112 -0
- package/dist/types/adapters/llm/contextWindow.d.ts.map +1 -0
- package/dist/types/adapters/types.d.ts +87 -0
- package/dist/types/adapters/types.d.ts.map +1 -1
- package/dist/types/core/Agent.d.ts +65 -0
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/RunnerBase.d.ts +51 -0
- package/dist/types/core/RunnerBase.d.ts.map +1 -1
- package/dist/types/core/agent/stages/seed.d.ts +12 -0
- package/dist/types/core/agent/stages/seed.d.ts.map +1 -1
- package/dist/types/core/agent/stages/toolCalls.d.ts +31 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +23 -2
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/codeRunnerTool.d.ts +121 -0
- package/dist/types/core/codeRunnerTool.d.ts.map +1 -0
- package/dist/types/core/runCheckpoint.d.ts +25 -0
- package/dist/types/core/runCheckpoint.d.ts.map +1 -1
- package/dist/types/core/toolSessions.d.ts +319 -0
- package/dist/types/core/toolSessions.d.ts.map +1 -0
- package/dist/types/core/tools.d.ts +60 -0
- package/dist/types/core/tools.d.ts.map +1 -1
- package/dist/types/doors/providers.d.ts +7 -0
- package/dist/types/doors/providers.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +50 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +9 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
- package/dist/types/lib/trace-toolpack/traceToolpack.d.ts.map +1 -1
- package/dist/types/memory/causal/writeSnapshot.d.ts +17 -4
- package/dist/types/memory/causal/writeSnapshot.d.ts.map +1 -1
- package/dist/types/memory/define.d.ts.map +1 -1
- package/dist/types/memory/define.types.d.ts +17 -0
- package/dist/types/memory/define.types.d.ts.map +1 -1
- package/dist/types/memory/index.d.ts +1 -0
- package/dist/types/memory/index.d.ts.map +1 -1
- package/dist/types/memory/stages/types.d.ts +13 -3
- package/dist/types/memory/stages/types.d.ts.map +1 -1
- package/dist/types/memory/turn/index.d.ts +8 -0
- package/dist/types/memory/turn/index.d.ts.map +1 -0
- package/dist/types/memory/turn/resolveTurnNumber.d.ts +95 -0
- package/dist/types/memory/turn/resolveTurnNumber.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ContextWindowExceededError — "the request did not fit" as a typed error
|
|
3
|
+
* that names the fixes (9.6.0).
|
|
4
|
+
*
|
|
5
|
+
* Every vendor refuses an over-long request in its own words, and until now
|
|
6
|
+
* every one of them reached the caller as an opaque provider error:
|
|
7
|
+
*
|
|
8
|
+
* [openai] 400 Input tokens exceed the configured limit of 272000 tokens.
|
|
9
|
+
* Your messages resulted in 879073 tokens.
|
|
10
|
+
*
|
|
11
|
+
* That is the message a production field deployment spent a day on. It is a
|
|
12
|
+
* true sentence and a useless one: it does not say which of the framework's
|
|
13
|
+
* dials moves that number, and it looks exactly like a transient 400 — so the
|
|
14
|
+
* natural next move is to retry, which re-sends the same oversized history and
|
|
15
|
+
* fails identically, forever.
|
|
16
|
+
*
|
|
17
|
+
* So the adapters translate it, ONCE, into an error whose message contains the
|
|
18
|
+
* three fixes in the order they are worth trying, and which carries the two
|
|
19
|
+
* numbers (limit, actual) when the vendor stated them.
|
|
20
|
+
*
|
|
21
|
+
* **Detection is deliberately conservative.** Only unmistakable phrases and
|
|
22
|
+
* vendor codes translate; everything else passes through untouched as the
|
|
23
|
+
* provider error it always was. In particular a RATE limit ("rate limit
|
|
24
|
+
* reached … tokens per min") is a different failure with a different fix and
|
|
25
|
+
* must never land here — which is why no pattern matches on "too many tokens".
|
|
26
|
+
*
|
|
27
|
+
* @see ../../core/runCheckpoint.ts where this class makes `resumeOnError`
|
|
28
|
+
* stop advertising a resume that cannot work
|
|
29
|
+
*/
|
|
30
|
+
/** Discriminator carried on the error — stable across releases. */
|
|
31
|
+
export const ERR_CONTEXT_WINDOW_EXCEEDED = 'ERR_CONTEXT_WINDOW_EXCEEDED';
|
|
32
|
+
/**
|
|
33
|
+
* Thrown by an LLM adapter when the provider refused the request because the
|
|
34
|
+
* prompt did not fit the model's context window.
|
|
35
|
+
*
|
|
36
|
+
* A refusal, not a failure of the model: nothing was generated and nothing was
|
|
37
|
+
* charged for output. Retrying the identical request is deterministic — it
|
|
38
|
+
* fails the same way — so this is one of the classes
|
|
39
|
+
* {@link canResume} reports as not resumable.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { ContextWindowExceededError } from 'agentfootprint';
|
|
44
|
+
*
|
|
45
|
+
* try {
|
|
46
|
+
* await agent.run({ message: 'summarise the fabric inventory' });
|
|
47
|
+
* } catch (err) {
|
|
48
|
+
* if (err instanceof ContextWindowExceededError) {
|
|
49
|
+
* console.error(`sent ${err.actualTokens} against ${err.limitTokens}`);
|
|
50
|
+
* // …cap the tool result, or add .window(slidingWindow({ keepRecentTurns: 2 }))
|
|
51
|
+
* }
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export class ContextWindowExceededError extends Error {
|
|
56
|
+
code = ERR_CONTEXT_WINDOW_EXCEEDED;
|
|
57
|
+
/** Which adapter refused — `'openai'`, `'anthropic'`, `'bedrock'`, … */
|
|
58
|
+
provider;
|
|
59
|
+
/** The model's (or gateway's) ceiling in tokens, when the vendor said it. */
|
|
60
|
+
limitTokens;
|
|
61
|
+
/** What the request actually came to in tokens, when the vendor said it. */
|
|
62
|
+
actualTokens;
|
|
63
|
+
/** HTTP status, when there was one. Kept so retry policies still see a 4xx. */
|
|
64
|
+
status;
|
|
65
|
+
/** The provider's own error, unchanged. */
|
|
66
|
+
cause;
|
|
67
|
+
constructor(args) {
|
|
68
|
+
super(buildMessage(args));
|
|
69
|
+
this.name = 'ContextWindowExceededError';
|
|
70
|
+
this.provider = args.provider;
|
|
71
|
+
if (args.limitTokens !== undefined)
|
|
72
|
+
this.limitTokens = args.limitTokens;
|
|
73
|
+
if (args.actualTokens !== undefined)
|
|
74
|
+
this.actualTokens = args.actualTokens;
|
|
75
|
+
if (args.status !== undefined)
|
|
76
|
+
this.status = args.status;
|
|
77
|
+
if (args.cause !== undefined)
|
|
78
|
+
this.cause = args.cause;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** `true` for the typed error, including across a `structuredClone`-free
|
|
82
|
+
* boundary where `instanceof` still holds. Kept as a function so callers do
|
|
83
|
+
* not have to import the class to ask the question. */
|
|
84
|
+
export function isContextWindowExceeded(err) {
|
|
85
|
+
return (err instanceof ContextWindowExceededError ||
|
|
86
|
+
(err instanceof Error && err.code === ERR_CONTEXT_WINDOW_EXCEEDED));
|
|
87
|
+
}
|
|
88
|
+
// ─── Detection ───────────────────────────────────────────────────────
|
|
89
|
+
/**
|
|
90
|
+
* The phrases that mean "your request was too big for the context window",
|
|
91
|
+
* as the four shipped wire vendors actually word them. Every one of these is
|
|
92
|
+
* unambiguous on its own — which is the bar for being on this list, because a
|
|
93
|
+
* pattern that also matches a rate limit or a `max_tokens` validation error
|
|
94
|
+
* would send callers to the wrong fix.
|
|
95
|
+
*
|
|
96
|
+
* openai This model's maximum context length is 8192 tokens. However,
|
|
97
|
+
* your messages resulted in 9000 tokens.
|
|
98
|
+
* openai (code) context_length_exceeded
|
|
99
|
+
* gateways Input tokens exceed the configured limit of 272000 tokens.
|
|
100
|
+
* Your messages resulted in 879073 tokens.
|
|
101
|
+
* anthropic prompt is too long: 250000 tokens > 200000 maximum
|
|
102
|
+
* anthropic input length and `max_tokens` exceed context limit:
|
|
103
|
+
* 195000 + 8192 > 200000
|
|
104
|
+
* bedrock Input is too long for requested model.
|
|
105
|
+
* bedrock (ValidationException carrying either anthropic phrase)
|
|
106
|
+
*/
|
|
107
|
+
const CONTEXT_PHRASES = [
|
|
108
|
+
/context_length_exceeded/i,
|
|
109
|
+
/maximum context length/i,
|
|
110
|
+
/prompt is too long/i,
|
|
111
|
+
/exceed(?:s)? context limit/i,
|
|
112
|
+
/input (?:is )?too long for (?:the )?requested model/i,
|
|
113
|
+
/input tokens exceed the configured limit/i,
|
|
114
|
+
// "input tokens" spelled out on purpose. A gateway saying "exceeds the
|
|
115
|
+
// maximum allowed number of tokens" with no side named could equally be an
|
|
116
|
+
// OUTPUT `max_tokens` cap, which has a different fix — and a pattern that
|
|
117
|
+
// cannot tell those apart sends callers to the wrong one.
|
|
118
|
+
/exceeds? the maximum (?:allowed )?(?:number of )?input tokens/i,
|
|
119
|
+
];
|
|
120
|
+
/** `"272,000"` → `272000`; anything unparseable → undefined. */
|
|
121
|
+
function num(raw) {
|
|
122
|
+
if (raw === undefined)
|
|
123
|
+
return undefined;
|
|
124
|
+
const value = Number(raw.replace(/[,_\s]/g, ''));
|
|
125
|
+
return Number.isFinite(value) && value > 0 ? value : undefined;
|
|
126
|
+
}
|
|
127
|
+
/** Pull `{ limit, actual }` out of the vendor's sentence when it stated them. */
|
|
128
|
+
function readNumbers(text) {
|
|
129
|
+
// anthropic: "prompt is too long: 250000 tokens > 200000 maximum"
|
|
130
|
+
const tooLong = /prompt is too long:\s*([\d,_]+)\s*tokens?\s*>\s*([\d,_]+)/i.exec(text);
|
|
131
|
+
if (tooLong) {
|
|
132
|
+
return { actualTokens: num(tooLong[1]), limitTokens: num(tooLong[2]) };
|
|
133
|
+
}
|
|
134
|
+
// anthropic / bedrock: "input length and `max_tokens` exceed context limit:
|
|
135
|
+
// 195000 + 8192 > 200000"
|
|
136
|
+
const sum = /exceed(?:s)? context limit:\s*([\d,_]+)\s*\+\s*([\d,_]+)\s*>\s*([\d,_]+)/i.exec(text);
|
|
137
|
+
if (sum) {
|
|
138
|
+
const input = num(sum[1]);
|
|
139
|
+
const output = num(sum[2]);
|
|
140
|
+
return {
|
|
141
|
+
...(input !== undefined && output !== undefined && { actualTokens: input + output }),
|
|
142
|
+
...(num(sum[3]) !== undefined && { limitTokens: num(sum[3]) }),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const limit = num(/maximum context length is\s*([\d,_]+)/i.exec(text)?.[1]) ??
|
|
146
|
+
num(/configured limit of\s*([\d,_]+)/i.exec(text)?.[1]) ??
|
|
147
|
+
num(/limit of\s*([\d,_]+)\s*tokens/i.exec(text)?.[1]);
|
|
148
|
+
const actual = num(/resulted in\s*([\d,_]+)\s*tokens/i.exec(text)?.[1]) ??
|
|
149
|
+
num(/requested\s*([\d,_]+)\s*tokens/i.exec(text)?.[1]) ??
|
|
150
|
+
num(/you (?:sent|submitted|provided)\s*([\d,_]+)\s*tokens/i.exec(text)?.[1]);
|
|
151
|
+
return {
|
|
152
|
+
...(limit !== undefined && { limitTokens: limit }),
|
|
153
|
+
...(actual !== undefined && { actualTokens: actual }),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/** Every place a vendor hides its sentence, flattened into one string. */
|
|
157
|
+
function textOf(err, extraText) {
|
|
158
|
+
const parts = [];
|
|
159
|
+
if (typeof extraText === 'string')
|
|
160
|
+
parts.push(extraText);
|
|
161
|
+
const seen = new Set();
|
|
162
|
+
let node = err;
|
|
163
|
+
for (let depth = 0; depth < 4 && node !== undefined && node !== null; depth++) {
|
|
164
|
+
if (seen.has(node))
|
|
165
|
+
break;
|
|
166
|
+
seen.add(node);
|
|
167
|
+
const record = node;
|
|
168
|
+
for (const value of [record.message, record.code, record.type, record.name]) {
|
|
169
|
+
if (typeof value === 'string')
|
|
170
|
+
parts.push(value);
|
|
171
|
+
}
|
|
172
|
+
node = record.error ?? record.cause;
|
|
173
|
+
}
|
|
174
|
+
return parts.join(' • ');
|
|
175
|
+
}
|
|
176
|
+
/** HTTP status from wherever the SDK put it. */
|
|
177
|
+
function statusOf(err) {
|
|
178
|
+
const record = err;
|
|
179
|
+
for (const value of [
|
|
180
|
+
record?.status,
|
|
181
|
+
record?.statusCode,
|
|
182
|
+
record?.$metadata?.httpStatusCode,
|
|
183
|
+
record?.response?.status,
|
|
184
|
+
]) {
|
|
185
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
186
|
+
return value;
|
|
187
|
+
}
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Does this error SAY it is a context overflow, whoever produced it?
|
|
192
|
+
*
|
|
193
|
+
* The same conservative phrase test the adapters translate on, asked without
|
|
194
|
+
* building anything — for code that has to classify an error it did not
|
|
195
|
+
* catch at an adapter boundary. A custom `LLMProvider`, a gateway wrapper or
|
|
196
|
+
* a proxy in front of a vendor produces the vendor's sentence without ever
|
|
197
|
+
* passing through `wrapError`, and a caller reading that error deserves the
|
|
198
|
+
* same answer an adapter would have given.
|
|
199
|
+
*
|
|
200
|
+
* @see ../../core/runCheckpoint.ts — the caller this exists for
|
|
201
|
+
*/
|
|
202
|
+
export function looksLikeContextWindowExceeded(err, bodyText) {
|
|
203
|
+
if (isContextWindowExceeded(err))
|
|
204
|
+
return true;
|
|
205
|
+
const text = textOf(err, bodyText);
|
|
206
|
+
return text.length > 0 && CONTEXT_PHRASES.some((pattern) => pattern.test(text));
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Translate a provider error into {@link ContextWindowExceededError} — or
|
|
210
|
+
* return `undefined`, which means "not this failure, leave it alone".
|
|
211
|
+
*
|
|
212
|
+
* Already-translated errors are returned as they are, so an adapter that
|
|
213
|
+
* wraps another adapter cannot double-wrap.
|
|
214
|
+
*/
|
|
215
|
+
export function asContextWindowExceeded(err, options) {
|
|
216
|
+
if (isContextWindowExceeded(err))
|
|
217
|
+
return err;
|
|
218
|
+
if (!looksLikeContextWindowExceeded(err, options.bodyText))
|
|
219
|
+
return undefined;
|
|
220
|
+
const text = textOf(err, options.bodyText);
|
|
221
|
+
const numbers = readNumbers(text);
|
|
222
|
+
// The status the SDK attached, else the one the adapter read off the
|
|
223
|
+
// response, else a leading `400` the vendor put in the message itself
|
|
224
|
+
// (several gateways do). Kept because retry policies classify on it, and a
|
|
225
|
+
// context overflow must never look retryable.
|
|
226
|
+
const status = statusOf(err) ?? options.status ?? num(/^\s*(4\d\d)\b/.exec(messageOf(err))?.[1]);
|
|
227
|
+
return new ContextWindowExceededError({
|
|
228
|
+
provider: options.provider,
|
|
229
|
+
providerMessage: messageOf(err) || options.bodyText || text,
|
|
230
|
+
...numbers,
|
|
231
|
+
...(status !== undefined && { status }),
|
|
232
|
+
...(err instanceof Error && { cause: err }),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
function messageOf(err) {
|
|
236
|
+
if (err instanceof Error)
|
|
237
|
+
return err.message;
|
|
238
|
+
if (typeof err === 'string')
|
|
239
|
+
return err;
|
|
240
|
+
return '';
|
|
241
|
+
}
|
|
242
|
+
// ─── The message ─────────────────────────────────────────────────────
|
|
243
|
+
function tokens(value) {
|
|
244
|
+
return value === undefined ? undefined : `${value.toLocaleString('en-US')} tokens`;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* The teaching half. Three fixes, cheapest first, and the one thing about
|
|
248
|
+
* `.compaction()` that is not obvious until it fails: folding a span means
|
|
249
|
+
* SENDING that span to the summarizer, so compaction cannot rescue a single
|
|
250
|
+
* round that is already bigger than the window.
|
|
251
|
+
*/
|
|
252
|
+
function buildMessage(args) {
|
|
253
|
+
const sent = tokens(args.actualTokens);
|
|
254
|
+
const limit = tokens(args.limitTokens);
|
|
255
|
+
const size = sent && limit
|
|
256
|
+
? ` — ${sent} sent against a limit of ${limit}`
|
|
257
|
+
: limit
|
|
258
|
+
? ` — the limit is ${limit}`
|
|
259
|
+
: sent
|
|
260
|
+
? ` — the request came to ${sent}`
|
|
261
|
+
: '';
|
|
262
|
+
return (`[${args.provider}] the request did not fit the context window${size}. ` +
|
|
263
|
+
`The provider refused it before the model saw it, so nothing was generated ` +
|
|
264
|
+
`and re-sending the same conversation fails the same way.\n` +
|
|
265
|
+
` Fix 1 — cap oversized TOOL RESULTS where they are produced. One raw ` +
|
|
266
|
+
`database dump returned to the model is the usual whole overrun: return a ` +
|
|
267
|
+
`summary plus an id the model can ask about, not every row.\n` +
|
|
268
|
+
` Fix 2 — .window(slidingWindow({ keepRecentTurns: 2 })) drops older ` +
|
|
269
|
+
`rounds before the request is assembled, so the conversation stops growing ` +
|
|
270
|
+
`without bound.\n` +
|
|
271
|
+
` Fix 3 — .compaction() keeps a LONG conversation small, but it cannot ` +
|
|
272
|
+
`fold a span that is already bigger than the window: the summarizer call ` +
|
|
273
|
+
`sends that span, so it fails exactly as this call did. Fix the oversized ` +
|
|
274
|
+
`round first, then compact.\n` +
|
|
275
|
+
` Provider said: ${args.providerMessage}`);
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=contextWindow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contextWindow.js","sourceRoot":"","sources":["../../../../src/adapters/llm/contextWindow.ts"],"names":[],"mappings":"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"}
|
|
@@ -584,3 +584,90 @@ export interface PricingTable {
|
|
|
584
584
|
/** USD per ONE token for the given model+kind. */
|
|
585
585
|
pricePerToken(model: string, kind: TokenKind): number;
|
|
586
586
|
}
|
|
587
|
+
/**
|
|
588
|
+
* A service that runs code in an isolated session — a managed code
|
|
589
|
+
* interpreter, a container pool, a subprocess.
|
|
590
|
+
*
|
|
591
|
+
* **The shape is Start → Execute ×N → Stop**, because that is what every real
|
|
592
|
+
* one is, and the middle is the part a framework has to make possible. Paying
|
|
593
|
+
* session start-up on every call is the honest cheap version; holding the
|
|
594
|
+
* session in a module-level map is the fast version that hands one live sandbox
|
|
595
|
+
* to whoever calls next. `ctx.onTeardown` + {@link ToolExecutionContext.runId}
|
|
596
|
+
* are what let a tool do neither.
|
|
597
|
+
*
|
|
598
|
+
* ── Why this port exists at all: "summarize prose, compute data" ────────────
|
|
599
|
+
* A tool that returns 40MB of rows does not need a bigger context window; it
|
|
600
|
+
* needs to not put the rows in one. The motivating failure is a real production
|
|
601
|
+
* request of 879,073 tokens — a tool result pasted straight into the prompt.
|
|
602
|
+
* With a code runner, the model writes the aggregation, the RUNNER holds the
|
|
603
|
+
* data, and what comes back is the answer. Prose gets summarized; data gets
|
|
604
|
+
* computed. `CodeResult.truncated` exists so the second half of that promise
|
|
605
|
+
* cannot quietly break.
|
|
606
|
+
*
|
|
607
|
+
* Implement it for your own backend; ship it to `codeRunnerTool({ runner })`.
|
|
608
|
+
*/
|
|
609
|
+
export interface CodeRunner {
|
|
610
|
+
/** Stable id — reported on every `agentfootprint.tools.session_*` event so a
|
|
611
|
+
* row names its backend, not just its tool. */
|
|
612
|
+
readonly id: string;
|
|
613
|
+
/**
|
|
614
|
+
* Open a session.
|
|
615
|
+
*
|
|
616
|
+
* `key` is the ISOLATION key the caller derived (see `toolSessionKey`). An
|
|
617
|
+
* adapter may use it to name the remote session; it must never widen it.
|
|
618
|
+
*/
|
|
619
|
+
start(req: {
|
|
620
|
+
readonly key: string;
|
|
621
|
+
readonly language?: string;
|
|
622
|
+
readonly signal?: AbortSignal;
|
|
623
|
+
}): Promise<CodeSession>;
|
|
624
|
+
}
|
|
625
|
+
/** One live session. `stop()` is idempotent and tolerates "already gone". */
|
|
626
|
+
export interface CodeSession {
|
|
627
|
+
/** The backend's own id for this session, when it has one. */
|
|
628
|
+
readonly id: string;
|
|
629
|
+
execute(req: {
|
|
630
|
+
readonly code: string;
|
|
631
|
+
readonly language?: string;
|
|
632
|
+
readonly timeoutMs?: number;
|
|
633
|
+
readonly signal?: AbortSignal;
|
|
634
|
+
}): Promise<CodeResult>;
|
|
635
|
+
/**
|
|
636
|
+
* Release the session.
|
|
637
|
+
*
|
|
638
|
+
* Must tolerate a session the far side already reaped — an idle timeout is
|
|
639
|
+
* the reality on every managed backend, and a `Stop` on a dead session is a
|
|
640
|
+
* no-op, not an error.
|
|
641
|
+
*/
|
|
642
|
+
stop(): Promise<void>;
|
|
643
|
+
}
|
|
644
|
+
/** What one execution produced. */
|
|
645
|
+
export interface CodeResult {
|
|
646
|
+
/** Did the code run to completion without an error exit? */
|
|
647
|
+
readonly ok: boolean;
|
|
648
|
+
readonly stdout: string;
|
|
649
|
+
readonly stderr: string;
|
|
650
|
+
readonly exitCode?: number;
|
|
651
|
+
/** Files the run produced, described rather than inlined — the whole point is
|
|
652
|
+
* that big data does not enter the window. */
|
|
653
|
+
readonly artifacts?: readonly {
|
|
654
|
+
readonly name: string;
|
|
655
|
+
readonly bytes: number;
|
|
656
|
+
readonly uri?: string;
|
|
657
|
+
}[];
|
|
658
|
+
/**
|
|
659
|
+
* Present IFF output was cut, and then it says by how much.
|
|
660
|
+
*
|
|
661
|
+
* Load-bearing, not politeness. A runner exists so big data is computed
|
|
662
|
+
* outside the context window instead of pasted into it; a runner that
|
|
663
|
+
* quietly slices its own output to fit is the same bug wearing a different
|
|
664
|
+
* hat, and the model would go on to reason over a truncated table it was
|
|
665
|
+
* never told was truncated. An unstated slice is a silent success.
|
|
666
|
+
*/
|
|
667
|
+
readonly truncated?: {
|
|
668
|
+
readonly stdout?: boolean;
|
|
669
|
+
readonly stderr?: boolean;
|
|
670
|
+
/** The pre-truncation length, in characters, of whichever stream was cut. */
|
|
671
|
+
readonly ofChars?: number;
|
|
672
|
+
};
|
|
673
|
+
}
|
package/dist/esm/core/Agent.d.ts
CHANGED
|
@@ -286,6 +286,9 @@ export declare class Agent extends RunnerBase<AgentInput, AgentOutput> {
|
|
|
286
286
|
* default is derived from a runId, and storing that would pin a whole
|
|
287
287
|
* conversation to the id of the one run that started it. */
|
|
288
288
|
private lastRunIdentity?;
|
|
289
|
+
/** How long ONE tool teardown may take before the runner stops waiting.
|
|
290
|
+
* See `AgentOptions.toolTeardownTimeoutMs`. */
|
|
291
|
+
private readonly toolTeardownTimeoutMs;
|
|
289
292
|
/** The run in flight, by id — the whole of the one-turn-at-a-time guard.
|
|
290
293
|
* Set before the executor is built and cleared in `finally`, so a run that
|
|
291
294
|
* throws does not leave the agent permanently refusing. */
|
|
@@ -611,6 +614,29 @@ export declare class Agent extends RunnerBase<AgentInput, AgentOutput> {
|
|
|
611
614
|
*/
|
|
612
615
|
private installCheckpointTracker;
|
|
613
616
|
resume(checkpoint: FlowchartCheckpoint, input?: unknown, options?: AgentRunOptions): Promise<AgentOutput | RunnerPauseOutcome>;
|
|
617
|
+
/**
|
|
618
|
+
* Fire `'run'`-scoped tool teardown — IF this run really ended.
|
|
619
|
+
*
|
|
620
|
+
* **Not on `finally`, and that is the whole point.** `finally` runs on every
|
|
621
|
+
* exit including a pause, and a pause exits TWO ways: a returned
|
|
622
|
+
* `RunnerPauseOutcome` and a thrown `PauseSignal`. A check-in on a
|
|
623
|
+
* code-interpreter call pauses the run so a person can approve the code —
|
|
624
|
+
* tearing the sandbox down there destroys the exact state the resume needs,
|
|
625
|
+
* and it fails QUIETLY, as a resumed run that "just re-ran everything".
|
|
626
|
+
* Both shapes are discriminated here and both are skipped.
|
|
627
|
+
*
|
|
628
|
+
* An error IS a terminal: the run is over, nobody is coming back, and a
|
|
629
|
+
* sandbox held by a run that crashed is the clearest kind of leak. Only a
|
|
630
|
+
* pause survives.
|
|
631
|
+
*
|
|
632
|
+
* Fired for the TURN, not for `currentRunContext.runId` — `resume()` mints a
|
|
633
|
+
* fresh run id, so a pause and its resume are one turn across two runs, and
|
|
634
|
+
* filtering on the id would leave everything a paused turn opened alive
|
|
635
|
+
* forever. See `ToolSessionTier.fireRun`.
|
|
636
|
+
*
|
|
637
|
+
* @param outcome what `run()`/`resume()` is about to return, or about to throw.
|
|
638
|
+
*/
|
|
639
|
+
private endRunToolSessions;
|
|
614
640
|
/**
|
|
615
641
|
* The conversation this agent's LAST completed run leaves behind, packed as
|
|
616
642
|
* the same `AgentRunCheckpoint` that `resumeOnError(...)` accepts. Store it,
|
|
@@ -761,6 +787,45 @@ export declare class Agent extends RunnerBase<AgentInput, AgentOutput> {
|
|
|
761
787
|
* An open pick ACTIVATES but never moves the cursor — see the tool-calls gate.
|
|
762
788
|
* Computed once per chart build; the injection list is fixed at construction.
|
|
763
789
|
*/
|
|
790
|
+
/**
|
|
791
|
+
* The identity facts this run hands `tool.execute` (9.7.0).
|
|
792
|
+
*
|
|
793
|
+
* Read through an ACCESSOR from the chart (see `ToolCallsHandlerDeps.currentRun`)
|
|
794
|
+
* because the chart is built once and this changes every run.
|
|
795
|
+
*
|
|
796
|
+
* `identity` is `lastRunIdentity` — what the CALLER passed — and deliberately
|
|
797
|
+
* NOT `scope.runIdentity`, which is always populated and defaults to
|
|
798
|
+
* `{ conversationId: '<runId>' }`. Handing a tool a synthesized conversation
|
|
799
|
+
* as "the identity" would let it key an isolated session on a fiction, and
|
|
800
|
+
* would make "absent" unrepresentable at exactly the layer that most needs to
|
|
801
|
+
* see it.
|
|
802
|
+
*/
|
|
803
|
+
private toolRunFacts;
|
|
804
|
+
/**
|
|
805
|
+
* The teardown tier, built on FIRST registration.
|
|
806
|
+
*
|
|
807
|
+
* An agent whose tools never hold a session never allocates one, and its
|
|
808
|
+
* terminals stay a single `undefined` check.
|
|
809
|
+
*/
|
|
810
|
+
private toolSessions;
|
|
811
|
+
/**
|
|
812
|
+
* Turn one TEARDOWN report into a typed `agentfootprint.tools.session_*` event.
|
|
813
|
+
*
|
|
814
|
+
* Only the two closing events come through here. A start and a reuse happen
|
|
815
|
+
* inside `tool.execute`, where the dispatch loop still holds the scope, so
|
|
816
|
+
* those ride the ordinary emit channel and carry the stage they really
|
|
817
|
+
* happened in. These two fire after the run's last stage committed, and this
|
|
818
|
+
* is the one place that has to answer "from where?" without a stage to point
|
|
819
|
+
* at.
|
|
820
|
+
*
|
|
821
|
+
* **Built with `buildEventMeta`, never `minimalMeta()`.** `minimalMeta()`
|
|
822
|
+
* hardcodes `runId: 'consumer-scope'`, and a teardown event stamped that way
|
|
823
|
+
* cannot be joined to the run that OPENED the session — the exact
|
|
824
|
+
* unjoinability 9.4.0 spent a release fixing for credential events. So the
|
|
825
|
+
* meta comes from `currentRunContext`, with a STATED pseudo-stage, the same
|
|
826
|
+
* move as the `'<stageId>#paused'` stamp at the pause boundary.
|
|
827
|
+
*/
|
|
828
|
+
private emitToolSessionReport;
|
|
764
829
|
private openSkillIds;
|
|
765
830
|
/**
|
|
766
831
|
* The per-iteration `read_skill` offer builder — or `undefined` to leave the tool
|