Skip to content

feat: implement Claude Sonnet 5 support in Zoo Code#778

Merged
edelauna merged 2 commits into
mainfrom
fix/sonnet-5-introductory-pricing
Jul 1, 2026
Merged

feat: implement Claude Sonnet 5 support in Zoo Code#778
edelauna merged 2 commits into
mainfrom
fix/sonnet-5-introductory-pricing

Conversation

@navedmerchant

@navedmerchant navedmerchant commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Related GitHub Issue

Closes: #777

Description

This PR implements full Claude Sonnet 5 support in Zoo Code across all provider paths, with correct model definitions, adaptive-thinking handling, fetcher overrides, and accurate introductory pricing.

Per Anthropic's published pricing, Sonnet 5 has introductory pricing of $2 / $10 per million input/output tokens in effect through August 31, 2026 (the standard $3 / $15 rates do not take effect until September 1, 2026). The previous definitions used the standard rates, which over-reported costs during the introductory period.

Key implementation details:

  • Model definitions (packages/types/src/providers/): Added claude-sonnet-5 to anthropic.ts, bedrock.ts, and vertex.ts with a native 1M context window (no beta header required), the adaptive-thinking binary toggle (supportsReasoningBudget/supportsReasoningBinary), supportsTemperature: false (sampling params return a 400), and introductory pricing (inputPrice: 2.0, outputPrice: 10.0, cacheWritesPrice: 2.5, cacheReadsPrice: 0.2). Cache prices follow Anthropic's standard multipliers (1.25× base input for 5m cache writes, 0.1× base input for cache reads) applied to the $2 introductory base rate.
  • Provider handling (src/api/providers/): Added sonnet-5 to the Bedrock adaptive-thinking guard so temperature is omitted, and added claude-sonnet-5 to the OpenRouter and Vercel AI Gateway model allow-lists.
  • Fetcher overrides (src/api/providers/fetchers/): Applied Sonnet 5 overrides (maxTokens, reasoning budget, temperature) in the openrouter, requesty, and vercel-ai-gateway fetchers so dynamically-fetched model info matches the static Anthropic definitions.
  • Tests: Added Sonnet 5 coverage across the provider and fetcher test suites.

Reviewers should pay attention to the pricing values in the three provider definition files — these are the introductory rates and will need to be reverted to the standard $3 / $15 rates on September 1, 2026.

Test Procedure

  1. cd packages/types && pnpm run lint — passes (no warnings).
  2. cd packages/types && npx tsc --noEmit — passes with no errors.
  3. cd src && pnpm run check-types — passes with no errors.
  4. cd src && npx vitest run api/providers/__tests__/bedrock.spec.ts api/providers/__tests__/anthropic-vertex.spec.ts — 112/112 tests pass.
  5. Manual verification: configure a provider (Anthropic/Bedrock/Vertex) with claude-sonnet-5, send a request, and confirm the reported token cost reflects the introductory $2/$10 rates rather than the standard $3/$15 rates.

