import { type TSchema } from "@sinclair/typebox"; import type { HarnessRegistry } from "#src/harness/registry"; import type { LifecycleRegistry } from "#src/lifecycle-controller"; import type { ParentContextCapture } from "#src/parent-context"; import type { SpawnQueue } from "#src/spawn-queue"; import { type TmuxManager } from "#src/tmux-manager"; import type { SubagentTracker } from "#src/tracker"; /** * Subagent tool — core execute logic and parameter schema. * * Spawns one or more subagents as real coding agents in detached tmux * windows, one call per array element. A single spawn is a one-element * `agents` array; N spawns fan out in parallel via `Promise.allSettled`, * each element resolving its own routing/guard/sandbox/style from its * `subagent_type` (batch-spawn-tool D5). Parent context is captured ONCE * for the whole batch when `inherit_context: true` and forked to every * element (D4). The `max-concurrent-agents` cap is the sole bound on batch * size — each element's `spawnSubagent` call atomically checks-and-reserves * against the spawner's existing per-parent counter; surplus elements * surface as structured per-element failures (D3). No tool-layer cap * precomputation. * * Host-neutral: pi's `defineTool`/`Text` rendering wrapper lives in * `src/host/pi/tools/subagent.ts`. Extracting parent conversation history * out of a host's session context is host-specific too — it's injected as * the `captureContext` dependency rather than imported directly (design D7). * * Resume was extracted to a dedicated `resume_subagent` tool * (`src/tools/resume.ts`) — it has no batch analogue and never fit a spawn * tool's schema (batch-spawn-tool D2). */ export declare const SUBAGENT_TOOL_NAME: "subagent"; type ToolExecuteResult = { content: { type: "text"; text: string; }[]; details: unknown; }; export interface SubagentToolSpec { name: typeof SUBAGENT_TOOL_NAME; label: string; description: string; parameters: TParams; execute: (toolCallId: string, params: Record, signal: AbortSignal | undefined, onUpdate: ((update: unknown) => void) | undefined, ctx: unknown) => Promise; } /** * Build the subagent tool's spec: description/parameters (enriched from the * configured agent roles) plus the bound execute closure. * * @param parentSessionLabel - When provided, included in spawn details so * the LLM knows which tmux session to target. * @param captureContext - Host-specific extraction of parent conversation * history out of the raw tool-execute `ctx`. Omitted on hosts that don't * support session introspection (inherit_context then reports unavailable). */ export declare function buildSubagentToolSpec(configDir: string, parentSessionId: string, tracker: SubagentTracker, tmux: TmuxManager, harnessRegistry: HarnessRegistry, abortSignal?: AbortSignal, parentSessionLabel?: string, registry?: LifecycleRegistry, captureContext?: (ctx: unknown) => ParentContextCapture | { warning: string; }, spawnQueue?: SpawnQueue, lookupContextWindow?: (provider: string | undefined, model: string | undefined) => number | undefined): { name: "subagent"; label: string; description: string; parameters: import("@sinclair/typebox").TObject<{ agents: import("@sinclair/typebox").TArray; thinking: import("@sinclair/typebox").TOptional; max_turns: import("@sinclair/typebox").TOptional; worktree_branch: import("@sinclair/typebox").TOptional; }>>; inherit_context: import("@sinclair/typebox").TOptional; backend: import("@sinclair/typebox").TOptional; restart_policy: import("@sinclair/typebox").TOptional; }>; execute: (toolCallId: string, params: Record, signal: AbortSignal | undefined, _onUpdate: ((update: unknown) => void) | undefined, ctx: unknown) => Promise; }; /** * Combine multiple optional AbortSignals into a single signal that aborts * when any of the inputs abort. Returns undefined if no signals provided. * Exported for reuse by the resume tool (batch-spawn-tool D2). */ export declare function combineSignals(signals: (AbortSignal | undefined)[]): AbortSignal | undefined; /** * Build the minimal model-channel text returned to the LLM after spawning a * single agent (subagent-tool-output: model channel carries only what the * model needs to act). The id is all the model needs to steer/retrieve * later; the wait-for-nudge contract lives once in the tool description, and * the attach hint / session details ride the `details` UI channel * (`buildSpawnDetails`). Exported for the poll-discipline message tests. */ export declare function buildMetaText(agentId: string, tracker: SubagentTracker, _parentSessionLabel?: string): string; /** * Build the structured one-line batch result for the model channel * (batch-spawn-tool D6). Successes are keyed by their real agent id (the * actionable handle for `get_subagent_result` / `steer_subagent`); failures * are keyed by their 1-indexed array position (a failed spawn's allocated * uuid is orphaned — no tracker record, no session — so the position is the * only stable identifier the model can map back to its input). */ export declare function buildBatchMetaText(successes: { id: string; role: string; }[], failures: { position: number; reason: string; }[], total: number): string; /** * Presentation-only spawn details for the UI/`details` channel (never the model * `content`): the attach hint, session/window, role, and parent label. Consumed * by the pi render wrapper to draw a compact chip and surface the attach command * on expand. Display-only — the attach hint is never parsed for targeting. */ export declare function buildSpawnDetails(agentId: string, tracker: SubagentTracker, parentSessionLabel?: string): { kind: "spawn"; agentId: string; role: string; sessionName?: string; windowIndex?: string; attachHint?: string; parentSessionLabel?: string; sandboxStatus?: "enforced" | "degraded"; sandboxReason?: string; }; export {}; //# sourceMappingURL=subagent.d.ts.map