@burtson-labs/bandit-engine 2.0.127 → 2.0.129

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.
Files changed (31) hide show
  1. package/dist/{chat-2XYHFUT2.mjs → chat-TO26ORKD.mjs} +5 -5
  2. package/dist/chat-provider.js +1 -1
  3. package/dist/chat-provider.js.map +1 -1
  4. package/dist/chat-provider.mjs +2 -2
  5. package/dist/{chunk-RRSACJI2.mjs → chunk-3LOS2EAN.mjs} +135 -448
  6. package/dist/chunk-3LOS2EAN.mjs.map +1 -0
  7. package/dist/{chunk-OLKDPUWL.mjs → chunk-BQW7DSJ6.mjs} +2 -2
  8. package/dist/{chunk-574ILQTT.mjs → chunk-FWFDOSRM.mjs} +2 -2
  9. package/dist/{chunk-TQP3GUW5.mjs → chunk-N3TVVQVS.mjs} +3 -3
  10. package/dist/{chunk-6ONL4SRK.mjs → chunk-NLBZZP3B.mjs} +2 -2
  11. package/dist/{chunk-6ONL4SRK.mjs.map → chunk-NLBZZP3B.mjs.map} +1 -1
  12. package/dist/{chunk-SAQUEXYS.mjs → chunk-PU74BI6Y.mjs} +2 -2
  13. package/dist/{chunk-7NBLIL76.mjs → chunk-VXGJ4XH6.mjs} +23 -6
  14. package/dist/chunk-VXGJ4XH6.mjs.map +1 -0
  15. package/dist/index.js +148 -442
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.mjs +7 -7
  18. package/dist/management/management.js +148 -442
  19. package/dist/management/management.js.map +1 -1
  20. package/dist/management/management.mjs +5 -5
  21. package/dist/modals/chat-modal/chat-modal.js +1 -1
  22. package/dist/modals/chat-modal/chat-modal.js.map +1 -1
  23. package/dist/modals/chat-modal/chat-modal.mjs +3 -3
  24. package/package.json +1 -1
  25. package/dist/chunk-7NBLIL76.mjs.map +0 -1
  26. package/dist/chunk-RRSACJI2.mjs.map +0 -1
  27. /package/dist/{chat-2XYHFUT2.mjs.map → chat-TO26ORKD.mjs.map} +0 -0
  28. /package/dist/{chunk-OLKDPUWL.mjs.map → chunk-BQW7DSJ6.mjs.map} +0 -0
  29. /package/dist/{chunk-574ILQTT.mjs.map → chunk-FWFDOSRM.mjs.map} +0 -0
  30. /package/dist/{chunk-TQP3GUW5.mjs.map → chunk-N3TVVQVS.mjs.map} +0 -0
  31. /package/dist/{chunk-SAQUEXYS.mjs.map → chunk-PU74BI6Y.mjs.map} +0 -0
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ONQMRE2G.mjs";
4
4
  import {
5
5
  StreamingMarkdown_default
6
- } from "./chunk-574ILQTT.mjs";
6
+ } from "./chunk-FWFDOSRM.mjs";
7
7
  import {
8
8
  useMCPToolsStore
9
9
  } from "./chunk-K2JGFKEB.mjs";
