agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
61 lines (60 loc) • 2.41 kB
TypeScript
/**
* Swarm — multi-agent handoff. At each step, an LLM-driven routing
* decision picks which agent handles the next turn.
*
* Origin: OpenAI Swarm experiment (2024). Useful for specialist
* routing — each agent has a narrow role + its own tools.
*
* Pattern: Factory → produces a `Runner` built from
* `Loop(Conditional(route-to-agent))`.
* Role: patterns/ layer. Pure composition over existing primitives.
* Agent roster is FIXED at build time; the routing decision
* is made at runtime by a consumer-supplied `route(input)`
* function (sync — pure over `{ message }`).
*
* For LLM-driven routing (the classic Swarm style), the consumer
* composes a "router" LLMCall as the first step of each iteration and
* parses its response in their `route()` function.
*/
import type { Runner } from '../core/runner.js';
export interface SwarmAgent {
/** Stable id used in events + routing decisions. */
readonly id: string;
/** Display name for topology / narrative. */
readonly name?: string;
/** The runner that handles a turn when selected. */
readonly runner: Runner<{
message: string;
}, string>;
}
export interface SwarmOptions {
/**
* The fixed agent roster. Must contain >= 2 agents. The order doesn't
* matter — the `route` function selects by id.
*/
readonly agents: readonly SwarmAgent[];
/**
* Routing function — receives the current message and returns the
* selected agent's id. Pure sync; evaluated before each iteration's
* chosen agent runs. Return `undefined` or an unknown id to halt
* the swarm (the loop's `until` guard fires).
*/
readonly route: (input: {
readonly message: string;
}) => string | undefined;
/** Max hand-offs before the loop halts. Default 10. */
readonly maxHandoffs?: number;
readonly name?: string;
readonly id?: string;
}
/**
* Build a Swarm Runner. Each iteration:
* 1. Router evaluates `route(input)` to pick an agent id.
* 2. Conditional dispatches to that agent's runner.
* 3. Agent's output becomes the next iteration's input.
* Loop halts when `route` returns a halt-sentinel id (or unknown id
* falling to the `done` branch) OR when `maxHandoffs` is reached.
*/
export declare function swarm(opts: SwarmOptions): Runner<{
message: string;
}, string>;