@djangocfg/ui-tools 2.1.381 → 2.1.383

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.
Files changed (178) hide show
  1. package/README.md +132 -899
  2. package/dist/ChatRoot-6IZFM5HM.mjs +5 -0
  3. package/dist/{ChatRoot-EJC5Y2YM.cjs.map → ChatRoot-6IZFM5HM.mjs.map} +1 -1
  4. package/dist/ChatRoot-LW4XNIKP.cjs +14 -0
  5. package/dist/{ChatRoot-QOSKJPM6.mjs.map → ChatRoot-LW4XNIKP.cjs.map} +1 -1
  6. package/dist/DictationField-U25MEYAL.mjs +4 -0
  7. package/dist/DictationField-U25MEYAL.mjs.map +1 -0
  8. package/dist/DictationField-XWR5VOID.cjs +13 -0
  9. package/dist/DictationField-XWR5VOID.cjs.map +1 -0
  10. package/dist/{DocsLayout-2YKPXZYO.mjs → DocsLayout-2P3ONDWJ.mjs} +3 -3
  11. package/dist/{DocsLayout-2YKPXZYO.mjs.map → DocsLayout-2P3ONDWJ.mjs.map} +1 -1
  12. package/dist/{DocsLayout-Q4KS3QWW.cjs → DocsLayout-2YZNS5VK.cjs} +8 -8
  13. package/dist/{DocsLayout-Q4KS3QWW.cjs.map → DocsLayout-2YZNS5VK.cjs.map} +1 -1
  14. package/dist/chunk-4PFW7MIJ.cjs +837 -0
  15. package/dist/chunk-4PFW7MIJ.cjs.map +1 -0
  16. package/dist/chunk-C2YN6WEO.mjs +833 -0
  17. package/dist/chunk-C2YN6WEO.mjs.map +1 -0
  18. package/dist/{chunk-XACCHZH2.cjs → chunk-FIRK5CEH.cjs} +42 -4
  19. package/dist/chunk-FIRK5CEH.cjs.map +1 -0
  20. package/dist/{chunk-NWUT327A.mjs → chunk-HIK6BPL7.mjs} +38 -5
  21. package/dist/chunk-HIK6BPL7.mjs.map +1 -0
  22. package/dist/chunk-OZAU3QWD.cjs +2493 -0
  23. package/dist/chunk-OZAU3QWD.cjs.map +1 -0
  24. package/dist/chunk-UWVP6LCW.mjs +2447 -0
  25. package/dist/chunk-UWVP6LCW.mjs.map +1 -0
  26. package/dist/index.cjs +1668 -99
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +1215 -107
  29. package/dist/index.d.ts +1215 -107
  30. package/dist/index.mjs +1555 -50
  31. package/dist/index.mjs.map +1 -1
  32. package/package.json +16 -15
  33. package/src/audio-assets.d.ts +8 -0
  34. package/src/components/markdown/MarkdownMessage/CollapseToggle.tsx +3 -1
  35. package/src/components/markdown/MarkdownMessage/components.tsx +2 -5
  36. package/src/tools/Chat/README.md +347 -530
  37. package/src/tools/Chat/components/Attachments.tsx +6 -1
  38. package/src/tools/Chat/components/ChatRoot.tsx +30 -2
  39. package/src/tools/Chat/components/Composer.tsx +20 -3
  40. package/src/tools/Chat/components/ErrorBanner.tsx +7 -3
  41. package/src/tools/Chat/components/MessageActions.tsx +3 -1
  42. package/src/tools/Chat/components/MessageBubble.tsx +6 -5
  43. package/src/tools/Chat/components/MessageList.tsx +87 -1
  44. package/src/tools/Chat/components/ToolCalls.tsx +21 -3
  45. package/src/tools/Chat/context/ChatProvider.tsx +21 -3
  46. package/src/tools/Chat/core/audio/audioBus.ts +10 -163
  47. package/src/tools/Chat/core/audio/defaults.ts +43 -0
  48. package/src/tools/Chat/core/audio/index.ts +1 -0
  49. package/src/tools/Chat/core/audio/preferences.ts +5 -59
  50. package/src/tools/Chat/core/audio/sounds/error.mp3 +0 -0
  51. package/src/tools/Chat/core/audio/sounds/mention.mp3 +0 -0
  52. package/src/tools/Chat/core/audio/sounds/notification.mp3 +0 -0
  53. package/src/tools/Chat/core/audio/sounds/received.mp3 +0 -0
  54. package/src/tools/Chat/core/audio/sounds/sent.mp3 +0 -0
  55. package/src/tools/Chat/core/audio/sounds/start.mp3 +0 -0
  56. package/src/tools/Chat/core/audio/types.ts +28 -0
  57. package/src/tools/Chat/core/reducer.ts +33 -0
  58. package/src/tools/Chat/core/transport/index.ts +13 -0
  59. package/src/tools/Chat/core/transport/mappers/index.ts +6 -0
  60. package/src/tools/Chat/core/transport/mappers/pydantic-ai.ts +142 -0
  61. package/src/tools/Chat/core/transport/pydantic-ai-transport.ts +208 -0
  62. package/src/tools/Chat/core/transport/sse.ts +18 -5
  63. package/src/tools/Chat/hooks/index.ts +25 -0
  64. package/src/tools/Chat/hooks/useAutoFocusOnStreamEnd.ts +5 -3
  65. package/src/tools/Chat/hooks/useChat.ts +28 -0
  66. package/src/tools/Chat/hooks/useChatAudio.ts +59 -180
  67. package/src/tools/Chat/hooks/useChatDockPrefs.ts +74 -0
  68. package/src/tools/Chat/hooks/useChatReset.ts +70 -0
  69. package/src/tools/Chat/hooks/useChatUnread.ts +87 -0
  70. package/src/tools/Chat/hooks/useFocusOnEmptyClick.ts +111 -0
  71. package/src/tools/Chat/hooks/useVisitorFingerprint.ts +48 -0
  72. package/src/tools/Chat/index.ts +84 -1
  73. package/src/tools/Chat/launcher/ChatDock.tsx +263 -0
  74. package/src/tools/Chat/launcher/ChatFAB.tsx +349 -0
  75. package/src/tools/Chat/launcher/ChatGreeting.tsx +200 -0
  76. package/src/tools/Chat/launcher/ChatHeader.tsx +76 -0
  77. package/src/tools/Chat/launcher/ChatHeaderActionButton.tsx +87 -0
  78. package/src/tools/Chat/launcher/ChatHeaderAudioToggle.tsx +47 -0
  79. package/src/tools/Chat/launcher/ChatHeaderLanguageButton.tsx +179 -0
  80. package/src/tools/Chat/launcher/ChatHeaderModeToggle.tsx +57 -0
  81. package/src/tools/Chat/launcher/ChatHeaderResetButton.tsx +93 -0
  82. package/src/tools/Chat/launcher/ChatLauncher.tsx +321 -0
  83. package/src/tools/Chat/launcher/ChatUnreadPreview.tsx +197 -0
  84. package/src/tools/Chat/launcher/index.ts +46 -0
  85. package/src/tools/Chat/launcher/useChatPresence.ts +44 -0
  86. package/src/tools/Chat/styles/bubbleTokens.ts +71 -0
  87. package/src/tools/Chat/styles/index.ts +16 -0
  88. package/src/tools/Chat/styles/useChatStyles.ts +101 -0
  89. package/src/tools/Chat/types/attachment.ts +25 -0
  90. package/src/tools/Chat/types/config.ts +48 -0
  91. package/src/tools/Chat/types/events.ts +35 -0
  92. package/src/tools/Chat/types/index.ts +34 -0
  93. package/src/tools/Chat/types/labels.ts +38 -0
  94. package/src/tools/Chat/types/message.ts +32 -0
  95. package/src/tools/Chat/types/persona.ts +31 -0
  96. package/src/tools/Chat/types/session.ts +43 -0
  97. package/src/tools/Chat/types/tool-call.ts +17 -0
  98. package/src/tools/Chat/types/transport.ts +28 -0
  99. package/src/tools/Chat/types.ts +5 -240
  100. package/src/tools/MarkdownEditor/MarkdownEditor.tsx +50 -14
  101. package/src/tools/MarkdownEditor/index.ts +1 -1
  102. package/src/tools/SpeechRecognition/README.md +336 -0
  103. package/src/tools/SpeechRecognition/__tests__/ids.test.ts +15 -0
  104. package/src/tools/SpeechRecognition/__tests__/language.test.ts +59 -0
  105. package/src/tools/SpeechRecognition/__tests__/reducer.test.ts +71 -0
  106. package/src/tools/SpeechRecognition/__tests__/transcript.test.ts +52 -0
  107. package/src/tools/SpeechRecognition/components/DevicePicker.tsx +49 -0
  108. package/src/tools/SpeechRecognition/components/DictationButton.tsx +93 -0
  109. package/src/tools/SpeechRecognition/components/EngineBadge.tsx +30 -0
  110. package/src/tools/SpeechRecognition/components/ErrorBanner.tsx +52 -0
  111. package/src/tools/SpeechRecognition/components/LanguagePicker.tsx +63 -0
  112. package/src/tools/SpeechRecognition/components/MicMeter.tsx +63 -0
  113. package/src/tools/SpeechRecognition/components/PushToTalkHint.tsx +51 -0
  114. package/src/tools/SpeechRecognition/components/TranscriptView.tsx +55 -0
  115. package/src/tools/SpeechRecognition/components/index.ts +16 -0
  116. package/src/tools/SpeechRecognition/context/SpeechRecognitionProvider.tsx +47 -0
  117. package/src/tools/SpeechRecognition/context/index.ts +6 -0
  118. package/src/tools/SpeechRecognition/core/audio/defaults.ts +24 -0
  119. package/src/tools/SpeechRecognition/core/engine/external.ts +222 -0
  120. package/src/tools/SpeechRecognition/core/engine/http.ts +147 -0
  121. package/src/tools/SpeechRecognition/core/engine/index.ts +52 -0
  122. package/src/tools/SpeechRecognition/core/engine/mediarecorder.ts +105 -0
  123. package/src/tools/SpeechRecognition/core/engine/websocket.ts +211 -0
  124. package/src/tools/SpeechRecognition/core/engine/webspeech.ts +188 -0
  125. package/src/tools/SpeechRecognition/core/ids.ts +11 -0
  126. package/src/tools/SpeechRecognition/core/index.ts +14 -0
  127. package/src/tools/SpeechRecognition/core/language.ts +78 -0
  128. package/src/tools/SpeechRecognition/core/languages-catalog.ts +229 -0
  129. package/src/tools/SpeechRecognition/core/logger.ts +3 -0
  130. package/src/tools/SpeechRecognition/core/reducer.ts +105 -0
  131. package/src/tools/SpeechRecognition/core/transcript.ts +36 -0
  132. package/src/tools/SpeechRecognition/hooks/index.ts +14 -0
  133. package/src/tools/SpeechRecognition/hooks/useDictation.ts +59 -0
  134. package/src/tools/SpeechRecognition/hooks/useEnginePrefs.ts +15 -0
  135. package/src/tools/SpeechRecognition/hooks/useMicDevices.ts +57 -0
  136. package/src/tools/SpeechRecognition/hooks/useMicLevel.ts +52 -0
  137. package/src/tools/SpeechRecognition/hooks/usePushToTalk.ts +85 -0
  138. package/src/tools/SpeechRecognition/hooks/useResolvedLanguage.ts +28 -0
  139. package/src/tools/SpeechRecognition/hooks/useSpeechLanguageInfo.ts +108 -0
  140. package/src/tools/SpeechRecognition/hooks/useSpeechRecognition.ts +188 -0
  141. package/src/tools/SpeechRecognition/hooks/useVoiceSupport.ts +78 -0
  142. package/src/tools/SpeechRecognition/index.ts +82 -0
  143. package/src/tools/SpeechRecognition/lazy.tsx +19 -0
  144. package/src/tools/SpeechRecognition/store/index.ts +2 -0
  145. package/src/tools/SpeechRecognition/store/prefsStore.ts +54 -0
  146. package/src/tools/SpeechRecognition/types.ts +133 -0
  147. package/src/tools/SpeechRecognition/widgets/DictationField.tsx +105 -0
  148. package/src/tools/SpeechRecognition/widgets/VoiceComposerSlot.tsx +305 -0
  149. package/src/tools/SpeechRecognition/widgets/VoiceMessageRecorder.tsx +88 -0
  150. package/src/tools/SpeechRecognition/widgets/index.ts +6 -0
  151. package/dist/ChatRoot-EJC5Y2YM.cjs +0 -14
  152. package/dist/ChatRoot-QOSKJPM6.mjs +0 -5
  153. package/dist/chunk-NWUT327A.mjs.map +0 -1
  154. package/dist/chunk-QLMKCSR6.mjs +0 -2420
  155. package/dist/chunk-QLMKCSR6.mjs.map +0 -1
  156. package/dist/chunk-SI5RD2GD.cjs +0 -2460
  157. package/dist/chunk-SI5RD2GD.cjs.map +0 -1
  158. package/dist/chunk-XACCHZH2.cjs.map +0 -1
  159. package/src/components/markdown/MarkdownMessage/MarkdownMessage.story.tsx +0 -771
  160. package/src/stories/index.ts +0 -33
  161. package/src/tools/AudioPlayer/AudioPlayer.story.tsx +0 -481
  162. package/src/tools/Chat/Chat.story.tsx +0 -1457
  163. package/src/tools/CodeEditor/CodeEditor.story.tsx +0 -202
  164. package/src/tools/CronScheduler/CronScheduler.story.tsx +0 -300
  165. package/src/tools/Gallery/Gallery.story.tsx +0 -237
  166. package/src/tools/ImageViewer/ImageViewer.story.tsx +0 -85
  167. package/src/tools/JsonForm/JsonForm.story.tsx +0 -350
  168. package/src/tools/JsonTree/JsonTree.story.tsx +0 -141
  169. package/src/tools/LottiePlayer/LottiePlayer.story.tsx +0 -95
  170. package/src/tools/Map/Map.story.tsx +0 -458
  171. package/src/tools/MarkdownEditor/MarkdownEditor.story.tsx +0 -225
  172. package/src/tools/Mermaid/Mermaid.story.tsx +0 -251
  173. package/src/tools/OpenapiViewer/OpenapiViewer.story.tsx +0 -230
  174. package/src/tools/PrettyCode/PrettyCode.story.tsx +0 -304
  175. package/src/tools/Tour/Tour.story.tsx +0 -279
  176. package/src/tools/Tree/Tree.story.tsx +0 -620
  177. package/src/tools/Uploader/Uploader.story.tsx +0 -415
  178. package/src/tools/VideoPlayer/VideoPlayer.story.tsx +0 -87
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var chunk4PFW7MIJ_cjs = require('./chunk-4PFW7MIJ.cjs');
3
4
  var chunkFEN5S772_cjs = require('./chunk-FEN5S772.cjs');
4
5
  var chunkQJ6GTUCO_cjs = require('./chunk-QJ6GTUCO.cjs');
5
6
  var chunkYDPDTOSP_cjs = require('./chunk-YDPDTOSP.cjs');
@@ -7,11 +8,11 @@ var chunkKNDLV4PI_cjs = require('./chunk-KNDLV4PI.cjs');
7
8
  var chunk5I5QNGUG_cjs = require('./chunk-5I5QNGUG.cjs');
8
9
  var chunkYW5IVWHQ_cjs = require('./chunk-YW5IVWHQ.cjs');
9
10
  var chunk76NNDZH6_cjs = require('./chunk-76NNDZH6.cjs');
