@tanstack/ai
Version:
Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.
59 lines (58 loc) • 2.52 kB
JavaScript
import { boolean, choice } from "../../evaluate/index.js";
//#region src/activities/chat/agents/route.ts
var ORDER_KEY = "order";
/**
* Build `decide()` questions for a subagent router.
*
* One yes/no question per agent, plus an `order` choice.
* `pick` returns `main`, one name, `{ names, order }`, or `{ steps }`.
* Names follow the `agents` array order.
* `{ names, order }` overrides `subagents.order` for that turn.
* `then`: agents that run after the other selected agents. The lead group
* starts together. The `then` agents then run one after another in list
* order, and each reads the text so far. Used only when the router picks at
* least one agent from each group. Otherwise `pick` returns `{ names, order }`.
*/
function subagentRoute(agents, options) {
const namesInList = new Set(agents.map((agent) => agent.name));
for (const agent of agents) if (agent.name === ORDER_KEY) throw new Error("subagentRoute cannot use an agent named \"order\". Rename that agent.");
for (const name of options?.then ?? []) if (!namesInList.has(name)) throw new Error(`subagentRoute then includes unknown agent "${name}".`);
const questions = { order: choice({
instructions: "When more than one agent runs, how must they run?",
options: {
parallel: "Start them together. Use this when no agent must read text from another agent. Working on the same topic is not a reason to wait.",
sequence: "Run them in agent-list order. Use this only when a later agent must read the earlier agent text, such as research notes and then a draft article."
}
}) };
for (const agent of agents) {
const when = options?.when?.[agent.name];
questions[agent.name] = boolean({ instructions: when ?? agent.description });
}
function pick(result) {
const names = agents.map((agent) => agent.name).filter((name) => result[name].value);
if (names.length === 0) return "main";
const only = names.length === 1 ? names[0] : void 0;
if (only !== void 0) return only;
const later = new Set(options?.then ?? []);
const lead = names.filter((name) => !later.has(name));
const tail = names.filter((name) => later.has(name));
if (lead.length === 0 || tail.length === 0) return {
names,
order: result.order.value
};
return { steps: [lead.length > 1 ? {
names: lead,
order: "parallel"
} : { names: lead }, tail.length > 1 ? {
names: tail,
order: "sequence"
} : { names: tail }] };
}
return {
questions,
pick
};
}
//#endregion
export { subagentRoute };
//# sourceMappingURL=route.js.map