@burtson-labs/bandit-engine 2.0.42 → 2.0.49

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 (54) hide show
  1. package/README.md +7 -5
  2. package/dist/{aiProviderStore-UQI33C5E.mjs → aiProviderStore-3N3VE6D4.mjs} +2 -2
  3. package/dist/chat-647M6BRG.mjs +15 -0
  4. package/dist/chat-provider.js +45 -10
  5. package/dist/chat-provider.js.map +1 -1
  6. package/dist/chat-provider.mjs +6 -6
  7. package/dist/{chunk-UXE67LR7.mjs → chunk-6WZUQHZT.mjs} +11 -7
  8. package/dist/chunk-6WZUQHZT.mjs.map +1 -0
  9. package/dist/{chunk-EOEI74X4.mjs → chunk-7HXARU5R.mjs} +101 -37
  10. package/dist/chunk-7HXARU5R.mjs.map +1 -0
  11. package/dist/{chunk-XUBYA5I7.mjs → chunk-7ZDS33S2.mjs} +34 -6
  12. package/dist/chunk-7ZDS33S2.mjs.map +1 -0
  13. package/dist/{chunk-SBNENBUQ.mjs → chunk-AXFX2HUK.mjs} +12 -12
  14. package/dist/{chunk-SBNENBUQ.mjs.map → chunk-AXFX2HUK.mjs.map} +1 -1
  15. package/dist/{chunk-54ZQ3FSN.mjs → chunk-BENL3EF2.mjs} +7 -4
  16. package/dist/chunk-BENL3EF2.mjs.map +1 -0
  17. package/dist/{chunk-RTQDQ6TC.mjs → chunk-EHNWQ4T3.mjs} +2 -2
  18. package/dist/{chunk-KBKWVG7X.mjs → chunk-HKJTRBWC.mjs} +5 -5
  19. package/dist/{chunk-4RCAVVDN.mjs → chunk-JCLL7AGP.mjs} +63 -45
  20. package/dist/chunk-JCLL7AGP.mjs.map +1 -0
  21. package/dist/{chunk-ERV7GLY3.mjs → chunk-TVF45U7B.mjs} +5 -5
  22. package/dist/{chunk-H4PBQ5LJ.mjs → chunk-VL3CMSDO.mjs} +4 -4
  23. package/dist/cli.js +45 -45
  24. package/dist/cli.js.map +1 -1
  25. package/dist/{gateway-5yt_3QDP.d.mts → gateway-oScD5tvE.d.mts} +4 -3
  26. package/dist/{gateway-5yt_3QDP.d.ts → gateway-oScD5tvE.d.ts} +4 -3
  27. package/dist/index.d.mts +2 -2
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.js +199 -76
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +10 -10
  32. package/dist/management/management.js +199 -76
  33. package/dist/management/management.js.map +1 -1
  34. package/dist/management/management.mjs +8 -8
  35. package/dist/modals/chat-modal/chat-modal.js +53 -18
  36. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  37. package/dist/modals/chat-modal/chat-modal.mjs +5 -5
  38. package/dist/{modelStore-UMJBDSEF.mjs → modelStore-XWFHNTBT.mjs} +2 -2
  39. package/dist/public-types.d.mts +2 -1
  40. package/dist/public-types.d.ts +2 -1
  41. package/package.json +2 -2
  42. package/dist/chat-XDC4SNJF.mjs +0 -15
  43. package/dist/chunk-4RCAVVDN.mjs.map +0 -1
  44. package/dist/chunk-54ZQ3FSN.mjs.map +0 -1
  45. package/dist/chunk-EOEI74X4.mjs.map +0 -1
  46. package/dist/chunk-UXE67LR7.mjs.map +0 -1
  47. package/dist/chunk-XUBYA5I7.mjs.map +0 -1
  48. /package/dist/{aiProviderStore-UQI33C5E.mjs.map → aiProviderStore-3N3VE6D4.mjs.map} +0 -0
  49. /package/dist/{chat-XDC4SNJF.mjs.map → chat-647M6BRG.mjs.map} +0 -0
  50. /package/dist/{chunk-RTQDQ6TC.mjs.map → chunk-EHNWQ4T3.mjs.map} +0 -0
  51. /package/dist/{chunk-KBKWVG7X.mjs.map → chunk-HKJTRBWC.mjs.map} +0 -0
  52. /package/dist/{chunk-ERV7GLY3.mjs.map → chunk-TVF45U7B.mjs.map} +0 -0
  53. /package/dist/{chunk-H4PBQ5LJ.mjs.map → chunk-VL3CMSDO.mjs.map} +0 -0
  54. /package/dist/{modelStore-UMJBDSEF.mjs.map → modelStore-XWFHNTBT.mjs.map} +0 -0
