UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

98 lines (97 loc) • 5.94 kB
/** * sessionBusy — the retry strategy: AgentCore Runtime's "session operation in * progress", recognised. One small function, on purpose. * * ── What the service says, in its own words ────────────────────────────────── * The AgentCore Runtime MCP protocol contract maps the runtime's exceptions onto * JSON-RPC errors, and exactly one of them is retryable by design: * * -32005 RetryableConflictException HTTP 200 "Session operation in progress, please retry" * * returned "when a second operation targets a session while the service is * provisioning or tearing down that session. Because MCP returns HTTP 200 with * the error in the JSON-RPC body, the caller must inspect the response body and * retry with short exponential backoff — MCP clients do not auto-retry it." * * So no status code says it, and the MCP SDK will not wait for it: left alone, * it reaches the model as a failed tool call, a moment after the session it was * waiting for came up. * * ── What asking again relies on ────────────────────────────────────────────── * AWS's contract returns this refusal while the service is provisioning or * tearing down the session: the PLATFORM's answer, about the session, not the * MCP server's. The retry series relies on that, as it relies on a 429 being a * rejection before execution: an assumption with a basis, not proof that * nothing ran (see `mcp/throttleRetry.ts` · `RetryDecision`). The adapter * retries it as its OWN policy ({@link SESSION_BUSY_ASSUMES}): each repeat * records that assumption (`permission: { by: 'adapter', assumes }`), and every * attempt's effect stays `unknown` (`mcp/replay.ts`). * * ── The known limit ────────────────────────────────────────────────────────── * The HTTP 200 form is matched by its code and message, so a server behind the * runtime can raise the same error itself — after it ran the call — and the * match cannot tell the two apart. Neither AWS page says a matching body ran * nothing. That is why the record never says so; the 409 form carries the * platform's own `x-amzn-errortype`. * * ── What it must NOT match ─────────────────────────────────────────────────── * `ConflictException` shares the code -32005 ("Resource conflict - Resource * already exists") and is not retryable; the contract tells the two apart only * by the message, so the message is part of the match. Anything else — another * status, an SSE stream, a batch reply, a body that is not JSON — is delivered * as it is. * * ── The API-layer form ─────────────────────────────────────────────────────── * `InvokeAgentRuntime`'s API reference gives the same exception as an HTTP 409, * its type in the `x-amzn-errortype` header (the REST protocol's error-type * header; the SigV4 strategy rebuilds exactly that from the SDK's exception, * because the transport's SDK client has its own retry off). It is the same * refusal, so it is the same decision — matched by the type, never by the 409 * alone. * * Pattern: Strategy (a `RetryDecision`). Role: outer ring, vendor fact. */ import type { RetryVerdict } from '../../../mcp/throttleRetry.js'; /** * What the adapter assumes in retrying this refusal as its own policy: that * the platform refused the request before running it. Attached to the * session-busy retry rule (`transport.ts`) and recorded beside each repeat — * an assumption, never evidence. */ export declare const SESSION_BUSY_ASSUMES: "refused-before-execution"; /** * Where AgentCore documents the refusal this file recognises, in both forms — * the basis of the adapter's retry policy. Neither page says that a matching * reply ran nothing, so the record never does: * * 1. The AgentCore Runtime MCP protocol contract, "Error handling": the row * `-32005 · RetryableConflictException · HTTP 200 · "Session operation in * progress, please retry"`, returned "when a second operation targets a * session while the service is provisioning or tearing down that session". * 2. The `InvokeAgentRuntime` API reference, "Errors": * `RetryableConflictException`, HTTP 409 — "a temporary condition that may * resolve itself with retries". */ export declare const SESSION_BUSY_DOCUMENTATION: readonly string[]; /** The JSON-RPC error code the contract gives `RetryableConflictException`. */ export declare const SESSION_BUSY_CODE = -32005; /** * Is this response AgentCore Runtime's session-busy refusal — in either form: * the MCP contract's HTTP 200 with JSON-RPC -32005, or the API's 409 * `RetryableConflictException`? * * Reads a CLONE of the body, so the response is delivered intact either way. * Answers `{}` (wait the loop's own backoff, then send the same request again) * or `undefined` (deliver it). * * `signal` is the request's: when it fires mid-read (the call's deadline, the * caller's cancellation), the clone's read is cancelled and released, and this * rejects with the abort — a stalled body never leaves a reader behind. */ export declare function sessionBusy(response: Response, signal?: AbortSignal): Promise<RetryVerdict | undefined>; /** * The match itself, over a parsed body: ONE JSON-RPC reply whose error carries * the contract's code and message. A batch is never retried whole — some of * its replies may be the record of work that ran. */ export declare function isSessionBusyReply(body: unknown): boolean;