Pre-Submission Checklist

  • Issue Linked: This PR is linked to issue [BUG] Implement Claude Sonnet 5 support in Zoo Code #777.
  • Scope: My changes are focused on the linked issue (Sonnet 5 implementation).
  • Self-Review: I have performed a thorough self-review of my code.
  • Testing: Updated tests have been added to cover the Sonnet 5 model across providers and fetchers.
  • Documentation Impact: No documentation updates required (pricing is sourced from Anthropic's published pricing page).
  • Contribution Guidelines: I have read and agree to the Contributor Guidelines.

Screenshots / Videos

N/A — no UI changes.

Documentation Updates

  • No documentation updates are required.

Additional Notes

The introductory pricing window ends August 31, 2026. On September 1, 2026, the pricing values in anthropic.ts, bedrock.ts, and vertex.ts should be reverted to the standard rates (inputPrice: 3.0, outputPrice: 15.0, cacheWritesPrice: 3.75, cacheReadsPrice: 0.3).

Get in Touch

navedmerchant

Summary by CodeRabbit

  • New Features
    • Added Claude Sonnet 5 model support across major AI providers, including updated provider allowlists and model metadata.
    • Enabled provider-specific prompt caching and capability handling for Sonnet 5.
  • Bug Fixes
    • Ensured Sonnet 5 requests use adaptive reasoning settings when enabled and omit unsupported temperature fields.
    • Updated token/max-output behavior for Sonnet 5 in hybrid reasoning scenarios.
  • Tests
    • Added/extended unit tests covering Sonnet 5 model info, request payload formatting, and provider-specific model parsing.

Add full Claude Sonnet 5 support across all provider paths with correct
model definitions, adaptive-thinking handling, fetcher overrides, and
accurate introductory pricing.

Model definitions (anthropic.ts, bedrock.ts, vertex.ts):
- 1M native context window (no beta header required)
- Adaptive-thinking binary toggle (supportsReasoningBudget/Binary)
- supportsTemperature: false (sampling params return a 400)
- Introductory pricing through Aug 31, 2026:
  inputPrice 2.0, outputPrice 10.0, cacheWrites 2.5, cacheReads 0.2
  (standard $3/$15 rates take effect Sep 1, 2026)

Provider handling:
- Add sonnet-5 to the Bedrock adaptive-thinking guard
- Add claude-sonnet-5 to OpenRouter and Vercel AI Gateway allow-lists
- Apply Sonnet 5 overrides (maxTokens, reasoning budget, temperature)
  in the openrouter, requesty, and vercel-ai-gateway fetchers

Tests:
- Add Sonnet 5 coverage across provider and fetcher test suites

Closes #777
@coderabbitai

coderabbitai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 3051842f-851c-41e1-820b-07a9e51ba6a8

📥 Commits

Reviewing files that changed from the base of the PR and between e4fdf27 and ed7c5d5.

📒 Files selected for processing (2)
  • src/api/providers/__tests__/bedrock.spec.ts
  • src/api/providers/__tests__/vercel-ai-gateway.spec.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/api/providers/tests/vercel-ai-gateway.spec.ts
  • src/api/providers/tests/bedrock.spec.ts

📝 Walkthrough

Walkthrough

Adds Claude Sonnet 5 support across provider model metadata, allowlists, adaptive-thinking handling, fetcher overrides, and unit tests for Anthropic, Bedrock, Vertex, OpenRouter, Requesty, and Vercel AI Gateway.

Changes

Claude Sonnet 5 provider support

Layer / File(s) Summary
Model definitions and allowlists
packages/types/src/providers/anthropic.ts, packages/types/src/providers/bedrock.ts, packages/types/src/providers/vertex.ts, packages/types/src/providers/openrouter.ts, packages/types/src/providers/vercel-ai-gateway.ts
Adds claude-sonnet-5 model entries with pricing and capability flags, and extends provider allowlists plus Bedrock global inference support.
Anthropic direct provider handling
src/api/providers/anthropic.ts, src/api/providers/__tests__/anthropic.spec.ts
Adds claude-sonnet-5 to Anthropic cache-control and prompt-caching branches, with tests for request shape and model metadata.
Bedrock adaptive-thinking guard
src/api/providers/bedrock.ts, src/api/providers/__tests__/bedrock.spec.ts
Extends adaptive-thinking detection for sonnet-5 ids and adds model, request, and global-prefix tests.
Vertex provider tests
src/api/providers/__tests__/anthropic-vertex.spec.ts
Adds model metadata and reasoning-effort tests for claude-sonnet-5.
OpenRouter fetcher override
src/api/providers/fetchers/openrouter.ts, src/api/providers/fetchers/__tests__/openrouter.spec.ts
Adds a Sonnet 5 parsing override and verifies max tokens, reasoning flags, and temperature behavior.
Requesty fetcher override and provider tests
src/api/providers/fetchers/requesty.ts, src/api/providers/fetchers/__tests__/requesty.spec.ts, src/api/providers/__tests__/requesty.spec.ts
Adds a Sonnet 5 parsing override and verifies adaptive-thinking and temperature omission in fetcher and handler tests.
Vercel AI Gateway fetcher override and provider tests
src/api/providers/fetchers/vercel-ai-gateway.ts, src/api/providers/fetchers/__tests__/vercel-ai-gateway.spec.ts, src/api/providers/__tests__/vercel-ai-gateway.spec.ts
Updates the temperature-disabling special case for Sonnet 5 and adds parsing plus request tests.
Shared max-output-tokens test
src/shared/__tests__/api.spec.ts
Adds a getModelMaxOutputTokens test for claude-sonnet-5 under different reasoning-effort settings.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: awaiting-review

Suggested reviewers: taltas, hannesrudolph, edelauna, JamesRobert20

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main change: Claude Sonnet 5 support in Zoo Code.
Description check ✅ Passed The description includes the required issue link, implementation details, test procedure, checklist, and notes.
Linked Issues check ✅ Passed The changes match #777 by adding Sonnet 5 support, pricing, allow-lists, adaptive-thinking handling, fetcher overrides, and tests.
Out of Scope Changes check ✅ Passed No clear out-of-scope changes are evident; the edits stay focused on Claude Sonnet 5 support and related tests.
✨ 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 fix/sonnet-5-introductory-pricing

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.

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@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.

🧹 Nitpick comments (2)
src/api/providers/fetchers/requesty.ts (1)

48-59: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider consolidating per-model override blocks.

The new claude-sonnet-5 block duplicates the exact same override logic as claude-fable-5 immediately above it. As more Anthropic models require this identical supportsReasoningBudget/supportsReasoningBinary/supportsTemperature override, this pattern will keep growing. Consider a small lookup set instead.

♻️ Proposed consolidation
-			if (rawModel.id === "anthropic/claude-fable-5") {
-				modelInfo.supportsReasoningBudget = true
-				modelInfo.supportsReasoningBinary = true
-				modelInfo.supportsTemperature = false
-			}
-
-			if (rawModel.id === "anthropic/claude-sonnet-5") {
-				modelInfo.supportsReasoningBudget = true
-				modelInfo.supportsReasoningBinary = true
-				modelInfo.supportsTemperature = false
-			}
+			if (REASONING_BUDGET_TEMPERATURE_OFF_MODELS.has(rawModel.id)) {
+				modelInfo.supportsReasoningBudget = true
+				modelInfo.supportsReasoningBinary = true
+				modelInfo.supportsTemperature = false
+			}

(with REASONING_BUDGET_TEMPERATURE_OFF_MODELS a module-level Set(["anthropic/claude-fable-5", "anthropic/claude-sonnet-5"]))

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers/fetchers/requesty.ts` around lines 48 - 59, The per-model
override logic in requesty.ts is duplicated for claude-fable-5 and
claude-sonnet-5, so consolidate it into a shared lookup instead of separate if
blocks. Add a module-level set (for example, a reasoning-budget/temperature-off
model set) and update the model override handling around the rawModel.id checks
so both models use the same branch to set supportsReasoningBudget,
supportsReasoningBinary, and supportsTemperature.
src/api/providers/fetchers/vercel-ai-gateway.ts (1)

117-124: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Same duplication pattern as in requesty.ts.

Consider consolidating the claude-fable-5 and claude-sonnet-5 checks into a single set-based lookup to avoid repeating this pattern for future one-off models.

♻️ Proposed consolidation
-	if (id === "anthropic/claude-fable-5") {
-		modelInfo.supportsTemperature = false
-	}
-
-	if (id === "anthropic/claude-sonnet-5") {
-		modelInfo.supportsTemperature = false
-	}
+	if (NO_TEMPERATURE_MODELS.has(id)) {
+		modelInfo.supportsTemperature = false
+	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/api/providers/fetchers/vercel-ai-gateway.ts` around lines 117 - 124, The
`fetchModelInfo` logic in `vercel-ai-gateway.ts` repeats separate `id === ...`
checks for `anthropic/claude-fable-5` and `anthropic/claude-sonnet-5`, matching
the duplication pattern already seen in `requesty.ts`. Consolidate these one-off
model IDs into a single set-based lookup near `modelInfo.supportsTemperature`
handling, then apply the flag once when `id` is in that set so future additions
only need one list update.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/api/providers/fetchers/requesty.ts`:
- Around line 48-59: The per-model override logic in requesty.ts is duplicated
for claude-fable-5 and claude-sonnet-5, so consolidate it into a shared lookup
instead of separate if blocks. Add a module-level set (for example, a
reasoning-budget/temperature-off model set) and update the model override
handling around the rawModel.id checks so both models use the same branch to set
supportsReasoningBudget, supportsReasoningBinary, and supportsTemperature.

In `@src/api/providers/fetchers/vercel-ai-gateway.ts`:
- Around line 117-124: The `fetchModelInfo` logic in `vercel-ai-gateway.ts`
repeats separate `id === ...` checks for `anthropic/claude-fable-5` and
`anthropic/claude-sonnet-5`, matching the duplication pattern already seen in
`requesty.ts`. Consolidate these one-off model IDs into a single set-based
lookup near `modelInfo.supportsTemperature` handling, then apply the flag once
when `id` is in that set so future additions only need one list update.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 658e50f0-b049-4c25-902d-0d7df9a161a3

📥 Commits

Reviewing files that changed from the base of the PR and between 9a2e8d8 and e4fdf27.

📒 Files selected for processing (19)
  • packages/types/src/providers/anthropic.ts
  • packages/types/src/providers/bedrock.ts
  • packages/types/src/providers/openrouter.ts
  • packages/types/src/providers/vercel-ai-gateway.ts
  • packages/types/src/providers/vertex.ts
  • src/api/providers/__tests__/anthropic-vertex.spec.ts
  • src/api/providers/__tests__/anthropic.spec.ts
  • src/api/providers/__tests__/bedrock.spec.ts
  • src/api/providers/__tests__/requesty.spec.ts
  • src/api/providers/__tests__/vercel-ai-gateway.spec.ts
  • src/api/providers/anthropic.ts
  • src/api/providers/bedrock.ts
  • src/api/providers/fetchers/__tests__/openrouter.spec.ts
  • src/api/providers/fetchers/__tests__/requesty.spec.ts
  • src/api/providers/fetchers/__tests__/vercel-ai-gateway.spec.ts
  • src/api/providers/fetchers/openrouter.ts
  • src/api/providers/fetchers/requesty.ts
  • src/api/providers/fetchers/vercel-ai-gateway.ts
  • src/shared/__tests__/api.spec.ts

edelauna
edelauna previously approved these changes Jul 1, 2026

@edelauna edelauna 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.

Looks good - nothing blocking, just a question about vercel, and if we wanted to increase test coverage.


const model = handler.getModel()
expect(model.id).toBe("global.anthropic.claude-sonnet-5")
})

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.

Opus 4.7 and 4.8 each have a createMessage test that asserts inferenceConfig.temperature is absent and additionalModelRequestFields.thinking.type === "adaptive" (lines ~1410–1458). Could we add an equivalent for anthropic.claude-sonnet-5? The isAdaptiveThinkingModel unit test confirms the predicate returns true, but a regression in the handler branch for this specific model wouldn't be caught without an end-to-end request test.


if (id === "anthropic/claude-sonnet-5") {
modelInfo.supportsTemperature = false
}

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.

The requesty and openrouter fetchers both set supportsReasoningBinary: true for claude-sonnet-5 alongside supportsTemperature: false. Does the Vercel AI Gateway support the binary reasoning toggle? If so, should we add modelInfo.supportsReasoningBinary = true here (and in the claude-fable-5 block above at line 118)?

temperature: undefined,
max_completion_tokens: 128000,
}),
)

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.

expect.objectContaining({ temperature: undefined }) passes whether temperature is explicitly undefined or simply absent from the call object — so it won't catch a regression where the handler stops consulting supportsTemperature entirely. Would asserting on the extracted call arg directly be tighter?

Suggested change
)
const call = mockCreate.mock.calls[mockCreate.mock.calls.length - 1][0]
expect(call.model).toBe("anthropic/claude-sonnet-5")
expect(call.temperature).toBeUndefined()
expect(call.max_completion_tokens).toBe(128000)

@github-actions github-actions Bot added the awaiting-review PR changes are ready and waiting for maintainer re-review label Jul 1, 2026
- Add Bedrock createMessage adaptive-thinking test for claude-sonnet-5
  (mirrors Opus 4.7/4.8: asserts thinking.type 'adaptive',
  output_config.effort 'xhigh', and temperature omitted).
- Tighten Vercel AI Gateway Sonnet 5 temperature assertion to extract
  the call arg directly instead of objectContaining({ temperature:
  undefined }), which can't distinguish absent from explicitly undefined.

Refs #778
@github-actions github-actions Bot added awaiting-review PR changes are ready and waiting for maintainer re-review and removed awaiting-review PR changes are ready and waiting for maintainer re-review labels Jul 1, 2026
@edelauna edelauna added this pull request to the merge queue Jul 1, 2026
Merged via the queue into main with commit f845f2a Jul 1, 2026
13 checks passed
@edelauna edelauna deleted the fix/sonnet-5-introductory-pricing branch July 1, 2026 13:03
hacker-b2k pushed a commit to hacker-b2k/Zoo-Code that referenced this pull request Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR changes are ready and waiting for maintainer re-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Implement Claude Sonnet 5 support in Zoo Code

2 participants