import { type ParsedAwaitGate } from './turn-gate.js';
import { type ChoicePick, type ChoiceRequest, type FrameworkEvent } from './events.js';
import type { DriverSession, DriverTurn } from './driver/index.js';
import type { AgentMessages } from './agent-messages.js';
/** What a resolved gate yields. */
export interface GateAnswer {
    /** The label(s) picked, as the continuation prompt words it to the agent. */
    answer: string;
    /** The user picked an option the agent marked `stop` (#358): hand back rather than continue. */
    stop: boolean;
}
/**
 * Resolve one parsed await gate (#337) to the user's answer text, ready to seed the continuation
 * prompt: emits the `choice`, parks for the pick (or the headless/abort fallback), and maps the
 * picked id(s) back to label(s). Round 0 keeps a stable gate id; later rounds get a unique one so
 * a dashboard never confuses a re-ask with the answer it just resolved. Shared by the build's
 * `agentAwaitGate`, the direct prompt path, and the backlog loop (#323).
 *
 * One path, where there were four. A gate that takes several picks answers with the labels it got
 * (or `(none)`); every other gate answers with the one label picked. What used to distinguish an
 * approval or a browser hand-off from an ordinary question was the options the agent wrote, and
 * that is all it is again.
 *
 * The answer also carries whether it *ends* the session, which is read off the option the user
 * picked rather than off the gate: on a multi-select one stopping pick among several is still a
 * stop, because an answer that says "stop" is not softened by the answers next to it.
 */
export declare function resolveAwaitGate(gate: ParsedAwaitGate, round: number, deps: {
    requestChoice?: ((req: ChoiceRequest) => Promise<ChoicePick>) | undefined;
    emit: (event: FrameworkEvent) => void;
    signal?: AbortSignal | undefined;
}): Promise<GateAnswer>;
/** What {@link runAwaitRounds} hands back. */
export interface AwaitRoundsResult {
    /** The last turn's text. */
    text: string;
    /** The agent was still asking when the round cap ran out. */
    exhausted: boolean;
    /** The user answered a gate with a `stop` option (#358), so the session ends here. */
    stopped: boolean;
}
/** Inputs to {@link runAwaitRounds}. */
export interface AwaitRoundsOptions {
    session: DriverSession;
    /** The prompt that opens the exchange. */
    prompt: string;
    /** Emit the signals each turn carries (#563). */
    emitTurnSignals: (text: string) => void;
    requestChoice?: ((req: ChoiceRequest) => Promise<ChoicePick>) | undefined;
    emit: (event: FrameworkEvent) => void;
    signal?: AbortSignal | undefined;
    /**
     * Live chat (#714): once the agent stops asking, take the user's own messages,
     * each resuming the same session. Unset for a headless agent, which then
     * ends when the agent stops asking — byte-identical to before this existed.
     */
    messages?: AgentMessages | undefined;
    /**
     * Keep the chat parked for the next message instead of ending on an idle queue (#1390).
     * Only for an agent whose own terminal dashboard is the single surface — everything else
     * ends itself and is reopened via `--resume`. Default off.
     */
    stayOpenChat?: boolean | undefined;
    /**
     * Resume a prior session on the OPENING prompt (#720): when the driver session was
     * seeded with a finished agent's id, this makes the first message `--resume` that
     * conversation (full prior context) instead of starting fresh. Default off.
     */
    resume?: boolean | undefined;
}
/** The shared deps of a turn that may hit an await gate or a chat message. */
export interface AwaitTurnDeps {
    requestChoice?: ((req: ChoiceRequest) => Promise<ChoicePick>) | undefined;
    emit: (event: FrameworkEvent) => void;
    emitTurnSignals: (text: string) => void;
    signal?: AbortSignal | undefined;
}
/**
 * Resolve the await gates (#337) a turn ended on: pick the answer, continue with it, repeat until
 * the agent stops asking, an answer says to stop (#358), or the {@link MAX_AWAIT_ROUNDS} cap trips.
 * Returns the settled turn plus which of those ended it.
 *
 * Every path that runs gates shares this loop: the opening prompt, each chat message, and
 * the build's `agentAwaitGate`. They differ only in how a turn is continued — a raw
 * `session.prompt`, or a pass that carries its own continuation — which is what
 * `continueWith` is. Keeping one loop is what stopped the per-turn signal emission from
 * having to be added to each copy by hand (#563).
 */
export declare function drainGates<T extends {
    text: string;
}>(turn: T, deps: AwaitTurnDeps, continueWith: (question: string, answer: string) => Promise<T>): Promise<{
    turn: T;
    exhausted: boolean;
    stopped: boolean;
}>;
/**
 * The live-chat loop (#714): deliver each of the user's messages by resuming the same
 * session (full conversational context), then honor any await gate it produced. Shared by
 * the direct prompt path and the build path, which both reach it once their work has settled.
 *
 * How it ends is the session-lifecycle rule of #1390. By default the loop only *drains*: a
 * message that already arrived is processed, and once the queue is idle the session ends
 * itself rather than parking on the user — merge fires at that natural end (armed + gated),
 * and a follow-up reopens the conversation via `--resume` (#762), like Claude Code web.
 * `stayOpen` keeps the old park-for-the-next-message lifecycle, for an agent whose own terminal
 * dashboard is the only surface — it has no daemon to resume through, so ending would leave
 * its composer a dead end; that agent still ends on Stop / budget cap (next -> undefined).
 *
 * Reports the settled `exhausted` of the *last* chat turn (#742): entering chat means the
 * opening prompt's await-round cap is no longer the agent's end reason, and a phase that ends
 * on Stop / close is not exhausted at all.
 */
