workflows/pool¶
Source: src/workflows/pool.ts
The pool: where a workflow’s turns are played.
A combinator says who speaks and what it is asked. The pool does the rest - who is spawned, who is reused, who is closed, with which signal and deadline every turn runs, and what the turns add up to. That is written here once, so that a combinator cannot forget half of it.
Held¶
type
export type Held = {
/** The subagent's id, which is its name wherever it is addressed. */
readonly id: string;
/** One turn, with the workflow's `signal` and `timeoutMs`. */
ask(task: string): Promise<Result>;
};
A subagent held for a conversation.
What a caller gets from {@link SubagentPool.hold}: enough to address it and
to ask it several things in a row, with the workflow’s signal and deadline
on every turn. Not the Subagent itself - closing it stays the pool’s job.
A hold refused on a signal already aborted is addressed by its key, and
every ask answers the same refusal without spawning anything.
SubagentPool¶
class
export class SubagentPool {
readonly trail: Trail;
async turn(agent: Agent, task: string, options: TurnOptions = {}): Promise<Result> { /* … */ }
async hold(agent: Agent, options: TurnOptions = {}): Promise<Held> { /* … */ }
async closeAll(): Promise<void> { /* … */ }
}
Holds the subagents a workflow created, plays their turns, and closes them all.
The lifetime rule lives here, in one place, and it is decided per agent:
the workflow’s lifetime when it names one, else the agent’s frontmatter,
else "task".
"task": a fresh subagent per turn, closed as soon as the turn is over.anything else: one subagent per key, reused, closed at the end.
A held subagent is the exception: a conversation is not a task, so it lives until {@link closeAll} whatever the lifetime.
TurnOptions¶
type
export type TurnOptions = {
/**
* Who shares a memory. Defaults to the agent's name.
*
* In a persistent lifetime, two turns under one key reach the same
* subagent: a chain keys by name so the same reviewer comes back with its
* remarks in mind. A fan-out keys by branch, because two branches must never
* share a context.
*/
key?: string;
};
Which subagent a turn goes to.