@burtson-labs/bandit-engine 2.0.21 → 2.0.23

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 (33) hide show
  1. package/dist/{chat-2Y72EFJ2.mjs → chat-VOVYLTMX.mjs} +4 -4
  2. package/dist/chat-provider.js +73 -47
  3. package/dist/chat-provider.js.map +1 -1
  4. package/dist/chat-provider.mjs +3 -3
  5. package/dist/{chunk-CY227I4F.mjs → chunk-6PQRG6W4.mjs} +3 -3
  6. package/dist/{chunk-2ZNIQD26.mjs → chunk-7RLN6ZGT.mjs} +53 -48
  7. package/dist/chunk-7RLN6ZGT.mjs.map +1 -0
  8. package/dist/{chunk-XEG45Q6V.mjs → chunk-GBANNFRD.mjs} +2 -2
  9. package/dist/{chunk-JECYIAWF.mjs → chunk-JTZL6WJJ.mjs} +6 -6
  10. package/dist/{chunk-L7UOQ2Y2.mjs → chunk-LG2JCTOE.mjs} +3 -3
  11. package/dist/{chunk-UMPVXYVC.mjs → chunk-XD5VJCFN.mjs} +23 -2
  12. package/dist/chunk-XD5VJCFN.mjs.map +1 -0
  13. package/dist/{chunk-6V2YMAX2.mjs → chunk-ZRTP2N7E.mjs} +74 -24
  14. package/dist/{chunk-6V2YMAX2.mjs.map → chunk-ZRTP2N7E.mjs.map} +1 -1
  15. package/dist/cli/cli.js +1 -1
  16. package/dist/cli/cli.js.map +1 -1
  17. package/dist/index.js +140 -65
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +7 -7
  20. package/dist/management/management.js +140 -65
  21. package/dist/management/management.js.map +1 -1
  22. package/dist/management/management.mjs +5 -5
  23. package/dist/modals/chat-modal/chat-modal.js +22 -1
  24. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  25. package/dist/modals/chat-modal/chat-modal.mjs +3 -3
  26. package/package.json +1 -1
  27. package/dist/chunk-2ZNIQD26.mjs.map +0 -1
  28. package/dist/chunk-UMPVXYVC.mjs.map +0 -1
  29. /package/dist/{chat-2Y72EFJ2.mjs.map → chat-VOVYLTMX.mjs.map} +0 -0
  30. /package/dist/{chunk-CY227I4F.mjs.map → chunk-6PQRG6W4.mjs.map} +0 -0
  31. /package/dist/{chunk-XEG45Q6V.mjs.map → chunk-GBANNFRD.mjs.map} +0 -0
  32. /package/dist/{chunk-JECYIAWF.mjs.map → chunk-JTZL6WJJ.mjs.map} +0 -0
  33. /package/dist/{chunk-L7UOQ2Y2.mjs.map → chunk-LG2JCTOE.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -1,24 +1,24 @@
1
1
  import {
2
2
  chat_default
3
- } from "./chunk-6V2YMAX2.mjs";
3
+ } from "./chunk-ZRTP2N7E.mjs";
4
4
  import {
5
5
  chat_provider_default
6
- } from "./chunk-CY227I4F.mjs";
6
+ } from "./chunk-6PQRG6W4.mjs";
7
7
  import "./chunk-ONQMRE2G.mjs";
8
8
  import {
9
9
  management_default,
10
10
  useGatewayHealth,
11
11
  useGatewayMemory,
12
12
  useGatewayModels
13
- } from "./chunk-JECYIAWF.mjs";
14
- import "./chunk-2ZNIQD26.mjs";
13
+ } from "./chunk-JTZL6WJJ.mjs";
14
+ import "./chunk-7RLN6ZGT.mjs";
15
15
  import "./chunk-RTQDQ6TC.mjs";
16
16
  import {
17
17
  defineCustomElement
18
18
  } from "./chunk-IXIM7BNO.mjs";
