Skip to content

fix: 修复缓存统计和 WebSearch 转换#392

Merged
icebear0828 merged 2 commits intoicebear0828:masterfrom
hangox:pr/upstream-fixes
Apr 17, 2026
Merged

fix: 修复缓存统计和 WebSearch 转换#392
icebear0828 merged 2 commits intoicebear0828:masterfrom
hangox:pr/upstream-fixes

Conversation

@hangox
Copy link
Copy Markdown
Contributor

@hangox hangox commented Apr 16, 2026

说明

这个 PR 主要修复两个问题:

  1. Claude / Anthropic 请求经过 Codex proxy 时,缓存创建相关的 usage 字段没有完整上报,导致缓存统计不准确。
  2. WebSearch 工具在不同协议之间转换不完整,导致 hosted web search 无法稳定映射到 Codex 的 web_search 工具。

这部分修改是我通过 AI 辅助整理和实现的。我已经在自己的分支上连续测试了几天,目前缓存统计和 WebSearch 使用都没有发现问题。

主要修改

  • 补齐 Anthropic 响应中的缓存创建用量字段,修复 cache_creation_input_tokens 等统计缺失的问题。
  • 使用请求内容派生稳定的 prompt_cache_key,提升 prompt cache 命中稳定性。
  • 加强 session affinity 和 previous response 续链处理,减少缓存续链场景下的上下文丢失或错误复用。
  • 支持 hosted WebSearch 工具转换:
    • OpenAI web_search_preview -> Codex web_search
    • Anthropic hosted web search -> Codex web_search
    • Gemini googleSearch -> Codex web_search
    • Claude Code WebSearch -> Codex hosted web_search
  • 保留小写自定义 web_search function tool 的语义,避免误判为 hosted web search。
  • 增加缓存统计、稳定会话 key、隐式续链和 WebSearch 工具转换相关单测。

验证情况

我已经在自己的分支上连续测试了几天,重点验证了:

  • 缓存统计可以正常上报。
  • prompt cache 使用正常。
  • Claude Code WebSearch 可以正常转换和调用。
  • hosted web search 不会影响普通 function tool。
  • previous response / session affinity 相关续链行为没有发现异常。

自动化测试

已通过:

npx vitest run tests/unit/cache-reporting.test.ts tests/unit/stable-conversation-key.test.ts tests/unit/auth/session-affinity.test.ts tests/unit/proxy/codex-api-headers.test.ts tests/unit/proxy/codex-sse.test.ts tests/unit/routes/responses-premature-close.test.ts tests/unit/routes/shared/anthropic-session-id.test.ts tests/unit/routes/shared/proxy-handler-implicit-resume.test.ts tests/unit/routes/upstream-auth-bypass.test.ts tests/unit/translation/anthropic-to-codex.test.ts tests/unit/translation/tool-format.test.ts tests/unit/types/codex-events.test.ts

结果:

12 个测试文件通过
185 个测试通过

也已通过:

npx tsc --noEmit
npm run build

修复 Claude / Anthropic 请求经过 Codex proxy 时的缓存统计问题,并补齐 hosted WebSearch 工具到 Codex web_search 的转换。

- 补齐 Anthropic 响应中的缓存创建用量字段

- 使用请求内容派生稳定的 prompt_cache_key

- 加强 session affinity 和 previous_response 续链稳定性

- 支持 OpenAI、Anthropic、Gemini 与 Claude Code WebSearch 的 hosted web_search 转换

- 增加缓存统计、稳定会话 key、隐式续链和工具转换相关单测
@SsuJojo SsuJojo requested a review from icebear0828 April 17, 2026 02:59
@SsuJojo
Copy link
Copy Markdown
Collaborator

SsuJojo commented Apr 17, 2026

