@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,12 +1,12 @@
1
1
  import {
2
2
  management_default
3
- } from "../chunk-ZTTGERUG.mjs";
4
- import "../chunk-KHKWYHXD.mjs";
5
- import "../chunk-VL3CMSDO.mjs";
3
+ } from "../chunk-Y5N3NSTU.mjs";
4
+ import "../chunk-YZ2HJFPQ.mjs";
5
+ import "../chunk-37PEP5JK.mjs";
6
6
  import "../chunk-EHNWQ4T3.mjs";
7
- import "../chunk-TVF45U7B.mjs";
8
- import "../chunk-AXFX2HUK.mjs";
9
- import "../chunk-6WZUQHZT.mjs";
7
+ import "../chunk-RSSJADDD.mjs";
8
+ import "../chunk-M3BEAMCC.mjs";
9
+ import "../chunk-QX6CO7TJ.mjs";
10
10
  import "../chunk-7ZDS33S2.mjs";
11
11
  import "../chunk-BENL3EF2.mjs";
12
12
  import "../chunk-KCI46M23.mjs";
@@ -7052,7 +7052,18 @@ async function saveStateToDB(state) {
7052
7052
  await indexedDBService_default.put(DB_NAME2, DB_VERSION, STORE_NAME2, state, storeConfigs2, STORAGE_KEY);
7053
7053
  }
7054
7054
  async function loadStateFromDB() {
7055
- return indexedDBService_default.get(DB_NAME2, DB_VERSION, STORE_NAME2, STORAGE_KEY, storeConfigs2);
7055
+ let timeoutId;
7056
+ const timeoutPromise = new Promise((resolve) => {
7057
+ timeoutId = window.setTimeout(() => resolve(void 0), 1200);
7058
+ });
7059
+ try {
7060
+ const getPromise = indexedDBService_default.get(DB_NAME2, DB_VERSION, STORE_NAME2, STORAGE_KEY, storeConfigs2).catch(() => void 0);
7061
+ return await Promise.race([getPromise, timeoutPromise]);
7062
+ } finally {
7063
+ if (timeoutId !== void 0) {
7064
+ window.clearTimeout(timeoutId);
7065
+ }
7066
+ }
7056
7067
  }