10
- var chunkSI5RD2GD_cjs = require('./chunk-SI5RD2GD.cjs');
11
+ var chunkOZAU3QWD_cjs = require('./chunk-OZAU3QWD.cjs');
11
12
  var chunkYXZ6GU7H_cjs = require('./chunk-YXZ6GU7H.cjs');
12
13
  var chunkFVVF7VCD_cjs = require('./chunk-FVVF7VCD.cjs');
13
14
  var chunk7EYHNP3E_cjs = require('./chunk-7EYHNP3E.cjs');
14
- var chunkXACCHZH2_cjs = require('./chunk-XACCHZH2.cjs');
15
+ var chunkFIRK5CEH_cjs = require('./chunk-FIRK5CEH.cjs');
15
16
  var chunkT3MWM23F_cjs = require('./chunk-T3MWM23F.cjs');
16
17
  require('./chunk-FP2RLYQZ.cjs');
17
18
  var chunkOLISEQHS_cjs = require('./chunk-OLISEQHS.cjs');
@@ -20,8 +21,8 @@ var lib = require('@djangocfg/ui-core/lib');
20
21
  var i18n = require('@djangocfg/i18n');
21
22
  var jsxRuntime = require('react/jsx-runtime');
22
23
  var lucideReact = require('lucide-react');
23
- var components = require('@djangocfg/ui-core/components');
24
24
  var hooks = require('@djangocfg/ui-core/hooks');
25
+ var components = require('@djangocfg/ui-core/components');
25
26
  var react = require('@tiptap/react');
26
27
  var StarterKit = require('@tiptap/starter-kit');
27
28
  var Placeholder = require('@tiptap/extension-placeholder');
@@ -268,7 +269,7 @@ function OpenapiLoadingFallback() {
268
269
  }
269
270
  chunkOLISEQHS_cjs.__name(OpenapiLoadingFallback, "OpenapiLoadingFallback");
