@nanmicoder/dsh-agent-teams 0.1.16-rc.1 → 0.1.17-rc.1

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 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, eleven coordination tools, persistent state, an automatic shared-task scheduler, and a live Web UI—without requiring a separate workflow engine.
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
- [v0.1.16-rc.1](./release-notes/v0.1.16-rc.1.md) is the release candidate for the npm `next` channel: a shared host adapter, exact compatibility matrix, real-host acceptance and release gates. Check [GitHub Releases](https://github.com/NanmiCoder/dsh-agent-teams/releases) for release availability and history.
33
+ [v0.1.17-rc.1](./release-notes/v0.1.17-rc.1.md) supports DeepSeek Harness `0.1.5-rc.1` on the npm `next` channel. It adapts subagent delivery, explicit member initialization, and Web panel navigation while retaining three older host targets.
34
34
 
35
35
  ## Why AgentTeams?
36
36
 
@@ -49,77 +49,39 @@ The conversation card and activity panel use Harness's official locale service.
49
49
 
50
50
  ## Install and choose versions
51
51
 
52
- > [!IMPORTANT]
53
- > **0.1.16-rc.1 is a prerelease on the `next` track.** Use the exact version below for the supported 0.1.2 hosts. Plugin 0.1.15 targets Alpha.2; do not use a mutable `latest` tag as a compatibility guarantee. Check the actual running host and profile before updating either side.
52
+ **Recommended pair: DeepSeek Harness `0.1.5-rc.1` + AgentTeams `0.1.17-rc.1`. Both are prereleases.**
54
53
 
55
- | Harness host | Candidate track | Installation rule |
54
+ | Use case | DeepSeek Harness | AgentTeams plugin |
56
55
  | --- | --- | --- |
57
- | **0.1.2-rc.1** | Default acceptance target | There is currently no GA host. RC is still a prerelease; ordinary users should not have to follow Alpha. |
58
- | **0.1.2-alpha.5** | Opt-in preview | Select the exact version and lock the entire host dependency cohort. |
59
- | **0.1.2-alpha.2** | Retained legacy preview | Pinning the CLI alone can still resolve rc.1 transitive dependencies. |
60
- | Other versions, source HEAD, embedded Desktop cores | Outside the current matrix | Keep a known working exact pair or complete acceptance before adding a target. |
56
+ | **Recommended installation** | **`0.1.5-rc.1`** | **`0.1.17-rc.1`** |
57
+ | Retaining an older RC | `0.1.2-rc.1` | `0.1.17-rc.1` |
58
+ | Developer Alpha testing | `0.1.2-alpha.5` | `0.1.17-rc.1` |
59
+ | Retaining an older Alpha | `0.1.2-alpha.2` | `0.1.17-rc.1` |
61
60
 
62
- [compatibility.json](./compatibility.json) is the single source for development, PR checks and release gates. Plugin prereleases use `next`. Unsuffixed versions may use `latest` only after the recommended host and full supported matrix pass. Harness dist-tags belong to upstream; this project cannot change them, so installation instructions use exact versions.
63
-
64
- ### Ordinary users: keep a matching host and plugin
65
-
66
- The recommended host installation target is:
61
+ ### 1. Install DeepSeek Harness
67
62
 
68
63
  ```sh
69
- npm install --global @deepseek-ai/dsh@0.1.2-rc.1
64
+ npm install --global @deepseek-ai/dsh@0.1.5-rc.1
70
65
  dsh --version
71
66
  ```
72
67
 
73
- Once the release is available, install the exact plugin version into the profile you actually use (`web` below):
74
-
75
- ```sh
76
- dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.16-rc.1
77
- ```
78
-
79
- Restart the actual Harness process after changing either side and refresh the browser. Updating a global CLI does not replace an embedded Desktop core or another source checkout. For an unpublished checkout, use the source build below.
80
-
81
- An exact npm CLI version can still contain broad transitive dependencies. Preserve a verified lockfile and inspect the actual installation. Do not delete credentials or `.agent-teams` data to address a version mismatch.
82
-
83
- ### Build and verify this candidate
68
+ 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).
84
69
 
85
- In a checkout containing this change:
86
-
87
- ```sh
88
- pnpm install --frozen-lockfile
89
- pnpm typecheck
90
- pnpm build
91
- pnpm verify
92
- pnpm pack --out ./agent-teams-candidate.tgz
93
- ```
70
+ ### 2. Install the AgentTeams plugin
94
71
 
95
- Inspect the actual host, then install the artifact into a separate test profile:
72
+ Install into the `web` profile. Replace the profile name if needed:
96
73
 
97
74
  ```sh
98
- node scripts/doctor.mjs --host-root "/actual/host/package/directory" --json
99
- dsh plugin --profile agent-teams-preview add --save-exact /absolute/path/agent-teams-candidate.tgz
100
- node scripts/doctor.mjs --host-root "/actual/host/package/directory" --profile-root "/actual/test/profile/directory" --json
101
- dsh --profile agent-teams-preview --dump-config
102
- dsh web --profile agent-teams-preview
75
+ dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.17-rc.1
103
76
  ```
104
77
 
105
- The doctor checks the DSH dependency cohort, duplicate runtime identities and the profile's plugin version. It reads package metadata without reading credentials or changing configuration. Passing it does not replace team, task and UI acceptance. Rebuild, repack and restart after source changes.
106
-
107
- ### Developers: explicitly test Alpha
108
-
109
- Choose an exact Alpha version; `^0.1.2-alpha.2` does not mean “Alpha.2 only.” Development uses exact rc.1 packages, cohort-wide `pnpm.overrides` and a frozen lockfile. The runtime runner creates separate dependency cohorts, profiles and workspaces for Alpha.2, Alpha.5 and rc.1, installs the same candidate tgz, and checks actual resolution.
78
+ **After installation, stop and restart Harness for that profile, then refresh the browser.**
110
79
 
111
- ```sh
112
- node scripts/harness-runtime-verify.mjs \
113
- --host-version 0.1.2-alpha.2 \
114
- --artifact ./agent-teams-candidate.tgz \
115
- --report-dir /tmp/agent-teams-alpha2-check
116
- ```
117
-
118
- This developer command downloads the host into temporary directories without modifying existing user profiles. It uses deterministic model responses with the real CLI, plugin, sessions, tools and subagents. See the [maintenance workflow](./docs/maintenance-workflow.md) for coverage and release requirements.
80
+ Plugin prereleases use npm `next`; use the exact-version command above. `latest` is not the recommended entry for this host pair. See the [source installation guide](./docs/maintenance-workflow.md) and [release verification](./docs/releases/v0.1.17-rc.1/README.md).
119
81
 
120
- ### Retaining an older host / rollback
82
+ > 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).
121
83
 
122
- For the historical Harness `0.1.0-rc.8` + plugin `0.1.14` pair, pin both sides. This is not a compatibility claim for every older RC. Keep another already verified older pair until a complete migration is ready. Historical [Alpha.2 compatibility](./docs/alpha2-compatibility.md) and [acceptance](./docs/alpha2-release-acceptance.md) reports describe those specific releases, not the current matrix.
84
+ 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).
123
85
 
124
86
  Then ask for a team directly:
125
87
 
@@ -127,7 +89,7 @@ Then ask for a team directly:
127
89
 
128
90
  ## How it works
129
91
 
130
- 1. The current session creates a team and becomes its captain.
92
+ 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.
131
93
  2. The captain adds role-specific members backed by continuable sub-agents.
132
94
  3. The goal becomes tasks with owners and explicit dependencies.
133
95
  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.
@@ -138,6 +100,8 @@ Team state is stored under `<workspace>/.agent-teams/`; the Web panel reads that
138
100
 
139
101
  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.
140
102
 
103
+ 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).
104
+
141
105
  ## Slash command
142
106
 
143
107
  No “use AgentTeams” phrasing required. The plugin registers the
@@ -152,7 +116,7 @@ command), describe the goal, and press Enter.
152
116
  The command pipeline claims the line, then preserves that exact input as an
153
117
  ordinary user follow-up so it remains visible in the main chat. The gesture
154
118
  boundary adds the deterministic activation directive at pre-step, so the
155
- captain protocol still starts immediately. The invocation is also durably
119
+ first model request follows the staged planning protocol without a mandatory helper call. The invocation is also durably
156
120
  logged (`command/run` / `command/done`).
157
121
 
158
122
  Surfaces without command adjudication (for example the headless CLI) get the
@@ -160,6 +124,8 @@ same deterministic activation through a gesture boundary: any genuine user
160
124
  message starting with `/agent-teams` activates the protocol for the rest of
161
125
  the text. Mid-sentence mentions stay ordinary prose.
162
126
 
127
+ Historical panels require saved team state or archives. Sessions from early versions that deleted teams without retaining archives do not yet support reconstructing the full panel from logs.
128
+
163
129
  ## Configuration
164
130
 
165
131
  Defaults work without extra setup. A trusted profile can override member behavior:
package/README_ZH.md CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  `dsh-agent-teams` 让当前 DeepSeek Harness 会话成为队长:创建可续聊的子 Agent、把目标拆成有依赖的任务,并通过直达消息协调成员工作。
24
24
 
25
- 你只需用自然语言提出目标。插件会提供团队协议、11 个协作工具、持久化状态、自动共享任务调度和实时 Web UI,不需要额外的 Workflow 引擎。
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
- [v0.1.16-rc.1](./release-notes/v0.1.16-rc.1.md) 是 npm `next` 渠道的发布候选:统一宿主兼容层、精确版本矩阵、真实宿主验收和发布门禁。发布状态与历史见 [GitHub Releases](https://github.com/NanmiCoder/dsh-agent-teams/releases)。
33
+ [v0.1.17-rc.1](./release-notes/v0.1.17-rc.1.md) 适配 DeepSeek Harness `0.1.5-rc.1`,发布到 npm `next` 渠道。新增子代理投递、成员初始化和 Web 面板导航适配,保留三个旧宿主目标。
34
34
 
35
35
  ## 为什么需要 AgentTeams?
36
36
 
@@ -48,82 +48,46 @@
48
48
 
49
49
  ## 安装与版本选择
50
50
 
51
- > [!IMPORTANT]
52
- > **0.1.16-rc.1 是 `next` 渠道的预发布版本。** 对当前支持的 0.1.2 宿主,请使用下方精确插件版本。0.1.15 面向 Alpha.2,不能把可变的 `latest` 标签当作兼容保证。请先核对实际运行的宿主和 profile,再更新两端。
51
+ **推荐组合:DeepSeek Harness `0.1.5-rc.1` + AgentTeams `0.1.17-rc.1`。两者均为预发布版本。**
53
52
 
54
- | Harness 宿主 | 本次候选的定位 | 使用原则 |
53
+ | 使用场景 | DeepSeek Harness | AgentTeams 插件 |
55
54
  | --- | --- | --- |
56
- | **0.1.2-rc.1** | 普通用户默认验收目标 | 当前没有 GA;RC 仍是预发布,但不再要求普通用户跟随 Alpha。 |
57
- | **0.1.2-alpha.5** | 主动选择的预览版本 | 明确指定版本,并锁定整组宿主依赖。 |
58
- | **0.1.2-alpha.2** | 保留兼容的旧预览版本 | 单锁 CLI 不够,间接依赖可能被解析成 rc.1。 |
59
- | 其他版本、源码 HEAD、Desktop 内置核心 | 不在当前支持清单中 | 保留已工作的精确组合,或单独完成验收后加入清单。 |
55
+ | **推荐安装** | **`0.1.5-rc.1`** | **`0.1.17-rc.1`** |
56
+ | 保留旧 RC | `0.1.2-rc.1` | `0.1.17-rc.1` |
57
+ | 开发者测试 Alpha | `0.1.2-alpha.5` | `0.1.17-rc.1` |
58
+ | 保留旧 Alpha | `0.1.2-alpha.2` | `0.1.17-rc.1` |
60
59
 
61
- 宿主矩阵只有一个来源:[compatibility.json](./compatibility.json)。开发、PR 验证和发布门禁都读取它。插件预发布版本统一发到 `next`;无后缀版本只有在推荐宿主与完整矩阵验收通过后才可以进入 `latest`。上游 Harness 的 npm 标签由上游维护,本项目不能修改它;我们的安装说明使用精确版本。
62
-
63
- ### 普通用户:固定匹配的宿主与插件
64
-
65
- 推荐宿主安装目标为:
60
+ ### 1. 安装 DeepSeek Harness
66
61
 
67
62
  ```sh
68
- npm install --global @deepseek-ai/dsh@0.1.2-rc.1
63
+ npm install --global @deepseek-ai/dsh@0.1.5-rc.1
69
64
  dsh --version
70
65
  ```
71
66
 
72
- 确认发行版本可用后,在实际使用的 profile 中安装精确插件版本(以下以 `web` 为例):
73
-
74
- ```sh
75
- dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.16-rc.1
76
- ```
77
-
78
- 宿主或插件更新后,停止并重启实际运行的 Harness,再刷新浏览器。全局 CLI 升级不会更换 Desktop 内置核心,也不会更新另一个源码工作区。尚未发布的 checkout 可使用下方源码构建方式。
79
-
80
- npm 的精确 CLI 版本仍可能包含宽范围间接依赖。升级时保留已验证的锁文件,对实际安装路径运行诊断;不要通过删除凭据或 `.agent-teams` 来处理版本错配。
67
+ 已有该版本可跳过。Alpha 仅供主动测试:手动指定表中的 Alpha 版本,并按[维护指南](./docs/maintenance-workflow.md)锁定整组宿主依赖。
81
68
 
82
- ### 从源码验证本次候选
69
+ ### 2. 安装 AgentTeams 插件
83
70
 
84
- 在包含本次改动的插件 checkout 中:
71
+ 安装到 `web` profile;使用其他 profile 时替换名称:
85
72
 
86
73
  ```sh
87
- pnpm install --frozen-lockfile
88
- pnpm typecheck
89
- pnpm build
90
- pnpm verify
91
- pnpm pack --out ./agent-teams-candidate.tgz
74
+ dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams@0.1.17-rc.1
92
75
  ```
93
76
 
94
- 先检查实际宿主的依赖,再在独立测试 profile 安装产物:
77
+ **安装后,停止并重新启动该 profile 的 Harness 进程,再刷新浏览器。**
95
78
 
96
- ```sh
97
- node scripts/doctor.mjs --host-root "/实际运行的宿主包目录" --json
98
- dsh plugin --profile agent-teams-preview add --save-exact /完整路径/agent-teams-candidate.tgz
99
- node scripts/doctor.mjs --host-root "/实际运行的宿主包目录" --profile-root "/实际测试profile目录" --json
100
- dsh --profile agent-teams-preview --dump-config
101
- dsh web --profile agent-teams-preview
102
- ```
103
-
104
- `doctor` 检查整组 DSH 包版本、重复运行时身份以及 profile 中的插件版本。它只读文件,不读取凭据、不修改配置;检查通过不替代实际建队、任务执行和 UI 验收。源码更改后需要重新构建、打包和重启。
105
-
106
- ### 开发者:显式测试 Alpha
79
+ 插件预发布使用 npm `next`,请使用上面的精确版本命令;`latest` 不是这组宿主的推荐安装入口。源码安装见[维护指南](./docs/maintenance-workflow.md),验证范围见[本版验收记录](./docs/releases/v0.1.17-rc.1/README.md)。
107
80
 
108
- Alpha 需要明确指定版本,不能用一个 `^0.1.2-alpha.2` 表达“只接受 Alpha.2”。本仓库开发依赖通过精确版本、整组 `pnpm.overrides` 和 frozen lockfile 固定到 rc.1;自动验收会为 Alpha.2、Alpha.5 和 rc.1 分别创建独立安装闭包、profile 与工作区,安装同一份 tgz,并核对真实解析结果。
81
+ > Desktop 用户需核对应用内置的 Harness 核心;全局 CLI 升级不会升级桌面内核。旧 `0.1.0-*` / `0.1.1-*` 或其他未列出的宿主,请先保留已工作的组合,参考[旧版本与诊断指引](./docs/maintenance-workflow.md)。
109
82
 
110
- ```sh
111
- node scripts/harness-runtime-verify.mjs \
112
- --host-version 0.1.2-alpha.2 \
113
- --artifact ./agent-teams-candidate.tgz \
114
- --report-dir /tmp/agent-teams-alpha2-check
115
- ```
116
-
117
- 这是会创建临时目录并下载宿主的开发验收命令,不会修改已有用户 profile。模型适配器使用固定测试响应;CLI、插件、会话、工具与子代理使用真实宿主实现。完整范围和发布流程见[维护流程](./docs/maintenance-workflow.md)。
118
-
119
- ### 保留旧宿主 / 回退
120
-
121
- 对于历史组合 Harness `0.1.0-rc.8` + 插件 `0.1.14`,应固定两端版本;不能据此推断所有旧 RC 都兼容。已使用其他已验证旧组合的用户先保留该组合。历史 [Alpha.2 兼容记录](./docs/alpha2-compatibility.md)和[验收报告](./docs/alpha2-release-acceptance.md)只描述当时版本,不覆盖当前清单。
83
+ 完整[兼容清单](./compatibility.json)、[源码安装与 Alpha 验证](./docs/maintenance-workflow.md)、[已验证范围与平台限制](./docs/maintenance-2026-09-06/release/README.md)。
122
84
 
123
85
  接着直接用自然语言拉团队:
124
86
 
125
87
  > 使用 AgentTeams 审查 v0.5.3 之后的提交,分别从性能、安全和产品角度分工,最后输出一份汇总报告。
126
88
 
89
+ 队长会话从第一轮起保留精简的固定核心协议和原有 13 个业务工具,直接调用,无需额外的加载工具或激活调用。已配置模板的精简目录固定保留。创建、批准、继续或结束团队都不会改写系统提示词和工具 schema,会话压缩或代码模式丢弃工具结果也不会丢失核心规则。成员保留四个团队工具、固定成员说明及普通编程/研究工具。Web 批准后会通知并唤醒队长,后续成员报告会再次唤醒它,无需忙轮询。详见[固定协议与 benchmark 标准](./docs/progressive-loading.md)。
90
+
127
91
  ## 工作方式
128
92
 
129
93
  1. 当前会话创建团队并成为队长。
@@ -172,6 +136,7 @@ node scripts/harness-runtime-verify.mjs \
172
136
  - 一个队长同一时间只能带一个活动团队。
173
137
  - 没有开放任务的空闲成员会自动续领就绪任务;仍持有开放 attempt 的空闲成员会停驻,队长可发消息让其沿用原 attempt 继续,或显式转派;冷重启遗留的开放任务才会生成新 attempt。暂时无法实时投递的消息会持久保存在邮箱中并在后续状态边界重投。
174
138
  - 状态使用文件持久化,并在单个 DSH 进程内串行操作;多个进程同时修改同一团队不保证一致。
139
+ - 历史面板依赖保存的团队状态或归档;早期版本删除团队时未保留归档的会话,暂不支持从日志重建完整面板。
175
140
  - 活动面板如实展示持久化状态;模型偶尔可能完成工作却没有按协议更新任务状态。
176
141
 
177
142
  完整工具列表、状态模型、Web UI 行为、配置与已知限制见 [docs/usage.md](./docs/usage.md)。
@@ -207,7 +172,7 @@ pnpm verify
207
172
 
208
173
  在 `cordis.patch.yml` 的 `profiles` 中配置完整团队模板。每个 profile 都提供成员阵容,可独立指定 provider、model、role、reasoning_effort。`taskPlanning: captain` 表示只提供阵容和约束,由 Captain 根据用户目标设计 DAG;省略该字段或设为 `seed` 时,展开模板中的固定任务图。使用 `/agent-teams --profile <名称> <目标>` 显式激活;不会把首个普通 token 隐式识别为 profile。
209
174
 
210
- 普通 `/agent-teams` 流程会调用 `agent_teams_create({ profile, approval: "required" })`:只落盘可编辑的成员占位和 DAG,不创建子会话、不领取任务。成员模型和推理等级直接读取 Harness 的模型目录。「返回对话修改」会终止仍在运行的规划轮次,让队长先追问修改方向,再用一次原子操作更新同一份草案;「放弃本次计划」经二次确认后会归档草案、中止轮次,并向模型注入不得自动重建团队的控制上下文。只有点击「确认并启动团队」才会按最终配置原子创建成员并启动就绪任务。运行中团队的停止入口位于该团队的面板标题,点击后需要二次确认,不再占用输入区域。直接工具调用方可显式传 `approval: "automatic"` 保留旧的立即执行路径。审查或测试失败不会解锁下游;自动 repair/review 不依赖 failed review。
175
+ 普通 `/agent-teams` 流程继续已有团队,按需调用 `agent_teams_status` 确认状态;仅在没有当前团队时调用 `agent_teams_create({ profile, approval: "required" })`:只落盘可编辑的成员占位和 DAG,不创建子会话、不领取任务。成员模型和推理等级直接读取 Harness 的模型目录。「返回对话修改」会终止仍在运行的规划轮次,让队长先追问修改方向,再用一次原子操作更新同一份草案;「放弃本次计划」经二次确认后会归档草案、中止轮次,并向模型注入不得自动重建团队的控制上下文。只有点击「确认并启动团队」才会按最终配置原子创建成员并启动就绪任务。运行中团队的停止入口位于该团队的面板标题,点击后需要二次确认,不再占用输入区域。直接工具调用方可显式传 `approval: "automatic"` 保留旧的立即执行路径。审查或测试失败不会解锁下游;自动 repair/review 不依赖 failed review。
211
176
 
212
177
  ## 许可证
213
178
 
@@ -1,10 +1,23 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "recommendedHost": "0.1.2-rc.1",
3
+ "recommendedHost": "0.1.5-rc.1",
4
4
  "previewTag": "next",
5
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" }
6
+ {
7
+ "version": "0.1.5-rc.1",
8
+ "track": "recommended"
9
+ },
10
+ {
11
+ "version": "0.1.2-rc.1",
12
+ "track": "legacy"
13
+ },
14
+ {
15
+ "version": "0.1.2-alpha.5",
16
+ "track": "preview"
17
+ },
18
+ {
19
+ "version": "0.1.2-alpha.2",
20
+ "track": "legacy"
21
+ }
9
22
  ]
