agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
61 lines • 2.63 kB
JavaScript
;
/**
* retryAfter — the wait a vendor's response headers state, for an adapter to
* DECLARE on the error it raises (`retryAfterMs`).
*
* Pattern: pure reader (no I/O). Role: outer ring, below the adapters.
*
* `withRetry` never reads headers or prose — it reads the declared field
* (resilience/statedWait.ts · statedRetryAfterMs). Each adapter knows its own
* wire, so the reading happens here, once, for every adapter that can see
* headers:
*
* - `retry-after-ms` — milliseconds, sent by the Anthropic and OpenAI APIs
* (their own SDKs read it first too);
* - `retry-after` — the standard header, delta-seconds or an HTTP-date
* (mcp/throttleRetry.ts · parseRetryAfter, the one parser of it).
*
* Headers arrive as a fetch `Headers` (anything with `get`) or a plain record
* (older SDKs, the AWS SDK's `$response.headers`); both are read
* case-insensitively. Anything unreadable is absent, never a guess.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.retryAfterMsFromError = exports.retryAfterMsFromHeaders = void 0;
const throttleRetry_js_1 = require("../../mcp/throttleRetry.js");
/** The stated wait in ms, or `undefined` when the headers state none. */
function retryAfterMsFromHeaders(headers) {
const ms = headerValue(headers, 'retry-after-ms');
if (ms !== undefined) {
const value = Number(ms.trim());
if (ms.trim() !== '' && Number.isFinite(value) && value >= 0)
return value;
}
return (0, throttleRetry_js_1.parseRetryAfter)(headerValue(headers, 'retry-after'));
}
exports.retryAfterMsFromHeaders = retryAfterMsFromHeaders;
/**
* The same wait read off an SDK error: `err.headers` (Anthropic and OpenAI SDK
* `APIError`) or `err.$response.headers` (AWS SDK v3 exceptions).
*/
function retryAfterMsFromError(err) {
if (err === null || typeof err !== 'object')
return undefined;
const e = err;
return retryAfterMsFromHeaders(e.headers) ?? retryAfterMsFromHeaders(e.$response?.headers);
}
exports.retryAfterMsFromError = retryAfterMsFromError;
function headerValue(headers, name) {
if (headers === null || typeof headers !== 'object')
return undefined;
const getter = headers.get;
if (typeof getter === 'function') {
const value = getter.call(headers, name);
return typeof value === 'string' ? value : undefined;
}
for (const [key, value] of Object.entries(headers)) {
if (key.toLowerCase() === name && typeof value === 'string')
return value;
}
return undefined;
}
//# sourceMappingURL=retryAfter.js.map