feat(responses): 实现响应状态续接路由 - #609
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
📝 WalkthroughWalkthrough本次变更为 OpenAI Responses 增加 Priority: ➖ Normal Merge Risk: 🟡 Moderate · up to Empty continuation IDs may bypass local validation, and the documentation advertises continuation channels beyond the stated support scope. Resolve these contract mismatches before merge. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 3.64% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 55 functions across 35 files. (3 skipped: 3 unsupported.) 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
internal/dialect/request_fields.go-79-80 (1)
79-80: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win拒绝空的
previous_response_id。当客户端发送
{"previous_response_id":""}时,Decode会成功,但PreviousResponseID保持为空。后续代码将空值视为非续接请求,因此跳过响应归属查找并把无效字段转发到上游,而不是在本地拒绝格式非法的 ID。请在保留
null支持的同时拒绝空字符串,并增加该用例的测试。建议修改
- if err := decoder.Decode(&result.PreviousResponseID); err != nil { + var previousResponseID *string + if err := decoder.Decode(&previousResponseID); err != nil { return RequestMetadata{}, fmt.Errorf("previous_response_id must be a string or null") } + if previousResponseID != nil { + if *previousResponseID == "" { + return RequestMetadata{}, fmt.Errorf("previous_response_id must be non-empty") + } + result.PreviousResponseID = *previousResponseID + }
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: QUIET
Plan: Advanced
Run ID: 2b7fcce6-71a6-4baa-b60e-91de4b1d9f6f
📒 Files selected for processing (30)
README.mdREADME_CN.mdREADME_JP.mdinternal/app/runtime_checkpoint.gointernal/app/runtime_checkpoint_test.gointernal/app/scheduling_checkpoint_test.gointernal/container/container.gointernal/control/group_create.gointernal/control/group_settings_test.gointernal/dialect/anthropic.gointernal/dialect/dialect.gointernal/dialect/openai.gointernal/dialect/openai_embeddings.gointernal/dialect/openai_images.gointernal/dialect/openai_responses.gointernal/dialect/openai_responses_test.gointernal/dialect/request_fields.gointernal/dialect/request_fields_test.gointernal/dialect/rerank.gointernal/gateway/execution_forward.gointernal/gateway/forward.gointernal/gateway/handler.gointernal/gateway/reason.gointernal/gateway/reason_test.gointernal/gateway/responses_continuation.gointernal/gateway/responses_continuation_test.gointernal/parameteroverride/response_continuation_test.gointernal/parameteroverride/rules.gointernal/state/response_bindings.gointernal/state/response_bindings_test.go
Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: QUIET
Plan: Advanced
Run ID: c6d4b18d-faa4-4862-855e-bf7eb0d01e79
📒 Files selected for processing (16)
README.mdREADME_CN.mdREADME_JP.mdinternal/dialect/request_execution.gointernal/dialect/request_execution_test.gointernal/execution/bifrost/executor.gointernal/execution/contracts.gointernal/execution/contracts_test.gointernal/execution/validation.gointernal/gateway/execution_forward.gointernal/gateway/forward.gointernal/gateway/handler.gointernal/gateway/responses_continuation.gointernal/gateway/responses_continuation_test.gointernal/scheduler/channel_scheduler_test.gointernal/scheduler/inspect.go
Included review availability: Your plan provides up to 8 included reviews per hour; 5 remain after this review.
|
针对审查汇总中剩余两项建议,保持现有实现:
|
关联 Issue / Related Issue
无关联 Issue。
变更内容 / Change Content
HTTP/SSE Responses 的后续请求原先可能被调度到无法访问上一轮响应的凭据。本次按
AccessKeyID + response_id记录归属,续接仅使用当前路由仍允许的原凭据;例如首轮由 A 生成响应,即使下一次普通轮询应选 B,续接也只能使用 A。previous_response_id。旧覆盖配置仍可加载和查看;应用时允许旧规则删除不存在的字段,仍拒绝删除实际存在的字段(包括 null 和空字符串)或通过 set 注入该字段。兼容性与边界:
upstream_managed存储声明自动接入,当前包括openai、gpt_load、xai、newapi、cliproxyapi、sub2api,不新增渠道开关。中转渠道仅保证回到原下一跳,实际状态可用性由上游决定。无状态、转换以及明确 store:false 的响应不登记新 ID;Codex 订阅的 WebSocket 接入留在后续阶段。conversation、background、保存的 prompt 或其他资源引用混用时继续保留原条件,其他 Responses 资源操作的归属路由不在本次范围。验证:
make check通过。Go 回归覆盖多凭据续接、AccessKey 隔离、亲和互斥、SSE 登记时点、冷却恢复、身份变更、失败不换号、参数覆盖、索引边界和 checkpoint 恢复。六个渠道均通过实际 Bifrost 执行链路连接本地 HTTP 上游,验证连续请求保留原凭据和 previous_response_id,store:false 仍可使用已有绑定且不登记新 ID;混合资源、无状态和转换候选继续受限。这些验证不代表真实上游账号的状态存储保证。未运行本地 race 或前端测试。自查清单 / Checklist
make check,或在说明中写明无法运行的原因和未验证范围。 / I ranmake check, or documented why it could not run and what remains unverified.