@burdenoff/fe-libs 2026.926.5 → 2026.927.2

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 (95) hide show
  1. package/dist/shared/assistant/conversation.d.ts +91 -3
  2. package/dist/shared/assistant/conversation.d.ts.map +1 -1
  3. package/dist/shared/assistant/gatewayClient.d.ts +15 -0
  4. package/dist/shared/assistant/gatewayClient.d.ts.map +1 -1
  5. package/dist/shared/assistant/gatewayClient.js +1 -1
  6. package/dist/shared/assistant/guardedStorage.d.ts +4 -2
  7. package/dist/shared/assistant/guardedStorage.d.ts.map +1 -1
  8. package/dist/shared/assistant/guardedStorage.js +1 -1
  9. package/dist/shared/assistant/history/historyApi.d.ts +38 -0
  10. package/dist/shared/assistant/history/historyApi.d.ts.map +1 -0
  11. package/dist/shared/assistant/history/historyApi.js +153 -0
  12. package/dist/shared/assistant/history/historyEngine.d.ts +96 -0
  13. package/dist/shared/assistant/history/historyEngine.d.ts.map +1 -0
  14. package/dist/shared/assistant/history/historyEngine.js +774 -0
  15. package/dist/shared/assistant/history/historyErrors.d.ts +72 -0
  16. package/dist/shared/assistant/history/historyErrors.d.ts.map +1 -0
  17. package/dist/shared/assistant/history/historyErrors.js +74 -0
  18. package/dist/shared/assistant/history/historyList.d.ts +115 -0
  19. package/dist/shared/assistant/history/historyList.d.ts.map +1 -0
  20. package/dist/shared/assistant/history/historyList.js +116 -0
  21. package/dist/shared/assistant/history/historyMapping.d.ts +65 -0
  22. package/dist/shared/assistant/history/historyMapping.d.ts.map +1 -0
  23. package/dist/shared/assistant/history/historyMapping.js +383 -0
  24. package/dist/shared/assistant/history/historyMerge.d.ts +65 -0
  25. package/dist/shared/assistant/history/historyMerge.d.ts.map +1 -0
  26. package/dist/shared/assistant/history/historyMerge.js +97 -0
  27. package/dist/shared/assistant/history/historyOperations.d.ts +24 -0
  28. package/dist/shared/assistant/history/historyOperations.d.ts.map +1 -0
  29. package/dist/shared/assistant/history/historyOperations.js +125 -0
  30. package/dist/shared/assistant/history/historyResume.d.ts +56 -0
  31. package/dist/shared/assistant/history/historyResume.d.ts.map +1 -0
  32. package/dist/shared/assistant/history/historyResume.js +55 -0
  33. package/dist/shared/assistant/history/historyStatus.d.ts +76 -0
  34. package/dist/shared/assistant/history/historyStatus.d.ts.map +1 -0
  35. package/dist/shared/assistant/history/historyStatus.js +47 -0
  36. package/dist/shared/assistant/history/historyStore.d.ts +192 -0
  37. package/dist/shared/assistant/history/historyStore.d.ts.map +1 -0
  38. package/dist/shared/assistant/history/historyStore.js +503 -0
  39. package/dist/shared/assistant/history/historyTimestamps.d.ts +11 -0
  40. package/dist/shared/assistant/history/historyTimestamps.d.ts.map +1 -0
  41. package/dist/shared/assistant/history/historyTimestamps.js +9 -0
  42. package/dist/shared/assistant/history/historyTypes.d.ts +256 -0
  43. package/dist/shared/assistant/history/historyTypes.d.ts.map +1 -0
  44. package/dist/shared/assistant/history/historyTypes.js +20 -0
  45. package/dist/shared/assistant/history/profileBoundStorage.d.ts +36 -0
  46. package/dist/shared/assistant/history/profileBoundStorage.d.ts.map +1 -0
  47. package/dist/shared/assistant/history/profileBoundStorage.js +74 -0
  48. package/dist/shared/assistant/history/stampRegistry.d.ts +84 -0
  49. package/dist/shared/assistant/history/stampRegistry.d.ts.map +1 -0
  50. package/dist/shared/assistant/history/stampRegistry.js +58 -0
  51. package/dist/shared/assistant/history/useAssistantServerHistory.d.ts +18 -0
  52. package/dist/shared/assistant/history/useAssistantServerHistory.d.ts.map +1 -0
  53. package/dist/shared/assistant/history/useAssistantServerHistory.js +12 -0
  54. package/dist/shared/assistant/i18nManifest.d.ts +18 -0
  55. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  56. package/dist/shared/assistant/i18nManifest.js +18 -0
  57. package/dist/shared/assistant/index.d.ts +16 -0
  58. package/dist/shared/assistant/index.d.ts.map +1 -1
  59. package/dist/shared/assistant/liveTurns.d.ts +7 -0
  60. package/dist/shared/assistant/liveTurns.d.ts.map +1 -1
  61. package/dist/shared/assistant/liveTurns.js +35 -32
  62. package/dist/shared/assistant/spokenTurns.d.ts +20 -0
  63. package/dist/shared/assistant/spokenTurns.d.ts.map +1 -1
  64. package/dist/shared/assistant/spokenTurns.js +13 -8
  65. package/dist/shared/assistant/store.d.ts +35 -1
  66. package/dist/shared/assistant/store.d.ts.map +1 -1
  67. package/dist/shared/assistant/store.js +93 -24
  68. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +16 -0
  69. package/dist/shared/assistant/ui/AIAssistantPanel.d.ts.map +1 -1
  70. package/dist/shared/assistant/ui/AIAssistantPanel.js +63 -60
  71. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  72. package/dist/shared/assistant/ui/AssistantChatArea.js +730 -672
  73. package/dist/shared/assistant/ui/AssistantConversationList.d.ts +17 -0
  74. package/dist/shared/assistant/ui/AssistantConversationList.d.ts.map +1 -1
  75. package/dist/shared/assistant/ui/AssistantConversationList.js +324 -145
  76. package/dist/shared/assistant/ui/AssistantHistoryNotices.d.ts +36 -0
  77. package/dist/shared/assistant/ui/AssistantHistoryNotices.d.ts.map +1 -0
  78. package/dist/shared/assistant/ui/AssistantHistoryNotices.js +103 -0
  79. package/dist/shared/assistant/ui/AssistantOverlay.d.ts +4 -0
  80. package/dist/shared/assistant/ui/AssistantOverlay.d.ts.map +1 -1
  81. package/dist/shared/assistant/ui/AssistantOverlay.js +97 -94
  82. package/dist/shared/assistant/ui/AssistantSpokenTurnsNotice.d.ts +5 -3
  83. package/dist/shared/assistant/ui/AssistantSpokenTurnsNotice.d.ts.map +1 -1
  84. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +6 -0
  85. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts.map +1 -1
  86. package/dist/shared/assistant/ui/composer/AssistantComposer.js +54 -54
  87. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts +9 -0
  88. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts.map +1 -1
  89. package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.js +37 -32
  90. package/dist/shared/assistant/voice/turnVisibility.d.ts +7 -5
  91. package/dist/shared/assistant/voice/turnVisibility.d.ts.map +1 -1
  92. package/dist/shared/assistant/voice/voiceTranscript.d.ts +3 -2
  93. package/dist/shared/assistant/voice/voiceTranscript.d.ts.map +1 -1
  94. package/dist/shared-assistant.js +153 -137
  95. package/package.json +1 -1
