kestrel.markets
Version:
A typed, token-efficient language + runtime for agentic trading: agents author bounded plans, the runtime fires them at the tick. CLI + typed library + MCP server.
79 lines • 5.28 kB
TypeScript
/**
* # session/authoring-loop — the bounded OPEN authoring loop (ADR-0029 §2) + its evidence log
*
* The driver-owned iteration the Simulate driver ({@link import("./simulate.ts")}) runs when the agent is
* viewshop-enabled (it exposes {@link Agent.authoringOpen}): {@link runOpenAuthoringLoop} drives a
* view-request / repair loop under ONE dual budget (`viewRequestCap` + `authoringTokenBudget`) and returns
* the TERMINAL {@link AgentTurn} — only that turn crosses to the Bus + CapturedTurns; the iterations are
* logged as {@link EmergenceRecord}s ABOVE the determinism line (private application data, never a replay
* or graded input). Terminal = a valid `supersede` / `standDown` / empty pass, or a fail-closed `standDown`
* on budget exhaustion (NEVER a forced Plan).
*
* The loop is driver-owned because only the driver holds the frozen snapshot + the pane catalog. It is
* extracted here so that surface — the loop, its dual-budget defaults, the emergence-record shape, and the
* View-document → {@link ViewSelection} mapper it fails closed through — lives beside its own interface. A
* baseline / recorded / fixed run never exposes `authoringOpen`, so this module is inert for it and the run
* is byte-identical (single-shot open).
*/
import { type ViewSelection } from "../frame/pane-catalog.ts";
import { type Agent, type AgentTurn, type LlmUsage } from "./agent.ts";
import type { BriefingInput } from "../frame/types.ts";
/** The conservative default cap on non-terminal authoring iterations (owner-confirmed 2026-07-13). */
export declare const DEFAULT_VIEW_REQUEST_CAP = 3;
/** The conservative default cumulative model-token ceiling for the authoring loop (a config axis). */
export declare const DEFAULT_AUTHORING_TOKEN_BUDGET = 8000;
/**
* One evidence record per NON-terminal authoring iteration (ADR-0029 §5), keyed by
* `(ordinal=OPEN_ORDINAL, iteration)`. It captures BOTH view-requests (the emergence-study signal:
* panes + budget + reason + usage) AND parse-error/repair events (the grammar-evolution signal,
* ADR-0030: the guiding error surfaced + the model + the spend). OFF the graded path — never a
* replay input, never a graded input (private application data).
*/
export interface EmergenceRecord {
/** {@link OPEN_ORDINAL} — the loop is OPEN-only in v1. */
readonly ordinal: number;
/** 0-based index of this non-terminal iteration (shared by view-requests + repairs). */
readonly iteration: number;
readonly kind: "view-request" | "repair";
readonly model: string;
readonly usage: LlmUsage;
readonly latencyMs?: number;
/** `true` when this iteration hit the dual budget → the driver failed closed to standDown. */
readonly budgetExhausted: boolean;
/** The catalog pane ids the requested View selected (empty when the View was a defect). */
readonly panes?: readonly string[];
/** The raw Kestrel VIEW document the agent authored. */
readonly view?: string;
/** The View's own declared token budget (the cost of the screen), distinct from the loop budget. */
readonly viewBudget?: number;
/** The agent's stated reason for this lens (the Brief-acting-through-perception signal). */
readonly reason?: string;
/** The repair-guiding error surfaced to the model (the malformed-input → error signal, ADR-0030). */
readonly error?: string;
}
/** Map a validated Kestrel VIEW document to the renderer's {@link ViewSelection} — pane names +
* budget + the authored pane ARGS (kestrel-wa0j.3: args thread through `resolveView` →
* `materializePanes`; a pane that does not understand an arg fails closed there, never a silent
* drop). Throws if it is not a single `View` (defensive — the harness parser already validated
* this shape in `parseAuthoringReply`). Exported for the pane-args threading test. */
export declare function viewSelectionOfDocument(doc: string): ViewSelection;
export interface AuthoringLoopParams {
readonly viewRequestCap: number;
readonly authoringTokenBudget: number;
readonly emergenceLog?: EmergenceRecord[];
readonly model: string;
}
/**
* Drive the bounded OPEN authoring loop (ADR-0029 §2) and return the TERMINAL {@link AgentTurn}. TWO
* kinds of non-terminal iteration share ONE dual budget (`viewRequestCap` + `authoringTokenBudget`):
* - a **requestView** → materialize the requested View (validated against the one catalog, fail-closed
* on an unknown pane) and re-ask under the SAME frozen snapshot / cutoff (the T-5m guard, §3 —
* structural, since the pane builders are pure functions of the frozen frame);
* - an **invalid author** → surface the repair-guiding error and re-ask (repair).
* Terminal = a valid `supersede` / `standDown` / empty pass, or — on budget exhaustion — a fail-closed
* `standDown` (NEVER a forced Plan). Only this returned turn crosses to the Bus + CapturedTurns; the
* iterations are logged as evidence, above the determinism line. The loop is driver-owned because only
* the driver holds the frozen snapshot and the pane catalog.
*/
export declare function runOpenAuthoringLoop(agent: Agent, briefing: BriefingInput, p: AuthoringLoopParams): Promise<AgentTurn>;
//# sourceMappingURL=authoring-loop.d.ts.map