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.

115 lines 5.83 kB
import type { Driver, DriverEvent } from './driver/index.js'; import { type FrameworkEvent } from './events.js'; /** Inputs to {@link emitSessionStart}. */ export interface SessionStartOptions { emit: (event: FrameworkEvent) => void; driver: Driver; /** The workspace the run works in. */ cwd: string; /** The session link, literal or templated with `{sessionId}`. */ sessionLink?: string | undefined; /** The model id the driver was started with (#1438), recorded on the event per leg. */ model?: string | undefined; } /** * Emit the run's opening `session` event. A literal link is shown right away; a * templated one (`.../{sessionId}`) can only resolve once the driver reports its * session id, so it waits for the `session-update` from {@link createDriverEventHandler}. */ export declare function emitSessionStart(opts: SessionStartOptions): void; /** Inputs to {@link createDriverEventHandler}. */ export interface DriverEventHandlerOptions { emit: (event: FrameworkEvent) => void; /** The session link template, when the caller configured one. */ sessionLink?: string | undefined; /** The run's spend cap (#322). Omitted = uncapped. */ budgetUsd?: number | undefined; /** * Answers "has the account reached its quota boundary?" between turns (#879). * Returns the label of the window that reached it, or null while there is room. */ consumptionGate?: (() => string | null) | undefined; /** Tripped when the budget cap is crossed. */ budgetController: AbortController; /** Tripped when the consumption gate reports a window is spent. */ consumptionController: AbortController; } /** What {@link createDriverEventHandler} hands back. */ export interface DriverEventHandler { /** Wire this as the driver session's `onEvent`. */ onDriverEvent: (event: DriverEvent) => void; /** The window that reached the boundary, once the consumption gate has fired. */ consumptionTrip: () => string | undefined; } /** * Watch the driver's black box (#165) and turn it into the run's stream: surface the * real session id as `session-update` once known (that is the honest handle a UI links * to, and it changes per prompt, so re-emit), fold each turn's usage into the run total, * and trip the two self-stops. * * Both stops fire *after* the turn that crossed them: its cost is already spent, so the * point is to stop the next one. Each is signalled once, and the run's `AbortSignal.any` * composition carries it downstream. An agent that reports no price leaves `costUsd` * undefined and so can never trip the budget cap (#540). A consumption gate that throws * is treated as "carry on": an unreadable quota must not stop the work (#519), and the * gate is answered from a cached reading because a live one spawns the agent CLI (~5s). */ export declare function createDriverEventHandler(opts: DriverEventHandlerOptions): DriverEventHandler; /** Inputs to {@link createRunControls}. */ export interface RunControlsOptions { emit: (event: FrameworkEvent) => void; /** The caller's abort signal (Stop button / Ctrl+C / control channel), if any. */ signal?: AbortSignal | undefined; sessionLink?: string | undefined; budgetUsd?: number | undefined; consumptionGate?: (() => string | null) | undefined; } /** The run's abort plumbing plus its driver-event sink. */ export interface RunControls extends DriverEventHandler { /** The composed signal every driver turn runs under. */ runSignal: AbortSignal; /** Trips a clean stop once this run has spent its budget cap (#322). */ budgetController: AbortController; /** Trips a clean pause once the account's quota window is spent (#529). */ consumptionController: AbortController; /** Trips a clean stop when the user declines a plan (#358); inert on the direct path. */ declineController: AbortController; } /** * Compose the run's signal and wire its driver-event handler in one place. The caller's * signal is OR'd (via {@link AbortSignal.any}) with three self-stops — the budget cap * (#322), a spent consumption window (#529), and a declined plan (#358) — so anything * downstream that watches `runSignal` stops the same way regardless of which fired. * Shared by the build (`run.ts`) and direct-prompt (`prompt-run.ts`) paths. */ export declare function createRunControls(opts: RunControlsOptions): RunControls; /** Inputs to {@link endStopDetail}. */ export interface StopDetailOptions { /** The error the run's turn loop threw. */ err: unknown; /** The caller's own signal, to tell a caller stop from a self-stop. */ signal?: AbortSignal | undefined; budgetController: AbortController; consumptionController: AbortController; declineController: AbortController; consumptionTrip: () => string | undefined; budgetUsd?: number | undefined; /** * Leave a resume note when the run paused on a consumption limit, returning where * it will resume from. Injected (not imported) so this module stays free of the * todo loop it would otherwise import in a cycle. */ leaveResumeNote: () => Promise<string | undefined>; } /** * Classify why a run's turn loop threw and render the `end` event's `detail`. A caller * interrupt, a budget cap (#322), a declined plan (#358), or a spent consumption window * (#529) are all clean stops; anything else is a real failure. The resume note is written * here (once `paused` is known) rather than at the trip, because it is file I/O racing the * run unwinding. Shared so the two run paths can never disagree on what "stopped" means. */ export declare function endStopDetail(opts: StopDetailOptions): Promise<{ stopped: boolean; detail: string; }>; //# sourceMappingURL=run-telemetry.d.ts.map