/** * The sentinel {@link raceCallDeadline} resolves to when the budget expired before the call * answered. A unique symbol, so no provider payload can ever be mistaken for it — the reason each * of the four sites used a `Symbol` rather than a string or `null` in the first place. */ export declare const CALL_TIMED_OUT: unique symbol; /** A started wall-clock budget: the signal to hand the call, and the promise that says it expired. */ export interface CallDeadline { /** * The signal to pass to the provider call. Aborted when — and only when — the budget expires. */ readonly signal: AbortSignal; /** * Resolves to {@link CALL_TIMED_OUT} when the budget expires. Never rejects, so it can be raced * against a call without the loser becoming a rejection of its own. */ readonly expired: Promise; /** * Clear the timer. Call this in a `finally` on every exit from the budgeted region, including * the successful one: a timer left armed keeps the event loop alive for the rest of the budget, * which is a smaller version of the very hang this module exists to end. */ dispose(): void; } /** * Start a wall-clock budget. * * **The ordering inside the timer callback is load-bearing.** The sentinel is resolved *before* the * controller is aborted, because aborting first can settle the in-flight call's promise ahead of * the sentinel — and then `Promise.race` yields the `AbortError` instead of {@link CALL_TIMED_OUT}. * At the rater that would silently re-file a timeout as a thrown call: the verdict's * `FailClosedCause` would become `'threw'` rather than `'timeout'`, moving a gate decision * [[EXT-171]] rules on onto a different arm, with the user-facing sentence changing to match. With * the sentinel resolved first the race is settled before the abort can be observed, so every site * keeps exactly the timeout path it had. * * The timer is deliberately **not** `unref`'d. It is the budget itself, not a backstop, and an * unref'd budget can be skipped entirely if nothing else is holding the loop — which would make the * timeout path untestable in exactly the conditions it exists for. {@link CallDeadline.dispose} is * what stops it outliving the call. * * @param timeoutMs The wall-clock budget in milliseconds. */ export declare function startCallDeadline(timeoutMs: number): CallDeadline; /** * Run one provider call under an already-started budget, returning either the call's value or * {@link CALL_TIMED_OUT}. * * The deadline is passed in rather than started here so that a **multi-turn** caller can hold one * budget across many calls. The alignment checker's budget is one wall-clock budget for one gate * decision; starting a fresh one per turn would silently multiply it by the turn count, on exactly * the slow local models the budget exists to accommodate. Single-shot callers use * {@link withCallDeadline}, which starts and disposes one for them. * * **The call's own rejections still propagate.** Only the abort *this* module causes is swallowed; * a provider error, an auth failure or a transport failure rejects out of here as before, so each * site's existing `catch` arm keeps its meaning. * * @param deadline The budget from {@link startCallDeadline}. * @param start Starts the call, given the signal to pass to the provider. It is called exactly * once. **The signal has to reach the provider invocation** — a `start` that ignores it produces * a helper that times out and aborts nothing, which is the defect this module was written to fix. * It is invoked inside {@link runWithCallSignal}, so a client that has no way to accept a signal * can still pick it up from the ambient context. */ export declare function raceCallDeadline(deadline: CallDeadline, start: (signal: AbortSignal) => Promise): Promise; /** * The single-shot form: start a budget, run one call under it, and dispose the budget on every * exit — including the throwing one, which is why the `finally` is not optional. * * @param timeoutMs The wall-clock budget in milliseconds. * @param start As {@link raceCallDeadline}'s. */ export declare function withCallDeadline(timeoutMs: number, start: (signal: AbortSignal) => Promise): Promise;