@@ -26,7 +26,6 @@ import {
26
26
  MicIcon,
27
27
  PanelLeftIcon,
28
28
  PsychologyIcon,
29
- RecordVoiceOverIcon,
30
29
  SignalWifi2BarIcon,
31
30
  WifiIcon,
32
31
  WifiOffIcon,
@@ -40,7 +39,7 @@ import {
40
39
  useNotificationService,
41
40
  useTTS,
42
41
  useVoiceStore
43
- } from "./chunk-OLKDPUWL.mjs";
42
+ } from "./chunk-BQW7DSJ6.mjs";
44
43
  import {
45
44
  brandingService_default,
46
45
  detectMessageMood,
@@ -64,7 +63,7 @@ import {
64
63
  useMemoryStore,
65
64
  useProjectStore,
66
65
  useVectorStore
67
- } from "./chunk-6ONL4SRK.mjs";
66
+ } from "./chunk-NLBZZP3B.mjs";
68
67
  import {
69
68
  indexedDBService_default,
70
69
  useModelStore,
@@ -851,7 +850,7 @@ var ChatMessages = ({
851
850
  StreamingMarkdown_default,
852
851
  {
853
852
  content: linkifyCitations(stripSourcesForDisplay(content), parseWebSources(content)),
854
- isStreaming: isStreaming && isLast,
853
+ isStreaming: isStreaming && isLast && !workingMatch,
855
854
  sources: sourceSummaries
856
855
  }
857
856
  ),
@@ -1895,7 +1894,7 @@ ${sanitize(
1895
1894
  fullWidth: true,
1896
1895
  multiline: true,
1897
1896
  maxRows: compactMobile ? 6 : 12,
1898
- placeholder: isIncognito ? "Incognito chat \u2014 not saved" : "What's on your mind?",
1897
+ placeholder: isIncognito ? "Temporary chat \u2014 not saved" : "What's on your mind?",
1899
1898
  value: inputValue,
1900
1899
  onChange: (e) => setInputValue(e.target.value),
1901
1900
  onKeyDown: handleKeyPress,
@@ -2019,7 +2018,7 @@ ${sanitize(
2019
2018
  fullWidth: true,
2020
2019
  multiline: true,
2021
2020
  maxRows: 6,
2022
- placeholder: isIncognito ? "Incognito chat \u2014 not saved" : "What's on your mind?",
2021
+ placeholder: isIncognito ? "Temporary chat \u2014 not saved" : "What's on your mind?",
2023
2022
  value: inputValue,
2024
2023
  onChange: (e) => setInputValue(e.target.value),
2025
2024
  onKeyDown: handleKeyPress,
@@ -2037,26 +2036,29 @@ ${sanitize(
2037
2036
  sx: { flex: 1, alignSelf: "center", mx: 0.5 }
2038
2037
  }
2039
2038
  ),
2040
- /* @__PURE__ */ jsx9(Box6, { sx: { display: "flex", alignItems: "center", gap: isMobile ? 0.6 : 1 }, children: /* @__PURE__ */ jsx9(Tooltip2, { title: isStreaming ? "Stop response" : "Send message", children: /* @__PURE__ */ jsx9("span", { children: /* @__PURE__ */ jsx9(
2041
- IconButton5,
2042
- {
2043
- onClick: isStreaming ? onStop || (() => {
2044
- }) : handleSubmit,
2045
- disabled: (isStreaming ? false : isSubmitting) || !isStreaming && !inputValue.trim() && pastedImages.length === 0 && fileInputs.length === 0,
2046
- sx: {
2047
- bgcolor: sendButtonBackground,
2048
- color: sendButtonColor,
2049
- borderRadius: "50%",
2050
- width: sendIconSize,
2051
- height: sendIconSize,
2052
- boxShadow: sendButtonShadow,
2053
- transition: "background-color 0.2s ease, box-shadow 0.2s ease",
2054
- "&:hover": { bgcolor: sendButtonHover },
2055
- "&.Mui-disabled": { opacity: 0.5 }
2056
- },
2057
- children: isStreaming ? /* @__PURE__ */ jsx9(CloseIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx9(ArrowUpwardIcon, { fontSize: "small" })
2058
- }
2059
- ) }) }) })
2039
+ /* @__PURE__ */ jsxs6(Box6, { sx: { display: "flex", alignItems: "center", gap: isMobile ? 0.6 : 1 }, children: [
2040
+ !isMobile && /* @__PURE__ */ jsx9(engine_picker_default, {}),
2041
+ /* @__PURE__ */ jsx9(Tooltip2, { title: isStreaming ? "Stop response" : "Send message", children: /* @__PURE__ */ jsx9("span", { children: /* @__PURE__ */ jsx9(
2042
+ IconButton5,
2043
+ {
2044
+ onClick: isStreaming ? onStop || (() => {
2045
+ }) : handleSubmit,
2046
+ disabled: (isStreaming ? false : isSubmitting) || !isStreaming && !inputValue.trim() && pastedImages.length === 0 && fileInputs.length === 0,
2047
+ sx: {
2048
+ bgcolor: sendButtonBackground,
2049
+ color: sendButtonColor,
2050
+ borderRadius: "50%",
2051
+ width: sendIconSize,
2052
+ height: sendIconSize,
2053
+ boxShadow: sendButtonShadow,
2054
+ transition: "background-color 0.2s ease, box-shadow 0.2s ease",
2055
+ "&:hover": { bgcolor: sendButtonHover },
2056
+ "&.Mui-disabled": { opacity: 0.5 }
2057
+ },
2058
+ children: isStreaming ? /* @__PURE__ */ jsx9(CloseIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx9(ArrowUpwardIcon, { fontSize: "small" })
2059
+ }
2060
+ ) }) })
2061
+ ] })
2060
2062
  ]
2061
2063
  }
2062
2064
  ),
@@ -2103,7 +2105,7 @@ ${sanitize(
2103
2105
  ]
2104
2106
  }
2105
2107
  ),
2106
- !isMobile && /* @__PURE__ */ jsxs6(
2108
+ (!isMobile || isIncognito) && /* @__PURE__ */ jsx9(
2107
2109
  Typography3,
2108
2110
  {
2109
2111
  variant: "caption",
@@ -2115,10 +2117,7 @@ ${sanitize(
2115
2117
  textAlign: "center",
2116
2118
  pointerEvents: "none"
2117
2119
  },
2118
- children: [
2119
- brandingText || "BanditAI",
2120
- " may be wrong - double-check important info."
2121
- ]
2120
+ children: isIncognito ? "Temporary chats aren't saved to history, synced, or added to memory." : `${brandingText || "BanditAI"} may be wrong - double-check important info.`
2122
2121
  }
2123
2122
  )
2124
2123
  ]
@@ -5312,8 +5311,6 @@ import { useEffect as useEffect13, useRef as useRef11, useState as useState16 }
5312
5311
  import {
5313
5312
  Box as Box15,
5314
5313
  IconButton as IconButton12,
5315
- Menu as Menu7,
5316
- MenuItem as MenuItem7,
5317
5314
  Tooltip as Tooltip5,
5318
5315
  useMediaQuery as useMediaQuery6,
5319
5316
  useTheme as useTheme15,
@@ -9163,13 +9160,13 @@ var ChatAppBar = ({
9163
9160
  /* @__PURE__ */ jsx18(
9164
9161
  Tooltip5,
9165
9162
  {
9166
- title: isIncognitoActive ? "End incognito chat" : "Start incognito chat \u2014 not saved",
9163
+ title: isIncognitoActive ? "End temporary chat" : "Temporary chat \u2014 not saved anywhere",
9167
9164
  arrow: true,
9168
9165
  children: /* @__PURE__ */ jsx18(
9169
9166
  IconButton12,
9170
9167
  {
9171
9168
  onClick: toggleIncognito,
9172
- "aria-label": isIncognitoActive ? "End incognito chat" : "Start incognito chat",
9169
+ "aria-label": isIncognitoActive ? "End temporary chat" : "Start temporary chat",
9173
9170
  "aria-pressed": isIncognitoActive,
9174
9171
  sx: {
9175
9172
  width: 44,
@@ -9268,35 +9265,11 @@ var ChatAppBar = ({
9268
9265
  "aria-label": "Create new conversation",
9269
9266
  children: /* @__PURE__ */ jsx18(AddIcon, {})
9270
9267
  }
9271
- ) }),
9272
- /* @__PURE__ */ jsx18(
9273
- Tooltip5,
9274
- {
9275
- title: isIncognitoActive ? "End incognito chat" : "Start incognito chat \u2014 not saved",
9276
- arrow: true,
9277
- children: /* @__PURE__ */ jsx18(
9278
- IconButton12,
9279
- {
9280
- onClick: toggleIncognito,
9281
- "aria-label": isIncognitoActive ? "End incognito chat" : "Start incognito chat",
9282
- "aria-pressed": isIncognitoActive,
9283
- sx: {
9284
- ...pillButtonStyles,
9285
- ...isIncognitoActive && {
9286
- bgcolor: theme.palette.text.primary,
9287
- color: theme.palette.getContrastText(theme.palette.text.primary),
9288
- "&:hover": { bgcolor: theme.palette.text.primary }
9289
- }
9290
- },
9291
- children: /* @__PURE__ */ jsx18(GhostIcon, {})
9292
- }
9293
- )
9294
- }
9295
- )
9268
+ ) })
9296
9269
  ]
9297
9270
  }
9298
9271
  ),
9299
- !isMobile && /* @__PURE__ */ jsxs15(
9272
+ !isMobile && /* @__PURE__ */ jsx18(
9300
9273
  Box15,
9301
9274
  {
9302
9275
  sx: {
@@ -9316,368 +9289,30 @@ var ChatAppBar = ({
9316
9289
  boxShadow: theme.palette.mode === "dark" ? "0 6px 20px rgba(0,0,0,0.4)" : "0 6px 20px rgba(0,0,0,0.15)"
9317
9290
  }
9318
9291
  },
9319
- children: [
9320
- /* @__PURE__ */ jsx18(Tooltip5, { title: `Current AI: ${selectedModel.replace("Bandit-", "")}`, arrow: true, children: /* @__PURE__ */ jsx18(
9321
- IconButton12,
9322
- {
9323
- onClick: (e) => setModelAnchorEl(e.currentTarget),
9324
- sx: {
9325
- ...pillButtonStyles,
9326
- "&:hover": {
9327
- ...pillButtonStyles["&:hover"],
9328
- "& .MuiAvatar-root": {
9329
- transform: "scale(1.1)",
9330
- filter: "brightness(2) saturate(1.2)"
9331
- }
9332
- }
9333
- },
9334
- "aria-label": `Change AI personality. Currently using ${selectedModel}`,
9335
- children: /* @__PURE__ */ jsx18(
9336
- Avatar8,
9337
- {
9338
- src: currentAvatar,
9339
- alt: selectedModel,
9340
- sx: {
9341
- width: "36px",
9342
- height: "36px",
9343
- filter: "brightness(1.7)",
9344
- transition: "all 0.2s ease-in-out",
9345
- border: `2px solid ${theme.palette.primary.main}20`
9346
- },
9347
- className: "MuiAvatar-root"
9348
- }
9349
- )
9350
- }
9351
- ) }),
9352
- /* @__PURE__ */ jsx18(Tooltip5, { title: `Engine \xB7 ${engineDisplay}`, arrow: true, children: /* @__PURE__ */ jsx18(
9353
- IconButton12,
9354
- {
9355
- onClick: (e) => setEngineAnchorEl(e.currentTarget),
9356
- sx: pillButtonStyles,
9357
- "aria-label": `Change base model (engine). Currently ${engineDisplay}`,
9358
- children: /* @__PURE__ */ jsx18(AutoAwesomeIcon, { fontSize: "small" })
9359
- }
9360
- ) }),
9361
- /* @__PURE__ */ jsxs15(
9362
- Menu7,
9363
- {
9364
- anchorEl: engineAnchorEl,
9365
- open: Boolean(engineAnchorEl),
9366
- onClose: () => setEngineAnchorEl(null),
9367
- transformOrigin: { horizontal: "right", vertical: "top" },
9368
- anchorOrigin: { horizontal: "right", vertical: "bottom" },
9369
- children: [
9370
- /* @__PURE__ */ jsx18(Typography12, { variant: "overline", sx: { px: 2, color: theme.palette.text.secondary }, children: "Engine \xB7 base model" }),
9371
- engines.length === 0 && /* @__PURE__ */ jsx18(MenuItem7, { disabled: true, children: /* @__PURE__ */ jsx18(Typography12, { variant: "body2", children: "No engines available" }) }),
9372
- engines.map((engine) => {
9373
- const badges = [
9374
- engine.vision && "vision",
9375
- engine.tools && "tools",
9376
- engine.thinking && "thinking",
9377
- engine.cloud && "cloud"
9378
- ].filter(Boolean);
9379
- const isGated = engine.cloud && !frontierEligible;
9380
- return /* @__PURE__ */ jsxs15(
9381
- MenuItem7,
9382
- {
9383
- selected: engine.id === resolvedEngineId,
9384
- disabled: !engine.available || isGated,
9385
- onClick: () => {
9386
- if (isGated) return;
9387
- useEngineStore.getState().setSelectedEngine(engine.id);
9388
- setEngineAnchorEl(null);
9389
- },
9390
- sx: {
9391
- display: "flex",
9392
- flexDirection: "column",
9393
- alignItems: "flex-start",
9394
- gap: 0.5,
9395
- py: 1,
9396
- px: 2,
9397
- maxWidth: 360,
9398
- whiteSpace: "normal",
9399
- // Keep gated rows readable (MUI disabled dims to ~38%) so the
9400
- // upsell stays legible.
9401
- ...isGated ? { opacity: 1, "&.Mui-disabled": { opacity: 1 } } : {}
9402
- },
9403
- children: [
9404
- /* @__PURE__ */ jsxs15(Box15, { sx: { display: "flex", alignItems: "center", gap: 1, width: "100%" }, children: [
9405
- isGated && /* @__PURE__ */ jsx18(
9406
- LockIcon,
9407
- {
9408
- fontSize: "small",
9409
- sx: { fontSize: "0.95rem", color: theme.palette.text.secondary }
9410
- }
9411
- ),
9412
- /* @__PURE__ */ jsx18(
9413
- Typography12,
9414
- {
9415
- variant: "body2",
9416
- sx: {
9417
- fontWeight: 600,
9418
- flex: 1,
9419
- color: isGated ? theme.palette.text.secondary : void 0
9420
- },
9421
- children: cleanEngineName(engine.displayName)
9422
- }
9423
- ),
9424
- engine.id === resolvedEngineId && !isGated && /* @__PURE__ */ jsx18(Box15, { sx: { width: 8, height: 8, borderRadius: "50%", bgcolor: theme.palette.primary.main } })
9425
- ] }),
9426
- /* @__PURE__ */ jsx18(Typography12, { variant: "caption", sx: { color: theme.palette.text.secondary }, children: isGated ? "Premium engine \u2014 available on a paid plan." : engine.available ? engine.description : engine.unavailableReason || "Unavailable" }),
9427
- isGated && /* @__PURE__ */ jsx18(
9428
- Button9,
9429
- {
9430
- size: "small",
9431
- variant: "text",
9432
- startIcon: /* @__PURE__ */ jsx18(LockIcon, { sx: { fontSize: "0.85rem" } }),
9433
- onClick: (e) => {
9434
- e.stopPropagation();
9435
- setEngineAnchorEl(null);
9436
- safeNavigate(plansPath);
9437
- },
9438
- sx: {
9439
- mt: 0.25,
9440
- px: 0.75,
9441
- py: 0.1,
9442
- minWidth: 0,
9443
- textTransform: "none",
9444
- fontSize: "0.7rem",
9445
- fontWeight: 600,
9446
- color: theme.palette.primary.main,
9447
- // Re-enable pointer events the disabled MenuItem strips.
9448
- pointerEvents: "auto"
9449
- },
9450
- children: "Upgrade to unlock"
9451
- }
9452
- ),
9453
- badges.length > 0 && /* @__PURE__ */ jsx18(Box15, { sx: { display: "flex", gap: 0.5, flexWrap: "wrap", mt: 0.25 }, children: badges.map((b) => /* @__PURE__ */ jsx18(
9454
- Box15,
9455
- {
9456
- sx: {
9457
- fontSize: "0.65rem",
9458
- px: 0.75,
9459
- py: 0.1,
9460
- borderRadius: 1,
9461
- bgcolor: theme.palette.primary.main + "22",
9462
- color: theme.palette.primary.main
9463
- },
9464
- children: b
9465
- },
9466
- b
9467
- )) })
9468
- ]
9469
- },
9470
- engine.id
9471
- );
9472
- })
9473
- ]
9474
- }
9475
- ),
9476
- /* @__PURE__ */ jsx18(
9477
- Menu7,
9478
- {
9479
- anchorEl: modelAnchorEl,
9480
- open: Boolean(modelAnchorEl),
9481
- onClose: () => setModelAnchorEl(null),
9482
- transformOrigin: { horizontal: "right", vertical: "top" },
9483
- anchorOrigin: { horizontal: "right", vertical: "bottom" },
9484
- PaperProps: {
9485
- sx: {
9486
- bgcolor: menuBackground,
9487
- color: menuText,
9488
- fontSize: "0.875rem",
9489
- zIndex: 2e4,
9490
- borderRadius: 2,
9491
- border: `1px solid ${border}`,
9492
- boxShadow: theme.palette.mode === "dark" ? "0 8px 32px rgba(0,0,0,0.5)" : "0 8px 32px rgba(0,0,0,0.2)",
9493
- minWidth: 200,
9494
- "& .MuiMenuItem-root": {
9495
- transition: "all 0.15s ease-in-out",
9496
- borderRadius: "6px",
9497
- margin: "2px 4px",
9498
- "&:hover": {
9499
- bgcolor: theme.palette.mode === "dark" ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.04)",
9500
- transform: "translateX(2px)"
9501
- },
9502
- "&.Mui-selected": {
9503
- bgcolor: theme.palette.primary.main + "20",
9504
- color: theme.palette.primary.main,
9505
- "&:hover": {
9506
- bgcolor: theme.palette.primary.main + "30"
9507
- }
9508
- }
9509
- }
9510
- }
9511
- },
9512
- children: availableModels.map((model) => /* @__PURE__ */ jsxs15(
9513
- MenuItem7,
9514
- {
9515
- selected: model.name === selectedModel,
9516
- onClick: () => {
9517
- if (!currentConversation?.history.length || currentConversation?.history.length === 0) {
9518
- handleModelChange(model.name);
9519
- useModelStore.getState().setSelectedModel(model.name);
9520
- (async () => {
9521
- try {
9522
- const storeConfigs = [{ name: "config", keyPath: "id" }];
9523
- const current = await indexedDBService_default.get(
9524
- "banditConfig",
9525
- 1,
9526
- "config",
9527
- "main",
9528
- storeConfigs
9529
- );
9530
- const updated = {
9531
- ...current ?? {},
9532
- id: "main",
9533
- model: {
9534
- ...current?.model || {},
9535
- name: model.name,
9536
- selectedModel: model.name
9537
- }
9538
- };
9539
- await indexedDBService_default.put("banditConfig", 1, "config", updated, storeConfigs);
9540
- } catch (err) {
9541
- debugLogger.error("Failed to persist selectedModel to IndexedDB", { error: err });
9542
- }
9543
- })();
9544
- setModelAnchorEl(null);
9545
- return;
9546
- }
9547
- setPendingModel(model.name);
9548
- setConfirmModelChangeOpen(true);
9549
- setModelAnchorEl(null);
9550
- },
9551
- sx: {
9552
- display: "flex",
9553
- alignItems: "center",
9554
- gap: 1.5,
9555
- minHeight: 48,
9556
- px: 2
9557
- },
9558
- children: [
9559
- /* @__PURE__ */ jsx18(
9560
- Avatar8,
9561
- {
9562
- src: model.avatarBase64 || modelAvatars[model.name] || banditHead,
9563
- alt: model.name,
9564
- sx: {
9565
- width: 28,
9566
- height: 28,
9567
- filter: "brightness(1.7)",
9568
- transition: "all 0.2s ease-in-out"
9569
- }
9570
- }
9571
- ),
9572
- /* @__PURE__ */ jsxs15(Box15, { sx: { flex: 1 }, children: [
9573
- /* @__PURE__ */ jsx18(Typography12, { variant: "body2", sx: { fontWeight: 500 }, children: model.name.replace("Bandit-", "") }),
9574
- /* @__PURE__ */ jsx18(Typography12, { variant: "caption", sx: { color: theme.palette.text.secondary, display: "block" }, children: model.name === selectedModel ? "Currently active" : "Switch to this AI" })
9575
- ] }),
9576
- model.name === selectedModel && /* @__PURE__ */ jsx18(
9577
- Box15,
9578
- {
9579
- sx: {
9580
- width: 8,
9581
- height: 8,
9582
- borderRadius: "50%",
9583
- bgcolor: theme.palette.primary.main
9584
- }
9585
- }
9586
- )
9587
- ]
9588
- },
9589
- model.name
9590
- ))
9591
- }
9592
- ),
9593
- isTTSAvailable && /* @__PURE__ */ jsxs15(Fragment10, { children: [
9594
- /* @__PURE__ */ jsx18(Tooltip5, { title: `Voice: ${selectedVoice ? toTitleCase(selectedVoice.split("-")[1]) : "Default"}`, arrow: true, children: /* @__PURE__ */ jsx18(
9292
+ children: /* @__PURE__ */ jsx18(
9293
+ Tooltip5,
9294
+ {
9295
+ title: isIncognitoActive ? "End temporary chat" : "Temporary chat \u2014 not saved anywhere",
9296
+ arrow: true,
9297
+ children: /* @__PURE__ */ jsx18(
9595
9298
  IconButton12,
9596
9299
  {
9597
- onClick: (e) => setVoiceAnchorEl(e.currentTarget),
9300
+ onClick: toggleIncognito,
9301
+ "aria-label": isIncognitoActive ? "End temporary chat" : "Start temporary chat",
9302
+ "aria-pressed": isIncognitoActive,
9598
9303
  sx: {
9599
9304
  ...pillButtonStyles,
9600
- bgcolor: theme.palette.info.main + "20",
9601
- color: theme.palette.info.main,
9602
- "&:hover": {
9603
- ...pillButtonStyles["&:hover"],
9604
- bgcolor: theme.palette.info.main + "30"
9305
+ ...isIncognitoActive && {
9306
+ bgcolor: theme.palette.text.primary,
9307
+ color: theme.palette.getContrastText(theme.palette.text.primary),
9308
+ "&:hover": { bgcolor: theme.palette.text.primary }
9605
9309
  }
9606
9310
  },
9607
- "aria-label": `Change voice. Currently using ${selectedVoice ? toTitleCase(selectedVoice.split("-")[1]) : "default"}`,
9608
- children: /* @__PURE__ */ jsx18(RecordVoiceOverIcon, { fontSize: "small" })
9609
- }
9610
- ) }),
9611
- /* @__PURE__ */ jsx18(
9612
- Menu7,
9613
- {
9614
- anchorEl: voiceAnchorEl,
9615
- open: Boolean(voiceAnchorEl),
9616
- onClose: () => setVoiceAnchorEl(null),
9617
- transformOrigin: { horizontal: "right", vertical: "top" },
9618
- anchorOrigin: { horizontal: "right", vertical: "bottom" },
9619
- PaperProps: {
9620
- sx: {
9621
- bgcolor: menuBackground,
9622
- color: menuText,
9623
- fontSize: "0.875rem",
9624
- zIndex: 2e4,
9625
- borderRadius: 2,
9626
- border: `1px solid ${border}`,
9627
- boxShadow: theme.palette.mode === "dark" ? "0 8px 32px rgba(0,0,0,0.5)" : "0 8px 32px rgba(0,0,0,0.2)",
9628
- minWidth: 180,
9629
- "& .MuiMenuItem-root": {
9630
- transition: "all 0.15s ease-in-out",
9631
- borderRadius: "6px",
9632
- margin: "2px 4px",
9633
- minHeight: 40,
9634
- "&:hover": {
9635
- bgcolor: theme.palette.mode === "dark" ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.04)",
9636
- transform: "translateX(2px)"
9637
- },
9638
- "&.Mui-selected": {
9639
- bgcolor: theme.palette.info.main + "20",
9640
- color: theme.palette.info.main,
9641
- "&:hover": {
9642
- bgcolor: theme.palette.info.main + "30"
9643
- }
9644
- }
9645
- }
9646
- }
9647
- },
9648
- children: availableVoices.length > 0 ? availableVoices.map((voice) => /* @__PURE__ */ jsx18(
9649
- MenuItem7,
9650
- {
9651
- selected: voice === selectedVoice,
9652
- onClick: () => {
9653
- handleVoiceChange(voice);
9654
- setVoiceAnchorEl(null);
9655
- },
9656
- children: /* @__PURE__ */ jsxs15(Box15, { sx: { display: "flex", alignItems: "center", gap: 1, width: "100%" }, children: [
9657
- /* @__PURE__ */ jsx18(RecordVoiceOverIcon, { fontSize: "small", sx: { color: theme.palette.text.secondary } }),
9658
- /* @__PURE__ */ jsxs15(Box15, { sx: { flex: 1 }, children: [
9659
- /* @__PURE__ */ jsx18(Typography12, { variant: "body2", children: toTitleCase(voice.split("-")[1]) }),
9660
- /* @__PURE__ */ jsx18(Typography12, { variant: "caption", sx: { color: theme.palette.text.secondary }, children: voice === selectedVoice ? "Currently active" : "Switch to this voice" })
9661
- ] }),
9662
- voice === selectedVoice && /* @__PURE__ */ jsx18(
9663
- Box15,
9664
- {
9665
- sx: {
9666
- width: 8,
9667
- height: 8,
9668
- borderRadius: "50%",
9669
- bgcolor: theme.palette.info.main
9670
- }
9671
- }
9672
- )
9673
- ] })
9674
- },
9675
- voice
9676
- )) : /* @__PURE__ */ jsx18(MenuItem7, { disabled: true, children: /* @__PURE__ */ jsx18(Typography12, { variant: "body2", color: "text.secondary", children: "No voices available" }) })
9311
+ children: /* @__PURE__ */ jsx18(GhostIcon, {})
9677
9312
  }
9678
9313
  )
9679
- ] })
9680
- ]
9314
+ }
9315
+ )
9681
9316
  }
9682
9317
  )
9683
9318
  ]
@@ -10433,7 +10068,7 @@ var useVoiceMode = (config) => {
10433
10068
  };
10434
10069
 
10435
10070
  // src/chat/chat.tsx
10436
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
10071
+ import { Fragment as Fragment12, jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
10437
10072
  var ChatContent = () => {
10438
10073
  const packageSettings = usePackageSettingsStore((state) => state.settings);
10439
10074
  const UnderReviewView = packageSettings?.components?.UnderReview ?? UnderReview_default;
@@ -10548,7 +10183,8 @@ var ChatContent = () => {
10548
10183
  const [inputHeight, setInputHeight] = useState18(80);
10549
10184
  const [isSubmitting, setIsSubmitting] = useState18(false);
10550
10185
  const [pendingMessage, setPendingMessage] = useState18(null);
10551
- const { conversations, currentId, _hasHydrated, hydrate } = useConversationStore();
10186
+ const { conversations, currentId, _hasHydrated, hydrate, toggleIncognito } = useConversationStore();
10187
+ const isTemporaryChat = Boolean(conversations.find((c) => c.id === currentId)?.incognito);
10552
10188
  const [isMobile, setIsMobile] = useState18(false);
10553
10189
  const [drawerOpen, setDrawerOpen] = useState18(false);
10554
10190
  const [mobileConversationsOpen, setMobileConversationsOpen] = useState18(false);
@@ -11401,12 +11037,11 @@ var ChatContent = () => {
11401
11037
  width: !isMobile && canvasOpen ? `calc(100vw - ${drawerOpen ? "340px" : "0px"} - ${CANVAS_WIDTH})` : drawerOpen && !isMobile ? "calc(100vw - 340px)" : "100vw",
11402
11038
  zIndex: 0,
11403
11039
  // Claude-style push (mobile only; desktop stays flush): the chat
11404
- // shell slides right and shrinks slightly into a rounded card. The
11405
- // scale insets the card from every screen edge so all four rounded
11406
- // corners stay visible — a full-height 100dvh card had its bottom
11407
- // corners clipped at the device edge in the PWA. Width kept in sync
11040
+ // shell slides right as a full-height rounded card — exactly like
11041
+ // Claude iOS, where the card runs edge-to-edge vertically and the
11042
+ // hairline border keeps the corners legible. Width kept in sync
11408
11043
  // with the drawer in enhanced-mobile-conversations-modal.tsx.
11409
- transform: isMobile && mobileConversationsOpen ? "translateX(min(calc(100vw - 56px), 360px)) scale(0.96)" : "none",
11044
+ transform: isMobile && mobileConversationsOpen ? "translateX(min(calc(100vw - 56px), 360px))" : "none",
11410
11045
  borderRadius: isMobile && mobileConversationsOpen ? "24px" : 0,
11411
11046
  // Hairline border so the rounded card reads even when the backdrop
11412
11047
  // is the same near-black as the shell.
@@ -11429,30 +11064,82 @@ var ChatContent = () => {
11429
11064
  onMobileConversationsOpenChange: setMobileConversationsOpen
11430
11065
  }
11431
11066
  ),
11432
- conversations.find((c) => c.id === currentId)?.incognito && /* @__PURE__ */ jsx22(
11433
- Box19,
11434
- {
11435
- sx: (theme) => ({
11436
- position: "absolute",
11437
- top: `calc(${theme.spacing(8)} + env(safe-area-inset-top, 0px))`,
11438
- left: "50%",
11439
- transform: "translateX(-50%)",
11440
- zIndex: 1200,
11441
- px: 1.5,
11442
- py: 0.5,
11443
- borderRadius: 999,
11444
- fontSize: "0.75rem",
11445
- fontWeight: 600,
11446
- color: theme.palette.text.secondary,
11447
- bgcolor: theme.palette.mode === "dark" ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.06)",
11448
- border: `1px solid ${theme.palette.divider}`,
11449
- backdropFilter: "blur(8px)",
11450
- pointerEvents: "none",
11451
- whiteSpace: "nowrap"
11452
- }),
11453
- children: "Incognito \u2014 this chat won't be saved"
11454
- }
11455
- ),
11067
+ isTemporaryChat && /* @__PURE__ */ jsxs17(Fragment12, { children: [
11068
+ /* @__PURE__ */ jsx22(
11069
+ Box19,
11070
+ {
11071
+ sx: (theme) => ({
11072
+ position: "absolute",
11073
+ inset: 0,
11074
+ border: `2px solid ${theme.palette.mode === "dark" ? "rgba(255,255,255,0.45)" : "rgba(0,0,0,0.4)"}`,
11075
+ borderRadius: "inherit",
11076
+ zIndex: 1400,
11077
+ pointerEvents: "none"
11078
+ })
11079
+ }
11080
+ ),
11081
+ /* @__PURE__ */ jsxs17(
11082
+ Box19,
11083
+ {
11084
+ sx: (theme) => ({
11085
+ position: "absolute",
11086
+ top: `calc(${theme.spacing(8)} + env(safe-area-inset-top, 0px))`,
11087
+ left: "50%",
11088
+ transform: "translateX(-50%)",
11089
+ zIndex: 1401,
11090
+ display: "flex",
11091
+ alignItems: "center",
11092
+ gap: 0.75,
11093
+ pl: 1.5,
11094
+ pr: 0.75,
11095
+ py: 0.4,
11096
+ borderRadius: 999,
11097
+ fontSize: "0.78rem",
11098
+ fontWeight: 600,
11099
+ color: theme.palette.text.primary,
11100
+ bgcolor: theme.palette.mode === "dark" ? "rgba(255,255,255,0.12)" : "rgba(0,0,0,0.08)",
11101
+ border: `1px solid ${theme.palette.divider}`,
11102
+ backdropFilter: "blur(8px)",
11103
+ whiteSpace: "nowrap"
11104
+ }),
11105
+ children: [
11106
+ /* @__PURE__ */ jsx22(Box19, { component: "span", "aria-hidden": true, sx: { fontSize: "0.9rem", lineHeight: 1 }, children: "\u{1F47B}" }),
11107
+ "Temporary chat",
11108
+ /* @__PURE__ */ jsx22(
11109
+ Box19,
11110
+ {
11111
+ component: "button",
11112
+ type: "button",
11113
+ onClick: toggleIncognito,
11114
+ "aria-label": "End temporary chat",
11115
+ sx: (theme) => ({
11116
+ display: "inline-flex",
11117
+ alignItems: "center",
11118
+ justifyContent: "center",
11119
+ width: 20,
11120
+ height: 20,
11121
+ ml: 0.25,
11122
+ p: 0,
11123
+ border: "none",
11124
+ borderRadius: "50%",
11125
+ cursor: "pointer",
11126
+ color: theme.palette.text.secondary,
11127
+ bgcolor: "transparent",
11128
+ font: "inherit",
11129
+ fontSize: "0.85rem",
11130
+ lineHeight: 1,
11131
+ "&:hover": {
11132
+ bgcolor: theme.palette.mode === "dark" ? "rgba(255,255,255,0.15)" : "rgba(0,0,0,0.1)",
11133
+ color: theme.palette.text.primary
11134
+ }
11135
+ }),
11136
+ children: "\u2715"
11137
+ }
11138
+ )
11139
+ ]
11140
+ }
11141
+ )
11142
+ ] }),
11456
11143
  /* @__PURE__ */ jsx22(
11457
11144
  Box19,
11458
11145
  {
@@ -11680,4 +11367,4 @@ var chat_default = Chat;
11680
11367
  export {
11681
11368
  chat_default
11682
11369
  };
11683
- //# sourceMappingURL=chunk-RRSACJI2.mjs.map
11370
+ //# sourceMappingURL=chunk-3LOS2EAN.mjs.map