19
19
  import {
20
20
  chat_modal_default
21
- } from "./chunk-L7UOQ2Y2.mjs";
21
+ } from "./chunk-LG2JCTOE.mjs";
22
22
  import {
23
23
  FeedbackButton,
24
24
  FeedbackModal,
@@ -36,7 +36,7 @@ import {
36
36
  useTTS,
37
37
  useVoiceStore,
38
38
  voiceService
39
- } from "./chunk-XEG45Q6V.mjs";
39
+ } from "./chunk-GBANNFRD.mjs";
40
40
  import {
41
41
  DEFAULT_TIER_FEATURES,
42
42
  FeatureFlagContext,
@@ -56,7 +56,7 @@ import {
56
56
  useVectorStore,
57
57
  vectorDatabaseService,
58
58
  vectorMigrationService
59
- } from "./chunk-UMPVXYVC.mjs";
59
+ } from "./chunk-XD5VJCFN.mjs";
60
60
  import {
61
61
  usePackageSettingsStore
62
62
  } from "./chunk-XUBYA5I7.mjs";
@@ -6796,13 +6796,27 @@ var init_conversationStore = __esm({
6796
6796
  });
6797
6797
  },
6798
6798
  deleteConversation: (id) => {
6799
+ const runHydrate = async () => {
6800
+ try {
6801
+ await get().hydrate();
6802
+ } catch (error) {
6803
+ debugLogger.warn("conversationStore: rehydrate after delete failed", {
6804
+ error: error instanceof Error ? error.message : String(error)
6805
+ });
6806
+ }
6807
+ };
6799
6808
  set((state) => {
6800
6809
  const filtered = state.conversations.filter((c) => c.id !== id);
6801
6810
  const isDeletingCurrent = state.currentId === id;
6802
6811
  if (isDeletingCurrent) {
6803
6812
  useAIQueryStore.getState().reset();
6804
6813
  }
6805
- deleteConversationFromDB(id);
6814
+ deleteConversationFromDB(id).then(runHydrate).catch((error) => {
6815
+ debugLogger.error("Failed to delete conversation from DB", {
6816
+ error,
6817
+ conversationId: id
6818
+ });
6819
+ });
6806
6820
  emitConversationDelete(id);
6807
6821
  return {
6808
6822
  conversations: filtered,
@@ -6972,6 +6986,13 @@ var init_conversationStore = __esm({
6972
6986
  currentId: isCurrentDeleted ? null : state.currentId
6973
6987
  };
6974
6988
  });
6989
+ try {
6990
+ await get().hydrate();
6991
+ } catch (error) {
6992
+ debugLogger.warn("conversationStore: hydrate failed after remote delete", {
6993
+ error: error instanceof Error ? error.message : String(error)
6994
+ });
6995
+ }
6975
6996
  }
6976
6997
  }));
6977
6998
  }
@@ -24635,6 +24656,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
24635
24656
  const [moveModalOpen, setMoveModalOpen] = (0, import_react49.useState)(false);
24636
24657
  const [conversationToMove, setConversationToMove] = (0, import_react49.useState)(null);
24637
24658
  const [renameProjectId, setRenameProjectId] = (0, import_react49.useState)(null);
24659
+ const [deletedConversationIds, setDeletedConversationIds] = (0, import_react49.useState)(/* @__PURE__ */ new Set());
24638
24660
  const [touchDragState, setTouchDragState] = (0, import_react49.useState)({ conversationId: null, originProjectId: null, hoverProjectId: null });
24639
24661
  const [avatarImage, setAvatarImage] = (0, import_react49.useState)(BANDIT_AVATAR2);
