import type { AgentSessionLike, AgentStreamMessage } from "./engines/session-types.js";
import type { TerminalReason } from "@anthropic-ai/claude-agent-sdk";
import type { ActivityTracker } from "./activity-tracker.js";
import type { SessionManager } from "./session-manager.js";
import { type ToolTimeoutInfo } from "./tool-call-watchdog.js";
import type { VisionClawConfig } from "../config/types.js";
export type { ToolTimeoutInfo } from "./tool-call-watchdog.js";
/**
 * Result of draining one agent stream to completion. `toolTimeout` is present
 * when the watchdog had to kill a stuck tool call; `finishCalled` reports
 * whether the agent explicitly ended its turn via `mcp__visionclaw__finish`.
 * The wake cycle uses `finishCalled` to distinguish an intentional end-of-turn
 * from an accidental one (e.g. the model produced text and stopped while async
 * subagents were still running).
 */
export interface ProcessAgentStreamResult {
    toolTimeout: ToolTimeoutInfo | null;
    finishCalled: boolean;
}
/**
 * Typed error thrown when the stream is silent for too long.
 * Callers can use `instanceof` to distinguish from other errors.
 */
export declare class StreamSilenceTimeoutError extends Error {
    constructor(silentSeconds: number);
}
export declare class SdkTerminalError extends Error {
    readonly terminalReason?: TerminalReason;
    readonly sdkSubtype?: string;
    constructor(message: string, options?: {
        terminalReason?: TerminalReason;
        sdkSubtype?: string;
    });
}
/**
 * The Claude Agent SDK historically called the subagent-spawn tool `Task`,
 * but newer CLI builds surface it as `Agent` (both names are still possible
 * depending on the pinned executable). Keep the match permissive so subagent
 * progress tracking survives version drift.
 */
export declare function isSubagentSpawnTool(blockName: string): boolean;
type TodoStatus = "pending" | "in_progress" | "completed";
/**
 * Newer Claude CLI builds replace the snapshot-style `TodoWrite` tool with
 * incremental `TaskCreate` / `TaskUpdate` tools. Unlike `TodoWrite` (which
 * sends the full todo array every call), these mutate one task at a time, and
 * `TaskCreate` only returns its generated id in the tool *result* — so we
 * correlate a create call to its result by tool_use_id, then track
 * subject/status by task id. `project()` renders the same `{ content, status }`
 * shape `activityTracker.recordTodos` already consumes, so operator surfaces
 * (/tasks, /status) stay identical regardless of which tool the CLI emits.
 */
export declare class TaskTodoAccumulator {
    private readonly sessionRegistry?;
    private readonly byId;
    private readonly pendingCreates;
    /**
     * Optional session-scoped registry (`taskId → {subject,status}`) shared
     * across turns. When provided, this accumulator mirrors every resolved
     * create / subject-bearing update into it, and consults it to recover the
     * subject for a status-only update whose task was created in a prior turn.
     * Without it the accumulator falls back to #465's behavior (ignore unknown
     * status-only updates), so plain per-stream callers/tests are unaffected.
     */
    constructor(sessionRegistry?: Map<string, {
        subject: string;
        status: TodoStatus;
    }> | undefined);
    /** Mirror a task's latest state into the cross-turn session registry. */
    private remember;
    /** Record a TaskCreate call; its task id is unknown until the result lands. */
    noteCreate(toolUseId: string, input: {
        subject?: unknown;
    }): void;
    hasPendingCreate(toolUseId: string): boolean;
    /** Resolve a TaskCreate result into a tracked task keyed by its id. */
    resolveCreate(toolUseId: string, taskId: string | undefined): boolean;
    /**
     * Apply a TaskUpdate call. Returns true if this stream's projection changed.
     *
     * The SDK's Task state is session-scoped, but this accumulator is scoped to a
     * single `processAgentStream()` call (one turn). So a TaskUpdate may reference
     * a `taskId` whose `TaskCreate` happened in an earlier turn and is therefore
     * unknown to `byId`. To preserve continuity we consult the session registry
     * (when present): a status-only update for such a task recovers its original
     * subject and materializes a proper todo. Only when the task is unknown to
     * both `byId` and the registry, and the update carries no non-empty subject,
     * do we ignore it — that avoids the blank-titled placeholder #465 guarded
     * against clobbering the operator's /tasks view.
     */
    noteUpdate(input: {
        taskId?: unknown;
        subject?: unknown;
        status?: unknown;
    }): boolean;
    /**
     * Project tracked tasks into the activity tracker's todo list shape.
     *
     * When a session registry is present we project from it (not just this
     * stream's `byId`) so /tasks reflects the full set of tasks seen across the
     * session — a status-only update to one prior-turn task must not drop the
     * sibling tasks created alongside it in earlier turns. The registry is an
     * insertion-ordered `Map`, so todos stay in stable creation order. Without a
     * registry we fall back to the per-stream `byId` (unchanged #465 behavior).
     */
    project(): {
        content: string;
        status: TodoStatus;
    }[];
}
/**
 * Pull the generated task id out of a `TaskCreate` tool result. The result
 * content may be a JSON string, a `{ task: { id } }` object, or an array of
 * text content blocks — tolerate all three.
 */
