Skip to content

feat: add claude-opus-4-6 - #2863

Merged
Calcium-Ion merged 5 commits into
QuantumNous:mainfrom
prnake:feat/claude-opus-4-6
Feb 6, 2026
Merged

feat: add claude-opus-4-6#2863
Calcium-Ion merged 5 commits into
QuantumNous:mainfrom
prnake:feat/claude-opus-4-6

Conversation

@prnake

@prnake prnake commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

Add:

  • claude-opus-4-6
  • claude-opus-4-6-max

Based on https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking:

thinking.type: "enabled" and budget_tokens are deprecated on Opus 4.6 and will be removed in a future model release. Use thinking.type: "adaptive" with the effort parameter instead.

Summary by CodeRabbit

  • New Features

    • Added support for Claude Opus 4-6 and its variants across channels, including cross-region availability.
    • Introduced adaptive-thinking behavior for Opus 4-6 models with configurable effort levels and output_config passthrough.
  • Performance / Tuning

    • Updated caching and model ratio defaults to include Opus 4-6 variants.
  • Behavior

    • Extended recognition of effort-level suffixes (e.g., "-max") for model selection.

@coderabbitai

coderabbitai Bot commented Feb 6, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds Claude Opus 4-6 model variants across AWS, Vertex, and Claude channels, adds an OutputConfig passthrough to request DTOs, extends effort-suffix detection for adaptive thinking, and registers cache/model ratio entries for the new variants.

Changes

Cohort / File(s) Summary
AWS Channel
relay/channel/aws/constants.go, relay/channel/aws/dto.go
Map claude-opus-4-6anthropic.claude-opus-4-6-v1 and allow cross-region usage; add OutputConfig json.RawMessage to AwsClaudeRequest.
Claude Channel
relay/channel/claude/constants.go, relay/channel/claude/relay-claude.go
Register five claude-opus-4-6 variants in ModelList; add adaptive-thinking branch that detects effort suffixes for claude-opus-4-6, sets adaptive thinking fields, OutputConfig, TopP=0, Temperature=1.0.
Vertex Channel
relay/channel/vertex/adaptor.go, relay/channel/vertex/dto.go
Map claude-opus-4-6 in claudeModelMap; add OutputConfig to VertexAIClaudeRequest and propagate it in copyRequest.
Core Handler
relay/claude_handler.go
Detect effort suffix for claude-opus-4-6, switch to base model, enable adaptive thinking, populate OutputConfig, set TopP/Temperature, and update upstream model name.
Ratios / Caching
setting/ratio_setting/cache_ratio.go, setting/ratio_setting/model_ratio.go
Add cache and create-cache ratios and model ratios for claude-opus-4-6 variants (entries for base and efforts).
Reasoning Suffixes
setting/reasoning/suffix.go
Add "-max" to EffortSuffixes, enabling recognition of the max effort suffix.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Relay as Relay (claude channel)
  participant Handler as ClaudeHandler
  participant Upstream as Upstream (AWS/Vertex)

  Client->>Relay: Send request (model, maybe effort-suffix, optional output_config)
  Relay->>Handler: RequestOpenAI2ClaudeMessage (includes model & OutputConfig)
  Handler->>Handler: TrimEffortSuffix -> detect effortLevel?
  alt effortLevel and model starts with "claude-opus-4-6"
    Handler->>Upstream: Set base model, enable adaptive thinking, set OutputConfig, TopP=0, Temp=1.0
  else ThinkingAdapterEnabled & model ends "-thinking"
    Handler->>Upstream: Preserve thinking settings / adjust TopP/Temp
  end
  Upstream-->>Handler: Upstream response
  Handler-->>Relay: Normalized response
  Relay-->>Client: Return response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • seefs001
  • Calcium-Ion

Poem

