@burtson-labs/bandit-engine 2.0.60 → 2.0.62

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  chat_default
3
- } from "./chunk-MFDMM5MS.mjs";
3
+ } from "./chunk-Y4NDNAAR.mjs";
4
4
  import "./chunk-ONQMRE2G.mjs";
5
5
  import "./chunk-SRCCNBHF.mjs";
6
6
  import "./chunk-6QTTNYF2.mjs";
@@ -13,4 +13,4 @@ import "./chunk-BJTO5JO5.mjs";
13
13
  export {
14
14
  chat_default as default
15
15
  };
16
- //# sourceMappingURL=chat-NLBCURUN.mjs.map
16
+ //# sourceMappingURL=chat-SN3UNX23.mjs.map
@@ -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-SN3UNX23.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-O7JGT7HR.mjs.map
@@ -1695,6 +1695,55 @@ function telemetryEndTurn(outcome) {
1695
1695
  void active?.endTurn(outcome);
1696
1696
  }
1697
1697
 
1698
+ // src/store/engineStore.ts
1699
+ import { create as create2 } from "zustand";
1700
+ var STORAGE_KEY = "bandit.selectedEngine";
1701
+ var readStored = () => {
1702
+ try {
1703
+ return typeof window !== "undefined" ? window.localStorage.getItem(STORAGE_KEY) : null;
1704
+ } catch {
1705
+ return null;
1706
+ }
1707
+ };
1708
+ var useEngineStore = create2((set, get) => ({
1709
+ selectedEngine: readStored(),
1710
+ engines: [],
1711
+ loaded: false,
1712
+ setSelectedEngine: (id) => {
1713
+ set({ selectedEngine: id });
1714
+ try {
1715
+ window.localStorage.setItem(STORAGE_KEY, id);
1716
+ } catch {
1717
+ }
1718
+ },
1719
+ getSelectedEngine: () => get().selectedEngine || usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core",
1720
+ fetchEngines: async () => {
1721
+ const settings = usePackageSettingsStore.getState().settings;
1722
+ const base = settings?.gatewayApiUrl?.replace(/\/$/, "") ?? "";
1723
+ if (!base || settings?.playgroundMode || base.toLowerCase().startsWith("playground://")) {
1724
+ set({ loaded: true });
1725
+ return;
1726
+ }
1727
+ try {
1728
+ const headers = { "Content-Type": "application/json" };
1729
+ const token = authenticationService.getToken();
1730
+ if (token) headers["Authorization"] = `Bearer ${token}`;
1731
+ const res = await fetch(`${base}/models`, { headers });
1732
+ const data = await res.json();
1733
+ if (res.ok && Array.isArray(data?.models)) {
1734
+ set({ engines: data.models, loaded: true });
1735
+ } else {
1736
+ set({ loaded: true });
1737
+ }
1738
+ } catch (error) {
1739
+ debugLogger.error("Failed to fetch engines", {
1740
+ error: error instanceof Error ? error.message : String(error)
1741
+ });
1742
+ set({ loaded: true });
1743
+ }
1744
+ }
1745
+ }));
1746
+
1698
1747
  // src/chat/hooks/useMemoryEnhancer.tsx
1699
1748
  import { lastValueFrom, map as map2 } from "rxjs";
1700
1749
  var MEMORY_LIMIT = 100;
@@ -2747,7 +2796,7 @@ var useAIProvider = ({
2747
2796
  question: pendingQuestion,
2748
2797
  images: pendingImages
2749
2798
  });
2750
- const modelName = usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core:4b-it-qat";
2799
+ const modelName = useEngineStore.getState().getSelectedEngine();
2751
2800
  const CONFIG = modelConfigs[modelName] ?? modelConfigs["bandit-core:4b-it-qat"];
2752
2801
  const base64Images = imageList.map((img) => img.split(",")[1]);
2753
2802
  const latestEntries = history.slice(-CONFIG.historyMessages);
