/**
 * 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 — 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;
}
/**
 * Fail the run (or retry, on early attempts) when the replay budget is
 * exhausted. The handling depends on whether the underlying World
 * supports `process.exit(1)` as a queue redelivery signal (see
 * `World.processExitTriggersQueueRedelivery`):
 *
 * - **Managed-platform Worlds** (`world-vercel`): on attempts <=
 *   `REPLAY_TIMEOUT_MAX_RETRIES` exit the process so the platform fails
 *   the invocation and the queue redelivers; on the next attempt write
 *   `run_failed` with `RUN_ERROR_CODES.REPLAY_TIMEOUT` and exit.
 *
 * - **In-process Worlds** (`world-local`, dev servers): calling
 *   `process.exit()` would terminate the host (e.g. `pnpm dev`), so
 *   instead log a warning, write `run_failed` best-effort, and return.
 *   The framework completes the request normally.
 */
export declare function handleReplayBudgetExhausted(args: {
    runId: string;
    workflowName: string;
    requestId: string | undefined;
    attempt: number;
    limitMs: number;
}): Promise<void>;
//# sourceMappingURL=replay-budget.d.ts.map