Skip to content

fix(codex): upgrade CPA and support response interrupts - #838

Merged
tbphp merged 4 commits into
mainfrom
tbphp/fix-codex-websocket-interrupt
Oct 9, 2026
Merged

tbphp merged 4 commits into
mainfrom
tbphp/fix-codex-websocket-interrupt

Conversation

@tbphp

@tbphp tbphp commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

关联 Issue / Related Issue

Related upstream fix: router-for-me/CLIProxyAPI#6456

变更内容 / Change Content

  • Bug 修复 / Bug fix
  • 新功能 / New feature
  • 其他改动 / Other changes

Answering an asynchronous Codex question during generation can send response.interrupt. GPT-Load previously queued and rejected that control frame, then closed sessions that ended with an incomplete response.

  • Upgrade CPA from v8.0.8 to v8.0.22 and use its InterruptExecutionSession API to forward interrupts immediately on the bound upstream connection.
  • Validate response ownership and current authorization, preserve control-frame fields, and allow same-connection continuation after an explicitly requested interruption. Control frames do not create inference attempts or increment RPM counters.
  • Log a matching, acknowledged interruption as a successful interaction only after the control write and turn both finish without errors. Clear failure fields while preserving the original terminal event, usage, pricing, and RPM accounting. Failed writes, executor errors, and other incomplete responses keep their existing outcomes.
  • Remove the Antigravity streaming reasoning-token compensation now provided by CPA, preserving existing token totals. Correct a malformed JSON test fixture exposed by stricter upstream parsing.
  • Bound interrupt writes to 30 seconds or the earlier caller/turn deadline. Cancellation or timeout closes the upstream connection even after generation has completed, releasing blocked writes.
  • Update model-catalog failure tests for CPA 8.0.22 warning text while retaining assertions that failed refreshes preserve the existing catalog.
  • Add regression coverage for in-flight interruption, continuation, invalid and stale controls, canceled calls, request accounting, and blocked interrupt writes after turn completion. This includes zero-output response.done continuation, exact output-token preservation, and rejecting incomplete responses without a requested interrupt.

Compatibility: existing configuration and database schemas are unchanged. The pinned Codex 0.159.2 identity and model template are retained; the template matches the official tag byte for byte.

Known limitation: CPA v8.0.22 closes the upstream WebSocket when a requested interruption returns response.incomplete with no output and output_tokens: 0. This remains an upstream issue. The PR uses the official CPA release; the corresponding continuation-success regression is deferred until an official CPA fix is available.

Validation using the official CPA v8.0.22 dependency:

  • make check
  • go test -count=20 -run '^TestWebsocketInterrupt' ./internal/gateway covers success/failure classification, terminal-before-write completion, continuation, usage, pricing, and RPM.
  • In third_party/cpaembedded: go mod tidy -diff, go vet ./..., and go test -count=1 ./...
  • Gateway-to-CPA mock-upstream diagnostics: supported interruption and rejection scenarios passed 20/20; the known zero-output response.incomplete failure remains reproducible and is not reclassified as success. A live Codex client/backend smoke test of this final revision has not been rerun.

自查清单 / Checklist

  • 我已运行 make check,或在说明中写明无法运行的原因和未验证范围。 / I ran make check, or documented why it could not run and what remains unverified.
  • 本 PR 范围聚焦,未包含无关改动。 / This PR is focused and contains no unrelated changes.
  • 我已更新必要的公开文档或发布说明。 / I updated any required public documentation or release notes.
  • 我已确认提交、日志和测试数据不包含敏感信息。 / I confirmed that commits, logs, and fixtures contain no sensitive data.
  • 如适用,我已说明兼容性或数据迁移影响。 / Where applicable, I documented compatibility or data-migration impact.

Copilot AI balanced review requested due to automatic review settings October 9, 2026 08:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

📝 Walkthrough

Walkthrough

升级 CPA 依赖版本,并新增 Codex WebSocket 的 response.interrupt 校验与转发。被中断的活动响应可作为不完整响应返回,客户端可在同一连接上继续请求。新增测试覆盖中断校验、转发和续接。另调整 Antigravity 的 OpenAI 格式用量处理,移除对 completion tokens 的额外累加。


Priority: ➖ Normal

Severity of issue fixed: Medium

Merge Risk: 🔵 Low · up to 6097f

