/** * ContextWindowExceededError — "the request did not fit" as a typed error * that names the fixes (9.6.0). * * Every vendor refuses an over-long request in its own words, and until now * every one of them reached the caller as an opaque provider error: * * [openai] 400 Input tokens exceed the configured limit of 272000 tokens. * Your messages resulted in 879073 tokens. * * That is the message a production field deployment spent a day on. It is a * true sentence and a useless one: it does not say which of the framework's * dials moves that number, and it looks exactly like a transient 400 — so the * natural next move is to retry, which re-sends the same oversized history and * fails identically, forever. * * So the adapters translate it, ONCE, into an error whose message contains the * three fixes in the order they are worth trying, and which carries the two * numbers (limit, actual) when the vendor stated them. * * **Detection is deliberately conservative.** Only unmistakable phrases and * vendor codes translate; everything else passes through untouched as the * provider error it always was. In particular a RATE limit ("rate limit * reached … tokens per min") is a different failure with a different fix and * must never land here — which is why no pattern matches on "too many tokens". * * @see ../../core/runCheckpoint.ts where this class makes `resumeOnError` * stop advertising a resume that cannot work */ /** Discriminator carried on the error — stable across releases. */ export declare const ERR_CONTEXT_WINDOW_EXCEEDED: "ERR_CONTEXT_WINDOW_EXCEEDED"; /** * Thrown by an LLM adapter when the provider refused the request because the * prompt did not fit the model's context window. * * A refusal, not a failure of the model: nothing was generated and nothing was * charged for output. Retrying the identical request is deterministic — it * fails the same way — so this is one of the classes * {@link canResume} reports as not resumable. * * @example * ```ts * import { ContextWindowExceededError } from 'agentfootprint'; * * try { * await agent.run({ message: 'summarise the fabric inventory' }); * } catch (err) { * if (err instanceof ContextWindowExceededError) { * console.error(`sent ${err.actualTokens} against ${err.limitTokens}`); * // …cap the tool result, or add .window(slidingWindow({ keepRecentTurns: 2 })) * } * } * ``` */ export declare class ContextWindowExceededError extends Error { readonly code: "ERR_CONTEXT_WINDOW_EXCEEDED"; /** Which adapter refused — `'openai'`, `'anthropic'`, `'bedrock'`, … */ readonly provider: string; /** The model's (or gateway's) ceiling in tokens, when the vendor said it. */ readonly limitTokens?: number; /** What the request actually came to in tokens, when the vendor said it. */ readonly actualTokens?: number; /** HTTP status, when there was one. Kept so retry policies still see a 4xx. */ readonly status?: number; /** The provider's own error, unchanged. */ readonly cause?: Error; constructor(args: { provider: string; providerMessage: string; limitTokens?: number; actualTokens?: number; status?: number; cause?: Error; }); } /** `true` for the typed error, including across a `structuredClone`-free * boundary where `instanceof` still holds. Kept as a function so callers do * not have to import the class to ask the question. */ export declare function isContextWindowExceeded(err: unknown): err is ContextWindowExceededError; export interface ContextWindowTranslation { /** Which adapter is asking — appears in the message prefix. */ readonly provider: string; /** * Extra text to search — the HTTP body, for adapters that read the response * themselves instead of going through a vendor SDK. */ readonly bodyText?: string; /** Status the adapter already knows (browser adapters read it off `Response`). */ readonly status?: number; } /** * Does this error SAY it is a context overflow, whoever produced it? * * The same conservative phrase test the adapters translate on, asked without * building anything — for code that has to classify an error it did not * catch at an adapter boundary. A custom `LLMProvider`, a gateway wrapper or * a proxy in front of a vendor produces the vendor's sentence without ever * passing through `wrapError`, and a caller reading that error deserves the * same answer an adapter would have given. * * @see ../../core/runCheckpoint.ts — the caller this exists for */ export declare function looksLikeContextWindowExceeded(err: unknown, bodyText?: string): boolean; /** * Translate a provider error into {@link ContextWindowExceededError} — or * return `undefined`, which means "not this failure, leave it alone". * * Already-translated errors are returned as they are, so an adapter that * wraps another adapter cannot double-wrap. */ export declare function asContextWindowExceeded(err: unknown, options: ContextWindowTranslation): ContextWindowExceededError | undefined;