审查结论:目前 不建议直接合并,我这边看到了 2 个需要先处理的问题。

  1. 高优先级:会破坏直连上游的 Anthropic 路由

    • src/routes/messages.ts:132 无条件设置了 codexRequest.useWebSocket = true
    • 但直连分支在 src/routes/messages.ts:142-148 会走 handleDirectRequest(...),对应的 adapter(例如 src/proxy/anthropic-upstream.ts:41-66)只支持把请求翻译成 Anthropic HTTP API,并不支持 Codex 的 previous_response_id / useWebSocket / turnState / prompt_cache_key 语义。
    • 这样会把 Codex 专有传输标记混进 adapter 路径,容易把不该发给 Anthropic 的字段一路带下去,属于明确的回归风险。
    • 建议只在真正走 Codex 后端时启用 useWebSocket / implicit resume 相关逻辑,直连上游路径保持纯协议转换。
  2. 中优先级:Anthropic hosted web search 的判定过宽,可能误伤用户自定义工具

    • src/translation/tool-format.ts:71-76 中,只要工具名是 WebSearch 就会被强制映射为 hosted search。
    • src/translation/tool-format.ts:82-90 / :186-190 中,tool_choice.name === \"WebSearch\" 也会直接转成 { type: \"web_search\" }
    • 这会把合法的同名 function tool 静默改语义。虽然 PR 已经避免误判小写 web_search,但大写 WebSearch 仍然存在冲突面。
    • 建议优先基于显式 hosted-search 类型字段判断;如果只靠名字兜底,最好再加更严格的来源条件,避免覆盖用户自定义 function tool。

其他方面:

  • 缓存统计修复和 implicit resume 的测试覆盖整体不错,tests/unit/cache-reporting.test.tstests/unit/routes/shared/proxy-handler-implicit-resume.test.ts 都覆盖到了关键路径。
  • src/routes/shared/proxy-handler.ts 这次把会话续链做得更完整了,但状态机复杂度明显上升,后续最好再补一组“跨账户 / 跨会话不误续链”的集成测试。

@SsuJojo SsuJojo marked this pull request as draft April 17, 2026 03:20
@SsuJojo SsuJojo added enhancement New feature or request good first issue Good for newcomers labels Apr 17, 2026
@hangox
Copy link
Copy Markdown
Contributor Author

hangox commented Apr 17, 2026

已按 review 意见追加修复,提交:956c706dc4ffb538761cc1807c7bb9afc90cda38

处理内容:

  • src/routes/messages.tsuseWebSocket 现在只在真正走本地 Codex 后端时设置,Anthropic/API-key direct upstream 分支不再携带这个 Codex 专有传输标记。
  • src/translation/tool-format.ts / src/translation/anthropic-to-codex.ts:收紧 WebSearch 按名称映射 hosted web_search 的条件。只有明确启用 Claude Code WebSearch 映射且工具形态像 Claude Code 内置 WebSearch 时才转换;大写自定义 WebSearch function tool 会保留为 function tool。
  • 补了 direct upstream 回归测试,覆盖 direct Anthropic 路由不携带 useWebSocket,也不把自定义 WebSearch 改成 hosted search。

验证:

npx vitest run tests/unit/translation/tool-format.test.ts tests/unit/translation/anthropic-to-codex.test.ts tests/unit/routes/upstream-auth-bypass.test.ts
# 3 个测试文件通过,103 个测试通过

npx tsc --noEmit
# 通过

npm run build
# 通过

另外我也跑了默认测试集:

npm test

结果是业务相关测试通过,但 Electron 打包相关有 3 个既有资源失败,原因是当前 PR worktree 根目录没有 bin/ 目录:

  • packages/electron/__tests__/builder-config.test.ts:要求 root bin/ 存在
  • packages/electron/__tests__/release-pipeline.test.ts:要求 prepare-pack 后 packages/electron/app/bin 存在

我没有在这个修复里补无关打包资源目录,避免把 review 修复范围扩大。

@SsuJojo SsuJojo marked this pull request as ready for review April 17, 2026 11:57
@icebear0828 icebear0828 merged commit 4a2310b into icebear0828:master Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request good first issue Good for newcomers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants