@burtson-labs/bandit-engine 2.0.136 → 2.0.137

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
@@ -19345,6 +19345,8 @@ ${sanitize(
19345
19345
  const hasFeedbackAction = isFeedbackEnabled && isMobile;
19346
19346
  const hasSttAction = isSTTAvailable && !isVoiceModeEnabled;
19347
19347
  const hasVoicePickerAction = isMobile && isTTSAvailable && availableVoices.length > 0;
19348
+ const hasComposeContent = !!inputValue.trim() || pastedImages.length > 0 || fileInputs.length > 0;
19349
+ const showSendButton = streamingActive || hasComposeContent || !isVoiceModeEligible;
19348
19350
  const hasSecondaryActions = isMobile && (hasAttachmentAction || hasMemoryAction || hasFeedbackAction || hasSttAction || hasVoicePickerAction);
19349
19351
  (0, import_react23.useEffect)(() => {
19350
19352
  if (!isMobile || !hasSecondaryActions) {
@@ -19409,6 +19411,33 @@ ${sanitize(
19409
19411
  if (!hasSttAction) return null;
19410
19412
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material18.Box, { sx: { display: "flex", alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(transcriber_default, { onTranscriptionCompleted: handleTranscriptionCompleted }) }, key ?? "stt");
19411
19413
  };
19414
+ const renderVoiceModeButton = (key) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19415
+ import_material18.Tooltip,
19416
+ {
19417
+ title: !isVoiceModeEnabled ? "Enable voice mode" : voiceStatus === "error" ? voiceError || "Voice mode error" : voiceStatus === "processing" ? "Transcribing your speech" : voiceStatus === "recording" ? "Recording - click to stop" : voiceStatus === "initializing" ? "Preparing microphone" : "Listening - click to turn off",
19418
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19419
+ import_material18.IconButton,
19420
+ {
19421
+ onClick: toggleVoiceMode,
19422
+ sx: {
19423
+ width: sendIconSize,
19424
+ height: sendIconSize,
19425
+ borderRadius: "50%",
19426
+ bgcolor: isVoiceModeEnabled ? (0, import_styles10.alpha)(theme.palette.error.main, theme.palette.mode === "dark" ? 0.45 : 0.3) : fileText,
19427
+ color: isVoiceModeEnabled ? theme.palette.common.white : fileIconBg,
19428
+ boxShadow: isVoiceModeEnabled && voiceStatus === "recording" ? `0 0 0 2px ${(0, import_styles10.alpha)(theme.palette.error.main, 0.25)}` : "none",
19429
+ transform: isVoiceModeEnabled && voiceStatus === "recording" ? "scale(1.05)" : "none",
19430
+ transition: "transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease",
19431
+ "&:hover": {
19432
+ bgcolor: isVoiceModeEnabled ? (0, import_styles10.alpha)(theme.palette.error.main, theme.palette.mode === "dark" ? 0.55 : 0.38) : hoverBadgeBackground
19433
+ }
19434
+ },
19435
+ children: !isVoiceModeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GraphicEqIcon, { fontSize: "small" }) : voiceStatus === "processing" || voiceStatus === "initializing" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material18.CircularProgress, { size: 18, sx: { color: theme.palette.common.white } }) : voiceStatus === "error" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(HearingDisabledIcon, { fontSize: "small", sx: { color: theme.palette.error.light } }) : voiceStatus === "recording" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GraphicEqIcon, { fontSize: "small", sx: { color: theme.palette.error.light } }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GraphicEqIcon, { fontSize: "small", sx: { color: theme.palette.common.white } })
19436
+ }
19437
+ )
19438
+ },
19439
+ key ?? "voice-mode"
19440
+ );
19412
19441
  const renderVoicePickerButton = (key) => {
19413
19442
  if (!hasVoicePickerAction) return null;
19414
19443
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material18.Tooltip, { title: `Voice: ${selectedVoice ? toTitleCase(selectedVoice.split("-")[1] ?? selectedVoice) : "Default"}`, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
@@ -19656,51 +19685,22 @@ ${sanitize(
19656
19685
  minHeight: primaryIconSize
19657
19686
  },
19658
19687
  children: [
19659
- isVoiceModeEligible && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
19660
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19661
- import_material18.Tooltip,
19662
- {
19663
- title: !isVoiceModeEnabled ? "Enable voice mode" : voiceStatus === "error" ? voiceError || "Voice mode error" : voiceStatus === "processing" ? "Transcribing your speech" : voiceStatus === "recording" ? "Recording - click to stop" : voiceStatus === "initializing" ? "Preparing microphone" : "Listening - click to turn off",
19664
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19665
- import_material18.IconButton,
19666
- {
19667
- onClick: toggleVoiceMode,
19668
- sx: {
19669
- width: primaryIconSize,
19670
- height: primaryIconSize,
19671
- borderRadius: "50%",
19672
- bgcolor: isVoiceModeEnabled ? (0, import_styles10.alpha)(theme.palette.error.main, theme.palette.mode === "dark" ? 0.45 : 0.3) : badgeBackground,
19673
- color: isVoiceModeEnabled ? theme.palette.common.white : fileText,
19674
- boxShadow: isVoiceModeEnabled && voiceStatus === "recording" ? `0 0 0 2px ${(0, import_styles10.alpha)(theme.palette.error.main, 0.25)}` : "none",
19675
- transform: isVoiceModeEnabled && voiceStatus === "recording" ? "scale(1.05)" : "none",
19676
- transition: "transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease",
19677
- "&:hover": {
19678
- bgcolor: isVoiceModeEnabled ? (0, import_styles10.alpha)(theme.palette.error.main, theme.palette.mode === "dark" ? 0.55 : 0.38) : hoverBadgeBackground
19679
- }
19680
- },
19681
- children: !isVoiceModeEnabled ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GraphicEqIcon, { fontSize: "small", sx: { color: theme.palette.mode === "dark" ? fileText : theme.palette.text.secondary } }) : voiceStatus === "processing" || voiceStatus === "initializing" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material18.CircularProgress, { size: 18, sx: { color: fileText } }) : voiceStatus === "error" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(HearingDisabledIcon, { fontSize: "small", sx: { color: theme.palette.error.light } }) : voiceStatus === "recording" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GraphicEqIcon, { fontSize: "small", sx: { color: theme.palette.error.light } }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(GraphicEqIcon, { fontSize: "small", sx: { color: theme.palette.common.white } })
19682
- }
19683
- )
19684
- }
19685
- ),
19686
- !isMobile && isVoiceModeEnabled && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19687
- import_material18.Typography,
19688
- {
19689
- variant: "caption",
19690
- sx: {
19691
- color: voiceStatus === "error" ? theme.palette.error.main : voiceStatus === "processing" ? theme.palette.warning.main : fileText,
19692
- maxWidth: 240,
19693
- overflow: "hidden",
19694
- textOverflow: "ellipsis",
19695
- whiteSpace: "nowrap"
19696
- },
19697
- children: voiceStatus === "error" ? voiceError || "Voice mode unavailable" : voiceStatus === "initializing" ? "Starting voice mode..." : voiceStatus === "recording" ? "Recording..." : voiceStatus === "processing" ? "Transcribing..." : voiceLastTranscript ? `Heard: "${voiceLastTranscript.length > 60 ? `${voiceLastTranscript.slice(0, 57)}...` : voiceLastTranscript}"` : "Listening..."
19698
- }
19699
- )
19700
- ] }),
19701
19688
  !isMobile && renderAttachmentButton("attach-inline"),
