@burtson-labs/bandit-engine 2.0.130 → 2.0.132

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-POQY66ZJ.mjs";
3
+ } from "./chunk-7KFVACAY.mjs";
4
4
  import {
5
5
  chat_provider_default
6
6
  } from "./chunk-PU74BI6Y.mjs";
@@ -10,7 +10,7 @@ import {
10
10
  useGatewayHealth,
11
11
  useGatewayMemory,
12
12
  useGatewayModels
13
- } from "./chunk-R7LKVTK7.mjs";
13
+ } from "./chunk-PMOZWSW2.mjs";
14
14
  import "./chunk-BVYSGIWG.mjs";
15
15
  import "./chunk-F7JXIW6T.mjs";
16
16
  import "./chunk-K2JGFKEB.mjs";
@@ -20437,7 +20437,7 @@ var init_source_chips = __esm({
20437
20437
  });
20438
20438
 
20439
20439
  // src/chat/chat-messages.tsx
20440
- var import_material36, import_jsx_runtime36, WORKING_TOKEN_RE, ToolWorkingChip, ChatMessages, chat_messages_default;
20440
+ var import_material36, import_jsx_runtime36, WORKING_TOKEN_RE, BYTE_TOKEN_RUN_RE, decodeByteTokens, ToolWorkingChip, ChatMessages, chat_messages_default;
20441
20441
  var init_chat_messages = __esm({
20442
20442
  "src/chat/chat-messages.tsx"() {
20443
20443
  "use strict";
@@ -20448,6 +20448,18 @@ var init_chat_messages = __esm({
20448
20448
  init_conversationStore();
20449
20449
  import_jsx_runtime36 = require("react/jsx-runtime");
20450
20450
  WORKING_TOKEN_RE = /\s*<<working:([^>]*)>>\s*$/;
20451
+ BYTE_TOKEN_RUN_RE = /(?:<0x[0-9A-Fa-f]{2}>)+/g;
20452
+ decodeByteTokens = (text) => {
20453
+ if (!text || text.indexOf("<0x") === -1) return text;
20454
+ return text.replace(BYTE_TOKEN_RUN_RE, (run) => {
20455
+ const bytes = Array.from(run.matchAll(/<0x([0-9A-Fa-f]{2})>/g), (m) => parseInt(m[1], 16));
20456
+ try {
20457
+ return new TextDecoder("utf-8", { fatal: true }).decode(new Uint8Array(bytes));
20458
+ } catch {
20459
+ return "";
20460
+ }
20461
+ });
20462
+ };
20451
20463
  ToolWorkingChip = ({ label }) => /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
20452
20464
  import_material36.Box,
20453
20465
  {
@@ -20498,7 +20510,7 @@ var init_chat_messages = __esm({
20498
20510
  const lastIndex = history.length - 1;
20499
20511
  const hasActivePlaceholder = lastIndex >= 0 && history[lastIndex]?.answer === "...";
20500
20512
  if (!responseStarted && !pendingMessage && history.length === 0) return null;
20501
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_material36.Box, { sx: { px: isMobile ? 0 : 0, pt: "100px", display: "flex", flexDirection: "column", gap: 2 }, children: [
20513
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_material36.Box, { sx: { px: isMobile ? 0 : 0, pt: "calc(100px + env(safe-area-inset-top, 0px))", display: "flex", flexDirection: "column", gap: 2 }, children: [
20502
20514
  history.map((entry, index) => {
20503
20515
  const isLast = index === lastIndex;
20504
20516
  const isPlaceholder = entry.answer === "...";
@@ -20506,7 +20518,9 @@ var init_chat_messages = __esm({
20506
20518
  const showThinking = showLoader && isThinking;
20507
20519
  const rawContent = isLast ? isStreaming ? streamBuffer || "" : isPlaceholder ? "" : entry.answer : entry.answer;
20508
20520
  const workingMatch = isLast && isStreaming ? rawContent.match(WORKING_TOKEN_RE) : null;
20509
- const content = workingMatch ? rawContent.replace(WORKING_TOKEN_RE, "") : rawContent;
20521
+ const content = decodeByteTokens(
20522
+ workingMatch ? rawContent.replace(WORKING_TOKEN_RE, "") : rawContent
20523
+ );
20510
20524
  const rawSources = entry.sourceFiles;
20511
20525
  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;
20512
20526
  const responseNode = /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
@@ -28116,7 +28130,10 @@ var init_enhanced_mobile_conversations_modal = __esm({
28116
28130
  display: "flex",
28117
28131
  flexDirection: "column",
28118
28132
  overflow: "hidden",
28119
- outline: "none"
28133
+ outline: "none",
28134
+ // Edge-to-edge PWA: the drawer surface runs under the status
28135
+ // bar (like Claude); its content starts below it.
28136
+ pt: "env(safe-area-inset-top, 0px)"
28120
28137
  },
28121
28138
  children: [
28122
28139
  /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
@@ -29005,6 +29022,8 @@ var init_chat_app_bar = __esm({
29005
29022
  width: "100%",
29006
29023
  px: 2,
29007
29024
  py: 1,
29025
+ // Edge-to-edge PWA: keep the pills below the status bar / notch.
29026
+ pt: "calc(8px + env(safe-area-inset-top, 0px))",
29008
29027
  display: "flex",
29009
29028
  alignItems: "center",
29010
29029
  justifyContent: "space-between",
@@ -29723,7 +29742,7 @@ var init_FeedbackPulse = __esm({
29723
29742
  recordInteraction("dismissed");
29724
29743
  setVisible(false);
29725
29744
  };
29726
- const choice = (emoji, label, outcome) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
29745
+ const choice = (icon, label, outcome) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(
29727
29746
  import_material52.Box,
29728
29747
  {
29729
29748
  component: "button",
@@ -29750,7 +29769,7 @@ var init_FeedbackPulse = __esm({
29750
29769
  "&:active": { transform: "scale(0.96)" }
29751
29770
  },
29752
29771
  children: [
29753
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Box, { component: "span", sx: { fontSize: "1.3rem", lineHeight: 1 }, children: emoji }),
29772
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Box, { component: "span", sx: { display: "inline-flex", lineHeight: 1 }, children: icon }),
29754
29773
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Typography, { variant: "caption", sx: { fontWeight: 600 }, children: label })
29755
29774
  ]
29756
29775
  }
@@ -29775,15 +29794,15 @@ var init_FeedbackPulse = __esm({
29775
29794
  bgcolor: theme.palette.background.paper,
29776
29795
  boxShadow: `0 12px 40px ${(0, import_styles33.alpha)(theme.palette.common.black, theme.palette.mode === "dark" ? 0.5 : 0.18)}`
29777
29796
  },
29778
- children: thanked ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Typography, { sx: { textAlign: "center", py: 1.5, fontWeight: 600 }, children: "Thanks for the feedback! \u{1F64C}" }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
29797
+ children: thanked ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Typography, { sx: { textAlign: "center", py: 1.5, fontWeight: 600 }, children: "Thanks for the feedback!" }) : /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_jsx_runtime51.Fragment, { children: [
29779
29798
  /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_material52.Box, { sx: { display: "flex", alignItems: "center", mb: 0.5 }, children: [
29780
29799
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.Typography, { variant: "body2", sx: { fontWeight: 600, flex: 1 }, children: "How's Bandit doing?" }),
29781
29800
  /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_material52.IconButton, { size: "small", onClick: dismiss, "aria-label": "Dismiss feedback prompt", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react16.X, { size: 16 }) })
29782
29801
  ] }),
29783
29802
  /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_material52.Box, { sx: { display: "flex", justifyContent: "space-evenly" }, children: [
29784
- choice("\u{1F60A}", "Good", "good"),
29785
- choice("\u{1F610}", "Fine", "fine"),
29786
- choice("\u{1F641}", "Bad", "bad")
29803
+ choice(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react16.Smile, { size: 22, color: theme.palette.success.main }), "Good", "good"),
29804
+ choice(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react16.Meh, { size: 22, color: theme.palette.warning.main }), "Fine", "fine"),
29805
+ choice(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_lucide_react16.Frown, { size: 22, color: theme.palette.error.main }), "Bad", "bad")
29787
29806
  ] })
29788
29807
  ] })
29789
29808
  }
@@ -30197,7 +30216,7 @@ var chat_exports = {};
30197
30216
  __export(chat_exports, {
30198
30217
  default: () => chat_default
30199
30218
  });
30200
- var import_react63, import_material54, import_styles34, import_react_router_dom5, import_jsx_runtime53, ChatContent, Chat, chat_default;
30219
+ var import_react63, import_material54, import_styles34, import_react_router_dom5, import_lucide_react17, import_jsx_runtime53, ChatContent, Chat, chat_default;
30201
30220
  var init_chat2 = __esm({
30202
30221
  "src/chat/chat.tsx"() {
30203
30222
  "use strict";
@@ -30243,6 +30262,7 @@ var init_chat2 = __esm({
30243
30262
  init_voiceModeStore();
30244
30263
  init_ttsSanitizer();
30245
30264
  init_FeatureFlagContext();
30265
+ import_lucide_react17 = require("lucide-react");
30246
30266
  import_jsx_runtime53 = require("react/jsx-runtime");
30247
30267
  ChatContent = () => {
30248
30268
  const packageSettings = usePackageSettingsStore((state) => state.settings);
@@ -31278,7 +31298,7 @@ var init_chat2 = __esm({
31278
31298
  whiteSpace: "nowrap"
31279
31299
  }),
31280
31300
  children: [
31281
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_material54.Box, { component: "span", "aria-hidden": true, sx: { fontSize: "0.9rem", lineHeight: 1 }, children: "\u{1F47B}" }),
31301
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_lucide_react17.Ghost, { size: 14, "aria-hidden": true }),
31282
31302
  "Temporary chat",
31283
31303
  /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
31284
31304
  import_material54.Box,
@@ -36384,7 +36404,12 @@ var PreferencesTab = ({
36384
36404
  const timeoutRef = (0, import_react27.useRef)(null);
36385
36405
  const fileInputRef = (0, import_react27.useRef)(null);
36386
36406
  const { exportPreferences, importPreferences, resetToDefaults } = usePreferencesStore();
36387
- const { isServiceAvailable: isTTSSTTAvailable } = useVoiceStore();
36407
+ const {
36408
+ isServiceAvailable: isTTSSTTAvailable,
36409
+ availableVoices,
36410
+ selectedVoice,
36411
+ setSelectedVoice
36412
+ } = useVoiceStore();
36388
36413
  const { hasAdvancedSearch, hasAdvancedMemories } = useFeatures();
36389
36414
  const {
36390
36415
  initialized: syncInitialized,
@@ -37004,6 +37029,19 @@ var PreferencesTab = ({
37004
37029
  ] })
37005
37030
  }
37006
37031
  ),
37032
+ preferences.ttsEnabled && isTTSSTTAvailable && availableVoices.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_material20.FormControl, { size: "small", sx: { ml: 6, mt: 1, maxWidth: 280 }, children: [
37033
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material20.InputLabel, { id: "tts-voice-label", children: "Voice" }),
37034
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
37035
+ import_material20.Select,
37036
+ {
37037
+ labelId: "tts-voice-label",
37038
+ label: "Voice",
37039
+ value: availableVoices.includes(selectedVoice) ? selectedVoice : "",
37040
+ onChange: (e) => setSelectedVoice(e.target.value),
37041
+ children: availableVoices.map((voice) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material20.MenuItem, { value: voice, children: voice.split("-")[1] ? voice.split("-")[1].charAt(0).toUpperCase() + voice.split("-")[1].slice(1) : voice }, voice))
37042
+ }
37043
+ )
37044
+ ] }),
37007
37045
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
37008
37046
  import_material20.FormControlLabel,
37009
37047
  {