export declare function runChatPhase(session: DriverSession, messages: AgentMessages, seed: DriverTurn, deps: AwaitTurnDeps, stayOpen?: boolean): Promise<{
    turn: DriverTurn;
    exhausted: boolean;
    stopped: boolean;
}>;
/**
 * Prompt the agent and honor its await gates (#337) until it stops asking: resolve each gate to
 * the user's answer, re-prompt with it, and repeat up to {@link MAX_AWAIT_ROUNDS}. When a live-chat
 * {@link AwaitRoundsOptions.messages} source is wired, the agent then stays open for the user's own
 * messages (#714) rather than finishing.
 *
 * Every turn here is a turn like any other, so each one's signals are emitted. That is the
 * point of sharing this: the direct prompt path and the backlog loop each had their own copy
 * of these rounds, and the emission had to be added to each by hand (#563).
 */
export declare function runAwaitRounds(opts: AwaitRoundsOptions): Promise<AwaitRoundsResult>;
/** One option of a {@link requestChoices} single-select gate (#304). */
export interface ChoicesOption {
    /** Stable id returned when this option is picked. */
    id: string;
    /** The label shown next to the option. */
    label: string;
    /** Optional one-line detail under the label. */
    detail?: string;
}
/** Inputs to {@link requestChoices}. */
export interface ChoicesDeps {
    /** Stable id for the gate; the pick is posted back against it. */
    id: string;
    /** The prompt shown above the options. */
    title: string;
    /** The options to choose between (pick one). */
    options: readonly ChoicesOption[];
    /** The option id pre-selected (autopilot auto-accepts it) and used as the headless/abort fallback. Default = the first option. */
    recommended?: string;
    /** The markdown file under approval; the dashboard's doc sidebar renders it. */
    file?: string;
    /** The interactive handler (the CLI wires it to the dashboard); omit for a headless agent. */
    requestChoice?: (req: ChoiceRequest) => Promise<ChoicePick>;
    /** Emit the `choice` / `choice-resolved` events onto the agent stream. */
    emit: (event: FrameworkEvent) => void;
    /** The agent signal; a gate parked for a pick unblocks (to the recommended option) if the agent aborts. */
    signal?: AbortSignal;
}
/**
 * The single-select gate (#304): show the options with the recommended one
 * pre-selected, pause, and resolve to the *one* option id the user picked. The twin
 * of {@link requestMultiSelect} for "pick one" — the agent-facing `showChoices()`
 * from the built-in system (#326) prompt and the [Research] preset (#331) both build on it.
 * A headless agent (no `requestChoice`), or one aborted mid-await, falls back to the
 * recommended option without hanging, so a programmatic agent stays deterministic.
 */
export declare function requestChoices(deps: ChoicesDeps): Promise<string>;
/** One option of a {@link requestMultiSelect} checklist (#332). */
export interface MultiSelectOption {
    /** Stable id returned when this option is checked. */
    id: string;
    /** The label shown next to the checkbox. */
    label: string;
    /** Optional one-line detail under the label. */
    detail?: string;
    /** Whether this option starts checked (e.g. a low-rated problem in the [Research] preset #331). */
    default?: boolean;
}
/** Inputs to {@link requestMultiSelect}. */
export interface MultiSelectDeps {
    /** Stable id for the gate; the pick is posted back against it. */
    id: string;
    /** The prompt shown above the checklist. */
    title: string;
    /** The options to choose from (checkboxes). */
    options: readonly MultiSelectOption[];
    /** The interactive handler (the CLI wires it to the dashboard); omit for a headless agent. */
    requestChoice?: (req: ChoiceRequest) => Promise<ChoicePick>;
    /** Emit the `choice` / `choice-resolved` events onto the agent stream. */
    emit: (event: FrameworkEvent) => void;
    /** The agent signal; a gate parked for a pick unblocks (to the defaults) if the agent aborts. */
    signal?: AbortSignal;
}
/**
 * The multi-select gate (#332): show a checklist with the default-checked options
 * pre-selected, pause, and resolve to the *subset* of option ids the user kept
 * checked. Built on the same `choice` gate + POST-back resolver as the single-select
 * plan-approval gate (#304), just in checklist mode. A headless agent (no
 * `requestChoice`) auto-accepts the default set without pausing, so a programmatic
 * run stays deterministic. This is the primitive the [Research] preset (#331) uses
 * to let the user pick which problems to deep-dive.
 */
export declare function requestMultiSelect(deps: MultiSelectDeps): Promise<string[]>;
//# sourceMappingURL=await-gate.d.ts.map