19702
19689
  !isMobile && renderMemoryButton("memory-inline"),
19703
- !isMobile && renderSttButton("stt-inline"),
19690
+ !isMobile && isVoiceModeEligible && isVoiceModeEnabled && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19691
+ import_material18.Typography,
19692
+ {
19693
+ variant: "caption",
19694
+ sx: {
19695
+ color: voiceStatus === "error" ? theme.palette.error.main : voiceStatus === "processing" ? theme.palette.warning.main : fileText,
19696
+ maxWidth: 240,
19697
+ overflow: "hidden",
19698
+ textOverflow: "ellipsis",
19699
+ whiteSpace: "nowrap"
19700
+ },
19701
+ children: voiceStatus === "error" ? voiceError || "Voice mode unavailable" : voiceStatus === "initializing" ? "Starting voice mode..." : voiceStatus === "recording" ? "Recording..." : voiceStatus === "processing" ? "Transcribing..." : voiceLastTranscript ? `Heard: "${voiceLastTranscript.length > 60 ? `${voiceLastTranscript.slice(0, 57)}...` : voiceLastTranscript}"` : "Listening..."
19702
+ }
19703
+ ),
19704
19704
  isMobile && hasSecondaryActions && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19705
19705
  import_material18.IconButton,
19706
19706
  {
@@ -19756,7 +19756,9 @@ ${sanitize(
19756
19756
  ),
19757
19757
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_material18.Box, { sx: { display: "flex", alignItems: "center", gap: isMobile ? 0.6 : 1 }, children: [
19758
19758
  !isMobile && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(engine_picker_default, {}),
19759
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material18.Tooltip, { title: isStreaming ? "Stop response" : "Send message", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19759
+ !isMobile && renderSttButton("stt-right"),
19760
+ isVoiceModeEligible && !showSendButton && renderVoiceModeButton("voice-right"),
19761
+ showSendButton && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_material18.Tooltip, { title: isStreaming ? "Stop response" : "Send message", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
19760
19762
  import_material18.IconButton,
19761
19763
  {
19762
19764
  onClick: isStreaming ? onStop || (() => {