fix(chat): 客户端已带 max_completion_tokens 时不再注入 max_tokens(修复 issue #35) - #36
Merged
Merged
Conversation
…et (issue #35) 配置 max_tokens_cap / max_tokens_cap_per_model 时,convertRequest 在客户端 未显式传 max_tokens 时无条件注入 cap。客户端只带 max_completion_tokens 的 请求因此同时携带 max_tokens(=cap) 与 max_completion_tokens 上行;OpenAI 已 废弃 max_tokens 并要求二者互斥,opencode zen 部分后端实例严格校验返回 400 (cannot both be set),其余实例放行,表现为偶发失败(重放常成功)且对 400 不重试的客户端(如 ZCode)硬失败。 改动: - convertRequest 在客户端已使用 max_completion_tokens 时跳过 cap 注入; 判定同时覆盖顶层 typed 字段与 extra_body 携带(SDK extra_body 顶层合并 惯例,复用 extraBodyValue),避免该入口漏判后由 fill-merge 重新凑成 并存对。 - 双字段均未提供时注入 cap 的行为不变;显式 max_tokens 的 clamp 不变; 客户端显式双带(OpenAI 本身即非法)原样转发,语义不变。 - 回归测试 TestConvertRequest_NoMaxTokensInjectionWhenMaxCompletionTokensSet 按 issue 原始线上 JSON 经 json.Unmarshal 走真实解析路径(仅 max_completion_tokens / 双字段缺省注入照旧 / 仅显式 max_tokens / extra_body 携带)。 验证:make test / go vet / gofmt 全绿;全库审计确认 convertRequest 为唯一 可能共发 max_tokens+max_completion_tokens 的站点,翻译路径经 resolveMaxTokens 收敛单值天然免疫,重试复用已构建字节不重建注入。 Ref: /docs CONFIGURATION.md 与 API.md 同步互斥说明。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题(issue #35)
配置
max_tokens_cap/max_tokens_cap_per_model时,chat 直通路径convertRequest(internal/app/chat.go)在客户端未显式传max_tokens时无条件注入 cap。客户端只带max_completion_tokens的请求因此同时携带两个字段上行:{"max_tokens": 200000, "max_completion_tokens": 32000, ...}OpenAI 已废弃
max_tokens并要求与max_completion_tokens互斥;opencode zen 的部分后端实例严格校验并直接拒绝:由于只有部分实例校验,同一请求重放经常成功 → 表现为偶发失败;对 400 不重试的客户端(如 ZCode)硬失败。
根因审计(全库写点梳理)
max_tokens+max_completion_tokens的站点就是convertRequest:extra_body携带 mct 时 typed 字段为 nil,注入分支漏判,随后 fill-merge 把 mct 放回 body,照常凑成并存对。resolveMaxTokens折叠为单值(fresh map),天然免疫;Claude→Chat / Responses→Chat 只写单键。max_output_tokens。max_tokens的[128, cap]clamp 不变。修复
convertRequest的 cap 注入分支增加守卫:客户端已使用max_completion_tokens(顶层 typed 字段 或extra_body携带,复用extraBodyValue)时跳过max_tokens注入。双字段均未提供时注入 cap 的行为不变。测试
TestConvertRequest_NoMaxTokensInjectionWhenMaxCompletionTokensSet(internal/app/chat_bridge_test.go),按 issue 原始线上 JSON 经json.Unmarshal走真实解析路径,覆盖四组:仅max_completion_tokens(不注入、原样转发)/ 双字段缺省(cap 注入照旧)/ 仅显式max_tokens/extra_body携带 mct。max_tokens_cap_test.go四条注入/clamp 套件、protocol_regression_test.go、claude_bridge_test.go显式双带 pin 等均保持绿色)。验证
make test全绿、go vet ./...与gofmt干净。{"big-pickle": 200000}+ 仅 mct=32000 的客户端请求,修复后上行 body 不再含max_tokens。文档
docs/CONFIGURATION.md:cap 注入语义补充例外条款;docs/API.mdChat 支持字段列表补max_completion_tokens;CHANGELOG.mdv0.14.17 (unreleased) 新增条目。备注(不在本 PR 范围)
max_output_tokens时不剥离客户端私带的 chat 风格键(不同键空间,zen chat 型后端的 400 签名不可达),如后续上游收紧校验可另行处理。Closes #35