Remove the model allowlist and instead derive the Fast tier premium
from matching catalogue entries, falling back to the documented
multiplier when metadata is missing or inconsistent. Endpoint and
cost-override guards, tests, and docs are preserved.
Signed-off-by: David Gageot <david.gageot@docker.com>
An explicitly configured base_url of https://api.openai.com/v1 was
being treated as a custom endpoint, so the fast/priority (2x) and
ultrafast (6x) service-tier cost multipliers silently fell back to
standard rates. Only the resolved client endpoint was checked before;
now both the configured and resolved values are compared against the
official endpoint.
Also narrows Vercel's gpt-6-astra long-context tier boundary from
272001 to 272000 tokens so it matches the exclusive threshold
RatesFor expects, and adds published-rate boundary coverage for
gpt-5.6-luna and gpt-6-astra plus mixed-tier SQLite persistence tests.
Assisted-By: docker-agent
Cost accounting now uses the tier the provider actually served instead
of the one requested, covering chat, responses, and websocket
transports. Custom endpoints, routers, and cost overrides are left
alone. WebSocket and HTTP paths now resolve the base URL the same way,
fixed at client construction for both transports.
Assisted-By: docker-agent
EmbeddedSnapshot exposes the build-time snapshot.json catalog as a
read-only singleton, and Fetch hits the live models.dev API directly,
surfacing a network failure instead of silently degrading to a cache
or the embedded snapshot.
Together with the existing NewDatabaseStore these let callers build a
Store that is either provably hermetic or provably live, instead of
Store's usual best-effort network-then-cache-then-snapshot fallback.
Groundwork for #4134.
models.dev removed deepseek-chat and deepseek-reasoner from the deepseek
provider. Update all references to use deepseek-v4-pro (the current
flagship model) and refresh the embedded snapshot to match the live
catalog.
Fixes: TestParseExamples/../../examples/deepseek.yaml
gemini-3-pro-preview was removed from the live models.dev catalog,
causing TestParseExamples to fail on both Linux and Windows CI runners
with: 'model "gemini-3-pro-preview" not found in provider "google"'.
Switch the reviewer agent in examples/gopher.{yaml,hcl} to
gemini-3.1-pro-preview, its direct successor in the catalog.
Also regenerate pkg/modelsdev/snapshot.json so the baked-in fallback
snapshot stays in sync with the current live catalog.
Runs go generate ./pkg/modelsdev/... to pull the latest catalog from
models.dev. The only change to the anthropic provider is the addition of
claude-opus-5 (family claude-opus, 1M context, 128k output, $5/$25
pricing, text+image+pdf input). Five new niche providers are also added
as part of the wholesale refresh.
Adds TestEmbeddedSnapshotIncludesClaudeOpus5 to guard against a future
stale snapshot silently dropping the new model, mirroring the existing
GPT-5.6 regression test.
pkg/modelsdev, pkg/gateway and pkg/httpclient only needed
remote.NewTransport, but importing pkg/remote drags the whole OCI
registry stack (go-containerregistry, docker/cli, credential helpers)
into every consumer of pkg/model/provider, pkg/session and pkg/agent.
Move the transport (and its proxy fallback logic) to
pkg/desktop/transport, which only depends on pkg/desktop and
pkg/memoize. remote.NewTransport is kept as a deprecated forwarder so
existing integrations keep compiling and behaving identically.
pkg/model/provider now pulls 24 external modules instead of 31.
Prevent picker stacking on ctrl+r, preserve the search query across
refreshes, and avoid holding the store mutex during network I/O.
Coalesce refreshes with a dedicated refreshMu, improve error handling
for in-memory and not-modified edge cases, and add covering tests.
Assisted-By: Claude (Anthropic)
Pressing Ctrl+R in the model picker bypasses the models.dev cache TTL,
re-fetches the catalog, and reopens the picker with updated choices.
Assisted-By: docker/docker-agent
Restore the context.Context parameter on app.New (the rebase auto-merge
silently dropped it while keeping the ctx-using body) and thread the
caller's context through all call sites, including tests.
Annotate the build-time root context in the new
pkg/modelsdev/internal/gen snapshot generator (landed from main) for the
ContextConnectivity cop: it is a standalone main with no parent context.
Adds a build-time snapshot of the models.dev catalog baked into the
binary via go:embed, used as last-resort fallback when the cache and
live fetch are both unavailable. A generator (pkg/modelsdev/internal/gen)
refreshes the snapshot; task update-models and a weekly GitHub Actions
workflow keep it current.
The fallback snapshot is not memoized on transient fetch failure, so the
Store retries the fetch once the network recovers. Context windows for
Fable and Opus 4.6-4.8 now come from the embedded snapshot (always
available, even offline); the Anthropic client falls back to the flat
200k floor only when no catalogue entry exists. A warning is logged when
the embedded snapshot fails to parse so a bad build artifact is
discoverable.
The snapshot freshness check is opt-in: TestSnapshotDateParses always
runs (time-independent) while TestSnapshotDateIsFresh is skipped unless
CHECK_MODELS_SNAPSHOT_FRESHNESS is set. A 'task check-models-fresh'
target provides the CI backstop.
Assisted-By: Claude
Resolving a model for a user-defined custom provider (a name that is not a
built-in or alias, e.g. mistral_gateway) loaded the full models.dev catalog,
which performs a blocking 30s GET to https://models.dev/api.json. In
internet-restricted environments this hung the request loop (loop.go) and
session compaction on every turn, making a self-contained custom-provider
config (base_url + token_key) unusable.
modelsdev.Store gains WithKnownProvider: a provider the predicate rejects is
resolved from the cache only and never triggers an outbound fetch (a missing
cache yields an empty catalog, so the lookup returns a clean "provider not
found"). The cache-only snapshot is memoized separately from the authoritative
catalog, keeping the per-turn hot path cheap (no repeated catalog re-parse)
without ever satisfying a fetch-eligible lookup for a known provider.
The runtime's default store (lazyModelStore) and RuntimeConfig.ModelsDevStore()
are wired with provider.IsKnownProvider, so only catalog providers (built-ins
and aliases) can reach the network; custom providers resolve locally and the
agent stays usable air-gapped.