Files
2026Technology-Competition/docs/superpowers/plans/ws-task-2-report.md
T
lhl 80daadcd31 fix(websocket): 修复 app.py 不可导入并新增真实链路验证
- 将 /api/sessions/{sid}/ws 端点移入 create_app(此前置于模块级导致整模块 import NameError,回归被验证拦截)
- register_loop + subscribe 调整至 accept 之前,缩小连接已开但未订阅期间的进度丢失窗口
- 新增 tests/test_verify_ws_real_flow.py:驱动真实 HTTP 聊天流程断言 WS 收到 agent 实际发射的 parse/impact 进度
- 同步 WebSocket 计划文档 Task 3 代码片段(标注端点必须位于 create_app 内)
- 全量 pytest 实测 583 passed / 99.03% 达标
2026-08-29 14:36:12 +08:00

27 lines
2.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Task 2 报告:agent 产出进度/错误时发射事件
## 状态
完成(2 passed)。
## 提交
- 提交短哈希:`8493bea`
- 提交信息:`feat(chat): agent 产出进度/错误时发射事件(保留持久化兜底)`
- 仅变更:`src/genesis/chat/agent.py``tests/test_chat_agent_ws.py`
## 测试输出摘要
- `python -m pytest tests/test_chat_agent_ws.py -q -o addopts=""``2 passed`
- `python -m pytest tests/test_chat_agent.py tests/test_server_chat_api.py -q -o addopts=""``43 passed`(既有聊天测试全绿,未破坏)
## 实现要点
1. 顶部新增导入 `from genesis.server.hub import hub as _progress_hub`(原文件无 `hub` 局部变量/导入,故直接用 `_progress_hub` 别名,无冲突)。
2. `ChatAgent.__init__` 新增可选参数 `progress_sink: Callable[[dict], None] | None = None`,保存为 `self.progress_sink`
3. 新增 `_emit_progress(session_id, item)``_emit_error(session_id, reply, action)`:优先 `progress_sink` 回调,否则经 `_progress_hub.emit` 发射。
4. 在全部 `progress.append(item)` 之后紧接着调用 `self._emit_progress(session_id, progress[-1])`(覆盖 `_handle_confirmation` 确认成功、`_parse_and_confirm` 中 parse/impact、`_run_impact` 的 impact、`_run_generate` 的 generate/qa ok/qa warn、`_run_qa` 的 qa ok 共 8 处)。
5. 在全部错误分支调用 `_store_error(...)` 之前先调用 `self._emit_error(session_id, reply, action)`(共 6 处:`confirm`/`generate`(解析)/`parse`/`impact`/生成失败/`qa`)。
6. 既有 `_persist_progress` / `_store_error` 数据库持久化保持不变(重载兜底)。
## 疑虑与偏离
- **测试偏离说明(重要)**:任务给定的测试模板使用 `SessionStore(db_path=":memory:")`。但本仓库 `SessionStore``_conn()` 每次都新建连接,而 `:memory:` 每次连接是独立空库,`_init_db()` 建表对后续 `create_session` 不可见,导致 `no such table: sessions`。实测按原样 `:memory:` 两个测试均 `OperationalError` 失败。为达到「2 passed」目标,将测试中的 `:memory:` 改为临时目录下的真实文件(`tempfile.mkdtemp` + 固定文件名),其余断言完全照抄。功能验证不受影响(两个测试仅直接调用 `_emit_progress`/`_emit_error`session_id 仅作占位)。建议后续评估 `SessionStore``:memory:` 的兼容性,或仓库统一测试约定。
- **旧错误回复写法**:核查确认原 `agent.py` 所有错误分支均已使用 `self._store_error(...)`(无 `self.store.add_message(..., "assistant", ...)` 旧写法),故未改动错误回复的持久化写法,仅在每处 `_store_error` 前插入 `_emit_error`
- **progress.append 位置**:已逐处确认 8 个 `progress.append` 均位于实际流程产出点;其中 `_parse_and_confirm` 内 emit 在 `if rec.status == "impact_running"` 分支的 impact append 之后,符合“每处 append 后 emit”的要求。