/** * act — PUBLIC. One bundle for every place a rule may speak. * * Pattern: Facade over five doors, with the facade's KEYS type-locked to the * list of moments they cover. * Role: core/ layer. `.act()` builds nothing new: it validates a bundle * and calls `.messageMiddleware()`, `.toolMiddleware()` and * `.window()` with exactly what a person would have passed by hand. * Everything about a run is decided by those doors, here and there * alike. * Emits: N/A. * * ## Why a bundle at all, when the doors already exist * * Because the doors are findable one at a time and the POSTURE is not. An * agent's governance currently reads as four unrelated calls scattered * through a builder chain, and the question a reviewer actually has — * "what does this agent do at each point in its loop?" — has no place to be * answered. `.act({ … })` is that place: five optional keys, named for the * five moments, so autocomplete on an empty object teaches the loop. * * ## The completeness lock * * The keys of {@link ActOptions} are pinned, at compile time, against * `ActKey` — the moment list, camel-cased. Add a sixth moment to * `LOOP_MOMENTS` and this file stops compiling until the bundle grows the key * for it; delete a key and the same. A surface that claims to be complete has * to be made unable to fall behind, or the claim is just a sentence in a doc. * * The runtime half is derived from the same list: the accepted key set is * `LOOP_MOMENTS.map(actKeyFor)`, so a typo'd key is refused by a validator * that cannot drift from the type it is validating. */ import type { MessageMiddleware, ToolMiddleware } from './middleware/types.js'; import { type ActKey } from './moments.js'; import type { WindowStrategy } from './window/strategy.js'; /** * The whole steering wheel: one key per moment of the loop, each optional. * * The declaration order below is the order the loop reaches them. */ export interface ActOptions { /** The user's message, before the run commits it. */ readonly input?: readonly MessageMiddleware[]; /** Every tool call, before it is dispatched. */ readonly beforeTool?: readonly ToolMiddleware[]; /** Every tool result, after the tool ran and before the model reads it. */ readonly afterTool?: readonly ToolMiddleware[]; /** What the live context window keeps, at each iteration boundary. */ readonly window?: WindowStrategy; /** The final answer, before the caller receives it. */ readonly output?: readonly MessageMiddleware[]; } /** The keys `.act()` accepts, derived from the moment list rather than typed. */ export declare const ACT_KEYS: readonly ActKey[]; /** What `.act()` hands to the five doors. */ export interface ResolvedAct { readonly message: readonly MessageMiddleware[]; readonly tool: readonly ToolMiddleware[]; readonly window?: WindowStrategy; } /** * Validate a bundle and turn it into the arguments the five doors take. * * Pure — it throws or it returns; it touches no builder state. `.act()` is * the caller that hands the result to the doors, which is what makes the * sugar provably the same agent. */ export declare function resolveAct(options: ActOptions): ResolvedAct;