workflows/route¶
Source: src/workflows/route.ts
route: 1 → 1. A classifier agent picks who should do the work.
pickDestination¶
function
export function pickDestination(output: string, destinations: readonly Agent[]): Agent | undefined { /* … */ }
Reads a destination out of whatever the classifier actually wrote.
The input here is a language model, not a caller, so this is lenient on
purpose - and only here. It tries, in order: the whole answer as a name, the
last non-empty line, then the first name mentioned anywhere. Matching is on
whole words, so coder never matches inside decoder.
Ambiguity is refused rather than guessed: an answer naming two destinations on its last line resolves to nothing, and the caller sees what was said.
route¶
function
export async function route(options: RouteOptions): Promise<RouteResult> { /* … */ }
Classifies a task, then hands it to the destination that was picked.
The classifier reads the destinations’ descriptions - the field pi already makes mandatory - so routing needs no second vocabulary to maintain. Write a description that says when to pick that agent and routing works; write a vague one and no parser will save it.
An unroutable task is a Result, not a throw. A classifier that answers
with prose, or names an agent that does not exist, is a model failure like any
other: with a fallback the work still happens, without one the caller gets
ok: false and the classifier’s actual answer to look at. What never happens
is a silent pick of the first destination.
RouteOptions¶
type
export type RouteOptions = WorkflowOptions & {
/** The agent that classifies. It sees the destinations, never the work. */
router: Agent;
/** Where the task may go. Their `description` is what the classifier reads. */
destinations: Agent[];
/** The work to route. The classifier is asked about it; only the destination does it. */
input: string;
/** Taken when the classifier names nothing recognisable. */
fallback?: Agent;
/** Overrides how the classifier's answer is read. See {@link pickDestination}. */
parse?: (output: string, destinations: readonly Agent[]) => Agent | undefined;
/** Overrides the question put to the classifier. See {@link routingPrompt}. */
format?: (input: string, destinations: readonly Agent[]) => string;
};
The classifier, the agents it may pick from, and what to do when it picks nobody.
RouteResult¶
type
export type RouteResult = WorkflowResult & {
/** Who was chosen, or `undefined` when nothing was. */
destination?: Agent;
/** The classifier's own turn, kept even when the routing failed. */
routing: Result;
};
The destination’s result, plus who was picked and how.
routingPrompt¶
function
export function routingPrompt(input: string, destinations: readonly Agent[]): string { /* … */ }
The question put to the classifier: the destinations, then the task.
It asks for the name alone. That is a hint, not a contract - {@link pickDestination} is what actually makes the answer usable.