package/README.md CHANGED
@@ -18,11 +18,13 @@ An AI chat toolkit built for speed, design, and control. Power branded AI assist
18
18
 
19
19
  ## Features
20
20
  - 🔌 Plug-and-play React chat, modal, and management surfaces
21
- - 🧠 Memory, vector knowledge, and provider switching behind a secure gateway
21
+ - 🧠 Memory, searchable knowledge, and provider switching behind a secure gateway
22
22
  - 🎨 Full MUI theming, dark mode, and branding controls out of the box
23
23
  - 🌐 Multimodal support (voice, images, documents) with Bandit AI, Ollama, OpenAI, Azure OpenAI, Anthropic, and xAI today — tell us which providers you need next so we can prioritize them
24
24
  - 🛠️ CLI scaffolding, sample gateway, and docs to launch in minutes
25
25
 
26
+ Bandit keeps confidentiality, integrity, and availability front and center: data stays within your routes, answers stay auditable, and the UI falls back gracefully when a provider is unavailable.
27
+
26
28
  ## Quick Links
27
29
  - 📚 Full docs: [banditailabs.com/npm-package](https://banditailabs.com/npm-package) (mirrors `/docs` in this repo)
28
30
  - 🎯 Live demo with OAuth sign-in: [banditailabs.com](https://banditailabs.com/)
@@ -163,7 +165,7 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
163
165
 
164
166
  **Option 1: Gateway Provider (Recommended)**
165
167
  ```tsx
166
- // Most secure - API keys stay on your backend
168
+ // Most controlled - all traffic flows through your gateway
167
169
  // Your gateway can be built in ANY language: Node.js, Python, .NET, Java, PHP, Go, etc.
168
170
  aiProvider: {
169
171
  type: "gateway",
@@ -701,11 +703,11 @@ const chatPackageSettings = {
701
703
  ```
702
704
 
703
705
  **Benefits:**
704
- - 🔒 **Security**: API keys stay on your server
706
+ - 🔒 **Control**: Your gateway owns credentials, routing, and policy enforcement
705
707
  - 📊 **Monitoring**: Request logging and usage analytics
706
708
  - 🚦 **Rate Limiting**: Built-in throttling and quotas
707
709
  - 🔄 **Provider Switching**: Change backends without frontend updates
708
- - 🛡️ **Authentication**: Unified auth across all AI services
710
+ - 🛡️ **Authentication**: Unified auth and request validation across services
709
711
 
710
712
  **Gateway Requirements:**
711
713
  Your gateway API can be built with any technology (Node.js, Python, .NET, Java, etc.) as long as it implements:
@@ -1120,7 +1122,7 @@ While Bandit Engine supports direct API key configuration for development and te
1120
1122
 
1121
1123
  1. **Use an API Gateway/Wrapper**: Deploy the OllamaGateway (soon to be renamed AiGateway) or similar backend service
1122
1124
  2. **Proxy AI Requests**: Route all AI requests through your secure backend
1123
- 3. **Environment Isolation**: Keep API keys and sensitive configuration on the server side
1125
+ 3. **Environment Isolation**: Keep credentials and sensitive configuration in backend services (not the browser bundle)
1124
1126
  4. **Authentication**: Implement proper user authentication and request validation
1125
1127
 
1126
1128
  ### Gateway Setup
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  useAIProviderStore
3
- } from "./chunk-54ZQ3FSN.mjs";
3
+ } from "./chunk-BENL3EF2.mjs";
4
4
  import "./chunk-KCI46M23.mjs";
5
5
  import "./chunk-BJTO5JO5.mjs";
6
6
  export {
7
7
  useAIProviderStore
8
8
  };
9
- //# sourceMappingURL=aiProviderStore-UQI33C5E.mjs.map
9
+ //# sourceMappingURL=aiProviderStore-3N3VE6D4.mjs.map
@@ -0,0 +1,15 @@
1
+ import {
2
+ chat_default
3
+ } from "./chunk-7HXARU5R.mjs";
4
+ import "./chunk-ONQMRE2G.mjs";
5
+ import "./chunk-EHNWQ4T3.mjs";
6
+ import "./chunk-AXFX2HUK.mjs";
7
+ import "./chunk-6WZUQHZT.mjs";
8
+ import "./chunk-7ZDS33S2.mjs";
9
+ import "./chunk-BENL3EF2.mjs";
10
+ import "./chunk-KCI46M23.mjs";
11
+ import "./chunk-BJTO5JO5.mjs";
12
+ export {
13
+ chat_default as default
14
+ };
15
+ //# sourceMappingURL=chat-647M6BRG.mjs.map
@@ -655,6 +655,27 @@ var init_modelStore = __esm({
655
655
  });
