Skip to content

Support Claude Opus 4.7 via adaptive thinking provider options#445

Open
sidneyswift wants to merge 2 commits intotestfrom
feature/anthropic-adaptive-thinking-opus-4-7
Open

Support Claude Opus 4.7 via adaptive thinking provider options#445
sidneyswift wants to merge 2 commits intotestfrom
feature/anthropic-adaptive-thinking-opus-4-7

Conversation

@sidneyswift
Copy link
Copy Markdown
Contributor

@sidneyswift sidneyswift commented Apr 16, 2026

Summary

Fixes the "thinking.type.enabled is not supported for this model" error users hit when selecting Claude Opus 4.7. Opus 4.7 rejects the old thinking config (`type: "enabled"` + `budgetTokens`) with a 400 error and requires the new `type: "adaptive"` shape. Adaptive is also preferred (but not required) on Opus 4.6 and Sonnet 4.6, while older Anthropic models (Sonnet 4.5, Opus 4.5, Haiku 3.x) only support the legacy shape.

Why this wasn't a one-line flip

A simple `enabled` → `adaptive` swap would break every Anthropic model below 4.6 that's still in the model list. The fix needs to be model-aware.

Changes

  • New helper: `getAnthropicProviderOptions(modelId)` returns the correct `AnthropicProviderOptions` shape per model. Allowlist-driven for explicitness. Legacy config is the safe default for unknown or non-Anthropic IDs.
  • SDK upgrade: `@ai-sdk/anthropic` `3.0.13` → `^3.0.70`. Required because the installed SDK's Zod schema only accepted `"enabled" | "disabled"` — `adaptive` was added in 3.0.37.
  • Wired into `getGeneralAgent.ts` replacing the hardcoded anthropic providerOptions.

Model compatibility matrix (from Anthropic docs)

Model `type: "enabled"` `type: "adaptive"`
Opus 4.7 ❌ 400 error ✅ only supported mode
Opus 4.6 ⚠️ deprecated ✅ preferred
Sonnet 4.6 ⚠️ deprecated ✅ preferred
Sonnet 4.5, Opus 4.5, Haiku 3.x, etc. ✅ required ❌ not supported

