import type { AgentDepsFactory } from '../agent-deps-factory.js';
import { type ChatQueueService } from '../chat-queue-service.js';
import { type HumanReply } from '../elicitation.js';
import type { AgentRunner, AgentRunStartOptions } from '../spi/agent-runner.js';
import type { AgentStore } from '../spi/agent-store.js';
import type { AgentRunInput } from '../types.js';
/**
 * Runs the agent turn in-process — the default runner (`durable: false`). A HITL wait resolves a
 * pending promise keyed run-namespaced by `${runId}:${toolCallId}`, so one run's reply can never
 * satisfy another's pending action.
 *
 * Sub-agent delegation runs a nested loop on a transient sub-thread, and that nested run parks on a
 * human exactly as a top-level one does — under its OWN runId, which is what makes it answerable:
 * the pending row it writes carries that runId, and its frames are forwarded into the top-level
 * ancestor's stream (the only stream anyone subscribed to) carrying it too. The mirror of the
 * durable runner's `sinkRunId`.
 *
 * Single-replica only — durable is the scaled path (deferred).
 */
export declare class InlineAgentRunner implements AgentRunner {
    private readonly factory;
    private readonly store;
    /** The thread message queue this runner drains when a thread's own turn settles. */
    private readonly queue?;
    private readonly pending;
    /**
     * The input of each top-level run this process is running — what {@link isRunActive} answers
     * from, and what a cancel settles the thread (and its queue) of.
     */
    private readonly live;
    /** Runs someone asked to stop; the loop observes it at its next safe point. */
    private readonly cancelled;
    /**
     * Aborted by {@link cancel}: what cuts short the model call or tool a stopped run is in (the
     * loop's `abortSignal` hook). Keyed like {@link cancelled}, and dropped with it.
     */
    private readonly aborts;
    /** The detached delegates this process is running, by runId — what a Stop on one settles. */
    private readonly detached;
    constructor(factory: AgentDepsFactory, store: AgentStore, 
    /** The thread message queue this runner drains when a thread's own turn settles. */
    queue?: ChatQueueService | undefined);
    /**
     * In-process, so exact: a run this process is not running is not running anywhere — the process
     * that was running it is gone (a restart), and a thread it still holds is a stale claim.
     */
    isRunActive(runId: string): Promise<boolean>;
    start(input: AgentRunInput, options?: AgentRunStartOptions): Promise<{
        runId: string;
    }>;
    /**
     * Move the thread past a settling TOP-LEVEL run — to the next queued message, which starts here,
     * or to a paused/empty queue — and write the resulting `queue` frame into this run's stream. A
     * no-op without a queue-capable store, and for a run that is not a thread's own turn.
     *
     * Never throws: the run is settling either way, and a queue that could not be advanced is picked
     * up by the next send or resume on the thread.
     */
    private settleQueue;
    /**
     * Deliver a human's reply to whichever wait this run is parked on.
     *
     * An approval wait takes a {@link Decision} only. Answers addressed there are refused rather than
     * delivered: `approved` is absent on them, and the tool-call row would record a rejection the
     * person never made. The refusal leaves the wait intact, so the approval is still there to make.
     *
     * The other direction IS delivered — a question set parks as a `pending_approval` action, so an
     * operator pressing Approve on it is expected, and the loop reads that as "confirmed the
     * pre-picked answers".
     */
    signal(runId: string, toolCallId: string, reply: HumanReply): Promise<void>;
    /** The signal {@link cancel} aborts for `runId` — one per run, shared by its awaited delegates. */
    private abortSignalFor;
    /** Drop a settled run's Stop: its flag and its abort controller. */
    private forgetCancel;
    cancel(runId: string): Promise<void>;
    private topLevelHooks;
    /**
     * The two waits a run parks on, keyed by the run that is parked. Identical for a top-level run and
     * for a delegated one: `signal(runId, …)` finds either, because the pending map belongs to the
     * runner rather than to a run.
     */
    private humanHooks;
    /** Hold a run at `key` until a human's reply arrives through {@link InlineAgentRunner.signal}. */
    /**
     * {@link park} for an approval, bounded by the policy's time to live when it has one: the timer
     * settles the wait as `expired` — the same Decision the durable runner builds from its signal
     * timeout — and a decision that arrives first disarms it.
     */
    private parkApproval;
    private park;
    /**
     * Delegate WITHOUT waiting: a nested loop nobody awaits, on its own scratch thread and its OWN
     * stream, which posts its answer back into the delegating thread when it lands (`deliverTo`,
     * delivered by the loop). The calling turn gets the run id straight back and finishes.
     *
     * No `sinkRunId`, unlike {@link runNested}: forwarding into the stream the human is watching would
     * write into a turn that has already ended. It parks on a human under its own runId, which is what
     * `tool-call/approve` resolves the pending row to; and it is stoppable on that id (the receipt
     * carries it), which settles the delegation as `cancelled` in the thread that asked.
     */
    private startDetached;
    /** Delegate to another agent as a nested in-process run (a transient sub-thread). */
    private runNested;
}
//# sourceMappingURL=inline-agent-runner.d.ts.map