24640
24662
  const getCustomClaim = (0, import_react49.useCallback)((key) => {
@@ -24706,20 +24728,19 @@ var init_enhanced_mobile_conversations_modal = __esm({
24706
24728
  }
24707
24729
  }, [projectsHydrated, projects]);
24708
24730
  const projectGroups = (0, import_react49.useMemo)(() => {
24709
- const groups = [];
24710
- projects.forEach((project) => {
24711
- const projectConversations = getConversationsByProject(project.id).map((conversation) => ({
24731
+ const visibleConversations = conversations.filter(
24732
+ (conversation) => !deletedConversationIds.has(conversation.id)
24733
+ );
24734
+ const groups = projects.map((project) => ({
24735
+ id: project.id,
24736
+ name: project.name,
24737
+ color: project.color,
24738
+ conversations: visibleConversations.filter((conversation) => conversation.projectId === project.id).map((conversation) => ({
24712
24739
  ...conversation
24713
- }));
24714
- groups.push({
24715
- id: project.id,
24716
- name: project.name,
24717
- color: project.color,
24718
- conversations: projectConversations,
24719
- collapsed: collapsedProjects.has(project.id)
24720
- });
24721
- });
24722
- const ungroupedConversations = getConversationsByProject(null).map((conversation) => ({
24740
+ })),
24741
+ collapsed: collapsedProjects.has(project.id)
24742
+ }));
24743
+ const ungroupedConversations = visibleConversations.filter((conversation) => !conversation.projectId).map((conversation) => ({
24723
24744
  ...conversation
24724
24745
  }));
24725
24746
  if (ungroupedConversations.length > 0) {
@@ -24728,11 +24749,14 @@ var init_enhanced_mobile_conversations_modal = __esm({
24728
24749
  name: "Ungrouped",
24729
24750
  conversations: ungroupedConversations,
24730
24751
  collapsed: false
24731
- // Never collapsed for ungrouped
24732
24752
  });
24733
24753
  }
24734
24754
  return groups.filter((group) => group.conversations.length > 0 || group.id !== null);
24735
- }, [projects, getConversationsByProject, collapsedProjects]);
24755
+ }, [projects, conversations, collapsedProjects, deletedConversationIds]);
24756
+ const visibleConversationCount = (0, import_react49.useMemo)(
24757
+ () => projectGroups.reduce((total, group) => total + group.conversations.length, 0),
24758
+ [projectGroups]
24759
+ );
24736
24760
  const filteredProjectGroups = (0, import_react49.useMemo)(() => {
24737
24761
  if (!searchQuery.trim()) return projectGroups;
24738
24762
  const query = searchQuery.toLowerCase();
@@ -24843,6 +24867,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
24843
24867
  };
24844
24868
  const handleClearAllConfirm = async () => {
24845
24869
  try {
24870
+ setDeletedConversationIds(new Set(conversations.map((conv) => conv.id)));
24846
24871
  await clearAllConversations();
24847
24872
  setClearConfirmOpen(false);
24848
24873
  handleMenuClose();
@@ -24861,6 +24886,21 @@ var init_enhanced_mobile_conversations_modal = __esm({
24861
24886
  setMoveModalOpen(false);
24862
24887
  setConversationToMove(null);
24863
24888
  };
24889
+ (0, import_react49.useEffect)(() => {
24890
+ setDeletedConversationIds((prev) => {
24891
+ let changed = false;
24892
+ const active = new Set(conversations.map((conv) => conv.id));
24893
+ const next = /* @__PURE__ */ new Set();
24894
+ prev.forEach((id) => {
24895
+ if (active.has(id)) {
24896
+ next.add(id);
24897
+ } else {
24898
+ changed = true;
24899
+ }
24900
+ });
24901
+ return changed ? next : prev;
24902
+ });
24903
+ }, [conversations]);
24864
24904
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
24865
24905
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
24866
24906
  import_material38.Modal,
@@ -24897,6 +24937,19 @@ var init_enhanced_mobile_conversations_modal = __esm({
24897
24937
  },
24898
24938
  children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_material38.Toolbar, { children: [
24899
24939
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.Typography, { variant: "h6", sx: { flex: 1, fontWeight: 600 }, children: "Conversations" }),
24940
+ visibleConversationCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
24941
+ import_material38.Chip,
24942
+ {
24943
+ label: visibleConversationCount,
24944
+ size: "small",
24945
+ sx: {
24946
+ mr: 1,
24947
+ bgcolor: theme.palette.mode === "dark" ? "rgba(148, 163, 184, 0.16)" : "rgba(15, 23, 42, 0.08)",
24948
+ color: theme.palette.text.secondary,
24949
+ fontWeight: 600
24950
+ }
24951
+ }
24952
+ ),
24900
24953
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
24901
24954
  import_material38.IconButton,
24902
24955
  {
@@ -25207,7 +25260,15 @@ var init_enhanced_mobile_conversations_modal = __esm({
25207
25260
  switchConversation(conversation.id);
25208
25261
  onClose();
25209
25262
  },
25210
- onDelete: () => deleteConversation(conversation.id),
25263
+ onDelete: () => {
25264
+ setDeletedConversationIds((prev) => {
25265
+ if (prev.has(conversation.id)) return prev;
25266
+ const next = new Set(prev);
25267
+ next.add(conversation.id);
25268
+ return next;
25269
+ });
25270
+ deleteConversation(conversation.id);
25271
+ },
25211
25272
  onRename: (newName) => renameConversation(conversation.id, newName),
25212
25273
  onMove: () => handleMoveConversation(conversation),
25213
25274
  projectColor: group.color,
@@ -25250,7 +25311,15 @@ var init_enhanced_mobile_conversations_modal = __esm({
25250
25311
  switchConversation(conversation.id);
25251
25312
  onClose();
25252
25313
  },
25253
- onDelete: () => deleteConversation(conversation.id),
25314
+ onDelete: () => {
25315
+ setDeletedConversationIds((prev) => {
25316
+ if (prev.has(conversation.id)) return prev;
25317
+ const next = new Set(prev);
25318
+ next.add(conversation.id);
25319
+ return next;
25320
+ });
25321
+ deleteConversation(conversation.id);
25322
+ },
25254
25323
  onRename: (newName) => renameConversation(conversation.id, newName),
25255
25324
  onMove: () => handleMoveConversation(conversation),
25256
25325
  projectColor: group.color,
@@ -25396,6 +25465,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25396
25465
  setClearConfirmOpen(true);
25397
25466
  handleMenuClose();
25398
25467
  },
25468
+ disabled: visibleConversationCount === 0,
25399
25469
  sx: { color: theme.palette.error.main },
25400
25470
  children: [
25401
25471
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.ListItemIcon, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_icons_material11.DeleteSweep, { fontSize: "small", sx: { color: theme.palette.error.main } }) }),
@@ -25414,7 +25484,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
25414
25484
  fullWidth: true,
25415
25485
  children: [
25416
25486
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.DialogTitle, { children: "Clear All Conversations?" }),
25417
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.DialogContent, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.Typography, { children: "This will permanently delete all conversations and cannot be undone. Are you sure you want to continue?" }) }),
25487
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.DialogContent, { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.Typography, { children: visibleConversationCount === 0 ? "No conversations available to clear." : `This will permanently delete ${visibleConversationCount} conversation${visibleConversationCount === 1 ? "" : "s"} and cannot be undone.` }) }),
25418
25488
  /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_material38.DialogActions, { children: [
25419
25489
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_material38.Button, { onClick: () => setClearConfirmOpen(false), children: "Cancel" }),
25420
25490
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
@@ -37504,58 +37574,63 @@ var AIProviderInitService = class _AIProviderInitService {
37504
37574
  hasAiProvider: !!settings.aiProvider,
37505
37575
  ollamaUrl: settings.ollamaUrl
37506
37576
  });
37507
- try {
37508
- const savedConfig = await indexedDBService_default.get(
37509
- "banditConfig",
37510
- 1,
37511
- "config",
37512
- "aiProvider",
37513
- [{ name: "config", keyPath: "id" }]
37514
- );
37515
- if (savedConfig) {
37516
- debugLogger.info("AI Provider Init: Found saved config in IndexedDB", { type: savedConfig.type });
37517
- const { id: _id, ...configWithoutId } = savedConfig;
37518
- providerConfig = { ...configWithoutId };
37519
- if ((providerConfig.type === "ollama" /* OLLAMA */ || providerConfig.type === "gateway" /* GATEWAY */) && !providerConfig.tokenFactory) {
37520
- providerConfig.tokenFactory = () => {
37521
- let token = authenticationService.getToken();
37522
- if (!token) {
37523
- token = localStorage.getItem("authToken");
37524
- }
37525
- if (!token) {
37577
+ const isPlaygroundEnvironment = settings.playgroundMode === true || settings.aiProvider?.type === "playground" /* PLAYGROUND */ || (settings.gatewayApiUrl?.toLowerCase()?.startsWith("playground://") ?? false) || typeof window !== "undefined" && window.location.pathname.includes("/playground");
37578
+ if (isPlaygroundEnvironment) {
37579
+ debugLogger.info("AI Provider Init: Playground environment detected, bypassing saved provider config");
37580
+ } else {
37581
+ try {
37582
+ const savedConfig = await indexedDBService_default.get(
37583
+ "banditConfig",
37584
+ 1,
37585
+ "config",
37586
+ "aiProvider",
37587
+ [{ name: "config", keyPath: "id" }]
37588
+ );
37589
+ if (savedConfig) {
37590
+ debugLogger.info("AI Provider Init: Found saved config in IndexedDB", { type: savedConfig.type });
37591
+ const { id: _id, ...configWithoutId } = savedConfig;
37592
+ providerConfig = { ...configWithoutId };
37593
+ if ((providerConfig.type === "ollama" /* OLLAMA */ || providerConfig.type === "gateway" /* GATEWAY */) && !providerConfig.tokenFactory) {
37594
+ providerConfig.tokenFactory = () => {
37595
+ let token = authenticationService.getToken();
37596
+ if (!token) {
37597
+ token = localStorage.getItem("authToken");
37598
+ }
37599
+ if (!token) {
37600
+ try {
37601
+ const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
37602
+ const authStore = useAuthenticationStore2.getState();
37603
+ token = authStore.token;
37604
+ } catch (e) {
37605
+ }
37606
+ }
37607
+ debugLogger.info("AI Provider Init: IndexedDB config token factory", {
37608
+ hasToken: !!token
37609
+ });
37610
+ return token;
37611
+ };
37612
+ }
37613
+ try {
37614
+ const { createProvider } = useAIProviderStore.getState();
37615
+ createProvider(providerConfig);
37616
+ const provider = useAIProviderStore.getState().provider;
37617
+ if (provider) {
37526
37618
  try {
37527
- const { useAuthenticationStore: useAuthenticationStore2 } = require("../../store/authenticationStore");
37528
- const authStore = useAuthenticationStore2.getState();
37529
- token = authStore.token;
37530
- } catch (e) {
37619
+ await provider.validateServiceAvailability({ timeoutMs: 5e3 });
37620
+ debugLogger.info(`AI Provider initialized and validated from IndexedDB: ${providerConfig.type}`);
37621
+ } catch (validationError) {
37622
+ debugLogger.warn(`AI Provider created but validation failed`, { error: validationError });
37531
37623
  }
37532
37624
  }
37533
- debugLogger.info("AI Provider Init: IndexedDB config token factory", {
37534
- hasToken: !!token
37535
- });
37536
- return token;
37537
- };
37538
- }
37539
- try {
37540
- const { createProvider } = useAIProviderStore.getState();
37541
- createProvider(providerConfig);
37542
- const provider = useAIProviderStore.getState().provider;
37543
- if (provider) {
37544
- try {
37545
- await provider.validateServiceAvailability({ timeoutMs: 5e3 });
37546
- debugLogger.info(`AI Provider initialized and validated from IndexedDB: ${providerConfig.type}`);
37547
- } catch (validationError) {
37548
- debugLogger.warn(`AI Provider created but validation failed`, { error: validationError });
37549
- }
37625
+ return;
37626
+ } catch (error) {
37627
+ debugLogger.error("Failed to initialize saved provider config, falling back to package settings", { error });
37550
37628
  }
37551
- return;
37552
- } catch (error) {
37553
- debugLogger.error("Failed to initialize saved provider config, falling back to package settings", { error });
37554
37629
  }
37630
+ debugLogger.info("AI Provider Init: No saved config found, using package settings");
37631
+ } catch (error) {
37632
+ debugLogger.warn("AI Provider Init: Failed to load from IndexedDB, using package settings", { error });
37555
37633
  }
37556
- debugLogger.info("AI Provider Init: No saved config found, using package settings");
37557
- } catch (error) {
37558
- debugLogger.warn("AI Provider Init: Failed to load from IndexedDB, using package settings", { error });
37559
37634
  }
37560
37635
  if (settings.aiProvider) {
37561
37636
  providerConfig = { ...settings.aiProvider };