UNPKG

framework

Version:

The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.

121 lines 6.4 kB
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