@burdenoff/fe-libs 2026.1016.2 → 2026.1017.1

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 (49) hide show
  1. package/dist/shared/assistant/avatar/live/AvatarFace.d.ts +13 -0
  2. package/dist/shared/assistant/avatar/live/AvatarFace.js +46 -0
  3. package/dist/shared/assistant/avatar/live/LiveAvatarTabView.d.ts +2 -0
  4. package/dist/shared/assistant/avatar/live/LiveAvatarTabView.js +172 -145
  5. package/dist/shared/assistant/avatar/live/avatarFaces.d.ts +31 -0
  6. package/dist/shared/assistant/avatar/live/avatarFaces.js +33 -0
  7. package/dist/shared/assistant/avatar/live/createLiveAvatarSeam.d.ts +12 -0
  8. package/dist/shared/assistant/avatar/live/createLiveAvatarSeam.js +142 -75
  9. package/dist/shared/assistant/avatar/live/liveAvatarController.d.ts +5 -0
  10. package/dist/shared/assistant/avatar/live/liveAvatarController.js +3 -1
  11. package/dist/shared/assistant/avatar/live/liveAvatarStatus.d.ts +14 -0
  12. package/dist/shared/assistant/avatar/live/liveAvatarStatus.js +11 -2
  13. package/dist/shared/assistant/avatar/useAvatarCopy.d.ts +42 -0
  14. package/dist/shared/assistant/avatar/useAvatarCopy.js +113 -75
  15. package/dist/shared/assistant/i18nManifest.d.ts +29 -0
  16. package/dist/shared/assistant/i18nManifest.js +29 -0
  17. package/dist/shared/assistant/index.d.ts +8 -0
  18. package/dist/shared/assistant/speech/hostedTtsSpeechEngine.d.ts +6 -0
  19. package/dist/shared/assistant/speech/hostedTtsSpeechEngine.js +118 -101
  20. package/dist/shared/assistant/speech/notifyCancellationSpeechEngine.js +3 -0
  21. package/dist/shared/assistant/speech/replySpeechRequests.d.ts +84 -0
  22. package/dist/shared/assistant/speech/replySpeechRequests.js +70 -0
  23. package/dist/shared/assistant/speech/routingSpeechEngine.js +13 -9
  24. package/dist/shared/assistant/speech/types.d.ts +39 -1
  25. package/dist/shared/assistant/ui/AIAssistantPanel.js +128 -119
  26. package/dist/shared/assistant/ui/AssistantChatArea.js +1572 -1430
  27. package/dist/shared/assistant/ui/AssistantMessageItem.js +110 -100
  28. package/dist/shared/assistant/ui/AssistantSpeechProvider.d.ts +10 -0
  29. package/dist/shared/assistant/ui/AssistantSpeechProvider.js +286 -225
  30. package/dist/shared/assistant/ui/assistantLiveAvatarSeam.d.ts +40 -0
  31. package/dist/shared/assistant/ui/avatar/AssistantAvatarTab.d.ts +6 -0
  32. package/dist/shared/assistant/ui/avatar/AssistantAvatarTab.js +99 -52
  33. package/dist/shared/assistant/ui/avatar/AvatarTabAskBox.d.ts +8 -0
  34. package/dist/shared/assistant/ui/avatar/AvatarTabAskBox.js +87 -0
  35. package/dist/shared/assistant/ui/avatar/AvatarTabLastExchange.d.ts +13 -0
  36. package/dist/shared/assistant/ui/avatar/AvatarTabLastExchange.js +97 -0
  37. package/dist/shared/assistant/ui/avatar/avatarAskGate.d.ts +104 -0
  38. package/dist/shared/assistant/ui/avatar/avatarAskGate.js +39 -0
  39. package/dist/shared/assistant/ui/avatar/avatarTabDraft.d.ts +17 -0
  40. package/dist/shared/assistant/ui/avatar/avatarTabDraft.js +22 -0
  41. package/dist/shared/assistant/ui/avatar/avatarTabExchange.d.ts +47 -0
  42. package/dist/shared/assistant/ui/avatar/avatarTabExchange.js +50 -0
  43. package/dist/shared/assistant/ui/panelOverlays.d.ts +8 -1
  44. package/dist/shared/assistant/ui/panelOverlays.js +1 -1
  45. package/dist/shared/assistant/ui/useVoiceSession.js +222 -227
  46. package/dist/shared/assistant/voice/handsfree/playbackReference.d.ts +15 -4
  47. package/dist/shared/assistant/voice/handsfree/playbackReference.js +9 -6
  48. package/dist/shared-assistant.js +270 -262
  49. package/package.json +1 -1
