Skip to content

fix: 修复 session 历史丢失 tool_calls - #68

Merged
zuiho-kai merged 29 commits into
masterfrom
fix-session-toolcalls
Mar 21, 2026
Merged

zuiho-kai merged 29 commits into
masterfrom
fix-session-toolcalls

Conversation

@zuiho-kai

@zuiho-kai zuiho-kai commented Mar 20, 2026 •

Copy link
Copy Markdown
Owner

修复内容

Python 逻辑修复

  • fix: interrupt 后补发 status:idle 修复测试死锁
    • interrupt() 新增返回值 was_running: bool
    • ws_handler 仅在 was_running=True 时补发 status:idle,避免打扰正常完成的响应

E2E 测试基础设施修复

  • fix: 改用 HTTP 轮询代替 pipe READY 信号(mock server EPIPE 崩溃)
    • global-setup.ts 改为 stdio: 'ignore' + HTTP /health 轮询,彻底消除 pipe EPIPE 问题
  • fix: E2E 测试时跳过后端启动,避免 mock server 被杀死
    • main.js 加 NODE_ENV !== "test" 守卫,防止 startBackend() 用 netstat 杀掉 mock server

CI 配置修复

  • ci: E2E job 禁用 uv 缓存
    • setup-uv 改为 enable-cache: false,修复 post-step 缓存目录不存在报错

流程改进

  • 落盘 DEV-107(E2E 测试未隔离 App 自启动后端)、DEV-108(CI cache post-step 坑)
  • CLAUDE.md 修复门禁补强跨 session 计数规则

CI 状态

✅ Python 测试通过 | ✅ E2E 测试通过

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

1. 修复 session 历史丢失 tool_calls 导致 LLM 输出 XML 格式工具调用
   - session_manager.py: add_turn() 接受可选 tool_calls 参数
   - voice_pipeline.py: 保存 assistant 回复时同时保存 tool_calls
   - prompt_assembler.py: 组装 prompt 时恢复 tool_calls

2. 提升易用性:自动安装 Chromium
   - pyproject.toml: playwright 从 optional 移到必需依赖
   - playwright_provider.py: 首次启动时自动检查并安装 Chromium

新用户现在只需:
  uv sync
无需手动运行 playwright install

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@zuiho-kai
zuiho-kai force-pushed the fix-session-toolcalls branch from 49f28a4 to 301a199 Compare March 20, 2026 18:00
zuiho-kai and others added 3 commits March 21, 2026 10:59
修复 PR #68 CI 失败:actions/setup-node 的 cache-dependency-path
指向不存在的 package-lock.json,改为使用 package.json。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- uv: 启用 setup-uv 内置缓存,避免每次下载 uv 工具
- Playwright: 添加浏览器二进制缓存,命中时跳过下载

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 缓存 tests/e2e/node_modules,命中时跳过 npm ci
- 配合 npm 全局缓存,E2E 依赖安装可提速

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zuiho-kai added a commit that referenced this pull request Mar 21, 2026
修复 PR #68 CI 失败:actions/setup-node 的 cache-dependency-path
指向不存在的 package-lock.json,改为使用 package.json。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
zuiho-kai and others added 23 commits March 21, 2026 11:33
npm ci 需要 lock 文件,之前缺失导致 CI 失败。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
合并 master 分支的变更:
- 添加 timeout-minutes 防止卡死
- 添加 uv pip 缓存和 cache-suffix

保留 PR 的优化:
- node_modules 缓存
- Playwright 浏览器缓存
- 修正 cache-dependency-path 为 package.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
测试名称中的引号冲突导致语法错误,将外层引号改为单引号。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
确保缓存 key 包含完整依赖树信息,避免缓存不完整导致 ws 模块缺失。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
添加 npm list ws 检查,确认 ws 模块已正确安装。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
统一缓存 key 使用 package-lock.json,确保缓存准确性。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
在 E2E 测试前手动启动 mock server 并测试 health endpoint,
确认服务可访问。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
global-setup.ts 已经会启动 mock server,CI 中不需要再手动启动。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 捕获 Electron 浏览器控制台日志以便调试
- 增加等待时间和超时时间,给 WebSocket 更多连接时间

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
将 mock server 从 127.0.0.1 改为 0.0.0.0,使 Electron 可以连接。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Windows CI 环境可能存在 127.0.0.1 解析问题,改为使用 localhost。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
检查端口占用、localhost 连通性和 hosts 配置。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 添加 shell: true 以支持 Windows 环境
- 添加详细日志便于调试
- 延长超时时间到 10 秒

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 使用 process.execPath 替代 'node' 命令
- 移除 shell: true,直接启动 node 进程
- 避免 shell 退出导致子进程被杀死

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 添加全局 uncaughtException 和 unhandledRejection 处理
- 添加 WebSocket 服务器级别错误处理
- 添加 HTTP 服务器错误处理
- 添加心跳定时器保持进程运行
- 添加详细的连接/关闭日志

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 添加 ws.readyState 检查确保连接打开才发送
- 添加详细的错误日志
- 在事件处理器中立即设置错误处理

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 将整个代码包装在 try-catch 中
- 添加更多错误处理和日志
- 添加 beforeExit 和 exit 事件处理

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 简化代码结构
- 在每个步骤添加日志
- 更容易定位崩溃位置

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
根因:_respond task 被 cancel 后 finally 块因 _interrupted=True
跳过发 status:idle;ws_handler interrupt 分支也不发。
导致 test_interrupt_does_not_crash 在 CI 死锁 15 分钟。

修复:interrupt() 返回 was_running 布尔值;
ws_handler 仅在确实取消了正在运行的任务时才补发 status:idle,
避免 _respond 已正常完成时发出多余的 idle 消息。
根因:stdio: pipe + detached 模式下,parent 关闭 stdout pipe 后
child 写 console.log 触发 EPIPE → uncaughtException 里再 console.error
→ 又 EPIPE → Node.js 因 exception-in-exception-handler 以 exit 1 退出。

这解释了为何有 10+ 次 fix 尝试都失败:都在 mock-server.js 里加错误处理,
但根本问题在 global-setup.ts 的 pipe 设计。

修复:spawn 时改为 stdio: 'ignore'(无 pipe),用 HTTP /health 轮询就绪,
彻底消除 EPIPE 可能。
NODE_ENV=test 时,startBackend() 会先用 netstat 查杀端口 12393
上的进程(即 mock server),再尝试启动 Python 后端(CI 无
runtime),导致 WebSocket 无处可连,前端显示"已断开 - 重连中..."。

添加 NODE_ENV 守卫,测试模式下跳过 startBackend(),mock server
保持运行,Electron 可正常连接到 ws://localhost:12393/ws。
E2E job 有 .venv 全量缓存,uv sync 通常被跳过,uv 不下载
任何包,导致 setup-uv 的 post-step 找不到缓存目录报错,
整个 run 被标记为 failure。改为 enable-cache: false 避免此问题。
DEV-107:E2E 测试时未考虑 Electron App 自带 startBackend() 会
netstat 查杀端口进程,把 mock server 干掉后 WebSocket 无处可连

DEV-108:GitHub Actions setup-uv enable-cache=true 但实际 step
被条件跳过时,post-step 找不到缓存目录 → 整个 job 标 failure
问题:跨 session 补丁螺旋时,每次新对话 fix 计数归零,
修复门禁从未触发(DEV-83 失效根因)。

修复:
1. 入口门禁 Bug 修复流程:明确要求先 git log 数已有 fix 次数
2. 修复门禁模板:注明跨 session 也算,必须从 git log 计数不能凭记忆
@zuiho-kai
zuiho-kai merged commit 6d28508 into master Mar 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant