import type { Driver } from './driver/index.js';
import { type TodoLoopResult } from './todo-loop.js';
import { type ChoicePick, type ChoiceRequest, type FrameworkEvent } from './events.js';
import type { AgentMessages } from './agent-messages.js';
import { type AgentLocation } from './agent-location.js';
/**
 * One session: frame the wrapped agent, send it a prompt, honor the gates it answers with, and
 * stream every step as a {@link FrameworkEvent}. Reversible — swap in a different `Driver`
 * without touching this wiring.
 *
 * There used to be two of these. `runFramework` drove a build through ai-autopilot's `Bootstrap`
 * spine, and `runPrompt` ran one prompt verbatim; `composeAgentSystem` exists specifically because
 * the two each inlined the system composition and drifted apart (#500/#501). Once the review loop
 * (A5) and the `Bootstrap` spine (A3) went, the build path *was* "one prompt, honoring gates" —
 * which is what the prompt path already was. What is left of the difference is two options rather
 * than two implementations: which prompt opens the session, and whether the agent's own backlog is
 * worked afterwards.
 */
/** What a session is: an intent to build from, or a prompt to run verbatim. */
export type AgentKind = 'build' | 'prompt';
/** Options for {@link runAgent}. */
export interface RunAgentOptions {
    /**
     * What the session is asked to do. For `build`, the intent the opening prompt is composed
     * around; for `prompt`, the text sent as-is (modulo the system template's user slot).
     */
    prompt: string;
    /** Which opening prompt this session gets, and whether the backlog loop follows. Default `build`. */
    kind?: AgentKind;
    /**
     * Where this session's turns execute (#1050/#610). Default `local`. Only `web` hands the work
     * somewhere this machine cannot follow, which makes the opening prompt the whole session —
     * see {@link isHandsOff}.
     */
    location?: AgentLocation;
    /** The wrapped coding agent. */
    driver: Driver;
    /** Absolute workspace path the agent works in. */
    cwd: string;
    /** Model id to pass through to the driver. */
    model?: string;
    /**
     * A user-authored system prompt (from `SYSTEM.md`) injected into every prompt
     * (#301). Load with `loadUserSystemPrompt(cwd)`. Composed after the built-in
     * #326 system prompt, so a repo can add its own instructions on top of the default.
     */
    systemPrompt?: string;
    /** Remove the built-in #326 system prompt (#301/C3). Default `false` — it is included. */
    vanilla?: boolean;
    /** This session has a real browser (#824), so the system channel says so. */
    browser?: boolean;
    /** Transparent mode (#625): empty the system channel entirely (raw `claude -p`); overrides vanilla. */
    transparent?: boolean;
    /** In-context directories (#439): added as one `Context:` line to the system prompt. */
    context?: readonly string[];
    /**
     * A link to the live agent session, shown on the dashboard. Either a literal
     * URL, or a template with `{sessionId}` (see {@link SESSION_ID_PLACEHOLDER})
     * that resolves once the wrapped agent reports its real id via `session-update`.
     */
    sessionLink?: string;
    /** Interrupt the session between turns. */
    signal?: AbortSignal;
    /**
     * Pause on an interactive choice and await a pick (#304). Called when a turn stops to ask
     * (#337/#358): the session emits a `choice` event, calls this, and resumes on the returned
     * option. Omit for a headless session: the gate then auto-accepts the recommended option
     * without pausing. The CLI wires this to the dashboard's Accept button.
     */
    requestChoice?: (req: ChoiceRequest) => Promise<ChoicePick>;
    /**
     * Work the agent's own `TODO_AGENTS.md` backlog after the opening exchange settles (#323), one
     * gated entry per turn until it is empty. Default: on for a `build` session with a real driver,
     * off otherwise (a `prompt` session is one prompt by definition, and the fake driver's scripted
     * demo writes no backlog and must stay deterministic). Set explicitly to force either way.
     */
    todoLoop?: boolean;
    /**
     * Continue a stopped session's conversation (#720/#1467): the captured agent session id to
     * `--resume`. When set, {@link prompt} is sent verbatim as a continuation message rather than
     * composed — the resumed transcript already carries the framing, which is exactly why #782
     * refused to bolt a resumed session onto a fresh build. Everything around the turn still runs:
     * the gates, the backlog loop, live chat — the flow resumes, not just the conversation.
     */
    resumeSessionId?: string;
    /**
     * Live chat (#714): once the opening exchange settles, take the user's own messages, each
     * continuing the same session. The session then ends itself when the queue is idle (#1390)
     * unless {@link stayOpenChat} parks it. Unset for a headless session, which ends when the agent
     * stops asking.
     */
    messages?: AgentMessages;
    /**
     * Keep the chat parked for the next message instead of ending on an idle queue (#1390).
     * Only for a session whose own surface is the single one — it has no dashboard to resume
     * through, so ending would leave its composer a dead end.
     */
    stayOpenChat?: boolean;
    /** Observe the unified event stream. */
    onEvent?: (event: FrameworkEvent) => void;
}
/** What a session returns. */
export interface RunAgentResult {
    /** The final turn's text. */
    text: string;
    /** Every event emitted, in order. */
    events: FrameworkEvent[];
    /** How the backlog loop (#323) ended, when it ran. */
    todo?: TodoLoopResult;
}
/**
 * Run one session to completion: send the opening prompt, honor each await gate (#337/#339) by
 * re-prompting with the user's answer, work the backlog if this is a build, and stay open for the
 * user's own messages when a chat source is wired.
 *
 * Emits the same {@link FrameworkEvent} stream throughout — `session`, `system-prompt`, `driver`,
 * `choice`, `usage`, `intent`, `end` — so the dashboard, the store, and the control channel (#344)
 * read one shape regardless of what opened the session.
 */
export declare function runAgent(opts: RunAgentOptions): Promise<RunAgentResult>;
//# sourceMappingURL=agent.d.ts.map