@burdenoff/fe-libs 2026.1004.4 → 2026.1004.5

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 (37) hide show
  1. package/dist/shared/assistant/i18nManifest.d.ts +10 -0
  2. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  3. package/dist/shared/assistant/i18nManifest.js +22 -12
  4. package/dist/shared/assistant/index.d.ts +3 -0
  5. package/dist/shared/assistant/index.d.ts.map +1 -1
  6. package/dist/shared/assistant/store.d.ts +10 -0
  7. package/dist/shared/assistant/store.d.ts.map +1 -1
  8. package/dist/shared/assistant/store.js +52 -44
  9. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  10. package/dist/shared/assistant/ui/AssistantChatArea.js +761 -746
  11. package/dist/shared/assistant/ui/AssistantMoreMenu.d.ts.map +1 -1
  12. package/dist/shared/assistant/ui/AssistantMoreMenu.js +58 -56
  13. package/dist/shared/assistant/ui/AssistantSpeechProvider.d.ts.map +1 -1
  14. package/dist/shared/assistant/ui/AssistantSpeechProvider.js +106 -105
  15. package/dist/shared/assistant/ui/composer/AssistantVoiceGraceSelector.d.ts +20 -0
  16. package/dist/shared/assistant/ui/composer/AssistantVoiceGraceSelector.d.ts.map +1 -0
  17. package/dist/shared/assistant/ui/composer/AssistantVoiceGraceSelector.js +39 -0
  18. package/dist/shared/assistant/ui/useVoiceSession.d.ts +35 -2
  19. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  20. package/dist/shared/assistant/ui/useVoiceSession.js +232 -171
  21. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +15 -1
  22. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
  23. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +121 -101
  24. package/dist/shared/assistant/voice/handsFree.d.ts +160 -0
  25. package/dist/shared/assistant/voice/handsFree.d.ts.map +1 -0
  26. package/dist/shared/assistant/voice/handsFree.js +104 -0
  27. package/dist/shared/assistant/voice/supersededTurns.d.ts +29 -0
  28. package/dist/shared/assistant/voice/supersededTurns.d.ts.map +1 -0
  29. package/dist/shared/assistant/voice/supersededTurns.js +17 -0
  30. package/dist/shared/assistant/voice/useVoiceInput.d.ts +7 -0
  31. package/dist/shared/assistant/voice/useVoiceInput.d.ts.map +1 -1
  32. package/dist/shared/assistant/voice/useVoiceInput.js +13 -10
  33. package/dist/shared/assistant/voice/voiceSession.d.ts +64 -20
  34. package/dist/shared/assistant/voice/voiceSession.d.ts.map +1 -1
  35. package/dist/shared/assistant/voice/voiceSession.js +120 -67
  36. package/dist/shared-assistant.js +206 -203
  37. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantMoreMenu.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMoreMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAiB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAqM/B,CAAC"}
1
+ {"version":3,"file":"AssistantMoreMenu.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantMoreMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAkB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAyM/B,CAAC"}
@@ -4,115 +4,117 @@ import { useAssistantSpeech as n } from "./AssistantSpeechProvider.js";
4
4
  import { AssistantLanguageMenu as r } from "./AssistantLanguageMenu.js";
5
5
  import { useDropdownEscape as i } from "./useDropdownEscape.js";
6
6
  import { AssistantVoiceSelector as a } from "./composer/AssistantVoiceSelector.js";
7
- import { downloadFile as o, exportConversation as s } from "../exportConversation.js";
8
- import { useEffect as c, useRef as l, useState as u } from "react";
9
- import { Check as d, FileJson as f, FileText as p, MoreHorizontal as m, Play as h, Volume2 as g } from "lucide-react";
10
- import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
7
+ import { AssistantVoiceGraceSelector as o } from "./composer/AssistantVoiceGraceSelector.js";
8
+ import { downloadFile as s, exportConversation as c } from "../exportConversation.js";
9
+ import { useEffect as l, useRef as u, useState as d } from "react";
10
+ import { Check as f, FileJson as p, FileText as m, MoreHorizontal as h, Play as g, Volume2 as _ } from "lucide-react";
11
+ import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
11
12
  //#region src/shared/assistant/ui/AssistantMoreMenu.tsx
