Skip to content

max_tokens 被 max_tokens_cap_per_model 填充后与客户端 max_completion_tokens 并存, 触发上游 400 (cannot both be set) #35

Description

@yangcore

问题描述

当客户端只发 max_completion_tokens(不发 max_tokens)时,代理会用 max_tokens_cap_per_model 自动补上 max_tokens 并一起转发给上游。opencode zen 的部分后端实例会严格校验,返回:

400 [invalid_request_error] `max_tokens` and `max_completion_tokens` cannot both be set; use `max_completion_tokens`.

由于只有部分后端实例校验(同一请求重放经常成功),表现为偶发失败,很容易被误判为上游抖动。客户端侧(如 ZCode)对 400 不重试,用户会看到硬失败。

环境

  • opencode2api v0.14.17(darwin/arm64,commit ea1f473)
  • 上游:opencode zen 免费层(Authorization: Bearer public)

复现与证据(本地假上游抓包)

客户端请求:stream=true + tools + thinking/reasoning 参数,仅带 "max_completion_tokens": 32000,无 max_tokens(代理日志 request_plan ... max_tokens=<nil> max_tokens_cap=200000 ...)。

代理实际转发到上游的请求体同时包含:

{"max_tokens": 200000, "max_completion_tokens": 32000, ...}

对照实验(同一客户端请求,仅修改 max_tokens_cap_per_model):

配置 转发给上游的 max_tokens
{"big-pickle": 200000} 200000(被填充)← 冲突来源
{"big-pickle": 0} 不出现
{}(空) 不出现

期望行为

仅当客户端的 max_tokens 与 max_completion_tokens 都未提供时才做填充;客户端已带 max_completion_tokens 时应原样转发(或填充时同步清除冲突参数)。

临时规避

将 max_tokens_cap_per_model 全部设为 0,可关闭填充、避开该问题。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions