@djangocfg/ui-tools 2.1.381 → 2.1.382
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -899
- package/dist/ChatRoot-6IZFM5HM.mjs +5 -0
- package/dist/{ChatRoot-EJC5Y2YM.cjs.map → ChatRoot-6IZFM5HM.mjs.map} +1 -1
- package/dist/ChatRoot-LW4XNIKP.cjs +14 -0
- package/dist/{ChatRoot-QOSKJPM6.mjs.map → ChatRoot-LW4XNIKP.cjs.map} +1 -1
- package/dist/DictationField-2ZLQWLYV.mjs +4 -0
- package/dist/DictationField-2ZLQWLYV.mjs.map +1 -0
- package/dist/DictationField-IPPJ54CU.cjs +13 -0
- package/dist/DictationField-IPPJ54CU.cjs.map +1 -0
- package/dist/{DocsLayout-2YKPXZYO.mjs → DocsLayout-2P3ONDWJ.mjs} +3 -3
- package/dist/{DocsLayout-2YKPXZYO.mjs.map → DocsLayout-2P3ONDWJ.mjs.map} +1 -1
- package/dist/{DocsLayout-Q4KS3QWW.cjs → DocsLayout-2YZNS5VK.cjs} +8 -8
- package/dist/{DocsLayout-Q4KS3QWW.cjs.map → DocsLayout-2YZNS5VK.cjs.map} +1 -1
- package/dist/chunk-4LXG3NBV.mjs +833 -0
- package/dist/chunk-4LXG3NBV.mjs.map +1 -0
- package/dist/{chunk-XACCHZH2.cjs → chunk-FIRK5CEH.cjs} +42 -4
- package/dist/chunk-FIRK5CEH.cjs.map +1 -0
- package/dist/{chunk-NWUT327A.mjs → chunk-HIK6BPL7.mjs} +38 -5
- package/dist/chunk-HIK6BPL7.mjs.map +1 -0
- package/dist/chunk-KMSBGNVC.cjs +835 -0
- package/dist/chunk-KMSBGNVC.cjs.map +1 -0
- package/dist/chunk-OZAU3QWD.cjs +2493 -0
- package/dist/chunk-OZAU3QWD.cjs.map +1 -0
- package/dist/chunk-UWVP6LCW.mjs +2447 -0
- package/dist/chunk-UWVP6LCW.mjs.map +1 -0
- package/dist/index.cjs +1532 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1148 -107
- package/dist/index.d.ts +1148 -107
- package/dist/index.mjs +1421 -51
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -8
- package/src/audio-assets.d.ts +8 -0
- package/src/components/markdown/MarkdownMessage/CollapseToggle.tsx +3 -1
- package/src/components/markdown/MarkdownMessage/components.tsx +2 -5
- package/src/stories/index.ts +32 -2
- package/src/tools/Chat/README.md +347 -530
- package/src/tools/Chat/components/Attachments.tsx +6 -1
- package/src/tools/Chat/components/ChatRoot.tsx +30 -2
- package/src/tools/Chat/components/Composer.tsx +20 -3
- package/src/tools/Chat/components/ErrorBanner.tsx +7 -3
- package/src/tools/Chat/components/MessageActions.tsx +3 -1
- package/src/tools/Chat/components/MessageBubble.tsx +6 -5
- package/src/tools/Chat/components/MessageList.tsx +87 -1
- package/src/tools/Chat/components/ToolCalls.tsx +21 -3
- package/src/tools/Chat/context/ChatProvider.tsx +21 -3
- package/src/tools/Chat/core/audio/audioBus.ts +10 -163
- package/src/tools/Chat/core/audio/defaults.ts +43 -0
- package/src/tools/Chat/core/audio/index.ts +1 -0
- package/src/tools/Chat/core/audio/preferences.ts +5 -59
- package/src/tools/Chat/core/audio/sounds/error.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/mention.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/notification.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/received.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/sent.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/start.mp3 +0 -0
- package/src/tools/Chat/core/audio/types.ts +28 -0
- package/src/tools/Chat/core/reducer.ts +33 -0
- package/src/tools/Chat/core/transport/index.ts +13 -0
- package/src/tools/Chat/core/transport/mappers/index.ts +6 -0
- package/src/tools/Chat/core/transport/mappers/pydantic-ai.ts +142 -0
- package/src/tools/Chat/core/transport/pydantic-ai-transport.ts +208 -0
- package/src/tools/Chat/core/transport/sse.ts +18 -5
- package/src/tools/Chat/hooks/index.ts +25 -0
- package/src/tools/Chat/hooks/useAutoFocusOnStreamEnd.ts +5 -3
- package/src/tools/Chat/hooks/useChat.ts +28 -0
- package/src/tools/Chat/hooks/useChatAudio.ts +59 -180
- package/src/tools/Chat/hooks/useChatDockPrefs.ts +74 -0
- package/src/tools/Chat/hooks/useChatReset.ts +70 -0
- package/src/tools/Chat/hooks/useChatUnread.ts +87 -0
- package/src/tools/Chat/hooks/useFocusOnEmptyClick.ts +111 -0
- package/src/tools/Chat/hooks/useVisitorFingerprint.ts +48 -0
- package/src/tools/Chat/index.ts +69 -1
- package/src/tools/Chat/launcher/ChatDock.tsx +263 -0
- package/src/tools/Chat/launcher/ChatFAB.tsx +349 -0
- package/src/tools/Chat/launcher/ChatGreeting.tsx +200 -0
- package/src/tools/Chat/launcher/ChatHeader.tsx +76 -0
- package/src/tools/Chat/launcher/ChatHeaderActionButton.tsx +87 -0
- package/src/tools/Chat/launcher/ChatHeaderAudioToggle.tsx +47 -0
- package/src/tools/Chat/launcher/ChatHeaderLanguageButton.tsx +179 -0
- package/src/tools/Chat/launcher/ChatHeaderModeToggle.tsx +57 -0
- package/src/tools/Chat/launcher/ChatHeaderResetButton.tsx +93 -0
- package/src/tools/Chat/launcher/ChatLauncher.tsx +321 -0
- package/src/tools/Chat/launcher/ChatUnreadPreview.tsx +197 -0
- package/src/tools/Chat/launcher/index.ts +46 -0
- package/src/tools/Chat/launcher/useChatPresence.ts +44 -0
- package/src/tools/Chat/stories/01-basic.story.tsx +64 -0
- package/src/tools/Chat/stories/02-bubbles.story.tsx +21 -0
- package/src/tools/Chat/stories/03-tool-calls.story.tsx +59 -0
- package/src/tools/Chat/stories/04-personas.story.tsx +78 -0
- package/src/tools/Chat/stories/05-launcher.story.tsx +321 -0
- package/src/tools/Chat/stories/06-header.story.tsx +147 -0
- package/src/tools/Chat/stories/07-audio-actions.story.tsx +112 -0
- package/src/tools/Chat/stories/shared/Frame.tsx +21 -0
- package/src/tools/Chat/stories/shared/index.ts +5 -0
- package/src/tools/Chat/stories/shared/messages.ts +39 -0
- package/src/tools/Chat/stories/shared/personas.ts +13 -0
- package/src/tools/Chat/stories/shared/seeds.ts +92 -0
- package/src/tools/Chat/stories/shared/transports.ts +36 -0
- package/src/tools/Chat/styles/bubbleTokens.ts +71 -0
- package/src/tools/Chat/styles/index.ts +16 -0
- package/src/tools/Chat/styles/useChatStyles.ts +101 -0
- package/src/tools/Chat/types/attachment.ts +25 -0
- package/src/tools/Chat/types/config.ts +48 -0
- package/src/tools/Chat/types/events.ts +35 -0
- package/src/tools/Chat/types/index.ts +34 -0
- package/src/tools/Chat/types/labels.ts +38 -0
- package/src/tools/Chat/types/message.ts +32 -0
- package/src/tools/Chat/types/persona.ts +31 -0
- package/src/tools/Chat/types/session.ts +43 -0
- package/src/tools/Chat/types/tool-call.ts +17 -0
- package/src/tools/Chat/types/transport.ts +28 -0
- package/src/tools/Chat/types.ts +5 -240
- package/src/tools/MarkdownEditor/MarkdownEditor.tsx +50 -14
- package/src/tools/MarkdownEditor/index.ts +1 -1
- package/src/tools/SpeechRecognition/README.md +336 -0
- package/src/tools/SpeechRecognition/__tests__/ids.test.ts +15 -0
- package/src/tools/SpeechRecognition/__tests__/language.test.ts +59 -0
- package/src/tools/SpeechRecognition/__tests__/reducer.test.ts +71 -0
- package/src/tools/SpeechRecognition/__tests__/transcript.test.ts +52 -0
- package/src/tools/SpeechRecognition/components/DevicePicker.tsx +49 -0
- package/src/tools/SpeechRecognition/components/DictationButton.tsx +93 -0
- package/src/tools/SpeechRecognition/components/EngineBadge.tsx +30 -0
- package/src/tools/SpeechRecognition/components/ErrorBanner.tsx +52 -0
- package/src/tools/SpeechRecognition/components/LanguagePicker.tsx +63 -0
- package/src/tools/SpeechRecognition/components/MicMeter.tsx +63 -0
- package/src/tools/SpeechRecognition/components/PushToTalkHint.tsx +51 -0
- package/src/tools/SpeechRecognition/components/TranscriptView.tsx +55 -0
- package/src/tools/SpeechRecognition/components/index.ts +16 -0
- package/src/tools/SpeechRecognition/context/SpeechRecognitionProvider.tsx +47 -0
- package/src/tools/SpeechRecognition/context/index.ts +6 -0
- package/src/tools/SpeechRecognition/core/audio/defaults.ts +24 -0
- package/src/tools/SpeechRecognition/core/engine/external.ts +222 -0
- package/src/tools/SpeechRecognition/core/engine/http.ts +147 -0
- package/src/tools/SpeechRecognition/core/engine/index.ts +52 -0
- package/src/tools/SpeechRecognition/core/engine/mediarecorder.ts +105 -0
- package/src/tools/SpeechRecognition/core/engine/websocket.ts +211 -0
- package/src/tools/SpeechRecognition/core/engine/webspeech.ts +188 -0
- package/src/tools/SpeechRecognition/core/ids.ts +11 -0
- package/src/tools/SpeechRecognition/core/index.ts +14 -0
- package/src/tools/SpeechRecognition/core/language.ts +78 -0
- package/src/tools/SpeechRecognition/core/languages-catalog.ts +229 -0
- package/src/tools/SpeechRecognition/core/logger.ts +3 -0
- package/src/tools/SpeechRecognition/core/reducer.ts +105 -0
- package/src/tools/SpeechRecognition/core/transcript.ts +36 -0
- package/src/tools/SpeechRecognition/hooks/index.ts +14 -0
- package/src/tools/SpeechRecognition/hooks/useDictation.ts +59 -0
- package/src/tools/SpeechRecognition/hooks/useEnginePrefs.ts +15 -0
- package/src/tools/SpeechRecognition/hooks/useMicDevices.ts +57 -0
- package/src/tools/SpeechRecognition/hooks/useMicLevel.ts +52 -0
- package/src/tools/SpeechRecognition/hooks/usePushToTalk.ts +85 -0
- package/src/tools/SpeechRecognition/hooks/useResolvedLanguage.ts +28 -0
- package/src/tools/SpeechRecognition/hooks/useSpeechLanguageInfo.ts +108 -0
- package/src/tools/SpeechRecognition/hooks/useSpeechRecognition.ts +188 -0
- package/src/tools/SpeechRecognition/hooks/useVoiceSupport.ts +78 -0
- package/src/tools/SpeechRecognition/index.ts +82 -0
- package/src/tools/SpeechRecognition/lazy.tsx +19 -0
- package/src/tools/SpeechRecognition/store/index.ts +2 -0
- package/src/tools/SpeechRecognition/store/prefsStore.ts +54 -0
- package/src/tools/SpeechRecognition/stories/01-basic.story.tsx +32 -0
- package/src/tools/SpeechRecognition/stories/02-dictation-field.story.tsx +32 -0
- package/src/tools/SpeechRecognition/stories/03-push-to-talk.story.tsx +27 -0
- package/src/tools/SpeechRecognition/stories/04-mic-meter.story.tsx +35 -0
- package/src/tools/SpeechRecognition/stories/05-custom-engine-http.story.tsx +40 -0
- package/src/tools/SpeechRecognition/stories/06-custom-engine-ws.story.tsx +48 -0
- package/src/tools/SpeechRecognition/stories/07-language-device.story.tsx +57 -0
- package/src/tools/SpeechRecognition/stories/08-errors-permissions.story.tsx +25 -0
- package/src/tools/SpeechRecognition/stories/09-chat-voice.story.tsx +90 -0
- package/src/tools/SpeechRecognition/stories/shared.tsx +123 -0
- package/src/tools/SpeechRecognition/types.ts +133 -0
- package/src/tools/SpeechRecognition/widgets/DictationField.tsx +105 -0
- package/src/tools/SpeechRecognition/widgets/VoiceComposerSlot.tsx +305 -0
- package/src/tools/SpeechRecognition/widgets/VoiceMessageRecorder.tsx +88 -0
- package/src/tools/SpeechRecognition/widgets/index.ts +6 -0
- package/dist/ChatRoot-EJC5Y2YM.cjs +0 -14
- package/dist/ChatRoot-QOSKJPM6.mjs +0 -5
- package/dist/chunk-NWUT327A.mjs.map +0 -1
- package/dist/chunk-QLMKCSR6.mjs +0 -2420
- package/dist/chunk-QLMKCSR6.mjs.map +0 -1
- package/dist/chunk-SI5RD2GD.cjs +0 -2460
- package/dist/chunk-SI5RD2GD.cjs.map +0 -1
- package/dist/chunk-XACCHZH2.cjs.map +0 -1
- package/src/tools/Chat/Chat.story.tsx +0 -1457
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as react from 'react';
|
|
3
|
-
import react__default, { ReactNode, ComponentType, RefObject, ChangeEvent, KeyboardEvent, ClipboardEvent } from 'react';
|
|
3
|
+
import react__default, { ReactNode, ComponentType, RefObject, ChangeEvent, KeyboardEvent, ClipboardEvent, CSSProperties, ButtonHTMLAttributes, MouseEvent } from 'react';
|
|
4
4
|
import { Components } from 'react-markdown';
|
|
5
5
|
import { ViewState } from 'react-map-gl/maplibre';
|
|
6
6
|
import { Language } from 'prism-react-renderer';
|
|
@@ -13,12 +13,14 @@ export { CustomJsonSchema7, CustomJsonSchema7Type, CustomJsonUiDisabledWhenRule,
|
|
|
13
13
|
import { CommonExternalProps } from 'react-json-tree';
|
|
14
14
|
import { b as TreeRootProps } from './types-CevSbyfD.cjs';
|
|
15
15
|
export { c as DEFAULT_TREE_APPEARANCE, D as DEFAULT_TREE_LABELS, F as FlatRow, R as ResolvedAppearance, m as TreeAccentIntensity, k as TreeAppearance, e as TreeContextMenuSlot, l as TreeDensity, f as TreeItemId, g as TreeLabels, j as TreeLoadChildren, T as TreeNode, n as TreeRadius, i as TreeRowRenderProps, a as TreeRowSlot, h as TreeSelectionMode, d as appearanceToStyle, r as resolveAppearance } from './types-CevSbyfD.cjs';
|
|
16
|
-
import * as zustand_middleware from 'zustand/middleware';
|
|
17
16
|
import * as zustand from 'zustand';
|
|
17
|
+
import { AudioPrefsState } from '@djangocfg/ui-core/hooks';
|
|
18
18
|
import { ConsolaInstance } from 'consola';
|
|
19
19
|
import { MediaPlayerInstance } from '@vidstack/react';
|
|
20
20
|
import * as monaco from 'monaco-editor';
|
|
21
|
+
import { Editor as Editor$1 } from '@tiptap/react';
|
|
21
22
|
export { ChildCache, ChildEntry, ChildEntryStatus, DemoNode, FlattenInput, PersistedTreeState, TreeRoot as Tree, TreeChevron, TreeChevronProps, TreeContent, TreeContentProps, TreeContextValue, TreeEmpty, TreeEmptyProps, TreeError, TreeErrorProps, TreeIcon, TreeIconProps, TreeIndentGuides, TreeIndentGuidesProps, TreeLabel, TreeLabelProps, TreeProvider, TreeProviderProps, TreeRoot, TreeRow, TreeRowProps, TreeSearchInput, TreeSearchInputProps, TreeSkeleton, TreeSkeletonProps, UseTreeKeyboardOptions, UseTreeTypeAheadOptions, clearTreeState, createChildCache, createDemoTree, flattenTree, loadTreeState, resolveChildren, saveTreeState, useTreeActions, useTreeContext, useTreeExpansion, useTreeFocus, useTreeKeyboard, useTreeLabels, useTreeRows, useTreeSearch, useTreeSelection, useTreeTypeAhead } from './tree/index.cjs';
|
|
23
|
+
import * as zustand_middleware from 'zustand/middleware';
|
|
22
24
|
|
|
23
25
|
interface LoadingFallbackProps {
|
|
24
26
|
/** Minimum height of the loading container */
|
|
@@ -1418,12 +1420,36 @@ declare const LazyCronScheduler: react.ComponentType<CronSchedulerProps>;
|
|
|
1418
1420
|
declare const LazyTree: react.ComponentType<TreeRootProps<unknown>>;
|
|
1419
1421
|
|
|
1420
1422
|
/**
|
|
1421
|
-
*
|
|
1423
|
+
* Persona — display identity attached to messages and config.
|
|
1422
1424
|
*
|
|
1423
|
-
*
|
|
1424
|
-
* the hooks layer and the components. Keep serializable (no Date, no Map).
|
|
1425
|
+
* Used by `ChatMessage.sender`, `ChatConfig.user`, `ChatConfig.assistant`.
|
|
1425
1426
|
*/
|
|
1426
1427
|
type ChatRole = 'user' | 'assistant' | 'system';
|
|
1428
|
+
interface ChatPersona {
|
|
1429
|
+
/** Display name. */
|
|
1430
|
+
name?: string;
|
|
1431
|
+
/** Avatar image URL. */
|
|
1432
|
+
avatarUrl?: string;
|
|
1433
|
+
/** Initials fallback when no avatar. Auto-derived from `name` if absent. */
|
|
1434
|
+
initials?: string;
|
|
1435
|
+
/** Tooltip / aria description. */
|
|
1436
|
+
description?: string;
|
|
1437
|
+
}
|
|
1438
|
+
interface ChatUserContext extends ChatPersona {
|
|
1439
|
+
email?: string;
|
|
1440
|
+
language?: string;
|
|
1441
|
+
role?: string;
|
|
1442
|
+
/** Free-form custom data forwarded to transport metadata. */
|
|
1443
|
+
custom?: Record<string, unknown>;
|
|
1444
|
+
}
|
|
1445
|
+
interface ChatAssistantContext extends ChatPersona {
|
|
1446
|
+
/** Model identifier (gpt-4o, claude-opus, …). */
|
|
1447
|
+
model?: string;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
/**
|
|
1451
|
+
* Tool calls — assistant-initiated function/tool invocations during a turn.
|
|
1452
|
+
*/
|
|
1427
1453
|
interface ChatToolCall {
|
|
1428
1454
|
id: string;
|
|
1429
1455
|
name: string;
|
|
@@ -1437,6 +1463,10 @@ interface ChatToolCall {
|
|
|
1437
1463
|
/** Optional grouping label for parallel/fan-out execution. */
|
|
1438
1464
|
sourceHostname?: string;
|
|
1439
1465
|
}
|
|
1466
|
+
|
|
1467
|
+
/**
|
|
1468
|
+
* Attachments + sources attached to a chat message.
|
|
1469
|
+
*/
|
|
1440
1470
|
interface ChatAttachment {
|
|
1441
1471
|
id: string;
|
|
1442
1472
|
type: 'image' | 'file' | 'audio' | 'video';
|
|
@@ -1457,16 +1487,14 @@ interface ChatSource {
|
|
|
1457
1487
|
snippet?: string;
|
|
1458
1488
|
chunkIndex?: number;
|
|
1459
1489
|
}
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
description?: string;
|
|
1469
|
-
}
|
|
1490
|
+
|
|
1491
|
+
/**
|
|
1492
|
+
* The atomic unit — a single message in a chat session.
|
|
1493
|
+
*
|
|
1494
|
+
* Composed of role + content + optional rich-data slots (attachments,
|
|
1495
|
+
* sources, tool calls). Serializable: no Date, no Map.
|
|
1496
|
+
*/
|
|
1497
|
+
|
|
1470
1498
|
interface ChatMessage {
|
|
1471
1499
|
id: string;
|
|
1472
1500
|
role: ChatRole;
|
|
@@ -1488,18 +1516,34 @@ interface ChatMessage {
|
|
|
1488
1516
|
tokensIn?: number;
|
|
1489
1517
|
tokensOut?: number;
|
|
1490
1518
|
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1519
|
+
|
|
1520
|
+
/**
|
|
1521
|
+
* UI label strings — i18n is the host's job. Pass overrides via
|
|
1522
|
+
* `ChatConfig.labels` and merge with `DEFAULT_LABELS`.
|
|
1523
|
+
*/
|
|
1524
|
+
interface ChatLabels {
|
|
1525
|
+
send: string;
|
|
1526
|
+
cancel: string;
|
|
1527
|
+
copy: string;
|
|
1528
|
+
regenerate: string;
|
|
1529
|
+
edit: string;
|
|
1530
|
+
delete: string;
|
|
1531
|
+
retry: string;
|
|
1532
|
+
newChat: string;
|
|
1533
|
+
loadMore: string;
|
|
1534
|
+
jumpToLatest: string;
|
|
1535
|
+
attach: string;
|
|
1536
|
+
voice: string;
|
|
1537
|
+
errorGeneric: string;
|
|
1538
|
+
cancelledSuffix: string;
|
|
1502
1539
|
}
|
|
1540
|
+
declare const DEFAULT_LABELS: ChatLabels;
|
|
1541
|
+
|
|
1542
|
+
/**
|
|
1543
|
+
* Top-level chat configuration — placeholder, suggestions, identities, prefs.
|
|
1544
|
+
*/
|
|
1545
|
+
|
|
1546
|
+
type ChatDisplayMode = 'closed' | 'embedded' | 'floating' | 'sidebar' | 'fullscreen';
|
|
1503
1547
|
interface ChatPrefs {
|
|
1504
1548
|
/** Submit hotkey for the composer. */
|
|
1505
1549
|
submitOn?: 'enter' | 'cmd+enter';
|
|
@@ -1541,55 +1585,14 @@ interface ChatConfig {
|
|
|
1541
1585
|
/** Visual labels (i18n is the host's job). */
|
|
1542
1586
|
labels?: Partial<ChatLabels>;
|
|
1543
1587
|
}
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
newChat: string;
|
|
1553
|
-
loadMore: string;
|
|
1554
|
-
jumpToLatest: string;
|
|
1555
|
-
attach: string;
|
|
1556
|
-
voice: string;
|
|
1557
|
-
errorGeneric: string;
|
|
1558
|
-
cancelledSuffix: string;
|
|
1559
|
-
}
|
|
1560
|
-
declare const DEFAULT_LABELS: ChatLabels;
|
|
1561
|
-
interface CreateSessionOptions {
|
|
1562
|
-
metadata?: Record<string, unknown>;
|
|
1563
|
-
}
|
|
1564
|
-
interface SessionInfo {
|
|
1565
|
-
sessionId: string;
|
|
1566
|
-
/** If the server resumed an existing session, it may return prior messages. */
|
|
1567
|
-
messages?: ChatMessage[];
|
|
1568
|
-
hasMore?: boolean;
|
|
1569
|
-
cursor?: string | null;
|
|
1570
|
-
resumed?: boolean;
|
|
1571
|
-
/**
|
|
1572
|
-
* Optional human-readable title (typically derived from the first
|
|
1573
|
-
* user message). Hosts that render a session-list sidebar can read
|
|
1574
|
-
* this directly instead of crawling messages. Plan64.
|
|
1575
|
-
*/
|
|
1576
|
-
title?: string;
|
|
1577
|
-
}
|
|
1578
|
-
interface HistoryPage {
|
|
1579
|
-
messages: ChatMessage[];
|
|
1580
|
-
hasMore: boolean;
|
|
1581
|
-
nextCursor: string | null;
|
|
1582
|
-
}
|
|
1583
|
-
interface StreamOptions {
|
|
1584
|
-
signal: AbortSignal;
|
|
1585
|
-
attachments?: ChatAttachment[];
|
|
1586
|
-
metadata?: Record<string, unknown>;
|
|
1587
|
-
}
|
|
1588
|
-
interface SendOptions {
|
|
1589
|
-
signal?: AbortSignal;
|
|
1590
|
-
attachments?: ChatAttachment[];
|
|
1591
|
-
metadata?: Record<string, unknown>;
|
|
1592
|
-
}
|
|
1588
|
+
|
|
1589
|
+
/**
|
|
1590
|
+
* SSE stream events — the canonical wire shape consumed by the reducer.
|
|
1591
|
+
*
|
|
1592
|
+
* Backend-specific shapes (e.g. pydantic-AI's `text_delta`) get normalized
|
|
1593
|
+
* into this union by `mapPydanticAIEvent` and friends.
|
|
1594
|
+
*/
|
|
1595
|
+
|
|
1593
1596
|
type ChatStreamEvent = {
|
|
1594
1597
|
type: 'message_start';
|
|
1595
1598
|
messageId: string;
|
|
@@ -1628,6 +1631,51 @@ type ChatStreamEvent = {
|
|
|
1628
1631
|
code: string;
|
|
1629
1632
|
message: string;
|
|
1630
1633
|
};
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* Session info + history page shapes returned by transports.
|
|
1637
|
+
*/
|
|
1638
|
+
|
|
1639
|
+
interface CreateSessionOptions {
|
|
1640
|
+
metadata?: Record<string, unknown>;
|
|
1641
|
+
}
|
|
1642
|
+
interface SessionInfo {
|
|
1643
|
+
sessionId: string;
|
|
1644
|
+
/** If the server resumed an existing session, it may return prior messages. */
|
|
1645
|
+
messages?: ChatMessage[];
|
|
1646
|
+
hasMore?: boolean;
|
|
1647
|
+
cursor?: string | null;
|
|
1648
|
+
resumed?: boolean;
|
|
1649
|
+
/**
|
|
1650
|
+
* Optional human-readable title (typically derived from the first
|
|
1651
|
+
* user message). Hosts that render a session-list sidebar can read
|
|
1652
|
+
* this directly instead of crawling messages. Plan64.
|
|
1653
|
+
*/
|
|
1654
|
+
title?: string;
|
|
1655
|
+
}
|
|
1656
|
+
interface HistoryPage {
|
|
1657
|
+
messages: ChatMessage[];
|
|
1658
|
+
hasMore: boolean;
|
|
1659
|
+
nextCursor: string | null;
|
|
1660
|
+
}
|
|
1661
|
+
interface StreamOptions {
|
|
1662
|
+
signal: AbortSignal;
|
|
1663
|
+
attachments?: ChatAttachment[];
|
|
1664
|
+
metadata?: Record<string, unknown>;
|
|
1665
|
+
}
|
|
1666
|
+
interface SendOptions {
|
|
1667
|
+
signal?: AbortSignal;
|
|
1668
|
+
attachments?: ChatAttachment[];
|
|
1669
|
+
metadata?: Record<string, unknown>;
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
/**
|
|
1673
|
+
* Transport interface — what every chat backend adapter implements.
|
|
1674
|
+
*
|
|
1675
|
+
* Default web implementation lives in `core/transport/http.ts`.
|
|
1676
|
+
* Pydantic-AI adapter lives in `core/transport/pydantic-ai-transport.ts`.
|
|
1677
|
+
*/
|
|
1678
|
+
|
|
1631
1679
|
interface ChatTransport {
|
|
1632
1680
|
createSession(opts?: CreateSessionOptions): Promise<SessionInfo>;
|
|
1633
1681
|
loadHistory(sessionId: string, cursor?: string | null, limit?: number): Promise<HistoryPage>;
|
|
@@ -1644,6 +1692,19 @@ interface ChatAudioConfig {
|
|
|
1644
1692
|
sounds?: ChatAudioSounds;
|
|
1645
1693
|
/** Master volume 0..1. Persisted via the global prefs store. */
|
|
1646
1694
|
volume?: number;
|
|
1695
|
+
/**
|
|
1696
|
+
* Per-event volume multipliers (0..1). Applied on top of `volume`.
|
|
1697
|
+
* Defaults applied by `useChatAudio` if not provided:
|
|
1698
|
+
* - error: 0.25 (gentle — error UI is the loud signal, not the sound)
|
|
1699
|
+
* - mention: 1.0 (louder than baseline received)
|
|
1700
|
+
* - messageSent: 0.5 (subtle self-confirmation)
|
|
1701
|
+
* - messageReceived: 0.7
|
|
1702
|
+
* - streamStart: 0.3 (very subtle, fires often)
|
|
1703
|
+
* - notification: 0.9
|
|
1704
|
+
*
|
|
1705
|
+
* Pass `{}` to disable defaults; pass overrides to tweak.
|
|
1706
|
+
*/
|
|
1707
|
+
eventVolumes?: Partial<Record<ChatAudioEvent, number>>;
|
|
1647
1708
|
/** Master mute. */
|
|
1648
1709
|
muted?: boolean;
|
|
1649
1710
|
/** Custom predicate — return `false` to suppress a play call. */
|
|
@@ -1654,6 +1715,17 @@ interface ChatAudioConfig {
|
|
|
1654
1715
|
respectReducedData?: boolean;
|
|
1655
1716
|
/** Mute when host page is hidden (`visibilityState === 'hidden'`). Default: true. */
|
|
1656
1717
|
muteWhenHidden?: boolean;
|
|
1718
|
+
/**
|
|
1719
|
+
* Skip web playback entirely — `play()` becomes a no-op. Pair with
|
|
1720
|
+
* `onSoundEvent` for native hosts (cmdop_go / Tauri) that play sounds
|
|
1721
|
+
* outside the browser.
|
|
1722
|
+
*/
|
|
1723
|
+
silenced?: boolean;
|
|
1724
|
+
/**
|
|
1725
|
+
* Side-channel fired whenever `play(event)` is called. Stays active
|
|
1726
|
+
* even when `silenced=true`. Use to bridge into a native audio backend.
|
|
1727
|
+
*/
|
|
1728
|
+
onSoundEvent?: (event: ChatAudioEvent) => void;
|
|
1657
1729
|
}
|
|
1658
1730
|
interface UseChatAudioReturn {
|
|
1659
1731
|
/** Play a sound for an event. No-ops if the event has no URL or is muted. */
|
|
@@ -1667,12 +1739,16 @@ interface UseChatAudioReturn {
|
|
|
1667
1739
|
/** Master mute (persistent). */
|
|
1668
1740
|
muted: boolean;
|
|
1669
1741
|
setMuted: (m: boolean) => void;
|
|
1742
|
+
/** Flip mute state — convenience. */
|
|
1743
|
+
toggleMute: () => void;
|
|
1670
1744
|
/** Master volume 0..1 (persistent). */
|
|
1671
1745
|
volume: number;
|
|
1672
1746
|
setVolume: (v: number) => void;
|
|
1673
1747
|
/** Per-event opt-out (persistent). */
|
|
1674
1748
|
isEventEnabled: (event: ChatAudioEvent) => boolean;
|
|
1675
1749
|
setEventEnabled: (event: ChatAudioEvent, enabled: boolean) => void;
|
|
1750
|
+
/** True when no sounds are configured (or `silenced`). */
|
|
1751
|
+
isSilent: boolean;
|
|
1676
1752
|
}
|
|
1677
1753
|
|
|
1678
1754
|
/**
|
|
@@ -1774,6 +1850,14 @@ type ChatAction = {
|
|
|
1774
1850
|
} | {
|
|
1775
1851
|
type: 'MESSAGE_DELETE';
|
|
1776
1852
|
id: string;
|
|
1853
|
+
} | {
|
|
1854
|
+
type: 'MESSAGE_INJECT';
|
|
1855
|
+
message: ChatMessage;
|
|
1856
|
+
position?: 'append' | 'prepend';
|
|
1857
|
+
} | {
|
|
1858
|
+
type: 'MESSAGE_PATCH';
|
|
1859
|
+
id: string;
|
|
1860
|
+
patch: Partial<ChatMessage>;
|
|
1777
1861
|
} | {
|
|
1778
1862
|
type: 'MESSAGES_CLEAR';
|
|
1779
1863
|
} | {
|
|
@@ -1831,6 +1915,18 @@ interface UseChatReturn extends ChatState {
|
|
|
1831
1915
|
loadMore: () => Promise<void>;
|
|
1832
1916
|
newSession: () => Promise<void>;
|
|
1833
1917
|
lastError: Error | null;
|
|
1918
|
+
/**
|
|
1919
|
+
* Inject a complete message from outside (push notification, admin
|
|
1920
|
+
* takeover, system notice). De-duped by id. Position defaults to
|
|
1921
|
+
* `append` — pass `prepend` for retroactive inserts.
|
|
1922
|
+
*/
|
|
1923
|
+
injectMessage: (message: ChatMessage, position?: 'append' | 'prepend') => void;
|
|
1924
|
+
/**
|
|
1925
|
+
* Patch fields of an existing message in place (e.g. live-edit the
|
|
1926
|
+
* admin's last reply, mark a message as resolved). No-op if the id
|
|
1927
|
+
* doesn't exist.
|
|
1928
|
+
*/
|
|
1929
|
+
updateMessage: (id: string, patch: Partial<ChatMessage>) => void;
|
|
1834
1930
|
}
|
|
1835
1931
|
declare function useChat(config: UseChatConfig): UseChatReturn;
|
|
1836
1932
|
|
|
@@ -1859,11 +1955,29 @@ interface UseChatLayoutReturn {
|
|
|
1859
1955
|
}
|
|
1860
1956
|
declare function useChatLayout(config?: UseChatLayoutConfig): UseChatLayoutReturn;
|
|
1861
1957
|
|
|
1862
|
-
/**
|
|
1863
|
-
* parts of the chat tree can drive it
|
|
1864
|
-
*
|
|
1958
|
+
/** Imperative handle a composer (built-in or custom) registers so
|
|
1959
|
+
* other parts of the chat tree can drive it without prop-drilling a
|
|
1960
|
+
* ref. `focus()` is the baseline; the rest is optional so non-textarea
|
|
1961
|
+
* hosts can keep returning `{ focus }` only.
|
|
1962
|
+
*
|
|
1963
|
+
* Implemented by:
|
|
1964
|
+
* - built-in `<Composer>` — backed by `useChatComposer.textareaRef`.
|
|
1965
|
+
* - `@djangocfg/ui-tools/markdown-editor` — backed by the TipTap
|
|
1966
|
+
* editor (`editor.commands.focus('end')`).
|
|
1967
|
+
* Consumed by `VoiceComposerSlot` for the focus / move-caret behaviour
|
|
1968
|
+
* during live dictation.
|
|
1969
|
+
*/
|
|
1865
1970
|
interface ComposerHandle {
|
|
1866
1971
|
focus: () => void;
|
|
1972
|
+
/** Move the caret to the very end of the input. */
|
|
1973
|
+
moveCursorToEnd?: () => void;
|
|
1974
|
+
/** Read the current draft text. Needed by voice dictation to anchor
|
|
1975
|
+
* partial transcripts onto the user's already-typed prefix. */
|
|
1976
|
+
getValue?: () => string;
|
|
1977
|
+
/** Replace the current draft text. Voice dictation uses this to push
|
|
1978
|
+
* interim + final transcripts into the composer without owning a
|
|
1979
|
+
* controlled binding. */
|
|
1980
|
+
setValue?: (value: string) => void;
|
|
1867
1981
|
}
|
|
1868
1982
|
interface ChatContextValue extends UseChatReturn {
|
|
1869
1983
|
layout: UseChatLayoutReturn;
|
|
@@ -2126,6 +2240,12 @@ interface ChatRootProps {
|
|
|
2126
2240
|
listClassName?: string;
|
|
2127
2241
|
/** Extra className forwarded to the `<Composer>` wrapper div. */
|
|
2128
2242
|
composerClassName?: string;
|
|
2243
|
+
/**
|
|
2244
|
+
* Click in the message area → focus the composer (Slack / ChatGPT / Linear).
|
|
2245
|
+
* Honours selection drag, interactive elements, and touch input.
|
|
2246
|
+
* @default true
|
|
2247
|
+
*/
|
|
2248
|
+
focusOnEmptyClick?: boolean;
|
|
2129
2249
|
}
|
|
2130
2250
|
declare function ChatRoot(props: ChatRootProps): react_jsx_runtime.JSX.Element;
|
|
2131
2251
|
|
|
@@ -2259,9 +2379,10 @@ interface RawEvent {
|
|
|
2259
2379
|
}
|
|
2260
2380
|
interface ParseSSEOptions {
|
|
2261
2381
|
signal?: AbortSignal;
|
|
2262
|
-
/** Map a raw SSE event to
|
|
2263
|
-
* and assume the JSON shape already
|
|
2264
|
-
|
|
2382
|
+
/** Map a raw SSE event to zero, one, or many `ChatStreamEvent`s.
|
|
2383
|
+
* Default: parse `data` as JSON and assume the JSON shape already
|
|
2384
|
+
* matches `ChatStreamEvent`. */
|
|
2385
|
+
map?: (raw: RawEvent) => ChatStreamEvent | ChatStreamEvent[] | null;
|
|
2265
2386
|
idleTimeoutMs?: number;
|
|
2266
2387
|
}
|
|
2267
2388
|
declare function parseSSE(response: Response, options?: ParseSSEOptions): AsyncGenerator<ChatStreamEvent, void, void>;
|
|
@@ -2276,6 +2397,643 @@ declare class TransportError extends Error {
|
|
|
2276
2397
|
constructor(message: string, code?: string);
|
|
2277
2398
|
}
|
|
2278
2399
|
|
|
2400
|
+
/**
|
|
2401
|
+
* Pydantic-AI SSE event mapper.
|
|
2402
|
+
*
|
|
2403
|
+
* Translates the event shape emitted by pydantic-AI–style Django backends
|
|
2404
|
+
* (text_delta / tool_call / tool_result / done / error / approval_required)
|
|
2405
|
+
* into the canonical `ChatStreamEvent` stream consumed by the Chat reducer.
|
|
2406
|
+
*
|
|
2407
|
+
* Backends that don't expose a stable `tool_call_id` are supported via a
|
|
2408
|
+
* per-stream FIFO queue keyed by tool name. The earlier "Map<name, toolId>"
|
|
2409
|
+
* approach lost the first toolId when a tool was invoked twice in one turn
|
|
2410
|
+
* (e.g. `list_tasks` for search and again for confirmation) — using a queue
|
|
2411
|
+
* keeps each call/result pair correctly matched.
|
|
2412
|
+
*/
|
|
2413
|
+
|
|
2414
|
+
interface PydanticAIEvent {
|
|
2415
|
+
type: 'text_delta' | 'tool_call' | 'tool_result' | 'done' | 'error' | 'approval_required';
|
|
2416
|
+
delta?: string;
|
|
2417
|
+
tool?: string;
|
|
2418
|
+
args?: unknown;
|
|
2419
|
+
result?: unknown;
|
|
2420
|
+
/**
|
|
2421
|
+
* Structured frontend payload — present on `tool_result` when the tool has
|
|
2422
|
+
* a `result_schema`. The LLM sees only `result` (compact text); the
|
|
2423
|
+
* frontend uses `data` to render rich UI (e.g. vehicle cards).
|
|
2424
|
+
*/
|
|
2425
|
+
data?: unknown;
|
|
2426
|
+
total_tokens?: number;
|
|
2427
|
+
error?: string;
|
|
2428
|
+
tool_call_id?: string;
|
|
2429
|
+
session_id?: string;
|
|
2430
|
+
}
|
|
2431
|
+
/** Per-stream FIFO queue keyed by tool name. Created via `createToolIdQueue`. */
|
|
2432
|
+
interface ToolIdQueue {
|
|
2433
|
+
/** Allocate a new toolId for a `tool_call` event and enqueue it under `name`. */
|
|
2434
|
+
push(name: string): string;
|
|
2435
|
+
/** Pop the oldest toolId for `name` (or return an orphan marker if none). */
|
|
2436
|
+
shift(name: string): string;
|
|
2437
|
+
/** Reset all queues (e.g. on stream close). */
|
|
2438
|
+
clear(): void;
|
|
2439
|
+
}
|
|
2440
|
+
declare function createToolIdQueue(): ToolIdQueue;
|
|
2441
|
+
/**
|
|
2442
|
+
* Translate a single pydantic-AI event into zero or more `ChatStreamEvent`s.
|
|
2443
|
+
* Pass a `ToolIdQueue` shared across the lifetime of one stream so that
|
|
2444
|
+
* `tool_call` / `tool_result` pairs match correctly.
|
|
2445
|
+
*/
|
|
2446
|
+
declare function mapPydanticAIEvent(ev: PydanticAIEvent, toolIds: ToolIdQueue): Generator<ChatStreamEvent>;
|
|
2447
|
+
/**
|
|
2448
|
+
* Convenience factory: returns a `ParseSSEOptions['map']` callback that
|
|
2449
|
+
* decodes raw SSE frames as `PydanticAIEvent` JSON and yields zero or
|
|
2450
|
+
* more `ChatStreamEvent`s through `mapPydanticAIEvent`.
|
|
2451
|
+
*
|
|
2452
|
+
* Allocates an internal `ToolIdQueue` — call this once per stream.
|
|
2453
|
+
*/
|
|
2454
|
+
declare function createPydanticAISSEMap(): NonNullable<ParseSSEOptions['map']>;
|
|
2455
|
+
|
|
2456
|
+
/**
|
|
2457
|
+
* High-level transport factory for pydantic-AI–style backends.
|
|
2458
|
+
*
|
|
2459
|
+
* Composes:
|
|
2460
|
+
* - `parseSSE` for spec-compliant SSE framing (multi-line `data:`, comments, idle timeout).
|
|
2461
|
+
* - `createPydanticAISSEMap` for normalizing pydantic-AI events into `ChatStreamEvent`.
|
|
2462
|
+
*
|
|
2463
|
+
* Use when your backend speaks the canonical pydantic-AI stream shape
|
|
2464
|
+
* (`text_delta` / `tool_call` / `tool_result` / `done` / `error`).
|
|
2465
|
+
* URL building, auth headers, history loading, and optional session
|
|
2466
|
+
* bootstrapping are caller responsibilities — pass them in.
|
|
2467
|
+
*/
|
|
2468
|
+
|
|
2469
|
+
interface PydanticAIChatTransportOpts {
|
|
2470
|
+
/**
|
|
2471
|
+
* Build the SSE stream URL for a user message turn.
|
|
2472
|
+
* @example (sessionId, message) => `${base}/stream?session_id=${sessionId}&message=${encodeURIComponent(message)}`
|
|
2473
|
+
*/
|
|
2474
|
+
buildStreamUrl: (sessionId: string, message: string) => string | URL;
|
|
2475
|
+
/** Optional history loader. If omitted, `loadHistory` returns an empty page. */
|
|
2476
|
+
loadHistory?: (sessionId: string, cursor?: string | null) => Promise<HistoryPage>;
|
|
2477
|
+
/**
|
|
2478
|
+
* Optional session bootstrap. Called from `createSession`. Useful for
|
|
2479
|
+
* backends that need a `POST /sessions` round-trip or want to pre-seed
|
|
2480
|
+
* history.
|
|
2481
|
+
*/
|
|
2482
|
+
bootstrapSession?: (opts?: CreateSessionOptions) => Promise<SessionInfo>;
|
|
2483
|
+
/** Optional session teardown. */
|
|
2484
|
+
closeSession?: (sessionId: string) => Promise<void>;
|
|
2485
|
+
/**
|
|
2486
|
+
* Optional non-streaming send (for hosts that need a buffered fallback,
|
|
2487
|
+
* e.g. when the user disables streaming). Defaults to throwing — most
|
|
2488
|
+
* hosts only use streaming.
|
|
2489
|
+
*/
|
|
2490
|
+
send?: (sessionId: string, content: string, options?: SendOptions) => Promise<ChatMessage>;
|
|
2491
|
+
/** Request headers (Authorization, content-type, etc.). */
|
|
2492
|
+
buildHeaders?: () => HeadersInit | Promise<HeadersInit>;
|
|
2493
|
+
/** Override fetch (tests, retry layers). */
|
|
2494
|
+
fetchImpl?: typeof fetch;
|
|
2495
|
+
/**
|
|
2496
|
+
* HTTP method for the stream request. Defaults to `'POST'` with
|
|
2497
|
+
* `{ content, attachments, metadata }` JSON body. Set to `'GET'` if
|
|
2498
|
+
* your backend embeds the message in the URL via `buildStreamUrl`.
|
|
2499
|
+
*/
|
|
2500
|
+
streamMethod?: 'GET' | 'POST';
|
|
2501
|
+
/** Idle timeout for the SSE connection, in ms. Forwarded to `parseSSE`. */
|
|
2502
|
+
idleTimeoutMs?: number;
|
|
2503
|
+
/**
|
|
2504
|
+
* Side-channel for events that don't translate to `ChatStreamEvent`
|
|
2505
|
+
* (e.g. `approval_required` — surfaces interactive prompts outside the
|
|
2506
|
+
* normal message stream). Called synchronously while parsing the SSE
|
|
2507
|
+
* frame; mutate caller-owned state, don't `await` long work here.
|
|
2508
|
+
*/
|
|
2509
|
+
onPydanticEvent?: (event: PydanticAIEvent) => void;
|
|
2510
|
+
}
|
|
2511
|
+
declare function createPydanticAIChatTransport(opts: PydanticAIChatTransportOpts): ChatTransport;
|
|
2512
|
+
|
|
2513
|
+
type ChatFABPosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
|
|
2514
|
+
type ChatFABVariant = 'simple' | 'animated' | 'glass';
|
|
2515
|
+
type ChatFABSize = 'sm' | 'md' | 'lg' | 'responsive';
|
|
2516
|
+
interface ChatFABProps {
|
|
2517
|
+
/** Click handler — typically toggles a `ChatDock`. */
|
|
2518
|
+
onClick: () => void;
|
|
2519
|
+
/** Accessible label. */
|
|
2520
|
+
ariaLabel?: string;
|
|
2521
|
+
/** Icon inside the FAB. Defaults to a bot glyph. */
|
|
2522
|
+
icon?: ReactNode;
|
|
2523
|
+
/** Visual style. @default 'simple' */
|
|
2524
|
+
variant?: ChatFABVariant;
|
|
2525
|
+
/** Button size. @default 'md' */
|
|
2526
|
+
size?: ChatFABSize;
|
|
2527
|
+
/** Fixed-screen position. @default 'bottom-right' */
|
|
2528
|
+
position?: ChatFABPosition;
|
|
2529
|
+
/** Pixel offset from screen edges. @default 24 */
|
|
2530
|
+
offset?: number;
|
|
2531
|
+
/** z-index for the button. @default 9999 */
|
|
2532
|
+
zIndex?: number;
|
|
2533
|
+
/** Show a small attention dot (unread / new). */
|
|
2534
|
+
pulse?: boolean;
|
|
2535
|
+
/**
|
|
2536
|
+
* Numeric badge — unread count. Numbers > 9 render as "9+".
|
|
2537
|
+
* Overrides `pulse` when both set.
|
|
2538
|
+
*/
|
|
2539
|
+
badge?: number;
|
|
2540
|
+
/** Hover tooltip text. Shows next to the FAB on hover/focus. */
|
|
2541
|
+
tooltip?: string;
|
|
2542
|
+
/**
|
|
2543
|
+
* Render in-place (no fixed positioning) so the FAB sits inline in the
|
|
2544
|
+
* normal document flow. Useful for stories, screenshots, and previews
|
|
2545
|
+
* inside a contained playground panel. @default false
|
|
2546
|
+
*/
|
|
2547
|
+
inline?: boolean;
|
|
2548
|
+
/** Override classes on the button itself. */
|
|
2549
|
+
className?: string;
|
|
2550
|
+
/** Extra style on the button (caller-controlled overrides). */
|
|
2551
|
+
style?: CSSProperties;
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Floating action button for opening a chat dock. Pure presentation — owns
|
|
2555
|
+
* no state. Wire it to whatever toggles your dock open.
|
|
2556
|
+
*
|
|
2557
|
+
* For the common "FAB + dock + hotkey" composition, use `<ChatLauncher>` —
|
|
2558
|
+
* this primitive is only useful when you need custom triggering.
|
|
2559
|
+
*/
|
|
2560
|
+
declare function ChatFAB({ onClick, ariaLabel, icon, variant, size, position, offset, zIndex, pulse, badge, tooltip, inline, className, style, }: ChatFABProps): react_jsx_runtime.JSX.Element;
|
|
2561
|
+
|
|
2562
|
+
type ChatDockMode = 'popover' | 'side';
|
|
2563
|
+
type ChatDockSide = 'left' | 'right';
|
|
2564
|
+
interface ChatDockProps {
|
|
2565
|
+
/** Controlled open state. */
|
|
2566
|
+
open: boolean;
|
|
2567
|
+
/** Called when the user clicks the close button. */
|
|
2568
|
+
onClose: () => void;
|
|
2569
|
+
/** Dock contents (typically a `<Chat>` component). */
|
|
2570
|
+
children: ReactNode;
|
|
2571
|
+
/**
|
|
2572
|
+
* Visual mode.
|
|
2573
|
+
* - `popover` (default): floating card anchored to a corner, fixed size, FAB-style.
|
|
2574
|
+
* - `side`: docked panel pinned to the left/right edge, full viewport height.
|
|
2575
|
+
*/
|
|
2576
|
+
mode?: ChatDockMode;
|
|
2577
|
+
/** Side for `mode='side'`. @default 'right' */
|
|
2578
|
+
side?: ChatDockSide;
|
|
2579
|
+
/** Header title text. */
|
|
2580
|
+
title?: ReactNode;
|
|
2581
|
+
/** Header icon. Defaults to a bot glyph. */
|
|
2582
|
+
icon?: ReactNode;
|
|
2583
|
+
/**
|
|
2584
|
+
* Header actions slot (right side, before the close button).
|
|
2585
|
+
* Use `ChatHeaderActionButton` to keep visual consistency.
|
|
2586
|
+
*/
|
|
2587
|
+
headerActions?: ReactNode;
|
|
2588
|
+
/** Hide the header entirely (you render your own inside `children`). */
|
|
2589
|
+
hideHeader?: boolean;
|
|
2590
|
+
/** ARIA label for the close button. @default 'Close' */
|
|
2591
|
+
closeLabel?: string;
|
|
2592
|
+
/** Dock width in px. Clamped to viewport. @default 480 (popover) / 420 (side) */
|
|
2593
|
+
width?: number;
|
|
2594
|
+
/** Dock height in px. Only used in `popover` mode. @default 720 */
|
|
2595
|
+
height?: number;
|
|
2596
|
+
/** Which screen corner to dock to in `popover` mode. @default 'bottom-right' */
|
|
2597
|
+
position?: ChatFABPosition;
|
|
2598
|
+
/** Offset from screen edges in px (popover only). @default 24 / 96 */
|
|
2599
|
+
offset?: {
|
|
2600
|
+
horizontal?: number;
|
|
2601
|
+
vertical?: number;
|
|
2602
|
+
};
|
|
2603
|
+
/** Transition duration in ms — should match CSS animation. @default 200 */
|
|
2604
|
+
exitDurationMs?: number;
|
|
2605
|
+
/** z-index. @default 10000 */
|
|
2606
|
+
zIndex?: number;
|
|
2607
|
+
/** Accessible dialog label. */
|
|
2608
|
+
ariaLabel?: string;
|
|
2609
|
+
/** Extra classes on the dock container. */
|
|
2610
|
+
className?: string;
|
|
2611
|
+
/**
|
|
2612
|
+
* Take over the full viewport on mobile (< 768px). Applies to both modes.
|
|
2613
|
+
* @default true
|
|
2614
|
+
*/
|
|
2615
|
+
mobileFullscreen?: boolean;
|
|
2616
|
+
/**
|
|
2617
|
+
* Render in-place (not in `document.body` via a portal). Useful for stories,
|
|
2618
|
+
* screenshots, or wrapping the dock inside a custom container. @default false
|
|
2619
|
+
*/
|
|
2620
|
+
disablePortal?: boolean;
|
|
2621
|
+
/**
|
|
2622
|
+
* Drop fixed positioning entirely — the dock renders as a normal flow
|
|
2623
|
+
* element sized by `width`/`height`. Combine with `disablePortal` for
|
|
2624
|
+
* stories/previews where the dock should sit inside the panel instead
|
|
2625
|
+
* of attaching to the viewport. @default false
|
|
2626
|
+
*/
|
|
2627
|
+
inline?: boolean;
|
|
2628
|
+
/**
|
|
2629
|
+
* In `mode='side'`, reserve space on the document body so page content
|
|
2630
|
+
* isn't covered by the dock. Sets `padding-{side}` on `<body>` while
|
|
2631
|
+
* the dock is open and exposes the width via the `--chat-dock-reserve`
|
|
2632
|
+
* CSS variable for custom layouts. @default true (when mode='side')
|
|
2633
|
+
*/
|
|
2634
|
+
reserveBodySpace?: boolean;
|
|
2635
|
+
}
|
|
2636
|
+
/**
|
|
2637
|
+
* Fixed-position chat surface. Two modes:
|
|
2638
|
+
*
|
|
2639
|
+
* - `popover` — floating card anchored to a corner. Companion to `<ChatFAB>`.
|
|
2640
|
+
* - `side` — full-height panel pinned to the left/right edge. App-shell style.
|
|
2641
|
+
*
|
|
2642
|
+
* Renders only when `open` is true (plus the leave-transition tail). Uses
|
|
2643
|
+
* `useChatPresence` for the four-phase mount/animate/unmount cycle.
|
|
2644
|
+
*/
|
|
2645
|
+
declare function ChatDock({ open, onClose, children, mode, side, title, icon, headerActions, hideHeader, closeLabel, width, height, position, offset, exitDurationMs, zIndex, ariaLabel, className, mobileFullscreen, disablePortal, inline, reserveBodySpace, }: ChatDockProps): react_jsx_runtime.JSX.Element;
|
|
2646
|
+
|
|
2647
|
+
interface ChatHeaderProps {
|
|
2648
|
+
/** Window title text. */
|
|
2649
|
+
title?: ReactNode;
|
|
2650
|
+
/** Icon next to the title. Defaults to a bot glyph. */
|
|
2651
|
+
icon?: ReactNode;
|
|
2652
|
+
/**
|
|
2653
|
+
* Action slot — appears to the right of the title, before the close button.
|
|
2654
|
+
* Use for reset / settings / minimize / etc. Compose with `ChatHeaderActionButton`.
|
|
2655
|
+
*/
|
|
2656
|
+
actions?: ReactNode;
|
|
2657
|
+
/** Show the close (×) button. @default true */
|
|
2658
|
+
showClose?: boolean;
|
|
2659
|
+
/** Close click handler. */
|
|
2660
|
+
onClose?: () => void;
|
|
2661
|
+
/** ARIA label for the close button. @default 'Close' */
|
|
2662
|
+
closeLabel?: string;
|
|
2663
|
+
/** Replace the close button entirely (rare — most hosts want the default). */
|
|
2664
|
+
closeSlot?: ReactNode;
|
|
2665
|
+
/** Extra classes on the `<header>` element. */
|
|
2666
|
+
className?: string;
|
|
2667
|
+
}
|
|
2668
|
+
/**
|
|
2669
|
+
* Standalone chat header — title + icon + action slot + close button.
|
|
2670
|
+
*
|
|
2671
|
+
* Used by `<ChatDock>` automatically, but can be rendered standalone when
|
|
2672
|
+
* the host owns the chat container (e.g. embedded inline in a page).
|
|
2673
|
+
*/
|
|
2674
|
+
declare function ChatHeader({ title, icon, actions, showClose, onClose, closeLabel, closeSlot, className, }: ChatHeaderProps): react_jsx_runtime.JSX.Element;
|
|
2675
|
+
|
|
2676
|
+
interface ChatHeaderActionButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
|
2677
|
+
/** Icon (required). */
|
|
2678
|
+
icon: ReactNode;
|
|
2679
|
+
/** Accessible label + native tooltip. */
|
|
2680
|
+
ariaLabel: string;
|
|
2681
|
+
/** Optional unread / status badge — small number on top-right. */
|
|
2682
|
+
badge?: number;
|
|
2683
|
+
/** Mark as destructive — uses destructive hover tokens. */
|
|
2684
|
+
destructive?: boolean;
|
|
2685
|
+
/** Optional visual loading state (e.g. while reset is in flight). */
|
|
2686
|
+
loading?: boolean;
|
|
2687
|
+
}
|
|
2688
|
+
/**
|
|
2689
|
+
* Compact icon button for the chat header actions slot.
|
|
2690
|
+
*
|
|
2691
|
+
* Standard chrome: 28×28 ghost button, hover bg-accent, focus ring, optional
|
|
2692
|
+
* destructive variant, optional numeric badge for unread / pending.
|
|
2693
|
+
*
|
|
2694
|
+
* @example
|
|
2695
|
+
* ```tsx
|
|
2696
|
+
* <ChatHeader
|
|
2697
|
+
* title="Assistant"
|
|
2698
|
+
* onClose={close}
|
|
2699
|
+
* actions={
|
|
2700
|
+
* <>
|
|
2701
|
+
* <ChatHeaderActionButton
|
|
2702
|
+
* icon={<RotateCcw className="h-3.5 w-3.5" />}
|
|
2703
|
+
* ariaLabel="Clear context"
|
|
2704
|
+
* onClick={handleReset}
|
|
2705
|
+
* loading={isResetting}
|
|
2706
|
+
* />
|
|
2707
|
+
* <ChatHeaderActionButton
|
|
2708
|
+
* icon={<Settings className="h-3.5 w-3.5" />}
|
|
2709
|
+
* ariaLabel="Settings"
|
|
2710
|
+
* onClick={openSettings}
|
|
2711
|
+
* />
|
|
2712
|
+
* </>
|
|
2713
|
+
* }
|
|
2714
|
+
* />
|
|
2715
|
+
* ```
|
|
2716
|
+
*/
|
|
2717
|
+
declare const ChatHeaderActionButton: react.ForwardRefExoticComponent<ChatHeaderActionButtonProps & react.RefAttributes<HTMLButtonElement>>;
|
|
2718
|
+
|
|
2719
|
+
interface ChatHeaderModeToggleProps {
|
|
2720
|
+
/** Current dock mode. */
|
|
2721
|
+
mode: ChatDockMode;
|
|
2722
|
+
/** Toggle handler. Wire to `useChatDockPrefs().toggleMode`. */
|
|
2723
|
+
onToggle: () => void;
|
|
2724
|
+
/** Override aria/tooltip label for popover→side. */
|
|
2725
|
+
expandLabel?: string;
|
|
2726
|
+
/** Override aria/tooltip label for side→popover. */
|
|
2727
|
+
collapseLabel?: string;
|
|
2728
|
+
/**
|
|
2729
|
+
* Always render — useful for stories. By default the toggle hides itself on
|
|
2730
|
+
* viewports below `lg` (1024px) since side mode falls back to popover there.
|
|
2731
|
+
*/
|
|
2732
|
+
forceVisible?: boolean;
|
|
2733
|
+
}
|
|
2734
|
+
/**
|
|
2735
|
+
* "Dock to side" / "back to popover" toggle.
|
|
2736
|
+
*
|
|
2737
|
+
* Side mode is desktop-only — on viewports below `lg` (1024px) `<ChatDock>`
|
|
2738
|
+
* silently falls back to popover anyway, so the toggle has nothing to do
|
|
2739
|
+
* and auto-hides. Pass `forceVisible` to override (e.g. in stories).
|
|
2740
|
+
*/
|
|
2741
|
+
declare function ChatHeaderModeToggle({ mode, onToggle, expandLabel, collapseLabel, forceVisible, }: ChatHeaderModeToggleProps): react_jsx_runtime.JSX.Element;
|
|
2742
|
+
|
|
2743
|
+
interface ChatHeaderAudioToggleProps {
|
|
2744
|
+
/** Current muted state. */
|
|
2745
|
+
muted: boolean;
|
|
2746
|
+
/** Toggle handler. Wire to `useChatAudio().setMuted` or `toggleMute`. */
|
|
2747
|
+
onToggle: () => void;
|
|
2748
|
+
/** Override tooltip label for muted → unmuted. */
|
|
2749
|
+
unmuteLabel?: string;
|
|
2750
|
+
/** Override tooltip label for unmuted → muted. */
|
|
2751
|
+
muteLabel?: string;
|
|
2752
|
+
}
|
|
2753
|
+
/**
|
|
2754
|
+
* Mute / unmute notification sounds. Drop into a `<ChatHeader>` actions
|
|
2755
|
+
* slot or into `<ChatDock headerActions>`.
|
|
2756
|
+
*
|
|
2757
|
+
* @example
|
|
2758
|
+
* ```tsx
|
|
2759
|
+
* const audio = useChatAudio({ sounds: {...} });
|
|
2760
|
+
* <ChatHeaderAudioToggle muted={audio.muted} onToggle={() => audio.setMuted(!audio.muted)} />
|
|
2761
|
+
* ```
|
|
2762
|
+
*/
|
|
2763
|
+
declare function ChatHeaderAudioToggle({ muted, onToggle, unmuteLabel, muteLabel, }: ChatHeaderAudioToggleProps): react_jsx_runtime.JSX.Element;
|
|
2764
|
+
|
|
2765
|
+
interface ChatHeaderResetButtonProps {
|
|
2766
|
+
/**
|
|
2767
|
+
* Backend reset call. Should resolve to `true` on success.
|
|
2768
|
+
* Plugged into `useChatReset` for in-flight state.
|
|
2769
|
+
*/
|
|
2770
|
+
onReset: () => Promise<boolean>;
|
|
2771
|
+
/** Called after a successful reset (e.g. clear local messages, refetch). */
|
|
2772
|
+
onSuccess?: () => void;
|
|
2773
|
+
/** Called when reset fails (returned `false` or threw). */
|
|
2774
|
+
onError?: (error?: unknown) => void;
|
|
2775
|
+
/**
|
|
2776
|
+
* Show a `window.dialog.confirm` before calling `onReset`. @default true
|
|
2777
|
+
*
|
|
2778
|
+
* Requires the host to mount `<DialogProvider>` from `@djangocfg/ui-core`
|
|
2779
|
+
* — it installs the `window.dialog` API used here.
|
|
2780
|
+
*/
|
|
2781
|
+
confirm?: boolean;
|
|
2782
|
+
/** Confirm dialog title. */
|
|
2783
|
+
confirmTitle?: string;
|
|
2784
|
+
/** Confirm dialog message. */
|
|
2785
|
+
confirmMessage?: string;
|
|
2786
|
+
/** Override tooltip / aria label. */
|
|
2787
|
+
ariaLabel?: string;
|
|
2788
|
+
}
|
|
2789
|
+
/**
|
|
2790
|
+
* Standard chat-reset action: prompts the user via `window.dialog.confirm`,
|
|
2791
|
+
* then runs the backend reset call through `useChatReset` so the button
|
|
2792
|
+
* spins while it's in flight.
|
|
2793
|
+
*
|
|
2794
|
+
* @example
|
|
2795
|
+
* ```tsx
|
|
2796
|
+
* <ChatHeaderResetButton
|
|
2797
|
+
* onReset={api.clearChat}
|
|
2798
|
+
* onSuccess={() => chat.clearMessages()}
|
|
2799
|
+
* />
|
|
2800
|
+
* ```
|
|
2801
|
+
*/
|
|
2802
|
+
declare function ChatHeaderResetButton({ onReset, onSuccess, onError, confirm, confirmTitle, confirmMessage, ariaLabel, }: ChatHeaderResetButtonProps): react_jsx_runtime.JSX.Element;
|
|
2803
|
+
|
|
2804
|
+
interface ChatGreetingProps {
|
|
2805
|
+
/** Controlled visibility — usually `!chatOpen && !userDismissed`. */
|
|
2806
|
+
open: boolean;
|
|
2807
|
+
/** Greeting text. Pass a string for the default bubble, or any ReactNode. */
|
|
2808
|
+
children: ReactNode;
|
|
2809
|
+
/** Click handler — typically opens the chat. Bubble is clickable when set. */
|
|
2810
|
+
onClick?: () => void;
|
|
2811
|
+
/** Close (×) button handler — typically marks the greeting as dismissed. */
|
|
2812
|
+
onDismiss?: () => void;
|
|
2813
|
+
/** Anchor relative to a FAB on the same side. @default 'bottom-right' */
|
|
2814
|
+
position?: ChatFABPosition;
|
|
2815
|
+
/**
|
|
2816
|
+
* Horizontal pixel offset matching the FAB's `offset` prop, so the greeting
|
|
2817
|
+
* lines up under the FAB. @default 24
|
|
2818
|
+
*/
|
|
2819
|
+
fabOffset?: number;
|
|
2820
|
+
/**
|
|
2821
|
+
* Vertical pixel offset above/below the FAB centerline. @default 96
|
|
2822
|
+
* (room for an `md` FAB plus a small gap).
|
|
2823
|
+
*/
|
|
2824
|
+
fabClearance?: number;
|
|
2825
|
+
/** Delay before the greeting appears, in ms. @default 1500 */
|
|
2826
|
+
delayMs?: number;
|
|
2827
|
+
/** z-index. @default 9998 (just below the default FAB at 9999). */
|
|
2828
|
+
zIndex?: number;
|
|
2829
|
+
/** Override classes on the bubble. */
|
|
2830
|
+
className?: string;
|
|
2831
|
+
/** Override styles on the bubble. */
|
|
2832
|
+
style?: CSSProperties;
|
|
2833
|
+
/** Optional sender avatar / icon shown on the left. */
|
|
2834
|
+
avatar?: ReactNode;
|
|
2835
|
+
/** Optional sender label rendered above the text. */
|
|
2836
|
+
senderName?: string;
|
|
2837
|
+
/** ARIA label for the dismiss button. @default 'Dismiss' */
|
|
2838
|
+
dismissLabel?: string;
|
|
2839
|
+
/**
|
|
2840
|
+
* Render in-place (no fixed positioning). Useful for stories and inline previews.
|
|
2841
|
+
* @default false
|
|
2842
|
+
*/
|
|
2843
|
+
inline?: boolean;
|
|
2844
|
+
}
|
|
2845
|
+
/**
|
|
2846
|
+
* Greeting bubble shown next to a `ChatFAB` to invite the user to start a
|
|
2847
|
+
* conversation (LiveChat / Intercom-style proactive prompt).
|
|
2848
|
+
*
|
|
2849
|
+
* Renders fixed-position, anchored to the same corner as the FAB. Owns its
|
|
2850
|
+
* own delayed-mount + presence animation. Hide on chat open and/or after
|
|
2851
|
+
* user dismissal.
|
|
2852
|
+
*
|
|
2853
|
+
* @example
|
|
2854
|
+
* ```tsx
|
|
2855
|
+
* const [open, setOpen] = useState(false);
|
|
2856
|
+
* const [dismissed, setDismissed] = useState(false);
|
|
2857
|
+
*
|
|
2858
|
+
* <ChatLauncher
|
|
2859
|
+
* open={open}
|
|
2860
|
+
* onOpenChange={setOpen}
|
|
2861
|
+
* fab={{ variant: 'animated' }}
|
|
2862
|
+
* dock={{ title: 'Support' }}
|
|
2863
|
+
* >
|
|
2864
|
+
* <SupportChat />
|
|
2865
|
+
* </ChatLauncher>
|
|
2866
|
+
*
|
|
2867
|
+
* <ChatGreeting
|
|
2868
|
+
* open={!open && !dismissed}
|
|
2869
|
+
* onClick={() => setOpen(true)}
|
|
2870
|
+
* onDismiss={() => setDismissed(true)}
|
|
2871
|
+
* senderName="Anna from Support"
|
|
2872
|
+
* delayMs={2000}
|
|
2873
|
+
* >
|
|
2874
|
+
* Hi! 👋 Got a question? I'm here to help.
|
|
2875
|
+
* </ChatGreeting>
|
|
2876
|
+
* ```
|
|
2877
|
+
*/
|
|
2878
|
+
declare function ChatGreeting({ open, children, onClick, onDismiss, position, fabOffset, fabClearance, delayMs, zIndex, className, style, avatar, senderName, dismissLabel, inline, }: ChatGreetingProps): react_jsx_runtime.JSX.Element;
|
|
2879
|
+
|
|
2880
|
+
interface ChatUnreadPreviewProps {
|
|
2881
|
+
/** Controlled — usually `!dockOpen && !!message`. */
|
|
2882
|
+
open: boolean;
|
|
2883
|
+
/** Inbound message to preview. `null` hides the bubble. */
|
|
2884
|
+
message: ChatMessage | null;
|
|
2885
|
+
/** Tap → open chat + mark read. */
|
|
2886
|
+
onClick?: () => void;
|
|
2887
|
+
/** × → mark read without opening. */
|
|
2888
|
+
onDismiss?: () => void;
|
|
2889
|
+
/** Anchor corner — match the FAB so the bubble sits above it. @default 'bottom-right' */
|
|
2890
|
+
position?: ChatFABPosition;
|
|
2891
|
+
/** Horizontal offset from screen edge, matches the FAB. @default 24 */
|
|
2892
|
+
fabOffset?: number;
|
|
2893
|
+
/** Vertical clearance above/below the FAB. @default 96 */
|
|
2894
|
+
fabClearance?: number;
|
|
2895
|
+
/** Lines of body text before ellipsis. @default 2 */
|
|
2896
|
+
truncate?: number;
|
|
2897
|
+
/** z-index. @default 9998 */
|
|
2898
|
+
zIndex?: number;
|
|
2899
|
+
/** Render in-place (stories / previews). @default false */
|
|
2900
|
+
inline?: boolean;
|
|
2901
|
+
/** Override classes on the bubble. */
|
|
2902
|
+
className?: string;
|
|
2903
|
+
/** Override styles on the bubble. */
|
|
2904
|
+
style?: CSSProperties;
|
|
2905
|
+
/** ARIA label for the dismiss button. @default 'Mark as read' */
|
|
2906
|
+
dismissLabel?: string;
|
|
2907
|
+
/** Override the avatar — defaults to derived from `message.sender`. */
|
|
2908
|
+
avatar?: ReactNode;
|
|
2909
|
+
/** Override the sender label — defaults to `message.sender?.name`. */
|
|
2910
|
+
senderName?: string;
|
|
2911
|
+
}
|
|
2912
|
+
/**
|
|
2913
|
+
* Push-notification bubble next to the chat FAB.
|
|
2914
|
+
*
|
|
2915
|
+
* Shows the last inbound message while the chat is closed —
|
|
2916
|
+
* Intercom / LiveChat-style. Tap → open chat (host wires `onClick`).
|
|
2917
|
+
* Dismiss × → keep chat closed but stop nagging.
|
|
2918
|
+
*
|
|
2919
|
+
* Pair with `useChatUnread()` (inside `<ChatProvider>`) for state.
|
|
2920
|
+
*/
|
|
2921
|
+
declare function ChatUnreadPreview({ open, message, onClick, onDismiss, position, fabOffset, fabClearance, truncate, zIndex, inline, className, style, dismissLabel, avatar, senderName, }: ChatUnreadPreviewProps): react_jsx_runtime.JSX.Element;
|
|
2922
|
+
|
|
2923
|
+
interface ChatLauncherHotkey {
|
|
2924
|
+
/** Key (case-sensitive single char or named like 'Escape'). */
|
|
2925
|
+
key: string;
|
|
2926
|
+
/** Require Cmd (mac) or Ctrl (other). */
|
|
2927
|
+
meta?: boolean;
|
|
2928
|
+
/** Require Shift. */
|
|
2929
|
+
shift?: boolean;
|
|
2930
|
+
/** Require Alt. */
|
|
2931
|
+
alt?: boolean;
|
|
2932
|
+
}
|
|
2933
|
+
interface ChatLauncherGreeting extends Omit<ChatGreetingProps, 'open' | 'onClick' | 'onDismiss' | 'position' | 'fabOffset' | 'children'> {
|
|
2934
|
+
/** Greeting body — string for the default style, or any ReactNode. */
|
|
2935
|
+
content: ReactNode;
|
|
2936
|
+
/** Persistence key for "user dismissed this greeting" in `localStorage`. Pass `null` to disable persistence. @default null */
|
|
2937
|
+
dismissStorageKey?: string | null;
|
|
2938
|
+
/** Hide the greeting once the user opens the chat. @default true */
|
|
2939
|
+
hideOnOpen?: boolean;
|
|
2940
|
+
}
|
|
2941
|
+
interface ChatLauncherProps {
|
|
2942
|
+
/** Dock contents — typically a `<Chat>` instance. */
|
|
2943
|
+
children: ReactNode;
|
|
2944
|
+
/** FAB customization (icon, position, label, pulse, badge, tooltip, variant, size). */
|
|
2945
|
+
fab?: Omit<ChatFABProps, 'onClick'>;
|
|
2946
|
+
/** Dock customization (size, title, position, transition, mobileFullscreen). */
|
|
2947
|
+
dock?: Omit<ChatDockProps, 'open' | 'onClose' | 'children'>;
|
|
2948
|
+
/**
|
|
2949
|
+
* Proactive greeting bubble shown next to the FAB before the user opens the chat.
|
|
2950
|
+
* Set to a string or full config object. Omit to disable.
|
|
2951
|
+
*/
|
|
2952
|
+
greeting?: string | ChatLauncherGreeting;
|
|
2953
|
+
/** Open/close via a keyboard shortcut. */
|
|
2954
|
+
hotkey?: ChatLauncherHotkey;
|
|
2955
|
+
/** Initial open state for uncontrolled mode. @default false */
|
|
2956
|
+
defaultOpen?: boolean;
|
|
2957
|
+
/** Controlled open state (pair with `onOpenChange`). */
|
|
2958
|
+
open?: boolean;
|
|
2959
|
+
/** Controlled open state setter. */
|
|
2960
|
+
onOpenChange?: (open: boolean) => void;
|
|
2961
|
+
/**
|
|
2962
|
+
* Focus the composer textarea when the dock opens. Saves a click for
|
|
2963
|
+
* every "FAB → start typing" interaction. @default true
|
|
2964
|
+
*/
|
|
2965
|
+
autoFocusComposerOnOpen?: boolean;
|
|
2966
|
+
/**
|
|
2967
|
+
* Close the dock on `Escape`. Mirrors standard popover / drawer UX.
|
|
2968
|
+
* Set to `false` to disable (e.g. if you want Escape to do something
|
|
2969
|
+
* else inside the chat). @default true
|
|
2970
|
+
*/
|
|
2971
|
+
closeOnEscape?: boolean;
|
|
2972
|
+
/**
|
|
2973
|
+
* Last inbound message (admin reply / system notice / agent push) the
|
|
2974
|
+
* user hasn't seen yet. Drives the `<ChatUnreadPreview>` bubble next
|
|
2975
|
+
* to the FAB and (by default) the FAB badge.
|
|
2976
|
+
*
|
|
2977
|
+
* Source it from `useChatUnread()` inside your `<ChatProvider>`.
|
|
2978
|
+
*/
|
|
2979
|
+
unreadMessage?: ChatMessage | null;
|
|
2980
|
+
/**
|
|
2981
|
+
* Called when the user opens the chat via FAB/preview/hotkey or
|
|
2982
|
+
* dismisses the preview with ×. Wire to `useChatUnread().markRead`.
|
|
2983
|
+
*/
|
|
2984
|
+
onMarkRead?: () => void;
|
|
2985
|
+
/**
|
|
2986
|
+
* Customize the unread bubble (`truncate`, `dismissLabel`, …).
|
|
2987
|
+
* `open`/`message`/`onClick`/`onDismiss`/`position`/`fabOffset` are
|
|
2988
|
+
* wired automatically.
|
|
2989
|
+
*/
|
|
2990
|
+
unreadPreview?: Omit<ChatUnreadPreviewProps, 'open' | 'message' | 'onClick' | 'onDismiss' | 'position' | 'fabOffset'>;
|
|
2991
|
+
/**
|
|
2992
|
+
* Auto-inject a mute / unmute button into the header. Pass the
|
|
2993
|
+
* `useChatAudio()` (or any compatible `{ muted, toggleMute }`)
|
|
2994
|
+
* instance — the launcher renders `<ChatHeaderAudioToggle>` in the
|
|
2995
|
+
* header's actions slot when audio is actually configured (not silent).
|
|
2996
|
+
*
|
|
2997
|
+
* Hosts that manage their own header can ignore this prop and render
|
|
2998
|
+
* `<ChatHeaderAudioToggle>` directly.
|
|
2999
|
+
*/
|
|
3000
|
+
audio?: {
|
|
3001
|
+
muted: boolean;
|
|
3002
|
+
toggleMute: () => void;
|
|
3003
|
+
isSilent?: boolean;
|
|
3004
|
+
} | null;
|
|
3005
|
+
/**
|
|
3006
|
+
* Suppress the auto-injected audio toggle even when `audio` is passed.
|
|
3007
|
+
* @default false
|
|
3008
|
+
*/
|
|
3009
|
+
hideAudioToggle?: boolean;
|
|
3010
|
+
}
|
|
3011
|
+
/**
|
|
3012
|
+
* Floating chat launcher = FAB + Dock + presence + optional greeting + hotkey.
|
|
3013
|
+
*
|
|
3014
|
+
* 99% of hosts use this directly. For non-FAB triggers (e.g. an inline
|
|
3015
|
+
* link in the page) compose `<ChatDock>` with your own button.
|
|
3016
|
+
*/
|
|
3017
|
+
declare function ChatLauncher({ children, fab, dock, greeting, hotkey, defaultOpen, open: controlledOpen, onOpenChange, autoFocusComposerOnOpen, closeOnEscape, unreadMessage, onMarkRead, unreadPreview, audio, hideAudioToggle, }: ChatLauncherProps): react_jsx_runtime.JSX.Element;
|
|
3018
|
+
|
|
3019
|
+
type ChatPresencePhase = 'hidden' | 'entering' | 'visible' | 'leaving';
|
|
3020
|
+
/**
|
|
3021
|
+
* Presence state machine for floating popovers.
|
|
3022
|
+
*
|
|
3023
|
+
* Drives a four-phase lifecycle so enter/leave CSS transitions actually fire:
|
|
3024
|
+
*
|
|
3025
|
+
* hidden → entering (mount, transition class starts) → visible
|
|
3026
|
+
* visible → leaving (transition runs) → hidden (unmount)
|
|
3027
|
+
*
|
|
3028
|
+
* Mounting in `entering` and ticking to `visible` on the next paint is what
|
|
3029
|
+
* lets transition classes animate. Without it the element appears already
|
|
3030
|
+
* at its final state and CSS transitions never observe a change.
|
|
3031
|
+
*
|
|
3032
|
+
* @param open - controlled open state
|
|
3033
|
+
* @param exitDurationMs - how long the leave transition runs; should match CSS
|
|
3034
|
+
*/
|
|
3035
|
+
declare function useChatPresence(open: boolean, exitDurationMs?: number): ChatPresencePhase;
|
|
3036
|
+
|
|
2279
3037
|
/**
|
|
2280
3038
|
* @deprecated Plan64. As of ui-tools 2.1.369, `<MessageList>` is
|
|
2281
3039
|
* virtualized via react-virtuoso and owns its own scroll viewport.
|
|
@@ -2319,6 +3077,11 @@ interface UseChatHistoryOptions {
|
|
|
2319
3077
|
* bump scrollTop by the delta so the previously-visible message stays put. */
|
|
2320
3078
|
declare function useChatHistory(options: UseChatHistoryOptions): void;
|
|
2321
3079
|
|
|
3080
|
+
/**
|
|
3081
|
+
* Chat-specific audio facade. Thin wrapper over `useNotificationSounds`
|
|
3082
|
+
* from `@djangocfg/ui-core` — keeps the `ChatAudioEvent` typing while
|
|
3083
|
+
* the underlying bus / prefs / Safari-unlock logic lives in ui-core.
|
|
3084
|
+
*/
|
|
2322
3085
|
declare function useChatAudio(config?: ChatAudioConfig): UseChatAudioReturn;
|
|
2323
3086
|
|
|
2324
3087
|
interface ChatLightboxState {
|
|
@@ -2404,32 +3167,167 @@ declare function useAutoFocusOnStreamEnd(options?: UseAutoFocusOnStreamEndOption
|
|
|
2404
3167
|
*
|
|
2405
3168
|
* No-op when called outside a `<ChatProvider>`.
|
|
2406
3169
|
*/
|
|
2407
|
-
declare function useRegisterComposer(
|
|
3170
|
+
declare function useRegisterComposer(handle: ComposerHandle): void;
|
|
2408
3171
|
|
|
2409
|
-
interface
|
|
2410
|
-
/**
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
3172
|
+
interface UseChatResetOptions {
|
|
3173
|
+
/**
|
|
3174
|
+
* Backend call that performs the actual reset (e.g. POST /chat/reset).
|
|
3175
|
+
* Should resolve to `true` on success, `false` on failure.
|
|
3176
|
+
* Throwing also counts as failure — caught and logged.
|
|
3177
|
+
*/
|
|
3178
|
+
onReset: () => Promise<boolean>;
|
|
3179
|
+
/**
|
|
3180
|
+
* Called after a successful reset (status === true). Use to clear the
|
|
3181
|
+
* local message list, navigate, or fire analytics.
|
|
3182
|
+
*/
|
|
3183
|
+
onSuccess?: () => void;
|
|
3184
|
+
/**
|
|
3185
|
+
* Called when reset fails (returned `false` or threw). Defaults to no-op
|
|
3186
|
+
* — wire to a toast/banner if you want to surface it.
|
|
3187
|
+
*/
|
|
3188
|
+
onError?: (error?: unknown) => void;
|
|
2419
3189
|
}
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
3190
|
+
interface UseChatResetReturn {
|
|
3191
|
+
/** Trigger the reset. Safe to call multiple times — re-entrant guard. */
|
|
3192
|
+
reset: () => Promise<boolean>;
|
|
3193
|
+
/** True while the reset is in flight. */
|
|
3194
|
+
isResetting: boolean;
|
|
3195
|
+
}
|
|
3196
|
+
/**
|
|
3197
|
+
* Generic "clear chat context" hook.
|
|
3198
|
+
*
|
|
3199
|
+
* Stays generic — the backend call lives in the host (it knows the URL,
|
|
3200
|
+
* auth, project slug). Provides the in-flight state and success/error
|
|
3201
|
+
* callbacks every consumer wires up the same way.
|
|
3202
|
+
*
|
|
3203
|
+
* @example
|
|
3204
|
+
* ```tsx
|
|
3205
|
+
* const { reset, isResetting } = useChatReset({
|
|
3206
|
+
* onReset: async () => {
|
|
3207
|
+
* const res = await fetch('/api/chat/reset', { method: 'POST', credentials: 'include' });
|
|
3208
|
+
* return res.ok;
|
|
3209
|
+
* },
|
|
3210
|
+
* onSuccess: () => chat.clearMessages(),
|
|
3211
|
+
* });
|
|
3212
|
+
* ```
|
|
3213
|
+
*/
|
|
3214
|
+
declare function useChatReset(opts: UseChatResetOptions): UseChatResetReturn;
|
|
3215
|
+
|
|
3216
|
+
interface UseVisitorFingerprintOptions {
|
|
3217
|
+
/** localStorage key. @default 'chat.visitor.fingerprint' */
|
|
3218
|
+
storageKey?: string;
|
|
3219
|
+
}
|
|
3220
|
+
/**
|
|
3221
|
+
* Persistent anonymous visitor id, kept in `localStorage`.
|
|
3222
|
+
*
|
|
3223
|
+
* Returns `null` on the first render (SSR-safe) and the stable id from
|
|
3224
|
+
* the second render onwards. Use as `fingerprint` for public chat
|
|
3225
|
+
* transports that need to dedupe sessions per visitor without auth.
|
|
3226
|
+
*/
|
|
3227
|
+
declare function useVisitorFingerprint(opts?: UseVisitorFingerprintOptions): string | null;
|
|
3228
|
+
|
|
3229
|
+
interface ChatDockPrefs {
|
|
3230
|
+
/** Popover (FAB-style) or side-docked panel. */
|
|
3231
|
+
mode: ChatDockMode;
|
|
3232
|
+
/** Which edge the side dock attaches to. */
|
|
3233
|
+
side: ChatDockSide;
|
|
3234
|
+
/** Width in px when side-docked (resizable in the future). */
|
|
3235
|
+
sideWidth: number;
|
|
3236
|
+
}
|
|
3237
|
+
declare const DEFAULT_DOCK_PREFS: ChatDockPrefs;
|
|
3238
|
+
interface UseChatDockPrefsOptions {
|
|
3239
|
+
/** localStorage key. @default 'chat.dock.prefs' */
|
|
3240
|
+
storageKey?: string;
|
|
3241
|
+
/** Override the baseline defaults (per-product branding, etc.). */
|
|
3242
|
+
defaults?: Partial<ChatDockPrefs>;
|
|
3243
|
+
}
|
|
3244
|
+
interface UseChatDockPrefsReturn extends ChatDockPrefs {
|
|
3245
|
+
/** Merge-update — pass only the fields that changed. */
|
|
3246
|
+
setPrefs: (patch: Partial<ChatDockPrefs>) => void;
|
|
3247
|
+
/** Convenience toggle: popover ⇆ side. */
|
|
3248
|
+
toggleMode: () => void;
|
|
3249
|
+
/** Convenience toggle: right ⇆ left (only affects side mode). */
|
|
3250
|
+
toggleSide: () => void;
|
|
3251
|
+
/** Reset to defaults. */
|
|
3252
|
+
reset: () => void;
|
|
3253
|
+
}
|
|
3254
|
+
/**
|
|
3255
|
+
* Persistent dock preferences (mode / side / width) via ui-core localStorage.
|
|
3256
|
+
*
|
|
3257
|
+
* SSR-safe: returns defaults on the server, hydrates on mount.
|
|
3258
|
+
* Survives reloads — power users keep their preferred chat layout.
|
|
3259
|
+
*/
|
|
3260
|
+
declare function useChatDockPrefs(opts?: UseChatDockPrefsOptions): UseChatDockPrefsReturn;
|
|
3261
|
+
|
|
3262
|
+
interface UseFocusOnEmptyClickOptions {
|
|
3263
|
+
/**
|
|
3264
|
+
* Custom focus target. Defaults to the composer registered in the chat
|
|
3265
|
+
* context.
|
|
3266
|
+
*/
|
|
3267
|
+
targetRef?: RefObject<Focusable | HTMLElement | null>;
|
|
3268
|
+
/** Opt-out without unmounting the hook. @default true */
|
|
3269
|
+
enabled?: boolean;
|
|
3270
|
+
/**
|
|
3271
|
+
* Don't focus if currently streaming (user is reading the reply).
|
|
3272
|
+
* @default true
|
|
3273
|
+
*/
|
|
3274
|
+
skipWhileStreaming?: boolean;
|
|
3275
|
+
}
|
|
3276
|
+
/**
|
|
3277
|
+
* "Click anywhere in the chat → focus the composer" — Slack / Linear /
|
|
3278
|
+
* ChatGPT behaviour.
|
|
3279
|
+
*
|
|
3280
|
+
* Returns a single `onMouseUp` handler to attach to the scrollable
|
|
3281
|
+
* messages container. Heuristics that mirror the popular chat apps:
|
|
3282
|
+
*
|
|
3283
|
+
* 1. Ignore clicks on interactive elements (`button`, `a`, `input`,
|
|
3284
|
+
* `textarea`, `[role="button"]`, `[contenteditable]`, …) — they
|
|
3285
|
+
* have their own behaviour.
|
|
3286
|
+
* 2. Ignore clicks that produced a text selection (drag-to-select).
|
|
3287
|
+
* Stealing focus would break copy-paste flow.
|
|
3288
|
+
* 3. Ignore touch input — on mobile the system focuses the textarea
|
|
3289
|
+
* via tap on the composer itself; touching messages should never
|
|
3290
|
+
* open the keyboard.
|
|
3291
|
+
* 4. Optionally skip while the assistant is streaming so the user
|
|
3292
|
+
* can keep reading without the keyboard popping up.
|
|
3293
|
+
*
|
|
3294
|
+
* @example
|
|
3295
|
+
* ```tsx
|
|
3296
|
+
* const onMouseUp = useFocusOnEmptyClick();
|
|
3297
|
+
* <div ref={scrollRef} onMouseUp={onMouseUp}>{messages}</div>
|
|
3298
|
+
* ```
|
|
3299
|
+
*/
|
|
3300
|
+
declare function useFocusOnEmptyClick(options?: UseFocusOnEmptyClickOptions): (event: MouseEvent<HTMLElement>) => void;
|
|
3301
|
+
|
|
3302
|
+
declare const useChatAudioPrefs: zustand.UseBoundStore<zustand.StoreApi<AudioPrefsState<ChatAudioEvent>>>;
|
|
3303
|
+
|
|
3304
|
+
/**
|
|
3305
|
+
* Built-in chat notification sounds.
|
|
3306
|
+
*
|
|
3307
|
+
* Bundled into the JS at build time as base64 data URLs (`tsup.config.ts`
|
|
3308
|
+
* loader: `.mp3 → dataurl`). Total ≈ 136KB, gzipped ≈ 130KB — added to
|
|
3309
|
+
* the lazy Chat tool so hosts get notification sounds with zero setup.
|
|
3310
|
+
*
|
|
3311
|
+
* Source files live in `./sounds/`. Re-encode via ffmpeg if you tweak:
|
|
3312
|
+
*
|
|
3313
|
+
* ffmpeg -i in.mp3 -ac 2 -ar 44100 -b:a 128k -af 'atrim=0:1.4,afade=t=out:st=1.22:d=0.18' out.mp3
|
|
3314
|
+
*/
|
|
3315
|
+
|
|
3316
|
+
/**
|
|
3317
|
+
* Default chat notification sounds. Pass to `useChatAudio` (or spread
|
|
3318
|
+
* into a custom map) so hosts don't have to ship assets themselves.
|
|
3319
|
+
*
|
|
3320
|
+
* @example
|
|
3321
|
+
* ```tsx
|
|
3322
|
+
* const audio = useChatAudio({ sounds: DEFAULT_CHAT_SOUNDS });
|
|
3323
|
+
*
|
|
3324
|
+
* // Override one event:
|
|
3325
|
+
* const audio = useChatAudio({
|
|
3326
|
+
* sounds: { ...DEFAULT_CHAT_SOUNDS, mention: '/custom-mention.mp3' },
|
|
3327
|
+
* });
|
|
3328
|
+
* ```
|
|
3329
|
+
*/
|
|
3330
|
+
declare const DEFAULT_CHAT_SOUNDS: ChatAudioSounds;
|
|
2433
3331
|
|
|
2434
3332
|
interface ToolPayloadMatcher {
|
|
2435
3333
|
/** Cheap predicate. First match wins. */
|
|
@@ -2449,6 +3347,120 @@ declare function isGeoJSONFeatureCollection(v: unknown): v is {
|
|
|
2449
3347
|
};
|
|
2450
3348
|
declare function isStringValue(v: unknown): v is string;
|
|
2451
3349
|
|
|
3350
|
+
/**
|
|
3351
|
+
* Chat color tokens — single source of truth.
|
|
3352
|
+
*
|
|
3353
|
+
* Every role-conditional class for chat surfaces lives here.
|
|
3354
|
+
* Components consume via `useChatBubbleStyles` / `useChatRoleStyles`,
|
|
3355
|
+
* never via raw Tailwind literals.
|
|
3356
|
+
*
|
|
3357
|
+
* Why centralize:
|
|
3358
|
+
* 1. One file to edit when the design system changes (e.g. light-theme
|
|
3359
|
+
* contrast tweaks, palette swap).
|
|
3360
|
+
* 2. Eliminates the "first-token-on-bg-primary-was-text-white" class
|
|
3361
|
+
* of bugs where each call site picks its own foreground.
|
|
3362
|
+
* 3. Lets us snapshot-test color decisions later.
|
|
3363
|
+
*/
|
|
3364
|
+
/** Bubble surface classes (background + text), keyed by message state. */
|
|
3365
|
+
declare const BUBBLE_SURFACE: {
|
|
3366
|
+
/** User-authored bubble — solid brand color. */
|
|
3367
|
+
readonly user: "bg-primary text-primary-foreground rounded-tr-md";
|
|
3368
|
+
/** Assistant bubble in normal state — neutral muted surface. */
|
|
3369
|
+
readonly assistant: "bg-muted text-foreground rounded-tl-md";
|
|
3370
|
+
/** Assistant bubble when the turn failed — destructive tint. */
|
|
3371
|
+
readonly error: "bg-destructive/10 text-destructive rounded-tl-md border border-destructive/30";
|
|
3372
|
+
};
|
|
3373
|
+
/**
|
|
3374
|
+
* Anchor (link) classes for markdown content rendered inside a bubble.
|
|
3375
|
+
*
|
|
3376
|
+
* On `bg-primary` the link MUST stay legible against the cyan/brand fill —
|
|
3377
|
+
* `text-primary-foreground` matches the bubble's foreground token, so
|
|
3378
|
+
* contrast tracks the design system automatically.
|
|
3379
|
+
*
|
|
3380
|
+
* On the neutral assistant bubble we keep the brand-primary color so links
|
|
3381
|
+
* still pop without competing with the body text.
|
|
3382
|
+
*/
|
|
3383
|
+
declare const ANCHOR: {
|
|
3384
|
+
readonly user: string;
|
|
3385
|
+
readonly assistant: "text-primary underline hover:text-primary/80 transition-colors break-all";
|
|
3386
|
+
};
|
|
3387
|
+
/** Inline secondary action (e.g. "Show more / less"). Same logic as anchors. */
|
|
3388
|
+
declare const TOGGLE: {
|
|
3389
|
+
readonly user: "text-primary-foreground/80 hover:text-primary-foreground";
|
|
3390
|
+
readonly assistant: "text-primary hover:text-primary/80";
|
|
3391
|
+
};
|
|
3392
|
+
/** Destructive surface — used by ErrorBanner and the delete action. */
|
|
3393
|
+
declare const DESTRUCTIVE_SURFACE: {
|
|
3394
|
+
/** Banner / card variant: border + tint + text. */
|
|
3395
|
+
readonly banner: "border border-destructive/40 bg-destructive/10 text-destructive";
|
|
3396
|
+
/** Subtle hover for destructive buttons inside the banner / menu. */
|
|
3397
|
+
readonly hover: "hover:bg-destructive/15";
|
|
3398
|
+
/** Strong-hover variant (e.g. trash overlay on attachments). */
|
|
3399
|
+
readonly hoverStrong: "hover:bg-destructive hover:text-destructive-foreground";
|
|
3400
|
+
/** Inline destructive text utility. */
|
|
3401
|
+
readonly text: "text-destructive";
|
|
3402
|
+
/** Hover style for menu items that delete data. */
|
|
3403
|
+
readonly menuItem: "text-destructive focus:text-destructive hover:bg-destructive/15 hover:text-destructive";
|
|
3404
|
+
};
|
|
3405
|
+
/** Tool-call result text. */
|
|
3406
|
+
declare const TOOL_CALL: {
|
|
3407
|
+
readonly errorText: "text-destructive";
|
|
3408
|
+
};
|
|
3409
|
+
type ChatBubbleSurface = keyof typeof BUBBLE_SURFACE;
|
|
3410
|
+
|
|
3411
|
+
/**
|
|
3412
|
+
* Role-aware style hooks for chat surfaces.
|
|
3413
|
+
*
|
|
3414
|
+
* Pure utility hooks — no React state, no side effects, just memoized
|
|
3415
|
+
* className strings derived from `bubbleTokens`. They exist so:
|
|
3416
|
+
* - components don't import token constants directly (single facade)
|
|
3417
|
+
* - "the user-bubble link color" can be changed in one file
|
|
3418
|
+
* - tests can mock the hook to assert intent without parsing classNames
|
|
3419
|
+
*/
|
|
3420
|
+
interface ChatBubbleStyles {
|
|
3421
|
+
/** className for the bubble container (background + text + border). */
|
|
3422
|
+
surface: string;
|
|
3423
|
+
/** className for an inline anchor inside markdown. */
|
|
3424
|
+
anchor: string;
|
|
3425
|
+
/** className for a secondary inline action (e.g. show more). */
|
|
3426
|
+
toggle: string;
|
|
3427
|
+
}
|
|
3428
|
+
/**
|
|
3429
|
+
* Resolve bubble + content styles for a single message.
|
|
3430
|
+
*
|
|
3431
|
+
* @param role 'user' | 'assistant' | 'system' (system defaults to assistant styling)
|
|
3432
|
+
* @param isError marks the bubble as a failed turn (overrides surface)
|
|
3433
|
+
*
|
|
3434
|
+
* @example
|
|
3435
|
+
* ```tsx
|
|
3436
|
+
* const { surface, anchor } = useChatBubbleStyles(message.role, !!message.isError);
|
|
3437
|
+
* <div className={cn('rounded-2xl px-3.5 py-2', surface)}>…</div>
|
|
3438
|
+
* ```
|
|
3439
|
+
*/
|
|
3440
|
+
declare function useChatBubbleStyles(role: 'user' | 'assistant' | 'system', isError: boolean): ChatBubbleStyles;
|
|
3441
|
+
interface ChatRoleStyles {
|
|
3442
|
+
anchor: string;
|
|
3443
|
+
toggle: string;
|
|
3444
|
+
}
|
|
3445
|
+
/**
|
|
3446
|
+
* Lightweight variant when only role matters (no error state, no surface).
|
|
3447
|
+
* Use in shared markdown renderers that don't know about bubble background.
|
|
3448
|
+
*/
|
|
3449
|
+
declare function useChatRoleStyles(isUser: boolean): ChatRoleStyles;
|
|
3450
|
+
interface ChatDestructiveStyles {
|
|
3451
|
+
banner: string;
|
|
3452
|
+
hover: string;
|
|
3453
|
+
hoverStrong: string;
|
|
3454
|
+
text: string;
|
|
3455
|
+
menuItem: string;
|
|
3456
|
+
toolErrorText: string;
|
|
3457
|
+
}
|
|
3458
|
+
/**
|
|
3459
|
+
* Destructive (delete / error) class facade. Hook form keeps the API
|
|
3460
|
+
* symmetric with the others; under the hood it returns a frozen object.
|
|
3461
|
+
*/
|
|
3462
|
+
declare function useChatDestructiveStyles(): ChatDestructiveStyles;
|
|
3463
|
+
|
|
2452
3464
|
/** Walk the conversation and collect image attachments in chronological order. */
|
|
2453
3465
|
declare function collectImageAttachments(messages: ChatMessage[]): ChatAttachment[];
|
|
2454
3466
|
|
|
@@ -2595,6 +3607,20 @@ interface MessageListProps {
|
|
|
2595
3607
|
* `!isAtBottom`. Plan64.
|
|
2596
3608
|
*/
|
|
2597
3609
|
onAtBottomChange?: (isAtBottom: boolean) => void;
|
|
3610
|
+
/**
|
|
3611
|
+
* Pixel distance from the bottom that still counts as "at bottom".
|
|
3612
|
+
* Default 120 — generous enough that mid-message users keep getting
|
|
3613
|
+
* sticky-followed (matches ChatGPT / Slack feel) while still letting
|
|
3614
|
+
* a deliberate scroll-up break the lock. Plan11.
|
|
3615
|
+
*/
|
|
3616
|
+
atBottomThreshold?: number;
|
|
3617
|
+
/**
|
|
3618
|
+
* Force-scroll to the bottom when this id changes. Wire to the id of
|
|
3619
|
+
* the most-recently-sent user message: every send re-anchors the
|
|
3620
|
+
* viewport so users always see their own bubble + the incoming
|
|
3621
|
+
* reply, even if they were scrolled up. Plan11.
|
|
3622
|
+
*/
|
|
3623
|
+
scrollAnchorId?: string | number | null;
|
|
2598
3624
|
}
|
|
2599
3625
|
interface MessageListHandle {
|
|
2600
3626
|
scrollToBottom: (smooth?: boolean) => void;
|
|
@@ -3567,7 +4593,22 @@ interface MarkdownEditorProps {
|
|
|
3567
4593
|
*/
|
|
3568
4594
|
onSubmit?: () => boolean | void;
|
|
3569
4595
|
}
|
|
3570
|
-
|
|
4596
|
+
/**
|
|
4597
|
+
* Imperative handle exposed via `ref`. Matches `ComposerHandle` from
|
|
4598
|
+
* `@djangocfg/ui-tools/chat` so consumers can forward it straight into
|
|
4599
|
+
* `useRegisterComposer({ focus, moveCursorToEnd })` — that's what makes
|
|
4600
|
+
* voice dictation (`VoiceComposerSlot`) push live text into a TipTap
|
|
4601
|
+
* composer.
|
|
4602
|
+
*/
|
|
4603
|
+
interface MarkdownEditorHandle {
|
|
4604
|
+
/** Move keyboard focus into the editor. */
|
|
4605
|
+
focus: () => void;
|
|
4606
|
+
/** Place the caret at the end of the document (and focus). */
|
|
4607
|
+
moveCursorToEnd: () => void;
|
|
4608
|
+
/** Escape hatch — the underlying TipTap `Editor` instance. */
|
|
4609
|
+
getEditor: () => Editor$1 | null;
|
|
4610
|
+
}
|
|
4611
|
+
declare const MarkdownEditor: react.ForwardRefExoticComponent<MarkdownEditorProps & react.RefAttributes<MarkdownEditorHandle>>;
|
|
3571
4612
|
|
|
3572
4613
|
/**
|
|
3573
4614
|
* Built-in serializers for the `MentionConfig.renderMarkdown` callback.
|
|
@@ -3776,4 +4817,4 @@ declare function useBlobUrlCleanup(key: string | null): void;
|
|
|
3776
4817
|
*/
|
|
3777
4818
|
declare function generateContentKey(content: ArrayBuffer): string;
|
|
3778
4819
|
|
|
3779
|
-
export { type ApiKey, ArrayFieldItemTemplate, ArrayFieldTemplate, type AspectRatioValue, type AttachmentRenderer, type AttachmentRendererArgs, type AttachmentRendererMap, Attachments, AttachmentsGrid, type AttachmentsGridProps, AttachmentsList, type AttachmentsListProps, type AttachmentsProps, Player as AudioPlayer, type PlayerProps as AudioPlayerProps, AudioToggle, type AudioToggleProps, BaseInputTemplate, type BlobSource, CHAT_EVENT_NAME, CSS_VARS, CardLoadingFallback, type ChatAction, type ChatAssistantContext, type ChatAttachment, type ChatAudioConfig, type ChatAudioEvent, type ChatAudioSounds, type ChatConfig, type ChatContextValue, type ChatDisplayMode, type ChatEventDetail, type ChatLabels, type ChatLightboxState, type ChatLogScope, type ChatLogger, type ChatMessage, type ChatPersona, type ChatPrefs, ChatProvider, type ChatProviderProps, type ChatRole, ChatRoot, type ChatRootProps, type ChatSource, type ChatState, type ChatStreamEvent, type ChatToolCall, type ChatTransport, type ChatUserContext, CheckboxWidget, ColorWidget, Composer, type ComposerProps, type CreateLazyComponentOptions, type CreateSessionOptions, type CreateVideoErrorFallbackOptions, CronScheduler, type CronSchedulerContextValue, type CronSchedulerProps, CronSchedulerProvider, type CronSchedulerState, CustomInput, type DASHSource, DEFAULT_LABELS, DEFAULT_SIDEBAR, DEFAULT_Z_INDEX, type DataUrlSource, DayChips, DiffEditor, type DiffEditorProps, type DisabledWhenRule, Editor, type EditorContextValue, type EditorFile, type EditorOptions, type EditorProps, EditorProvider, type EditorRef, EmptyState, type EmptyStateProps, ErrorBanner, type ErrorBannerProps, type ErrorFallbackProps, ErrorListTemplate, FieldTemplate, type Focusable, type HLSSource, HOTKEYS, type HistoryPage, type HttpTransportConfig, type ImageFile, ImageViewer, type ImageViewerProps, type JsonFormContext, type JsonFormDensity, JsonSchemaForm, type JsonSchemaFormProps, JsonTreeComponent as JsonTree, type JsonTreeConfig, type JsonTreeProps, JumpToLatest, type JumpToLatestProps, LIMITS, LazyPlayer as LazyAudioPlayer, LazyChat, type ChatRootProps as LazyChatProps, LazyCronScheduler, LazyImageViewer, LazyJsonSchemaForm, LazyJsonTree, LazyLottiePlayer, LazyMapContainer, LazyMapView, LazyMermaid, LazyOpenapiViewer, LazyPrettyCode, LazyTree, TreeRootProps as LazyTreeProps, LazyVideoPlayer, LazyWrapper, type LazyWrapperProps, type LinkRule, LoadingFallback, type LoadingFallbackProps, type LottieDirection, LottiePlayer, type LottiePlayerProps, type LottieSize, type LottieSpeed, type MapContainerProps, MapLoadingFallback, type MapStyleKey, type MapViewport, MarkdownEditor, type MarkdownEditorProps, MarkdownMessage, type MarkdownMessageProps, type MarkerData, type MentionAttrs, type MentionConfig, type MentionItem, type MentionMarkdownRenderer, Mermaid, type MermaidProps, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, MessageList, type MessageListHandle, type MessageListProps, type MockTransportOptions, type MonthDay, MonthDayGrid, NativeProvider, NumberWidget, ObjectFieldTemplate, Playground as OpenapiViewer, type ParseSSEOptions, type PlayerMode, type PlaygroundConfig, type PlaygroundProps$1 as PlaygroundProps, PrettyCode, type PrettyCodeProps$1 as PrettyCodeProps, type ResolveFileSourceOptions, STORAGE_KEYS, SchedulePreview, type ScheduleType, ScheduleTypeSelector, type SchemaSource, SelectWidget, type SendOptions, type SessionInfo, type SimpleStreamSource, SliderWidget, Sources, type SourcesProps, Spinner, type StreamOptions, StreamProvider, type StreamSource, StreamingIndicator, type StreamingIndicatorProps, SwitchWidget, TextWidget, TimeSelector, type TokenBuffer, ToolCalls, type ToolCallsProps, type ToolPayloadFallback, type ToolPayloadKind, type ToolPayloadMatcher, TransportError, TreeRootProps, type UiGroup, type UrlSource, type UseAutoFocusOnStreamEndOptions, type UseChatAudioReturn, type UseChatComposerOptions, type UseChatComposerReturn, type UseChatConfig, type UseChatHistoryOptions, type UseChatLayoutConfig, type UseChatLayoutReturn, type UseChatLightboxReturn, type UseChatReturn, type UseChatScrollOptions, type UseChatScrollReturn, type UseCollapsibleContentOptions, type UseCollapsibleContentResult, type UseEditorReturn, type UseLottieOptions, type UseLottieReturn, type UseMonacoReturn, VideoControls, VideoErrorFallback, type VideoErrorFallbackProps, VideoPlayer, type VideoPlayerContextValue, type VideoPlayerProps, VideoPlayerProvider, type VideoPlayerProviderProps, type VideoPlayerRef, type VideoSourceUnion, VidstackProvider, type VimeoSource, type WeekDay, type YouTubeSource, buildCron, collectImageAttachments, createHttpTransport, createId, createLazyComponent, createMockTransport, createTokenBuffer, createVideoErrorFallback, deriveInitials, dispatchToolPayload, evaluateDisabledWhen, extractTextFromChildren, generateContentKey, getChatLogger, getRequiredFields, hasRequiredFields, humanizeCron, initialState, isGeoJSONFeatureCollection, isLatLng, isPlainObject, isSimpleStreamSource, isStringValue, isSubmittableDraft, isValidCron, mentionPresets, mergeDefaults, normalizeFormData, parseCron, parseSSE, reducer, resolveFileSource, resolvePersona, resolvePlayerMode, resolveStreamSource, safeJsonParse, safeJsonStringify, sanitizeDraft, useAudioCache, useAutoFocusOnStreamEnd, useBlobUrlCleanup, useChat, useChatAudio, useChatAudioPrefs, useChatComposer, useChatContext, useChatContextOptional, useChatHistory, useChatLayout, useChatLightbox, useChatScroll, useCollapsibleContent, useCronCustom, useCronMonthDays, useCronPreview, useCronScheduler, useCronSchedulerContext, useCronTime, useCronType, useCronWeekDays, useEditor, useEditorContext, useImageCache, useLanguage, useLottie, useMediaCacheStore, useMonaco, useRegisterComposer, useVideoCache, useVideoPlayerContext, useVideoPlayerSettings, validateRequiredFields, validateSchema };
|
|
4820
|
+
export { ANCHOR, type ApiKey, ArrayFieldItemTemplate, ArrayFieldTemplate, type AspectRatioValue, type AttachmentRenderer, type AttachmentRendererArgs, type AttachmentRendererMap, Attachments, AttachmentsGrid, type AttachmentsGridProps, AttachmentsList, type AttachmentsListProps, type AttachmentsProps, Player as AudioPlayer, type PlayerProps as AudioPlayerProps, AudioToggle, type AudioToggleProps, BUBBLE_SURFACE, BaseInputTemplate, type BlobSource, CHAT_EVENT_NAME, CSS_VARS, CardLoadingFallback, type ChatAction, type ChatAssistantContext, type ChatAttachment, type ChatAudioConfig, type ChatAudioEvent, type ChatAudioSounds, type ChatBubbleStyles, type ChatBubbleSurface, type ChatConfig, type ChatContextValue, type ChatDestructiveStyles, type ChatDisplayMode, ChatDock, type ChatDockMode, type ChatDockPrefs, type ChatDockProps, type ChatDockSide, type ChatEventDetail, ChatFAB, type ChatFABPosition, type ChatFABProps, type ChatFABSize, type ChatFABVariant, ChatGreeting, type ChatGreetingProps, ChatHeader, ChatHeaderActionButton, type ChatHeaderActionButtonProps, ChatHeaderAudioToggle, type ChatHeaderAudioToggleProps, ChatHeaderModeToggle, type ChatHeaderModeToggleProps, type ChatHeaderProps, ChatHeaderResetButton, type ChatHeaderResetButtonProps, type ChatLabels, ChatLauncher, type ChatLauncherGreeting, type ChatLauncherHotkey, type ChatLauncherProps, type ChatLightboxState, type ChatLogScope, type ChatLogger, type ChatMessage, type ChatPersona, type ChatPrefs, type ChatPresencePhase, ChatProvider, type ChatProviderProps, type ChatRole, type ChatRoleStyles, ChatRoot, type ChatRootProps, type ChatSource, type ChatState, type ChatStreamEvent, type ChatToolCall, type ChatTransport, ChatUnreadPreview, type ChatUnreadPreviewProps, type ChatUserContext, CheckboxWidget, ColorWidget, Composer, type ComposerProps, type CreateLazyComponentOptions, type CreateSessionOptions, type CreateVideoErrorFallbackOptions, CronScheduler, type CronSchedulerContextValue, type CronSchedulerProps, CronSchedulerProvider, type CronSchedulerState, CustomInput, type DASHSource, DEFAULT_CHAT_SOUNDS, DEFAULT_DOCK_PREFS, DEFAULT_LABELS, DEFAULT_SIDEBAR, DEFAULT_Z_INDEX, DESTRUCTIVE_SURFACE, type DataUrlSource, DayChips, DiffEditor, type DiffEditorProps, type DisabledWhenRule, Editor, type EditorContextValue, type EditorFile, type EditorOptions, type EditorProps, EditorProvider, type EditorRef, EmptyState, type EmptyStateProps, ErrorBanner, type ErrorBannerProps, type ErrorFallbackProps, ErrorListTemplate, FieldTemplate, type Focusable, type HLSSource, HOTKEYS, type HistoryPage, type HttpTransportConfig, type ImageFile, ImageViewer, type ImageViewerProps, type JsonFormContext, type JsonFormDensity, JsonSchemaForm, type JsonSchemaFormProps, JsonTreeComponent as JsonTree, type JsonTreeConfig, type JsonTreeProps, JumpToLatest, type JumpToLatestProps, LIMITS, LazyPlayer as LazyAudioPlayer, LazyChat, type ChatRootProps as LazyChatProps, LazyCronScheduler, LazyImageViewer, LazyJsonSchemaForm, LazyJsonTree, LazyLottiePlayer, LazyMapContainer, LazyMapView, LazyMermaid, LazyOpenapiViewer, LazyPrettyCode, LazyTree, TreeRootProps as LazyTreeProps, LazyVideoPlayer, LazyWrapper, type LazyWrapperProps, type LinkRule, LoadingFallback, type LoadingFallbackProps, type LottieDirection, LottiePlayer, type LottiePlayerProps, type LottieSize, type LottieSpeed, type MapContainerProps, MapLoadingFallback, type MapStyleKey, type MapViewport, MarkdownEditor, type MarkdownEditorProps, MarkdownMessage, type MarkdownMessageProps, type MarkerData, type MentionAttrs, type MentionConfig, type MentionItem, type MentionMarkdownRenderer, Mermaid, type MermaidProps, MessageActions, type MessageActionsProps, MessageBubble, type MessageBubbleProps, MessageList, type MessageListHandle, type MessageListProps, type MockTransportOptions, type MonthDay, MonthDayGrid, NativeProvider, NumberWidget, ObjectFieldTemplate, Playground as OpenapiViewer, type ParseSSEOptions, type PlayerMode, type PlaygroundConfig, type PlaygroundProps$1 as PlaygroundProps, PrettyCode, type PrettyCodeProps$1 as PrettyCodeProps, type PydanticAIChatTransportOpts, type PydanticAIEvent, type ResolveFileSourceOptions, STORAGE_KEYS, SchedulePreview, type ScheduleType, ScheduleTypeSelector, type SchemaSource, SelectWidget, type SendOptions, type SessionInfo, type SimpleStreamSource, SliderWidget, Sources, type SourcesProps, Spinner, type StreamOptions, StreamProvider, type StreamSource, StreamingIndicator, type StreamingIndicatorProps, SwitchWidget, TOGGLE, TOOL_CALL, TextWidget, TimeSelector, type TokenBuffer, ToolCalls, type ToolCallsProps, type ToolIdQueue, type ToolPayloadFallback, type ToolPayloadKind, type ToolPayloadMatcher, TransportError, TreeRootProps, type UiGroup, type UrlSource, type UseAutoFocusOnStreamEndOptions, type UseChatAudioReturn, type UseChatComposerOptions, type UseChatComposerReturn, type UseChatConfig, type UseChatDockPrefsOptions, type UseChatDockPrefsReturn, type UseChatHistoryOptions, type UseChatLayoutConfig, type UseChatLayoutReturn, type UseChatLightboxReturn, type UseChatResetOptions, type UseChatResetReturn, type UseChatReturn, type UseChatScrollOptions, type UseChatScrollReturn, type UseCollapsibleContentOptions, type UseCollapsibleContentResult, type UseEditorReturn, type UseFocusOnEmptyClickOptions, type UseLottieOptions, type UseLottieReturn, type UseMonacoReturn, type UseVisitorFingerprintOptions, VideoControls, VideoErrorFallback, type VideoErrorFallbackProps, VideoPlayer, type VideoPlayerContextValue, type VideoPlayerProps, VideoPlayerProvider, type VideoPlayerProviderProps, type VideoPlayerRef, type VideoSourceUnion, VidstackProvider, type VimeoSource, type WeekDay, type YouTubeSource, buildCron, collectImageAttachments, createHttpTransport, createId, createLazyComponent, createMockTransport, createPydanticAIChatTransport, createPydanticAISSEMap, createTokenBuffer, createToolIdQueue, createVideoErrorFallback, deriveInitials, dispatchToolPayload, evaluateDisabledWhen, extractTextFromChildren, generateContentKey, getChatLogger, getRequiredFields, hasRequiredFields, humanizeCron, initialState, isGeoJSONFeatureCollection, isLatLng, isPlainObject, isSimpleStreamSource, isStringValue, isSubmittableDraft, isValidCron, mapPydanticAIEvent, mentionPresets, mergeDefaults, normalizeFormData, parseCron, parseSSE, reducer, resolveFileSource, resolvePersona, resolvePlayerMode, resolveStreamSource, safeJsonParse, safeJsonStringify, sanitizeDraft, useAudioCache, useAutoFocusOnStreamEnd, useBlobUrlCleanup, useChat, useChatAudio, useChatAudioPrefs, useChatBubbleStyles, useChatComposer, useChatContext, useChatContextOptional, useChatDestructiveStyles, useChatDockPrefs, useChatHistory, useChatLayout, useChatLightbox, useChatPresence, useChatReset, useChatRoleStyles, useChatScroll, useCollapsibleContent, useCronCustom, useCronMonthDays, useCronPreview, useCronScheduler, useCronSchedulerContext, useCronTime, useCronType, useCronWeekDays, useEditor, useEditorContext, useFocusOnEmptyClick, useImageCache, useLanguage, useLottie, useMediaCacheStore, useMonaco, useRegisterComposer, useVideoCache, useVideoPlayerContext, useVideoPlayerSettings, useVisitorFingerprint, validateRequiredFields, validateSchema };
|