@burtson-labs/bandit-engine 2.0.125 → 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-2WFTEJPS.mjs";
3
+ } from "./chunk-JXFPCLEY.mjs";
4
4
  import {
5
5
  chat_provider_default
6
6
  } from "./chunk-SAQUEXYS.mjs";
@@ -10,7 +10,7 @@ import {
10
10
  useGatewayHealth,
11
11
  useGatewayMemory,
12
12
  useGatewayModels
13
- } from "./chunk-ID6CTZ3G.mjs";
13
+ } from "./chunk-RKA3X3EY.mjs";
14
14
  import "./chunk-574ILQTT.mjs";
15
15
  import "./chunk-F7JXIW6T.mjs";
16
16
  import "./chunk-K2JGFKEB.mjs";
@@ -20570,7 +20570,7 @@ var init_source_chips = __esm({
20570
20570
  });
20571
20571
 
20572
20572
  // src/chat/chat-messages.tsx
20573
- 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;
20574
20574
  var init_chat_messages = __esm({
20575
20575
  "src/chat/chat-messages.tsx"() {
20576
20576
  "use strict";
@@ -20580,6 +20580,38 @@ var init_chat_messages = __esm({
20580
20580
  init_source_chips();
20581
20581
  init_conversationStore();
20582
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
+ );
20583
20615
  ChatMessages = ({
20584
20616
  pendingMessage,
20585
20617
  streamBuffer,
@@ -20605,7 +20637,9 @@ var init_chat_messages = __esm({
20605
20637
  const isPlaceholder = entry.answer === "...";
20606
20638
  const showLoader = isLast && isStreaming && streamBuffer.trim() === "";
20607
20639
  const showThinking = showLoader && isThinking;
20608
- 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;
20609
20643
  const rawSources = entry.sourceFiles;
20610
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;
20611
20645
  const responseNode = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
@@ -20678,6 +20712,7 @@ var init_chat_messages = __esm({
20678
20712
  sources: sourceSummaries
20679
20713
  }
20680
20714
  ),
20715
+ workingMatch && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ToolWorkingChip, { label: workingMatch[1] }),
20681
20716
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(source_chips_default, { content })
20682
20717
  ]
20683
20718
  }
@@ -20690,7 +20725,7 @@ var init_chat_messages = __esm({
20690
20725
  {
20691
20726
  question: entry.question,
20692
20727
  response: responseNode,
20693
- responseText: isLast ? isStreaming ? streamBuffer || "" : isPlaceholder ? "" : entry.answer : entry.answer,
20728
+ responseText: content,
20694
20729
  backgroundColor: "#444",
20695
20730
  images: entry.images,
20696
20731
  memoryUpdated: entry.memoryUpdated && !isPlaceholder,
@@ -24239,8 +24274,20 @@ ${protocol}`;
24239
24274
  return result.trimStart();
24240
24275
  };
24241
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
+ };
24242
24290
  let workingLabel = "Working on it";
24243
- let workingPreamble = "";
24244
24291
  const stopWorking = () => {
24245
24292
  if (workingTimer) {
24246
24293
  clearInterval(workingTimer);
@@ -24249,17 +24296,10 @@ ${protocol}`;
24249
24296
  };
24250
24297
  const startWorking = (label = "Working on it") => {
24251
24298
  workingLabel = label.replace(/[.…]+\s*$/, "").trim() || "Working on it";
24252
- workingPreamble = stripToolBlocks(stripThinking(fullMessage)).trim();
24253
- if (workingTimer) return;
24254
- let dots = 0;
24255
- const render = () => {
24256
- dots = (dots + 1) % 4;
24257
- setStreamBuffer(
24258
- `${workingPreamble}${workingPreamble ? "\n\n" : ""}_${workingLabel}${".".repeat(dots)}_`
24259
- );
24260
- };
24261
- render();
24262
- workingTimer = setInterval(render, 450);
24299
+ const preamble = truncateAtToolApparatus(stripToolBlocks(stripThinking(fullMessage)));
24300
+ setStreamBuffer(
24301
+ `${preamble}${preamble ? "\n\n" : ""}<<working:${workingLabel}>>`
24302
+ );
24263
24303
  };
24264
24304
  const flushNow = () => {
24265
24305
  clearFlushTimer();
@@ -24305,10 +24345,16 @@ ${protocol}`;
24305
24345
  const inThinkBlock = /<think>/.test(fullMessage) && !/<think>[\s\S]*<\/think>/.test(fullMessage);
24306
24346
  setIsThinking?.(inThinkBlock);
24307
24347
  const visibleMessage = stripThinking(fullMessage);
24308
- 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) {
24309
24352
  sawToolBlock = true;
24310
24353
  clearFlushTimer();
24311
- 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
+ );
24312
24358
  }
24313
24359
  latestDisplayMessage = visibleMessage;
24314
24360
  if (!sawToolBlock) {