Due diligence — why this upgrade is low-risk

  • Zero breaking changes across the `3.0.14 → 3.0.70` span (reviewed every changelog entry — all patch-level additions, no majors)
  • SDK stays on v6 track — no `ai` package upgrade needed (4.0.0-beta.x is for the v7 pre-release and is not yet fully published anyway)
  • Single caller of `@ai-sdk/anthropic` in the codebase (`getGeneralAgent.ts`)
  • `AnthropicProviderOptions` type export preserved (aliased to `AnthropicLanguageModelOptions` after 3.0.42's type normalization; verified)

Verification

  • ✅ All 1906 existing tests pass post-upgrade
  • ✅ 9 new unit tests for `getAnthropicProviderOptions` (3 adaptive models + 2 legacy models + 2 defensive + 2 branch shape checks)
  • ✅ 3 new integration tests on `getGeneralAgent` proving wiring per model
  • ✅ `pnpm lint:check` clean

Test plan

  • Merge to test and deploy
  • In chat app, select "Claude Opus 4.7" and send a message → should stream a response (no 400 error)
  • Select "Claude Sonnet 4.6" → should stream successfully (adaptive branch)
  • Select "Claude Sonnet 4.5" → should stream successfully (legacy branch, backwards compat)
  • Select "GPT-5.4 Mini" → should stream successfully (default model, no Anthropic options apply)

Follow-ups (not in this PR)

  • Consider exposing `effort` as a user-configurable setting (currently hardcoded to `medium`)
  • On Opus 4.7, `thinking.display` defaults to `"omitted"` upstream; we explicitly set `"summarized"` to preserve the reasoning UI. If thinking blocks don't render correctly in chat, that's the knob to investigate.

Made with Cursor


Summary by cubic

Support Claude Opus 4.7 with model-aware Anthropic thinking options. Enables adaptive mode where required and keeps legacy settings for older models to prevent 400s.

  • New Features

    • Added getAnthropicProviderOptions(modelId) to return the right AnthropicProviderOptions per model.
      • Adaptive for anthropic/claude-opus-4.7, anthropic/claude-opus-4.6, anthropic/claude-sonnet-4.6 with display: "summarized" and effort: "medium".
      • Legacy enabled with budgetTokens: 12000 for older, unknown, and non-Anthropic models.
    • Wired into getGeneralAgent to set providerOptions.anthropic.
    • Added tests for both adaptive and legacy branches.
  • Dependencies

    • Bump @ai-sdk/anthropic from ^3.0.13 to ^3.0.70 to support type: "adaptive".

Written for commit 69bcc4a. Summary will update on new commits.

Summary by CodeRabbit

  • Improvements
    • Configured adaptive thinking for newer Claude models (Opus 4.7, 4.6, and Sonnet 4.6) with summarized output and medium effort level.
    • Maintained legacy thinking configuration for other models.

arpitgupta1214 and others added 2 commits April 15, 2026 04:41
…435) (#440)

* chore(lint): scope eslint rules by file type + residual code fixes

Splits eslint.config.js into three file-scoped rule blocks so strict JSDoc
requirements apply only where they belong:

- all `**/*.ts`: keeps import/first, prettier, member-ordering, and tightens
  `no-unused-vars` to `argsIgnorePattern: "^_"` (was `"^_$"` which only
  matched bare `_`)
- `app/api/**/*.ts`: retains the full jsdoc ruleset per CLAUDE.md's "all
  API routes require JSDoc" mandate
- test files (`**/*.test.ts`, `**/__tests__/**`): disables
  `no-explicit-any` and `jsdoc/require-jsdoc` — tests legitimately need
  loose typing and don't ship as docs

Residual code-level fixes the new config surfaces:
- `lib/credits/getCreditUsage.ts`: replace `(usage as any)` with a typed
  Partial record narrowing
- `lib/content/templates/types.ts`, `lib/trigger/fetchTriggerRuns.ts`:
  move `[key: string]: unknown` index signature before named fields
  (member-ordering)
- `lib/artists/createArtistInDb.ts`, `lib/workspaces/createWorkspaceInDb.ts`:
  drop unused `error` binding from catch
- misc test files: remove unused imports/vars, fix import/first ordering



* docs(api): meaningful JSDoc for 19 route handlers

Writes endpoint-specific JSDoc against the strict rules scoped to
`app/api/**`. Each handler now documents the HTTP verb + path, the
request body/query shape (referencing the `validate*Body` / `validate*Query`
schema file where applicable), the success response shape, and the
relevant non-200 status codes. No placeholder filler — every description
conveys something the signature does not.

Files:
- accounts/[id], admins/coding/pr, admins/coding/slack,
  admins/content/slack, admins/privy
- chats/[id]/messages/trailing
- coding-agent/callback, coding-agent/github
- connectors
- content (PATCH), content/analyze, content/caption, content/image,
  content/templates/[id], content/transcribe, content/upscale,
  content/video
- songs/analyze/presets
- transcribe



* fix(credits): use typed LanguageModelUsage fields; restore json() assertion in sandbox test

- `getCreditUsage`: drop the hand-rolled Partial-record cast and the v2-compat
  `promptTokens`/`completionTokens` fallback — `LanguageModelUsage` (= V3Usage)
  already types `inputTokens` / `outputTokens` directly, and the real runtime
  caller (`handleChatCredits`) passes this exact type. The compat branch was
  dead against the typed surface.
- `getCreditUsage.test.ts`: update mock usage objects from the legacy
  `promptTokens`/`completionTokens` shape to the SDK V3 shape the function is
  actually typed against.
- `postSandboxesFilesHandler.test.ts`: restore `result.json()` so the 500-path
  still asserts the response is valid JSON (not just status code), matching
  the original test intent.



* docs(api): correct @returns shape for coding-agent github webhook

Cubic review feedback: the JSDoc claimed `{ ok: true }` on 200 but the handler
returns `{ status: <outcome> }` payloads (`update_triggered`, `ignored`, `busy`,
`no_state`, `updating`) and `{ status: "error", error }` on non-200s. Update the
doc to match the actual contract.



---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Opus 4.7 rejects the old thinking.type: "enabled" + budgetTokens shape with
a 400 error and requires thinking.type: "adaptive" + effort. Adaptive mode
is also preferred (but not required) for Opus 4.6 and Sonnet 4.6, while
older Anthropic models (Sonnet 4.5, Opus 4.5, Haiku 3.x) only support the
legacy enabled shape.

Extract a model-aware helper that returns the correct AnthropicProviderOptions
shape for each model instead of hardcoding one config for every Anthropic
model. Legacy config remains the safe default for unknown or non-Anthropic
model IDs.

Upgrade @ai-sdk/anthropic 3.0.13 → 3.0.70 so the SDK schema accepts the
adaptive discriminant and the top-level effort parameter. Verified via
changelog review that 3.0.14 → 3.0.70 contains no breaking changes (all
patch-level additions) and that the ai-v6 track is unaffected.

Verification:
- All 1906 existing tests pass after the SDK bump
- 9 new unit tests for the helper (adaptive / legacy / defensive branches)
- 3 new integration tests on getGeneralAgent verifying wiring per model
- Lint clean

Made-with: Cursor
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
recoup-api Ready Ready Preview Apr 16, 2026 6:27pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9dd5935e-85f3-4cbb-a7d6-3a5ab29e6b6a

📥 Commits

Reviewing files that changed from the base of the PR and between ec0008b and 69bcc4a.

⛔ Files ignored due to path filters (4)
  • lib/agents/generalAgent/__tests__/getAnthropicProviderOptions.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agents/generalAgent/__tests__/getGeneralAgent.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • package.json is excluded by none and included by none
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml and included by none
📒 Files selected for processing (2)
  • lib/agents/generalAgent/getAnthropicProviderOptions.ts
  • lib/agents/generalAgent/getGeneralAgent.ts

📝 Walkthrough

Walkthrough

A new utility function getAnthropicProviderOptions was created to centralize Anthropic provider option configuration based on model IDs, differentiating between adaptive thinking models and others. The general agent initialization was refactored to use this new function instead of inline configuration.

Changes

Cohort / File(s) Summary
Anthropic Provider Options Module
lib/agents/generalAgent/getAnthropicProviderOptions.ts
New module exporting a function that maps model IDs to AnthropicProviderOptions. Returns adaptive thinking config for specified models (claude-opus-4.7, claude-opus-4.6, claude-sonnet-4.6) with type: "adaptive", display: "summarized", and effort: "medium"; falls back to legacy config with type: "enabled" and budgetTokens: 12000 for other models.
General Agent Refactoring
lib/agents/generalAgent/getGeneralAgent.ts
Replaced inline Anthropic thinking configuration with call to getAnthropicProviderOptions(model). Removed direct import of AnthropicProviderOptions from @ai-sdk/anthropic and added import of the new utility function.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • sweetmantech

Poem

🧠 Configuration scattered? Fear not, friends!
A tidy new function makes amends,
Anthropic options now centralized and clean,
The agent reads it all: adaptive between! ✨

🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Solid & Clean Code ✅ Passed Pull request demonstrates excellent adherence to SOLID principles and Clean Code practices with proper SRP isolation, OCP compliance, DRY implementation, and comprehensive test coverage.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/anthropic-adaptive-thinking-opus-4-7

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.

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 6 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Requires human review: This PR modifies core agent logic and includes a production dependency update (@ai-sdk/anthropic 3.0.13 -> 3.0.70) which requires human review for stability.

Architecture diagram
sequenceDiagram
    participant UI as Chat UI
    participant API as Chat API Route
    participant Factory as getGeneralAgent
    participant Helper as getAnthropicProviderOptions
    participant SDK as @ai-sdk/anthropic (v3.0.70)
    participant Anthropic as Anthropic API

    UI->>API: POST /api/chat { model: "anthropic/claude-opus-4.7", messages }
    API->>Factory: getGeneralAgent(body)

    Note over Factory,Helper: NEW: Model-aware provider options selection
    Factory->>Helper: NEW: getAnthropicProviderOptions(modelId)

    alt Model is Opus 4.7, 4.6, or Sonnet 4.6
        Helper-->>Factory: { thinking: { type: "adaptive", display: "summarized" }, effort: "medium" }
    else Model is Sonnet 4.5, Opus 4.5, or Legacy/Unknown
        Helper-->>Factory: { thinking: { type: "enabled", budgetTokens: 12000 } }
    end

    Factory->>Factory: Initialize ToolLoopAgent with providerOptions
    Factory-->>API: Return Agent Instance
    
    API->>SDK: streamText() with providerOptions
    
    rect rgb(240, 240, 240)
        Note right of SDK: CHANGED: SDK v3.0.70 validates "adaptive" schema
        SDK->>Anthropic: Request with selected thinking config
        
        alt Path: Adaptive (Opus 4.7)
            Anthropic-->>SDK: 200 OK + Thinking Blocks
        else Path: Legacy config sent to Opus 4.7
            Note right of Anthropic: Rejects old 'enabled' type for 4.7
            Anthropic-->>SDK: 400 Bad Request
        end
    end

    SDK-->>UI: Stream response to client
Loading

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