@burtson-labs/bandit-engine 2.0.61 → 2.0.63

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.
package/dist/index.js CHANGED
@@ -13559,7 +13559,7 @@ var init_ai_response_action_bar = __esm({
13559
13559
  });
13560
13560
 
13561
13561
  // src/modals/chat-modal/ai-response-text-field.tsx
13562
- var import_react15, import_styles4, import_react_markdown, import_remark_gfm, import_rehype_raw, import_rehype_sanitize2, import_material8, import_jsx_runtime11, brainIcon, avatarFilenames, banditHead2, resolveAvatar2, normalizeTables, isNonEmptyString, toDateSafe, toNumberArray, MarkdownCodeBlock, AIResponseTextField, ai_response_text_field_default;
13562
+ var import_react15, import_styles4, import_react_markdown, import_remark_gfm, import_rehype_raw, import_rehype_sanitize2, import_material8, import_jsx_runtime11, brainIcon, normalizeTables, isNonEmptyString, toDateSafe, toNumberArray, MarkdownCodeBlock, AIResponseTextField, ai_response_text_field_default;
13563
13563
  var init_ai_response_text_field = __esm({
13564
13564
  "src/modals/chat-modal/ai-response-text-field.tsx"() {
13565
13565
  "use strict";
@@ -13574,33 +13574,12 @@ var init_ai_response_text_field = __esm({
13574
13574
  import_rehype_sanitize2 = __toESM(require("rehype-sanitize"));
13575
13575
  init_debugLogger();
13576
13576
  import_material8 = require("@mui/material");
13577
- init_modelStore();
13578
13577
  init_lowlight();
13579
13578
  init_markdownRendering();
13580
13579
  init_lucide_icons();
13581
13580
  init_ai_response_action_bar();
13582
- init_brandingService();
13583
13581
  import_jsx_runtime11 = require("react/jsx-runtime");
13584
13582
  brainIcon = "https://cdn.burtson.ai/images/brain-icon.png";
13585
- avatarFilenames = {
13586
- "Bandit-Core": "core-avatar.png",
13587
- "Bandit-Muse": "muse-avatar.png",
13588
- "Bandit-Logic": "logic-avatar.png",
13589
- "Bandit-D1VA": "d1va-avatar.png",
13590
- "Bandit-Exec": "exec-avatar.png",
13591
- "default": "bandit-head.png"
13592
- };
13593
- banditHead2 = `https://cdn.burtson.ai/images/bandit-head.png`;
13594
- resolveAvatar2 = (selectedModel) => {
13595
- const model = useModelStore.getState().availableModels.find(
13596
- (m) => m.name === selectedModel
13597
- );
13598
- if (model?.avatarBase64) {
13599
- return model.avatarBase64;
13600
- }
13601
- const avatarFilename = avatarFilenames[selectedModel] || avatarFilenames["default"];
13602
- return `https://cdn.burtson.ai/avatars/${avatarFilename}`;
13603
- };
13604
13583
  normalizeTables = (markdown2) => {
13605
13584
  const lines = markdown2.split("\n");
13606
13585
  const output = [];
@@ -13946,15 +13925,6 @@ var init_ai_response_text_field = __esm({
13946
13925
  const timeout3 = setTimeout(() => setShowMemoryUpdated(false), 3e3);
13947
13926
  return () => clearTimeout(timeout3);
13948
13927
  }, [memoryUpdated]);
13949
- const selectedModel = useModelStore((state) => state.selectedModel);
13950
- const [userAvatar, setUserAvatar] = (0, import_react15.useState)(banditHead2);
13951
- (0, import_react15.useEffect)(() => {
13952
- const fetchBranding = async () => {
13953
- const branding = await brandingService_default.getBranding();
13954
- setUserAvatar(branding?.logoBase64 || banditHead2);
13955
- };
13956
- fetchBranding();
13957
- }, []);
13958
13928
  const theme = (0, import_styles4.useTheme)();
13959
13929
  const chatResponse = theme.palette.chat?.response;
13960
13930
  const sanitizeMarkdown = (raw) => {
@@ -14323,283 +14293,108 @@ ${sourcesMarkdownList.join("\n")}`;
14323
14293
  alignSelf: "stretch",
14324
14294
  display: "flex",
14325
14295
  flexDirection: "column",
14326
- bgcolor: chatResponse.containerBackground,
14327
- color: chatResponse.aiText || "#fff",
14328
- p: isMobile ? 1 : 2,
14329
- borderRadius: "4px",
14330
- userSelect: "text",
14331
- border: "1px solid " + (chatResponse.aiBorder || "#ccc"),
14332
- boxShadow: "0 0 6px rgba(0,0,0,0.3)"
14296
+ color: chatResponse.aiText || theme.palette.text.primary,
14297
+ px: isMobile ? 0.5 : 2,
14298
+ py: 1,
14299
+ userSelect: "text"
14333
14300
  },
14334
14301
  children: [
14335
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14336
- import_material8.Box,
14337
- {
14338
- sx: {
14339
- display: "flex",
14340
- flexDirection: "column",
14341
- alignItems: {
14342
- xs: "flex-start",
14343
- sm: "flex-end"
14302
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { display: "flex", justifyContent: "flex-end", mb: 2.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material8.Box, { sx: { maxWidth: { xs: "100%", sm: "85%" }, minWidth: 0 }, children: [
14303
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14304
+ import_material8.Box,
14305
+ {
14306
+ sx: {
14307
+ bgcolor: chatResponse.userBubble || (0, import_styles4.alpha)(theme.palette.common.white, 0.07),
14308
+ borderRadius: "18px",
14309
+ px: 2,
14310
+ py: 1.25,
14311
+ wordBreak: "break-word",
14312
+ whiteSpace: "pre-wrap",
14313
+ overflowWrap: "break-word"
14344
14314
  },
14345
- gap: 2,
14346
- mb: 2,
14347
- justifyContent: "flex-end"
14348
- },
14349
- children: [
14350
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14351
- import_material8.Box,
14315
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14316
+ import_material8.Typography,
14352
14317
  {
14353
14318
  sx: {
14354
- display: "flex",
14355
- flexDirection: "column",
14356
- alignItems: "center"
14319
+ color: theme.palette.text.primary,
14320
+ lineHeight: 1.5,
14321
+ wordBreak: "break-word",
14322
+ whiteSpace: "pre-wrap"
14357
14323
  },
14358
- children: [
14359
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14360
- import_material8.Avatar,
14361
- {
14362
- alt: "You",
14363
- src: userAvatar,
14364
- sx: {
14365
- display: { xs: "none", sm: "flex" },
14366
- width: { sm: 72 },
14367
- height: { sm: 72 },
14368
- bgcolor: chatResponse.userAvatarBackground || (theme.palette.mode === "dark" ? "transparent" : "#eee"),
14369
- color: "#fff",
14370
- fontWeight: "bold",
14371
- fontSize: { sm: "1.1rem" },
14372
- border: "2px solid #a78bfa",
14373
- boxShadow: "0 0 8px rgba(167, 139, 250, 0.3)",
14374
- transform: "scaleX(1)"
14375
- }
14376
- }
14377
- ),
14378
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14379
- import_material8.Typography,
14380
- {
14381
- variant: "caption",
14382
- sx: { color: chatResponse.modelLabel || "#888", mt: 1, fontStyle: "italic" },
14383
- children: "You said"
14384
- }
14385
- )
14386
- ]
14324
+ children: question
14387
14325
  }
14388
- ),
14389
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material8.Box, { sx: { flex: 1 }, children: [
14390
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14391
- import_material8.Box,
14392
- {
14393
- sx: {
14394
- display: "inline-block",
14395
- textAlign: "left",
14396
- bgcolor: chatResponse.userBubble || "#1f1f1f",
14397
- borderRadius: "4px",
14398
- px: isMobile ? 1 : 2,
14399
- py: 1.5,
14400
- width: isMobile ? "100%" : "fit-content",
14401
- maxWidth: "100%",
14402
- border: "1px solid " + (chatResponse.aiBorder || "#444"),
14403
- wordBreak: "break-word",
14404
- whiteSpace: "pre-wrap",
14405
- overflowWrap: "break-word",
14406
- mt: { xs: 0.5, sm: 0.25 }
14407
- },
14408
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14409
- import_material8.Typography,
14410
- {
14411
- sx: {
14412
- color: chatResponse.userText || "#6C9AC5",
14413
- fontStyle: "italic",
14414
- wordBreak: "break-word",
14415
- whiteSpace: "pre-wrap"
14416
- },
14417
- children: question
14418
- }
14419
- )
14420
- }
14421
- ),
14422
- images && images.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { display: "flex", gap: 1, mt: 1, flexWrap: "wrap" }, children: images.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14423
- import_material8.Avatar,
14424
- {
14425
- src: img,
14426
- variant: "rounded",
14427
- onClick: () => setOpenImage(img),
14428
- sx: {
14429
- width: 64,
14430
- height: 64,
14431
- borderRadius: 2,
14432
- cursor: "pointer",
14433
- "&:hover": { boxShadow: `0 0 0 2px ${theme.palette.primary.main}` }
14434
- }
14435
- },
14436
- i
14437
- )) })
14438
- ] })
14439
- ]
14440
- }
14441
- ),
14442
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { borderBottom: `1px solid ${theme.palette.divider}`, my: 2 } }),
14443
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14444
- import_material8.Box,
14445
- {
14446
- sx: {
14447
- display: "flex",
14448
- flexDirection: "column",
14449
- alignItems: {
14450
- xs: "center",
14451
- sm: "flex-start"
14452
- },
14453
- gap: 2,
14454
- mb: 2
14326
+ )
14327
+ }
14328
+ ),
14329
+ images && images.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { display: "flex", gap: 1, mt: 1, flexWrap: "wrap", justifyContent: "flex-end" }, children: images.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14330
+ import_material8.Avatar,
14331
+ {
14332
+ src: img,
14333
+ variant: "rounded",
14334
+ onClick: () => setOpenImage(img),
14335
+ sx: {
14336
+ width: 64,
14337
+ height: 64,
14338
+ borderRadius: 2,
14339
+ cursor: "pointer",
14340
+ "&:hover": { boxShadow: `0 0 0 2px ${theme.palette.primary.main}` }
14341
+ }
14455
14342
  },
14456
- children: [
14457
- typeof response === "string" && response.trim() !== "" && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14458
- import_material8.Box,
14459
- {
14460
- sx: {
14461
- display: "flex",
14462
- flexDirection: "column",
14463
- alignItems: "center",
14464
- mr: 2,
14465
- position: "relative"
14466
- },
14467
- children: [
14468
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14469
- import_material8.Avatar,
14470
- {
14471
- src: resolveAvatar2(selectedModel),
14472
- alt: selectedModel,
14473
- sx: {
14474
- display: { xs: "none", sm: "flex" },
14475
- width: 72,
14476
- height: 72,
14477
- border: "1px solid #888",
14478
- boxShadow: "0 0 6px rgba(136, 136, 136, 0.4)",
14479
- filter: "brightness(1.6)"
14480
- }
14481
- }
14482
- ),
14483
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { display: { xs: "none", sm: "block" } }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14484
- import_material8.Typography,
14485
- {
14486
- variant: "caption",
14487
- sx: { color: chatResponse.modelLabel || "#888", mt: 1, fontStyle: "italic" },
14488
- children: [
14489
- selectedModel,
14490
- " says"
14491
- ]
14492
- }
14493
- ) })
14494
- ]
14495
- }
14496
- ),
14497
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14498
- import_material8.Box,
14499
- {
14500
- sx: {
14501
- display: { xs: "flex", sm: "none" },
14502
- justifyContent: "right",
14503
- width: "100%",
14504
- mt: -1,
14505
- mb: 1
14506
- },
14507
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14508
- import_material8.Typography,
14509
- {
14510
- variant: "caption",
14511
- sx: { fontStyle: "italic", color: chatResponse.modelLabel || "#888" },
14512
- children: [
14513
- selectedModel,
14514
- " says"
14515
- ]
14516
- }
14517
- )
14518
- }
14519
- ),
14520
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material8.Box, { sx: { position: "relative", width: "100%" }, children: [
14521
- cancelled && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14522
- import_material8.Box,
14523
- {
14524
- sx: {
14525
- position: "absolute",
14526
- top: -24,
14527
- left: 0,
14528
- display: "flex",
14529
- alignItems: "center",
14530
- gap: 1,
14531
- pl: 1,
14532
- zIndex: 1
14533
- },
14534
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Typography, { variant: "caption", sx: { fontStyle: "italic", opacity: 0.85 }, children: "Cancelled by you" })
14535
- }
14536
- ),
14537
- showMemoryUpdated && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14538
- import_material8.Box,
14539
- {
14540
- sx: {
14541
- position: "absolute",
14542
- top: -24,
14543
- right: 0,
14544
- display: "flex",
14545
- alignItems: "center",
14546
- gap: 1,
14547
- pr: 1,
14548
- animation: "fadeOut 0.3s ease-in 2.7s forwards",
14549
- zIndex: 1
14550
- },
14551
- children: [
14552
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14553
- "img",
14554
- {
14555
- src: brainIcon,
14556
- alt: "Memory",
14557
- style: { width: 18, height: 18 }
14558
- }
14559
- ),
14560
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14561
- import_material8.Typography,
14562
- {
14563
- variant: "caption",
14564
- sx: { color: chatResponse.memoryText || "#2e7d32", fontStyle: "italic" },
14565
- children: "Bandit added to memory"
14566
- }
14567
- )
14568
- ]
14569
- }
14570
- ),
14343
+ i
14344
+ )) })
14345
+ ] }) }),
14346
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material8.Box, { sx: { position: "relative", width: "100%", maxWidth: { xs: "100%", sm: "768px" } }, children: [
14347
+ cancelled && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14348
+ import_material8.Box,
14349
+ {
14350
+ sx: {
14351
+ position: "absolute",
14352
+ top: -22,
14353
+ left: 0,
14354
+ display: "flex",
14355
+ alignItems: "center",
14356
+ gap: 1,
14357
+ zIndex: 1
14358
+ },
14359
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Typography, { variant: "caption", sx: { fontStyle: "italic", opacity: 0.85 }, children: "Cancelled by you" })
14360
+ }
14361
+ ),
14362
+ showMemoryUpdated && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14363
+ import_material8.Box,
14364
+ {
14365
+ sx: {
14366
+ position: "absolute",
14367
+ top: -22,
14368
+ right: 0,
14369
+ display: "flex",
14370
+ alignItems: "center",
14371
+ gap: 1,
14372
+ animation: "fadeOut 0.3s ease-in 2.7s forwards",
14373
+ zIndex: 1
14374
+ },
14375
+ children: [
14376
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { src: brainIcon, alt: "Memory", style: { width: 16, height: 16 } }),
14571
14377
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14572
- import_material8.Box,
14378
+ import_material8.Typography,
14573
14379
  {
14574
- sx: {
14575
- bgcolor: chatResponse.aiBubble ?? "#2f2f2f",
14576
- borderRadius: "4px",
14577
- px: isMobile ? 1 : 1.5,
14578
- // Reduced padding on mobile
14579
- py: 1.25,
14580
- width: "100%",
14581
- maxWidth: isMobile ? "100%" : "768px",
14582
- // Full width on mobile
14583
- border: "1px solid " + (chatResponse.aiBorder || "#ccc"),
14584
- wordBreak: "break-word",
14585
- alignSelf: "flex-start",
14586
- mt: { xs: 0.5, sm: 0.25 }
14587
- },
14588
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { width: "100%", maxWidth: "100%" }, children: typeof response === "string" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14589
- import_react_markdown.default,
14590
- {
14591
- remarkPlugins: [import_remark_gfm.default],
14592
- rehypePlugins: [import_rehype_raw.default, [import_rehype_sanitize2.default, markdownSanitizeSchema]],
14593
- components,
14594
- children: enrichedMarkdown ?? sanitizeMarkdown(response)
14595
- }
14596
- ) : import_react15.default.isValidElement(response) ? response : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Typography, { color: "error", children: "\u26A0\uFE0F Invalid AI response" }) })
14380
+ variant: "caption",
14381
+ sx: { color: chatResponse.memoryText || "#2e7d32", fontStyle: "italic" },
14382
+ children: "Bandit added to memory"
14597
14383
  }
14598
14384
  )
14599
- ] })
14600
- ]
14601
- }
14602
- ),
14385
+ ]
14386
+ }
14387
+ ),
14388
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { width: "100%", maxWidth: "100%" }, children: typeof response === "string" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14389
+ import_react_markdown.default,
14390
+ {
14391
+ remarkPlugins: [import_remark_gfm.default],
14392
+ rehypePlugins: [import_rehype_raw.default, [import_rehype_sanitize2.default, markdownSanitizeSchema]],
14393
+ components,
14394
+ children: enrichedMarkdown ?? sanitizeMarkdown(response)
14395
+ }
14396
+ ) : import_react15.default.isValidElement(response) ? response : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Typography, { color: "error", children: "\u26A0\uFE0F Invalid AI response" }) })
14397
+ ] }),
14603
14398
  !!(responseText || typeof response === "string" && response) && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ai_response_action_bar_default, { text: responseText || response }),
14604
14399
  displaySourceFiles && displaySourceFiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material8.Box, { sx: { mt: 1.5, display: "flex", gap: 2, flexWrap: "wrap", justifyContent: "flex-start" }, children: displaySourceFiles.map((doc, idx) => {
14605
14400
  debugLogger.debug("Rendering DocumentCard in AI response", {
@@ -20977,6 +20772,7 @@ ${protocol}`;
20977
20772
  let fullMessage = "";
20978
20773
  let latestDisplayMessage = "";
20979
20774
  let sawToolBlock = false;
20775
+ const nativeToolCalls = [];
20980
20776
  const stripThinking = (text) => {
20981
20777
  let result = text.replace(/<think>[\s\S]*?<\/think>/g, "");
20982
20778
  const openIdx = result.indexOf("<think>");
@@ -21015,6 +20811,11 @@ ${protocol}`;
21015
20811
  const sub = stream.subscribe({
21016
20812
  next: (data) => {
21017
20813
  if (!data?.message?.content && !data?.message?.tool_calls) return;
20814
+ if (Array.isArray(data.message.tool_calls) && data.message.tool_calls.length > 0) {
20815
+ nativeToolCalls.push(...data.message.tool_calls);
20816
+ sawToolBlock = true;
20817
+ clearFlushTimer();
20818
+ }
21018
20819
  if (data.message.content) {
21019
20820
  fullMessage += data.message.content;
21020
20821
  telemetryEvent("tool_loop:llm_chunk", { chunk: data.message.content });
@@ -21063,6 +20864,20 @@ ${protocol}`;
21063
20864
  if (!sawToolBlock) {
21064
20865
  flushNow();
21065
20866
  }
20867
+ if (nativeToolCalls.length > 0 && !/```(?:tool_code|TOOL_CODE)/.test(fullMessage)) {
20868
+ for (const raw of nativeToolCalls) {
20869
+ const tc = raw;
20870
+ const fn = tc.function?.name ?? tc.name;
20871
+ if (!fn) continue;
20872
+ const rawArgs = tc.function?.arguments ?? tc.arguments ?? {};
20873
+ const argStr = typeof rawArgs === "string" ? rawArgs : JSON.stringify(rawArgs ?? {});
20874
+ fullMessage += `
20875
+
20876
+ \`\`\`tool_code
20877
+ ${fn}(${argStr})
20878
+ \`\`\``;
20879
+ }
20880
+ }
21066
20881
  const toolCallMatches = fullMessage.match(/```(?:tool_code|TOOL_CODE)\s*\n([^`]+)\n```/gi);
21067
20882
  let enhancedMessage = fullMessage;
21068
20883
  const summarizableResults = [];
@@ -24816,7 +24631,7 @@ var init_enhanced_mobile_conversations_modal = __esm({
24816
24631
  });
24817
24632
 
24818
24633
  // src/chat/chat-app-bar.tsx
24819
- var import_material22, import_react31, import_material23, import_react_router_dom, import_shallow2, import_jsx_runtime24, CDN_BASE, banditHead3, modelAvatars2, ChatAppBar, chat_app_bar_default;
24634
+ var import_material22, import_react31, import_material23, import_react_router_dom, import_shallow2, import_jsx_runtime24, CDN_BASE, banditHead2, modelAvatars2, ChatAppBar, chat_app_bar_default;
24820
24635
  var init_chat_app_bar = __esm({
24821
24636
  "src/chat/chat-app-bar.tsx"() {
24822
24637
  "use strict";
@@ -24840,7 +24655,7 @@ var init_chat_app_bar = __esm({
24840
24655
  import_shallow2 = require("zustand/shallow");
24841
24656
  import_jsx_runtime24 = require("react/jsx-runtime");
24842
24657
  CDN_BASE = "https://cdn.burtson.ai/";
24843
- banditHead3 = `${CDN_BASE}/images/bandit-head.png`;
24658
+ banditHead2 = `${CDN_BASE}/images/bandit-head.png`;
24844
24659
  modelAvatars2 = {
24845
24660
  "Bandit-Core": `${CDN_BASE}/avatars/core-avatar.png`,
24846
24661
  "Bandit-Muse": `${CDN_BASE}/avatars/muse-avatar.png`,
@@ -25006,16 +24821,18 @@ var init_chat_app_bar = __esm({
25006
24821
  };
25007
24822
  const selectedModel = useModelStore((s) => s.selectedModel);
25008
24823
  const currentModel = useModelStore((s) => s.availableModels.find((m) => m.name === selectedModel));
25009
- const currentAvatar = currentModel?.avatarBase64 || modelAvatars2[selectedModel] || banditHead3;
24824
+ const currentAvatar = currentModel?.avatarBase64 || modelAvatars2[selectedModel] || banditHead2;
25010
24825
  const engines = useEngineStore((s) => s.engines);
25011
24826
  const selectedEngine = useEngineStore((s) => s.selectedEngine);
25012
24827
  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";
24828
+ const currentEngine = engines.find((e) => e.id === effectiveEngineId) || engines.find((e) => effectiveEngineId.startsWith(e.id + ":"));
24829
+ const resolvedEngineId = currentEngine?.id ?? effectiveEngineId;
24830
+ const cleanEngineName = (name) => (name || "").replace(/\s*\([^)]*\)\s*$/, "").trim();
24831
+ const engineDisplay = cleanEngineName(currentEngine?.displayName) || "Engine";
25015
24832
  (0, import_react31.useEffect)(() => {
25016
24833
  useEngineStore.getState().fetchEngines();
25017
24834
  }, []);
25018
- const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars2[pendingModel || ""] || banditHead3;
24835
+ const pendingModelAvatar = useModelStore.getState().availableModels.find((m) => m.name === pendingModel)?.avatarBase64 || modelAvatars2[pendingModel || ""] || banditHead2;
25019
24836
  const resolvedHomeUrl = preferences.homeUrl?.trim() || packageSettings?.homeUrl?.trim() || "";
25020
24837
  const homeTooltip = (() => {
25021
24838
  if (!resolvedHomeUrl) return "Home";
@@ -25327,16 +25144,13 @@ var init_chat_app_bar = __esm({
25327
25144
  )
25328
25145
  }
25329
25146
  ) }),
25330
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Tooltip, { title: `Engine: ${currentEngine?.displayName ?? effectiveEngineId}`, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
25147
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Tooltip, { title: `Engine \xB7 ${engineDisplay}`, arrow: true, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
25331
25148
  import_material23.IconButton,
25332
25149
  {
25333
25150
  onClick: (e) => setEngineAnchorEl(e.currentTarget),
25334
25151
  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
- ]
25152
+ "aria-label": `Change base model (engine). Currently ${engineDisplay}`,
25153
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(AutoAwesomeIcon, { fontSize: "small" })
25340
25154
  }
25341
25155
  ) }),
25342
25156
  /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
@@ -25360,7 +25174,7 @@ var init_chat_app_bar = __esm({
25360
25174
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
25361
25175
  import_material23.MenuItem,
25362
25176
  {
25363
- selected: engine.id === effectiveEngineId,
25177
+ selected: engine.id === resolvedEngineId,
25364
25178
  disabled: !engine.available,
25365
25179
  onClick: () => {
25366
25180
  useEngineStore.getState().setSelectedEngine(engine.id);
@@ -25378,8 +25192,8 @@ var init_chat_app_bar = __esm({
25378
25192
  },
25379
25193
  children: [
25380
25194
  /* @__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 } })
25195
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Typography, { variant: "body2", sx: { fontWeight: 600, flex: 1 }, children: cleanEngineName(engine.displayName) }),
25196
+ engine.id === resolvedEngineId && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material23.Box, { sx: { width: 8, height: 8, borderRadius: "50%", bgcolor: theme.palette.primary.main } })
25383
25197
  ] }),
25384
25198
  /* @__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
25199
  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)(
@@ -25491,7 +25305,7 @@ var init_chat_app_bar = __esm({
25491
25305
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
25492
25306
  import_material22.Avatar,
25493
25307
  {
25494
- src: model.avatarBase64 || modelAvatars2[model.name] || banditHead3,
25308
+ src: model.avatarBase64 || modelAvatars2[model.name] || banditHead2,
25495
25309
  alt: model.name,
25496
25310
  sx: {
25497
25311
  width: 28,
@@ -30854,7 +30668,7 @@ var import_material30 = require("@mui/material");
30854
30668
  init_lucide_icons();
30855
30669
  var import_jsx_runtime31 = require("react/jsx-runtime");
30856
30670
  var banditaiLogo = "https://cdn.burtson.ai/logos/bandit-ai-logo.png";
30857
- var banditHead4 = "https://cdn.burtson.ai/images/bandit-head.png";
30671
+ var banditHead3 = "https://cdn.burtson.ai/images/bandit-head.png";
30858
30672
  var ModalHeader = ({
30859
30673
  fullScreen,
30860
30674
  setFullScreen,
@@ -30868,7 +30682,7 @@ var ModalHeader = ({
30868
30682
  }) => {
30869
30683
  const theme = (0, import_material30.useTheme)();
30870
30684
  const isMobile = (0, import_material30.useMediaQuery)((theme2) => theme2.breakpoints.down("sm"));
30871
- const displayLogo = logo && logo !== banditaiLogo ? logo : banditHead4;
30685
+ const displayLogo = logo && logo !== banditaiLogo ? logo : banditHead3;
30872
30686
  const [isHovering, setIsHovering] = (0, import_react38.useState)(false);
30873
30687
  const buttonStyles = {
30874
30688
  transition: "all 0.15s ease-out",
@@ -32863,7 +32677,7 @@ init_lucide_icons();
32863
32677
  var import_jsx_runtime35 = require("react/jsx-runtime");
32864
32678
  var FULL_SCREEN_THRESHOLD = 100;
32865
32679
  var CDN_BASE2 = "https://cdn.burtson.ai/";
32866
- var banditHead5 = `${CDN_BASE2}/images/bandit-head.png`;
32680
+ var banditHead4 = `${CDN_BASE2}/images/bandit-head.png`;
32867
32681
  var modelAvatars3 = {
32868
32682
  "Bandit-Core": `${CDN_BASE2}/avatars/core-avatar.png`,
32869
32683
  "Bandit-Muse": `${CDN_BASE2}/avatars/muse-avatar.png`,
@@ -32953,7 +32767,7 @@ var ChatModal = ({
32953
32767
  const provider = useAIProviderStore((state) => state.provider);
32954
32768
  const notificationService2 = useNotificationService();
32955
32769
  const currentModel = availableModels.find((m) => m.name === selectedModel);
32956
- const currentAvatar = currentModel?.avatarBase64 || modelAvatars3[selectedModel] || banditHead5;
32770
+ const currentAvatar = currentModel?.avatarBase64 || modelAvatars3[selectedModel] || banditHead4;
32957
32771
  const removeImage = (index) => {
32958
32772
  setPastedImages((prev) => prev.filter((_, i) => i !== index));
32959
32773
  };
@@ -33273,7 +33087,7 @@ var ChatModal = ({
33273
33087
  /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
33274
33088
  import_material35.Avatar,
33275
33089
  {
33276
- src: model.avatarBase64 || modelAvatars3[model.name] || banditHead5,
33090
+ src: model.avatarBase64 || modelAvatars3[model.name] || banditHead4,
33277
33091
  alt: model.name,
33278
33092
  sx: {
33279
33093
  width: 28,
@@ -42741,7 +42555,7 @@ var Management = () => {
42741
42555
  const isMobile = (0, import_useMediaQuery2.default)("(max-width:900px)");
42742
42556
  const [sidebarOpen, setSidebarOpen] = (0, import_react58.useState)(false);
42743
42557
  const getOptimalFabLogo = async () => {
42744
- const banditHead7 = "https://cdn.burtson.ai/images/bandit-head.png";
42558
+ const banditHead6 = "https://cdn.burtson.ai/images/bandit-head.png";
42745
42559
  try {
42746
42560
  const subdomain = window.location.hostname.split(".")[0];
42747
42561
  const faviconUrl = `https://cdn.burtson.ai/favicons/${subdomain}/favicon.png`;
@@ -42758,10 +42572,10 @@ var Management = () => {
42758
42572
  if (branding?.logoBase64) {
42759
42573
  return branding.logoBase64;
42760
42574
  }
42761
- return banditHead7;
42575
+ return banditHead6;
42762
42576
  } catch (error) {
42763
42577
  debugLogger.error("Failed to get optimal FAB logo", { error });
42764
- return banditHead7;
42578
+ return banditHead6;
42765
42579
  }
42766
42580
  };
42767
42581
  const {
@@ -42780,8 +42594,8 @@ var Management = () => {
42780
42594
  setHasTransparentLogo
42781
42595
  } = useModelStore();
42782
42596
  const [modalOpen, setModalOpen] = (0, import_react58.useState)(false);
42783
- const banditHead6 = "https://cdn.burtson.ai/images/bandit-head.png";
42784
- const [fabLogo, setFabLogo] = (0, import_react58.useState)(banditHead6);
42597
+ const banditHead5 = "https://cdn.burtson.ai/images/bandit-head.png";
42598
+ const [fabLogo, setFabLogo] = (0, import_react58.useState)(banditHead5);
42785
42599
  const [tabIndex, setTabIndex] = (0, import_react58.useState)(4);
42786
42600
  const [logoFile, setLogoFile] = (0, import_react58.useState)(null);
42787
42601
  const [logoBase64, setLogoBase64] = (0, import_react58.useState)(null);