@burtson-labs/bandit-engine 2.0.51 → 2.0.52

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 (36) hide show
  1. package/dist/{chat-W5IFNEUC.mjs → chat-YWYLVKXX.mjs} +5 -5
  2. package/dist/chat-provider.js +225 -8
  3. package/dist/chat-provider.js.map +1 -1
  4. package/dist/chat-provider.mjs +3 -3
  5. package/dist/{chunk-EWUUF4GE.mjs → chunk-37PEP5JK.mjs} +2 -2
  6. package/dist/{chunk-HETIHZ42.mjs → chunk-M3BEAMCC.mjs} +2 -2
  7. package/dist/{chunk-QFSEZAG6.mjs → chunk-MH7WFWCP.mjs} +34 -3
  8. package/dist/chunk-MH7WFWCP.mjs.map +1 -0
  9. package/dist/{chunk-IDH2YOW3.mjs → chunk-QX6CO7TJ.mjs} +196 -9
  10. package/dist/chunk-QX6CO7TJ.mjs.map +1 -0
  11. package/dist/{chunk-LXD3IV6Z.mjs → chunk-RSSJADDD.mjs} +3 -3
  12. package/dist/{chunk-STMXPFAQ.mjs → chunk-TSQCNHOX.mjs} +4 -4
  13. package/dist/{chunk-JBXNXSAH.mjs → chunk-Y5N3NSTU.mjs} +459 -180
  14. package/dist/chunk-Y5N3NSTU.mjs.map +1 -0
  15. package/dist/{chunk-N7RMUOFB.mjs → chunk-YZ2HJFPQ.mjs} +2 -2
  16. package/dist/cli.js +1 -1
  17. package/dist/cli.js.map +1 -1
  18. package/dist/index.js +678 -183
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.mjs +8 -8
  21. package/dist/management/management.js +648 -183
  22. package/dist/management/management.js.map +1 -1
  23. package/dist/management/management.mjs +6 -6
  24. package/dist/modals/chat-modal/chat-modal.js +197 -8
  25. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  26. package/dist/modals/chat-modal/chat-modal.mjs +3 -3
  27. package/package.json +1 -1
  28. package/dist/chunk-IDH2YOW3.mjs.map +0 -1
  29. package/dist/chunk-JBXNXSAH.mjs.map +0 -1
  30. package/dist/chunk-QFSEZAG6.mjs.map +0 -1
  31. /package/dist/{chat-W5IFNEUC.mjs.map → chat-YWYLVKXX.mjs.map} +0 -0
  32. /package/dist/{chunk-EWUUF4GE.mjs.map → chunk-37PEP5JK.mjs.map} +0 -0
  33. /package/dist/{chunk-HETIHZ42.mjs.map → chunk-M3BEAMCC.mjs.map} +0 -0
  34. /package/dist/{chunk-LXD3IV6Z.mjs.map → chunk-RSSJADDD.mjs.map} +0 -0
  35. /package/dist/{chunk-STMXPFAQ.mjs.map → chunk-TSQCNHOX.mjs.map} +0 -0
  36. /package/dist/{chunk-N7RMUOFB.mjs.map → chunk-YZ2HJFPQ.mjs.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ChatProvider,
3
3
  chat_provider_default
4
- } from "./chunk-QFSEZAG6.mjs";
4
+ } from "./chunk-MH7WFWCP.mjs";
5
5
  import "./chunk-ONQMRE2G.mjs";
6
- import "./chunk-EWUUF4GE.mjs";
6
+ import "./chunk-37PEP5JK.mjs";
7
7
  import "./chunk-EHNWQ4T3.mjs";
8
- import "./chunk-IDH2YOW3.mjs";
8
+ import "./chunk-QX6CO7TJ.mjs";
9
9
  import "./chunk-7ZDS33S2.mjs";
10
10
  import "./chunk-BENL3EF2.mjs";
11
11
  import "./chunk-KCI46M23.mjs";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  authenticationService
3
- } from "./chunk-IDH2YOW3.mjs";
3
+ } from "./chunk-QX6CO7TJ.mjs";
4
4
  import {
5
5
  indexedDBService_default,
6
6
  usePackageSettingsStore
@@ -287,4 +287,4 @@ var aiProviderInitService = AIProviderInitService.getInstance();
287
287
  export {
288
288
  aiProviderInitService
289
289
  };
290
- //# sourceMappingURL=chunk-EWUUF4GE.mjs.map
290
+ //# sourceMappingURL=chunk-37PEP5JK.mjs.map
@@ -8,7 +8,7 @@ import {
8
8
  useMemoryStore,
9
9
  useNotification,
10
10
  useVectorStore
11
- } from "./chunk-IDH2YOW3.mjs";
11
+ } from "./chunk-QX6CO7TJ.mjs";
12
12
  import {
13
13
  useModelStore,
14
14
  usePackageSettingsStore,
@@ -8922,4 +8922,4 @@ export {
8922
8922
  FeedbackButton,
8923
8923
  useNotificationService
8924
8924
  };
8925
- //# sourceMappingURL=chunk-HETIHZ42.mjs.map
8925
+ //# sourceMappingURL=chunk-M3BEAMCC.mjs.map
@@ -3,11 +3,12 @@ import {
3
3
  } from "./chunk-ONQMRE2G.mjs";
4
4
  import {
5
5
  aiProviderInitService
6
- } from "./chunk-EWUUF4GE.mjs";
6
+ } from "./chunk-37PEP5JK.mjs";
7
7
  import {
8
8
  useMCPToolsStore
9
9
  } from "./chunk-EHNWQ4T3.mjs";
10
10
  import {
11
+ AUTH_TOKEN_CHANGED_EVENT,
11
12
  FeatureFlagProvider,
12
13
  NotificationProvider,
13
14
  authenticationService,
@@ -20,7 +21,7 @@ import {
20
21
  useKnowledgeStore2,
21
22
  useMemoryStore,
22
23
  useProjectStore
23
- } from "./chunk-IDH2YOW3.mjs";
24
+ } from "./chunk-QX6CO7TJ.mjs";
24
25
  import {
25
26
  indexedDBService_default,
26
27
  useModelStore,
@@ -149,6 +150,36 @@ var ChatProvider = (props) => {
149
150
  };
150
151
  initializeAsync();
151
152
  }, [props.packageSettings, loadDocuments]);
153
+ useEffect(() => {
154
+ const isPlaygroundRoute = typeof window !== "undefined" && window.location.pathname.includes("/playground");
155
+ const isPlaygroundMode = isPlaygroundRoute || props.packageSettings.playgroundMode === true;
156
+ if (isPlaygroundMode || !props.packageSettings.gatewayApiUrl) {
157
+ return;
158
+ }
159
+ const initializeSyncState = async () => {
160
+ try {
161
+ await useConversationSyncStore.getState().initialize();
162
+ } catch (error) {
163
+ debugLogger.error("ChatProvider: deferred sync initialization failed", {
164
+ error: error instanceof Error ? error.message : String(error)
165
+ });
166
+ }
167
+ };
168
+ if (typeof window === "undefined") {
169
+ return;
170
+ }
171
+ const handleAuthTokenChange = () => {
172
+ void initializeSyncState();
173
+ };
174
+ window.addEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);
175
+ window.addEventListener("pageshow", handleAuthTokenChange);
176
+ window.addEventListener("focus", handleAuthTokenChange);
177
+ return () => {
178
+ window.removeEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);
179
+ window.removeEventListener("pageshow", handleAuthTokenChange);
180
+ window.removeEventListener("focus", handleAuthTokenChange);
181
+ };
182
+ }, [props.packageSettings.gatewayApiUrl, props.packageSettings.playgroundMode]);
152
183
  return /* @__PURE__ */ jsx(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx(FeatureFlagProvider, { config: featureFlagConfig, children: /* @__PURE__ */ jsx(NotificationProvider, { children: props.children }) }) });
153
184
  };
154
185
  var chat_provider_default = ChatProvider;
@@ -157,4 +188,4 @@ export {
157
188
  ChatProvider,
158
189
  chat_provider_default
159
190
  };
