feat: add Claude Fable 5 and sync Anthropic models from the first-party Models API#733
feat: add Claude Fable 5 and sync Anthropic models from the first-party Models API#733tombeckenham wants to merge 4 commits into
Conversation
…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
📝 WalkthroughWalkthroughThis 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. ChangesClaude Fable 5 Model Support & Anthropic First-Party Sync Pipeline
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
View your CI Pipeline Execution ↗ for commit 2e15251
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-anthropic
@tanstack/ai-client
@tanstack/ai-code-mode
@tanstack/ai-code-mode-skills
@tanstack/ai-devtools-core
@tanstack/ai-elevenlabs
@tanstack/ai-event-client
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-groq
@tanstack/ai-isolate-cloudflare
@tanstack/ai-isolate-node
@tanstack/ai-isolate-quickjs
@tanstack/ai-mcp
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-utils
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/openai-base
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
…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>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
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 winChange detection is too narrow for the files this job now writes.
At Line 40, the gate only checks
packages/, but this workflow also updatesscripts/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 | 🟡 MinorAdd
CLAUDE_FABLE_5toANTHROPIC_COMBINED_TOOLS_AND_SCHEMA_MODELS
claude-fable-5supports structured outputs viaoutput_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 legacystructuredOutputfinalization 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 winSort
newModelsbefore 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 winUse
import typefor type-only imports.The
ANTHROPIC_MODELSimport 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 useimport typeinstead 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (16)
.changeset/fable-model-support.md.github/workflows/sync-models.ymldocs/adapters/anthropic.mddocs/advanced/multimodal-content.mddocs/tools/provider-tools.mdpackage.jsonpackages/ai-anthropic/package.jsonpackages/ai-anthropic/src/model-meta.tspackages/ai-anthropic/tests/model-meta.test.tspackages/ai-openrouter/src/model-meta.tsscripts/.sync-models-last-runscripts/anthropic.models.jsonscripts/fetch-anthropic-models.tsscripts/openrouter.models.jsonscripts/sync-anthropic-models.tsscripts/sync-provider-models.ts
| 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 | ||
| > |
There was a problem hiding this comment.
🧩 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:
- 1: https://platform.claude.com/docs/en/about-claude/models/overview
- 2: https://platform.claude.com/docs/en/build-with-claude/extended-thinking
- 3: https://platform.claude.com/docs/en/build-with-claude/adaptive-thinking
- 4: https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-fable-5
🏁 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" || trueRepository: 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
doneRepository: 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 220Repository: 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 260Repository: 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
doneRepository: 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 || trueRepository: TanStack/ai
Length of output: 644
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n "adaptive_thinking\s*:" packages/ai-anthropic/src/model-meta.tsRepository: 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.
| const response = await fetch(url, { | ||
| headers: { | ||
| 'x-api-key': apiKey, | ||
| 'anthropic-version': '2023-06-01', | ||
| }, | ||
| }) |
There was a problem hiding this comment.
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.
🎯 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-5on the Anthropic adapter andanthropic/claude-fable-5on the OpenRouter adapter: model metadata, per-model provider option types, input modality types, and server-tool capability types.ANTHROPIC_MODELShas entries in all three per-model type maps.Anthropic sync from the first-party Models API
scripts/fetch-anthropic-models.tssnapshotsGET /v1/modelstoscripts/anthropic.models.json(committed snapshot is genuine API output, 11 models).scripts/sync-anthropic-models.tsadds new catalog models topackages/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-maintainedPRICINGtable is the source of truth; a new model fails the sync loudly until a row is added.@tanstack/ai-anthropic(OpenRouter's dotted slugs likeclaude-opus-4.8are not valid Anthropic API ids).sync-models.ymlworkflow now runs the Anthropic sync too:pnpm generate:modelschains the Anthropic fetch + sync after the OpenRouter steps. Requires a newANTHROPIC_API_KEYrepo 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)
claude-opus-4-5is $5/MTok in, $25/MTok out (was wrongly $15/$75); cache-read (cached) prices added for all models that publish them.claude-opus-4.8/claude-opus-4.8-fastrenamed to the real API idsclaude-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.claude-fable-5,claude-opus-4-7-fast,claude-opus-4-8, andclaude-opus-4-8-fastwere missing fromAnthropicChatModelToolCapabilitiesByName, so the typed API rejected every server tool on those models. Fixed, and the sync script now maintains that map.@anthropic-ai/sdkbumped to ^0.104.0 (itsModelunion includesclaude-fable-5andclaude-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
pnpm run test:pr.🚀 Release Impact
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Documentation