@michengai/dsh-agency-agents 0.1.17 → 0.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +74 -16
  2. package/README.zh-CN.md +73 -15
  3. package/assets/branding/banner.svg +52 -0
  4. package/assets/branding/banner.txt +11 -0
  5. package/assets/screenshots/agent-roster-en.png +0 -0
  6. package/assets/screenshots/agent-roster.png +0 -0
  7. package/assets/screenshots/expert-picker.png +0 -0
  8. package/assets/screenshots/summon-prompt.png +0 -0
  9. package/lib/{i18n-x9V6Ga4d.js → i18n-BDZqnN0K.js} +18 -3
  10. package/lib/index.d.ts +32 -1
  11. package/lib/index.js +84 -9
  12. package/lib/remote.js +1 -1
  13. package/package.json +8 -7
  14. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/00-/351/230/205/350/257/273/345/257/274/350/210/252.md +0 -13
  15. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/01-/351/241/271/347/233/256/346/246/202/350/247/210.md +0 -9
  16. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/02-/345/275/223/345/211/215/347/212/266/346/200/201.md +0 -14
  17. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/03-/345/276/205/345/212/236/344/270/216/351/230/273/345/241/236.md +0 -10
  18. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/04-/350/277/255/344/273/243/350/267/257/347/272/277/345/233/276.md +0 -12
  19. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/05-/346/212/200/346/234/257/346/236/266/346/236/204/345/237/272/347/272/277.md +0 -31
  20. package/docs/00-/344/272/244/346/216/245/345/205/245/345/217/243/06-/346/226/207/346/241/243/347/274/226/345/206/231/350/247/204/350/214/203.md +0 -8
  21. package/docs/03-/346/212/200/346/234/257/346/236/266/346/236/204/00-/346/217/222/344/273/266/346/236/266/346/236/204.md +0 -19
  22. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/00-/346/231/272/350/203/275/344/275/223/345/212/240/350/275/275/344/270/216/345/247/224/346/264/276.md +0 -19
  23. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/00-/346/270/205/345/215/225/347/264/242/345/274/225.md +0 -29
  24. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/01-/345/255/246/346/234/257.md +0 -14
  25. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/02-/350/256/276/350/256/241.md +0 -18
  26. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/03-/345/267/245/347/250/213.md +0 -67
  27. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/04-/350/264/242/345/212/241.md +0 -13
  28. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/05-/346/270/270/346/210/217/345/274/200/345/217/221.md +0 -29
  29. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/06-/345/234/260/347/220/206/344/277/241/346/201/257.md +0 -21
  30. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/07-/345/214/273/347/226/227/345/201/245/345/272/267.md +0 -11
  31. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/08-/345/270/202/345/234/272/350/220/245/351/224/200.md +0 -44
  32. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/09-/344/273/230/350/264/271/345/252/222/344/275/223.md +0 -15
  33. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/10-/344/272/247/345/223/201.md +0 -13
  34. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/11-/351/241/271/347/233/256/347/256/241/347/220/206.md +0 -15
  35. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/12-/351/224/200/345/224/256.md +0 -17
  36. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/13-/345/256/211/345/205/250.md +0 -20
  37. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/14-/347/251/272/351/227/264/350/256/241/347/256/227.md +0 -14
  38. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/15-/344/270/223/351/241/271/351/242/206/345/237/237.md +0 -65
  39. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/16-/346/224/257/346/214/201.md +0 -14
  40. package/docs/04-Agent/350/277/220/350/241/214/344/275/223/347/263/273/01-/345/206/205/347/275/256/346/231/272/350/203/275/344/275/223/346/270/205/345/215/225/17-/346/265/213/350/257/225.md +0 -17
  41. package/docs/05-/345/267/245/347/250/213/344/272/244/344/273/230/00-/345/256/211/350/243/205/346/236/204/345/273/272/345/217/221/345/270/203.md +0 -31
  42. package/docs/07-/350/277/255/344/273/243/345/275/222/346/241/243/2026/I006-npm/350/207/252/345/212/250/345/217/221/345/270/203/00-/350/277/255/344/273/243/346/200/273/350/247/210.md +0 -50
package/README.md CHANGED
@@ -1,14 +1,35 @@
1
1
  <div align="center">
2
- <img src="https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/branding/dsh-logo.png" width="88" alt="DeepSeek Harness logo">
2
+ <table cellpadding="0" cellspacing="0">
3
+ <tr>
4
+ <td valign="middle" align="center">
5
+ <img src="assets/branding/dsh-logo.png" alt="DeepSeek Harness logo" width="168">
6
+ </td>
7
+ <td valign="middle">
8
+ <pre>
9
+ ____ ____ _ _
10
+ | _ \/ ___|| | | |
11
+ | | | \___ \| |_| |
12
+ | |_| |___) | _ |
13
+ |____/|____/|_| |_|
14
+ AGENCY AGENTS
15
+ 271 summonable specialists
16
+ DeepSeek Harness plugin
17
+ </pre>
18
+ </td>
19
+ </tr>
20
+ </table>
21
+ </div>
22
+
23
+ <div align="center">
3
24
 
4
25
  # DSH Agency Agents
5
26
 
6
27
  **271 summonable specialist agents for DeepSeek Harness**
7
28
 
8
- [简体中文](README.zh-CN.md) · [Documentation](docs/00-交接入口/00-阅读导航.md) · [Apache-2.0](LICENSE)
29
+ [简体中文](README.zh-CN.md) · [Apache-2.0](LICENSE)
9
30
 
