UNPKG

agentfootprint

Version:

The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.

56 lines (55 loc) • 2.69 kB
/** * moments — PUBLIC. The five places in the loop where a rule may speak. * * Pattern: Closed enumeration + a mechanical name mapping, with the mapping * pinned by the compiler rather than by memory. * Role: lib/ leaf (Map). `LoopMoment` is the vocabulary `.act()` is keyed on * and the vocabulary every ledger row now stamps itself with, so a * person asking "where in the loop did this happen?" and a person * asking "where in the loop can I intervene?" are reading the same * five words. * Emits: N/A (types + one pure function). * * ## Why the list is here and not inside `.act()` * * A bundle whose keys ARE the moments is only honest while the two sets * agree. Keep the list of moments in the options type and the sixth moment * ships with no key and nothing notices; keep it here, derive the key names * from it, and the day a moment is added the build fails inside `act.ts` * naming the key nobody wrote. That is the same trick `conformSource` plays * on the outside world, turned inward on ourselves. * * The mapping between the two spellings is mechanical — kebab in the record * (`'before-tool'`, which reads as a phase), camel in the bundle * (`beforeTool`, which reads as a property) — and `actKeyFor` is its runtime * twin, so the validator that decides which keys `.act()` accepts is * DERIVED from this list rather than typed out beside it. */ /** * Every moment of one agent turn where a rule may act, in the order the loop * reaches them. * * ``` * input → [ window → … LLM … → before-tool → tool → after-tool ]* → output * ``` * * `watch` attends all five and more; `act` attends exactly these. The * difference is what a rule may DO there — an observer reports, a rule * changes what happens next. */ export declare const LOOP_MOMENTS: readonly ["input", "before-tool", "after-tool", "window", "output"]; /** One of the five moments. See {@link LOOP_MOMENTS}. */ export type LoopMoment = (typeof LOOP_MOMENTS)[number]; /** * The `.act()` key that governs a moment: the moment's name, camel-cased. * * `'before-tool'` → `beforeTool`. Purely mechanical, so there is no list of * pairs anywhere for the two spellings to drift apart in. */ export type ActKey<M extends LoopMoment = LoopMoment> = M extends `${infer Head}-${infer Tail}` ? `${Head}${Capitalize<Tail>}` : M; /** * The runtime twin of {@link ActKey}. `.act()`'s accepted key set is built * from this over `LOOP_MOMENTS`, so an unknown key is refused by a rule that * cannot fall behind the list it is derived from. */ export declare function actKeyFor(moment: LoopMoment): ActKey;