import type { LlmClient, ContentBlock } from "../llm/types.js";
import type { BrowserActions } from "../browser/actions.js";
import { type MemoryManager } from "./memory.js";
import type { StoreManager } from "./store.js";
import type { Scheduler } from "./scheduler.js";
import type { SkillGenerator } from "./skill-generator.js";
import type { ImageGenerator } from "./image-generator.js";
import type { OrgManager } from "./org-manager.js";
import type { DipclawConfig } from "../config/types.js";
import type { AttachmentSender, ProgressNotifier } from "./agent-types.js";
export type ChatInput = string | ContentBlock[];
export interface ChatEngineDeps {
    llmClient: LlmClient;
    browserActions: BrowserActions;
    memory: MemoryManager;
    store: StoreManager;
    scheduler: Scheduler;
    skillGenerator: SkillGenerator;
    imageGenerator: ImageGenerator | null;
    orgManager: OrgManager | null;
    /** Org section of the active config; used for system prompt + executor. */
    orgConfig: DipclawConfig["org"];
    /** LLM protocol of the active config; used to tune the loop detector. */
    llmProtocol: DipclawConfig["llm"]["protocol"];
    workspace: string;
    agentName: string;
    maxIterations: number;
    /**
     * Resolved on each call so the frontend can attach/detach without
     * re-wiring the engine.
     */
    getAttachmentSender: () => AttachmentSender | null;
    getProgressNotifier: () => ProgressNotifier | null;
}
/** Short loggable preview of chat input (string or multimodal). */
export declare function summarizeChatInput(message: ChatInput): string;
/**
 * Owns the LLM chat loop: history, tool dispatch, summarization, system
 * prompt assembly. The browser lock and per-turn logging are intentionally
 * NOT here — they belong to the caller (Agent) so the same engine can be
 * shared if we ever spawn a second chat surface.
 */
export declare class ChatEngine {
    private deps;
    private chatHistory;
    private contextState;
    private transcript;
    private summarizationCooldown;
    /**
     * Identifies this chat as a logical session to the upstream gateway
     * (e.g. sub2api's sticky-session router). Regenerated on every reset()
     * so a cleared conversation gets a new sticky binding.
     */
    private sessionId;
    constructor(deps: ChatEngineDeps);
    /** Clear chat history and earlier-summary context. */
    reset(): void;
    /** For logging metadata — how many messages currently in history. */
    getHistoryLength(): number;
    /** Non-streaming chat turn. Returns the final assistant text. */
    chat(message: ChatInput): Promise<string>;
    /** Streaming chat turn. Yields text deltas; tool calls happen between yields. */
    chatStream(message: ChatInput): AsyncIterable<string>;
    private executeToolCall;
    private estimateHistoryChars;
    private pushHistory;
    /**
     * Compress chat history into structured context state. Raw messages are
     * always retained in the transcript; if summarization fails we keep the live
     * history until the hard limit requires a last-resort trim.
     */
    private compressHistory;
    /**
     * Drop old messages at user-message boundaries to fit budget. Fallback
     * when summarization is unavailable.
     */
    private simpleTrim;
    private buildRequestForLlm;
    /**
     * Translate the static/dynamic split into LLM provider cache hints. Anthropic
     * uses these for explicit cache_control breakpoints; OpenAI ignores them.
     */
    private cacheHintsFor;
    private loadChatMemoryIndex;
    private loadInstalledSkillsIndex;
    private buildChatSystemPrompt;
}
