@wwkit/harness 1.0.9 → 1.0.11
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/agents/extract.md +2 -14
- package/agents/lint.md +368 -0
- package/agents/pyit.md +361 -0
- package/agents/pyut.md +347 -0
- package/agents/query.md +2 -14
- package/agents/revise.md +2 -14
- package/agents/work.md +631 -0
- package/commands/fix.md +77 -0
- package/commands/git-sync.md +218 -0
- package/commands/net-port.md +364 -0
- package/commands/pyit.md +6 -0
- package/commands/pyut.md +6 -0
- package/commands/resume.md +104 -0
- package/package.json +4 -2
- package/plugins/work-bootstrap.js +77 -0
- package/scripts/work-review-package +50 -0
- package/scripts/work-task-brief +27 -0
- package/scripts/work-workspace +31 -0
- package/skills/better-skill/SKILL.md +124 -0
- package/skills/blame-skill/SKILL.md +201 -0
- package/skills/lint-ai-fix/SKILL.md +141 -0
- package/skills/lint-config-setup/SKILL.md +106 -0
- package/skills/lint-config-setup/references/languages/js.md +110 -0
- package/skills/lint-config-setup/references/languages/py.md +89 -0
- package/skills/lint-env-ensure/SKILL.md +92 -0
- package/skills/lint-env-ensure/references/config.md +65 -0
- package/skills/lint-language-detect/SKILL.md +79 -0
- package/skills/lint-language-detect/references/detect-language.js +65 -0
- package/skills/lint-rules-analyze/SKILL.md +129 -0
- package/skills/lint-suitability-check/SKILL.md +84 -0
- package/skills/lint-tool-fix/SKILL.md +94 -0
- package/skills/new-skill/SKILL.md +227 -0
- package/skills/new-skill/references/template.md +53 -0
- package/skills/new-skill/references/workflow-patterns.md +104 -0
- package/skills/pytest-case-create/SKILL.md +327 -0
- package/skills/pytest-case-create/references/test-standards.md +244 -0
- package/skills/pytest-case-fix/SKILL.md +274 -0
- package/skills/pytest-coverage-analyze/SKILL.md +226 -0
- package/skills/pytest-coverage-analyze/references/scoring-rules.md +57 -0
- package/skills/pytest-env-ensure/SKILL.md +198 -0
- package/skills/pytest-env-ensure/references/config.md +145 -0
- package/skills/pytest-execute/SKILL.md +155 -0
- package/skills/pytest-sample/SKILL.md +164 -0
- package/skills/pytest-sample/references/src/pytest-sample/Calculator.py +67 -0
- package/skills/pytest-sample/references/src/pytest-sample/ConfigManager.py +68 -0
- package/skills/pytest-sample/references/src/pytest-sample/FileProcessor.py +53 -0
- package/skills/pytest-sample/references/src/pytest-sample/OrderService.py +82 -0
- package/skills/pytest-sample/references/src/pytest-sample/TokenGenerator.py +50 -0
- package/skills/pytest-sample/references/src/pytest-sample/UserService.py +45 -0
- package/skills/pytest-sample/references/src/pytest-sample/__init__.py +0 -0
- package/skills/pytest-suitability-check/SKILL.md +224 -0
- package/skills/read-docs/SKILL.md +134 -0
- package/skills/read-docs/references/opencode/agents/cases.md +206 -0
- package/skills/read-docs/references/opencode/agents/design-pattern.md +47 -0
- package/skills/read-docs/references/opencode/agents/detail.md +191 -0
- package/skills/read-docs/references/opencode/agents/examples.md +100 -0
- package/skills/read-docs/references/opencode/agents/index.md +309 -0
- package/skills/read-docs/references/opencode/agents/parallel-dispatch.md +149 -0
- package/skills/read-docs/references/opencode/agents/subagent-internals.md +217 -0
- package/skills/read-docs/references/opencode/agents/workflow.md +161 -0
- package/skills/read-docs/references/opencode/cli/commands/acp.md +32 -0
- package/skills/read-docs/references/opencode/cli/commands/agent.md +16 -0
- package/skills/read-docs/references/opencode/cli/commands/attach.md +20 -0
- package/skills/read-docs/references/opencode/cli/commands/mcp.md +37 -0
- package/skills/read-docs/references/opencode/cli/commands/others.md +49 -0
- package/skills/read-docs/references/opencode/cli/commands/plugin.md +13 -0
- package/skills/read-docs/references/opencode/cli/commands/provider.md +44 -0
- package/skills/read-docs/references/opencode/cli/commands/run.md +81 -0
- package/skills/read-docs/references/opencode/cli/commands/serve.md +84 -0
- package/skills/read-docs/references/opencode/cli/commands/session.md +38 -0
- package/skills/read-docs/references/opencode/cli/commands/web.md +15 -0
- package/skills/read-docs/references/opencode/cli/env.md +39 -0
- package/skills/read-docs/references/opencode/cli/index.md +19 -0
- package/skills/read-docs/references/opencode/cli/tui.md +35 -0
- package/skills/read-docs/references/opencode/commands/examples.md +42 -0
- package/skills/read-docs/references/opencode/commands/index.md +185 -0
- package/skills/read-docs/references/opencode/config/provider.md +152 -0
- package/skills/read-docs/references/opencode/formatter/index.md +71 -0
- package/skills/read-docs/references/opencode/guide/config.md +419 -0
- package/skills/read-docs/references/opencode/guide/formatters.md +70 -0
- package/skills/read-docs/references/opencode/guide/index.md +37 -0
- package/skills/read-docs/references/opencode/guide/providers.md +31 -0
- package/skills/read-docs/references/opencode/guide/rules.md +63 -0
- package/skills/read-docs/references/opencode/plugins/examples.md +75 -0
- package/skills/read-docs/references/opencode/plugins/index.md +188 -0
- package/skills/read-docs/references/opencode/reference/index.md +119 -0
- package/skills/read-docs/references/opencode/rule/index.md +78 -0
- package/skills/read-docs/references/opencode/skills/detail.md +113 -0
- package/skills/read-docs/references/opencode/skills/examples.md +141 -0
- package/skills/read-docs/references/opencode/skills/index.md +126 -0
- package/skills/read-docs/references/opencode/skills/workflow.md +146 -0
- package/skills/read-docs/references/opencode/tests/agent.md +10 -0
- package/skills/read-docs/references/opencode/tests/config.md +60 -0
- package/skills/read-docs/references/opencode/tests/file.md +12 -0
- package/skills/read-docs/references/opencode/tests/serve.md +18 -0
- package/skills/read-docs/references/opencode/tests/session.md +31 -0
- package/skills/read-docs/references/opencode/tests/web.md +17 -0
- package/skills/read-docs/references/opencode/tools/arguments.md +305 -0
- package/skills/read-docs/references/opencode/tools/context.md +18 -0
- package/skills/read-docs/references/opencode/tools/custom.md +111 -0
- package/skills/read-docs/references/opencode/tools/detail.md +104 -0
- package/skills/read-docs/references/opencode/tools/examples.md +71 -0
- package/skills/read-docs/references/opencode/tools/index.md +56 -0
- package/skills/read-docs/references/opencode/tools/lsp.md +26 -0
- package/skills/read-docs/references/opencode/tools/mcp.md +132 -0
- package/skills/read-docs/references/opencode/train/README.md +135 -0
- package/skills/read-docs/references/opencode/train/agent-basic.md +772 -0
- package/skills/read-docs/references/opencode/train/command-basic.md +668 -0
- package/skills/read-docs/references/opencode/train/config-basic.md +509 -0
- package/skills/read-docs/references/opencode/train/index.md +164 -0
- package/skills/read-docs/references/opencode/train/practice.md +873 -0
- package/skills/read-docs/references/opencode/train/skill-basic.md +608 -0
- package/skills/read-docs/references/opencode/tui/commands/config.md +32 -0
- package/skills/read-docs/references/opencode/tui/commands/editor.md +47 -0
- package/skills/read-docs/references/opencode/tui/commands/index.md +125 -0
- package/skills/read-docs/references/opencode/tui/commands/init.md +5 -0
- package/skills/read-docs/references/opencode/tui/index.md +26 -0
- package/skills/read-docs/references/superpowers/bootstrap.md +107 -0
- package/skills/read-docs/references/superpowers/comparison.md +77 -0
- package/skills/read-docs/references/superpowers/context.md +71 -0
- package/skills/read-docs/references/superpowers/index.md +58 -0
- package/skills/read-docs/references/superpowers/parallel.md +49 -0
- package/skills/read-docs/references/superpowers/sdd.md +183 -0
- package/skills/read-docs/references/superpowers/skills.md +68 -0
- package/skills/read-docs/references/superpowers/workflow.md +83 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
# Agent
|
|
2
|
+
|
|
3
|
+
Agent 是可配置的专门 AI 助手,用于特定任务和工作流。
|
|
4
|
+
|
|
5
|
+
可以在会话中切换 Agent,或使用 `@` 提及调用。
|
|
6
|
+
|
|
7
|
+
## Agent 类型
|
|
8
|
+
|
|
9
|
+
| 类型 | 说明 |
|
|
10
|
+
|------|------|
|
|
11
|
+
| Primary Agent | 直接交互的主助手 |
|
|
12
|
+
| Subagent | Primary Agent 可调用的专门助手(也可通过 `@` 手动调用) |
|
|
13
|
+
|
|
14
|
+
## 内置 Agent
|
|
15
|
+
|
|
16
|
+
### Primary Agent
|
|
17
|
+
|
|
18
|
+
| Agent | 说明 |
|
|
19
|
+
|-------|------|
|
|
20
|
+
| build | 默认主 Agent,所有工具启用 |
|
|
21
|
+
| plan | 规划和分析专用,文件编辑和 bash 默认需审批 |
|
|
22
|
+
|
|
23
|
+
### Subagent
|
|
24
|
+
|
|
25
|
+
| Agent | 说明 |
|
|
26
|
+
|-------|------|
|
|
27
|
+
| general | 通用多步骤任务,完整工具访问(除 todo),可并行执行 |
|
|
28
|
+
| explore | 快速只读代码探索,查找文件和搜索代码 |
|
|
29
|
+
| scout | 外部文档和依赖研究 |
|
|
30
|
+
|
|
31
|
+
## 使用方式
|
|
32
|
+
|
|
33
|
+
### 切换 Primary Agent
|
|
34
|
+
|
|
35
|
+
使用 Tab 键在会话中切换。
|
|
36
|
+
|
|
37
|
+
### 调用 Subagent
|
|
38
|
+
|
|
39
|
+
- **自动调用**:Primary Agent 根据描述自动选择合适的 Subagent
|
|
40
|
+
- **手动调用**:在消息中 `@` 提及,如 `@general help me search for this function`
|
|
41
|
+
|
|
42
|
+
### 会话导航
|
|
43
|
+
|
|
44
|
+
| 操作 | 快捷键 |
|
|
45
|
+
|------|--------|
|
|
46
|
+
| 进入第一个子会话 | `Leader+Down`(`session_child_first`) |
|
|
47
|
+
| 切换到下一个子会话 | `Right`(`session_child_cycle`) |
|
|
48
|
+
| 切换到上一个子会话 | `Left`(`session_child_cycle_reverse`) |
|
|
49
|
+
| 返回父会话 | `Up`(`session_parent`) |
|
|
50
|
+
|
|
51
|
+
## 配置方式
|
|
52
|
+
|
|
53
|
+
### JSON 配置
|
|
54
|
+
|
|
55
|
+
在 `opencode.json` 中配置:
|
|
56
|
+
|
|
57
|
+
```jsonc
|
|
58
|
+
{
|
|
59
|
+
"$schema": "https://opencode.ai/config.json",
|
|
60
|
+
"agent":{
|
|
61
|
+
"code-reviewer": {
|
|
62
|
+
"description": "Reviews code for best practices and potential issues",
|
|
63
|
+
"mode": "subagent",
|
|
64
|
+
"model": "anthropic/claude-sonnet-4-20250514",
|
|
65
|
+
"prompt": "You are a code reviewer. Focus on security, performance, and maintainability.",
|
|
66
|
+
"permission": {
|
|
67
|
+
"edit": "deny"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Markdown 配置
|
|
75
|
+
|
|
76
|
+
放置在以下位置:
|
|
77
|
+
|
|
78
|
+
- 全局:`~/.config/opencode/agents/`,如 `~/.config/opencode/agents/review.md`
|
|
79
|
+
- 项目级:`.opencode/agents/`
|
|
80
|
+
|
|
81
|
+
```md
|
|
82
|
+
---
|
|
83
|
+
description: Reviews code for quality and best practices
|
|
84
|
+
mode: subagent
|
|
85
|
+
model: anthropic/claude-sonnet-4-20250514
|
|
86
|
+
temperature: 0.1
|
|
87
|
+
permission:
|
|
88
|
+
edit: deny
|
|
89
|
+
bash: deny
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
You are in code review mode. Focus on:
|
|
93
|
+
|
|
94
|
+
- Code quality and best practices
|
|
95
|
+
- Potential bugs and edge cases
|
|
96
|
+
- Performance implications
|
|
97
|
+
- Security considerations
|
|
98
|
+
|
|
99
|
+
Provide constructive feedback without making direct changes.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
文件名即为 Agent 名称,如 `review.md` 创建 `review` Agent。
|
|
103
|
+
|
|
104
|
+
## 配置选项
|
|
105
|
+
|
|
106
|
+
### Description
|
|
107
|
+
|
|
108
|
+
提供 Agent 的简要描述和使用场景。
|
|
109
|
+
|
|
110
|
+
### Temperature
|
|
111
|
+
|
|
112
|
+
控制 LLM 响应的随机性和创造性:
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
{
|
|
116
|
+
"agent": {
|
|
117
|
+
"plan": { "temperature": 0.1 },
|
|
118
|
+
"creative": { "temperature": 0.8 }
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Steps
|
|
124
|
+
|
|
125
|
+
控制 Agent 最大迭代次数:
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
{
|
|
129
|
+
"agent": {
|
|
130
|
+
"quick-thinker": {
|
|
131
|
+
"description": "Fast reasoning with limited iterations",
|
|
132
|
+
"prompt": "You are a quick thinker. Solve problems with minimal steps.",
|
|
133
|
+
"steps": 5
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Disable
|
|
140
|
+
|
|
141
|
+
禁用 Agent:
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"agent": {
|
|
146
|
+
"review": { "disable": true }
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Prompt
|
|
152
|
+
|
|
153
|
+
指定自定义系统提示词文件:
|
|
154
|
+
|
|
155
|
+
```json
|
|
156
|
+
{
|
|
157
|
+
"agent": {
|
|
158
|
+
"review": {
|
|
159
|
+
"prompt": "{file:./prompts/code-review.txt}"
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Model
|
|
166
|
+
|
|
167
|
+
为 Agent 覆盖默认模型:
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"agent": {
|
|
172
|
+
"plan": { "model": "anthropic/claude-haiku-4-20250514" }
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Permissions
|
|
178
|
+
|
|
179
|
+
配置 Agent 的操作权限:
|
|
180
|
+
|
|
181
|
+
| 值 | 说明 |
|
|
182
|
+
|----|------|
|
|
183
|
+
| `ask` | 运行前需审批 |
|
|
184
|
+
| `allow` | 允许所有操作 |
|
|
185
|
+
| `deny` | 禁用工具 |
|
|
186
|
+
|
|
187
|
+
权限键值表:
|
|
188
|
+
|
|
189
|
+
| 键 | 控制的工具 |
|
|
190
|
+
|----|-----------|
|
|
191
|
+
| read | read |
|
|
192
|
+
| edit | write, edit, apply_patch |
|
|
193
|
+
| glob | glob |
|
|
194
|
+
| grep | grep |
|
|
195
|
+
| list | list |
|
|
196
|
+
| bash | bash |
|
|
197
|
+
| task | task |
|
|
198
|
+
| external_directory | 读写项目工作树外的文件 |
|
|
199
|
+
| todowrite | todowrite, todoread |
|
|
200
|
+
| webfetch | webfetch |
|
|
201
|
+
| websearch | websearch |
|
|
202
|
+
| lsp | lsp |
|
|
203
|
+
| skill | skill |
|
|
204
|
+
| question | question |
|
|
205
|
+
| doom_loop | Agent 卡住时的恢复提示 |
|
|
206
|
+
|
|
207
|
+
`read`、`edit`、`glob`、`grep`、`list`、`bash`、`task`、`external_directory`、`lsp`、`skill` 支持简写操作或 glob/模式到操作的对象映射。
|
|
208
|
+
|
|
209
|
+
按 Agent 覆盖权限:
|
|
210
|
+
|
|
211
|
+
```jsonc
|
|
212
|
+
{
|
|
213
|
+
"$schema": "https://opencode.ai/config.json",
|
|
214
|
+
"permission": { "edit": "deny" },
|
|
215
|
+
"agent": {
|
|
216
|
+
"build": { "permission": { "edit": "ask" } }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Markdown Agent 中配置权限:
|
|
222
|
+
|
|
223
|
+
```md
|
|
224
|
+
---
|
|
225
|
+
description: Code review without edits
|
|
226
|
+
mode: subagent
|
|
227
|
+
permission:
|
|
228
|
+
edit: deny
|
|
229
|
+
bash:
|
|
230
|
+
"*": ask
|
|
231
|
+
"git diff": allow
|
|
232
|
+
"git log*": allow
|
|
233
|
+
"grep *": allow
|
|
234
|
+
webfetch: deny
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
Only analyze code and suggest changes.
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Mode
|
|
241
|
+
|
|
242
|
+
控制 Agent 模式:`primary`、`subagent` 或 `all`(默认)。
|
|
243
|
+
|
|
244
|
+
### Hidden
|
|
245
|
+
|
|
246
|
+
隐藏 Subagent(不在 `@` 自动补全中显示):
|
|
247
|
+
|
|
248
|
+
```json
|
|
249
|
+
{
|
|
250
|
+
"agent": {
|
|
251
|
+
"internal-helper": { "mode": "subagent", "hidden": true }
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
仅对 `mode: subagent` 的 Agent 有效。
|
|
257
|
+
|
|
258
|
+
### Additional
|
|
259
|
+
|
|
260
|
+
其他选项将直接传递给 Provider 作为模型选项:
|
|
261
|
+
|
|
262
|
+
```json
|
|
263
|
+
{
|
|
264
|
+
"agent": {
|
|
265
|
+
"deep-thinker": {
|
|
266
|
+
"description": "Agent that uses high reasoning effort for complex problems",
|
|
267
|
+
"model": "openai/gpt-5",
|
|
268
|
+
"reasoningEffort": "high",
|
|
269
|
+
"textVerbosity": "low"
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## 创建 Agent
|
|
276
|
+
|
|
277
|
+
使用命令创建:
|
|
278
|
+
|
|
279
|
+
```
|
|
280
|
+
opencode agent create
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
交互式流程:
|
|
284
|
+
|
|
285
|
+
1. 选择保存位置(全局或项目级)
|
|
286
|
+
2. 描述 Agent 功能
|
|
287
|
+
3. 生成系统提示词和标识符
|
|
288
|
+
4. 选择允许的权限
|
|
289
|
+
5. 创建 Markdown 配置文件
|
|
290
|
+
|
|
291
|
+
## 常见用例
|
|
292
|
+
|
|
293
|
+
| Agent | 用途 |
|
|
294
|
+
|-------|------|
|
|
295
|
+
| Build | 全功能开发,所有工具启用 |
|
|
296
|
+
| Plan | 分析和规划,不修改文件 |
|
|
297
|
+
| Review | 代码审查,只读 + 文档工具 |
|
|
298
|
+
| Debug | 调查问题,bash + read 工具 |
|
|
299
|
+
| Docs | 文档编写,文件操作但无系统命令 |
|
|
300
|
+
|
|
301
|
+
## 更多内容
|
|
302
|
+
|
|
303
|
+
- [Agent 详解](/agents/detail) — 父子协作、提示词组装、权限设计
|
|
304
|
+
- [Agent 工作流](/agents/workflow) — 5 种工作流模式
|
|
305
|
+
- [Agent 设计模式](/agents/design-pattern) — 核心设计原则
|
|
306
|
+
- [Agent 示例](/agents/examples) — 实用示例
|
|
307
|
+
- [Agent 案例](/agents/cases) — 完整系统设计案例
|
|
308
|
+
- [Subagent 内部机制](/agents/subagent-internals) — task 工具实现、会话生命周期、权限隔离、后台 subagent、命令触发子任务
|
|
309
|
+
- [并行派发与调度策略](/agents/parallel-dispatch) — 并行机制、work agent 路由决策、摘要协议、设计决策
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# 并行派发与调度策略
|
|
2
|
+
|
|
3
|
+
> 并行工作流模式参见 [Agent 工作流](/agents/workflow)。本文聚焦 opencode task 工具的并行内部机制和 harness work agent 的调度策略。
|
|
4
|
+
|
|
5
|
+
## 并行原理
|
|
6
|
+
|
|
7
|
+
opencode 的 `task` 工具描述明确鼓励并行:
|
|
8
|
+
|
|
9
|
+
> "Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses"
|
|
10
|
+
|
|
11
|
+
当 LLM 在一条 assistant message 中返回多个 `task` tool call 时,opencode 的 chat processor **并发执行**这些工具调用。每个 `task` 调用创建独立的子会话,互不干扰。
|
|
12
|
+
|
|
13
|
+
## 并行限制
|
|
14
|
+
|
|
15
|
+
| 限制项 | 默认值 | 说明 |
|
|
16
|
+
|--------|--------|------|
|
|
17
|
+
| 并行数量 | 无显式限制 | work agent prompt 中限制 ≤5 |
|
|
18
|
+
| 嵌套深度 | `subagent_depth: 1` | 子 agent 默认不能再派发子 agent |
|
|
19
|
+
| 文件所有权 | 由编排者保证 | 同一文件不并行改(work agent 规划 writable 白名单) |
|
|
20
|
+
|
|
21
|
+
## 完整调度时序
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
用户 work agent task 工具 子会话(explore) 子会话(general)
|
|
25
|
+
│ │ │ │ │
|
|
26
|
+
│── "实现功能X" ─────►│ │ │ │
|
|
27
|
+
│ │ │ │ │
|
|
28
|
+
│ 解析输入 │ │ │
|
|
29
|
+
│ 路由判断: parallel │ │ │
|
|
30
|
+
│ 内联规划 │ │ │
|
|
31
|
+
│ todowrite 落单 │ │ │
|
|
32
|
+
│ │ │ │ │
|
|
33
|
+
│ ├── task(explore) ──►│创建子会话 ─────────►│ │
|
|
34
|
+
│ │ │parentID=父ID │ │
|
|
35
|
+
│ │ │权限隔离 │ │
|
|
36
|
+
│ │ │prompt 注入 ───────►│ │
|
|
37
|
+
│ ├── task(general) ──►│创建子会话 ──────────────────────────────►│
|
|
38
|
+
│ │ │parentID=父ID │ │
|
|
39
|
+
│ │ │权限隔离 │ │
|
|
40
|
+
│ │ │prompt 注入 ────────────────────────────►│
|
|
41
|
+
│ │ │ │ │
|
|
42
|
+
│ │ │ │ 工具调用(read/grep) │
|
|
43
|
+
│ │ │ │ 多轮 reasoning │
|
|
44
|
+
│ │ │ │ 生成结果摘要 │
|
|
45
|
+
│ │ │◄── XML 结果 ──────│ │
|
|
46
|
+
│ │ │ │ │
|
|
47
|
+
│ │ │ │ │ 工具调用(edit/bash)
|
|
48
|
+
│ │ │ │ │ 多轮 reasoning
|
|
49
|
+
│ │ │ │ │ 生成结果摘要
|
|
50
|
+
│ │ │◄── XML 结果 ─────────────────────────────│
|
|
51
|
+
│ │◄── 结果返回 ─────────│ │ │
|
|
52
|
+
│ │ │ │ │
|
|
53
|
+
│ 收集摘要 │ │ │
|
|
54
|
+
│ todowrite 勾单 │ │ │
|
|
55
|
+
│ 综合分析 │ │ │
|
|
56
|
+
│ 验收 │ │ │
|
|
57
|
+
│ │ │ │ │
|
|
58
|
+
│◄── 最终结果 ────────│ │ │ │
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## work agent 调度策略
|
|
62
|
+
|
|
63
|
+
### 路由决策
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
用户输入
|
|
67
|
+
│
|
|
68
|
+
▼
|
|
69
|
+
解析 target / root_dir / constraints
|
|
70
|
+
│
|
|
71
|
+
▼
|
|
72
|
+
路由判断
|
|
73
|
+
├─ single(单 worker 足够)
|
|
74
|
+
│ └─ 派 1 个 subagent 直接执行
|
|
75
|
+
│
|
|
76
|
+
└─ parallel(需要编排)
|
|
77
|
+
└─ 内联规划 → 并行派发 → 收集摘要 → 综合/验收
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
路由判断权重:**可拆性**(≥2 个独立子问题)> **时效**(用户要求快)> **规模**(文件多/改动大)
|
|
81
|
+
|
|
82
|
+
### subagent_type 选择
|
|
83
|
+
|
|
84
|
+
| subagent_type | 场景 | 工具权限 |
|
|
85
|
+
|---------------|------|---------|
|
|
86
|
+
| `explore` | 只读调研(搜索代码、读取文件、理解结构) | read/grep/glob(只读) |
|
|
87
|
+
| `general` | 可写改动(编辑代码、执行命令、多步实现) | 全部工具(可写) |
|
|
88
|
+
|
|
89
|
+
### 任务项规划格式
|
|
90
|
+
|
|
91
|
+
work agent 为每个子任务规划以下字段:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
task_id: T1 / T2 / ...
|
|
95
|
+
goal: 目标,≤1 句话,可验收
|
|
96
|
+
agent: explore(只读)| general(可写)
|
|
97
|
+
input: 自包含完整上下文
|
|
98
|
+
writable: 可写文件白名单(为空 ⇒ 只读)
|
|
99
|
+
forbidden: 禁改文件清单(至少含 constraints)
|
|
100
|
+
output: 交付说明(强制以摘要协议结尾)
|
|
101
|
+
budget: 预计 ≤5 分钟
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 并行规则
|
|
105
|
+
|
|
106
|
+
1. **路由判断**:先判断 single(单 worker 足够)还是 parallel(需要编排)
|
|
107
|
+
2. **文件所有权分区**:同一轮内并行的 subagent 不得改同一文件
|
|
108
|
+
3. **只读与可写并行**:只读调研任务与写文件任务可并行(只读不受分区限制)
|
|
109
|
+
4. **有依赖串行**:无依赖的并行,有依赖的串行
|
|
110
|
+
5. **容忍部分失败**:单个 worker failed/blocked 只记录不中断
|
|
111
|
+
|
|
112
|
+
## 摘要协议
|
|
113
|
+
|
|
114
|
+
所有被 work 派发的 subagent 必须以固定格式摘要结尾:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
## 结果摘要
|
|
118
|
+
status=done|partial|failed|blocked|escalate
|
|
119
|
+
结论: <≤3 行>
|
|
120
|
+
变更: <文件路径 + diff 摘要,每文件一行,无则填 无>
|
|
121
|
+
阻塞: <阻塞项,无则填 无>
|
|
122
|
+
建议: <下一步建议>
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Status | 含义 | 编排者动作 |
|
|
126
|
+
|--------|------|-----------|
|
|
127
|
+
| `done` | 目标完成 | 标记任务完成 |
|
|
128
|
+
| `partial` | 部分完成 | 记录,继续综合 |
|
|
129
|
+
| `failed` | 失败 | 记录失败项 |
|
|
130
|
+
| `blocked` | 被环境/依赖卡住 | 记录,可能重规划 |
|
|
131
|
+
| `escalate` | 超出边界/需人工介入 | 停止该分支,向用户说明 |
|
|
132
|
+
|
|
133
|
+
## 关键设计决策
|
|
134
|
+
|
|
135
|
+
### 上下文隔离
|
|
136
|
+
|
|
137
|
+
子 agent 完全隔离,看不到父会话历史。原因:防止上下文爆炸、确保聚焦、降低 token 消耗、使并行子 agent 互不干扰。代价:编排者必须为每个子任务编写自包含的 prompt。
|
|
138
|
+
|
|
139
|
+
### 权限收敛
|
|
140
|
+
|
|
141
|
+
子 agent 默认不能使用 `task` 和 `todowrite` 工具。原因:防止无限递归、任务清单管理是编排者独有的职责。例外:agent 的 `permission` 配置中显式允许 `task` 时可嵌套,但受 `subagent_depth` 限制。
|
|
142
|
+
|
|
143
|
+
### 结果精简
|
|
144
|
+
|
|
145
|
+
子 agent 只返回最后一条 text part,编排者只读取摘要。原因:防止结果倾倒导致父会话上下文膨胀、强制子 agent 浓缩信息。
|
|
146
|
+
|
|
147
|
+
### 容忍部分失败
|
|
148
|
+
|
|
149
|
+
单个 worker failed/blocked 只记录不中断。原因:并行任务中一个失败不应影响其他独立任务、最大化任务完成率。
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# Subagent 内部机制
|
|
2
|
+
|
|
3
|
+
> 基于 opencode v1.18.30 二进制逆向 + SDK 类型定义分析。配置层面(agent 定义、mode、permission)参见 [Agent 详解](/agents/detail)。
|
|
4
|
+
|
|
5
|
+
## task 工具参数
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
{
|
|
9
|
+
description: string, // 3-5 词的任务描述
|
|
10
|
+
prompt: string, // 完整任务指令(必须自包含)
|
|
11
|
+
subagent_type: string, // agent 名称(如 "explore"、"general")
|
|
12
|
+
task_id?: string, // 传入已有 task_id 可恢复之前的子会话
|
|
13
|
+
background?: boolean, // 实验性:后台执行
|
|
14
|
+
command?: string // 触发此任务的命令
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 执行流程(TaskTool.execute)
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
22
|
+
│ 1. 深度检查 │
|
|
23
|
+
│ 沿 parentID 链向上遍历,计算嵌套深度 h │
|
|
24
|
+
│ if h >= subagent_depth (默认 1) → 报错退出 │
|
|
25
|
+
├─────────────────────────────────────────────────────────────┤
|
|
26
|
+
│ 2. 权限检查 │
|
|
27
|
+
│ 向用户请求使用 subagent_type 的权限 │
|
|
28
|
+
│ (除非 bypassAgentCheck=true,如命令触发的子任务) │
|
|
29
|
+
├─────────────────────────────────────────────────────────────┤
|
|
30
|
+
│ 3. Agent 解析 │
|
|
31
|
+
│ AgentRegistry.get(subagent_type) │
|
|
32
|
+
│ 找不到 → "Unknown agent type" 错误 │
|
|
33
|
+
├─────────────────────────────────────────────────────────────┤
|
|
34
|
+
│ 4. 会话创建/恢复 │
|
|
35
|
+
│ 有 task_id → 尝试恢复已有子会话(继续之前的上下文) │
|
|
36
|
+
│ 无 task_id → 创建新子会话: │
|
|
37
|
+
│ Session.create({ │
|
|
38
|
+
│ parentID: 当前会话ID, │
|
|
39
|
+
│ title: description + " (@agent subagent)", │
|
|
40
|
+
│ agent: subagent_type, │
|
|
41
|
+
│ permission: [...继承+限制规则...] │
|
|
42
|
+
│ }) │
|
|
43
|
+
├─────────────────────────────────────────────────────────────┤
|
|
44
|
+
│ 5. 模型解析 │
|
|
45
|
+
│ 优先使用 agent 配置的 model │
|
|
46
|
+
│ 否则继承父 assistant message 的 model │
|
|
47
|
+
├─────────────────────────────────────────────────────────────┤
|
|
48
|
+
│ 6. 执行子任务 (TaskTool.runTask) │
|
|
49
|
+
│ a. 解析 prompt 中的 @file 引用 │
|
|
50
|
+
│ b. 调用 SessionPrompt.prompt({ │
|
|
51
|
+
│ sessionID: 子会话ID, │
|
|
52
|
+
│ model: 解析的模型, │
|
|
53
|
+
│ agent: subagent_type, │
|
|
54
|
+
│ parts: 解析后的 prompt parts │
|
|
55
|
+
│ }) │
|
|
56
|
+
│ c. 等待子会话 LLM 执行完成 │
|
|
57
|
+
│ d. 提取子 agent 最终消息的最后一个 text part │
|
|
58
|
+
├─────────────────────────────────────────────────────────────┤
|
|
59
|
+
│ 7. 结果返回 │
|
|
60
|
+
│ 前台模式: 等待完成,返回 XML 格式结果 │
|
|
61
|
+
│ 后台模式: 立即返回,完成后注入结果 │
|
|
62
|
+
└─────────────────────────────────────────────────────────────┘
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 结果格式
|
|
66
|
+
|
|
67
|
+
子 agent 的结果以 XML 标签返回给父 agent:
|
|
68
|
+
|
|
69
|
+
```xml
|
|
70
|
+
<task id="<sessionID>" state="completed">
|
|
71
|
+
<task_result>
|
|
72
|
+
<子 agent 最后一条 text part 的内容>
|
|
73
|
+
</task_result>
|
|
74
|
+
</task>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
失败时:
|
|
78
|
+
|
|
79
|
+
```xml
|
|
80
|
+
<task id="<sessionID>" state="error">
|
|
81
|
+
<task_error>
|
|
82
|
+
<错误信息>
|
|
83
|
+
</task_error>
|
|
84
|
+
</task>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 权限隔离(lt 函数)
|
|
88
|
+
|
|
89
|
+
子会话创建时,权限规则由 `lt()` 函数生成:
|
|
90
|
+
|
|
91
|
+
| 规则 | 默认效果 | 说明 |
|
|
92
|
+
|------|---------|------|
|
|
93
|
+
| `task: deny` | 禁止子 agent 再派发子 agent | 防止无限递归 |
|
|
94
|
+
| `todowrite: deny` | 禁止子 agent 使用 todowrite | 只有编排者管理任务清单 |
|
|
95
|
+
| `primary_tools: deny` | 禁止子 agent 使用 primary 专属工具 | 如 `experimental.primary_tools` 配置 |
|
|
96
|
+
| 继承父会话 `deny` 规则 | 保持安全策略一致 | |
|
|
97
|
+
| 继承父会话 `external_directory` 规则 | 保持目录访问限制 | |
|
|
98
|
+
|
|
99
|
+
除非 agent 的 `permission` 配置中显式允许 `task` 或 `todowrite`,否则默认被拒绝。
|
|
100
|
+
|
|
101
|
+
## 会话恢复(task_id 复用)
|
|
102
|
+
|
|
103
|
+
传入 `task_id` 可以恢复之前的子会话:
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
let T = m.task_id
|
|
107
|
+
? yield* t.get(wt.make(m.task_id)).pipe(s.catchCause(() => s.succeed(void 0)))
|
|
108
|
+
: void 0;
|
|
109
|
+
|
|
110
|
+
// 如果找到已有会话,复用;否则创建新的
|
|
111
|
+
let O = T ?? (yield* t.create({...}));
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
恢复时,子会话**保留之前的所有消息和工具输出**,新的 prompt 追加到已有消息序列后。这使得编排者可以:
|
|
115
|
+
- 让子 agent 继续未完成的任务
|
|
116
|
+
- 向子 agent 提供额外信息后重试
|
|
117
|
+
- 让子 agent 修正之前的错误
|
|
118
|
+
|
|
119
|
+
## 会话存储
|
|
120
|
+
|
|
121
|
+
- **存储后端**:SQLite(Node >= 22.5 用内置 `node:sqlite`,否则 `sqlite3` CLI)
|
|
122
|
+
- **存储位置**:`Path.state` 目录下的 SQLite 数据库
|
|
123
|
+
- **事件溯源**:v2 使用 durable events(`aggregateID` = sessionID, `seq` = 单调序号)
|
|
124
|
+
|
|
125
|
+
| 隔离维度 | 方式 |
|
|
126
|
+
|---------|------|
|
|
127
|
+
| 消息 | 每个 Message/Part 有 `sessionID`,按会话隔离 |
|
|
128
|
+
| 上下文 | 子会话不继承父会话消息 |
|
|
129
|
+
| 权限 | `lt()` 函数生成隔离的权限规则集 |
|
|
130
|
+
| 工具 | `primary_tools` 限制 + agent `tools` 配置 |
|
|
131
|
+
| 深度 | `subagent_depth` 限制嵌套层数 |
|
|
132
|
+
|
|
133
|
+
父子关系查询:`GET /session/{id}/children → Array<Session>`
|
|
134
|
+
|
|
135
|
+
## 后台 Subagent(实验性)
|
|
136
|
+
|
|
137
|
+
启用方式:`OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS=true` 或配置 `experimental.backgroundSubagents`。
|
|
138
|
+
|
|
139
|
+
| 维度 | 前台模式(默认) | 后台模式(实验性) |
|
|
140
|
+
|------|----------------|-------------------|
|
|
141
|
+
| 返回时机 | 等待子会话完成 | 立即返回 "running" |
|
|
142
|
+
| 父 agent 行为 | 阻塞等待 | 继续执行其他任务 |
|
|
143
|
+
| 结果注入 | 作为 tool result | 完成后注入 synthetic message |
|
|
144
|
+
| 提升机制 | 无 | `waitForPromotion()` 可将后台提升为前台 |
|
|
145
|
+
|
|
146
|
+
后台完成后,结果通过 `TaskTool.injectBackgroundResult` 注入父会话:
|
|
147
|
+
|
|
148
|
+
```javascript
|
|
149
|
+
yield* K.prompt({
|
|
150
|
+
sessionID: <父会话ID>,
|
|
151
|
+
parts: [{
|
|
152
|
+
type: "text",
|
|
153
|
+
synthetic: true,
|
|
154
|
+
text: <XML 格式的任务结果>
|
|
155
|
+
}]
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 命令触发的子任务(handleSubtask 路径)
|
|
160
|
+
|
|
161
|
+
除了 LLM 直接调用 `task` 工具外,还有一条由**命令**触发的子任务路径。
|
|
162
|
+
|
|
163
|
+
### 触发条件
|
|
164
|
+
|
|
165
|
+
当用户执行一个命令,且命令对应的 agent `mode === "subagent"` 时(或命令配置了 `subtask: true`),opencode 自动创建 `SubtaskPart`:
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
let G = ie.mode === "subagent" && O.subtask !== false || O.subtask === true;
|
|
169
|
+
let We = G ? [{
|
|
170
|
+
type: "subtask",
|
|
171
|
+
agent: ie.name,
|
|
172
|
+
description: O.description ?? "",
|
|
173
|
+
command: t.command,
|
|
174
|
+
model: { providerID, modelID },
|
|
175
|
+
prompt: Y.find((A) => A.type === "text")?.text ?? ""
|
|
176
|
+
}] : [...L, ...t.parts ?? []];
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### 执行差异
|
|
180
|
+
|
|
181
|
+
- **权限检查**:`bypassAgentCheck: true`,跳过用户权限确认
|
|
182
|
+
- **结果处理**:命令触发的子任务完成后,注入 synthetic user message:`"Summarize the task tool output above and continue with your task."`
|
|
183
|
+
- **消息创建**:自动创建 assistant message + tool part 记录子任务执行
|
|
184
|
+
|
|
185
|
+
### @agent 引用
|
|
186
|
+
|
|
187
|
+
用户在消息中使用 `@agent` 语法时,生成 `AgentPart`,opencode 注入 synthetic 指令:
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
Use the above message and context to generate a prompt and call the task tool with subagent: <agent_name>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## 关键类型定义
|
|
194
|
+
|
|
195
|
+
### SubtaskPart
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
type SubtaskPart = {
|
|
199
|
+
id: string
|
|
200
|
+
sessionID: string
|
|
201
|
+
messageID: string
|
|
202
|
+
type: "subtask"
|
|
203
|
+
prompt: string
|
|
204
|
+
description: string
|
|
205
|
+
agent: string // 要派发的 subagent 名称
|
|
206
|
+
model?: { providerID: string; modelID: string }
|
|
207
|
+
command?: string
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### 配置项参考
|
|
212
|
+
|
|
213
|
+
| 配置项 | 默认值 | 说明 |
|
|
214
|
+
|--------|--------|------|
|
|
215
|
+
| `subagent_depth` | `1` | 子 agent 嵌套深度限制 |
|
|
216
|
+
| `experimental.primary_tools` | `[]` | 仅 primary agent 可用的工具列表 |
|
|
217
|
+
| `experimental.backgroundSubagents` | `false` | 启用后台 subagent |
|