@burdenoff/fe-libs 2026.1007.6 → 2026.1008.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 (39) hide show
  1. package/dist/shared/assistant/attachmentCommit.d.ts +175 -0
  2. package/dist/shared/assistant/attachmentCommit.d.ts.map +1 -0
  3. package/dist/shared/assistant/attachmentCommit.js +638 -0
  4. package/dist/shared/assistant/attachments.d.ts +39 -19
  5. package/dist/shared/assistant/attachments.d.ts.map +1 -1
  6. package/dist/shared/assistant/history/historyEngine.js +280 -280
  7. package/dist/shared/assistant/i18nManifest.d.ts +14 -2
  8. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  9. package/dist/shared/assistant/i18nManifest.js +17 -3
  10. package/dist/shared/assistant/index.d.ts +3 -0
  11. package/dist/shared/assistant/index.d.ts.map +1 -1
  12. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  13. package/dist/shared/assistant/ui/AssistantChatArea.js +1390 -1371
  14. package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.d.ts +8 -5
  15. package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.d.ts.map +1 -1
  16. package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.js +26 -9
  17. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +3 -2
  18. package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts.map +1 -1
  19. package/dist/shared/assistant/ui/composer/AssistantComposer.js +214 -125
  20. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +10 -0
  21. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
  22. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +124 -116
  23. package/dist/shared/assistant/useAssistantAttachments.d.ts +20 -2
  24. package/dist/shared/assistant/useAssistantAttachments.d.ts.map +1 -1
  25. package/dist/shared/assistant/useAssistantAttachments.js +146 -202
  26. package/dist/shared/assistant/useAttachmentCommitter.d.ts +17 -0
  27. package/dist/shared/assistant/useAttachmentCommitter.d.ts.map +1 -0
  28. package/dist/shared/assistant/useAttachmentCommitter.js +41 -0
  29. package/dist/shared/assistant/voiceCommit.d.ts +36 -0
  30. package/dist/shared/assistant/voiceCommit.d.ts.map +1 -0
  31. package/dist/shared/assistant/voiceCommit.js +24 -0
  32. package/dist/shared-assistant.js +161 -158
  33. package/dist/storage/filesPort.d.ts +120 -0
  34. package/dist/storage/filesPort.d.ts.map +1 -0
  35. package/dist/storage/filesPort.js +269 -0
  36. package/dist/storage/index.d.ts +2 -0
  37. package/dist/storage/index.d.ts.map +1 -1
  38. package/dist/storage/index.js +9 -8
  39. package/package.json +1 -1
