UNPKG

agentfootprint

Version:

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

82 lines • 4.45 kB
/** * backoff — builders of a `RetryPolicy.backoffMs` function: an exponential * schedule, and a wait the server stated winning over it. * * STAND-IN, TO BE DELETED. footprintjs is adding these two helpers to its * attempt runner (`attempt/backoff.ts`): `exponentialBackoff({ baseDelayMs, * multiplier, jitter, maxDelayMs, random })` and * `statedWaitFirst(readStatedWaitMs, inner)`, with these names, signatures and * laws. Once a footprintjs release * ships them, import them in `throttleRetry.ts` and delete this file; nothing * else changes. * * Pattern: Two pure builders. Each returns `(attempt, error?) => ms`. * Role: The wait `throttleRetry.ts` plans for each retry. * Emits: N/A. * * ── THE LAW ────────────────────────────────────────────────────────────── * `exponentialBackoff`: after failed attempt `n` (1-based) the ceiling is * * c = min(maxDelayMs, baseDelayMs × multiplier^(n − 1)) * (saturating at MAX_SAFE_INTEGER) * * and, for `r = random()` in [0, 1]: * * 'none' c `random` is never called * 'equal' min(c, c/2 + r × c/2) never below half the ceiling * 'full' r × c anywhere from 0 up to it * * Waits are exact milliseconds — nothing is rounded. `random` defaults to * `Math.random`, taken when the function is BUILT; a fixed source makes a test * exact. A `random()` answering outside [0, 1] throws when asked. * * `statedWaitFirst`: when `readStatedWaitMs(error)` answers a finite number * ≥ 0, that is the wait; otherwise `inner` decides. A reader that throws or * answers anything else states nothing, so a malformed `Retry-After` falls back * to the schedule rather than to a wrong wait. * * `maxDelayMs` caps the CEILING, before the draw, so capped waits keep their * jitter: at the cap, equal jitter still spreads between c/2 and c. Capped * after the draw instead, every wait past twice the cap would BE the cap, and * clients refused together would retry in lockstep. A stated wait is never * capped: `statedWaitFirst` hands it back whole. */ /** How much of an exponential wait is random: none of it, half of it, or all of it. */ export type BackoffJitter = 'none' | 'equal' | 'full'; /** The schedule {@link exponentialBackoff} builds a backoff function from. */ export interface BackoffSpec { /** The ceiling of the first wait (after attempt 1), in milliseconds — a finite number ≥ 0. */ readonly baseDelayMs: number; /** How much each ceiling grows over the one before — a finite number ≥ 1. Default `2`. */ readonly multiplier?: number; /** How much of each wait is random. Default `'none'`: the wait IS the ceiling. */ readonly jitter?: BackoffJitter; /** * The cap on every ceiling, in milliseconds — a number ≥ 0, applied BEFORE * the draw, so capped waits keep their jitter. Default: none. */ readonly maxDelayMs?: number; /** The jitter's random source, answering in [0, 1]. Default `Math.random`, taken when built. */ readonly random?: () => number; } /** A `RetryPolicy.backoffMs` function: the wait in milliseconds after failed attempt `attempt` (1-based). */ export type BackoffFunction = (attempt: number, error?: unknown) => number; /** Reads the wait an error states (a parsed `Retry-After`), in milliseconds, or `undefined` when it states none. */ export type StatedWaitReader = (error: unknown) => number | undefined; /** * An exponential schedule: the wait after failed attempt `n` is drawn under * `baseDelayMs × multiplier^(n − 1)` by the declared jitter. * * @throws when built: a `TypeError` for an option of the wrong type, a * `RangeError` for one out of range — each naming the option. */ export declare function exponentialBackoff(spec: BackoffSpec): BackoffFunction; /** * A wait the outside system stated wins; otherwise `inner` — a backoff * function, or a fixed number of milliseconds — decides. * * @throws when built: a `TypeError` for a reader that is not a function, or an * `inner` that is neither a function nor a finite number ≥ 0. */ export declare function statedWaitFirst(readStatedWaitMs: StatedWaitReader, inner: BackoffFunction | number): BackoffFunction; //# sourceMappingURL=backoff.d.ts.map