@burtson-labs/bandit-engine 2.0.60 → 2.0.61

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.
@@ -9459,7 +9459,7 @@ var MCPToolsTabV2_default = MCPToolsTabV2;
9459
9459
 
9460
9460
  // src/management/management.tsx
9461
9461
  import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
9462
- var preloadChatPage = () => import("./chat-NLBCURUN.mjs");
9462
+ var preloadChatPage = () => import("./chat-E23BSMK5.mjs");
9463
9463
  var buildCapabilitiesUrl = (gatewayApiUrl) => {
9464
9464
  const trimmed = gatewayApiUrl.replace(/\/$/, "");
9465
9465
  if (trimmed.endsWith("/api")) {
@@ -10804,4 +10804,4 @@ export {
10804
10804
  useGatewayMemory,
10805
10805
  management_default
10806
10806
  };
10807
- //# sourceMappingURL=chunk-3AWAL2YH.mjs.map
10807
+ //# sourceMappingURL=chunk-SKMJ43NN.mjs.map
package/dist/index.js CHANGED
@@ -19435,6 +19435,64 @@ var init_telemetry = __esm({
19435
19435
  }
19436
19436
  });
19437
19437
 
19438
+ // src/store/engineStore.ts
19439
+ var import_zustand15, STORAGE_KEY2, readStored, useEngineStore;
19440
+ var init_engineStore = __esm({
19441
+ "src/store/engineStore.ts"() {
19442
+ "use strict";
19443
+ import_zustand15 = require("zustand");
19444
+ init_packageSettingsStore();
19445
+ init_authenticationService();
19446
+ init_debugLogger();
19447
+ STORAGE_KEY2 = "bandit.selectedEngine";
19448
+ readStored = () => {
19449
+ try {
19450
+ return typeof window !== "undefined" ? window.localStorage.getItem(STORAGE_KEY2) : null;
19451
+ } catch {
19452
+ return null;
19453
+ }
19454
+ };
19455
+ useEngineStore = (0, import_zustand15.create)((set, get) => ({
19456
+ selectedEngine: readStored(),
19457
+ engines: [],
19458
+ loaded: false,
19459
+ setSelectedEngine: (id) => {
19460
+ set({ selectedEngine: id });
19461
+ try {
19462
+ window.localStorage.setItem(STORAGE_KEY2, id);
19463
+ } catch {
19464
+ }
19465
+ },
19466
+ getSelectedEngine: () => get().selectedEngine || usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core",
19467
+ fetchEngines: async () => {
19468
+ const settings = usePackageSettingsStore.getState().settings;
19469
+ const base = settings?.gatewayApiUrl?.replace(/\/$/, "") ?? "";
19470
+ if (!base || settings?.playgroundMode || base.toLowerCase().startsWith("playground://")) {
19471
+ set({ loaded: true });
19472
+ return;
19473
+ }
19474
+ try {
19475
+ const headers = { "Content-Type": "application/json" };
19476
+ const token = authenticationService.getToken();
19477
+ if (token) headers["Authorization"] = `Bearer ${token}`;
19478
+ const res = await fetch(`${base}/models`, { headers });
19479
+ const data = await res.json();
19480
+ if (res.ok && Array.isArray(data?.models)) {
19481
+ set({ engines: data.models, loaded: true });
19482
+ } else {
19483
+ set({ loaded: true });
19484
+ }
19485
+ } catch (error) {
19486
+ debugLogger.error("Failed to fetch engines", {
19487
+ error: error instanceof Error ? error.message : String(error)
19488
+ });
19489
+ set({ loaded: true });
19490
+ }
19491
+ }
19492
+ }));
19493
+ }
19494
+ });
19495
+
19438
19496
  // src/chat/hooks/useMemoryEnhancer.tsx
19439
19497
  var import_rxjs20, MEMORY_LIMIT, MIN_MEMORY_WORDS, MERGE_THRESHOLD, REJECT_ECHO_THRESHOLD, REJECT_DUPLICATE_THRESHOLD, CONTEXTUAL_DIVERGENCE_THRESHOLD, normalizeText, isStructurallyDuplicate, isAboutBandit, hasEngagementValue, isMemoryTooShortOrGeneric, isPersonalText, mergeMemory, isVoiceShifted, sanitizeMemory, sanitizeMemoryText, shouldAcceptMemory, isContextuallyDivergent, useMemoryEnhancer;
19440
19498
  var init_useMemoryEnhancer = __esm({
@@ -20177,12 +20235,12 @@ var init_useAIProvider = __esm({
20177
20235
  init_knowledgeStore();
20178
20236
  init_aiProviderStore();
20179
20237
  init_telemetry();
20238
+ init_engineStore();
20180
20239
  init_conversationStore();
20181
20240
  init_useMemoryEnhancer();
20182
20241
  init_useVectorStore();
20183
20242
  init_embeddingService();
20184
20243
  init_useMoodEngine();
20185
- init_packageSettingsStore();
20186
20244
  init_prompts();
20187
20245
  init_preferencesStore();
20188
20246
  init_mcp();
@@ -20546,7 +20604,7 @@ var init_useAIProvider = __esm({
20546
20604
  question: pendingQuestion,
20547
20605
  images: pendingImages
20548
20606
  });
20549
- const modelName = usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core:4b-it-qat";
20607
+ const modelName = useEngineStore.getState().getSelectedEngine();
20550
20608
  const CONFIG = modelConfigs[modelName] ?? modelConfigs["bandit-core:4b-it-qat"];
20551
20609
  const base64Images = imageList.map((img) => img.split(",")[1]);
20552
20610
  const latestEntries = history.slice(-CONFIG.historyMessages);
@@ -24778,6 +24836,7 @@ var init_chat_app_bar = __esm({
24778
24836
  init_packageSettingsStore();
24779
24837
  init_useFeatures();
24780
24838
  init_conversationSyncStore();
24839
+ init_engineStore();
24781
24840
  import_shallow2 = require("zustand/shallow");
24782
24841
  import_jsx_runtime24 = require("react/jsx-runtime");
24783
24842
  CDN_BASE = "https://cdn.burtson.ai/";
@@ -24827,6 +24886,7 @@ var init_chat_app_bar = __esm({
24827
24886
  menuText
24828
24887
  } = theme.palette.chat.appBar;
24829
24888
  const [modelAnchorEl, setModelAnchorEl] = (0, import_react31.useState)(null);
24889
+ const [engineAnchorEl, setEngineAnchorEl] = (0, import_react31.useState)(null);
24830
24890
  const [voiceAnchorEl, setVoiceAnchorEl] = (0, import_react31.useState)(null);
24831
24891
  const [modalOpen, setModalOpen] = (0, import_react31.useState)(false);
24832
24892
  const [confirmModelChangeOpen, setConfirmModelChangeOpen] = (0, import_react31.useState)(false);
@@ -24947,6 +25007,14 @@ var init_chat_app_bar = __esm({
24947
25007
  const selectedModel = useModelStore((s) => s.selectedModel);
24948
25008
  const currentModel = useModelStore((s) => s.availableModels.find((m) => m.name === selectedModel));
24949
25009
  const currentAvatar = currentModel?.avatarBase64 || modelAvatars2[selectedModel] || banditHead3;
25010
+ const engines = useEngineStore((s) => s.engines);
25011
+ const selectedEngine = useEngineStore((s) => s.selectedEngine);
25012
+ const effectiveEngineId = selectedEngine || usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core";
25013
+ const currentEngine = engines.find((e) => e.id === effectiveEngineId);
25014
+ const engineLabel = currentEngine?.displayName?.replace(/^Bandit /, "") || "Engine";
25015
+ (0, import_react31.useEffect)(() => {
25016
+ useEngineStore.getState().fetchEngines();
25017
+ }, []);
24950
25018
  const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars2[pendingModel || ""] || banditHead3;
24951
25019
  const resolvedHomeUrl = preferences.homeUrl?.trim() || packageSettings?.homeUrl?.trim() || "";
24952
25020
  const homeTooltip = (() => {
@@ -25259,6 +25327,84 @@ var init_chat_app_bar = __esm({
25259
25327
  )
25260
25328
  }
25261
25329
  ) }),
25330
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Tooltip, { title: `Engine: ${currentEngine?.displayName ?? effectiveEngineId}`, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
25331
+ import_material23.IconButton,
25332
+ {
25333
+ onClick: (e) => setEngineAnchorEl(e.currentTarget),
25334
+ sx: pillButtonStyles,
25335
+ "aria-label": `Change base model (engine). Currently ${effectiveEngineId}`,
25336
+ children: [
25337
+ currentEngine?.cloud ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CloudDoneIcon, { fontSize: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(CloudOffIcon, { fontSize: "small" }),
25338
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Typography, { variant: "caption", sx: { ml: 0.75, fontWeight: 600, whiteSpace: "nowrap" }, children: engineLabel })
25339
+ ]
25340
+ }
25341
+ ) }),
25342
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
25343
+ import_material23.Menu,
25344
+ {
25345
+ anchorEl: engineAnchorEl,
25346
+ open: Boolean(engineAnchorEl),
25347
+ onClose: () => setEngineAnchorEl(null),
25348
+ transformOrigin: { horizontal: "right", vertical: "top" },
25349
+ anchorOrigin: { horizontal: "right", vertical: "bottom" },
25350
+ children: [
25351
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Typography, { variant: "overline", sx: { px: 2, color: theme.palette.text.secondary }, children: "Engine \xB7 base model" }),
25352
+ engines.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.MenuItem, { disabled: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Typography, { variant: "body2", children: "No engines available" }) }),
25353
+ engines.map((engine) => {
25354
+ const badges = [
25355
+ engine.vision && "vision",
25356
+ engine.tools && "tools",
25357
+ engine.thinking && "thinking",
25358
+ engine.cloud && "cloud"
25359
+ ].filter(Boolean);
25360
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
25361
+ import_material23.MenuItem,
25362
+ {
25363
+ selected: engine.id === effectiveEngineId,
25364
+ disabled: !engine.available,
25365
+ onClick: () => {
25366
+ useEngineStore.getState().setSelectedEngine(engine.id);
25367
+ setEngineAnchorEl(null);
25368
+ },
25369
+ sx: {
25370
+ display: "flex",
25371
+ flexDirection: "column",
25372
+ alignItems: "flex-start",
25373
+ gap: 0.5,
25374
+ py: 1,
25375
+ px: 2,
25376
+ maxWidth: 360,
25377
+ whiteSpace: "normal"
25378
+ },
25379
+ children: [
25380
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_material23.Box, { sx: { display: "flex", alignItems: "center", gap: 1, width: "100%" }, children: [
25381
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Typography, { variant: "body2", sx: { fontWeight: 600, flex: 1 }, children: engine.displayName }),
25382
+ engine.id === effectiveEngineId && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Box, { sx: { width: 8, height: 8, borderRadius: "50%", bgcolor: theme.palette.primary.main } })
25383
+ ] }),
25384
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Typography, { variant: "caption", sx: { color: theme.palette.text.secondary }, children: engine.available ? engine.description : engine.unavailableReason || "Unavailable" }),
25385
+ badges.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Box, { sx: { display: "flex", gap: 0.5, flexWrap: "wrap", mt: 0.25 }, children: badges.map((b) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
25386
+ import_material23.Box,
25387
+ {
25388
+ sx: {
25389
+ fontSize: "0.65rem",
25390
+ px: 0.75,
25391
+ py: 0.1,
25392
+ borderRadius: 1,
25393
+ bgcolor: theme.palette.primary.main + "22",
25394
+ color: theme.palette.primary.main
25395
+ },
25396
+ children: b
25397
+ },
25398
+ b
25399
+ )) })
25400
+ ]
25401
+ },
25402
+ engine.id
25403
+ );
25404
+ })
25405
+ ]
25406
+ }
25407
+ ),
25262
25408
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
25263
25409
  import_material23.Menu,
25264
25410
  {