160
- //# sourceMappingURL=chunk-QFSEZAG6.mjs.map
191
+ //# sourceMappingURL=chunk-MH7WFWCP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chat-provider.tsx","../src/chat-provider.css"],"sourcesContent":["/*\n © 2025 Burtson Labs — Licensed under Business Source License 1.1\n https://burtson.ai/license\n\n This file is protected intellectual property.\n Do NOT use in commercial software, prompts, AI training data, or derivative works without a valid commercial license.\n\n 🚫 AI NOTICE: This file contains visible and invisible watermarks.\n ⚖️ VIOLATION NOTICE: Removing, modifying, or obscuring these watermarks is a license violation.\n 🔒 LICENSE TERMINATION: Upon license termination, ALL forks, copies, and derivatives must be permanently deleted.\n 📋 AUDIT TRAIL: File usage is logged and monitored for compliance verification.\n*/\n\n// Bandit Engine Watermark: BL-WM-9A05-FB9C98\nconst __banditFingerprint_chatprovidertsx = 'BL-FP-E60286-2996';\nconst __auditTrail_chatprovidertsx = 'BL-AU-MGOIKVV6-O6E4';\n// File: chat-provider.tsx | Path: src/chat-provider.tsx | Hash: 9a052996\n\nimport React, { useEffect, useState } from \"react\";\nimport { PackageSettings, usePackageSettingsStore } from \"./store/packageSettingsStore\";\nimport { AUTH_TOKEN_CHANGED_EVENT, authenticationService } from \"./services/auth/authenticationService\";\nimport { useConversationStore } from \"./store/conversationStore\";\nimport { useAIQueryStore } from \"./store/aiQueryStore\";\nimport { useMemoryStore } from \"./store/memoryStore\";\nimport { useModelStore } from \"./store/modelStore\";\nimport { usePreferencesStore } from \"./store/preferencesStore\";\nimport { useProjectStore } from \"./store/projectStore\";\nimport { useConversationSyncStore } from \"./store/conversationSyncStore\";\nimport { useKnowledgeStore } from \"./store/knowledgeStore\";\nimport { useMCPToolsStore } from \"./store/mcpToolsStore\";\nimport { useKnowledgeStore as useKnowledgeHook } from \"./chat/hooks/useKnowledgeStore\";\nimport { embeddingService } from \"./services/embedding/embeddingService\";\nimport { aiProviderInitService } from \"./services/ai-provider-init.service\";\nimport brandingService, { BrandingConfigPayload } from \"./services/branding/brandingService\";\nimport indexedDBService from \"./services/indexedDB/indexedDBService\";\nimport { debugLogger } from \"./services/logging/debugLogger\";\nimport { NotificationProvider } from \"./shared/components/NotificationProvider\";\nimport { FeatureFlagProvider } from \"./contexts/FeatureFlagContext\";\nimport { FeatureFlagConfig } from \"./types/featureFlags\";\nimport \"./chat-provider.css\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { StoredBanditConfigRecord } from \"./types/config\";\n\nexport interface ChatConfig {\n packageSettings: PackageSettings;\n /** Feature flag configuration - can override packageSettings.featureFlags */\n featureFlags?: FeatureFlagConfig;\n children?: React.ReactNode;\n}\n\nexport const ChatProvider: React.FC<ChatConfig> = (props) => {\n const { loadDocuments } = useKnowledgeHook();\n const [queryClient] = useState(() => new QueryClient());\n\n // Determine final feature flag configuration\n const featureFlagConfig: FeatureFlagConfig = {\n ...props.packageSettings.featureFlags,\n ...props.featureFlags\n };\n\n useEffect(() => {\n const initializeAsync = async () => {\n // Set package settings first\n usePackageSettingsStore.setState(() => ({\n settings: props.packageSettings,\n }));\n\n // Initialize the new AI provider system early\n try {\n await aiProviderInitService.initializeFromSettings();\n } catch (error) {\n debugLogger.error(\"Failed to initialize AI provider:\", { error });\n }\n\n const token = authenticationService.getToken();\n if (token && !authenticationService.isTokenExpired(token)) {\n authenticationService.setToken(token);\n } else {\n authenticationService.clearToken();\n }\n\n useConversationStore.getState().hydrate();\n useProjectStore.getState().hydrate();\n useAIQueryStore.getState().hydrate();\n useMemoryStore.getState().hydrate();\n \n const isPlaygroundRoute = typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\");\n const isPlaygroundMode = isPlaygroundRoute || props.packageSettings.playgroundMode === true;\n\n if (isPlaygroundMode) {\n debugLogger.info(\"ChatProvider: Playground mode detected — skipping remote preference and sync initialization\");\n } else {\n // Load preferences, knowledge docs, and MCP tools\n await usePreferencesStore.getState().loadPreferences();\n await useKnowledgeStore.getState().loadDocs();\n await useMCPToolsStore.getState().loadTools();\n await useConversationSyncStore.getState().initialize();\n }\n \n // Initialize models after AI provider is set up\n debugLogger.info(\"ChatProvider about to call initModels - checking for existing branding first\");\n \n // Get existing branding before initModels to protect user-saved branding\n const storeConfigs = [{ name: \"config\", keyPath: \"id\" }] as const;\n let existingBranding: StoredBanditConfigRecord[\"branding\"] | null = null;\n try {\n const config = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n if (config?.branding?.userSaved) {\n existingBranding = config.branding;\n debugLogger.info(\"Found user-saved branding to protect during initModels\", {\n hasText: !!existingBranding.brandingText,\n hasLogo: !!existingBranding.logoBase64,\n theme: existingBranding.theme\n });\n }\n } catch (err) {\n debugLogger.warn(\"Could not check existing branding before initModels\", { error: err });\n }\n \n await useModelStore.getState().initModels().catch((err) => {\n debugLogger.error(\"❌ Failed to initialize models:\", { error: err });\n });\n \n // Restore user branding if it was overwritten\n if (existingBranding) {\n try {\n const afterInitModels = await indexedDBService.get<StoredBanditConfigRecord>(\n \"banditConfig\",\n 1,\n \"config\",\n \"main\",\n storeConfigs\n );\n if (JSON.stringify(afterInitModels?.branding) !== JSON.stringify(existingBranding)) {\n debugLogger.warn(\"ChatProvider: initModels overwrote user branding! Restoring...\");\n await indexedDBService.put<StoredBanditConfigRecord>(\"banditConfig\", 1, \"config\", {\n ...afterInitModels,\n id: \"main\",\n branding: existingBranding,\n }, storeConfigs);\n debugLogger.info(\"ChatProvider: User branding restored after initModels\");\n }\n } catch (err) {\n debugLogger.error(\"ChatProvider: Failed to restore branding after initModels\", { error: err });\n }\n }\n\n if (props.packageSettings.brandingConfigUrl) {\n fetch(props.packageSettings.brandingConfigUrl)\n .then((res) => {\n if (!res.ok) {\n throw new Error(`HTTP error ${res.status}`);\n }\n return res.json();\n })\n .then((json: unknown) => {\n if (json && typeof json === \"object\") {\n brandingService.setBrandingFromConfig(json as BrandingConfigPayload);\n }\n })\n .catch((err) => {\n debugLogger.error(\"❌ Failed to fetch or apply branding config:\", { error: err });\n });\n }\n\n if (!isPlaygroundMode) {\n loadDocuments();\n embeddingService.backfillMissingEmbeddings().catch((err: unknown) => {\n debugLogger.error(\"❌ Failed to backfill memory embeddings:\", { error: err });\n });\n } else {\n debugLogger.info(\"ChatProvider: Playground mode skipping knowledge backfill\");\n }\n };\n\n initializeAsync();\n }, [props.packageSettings, loadDocuments]);\n\n useEffect(() => {\n const isPlaygroundRoute = typeof window !== \"undefined\" && window.location.pathname.includes(\"/playground\");\n const isPlaygroundMode = isPlaygroundRoute || props.packageSettings.playgroundMode === true;\n\n if (isPlaygroundMode || !props.packageSettings.gatewayApiUrl) {\n return;\n }\n\n const initializeSyncState = async () => {\n try {\n await useConversationSyncStore.getState().initialize();\n } catch (error) {\n debugLogger.error(\"ChatProvider: deferred sync initialization failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleAuthTokenChange = () => {\n void initializeSyncState();\n };\n\n window.addEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);\n window.addEventListener(\"pageshow\", handleAuthTokenChange);\n window.addEventListener(\"focus\", handleAuthTokenChange);\n\n return () => {\n window.removeEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);\n window.removeEventListener(\"pageshow\", handleAuthTokenChange);\n window.removeEventListener(\"focus\", handleAuthTokenChange);\n };\n }, [props.packageSettings.gatewayApiUrl, props.packageSettings.playgroundMode]);\n\n return (\n <QueryClientProvider client={queryClient}>\n <FeatureFlagProvider config={featureFlagConfig}>\n <NotificationProvider>\n {props.children}\n </NotificationProvider>\n </FeatureFlagProvider>\n </QueryClientProvider>\n );\n};\n\nexport default ChatProvider;\n","import styleInject from '#style-inject';styleInject(\"*,\\n*::before,\\n*::after {\\n box-sizing: border-box;\\n margin: 0;\\n padding: 0;\\n}\\n:root {\\n --vh: 1vh;\\n --input-offset: 1.5rem;\\n}\\nhtml {\\n height: 100%;\\n overflow: hidden;\\n scrollbar-width: none;\\n -ms-overflow-style: none;\\n}\\nhtml::-webkit-scrollbar {\\n display: none;\\n}\\nbody {\\n height: 100%;\\n overflow: auto;\\n scrollbar-width: none;\\n -ms-overflow-style: none;\\n}\\nbody::-webkit-scrollbar {\\n display: none;\\n}\\na {\\n color: inherit;\\n text-decoration: none;\\n}\\n.container {\\n max-width: 1200px;\\n margin: 0 auto;\\n padding: 2rem;\\n}\\n.mt-2 {\\n margin-top: 0.5rem;\\n}\\n.mb-2 {\\n margin-bottom: 0.5rem;\\n}\\n.mx-auto {\\n margin-left: auto;\\n margin-right: auto;\\n}\\n.bandit-logo-container {\\n display: flex;\\n height: 50vh;\\n margin: auto;\\n}\\n.bandit-logo {\\n margin: auto;\\n display: flex;\\n flex: 1 1 auto;\\n flex-direction: column;\\n align-items: center;\\n width: 90vw;\\n max-width: 640px;\\n height: 55vh;\\n background-size: cover;\\n background-position: center center;\\n background-repeat: no-repeat;\\n transition: opacity 0.6s ease-in-out, transform 0.6s ease-in-out;\\n}\\n.bandit-logo-hidden {\\n opacity: 0;\\n transform: translateY(-10px);\\n pointer-events: none;\\n}\\n.bandit-logo-visible {\\n opacity: 1;\\n transform: translateY(0);\\n}\\n\")"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,SAAgB,WAAW,gBAAgB;;;AClBH,YAAY,uxCAAuxC;;;ADwC30C,SAAS,aAAa,2BAA2B;AAwLzC;AA9KD,IAAM,eAAqC,CAAC,UAAU;AAC3D,QAAM,EAAE,cAAc,IAAIA,mBAAiB;AAC3C,QAAM,CAAC,WAAW,IAAI,SAAS,MAAM,IAAI,YAAY,CAAC;AAGtD,QAAM,oBAAuC;AAAA,IAC3C,GAAG,MAAM,gBAAgB;AAAA,IACzB,GAAG,MAAM;AAAA,EACX;AAEA,YAAU,MAAM;AACd,UAAM,kBAAkB,YAAY;AAElC,8BAAwB,SAAS,OAAO;AAAA,QACtC,UAAU,MAAM;AAAA,MAClB,EAAE;AAGF,UAAI;AACF,cAAM,sBAAsB,uBAAuB;AAAA,MACrD,SAAS,OAAO;AACd,oBAAY,MAAM,qCAAqC,EAAE,MAAM,CAAC;AAAA,MAClE;AAEA,YAAM,QAAQ,sBAAsB,SAAS;AAC7C,UAAI,SAAS,CAAC,sBAAsB,eAAe,KAAK,GAAG;AACzD,8BAAsB,SAAS,KAAK;AAAA,MACtC,OAAO;AACL,8BAAsB,WAAW;AAAA,MACnC;AAEA,2BAAqB,SAAS,EAAE,QAAQ;AACxC,sBAAgB,SAAS,EAAE,QAAQ;AACnC,sBAAgB,SAAS,EAAE,QAAQ;AACnC,qBAAe,SAAS,EAAE,QAAQ;AAElC,YAAM,oBAAoB,OAAO,WAAW,eAAe,OAAO,SAAS,SAAS,SAAS,aAAa;AAC1G,YAAM,mBAAmB,qBAAqB,MAAM,gBAAgB,mBAAmB;AAEvF,UAAI,kBAAkB;AACpB,oBAAY,KAAK,kGAA6F;AAAA,MAChH,OAAO;AAEL,cAAM,oBAAoB,SAAS,EAAE,gBAAgB;AACrD,cAAM,kBAAkB,SAAS,EAAE,SAAS;AAC5C,cAAM,iBAAiB,SAAS,EAAE,UAAU;AAC5C,cAAM,yBAAyB,SAAS,EAAE,WAAW;AAAA,MACvD;AAGA,kBAAY,KAAK,8EAA8E;AAG/F,YAAM,eAAe,CAAC,EAAE,MAAM,UAAU,SAAS,KAAK,CAAC;AACvD,UAAI,mBAAgE;AACpE,UAAI;AACF,cAAM,SAAS,MAAM,yBAAiB;AAAA,UACpC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AACA,YAAI,QAAQ,UAAU,WAAW;AAC/B,6BAAmB,OAAO;AAC1B,sBAAY,KAAK,0DAA0D;AAAA,YACzE,SAAS,CAAC,CAAC,iBAAiB;AAAA,YAC5B,SAAS,CAAC,CAAC,iBAAiB;AAAA,YAC5B,OAAO,iBAAiB;AAAA,UAC1B,CAAC;AAAA,QACH;AAAA,MACF,SAAS,KAAK;AACZ,oBAAY,KAAK,uDAAuD,EAAE,OAAO,IAAI,CAAC;AAAA,MACxF;AAEA,YAAM,cAAc,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,QAAQ;AACzD,oBAAY,MAAM,uCAAkC,EAAE,OAAO,IAAI,CAAC;AAAA,MACpE,CAAC;AAGD,UAAI,kBAAkB;AACpB,YAAI;AACF,gBAAM,kBAAkB,MAAM,yBAAiB;AAAA,YAC7C;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AACA,cAAI,KAAK,UAAU,iBAAiB,QAAQ,MAAM,KAAK,UAAU,gBAAgB,GAAG;AAClF,wBAAY,KAAK,gEAAgE;AACjF,kBAAM,yBAAiB,IAA8B,gBAAgB,GAAG,UAAU;AAAA,cAChF,GAAG;AAAA,cACH,IAAI;AAAA,cACJ,UAAU;AAAA,YACZ,GAAG,YAAY;AACf,wBAAY,KAAK,uDAAuD;AAAA,UAC1E;AAAA,QACF,SAAS,KAAK;AACZ,sBAAY,MAAM,6DAA6D,EAAE,OAAO,IAAI,CAAC;AAAA,QAC/F;AAAA,MACF;AAEA,UAAI,MAAM,gBAAgB,mBAAmB;AAC3C,cAAM,MAAM,gBAAgB,iBAAiB,EAC1C,KAAK,CAAC,QAAQ;AACb,cAAI,CAAC,IAAI,IAAI;AACX,kBAAM,IAAI,MAAM,cAAc,IAAI,MAAM,EAAE;AAAA,UAC5C;AACA,iBAAO,IAAI,KAAK;AAAA,QAClB,CAAC,EACA,KAAK,CAAC,SAAkB;AACvB,cAAI,QAAQ,OAAO,SAAS,UAAU;AACpC,oCAAgB,sBAAsB,IAA6B;AAAA,UACrE;AAAA,QACF,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,sBAAY,MAAM,oDAA+C,EAAE,OAAO,IAAI,CAAC;AAAA,QACjF,CAAC;AAAA,MACL;AAEA,UAAI,CAAC,kBAAkB;AACrB,sBAAc;AACd,yBAAiB,0BAA0B,EAAE,MAAM,CAAC,QAAiB;AACnE,sBAAY,MAAM,gDAA2C,EAAE,OAAO,IAAI,CAAC;AAAA,QAC7E,CAAC;AAAA,MACH,OAAO;AACL,oBAAY,KAAK,2DAA2D;AAAA,MAC9E;AAAA,IACF;AAEA,oBAAgB;AAAA,EAClB,GAAG,CAAC,MAAM,iBAAiB,aAAa,CAAC;AAEzC,YAAU,MAAM;AACd,UAAM,oBAAoB,OAAO,WAAW,eAAe,OAAO,SAAS,SAAS,SAAS,aAAa;AAC1G,UAAM,mBAAmB,qBAAqB,MAAM,gBAAgB,mBAAmB;AAEvF,QAAI,oBAAoB,CAAC,MAAM,gBAAgB,eAAe;AAC5D;AAAA,IACF;AAEA,UAAM,sBAAsB,YAAY;AACtC,UAAI;AACF,cAAM,yBAAyB,SAAS,EAAE,WAAW;AAAA,MACvD,SAAS,OAAO;AACd,oBAAY,MAAM,qDAAqD;AAAA,UACrE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,aAAa;AACjC;AAAA,IACF;AAEA,UAAM,wBAAwB,MAAM;AAClC,WAAK,oBAAoB;AAAA,IAC3B;AAEA,WAAO,iBAAiB,0BAA0B,qBAAqB;AACvE,WAAO,iBAAiB,YAAY,qBAAqB;AACzD,WAAO,iBAAiB,SAAS,qBAAqB;AAEtD,WAAO,MAAM;AACX,aAAO,oBAAoB,0BAA0B,qBAAqB;AAC1E,aAAO,oBAAoB,YAAY,qBAAqB;AAC5D,aAAO,oBAAoB,SAAS,qBAAqB;AAAA,IAC3D;AAAA,EACF,GAAG,CAAC,MAAM,gBAAgB,eAAe,MAAM,gBAAgB,cAAc,CAAC;AAE9E,SACE,oBAAC,uBAAoB,QAAQ,aAC3B,8BAAC,uBAAoB,QAAQ,mBAC3B,8BAAC,wBACE,gBAAM,UACT,GACF,GACF;AAEJ;AAEA,IAAO,wBAAQ;","names":["useKnowledgeStore"]}
@@ -63,6 +63,15 @@ var useAuthenticationStore = create((set) => ({
63
63
 
64
64
  // src/services/auth/authenticationService.ts
65
65
  var TOKEN_KEY2 = "authToken";
66
+ var AUTH_TOKEN_CHANGED_EVENT = "bandit:auth-token-changed";
67
+ function emitAuthTokenChanged(token) {
68
+ if (typeof window === "undefined") {
69
+ return;
70
+ }
71
+ window.dispatchEvent(new CustomEvent(AUTH_TOKEN_CHANGED_EVENT, {
72
+ detail: { token }
73
+ }));
74
+ }
66
75
  var AuthenticationService = class {
67
76
  getToken() {
68
77
  const token = localStorage.getItem(TOKEN_KEY2);
@@ -71,10 +80,12 @@ var AuthenticationService = class {
71
80
  setToken(token) {
72
81
  localStorage.setItem(TOKEN_KEY2, token);
73
82
  useAuthenticationStore.getState().setToken(token);
83
+ emitAuthTokenChanged(token);
74
84
  }
75
85
  clearToken() {
76
86
  localStorage.removeItem(TOKEN_KEY2);
77
87
  useAuthenticationStore.getState().clearToken();
88
+ emitAuthTokenChanged(null);
78
89
  }
79
90
  isAuthenticated() {
80
91
  const token = useAuthenticationStore.getState().token;
@@ -1076,9 +1087,14 @@ async function syncConversations(request) {
1076
1087
 
1077
1088
  // src/store/conversationSyncStore.ts
1078
1089
  var DEVICE_STORAGE_KEY = "banditConversationDeviceId";
1090
+ var SYNC_IDENTITY_STORAGE_KEY = "banditConversationSyncIdentity";
1079
1091
  var PAYLOAD_VERSION = 1;
1080
1092
  var MAX_CONVERSATION_BYTES = 12 * 1024 * 1024;
1081
1093
  var WARN_CONVERSATION_BYTES = 10 * 1024 * 1024;
1094
+ var PROJECT_DB_NAME = "bandit-projects";
1095
+ var PROJECT_DB_VERSION = 1;
1096
+ var PROJECT_STORE_NAME = "projects";
1097
+ var PROJECT_STORE_CONFIGS = [{ name: PROJECT_STORE_NAME, keyPath: "id" }];
1082
1098
  var suppressTracking = false;
1083
1099
  var conversationsMeta = /* @__PURE__ */ new Map();
1084
1100
  var projectsMeta = /* @__PURE__ */ new Map();
@@ -1103,9 +1119,99 @@ function ensureDeviceId() {
1103
1119
  return uuidv43();
1104
1120
  }
1105
1121
  }
1122
+ function getStoredSyncIdentity() {
1123
+ if (typeof window === "undefined") {
1124
+ return null;
1125
+ }
1126
+ try {
1127
+ return window.localStorage.getItem(SYNC_IDENTITY_STORAGE_KEY);
1128
+ } catch (error) {
1129
+ debugLogger.warn("conversationSyncStore: unable to read stored sync identity", { error });
1130
+ return null;
1131
+ }
1132
+ }
1133
+ function setStoredSyncIdentity(identity) {
1134
+ if (typeof window === "undefined") {
1135
+ return;
1136
+ }
1137
+ try {
1138
+ if (identity) {
1139
+ window.localStorage.setItem(SYNC_IDENTITY_STORAGE_KEY, identity);
1140
+ } else {
1141
+ window.localStorage.removeItem(SYNC_IDENTITY_STORAGE_KEY);
1142
+ }
1143
+ } catch (error) {
1144
+ debugLogger.warn("conversationSyncStore: unable to persist sync identity", { error });
1145
+ }
1146
+ }
1106
1147
  function getPackageDefaultAdvancedKnowledgeSync() {
1107
1148
  return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;
1108
1149
  }
1150
+ function clearAutoSyncTimer() {
1151
+ if (autoSyncTimeout) {
1152
+ clearTimeout(autoSyncTimeout);
1153
+ autoSyncTimeout = null;
1154
+ }
1155
+ }
1156
+ function resolveAuthIdentity(token) {
1157
+ if (!token) {
1158
+ return null;
1159
+ }
1160
+ const claims = authenticationService.parseJwtClaims(token);
1161
+ if (claims?.sub) {
1162
+ return claims.sub;
1163
+ }
1164
+ if (claims?.email) {
1165
+ return `email:${claims.email.toLowerCase()}`;
1166
+ }
1167
+ return `token:${token.slice(0, 32)}`;
1168
+ }
1169
+ function buildQueueResetState() {
1170
+ return {
1171
+ pendingConversationUpserts: /* @__PURE__ */ new Set(),
1172
+ pendingConversationDeletes: /* @__PURE__ */ new Set(),
1173
+ pendingProjectUpserts: /* @__PURE__ */ new Set(),
1174
+ pendingProjectDeletes: /* @__PURE__ */ new Set(),
1175
+ conflicts: null,
1176
+ lastSyncAt: null,
1177
+ cursor: null,
1178
+ lastError: null,
1179
+ totalConversationsOnServer: void 0,
1180
+ totalProjectsOnServer: void 0,
1181
+ hasCompletedInitialUpload: false,
1182
+ warningConversations: [],
1183
+ oversizedConversations: []
1184
+ };
1185
+ }
1186
+ async function clearLocalStoresForIdentitySwitch(fromIdentity, toIdentity) {
1187
+ const conversationCount = useConversationStore.getState().conversations.length;
1188
+ const projectCount = useProjectStore.getState().projects.length;
1189
+ debugLogger.warn("conversationSyncStore: auth identity changed, clearing local conversation/project cache", {
1190
+ fromIdentity,
1191
+ toIdentity,
1192
+ conversationCount,
1193
+ projectCount
1194
+ });
1195
+ suppressTracking = true;
1196
+ try {
1197
+ await useConversationStore.getState().clearAllConversations();
1198
+ await indexedDBService_default.clear(
1199
+ PROJECT_DB_NAME,
1200
+ PROJECT_DB_VERSION,
1201
+ PROJECT_STORE_NAME,
1202
+ PROJECT_STORE_CONFIGS
1203
+ );
1204
+ useProjectStore.setState({ projects: [] });
1205
+ conversationsMeta = snapshotConversationMetaMap(useConversationStore.getState().conversations);
1206
+ projectsMeta = snapshotProjectMetaMap(useProjectStore.getState().projects);
1207
+ } catch (error) {
1208
+ debugLogger.error("conversationSyncStore: failed to clear local stores on auth switch", {
1209
+ error: error instanceof Error ? error.message : String(error)
1210
+ });
1211
+ } finally {
1212
+ suppressTracking = false;
1213
+ }
1214
+ }
1109
1215
  function mapConversationToDTO(conversation) {
1110
1216
  const updatedAtIso = (conversation.updatedAt ?? /* @__PURE__ */ new Date()).toISOString();
1111
1217
  const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;
@@ -1474,6 +1580,9 @@ async function applyServerResults(response) {
1474
1580
  }
1475
1581
  var useConversationSyncStore = create6((set, get) => ({
1476
1582
  initialized: false,
1583
+ hasLoadedPreference: false,
1584
+ initializedForToken: null,
1585
+ initializedForIdentity: null,
1477
1586
  syncEnabled: false,
1478
1587
  status: "disabled",
1479
1588
  lastSyncAt: null,
@@ -1493,20 +1602,63 @@ var useConversationSyncStore = create6((set, get) => ({
1493
1602
  warningConversations: [],
1494
1603
  oversizedConversations: [],
1495
1604
  async initialize() {
1496
- if (get().initialized) {
1497
- return;
1498
- }
1499
1605
  ensureTrackersInitialized();
1500
1606
  const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
1607
+ const token = authenticationService.getToken();
1608
+ const tokenIdentity = resolveAuthIdentity(token);
1609
+ const current = get();
1610
+ const storedIdentity = getStoredSyncIdentity();
1611
+ const knownIdentity = current.initializedForIdentity ?? storedIdentity;
1612
+ if (current.initialized && current.hasLoadedPreference && knownIdentity && tokenIdentity && knownIdentity === tokenIdentity) {
1613
+ return;
1614
+ }
1615
+ const hasIdentitySwitch = Boolean(
1616
+ knownIdentity && tokenIdentity && knownIdentity !== tokenIdentity
1617
+ );
1618
+ if (hasIdentitySwitch) {
1619
+ clearAutoSyncTimer();
1620
+ set({
1621
+ ...buildQueueResetState(),
1622
+ syncEnabled: false,
1623
+ status: "disabled",
1624
+ hasLoadedPreference: false,
1625
+ initializedForToken: null,
1626
+ initializedForIdentity: tokenIdentity
1627
+ });
1628
+ await clearLocalStoresForIdentitySwitch(
1629
+ knownIdentity,
1630
+ tokenIdentity
1631
+ );
1632
+ setStoredSyncIdentity(tokenIdentity);
1633
+ }
1501
1634
  if (!gatewayUrl) {
1502
1635
  debugLogger.info("conversationSyncStore: gateway API URL not configured; sync disabled");
1503
- set({ initialized: true, status: "disabled", syncEnabled: false });
1636
+ if (tokenIdentity) {
1637
+ setStoredSyncIdentity(tokenIdentity);
1638
+ }
1639
+ set({
1640
+ ...buildQueueResetState(),
1641
+ initialized: true,
1642
+ hasLoadedPreference: false,
1643
+ initializedForToken: null,
1644
+ initializedForIdentity: tokenIdentity,
1645
+ status: "disabled",
1646
+ syncEnabled: false
1647
+ });
1504
1648
  return;
1505
1649
  }
1506
- const token = authenticationService.getToken();
1507
1650
  if (!token) {
1508
1651
  debugLogger.info("conversationSyncStore: no authentication token; sync disabled until login");
1509
- set({ initialized: true, status: "disabled", syncEnabled: false });
1652
+ clearAutoSyncTimer();
1653
+ set({
1654
+ ...buildQueueResetState(),
1655
+ initialized: true,
1656
+ hasLoadedPreference: false,
1657
+ initializedForToken: null,
1658
+ initializedForIdentity: null,
1659
+ status: "disabled",
1660
+ syncEnabled: false
1661
+ });
1510
1662
  return;
1511
1663
  }
1512
1664
  try {
@@ -1528,14 +1680,27 @@ var useConversationSyncStore = create6((set, get) => ({
1528
1680
  isAdvancedVectorFeaturesEnabled: get().isAdvancedVectorFeaturesEnabled
1529
1681
  }
1530
1682
  });
1531
- set({ initialized: true });
1683
+ set({
1684
+ initialized: true,
1685
+ hasLoadedPreference: true,
1686
+ initializedForToken: token,
1687
+ initializedForIdentity: tokenIdentity
1688
+ });
1689
+ setStoredSyncIdentity(tokenIdentity);
1532
1690
  if (preference.syncEnabled) {
1533
1691
  await get().runSync({ force: true });
1534
1692
  }
1535
1693
  } catch (error) {
1536
1694
  const message = error instanceof Error ? error.message : "Failed to load conversation sync preference";
1537
1695
  debugLogger.error("conversationSyncStore: initialization failed", { error: message });
1538
- set({ initialized: true, status: "error", lastError: message });
1696
+ set({
1697
+ initialized: true,
1698
+ hasLoadedPreference: false,
1699
+ initializedForToken: null,
1700
+ initializedForIdentity: tokenIdentity,
1701
+ status: "error",
1702
+ lastError: message
1703
+ });
1539
1704
  }
1540
1705
  },
1541
1706
  async setSyncEnabled(enabled) {
@@ -1563,6 +1728,12 @@ var useConversationSyncStore = create6((set, get) => ({
1563
1728
  isAdvancedVectorFeaturesEnabled
1564
1729
  }
1565
1730
  });
1731
+ set({
1732
+ hasLoadedPreference: true,
1733
+ initializedForToken: authenticationService.getToken(),
1734
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
1735
+ });
1736
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
1566
1737
  if (enabled) {
1567
1738
  set({ hasCompletedInitialUpload: false });
1568
1739
  }
@@ -1600,6 +1771,12 @@ var useConversationSyncStore = create6((set, get) => ({
1600
1771
  isAdvancedVectorFeaturesEnabled: enabled
1601
1772
  }
1602
1773
  });
1774
+ set({
1775
+ hasLoadedPreference: true,
1776
+ initializedForToken: authenticationService.getToken(),
1777
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
1778
+ });
1779
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
1603
1780
  if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
1604
1781
  await get().runSync({ force: true });
1605
1782
  }
@@ -1645,6 +1822,15 @@ var useConversationSyncStore = create6((set, get) => ({
1645
1822
  debugLogger.error("conversationSyncStore: runSync error - missing auth token");
1646
1823
  return;
1647
1824
  }
1825
+ const tokenIdentity = resolveAuthIdentity(token);
1826
+ if (state.initializedForIdentity && tokenIdentity && state.initializedForIdentity !== tokenIdentity) {
1827
+ debugLogger.warn("conversationSyncStore: runSync aborted due auth identity mismatch; reinitializing", {
1828
+ initializedForIdentity: state.initializedForIdentity,
1829
+ tokenIdentity
1830
+ });
1831
+ await get().initialize();
1832
+ return;
1833
+ }
1648
1834
  const pendingConversationIds = Array.from(state.pendingConversationUpserts);
1649
1835
  const pendingConversationDeleteIds = Array.from(state.pendingConversationDeletes);
1650
1836
  const pendingProjectIds = Array.from(state.pendingProjectUpserts);
@@ -5699,6 +5885,7 @@ var NotificationProvider = ({
5699
5885
 
5700
5886
  export {
5701
5887
  useAuthenticationStore,
5888
+ AUTH_TOKEN_CHANGED_EVENT,
5702
5889
  authenticationService,
5703
5890
  useAIQueryStore,
5704
5891
  sanitizeConversationName,
@@ -5737,4 +5924,4 @@ export {
5737
5924
  useNotification,
5738
5925
  NotificationProvider
5739
5926
  };
5740
- //# sourceMappingURL=chunk-IDH2YOW3.mjs.map
5927
+ //# sourceMappingURL=chunk-QX6CO7TJ.mjs.map