@burtson-labs/bandit-engine 2.0.124 → 2.0.126

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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  chat_default
3
- } from "./chunk-QPZC6GTA.mjs";
3
+ } from "./chunk-JXFPCLEY.mjs";
4
4
  import {
5
5
  chat_provider_default
6
6
  } from "./chunk-SAQUEXYS.mjs";
@@ -10,8 +10,8 @@ import {
10
10
  useGatewayHealth,
11
11
  useGatewayMemory,
12
12
  useGatewayModels
13
- } from "./chunk-K5HAVOPD.mjs";
14
- import "./chunk-WSNV6EX5.mjs";
13
+ } from "./chunk-RKA3X3EY.mjs";
14
+ import "./chunk-574ILQTT.mjs";
15
15
  import "./chunk-F7JXIW6T.mjs";
16
16
  import "./chunk-K2JGFKEB.mjs";
17
17
  import {
@@ -19,7 +19,7 @@ import {
19
19
  } from "./chunk-IXIM7BNO.mjs";
20
20
  import {
21
21
  chat_modal_default
22
- } from "./chunk-4RRQQPFZ.mjs";
22
+ } from "./chunk-TQP3GUW5.mjs";
23
23
  import {
24
24
  FeedbackButton,
25
25
  FeedbackModal,
@@ -37,7 +37,7 @@ import {
37
37
  useTTS,
38
38
  useVoiceStore,
39
39
  voiceService
40
- } from "./chunk-JJTUEC2E.mjs";
40
+ } from "./chunk-OLKDPUWL.mjs";
41
41
  import {
42
42
  DEFAULT_TIER_FEATURES,
43
43
  FeatureFlagContext,
@@ -15611,8 +15611,10 @@ var init_FeedbackModal = __esm({
15611
15611
  overflow: "hidden",
15612
15612
  display: "flex",
15613
15613
  flexDirection: "column",
15614
- height: "100dvh",
15615
- maxHeight: "100dvh",
15614
+ // Size to the (now condensed) content instead of pinning to the
15615
+ // full viewport — a mostly-empty full-height sheet looked broken.
15616
+ height: isMobile ? "100dvh" : "auto",
15617
+ maxHeight: isMobile ? "100dvh" : "90vh",
15616
15618
  margin: isMobile ? 0 : "auto",
15617
15619
  position: "relative"
15618
15620
  }
@@ -15736,7 +15738,11 @@ var init_FeedbackModal = __esm({
15736
15738
  gridTemplateRows: "auto auto auto auto",
15737
15739
  rowGap: "16px",
15738
15740
  columnGap: "0px",
15739
- width: "100%"
15741
+ width: "100%",
15742
+ // Headroom for the first field's floating label — MUI zeroes
15743
+ // DialogContent's top padding after a DialogTitle, which clipped
15744
+ // the "Title" label under the header.
15745
+ pt: 1.5
15740
15746
  },
15741
15747
  children: [
15742
15748
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
@@ -20564,7 +20570,7 @@ var init_source_chips = __esm({
20564
20570
  });
20565
20571
 
20566
20572
  // src/chat/chat-messages.tsx
20567
- var import_material36, import_jsx_runtime36, ChatMessages, chat_messages_default;
20573
+ var import_material36, import_jsx_runtime36, WORKING_TOKEN_RE, ToolWorkingChip, ChatMessages, chat_messages_default;
20568
20574
  var init_chat_messages = __esm({
20569
20575
  "src/chat/chat-messages.tsx"() {
20570
20576
  "use strict";
@@ -20574,6 +20580,38 @@ var init_chat_messages = __esm({
20574
20580
  init_source_chips();
20575
20581
  init_conversationStore();
20576
20582
  import_jsx_runtime36 = require("react/jsx-runtime");
20583
+ WORKING_TOKEN_RE = /\s*<<working:([^>]*)>>\s*$/;
20584
+ ToolWorkingChip = ({ label }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
20585
+ import_material36.Box,
20586
+ {
20587
+ sx: (theme) => ({
20588
+ display: "inline-flex",
20589
+ alignItems: "center",
20590
+ gap: 1.25,
20591
+ mt: 1.5,
20592
+ px: 1.75,
20593
+ py: 0.9,
20594
+ borderRadius: 999,
20595
+ bgcolor: theme.palette.action.hover,
20596
+ border: `1px solid ${theme.palette.divider}`
20597
+ }),
20598
+ children: [
20599
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "typing-only", children: [
20600
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "dot" }),
20601
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "dot" }),
20602
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "dot" })
20603
+ ] }),
20604
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
20605
+ import_material36.Box,
20606
+ {
20607
+ component: "span",
20608
+ sx: { fontSize: "0.85rem", fontWeight: 500, color: "text.secondary", userSelect: "none" },
20609
+ children: label || "Working on it"
20610
+ }
20611
+ )
20612
+ ]
20613
+ }
20614
+ );
20577
20615
  ChatMessages = ({
20578
20616
  pendingMessage,
20579
20617
  streamBuffer,
@@ -20599,7 +20637,9 @@ var init_chat_messages = __esm({
20599
20637
  const isPlaceholder = entry.answer === "...";
20600
20638
  const showLoader = isLast && isStreaming && streamBuffer.trim() === "";
20601
20639
  const showThinking = showLoader && isThinking;
20602
- const content = isLast ? isStreaming ? streamBuffer || "" : isPlaceholder ? "" : entry.answer : entry.answer;
20640
+ const rawContent = isLast ? isStreaming ? streamBuffer || "" : isPlaceholder ? "" : entry.answer : entry.answer;
20641
+ const workingMatch = isLast && isStreaming ? rawContent.match(WORKING_TOKEN_RE) : null;
20642
+ const content = workingMatch ? rawContent.replace(WORKING_TOKEN_RE, "") : rawContent;
20603
20643
  const rawSources = entry.sourceFiles;
20604
20644
  const sourceSummaries = rawSources ? rawSources.filter((doc) => doc && typeof doc.name === "string" && doc.name.trim()).map((doc) => ({ id: doc.id || doc.name, name: doc.name.trim() })) : void 0;
20605
20645
  const responseNode = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
@@ -20672,6 +20712,7 @@ var init_chat_messages = __esm({
20672
20712
  sources: sourceSummaries
20673
20713
  }
20674
20714
  ),
20715
+ workingMatch && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ToolWorkingChip, { label: workingMatch[1] }),
20675
20716
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(source_chips_default, { content })
20676
20717
  ]
20677
20718
  }
@@ -20684,7 +20725,7 @@ var init_chat_messages = __esm({
20684
20725
  {
20685
20726
  question: entry.question,
20686
20727
  response: responseNode,
20687
- responseText: isLast ? isStreaming ? streamBuffer || "" : isPlaceholder ? "" : entry.answer : entry.answer,
20728
+ responseText: content,
20688
20729
  backgroundColor: "#444",
20689
20730
  images: entry.images,
20690
20731
  memoryUpdated: entry.memoryUpdated && !isPlaceholder,
@@ -24233,8 +24274,20 @@ ${protocol}`;
24233
24274
  return result.trimStart();
24234
24275
  };
24235
24276
  const stripToolBlocks = (text) => text.replace(/```(?:tool_code|TOOL_CODE)\s*\n[\s\S]*?\n```/gi, "").trim();
24277
+ const truncateAtToolApparatus = (text) => {
24278
+ let t = text;
24279
+ const fenceIdx = t.search(/```(?:tool_code|TOOL_CODE)/);
24280
+ if (fenceIdx !== -1) t = t.slice(0, fenceIdx);
24281
+ const callIdx = t.search(
24282
+ /\b(?:web_search|web_fetch|image_generation|create_file|ask_user)\s*\(/
24283
+ );
24284
+ if (callIdx !== -1) t = t.slice(0, callIdx);
24285
+ t = t.replace(/```[\w-]*\s*$/, "");
24286
+ const fenceCount = (t.match(/```/g) || []).length;
24287
+ if (fenceCount % 2 === 1) t = t.slice(0, t.lastIndexOf("```"));
24288
+ return t.trim();
24289
+ };
24236
24290
  let workingLabel = "Working on it";
24237
- let workingPreamble = "";
24238
24291
  const stopWorking = () => {
24239
24292
  if (workingTimer) {
24240
24293
  clearInterval(workingTimer);
@@ -24243,17 +24296,10 @@ ${protocol}`;
24243
24296
  };
24244
24297
  const startWorking = (label = "Working on it") => {
24245
24298
  workingLabel = label.replace(/[.…]+\s*$/, "").trim() || "Working on it";
24246
- workingPreamble = stripToolBlocks(stripThinking(fullMessage)).trim();
24247
- if (workingTimer) return;
24248
- let dots = 0;
24249
- const render = () => {
24250
- dots = (dots + 1) % 4;
24251
- setStreamBuffer(
24252
- `${workingPreamble}${workingPreamble ? "\n\n" : ""}_${workingLabel}${".".repeat(dots)}_`
24253
- );
24254
- };
24255
- render();
24256
- workingTimer = setInterval(render, 450);
24299
+ const preamble = truncateAtToolApparatus(stripToolBlocks(stripThinking(fullMessage)));
24300
+ setStreamBuffer(
24301
+ `${preamble}${preamble ? "\n\n" : ""}<<working:${workingLabel}>>`
24302
+ );
24257
24303
  };
24258
24304
  const flushNow = () => {
24259
24305
  clearFlushTimer();
@@ -24299,10 +24345,16 @@ ${protocol}`;
24299
24345
  const inThinkBlock = /<think>/.test(fullMessage) && !/<think>[\s\S]*<\/think>/.test(fullMessage);
24300
24346
  setIsThinking?.(inThinkBlock);
24301
24347
  const visibleMessage = stripThinking(fullMessage);
24302
- if (/```(?:tool_code|TOOL_CODE)/.test(visibleMessage) || /\b(?:web_search|web_fetch|image_generation|create_file|ask_user)\s*\(/.test(visibleMessage)) {
24348
+ const bareToolMatch = visibleMessage.match(
24349
+ /\b(web_search|web_fetch|image_generation|create_file|ask_user)\s*\(/
24350
+ );
24351
+ if (/```(?:tool_code|TOOL_CODE)/.test(visibleMessage) || bareToolMatch) {
24303
24352
  sawToolBlock = true;
24304
24353
  clearFlushTimer();
24305
- startWorking();
24354
+ const fn = bareToolMatch?.[1];
24355
+ startWorking(
24356
+ fn === "create_file" ? "Creating your file" : fn === "web_search" ? "Searching the web" : fn === "web_fetch" ? "Reading the page" : fn === "image_generation" ? "Generating the image" : "Working on it"
24357
+ );
24306
24358
  }
24307
24359
  latestDisplayMessage = visibleMessage;
24308
24360
  if (!sawToolBlock) {