agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
63 lines • 3.03 kB
JavaScript
/**
* recipes/types — the declared unit of agent configuration.
*
* Pattern: a data DECLARATION over an existing fluent builder. No class, no
* registry, no lifecycle. The repo's own instruction is that named
* patterns are recipes over primitives rather than new machinery, and
* this file is that instruction taken literally.
* Role: recipes/ layer, pure. Nothing here imports the engine, a provider,
* or a store — the only agentfootprint type it names is
* {@link AgentBuilder}, and it names it as a TYPE.
* Emits: N/A. `AgentBuilder.recipe()` records the row; `runManifest` reports
* it.
*
* ## The gap this closes
*
* Every capability an agent needs already ships. What did not ship was a
* declared, versioned, inspectable unit of CONFIGURATION. So an agent's setup
* lived as prose in an example, was copy-pasted into an app, drifted there, and
* afterwards nothing on the run could say which composition produced the agent
* that answered. Two runs of "the support agent" could differ in every tool and
* every instruction and be indistinguishable on the record.
*
* A recipe is the missing noun: a name, a version, and a function that calls
* the builder methods that already exist.
*
* ```ts
* export const supportDesk = defineAgentRecipe({
* id: 'support-desk',
* version: '1.2.0',
* description: 'Order lookup + refund policy, the way support runs it.',
* configure: (agent) => {
* agent.system('You answer support questions.').tool(lookupOrder);
* },
* });
*
* const agent = Agent.create({ provider, model }).recipe(supportDesk).build();
* ```
*
* ## No lifecycle magic — stated here because it is the load-bearing limit
*
* A recipe composes CONFIGURATION and nothing else:
*
* • nothing is registered anywhere — a recipe is not discovered, not looked
* up by name, and not resolved from a registry. You import the object and
* hand it to `.recipe()`. There is no global map to go stale, and no
* "which version of `support-desk` is installed" question;
* • nothing is closable — a recipe holds no connection, no handle and no
* process. It never gets a `close()`, a `dispose()` or a teardown hook,
* and it is never awaited: `configure` is synchronous because `build()`
* is (an `async configure` is refused by name rather than silently not
* awaited);
* • nothing is deferred — every call `configure` makes happens during
* `.recipe()`, at the position in the chain where you wrote it. There is
* no later phase in which a recipe acts, so a run's behaviour is decided
* entirely by the builder calls you can read.
*
* That is deliberately thin. The thing being named is a COMPOSITION, and a
* composition that also owned a resource would be a component wearing a
* composition's name — the shape that makes "who closed the pool?" unanswerable
* two releases later.
*/
export {};
//# sourceMappingURL=types.js.map