@@ -0,0 +1,103 @@
1
+ import { useAssistantTr as e } from "../i18n.js";
2
+ import { AlertTriangle as t, History as n, Loader2 as r, Lock as i, Trash2 as a, X as o } from "lucide-react";
3
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
4
+ //#region src/shared/assistant/ui/AssistantHistoryNotices.tsx
5
+ var l = ({ state: t, onRetry: n, compact: i = !1 }) => {
6
+ let a = e(), o = i ? "mx-3 mb-2 flex items-center justify-center gap-2 text-xs" : "flex flex-1 flex-col items-center justify-center gap-2 px-4 text-center text-xs";
7
+ return t === "loading" ? /* @__PURE__ */ c("div", {
8
+ role: "status",
9
+ className: `${o} text-text-muted`,
10
+ "data-testid": "assistant-history-loading",
11
+ children: [/* @__PURE__ */ s(r, {
12
+ className: "size-4 motion-safe:animate-spin",
13
+ "aria-hidden": "true"
14
+ }), /* @__PURE__ */ s("span", { children: a("history.loading", "Loading conversation…") })]
15
+ }) : /* @__PURE__ */ c("div", {
16
+ role: "alert",
17
+ className: `${o} text-text-secondary`,
18
+ "data-testid": "assistant-history-load-failed",
19
+ children: [/* @__PURE__ */ s("span", { children: a("history.loadFailed", "Couldn't load this conversation.") }), /* @__PURE__ */ s("button", {
20
+ type: "button",
21
+ onClick: n,
22
+ className: "rounded-md px-2 py-1 font-medium text-action-primary-bg transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
23
+ "data-testid": "assistant-history-retry-load",
24
+ children: a("history.tryAgain", "Try again")
25
+ })]
26
+ });
27
+ }, u = ({ onShowEarlier: t, disabled: r = !1 }) => {
28
+ let i = e();
29
+ return /* @__PURE__ */ c("button", {
30
+ type: "button",
31
+ onClick: t,
32
+ disabled: r,
33
+ className: "mx-auto mt-2 flex items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium text-action-primary-bg transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:opacity-50",
34
+ "data-testid": "assistant-history-show-earlier",
35
+ children: [/* @__PURE__ */ s(n, {
36
+ className: "size-3.5",
37
+ "aria-hidden": "true"
38
+ }), i("history.showEarlier", "Show earlier messages")]
39
+ });
40
+ }, d = ({ onStartNew: t }) => {
41
+ let n = e();
42
+ return /* @__PURE__ */ c("div", {
43
+ className: "mx-3 mb-2 flex items-start gap-2 rounded-lg border border-border-default bg-bg-sunken px-3 py-2 text-xs text-text-secondary",
44
+ "data-testid": "assistant-history-read-only",
45
+ children: [/* @__PURE__ */ s(i, {
46
+ className: "mt-0.5 size-3.5 flex-shrink-0",
47
+ "aria-hidden": "true"
48
+ }), /* @__PURE__ */ c("div", {
49
+ className: "min-w-0 flex-1",
50
+ children: [/* @__PURE__ */ s("p", { children: n("history.legacyReadOnly", "This conversation was saved by an earlier version of the assistant. You can read it, but it can't be continued.") }), /* @__PURE__ */ s("button", {
51
+ type: "button",
52
+ onClick: t,
53
+ className: "mt-1 font-medium text-action-primary-bg hover:underline focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
54
+ "data-testid": "assistant-history-start-new",
55
+ children: n("conversations.startNew", "Start a new conversation")
56
+ })]
57
+ })]
58
+ });
59
+ }, f = ({ onDismiss: t }) => {
60
+ let n = e();
61
+ return /* @__PURE__ */ c("div", {
62
+ role: "status",
63
+ className: "flex items-center gap-2 border-b border-border-subtle bg-bg-sunken/60 px-3 py-2 text-xs text-text-secondary",
64
+ "data-testid": "assistant-history-deleted-elsewhere",
65
+ children: [
66
+ /* @__PURE__ */ s(a, {
67
+ className: "size-3.5 flex-shrink-0",
68
+ "aria-hidden": "true"
69
+ }),
70
+ /* @__PURE__ */ s("span", {
71
+ className: "min-w-0 flex-1",
72
+ children: n("history.deletedElsewhere", "The conversation you had open was deleted on another device.")
73
+ }),
74
+ /* @__PURE__ */ s("button", {
75
+ type: "button",
76
+ onClick: t,
77
+ className: "flex-shrink-0 rounded-md p-1 transition-colors hover:bg-bg-elevated focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
78
+ "aria-label": n("history.dismiss", "Dismiss"),
79
+ "data-testid": "assistant-history-dismiss-deleted",
80
+ children: /* @__PURE__ */ s(o, {
81
+ className: "size-3.5",
82
+ "aria-hidden": "true"
83
+ })
84
+ })
85
+ ]
86
+ });
87
+ }, p = () => {
88
+ let n = e();
89
+ return /* @__PURE__ */ c("div", {
90
+ role: "alert",
91
+ className: "flex items-start gap-2 border-b border-border-subtle bg-bg-sunken/60 px-3 py-2 text-xs text-text-secondary",
92
+ "data-testid": "assistant-history-delete-not-saved",
93
+ children: [/* @__PURE__ */ s(t, {
94
+ className: "mt-0.5 size-3.5 flex-shrink-0",
95
+ "aria-hidden": "true"
96
+ }), /* @__PURE__ */ s("span", {
97
+ className: "min-w-0 flex-1",
98
+ children: n("history.deleteNotSaved", "This device's storage is full, so that delete isn't saved here yet. Keep this page open until it reaches the server.")
99
+ })]
100
+ });
101
+ };
102
+ //#endregion
103
+ export { f as AssistantHistoryDeletedNotice, l as AssistantHistoryLoadState, d as AssistantHistoryReadOnlyBanner, u as AssistantHistoryShowEarlier, p as AssistantHistoryUnsavedDeleteNotice };
@@ -87,6 +87,10 @@ export interface AssistantOverlayProps {
87
87
  * is closed (BOFF-7367). A `renderPanel` wrapper that hands its panel the
88
88
  * same controller should pass it here too; one it passes only to its panel is
89
89
  * bridged by that panel, for that panel's lifetime.
90
+ *
91
+ * ★★ `serverHistory` likewise (BOFF-7335): held on HERE, so the history a
92
+ * closed panel's turns and deletes queued keeps going out, and a reopened
93
+ * panel finds the list already current.
90
94
  */
91
95
  panelProps?: Omit<AIAssistantPanelProps, keyof AssistantOverlayPanelProps>;
92
96
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantOverlay.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAUL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI1C,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,EAmBL,KAAK,oBAAoB,EAC1B,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,oBAAoB,CAAC;CAC5B;AAID,uEAAuE;AACvE,wBAAgB,yBAAyB,IAAI,4BAA4B,GAAG,IAAI,CAE/E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AA6BD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GACnD,IAAI,CAaN;AAID,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KACtD,CAAC;IACF,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,SAAS,EACT,KAAK,EACL,QAAQ,GACT,EAAE,6BAA6B,2CAkE/B;AAED,mDAAmD;AACnD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,0BAA0B,CAAC,CAAC;IAC3E;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,SAAS,CAAC;IAC/D;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAOD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,kDAI5D"}
1
+ {"version":3,"file":"AssistantOverlay.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAUL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAK1C,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,OAAO,EAmBL,KAAK,oBAAoB,EAC1B,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,oBAAoB,CAAC;CAC5B;AAID,uEAAuE;AACvE,wBAAgB,yBAAyB,IAAI,4BAA4B,GAAG,IAAI,CAE/E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AA6BD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GACnD,IAAI,CAaN;AAID,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;KACtD,CAAC;IACF,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,SAAS,EACT,KAAK,EACL,QAAQ,GACT,EAAE,6BAA6B,2CAkE/B;AAED,mDAAmD;AACnD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;;;;OAcG;IACH,UAAU,CAAC,EAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,0BAA0B,CAAC,CAAC;IAC3E;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,SAAS,CAAC;IAC/D;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,kEAAkE;IAClE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAOD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,kDAI5D"}
@@ -2,169 +2,172 @@ import { useAssistantTr as e } from "../i18n.js";
2
2
  import { quotaExhaustedEventName as t } from "../quota.js";
3
3
  import { assistantPanelOwnsEscape as n } from "./panelOverlays.js";
4
4
  import { AssistantPreviewBridgeHost as r } from "../preview/bridgeHost.js";
5
- import { AIAssistantPanel as i } from "./AIAssistantPanel.js";
6
- import { ASSISTANT_DOCK_WIDTH_VAR as a, ASSISTANT_OVERLAY_DESKTOP_QUERY as o, ASSISTANT_OVERLAY_TOP_VAR as s, aboveAssistantBottomChrome as c, assistantOverlayClassName as l, assistantOverlayEscapeAction as u, assistantOverlayKeys as d, assistantQuotaKindOf as f, createAssistantNavigate as p, isAssistantToggleShortcut as m, nextAssistantOpenState as h, publishedAssistantDockWidth as g, readAssistantOverlayFlag as _, requestedAssistantOpenState as v, writeAssistantOverlayFlag as y } from "./assistantOverlayState.js";
7
- import { createContext as b, useCallback as x, useContext as S, useEffect as C, useMemo as w, useRef as T, useState as E, useSyncExternalStore as D } from "react";
8
- import { Sparkles as O } from "lucide-react";
9
- import { jsx as k, jsxs as A } from "react/jsx-runtime";
5
+ import { useAssistantServerHistory as i } from "../history/useAssistantServerHistory.js";
6
+ import { AIAssistantPanel as a } from "./AIAssistantPanel.js";
7
+ import { ASSISTANT_DOCK_WIDTH_VAR as o, ASSISTANT_OVERLAY_DESKTOP_QUERY as s, ASSISTANT_OVERLAY_TOP_VAR as c, aboveAssistantBottomChrome as l, assistantOverlayClassName as u, assistantOverlayEscapeAction as d, assistantOverlayKeys as f, assistantQuotaKindOf as p, createAssistantNavigate as m, isAssistantToggleShortcut as h, nextAssistantOpenState as g, publishedAssistantDockWidth as _, readAssistantOverlayFlag as v, requestedAssistantOpenState as y, writeAssistantOverlayFlag as b } from "./assistantOverlayState.js";
8
+ import { createContext as x, useCallback as S, useContext as C, useEffect as w, useMemo as T, useRef as E, useState as D, useSyncExternalStore as O } from "react";
9
+ import { Sparkles as k } from "lucide-react";
10
+ import { jsx as A, jsxs as j } from "react/jsx-runtime";
10
11
  //#region src/shared/assistant/ui/AssistantOverlay.tsx
11
- var j = b(null);
12
- function M() {
13
- return S(j);
14
- }
12
+ var M = x(null);
15
13
  function N() {
16
- return S(j)?.dockWidthPx ?? 0;
14
+ return C(M);
15
+ }
16
+ function P() {
17
+ return C(M)?.dockWidthPx ?? 0;
17
18
  }
18
- var P = () => typeof window > "u" ? void 0 : window.sessionStorage, F = () => typeof window > "u" ? void 0 : window.localStorage;
19
- function I(e) {
19
+ var F = () => typeof window > "u" ? void 0 : window.sessionStorage, I = () => typeof window > "u" ? void 0 : window.localStorage;
20
+ function L(e) {
20
21
  if (typeof window > "u" || typeof window.matchMedia != "function") return () => {};
21
- let t = window.matchMedia(o);
22
+ let t = window.matchMedia(s);
22
23
  return t.addEventListener("change", e), () => t.removeEventListener("change", e);
23
24
  }
24
- function L() {
25
+ function R() {
25
26
  return typeof window < "u" && typeof window.matchMedia == "function" && window.matchMedia("(min-width: 640px)").matches;
26
27
  }
27
- function R() {
28
- return D(I, L, () => !1);
28
+ function z() {
29
+ return O(L, R, () => !1);
29
30
  }
30
- function z(e, n) {
31
- let r = T(n);
32
- C(() => {
31
+ function B(e, n) {
32
+ let r = E(n);
33
+ w(() => {
33
34
  r.current = n;
34
- }, [n]), C(() => {
35
+ }, [n]), w(() => {
35
36
  if (!e || typeof window > "u") return;
36
- let n = t(e), i = (e) => r.current(f(e), e);
37
+ let n = t(e), i = (e) => r.current(p(e), e);
37
38
  return window.addEventListener(n, i), () => window.removeEventListener(n, i);
38
39
  }, [e]);
39
40
  }
40
- var B = () => {};
41
- function V({ keyPrefix: e, quota: t, children: n }) {
42
- let r = w(() => d(e), [e]), [i, o] = E(() => _(P, r.openStorageKey)), [s, c] = E(() => _(F, r.dockStorageKey)), l = x(() => o(!0), []), u = x(() => o(!1), []), f = x(() => o((e) => !e), []), p = x(() => c((e) => !e), []);
43
- C(() => {
44
- y(P, r.openStorageKey, i);
45
- }, [r.openStorageKey, i]), C(() => {
46
- y(F, r.dockStorageKey, s);
47
- }, [r.dockStorageKey, s]), C(() => {
41
+ var V = () => {};
42
+ function H({ keyPrefix: e, quota: t, children: n }) {
43
+ let r = T(() => f(e), [e]), [i, a] = D(() => v(F, r.openStorageKey)), [s, c] = D(() => v(I, r.dockStorageKey)), l = S(() => a(!0), []), u = S(() => a(!1), []), d = S(() => a((e) => !e), []), p = S(() => c((e) => !e), []);
44
+ w(() => {
45
+ b(F, r.openStorageKey, i);
46
+ }, [r.openStorageKey, i]), w(() => {
47
+ b(I, r.dockStorageKey, s);
48
+ }, [r.dockStorageKey, s]), w(() => {
48
49
  if (typeof window > "u") return;
49
50
  let e = (e) => {
50
- let t = v(e);
51
- o((e) => h(e, t));
51
+ let t = y(e);
52
+ a((e) => g(e, t));
52
53
  };
53
54
  return window.addEventListener(r.toggleEvent, e), () => window.removeEventListener(r.toggleEvent, e);
54
- }, [r.toggleEvent]), C(() => {
55
+ }, [r.toggleEvent]), w(() => {
55
56
  if (typeof document > "u") return;
56
57
  let e = (e) => {
57
- m(e) && (e.preventDefault(), o((e) => !e));
58
+ h(e) && (e.preventDefault(), a((e) => !e));
58
59
  };
59
60
  return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
60
- }, []), z(t?.product ?? null, t?.onExhausted ?? B);
61
- let b = g({
61
+ }, []), B(t?.product ?? null, t?.onExhausted ?? V);
62
+ let m = _({
62
63
  isOpen: i,
63
64
  docked: s,
64
- isDesktop: R()
65
+ isDesktop: z()
65
66
  });
66
- C(() => {
67
+ w(() => {
67
68
  if (typeof document > "u") return;
68
69
  let e = document.documentElement.style;
69
- return e.setProperty(a, `${b}px`), () => {
70
- e.removeProperty(a);
70
+ return e.setProperty(o, `${m}px`), () => {
71
+ e.removeProperty(o);
71
72
  };
72
- }, [b]);
73
- let S = w(() => ({
73
+ }, [m]);
74
+ let x = T(() => ({
74
75
  isOpen: i,
75
76
  open: l,
76
77
  close: u,
77
- toggle: f,
78
+ toggle: d,
78
79
  docked: s,
79
80
  toggleDock: p,
80
- dockWidthPx: b,
81
+ dockWidthPx: m,
81
82
  keys: r
82
83
  }), [
83
84
  i,
84
85
  l,
85
86
  u,
86
- f,
87
+ d,
87
88
  s,
88
89
  p,
89
- b,
90
+ m,
90
91
  r
91
92
  ]);
92
- return /* @__PURE__ */ k(j.Provider, {
93
- value: S,
93
+ return /* @__PURE__ */ A(M.Provider, {
94
+ value: x,
94
95
  children: n
95
96
  });
96
97
  }
97
- var H = (e, t) => /* @__PURE__ */ k(i, {
98
+ var U = (e, t) => /* @__PURE__ */ A(a, {
98
99
  ...e,
99
100
  ...t
100
101
  });
101
- function U(e) {
102
- let t = M();
103
- return t ? /* @__PURE__ */ k(W, {
102
+ function W(e) {
103
+ let t = N();
104
+ return t ? /* @__PURE__ */ A(G, {
104
105
  state: t,
105
106
  ...e
106
107
  }) : null;
107
108
  }
108
- function W({ state: t, panelId: i = "ai-assistant", panelProps: a, renderPanel: o, navigate: d, isShellLessTarget: f, topOffsetPx: m = 56, launcherIcon: h, launcherBottomInset: g = "1.5rem", showLauncher: _ = !0 }) {
109
- let { isOpen: v, close: y, toggle: b, docked: x, toggleDock: S } = t, T = e(), [D, j] = E(!1), M = w(() => d ? p({
110
- navigate: d,
111
- isShellLessTarget: f,
112
- isDesktop: L,
113
- collapseSheet: () => j(!1),
109
+ function G({ state: t, panelId: a = "ai-assistant", panelProps: o, renderPanel: s, navigate: f, isShellLessTarget: p, topOffsetPx: h = 56, launcherIcon: g, launcherBottomInset: _ = "1.5rem", showLauncher: v = !0 }) {
110
+ let { isOpen: y, close: b, toggle: x, docked: S, toggleDock: C } = t, E = e();
111
+ i(o?.serverHistory === !0);
112
+ let [O, M] = D(!1), N = T(() => f ? m({
113
+ navigate: f,
114
+ isShellLessTarget: p,
115
+ isDesktop: R,
116
+ collapseSheet: () => M(!1),
114
117
  openInNewTab: (e) => window.open(e, "_blank", "noopener,noreferrer")
115
- }) : void 0, [d, f]);
116
- C(() => {
117
- if (!v) return;
118
+ }) : void 0, [f, p]);
119
+ w(() => {
120
+ if (!y) return;
118
121
  let e = (e) => {
119
- u({
122
+ d({
120
123
  key: e.key,
121
- isOpen: v,
124
+ isOpen: y,
122
125
  dialogOpen: document.querySelector("[role=\"dialog\"],[role=\"alertdialog\"],dialog[open]") !== null,
123
126
  panelOwnsEscape: n()
124
- }) === "close" && (e.preventDefault(), y());
127
+ }) === "close" && (e.preventDefault(), b());
125
128
  };
126
129
  return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
127
- }, [v, y]);
128
- let N = {
129
- panelId: i,
130
+ }, [y, b]);
131
+ let P = {
132
+ panelId: a,
130
133
  visible: !0,
131
- onClose: y,
132
- docked: x,
133
- onToggleDock: S,
134
- onNavigate: M
135
- }, P = T("overlay.launcher", "AI Assistant"), F = { [s]: `${m}px` };
136
- return /* @__PURE__ */ A(r, {
137
- preview: a?.preview,
138
- children: [v && /* @__PURE__ */ A("div", {
139
- className: l({
140
- expanded: D,
141
- docked: x
134
+ onClose: b,
135
+ docked: S,
136
+ onToggleDock: C,
137
+ onNavigate: N
138
+ }, F = E("overlay.launcher", "AI Assistant"), I = { [c]: `${h}px` };
139
+ return /* @__PURE__ */ j(r, {
140
+ preview: o?.preview,
141
+ children: [y && /* @__PURE__ */ j("div", {
142
+ className: u({
143
+ expanded: O,
144
+ docked: S
142
145
  }),
143
- style: F,
146
+ style: I,
144
147
  "data-testid": "assistant-overlay",
145
- children: [/* @__PURE__ */ k("button", {
148
+ children: [/* @__PURE__ */ A("button", {
146
149
  type: "button",
147
- onClick: () => j((e) => !e),
150
+ onClick: () => M((e) => !e),
148
151
  className: "flex w-full shrink-0 justify-center pt-2 pb-1 sm:hidden",
149
- "aria-label": D ? T("sheet.collapse", "Shrink the assistant") : T("sheet.expand", "Expand the assistant"),
150
- "aria-expanded": D,
152
+ "aria-label": O ? E("sheet.collapse", "Shrink the assistant") : E("sheet.expand", "Expand the assistant"),
153
+ "aria-expanded": O,
151
154
  "data-testid": "assistant-sheet-handle",
152
- children: /* @__PURE__ */ k("span", { className: "h-1.5 w-10 rounded-full bg-border-strong" })
153
- }), /* @__PURE__ */ k("div", {
155
+ children: /* @__PURE__ */ A("span", { className: "h-1.5 w-10 rounded-full bg-border-strong" })
156
+ }), /* @__PURE__ */ A("div", {
154
157
  className: "flex min-h-0 flex-1 flex-col",
155
- children: o ? o(N) : H(a, N)
158
+ children: s ? s(P) : U(o, P)
156
159
  })]
157
- }), _ && /* @__PURE__ */ k("button", {
160
+ }), v && /* @__PURE__ */ A("button", {
158
161
  type: "button",
159
- onClick: b,
160
- title: T("overlay.launcherTitle", "AI Assistant ({{shortcut}})", { shortcut: "Ctrl+Shift+A" }),
161
- "aria-label": P,
162
+ onClick: x,
163
+ title: E("overlay.launcherTitle", "AI Assistant ({{shortcut}})", { shortcut: "Ctrl+Shift+A" }),
164
+ "aria-label": F,
162
165
  "aria-haspopup": "dialog",
163
- "aria-expanded": v,
166
+ "aria-expanded": y,
164
167
  "data-testid": "assistant-fab",
165
- style: { bottom: c(g) },
166
- className: "fixed right-6 z-30 size-14 items-center justify-center rounded-full border border-border-strong bg-[var(--color-accent-soft)] text-action-primary-bg shadow-float transition-colors duration-200 hover:border-action-primary-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] cursor-pointer " + (v ? "hidden sm:inline-flex" : "inline-flex"),
167
- children: h ?? /* @__PURE__ */ k(O, {
168
+ style: { bottom: l(_) },
169
+ className: "fixed right-6 z-30 size-14 items-center justify-center rounded-full border border-border-strong bg-[var(--color-accent-soft)] text-action-primary-bg shadow-float transition-colors duration-200 hover:border-action-primary-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] cursor-pointer " + (y ? "hidden sm:inline-flex" : "inline-flex"),
170
+ children: g ?? /* @__PURE__ */ A(k, {
168
171
  className: "size-6",
169
172
  "aria-hidden": "true"
170
173
  })
@@ -172,4 +175,4 @@ function W({ state: t, panelId: i = "ai-assistant", panelProps: a, renderPanel:
172
175
  });
173
176
  }
174
177
  //#endregion
175
- export { U as AssistantOverlay, V as AssistantOverlayProvider, N as useAssistantDockWidth, M as useAssistantOverlayOrNull, z as useAssistantQuotaExhausted };
178
+ export { W as AssistantOverlay, H as AssistantOverlayProvider, P as useAssistantDockWidth, N as useAssistantOverlayOrNull, B as useAssistantQuotaExhausted };
@@ -8,9 +8,11 @@ interface Props {
8
8
  * "You said things here that this thread is not showing you."
9
9
  *
10
10
  * ★ The assistant and the typed thread share ONE backend session, and the
11
- * client sends no history array — the model's memory IS that session. So a
12
- * spoken turn is in the model's context permanently, whether or not the chat
13
- * panel draws it. Hiding those turns without saying so produced the worst
11
+ * model's memory IS that session — the client replays no history into it. The
12
+ * one exception (BOFF-7335) is a NEW session in a conversation saved to server
13
+ * history, which is handed a framed digest of the saved exchanges, spoken ones
14
+ * included (`resumeContextFor`). Either way a spoken turn is in the model's
15
+ * context, whether or not the chat panel draws it. Hiding those turns without saying so produced the worst
14
16
  * possible combination: replies that open "as I mentioned about your urea dose"
15
17
  * with no such message anywhere on screen, and an Export button on a chat that
16
18
  * looks empty.
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantSpokenTurnsNotice.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantSpokenTurnsNotice.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,UAAU,KAAK;IACb,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,0BAA0B,EAAE,EAAE,CAAC,KAAK,CA0ChD,CAAC"}
1
+ {"version":3,"file":"AssistantSpokenTurnsNotice.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantSpokenTurnsNotice.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,UAAU,KAAK;IACb,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,0BAA0B,EAAE,EAAE,CAAC,KAAK,CA0ChD,CAAC"}
@@ -17,6 +17,12 @@ interface Props {
17
17
  onSend: (message: string, attachments: AssistantAttachment[]) => void;
18
18
  /** True while a turn is in-flight (assistant busy) — disables send + shows the spinner. */
19
19
  disabled?: boolean;
20
+ /**
21
+ * Nothing can be sent into this conversation at all (BOFF-7335: one saved
22
+ * before server history). Everything is disabled as by `disabled`, but it is
23
+ * not BUSY, so no spinner claims something is on its way.
24
+ */
25
+ readOnly?: boolean;
20
26
  placeholder?: string;
21
27
  mode: AssistantMode;
22
28
  /** Role-filtered list of modes the user may pick. */
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantComposer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/composer/AssistantComposer.tsx"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,EAAE,EAER,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQjD,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,UAAU,KAAK;IACb;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAC;IACtE,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,qDAAqD;IACrD,cAAc,EAAE,mBAAmB,EAAE,CAAC;IACtC;;;;;;;;;;OAUG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,qFAAqF;IACrF,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,KAAK,CA6avC,CAAC"}
1
+ {"version":3,"file":"AssistantComposer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/composer/AssistantComposer.tsx"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,EAAE,EAER,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAQjD,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,UAAU,KAAK;IACb;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,EAAE,KAAK,IAAI,CAAC;IACtE,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC;IACpB,qDAAqD;IACrD,cAAc,EAAE,mBAAmB,EAAE,CAAC;IACtC;;;;;;;;;;OAUG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,qFAAqF;IACrF,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAID;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,KAAK,CA+avC,CAAC"}
@@ -15,44 +15,44 @@ import { useCallback as l, useEffect as ie, useLayoutEffect as u, useMemo as d,
15
15
  import { ArrowUp as m, Loader2 as h } from "lucide-react";
16
16
  import { jsx as g, jsxs as _ } from "react/jsx-runtime";
17
17
  //#region src/shared/assistant/ui/composer/AssistantComposer.tsx
18
- var v = 200, y = ({ writeAccessDenied: y = !1, onSend: b, disabled: x = !1, placeholder: ae, mode: oe, availableModes: S, attachmentCharsPerFile: se, onModeChange: ce, auto: le, onStartVoiceSession: C, onDraftStart: w }) => {
19
- let T = ee(), { locale: E } = e(), D = f(null), [O, k] = p(""), [A, j] = p(!1), M = f(0), { attachments: N, isBusy: P, preparingCount: F, sendBlocker: I, rejection: L, addFiles: R, remove: z, retry: B, clear: V, clearRejection: H, canAddMore: ue } = re({ perFileChars: se }), U = O.trim() !== "" || N.length > 0, W = f(!1);
18
+ var v = 200, y = ({ writeAccessDenied: y = !1, onSend: b, disabled: x = !1, readOnly: ae = !1, placeholder: oe, mode: se, availableModes: S, attachmentCharsPerFile: ce, onModeChange: le, auto: ue, onStartVoiceSession: C, onDraftStart: w }) => {
19
+ let T = ee(), { locale: E } = e(), D = x || ae, O = f(null), [k, A] = p(""), [j, M] = p(!1), N = f(0), { attachments: P, isBusy: F, preparingCount: I, sendBlocker: L, rejection: R, addFiles: z, remove: B, retry: V, clear: H, clearRejection: de, canAddMore: fe } = re({ perFileChars: ce }), U = k.trim() !== "" || P.length > 0, W = f(!1);
20
20
  ie(() => {
21
21
  U && !W.current ? (W.current = !0, w?.()) : U || (W.current = !1);
22
22
  }, [U, w]);
23
- let de = l((e) => {
24
- k((t) => t ? `${t.replace(/\s+$/, "")} ${e}` : e);
23
+ let pe = l((e) => {
24
+ A((t) => t ? `${t.replace(/\s+$/, "")} ${e}` : e);
25
25
  }, []), G = a((e) => e.assistantLanguage), K = t({
26
- onFinalize: de,
26
+ onFinalize: pe,
27
27
  language: d(() => r(G, E), [G, E]).tag
28
- }), fe = ae ?? T("composer.placeholder", "Ask me anything…"), q = O.trim(), J = i(N), Y = N.filter((e) => e.status === "error"), X = (q.length > 0 || J.length > 0) && !x && I === null;
28
+ }), me = oe ?? T("composer.placeholder", "Ask me anything…"), q = k.trim(), J = i(P), Y = P.filter((e) => e.status === "error"), X = (q.length > 0 || J.length > 0) && !D && L === null;
29
29
  u(() => {
30
- let e = D.current;
30
+ let e = O.current;
31
31
  e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, v)}px`);
32
- }, [O]);
32
+ }, [k]);
33
33
  let Z = l(() => {
34
- X && (K.isActive && K.stop(), b(O.trim(), J), k(""), V());
34
+ X && (K.isActive && K.stop(), b(k.trim(), J), A(""), H());
35
35
  }, [
36
36
  X,
37
37
  b,
38
- O,
38
+ k,
39
39
  J,
40
- V,
40
+ H,
41
41
  K
42
- ]), pe = l((e) => {
42
+ ]), he = l((e) => {
43
43
  e.key === "Enter" && !e.shiftKey && (e.preventDefault(), Z());
44
- }, [Z]), me = l((e) => {
44
+ }, [Z]), ge = l((e) => {
45
45
  let t = Array.from(e.clipboardData?.files ?? []);
46
- t.length !== 0 && (e.preventDefault(), R(t));
47
- }, [R]), he = l((e) => {
48
- Array.from(e.dataTransfer?.types ?? []).includes("Files") && (M.current += 1, j(!0));
49
- }, []), ge = l(() => {
50
- M.current = Math.max(0, M.current - 1), M.current === 0 && j(!1);
51
- }, []), _e = l((e) => {
46
+ t.length !== 0 && (e.preventDefault(), z(t));
47
+ }, [z]), _e = l((e) => {
48
+ Array.from(e.dataTransfer?.types ?? []).includes("Files") && (N.current += 1, M(!0));
49
+ }, []), Q = l(() => {
50
+ N.current = Math.max(0, N.current - 1), N.current === 0 && M(!1);
51
+ }, []), ve = l((e) => {
52
52
  Array.from(e.dataTransfer?.types ?? []).includes("Files") && e.preventDefault();
53
- }, []), Q = l((e) => {
54
- e.preventDefault(), M.current = 0, j(!1), R(e.dataTransfer?.files ?? null);
55
- }, [R]), ve = (e) => {
53
+ }, []), ye = l((e) => {
54
+ e.preventDefault(), N.current = 0, M(!1), z(e.dataTransfer?.files ?? null);
55
+ }, [z]), be = (e) => {
56
56
  switch (e) {
57
57
  case "too-many": return T("attachments.tooMany", "You can attach up to {{max}} files per message.", { max: 5 });
58
58
  case "too-large": return T("attachments.tooLarge", "That file is larger than 10 MB.");
@@ -74,36 +74,36 @@ var v = 200, y = ({ writeAccessDenied: y = !1, onSend: b, disabled: x = !1, plac
74
74
  className: "flex-shrink-0 px-3 pb-3 pt-1.5",
75
75
  children: [
76
76
  /* @__PURE__ */ _("div", {
77
- onDragEnter: he,
78
- onDragLeave: ge,
79
- onDragOver: _e,
80
- onDrop: Q,
81
- className: `rounded-2xl border p-2 shadow-sm transition-colors focus-within:border-action-primary-bg focus-within:ring-2 focus-within:ring-action-primary-bg/15 ${A ? "border-action-primary-bg border-dashed bg-action-primary-bg/5" : "border-border-default bg-bg-sunken"}`,
77
+ onDragEnter: _e,
78
+ onDragLeave: Q,
79
+ onDragOver: ve,
80
+ onDrop: ye,
81
+ className: `rounded-2xl border p-2 shadow-sm transition-colors focus-within:border-action-primary-bg focus-within:ring-2 focus-within:ring-action-primary-bg/15 ${j ? "border-action-primary-bg border-dashed bg-action-primary-bg/5" : "border-border-default bg-bg-sunken"}`,
82
82
  "data-testid": "assistant-composer",
83
83
  children: [
84
84
  /* @__PURE__ */ g(s, {
85
- attachments: N,
86
- onRemove: z,
87
- onRetry: B,
88
- disabled: x,
89
- preparingCount: F
85
+ attachments: P,
86
+ onRemove: B,
87
+ onRetry: V,
88
+ disabled: D,
89
+ preparingCount: I
90
90
  }),
91
91
  /* @__PURE__ */ _("div", {
92
92
  className: "flex items-end gap-2",
93
93
  children: [
94
94
  /* @__PURE__ */ g(o, {
95
- onFiles: R,
96
- canAddMore: ue,
97
- disabled: x
95
+ onFiles: z,
96
+ canAddMore: fe,
97
+ disabled: D
98
98
  }),
99
99
  /* @__PURE__ */ g("textarea", {
100
- ref: D,
101
- value: O,
102
- onChange: (e) => k(e.target.value),
103
- onKeyDown: pe,
104
- onPaste: me,
105
- disabled: x,
106
- placeholder: A ? T("composer.dropHere", "Drop files to attach") : fe,
100
+ ref: O,
101
+ value: k,
102
+ onChange: (e) => A(e.target.value),
103
+ onKeyDown: he,
104
+ onPaste: ge,
105
+ disabled: D,
106
+ placeholder: j ? T("composer.dropHere", "Drop files to attach") : me,
107
107
  rows: 1,
108
108
  className: "min-h-[36px] flex-1 resize-none self-center bg-transparent px-1 py-2 text-[15px] leading-relaxed text-text-primary placeholder:text-text-muted focus:outline-none disabled:opacity-50",
109
109
  "aria-label": T("chatInput.ariaLabel", "Message input"),
@@ -113,11 +113,11 @@ var v = 200, y = ({ writeAccessDenied: y = !1, onSend: b, disabled: x = !1, plac
113
113
  isListening: K.isListening,
114
114
  isStarting: K.isStarting,
115
115
  onToggle: K.toggle,
116
- disabled: x
116
+ disabled: D
117
117
  }),
118
- C && q.length === 0 && N.length === 0 && !K.isActive ? /* @__PURE__ */ g(ne, {
118
+ C && q.length === 0 && P.length === 0 && !K.isActive ? /* @__PURE__ */ g(ne, {
119
119
  onStart: C,
120
- disabled: x
120
+ disabled: D
121
121
  }) : /* @__PURE__ */ g("button", {
122
122
  type: "button",
123
123
  onClick: Z,
@@ -125,18 +125,18 @@ var v = 200, y = ({ writeAccessDenied: y = !1, onSend: b, disabled: x = !1, plac
125
125
  className: `flex size-9 flex-shrink-0 items-center justify-center rounded-full shadow-sm transition-all focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${X ? "bg-action-primary-bg text-action-primary-text hover:scale-105 hover:bg-action-primary-bg-hover" : "bg-bg-elevated text-text-muted"}`,
126
126
  "aria-label": T("chatInput.send", "Send message"),
127
127
  "data-testid": "assistant-send",
128
- children: x || P ? /* @__PURE__ */ g(h, { className: "size-4 motion-safe:animate-spin" }) : /* @__PURE__ */ g(m, { className: "size-4" })
128
+ children: x || F ? /* @__PURE__ */ g(h, { className: "size-4 motion-safe:animate-spin" }) : /* @__PURE__ */ g(m, { className: "size-4" })
129
129
  })
130
130
  ]
131
131
  }),
132
132
  S.length > 1 && /* @__PURE__ */ g("div", {
133
133
  className: "mt-2 px-0.5",
134
134
  children: /* @__PURE__ */ g(c, {
135
- mode: oe,
135
+ mode: se,
136
136
  availableModes: S,
137
- onModeChange: ce,
138
- disabled: x,
139
- auto: le
137
+ onModeChange: le,
138
+ disabled: D,
139
+ auto: ue
140
140
  })
141
141
  })
142
142
  ]
@@ -161,13 +161,13 @@ var v = 200, y = ({ writeAccessDenied: y = !1, onSend: b, disabled: x = !1, plac
161
161
  className: "text-status-error-text",
162
162
  "data-testid": "assistant-voice-error",
163
163
  children: $
164
- }) : L ? /* @__PURE__ */ g("button", {
164
+ }) : R ? /* @__PURE__ */ g("button", {
165
165
  type: "button",
166
- onClick: H,
166
+ onClick: de,
167
167
  className: "text-status-error-text underline-offset-2 hover:underline",
168
168
  "data-testid": "assistant-attachment-rejection",
169
- children: ve(L)
170
- }) : I === "failed" ? /* @__PURE__ */ g("p", {
169
+ children: be(R)
170
+ }) : L === "failed" ? /* @__PURE__ */ g("p", {
171
171
  className: "text-status-error-text",
172
172
  "data-testid": "assistant-attachment-blocked",
173
173
  children: Y.length === 1 ? T("attachments.blockedOne", "{{name}} didn't upload. Retry or remove it before sending.", { name: Y[0].filename }) : T("attachments.blockedMany", "{{count}} attachments didn't upload. Retry or remove them before sending.", { count: Y.length })