270
271
  var LazyDocsLayout = createLazyComponent(
271
- () => import('./DocsLayout-Q4KS3QWW.cjs').then((mod) => ({ default: mod.DocsLayout })),
272
+ () => import('./DocsLayout-2YZNS5VK.cjs').then((mod) => ({ default: mod.DocsLayout })),
272
273
  {
273
274
  displayName: "LazyDocsLayout",
274
275
  fallback: /* @__PURE__ */ jsxRuntime.jsx(OpenapiLoadingFallback, {})
@@ -374,7 +375,7 @@ var LazyTree = createLazyComponent(
374
375
  }
375
376
  );
376
377
  var LazyChat = createLazyComponent(
377
- () => import('./ChatRoot-EJC5Y2YM.cjs').then((m) => ({ default: m.ChatRoot })),
378
+ () => import('./ChatRoot-LW4XNIKP.cjs').then((m) => ({ default: m.ChatRoot })),
378
379
  {
379
380
  displayName: "LazyChat",
380
381
  fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingFallback, { minHeight: 320, text: "Loading chat\u2026" })
@@ -411,7 +412,7 @@ async function* parseSSE(response, options = {}) {
411
412
  throw new Error("SSE response has no body");
412
413
  }
413
414
  const map = options.map ?? DEFAULT_MAP;
414
- const idleMs = options.idleTimeoutMs ?? chunkSI5RD2GD_cjs.LIMITS.sseIdleMs;
415
+ const idleMs = options.idleTimeoutMs ?? chunkOZAU3QWD_cjs.LIMITS.sseIdleMs;
415
416
  const reader = response.body.getReader();
416
417
  const decoder = new TextDecoder();
417
418
  let buffer = "";
@@ -436,7 +437,13 @@ async function* parseSSE(response, options = {}) {
436
437
  buffer = buffer.slice(separator + 2);
437
438
  const raw = parseEventBlock(rawBlock);
438
439
  const evt = map(raw);
439
- if (evt) yield evt;
440
+ if (evt) {
441
+ if (Array.isArray(evt)) {
442
+ for (const e of evt) yield e;
443
+ } else {
444
+ yield evt;
445
+ }
446
+ }
440
447
  separator = buffer.indexOf("\n\n");
441
448
  }
442
449
  idleCheck();
@@ -444,7 +451,13 @@ async function* parseSSE(response, options = {}) {
444
451
  if (buffer.trim()) {
445
452
  const raw = parseEventBlock(buffer);
446
453
  const evt = map(raw);
447
- if (evt) yield evt;
454
+ if (evt) {
455
+ if (Array.isArray(evt)) {
456
+ for (const e of evt) yield e;
457
+ } else {
458
+ yield evt;
459
+ }
460
+ }
448
461
  }
449
462
  } finally {
450
463
  try {
@@ -614,7 +627,7 @@ function createMockTransport(opts = {}) {
614
627
  async createSession(_opts) {
615
628
  await sleep(latency);
616
629
  return {
617
- sessionId: chunkSI5RD2GD_cjs.createId("s"),
630
+ sessionId: chunkOZAU3QWD_cjs.createId("s"),
618
631
  messages: history.length ? [...history] : void 0,
619
632
  hasMore: false,
620
633
  cursor: null,
@@ -631,12 +644,12 @@ function createMockTransport(opts = {}) {
631
644
  throw new Error("mock transport scripted failure");
632
645
  }
633
646
  history.push({
634
- id: chunkSI5RD2GD_cjs.createId("u"),
647
+ id: chunkOZAU3QWD_cjs.createId("u"),
635
648
  role: "user",
636
649
  content,
637
650
  createdAt: Date.now()
638
651
  });
639
- const messageId = chunkSI5RD2GD_cjs.createId("a");
652
+ const messageId = chunkOZAU3QWD_cjs.createId("a");
640
653
  yield { type: "message_start", messageId, sessionId: _sid };
641
654
  const reply = replies[turn % replies.length];
642
655
  turn += 1;
@@ -665,7 +678,7 @@ function createMockTransport(opts = {}) {
665
678
  turn += 1;
666
679
  const text = typeof reply === "string" ? reply : reply.filter((e) => e.type === "chunk").map((e) => e.delta).join("");
667
680
  return {
668
- id: chunkSI5RD2GD_cjs.createId("a"),
681
+ id: chunkOZAU3QWD_cjs.createId("a"),
669
682
  role: "assistant",
670
683
  content: text || DEFAULT_REPLY,
671
684
  createdAt: Date.now()
@@ -676,6 +689,1440 @@ function createMockTransport(opts = {}) {
676
689
  };
677
690
  }
678
691
  chunkOLISEQHS_cjs.__name(createMockTransport, "createMockTransport");
692
+
693
+ // src/tools/Chat/core/transport/mappers/pydantic-ai.ts
694
+ function createToolIdQueue() {
695
+ const queues = /* @__PURE__ */ new Map();
696
+ let counter = 0;
697
+ return {
698
+ push(name) {
699
+ const id = `${name}-${counter++}-${Date.now()}`;
700
+ const q = queues.get(name) ?? [];
701
+ q.push(id);
702
+ queues.set(name, q);
703
+ return id;
704
+ },
705
+ shift(name) {
706
+ return queues.get(name)?.shift() ?? `${name}-orphan-${counter++}`;
707
+ },
708
+ clear() {
709
+ queues.clear();
710
+ }
711
+ };
712
+ }
713
+ chunkOLISEQHS_cjs.__name(createToolIdQueue, "createToolIdQueue");
714
+ function* mapPydanticAIEvent(ev, toolIds) {
715
+ switch (ev.type) {
716
+ case "text_delta":
717
+ if (ev.delta) yield { type: "chunk", delta: ev.delta };
718
+ return;
719
+ case "tool_call": {
720
+ const name = ev.tool ?? "tool";
721
+ const toolId = toolIds.push(name);
722
+ yield { type: "tool_call_start", toolId, name, input: ev.args };
723
+ return;
724
+ }
725
+ case "tool_result": {
726
+ const name = ev.tool ?? "tool";
727
+ const toolId = toolIds.shift(name);
728
+ const output = ev.data !== void 0 ? ev.data : ev.result;
729
+ yield { type: "tool_call_end", toolId, output, status: "success" };
730
+ return;
731
+ }
732
+ case "done":
733
+ yield { type: "message_end", tokensOut: ev.total_tokens };
734
+ return;
735
+ case "error":
736
+ yield { type: "error", code: "backend_error", message: ev.error ?? "Unknown error" };
737
+ return;
738
+ case "approval_required":
739
+ return;
740
+ }
741
+ }
742
+ chunkOLISEQHS_cjs.__name(mapPydanticAIEvent, "mapPydanticAIEvent");
743
+ function createPydanticAISSEMap() {
744
+ const toolIds = createToolIdQueue();
745
+ return (raw) => {
746
+ if (!raw.data) return null;
747
+ let parsed;
748
+ try {
749
+ parsed = JSON.parse(raw.data);
750
+ } catch {
751
+ return null;
752
+ }
753
+ const out = [];
754
+ for (const evt of mapPydanticAIEvent(parsed, toolIds)) {
755
+ out.push(evt);
756
+ }
757
+ if (out.length === 0) return null;
758
+ if (out.length === 1) return out[0];
759
+ return out;
760
+ };
761
+ }
762
+ chunkOLISEQHS_cjs.__name(createPydanticAISSEMap, "createPydanticAISSEMap");
763
+
764
+ // src/tools/Chat/core/transport/pydantic-ai-transport.ts
765
+ var DEFAULT_SESSION_ID = "default";
766
+ function mapStatusToCode2(status) {
767
+ if (status === 401 || status === 403) return "unauthorized";
768
+ if (status === 404) return "not_found";
769
+ if (status === 408) return "timeout";
770
+ if (status === 429) return "rate_limited";
771
+ if (status >= 500) return "server_error";
772
+ return "error";
773
+ }
774
+ chunkOLISEQHS_cjs.__name(mapStatusToCode2, "mapStatusToCode");
775
+ function createPydanticAIChatTransport(opts) {
776
+ const fetchImpl = opts.fetchImpl ?? fetch.bind(globalThis);
777
+ const streamMethod = opts.streamMethod ?? "POST";
778
+ async function resolvedHeaders(extra) {
779
+ const base = opts.buildHeaders ? await opts.buildHeaders() : {};
780
+ const headers = new Headers(base);
781
+ if (extra) {
782
+ for (const [k, v] of Object.entries(extra)) headers.set(k, v);
783
+ }
784
+ return headers;
785
+ }
786
+ chunkOLISEQHS_cjs.__name(resolvedHeaders, "resolvedHeaders");
787
+ return {
788
+ async createSession(createOpts) {
789
+ if (opts.bootstrapSession) return opts.bootstrapSession(createOpts);
790
+ return { sessionId: DEFAULT_SESSION_ID };
791
+ },
792
+ async loadHistory(sessionId, cursor) {
793
+ if (opts.loadHistory) return opts.loadHistory(sessionId, cursor);
794
+ return { messages: [], hasMore: false, nextCursor: null };
795
+ },
796
+ async *stream(sessionId, content, options) {
797
+ const url = opts.buildStreamUrl(sessionId, content);
798
+ const headers = await resolvedHeaders({ Accept: "text/event-stream" });
799
+ const init = {
800
+ method: streamMethod,
801
+ headers,
802
+ signal: options.signal
803
+ };
804
+ if (streamMethod === "POST") {
805
+ headers.set("Content-Type", "application/json");
806
+ init.body = JSON.stringify({
807
+ content,
808
+ attachments: options.attachments ?? [],
809
+ metadata: options.metadata ?? {}
810
+ });
811
+ }
812
+ const res = await fetchImpl(typeof url === "string" ? url : url.toString(), init);
813
+ if (!res.ok) {
814
+ const text = await res.text().catch(() => "");
815
+ throw new TransportError(
816
+ `stream failed (${res.status}): ${text || res.statusText}`,
817
+ mapStatusToCode2(res.status)
818
+ );
819
+ }
820
+ const sideChannel = opts.onPydanticEvent;
821
+ if (!sideChannel) {
822
+ yield* parseSSE(res, {
823
+ signal: options.signal,
824
+ idleTimeoutMs: opts.idleTimeoutMs,
825
+ map: createPydanticAISSEMap()
826
+ });
827
+ return;
828
+ }
829
+ const toolIds = createToolIdQueue();
830
+ yield* parseSSE(res, {
831
+ signal: options.signal,
832
+ idleTimeoutMs: opts.idleTimeoutMs,
833
+ map: /* @__PURE__ */ chunkOLISEQHS_cjs.__name((raw) => {
834
+ if (!raw.data) return null;
835
+ let parsed;
836
+ try {
837
+ parsed = JSON.parse(raw.data);
838
+ } catch {
839
+ return null;
840
+ }
841
+ try {
842
+ sideChannel(parsed);
843
+ } catch {
844
+ }
845
+ const out = [];
846
+ for (const evt of mapPydanticAIEvent(parsed, toolIds)) out.push(evt);
847
+ if (out.length === 0) return null;
848
+ if (out.length === 1) return out[0];
849
+ return out;
850
+ }, "map")
851
+ });
852
+ },
853
+ async send(sessionId, content, sendOpts) {
854
+ if (opts.send) return opts.send(sessionId, content, sendOpts);
855
+ throw new TransportError(
856
+ "Buffered send is not supported by this transport",
857
+ "unsupported"
858
+ );
859
+ },
860
+ async closeSession(sessionId) {
861
+ if (opts.closeSession) await opts.closeSession(sessionId);
862
+ }
863
+ };
864
+ }
865
+ chunkOLISEQHS_cjs.__name(createPydanticAIChatTransport, "createPydanticAIChatTransport");
866
+ var SIZE_PX = { sm: 44, md: 56, lg: 64 };
867
+ var ICON_PX = { sm: 18, md: 22, lg: 26 };
868
+ function useEffectiveFABSize(size, inline) {
869
+ const isPhone = hooks.useIsPhone();
870
+ const isBelowDesktop = hooks.useIsTabletOrBelow();
871
+ if (size !== "responsive") return size;
872
+ if (inline) return "md";
873
+ if (isPhone) return "sm";
874
+ if (isBelowDesktop) return "md";
875
+ return "lg";
876
+ }
877
+ chunkOLISEQHS_cjs.__name(useEffectiveFABSize, "useEffectiveFABSize");
878
+ function positionStyle(position, offset2) {
879
+ const [vert, horiz] = position.split("-");
880
+ return { [vert]: offset2, [horiz]: offset2 };
881
+ }
882
+ chunkOLISEQHS_cjs.__name(positionStyle, "positionStyle");
883
+ function tooltipSideClasses(position) {
884
+ return position.endsWith("right") ? "right-full mr-3 origin-right" : "left-full ml-3 origin-left";
885
+ }
886
+ chunkOLISEQHS_cjs.__name(tooltipSideClasses, "tooltipSideClasses");
887
+ function Badge({ value }) {
888
+ const display = value > 9 ? "9+" : String(value);
889
+ return /* @__PURE__ */ jsxRuntime.jsx(
890
+ "span",
891
+ {
892
+ "aria-hidden": "true",
893
+ className: lib.cn(
894
+ "absolute -right-1 -top-1 inline-flex min-w-[18px] h-[18px] items-center justify-center",
895
+ "rounded-full bg-destructive px-1 text-[10px] font-semibold leading-none text-destructive-foreground",
896
+ "ring-2 ring-background"
897
+ ),
898
+ children: display
899
+ }
900
+ );
901
+ }
902
+ chunkOLISEQHS_cjs.__name(Badge, "Badge");
903
+ function PulseDot() {
904
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "absolute right-1 top-1", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "relative inline-flex h-2.5 w-2.5", children: [
905
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute inset-0 rounded-full bg-destructive opacity-75 animate-ping" }),
906
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "relative inline-flex h-2.5 w-2.5 rounded-full bg-destructive ring-2 ring-background" })
907
+ ] }) });
908
+ }
909
+ chunkOLISEQHS_cjs.__name(PulseDot, "PulseDot");
910
+ function Tooltip({ text, side }) {
911
+ return /* @__PURE__ */ jsxRuntime.jsx(
912
+ "span",
913
+ {
914
+ role: "tooltip",
915
+ className: lib.cn(
916
+ "pointer-events-none absolute top-1/2 -translate-y-1/2 whitespace-nowrap",
917
+ "rounded-md bg-popover px-2.5 py-1 text-xs font-medium text-popover-foreground shadow-md",
918
+ "border border-border opacity-0 scale-95 transition-all duration-150",
919
+ "group-hover:opacity-100 group-hover:scale-100",
920
+ "group-focus-within:opacity-100 group-focus-within:scale-100",
921
+ side
922
+ ),
923
+ children: text
924
+ }
925
+ );
926
+ }
927
+ chunkOLISEQHS_cjs.__name(Tooltip, "Tooltip");
928
+ function ChatFAB({
929
+ onClick,
930
+ ariaLabel = "Open chat",
931
+ icon,
932
+ variant = "simple",
933
+ size = "responsive",
934
+ position = "bottom-right",
935
+ offset: offset2 = 24,
936
+ zIndex = 9999,
937
+ pulse = false,
938
+ badge,
939
+ tooltip,
940
+ inline = false,
941
+ className,
942
+ style
943
+ }) {
944
+ const effectiveSize = useEffectiveFABSize(size, inline);
945
+ const px = SIZE_PX[effectiveSize];
946
+ const iconPx = ICON_PX[effectiveSize];
947
+ const renderedIcon = icon ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bot, { size: iconPx });
948
+ const baseButton = lib.cn(
949
+ "relative grid place-items-center rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
950
+ "transition-transform hover:scale-105"
951
+ );
952
+ return /* @__PURE__ */ jsxRuntime.jsxs(
953
+ "div",
954
+ {
955
+ className: lib.cn("group", inline ? "relative inline-flex" : "fixed"),
956
+ style: inline ? void 0 : { ...positionStyle(position, offset2), zIndex },
957
+ children: [
958
+ variant === "animated" && /* @__PURE__ */ jsxRuntime.jsx(
959
+ AnimatedFAB,
960
+ {
961
+ ariaLabel,
962
+ onClick,
963
+ size: px,
964
+ className,
965
+ style,
966
+ children: renderedIcon
967
+ }
968
+ ),
969
+ variant === "glass" && /* @__PURE__ */ jsxRuntime.jsxs(
970
+ "button",
971
+ {
972
+ type: "button",
973
+ "aria-label": ariaLabel,
974
+ onClick,
975
+ className: lib.cn(
976
+ baseButton,
977
+ "border border-border/40 bg-background/60 text-foreground shadow-lg backdrop-blur-xl",
978
+ "hover:bg-background/80",
979
+ className
980
+ ),
981
+ style: { width: px, height: px, ...style },
982
+ children: [
983
+ renderedIcon,
984
+ badge !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { value: badge }) : pulse ? /* @__PURE__ */ jsxRuntime.jsx(PulseDot, {}) : null
985
+ ]
986
+ }
987
+ ),
988
+ variant === "simple" && /* @__PURE__ */ jsxRuntime.jsxs(
989
+ "button",
990
+ {
991
+ type: "button",
992
+ "aria-label": ariaLabel,
993
+ onClick,
994
+ className: lib.cn(
995
+ baseButton,
996
+ "bg-primary text-primary-foreground hover:bg-primary/90 shadow-2xl",
997
+ className
998
+ ),
999
+ style: { width: px, height: px, ...style },
1000
+ children: [
1001
+ renderedIcon,
1002
+ badge !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(Badge, { value: badge }) : pulse ? /* @__PURE__ */ jsxRuntime.jsx(PulseDot, {}) : null
1003
+ ]
1004
+ }
1005
+ ),
1006
+ tooltip && /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { text: tooltip, side: tooltipSideClasses(position) })
1007
+ ]
1008
+ }
1009
+ );
1010
+ }
1011
+ chunkOLISEQHS_cjs.__name(ChatFAB, "ChatFAB");
1012
+ function AnimatedFAB({ ariaLabel, onClick, size, className, style, children }) {
1013
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: ANIMATED_CSS }),
1015
+ /* @__PURE__ */ jsxRuntime.jsx(
1016
+ "div",
1017
+ {
1018
+ className: lib.cn("cmdop-fab-anim", className),
1019
+ style: { width: size, height: size, ...style },
1020
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cmdop-fab-anim-glow", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "cmdop-fab-anim-wrap", children: [
1021
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cmdop-fab-anim-grad cmdop-fab-anim-grad-1" }),
1022
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cmdop-fab-anim-grad cmdop-fab-anim-grad-2" }),
1023
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "cmdop-fab-anim-inner" }),
1024
+ /* @__PURE__ */ jsxRuntime.jsx(
1025
+ "button",
1026
+ {
1027
+ type: "button",
1028
+ "aria-label": ariaLabel,
1029
+ onClick,
1030
+ className: "cmdop-fab-anim-btn",
1031
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "cmdop-fab-anim-icon", children })
1032
+ }
1033
+ )
1034
+ ] }) })
1035
+ }
1036
+ )
1037
+ ] });
1038
+ }
1039
+ chunkOLISEQHS_cjs.__name(AnimatedFAB, "AnimatedFAB");
1040
+ var ANIMATED_CSS = `
1041
+ .cmdop-fab-anim {
1042
+ position: relative;
1043
+ pointer-events: auto;
1044
+ }
1045
+ .cmdop-fab-anim-glow {
1046
+ width: 100%; height: 100%;
1047
+ border-radius: 50%;
1048
+ overflow: hidden;
1049
+ animation:
1050
+ cmdop-fab-entrance 0.6s cubic-bezier(0.34, 1.45, 0.64, 1) forwards,
1051
+ cmdop-fab-glow-shift 8s ease-in-out 0.6s infinite;
1052
+ }
1053
+ .cmdop-fab-anim-wrap {
1054
+ position: relative; width: 100%; height: 100%;
1055
+ border-radius: 50%; overflow: hidden;
1056
+ }
1057
+ .cmdop-fab-anim-grad { position: absolute; inset: 0; border-radius: 50%; }
1058
+ .cmdop-fab-anim-grad-1 {
1059
+ background: conic-gradient(
1060
+ from 0deg,
1061
+ #fbbf24 0%, rgba(251,191,36,0) 15%,
1062
+ rgba(168,85,247,0) 20%, #a855f7 35%, rgba(168,85,247,0) 50%,
1063
+ rgba(20,184,166,0) 55%, #14b8a6 70%, rgba(20,184,166,0) 85%,
1064
+ rgba(236,72,153,0) 88%, #ec4899 97%, #fbbf24 100%
1065
+ );
1066
+ animation: cmdop-fab-rotate 7s linear infinite;
1067
+ filter: blur(1px); opacity: 0.95;
1068
+ }
1069
+ .cmdop-fab-anim-grad-2 {
1070
+ inset: 1px;
1071
+ background: conic-gradient(
1072
+ from 180deg,
1073
+ #a855f7 0%, rgba(168,85,247,0) 20%,
1074
+ rgba(20,184,166,0) 30%, #14b8a6 50%, rgba(20,184,166,0) 70%,
1075
+ rgba(251,191,36,0) 75%, #fbbf24 95%, #a855f7 100%
1076
+ );
1077
+ animation: cmdop-fab-rotate-rev 9s linear infinite;
1078
+ filter: blur(0.75px); opacity: 0.7;
1079
+ }
1080
+ .cmdop-fab-anim-inner {
1081
+ position: absolute; inset: 3px; border-radius: 50%;
1082
+ background: rgba(10, 10, 10, 0.65);
1083
+ backdrop-filter: blur(12px) saturate(1.8);
1084
+ -webkit-backdrop-filter: blur(12px) saturate(1.8);
1085
+ animation: cmdop-fab-inner-glow 5s ease-in-out infinite;
1086
+ }
1087
+ .cmdop-fab-anim-btn {
1088
+ position: absolute; inset: 2px;
1089
+ border-radius: 50%; border: none; background: transparent;
1090
+ cursor: pointer; display: flex; align-items: center; justify-content: center;
1091
+ transition: transform 0.2s;
1092
+ }
1093
+ .cmdop-fab-anim-btn:hover { transform: scale(1.06); }
1094
+ .cmdop-fab-anim-icon {
1095
+ color: #fbbf24; display: flex;
1096
+ filter: drop-shadow(0 0 6px rgba(251,191,36,0.8));
1097
+ animation: cmdop-fab-icon-pulse 2.5s ease-in-out infinite;
1098
+ }
1099
+ @keyframes cmdop-fab-rotate { to { transform: rotate(360deg); } }
1100
+ @keyframes cmdop-fab-rotate-rev { to { transform: rotate(-360deg); } }
1101
+ @keyframes cmdop-fab-entrance {
1102
+ 0% { transform: scale(0); }
1103
+ 50% { transform: scale(1.08); }
1104
+ 70% { transform: scale(0.98); }
1105
+ 100% { transform: scale(1); }
1106
+ }
1107
+ @keyframes cmdop-fab-glow-shift {
1108
+ 0%, 100% { box-shadow: 0 0 20px rgba(251,191,36,0.5), 0 0 40px rgba(168,85,247,0.3); }
1109
+ 33% { box-shadow: 0 0 20px rgba(168,85,247,0.5), 0 0 40px rgba(20,184,166,0.3); }
1110
+ 66% { box-shadow: 0 0 20px rgba(20,184,166,0.5), 0 0 40px rgba(236,72,153,0.3); }
1111
+ }
1112
+ @keyframes cmdop-fab-icon-pulse {
1113
+ 0%, 100% { opacity: 1; transform: scale(1); }
1114
+ 50% { opacity: 0.85; transform: scale(1.15); }
1115
+ }
1116
+ @keyframes cmdop-fab-inner-glow {
1117
+ 0%, 100% { box-shadow: inset 0 0 20px rgba(251,191,36,0.25), inset 0 0 40px rgba(168,85,247,0.15); }
1118
+ 50% { box-shadow: inset 0 0 25px rgba(168,85,247,0.3), inset 0 0 45px rgba(20,184,166,0.2); }
1119
+ }
1120
+ `;
1121
+ function ChatHeader({
1122
+ title,
1123
+ icon,
1124
+ actions,
1125
+ showClose = true,
1126
+ onClose,
1127
+ closeLabel = "Close",
1128
+ closeSlot,
1129
+ className
1130
+ }) {
1131
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1132
+ "header",
1133
+ {
1134
+ className: lib.cn(
1135
+ "border-border bg-muted/30 flex shrink-0 items-center justify-between border-b px-4 py-2.5",
1136
+ className
1137
+ ),
1138
+ children: [
1139
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 items-center gap-2 text-sm font-semibold", children: [
1140
+ icon ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Bot, { className: "text-primary h-4 w-4 shrink-0" }),
1141
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: title })
1142
+ ] }),
1143
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
1144
+ actions,
1145
+ closeSlot ?? (showClose && onClose && /* @__PURE__ */ jsxRuntime.jsx(
1146
+ components.Button,
1147
+ {
1148
+ variant: "ghost",
1149
+ size: "sm",
1150
+ onClick: onClose,
1151
+ "aria-label": closeLabel,
1152
+ className: "-mr-1 h-7 w-7 p-0",
1153
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4" })
1154
+ }
1155
+ ))
1156
+ ] })
1157
+ ]
1158
+ }
1159
+ );
1160
+ }
1161
+ chunkOLISEQHS_cjs.__name(ChatHeader, "ChatHeader");
1162
+ function useChatPresence(open, exitDurationMs = 200) {
1163
+ const [phase, setPhase] = React.useState("hidden");
1164
+ const timerRef = React.useRef(null);
1165
+ React.useEffect(() => {
1166
+ if (timerRef.current) clearTimeout(timerRef.current);
1167
+ if (open) {
1168
+ setPhase("entering");
1169
+ timerRef.current = setTimeout(() => setPhase("visible"), 16);
1170
+ } else {
1171
+ setPhase("leaving");
1172
+ timerRef.current = setTimeout(() => setPhase("hidden"), exitDurationMs);
1173
+ }
1174
+ return () => {
1175
+ if (timerRef.current) clearTimeout(timerRef.current);
1176
+ };
1177
+ }, [open, exitDurationMs]);
1178
+ return phase;
1179
+ }
1180
+ chunkOLISEQHS_cjs.__name(useChatPresence, "useChatPresence");
1181
+ function dockPositionStyle(position, horizontal, vertical) {
1182
+ const [vert, horiz] = position.split("-");
1183
+ return { [vert]: vertical, [horiz]: horizontal };
1184
+ }
1185
+ chunkOLISEQHS_cjs.__name(dockPositionStyle, "dockPositionStyle");
1186
+ function ChatDock({
1187
+ open,
1188
+ onClose,
1189
+ children,
1190
+ mode = "popover",
1191
+ side = "right",
1192
+ title = "Chat",
1193
+ icon,
1194
+ headerActions,
1195
+ hideHeader = false,
1196
+ closeLabel,
1197
+ width,
1198
+ height = 720,
1199
+ position = "bottom-right",
1200
+ offset: offset2,
1201
+ exitDurationMs = 200,
1202
+ zIndex = 1e4,
1203
+ ariaLabel,
1204
+ className,
1205
+ mobileFullscreen = true,
1206
+ disablePortal = false,
1207
+ inline = false,
1208
+ reserveBodySpace
1209
+ }) {
1210
+ const phase = useChatPresence(open, exitDurationMs);
1211
+ const isMobile = hooks.useIsMobile();
1212
+ const isBelowDesktop = hooks.useIsTabletOrBelow();
1213
+ const effectiveMode = mode === "side" && !isBelowDesktop ? "side" : "popover";
1214
+ const fullscreen = mobileFullscreen && isMobile;
1215
+ const wantsReserve = !inline && !fullscreen && effectiveMode === "side" && (reserveBodySpace ?? true);
1216
+ const resolvedSideWidth = width ?? 420;
1217
+ React.useEffect(() => {
1218
+ if (!wantsReserve || phase === "hidden") return;
1219
+ const body = document.body;
1220
+ if (!body) return;
1221
+ const cssVar = `${resolvedSideWidth}px`;
1222
+ const padKey = side === "right" ? "paddingRight" : "paddingLeft";
1223
+ const prevPad = body.style[padKey];
1224
+ const prevVar = body.style.getPropertyValue("--chat-dock-reserve");
1225
+ body.style[padKey] = cssVar;
1226
+ body.style.setProperty("--chat-dock-reserve", cssVar);
1227
+ return () => {
1228
+ body.style[padKey] = prevPad;
1229
+ if (prevVar) body.style.setProperty("--chat-dock-reserve", prevVar);
1230
+ else body.style.removeProperty("--chat-dock-reserve");
1231
+ };
1232
+ }, [wantsReserve, phase, side, resolvedSideWidth]);
1233
+ if (phase === "hidden") return null;
1234
+ const animating = phase === "entering" || phase === "leaving";
1235
+ const horizontal = offset2?.horizontal ?? 24;
1236
+ const vertical = offset2?.vertical ?? 96;
1237
+ const resolvedWidth = width ?? (effectiveMode === "side" ? resolvedSideWidth : 480);
1238
+ let containerStyle;
1239
+ let cornerClass;
1240
+ const dynVH = "100dvh";
1241
+ if (inline) {
1242
+ containerStyle = {
1243
+ position: "relative",
1244
+ width: resolvedWidth,
1245
+ height,
1246
+ maxHeight: `calc(${dynVH} - 16px)`,
1247
+ pointerEvents: phase === "visible" ? "auto" : "none"
1248
+ };
1249
+ cornerClass = "rounded-xl border";
1250
+ } else if (fullscreen) {
1251
+ containerStyle = {
1252
+ position: "fixed",
1253
+ top: 0,
1254
+ [side === "left" ? "left" : "right"]: 0,
1255
+ width: "100vw",
1256
+ height: dynVH,
1257
+ zIndex,
1258
+ pointerEvents: phase === "visible" ? "auto" : "none"
1259
+ };
1260
+ cornerClass = "rounded-none border-0";
1261
+ } else if (effectiveMode === "side") {
1262
+ containerStyle = {
1263
+ position: "fixed",
1264
+ top: 0,
1265
+ [side]: 0,
1266
+ height: dynVH,
1267
+ zIndex,
1268
+ width: `min(${resolvedWidth}px, 100vw)`,
1269
+ pointerEvents: phase === "visible" ? "auto" : "none"
1270
+ };
1271
+ cornerClass = side === "right" ? "rounded-none border-l" : "rounded-none border-r";
1272
+ } else {
1273
+ const heightCap = `calc(${dynVH} - ${vertical + 24}px)`;
1274
+ containerStyle = {
1275
+ position: "fixed",
1276
+ ...dockPositionStyle(position, horizontal, vertical),
1277
+ zIndex,
1278
+ width: `min(${resolvedWidth}px, calc(100vw - 32px))`,
1279
+ height: `min(${height}px, ${heightCap})`,
1280
+ minHeight: `min(320px, ${heightCap})`,
1281
+ pointerEvents: phase === "visible" ? "auto" : "none"
1282
+ };
1283
+ cornerClass = "rounded-xl border";
1284
+ }
1285
+ const enterClass = (() => {
1286
+ if (fullscreen) return "opacity-0";
1287
+ if (effectiveMode === "side") {
1288
+ return side === "right" ? "opacity-0 translate-x-4" : "opacity-0 -translate-x-4";
1289
+ }
1290
+ return "opacity-0 scale-95 translate-y-2";
1291
+ })();
1292
+ const visibleClass = "opacity-100 scale-100 translate-y-0 translate-x-0";
1293
+ return /* @__PURE__ */ jsxRuntime.jsx(components.Portal, { disablePortal: disablePortal || inline, children: /* @__PURE__ */ jsxRuntime.jsxs(
1294
+ "div",
1295
+ {
1296
+ role: "dialog",
1297
+ "aria-label": ariaLabel ?? (typeof title === "string" ? title : "Chat"),
1298
+ "aria-hidden": phase === "leaving",
1299
+ className: lib.cn(
1300
+ "bg-popover text-popover-foreground border-border",
1301
+ "flex flex-col overflow-hidden shadow-2xl",
1302
+ cornerClass,
1303
+ "transition-all duration-200 ease-out",
1304
+ animating ? enterClass : visibleClass,
1305
+ className
1306
+ ),
1307
+ style: containerStyle,
1308
+ children: [
1309
+ !hideHeader && /* @__PURE__ */ jsxRuntime.jsx(
1310
+ ChatHeader,
1311
+ {
1312
+ title,
1313
+ icon,
1314
+ actions: headerActions,
1315
+ onClose,
1316
+ closeLabel
1317
+ }
1318
+ ),
1319
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-h-0 min-w-0 flex-1 overflow-hidden", children })
1320
+ ]
1321
+ }
1322
+ ) });
1323
+ }
1324
+ chunkOLISEQHS_cjs.__name(ChatDock, "ChatDock");
1325
+ var ChatHeaderActionButton = React.forwardRef(
1326
+ /* @__PURE__ */ chunkOLISEQHS_cjs.__name(function ChatHeaderActionButton2({ icon, ariaLabel, badge, destructive, loading, disabled, className, ...rest }, ref) {
1327
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1328
+ "button",
1329
+ {
1330
+ ref,
1331
+ type: "button",
1332
+ "aria-label": ariaLabel,
1333
+ title: ariaLabel,
1334
+ disabled: disabled || loading,
1335
+ className: lib.cn(
1336
+ "relative inline-flex h-7 w-7 items-center justify-center rounded-md",
1337
+ "text-muted-foreground transition-colors",
1338
+ "hover:bg-accent hover:text-foreground",
1339
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1340
+ "disabled:opacity-50 disabled:cursor-not-allowed",
1341
+ destructive && "hover:bg-destructive/15 hover:text-destructive",
1342
+ loading && "animate-pulse",
1343
+ className
1344
+ ),
1345
+ ...rest,
1346
+ children: [
1347
+ icon,
1348
+ badge !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(
1349
+ "span",
1350
+ {
1351
+ "aria-hidden": "true",
1352
+ className: "absolute -right-0.5 -top-0.5 inline-flex min-w-[14px] h-[14px] items-center justify-center rounded-full bg-destructive px-1 text-[9px] font-semibold leading-none text-destructive-foreground ring-2 ring-background",
1353
+ children: badge > 9 ? "9+" : badge
1354
+ }
1355
+ )
1356
+ ]
1357
+ }
1358
+ );
1359
+ }, "ChatHeaderActionButton")
1360
+ );
1361
+ function ChatHeaderModeToggle({
1362
+ mode,
1363
+ onToggle,
1364
+ expandLabel = "Dock to side",
1365
+ collapseLabel = "Back to popover",
1366
+ forceVisible = false
1367
+ }) {
1368
+ const isBelowDesktop = hooks.useIsTabletOrBelow();
1369
+ if (isBelowDesktop && !forceVisible) return null;
1370
+ const isSide = mode === "side";
1371
+ return /* @__PURE__ */ jsxRuntime.jsx(
1372
+ ChatHeaderActionButton,
1373
+ {
1374
+ icon: isSide ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightClose, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelRightOpen, { className: "h-3.5 w-3.5" }),
1375
+ ariaLabel: isSide ? collapseLabel : expandLabel,
1376
+ onClick: onToggle
1377
+ }
1378
+ );
1379
+ }
1380
+ chunkOLISEQHS_cjs.__name(ChatHeaderModeToggle, "ChatHeaderModeToggle");
1381
+ function ChatHeaderAudioToggle({
1382
+ muted,
1383
+ onToggle,
1384
+ unmuteLabel = "Unmute notifications",
1385
+ muteLabel = "Mute notifications"
1386
+ }) {
1387
+ return /* @__PURE__ */ jsxRuntime.jsx(
1388
+ ChatHeaderActionButton,
1389
+ {
1390
+ icon: muted ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.VolumeX, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Volume2, { className: "h-3.5 w-3.5" }),
1391
+ ariaLabel: muted ? unmuteLabel : muteLabel,
1392
+ onClick: onToggle
1393
+ }
1394
+ );
1395
+ }
1396
+ chunkOLISEQHS_cjs.__name(ChatHeaderAudioToggle, "ChatHeaderAudioToggle");
1397
+ function useChatReset(opts) {
1398
+ const { onReset, onSuccess, onError } = opts;
1399
+ const [isResetting, setIsResetting] = React.useState(false);
1400
+ const reset = React.useCallback(async () => {
1401
+ if (isResetting) return false;
1402
+ setIsResetting(true);
1403
+ try {
1404
+ const ok = await onReset();
1405
+ if (ok) onSuccess?.();
1406
+ else onError?.();
1407
+ return ok;
1408
+ } catch (err) {
1409
+ onError?.(err);
1410
+ return false;
1411
+ } finally {
1412
+ setIsResetting(false);
1413
+ }
1414
+ }, [isResetting, onReset, onSuccess, onError]);
1415
+ return { reset, isResetting };
1416
+ }
1417
+ chunkOLISEQHS_cjs.__name(useChatReset, "useChatReset");
1418
+ var DEFAULT_TITLE = "Clear conversation?";
1419
+ var DEFAULT_MESSAGE = "The assistant will forget this session and start a new one. This cannot be undone.";
1420
+ var DEFAULT_LABEL = "Clear conversation";
1421
+ function ChatHeaderResetButton({
1422
+ onReset,
1423
+ onSuccess,
1424
+ onError,
1425
+ confirm = true,
1426
+ confirmTitle = DEFAULT_TITLE,
1427
+ confirmMessage = DEFAULT_MESSAGE,
1428
+ ariaLabel = DEFAULT_LABEL
1429
+ }) {
1430
+ const { reset, isResetting } = useChatReset({ onReset, onSuccess, onError });
1431
+ const handleClick = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(async () => {
1432
+ if (confirm) {
1433
+ const api = typeof window !== "undefined" ? window.dialog : void 0;
1434
+ if (api?.confirm) {
1435
+ const ok = await api.confirm({
1436
+ title: confirmTitle,
1437
+ message: confirmMessage,
1438
+ variant: "destructive",
1439
+ confirmText: "Clear",
1440
+ cancelText: "Cancel"
1441
+ });
1442
+ if (!ok) return;
1443
+ } else if (typeof window !== "undefined" && typeof window.confirm === "function") {
1444
+ const ok = window.confirm(`${confirmTitle}
1445
+
1446
+ ${confirmMessage}`);
1447
+ if (!ok) return;
1448
+ }
1449
+ }
1450
+ await reset();
1451
+ }, "handleClick");
1452
+ return /* @__PURE__ */ jsxRuntime.jsx(
1453
+ ChatHeaderActionButton,
1454
+ {
1455
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCcw, { className: "h-3.5 w-3.5" }),
1456
+ ariaLabel,
1457
+ onClick: handleClick,
1458
+ loading: isResetting,
1459
+ destructive: true
1460
+ }
1461
+ );
1462
+ }
1463
+ chunkOLISEQHS_cjs.__name(ChatHeaderResetButton, "ChatHeaderResetButton");
1464
+
1465
+ // src/tools/SpeechRecognition/core/languages-catalog.ts
1466
+ var WEB_SPEECH_LANGUAGES = [
1467
+ { name: "Afrikaans", iso: "af", englishName: "afrikaans", dialects: [{ code: "af-ZA", region: "South Africa" }] },
1468
+ { name: "\u12A0\u121B\u122D\u129B", iso: "am", englishName: "amharic", dialects: [{ code: "am-ET", region: "Ethiopia" }] },
1469
+ { name: "Az\u0259rbaycanca", iso: "az", englishName: "azerbaijani", dialects: [{ code: "az-AZ", region: "Azerbaijan" }] },
1470
+ {
1471
+ name: "\u09AC\u09BE\u0982\u09B2\u09BE",
1472
+ iso: "bn",
1473
+ englishName: "bengali",
1474
+ dialects: [
1475
+ { code: "bn-BD", region: "Bangladesh" },
1476
+ { code: "bn-IN", region: "India" }
1477
+ ]
1478
+ },
1479
+ { name: "Bahasa Indonesia", iso: "id", englishName: "indonesian", dialects: [{ code: "id-ID", region: "Indonesia" }] },
1480
+ { name: "Bahasa Melayu", iso: "ms", englishName: "malay", dialects: [{ code: "ms-MY", region: "Malaysia" }] },
1481
+ { name: "Catal\xE0", iso: "ca", englishName: "catalan", dialects: [{ code: "ca-ES", region: "Spain" }] },
1482
+ { name: "\u010Ce\u0161tina", iso: "cs", englishName: "czech", dialects: [{ code: "cs-CZ", region: "Czechia" }] },
1483
+ { name: "Dansk", iso: "da", englishName: "danish", dialects: [{ code: "da-DK", region: "Denmark" }] },
1484
+ { name: "Deutsch", iso: "de", englishName: "german", dialects: [{ code: "de-DE", region: "Germany" }] },
1485
+ {
1486
+ name: "English",
1487
+ iso: "en",
1488
+ englishName: "english",
1489
+ dialects: [
1490
+ { code: "en-US", region: "United States" },
1491
+ { code: "en-GB", region: "United Kingdom" },
1492
+ { code: "en-AU", region: "Australia" },
1493
+ { code: "en-CA", region: "Canada" },
1494
+ { code: "en-IN", region: "India" },
1495
+ { code: "en-NZ", region: "New Zealand" },
1496
+ { code: "en-PH", region: "Philippines" },
1497
+ { code: "en-ZA", region: "South Africa" },
1498
+ { code: "en-NG", region: "Nigeria" },
1499
+ { code: "en-GH", region: "Ghana" },
1500
+ { code: "en-KE", region: "Kenya" },
1501
+ { code: "en-TZ", region: "Tanzania" }
1502
+ ]
1503
+ },
1504
+ {
1505
+ name: "Espa\xF1ol",
1506
+ iso: "es",
1507
+ englishName: "spanish",
1508
+ dialects: [
1509
+ { code: "es-ES", region: "Espa\xF1a" },
1510
+ { code: "es-MX", region: "M\xE9xico" },
1511
+ { code: "es-US", region: "Estados Unidos" },
1512
+ { code: "es-AR", region: "Argentina" },
1513
+ { code: "es-CL", region: "Chile" },
1514
+ { code: "es-CO", region: "Colombia" },
1515
+ { code: "es-PE", region: "Per\xFA" },
1516
+ { code: "es-VE", region: "Venezuela" },
1517
+ { code: "es-EC", region: "Ecuador" },
1518
+ { code: "es-GT", region: "Guatemala" },
1519
+ { code: "es-CR", region: "Costa Rica" },
1520
+ { code: "es-PA", region: "Panam\xE1" },
1521
+ { code: "es-DO", region: "Rep. Dominicana" },
1522
+ { code: "es-UY", region: "Uruguay" },
1523
+ { code: "es-PY", region: "Paraguay" },
1524
+ { code: "es-BO", region: "Bolivia" },
1525
+ { code: "es-SV", region: "El Salvador" },
1526
+ { code: "es-HN", region: "Honduras" },
1527
+ { code: "es-NI", region: "Nicaragua" },
1528
+ { code: "es-PR", region: "Puerto Rico" }
1529
+ ]
1530
+ },
1531
+ { name: "Euskara", iso: "eu", englishName: "basque", dialects: [{ code: "eu-ES", region: "Spain" }] },
1532
+ { name: "Filipino", iso: "fil", englishName: "filipino tagalog", dialects: [{ code: "fil-PH", region: "Philippines" }] },
1533
+ { name: "Fran\xE7ais", iso: "fr", englishName: "french", dialects: [{ code: "fr-FR", region: "France" }] },
1534
+ { name: "Basa Jawa", iso: "jv", englishName: "javanese", dialects: [{ code: "jv-ID", region: "Indonesia" }] },
1535
+ { name: "Galego", iso: "gl", englishName: "galician", dialects: [{ code: "gl-ES", region: "Spain" }] },
1536
+ { name: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0", iso: "gu", englishName: "gujarati", dialects: [{ code: "gu-IN", region: "India" }] },
1537
+ { name: "Hrvatski", iso: "hr", englishName: "croatian", dialects: [{ code: "hr-HR", region: "Croatia" }] },
1538
+ { name: "IsiZulu", iso: "zu", englishName: "zulu", dialects: [{ code: "zu-ZA", region: "South Africa" }] },
1539
+ { name: "\xCDslenska", iso: "is", englishName: "icelandic", dialects: [{ code: "is-IS", region: "Iceland" }] },
1540
+ {
1541
+ name: "Italiano",
1542
+ iso: "it",
1543
+ englishName: "italian",
1544
+ dialects: [
1545
+ { code: "it-IT", region: "Italia" },
1546
+ { code: "it-CH", region: "Svizzera" }
1547
+ ]
1548
+ },
1549
+ { name: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1", iso: "kn", englishName: "kannada", dialects: [{ code: "kn-IN", region: "India" }] },
1550
+ { name: "\u1797\u17B6\u179F\u17B6\u1781\u17D2\u1798\u17C2\u179A", iso: "km", englishName: "khmer cambodian", dialects: [{ code: "km-KH", region: "Cambodia" }] },
1551
+ { name: "Latvie\u0161u", iso: "lv", englishName: "latvian", dialects: [{ code: "lv-LV", region: "Latvia" }] },
1552
+ { name: "Lietuvi\u0173", iso: "lt", englishName: "lithuanian", dialects: [{ code: "lt-LT", region: "Lithuania" }] },
1553
+ { name: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02", iso: "ml", englishName: "malayalam", dialects: [{ code: "ml-IN", region: "India" }] },
1554
+ { name: "\u092E\u0930\u093E\u0920\u0940", iso: "mr", englishName: "marathi", dialects: [{ code: "mr-IN", region: "India" }] },
1555
+ { name: "Magyar", iso: "hu", englishName: "hungarian", dialects: [{ code: "hu-HU", region: "Hungary" }] },
1556
+ { name: "\u0EA5\u0EB2\u0EA7", iso: "lo", englishName: "lao laotian", dialects: [{ code: "lo-LA", region: "Laos" }] },
1557
+ { name: "Nederlands", iso: "nl", englishName: "dutch", dialects: [{ code: "nl-NL", region: "Netherlands" }] },
1558
+ { name: "\u0928\u0947\u092A\u093E\u0932\u0940 \u092D\u093E\u0937\u093E", iso: "ne", englishName: "nepali", dialects: [{ code: "ne-NP", region: "Nepal" }] },
1559
+ { name: "Norsk bokm\xE5l", iso: "nb", englishName: "norwegian bokmal", dialects: [{ code: "nb-NO", region: "Norway" }] },
1560
+ { name: "Polski", iso: "pl", englishName: "polish", dialects: [{ code: "pl-PL", region: "Poland" }] },
1561
+ {
1562
+ name: "Portugu\xEAs",
1563
+ iso: "pt",
1564
+ englishName: "portuguese",
1565
+ dialects: [
1566
+ { code: "pt-BR", region: "Brasil" },
1567
+ { code: "pt-PT", region: "Portugal" }
1568
+ ]
1569
+ },
1570
+ { name: "Rom\xE2n\u0103", iso: "ro", englishName: "romanian", dialects: [{ code: "ro-RO", region: "Romania" }] },
1571
+ { name: "\u0DC3\u0DD2\u0D82\u0DC4\u0DBD", iso: "si", englishName: "sinhala sinhalese", dialects: [{ code: "si-LK", region: "Sri Lanka" }] },
1572
+ { name: "Sloven\u0161\u010Dina", iso: "sl", englishName: "slovenian", dialects: [{ code: "sl-SI", region: "Slovenia" }] },
1573
+ { name: "Basa Sunda", iso: "su", englishName: "sundanese", dialects: [{ code: "su-ID", region: "Indonesia" }] },
1574
+ { name: "Sloven\u010Dina", iso: "sk", englishName: "slovak", dialects: [{ code: "sk-SK", region: "Slovakia" }] },
1575
+ { name: "Suomi", iso: "fi", englishName: "finnish", dialects: [{ code: "fi-FI", region: "Finland" }] },
1576
+ { name: "Svenska", iso: "sv", englishName: "swedish", dialects: [{ code: "sv-SE", region: "Sweden" }] },
1577
+ {
1578
+ name: "Kiswahili",
1579
+ iso: "sw",
1580
+ englishName: "swahili",
1581
+ dialects: [
1582
+ { code: "sw-TZ", region: "Tanzania" },
1583
+ { code: "sw-KE", region: "Kenya" }
1584
+ ]
1585
+ },
1586
+ { name: "\u10E5\u10D0\u10E0\u10D7\u10E3\u10DA\u10D8", iso: "ka", englishName: "georgian", dialects: [{ code: "ka-GE", region: "Georgia" }] },
1587
+ { name: "\u0540\u0561\u0575\u0565\u0580\u0565\u0576", iso: "hy", englishName: "armenian", dialects: [{ code: "hy-AM", region: "Armenia" }] },
1588
+ {
1589
+ name: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD",
1590
+ iso: "ta",
1591
+ englishName: "tamil",
1592
+ dialects: [
1593
+ { code: "ta-IN", region: "\u0B87\u0BA8\u0BCD\u0BA4\u0BBF\u0BAF\u0BBE" },
1594
+ { code: "ta-SG", region: "\u0B9A\u0BBF\u0B99\u0BCD\u0B95\u0BAA\u0BCD\u0BAA\u0BC2\u0BB0\u0BCD" },
1595
+ { code: "ta-LK", region: "\u0B87\u0BB2\u0B99\u0BCD\u0B95\u0BC8" },
1596
+ { code: "ta-MY", region: "\u0BAE\u0BB2\u0BC7\u0B9A\u0BBF\u0BAF\u0BBE" }
1597
+ ]
1598
+ },
1599
+ { name: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41", iso: "te", englishName: "telugu", dialects: [{ code: "te-IN", region: "India" }] },
1600
+ { name: "Ti\u1EBFng Vi\u1EC7t", iso: "vi", englishName: "vietnamese", dialects: [{ code: "vi-VN", region: "Vietnam" }] },
1601
+ { name: "T\xFCrk\xE7e", iso: "tr", englishName: "turkish", dialects: [{ code: "tr-TR", region: "T\xFCrkiye" }] },
1602
+ {
1603
+ name: "\u0627\u064F\u0631\u062F\u064F\u0648",
1604
+ iso: "ur",
1605
+ englishName: "urdu",
1606
+ dialects: [
1607
+ { code: "ur-PK", region: "\u067E\u0627\u06A9\u0633\u062A\u0627\u0646" },
1608
+ { code: "ur-IN", region: "\u0628\u06BE\u0627\u0631\u062A" }
1609
+ ]
1610
+ },
1611
+ { name: "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC", iso: "el", englishName: "greek", dialects: [{ code: "el-GR", region: "Greece" }] },
1612
+ { name: "\u0431\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438", iso: "bg", englishName: "bulgarian", dialects: [{ code: "bg-BG", region: "Bulgaria" }] },
1613
+ { name: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439", iso: "ru", englishName: "russian", dialects: [{ code: "ru-RU", region: "Russia" }] },
1614
+ { name: "\u0421\u0440\u043F\u0441\u043A\u0438", iso: "sr", englishName: "serbian", dialects: [{ code: "sr-RS", region: "Serbia" }] },
1615
+ { name: "\u0423\u043A\u0440\u0430\u0457\u043D\u0441\u044C\u043A\u0430", iso: "uk", englishName: "ukrainian", dialects: [{ code: "uk-UA", region: "Ukraine" }] },
1616
+ { name: "\uD55C\uAD6D\uC5B4", iso: "ko", englishName: "korean", dialects: [{ code: "ko-KR", region: "Korea" }] },
1617
+ {
1618
+ name: "\u4E2D\u6587",
1619
+ iso: "cmn",
1620
+ englishName: "chinese mandarin cantonese",
1621
+ dialects: [
1622
+ { code: "cmn-Hans-CN", region: "\u666E\u901A\u8BDD (\u4E2D\u56FD\u5927\u9646)" },
1623
+ { code: "cmn-Hans-HK", region: "\u666E\u901A\u8BDD (\u9999\u6E2F)" },
1624
+ { code: "cmn-Hant-TW", region: "\u4E2D\u6587 (\u53F0\u7063)" },
1625
+ { code: "yue-Hant-HK", region: "\u7CB5\u8A9E (\u9999\u6E2F)" }
1626
+ ]
1627
+ },
1628
+ { name: "\u65E5\u672C\u8A9E", iso: "ja", englishName: "japanese", dialects: [{ code: "ja-JP", region: "Japan" }] },
1629
+ { name: "\u0939\u093F\u0928\u094D\u0926\u0940", iso: "hi", englishName: "hindi", dialects: [{ code: "hi-IN", region: "India" }] },
1630
+ { name: "\u0E20\u0E32\u0E29\u0E32\u0E44\u0E17\u0E22", iso: "th", englishName: "thai", dialects: [{ code: "th-TH", region: "Thailand" }] }
1631
+ ];
1632
+ WEB_SPEECH_LANGUAGES.flatMap(
1633
+ (l) => l.dialects.map((d) => d.code)
1634
+ );
1635
+ function findSpeechLanguage(tag) {
1636
+ if (!tag) return null;
1637
+ const lower = tag.toLowerCase();
1638
+ for (const language of WEB_SPEECH_LANGUAGES) {
1639
+ for (const dialect of language.dialects) {
1640
+ if (dialect.code.toLowerCase() === lower) return { language, dialect };
1641
+ }
1642
+ }
1643
+ return null;
1644
+ }
1645
+ chunkOLISEQHS_cjs.__name(findSpeechLanguage, "findSpeechLanguage");
1646
+ function countryFromTag(tag) {
1647
+ if (!tag) return null;
1648
+ const parts = tag.split("-");
1649
+ for (let i = parts.length - 1; i >= 0; i -= 1) {
1650
+ const p = parts[i];
1651
+ if (p.length === 2 && /^[A-Za-z]{2}$/.test(p)) return p.toUpperCase();
1652
+ }
1653
+ return null;
1654
+ }
1655
+ chunkOLISEQHS_cjs.__name(countryFromTag, "countryFromTag");
1656
+ React.createContext(null);
1657
+ createLazyComponent(
1658
+ () => import('./DictationField-XWR5VOID.cjs').then((mod) => ({
1659
+ default: mod.DictationField
1660
+ })),
1661
+ {
1662
+ displayName: "LazyDictationField",
1663
+ fallback: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-lg border border-border/60 bg-card px-3 py-2 text-xs text-muted-foreground", children: "Loading dictation\u2026" })
1664
+ }
1665
+ );
1666
+ function ChatHeaderLanguageButton({
1667
+ ariaLabel = "Speech language",
1668
+ allowedTags,
1669
+ hideFallbackIcon,
1670
+ className
1671
+ }) {
1672
+ const prefs = chunk4PFW7MIJ_cjs.useSpeechPrefs();
1673
+ const active = chunk4PFW7MIJ_cjs.useResolvedLanguage();
1674
+ const options = React.useMemo(() => {
1675
+ const allow = allowedTags ? new Set(allowedTags) : null;
1676
+ const out = [];
1677
+ for (const lang of WEB_SPEECH_LANGUAGES) {
1678
+ for (const d of lang.dialects) {
1679
+ if (allow && !allow.has(d.code)) continue;
1680
+ out.push({
1681
+ value: d.code,
1682
+ // "Русский" / "Español — Argentina" / "English — United States"
1683
+ label: lang.dialects.length === 1 ? lang.name : `${lang.name} \u2014 ${d.region}`,
1684
+ // Search-only index: English name, BCP-47 tag, ISO, region.
1685
+ // Lets users type "russian" / "ru-RU" / "ru" / "argentina"
1686
+ // and still find the row regardless of native script.
1687
+ description: `${lang.englishName} ${d.code} ${lang.iso} ${d.region}`.toLowerCase()
1688
+ });
1689
+ }
1690
+ }
1691
+ return out;
1692
+ }, [allowedTags]);
1693
+ return /* @__PURE__ */ jsxRuntime.jsx(
1694
+ components.Combobox,
1695
+ {
1696
+ options,
1697
+ value: prefs.language ?? active,
1698
+ onValueChange: (v) => prefs.setLanguage(v || null),
1699
+ placeholder: ariaLabel,
1700
+ searchPlaceholder: "Search language\u2026",
1701
+ filterFunction: (opt, search) => {
1702
+ const s = search.toLowerCase();
1703
+ return opt.label.toLowerCase().includes(s) || opt.value.toLowerCase().includes(s) || (opt.description?.includes(s) ?? false);
1704
+ },
1705
+ contentClassName: "w-[280px]",
1706
+ contentStyle: { zIndex: 10001 },
1707
+ renderOption: (option) => {
1708
+ const country = countryFromTag(option.value);
1709
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [
1710
+ country ? /* @__PURE__ */ jsxRuntime.jsx(
1711
+ components.Flag,
1712
+ {
1713
+ countryCode: country,
1714
+ className: "h-4 w-5 shrink-0 overflow-hidden rounded-[2px] border border-border/60 ring-1 ring-black/5"
1715
+ }
1716
+ ) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "h-4 w-4 shrink-0 text-muted-foreground", "aria-hidden": true }),
1717
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate text-sm", children: option.label })
1718
+ ] });
1719
+ },
1720
+ renderTrigger: (selected, open) => {
1721
+ const tag = selected?.value ?? active;
1722
+ const country = countryFromTag(tag);
1723
+ const found = findSpeechLanguage(tag);
1724
+ const tooltipLabel = found ? `${found.language.name}${found.language.dialects.length > 1 ? ` \u2014 ${found.dialect.region}` : ""} \xB7 ${tag}` : tag;
1725
+ return /* @__PURE__ */ jsxRuntime.jsx(
1726
+ "button",
1727
+ {
1728
+ type: "button",
1729
+ "aria-label": `${ariaLabel}: ${tooltipLabel}`,
1730
+ "aria-expanded": open,
1731
+ title: tooltipLabel,
1732
+ className: lib.cn(
1733
+ "inline-flex h-7 w-7 items-center justify-center rounded-md",
1734
+ "text-muted-foreground transition-colors",
1735
+ "hover:bg-accent hover:text-foreground",
1736
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1737
+ className
1738
+ ),
1739
+ children: country ? /* @__PURE__ */ jsxRuntime.jsx(
1740
+ components.Flag,
1741
+ {
1742
+ countryCode: country,
1743
+ className: "h-4 w-5 overflow-hidden rounded-[2px] border border-border/60 ring-1 ring-black/5"
1744
+ }
1745
+ ) : hideFallbackIcon ? null : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Globe, { className: "h-3.5 w-3.5", "aria-hidden": true })
1746
+ }
1747
+ );
1748
+ }
1749
+ }
1750
+ );
1751
+ }
1752
+ chunkOLISEQHS_cjs.__name(ChatHeaderLanguageButton, "ChatHeaderLanguageButton");
1753
+ function anchorStyle(position, fabOffset, fabClearance) {
1754
+ const [vert, horiz] = position.split("-");
1755
+ return { [vert]: fabClearance, [horiz]: fabOffset };
1756
+ }
1757
+ chunkOLISEQHS_cjs.__name(anchorStyle, "anchorStyle");
1758
+ function originClass(position) {
1759
+ if (position === "bottom-right") return "origin-bottom-right";
1760
+ if (position === "bottom-left") return "origin-bottom-left";
1761
+ if (position === "top-right") return "origin-top-right";
1762
+ return "origin-top-left";
1763
+ }
1764
+ chunkOLISEQHS_cjs.__name(originClass, "originClass");
1765
+ function ChatGreeting({
1766
+ open,
1767
+ children,
1768
+ onClick,
1769
+ onDismiss,
1770
+ position = "bottom-right",
1771
+ fabOffset = 24,
1772
+ fabClearance = 96,
1773
+ delayMs = 1500,
1774
+ zIndex = 9998,
1775
+ className,
1776
+ style,
1777
+ avatar,
1778
+ senderName,
1779
+ dismissLabel = "Dismiss",
1780
+ inline = false
1781
+ }) {
1782
+ const [delayed, setDelayed] = React.useState(delayMs <= 0);
1783
+ React.useEffect(() => {
1784
+ if (!open || delayMs <= 0) return;
1785
+ const t = setTimeout(() => setDelayed(true), delayMs);
1786
+ return () => clearTimeout(t);
1787
+ }, [open, delayMs]);
1788
+ const shouldShow = open && delayed;
1789
+ const phase = useChatPresence(shouldShow, 220);
1790
+ if (phase === "hidden") return null;
1791
+ const animating = phase === "entering" || phase === "leaving";
1792
+ const clickable = !!onClick;
1793
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1794
+ "div",
1795
+ {
1796
+ role: clickable ? "button" : "status",
1797
+ "aria-live": "polite",
1798
+ tabIndex: clickable ? 0 : -1,
1799
+ onClick: clickable ? onClick : void 0,
1800
+ onKeyDown: clickable ? (e) => {
1801
+ if (e.key === "Enter" || e.key === " ") {
1802
+ e.preventDefault();
1803
+ onClick?.();
1804
+ }
1805
+ } : void 0,
1806
+ className: lib.cn(
1807
+ inline ? "relative inline-flex" : "fixed",
1808
+ "flex items-start gap-2.5 max-w-[280px]",
1809
+ "rounded-2xl border border-border bg-popover text-popover-foreground",
1810
+ "px-3.5 py-2.5 shadow-2xl transition-all duration-200 ease-out",
1811
+ clickable && "cursor-pointer hover:bg-accent/40 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1812
+ originClass(position),
1813
+ animating ? "opacity-0 scale-95 translate-y-1" : "opacity-100 scale-100 translate-y-0",
1814
+ className
1815
+ ),
1816
+ style: {
1817
+ ...inline ? {} : anchorStyle(position, fabOffset, fabClearance),
1818
+ ...inline ? {} : { zIndex },
1819
+ pointerEvents: phase === "visible" ? "auto" : "none",
1820
+ ...style
1821
+ },
1822
+ children: [
1823
+ avatar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 shrink-0", children: avatar }),
1824
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 text-sm leading-snug", children: [
1825
+ senderName && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-0.5 text-[11px] font-medium text-muted-foreground", children: senderName }),
1826
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-foreground", children })
1827
+ ] }),
1828
+ onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
1829
+ "button",
1830
+ {
1831
+ type: "button",
1832
+ "aria-label": dismissLabel,
1833
+ onClick: (e) => {
1834
+ e.stopPropagation();
1835
+ onDismiss();
1836
+ },
1837
+ className: lib.cn(
1838
+ "-mr-1 -mt-1 flex h-6 w-6 shrink-0 items-center justify-center rounded-full",
1839
+ "text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
1840
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
1841
+ ),
1842
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
1843
+ }
1844
+ )
1845
+ ]
1846
+ }
1847
+ );
1848
+ }
1849
+ chunkOLISEQHS_cjs.__name(ChatGreeting, "ChatGreeting");
1850
+ var TIME_FORMAT = new Intl.DateTimeFormat(void 0, {
1851
+ hour: "2-digit",
1852
+ minute: "2-digit"
1853
+ });
1854
+ function anchorStyle2(position, fabOffset, fabClearance) {
1855
+ const [vert, horiz] = position.split("-");
1856
+ return { [vert]: fabClearance, [horiz]: fabOffset };
1857
+ }
1858
+ chunkOLISEQHS_cjs.__name(anchorStyle2, "anchorStyle");
1859
+ function originClass2(position) {
1860
+ if (position === "bottom-right") return "origin-bottom-right";
1861
+ if (position === "bottom-left") return "origin-bottom-left";
1862
+ if (position === "top-right") return "origin-top-right";
1863
+ return "origin-top-left";
1864
+ }
1865
+ chunkOLISEQHS_cjs.__name(originClass2, "originClass");
1866
+ function deriveAvatar(persona, name) {
1867
+ const initials = persona?.initials ?? (name ?? persona?.name ?? "?").split(/\s+/).map((p) => p[0]).filter(Boolean).slice(0, 2).join("").toUpperCase();
1868
+ return /* @__PURE__ */ jsxRuntime.jsxs(components.Avatar, { className: "h-9 w-9", children: [
1869
+ persona?.avatarUrl ? /* @__PURE__ */ jsxRuntime.jsx(components.AvatarImage, { src: persona.avatarUrl }) : null,
1870
+ /* @__PURE__ */ jsxRuntime.jsx(components.AvatarFallback, { children: initials || "?" })
1871
+ ] });
1872
+ }
1873
+ chunkOLISEQHS_cjs.__name(deriveAvatar, "deriveAvatar");
1874
+ function ChatUnreadPreview({
1875
+ open,
1876
+ message,
1877
+ onClick,
1878
+ onDismiss,
1879
+ position = "bottom-right",
1880
+ fabOffset = 24,
1881
+ fabClearance = 96,
1882
+ truncate = 2,
1883
+ zIndex = 9998,
1884
+ inline = false,
1885
+ className,
1886
+ style,
1887
+ dismissLabel = "Mark as read",
1888
+ avatar,
1889
+ senderName
1890
+ }) {
1891
+ const shouldShow = open && !!message;
1892
+ const phase = useChatPresence(shouldShow, 200);
1893
+ if (phase === "hidden" || !message) return null;
1894
+ const animating = phase === "entering" || phase === "leaving";
1895
+ const clickable = !!onClick;
1896
+ const displayName = senderName ?? message.sender?.name ?? "New message";
1897
+ const stamp = TIME_FORMAT.format(new Date(message.createdAt));
1898
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1899
+ "div",
1900
+ {
1901
+ role: clickable ? "button" : "status",
1902
+ "aria-live": "polite",
1903
+ tabIndex: clickable ? 0 : -1,
1904
+ onClick: clickable ? onClick : void 0,
1905
+ onKeyDown: clickable ? (e) => {
1906
+ if (e.key === "Enter" || e.key === " ") {
1907
+ e.preventDefault();
1908
+ onClick?.();
1909
+ }
1910
+ } : void 0,
1911
+ className: lib.cn(
1912
+ inline ? "relative inline-flex" : "fixed",
1913
+ "flex items-start gap-2.5 max-w-[300px]",
1914
+ "rounded-2xl border border-border bg-popover text-popover-foreground",
1915
+ "px-3.5 py-2.5 shadow-2xl transition-all duration-200 ease-out",
1916
+ clickable && "cursor-pointer hover:bg-accent/40 focus:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1917
+ originClass2(position),
1918
+ animating ? "opacity-0 scale-95 translate-y-1" : "opacity-100 scale-100 translate-y-0",
1919
+ className
1920
+ ),
1921
+ style: {
1922
+ ...inline ? {} : anchorStyle2(position, fabOffset, fabClearance),
1923
+ ...inline ? {} : { zIndex },
1924
+ pointerEvents: phase === "visible" ? "auto" : "none",
1925
+ ...style
1926
+ },
1927
+ children: [
1928
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 shrink-0", children: avatar ?? deriveAvatar(message.sender, displayName) }),
1929
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 text-sm leading-snug", children: [
1930
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline justify-between gap-2", children: [
1931
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[12px] font-semibold text-foreground", children: displayName }),
1932
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0 text-[10px] text-muted-foreground", children: stamp })
1933
+ ] }),
1934
+ /* @__PURE__ */ jsxRuntime.jsx(
1935
+ "div",
1936
+ {
1937
+ className: "text-foreground/90 mt-0.5 break-words",
1938
+ style: {
1939
+ display: "-webkit-box",
1940
+ WebkitLineClamp: truncate,
1941
+ WebkitBoxOrient: "vertical",
1942
+ overflow: "hidden"
1943
+ },
1944
+ children: message.content
1945
+ }
1946
+ )
1947
+ ] }),
1948
+ onDismiss ? /* @__PURE__ */ jsxRuntime.jsx(
1949
+ "button",
1950
+ {
1951
+ type: "button",
1952
+ "aria-label": dismissLabel,
1953
+ onClick: (e) => {
1954
+ e.stopPropagation();
1955
+ onDismiss();
1956
+ },
1957
+ className: lib.cn(
1958
+ "-mr-1 -mt-1 flex h-6 w-6 shrink-0 items-center justify-center rounded-full",
1959
+ "text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
1960
+ "focus:outline-none focus-visible:ring-2 focus-visible:ring-ring"
1961
+ ),
1962
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-3.5 w-3.5" })
1963
+ }
1964
+ ) : null
1965
+ ]
1966
+ }
1967
+ );
1968
+ }
1969
+ chunkOLISEQHS_cjs.__name(ChatUnreadPreview, "ChatUnreadPreview");
1970
+ function readDismissed(storageKey) {
1971
+ if (!storageKey) return false;
1972
+ if (typeof window === "undefined") return false;
1973
+ try {
1974
+ return window.localStorage.getItem(storageKey) === "1";
1975
+ } catch {
1976
+ return false;
1977
+ }
1978
+ }
1979
+ chunkOLISEQHS_cjs.__name(readDismissed, "readDismissed");
1980
+ function writeDismissed(storageKey) {
1981
+ if (!storageKey) return;
1982
+ if (typeof window === "undefined") return;
1983
+ try {
1984
+ window.localStorage.setItem(storageKey, "1");
1985
+ } catch {
1986
+ }
1987
+ }
1988
+ chunkOLISEQHS_cjs.__name(writeDismissed, "writeDismissed");
1989
+ function ChatLauncher({
1990
+ children,
1991
+ fab,
1992
+ dock,
1993
+ greeting,
1994
+ hotkey,
1995
+ defaultOpen = false,
1996
+ open: controlledOpen,
1997
+ onOpenChange,
1998
+ autoFocusComposerOnOpen = true,
1999
+ closeOnEscape = true,
2000
+ unreadMessage,
2001
+ onMarkRead,
2002
+ unreadPreview,
2003
+ audio,
2004
+ hideAudioToggle = false
2005
+ }) {
2006
+ const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
2007
+ const isControlled = controlledOpen !== void 0;
2008
+ const open = isControlled ? controlledOpen : uncontrolledOpen;
2009
+ const dockContentRef = React.useRef(null);
2010
+ React.useEffect(() => {
2011
+ if (!autoFocusComposerOnOpen || !open) return;
2012
+ const t = setTimeout(() => {
2013
+ const root = dockContentRef.current;
2014
+ if (!root) return;
2015
+ const target = root.querySelector(
2016
+ 'textarea:not([disabled]):not([readonly]), input[type="text"]:not([disabled]):not([readonly])'
2017
+ );
2018
+ target?.focus();
2019
+ }, 120);
2020
+ return () => clearTimeout(t);
2021
+ }, [open, autoFocusComposerOnOpen]);
2022
+ const setOpen = React.useCallback(
2023
+ (next) => {
2024
+ if (!isControlled) setUncontrolledOpen(next);
2025
+ onOpenChange?.(next);
2026
+ },
2027
+ [isControlled, onOpenChange]
2028
+ );
2029
+ const toggleOpen = React.useCallback(() => setOpen(!open), [open, setOpen]);
2030
+ hooks.useHotkey(
2031
+ "escape",
2032
+ (e) => {
2033
+ const target = e?.target ?? null;
2034
+ const inEditable = !!target && (target.matches?.('input, textarea, [contenteditable="true"]') ?? false);
2035
+ if (inEditable) {
2036
+ target.blur();
2037
+ return;
2038
+ }
2039
+ setOpen(false);
2040
+ },
2041
+ { enabled: closeOnEscape && open }
2042
+ );
2043
+ const greetingConfig = greeting === void 0 ? null : typeof greeting === "string" ? { content: greeting } : greeting;
2044
+ const [dismissed, setDismissed] = React.useState(
2045
+ () => readDismissed(greetingConfig?.dismissStorageKey)
2046
+ );
2047
+ React.useEffect(() => {
2048
+ if (!hotkey) return;
2049
+ const handler = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((e) => {
2050
+ const metaOk = hotkey.meta ? e.metaKey || e.ctrlKey : !e.metaKey && !e.ctrlKey;
2051
+ const shiftOk = hotkey.shift ? e.shiftKey : !e.shiftKey;
2052
+ const altOk = hotkey.alt ? e.altKey : !e.altKey;
2053
+ if (!metaOk || !shiftOk || !altOk) return;
2054
+ if (e.key !== hotkey.key) return;
2055
+ e.preventDefault();
2056
+ setOpen(!open);
2057
+ }, "handler");
2058
+ window.addEventListener("keydown", handler);
2059
+ return () => window.removeEventListener("keydown", handler);
2060
+ }, [hotkey?.key, hotkey?.meta, hotkey?.shift, hotkey?.alt, open, setOpen, hotkey]);
2061
+ const greetingOpen = !!greetingConfig && !dismissed && (greetingConfig.hideOnOpen === false || !open);
2062
+ const fabPosition = fab?.position ?? "bottom-right";
2063
+ const fabOffset = fab?.offset ?? 24;
2064
+ const handleGreetingDismiss = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
2065
+ setDismissed(true);
2066
+ writeDismissed(greetingConfig?.dismissStorageKey);
2067
+ }, "handleGreetingDismiss");
2068
+ const handleGreetingClick = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
2069
+ setOpen(true);
2070
+ setDismissed(true);
2071
+ writeDismissed(greetingConfig?.dismissStorageKey);
2072
+ }, "handleGreetingClick");
2073
+ React.useEffect(() => {
2074
+ if (open && unreadMessage) onMarkRead?.();
2075
+ }, [open, unreadMessage, onMarkRead]);
2076
+ const unreadOpen = !open && !!unreadMessage;
2077
+ const handleUnreadClick = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
2078
+ setOpen(true);
2079
+ onMarkRead?.();
2080
+ }, "handleUnreadClick");
2081
+ const handleUnreadDismiss = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
2082
+ onMarkRead?.();
2083
+ }, "handleUnreadDismiss");
2084
+ const resolvedFab = unreadMessage && fab?.badge === void 0 ? { ...fab, badge: 1 } : fab;
2085
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2086
+ /* @__PURE__ */ jsxRuntime.jsx(ChatFAB, { ...resolvedFab, onClick: toggleOpen }),
2087
+ unreadMessage ? /* @__PURE__ */ jsxRuntime.jsx(
2088
+ ChatUnreadPreview,
2089
+ {
2090
+ ...unreadPreview,
2091
+ open: unreadOpen,
2092
+ message: unreadMessage,
2093
+ onClick: handleUnreadClick,
2094
+ onDismiss: handleUnreadDismiss,
2095
+ position: fabPosition,
2096
+ fabOffset
2097
+ }
2098
+ ) : greetingConfig ? /* @__PURE__ */ jsxRuntime.jsx(
2099
+ ChatGreeting,
2100
+ {
2101
+ ...greetingConfig,
2102
+ open: greetingOpen,
2103
+ onClick: handleGreetingClick,
2104
+ onDismiss: handleGreetingDismiss,
2105
+ position: fabPosition,
2106
+ fabOffset,
2107
+ children: greetingConfig.content
2108
+ }
2109
+ ) : null,
2110
+ /* @__PURE__ */ jsxRuntime.jsx(
2111
+ ChatDock,
2112
+ {
2113
+ ...dock,
2114
+ open,
2115
+ onClose: () => setOpen(false),
2116
+ headerActions: audio && !audio.isSilent && !hideAudioToggle || dock?.headerActions ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2117
+ dock?.headerActions,
2118
+ audio && !audio.isSilent && !hideAudioToggle ? /* @__PURE__ */ jsxRuntime.jsx(ChatHeaderAudioToggle, { muted: audio.muted, onToggle: audio.toggleMute }) : null
2119
+ ] }) : void 0,
2120
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: dockContentRef, className: "flex h-full min-h-0 min-w-0 flex-col", children })
2121
+ }
2122
+ )
2123
+ ] });
2124
+ }
2125
+ chunkOLISEQHS_cjs.__name(ChatLauncher, "ChatLauncher");
679
2126
  function useChatScroll(options) {
680
2127
  const {
681
2128
  containerRef,
@@ -819,42 +2266,88 @@ function useChatLightbox() {
819
2266
  return { state, open, close };
820
2267
  }
821
2268
  chunkOLISEQHS_cjs.__name(useChatLightbox, "useChatLightbox");
822
- function useAutoFocusOnStreamEnd(options = {}) {
823
- const { isStreaming: isStreamingProp, targetRef, enabled = true, delayMs = 0 } = options;
824
- const ctx = chunkSI5RD2GD_cjs.useChatContextOptional();
825
- const isStreaming = isStreamingProp ?? ctx?.isStreaming ?? false;
826
- const composerHandleRef = React.useRef(null);
827
- composerHandleRef.current = ctx?.composer ?? null;
828
- const prevStreamingRef = React.useRef(isStreaming);
2269
+ var DEFAULT_STORAGE_KEY = "chat.visitor.fingerprint";
2270
+ function generate() {
2271
+ if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
2272
+ return crypto.randomUUID();
2273
+ }
2274
+ return `v-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
2275
+ }
2276
+ chunkOLISEQHS_cjs.__name(generate, "generate");
2277
+ function useVisitorFingerprint(opts = {}) {
2278
+ const storageKey = opts.storageKey ?? DEFAULT_STORAGE_KEY;
2279
+ const [fp, setFp] = React.useState(null);
829
2280
  React.useEffect(() => {
830
- const wasStreaming = prevStreamingRef.current;
831
- prevStreamingRef.current = isStreaming;
832
- if (!enabled) return;
833
- if (!(wasStreaming && !isStreaming)) return;
834
- const focusNow = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
835
- const explicit = targetRef?.current;
836
- const target = explicit ?? composerHandleRef.current;
837
- target?.focus();
838
- }, "focusNow");
839
- if (delayMs > 0) {
840
- const id = window.setTimeout(focusNow, delayMs);
841
- return () => window.clearTimeout(id);
2281
+ let value = null;
2282
+ try {
2283
+ value = window.localStorage.getItem(storageKey);
2284
+ if (!value) {
2285
+ value = generate();
2286
+ window.localStorage.setItem(storageKey, value);
2287
+ }
2288
+ } catch {
2289
+ value = generate();
842
2290
  }
843
- const raf = requestAnimationFrame(focusNow);
844
- return () => cancelAnimationFrame(raf);
845
- }, [isStreaming, enabled, delayMs, targetRef]);
846
- }
847
- chunkOLISEQHS_cjs.__name(useAutoFocusOnStreamEnd, "useAutoFocusOnStreamEnd");
848
- function useRegisterComposer(focus) {
849
- const ctx = chunkSI5RD2GD_cjs.useChatContextOptional();
850
- const register = ctx?.registerComposer;
2291
+ setFp(value);
2292
+ }, [storageKey]);
2293
+ return fp;
2294
+ }
2295
+ chunkOLISEQHS_cjs.__name(useVisitorFingerprint, "useVisitorFingerprint");
2296
+ var DEFAULT_DOCK_PREFS = {
2297
+ mode: "popover",
2298
+ side: "right",
2299
+ sideWidth: 420
2300
+ };
2301
+ var DEFAULT_KEY = "chat.dock.prefs";
2302
+ function useChatDockPrefs(opts = {}) {
2303
+ const key = opts.storageKey ?? DEFAULT_KEY;
2304
+ const initial = { ...DEFAULT_DOCK_PREFS, ...opts.defaults };
2305
+ const [prefs, setStored] = hooks.useLocalStorage(key, initial);
2306
+ const setPrefs = React.useCallback(
2307
+ (patch) => {
2308
+ setStored((prev) => ({ ...prev, ...patch }));
2309
+ },
2310
+ [setStored]
2311
+ );
2312
+ const toggleMode = React.useCallback(() => {
2313
+ setStored((prev) => ({ ...prev, mode: prev.mode === "side" ? "popover" : "side" }));
2314
+ }, [setStored]);
2315
+ const toggleSide = React.useCallback(() => {
2316
+ setStored((prev) => ({ ...prev, side: prev.side === "right" ? "left" : "right" }));
2317
+ }, [setStored]);
2318
+ const reset = React.useCallback(() => setStored(initial), [setStored, initial]);
2319
+ return { ...prefs, setPrefs, toggleMode, toggleSide, reset };
2320
+ }
2321
+ chunkOLISEQHS_cjs.__name(useChatDockPrefs, "useChatDockPrefs");
2322
+ function useChatUnread(opts = {}) {
2323
+ const { open = false, countRoles = ["assistant"] } = opts;
2324
+ const ctx = chunkOZAU3QWD_cjs.useChatContext();
2325
+ const [lastSeenId, setLastSeenId] = React.useState(null);
2326
+ const initialized = React.useRef(false);
851
2327
  React.useEffect(() => {
852
- if (!register) return;
853
- register({ focus });
854
- return () => register(null);
855
- }, [register, focus]);
2328
+ if (initialized.current) return;
2329
+ initialized.current = true;
2330
+ const tail = ctx.messages[ctx.messages.length - 1];
2331
+ setLastSeenId(tail?.id ?? null);
2332
+ }, [ctx.messages]);
2333
+ React.useEffect(() => {
2334
+ if (!open) return;
2335
+ const tail = ctx.messages[ctx.messages.length - 1];
2336
+ setLastSeenId(tail?.id ?? null);
2337
+ }, [open, ctx.messages]);
2338
+ const seenIdx = lastSeenId ? ctx.messages.findIndex((m) => m.id === lastSeenId) : -1;
2339
+ const after = seenIdx === -1 ? ctx.messages : ctx.messages.slice(seenIdx + 1);
2340
+ const inbound = after.filter((m) => countRoles.includes(m.role));
2341
+ const unread = inbound.length > 0 ? inbound[inbound.length - 1] : null;
2342
+ const markRead = React.useCallback(() => {
2343
+ const tail = ctx.messages[ctx.messages.length - 1];
2344
+ setLastSeenId(tail?.id ?? null);
2345
+ }, [ctx.messages]);
2346
+ return { unread, count: inbound.length, markRead };
856
2347
  }
857
- chunkOLISEQHS_cjs.__name(useRegisterComposer, "useRegisterComposer");
2348
+ chunkOLISEQHS_cjs.__name(useChatUnread, "useChatUnread");
2349
+ var STORAGE_KEY = "djangocfg-chat-audio:prefs";
2350
+ var useChatAudioPrefs = hooks.createAudioPrefsStore(STORAGE_KEY);
858
2351
 
859
2352
  // src/tools/Chat/core/payload-dispatch.ts
860
2353
  function dispatchToolPayload(matchers, fallback) {
@@ -901,9 +2394,9 @@ function AudioToggle({
901
2394
  alwaysShow = false,
902
2395
  className
903
2396
  }) {
904
- const muted = chunkSI5RD2GD_cjs.useChatAudioPrefs((s) => s.muted);
905
- const setMuted = chunkSI5RD2GD_cjs.useChatAudioPrefs((s) => s.setMuted);
906
- const ctx = chunkSI5RD2GD_cjs.useChatContextOptional();
2397
+ const muted = useChatAudioPrefs((s) => s.muted);
2398
+ const setMuted = useChatAudioPrefs((s) => s.setMuted);
2399
+ const ctx = chunkOZAU3QWD_cjs.useChatContextOptional();
907
2400
  if (ctx && !ctx.hasAudio && !alwaysShow) return null;
908
2401
  const Icon = muted ? lucideReact.VolumeX : lucideReact.Volume2;
909
2402
  const label = muted ? "Unmute chat sounds" : "Mute chat sounds";
@@ -935,7 +2428,7 @@ function LottiePlayer(props) {
935
2428
  }
936
2429
  chunkOLISEQHS_cjs.__name(LottiePlayer, "LottiePlayer");
937
2430
  var DocsLayout = React.lazy(
938
- () => import('./DocsLayout-Q4KS3QWW.cjs').then((mod) => ({ default: mod.DocsLayout }))
2431
+ () => import('./DocsLayout-2YZNS5VK.cjs').then((mod) => ({ default: mod.DocsLayout }))
939
2432
  );
940
2433
  var LoadingFallback6 = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center min-h-[400px]", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground", children: "Loading API Playground..." }) }), "LoadingFallback");
941
2434
  var Playground = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(({ config }) => {
@@ -1874,7 +3367,7 @@ function extractMentionIds(editor) {
1874
3367
  return [...new Set(ids)];
1875
3368
  }
1876
3369
  chunkOLISEQHS_cjs.__name(extractMentionIds, "extractMentionIds");
1877
- function MarkdownEditor({
3370
+ var MarkdownEditor = React.forwardRef(/* @__PURE__ */ chunkOLISEQHS_cjs.__name(function MarkdownEditor2({
1878
3371
  value,
1879
3372
  onChange,
1880
3373
  placeholder = "Write markdown...",
@@ -1885,7 +3378,7 @@ function MarkdownEditor({
1885
3378
  mentions,
1886
3379
  onMentionIdsChange,
1887
3380
  onSubmit
1888
- }) {
3381
+ }, ref) {
1889
3382
  const onSubmitRef = React.useRef(onSubmit);
1890
3383
  onSubmitRef.current = onSubmit;
1891
3384
  const isExternalUpdate = React.useRef(false);
@@ -1965,13 +3458,25 @@ function MarkdownEditor({
1965
3458
  isExternalUpdate.current = false;
1966
3459
  }
1967
3460
  }, [value, editor]);
3461
+ React.useImperativeHandle(
3462
+ ref,
3463
+ () => ({
3464
+ focus: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
3465
+ editor?.commands.focus();
3466
+ }, "focus"),
3467
+ moveCursorToEnd: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => {
3468
+ editor?.commands.focus("end");
3469
+ }, "moveCursorToEnd"),
3470
+ getEditor: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => editor ?? null, "getEditor")
3471
+ }),
3472
+ [editor]
3473
+ );
1968
3474
  const wrapperClass = `markdown-editor rounded-md border border-input bg-background ${disabled ? "opacity-60" : ""} ${className}`.trim();
1969
3475
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClass, children: [
1970
3476
  showToolbar && editor && /* @__PURE__ */ jsxRuntime.jsx(MarkdownToolbar, { editor }),
1971
3477
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-2", children: /* @__PURE__ */ jsxRuntime.jsx(react.EditorContent, { editor }) })
1972
3478
  ] });
1973
- }
1974
- chunkOLISEQHS_cjs.__name(MarkdownEditor, "MarkdownEditor");
3479
+ }, "MarkdownEditor"));
1975
3480
  function MarkdownToolbar({ editor }) {
1976
3481
  const items = React.useMemo(() => [
1977
3482
  { icon: lucideReact.Bold, title: "Bold", action: /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => editor.chain().focus().toggleBold().run(), "action"), active: editor.isActive("bold") },
@@ -2259,159 +3764,183 @@ Object.defineProperty(exports, "useCronWeekDays", {
2259
3764
  });
2260
3765
  Object.defineProperty(exports, "Attachments", {
2261
3766
  enumerable: true,
2262
- get: function () { return chunkSI5RD2GD_cjs.Attachments; }
3767
+ get: function () { return chunkOZAU3QWD_cjs.Attachments; }
2263
3768
  });
2264
3769
  Object.defineProperty(exports, "AttachmentsGrid", {
2265
3770
  enumerable: true,
2266
- get: function () { return chunkSI5RD2GD_cjs.AttachmentsGrid; }
3771
+ get: function () { return chunkOZAU3QWD_cjs.AttachmentsGrid; }
2267
3772
  });
2268
3773
  Object.defineProperty(exports, "AttachmentsList", {
2269
3774
  enumerable: true,
2270
- get: function () { return chunkSI5RD2GD_cjs.AttachmentsList; }
3775
+ get: function () { return chunkOZAU3QWD_cjs.AttachmentsList; }
2271
3776
  });
2272
3777
  Object.defineProperty(exports, "CHAT_EVENT_NAME", {
2273
3778
  enumerable: true,
2274
- get: function () { return chunkSI5RD2GD_cjs.CHAT_EVENT_NAME; }
3779
+ get: function () { return chunkOZAU3QWD_cjs.CHAT_EVENT_NAME; }
2275
3780
  });
2276
3781
  Object.defineProperty(exports, "CSS_VARS", {
2277
3782
  enumerable: true,
2278
- get: function () { return chunkSI5RD2GD_cjs.CSS_VARS; }
3783
+ get: function () { return chunkOZAU3QWD_cjs.CSS_VARS; }
2279
3784
  });
2280
3785
  Object.defineProperty(exports, "ChatProvider", {
2281
3786
  enumerable: true,
2282
- get: function () { return chunkSI5RD2GD_cjs.ChatProvider; }
3787
+ get: function () { return chunkOZAU3QWD_cjs.ChatProvider; }
2283
3788
  });
2284
3789
  Object.defineProperty(exports, "ChatRoot", {
2285
3790
  enumerable: true,
2286
- get: function () { return chunkSI5RD2GD_cjs.ChatRoot; }
3791
+ get: function () { return chunkOZAU3QWD_cjs.ChatRoot; }
2287
3792
  });
2288
3793
  Object.defineProperty(exports, "Composer", {
2289
3794
  enumerable: true,
2290
- get: function () { return chunkSI5RD2GD_cjs.Composer; }
3795
+ get: function () { return chunkOZAU3QWD_cjs.Composer; }
3796
+ });
3797
+ Object.defineProperty(exports, "DEFAULT_CHAT_SOUNDS", {
3798
+ enumerable: true,
3799
+ get: function () { return chunkOZAU3QWD_cjs.DEFAULT_CHAT_SOUNDS; }
2291
3800
  });
2292
3801
  Object.defineProperty(exports, "DEFAULT_LABELS", {
2293
3802
  enumerable: true,
2294
- get: function () { return chunkSI5RD2GD_cjs.DEFAULT_LABELS; }
3803
+ get: function () { return chunkOZAU3QWD_cjs.DEFAULT_LABELS; }
2295
3804
  });
2296
3805
  Object.defineProperty(exports, "DEFAULT_SIDEBAR", {
2297
3806
  enumerable: true,
2298
- get: function () { return chunkSI5RD2GD_cjs.DEFAULT_SIDEBAR; }
3807
+ get: function () { return chunkOZAU3QWD_cjs.DEFAULT_SIDEBAR; }
2299
3808
  });
2300
3809
  Object.defineProperty(exports, "DEFAULT_Z_INDEX", {
2301
3810
  enumerable: true,
2302
- get: function () { return chunkSI5RD2GD_cjs.DEFAULT_Z_INDEX; }
3811
+ get: function () { return chunkOZAU3QWD_cjs.DEFAULT_Z_INDEX; }
2303
3812
  });
2304
3813
  Object.defineProperty(exports, "EmptyState", {
2305
3814
  enumerable: true,
2306
- get: function () { return chunkSI5RD2GD_cjs.EmptyState; }
3815
+ get: function () { return chunkOZAU3QWD_cjs.EmptyState; }
2307
3816
  });
2308
3817
  Object.defineProperty(exports, "ErrorBanner", {
2309
3818
  enumerable: true,
2310
- get: function () { return chunkSI5RD2GD_cjs.ErrorBanner; }
3819
+ get: function () { return chunkOZAU3QWD_cjs.ErrorBanner; }
2311
3820
  });
2312
3821
  Object.defineProperty(exports, "HOTKEYS", {
2313
3822
  enumerable: true,
2314
- get: function () { return chunkSI5RD2GD_cjs.HOTKEYS; }
3823
+ get: function () { return chunkOZAU3QWD_cjs.HOTKEYS; }
2315
3824
  });
2316
3825
  Object.defineProperty(exports, "JumpToLatest", {
2317
3826
  enumerable: true,
2318
- get: function () { return chunkSI5RD2GD_cjs.JumpToLatest; }
3827
+ get: function () { return chunkOZAU3QWD_cjs.JumpToLatest; }
2319
3828
  });
2320
3829
  Object.defineProperty(exports, "LIMITS", {
2321
3830
  enumerable: true,
2322
- get: function () { return chunkSI5RD2GD_cjs.LIMITS; }
3831
+ get: function () { return chunkOZAU3QWD_cjs.LIMITS; }
2323
3832
  });
2324
3833
  Object.defineProperty(exports, "MessageActions", {
2325
3834
  enumerable: true,
2326
- get: function () { return chunkSI5RD2GD_cjs.MessageActions; }
3835
+ get: function () { return chunkOZAU3QWD_cjs.MessageActions; }
2327
3836
  });
2328
3837
  Object.defineProperty(exports, "MessageBubble", {
2329
3838
  enumerable: true,
2330
- get: function () { return chunkSI5RD2GD_cjs.MessageBubble; }
3839
+ get: function () { return chunkOZAU3QWD_cjs.MessageBubble; }
2331
3840
  });
2332
3841
  Object.defineProperty(exports, "MessageList", {
2333
3842
  enumerable: true,
2334
- get: function () { return chunkSI5RD2GD_cjs.MessageList; }
3843
+ get: function () { return chunkOZAU3QWD_cjs.MessageList; }
2335
3844
  });
2336
3845
  Object.defineProperty(exports, "STORAGE_KEYS", {
2337
3846
  enumerable: true,
2338
- get: function () { return chunkSI5RD2GD_cjs.STORAGE_KEYS; }
3847
+ get: function () { return chunkOZAU3QWD_cjs.STORAGE_KEYS; }
2339
3848
  });
2340
3849
  Object.defineProperty(exports, "Sources", {
2341
3850
  enumerable: true,
2342
- get: function () { return chunkSI5RD2GD_cjs.Sources; }
3851
+ get: function () { return chunkOZAU3QWD_cjs.Sources; }
2343
3852
  });
2344
3853
  Object.defineProperty(exports, "StreamingIndicator", {
2345
3854
  enumerable: true,
2346
- get: function () { return chunkSI5RD2GD_cjs.StreamingIndicator; }
3855
+ get: function () { return chunkOZAU3QWD_cjs.StreamingIndicator; }
2347
3856
  });
2348
3857
  Object.defineProperty(exports, "ToolCalls", {
2349
3858
  enumerable: true,
2350
- get: function () { return chunkSI5RD2GD_cjs.ToolCalls; }
3859
+ get: function () { return chunkOZAU3QWD_cjs.ToolCalls; }
2351
3860
  });
2352
3861
  Object.defineProperty(exports, "createId", {
2353
3862
  enumerable: true,
2354
- get: function () { return chunkSI5RD2GD_cjs.createId; }
3863
+ get: function () { return chunkOZAU3QWD_cjs.createId; }
2355
3864
  });
2356
3865
  Object.defineProperty(exports, "createTokenBuffer", {
2357
3866
  enumerable: true,
2358
- get: function () { return chunkSI5RD2GD_cjs.createTokenBuffer; }
3867
+ get: function () { return chunkOZAU3QWD_cjs.createTokenBuffer; }
2359
3868
  });
2360
3869
  Object.defineProperty(exports, "deriveInitials", {
2361
3870
  enumerable: true,
2362
- get: function () { return chunkSI5RD2GD_cjs.deriveInitials; }
3871
+ get: function () { return chunkOZAU3QWD_cjs.deriveInitials; }
2363
3872
  });
2364
3873
  Object.defineProperty(exports, "getChatLogger", {
2365
3874
  enumerable: true,
2366
- get: function () { return chunkSI5RD2GD_cjs.getChatLogger; }
3875
+ get: function () { return chunkOZAU3QWD_cjs.getChatLogger; }
2367
3876
  });
2368
3877
  Object.defineProperty(exports, "initialState", {
2369
3878
  enumerable: true,
2370
- get: function () { return chunkSI5RD2GD_cjs.initialState; }
3879
+ get: function () { return chunkOZAU3QWD_cjs.initialState; }
2371
3880
  });
2372
3881
  Object.defineProperty(exports, "isSubmittableDraft", {
2373
3882
  enumerable: true,
2374
- get: function () { return chunkSI5RD2GD_cjs.isSubmittableDraft; }
3883
+ get: function () { return chunkOZAU3QWD_cjs.isSubmittableDraft; }
2375
3884
  });
2376
3885
  Object.defineProperty(exports, "reducer", {
2377
3886
  enumerable: true,
2378
- get: function () { return chunkSI5RD2GD_cjs.reducer; }
3887
+ get: function () { return chunkOZAU3QWD_cjs.reducer; }
2379
3888
  });
2380
3889
  Object.defineProperty(exports, "resolvePersona", {
2381
3890
  enumerable: true,
2382
- get: function () { return chunkSI5RD2GD_cjs.resolvePersona; }
3891
+ get: function () { return chunkOZAU3QWD_cjs.resolvePersona; }
2383
3892
  });
2384
3893
  Object.defineProperty(exports, "sanitizeDraft", {
2385
3894
  enumerable: true,
2386
- get: function () { return chunkSI5RD2GD_cjs.sanitizeDraft; }
3895
+ get: function () { return chunkOZAU3QWD_cjs.sanitizeDraft; }
3896
+ });
3897
+ Object.defineProperty(exports, "useAutoFocusOnStreamEnd", {
3898
+ enumerable: true,
3899
+ get: function () { return chunkOZAU3QWD_cjs.useAutoFocusOnStreamEnd; }
2387
3900
  });
2388
3901
  Object.defineProperty(exports, "useChat", {
2389
3902
  enumerable: true,
2390
- get: function () { return chunkSI5RD2GD_cjs.useChat; }
3903
+ get: function () { return chunkOZAU3QWD_cjs.useChat; }
2391
3904
  });
2392
3905
  Object.defineProperty(exports, "useChatAudio", {
2393
3906
  enumerable: true,
2394
- get: function () { return chunkSI5RD2GD_cjs.useChatAudio; }
3907
+ get: function () { return chunkOZAU3QWD_cjs.useChatAudio; }
2395
3908
  });
2396
- Object.defineProperty(exports, "useChatAudioPrefs", {
3909
+ Object.defineProperty(exports, "useChatBubbleStyles", {
2397
3910
  enumerable: true,
2398
- get: function () { return chunkSI5RD2GD_cjs.useChatAudioPrefs; }
3911
+ get: function () { return chunkOZAU3QWD_cjs.useChatBubbleStyles; }
2399
3912
  });
2400
3913
  Object.defineProperty(exports, "useChatComposer", {
2401
3914
  enumerable: true,
2402
- get: function () { return chunkSI5RD2GD_cjs.useChatComposer; }
3915
+ get: function () { return chunkOZAU3QWD_cjs.useChatComposer; }
2403
3916
  });
2404
3917
  Object.defineProperty(exports, "useChatContext", {
2405
3918
  enumerable: true,
2406
- get: function () { return chunkSI5RD2GD_cjs.useChatContext; }
3919
+ get: function () { return chunkOZAU3QWD_cjs.useChatContext; }
2407
3920
  });
2408
3921
  Object.defineProperty(exports, "useChatContextOptional", {
2409
3922
  enumerable: true,
2410
- get: function () { return chunkSI5RD2GD_cjs.useChatContextOptional; }
3923
+ get: function () { return chunkOZAU3QWD_cjs.useChatContextOptional; }
3924
+ });
3925
+ Object.defineProperty(exports, "useChatDestructiveStyles", {
3926
+ enumerable: true,
3927
+ get: function () { return chunkOZAU3QWD_cjs.useChatDestructiveStyles; }
2411
3928
  });
2412
3929
  Object.defineProperty(exports, "useChatLayout", {
2413
3930
  enumerable: true,
2414
- get: function () { return chunkSI5RD2GD_cjs.useChatLayout; }
3931
+ get: function () { return chunkOZAU3QWD_cjs.useChatLayout; }
3932
+ });
3933
+ Object.defineProperty(exports, "useChatRoleStyles", {
3934
+ enumerable: true,
3935
+ get: function () { return chunkOZAU3QWD_cjs.useChatRoleStyles; }
3936
+ });
3937
+ Object.defineProperty(exports, "useFocusOnEmptyClick", {
3938
+ enumerable: true,
3939
+ get: function () { return chunkOZAU3QWD_cjs.useFocusOnEmptyClick; }
3940
+ });
3941
+ Object.defineProperty(exports, "useRegisterComposer", {
3942
+ enumerable: true,
3943
+ get: function () { return chunkOZAU3QWD_cjs.useRegisterComposer; }
2415
3944
  });
2416
3945
  Object.defineProperty(exports, "TreeError", {
2417
3946
  enumerable: true,
@@ -2549,25 +4078,45 @@ Object.defineProperty(exports, "useTreeTypeAhead", {
2549
4078
  enumerable: true,
2550
4079
  get: function () { return chunkFVVF7VCD_cjs.useTreeTypeAhead; }
2551
4080
  });
4081
+ Object.defineProperty(exports, "ANCHOR", {
4082
+ enumerable: true,
4083
+ get: function () { return chunkFIRK5CEH_cjs.ANCHOR; }
4084
+ });
4085
+ Object.defineProperty(exports, "BUBBLE_SURFACE", {
4086
+ enumerable: true,
4087
+ get: function () { return chunkFIRK5CEH_cjs.BUBBLE_SURFACE; }
4088
+ });
4089
+ Object.defineProperty(exports, "DESTRUCTIVE_SURFACE", {
4090
+ enumerable: true,
4091
+ get: function () { return chunkFIRK5CEH_cjs.DESTRUCTIVE_SURFACE; }
4092
+ });
2552
4093
  Object.defineProperty(exports, "MarkdownMessage", {
2553
4094
  enumerable: true,
2554
- get: function () { return chunkXACCHZH2_cjs.MarkdownMessage; }
4095
+ get: function () { return chunkFIRK5CEH_cjs.MarkdownMessage; }
2555
4096
  });
2556
4097
  Object.defineProperty(exports, "Mermaid", {
2557
4098
  enumerable: true,
2558
- get: function () { return chunkXACCHZH2_cjs.Mermaid_default; }
4099
+ get: function () { return chunkFIRK5CEH_cjs.Mermaid_default; }
2559
4100
  });
2560
4101
  Object.defineProperty(exports, "PrettyCode", {
2561
4102
  enumerable: true,
2562
- get: function () { return chunkXACCHZH2_cjs.PrettyCode_default; }
4103
+ get: function () { return chunkFIRK5CEH_cjs.PrettyCode_default; }
4104
+ });
4105
+ Object.defineProperty(exports, "TOGGLE", {
4106
+ enumerable: true,
4107
+ get: function () { return chunkFIRK5CEH_cjs.TOGGLE; }
4108
+ });
4109
+ Object.defineProperty(exports, "TOOL_CALL", {
4110
+ enumerable: true,
4111
+ get: function () { return chunkFIRK5CEH_cjs.TOOL_CALL; }
2563
4112
  });
2564
4113
  Object.defineProperty(exports, "extractTextFromChildren", {
2565
4114
  enumerable: true,
2566
- get: function () { return chunkXACCHZH2_cjs.extractTextFromChildren; }
4115
+ get: function () { return chunkFIRK5CEH_cjs.extractTextFromChildren; }
2567
4116
  });
2568
4117
  Object.defineProperty(exports, "useCollapsibleContent", {
2569
4118
  enumerable: true,
2570
- get: function () { return chunkXACCHZH2_cjs.useCollapsibleContent; }
4119
+ get: function () { return chunkFIRK5CEH_cjs.useCollapsibleContent; }
2571
4120
  });
2572
4121
  Object.defineProperty(exports, "JsonTree", {
2573
4122
  enumerable: true,
@@ -2575,7 +4124,19 @@ Object.defineProperty(exports, "JsonTree", {
2575
4124
  });
2576
4125
  exports.AudioToggle = AudioToggle;
2577
4126
  exports.CardLoadingFallback = CardLoadingFallback;
4127
+ exports.ChatDock = ChatDock;
4128
+ exports.ChatFAB = ChatFAB;
4129
+ exports.ChatGreeting = ChatGreeting;
4130
+ exports.ChatHeader = ChatHeader;
4131
+ exports.ChatHeaderActionButton = ChatHeaderActionButton;
4132
+ exports.ChatHeaderAudioToggle = ChatHeaderAudioToggle;
4133
+ exports.ChatHeaderLanguageButton = ChatHeaderLanguageButton;
4134
+ exports.ChatHeaderModeToggle = ChatHeaderModeToggle;
4135
+ exports.ChatHeaderResetButton = ChatHeaderResetButton;
4136
+ exports.ChatLauncher = ChatLauncher;
4137
+ exports.ChatUnreadPreview = ChatUnreadPreview;
2578
4138
  exports.CronScheduler = CronScheduler;
4139
+ exports.DEFAULT_DOCK_PREFS = DEFAULT_DOCK_PREFS;
2579
4140
  exports.DiffEditor = DiffEditor;
2580
4141
  exports.Editor = Editor;
2581
4142
  exports.EditorProvider = EditorProvider;
@@ -2605,21 +4166,29 @@ exports.collectImageAttachments = collectImageAttachments;
2605
4166
  exports.createHttpTransport = createHttpTransport;
2606
4167
  exports.createLazyComponent = createLazyComponent;
2607
4168
  exports.createMockTransport = createMockTransport;
4169
+ exports.createPydanticAIChatTransport = createPydanticAIChatTransport;
4170
+ exports.createPydanticAISSEMap = createPydanticAISSEMap;
4171
+ exports.createToolIdQueue = createToolIdQueue;
2608
4172
  exports.dispatchToolPayload = dispatchToolPayload;
2609
4173
  exports.isGeoJSONFeatureCollection = isGeoJSONFeatureCollection;
2610
4174
  exports.isLatLng = isLatLng;
2611
4175
  exports.isPlainObject = isPlainObject;
2612
4176
  exports.isStringValue = isStringValue;
4177
+ exports.mapPydanticAIEvent = mapPydanticAIEvent;
2613
4178
  exports.mentionPresets = mentionPresets;
2614
4179
  exports.parseSSE = parseSSE;
2615
- exports.useAutoFocusOnStreamEnd = useAutoFocusOnStreamEnd;
4180
+ exports.useChatAudioPrefs = useChatAudioPrefs;
4181
+ exports.useChatDockPrefs = useChatDockPrefs;
2616
4182
  exports.useChatHistory = useChatHistory;
2617
4183
  exports.useChatLightbox = useChatLightbox;
4184
+ exports.useChatPresence = useChatPresence;
4185
+ exports.useChatReset = useChatReset;
2618
4186
  exports.useChatScroll = useChatScroll;
4187
+ exports.useChatUnread = useChatUnread;
2619
4188
  exports.useEditor = useEditor;
2620
4189
  exports.useEditorContext = useEditorContext;
2621
4190
  exports.useLanguage = useLanguage;
2622
4191
  exports.useMonaco = useMonaco;
2623
- exports.useRegisterComposer = useRegisterComposer;
4192
+ exports.useVisitorFingerprint = useVisitorFingerprint;
2624
4193
  //# sourceMappingURL=index.cjs.map
2625
4194
  //# sourceMappingURL=index.cjs.map