/**
 * Pure agent typeszero I/O framework dependencies.
 *
 * Wire-level types (ChatMessage, ToolDefinition) are canonical in
 * protocol/wire/. This file re-exports them and adds
 * internal-only extensions (e.g. backfillObservableInput on ToolDefinition).
 */
import type { SkillInstruction } from "../orchestration/index.js";
import type { HookRegistry } from "../contracts/hooks.js";
import type { AccumulatedToolCall, LLMChunk, LLMRequest, LLMTransport } from "../runtime/ports/index.js";
import type { ChatMessage as WireChatMessage, ChatMessageRole as WireChatMessageRole, ThinkingBlock as WireThinkingBlock, ToolCallMessage as WireToolCallMessage, ToolDefinition as WireToolDefinition, WireTokenUsage } from "../protocol/wire/index.js";
export type ChatMessageRole = WireChatMessageRole;
export type ThinkingBlock = WireThinkingBlock;
export type ToolCallMessage = WireToolCallMessage;
export type ChatMessage = WireChatMessage;
export type { AccumulatedToolCall, LLMChunk, LLMRequest, LLMTransport, };
export type MediaCapability = "image" | "video" | "music" | "music_realtime" | "tts" | "3d" | "stt" | "embedding" | "video_understanding" | "image_understanding" | "voice_clone" | "rerank" | "document_parsing" | "realtime_audio" | "realtime_video";
export interface ToolDefinition extends WireToolDefinition {
    /**
     * Backfill derived/legacy fields onto a shallow copy of the tool input
     * before hooks and observers see it (CC backfillObservableInput parity).
     * The original API-bound input is never modified.
     * Internal-onlynever serialized over JSON-RPC.
     */
    backfillObservableInput?: (input: Record<string, unknown>) => void;
}
/**
 * Token usageunified with WireTokenUsage from contracts.
 * No more internal/wire split: all code uses the same field names
 * (inputTokens, outputTokens, reasoningTokens, cacheRead, cacheWrite).
 */
export type TokenUsage = WireTokenUsage;
/**
 * Why the previous iteration continuedeach variant corresponds to one of
 * the 7 `continue` sites in the main while(true) loop.
 * Tests can assert recovery paths fired without inspecting message contents.
 */
