@burtson-labs/bandit-engine 2.0.161 → 2.0.163

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 (213) hide show
  1. package/README.md +7 -22
  2. package/dist/aiProviderStore-PEGSX4PK.mjs +9 -0
  3. package/dist/chat-MRDQ2WRJ.mjs +16 -0
  4. package/dist/chat-provider.js +86 -31
  5. package/dist/chat-provider.js.map +1 -1
  6. package/dist/chat-provider.mjs +7 -7
  7. package/dist/{chunk-QXITTH2X.mjs → chunk-5KBTOCQZ.mjs} +4 -4
  8. package/dist/chunk-5KBTOCQZ.mjs.map +1 -0
  9. package/dist/{chunk-B3HAQC6F.mjs → chunk-CQJGUYRW.mjs} +69 -26
  10. package/dist/chunk-CQJGUYRW.mjs.map +1 -0
  11. package/dist/{chunk-TTAORNWI.mjs → chunk-F32P7Q5O.mjs} +122 -232
  12. package/dist/chunk-F32P7Q5O.mjs.map +1 -0
  13. package/dist/{chunk-XC7HDKFW.mjs → chunk-HSGQXL4N.mjs} +11 -11
  14. package/dist/chunk-HSGQXL4N.mjs.map +1 -0
  15. package/dist/{chunk-QPXG4A5C.mjs → chunk-IZX2J65Q.mjs} +2 -2
  16. package/dist/chunk-IZX2J65Q.mjs.map +1 -0
  17. package/dist/{chunk-MIDYEQOS.mjs → chunk-J6SWNO7Z.mjs} +20 -35
  18. package/dist/chunk-J6SWNO7Z.mjs.map +1 -0
  19. package/dist/{chunk-PFKKGJAQ.mjs → chunk-O6P37PFR.mjs} +4 -4
  20. package/dist/chunk-O6P37PFR.mjs.map +1 -0
  21. package/dist/{chunk-KCI46M23.mjs → chunk-OCVZVBQQ.mjs} +1 -1
  22. package/dist/chunk-OCVZVBQQ.mjs.map +1 -0
  23. package/dist/{chunk-IXIM7BNO.mjs → chunk-P4C5IRM5.mjs} +1 -1
  24. package/dist/chunk-P4C5IRM5.mjs.map +1 -0
  25. package/dist/{chunk-WQEBTH2R.mjs → chunk-TY5VL3SG.mjs} +3 -3
  26. package/dist/chunk-TY5VL3SG.mjs.map +1 -0
  27. package/dist/{chunk-X65A3NED.mjs → chunk-URZSIL7X.mjs} +7 -7
  28. package/dist/chunk-URZSIL7X.mjs.map +1 -0
  29. package/dist/{chunk-FSRMNQRN.mjs → chunk-VBHI4TJC.mjs} +6 -6
  30. package/dist/chunk-VBHI4TJC.mjs.map +1 -0
  31. package/dist/{chunk-EOMOOMUC.mjs → chunk-WLNZL6SP.mjs} +5 -16
  32. package/dist/chunk-WLNZL6SP.mjs.map +1 -0
  33. package/dist/index.d.mts +6 -0
  34. package/dist/index.d.ts +6 -0
  35. package/dist/index.js +660 -759
  36. package/dist/index.js.map +1 -1
  37. package/dist/index.mjs +15 -31
  38. package/dist/index.mjs.map +1 -1
  39. package/dist/management/management.js +300 -383
  40. package/dist/management/management.js.map +1 -1
  41. package/dist/management/management.mjs +10 -10
  42. package/dist/{memoryUtils-33TZKHSQ.mjs → memoryUtils-2FVXDSS6.mjs} +1 -1
  43. package/dist/memoryUtils-2FVXDSS6.mjs.map +1 -0
  44. package/dist/modals/chat-modal/chat-modal.js +86 -31
  45. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  46. package/dist/modals/chat-modal/chat-modal.mjs +6 -6
  47. package/dist/modelStore-7XYYDCNC.mjs +9 -0
  48. package/dist/shared/custom-element.js.map +1 -1
  49. package/dist/shared/custom-element.mjs +1 -1
  50. package/docs/05_contributing.md +1 -1
  51. package/docs/api_reference/assets/navigation.js +1 -1
  52. package/docs/api_reference/assets/search.js +1 -1
  53. package/docs/api_reference/classes/DebugLogger.html +11 -11
  54. package/docs/api_reference/classes/FeatureFlagService.html +13 -13
  55. package/docs/api_reference/classes/NotificationService.html +10 -10
  56. package/docs/api_reference/classes/StreamingTTSClient.html +9 -9
  57. package/docs/api_reference/classes/VectorDatabaseService.html +24 -24
  58. package/docs/api_reference/classes/VectorMigrationService.html +8 -8
  59. package/docs/api_reference/classes/VoiceService.html +2 -2
  60. package/docs/api_reference/enums/TTSState.html +2 -2
  61. package/docs/api_reference/functions/Chat.html +1 -1
  62. package/docs/api_reference/functions/ChatModal.html +1 -1
  63. package/docs/api_reference/functions/ChatProvider.html +1 -1
  64. package/docs/api_reference/functions/FeatureFlagProvider.html +1 -1
  65. package/docs/api_reference/functions/FeedbackButton.html +1 -1
  66. package/docs/api_reference/functions/FeedbackModal.html +1 -1
  67. package/docs/api_reference/functions/InterestsEditor.html +5 -0
  68. package/docs/api_reference/functions/Management.html +1 -1
  69. package/docs/api_reference/functions/NotificationProvider.html +1 -1
  70. package/docs/api_reference/functions/SubscriptionExpiredGuard.html +1 -1
  71. package/docs/api_reference/functions/SubscriptionExpiredModal.html +1 -1
  72. package/docs/api_reference/functions/defineCustomElement.html +1 -1
  73. package/docs/api_reference/functions/getCriticalConfig.html +2 -1
  74. package/docs/api_reference/functions/getFeatureMatrix.html +1 -1
  75. package/docs/api_reference/functions/getStreamingTTSClient.html +1 -1
  76. package/docs/api_reference/functions/getSystemConstants.html +2 -1
  77. package/docs/api_reference/functions/getTTSState.html +1 -1
  78. package/docs/api_reference/functions/handleHttpError.html +1 -1
  79. package/docs/api_reference/functions/handleSubscriptionUpgrade.html +1 -1
  80. package/docs/api_reference/functions/handleValidationError.html +1 -1
  81. package/docs/api_reference/functions/initializeCoreSystem.html +2 -1
  82. package/docs/api_reference/functions/isWorkspaceAdminRole.html +6 -0
  83. package/docs/api_reference/functions/pauseTTS.html +1 -1
  84. package/docs/api_reference/functions/previewTierUpgrade.html +1 -1
  85. package/docs/api_reference/functions/resolveManagementSections.html +2 -0
  86. package/docs/api_reference/functions/resumeTTS.html +1 -1
  87. package/docs/api_reference/functions/showInfoNotification.html +1 -1
  88. package/docs/api_reference/functions/showSuccessNotification.html +1 -1
  89. package/docs/api_reference/functions/speakWithStreaming.html +1 -1
  90. package/docs/api_reference/functions/stopTTS.html +1 -1
  91. package/docs/api_reference/functions/syncSubscriptionWithAPI.html +1 -1
  92. package/docs/api_reference/functions/updateSubscriptionTier.html +1 -1
  93. package/docs/api_reference/functions/useFeatureFlag.html +1 -1
  94. package/docs/api_reference/functions/useFeatureVisibility.html +1 -1
  95. package/docs/api_reference/functions/useFeatures.html +1 -1
  96. package/docs/api_reference/functions/useGatewayHealth.html +1 -1
  97. package/docs/api_reference/functions/useGatewayMemory.html +1 -1
  98. package/docs/api_reference/functions/useGatewayModels.html +1 -1
  99. package/docs/api_reference/functions/useGlobalTTS.html +1 -1
  100. package/docs/api_reference/functions/useManagementAccess.html +2 -0
  101. package/docs/api_reference/functions/useNotification.html +1 -1
  102. package/docs/api_reference/functions/useNotificationService.html +1 -1
  103. package/docs/api_reference/functions/useTTS.html +1 -1
  104. package/docs/api_reference/functions/useVectorStore.html +1 -1
  105. package/docs/api_reference/functions/useVoiceStore.html +2 -2
  106. package/docs/api_reference/functions/useVoices.html +1 -1
  107. package/docs/api_reference/functions/validateEnvironment.html +2 -1
  108. package/docs/api_reference/functions/validateSystemIntegrity.html +2 -1
  109. package/docs/api_reference/index.html +219 -155
  110. package/docs/api_reference/interfaces/AIChatRequest.html +2 -2
  111. package/docs/api_reference/interfaces/AIChatResponse.html +2 -2
  112. package/docs/api_reference/interfaces/AIGenerateRequest.html +2 -2
  113. package/docs/api_reference/interfaces/AIGenerateResponse.html +2 -2
  114. package/docs/api_reference/interfaces/AIMessage.html +2 -2
  115. package/docs/api_reference/interfaces/AIModel.html +2 -2
  116. package/docs/api_reference/interfaces/AIProviderConfig.html +5 -2
  117. package/docs/api_reference/interfaces/ChatConfig.html +3 -3
  118. package/docs/api_reference/interfaces/ChatModalProps.html +3 -3
  119. package/docs/api_reference/interfaces/CreateMemoryOptions.html +2 -2
  120. package/docs/api_reference/interfaces/FeatureEvaluation.html +7 -7
  121. package/docs/api_reference/interfaces/FeatureFlagConfig.html +9 -9
  122. package/docs/api_reference/interfaces/FeatureFlagContextValue.html +8 -8
  123. package/docs/api_reference/interfaces/FeatureFlagProviderProps.html +2 -2
  124. package/docs/api_reference/interfaces/FeedbackButtonProps.html +10 -10
  125. package/docs/api_reference/interfaces/FeedbackCategories.html +2 -2
  126. package/docs/api_reference/interfaces/FeedbackModalProps.html +2 -2
  127. package/docs/api_reference/interfaces/FeedbackPriorities.html +2 -2
  128. package/docs/api_reference/interfaces/FeedbackRequest.html +2 -2
  129. package/docs/api_reference/interfaces/FeedbackResponse.html +2 -2
  130. package/docs/api_reference/interfaces/FileUploadResult.html +2 -2
  131. package/docs/api_reference/interfaces/GatewayChatRequest.html +3 -2
  132. package/docs/api_reference/interfaces/GatewayChatResponse.html +2 -2
  133. package/docs/api_reference/interfaces/GatewayContract.html +2 -2
  134. package/docs/api_reference/interfaces/GatewayGenerateRequest.html +2 -2
  135. package/docs/api_reference/interfaces/GatewayGenerateResponse.html +2 -2
  136. package/docs/api_reference/interfaces/GatewayHealthResponse.html +2 -2
  137. package/docs/api_reference/interfaces/GatewayMemoryRecord.html +2 -2
  138. package/docs/api_reference/interfaces/GatewayMemoryResponse.html +2 -2
  139. package/docs/api_reference/interfaces/GatewayMessage.html +2 -2
  140. package/docs/api_reference/interfaces/GatewayMessageContent.html +2 -2
  141. package/docs/api_reference/interfaces/GatewayModel.html +2 -2
  142. package/docs/api_reference/interfaces/GatewayModelsResponse.html +2 -2
  143. package/docs/api_reference/interfaces/ManagementAccess.html +5 -0
  144. package/docs/api_reference/interfaces/ManagementAccessInput.html +5 -0
  145. package/docs/api_reference/interfaces/ManagementLink.html +7 -0
  146. package/docs/api_reference/interfaces/ManagementProps.html +22 -0
  147. package/docs/api_reference/interfaces/ManagementSectionDef.html +10 -0
  148. package/docs/api_reference/interfaces/MemorySearchFilters.html +2 -2
  149. package/docs/api_reference/interfaces/MigrationProgress.html +2 -2
  150. package/docs/api_reference/interfaces/MigrationStatus.html +2 -2
  151. package/docs/api_reference/interfaces/NotificationConfig.html +2 -2
  152. package/docs/api_reference/interfaces/NotificationContextType.html +2 -2
  153. package/docs/api_reference/interfaces/NotificationProviderProps.html +2 -2
  154. package/docs/api_reference/interfaces/PackageSettings.html +11 -2
  155. package/docs/api_reference/interfaces/SearchOptions.html +2 -2
  156. package/docs/api_reference/interfaces/SearchResult.html +2 -2
  157. package/docs/api_reference/interfaces/SubscriptionExpiredGuardProps.html +2 -2
  158. package/docs/api_reference/interfaces/SubscriptionExpiredModalProps.html +2 -2
  159. package/docs/api_reference/interfaces/TTSOptions.html +2 -2
  160. package/docs/api_reference/interfaces/TTSProgress.html +2 -2
  161. package/docs/api_reference/interfaces/TrialUsage.html +2 -2
  162. package/docs/api_reference/interfaces/UploadRequest.html +3 -3
  163. package/docs/api_reference/interfaces/UseTTSReturn.html +2 -2
  164. package/docs/api_reference/interfaces/VectorDocument.html +2 -2
  165. package/docs/api_reference/interfaces/VectorMemory.html +2 -2
  166. package/docs/api_reference/interfaces/VectorMemoryMetadata.html +2 -2
  167. package/docs/api_reference/interfaces/VectorStoreStatus.html +2 -2
  168. package/docs/api_reference/interfaces/VoiceModelsResponse.html +2 -2
  169. package/docs/api_reference/interfaces/VoiceState.html +2 -2
  170. package/docs/api_reference/media/PROTECTION-NOTICE.md +6 -55
  171. package/docs/api_reference/media/README.md +20 -1
  172. package/docs/api_reference/modules.html +18 -6
  173. package/docs/api_reference/types/FeatureKey.html +1 -1
  174. package/docs/api_reference/types/FeatureMatrix.html +1 -1
  175. package/docs/api_reference/types/GatewayQueryOptions.html +1 -1
  176. package/docs/api_reference/types/LogContext.html +1 -1
  177. package/docs/api_reference/types/ManagementRequest.html +1 -0
  178. package/docs/api_reference/types/ManagementSectionId.html +2 -0
  179. package/docs/api_reference/types/SubscriptionTier.html +1 -1
  180. package/docs/api_reference/variables/DEFAULT_TIER_FEATURES.html +1 -1
  181. package/docs/api_reference/variables/FeatureFlagContext.html +1 -1
  182. package/docs/api_reference/variables/MANAGEMENT_SECTIONS.html +1 -0
  183. package/docs/api_reference/variables/OSS_DEFAULT_FEATURES.html +1 -1
  184. package/docs/api_reference/variables/SYSTEM_FLAGS.html +2 -1
  185. package/docs/api_reference/variables/authenticationService.html +1 -1
  186. package/docs/api_reference/variables/debugLogger-1.html +1 -1
  187. package/docs/api_reference/variables/featureFlagService-1.html +1 -1
  188. package/docs/api_reference/variables/notificationService-1.html +1 -1
  189. package/docs/api_reference/variables/vectorDatabaseService-1.html +1 -1
  190. package/docs/api_reference/variables/vectorMigrationService-1.html +1 -1
  191. package/docs/api_reference/variables/voiceService-1.html +1 -1
  192. package/package.json +1 -1
  193. package/dist/aiProviderStore-BNZGM6QU.mjs +0 -9
  194. package/dist/chat-3JAV77HO.mjs +0 -16
  195. package/dist/chunk-B3HAQC6F.mjs.map +0 -1
  196. package/dist/chunk-EOMOOMUC.mjs.map +0 -1
  197. package/dist/chunk-FSRMNQRN.mjs.map +0 -1
  198. package/dist/chunk-IXIM7BNO.mjs.map +0 -1
  199. package/dist/chunk-KCI46M23.mjs.map +0 -1
  200. package/dist/chunk-MIDYEQOS.mjs.map +0 -1
  201. package/dist/chunk-PFKKGJAQ.mjs.map +0 -1
  202. package/dist/chunk-QPXG4A5C.mjs.map +0 -1
  203. package/dist/chunk-QXITTH2X.mjs.map +0 -1
  204. package/dist/chunk-TTAORNWI.mjs.map +0 -1
  205. package/dist/chunk-WQEBTH2R.mjs.map +0 -1
  206. package/dist/chunk-X65A3NED.mjs.map +0 -1
  207. package/dist/chunk-XC7HDKFW.mjs.map +0 -1
  208. package/dist/memoryUtils-33TZKHSQ.mjs.map +0 -1
  209. package/dist/modelStore-FGUGOWTL.mjs +0 -9
  210. package/docs/api_reference/media/PROTECTION-README.md +0 -39
  211. /package/dist/{aiProviderStore-BNZGM6QU.mjs.map → aiProviderStore-PEGSX4PK.mjs.map} +0 -0
  212. /package/dist/{chat-3JAV77HO.mjs.map → chat-MRDQ2WRJ.mjs.map} +0 -0
  213. /package/dist/{modelStore-FGUGOWTL.mjs.map → modelStore-7XYYDCNC.mjs.map} +0 -0
