dsh-lead-mode 0.2.3 → 0.2.4
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.md +57 -17
- package/README.zh-CN.md +57 -17
- package/cordis.patch.yml +50 -21
- package/lib/index.js +59 -14
- package/package.json +1 -1
- package/skills/lead-mode/SKILL.md +122 -14
- package/skills/team-digest/SKILL.md +4 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ English | [中文](README.zh-CN.md)
|
|
|
4
4
|
|
|
5
5
|
Adds a Lead mode to DSH. One preset, two skills, one self-check command, two reminders.
|
|
6
6
|
|
|
7
|
-
The official Team runtime ships tools
|
|
7
|
+
The official Team runtime ships the tools. The older generation has `spawn_teammate`, `send_message` and `team_task_*`; the newer one builds members with `subagent`, and `send_message`, `team_task_*` and `wait_agent` come from the subagent tooling. When to delegate, whom to delegate to, how to wait for a result, how to write the closing message, how to merge several members' output: none of that is in the tools. This plugin adds that layer. It does not replace the official Team mode; it sits on top of it.
|
|
8
8
|
|
|
9
9
|
Once installed, the model works the way a Lead does: split the work, delegate it, accept the result. It delegates hands-on work instead of doing everything alone.
|
|
10
10
|
|
|
@@ -43,14 +43,14 @@ It is not tied to the preset. Any session can load it, two ways:
|
|
|
43
43
|
- The model loads it when it judges the task needs it (the skill is marked model-invocable)
|
|
44
44
|
- You run `/skill lead-mode` yourself
|
|
45
45
|
|
|
46
|
-
It covers: agreeing on the goal before starting, making a delegation self-contained, keeping write scopes disjoint, the list/get/claim/complete flow for shared tasks, how to wait on teammates, where a teammate's model comes from, and doing the final verification yourself.
|
|
46
|
+
It covers: agreeing on the goal before starting, making a delegation self-contained, keeping write scopes disjoint, the list/get/claim/complete flow for shared tasks, how to wait on teammates (the two generations answer differently; see "Two generations of Agent Teams"), where a teammate's model comes from, and doing the final verification yourself.
|
|
47
47
|
|
|
48
48
|
Two of those facts only show up when you read the runtime source:
|
|
49
49
|
|
|
50
50
|
| Fact | Why it matters |
|
|
51
51
|
|---|---|
|
|
52
52
|
| A teammate settling notifies you automatically, carrying its closing message | Finish your turn after delegating; you do not need to sit and watch |
|
|
53
|
-
| A task change does not wake an idle Lead | Do not count on "it marked the task complete, so I know"
|
|
53
|
+
| A task change does not wake an idle Lead | Do not count on "it marked the task complete, so I know". The older generation wakes only a caller currently inside `wait_agent`; the newer one wakes nobody, because `wait_agent` only waits for your own inbox |
|
|
54
54
|
|
|
55
55
|
So the skill's default is: finish your turn after delegating and let the notification wake you (the user sees progress immediately), and use one `wait_agent` only when the current turn cannot continue without the result. Never loop `wait_agent`, and never poll with repeated `list_agents`.
|
|
56
56
|
|
|
@@ -75,9 +75,9 @@ The six headings are fixed Chinese strings; an empty block says 无. Take the la
|
|
|
75
75
|
|
|
76
76
|
| Reported | Content |
|
|
77
77
|
|---|---|
|
|
78
|
-
| Team runtime | Mounted or not; its `maxMembers`
|
|
78
|
+
| Team runtime | Mounted or not; on the older generation, its `maxMembers` too |
|
|
79
79
|
| lead-mode preset | Registered or not |
|
|
80
|
-
| Missing pieces | The version-pinned install command |
|
|
80
|
+
| Missing pieces | The next step by generation: the session switch first on the newer one, the version-pinned install command on the older one |
|
|
81
81
|
|
|
82
82
|
Everything in place returns success. Anything missing returns error. Nothing is skipped silently.
|
|
83
83
|
|
|
@@ -92,22 +92,60 @@ Two channels:
|
|
|
92
92
|
| First persona section | The model | As soon as you switch to Lead mode. It is section 0 of the system prompt |
|
|
93
93
|
| Startup warn and `/lead-mode` | You | When the Team runtime is detected missing |
|
|
94
94
|
|
|
95
|
-
Both say the same thing:
|
|
95
|
+
Both say the same thing: when the Team tools are missing, stop and tell the user how to turn them on — the session switch on a newer host, the profile package on an older one.
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
On an older host the model will not pretend it can delegate, and it will not pass `subagent` off as a teammate. On a newer host `subagent` is how a teammate is built, so that caution does not apply.
|
|
98
98
|
|
|
99
|
-
##
|
|
99
|
+
## Two generations of Agent Teams
|
|
100
100
|
|
|
101
|
-
Lead mode delegates through
|
|
101
|
+
Lead mode delegates through the official dsh Team runtime, which this plugin does not ship. That runtime comes in two shapes: the older one in the published host 0.2.2-rc.1, and the newer one on master only, not released, with no version number to point at.
|
|
102
|
+
|
|
103
|
+
| Dimension | Older generation: published host 0.2.2-rc.1 | Newer generation: master, unreleased |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| Defined in | `@deepseek-ai/dsh-experimental-tool-agent-team@0.2.2-rc.1` inside the desktop app.asar | `packages/team/tool-agent-team` and `packages/subagent/*` |
|
|
106
|
+
| Creating a member | `spawn_teammate({ name, description, prompt, context })` | `subagent({ name?, description, prompt, cwd?, agent_preset?, provider?, model?, reasoning_effort? })`; `subagent_fork` when the child inherits your history |
|
|
107
|
+
| Member identity | A durable named member carrying a `target` | A session id plus an agent name; the name is a path from the root (e.g. `reviewer/checker`), and the root is always `lead` |
|
|
108
|
+
| Sending a message | `send_message({ target, message })` | `send_message({ agent, message })`, returns `{ messageId }` |
|
|
109
|
+
| Interrupting | `interrupt_agent({ target })` | `interrupt_agent({ agent })`, returns `{ accepted }` |
|
|
110
|
+
| Roster | `list_agents({})` lists the Lead and its members | `list_agents({})` lists the whole tree; rows are `{ name, status, description? }`, and status gains `corrupt`, `unsupported`, `unavailable` |
|
|
111
|
+
| Waiting semantics | Team-scoped: waits for member status, messages or task changes; returns `noProgress` at once when nobody can produce a change | An ordinary subagent control tool: waits for the caller's own next input (a member message, a completion notice, the user cutting in); returns only `{ timedOut }`, never `noProgress` |
|
|
112
|
+
| Task board owner | The four `team_task_*` tools; owner is a member name | The same four tools; owner is a member name or a session id, and the check field is `ownerId` instead of `ownerName` |
|
|
113
|
+
| Turning it on | Install the profile package `@deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1` | Do not install it: it is in `RETIRED_BUNDLES`, and app-boot removes it from the profile. The Team plugins ship with the base and web bundles; turn it on per session with the agent team switch in the model-and-reasoning menu (Chinese UI: 模型与推理等级 → 使用智能体团队) |
|
|
114
|
+
| Member model | Inherits the Lead; `spawn_teammate` takes no model parameter | `subagent` takes `provider`, `model` and `reasoning_effort` (the `standard` preset already enables `modelSelection`); `agent_preset` picks a preset |
|
|
115
|
+
| Member cap | `agentTeams.config.maxMembers` | The `maxMembers` config key is rejected, so there is no cap to read |
|
|
116
|
+
|
|
117
|
+
The newer generation drops `spawn_teammate`; `wait_agent` moves out of the Team tools into the subagent control tools, and its meaning becomes "wait for my own inbox".
|
|
118
|
+
|
|
119
|
+
### Telling the two apart
|
|
120
|
+
|
|
121
|
+
Do not go by version string. Go by the tool list.
|
|
122
|
+
|
|
123
|
+
| What you see | Generation | Next step |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| `spawn_teammate` is there | Older | Install the profile package, next section |
|
|
126
|
+
| No `spawn_teammate`, but `subagent` and `team_task_*` are there | Newer | Nothing to install; make sure the session switch is on |
|
|
127
|
+
| No `team_task_*` at all | Team is off | Look for the session switch first; install the package only after confirming this is an older host that has no such switch |
|
|
128
|
+
|
|
129
|
+
The order matters. Telling someone on a newer host to install the profile package is wrong: app-boot removes that package, so it buys nothing.
|
|
130
|
+
|
|
131
|
+
### Older generation: install the profile package
|
|
102
132
|
|
|
103
133
|
```bash
|
|
104
134
|
dsh plugin --profile <your profile name> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1
|
|
105
135
|
```
|
|
106
136
|
|
|
107
|
-
|
|
137
|
+
`0.2.2-rc.1` above is the current host line; replace it with your own `dsh --version` output.
|
|
138
|
+
|
|
139
|
+
**The version pin is required, and it must equal the host version.** Without it npm resolves `latest`, which is 0.1.5-alpha.2 — built for 0.1.x hosts, and it will not mount on a 0.2.2 host. `next` points at 0.2.2-rc.1, the right build for this line and the one this plugin's own text pins. The team packages pin exact `dsh-*` peers, so an older rc installs a peer set the newer host does not satisfy. Restart dsh afterwards.
|
|
108
140
|
|
|
109
141
|
Not sure whether it is installed? Run `/lead-mode` in dsh; it reports dependency state.
|
|
110
142
|
|
|
143
|
+
### Newer generation: do not install the package, flip the session switch
|
|
144
|
+
|
|
145
|
+
On a newer host, do not run the command above. `@deepseek-ai/dsh-experimental-agent-team-profile` sits in the official `RETIRED_BUNDLES`, and app-boot removes it from the profile. The Team plugins ship with the base and web bundles.
|
|
146
|
+
|
|
147
|
+
Turning it on is per session: open the model-and-reasoning menu and switch on the agent team option (Chinese UI: 模型与推理等级 → 使用智能体团队). The switch is session-scoped, not profile-scoped.
|
|
148
|
+
|
|
111
149
|
## Install this plugin
|
|
112
150
|
|
|
113
151
|
Two routes, pick one.
|
|
@@ -132,7 +170,7 @@ Three steps.
|
|
|
132
170
|
|
|
133
171
|
**1. Switch to Lead mode.** Pick "Lead 模式" in a new session's preset list. The first system-prompt section becomes the Lead persona, and the reminder at its top goes in with it.
|
|
134
172
|
|
|
135
|
-
**2. Run `/lead-mode` to check dependencies.** This command delegates nothing; it only reports state. When something is missing it
|
|
173
|
+
**2. Run `/lead-mode` to check dependencies.** This command delegates nothing; it only reports state. When something is missing it gives the next step by generation: the session switch on a newer host, the version-pinned install command on an older one.
|
|
136
174
|
|
|
137
175
|
**3. Let the model work.** With the delegation tools in place, the model splits the work, delegates to teammates, and waits for all of them before wrapping up. Without them, its first move is to tell you to enable the Team runtime.
|
|
138
176
|
|
|
@@ -140,7 +178,7 @@ Three steps.
|
|
|
140
178
|
|
|
141
179
|
You do not have to touch your preset. Install the plugin, keep `standard` or whatever you already use, and run `/skill lead-mode` in any session to load the method; the model also loads it when it judges the task needs it.
|
|
142
180
|
|
|
143
|
-
One thing is missing: the upfront reminder lives in the persona, so it appears only under the `lead-mode` preset. Run `/lead-mode` once before you start to check the dependencies; it
|
|
181
|
+
One thing is missing: the upfront reminder lives in the persona, so it appears only under the `lead-mode` preset. Run `/lead-mode` once before you start to check the dependencies; when the Team runtime is absent it gives the next step — the session switch on a newer host, the version-pinned install command on an older one.
|
|
144
182
|
|
|
145
183
|
`team-digest` works the same way. It is not tied to a preset, any session can use it, and the model decides at wrap-up whether a digest is worth writing.
|
|
146
184
|
|
|
@@ -177,11 +215,11 @@ The Lead mode skill names this entry point too, so the model points you here ins
|
|
|
177
215
|
|
|
178
216
|
## Required official bundles and versions
|
|
179
217
|
|
|
180
|
-
This plugin ships none of the packages below. The host or an official bundle provides them;
|
|
218
|
+
This plugin ships none of the packages below. The host or an official bundle provides them; the ones with a version constraint are declared in `peerDependencies`, and the profile package is not among them — you install it yourself.
|
|
181
219
|
|
|
182
220
|
| Package | Requirement | Provided by | When missing |
|
|
183
221
|
|---|---|---|---|
|
|
184
|
-
| `@deepseek-ai/dsh-experimental-agent-team-profile` | `0.2.2-rc.1` | You install it explicitly |
|
|
222
|
+
| `@deepseek-ai/dsh-experimental-agent-team-profile` | `0.2.2-rc.1` | You install it explicitly, older-generation hosts only | On an older host only: cannot delegate; `/lead-mode` returns error; startup warn |
|
|
185
223
|
| `@deepseek-ai/dsh` | `>=0.2.2-rc.1` | Host | Will not install |
|
|
186
224
|
| `@deepseek-ai/cordis` | `^4.0.5` | Host | Will not install |
|
|
187
225
|
| `@deepseek-ai/schemastery` | `^3.18.5` | Host | Will not install |
|
|
@@ -191,7 +229,9 @@ This plugin ships none of the packages below. The host or an official bundle pro
|
|
|
191
229
|
|
|
192
230
|
The target host version is `dshTarget` in `package.json`: `0.2.2-rc.1`.
|
|
193
231
|
|
|
194
|
-
|
|
232
|
+
The first row holds for older-generation hosts only. On a newer host that package is in `RETIRED_BUNDLES`; there is nothing to install, and installing it does not stick.
|
|
233
|
+
|
|
234
|
+
## Why the older generation's install command pins a version
|
|
195
235
|
|
|
196
236
|
`@deepseek-ai/dsh-experimental-agent-team-profile` has three dist-tags on npm:
|
|
197
237
|
|
|
@@ -210,7 +250,7 @@ $ npm view @deepseek-ai/dsh-experimental-agent-team-profile version
|
|
|
210
250
|
0.1.5-alpha.2
|
|
211
251
|
```
|
|
212
252
|
|
|
213
|
-
So every install command in this plugin carries `@0.2.2-rc.1`: the persona prefix, the `/lead-mode` output, the startup warn, and SKILL.md. `test/preset.test.mjs` and `test/smoke.test.mjs` both assert that string, so a future edit cannot quietly drop back to the bare name.
|
|
253
|
+
So every install command in this plugin's own text carries `@0.2.2-rc.1`, the current `dshTarget`: the persona prefix, the `/lead-mode` output, the startup warn, and SKILL.md. `test/preset.test.mjs` and `test/smoke.test.mjs` both assert that string, so a future edit cannot quietly drop back to the bare name.
|
|
214
254
|
|
|
215
255
|
`next` now points at `0.2.2-rc.1`, the build this plugin pins; `alpha` (`0.2.2-alpha.3`) is an earlier preview of the same line.
|
|
216
256
|
|
|
@@ -229,7 +269,7 @@ The three classic subagent rows (`tool-subagent-control`, `tool-subagent`, `tool
|
|
|
229
269
|
|
|
230
270
|
`apply()` in `@deepseek-ai/dsh-experimental-tool-agent-team` listens on the global `agent/created` event and installs Team tools on every agent. It is a host-plane plugin; putting it in a preset would leak it into every session.
|
|
231
271
|
|
|
232
|
-
So this plugin stays at: preset, two skills, reminder. Whether the Team runtime is on is decided by the user through the official profile package.
|
|
272
|
+
So this plugin stays at: preset, two skills, reminder. Whether the Team runtime is on is decided by the user: through the official profile package on an older host, through the session switch on a newer one.
|
|
233
273
|
|
|
234
274
|
## Layout
|
|
235
275
|
|
package/README.zh-CN.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
给 DSH 加一个 Lead 模式。一个预设、两个 skill、一个自检命令、两条前置提醒。
|
|
6
6
|
|
|
7
|
-
官方 Team
|
|
7
|
+
官方 Team 运行时只给工具。老一代是 `spawn_teammate`、`send_message`、`team_task_*`;新一代改成用 `subagent` 建成员,`send_message`、`team_task_*`、`wait_agent` 从 subagent 体系下发。什么时候派活、派给谁、怎么等结果、收尾怎么写、多成员的产出怎么合并,这些方法它不管。本插件补的就是这一层。它不替代官方 Team 模式,是配套。
|
|
8
8
|
|
|
9
9
|
装好后模型能按 Lead 的方式干活:拆活、派活、验收。动手的活尽量派出去。
|
|
10
10
|
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
- 模型判断需要时自己加载(skill 标记为模型可调用)
|
|
44
44
|
- 你直接敲 `/skill lead-mode`
|
|
45
45
|
|
|
46
|
-
覆盖这些内容:开工前对齐目标、派活必须自包含、写作用域不重叠、共享任务的 list/get/claim/complete 流程、怎么等 teammate
|
|
46
|
+
覆盖这些内容:开工前对齐目标、派活必须自包含、写作用域不重叠、共享任务的 list/get/claim/complete 流程、怎么等 teammate(两代答案不同,见「两代 Agent Teams 定义」)、teammate 的模型从哪来、最终验证自己做。
|
|
47
47
|
|
|
48
48
|
其中两条是读源码才确认的,容易踩:
|
|
49
49
|
|
|
50
50
|
| 事实 | 为什么重要 |
|
|
51
51
|
|---|---|
|
|
52
52
|
| teammate 收工会自动通知你,通知里带它收尾那条消息 | 派完活结束回合就够,不用盯着等 |
|
|
53
|
-
| task 变更不会唤醒空闲的 Lead | 别指望「它把 task 标 complete
|
|
53
|
+
| task 变更不会唤醒空闲的 Lead | 别指望「它把 task 标 complete 了我就知道了」。老一代只唤醒正在 `wait_agent` 的调用方;新一代谁都不唤醒,`wait_agent` 只等自己的收件箱 |
|
|
54
54
|
|
|
55
55
|
所以 skill 的默认建议是:派完活就结束回合等通知(用户立刻看到进展),只有本回合内就必须拿到结果时才用一次 `wait_agent`。不要 `wait_agent` 套循环,也不要反复 `list_agents` 轮询。
|
|
56
56
|
|
|
@@ -75,9 +75,9 @@
|
|
|
75
75
|
|
|
76
76
|
| 报什么 | 内容 |
|
|
77
77
|
|---|---|
|
|
78
|
-
| Team 运行时 |
|
|
78
|
+
| Team 运行时 | 挂没挂;老一代挂了再报 `maxMembers` |
|
|
79
79
|
| lead-mode 预设 | 注册没注册 |
|
|
80
|
-
| 缺东西时 |
|
|
80
|
+
| 缺东西时 | 按代际给下一步:新一代先提示会话开关,老一代给带版本号的安装命令 |
|
|
81
81
|
|
|
82
82
|
依赖齐全返回 success,缺东西返回 error。不会静默跳过。
|
|
83
83
|
|
|
@@ -92,22 +92,60 @@
|
|
|
92
92
|
| persona 第一段 | 模型 | 一切到 Lead 模式就在。system prompt 的第 0 段 |
|
|
93
93
|
| 启动 warn 与 `/lead-mode` | 用户 | 检测到 Team 运行时缺失时 |
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
两条讲同一件事:Team 工具不齐就先停下来,告诉你下一步怎么开。新宿主去打开会话开关,老宿主去装 profile 包。
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
老一代宿主上,模型不会假装能派活,也不会拿 `subagent` 顶替 teammate;新一代的 teammate 本来就是 `subagent` 建的,这条不适用。
|
|
98
98
|
|
|
99
|
-
##
|
|
99
|
+
## 两代 Agent Teams 定义
|
|
100
100
|
|
|
101
|
-
Lead 模式靠
|
|
101
|
+
Lead 模式靠 dsh 官方的 Team 运行时派活,本插件不带它。这套运行时在两代宿主上是两套 API:老一代是已发布的 0.2.2-rc.1;新一代只在本地 master 上,还没发版,没有版本号可指。
|
|
102
|
+
|
|
103
|
+
| 维度 | 老一代:已发布宿主 0.2.2-rc.1 | 新一代:本地 master,未发布 |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| 定义在哪 | 桌面端 asar 内的 `@deepseek-ai/dsh-experimental-tool-agent-team@0.2.2-rc.1` | `packages/team/tool-agent-team` 与 `packages/subagent/*` |
|
|
106
|
+
| 建成员 | `spawn_teammate({ name, description, prompt, context })` | `subagent({ name?, description, prompt, cwd?, agent_preset?, provider?, model?, reasoning_effort? })`;要继承历史用 `subagent_fork` |
|
|
107
|
+
| 成员身份 | 持久命名的成员,带 `target` | Session id 加一个 agent 名;名字是从根算起的路径(如 `reviewer/checker`),根固定叫 `lead` |
|
|
108
|
+
| 发消息 | `send_message({ target, message })` | `send_message({ agent, message })`,返回 `{ messageId }` |
|
|
109
|
+
| 打断 | `interrupt_agent({ target })` | `interrupt_agent({ agent })`,返回 `{ accepted }` |
|
|
110
|
+
| 名册 | `list_agents({})` 列 Lead 加成员 | `list_agents({})` 列整棵树,每行 `{ name, status, description? }`,状态多了 `corrupt`、`unsupported`、`unavailable` |
|
|
111
|
+
| 等待语义 | team 作用域:等成员状态、消息、任务变更;没人能产出变更时立刻回 `noProgress` | 普通 subagent 控制工具:等调用者自己的下一条输入(成员消息、完成通知、用户插话),只回 `{ timedOut }`,没有 `noProgress` |
|
|
112
|
+
| 任务板 owner | `team_task_*` 四个工具,owner 填成员名 | 同样四个工具,owner 填成员名或 Session id;判据字段从 `ownerName` 变成 `ownerId` |
|
|
113
|
+
| 开启方式 | 装 profile 包 `@deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1` | 不要装这个包:它已进 `RETIRED_BUNDLES`,app-boot 会把 profile 里的它删掉。Team 插件随 base 与 web 组合下发,按会话开:模型与推理等级菜单里的「使用智能体团队」 |
|
|
114
|
+
| 成员模型 | 继承 Lead,`spawn_teammate` 没有模型参数 | `subagent` 有 `provider`、`model`、`reasoning_effort`(`standard` 预设已开 `modelSelection`);`agent_preset` 可指定预设 |
|
|
115
|
+
| 成员上限 | `agentTeams.config.maxMembers` | 配置键 `maxMembers` 已被拒绝,读不到上限 |
|
|
116
|
+
|
|
117
|
+
新一代删掉了 `spawn_teammate`;`wait_agent` 从 team 工具搬到 subagent 控制工具,语义换成「等自己的收件箱」。
|
|
118
|
+
|
|
119
|
+
### 怎么知道自己属于哪一代
|
|
120
|
+
|
|
121
|
+
不按版本号认,按工具清单认。
|
|
122
|
+
|
|
123
|
+
| 你看到的 | 属于 | 下一步 |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| 有 `spawn_teammate` | 老一代 | 装 profile 包,见下一节 |
|
|
126
|
+
| 没有 `spawn_teammate`,但有 `subagent` 和 `team_task_*` | 新一代 | 不用装,确认会话开关已开 |
|
|
127
|
+
| `team_task_*` 一个都没有 | Team 没开 | 先找会话开关;确认是老一代宿主没有这个开关,才去装包 |
|
|
128
|
+
|
|
129
|
+
顺序不能反。新一代宿主上让人去装 profile 包是错的:那个包会被 app-boot 移除,装了也白装。
|
|
130
|
+
|
|
131
|
+
### 老一代:装 profile 包
|
|
102
132
|
|
|
103
133
|
```bash
|
|
104
134
|
dsh plugin --profile <你的 profile 名> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1
|
|
105
135
|
```
|
|
106
136
|
|
|
107
|
-
|
|
137
|
+
上面写的 `0.2.2-rc.1` 是当前宿主线,按你自己 `dsh --version` 的输出替换。
|
|
138
|
+
|
|
139
|
+
**必须带版本号,而且要和宿主版本一致。** 不带会装到 `latest` 上的 0.1.5-alpha.2,那是给 0.1.x 宿主用的,在 0.2.2 宿主上挂不上。`next` 指向的 0.2.2-rc.1 才是这条线现在对的版本,也是本插件文案里钉的那个。团队包把 `dsh-*` 的 peer 钉死到具体版本,老 rc 装到新宿主上,peer 对不上。装完重启 dsh。
|
|
108
140
|
|
|
109
141
|
不确定装没装?进 dsh 敲 `/lead-mode`,它会报依赖状态。
|
|
110
142
|
|
|
143
|
+
### 新一代:不要装 profile 包,开会话开关
|
|
144
|
+
|
|
145
|
+
新一代宿主上不要执行上面那条命令。`@deepseek-ai/dsh-experimental-agent-team-profile` 已进官方的 `RETIRED_BUNDLES`,app-boot 会把它从 profile 里删掉。Team 插件随 base 与 web 组合下发。
|
|
146
|
+
|
|
147
|
+
开法是按会话开:打开「模型与推理等级」菜单,把「使用智能体团队」开关打开。这个开关是会话级的,不是 profile 级的。
|
|
148
|
+
|
|
111
149
|
## 装本插件
|
|
112
150
|
|
|
113
151
|
两条路,选一条。
|
|
@@ -132,7 +170,7 @@ dsh plugin --profile <你的 profile 名> add https://github.com/xiebaiyuan/dsh-
|
|
|
132
170
|
|
|
133
171
|
**1. 切到 Lead 模式。** 新会话的预设列表里选「Lead 模式」。切过去之后,模型 system prompt 的第一段就换成 Lead 人设,开头那段提醒跟着进去。
|
|
134
172
|
|
|
135
|
-
**2. 敲 `/lead-mode` 查依赖。**
|
|
173
|
+
**2. 敲 `/lead-mode` 查依赖。** 这条命令不派活,只报状态。缺东西时它按代际给下一步:新一代提示会话开关,老一代给出带版本号的安装命令。
|
|
136
174
|
|
|
137
175
|
**3. 让模型干活。** 派活工具齐了,模型会自己拆活、派给 teammate、等齐再收尾。工具不齐,它第一句就是让你去开 Team 运行时。
|
|
138
176
|
|
|
@@ -140,7 +178,7 @@ dsh plugin --profile <你的 profile 名> add https://github.com/xiebaiyuan/dsh-
|
|
|
140
178
|
|
|
141
179
|
预设不动也能用。插件装好,预设保持 `standard` 或你自己的,任何会话敲 `/skill lead-mode` 就加载那套方法;模型判断任务需要时也会自己加载。
|
|
142
180
|
|
|
143
|
-
少了一样东西:persona 里那段前置提醒只在 `lead-mode` 预设里,不切过去就看不到。所以第一次先敲 `/lead-mode`
|
|
181
|
+
少了一样东西:persona 里那段前置提醒只在 `lead-mode` 预设里,不切过去就看不到。所以第一次先敲 `/lead-mode` 看依赖:缺 Team 运行时它会给下一步,新一代是会话开关,老一代才是带版本号的安装命令。
|
|
144
182
|
|
|
145
183
|
`team-digest` 同理。它不绑预设,任何会话可用,收尾时模型自己判断要不要写汇总。
|
|
146
184
|
|
|
@@ -177,11 +215,11 @@ Lead 模式 skill 里也写了这个入口,所以派活时模型会直接让
|
|
|
177
215
|
|
|
178
216
|
## 依赖的官方 bundle 与版本
|
|
179
217
|
|
|
180
|
-
本插件不捆绑下面这些包。它们由宿主或官方 bundle
|
|
218
|
+
本插件不捆绑下面这些包。它们由宿主或官方 bundle 提供;带版本约束的那些写在 `peerDependencies` 里,profile 包不在其中,要用户自己装。
|
|
181
219
|
|
|
182
220
|
| 包 | 版本要求 | 谁提供 | 缺了会怎样 |
|
|
183
221
|
|---|---|---|---|
|
|
184
|
-
| `@deepseek-ai/dsh-experimental-agent-team-profile` | `0.2.2-rc.1` |
|
|
222
|
+
| `@deepseek-ai/dsh-experimental-agent-team-profile` | `0.2.2-rc.1` | 用户显式安装,只给老一代宿主 | 只在老一代宿主上:派不了活,`/lead-mode` 报 error,启动 warn |
|
|
185
223
|
| `@deepseek-ai/dsh` | `>=0.2.2-rc.1` | 宿主 | 装不上 |
|
|
186
224
|
| `@deepseek-ai/cordis` | `^4.0.5` | 宿主 | 装不上 |
|
|
187
225
|
| `@deepseek-ai/schemastery` | `^3.18.5` | 宿主 | 装不上 |
|
|
@@ -191,7 +229,9 @@ Lead 模式 skill 里也写了这个入口,所以派活时模型会直接让
|
|
|
191
229
|
|
|
192
230
|
目标宿主版本写在 `package.json` 的 `dshTarget` 字段:`0.2.2-rc.1`。
|
|
193
231
|
|
|
194
|
-
|
|
232
|
+
第一行只管老一代宿主。新一代宿主上这个包已进 `RETIRED_BUNDLES`,不需要装,也装不住。
|
|
233
|
+
|
|
234
|
+
## 为什么老一代的安装命令要带版本号
|
|
195
235
|
|
|
196
236
|
`@deepseek-ai/dsh-experimental-agent-team-profile` 在 npm 上有三个 dist-tag:
|
|
197
237
|
|
|
@@ -210,7 +250,7 @@ $ npm view @deepseek-ai/dsh-experimental-agent-team-profile version
|
|
|
210
250
|
0.1.5-alpha.2
|
|
211
251
|
```
|
|
212
252
|
|
|
213
|
-
|
|
253
|
+
所以本插件文案里所有出现安装命令的地方都带 `@0.2.2-rc.1`:persona prefix、`/lead-mode` 输出、启动 warn、SKILL.md,也就是当前的 `dshTarget`。`test/preset.test.mjs` 与 `test/smoke.test.mjs` 都断言这个字符串在,防止以后被改回裸包名。
|
|
214
254
|
|
|
215
255
|
`next` 现在指向 `0.2.2-rc.1`,就是本插件钉的版本;`alpha`(`0.2.2-alpha.3`)是同一条线的早期预览。
|
|
216
256
|
|
|
@@ -229,7 +269,7 @@ classic subagent 三行(`tool-subagent-control`、`tool-subagent`、`tool-suba
|
|
|
229
269
|
|
|
230
270
|
`@deepseek-ai/dsh-experimental-tool-agent-team` 的 `apply()` 监听全局 `agent/created`,给每一个 agent 装 Team 工具。它是 host 平面的插件,放进预设会漏到所有会话。
|
|
231
271
|
|
|
232
|
-
所以本插件的定位是:预设 + 两个 skill + 提醒。开不开 Team
|
|
272
|
+
所以本插件的定位是:预设 + 两个 skill + 提醒。开不开 Team 运行时:老一代宿主由用户装官方 profile 包决定,新一代由会话开关决定。
|
|
233
273
|
|
|
234
274
|
## 目录
|
|
235
275
|
|
package/cordis.patch.yml
CHANGED
|
@@ -11,18 +11,32 @@
|
|
|
11
11
|
# the persona prefix, which switches the session into Lead mode and states
|
|
12
12
|
# the Agent Teams prerequisite up front.
|
|
13
13
|
#
|
|
14
|
-
# This plugin does NOT mount the Team runtime.
|
|
15
|
-
#
|
|
16
|
-
# agent, so it belongs to the host plane, not to a preset row. Users turn it on
|
|
17
|
-
# with the official profile package:
|
|
14
|
+
# This plugin does NOT mount the Team runtime. There are two generations of it,
|
|
15
|
+
# and they are turned on in completely different ways:
|
|
18
16
|
#
|
|
19
|
-
#
|
|
17
|
+
# - Old generation (host up to 0.2.2-rc.1, the currently published line):
|
|
18
|
+
# `@deepseek-ai/dsh-experimental-tool-agent-team` listens on the global
|
|
19
|
+
# `agent/created` event and installs Team tools on every agent, so it belongs to
|
|
20
|
+
# the host plane, not to a preset row. Users turn it on with the official
|
|
21
|
+
# profile package:
|
|
20
22
|
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
23
|
+
# dsh plugin --profile <name> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1
|
|
24
|
+
#
|
|
25
|
+
# The version pin matters: bare `npm i` resolves `latest`, which is 0.1.5-alpha.2
|
|
26
|
+
# and does not mount on a 0.2.2 host. `next` points at 0.2.2-rc.1. The pin must
|
|
27
|
+
# equal the host version (`dsh --version`): the team packages pin exact `dsh-*`
|
|
28
|
+
# peers, so a profile built for an older rc installs peers this host does not
|
|
29
|
+
# satisfy.
|
|
30
|
+
#
|
|
31
|
+
# - New generation (local master, not released yet): Team tools ship with the base
|
|
32
|
+
# and web bundles, and a teammate is just a `subagent`. Nothing is installed.
|
|
33
|
+
# Users flip the per-session switch 「使用智能体团队」 in the model & reasoning
|
|
34
|
+
# menu. The profile package above is now in `RETIRED_BUNDLES`, and app-boot
|
|
35
|
+
# deletes it from a profile, so the install command must never be shown to a
|
|
36
|
+
# user on a new host.
|
|
37
|
+
#
|
|
38
|
+
# The persona prefix below decides which generation it is addressing from the
|
|
39
|
+
# session's tool list, not from a version string.
|
|
26
40
|
- insert:
|
|
27
41
|
- id: dsh-lead-mode
|
|
28
42
|
name: 'dsh-lead-mode'
|
|
@@ -40,28 +54,43 @@
|
|
|
40
54
|
prefix: |
|
|
41
55
|
你是 Lead,负责拆活、派活、验收。动手的活尽量派出去。
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
开工第一件事:看本会话的工具清单,判断这里属于哪一代 Agent Teams。按工具清单判断,不要靠版本号字符串:
|
|
58
|
+
|
|
59
|
+
1. 有 spawn_teammate:老一代。建成员 spawn_teammate({ name, description, prompt, context }),发消息 send_message({ target, message }),打断 interrupt_agent({ target })。
|
|
60
|
+
2. 没有 spawn_teammate,但有 subagent 和 team_task_*:新一代。teammate 就是 subagent,建成员 subagent({ name, description, prompt }),要继承你已完成的回合用 subagent_fork;发消息 send_message({ agent, message }),打断 interrupt_agent({ agent })。
|
|
61
|
+
3. team_task_* 一个都没有:Team 没开,照下面那段做,别跳步。
|
|
62
|
+
|
|
63
|
+
没开 Team 时,顺序不能反,先开关后装包:
|
|
44
64
|
|
|
45
|
-
|
|
65
|
+
第一步,让用户打开会话开关。位置在模型与推理等级菜单里的「使用智能体团队」。新一代宿主 Team 插件随 base 与 web 组合下发,打开这个开关就有工具,不需要装任何包。
|
|
66
|
+
|
|
67
|
+
第二步,只有在确认是老一代宿主(≤0.2.2-rc.1,那个菜单里没有这个开关)时,才给装包命令:
|
|
46
68
|
|
|
47
69
|
dsh plugin --profile <你的 profile 名> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1
|
|
48
70
|
|
|
49
|
-
|
|
71
|
+
版本号要跟 `dsh --version` 的输出一致。不带版本号会装到 0.1.5-alpha.2,和 0.2.2 宿主对不上。装完重启 dsh。新版宿主上不要让人装这个包:它已进 RETIRED_BUNDLES,app-boot 会把 profile 里的它删掉,装了也白装。
|
|
50
72
|
|
|
51
|
-
这是本插件存在的主要理由。没有这些工具,你派不了活。不要自己硬干,不要假装能派活,也不要拿 subagent
|
|
73
|
+
这是本插件存在的主要理由。没有这些工具,你派不了活。不要自己硬干,不要假装能派活,也不要拿 subagent 当别的工具凑数:新一代里 subagent 本身就是 teammate。
|
|
52
74
|
|
|
53
|
-
|
|
75
|
+
派了活就按 Lead 工作法执行,这些条目两代通用:
|
|
54
76
|
|
|
55
77
|
- 派活自包含。teammate 看不到你的上下文,把目标、约束、验收标准、已知失败、绝对路径都写进 prompt。
|
|
56
|
-
-
|
|
78
|
+
- 要求它收尾那条消息写清交付物。它收工时那条消息会随通知回到你手上,格式仍是「Its closing message:」。
|
|
57
79
|
- 派活时要求它第一步建工作日志(.scratch/<effort>/worklog-<mate>.md),收尾前补完最后一轮。
|
|
58
80
|
- 写作用域不重叠。一人一块文件。分不开的活排成依赖。
|
|
59
|
-
- 共享任务走 list、get、claim
|
|
60
|
-
- 等活就结束回合等通知:teammate
|
|
61
|
-
- 不要用 wait_agent 套循环,也不要反复 list_agents 轮询。只有本回合内就必须拿到结果时才等一次。
|
|
62
|
-
- 等齐必需的 teammate 再给最终答复。
|
|
63
|
-
- teammate 继承你的模型,spawn_teammate 没法单独指定模型。
|
|
81
|
+
- 共享任务走 list、get、claim(带当前 revision)、干、complete。task 只是账本,不是唤醒通道。
|
|
82
|
+
- 等活就结束回合等通知:teammate 收工、或给你发消息,都会唤醒你。不要用 wait_agent 套循环,不要反复 list_agents 轮询。
|
|
64
83
|
- 最终验证自己做:跑测试、看 diff、核数字。不要只信回报。
|
|
84
|
+
|
|
85
|
+
判完代际,下面几条按对应那一代做,别混用:
|
|
86
|
+
|
|
87
|
+
- 等活的返回:老一代 wait_agent 是 team 作用域,等成员状态、消息和任务变更,没人在跑时立即返回 noProgress。新一代 wait_agent 只等你自己收件箱的下一条输入,只回 { timedOut },没有 noProgress:timedOut 为 true 就是等到超时,没人找你。
|
|
88
|
+
- 任务变更:老一代只唤醒正在 wait_agent 的调用方,空闲的你收不到通知;新一代连正在等的那次都不结束、不往收件箱塞消息、也不启动空闲成员。新一代要成员处理任务,必须 send_message 叫它。
|
|
89
|
+
- 成员模型:老一代 teammate 继承你的模型,spawn_teammate 没法单独指定。新一代可以按成员挑,subagent 传 provider、model、reasoning_effort。
|
|
90
|
+
- 名册:两代都用 list_agents。新一代返回整棵树,后代名字是从根算起的路径(如 reviewer/checker,根固定叫 lead),inactive 在两代都不代表活干完或失败。
|
|
91
|
+
- 成员上限:老一代读 agentTeams.config.maxMembers。新一代这个配置键已被拒绝,读不到上限,别报一个假数字。
|
|
92
|
+
|
|
93
|
+
等齐必需的 teammate 再给最终答复。
|
|
65
94
|
- id: agent-instructions
|
|
66
95
|
name: '@deepseek-ai/dsh-agent-instructions'
|
|
67
96
|
config:
|
package/lib/index.js
CHANGED
|
@@ -30,11 +30,26 @@ export const name = 'lead-mode'
|
|
|
30
30
|
*/
|
|
31
31
|
const TEAM_PROFILE_PACKAGE = '@deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1'
|
|
32
32
|
|
|
33
|
-
/** Install command shown
|
|
33
|
+
/** Install command for the old-generation host; shown only where it applies. */
|
|
34
34
|
const ENABLE_COMMAND = `dsh plugin --profile <你的 profile 名> add ${TEAM_PROFILE_PACKAGE}`
|
|
35
35
|
|
|
36
36
|
/** Why the version pin matters, repeated wherever the command appears. */
|
|
37
|
-
const VERSION_NOTE = '不带版本号会装到 0.1.5-alpha.2,和 0.2.
|
|
37
|
+
const VERSION_NOTE = '不带版本号会装到 0.1.5-alpha.2,和 0.2.2 宿主对不上。版本号要跟 `dsh --version` 的输出一致。'
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Where the new-generation Team runtime is turned on.
|
|
41
|
+
*
|
|
42
|
+
* The new generation has no released version yet: 0.2.2-rc.1 is the latest
|
|
43
|
+
* published host and it is still the old one. On the unreleased line the Team
|
|
44
|
+
* plugins ship with the base composition and the old profile package is retired
|
|
45
|
+
* (`RETIRED_BUNDLES`, removed from the profile at boot). What decides whether
|
|
46
|
+
* the team tools reach the model is a per-session switch, so the reminder has to
|
|
47
|
+
* name the switch instead of a package.
|
|
48
|
+
*/
|
|
49
|
+
const SESSION_SWITCH_HINT = 'Team 开关是会话级的:模型与推理等级菜单里打开「使用智能体团队」。'
|
|
50
|
+
|
|
51
|
+
/** Labels the old-host-only branch, so nobody installs a retired package on a new host. */
|
|
52
|
+
const OLD_HOST_NOTE = '老宿主(≤ 0.2.2-rc.1,菜单里没有这个开关)才需要装官方 profile 包:'
|
|
38
53
|
|
|
39
54
|
/** Directory holding one subdirectory per bundled skill; the directory name is the skill name. */
|
|
40
55
|
const SKILLS_DIR = new URL('../skills/', import.meta.url)
|
|
@@ -147,19 +162,31 @@ export function syncBundledSkills(skillsRoot, registry, warn) {
|
|
|
147
162
|
}
|
|
148
163
|
|
|
149
164
|
/**
|
|
150
|
-
* Report whether the Team runtime is mounted.
|
|
165
|
+
* Report whether the Team runtime is mounted, and which generation it is.
|
|
166
|
+
*
|
|
167
|
+
* Two generations of the Team runtime answer to the same service name:
|
|
151
168
|
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
169
|
+
* - old (published through 0.2.2-rc.1, `@deepseek-ai/dsh-experimental-tool-agent-team`):
|
|
170
|
+
* the service owns member spawning, `spawnTeammate` is a function on it, and
|
|
171
|
+
* `config.maxMembers` is a real cap;
|
|
172
|
+
* - new (unreleased; Team ships with the base composition): teammates are
|
|
173
|
+
* subagents, so `spawnTeammate` is gone, `maxMembers` is a rejected config
|
|
174
|
+
* key, and the per-session switch decides whether the tools reach the model.
|
|
175
|
+
*
|
|
176
|
+
* `spawnTeammate` is the one discriminator that is reliable from here: the
|
|
177
|
+
* service name and the `config` object exist in both generations. Its absence
|
|
178
|
+
* from a present service means "new", not "broken".
|
|
155
179
|
*
|
|
156
180
|
* @param ctx - a context that can resolve host services.
|
|
157
|
-
* @returns the mount state
|
|
181
|
+
* @returns the mount state, the generation, and (old only) the member cap.
|
|
158
182
|
*/
|
|
159
183
|
function teamRuntimeState(ctx) {
|
|
160
184
|
const agentTeams = ctx.get('agentTeams')
|
|
161
|
-
if (agentTeams === undefined) return { mounted: false }
|
|
162
|
-
|
|
185
|
+
if (agentTeams === undefined) return { mounted: false, generation: 'none' }
|
|
186
|
+
if (typeof agentTeams.spawnTeammate === 'function') {
|
|
187
|
+
return { mounted: true, generation: 'legacy', maxMembers: agentTeams.config?.maxMembers }
|
|
188
|
+
}
|
|
189
|
+
return { mounted: true, generation: 'subagent' }
|
|
163
190
|
}
|
|
164
191
|
|
|
165
192
|
/**
|
|
@@ -195,17 +222,30 @@ function describePreset(state) {
|
|
|
195
222
|
/**
|
|
196
223
|
* Build the `/lead-mode` report.
|
|
197
224
|
*
|
|
225
|
+
* Three branches, because the next step differs per generation:
|
|
226
|
+
*
|
|
227
|
+
* - old and mounted: unchanged from 0.2.3 — mount state with `maxMembers`, the
|
|
228
|
+
* preset state, and the install command only when the runtime is missing;
|
|
229
|
+
* - new and mounted: the runtime is there, so report the generation, never
|
|
230
|
+
* print `maxMembers` (rejected key) and never print the install command;
|
|
231
|
+
* point at the per-session switch instead;
|
|
232
|
+
* - not mounted: the switch first, because on a new host installing the profile
|
|
233
|
+
* package is wrong (app-boot strips it). The install command follows, labelled
|
|
234
|
+
* as old-host-only.
|
|
235
|
+
*
|
|
198
236
|
* @param ctx - a context that can resolve host services.
|
|
199
|
-
* @returns a command result reporting dependency state and the
|
|
237
|
+
* @returns a command result reporting dependency state and the next step.
|
|
200
238
|
*/
|
|
201
239
|
async function report(ctx) {
|
|
202
240
|
const team = teamRuntimeState(ctx)
|
|
203
241
|
const preset = await presetState(ctx)
|
|
204
242
|
const lines = []
|
|
205
243
|
|
|
206
|
-
if (team.
|
|
244
|
+
if (team.generation === 'legacy') {
|
|
207
245
|
const cap = team.maxMembers === undefined ? '' : `(maxMembers ${team.maxMembers})`
|
|
208
246
|
lines.push(`Team 运行时:已挂载${cap}`)
|
|
247
|
+
} else if (team.generation === 'subagent') {
|
|
248
|
+
lines.push('Team 运行时:已挂载(新一代,teammate 走 subagent)')
|
|
209
249
|
} else {
|
|
210
250
|
lines.push('Team 运行时:未挂载')
|
|
211
251
|
}
|
|
@@ -214,12 +254,17 @@ async function report(ctx) {
|
|
|
214
254
|
if (team.mounted && preset === 'present') {
|
|
215
255
|
lines.push('')
|
|
216
256
|
lines.push('依赖齐了。切到 Lead 模式这个预设就能派活。')
|
|
257
|
+
if (team.generation === 'subagent') lines.push(SESSION_SWITCH_HINT)
|
|
217
258
|
return { kind: 'success', text: lines.join('\n') }
|
|
218
259
|
}
|
|
219
260
|
|
|
220
261
|
lines.push('')
|
|
221
|
-
if (
|
|
222
|
-
lines.push(
|
|
262
|
+
if (team.generation === 'subagent') {
|
|
263
|
+
lines.push(`Team 运行时在(新一代)。${SESSION_SWITCH_HINT}`)
|
|
264
|
+
} else if (!team.mounted) {
|
|
265
|
+
lines.push(`Team 运行时不在。新宿主(Team 随 base 下发、teammate 走 subagent)不要装 profile 包。${SESSION_SWITCH_HINT}`)
|
|
266
|
+
lines.push('')
|
|
267
|
+
lines.push(OLD_HOST_NOTE)
|
|
223
268
|
lines.push('')
|
|
224
269
|
lines.push(` ${ENABLE_COMMAND}`)
|
|
225
270
|
lines.push('')
|
|
@@ -258,6 +303,6 @@ export function apply(ctx) {
|
|
|
258
303
|
warn('[lead-mode] commands 服务不在,/lead-mode 命令暂时没注册。它会等 dsh-commands 挂载后再注册。')
|
|
259
304
|
}
|
|
260
305
|
if (ctx.get('agentTeams') === undefined) {
|
|
261
|
-
warn(`[lead-mode] 没检测到 Team 运行时(agentTeams 服务)。Lead
|
|
306
|
+
warn(`[lead-mode] 没检测到 Team 运行时(agentTeams 服务)。Lead 模式能切,但派不了活。新宿主(Team 随 base 下发、teammate 走 subagent)不要装 profile 包;${SESSION_SWITCH_HINT}${OLD_HOST_NOTE}${ENABLE_COMMAND}。${VERSION_NOTE}`)
|
|
262
307
|
}
|
|
263
308
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-lead-mode",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Lead mode for DSH: an agent preset, a working-method skill, a dependency self-check, and two reminders that tell you to enable the official Agent Teams. | 给 DSH 加 Lead 模式:预设、skill、依赖自检、两条前置提醒。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -1,25 +1,44 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lead-mode
|
|
3
|
-
description: Lead
|
|
3
|
+
description: Lead 工作法,兼容两代 Agent Teams 定义。当你要拆活、派活给 teammate、用共享任务板协作,或验收多路并行产出时用。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Lead 工作法
|
|
7
7
|
|
|
8
8
|
你是 Lead。你拆活、派活、验收。动手的活尽量派出去,别自己一个人干完。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
宿主里同时存在两代 Agent Teams 定义,工具名不一样,工作法主体一样。先判代际,再读对应那几节。
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## 开工先确认能不能派活:按工具清单判代际
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
不靠版本号字符串判断,靠本会话的工具清单判断:
|
|
15
|
+
|
|
16
|
+
| 判据 | 属于 | 建成员 | 发消息 / 打断 | 往下读 |
|
|
17
|
+
|---|---|---|---|---|
|
|
18
|
+
| 有 `spawn_teammate` | 老一代(已发布宿主 0.2.2-rc.1 这一线) | `spawn_teammate` | `send_message({ target })` / `interrupt_agent({ target })` | 「老一代」各节 |
|
|
19
|
+
| 没有 `spawn_teammate`,但有 `subagent` 和 `team_task_*` | 新一代 | `subagent`,继承历史用 `subagent_fork` | `send_message({ agent })` / `interrupt_agent({ agent })` | 「新一代」那一节 |
|
|
20
|
+
| `team_task_*` 一个都没有 | Team 没开 | — | — | 「没开 Team 怎么办」 |
|
|
21
|
+
|
|
22
|
+
判完代际再动手:老一代按原文执行,语义一字不改;新一代按「新一代」那一节。
|
|
23
|
+
|
|
24
|
+
不要自己硬干,也不要假装能派活。
|
|
25
|
+
|
|
26
|
+
## 没开 Team 怎么办
|
|
27
|
+
|
|
28
|
+
没有 `team_task_*` 就停下,别自己把活干完,也别说自己能派活。顺序不能反:先看会话开关,再谈装包。
|
|
29
|
+
|
|
30
|
+
1. 先让用户打开会话开关。位置在**模型与推理等级菜单**里的**「使用智能体团队」**。新一代宿主的 Team 插件随 base 与 web 组合下发,打开这个开关就有工具,不需要装任何包。
|
|
31
|
+
2. 只有确认是老一代宿主(≤ `0.2.2-rc.1`,那个菜单里没有这个开关)才是缺 profile 包,这时才给装包命令:
|
|
15
32
|
|
|
16
33
|
```
|
|
17
34
|
dsh plugin --profile <你的 profile 名> add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.2-rc.1
|
|
18
35
|
```
|
|
19
36
|
|
|
20
|
-
不带版本号会装到 0.1.5-alpha.2,和 0.2.2 宿主对不上。版本号要跟 `dsh --version`
|
|
37
|
+
不带版本号会装到 0.1.5-alpha.2,和 0.2.2 宿主对不上。版本号要跟 `dsh --version` 的输出一致。装完重启 dsh。
|
|
21
38
|
|
|
22
|
-
|
|
39
|
+
新版宿主上**不要**让人装这个包。它已进 `RETIRED_BUNDLES`,app-boot 启动时会把它从 profile 里删掉。装了白装,还会让人以为开关是坏的。
|
|
40
|
+
|
|
41
|
+
不确定是哪一代时,先问一句「模型与推理等级菜单里有没有『使用智能体团队』这个开关」,别直接甩装包命令。用户跑 `/lead-mode` 命令也能看到当前这一支的判定结果。
|
|
23
42
|
|
|
24
43
|
## 开工前对齐三件事
|
|
25
44
|
|
|
@@ -35,6 +54,8 @@ dsh plugin --profile <你的 profile 名> add @deepseek-ai/dsh-experimental-agen
|
|
|
35
54
|
|
|
36
55
|
teammate 干完你**会被唤醒**,不用自己盯着。
|
|
37
56
|
|
|
57
|
+
下面这张表是老一代的事件语义:
|
|
58
|
+
|
|
38
59
|
| 事件 | 唤醒空闲的你吗 | 带回什么 |
|
|
39
60
|
|---|---|---|
|
|
40
61
|
| teammate 一轮干完、没有新消息 | 会 | 它收尾那条消息 |
|
|
@@ -43,7 +64,12 @@ teammate 干完你**会被唤醒**,不用自己盯着。
|
|
|
43
64
|
|
|
44
65
|
所以默认这么做:**派完活就结束回合。** 把「派了谁、等什么」写清楚,然后收工。用户立刻看到进展,你不空转。teammate 收工时你被唤醒,接着干。
|
|
45
66
|
|
|
46
|
-
`wait_agent`
|
|
67
|
+
`wait_agent` 只在「本回合内就必须拿到结果才能继续」时用一次。老一代的好处是 task 变更也能唤醒它。默认等 30 秒,上限 1 小时。
|
|
68
|
+
|
|
69
|
+
新一代的差别只有两条,其余照旧:
|
|
70
|
+
|
|
71
|
+
- `wait_agent` 等的是**你自己收件箱**的下一条输入,只回 `{ timedOut }`。`timedOut: false` 表示已有新输入待处理;`timedOut: true` 就是等到超时。**没有 `noProgress` 这种返回。**
|
|
72
|
+
- task 变更不结束 `wait_agent`、不往收件箱塞消息、也不启动空闲成员。要成员处理任务,必须 `send_message` 叫它。
|
|
47
73
|
|
|
48
74
|
禁止这两件事:
|
|
49
75
|
|
|
@@ -52,9 +78,11 @@ teammate 干完你**会被唤醒**,不用自己盯着。
|
|
|
52
78
|
|
|
53
79
|
`list_agents` 只用来回答「谁在跑、谁卡住了」,不用来等。
|
|
54
80
|
|
|
55
|
-
|
|
81
|
+
老一代还有一条:`wait_agent` 返回 `noProgress` 不是错误,是告诉你没人在跑,该换手段。新一代没有这个返回,别去找它。
|
|
56
82
|
|
|
57
|
-
##
|
|
83
|
+
## 老一代:派活的四个参数
|
|
84
|
+
|
|
85
|
+
判据:本会话有 `spawn_teammate`。没有的话看后面「新一代:teammate 走 subagent」那一节。
|
|
58
86
|
|
|
59
87
|
`spawn_teammate` 只有 `name`、`description`、`prompt`、`context` 四个参数。
|
|
60
88
|
|
|
@@ -109,6 +137,10 @@ teammate 收工时,它**最后那条消息**会随通知回到你手上,格
|
|
|
109
137
|
|
|
110
138
|
## 上下文变长怎么办:压缩、复用、交接、换人
|
|
111
139
|
|
|
140
|
+
这一节的工具细节按老一代写(`list_agents` 给成员 id、`spawn_teammate` 建人、`interrupt_agent({ target })`)。
|
|
141
|
+
|
|
142
|
+
新一代的对应关系只有三处:建人换 `subagent`(`subagent_fork` 继承你已完成回合),`interrupt_agent` 的参数名换成 `agent`,`list_agents` 只给名字和路径、不给 session id。所以「怎么检测」那一步拿不到 id 就跳过,照实写「未验证」,别硬编一个 id。
|
|
143
|
+
|
|
112
144
|
### 为什么会丢
|
|
113
145
|
|
|
114
146
|
宿主对每个 agent 都自动压缩会话。压力到阈值就触发,会话 id 不变,早期节点被一条摘要替换。这就是**上下文降级**:细节只剩摘要,不再完整可见。
|
|
@@ -136,7 +168,7 @@ teammate 收工时,它**最后那条消息**会随通知回到你手上,格
|
|
|
136
168
|
1. 继续跑:命中 0–1 次、活快收尾,交给自动压缩兜住。
|
|
137
169
|
2. 重发窄单:用 `send_message` 给同一个成员一张更窄的单,只做剩下的部分。成员常驻,别急着换人。
|
|
138
170
|
3. 写交接文档:要求它先补完工作日志,再写 handoff,然后 `interrupt_agent`。
|
|
139
|
-
4.
|
|
171
|
+
4. 换新成员(老一代,新一代换成 `subagent`):`spawn_teammate`,`context` 用 `fresh`。原因写死:`fork` 拷的是你 Lead 自己的历史,不是上一个成员的历史,所以拿不到前任的细节。
|
|
140
172
|
|
|
141
173
|
### 工作日志与交接文档放哪
|
|
142
174
|
|
|
@@ -162,7 +194,7 @@ teammate 收工时,它**最后那条消息**会随通知回到你手上,格
|
|
|
162
194
|
|
|
163
195
|
### 换人操作清单
|
|
164
196
|
|
|
165
|
-
- 先查名额:`/lead-mode` 报 `maxMembers
|
|
197
|
+
- 先查名额:`/lead-mode` 报 `maxMembers`。换一次吃一个名额,创建失败的也占位,名字永不复用。新一代读不到上限,这条跳过。
|
|
166
198
|
- 旧 task 你先 `team_task_update` 执行 `release`,续作成员再 `claim`。revision 会变。
|
|
167
199
|
- 续作成员名字加 `-r2` 后缀,与被接手的成员并存,不要复用旧名字。
|
|
168
200
|
- `interrupt_agent` 不清空它排队的消息,打断前确认工作日志已写完。
|
|
@@ -193,7 +225,16 @@ task 描述就是完整规格。规格写细一点,teammate 少问一轮。
|
|
|
193
225
|
|
|
194
226
|
task 是给人看的账本,不是唤醒通道。别指望「它把 task 标 complete 了我就知道了」。
|
|
195
227
|
|
|
196
|
-
|
|
228
|
+
新一代的差别只有 owner 这一块:
|
|
229
|
+
|
|
230
|
+
- 任务视图里的判据字段是 `ownerId`,老一代是 `ownerName`。
|
|
231
|
+
- owner 填成员名即可,也接受 Session id。
|
|
232
|
+
- 根 agent(`lead`)能把任务改派给自己或任何可续聊的后代;其他成员只能自己 claim 就绪的任务。
|
|
233
|
+
- 就绪状态不会启动 owner,任务变更也不唤醒任何人。要成员处理任务,必须 `send_message` 叫它。
|
|
234
|
+
|
|
235
|
+
## 老一代:teammate 用什么模型
|
|
236
|
+
|
|
237
|
+
判据:本会话有 `spawn_teammate`。新一代的规则在下一节。
|
|
197
238
|
|
|
198
239
|
**不能单独指定。** `spawn_teammate` 没有 model 或 provider 参数。
|
|
199
240
|
|
|
@@ -206,7 +247,72 @@ teammate 继承你(Lead)在 spawn 那一刻的 provider 和 model。想换
|
|
|
206
247
|
|
|
207
248
|
经典 `subagent` 支持 `provider`、`model`、`reasoning_effort`、`agent_preset` 四个参数(本插件预设已开 `modelSelection` 与 `modelDiscovery`)。
|
|
208
249
|
|
|
209
|
-
代价说清楚:经典 `subagent`
|
|
250
|
+
代价说清楚:经典 `subagent` 是一次性子代理,没有共享任务板,没有持久身份。要用团队就得接受统一模型。这段代价只对老一代成立:新一代的 teammate 本身就是 `subagent`,也能按成员挑模型,见下一节。
|
|
251
|
+
|
|
252
|
+
## 新一代:teammate 走 subagent
|
|
253
|
+
|
|
254
|
+
判据:本会话没有 `spawn_teammate`,但有 `subagent` 和 `team_task_*`。下面按工具的真实签名写,别按老一代的习惯推。
|
|
255
|
+
|
|
256
|
+
### 建成员
|
|
257
|
+
|
|
258
|
+
`subagent({ name, description, prompt })` 就是老一代的 `spawn_teammate`:teammate 和子代理是同一个东西,不需要再找 team 专用工具。调用立刻返回子代理的名字,不等它干活。
|
|
259
|
+
|
|
260
|
+
| 参数 | 要点 |
|
|
261
|
+
|---|---|
|
|
262
|
+
| `description` | 必填。三到五个词的职责,显示用 |
|
|
263
|
+
| `prompt` | 必填。全部指令,写法照「prompt 怎么写」那一节 |
|
|
264
|
+
| `name` | 可选。小写字母、数字、连字符,字母开头,最长 32 个字符。同一棵树内唯一,`lead` 留给根不能用。省略时按 `agent-1`、`agent-2` 顺序自动命名 |
|
|
265
|
+
| `cwd` | 可选。子代理的初始工作目录,省略就继承你的 |
|
|
266
|
+
| `provider` / `model` / `reasoning_effort` | 可选。按成员挑模型,规则见下面「成员模型」 |
|
|
267
|
+
| `agent_preset` | 可选。只在宿主开放预设选择时才出现这个参数,本插件预设没开 |
|
|
268
|
+
|
|
269
|
+
新成员默认看不到你的历史,这点和老一代的 `fresh` 一样。要它继承**你已完成回合**的上下文,用 `subagent_fork`(参数同上,本插件预设里它没有模型参数)。
|
|
270
|
+
|
|
271
|
+
命名规则和老一代不同:新一代没有「名字永久占用」,只是同一棵树内唯一。取名前照样先 `list_agents` 看一眼。
|
|
272
|
+
|
|
273
|
+
### 发消息、续聊、打断
|
|
274
|
+
|
|
275
|
+
- `send_message({ agent, message })`。`agent` 填 `list_agents` 给出的名字或路径,返回 `{ messageId }`。`inactive` 的成员收到消息会起一轮。
|
|
276
|
+
- `interrupt_agent({ agent })`。返回 `{ accepted }`,只是受理,不等它真停。它自己起的子代理会继续跑。
|
|
277
|
+
- 参数名是 `agent`,不是老一代的 `target`。
|
|
278
|
+
|
|
279
|
+
### 等活
|
|
280
|
+
|
|
281
|
+
新一代的 `wait_agent` 是普通 subagent 控制工具,不是 team 作用域:
|
|
282
|
+
|
|
283
|
+
- 等的是**你自己收件箱**的下一条输入:成员消息、完成通知、用户插话。
|
|
284
|
+
- 只返回 `{ timedOut }`。`timedOut: false` 表示已有新输入待处理;`timedOut: true` 是等满了没人找你。
|
|
285
|
+
- **没有 `noProgress`。** 别照老一代的写法去判它。
|
|
286
|
+
- `timeout_ms` 取值 10000 到 3600000,默认 30000。
|
|
287
|
+
|
|
288
|
+
结论不变:派完活就结束回合等通知,不套循环。
|
|
289
|
+
|
|
290
|
+
### 任务板
|
|
291
|
+
|
|
292
|
+
`team_task_list` / `get` / `create` / `update` 四个名字两代一样,claim 与 owner 的差别见前面「共享任务流程」末尾那几条。
|
|
293
|
+
|
|
294
|
+
### 成员模型
|
|
295
|
+
|
|
296
|
+
可以按成员挑:`subagent` 传 `provider`、`model`、`reasoning_effort`。`provider` 与 `model` 要成对给;`reasoning_effort` 要在两者都给了的前提下用。不传就跟随默认,回落到兼容的父值。
|
|
297
|
+
|
|
298
|
+
所以老一代那句「teammate 不能单独指定模型,只能整队换」只对老一代成立。
|
|
299
|
+
|
|
300
|
+
### 名册
|
|
301
|
+
|
|
302
|
+
`list_agents({})` 返回整棵树,从根开始,含你自己这一行。行是 `{ name, status, description? }`。
|
|
303
|
+
|
|
304
|
+
- 后代名字是从根算起的路径,比如 `reviewer/checker`;根固定叫 `lead`。
|
|
305
|
+
- 可以直接给树里任何其他成员发消息。
|
|
306
|
+
- 状态多了三种:`corrupt`、`unsupported`、`unavailable`,说的是这一行自己的后代读不出来,这一行本身仍是能发消息的成员。
|
|
307
|
+
- `inactive` 仍然不代表活干完、也不代表失败。
|
|
308
|
+
|
|
309
|
+
### 完成通知
|
|
310
|
+
|
|
311
|
+
成员的完成通知会自动送到你手上,带着它的最终答复,「Its closing message:」这个格式仍然适用。收工前刚给你发过 `send_message` 的,通知里省掉收尾正文。
|
|
312
|
+
|
|
313
|
+
### 成员上限
|
|
314
|
+
|
|
315
|
+
新一代读不到上限:`maxMembers` 这个配置键已被拒绝。别在报告里写一个假数字。
|
|
210
316
|
|
|
211
317
|
## 状态怎么看
|
|
212
318
|
|
|
@@ -217,9 +323,11 @@ teammate 继承你(Lead)在 spawn 那一刻的 provider 和 model。想换
|
|
|
217
323
|
| `provisioning` | 正在创建 |
|
|
218
324
|
| `failed` | 创建失败 |
|
|
219
325
|
|
|
326
|
+
这张表是老一代的取值。新一代没有 `provisioning` 与 `failed`,多了 `corrupt`、`unsupported`、`unavailable` 三种,含义见「新一代」那节的「名册」。
|
|
327
|
+
|
|
220
328
|
`inactive` 有两种情况:teammate 已经收工(你收到过它的通知),或者它被存档了、等你再给它发消息才醒来。
|
|
221
329
|
|
|
222
|
-
|
|
330
|
+
老一代只有 Lead 能创建和打断 teammate(`interrupt_agent`),打断不清空它排队的消息。新一代不限于根:成员也能建自己的子代理,`interrupt_agent` 可以由任何祖先发给它下面直接或更深的那个后代。
|
|
223
331
|
|
|
224
332
|
### 想看全局,用 dsh-context 的编队页
|
|
225
333
|
|
|
@@ -150,6 +150,8 @@ session_event_search({
|
|
|
150
150
|
})
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
+
成员 id 老一代由 `list_agents` 直接给出。新一代的 `list_agents` 只给名字和路径、不给 session id,拿不到 id 就跳过这一层,照实写「未验证」。
|
|
154
|
+
|
|
153
155
|
两条限制:
|
|
154
156
|
|
|
155
157
|
- 跨 cwd 读不到。成员会话的工作目录必须和 Lead 相同,否则这条查不到东西。
|
|
@@ -186,10 +188,10 @@ session_event_search({
|
|
|
186
188
|
| 事实 | 后果 |
|
|
187
189
|
|---|---|
|
|
188
190
|
| `team_task_update` 的 `complete` 不能带结果载荷 | 任务板不是结果记录本,结论只能写进汇总 |
|
|
189
|
-
| `wait_agent` 只返回 `{timedOut
|
|
191
|
+
| `wait_agent` 只返回 `{timedOut}`(老一代还多一个 `noProgress`) | 它不带任何内容,别指望从返回值里拿到成员说了什么 |
|
|
190
192
|
| 宿主没有报告类工具 | 汇总只能自己组织,没有现成模板命令可调 |
|
|
191
193
|
| 压缩事件(`compaction/start` 等)都是 log-only | 检索必须显式带 `surfaces: ['log-only']`,否则查不到 |
|
|
192
|
-
| 成员名额 `maxMembers`
|
|
194
|
+
| 成员名额 `maxMembers` 只有老一代可读(新一代拒绝这个配置键) | 老一代名字永不释放,创建失败也占名额;新一代读不到上限,别写一个假数字 |
|
|
193
195
|
|
|
194
196
|
## 写作口径
|
|
195
197
|
|