/** * Alia Assistant — shared types. * * These types describe the message, suggestion, and surface props that * the consuming app flows into the Alia pattern. The pattern itself owns * NO state or business logic — it is a purely presentational composition * of existing DS primitives (ChatContainer, ChatMessage, StreamingText, * SuggestionChip, TypingIndicator, Progress, …). */ import type { ReactNode } from 'react'; export interface AliaMessage { id: string; role: 'user' | 'assistant' | 'system'; content: string; timestamp?: Date | number | string; status?: 'sending' | 'sent' | 'error' | 'edited'; /** When true, content is still being streamed — renders via StreamingText. */ streaming?: boolean; /** * Optional rich body rendered verbatim INSTEAD of `content` (bypasses the * markdown tokenizer) — e.g. an entity card / tool result. `content` stays * the plain-text source of truth used for copy / download / aria. Omit for * plain string messages — full back-compat. Ignored on streaming rows. */ body?: ReactNode; } /** * An Alia message whose body is a custom node (e.g. an entity card / tool * result). `body` is required here; `content` remains the plain-text mirror * used for copy / download / accessibility. */ export interface AliaEntityMessage extends AliaMessage { body: ReactNode; } export interface AliaSuggestion { id: string; label: string; /** Optional icon (e.g. from lucide-react). */ icon?: ReactNode; } /** * A composer attachment chip. Presentational only — the consuming app owns the * attachment list (adds via `onAttach`, removes via `onRemoveAttachment`). */ export interface AliaAttachment { /** Stable id — chip key + the `onRemoveAttachment` argument. */ id: string; /** Display filename. */ name: string; } export interface AliaAssistantAvatar { name?: string; src?: string; } /** * Current-user avatar for user-role messages in the Alia surface. Consumers * plug this through from their auth/profile store so the conversation * shows the real user's initials or photo instead of the default generic * person tile. * * - `name` — initials fallback (e.g. "Michael Lockyer" → "ML"). * - `src` — optional image. Scrubbed through `safeImageSrc` by * `ChatMessage` before reaching ``. * - `slot` — escape hatch: a fully custom node (e.g. a branded tile or * ``-style chip). When set, replaces * `` entirely. */ export interface AliaUserAvatar { name?: string; src?: string; slot?: import('react').ReactNode; } export interface AliaUsage { current: number; limit: number; /** * Optional override for the "X of Y messages used" label. * Defaults to `t('alia.usageLabel', { current, limit })`. */ label?: string; } export interface AliaChatSurfaceProps { /** Current message history. */ messages: AliaMessage[]; /** Fires when the user submits a message through the composer. */ onSend: (text: string) => void; /** Fires when the user clicks retry on a failed message. */ onRetry?: (messageId: string) => void; /** Fires when the user clicks a suggestion chip. */ onSuggestion?: (suggestion: AliaSuggestion) => void; /** * Suggestion chips shown above the composer (and inline in the empty * state). Typically refreshed by the consuming app after each assistant * response. */ suggestions?: AliaSuggestion[]; /** Whether the assistant is currently generating a response. */ isGenerating?: boolean; /** Fires when the user clicks "Stop generating". */ onStopGenerating?: () => void; /** Usage data for the freemium paywall — omit to hide the usage bar. */ usage?: AliaUsage; /** Fires when the user clicks "Upgrade" in the paywall CTA. */ onUpgrade?: () => void; /** * Assistant name shown in the header and message avatars. Defaults to * `t('alia.name')` → "Alia". */ assistantName?: string; /** Assistant avatar props (passed to ``). */ assistantAvatar?: AliaAssistantAvatar; /** * Current-user avatar for user-role messages. When omitted, Alia renders * a neutral `User`-icon tile. See `AliaUserAvatar`. */ userAvatar?: AliaUserAvatar; /** * Greeting heading shown when the conversation is empty. Defaults to * `t('alia.greeting')`. */ greeting?: string; /** * Subheading under the greeting. Defaults to `t('alia.subtitle')`. */ subtitle?: string; /** Density variant. */ density?: 'default' | 'compact'; /** When true, assistant message bodies render via the safe markdown parser. */ renderMarkdown?: boolean; /** Fires when the user clicks "New conversation" in the header. */ onNewConversation?: () => void; /** * Fires when the user picks or drops files via the composer's attach * control. When omitted, the attach button isn't rendered. Consumers are * responsible for uploading, validating, and echoing the file(s) back * into the conversation — Alia itself holds no attachment state. */ onAttach?: (files: FileList) => void; /** MIME / extension allow-list forwarded to the native file picker. */ acceptedFileTypes?: string; /** * Slot rendered at the inline-end of the header bar — used by the * popout mode to inject a close button. Leave undefined otherwise. */ headerEndSlot?: ReactNode; /** * Suppress Alia's built-in header bar (the identity tile + name + * new-conversation control). Use when the HOST chrome already provides a * panel header — e.g. mounting the surface inside a Control Room rail tool * that renders its own `PanelHeader`. Default `false` (header shown), so * the embedded / popout / sidebar modes are unchanged. When `true`, drive * "new conversation" from the host header via `onNewConversation`. */ hideHeader?: boolean; /** * CONVERSATION-ENDED / UI-LOCKED state. When set, Alia renders * `ended.note` as a centred, locked system divider at the END of the * message list and freezes forward interaction: the composer * (`ChatInput`, including send + attach) is disabled, and the * suggestion chips + the stop-generating button stop rendering. The * header and existing message history stay visible and read-only — only * NEW input is blocked. * * The surface stays presentational: it does NOT decide *when* to end. * The consuming app owns the termination decision (e.g. a detected * jailbreak / safety violation, or any policy that closes the session) * and supplies the notice via `note`. Because `note` is a * consumer-provided `ReactNode`, the copy lives in the host app — no * new keys are added to the DS `ui.*` locale bundles. */ ended?: { /** Consumer-provided notice shown in the locked end divider. */ note: ReactNode; }; /** * Per-assistant-message action row. Pass any of `'copy'` / `'download'` to * render those icon-buttons under each assistant message. Both are pure * client actions handled internally: `'copy'` writes the message's raw * markdown to the clipboard (brief "Copied" confirmation, graceful fallback * when the clipboard API is unavailable); `'download'` saves it as * `-prompt-.md`. Default off → no action row. */ messageActions?: Array<'copy' | 'download'>; /** Analytics-only hook fired after an assistant message is copied. */ onCopyMessage?: (messageId: string) => void; /** Analytics-only hook fired after an assistant message is downloaded. */ onDownloadMessage?: (messageId: string) => void; /** * Enable the composer voice-dictation mic (Web Speech API). It transcribes * speech into the composer text. Feature-detected: when `SpeechRecognition` * is unsupported the mic is not rendered (no broken button). Opt-in. * * PRIVACY: Chrome's `SpeechRecognition` streams audio to Google's servers. * Do not enable in contexts where sensitive audio could be dictated. * * @deprecated Use `onDictate` with the host's speech service (Amazon * Transcribe through `@alfadocs/ui-kit/aws-transcribe`). Ignored when * `onDictate` is set. */ voiceInput?: boolean; /** * Optional hook receiving each finalised transcript chunk. The transcript is * appended to the composer regardless; this is for analytics or swapping in * a different speech engine later. */ onVoiceTranscript?: (text: string) => void; /** * Voice dictation into the composer, through the host's speech service. * The same seam as RichTextEditor's `onDictate`: the kit draws the mic and * the text; the host runs the microphone and transcription and pushes text * back. The phrase being spoken shows in the composer, which is read-only * while dictating; each final phrase is appended, including one that * arrives after the user presses stop and before the promise settles. * Resolve when the session ends; honour `signal` to stop. A rejection shows * a short error. Takes precedence over `voiceInput`. * * For Amazon Transcribe, pass `createAwsTranscribeDictation(...)` from * `@alfadocs/ui-kit/aws-transcribe`. */ onDictate?: (ctx: { signal: AbortSignal; onPartialTranscript: (text: string) => void; onFinalTranscript: (text: string) => void; }) => Promise; /** * Attachment chips shown above the composer (filename + remove). Presentational * — the consumer owns the list: add via `onAttach`, remove via * `onRemoveAttachment`. Omit to render no chip row. */ attachments?: AliaAttachment[]; /** Fires when the user removes an attachment chip. */ onRemoveAttachment?: (id: string) => void; /** Show a "jump to latest" affordance when the user has scrolled up. Opt-in. */ showScrollToLatest?: boolean; /** * Regenerate the LAST assistant message. When set, a Regenerate action is * added to that message's action row (distinct from `onRetry`, the * failed-message retry). Omit to hide it. */ onRegenerate?: (messageId: string) => void; /** * Edit & resend a user message. When set, user messages gain an Edit action; * on save the surface calls this with the message id + the new text. The * surface owns the transient edit-draft state; the consumer owns the * resulting conversation update. */ onEditMessage?: (messageId: string, text: string) => void; } //# sourceMappingURL=alia-types.d.ts.map