@@ -448,6 +448,40 @@ var init_common_types = __esm({
448
448
  }
449
449
  });
450
450
 
451
+ // src/services/stream/streamLineParser.ts
452
+ var SKIP, StreamLineParser;
453
+ var init_streamLineParser = __esm({
454
+ "src/services/stream/streamLineParser.ts"() {
455
+ "use strict";
456
+ SKIP = { kind: "skip" };
457
+ StreamLineParser = class {
458
+ /** Set by `event: ping` until the frame's blank-line terminator. */
459
+ inHeartbeatFrame = false;
460
+ next(rawLine) {
461
+ const line = rawLine.trim();
462
+ if (!line) {
463
+ this.inHeartbeatFrame = false;
464
+ return SKIP;
465
+ }
466
+ if (line.startsWith(":")) return SKIP;
467
+ if (line.startsWith("event:")) {
468
+ this.inHeartbeatFrame = line.slice(6).trim().toLowerCase() === "ping";
469
+ return SKIP;
470
+ }
471
+ if (line.startsWith("id:") || line.startsWith("retry:")) return SKIP;
472
+ if (line.startsWith("data:")) {
473
+ if (this.inHeartbeatFrame) return SKIP;
474
+ const data = line.slice(5).trim();
475
+ if (!data) return SKIP;
476
+ if (data === "[DONE]") return { kind: "done" };
477
+ return { kind: "json", text: data };
478
+ }
479
+ return { kind: "json", text: line };
480
+ }
481
+ };
482
+ }
483
+ });
484
+
451
485
  // src/services/ollama/ollama.service.ts
452
486
  var import_rxjs, handleError, parseResponseBody, OllamaService;
