@nanmicoder/dsh-agent-teams 0.1.15 → 0.1.16-rc.3
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 +24 -44
- package/README_ZH.md +24 -44
- package/compatibility.json +10 -0
- package/lib/capabilities.js +106 -0
- package/lib/client/ActivityPanel.js +2 -2
- package/lib/client/locales.js +0 -2
- package/lib/client.js +30 -32
- package/lib/client.js.map +1 -1
- package/lib/command.js +3 -3
- package/lib/harness-compat.js +159 -0
- package/lib/index.js +47 -75
- package/lib/members.js +185 -73
- package/lib/profiles.js +1 -1
- package/lib/quality-gates.js +45 -0
- package/lib/scheduler.js +37 -12
- package/lib/state.js +44 -11
- package/lib/tool-names.js +11 -0
- package/lib/tools.js +81 -64
- package/lib/types/capabilities.d.ts +14 -0
- package/lib/types/client/locales.d.ts +0 -2
- package/lib/types/harness-compat.d.ts +22 -0
- package/lib/types/index.d.ts +3 -1
- package/lib/types/members.d.ts +21 -5
- package/lib/types/quality-gates.d.ts +8 -0
- package/lib/types/scheduler.d.ts +7 -1
- package/lib/types/state.d.ts +8 -2
- package/lib/types/tool-names.d.ts +4 -0
- package/lib/types/tools.d.ts +4 -1
- package/lib/types/web-routes.d.ts +6 -0
- package/lib/web-routes.js +60 -0
- package/package.json +69 -58
- package/release-notes/v0.1.11.md +1 -1
- package/release-notes/v0.1.16-rc.1.md +33 -0
- package/release-notes/v0.1.16-rc.2.md +33 -0
- package/release-notes/v0.1.16-rc.3.md +33 -0
- package/scripts/compatibility.mjs +90 -0
- package/scripts/doctor.mjs +126 -0
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
`dsh-agent-teams` turns the current DeepSeek Harness session into a captain that can assemble durable sub-agents, split a goal into dependency-aware tasks, and coordinate work through direct messages.
|
|
24
24
|
|
|
25
|
-
Ask in natural language. The plugin provides the team protocol,
|
|
25
|
+
Ask in natural language. The plugin provides the team protocol, 13 coordination tools, persistent state, an automatic shared-task scheduler, and a live Web UI—without requiring a separate workflow engine.
|
|
26
26
|
|
|
27
27
|
<p align="center">
|
|
28
28
|
<img src="./assets/ui.png" width="100%" alt="DeepSeek Harness conversation with the AgentTeams live activity panel, members, tasks, dependencies, and reports">
|
|
@@ -30,7 +30,7 @@ Ask in natural language. The plugin provides the team protocol, eleven coordinat
|
|
|
30
30
|
|
|
31
31
|
## Releases
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
[v0.1.16-rc.3](./release-notes/v0.1.16-rc.3.md) targets npm `next`, with a concise fixed team protocol, existing-team reuse guidance, Web approval wakeups, and team-lock cleanup. Choose a version pair below.
|
|
34
34
|
|
|
35
35
|
## Why AgentTeams?
|
|
36
36
|
|
|
@@ -47,64 +47,40 @@ The [latest release](https://github.com/NanmiCoder/dsh-agent-teams/releases/late
|
|
|
47
47
|
|
|
48
48
|
The conversation card and activity panel use Harness's official locale service. They follow live language changes between English and Simplified Chinese—including status labels, dynamic summaries, controls, archive markers, and accessibility text—without a page reload or a separate plugin setting.
|
|
49
49
|
|
|
50
|
-
## Install
|
|
50
|
+
## Install and choose versions
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
> **Plugin 0.1.15 (`@latest`) requires DeepSeek Harness 0.1.2-alpha.2.** Updating this plugin does not update Harness. This release has no adapter for the old RC host APIs. Check the version of the instance you actually launch with `dsh --version` before installing.
|
|
52
|
+
**Recommended pair: DeepSeek Harness `0.1.2-rc.1` + AgentTeams `0.1.16-rc.3`. Both are still prereleases.**
|
|
54
53
|
|
|
55
|
-
|
|
|
54
|
+
| Use case | DeepSeek Harness | AgentTeams plugin |
|
|
56
55
|
| --- | --- | --- |
|
|
57
|
-
| **0.1.2-
|
|
58
|
-
|
|
|
59
|
-
|
|
|
60
|
-
| Alpha.1, later Alpha versions, or other source revisions | Not verified | Match the documented host version or validate separately. |
|
|
56
|
+
| **Recommended installation** | **`0.1.2-rc.1`** | **`0.1.16-rc.3`** |
|
|
57
|
+
| Developer Alpha testing | `0.1.2-alpha.5` | `0.1.16-rc.3` |
|
|
58
|
+
| Retaining an older Alpha | `0.1.2-alpha.2` | `0.1.16-rc.3` |
|
|
61
59
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
See the [compatibility details](./docs/alpha2-compatibility.md) and [real business / UI acceptance report](./docs/alpha2-release-acceptance.md).
|
|
65
|
-
|
|
66
|
-
### npm: Harness Alpha.2
|
|
67
|
-
|
|
68
|
-
If you install Harness through npm, upgrade the host first, then install the matching plugin:
|
|
60
|
+
### 1. Install DeepSeek Harness
|
|
69
61
|
|
|
70
62
|
```sh
|
|
71
|
-
npm install --global @deepseek-ai/dsh@0.1.2-
|
|
63
|
+
npm install --global @deepseek-ai/dsh@0.1.2-rc.1
|
|
72
64
|
dsh --version
|
|
73
|
-
dsh plugin --profile web add @nanmicoder/dsh-agent-teams@latest
|
|
74
65
|
```
|
|
75
66
|
|
|
76
|
-
|
|
67
|
+
Skip this if you already run this version. Alpha is opt-in: select an exact Alpha version from the table and lock all host dependencies as described in the [maintenance guide](./docs/maintenance-workflow.md).
|
|
77
68
|
|
|
78
|
-
###
|
|
69
|
+
### 2. Install the AgentTeams plugin
|
|
79
70
|
|
|
80
|
-
|
|
71
|
+
This installs into the `web` profile. Replace `web` with your actual profile name if different:
|
|
81
72
|
|
|
82
73
|
```sh
|
|
83
|
-
dsh plugin --profile web add @nanmicoder/dsh-agent-teams@0.1.
|
|
74
|
+
dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.16-rc.3
|
|
84
75
|
```
|
|
85
76
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
**Harness built from source:** updating this plugin repository, rebuilding it, or installing a global CLI does not upgrade a separately launched Harness checkout. Preserve your local changes, update the actual host checkout to [dsh-v0.1.2-alpha.2](https://github.com/deepseek-ai/deepseek-harness/tree/dsh-v0.1.2-alpha.2), follow its build instructions, and restart that host. If its source must stay old, keep the old plugin too; for a source-linked plugin use tag `v0.1.14` and its matching dependencies/build, not the current `main` branch.
|
|
77
|
+
**After installation, stop and restart Harness for that profile, then refresh the browser.**
|
|
89
78
|
|
|
90
|
-
|
|
79
|
+
Plugin `0.1.16-rc.3` uses the `next` channel; `latest` still points to `0.1.15`, which targets Alpha.2. Use the exact-version command above. Future plugin prereleases use `next`; only stable plugin releases that pass the full verification matrix may use `latest`.
|
|
91
80
|
|
|
92
|
-
|
|
93
|
-
git clone --branch v0.1.15 https://github.com/NanmiCoder/dsh-agent-teams.git
|
|
94
|
-
cd dsh-agent-teams
|
|
95
|
-
pnpm install --frozen-lockfile
|
|
96
|
-
pnpm build
|
|
97
|
-
dsh plugin --profile web add .
|
|
98
|
-
```
|
|
81
|
+
> Desktop users must check the app's embedded Harness core; upgrading the global CLI does not upgrade it. For older `0.1.0-*` / `0.1.1-*` or unlisted hosts, keep a working pair and follow the [older-version and diagnostic guide](./docs/maintenance-workflow.md).
|
|
99
82
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
Validate the composed profile, restart DSH, and refresh the Web UI:
|
|
103
|
-
|
|
104
|
-
```sh
|
|
105
|
-
dsh --profile web --dump-config
|
|
106
|
-
dsh web
|
|
107
|
-
```
|
|
83
|
+
See the full [compatibility matrix](./compatibility.json), [source installation and Alpha testing guide](./docs/maintenance-workflow.md), and [verification coverage and platform limits](./docs/maintenance-2026-09-06/release/README.md).
|
|
108
84
|
|
|
109
85
|
Then ask for a team directly:
|
|
110
86
|
|
|
@@ -112,7 +88,7 @@ Then ask for a team directly:
|
|
|
112
88
|
|
|
113
89
|
## How it works
|
|
114
90
|
|
|
115
|
-
1.
|
|
91
|
+
1. For a request to use AgentTeams, the captain follows the core protocol already in its system instructions. It continues an existing team and uses `agent_teams_status` when current state needs checking. When no team exists, the goal becomes a staged plan for review.
|
|
116
92
|
2. The captain adds role-specific members backed by continuable sub-agents.
|
|
117
93
|
3. The goal becomes tasks with owners and explicit dependencies.
|
|
118
94
|
4. The shared scheduler uses real `running / idle / ready` state to atomically claim one ready task per idle member and wake it. An interrupted resident attempt stays parked and can resume through a direct message without losing its capability; after a cold process restart, the scheduler retries stranded open work with a fresh attempt.
|
|
@@ -123,6 +99,8 @@ Team state is stored under `<workspace>/.agent-teams/`; the Web panel reads that
|
|
|
123
99
|
|
|
124
100
|
Member creation is zero-interaction by default: a member on the captain's current LLM route snapshots that provider, model, and reasoning effort, while a member on a requested alternative route snapshots the target model's default effort; later continuations restore the resolved snapshot. Only an explicit heterogeneous-team request (for example, “backend on provider A/model X, frontend on provider B/model Y”) supplies a member-specific `provider` + `model`; there is no per-member model or reasoning prompt.
|
|
125
101
|
|
|
102
|
+
Captain sessions keep the concise core protocol and the original 13 native team tools from their first request. All business tools are directly available; no loading tool or extra activation call is needed. Configured profiles retain their bounded directory in the fixed system prompt. Creating, approving, continuing or ending a team does not rewrite the system prompt or tool schemas. Core rules remain available after history compaction or discarded code-mode tool results. Members receive four team tools, fixed member instructions, and their ordinary coding/research tools. Web approval wakes the captain with a control message; later member reports wake it again. See the [fixed protocol and benchmark contract](./docs/progressive-loading.md).
|
|
103
|
+
|
|
126
104
|
## Slash command
|
|
127
105
|
|
|
128
106
|
No “use AgentTeams” phrasing required. The plugin registers the
|
|
@@ -137,7 +115,7 @@ command), describe the goal, and press Enter.
|
|
|
137
115
|
The command pipeline claims the line, then preserves that exact input as an
|
|
138
116
|
ordinary user follow-up so it remains visible in the main chat. The gesture
|
|
139
117
|
boundary adds the deterministic activation directive at pre-step, so the
|
|
140
|
-
|
|
118
|
+
first model request follows the staged planning protocol without a mandatory helper call. The invocation is also durably
|
|
141
119
|
logged (`command/run` / `command/done`).
|
|
142
120
|
|
|
143
121
|
Surfaces without command adjudication (for example the headless CLI) get the
|
|
@@ -174,6 +152,8 @@ See [docs/usage.md](./docs/usage.md) for the full tool reference, state model, W
|
|
|
174
152
|
|
|
175
153
|
## Plugin development Skill
|
|
176
154
|
|
|
155
|
+
Community upgrade, audit, benchmark, testing and release skills are vendored with a pinned source revision. See [skills/README.md](./skills/README.md) for local rules and [CONTRIBUTING.md](./CONTRIBUTING.md) for the contribution workflow.
|
|
156
|
+
|
|
177
157
|
The repository also ships the open Agent Skills package [`dsh-plugin-development`](./skills/dsh-plugin-development/SKILL.md):
|
|
178
158
|
|
|
179
159
|
```sh
|
package/README_ZH.md
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
|
|
23
23
|
`dsh-agent-teams` 让当前 DeepSeek Harness 会话成为队长:创建可续聊的子 Agent、把目标拆成有依赖的任务,并通过直达消息协调成员工作。
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
你只需用自然语言提出目标。插件会提供精简的固定团队协议、13 个业务工具、持久化状态、自动共享任务调度和实时 Web UI,不需要额外的 Workflow 引擎。
|
|
26
26
|
|
|
27
27
|
<p align="center">
|
|
28
28
|
<img src="./assets/ui.png" width="100%" alt="DeepSeek Harness 对话与 AgentTeams 实时活动面板,展示成员、任务依赖和回报">
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
|
|
31
31
|
## 版本更新
|
|
32
32
|
|
|
33
|
-
[
|
|
33
|
+
[v0.1.16-rc.3](./release-notes/v0.1.16-rc.3.md) 面向 npm `next` 渠道,精简固定团队协议、引导复用已有团队,并修复 Web 批准通知和团队锁清理。安装版本见下方配对表。
|
|
34
34
|
|
|
35
35
|
## 为什么需要 AgentTeams?
|
|
36
36
|
|
|
@@ -46,69 +46,47 @@
|
|
|
46
46
|
|
|
47
47
|
对话卡片与活动面板接入 Harness 官方多语言服务,会随宿主在简体中文和英文之间实时切换;任务/成员状态、动态摘要、操作按钮、历史归档标识和无障碍文案都会同步更新,无需刷新页面,也不增加插件自己的语言设置。
|
|
48
48
|
|
|
49
|
-
##
|
|
49
|
+
## 安装与版本选择
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
> **插件 0.1.15(`@latest`)对应 DeepSeek Harness 0.1.2-alpha.2。** 升级插件不会自动升级 Harness,本版也没有兼容旧 RC 宿主 API 的适配层。安装前先用 `dsh --version` 核对你实际启动的宿主版本。
|
|
51
|
+
**推荐组合:DeepSeek Harness `0.1.2-rc.1` + AgentTeams `0.1.16-rc.3`。两者都仍是预发布版本。**
|
|
53
52
|
|
|
54
|
-
|
|
|
53
|
+
| 使用场景 | DeepSeek Harness | AgentTeams 插件 |
|
|
55
54
|
| --- | --- | --- |
|
|
56
|
-
|
|
|
57
|
-
|
|
|
58
|
-
|
|
|
59
|
-
| Alpha.1、后续 Alpha 或其他源码提交 | 尚未验证 | 请对齐上面明确验证的宿主版本,或单独验证。 |
|
|
55
|
+
| **推荐安装** | **`0.1.2-rc.1`** | **`0.1.16-rc.3`** |
|
|
56
|
+
| 开发者测试 Alpha | `0.1.2-alpha.5` | `0.1.16-rc.3` |
|
|
57
|
+
| 保留旧 Alpha | `0.1.2-alpha.2` | `0.1.16-rc.3` |
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
详见[兼容性记录](./docs/alpha2-compatibility.md)和[真实业务 / UI 验收报告](./docs/alpha2-release-acceptance.md)。
|
|
64
|
-
|
|
65
|
-
### npm:使用 Harness Alpha.2
|
|
66
|
-
|
|
67
|
-
通过 npm 安装 Harness 的用户,先升级宿主,再安装对应插件:
|
|
59
|
+
### 1. 安装 DeepSeek Harness
|
|
68
60
|
|
|
69
61
|
```sh
|
|
70
|
-
npm install --global @deepseek-ai/dsh@0.1.2-
|
|
62
|
+
npm install --global @deepseek-ai/dsh@0.1.2-rc.1
|
|
71
63
|
dsh --version
|
|
72
|
-
dsh plugin --profile web add @nanmicoder/dsh-agent-teams@latest
|
|
73
64
|
```
|
|
74
65
|
|
|
75
|
-
|
|
66
|
+
已有该版本可跳过。Alpha 仅供主动测试:手动指定表中的 Alpha 版本,并按[维护指南](./docs/maintenance-workflow.md)锁定整组宿主依赖。
|
|
76
67
|
|
|
77
|
-
###
|
|
68
|
+
### 2. 安装 AgentTeams 插件
|
|
78
69
|
|
|
79
|
-
|
|
70
|
+
以下安装到 `web` profile;使用其他 profile 时,将 `web` 换成实际名称:
|
|
80
71
|
|
|
81
72
|
```sh
|
|
82
|
-
dsh plugin --profile web add @nanmicoder/dsh-agent-teams@0.1.
|
|
73
|
+
dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.16-rc.3
|
|
83
74
|
```
|
|
84
75
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
**从源码运行 Harness 的用户:** 更新本插件仓库、重新构建插件,或安装全局 CLI,都不会自动升级另一个正在运行的 Harness 源码目录。请先保留本地改动,把实际启动的宿主源码更新到 [dsh-v0.1.2-alpha.2](https://github.com/deepseek-ai/deepseek-harness/tree/dsh-v0.1.2-alpha.2),按该版本说明安装依赖、构建并重启。如果宿主源码必须保持旧版,插件也应保留旧版;本地链接插件请使用 `v0.1.14` tag 及其对应依赖和构建,不要直接更新到当前 `main`。
|
|
76
|
+
**安装后,停止并重新启动该 profile 的 Harness 进程,再刷新浏览器。**
|
|
88
77
|
|
|
89
|
-
|
|
78
|
+
插件 `0.1.16-rc.3` 使用 `next` 渠道;当前 `latest` 仍是面向 Alpha.2 的 `0.1.15`。请使用上面的精确版本命令。后续插件预发布版本继续进入 `next`,通过完整验证的正式版本才进入 `latest`。
|
|
90
79
|
|
|
91
|
-
|
|
92
|
-
git clone --branch v0.1.15 https://github.com/NanmiCoder/dsh-agent-teams.git
|
|
93
|
-
cd dsh-agent-teams
|
|
94
|
-
pnpm install --frozen-lockfile
|
|
95
|
-
pnpm build
|
|
96
|
-
dsh plugin --profile web add .
|
|
97
|
-
```
|
|
80
|
+
> Desktop 用户需核对应用内置的 Harness 核心;全局 CLI 升级不会升级桌面内核。旧 `0.1.0-*` / `0.1.1-*` 或其他未列出的宿主,请先保留已工作的组合,参考[旧版本与诊断指引](./docs/maintenance-workflow.md)。
|
|
98
81
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
检查组合配置、重启 DSH,然后刷新 Web UI:
|
|
102
|
-
|
|
103
|
-
```sh
|
|
104
|
-
dsh --profile web --dump-config
|
|
105
|
-
dsh web
|
|
106
|
-
```
|
|
82
|
+
完整[兼容清单](./compatibility.json)、[源码安装与 Alpha 验证](./docs/maintenance-workflow.md)、[已验证范围与平台限制](./docs/maintenance-2026-09-06/release/README.md)。
|
|
107
83
|
|
|
108
84
|
接着直接用自然语言拉团队:
|
|
109
85
|
|
|
110
86
|
> 使用 AgentTeams 审查 v0.5.3 之后的提交,分别从性能、安全和产品角度分工,最后输出一份汇总报告。
|
|
111
87
|
|
|
88
|
+
队长会话从第一轮起保留精简的固定核心协议和原有 13 个业务工具,直接调用,无需额外的加载工具或激活调用。已配置模板的精简目录固定保留。创建、批准、继续或结束团队都不会改写系统提示词和工具 schema,会话压缩或代码模式丢弃工具结果也不会丢失核心规则。成员保留四个团队工具、固定成员说明及普通编程/研究工具。Web 批准后会通知并唤醒队长,后续成员报告会再次唤醒它,无需忙轮询。详见[固定协议与 benchmark 标准](./docs/progressive-loading.md)。
|
|
89
|
+
|
|
112
90
|
## 工作方式
|
|
113
91
|
|
|
114
92
|
1. 当前会话创建团队并成为队长。
|
|
@@ -163,7 +141,9 @@ dsh web
|
|
|
163
141
|
|
|
164
142
|
## 插件开发 Skill
|
|
165
143
|
|
|
166
|
-
|
|
144
|
+
仓库已引入社区升级、审计、测试和发布 skills,来源与本项目规则见 [skills/README.md](./skills/README.md),贡献入口见 [CONTRIBUTING.md](./CONTRIBUTING.md)。
|
|
145
|
+
|
|
146
|
+
另提供开放 Agent Skills 包 [`dsh-plugin-development`](./skills/dsh-plugin-development/SKILL.md):
|
|
167
147
|
|
|
168
148
|
```sh
|
|
169
149
|
npx skills add NanmiCoder/dsh-agent-teams --skill dsh-plugin-development
|
|
@@ -190,7 +170,7 @@ pnpm verify
|
|
|
190
170
|
|
|
191
171
|
在 `cordis.patch.yml` 的 `profiles` 中配置完整团队模板。每个 profile 都提供成员阵容,可独立指定 provider、model、role、reasoning_effort。`taskPlanning: captain` 表示只提供阵容和约束,由 Captain 根据用户目标设计 DAG;省略该字段或设为 `seed` 时,展开模板中的固定任务图。使用 `/agent-teams --profile <名称> <目标>` 显式激活;不会把首个普通 token 隐式识别为 profile。
|
|
192
172
|
|
|
193
|
-
普通 `/agent-teams`
|
|
173
|
+
普通 `/agent-teams` 流程继续已有团队,按需调用 `agent_teams_status` 确认状态;仅在没有当前团队时调用 `agent_teams_create({ profile, approval: "required" })`:只落盘可编辑的成员占位和 DAG,不创建子会话、不领取任务。成员模型和推理等级直接读取 Harness 的模型目录。「返回对话修改」会终止仍在运行的规划轮次,让队长先追问修改方向,再用一次原子操作更新同一份草案;「放弃本次计划」经二次确认后会归档草案、中止轮次,并向模型注入不得自动重建团队的控制上下文。只有点击「确认并启动团队」才会按最终配置原子创建成员并启动就绪任务。运行中团队的停止入口位于该团队的面板标题,点击后需要二次确认,不再占用输入区域。直接工具调用方可显式传 `approval: "automatic"` 保留旧的立即执行路径。审查或测试失败不会解锁下游;自动 repair/review 不依赖 failed review。
|
|
194
174
|
|
|
195
175
|
## 许可证
|
|
196
176
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"recommendedHost": "0.1.2-rc.1",
|
|
4
|
+
"previewTag": "next",
|
|
5
|
+
"supportedHosts": [
|
|
6
|
+
{ "version": "0.1.2-rc.1", "track": "recommended" },
|
|
7
|
+
{ "version": "0.1.2-alpha.5", "track": "preview" },
|
|
8
|
+
{ "version": "0.1.2-alpha.2", "track": "legacy" }
|
|
9
|
+
]
|
|
10
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { readTeamSync, readRetiredMemberIdsSync } from "./state.js";
|
|
4
|
+
import { MEMBER_TOOL_NAMES, TEAM_TOOL_NAMES } from "./tool-names.js";
|
|
5
|
+
export const TEAM_ACTIVATION_PROMPT = 'AgentTeams (Agent Teams) provides multi-agent team collaboration. Apply these rules when the user requests it (including /agent-teams) or when continuing an existing team. Mentioning, quoting, discussing, or declining AgentTeams alone is not a request to start work.';
|
|
6
|
+
export const TEAM_MEMBER_PROMPT = 'You are an AgentTeams member. Follow your assigned member persona and task contract. Use agent_teams_claim_task, agent_teams_update_task, agent_teams_send_message and agent_teams_status for your own work. Include the current attempt_id in updates; report completion or failure to the captain. Do not create, approve, edit or resume a team. If your durable membership is unavailable, report that to the parent instead of creating a replacement.';
|
|
7
|
+
function stateRoot(agent, config) {
|
|
8
|
+
return join(agent.session.header.cwd ?? process.cwd(), config.stateDir);
|
|
9
|
+
}
|
|
10
|
+
/** Synchronous startup/HMR hydration must finish before the first assembly. */
|
|
11
|
+
function currentTeam(agent, config) {
|
|
12
|
+
const root = stateRoot(agent, config);
|
|
13
|
+
let entries;
|
|
14
|
+
try {
|
|
15
|
+
entries = readdirSync(root, { withFileTypes: true });
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (error.code === 'ENOENT')
|
|
19
|
+
return undefined;
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
let found;
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
if (!entry.isDirectory() || entry.name === 'archive')
|
|
25
|
+
continue;
|
|
26
|
+
const team = readTeamSync(root, entry.name);
|
|
27
|
+
if (team === undefined || (team.captainSessionId !== agent.id
|
|
28
|
+
&& !team.members.some(member => member.id === agent.id)))
|
|
29
|
+
continue;
|
|
30
|
+
if (found !== undefined)
|
|
31
|
+
throw new Error('ambiguous AgentTeams membership');
|
|
32
|
+
found = team;
|
|
33
|
+
}
|
|
34
|
+
return found;
|
|
35
|
+
}
|
|
36
|
+
/** Call once, after all business definitions have registered. Never per member. */
|
|
37
|
+
export function installTeamCapabilities(ctx, config) {
|
|
38
|
+
const states = new WeakMap();
|
|
39
|
+
const active = new Set();
|
|
40
|
+
let mounted = true;
|
|
41
|
+
// Snapshot policy once: profiles, team state, and tool results must never
|
|
42
|
+
// rewrite this prefix or control whether core instructions are available.
|
|
43
|
+
const captainPrompt = `${TEAM_ACTIVATION_PROMPT}\n\n${config.captainPrompt()}`;
|
|
44
|
+
function attach(agent) {
|
|
45
|
+
const prior = states.get(agent);
|
|
46
|
+
if (prior !== undefined)
|
|
47
|
+
return prior;
|
|
48
|
+
if (!mounted)
|
|
49
|
+
throw new Error('AgentTeams capability provider is disposed');
|
|
50
|
+
// Determine a member's role before its first request and retain it for the
|
|
51
|
+
// lifetime of this scope. Team creation/archive must never rewrite the
|
|
52
|
+
// captain's system/tools prefix, even after a long ordinary conversation.
|
|
53
|
+
let member = config.isPendingMember(agent);
|
|
54
|
+
try {
|
|
55
|
+
member ||= readRetiredMemberIdsSync(stateRoot(agent, config)).has(agent.id);
|
|
56
|
+
const team = currentTeam(agent, config);
|
|
57
|
+
member ||= team !== undefined && team.captainSessionId !== agent.id;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
// Unrelated damaged state must not disable ordinary conversation.
|
|
61
|
+
// Business tools still validate durable team state before acting.
|
|
62
|
+
ctx.logger.warn(`agent-teams: capability hydration failed: ${String(error)}`);
|
|
63
|
+
}
|
|
64
|
+
const state = { member, dispose: () => undefined };
|
|
65
|
+
let revoke;
|
|
66
|
+
let disposed = false;
|
|
67
|
+
let releaseLifetime;
|
|
68
|
+
state.dispose = () => {
|
|
69
|
+
if (disposed)
|
|
70
|
+
return;
|
|
71
|
+
disposed = true;
|
|
72
|
+
revoke?.();
|
|
73
|
+
releaseLifetime?.();
|
|
74
|
+
states.delete(agent);
|
|
75
|
+
active.delete(state);
|
|
76
|
+
};
|
|
77
|
+
states.set(agent, state);
|
|
78
|
+
active.add(state);
|
|
79
|
+
try {
|
|
80
|
+
if (member)
|
|
81
|
+
revoke = agent.ctx.tools.restrict({
|
|
82
|
+
deny: TEAM_TOOL_NAMES.filter(name => !MEMBER_TOOL_NAMES.includes(name)),
|
|
83
|
+
});
|
|
84
|
+
releaseLifetime = agent.ctx.effect(() => state.dispose, 'agent-teams: capability lifetime');
|
|
85
|
+
return state;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
state.dispose();
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
ctx.systemPrompt.section({
|
|
93
|
+
name: 'agent-teams:usage', order: config.order ?? 117,
|
|
94
|
+
text: ({ agent }) => {
|
|
95
|
+
return agent !== undefined && states.get(agent)?.member ? TEAM_MEMBER_PROMPT : captainPrompt;
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
ctx.on('agent/session-start', ({ agent }) => { attach(agent); });
|
|
99
|
+
ctx.effect(() => () => {
|
|
100
|
+
mounted = false;
|
|
101
|
+
for (const state of [...active])
|
|
102
|
+
state.dispose();
|
|
103
|
+
}, 'agent-teams: capability scopes');
|
|
104
|
+
for (const agent of ctx.agents.list())
|
|
105
|
+
attach(agent);
|
|
106
|
+
}
|
|
@@ -358,7 +358,7 @@ function TeamSection({ team, modelDirectory, onContinuePlanning, onDiscarded, on
|
|
|
358
358
|
if (member.id !== '') {
|
|
359
359
|
onNavigate(team.captainSessionId, member.id);
|
|
360
360
|
}
|
|
361
|
-
}, children: [_jsxs("span", { className: css.memberAvatar, "data-unread": member.unread > 0, children: [memberArtUrl(member.name, member.role) !== null ? (_jsx("img", { className: css.memberArt, src: memberArtUrl(member.name, member.role) ?? '', alt: "", "aria-hidden": true })) : (_jsx("span", { className: css.memberInitial, style: { background: accentOf(member.id) }, children: memberInitial(member.name) })), _jsx("img", { className: css.stateArt, "data-activity": member.activity, src: ACTION_ART[member.activity], alt: "", "aria-hidden": true })] }), _jsxs("span", { className: css.memberInfo, children: [_jsxs("span", { className: css.memberLine, children: [_jsx("span", { className: css.memberName, children: member.name }), member.role !== '' && _jsx("span", { className: css.memberRole, children: member.role }), _jsxs("span", { className: css.memberState, "data-activity": member.activity, children: [_jsx(WorkGlyph, { active: member.activity === 'working' }), discarded
|
|
361
|
+
}, children: [_jsxs("span", { className: css.memberAvatar, "data-unread": member.unread > 0, children: [memberArtUrl(member.name, member.role) !== null ? (_jsx("img", { className: css.memberArt, src: memberArtUrl(member.name, member.role) ?? '', alt: "", "aria-hidden": true })) : (_jsx("span", { className: css.memberInitial, style: { background: accentOf(member.id) }, children: memberInitial(member.name) })), _jsx("img", { className: css.stateArt, "data-activity": member.activity, src: ACTION_ART[member.activity], alt: "", "aria-hidden": true })] }), _jsxs("span", { className: css.memberInfo, children: [_jsxs("span", { className: css.memberLine, children: [_jsx("span", { className: css.memberName, children: member.name }), member.role !== '' && _jsx("span", { className: css.memberRole, children: member.role }), memberModel !== '' && (_jsx("span", { className: css.memberModel, role: "img", "data-member-model": memberModel, title: memberModel, "aria-label": memberModel, children: compactModelLabel(memberModel) })), _jsxs("span", { className: css.memberState, "data-activity": member.activity, children: [_jsx(WorkGlyph, { active: member.activity === 'working' }), discarded
|
|
362
362
|
? t('member.state.notCreated')
|
|
363
363
|
: stopped
|
|
364
364
|
? t('member.state.stopped')
|
|
@@ -372,7 +372,7 @@ function TeamSection({ team, modelDirectory, onContinuePlanning, onDiscarded, on
|
|
|
372
372
|
? t('member.status.staged')
|
|
373
373
|
: historic && owned.length > 0 && owned.every((task) => (task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled'))
|
|
374
374
|
? t('member.status.settled')
|
|
375
|
-
: memberStatusText(member, team.tasks, t) })
|
|
375
|
+
: memberStatusText(member, team.tasks, t) })] }), _jsxs("span", { className: css.memberCount, children: [member.done, "/", member.total] })] }), _jsxs("div", { className: css.assignmentLine, children: [_jsx("span", { className: css.assignmentLabel, children: t(discarded
|
|
376
376
|
? 'assignment.discarded'
|
|
377
377
|
: team.phase === 'staged'
|
|
378
378
|
? 'assignment.staged'
|
package/lib/client/locales.js
CHANGED
|
@@ -81,7 +81,6 @@ export const zh = {
|
|
|
81
81
|
'dependency.hint.pinned': '{taskId} 已固定 · Esc 取消',
|
|
82
82
|
'task.runningAria': '运行中',
|
|
83
83
|
'task.model': '{model}',
|
|
84
|
-
'member.model': '{model}',
|
|
85
84
|
'task.detail.completed': '已完成并交付',
|
|
86
85
|
'task.detail.noPrerequisite': '无前置,可立即开工',
|
|
87
86
|
'task.detail.ready': '前置已就绪,可开工',
|
|
@@ -273,7 +272,6 @@ export const en = {
|
|
|
273
272
|
'dependency.hint.pinned': '{taskId} pinned · Esc to clear',
|
|
274
273
|
'task.runningAria': 'Running',
|
|
275
274
|
'task.model': '{model}',
|
|
276
|
-
'member.model': '{model}',
|
|
277
275
|
'task.detail.completed': 'Completed and delivered',
|
|
278
276
|
'task.detail.noPrerequisite': 'No prerequisites; ready to start',
|
|
279
277
|
'task.detail.ready': 'Prerequisites ready; can start',
|