656
656
  }
657
657
  }
658
+ (async () => {
659
+ const storeConfigs6 = [{ name: "config", keyPath: "id" }];
660
+ try {
661
+ const existing = await indexedDBService_default.get("banditConfig", 1, "config", "main", storeConfigs6);
662
+ await indexedDBService_default.put(
663
+ "banditConfig",
664
+ 1,
665
+ "config",
666
+ {
667
+ ...existing,
668
+ id: "main",
669
+ model: { ...existing?.model ?? {}, selectedModel: modelName }
670
+ },
671
+ storeConfigs6
672
+ );
673
+ } catch (err) {
674
+ debugLogger.warn("setSelectedModel: failed to persist selected model", {
675
+ error: err instanceof Error ? err.message : String(err)
676
+ });
677
+ }
678
+ })();
658
679
  },
659
680
  saveModel: async () => {
660
681
  const state = get();
@@ -664,7 +685,8 @@ var init_modelStore = __esm({
664
685
  tagline: state.tagline,
665
686
  systemPrompt: state.systemPrompt,
666
687
  commands: state.commands,
667
- avatarBase64: state.avatarBase64 ?? void 0
688
+ // Ensure avatar changes are persisted even when cleared
689
+ avatarBase64: state.avatarBase64 ?? null
668
690
  };
669
691
  await indexedDBService_default.put("banditConfig", 1, "config", { id: newModel.name, model: newModel }, storeConfigs6);
670
692
  const exists = state.availableModels.find((m) => m.name === newModel.name);
@@ -691,7 +713,12 @@ var init_modelStore = __esm({
691
713
  debugLogger.info("initModels: starting initialization");
692
714
  set({ isLoading: true, isInitializing: true });
693
715
  const storeConfigs6 = [{ name: "config", keyPath: "id" }];
694
- const entries = await indexedDBService_default.getAll("banditConfig", 1, "config", storeConfigs6);
716
+ const entries = await indexedDBService_default.getAll(
717
+ "banditConfig",
718
+ 1,
719
+ "config",
720
+ storeConfigs6
721
+ );
695
722
  const mainEntry = entries.find((entry) => entry.id === "main");
696
723
  const modelEntries = entries.filter((entry) => entry.id !== "main" && entry.id !== "deletedModels");
697
724
  const deletedEntry = await indexedDBService_default.get("banditConfig", 1, "config", "deletedModels", storeConfigs6);
@@ -701,13 +728,14 @@ var init_modelStore = __esm({
701
728
  if (modelEntries.length > 0) {
702
729
  debugLogger.info("Loading models from IndexedDB");
703
730
  allModels = modelEntries.map((entry) => {
704
- const modelData = entry.model?.name ? entry.model : entry;
731
+ const modelData = entry.model ?? entry;
705
732
  return {
706
733
  name: modelData.name,
707
734
  tagline: modelData.tagline || "",
708
735
  systemPrompt: modelData.systemPrompt || "",
709
736
  commands: modelData.commands ?? [],
710
- avatarBase64: modelData.avatarBase64 ?? null
737
+ // Fall back to legacy top-level avatar when the nested model config omitted it
738
+ avatarBase64: modelData.avatarBase64 ?? entry.avatarBase64 ?? null
711
739
  };
712
740
  }).filter((m) => m.name && !deletedModelNames.includes(m.name));
713
741
  const preferences = usePreferencesStore.getState().preferences;
@@ -2221,7 +2249,7 @@ var init_gateway_service = __esm({
2221
2249
  * Chat completion using the gateway API
2222
2250
  */
2223
2251
  chat(request) {
2224
- const endpoint = request.provider === "ollama" ? `/api/${request.provider}/chat` : request.provider ? `/api/${request.provider}/chat/completions` : "/api/chat/completions";
2252
+ const endpoint = request.provider === "ollama" ? `/api/${request.provider}/chat` : request.provider === "playground" ? "/api/playground/chat/completions" : request.provider ? `/api/${request.provider}/chat/completions` : "/api/chat/completions";
2225
2253
  const fallbackEndpoint = request.provider === "bandit" ? "/completions" : null;
2226
2254
  const normalizedModel = request.provider === "bandit" ? (() => {
2227
2255
  const trimmed = (request.model ?? "").replace(/^bandit:/, "").trim();
@@ -3192,6 +3220,9 @@ var init_gateway_provider = __esm({
3192
3220
  case "ollama":
3193
3221
  this.providerSpecificService = new OllamaGatewayService(gatewayUrl, tokenFactory);
3194
3222
  break;
3223
+ case "playground":
3224
+ this.providerSpecificService = null;
3225
+ break;
3195
3226
  default:
3196
3227
  debugLogger.warn("Unknown provider for gateway, using generic gateway service", {
3197
3228
  provider: this.config.provider
@@ -3222,7 +3253,7 @@ var init_gateway_provider = __esm({
3222
3253
  images: request.images
3223
3254
  };
3224
3255
  }
3225
- } else if (["openai", "azure-openai", "anthropic", "bandit"].includes(this.config.provider || "")) {
3256
+ } else if (["openai", "azure-openai", "anthropic", "bandit", "playground"].includes(this.config.provider || "")) {
3226
3257
  if (lastUserMessageIndex !== -1) {
3227
3258
  const currentMessage = messages[lastUserMessageIndex];
3228
3259
  const contentArray = [
@@ -3269,7 +3300,7 @@ var init_gateway_provider = __esm({
3269
3300
  stream: request.stream,
3270
3301
  hasImages: !!(request.images && request.images.length > 0),
3271
3302
  imageCount: request.images?.length || 0,
3272
- imageStrategy: this.config.provider === "ollama" ? "message-level-array" : ["openai", "azure-openai", "anthropic"].includes(this.config.provider || "") ? "structured-content" : "top-level-fallback",
3303
+ imageStrategy: this.config.provider === "ollama" ? "message-level-array" : ["openai", "azure-openai", "anthropic", "playground"].includes(this.config.provider || "") ? "structured-content" : "top-level-fallback",
3273
3304
  finalMessages: messages.map((m) => ({
3274
3305
  role: m.role,
3275
3306
  hasImages: Array.isArray(m.images) && m.images.length > 0,
@@ -5447,6 +5478,9 @@ function ensureDeviceId() {
5447
5478
  return (0, import_uuid3.v4)();
5448
5479
  }
5449
5480
  }
5481
+ function getPackageDefaultAdvancedKnowledgeSync() {
5482
+ return usePackageSettingsStore.getState().settings?.advancedKnowledgeSyncDefaultEnabled;
5483
+ }
5450
5484
  function mapConversationToDTO(conversation) {
5451
5485
  const updatedAtIso = (conversation.updatedAt ?? /* @__PURE__ */ new Date()).toISOString();
5452
5486
  const createdAtIso = conversation.createdAt ? conversation.createdAt.toISOString() : null;
@@ -5821,7 +5855,7 @@ var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
5821
5855
  cursor: null,
5822
5856
  lastError: null,
5823
5857
  keepLocalOnly: false,
5824
- isAdvancedVectorFeaturesEnabled: false,
5858
+ isAdvancedVectorFeaturesEnabled: getPackageDefaultAdvancedKnowledgeSync() ?? false,
5825
5859
  conflicts: null,
5826
5860
  deviceId: ensureDeviceId(),
5827
5861
  pendingConversationUpserts: /* @__PURE__ */ new Set(),
@@ -5945,7 +5979,7 @@ var useConversationSyncStore = (0, import_zustand9.create)((set, get) => ({
5945
5979
  await get().runSync({ force: true });
5946
5980
  }
5947
5981
  } catch (error) {
5948
- const message = error instanceof Error ? error.message : "Failed to update advanced vector setting";
5982
+ const message = error instanceof Error ? error.message : "Failed to update advanced knowledge setting";
5949
5983
  debugLogger.error("conversationSyncStore: setAdvancedVectorFeaturesEnabled failed", { error: message });
5950
5984
  set({ status: "error", lastError: message });
5951
5985
  throw error;
@@ -6153,7 +6187,8 @@ function applyPreference(preference, set, getState, options) {
6153
6187
  const override = options?.override ?? {};
6154
6188
  const preferenceVectorFlag = preference.isAdvancedVectorFeaturesEnabled;
6155
6189
  const overrideVectorFlag = override.isAdvancedVectorFeaturesEnabled;
6156
- const resolvedVectorFlag = preferenceVectorFlag !== void 0 ? preferenceVectorFlag : overrideVectorFlag !== void 0 ? overrideVectorFlag : current.isAdvancedVectorFeaturesEnabled ?? false;
6190
+ const packageDefaultVectorFlag = getPackageDefaultAdvancedKnowledgeSync();
6191
+ const resolvedVectorFlag = preferenceVectorFlag !== void 0 ? preferenceVectorFlag : overrideVectorFlag !== void 0 ? overrideVectorFlag : packageDefaultVectorFlag !== void 0 ? packageDefaultVectorFlag : current.isAdvancedVectorFeaturesEnabled ?? false;
6157
6192
  set({
6158
6193
  syncEnabled: preference.syncEnabled,
6159
6194
  status: preference.syncEnabled ? "idle" : "disabled",