import { type SlotSnapshotParams } from './helpers.js';
/**
 * Per-invocation accounting of the *non-step* portion of a workflow
 * handler run: deterministic event-log replay, workflow-VM execution
 * between step boundaries, suspension handling, queue round-trips, etc.
 * Inline step bodies (`"use step"` functions invoked via `executeStep`)
 * are intentionally excluded since they are bounded by the platform's
 * function `maxDuration` and the `NO_INLINE_REPLAY_AFTER_MS` early-return
 * guard.
 *
 * Usage:
 *
 * ```ts
 * const budget = new ReplayBudget();
 * // …non-step work happens here, accumulates against the budget…
 * budget.pause();
 * try {
 *   await executeStep(...); // not charged
 * } finally {
 *   budget.resume();
 * }
 * // back to charging
 * if (budget.isExhausted()) { ... }
 * ```
 *
 * Implementation notes:
 *
 * - `pause()` and `resume()` are idempotent: calling `pause()` while
 *   already paused (or `resume()` while already resumed) is a no-op.
 *   This protects against double-counting in future refactors that nest
 *   step execution or take an early-return path between a `pause()` and
 *   the matching `resume()`.
 * - `isExhausted()` is checked at loop boundaries by the caller; the
 *   budget itself does not arm any timers. This means an in-flight
 *   pathological `runWorkflow` call (e.g. a huge event-log replay) can
 *   overshoot the budget by up to one iteration's worth of work before
 *   the next check fires. In practice the 20s headroom built into
 *   `MAX_REPLAY_TIMEOUT_MS` (and the function `maxDuration` ceiling)
 *   gives us slack; the old `setTimeout`-based approach also ultimately
 *   relied on the platform SIGTERM as the hard backstop.
 */
export declare class ReplayBudget {
    private readonly limitMs;
    private elapsedMs;
    private intervalStart;
    constructor(limitMs?: number);
    /**
     * The configured replay-timeout limit, in ms. Useful for log messages.
     */
    get configuredLimitMs(): number;
    /**
     * Total non-step time accumulated so far, in ms. Includes the
     * currently-active interval if the budget is not paused.
     */
    elapsed(): number;
    /**
     * Stop counting elapsed time toward the budget. Idempotent: safe to
     * call multiple times in a row; subsequent calls are no-ops until
     * `resume()` reopens an interval.
     */
    pause(): void;
    /**
     * Resume counting elapsed time toward the budget. Idempotent: safe to
     * call multiple times in a row; subsequent calls re-anchor the
     * interval start to `now()`, which is fine because no time accrues
     * between back-to-back `resume()` calls.
     */
    resume(): void;
    /**
     * True if the budget has been exhausted (`elapsed() >= limitMs`).
     * Callers should invoke `handleExhausted(...)` afterward and return
     * from the handler.
     */
    isExhausted(): boolean;
}
export declare class ReplayTimeoutRetryError extends Error {
    readonly name = "ReplayTimeoutRetryError";
}
/**
 * Reject the current delivery while replay-timeout retries remain. Once
 * exhausted, fail the run and let the queue acknowledge the delivery.
 */
export declare function handleReplayBudgetExhausted(args: {
    runId: string;
    workflowName: string;
    requestId: string | undefined;
    attempt: number;
    limitMs: number;
    /**
     * How much of the log the replay that ran out of budget had loaded. Carried
     * onto the terminal write for the same reason every other write from that
     * replay carries it: the run is being failed on a view of the log, and the
     * World should be told which view.
     */
    slotSnapshot?: SlotSnapshotParams;
}): Promise<void>;
//# sourceMappingURL=replay-budget.d.ts.map