10
31
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)
11
- [![Bundled agents](https://img.shields.io/badge/Bundled%20agents-271-0f766e.svg)](docs/04-Agent运行体系/01-内置智能体清单/00-清单索引.md)
32
+ [![Bundled agents](https://img.shields.io/badge/Bundled%20agents-271-0f766e.svg)](#features)
12
33
  [![npm package](https://img.shields.io/npm/v/%40michengai%2Fdsh-agency-agents.svg?label=npm%20package)](https://www.npmjs.com/package/@michengai/dsh-agency-agents)
13
34
  [![DSH Web Plugin](https://img.shields.io/badge/DSH%20Web-Plugin-0f766e.svg)](https://github.com/MichengAI/dsh-agency-agents)
14
35
  [![Node.js 22 or later](https://img.shields.io/badge/Node.js-22%20or%20later-339933.svg?logo=node.js&logoColor=white)](https://nodejs.org/)
@@ -21,21 +42,21 @@
21
42
  - Filter by category or search, then enable or disable bundled experts in **Settings → Experts**.
22
43
  - Summon enabled experts by name or slug from the composer's **Experts** picker.
23
44
  - Use `list_experts` to discover experts and `summon_expert` to start a one-shot specialist subagent.
24
- - Use 271 bundled personas immediately, or connect a separately synchronized expert directory.
45
+ - Use 271 bundled personas immediately, or connect a separately synchronized expert directory.`n- Paste one sentence into DSH, Codex, or WorkBuddy and let that agent install the plugin locally.
25
46
 
26
47
  The parent session keeps task context, judgment, and the final answer. Expert children provide a specialist perspective only and cannot summon further experts.
27
48
 
28
49
  ## Screenshots
29
50
 
30
- Enable the experts you need in **Settings → Experts**:
51
+ Filter by category or search in **Settings → Experts**, then enable the experts you need:
31
52
 
32
- ![DSH Experts panel](https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/screenshots/agent-roster.png)
53
+ ![DSH Experts panel](https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/screenshots/agent-roster-en.png)
33
54
 
34
- Open the composer's **Experts** picker and choose an enabled expert:
55
+ Use `@` or the composer's **Experts** picker to choose an enabled expert:
35
56
 
36
57
  ![Experts picker](https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/screenshots/expert-picker.png)
37
58
 
38
- Then write the complete task with the expert name and slug:
59
+ The name and slug are filled in; write the complete task next:
39
60
 
40
61
  ![Summoning an expert from the composer](https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/screenshots/summon-prompt.png)
41
62
 
@@ -47,20 +68,54 @@ Then write the complete task with the expert name and slug:
47
68
 
48
69
  ## Installation
49
70
 
50
- ### Install from npm
71
+ `dsh plugin add` forwards to `pnpm add` in the profile directory. Without a version and official registry, a local mirror or minimum-release-age policy can leave you on an older build.
72
+
73
+ ### Ask another agent to install it
74
+
75
+ This plugin runs inside DeepSeek Harness Web. Copy one of the sentences below into DSH, Codex, or WorkBuddy and let that agent install it into your local `web` profile.
76
+
77
+ From npm:
78
+
79
+ ```text
80
+ Install the latest DSH plugin @michengai/dsh-agency-agents into my local web profile using the official npm registry: dsh plugin --profile web add @michengai/dsh-agency-agents@latest --registry=https://registry.npmjs.org/. Then run dsh --profile web --dump-config, confirm agency-agents is mounted, and remind me to restart DSH Web and hard-refresh the browser.
81
+ ```
82
+
83
+ From source:
84
+
85
+ ```text
86
+ Install the DSH plugin from source at https://github.com/MichengAI/dsh-agency-agents: clone it, run pnpm install --frozen-lockfile and pnpm build, then run dsh plugin --profile web add . from that directory. Do not copy lib by itself. Then run dsh --profile web --dump-config, confirm agency-agents is mounted, and remind me to restart DSH Web and hard-refresh the browser.
87
+ ```
51
88
 
52
- Run this from any PowerShell directory. `dsh plugin` installs the npm package and applies its bundled `cordis.patch.yml`:
89
+ | Product | How to use it |
90
+ | --- | --- |
91
+ | DSH | Send one of the sentences above to the current session. |
92
+ | Codex | Send one of the sentences above to Codex and let it install locally. |
93
+ | WorkBuddy | Send one of the sentences above to WorkBuddy; for a source install you can also paste `https://github.com/MichengAI/dsh-agency-agents`. |
94
+
95
+ Codex and WorkBuddy only install the plugin. After that, open DSH Web and use **Settings → Experts**.
96
+
97
+ You can also run the same npm command yourself:
98
+
99
+ ```powershell
100
+ dsh plugin --profile web add @michengai/dsh-agency-agents@latest --registry=https://registry.npmjs.org/
101
+ ```
102
+
103
+ If `dsh` is not on PATH, replace the leading `dsh` with `npx --yes @deepseek-ai/dsh`.
104
+
105
+ ### Install the latest package from the official npm registry
106
+
107
+ Run this from any PowerShell directory:
53
108
 
54
109
  ```powershell
55
110
  [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
56
111
  $OutputEncoding = [System.Text.Encoding]::UTF8
57
- dsh plugin --profile web add @michengai/dsh-agency-agents
112
+ dsh plugin --profile web add @michengai/dsh-agency-agents@latest --registry=https://registry.npmjs.org/
58
113
  dsh --profile web --dump-config
59
114
  ```
60
115
 
61
- The configuration output should contain `agency-agents` and `agency-agents-remote`. Restart DSH Web and hard-refresh the browser. Do not copy client files manually: the Settings page needs the mounted Remote service.
116
+ To pin a release, replace `@latest` with a version such as `@0.1.17`.
62
117
 
63
- If a package mirror has not synchronized the latest version, append `--registry=https://registry.npmjs.org/`.
118
+ The configuration output should contain `agency-agents` and `agency-agents-remote`. Restart DSH Web and hard-refresh the browser. Do not copy client files manually: the Settings page needs the mounted Remote service.
64
119
 
65
120
  ### Install from source
66
121
 
@@ -83,7 +138,7 @@ Restart DSH Web and hard-refresh the browser. `dsh plugin ... add .` reads the p
83
138
  ## Usage
84
139
 
85
140
  1. Open **Settings → Experts** and enable the needed experts.
86
- 2. Open the composer's **Experts** picker and choose an enabled expert.
141
+ 2. Use `@` or the composer **Experts** picker to choose an enabled expert.
87
142
  3. Name the expert and slug, then provide the complete task.
88
143
 
89
144
  ```text
@@ -101,7 +156,7 @@ The parent session can also call `list_experts(division?)`, then delegate with `
101
156
  | `divisions` | 17 standard divisions | Top-level divisions to scan. |
102
157
  | `maxDepth` | Unset | Positive absolute subagent-depth limit. |
103
158
 
104
- Set `AGENCY_AGENTS_ROOT` to use an external expert directory. The provider must support persona and tool filtering.
159
+ Set `AGENCY_AGENTS_ROOT` to use an external expert directory. Persona bodies from that directory are injected as the child system prompt, so load them only from a trusted source. The provider must support persona and tool filtering. `summon_experts` accepts at most 8 experts with a concurrency of 4 and still returns successful answers when some experts fail.
105
160
 
106
161
  ## Secondary development
107
162
 
@@ -121,7 +176,9 @@ pnpm verify
121
176
  dsh plugin --profile web add .
122
177
  ```
123
178
 
124
- The published package includes `lib`, `assets`, the patch, and documentation only. Do not publish `node_modules` or local development files.
179
+ Handoff and iteration notes stay in the local `docs` directory and are not tracked in Git; a fresh clone will not include that handover entry.
180
+
181
+ The published package includes `lib`, `assets`, the patch, and the root README/license files. Do not publish `node_modules` or local development files.
125
182
 
126
183
  ## Validation
127
184
 
@@ -138,3 +195,4 @@ pnpm verify
138
195
  ## License and attribution
139
196
 
140
197
  This project’s TypeScript source, build scripts, and documentation use [Apache License 2.0](LICENSE). Bundled personas originate from [The Agency](https://github.com/msitarzewski/agency-agents) and remain MIT-licensed; see [assets\agency-agents\LICENSE](assets/agency-agents/LICENSE).
198
+
package/README.zh-CN.md CHANGED
@@ -1,14 +1,35 @@
1
1
  <div align="center">
2
- <img src="https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/branding/dsh-logo.png" width="88" alt="DeepSeek Harness 标识">
2
+ <table cellpadding="0" cellspacing="0">
3
+ <tr>
4
+ <td valign="middle" align="center">
5
+ <img src="assets/branding/dsh-logo.png" alt="DeepSeek Harness 标识" width="168">
6
+ </td>
7
+ <td valign="middle">
8
+ <pre>
9
+ ____ ____ _ _
10
+ | _ \/ ___|| | | |
11
+ | | | \___ \| |_| |
12
+ | |_| |___) | _ |
13
+ |____/|____/|_| |_|
14
+ AGENCY AGENTS
15
+ 271 summonable specialists
16
+ DeepSeek Harness plugin
17
+ </pre>
18
+ </td>
19
+ </tr>
20
+ </table>
21
+ </div>
22
+
23
+ <div align="center">
3
24
 
4
25
  # DSH Agency Agents
5
26
 
6
27
  **为 DeepSeek Harness 提供 271 名可召唤的专业智能体**
7
28
 
8
- [English](README.md) · [完整文档](docs/00-交接入口/00-阅读导航.md) · [Apache-2.0](LICENSE)
29
+ [English](README.md) · [Apache-2.0](LICENSE)
9
30
 
10
31
  [![许可证:Apache-2.0](https://img.shields.io/badge/许可证-Apache--2.0-blue.svg)](LICENSE)
11
- [![内置智能体](https://img.shields.io/badge/内置智能体-271-0f766e.svg)](docs/04-Agent运行体系/01-内置智能体清单/00-清单索引.md)
32
+ [![内置智能体](https://img.shields.io/badge/内置智能体-271-0f766e.svg)](#功能概览)
12
33
  [![npm package](https://img.shields.io/npm/v/%40michengai%2Fdsh-agency-agents.svg?label=npm%20package)](https://www.npmjs.com/package/@michengai/dsh-agency-agents)
13
34
  [![DSH Web Plugin](https://img.shields.io/badge/DSH%20Web-Plugin-0f766e.svg)](https://github.com/MichengAI/dsh-agency-agents)
14
35
  [![Node.js 22 or later](https://img.shields.io/badge/Node.js-22%20or%20later-339933.svg?logo=node.js&logoColor=white)](https://nodejs.org/)
@@ -21,21 +42,21 @@
21
42
  - 在「设置 → 专家」中按分类筛选或搜索,再启用或停用内置专家。
22
43
  - 在输入框的「专家」中按名称或 slug 召唤已启用的专家处理完整任务。
23
44
  - 提供 `list_experts` 与 `summon_expert` 工具,分别用于发现专家和启动一次性子代理。
24
- - 内置 271 份 persona,无需额外下载;也可接入自行同步的专家目录。
45
+ - 内置 271 份 persona,无需额外下载;也可接入自行同步的专家目录。`n- 可把一句话复制到 DSH、Codex 或 WorkBuddy,让对方代装到本机 DSH。
25
46
 
26
47
  主会话保留任务上下文、判断和最终交付;专家子代理只提供专业视角,不能继续召唤专家,避免递归委派。
27
48
 
28
49
  ## 界面预览
29
50
 
30
- 在「设置 → 专家」中启用需要的专家:
51
+ 在「设置 → 专家」中按分类筛选或搜索,再启用需要的专家:
31
52
 
32
53
  ![DSH 专家面板](https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/screenshots/agent-roster.png)
33
54
 
34
- 在输入框点击「专家」,选择已启用的专家:
55
+ 在输入框用 `@` 或「专家」选择已启用的专家:
35
56
 
36
57
  ![专家选择器](https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/screenshots/expert-picker.png)
37
58
 
38
- 再用名称和 slug 写出完整任务:
59
+ 回填名称和 slug 后,写出完整任务:
39
60
 
40
61
  ![召唤专家的输入方式](https://raw.githubusercontent.com/MichengAI/dsh-agency-agents/main/assets/screenshots/summon-prompt.png)
41
62
 
@@ -47,20 +68,54 @@
47
68
 
48
69
  ## 安装
49
70
 
50
- ### 从 npm 安装
71
+ `dsh plugin add` 会转发到 profile 目录里的 `pnpm add`。不写版本、不指定官方源时,本机镜像和最短发布间隔可能让你停在旧版。
72
+
73
+ ### 交给其他 Agent 一句话安装
74
+
75
+ 本插件运行在 DeepSeek Harness Web 里。把下面其中一句复制到 DSH、Codex 或 WorkBuddy,让它代你安装到本机 `web` profile。
76
+
77
+ 从 npm 安装:
78
+
79
+ ```text
80
+ 请把 DSH 插件 @michengai/dsh-agency-agents 最新版装进本机 web profile,使用官方 npm 源执行:dsh plugin --profile web add @michengai/dsh-agency-agents@latest --registry=https://registry.npmjs.org/。装完执行 dsh --profile web --dump-config,确认已挂载 agency-agents,并提醒我重启 DSH Web 后硬刷新浏览器。
81
+ ```
82
+
83
+ 从源码安装:
84
+
85
+ ```text
86
+ 请从源码安装 DSH 插件 https://github.com/MichengAI/dsh-agency-agents:克隆到本机后执行 pnpm install --frozen-lockfile 和 pnpm build,再用 dsh plugin --profile web add . 把当前目录装进 web profile。不要只复制 lib。装完执行 dsh --profile web --dump-config,确认已挂载 agency-agents,并提醒我重启 DSH Web 后硬刷新浏览器。
87
+ ```
51
88
 
52
- 在任意 PowerShell 目录执行。`dsh plugin` 会安装 npm 包并自动应用包内的 `cordis.patch.yml`:
89
+ | 产品 | 怎么用 |
90
+ | --- | --- |
91
+ | DSH | 把上面其中一句发给当前会话。 |
92
+ | Codex | 把上面其中一句发给 Codex,让它在本机执行安装。 |
93
+ | WorkBuddy | 把上面其中一句发给 WorkBuddy;源码安装也可同时粘贴仓库地址 `https://github.com/MichengAI/dsh-agency-agents`。 |
94
+
95
+ Codex 和 WorkBuddy 只负责代装;装好后仍要打开 DSH Web 使用「设置 → 专家」。
96
+
97
+ 也可以自己执行同一条 npm 命令:
98
+
99
+ ```powershell
100
+ dsh plugin --profile web add @michengai/dsh-agency-agents@latest --registry=https://registry.npmjs.org/
101
+ ```
102
+
103
+ 未把 `dsh` 装进 PATH 时,把开头的 `dsh` 换成 `npx --yes @deepseek-ai/dsh`。
104
+
105
+ ### 从官方 npm 安装最新版
106
+
107
+ 在任意 PowerShell 目录执行:
53
108
 
54
109
  ```powershell
55
110
  [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
56
111
  $OutputEncoding = [System.Text.Encoding]::UTF8
57
- dsh plugin --profile web add @michengai/dsh-agency-agents
112
+ dsh plugin --profile web add @michengai/dsh-agency-agents@latest --registry=https://registry.npmjs.org/
58
113
  dsh --profile web --dump-config
59
114
  ```
60
115
 
61
- 配置输出中应包含 `agency-agents` 与 `agency-agents-remote`。安装后重启 DSH Web 并在浏览器硬刷新;请勿手工复制客户端文件,否则设置页所需的 Remote 服务不会被挂载。
116
+ 需要钉死某一版时,把 `@latest` 换成具体版本,例如 `@0.1.17`。
62
117
 
63
- 若镜像未同步最新版本,可在安装命令末尾追加 `--registry=https://registry.npmjs.org/`。
118
+ 配置输出中应包含 `agency-agents` 与 `agency-agents-remote`。安装后重启 DSH Web 并在浏览器硬刷新;请勿手工复制客户端文件,否则设置页所需的 Remote 服务不会被挂载。
64
119
 
65
120
  ### 从源码安装
66
121
 
@@ -83,7 +138,7 @@ dsh --profile web --dump-config
83
138
  ## 使用
84
139
 
85
140
  1. 打开「设置 → 专家」,启用需要的专家。
86
- 2. 在对话输入框点击「专家」,选择已启用的专家。
141
+ 2. 在对话输入框用 `@` 或点击「专家」,选择已启用的专家。
87
142
  3. 用名称和 slug 明确指定专家,并给出完整任务。例如:
88
143
 
89
144
  ```text
@@ -101,7 +156,7 @@ dsh --profile web --dump-config
101
156
  | `divisions` | 17 个标准分区 | 需要扫描的顶层分区。 |
102
157
  | `maxDepth` | 未设置 | 正整数形式的绝对子代理深度上限。 |
103
158
 
104
- 也可设置 `AGENCY_AGENTS_ROOT` 环境变量指定外部专家目录。子代理 provider 必须支持 persona 和工具过滤能力。
159
+ 也可设置 `AGENCY_AGENTS_ROOT` 环境变量指定外部专家目录。外部目录里的 persona 正文会注入为子代理系统提示,只应从可信来源加载。子代理 provider 必须支持 persona 和工具过滤能力。`summon_experts` 一次最多 8 名专家,并发 4,部分失败仍返回成功结果。
105
160
 
106
161
  ## 二次开发
107
162
 
@@ -121,7 +176,9 @@ pnpm verify
121
176
  dsh plugin --profile web add .
122
177
  ```
123
178
 
124
- 发布包只包含 `lib`、`assets`、补丁和文档;不要将 `node_modules` 或本地开发文件加入发布内容。
179
+ 交接与迭代文档只保留在本机 `docs` 目录,不纳入 Git;克隆仓库后不会得到交接入口。
180
+
181
+ 发布包只包含 `lib`、`assets`、补丁和根目录说明/许可证;不要将 `node_modules` 或本地开发文件加入发布内容。
125
182
 
126
183
  ## 验证
127
184
 
@@ -138,3 +195,4 @@ pnpm verify
138
195
  ## 许可证与归属
139
196
 
140
197
  本项目 TypeScript 源码、构建脚本和文档采用 [Apache License 2.0](LICENSE)。内置专家 persona 源自 [The Agency](https://github.com/msitarzewski/agency-agents),仍采用 MIT,许可证位于 [assets\agency-agents\LICENSE](assets/agency-agents/LICENSE)。
198
+
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="640" height="240" viewBox="0 0 640 240" role="img" aria-label="DSH Agency Agents">
3
+ <rect width="640" height="240" rx="8" fill="#0d1117" stroke="#30363d" stroke-width="1"/>
4
+ <line x1="320" y1="12" x2="320" y2="228" stroke="#30363d" stroke-width="1"/>
5
+ <rect x="88" y="24" width="72" height="12" fill="#e6edf3"/>
6
+ <rect x="196" y="24" width="24" height="12" fill="#e6edf3"/>
7
+ <rect x="64" y="36" width="96" height="12" fill="#e6edf3"/>
8
+ <rect x="196" y="36" width="36" height="12" fill="#e6edf3"/>
9
+ <rect x="268" y="36" width="24" height="12" fill="#e6edf3"/>
10
+ <rect x="52" y="48" width="120" height="12" fill="#e6edf3"/>
11
+ <rect x="208" y="48" width="84" height="12" fill="#e6edf3"/>
12
+ <rect x="40" y="60" width="144" height="12" fill="#e6edf3"/>
13
+ <rect x="208" y="60" width="72" height="12" fill="#e6edf3"/>
14
+ <rect x="28" y="72" width="168" height="12" fill="#e6edf3"/>
15
+ <rect x="220" y="72" width="48" height="12" fill="#e6edf3"/>
16
+ <rect x="28" y="84" width="24" height="12" fill="#e6edf3"/>
17
+ <rect x="76" y="84" width="168" height="12" fill="#e6edf3"/>
18
+ <rect x="28" y="96" width="24" height="12" fill="#e6edf3"/>
19
+ <rect x="100" y="96" width="72" height="12" fill="#e6edf3"/>
20
+ <rect x="184" y="96" width="60" height="12" fill="#e6edf3"/>
21
+ <rect x="28" y="108" width="24" height="12" fill="#e6edf3"/>
22
+ <rect x="124" y="108" width="60" height="12" fill="#e6edf3"/>
23
+ <rect x="196" y="108" width="48" height="12" fill="#e6edf3"/>
24
+ <rect x="28" y="120" width="24" height="12" fill="#e6edf3"/>
25
+ <rect x="136" y="120" width="48" height="12" fill="#e6edf3"/>
26
+ <rect x="196" y="120" width="48" height="12" fill="#e6edf3"/>
27
+ <rect x="28" y="132" width="36" height="12" fill="#e6edf3"/>
28
+ <rect x="148" y="132" width="84" height="12" fill="#e6edf3"/>
29
+ <rect x="40" y="144" width="24" height="12" fill="#e6edf3"/>
30
+ <rect x="148" y="144" width="84" height="12" fill="#e6edf3"/>
31
+ <rect x="40" y="156" width="36" height="12" fill="#e6edf3"/>
32
+ <rect x="112" y="156" width="24" height="12" fill="#e6edf3"/>
33
+ <rect x="160" y="156" width="60" height="12" fill="#e6edf3"/>
34
+ <rect x="52" y="168" width="36" height="12" fill="#e6edf3"/>
35
+ <rect x="112" y="168" width="36" height="12" fill="#e6edf3"/>
36
+ <rect x="172" y="168" width="48" height="12" fill="#e6edf3"/>
37
+ <rect x="64" y="180" width="108" height="12" fill="#e6edf3"/>
38
+ <rect x="184" y="180" width="48" height="12" fill="#e6edf3"/>
39
+ <rect x="76" y="192" width="108" height="12" fill="#e6edf3"/>
40
+ <rect x="112" y="204" width="48" height="12" fill="#e6edf3"/>
41
+ <g font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace" fill="#e6edf3" text-anchor="middle">
42
+ <text x="480" y="51" font-size="13" xml:space="preserve"> _____ _____ _ _</text>
43
+ <text x="480" y="67" font-size="13" xml:space="preserve"> | __ \ / ____| | | |</text>
44
+ <text x="480" y="83" font-size="13" xml:space="preserve"> | | | | (___ | |__| |</text>
45
+ <text x="480" y="99" font-size="13" xml:space="preserve"> | | | |\___ \| __ |</text>
46
+ <text x="480" y="115" font-size="13" xml:space="preserve"> | |__| |____) | | | |</text>
47
+ <text x="480" y="131" font-size="13" xml:space="preserve"> |_____/|_____/|_| |_|</text>
48
+ <text x="480" y="161" font-size="12" font-weight="700">AGENCY AGENTS</text>
49
+ <text x="480" y="179" font-size="12">271 summonable specialists</text>
50
+ <text x="480" y="197" font-size="12">DeepSeek Harness plugin</text>
51
+ </g>
52
+ </svg>
@@ -0,0 +1,11 @@
1
+ README 左侧使用 assets/branding/dsh-logo.png(宽 168,不随表格均分撑开)
2
+ 右侧字符:
3
+
4
+ ____ ____ _ _
5
+ | _ \/ ___|| | | |
6
+ | | | \___ \| |_| |
7
+ | |_| |___) | _ |
8
+ |____/|____/|_| |_|
9
+ AGENCY AGENTS
10
+ 271 summonable specialists
11
+ DeepSeek Harness plugin
Binary file
@@ -333,6 +333,9 @@ const zhHost = {
333
333
  "error.summonRequiresAgent": "summon_expert 需要由智能体调用",
334
334
  "error.summonManyRequiresAgent": "summon_experts 需要由智能体调用",
335
335
  "error.expertsEmpty": "experts 必须是非空数组",
336
+ "error.expertsTooMany": "一次最多召唤 {max} 名专家,当前为 {count}",
337
+ "error.taskEmpty": "第 {index} 个专家任务不能为空",
338
+ "error.taskTooLong": "第 {index} 个专家任务过长({length} 个字符,上限 {max})",
336
339
  "error.providerMissing": "子代理 provider \"{provider}\" 未注册",
337
340
  "error.providerNoPersona": "子代理 provider \"{provider}\" 不支持专家人格",
338
341
  "error.providerNoToolFilter": "子代理 provider \"{provider}\" 无法阻止递归专家委派",
@@ -344,7 +347,8 @@ const zhHost = {
344
347
  "list.empty": "暂无可用专家。",
345
348
  "list.emptyDivision": "没有匹配分区 \"{division}\" 的专家。",
346
349
  "list.heading": "{total} 位专家,覆盖 {count} 个分区:",
347
- "list.group": "## {division}({count})"
350
+ "list.group": "## {division}({count})",
351
+ "list.expertFailed": "失败:{error}"
348
352
  };
349
353
  /** 英文宿主文案,key 完整性由 satisfies 在编译期保证。 */
350
354
  const enHost = {
@@ -359,6 +363,9 @@ const enHost = {
359
363
  "error.summonRequiresAgent": "summon_expert requires a calling agent",
360
364
  "error.summonManyRequiresAgent": "summon_experts requires a calling agent",
361
365
  "error.expertsEmpty": "experts must be a non-empty array",
366
+ "error.expertsTooMany": "summon at most {max} experts at once, got {count}",
367
+ "error.taskEmpty": "expert task #{index} must not be empty",
368
+ "error.taskTooLong": "expert task #{index} is too long ({length} characters, limit {max})",
362
369
  "error.providerMissing": "subagent provider \"{provider}\" is not registered",
363
370
  "error.providerNoPersona": "subagent provider \"{provider}\" does not support expert personas",
364
371
  "error.providerNoToolFilter": "subagent provider \"{provider}\" cannot prevent recursive expert delegation",
@@ -370,7 +377,8 @@ const enHost = {
370
377
  "list.empty": "No experts available.",
371
378
  "list.emptyDivision": "No experts matched division \"{division}\".",
372
379
  "list.heading": "{total} experts across {count} divisions:",
373
- "list.group": "## {division} ({count})"
380
+ "list.group": "## {division} ({count})",
381
+ "list.expertFailed": "Failed: {error}"
374
382
  };
375
383
  /** 将未知值收成 zh / en;只有显式 en 才走英文。 */
376
384
  function resolveHostLocale(value) {
@@ -438,5 +446,12 @@ function renderExpertList(locale, args, value) {
438
446
  }));
439
447
  return lines.join("\n");
440
448
  }
449
+ /** 渲染批量召唤结果:成功项输出答案,失败项输出本地化失败句。 */
450
+ function renderSummonResults(locale, results) {
451
+ return results.map((item) => {
452
+ const body = item.ok ? item.answer : formatHost(locale, "list.expertFailed", { error: item.error ?? "" });
453
+ return "## " + item.expert + "\n" + body;
454
+ }).join("\n\n");
455
+ }
441
456
  //#endregion
442
- export { readHostLocale as a, ZH_NAME as c, matchDivision as i, localizedExpertDescription as n, renderExpertList as o, localizedExpertName as r, ZH_DIVISION as s, formatHost as t };
457
+ export { readHostLocale as a, ZH_DIVISION as c, matchDivision as i, ZH_NAME as l, localizedExpertDescription as n, renderExpertList as o, localizedExpertName as r, renderSummonResults as s, formatHost as t };
package/lib/index.d.ts CHANGED
@@ -1,6 +1,10 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
2
  import "@deepseek-ai/dsh-settings";
3
3
  import { Context } from "@deepseek-ai/cordis";
4
+ //#region src/names.d.ts
5
+ /** 智能体 slug(文件名去 .md)→ 中文名(现实岗位)。缺省时回退英文 frontmatter name。 */
6
+ declare const ZH_NAME: Readonly<Record<string, string>>;
7
+ //#endregion
4
8
  //#region src/i18n.d.ts
5
9
  /** 与 DSH locale 插件一致的语言标识。 */
6
10
  type LocaleId = 'zh' | 'en';
@@ -8,6 +12,33 @@ type LocaleId = 'zh' | 'en';
8
12
  //#region src/index.d.ts
9
13
  declare const name = "agency-agents";
10
14
  declare const inject: string[];
15
+ /** 一次批量召唤的专家数量上限,避免无界并行拖垮宿主。 */
16
+ declare const SUMMON_EXPERTS_MAX = 8;
17
+ /** 批量召唤的并发上限。 */
18
+ declare const SUMMON_EXPERTS_CONCURRENCY = 4;
19
+ /** 单条任务的 Unicode 码点上限。 */
20
+ declare const SUMMON_TASK_MAX_CHARS = 8000;
21
+ /** 已校验的批量召唤条目。 */
22
+ interface SummonExpertSpec {
23
+ readonly expert: unknown;
24
+ readonly task: string;
25
+ }
26
+ /** 批量召唤中单个专家的结果。 */
27
+ interface SummonExpertItemResult {
28
+ readonly expert: string;
29
+ readonly ok: boolean;
30
+ readonly answer: string;
31
+ readonly error?: string;
32
+ }
33
+ /** 校验批量召唤入参:非空、数量上限、任务非空且不超过码点上限。 */
34
+ declare function validateSummonSpecs(specs: unknown, locale: LocaleId): SummonExpertSpec[];
35
+ /** 受限并发地映射异步任务,结果顺序与输入一致。 */
36
+ declare function mapPool<T, R>(items: readonly T[], concurrency: number, mapper: (item: T, index: number) => Promise<R>): Promise<R[]>;
37
+ /** 把单次专家运行结果收成批量条目;失败时保留原始查询作为专家名。 */
38
+ declare function toSummonItemResult(query: unknown, result: {
39
+ expert: string;
40
+ answer: string;
41
+ } | Error): SummonExpertItemResult;
11
42
  /** One resolved expert ready to be summoned. */
12
43
  interface Expert {
13
44
  readonly slug: string;
@@ -61,4 +92,4 @@ declare function resolveExpert<T extends {
61
92
  }>(experts: readonly T[], query: unknown, locale?: LocaleId): T;
62
93
  declare function apply(ctx: Context, config: Config): void;
63
94
  //#endregion
64
- export { Config, apply, inject, loadCatalog, name, parseFrontmatter, resolveCatalogRoot, resolveExpert, sanitize, stripBom, truncate, unquote };
95
+ export { Config, SUMMON_EXPERTS_CONCURRENCY, SUMMON_EXPERTS_MAX, SUMMON_TASK_MAX_CHARS, SummonExpertItemResult, SummonExpertSpec, ZH_NAME, apply, inject, loadCatalog, mapPool, name, parseFrontmatter, resolveCatalogRoot, resolveExpert, sanitize, stripBom, toSummonItemResult, truncate, unquote, validateSummonSpecs };
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as readHostLocale, c as ZH_NAME, i as matchDivision, n as localizedExpertDescription, o as renderExpertList, r as localizedExpertName, s as ZH_DIVISION, t as formatHost } from "./i18n-x9V6Ga4d.js";
1
+ import { a as readHostLocale, c as ZH_DIVISION, i as matchDivision, l as ZH_NAME, n as localizedExpertDescription, o as renderExpertList, r as localizedExpertName, s as renderSummonResults, t as formatHost } from "./i18n-BDZqnN0K.js";
2
2
  import z from "@deepseek-ai/schemastery";
3
3
  import { defineTool } from "@deepseek-ai/dsh-tools";
4
4
  import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
@@ -39,6 +39,70 @@ const EXTRA_SOURCES = [{
39
39
  }];
40
40
  /** 描述截断上限,避免无过滤列出全量智能体时 token 开销过大。 */
41
41
  const DESCRIPTION_LIMIT = 120;
42
+ /** 一次批量召唤的专家数量上限,避免无界并行拖垮宿主。 */
43
+ const SUMMON_EXPERTS_MAX = 8;
44
+ /** 批量召唤的并发上限。 */
45
+ const SUMMON_EXPERTS_CONCURRENCY = 4;
46
+ /** 单条任务的 Unicode 码点上限。 */
47
+ const SUMMON_TASK_MAX_CHARS = 8e3;
48
+ /** 校验批量召唤入参:非空、数量上限、任务非空且不超过码点上限。 */
49
+ function validateSummonSpecs(specs, locale) {
50
+ if (!Array.isArray(specs) || specs.length === 0) throw new Error(formatHost(locale, "error.expertsEmpty"));
51
+ if (specs.length > 8) throw new Error(formatHost(locale, "error.expertsTooMany", {
52
+ max: 8,
53
+ count: specs.length
54
+ }));
55
+ return specs.map((item, index) => {
56
+ const record = item;
57
+ const rawTask = record === null || record === void 0 ? void 0 : record.task;
58
+ const task = rawTask === void 0 || rawTask === null ? "" : String(rawTask);
59
+ const length = Array.from(task).length;
60
+ if (task.trim() === "") throw new Error(formatHost(locale, "error.taskEmpty", { index: index + 1 }));
61
+ if (length > 8e3) throw new Error(formatHost(locale, "error.taskTooLong", {
62
+ index: index + 1,
63
+ length,
64
+ max: SUMMON_TASK_MAX_CHARS
65
+ }));
66
+ return {
67
+ expert: record?.expert,
68
+ task
69
+ };
70
+ });
71
+ }
72
+ /** 受限并发地映射异步任务,结果顺序与输入一致。 */
73
+ async function mapPool(items, concurrency, mapper) {
74
+ if (items.length === 0) return [];
75
+ const limit = Math.max(1, Math.min(concurrency, items.length));
76
+ const results = new Array(items.length);
77
+ let next = 0;
78
+ const workers = Array.from({ length: limit }, async () => {
79
+ while (true) {
80
+ const index = next;
81
+ next += 1;
82
+ if (index >= items.length) return;
83
+ results[index] = await mapper(items[index], index);
84
+ }
85
+ });
86
+ await Promise.all(workers);
87
+ return results;
88
+ }
89
+ /** 把单次专家运行结果收成批量条目;失败时保留原始查询作为专家名。 */
90
+ function toSummonItemResult(query, result) {
91
+ if (result instanceof Error) {
92
+ const expert = String(query ?? "").trim();
93
+ return {
94
+ expert: expert === "" ? "unknown" : expert,
95
+ ok: false,
96
+ answer: "",
97
+ error: result.message
98
+ };
99
+ }
100
+ return {
101
+ expert: result.expert,
102
+ ok: true,
103
+ answer: result.answer
104
+ };
105
+ }
42
106
  /** 未在配置中显式提供 `root` 时,先读取该环境变量,再使用随包发布的智能体目录。 */
43
107
  const ROOT_ENV = "AGENCY_AGENTS_ROOT";
44
108
  const BUNDLED_ROOT = fileURLToPath(new URL("../assets/agency-agents/", import.meta.url));
@@ -356,7 +420,7 @@ function apply(ctx, config) {
356
420
  }));
357
421
  ctx.tools.register(defineTool({
358
422
  name: "summon_experts",
359
- description: "Summon multiple domain experts in parallel to work on one mission. Each expert gets its own task/role and runs as a specialist subagent with its own persona; results are returned per expert. Use this to assemble a specialist team. This call waits for all experts.",
423
+ description: "Summon multiple domain experts in parallel to work on one mission. Each expert gets its own task/role and runs as a specialist subagent with its own persona. At most 8 experts run with concurrency 4; if some fail, successful answers are still returned. Use this to assemble a specialist team.",
360
424
  parameters: { experts: {
361
425
  type: "array",
362
426
  required: true,
@@ -389,18 +453,29 @@ function apply(ctx, config) {
389
453
  } }
390
454
  },
391
455
  render: (_args, value) => {
456
+ const results = value.results;
392
457
  return [{
393
458
  type: "text",
394
- text: value.results.map((r) => `## ${r.expert}\n${r.answer}`).join("\n\n")
459
+ text: renderSummonResults(activeLocale(), results)
395
460
  }];
396
461
  }
397
462
  },
398
463
  async execute(args, exec) {
399
464
  await ensureReady();
400
- if (exec.agent === void 0) throw new Error(formatHost(activeLocale(), "error.summonManyRequiresAgent"));
401
- const specs = args.experts;
402
- if (!Array.isArray(specs) || specs.length === 0) throw new Error(formatHost(activeLocale(), "error.expertsEmpty"));
403
- return { results: await Promise.all(specs.map((spec) => runExpert(spec.expert, spec.task, exec))) };
465
+ const locale = activeLocale();
466
+ if (exec.agent === void 0) throw new Error(formatHost(locale, "error.summonManyRequiresAgent"));
467
+ return { results: (await mapPool(validateSummonSpecs(args.experts, locale), 4, async (spec) => {
468
+ try {
469
+ return toSummonItemResult(spec.expert, await runExpert(spec.expert, spec.task, exec));
470
+ } catch (error) {
471
+ return toSummonItemResult(spec.expert, error instanceof Error ? error : new Error(String(error)));
472
+ }
473
+ })).map((item) => ({
474
+ expert: item.expert,
475
+ ok: item.ok,
476
+ answer: item.answer,
477
+ ...item.error === void 0 ? {} : { error: item.error }
478
+ })) };
404
479
  }
405
480
  }));
406
481
  ctx.systemPrompt.section({
@@ -408,9 +483,9 @@ function apply(ctx, config) {
408
483
  order: 117,
409
484
  text: (context) => {
410
485
  if (context.agent?.session?.header?.parentSession !== void 0) return "";
411
- return "## Agency expert mode\nThe parent session has a roster of domain experts from The Agency (specialists across 17 divisions, individually enable/disable; ALL are disabled by default, and the user enables some in the Agency settings tab). In the parent session, call `list_experts()` to see enabled division names and counts, then call `list_experts(division)` to browse enabled experts and find an exact slug before using `summon_expert(expert, task)`. A disabled expert cannot be summoned.";
486
+ return "## Agency expert mode\nThe parent session has a roster of domain experts from The Agency (specialists across 17 divisions, individually enable/disable; ALL are disabled by default, and the user enables some in the Agency settings tab). In the parent session, call `list_experts()` to see enabled division names and counts, then call `list_experts(division)` to browse enabled experts and find an exact slug before using `summon_expert(expert, task)` or `summon_experts` for a small parallel team (at most 8; partial results if some fail). A disabled expert cannot be summoned.";
412
487
  }
413
488
  });
414
489
  }
415
490
  //#endregion
416
- export { Config, apply, inject, loadCatalog, name, parseFrontmatter, resolveCatalogRoot, resolveExpert, sanitize, stripBom, truncate, unquote };
491
+ export { Config, SUMMON_EXPERTS_CONCURRENCY, SUMMON_EXPERTS_MAX, SUMMON_TASK_MAX_CHARS, ZH_NAME, apply, inject, loadCatalog, mapPool, name, parseFrontmatter, resolveCatalogRoot, resolveExpert, sanitize, stripBom, toSummonItemResult, truncate, unquote, validateSummonSpecs };
package/lib/remote.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as formatHost } from "./i18n-x9V6Ga4d.js";
1
+ import { t as formatHost } from "./i18n-BDZqnN0K.js";
2
2
  import { settingsNamespace } from "@deepseek-ai/dsh-settings";
3
3
  import { Remote, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
4
4
  import { z } from "zod";