453
487
  var init_ollama_service = __esm({
@@ -455,6 +489,7 @@ var init_ollama_service = __esm({
455
489
  "use strict";
456
490
  import_rxjs = require("rxjs");
457
491
  init_debugLogger();
492
+ init_streamLineParser();
458
493
  handleError = () => (obs) => obs.pipe(
459
494
  (0, import_rxjs.switchMap)(
460
495
  (response) => response.ok ? (0, import_rxjs.of)(response) : (0, import_rxjs.throwError)(() => new Error(`Request failed: ${response.status} ${response.statusText}`))
@@ -545,13 +580,15 @@ var init_ollama_service = __esm({
545
580
  this._throwErrorIfNotOk(url, response);
546
581
  const reader = response.body?.getReader();
547
582
  const decoder = new TextDecoder();
583
+ const lineParser = new StreamLineParser();
548
584
  let buffer = "";
549
585
  const read = () => {
550
586
  reader?.read().then(({ done, value }) => {
551
587
  if (done) {
552
- if (buffer.trim() !== "") {
588
+ const tail = lineParser.next(buffer);
589
+ if (tail.kind === "json") {
553
590
  try {
554
- observer.next(JSON.parse(buffer));
591
+ observer.next(JSON.parse(tail.text));
555
592
  } catch (err) {
556
593
  observer.error(err);
557
594
  debugLogger.error("Final chunk parsing error (generate):", { buffer });
@@ -564,9 +601,10 @@ var init_ollama_service = __esm({
564
601
  const lines = buffer.split("\n");
565
602
  buffer = lines.pop() ?? "";
566
603
  for (const line of lines) {
567
- if (line.trim()) {
604
+ const classified = lineParser.next(line);
605
+ if (classified.kind === "json") {
568
606
  try {
569
- observer.next(JSON.parse(line));
607
+ observer.next(JSON.parse(classified.text));
570
608
  } catch (err) {
571
609
  observer.error(err);
572
610
  debugLogger.error("Error parsing JSON line (generate):", { line });
@@ -596,13 +634,15 @@ var init_ollama_service = __esm({
596
634
  this._throwErrorIfNotOk(url, response);
597
635
  const reader = response.body?.getReader();
598
636
  const decoder = new TextDecoder();
637
+ const lineParser = new StreamLineParser();
599
638
  let buffer = "";
600
639
  const read = () => {
601
640
  reader?.read().then(({ done, value }) => {
602
641
  if (done) {
603
- if (buffer.trim() !== "") {
642
+ const tail = lineParser.next(buffer);
643
+ if (tail.kind === "json") {
604
644
  try {
605
- observer.next(JSON.parse(buffer));
645
+ observer.next(JSON.parse(tail.text));
606
646
  } catch (err) {
607
647
  observer.error(err);
608
648
  debugLogger.error("Final chunk parsing error (chat):", { buffer });
@@ -615,9 +655,10 @@ var init_ollama_service = __esm({
615
655
  const lines = buffer.split("\n");
616
656
  buffer = lines.pop() ?? "";
617
657
  for (const line of lines) {
618
- if (line.trim()) {
658
+ const classified = lineParser.next(line);
659
+ if (classified.kind === "json") {
619
660
  try {
620
- observer.next(JSON.parse(line));
661
+ observer.next(JSON.parse(classified.text));
621
662
  } catch (err) {
622
663
  observer.error(err);
623
664
  debugLogger.error("Error parsing JSON line (chat):", { line });
@@ -1648,6 +1689,7 @@ var init_gateway_service = __esm({
1648
1689
  "src/services/gateway/gateway.service.ts"() {
1649
1690
  "use strict";
1650
1691
  import_axios = __toESM(require("axios"));
1692
+ init_streamLineParser();
1651
1693
  import_rxjs6 = require("rxjs");
1652
1694
  init_debugLogger();
1653
1695
  init_authenticationService();
@@ -1829,13 +1871,15 @@ var init_gateway_service = __esm({
1829
1871
  const handleStreamingResponse = async (response) => {
1830
1872
  const reader = response.body?.getReader();
1831
1873
  const decoder = new TextDecoder();
1874
+ const lineParser = new StreamLineParser();
1832
1875
  let buffer = "";
1833
1876
  const read = () => {
1834
1877
  reader?.read().then(({ done, value }) => {
1835
1878
  if (done) {
1836
- if (buffer.trim() !== "") {
1879
+ const tail = lineParser.next(buffer);
1880
+ if (tail.kind === "json") {
1837
1881
  try {
1838
- const finalResponse = JSON.parse(buffer);
1882
+ const finalResponse = JSON.parse(tail.text);
1839
1883
  observer.next(finalResponse);
1840
1884
  } catch (err) {
1841
1885
  debugLogger.error("GatewayService chat final chunk parsing error", { buffer, error: err });
@@ -1849,16 +1893,14 @@ var init_gateway_service = __esm({
1849
1893
  const lines = buffer.split("\n");
1850
1894
  buffer = lines.pop() ?? "";
1851
1895
  for (const line of lines) {
1852
- const trimmed = line.trim();
1853
- if (trimmed) {
1854
- let data = trimmed;
1855
- if (trimmed.startsWith("data: ")) {
1856
- data = trimmed.slice(6);
1857
- if (data === "[DONE]") {
1858
- observer.complete();
1859
- return;
1860
- }
1861
- }
1896
+ const classified = lineParser.next(line);
1897
+ if (classified.kind === "done") {
1898
+ observer.complete();
1899
+ return;
1900
+ }
1901
+ if (classified.kind === "json") {
1902
+ const trimmed = line.trim();
1903
+ const data = classified.text;
1862
1904
  try {
1863
1905
  const parsed = JSON.parse(data);
1864
1906
  if (request.provider === "ollama" && parsed.message) {
@@ -2025,13 +2067,15 @@ var init_gateway_service = __esm({
2025
2067
  }
2026
2068
  const reader = response.body?.getReader();
2027
2069
  const decoder = new TextDecoder();
2070
+ const lineParser = new StreamLineParser();
2028
2071
  let buffer = "";
2029
2072
  const read = () => {
2030
2073
  reader?.read().then(({ done, value }) => {
2031
2074
  if (done) {
2032
- if (buffer.trim() !== "") {
2075
+ const tail = lineParser.next(buffer);
2076
+ if (tail.kind === "json") {
2033
2077
  try {
2034
- observer.next(JSON.parse(buffer));
2078
+ observer.next(JSON.parse(tail.text));
2035
2079
  } catch (err) {
2036
2080
  observer.error(err);
2037
2081
  debugLogger.error("Final chunk parsing error (gateway generate):", { buffer });
@@ -2044,9 +2088,14 @@ var init_gateway_service = __esm({
2044
2088
  const lines = buffer.split("\n");
2045
2089
  buffer = lines.pop() ?? "";
2046
2090
  for (const line of lines) {
2047
- if (line.trim()) {
2091
+ const classified = lineParser.next(line);
2092
+ if (classified.kind === "done") {
2093
+ observer.complete();
2094
+ return;
2095
+ }
2096
+ if (classified.kind === "json") {
2048
2097
  try {
2049
- observer.next(JSON.parse(line));
2098
+ observer.next(JSON.parse(classified.text));
2050
2099
  } catch (err) {
2051
2100
  observer.error(err);
2052
2101
  debugLogger.error("Error parsing JSON line (gateway generate):", { line });
@@ -3732,13 +3781,12 @@ var init_packageSettingsStore = __esm({
3732
3781
  });
3733
3782
 
3734
3783
  // src/util.ts
3735
- var toTitleCase, randomRange, generateSeed, fetchAndConvertToBase64, detectTransparency, banditHead, modelAvatars, resolveAvatar;
3784
+ var toTitleCase, generateSeed, fetchAndConvertToBase64, detectTransparency, banditHead, modelAvatars, resolveAvatar;
3736
3785
  var init_util = __esm({
3737
3786
  "src/util.ts"() {
3738
3787
  "use strict";
3739
3788
  init_debugLogger();
3740
3789
  toTitleCase = (str) => str.toLowerCase().split(" ").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
3741
- randomRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
3742
3790
  generateSeed = () => Math.floor(Math.random() * 1e4);
3743
3791
  fetchAndConvertToBase64 = async (src) => {
3744
3792
  const response = await fetch(src);
@@ -3798,30 +3846,12 @@ var init_util = __esm({
3798
3846
  });
3799
3847
 
3800
3848
  // src/prompts/getStableQuestionPrompt.ts
3801
- var TOPICS, getRandomTopicOfInterest, pickDistinctRandomTopics, getStableQuestionPrompt;
3849
+ var TOPICS, getStableQuestionPrompt;
3802
3850
  var init_getStableQuestionPrompt = __esm({
3803
3851
  "src/prompts/getStableQuestionPrompt.ts"() {
3804
3852
  "use strict";
3805
3853
  init_util();
3806
3854
  TOPICS = ["everyday life", "finance", "sports", "travel", "technology", "politics", "health", "food", "entertainment", "education", "science", "history", "art", "music", "literature", "philosophy", "psychology", "sociology", "environmental issues", "current events"];
3807
- getRandomTopicOfInterest = () => {
3808
- const minIndex = 0;
3809
- const maxIndex = TOPICS.length - 1;
3810
- const randomIndex = randomRange(minIndex, maxIndex);
3811
- const randomTopic = TOPICS[randomIndex];
3812
- return randomTopic;
3813
- };
3814
- pickDistinctRandomTopics = (count) => {
3815
- const pool = [...TOPICS];
3816
- const picked = [];
3817
- const n = Math.min(Math.max(count, 0), pool.length);
3818
- for (let i = 0; i < n; i++) {
3819
- const idx = randomRange(0, pool.length - 1);
3820
- picked.push(pool[idx]);
3821
- pool.splice(idx, 1);
3822
- }
3823
- return picked;
3824
- };
3825
3855
  getStableQuestionPrompt = (args) => {
3826
3856
  const { limit, topicOfInterest, modelSystemPrompt, interests, knowledgeTopics, webSearchAvailable } = args;
3827
3857
  if (limit < 1 || limit > 10) {
@@ -9308,9 +9338,17 @@ var init_useVectorStore = __esm({
9308
9338
  const hasAnyAdvancedFeatures = isAdvancedVectorFeaturesEnabled;
9309
9339
  const hasVectorAccess = features.isAdmin() || features.hasAdvancedSearch() || features.hasAdvancedMemories();
9310
9340
  const [hasCompatibleProvider, setHasCompatibleProvider] = (0, import_react3.useState)(false);
9341
+ const mountedRef = (0, import_react3.useRef)(true);
9342
+ (0, import_react3.useEffect)(() => {
9343
+ mountedRef.current = true;
9344
+ return () => {
9345
+ mountedRef.current = false;
9346
+ };
9347
+ }, []);
9311
9348
  const checkProviderCompatibility = (0, import_react3.useCallback)(async () => {
9312
9349
  try {
9313
9350
  const { useAIProviderStore: useAIProviderStore2 } = await Promise.resolve().then(() => (init_aiProviderStore(), aiProviderStore_exports));
9351
+ if (!mountedRef.current) return false;
9314
9352
  const aiProviderState = useAIProviderStore2.getState();
9315
9353
  const provider = aiProviderState.provider;
9316
9354
  const config = aiProviderState.config;
@@ -9327,7 +9365,7 @@ var init_useVectorStore = __esm({
9327
9365
  return isCompatible;
9328
9366
  } catch (error) {
9329
9367
  debugLogger.warn("Could not check AI provider for vector compatibility", { error });
9330
- setHasCompatibleProvider(false);
9368
+ if (mountedRef.current) setHasCompatibleProvider(false);
9331
9369
  return false;
9332
9370
  }
9333
9371
  }, []);
@@ -9335,12 +9373,10 @@ var init_useVectorStore = __esm({
9335
9373
  checkProviderCompatibility();
9336
9374
  }, [checkProviderCompatibility]);
9337
9375
  (0, import_react3.useEffect)(() => {
9338
- const checkOnProviderChange = async () => {
9339
- setTimeout(() => {
9340
- checkProviderCompatibility();
9341
- }, 100);
9342
- };
9343
- checkOnProviderChange();
9376
+ const timer = setTimeout(() => {
9377
+ void checkProviderCompatibility();
9378
+ }, 100);
9379
+ return () => clearTimeout(timer);
9344
9380
  }, [authStore.token, checkProviderCompatibility]);
9345
9381
  (0, import_react3.useEffect)(() => {
9346
9382
  const interval = setInterval(() => {
@@ -12743,16 +12779,6 @@ function appBarTokens(theme) {
12743
12779
  menuText: s.control.foreground
12744
12780
  };
12745
12781
  }
12746
- function suggestionTokens(theme) {
12747
- const s = chatTokens(theme);
12748
- return {
12749
- background: s.surface.subtle,
12750
- text: s.conversation.assistant.foreground,
12751
- border: s.conversation.border,
12752
- hoverBackground: s.surface.interactive,
12753
- hoverBorder: theme.palette.divider
12754
- };
12755
- }
12756
12782
  function responseTokens(theme) {
12757
12783
  const s = chatTokens(theme);
12758
12784
  return {
@@ -28457,203 +28483,84 @@ Respond with just the title and nothing else.
28457
28483
  });
28458
28484
 
28459
28485
  // src/chat/query-suggestion-picker.tsx
28460
- var import_react77, import_material55, import_styles30, import_react_markdown3, import_remark_gfm3, import_rehype_raw3, import_jsx_runtime56, markdownComponents, QuerySuggestionPicker;
28486
+ function QuerySuggestionPicker({ onSend, onSelect }) {
28487
+ const [ideas, setIdeas] = (0, import_react77.useState)([]);
28488
+ const [generating, setGenerating] = (0, import_react77.useState)(false);
28489
+ const [message, setMessage] = (0, import_react77.useState)("");
28490
+ const mounted = (0, import_react77.useRef)(false);
28491
+ const generatingRef = (0, import_react77.useRef)(false);
28492
+ (0, import_react77.useEffect)(() => {
28493
+ mounted.current = true;
28494
+ return () => {
28495
+ mounted.current = false;
28496
+ };
28497
+ }, []);
28498
+ const select = (prompt) => {
28499
+ if (onSelect) onSelect(prompt);
28500
+ else void Promise.resolve(onSend(prompt, [])).catch(() => {
28501
+ });
28502
+ };
28503
+ const generateIdeas = async () => {
28504
+ if (generatingRef.current) return;
28505
+ generatingRef.current = true;
28506
+ setGenerating(true);
28507
+ setMessage("");
28508
+ try {
28509
+ const prefs = usePreferencesStore.getState().preferences;
28510
+ const interests = (prefs.interests ?? []).filter((value) => value?.trim());
28511
+ const prompts = await generateConversationStarters({
28512
+ limit: 3,
28513
+ topicOfInterest: interests.join(", ") || "practical writing, learning, and decisions",
28514
+ interests,
28515
+ modelSystemPrompt: useModelStore.getState().getCurrentModel()?.systemPrompt,
28516
+ knowledgeTopics: prefs.useKnowledgeForStarters ? useKnowledgeStore.getState().docs.map((doc) => doc.name).filter(Boolean).slice(0, 12) : void 0,
28517
+ webSearchAvailable: useMCPToolsStore.getState().getEnabledTools().some((tool) => tool.name === "web_search")
28518
+ });
28519
+ if (!mounted.current) return;
28520
+ const next = prompts.filter((prompt) => typeof prompt === "string" && prompt.trim()).slice(0, 3);
28521
+ setIdeas(next);
28522
+ setMessage(next.length ? "New ideas are ready. Choose one to get started." : "Ideas are unavailable right now. You can still use a starter or write your own.");
28523
+ } catch {
28524
+ if (mounted.current) setMessage("Ideas are unavailable right now. You can still use a starter or write your own.");
28525
+ } finally {
28526
+ generatingRef.current = false;
28527
+ if (mounted.current) setGenerating(false);
28528
+ }
28529
+ };
28530
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_material55.Box, { component: "section", "aria-label": "Start with a task", sx: { width: "100%", px: { xs: 2, sm: 3 } }, children: [
28531
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_material55.Box, { sx: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 1, mb: 1.5 }, children: [
28532
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Typography, { variant: "body2", sx: { fontWeight: 600 }, children: "What would move your work forward?" }),
28533
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Button, { size: "small", startIcon: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react78.Refresh, { size: 14 }), disabled: generating, onClick: () => void generateIdeas(), sx: { flexShrink: 0 }, children: generating ? "Finding ideas\u2026" : "Suggest ideas" })
28534
+ ] }),
28535
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Box, { sx: { display: "grid", gridTemplateColumns: { xs: "1fr", sm: "repeat(3, minmax(0, 1fr))" }, gap: 1 }, children: (ideas.length ? ideas.map((prompt) => ({ title: prompt, detail: "", icon: import_react78.ArrowRight, prompt })) : STARTERS).map(({ title, detail, icon: Icon, prompt }) => /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_material55.Button, { variant: "outlined", onClick: () => select(prompt), sx: { display: "flex", alignItems: "flex-start", justifyContent: "flex-start", gap: 1.2, textAlign: "left", textTransform: "none", p: { xs: 1.5, sm: 2 }, height: "100%", color: "text.primary", borderColor: "divider" }, children: [
28536
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Box, { component: "span", sx: { display: "flex", color: "primary.main", mt: 0.25 }, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Icon, { size: 18 }) }),
28537
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_material55.Box, { component: "span", children: [
28538
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Typography, { component: "span", variant: "body2", sx: { display: "block", fontWeight: 550, lineHeight: 1.45 }, children: title }),
28539
+ detail && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Typography, { component: "span", variant: "caption", sx: { display: "block", color: "text.secondary", mt: 0.5, lineHeight: 1.5 }, children: detail })
28540
+ ] })
28541
+ ] }, title)) }),
28542
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Typography, { variant: "caption", sx: { display: "block", color: "text.secondary", mt: 1.25 }, children: onSelect ? "Choose a starting point, then make it your own before sending." : "Choose a starting point or write your own message." }),
28543
+ message && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_material55.Typography, { role: "status", variant: "caption", sx: { display: "block", color: "text.secondary", mt: 1 }, children: message })
28544
+ ] });
28545
+ }
28546
+ var import_react77, import_material55, import_react78, import_jsx_runtime56, STARTERS;
28461
28547
  var init_query_suggestion_picker = __esm({
28462
28548
  "src/chat/query-suggestion-picker.tsx"() {
28463
28549
  "use strict";
28464
28550
  import_react77 = require("react");
28465
28551
  import_material55 = require("@mui/material");
28466
- import_styles30 = require("@mui/material/styles");
28467
- import_react_markdown3 = __toESM(require("react-markdown"));
28468
- import_remark_gfm3 = __toESM(require("remark-gfm"));
28469
- import_rehype_raw3 = __toESM(require("rehype-raw"));
28552
+ import_react78 = require("@burtson-labs/icons/react");
28470
28553
  init_prompts();
28471
- init_getStableQuestionPrompt();
28472
28554
  init_modelStore();
28473
28555
  init_preferencesStore();
28474
28556
  init_knowledgeStore();
28475
28557
  init_mcpToolsStore();
28476
- init_chat_tokens();
28477
28558
  import_jsx_runtime56 = require("react/jsx-runtime");
28478
- markdownComponents = {
28479
- p: ({ node, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { ...props }),
28480
- mark: ({ node, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("mark", { ...props, children }),
28481
- code: ({ node, children, ...props }) => {
28482
- const { inline, ...rest } = props;
28483
- return inline ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { ...rest, children }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { ...rest, children });
28484
- }
28485
- };
28486
- QuerySuggestionPicker = ({
28487
- onSend,
28488
- inputHeight
28489
- }) => {
28490
- const hasGenerated = (0, import_react77.useRef)(false);
28491
- const [hasSentPrompt, setHasSentPrompt] = (0, import_react77.useState)(false);
28492
- const [examplePrompts, setExamplePrompts] = (0, import_react77.useState)([]);
28493
- const [visiblePrompts, setVisiblePrompts] = (0, import_react77.useState)([]);
28494
- const scrollRef = (0, import_react77.useRef)(null);
28495
- const theme = (0, import_styles30.useTheme)();
28496
- const isMobile = (0, import_material55.useMediaQuery)((theme2) => theme2.breakpoints.down("sm"));
28497
- const { background, text, border, hoverBackground, hoverBorder } = suggestionTokens(theme);
28498
- const { getCurrentModel, isLoading } = useModelStore();
28499
- (0, import_react77.useEffect)(() => {
28500
- if (hasGenerated.current || isLoading) return;
28501
- hasGenerated.current = true;
28502
- const currentModel = getCurrentModel();
28503
- const prefs = usePreferencesStore.getState().preferences;
28504
- const interests = (prefs.interests ?? []).filter((i) => i && i.trim());
28505
- const randomTopics = pickDistinctRandomTopics(interests.length ? 3 : 5);
28506
- const topicOfInterest = Array.from(/* @__PURE__ */ new Set([...interests, ...randomTopics])).join(", ") || getRandomTopicOfInterest();
28507
- const webSearchAvailable = useMCPToolsStore.getState().getEnabledTools().some((t) => t.name === "web_search");
28508
- const knowledgeTopics = prefs.useKnowledgeForStarters ? useKnowledgeStore.getState().docs.map((d) => d.name).filter((n) => n && n.trim()).slice(0, 12) : void 0;
28509
- const args = {
28510
- limit: 9,
28511
- topicOfInterest,
28512
- modelSystemPrompt: currentModel?.systemPrompt,
28513
- interests,
28514
- knowledgeTopics,
28515
- webSearchAvailable
28516
- };
28517
- generateConversationStarters(args).then((prompts) => {
28518
- if (prompts.length > 0) {
28519
- setExamplePrompts(prompts);
28520
- setVisiblePrompts(prompts.slice(0, 3));
28521
- } else {
28522
- setExamplePrompts([]);
28523
- setVisiblePrompts([]);
28524
- hasGenerated.current = false;
28525
- }
28526
- }).catch((error) => {
28527
- setExamplePrompts([]);
28528
- setVisiblePrompts([]);
28529
- hasGenerated.current = false;
28530
- });
28531
- }, [getCurrentModel, isLoading]);
28532
- (0, import_react77.useEffect)(() => {
28533
- if (!isLoading) {
28534
- hasGenerated.current = false;
28535
- }
28536
- }, [isLoading]);
28537
- (0, import_react77.useEffect)(() => {
28538
- if (hasSentPrompt || examplePrompts.length === 0) return;
28539
- const interval = setInterval(() => {
28540
- setExamplePrompts((prev) => {
28541
- if (prev.length < 3) return prev;
28542
- const shuffled = [...prev].sort(() => 0.5 - Math.random());
28543
- setVisiblePrompts((current) => [shuffled[0], current[1], current[2]]);
28544
- setTimeout(() => {
28545
- setVisiblePrompts((current) => [shuffled[0], shuffled[1], current[2]]);
28546
- }, 400);
28547
- setTimeout(() => {
28548
- setVisiblePrompts(shuffled.slice(0, 3));
28549
- }, 800);
28550
- return shuffled;
28551
- });
28552
- }, 12e3);
28553
- return () => clearInterval(interval);
28554
- }, [hasSentPrompt, examplePrompts.length]);
28555
- const displayPrompts = isMobile ? visiblePrompts.slice(0, Math.min(visiblePrompts.length, 6)) : visiblePrompts;
28556
- return displayPrompts.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_jsx_runtime56.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
28557
- import_material55.Box,
28558
- {
28559
- ref: scrollRef,
28560
- sx: {
28561
- zIndex: 1200,
28562
- width: "100%",
28563
- display: "flex",
28564
- flexDirection: "row",
28565
- gap: isMobile ? 0.8 : 1,
28566
- px: isMobile ? 1.5 : 2,
28567
- overflowX: isMobile ? "auto" : "visible",
28568
- scrollSnapType: isMobile ? "x mandatory" : "none",
28569
- WebkitOverflowScrolling: "touch",
28570
- pb: isMobile ? 0.4 : 0,
28571
- "&::-webkit-scrollbar": { display: "none" }
28572
- },
28573
- children: displayPrompts.map((prompt, i) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
28574
- import_material55.Box,
28575
- {
28576
- component: "button",
28577
- type: "button",
28578
- sx: {
28579
- appearance: "none",
28580
- font: "inherit",
28581
- textAlign: "inherit",
28582
- "&:focus-visible": { outline: `2px solid ${theme.palette.primary.main}`, outlineOffset: 2 },
28583
- px: isMobile ? 1.4 : 2,
28584
- py: isMobile ? 1.2 : 2,
28585
- flex: isMobile ? "0 0 85%" : 1,
28586
- minWidth: isMobile ? "85%" : "auto",
28587
- display: "flex",
28588
- alignItems: "flex-start",
28589
- gap: isMobile ? 0.9 : 1,
28590
- backgroundColor: background,
28591
- borderRadius: 2,
28592
- fontSize: isMobile ? "0.875rem" : "0.9rem",
28593
- color: text,
28594
- userSelect: "none",
28595
- cursor: "pointer",
28596
- border: `1px solid ${border || (0, import_styles30.alpha)(text, 0.12)}`,
28597
- boxShadow: theme.palette.mode === "dark" ? "0 4px 18px rgba(0,0,0,0.25)" : "0 6px 20px rgba(15,23,42,0.12)",
28598
- scrollSnapAlign: isMobile ? "start" : "none",
28599
- transition: "transform 0.25s ease, box-shadow 0.25s ease, background-color 0.25s ease",
28600
- "&:hover": {
28601
- backgroundColor: hoverBackground,
28602
- borderColor: hoverBorder,
28603
- transform: "translateY(-2px)",
28604
- boxShadow: theme.palette.mode === "dark" ? "0 6px 22px rgba(0,0,0,0.28)" : "0 8px 24px rgba(15,23,42,0.14)"
28605
- },
28606
- "&:active": {
28607
- transform: "translateY(0) scale(0.98)"
28608
- }
28609
- },
28610
- onClick: () => {
28611
- void Promise.resolve(onSend(prompt, [])).catch(() => {
28612
- });
28613
- setHasSentPrompt(true);
28614
- },
28615
- children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
28616
- import_material55.Box,
28617
- {
28618
- sx: {
28619
- flex: 1,
28620
- lineHeight: 1.4,
28621
- fontWeight: isMobile ? 500 : 400,
28622
- textAlign: isMobile ? "left" : "center",
28623
- ...isMobile && { hyphens: "auto", wordBreak: "break-word" },
28624
- "& code": {
28625
- borderRadius: 4,
28626
- fontSize: "0.92em",
28627
- fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
28628
- backgroundColor: theme.palette.mode === "dark" ? (0, import_styles30.alpha)(theme.palette.common.white, 0.06) : (0, import_styles30.alpha)(theme.palette.text.primary, 0.06),
28629
- border: `1px solid ${(0, import_styles30.alpha)(theme.palette.text.primary, 0.15)}`,
28630
- padding: "0.15em 0.35em"
28631
- },
28632
- "& mark": {
28633
- display: "inline-block",
28634
- backgroundColor: theme.palette.mode === "dark" ? (0, import_styles30.alpha)(theme.palette.common.white, 0.06) : (0, import_styles30.alpha)(theme.palette.text.primary, 0.12),
28635
- color: theme.palette.mode === "dark" ? theme.palette.common.white : theme.palette.text.primary,
28636
- borderRadius: 4,
28637
- padding: "0.1em 0.25em"
28638
- }
28639
- },
28640
- children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
28641
- import_react_markdown3.default,
28642
- {
28643
- remarkPlugins: [import_remark_gfm3.default],
28644
- rehypePlugins: [import_rehype_raw3.default],
28645
- components: markdownComponents,
28646
- children: prompt
28647
- }
28648
- )
28649
- }
28650
- )
28651
- },
28652
- `${i}-${prompt}`
28653
- ))
28654
- }
28655
- ) });
28656
- };
28559
+ STARTERS = [
28560
+ { title: "Make sense of something", detail: "Find the important parts and the open questions.", icon: import_react78.FileText, prompt: "Help me understand the material I share next. Summarize the key points, distinguish facts from assumptions, and call out what is missing." },
28561
+ { title: "Think through a decision", detail: "Compare options against what matters to you.", icon: import_react78.ListChecks, prompt: "Help me work through a decision. Ask me for the options, constraints, and what matters most, then compare the tradeoffs." },
28562
+ { title: "Create a useful first draft", detail: "Turn a rough idea into something you can use.", icon: import_react78.PenLine, prompt: "Help me turn an idea into a useful first draft. Ask me what I am making, who it is for, and what a good result looks like." }
28563
+ ];
28657
28564
  }
28658
28565
  });
28659
28566
 
@@ -28732,14 +28639,14 @@ var init_UnderReview = __esm({
28732
28639
  });
28733
28640
 
28734
28641
  // src/components/feedback/FeedbackPulse.tsx
28735
- var import_react78, import_material57, import_styles31, import_react79, import_jsx_runtime58, STORAGE_KEY3, COOLDOWN_DAYS, MIN_SESSION_MS, MIN_MESSAGES_SENT, CHECK_INTERVAL_MS, readLastInteraction, recordInteraction, FeedbackPulse, FeedbackPulse_default;
28642
+ var import_react79, import_material57, import_styles30, import_react80, import_jsx_runtime58, STORAGE_KEY3, COOLDOWN_DAYS, MIN_SESSION_MS, MIN_MESSAGES_SENT, CHECK_INTERVAL_MS, readLastInteraction, recordInteraction, FeedbackPulse, FeedbackPulse_default;
28736
28643
  var init_FeedbackPulse = __esm({
28737
28644
  "src/components/feedback/FeedbackPulse.tsx"() {
28738
28645
  "use strict";
28739
- import_react78 = require("react");
28646
+ import_react79 = require("react");
28740
28647
  import_material57 = require("@mui/material");
28741
- import_styles31 = require("@mui/material/styles");
28742
- import_react79 = require("@burtson-labs/icons/react");
28648
+ import_styles30 = require("@mui/material/styles");
28649
+ import_react80 = require("@burtson-labs/icons/react");
28743
28650
  init_conversationStore();
28744
28651
  init_FeedbackModal();
28745
28652
  init_debugLogger();
@@ -28764,22 +28671,22 @@ var init_FeedbackPulse = __esm({
28764
28671
  debugLogger.info("FeedbackPulse: interaction recorded", { outcome });
28765
28672
  };
28766
28673
  FeedbackPulse = ({ isMobile, feedbackEmail }) => {
28767
- const theme = (0, import_styles31.useTheme)();
28768
- const [visible, setVisible] = (0, import_react78.useState)(false);
28769
- const [thanked, setThanked] = (0, import_react78.useState)(false);
28770
- const [modalOpen, setModalOpen] = (0, import_react78.useState)(false);
28771
- const mountedAtRef = (0, import_react78.useRef)(Date.now());
28772
- const baselineMessagesRef = (0, import_react78.useRef)(null);
28674
+ const theme = (0, import_styles30.useTheme)();
28675
+ const [visible, setVisible] = (0, import_react79.useState)(false);
28676
+ const [thanked, setThanked] = (0, import_react79.useState)(false);
28677
+ const [modalOpen, setModalOpen] = (0, import_react79.useState)(false);
28678
+ const mountedAtRef = (0, import_react79.useRef)(Date.now());
28679
+ const baselineMessagesRef = (0, import_react79.useRef)(null);
28773
28680
  const totalMessages = useConversationStore(
28774
28681
  (s) => s.conversations.reduce((n, c) => n + c.history.length, 0)
28775
28682
  );
28776
28683
  const hydrated = useConversationStore((s) => s._hasHydrated);
28777
- (0, import_react78.useEffect)(() => {
28684
+ (0, import_react79.useEffect)(() => {
28778
28685
  if (hydrated && baselineMessagesRef.current === null) {
28779
28686
  baselineMessagesRef.current = totalMessages;
28780
28687
  }
28781
28688
  }, [hydrated, totalMessages]);
28782
- (0, import_react78.useEffect)(() => {
28689
+ (0, import_react79.useEffect)(() => {
28783
28690
  const cooldownMs = COOLDOWN_DAYS * 24 * 60 * 60 * 1e3;
28784
28691
  const forced = typeof window !== "undefined" && new URLSearchParams(window.location.search).has("feedbackPulse");
28785
28692
  const check = () => {
@@ -28838,7 +28745,7 @@ var init_FeedbackPulse = __esm({
28838
28745
  color: theme.palette.text.secondary,
28839
28746
  transition: "background-color 0.15s ease, transform 0.1s ease",
28840
28747
  "&:hover": {
28841
- bgcolor: (0, import_styles31.alpha)(theme.palette.text.primary, 0.06),
28748
+ bgcolor: (0, import_styles30.alpha)(theme.palette.text.primary, 0.06),
28842
28749
  color: theme.palette.text.primary
28843
28750
  },
28844
28751
  "&:active": { transform: "scale(0.96)" }
@@ -28867,17 +28774,17 @@ var init_FeedbackPulse = __esm({
28867
28774
  borderRadius: 3,
28868
28775
  border: `1px solid ${theme.palette.divider}`,
28869
28776
  bgcolor: theme.palette.background.paper,
28870
- boxShadow: `0 12px 40px ${(0, import_styles31.alpha)(theme.palette.common.black, theme.palette.mode === "dark" ? 0.5 : 0.18)}`
28777
+ boxShadow: `0 12px 40px ${(0, import_styles30.alpha)(theme.palette.common.black, theme.palette.mode === "dark" ? 0.5 : 0.18)}`
28871
28778
  },
28872
28779
  children: thanked ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material57.Typography, { sx: { textAlign: "center", py: 1.5, fontWeight: 600 }, children: "Thanks for the feedback!" }) : /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_jsx_runtime58.Fragment, { children: [
28873
28780
  /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_material57.Box, { sx: { display: "flex", alignItems: "center", mb: 0.5 }, children: [
28874
28781
  /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material57.Typography, { variant: "body2", sx: { fontWeight: 600, flex: 1 }, children: "How's Bandit doing?" }),
28875
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material57.IconButton, { size: "small", onClick: dismiss, "aria-label": "Dismiss feedback prompt", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react79.X, { size: 16 }) })
28782
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_material57.IconButton, { size: "small", onClick: dismiss, "aria-label": "Dismiss feedback prompt", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react80.X, { size: 16 }) })
28876
28783
  ] }),
28877
28784
  /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_material57.Box, { sx: { display: "flex", justifyContent: "space-evenly" }, children: [
28878
- choice(/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react79.Smile, { size: 22, color: theme.palette.success.main }), "Good", "good"),
28879
- choice(/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react79.Meh, { size: 22, color: theme.palette.warning.main }), "Fine", "fine"),
28880
- choice(/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react79.Frown, { size: 22, color: theme.palette.error.main }), "Bad", "bad")
28785
+ choice(/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react80.Smile, { size: 22, color: theme.palette.success.main }), "Good", "good"),
28786
+ choice(/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react80.Meh, { size: 22, color: theme.palette.warning.main }), "Fine", "fine"),
28787
+ choice(/* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react80.Frown, { size: 22, color: theme.palette.error.main }), "Bad", "bad")
28881
28788
  ] })
28882
28789
  ] })
28883
28790
  }
@@ -28989,11 +28896,11 @@ var init_ConnectionStatus = __esm({
28989
28896
  });
28990
28897
 
28991
28898
  // src/hooks/useVoiceMode.ts
28992
- var import_react80, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
28899
+ var import_react81, RMS_BASELINE, RMS_NORMALIZER, computeRms, pickSupportedMimeType, useVoiceMode;
28993
28900
  var init_useVoiceMode = __esm({
28994
28901
  "src/hooks/useVoiceMode.ts"() {
28995
28902
  "use strict";
28996
- import_react80 = require("react");
28903
+ import_react81 = require("react");
28997
28904
  init_stt_client();
28998
28905
  init_debugLogger();
28999
28906
  init_voiceModeStore();
@@ -29026,11 +28933,11 @@ var init_useVoiceMode = __esm({
29026
28933
  const setError = useVoiceModeStore((state) => state.setError);
29027
28934
  const resetTransientState = useVoiceModeStore((state) => state.resetTransientState);
29028
28935
  const setLastTranscript = useVoiceModeStore((state) => state.setLastTranscript);
29029
- const configRef = (0, import_react80.useRef)(config);
29030
- (0, import_react80.useEffect)(() => {
28936
+ const configRef = (0, import_react81.useRef)(config);
28937
+ (0, import_react81.useEffect)(() => {
29031
28938
  configRef.current = config;
29032
28939
  }, [config]);
29033
- (0, import_react80.useEffect)(() => {
28940
+ (0, import_react81.useEffect)(() => {
29034
28941
  if (!enabled) {
29035
28942
  return () => void 0;
29036
28943
  }
@@ -29291,15 +29198,15 @@ var chat_exports = {};
29291
29198
  __export(chat_exports, {
29292
29199
  default: () => chat_default
29293
29200
  });
29294
- var import_react81, import_material59, import_styles32, import_react_router_dom6, import_react82, import_jsx_runtime60, ChatContent, Chat, chat_default;
29201
+ var import_react82, import_material59, import_styles31, import_react_router_dom6, import_react83, import_jsx_runtime60, ChatContent, Chat, chat_default;
29295
29202
  var init_chat2 = __esm({
29296
29203
  "src/chat/chat.tsx"() {
29297
29204
  "use strict";
29298
- import_react81 = require("react");
29205
+ import_react82 = require("react");
29299
29206
  init_custom_logo();
29300
29207
  init_indexedDBService();
29301
29208
  import_material59 = require("@mui/material");
29302
- import_styles32 = require("@mui/material/styles");
29209
+ import_styles31 = require("@mui/material/styles");
29303
29210
  init_chat_tokens();
29304
29211
  init_chat_skeleton();
29305
29212
  init_aiQueryStore();
@@ -29341,7 +29248,7 @@ var init_chat2 = __esm({
29341
29248
  init_FeatureFlagContext();
29342
29249
  init_knowledgeStore();
29343
29250
  init_icons();
29344
- import_react82 = require("@burtson-labs/icons/react");
29251
+ import_react83 = require("@burtson-labs/icons/react");
29345
29252
  import_jsx_runtime60 = require("react/jsx-runtime");
29346
29253
  ChatContent = () => {
29347
29254
  const packageSettings = usePackageSettingsStore((state) => state.settings);
@@ -29351,8 +29258,8 @@ var init_chat2 = __esm({
29351
29258
  const ossMode = isOSSMode() || !packageSettings?.featureFlags?.subscriptionType;
29352
29259
  const playgroundBypassAccess = packageSettings?.playgroundBypassAuth || typeof window !== "undefined" && window.location.pathname.includes("/playground");
29353
29260
  const notificationService2 = useNotificationService();
29354
- const [selectedTheme, setSelectedTheme] = (0, import_react81.useState)(null);
29355
- const [themeLoading, setThemeLoading] = (0, import_react81.useState)(true);
29261
+ const [selectedTheme, setSelectedTheme] = (0, import_react82.useState)(null);
29262
+ const [themeLoading, setThemeLoading] = (0, import_react82.useState)(true);
29356
29263
  const token = authenticationService.getToken();
29357
29264
  const claims = token ? authenticationService.parseJwtClaims(token) : null;
29358
29265
  const baseTheme = registry_default[selectedTheme ?? "bandit-dark"] || banditDarkTheme;
@@ -29379,12 +29286,12 @@ var init_chat2 = __esm({
29379
29286
  } = useVoiceStore();
29380
29287
  const isVoiceModeEnabled = useVoiceModeStore((state) => state.enabled);
29381
29288
  const canvasOpen = useCanvasStore((state) => state.open);
29382
- const previousVoiceModeEnabledRef = (0, import_react81.useRef)(isVoiceModeEnabled);
29383
- const historyRef = (0, import_react81.useRef)(history);
29384
- (0, import_react81.useEffect)(() => {
29289
+ const previousVoiceModeEnabledRef = (0, import_react82.useRef)(isVoiceModeEnabled);
29290
+ const historyRef = (0, import_react82.useRef)(history);
29291
+ (0, import_react82.useEffect)(() => {
29385
29292
  historyRef.current = history;
29386
29293
  }, [history]);
29387
- (0, import_react81.useEffect)(() => {
29294
+ (0, import_react82.useEffect)(() => {
29388
29295
  if (!hydrated) return;
29389
29296
  const params = new URLSearchParams(window.location.search);
29390
29297
  const title = params.get("title") || "";
@@ -29400,7 +29307,7 @@ var init_chat2 = __esm({
29400
29307
  stop: ttsStop,
29401
29308
  isAvailable: isTTSAvailable
29402
29309
  } = useTTS();
29403
- (0, import_react81.useEffect)(() => {
29310
+ (0, import_react82.useEffect)(() => {
29404
29311
  const timer = setTimeout(() => {
29405
29312
  const isAuthenticated = authenticationService.isAuthenticated();
29406
29313
  if (!initialized || availableVoices.length === 0) {
@@ -29414,7 +29321,7 @@ var init_chat2 = __esm({
29414
29321
  }, 500);
29415
29322
  return () => clearTimeout(timer);
29416
29323
  }, [initialized, availableVoices.length, loadVoicesFromAPI, token]);
29417
- (0, import_react81.useEffect)(() => {
29324
+ (0, import_react82.useEffect)(() => {
29418
29325
  const isAuthenticated = authenticationService.isAuthenticated();
29419
29326
  if (packageSettings?.gatewayApiUrl && availableVoices.length === 0 && !initialized) {
29420
29327
  if (token && isAuthenticated) {
@@ -29426,22 +29333,22 @@ var init_chat2 = __esm({
29426
29333
  }
29427
29334
  }, [packageSettings?.gatewayApiUrl, availableVoices.length, initialized, loadVoicesFromAPI, token]);
29428
29335
  const provider = useAIProviderStore((state) => state.provider);
29429
- const inputRef = (0, import_react81.useRef)(null);
29430
- const [pastedImages, setPastedImages] = (0, import_react81.useState)([]);
29431
- const inputContainerRef = (0, import_react81.useRef)(null);
29432
- const [inputHeight, setInputHeight] = (0, import_react81.useState)(80);
29433
- const [isSubmitting, setIsSubmitting] = (0, import_react81.useState)(false);
29434
- const [pendingMessage, setPendingMessage] = (0, import_react81.useState)(null);
29336
+ const inputRef = (0, import_react82.useRef)(null);
29337
+ const [pastedImages, setPastedImages] = (0, import_react82.useState)([]);
29338
+ const inputContainerRef = (0, import_react82.useRef)(null);
29339
+ const [inputHeight, setInputHeight] = (0, import_react82.useState)(80);
29340
+ const [isSubmitting, setIsSubmitting] = (0, import_react82.useState)(false);
29341
+ const [pendingMessage, setPendingMessage] = (0, import_react82.useState)(null);
29435
29342
  const { conversations, currentId, _hasHydrated, hydrate, toggleIncognito } = useConversationStore();
29436
29343
  const isTemporaryChat = Boolean(conversations.find((c) => c.id === currentId)?.incognito);
29437
- const [isMobile, setIsMobile] = (0, import_react81.useState)(false);
29438
- const [drawerOpen, setDrawerOpen] = (0, import_react81.useState)(false);
29439
- const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react81.useState)(false);
29440
- const cardSwipeStartXRef = (0, import_react81.useRef)(null);
29441
- const dragStartRef = (0, import_react81.useRef)(null);
29442
- const [drawerDragX, setDrawerDragX] = (0, import_react81.useState)(null);
29443
- const [drawerSettling, setDrawerSettling] = (0, import_react81.useState)(false);
29444
- const [drawerSwap, setDrawerSwap] = (0, import_react81.useState)(false);
29344
+ const [isMobile, setIsMobile] = (0, import_react82.useState)(false);
29345
+ const [drawerOpen, setDrawerOpen] = (0, import_react82.useState)(false);
29346
+ const [mobileConversationsOpen, setMobileConversationsOpen] = (0, import_react82.useState)(false);
29347
+ const cardSwipeStartXRef = (0, import_react82.useRef)(null);
29348
+ const dragStartRef = (0, import_react82.useRef)(null);
29349
+ const [drawerDragX, setDrawerDragX] = (0, import_react82.useState)(null);
29350
+ const [drawerSettling, setDrawerSettling] = (0, import_react82.useState)(false);
29351
+ const [drawerSwap, setDrawerSwap] = (0, import_react82.useState)(false);
29445
29352
  const drawerOpenOffset = () => (typeof window === "undefined" ? 360 : Math.min(window.innerWidth - 56, 360)) - 12;
29446
29353
  const drawerDragStart = (e) => {
29447
29354
  const t = e.touches[0];
@@ -29501,7 +29408,7 @@ var init_chat2 = __esm({
29501
29408
  translate: `${drawerDragX}px 0`,
29502
29409
  transition: drawerSettling ? "translate 0.22s cubic-bezier(0.2, 0.8, 0.2, 1)" : "none"
29503
29410
  } : void 0;
29504
- (0, import_react81.useEffect)(() => {
29411
+ (0, import_react82.useEffect)(() => {
29505
29412
  if (typeof document === "undefined") return;
29506
29413
  const meta = document.querySelector('meta[name="theme-color"]');
29507
29414
  if (!meta) return;
@@ -29519,36 +29426,36 @@ var init_chat2 = __esm({
29519
29426
  const chatContainerEl = chatContainerRef.current;
29520
29427
  const scrollTargetEl = scrollTargetRef.current;
29521
29428
  const { isSlowConnection, connectionQuality, trackRequestStart, trackRequestEnd } = useNetworkStatus();
29522
- const [showScrollToBottom, setShowScrollToBottom] = (0, import_react81.useState)(false);
29523
- const [streamBuffer, setStreamBuffer] = (0, import_react81.useState)("");
29524
- const [responseStarted, setResponseStarted] = (0, import_react81.useState)(false);
29525
- const [isStreaming, setIsStreaming] = (0, import_react81.useState)(false);
29526
- const [isThinking, setIsThinking] = (0, import_react81.useState)(false);
29429
+ const [showScrollToBottom, setShowScrollToBottom] = (0, import_react82.useState)(false);
29430
+ const [streamBuffer, setStreamBuffer] = (0, import_react82.useState)("");
29431
+ const [responseStarted, setResponseStarted] = (0, import_react82.useState)(false);
29432
+ const [isStreaming, setIsStreaming] = (0, import_react82.useState)(false);
29433
+ const [isThinking, setIsThinking] = (0, import_react82.useState)(false);
29527
29434
  const initialLogoState = history.length === 0;
29528
- const [logoVisible, setLogoVisible] = (0, import_react81.useState)(initialLogoState);
29529
- const [logoShouldRender, setLogoShouldRender] = (0, import_react81.useState)(initialLogoState);
29530
- const streamingGraceUntilRef = (0, import_react81.useRef)(0);
29435
+ const [logoVisible, setLogoVisible] = (0, import_react82.useState)(initialLogoState);
29436
+ const [logoShouldRender, setLogoShouldRender] = (0, import_react82.useState)(initialLogoState);
29437
+ const streamingGraceUntilRef = (0, import_react82.useRef)(0);
29531
29438
  const GRACE_MS = 450;
29532
29439
  const GRACE_OFFSET_DESKTOP = 28;
29533
29440
  const GRACE_OFFSET_MOBILE = 20;
29534
- const followStreamRef = (0, import_react81.useRef)(true);
29535
- const lastSpokenResponseRef = (0, import_react81.useRef)(null);
29536
- const previousConversationIdRef = (0, import_react81.useRef)(null);
29537
- const logoFadeTimeoutRef = (0, import_react81.useRef)(null);
29538
- const [branding, setBranding] = (0, import_react81.useState)(null);
29539
- const [brandingLoading, setBrandingLoading] = (0, import_react81.useState)(true);
29540
- const isBrandingLoadInProgressRef = (0, import_react81.useRef)(false);
29441
+ const followStreamRef = (0, import_react82.useRef)(true);
29442
+ const lastSpokenResponseRef = (0, import_react82.useRef)(null);
29443
+ const previousConversationIdRef = (0, import_react82.useRef)(null);
29444
+ const logoFadeTimeoutRef = (0, import_react82.useRef)(null);
29445
+ const [branding, setBranding] = (0, import_react82.useState)(null);
29446
+ const [brandingLoading, setBrandingLoading] = (0, import_react82.useState)(true);
29447
+ const isBrandingLoadInProgressRef = (0, import_react82.useRef)(false);
29541
29448
  const logoOnly = history.length === 0 && !brandingLoading;
29542
29449
  const knowledgeDocs = useKnowledgeStore((s) => s.docs);
29543
29450
  const knowledgeLoaded = useKnowledgeStore((s) => s.isLoaded);
29544
- const [knowledgeNudgeDismissed, setKnowledgeNudgeDismissed] = (0, import_react81.useState)(() => {
29451
+ const [knowledgeNudgeDismissed, setKnowledgeNudgeDismissed] = (0, import_react82.useState)(() => {
29545
29452
  try {
29546
29453
  return localStorage.getItem("bandit.knowledgeNudge.dismissed") === "true";
29547
29454
  } catch {
29548
29455
  return false;
29549
29456
  }
29550
29457
  });
29551
- const dismissKnowledgeNudge = (0, import_react81.useCallback)(() => {
29458
+ const dismissKnowledgeNudge = (0, import_react82.useCallback)(() => {
29552
29459
  setKnowledgeNudgeDismissed(true);
29553
29460
  try {
29554
29461
  localStorage.setItem("bandit.knowledgeNudge.dismissed", "true");
@@ -29562,7 +29469,7 @@ var init_chat2 = __esm({
29562
29469
  window.location.assign(to);
29563
29470
  }
29564
29471
  };
29565
- (0, import_react81.useEffect)(() => {
29472
+ (0, import_react82.useEffect)(() => {
29566
29473
  const isEmptyConversation = (history?.length ?? 0) === 0;
29567
29474
  const isSending = Boolean(pendingMessage);
29568
29475
  const shouldShowLogo = isEmptyConversation && !isSending;
@@ -29592,7 +29499,7 @@ var init_chat2 = __esm({
29592
29499
  }, 500);
29593
29500
  }
29594
29501
  }, [history, pendingMessage]);
29595
- (0, import_react81.useEffect)(() => {
29502
+ (0, import_react82.useEffect)(() => {
29596
29503
  if (!brandingLoading && !themeLoading) {
29597
29504
  return;
29598
29505
  }
@@ -29608,18 +29515,18 @@ var init_chat2 = __esm({
29608
29515
  }, 2500);
29609
29516
  return () => window.clearTimeout(timeoutId);
29610
29517
  }, [brandingLoading, themeLoading, selectedTheme]);
29611
- (0, import_react81.useEffect)(() => () => {
29518
+ (0, import_react82.useEffect)(() => () => {
29612
29519
  if (logoFadeTimeoutRef.current) {
29613
29520
  window.clearTimeout(logoFadeTimeoutRef.current);
29614
29521
  logoFadeTimeoutRef.current = null;
29615
29522
  }
29616
29523
  }, []);
29617
- (0, import_react81.useEffect)(() => {
29524
+ (0, import_react82.useEffect)(() => {
29618
29525
  if (isStreaming && streamBuffer.trim() === "") {
29619
29526
  streamingGraceUntilRef.current = Date.now() + GRACE_MS;
29620
29527
  }
29621
29528
  }, [isStreaming, streamBuffer]);
29622
- (0, import_react81.useEffect)(() => {
29529
+ (0, import_react82.useEffect)(() => {
29623
29530
  if (!isStreaming) return;
29624
29531
  const container = chatContainerRef.current;
29625
29532
  if (!container) return;
@@ -29630,13 +29537,13 @@ var init_chat2 = __esm({
29630
29537
  container.scrollTo({ top: targetTop, behavior: "smooth" });
29631
29538
  }
29632
29539
  }, [streamBuffer, isStreaming, isMobile, chatContainerRef]);
29633
- (0, import_react81.useEffect)(() => {
29540
+ (0, import_react82.useEffect)(() => {
29634
29541
  if (!_hasHydrated) {
29635
29542
  debugLogger.info("Chat component triggering conversation store hydration");
29636
29543
  hydrate();
29637
29544
  }
29638
29545
  }, [_hasHydrated, hydrate]);
29639
- (0, import_react81.useEffect)(() => {
29546
+ (0, import_react82.useEffect)(() => {
29640
29547
  const loadBrandingAndTheme = async () => {
29641
29548
  if (isBrandingLoadInProgressRef.current) {
29642
29549
  debugLogger.warn("Branding loading already in progress, skipping");
@@ -29825,7 +29732,7 @@ var init_chat2 = __esm({
29825
29732
  window.removeEventListener("bandit-theme-changed", handleThemeChange);
29826
29733
  };
29827
29734
  }, []);
29828
- (0, import_react81.useEffect)(() => {
29735
+ (0, import_react82.useEffect)(() => {
29829
29736
  if (!chatContainerEl) return;
29830
29737
  const blurInputOnTouchScroll = () => {
29831
29738
  if (document.activeElement === inputRef.current) inputRef.current?.blur();
@@ -29833,13 +29740,13 @@ var init_chat2 = __esm({
29833
29740
  chatContainerEl.addEventListener("touchmove", blurInputOnTouchScroll, { passive: true });
29834
29741
  return () => chatContainerEl.removeEventListener("touchmove", blurInputOnTouchScroll);
29835
29742
  }, [chatContainerEl]);
29836
- (0, import_react81.useEffect)(() => {
29743
+ (0, import_react82.useEffect)(() => {
29837
29744
  const handleResize = () => setIsMobile(window.innerWidth <= 768);
29838
29745
  handleResize();
29839
29746
  window.addEventListener("resize", handleResize);
29840
29747
  return () => window.removeEventListener("resize", handleResize);
29841
29748
  }, []);
29842
- (0, import_react81.useEffect)(() => {
29749
+ (0, import_react82.useEffect)(() => {
29843
29750
  const setViewportHeight = () => {
29844
29751
  document.documentElement.style.setProperty(
29845
29752
  "--vh",
@@ -29850,7 +29757,7 @@ var init_chat2 = __esm({
29850
29757
  window.addEventListener("resize", setViewportHeight);
29851
29758
  return () => window.removeEventListener("resize", setViewportHeight);
29852
29759
  }, []);
29853
- (0, import_react81.useEffect)(() => {
29760
+ (0, import_react82.useEffect)(() => {
29854
29761
  if (!chatContainerEl) return;
29855
29762
  let rafId = null;
29856
29763
  const update = () => {
@@ -29869,7 +29776,7 @@ var init_chat2 = __esm({
29869
29776
  chatContainerEl.removeEventListener(SCROLL_STATE_CHANGED_EVENT, update);
29870
29777
  };
29871
29778
  }, [chatContainerEl, getScrollState]);
29872
- (0, import_react81.useEffect)(() => {
29779
+ (0, import_react82.useEffect)(() => {
29873
29780
  if (!chatContainerEl) return;
29874
29781
  let observer = null;
29875
29782
  let rafId = null;
@@ -29904,7 +29811,7 @@ var init_chat2 = __esm({
29904
29811
  if (observer) observer.disconnect();
29905
29812
  };
29906
29813
  }, [chatContainerEl, scrollTargetEl, scrollTargetRef, getScrollState, inputHeight, history.length]);
29907
- (0, import_react81.useEffect)(() => {
29814
+ (0, import_react82.useEffect)(() => {
29908
29815
  const isTransitioning = isStreaming || streamBuffer.trim() === "";
29909
29816
  const delay = isTransitioning ? 400 : 100;
29910
29817
  const timer = setTimeout(() => {
@@ -29913,7 +29820,7 @@ var init_chat2 = __esm({
29913
29820
  }, delay);
29914
29821
  return () => clearTimeout(timer);
29915
29822
  }, [history, streamBuffer, getScrollState, isStreaming]);
29916
- (0, import_react81.useLayoutEffect)(() => {
29823
+ (0, import_react82.useLayoutEffect)(() => {
29917
29824
  const scrollState = getScrollState();
29918
29825
  const now = Date.now();
29919
29826
  if (isStreaming && scrollState.shouldAutoScroll && followStreamRef.current) {
@@ -29947,7 +29854,7 @@ var init_chat2 = __esm({
29947
29854
  return () => clearTimeout(scrollTimer);
29948
29855
  }
29949
29856
  }, [history, isStreaming, scrollToBottom, getScrollState, isMobile, chatContainerRef]);
29950
- (0, import_react81.useEffect)(() => {
29857
+ (0, import_react82.useEffect)(() => {
29951
29858
  const observer = new ResizeObserver(() => {
29952
29859
  if (inputContainerRef.current)
29953
29860
  setInputHeight(inputContainerRef.current.offsetHeight);
@@ -29958,7 +29865,7 @@ var init_chat2 = __esm({
29958
29865
  }
29959
29866
  return () => observer.disconnect();
29960
29867
  }, []);
29961
- (0, import_react81.useEffect)(() => {
29868
+ (0, import_react82.useEffect)(() => {
29962
29869
  if (!hydrated || !_hasHydrated) return;
29963
29870
  if (currentId === null) {
29964
29871
  useAIQueryStore.setState({ history: [] });
@@ -30007,7 +29914,7 @@ var init_chat2 = __esm({
30007
29914
  setResponse,
30008
29915
  setComponentStatus
30009
29916
  ]);
30010
- (0, import_react81.useEffect)(() => {
29917
+ (0, import_react82.useEffect)(() => {
30011
29918
  debugLogger.info("Chat component conversation state", {
30012
29919
  hasHydrated: _hasHydrated,
30013
29920
  conversationCount: conversations.length,
@@ -30016,7 +29923,7 @@ var init_chat2 = __esm({
30016
29923
  storeState: "main-chat"
30017
29924
  });
30018
29925
  }, [_hasHydrated, conversations, currentId]);
30019
- (0, import_react81.useEffect)(() => {
29926
+ (0, import_react82.useEffect)(() => {
30020
29927
  if (!_hasHydrated || !chatContainerEl) return;
30021
29928
  let rafId = null;
30022
29929
  const sync = () => {
@@ -30030,8 +29937,8 @@ var init_chat2 = __esm({
30030
29937
  if (rafId) cancelAnimationFrame(rafId);
30031
29938
  };
30032
29939
  }, [_hasHydrated, chatContainerEl, getScrollState, history.length]);
30033
- const sendAckRef = (0, import_react81.useRef)(null);
30034
- const settleSendAck = (0, import_react81.useCallback)((outcome) => {
29940
+ const sendAckRef = (0, import_react82.useRef)(null);
29941
+ const settleSendAck = (0, import_react82.useCallback)((outcome) => {
30035
29942
  const ack = sendAckRef.current;
30036
29943
  if (!ack) return;
30037
29944
  sendAckRef.current = null;
@@ -30060,7 +29967,7 @@ var init_chat2 = __esm({
30060
29967
  notificationService2?.handleHttpError(error);
30061
29968
  }
30062
29969
  });
30063
- const handleStop = (0, import_react81.useCallback)(() => {
29970
+ const handleStop = (0, import_react82.useCallback)(() => {
30064
29971
  try {
30065
29972
  aiProvider.cancel();
30066
29973
  } catch (error) {
@@ -30069,7 +29976,7 @@ var init_chat2 = __esm({
30069
29976
  });
30070
29977
  }
30071
29978
  }, [aiProvider]);
30072
- const handleVoiceInterrupt = (0, import_react81.useCallback)(() => {
29979
+ const handleVoiceInterrupt = (0, import_react82.useCallback)(() => {
30073
29980
  try {
30074
29981
  ttsStop();
30075
29982
  } catch (error) {
@@ -30088,7 +29995,7 @@ var init_chat2 = __esm({
30088
29995
  handleStop();
30089
29996
  }
30090
29997
  }, [ttsStop, isStreaming, handleStop]);
30091
- const handleSend = (0, import_react81.useCallback)(
29998
+ const handleSend = (0, import_react82.useCallback)(
30092
29999
  (question, images, displayQuestion) => {
30093
30000
  sendAckRef.current?.resolve();
30094
30001
  const acknowledged = new Promise((resolve, reject) => {
@@ -30225,7 +30132,7 @@ var init_chat2 = __esm({
30225
30132
  trackRequestStart
30226
30133
  ]
30227
30134
  );
30228
- const handleVoiceTranscription = (0, import_react81.useCallback)(
30135
+ const handleVoiceTranscription = (0, import_react82.useCallback)(
30229
30136
  (text) => {
30230
30137
  const cleaned = text.trim();
30231
30138
  if (!cleaned) {
@@ -30243,7 +30150,7 @@ var init_chat2 = __esm({
30243
30150
  onInterrupt: handleVoiceInterrupt,
30244
30151
  onError: (message) => notificationService2?.showError?.(message)
30245
30152
  });
30246
- (0, import_react81.useEffect)(() => {
30153
+ (0, import_react82.useEffect)(() => {
30247
30154
  const previouslyEnabled = previousVoiceModeEnabledRef.current;
30248
30155
  previousVoiceModeEnabledRef.current = isVoiceModeEnabled;
30249
30156
  if (!previouslyEnabled && isVoiceModeEnabled) {
@@ -30268,7 +30175,7 @@ var init_chat2 = __esm({
30268
30175
  }
30269
30176
  }
30270
30177
  }, [isVoiceModeEnabled, ttsStop]);
30271
- (0, import_react81.useEffect)(() => {
30178
+ (0, import_react82.useEffect)(() => {
30272
30179
  if (!isVoiceModeEnabled || !isStreaming) {
30273
30180
  return;
30274
30181
  }
@@ -30288,7 +30195,7 @@ var init_chat2 = __esm({
30288
30195
  }
30289
30196
  lastSpokenResponseRef.current = null;
30290
30197
  }, [isStreaming, isVoiceModeEnabled, ttsStop]);
30291
- (0, import_react81.useEffect)(() => {
30198
+ (0, import_react82.useEffect)(() => {
30292
30199
  if (!isVoiceModeEnabled) {
30293
30200
  lastSpokenResponseRef.current = null;
30294
30201
  return;
@@ -30329,13 +30236,13 @@ var init_chat2 = __esm({
30329
30236
  cancelled = true;
30330
30237
  };
30331
30238
  }, [history, isStreaming, isVoiceModeEnabled, isTTSAvailable, ttsSpeak]);
30332
- const handleModelChange = (0, import_react81.useCallback)(
30239
+ const handleModelChange = (0, import_react82.useCallback)(
30333
30240
  (modelId) => {
30334
30241
  setSelectedModel(modelId);
30335
30242
  },
30336
30243
  [setSelectedModel]
30337
30244
  );
30338
- const handleVoiceChange = (0, import_react81.useCallback)(async (voiceId) => {
30245
+ const handleVoiceChange = (0, import_react82.useCallback)(async (voiceId) => {
30339
30246
  ttsStop();
30340
30247
  stopTTS();
30341
30248
  setSelectedVoice(voiceId);
@@ -30509,7 +30416,7 @@ var init_chat2 = __esm({
30509
30416
  whiteSpace: "nowrap"
30510
30417
  }),
30511
30418
  children: [
30512
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react82.Ghost, { size: 14, "aria-hidden": true }),
30419
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react83.Ghost, { size: 14, "aria-hidden": true }),
30513
30420
  "Temporary chat",
30514
30421
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
30515
30422
  import_material59.Box,
@@ -30539,7 +30446,7 @@ var init_chat2 = __esm({
30539
30446
  "@media (pointer: coarse)": { "&::after": { content: '""', position: "absolute", inset: -11 } },
30540
30447
  "&:hover": {
30541
30448
  opacity: 1,
30542
- bgcolor: (0, import_styles32.alpha)(theme.palette.getContrastText(theme.palette.text.primary), 0.16)
30449
+ bgcolor: (0, import_styles31.alpha)(theme.palette.getContrastText(theme.palette.text.primary), 0.16)
30543
30450
  }
30544
30451
  }),
30545
30452
  children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_x.X, { fontSize: "inherit", "aria-hidden": true })
@@ -30725,7 +30632,17 @@ var init_chat2 = __esm({
30725
30632
  },
30726
30633
  children: [
30727
30634
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material59.Box, { sx: { flex: "1 1 auto" } }),
30728
- history.length === 0 && componentStatus !== "Loading" && !pendingMessage && preferences.chatSuggestionsEnabled && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material59.Box, { sx: { marginBottom: "20px" }, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(QuerySuggestionPicker, { onSend: handleSend, inputHeight }) }),
30635
+ history.length === 0 && componentStatus !== "Loading" && !pendingMessage && preferences.chatSuggestionsEnabled && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_material59.Box, { sx: { marginBottom: "20px", width: "100%" }, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
30636
+ QuerySuggestionPicker,
30637
+ {
30638
+ onSend: handleSend,
30639
+ onSelect: (prompt) => {
30640
+ setInputValue(prompt);
30641
+ inputRef.current?.focus();
30642
+ },
30643
+ inputHeight
30644
+ }
30645
+ ) }),
30729
30646
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(rate_limit_prompt_default, {}),
30730
30647
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(ask_user_card_default, {}),
30731
30648
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
@@ -30800,7 +30717,7 @@ __export(management_exports, {
30800
30717
  default: () => management_default
30801
30718
  });
30802
30719
  module.exports = __toCommonJS(management_exports);
30803
- var import_react83 = require("react");
30720
+ var import_react84 = require("react");
30804
30721
  var import_useMediaQuery2 = __toESM(require("@mui/material/useMediaQuery"));
30805
30722
  init_useKnowledgeStore();
30806
30723
  init_indexedDBService();
@@ -43259,16 +43176,16 @@ var Management = ({
43259
43176
  hasTransparentLogo,
43260
43177
  setHasTransparentLogo
43261
43178
  } = useModelStore();
43262
- const [modalOpen, setModalOpen] = (0, import_react83.useState)(false);
43179
+ const [modalOpen, setModalOpen] = (0, import_react84.useState)(false);
43263
43180
  const banditHead5 = "https://cdn.burtson.ai/images/bandit-head.png";
43264
- const [fabLogo, setFabLogo] = (0, import_react83.useState)(banditHead5);
43265
- const [logoFile, setLogoFile] = (0, import_react83.useState)(null);
43266
- const [logoBase64, setLogoBase64] = (0, import_react83.useState)(null);
43267
- const [brandingText, setBrandingText] = (0, import_react83.useState)("");
43268
- const [headerMode, setHeaderMode] = (0, import_react83.useState)("logo");
43269
- const [theme, setTheme] = (0, import_react83.useState)("bandit-dark");
43270
- const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react83.useState)(null);
43271
- const [presetAvatar, setPresetAvatar] = (0, import_react83.useState)(null);
43181
+ const [fabLogo, setFabLogo] = (0, import_react84.useState)(banditHead5);
43182
+ const [logoFile, setLogoFile] = (0, import_react84.useState)(null);
43183
+ const [logoBase64, setLogoBase64] = (0, import_react84.useState)(null);
43184
+ const [brandingText, setBrandingText] = (0, import_react84.useState)("");
43185
+ const [headerMode, setHeaderMode] = (0, import_react84.useState)("logo");
43186
+ const [theme, setTheme] = (0, import_react84.useState)("bandit-dark");
43187
+ const [customAvatarBase64, setCustomAvatarBase64] = (0, import_react84.useState)(null);
43188
+ const [presetAvatar, setPresetAvatar] = (0, import_react84.useState)(null);
43272
43189
  const showSnackbarMessage = (message, severity = "success") => {
43273
43190
  if (severity === "success") {
43274
43191
  notificationService2?.showSuccess(message);
@@ -43276,15 +43193,15 @@ var Management = ({
43276
43193
  notificationService2?.showError(message);
43277
43194
  }
43278
43195
  };
43279
- const [brandingLoaded, setBrandingLoaded] = (0, import_react83.useState)(false);
43280
- const [isLoadingBranding, setIsLoadingBranding] = (0, import_react83.useState)(false);
43196
+ const [brandingLoaded, setBrandingLoaded] = (0, import_react84.useState)(false);
43197
+ const [isLoadingBranding, setIsLoadingBranding] = (0, import_react84.useState)(false);
43281
43198
  const { initModels } = useModelStore();
43282
43199
  const { settings: packageSettings } = usePackageSettingsStore();
43283
43200
  const authToken = useAuthenticationStore((state) => state.token);
43284
43201
  const { preferences, updatePreference } = usePreferencesStore();
43285
43202
  const { provider: currentProvider, config: currentProviderConfig } = useAIProviderStore();
43286
- const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react83.useState)(false);
43287
- const [localSelectedModel, setLocalSelectedModel] = (0, import_react83.useState)({
43203
+ const [seedPacksEnabled, setSeedPacksEnabled] = (0, import_react84.useState)(false);
43204
+ const [localSelectedModel, setLocalSelectedModel] = (0, import_react84.useState)({
43288
43205
  name: "",
43289
43206
  tagline: "",
43290
43207
  systemPrompt: "",
@@ -43297,7 +43214,7 @@ var Management = ({
43297
43214
  loadDocuments,
43298
43215
  clearAllDocuments
43299
43216
  } = useKnowledgeStore2();
43300
- (0, import_react83.useEffect)(() => {
43217
+ (0, import_react84.useEffect)(() => {
43301
43218
  if (selectedModel) {
43302
43219
  const selected = availableModels.find((m) => m.name === selectedModel);
43303
43220
  if (selected) {
@@ -43321,7 +43238,7 @@ var Management = ({
43321
43238
  }
43322
43239
  }
43323
43240
  }, [selectedModel, availableModels]);
43324
- const loadBrandingConfig = (0, import_react83.useCallback)(async () => {
43241
+ const loadBrandingConfig = (0, import_react84.useCallback)(async () => {
43325
43242
  if (isLoadingBranding || brandingLoaded) {
43326
43243
  debugLogger.warn("Branding loading already in progress or completed, skipping");
43327
43244
  return;
@@ -43438,15 +43355,15 @@ var Management = ({
43438
43355
  setTagline,
43439
43356
  setTheme
43440
43357
  ]);
43441
- (0, import_react83.useEffect)(() => {
43358
+ (0, import_react84.useEffect)(() => {
43442
43359
  void loadBrandingConfig();
43443
43360
  }, [loadBrandingConfig]);
43444
43361
  const handleOpenModal = () => setModalOpen(true);
43445
43362
  const handleCloseModal = () => setModalOpen(false);
43446
- (0, import_react83.useEffect)(() => {
43363
+ (0, import_react84.useEffect)(() => {
43447
43364
  getOptimalFabLogo().then(setFabLogo);
43448
43365
  }, []);
43449
- (0, import_react83.useEffect)(() => {
43366
+ (0, import_react84.useEffect)(() => {
43450
43367
  if (logoBase64) {
43451
43368
  setFabLogo(logoBase64);
43452
43369
  } else {
@@ -43904,7 +43821,7 @@ var Management = ({
43904
43821
  reader.readAsText(file);
43905
43822
  }
43906
43823
  };
43907
- (0, import_react83.useEffect)(() => {
43824
+ (0, import_react84.useEffect)(() => {
43908
43825
  if (localSelectedModel.selectedModel && !availableModels.some((m) => m.name === localSelectedModel.selectedModel)) {
43909
43826
  setLocalSelectedModel((prev) => ({
43910
43827
  ...prev,
@@ -43912,10 +43829,10 @@ var Management = ({
43912
43829
  }));
43913
43830
  }
43914
43831
  }, [availableModels, localSelectedModel.selectedModel]);
43915
- (0, import_react83.useEffect)(() => {
43832
+ (0, import_react84.useEffect)(() => {
43916
43833
  loadDocuments();
43917
43834
  }, [loadDocuments]);
43918
- (0, import_react83.useEffect)(() => {
43835
+ (0, import_react84.useEffect)(() => {
43919
43836
  const gatewayApiUrl = packageSettings?.gatewayApiUrl;
43920
43837
  if (!gatewayApiUrl || gatewayApiUrl.toLowerCase().startsWith("playground://")) {
43921
43838
  setSeedPacksEnabled(false);
@@ -43958,20 +43875,20 @@ var Management = ({
43958
43875
  isActive = false;
43959
43876
  };
43960
43877
  }, [packageSettings?.gatewayApiUrl, authToken]);
43961
- const currentTheme = (0, import_react83.useMemo)(() => createBrandingTheme(theme, { density: "compact" }), [theme]);
43962
- (0, import_react83.useEffect)(() => {
43878
+ const currentTheme = (0, import_react84.useMemo)(() => createBrandingTheme(theme, { density: "compact" }), [theme]);
43879
+ (0, import_react84.useEffect)(() => {
43963
43880
  onThemeChange?.(currentTheme);
43964
43881
  }, [currentTheme, onThemeChange]);
43965
43882
  const access = useManagementAccess();
43966
- const sections = (0, import_react83.useMemo)(
43883
+ const sections = (0, import_react84.useMemo)(
43967
43884
  () => sectionOverride ? MANAGEMENT_SECTIONS.filter((s) => sectionOverride.includes(s.id)) : access.sections,
43968
43885
  [sectionOverride, access.sections]
43969
43886
  );
43970
43887
  const defaultSection = sections.some((s) => s.id === "overview") ? "overview" : sections.some((s) => s.id === "preferences") ? "preferences" : sections[0]?.id ?? "preferences";
43971
- const [ownSection, setOwnSection] = (0, import_react83.useState)(null);
43888
+ const [ownSection, setOwnSection] = (0, import_react84.useState)(null);
43972
43889
  const requested = controlledSection ?? ownSection ?? defaultSection;
43973
43890
  const active2 = sections.some((s) => s.id === requested) ? requested : defaultSection;
43974
- const selectSection = (0, import_react83.useCallback)(
43891
+ const selectSection = (0, import_react84.useCallback)(
43975
43892
  (id) => {
43976
43893
  setOwnSection(id);
43977
43894
  onSectionChange?.(id);
@@ -43979,9 +43896,9 @@ var Management = ({
43979
43896
  [onSectionChange]
43980
43897
  );
43981
43898
  const activeDef = sectionById(active2);
43982
- const [createPersonalityRequest, setCreatePersonalityRequest] = (0, import_react83.useState)(0);
43983
- const [pendingUpload, setPendingUpload] = (0, import_react83.useState)(0);
43984
- (0, import_react83.useEffect)(() => {
43899
+ const [createPersonalityRequest, setCreatePersonalityRequest] = (0, import_react84.useState)(0);
43900
+ const [pendingUpload, setPendingUpload] = (0, import_react84.useState)(0);
43901
+ (0, import_react84.useEffect)(() => {
43985
43902
  if (!request) return;
43986
43903
  if (request.action === "create-personality") {
43987
43904
  selectSection("personalities");
@@ -43991,10 +43908,10 @@ var Management = ({
43991
43908
  setPendingUpload(request.id);
43992
43909
  }
43993
43910
  }, [request?.id]);
43994
- (0, import_react83.useEffect)(() => {
43911
+ (0, import_react84.useEffect)(() => {
43995
43912
  if (createPersonalityRequest && active2 === "personalities" && brandingLoaded) setCreatePersonalityRequest(0);
43996
43913
  }, [createPersonalityRequest, active2, brandingLoaded]);
43997
- (0, import_react83.useEffect)(() => {
43914
+ (0, import_react84.useEffect)(() => {
43998
43915
  if (!pendingUpload || active2 !== "knowledge" || !brandingLoaded) return;
43999
43916
  const frame = requestAnimationFrame(() => {
44000
43917
  document.getElementById("file-upload")?.click();
@@ -44006,9 +43923,9 @@ var Management = ({
44006
43923
  const prefSavedAt = usePreferencesStore((state) => state.lastSavedAt);
44007
43924
  const retryPreferences = usePreferencesStore((state) => state.savePreferences);
44008
43925
  const brandingValue = JSON.stringify({ logoBase64, brandingText, headerMode, theme });
44009
- const [brandingBaseline, setBrandingBaseline] = (0, import_react83.useState)(null);
44010
- const [brandingSave, setBrandingSave] = (0, import_react83.useState)("idle");
44011
- (0, import_react83.useEffect)(() => {
43926
+ const [brandingBaseline, setBrandingBaseline] = (0, import_react84.useState)(null);
43927
+ const [brandingSave, setBrandingSave] = (0, import_react84.useState)("idle");
43928
+ (0, import_react84.useEffect)(() => {
44012
43929
  if (brandingLoaded && brandingBaseline === null) setBrandingBaseline(brandingValue);
44013
43930
  }, [brandingLoaded, brandingBaseline, brandingValue]);
44014
43931
  const brandingDirty = brandingBaseline !== null && brandingBaseline !== brandingValue;
@@ -44033,7 +43950,7 @@ var Management = ({
44033
43950
  (m) => m.name === (localSelectedModel.selectedModel || localSelectedModel.name)
44034
43951
  );
44035
43952
  const personalityDirty = savedPersonality ? norm(localSelectedModel.name) !== norm(savedPersonality.name) || norm(localSelectedModel.tagline) !== norm(savedPersonality.tagline) || norm(localSelectedModel.systemPrompt) !== norm(savedPersonality.systemPrompt) : Boolean(norm(localSelectedModel.name) || norm(localSelectedModel.tagline) || norm(localSelectedModel.systemPrompt));
44036
- const [personalitySaving, setPersonalitySaving] = (0, import_react83.useState)(false);
43953
+ const [personalitySaving, setPersonalitySaving] = (0, import_react84.useState)(false);
44037
43954
  const savePersonalityFromBar = async () => {
44038
43955
  setPersonalitySaving(true);
44039
43956
  try {