@flowingspring/dsh-voco 0.2.3 → 0.2.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.
- package/LICENSE +21 -21
- package/README.md +56 -56
- package/README.zh.md +56 -56
- package/cordis.patch.yml +13 -13
- package/lib/client.js +127 -72
- package/lib/client.js.map +1 -1
- package/package.json +114 -114
package/lib/client.js
CHANGED
|
@@ -7,8 +7,8 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
8
|
let react = require("react");
|
|
9
9
|
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
10
|
-
//#region \0dsh-css:
|
|
11
|
-
const css$3 = ".
|
|
10
|
+
//#region \0dsh-css:C:\Users\QUAN\AppData\Local\Temp\dsh-voco-release-0.2.5\packages\ui-voice\src\client\VoiceControl.module.css.mjs
|
|
11
|
+
const css$3 = ".Hv0BZG_button{width:28px;height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:8px;justify-content:center;align-items:center;padding:0;display:inline-flex}.Hv0BZG_button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.Hv0BZG_active{color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover-solid)}.Hv0BZG_button[data-muted=true]{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, currentColor 12%, transparent)}.Hv0BZG_button[data-muted=true]:hover{background:color-mix(in srgb, currentColor 18%, transparent)}.Hv0BZG_button[data-state=speaking][data-muted=false]{animation:1.2s ease-in-out infinite Hv0BZG_voice-pulse}@keyframes Hv0BZG_voice-pulse{50%{opacity:.55;transform:scale(.94)}}@media (prefers-reduced-motion:reduce){.Hv0BZG_button[data-state=speaking][data-muted=false]{animation:none}}";
|
|
12
12
|
const tagId$3 = "@flowingspring/dsh-voco/VoiceControl.module.css";
|
|
13
13
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
14
14
|
const tag = document.createElement("style");
|
|
@@ -18,16 +18,17 @@ window.__ModuleLoader__.load({
|
|
|
18
18
|
document.head.appendChild(tag);
|
|
19
19
|
}
|
|
20
20
|
var VoiceControl_module_css_default = {
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
21
|
+
"button": "Hv0BZG_button",
|
|
22
|
+
"voice-pulse": "Hv0BZG_voice-pulse",
|
|
23
|
+
"active": "Hv0BZG_active"
|
|
24
24
|
};
|
|
25
25
|
//#endregion
|
|
26
26
|
//#region ../ui-voice/src/client/VoiceControl.tsx
|
|
27
27
|
/** Start a fresh Voice Session from this Session's location or control the active connection. */
|
|
28
|
-
function VoiceControl({ sessionId, useVoice, startVoice, retryVoice,
|
|
28
|
+
function VoiceControl({ sessionId, useVoice, startVoice, retryVoice, setVoiceMuted, t }) {
|
|
29
29
|
const state = useVoice((snapshot) => snapshot.state);
|
|
30
30
|
const activeSessionId = useVoice((snapshot) => snapshot.sessionId);
|
|
31
|
+
const inputMuted = useVoice((snapshot) => snapshot.inputMuted);
|
|
31
32
|
const toggle = async () => {
|
|
32
33
|
if (state === "error" && activeSessionId !== void 0) {
|
|
33
34
|
try {
|
|
@@ -36,20 +37,23 @@ window.__ModuleLoader__.load({
|
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
39
|
if (state !== "off" && state !== "error") {
|
|
39
|
-
|
|
40
|
+
setVoiceMuted(!inputMuted);
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
43
|
try {
|
|
43
44
|
await startVoice(sessionId);
|
|
44
45
|
} catch {}
|
|
45
46
|
};
|
|
46
|
-
const label = state === "off" ? t("control.start") : state === "error" ? t("control.retry") : t("control.
|
|
47
|
+
const label = state === "off" ? t("control.start") : state === "error" ? t("control.retry") : inputMuted ? t("control.unmute") : t("control.mute");
|
|
48
|
+
const active = state !== "off" && state !== "error";
|
|
47
49
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
48
50
|
type: "button",
|
|
49
|
-
className: `${VoiceControl_module_css_default.button} ${
|
|
51
|
+
className: `${VoiceControl_module_css_default.button} ${active ? VoiceControl_module_css_default.active : ""}`,
|
|
50
52
|
"aria-label": label,
|
|
53
|
+
"aria-pressed": active ? inputMuted : void 0,
|
|
51
54
|
title: label,
|
|
52
55
|
"data-state": state,
|
|
56
|
+
"data-muted": inputMuted,
|
|
53
57
|
onClick: () => {
|
|
54
58
|
toggle();
|
|
55
59
|
},
|
|
@@ -58,28 +62,38 @@ window.__ModuleLoader__.load({
|
|
|
58
62
|
width: "16",
|
|
59
63
|
height: "16",
|
|
60
64
|
"aria-hidden": true,
|
|
61
|
-
children: [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("rect", {
|
|
67
|
+
x: "5",
|
|
68
|
+
y: "2",
|
|
69
|
+
width: "6",
|
|
70
|
+
height: "8",
|
|
71
|
+
rx: "3",
|
|
72
|
+
fill: "none",
|
|
73
|
+
stroke: "currentColor",
|
|
74
|
+
strokeWidth: "1.4"
|
|
75
|
+
}),
|
|
76
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
77
|
+
d: "M3.5 7.5a4.5 4.5 0 0 0 9 0M8 12v2M5.5 14h5",
|
|
78
|
+
fill: "none",
|
|
79
|
+
stroke: "currentColor",
|
|
80
|
+
strokeWidth: "1.4",
|
|
81
|
+
strokeLinecap: "round"
|
|
82
|
+
}),
|
|
83
|
+
inputMuted && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
84
|
+
d: "M2.5 2.5l11 11",
|
|
85
|
+
fill: "none",
|
|
86
|
+
stroke: "currentColor",
|
|
87
|
+
strokeWidth: "1.8",
|
|
88
|
+
strokeLinecap: "round"
|
|
89
|
+
})
|
|
90
|
+
]
|
|
77
91
|
})
|
|
78
92
|
});
|
|
79
93
|
}
|
|
80
94
|
//#endregion
|
|
81
|
-
//#region \0dsh-css:
|
|
82
|
-
const css$2 = ".
|
|
95
|
+
//#region \0dsh-css:C:\Users\QUAN\AppData\Local\Temp\dsh-voco-release-0.2.5\packages\ui-voice\src\client\VoiceHistoryAction.module.css.mjs
|
|
96
|
+
const css$2 = "._6KMZha_trigger{width:100%;min-height:36px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:8px;justify-content:center;align-items:center;gap:9px;display:flex}._6KMZha_trigger:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._6KMZha_panel{z-index:60;border:1px solid var(--dsw-alias-border-l2);width:min(320px,100vw - 32px);max-height:min(480px,100vh - 96px);color:var(--dsw-alias-label-primary);background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv3);border-radius:14px;flex-direction:column;display:flex;position:fixed;bottom:64px;left:16px;overflow:hidden}._6KMZha_header{border-bottom:1px solid var(--dsw-alias-border-l2);justify-content:space-between;align-items:center;min-height:48px;padding:0 12px 0 16px;display:flex}._6KMZha_close{width:28px;height:28px;color:inherit;cursor:pointer;background:0 0;border:0;border-radius:7px;font-size:20px;line-height:1}._6KMZha_close:hover{background:var(--dsw-alias-interactive-bg-hover)}._6KMZha_list{padding:8px;overflow:auto}._6KMZha_empty{color:var(--dsw-alias-label-tertiary);text-align:center;margin:0;padding:24px 12px;font-size:13px}._6KMZha_row{width:100%;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:9px;align-items:center;gap:10px;padding:10px;display:flex}._6KMZha_row:hover,._6KMZha_row[data-active=true]{background:var(--dsw-alias-interactive-bg-hover)}._6KMZha_wave{width:24px;height:24px;color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb, currentColor 10%, transparent);border-radius:50%;flex:none;justify-content:center;align-items:center;gap:2px;display:flex}._6KMZha_wave i{background:currentColor;border-radius:2px;width:2px}._6KMZha_wave i:first-child{height:6px}._6KMZha_wave i:nth-child(2){height:11px}._6KMZha_wave i:nth-child(3){height:8px}._6KMZha_rowText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}._6KMZha_title{text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;overflow:hidden}._6KMZha_meta{color:var(--dsw-alias-label-tertiary);font-size:11px}";
|
|
83
97
|
const tagId$2 = "@flowingspring/dsh-voco/VoiceHistoryAction.module.css";
|
|
84
98
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
85
99
|
const tag = document.createElement("style");
|
|
@@ -89,17 +103,17 @@ window.__ModuleLoader__.load({
|
|
|
89
103
|
document.head.appendChild(tag);
|
|
90
104
|
}
|
|
91
105
|
var VoiceHistoryAction_module_css_default = {
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
106
|
+
"close": "_6KMZha_close",
|
|
107
|
+
"list": "_6KMZha_list",
|
|
108
|
+
"panel": "_6KMZha_panel",
|
|
109
|
+
"title": "_6KMZha_title",
|
|
110
|
+
"trigger": "_6KMZha_trigger",
|
|
111
|
+
"empty": "_6KMZha_empty",
|
|
112
|
+
"row": "_6KMZha_row",
|
|
113
|
+
"header": "_6KMZha_header",
|
|
114
|
+
"wave": "_6KMZha_wave",
|
|
115
|
+
"meta": "_6KMZha_meta",
|
|
116
|
+
"rowText": "_6KMZha_rowText"
|
|
103
117
|
};
|
|
104
118
|
//#endregion
|
|
105
119
|
//#region ../ui-voice/src/client/VoiceHistoryAction.tsx
|
|
@@ -200,8 +214,8 @@ window.__ModuleLoader__.load({
|
|
|
200
214
|
})] });
|
|
201
215
|
}
|
|
202
216
|
//#endregion
|
|
203
|
-
//#region \0dsh-css:
|
|
204
|
-
const css$1 = ".
|
|
217
|
+
//#region \0dsh-css:C:\Users\QUAN\AppData\Local\Temp\dsh-voco-release-0.2.5\packages\ui-voice\src\client\VoiceNodeViews.module.css.mjs
|
|
218
|
+
const css$1 = ".xadqOW_utterance{flex-direction:column;align-items:flex-start;gap:6px;min-width:0;display:flex}.xadqOW_utterance[data-role=user]{align-items:flex-end}.xadqOW_bubble{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-1);max-width:min(525px,82%);color:var(--dsw-alias-label-primary);overflow-wrap:anywhere;white-space:pre-wrap;border-radius:18px;padding:10px 16px;font-size:16px;line-height:24px}.xadqOW_utterance[data-role=user] .xadqOW_bubble{background:var(--dsw-specific-bubble);border-color:#0000}.xadqOW_utterance[data-state=streaming] .xadqOW_bubble{color:var(--dsw-alias-label-secondary)}.xadqOW_meta,.xadqOW_voiceBadge{align-items:center;display:inline-flex}.xadqOW_meta{color:var(--dsw-alias-label-tertiary);gap:8px;padding:0 5px;font-size:10px;line-height:14px}.xadqOW_voiceBadge{color:var(--dsw-alias-state-business-primary);letter-spacing:.04em;gap:4px;font-weight:600}.xadqOW_miniWave{align-items:center;gap:1px;height:10px;display:inline-flex}.xadqOW_miniWave i{background:currentColor;border-radius:1px;width:1.5px;height:4px}.xadqOW_miniWave i:nth-child(2){height:8px}.xadqOW_miniWave i:nth-child(3){height:6px}.xadqOW_taskCard{box-sizing:border-box;width:fit-content;min-width:0;max-width:min(525px,100%)}.xadqOW_taskSummary{min-width:0;max-width:100%;color:inherit;cursor:pointer;font:inherit;background:0 0;border:0;border-radius:6px;align-items:center;gap:7px;margin:-3px -5px;padding:3px 5px;display:inline-flex}.xadqOW_taskSummary:hover{background:var(--dsw-alias-bg-layer-1)}.xadqOW_taskDot{background:var(--dsw-alias-state-business-primary);border-radius:50%;flex:none;width:7px;height:7px}.xadqOW_taskCard[data-status=completed] .xadqOW_taskDot{background:var(--dsw-alias-state-success-primary)}.xadqOW_taskCard[data-status=failed] .xadqOW_taskDot{background:var(--dsw-alias-state-error-primary)}.xadqOW_taskCard[data-status=cancelled] .xadqOW_taskDot,.xadqOW_taskCard[data-status=interrupted] .xadqOW_taskDot{background:var(--dsw-alias-state-warn-primary)}.xadqOW_taskTitle{min-width:0;color:var(--dsw-alias-label-secondary);text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:600;line-height:20px;overflow:hidden}.xadqOW_taskStatus{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;line-height:16px}.xadqOW_taskStatus:before{content:\"·\";margin-right:7px}.xadqOW_taskChevron{border-right:1px solid var(--dsw-alias-label-tertiary);border-bottom:1px solid var(--dsw-alias-label-tertiary);width:6px;height:6px;margin:0 2px 0 1px;transition:transform .12s;transform:rotate(-45deg)}.xadqOW_taskCard[data-expanded=true] .xadqOW_taskChevron{transform:rotate(45deg)}.xadqOW_taskInput,.xadqOW_taskUpdate{overflow-wrap:anywhere;margin:0;font-size:13px;line-height:20px}.xadqOW_taskInput{color:var(--dsw-alias-label-primary)}.xadqOW_taskUpdate{color:var(--dsw-alias-label-secondary);margin-top:4px}.xadqOW_taskDetails{border-left:1px solid var(--dsw-alias-border-l2);margin:9px 0 0 3px;padding:2px 0 2px 16px}.xadqOW_taskActions{align-items:center;gap:14px;margin-top:7px;display:flex}.xadqOW_taskLink{color:var(--dsw-alias-state-business-primary);cursor:pointer;font:inherit;background:0 0;border:0;padding:0;font-size:12px;line-height:18px}.xadqOW_taskLink:hover:not(:disabled){text-underline-position:from-font;text-decoration:underline}.xadqOW_taskLink:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.xadqOW_taskCancel{color:var(--dsw-alias-state-error-primary)}";
|
|
205
219
|
const tagId$1 = "@flowingspring/dsh-voco/VoiceNodeViews.module.css";
|
|
206
220
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
207
221
|
const tag = document.createElement("style");
|
|
@@ -211,23 +225,23 @@ window.__ModuleLoader__.load({
|
|
|
211
225
|
document.head.appendChild(tag);
|
|
212
226
|
}
|
|
213
227
|
var VoiceNodeViews_module_css_default = {
|
|
214
|
-
"
|
|
215
|
-
"
|
|
216
|
-
"
|
|
217
|
-
"
|
|
218
|
-
"
|
|
219
|
-
"
|
|
220
|
-
"taskActions": "
|
|
221
|
-
"
|
|
222
|
-
"taskInput": "
|
|
223
|
-
"
|
|
224
|
-
"taskDot": "
|
|
225
|
-
"
|
|
226
|
-
"
|
|
227
|
-
"
|
|
228
|
-
"
|
|
229
|
-
"
|
|
230
|
-
"
|
|
228
|
+
"miniWave": "xadqOW_miniWave",
|
|
229
|
+
"taskChevron": "xadqOW_taskChevron",
|
|
230
|
+
"utterance": "xadqOW_utterance",
|
|
231
|
+
"taskUpdate": "xadqOW_taskUpdate",
|
|
232
|
+
"taskCard": "xadqOW_taskCard",
|
|
233
|
+
"taskStatus": "xadqOW_taskStatus",
|
|
234
|
+
"taskActions": "xadqOW_taskActions",
|
|
235
|
+
"taskDetails": "xadqOW_taskDetails",
|
|
236
|
+
"taskInput": "xadqOW_taskInput",
|
|
237
|
+
"voiceBadge": "xadqOW_voiceBadge",
|
|
238
|
+
"taskDot": "xadqOW_taskDot",
|
|
239
|
+
"taskCancel": "xadqOW_taskCancel",
|
|
240
|
+
"meta": "xadqOW_meta",
|
|
241
|
+
"taskSummary": "xadqOW_taskSummary",
|
|
242
|
+
"taskTitle": "xadqOW_taskTitle",
|
|
243
|
+
"taskLink": "xadqOW_taskLink",
|
|
244
|
+
"bubble": "xadqOW_bubble"
|
|
231
245
|
};
|
|
232
246
|
//#endregion
|
|
233
247
|
//#region ../ui-voice/src/client/VoiceNodeViews.tsx
|
|
@@ -344,8 +358,8 @@ window.__ModuleLoader__.load({
|
|
|
344
358
|
return status === "completed" || status === "failed" || status === "cancelled" || status === "interrupted";
|
|
345
359
|
}
|
|
346
360
|
//#endregion
|
|
347
|
-
//#region \0dsh-css:
|
|
348
|
-
const css = ".
|
|
361
|
+
//#region \0dsh-css:C:\Users\QUAN\AppData\Local\Temp\dsh-voco-release-0.2.5\packages\ui-voice\src\client\VoiceOverlay.module.css.mjs
|
|
362
|
+
const css = ".uzdD-G_root{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-overlay);width:366px;max-width:min(520px,100vw - 36px);min-height:36px;box-shadow:var(--dsw-shadow-lv2);color:var(--dsw-alias-label-primary);pointer-events:auto;border-radius:12px;align-items:center;gap:10px;padding:4px 6px 4px 12px;font-size:12px;line-height:18px;display:flex;position:absolute;bottom:18px;right:18px}.uzdD-G_wave{width:18px;height:18px;color:var(--dsw-alias-state-business-primary);flex:none;justify-content:center;align-items:center;gap:2px;display:inline-flex}.uzdD-G_wave i{background:currentColor;border-radius:1px;width:2px;height:5px;animation:.9s ease-in-out infinite alternate uzdD-G_voice-wave}.uzdD-G_wave i:nth-child(2){height:11px;animation-delay:-300ms}.uzdD-G_wave i:nth-child(3){height:8px;animation-delay:-600ms}.uzdD-G_wave i:nth-child(4){height:4px;animation-delay:-150ms}.uzdD-G_root[data-state=connecting] .uzdD-G_wave,.uzdD-G_root[data-state=error] .uzdD-G_wave{opacity:.55}.uzdD-G_root[data-state=error] .uzdD-G_wave{color:var(--dsw-alias-state-error-primary)}.uzdD-G_status{text-overflow:ellipsis;white-space:nowrap;flex:auto;min-width:0;overflow:hidden}.uzdD-G_muted{width:3em;color:var(--dsw-alias-state-error-primary);text-align:center;white-space:nowrap;flex:none;font-weight:600}.uzdD-G_muted[data-visible=false]{visibility:hidden}.uzdD-G_root[data-muted=true] .uzdD-G_wave{color:var(--dsw-alias-state-error-primary);opacity:.65}.uzdD-G_root[data-muted=true] .uzdD-G_wave i{animation:none}.uzdD-G_link,.uzdD-G_stop{min-height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;font:inherit;background:0 0;border:0;border-radius:7px;flex:none;padding:0 8px}.uzdD-G_link:hover:not(:disabled),.uzdD-G_stop:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.uzdD-G_link:disabled{cursor:default;opacity:.45}.uzdD-G_stop{color:var(--dsw-alias-state-error-primary)}@keyframes uzdD-G_voice-wave{to{transform:scaleY(.55)}}@media (prefers-reduced-motion:reduce){.uzdD-G_wave i{animation:none}}";
|
|
349
363
|
const tagId = "@flowingspring/dsh-voco/VoiceOverlay.module.css";
|
|
350
364
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
351
365
|
const tag = document.createElement("style");
|
|
@@ -355,12 +369,13 @@ window.__ModuleLoader__.load({
|
|
|
355
369
|
document.head.appendChild(tag);
|
|
356
370
|
}
|
|
357
371
|
var VoiceOverlay_module_css_default = {
|
|
358
|
-
"
|
|
359
|
-
"status": "
|
|
360
|
-
"root": "
|
|
361
|
-
"
|
|
362
|
-
"
|
|
363
|
-
"wave": "
|
|
372
|
+
"stop": "uzdD-G_stop",
|
|
373
|
+
"status": "uzdD-G_status",
|
|
374
|
+
"root": "uzdD-G_root",
|
|
375
|
+
"wave": "uzdD-G_wave",
|
|
376
|
+
"muted": "uzdD-G_muted",
|
|
377
|
+
"voice-wave": "uzdD-G_voice-wave",
|
|
378
|
+
"link": "uzdD-G_link"
|
|
364
379
|
};
|
|
365
380
|
//#endregion
|
|
366
381
|
//#region ../ui-voice/src/client/VoiceOverlay.tsx
|
|
@@ -379,6 +394,7 @@ window.__ModuleLoader__.load({
|
|
|
379
394
|
className: VoiceOverlay_module_css_default.root,
|
|
380
395
|
"data-voice-overlay": true,
|
|
381
396
|
"data-state": voice.state,
|
|
397
|
+
"data-muted": voice.inputMuted,
|
|
382
398
|
"aria-live": "polite",
|
|
383
399
|
children: [
|
|
384
400
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
@@ -395,6 +411,12 @@ window.__ModuleLoader__.load({
|
|
|
395
411
|
className: VoiceOverlay_module_css_default.status,
|
|
396
412
|
children: t(STATE_KEYS[voice.state])
|
|
397
413
|
}),
|
|
414
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
415
|
+
className: VoiceOverlay_module_css_default.muted,
|
|
416
|
+
"data-visible": voice.inputMuted && voice.state !== "error",
|
|
417
|
+
"aria-hidden": !(voice.inputMuted && voice.state !== "error"),
|
|
418
|
+
children: t("overlay.muted")
|
|
419
|
+
}),
|
|
398
420
|
voice.sessionId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
399
421
|
type: "button",
|
|
400
422
|
className: VoiceOverlay_module_css_default.link,
|
|
@@ -419,6 +441,7 @@ window.__ModuleLoader__.load({
|
|
|
419
441
|
//#region ../ui-voice/src/client/voice-controller.ts
|
|
420
442
|
const INITIAL_SNAPSHOT = {
|
|
421
443
|
state: "off",
|
|
444
|
+
inputMuted: false,
|
|
422
445
|
textById: {}
|
|
423
446
|
};
|
|
424
447
|
/** Own the single browser microphone, provider WebSocket, playback queue, and live transcript feed. */
|
|
@@ -450,6 +473,9 @@ window.__ModuleLoader__.load({
|
|
|
450
473
|
* @param sessionId - durable voice session to connect.
|
|
451
474
|
*/
|
|
452
475
|
async start(sessionId) {
|
|
476
|
+
await this.open(sessionId, false);
|
|
477
|
+
}
|
|
478
|
+
async open(sessionId, inputMuted) {
|
|
453
479
|
const generation = ++this.generation;
|
|
454
480
|
this.pendingText.splice(0);
|
|
455
481
|
this.conversationStarted = false;
|
|
@@ -463,6 +489,7 @@ window.__ModuleLoader__.load({
|
|
|
463
489
|
this.openingAbort = openingAbort;
|
|
464
490
|
this.publish({
|
|
465
491
|
state: "connecting",
|
|
492
|
+
inputMuted,
|
|
466
493
|
sessionId,
|
|
467
494
|
textById: {}
|
|
468
495
|
});
|
|
@@ -481,8 +508,10 @@ window.__ModuleLoader__.load({
|
|
|
481
508
|
this.handleUnexpectedClose();
|
|
482
509
|
}
|
|
483
510
|
}, openingAbort.signal, (opening) => {
|
|
484
|
-
if (generation === this.generation)
|
|
485
|
-
|
|
511
|
+
if (generation === this.generation) {
|
|
512
|
+
this.openingTransport = opening;
|
|
513
|
+
opening.setInputMuted(this.snapshot.inputMuted);
|
|
514
|
+
} else opening.close();
|
|
486
515
|
}, contexts);
|
|
487
516
|
if (generation !== this.generation) {
|
|
488
517
|
await transport.close();
|
|
@@ -505,7 +534,18 @@ window.__ModuleLoader__.load({
|
|
|
505
534
|
async retry() {
|
|
506
535
|
const sessionId = this.snapshot.sessionId;
|
|
507
536
|
if (sessionId === void 0) throw new Error("voice retry requires an active session");
|
|
508
|
-
await this.
|
|
537
|
+
await this.open(sessionId, this.snapshot.inputMuted);
|
|
538
|
+
}
|
|
539
|
+
/** Mute or resume microphone input without closing text submission or playback. */
|
|
540
|
+
setInputMuted(muted) {
|
|
541
|
+
if (this.snapshot.state === "off" || this.snapshot.state === "error" || this.snapshot.sessionId === void 0) throw new Error("voice input mute requires an active connection");
|
|
542
|
+
if (this.snapshot.inputMuted === muted) return;
|
|
543
|
+
this.openingTransport?.setInputMuted(muted);
|
|
544
|
+
this.transport?.setInputMuted(muted);
|
|
545
|
+
this.publish({
|
|
546
|
+
...this.snapshot,
|
|
547
|
+
inputMuted: muted
|
|
548
|
+
});
|
|
509
549
|
}
|
|
510
550
|
/** Cancel the exact active background task through the attached Voice transport. */
|
|
511
551
|
cancelTask(taskId) {
|
|
@@ -673,6 +713,7 @@ window.__ModuleLoader__.load({
|
|
|
673
713
|
let outputSampleRate = 24e3;
|
|
674
714
|
let audioFormat = "pcm_s16le";
|
|
675
715
|
let playAt = outputContext.currentTime;
|
|
716
|
+
let inputMuted = false;
|
|
676
717
|
const chunks = [];
|
|
677
718
|
const playing = /* @__PURE__ */ new Set();
|
|
678
719
|
const transport = {
|
|
@@ -683,6 +724,13 @@ window.__ModuleLoader__.load({
|
|
|
683
724
|
taskId
|
|
684
725
|
}));
|
|
685
726
|
},
|
|
727
|
+
setInputMuted: (muted) => {
|
|
728
|
+
if (inputMuted === muted) return;
|
|
729
|
+
inputMuted = muted;
|
|
730
|
+
chunks.splice(0);
|
|
731
|
+
for (const track of stream?.getTracks() ?? []) track.enabled = !muted;
|
|
732
|
+
if (muted && !stopped && socket.readyState === WebSocket.OPEN) socket.send(JSON.stringify({ type: "audio.commit" }));
|
|
733
|
+
},
|
|
686
734
|
submitText: (text) => {
|
|
687
735
|
if (socket.readyState !== WebSocket.OPEN) throw new Error("voice transport is not open");
|
|
688
736
|
socket.send(JSON.stringify({
|
|
@@ -787,6 +835,7 @@ window.__ModuleLoader__.load({
|
|
|
787
835
|
throw new Error("voice connection opening aborted");
|
|
788
836
|
}
|
|
789
837
|
stream = captured;
|
|
838
|
+
for (const track of stream.getTracks()) track.enabled = !inputMuted;
|
|
790
839
|
await abortable(inputContext.audioWorklet.addModule(workletUrl), signal);
|
|
791
840
|
if (openingStopped(signal, stopped)) throw new Error("voice connection opening aborted");
|
|
792
841
|
source = inputContext.createMediaStreamSource(stream);
|
|
@@ -794,7 +843,7 @@ window.__ModuleLoader__.load({
|
|
|
794
843
|
silent = inputContext.createGain();
|
|
795
844
|
silent.gain.value = 0;
|
|
796
845
|
processor.port.onmessage = (event) => {
|
|
797
|
-
if (socket.readyState !== WebSocket.OPEN) return;
|
|
846
|
+
if (inputMuted || socket.readyState !== WebSocket.OPEN) return;
|
|
798
847
|
chunks.push(...resample(event.data, inputContext.sampleRate, inputSampleRate));
|
|
799
848
|
const frameSize = Math.max(1, Math.round(inputSampleRate / 5));
|
|
800
849
|
while (chunks.length >= frameSize) {
|
|
@@ -1297,11 +1346,13 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
1297
1346
|
"badge.voice": "VOICE",
|
|
1298
1347
|
"control.start": "开始语音对话",
|
|
1299
1348
|
"control.retry": "语音连接失败,点击重试",
|
|
1300
|
-
"control.
|
|
1349
|
+
"control.mute": "静音麦克风",
|
|
1350
|
+
"control.unmute": "解除静音",
|
|
1301
1351
|
"overlay.connecting": "正在连接语音",
|
|
1302
1352
|
"overlay.listening": "正在聆听",
|
|
1303
1353
|
"overlay.speaking": "正在播放回复",
|
|
1304
1354
|
"overlay.error": "语音连接失败",
|
|
1355
|
+
"overlay.muted": "已静音",
|
|
1305
1356
|
"overlay.return": "返回语音对话",
|
|
1306
1357
|
"overlay.stop": "结束",
|
|
1307
1358
|
"history.open": "打开语音历史",
|
|
@@ -1333,11 +1384,13 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
1333
1384
|
"badge.voice": "VOICE",
|
|
1334
1385
|
"control.start": "Start voice conversation",
|
|
1335
1386
|
"control.retry": "Voice connection failed, press to retry",
|
|
1336
|
-
"control.
|
|
1387
|
+
"control.mute": "Mute microphone",
|
|
1388
|
+
"control.unmute": "Unmute microphone",
|
|
1337
1389
|
"overlay.connecting": "Connecting voice",
|
|
1338
1390
|
"overlay.listening": "Listening",
|
|
1339
1391
|
"overlay.speaking": "Playing response",
|
|
1340
1392
|
"overlay.error": "Voice connection failed",
|
|
1393
|
+
"overlay.muted": "Muted",
|
|
1341
1394
|
"overlay.return": "Return to voice conversation",
|
|
1342
1395
|
"overlay.stop": "End",
|
|
1343
1396
|
"history.open": "Open voice history",
|
|
@@ -1407,7 +1460,9 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
1407
1460
|
const sessionId = controller.getSnapshot().sessionId;
|
|
1408
1461
|
if (sessionId !== void 0) history.record(sessionId);
|
|
1409
1462
|
},
|
|
1410
|
-
|
|
1463
|
+
setVoiceMuted: (muted) => {
|
|
1464
|
+
controller.setInputMuted(muted);
|
|
1465
|
+
}
|
|
1411
1466
|
});
|
|
1412
1467
|
const voiceOverlayInjected = () => ({
|
|
1413
1468
|
hooks: { voice: controller },
|