export declare function extractCreatedTaskId(content: unknown): string | undefined;
/**
 * Shape of `system` messages emitted by the async-agent protocol.
 *
 * The SDK currently emits four subtypes — `task_started`, `task_progress`,
 * `task_updated`, and `task_notification` — each sharing `tool_use_id` so we
 * can correlate back to the parent Agent tool_use block that kicked off the
 * async task. We only rely on a small, observed subset of their fields; the
 * full shape is larger.
 */
export interface TaskSystemEvent {
    subtype: "task_started" | "task_progress" | "task_updated" | "task_notification";
    tool_use_id?: string;
    task_id?: string;
    description?: string;
    last_tool_name?: string;
    status?: string;
    summary?: string;
    usage?: {
        tool_uses?: number;
    };
    patch?: {
        status?: string;
    };
}
/**
 * Drive the ActivityTracker from async Agent lifecycle events. Completion is
 * signalled by either `task_updated` with `patch.status === "completed"` /
 * `"failed"` or by a top-level `task_notification` with `status: "completed"`.
 * Progress updates fold in the cumulative tool-use counter and the most
 * recent tool name (preferred) or description.
 *
 * Note: the SDK's `task_updated` events carry ONLY `task_id` — no
 * `tool_use_id`. `task_started`, `task_progress`, and `task_notification`
 * carry both. We therefore stash the `task_id` → `tool_use_id` mapping on
 * `task_started` so that subsequent `task_updated` events can be routed to
 * the right subagent via a `task_id` fallback lookup. Without this, the
 * SDK's completion signal is silently dropped whenever the main agent
 * polls via `wait()` instead of collecting output via `TaskOutput` (the
 * latter is what triggers `task_notification`).
 */
/**
 * Shape of the `system/memory_recall` message emitted by the CLI's
 * auto-memory recall supervisor when it surfaces memory files into the
 * current turn. The CLI's Zod schema (observed via `strings` on the native
 * binary) is roughly:
 *
 *   { type: "system",
 *     subtype: "memory_recall",
 *     mode: "select" | "synthesize",
 *     memories: [{ path, scope, content? }],
 *     uuid, session_id }
 *
 * `content` only appears in `"synthesize"` mode and is a Sonnet-authored
 * distillation; we accept it for completeness but deliberately drop it
 * before storing so /obs doesn't balloon.
 */
export interface MemoryRecallSystemEvent {
    subtype: "memory_recall";
    /** `"select" | "synthesize"` today; typed as plain string for drift safety. */
    mode?: string;
    memories?: {
        path?: string;
        scope?: string;
        content?: string;
    }[];
}
/**
 * Route a CLI `system/memory_recall` event into the ActivityTracker. Skips
 * malformed payloads defensively — the CLI is evolving this shape and we
 * never want a schema drift in an observability path to take the agent
 * loop down.
 */
export declare function handleMemoryRecallEvent(event: MemoryRecallSystemEvent, activityTracker: ActivityTracker): void;
export declare function handleAsyncTaskEvent(event: TaskSystemEvent, subagentByTaskToolUseId: Map<string, {
    subagent_type?: string;
    agentId?: string;
}>, activityTracker: ActivityTracker): void;
/**
 * Process the agent SDK response stream for a single wake cycle.
 * Handles logging, activity tracking, subagent correlation, and
 * detecting the finish tool call.
 *
 * Returns timeout info if the query was aborted due to a tool call timeout,
 * or `null` if the query completed normally.
 */
export declare function processAgentStream(queryStream: AsyncIterable<AgentStreamMessage>, session: AgentSessionLike, activityTracker: ActivityTracker, sessionManager?: SessionManager, config?: VisionClawConfig, silenceTimeoutMs?: number): Promise<ProcessAgentStreamResult>;
//# sourceMappingURL=stream-handler.d.ts.map