@@ -3120,6 +3169,7 @@ ${protocol}`;
3120
3169
  let fullMessage = "";
3121
3170
  let latestDisplayMessage = "";
3122
3171
  let sawToolBlock = false;
3172
+ const nativeToolCalls = [];
3123
3173
  const stripThinking = (text) => {
3124
3174
  let result = text.replace(/<think>[\s\S]*?<\/think>/g, "");
3125
3175
  const openIdx = result.indexOf("<think>");
@@ -3158,6 +3208,11 @@ ${protocol}`;
3158
3208
  const sub = stream.subscribe({
3159
3209
  next: (data) => {
3160
3210
  if (!data?.message?.content && !data?.message?.tool_calls) return;
3211
+ if (Array.isArray(data.message.tool_calls) && data.message.tool_calls.length > 0) {
3212
+ nativeToolCalls.push(...data.message.tool_calls);
3213
+ sawToolBlock = true;
3214
+ clearFlushTimer();
3215
+ }
3161
3216
  if (data.message.content) {
3162
3217
  fullMessage += data.message.content;
3163
3218
  telemetryEvent("tool_loop:llm_chunk", { chunk: data.message.content });
@@ -3206,6 +3261,20 @@ ${protocol}`;
3206
3261
  if (!sawToolBlock) {
3207
3262
  flushNow();
3208
3263
  }
3264
+ if (nativeToolCalls.length > 0 && !/```(?:tool_code|TOOL_CODE)/.test(fullMessage)) {
3265
+ for (const raw of nativeToolCalls) {
3266
+ const tc = raw;
3267
+ const fn = tc.function?.name ?? tc.name;
3268
+ if (!fn) continue;
3269
+ const rawArgs = tc.function?.arguments ?? tc.arguments ?? {};
3270
+ const argStr = typeof rawArgs === "string" ? rawArgs : JSON.stringify(rawArgs ?? {});
3271
+ fullMessage += `
3272
+
3273
+ \`\`\`tool_code
3274
+ ${fn}(${argStr})
3275
+ \`\`\``;
3276
+ }
3277
+ }
3209
3278
  const toolCallMatches = fullMessage.match(/```(?:tool_code|TOOL_CODE)\s*\n([^`]+)\n```/gi);
3210
3279
  let enhancedMessage = fullMessage;
3211
3280
  const summarizableResults = [];
@@ -7049,6 +7118,7 @@ var ChatAppBar = ({
7049
7118
  menuText
7050
7119
  } = theme.palette.chat.appBar;
7051
7120
  const [modelAnchorEl, setModelAnchorEl] = useState12(null);
7121
+ const [engineAnchorEl, setEngineAnchorEl] = useState12(null);
7052
7122
  const [voiceAnchorEl, setVoiceAnchorEl] = useState12(null);
7053
7123
  const [modalOpen, setModalOpen] = useState12(false);
7054
7124
  const [confirmModelChangeOpen, setConfirmModelChangeOpen] = useState12(false);
@@ -7169,6 +7239,16 @@ var ChatAppBar = ({
7169
7239
  const selectedModel = useModelStore((s) => s.selectedModel);
7170
7240
  const currentModel = useModelStore((s) => s.availableModels.find((m) => m.name === selectedModel));
7171
7241
  const currentAvatar = currentModel?.avatarBase64 || modelAvatars[selectedModel] || banditHead;
7242
+ const engines = useEngineStore((s) => s.engines);
7243
+ const selectedEngine = useEngineStore((s) => s.selectedEngine);
7244
+ const effectiveEngineId = selectedEngine || usePackageSettingsStore.getState().settings?.defaultModel || "bandit-core";
7245
+ const currentEngine = engines.find((e) => e.id === effectiveEngineId) || engines.find((e) => effectiveEngineId.startsWith(e.id + ":"));
7246
+ const resolvedEngineId = currentEngine?.id ?? effectiveEngineId;
7247
+ const cleanEngineName = (name) => (name || "").replace(/\s*\([^)]*\)\s*$/, "").trim();
7248
+ const engineDisplay = cleanEngineName(currentEngine?.displayName) || "Engine";
7249
+ useEffect11(() => {
7250
+ useEngineStore.getState().fetchEngines();
7251
+ }, []);
7172
7252
  const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars[pendingModel || ""] || banditHead;
7173
7253
  const resolvedHomeUrl = preferences.homeUrl?.trim() || packageSettings?.homeUrl?.trim() || "";
7174
7254
  const homeTooltip = (() => {
@@ -7481,6 +7561,81 @@ var ChatAppBar = ({
7481
7561
  )
7482
7562
  }
7483
7563
  ) }),
7564
+ /* @__PURE__ */ jsx13(Tooltip4, { title: `Engine \xB7 ${engineDisplay}`, arrow: true, children: /* @__PURE__ */ jsx13(
7565
+ IconButton9,
7566
+ {
7567
+ onClick: (e) => setEngineAnchorEl(e.currentTarget),
7568
+ sx: pillButtonStyles,
7569
+ "aria-label": `Change base model (engine). Currently ${engineDisplay}`,
7570
+ children: /* @__PURE__ */ jsx13(PsychologyIcon, { fontSize: "small" })
7571
+ }
7572
+ ) }),
7573
+ /* @__PURE__ */ jsxs10(
7574
+ Menu5,
7575
+ {
7576
+ anchorEl: engineAnchorEl,
7577
+ open: Boolean(engineAnchorEl),
7578
+ onClose: () => setEngineAnchorEl(null),
7579
+ transformOrigin: { horizontal: "right", vertical: "top" },
7580
+ anchorOrigin: { horizontal: "right", vertical: "bottom" },
7581
+ children: [
7582
+ /* @__PURE__ */ jsx13(Typography8, { variant: "overline", sx: { px: 2, color: theme.palette.text.secondary }, children: "Engine \xB7 base model" }),
7583
+ engines.length === 0 && /* @__PURE__ */ jsx13(MenuItem5, { disabled: true, children: /* @__PURE__ */ jsx13(Typography8, { variant: "body2", children: "No engines available" }) }),
7584
+ engines.map((engine) => {
7585
+ const badges = [
7586
+ engine.vision && "vision",
7587
+ engine.tools && "tools",
7588
+ engine.thinking && "thinking",
7589
+ engine.cloud && "cloud"
7590
+ ].filter(Boolean);
7591
+ return /* @__PURE__ */ jsxs10(
7592
+ MenuItem5,
7593
+ {
7594
+ selected: engine.id === resolvedEngineId,
7595
+ disabled: !engine.available,
7596
+ onClick: () => {
7597
+ useEngineStore.getState().setSelectedEngine(engine.id);
7598
+ setEngineAnchorEl(null);
7599
+ },
7600
+ sx: {
7601
+ display: "flex",
7602
+ flexDirection: "column",
7603
+ alignItems: "flex-start",
7604
+ gap: 0.5,
7605
+ py: 1,
7606
+ px: 2,
7607
+ maxWidth: 360,
7608
+ whiteSpace: "normal"
7609
+ },
7610
+ children: [
7611
+ /* @__PURE__ */ jsxs10(Box10, { sx: { display: "flex", alignItems: "center", gap: 1, width: "100%" }, children: [
7612
+ /* @__PURE__ */ jsx13(Typography8, { variant: "body2", sx: { fontWeight: 600, flex: 1 }, children: cleanEngineName(engine.displayName) }),
7613
+ engine.id === resolvedEngineId && /* @__PURE__ */ jsx13(Box10, { sx: { width: 8, height: 8, borderRadius: "50%", bgcolor: theme.palette.primary.main } })
7614
+ ] }),
7615
+ /* @__PURE__ */ jsx13(Typography8, { variant: "caption", sx: { color: theme.palette.text.secondary }, children: engine.available ? engine.description : engine.unavailableReason || "Unavailable" }),
7616
+ badges.length > 0 && /* @__PURE__ */ jsx13(Box10, { sx: { display: "flex", gap: 0.5, flexWrap: "wrap", mt: 0.25 }, children: badges.map((b) => /* @__PURE__ */ jsx13(
7617
+ Box10,
7618
+ {
7619
+ sx: {
7620
+ fontSize: "0.65rem",
7621
+ px: 0.75,
7622
+ py: 0.1,
7623
+ borderRadius: 1,
7624
+ bgcolor: theme.palette.primary.main + "22",
7625
+ color: theme.palette.primary.main
7626
+ },
7627
+ children: b
7628
+ },
7629
+ b
7630
+ )) })
7631
+ ]
7632
+ },
7633
+ engine.id
7634
+ );
7635
+ })
7636
+ ]
7637
+ }
7638
+ ),
7484
7639
  /* @__PURE__ */ jsx13(
7485
7640
  Menu5,
7486
7641
  {
@@ -9586,4 +9741,4 @@ var chat_default = Chat;
9586
9741
  export {
9587
9742
  chat_default
9588
9743
  };
9589
- //# sourceMappingURL=chunk-MFDMM5MS.mjs.map
9744
+ //# sourceMappingURL=chunk-Y4NDNAAR.mjs.map