@@ -3,7 +3,7 @@ import { AssistantAttachment } from '../../attachments';
3
3
  interface Props {
4
4
  attachments: AssistantAttachment[];
5
5
  onRemove: (id: string) => void;
6
- /** Re-upload a failed attachment from the bytes already prepared. */
6
+ /** Clear a failed attachment's error so the next Send saves it again from the bytes already held. */
7
7
  onRetry: (id: string) => void;
8
8
  disabled?: boolean;
9
9
  /**
@@ -19,10 +19,13 @@ interface Props {
19
19
  /**
20
20
  * Pending-attachment strip above the composer input (Workstream 3).
21
21
  *
22
- * Images get a thumbnail, everything else a typed icon chip. Upload state is
23
- * shown on the chip itself — a spinner while it is in flight, a red outline plus
24
- * the reason when it fails — so a farmer on a weak connection can see which
25
- * photo is still going up instead of guessing why send is disabled.
22
+ * Images get a thumbnail, everything else a typed icon chip. Nothing is saved to
23
+ * Files until Send, so a chip is just "ready" until then. While Send saves it the
24
+ * chip shows a progress bar and a percentage (and cannot be removed — the save is
25
+ * using it); when a Send could not save it, a red outline plus the reason
26
+ * (`saveError`), and the person can press Send again or remove it. A file that is
27
+ * deliberately not saved (over the 5 MB direct-upload limit, text still sent) says
28
+ * so on its chip.
26
29
  */
27
30
  export declare const AssistantAttachmentChips: FC<Props>;
28
31
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantAttachmentChips.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/composer/AssistantAttachmentChips.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAUhC,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,UAAU,KAAK;IACb,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,qEAAqE;IACrE,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,EAAE,EAAE,CAAC,KAAK,CA2H9C,CAAC"}
1
+ {"version":3,"file":"AssistantAttachmentChips.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/composer/AssistantAttachmentChips.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAUhC,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE1E,UAAU,KAAK;IACb,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,qGAAqG;IACrG,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,EAAE,EAAE,CAAC,KAAK,CA+J9C,CAAC"}
@@ -10,7 +10,7 @@ var u = ({ attachments: u, onRemove: d, onRetry: f, preparingCount: p = 0, disab
10
10
  "aria-label": h("attachments.listLabel", "Attached files"),
11
11
  "data-testid": "assistant-attachment-chips",
12
12
  children: [u.map((e) => {
13
- let u = e.status === "pending" || e.status === "uploading", p = e.status === "error";
13
+ let u = e.status === "pending" || e.status === "uploading", p = e.status === "error" || !!e.saveError, g = e.status === "uploading", _ = Math.max(0, Math.min(100, Math.round(e.progress ?? 0))), v = p ? e.saveError ?? e.error ?? h("attachments.failed", "Upload failed") : g ? e.progressNote ?? h("attachments.savingProgress", "Saving {{percent}}%", { percent: _ }) : u ? h("attachments.uploading", "Uploading…") : e.inlineOnly ? h("attachments.inlineOnly", "Not saved to Files (over 5 MB). Its text is still included.") : t(e.size);
14
14
  return /* @__PURE__ */ l("li", {
15
15
  className: `flex max-w-[220px] items-center gap-1.5 rounded-lg border py-1 pl-1 pr-1.5 ${p ? "border-status-error-text/40 bg-status-error-bg/10" : "border-border-subtle bg-bg-surface"}`,
16
16
  "data-testid": "assistant-attachment-chip",
@@ -25,15 +25,32 @@ var u = ({ attachments: u, onRemove: d, onRetry: f, preparingCount: p = 0, disab
25
25
  }),
26
26
  /* @__PURE__ */ l("span", {
27
27
  className: "min-w-0 flex-1",
28
- children: [/* @__PURE__ */ c("span", {
29
- className: "block truncate text-[11px] font-medium leading-tight text-text-primary",
30
- children: e.filename
31
- }), /* @__PURE__ */ c("span", {
32
- className: "block truncate text-[10px] leading-tight text-text-muted",
33
- children: p ? e.error ?? h("attachments.failed", "Upload failed") : u ? e.progressNote ?? h("attachments.uploading", "Uploading…") : t(e.size)
34
- })]
28
+ children: [
29
+ /* @__PURE__ */ c("span", {
30
+ className: "block truncate text-[11px] font-medium leading-tight text-text-primary",
31
+ children: e.filename
32
+ }),
33
+ /* @__PURE__ */ c("span", {
34
+ className: `block truncate text-[10px] leading-tight ${p ? "text-status-error-text" : "text-text-muted"}`,
35
+ title: v,
36
+ children: v
37
+ }),
38
+ g ? /* @__PURE__ */ c("span", {
39
+ role: "progressbar",
40
+ "aria-label": h("attachments.saving", "Saving your attachments…"),
41
+ "aria-valuemin": 0,
42
+ "aria-valuemax": 100,
43
+ "aria-valuenow": _,
44
+ className: "mt-0.5 block h-1 overflow-hidden rounded-full bg-bg-sunken",
45
+ "data-testid": "assistant-attachment-progress",
46
+ children: /* @__PURE__ */ c("span", {
47
+ className: "block h-full rounded-full bg-action-primary-bg transition-[width]",
48
+ style: { width: `${_}%` }
49
+ })
50
+ }) : null
51
+ ]
35
52
  }),
36
- p && /* @__PURE__ */ c("button", {
53
+ e.status === "error" && /* @__PURE__ */ c("button", {
37
54
  type: "button",
38
55
  onClick: () => f(e.id),
39
56
  disabled: m,
@@ -11,8 +11,9 @@ interface Props {
11
11
  */
12
12
  writeAccessDenied?: boolean;
13
13
  /**
14
- * Send the message. `attachments` are already uploaded and ready; the chat
15
- * area folds them into the prompt and onto the user bubble.
14
+ * Send the message. `attachments` are already SAVED to Files and ready (the
15
+ * composer saves them first, at Send, and sends nothing if that fails); the
16
+ * chat area folds them into the prompt and onto the user bubble.
16
17
  */
17
18
  onSend: (message: string, attachments: AssistantAttachment[]) => void;
18
19
  /** True while a turn is in-flight (assistant busy) — disables send + shows the spinner. */
@@ -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;;;;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,CAgbvC,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;AAGf,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;AAS3B,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,UAAU,KAAK;IACb;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;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;AAYD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,KAAK,CA6mBvC,CAAC"}
@@ -1,184 +1,273 @@
1
1
  import { useI18n as e } from "../../../providers/shell/I18nProvider.js";
2
- import { useVoiceInput as t } from "../../voice/useVoiceInput.js";
3
- import { useAssistantTr as n } from "../../i18n.js";
4
- import { useAssistantStore as ee } from "../../store.js";
5
- import { languageDisplayName as te } from "../../voice/speechVoices.js";
6
- import { resolveAssistantLanguage as r } from "../../voice/languages.js";
7
- import { getSendableAttachments as ne } from "../../attachments.js";
8
- import { AssistantAttachmentButton as re } from "./AssistantAttachmentButton.js";
9
- import { AssistantAttachmentChips as i } from "./AssistantAttachmentChips.js";
10
- import { AssistantModeSelector as a } from "./AssistantModeSelector.js";
11
- import { AssistantVoiceButton as o, ListeningDot as s } from "./AssistantVoiceButton.js";
12
- import { AssistantVoiceSessionButton as c } from "../voice/AssistantVoiceSessionButton.js";
13
- import { useAssistantAttachments as l } from "../../useAssistantAttachments.js";
14
- import { useCallback as u, useEffect as d, useLayoutEffect as ie, useMemo as ae, useRef as f, useState as p } from "react";
15
- import { ArrowUp as oe, Loader2 as se } from "lucide-react";
16
- import { jsx as m, jsxs as h } from "react/jsx-runtime";
2
+ import { EscapeLayer as t } from "../../../components/EscapeLayer.js";
3
+ import { useVoiceInput as n } from "../../voice/useVoiceInput.js";
4
+ import { useAssistantTr as r } from "../../i18n.js";
5
+ import { useAssistantStore as i } from "../../store.js";
6
+ import { languageDisplayName as ee } from "../../voice/speechVoices.js";
7
+ import { resolveAssistantLanguage as te } from "../../voice/languages.js";
8
+ import { getSendableAttachments as a } from "../../attachments.js";
9
+ import { ATTACHMENT_COMMIT_CODES as o } from "../../attachmentCommit.js";
10
+ import { AssistantAttachmentButton as ne } from "./AssistantAttachmentButton.js";
11
+ import { AssistantAttachmentChips as re } from "./AssistantAttachmentChips.js";
12
+ import { AssistantModeSelector as ie } from "./AssistantModeSelector.js";
13
+ import { AssistantVoiceButton as ae, ListeningDot as oe } from "./AssistantVoiceButton.js";
14
+ import { AssistantVoiceSessionButton as se } from "../voice/AssistantVoiceSessionButton.js";
15
+ import { useAssistantAttachments as ce } from "../../useAssistantAttachments.js";
16
+ import { useCallback as s, useEffect as c, useLayoutEffect as le, useMemo as ue, useRef as l, useState as u } from "react";
17
+ import { ArrowUp as de, Loader2 as d } from "lucide-react";
18
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
17
19
  //#region src/shared/assistant/ui/composer/AssistantComposer.tsx
18
- var g = 200, _ = ({ writeAccessDenied: _ = !1, onSend: v, disabled: y = !1, readOnly: b = !1, placeholder: ce, mode: le, availableModes: x, attachmentCharsPerFile: S, onModeChange: C, auto: ue, onStartVoiceSession: w, onDraftStart: T }) => {
19
- let E = n(), { locale: D } = e(), O = y || b, k = f(null), [A, j] = p(""), [M, N] = p(!1), P = f(0), { attachments: F, isBusy: I, preparingCount: L, sendBlocker: R, rejection: z, addFiles: B, remove: V, retry: H, clear: U, clearRejection: de, canAddMore: fe } = l({ perFileChars: S }), W = A.trim() !== "" || F.length > 0, G = f(!1);
20
- d(() => {
21
- W && !G.current ? (G.current = !0, T?.()) : W || (G.current = !1);
22
- }, [W, T]);
23
- let pe = u((e) => {
24
- j((t) => t ? `${t.replace(/\s+$/, "")} ${e}` : e);
25
- }, []), K = ee((e) => e.assistantLanguage), q = t({
26
- onFinalize: pe,
27
- language: ae(() => r(K, D), [K, D]).tag
28
- }), me = ce ?? E("composer.placeholder", "Ask me anything…"), J = A.trim(), Y = ne(F), X = F.filter((e) => e.status === "error"), Z = (J.length > 0 || Y.length > 0) && !O && R === null;
29
- ie(() => {
30
- let e = k.current;
31
- e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, g)}px`);
32
- }, [A]);
33
- let Q = u(() => {
34
- Z && (q.isActive && q.stop(), v(A.trim(), Y), j(""), U());
20
+ var fe = 200, m = ({ writeAccessDenied: m = !1, onSend: h, disabled: g = !1, readOnly: pe = !1, placeholder: me, mode: he, availableModes: _, attachmentCharsPerFile: ge, onModeChange: _e, auto: ve, onStartVoiceSession: v, onDraftStart: y }) => {
21
+ let b = r(), { locale: x } = e(), S = g || pe, C = l(null), [w, T] = u(""), [E, D] = u(!1), [O, k] = u(!1), A = l(!1), [j, M] = u(null), N = l(0), { attachments: P, isBusy: ye, preparingCount: be, sendBlocker: F, rejection: I, addFiles: L, remove: xe, retry: Se, clear: R, clearRejection: Ce, canAddMore: we, commit: z, cancelCommit: B } = ce({ perFileChars: ge }), V = w.trim() !== "" || P.length > 0, H = l(!1);
22
+ c(() => {
23
+ V && !H.current ? (H.current = !0, y?.()) : V || (H.current = !1);
24
+ }, [V, y]);
25
+ let Te = s((e) => {
26
+ T((t) => t ? `${t.replace(/\s+$/, "")} ${e}` : e);
27
+ }, []), U = i((e) => e.assistantLanguage), W = n({
28
+ onFinalize: Te,
29
+ language: ue(() => te(U, x), [U, x]).tag
30
+ }), Ee = me ?? b("composer.placeholder", "Ask me anything…"), G = w.trim(), K = a(P), q = P.filter((e) => e.status === "error"), J = (G.length > 0 || K.length > 0) && !S && !O && F === null, Y = K.some((e) => !e.fileId && !e.inlineOnly), X = l(S);
31
+ X.current = S;
32
+ let Z = l(!0);
33
+ c(() => (Z.current = !0, () => {
34
+ Z.current = !1;
35
+ }), []), le(() => {
36
+ let e = C.current;
37
+ e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, fe)}px`);
38
+ }, [w]);
39
+ let Q = s(async () => {
40
+ if (!J || A.current) return;
41
+ W.isActive && W.stop();
42
+ let e = w.trim();
43
+ if (M(null), !Y) {
44
+ h(e, K), T(""), R();
45
+ return;
46
+ }
47
+ let t = i.getState().activeConversationId;
48
+ A.current = !0, k(!0);
49
+ try {
50
+ let n = await z();
51
+ if (!Z.current) {
52
+ n.ok && await n.rollback();
53
+ return;
54
+ }
55
+ if (!n.ok) {
56
+ n.cancelled || M({
57
+ kind: "failed",
58
+ failures: n.failures
59
+ });
60
+ return;
61
+ }
62
+ if (X.current) {
63
+ await n.rollback(), Z.current && M({
64
+ kind: "busy",
65
+ failures: []
66
+ });
67
+ return;
68
+ }
69
+ let r = i.getState();
70
+ if (!(r.activeConversationId === t && (t === null || r.conversations.some((e) => e.id === t)))) {
71
+ await n.rollback(), Z.current && M({
72
+ kind: "moved",
73
+ failures: []
74
+ });
75
+ return;
76
+ }
77
+ h(e, a(n.attachments)), n.handedOver(), T(""), R();
78
+ } finally {
79
+ A.current = !1, Z.current && k(!1);
80
+ }
35
81
  }, [
36
- Z,
37
- v,
38
- A,
82
+ J,
39
83
  Y,
40
- U,
41
- q
42
- ]), he = u((e) => {
84
+ z,
85
+ h,
86
+ w,
87
+ K,
88
+ R,
89
+ W
90
+ ]), $ = s(() => {
91
+ B(), C.current?.focus();
92
+ }, [B]);
93
+ c(() => {
94
+ M(null);
95
+ }, [P.length]);
96
+ let De = (e) => {
97
+ if (e.kind === "busy") return b("attachments.saveBusy", "The assistant started another reply, so nothing was sent. Your message and files are still here.");
98
+ if (e.kind === "moved") return b("attachments.saveMoved", "You switched conversations while the files were being saved, so nothing was sent. Your message and files are still here.");
99
+ let { failures: t } = e;
100
+ if (t.some((e) => e.code === o.quotaExceeded || e.code === o.quotaNotProvisioned)) return `${b("attachments.quotaFull", "File storage is full or not set up for this workspace, so the attachments couldn't be saved. Nothing was sent.")} ${b("attachments.retrySend", "Press Send to try again, or remove the file.")}`;
101
+ let n = t[0], r = P.find((e) => e.id === n?.id)?.filename ?? "";
102
+ return `${t.length <= 1 ? b("attachments.saveFailedOne", "{{name}} couldn't be saved, so nothing was sent.", { name: r }) : b("attachments.saveFailedMany", "{{count}} attachments couldn't be saved, so nothing was sent.", { count: t.length })} ${b("attachments.retrySend", "Press Send to try again, or remove the file.")}`;
103
+ }, Oe = s((e) => {
43
104
  e.key === "Enter" && !e.shiftKey && (e.preventDefault(), Q());
44
- }, [Q]), ge = u((e) => {
105
+ }, [Q]), ke = s((e) => {
45
106
  let t = Array.from(e.clipboardData?.files ?? []);
46
- t.length !== 0 && (e.preventDefault(), B(t));
47
- }, [B]), _e = u((e) => {
48
- Array.from(e.dataTransfer?.types ?? []).includes("Files") && (P.current += 1, N(!0));
49
- }, []), ve = u(() => {
50
- P.current = Math.max(0, P.current - 1), P.current === 0 && N(!1);
51
- }, []), ye = u((e) => {
107
+ t.length !== 0 && (e.preventDefault(), L(t));
108
+ }, [L]), Ae = s((e) => {
109
+ Array.from(e.dataTransfer?.types ?? []).includes("Files") && (N.current += 1, D(!0));
110
+ }, []), je = s(() => {
111
+ N.current = Math.max(0, N.current - 1), N.current === 0 && D(!1);
112
+ }, []), Me = s((e) => {
52
113
  Array.from(e.dataTransfer?.types ?? []).includes("Files") && e.preventDefault();
53
- }, []), be = u((e) => {
54
- e.preventDefault(), P.current = 0, N(!1), B(e.dataTransfer?.files ?? null);
55
- }, [B]), xe = (e) => {
114
+ }, []), Ne = s((e) => {
115
+ e.preventDefault(), N.current = 0, D(!1), L(e.dataTransfer?.files ?? null);
116
+ }, [L]), Pe = (e) => {
56
117
  switch (e) {
57
- case "too-many": return E("attachments.tooMany", "You can attach up to {{max}} files per message.", { max: 5 });
58
- case "too-large": return E("attachments.tooLarge", "That file is larger than 10 MB.");
59
- case "empty": return E("attachments.empty", "That file is empty.");
60
- case "unreadable": return E("attachments.unreadable", "That file could not be read.");
61
- case "unsupported-image": return E("attachments.unsupportedImage", "This device can't read that image format, so it can't be resized to send. Save it as JPEG and try again.");
118
+ case "too-many": return b("attachments.tooMany", "You can attach up to {{max}} files per message.", { max: 5 });
119
+ case "too-large": return b("attachments.tooLarge", "That file is larger than 10 MB.");
120
+ case "empty": return b("attachments.empty", "That file is empty.");
121
+ case "unreadable": return b("attachments.unreadable", "That file could not be read.");
122
+ case "unsupported-image": return b("attachments.unsupportedImage", "This device can't read that image format, so it can't be resized to send. Save it as JPEG and try again.");
123
+ case "too-large-to-save": return b("attachments.tooLargeToSave", "That file is over 5 MB, so it can't be saved to Files, and no text could be read from it.");
62
124
  }
63
- }, $ = (() => {
64
- switch (q.error) {
65
- case "not-allowed": return E("voice.denied", "Microphone access is blocked. Allow it in your browser settings to dictate.");
66
- case "audio-capture": return E("voice.noMic", "No microphone was found.");
67
- case "network": return E("voice.network", "Speech recognition is offline right now.");
68
- case "language-not-supported": return E("voice.languageNotSupported", "This browser cannot recognise spoken {{language}}. Try a different browser, or type instead.", { language: te(q.language, D) });
69
- case "unknown": return E("voice.failed", "Dictation stopped unexpectedly.");
125
+ }, Fe = (() => {
126
+ switch (W.error) {
127
+ case "not-allowed": return b("voice.denied", "Microphone access is blocked. Allow it in your browser settings to dictate.");
128
+ case "audio-capture": return b("voice.noMic", "No microphone was found.");
129
+ case "network": return b("voice.network", "Speech recognition is offline right now.");
130
+ case "language-not-supported": return b("voice.languageNotSupported", "This browser cannot recognise spoken {{language}}. Try a different browser, or type instead.", { language: ee(W.language, x) });
131
+ case "unknown": return b("voice.failed", "Dictation stopped unexpectedly.");
70
132
  default: return null;
71
133
  }
72
134
  })();
73
- return /* @__PURE__ */ h("div", {
135
+ return /* @__PURE__ */ p("div", {
74
136
  className: "flex-shrink-0 px-3 pb-3 pt-1.5",
75
137
  children: [
76
- /* @__PURE__ */ h("div", {
77
- onDragEnter: _e,
78
- onDragLeave: ve,
79
- onDragOver: ye,
80
- onDrop: be,
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 ${M ? "border-action-primary-bg border-dashed bg-action-primary-bg/5" : "border-border-default bg-bg-sunken"}`,
138
+ /* @__PURE__ */ p("div", {
139
+ onDragEnter: Ae,
140
+ onDragLeave: je,
141
+ onDragOver: Me,
142
+ onDrop: Ne,
143
+ 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 ${E ? "border-action-primary-bg border-dashed bg-action-primary-bg/5" : "border-border-default bg-bg-sunken"}`,
82
144
  "data-testid": "assistant-composer",
83
145
  children: [
84
- /* @__PURE__ */ m(i, {
85
- attachments: F,
86
- onRemove: V,
87
- onRetry: H,
88
- disabled: O,
89
- preparingCount: L
146
+ /* @__PURE__ */ f(re, {
147
+ attachments: P,
148
+ onRemove: xe,
149
+ onRetry: Se,
150
+ disabled: S || O,
151
+ preparingCount: be
90
152
  }),
91
- /* @__PURE__ */ h("div", {
153
+ /* @__PURE__ */ p("div", {
92
154
  className: "flex items-end gap-2",
93
155
  children: [
94
- /* @__PURE__ */ m(re, {
95
- onFiles: B,
96
- canAddMore: fe,
97
- disabled: O,
156
+ /* @__PURE__ */ f(ne, {
157
+ onFiles: L,
158
+ canAddMore: we,
159
+ disabled: S || O,
98
160
  showLabel: !0
99
161
  }),
100
- /* @__PURE__ */ m("textarea", {
101
- ref: k,
102
- value: A,
103
- onChange: (e) => j(e.target.value),
104
- onKeyDown: he,
105
- onPaste: ge,
106
- disabled: O,
107
- placeholder: M ? E("composer.dropHere", "Drop files to attach") : me,
162
+ /* @__PURE__ */ f("textarea", {
163
+ ref: C,
164
+ value: w,
165
+ onChange: (e) => T(e.target.value),
166
+ onKeyDown: Oe,
167
+ onPaste: ke,
168
+ disabled: S,
169
+ readOnly: O,
170
+ "aria-busy": O || void 0,
171
+ placeholder: E ? b("composer.dropHere", "Drop files to attach") : Ee,
108
172
  rows: 1,
109
173
  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",
110
- "aria-label": E("chatInput.ariaLabel", "Message input"),
174
+ "aria-label": b("chatInput.ariaLabel", "Message input"),
111
175
  "data-testid": "assistant-input"
112
176
  }),
113
- q.isSupported && /* @__PURE__ */ m(o, {
114
- isListening: q.isListening,
115
- isStarting: q.isStarting,
116
- onToggle: q.toggle,
117
- disabled: O
177
+ W.isSupported && /* @__PURE__ */ f(ae, {
178
+ isListening: W.isListening,
179
+ isStarting: W.isStarting,
180
+ onToggle: W.toggle,
181
+ disabled: S || O
118
182
  }),
119
- w && J.length === 0 && F.length === 0 && !q.isActive ? /* @__PURE__ */ m(c, {
120
- onStart: w,
121
- disabled: O
122
- }) : /* @__PURE__ */ m("button", {
183
+ v && G.length === 0 && P.length === 0 && !W.isActive ? /* @__PURE__ */ f(se, {
184
+ onStart: v,
185
+ disabled: S || O
186
+ }) : /* @__PURE__ */ f("button", {
123
187
  type: "button",
124
- onClick: Q,
125
- disabled: !Z,
126
- 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 ${Z ? "bg-action-primary-bg text-action-primary-text hover:scale-105 hover:bg-action-primary-bg-hover" : "bg-bg-elevated text-text-muted"}`,
127
- "aria-label": E("chatInput.send", "Send message"),
188
+ onClick: () => void Q(),
189
+ disabled: !J,
190
+ 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 ${J ? "bg-action-primary-bg text-action-primary-text hover:scale-105 hover:bg-action-primary-bg-hover" : "bg-bg-elevated text-text-muted"}`,
191
+ "aria-label": b("chatInput.send", "Send message"),
128
192
  "data-testid": "assistant-send",
129
- children: y || I ? /* @__PURE__ */ m(se, { className: "size-4 motion-safe:animate-spin" }) : /* @__PURE__ */ m(oe, { className: "size-4" })
193
+ children: g || ye || O ? /* @__PURE__ */ f(d, { className: "size-4 motion-safe:animate-spin" }) : /* @__PURE__ */ f(de, { className: "size-4" })
130
194
  })
131
195
  ]
132
196
  }),
133
- x.length > 1 && /* @__PURE__ */ m("div", {
197
+ _.length > 1 && /* @__PURE__ */ f("div", {
134
198
  className: "mt-2 px-0.5",
135
- children: /* @__PURE__ */ m(a, {
136
- mode: le,
137
- availableModes: x,
138
- onModeChange: C,
139
- disabled: O,
140
- auto: ue
199
+ children: /* @__PURE__ */ f(ie, {
200
+ mode: he,
201
+ availableModes: _,
202
+ onModeChange: _e,
203
+ disabled: S || O,
204
+ auto: ve
141
205
  })
142
206
  })
143
207
  ]
144
208
  }),
145
- _ ? /* @__PURE__ */ m("p", {
209
+ m ? /* @__PURE__ */ f("p", {
146
210
  className: "mt-1.5 px-1 text-center text-[11px] text-status-warning",
147
211
  "data-testid": "assistant-write-access-warning",
148
- children: E("composer.writeAccessDenied", "Changes may not save — your role in this workspace does not currently allow edits. You can still plan and review an action.")
212
+ children: b("composer.writeAccessDenied", "Changes may not save — your role in this workspace does not currently allow edits. You can still plan and review an action.")
149
213
  }) : null,
150
- /* @__PURE__ */ m("div", {
214
+ /* @__PURE__ */ f("div", {
151
215
  className: "mt-1.5 px-1 text-center text-[11px]",
152
216
  "aria-live": "polite",
153
- children: q.isStarting && !q.isListening ? /* @__PURE__ */ m("p", {
217
+ children: O ? /* @__PURE__ */ f(t, {
218
+ onDismiss: $,
219
+ children: /* @__PURE__ */ p("p", {
220
+ className: "flex items-center justify-center gap-2 text-text-muted",
221
+ "data-testid": "assistant-commit-status",
222
+ children: [
223
+ /* @__PURE__ */ f(d, {
224
+ className: "size-3 motion-safe:animate-spin",
225
+ "aria-hidden": "true"
226
+ }),
227
+ /* @__PURE__ */ f("span", { children: b("attachments.saving", "Saving your attachments…") }),
228
+ /* @__PURE__ */ f("button", {
229
+ type: "button",
230
+ onClick: $,
231
+ className: "rounded text-text-primary underline underline-offset-2 hover:text-action-primary-bg focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
232
+ "data-testid": "assistant-commit-cancel",
233
+ children: b("attachments.cancelSaving", "Cancel")
234
+ })
235
+ ]
236
+ })
237
+ }) : j ? /* @__PURE__ */ f("p", {
238
+ className: "text-status-error-text",
239
+ role: "alert",
240
+ "data-testid": "assistant-commit-failed",
241
+ children: De(j)
242
+ }) : W.isStarting && !W.isListening ? /* @__PURE__ */ f("p", {
154
243
  className: "text-text-muted",
155
244
  "data-testid": "assistant-voice-starting",
156
- children: E("voice.starting", "Starting the microphone…")
157
- }) : q.isListening ? /* @__PURE__ */ h("p", {
245
+ children: b("voice.starting", "Starting the microphone…")
246
+ }) : W.isListening ? /* @__PURE__ */ p("p", {
158
247
  className: "text-status-error-text",
159
248
  "data-testid": "assistant-voice-status",
160
- children: [/* @__PURE__ */ m(s, {}), q.interim || E("voice.listening", "Listening… speak now, tap the square to stop")]
161
- }) : $ ? /* @__PURE__ */ m("p", {
249
+ children: [/* @__PURE__ */ f(oe, {}), W.interim || b("voice.listening", "Listening… speak now, tap the square to stop")]
250
+ }) : Fe ? /* @__PURE__ */ f("p", {
162
251
  className: "text-status-error-text",
163
252
  "data-testid": "assistant-voice-error",
164
- children: $
165
- }) : z ? /* @__PURE__ */ m("button", {
253
+ children: Fe
254
+ }) : I ? /* @__PURE__ */ f("button", {
166
255
  type: "button",
167
- onClick: de,
256
+ onClick: Ce,
168
257
  className: "text-status-error-text underline-offset-2 hover:underline",
169
258
  "data-testid": "assistant-attachment-rejection",
170
- children: xe(z)
171
- }) : R === "failed" ? /* @__PURE__ */ m("p", {
259
+ children: Pe(I)
260
+ }) : F === "failed" ? /* @__PURE__ */ f("p", {
172
261
  className: "text-status-error-text",
173
262
  "data-testid": "assistant-attachment-blocked",
174
- children: X.length === 1 ? E("attachments.blockedOne", "{{name}} didn't upload. Retry or remove it before sending.", { name: X[0].filename }) : E("attachments.blockedMany", "{{count}} attachments didn't upload. Retry or remove them before sending.", { count: X.length })
175
- }) : /* @__PURE__ */ m("p", {
263
+ children: q.length === 1 ? b("attachments.blockedOne", "{{name}} didn't upload. Retry or remove it before sending.", { name: q[0].filename }) : b("attachments.blockedMany", "{{count}} attachments didn't upload. Retry or remove them before sending.", { count: q.length })
264
+ }) : /* @__PURE__ */ f("p", {
176
265
  className: "text-text-muted",
177
- children: E("composer.hint", "Enter to send · Shift+Enter for newline · drag or paste files to attach")
266
+ children: b("composer.hint", "Enter to send · Shift+Enter for newline · drag or paste files to attach")
178
267
  })
179
268
  })
180
269
  ]
181
270
  });
182
271
  };
183
272
  //#endregion
184
- export { _ as AssistantComposer };
273
+ export { m as AssistantComposer };
@@ -41,6 +41,16 @@ interface Props {
41
41
  canAttachMore?: boolean;
42
42
  /** Files being read — placeholder chips, see AssistantAttachmentChips. */
43
43
  preparingAttachments?: number;
44
+ /**
45
+ * The spoken turn's files are being SAVED (BOFF-8677). Attaching and the chips' actions are
46
+ * disabled meanwhile, so the draft cannot change under the save.
47
+ */
48
+ attachmentsLocked?: boolean;
49
+ /**
50
+ * Some files could not be saved and were not sent with the question that was still asked
51
+ * ("2 attachments couldn't be saved and weren't sent."). Announced politely; clears itself.
52
+ */
53
+ attachmentNotice?: string | null;
44
54
  /** Reveals the assistant caption in step with the audio. */
45
55
  spokenChunks?: {
46
56
  chunks: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantVoiceSession.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceSession.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAS7D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,6CAA6C,CAAC;AAqBjG,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,iEAAiE;IACjE,KAAK,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC3C,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,aAAa,CAAC,EAAE,6BAA6B,GAAG,IAAI,CAAC;IACrD,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,6EAA6E;IAC7E,YAAY,CAAC,EAAE;QACb,OAAO,EAAE,SAAS,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,GAAG,IAAI,CAAC;IACT;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC;CACjD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CA81B3C,CAAC"}
1
+ {"version":3,"file":"AssistantVoiceSession.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceSession.tsx"],"names":[],"mappings":"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"}