feat: upstream model autodetection + one long-context rule for every family (v4.8.57)#489
Merged
Merged
Conversation
…family (v4.8.57) /v1/models now serves Anthropic's live catalog (TTL-cached, stale-while- revalidate, baked fallback on every failure path) instead of a hardcoded list, and family shortcuts resolve against it — a new model shows up and routes the day it lands, no dario release needed. [1m] long-context variants are generated by ONE rule for every family (everything except haiku) instead of being hand-listed: the listing now carries claude-opus-4-8[1m] / claude-sonnet-4-6[1m] exactly like fable's, and <family>1m aliases derive from <family> + '[1m]' so they can't drift. Behavior change: opus1m now resolves to claude-opus-4-8[1m] (was stale claude-opus-4-7[1m] from before #389 bumped opus to 4-8). New src/model-catalog.ts + test/model-catalog.mjs (59 assertions); full suite 85/85.
Contributor
Compat test: ✅ PASSEDRan Output |
askalf
added a commit
that referenced
this pull request
Jun 10, 2026
RELEASING.md pre-merge checklist item that #489 (and the 4.8.56 release before it) missed. Lockfile-only; no dependency changes, no version bump — does not trigger auto-release.
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.
What
Operator direction (2026-06-10): model availability should be autodetected, and all models should use the same method for context windows.
1. Upstream model autodetection
New
src/model-catalog.ts:GET /v1/modelsnow asksapi.anthropic.com/v1/modelswhat actually exists (authenticated the same way the request path is — OAuth bearer, orx-api-keyinANTHROPIC_UPSTREAM_API_KEYmode), normalizes the listing (claude-only; legacy claude-3-x dropped; CC-style short ids preferred over dated duplicates; deterministic family-rank/version-desc order; unknown future families kept — the next fable-like launch appears on the next refresh with no dario release), and serves it from a stale-while-revalidate TTL cache (1h,DARIO_MODEL_CATALOG_TTL_MS; failed fetches back off 5 min). Every failure path falls back to the baked list — cold start offline, broken auth, upstream 4xx/5xx, garbage listing — so the route always 200s and behaves exactly as before when upstream is unreachable. Prewarmed at startup so the first client call is answered from cache.2. One long-context rule
[1m]handling was hand-sprinkled: the listing carriedclaude-fable-5[1m]but no opus/sonnet variants, and each<family>1malias was a hand-picked pin — already drifted (#389 bumpedopusto 4-8;opus1msilently stayed on 4-7).Now:
longContextEligible()is the single rule: every claude family takes a[1m]variant except haiku (real CC never offers 1M haiku).withLongContextVariants()generates the advertised variants from that rule — the listing now carriesclaude-opus-4-8[1m],claude-sonnet-4-6[1m], etc., exactly like fable's.<family>1maliases derive fromresolve(<family>) + '[1m]'— the pair can never disagree again.Wire mechanics unchanged (and already uniform):
[1m]stays a client-side label — base id +context-1m-2025-08-07on the wire, existing billing-rejection auto-retry untouched.opus1mnow resolves toclaude-opus-4-8[1m](was the staleclaude-opus-4-7[1m]). Want the old target? Sendclaude-opus-4-7[1m]explicitly.Tests
test/model-catalog.mjs— 59 assertions: the eligibility rule, variant generation/adjacency, upstream normalization (dated-id dedupe, legacy-generation filter, unknown-family retention), family resolution + alias derivation, cache success/fallback/TTL/backoff, x-api-key auth mode, payload shape.test/provider-prefix.mjsupdated for the derivedopus1m.tscclean.Risk
Low. The hot request path only gains a synchronous cache read in
resolveClaudeAlias. /v1/models is the only route that awaits the catalog, and it cannot throw. Offline/air-gapped deployments serve the identical baked list as today.