/** * Quota-exhaustion classification and reset-time math — the shared brain of * the two auto-resume paths (workflow run watchdog, /auto goal-loop wait). * * Why this exists: a GlM-style usage cap (business code 1308, …) is a * DETERMINISTIC model failure — upstream's workflow policy stops the whole run * as `stopped(provider)` with `ProviderStopDetails{kind:"quota"}` and its * notification tells the main agent to call ResumeWorkflowRun AFTER the reset * (workflow-model-failure-policy.ts:36-55 workflown quata codes; * workflow-notification-copy.ts:55-64). Nothing in the stack schedules that * "after": the desktop expects a human/model to act later. The bridge owns * both surfaces that CAN wait (the /auto driver and the workflow poller), so * the wait-and-continue behavior lives here. * * Everything is defensive: error payload shapes span bridge RequestError data, * raw turn.failed causes, and upstream WorkflowErrorJson — read by shape, * never by class identity. */ import type { QuotaResult } from "./types.js"; /** Upstream stop-class quota business codes (adapters/src/model/workflow-model-failure-policy.ts:36-55). */ export declare const QUOTA_PROVIDER_CODES: ReadonlySet; /** * A window at/above this used-percent counts as exhausted when a quota stop * was already observed (only used to pick the reset moment, never to detect a * stop by itself). 98 leaves room for the API's integer rounding. */ export declare const QUOTA_EXHAUSTED_PERCENT = 98; /** Provider business code and/or reset moment of a quota exhaustion. */ export interface QuotaExhaustionInfo { providerCode?: string; /** Reset moment (epoch ms) when the provider (or a Retry-After) told us. */ resetAt?: number; } /** * Whether a run's `failureMessage` reads as a quota stop. Used by the * workflow scan, where only the summary string travels — the structured * `providerStop` does not. The bracket check mirrors the upstream driver's * fixed message format; the wording fallback covers providers without a * numeric code. Re-check against `workflow-notification-copy.ts` on version * bumps. */ export declare function isQuotaStopFailureMessage(message: unknown): boolean; /** * Classify an error as a quota exhaustion, digging through the shapes seen in * practice: bridge `RequestError.data` (AcpTurnFailureData), raw turn.failed * `cause`/`context`, and upstream WorkflowErrorJson (`providerStop`). * * The structured `providerStop.kind` verdict is authoritative when present — * a non-quota stop never falls through to the message heuristics. */ export declare function classifyQuotaExhaustion(error: unknown): QuotaExhaustionInfo | undefined; /** * The moment to try again, derived from a fresh quota card: the EARLIEST * future reset among windows already at/near exhaustion. Min (not max) is * deliberate: resuming a touch early only costs one rejected request, while * waiting for the LAST window can delay work by days when a second window was * only caught by the rounding margin. */ export declare function quotaResetAtFromResult(result: QuotaResult, now?: number): number | undefined; /** * Exponential backoff for resume attempts with no known reset moment * (attempt 1 = base). Capped so a long outage still gets periodic tries * without hammering a provider that is plainly still capped. */ export declare function quotaBackoffMs(attempt: number, baseMs?: number, capMs?: number): number; //# sourceMappingURL=resume.d.ts.map