import type { EmbedProtocolVersion } from "../version.js"; import type { RouteManifest } from "./routes.js"; import type { ToolManifest } from "./tools.js"; /** * Color values for a single mode (light or dark). * Applied as CSS variables within the chat UI. */ export type ThemeColors = { /** Main background color of the chat panel */ background?: string; /** Border color for the chat panel and elements */ border?: string; /** User message bubble background color */ messageBackground?: string; /** Input placeholder text color */ placeholderColor?: string; /** Submit button background color */ submitButtonColor?: string; /** Submit button text/icon color */ submitButtonTextColor?: string; /** Header icon color (restart and close buttons) */ headerIconColor?: string; }; /** * Widget position on the screen. * - For chatbox mode: specifies where the trigger button and chatbox appear * - For drawer mode: only left-center and right-center are used (drawer slides from that side) */ export type WidgetPosition = "top-left" | "top-center" | "top-right" | "left-center" | "right-center" | "bottom-left" | "bottom-center" | "bottom-right"; /** * Theme configuration for the chatbot widget */ export type Theme = { /** Widget position: for chatbox mode this is the corner/edge, for drawer mode this is the side (left-center or right-center) */ position?: WidgetPosition; /** Force a specific color mode instead of following system preference */ colorMode?: "light" | "dark" | "system"; /** Display mode: chatbox (floating corner panel) or drawer (full-height side panel) */ displayMode?: "chatbox" | "drawer"; /** Whether the widget is displayed fullscreen (e.g., on mobile). When true, the chat-ui removes its border and border-radius. */ fullscreen?: boolean; /** Color customization for light mode (applied when colorMode is "light" or system prefers light) */ light?: ThemeColors; /** Color customization for dark mode (applied when colorMode is "dark" or system prefers dark) */ dark?: ThemeColors; }; /** * Page context information from the host page */ export type PageContext = { url: string; title: string; text: string; timestamp: number; }; /** * Chat configuration options passed from host to chat-ui. * Grouped to minimize contract changes when adding new options. */ export type ChatOptions = { /** Disable the restart session button in the header */ disableRestartButton?: boolean; }; /** * End-user identity for server-side conversation persistence. * * The integrator's backend signs `id` with the application's apiSecret using * HMAC-SHA256 and passes `{ id, hash }` into the widget. When the hash * verifies, conversations are stored server-side and the widget shows a * history pane so end-users can resume past chats. When omitted, the widget * operates in anonymous mode (no persistence). */ export type UserIdentity = { /** Stable user id from the integrator's system. HMAC-protected. */ id: string; /** Hex HMAC-SHA256(apiSecret, id). Computed on the integrator's backend. */ hash: string; }; /** * Messages sent FROM the host application TO the iframe */ export type IframeMessageFromHost = { type: "yak:config"; payload: { /** Protocol version for compatibility checking */ version?: EmbedProtocolVersion; appId: string; theme?: Theme; toolManifest?: ToolManifest; routeManifest?: RouteManifest; /** Chat configuration options */ options?: ChatOptions; /** Logging enabled flag from host (for cross-origin sync) */ loggingEnabled?: boolean; /** * Signed end-user identity. Optional metadata used to link * conversations back to the integrator's user records. */ user?: UserIdentity; /** * Signed session token previously minted by the server and stored in * the host SDK's localStorage. When absent, the iframe will mint a * fresh one and `yak:session` it back so we can persist it. */ sessionToken?: string; /** * Pointer to the active conversation in the form * `.`. Persisted in the host SDK's * localStorage and shipped back into the iframe so the embed can * restore that specific thread on mount. */ conversationPointer?: string; }; } | { type: "yak:tool_result"; payload: { id: string; ok: true; result: unknown; }; } | { type: "yak:tool_result"; payload: { id: string; ok: false; error: string; }; } | { type: "yak:page_context"; payload: PageContext; } | { type: "yak:prompt"; payload: { prompt: string; }; } | { type: "yak:focus"; } | { type: "yak:viewport"; payload: { fullscreen: boolean; }; }; /** * Messages sent FROM the iframe TO the host application */ export type IframeMessageToHost = { type: "yak:ready"; /** Protocol version supported by the embed page */ payload?: { version: EmbedProtocolVersion; }; } | { type: "yak:tool_call"; payload: { id: string; name: string; args: unknown; }; } | { type: "yak:redirect"; payload: { path: string; }; } | { /** * Iframe → host: a freshly-minted or refreshed session token. The host * SDK persists this in `localStorage` so future widget loads can pass * it straight back via the next `yak:config`. */ type: "yak:session"; payload: { sessionToken: string; issuedAt: number; }; } | { /** * Iframe → host: persist (or clear) the active-conversation pointer. * `null` means "drop the stored key" (restart, stale, or invalid). */ type: "yak:conversation"; payload: { pointer: string | null; }; } | { type: "yak:close"; }; /** * Union of all message types (for type guards) */ export type IframeMessage = IframeMessageFromHost | IframeMessageToHost; //# sourceMappingURL=messaging.d.ts.map