@burtson-labs/bandit-engine 2.0.50 → 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 (37) hide show
  1. package/dist/{chat-CQWZOJH4.mjs → chat-YWYLVKXX.mjs} +5 -5
  2. package/dist/chat-provider.js +254 -22
  3. package/dist/chat-provider.js.map +1 -1
  4. package/dist/chat-provider.mjs +3 -3
  5. package/dist/{chunk-VL3CMSDO.mjs → chunk-37PEP5JK.mjs} +2 -2
  6. package/dist/{chunk-AXFX2HUK.mjs → chunk-M3BEAMCC.mjs} +2 -2
  7. package/dist/{chunk-HKJTRBWC.mjs → chunk-MH7WFWCP.mjs} +34 -3
  8. package/dist/chunk-MH7WFWCP.mjs.map +1 -0
  9. package/dist/{chunk-6WZUQHZT.mjs → chunk-QX6CO7TJ.mjs} +225 -23
  10. package/dist/chunk-QX6CO7TJ.mjs.map +1 -0
  11. package/dist/{chunk-TVF45U7B.mjs → chunk-RSSJADDD.mjs} +3 -3
  12. package/dist/{chunk-Q2N7CCZI.mjs → chunk-TSQCNHOX.mjs} +45 -6
  13. package/dist/chunk-TSQCNHOX.mjs.map +1 -0
  14. package/dist/{chunk-ZTTGERUG.mjs → chunk-Y5N3NSTU.mjs} +459 -180
  15. package/dist/chunk-Y5N3NSTU.mjs.map +1 -0
  16. package/dist/{chunk-KHKWYHXD.mjs → chunk-YZ2HJFPQ.mjs} +2 -2
  17. package/dist/cli.js +1 -1
  18. package/dist/cli.js.map +1 -1
  19. package/dist/index.js +747 -198
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +8 -8
  22. package/dist/management/management.js +717 -198
  23. package/dist/management/management.js.map +1 -1
  24. package/dist/management/management.mjs +6 -6
  25. package/dist/modals/chat-modal/chat-modal.js +226 -22
  26. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  27. package/dist/modals/chat-modal/chat-modal.mjs +3 -3
  28. package/package.json +1 -1
  29. package/dist/chunk-6WZUQHZT.mjs.map +0 -1
  30. package/dist/chunk-HKJTRBWC.mjs.map +0 -1
  31. package/dist/chunk-Q2N7CCZI.mjs.map +0 -1
  32. package/dist/chunk-ZTTGERUG.mjs.map +0 -1
  33. /package/dist/{chat-CQWZOJH4.mjs.map → chat-YWYLVKXX.mjs.map} +0 -0
  34. /package/dist/{chunk-VL3CMSDO.mjs.map → chunk-37PEP5JK.mjs.map} +0 -0
  35. /package/dist/{chunk-AXFX2HUK.mjs.map → chunk-M3BEAMCC.mjs.map} +0 -0
  36. /package/dist/{chunk-TVF45U7B.mjs.map → chunk-RSSJADDD.mjs.map} +0 -0
  37. /package/dist/{chunk-KHKWYHXD.mjs.map → chunk-YZ2HJFPQ.mjs.map} +0 -0
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  chat_default
3
- } from "./chunk-Q2N7CCZI.mjs";
3
+ } from "./chunk-TSQCNHOX.mjs";
4
4
  import "./chunk-ONQMRE2G.mjs";
5
- import "./chunk-KHKWYHXD.mjs";
5
+ import "./chunk-YZ2HJFPQ.mjs";
6
6
  import "./chunk-EHNWQ4T3.mjs";
7
- import "./chunk-AXFX2HUK.mjs";
8
- import "./chunk-6WZUQHZT.mjs";
7
+ import "./chunk-M3BEAMCC.mjs";
8
+ import "./chunk-QX6CO7TJ.mjs";
9
9
  import "./chunk-7ZDS33S2.mjs";
