/** * The body of the `subagent` tool: argument → combinator → result. * * It lives apart from `index.ts` for one reason: **everything it touches is * injectable**. Loading the agents, spawning, the herdr reporter and the widget * surface all arrive as parameters, so the path that wires the reporters and * calls the combinators can be tested offline - like the combinators * themselves. The three bugs that reached the user through this path (an * `undefined` model API, a herdr reporter nobody subscribed, an `openInHerdr` * silently dropped) were all invisible to a green suite because this code had * no seam. * * `index.ts` keeps what genuinely needs a terminal: the renderers. */ import { loadFlowCatalogue, type Agent, type AgentScope, type EventListener, type LivePlan, type Result, type SpawnFn, type SubagentSnapshot } from "../src/index.ts"; import { type Mode, type Params } from "./params.ts"; import type { ToolDeps } from "./pi.ts"; /** What `renderResult` needs, and nothing the LLM has to read. */ export type Details = { mode: Mode; subagents: SubagentSnapshot[]; wallMs: number; converged?: boolean; iterations?: number; /** For route and orchestrate: what the deciding agent chose. */ decision?: string; /** Where the run was exported, when one was asked for. */ exportDir?: string; /** A flow's run directory, which `/run resume` takes. */ runDir?: string; /** A flow's last frame. */ live?: LivePlan; /** A flow's line on how its run ended. */ end?: string; }; /** The tool's final answer: what the model reads, plus what the renderers draw. */ export type ToolOutput = { content: { type: "text"; text: string; }[]; details: Details; }; /** Everything the tool body reaches for: what pi handed it, and what a test may replace. Defaults are the real thing. */ export type ExecuteDeps = Partial & { /** Defaults to reading the agent directories from disk. */ loadAgents?: (options: { cwd?: string; scope?: AgentScope; builtin?: boolean; }) => Agent[]; /** Where `flow` mode finds its flows and the agents they name. Defaults to reading them from disk. */ loadFlowCatalogue?: typeof loadFlowCatalogue; /** Defaults to the real `spawn`, through the combinators. */ spawn?: SpawnFn; /** * A second observer beside the TUI picture. Defaults to the herdr * reporter, which is `undefined` unless pi itself runs inside herdr. */ reporter?: EventListener; /** Widget repaint period. `0` disables the timer - tests want that. */ tickMs?: number; /** Where an export lands, and a flow runs. Defaults to a fresh `runs//`. */ runDir?: () => string; }; /** * Runs one `subagent` tool call. * * Never throws for a workflow failure: a failed subagent comes back as a * `Result` with `ok: false`. It does throw for a caller error - an unknown * agent, a missing `steps` - because that is a programming mistake, not a * result. */ export declare function executeSubagent(params: Params, deps?: ExecuteDeps): Promise; /** What the model gets back: the outputs, plainly labelled. */ export declare function textForModel(results: Result[], converged?: boolean, iterations?: number): string; //# sourceMappingURL=execute.d.ts.map