7057
7068
  var useAIQueryStore = (0, import_zustand6.create)((set, get) => ({
7058
7069
  inputValue: "",
@@ -7108,19 +7119,23 @@ var useAIQueryStore = (0, import_zustand6.create)((set, get) => ({
7108
7119
  saveStateToDB(resetState);
7109
7120
  },
7110
7121
  hydrate: async () => {
7111
- const storedState = await loadStateFromDB();
7112
- if (storedState) {
7113
- set({
7114
- inputValue: storedState.inputValue ?? "",
7115
- response: storedState.response ?? "",
7116
- previousQuestion: storedState.previousQuestion ?? "",
7117
- position: storedState.position ?? { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },
7118
- componentStatus: "Idle",
7119
- history: storedState.history ?? [],
7120
- apiKey: storedState.apiKey ?? "",
7121
- hydrated: true
7122
- });
7123
- } else {
7122
+ try {
7123
+ const storedState = await loadStateFromDB();
7124
+ if (storedState) {
7125
+ set({
7126
+ inputValue: storedState.inputValue ?? "",
7127
+ response: storedState.response ?? "",
7128
+ previousQuestion: storedState.previousQuestion ?? "",
7129
+ position: storedState.position ?? { x: window.innerWidth / 2 - 300, y: window.innerHeight - 350 },
7130
+ componentStatus: "Idle",
7131
+ history: storedState.history ?? [],
7132
+ apiKey: storedState.apiKey ?? "",
7133
+ hydrated: true
7134
+ });
7135
+ } else {
7136
+ set({ hydrated: true });
7137
+ }
7138
+ } catch {
7124
7139
  set({ hydrated: true });
7125
7140
  }
7126
7141
  }
@@ -7830,6 +7845,15 @@ init_packageSettingsStore();
7830
7845
  // src/services/auth/authenticationService.ts
7831
7846
  init_debugLogger();
7832
7847
  var TOKEN_KEY2 = "authToken";
7848
+ var AUTH_TOKEN_CHANGED_EVENT = "bandit:auth-token-changed";
7849
+ function emitAuthTokenChanged(token) {
7850
+ if (typeof window === "undefined") {
7851
+ return;
7852
+ }
7853
+ window.dispatchEvent(new CustomEvent(AUTH_TOKEN_CHANGED_EVENT, {
7854
+ detail: { token }
7855
+ }));
7856
+ }
7833
7857
  var AuthenticationService = class {
7834
7858
  getToken() {
7835
7859
  const token = localStorage.getItem(TOKEN_KEY2);
@@ -7838,10 +7862,12 @@ var AuthenticationService = class {
7838
7862
  setToken(token) {
7839
7863
  localStorage.setItem(TOKEN_KEY2, token);
7840
7864
  useAuthenticationStore.getState().setToken(token);
7865
+ emitAuthTokenChanged(token);
7841
7866
  }
7842
7867
  clearToken() {
7843
7868
  localStorage.removeItem(TOKEN_KEY2);
7844
7869
  useAuthenticationStore.getState().clearToken();
7870
+ emitAuthTokenChanged(null);
7845
7871
  }
7846
7872
  isAuthenticated() {
7847
7873
  const token = useAuthenticationStore.getState().token;
@@ -7875,6 +7901,9 @@ var AuthenticationService = class {
7875
7901
  };
7876
7902
  var authenticationService = new AuthenticationService();
7877
7903
 
7904
+ // src/store/conversationSyncStore.ts
7905
+ init_indexedDBService();
7906
+
7878
7907
  // src/services/conversationSync/conversationSyncService.ts
7879
7908
  init_packageSettingsStore();
7880
7909
  init_debugLogger();
@@ -7974,9 +8003,14 @@ async function syncConversations(request) {
7974
8003
  // src/store/conversationSyncStore.ts
7975
8004
  init_debugLogger();
7976
8005
  var DEVICE_STORAGE_KEY = "banditConversationDeviceId";
8006
+ var SYNC_IDENTITY_STORAGE_KEY = "banditConversationSyncIdentity";
7977
8007
  var PAYLOAD_VERSION = 1;
7978
8008
  var MAX_CONVERSATION_BYTES = 12 * 1024 * 1024;
7979
8009
  var WARN_CONVERSATION_BYTES = 10 * 1024 * 1024;
8010
+ var PROJECT_DB_NAME = "bandit-projects";
8011
+ var PROJECT_DB_VERSION = 1;
8012
+ var PROJECT_STORE_NAME = "projects";
8013
+ var PROJECT_STORE_CONFIGS = [{ name: PROJECT_STORE_NAME, keyPath: "id" }];
7980
8014
  var suppressTracking = false;
7981
8015
  var conversationsMeta = /* @__PURE__ */ new Map();
7982
8016
  var projectsMeta = /* @__PURE__ */ new Map();
@@ -8001,9 +8035,99 @@ function ensureDeviceId() {
8001
8035
  return (0, import_uuid4.v4)();
8002
8036
  }
8003
8037
  }
8038
+ function getStoredSyncIdentity() {
8039
+ if (typeof window === "undefined") {
8040
+ return null;
8041
+ }
8042
+ try {
8043
+ return window.localStorage.getItem(SYNC_IDENTITY_STORAGE_KEY);
8044
+ } catch (error) {
8045
+ debugLogger.warn("conversationSyncStore: unable to read stored sync identity", { error });
8046
+ return null;
8047
+ }
8048
+ }
8049
+ function setStoredSyncIdentity(identity) {
8050
+ if (typeof window === "undefined") {
8051
+ return;
8052
+ }
8053
+ try {
8054
+ if (identity) {
8055
+ window.localStorage.setItem(SYNC_IDENTITY_STORAGE_KEY, identity);
8056
+ } else {
8057
+ window.localStorage.removeItem(SYNC_IDENTITY_STORAGE_KEY);
8058
+ }
8059
+ } catch (error) {
8060
+ debugLogger.warn("conversationSyncStore: unable to persist sync identity", { error });
8061
+ }
8062
+ }
8004
8063
  function getPackageDefaultAdvancedKnowledgeSync() {
8005
8064
  return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;
8006
8065
  }
8066
+ function clearAutoSyncTimer() {
8067
+ if (autoSyncTimeout) {
8068
+ clearTimeout(autoSyncTimeout);
8069
+ autoSyncTimeout = null;
8070
+ }
8071
+ }
8072
+ function resolveAuthIdentity(token) {
8073
+ if (!token) {
8074
+ return null;
8075
+ }
8076
+ const claims = authenticationService.parseJwtClaims(token);
8077
+ if (claims?.sub) {
8078
+ return claims.sub;
8079
+ }
8080
+ if (claims?.email) {
8081
+ return `email:${claims.email.toLowerCase()}`;
8082
+ }
8083
+ return `token:${token.slice(0, 32)}`;
8084
+ }
8085
+ function buildQueueResetState() {
8086
+ return {
8087
+ pendingConversationUpserts: /* @__PURE__ */ new Set(),
8088
+ pendingConversationDeletes: /* @__PURE__ */ new Set(),
8089
+ pendingProjectUpserts: /* @__PURE__ */ new Set(),
8090
+ pendingProjectDeletes: /* @__PURE__ */ new Set(),
8091
+ conflicts: null,
8092
+ lastSyncAt: null,
8093
+ cursor: null,
8094
+ lastError: null,
8095
+ totalConversationsOnServer: void 0,
8096
+ totalProjectsOnServer: void 0,
8097
+ hasCompletedInitialUpload: false,
8098
+ warningConversations: [],
8099
+ oversizedConversations: []
8100
+ };
8101
+ }
8102
+ async function clearLocalStoresForIdentitySwitch(fromIdentity, toIdentity) {
8103
+ const conversationCount = useConversationStore.getState().conversations.length;
8104
+ const projectCount = useProjectStore.getState().projects.length;
8105
+ debugLogger.warn("conversationSyncStore: auth identity changed, clearing local conversation/project cache", {
8106
+ fromIdentity,
8107
+ toIdentity,
8108
+ conversationCount,
8109
+ projectCount
8110
+ });
8111
+ suppressTracking = true;
8112
+ try {
8113
+ await useConversationStore.getState().clearAllConversations();
8114
+ await indexedDBService_default.clear(
8115
+ PROJECT_DB_NAME,
8116
+ PROJECT_DB_VERSION,
8117
+ PROJECT_STORE_NAME,
8118
+ PROJECT_STORE_CONFIGS
8119
+ );
8120
+ useProjectStore.setState({ projects: [] });
8121
+ conversationsMeta = snapshotConversationMetaMap(useConversationStore.getState().conversations);
8122
+ projectsMeta = snapshotProjectMetaMap(useProjectStore.getState().projects);
8123
+ } catch (error) {
8124
+ debugLogger.error("conversationSyncStore: failed to clear local stores on auth switch", {
8125
+ error: error instanceof Error ? error.message : String(error)
8126
+ });
8127
+ } finally {
8128
+ suppressTracking = false;
8129
+ }
8130
+ }
8007
8131
  function mapConversationToDTO(conversation) {
8008
8132
  const updatedAtIso = (conversation.updatedAt ?? /* @__PURE__ */ new Date()).toISOString();
8009
8133
  const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;
@@ -8372,6 +8496,9 @@ async function applyServerResults(response) {
8372
8496
  }
8373
8497
  var useConversationSyncStore = (0, import_zustand11.create)((set, get) => ({
8374
8498
  initialized: false,
8499
+ hasLoadedPreference: false,
8500
+ initializedForToken: null,
8501
+ initializedForIdentity: null,
8375
8502
  syncEnabled: false,
8376
8503
  status: "disabled",
8377
8504
  lastSyncAt: null,
@@ -8391,20 +8518,63 @@ var useConversationSyncStore = (0, import_zustand11.create)((set, get) => ({
8391
8518
  warningConversations: [],
8392
8519
  oversizedConversations: [],
8393
8520
  async initialize() {
8394
- if (get().initialized) {
8395
- return;
8396
- }
8397
8521
  ensureTrackersInitialized();
8398
8522
  const gatewayUrl = usePackageSettingsStore.getState().settings?.gatewayApiUrl;
8523
+ const token = authenticationService.getToken();
8524
+ const tokenIdentity = resolveAuthIdentity(token);
8525
+ const current = get();
8526
+ const storedIdentity = getStoredSyncIdentity();
8527
+ const knownIdentity = current.initializedForIdentity ?? storedIdentity;
8528
+ if (current.initialized && current.hasLoadedPreference && knownIdentity && tokenIdentity && knownIdentity === tokenIdentity) {
8529
+ return;
8530
+ }
8531
+ const hasIdentitySwitch = Boolean(
8532
+ knownIdentity && tokenIdentity && knownIdentity !== tokenIdentity
8533
+ );
8534
+ if (hasIdentitySwitch) {
8535
+ clearAutoSyncTimer();
8536
+ set({
8537
+ ...buildQueueResetState(),
8538
+ syncEnabled: false,
8539
+ status: "disabled",
8540
+ hasLoadedPreference: false,
8541
+ initializedForToken: null,
8542
+ initializedForIdentity: tokenIdentity
8543
+ });
8544
+ await clearLocalStoresForIdentitySwitch(
8545
+ knownIdentity,
8546
+ tokenIdentity
8547
+ );
8548
+ setStoredSyncIdentity(tokenIdentity);
8549
+ }
8399
8550
  if (!gatewayUrl) {
8400
8551
  debugLogger.info("conversationSyncStore: gateway API URL not configured; sync disabled");
8401
- set({ initialized: true, status: "disabled", syncEnabled: false });
8552
+ if (tokenIdentity) {
8553
+ setStoredSyncIdentity(tokenIdentity);
8554
+ }
8555
+ set({
8556
+ ...buildQueueResetState(),
8557
+ initialized: true,
8558
+ hasLoadedPreference: false,
8559
+ initializedForToken: null,
8560
+ initializedForIdentity: tokenIdentity,
8561
+ status: "disabled",
8562
+ syncEnabled: false
8563
+ });
8402
8564
  return;
8403
8565
  }
8404
- const token = authenticationService.getToken();
8405
8566
  if (!token) {
8406
8567
  debugLogger.info("conversationSyncStore: no authentication token; sync disabled until login");
8407
- set({ initialized: true, status: "disabled", syncEnabled: false });
8568
+ clearAutoSyncTimer();
8569
+ set({
8570
+ ...buildQueueResetState(),
8571
+ initialized: true,
8572
+ hasLoadedPreference: false,
8573
+ initializedForToken: null,
8574
+ initializedForIdentity: null,
8575
+ status: "disabled",
8576
+ syncEnabled: false
8577
+ });
8408
8578
  return;
8409
8579
  }
8410
8580
  try {
@@ -8426,14 +8596,27 @@ var useConversationSyncStore = (0, import_zustand11.create)((set, get) => ({
8426
8596
  isAdvancedVectorFeaturesEnabled: get().isAdvancedVectorFeaturesEnabled
8427
8597
  }
8428
8598
  });
8429
- set({ initialized: true });
8599
+ set({
8600
+ initialized: true,
8601
+ hasLoadedPreference: true,
8602
+ initializedForToken: token,
8603
+ initializedForIdentity: tokenIdentity
8604
+ });
8605
+ setStoredSyncIdentity(tokenIdentity);
8430
8606
  if (preference.syncEnabled) {
8431
8607
  await get().runSync({ force: true });
8432
8608
  }
8433
8609
  } catch (error) {
8434
8610
  const message = error instanceof Error ? error.message : "Failed to load conversation sync preference";
8435
8611
  debugLogger.error("conversationSyncStore: initialization failed", { error: message });
8436
- set({ initialized: true, status: "error", lastError: message });
8612
+ set({
8613
+ initialized: true,
8614
+ hasLoadedPreference: false,
8615
+ initializedForToken: null,
8616
+ initializedForIdentity: tokenIdentity,
8617
+ status: "error",
8618
+ lastError: message
8619
+ });
8437
8620
  }
8438
8621
  },
8439
8622
  async setSyncEnabled(enabled) {
@@ -8461,6 +8644,12 @@ var useConversationSyncStore = (0, import_zustand11.create)((set, get) => ({
8461
8644
  isAdvancedVectorFeaturesEnabled
8462
8645
  }
8463
8646
  });
8647
+ set({
8648
+ hasLoadedPreference: true,
8649
+ initializedForToken: authenticationService.getToken(),
8650
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
8651
+ });
8652
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
8464
8653
  if (enabled) {
8465
8654
  set({ hasCompletedInitialUpload: false });
8466
8655
  }
@@ -8498,6 +8687,12 @@ var useConversationSyncStore = (0, import_zustand11.create)((set, get) => ({
8498
8687
  isAdvancedVectorFeaturesEnabled: enabled
8499
8688
  }
8500
8689
  });
8690
+ set({
8691
+ hasLoadedPreference: true,
8692
+ initializedForToken: authenticationService.getToken(),
8693
+ initializedForIdentity: resolveAuthIdentity(authenticationService.getToken())
8694
+ });
8695
+ setStoredSyncIdentity(resolveAuthIdentity(authenticationService.getToken()));
8501
8696
  if (preference.syncEnabled && preference.isAdvancedVectorFeaturesEnabled) {
8502
8697
  await get().runSync({ force: true });
8503
8698
  }
@@ -8543,6 +8738,15 @@ var useConversationSyncStore = (0, import_zustand11.create)((set, get) => ({
8543
8738
  debugLogger.error("conversationSyncStore: runSync error - missing auth token");
8544
8739
  return;
8545
8740
  }
8741
+ const tokenIdentity = resolveAuthIdentity(token);
8742
+ if (state.initializedForIdentity && tokenIdentity && state.initializedForIdentity !== tokenIdentity) {
8743
+ debugLogger.warn("conversationSyncStore: runSync aborted due auth identity mismatch; reinitializing", {
8744
+ initializedForIdentity: state.initializedForIdentity,
8745
+ tokenIdentity
8746
+ });
8747
+ await get().initialize();
8748
+ return;
8749
+ }
8546
8750
  const pendingConversationIds = Array.from(state.pendingConversationUpserts);
8547
8751
  const pendingConversationDeleteIds = Array.from(state.pendingConversationDeletes);
8548
8752
  const pendingProjectIds = Array.from(state.pendingProjectUpserts);