feat: add Claude Fable 5.1 support — pricing (75% cache-read reduction), capability parity with Fable 5 - #112
Merged
Salil Das (sadlilas) merged 5 commits intoSep 2, 2026
Conversation
added 3 commits
September 2, 2026 00:49
Registers claude-fable-5-1 in the provider module:
- _cost.py: add claude-fable-5-1 to _RATES with the new cache read price
($0.25/MTok, 75% reduction from Fable 5's $1.00/MTok). Input/output/
cache-write rates are unchanged ($10/$50/$12.50 per MTok).
- __init__.py: update _get_capabilities docstring to mention Fable 5.1.
The fable branch already handles all fable models generically -- no
version-gating needed since 5.1 has identical capabilities to 5.
- tests/test_cost.py: add pricing tests for claude-fable-5-1 (input,
output, cache_read, cache_write, comparative vs Fable 5).
- tests/test_fable51_support.py: new test file covering family/version
detection, capabilities, _RATES registration, cache read rate,
fallback target, and cost_usd stamping.
Also auto-fixes a pre-existing ruff FURB157 lint issue in _cost.py
(_PER_M = Decimal(1_000_000) instead of Decimal("1_000_000")) and
import-sort in tests/test_cost.py.
Facts sourced from:
- API model identifier: claude-fable-5-1
Source: https://docs.anthropic.com/en/docs/about-claude/models/overview
- Context window: 1M tokens (same as Fable 5)
Source: https://docs.anthropic.com/en/docs/about-claude/models/overview
- Max output tokens: 128K tokens (same as Fable 5)
Source: https://docs.anthropic.com/en/docs/about-claude/models/overview
- Pricing: $10/$50/$0.25/$12.50 per MTok (input/output/cache_read/cache_write)
Source: https://www.anthropic.com/pricing
https://www.anthropic.com/claude-fable-and-mythos-5-1
- No new or changed API request parameters
Source: https://www.anthropic.com/claude-fable-and-mythos-5-1
Live API validation (2026-09-02, resolve worker environment):
Model: claude-fable-5-1
Request: {messages: [{role: user, content: 'Say: fable51ok'}], max_tokens: 20}
Response: text='fable51ok', finish_reason='end_turn',
usage.input_tokens=16, usage.output_tokens=7,
usage.cost_usd=0.00051
These 9 files are working state from the automation that produced this branch (goal_journal.md, goal_verdict.json, goal_condition.md, ...), not part of the Fable 5.1 change. Only 4 files are the real diff. Generated with Amplifier Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
Addresses the CHANGES_REQUESTED findings from the adversarial review.
BLOCKING
- B1: the 1M-context model list is enumerated by explicit version in three
places; the PR had updated only one. Add Fable 5.1 to the other two --
__init__.py:980 (comment) and README.md:275 (user-facing). The code
already sets supports_1m=True for it, so both were simply stale.
- B2: _cost.py's "cache_read ~= 10 % of input_per_m" invariant held for
19 of 20 rate rows; claude-fable-5-1 is the first exception at 2.5 %
(Anthropic cut Fable 5.1 cache reads 75 %). Note it inline. Also add a
pointer on the Fable 5 "exactly 2x Opus 4.8" comment so it is not
over-generalised to the fable family. test_fable5_exact_2x_opus48 is
correct for Fable 5 itself and is left untouched.
- B3: test_fable51_fallback_target_is_opus had no discriminating power --
_fallback_target_for_model branches only on _detect_family, so the
family-level assertion also held for "claude-fable-banana". Assert the
concrete target ("claude-opus-5"), which catches a regression in the
_STATIC_FALLBACK_MODELS backstop. Verified by mutation: pointing the
opus rung at claude-opus-4-8 passes the old assert, fails the new one.
NON-BLOCKING
- N1: replace 16 hand-rolled field comparisons with whole-object equality.
ModelCapabilities has 21 fields; the list silently omitted 5. The test is
kept -- the sibling mythos branch IS version-gated, so a future fable
version gate is a real regression this guards -- with that rationale
moved into the docstring.
- N2: a local named `expected` held a dimensionless RATIO (0.25) that
collided with the expected DOLLAR value ($0.25). Renamed.
- N3: revert two unrelated ride-along style edits back to origin/main.
They were attributed to ruff FURB157/I001, but this repo has no
[tool.ruff] config, ruff is not a dev dependency, CI runs only
`uv run pytest -q`, and neither rule is in ruff's default set.
Out of scope, deliberately untouched: the claude-sonnet-5 durable-vs-intro
rate question (pre-existing, filed separately) and Mythos 5.1.
Verified: uv run pytest -q -> 770 passed (baseline unchanged).
Generated with Amplifier
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for Claude Fable 5.1 (
claude-fable-5-1), announced September 2026. Fable 5.1 is generally available; its Mythos 5.1 counterpart is trusted-access only and is deliberately out of scope here (see Not In Scope).Fable 5.1 is the same capability shape as Fable 5 — the change is almost entirely pricing. Anthropic's headline for 5.1 is a cost reduction delivered specifically through cache reads, which is the one rate that moves.
Key changes:
_RATESentry forclaude-fable-5-1: $10.00 / $50.00 input/output, cache read $0.25/MTok — a 75% reduction from Fable 5's $1.00, cache write $12.50/MTok (unchanged)_detect_family("claude-fable-5-1")already returns"fable"and the fable capability branch is version-agnostic, so 5.1 inherits the full Fable 5 profile automatically__init__.pyto name Fable 5.1 alongside Fable 5What's New in Fable 5.1 (API-Level)
Pricing — the only substantive change. Anthropic states Fable 5.1 "will cost an estimated 25% less than Fable 5 for typical workloads… because we're reducing our pricing on cache reads," and up to ~45% for highly agentic work. Input, output, and cache-write rates are unchanged from Fable 5;
cache_read_per_mdrops $1.00 → $0.25.No new or changed request parameters. Confirmed against the announcement and the model docs. Effort tiers (
low/medium/high/xhigh/max) already exist in this module and are unchanged — the announcement's note that Fable 5.1 defaults to High effort in Claude Code and Medium elsewhere is a client default, not a provider-level API change.No dated snapshot ID published. The docs list only the alias
claude-fable-5-1. If a dated snapshot appears later it will need a separate_RATESentry, as with previous models.Capability Profile for
claude-fable-5-1Identical to
claude-fable-5— asserted as whole-object equality (assert caps51 == caps5) intest_fable51_capabilities_match_fable5, covering all 21ModelCapabilitiesfields.Implementation Details
1. Pricing (
_cost.py)claude-fable-5-1added to_RATES, with the source URLs and the cache-read delta recorded inline as a comment.2. Capabilities (
__init__.py)No functional change needed.
_detect_familyreturns"fable",_detect_versionreturns(5, 1), and the fable branch of_get_capabilitiesis version-agnostic. Only the docstring changed, to name Fable 5.1 explicitly. This is worth a reviewer's eye: the tests assert the inheritance holds rather than assuming it.3. Tests
tests/test_fable51_support.py(8) — family detection, version detection, capability matrix, capability parity with Fable 5,_RATESregistration, cache-read rate, fallback target,cost_usdstampingtests/test_cost.py(+7) — input, output, cache-read, cache-write costs; cache read cheaper than Fable 5; not fast-mode eligible; input/output identical to Fable 5Verification
Live API call against the real model, executed in the Resolve worker (not mocked):
Cost arithmetic checks out end-to-end:
16 × $10/MTok + 7 × $50/MTok = $0.00016 + $0.00035 = $0.00051. This confirms the identifier resolves, the model responds, and the new_RATESentry is actually wired into cost stamping.Suite:
uv run pytest --tb=short→770 passed. No new lint errors versusmain(the two pre-existing ruff findings in the touched files are unchanged — see reviewer note 1).Research Sources
claude-fable-5-1Not In Scope
models.list()returns no Mythos models at all. No Mythos identifiers added, tested, or referenced. (Not citing fix: descope Mythos-5, add refusal-fallback-to-opus (follow-up to #58) #67 as precedent — that PR did descope Mythos 5, butmainhas since re-added Mythos across capability detection, the fallback ladder, and the README, so the precedent no longer holds. The reason here is simply no access.)Reviewer notes — two things to look at
Reverted — this repo has no_PER_Mand an import blank line were changed as ruff auto-fixes.[tool.ruff]config, ruff isn't a dev dependency, and CI runs onlypytest, so neither rule is actually enforced here. Both lines are byte-identical tomainagain.This PR carried 9Resolved — stripped in.ai/*scratch files from the automation that produced it.chore: drop .ai/ pipeline scratch from the PR. The diff is now 5 files:__init__.py,_cost.py,README.md, and the two test files. The pipeline-side cause is fixed in amplifier-resolver-dot-graph#142 so it stops recurring.Provenance
Authored by an automated Amplifier Resolve
goalrun (instancee2f0540e3ae2). The verification above is the run's own captured output, reproduced here rather than summarized. The pricing figures were taken from Anthropic's published pages at the time of the run and should be spot-checked by a reviewer before merge.Review round 1 — findings applied (
4d68b1a)An adversarial review against the five-check framework (Necessity · Layer fit · Pattern · Correctness · Calibration) returned
CHANGES_REQUESTED. All six findings are fixed:__init__.py:980andREADME.md:275_cost.py:40statescache_read ≈ 10 % of input_per_m— 19 of 20 rows obey it; this PR added the first exception (2.5%) without amending ittest_fable51_fallback_target_is_opuscouldn't fail for a Fable-5.1 reason —claude-fable-bananaalso returnsclaude-opus-5ModelCapabilitieshas 21assert caps51 == caps5— 21 fields, 15 lines shorter, mutation-verified against all 5 previously-blind fieldsexpectedheld a ratio that coincidentally equalled the expected dollar valueratio_of_fable5mainSuite still
770 passed.Filed separately — not fixed here
Verification surfaced a pre-existing discrepancy on an untouched row:
_cost.py:65-77encodesclaude-sonnet-5at$3/$15, treating the published$2/$10as an introductory discount expiring 2026-08-31. That date has passed and the published price is still$2/$10, which would mean the repo's default model over-reports cost by 50%. Entirely outside this diff and deliberately not bolted on — it needs its own verification and its own change.Review round 2 — five-check rubric (branch tip
4d68b1a)Protocol followed: diff read to orient; all 5 changed files read in full; callers, tests, and related surfaces read; five checks applied; sibling-model sweep performed.
Five checks
1. Necessity — The
claude-fable-5-1entry in_RATESis required: without itcompute_cost("claude-fable-5-1", ...)returnsNone, silently breaking cost tracking for any user of Fable 5.1. The capability detection works automatically via_detect_familyreturning"fable"— no new capability branch needed. The implementation is minimal and correct. PASS2. Layer fit — Change is in
amplifier_module_provider_anthropic, the Anthropic provider module. Model pricing and capability registration belong here. PASS3. Pattern —
_RATESentry follows the exact same 4-key pattern as all other models (input_per_m,output_per_m,cache_read_per_m,cache_write_per_m). Comment style matches. Tests follow the same pattern as existing model tests. PASS4. Correctness — Pricing verified directly against
https://www.anthropic.com/pricing(2026-09-02): Input $10/MTok, Output $50/MTok, Cache Read $0.25/MTok, Cache Write $12.50/MTok — all match_cost.py:166-171. Version detection:_detect_version("claude-fable-5-1", "fable")returns(5, 1)via thefable-(\d+)-(\d{1,2})(?:-|$)pattern; the 2-digit minor guard prevents a hypothetical dated snapshotclaude-fable-5-20260901from being mis-parsed as(5, 20). Capabilities:_get_capabilitiesfable branch is version-agnostic;caps51 == caps5confirmed. Fallback:_fallback_target_for_model("claude-fable-5-1") == "claude-opus-5"confirmed. PASS5. Calibration — Sibling-model sweep: every surface where
claude-fable-5appears was checked for whetherclaude-fable-5-1also needed to appear. Surfaces checked:_RATES— ✓ present (_cost.py:166)__init__.pycomment at line 980 — ✓ updated (Fable 5/5.1)__init__.pydocstring at line 1662 — ✓ updated (Fable 5 / Fable 5.1)README.md:276— ✓ updated (Fable 5/5.1)_FAST_ELIGIBLE_MODELS— ✓ NOT added (Fable has no speed mode; test guards this)_FALLBACK_NEXT_FAMILY— ✓ NOT added (family-level map; fable->opus covers all fable models)_STATIC_FALLBACK_MODELS— ✓ NOT added (values are targets, not sources; fable never appears as a value)_INERT_CONFIG_KEY_MESSAGES— ✓ no model-specific entriesdocs/,scripts/— ✓ no fable referencesNo missing surface found. PASS
Mutation verification
Cache-read rate guard: setting
cache_read_per_mtoDecimal("0.50")causedtest_fable51_cache_read_rate,test_fable51_cache_read_cost, andtest_fable51_cache_read_cheaper_than_fable5to fail as expected. Restored.Capability parity guard: adding a version gate (
max_output_tokens=64000 if (major, minor) == (5, 1) else 128000) causedtest_fable51_capabilities_match_fable5andtest_fable51_capabilities_correctto fail as expected. Restored.Suite
No regressions. Count at or above pre-work baseline (770 passed before this PR; 770 passed now, with 15 new tests added by this PR).
No blocking findings
All five checks pass. No new findings.
VERDICT: PASS