import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@gajae-code/agent-core"; import * as z from "zod/v4"; import type { AgentProgress, AgentSource, LocalErrorSummary } from "../task/types"; import type { ToolSession } from "./index"; declare const subagentSchema: z.ZodObject<{ action: z.ZodEnum<{ await: "await"; cancel: "cancel"; inspect: "inspect"; list: "list"; pause: "pause"; resume: "resume"; steer: "steer"; }>; ids: z.ZodOptional>; id: z.ZodOptional; message: z.ZodOptional; pause: z.ZodOptional; condition: z.ZodOptional>; heartbeat_ms: z.ZodOptional; timeout_ms: z.ZodOptional; limit: z.ZodOptional; verbosity: z.ZodOptional>; }, z.core.$strip>; type SubagentParams = z.infer; type SubagentStatus = "running" | "paused" | "queued" | "completed" | "failed" | "cancelled" | "not_found" | "already_completed"; export interface SubagentSnapshot { id: string; jobId: string; status: SubagentStatus; label: string; agent: string; agentSource: AgentSource; description?: string; assignment?: string; durationMs: number; resultText?: string; errorText?: string; /** Safe setup failure cause retained from the executor launch path. */ setupFailureSummary?: string; /** Safe, bounded summary of a terminal local (non-provider) failure (e.g. local_buffer_overflow). */ localErrorSummary?: LocalErrorSummary; resultPreview?: string; outputRef?: string; truncated?: boolean; guidance?: string; steerMessage?: string; steerState?: "queued" | "resume_queued" | "resume_started"; steerPauseRequested?: boolean; /** Bounded live progress approved for the await panel and public tool details. */ progress?: SubagentLiveProgress; /** True when a live in-session progress producer exists for this subagent. */ liveProgressAvailable?: boolean; /** Model the subagent actually runs on (after any auth fallback). */ effectiveModel?: string; /** Model originally requested via role/preset mapping; differs from effective on fallback. */ requestedModel?: string; /** True when the requested model lacked credentials and fell back to the parent model. */ modelFellBack?: boolean; /** True when the effective subagent provider is in fast mode. */ fastMode?: boolean; } /** * Public await-panel progress. This is deliberately not `AgentProgress`: raw * progress contains model deltas, tool arguments, arbitrary output, and nested * task payloads that must never enter tool-result, ACP, or telemetry envelopes. */ export interface SubagentLiveProgress { id: string; status: AgentProgress["status"]; currentTool?: string; recentTool?: string; recentOutputSummary?: { lineCount: number; }; fastMode?: boolean; retryState?: { attempt: number; maxAttempts: number; unbounded?: boolean; kind: NonNullable["kind"]; provider?: string; lastProviderProgressAtMs?: number; delayMs: number; startedAtMs: number; }; retryFailure?: { attempt: number; }; } export type SubagentAwaitOutcome = "completed" | "timed_out" | "interrupted"; export interface SubagentToolDetails { subagents: SubagentSnapshot[]; /** Await outcome for a live await receipt; omitted when no wait was started. */ awaitOutcome?: SubagentAwaitOutcome; waitOutcome?: "completed" | "timed_out_wait" | "interrupted"; condition?: "all_terminal" | "any_terminal"; heartbeatMs?: number; terminalIds?: string[]; acknowledgedTerminalIds?: string[]; /** True only when the parent await was interrupted; the child was not cancelled. */ interrupted?: true; } export declare class SubagentTool implements AgentTool { #private; private readonly session; readonly name = "subagent"; readonly label = "Subagent"; readonly summary = "Manage detached task subagents"; readonly description: string; readonly parameters: z.ZodObject<{ action: z.ZodEnum<{ await: "await"; cancel: "cancel"; inspect: "inspect"; list: "list"; pause: "pause"; resume: "resume"; steer: "steer"; }>; ids: z.ZodOptional>; id: z.ZodOptional; message: z.ZodOptional; pause: z.ZodOptional; condition: z.ZodOptional>; heartbeat_ms: z.ZodOptional; timeout_ms: z.ZodOptional; limit: z.ZodOptional; verbosity: z.ZodOptional>; }, z.core.$strip>; readonly strict = true; readonly loadMode = "discoverable"; /** Test-only seam: substitute the liveness clock. Returns a restore function. */ withLivenessClock(nowMs: () => number): () => void; constructor(session: ToolSession); execute(_toolCallId: string, params: SubagentParams, signal?: AbortSignal, onUpdate?: AgentToolUpdateCallback, _context?: AgentToolContext): Promise>; } export declare function capCodePointsAndBytes(text: string, maxCodePoints: number, maxBytes: number): string; /** * Canonical, value-based rendered-state signature for the `subagent` await panel. * * Producer-side await gating compares this signature against the last emitted one * and only fires `onUpdate` when the *rendered* state actually changed. Unchanged * idle ticks therefore stop rebuilding the renderer component and stop mutating * transcript lines above the viewport, which is what triggers TUI full-redraw * storms (`tui.ts` `firstChanged < viewportTop`). * * It is deliberately value-based, never object identity: `AsyncJobManager.record- * SubagentProgress` stores a `structuredClone` but `getSubagentProgress` returns * the retained object by reference, so identity comparison would be both noisy and * unsafe. * * Time-derived fields are intentionally excluded so the panel does not churn while * idle: raw durations (`durationMs`), current-tool elapsed (`currentToolStartMs`), * and retry countdowns (`retryState.startedAtMs`) are omitted. Idle duration and * countdown ticking is sacrificed by design; every real transition still changes * the signature. */ export declare function subagentAwaitRenderedStateSignature(subagents: readonly SubagentSnapshot[], receipt?: Pick): string; export {};