@@ -1,99 +1,137 @@
1
1
  import { useI18n as e } from "../../providers/shell/I18nProvider.js";
2
2
  import { useAssistantTr as t } from "../i18n.js";
3
- import { useMemo as n } from "react";
3
+ import { VOICE_THINKING_LABEL as n } from "../voice/voiceStatus.js";
4
+ import { useMemo as r } from "react";
4
5
  //#region src/shared/assistant/avatar/useAvatarCopy.ts
5
- var r = {
6
+ var i = {
6
7
  hour: "numeric",
7
8
  minute: "2-digit"
8
- }, i = {
9
+ }, a = {
9
10
  month: "short",
10
11
  day: "numeric",
11
12
  hour: "numeric",
12
13
  minute: "2-digit"
13
14
  };
14
- function a(e, t, n) {
15
- let a = new Date(e).toDateString() === new Date(t).toDateString() ? r : i;
15
+ function o(e, t, n) {
16
+ let r = new Date(e).toDateString() === new Date(t).toDateString() ? i : a;
16
17
  try {
17
- return new Intl.DateTimeFormat(n, a).format(e);
18
+ return new Intl.DateTimeFormat(n, r).format(e);
18
19
  } catch {
19
- return new Intl.DateTimeFormat("en", a).format(e);
20
+ return new Intl.DateTimeFormat("en", r).format(e);
20
21
  }
21
22
  }
22
- function o() {
23
- let r = t(), { locale: i } = e();
24
- return n(() => ({
25
- toggle: r("avatar.toggle", "Live avatar"),
26
- toggleHint: r("avatar.toggleHint", "Show the assistant as a speaking avatar during voice conversations."),
27
- stop: r("avatar.stop", "Turn off the avatar"),
28
- consent: r("avatar.consent", "Turning on Avatar shares the assistant's reply audio with LiveKit and Protoface to animate the avatar. This feature does not send your microphone audio to Protoface."),
29
- consentConfirm: r("avatar.consentConfirm", "Turn on the avatar"),
30
- consentCancel: r("avatar.consentCancel", "Not now"),
31
- stateOff: r("avatar.stateOff", "Avatar off"),
32
- stateOn: r("avatar.stateOn", "Avatar on"),
33
- stateStarting: r("avatar.stateStarting", "Starting the avatar…"),
34
- stateReady: r("avatar.stateReady", "Avatar ready"),
35
- stateEnding: r("avatar.stateEnding", "Stopping the avatar…"),
36
- stateInterrupted: r("avatar.stateInterrupted", "The avatar was interrupted. You can keep talking."),
37
- stateVoiceOnly: r("avatar.stateVoiceOnly", "The avatar is unavailable right now. Continuing with voice only."),
38
- stateTimeLimit: r("avatar.stateTimeLimit", "The avatar reached its time limit. Continuing with voice only."),
39
- stageLabel: r("avatar.stageLabel", "Live avatar"),
40
- stageWaiting: r("avatar.stageWaiting", "Waiting for the avatar…"),
41
- chooserTitle: r("avatar.chooserTitle", "Choose an avatar"),
42
- chooserLabel: r("avatar.chooserLabel", "Avatar"),
43
- chooserNone: r("avatar.chooserNone", "No avatar chosen"),
44
- chooserLoading: r("avatar.chooserLoading", "Loading avatars…"),
45
- chooserEmpty: r("avatar.chooserEmpty", "No avatars are available."),
46
- chooserRetry: r("avatar.chooserRetry", "Try again"),
47
- chooserOption: (e) => r("avatar.chooserOption", "Use {{name}}", { name: e }),
48
- chooserSelected: (e) => r("avatar.chooserSelected", "{{name}} (selected)", { name: e }),
49
- voiceModeLabel: r("avatar.voiceModeLabel", "Avatar voice"),
50
- voiceModeDefaultNamed: (e) => r("avatar.voiceModeDefaultNamed", "Default for this avatar ({{name}})", { name: e }),
51
- voiceModeMine: r("avatar.voiceModeMine", "Keep my current voice"),
52
- voiceModeMineNamed: (e) => r("avatar.voiceModeMineNamed", "Keep my current voice ({{name}})", { name: e }),
53
- voiceModeHint: r("avatar.voiceModeNextReplyHint", "Used from the avatar's next reply. The assistant's own voice doesn't change."),
54
- tabsLabel: r("avatar.tabsLabel", "Assistant views"),
55
- tabChat: r("avatar.tabChat", "Chat"),
56
- tabAvatar: r("avatar.tabAvatar", "Avatar"),
57
- chooserLocked: r("avatar.chooserLocked", "Turn off the avatar to change it."),
58
- tabLeaveHint: r("avatar.tabLeaveHint", "Leaving the Avatar tab turns the avatar off."),
59
- availableAgain: (e) => r("avatar.availableAgain", "You can start it again at {{time}}.", { time: e }),
60
- retryTime: (e, t) => a(e, t, i),
61
- stateTimeLimitNoVoice: r("avatar.stateTimeLimitNoVoice", "The avatar reached its time limit."),
62
- stateVoiceOnlyNoVoice: r("avatar.stateVoiceOnlyNoVoice", "The avatar is unavailable right now."),
63
- turnOnStarting: r("avatar.turnOnStarting", "Starting the avatar…"),
64
- startVoice: r("voiceSession.start", "Start a voice conversation"),
65
- hearVoice: r("voice.preview", "Hear this voice"),
23
+ function s() {
24
+ let i = t(), { locale: a } = e();
25
+ return r(() => ({
26
+ toggle: i("avatar.toggle", "Live avatar"),
27
+ toggleHint: i("avatar.toggleHint", "Show the assistant as a speaking avatar during voice conversations."),
28
+ stop: i("avatar.stop", "Turn off the avatar"),
29
+ consent: i("avatar.consent", "Turning on Avatar shares the assistant's reply audio with LiveKit and Protoface to animate the avatar. This feature does not send your microphone audio to Protoface."),
30
+ consentConfirm: i("avatar.consentConfirm", "Turn on the avatar"),
31
+ consentCancel: i("avatar.consentCancel", "Not now"),
32
+ stateOff: i("avatar.stateOff", "Avatar off"),
33
+ stateOn: i("avatar.stateOn", "Avatar on"),
34
+ stateStarting: i("avatar.stateStarting", "Starting the avatar…"),
35
+ stateReady: i("avatar.stateReady", "Avatar ready"),
36
+ stateEnding: i("avatar.stateEnding", "Stopping the avatar…"),
37
+ stateInterrupted: i("avatar.stateInterrupted", "The avatar was interrupted. You can keep talking."),
38
+ stateVoiceOnly: i("avatar.stateVoiceOnly", "The avatar is unavailable right now. Continuing with voice only."),
39
+ stateTimeLimit: i("avatar.stateTimeLimit", "The avatar reached its time limit. Continuing with voice only."),
40
+ stageLabel: i("avatar.stageLabel", "Live avatar"),
41
+ stageWaiting: i("avatar.stageWaiting", "Waiting for the avatar…"),
42
+ chooserTitle: i("avatar.chooserTitle", "Choose an avatar"),
43
+ chooserLabel: i("avatar.chooserLabel", "Avatar"),
44
+ chooserNone: i("avatar.chooserNone", "No avatar chosen"),
45
+ chooserLoading: i("avatar.chooserLoading", "Loading avatars…"),
46
+ chooserEmpty: i("avatar.chooserEmpty", "No avatars are available."),
47
+ chooserRetry: i("avatar.chooserRetry", "Try again"),
48
+ chooserOption: (e) => i("avatar.chooserOption", "Use {{name}}", { name: e }),
49
+ chooserSelected: (e) => i("avatar.chooserSelected", "{{name}} (selected)", { name: e }),
50
+ voiceModeLabel: i("avatar.voiceModeLabel", "Avatar voice"),
51
+ voiceModeDefaultNamed: (e) => i("avatar.voiceModeDefaultNamed", "Default for this avatar ({{name}})", { name: e }),
52
+ voiceModeMine: i("avatar.voiceModeMine", "Keep my current voice"),
53
+ voiceModeMineNamed: (e) => i("avatar.voiceModeMineNamed", "Keep my current voice ({{name}})", { name: e }),
54
+ voiceModeHint: i("avatar.voiceModeNextReplyHint", "Used from the avatar's next reply. The assistant's own voice doesn't change."),
55
+ tabsLabel: i("avatar.tabsLabel", "Assistant views"),
56
+ tabChat: i("avatar.tabChat", "Chat"),
57
+ tabAvatar: i("avatar.tabAvatar", "Avatar"),
58
+ chooserLocked: i("avatar.chooserLocked", "Turn off the avatar to change it."),
59
+ tabLeaveHint: i("avatar.tabLeaveHint", "Leaving the Avatar tab turns the avatar off."),
60
+ availableAgain: (e) => i("avatar.availableAgain", "You can start it again at {{time}}.", { time: e }),
61
+ retryTime: (e, t) => o(e, t, a),
62
+ stateTimeLimitNoVoice: i("avatar.stateTimeLimitNoVoice", "The avatar reached its time limit."),
63
+ stateVoiceOnlyNoVoice: i("avatar.stateVoiceOnlyNoVoice", "The avatar is unavailable right now."),
64
+ turnOnStarting: i("avatar.turnOnStarting", "Starting the avatar…"),
65
+ startVoice: i("voiceSession.start", "Start a voice conversation"),
66
+ hearVoice: i("voice.preview", "Hear this voice"),
66
67
  voiceStartBlocked: (e) => {
67
68
  switch (e) {
68
- case "unavailable": return r("avatar.voiceStartUnavailable", "Voice conversations aren’t available here.");
69
- case "mode": return r("avatar.voiceStartMode", "Voice conversations aren’t available in this mode.");
70
- case "read-only": return r("avatar.voiceStartReadOnly", "This conversation can’t take new questions. Start a new conversation to ask by voice.");
71
- case "busy": return r("avatar.voiceStartBusy", "You can start a voice conversation when the assistant is ready.");
72
- case "committing": return r("avatar.voiceStartCommitting", "You can start a voice conversation once your attachments are saved.");
73
- case "dictating": return r("avatar.voiceStartDictating", "Stop dictating to start a voice conversation.");
69
+ case "unavailable": return i("avatar.voiceStartUnavailable", "Voice conversations aren’t available here.");
70
+ case "mode": return i("avatar.voiceStartMode", "Voice conversations aren’t available in this mode.");
71
+ case "read-only": return i("avatar.voiceStartReadOnly", "This conversation can’t take new questions. Start a new conversation to ask by voice.");
72
+ case "busy": return i("avatar.voiceStartBusy", "You can start a voice conversation when the assistant is ready.");
73
+ case "committing": return i("avatar.voiceStartCommitting", "You can start a voice conversation once your attachments are saved.");
74
+ case "dictating": return i("avatar.voiceStartDictating", "Stop dictating to start a voice conversation.");
74
75
  }
75
76
  },
76
- askNeedsVoice: r("avatar.askNeedsVoice", "You can still turn the avatar on, but you ask it questions in a voice conversation."),
77
- handsFreeOff: r("avatar.handsFreeOff", "Hands-free interrupt is off, so the avatar's voice can't interrupt itself. It stays off after you turn the avatar off; turn it back on in More options. You can still tap to interrupt."),
77
+ askNeedsVoice: i("avatar.askNeedsVoice", "You can still turn the avatar on, but you ask it questions in a voice conversation."),
78
+ askByTyping: i("avatar.askByTyping", "You can still turn the avatar on and type your questions below."),
79
+ askNothing: i("avatar.askNothing", "You can't ask the avatar anything in this conversation."),
80
+ askLabel: i("avatar.askLabel", "Type a question for the avatar"),
81
+ askPlaceholder: i("avatar.askPlaceholder", "Ask the avatar…"),
82
+ askHint: i("avatar.askHint", "Enter to send · Shift+Enter for a new line"),
83
+ askSend: i("chatInput.send", "Send message"),
84
+ askBlocked: (e) => {
85
+ switch (e) {
86
+ case "hidden-voice": return null;
87
+ case "read-only": return i("avatar.askReadOnly", "This conversation can't take new questions. Start a new conversation to ask one.");
88
+ case "mode-picked": return i("avatar.askModePicked", "Typed questions work only in Ask. You can change that in Chat, but leaving this tab turns the avatar off.");
89
+ case "mode-escalated": return i("avatar.askMode", "This conversation can make changes, so typed questions to the avatar aren't available here. Start a new conversation to ask one.");
90
+ case "avatar-off": return i("avatar.askNeedsAvatar", "Turn on the avatar to send your question. You can type it now.");
91
+ case "avatar-again": return i("avatar.askAgain", "You can send your question when the avatar is on again.");
92
+ case "sound": return i("avatar.askSound", "Turn on the avatar's sound first.");
93
+ case "starting": return i("avatar.askStarting", "You can send your question when the avatar is ready.");
94
+ case "busy": return i("avatar.askBusy", "You can send your question when the assistant is ready.");
95
+ case "committing": return i("avatar.askCommitting", "You can send your question once the files in Chat are saved.");
96
+ }
97
+ },
98
+ askNoFiles: i("avatar.askNoFiles", "To attach files, use Chat."),
99
+ askEmpty: i("avatar.askEmpty", "Type a question below, and the avatar answers it aloud."),
100
+ askExchangeLabel: i("avatar.askExchangeLabel", "Last question and answer"),
101
+ askYouAsked: i("avatar.askYouAsked", "You asked"),
102
+ askAnswer: i("avatar.askAnswer", "Answer"),
103
+ askAskedIn: (e) => i("avatar.askAskedIn", "Asked in: {{title}}", { title: e }),
104
+ askShowAll: i("avatar.askShowAll", "Show the whole answer"),
105
+ askShowLess: i("avatar.askShowLess", "Show less"),
106
+ askThinking: i(n.key, n.fallback),
107
+ askNotSpoken: i("avatar.askNotSpoken", "The avatar wasn't available, so this answer wasn't read aloud."),
108
+ askCut: i("avatar.askCut", "The avatar stopped before the end of this answer. The whole answer is in Chat."),
109
+ askNotHeard: i("avatar.askNotHeard", "This answer wasn't read aloud: the avatar may still have been finishing the last answer."),
110
+ askFailed: i("avatar.askFailed", "The assistant couldn't answer. Your question is back in the box."),
111
+ askFailedInChat: i("avatar.askFailedInChat", "The assistant couldn't answer. Your question is still in Chat."),
112
+ askAlsoInChat: i("avatar.askAlsoInChat", "This answer is also in Chat."),
113
+ askStop: i("message.stopSpeaking", "Stop reading aloud"),
114
+ askStopShort: i("message.stopSpeakingShort", "Stop"),
115
+ handsFreeOff: i("avatar.handsFreeOff", "Hands-free interrupt is off, so the avatar's voice can't interrupt itself. It stays off after you turn the avatar off; turn it back on in More options. You can still tap to interrupt."),
78
116
  problem: (e, t = {}) => {
79
- let n = t.voiceLive !== !1, i = t.timed === !0;
117
+ let n = t.voiceLive !== !1, r = t.timed === !0;
80
118
  switch (e) {
81
- case "unavailable": return r("avatar.problemUnavailable", "The avatar isn’t available here.");
82
- case "not-ready": return r("avatar.problemNotReady", "This avatar isn’t ready yet. Try another one.");
83
- case "already-running": return r("avatar.problemAlreadyRunning", "An avatar is already running for you.");
84
- case "capacity": return i ? r("avatar.problemCapacityTimed", "Avatars are busy right now.") : r("avatar.problemCapacity", "Avatars are busy right now. Try again in a moment.");
85
- case "rate-limited": return i ? r("avatar.problemRateLimitedTimed", "You started avatars too quickly.") : r("avatar.problemRateLimited", "You started avatars too quickly. Wait a minute and try again.");
86
- case "paused": return r("avatar.problemPaused", "Avatars are paused for now.");
87
- case "budget-exhausted": return r("avatar.problemBudgetExhausted", "Avatar time is used up for now.");
88
- case "start-timeout": return r("avatar.problemStartTimeout", "The avatar took too long to start. Try again in a moment.");
89
- case "provider": return n ? r("avatar.problemProvider", "The avatar had a problem. Voice continues without it.") : r("avatar.problemProviderNoVoice", "The avatar had a problem.");
90
- case "connection": return r("avatar.problemConnection", "The connection to the avatar was lost.");
91
- case "needs-hosted-voice": return r("avatar.problemNeedsHostedVoice", "The avatar needs one of the assistant’s own voices. Choose one in the voice settings.");
92
- case "unsupported-browser": return r("avatar.problemUnsupportedBrowser", "This browser can’t show the avatar.");
93
- case "playback-blocked": return r("avatar.problemPlaybackBlocked", "The browser blocked the avatar’s sound. Tap the avatar to turn it on.");
119
+ case "unavailable": return i("avatar.problemUnavailable", "The avatar isn’t available here.");
120
+ case "not-ready": return i("avatar.problemNotReady", "This avatar isn’t ready yet. Try another one.");
121
+ case "already-running": return i("avatar.problemAlreadyRunning", "An avatar is already running for you.");
122
+ case "capacity": return r ? i("avatar.problemCapacityTimed", "Avatars are busy right now.") : i("avatar.problemCapacity", "Avatars are busy right now. Try again in a moment.");
123
+ case "rate-limited": return r ? i("avatar.problemRateLimitedTimed", "You started avatars too quickly.") : i("avatar.problemRateLimited", "You started avatars too quickly. Wait a minute and try again.");
124
+ case "paused": return i("avatar.problemPaused", "Avatars are paused for now.");
125
+ case "budget-exhausted": return i("avatar.problemBudgetExhausted", "Avatar time is used up for now.");
126
+ case "start-timeout": return i("avatar.problemStartTimeout", "The avatar took too long to start. Try again in a moment.");
127
+ case "provider": return n ? i("avatar.problemProvider", "The avatar had a problem. Voice continues without it.") : i("avatar.problemProviderNoVoice", "The avatar had a problem.");
128
+ case "connection": return i("avatar.problemConnection", "The connection to the avatar was lost.");
129
+ case "needs-hosted-voice": return i("avatar.problemNeedsHostedVoice", "The avatar needs one of the assistant’s own voices. Choose one in the voice settings.");
130
+ case "unsupported-browser": return i("avatar.problemUnsupportedBrowser", "This browser can’t show the avatar.");
131
+ case "playback-blocked": return i("avatar.problemPlaybackBlocked", "The browser blocked the avatar’s sound. Tap the avatar to turn it on.");
94
132
  }
95
133
  }
96
- }), [r, i]);
134
+ }), [i, a]);
97
135
  }
98
136
  //#endregion
99
- export { a as formatAvatarRetryTime, o as useAvatarCopy };
137
+ export { o as formatAvatarRetryTime, s as useAvatarCopy };
@@ -216,7 +216,35 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
216
216
  readonly "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.";
217
217
  readonly "attachments.uploading": "Uploading…";
218
218
  readonly "attachments.voiceDropped": "{{count}} attachment(s) couldn't be saved and weren't sent.";
219
+ readonly "avatar.askAgain": "You can send your question when the avatar is on again.";
220
+ readonly "avatar.askAlsoInChat": "This answer is also in Chat.";
221
+ readonly "avatar.askAnswer": "Answer";
222
+ readonly "avatar.askAskedIn": "Asked in: {{title}}";
223
+ readonly "avatar.askBusy": "You can send your question when the assistant is ready.";
224
+ readonly "avatar.askByTyping": "You can still turn the avatar on and type your questions below.";
225
+ readonly "avatar.askCommitting": "You can send your question once the files in Chat are saved.";
226
+ readonly "avatar.askCut": "The avatar stopped before the end of this answer. The whole answer is in Chat.";
227
+ readonly "avatar.askEmpty": "Type a question below, and the avatar answers it aloud.";
228
+ readonly "avatar.askExchangeLabel": "Last question and answer";
229
+ readonly "avatar.askFailed": "The assistant couldn't answer. Your question is back in the box.";
230
+ readonly "avatar.askFailedInChat": "The assistant couldn't answer. Your question is still in Chat.";
231
+ readonly "avatar.askHint": "Enter to send · Shift+Enter for a new line";
232
+ readonly "avatar.askLabel": "Type a question for the avatar";
233
+ readonly "avatar.askMode": "This conversation can make changes, so typed questions to the avatar aren't available here. Start a new conversation to ask one.";
234
+ readonly "avatar.askModePicked": "Typed questions work only in Ask. You can change that in Chat, but leaving this tab turns the avatar off.";
235
+ readonly "avatar.askNeedsAvatar": "Turn on the avatar to send your question. You can type it now.";
219
236
  readonly "avatar.askNeedsVoice": "You can still turn the avatar on, but you ask it questions in a voice conversation.";
237
+ readonly "avatar.askNoFiles": "To attach files, use Chat.";
238
+ readonly "avatar.askNotHeard": "This answer wasn't read aloud: the avatar may still have been finishing the last answer.";
239
+ readonly "avatar.askNotSpoken": "The avatar wasn't available, so this answer wasn't read aloud.";
240
+ readonly "avatar.askNothing": "You can't ask the avatar anything in this conversation.";
241
+ readonly "avatar.askPlaceholder": "Ask the avatar…";
242
+ readonly "avatar.askReadOnly": "This conversation can't take new questions. Start a new conversation to ask one.";
243
+ readonly "avatar.askShowAll": "Show the whole answer";
244
+ readonly "avatar.askShowLess": "Show less";
245
+ readonly "avatar.askSound": "Turn on the avatar's sound first.";
246
+ readonly "avatar.askStarting": "You can send your question when the avatar is ready.";
247
+ readonly "avatar.askYouAsked": "You asked";
220
248
  readonly "avatar.availableAgain": "You can start it again at {{time}}.";
221
249
  readonly "avatar.chooserEmpty": "No avatars are available.";
222
250
  readonly "avatar.chooserLabel": "Avatar";
@@ -471,6 +499,7 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
471
499
  readonly "sheet.collapse": "Shrink the assistant";
472
500
  readonly "sheet.expand": "Expand the assistant";
473
501
  readonly "speech.codeBlock": "Code block";
502
+ readonly "speech.deviceFallback": "Device voice used: the selected voice was unavailable.";
474
503
  readonly "speech.emailAt": "at";
475
504
  readonly "speech.emailDot": "dot";
476
505
  readonly "speech.image": "image";
@@ -110,7 +110,35 @@ var m = {
110
110
  "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.",
111
111
  "attachments.uploading": "Uploading…",
112
112
  "attachments.voiceDropped": "{{count}} attachment(s) couldn't be saved and weren't sent.",
113
+ "avatar.askAgain": "You can send your question when the avatar is on again.",
114
+ "avatar.askAlsoInChat": "This answer is also in Chat.",
115
+ "avatar.askAnswer": "Answer",
116
+ "avatar.askAskedIn": "Asked in: {{title}}",
117
+ "avatar.askBusy": "You can send your question when the assistant is ready.",
118
+ "avatar.askByTyping": "You can still turn the avatar on and type your questions below.",
119
+ "avatar.askCommitting": "You can send your question once the files in Chat are saved.",
120
+ "avatar.askCut": "The avatar stopped before the end of this answer. The whole answer is in Chat.",
121
+ "avatar.askEmpty": "Type a question below, and the avatar answers it aloud.",
122
+ "avatar.askExchangeLabel": "Last question and answer",
123
+ "avatar.askFailed": "The assistant couldn't answer. Your question is back in the box.",
124
+ "avatar.askFailedInChat": "The assistant couldn't answer. Your question is still in Chat.",
125
+ "avatar.askHint": "Enter to send · Shift+Enter for a new line",
126
+ "avatar.askLabel": "Type a question for the avatar",
127
+ "avatar.askMode": "This conversation can make changes, so typed questions to the avatar aren't available here. Start a new conversation to ask one.",
128
+ "avatar.askModePicked": "Typed questions work only in Ask. You can change that in Chat, but leaving this tab turns the avatar off.",
129
+ "avatar.askNeedsAvatar": "Turn on the avatar to send your question. You can type it now.",
113
130
  "avatar.askNeedsVoice": "You can still turn the avatar on, but you ask it questions in a voice conversation.",
131
+ "avatar.askNoFiles": "To attach files, use Chat.",
132
+ "avatar.askNotHeard": "This answer wasn't read aloud: the avatar may still have been finishing the last answer.",
133
+ "avatar.askNotSpoken": "The avatar wasn't available, so this answer wasn't read aloud.",
134
+ "avatar.askNothing": "You can't ask the avatar anything in this conversation.",
135
+ "avatar.askPlaceholder": "Ask the avatar…",
136
+ "avatar.askReadOnly": "This conversation can't take new questions. Start a new conversation to ask one.",
137
+ "avatar.askShowAll": "Show the whole answer",
138
+ "avatar.askShowLess": "Show less",
139
+ "avatar.askSound": "Turn on the avatar's sound first.",
140
+ "avatar.askStarting": "You can send your question when the avatar is ready.",
141
+ "avatar.askYouAsked": "You asked",
114
142
  "avatar.availableAgain": "You can start it again at {{time}}.",
115
143
  "avatar.chooserEmpty": "No avatars are available.",
116
144
  "avatar.chooserLabel": "Avatar",
@@ -365,6 +393,7 @@ var m = {
365
393
  "sheet.collapse": "Shrink the assistant",
366
394
  "sheet.expand": "Expand the assistant",
367
395
  "speech.codeBlock": "Code block",
396
+ "speech.deviceFallback": "Device voice used: the selected voice was unavailable.",
368
397
  "speech.emailAt": "at",
369
398
  "speech.emailDot": "dot",
370
399
  "speech.image": "image",
@@ -46,6 +46,7 @@ export * from './speech/routingSpeechEngine';
46
46
  export * from './speech/hostedVoiceCatalogue';
47
47
  export * from './speech/pieceSink';
48
48
  export * from './speech/speechFeed';
49
+ export * from './speech/replySpeechRequests';
49
50
  export * from './voice/useVoiceInput';
50
51
  export * from './voice/voiceStageState';
51
52
  export * from './voice/voiceStatus';
@@ -227,6 +228,11 @@ export * from './ui/assistantLiveAvatarSeam';
227
228
  export * from './ui/AssistantAvatarTabs';
228
229
  export * from './ui/avatar/AssistantAvatarTab';
229
230
  export * from './ui/voice/voiceStartGate';
231
+ export * from './ui/avatar/avatarAskGate';
232
+ export * from './ui/avatar/AvatarTabAskBox';
233
+ export * from './ui/avatar/AvatarTabLastExchange';
234
+ export * from './ui/avatar/avatarTabExchange';
235
+ export * from './ui/avatar/avatarTabDraft';
230
236
  export * from './useAssistantApiAccess';
231
237
  export * from './useConversationTurns';
232
238
  export * from './transportErrors';
@@ -334,6 +340,8 @@ export * from './avatar/live/liveAvatarController';
334
340
  export * from './avatar/live/liveKitAvatarRoom';
335
341
  export * from './avatar/live/LiveAvatarStage';
336
342
  export * from './avatar/live/LiveAvatarTabView';
343
+ export * from './avatar/live/avatarFaces';
344
+ export * from './avatar/live/AvatarFace';
337
345
  export * from './avatar/live/liveAvatarStatus';
338
346
  export * from './avatar/live/createLiveAvatarSeam';
339
347
  export * from './avatar/live/avatarVoice';
@@ -60,4 +60,10 @@ export declare const HOSTED_OUTPUT_STALL_AUDIO_RATIO = 2;
60
60
  export declare const HOSTED_OUTPUT_MIN_AUDIO_BYTES_PER_SECOND = 1000;
61
61
  /** The watchdog's window once `bytesHanded` bytes of audio went to the output. */
62
62
  export declare function hostedOutputStallMs(bytesHanded: number): number;
63
+ /** 44 bytes of silence: what a tap plays to unlock an engine's element. */
64
+ export declare const SILENT_WAV_DATA_URI = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
65
+ /** Unlock every hosted engine's playback element. Call inside a user gesture. */
66
+ export declare function primeHostedPlayback(): void;
67
+ /** Test seam: forget every engine registered so far. */
68
+ export declare function resetHostedPlaybackForTest(): void;
63
69
  export declare function createHostedTtsEngine(options: HostedTtsOptions): HostedSpeechEngine;