export type ToolLoopTransition = {
    reason: "collapse_drain_retry";
    committed: number;
} | {
    reason: "reactive_compact_retry";
} | {
    reason: "max_output_tokens_escalate";
} | {
    reason: "max_output_tokens_recovery";
    attempt: number;
} | {
    reason: "stop_hook_blocking";
} | {
    reason: "token_budget_continuation";
} | {
    reason: "next_turn";
};
/** Terminal exit reasons from the tool loop. */
export type ToolLoopTerminal = {
    reason: "completed";
} | {
    reason: "aborted";
} | {
    reason: "prompt_too_long";
} | {
    reason: "image_error";
} | {
    reason: "model_error";
    error?: unknown;
} | {
    reason: "max_turns";
} | {
    reason: "budget_exhausted";
} | {
    reason: "tool_loop_limit";
} | {
    reason: "stop_hook_prevented";
} | {
    reason: "hook_stopped";
};
export interface TurnRequest {
    turnId: string;
    sessionId: string;
    messages: ChatMessage[];
    tools: ToolDefinition[];
    systemPrompt?: string;
    config?: TurnConfig;
}
export interface TurnConfig {
    /**
     * Model purpose to resolve from the registry for this turn.
     * Defaults to textGeneration. Focused media-understanding turns can override
     * this so the main loop uses a vision/video model instead of a text model
     * trying to fetch media URLs as plain text.
     */
    modelPurpose?: "textGeneration" | "imageUnderstanding" | "videoUnderstanding";
    /** LLM provider id, e.g. "deepseek" */
    provider?: string;
    /** Model id, e.g. "deepseek-v4-flash" */
    model?: string;
    /** User API key */
    apiKey?: string;
    /** Optional base URL override */
    baseUrl?: string;
    /** Max tool-call rounds per turn (default 25, max 100) */
    maxRounds?: number;
    /** Temperature override */
    temperature?: number;
    /** Context window size in tokens (for turn-loop-guard budget checks) */
    contextWindowTokens?: number;
    /** Max output tokens for current model */
    maxOutputTokens?: number;
    /** Model's absolute max output tokens (for escalation ceiling) */
    modelMaxOutputTokens?: number;
    /** Tool choice strategy: "auto" (default), "none", "required" */
    toolChoice?: "auto" | "none" | "required";
    /** Parent fork depth (0 = top-level, default 0). CC: depth tracking for fork recursion limit. */
    parentDepth?: number;
    /** Per-turn token budget (prompt + completion). 0 or undefined = unlimited. */
    tokenBudget?: number;
    /** Fallback model to switch to after repeated 529 errors (CC parity). */
    fallbackModel?: string;
    /** Max turns (tool loop iterations). 0 or undefined = use maxRounds. */
    maxTurns?: number;
    /** Max concurrent tool executions (0 = unlimited). */
    maxConcurrentTools?: number;
    /** Model requires streamingdisable non-streaming fallback. */
    streamRequired?: boolean;
    /** Reasoning effort for models that support it (GPT-5.x, o-series). */
    reasoning?: {
        effort: "minimal" | "low" | "medium" | "high" | "xhigh";
        includeEncryptedReasoning?: boolean;
    };
    /** Prompt cache bucketing key used instead of the provider-level `user` field. */
    promptCacheKey?: string;
    /** Prompt cache retention: "in_memory" (5-10min) or "24h". */
    promptCacheRetention?: "in_memory" | "24h";
    /** Service tier: "auto", "default", "flex" (50% cheaper), "priority". */
    serviceTier?: "auto" | "default" | "flex" | "priority";
    /** OpenAI Responses API built-in tools to inject. */
    openaiBuiltinTools?: Array<{
        type: "web_search_preview" | "file_search" | "code_interpreter" | "computer_use_preview";
        [key: string]: unknown;
    }>;
    /** Max builtin tool calls per turn (shared across all builtin tools). */
    maxToolCalls?: number;
    /** Disable parallel tool calling (force sequential). */
    parallelToolCalls?: boolean;
    /** Text output verbosity hint: "low", "medium", "high". */
    textVerbosity?: "low" | "medium" | "high";
    /**
     * User-designated provider+model per media category.
     * Each entry maps a media type (image/video/music/tts/3d/...) to
     * the specific provider and model the user chose. No failover
     * if the designated provider fails, the error propagates directly.
     */
    mediaProviders?: Partial<Record<MediaCapability, {
        provider: string;
        model: string;
    }>>;
    /** MCP server configurations (stdio/sse/http). Passed from host to agent per-turn. */
    mcpServers?: Record<string, unknown>;
}
export type TurnEvent = {
    type: "start";
    turnId: string;
} | {
    type: "delta";
    turnId: string;
    text: string;
} | {
    type: "tool_call";
    turnId: string;
    callId: string;
    name: string;
    arguments: string;
    inputSummary?: string;
} | {
    type: "end";
    turnId: string;
    content: string;
    usage?: TokenUsage;
    model?: string;
    provider?: string;
    /** Per-turn recovery trace (action -> count); present only when recoveries fired. */
    recoveryTrace?: Record<string, number>;
} | {
    type: "error";
    turnId: string;
    error: string;
    code?: string;
    usage?: TokenUsage;
} | {
    type: "skill_instruction";
    turnId: string;
    instruction: SkillInstruction;
} | {
    type: "tool_result";
    turnId: string;
    callId: string;
    name: string;
    ok: boolean;
    error?: string;
    outputPreview?: string;
    durationMs?: number;
    exitCode?: number;
    stdout?: string;
    stderr?: string;
    details?: Record<string, unknown>;
} | {
    type: "tool_blocked";
    turnId: string;
    callId: string;
    name: string;
    reason: string;
} | {
    type: "recovery";
    turnId: string;
    action: string;
    detail?: string;
} | {
    type: "plan_update";
    turnId: string;
    slug: string;
    content: string;
} | {
    type: "heartbeat";
    turnId: string;
    message: string;
} | {
    type: "tool_use_summary";
    turnId: string;
    summary: string;
} | {
    type: "reasoning_delta";
    turnId: string;
    text: string;
} | {
    type: "suggestions";
    turnId: string;
    items: Array<{
        text: string;
        icon?: string;
        action?: string;
    }>;
} | {
    type: "media_result";
    turnId: string;
    mediaType: "image" | "tts" | "video" | "music" | "3d";
    url: string;
    model?: string;
    provider?: string;
    durationSeconds?: number;
    width?: number;
    height?: number;
    mimeType?: string;
    billingUnit?: string;
    billingQuantity?: number;
    taskId?: string;
} | {
    type: "artifact";
    turnId: string;
    artifactId: string;
    artifactType: "code" | "file" | "image" | "document" | "diagram" | "table";
    title: string;
    filePath?: string;
    language?: string;
    content?: string;
    mimeType?: string;
} | {
    type: "annotations";
    turnId: string;
    annotations: Array<{
        type: string;
        url?: string;
        title?: string;
        [key: string]: unknown;
    }>;
} | {
    type: "subagent_started";
    turnId: string;
    subagentId: string;
    agentType: string;
    prompt?: string;
} | {
    type: "subagent_ended";
    turnId: string;
    subagentId: string;
    agentType: string;
    ok: boolean;
    outputPreview?: string;
    error?: string;
};
/**
 * ToolInvoker: request tool execution from the host process (Gateway).
 * In CLI mode this sends a JSON-RPC notification over stdio and waits for result.
 */
export interface ToolInvoker {
    invoke(turnId: string, name: string, args: string, signal?: AbortSignal): Promise<{
        result: string;
        error?: string;
        toolReferences?: string[];
        imageUrls?: string[];
        details?: Record<string, unknown>;
    }>;
}
/**
 * AgentLogger: structured logging interface.
 * In CLI mode this writes to stderr; in Hub mode this uses pino.
 */
export interface AgentLogger {
    info(message: string): void;
    info(obj: Record<string, unknown>, message: string): void;
    warn(message: string): void;
    warn(obj: Record<string, unknown>, message: string): void;
    error(message: string): void;
    error(obj: Record<string, unknown>, message: string): void;
    debug(message: string): void;
    debug(obj: Record<string, unknown>, message: string): void;
}
export type { HookRegistry };