🐰 Soft hops and clever hops, an opus bright and new,
I trim a suffix, set the thought, and pass the output through,
Across AWS and Vertex lanes the models now align,
Cache hums low, ratios glow, adaptive thinking fine,
Hooray — the rabbit cheers for Claude's expanded crew!

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add claude-opus-4-6' clearly and concisely summarizes the main change—adding support for the new Claude Opus 4-6 model family across multiple files and components.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
relay/channel/claude/relay-claude.go (1)

145-174: ⚠️ Potential issue | 🟡 Minor

ReasoningEffort / Reasoning blocks can silently revert adaptive thinking to deprecated "enabled" mode.

If a request targets claude-opus-4-6-max (handled at lines 145–153, setting Type: "adaptive"), but also carries ReasoningEffort or Reasoning, lines 176–210 will overwrite claudeRequest.Thinking with Type: "enabled" and a fixed BudgetTokens. On Opus 4.6, type: "enabled" with budget_tokens is still accepted but deprecated, so this would silently downgrade the request.

Consider guarding lines 176–210 to skip when adaptive thinking is already configured, e.g.:

if claudeRequest.Thinking == nil || claudeRequest.Thinking.Type != "adaptive" {
    // existing ReasoningEffort / Reasoning logic
}

Also applies to: 176-194

🤖 Fix all issues with AI agents
In `@relay/channel/aws/constants.go`:
- Line 19: The map entry for the key "claude-opus-4-6" in
relay/channel/aws/constants.go uses a malformed Bedrock model ID
("anthropic.claude-opus-4-6-v1") missing the snapshot date and the ":0" suffix;
update the value to the full Bedrock ID format
anthropic.claude-opus-4-6-<YYYYMMDD>-v1:0 (replace <YYYYMMDD> with the correct
Claude Opus 4.6 snapshot date) so it matches the pattern used by other entries
(e.g., anthropic.claude-opus-4-1-20250805-v1:0).

In `@relay/claude_handler.go`:
- Around line 54-61: The adaptive-thinking branch that trims the effort suffix
(when reasoning.TrimEffortSuffix returns ok and strings.HasPrefix(request.Model,
"claude-opus-4-6")) fails to reset request.TopP and request.Temperature, which
can propagate non-default values and cause Claude API errors; update that branch
in claude_handler.go (the block that sets request.Model, request.Thinking,
request.OutputConfig and info.UpstreamModelName) to explicitly set request.TopP
= 0 and request.Temperature = 1.0 alongside the existing changes so adaptive
requests use the expected defaults.

In `@setting/reasoning/suffix.go`:
- Line 9: The three callers that invoke TrimEffortSuffix need the same
model-prefix guard used in the Claude handlers: before calling TrimEffortSuffix,
add a check like strings.HasPrefix(model, "claude-opus-4-6") (or the appropriate
provider-specific prefix) so you only strip the new "-max" suffix for Claude
Opus 4.6; update the call sites referenced (the Vertex adaptor call, the Gemini
relay call, and the Gemini adaptor call) to wrap their TrimEffortSuffix(model)
invocation in a conditional that first verifies the model string prefix, using
the existing pattern from the Claude handlers to avoid stripping "-max" from
unrelated models.
🧹 Nitpick comments (2)
relay/claude_handler.go (1)

60-60: Consider using json.Marshal instead of string interpolation for JSON construction.

While effortLevel is currently constrained to the predefined suffix list (safe values), building JSON via fmt.Sprintf is fragile if the suffix set ever expands to include characters requiring escaping.

♻️ Safer alternative
-		request.OutputConfig = json.RawMessage(fmt.Sprintf(`{"effort":"%s"}`, effortLevel))
+		effortConfig, _ := json.Marshal(map[string]string{"effort": effortLevel})
+		request.OutputConfig = json.RawMessage(effortConfig)
relay/channel/claude/relay-claude.go (1)

145-153: Duplicated adaptive-thinking logic across two files.

The adaptive-thinking block is nearly identical in relay/claude_handler.go (lines 54–61) and here. Different request types make direct extraction non-trivial, but consider a small shared helper (e.g., returning the resolved model name, effort level, and a boolean) to keep the condition and model-prefix check in one place, reducing the risk of the two paths drifting apart (as already evidenced by the missing TopP/Temperature bug in claude_handler.go).

"claude-sonnet-4-5-20250929": "anthropic.claude-sonnet-4-5-20250929-v1:0",
"claude-haiku-4-5-20251001": "anthropic.claude-haiku-4-5-20251001-v1:0",
"claude-opus-4-5-20251101": "anthropic.claude-opus-4-5-20251101-v1:0",
"claude-opus-4-6": "anthropic.claude-opus-4-6-v1",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

AWS Bedrock claude-opus-4-6 model ID format anthropic

💡 Result:

AWS Bedrock Anthropic Claude model IDs use this pattern:

  • Base model ID: anthropic.claude-opus-<major>-<minor>-<YYYYMMDD>-v1:0 (e.g., anthropic.claude-opus-4-1-20250805-v1:0, anthropic.claude-opus-4-5-20251101-v1:0) [2]
  • Cross‑region inference profile prefixes (when available): global. / us. / eu. / jp. / apac. + the base model ID (as shown in Anthropic’s Bedrock table) [2]

For Claude Opus 4.6, AWS announced it became available in Bedrock on Feb 5, 2026, but the exact Bedrock model ID string (including the <YYYYMMDD> snapshot) isn’t shown in the public tables I found yet [1][2]. The reliable way to get the exact ID in your region is to list models from Bedrock:

aws bedrock list-foundation-models --by-provider anthropic --query "modelSummaries[*].modelId" --region <your-region>

AWS Bedrock model ID is malformed — missing both snapshot date and version suffix.

According to AWS Bedrock documentation, Anthropic Claude model IDs follow the pattern anthropic.claude-opus-<major>-<minor>-<YYYYMMDD>-v1:0. The entry "anthropic.claude-opus-4-6-v1" is missing both the snapshot date (<YYYYMMDD>) and the :0 version suffix. All other Claude models in this map include these components (e.g., anthropic.claude-opus-4-1-20250805-v1:0). The malformed ID will fail API calls to AWS Bedrock. Update to the correct format with the appropriate snapshot date for Claude Opus 4.6.

🤖 Prompt for AI Agents
In `@relay/channel/aws/constants.go` at line 19, The map entry for the key
"claude-opus-4-6" in relay/channel/aws/constants.go uses a malformed Bedrock
model ID ("anthropic.claude-opus-4-6-v1") missing the snapshot date and the ":0"
suffix; update the value to the full Bedrock ID format
anthropic.claude-opus-4-6-<YYYYMMDD>-v1:0 (replace <YYYYMMDD> with the correct
Claude Opus 4.6 snapshot date) so it matches the pattern used by other entries
(e.g., anthropic.claude-opus-4-1-20250805-v1:0).

Comment thread relay/claude_handler.go
Comment on lines +54 to +61
if baseModel, effortLevel, ok := reasoning.TrimEffortSuffix(request.Model); ok && effortLevel != "" &&
strings.HasPrefix(request.Model, "claude-opus-4-6") {
request.Model = baseModel
request.Thinking = &dto.Thinking{
Type: "adaptive",
}
request.OutputConfig = json.RawMessage(fmt.Sprintf(`{"effort":"%s"}`, effortLevel))
info.UpstreamModelName = request.Model

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Bug: Missing TopP and Temperature reset for adaptive thinking.

The parallel code in relay/channel/claude/relay-claude.go (lines 152–153) resets TopP = 0 and Temperature = 1.0 for the adaptive thinking branch, matching the existing -thinking branch in this file (lines 77–78). This branch omits those resets, which can cause Claude API errors if the incoming request carries non-default values.

🐛 Proposed fix
 	if baseModel, effortLevel, ok := reasoning.TrimEffortSuffix(request.Model); ok && effortLevel != "" &&
 		strings.HasPrefix(request.Model, "claude-opus-4-6") {
 		request.Model = baseModel
 		request.Thinking = &dto.Thinking{
 			Type: "adaptive",
 		}
 		request.OutputConfig = json.RawMessage(fmt.Sprintf(`{"effort":"%s"}`, effortLevel))
+		request.TopP = 0
+		request.Temperature = common.GetPointer[float64](1.0)
 		info.UpstreamModelName = request.Model
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if baseModel, effortLevel, ok := reasoning.TrimEffortSuffix(request.Model); ok && effortLevel != "" &&
strings.HasPrefix(request.Model, "claude-opus-4-6") {
request.Model = baseModel
request.Thinking = &dto.Thinking{
Type: "adaptive",
}
request.OutputConfig = json.RawMessage(fmt.Sprintf(`{"effort":"%s"}`, effortLevel))
info.UpstreamModelName = request.Model
if baseModel, effortLevel, ok := reasoning.TrimEffortSuffix(request.Model); ok && effortLevel != "" &&
strings.HasPrefix(request.Model, "claude-opus-4-6") {
request.Model = baseModel
request.Thinking = &dto.Thinking{
Type: "adaptive",
}
request.OutputConfig = json.RawMessage(fmt.Sprintf(`{"effort":"%s"}`, effortLevel))
request.TopP = 0
request.Temperature = common.GetPointer[float64](1.0)
info.UpstreamModelName = request.Model
🤖 Prompt for AI Agents
In `@relay/claude_handler.go` around lines 54 - 61, The adaptive-thinking branch
that trims the effort suffix (when reasoning.TrimEffortSuffix returns ok and
strings.HasPrefix(request.Model, "claude-opus-4-6")) fails to reset request.TopP
and request.Temperature, which can propagate non-default values and cause Claude
API errors; update that branch in claude_handler.go (the block that sets
request.Model, request.Thinking, request.OutputConfig and
info.UpstreamModelName) to explicitly set request.TopP = 0 and
request.Temperature = 1.0 alongside the existing changes so adaptive requests
use the expected defaults.

)

var EffortSuffixes = []string{"-high", "-medium", "-low", "-minimal"}
var EffortSuffixes = []string{"-max", "-high", "-medium", "-low", "-minimal"}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n --type=go 'TrimEffortSuffix' -B 5 -A 5

Repository: QuantumNous/new-api

Length of output: 5151


Add model-prefix guards to three additional callers of TrimEffortSuffix that lack them.

Adding -max to EffortSuffixes is correct for Claude Opus 4.6, which has four effort levels. However, both Claude handler call sites properly guard with strings.HasPrefix(model, "claude-opus-4-6"), while three other callers do not:

  • relay/channel/vertex/adaptor.go:219 (Vertex)
  • relay/channel/gemini/relay-gemini.go:187 (Gemini relay)
  • relay/channel/gemini/adaptor.go:141 (Gemini adaptor)

These unguarded sites will now strip -max from any model name ending in -max, risking incorrect behavior for other providers (e.g., hypothetical gpt-4o-max in Gemini). Add model-provider checks similar to the Claude guards.

🤖 Prompt for AI Agents
In `@setting/reasoning/suffix.go` at line 9, The three callers that invoke
TrimEffortSuffix need the same model-prefix guard used in the Claude handlers:
before calling TrimEffortSuffix, add a check like strings.HasPrefix(model,
"claude-opus-4-6") (or the appropriate provider-specific prefix) so you only
strip the new "-max" suffix for Claude Opus 4.6; update the call sites
referenced (the Vertex adaptor call, the Gemini relay call, and the Gemini
adaptor call) to wrap their TrimEffortSuffix(model) invocation in a conditional
that first verifies the model string prefix, using the existing pattern from the
Claude handlers to avoid stripping "-max" from unrelated models.

@Calcium-Ion
Calcium-Ion merged commit f3d6e99 into QuantumNous:main Feb 6, 2026
1 check passed
ennnnny pushed a commit to ennnnny/new-api that referenced this pull request Mar 17, 2026
@coderabbitai coderabbitai Bot mentioned this pull request May 29, 2026
11 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants