Skip to content

[Bug] GPT-5.6 explicit max effort is downgraded to xhigh in Claude → Responses conversion #5367

Description

@xiaodream551-a11y

Self Checks / 自检

  • I have read the FAQ section in README. / 我已阅读 README 中的常见问题。
  • I have searched existing issues, including closed ones. / 我已搜索已有 Issue(含已关闭)。

CC Switch Version / 版本号

3.17.0

Operating System / 操作系统

Linux

Related App / 涉及应用

Claude Code

Steps to Reproduce / 重现步骤

  1. Configure a Claude provider using apiFormat = "openai_responses", with the Claude Fable/Opus role mapped to gpt-5.6-sol.
  2. In Claude Code, select /effort max.
  3. Send a request through the CC Switch local proxy.
  4. Inspect the Claude → OpenAI Responses conversion in resolve_reasoning_effort() and anthropic_to_responses().

CC Switch v3.17.0 currently contains:

return match effort {
    "low" => Some("low"),
    "medium" => Some("medium"),
    "high" => Some("high"),
    "max" => Some("xhigh"),
    _ => None,
};

Source in the v3.17.0 release:

/// Resolve the appropriate OpenAI `reasoning_effort` from an Anthropic request body.
///
/// Priority:
/// 1. Explicit `output_config.effort` — preserves the user's intent directly.
/// `low`/`medium`/`high` map 1:1; `max` maps to `xhigh`
/// (supported by mainstream GPT models). Unknown values are ignored.
/// 2. Fallback: `thinking.type` + `budget_tokens`:
/// - `adaptive` → `xhigh` (adaptive = maximum reasoning effort)
/// - `enabled` with budget → `low` (<4 000) / `medium` (4 000–15 999) / `high` (≥16 000)
/// - `enabled` without budget → `high` (conservative default)
/// - `disabled` / absent → `None`
pub fn resolve_reasoning_effort(body: &Value) -> Option<&'static str> {
// --- Priority 1: explicit output_config.effort ---
if let Some(effort) = body
.pointer("/output_config/effort")
.and_then(|v| v.as_str())
{
return match effort {
"low" => Some("low"),
"medium" => Some("medium"),
"high" => Some("high"),
"max" => Some("xhigh"), // OpenAI xhigh = maximum reasoning effort
_ => None, // unknown value — do not inject
};

anthropic_to_responses() then emits the resolved value as:

{
  "model": "gpt-5.6-sol",
  "reasoning": { "effort": "xhigh" }
}

Therefore an explicit Claude Code request with output_config.effort = "max" is downgraded to OpenAI reasoning.effort = "xhigh".

OpenAI's current GPT-5.6 documentation explicitly lists none, low, medium, high, xhigh, and max, and describes max as distinct from xhigh:

This can be observed without logging request contents: CC Switch request records confirm claude-fable-5 is mapped to gpt-5.6-sol and succeeds, while the conversion code deterministically changes the explicit effort value before forwarding.

Expected Behavior / 期望行为

For models that support OpenAI reasoning.effort = "max" (notably GPT-5.6), preserve an explicit Claude output_config.effort = "max":

{
  "model": "gpt-5.6-sol",
  "reasoning": { "effort": "max" }
}

The mapping should be model- or capability-aware rather than globally changing max to xhigh, because older models/providers may still accept only up to xhigh.

Possible direction:

"max" if supports_max_reasoning_effort(model) => Some("max"),
"max" => Some("xhigh"),

Alternatively, provider/model-level supported effort metadata could drive the mapping.

Suggested tests:

  1. GPT-5.6 Responses: Claude max → OpenAI reasoning.effort = "max".
  2. Older GPT model supporting only through xhigh: Claude maxxhigh compatibility fallback.
  3. Existing low/medium/high behavior remains unchanged.

Actual Behavior / 实际行为

CC Switch globally maps Claude max to OpenAI xhigh, despite GPT-5.6 supporting both as separate effort levels. The user's explicit highest-effort selection is therefore not preserved for gpt-5.6-sol.

Additional Context / 补充信息

Related but distinct issues:

No credentials, prompts, or full request bodies are included in this report.

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