10
23
  }
@@ -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
+ }
@@ -410,7 +410,7 @@ function historicCardTeam(data, owner) {
410
410
  captainInbox: [],
411
411
  };
412
412
  }
413
- export function ActivityPanel({ sessionsList, modelDirectories, openMember, t }) {
413
+ export function ActivityPanel({ sessionsList, modelDirectories, openMember, t, conversationVisible = true }) {
414
414
  // Navigating to a member's subagent transcript is an explicit departure:
415
415
  // hide the floater immediately instead of waiting out the autocollapse
416
416
  // grace, so the panel never lingers over the member session.
@@ -439,7 +439,7 @@ export function ActivityPanel({ sessionsList, modelDirectories, openMember, t })
439
439
  setOpen(false);
440
440
  setOpenOwner(undefined);
441
441
  window.requestAnimationFrame(() => {
442
- document.querySelector('[data-composer-card] textarea')?.focus();
442
+ document.querySelector('[data-composer-card] [contenteditable="true"][role="textbox"], [data-composer-card] textarea')?.focus();
443
443
  });
444
444
  };
445
445
  const { teams, archivedTeams } = useSyncExternalStore(subscribeActivitySnapshots, getActivitySnapshotsSnapshot);
@@ -447,7 +447,7 @@ export function ActivityPanel({ sessionsList, modelDirectories, openMember, t })
447
447
  const currentRef = useRef(current);
448
448
  useEffect(() => { currentRef.current = current; }, [current]);
449
449
  const mountedAtRef = useRef(performance.now());
450
- const expanded = activityPanelExpandedForSession(open, openOwner, current);
450
+ const expanded = conversationVisible && activityPanelExpandedForSession(open, openOwner, current);
451
451
  const geometry = useMemo(() => resolvePanelGeometry(layout, bounds), [layout, bounds]);
452
452
  const compact = compactPanelForBounds(bounds);
453
453
  const commitLayout = useCallback((next) => {
@@ -754,7 +754,7 @@ export function ActivityPanel({ sessionsList, modelDirectories, openMember, t })
754
754
  maxHeight: panelMaximumHeight(geometry, bounds),
755
755
  transform: `translate3d(${geometry.x}px, ${geometry.y}px, 0)`,
756
756
  };
757
- if (!hasTeams && !expanded)
757
+ if (!conversationVisible || (!hasTeams && !expanded))
758
758
  return null;
759
759
  return (_jsxs(_Fragment, { children: [!expanded && (_jsx(CollapsedBadge, { count: visibleCount, busy: busy, t: t, onClick: () => {
760
760
  if (current === undefined)
@@ -5,7 +5,8 @@ import { agentTeamsCardDefinition } from "./agent-teams-card-definition.js";
5
5
  import { AGENT_TEAMS_LOCALE_NAMESPACE, en, zh, } from "./locales.js";
6
6
  import { openAgentTeamMember } from "./session-navigation.js";
7
7
  /** Required services: conversation nodes, slots, sessions navigation, and locale. */
8
- export const inject = ['uiConversation', 'slots', 'sessions', 'locale', 'modelDirectories'];
8
+ export const inject = ['uiConversation', 'slots', 'sessions', 'locale', 'modelDirectories', 'layout'];
9
+ const useLegacyPanelInfo = select => select({ activePanelId: null });
9
10
  /** The replayed user message is the canonical transcript entry. */
10
11
  function HiddenAgentTeamsCommand() {
11
12
  return null;
@@ -18,11 +19,16 @@ function HiddenAgentTeamsCommand() {
18
19
  export function apply(ctx) {
19
20
  ctx.effect(() => ctx.locale.register(AGENT_TEAMS_LOCALE_NAMESPACE, { zh, en }), 'agent-teams: dictionaries');
20
21
  const openMember = (parentId, childId) => {
21
- void openAgentTeamMember(ctx.sessions, parentId, childId).catch((error) => {
22
+ void openAgentTeamMember(ctx.sessions, parentId, childId, ctx.layout).catch((error) => {
22
23
  console.warn(`agent-teams: failed to open member transcript ${childId}: ${String(error)}`);
23
24
  });
24
25
  };
25
- const Panel = ({ t }) => (_jsx(ActivityPanel, { sessionsList: ctx.sessions.list, modelDirectories: ctx.modelDirectories, openMember: openMember, t: t }));
26
+ const Panel = ({ t, usePanelInfo }) => {
27
+ // A host's standard hook set is fixed for this mounted plugin instance.
28
+ const usePanel = usePanelInfo ?? useLegacyPanelInfo;
29
+ const conversationVisible = usePanel(panel => panel.activePanelId === null);
30
+ return (_jsx(ActivityPanel, { conversationVisible: conversationVisible, sessionsList: ctx.sessions.list, modelDirectories: ctx.modelDirectories, openMember: openMember, t: t }));
31
+ };
26
32
  ctx.slots.inject('shell.overlay', () => ctx.slots.register({
27
33
  name: 'shell.overlay',
28
34
  id: 'agent-teams-activity',
@@ -5,17 +5,23 @@
5
5
  * Harness rc.8 intentionally removed cold subagents from the ordinary session
6
6
  * list. They must first be rediscovered in their parent's catalog, then opened
7
7
  * with the exact parent/child/mode address. Older runtimes have only `open()`;
8
- * the fallback preserves the plugin's rc.6 peer range.
8
+ * the fallback preserves ordinary-session navigation. New layouts also select
9
+ * the Conversation panel and cancel catalog refreshes superseded by navigation.
9
10
  */
10
- export async function openAgentTeamMember(sessions, parentSessionId, childSessionId) {
11
+ export async function openAgentTeamMember(sessions, parentSessionId, childSessionId, layout) {
12
+ const navigation = layout?.beginNavigation?.();
11
13
  if (sessions.openSubagent === undefined || sessions.refreshSubagents === undefined) {
12
14
  sessions.open(childSessionId);
15
+ layout?.selectPanel?.(null);
13
16
  return 'session';
14
17
  }
15
18
  await sessions.refreshSubagents(parentSessionId);
19
+ if (navigation?.aborted)
20
+ return 'cancelled';
16
21
  const retained = sessions.subagentAddress?.(childSessionId);
17
22
  sessions.openSubagent(retained?.parentSessionId === parentSessionId
18
23
  ? retained
19
24
  : { parentSessionId, childSessionId, mode: 'continuable' });
25
+ layout?.selectPanel?.(null);
20
26
  return 'subagent';
21
27
  }
package/lib/client.js CHANGED
@@ -2692,7 +2692,7 @@ window.__ModuleLoader__.load({
2692
2692
  captainInbox: []
2693
2693
  };
2694
2694
  }
2695
- function ActivityPanel({ sessionsList, modelDirectories, openMember, t }) {
2695
+ function ActivityPanel({ sessionsList, modelDirectories, openMember, t, conversationVisible = true }) {
2696
2696
  const navigateToSession = (parentId, childId) => {
2697
2697
  setOpen(false);
2698
2698
  setWasActive(false);
@@ -2722,7 +2722,7 @@ window.__ModuleLoader__.load({
2722
2722
  setOpen(false);
2723
2723
  setOpenOwner(void 0);
2724
2724
  window.requestAnimationFrame(() => {
2725
- document.querySelector("[data-composer-card] textarea")?.focus();
2725
+ document.querySelector("[data-composer-card] [contenteditable=\"true\"][role=\"textbox\"], [data-composer-card] textarea")?.focus();
2726
2726
  });
2727
2727
  };
2728
2728
  const { teams, archivedTeams } = (0, react.useSyncExternalStore)(subscribeActivitySnapshots, getActivitySnapshotsSnapshot);
@@ -2732,7 +2732,7 @@ window.__ModuleLoader__.load({
2732
2732
  currentRef.current = current;
2733
2733
  }, [current]);
2734
2734
  const mountedAtRef = (0, react.useRef)(performance.now());
2735
- const expanded = activityPanelExpandedForSession(open, openOwner, current);
2735
+ const expanded = conversationVisible && activityPanelExpandedForSession(open, openOwner, current);
2736
2736
  const geometry = (0, react.useMemo)(() => resolvePanelGeometry(layout, bounds), [layout, bounds]);
2737
2737
  const compact = compactPanelForBounds(bounds);
2738
2738
  const commitLayout = (0, react.useCallback)((next) => {
@@ -3006,7 +3006,7 @@ window.__ModuleLoader__.load({
3006
3006
  maxHeight: panelMaximumHeight(geometry, bounds),
3007
3007
  transform: `translate3d(${geometry.x}px, ${geometry.y}px, 0)`
3008
3008
  };
3009
- if (!hasTeams && !expanded) return null;
3009
+ if (!conversationVisible || !hasTeams && !expanded) return null;
3010
3010
  return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [!expanded && (0, react_jsx_runtime.jsx)(CollapsedBadge, {
3011
3011
  count: visibleCount,
3012
3012
  busy,
@@ -3620,20 +3620,25 @@ window.__ModuleLoader__.load({
3620
3620
  * Harness rc.8 intentionally removed cold subagents from the ordinary session
3621
3621
  * list. They must first be rediscovered in their parent's catalog, then opened
3622
3622
  * with the exact parent/child/mode address. Older runtimes have only `open()`;
3623
- * the fallback preserves the plugin's rc.6 peer range.
3623
+ * the fallback preserves ordinary-session navigation. New layouts also select
3624
+ * the Conversation panel and cancel catalog refreshes superseded by navigation.
3624
3625
  */
3625
- async function openAgentTeamMember(sessions, parentSessionId, childSessionId) {
3626
+ async function openAgentTeamMember(sessions, parentSessionId, childSessionId, layout) {
3627
+ const navigation = layout?.beginNavigation?.();
3626
3628
  if (sessions.openSubagent === void 0 || sessions.refreshSubagents === void 0) {
3627
3629
  sessions.open(childSessionId);
3630
+ layout?.selectPanel?.(null);
3628
3631
  return "session";
3629
3632
  }
3630
3633
  await sessions.refreshSubagents(parentSessionId);
3634
+ if (navigation?.aborted) return "cancelled";
3631
3635
  const retained = sessions.subagentAddress?.(childSessionId);
3632
3636
  sessions.openSubagent(retained?.parentSessionId === parentSessionId ? retained : {
3633
3637
  parentSessionId,
3634
3638
  childSessionId,
3635
3639
  mode: "continuable"
3636
3640
  });
3641
+ layout?.selectPanel?.(null);
3637
3642
  return "subagent";
3638
3643
  }
3639
3644
  //#endregion
@@ -3644,8 +3649,10 @@ window.__ModuleLoader__.load({
3644
3649
  "slots",
3645
3650
  "sessions",
3646
3651
  "locale",
3647
- "modelDirectories"
3652
+ "modelDirectories",
3653
+ "layout"
3648
3654
  ];
3655
+ const useLegacyPanelInfo = (select) => select({ activePanelId: null });
3649
3656
  /** The replayed user message is the canonical transcript entry. */
3650
3657
  function HiddenAgentTeamsCommand() {
3651
3658
  return null;
@@ -3661,16 +3668,19 @@ window.__ModuleLoader__.load({
3661
3668
  en
3662
3669
  }), "agent-teams: dictionaries");
3663
3670
  const openMember = (parentId, childId) => {
3664
- openAgentTeamMember(ctx.sessions, parentId, childId).catch((error) => {
3671
+ openAgentTeamMember(ctx.sessions, parentId, childId, ctx.layout).catch((error) => {
3665
3672
  console.warn(`agent-teams: failed to open member transcript ${childId}: ${String(error)}`);
3666
3673
  });
3667
3674
  };
3668
- const Panel = ({ t }) => (0, react_jsx_runtime.jsx)(ActivityPanel, {
3669
- sessionsList: ctx.sessions.list,
3670
- modelDirectories: ctx.modelDirectories,
3671
- openMember,
3672
- t
3673
- });
3675
+ const Panel = ({ t, usePanelInfo }) => {
3676
+ return (0, react_jsx_runtime.jsx)(ActivityPanel, {
3677
+ conversationVisible: (usePanelInfo ?? useLegacyPanelInfo)((panel) => panel.activePanelId === null),
3678
+ sessionsList: ctx.sessions.list,
3679
+ modelDirectories: ctx.modelDirectories,
3680
+ openMember,
3681
+ t
3682
+ });
3683
+ };
3674
3684
  ctx.slots.inject("shell.overlay", () => ctx.slots.register({
3675
3685
  name: "shell.overlay",
3676
3686
  id: "agent-teams-activity",