An upstream write stall could leave an interrupted connection unresponsive. Add a write deadline before merging, or accept this bounded connection-level risk.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 13 files. (2 skipped: 2… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed 直接关联的 #6456 已关闭,仅提供历史背景,不产生本 PR 必须完成的编码要求。当前改动实现了同一问题域的中断转发、连接继续、授权校验和请求计数测试;未发现需要按已关闭 Issue 追加完成的编码内容。
Out of Scope Changes check Passed 改动集中在 CPA 升级、Codex response.interrupt 转发、同连接继续、响应状态处理、请求计数和回归测试。Antigravity 用量修正及测试夹具修正直接支持 CPA 升级后的行为。根据变更摘要,未发现与该修复无关且会影响正确性、安全性、可靠性或性能的改动。
Description check Passed PR 描述完整说明了变更目标、实现范围、兼容性、已知限制和验证结果。虽然未使用 Closes # 格式,但已提供相关上游 Issue,且未勾选公开文档项已明确表示当前未更新文档;整体信息充分。
Title check Passed 标题准确概括了主要变更:升级 CPA 并支持 Codex response interrupts。标题简洁、明确,且与变更内容一致。

Full details: Docstring Coverage

Explanation

Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 13 files. (2 skipped: 2 unsupported.)



  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.

🟡 Other comments (1)
internal/gateway/websocket.go (1)

379-386: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

为中断写入设置实际的写超时。

读取循环会同步等待 handleInterrupt。CodexWebsocketsExecutor.InterruptExecutionSession 只在写入前检查一次 ctx.Err(),随后直接调用 conn.WriteMessage 或 NextWriter。这条写入路径没有设置 SetWriteDeadline,因此上游写入阻塞时,读取循环可能无法继续读取后续帧。仅在调用处包装 context.WithTimeout 不能中断已经开始的 WebSocket 写入。

请在 CPA 的中断写入路径设置有限的 WebSocket 写期限,并在写入结束后清除或恢复期限。若该逻辑属于外部 CPA 依赖,请升级到包含此修复的版本,或应用等效的本地补丁。


ℹ️ Review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: QUIET
  • Plan: Advanced
  • Run ID: ad574c8b-b7d5-40d8-a628-ad480955e662
📥 Commits

Reviewing files that changed from the base of the PR and between 935aff9 and 6097f1b.

⛔ Files ignored due to path filters (2)
  • go.sum is excluded by !**/*.sum
  • third_party/cpaembedded/go.sum is excluded by !**/*.sum
📒 Files selected for processing (16)
  • go.mod
  • internal/catalog/codex_client_models.go
  • internal/execution/cpa/websocket.go
  • internal/execution/cpa/websocket_test.go
  • internal/execution/websocket.go
  • internal/gateway/execution_forward.go
  • internal/gateway/websocket.go
  • internal/gateway/websocket_interrupt.go
  • internal/gateway/websocket_interrupt_test.go
  • internal/gateway/websocket_turn.go
  • internal/subscription/providers/codex/websocket.go
  • third_party/cpaembedded/embedded/antigravity_executor.go
  • third_party/cpaembedded/embedded/antigravity_test.go
  • third_party/cpaembedded/embedded/codex_websocket.go
  • third_party/cpaembedded/embedded/codex_websocket_interrupt_test.go
  • third_party/cpaembedded/go.mod
💤 Files with no reviewable changes (1)
  • third_party/cpaembedded/embedded/antigravity_executor.go

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.

@tbphp

tbphp commented Oct 9, 2026

Copy link
Copy Markdown
Owner Author

Addressed the interrupt-write finding in 13079f0. Interrupt writes now have an independent deadline capped at 30 seconds and the earlier caller/turn deadline. Cancellation or timeout closes the underlying connection to release the blocked SDK write, even after generation finishes. Regression tests cover cancellation, both deadline sources, and same-connection continuation.

The model-catalog CI failure was also fixed by matching CPA 8.0.22's updated warning text; the unchanged-catalog assertions remain in place.

Regarding the docstring coverage warning: The repository does not require 80% docstring coverage; no bulk comment changes are needed for this fix.

Validation passed: make check; go mod tidy -diff, go vet ./..., and go test -count=1 ./... in third_party/cpaembedded.

@tbphp tbphp self-assigned this Oct 9, 2026
@tbphp tbphp added enhancement New feature or request bug Something isn't working labels Oct 9, 2026
@tbphp tbphp added this to the v2.0.0 milestone Oct 9, 2026
@tbphp
tbphp merged commit c71c34d into main Oct 9, 2026
12 checks passed
@tbphp
tbphp deleted the tbphp/fix-codex-websocket-interrupt branch October 9, 2026 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(codex): 支持 response.interrupt,修复插队消息报错

2 participants