@harmonyos-arkts/opencode-acp 0.0.2 → 0.0.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/CHANGELOG.md +91 -0
- package/README.md +100 -42
- package/README.zh.md +36 -37
- package/dist/index.cjs +464 -187
- package/dist/index.cjs.map +4 -4
- package/docs/codebase-overview.md +49 -49
- package/docs/mcp-extmethod-design.md +366 -0
- package/docs/provider-config-flow.md +312 -0
- package/docs/question-asked.md +35 -18
- package/docs/session-stats-to-vscode-design.md +217 -0
- package/docs/subagent-visibility.md +26 -25
- package/docs/tui-vs-acp-analysis.md +36 -36
- package/package.json +4 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Provider Auth extMethod API:通过 ACP `extMethod("provider/*")` 向 VSCode 暴露 OpenCode 的 API Key 配置能力
|
|
10
|
+
- `provider/list` — 列出所有 provider 及连接状态
|
|
11
|
+
- `provider/auth/methods` — 获取各 provider 的认证方式和 prompts
|
|
12
|
+
- `provider/auth/set` — 设置 API Key 凭证
|
|
13
|
+
- `provider/auth/remove` — 移除 provider 凭证
|
|
14
|
+
- `provider/oauth/authorize` — 发起 OAuth 授权,获取授权 URL
|
|
15
|
+
- `provider/oauth/callback` — 完成 OAuth 回调
|
|
16
|
+
- `initialize()` 返回 `_meta.providers` 包含初始 provider 连接状态,VSCode 无需额外请求即可展示配置入口
|
|
17
|
+
- 新增 `src/auth-provider.ts`:AuthProviderManager 封装所有 SDK auth/provider 调用
|
|
18
|
+
|
|
19
|
+
### Tests
|
|
20
|
+
|
|
21
|
+
- 新增 `src/__tests__/auth-provider.test.ts`:AuthProviderManager 单元测试(6 个用例)
|
|
22
|
+
- `agent.test.ts` 新增 extMethod 路由测试(11 个用例),含参数校验和错误处理
|
|
23
|
+
- 测试总数从 101 增加到 118
|
|
24
|
+
|
|
25
|
+
## [0.0.3] - 2026-04-24
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- 子 session 完成事件:父 session 的 task 工具完成时发送 `session_info_update` + `status: "completed"`,包含 toolCallCount 和 durationMs
|
|
30
|
+
- 子 session 历史回放:`loadSession` 时自动发现并回放子 session 消息,客户端加载历史 session 时可见子 agent 输出
|
|
31
|
+
- 结构化子 session 元数据:`_meta` 中新增 `agentType`(如 `"explore"`)和 `description`(如 `"Explore project structure"`),客户端无需从 title 解析
|
|
32
|
+
- 子 session 用量汇总:`usage_update` 的 cost 包含所有子 session 开销,`_meta` 中附带 `parentCost`、`childCost`、`childSessionCount`
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- delta 处理性能优化:新增 `messageMetaCache` 缓存消息元数据,每个消息仅拉取一次 SDK(之前每个 delta chunk 拉取一次,N+1 查询问题)
|
|
37
|
+
- buffer flush 性能优化:新增 `sessionBufferIndex` 索引(sessionId → Set\<messageId\>),替代线性扫描全量 messageBuffers
|
|
38
|
+
- `resolveSession` 简化:移除冗余的 `findRootSession` 递归查找和第二次 `tryGet` 调用
|
|
39
|
+
- `announceChildSession` 支持可选 `meta` 参数传递结构化 agentType/description
|
|
40
|
+
|
|
41
|
+
### Tests
|
|
42
|
+
|
|
43
|
+
- 新增子 session 完成事件测试(task 工具完成 → completion event,非 task 工具 → 无 event)
|
|
44
|
+
- 新增结构化元数据解析测试(title 格式 `"description (@agent subagent)"` → agentType + description)
|
|
45
|
+
- 测试总数从 74 增加到 101(新增 27 个测试用例)
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
|
|
49
|
+
- MCP server 注册时正确传递 HTTP headers 和 local environment variables(之前被丢弃为空)
|
|
50
|
+
- MCP server 注册改为并行(`Promise.all`),多个 server 初始化更快
|
|
51
|
+
- `setSessionModel` 正确解析含 variant 的 modelId(如 `claude-sonnet-4/high`),返回 `_meta` 反馈
|
|
52
|
+
- `setSessionConfigOption` 正确处理 variant 和 mode,返回完整模型+模式列表
|
|
53
|
+
- `loadSessionMode` 模型列表包含 variant 选项,返回 `_meta` 含 variant 信息
|
|
54
|
+
- `loadSessionMode` 加载可用 agent/mode 列表并返回(之前固定返回 `undefined`)
|
|
55
|
+
- `setSessionMode` 增加 mode 存在性校验(之前静默接受无效 modeId)
|
|
56
|
+
- `prompt()` 使用动态解析的默认 agent 替代硬编码 `"build"`
|
|
57
|
+
- TodoWrite 工具输出解析为 plan update(历史回放 + 实时事件均已支持)
|
|
58
|
+
- `initialize` 检查 `clientCapabilities._meta["terminal-auth"]`,支持编辑器内登录(Zed 等)
|
|
59
|
+
- `/compact` 命令调用 `session.summarize()` 执行会话压缩(之前会被当成普通 prompt)
|
|
60
|
+
- 自动注入内置 `compact` 命令到 `available_commands_update`
|
|
61
|
+
|
|
62
|
+
### Added
|
|
63
|
+
|
|
64
|
+
- 添加 Vitest 单元测试框架(74 个测试用例)
|
|
65
|
+
- `src/__tests__/utils.test.ts` — toToolKind / toLocations / parseUri 纯函数测试
|
|
66
|
+
- `src/__tests__/session-manager.test.ts` — SessionManager 父子关系、session 生命周期测试
|
|
67
|
+
- `src/__tests__/logger.test.ts` — Logger 开关、分类、sanitize 测试
|
|
68
|
+
- `src/__tests__/event-handler.test.ts` — SSE 事件路由、权限处理、问题处理、工具状态转换测试
|
|
69
|
+
- 将 `parseUri` 从 `agent.ts` 提取到 `utils.ts` 以便复用和测试
|
|
70
|
+
|
|
71
|
+
## [0.0.1] - 2026-04-22
|
|
72
|
+
|
|
73
|
+
### event-handler.ts 改动
|
|
74
|
+
|
|
75
|
+
| 修复 | 说明 |
|
|
76
|
+
| ----------------- | ----------------------------------------------------------------------------------------- |
|
|
77
|
+
| edit 权限写空内容 | 使用 sdk.file.read() 读取原始内容 + applyPatch() 计算差异后的新内容,替代原来发送空字符串 |
|
|
78
|
+
| extMethod 吞错误 | .catch() 内增加 console.error 记录失败原因 |
|
|
79
|
+
| 60s 超时保护 | Promise.race 对 extMethod("questionAsked") 加 60 秒超时 |
|
|
80
|
+
| 转发 tool 上下文 | extMethod 参数中增加 q.tool(messageID + callID) |
|
|
81
|
+
| answers 校验 | 发送前验证 Array<Array<string>> 结构,不合法则 reject |
|
|
82
|
+
| 新增 diff 依赖 | package.json 中添加 diff 包 |
|
|
83
|
+
|
|
84
|
+
### agent.ts 改动
|
|
85
|
+
|
|
86
|
+
| 修复 | 说明 |
|
|
87
|
+
| -------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| LoadAPIKeyError 处理 | newSession/loadSession/forkSession/resumeSession 均增加 try/catch,检测 API key 错误抛 RequestError.authRequired() |
|
|
89
|
+
| usage_update size | 从 sdk.config.providers() 查询 model.limit.context 替代硬编码 0 |
|
|
90
|
+
| file 类型回放 | processMessage 中新增 file part 回放,支持 file://(resource_link)和 data: URL(image/resource) |
|
|
91
|
+
| resource_link 解析 | convertPromptParts 中实现 parseUri(),支持 file:// 和 zed:// URL 转为 file part;resource 类型也支持 blob 二进制数据 |
|
package/README.md
CHANGED
|
@@ -46,12 +46,17 @@ await sendToClient({
|
|
|
46
46
|
update: {
|
|
47
47
|
sessionUpdate: "session_info_update",
|
|
48
48
|
title: "Explore project structure (@explore subagent)",
|
|
49
|
-
_meta: {
|
|
49
|
+
_meta: {
|
|
50
|
+
parentSessionId,
|
|
51
|
+
isSubagent: true,
|
|
52
|
+
agentType: "explore",
|
|
53
|
+
description: "Explore project structure",
|
|
54
|
+
},
|
|
50
55
|
},
|
|
51
|
-
})
|
|
56
|
+
});
|
|
52
57
|
```
|
|
53
58
|
|
|
54
|
-
The client can distinguish parent vs child messages by sessionId, and use `_meta.parentSessionId` to display the hierarchy.
|
|
59
|
+
The client can distinguish parent vs child messages by sessionId, and use `_meta.parentSessionId` to display the hierarchy. When the subagent finishes, a `session_info_update` with `status: "completed"` is sent including `toolCallCount` and `durationMs`.
|
|
55
60
|
|
|
56
61
|
### Message Assembly
|
|
57
62
|
|
|
@@ -127,13 +132,13 @@ All communication is logged to `~/.harmony-acp/logs/` as JSONL files (auto-rotat
|
|
|
127
132
|
|
|
128
133
|
### Log Categories
|
|
129
134
|
|
|
130
|
-
| Category
|
|
131
|
-
|
|
132
|
-
| `acp.in`
|
|
133
|
-
| `acp.out`
|
|
134
|
-
| `oc.call`
|
|
135
|
-
| `oc.event` | OpenCode → Harmony-ACP | SSE events (session.created, permission.asked, etc.)
|
|
136
|
-
| `system`
|
|
135
|
+
| Category | Direction | Description |
|
|
136
|
+
| ---------- | ---------------------- | ------------------------------------------------------------ |
|
|
137
|
+
| `acp.in` | Editor → Harmony-ACP | Incoming ACP requests (initialize, prompt, newSession, etc.) |
|
|
138
|
+
| `acp.out` | Harmony-ACP → Editor | Outgoing ACP responses and session updates |
|
|
139
|
+
| `oc.call` | Harmony-ACP → OpenCode | Calls to OpenCode SDK (session.create, session.prompt, etc.) |
|
|
140
|
+
| `oc.event` | OpenCode → Harmony-ACP | SSE events (session.created, permission.asked, etc.) |
|
|
141
|
+
| `system` | Internal | Lifecycle events (start, stop, errors) |
|
|
137
142
|
|
|
138
143
|
### Log Viewer
|
|
139
144
|
|
|
@@ -167,17 +172,18 @@ When using `--content`, assembled messages are displayed with full text:
|
|
|
167
172
|
|
|
168
173
|
## Architecture
|
|
169
174
|
|
|
170
|
-
| File
|
|
171
|
-
|
|
172
|
-
| `src/index.ts`
|
|
173
|
-
| `src/agent.ts`
|
|
174
|
-
| `src/
|
|
175
|
-
| `src/
|
|
176
|
-
| `src/
|
|
177
|
-
| `src/
|
|
178
|
-
| `src/
|
|
179
|
-
| `
|
|
180
|
-
| `scripts/
|
|
175
|
+
| File | Purpose |
|
|
176
|
+
| ------------------------------ | ---------------------------------------------------------------------- |
|
|
177
|
+
| `src/index.ts` | CLI entry: argument parsing, stdio setup, server connection |
|
|
178
|
+
| `src/agent.ts` | ACP Agent: implements `Agent` interface, session management, prompting |
|
|
179
|
+
| `src/auth-provider.ts` | Provider auth manager: wraps SDK calls for API Key/OAuth configuration |
|
|
180
|
+
| `src/session-manager.ts` | Enhanced session tracking with parent-child relationship index |
|
|
181
|
+
| `src/event-handler.ts` | SSE event subscription, routing, and message delta assembly |
|
|
182
|
+
| `src/logger.ts` | JSONL structured logging with message assembly support |
|
|
183
|
+
| `src/types.ts` | Shared type definitions |
|
|
184
|
+
| `src/utils.ts` | Tool kind mapping utilities |
|
|
185
|
+
| `scripts/view-log.mjs` | Colorized log viewer |
|
|
186
|
+
| `scripts/test-integration.mjs` | Full pipeline integration test |
|
|
181
187
|
|
|
182
188
|
### SessionManager Enhancement
|
|
183
189
|
|
|
@@ -185,18 +191,64 @@ Unlike OpenCode's built-in `ACPSessionManager` which only knows about explicitly
|
|
|
185
191
|
|
|
186
192
|
- **Auto-discovers** child sessions via `session.created` SSE events
|
|
187
193
|
- **Maintains a parent-child index** (`children: Map<parentID, Set<childID>>`)
|
|
188
|
-
- **
|
|
194
|
+
- **Aggregates child session costs** for accurate usage reporting
|
|
189
195
|
|
|
190
196
|
### EventHandler Enhancement
|
|
191
197
|
|
|
192
198
|
The `EventHandler` subscribes to OpenCode's global SSE event stream and handles:
|
|
193
199
|
|
|
194
|
-
| Event
|
|
195
|
-
|
|
196
|
-
| `session.created`
|
|
197
|
-
| `permission.asked`
|
|
198
|
-
| `message.part.updated` | Routes tool execution updates
|
|
199
|
-
| `message.part.delta`
|
|
200
|
+
| Event | Behavior |
|
|
201
|
+
| ---------------------- | ------------------------------------------------------------------------------------ |
|
|
202
|
+
| `session.created` | Auto-registers child sessions, announces as virtual session with structured metadata |
|
|
203
|
+
| `permission.asked` | Forwards permission requests including those from child sessions |
|
|
204
|
+
| `message.part.updated` | Routes tool execution updates; sends completion event when task tool finishes |
|
|
205
|
+
| `message.part.delta` | Accumulates text/reasoning deltas using cached metadata (no N+1 queries) |
|
|
206
|
+
|
|
207
|
+
## Provider Auth extMethod API
|
|
208
|
+
|
|
209
|
+
Harmony-ACP exposes OpenCode's provider auth API to VSCode through ACP `extMethod` calls. This allows users to configure API keys and complete OAuth flows directly from the editor.
|
|
210
|
+
|
|
211
|
+
### Available Methods
|
|
212
|
+
|
|
213
|
+
| extMethod | Description |
|
|
214
|
+
|-----------|-------------|
|
|
215
|
+
| `provider/list` | List all providers with connected status |
|
|
216
|
+
| `provider/auth/methods` | Get auth methods per provider (API key prompts, OAuth) |
|
|
217
|
+
| `provider/auth/set` | Set API key credentials |
|
|
218
|
+
| `provider/auth/remove` | Remove credentials for a provider |
|
|
219
|
+
| `provider/oauth/authorize` | Start OAuth flow, returns authorization URL |
|
|
220
|
+
| `provider/oauth/callback` | Complete OAuth with authorization code |
|
|
221
|
+
|
|
222
|
+
### Usage Example (VSCode → Harmony-ACP)
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// List providers
|
|
226
|
+
const providers = await extMethod("provider/list", { sessionId });
|
|
227
|
+
|
|
228
|
+
// Set API key
|
|
229
|
+
await extMethod("provider/auth/set", {
|
|
230
|
+
providerID: "anthropic",
|
|
231
|
+
auth: { type: "api", key: "sk-ant-xxx" }
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
// Remove credentials
|
|
235
|
+
await extMethod("provider/auth/remove", { providerID: "anthropic" });
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Initialize Response
|
|
239
|
+
|
|
240
|
+
The `initialize()` response includes provider connectivity status in `_meta`:
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
{
|
|
244
|
+
_meta: {
|
|
245
|
+
providers: [
|
|
246
|
+
{ id: "anthropic", name: "Anthropic", connected: true },
|
|
247
|
+
{ id: "openai", name: "OpenAI", connected: false },
|
|
248
|
+
]
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
```
|
|
200
252
|
|
|
201
253
|
## Development
|
|
202
254
|
|
|
@@ -209,20 +261,26 @@ npm run test:integration # Full pipeline test (requires running OpenCode server
|
|
|
209
261
|
|
|
210
262
|
## Comparison with Built-in ACP
|
|
211
263
|
|
|
212
|
-
| Feature
|
|
213
|
-
|
|
214
|
-
| Session management
|
|
215
|
-
| Subagent tool calls visible
|
|
216
|
-
| Subagent text output visible
|
|
217
|
-
| Subagent permissions forwarded
|
|
218
|
-
|
|
|
219
|
-
|
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
|
|
|
223
|
-
|
|
|
224
|
-
|
|
|
225
|
-
|
|
|
264
|
+
| Feature | OpenCode Built-in ACP | Harmony-ACP |
|
|
265
|
+
| ------------------------------- | --------------------- | ---------------------------------- |
|
|
266
|
+
| Session management | Top-level only | Top-level + child sessions |
|
|
267
|
+
| Subagent tool calls visible | No | Yes |
|
|
268
|
+
| Subagent text output visible | No | Yes |
|
|
269
|
+
| Subagent permissions forwarded | No | Yes |
|
|
270
|
+
| Subagent completion event | No | Yes (status, duration, tool count) |
|
|
271
|
+
| Subagent history replay on load | No | Yes |
|
|
272
|
+
| Subagent cost aggregation | No | Yes (childCost in usage_update) |
|
|
273
|
+
| Structured subagent metadata | No | Yes (agentType, description) |
|
|
274
|
+
| Traffic logging | No | Yes (JSONL, categorized) |
|
|
275
|
+
| Message assembly | N/A | Yes (delta → complete) |
|
|
276
|
+
| Delta N+1 query optimization | N/A | Yes (message metadata cache) |
|
|
277
|
+
| MCP headers/env passthrough | Yes | Yes |
|
|
278
|
+
| Model variant support | Yes | Yes |
|
|
279
|
+
| Mode/agent list loading | Yes | Yes |
|
|
280
|
+
| TodoWrite → plan update | Yes | Yes |
|
|
281
|
+
| Provider auth via extMethod | No | Yes (API Key + OAuth) |
|
|
282
|
+
| Modifies OpenCode source | N/A | No |
|
|
283
|
+
| Runs as independent process | No (integrated) | Yes |
|
|
226
284
|
|
|
227
285
|
## License
|
|
228
286
|
|
package/README.zh.md
CHANGED
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
OpenCode 内置的 ACP 有两个关键限制:
|
|
8
8
|
|
|
9
9
|
1. **子代理不可见**:当代理通过 Task 工具派生子代理时,子 session 的事件——工具调用、文本输出、权限请求——对 ACP 客户端(如 Zed、VSCode)完全不可见。原因是内置的 `SessionManager` 只注册顶层 session,来自子 session 的事件会被静默丢弃。
|
|
10
|
-
|
|
11
|
-
2. **无法进行问题回答**:无法进行
|
|
10
|
+
2. **无法进行问题回答**:当大模型有问题需要用户回答时,opencode acp没有监听,ACP客户端(如Zed/ VSCode)无法感知
|
|
12
11
|
|
|
13
12
|
Harmony-ACP 在不修改任何 OpenCode 源码的前提下解决了这两个问题。
|
|
14
13
|
|
|
@@ -46,7 +45,7 @@ await sendToClient({
|
|
|
46
45
|
title: "Explore project structure (@explore subagent)",
|
|
47
46
|
_meta: { parentSessionId, isSubagent: true },
|
|
48
47
|
},
|
|
49
|
-
})
|
|
48
|
+
});
|
|
50
49
|
```
|
|
51
50
|
|
|
52
51
|
客户端通过 sessionId 区分父/子消息,通过 `_meta.parentSessionId` 展示层级关系。
|
|
@@ -125,13 +124,13 @@ node dist/index.cjs --server http://localhost:4096
|
|
|
125
124
|
|
|
126
125
|
### 日志分类
|
|
127
126
|
|
|
128
|
-
| 分类
|
|
129
|
-
|
|
130
|
-
| `acp.in`
|
|
131
|
-
| `acp.out`
|
|
132
|
-
| `oc.call`
|
|
133
|
-
| `oc.event` | OpenCode → Harmony-ACP | SSE 事件(session.created、permission.asked 等)
|
|
134
|
-
| `system`
|
|
127
|
+
| 分类 | 方向 | 说明 |
|
|
128
|
+
| ---------- | ---------------------- | ----------------------------------------------------------- |
|
|
129
|
+
| `acp.in` | 编辑器 → Harmony-ACP | 收到的 ACP 请求(initialize、prompt、newSession 等) |
|
|
130
|
+
| `acp.out` | Harmony-ACP → 编辑器 | 发出的 ACP 响应和 session 更新 |
|
|
131
|
+
| `oc.call` | Harmony-ACP → OpenCode | 对 OpenCode SDK 的调用(session.create、session.prompt 等) |
|
|
132
|
+
| `oc.event` | OpenCode → Harmony-ACP | SSE 事件(session.created、permission.asked 等) |
|
|
133
|
+
| `system` | 内部 | 生命周期事件(启动、停止、错误) |
|
|
135
134
|
|
|
136
135
|
### 日志查看器
|
|
137
136
|
|
|
@@ -165,17 +164,17 @@ node scripts/view-log.mjs --list
|
|
|
165
164
|
|
|
166
165
|
## 架构
|
|
167
166
|
|
|
168
|
-
| 文件
|
|
169
|
-
|
|
170
|
-
| `src/index.ts`
|
|
171
|
-
| `src/agent.ts`
|
|
172
|
-
| `src/session-manager.ts`
|
|
173
|
-
| `src/event-handler.ts`
|
|
174
|
-
| `src/logger.ts`
|
|
175
|
-
| `src/types.ts`
|
|
176
|
-
| `src/utils.ts`
|
|
177
|
-
| `scripts/view-log.mjs`
|
|
178
|
-
| `scripts/test-integration.mjs` | 全链路集成测试
|
|
167
|
+
| 文件 | 职责 |
|
|
168
|
+
| ------------------------------ | ---------------------------------------------------------------- |
|
|
169
|
+
| `src/index.ts` | 入口:参数解析、stdio 设置、服务器连接 |
|
|
170
|
+
| `src/agent.ts` | ACP 代理:实现 `Agent` 接口、session 管理、prompt 转发、日志包装 |
|
|
171
|
+
| `src/session-manager.ts` | 增强版 session 管理,维护父子关系索引 |
|
|
172
|
+
| `src/event-handler.ts` | SSE 事件订阅、路由和消息 delta 拼装 |
|
|
173
|
+
| `src/logger.ts` | JSONL 结构化日志,支持消息拼装 |
|
|
174
|
+
| `src/types.ts` | 共享类型定义 |
|
|
175
|
+
| `src/utils.ts` | 工具函数(toolKind 映射等) |
|
|
176
|
+
| `scripts/view-log.mjs` | 彩色日志查看器 |
|
|
177
|
+
| `scripts/test-integration.mjs` | 全链路集成测试 |
|
|
179
178
|
|
|
180
179
|
各文件的详细分析见 [docs/codebase-overview.md](docs/codebase-overview.md)。
|
|
181
180
|
|
|
@@ -191,12 +190,12 @@ node scripts/view-log.mjs --list
|
|
|
191
190
|
|
|
192
191
|
`EventHandler` 订阅 OpenCode 的全局 SSE 事件流并处理:
|
|
193
192
|
|
|
194
|
-
| 事件
|
|
195
|
-
|
|
196
|
-
| `session.created`
|
|
197
|
-
| `permission.asked`
|
|
198
|
-
| `message.part.updated` | 路由子 session 的工具执行状态更新
|
|
199
|
-
| `message.part.delta`
|
|
193
|
+
| 事件 | 行为 |
|
|
194
|
+
| ---------------------- | ----------------------------------------------------- |
|
|
195
|
+
| `session.created` | 自动注册子 session,作为虚拟 session 公告给客户端 |
|
|
196
|
+
| `permission.asked` | 转发权限请求,包括来自子 session 的请求 |
|
|
197
|
+
| `message.part.updated` | 路由子 session 的工具执行状态更新 |
|
|
198
|
+
| `message.part.delta` | 累积文本/推理 delta,流式转发给客户端,拼装后写入日志 |
|
|
200
199
|
|
|
201
200
|
## 开发
|
|
202
201
|
|
|
@@ -210,16 +209,16 @@ npm run test:integration # 全链路集成测试(需运行 OpenCode 服务
|
|
|
210
209
|
|
|
211
210
|
## 与内置 ACP 对比
|
|
212
211
|
|
|
213
|
-
| 特性
|
|
214
|
-
|
|
215
|
-
| Session 管理
|
|
216
|
-
| 子代理工具调用可见
|
|
217
|
-
| 子代理文本输出可见
|
|
218
|
-
| 子代理权限请求转发
|
|
219
|
-
| 流量日志
|
|
220
|
-
| 消息碎片拼装
|
|
221
|
-
| 是否修改 OpenCode 源码 | —
|
|
222
|
-
| 运行方式
|
|
212
|
+
| 特性 | OpenCode 内置 ACP | Harmony-ACP |
|
|
213
|
+
| ---------------------- | ---------------------- | ---------------------- |
|
|
214
|
+
| Session 管理 | 仅顶层 session | 顶层 + 子 session |
|
|
215
|
+
| 子代理工具调用可见 | 否 | 是 |
|
|
216
|
+
| 子代理文本输出可见 | 否 | 是 |
|
|
217
|
+
| 子代理权限请求转发 | 否 | 是 |
|
|
218
|
+
| 流量日志 | 无 | 有(JSONL,分类记录) |
|
|
219
|
+
| 消息碎片拼装 | N/A | 有(delta → 完整消息) |
|
|
220
|
+
| 是否修改 OpenCode 源码 | — | 否 |
|
|
221
|
+
| 运行方式 | 集成在 OpenCode 进程内 | 独立进程 |
|
|
223
222
|
|
|
224
223
|
## 许可证
|
|
225
224
|
|