12
- var b = () => {
13
- let b = e(), [x, S] = u(!1), C = l(null), w = l(null), { conversations: T, activeConversationId: E, processingByConversationId: D } = t(), O = T.find((e) => e.id === E), k = !!(O && O.messages.length > 0), { isSupported: A, isBlocked: j, disabledReason: M, autoSpeakEnabled: N, setAutoSpeak: P, stop: F, previewVoice: I, activeVoiceName: L } = n(), R = j && !N;
14
- i(x, C, w, () => S(!1)), c(() => {
15
- if (!x) return;
13
+ var x = () => {
14
+ let x = e(), [S, C] = d(!1), w = u(null), T = u(null), { conversations: E, activeConversationId: D, processingByConversationId: O } = t(), k = E.find((e) => e.id === D), A = !!(k && k.messages.length > 0), { isSupported: j, isBlocked: M, disabledReason: N, autoSpeakEnabled: P, setAutoSpeak: F, stop: I, previewVoice: L, activeVoiceName: R } = n(), z = M && !P;
15
+ i(S, w, T, () => C(!1)), l(() => {
16
+ if (!S) return;
16
17
  let e = (e) => {
17
18
  let t = e.target;
18
- C.current?.contains(t) || w.current?.contains(t) || S(!1);
19
+ w.current?.contains(t) || T.current?.contains(t) || C(!1);
19
20
  };
20
21
  return document.addEventListener("mousedown", e), () => {
21
22
  document.removeEventListener("mousedown", e);
22
23
  };
23
- }, [x]);
24
- let z = (e) => {
25
- if (!O) return;
26
- let { content: t, filename: n, mimeType: r } = s(O, e, {
27
- processing: D[O.id],
28
- tr: b
24
+ }, [S]);
25
+ let B = (e) => {
26
+ if (!k) return;
27
+ let { content: t, filename: n, mimeType: r } = c(k, e, {
28
+ processing: O[k.id],
29
+ tr: x
29
30
  });
30
- o(t, n, r), S(!1);
31
- }, B = () => {
32
- N && F(), P(!N);
33
- }, V = b("header.more", "More options");
34
- return /* @__PURE__ */ y("div", {
31
+ s(t, n, r), C(!1);
32
+ }, V = () => {
33
+ P && I(), F(!P);
34
+ }, H = x("header.more", "More options");
35
+ return /* @__PURE__ */ b("div", {
35
36
  className: "relative",
36
- children: [/* @__PURE__ */ v("button", {
37
- ref: w,
37
+ children: [/* @__PURE__ */ y("button", {
38
+ ref: T,
38
39
  type: "button",
39
- onClick: () => S((e) => !e),
40
+ onClick: () => C((e) => !e),
40
41
  className: "rounded p-1 transition-colors hover:bg-bg-elevated",
41
- "aria-label": V,
42
+ "aria-label": H,
42
43
  "aria-haspopup": "menu",
43
- "aria-expanded": x,
44
+ "aria-expanded": S,
44
45
  "data-testid": "assistant-more",
45
- children: /* @__PURE__ */ v(m, { className: "size-4 text-text-secondary" })
46
- }), x ? /* @__PURE__ */ y("div", {
47
- ref: C,
46
+ children: /* @__PURE__ */ y(h, { className: "size-4 text-text-secondary" })
47
+ }), S ? /* @__PURE__ */ b("div", {
48
+ ref: w,
48
49
  role: "menu",
49
- "aria-label": V,
50
+ "aria-label": H,
50
51
  className: "absolute right-0 top-full z-50 mt-1 min-w-56 overflow-hidden rounded-xl border border-border-default bg-bg-surface py-1 shadow-lg",
51
52
  "data-testid": "assistant-more-menu",
52
53
  children: [
53
- A ? /* @__PURE__ */ y("button", {
54
+ j ? /* @__PURE__ */ b("button", {
54
55
  type: "button",
55
56
  role: "menuitemcheckbox",
56
- "aria-checked": N,
57
- onClick: B,
58
- disabled: R,
59
- title: R ? M ?? void 0 : void 0,
57
+ "aria-checked": P,
58
+ onClick: V,
59
+ disabled: z,
60
+ title: z ? N ?? void 0 : void 0,
60
61
  className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated disabled:cursor-not-allowed disabled:text-text-muted disabled:hover:bg-transparent",
61
62
  "data-testid": "assistant-auto-speak",
62
63
  children: [
63
- /* @__PURE__ */ v(g, {
64
+ /* @__PURE__ */ y(_, {
64
65
  className: "size-3.5 flex-shrink-0 text-text-secondary",
65
66
  "aria-hidden": "true"
66
67
  }),
67
- /* @__PURE__ */ v("span", {
68
+ /* @__PURE__ */ y("span", {
68
69
  className: "flex-1",
69
- children: b("header.autoRead", "Auto-read replies")
70
+ children: x("header.autoRead", "Auto-read replies")
70
71
  }),
71
- N ? /* @__PURE__ */ v(d, { className: "size-3.5 flex-shrink-0 text-action-primary-bg" }) : null
72
+ P ? /* @__PURE__ */ y(f, { className: "size-3.5 flex-shrink-0 text-action-primary-bg" }) : null
72
73
  ]
73
74
  }) : null,
74
- /* @__PURE__ */ v(r, {}),
75
- /* @__PURE__ */ y("div", {
75
+ /* @__PURE__ */ y(r, {}),
76
+ /* @__PURE__ */ b("div", {
76
77
  className: "flex items-center gap-1 px-3 py-1.5",
77
78
  "data-testid": "assistant-more-voice",
78
- children: [/* @__PURE__ */ v(a, {}), L ? /* @__PURE__ */ y("button", {
79
+ children: [/* @__PURE__ */ y(a, {}), R ? /* @__PURE__ */ b("button", {
79
80
  type: "button",
80
- onClick: () => I(L),
81
+ onClick: () => L(R),
81
82
  className: "flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-text-muted transition-colors hover:bg-bg-elevated hover:text-text-secondary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
82
- "aria-label": b("voice.preview", "Hear this voice"),
83
+ "aria-label": x("voice.preview", "Hear this voice"),
83
84
  "data-testid": "assistant-voice-preview",
84
- children: [/* @__PURE__ */ v(h, {
85
+ children: [/* @__PURE__ */ y(g, {
85
86
  className: "size-3",
86
87
  "aria-hidden": "true"
87
- }), b("voice.previewShort", "Preview")]
88
+ }), x("voice.previewShort", "Preview")]
88
89
  }) : null]
89
90
  }),
90
- k ? /* @__PURE__ */ y(_, { children: [
91
- /* @__PURE__ */ v("div", {
91
+ /* @__PURE__ */ y(o, {}),
92
+ A ? /* @__PURE__ */ b(v, { children: [
93
+ /* @__PURE__ */ y("div", {
92
94
  className: "my-1 border-t border-border-subtle",
93
95
  role: "separator"
94
96
  }),
95
- /* @__PURE__ */ y("button", {
97
+ /* @__PURE__ */ b("button", {
96
98
  type: "button",
97
99
  role: "menuitem",
98
- onClick: () => z("json"),
100
+ onClick: () => B("json"),
99
101
  className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated",
100
102
  "data-testid": "export-json",
101
- children: [/* @__PURE__ */ v(f, {
103
+ children: [/* @__PURE__ */ y(p, {
102
104
  className: "size-3.5 flex-shrink-0 text-text-secondary",
103
105
  "aria-hidden": "true"
104
- }), b("export.json", "Export as JSON")]
106
+ }), x("export.json", "Export as JSON")]
105
107
  }),
106
- /* @__PURE__ */ y("button", {
108
+ /* @__PURE__ */ b("button", {
107
109
  type: "button",
108
110
  role: "menuitem",
109
- onClick: () => z("markdown"),
111
+ onClick: () => B("markdown"),
110
112
  className: "flex w-full items-center gap-2.5 px-3 py-2 text-left text-xs text-text-primary transition-colors hover:bg-bg-elevated",
111
113
  "data-testid": "export-markdown",
112
- children: [/* @__PURE__ */ v(p, {
114
+ children: [/* @__PURE__ */ y(m, {
113
115
  className: "size-3.5 flex-shrink-0 text-text-secondary",
114
116
  "aria-hidden": "true"
115
- }), b("export.markdown", "Export as Markdown")]
117
+ }), x("export.markdown", "Export as Markdown")]
116
118
  })
117
119
  ] }) : null
118
120
  ]
@@ -120,4 +122,4 @@ var b = () => {
120
122
  });
121
123
  };
122
124
  //#endregion
123
- export { b as AssistantMoreMenu };
125
+ export { x as AssistantMoreMenu };
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantSpeechProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantSpeechProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAUL,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA6B/D,OAAO,EAQL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAoB/B,MAAM,WAAW,2BAA2B;IAC1C,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;;OAMG;IACH,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,8EAA8E;IAC9E;;;;;;OAMG;IACH,YAAY,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;;;;OAQG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3E,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;;;;;;;;;;OAaG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;;;;;;;;;;;OAaG;IACH,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C;;;;;;;OAOG;IACH,kBAAkB,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,kFAAkF;IAClF,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AA6BD,wBAAgB,kBAAkB,IAAI,2BAA2B,CAEhE;AAED,UAAU,KAAK;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,KAAK,CAilC7C,CAAC"}
1
+ {"version":3,"file":"AssistantSpeechProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantSpeechProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAUL,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA6B/D,OAAO,EAQL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAqB/B,MAAM,WAAW,2BAA2B;IAC1C,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;;OAMG;IACH,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,8EAA8E;IAC9E;;;;;;OAMG;IACH,YAAY,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;;;;OAQG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3E,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;;;;;;;;;;OAaG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;;;;;;;;;;;OAaG;IACH,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C;;;;;;;OAOG;IACH,kBAAkB,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,kFAAkF;IAClF,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AA6BD,wBAAgB,kBAAkB,IAAI,2BAA2B,CAEhE;AAED,UAAU,KAAK;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,KAAK,CAylC7C,CAAC"}
@@ -3,23 +3,24 @@ import { useAssistantTr as t } from "../i18n.js";
3
3
  import { useAssistantStore as n } from "../store.js";
4
4
  import { isVoiceTurn as r } from "../voice/turnVisibility.js";
5
5
  import { VOICE_LIST_TIMEOUT_MS as i, languageDisplayName as a, selectVoiceForLocale as o, speechGate as s, speechLangForLocale as c, voiceAvailability as l, voicesForLocale as u } from "../voice/speechVoices.js";
6
- import { getSpeechEngine as d, subscribeSpeechEngine as f } from "../speech/createSpeechEngine.js";
7
- import { speechFeed as p } from "../speech/speechFeed.js";
8
- import { chunkForSpeech as ee, toSpeakableText as m } from "../voice/speakableText.js";
9
- import { voicePreviewText as te } from "../voice/voicePreview.js";
10
- import { findAssistantLanguage as ne } from "../voice/languages.js";
11
- import { resolveLanguagePair as re } from "../voice/languagePair.js";
12
- import { speechLabelsFor as ie } from "../voice/speechLabels.js";
13
- import { resolveSpeechLocale as ae } from "../voice/replyLanguage.js";
14
- import { IDLE_PLAYBACK as oe, isSpeakingMessage as se, publishedChunks as ce, speechPlaybackReducer as le } from "../voice/speechPlayback.js";
15
- import { isTurnInFlight as ue } from "../turnState.js";
16
- import { parseToolActivity as de } from "./AssistantToolActivity.js";
6
+ import { getSpeechEngine as d, subscribeSpeechEngine as ee } from "../speech/createSpeechEngine.js";
7
+ import { speechFeed as f } from "../speech/speechFeed.js";
8
+ import { isTurnSuperseded as p } from "../voice/supersededTurns.js";
9
+ import { chunkForSpeech as te, toSpeakableText as m } from "../voice/speakableText.js";
10
+ import { voicePreviewText as ne } from "../voice/voicePreview.js";
11
+ import { findAssistantLanguage as re } from "../voice/languages.js";
12
+ import { resolveLanguagePair as ie } from "../voice/languagePair.js";
13
+ import { speechLabelsFor as ae } from "../voice/speechLabels.js";
14
+ import { resolveSpeechLocale as oe } from "../voice/replyLanguage.js";
15
+ import { IDLE_PLAYBACK as se, isSpeakingMessage as ce, publishedChunks as le, speechPlaybackReducer as ue } from "../voice/speechPlayback.js";
16
+ import { isTurnInFlight as de } from "../turnState.js";
17
+ import { parseToolActivity as fe } from "./AssistantToolActivity.js";
17
18
  import "../speech/index.js";
18
19
  import { markTurn as h } from "../turnTimeline.js";
19
- import { createContext as fe, useCallback as g, useContext as _, useEffect as v, useMemo as y, useReducer as pe, useRef as b, useState as x, useSyncExternalStore as me } from "react";
20
- import { jsx as he } from "react/jsx-runtime";
20
+ import { createContext as pe, useCallback as g, useContext as _, useEffect as v, useMemo as y, useReducer as me, useRef as b, useState as x, useSyncExternalStore as he } from "react";
21
+ import { jsx as ge } from "react/jsx-runtime";
21
22
  //#region src/shared/assistant/ui/AssistantSpeechProvider.tsx
22
- var ge = {
23
+ var _e = {
23
24
  codeBlock: "",
24
25
  image: "",
25
26
  link: "",
@@ -28,7 +29,7 @@ var ge = {
28
29
  emailAt: "at",
29
30
  emailDot: "dot",
30
31
  nestedItem: ""
31
- }, _e = 4e3, ve = fe({
32
+ }, ve = 4e3, ye = pe({
32
33
  isSupported: !1,
33
34
  availability: "unsupported",
34
35
  isBlocked: !0,
@@ -51,17 +52,17 @@ var ge = {
51
52
  speakFinishedReply: () => {},
52
53
  previewVoice: () => {}
53
54
  });
54
- function ye() {
55
- return _(ve);
55
+ function be() {
56
+ return _(ye);
56
57
  }
57
- var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
58
- let be = me(f, d, d), S = ye ?? be, C = t(), { locale: w } = e(), [T, E] = pe(le, oe), [D, O] = x(() => S.listVoices()), [k, xe] = x(!1), [Se, A] = x(() => /* @__PURE__ */ new Map()), j = b(0), M = b(null), N = b(null), P = b(null);
58
+ var xe = ({ children: pe, visible: _ = !0, engine: be }) => {
59
+ let xe = he(ee, d, d), S = be ?? xe, C = t(), { locale: w } = e(), [T, E] = me(ue, se), [D, O] = x(() => S.listVoices()), [k, Se] = x(!1), [Ce, A] = x(() => /* @__PURE__ */ new Map()), j = b(0), M = b(null), N = b(null), P = b(null);
59
60
  v(() => () => {
60
61
  P.current !== null && clearTimeout(P.current);
61
62
  }, []);
62
- let [Ce, F] = x(null), I = b(null), we = b(() => {}), L = g(() => {
63
+ let [we, F] = x(null), I = b(null), Te = b(() => {}), L = g(() => {
63
64
  I.current?.(), I.current = null;
64
- }, []), R = n((e) => e.autoSpeakEnabled), Te = n((e) => e.setAutoSpeak), [z, Ee] = x(!1), B = b(!1), De = g((e) => {
65
+ }, []), R = n((e) => e.autoSpeakEnabled), Ee = n((e) => e.setAutoSpeak), [z, De] = x(!1), B = b(!1), Oe = g((e) => {
65
66
  B.current = e;
66
67
  }, []), V = n((e) => e.activeConversationId), H = y(() => S.isSupported(), [S]);
67
68
  v(() => {
@@ -71,16 +72,16 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
71
72
  };
72
73
  return e(), S.subscribeVoices(e);
73
74
  }, [S, H]);
74
- let Oe = n((e) => e.assistantLanguage), ke = n((e) => e.replyLanguage), U = n((e) => e.preferredVoices), Ae = n((e) => e.setPreferredVoice), W = y(() => re(Oe, ke, w).reply, [
75
- Oe,
75
+ let ke = n((e) => e.assistantLanguage), Ae = n((e) => e.replyLanguage), U = n((e) => e.preferredVoices), je = n((e) => e.setPreferredVoice), W = y(() => ie(ke, Ae, w).reply, [
76
76
  ke,
77
+ Ae,
77
78
  w
78
- ]), G = W.code, K = g((e) => ne(e)?.tag ?? c(e), []), je = g((e) => ne(e)?.rate ?? .9, []), q = y(() => l(H, D, W.tag, k), [
79
+ ]), G = W.code, K = g((e) => re(e)?.tag ?? c(e), []), Me = g((e) => re(e)?.rate ?? .9, []), q = y(() => l(H, D, W.tag, k), [
79
80
  H,
80
81
  D,
81
82
  W,
82
83
  k
83
- ]), Me = y(() => ({
84
+ ]), Ne = y(() => ({
84
85
  codeBlock: C("speech.codeBlock", "Code block"),
85
86
  image: C("speech.image", "image"),
86
87
  link: C("speech.link", "link"),
@@ -91,12 +92,12 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
91
92
  emailDot: C("speech.emailDot", "dot")
92
93
  }), [C]), J = g(() => {
93
94
  L(), M.current = null, S.cancel(), E({ type: "stop" });
94
- }, [L, S]), Ne = g((e) => {
95
+ }, [L, S]), Pe = g((e) => {
95
96
  let t = S.listVoices().find((t) => t.name === e) ?? null;
96
97
  if (t) {
97
98
  J();
98
99
  try {
99
- S.speak([te(G)], {
100
+ S.speak([ne(G)], {
100
101
  voice: t,
101
102
  lang: K(G),
102
103
  fallback: !1
@@ -108,15 +109,15 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
108
109
  G,
109
110
  J,
110
111
  K
111
- ]), Pe = g((e) => Se.get(e) ?? null, [Se]), Fe = g((e, t, n, r, a) => {
112
+ ]), Fe = g((e) => Ce.get(e) ?? null, [Ce]), Ie = g((e, t, n, r, a) => {
112
113
  L();
113
114
  let o = !1, s = () => {}, c = (i) => {
114
115
  if (!o) {
115
116
  if (o = !0, I.current = null, clearTimeout(l), s(), i.length === 0) {
116
- xe(!0);
117
+ Se(!0);
117
118
  return;
118
119
  }
119
- O(i), we.current(e, t, i, n, r, a);
120
+ O(i), Te.current(e, t, i, n, r, a);
120
121
  }
121
122
  }, l = setTimeout(() => c(S.listVoices()), i);
122
123
  s = S.subscribeVoices(() => c(S.listVoices())), I.current = () => {
@@ -128,14 +129,14 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
128
129
  let e = S.listVoices();
129
130
  e.length > 0 && (u = e, O(e));
130
131
  }
131
- let d = K(r), f = s(l(!0, u, r, k));
132
- if (f === "block") {
132
+ let d = K(r), ee = s(l(!0, u, r, k));
133
+ if (ee === "block") {
133
134
  let t = C("speech.noVoiceForReply", "This reply is in {{language}}, and no {{language}} voice is installed on this device.", { language: a(d, w) });
134
135
  A((n) => new Map(n).set(e, t));
135
136
  return;
136
137
  }
137
- if (f === "wait-for-voices") {
138
- Fe(e, t, r, i, c);
138
+ if (ee === "wait-for-voices") {
139
+ Ie(e, t, r, i, c);
139
140
  return;
140
141
  }
141
142
  A((t) => {
@@ -143,85 +144,85 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
143
144
  let n = new Map(t);
144
145
  return n.delete(e), n;
145
146
  }), L();
146
- let p = j.current + 1;
147
- j.current = p, E({
147
+ let f = j.current + 1;
148
+ j.current = f, E({
148
149
  type: "start",
149
150
  messageId: e,
150
- requestId: p
151
- }), M.current = i ? p : null, i && h(e, "ttsStarted");
152
- let m = c === void 0 ? ee(t) : ee(t, void 0, void 0, { firstChunkMaxChars: c });
151
+ requestId: f
152
+ }), M.current = i ? f : null, i && h(e, "ttsStarted");
153
+ let p = c === void 0 ? te(t) : te(t, void 0, void 0, { firstChunkMaxChars: c });
153
154
  F({
154
- requestId: p,
155
- chunks: m,
155
+ requestId: f,
156
+ chunks: p,
156
157
  index: -1
157
158
  }), P.current !== null && clearTimeout(P.current), P.current = setTimeout(() => {
158
- F((e) => e?.requestId === p && e.index < 0 ? null : e);
159
- }, _e);
160
- let te = () => {
161
- j.current === p && P.current !== null && (clearTimeout(P.current), P.current = null), E({
159
+ F((e) => e?.requestId === f && e.index < 0 ? null : e);
160
+ }, ve);
161
+ let m = () => {
162
+ j.current === f && P.current !== null && (clearTimeout(P.current), P.current = null), E({
162
163
  type: "failed",
163
- requestId: p
164
+ requestId: f
164
165
  });
165
166
  };
166
167
  try {
167
- S.speak(m, {
168
+ S.speak(p, {
168
169
  voice: o(u, d, U[r]),
169
170
  lang: d,
170
- rate: je(r)
171
+ rate: Me(r)
171
172
  }, {
172
173
  onStart: () => {
173
- j.current === p && M.current === p && h(e, "firstAudio");
174
+ j.current === f && M.current === f && h(e, "firstAudio");
174
175
  },
175
176
  onChunkStart: (e) => {
176
- j.current === p && P.current !== null && (clearTimeout(P.current), P.current = null), F((t) => t?.requestId === p ? {
177
+ j.current === f && P.current !== null && (clearTimeout(P.current), P.current = null), F((t) => t?.requestId === f ? {
177
178
  ...t,
178
179
  index: e
179
- } : j.current === p ? {
180
- requestId: p,
181
- chunks: m,
180
+ } : j.current === f ? {
181
+ requestId: f,
182
+ chunks: p,
182
183
  index: e
183
184
  } : t);
184
185
  },
185
186
  onEnd: () => {
186
- j.current === p && M.current === p && h(e, "audioEnded"), E({
187
+ j.current === f && M.current === f && h(e, "audioEnded"), E({
187
188
  type: "finished",
188
- requestId: p
189
+ requestId: f
189
190
  });
190
191
  },
191
192
  onError: () => E({
192
193
  type: "failed",
193
- requestId: p
194
+ requestId: f
194
195
  })
195
196
  });
196
197
  } catch {
197
- te();
198
+ m();
198
199
  }
199
200
  }, [
200
201
  L,
201
202
  S,
202
203
  w,
203
204
  U,
204
- je,
205
+ Me,
205
206
  K,
206
207
  C,
207
208
  k,
208
- Fe
209
+ Ie
209
210
  ]);
210
211
  v(() => {
211
- we.current = Y;
212
+ Te.current = Y;
212
213
  }, [Y]);
213
214
  let X = g((e, t, n, r) => {
214
215
  if (!H) return;
215
- let i = ae(m(t, { labels: ge }), n ?? G), a = m(t, { labels: ie(i, Me) });
216
+ let i = oe(m(t, { labels: _e }), n ?? G), a = m(t, { labels: ae(i, Ne) });
216
217
  a && Y(e, a, D, i, r?.auto === !0, r?.firstChunkMaxChars);
217
218
  }, [
218
219
  H,
219
- Me,
220
+ Ne,
220
221
  G,
221
222
  Y,
222
223
  D
223
- ]), Ie = g((e, t, n) => {
224
- if (se(T, e)) {
224
+ ]), Le = g((e, t, n) => {
225
+ if (ce(T, e)) {
225
226
  J();
226
227
  return;
227
228
  }
@@ -234,14 +235,14 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
234
235
  v(() => {
235
236
  _ || J();
236
237
  }, [_, J]);
237
- let Le = b({
238
+ let Z = b({
238
239
  autoSpeakEnabled: R,
239
240
  sessionSpeaking: z,
240
241
  visible: _,
241
242
  isSupported: H
242
243
  });
243
244
  v(() => {
244
- Le.current = {
245
+ Z.current = {
245
246
  autoSpeakEnabled: R,
246
247
  sessionSpeaking: z,
247
248
  visible: _,
@@ -271,7 +272,7 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
271
272
  let e = () => {
272
273
  if (document.visibilityState !== "visible") return;
273
274
  let e = S.listVoices();
274
- e.length > 0 && L(), O(e), xe(!1), A((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
275
+ e.length > 0 && L(), O(e), Se(!1), A((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
275
276
  };
276
277
  return document.addEventListener("visibilitychange", e), window.addEventListener("focus", e), () => {
277
278
  document.removeEventListener("visibilitychange", e), window.removeEventListener("focus", e);
@@ -281,15 +282,15 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
281
282
  S,
282
283
  H
283
284
  ]);
284
- let Z = b(X);
285
+ let Ve = b(X);
285
286
  v(() => {
286
- Z.current = X;
287
+ Ve.current = X;
287
288
  }, [X]);
288
289
  let Q = g((e, t) => {
289
- if (r(e) !== t || N.current?.messageId === e.id || B.current) return;
290
- let { text: n } = de(e.content);
290
+ if (r(e) !== t || p(e.id) || N.current?.messageId === e.id || B.current) return;
291
+ let { text: n } = fe(e.content);
291
292
  if (n.trim()) try {
292
- Z.current(e.id, n, e.metadata?.lang, { auto: !0 });
293
+ Ve.current(e.id, n, e.metadata?.lang, { auto: !0 });
293
294
  } catch {}
294
295
  }, []), $ = g((e, t) => {
295
296
  if (e !== Re.current) {
@@ -299,7 +300,7 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
299
300
  });
300
301
  return;
301
302
  }
302
- let r = Le.current;
303
+ let r = Z.current;
303
304
  if (!r.autoSpeakEnabled && !r.sessionSpeaking || !r.visible || !r.isSupported) return;
304
305
  let i = n.getState();
305
306
  if (i.activeConversationId !== e) return;
@@ -313,7 +314,7 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
313
314
  let n = e.activeConversationId;
314
315
  if (!n || n !== t.activeConversationId) return;
315
316
  let r = e.processingByConversationId[n], i = t.processingByConversationId[n];
316
- if (r?.status !== "complete" || !ue(i?.status)) return;
317
+ if (r?.status !== "complete" || !de(i?.status)) return;
317
318
  let a = r.messageId ?? i?.messageId ?? null;
318
319
  if (!a) return;
319
320
  let o = e.conversations.find((e) => e.id === n)?.messages.find((e) => e.id === a);
@@ -326,20 +327,20 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
326
327
  _,
327
328
  Q
328
329
  ]);
329
- let Ve = g((e) => {
330
+ let He = g((e) => {
330
331
  if (e.type === "abort") {
331
332
  let t = N.current;
332
333
  if (!t || t.messageId !== e.messageId) return;
333
334
  N.current = null, (t.requestId === null ? t.waiting && I.current !== null : j.current === t.requestId) && J();
334
335
  return;
335
336
  }
336
- let { messageId: t, item: r } = e, i = Le.current;
337
- if (!i.autoSpeakEnabled && !i.sessionSpeaking || !i.visible || !i.isSupported || r.channel === "voice" !== i.sessionSpeaking || B.current || N.current?.messageId === t || n.getState().activeConversationId !== r.conversationId || Re.current !== r.conversationId) return;
338
- let { text: a } = de(r.text);
337
+ let { messageId: t, item: r } = e, i = Z.current;
338
+ if (!i.autoSpeakEnabled && !i.sessionSpeaking || !i.visible || !i.isSupported || r.channel === "voice" !== i.sessionSpeaking || p(t) || B.current || N.current?.messageId === t || n.getState().activeConversationId !== r.conversationId || Re.current !== r.conversationId) return;
339
+ let { text: a } = fe(r.text);
339
340
  if (!a.trim()) return;
340
341
  let o = j.current;
341
342
  try {
342
- Z.current(t, a, r.lang, {
343
+ Ve.current(t, a, r.lang, {
343
344
  auto: !0,
344
345
  firstChunkMaxChars: 110
345
346
  });
@@ -351,59 +352,59 @@ var be = ({ children: fe, visible: _ = !0, engine: ye }) => {
351
352
  waiting: !s && I.current !== null
352
353
  };
353
354
  }, [J]);
354
- v(() => p.subscribe(Ve), [Ve]);
355
- let He = y(() => u(D, W.tag), [D, W]), Ue = y(() => o(D, W.tag, U[G]), [
355
+ v(() => f.subscribe(He), [He]);
356
+ let Ue = y(() => u(D, W.tag), [D, W]), We = y(() => o(D, W.tag, U[G]), [
356
357
  D,
357
358
  W,
358
359
  U,
359
360
  G
360
- ]), We = y(() => ({
361
+ ]), Ge = y(() => ({
361
362
  isSupported: H,
362
363
  availability: q,
363
364
  isBlocked: q === "no-voices",
364
365
  disabledReason: q === "no-voices" ? C("speech.noVoicesOnDevice", "This device has no speech voices installed. Add one in your device speech or accessibility settings.") : null,
365
- blockedFor: Pe,
366
- voiceChoices: He,
367
- spokenChunks: ce(T, Ce),
368
- activeVoiceName: Ue?.name ?? null,
366
+ blockedFor: Fe,
367
+ voiceChoices: Ue,
368
+ spokenChunks: le(T, we),
369
+ activeVoiceName: We?.name ?? null,
369
370
  preferredVoiceName: U[G] ?? null,
370
- setVoice: (e) => Ae(G, e),
371
+ setVoice: (e) => je(G, e),
371
372
  speakingMessageId: T.status === "speaking" ? T.messageId : null,
372
- isSpeaking: (e) => se(T, e),
373
- toggle: Ie,
373
+ isSpeaking: (e) => ce(T, e),
374
+ toggle: Le,
374
375
  stop: J,
375
376
  autoSpeakEnabled: R,
376
- setAutoSpeak: Te,
377
+ setAutoSpeak: Ee,
377
378
  sessionSpeaking: z,
378
- setSessionSpeaking: Ee,
379
- setSessionMicOpen: De,
379
+ setSessionSpeaking: De,
380
+ setSessionMicOpen: Oe,
380
381
  speakFinishedReply: $,
381
- previewVoice: Ne
382
+ previewVoice: Pe
382
383
  }), [
383
384
  H,
384
385
  q,
385
- Pe,
386
- He,
386
+ Fe,
387
387
  Ue,
388
+ We,
388
389
  U,
389
- Ae,
390
+ je,
390
391
  G,
391
392
  T,
392
- Ie,
393
+ Le,
393
394
  J,
394
395
  R,
395
- Te,
396
+ Ee,
396
397
  z,
397
- De,
398
+ Oe,
398
399
  $,
399
- Ne,
400
+ Pe,
400
401
  C,
401
- Ce
402
+ we
402
403
  ]);
403
- return /* @__PURE__ */ he(ve.Provider, {
404
- value: We,
405
- children: fe
404
+ return /* @__PURE__ */ ge(ye.Provider, {
405
+ value: Ge,
406
+ children: pe
406
407
  });
407
408
  };
408
409
  //#endregion
409
- export { be as AssistantSpeechProvider, ye as useAssistantSpeech };
410
+ export { xe as AssistantSpeechProvider, be as useAssistantSpeech };
@@ -0,0 +1,20 @@
1
+ import { FC } from 'react';
2
+ /**
3
+ * How long a voice conversation waits, in silence, before it sends what you
4
+ * said (H1): 2 seconds by default, or 3 or 5 for people who pause to think.
5
+ *
6
+ * The preference is persisted per profile and is the ONE value the voice
7
+ * session's submit timer waits (`planSubmitTimer`). Resuming to speak inside
8
+ * the wait cancels the send and carries on with the same turn, and "Let me
9
+ * finish" in the session holds it entirely — this is only the default patience.
10
+ *
11
+ * Renders nothing where there is no speech recognition: a setting for a
12
+ * microphone that cannot exist is a control that cannot do anything.
13
+ *
14
+ * A native `<select>`, like the voice and language pickers: on a phone it opens
15
+ * the OS picker, which already scrolls, localises itself and is reachable by
16
+ * speech-control users. Wrapped in its `<label>`, so the visible words are the
17
+ * accessible name (WCAG 2.5.3).
18
+ */
19
+ export declare const AssistantVoiceGraceSelector: FC;
20
+ //# sourceMappingURL=AssistantVoiceGraceSelector.d.ts.map