Quickstart¶
Install¶
npm install @ai-for-dev/combo # the library
pi install npm:@ai-for-dev/combo # the same package, loaded into pi
Node 23.6 or later is required: it runs TypeScript natively, and there is no
build step. The package ships the TypeScript it was written in, and tsc is
used only to typecheck.
From a clone, the same three commands the CI runs:
npm install
npm test # offline, no network calls
npm run typecheck
A model is needed for anything that actually talks to a provider. pi resolves it
the usual way, and the examples take --model on the command line:
node examples/01-run.ts --model local/qwen/qwen3-coder-next
Not every provider reports tokens. When one does not, the usage lines read 0,
and that is deliberate: nothing here is estimated by counting characters. See
Measurements.
One subagent, one task¶
The high level form is disposable: it spawns, asks, and closes.
import { findAgent, loadAgents, run } from "@ai-for-dev/combo";
const agents = loadAgents();
const scout = findAgent(agents, "scout");
const result = await run(scout, "Find the authentication code");
console.log(result.output);
console.log(result.usage.turns, result.usage.input, result.usage.cost);
run never throws on a model failure. It returns a Result with ok: false
and an error, and the usage it managed to spend is still filled in.
A subagent that remembers¶
The low level form gives you the object, and you decide how long it lives.
import { spawn } from "@ai-for-dev/combo";
const coder = await spawn(coderAgent, { lifetime: "workflow" });
try {
await coder.ask("Implement the parser");
await coder.ask("Apply these remarks: …"); // it remembers the previous turn
console.log(coder.usage); // cumulative since spawn
} finally {
await coder.close();
}
Whoever opens, closes. The finally is not decoration: an undisposed session
leaks, and closing is also what triggers an export when one was asked for.
Read Lifetime before choosing anything other than the default.
A workflow¶
Combinators take agents and give back results. They compose because they all
speak the same Result.
import { chain, fanOut, loop, saysWord } from "@ai-for-dev/combo";
await chain({ steps: [scout, reviewer], input: "Explain how usage is measured" });
await fanOut({ agent: scout, tasks: ["find A", "find B", "find C"], concurrency: 2 });
await loop({
steps: [coder, reviewer],
input: "Implement the parser",
until: (step) => saysWord(step.output, "LGTM"),
lifetime: "workflow",
});
Set a deadline on anything unattended. There is no default one, and pi’s agent loop has no step cap:
await fanOut({ agent: scout, tasks, timeoutMs: 60_000 }); // per branch, not total
Workflows covers every combinator.
From pi¶
pi -e extension # this session only
pi install ./extension # permanently, via settings
Then, in the TUI:
> /run build add a slugify helper with tests
> use subagent with scope "project" and agent "scout" to find the auth code
The demo agents of this repository live in .pi/agents/, which is
repository-controlled content and therefore never loaded by default - hence the
explicit scope. See Agents and Extension.
Next¶
Agents - write your own.
Workflows - the shapes available.
Deliver a change - the whole build, from a request to a finished working tree.