import { ComposerDoc } from '../primitives/composer-model';
import { AttachmentData } from './attachments';
import { MessageActionDetail } from '../primitives/message-feedback';
import { TriggerDef } from './composer';
import { ChatMessage } from '../elements/chat-types';
import { ProseSize } from '../primitives/chat-config';
import { ModelOption } from '../types';
export interface ChatThreadContextUsage {
    usedTokens: number;
    maxTokens: number;
    inputTokens?: number;
    outputTokens?: number;
    estimatedCost?: number;
}
export interface ChatThreadProps {
    /** Extra classes for the thread root (e.g. `h-full`). */
    class?: string;
    /** The full message thread to render, newest last. Each entry carries its role,
     *  content, and optional reasoning/tools/attachments/actions. Set as a JS
     *  property (`el.messages = [...]`). */
    messages: ChatMessage[];
    /** Value of the input. A **string** is controlled (the host owns the text and
     *  updates it on `kai-value-change`). A **ComposerDoc** is a one-time seed that
     *  pre-populates pills; the user then edits freely. Leave unset for uncontrolled. */
    value?: string | ComposerDoc;
    /** Placeholder text shown in the empty input. */
    placeholder?: string;
    /** When true, shows the loading/streaming state and disables submit (use while
     *  awaiting the assistant's reply). */
    loading?: boolean;
    /** Starter prompts shown above the input when the thread is empty. Clicking one
     *  follows `suggestionMode`. Set as a JS property. */
    suggestions?: string[];
    /** What clicking a suggestion does: `'submit'` (default) sends it immediately
     *  as if typed and submitted; `'fill'` just places it in the input. */
    suggestionMode?: 'submit' | 'fill';
    /** Keep suggestions visible after the conversation starts. By default
     *  suggestions are conversation starters and hide once `messages` is
     *  non-empty; set this to keep them always shown. Default false. */
    persistSuggestions?: boolean;
    /** Body/prose font scale for rendered markdown (`'xs' | 'sm' | 'base' | 'lg'`).
     *  Defaults to `'sm'`. */
    proseSize?: ProseSize;
    /** Shiki theme name for syntax-highlighted code blocks (e.g.
     *  `'github-dark-dimmed'`). */
    codeTheme?: string;
    /** Enable Shiki syntax highlighting in code blocks. Turn off to render plain
     *  `<pre>` blocks (lighter, no highlighter load). Default true. */
    codeHighlight?: boolean;
    /** Optional header title shown on the left of the header. */
    chatTitle?: string;
    /** Optional model list. When set (>1 model) a ModelSwitcher is shown in the
     *  header and a `kai-model-change` event fires on selection. */
    models?: ModelOption[];
    /** The currently selected model id (pairs with `models`). */
    currentModel?: string;
    /** Optional context-window token usage. When set, a Context token meter is
     *  shown in the header. */
    context?: ChatThreadContextUsage;
    /** Show the scroll-to-bottom button inside the scroll area. Default true. */
    scrollButton?: boolean;
    /** Whether the host has `slot="header-start"` content (left of the title) —
     *  set by the `<kai-chat>` facade so a custom control forces the header open. */
    headerStart?: boolean;
    /** Whether the host has `slot="header-end"` content (right of the controls). */
    headerEnd?: boolean;
    /** REPLACE — full custom header in place of the built-in title/model/context bar. */
    headerFull?: boolean;
    /** INJECT — left sidebar column (e.g. a conversation list / your own nav). */
    sidebar?: boolean;
    /** REPLACE — custom zero-state rendered in the message area while the thread is empty (replaces the empty message list only; the composer and its suggestions still render). */
    empty?: boolean;
    /** REPLACE — full custom composer in place of the built-in prompt input. The
     *  projected content wires its own submit (the data-flow boundary). */
    composer?: boolean;
    /** INJECT — accessory row just above the composer (e.g. extra actions). */
    composerActions?: boolean;
    /** INJECT — footer row below the composer (disclaimers, token meter, …). */
    footer?: boolean;
    /** Show a Search (Globe) button in the input toolbar; fires a `search` event. */
    search?: boolean;
    /** Show a Voice (Mic) button in the input toolbar; fires a `voice` event. */
    voice?: boolean;
    /** Rich entity triggers — each `{ char, kind, items }` opens a caret-anchored
     *  menu that inserts an atomic pill (`/` skills, `@` agents/plugins). Set as a
     *  JS property; forwarded to the input. */
    triggers?: TriggerDef[];
    /** Default icon per entity kind (kind → image src) for pills/menu items. */
    kindIcons?: Record<string, string>;
    /** Whether each message's action bar is always visible (`'always'`, default)
     *  or only revealed on hover of that message row (`'hover'`). */
    actionsReveal?: 'always' | 'hover';
    onValueChange?: (value: string) => void;
    onSubmit?: (detail: {
        value: string;
        attachments: AttachmentData[];
    }) => void;
    onAttachmentsChange?: (attachments: AttachmentData[]) => void;
    onSuggestionClick?: (value: string) => void;
    onModelChange?: (modelId: string) => void;
    onMessageAction?: (detail: MessageActionDetail) => void;
    onSearch?: () => void;
    onVoice?: () => void;
    /** Receive the imperative controller once mounted. The kai-chat facade forwards
     *  these as element methods (focus/clear/send/scrollToBottom). */
    controllerRef?: (controller: ChatThreadController) => void;
}
/** Imperative handle exposed via `controllerRef` — the input half of the chat's
 *  interaction surface, forwarded onto `<kai-chat>` as instance methods. */
export interface ChatThreadController {
    focus(options?: FocusOptions): void;
    clear(): void;
    send(): void;
    scrollToBottom(behavior?: ScrollBehavior): void;
}
export declare function ChatThread(props: ChatThreadProps): import("solid-js").JSX.Element;
