/** * Chat defaults and constants. */ export const STORAGE_KEYS = { mode: 'djc-chat-mode', sidebarWidth: 'djc-chat-sidebar-width', composerHistory: 'djc-chat-composer-history', } as const; export const CSS_VARS = { reserve: '--djc-chat-reserve', } as const; /** * Z-index tier for the floating chat surface. * * The chat dock is page furniture — a peer of page content, not a modal. * It must sit ABOVE the page yet BELOW every `@djangocfg/ui-core` overlay * (sheet 200, drawer 500, dialog 600, anchored overlays 700) so that any * dialog — including one launched from inside the chat — always wins. * * dock 100 the chat surface * companion 99 FAB / greeting / unread preview (behind the open dock) * tooltip 101 chat-header tooltips (just above the dock, still * below ui-core's modal/overlay tiers) */ export const Z_INDEX = { /** The chat dock surface. */ dock: 100, /** FAB, greeting bubble and unread preview — sit just below the dock. */ companion: 99, /** Tooltips portaled out of the chat header — just above the dock. */ tooltip: 101, } as const; /** @deprecated Use {@link Z_INDEX.dock}. Kept for the public API surface. */ export const DEFAULT_Z_INDEX = Z_INDEX.dock; export const LIMITS = { /** Max characters per single message. */ messageMaxLength: 8000, /** Max attachments per message. */ attachmentsMax: 10, /** Composer history slots. */ composerHistorySize: 50, /** * Coalesce stream tokens within this window before dispatching one * aggregated chunk. 33ms ≈ 30fps — enough to feel live while halving * the re-parse count now that markdown renders during streaming * (block-split + per-block memoization keeps each render ~O(n), but * fewer dispatches still means fewer tail re-parses). ai-sdk uses ~50ms * for the same reason. */ streamCoalesceMs: 33, /** Default history page size. */ pageSize: 50, /** Virtualize list when >= this many messages (host-controlled threshold). */ virtualizeThreshold: 50, /** SSE idle timeout. */ sseIdleMs: 45_000, } as const; export const DEFAULT_SIDEBAR = { width: 420, min: 320, max: 720, } as const; export const HOTKEYS = { send: 'mod+enter', cancel: 'esc', newChat: 'mod+shift+n', toggleOpen: 'mod+/', focusComposer: 'mod+l', } as const; export const CHAT_EVENT_NAME = 'djc:chat:send'; export interface ChatEventDetail { content: string; sessionId?: string; attachments?: unknown[]; metadata?: Record; }