import { type SystemPromptBuilder } from "../prompt/system-prompt.js";
import type { CodeMapResult } from "../indexer/types.js";
import { Session } from "../session/session.js";
import type { CompactionResult } from "../session/session.js";
import { ToolRegistry } from "../tools/registry.js";
import type { AgentConfig, BeforeToolCallHook, ModelClient, OutputSchema } from "./types.js";
/**
 * Content-aware truncation for tool outputs.
 * Different tools benefit from different truncation strategies:
 * - read_file: No truncation — the model needs exact text for edits
 * - run_command: Keep head + tail (50/50). Errors live at the end of
 *   normal failures, but pathological cases (infinite loops, runaway
 *   recursion, excessive logging) reveal themselves at the start. A
 *   tail-heavy split hides the diagnostic bytes for the runaway case.
 * - search: Keep head with a match count footer
 * - default: Keep head (existing behavior)
 */
export declare function truncateToolOutput(toolName: string, output: string, maxChars: number): string;
export type UiUpdateThinking = {
    type: "thinking";
    content: string;
};
export type UiUpdateStreamingChunk = {
    type: "streaming_chunk";
    content: string;
};
export type UiUpdateStep = {
    type: "step";
    step: number;
};
export type UiUpdateToolCallStart = {
    type: "tool_call_start";
    name: string;
    input: Record<string, unknown>;
};
export type UiUpdateToolCallEnd = {
    type: "tool_call_end";
    name: string;
    input: Record<string, unknown>;
    result: string;
    elapsedMs: number;
};
export type UiUpdateContextStatus = {
    type: "context_status";
    contextTokens: number;
    maxContextTokens: number;
};
export type UiUpdate = UiUpdateThinking | UiUpdateStreamingChunk | UiUpdateStep | UiUpdateToolCallStart | UiUpdateToolCallEnd | UiUpdateContextStatus;
export declare class CodingAgent {
    private readonly session;
    private config;
    private readonly modelClient;
    private readonly toolRegistry;
    private readonly getCodeMap;
    private readonly verbose;
    private readonly onProgress;
    private readonly onUiUpdate;
    private readonly onVerbose;
    private readonly getSystemPromptSuffix;
    private readonly buildSystemPrompt;
    private readonly beforeToolCall;
    /**
     * Tracks symbol names the user/agent has been working with.
     * Persists across turns so the code map stays focused on the
     * current area of interest.
     */
    private readonly focusTracker;
    /**
     * Cache of recently read file paths (key: "path:offset:limit") to avoid
     * sending duplicate full file contents through the context window.
     * Maps to the step number when the file was last read.
     */
    private readonly fileReadCache;
    /** Cached system prompt for when dynamic prompts are disabled. */
    private cachedSystemPrompt;
    constructor(params: {
        config: AgentConfig;
        modelClient: ModelClient;
        toolRegistry: ToolRegistry;
        session?: Session;
        getCodeMap?: (focusSymbols?: Set<string>) => CodeMapResult | undefined;
        verbose?: boolean;
        onProgress?: (message: string) => void;
        onUiUpdate?: (event: UiUpdate) => void;
        onVerbose?: (message: string) => void;
        getSystemPromptSuffix?: () => string | undefined;
        /**
         * Replace the default system-prompt builder. Receives the agent's
         * config, the active tools, and the current code-map snippet (when
         * available). Return a string or a Promise<string>. When omitted,
         * minicode's default coding-agent prompt is used.
         *
         * Use this to point the agent at a different domain (review bot,
         * RAG assistant, non-coding use case) without rewriting the rest
         * of the SDK. Import `buildSystemPrompt` from `@sean.holung/minicode-sdk`
         * and call it from your builder to extend the default rather than
         * replace it.
         */
        buildSystemPrompt?: SystemPromptBuilder;
        /**
         * Called before each tool call. Return `{outcome: "deny", reason}` to
         * skip execution; the reason is fed back to the model as the tool's
         * result. Hosts use this to implement permission prompts (web UI
         * modal, CLI confirmation, etc.).
         */
        beforeToolCall?: BeforeToolCallHook;
    });
    private verboseLog;
    getSession(): Session;
    getReasoningEffort(): AgentConfig["reasoningEffort"];
    getContextStatus(): {
        contextTokens: number;
        maxContextTokens: number;
    };
    setReasoningEffort(effort: AgentConfig["reasoningEffort"]): void;
    /**
     * Manually compact the conversation context. Uses LLM-based
     * summarization with `config.compactionModel` if set, otherwise the
     * agent's primary model (`config.model`). Mechanical compaction is
     * the internal fallback inside `compactWithLlm` when the LLM call
     * fails — the result's `method` field tells you which strategy
     * actually ran.
     */
    compactContext(): Promise<CompactionResult | null>;
    private getFocusSet;
    /**
     * Check whether a previously-read file's content is still present in the
     * session context (i.e. hasn't been trimmed/compacted away). We look for
     * a tool message from "read_file" whose content still contains the file
     * path and hasn't been replaced with a summary stub.
     */
    private isFileReadStillInContext;
    /**
     * Run a tool call, gated through `beforeToolCall` if a hook was provided.
     * A `deny` decision short-circuits execution and feeds the hook's reason
     * back to the model as the tool's result, so the model sees the rejection
     * in-band and can choose how to respond.
     */
    private executeToolCall;
    runTurn(userMessage: string, options?: {
        signal?: AbortSignal;
        outputSchema?: OutputSchema;
    }): Promise<{
        text: string;
        output?: unknown;
        usage?: {
            inputTokens: number;
            outputTokens: number;
            cachedInputTokens?: number;
            reasoningTokens?: number;
        };
        /**
         * Most recent step's reasoning content, when the model provided any
         * (Anthropic extended thinking blocks or OpenRouter `message.reasoning`).
         * Surfaced so callers can include it when re-prompting after a failed
         * attempt — e.g. benchmark mode's retry path can feed the model's own
         * prior thinking back so it sees what it was about to do.
         */
        reasoningContent?: string;
        streamed?: boolean;
    }>;
}
//# sourceMappingURL=agent.d.ts.map