Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ Codeg(Code Generation)是一个多智能体编码工作台,它将多个智

## 代码检查与测试(任务完成后进行必要的检查)

### 测试运行方式(必须遵守)

- 功能验证只使用 Web 服务(`codeg-server`)及其浏览器页面,不使用 Windows 桌面客户端作为测试对象。
- 永远不编译、构建或打包桌面端,也不启动桌面客户端进行测试。禁止启用 `tauri-runtime`,禁止运行 `pnpm tauri dev`、`pnpm tauri build` 或默认开启桌面 feature 的 Cargo 命令。
- 所有后端检查、测试和构建必须显式指定 `--no-default-features`;按需启用 `server-bin` 或 `mcp-bin`。
- 验证界面时启动 WebServer 并访问其 HTTP 地址。需要隔离数据时使用独立 `CODEG_DATA_DIR`,不得通过测试修改正在使用的桌面数据。

### 前端

```bash
Expand All @@ -31,11 +38,6 @@ pnpm build # 静态导出构建
### 后端 Rust(在 `src-tauri/` 目录下执行)

```bash
# 桌面模式(默认 feature)
cargo check
cargo test --features test-utils
cargo clippy --all-targets --features test-utils -- -D warnings

# 服务器模式
cargo check --no-default-features --features server-bin --bin codeg-server
cargo test --no-default-features --features server-bin --bin codeg-server --lib
Expand All @@ -47,7 +49,7 @@ cargo clippy --no-default-features --features mcp-bin --bin codeg-mcp -- -D warn

# 解析器快照评审(输出变化时)
cargo insta review
INSTA_UPDATE=auto cargo test --features test-utils # 自动写新 .snap
INSTA_UPDATE=auto cargo test --no-default-features --features server-bin --lib
```

## 架构
Expand Down
98 changes: 98 additions & 0 deletions docs/development/subsession-messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# 父子会话多轮沟通

父会话先用 `delegate_to_agent` 创建子会话,再用返回的
`child_conversation_id` 向同一个子会话继续发送消息。每次发送都有独立的
`message_id`,子会话的 ID、工作目录和代理上下文保持不变。

## 发送和管理

排队发送是默认行为,当前轮结束后按顺序执行:

```json
{"child_conversation_id": 42, "message": "完成后补充接口测试", "delivery": "queue"}
```

以上参数传给 `send_to_subsession`。需要马上调整时,使用
`"delivery": "immediate"`:支持原生 steering 的连接直接接收指令;否则取消
当前轮,等待原 ACP 请求、旧通知和生命周期持久化处理完成,再发送新一轮。
取消确认超过 30 秒会暂停续发并返回错误,不会并发执行两个 prompt,也不会
暗中新建空白会话。

通过 `manage_subsession_messages` 查询消息及结果:

```json
{"child_conversation_id": 42, "action": "list"}
```

修改或取消仍在排队的消息:

```json
{"child_conversation_id": 42, "action": "update", "message_id": "返回的消息 ID", "message": "完成后改为补充异常路径测试"}
{"child_conversation_id": 42, "action": "cancel", "message_id": "返回的消息 ID"}
```

编辑、取消与出队竞争时,以数据库条件更新的结果为准。已经开始投递或执行
的消息返回 `not_queued`,不会被队列编辑接口覆盖。

## 状态和恢复

- `queued`:等待执行,可编辑或取消。
- `dispatching`:立即消息已被认领,正在 steering 或停止原执行轮。
- `running`:消息作为新一轮 prompt 执行。
- `delivered`:指令已通过 steering 投递,不表示代理已完成处理。
- `completed`、`failed`、`canceled`:该轮的结果。
- `interrupted`:认领消息的进程已退出;不会自动重放已执行过的操作。

消息、顺序和结果保存在 SQLite。刷新浏览器不会丢失队列;父会话重新连接后
查询或发送消息,会重新检查待执行队列。代理连接已回收时,必须成功加载原
代理会话才能继续;无法续接时明确拒绝。

原 `task_id` 仍用于首次委托和中断恢复。后续消息通过上述管理工具读取结果,
不使用 `resume_delegation` 携带新指令。普通子会话回复仍由父会话查询;需要主动
汇报时,子会话显式调用下面的 `send_to_parent`。

`manage_subsession_messages(action=list)` 只列出 `send_to_subsession` 创建的
后续消息。首次委派的结果仍通过 `get_delegation_status` 查询。

## 子会话主动汇报

子会话调用 `send_to_parent`,只传消息内容:

```json
{"message": "接口已完成,测试发现一个需要你决定的问题:是否保留旧参数?"}
```

父会话由当前已认证的子会话和数据库归属关系确定,不能指定其他会话。普通
会话、已删除的子会话或已删除的父会话不能使用此工具。

工具立即返回消息 ID 和 `queued` 回执,不等待父会话回答。父会话忙时,消息
保持排队;父会话当前轮结束且生命周期处理完成后,系统向原父会话发送带
来源标记的新一轮消息,自动唤醒父代理处理。多个子会话的汇报按入队顺序
串行投递,不中断父会话当前工作。父会话可以通过 `send_to_subsession` 回答。

汇报记录保存在 `parent_reply` 收件箱中,包含子会话 ID、消息 ID、状态及
父会话处理结果。父会话连接关闭时保留排队消息;可以从仍活跃的子会话严格
续接父代理,也可以等待父会话重新打开。无法确认运行时归属时不接管原会话。
进程退出前已经开始执行的汇报恢复为 `interrupted`,不会自动重放。

只有显式汇报才会唤醒父会话。父子代理应在有进展、结果或问题时发送,避免
互相发送无意义的确认消息,反复启动对方。

聊天输入框上方的现有排队区域同时显示手工消息和后端待执行消息。父子会话
消息带来源会话名称和“排队中”状态;开始执行后从排队区域移除。后端消息由
`list_pending_session_messages` 读取 SQLite,在当前会话打开时加载、每秒更新,
刷新页面后恢复。前端只展示这些条目,不参与投递,也不提供手工队列的拖动、
编辑、取消或立即插入按钮。

## 验证

只使用 `codeg-server` 的浏览器页面、HTTP/WebSocket 服务及 MCP 伴生进程
验证。遵守 `AGENTS.md`,禁止编译或使用桌面端作为测试对象。

浏览器验收包含两类代理:可控 ACP 测试代理用于排队、编辑、取消和立即发送;
真实 Claude Code ACP 代理用于验证模型实际调用工具、完成首次委派,再向
同一子会话发送后续消息并查询结果,确认跨轮上下文保留。

主动汇报使用真实 Claude Code ACP 代理在 Web 页面验证:子会话调用
`send_to_parent` 后,空闲父会话自动开启新轮处理;父会话正在执行时,报告
先入队,当前轮完成后自动投递。两条报告均保存了父会话的处理结果。
Loading
Loading