@flowingspring/dsh-voco 0.3.11 → 0.3.13

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.en.md ADDED
@@ -0,0 +1,156 @@
1
+ # dsh-voco
2
+
3
+ English | [中文](README.md)
4
+
5
+ `dsh-voco` is a voice conversation plugin for the DeepSeek Harness (DSH) Web UI. Speak a request naturally and work that needs project tools is delegated to a background Agent. The complete task report stays in the DSH task UI while Voice speaks a concise result.
6
+
7
+ The plugin uses SiliconFlow cloud speech recognition and Edge TTS. It is not a standalone browser extension and does not require a separate background service.
8
+
9
+ ## Prerequisites
10
+
11
+ - Node.js 22.19 or newer (used by the DSH CLI).
12
+ - A DSH Web profile that can start successfully.
13
+ - A SiliconFlow API key. Voco uses the currently free [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra) speech-to-text model, but every user still needs their own key. Current availability and pricing are governed by the SiliconFlow model page.
14
+ - A modern browser with microphone support.
15
+
16
+ Install the DSH CLI first if it is not already available:
17
+
18
+ ```powershell
19
+ npm install -g @deepseek-ai/dsh
20
+ ```
21
+
22
+ ## Option 1: Install from npm (recommended)
23
+
24
+ This is the intended path for regular users. It installs the one public plugin package without downloading or editing this repository:
25
+
26
+ ```powershell
27
+ dsh plugin --profile web add @flowingspring/dsh-voco
28
+ ```
29
+
30
+ Start the DSH Web UI:
31
+
32
+ ```powershell
33
+ dsh web
34
+ ```
35
+
36
+ Open the local URL printed by DSH, click the microphone in a session, and allow microphone access in the browser.
37
+
38
+ ## Option 2: Install from a GitHub Release
39
+
40
+ GitHub Releases provide the same prebuilt plugin package as npm. No source checkout or pnpm development environment is required:
41
+
42
+ ```powershell
43
+ dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.13/flowingspring-dsh-voco-0.3.13.tgz
44
+ ```
45
+
46
+ Release page: [v0.3.13](https://github.com/lgquan/dsh-voco/releases/tag/v0.3.13)
47
+
48
+ Whichever installation method you choose, start the Web UI through DSH:
49
+
50
+ ```powershell
51
+ dsh web
52
+ ```
53
+
54
+ ## Configure the SiliconFlow API key
55
+
56
+ The only required secret is `SILICONFLOW_API_KEY`. Get your own key from the [SiliconFlow console](https://siliconflow.cn/). 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. Never put a real key in source code, commit it to GitHub, or share it with other users.
57
+
58
+ ### Recommended: DSH settings
59
+
60
+ After starting DSH, open **Settings → Plugins → Plugin configuration**, expand **Voice Assistant (Voco)**, enter the API key, and save. The key is written to the DSH credentials store rather than the regular settings file, and the UI never reads the secret back. Start or reconnect Voice after saving.
61
+
62
+ Environment variables and `.env` remain supported for automation and existing deployments.
63
+
64
+ ### Temporary: current PowerShell session
65
+
66
+ Set the variable in the same terminal that starts DSH:
67
+
68
+ ```powershell
69
+ $env:SILICONFLOW_API_KEY = "sk-your-api-key"
70
+ dsh web
71
+ ```
72
+
73
+ The value disappears when that terminal closes.
74
+
75
+ ### Persistent: DSH user environment file
76
+
77
+ Create `.env` in the DSH user directory. On Windows the default path is `%USERPROFILE%\.dsh\.env` (or `$DSH_HOME/.env` when `DSH_HOME` is set):
78
+
79
+ ```dotenv
80
+ SILICONFLOW_API_KEY=sk-your-api-key
81
+ ```
82
+
83
+ You may also create `.env` in the directory from which you run `dsh web`. The DSH credentials service reads these environment layers, and the plugin resolves `SILICONFLOW_API_KEY` through that service for each new voice connection. Do not enter the npm installation directory or edit files under `node_modules`.
84
+
85
+ An already inherited environment variable takes precedence, followed by the DSH credentials store and then `.env` fallbacks. Restart `dsh web` after changing `.env`, because the environment is loaded once per process.
86
+
87
+ ## After installation
88
+
89
+ 1. Run `dsh web` and open the DSH Web UI.
90
+ 2. Create or select a session.
91
+ 3. Click the microphone and grant browser permission.
92
+ 4. Speak naturally. About 1.5 seconds of continuous silence ends an utterance and sends it to cloud recognition. You can also hold the microphone for about 400 ms to use push-to-talk; release it to submit only that utterance. A disconnected session stays muted after a push-to-talk submission so its spoken reply can arrive.
93
+ 5. Ordinary conversation is handled in the frontend; work that needs project files, Shell, or other tools is delegated to the background Agent.
94
+
95
+ Voice sessions support interruption, reconnects, and history restoration. Each Voice Session keeps its own background Agent Session binding. When the context rotation threshold is reached, Voco creates a new child session for later tasks while keeping it under the same Voice Session.
96
+
97
+ ## Update
98
+
99
+ Update from npm:
100
+
101
+ ```powershell
102
+ dsh plugin --profile web add @flowingspring/dsh-voco
103
+ ```
104
+
105
+ You can also install a specific GitHub Release `.tgz` URL. Restart `dsh web` after updating.
106
+
107
+ ## Uninstall
108
+
109
+ ```powershell
110
+ dsh plugin --profile web remove @flowingspring/dsh-voco
111
+ ```
112
+
113
+ Uninstalling the plugin does not remove a saved API key. To remove it 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.
114
+
115
+ Uninstalling the plugin does not delete existing DSH sessions or Voice history. Confirm the relevant data directory before removing any stored data manually.
116
+
117
+ ## Highlights
118
+
119
+ - SiliconFlow's free [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra) cloud speech-to-text model.
120
+ - Edge TTS `zh-CN-XiaoxiaoNeural` voice output.
121
+ - Voice, typed messages, and background Agent tasks in one DSH session.
122
+ - Immediate acknowledgement before delegation; full reports remain in the task UI.
123
+ - Voice binding survives navigation, reconnects, and DSH restarts.
124
+ - Optional integration with `@flowingspring/dsh-workspace-memory` for Workspace memory.
125
+
126
+ ## Troubleshooting
127
+
128
+ ### Missing API key when clicking the microphone
129
+
130
+ Make sure the DSH process can read `SILICONFLOW_API_KEY`. After creating or changing `.env`, stop the old DSH process and run `dsh web` again.
131
+
132
+ ### No microphone or audio output
133
+
134
+ Check browser microphone permission and the system input device. Use the page served by `dsh web`; do not open an HTML file directly.
135
+
136
+ ### Recognition fails or takes a long time
137
+
138
+ Speech recognition needs network access to SiliconFlow. Check connectivity, key validity, account quota, and the latency of the selected model and provider.
139
+
140
+ ### Tuning silence detection
141
+
142
+ Advanced settings live in the plugin profile's `cordis.patch.yml`, including `silenceDurationMs`, `speechThreshold`, `minSpeechDurationMs`, and `maxUtteranceMs`. Most users can keep the defaults.
143
+
144
+ ## Optional Workspace Memory
145
+
146
+ Workspace Memory is not required by Voco. Install `@flowingspring/dsh-workspace-memory` separately when needed; Voco also works by itself. See that project's documentation for its own installation and configuration.
147
+
148
+ ## Development and support
149
+
150
+ - Source and issues: [GitHub](https://github.com/lgquan/dsh-voco)
151
+ - npm package: [`@flowingspring/dsh-voco`](https://www.npmjs.com/package/@flowingspring/dsh-voco)
152
+ - Architecture notes: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
153
+
154
+ ## License
155
+
156
+ [MIT](LICENSE)
package/README.md CHANGED
@@ -1,108 +1,156 @@
1
- # `@flowingspring/dsh-voco`
1
+ # dsh-voco
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@flowingspring/dsh-voco.svg)](https://www.npmjs.com/package/@flowingspring/dsh-voco)
4
- [![license](https://img.shields.io/npm/l/@flowingspring/dsh-voco.svg)](https://github.com/lgquan/dsh-voco/blob/master/LICENSE)
3
+ [English](README.en.md) | 中文
5
4
 
6
- English | [中文](README.zh.md)
5
+ `dsh-voco` 是面向 DeepSeek Harness(DSH)Web UI 的语音对话插件。它让你用自然语言说出需求,并将需要项目工具的工作委派给后台 Agent;完整任务报告仍保留在 DSH 会话中,语音只播报简洁结果。
7
6
 
8
- Recoverable, interruptible voice conversations for the DeepSeek Harness (DSH) Web UI. Voco uses SiliconFlow cloud speech recognition and Edge TTS, and delegates work that needs tools to a background Agent.
7
+ 插件使用硅基流动云端语音识别和 Edge TTS。它不是独立的浏览器扩展,也不需要单独运行一个后台服务。
9
8
 
10
- ## Install
9
+ ## 安装前准备
11
10
 
12
- ### npm (recommended)
11
+ - Node.js 22.19 或更高版本(安装 DSH CLI 时使用)。
12
+ - 一个已经可以运行的 DSH Web profile。
13
+ - 一个硅基流动 API Key。插件使用当前免费的语音转文字模型 [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra),但仍需用户自行申请 Key;免费状态和使用规则以硅基流动模型页面为准。
14
+ - 支持麦克风的现代浏览器。
13
15
 
14
- Install the DSH CLI first:
16
+ 如果还没有 DSH CLI,先安装:
15
17
 
16
18
  ```powershell
17
19
  npm install -g @deepseek-ai/dsh
18
20
  ```
19
21
 
20
- Add the plugin to the Web profile and start it:
22
+ ## 方式一:从 npm 安装(推荐)
23
+
24
+ 这是普通用户最简单的安装方式。只安装公开的单一插件包,不需要下载或修改本仓库源码:
21
25
 
22
26
  ```powershell
23
27
  dsh plugin --profile web add @flowingspring/dsh-voco
28
+ ```
29
+
30
+ 安装完成后启动 DSH Web:
31
+
32
+ ```powershell
24
33
  dsh web
25
34
  ```
26
35
 
27
- ### GitHub Release
36
+ 打开终端显示的本地地址,在会话中点击麦克风并允许浏览器使用麦克风即可。
37
+
38
+ ## 方式二:通过 GitHub Release 安装
28
39
 
29
- GitHub Releases provide a prebuilt plugin package; no source checkout or pnpm installation is required:
40
+ GitHub Release 提供和 npm 相同的预构建插件包,不需要 clone 源码或准备 pnpm 开发环境:
30
41
 
31
42
  ```powershell
32
- dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.11/flowingspring-dsh-voco-0.3.11.tgz
43
+ dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.13/flowingspring-dsh-voco-0.3.13.tgz
33
44
  ```
34
45
 
35
- Release page: [v0.3.11](https://github.com/lgquan/dsh-voco/releases/tag/v0.3.11)
46
+ Release 页面:[v0.3.13](https://github.com/lgquan/dsh-voco/releases/tag/v0.3.13)
47
+
48
+ 无论选择哪种安装方式,最后都通过 DSH 启动 Web UI:
49
+
50
+ ```powershell
51
+ dsh web
52
+ ```
53
+
54
+ ## 配置硅基流动 API Key
55
+
56
+ 插件只需要一个密钥:`SILICONFLOW_API_KEY`。请先在[硅基流动控制台](https://siliconflow.cn/)申请自己的 API Key。语音转文字使用硅基流动当前免费的 [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra);免费状态和使用规则以后续模型页面为准。不要把真实密钥写进源码、提交到 GitHub,或发送给其他人。
36
57
 
37
- ## Configure the API key
58
+ ### 推荐配置:DSH 设置页面
38
59
 
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.
60
+ 启动 DSH 后打开“设置 插件 插件配置”,展开“语音助手(Voco)”,填写 API Key 并保存。密钥写入 DSH 的凭据库,不会写进普通设置文件,界面也不会读回密钥明文。保存后重新开启或重连语音即可生效。
40
61
 
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.
62
+ 下面的环境变量和 `.env` 方式继续保留,适合自动化或已有部署。
42
63
 
43
- Environment variables and `.env` remain supported for compatibility and automation.
64
+ ### 临时配置:当前 PowerShell 会话
44
65
 
45
- For a temporary setting, use the same PowerShell session that starts DSH:
66
+ 在启动 DSH 的同一个终端中设置:
46
67
 
47
68
  ```powershell
48
69
  $env:SILICONFLOW_API_KEY = "sk-your-api-key"
49
70
  dsh web
50
71
  ```
51
72
 
52
- For a persistent setting, create `.env` in the DSH user directory: `%USERPROFILE%\.dsh\.env` on Windows, or `$DSH_HOME/.env` when `DSH_HOME` is set:
73
+ 关闭该终端后,变量会失效。
74
+
75
+ ### 持久配置:DSH 用户环境文件
76
+
77
+ 可以创建 DSH 用户目录下的 `.env`。默认位置是 Windows 的 `%USERPROFILE%\.dsh\.env`(如果设置了 `DSH_HOME`,则使用 `$DSH_HOME/.env`):
53
78
 
54
79
  ```dotenv
55
80
  SILICONFLOW_API_KEY=sk-your-api-key
56
81
  ```
57
82
 
58
- You may also put `.env` in the directory from which you run `dsh web`. Restart DSH after changing it. Never edit the npm installation directory or files under `node_modules`, and never commit a real key to GitHub.
83
+ 也可以在执行 `dsh web` 的当前目录创建 `.env`。DSH 凭据服务会读取这些环境层,插件在每次新建语音连接时通过凭据服务解析 `SILICONFLOW_API_KEY`。无需进入 npm 安装目录,也不要修改 `node_modules` 中的文件。
84
+
85
+ 如果同时设置了系统环境变量、DSH 凭据库和 `.env`,已经继承的环境变量优先,其次是 DSH 凭据库。修改 `.env` 后请重启 `dsh web`,因为环境在进程启动时读取一次。
86
+
87
+ ## 安装后怎么使用
59
88
 
60
- ## First use
89
+ 1. 运行 `dsh web` 并打开 DSH Web UI。
90
+ 2. 新建或选择一个会话。
91
+ 3. 点击麦克风按钮并允许浏览器权限。
92
+ 4. 直接说话;连续静音约 1.5 秒后,当前语句会提交给云端识别。也可以长按麦克风约 400 毫秒按住说话,松手后只提交这一段;未连接时长按会在提交后保持静音,以便接收语音回复。
93
+ 5. 普通聊天由前台处理,需要读写项目或运行工具的工作会交给后台 Agent。
61
94
 
62
- 1. Run `dsh web` and open the DSH Web UI.
63
- 2. Create or select a session, click the microphone, and grant browser permission.
64
- 3. Speak naturally. About 1.5 seconds of continuous silence submits an utterance.
65
- 4. Ordinary conversation is answered in the frontend; work that needs project tools is delegated to the background Agent.
95
+ 语音会话可以被打断、断线重连和恢复历史。每个语音会话会持续绑定自己的后台 Agent Session;上下文达到轮换阈值时,插件会为后续任务创建新的子会话,但仍归属于同一语音会话。
66
96
 
67
- Each Voice Session keeps its own background Agent Session binding. When the context rotation threshold is reached, later tasks automatically use a new child session that remains associated with the original Voice Session.
97
+ ## 更新
68
98
 
69
- ## Update
99
+ 使用 npm 更新到最新版本:
70
100
 
71
101
  ```powershell
72
102
  dsh plugin --profile web add @flowingspring/dsh-voco
73
103
  ```
74
104
 
75
- You can also install a specific GitHub Release. Restart `dsh web` after updating.
105
+ 也可以改用指定的 GitHub Release `.tgz` 地址。更新后重启 `dsh web`。
76
106
 
77
- ## Uninstall
107
+ ## 卸载
78
108
 
79
109
  ```powershell
80
110
  dsh plugin --profile web remove @flowingspring/dsh-voco
81
111
  ```
82
112
 
83
- Uninstalling does not delete DSH sessions or Voice history.
113
+ 卸载插件不会自动删除已经保存的 API Key。需要彻底清除时,从 `%USERPROFILE%\.dsh\.credentials.yaml`(设置了 `DSH_HOME` 时为 `$DSH_HOME/.credentials.yaml`)的 `refs` 下删除 `SILICONFLOW_API_KEY`,并同时清理系统环境变量或 `.env` 中的同名配置。
114
+
115
+ 卸载插件不会删除已经保存的 DSH 会话和语音历史;如需清理数据,请先确认对应数据目录后再手动处理。
116
+
117
+ ## 主要能力
118
+
119
+ - SiliconFlow 免费模型 [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra) 云端语音转文字。
120
+ - Edge TTS `zh-CN-XiaoxiaoNeural` 中文语音回复。
121
+ - 语音、文字和后台 Agent 任务可以在同一 DSH 会话中协作。
122
+ - 委派前即时播报确认语,完整报告保留在任务界面。
123
+ - 页面切换、断线重连和 DSH 重启后恢复语音会话绑定。
124
+ - 可选接入 `@flowingspring/dsh-workspace-memory`;语音主会话和每个完成的委派子任务都会进入同一个 Workspace 长期记忆范围。
125
+
126
+ ## 常见问题
127
+
128
+ ### 点击麦克风提示缺少 API Key
129
+
130
+ 确认启动 DSH 的进程能读到 `SILICONFLOW_API_KEY`。如果刚创建或修改了 `.env`,先停止旧的 DSH 进程,再重新运行 `dsh web`。
131
+
132
+ ### 浏览器没有声音或无法录音
133
+
134
+ 检查当前页面是否获得麦克风权限、系统输入设备是否正常,并确认使用的是 `dsh web` 提供的页面,而不是直接打开 HTML 文件。
135
+
136
+ ### 识别失败或等待时间较长
84
137
 
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.
138
+ 语音识别需要访问硅基流动网络服务。请检查网络、API Key 有效期、账户额度,以及所选模型和 Provider 的响应延迟。
86
139
 
87
- ## Features
140
+ ### 想调整静音和起音阈值
88
141
 
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.
90
- - Edge TTS `zh-CN-XiaoxiaoNeural` voice responses.
91
- - Interruption, navigation, reconnects, and restored history.
92
- - Immediate acknowledgement before delegation; full reports remain in the DSH task UI.
93
- - Optional `@flowingspring/dsh-workspace-memory` integration for both the source Voice Session and every completed delegated child task.
142
+ 高级参数位于插件 profile `cordis.patch.yml`,包括 `silenceDurationMs`、`speechThreshold`、`minSpeechDurationMs` `maxUtteranceMs`。普通用户通常不需要修改这些参数。
94
143
 
95
- ## Troubleshooting
144
+ ## 可选 Workspace Memory
96
145
 
97
- - **Missing API key**: verify that `SILICONFLOW_API_KEY` is visible to the DSH process; restart `dsh web` after changing `.env`.
98
- - **Microphone unavailable**: check browser permission and the system input device, and make sure the page is served by `dsh web`.
99
- - **Recognition fails or is slow**: check network access, key validity, SiliconFlow quota, and model/provider latency.
146
+ 长期记忆不是 Voco 的必需依赖。需要时另外安装 `@flowingspring/dsh-workspace-memory`;只安装 Voco 也可以独立使用。安装 Memory 后,完成的委派任务会提交用户原始请求和最终可见结果,不会提交 reasoning、工具日志或注入上下文。Memory 插件的安装和配置请参阅其项目文档。
100
147
 
101
- ## Links
148
+ ## 开发与反馈
102
149
 
103
- - [GitHub source and issues](https://github.com/lgquan/dsh-voco)
104
- - [npm package](https://www.npmjs.com/package/@flowingspring/dsh-voco)
150
+ - 源码与问题反馈:[GitHub](https://github.com/lgquan/dsh-voco)
151
+ - npm 包:[`@flowingspring/dsh-voco`](https://www.npmjs.com/package/@flowingspring/dsh-voco)
152
+ - 架构说明:[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
105
153
 
106
- ## License
154
+ ## 许可证
107
155
 
108
156
  [MIT](LICENSE)
package/cordis.patch.yml CHANGED
@@ -1,29 +1,29 @@
1
- # Voice interaction mode layered after dsh-base and dsh-web-app.
2
- - insert:
1
+ # Voice interaction mode layered after dsh-base and dsh-web-app.
2
+ - insert:
3
3
  - id: llm-tool-call-compat
4
4
  name: '@flowingspring/dsh-voco/llm-tool-call-compat'
5
5
 
6
6
  - id: voice
7
7
  name: '@flowingspring/dsh-voco/voice'
8
- config:
9
- provider: local
10
-
8
+ config:
9
+ provider: local
10
+
11
11
  - id: voice-local
12
12
  name: '@flowingspring/dsh-voco/voice-local'
13
- config:
14
- interactionMode: frontend-agent
15
- inputSampleRate: 16000
16
- outputSampleRate: 48000
17
- ttsRate: '+20%'
18
- silenceDurationMs: 1500
19
- speechThreshold: 0.015
20
- minSpeechDurationMs: 250
21
- maxUtteranceMs: 60000
22
-
13
+ config:
14
+ interactionMode: frontend-agent
15
+ inputSampleRate: 16000
16
+ outputSampleRate: 48000
17
+ ttsRate: '+20%'
18
+ silenceDurationMs: 1500
19
+ speechThreshold: 0.015
20
+ minSpeechDurationMs: 250
21
+ maxUtteranceMs: 60000
22
+
23
23
  - id: voice-assistant
24
24
  name: '@flowingspring/dsh-voco/voice-assistant'
25
- config:
26
- maxPendingObservations: 64
25
+ config:
26
+ maxPendingObservations: 64
27
27
  restoreConversation: true
28
28
  memoryRecallTimeoutMs: 250
29
29
  maxRestoredUtterances: 24
@@ -32,16 +32,16 @@
32
32
  taskSessionRotationReserveTokens: 2048
33
33
  taskSessionHandoffMaxChars: 12000
34
34
  completedAnnouncement: 任务已完成。
35
- failedAnnouncement: 任务失败了,请查看屏幕上的错误信息。
36
- cancelledAnnouncement: 任务已取消。
37
- interruptedAnnouncement: 上次任务因服务关闭而中断,没有自动重放。你可以告诉我是否继续。
38
-
35
+ failedAnnouncement: 任务失败了,请查看屏幕上的错误信息。
36
+ cancelledAnnouncement: 任务已取消。
37
+ interruptedAnnouncement: 上次任务因服务关闭而中断,没有自动重放。你可以告诉我是否继续。
38
+
39
39
  - id: voice-web
40
40
  name: '@flowingspring/dsh-voco/voice-web'
41
- inject: [webRuntime]
42
- config:
43
- trustedHosts: !!js ctx.webRuntime.trustedHosts
44
- maxAudioFrameBytes: 65536
45
-
41
+ inject: [webRuntime]
42
+ config:
43
+ trustedHosts: !!js ctx.webRuntime.trustedHosts
44
+ maxAudioFrameBytes: 65536
45
+
46
46
  - id: ui-voice
47
47
  name: '@flowingspring/dsh-voco'
package/lib/client.js CHANGED
@@ -21,12 +21,12 @@ window.__ModuleLoader__.load({
21
21
  var VoiceControl_module_css_default = {
22
22
  "voice-pulse": "TFZsua_voice-pulse",
23
23
  "active": "TFZsua_active",
24
- "controls": "TFZsua_controls",
24
+ "interruptButton": "TFZsua_interruptButton",
25
25
  "button": "TFZsua_button",
26
- "interruptButton": "TFZsua_interruptButton"
26
+ "controls": "TFZsua_controls"
27
27
  };
28
28
  //#endregion
29
- //#region ../ui-voice/src/client/VoiceControl.tsx
29
+ //#region packages/ui-voice/src/client/VoiceControl.tsx
30
30
  /** Start a fresh Voice Session from this Session's location or control the active connection. */
31
31
  function VoiceControl({ sessionId, useVoice, startVoice, retryVoice, beginPushToTalk, endPushToTalk, setVoiceMuted, t, interruptResponse }) {
32
32
  const state = useVoice((snapshot) => snapshot.state);
@@ -191,7 +191,7 @@ window.__ModuleLoader__.load({
191
191
  });
192
192
  }
193
193
  //#endregion
194
- //#region ../ui-voice/src/client/session-archive.ts
194
+ //#region packages/ui-voice/src/client/session-archive.ts
195
195
  /**
196
196
  * Returns whether a session is archived itself or inherits archive state from
197
197
  * any known ancestor. The optional fallback resolves a parent when the
@@ -222,26 +222,26 @@ window.__ModuleLoader__.load({
222
222
  document.head.appendChild(tag);
223
223
  }
224
224
  var VoiceNodeViews_module_css_default = {
225
- "taskDetails": "Kt2smW_taskDetails",
226
- "taskUpdate": "Kt2smW_taskUpdate",
227
- "utterance": "Kt2smW_utterance",
228
225
  "miniWave": "Kt2smW_miniWave",
229
226
  "voiceBadge": "Kt2smW_voiceBadge",
230
- "taskCard": "Kt2smW_taskCard",
231
- "taskTitle": "Kt2smW_taskTitle",
232
- "taskChevron": "Kt2smW_taskChevron",
233
- "bubble": "Kt2smW_bubble",
234
- "taskDot": "Kt2smW_taskDot",
235
- "taskInput": "Kt2smW_taskInput",
236
- "taskStatus": "Kt2smW_taskStatus",
237
227
  "taskSummary": "Kt2smW_taskSummary",
228
+ "taskStatus": "Kt2smW_taskStatus",
229
+ "taskDot": "Kt2smW_taskDot",
230
+ "taskCancel": "Kt2smW_taskCancel",
231
+ "bubble": "Kt2smW_bubble",
232
+ "taskDetails": "Kt2smW_taskDetails",
238
233
  "taskLink": "Kt2smW_taskLink",
234
+ "taskUpdate": "Kt2smW_taskUpdate",
235
+ "taskActions": "Kt2smW_taskActions",
236
+ "taskChevron": "Kt2smW_taskChevron",
237
+ "taskInput": "Kt2smW_taskInput",
238
+ "taskTitle": "Kt2smW_taskTitle",
239
+ "utterance": "Kt2smW_utterance",
239
240
  "meta": "Kt2smW_meta",
240
- "taskCancel": "Kt2smW_taskCancel",
241
- "taskActions": "Kt2smW_taskActions"
241
+ "taskCard": "Kt2smW_taskCard"
242
242
  };
243
243
  //#endregion
244
- //#region ../ui-voice/src/client/VoiceNodeViews.tsx
244
+ //#region packages/ui-voice/src/client/VoiceNodeViews.tsx
245
245
  /** Render a durable Voice utterance while replacing its unsettled text with live WebSocket deltas. */
246
246
  function VoiceUtteranceView({ node, sessionId, useVoice, t }) {
247
247
  const liveText = useVoice((snapshot) => snapshot.sessionId === sessionId ? snapshot.textById[String(node.data.utteranceId)]?.text : void 0);
@@ -377,13 +377,13 @@ window.__ModuleLoader__.load({
377
377
  }
378
378
  var VoiceOverlay_module_css_default = {
379
379
  "root": "GPPB2G_root",
380
- "status": "GPPB2G_status",
381
380
  "wave": "GPPB2G_wave",
382
381
  "voice-wave": "GPPB2G_voice-wave",
383
- "stop": "GPPB2G_stop"
382
+ "stop": "GPPB2G_stop",
383
+ "status": "GPPB2G_status"
384
384
  };
385
385
  //#endregion
386
- //#region ../ui-voice/src/client/VoiceOverlay.tsx
386
+ //#region packages/ui-voice/src/client/VoiceOverlay.tsx
387
387
  const STATE_KEYS = {
388
388
  connecting: "overlay.connecting",
389
389
  listening: "overlay.listening",
@@ -439,11 +439,11 @@ window.__ModuleLoader__.load({
439
439
  document.head.appendChild(tag);
440
440
  }
441
441
  var VoiceSessionMarkers_module_css_default = {
442
- "marker": "_0brRca_marker",
443
- "slot": "_0brRca_slot"
442
+ "slot": "_0brRca_slot",
443
+ "marker": "_0brRca_marker"
444
444
  };
445
445
  //#endregion
446
- //#region ../ui-voice/src/client/VoiceSessionMarkers.tsx
446
+ //#region packages/ui-voice/src/client/VoiceSessionMarkers.tsx
447
447
  /**
448
448
  * The workspace package owns the session-row renderer and filters addressed
449
449
  * subagent children from its top-level list. This decorator only adds the
@@ -550,33 +550,33 @@ window.__ModuleLoader__.load({
550
550
  document.head.appendChild(tag);
551
551
  }
552
552
  var VocoSettingsCard_module_css_default = {
553
- "readOnly": "G5LlXq_readOnly",
554
- "body": "G5LlXq_body",
553
+ "cardOpen": "G5LlXq_cardOpen",
555
554
  "fieldHead": "G5LlXq_fieldHead",
555
+ "providerDetail": "G5LlXq_providerDetail",
556
+ "card": "G5LlXq_card",
556
557
  "failed": "G5LlXq_failed",
557
- "chevron": "G5LlXq_chevron",
558
- "pending": "G5LlXq_pending",
559
- "discard": "G5LlXq_discard",
560
- "name": "G5LlXq_name",
561
- "footer": "G5LlXq_footer",
562
- "cardOpen": "G5LlXq_cardOpen",
563
- "save": "G5LlXq_save",
564
558
  "headText": "G5LlXq_headText",
565
559
  "chevronOpen": "G5LlXq_chevronOpen",
566
- "header": "G5LlXq_header",
567
- "badgeMuted": "G5LlXq_badgeMuted",
568
- "hint": "G5LlXq_hint",
569
- "providerDetail": "G5LlXq_providerDetail",
570
560
  "badge": "G5LlXq_badge",
571
- "input": "G5LlXq_input",
561
+ "save": "G5LlXq_save",
562
+ "pending": "G5LlXq_pending",
563
+ "badgeMuted": "G5LlXq_badgeMuted",
572
564
  "providerDetails": "G5LlXq_providerDetails",
565
+ "discard": "G5LlXq_discard",
566
+ "header": "G5LlXq_header",
567
+ "body": "G5LlXq_body",
568
+ "readOnly": "G5LlXq_readOnly",
569
+ "input": "G5LlXq_input",
570
+ "hint": "G5LlXq_hint",
571
+ "name": "G5LlXq_name",
572
+ "footer": "G5LlXq_footer",
573
573
  "field": "G5LlXq_field",
574
- "card": "G5LlXq_card",
574
+ "chevron": "G5LlXq_chevron",
575
575
  "description": "G5LlXq_description",
576
576
  "label": "G5LlXq_label"
577
577
  };
578
578
  //#endregion
579
- //#region ../ui-voice/src/client/VocoSettingsCard.tsx
579
+ //#region packages/ui-voice/src/client/VocoSettingsCard.tsx
580
580
  /** Official plugin-settings slot contribution for the Voco credential. */
581
581
  function VocoSettingsCard({ useVocoSettings, editApiKey, save, discard, t }) {
582
582
  const [open, setOpen] = (0, react.useState)(false);
@@ -690,7 +690,7 @@ window.__ModuleLoader__.load({
690
690
  });
691
691
  }
692
692
  //#endregion
693
- //#region ../ui-voice/src/client/voice-controller.ts
693
+ //#region packages/ui-voice/src/client/voice-controller.ts
694
694
  const INITIAL_SNAPSHOT = {
695
695
  state: "off",
696
696
  inputMuted: false,
@@ -1506,7 +1506,7 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
1506
1506
  node.start(start);
1507
1507
  }
1508
1508
  //#endregion
1509
- //#region ../ui-voice/src/client/voice-history.ts
1509
+ //#region packages/ui-voice/src/client/voice-history.ts
1510
1510
  const STORAGE_KEY = "dsh.voice.history.v1";
1511
1511
  function parseEntry(input) {
1512
1512
  if (typeof input !== "object" || input === null) return void 0;
@@ -1637,7 +1637,7 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
1637
1637
  }
1638
1638
  };
1639
1639
  //#endregion
1640
- //#region ../ui-voice/src/client/voice-text-submit.ts
1640
+ //#region packages/ui-voice/src/client/voice-text-submit.ts
1641
1641
  /** Routes the native composer through Voice while preserving its ordinary offline submission. */
1642
1642
  var VoiceTextSubmitBridge = class {
1643
1643
  voice;
@@ -1683,7 +1683,7 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
1683
1683
  }
1684
1684
  };
1685
1685
  //#endregion
1686
- //#region ../ui-voice/src/client/voice-definitions.ts
1686
+ //#region packages/ui-voice/src/client/voice-definitions.ts
1687
1687
  /** Fold one streamed utterance into a stable Chat node. */
1688
1688
  const voiceUtteranceDefinition = {
1689
1689
  kind: "voice-utterance",
@@ -1781,7 +1781,7 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
1781
1781
  }
1782
1782
  };
1783
1783
  //#endregion
1784
- //#region ../ui-voice/src/client/locales.ts
1784
+ //#region packages/ui-voice/src/client/locales.ts
1785
1785
  /** `voice` namespace dictionaries. */
1786
1786
  /** Dictionary namespace owned by this plugin. */
1787
1787
  const NS = "voice";
@@ -1886,7 +1886,7 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
1886
1886
  "settings.saveFailed": "The key could not be saved and was kept for you to retry."
1887
1887
  };
1888
1888
  //#endregion
1889
- //#region ../ui-voice/src/client/voco-settings-controller.ts
1889
+ //#region packages/ui-voice/src/client/voco-settings-controller.ts
1890
1890
  const VOCO_SETTINGS_NAMESPACE = "voice-local";
1891
1891
  const SILICONFLOW_API_KEY_REF = "SILICONFLOW_API_KEY";
1892
1892
  /** Bridges the voice-local namespace and the write-only DSH credentials API. */
@@ -1988,7 +1988,7 @@ registerProcessor('dsh-pcm-capture', DshPcmCaptureProcessor)
1988
1988
  }
1989
1989
  };
1990
1990
  //#endregion
1991
- //#region ../ui-voice/src/client/index.ts
1991
+ //#region packages/ui-voice/src/client/index.ts
1992
1992
  const inject = [
1993
1993
  "conversation",
1994
1994
  "conversationEvents",
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region lib/types/index.js
1
+ //#region packages/voice-app/src/index.ts
2
2
  /** Voice profile patch package. @module @flowingspring/dsh-voco */
3
3
  /** Runtime no-op; the package manifest exposes the patch layer. */
4
4
  function apply() {}
package/lib/invariant.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region lib/types/invariant.js
1
+ //#region packages/voice-app/src/invariant.ts
2
2
  const name = "voco-invariant";
3
3
  const inject = ["invariants"];
4
4
  /** No runtime invariant: this package is a static patch-list carrier. */
@@ -1,4 +1,4 @@
1
- //#region ../llm-tool-call-compat/src/index.ts
1
+ //#region packages/llm-tool-call-compat/src/index.ts
2
2
  /** Restore metadata omitted as empty strings by some OpenAI-compatible gateways. */
3
3
  function normalizeToolCallSseEvent(event, states) {
4
4
  if (!event.startsWith("data: ")) return event;
@@ -10,7 +10,7 @@ import { ReasoningEffortId, createUserMessage } from "@deepseek-ai/dsh-llm";
10
10
  import { resolveSessionPreset } from "@deepseek-ai/dsh-agent-presets";
11
11
  import { defineTool } from "@deepseek-ai/dsh-tools";
12
12
  import { KNOWN_SESSION_EVENT_TYPES, SessionId, foldRequestHeader, snapshotJsonValue } from "@deepseek-ai/dsh-session";
13
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
13
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js
14
14
  var _a$1;
15
15
  function $constructor(name, initializer, params) {
16
16
  function init(inst, def) {
@@ -69,7 +69,7 @@ function config(newConfig) {
69
69
  return globalConfig;
70
70
  }
71
71
  //#endregion
72
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js
72
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js
73
73
  function getEnumValues(entries) {
74
74
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
75
75
  return Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
@@ -383,7 +383,7 @@ function issue(...args) {
383
383
  return { ...iss };
384
384
  }
385
385
  //#endregion
386
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/errors.js
386
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/errors.js
387
387
  const initializer$1 = (inst, def) => {
388
388
  inst.name = "$ZodError";
389
389
  Object.defineProperty(inst, "_zod", {
@@ -443,7 +443,7 @@ function formatError(error, mapper = (issue) => issue.message) {
443
443
  return fieldErrors;
444
444
  }
445
445
  //#endregion
446
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/parse.js
446
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/parse.js
447
447
  const _parse = (_Err) => (schema, value, _ctx, _params) => {
448
448
  const ctx = _ctx ? {
449
449
  ..._ctx,
@@ -557,7 +557,7 @@ const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
557
557
  return _safeParseAsync(_Err)(schema, value, _ctx);
558
558
  };
559
559
  //#endregion
560
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/regexes.js
560
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/regexes.js
561
561
  /**
562
562
  * @deprecated CUID v1 is deprecated by its authors due to information leakage
563
563
  * (timestamps embedded in the id). Use {@link cuid2} instead.
@@ -621,7 +621,7 @@ const boolean$1 = /^(?:true|false)$/i;
621
621
  const lowercase = /^[^A-Z]*$/;
622
622
  const uppercase = /^[^a-z]*$/;
623
623
  //#endregion
624
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/checks.js
624
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/checks.js
625
625
  const $ZodCheck = /*@__PURE__*/ $constructor("$ZodCheck", (inst, def) => {
626
626
  var _a;
627
627
  inst._zod ?? (inst._zod = {});
@@ -983,7 +983,7 @@ const $ZodCheckOverwrite = /*@__PURE__*/ $constructor("$ZodCheckOverwrite", (ins
983
983
  };
984
984
  });
985
985
  //#endregion
986
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/doc.js
986
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/doc.js
987
987
  var Doc = class {
988
988
  constructor(args = []) {
989
989
  this.content = [];
@@ -1014,14 +1014,14 @@ var Doc = class {
1014
1014
  }
1015
1015
  };
1016
1016
  //#endregion
1017
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js
1017
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js
1018
1018
  const version = {
1019
1019
  major: 4,
1020
1020
  minor: 4,
1021
1021
  patch: 3
1022
1022
  };
1023
1023
  //#endregion
1024
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/schemas.js
1024
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/schemas.js
1025
1025
  const $ZodType = /*@__PURE__*/ $constructor("$ZodType", (inst, def) => {
1026
1026
  var _a;
1027
1027
  inst ?? (inst = {});
@@ -2198,7 +2198,7 @@ function handleRefineResult(result, payload, input, inst) {
2198
2198
  }
2199
2199
  }
2200
2200
  //#endregion
2201
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/registries.js
2201
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/registries.js
2202
2202
  var _a;
2203
2203
  var $ZodRegistry = class {
2204
2204
  constructor() {
@@ -2245,7 +2245,7 @@ function registry() {
2245
2245
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
2246
2246
  const globalRegistry = globalThis.__zod_globalRegistry;
2247
2247
  //#endregion
2248
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/api.js
2248
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/api.js
2249
2249
  // @__NO_SIDE_EFFECTS__
2250
2250
  function _string(Class, params) {
2251
2251
  return new Class({
@@ -2750,7 +2750,7 @@ function _check(fn, params) {
2750
2750
  return ch;
2751
2751
  }
2752
2752
  //#endregion
2753
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/to-json-schema.js
2753
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/to-json-schema.js
2754
2754
  function initializeContext(params) {
2755
2755
  let target = params?.target ?? "draft-2020-12";
2756
2756
  if (target === "draft-4") target = "draft-04";
@@ -3045,7 +3045,7 @@ const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params)
3045
3045
  return finalize(ctx, schema);
3046
3046
  };
3047
3047
  //#endregion
3048
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-processors.js
3048
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-processors.js
3049
3049
  const formatMap = {
3050
3050
  guid: "uuid",
3051
3051
  url: "uri",
@@ -3277,7 +3277,7 @@ const optionalProcessor = (schema, ctx, _json, params) => {
3277
3277
  seen.ref = def.innerType;
3278
3278
  };
3279
3279
  //#endregion
3280
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/iso.js
3280
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/iso.js
3281
3281
  const ZodISODateTime = /*@__PURE__*/ $constructor("ZodISODateTime", (inst, def) => {
3282
3282
  $ZodISODateTime.init(inst, def);
3283
3283
  ZodStringFormat.init(inst, def);
@@ -3307,7 +3307,7 @@ function duration(params) {
3307
3307
  return /* @__PURE__ */ _isoDuration(ZodISODuration, params);
3308
3308
  }
3309
3309
  //#endregion
3310
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/errors.js
3310
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/errors.js
3311
3311
  const initializer = (inst, issues) => {
3312
3312
  $ZodError.init(inst, issues);
3313
3313
  inst.name = "ZodError";
@@ -3329,7 +3329,7 @@ const initializer = (inst, issues) => {
3329
3329
  };
3330
3330
  const ZodRealError = /*@__PURE__*/ $constructor("ZodError", initializer, { Parent: Error });
3331
3331
  //#endregion
3332
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/parse.js
3332
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/parse.js
3333
3333
  const parse = /* @__PURE__ */ _parse(ZodRealError);
3334
3334
  const parseAsync = /* @__PURE__ */ _parseAsync(ZodRealError);
3335
3335
  const safeParse = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -3343,7 +3343,7 @@ const safeDecode = /* @__PURE__ */ _safeDecode(ZodRealError);
3343
3343
  const safeEncodeAsync = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
3344
3344
  const safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
3345
3345
  //#endregion
3346
- //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js
3346
+ //#region node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js
3347
3347
  const _installedGroups = /* @__PURE__ */ new WeakMap();
3348
3348
  function _installLazyMethods(inst, group, methods) {
3349
3349
  const proto = Object.getPrototypeOf(inst);
@@ -4129,7 +4129,7 @@ function superRefine(fn, params) {
4129
4129
  return /* @__PURE__ */ _superRefine(fn, params);
4130
4130
  }
4131
4131
  //#endregion
4132
- //#region ../../node_modules/.pnpm/@deepseek-ai+dsh-subagent@0_333a83db5ad7aba5051480205ed90428/node_modules/@deepseek-ai/dsh-subagent/lib/index.js
4132
+ //#region node_modules/.pnpm/@deepseek-ai+dsh-subagent@0_333a83db5ad7aba5051480205ed90428/node_modules/@deepseek-ai/dsh-subagent/lib/index.js
4133
4133
  const DESCRIPTOR_BASE_KEYS = [
4134
4134
  "version",
4135
4135
  "mode",
@@ -4298,7 +4298,7 @@ Object.freeze({
4298
4298
  persona: false
4299
4299
  });
4300
4300
  //#endregion
4301
- //#region ../voice-assistant/src/tool.ts
4301
+ //#region packages/voice-assistant/src/tool.ts
4302
4302
  const VOICE_MESSAGE_SECTION_ORDER = 118;
4303
4303
  /**
4304
4304
  * Install `send_voice_message` and its guidance into one delegated task Agent scope.
@@ -4401,7 +4401,7 @@ function installVoiceMessageTool(agentCtx, send, resolveDelegationId) {
4401
4401
  };
4402
4402
  }
4403
4403
  //#endregion
4404
- //#region ../voice-assistant/src/index.ts
4404
+ //#region packages/voice-assistant/src/index.ts
4405
4405
  /** Voice-to-Agent driver using ordinary followup, steer and cancel operations. @module @flowingspring/dsh-voice-assistant */
4406
4406
  const name = "voice-assistant";
4407
4407
  const inject = [
@@ -10,7 +10,7 @@ import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-sett
10
10
  import { mkdtemp, readFile, rm } from "node:fs/promises";
11
11
  import { tmpdir } from "node:os";
12
12
  import { EdgeTTS } from "node-edge-tts";
13
- //#region ../voice-local/src/edge-tts.ts
13
+ //#region packages/voice-local/src/edge-tts.ts
14
14
  const EDGE_TTS_VOICE = "zh-CN-XiaoxiaoNeural";
15
15
  const DEFAULT_EDGE_TTS_RATE = "+20%";
16
16
  /** Edge TTS adapter. Returns the service's MP3 bytes for browser decoding. */
@@ -47,7 +47,7 @@ function splitSpeechText(text) {
47
47
  return (normalized.match(/[^。!?!?;;::\n]+[。!?!?;;::]?|[^。!?!?;;::\n]+$/g) ?? [normalized]).map((part) => part.trim()).filter(Boolean);
48
48
  }
49
49
  //#endregion
50
- //#region ../voice-local/src/session.ts
50
+ //#region packages/voice-local/src/session.ts
51
51
  /** Provider session translating local speech events to the shared voice seam. */
52
52
  var LocalSession = class {
53
53
  backend;
@@ -246,7 +246,7 @@ function isTerminalTaskStatus(status) {
246
246
  return status === "completed" || status === "failed" || status === "cancelled" || status === "interrupted";
247
247
  }
248
248
  //#endregion
249
- //#region ../voice-local/src/siliconflow-asr.ts
249
+ //#region packages/voice-local/src/siliconflow-asr.ts
250
250
  const WAV_HEADER_BYTES = 44;
251
251
  /** Upload one completed PCM utterance to SiliconFlow and return its final transcript. */
252
252
  var SiliconFlowAsr = class {
@@ -306,7 +306,7 @@ function isRecord(value) {
306
306
  return typeof value === "object" && value !== null && !Array.isArray(value);
307
307
  }
308
308
  //#endregion
309
- //#region ../voice-local/src/node-backend.ts
309
+ //#region packages/voice-local/src/node-backend.ts
310
310
  const INPUT_SAMPLE_RATE = 16e3;
311
311
  /** Lightweight PCM silence detector plus SiliconFlow cloud ASR and Edge TTS. */
312
312
  var NodeSpeechBackend = class {
@@ -557,7 +557,7 @@ function errorMessage(error) {
557
557
  return error instanceof Error ? error.message : String(error);
558
558
  }
559
559
  //#endregion
560
- //#region ../voice-local/src/index.ts
560
+ //#region packages/voice-local/src/index.ts
561
561
  /** Silence-gated SiliconFlow cloud ASR with Edge TTS. */
562
562
  const name = "voice-local";
563
563
  const inject = ["voice"];
@@ -3,7 +3,7 @@ import { randomUUID } from "node:crypto";
3
3
  import z from "@deepseek-ai/schemastery";
4
4
  import { SessionId } from "@deepseek-ai/dsh-session";
5
5
  import WebSocket, { WebSocketServer } from "ws";
6
- //#region ../voice-web/src/loopback-hostname.ts
6
+ //#region packages/voice-web/src/loopback-hostname.ts
7
7
  /**
8
8
  * Browser-safe, zero-dependency loopback classification shared by the `/api`
9
9
  * Host fence and the package's `ctx.connection` state. The predicate stays
@@ -20,7 +20,7 @@ function isLoopbackHostname(hostname) {
20
20
  return parts.length === 4 && parts[0] === "127" && parts.every((part) => /^\d{1,3}$/.test(part) && Number(part) <= 255);
21
21
  }
22
22
  //#endregion
23
- //#region ../voice-web/src/api-request-trust.ts
23
+ //#region packages/voice-web/src/api-request-trust.ts
24
24
  function header(headers, name) {
25
25
  if (headers instanceof Headers) return headers.get(name) ?? void 0;
26
26
  const value = headers[name];
@@ -100,7 +100,7 @@ function isTrustedApiRequest(request, trustedHosts) {
100
100
  }
101
101
  }
102
102
  //#endregion
103
- //#region ../voice-web/src/index.ts
103
+ //#region packages/voice-web/src/index.ts
104
104
  /** Dedicated browser WebSocket carrier for realtime voice audio and events. @module @flowingspring/dsh-voice-web */
105
105
  const name = "voice-web";
106
106
  const inject = ["voice", "webServer"];
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { Service } from "@deepseek-ai/cordis";
3
3
  import z from "@deepseek-ai/schemastery";
4
- //#region ../voice/src/types.ts
4
+ //#region packages/voice/src/types.ts
5
5
  /**
6
6
  * Brand a raw id as a voice-session identity.
7
7
  * @param value - raw identity.
@@ -51,7 +51,7 @@ function VoiceTaskMessageId(value) {
51
51
  return value;
52
52
  }
53
53
  //#endregion
54
- //#region ../voice/src/index.ts
54
+ //#region packages/voice/src/index.ts
55
55
  /** Provider-neutral realtime voice session capability seam. @module @flowingspring/dsh-voice */
56
56
  /** Provider registry and connected-session coordinator. */
57
57
  var VoiceRuntime = class extends Service {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,mEAAmE;AACnE,wBAAgB,KAAK,IAAI,IAAI,CAAG"}
@@ -0,0 +1,4 @@
1
+ /** Voice profile patch package. @module @flowingspring/dsh-voco */
2
+ /** Runtime no-op; the package manifest exposes the patch layer. */
3
+ export function apply() { }
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,mEAAmE;AACnE,MAAM,UAAU,KAAK,KAAU,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariant.d.ts","sourceRoot":"","sources":["../../src/invariant.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,eAAO,MAAM,IAAI,mBAAmB,CAAA;AACpC,eAAO,MAAM,MAAM,UAAiB,CAAA;AAGpC,qFAAqF;AACrF,eAAO,MAAM,KAAK,GAAI,KAAK,OAAO,KAAG,OAAO,CAAC,MAAM,IAAI,CAAiF,CAAA"}
@@ -0,0 +1,7 @@
1
+ export const name = 'voco-invariant';
2
+ export const inject = ['invariants'];
3
+ /** No runtime invariant: this package is a static patch-list carrier. */
4
+ const install = () => { };
5
+ /** Register invariant ownership. @param ctx - runtime context. @returns disposer. */
6
+ export const apply = (ctx) => Promise.resolve(ctx.invariants.register('@flowingspring/dsh-voco', install));
7
+ //# sourceMappingURL=invariant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariant.js","sourceRoot":"","sources":["../../src/invariant.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,IAAI,GAAG,gBAAgB,CAAA;AACpC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,YAAY,CAAC,CAAA;AACpC,yEAAyE;AACzE,MAAM,OAAO,GAAuB,GAAG,EAAE,GAAE,CAAC,CAAA;AAC5C,qFAAqF;AACrF,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,GAAY,EAAuB,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAC,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
- {
1
+ {
2
2
  "name": "@flowingspring/dsh-voco",
3
3
  "description": "Persistent voice conversations for DSH with cloud speech recognition, Edge TTS, and background Agent delegation",
4
- "version": "0.3.11",
4
+ "version": "0.3.13",
5
5
  "keywords": [
6
6
  "deepseek-harness",
7
7
  "dsh",
@@ -15,18 +15,17 @@
15
15
  "bugs": {
16
16
  "url": "https://github.com/lgquan/dsh-voco/issues"
17
17
  },
18
- "publishConfig": {
19
- "access": "public"
20
- },
21
- "repository": {
22
- "type": "git",
23
- "url": "git+https://github.com/lgquan/dsh-voco.git",
24
- "directory": "packages/voice-app"
25
- },
26
- "type": "module",
27
- "main": "lib/index.js",
28
- "types": "lib/types/index.d.ts",
29
- "exports": {
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/lgquan/dsh-voco.git"
24
+ },
25
+ "type": "module",
26
+ "main": "lib/index.js",
27
+ "types": "lib/types/index.d.ts",
28
+ "exports": {
30
29
  ".": {
31
30
  "types": "./lib/types/index.d.ts",
32
31
  "default": "./lib/index.js"
@@ -45,35 +44,21 @@
45
44
  "./voice-web": "./lib/plugins/voice-web.js",
46
45
  "./cordis.patch.yml": "./cordis.patch.yml",
47
46
  "./package.json": "./package.json"
48
- },
49
- "files": [
50
- "lib/index.js",
51
- "lib/invariant.js",
52
- "lib/client.js",
53
- "lib/client.js.map",
54
- "lib/plugins/*.js",
55
- "cordis.patch.yml",
56
- "lib/types/**/*.d.ts"
57
- ],
58
- "license": "MIT",
59
- "dsh": {
60
- "bundle": {
61
- "patch": "./cordis.patch.yml"
62
- },
63
- "client": {
64
- "inject": [
65
- "@deepseek-ai/dsh-client-connection",
66
- "@deepseek-ai/dsh-client-locale",
67
- "@deepseek-ai/dsh-client-runtime",
68
- "@deepseek-ai/dsh-client-ui-settings",
69
- "@deepseek-ai/dsh-client-ui-settings-plugins",
70
- "@deepseek-ai/dsh-client-ui-conversation",
71
- "@deepseek-ai/dsh-client-ui-layout",
72
- "@deepseek-ai/dsh-client-ui-sidebar"
73
- ],
74
- "platform": "web"
75
- }
76
47
  },
48
+ "packageManager": "pnpm@11.7.0",
49
+ "engines": {
50
+ "node": "^22.19.0 || >=24.0.0"
51
+ },
52
+ "scripts": {
53
+ "build": "tsc -b && node scripts/copy-types.mjs && tsdown",
54
+ "prepare": "pnpm run build",
55
+ "test": "vitest run",
56
+ "typecheck": "tsc -b"
57
+ },
58
+ "files": [
59
+ "cordis.patch.yml",
60
+ "lib"
61
+ ],
77
62
  "dependencies": {
78
63
  "@deepseek-ai/schemastery": "^3.18.1",
79
64
  "node-edge-tts": "1.2.10",
@@ -107,39 +92,30 @@
107
92
  "react": "^18.2.0"
108
93
  },
109
94
  "devDependencies": {
110
- "@deepseek-ai/cordis": "^4.0.1",
111
- "@deepseek-ai/dsh-agent": "^0.1.1-rc.1",
112
- "@deepseek-ai/dsh-agent-default-model": "^0.1.1-rc.1",
113
- "@deepseek-ai/dsh-agent-presets": "^0.1.1-rc.1",
114
- "@deepseek-ai/dsh-brand": "^0.1.1-rc.1",
115
- "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.1",
116
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.1",
117
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
118
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
119
- "@deepseek-ai/dsh-client-ui-settings-plugins": "^0.1.1-rc.2",
120
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.1-rc.1",
121
- "@deepseek-ai/dsh-client-ui-layout": "^0.1.1-rc.1",
122
- "@deepseek-ai/dsh-client-ui-sidebar": "^0.1.1-rc.1",
123
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.1",
124
- "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.1",
125
- "@deepseek-ai/dsh-invariants": "^0.1.1-rc.1",
126
- "@deepseek-ai/dsh-credentials": "^0.1.1-rc.2",
127
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.1",
128
- "@deepseek-ai/dsh-session": "^0.1.1-rc.1",
129
- "@deepseek-ai/dsh-session-persistence": "^0.1.1-rc.1",
130
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
131
- "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.1",
132
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.1",
133
- "@deepseek-ai/dsh-workspace": "^0.1.1-rc.1",
134
- "@flowingspring/dsh-client-ui-voice": "workspace:*",
135
- "@flowingspring/dsh-llm-tool-call-compat": "workspace:*",
136
- "@flowingspring/dsh-voice": "workspace:*",
137
- "@flowingspring/dsh-voice-assistant": "workspace:*",
138
- "@flowingspring/dsh-voice-local": "workspace:*",
139
- "@flowingspring/dsh-voice-web": "workspace:*",
140
- "@types/react": "~18.3.1",
141
- "@types/ws": "^8.18.1",
142
- "react": "^18.2.0",
143
- "react-dom": "^18.2.0"
144
- }
95
+ "@types/node": "^22.20.0",
96
+ "jsdom": "^30.0.1",
97
+ "lightningcss": "^1.32.0",
98
+ "tsdown": "^0.22.2",
99
+ "typescript": "^6.0.3",
100
+ "vitest": "^4.1.11"
101
+ },
102
+ "dsh": {
103
+ "bundle": {
104
+ "patch": "./cordis.patch.yml"
105
+ },
106
+ "client": {
107
+ "inject": [
108
+ "@deepseek-ai/dsh-client-connection",
109
+ "@deepseek-ai/dsh-client-locale",
110
+ "@deepseek-ai/dsh-client-runtime",
111
+ "@deepseek-ai/dsh-client-ui-settings",
112
+ "@deepseek-ai/dsh-client-ui-settings-plugins",
113
+ "@deepseek-ai/dsh-client-ui-conversation",
114
+ "@deepseek-ai/dsh-client-ui-layout",
115
+ "@deepseek-ai/dsh-client-ui-sidebar"
116
+ ],
117
+ "platform": "web"
118
+ }
119
+ },
120
+ "license": "MIT"
145
121
  }
package/README.i18n.yaml DELETED
@@ -1,6 +0,0 @@
1
- # Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
2
- # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
- # after editing either side, bring the other along and re-record with:
4
- # pnpm run verify-translation-pairing --write packages/bundle/voice-app/README.md
5
- README.md: 3582129953c75938c6c08caa11526d5179f0631f
6
- README.zh.md: f7253637cf50cf5b9677bee512e45fdadd8cc712
package/README.zh.md DELETED
@@ -1,108 +0,0 @@
1
- # `@flowingspring/dsh-voco`
2
-
3
- [![npm version](https://img.shields.io/npm/v/@flowingspring/dsh-voco.svg)](https://www.npmjs.com/package/@flowingspring/dsh-voco)
4
- [![许可证](https://img.shields.io/npm/l/@flowingspring/dsh-voco.svg)](https://github.com/lgquan/dsh-voco/blob/master/LICENSE)
5
-
6
- [English](README.md) | 中文
7
-
8
- 面向 DeepSeek Harness(DSH)Web UI 的可恢复、可打断语音对话插件。它使用硅基流动云端语音识别和 Edge TTS,并把需要工具的工作委派给后台 Agent。
9
-
10
- ## 安装
11
-
12
- ### npm 安装(推荐)
13
-
14
- 先安装 DSH CLI:
15
-
16
- ```powershell
17
- npm install -g @deepseek-ai/dsh
18
- ```
19
-
20
- 将插件加入 Web profile 并启动:
21
-
22
- ```powershell
23
- dsh plugin --profile web add @flowingspring/dsh-voco
24
- dsh web
25
- ```
26
-
27
- ### GitHub Release 安装
28
-
29
- GitHub Release 提供已经构建好的插件包,不需要下载源码或安装 pnpm:
30
-
31
- ```powershell
32
- dsh plugin --profile web add https://github.com/lgquan/dsh-voco/releases/download/v0.3.11/flowingspring-dsh-voco-0.3.11.tgz
33
- ```
34
-
35
- Release 页面:[v0.3.11](https://github.com/lgquan/dsh-voco/releases/tag/v0.3.11)
36
-
37
- ## 配置 API Key
38
-
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` 仍作为兼容与自动化配置方式保留。
44
-
45
- 在启动 DSH 的同一个 PowerShell 中临时设置:
46
-
47
- ```powershell
48
- $env:SILICONFLOW_API_KEY = "sk-your-api-key"
49
- dsh web
50
- ```
51
-
52
- 要持久保存,可创建 DSH 用户环境文件 `%USERPROFILE%\.dsh\.env`(设置了 `DSH_HOME` 时使用 `$DSH_HOME/.env`):
53
-
54
- ```dotenv
55
- SILICONFLOW_API_KEY=sk-your-api-key
56
- ```
57
-
58
- 也可在运行 `dsh web` 的当前目录放置 `.env`。修改后重启 DSH;不要修改 npm 安装目录或 `node_modules` 中的文件,也不要把真实密钥提交到 GitHub。
59
-
60
- ## 首次使用
61
-
62
- 1. 运行 `dsh web` 并打开 DSH Web UI。
63
- 2. 新建或选择会话,点击麦克风并允许浏览器权限。
64
- 3. 直接说话,连续静音约 1.5 秒后提交一句话;也可以长按麦克风约 400 毫秒按住说话,松手后提交这一段。
65
- 4. 普通聊天由前台回答,需要项目工具的工作会委派给后台 Agent。
66
-
67
- 每个语音会话持续绑定自己的后台 Agent Session。上下文达到轮换阈值后,后续任务会自动进入新的子会话,但仍与原语音会话绑定。
68
-
69
- ## 更新
70
-
71
- ```powershell
72
- dsh plugin --profile web add @flowingspring/dsh-voco
73
- ```
74
-
75
- 也可以安装指定的 GitHub Release。更新后重启 `dsh web`。
76
-
77
- ## 卸载
78
-
79
- ```powershell
80
- dsh plugin --profile web remove @flowingspring/dsh-voco
81
- ```
82
-
83
- 卸载不会自动删除 DSH 会话或语音历史。
84
-
85
- 卸载也不会删除已经保存的 API Key。需要彻底清除时,从 `%USERPROFILE%\.dsh\.credentials.yaml`(设置了 `DSH_HOME` 时为 `$DSH_HOME/.credentials.yaml`)的 `refs` 下删除 `SILICONFLOW_API_KEY`,并同时清理系统环境变量或 `.env` 中的同名配置。
86
-
87
- ## 功能
88
-
89
- - SiliconFlow 免费模型 [`XingChenAGI/XingChenASR-V3.2-Ultra`](https://cloud.siliconflow.cn/models?target=XingChenAGI/XingChenASR-V3.2-Ultra) 云端语音转文字。
90
- - Edge TTS `zh-CN-XiaoxiaoNeural` 语音回复。
91
- - 语音打断、页面切换、断线重连和历史恢复。
92
- - 委派前即时确认,完整报告保留在 DSH 任务界面。
93
- - 可选接入 `@flowingspring/dsh-workspace-memory`,让语音主会话和每个完成的委派子任务共享同一 Workspace 长期记忆范围。
94
-
95
- ## 排查
96
-
97
- - **缺少 API Key**:确认 `SILICONFLOW_API_KEY` 在启动 DSH 的进程中可见;修改 `.env` 后重启 `dsh web`。
98
- - **无法录音**:检查浏览器麦克风权限和系统输入设备,并确认页面来自 `dsh web`。
99
- - **识别失败或较慢**:检查网络、Key 有效期、硅基流动账户额度及模型/Provider 延迟。
100
-
101
- ## 链接
102
-
103
- - [GitHub 源码与问题反馈](https://github.com/lgquan/dsh-voco)
104
- - [npm 包](https://www.npmjs.com/package/@flowingspring/dsh-voco)
105
-
106
- ## 许可证
107
-
108
- [MIT](LICENSE)