10
10
  import "./chunk-BENL3EF2.mjs";
11
11
  import "./chunk-KCI46M23.mjs";
@@ -13,4 +13,4 @@ import "./chunk-BJTO5JO5.mjs";
13
13
  export {
14
14
  chat_default as default
15
15
  };
16
- //# sourceMappingURL=chat-CQWZOJH4.mjs.map
16
+ //# sourceMappingURL=chat-YWYLVKXX.mjs.map
@@ -4432,6 +4432,15 @@ var useAuthenticationStore = (0, import_zustand2.create)((set) => ({
4432
4432
  // src/services/auth/authenticationService.ts
4433
4433
  init_debugLogger();
4434
4434
  var TOKEN_KEY2 = "authToken";
4435
+ var AUTH_TOKEN_CHANGED_EVENT = "bandit:auth-token-changed";
4436
+ function emitAuthTokenChanged(token) {
4437
+ if (typeof window === "undefined") {
4438
+ return;
4439
+ }
4440
+ window.dispatchEvent(new CustomEvent(AUTH_TOKEN_CHANGED_EVENT, {
4441
+ detail: { token }
4442
+ }));
4443
+ }
4435
4444
  var AuthenticationService = class {
4436
4445
  getToken() {
4437
4446
  const token = localStorage.getItem(TOKEN_KEY2);
@@ -4440,10 +4449,12 @@ var AuthenticationService = class {
4440
4449
  setToken(token) {
4441
4450
  localStorage.setItem(TOKEN_KEY2, token);
4442
4451
  useAuthenticationStore.getState().setToken(token);
4452
+ emitAuthTokenChanged(token);
4443
4453
  }
4444
4454
  clearToken() {
4445
4455
  localStorage.removeItem(TOKEN_KEY2);
4446
4456
  useAuthenticationStore.getState().clearToken();
4457
+ emitAuthTokenChanged(null);
4447
4458
  }
4448
4459
  isAuthenticated() {
4449
4460
  const token = useAuthenticationStore.getState().token;
@@ -4493,7 +4504,18 @@ async function saveStateToDB(state) {
4493
4504
  await indexedDBService_default.put(DB_NAME, DB_VERSION, STORE_NAME, state, storeConfigs, STORAGE_KEY);
4494
4505
  }
4495
4506
  async function loadStateFromDB() {
4496
- return indexedDBService_default.get(DB_NAME, DB_VERSION, STORE_NAME, STORAGE_KEY, storeConfigs);
4507
+ let timeoutId;
4508
+ const timeoutPromise = new Promise((resolve) => {
4509
+ timeoutId = window.setTimeout(() => resolve(void 0), 1200);
4510
+ });
4511
+ try {
4512
+ const getPromise = indexedDBService_default.get(DB_NAME, DB_VERSION, STORE_NAME, STORAGE_KEY, storeConfigs).catch(() => void 0);
4513
+ return await Promise.race([getPromise, timeoutPromise]);
4514
+ } finally {
4515
+ if (timeoutId !== void 0) {
4516
+ window.clearTimeout(timeoutId);
4517
+ }
4518
+ }
4497
4519
  }
4498
4520
  var useAIQueryStore = (0, import_zustand3.create)((set, get) => ({
4499
4521
  inputValue: "",
@@ -4549,19 +4571,23 @@ var useAIQueryStore = (0, import_zustand3.create)((set, get) => ({
4549
4571
  saveStateToDB(resetState);
4550
4572
  },
4551
4573
  hydrate: async () => {
4552
- const storedState = await loadStateFromDB();
4553
- if (storedState) {
4554
- set({
4555
- inputValue: storedState.inputValue ?? "",
4556
- response: storedState.response ?? "",
4557
- previousQuestion: storedState.previousQuestion ?? "",
4558
- position: storedState.position ?? { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },
4559
- componentStatus: "Idle",
4560
- history: storedState.history ?? [],
4561
- apiKey: storedState.apiKey ?? "",
4562
- hydrated: true
4563
- });
4564
- } else {
4574
+ try {
4575
+ const storedState = await loadStateFromDB();
4576
+ if (storedState) {
4577
+ set({
4578
+ inputValue: storedState.inputValue ?? "",
4579
+ response: storedState.response ?? "",
4580
+ previousQuestion: storedState.previousQuestion ?? "",
4581
+ position: storedState.position ?? { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },
4582
+ componentStatus: "Idle",
4583
+ history: storedState.history ?? [],
4584
+ apiKey: storedState.apiKey ?? "",
4585
+ hydrated: true
4586
+ });
4587
+ } else {
4588
+ set({ hydrated: true });
4589
+ }
4590
+ } catch {
4565
4591
  set({ hydrated: true });
4566
4592
  }
4567
4593
  }
@@ -5351,6 +5377,7 @@ function emitProjectDelete(id) {
5351
5377
  var import_zustand9 = require("zustand");
5352
5378
  var import_uuid3 = require("uuid");
5353
5379
  init_packageSettingsStore();
5380
+ init_indexedDBService();
5354
5381
 
5355
5382
  // src/services/conversationSync/conversationSyncService.ts
5356
5383
  init_packageSettingsStore();
@@ -5451,9 +5478,14 @@ async function syncConversations(request) {
5451
5478
  // src/store/conversationSyncStore.ts
5452
5479
  init_debugLogger();
5453
5480
  var DEVICE_STORAGE_KEY = "banditConversationDeviceId";
5481
+ var SYNC_IDENTITY_STORAGE_KEY = "banditConversationSyncIdentity";
5454
5482
  var PAYLOAD_VERSION = 1;
5455
5483
  var MAX_CONVERSATION_BYTES = 12 * 1024 * 1024;
5456
5484
  var WARN_CONVERSATION_BYTES = 10 * 1024 * 1024;
5485
+ var PROJECT_DB_NAME = "bandit-projects";
5486
+ var PROJECT_DB_VERSION = 1;
5487
+ var PROJECT_STORE_NAME = "projects";
5488
+ var PROJECT_STORE_CONFIGS = [{ name: PROJECT_STORE_NAME, keyPath: "id" }];
5457
5489
  var suppressTracking = false;
5458
5490
  var conversationsMeta = /* @__PURE__ */ new Map();
5459
5491
  var projectsMeta = /* @__PURE__ */ new Map();
@@ -5478,9 +5510,99 @@ function ensureDeviceId() {
5478
5510
  return (0, import_uuid3.v4)();
5479
5511
  }
5480
5512
  }
5513
+ function getStoredSyncIdentity() {
5514
+ if (typeof window === "undefined") {
5515
+ return null;
5516
+ }
5517
+ try {
5518
+ return window.localStorage.getItem(SYNC_IDENTITY_STORAGE_KEY);
5519
+ } catch (error) {
5520
+ debugLogger.warn("conversationSyncStore: unable to read stored sync identity", { error });
5521
+ return null;
5522
+ }
5523
+ }
5524
+ function setStoredSyncIdentity(identity) {
5525
+ if (typeof window === "undefined") {
5526
+ return;
5527
+ }
5528
+ try {
5529
+ if (identity) {
5530
+ window.localStorage.setItem(SYNC_IDENTITY_STORAGE_KEY, identity);
5531
+ } else {
5532
+ window.localStorage.removeItem(SYNC_IDENTITY_STORAGE_KEY);
5533
+ }
5534
+ } catch (error) {
5535
+ debugLogger.warn("conversationSyncStore: unable to persist sync identity", { error });
5536
+ }
5537
+ }
5481
5538
  function getPackageDefaultAdvancedKnowledgeSync() {
5482
5539
  return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;
5483
5540
  }
5541
+ function clearAutoSyncTimer() {
5542
+ if (autoSyncTimeout) {
5543
+ clearTimeout(autoSyncTimeout);
5544
+ autoSyncTimeout = null;
5545
+ }
5546
+ }
5547
+ function resolveAuthIdentity(token) {
5548
+ if (!token) {
5549
+ return null;
5550
+ }
5551
+ const claims = authenticationService.parseJwtClaims(token);
5552
+ if (claims?.sub) {
5553
+ return claims.sub;
5554
+ }
5555
+ if (claims?.email) {
5556
+ return `email:${claims.email.toLowerCase()}`;
5557
+ }
5558
+ return `token:${token.slice(0, 32)}`;
5559
+ }
5560
+ function buildQueueResetState() {
5561
+ return {
5562
+ pendingConversationUpserts: /* @__PURE__ */ new Set(),
5563
+ pendingConversationDeletes: /* @__PURE__ */ new Set(),
5564
+ pendingProjectUpserts: /* @__PURE__ */ new Set(),
5565
+ pendingProjectDeletes: /* @__PURE__ */ new Set(),
5566
+ conflicts: null,
5567
+ lastSyncAt: null,
5568
+ cursor: null,
5569
+ lastError: null,
5570
+ totalConversationsOnServer: void 0,
5571
+ totalProjectsOnServer: void 0,
5572
+ hasCompletedInitialUpload: false,
5573
+ warningConversations: [],
5574
+ oversizedConversations: []
5575
+ };
5576
+ }
5577
+ async function clearLocalStoresForIdentitySwitch(fromIdentity, toIdentity) {
5578
+ const conversationCount = useConversationStore.getState().conversations.length;
5579
+ const projectCount = useProjectStore.getState().projects.length;
5580
+ debugLogger.warn("conversationSyncStore: auth identity changed, clearing local conversation/project cache", {
5581
+ fromIdentity,
5582
+ toIdentity,
5583
+ conversationCount,
5584
+ projectCount
5585
+ });
5586
+ suppressTracking = true;
5587
+ try {
5588
+ await useConversationStore.getState().clearAllConversations();
5589
+ await indexedDBService_default.clear(
5590
+ PROJECT_DB_NAME,
5591
+ PROJECT_DB_VERSION,
5592
+ PROJECT_STORE_NAME,
5593
+ PROJECT_STORE_CONFIGS
5594
+ );
5595
+ useProjectStore.setState({ projects: [] });
5596
+ conversationsMeta = snapshotConversationMetaMap(useConversationStore.getState().conversations);
5597
+ projectsMeta = snapshotProjectMetaMap(useProjectStore.getState().projects);
5598
+ } catch (error) {
5599
+ debugLogger.error("conversationSyncStore: failed to clear local stores on auth switch", {
5600
+ error: error instanceof Error ? error.message : String(error)
5601
+ });
5602
+ } finally {
5603
+ suppressTracking = false;
5604
+ }
5605
+ }
5484
5606
  function mapConversationToDTO(conversation) {
5485
5607
  const updatedAtIso = (conversation.updatedAt ?? /* @__PURE__ */ new Date()).toISOString();
5486
5608
  const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;
@@ -5849,6 +5971,9 @@ async function applyServerResults(response) {
5849
5971
  }
5850
5972
  var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
5851
5973
  initialized: false,
5974
+ hasLoadedPreference: false,
5975
+ initializedForToken: null,
5976
+ initializedForIdentity: null,
5852
5977
  syncEnabled: false,
5853
5978
  status: "disabled",
5854
5979
  lastSyncAt: null,
@@ -5868,20 +5993,63 @@ var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
5868
5993
  warningConversations: [],
5869
5994
  oversizedConversations: [],
5870
5995
  async initialize() {
5871
- if (get().initialized) {
5872
- return;
5873
- }
5874
5996
  ensureTrackersInitialized();
5875
5997
  const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
5998
+ const token = authenticationService.getToken();
5999
+ const tokenIdentity = resolveAuthIdentity(token);
6000
+ const current = get();
6001
+ const storedIdentity = getStoredSyncIdentity();
6002
+ const knownIdentity = current.initializedForIdentity ?? storedIdentity;
6003
+ if (current.initialized && current.hasLoadedPreference && knownIdentity && tokenIdentity && knownIdentity === tokenIdentity) {
6004
+ return;
6005
+ }
6006
+ const hasIdentitySwitch = Boolean(
6007
+ knownIdentity && tokenIdentity && knownIdentity !== tokenIdentity
6008
+ );
6009
+ if (hasIdentitySwitch) {
6010
+ clearAutoSyncTimer();
6011
+ set({
6012
+ ...buildQueueResetState(),
6013
+ syncEnabled: false,
6014
+ status: "disabled",
6015
+ hasLoadedPreference: false,
6016
+ initializedForToken: null,
6017
+ initializedForIdentity: tokenIdentity
6018
+ });
6019
+ await clearLocalStoresForIdentitySwitch(
6020
+ knownIdentity,
6021
+ tokenIdentity
6022
+ );
6023
+ setStoredSyncIdentity(tokenIdentity);
6024
+ }
5876
6025
  if (!gatewayUrl) {
5877
6026
  debugLogger.info("conversationSyncStore: gateway API URL not configured; sync disabled");
5878
- set({ initialized: true, status: "disabled", syncEnabled: false });
6027
+ if (tokenIdentity) {
6028
+ setStoredSyncIdentity(tokenIdentity);
6029
+ }
6030
+ set({
6031
+ ...buildQueueResetState(),
6032
+ initialized: true,
6033
+ hasLoadedPreference: false,
6034
+ initializedForToken: null,
6035
+ initializedForIdentity: tokenIdentity,
6036
+ status: "disabled",
6037
+ syncEnabled: false
6038
+ });
5879
6039
  return;
5880
6040
  }
5881
- const token = authenticationService.getToken();
5882
6041
  if (!token) {
5883
6042
  debugLogger.info("conversationSyncStore: no authentication token; sync disabled until login");
5884
- set({ initialized: true, status: "disabled", syncEnabled: false });
6043
+ clearAutoSyncTimer();
6044
+ set({
6045
+ ...buildQueueResetState(),
6046
+ initialized: true,
6047
+ hasLoadedPreference: false,
6048
+ initializedForToken: null,
6049
+ initializedForIdentity: null,
6050
+ status: "disabled",
6051
+ syncEnabled: false
6052
+ });
5885
6053
  return;
5886
6054
  }
5887
6055
  try {
@@ -5903,14 +6071,27 @@ var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
5903
6071
  isAdvancedVectorFeaturesEnabled: get().isAdvancedVectorFeaturesEnabled
5904
6072
  }
5905
6073
  });
5906
- set({ initialized: true });
6074
+ set({
6075
+ initialized: true,
6076
+ hasLoadedPreference: true,
6077
+ initializedForToken: token,
6078
+ initializedForIdentity: tokenIdentity
6079
+ });
6080
+ setStoredSyncIdentity(tokenIdentity);
5907
6081
  if (preference.syncEnabled) {
5908
6082
  await get().runSync({ force: true });
5909
6083
  }
5910
6084
  } catch (error) {
5911
6085
  const message = error instanceof Error ? error.message : "Failed to load conversation sync preference";
5912
6086
  debugLogger.error("conversationSyncStore: initialization failed", { error: message });
5913
- set({ initialized: true, status: "error", lastError: message });
6087
+ set({
6088
+ initialized: true,
6089
+ hasLoadedPreference: false,
6090
+ initializedForToken: null,
6091
+ initializedForIdentity: tokenIdentity,
6092
+ status: "error",
6093
+ lastError: message
6094
+ });
5914
6095
  }
5915
6096
  },
5916
6097
  async setSyncEnabled(enabled) {
@@ -5938,6 +6119,12 @@ var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
5938
6119
  isAdvancedVectorFeaturesEnabled
5939
6120
  }
5940
6121
  });
6122
+ set({
6123
+ hasLoadedPreference: true,
6124
+ initializedForToken: authenticationService.getToken(),
6125
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
6126
+ });
6127
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
5941
6128
  if (enabled) {
5942
6129
  set({ hasCompletedInitialUpload: false });
5943
6130
  }
@@ -5975,6 +6162,12 @@ var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
5975
6162
  isAdvancedVectorFeaturesEnabled: enabled
5976
6163
  }
5977
6164
  });
6165
+ set({
6166
+ hasLoadedPreference: true,
6167
+ initializedForToken: authenticationService.getToken(),
6168
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
6169
+ });
6170
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
5978
6171
  if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
5979
6172
  await get().runSync({ force: true });
5980
6173
  }
@@ -6020,6 +6213,15 @@ var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
6020
6213
  debugLogger.error("conversationSyncStore: runSync error - missing auth token");
6021
6214
  return;
6022
6215
  }
6216
+ const tokenIdentity = resolveAuthIdentity(token);
6217
+ if (state.initializedForIdentity && tokenIdentity && state.initializedForIdentity !== tokenIdentity) {
6218
+ debugLogger.warn("conversationSyncStore: runSync aborted due auth identity mismatch; reinitializing", {
6219
+ initializedForIdentity: state.initializedForIdentity,
6220
+ tokenIdentity
6221
+ });
6222
+ await get().initialize();
6223
+ return;
6224
+ }
6023
6225
  const pendingConversationIds = Array.from(state.pendingConversationUpserts);
6024
6226
  const pendingConversationDeleteIds = Array.from(state.pendingConversationDeletes);
6025
6227
  const pendingProjectIds = Array.from(state.pendingProjectUpserts);
@@ -10352,6 +10554,36 @@ var ChatProvider = (props) => {
10352
10554
  };
10353
10555
  initializeAsync();
10354
10556
  }, [props.packageSettings, loadDocuments]);
10557
+ (0, import_react6.useEffect)(() => {
10558
+ const isPlaygroundRoute = typeof window !== "undefined" && window.location.pathname.includes("/playground");
10559
+ const isPlaygroundMode = isPlaygroundRoute || props.packageSettings.playgroundMode === true;
10560
+ if (isPlaygroundMode || !props.packageSettings.gatewayApiUrl) {
10561
+ return;
10562
+ }
10563
+ const initializeSyncState = async () => {
10564
+ try {
10565
+ await useConversationSyncStore.getState().initialize();
10566
+ } catch (error) {
10567
+ debugLogger.error("ChatProvider: deferred sync initialization failed", {
10568
+ error: error instanceof Error ? error.message : String(error)
10569
+ });
10570
+ }
10571
+ };
10572
+ if (typeof window === "undefined") {
10573
+ return;
10574
+ }
10575
+ const handleAuthTokenChange = () => {
10576
+ void initializeSyncState();
10577
+ };
10578
+ window.addEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);
10579
+ window.addEventListener("pageshow", handleAuthTokenChange);
10580
+ window.addEventListener("focus", handleAuthTokenChange);
10581
+ return () => {
10582
+ window.removeEventListener(AUTH_TOKEN_CHANGED_EVENT, handleAuthTokenChange);
10583
+ window.removeEventListener("pageshow", handleAuthTokenChange);
10584
+ window.removeEventListener("focus", handleAuthTokenChange);
10585
+ };
10586
+ }, [props.packageSettings.gatewayApiUrl, props.packageSettings.playgroundMode]);
10355
10587
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_query.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(FeatureFlagProvider, { config: featureFlagConfig, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(NotificationProvider, { children: props.children }) }) });
10356
10588
  };
10357
10589
  var chat_provider_default = ChatProvider;