Skip to content

feat: add Claude Fable 5 and sync Anthropic models from the first-party Models API#733

Open
tombeckenham wants to merge 4 commits into
TanStack:mainfrom
tombeckenham:claude/fable-model-support-qoigw1
Open

feat: add Claude Fable 5 and sync Anthropic models from the first-party Models API#733
tombeckenham wants to merge 4 commits into
TanStack:mainfrom
tombeckenham:claude/fable-model-support-qoigw1

Conversation

@tombeckenham

@tombeckenham tombeckenham commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🎯 Changes

Adds Anthropic's Claude Fable 5 model, moves Anthropic model syncing onto the first-party Models API, and fixes incorrect Anthropic model metadata uncovered along the way.

New model: Claude Fable 5

  • claude-fable-5 on the Anthropic adapter and anthropic/claude-fable-5 on the OpenRouter adapter: model metadata, per-model provider option types, input modality types, and server-tool capability types.
  • Type-level tests cover provider options, map membership, modalities (positive and negative), and a new drift-guard asserting every id in ANTHROPIC_MODELS has entries in all three per-model type maps.

Anthropic sync from the first-party Models API

  • scripts/fetch-anthropic-models.ts snapshots GET /v1/models to scripts/anthropic.models.json (committed snapshot is genuine API output, 11 models).
  • scripts/sync-anthropic-models.ts adds new catalog models to packages/ai-anthropic/src/model-meta.ts — constants, ANTHROPIC_MODELS, and all three type maps — and writes a changeset. Pricing isn't exposed by the API, so a hand-maintained PRICING table is the source of truth; a new model fails the sync loudly until a row is added.
  • The OpenRouter-based sync no longer manages @tanstack/ai-anthropic (OpenRouter's dotted slugs like claude-opus-4.8 are not valid Anthropic API ids).
  • The nightly sync-models.yml workflow now runs the Anthropic sync too: pnpm generate:models chains the Anthropic fetch + sync after the OpenRouter steps. Requires a new ANTHROPIC_API_KEY repo secret before merge — without it the nightly job fails (intentionally loud, but it also blocks the OpenRouter half).

Metadata corrections (verified against the live Models API and pricing docs)

  • Pricing: claude-opus-4-5 is $5/MTok in, $25/MTok out (was wrongly $15/$75); cache-read (cached) prices added for all models that publish them.
  • Invalid ids: claude-opus-4.8 / claude-opus-4.8-fast renamed to the real API ids claude-opus-4-8 / claude-opus-4-8-fast (the dotted ids 404 against the Anthropic API; three docs pages fixed too). Note: this changes a published type-map key, but the dotted id never worked at runtime.
  • Limits: Opus 4.6, Sonnet 4.5, and Sonnet 4 have 1M context; Sonnet 4.6 supports 128K output; Opus 4.5 supports 64K output; Opus 4.1 caps at 32K output.
  • Tool capabilities: claude-fable-5, claude-opus-4-7-fast, claude-opus-4-8, and claude-opus-4-8-fast were missing from AnthropicChatModelToolCapabilitiesByName, so the typed API rejected every server tool on those models. Fixed, and the sync script now maintains that map.
  • Dependency: @anthropic-ai/sdk bumped to ^0.104.0 (its Model union includes claude-fable-5 and claude-opus-4-8).

No E2E changes: the E2E matrix is provider-granular with pinned model ids, and this change has no runtime behavior — model metadata is consumed as types; type tests run under test:lib/test:types.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for Claude Fable 5 model in Anthropic and OpenRouter adapters.
  • Bug Fixes

    • Corrected model ID naming conventions for Opus variants (dotted to hyphenated format).
    • Updated pricing data, context windows, and output token limits for Claude models.
  • Documentation

    • Updated model ID examples to reflect new naming conventions.

claude added 2 commits June 9, 2026 21:40
…adapters

Adds claude-fable-5 to scripts/openrouter.models.json and regenerates the
model lists via the codegen pipeline (regenerate:models +
sync-provider-models), registering the model in both adapters' model
metadata, provider option types, and input modality types.

https://claude.ai/code/session_01GFGB3ZPVG4tMpYnUYUVpPK
…f OpenRouter

Adds scripts/fetch-anthropic-models.ts (snapshots GET /v1/models to
scripts/anthropic.models.json) and scripts/sync-anthropic-models.ts
(inserts missing models into packages/ai-anthropic/src/model-meta.ts).

The Models API is authoritative for model IDs, context windows, max
output tokens, and per-model capabilities (adaptive vs extended
thinking, image input) — unlike OpenRouter slugs, which use dotted IDs
that are not valid Anthropic API model IDs. Pricing is not exposed by
the Models API, so it lives in a hand-maintained PRICING table and the
sync fails loudly for new models without an entry.

The 'anthropic/' provider is removed from sync-provider-models.ts so
Anthropic models are no longer added from OpenRouter data. New
package.json scripts: generate:anthropic-models[:fetch],
regenerate:anthropic-models.

Also corrects claude-fable-5 thinking flags (extended_thinking: false,
adaptive_thinking: true) to match what the capability-aware sync
generates.

https://claude.ai/code/session_01GFGB3ZPVG4tMpYnUYUVpPK
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds Claude Fable 5 model support across Anthropic and OpenRouter adapters, corrects Anthropic model metadata from live APIs (pricing, context windows), fixes model ID formatting from dotted to hyphenated notation, and establishes a new sync pipeline that sources Anthropic models from the first-party Models API instead of OpenRouter.

Changes

Claude Fable 5 Model Support & Anthropic First-Party Sync Pipeline

Layer / File(s) Summary
SDK Dependency & Release Notes
packages/ai-anthropic/package.json, .changeset/fable-model-support.md
@anthropic-ai/sdk bumped from ^0.97.1 to ^0.104.0 to include new model IDs. Changeset documents Fable 5 support, metadata corrections, and tool-capability map registrations.
Model ID Format Corrections & Documentation
docs/adapters/anthropic.md, docs/advanced/multimodal-content.md, docs/tools/provider-tools.md, packages/ai-anthropic/src/model-meta.ts
Model identifiers corrected from dotted format (claude-opus-4.8) to hyphenated (claude-opus-4-8) across all documentation examples and CLAUDE_OPUS_4_8/CLAUDE_OPUS_4_8_FAST constants.
Anthropic Model Metadata Corrections
packages/ai-anthropic/src/model-meta.ts
Pricing, cached rates, context windows, and max output tokens refreshed for nine Claude model variants (Opus 4.6/4.5/4.1/4, Sonnet 4.6/4.5/4, Haiku 4.5/3.5) using live Models API data.
Anthropic Fable 5 Model Definition & Type Maps
packages/ai-anthropic/src/model-meta.ts
Introduces CLAUDE_FABLE_5 constant with complete supports/pricing metadata; adds claude-fable-5 to ANTHROPIC_MODELS export; wires model into AnthropicChatModelProviderOptionsByName, AnthropicChatModelToolCapabilitiesByName, and AnthropicModelInputModalitiesByName type maps.
Anthropic Test Coverage for Fable 5 & Cross-Map Validation
packages/ai-anthropic/tests/model-meta.test.ts
Adds type assertions for claude-fable-5 extended_thinking support, provider options, and input modalities (text/image/document). Introduces comprehensive cross-map completeness check verifying all models in ANTHROPIC_MODELS have entries in all three related type maps.
OpenRouter Fable 5 Support & Snapshot
packages/ai-openrouter/src/model-meta.ts, scripts/openrouter.models.json
Adds ~anthropic/claude-fable-5 model metadata, wires into OpenRouterModelOptionsByName and OpenRouterModelInputModalitiesByName type maps, and appends to OPENROUTER_CHAT_MODELS export. Includes OpenRouter API snapshot data for the new model.
Anthropic Models Sync Scripts
scripts/fetch-anthropic-models.ts, scripts/anthropic.models.json, scripts/sync-anthropic-models.ts
fetch-anthropic-models.ts paginates Anthropic Models API (requiring ANTHROPIC_API_KEY) and writes catalog to anthropic.models.json. sync-anthropic-models.ts reads snapshot, normalizes/aliases dated model IDs, generates model-meta.ts constants, detects new models, and updates type-map entries via regex-based file insertion with mandatory pricing validation.
Sync Pipeline Orchestration & Configuration
package.json, .github/workflows/sync-models.yml, scripts/sync-provider-models.ts
Adds npm scripts generate:anthropic-models, generate:anthropic-models:fetch, regenerate:anthropic-models and updates generate:models to orchestrate OpenRouter + Anthropic fetches/syncs. Modifies sync-models.yml to set ANTHROPIC_API_KEY and describe provider API syncing. Removes anthropic/ from sync-provider-models.ts PROVIDER_MAP so Claude models are sourced from first-party API, not OpenRouter.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • TanStack/ai#433: Established the foundational model-sync pipeline; this PR extends it with Anthropic first-party API sourcing and excludes anthropic/ from OpenRouter-based sync in sync-provider-models.ts.

Suggested reviewers

  • jherr

🐰 Hopping through the models bright,
Fable Five joins the Anthropic light,
Cached rates and contexts all aligned,
First-party syncs leave OpenRouter behind,
A cleaner pipeline, oh what a sight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% 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 PR title clearly and specifically summarizes the main changes: adding Claude Fable 5 model and syncing Anthropic models from their first-party Models API.
Description check ✅ Passed The PR description comprehensively covers all required template sections with detailed explanations of changes, includes checklists properly completed, and provides clear release impact information.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@nx-cloud

nx-cloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 2e15251

Command Status Duration Result
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 1m 16s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-09 23:31:34 UTC

@pkg-pr-new

pkg-pr-new Bot commented Jun 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@733

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@733

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@733

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@733

@tanstack/ai-code-mode-skills

npm i https://pkg.pr.new/@tanstack/ai-code-mode-skills@733

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@733

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@733

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@733

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@733

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@733

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@733

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@733

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@733

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@733

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@733

@tanstack/ai-mcp

npm i https://pkg.pr.new/@tanstack/ai-mcp@733

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@733

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@733

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@733

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@733

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@733

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@733

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@733

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@733

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@733

@tanstack/ai-utils

npm i https://pkg.pr.new/@tanstack/ai-utils@733

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@733

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@733

@tanstack/openai-base

npm i https://pkg.pr.new/@tanstack/openai-base@733

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@733

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@733

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@733

commit: 2e15251

tombeckenham and others added 2 commits June 10, 2026 09:24
…e Models API

- Fix claude-opus-4-5 pricing ($5/$25, was wrongly $15/$75) in the sync
  script's PRICING table and model-meta.ts; add documented cache-read
  prices to all legacy model entries
- Rename invalid OpenRouter-style ids claude-opus-4.8/-fast to the real
  Anthropic API ids claude-opus-4-8/-fast (dotted ids 404), including
  three docs pages that copied them
- Correct stale context windows / output limits per the Models API
  (Opus 4.6, Sonnet 4.5, Sonnet 4: 1M ctx; Sonnet 4.6: 128K out;
  Opus 4.5: 64K out; Opus 4.1: 32K out)
- Register claude-fable-5, claude-opus-4-7-fast, claude-opus-4-8 and
  claude-opus-4-8-fast in AnthropicChatModelToolCapabilitiesByName, teach
  the sync script to maintain that map, and add a drift-guard type test
- Refresh scripts/anthropic.models.json from a genuine live fetch
  (11 models, was a hand-trimmed 6)
- Bump @anthropic-ai/sdk to ^0.104.0 (Model union includes
  claude-fable-5 and claude-opus-4-8)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…orkflow

pnpm generate:models now chains the Anthropic fetch + sync after the
OpenRouter sync, so the nightly sync-models workflow keeps
@tanstack/ai-anthropic current too. The workflow passes
ANTHROPIC_API_KEY (new repo secret required) to the sync step and
commits the refreshed scripts/anthropic.models.json snapshot alongside
package changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​anthropic-ai/​sdk@​0.104.0100100100100100

View full report

@tombeckenham tombeckenham marked this pull request as ready for review June 9, 2026 23:33
@tombeckenham tombeckenham requested a review from a team as a code owner June 9, 2026 23:33

@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: 2

Caution

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

⚠️ Outside diff range comments (2)
.github/workflows/sync-models.yml (1)

40-44: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Change detection is too narrow for the files this job now writes.

At Line 40, the gate only checks packages/, but this workflow also updates scripts/anthropic.models.json, scripts/openrouter.models.json, scripts/.sync-models-last-run, and .changeset/. If only those change, commit/PR creation is skipped.

🤖 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 @.github/workflows/sync-models.yml around lines 40 - 44, The git-change gate
currently checks only the command "git diff --quiet -- packages/" so the job
will miss changes made to scripts/anthropic.models.json,
scripts/openrouter.models.json, scripts/.sync-models-last-run, and .changeset/;
update the condition that writes "changed=true/false" to include those paths
(e.g., extend the git diff check to include scripts/, .changeset/, and the
specific model files) or switch to a broader check (e.g., any changes outside
the excluded set) so changes to scripts/ and .changeset/ cause the job to run
and create the commit/PR; locate the existing git diff check string "git diff
--quiet -- packages/" in the workflow and modify it accordingly.
packages/ai-anthropic/src/model-meta.ts (1)

794-803: ⚠️ Potential issue | 🟡 Minor

Add CLAUDE_FABLE_5 to ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS

claude-fable-5 supports structured outputs via output_config.format, and it can be used together with tool calls; without being in this Set, the adapter won’t opt into the native combined tools+schema streaming path and will fall back to the legacy structuredOutput finalization flow instead.

Proposed diff
 export const ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS = new Set<string>([
   CLAUDE_OPUS_4_5.id,
   CLAUDE_OPUS_4_6.id,
   CLAUDE_OPUS_4_6_FAST.id,
   CLAUDE_OPUS_4_7.id,
   CLAUDE_OPUS_4_7_FAST.id,
   CLAUDE_SONNET_4_5.id,
   CLAUDE_SONNET_4_6.id,
   CLAUDE_HAIKU_4_5.id,
+  CLAUDE_FABLE_5.id,
 ])
🤖 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 `@packages/ai-anthropic/src/model-meta.ts` around lines 794 - 803, Add
CLAUDE_FABLE_5.id to the ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS Set so the
adapter opts into the native combined tools+schema streaming path; locate the
Set declaration named ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS and append
CLAUDE_FABLE_5.id alongside the other model ids (e.g., CLAUDE_OPUS_4_5.id,
CLAUDE_SONNET_4_6.id) to ensure claude-fable-5 uses output_config.format and
combined tools+schema streaming.
🧹 Nitpick comments (2)
scripts/sync-anthropic-models.ts (1)

313-347: ⚡ Quick win

Sort newModels before generation to keep diffs deterministic.

At Line 313+, emitted constants/map entries currently follow map insertion order from the snapshot. Sorting by alias before Line 345 reduces diff churn across runs.

🤖 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 `@scripts/sync-anthropic-models.ts` around lines 313 - 347, The newModels array
is built from byAlias and preserves snapshot insertion order causing
non-deterministic diffs; sort newModels by alias (e.g., using localeCompare on
the alias field) after you finish populating it and before you log/print and
before you generate constants with generateModelConstant and toConstName so
generated map entries and constants are emitted in a stable, deterministic
order; ensure the sort happens prior to the check/newModels.length logging and
the constants = newModels.map(...) call.
packages/ai-anthropic/tests/model-meta.test.ts (1)

2-2: ⚡ Quick win

Use import type for type-only imports.

The ANTHROPIC_MODELS import on line 2 is only used in type positions (line 253: typeof ANTHROPIC_MODELS). Per the project's TypeScript conventions and ESLint rules, this should use import type instead of a value import.

♻️ Suggested fix
-import { ANTHROPIC_MODELS } from '../src/model-meta'
+import type { ANTHROPIC_MODELS } from '../src/model-meta'
🤖 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 `@packages/ai-anthropic/tests/model-meta.test.ts` at line 2, The import of
ANTHROPIC_MODELS in packages/ai-anthropic/tests/model-meta.test.ts is only used
in type positions (e.g., typeof ANTHROPIC_MODELS) so change the value import to
a type-only import: replace the current import of ANTHROPIC_MODELS with an
import type statement (import type { ANTHROPIC_MODELS } from
'../src/model-meta') so TypeScript/ESLint treat it as a type-only import and
avoid emitting runtime imports.

Source: Linters/SAST tools

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

Inline comments:
In `@packages/ai-anthropic/src/model-meta.ts`:
- Around line 722-760: CLAUDE_FABLE_5 is typed with AnthropicThinkingOptions but
the model only supports adaptive/effort controls (extended_thinking: false);
remove AnthropicThinkingOptions from the generic type list for CLAUDE_FABLE_5
and replace it with the specific adaptive/effort options type used by your
codebase (e.g., AnthropicAdaptiveThinkingOptions or AnthropicEffortOptions) so
the provider-options reflect effort/`effort`-style controls instead of the
`thinking: { type: 'enabled', budget_tokens }` shape; update the satisfies
ModelMeta<...> clause for CLAUDE_FABLE_5 accordingly and ensure imports/types
are adjusted to reference the adaptive/effort options symbol.

In `@scripts/fetch-anthropic-models.ts`:
- Around line 39-44: The fetch call in scripts/fetch-anthropic-models.ts (the
const response = await fetch(url, { ... }) line) needs an abort timeout to avoid
hanging; create an AbortController (or use AbortSignal.timeout) and pass its
signal in the fetch options, set a sensible timeout (e.g., 10s) and ensure you
handle the abort by catching the thrown error and logging/propagating it back
from the function that calls fetch; keep the existing headers ('x-api-key' and
'anthropic-version') and ensure any manual timer is cleared on success when
using AbortController.

---

Outside diff comments:
In @.github/workflows/sync-models.yml:
- Around line 40-44: The git-change gate currently checks only the command "git
diff --quiet -- packages/" so the job will miss changes made to
scripts/anthropic.models.json, scripts/openrouter.models.json,
scripts/.sync-models-last-run, and .changeset/; update the condition that writes
"changed=true/false" to include those paths (e.g., extend the git diff check to
include scripts/, .changeset/, and the specific model files) or switch to a
broader check (e.g., any changes outside the excluded set) so changes to
scripts/ and .changeset/ cause the job to run and create the commit/PR; locate
the existing git diff check string "git diff --quiet -- packages/" in the
workflow and modify it accordingly.

In `@packages/ai-anthropic/src/model-meta.ts`:
- Around line 794-803: Add CLAUDE_FABLE_5.id to the
ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS Set so the adapter opts into the
native combined tools+schema streaming path; locate the Set declaration named
ANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS and append CLAUDE_FABLE_5.id
alongside the other model ids (e.g., CLAUDE_OPUS_4_5.id, CLAUDE_SONNET_4_6.id)
to ensure claude-fable-5 uses output_config.format and combined tools+schema
streaming.

---

Nitpick comments:
In `@packages/ai-anthropic/tests/model-meta.test.ts`:
- Line 2: The import of ANTHROPIC_MODELS in
packages/ai-anthropic/tests/model-meta.test.ts is only used in type positions
(e.g., typeof ANTHROPIC_MODELS) so change the value import to a type-only
import: replace the current import of ANTHROPIC_MODELS with an import type
statement (import type { ANTHROPIC_MODELS } from '../src/model-meta') so
TypeScript/ESLint treat it as a type-only import and avoid emitting runtime
imports.

In `@scripts/sync-anthropic-models.ts`:
- Around line 313-347: The newModels array is built from byAlias and preserves
snapshot insertion order causing non-deterministic diffs; sort newModels by
alias (e.g., using localeCompare on the alias field) after you finish populating
it and before you log/print and before you generate constants with
generateModelConstant and toConstName so generated map entries and constants are
emitted in a stable, deterministic order; ensure the sort happens prior to the
check/newModels.length logging and the constants = newModels.map(...) call.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b141ad52-b57a-4284-9625-9895e82ce829

📥 Commits

Reviewing files that changed from the base of the PR and between e8ce0e1 and 2e15251.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • .changeset/fable-model-support.md
  • .github/workflows/sync-models.yml
  • docs/adapters/anthropic.md
  • docs/advanced/multimodal-content.md
  • docs/tools/provider-tools.md
  • package.json
  • packages/ai-anthropic/package.json
  • packages/ai-anthropic/src/model-meta.ts
  • packages/ai-anthropic/tests/model-meta.test.ts
  • packages/ai-openrouter/src/model-meta.ts
  • scripts/.sync-models-last-run
  • scripts/anthropic.models.json
  • scripts/fetch-anthropic-models.ts
  • scripts/openrouter.models.json
  • scripts/sync-anthropic-models.ts
  • scripts/sync-provider-models.ts

Comment on lines +722 to +760
const CLAUDE_FABLE_5 = {
name: 'claude-fable-5',
id: 'claude-fable-5',
context_window: 1_000_000,
max_output_tokens: 128_000,
supports: {
input: ['text', 'image', 'document'],
extended_thinking: false,
adaptive_thinking: true,
priority_tier: true,
tools: [
'web_search',
'web_fetch',
'code_execution',
'computer_use',
'bash',
'text_editor',
'memory',
],
},
pricing: {
input: {
normal: 10,
cached: 1,
},
output: {
normal: 50,
},
},
} as const satisfies ModelMeta<
AnthropicContainerOptions &
AnthropicContextManagementOptions &
AnthropicMCPOptions &
AnthropicServiceTierOptions &
AnthropicStopSequencesOptions &
AnthropicThinkingOptions &
AnthropicToolChoiceOptions &
AnthropicSamplingOptions
>

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

🌐 Web query:

Does Anthropic's Claude Fable 5 model support extended thinking or thinking budget configuration via the thinking parameter?

💡 Result:

Anthropic's Claude Fable 5 model does not support manual extended thinking configuration via the traditional thinking parameter and budget_tokens [1][2][3]. Instead, Claude Fable 5 uses "adaptive thinking," which is permanently enabled and cannot be disabled [1][3]. Because thinking is always active, attempting to use the manual thinking: {type: "enabled", budget_tokens: N} configuration will result in a 400 error [2][3]. Similarly, attempting to disable it with thinking: {type: "disabled"} is not supported and will also trigger an error [2]. In place of a manual token budget, you manage the trade-off between intelligence, latency, and cost on Claude Fable 5 using the effort parameter [4][3]. The effort parameter allows you to guide the model's adaptive thinking process, with options such as high (recommended default), xhigh (for maximum capability), and medium or low (for routine tasks) [4].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/model-meta.ts"

# Show the Fable 5 block with nearby type intersections
sed -n '700,790p' "$FILE" | nl -ba

# Show the Haiku 3.5 and Haiku 3 blocks that were referenced
sed -n '860,940p' "$FILE" | nl -ba

# Search for AnthropicThinkingOptions usage within this file
rg -n "AnthropicThinkingOptions" "$FILE"

Repository: TanStack/ai

Length of output: 98


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/model-meta.ts"

echo "== Fable 5 block (approx 700-790) =="
sed -n '700,790p' "$FILE" | awk '{printf "%5d\t%s\n", NR, $0}'

echo
echo "== Haiku blocks (approx 860-940) =="
sed -n '860,940p' "$FILE" | awk '{printf "%5d\t%s\n", NR, $0}'

echo
echo "== All AnthropicThinkingOptions occurrences =="
rg -n "AnthropicThinkingOptions" "$FILE" || true

Repository: TanStack/ai

Length of output: 7131


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate definition(s) of AnthropicThinkingOptions and what parameters it covers
rg -n "type\s+AnthropicThinkingOptions|interface\s+AnthropicThinkingOptions|export\s+type\s+AnthropicThinkingOptions|export\s+interface\s+AnthropicThinkingOptions" packages/ai-anthropic/src/model-meta.ts packages/ai-anthropic/src -S || true

echo "---- Search for budget_tokens / effort in the repo (ai-anthropic) ----"
rg -n "budget_tokens|effort'\s*:|effort\b" packages/ai-anthropic/src -S || true

echo "---- Show lines around AnthropicThinkingOptions occurrences in model-meta.ts ----"
FILE="packages/ai-anthropic/src/model-meta.ts"
for L in 700 720 740 750 760 820 840 860 900 945 950; do
  # best-effort; only print if within file
  if [ "$(wc -l < "$FILE")" -ge "$L" ]; then
    sed -n "$((L-5)),$((L+10))p" "$FILE" | awk -v start="$L" 'NR==1{printf "=== around %s ===\n", start} {print}'
  fi
done

Repository: TanStack/ai

Length of output: 8295


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/text/text-provider-options.ts"

# Show AnthropicThinkingOptions interface + nearby comments
sed -n '70,230p' "$FILE" | awk '{print}' | nl -ba | sed -n '1,200p'

echo
echo "---- Also show relevant adapter usage for thinking/effort ----"
ADAPTER="packages/ai-anthropic/src/adapters/text.ts"
sed -n '330,520p' "$ADAPTER" | awk '{print}' | nl -ba | head -n 220

Repository: TanStack/ai

Length of output: 98


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/text/text-provider-options.ts"
ADAPTER="packages/ai-anthropic/src/adapters/text.ts"

echo "== AnthropicThinkingOptions + comments (text-provider-options.ts:70-230) =="
awk '{printf "%5d\t%s\n", NR, $0}' <(sed -n '70,230p' "$FILE")

echo
echo "== adapter text.ts: thinking/effort handling (text.ts:330-520) =="
awk '{printf "%5d\t%s\n", NR, $0}' <(sed -n '330,520p' "$ADAPTER") | head -n 260

Repository: TanStack/ai

Length of output: 15363


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/model-meta.ts"
echo "== Search for AnthropicAdaptiveThinkingOptions and AnthropicEffortOptions in model-meta.ts =="
rg -n "AnthropicAdaptiveThinkingOptions|AnthropicEffortOptions" "$FILE" || true

echo
echo "== Search for 'extended_thinking' usage in model-meta.ts =="
rg -n "extended_thinking" "$FILE" || true

echo
echo "== Show imports near top of model-meta.ts (first 80 lines) =="
sed -n '1,120p' "$FILE" | awk '{print NR"\t"$0}'

echo
echo "== Show how Fable 5 typing is declared around type mapping near lines ~900-970 =="
sed -n '900,970p' "$FILE" | awk '{print NR"\t"$0}'

Repository: TanStack/ai

Length of output: 7337


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "validateTextProviderOptions|InternalTextProviderOptions|AnthropicTextProviderOptions" packages/ai-anthropic/src -S

echo "---- extended_thinking / CLAUDE_FABLE_5 usage ----"
rg -n "extended_thinking|CLAUDE_FABLE_5|claude-fable-5" packages/ai-anthropic/src -S

echo "---- show validateTextProviderOptions implementation (if any) ----"
rg -n "function validateTextProviderOptions|const validateTextProviderOptions|validateTextProviderOptions\s*=" packages/ai-anthropic/src -S

# Print candidate file sections around validateTextProviderOptions
FILE_MATCHES=$(rg -l "validateTextProviderOptions" packages/ai-anthropic/src -S || true)
for f in $FILE_MATCHES; do
  echo
  echo "== $f =="
  sed -n '1,240p' "$f" | head -n 240
done

Repository: TanStack/ai

Length of output: 21944


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/text/text-provider-options.ts"
sed -n '220,370p' "$FILE" | awk '{printf "%5d\t%s\n", NR+220, $0}'

Repository: TanStack/ai

Length of output: 4262


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/model-meta.ts"

echo "== ProviderOptions mapping for non-extended models around comments ~860-940 =="
sed -n '850,930p' "$FILE" | awk '{print}' | head -n 240

echo
echo "== ProviderOptions mapping around CLAUDE_FABLE_5 entry (~930-960) =="
sed -n '930,970p' "$FILE" | awk '{print}'

echo
echo "== Check models with extended_thinking:false and what provider options they map to =="
# Print lines mentioning extended_thinking:false and nearby following provider option mapping entries
rg -n "extended_thinking:\s*false" "$FILE"

echo
echo "== Show around extended_thinking:false blocks near first occurrences (~420-520) =="
sed -n '400,520p' "$FILE" | awk '{print}' | head -n 260

echo
echo "== Show around extended_thinking:false blocks near ~450-490 for Haiku/others =="
sed -n '440,510p' "$FILE" | awk '{print}'

Repository: TanStack/ai

Length of output: 9999


🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n "output_config\.effort|output_config.*effort|effort.*output_config" packages/ai-anthropic/src -S || true
rg -n "model.*FABLE|fable" packages/ai-anthropic/src/adapters/text.ts packages/ai-anthropic/src/model-meta.ts -S || true
rg -n "effort'\s*,|effort\W" packages/ai-anthropic/src/adapters/text.ts -S || true

Repository: TanStack/ai

Length of output: 644


🏁 Script executed:

#!/bin/bash
set -euo pipefail
rg -n "adaptive_thinking\s*:" packages/ai-anthropic/src/model-meta.ts

Repository: TanStack/ai

Length of output: 121


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/model-meta.ts"

echo "== Around line ~130-190 =="
sed -n '120,200p' "$FILE" | awk '{print NR "\t" $0}'

echo
echo "== Around line ~710-750 =="
sed -n '710,750p' "$FILE" | awk '{print NR "\t" $0}'

Repository: TanStack/ai

Length of output: 3042


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="packages/ai-anthropic/src/model-meta.ts"

echo "== model-meta.ts: lines 710-770 =="
awk 'NR>=710 && NR<=770 {printf "%5d\t%s\n", NR, $0}' "$FILE"

echo
echo "== model-meta.ts: lines 930-970 =="
awk 'NR>=930 && NR<=970 {printf "%5d\t%s\n", NR, $0}' "$FILE"

Repository: TanStack/ai

Length of output: 3910


Fix AnthropicThinkingOptions typing for CLAUDE_FABLE_5
packages/ai-anthropic/src/model-meta.ts sets CLAUDE_FABLE_5.supports.extended_thinking: false but the model’s provider options still include AnthropicThinkingOptions (lines 722-760, 945-952). Claude Fable 5 only supports “adaptive thinking” via effort and does not accept thinking: { type: 'enabled', budget_tokens } (400). Remove AnthropicThinkingOptions from the Fable 5 provider-options type and type the adaptive/effort controls instead.

🤖 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 `@packages/ai-anthropic/src/model-meta.ts` around lines 722 - 760,
CLAUDE_FABLE_5 is typed with AnthropicThinkingOptions but the model only
supports adaptive/effort controls (extended_thinking: false); remove
AnthropicThinkingOptions from the generic type list for CLAUDE_FABLE_5 and
replace it with the specific adaptive/effort options type used by your codebase
(e.g., AnthropicAdaptiveThinkingOptions or AnthropicEffortOptions) so the
provider-options reflect effort/`effort`-style controls instead of the
`thinking: { type: 'enabled', budget_tokens }` shape; update the satisfies
ModelMeta<...> clause for CLAUDE_FABLE_5 accordingly and ensure imports/types
are adjusted to reference the adaptive/effort options symbol.

Comment on lines +39 to +44
const response = await fetch(url, {
headers: {
'x-api-key': apiKey,
'anthropic-version': '2023-06-01',
},
})

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 | ⚡ Quick win

Add a timeout/abort to the Anthropic API request.

At Line 39, fetch has no timeout, so a stalled connection can hang the sync job indefinitely. Use AbortSignal.timeout(...) (or an AbortController) and fail fast.

🤖 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 `@scripts/fetch-anthropic-models.ts` around lines 39 - 44, The fetch call in
scripts/fetch-anthropic-models.ts (the const response = await fetch(url, { ...
}) line) needs an abort timeout to avoid hanging; create an AbortController (or
use AbortSignal.timeout) and pass its signal in the fetch options, set a
sensible timeout (e.g., 10s) and ensure you handle the abort by catching the
thrown error and logging/propagating it back from the function that calls fetch;
keep the existing headers ('x-api-key' and 'anthropic-version') and ensure any
manual timer is cleared on success when using AbortController.

@tombeckenham tombeckenham requested a review from AlemTuzlak June 10, 2026 03:53
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