wait_for
Blocks execution until an agent reaches a specified state (ready, done, error) with retroactive checking and timeout control.
Instructions
Block until an agent reaches a target state (ready, done, error). Checks retroactively first.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| agent_id | Yes | Agent ID from spawn_agent | |
| target_state | Yes | State to wait for | |
| timeout_ms | No | Timeout in milliseconds (default: 5 minutes) |
Implementation Reference
- src/agent-engine.ts:406-478 (handler)The core logic for waitFor which checks agent states and manages waiting/timeouts.
async waitFor( agentId: string, targetState: AgentState, timeoutMs: number, ): Promise<WaitResult> { const start = Date.now(); // Check if agent exists const initial = this.registry.get(agentId); if (!initial) { throw new Error(`Agent not found: ${agentId}`); } // Retroactive check — already in target state? if (initial.state === targetState) { return { matched: true, state: initial.state, elapsed: Date.now() - start, source: "immediate", }; } // Already in terminal error state and target isn't error? if (initial.state === "error" && targetState !== "error") { return { matched: false, state: initial.state, elapsed: Date.now() - start, source: "immediate", error: initial.error ?? "Agent is in error state", }; } // Already in terminal done state and target isn't done? if (initial.state === "done" && targetState !== "done") { return { matched: false, state: initial.state, elapsed: Date.now() - start, source: "immediate", error: "Agent has already completed", }; } // Polling sweep loop return new Promise<WaitResult>((resolve) => { const checkInterval = setInterval(async () => { const elapsed = Date.now() - start; if (elapsed >= timeoutMs) { clearInterval(checkInterval); const current = this.registry.get(agentId); resolve({ matched: false, state: current?.state ?? "error", elapsed, source: "timeout", error: `Timed out after ${timeoutMs}ms waiting for state "${targetState}"`, }); return; } // Re-read from disk (another process may have updated) await this.registry.reconcile(); const current = this.registry.get(agentId); if (!current) { clearInterval(checkInterval); resolve({ matched: false, state: "error", elapsed, source: "sweep", error: "Agent disappeared during wait", - src/server.ts:716-745 (registration)MCP tool registration for the 'wait_for' tool in src/server.ts.
// 12. wait_for server.tool( "wait_for", "Block until an agent reaches a target state (ready, done, error). Checks retroactively first.", { agent_id: z.string().describe("Agent ID from spawn_agent"), target_state: z .enum(["ready", "working", "idle", "done", "error"]) .describe("State to wait for"), timeout_ms: z .number() .int() .positive() .optional() .default(300000) .describe("Timeout in milliseconds (default: 5 minutes)"), }, async (args) => { try { const result = await engine.waitFor( args.agent_id, args.target_state, args.timeout_ms, ); return ok({ ...result }); } catch (e) { return err(e); } }, );