import { SmolConfig } from "smoltalk";
import type { DebuggerState } from "../../debugger/debuggerState.js";
import type { LogLevel } from "../../logger.js";
import { SimpleMachine } from "../../simplemachine/index.js";
import { StatelogClient, StatelogConfig } from "../../statelogClient.js";
import { CoverageCollector } from "../coverageCollector.js";
import type { AgencyCallbacks } from "../hooks.js";
import type { InterruptResponse } from "../interrupts.js";
import { LLMClient } from "../llmClient.js";
import { MemoryManager } from "../memory/manager.js";
import type { MemoryConfig } from "../memory/types.js";
import { GlobalStore } from "../state/globalStore.js";
import { StateStack } from "../state/stateStack.js";
import type { TraceConfig } from "../trace/types.js";
import type { HandlerFn } from "../types.js";
import type { Checkpoint } from "./checkpointStore.js";
import { CheckpointStore } from "./checkpointStore.js";
import { PendingPromiseStore } from "./pendingPromiseStore.js";
export declare class RuntimeContext<T> {
    stateStack: StateStack;
    globals: GlobalStore;
    checkpoints: CheckpointStore;
    callbacks: AgencyCallbacks;
    onStreamLock: boolean;
    handlers: HandlerFn[];
    pendingPromises: PendingPromiseStore;
    graph: SimpleMachine<T>;
    _skipNextCheckpoint: boolean;
    _pendingArgOverrides?: Record<string, any>;
    _restoreCount: number;
    _toolCallDepth: number;
    /** Nested-dispatch depth counter for `runHandlerChain` (lib/runtime/interrupts.ts).
     *  Incremented on entry to each handler-chain dispatch, decremented in its
     *  `finally`. The dispatcher throws a `HandlerRecursionError` when this counter
     *  exceeds `MAX_HANDLER_CHAIN_DEPTH` — that means a handler raised an interrupt
     *  whose dispatch re-entered the same chain too many times, almost always a
     *  handler accidentally re-invoking itself (see the recursion case debugged in
     *  https://ampcode.com/threads/T-019e7a80-0a51-75ce-840e-89b5f595da5c).
     *
     *  This is NOT the length of `ctx.handlers`. It only grows when a handler's body
     *  triggers another interrupt while the outer dispatch is still in flight. Normal
     *  push/pop of handlers via `with approve` does not increment it. */
    _handlerChainDepth: number;
    debuggerState: DebuggerState | null;
    private traceWriter;
    statelogClient: StatelogClient;
    smoltalkDefaults: Partial<SmolConfig>;
    private _llmClient;
    private _interruptResponses;
    get llmClient(): LLMClient;
    setLLMClient(client: LLMClient): void;
    setInterruptResponses(responses: Record<string, {
        response: InterruptResponse;
    }>): void;
    getInterruptResponse(interruptId: string): InterruptResponse | undefined;
    dirname: string;
    /** Callbacks registered at module top-level (via `_callback` during
     *  `__initializeGlobals`, when no real caller frame exists yet). Persist for
     *  the whole run. */
    topLevelCallbacks: Array<{
        name: string;
        fn: any;
    }>;
    abortController: AbortController;
    traceConfig: TraceConfig;
    runId: string | null;
    verbose: boolean;
    /**
     * Log threshold used by ad-hoc subsystem loggers (memory, etc.).
     * Plumbed in from `AgencyConfig.logLevel` so users can crank it up to
     * `"debug"` when investigating issues without recompiling. The logger
     * itself is stateless — consumers call `createLogger(execCtx.logLevel)`
     * on demand rather than carrying a long-lived Logger instance, which
     * lets each subsystem add its own prefix without coordinating an
     * instance pool.
     */
    logLevel: LogLevel;
    getStaticVars?: () => Record<string, unknown>;
    coverageCollector: CoverageCollector | null;
    private statelogConfig;
    maxRestores: number;
    jsonMemoryConfig?: MemoryConfig;
    private memoryManagerCache;
    constructor(args: {
        statelogConfig: StatelogConfig;
        smoltalkDefaults: Partial<SmolConfig>;
        dirname: string;
        maxRestores?: number;
        traceConfig?: TraceConfig;
        verbose?: boolean;
        memory?: MemoryConfig;
        /** Threshold for ad-hoc subsystem loggers. Optional so existing
         *  test/runtime constructors keep working; defaults to "info" to
         *  match the established no-debug-by-default behavior. */
        logLevel?: LogLevel;
    });
    getRunId(): string;
    createExecutionContext(runId: string): Promise<RuntimeContext<T>>;
    /**
     * Resolve the active `MemoryManager` for the current stateStack.
     *
     * Single rule: top of `stateStack.other.memoryFrames` (accessed via
     * `activeMemoryFrame()`) wins. No fallback to a "default" manager —
     * the JSON config gets seeded as the bottom frame at execCtx
     * creation, so if JSON was set there will always be a frame and
     * this never returns `undefined` for JSON-only setups.
     *
     * The one back-compat seam: a checkpoint written before
     * `memoryFrames` existed (or one taken right after a user called
     * `disableMemory()` on the JSON-seeded bottom frame) has no frames.
     * If `jsonMemoryConfig` is set we re-seed it as a courtesy so old
     * traces resume as before. If the user explicitly popped, they
     * call `enableMemory(...)` again to turn it back on.
     *
     * Managers are cached per execCtx keyed by `configKey` so
     * push/pop/push of the same dir reuses one instance — important
     * for the "pop back to A returns A's manager" semantics.
     */
    getActiveMemoryManager(): MemoryManager | undefined;
    /** Iterate every cached memory manager. Used at shutdown so a
     *  branch that opened a side store doesn't lose its writes. */
    getAllCachedMemoryManagers(): MemoryManager[];
    pushHandler(fn: HandlerFn): void;
    popHandler(): void;
    enterToolCall(): void;
    exitToolCall(): void;
    isInsideToolCall(): boolean;
    get aborted(): boolean;
    /**
     * Branch-aware cancellation check. Returns true if either:
     *   - the global ctx is aborted (e.g., user pressed Ctrl-C), OR
     *   - the given branch stack's per-branch abort signal has fired (e.g.,
     *     this branch is a race loser).
     *
     * Pass the local stateStack at any call site that lives inside a fork/race
     * branch so the check sees that branch's signal. Without a stack arg, this
     * is equivalent to `ctx.aborted`.
     */
    isCancelled(stack?: StateStack): boolean;
    /**
     * Branch-aware AbortSignal for HTTP/fetch/streaming calls. Returns a
     * composite signal that fires on either global ctx abort OR the given
     * branch stack's abort. Pass to smoltalk's `abortSignal` so per-branch
     * cancellation actually tears down in-flight network requests.
     *
     * If no stack is given (or the stack has no branch signal), returns the
     * global ctx signal — same behavior as before.
     */
    getAbortSignal(stack?: StateStack): AbortSignal;
    cancel(reason?: string): void;
    forkStack(): StateStack;
    /** Sever references held by an execution context so GC can reclaim them. */
    cleanup(): void;
    /** Get the most recent result-entry checkpoint for the current function. */
    getResultCheckpoint(): Checkpoint | undefined;
    restoreState(checkpoint: Checkpoint): void;
    /** @deprecated Use checkpoints.create() instead */
    stateToJSON(): {
        stack: import("../state/stateStack.js").StateStackJSON;
        globals: import("../state/globalStore.js").GlobalStoreJSON;
    };
    toJSON(): {
        stateStack: import("../state/stateStack.js").StateStackJSON;
        callbacks: string[];
        onStreamLock: boolean;
        graph: {
            nodes: string[];
            edges: Record<string, string[]>;
            config: {
                debug: {
                    log?: boolean;
                    logData?: boolean;
                } | undefined;
            };
        };
        statelogClient: string;
        smoltalkDefaults: string;
        dirname: string;
    };
    getSmoltalkConfig(config?: Partial<SmolConfig>): Partial<SmolConfig>;
    pauseTraceWriter(): Promise<void>;
    closeTraceWriter(): Promise<void>;
    writeCheckpointToTraceWriter(checkpoint: Checkpoint): Promise<void>;
    writeStaticStateToTrace(values: Record<string, unknown>): Promise<void>;
    hasDebugger(): boolean;
    hasTraceWriter(): boolean;
}
