/** * watch — PUBLIC. The door named for what an observer does. * * Pattern: naming, not machinery. `.watch()` attaches what the removed * `.recorder()` attached; the type it takes is exactly footprintjs's * `CombinedRecorder`. Nothing new happens at run time. * Role: core/ layer. The counterpart `moments.ts` has described in prose * since the loop moments were written down: * * "`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." * * That sentence named an API that did not exist. This is it. * Emits: N/A (one type alias). * * ## Why there is no `WATCH_MOMENTS` * * `.act()`'s keys are a closed, compiler-pinned list because a rule has to be * TOLD where it may speak — a rule written for a moment nobody reads is a * governance hole, so the list is checked and the build fails when it drifts. * An observer is the opposite: it attends the entire event stream, and there * is no closed set to enumerate. Publishing a `WATCH_MOMENTS` list would be * inventing a vocabulary we would then have to keep true against every event * added forever. The honest surface for watching is the door and the type. * * ## Build time and run time are different doors on purpose * * `.watch(observer)` — on the BUILDER. Attached before the agent exists, * so the observer sees the very first run. Returns * the builder, because you are still building. * `agent.attach(o)` — on the RUNNER. Attached to a live agent, and * returns an `Unsubscribe` you own and must call. * * Two return types, no ambiguity about which one you are holding. */ import type { CombinedRecorder } from 'footprintjs'; /** * Anything that can watch a run. * * The plain name for footprintjs's `CombinedRecorder` — the substrate's word * for the same thing, still exported from the main barrel for anyone typing * against the engine directly. Every recorder factory in * `agentfootprint/observe` returns something assignable to this, as does any * object with the recorder hook methods on it. * * @example * ```ts * import { Agent, type Watcher } from 'agentfootprint'; * import { toolChoiceRecorder, routeRecorder } from 'agentfootprint/observe'; * * const observers: Watcher[] = [toolChoiceRecorder(), routeRecorder()]; * * const agent = Agent.create({ provider, model }) * .watch(...observers) * .build(); * ``` */ export type Watcher = CombinedRecorder;