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 * `
` 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 `` 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;
    /** 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 `` 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;