@flowingspring/dsh-voco 0.3.5 → 0.3.7
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/README.i18n.yaml +2 -2
- package/README.md +11 -5
- package/README.zh.md +11 -5
- package/lib/client.js +349 -48
- package/lib/client.js.map +1 -1
- package/lib/plugins/voice-assistant.js +27 -0
- package/lib/plugins/voice-local.js +36 -17
- package/package.json +11 -1
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/bundle/voice-app/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 3582129953c75938c6c08caa11526d5179f0631f
|
|
6
|
+
README.zh.md: f7253637cf50cf5b9677bee512e45fdadd8cc712
|
package/README.md
CHANGED
|
@@ -29,14 +29,18 @@ dsh web
|
|
|
29
29
|
GitHub Releases provide a prebuilt plugin package; no source checkout or pnpm installation is required:
|
|
30
30
|
|
|
31
31
|
```powershell
|
|
32
|
-
dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.
|
|
32
|
+
dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.6/flowingspring-dsh-voco-0.3.6.tgz
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Release page: [v0.3.
|
|
35
|
+
Release page: [v0.3.6](https://github.com/lgquan/dsh-voco/releases/tag/v0.3.6)
|
|
36
36
|
|
|
37
37
|
## Configure the API key
|
|
38
38
|
|
|
39
|
-
Speech recognition requires your own [SiliconFlow API key](https://siliconflow.cn/). The only configuration name is `SILICONFLOW_API_KEY
|
|
39
|
+
Speech recognition requires your own [SiliconFlow API key](https://siliconflow.cn/). The only configuration name is `SILICONFLOW_API_KEY`. Speech-to-text uses SiliconFlow's currently free [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra) model; current availability and pricing are governed by the model page. Edge TTS does not require a key.
|
|
40
|
+
|
|
41
|
+
The recommended path is **Settings → Plugins → Plugin configuration** in DSH. Expand **Voice Assistant (Voco)**, enter the API key, and save. The key is stored in DSH credentials rather than the regular settings file. Start or reconnect Voice after saving.
|
|
42
|
+
|
|
43
|
+
Environment variables and `.env` remain supported for compatibility and automation.
|
|
40
44
|
|
|
41
45
|
For a temporary setting, use the same PowerShell session that starts DSH:
|
|
42
46
|
|
|
@@ -78,13 +82,15 @@ dsh plugin --profile web remove @flowingspring/dsh-voco
|
|
|
78
82
|
|
|
79
83
|
Uninstalling does not delete DSH sessions or Voice history.
|
|
80
84
|
|
|
85
|
+
It also leaves a saved API key in place. To remove the key completely, delete `SILICONFLOW_API_KEY` from `refs` in `%USERPROFILE%\.dsh\.credentials.yaml` (or `$DSH_HOME/.credentials.yaml` when configured), and remove the same name from the process environment or any `.env` file.
|
|
86
|
+
|
|
81
87
|
## Features
|
|
82
88
|
|
|
83
|
-
- SiliconFlow `XingChenAGI/XingChenASR-V3.2-Ultra` cloud speech
|
|
89
|
+
- SiliconFlow's free [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra) cloud speech-to-text model.
|
|
84
90
|
- Edge TTS `zh-CN-XiaoxiaoNeural` voice responses.
|
|
85
91
|
- Interruption, navigation, reconnects, and restored history.
|
|
86
92
|
- Immediate acknowledgement before delegation; full reports remain in the DSH task UI.
|
|
87
|
-
- Optional `@flowingspring/dsh-workspace-memory` integration.
|
|
93
|
+
- Optional `@flowingspring/dsh-workspace-memory` integration for both the source Voice Session and every completed delegated child task.
|
|
88
94
|
|
|
89
95
|
## Troubleshooting
|
|
90
96
|
|
package/README.zh.md
CHANGED
|
@@ -29,14 +29,18 @@ dsh web
|
|
|
29
29
|
GitHub Release 提供已经构建好的插件包,不需要下载源码或安装 pnpm:
|
|
30
30
|
|
|
31
31
|
```powershell
|
|
32
|
-
dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.
|
|
32
|
+
dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.6/flowingspring-dsh-voco-0.3.6.tgz
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Release 页面:[v0.3.
|
|
35
|
+
Release 页面:[v0.3.6](https://github.com/lgquan/dsh-voco/releases/tag/v0.3.6)
|
|
36
36
|
|
|
37
37
|
## 配置 API Key
|
|
38
38
|
|
|
39
|
-
语音识别需要你自己的[硅基流动 API Key](https://siliconflow.cn/),配置名只有一个:`SILICONFLOW_API_KEY
|
|
39
|
+
语音识别需要你自己的[硅基流动 API Key](https://siliconflow.cn/),配置名只有一个:`SILICONFLOW_API_KEY`。语音转文字使用硅基流动当前免费的 [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra);免费状态和使用规则以模型页面为准。Edge TTS 不需要 API Key。
|
|
40
|
+
|
|
41
|
+
推荐在 DSH 中打开“设置 → 插件 → 插件配置”,展开“语音助手(Voco)”,填写 API Key 并保存。密钥保存在 DSH 凭据库中,不写入普通设置文件;保存后重新开启或重连语音即可生效。
|
|
42
|
+
|
|
43
|
+
环境变量和 `.env` 仍作为兼容与自动化配置方式保留。
|
|
40
44
|
|
|
41
45
|
在启动 DSH 的同一个 PowerShell 中临时设置:
|
|
42
46
|
|
|
@@ -78,13 +82,15 @@ dsh plugin --profile web remove @flowingspring/dsh-voco
|
|
|
78
82
|
|
|
79
83
|
卸载不会自动删除 DSH 会话或语音历史。
|
|
80
84
|
|
|
85
|
+
卸载也不会删除已经保存的 API Key。需要彻底清除时,从 `%USERPROFILE%\.dsh\.credentials.yaml`(设置了 `DSH_HOME` 时为 `$DSH_HOME/.credentials.yaml`)的 `refs` 下删除 `SILICONFLOW_API_KEY`,并同时清理系统环境变量或 `.env` 中的同名配置。
|
|
86
|
+
|
|
81
87
|
## 功能
|
|
82
88
|
|
|
83
|
-
- SiliconFlow `XingChenAGI/XingChenASR-V3.2-Ultra`
|
|
89
|
+
- SiliconFlow 免费模型 [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra) 云端语音转文字。
|
|
84
90
|
- Edge TTS `zh-CN-XiaoxiaoNeural` 语音回复。
|
|
85
91
|
- 语音打断、页面切换、断线重连和历史恢复。
|
|
86
92
|
- 委派前即时确认,完整报告保留在 DSH 任务界面。
|
|
87
|
-
- 可选接入 `@flowingspring/dsh-workspace-memory
|
|
93
|
+
- 可选接入 `@flowingspring/dsh-workspace-memory`,让语音主会话和每个完成的委派子任务共享同一 Workspace 长期记忆范围。
|
|
88
94
|
|
|
89
95
|
## 排查
|
|
90
96
|
|
package/lib/client.js
CHANGED
|
@@ -10,20 +10,20 @@ window.__ModuleLoader__.load({
|
|
|
10
10
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
11
11
|
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
12
12
|
//#region \0dsh-css:D:\QUAN\DevCode\Python\Project\dsh\dsh-voco\packages\ui-voice\src\client\VoiceControl.module.css.mjs
|
|
13
|
-
const css$
|
|
14
|
-
const tagId$
|
|
15
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
13
|
+
const css$4 = ".TFZsua_controls{align-items:center;gap:2px;display:inline-flex}.TFZsua_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}.TFZsua_button:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.TFZsua_active{color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-interactive-bg-hover-solid)}.TFZsua_button[data-muted=true]{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, currentColor 12%, transparent)}.TFZsua_interruptButton,.TFZsua_interruptButton:hover{color:var(--dsw-alias-state-error-primary)}.TFZsua_button[data-muted=true]:hover{background:color-mix(in srgb, currentColor 18%, transparent)}.TFZsua_button[data-state=speaking][data-muted=false]{animation:1.2s ease-in-out infinite TFZsua_voice-pulse}@keyframes TFZsua_voice-pulse{50%{opacity:.55;transform:scale(.94)}}@media (prefers-reduced-motion:reduce){.TFZsua_button[data-state=speaking][data-muted=false]{animation:none}}";
|
|
14
|
+
const tagId$4 = "@flowingspring/dsh-voco/VoiceControl.module.css";
|
|
15
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
16
16
|
const tag = document.createElement("style");
|
|
17
17
|
tag.dataset.plugin = "@flowingspring/dsh-voco";
|
|
18
|
-
tag.dataset.pluginCss = tagId$
|
|
19
|
-
tag.textContent = css$
|
|
18
|
+
tag.dataset.pluginCss = tagId$4;
|
|
19
|
+
tag.textContent = css$4;
|
|
20
20
|
document.head.appendChild(tag);
|
|
21
21
|
}
|
|
22
22
|
var VoiceControl_module_css_default = {
|
|
23
|
+
"button": "TFZsua_button",
|
|
23
24
|
"controls": "TFZsua_controls",
|
|
24
25
|
"active": "TFZsua_active",
|
|
25
26
|
"interruptButton": "TFZsua_interruptButton",
|
|
26
|
-
"button": "TFZsua_button",
|
|
27
27
|
"voice-pulse": "TFZsua_voice-pulse"
|
|
28
28
|
};
|
|
29
29
|
//#endregion
|
|
@@ -153,33 +153,33 @@ window.__ModuleLoader__.load({
|
|
|
153
153
|
}
|
|
154
154
|
//#endregion
|
|
155
155
|
//#region \0dsh-css:D:\QUAN\DevCode\Python\Project\dsh\dsh-voco\packages\ui-voice\src\client\VoiceNodeViews.module.css.mjs
|
|
156
|
-
const css$
|
|
157
|
-
const tagId$
|
|
158
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
156
|
+
const css$3 = ".Kt2smW_utterance{flex-direction:column;align-items:flex-start;gap:6px;min-width:0;display:flex}.Kt2smW_utterance[data-role=user]{align-items:flex-end}.Kt2smW_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}.Kt2smW_utterance[data-role=user] .Kt2smW_bubble{background:var(--dsw-specific-bubble);border-color:#0000}.Kt2smW_utterance[data-state=streaming] .Kt2smW_bubble{color:var(--dsw-alias-label-secondary)}.Kt2smW_meta,.Kt2smW_voiceBadge{align-items:center;display:inline-flex}.Kt2smW_meta{color:var(--dsw-alias-label-tertiary);gap:8px;padding:0 5px;font-size:10px;line-height:14px}.Kt2smW_voiceBadge{color:var(--dsw-alias-state-business-primary);letter-spacing:.04em;gap:4px;font-weight:600}.Kt2smW_miniWave{align-items:center;gap:1px;height:10px;display:inline-flex}.Kt2smW_miniWave i{background:currentColor;border-radius:1px;width:1.5px;height:4px}.Kt2smW_miniWave i:nth-child(2){height:8px}.Kt2smW_miniWave i:nth-child(3){height:6px}.Kt2smW_taskCard{box-sizing:border-box;width:fit-content;min-width:0;max-width:min(525px,100%)}.Kt2smW_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}.Kt2smW_taskSummary:hover{background:var(--dsw-alias-bg-layer-1)}.Kt2smW_taskDot{background:var(--dsw-alias-state-business-primary);border-radius:50%;flex:none;width:7px;height:7px}.Kt2smW_taskCard[data-status=completed] .Kt2smW_taskDot{background:var(--dsw-alias-state-success-primary)}.Kt2smW_taskCard[data-status=failed] .Kt2smW_taskDot{background:var(--dsw-alias-state-error-primary)}.Kt2smW_taskCard[data-status=cancelled] .Kt2smW_taskDot,.Kt2smW_taskCard[data-status=interrupted] .Kt2smW_taskDot{background:var(--dsw-alias-state-warn-primary)}.Kt2smW_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}.Kt2smW_taskStatus{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;line-height:16px}.Kt2smW_taskStatus:before{content:\"·\";margin-right:7px}.Kt2smW_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)}.Kt2smW_taskCard[data-expanded=true] .Kt2smW_taskChevron{transform:rotate(45deg)}.Kt2smW_taskInput,.Kt2smW_taskUpdate{overflow-wrap:anywhere;margin:0;font-size:13px;line-height:20px}.Kt2smW_taskInput{color:var(--dsw-alias-label-primary)}.Kt2smW_taskUpdate{color:var(--dsw-alias-label-secondary);margin-top:4px}.Kt2smW_taskDetails{border-left:1px solid var(--dsw-alias-border-l2);margin:9px 0 0 3px;padding:2px 0 2px 16px}.Kt2smW_taskActions{align-items:center;gap:14px;margin-top:7px;display:flex}.Kt2smW_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}.Kt2smW_taskLink:hover:not(:disabled){text-underline-position:from-font;text-decoration:underline}.Kt2smW_taskLink:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.Kt2smW_taskCancel{color:var(--dsw-alias-state-error-primary)}";
|
|
157
|
+
const tagId$3 = "@flowingspring/dsh-voco/VoiceNodeViews.module.css";
|
|
158
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
159
159
|
const tag = document.createElement("style");
|
|
160
160
|
tag.dataset.plugin = "@flowingspring/dsh-voco";
|
|
161
|
-
tag.dataset.pluginCss = tagId$
|
|
162
|
-
tag.textContent = css$
|
|
161
|
+
tag.dataset.pluginCss = tagId$3;
|
|
162
|
+
tag.textContent = css$3;
|
|
163
163
|
document.head.appendChild(tag);
|
|
164
164
|
}
|
|
165
165
|
var VoiceNodeViews_module_css_default = {
|
|
166
|
+
"taskDot": "Kt2smW_taskDot",
|
|
167
|
+
"taskCard": "Kt2smW_taskCard",
|
|
168
|
+
"meta": "Kt2smW_meta",
|
|
169
|
+
"taskTitle": "Kt2smW_taskTitle",
|
|
166
170
|
"utterance": "Kt2smW_utterance",
|
|
171
|
+
"bubble": "Kt2smW_bubble",
|
|
172
|
+
"taskDetails": "Kt2smW_taskDetails",
|
|
167
173
|
"taskSummary": "Kt2smW_taskSummary",
|
|
168
|
-
"
|
|
174
|
+
"miniWave": "Kt2smW_miniWave",
|
|
169
175
|
"taskCancel": "Kt2smW_taskCancel",
|
|
170
|
-
"taskTitle": "Kt2smW_taskTitle",
|
|
171
|
-
"taskDetails": "Kt2smW_taskDetails",
|
|
172
|
-
"taskInput": "Kt2smW_taskInput",
|
|
173
|
-
"taskDot": "Kt2smW_taskDot",
|
|
174
|
-
"taskChevron": "Kt2smW_taskChevron",
|
|
175
|
-
"meta": "Kt2smW_meta",
|
|
176
|
-
"voiceBadge": "Kt2smW_voiceBadge",
|
|
177
176
|
"taskUpdate": "Kt2smW_taskUpdate",
|
|
178
|
-
"
|
|
177
|
+
"voiceBadge": "Kt2smW_voiceBadge",
|
|
179
178
|
"taskStatus": "Kt2smW_taskStatus",
|
|
180
|
-
"
|
|
181
|
-
"
|
|
182
|
-
"
|
|
179
|
+
"taskLink": "Kt2smW_taskLink",
|
|
180
|
+
"taskInput": "Kt2smW_taskInput",
|
|
181
|
+
"taskChevron": "Kt2smW_taskChevron",
|
|
182
|
+
"taskActions": "Kt2smW_taskActions"
|
|
183
183
|
};
|
|
184
184
|
//#endregion
|
|
185
185
|
//#region ../ui-voice/src/client/VoiceNodeViews.tsx
|
|
@@ -307,21 +307,21 @@ window.__ModuleLoader__.load({
|
|
|
307
307
|
}
|
|
308
308
|
//#endregion
|
|
309
309
|
//#region \0dsh-css:D:\QUAN\DevCode\Python\Project\dsh\dsh-voco\packages\ui-voice\src\client\VoiceOverlay.module.css.mjs
|
|
310
|
-
const css$
|
|
311
|
-
const tagId$
|
|
312
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$
|
|
310
|
+
const css$2 = ".GPPB2G_root{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-overlay);max-width:min(260px,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:8px;padding:4px 6px 4px 12px;font-size:12px;line-height:18px;display:flex;position:absolute;bottom:18px;right:18px}.GPPB2G_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}.GPPB2G_wave i{background:currentColor;border-radius:1px;width:2px;height:5px;animation:.9s ease-in-out infinite alternate GPPB2G_voice-wave}.GPPB2G_wave i:nth-child(2){height:11px;animation-delay:-300ms}.GPPB2G_wave i:nth-child(3){height:8px;animation-delay:-600ms}.GPPB2G_wave i:nth-child(4){height:4px;animation-delay:-150ms}.GPPB2G_root[data-state=connecting] .GPPB2G_wave,.GPPB2G_root[data-state=error] .GPPB2G_wave{opacity:.55}.GPPB2G_root[data-state=error] .GPPB2G_wave{color:var(--dsw-alias-state-error-primary)}.GPPB2G_status{text-overflow:ellipsis;white-space:nowrap;flex:0 auto;min-width:0;overflow:hidden}.GPPB2G_root[data-muted=true] .GPPB2G_wave{color:var(--dsw-alias-state-error-primary);opacity:.65}.GPPB2G_root[data-muted=true] .GPPB2G_status{color:var(--dsw-alias-state-error-primary);font-weight:600}.GPPB2G_root[data-muted=true] .GPPB2G_wave i{animation:none}.GPPB2G_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}.GPPB2G_stop:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.GPPB2G_stop{color:var(--dsw-alias-state-error-primary)}@keyframes GPPB2G_voice-wave{to{transform:scaleY(.55)}}@media (prefers-reduced-motion:reduce){.GPPB2G_wave i{animation:none}}";
|
|
311
|
+
const tagId$2 = "@flowingspring/dsh-voco/VoiceOverlay.module.css";
|
|
312
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
313
313
|
const tag = document.createElement("style");
|
|
314
314
|
tag.dataset.plugin = "@flowingspring/dsh-voco";
|
|
315
|
-
tag.dataset.pluginCss = tagId$
|
|
316
|
-
tag.textContent = css$
|
|
315
|
+
tag.dataset.pluginCss = tagId$2;
|
|
316
|
+
tag.textContent = css$2;
|
|
317
317
|
document.head.appendChild(tag);
|
|
318
318
|
}
|
|
319
319
|
var VoiceOverlay_module_css_default = {
|
|
320
320
|
"root": "GPPB2G_root",
|
|
321
|
-
"status": "GPPB2G_status",
|
|
322
|
-
"stop": "GPPB2G_stop",
|
|
323
321
|
"voice-wave": "GPPB2G_voice-wave",
|
|
324
|
-
"wave": "GPPB2G_wave"
|
|
322
|
+
"wave": "GPPB2G_wave",
|
|
323
|
+
"status": "GPPB2G_status",
|
|
324
|
+
"stop": "GPPB2G_stop"
|
|
325
325
|
};
|
|
326
326
|
//#endregion
|
|
327
327
|
//#region ../ui-voice/src/client/VoiceOverlay.tsx
|
|
@@ -370,30 +370,30 @@ window.__ModuleLoader__.load({
|
|
|
370
370
|
}
|
|
371
371
|
//#endregion
|
|
372
372
|
//#region \0dsh-css:D:\QUAN\DevCode\Python\Project\dsh\dsh-voco\packages\ui-voice\src\client\VoiceSessionMarkers.module.css.mjs
|
|
373
|
-
const css = "._0brRca_slot{flex:none;justify-content:center;align-items:center;width:16px;height:20px;display:inline-flex}._0brRca_marker{width:16px;height:16px;color:var(--dsw-alias-state-business-primary);pointer-events:none;justify-content:center;align-items:center;display:inline-flex}._0brRca_marker svg{width:14px;height:14px;display:block}._0brRca_toggle{width:18px;height:18px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;flex:none;justify-content:center;align-items:center;margin-left:1px;padding:0;font-size:16px;line-height:16px;display:inline-flex}._0brRca_toggle:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._0brRca_children{flex-direction:column;gap:2px;margin:2px 0 2px 20px;display:flex}._0brRca_child{min-width:0;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;font:inherit;background:0 0;border:0;border-radius:8px;align-items:center;gap:8px;padding:0 10px 0 12px;display:flex;position:relative}._0brRca_childMain{min-width:0;height:30px;color:inherit;cursor:pointer;text-align:left;font:inherit;background:0 0;border:0;flex:1;align-items:center;gap:8px;padding:0;display:flex}._0brRca_child:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._0brRca_childMain:disabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed;opacity:.72}._0brRca_child[aria-current=page]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-selected)}._0brRca_childDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:6px;height:6px}._0brRca_childDot[data-activity=running]{background:var(--dsw-alias-state-success-primary)}._0brRca_childLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}._0brRca_childTime{color:var(--dsw-alias-label-tertiary);flex:none;margin-left:auto;font-size:12px;line-height:20px}._0brRca_child[data-menu-open=true] ._0brRca_childTime,._0brRca_child:hover ._0brRca_childTime{display:none}._0brRca_childActions{flex:none;align-items:center;display:none;position:absolute;right:10px}._0brRca_child:hover ._0brRca_childActions,._0brRca_child[data-menu-open=true] ._0brRca_childActions{display:inline-flex}._0brRca_childMenuButton{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;padding:0;display:inline-flex}._0brRca_childMenuButton:hover{color:var(--dsw-alias-label-primary)}._0brRca_deleteAction:not(:disabled){color:var(--dsw-alias-state-error-primary)}._0brRca_deleteStatus{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}._0brRca_deleteError{color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}";
|
|
374
|
-
const tagId = "@flowingspring/dsh-voco/VoiceSessionMarkers.module.css";
|
|
375
|
-
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
373
|
+
const css$1 = "._0brRca_slot{flex:none;justify-content:center;align-items:center;width:16px;height:20px;display:inline-flex}._0brRca_marker{width:16px;height:16px;color:var(--dsw-alias-state-business-primary);pointer-events:none;justify-content:center;align-items:center;display:inline-flex}._0brRca_marker svg{width:14px;height:14px;display:block}._0brRca_toggle{width:18px;height:18px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;flex:none;justify-content:center;align-items:center;margin-left:1px;padding:0;font-size:16px;line-height:16px;display:inline-flex}._0brRca_toggle:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._0brRca_children{flex-direction:column;gap:2px;margin:2px 0 2px 20px;display:flex}._0brRca_child{min-width:0;height:30px;color:var(--dsw-alias-label-secondary);cursor:pointer;text-align:left;font:inherit;background:0 0;border:0;border-radius:8px;align-items:center;gap:8px;padding:0 10px 0 12px;display:flex;position:relative}._0brRca_childMain{min-width:0;height:30px;color:inherit;cursor:pointer;text-align:left;font:inherit;background:0 0;border:0;flex:1;align-items:center;gap:8px;padding:0;display:flex}._0brRca_child:hover{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-hover)}._0brRca_childMain:disabled{color:var(--dsw-alias-label-tertiary);cursor:not-allowed;opacity:.72}._0brRca_child[aria-current=page]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-interactive-bg-selected)}._0brRca_childDot{background:var(--dsw-alias-label-tertiary);border-radius:50%;flex:none;width:6px;height:6px}._0brRca_childDot[data-activity=running]{background:var(--dsw-alias-state-success-primary)}._0brRca_childLabel{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}._0brRca_childTime{color:var(--dsw-alias-label-tertiary);flex:none;margin-left:auto;font-size:12px;line-height:20px}._0brRca_child[data-menu-open=true] ._0brRca_childTime,._0brRca_child:hover ._0brRca_childTime{display:none}._0brRca_childActions{flex:none;align-items:center;display:none;position:absolute;right:10px}._0brRca_child:hover ._0brRca_childActions,._0brRca_child[data-menu-open=true] ._0brRca_childActions{display:inline-flex}._0brRca_childMenuButton{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:4px;justify-content:center;align-items:center;padding:0;display:inline-flex}._0brRca_childMenuButton:hover{color:var(--dsw-alias-label-primary)}._0brRca_deleteAction:not(:disabled){color:var(--dsw-alias-state-error-primary)}._0brRca_deleteStatus{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px}._0brRca_deleteError{color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px}";
|
|
374
|
+
const tagId$1 = "@flowingspring/dsh-voco/VoiceSessionMarkers.module.css";
|
|
375
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
376
376
|
const tag = document.createElement("style");
|
|
377
377
|
tag.dataset.plugin = "@flowingspring/dsh-voco";
|
|
378
|
-
tag.dataset.pluginCss = tagId;
|
|
379
|
-
tag.textContent = css;
|
|
378
|
+
tag.dataset.pluginCss = tagId$1;
|
|
379
|
+
tag.textContent = css$1;
|
|
380
380
|
document.head.appendChild(tag);
|
|
381
381
|
}
|
|
382
382
|
var VoiceSessionMarkers_module_css_default = {
|
|
383
|
-
"
|
|
384
|
-
"
|
|
383
|
+
"child": "_0brRca_child",
|
|
384
|
+
"toggle": "_0brRca_toggle",
|
|
385
385
|
"childDot": "_0brRca_childDot",
|
|
386
|
+
"childLabel": "_0brRca_childLabel",
|
|
387
|
+
"marker": "_0brRca_marker",
|
|
386
388
|
"childTime": "_0brRca_childTime",
|
|
387
|
-
"
|
|
388
|
-
"child": "_0brRca_child",
|
|
389
|
+
"deleteStatus": "_0brRca_deleteStatus",
|
|
389
390
|
"children": "_0brRca_children",
|
|
390
|
-
"
|
|
391
|
+
"childMain": "_0brRca_childMain",
|
|
391
392
|
"childActions": "_0brRca_childActions",
|
|
392
|
-
"deleteAction": "_0brRca_deleteAction",
|
|
393
|
-
"deleteStatus": "_0brRca_deleteStatus",
|
|
394
393
|
"childMenuButton": "_0brRca_childMenuButton",
|
|
395
|
-
"
|
|
396
|
-
"
|
|
394
|
+
"deleteAction": "_0brRca_deleteAction",
|
|
395
|
+
"deleteError": "_0brRca_deleteError",
|
|
396
|
+
"slot": "_0brRca_slot"
|
|
397
397
|
};
|
|
398
398
|
//#endregion
|
|
399
399
|
//#region ../ui-voice/src/client/VoiceSessionMarkers.tsx
|
|
@@ -857,6 +857,157 @@ window.__ModuleLoader__.load({
|
|
|
857
857
|
return marker;
|
|
858
858
|
}
|
|
859
859
|
//#endregion
|
|
860
|
+
//#region \0dsh-css:D:\QUAN\DevCode\Python\Project\dsh\dsh-voco\packages\ui-voice\src\client\VocoSettingsCard.module.css.mjs
|
|
861
|
+
const css = ".G5LlXq_card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}.G5LlXq_card:hover{border-color:var(--dsw-alias-label-dimmed)}.G5LlXq_cardOpen{border-color:var(--dsw-alias-label-dimmed);background:var(--dsw-alias-bg-layer-2)}.G5LlXq_header{appearance:none;width:100%;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.G5LlXq_header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.G5LlXq_headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.G5LlXq_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.G5LlXq_description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}.G5LlXq_chevron{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.G5LlXq_chevronOpen{transform:rotate(180deg)}.G5LlXq_body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}.G5LlXq_readOnly{color:var(--dsw-alias-label-tertiary);margin:12px 0 0;font-size:12px;line-height:1.5}.G5LlXq_pending,.G5LlXq_badge{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);white-space:nowrap;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}.G5LlXq_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.G5LlXq_fieldHead{align-items:center;gap:8px;display:flex}.G5LlXq_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.G5LlXq_badgeMuted{color:var(--dsw-alias-label-tertiary);white-space:nowrap;border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px}.G5LlXq_input{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);height:34px;color:var(--dsw-alias-label-primary);font:inherit;border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.G5LlXq_input:focus-visible{border-color:var(--dsw-alias-brand-primary);outline:none}.G5LlXq_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.G5LlXq_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}.G5LlXq_providerDetails{flex-direction:column;gap:4px;margin:6px 0 0;display:flex}.G5LlXq_providerDetail{grid-template-columns:88px minmax(0,1fr);gap:8px;font-size:12px;line-height:1.5;display:grid}.G5LlXq_providerDetail dt{color:var(--dsw-alias-label-tertiary)}.G5LlXq_providerDetail dd{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-secondary);margin:0}.G5LlXq_footer{border-top:1px solid var(--dsw-alias-border-l2);justify-content:flex-end;align-items:center;gap:8px;padding:12px 0 4px;display:flex}.G5LlXq_failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}.G5LlXq_discard,.G5LlXq_save{appearance:none;font:inherit;cursor:pointer;border:1px solid #0000;border-radius:8px;padding:5px 14px;font-size:13px;line-height:1.5}.G5LlXq_discard{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:0 0}.G5LlXq_discard:hover:not(:disabled){border-color:var(--dsw-alias-label-dimmed);color:var(--dsw-alias-label-primary)}.G5LlXq_save{background:var(--dsw-alias-label-primary);color:var(--dsw-alias-bg-layer-3)}.G5LlXq_discard:disabled,.G5LlXq_save:disabled{opacity:.4;cursor:default}.G5LlXq_discard:focus-visible,.G5LlXq_save:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}";
|
|
862
|
+
const tagId = "@flowingspring/dsh-voco/VocoSettingsCard.module.css";
|
|
863
|
+
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
864
|
+
const tag = document.createElement("style");
|
|
865
|
+
tag.dataset.plugin = "@flowingspring/dsh-voco";
|
|
866
|
+
tag.dataset.pluginCss = tagId;
|
|
867
|
+
tag.textContent = css;
|
|
868
|
+
document.head.appendChild(tag);
|
|
869
|
+
}
|
|
870
|
+
var VocoSettingsCard_module_css_default = {
|
|
871
|
+
"pending": "G5LlXq_pending",
|
|
872
|
+
"badgeMuted": "G5LlXq_badgeMuted",
|
|
873
|
+
"input": "G5LlXq_input",
|
|
874
|
+
"footer": "G5LlXq_footer",
|
|
875
|
+
"name": "G5LlXq_name",
|
|
876
|
+
"chevronOpen": "G5LlXq_chevronOpen",
|
|
877
|
+
"headText": "G5LlXq_headText",
|
|
878
|
+
"cardOpen": "G5LlXq_cardOpen",
|
|
879
|
+
"hint": "G5LlXq_hint",
|
|
880
|
+
"discard": "G5LlXq_discard",
|
|
881
|
+
"providerDetails": "G5LlXq_providerDetails",
|
|
882
|
+
"save": "G5LlXq_save",
|
|
883
|
+
"failed": "G5LlXq_failed",
|
|
884
|
+
"field": "G5LlXq_field",
|
|
885
|
+
"description": "G5LlXq_description",
|
|
886
|
+
"badge": "G5LlXq_badge",
|
|
887
|
+
"label": "G5LlXq_label",
|
|
888
|
+
"providerDetail": "G5LlXq_providerDetail",
|
|
889
|
+
"header": "G5LlXq_header",
|
|
890
|
+
"body": "G5LlXq_body",
|
|
891
|
+
"fieldHead": "G5LlXq_fieldHead",
|
|
892
|
+
"readOnly": "G5LlXq_readOnly",
|
|
893
|
+
"chevron": "G5LlXq_chevron",
|
|
894
|
+
"card": "G5LlXq_card"
|
|
895
|
+
};
|
|
896
|
+
//#endregion
|
|
897
|
+
//#region ../ui-voice/src/client/VocoSettingsCard.tsx
|
|
898
|
+
/** Official plugin-settings slot contribution for the Voco credential. */
|
|
899
|
+
function VocoSettingsCard({ useVocoSettings, editApiKey, save, discard, t }) {
|
|
900
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
901
|
+
const state = useVocoSettings((value) => value);
|
|
902
|
+
if (!state.available) return null;
|
|
903
|
+
const title = t("settings.title");
|
|
904
|
+
const disabled = !state.writable || !state.apiKeyWritable || state.saving;
|
|
905
|
+
const saveDisabled = !state.dirty || disabled;
|
|
906
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
907
|
+
className: `${VocoSettingsCard_module_css_default.card} ${open ? VocoSettingsCard_module_css_default.cardOpen : ""}`,
|
|
908
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
909
|
+
type: "button",
|
|
910
|
+
className: VocoSettingsCard_module_css_default.header,
|
|
911
|
+
"aria-expanded": open,
|
|
912
|
+
"aria-label": `${t(open ? "settings.collapse" : "settings.expand")}: ${title}`,
|
|
913
|
+
onClick: () => {
|
|
914
|
+
setOpen(!open);
|
|
915
|
+
},
|
|
916
|
+
children: [
|
|
917
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
918
|
+
className: VocoSettingsCard_module_css_default.headText,
|
|
919
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
920
|
+
className: VocoSettingsCard_module_css_default.name,
|
|
921
|
+
children: title
|
|
922
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
923
|
+
className: VocoSettingsCard_module_css_default.description,
|
|
924
|
+
children: t("settings.description")
|
|
925
|
+
})]
|
|
926
|
+
}),
|
|
927
|
+
state.dirty && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
928
|
+
className: VocoSettingsCard_module_css_default.pending,
|
|
929
|
+
children: t("settings.unsaved")
|
|
930
|
+
}),
|
|
931
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, { className: `${VocoSettingsCard_module_css_default.chevron} ${open ? VocoSettingsCard_module_css_default.chevronOpen : ""}` })
|
|
932
|
+
]
|
|
933
|
+
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
934
|
+
className: VocoSettingsCard_module_css_default.body,
|
|
935
|
+
children: [
|
|
936
|
+
!state.writable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
937
|
+
className: VocoSettingsCard_module_css_default.readOnly,
|
|
938
|
+
role: "status",
|
|
939
|
+
children: t("settings.readOnly")
|
|
940
|
+
}),
|
|
941
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
942
|
+
className: VocoSettingsCard_module_css_default.field,
|
|
943
|
+
children: [
|
|
944
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
945
|
+
className: VocoSettingsCard_module_css_default.fieldHead,
|
|
946
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
947
|
+
className: VocoSettingsCard_module_css_default.label,
|
|
948
|
+
htmlFor: "voco-siliconflow-api-key",
|
|
949
|
+
children: t("settings.apiKey")
|
|
950
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
951
|
+
className: state.apiKeyConfigured ? VocoSettingsCard_module_css_default.badge : VocoSettingsCard_module_css_default.badgeMuted,
|
|
952
|
+
children: t(state.apiKeyConfigured ? "settings.apiKeySet" : "settings.apiKeyUnset")
|
|
953
|
+
})]
|
|
954
|
+
}),
|
|
955
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
956
|
+
id: "voco-siliconflow-api-key",
|
|
957
|
+
className: VocoSettingsCard_module_css_default.input,
|
|
958
|
+
type: "password",
|
|
959
|
+
autoComplete: "off",
|
|
960
|
+
value: state.apiKey,
|
|
961
|
+
disabled,
|
|
962
|
+
onChange: (event) => {
|
|
963
|
+
editApiKey(event.target.value);
|
|
964
|
+
}
|
|
965
|
+
}),
|
|
966
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
967
|
+
className: VocoSettingsCard_module_css_default.hint,
|
|
968
|
+
children: t("settings.apiKeyHint")
|
|
969
|
+
}),
|
|
970
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", {
|
|
971
|
+
className: VocoSettingsCard_module_css_default.providerDetails,
|
|
972
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
973
|
+
className: VocoSettingsCard_module_css_default.providerDetail,
|
|
974
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("settings.platform") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: t("settings.platformValue") })]
|
|
975
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
976
|
+
className: VocoSettingsCard_module_css_default.providerDetail,
|
|
977
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("dt", { children: t("settings.model") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dd", { children: t("settings.modelValue") })]
|
|
978
|
+
})]
|
|
979
|
+
})
|
|
980
|
+
]
|
|
981
|
+
}),
|
|
982
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
983
|
+
className: VocoSettingsCard_module_css_default.footer,
|
|
984
|
+
children: [
|
|
985
|
+
state.failed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
986
|
+
className: VocoSettingsCard_module_css_default.failed,
|
|
987
|
+
role: "status",
|
|
988
|
+
children: t("settings.saveFailed")
|
|
989
|
+
}),
|
|
990
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
991
|
+
type: "button",
|
|
992
|
+
className: VocoSettingsCard_module_css_default.discard,
|
|
993
|
+
disabled: !state.dirty || state.saving,
|
|
994
|
+
onClick: discard,
|
|
995
|
+
children: t("settings.discard")
|
|
996
|
+
}),
|
|
997
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
998
|
+
type: "button",
|
|
999
|
+
className: VocoSettingsCard_module_css_default.save,
|
|
1000
|
+
disabled: saveDisabled,
|
|
1001
|
+
onClick: save,
|
|
1002
|
+
children: t(state.saving ? "settings.saving" : "settings.save")
|
|
1003
|
+
})
|
|
1004
|
+
]
|
|
1005
|
+
})
|
|
1006
|
+
]
|
|
1007
|
+
})]
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
//#endregion
|
|
860
1011
|
//#region ../ui-voice/src/client/voice-controller.ts
|
|
861
1012
|
const INITIAL_SNAPSHOT = {
|
|
862
1013
|
state: "off",
|
|
@@ -1862,7 +2013,25 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
1862
2013
|
"task.expand": "展开后台处理详情",
|
|
1863
2014
|
"task.collapse": "收起后台处理详情",
|
|
1864
2015
|
"task.cancel": "取消任务",
|
|
1865
|
-
"task.open": "查看后台详情"
|
|
2016
|
+
"task.open": "查看后台详情",
|
|
2017
|
+
"settings.title": "语音助手(Voco)",
|
|
2018
|
+
"settings.description": "语音识别供应商配置。",
|
|
2019
|
+
"settings.expand": "展开设置",
|
|
2020
|
+
"settings.collapse": "收起设置",
|
|
2021
|
+
"settings.unsaved": "未保存",
|
|
2022
|
+
"settings.readOnly": "本部署的设置为只读。",
|
|
2023
|
+
"settings.apiKey": "API Key",
|
|
2024
|
+
"settings.apiKeyHint": "安全保存到 DSH 凭据库。留空表示保持当前密钥。",
|
|
2025
|
+
"settings.platform": "API 平台",
|
|
2026
|
+
"settings.platformValue": "硅基流动",
|
|
2027
|
+
"settings.model": "语音识别模型",
|
|
2028
|
+
"settings.modelValue": "XingChenAGI/XingChenASR-V3.2-Ultra(免费)",
|
|
2029
|
+
"settings.apiKeySet": "已配置密钥。",
|
|
2030
|
+
"settings.apiKeyUnset": "未配置密钥。",
|
|
2031
|
+
"settings.save": "保存",
|
|
2032
|
+
"settings.saving": "保存中…",
|
|
2033
|
+
"settings.discard": "放弃修改",
|
|
2034
|
+
"settings.saveFailed": "密钥保存失败,已保留供你重试。"
|
|
1866
2035
|
};
|
|
1867
2036
|
/** English dictionary, checked complete against the zh key set. */
|
|
1868
2037
|
const en = {
|
|
@@ -1893,7 +2062,127 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
1893
2062
|
"task.expand": "Show background task details",
|
|
1894
2063
|
"task.collapse": "Hide background task details",
|
|
1895
2064
|
"task.cancel": "Cancel task",
|
|
1896
|
-
"task.open": "View background details"
|
|
2065
|
+
"task.open": "View background details",
|
|
2066
|
+
"settings.title": "Voice Assistant (Voco)",
|
|
2067
|
+
"settings.description": "Speech recognition provider configuration.",
|
|
2068
|
+
"settings.expand": "Show settings",
|
|
2069
|
+
"settings.collapse": "Hide settings",
|
|
2070
|
+
"settings.unsaved": "Unsaved",
|
|
2071
|
+
"settings.readOnly": "This deployment stores settings read-only.",
|
|
2072
|
+
"settings.apiKey": "API key",
|
|
2073
|
+
"settings.apiKeyHint": "Stored securely in DSH credentials. Leave blank to keep the current key.",
|
|
2074
|
+
"settings.platform": "API platform",
|
|
2075
|
+
"settings.platformValue": "SiliconFlow",
|
|
2076
|
+
"settings.model": "Speech model",
|
|
2077
|
+
"settings.modelValue": "XingChenAGI/XingChenASR-V3.2-Ultra (free)",
|
|
2078
|
+
"settings.apiKeySet": "A key is configured.",
|
|
2079
|
+
"settings.apiKeyUnset": "No key is configured.",
|
|
2080
|
+
"settings.save": "Save",
|
|
2081
|
+
"settings.saving": "Saving…",
|
|
2082
|
+
"settings.discard": "Discard",
|
|
2083
|
+
"settings.saveFailed": "The key could not be saved and was kept for you to retry."
|
|
2084
|
+
};
|
|
2085
|
+
//#endregion
|
|
2086
|
+
//#region ../ui-voice/src/client/voco-settings-controller.ts
|
|
2087
|
+
const VOCO_SETTINGS_NAMESPACE = "voice-local";
|
|
2088
|
+
const SILICONFLOW_API_KEY_REF = "SILICONFLOW_API_KEY";
|
|
2089
|
+
/** Bridges the voice-local namespace and the write-only DSH credentials API. */
|
|
2090
|
+
var VocoSettingsController = class {
|
|
2091
|
+
scope;
|
|
2092
|
+
api;
|
|
2093
|
+
store;
|
|
2094
|
+
draft = "";
|
|
2095
|
+
saving = false;
|
|
2096
|
+
failed = false;
|
|
2097
|
+
credential = {
|
|
2098
|
+
configured: false,
|
|
2099
|
+
writable: true
|
|
2100
|
+
};
|
|
2101
|
+
constructor(scope, api) {
|
|
2102
|
+
this.scope = scope;
|
|
2103
|
+
this.api = api;
|
|
2104
|
+
this.store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)(this.projection());
|
|
2105
|
+
scope.subscribe(() => {
|
|
2106
|
+
this.publish();
|
|
2107
|
+
});
|
|
2108
|
+
this.readCredential();
|
|
2109
|
+
}
|
|
2110
|
+
refreshCredential(ref) {
|
|
2111
|
+
if (ref === "SILICONFLOW_API_KEY") this.readCredential();
|
|
2112
|
+
}
|
|
2113
|
+
inject() {
|
|
2114
|
+
return {
|
|
2115
|
+
hooks: { vocoSettings: this.store },
|
|
2116
|
+
editApiKey: (value) => {
|
|
2117
|
+
this.draft = value;
|
|
2118
|
+
this.failed = false;
|
|
2119
|
+
this.publish();
|
|
2120
|
+
},
|
|
2121
|
+
save: () => {
|
|
2122
|
+
this.save();
|
|
2123
|
+
},
|
|
2124
|
+
discard: () => {
|
|
2125
|
+
this.draft = "";
|
|
2126
|
+
this.failed = false;
|
|
2127
|
+
this.publish();
|
|
2128
|
+
}
|
|
2129
|
+
};
|
|
2130
|
+
}
|
|
2131
|
+
projection() {
|
|
2132
|
+
const snapshot = this.scope.getSnapshot();
|
|
2133
|
+
return {
|
|
2134
|
+
available: snapshot.status === "ready",
|
|
2135
|
+
writable: snapshot.writable,
|
|
2136
|
+
dirty: this.draft.trim() !== "",
|
|
2137
|
+
saving: this.saving,
|
|
2138
|
+
failed: this.failed,
|
|
2139
|
+
apiKey: this.draft,
|
|
2140
|
+
apiKeyConfigured: this.credential.configured,
|
|
2141
|
+
apiKeyWritable: this.credential.writable
|
|
2142
|
+
};
|
|
2143
|
+
}
|
|
2144
|
+
publish() {
|
|
2145
|
+
this.store.set(this.projection());
|
|
2146
|
+
}
|
|
2147
|
+
async readCredential() {
|
|
2148
|
+
let response;
|
|
2149
|
+
try {
|
|
2150
|
+
response = await this.api.credentials.describe({ refs: [SILICONFLOW_API_KEY_REF] });
|
|
2151
|
+
} catch {
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
if (!response.result.ok) return;
|
|
2155
|
+
const view = response.result.value.credentials[SILICONFLOW_API_KEY_REF];
|
|
2156
|
+
this.credential = {
|
|
2157
|
+
configured: view?.configured ?? false,
|
|
2158
|
+
writable: view?.writable ?? true
|
|
2159
|
+
};
|
|
2160
|
+
this.publish();
|
|
2161
|
+
}
|
|
2162
|
+
async save() {
|
|
2163
|
+
const value = this.draft.trim();
|
|
2164
|
+
if (value === "" || this.saving || !this.scope.getSnapshot().writable || !this.credential.writable) return;
|
|
2165
|
+
this.saving = true;
|
|
2166
|
+
this.failed = false;
|
|
2167
|
+
this.publish();
|
|
2168
|
+
try {
|
|
2169
|
+
if (!(await this.api.credentials.set({
|
|
2170
|
+
ref: "SILICONFLOW_API_KEY",
|
|
2171
|
+
value
|
|
2172
|
+
})).result.ok) {
|
|
2173
|
+
this.failed = true;
|
|
2174
|
+
return;
|
|
2175
|
+
}
|
|
2176
|
+
await this.readCredential();
|
|
2177
|
+
if (this.credential.configured) this.draft = "";
|
|
2178
|
+
else this.failed = true;
|
|
2179
|
+
} catch {
|
|
2180
|
+
this.failed = true;
|
|
2181
|
+
} finally {
|
|
2182
|
+
this.saving = false;
|
|
2183
|
+
this.publish();
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
1897
2186
|
};
|
|
1898
2187
|
//#endregion
|
|
1899
2188
|
//#region ../ui-voice/src/client/index.ts
|
|
@@ -1904,7 +2193,9 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
1904
2193
|
"sessions",
|
|
1905
2194
|
"workspaces",
|
|
1906
2195
|
"locale",
|
|
1907
|
-
"remote"
|
|
2196
|
+
"remote",
|
|
2197
|
+
"connection",
|
|
2198
|
+
"settingsScope"
|
|
1908
2199
|
];
|
|
1909
2200
|
/**
|
|
1910
2201
|
* The Harness model-selection UI intentionally hides addressed children. Voice
|
|
@@ -1949,6 +2240,7 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
1949
2240
|
}
|
|
1950
2241
|
/** Mount root transport controls and durable Voice conversation renderers. @param ctx - browser context. */
|
|
1951
2242
|
function apply(ctx) {
|
|
2243
|
+
const vocoSettings = new VocoSettingsController(ctx.settingsScope.bind({ namespace: VOCO_SETTINGS_NAMESPACE }), ctx.get("connection").api);
|
|
1952
2244
|
const controller = new VoiceController({ onConversationStarted: () => {
|
|
1953
2245
|
refreshSessions(ctx);
|
|
1954
2246
|
} });
|
|
@@ -2053,6 +2345,9 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
2053
2345
|
zh,
|
|
2054
2346
|
en
|
|
2055
2347
|
}), "ui-voice: dictionaries");
|
|
2348
|
+
ctx.effect(() => ctx.remote.$on("credentials/reference-updated", (ref) => {
|
|
2349
|
+
vocoSettings.refreshCredential(ref);
|
|
2350
|
+
}), "ui-voice: credential invalidations");
|
|
2056
2351
|
ctx.effect(() => async () => {
|
|
2057
2352
|
await controller.stop();
|
|
2058
2353
|
}, "ui-voice: transport teardown");
|
|
@@ -2098,6 +2393,12 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
|
|
|
2098
2393
|
locale: NS,
|
|
2099
2394
|
inject: delegationInjected
|
|
2100
2395
|
}, VoiceDelegationView));
|
|
2396
|
+
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
|
2397
|
+
name: "settings.plugin.item",
|
|
2398
|
+
key: VOCO_SETTINGS_NAMESPACE,
|
|
2399
|
+
locale: NS,
|
|
2400
|
+
inject: () => vocoSettings.inject()
|
|
2401
|
+
}, VocoSettingsCard));
|
|
2101
2402
|
}
|
|
2102
2403
|
/** Archive-manager archives one requested ID; Voice treats that state as
|
|
2103
2404
|
* inherited by every descendant without mutating the third-party archive set. */
|