From e42dc5a7fb58d518c89260b7a097ea783d8b1aac Mon Sep 17 00:00:00 2001 From: hshinosa <116771617+hshinosa@users.noreply.github.com> Date: Tue, 15 Sep 2026 16:34:17 +0700 Subject: [PATCH 1/2] feat(models): enrich provider model list from models.dev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provider /models endpoints rarely return the metadata a picker needs — Anthropic hard-coded 200000 for every model (lied for Claude Sonnet 4.6, whose real window is 1M), Gemini returned no capability flags, and most providers report zero pricing. The dashboard's Models page, the composer gauge, and the TUI's picker therefore either showed wrong numbers or none at all. This ships a hybrid catalogue: 1. Bundled snapshot (compact JSON via //go:embed) — offline-first, answers every lookup immediately, works on corporate networks that block outbound HTTPS. 2. Background refresh — one hour after boot and hourly thereafter, a goroutine pulls models.dev/api.json, hot-swaps the in-memory table via atomic.Pointer, and persists the normalised bytes to $XDG_CACHE_HOME/antares/models.json so warm boots skip the wait. 3. Env kill-switch — ANTARES_DISABLE_MODELS_FETCH=1 for airgapped hosts, ANTARES_MODELS_URL for a mirror, ANTARES_MODELS_CACHE for tests. Live provider values still win when the enrichment cascade runs; the snapshot is metadata-only, never a source of "what models exist". The snapshot ships as a JSON asset consumed via //go:embed rather than as a generated Go source file full of struct literals. Data as data, not code: the bundled asset is a single compact line (~285 KB) that GitHub collapses in review, git history stays lean, and the runtime cost is one json.Unmarshal at init. Cascade for context window (unchanged from the earlier iteration): 1. Per-provider user override in cfg.Providers[…].ModelMeta (kept from upstream; the Providers page still writes here). 2. Strict providers.MetaByProvider — exact provider/id, with slug variant fallback (Anthropic ships claude-opus-4.7 while models.dev catalogues claude-opus-4-7 — same model, different spelling). 3. Proxy fallback via MetaByAnyProvider — only for openai-compatible and custom providers (EnxAPI, LiteLLM, self-hosted endpoints) that re-serve official ids. First-party providers that genuinely do not carry a model never inherit some other provider's entry. 4. cfg.Model.ContextWindow global fallback. 5. 128000 safety net. The earlier cascade iterated every provider in the config and returned the first hit, which caused MetaByProvider's loose fallback to attribute the wrong entry to unrelated providers — e.g. reading Anthropic's row for a Kimi request. The new candidateProviders walks only providers that actually claim the id in their Models list or ModelMeta keys. Adapter cleanup: - internal/llm/anthropic.go: drop the hard-coded 200000/64000/true/true block; emit id+name only and let the server layer enrich. - internal/llm/gemini.go: drop `strings.Contains(id, "2.5")` reasoning heuristic (was wrong for every non-Gemini id a proxy re-serves). Keep the real InputTokenLimit/OutputTokenLimit the API returns. Composer gauge: - ChatPage refetches /context-window whenever activeModel changes, passing the qualified provider/model id so the server can honour the caller's provider hint. - ModelPicker emits an `antares:model-changed` event on successful /model/set; StatusPill listens so the "Connected · " label refreshes at once instead of waiting up to 10 s for the next poll. TUI: - New providers.FetchModelInfos preserves the full ModelInfo from the live probe (FetchModels still returns []string for the CLI). - Model picker's right column now shows "1000K ctx · anthropic" when the cascade knows the window, falling back to the provider name. - Header adds "145K/1000K (14%)" alongside the ↑↓ counters; a Context section joins the Tokens section in the sidebar. /status prints the same ratio. Both fall back to the metadata cascade so a fresh session shows the model's budget before the first turn. - The agent-side contextWindowFor picks up the new cascade, so compaction now triggers at the model's real window (Claude Sonnet 4.6 compacts at 800k instead of 160k) even for TUI-only users. Regeneration: `make sync-models` fetches models.dev/api.json and writes internal/providers/models_generated.json (marked linguist-generated). The 3-entry hand-curated contextWindows map stays as an escape hatch for cases where upstream regresses. --- .gitattributes | 3 + Makefile | 4 + cmd/antares/main.go | 7 + internal/agent/compact.go | 77 ++++- internal/llm/anthropic.go | 10 +- internal/llm/gemini.go | 14 +- internal/providers/catalog.go | 25 +- internal/providers/generated_models.go | 100 +++++++ internal/providers/metadata.go | 267 +++++++++++++++++ internal/providers/metadata_test.go | 157 ++++++++++ internal/providers/models.go | 19 ++ internal/providers/models_generated.json | 1 + internal/providers/refresh.go | 323 +++++++++++++++++++++ internal/server/handlers_config.go | 69 +++++ internal/server/handlers_providers.go | 146 +++++++++- internal/tui/commands.go | 13 +- internal/tui/pickers.go | 60 +++- internal/tui/tui.go | 9 +- internal/tui/view.go | 35 ++- scripts/sync-models-dev.go | 351 +++++++++++++++++++++++ web/src/components/chat/ModelPicker.tsx | 4 + web/src/components/layout/StatusPill.tsx | 12 +- web/src/pages/ChatPage.tsx | 14 +- 23 files changed, 1667 insertions(+), 53 deletions(-) create mode 100644 .gitattributes create mode 100644 internal/providers/generated_models.go create mode 100644 internal/providers/metadata.go create mode 100644 internal/providers/metadata_test.go create mode 100644 internal/providers/models_generated.json create mode 100644 internal/providers/refresh.go create mode 100644 scripts/sync-models-dev.go diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..39e03aa --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# Generated files — collapse in GitHub diffs by default and skip from +# linguist language stats. Regenerate with `make sync-models`. +internal/providers/models_generated.json linguist-generated=true diff --git a/Makefile b/Makefile index e538f4d..c5821ca 100644 --- a/Makefile +++ b/Makefile @@ -119,6 +119,10 @@ check: vet test typecheck web-test ## Run every check (add `make smoke` for the fmt: ## Format Go sources @$(GO) fmt ./... +.PHONY: sync-models +sync-models: ## Refresh internal/providers/models_generated.json from models.dev + @$(GO) run ./scripts/sync-models-dev.go + .PHONY: release release: ## Cross-compile release binaries for all platforms into dist/release @VERSION="$(VERSION)" GO="$(GO)" BUN="$(BUN)" ./scripts/release-build.sh diff --git a/cmd/antares/main.go b/cmd/antares/main.go index 02dd6bc..c36a492 100644 --- a/cmd/antares/main.go +++ b/cmd/antares/main.go @@ -217,6 +217,13 @@ func bootstrap(ctx context.Context) (*runtimeServices, error) { if err := logx.Setup(cfg.Logging.Level, cfg.Logging.File, cfg.Logging.JSON); err != nil { return nil, fmt.Errorf("setting up logging: %w", err) } + // Kick off the background models.dev refresh. The bundled snapshot + // answers every lookup immediately (offline, first-run, corporate + // firewall); this pulls a fresh copy in the background and caches it + // under $XDG_CACHE_HOME/antares/models.json for the next boot. Set + // ANTARES_DISABLE_MODELS_FETCH=1 to skip on airgapped hosts. + providers.StartRefresh(ctx) + // Don't create the default workspace before the wizard has run — a fresh // install shouldn't leave ~/antares-workspace behind if setup is abandoned. if !needsSetup(cfg) { diff --git a/internal/agent/compact.go b/internal/agent/compact.go index c9ce46c..d229f2e 100644 --- a/internal/agent/compact.go +++ b/internal/agent/compact.go @@ -8,6 +8,7 @@ import ( "strings" "unicode/utf8" + "github.com/enowdev/antares/internal/config" "github.com/enowdev/antares/internal/llm" "github.com/enowdev/antares/internal/providers" "github.com/enowdev/antares/internal/store" @@ -21,21 +22,81 @@ import ( // sane fallback. It mirrors the window maybeCompact governs, so the UI's // "context full" bar agrees with compaction. func (a *Agent) contextWindowFor(model string) int { - if a.config() != nil { - for _, p := range a.config().Providers { - if m, ok := p.ModelMeta[model]; ok && m.ContextWindow > 0 { - return m.ContextWindow - } + cfg := a.config() + if cfg == nil || model == "" { + return 128000 + } + candidates := candidateProvidersForModel(cfg, model) + // First pass: strict provider/id lookup. + for _, providerID := range candidates { + p := cfg.Providers[providerID] + if m, ok := p.ModelMeta[model]; ok && m.ContextWindow > 0 { + return m.ContextWindow + } + if meta, ok := providers.MetaByProvider(providerID, model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow } } - if w := providers.ContextWindow(model); w > 0 { + // Second pass: proxy fallback for openai-compatible providers that + // re-serve official models under real ids. + for _, providerID := range candidates { + kind := cfg.Providers[providerID].Kind + if kind != "openai-compatible" && kind != "custom" { + continue + } + if meta, ok := providers.MetaByAnyProvider(model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + } + if w := legacyCuratedWindow(model); w > 0 { return w } - if a.config() != nil && a.config().Model.ContextWindow > 0 { - return a.config().Model.ContextWindow + if cfg.Model.ContextWindow > 0 { + return cfg.Model.ContextWindow } return 128000 } +// candidateProvidersForModel mirrors the server's candidateProviders: active +// provider first, then any provider whose Models list *or* ModelMeta keys +// mention the id. A provider that carries a per-model meta entry has clearly +// claimed the model even if it never added the id to Models. +func candidateProvidersForModel(cfg *config.Config, model string) []string { + seen := map[string]bool{} + var out []string + push := func(id string) { + if id == "" || seen[id] { + return + } + seen[id] = true + out = append(out, id) + } + push(cfg.Model.Provider) + for providerID, p := range cfg.Providers { + if _, ok := p.ModelMeta[model]; ok { + push(providerID) + continue + } + for _, m := range p.Models { + if m == model { + push(providerID) + break + } + } + } + return out +} + +// legacyCuratedWindow reaches into providers.ContextWindow only for the +// curated map's hits. Since providers.ContextWindow now delegates to Meta() +// (which can loose-match across the generated table), we accept a value only +// if it came from the curated layer. A miss is reported as 0. +func legacyCuratedWindow(model string) int { + m, ok := providers.Meta(model) + if !ok || m.Source != "curated" { + return 0 + } + return m.ContextWindow +} // maybeCompact summarises older turns once the conversation approaches the // model's context window, keeping recent turns verbatim. On success the diff --git a/internal/llm/anthropic.go b/internal/llm/anthropic.go index f51ce7e..822e7dc 100644 --- a/internal/llm/anthropic.go +++ b/internal/llm/anthropic.go @@ -427,9 +427,15 @@ func (c *anthropicClient) Models(ctx context.Context) ([]ModelInfo, error) { } out := make([]ModelInfo, 0, len(raw.Data)) for _, m := range raw.Data { + // The Anthropic /models endpoint does not return context window, + // max output, or capability flags. Emit only what the API tells us + // and let the server layer enrich from the models.dev snapshot; + // hard-coding 200000 across the family lied for Claude Sonnet 4.6 + // (real window: 1M). out = append(out, ModelInfo{ - ID: m.ID, Name: firstNonEmpty(m.DisplayName, m.ID), Provider: c.opts.ProviderID, - ContextWindow: 200000, MaxOutput: 64000, Vision: true, Tools: true, Reasoning: true, + ID: m.ID, + Name: firstNonEmpty(m.DisplayName, m.ID), + Provider: c.opts.ProviderID, }) } return out, nil diff --git a/internal/llm/gemini.go b/internal/llm/gemini.go index 700e15d..6968516 100644 --- a/internal/llm/gemini.go +++ b/internal/llm/gemini.go @@ -627,10 +627,18 @@ func (c *geminiClient) Models(ctx context.Context) ([]ModelInfo, error) { continue } id := strings.TrimPrefix(m.Name, "models/") + // Gemini /models returns real token limits (InputTokenLimit / + // OutputTokenLimit); use those. Capability flags — vision, + // reasoning — are not in the response; leave them zero so the + // server layer enriches from the models.dev snapshot instead of + // guessing from the id ("contains 2.5" was wrong for every + // non-Gemini id a proxy happens to expose). out = append(out, ModelInfo{ - ID: id, Name: firstNonEmpty(m.DisplayName, id), Provider: c.opts.ProviderID, - ContextWindow: m.InputTokenLimit, MaxOutput: m.OutputTokenLimit, - Vision: true, Tools: true, Reasoning: strings.Contains(id, "2.5") || strings.Contains(id, "3"), + ID: id, + Name: firstNonEmpty(m.DisplayName, id), + Provider: c.opts.ProviderID, + ContextWindow: m.InputTokenLimit, + MaxOutput: m.OutputTokenLimit, }) } return out, nil diff --git a/internal/providers/catalog.go b/internal/providers/catalog.go index 5e38457..bf4e877 100644 --- a/internal/providers/catalog.go +++ b/internal/providers/catalog.go @@ -20,20 +20,29 @@ type Info struct { Models []string } -// contextWindows records the true context window (in tokens) for models whose -// provider API does not report one, keyed by model id. The agent consults this -// when a config has no explicit model_meta, so the context gauge and compaction -// use the real window instead of the 200k default. Source: provider docs. +// contextWindows is the hand-curated escape hatch consulted by metadata.go's +// cascade. Prefer regenerating the models.dev snapshot (make sync-models) +// over adding an entry here; this map is for cases where upstream is missing +// or wrong and cannot wait for a refresh. var contextWindows = map[string]int{ // Z.ai GLM — https://docs.z.ai/guides/llm - "glm-5.2": 1_000_000, // 1M context + // Kept as a reference example. The generated snapshot covers Z.ai too, + // so these values only win if models.dev regresses. + "glm-5.2": 1_000_000, "glm-4.7": 200_000, "glm-4.6": 200_000, } -// ContextWindow returns the known context window for a model id, or 0 if none -// is catalogued. -func ContextWindow(model string) int { return contextWindows[model] } +// ContextWindow returns the known context window for a model id, walking the +// same cascade as Meta(): hand-curated overrides → generated models.dev +// snapshot → 0 when nothing knows. Callers layer their own user-config +// overrides on top; this function stays package-local by design. +func ContextWindow(model string) int { + if m, ok := Meta(model); ok { + return m.ContextWindow + } + return 0 +} var catalog = []Info{ {"anthropic", "Anthropic", "anthropic", "ANTHROPIC_API_KEY", "", true, diff --git a/internal/providers/generated_models.go b/internal/providers/generated_models.go new file mode 100644 index 0000000..daec64e --- /dev/null +++ b/internal/providers/generated_models.go @@ -0,0 +1,100 @@ +// Package providers — see metadata.go for the type + cascade. +// +// This file wires the bundled models.dev snapshot (models_generated.json) +// into a lookup table used by Meta() and MetaByProvider(). The bundled +// snapshot is the offline-first fallback; refresh.go replaces it in place +// with a fresh models.dev pull once the process has network. +// +// Rationale for a JSON asset + //go:embed rather than a generated .go file +// full of struct literals: the snapshot is data, not code. Bundling it as a +// literal source file bloats every review with thousands of lines of key/ +// value diffs whenever `make sync-models` runs. As a compact JSON asset the +// diff stays in one file GitHub already knows how to collapse, git history +// stays lean, and the runtime cost (one json.Unmarshal at process start) is +// trivial for ~1k entries. + +package providers + +import ( + _ "embed" + "encoding/json" + "fmt" + "sync/atomic" +) + +//go:embed models_generated.json +var generatedModelsRaw []byte + +// generatedTable holds the current snapshot behind an atomic.Pointer so a +// background refresh can hot-swap it without racing readers. The Meta() +// callers read millions of times per session; the write path fires once at +// startup and again every refreshInterval, so lock-free reads are worth the +// tiny allocation each refresh. +var generatedTable atomic.Pointer[map[string]ModelMeta] + +func init() { + initial := mustLoadGeneratedModels(generatedModelsRaw) + generatedTable.Store(&initial) +} + +// generatedModels returns the current snapshot. Callers get a value copy of +// the map header — the underlying map is never mutated in place, only +// replaced wholesale, so the returned reference stays consistent for the +// duration of one lookup even if a refresh lands mid-call. +func generatedModels() map[string]ModelMeta { + p := generatedTable.Load() + if p == nil { + return nil + } + return *p +} + +// setGeneratedModels swaps in a fresh snapshot. Called by the refresh +// goroutine in refresh.go once a live models.dev pull lands, and by tests +// that need a deterministic table. +func setGeneratedModels(m map[string]ModelMeta) { + generatedTable.Store(&m) +} + +// generatedModelsEnvelope matches the shape written by scripts/sync-models-dev.go. +// Only the models map is loaded into memory — the _source/_fetched_at fields +// stay in the file for humans reading the diff and are not needed at runtime. +type generatedModelsEnvelope struct { + Models map[string]ModelMeta `json:"models"` +} + +// mustLoadGeneratedModels parses the embedded snapshot at init time. A panic +// here would only fire on a malformed regeneration — a bug in the sync script +// or a hand-edit of the JSON — which is caught immediately by `go test`, +// never by an end user. Returning an empty map on decode failure would hide +// the bug behind silently missing metadata, which is worse. +func mustLoadGeneratedModels(raw []byte) map[string]ModelMeta { + if len(raw) == 0 { + return map[string]ModelMeta{} + } + var env generatedModelsEnvelope + if err := json.Unmarshal(raw, &env); err != nil { + panic(fmt.Errorf("providers: parse embedded models_generated.json: %w", err)) + } + if env.Models == nil { + return map[string]ModelMeta{} + } + return env.Models +} + +// parseGeneratedModels is the non-panicking sibling used by the disk cache +// and live-fetch paths where a corrupted payload should be an error (log + +// keep prior snapshot), not a process kill. +func parseGeneratedModels(raw []byte) (map[string]ModelMeta, error) { + if len(raw) == 0 { + return nil, fmt.Errorf("empty payload") + } + var env generatedModelsEnvelope + if err := json.Unmarshal(raw, &env); err != nil { + return nil, err + } + if env.Models == nil { + return map[string]ModelMeta{}, nil + } + return env.Models, nil +} diff --git a/internal/providers/metadata.go b/internal/providers/metadata.go new file mode 100644 index 0000000..7e05769 --- /dev/null +++ b/internal/providers/metadata.go @@ -0,0 +1,267 @@ +package providers + +import "strings" + +// ModelMeta describes a single model — context window, pricing, capability +// flags, and identity — as far as Antares needs to know. It is the shape the +// generated models.dev snapshot uses and the shape Meta() returns to callers. +// +// Zero-values mean "unknown" — callers walking the cascade fall through to the +// next layer instead of trusting a fabricated 0-token window or a $0 price. +type ModelMeta struct { + Provider string `json:"provider,omitempty"` + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Family string `json:"family,omitempty"` + ContextWindow int `json:"context_window,omitempty"` + MaxOutput int `json:"max_output,omitempty"` + Cost Cost `json:"cost,omitempty"` + Reasoning bool `json:"reasoning,omitempty"` + ToolCall bool `json:"tool_call,omitempty"` + Attachment bool `json:"attachment,omitempty"` + Vision bool `json:"vision,omitempty"` + PDF bool `json:"pdf,omitempty"` + OpenWeights bool `json:"open_weights,omitempty"` + KnowledgeCutoff string `json:"knowledge_cutoff,omitempty"` + ReleaseDate string `json:"release_date,omitempty"` + // Source records which cascade layer answered — useful in debug logs and + // the dashboard so operators can tell whether metadata came from their + // own config, the bundled models.dev snapshot, a hand-curated escape + // hatch, or fell through to zero. Values: "user", "generated", + // "curated", "" (miss). Not persisted in the bundled snapshot; the + // caller stamps it after lookup. + Source string `json:"-"` +} + +// Cost is per 1M-token pricing in USD, matching the models.dev unit. +type Cost struct { + Input float64 `json:"input,omitempty"` + Output float64 `json:"output,omitempty"` + CacheRead float64 `json:"cache_read,omitempty"` + CacheWrite float64 `json:"cache_write,omitempty"` +} + +// HasCost reports whether the entry carries any pricing data at all — used to +// decide whether the dashboard should draw a "$3/M in" chip or hide the field. +func (c Cost) HasCost() bool { + return c.Input > 0 || c.Output > 0 || c.CacheRead > 0 || c.CacheWrite > 0 +} + +// Meta looks up model metadata by bare id (e.g. "claude-sonnet-4-6") without a +// caller-supplied provider hint. It walks the cascade in the same order as +// MetaByProvider and picks the first generated-table hit across every known +// provider — good enough for the agent's contextWindowFor() which only knows +// the model name, not always which provider it belongs to. +// +// Prefer MetaByProvider when the caller already knows the provider, because +// the same model id can appear under multiple provider prefixes +// (e.g. "claude-opus" via anthropic and openrouter) with different pricing. +func Meta(model string) (ModelMeta, bool) { + if model == "" { + return ModelMeta{}, false + } + // Fast path: id carries a provider prefix (openrouter's "anthropic/…"). + if provider, id, ok := strings.Cut(model, "/"); ok { + if m, hit := MetaByProvider(provider, id); hit { + return m, true + } + } + // Slow path: scan the generated table for any provider that lists this id. + if m, ok := lookupBareID(model); ok { + return m, true + } + if w, ok := legacyContextWindow(model); ok { + return ModelMeta{ID: model, ContextWindow: w, Source: "curated"}, true + } + return ModelMeta{}, false +} + +// MetaByProvider looks up metadata for a specific provider+model pair, +// walking the full cascade: +// +// 1. Hand-curated overrides (legacyContextWindow) — an escape hatch for +// entries where models.dev is missing or upstream is wrong. Kept small. +// 2. Generated snapshot from models.dev, exact key "provider/id" first, +// then the same key with dots/dashes normalised (models.dev uses "4-6", +// Anthropic's own API uses "4.7" — same model, different spelling). +// 3. Bare-id lookup across every provider — this is the escape hatch for +// custom proxies (e.g. enxapi) that re-serve official models under +// their own provider id. If exactly one entry in the table has that +// bare id, use it; if several do, prefer any anthropic/openai/google +// entry over noisy re-listings. +// 4. Miss — the caller falls through to whatever default it has. +// +// Note: layer 0 ("user override" via cfg.Providers[…].ModelMeta) is applied +// by higher-level callers that already hold *config.Config; the pure +// providers package stays free of runtime config to keep it importable from +// anywhere. +func MetaByProvider(provider, model string) (ModelMeta, bool) { + if model == "" { + return ModelMeta{}, false + } + // Layer 1: hand-curated override — highest priority within this package + // so we can correct a models.dev entry without regenerating. + if w, ok := legacyContextWindow(model); ok { + return ModelMeta{Provider: provider, ID: model, ContextWindow: w, Source: "curated"}, true + } + // Layer 2: strict provider/id lookup. Try the exact key first, then the + // same key with dot/dash slug variants (Anthropic ships "claude-opus-4.7" + // on the wire; models.dev catalogues it as "claude-opus-4-7"). No + // cross-provider fallback here — a first-party provider that does not + // carry the id is authoritative "does not have this model", and pinning + // to some other provider's re-listing would attribute the wrong + // context/cost to a model the caller specifically asked about. + if provider == "" { + return ModelMeta{}, false + } + // Hoist the snapshot once so a mid-lookup refresh cannot make the two + // keyed reads see different tables. + table := generatedModels() + if m, ok := table[provider+"/"+model]; ok { + m.Source = "generated" + return m, true + } + for _, variant := range slugVariants(model) { + if m, ok := table[provider+"/"+variant]; ok { + m.Source = "generated" + return m, true + } + } + return ModelMeta{}, false +} + +// MetaByAnyProvider looks up metadata by bare id across every provider in the +// generated table. Used only by callers that know their provider is a proxy +// re-serving official models (e.g. an OpenAI-compatible endpoint like EnxAPI +// that fronts Anthropic, OpenAI, Google under their real ids). Callers that +// know a specific provider should use MetaByProvider — it refuses to pin the +// wrong entry when the provider genuinely does not carry the model. +// +// Preference order among candidates: first-party providers +// (anthropic > openai > google > well-known labs) win over noisy re-listings +// so "gpt-5" resolves to openai's numbers rather than some proxy's markup. +func MetaByAnyProvider(model string) (ModelMeta, bool) { + if model == "" { + return ModelMeta{}, false + } + if w, ok := legacyContextWindow(model); ok { + return ModelMeta{ID: model, ContextWindow: w, Source: "curated"}, true + } + return lookupBareID(model) +} +// lookupBareID scans the generated table for any entry whose bare model id +// matches, with slug normalisation. Prefers first-party providers (anthropic, +// openai, google) when several proxies re-list the same model so a lookup for +// "claude-opus-4.7" doesn't accidentally pin to github-copilot's re-listing. +func lookupBareID(model string) (ModelMeta, bool) { + variants := append([]string{model}, slugVariants(model)...) + var best ModelMeta + var found bool + for _, m := range generatedModels() { + if !containsAny(variants, m.ID) { + continue + } + m.Source = "generated" + if !found { + best = m + found = true + continue + } + if firstPartyRank(m.Provider) < firstPartyRank(best.Provider) { + best = m + } + } + return best, found +} + +// slugVariants returns the model id with common separator flips. Anthropic's +// own API uses dots ("claude-opus-4.7"); models.dev uses dashes +// ("claude-opus-4-6"). Return both spellings so a lookup succeeds regardless +// of which convention the caller passed in. Also handles the reverse. +func slugVariants(model string) []string { + var out []string + if strings.ContainsRune(model, '.') { + out = append(out, strings.ReplaceAll(model, ".", "-")) + } + // Reverse: some model ids in the table use dots — unusual but safe. + if strings.ContainsRune(model, '-') { + // Only flip the trailing version segment to a dot; blindly replacing + // every dash breaks "claude-opus" itself. Grab the last two segments + // and see if they look like a version pair ("4-7" -> "4.7"). + parts := strings.Split(model, "-") + if n := len(parts); n >= 2 { + if _, err := parseUint(parts[n-1]); err == nil { + if _, err := parseUint(parts[n-2]); err == nil { + joined := strings.Join(parts[:n-2], "-") + "-" + parts[n-2] + "." + parts[n-1] + out = append(out, joined) + } + } + } + } + return out +} + +// firstPartyRank returns a lower number for first-party providers so +// lookupBareID prefers them over re-listings. Unknown providers rank last. +func firstPartyRank(provider string) int { + switch provider { + case "anthropic": + return 0 + case "openai": + return 1 + case "google": + return 2 + case "xai", "deepseek", "mistral", "cohere", "groq": + return 3 + default: + return 4 + } +} + +func containsAny(haystack []string, needle string) bool { + for _, h := range haystack { + if h == needle { + return true + } + } + return false +} + +// parseUint is a strconv.ParseUint wrapper that keeps the metadata helpers +// free of a strconv import — the standard library dep is fine, this just +// keeps the diff on this file self-contained. +func parseUint(s string) (uint64, error) { + if s == "" { + return 0, errEmpty + } + var n uint64 + for _, r := range s { + if r < '0' || r > '9' { + return 0, errNotDigit + } + n = n*10 + uint64(r-'0') + } + return n, nil +} + +var ( + errEmpty = &parseErr{"empty"} + errNotDigit = &parseErr{"not a digit"} +) + +type parseErr struct{ msg string } + +func (e *parseErr) Error() string { return e.msg } + + +// legacyContextWindow bridges the old package-level contextWindows map. It +// exists so metadata.go stays the single lookup surface even while callers +// still expect ContextWindow() to work. The map itself lives in catalog.go +// alongside the rest of the hand-curated provider data. +func legacyContextWindow(model string) (int, bool) { + w, ok := contextWindows[model] + if !ok || w <= 0 { + return 0, false + } + return w, true +} diff --git a/internal/providers/metadata_test.go b/internal/providers/metadata_test.go new file mode 100644 index 0000000..2960ab6 --- /dev/null +++ b/internal/providers/metadata_test.go @@ -0,0 +1,157 @@ +package providers + +import "testing" + +// TestMetaLookupBareID exercises Meta() for callers that only know the model +// id (e.g. agent.contextWindowFor). Should hit the generated table without +// needing a provider hint. +func TestMetaLookupBareID(t *testing.T) { + // pick a model we know models.dev catalogues with a non-zero window. + // Choose one whose id is unique across providers to keep the assertion + // robust — a bare id lookup returns the first-matching entry. + got, ok := Meta("claude-sonnet-4-6") + if !ok { + t.Fatalf("Meta(claude-sonnet-4-6): expected hit from generated snapshot") + } + if got.ContextWindow == 0 { + t.Errorf("expected non-zero ContextWindow for claude-sonnet-4-6, got 0") + } + if got.Source != "generated" { + t.Errorf("expected Source=generated, got %q", got.Source) + } +} + +// TestMetaLookupProviderQualified covers the "provider/id" shortcut path. +func TestMetaLookupProviderQualified(t *testing.T) { + got, ok := Meta("anthropic/claude-sonnet-4-6") + if !ok { + t.Fatalf("Meta(anthropic/claude-sonnet-4-6): expected hit") + } + if got.Provider != "anthropic" { + t.Errorf("expected Provider=anthropic, got %q", got.Provider) + } + if got.ContextWindow == 0 { + t.Errorf("expected non-zero ContextWindow, got 0") + } +} + +// TestMetaLookupUnknown returns miss for a model id not in any layer. +func TestMetaLookupUnknown(t *testing.T) { + _, ok := Meta("this-model-definitely-does-not-exist-42") + if ok { + t.Errorf("expected miss for unknown model, got hit") + } +} + +// TestMetaByProviderGeneratedHit — direct provider+model lookup on the +// generated snapshot. +func TestMetaByProviderGeneratedHit(t *testing.T) { + got, ok := MetaByProvider("anthropic", "claude-sonnet-4-6") + if !ok { + t.Fatalf("MetaByProvider(anthropic, claude-sonnet-4-6): expected hit") + } + if got.ContextWindow == 0 { + t.Errorf("expected non-zero context window") + } + if !got.ToolCall { + t.Errorf("expected ToolCall=true for Claude Sonnet") + } + if got.Cost.Input == 0 { + t.Errorf("expected non-zero input cost") + } +} + +// TestMetaByProviderMiss returns not-ok when the pair is unknown. +func TestMetaByProviderMiss(t *testing.T) { + _, ok := MetaByProvider("anthropic", "nonexistent-model-xyz") + if ok { + t.Errorf("expected miss") + } +} + +// TestMetaCuratedOverridesGenerated verifies the hand-curated +// contextWindows map wins over the generated snapshot in +// MetaByProvider, so operators can patch a wrong upstream value +// without waiting for the sync script. +func TestMetaCuratedOverridesGenerated(t *testing.T) { + // glm-5.2 sits in both the curated map (1_000_000) and the generated + // snapshot. If the cascade order is correct, we get the curated value. + got, ok := MetaByProvider("zai", "glm-5.2") + if !ok { + t.Fatalf("MetaByProvider(zai, glm-5.2): expected hit") + } + if got.ContextWindow != 1_000_000 { + t.Errorf("expected curated 1_000_000, got %d", got.ContextWindow) + } + if got.Source != "curated" { + t.Errorf("expected Source=curated, got %q", got.Source) + } +} + +// TestContextWindowUsesCascade confirms the package-level ContextWindow() +// helper is a thin wrapper on Meta() — no more standalone map lookup. +func TestContextWindowUsesCascade(t *testing.T) { + if got := ContextWindow("claude-sonnet-4-6"); got == 0 { + t.Errorf("expected non-zero ContextWindow from generated snapshot, got 0") + } + if got := ContextWindow("glm-5.2"); got != 1_000_000 { + t.Errorf("expected 1_000_000 for glm-5.2, got %d", got) + } + if got := ContextWindow("bogus-model-name"); got != 0 { + t.Errorf("expected 0 for unknown model, got %d", got) + } +} + +// TestMetaByProviderRejectsWrongProvider guards the fix for a bug where +// requesting a model under a first-party provider that does not carry the +// id (e.g. anthropic + kimi-k2.5) fell through to a random re-listing under +// opencode or similar, silently attributing the wrong context window. The +// strict pair lookup now returns miss so callers can decide how to fall back. +func TestMetaByProviderRejectsWrongProvider(t *testing.T) { + cases := []struct{ provider, model string }{ + {"anthropic", "kimi-k2.5"}, + {"openai", "kimi-k2.5"}, + {"deepseek", "deepseek-v3.2"}, // v3.2 is not in the catalogue + {"anthropic", "deepseek-v3.2"}, + } + for _, c := range cases { + if _, ok := MetaByProvider(c.provider, c.model); ok { + t.Errorf("MetaByProvider(%q, %q): expected miss, got hit — cross-provider pin regressed", + c.provider, c.model) + } + } +} + +// TestMetaByProviderSlugVariants verifies dot↔dash normalisation still finds +// the entry when a caller passes a slug in the "other" convention. +func TestMetaByProviderSlugVariants(t *testing.T) { + got, ok := MetaByProvider("anthropic", "claude-sonnet-4.6") + if !ok { + t.Fatalf("MetaByProvider(anthropic, claude-sonnet-4.6): expected hit via slug variant") + } + if got.ContextWindow == 0 { + t.Errorf("expected non-zero context window, got 0") + } +} + +// TestMetaByAnyProviderResolvesProxy is the escape hatch OpenAI-compatible +// proxies use — the strict pair lookup misses because enx/kimi-k2.5 does not +// exist in the table, but the bare id has a canonical entry the picker +// should still surface. +func TestMetaByAnyProviderResolvesProxy(t *testing.T) { + got, ok := MetaByAnyProvider("kimi-k2.5") + if !ok { + t.Fatalf("MetaByAnyProvider(kimi-k2.5): expected hit from generated snapshot") + } + if got.ContextWindow == 0 { + t.Errorf("expected non-zero context window") + } +} + +// TestMetaByAnyProviderMissForUnknown — the loose lookup must still refuse +// to fabricate metadata for an id that genuinely does not exist. +func TestMetaByAnyProviderMissForUnknown(t *testing.T) { + if _, ok := MetaByAnyProvider("this-id-does-not-exist-42"); ok { + t.Errorf("expected miss for bogus id, got hit") + } +} diff --git a/internal/providers/models.go b/internal/providers/models.go index b182d1a..fa7dcd3 100644 --- a/internal/providers/models.go +++ b/internal/providers/models.go @@ -34,3 +34,22 @@ func FetchModels(ctx context.Context, cfg *config.Config, providerID string) ([] } return out, nil } + +// FetchModelInfos is FetchModels' richer cousin: same live /models probe but +// keeps every field the adapter fills in (context window, capability flags, +// pricing when the provider reports it). Callers that render a picker with +// window/cost badges should use this; callers that only need ids call +// FetchModels and stay allocation-light. +func FetchModelInfos(ctx context.Context, cfg *config.Config, providerID string) ([]llm.ModelInfo, error) { + id, p := cfg.ResolveProvider(providerID) + client, err := llm.New(llm.Options{ + Kind: p.Kind, BaseURL: p.BaseURL, APIKey: p.APIKey, Headers: p.Headers, + ProviderID: id, Timeout: 20 * time.Second, APIVersion: p.APIVersion, Region: p.Region, + }) + if err != nil { + return nil, err + } + ctx, cancel := context.WithTimeout(ctx, 15*time.Second) + defer cancel() + return client.Models(ctx) +} diff --git a/internal/providers/models_generated.json b/internal/providers/models_generated.json new file mode 100644 index 0000000..86c1c25 --- /dev/null +++ b/internal/providers/models_generated.json @@ -0,0 +1 @@ +{"_source":"https://models.dev/api.json","_fetched_at":"2026-09-15T10:07:38Z","models":{"alibaba/deepseek-v4-flash-0731":{"provider":"alibaba","id":"deepseek-v4-flash-0731","name":"DeepSeek V4 Flash 0731","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.2,"output":0.4,"cache_read":0.04},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-07-31"},"alibaba/glm-5.2":{"provider":"alibaba","id":"glm-5.2","name":"GLM-5.2","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.28},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-13"},"alibaba/qvq-max":{"provider":"alibaba","id":"qvq-max","name":"QVQ Max","family":"qvq","context_window":131072,"max_output":8192,"cost":{"input":1.2,"output":4.8},"reasoning":true,"tool_call":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2025-03-25"},"alibaba/qwen-flash":{"provider":"alibaba","id":"qwen-flash","name":"Qwen Flash","family":"qwen","context_window":1000000,"max_output":32768,"cost":{"input":0.05,"output":0.4},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2024-04","release_date":"2025-07-28"},"alibaba/qwen-max":{"provider":"alibaba","id":"qwen-max","name":"Qwen Max","family":"qwen","context_window":32768,"max_output":8192,"cost":{"input":1.6,"output":6.4},"tool_call":true,"knowledge_cutoff":"2024-04","release_date":"2024-04-03"},"alibaba/qwen-mt-plus":{"provider":"alibaba","id":"qwen-mt-plus","name":"Qwen-MT Plus","family":"qwen","context_window":16384,"max_output":8192,"cost":{"input":2.46,"output":7.37},"knowledge_cutoff":"2024-04","release_date":"2025-01"},"alibaba/qwen-mt-turbo":{"provider":"alibaba","id":"qwen-mt-turbo","name":"Qwen-MT Turbo","family":"qwen","context_window":16384,"max_output":8192,"cost":{"input":0.16,"output":0.49},"knowledge_cutoff":"2024-04","release_date":"2025-01"},"alibaba/qwen-omni-turbo":{"provider":"alibaba","id":"qwen-omni-turbo","name":"Qwen-Omni Turbo","family":"qwen","context_window":32768,"max_output":2048,"cost":{"input":0.07,"output":0.27},"tool_call":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2025-01-19"},"alibaba/qwen-omni-turbo-realtime":{"provider":"alibaba","id":"qwen-omni-turbo-realtime","name":"Qwen-Omni Turbo Realtime","family":"qwen","context_window":32768,"max_output":2048,"cost":{"input":0.27,"output":1.07},"tool_call":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2025-05-08"},"alibaba/qwen-plus":{"provider":"alibaba","id":"qwen-plus","name":"Qwen Plus","family":"qwen","context_window":1000000,"max_output":32768,"cost":{"input":0.4,"output":1.2},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2024-04","release_date":"2024-01-25"},"alibaba/qwen-plus-character-ja":{"provider":"alibaba","id":"qwen-plus-character-ja","name":"Qwen Plus Character (Japanese)","family":"qwen","context_window":8192,"max_output":512,"cost":{"input":0.5,"output":1.4},"tool_call":true,"knowledge_cutoff":"2024-04","release_date":"2024-01"},"alibaba/qwen-turbo":{"provider":"alibaba","id":"qwen-turbo","name":"Qwen Turbo","family":"qwen","context_window":1000000,"max_output":16384,"cost":{"input":0.05,"output":0.2},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2024-04","release_date":"2024-11-01"},"alibaba/qwen-vl-max":{"provider":"alibaba","id":"qwen-vl-max","name":"Qwen-VL Max","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.8,"output":3.2},"tool_call":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2024-04-08"},"alibaba/qwen-vl-ocr":{"provider":"alibaba","id":"qwen-vl-ocr","name":"Qwen-VL OCR","family":"qwen","context_window":34096,"max_output":4096,"cost":{"input":0.72,"output":0.72},"vision":true,"knowledge_cutoff":"2024-04","release_date":"2024-10-28"},"alibaba/qwen-vl-plus":{"provider":"alibaba","id":"qwen-vl-plus","name":"Qwen-VL Plus","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.21,"output":0.63},"tool_call":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2024-01-25"},"alibaba/qwen2-5-14b-instruct":{"provider":"alibaba","id":"qwen2-5-14b-instruct","name":"Qwen2.5 14B Instruct","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.35,"output":1.4},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-09"},"alibaba/qwen2-5-32b-instruct":{"provider":"alibaba","id":"qwen2-5-32b-instruct","name":"Qwen2.5 32B Instruct","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.7,"output":2.8},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-09"},"alibaba/qwen2-5-72b-instruct":{"provider":"alibaba","id":"qwen2-5-72b-instruct","name":"Qwen2.5 72B Instruct","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":1.4,"output":5.6},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-09"},"alibaba/qwen2-5-7b-instruct":{"provider":"alibaba","id":"qwen2-5-7b-instruct","name":"Qwen2.5 7B Instruct","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.175,"output":0.7},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-09"},"alibaba/qwen2-5-omni-7b":{"provider":"alibaba","id":"qwen2-5-omni-7b","name":"Qwen2.5-Omni 7B","family":"qwen","context_window":32768,"max_output":2048,"cost":{"input":0.1,"output":0.4},"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-12"},"alibaba/qwen2-5-vl-72b-instruct":{"provider":"alibaba","id":"qwen2-5-vl-72b-instruct","name":"Qwen2.5-VL 72B Instruct","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":2.8,"output":8.4},"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-09"},"alibaba/qwen2-5-vl-7b-instruct":{"provider":"alibaba","id":"qwen2-5-vl-7b-instruct","name":"Qwen2.5-VL 7B Instruct","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.35,"output":1.05},"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-09"},"alibaba/qwen3-14b":{"provider":"alibaba","id":"qwen3-14b","name":"Qwen3 14B","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.35,"output":1.4},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-235b-a22b":{"provider":"alibaba","id":"qwen3-235b-a22b","name":"Qwen3 235B-A22B","family":"qwen","context_window":131072,"max_output":16384,"cost":{"input":0.7,"output":2.8},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-32b":{"provider":"alibaba","id":"qwen3-32b","name":"Qwen3 32B","family":"qwen","context_window":131072,"max_output":16384,"cost":{"input":0.7,"output":2.8},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-8b":{"provider":"alibaba","id":"qwen3-8b","name":"Qwen3 8B","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.18,"output":0.7},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-asr-flash":{"provider":"alibaba","id":"qwen3-asr-flash","name":"Qwen3-ASR Flash","family":"qwen","context_window":53248,"max_output":4096,"cost":{"input":0.035,"output":0.035},"knowledge_cutoff":"2024-04","release_date":"2025-09-08"},"alibaba/qwen3-coder-30b-a3b-instruct":{"provider":"alibaba","id":"qwen3-coder-30b-a3b-instruct","name":"Qwen3-Coder 30B-A3B Instruct","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.45,"output":2.25},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-coder-480b-a35b-instruct":{"provider":"alibaba","id":"qwen3-coder-480b-a35b-instruct","name":"Qwen3-Coder 480B-A35B Instruct","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":1.5,"output":7.5},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-coder-flash":{"provider":"alibaba","id":"qwen3-coder-flash","name":"Qwen3 Coder Flash","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.3,"output":1.5},"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-28"},"alibaba/qwen3-coder-plus":{"provider":"alibaba","id":"qwen3-coder-plus","name":"Qwen3 Coder Plus","family":"qwen","context_window":1048576,"max_output":65536,"cost":{"input":1,"output":5},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-23"},"alibaba/qwen3-livetranslate-flash-realtime":{"provider":"alibaba","id":"qwen3-livetranslate-flash-realtime","name":"Qwen3-LiveTranslate Flash Realtime","family":"qwen","context_window":53248,"max_output":4096,"cost":{"input":10,"output":10},"vision":true,"knowledge_cutoff":"2024-04","release_date":"2025-09-22"},"alibaba/qwen3-max":{"provider":"alibaba","id":"qwen3-max","name":"Qwen3 Max","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":1.2,"output":6},"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2025-09-23"},"alibaba/qwen3-next-80b-a3b-instruct":{"provider":"alibaba","id":"qwen3-next-80b-a3b-instruct","name":"Qwen3-Next 80B-A3B Instruct","family":"qwen","context_window":131072,"max_output":32768,"cost":{"input":0.5,"output":2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-09"},"alibaba/qwen3-next-80b-a3b-thinking":{"provider":"alibaba","id":"qwen3-next-80b-a3b-thinking","name":"Qwen3-Next 80B-A3B (Thinking)","family":"qwen","context_window":131072,"max_output":32768,"cost":{"input":0.5,"output":6},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-09"},"alibaba/qwen3-omni-flash":{"provider":"alibaba","id":"qwen3-omni-flash","name":"Qwen3-Omni Flash","family":"qwen","context_window":65536,"max_output":16384,"cost":{"input":0.43,"output":1.66},"reasoning":true,"tool_call":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2025-09-15"},"alibaba/qwen3-omni-flash-realtime":{"provider":"alibaba","id":"qwen3-omni-flash-realtime","name":"Qwen3-Omni Flash Realtime","family":"qwen","context_window":65536,"max_output":16384,"cost":{"input":0.52,"output":1.99},"tool_call":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2025-09-15"},"alibaba/qwen3-vl-235b-a22b":{"provider":"alibaba","id":"qwen3-vl-235b-a22b","name":"Qwen3-VL 235B-A22B","family":"qwen","context_window":131072,"max_output":32768,"cost":{"input":0.7,"output":2.8},"reasoning":true,"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-vl-30b-a3b":{"provider":"alibaba","id":"qwen3-vl-30b-a3b","name":"Qwen3-VL 30B-A3B","family":"qwen","context_window":131072,"max_output":32768,"cost":{"input":0.2,"output":0.8},"reasoning":true,"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"alibaba/qwen3-vl-plus":{"provider":"alibaba","id":"qwen3-vl-plus","name":"Qwen3-VL Plus","family":"qwen","context_window":262144,"max_output":32768,"cost":{"input":0.2,"output":1.6},"reasoning":true,"tool_call":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2025-09-23"},"alibaba/qwen3.5-122b-a10b":{"provider":"alibaba","id":"qwen3.5-122b-a10b","name":"Qwen3.5 122B-A10B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.4,"output":3.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"alibaba/qwen3.5-27b":{"provider":"alibaba","id":"qwen3.5-27b","name":"Qwen3.5 27B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.3,"output":2.4},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"alibaba/qwen3.5-35b-a3b":{"provider":"alibaba","id":"qwen3.5-35b-a3b","name":"Qwen3.5 35B-A3B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.25,"output":2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"alibaba/qwen3.5-397b-a17b":{"provider":"alibaba","id":"qwen3.5-397b-a17b","name":"Qwen3.5 397B-A17B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.6,"output":3.6},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-15"},"alibaba/qwen3.5-plus":{"provider":"alibaba","id":"qwen3.5-plus","name":"Qwen3.5 Plus","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.4,"output":2.4},"reasoning":true,"tool_call":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-02-16"},"alibaba/qwen3.6-27b":{"provider":"alibaba","id":"qwen3.6-27b","name":"Qwen3.6 27B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.6,"output":3.6},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-22"},"alibaba/qwen3.6-35b-a3b":{"provider":"alibaba","id":"qwen3.6-35b-a3b","name":"Qwen3.6 35B-A3B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.248,"output":1.485},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-17"},"alibaba/qwen3.6-flash":{"provider":"alibaba","id":"qwen3.6-flash","name":"Qwen3.6 Flash","family":"qwen3.6","context_window":1000000,"max_output":65536,"cost":{"input":0.1875,"output":1.125,"cache_write":0.234375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-04-27"},"alibaba/qwen3.6-max-preview":{"provider":"alibaba","id":"qwen3.6-max-preview","name":"Qwen3.6 Max Preview","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":1.3,"output":7.8,"cache_read":0.13,"cache_write":1.625},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2026-04-20"},"alibaba/qwen3.6-plus":{"provider":"alibaba","id":"qwen3.6-plus","name":"Qwen3.6 Plus","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.5,"output":3,"cache_read":0.05,"cache_write":0.625},"reasoning":true,"tool_call":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-04-02"},"alibaba/qwen3.7-max":{"provider":"alibaba","id":"qwen3.7-max","name":"Qwen3.7 Max","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":2.5,"output":7.5,"cache_read":0.5,"cache_write":3.125},"reasoning":true,"tool_call":true,"release_date":"2026-05-21"},"alibaba/qwen3.7-plus":{"provider":"alibaba","id":"qwen3.7-plus","name":"Qwen3.7 Plus","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.5,"output":3,"cache_read":0.05,"cache_write":0.625},"reasoning":true,"tool_call":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-06-02"},"alibaba/qwen3.8-flash":{"provider":"alibaba","id":"qwen3.8-flash","name":"Qwen3.8 Flash","family":"qwen","context_window":1000000,"max_output":131072,"cost":{"input":0.15,"output":0.47,"cache_read":0.016,"cache_write":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-26"},"alibaba/qwen3.8-max":{"provider":"alibaba","id":"qwen3.8-max","name":"Qwen3.8 Max","family":"qwen","context_window":1000000,"max_output":131072,"cost":{"input":2,"output":6,"cache_read":0.25,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-03"},"alibaba/qwq-plus":{"provider":"alibaba","id":"qwq-plus","name":"QwQ Plus","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.8,"output":2.4},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2024-04","release_date":"2025-03-05"},"anthropic/claude-fable-5":{"provider":"anthropic","id":"claude-fable-5","name":"Claude Fable 5","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-06-07"},"anthropic/claude-fable-5-1":{"provider":"anthropic","id":"claude-fable-5-1","name":"Claude Fable 5.1","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":0.25,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-06","release_date":"2026-09-01"},"anthropic/claude-haiku-4-5":{"provider":"anthropic","id":"claude-haiku-4-5","name":"Claude Haiku 4.5 (latest)","family":"claude-haiku","context_window":200000,"max_output":64000,"cost":{"input":1,"output":5,"cache_read":0.1,"cache_write":1.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-02-28","release_date":"2025-10-15"},"anthropic/claude-haiku-4-5-20251001":{"provider":"anthropic","id":"claude-haiku-4-5-20251001","name":"Claude Haiku 4.5","family":"claude-haiku","context_window":200000,"max_output":64000,"cost":{"input":1,"output":5,"cache_read":0.1,"cache_write":1.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-02-28","release_date":"2025-10-15"},"anthropic/claude-opus-4-5":{"provider":"anthropic","id":"claude-opus-4-5","name":"Claude Opus 4.5 (latest)","family":"claude-opus","context_window":200000,"max_output":64000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-05","release_date":"2025-11-24"},"anthropic/claude-opus-4-5-20251101":{"provider":"anthropic","id":"claude-opus-4-5-20251101","name":"Claude Opus 4.5","family":"claude-opus","context_window":200000,"max_output":64000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-05","release_date":"2025-11-24"},"anthropic/claude-opus-4-6":{"provider":"anthropic","id":"claude-opus-4-6","name":"Claude Opus 4.6","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-05-31","release_date":"2026-02-04"},"anthropic/claude-opus-4-7":{"provider":"anthropic","id":"claude-opus-4-7","name":"Claude Opus 4.7","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-04-14"},"anthropic/claude-opus-4-8":{"provider":"anthropic","id":"claude-opus-4-8","name":"Claude Opus 4.8","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01","release_date":"2026-05-28"},"anthropic/claude-opus-5":{"provider":"anthropic","id":"claude-opus-5","name":"Claude Opus 5","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-05","release_date":"2026-07-24"},"anthropic/claude-sonnet-4-5":{"provider":"anthropic","id":"claude-sonnet-4-5","name":"Claude Sonnet 4.5 (latest)","family":"claude-sonnet","context_window":1000000,"max_output":64000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-07-31","release_date":"2025-09-29"},"anthropic/claude-sonnet-4-5-20250929":{"provider":"anthropic","id":"claude-sonnet-4-5-20250929","name":"Claude Sonnet 4.5","family":"claude-sonnet","context_window":1000000,"max_output":64000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-07-31","release_date":"2025-09-29"},"anthropic/claude-sonnet-4-6":{"provider":"anthropic","id":"claude-sonnet-4-6","name":"Claude Sonnet 4.6","family":"claude-sonnet","context_window":1000000,"max_output":128000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-17"},"anthropic/claude-sonnet-5":{"provider":"anthropic","id":"claude-sonnet-5","name":"Claude Sonnet 5","family":"claude-sonnet","context_window":1000000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-06-29"},"cohere/c4ai-aya-expanse-32b":{"provider":"cohere","id":"c4ai-aya-expanse-32b","name":"Aya Expanse 32B","context_window":128000,"max_output":4000,"open_weights":true,"release_date":"2024-10-24"},"cohere/c4ai-aya-expanse-8b":{"provider":"cohere","id":"c4ai-aya-expanse-8b","name":"Aya Expanse 8B","context_window":8000,"max_output":4000,"open_weights":true,"release_date":"2024-10-24"},"cohere/c4ai-aya-vision-32b":{"provider":"cohere","id":"c4ai-aya-vision-32b","name":"Aya Vision 32B","context_window":16000,"max_output":4000,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-03-04"},"cohere/c4ai-aya-vision-8b":{"provider":"cohere","id":"c4ai-aya-vision-8b","name":"Aya Vision 8B","context_window":16000,"max_output":4000,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-03-04"},"cohere/command-a-03-2025":{"provider":"cohere","id":"command-a-03-2025","name":"Command A","family":"command-a","context_window":256000,"max_output":8000,"cost":{"input":2.5,"output":10},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2025-03-13"},"cohere/command-a-plus-05-2026":{"provider":"cohere","id":"command-a-plus-05-2026","name":"Command A Plus","family":"command-a","context_window":128000,"max_output":64000,"cost":{"input":2.5,"output":10},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-04-01","release_date":"2026-05-20"},"cohere/command-a-reasoning-08-2025":{"provider":"cohere","id":"command-a-reasoning-08-2025","name":"Command A Reasoning","family":"command-a","context_window":256000,"max_output":32000,"cost":{"input":2.5,"output":10},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2025-08-21"},"cohere/command-a-translate-08-2025":{"provider":"cohere","id":"command-a-translate-08-2025","name":"Command A Translate","family":"command-a","context_window":8000,"max_output":8000,"cost":{"input":2.5,"output":10},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2025-08-28"},"cohere/command-a-vision-07-2025":{"provider":"cohere","id":"command-a-vision-07-2025","name":"Command A Vision","family":"command-a","context_window":128000,"max_output":8000,"cost":{"input":2.5,"output":10},"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2025-07-31"},"cohere/command-r-08-2024":{"provider":"cohere","id":"command-r-08-2024","name":"Command R","family":"command-r","context_window":128000,"max_output":4000,"cost":{"input":0.15,"output":0.6},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2024-08-30"},"cohere/command-r-plus-08-2024":{"provider":"cohere","id":"command-r-plus-08-2024","name":"Command R+","family":"command-r","context_window":128000,"max_output":4000,"cost":{"input":2.5,"output":10},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2024-08-30"},"cohere/command-r7b-12-2024":{"provider":"cohere","id":"command-r7b-12-2024","name":"Command R7B","family":"command-r","context_window":128000,"max_output":4000,"cost":{"input":0.0375,"output":0.15},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2024-12-02"},"cohere/command-r7b-arabic-02-2025":{"provider":"cohere","id":"command-r7b-arabic-02-2025","name":"Command R7B Arabic","family":"command-r","context_window":128000,"max_output":4000,"cost":{"input":0.0375,"output":0.15},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2025-02-27"},"cohere/north-mini-code-1-0":{"provider":"cohere","id":"north-mini-code-1-0","name":"North Mini Code","family":"north","context_window":256000,"max_output":64000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-09-23","release_date":"2026-06-09"},"deepseek/deepseek-flash":{"provider":"deepseek","id":"deepseek-flash","name":"DeepSeek V4.1 Flash","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.15,"output":0.6,"cache_read":0.003},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-09-10"},"deepseek/deepseek-v4-flash":{"provider":"deepseek","id":"deepseek-v4-flash","name":"DeepSeek V4 Flash","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.15,"output":0.6,"cache_read":0.003},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-09-10"},"deepseek/deepseek-v4-flash-vision-exp":{"provider":"deepseek","id":"deepseek-v4-flash-vision-exp","name":"DeepSeek V4 Flash Vision Exp","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.15,"output":0.6,"cache_read":0.003},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-09-10"},"deepseek/deepseek-v4-pro":{"provider":"deepseek","id":"deepseek-v4-pro","name":"DeepSeek V4 Pro","family":"deepseek-thinking","context_window":1000000,"max_output":384000,"cost":{"input":0.435,"output":0.87,"cache_read":0.003625},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-12"},"fireworks-ai/accounts/fireworks/models/deepseek-v4-flash-0731":{"provider":"fireworks-ai","id":"accounts/fireworks/models/deepseek-v4-flash-0731","name":"DeepSeek V4 Flash 0731","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.22,"output":0.66,"cache_read":0.007},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-07-31"},"fireworks-ai/accounts/fireworks/models/deepseek-v4-flash-vision-exp":{"provider":"fireworks-ai","id":"accounts/fireworks/models/deepseek-v4-flash-vision-exp","name":"DeepSeek V4 Flash Vision Exp","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.22,"output":0.66,"cache_read":0.007},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-21"},"fireworks-ai/accounts/fireworks/models/deepseek-v4-pro-0813":{"provider":"fireworks-ai","id":"accounts/fireworks/models/deepseek-v4-pro-0813","name":"DeepSeek V4 Pro 0813","family":"deepseek-thinking","context_window":1000000,"max_output":384000,"cost":{"input":1.32,"output":3.96,"cache_read":0.044},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-12"},"fireworks-ai/accounts/fireworks/models/deepseek-v4p1-flash":{"provider":"fireworks-ai","id":"accounts/fireworks/models/deepseek-v4p1-flash","name":"DeepSeek V4.1 Flash","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.22,"output":0.66,"cache_read":0.007},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-09-10"},"fireworks-ai/accounts/fireworks/models/glm-5p2":{"provider":"fireworks-ai","id":"accounts/fireworks/models/glm-5p2","name":"GLM 5.2","family":"glm","context_window":1048575,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.14},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-16"},"fireworks-ai/accounts/fireworks/models/glm-5p3":{"provider":"fireworks-ai","id":"accounts/fireworks/models/glm-5p3","name":"GLM 5.3","family":"glm","context_window":1048573,"max_output":262144,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-14"},"fireworks-ai/accounts/fireworks/models/glm-5p3-flash":{"provider":"fireworks-ai","id":"accounts/fireworks/models/glm-5p3-flash","name":"GLM 5.3 Flash","family":"glm","context_window":1048573,"max_output":131072,"cost":{"input":0.15,"output":0.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-08-26"},"fireworks-ai/accounts/fireworks/models/gpt-oss-120b":{"provider":"fireworks-ai","id":"accounts/fireworks/models/gpt-oss-120b","name":"GPT OSS 120B","family":"gpt-oss","context_window":131072,"max_output":32768,"cost":{"input":0.15,"output":0.6,"cache_read":0.015},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-08-05"},"fireworks-ai/accounts/fireworks/models/inkling":{"provider":"fireworks-ai","id":"accounts/fireworks/models/inkling","name":"Inkling","family":"ling","context_window":1048576,"max_output":1048576,"cost":{"input":1,"output":4.05,"cache_read":0.17},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-15"},"fireworks-ai/accounts/fireworks/models/kimi-k2p6":{"provider":"fireworks-ai","id":"accounts/fireworks/models/kimi-k2p6","name":"Kimi K2.6","family":"kimi-thinking","context_window":262000,"max_output":262000,"cost":{"input":0.95,"output":4,"cache_read":0.16},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-17"},"fireworks-ai/accounts/fireworks/models/kimi-k2p7-code":{"provider":"fireworks-ai","id":"accounts/fireworks/models/kimi-k2p7-code","name":"Kimi K2.7 Code","family":"kimi-k2","context_window":262000,"max_output":262000,"cost":{"input":0.95,"output":4,"cache_read":0.19},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-12"},"fireworks-ai/accounts/fireworks/models/kimi-k3":{"provider":"fireworks-ai","id":"accounts/fireworks/models/kimi-k3","name":"Kimi K3","family":"kimi-k3","context_window":1048576,"max_output":131072,"cost":{"input":3,"output":15,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-27"},"fireworks-ai/accounts/fireworks/models/minimax-m3":{"provider":"fireworks-ai","id":"accounts/fireworks/models/minimax-m3","name":"MiniMax-M3","family":"minimax","context_window":512000,"max_output":512000,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-12"},"fireworks-ai/accounts/fireworks/models/mistral-large-3-fp8":{"provider":"fireworks-ai","id":"accounts/fireworks/models/mistral-large-3-fp8","name":"Mistral Large 3 675B Instruct 2512","family":"mistral-large","context_window":262144,"max_output":262144,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-11","release_date":"2025-12-02"},"fireworks-ai/accounts/fireworks/models/muse-glimmer-30b":{"provider":"fireworks-ai","id":"accounts/fireworks/models/muse-glimmer-30b","name":"Muse Glimmer 30B","family":"muse","context_window":131072,"max_output":131072,"cost":{"input":0.35,"output":1.5,"cache_read":0.04},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2026-01-04","release_date":"2026-08-10"},"fireworks-ai/accounts/fireworks/models/nemotron-3-ultra-nvfp4":{"provider":"fireworks-ai","id":"accounts/fireworks/models/nemotron-3-ultra-nvfp4","name":"Nemotron 3 Ultra 550B A55B","family":"nemotron","context_window":262144,"max_output":128000,"cost":{"input":0.6,"output":2.4,"cache_read":0.12},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-04"},"fireworks-ai/accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b":{"provider":"fireworks-ai","id":"accounts/fireworks/models/nemotron-lightning-3p5-30b-a3b","name":"Nemotron 3.5 Lightning 30B A3B","family":"nemotron","context_window":262144,"max_output":262144,"cost":{"input":0.05,"output":0.2,"cache_read":0.01},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-11"},"fireworks-ai/accounts/fireworks/models/qwen3p7-plus":{"provider":"fireworks-ai","id":"accounts/fireworks/models/qwen3p7-plus","name":"Qwen 3.7 Plus","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.4,"output":1.6,"cache_read":0.08},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-06-12"},"fireworks-ai/accounts/fireworks/models/qwen3p8-2p4t-a95b":{"provider":"fireworks-ai","id":"accounts/fireworks/models/qwen3p8-2p4t-a95b","name":"Qwen3.8 2.4T A95B","family":"qwen","context_window":262144,"max_output":131072,"cost":{"input":2,"output":6,"cache_read":0.25},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-12"},"fireworks-ai/accounts/fireworks/models/qwen3p8-max":{"provider":"fireworks-ai","id":"accounts/fireworks/models/qwen3p8-max","name":"Qwen3.8 Max","family":"qwen","context_window":262144,"max_output":131072,"cost":{"input":2,"output":6,"cache_read":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-03"},"fireworks-ai/accounts/fireworks/routers/glm-5p2-fast":{"provider":"fireworks-ai","id":"accounts/fireworks/routers/glm-5p2-fast","name":"GLM 5.2 Fast","family":"glm","context_window":1048575,"max_output":131072,"cost":{"input":2.1,"output":6.6,"cache_read":0.21},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-26"},"fireworks-ai/accounts/fireworks/routers/glm-5p3-fast":{"provider":"fireworks-ai","id":"accounts/fireworks/routers/glm-5p3-fast","name":"GLM 5.3 Fast","family":"glm","context_window":1048572,"max_output":262144,"cost":{"input":2.1,"output":6.6,"cache_read":0.39},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-28"},"fireworks-ai/accounts/fireworks/routers/kimi-k3-fast":{"provider":"fireworks-ai","id":"accounts/fireworks/routers/kimi-k3-fast","name":"Kimi K3 Fast","family":"kimi-k3","context_window":1048576,"max_output":131072,"cost":{"input":4.5,"output":22.5,"cache_read":0.45},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-27"},"github-copilot/claude-fable-5":{"provider":"github-copilot","id":"claude-fable-5","name":"Claude Fable 5","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-06-09"},"github-copilot/claude-fable-5.1":{"provider":"github-copilot","id":"claude-fable-5.1","name":"Claude Fable 5.1","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":0.25,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-06","release_date":"2026-09-01"},"github-copilot/claude-haiku-4.5":{"provider":"github-copilot","id":"claude-haiku-4.5","name":"Claude Haiku 4.5 (latest)","family":"claude-haiku","context_window":200000,"max_output":64000,"cost":{"input":1,"output":5,"cache_read":0.1,"cache_write":1.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-02-28","release_date":"2025-10-15"},"github-copilot/claude-opus-4.7":{"provider":"github-copilot","id":"claude-opus-4.7","name":"Claude Opus 4.7","family":"claude-opus","context_window":200000,"max_output":32000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-04-16"},"github-copilot/claude-opus-4.8":{"provider":"github-copilot","id":"claude-opus-4.8","name":"Claude Opus 4.8","family":"claude-opus","context_window":200000,"max_output":64000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01","release_date":"2026-05-28"},"github-copilot/claude-opus-5":{"provider":"github-copilot","id":"claude-opus-5","name":"Claude Opus 5","family":"claude-opus","context_window":1000000,"max_output":64000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-05","release_date":"2026-07-24"},"github-copilot/claude-sonnet-4.6":{"provider":"github-copilot","id":"claude-sonnet-4.6","name":"Claude Sonnet 4.6","family":"claude-sonnet","context_window":200000,"max_output":32000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-17"},"github-copilot/claude-sonnet-5":{"provider":"github-copilot","id":"claude-sonnet-5","name":"Claude Sonnet 5","family":"claude-sonnet","context_window":1000000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-06-30"},"github-copilot/gemini-3.5-flash":{"provider":"github-copilot","id":"gemini-3.5-flash","name":"Gemini 3.5 Flash","family":"gemini-flash","context_window":200000,"max_output":64000,"cost":{"input":1.5,"output":9,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-19"},"github-copilot/gemini-3.6-flash":{"provider":"github-copilot","id":"gemini-3.6-flash","name":"Gemini 3.6 Flash","family":"gemini-flash","context_window":1000000,"max_output":64000,"cost":{"input":0.75,"output":3.75,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"github-copilot/gemini-3.7-flash":{"provider":"github-copilot","id":"gemini-3.7-flash","name":"Gemini 3.7 Flash","family":"gemini-flash","context_window":1000000,"max_output":64000,"cost":{"input":0.75,"output":3.75,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2026-03","release_date":"2026-08-13"},"github-copilot/gemini-3.8-flash":{"provider":"github-copilot","id":"gemini-3.8-flash","name":"Gemini 3.8 Flash","family":"gemini-flash","context_window":1000000,"max_output":64000,"cost":{"input":0.75,"output":3.75,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-09-02"},"github-copilot/gpt-5-mini":{"provider":"github-copilot","id":"gpt-5-mini","name":"GPT-5 Mini","family":"gpt-mini","context_window":264000,"max_output":64000,"cost":{"input":0.25,"output":2,"cache_read":0.025},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-05-30","release_date":"2025-08-07"},"github-copilot/gpt-5.3-codex":{"provider":"github-copilot","id":"gpt-5.3-codex","name":"GPT-5.3 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-05"},"github-copilot/gpt-5.4":{"provider":"github-copilot","id":"gpt-5.4","name":"GPT-5.4","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":2.5,"output":15,"cache_read":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-05"},"github-copilot/gpt-5.4-mini":{"provider":"github-copilot","id":"gpt-5.4-mini","name":"GPT-5.4 mini","family":"gpt-mini","context_window":400000,"max_output":128000,"cost":{"input":0.75,"output":4.5,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"github-copilot/gpt-5.4-nano":{"provider":"github-copilot","id":"gpt-5.4-nano","name":"GPT-5.4 nano","family":"gpt-nano","context_window":400000,"max_output":128000,"cost":{"input":0.2,"output":1.25,"cache_read":0.02},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"github-copilot/gpt-5.5":{"provider":"github-copilot","id":"gpt-5.5","name":"GPT-5.5","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":5,"output":30,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-12-01","release_date":"2026-04-23"},"github-copilot/gpt-5.6-luna":{"provider":"github-copilot","id":"gpt-5.6-luna","name":"GPT-5.6 Luna","family":"gpt-luna","context_window":1050000,"max_output":128000,"cost":{"input":0.2,"output":1.2,"cache_read":0.02,"cache_write":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"github-copilot/gpt-5.6-sol":{"provider":"github-copilot","id":"gpt-5.6-sol","name":"GPT-5.6 Sol","family":"gpt-sol","context_window":1050000,"max_output":128000,"cost":{"input":4,"output":20,"cache_read":0.4,"cache_write":5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"github-copilot/gpt-5.6-terra":{"provider":"github-copilot","id":"gpt-5.6-terra","name":"GPT-5.6 Terra","family":"gpt-terra","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"github-copilot/gpt-6-astra":{"provider":"github-copilot","id":"gpt-6-astra","name":"GPT-6 Astra","family":"gpt-astra","context_window":1050000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-04-30","release_date":"2026-09-04"},"github-copilot/grok-4.5":{"provider":"github-copilot","id":"grok-4.5","name":"Grok 4.5","family":"grok","context_window":500000,"max_output":128000,"cost":{"input":2,"output":6,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-07-08"},"github-copilot/grok-4.6":{"provider":"github-copilot","id":"grok-4.6","name":"Grok 4.6","family":"grok","context_window":500000,"max_output":128000,"cost":{"input":2,"output":6,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2026-02-01","release_date":"2026-08-12"},"github-copilot/kimi-k2.7-code":{"provider":"github-copilot","id":"kimi-k2.7-code","name":"Kimi K2.7 Code","family":"kimi-k2","context_window":256000,"max_output":32000,"cost":{"input":0.95,"output":4,"cache_read":0.19},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-06-12"},"github-copilot/kimi-k3":{"provider":"github-copilot","id":"kimi-k3","name":"Kimi K3","family":"kimi-k3","context_window":1048576,"max_output":131072,"cost":{"input":3,"output":15,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-16"},"github-copilot/mai-code-1-flash-picker":{"provider":"github-copilot","id":"mai-code-1-flash-picker","name":"MAI-Code-1-Flash","family":"mai","context_window":256000,"max_output":128000,"cost":{"input":0.75,"output":4.5,"cache_read":0.075},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2025-12","release_date":"2026-06-02"},"github-copilot/mai-code-1.1-flash":{"provider":"github-copilot","id":"mai-code-1.1-flash","name":"MAI-Code-1.1-Flash","family":"mai","context_window":256000,"max_output":128000,"cost":{"input":0.2,"output":1.2,"cache_read":0.02},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-11"},"google/deep-research-max-preview-04-2026":{"provider":"google","id":"deep-research-max-preview-04-2026","name":"Deep Research Max Preview (Apr-21-2026)","family":"gemini-pro","context_window":131072,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-21"},"google/deep-research-preview-04-2026":{"provider":"google","id":"deep-research-preview-04-2026","name":"Deep Research Preview (Apr-21-2026)","family":"gemini-pro","context_window":131072,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-21"},"google/gemini-2.5-computer-use-preview-10-2025":{"provider":"google","id":"gemini-2.5-computer-use-preview-10-2025","name":"Gemini 2.5 Computer Use Preview 10-2025","family":"gemini-pro","context_window":131072,"max_output":65536,"cost":{"input":1.25,"output":10},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2025-10-07"},"google/gemini-2.5-flash":{"provider":"google","id":"gemini-2.5-flash","name":"Gemini 2.5 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.3,"output":2.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-06-17"},"google/gemini-2.5-flash-image":{"provider":"google","id":"gemini-2.5-flash-image","name":"Nano Banana","family":"gemini-flash","context_window":32768,"max_output":32768,"cost":{"input":0.3,"output":30,"cache_read":0.075},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-06","release_date":"2025-08-26"},"google/gemini-2.5-flash-lite":{"provider":"google","id":"gemini-2.5-flash-lite","name":"Gemini 2.5 Flash-Lite","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.1,"output":0.4,"cache_read":0.01},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-06-17"},"google/gemini-2.5-flash-preview-tts":{"provider":"google","id":"gemini-2.5-flash-preview-tts","name":"Gemini 2.5 Flash Preview TTS","family":"gemini-flash","context_window":8192,"max_output":16384,"cost":{"input":0.5,"output":10},"knowledge_cutoff":"2025-01","release_date":"2025-05-01"},"google/gemini-2.5-pro":{"provider":"google","id":"gemini-2.5-pro","name":"Gemini 2.5 Pro","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":1.25,"output":10,"cache_read":0.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-06-17"},"google/gemini-2.5-pro-preview-tts":{"provider":"google","id":"gemini-2.5-pro-preview-tts","name":"Gemini 2.5 Pro Preview TTS","family":"gemini-flash","context_window":8192,"max_output":16384,"cost":{"input":1,"output":20},"knowledge_cutoff":"2025-01","release_date":"2025-05-01"},"google/gemini-3-flash-preview":{"provider":"google","id":"gemini-3-flash-preview","name":"Gemini 3 Flash Preview","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.5,"output":3,"cache_read":0.05},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-12-17"},"google/gemini-3-pro-image":{"provider":"google","id":"gemini-3-pro-image","name":"Nano Banana Pro","family":"gemini-pro","context_window":131072,"max_output":32768,"cost":{"input":2,"output":120},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-28"},"google/gemini-3-pro-image-preview":{"provider":"google","id":"gemini-3-pro-image-preview","name":"Nano Banana Pro","family":"gemini-pro","context_window":131072,"max_output":32768,"cost":{"input":2,"output":120},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2025-11-20"},"google/gemini-3.1-flash-image":{"provider":"google","id":"gemini-3.1-flash-image","name":"Nano Banana 2","family":"gemini-flash","context_window":65536,"max_output":65536,"cost":{"input":0.5,"output":60},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-28"},"google/gemini-3.1-flash-image-preview":{"provider":"google","id":"gemini-3.1-flash-image-preview","name":"Nano Banana 2","family":"gemini-flash","context_window":65536,"max_output":65536,"cost":{"input":0.5,"output":60},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-26"},"google/gemini-3.1-flash-lite":{"provider":"google","id":"gemini-3.1-flash-lite","name":"Gemini 3.1 Flash Lite","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.25,"output":1.5,"cache_read":0.025},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-07"},"google/gemini-3.1-flash-lite-image":{"provider":"google","id":"gemini-3.1-flash-lite-image","name":"Nano Banana 2 Lite","family":"gemini-flash-lite","context_window":65536,"max_output":65536,"cost":{"input":0.25,"output":30},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2026-06-30"},"google/gemini-3.1-flash-lite-preview":{"provider":"google","id":"gemini-3.1-flash-lite-preview","name":"Gemini 3.1 Flash Lite Preview","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.25,"output":1.5,"cache_read":0.025},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-03-03"},"google/gemini-3.1-flash-live-preview":{"provider":"google","id":"gemini-3.1-flash-live-preview","name":"Gemini 3.1 Flash Live Preview","family":"gemini-flash","context_window":131072,"max_output":65536,"cost":{"input":0.75,"output":4.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2026-03-26"},"google/gemini-3.1-flash-tts-preview":{"provider":"google","id":"gemini-3.1-flash-tts-preview","name":"Gemini 3.1 Flash TTS Preview","family":"gemini-flash","context_window":8192,"max_output":16384,"cost":{"input":1,"output":20},"reasoning":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-15"},"google/gemini-3.1-pro-preview":{"provider":"google","id":"gemini-3.1-pro-preview","name":"Gemini 3.1 Pro Preview","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-19"},"google/gemini-3.1-pro-preview-customtools":{"provider":"google","id":"gemini-3.1-pro-preview-customtools","name":"Gemini 3.1 Pro Preview Custom Tools","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-19"},"google/gemini-3.5-flash":{"provider":"google","id":"gemini-3.5-flash","name":"Gemini 3.5 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":1.5,"output":9,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-19"},"google/gemini-3.5-flash-lite":{"provider":"google","id":"gemini-3.5-flash-lite","name":"Gemini 3.5 Flash Lite","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.3,"output":2.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"google/gemini-3.5-live-translate-preview":{"provider":"google","id":"gemini-3.5-live-translate-preview","name":"Gemini 3.5 Live Translate Preview","family":"gemini-pro","context_window":16384,"max_output":32768,"cost":{"input":3.5,"output":21},"knowledge_cutoff":"2025-01","release_date":"2026-06-09"},"google/gemini-3.6-flash":{"provider":"google","id":"gemini-3.6-flash","name":"Gemini 3.6 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"google/gemini-3.7-flash":{"provider":"google","id":"gemini-3.7-flash","name":"Gemini 3.7 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-08-13"},"google/gemini-3.8-flash":{"provider":"google","id":"gemini-3.8-flash","name":"Gemini 3.8 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-02"},"google/gemini-embedding-001":{"provider":"google","id":"gemini-embedding-001","name":"Gemini Embedding 001","family":"gemini","context_window":2048,"max_output":1,"cost":{"input":0.15},"knowledge_cutoff":"2025-05","release_date":"2025-05-20"},"google/gemini-embedding-2":{"provider":"google","id":"gemini-embedding-2","name":"Gemini Embedding 2","family":"gemini","context_window":8192,"max_output":1,"cost":{"input":0.2},"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-11","release_date":"2026-04-22"},"google/gemini-flash-latest":{"provider":"google","id":"gemini-flash-latest","name":"Gemini Flash Latest","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-08-13"},"google/gemini-flash-lite-latest":{"provider":"google","id":"gemini-flash-lite-latest","name":"Gemini Flash-Lite Latest","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.3,"output":2.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"google/gemini-omni-flash-preview":{"provider":"google","id":"gemini-omni-flash-preview","name":"Gemini Omni Flash Preview","family":"gemini","context_window":131072,"max_output":65536,"cost":{"input":1.5,"output":17.5},"reasoning":true,"attachment":true,"vision":true,"release_date":"2026-06-30"},"google/gemma-4-26b-a4b-it":{"provider":"google","id":"gemma-4-26b-a4b-it","name":"Gemma 4 26B A4B IT","family":"gemma","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-02"},"google/gemma-4-31b-it":{"provider":"google","id":"gemma-4-31b-it","name":"Gemma 4 31B IT","family":"gemma","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-02"},"google/lyria-3-clip-preview":{"provider":"google","id":"lyria-3-clip-preview","name":"Lyria 3 Clip Preview","family":"lyria","context_window":1048576,"max_output":65536,"attachment":true,"vision":true,"release_date":"2026-03-25"},"google/lyria-3-pro-preview":{"provider":"google","id":"lyria-3-pro-preview","name":"Lyria 3 Pro Preview","family":"lyria","context_window":1048576,"max_output":65536,"attachment":true,"vision":true,"release_date":"2026-03-25"},"google/veo-3.1-fast-generate-preview":{"provider":"google","id":"veo-3.1-fast-generate-preview","name":"Veo 3.1 fast","family":"veo","context_window":480,"max_output":8192,"attachment":true,"vision":true,"release_date":"2025-10-15"},"google/veo-3.1-generate-preview":{"provider":"google","id":"veo-3.1-generate-preview","name":"Veo 3.1","family":"veo","context_window":480,"max_output":8192,"attachment":true,"vision":true,"release_date":"2025-10-15"},"google/veo-3.1-lite-generate-preview":{"provider":"google","id":"veo-3.1-lite-generate-preview","name":"Veo 3.1 lite","family":"veo","context_window":480,"max_output":8192,"attachment":true,"vision":true,"release_date":"2026-03-31"},"groq/allam-2-7b":{"provider":"groq","id":"allam-2-7b","name":"ALLaM-2-7b","context_window":4096,"max_output":4096,"open_weights":true,"release_date":"2025-01-23"},"groq/canopylabs/orpheus-arabic-saudi":{"provider":"groq","id":"canopylabs/orpheus-arabic-saudi","name":"Canopy Labs Orpheus Arabic Saudi","family":"canopylabs","context_window":4000,"max_output":50000,"release_date":"2025-12-16"},"groq/canopylabs/orpheus-v1-english":{"provider":"groq","id":"canopylabs/orpheus-v1-english","name":"Canopy Labs Orpheus V1 English","family":"canopylabs","context_window":4000,"max_output":50000,"release_date":"2025-12-19"},"groq/compound":{"provider":"groq","id":"compound","name":"Compound","family":"groq","context_window":131072,"max_output":8192,"release_date":"2025-09-04"},"groq/compound-mini":{"provider":"groq","id":"compound-mini","name":"Compound Mini","family":"groq","context_window":131072,"max_output":8192,"release_date":"2025-09-04"},"groq/llama-3.1-8b-instant":{"provider":"groq","id":"llama-3.1-8b-instant","name":"Llama 3.1 8B","family":"llama","context_window":131072,"max_output":131072,"cost":{"input":0.05,"output":0.08},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-07-23"},"groq/llama-3.3-70b-versatile":{"provider":"groq","id":"llama-3.3-70b-versatile","name":"Llama 3.3 70B","family":"llama","context_window":131072,"max_output":32768,"cost":{"input":0.59,"output":0.79},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-12-06"},"groq/meta-llama/llama-prompt-guard-2-22m":{"provider":"groq","id":"meta-llama/llama-prompt-guard-2-22m","name":"Llama Prompt Guard 2 22M","family":"llama","context_window":512,"max_output":512,"cost":{"input":0.03,"output":0.03},"open_weights":true,"release_date":"2025-05-29"},"groq/meta-llama/llama-prompt-guard-2-86m":{"provider":"groq","id":"meta-llama/llama-prompt-guard-2-86m","name":"Prompt Guard 2 86M","family":"llama","context_window":512,"max_output":512,"cost":{"input":0.04,"output":0.04},"open_weights":true,"release_date":"2025-05-29"},"groq/openai/gpt-oss-120b":{"provider":"groq","id":"openai/gpt-oss-120b","name":"GPT OSS 120B","family":"gpt-oss","context_window":131072,"max_output":65536,"cost":{"input":0.15,"output":0.6,"cache_read":0.075},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-08-05"},"groq/openai/gpt-oss-20b":{"provider":"groq","id":"openai/gpt-oss-20b","name":"GPT OSS 20B","family":"gpt-oss","context_window":131072,"max_output":65536,"cost":{"input":0.075,"output":0.3,"cache_read":0.0375},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-08-05"},"groq/openai/gpt-oss-safeguard-20b":{"provider":"groq","id":"openai/gpt-oss-safeguard-20b","name":"Safety GPT OSS 20B","family":"gpt-oss","context_window":131072,"max_output":65536,"cost":{"input":0.075,"output":0.3},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-10-29"},"groq/qwen/qwen3.6-27b":{"provider":"groq","id":"qwen/qwen3.6-27b","name":"Qwen3.6 27B","family":"qwen","context_window":131072,"max_output":16384,"cost":{"input":0.6,"output":3,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-22"},"groq/qwen/qwen3.8-27b":{"provider":"groq","id":"qwen/qwen3.8-27b","name":"Qwen3.8 27B","family":"qwen","context_window":131042,"max_output":16384,"cost":{"input":0.8,"output":4},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-08-14"},"groq/whisper-large-v3":{"provider":"groq","id":"whisper-large-v3","name":"Whisper","family":"whisper","open_weights":true,"release_date":"2023-09-01"},"groq/whisper-large-v3-turbo":{"provider":"groq","id":"whisper-large-v3-turbo","name":"Whisper Large V3 Turbo","family":"whisper","open_weights":true,"release_date":"2024-10-01"},"kimi-for-coding/k3":{"provider":"kimi-for-coding","id":"k3","name":"Kimi K3","family":"kimi-k3","context_window":1048576,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-16"},"kimi-for-coding/k3-256k":{"provider":"kimi-for-coding","id":"k3-256k","name":"Kimi K3-256K","family":"kimi-k3","context_window":262144,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-16"},"kimi-for-coding/kimi-for-coding":{"provider":"kimi-for-coding","id":"kimi-for-coding","family":"kimi-k2","context_window":1048576,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-09-11"},"kimi-for-coding/kimi-for-coding-highspeed":{"provider":"kimi-for-coding","id":"kimi-for-coding-highspeed","name":"Kimi For Coding HighSpeed","family":"kimi-k2","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-06-12"},"minimax/MiniMax-M2":{"provider":"minimax","id":"MiniMax-M2","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-10-27"},"minimax/MiniMax-M2.1":{"provider":"minimax","id":"MiniMax-M2.1","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.03,"cache_write":0.375},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-12-23"},"minimax/MiniMax-M2.5":{"provider":"minimax","id":"MiniMax-M2.5","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.03,"cache_write":0.375},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-12"},"minimax/MiniMax-M2.5-highspeed":{"provider":"minimax","id":"MiniMax-M2.5-highspeed","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.6,"output":2.4,"cache_read":0.06,"cache_write":0.375},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-13"},"minimax/MiniMax-M2.7":{"provider":"minimax","id":"MiniMax-M2.7","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.06,"cache_write":0.375},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-03-18"},"minimax/MiniMax-M2.7-highspeed":{"provider":"minimax","id":"MiniMax-M2.7-highspeed","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.6,"output":2.4,"cache_read":0.06,"cache_write":0.375},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-03-18"},"minimax/MiniMax-M3":{"provider":"minimax","id":"MiniMax-M3","family":"minimax","context_window":1048576,"max_output":512000,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-01"},"mistral/codestral-latest":{"provider":"mistral","id":"codestral-latest","name":"Codestral (latest)","family":"codestral","context_window":256000,"max_output":4096,"cost":{"input":0.3,"output":0.9},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2024-05-29"},"mistral/devstral-2512":{"provider":"mistral","id":"devstral-2512","name":"Devstral 2","family":"devstral","context_window":262144,"max_output":262144,"cost":{"input":0.4,"output":2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-12","release_date":"2025-12-09"},"mistral/devstral-latest":{"provider":"mistral","id":"devstral-latest","name":"Devstral 2","family":"devstral","context_window":262144,"max_output":262144,"cost":{"input":0.4,"output":2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-12","release_date":"2025-12-09"},"mistral/devstral-medium-2507":{"provider":"mistral","id":"devstral-medium-2507","name":"Devstral Medium","family":"devstral","context_window":128000,"max_output":128000,"cost":{"input":0.4,"output":2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2025-07-10"},"mistral/devstral-medium-latest":{"provider":"mistral","id":"devstral-medium-latest","name":"Devstral 2 (latest)","family":"devstral","context_window":262144,"max_output":262144,"cost":{"input":0.4,"output":2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-12","release_date":"2025-12-02"},"mistral/devstral-small-2505":{"provider":"mistral","id":"devstral-small-2505","name":"Devstral Small 2505","family":"devstral","context_window":128000,"max_output":128000,"cost":{"input":0.1,"output":0.3},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2025-05-07"},"mistral/devstral-small-2507":{"provider":"mistral","id":"devstral-small-2507","name":"Devstral Small","family":"devstral","context_window":128000,"max_output":128000,"cost":{"input":0.1,"output":0.3},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2025-07-10"},"mistral/labs-devstral-small-2512":{"provider":"mistral","id":"labs-devstral-small-2512","name":"Devstral Small 2","family":"devstral","context_window":256000,"max_output":256000,"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-12","release_date":"2025-12-09"},"mistral/magistral-medium-latest":{"provider":"mistral","id":"magistral-medium-latest","name":"Magistral Medium (latest)","family":"magistral-medium","context_window":128000,"max_output":16384,"cost":{"input":2,"output":5},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2025-03-17"},"mistral/magistral-small":{"provider":"mistral","id":"magistral-small","name":"Magistral Small","family":"magistral-small","context_window":128000,"max_output":128000,"cost":{"input":0.5,"output":1.5},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2025-03-17"},"mistral/ministral-3b-latest":{"provider":"mistral","id":"ministral-3b-latest","name":"Ministral 3B (latest)","family":"ministral","context_window":128000,"max_output":128000,"cost":{"input":0.04,"output":0.04},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2024-10-01"},"mistral/ministral-8b-latest":{"provider":"mistral","id":"ministral-8b-latest","name":"Ministral 8B (latest)","family":"ministral","context_window":128000,"max_output":128000,"cost":{"input":0.1,"output":0.1},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2024-10-01"},"mistral/mistral-embed":{"provider":"mistral","id":"mistral-embed","name":"Mistral Embed","family":"mistral-embed","context_window":8000,"max_output":3072,"cost":{"input":0.1},"release_date":"2023-12-11"},"mistral/mistral-large-2411":{"provider":"mistral","id":"mistral-large-2411","name":"Mistral Large 2.1","family":"mistral-large","context_window":131072,"max_output":16384,"cost":{"input":2,"output":6},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-11","release_date":"2024-11-18"},"mistral/mistral-large-2512":{"provider":"mistral","id":"mistral-large-2512","name":"Mistral Large 3","family":"mistral-large","context_window":262144,"max_output":262144,"cost":{"input":0.5,"output":1.5},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-11","release_date":"2024-11-01"},"mistral/mistral-large-latest":{"provider":"mistral","id":"mistral-large-latest","name":"Mistral Large (latest)","family":"mistral-large","context_window":262144,"max_output":262144,"cost":{"input":0.5,"output":1.5},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-11","release_date":"2024-11-01"},"mistral/mistral-medium-2505":{"provider":"mistral","id":"mistral-medium-2505","name":"Mistral Medium 3","family":"mistral-medium","context_window":131072,"max_output":131072,"cost":{"input":0.4,"output":2},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-05","release_date":"2025-05-07"},"mistral/mistral-medium-2508":{"provider":"mistral","id":"mistral-medium-2508","name":"Mistral Medium 3.1","family":"mistral-medium","context_window":262144,"max_output":262144,"cost":{"input":0.4,"output":2},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-05","release_date":"2025-08-12"},"mistral/mistral-medium-2604":{"provider":"mistral","id":"mistral-medium-2604","name":"Mistral Medium 3.5","family":"mistral-medium","context_window":262144,"max_output":262144,"cost":{"input":1.5,"output":7.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-29"},"mistral/mistral-medium-latest":{"provider":"mistral","id":"mistral-medium-latest","name":"Mistral Medium (latest)","family":"mistral-medium","context_window":262144,"max_output":262144,"cost":{"input":1.5,"output":7.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-29"},"mistral/mistral-nemo":{"provider":"mistral","id":"mistral-nemo","name":"Mistral Nemo","family":"mistral-nemo","context_window":128000,"max_output":128000,"cost":{"input":0.15,"output":0.15},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2024-07-01"},"mistral/mistral-small-2506":{"provider":"mistral","id":"mistral-small-2506","name":"Mistral Small 3.2","family":"mistral-small","context_window":128000,"max_output":16384,"cost":{"input":0.1,"output":0.3},"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-03","release_date":"2025-06-20"},"mistral/mistral-small-2603":{"provider":"mistral","id":"mistral-small-2603","name":"Mistral Small 4","family":"mistral-small","context_window":256000,"max_output":256000,"cost":{"input":0.15,"output":0.6},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-03-16"},"mistral/mistral-small-latest":{"provider":"mistral","id":"mistral-small-latest","name":"Mistral Small (latest)","family":"mistral-small","context_window":256000,"max_output":256000,"cost":{"input":0.15,"output":0.6},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-03-16"},"mistral/open-mistral-7b":{"provider":"mistral","id":"open-mistral-7b","name":"Mistral 7B","family":"mistral","context_window":8000,"max_output":8000,"cost":{"input":0.25,"output":0.25},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2023-09-27"},"mistral/open-mistral-nemo":{"provider":"mistral","id":"open-mistral-nemo","name":"Open Mistral Nemo","family":"mistral-nemo","context_window":128000,"max_output":128000,"cost":{"input":0.15,"output":0.15},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2024-07-01"},"mistral/open-mixtral-8x22b":{"provider":"mistral","id":"open-mixtral-8x22b","name":"Mixtral 8x22B","family":"mixtral","context_window":64000,"max_output":64000,"cost":{"input":2,"output":6},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2024-04-17"},"mistral/open-mixtral-8x7b":{"provider":"mistral","id":"open-mixtral-8x7b","name":"Mixtral 8x7B","family":"mixtral","context_window":32000,"max_output":32000,"cost":{"input":0.7,"output":0.7},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-01","release_date":"2023-12-11"},"mistral/pixtral-12b":{"provider":"mistral","id":"pixtral-12b","name":"Pixtral 12B","family":"pixtral","context_window":128000,"max_output":128000,"cost":{"input":0.15,"output":0.15},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-09","release_date":"2024-09-01"},"mistral/pixtral-large-latest":{"provider":"mistral","id":"pixtral-large-latest","name":"Pixtral Large (latest)","family":"pixtral","context_window":128000,"max_output":128000,"cost":{"input":2,"output":6},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-11","release_date":"2024-11-01"},"mistral/voxtral-mini-latest":{"provider":"mistral","id":"voxtral-mini-latest","name":"Voxtral Mini (latest)","family":"voxtral","release_date":"2026-02-01"},"mistral/voxtral-mini-tts-latest":{"provider":"mistral","id":"voxtral-mini-tts-latest","name":"Voxtral Mini TTS (latest)","family":"voxtral","release_date":"2026-03-01"},"mistral/voxtral-small-latest":{"provider":"mistral","id":"voxtral-small-latest","name":"Voxtral Small (latest)","family":"voxtral","context_window":32000,"max_output":32000,"cost":{"input":0.1,"output":0.3},"tool_call":true,"attachment":true,"open_weights":true,"release_date":"2025-07-15"},"mistral/zai-glm-5-2":{"provider":"mistral","id":"zai-glm-5-2","name":"GLM-5.2","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.14},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-13"},"nvidia/abacusai/dracarys-llama-3.1-70b-instruct":{"provider":"nvidia","id":"abacusai/dracarys-llama-3.1-70b-instruct","name":"dracarys-llama-3.1-70b-instruct","context_window":128000,"max_output":8192,"tool_call":true,"open_weights":true,"release_date":"2024-09-11"},"nvidia/active-speaker-detection":{"provider":"nvidia","id":"active-speaker-detection","name":"Active Speaker Detection","max_output":4096,"attachment":true,"open_weights":true,"release_date":"2026-04-16"},"nvidia/baai/bge-m3":{"provider":"nvidia","id":"baai/bge-m3","name":"BGE M3","family":"bge","context_window":8192,"max_output":1024,"open_weights":true,"release_date":"2024-01-30"},"nvidia/bevformer":{"provider":"nvidia","id":"bevformer","context_window":128000,"max_output":8192,"attachment":true,"open_weights":true,"release_date":"2025-03-18"},"nvidia/black-forest-labs/flux.1-dev":{"provider":"nvidia","id":"black-forest-labs/flux.1-dev","name":"FLUX.1-dev","family":"flux","context_window":4096,"knowledge_cutoff":"2024-08","release_date":"2024-08-01"},"nvidia/black-forest-labs/flux_1-kontext-dev":{"provider":"nvidia","id":"black-forest-labs/flux_1-kontext-dev","name":"FLUX.1-Kontext-dev","context_window":40960,"max_output":40960,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-08-12"},"nvidia/black-forest-labs/flux_1-schnell":{"provider":"nvidia","id":"black-forest-labs/flux_1-schnell","name":"FLUX.1-schnell","context_window":77,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2024-08-01"},"nvidia/black-forest-labs/flux_2-klein-4b":{"provider":"nvidia","id":"black-forest-labs/flux_2-klein-4b","name":"FLUX.2 Klein 4B","family":"flux","context_window":40960,"max_output":40960,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-01-14"},"nvidia/bytedance/seed-oss-36b-instruct":{"provider":"nvidia","id":"bytedance/seed-oss-36b-instruct","name":"ByteDance-Seed/Seed-OSS-36B-Instruct","family":"seed","context_window":262000,"max_output":262000,"tool_call":true,"release_date":"2025-09-04"},"nvidia/cosmos-predict1-5b":{"provider":"nvidia","id":"cosmos-predict1-5b","max_output":4096,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-03-18"},"nvidia/cosmos-reason2-8b":{"provider":"nvidia","id":"cosmos-reason2-8b","name":"Cosmos Reason2 8B","context_window":131072,"max_output":16384,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-12-01"},"nvidia/cosmos-transfer1-7b":{"provider":"nvidia","id":"cosmos-transfer1-7b","max_output":4096,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-06-13"},"nvidia/cosmos-transfer2_5-2b":{"provider":"nvidia","id":"cosmos-transfer2_5-2b","name":"cosmos-transfer2.5-2b","max_output":4096,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-26"},"nvidia/deepseek-ai/deepseek-v4-flash":{"provider":"nvidia","id":"deepseek-ai/deepseek-v4-flash","name":"DeepSeek V4 Flash","family":"deepseek-flash","context_window":1048576,"max_output":393216,"cost":{"input":0.14,"output":0.28,"cache_read":0.0028},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-04-24"},"nvidia/deepseek-ai/deepseek-v4-flash-0731":{"provider":"nvidia","id":"deepseek-ai/deepseek-v4-flash-0731","name":"DeepSeek V4 Flash 0731","family":"deepseek-flash","context_window":1000000,"max_output":384000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-07-31"},"nvidia/deepseek-ai/deepseek-v4-pro":{"provider":"nvidia","id":"deepseek-ai/deepseek-v4-pro","name":"DeepSeek V4 Pro","family":"deepseek-thinking","context_window":1048576,"max_output":393216,"cost":{"input":0.435,"output":0.87,"cache_read":0.003625},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-04-24"},"nvidia/deepseek-ai/deepseek-v4-pro-0813":{"provider":"nvidia","id":"deepseek-ai/deepseek-v4-pro-0813","name":"DeepSeek V4 Pro 0813","family":"deepseek-thinking","context_window":1000000,"max_output":384000,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-12"},"nvidia/gliner-pii":{"provider":"nvidia","id":"gliner-pii","context_window":128000,"max_output":4096,"open_weights":true,"release_date":"2026-03-03"},"nvidia/google/gemma-2-2b-it":{"provider":"nvidia","id":"google/gemma-2-2b-it","name":"Gemma 2 2b It","context_window":128000,"max_output":4096,"tool_call":true,"open_weights":true,"release_date":"2024-07-16"},"nvidia/google/gemma-3-12b-it":{"provider":"nvidia","id":"google/gemma-3-12b-it","name":"Gemma 3 12B IT","family":"gemma","context_window":131072,"max_output":16384,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-03-12"},"nvidia/google/gemma-3-4b-it":{"provider":"nvidia","id":"google/gemma-3-4b-it","name":"Gemma 3 4B IT","family":"gemma","context_window":131072,"max_output":16384,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-03-12"},"nvidia/google/gemma-3n-e2b-it":{"provider":"nvidia","id":"google/gemma-3n-e2b-it","name":"Gemma 3n E2b It","context_window":128000,"max_output":4096,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-06","release_date":"2025-06-12"},"nvidia/google/gemma-3n-e4b-it":{"provider":"nvidia","id":"google/gemma-3n-e4b-it","name":"Gemma 3n E4b It","context_window":128000,"max_output":4096,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-06","release_date":"2025-06-03"},"nvidia/google/gemma-4-31b-it":{"provider":"nvidia","id":"google/gemma-4-31b-it","name":"Gemma-4-31B-IT","family":"gemma","context_window":256000,"max_output":16384,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-02"},"nvidia/google/google-paligemma":{"provider":"nvidia","id":"google/google-paligemma","name":"paligemma","context_window":128000,"max_output":8192,"attachment":true,"vision":true,"open_weights":true,"release_date":"2024-05-14"},"nvidia/llama-3.1-nemotron-70b-instruct":{"provider":"nvidia","id":"llama-3.1-nemotron-70b-instruct","name":"Llama 3.1 Nemotron 70B Instruct","family":"nemotron","context_window":128000,"max_output":8192,"tool_call":true,"open_weights":true,"release_date":"2025-04-15"},"nvidia/llama-3.1-nemotron-nano-8b-v1":{"provider":"nvidia","id":"llama-3.1-nemotron-nano-8b-v1","name":"Llama 3.1 Nemotron Nano 8B v1","family":"nemotron","context_window":131072,"max_output":16384,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-03-18"},"nvidia/llama-3.1-nemotron-nano-vl-8b-v1":{"provider":"nvidia","id":"llama-3.1-nemotron-nano-vl-8b-v1","name":"Llama 3.1 Nemotron Nano VL 8B v1","family":"nemotron","context_window":32768,"max_output":16384,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-04-10"},"nvidia/llama-3.1-nemotron-safety-guard-8b-v3":{"provider":"nvidia","id":"llama-3.1-nemotron-safety-guard-8b-v3","family":"nemotron","context_window":128000,"max_output":4096,"open_weights":true,"release_date":"2025-10-28"},"nvidia/llama-3.1-nemotron-ultra-253b-v1":{"provider":"nvidia","id":"llama-3.1-nemotron-ultra-253b-v1","name":"Llama 3.1 Nemotron Ultra 253B","family":"nemotron","context_window":128000,"max_output":16384,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-04-07"},"nvidia/llama-3.3-nemotron-super-49b-v1":{"provider":"nvidia","id":"llama-3.3-nemotron-super-49b-v1","name":"Llama 3.3 Nemotron Super 49B v1","family":"nemotron","context_window":131072,"max_output":65536,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-04-07"},"nvidia/llama-3.3-nemotron-super-49b-v1.5":{"provider":"nvidia","id":"llama-3.3-nemotron-super-49b-v1.5","name":"Llama 3.3 Nemotron Super 49B v1.5","family":"nemotron","context_window":131072,"max_output":65536,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-07-25"},"nvidia/llama-3_2-nemoretriever-300m-embed-v1":{"provider":"nvidia","id":"llama-3_2-nemoretriever-300m-embed-v1","context_window":32768,"max_output":2048,"open_weights":true,"release_date":"2025-07-24"},"nvidia/llama-nemotron-embed-vl-1b-v2":{"provider":"nvidia","id":"llama-nemotron-embed-vl-1b-v2","family":"nemotron","context_window":32768,"max_output":2048,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-10"},"nvidia/llama-nemotron-rerank-vl-1b-v2":{"provider":"nvidia","id":"llama-nemotron-rerank-vl-1b-v2","family":"nemotron","context_window":128000,"max_output":4096,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-03-31"},"nvidia/magpie-tts-zeroshot":{"provider":"nvidia","id":"magpie-tts-zeroshot","max_output":4096,"attachment":true,"open_weights":true,"release_date":"2025-05-22"},"nvidia/meta/esm2-650m":{"provider":"nvidia","id":"meta/esm2-650m","name":"esm2-650m","context_window":128000,"max_output":8192,"open_weights":true,"release_date":"2024-08-29"},"nvidia/meta/esmfold":{"provider":"nvidia","id":"meta/esmfold","name":"esmfold","context_window":128000,"max_output":8192,"open_weights":true,"release_date":"2024-03-15"},"nvidia/meta/llama-3.1-70b-instruct":{"provider":"nvidia","id":"meta/llama-3.1-70b-instruct","name":"Llama 3.1 70b Instruct","context_window":128000,"max_output":4096,"tool_call":true,"open_weights":true,"release_date":"2024-07-16"},"nvidia/meta/llama-3.1-8b-instruct":{"provider":"nvidia","id":"meta/llama-3.1-8b-instruct","name":"Llama 3.1 8B Instruct","family":"llama","context_window":16000,"max_output":4096,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2025-01-01"},"nvidia/meta/llama-3.2-11b-vision-instruct":{"provider":"nvidia","id":"meta/llama-3.2-11b-vision-instruct","name":"Llama 3.2 11b Vision Instruct","context_window":128000,"max_output":4096,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-09-18"},"nvidia/meta/llama-3.2-1b-instruct":{"provider":"nvidia","id":"meta/llama-3.2-1b-instruct","name":"Llama 3.2 1b Instruct","context_window":128000,"max_output":4096,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-09-18"},"nvidia/meta/llama-3.2-3b-instruct":{"provider":"nvidia","id":"meta/llama-3.2-3b-instruct","name":"Llama 3.2 3B Instruct","family":"llama","context_window":32768,"max_output":32000,"open_weights":true,"release_date":"2024-09-18"},"nvidia/meta/llama-3.2-90b-vision-instruct":{"provider":"nvidia","id":"meta/llama-3.2-90b-vision-instruct","name":"Llama-3.2-90B-Vision-Instruct","family":"llama","context_window":128000,"max_output":8192,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-09-25"},"nvidia/meta/llama-3.3-70b-instruct":{"provider":"nvidia","id":"meta/llama-3.3-70b-instruct","name":"Llama 3.3 70b Instruct","context_window":128000,"max_output":4096,"tool_call":true,"open_weights":true,"release_date":"2024-11-26"},"nvidia/meta/llama-4-maverick-17b-128e-instruct":{"provider":"nvidia","id":"meta/llama-4-maverick-17b-128e-instruct","name":"Llama 4 Maverick 17b 128e Instruct","context_window":128000,"max_output":4096,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-02","release_date":"2025-04-01"},"nvidia/meta/llama-guard-4-12b":{"provider":"nvidia","id":"meta/llama-guard-4-12b","name":"Llama Guard 4 12B","family":"llama","context_window":128000,"max_output":16384,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-04-05"},"nvidia/meta/muse-glimmer-30b":{"provider":"nvidia","id":"meta/muse-glimmer-30b","name":"Muse Glimmer 30B","family":"muse","context_window":131072,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2026-01-04","release_date":"2026-08-10"},"nvidia/microsoft/phi-4-mini-instruct":{"provider":"nvidia","id":"microsoft/phi-4-mini-instruct","name":"Phi-4-Mini","family":"phi","context_window":131072,"max_output":8192,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-12","release_date":"2024-12-01"},"nvidia/microsoft/phi-4-multimodal-instruct":{"provider":"nvidia","id":"microsoft/phi-4-multimodal-instruct","name":"Phi 4 Multimodal","context_window":128000,"max_output":16384,"release_date":"2025-07-26"},"nvidia/minimaxai/minimax-m2.7":{"provider":"nvidia","id":"minimaxai/minimax-m2.7","name":"MiniMax-M2.7","family":"minimax","context_window":204800,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-03-18"},"nvidia/minimaxai/minimax-m3":{"provider":"nvidia","id":"minimaxai/minimax-m3","name":"MiniMax-M3","family":"minimax","context_window":1000000,"max_output":16384,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-01"},"nvidia/mistralai/magistral-small-2506":{"provider":"nvidia","id":"mistralai/magistral-small-2506","name":"Magistral Small 2506","context_window":32768,"max_output":32768,"release_date":"2025-09-25"},"nvidia/mistralai/ministral-14b-instruct-2512":{"provider":"nvidia","id":"mistralai/ministral-14b-instruct-2512","name":"Ministral 3 14B Instruct 2512","family":"ministral","context_window":262144,"max_output":16384,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-12-02"},"nvidia/mistralai/mistral-7b-instruct-v0.3":{"provider":"nvidia","id":"mistralai/mistral-7b-instruct-v0.3","name":"Mistral-7B-Instruct-v0.3","context_window":65536,"max_output":65536,"tool_call":true,"open_weights":true,"release_date":"2025-04-01"},"nvidia/mistralai/mistral-large-3-675b-instruct-2512":{"provider":"nvidia","id":"mistralai/mistral-large-3-675b-instruct-2512","name":"Mistral Large 3 675B Instruct 2512","family":"mistral-large","context_window":262144,"max_output":262144,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2025-12-02"},"nvidia/mistralai/mistral-medium-3-instruct":{"provider":"nvidia","id":"mistralai/mistral-medium-3-instruct","name":"Mistral Medium 3","family":"mistral-medium","context_window":131072,"max_output":32768,"attachment":true,"vision":true,"release_date":"2025-09-25"},"nvidia/mistralai/mistral-medium-3.5-128b":{"provider":"nvidia","id":"mistralai/mistral-medium-3.5-128b","name":"Mistral Medium 3.5","family":"mistral-medium","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-29"},"nvidia/mistralai/mistral-nemotron":{"provider":"nvidia","id":"mistralai/mistral-nemotron","name":"mistral-nemotron","family":"nemotron","context_window":128000,"max_output":8192,"tool_call":true,"open_weights":true,"release_date":"2025-06-11"},"nvidia/mistralai/mistral-small-4-119b-2603":{"provider":"nvidia","id":"mistralai/mistral-small-4-119b-2603","name":"mistral-small-4-119b-2603","context_window":128000,"max_output":8192,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-03-16"},"nvidia/mistralai/mixtral-8x22b-instruct":{"provider":"nvidia","id":"mistralai/mixtral-8x22b-instruct","name":"Mistral: Mixtral 8x22B Instruct","context_window":65536,"max_output":13108,"tool_call":true,"open_weights":true,"release_date":"2024-04-17"},"nvidia/mistralai/mixtral-8x7b-instruct":{"provider":"nvidia","id":"mistralai/mixtral-8x7b-instruct","name":"Mistral: Mixtral 8x7B Instruct","context_window":32768,"max_output":16384,"tool_call":true,"open_weights":true,"release_date":"2023-12-10"},"nvidia/moonshotai/kimi-k2-instruct-0905":{"provider":"nvidia","id":"moonshotai/kimi-k2-instruct-0905","name":"Kimi K2 0905","family":"kimi-k2","context_window":262144,"max_output":262144,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2025-09-05"},"nvidia/moonshotai/kimi-k2.6":{"provider":"nvidia","id":"moonshotai/kimi-k2.6","name":"Kimi K2.6","family":"kimi-k2","context_window":262144,"max_output":262144,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-21"},"nvidia/moonshotai/kimi-k3":{"provider":"nvidia","id":"moonshotai/kimi-k3","name":"Kimi K3","family":"kimi-k3","context_window":1048576,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-16"},"nvidia/nemotron-3-content-safety":{"provider":"nvidia","id":"nemotron-3-content-safety","family":"nemotron","context_window":128000,"max_output":4096,"open_weights":true,"release_date":"2026-04-16"},"nvidia/nemotron-3-nano-30b-a3b":{"provider":"nvidia","id":"nemotron-3-nano-30b-a3b","family":"nemotron","context_window":131072,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-09","release_date":"2024-12"},"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning":{"provider":"nvidia","id":"nemotron-3-nano-omni-30b-a3b-reasoning","name":"Nemotron 3 Nano Omni","family":"nemotron","context_window":256000,"max_output":65536,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-28"},"nvidia/nemotron-3-super-120b-a12b":{"provider":"nvidia","id":"nemotron-3-super-120b-a12b","name":"Nemotron 3 Super","family":"nemotron","context_window":262144,"max_output":262144,"cost":{"input":0.2,"output":0.8},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-04","release_date":"2026-03-11"},"nvidia/nemotron-3-ultra-550b-a55b":{"provider":"nvidia","id":"nemotron-3-ultra-550b-a55b","name":"Nemotron 3 Ultra 550B A55B","family":"nemotron","context_window":1000000,"max_output":65536,"cost":{"input":0.5,"output":2.5,"cache_read":0.15},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-04"},"nvidia/nemotron-3.5-lightning-30b-a3b":{"provider":"nvidia","id":"nemotron-3.5-lightning-30b-a3b","name":"Nemotron 3.5 Lightning 30B A3B","family":"nemotron","context_window":262144,"max_output":262144,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-11"},"nvidia/nemotron-content-safety-reasoning-4b":{"provider":"nvidia","id":"nemotron-content-safety-reasoning-4b","family":"nemotron","context_window":128000,"max_output":4096,"reasoning":true,"open_weights":true,"release_date":"2026-01-22"},"nvidia/nemotron-mini-4b-instruct":{"provider":"nvidia","id":"nemotron-mini-4b-instruct","family":"nemotron","context_window":128000,"max_output":8192,"tool_call":true,"open_weights":true,"release_date":"2024-08-21"},"nvidia/nemotron-nano-12b-v2-vl":{"provider":"nvidia","id":"nemotron-nano-12b-v2-vl","name":"Nemotron Nano 12B v2 VL","family":"nemotron","context_window":128000,"max_output":128000,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-10-28"},"nvidia/nemotron-voicechat":{"provider":"nvidia","id":"nemotron-voicechat","family":"nemotron","context_window":128000,"max_output":8192,"tool_call":true,"attachment":true,"open_weights":true,"release_date":"2026-03-16"},"nvidia/nv-embed-v1":{"provider":"nvidia","id":"nv-embed-v1","context_window":32768,"max_output":2048,"open_weights":true,"release_date":"2024-06-07"},"nvidia/nv-embedcode-7b-v1":{"provider":"nvidia","id":"nv-embedcode-7b-v1","context_window":32768,"max_output":2048,"open_weights":true,"release_date":"2025-03-17"},"nvidia/nvidia-nemotron-nano-9b-v2":{"provider":"nvidia","id":"nvidia-nemotron-nano-9b-v2","family":"nemotron","context_window":131072,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-09","release_date":"2025-08-18"},"nvidia/openai/gpt-oss-120b":{"provider":"nvidia","id":"openai/gpt-oss-120b","name":"GPT-OSS-120B","family":"gpt-oss","context_window":128000,"max_output":8192,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-08","release_date":"2025-08-04"},"nvidia/openai/gpt-oss-20b":{"provider":"nvidia","id":"openai/gpt-oss-20b","name":"GPT OSS 20B","family":"gpt-oss","context_window":131072,"max_output":32768,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-08-05"},"nvidia/openai/whisper-large-v3":{"provider":"nvidia","id":"openai/whisper-large-v3","name":"Whisper Large v3","family":"whisper","max_output":4096,"open_weights":true,"knowledge_cutoff":"2023-09","release_date":"2023-09-01"},"nvidia/poolside/laguna-xs-2.1":{"provider":"nvidia","id":"poolside/laguna-xs-2.1","name":"Laguna XS 2.1","family":"laguna","context_window":262144,"max_output":16384,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-02"},"nvidia/qwen/qwen-image":{"provider":"nvidia","id":"qwen/qwen-image","name":"Qwen Image","family":"qwen","attachment":true,"vision":true,"release_date":"2025-08-07"},"nvidia/qwen/qwen-image-edit":{"provider":"nvidia","id":"qwen/qwen-image-edit","name":"Qwen Image Edit","family":"qwen","attachment":true,"vision":true,"release_date":"2025-08-19"},"nvidia/qwen/qwen2.5-coder-32b-instruct":{"provider":"nvidia","id":"qwen/qwen2.5-coder-32b-instruct","name":"Qwen2.5 Coder 32b Instruct","context_window":128000,"max_output":4096,"tool_call":true,"open_weights":true,"release_date":"2024-11-06"},"nvidia/qwen/qwen3-coder-480b-a35b-instruct":{"provider":"nvidia","id":"qwen/qwen3-coder-480b-a35b-instruct","name":"Qwen3 Coder 480B A35B Instruct","family":"qwen","context_window":262144,"max_output":66536,"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-23"},"nvidia/qwen/qwen3-next-80b-a3b-instruct":{"provider":"nvidia","id":"qwen/qwen3-next-80b-a3b-instruct","name":"Qwen3-Next-80B-A3B-Instruct","family":"qwen","context_window":262144,"max_output":16384,"tool_call":true,"knowledge_cutoff":"2024-12","release_date":"2024-12-01"},"nvidia/qwen/qwen3.5-122b-a10b":{"provider":"nvidia","id":"qwen/qwen3.5-122b-a10b","name":"Qwen3.5 122B-A10B","family":"qwen","context_window":262144,"max_output":65536,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"nvidia/qwen/qwen3.5-397b-a17b":{"provider":"nvidia","id":"qwen/qwen3.5-397b-a17b","name":"Qwen3.5-397B-A17B","family":"qwen","context_window":262144,"max_output":8192,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2026-01","release_date":"2026-02-16"},"nvidia/rerank-qa-mistral-4b":{"provider":"nvidia","id":"rerank-qa-mistral-4b","context_window":128000,"max_output":4096,"open_weights":true,"release_date":"2024-03-17"},"nvidia/riva-translate-4b-instruct-v1.1":{"provider":"nvidia","id":"riva-translate-4b-instruct-v1.1","name":"riva-translate-4b-instruct-v1_1","context_window":128000,"max_output":4096,"open_weights":true,"release_date":"2025-12-12"},"nvidia/sarvamai/sarvam-m":{"provider":"nvidia","id":"sarvamai/sarvam-m","name":"sarvam-m","context_window":128000,"max_output":8192,"tool_call":true,"open_weights":true,"release_date":"2025-07-25"},"nvidia/sparsedrive":{"provider":"nvidia","id":"sparsedrive","context_window":128000,"max_output":8192,"attachment":true,"open_weights":true,"release_date":"2025-03-18"},"nvidia/stepfun-ai/step-3.5-flash":{"provider":"nvidia","id":"stepfun-ai/step-3.5-flash","name":"Step 3.5 Flash","context_window":256000,"max_output":16384,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-02"},"nvidia/stepfun-ai/step-3.7-flash":{"provider":"nvidia","id":"stepfun-ai/step-3.7-flash","name":"Step 3.7 Flash","context_window":256000,"max_output":16384,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-05-28"},"nvidia/streampetr":{"provider":"nvidia","id":"streampetr","context_window":128000,"max_output":8192,"attachment":true,"open_weights":true,"release_date":"2025-11-13"},"nvidia/studiovoice":{"provider":"nvidia","id":"studiovoice","context_window":128000,"max_output":8192,"open_weights":true,"release_date":"2024-10-03"},"nvidia/synthetic-video-detector":{"provider":"nvidia","id":"synthetic-video-detector","max_output":4096,"attachment":true,"open_weights":true,"release_date":"2026-04-16"},"nvidia/thinkingmachines/inkling":{"provider":"nvidia","id":"thinkingmachines/inkling","name":"Inkling","family":"ling","context_window":1048576,"max_output":16384,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-15"},"nvidia/upstage/solar-10.7b-instruct":{"provider":"nvidia","id":"upstage/solar-10.7b-instruct","name":"solar-10.7b-instruct","context_window":128000,"max_output":8192,"tool_call":true,"open_weights":true,"release_date":"2024-06-05"},"nvidia/usdcode":{"provider":"nvidia","id":"usdcode","context_window":128000,"max_output":4096,"release_date":"2026-01-01"},"nvidia/usdvalidate":{"provider":"nvidia","id":"usdvalidate","max_output":4096,"open_weights":true,"release_date":"2024-07-24"},"nvidia/z-ai/glm-5.2":{"provider":"nvidia","id":"z-ai/glm-5.2","name":"GLM-5.2","family":"glm","context_window":1000000,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-13"},"nvidia/z-ai/glm-5.3-flash":{"provider":"nvidia","id":"z-ai/glm-5.3-flash","name":"GLM-5.3-Flash","family":"glm","context_window":1000000,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"open_weights":true,"release_date":"2026-08-26"},"openai/chatgpt-image-latest":{"provider":"openai","id":"chatgpt-image-latest","family":"gpt-image","attachment":true,"vision":true,"release_date":"2025-12-16"},"openai/gpt-3.5-turbo":{"provider":"openai","id":"gpt-3.5-turbo","name":"GPT-3.5-turbo","family":"gpt","context_window":16385,"max_output":4096,"cost":{"input":0.5,"output":1.5},"knowledge_cutoff":"2021-09-01","release_date":"2023-03-01"},"openai/gpt-4":{"provider":"openai","id":"gpt-4","name":"GPT-4","family":"gpt","context_window":8192,"max_output":8192,"cost":{"input":30,"output":60},"tool_call":true,"attachment":true,"knowledge_cutoff":"2023-11","release_date":"2023-11-06"},"openai/gpt-4-turbo":{"provider":"openai","id":"gpt-4-turbo","name":"GPT-4 Turbo","family":"gpt","context_window":128000,"max_output":4096,"cost":{"input":10,"output":30},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2023-12","release_date":"2023-11-06"},"openai/gpt-4.1":{"provider":"openai","id":"gpt-4.1","name":"GPT-4.1","family":"gpt","context_window":1047576,"max_output":32768,"cost":{"input":2,"output":8,"cache_read":0.5},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-04","release_date":"2025-04-14"},"openai/gpt-4.1-mini":{"provider":"openai","id":"gpt-4.1-mini","name":"GPT-4.1 mini","family":"gpt-mini","context_window":1047576,"max_output":32768,"cost":{"input":0.4,"output":1.6,"cache_read":0.1},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-04","release_date":"2025-04-14"},"openai/gpt-4.1-nano":{"provider":"openai","id":"gpt-4.1-nano","name":"GPT-4.1 nano","family":"gpt-nano","context_window":1047576,"max_output":32768,"cost":{"input":0.1,"output":0.4,"cache_read":0.025},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-04","release_date":"2025-04-14"},"openai/gpt-4o":{"provider":"openai","id":"gpt-4o","name":"GPT-4o","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":2.5,"output":10,"cache_read":1.25},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-05-13"},"openai/gpt-4o-2024-05-13":{"provider":"openai","id":"gpt-4o-2024-05-13","name":"GPT-4o (2024-05-13)","family":"gpt","context_window":128000,"max_output":4096,"cost":{"input":5,"output":15},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2023-09","release_date":"2024-05-13"},"openai/gpt-4o-2024-08-06":{"provider":"openai","id":"gpt-4o-2024-08-06","name":"GPT-4o (2024-08-06)","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":2.5,"output":10,"cache_read":1.25},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2023-09","release_date":"2024-08-06"},"openai/gpt-4o-2024-11-20":{"provider":"openai","id":"gpt-4o-2024-11-20","name":"GPT-4o (2024-11-20)","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":2.5,"output":10,"cache_read":1.25},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2023-09","release_date":"2024-11-20"},"openai/gpt-4o-mini":{"provider":"openai","id":"gpt-4o-mini","name":"GPT-4o mini","family":"gpt-mini","context_window":128000,"max_output":16384,"cost":{"input":0.15,"output":0.6,"cache_read":0.075},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-07-18"},"openai/gpt-5":{"provider":"openai","id":"gpt-5","name":"GPT-5","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.25,"output":10,"cache_read":0.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-08-07"},"openai/gpt-5-mini":{"provider":"openai","id":"gpt-5-mini","name":"GPT-5 Mini","family":"gpt-mini","context_window":400000,"max_output":128000,"cost":{"input":0.25,"output":2,"cache_read":0.025},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-05-30","release_date":"2025-08-07"},"openai/gpt-5-nano":{"provider":"openai","id":"gpt-5-nano","name":"GPT-5 Nano","family":"gpt-nano","context_window":400000,"max_output":128000,"cost":{"input":0.05,"output":0.4,"cache_read":0.005},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-05-30","release_date":"2025-08-07"},"openai/gpt-5-pro":{"provider":"openai","id":"gpt-5-pro","name":"GPT-5 Pro","family":"gpt-pro","context_window":400000,"max_output":272000,"cost":{"input":15,"output":120},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-10-06"},"openai/gpt-5.1":{"provider":"openai","id":"gpt-5.1","name":"GPT-5.1","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.25,"output":10,"cache_read":0.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"openai/gpt-5.2":{"provider":"openai","id":"gpt-5.2","name":"GPT-5.2","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-11"},"openai/gpt-5.2-chat-latest":{"provider":"openai","id":"gpt-5.2-chat-latest","name":"GPT-5.2 Chat","family":"gpt-codex","context_window":128000,"max_output":16384,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-11"},"openai/gpt-5.2-pro":{"provider":"openai","id":"gpt-5.2-pro","name":"GPT-5.2 Pro","family":"gpt-pro","context_window":400000,"max_output":128000,"cost":{"input":21,"output":168},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-11"},"openai/gpt-5.3-chat-latest":{"provider":"openai","id":"gpt-5.3-chat-latest","name":"GPT-5.3 Chat (latest)","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":1.75,"output":14,"cache_read":0.175},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-03"},"openai/gpt-5.3-codex":{"provider":"openai","id":"gpt-5.3-codex","name":"GPT-5.3 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-05"},"openai/gpt-5.3-codex-spark":{"provider":"openai","id":"gpt-5.3-codex-spark","name":"GPT-5.3 Codex Spark","family":"gpt-codex-spark","context_window":128000,"max_output":32000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-05"},"openai/gpt-5.4":{"provider":"openai","id":"gpt-5.4","name":"GPT-5.4","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":2.5,"output":15,"cache_read":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-05"},"openai/gpt-5.4-mini":{"provider":"openai","id":"gpt-5.4-mini","name":"GPT-5.4 mini","family":"gpt-mini","context_window":400000,"max_output":128000,"cost":{"input":0.75,"output":4.5,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"openai/gpt-5.4-nano":{"provider":"openai","id":"gpt-5.4-nano","name":"GPT-5.4 nano","family":"gpt-nano","context_window":400000,"max_output":128000,"cost":{"input":0.2,"output":1.25,"cache_read":0.02},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"openai/gpt-5.4-pro":{"provider":"openai","id":"gpt-5.4-pro","name":"GPT-5.4 Pro","family":"gpt-pro","context_window":1050000,"max_output":128000,"cost":{"input":30,"output":180},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-05"},"openai/gpt-5.5":{"provider":"openai","id":"gpt-5.5","name":"GPT-5.5","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":5,"output":30,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-12-01","release_date":"2026-04-23"},"openai/gpt-5.5-pro":{"provider":"openai","id":"gpt-5.5-pro","name":"GPT-5.5 Pro","family":"gpt-pro","context_window":1050000,"max_output":128000,"cost":{"input":30,"output":180},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-12-01","release_date":"2026-04-23"},"openai/gpt-5.6":{"provider":"openai","id":"gpt-5.6","name":"GPT-5.6","family":"gpt-sol","context_window":1050000,"max_output":128000,"cost":{"input":4,"output":20,"cache_read":0.4,"cache_write":5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openai/gpt-5.6-luna":{"provider":"openai","id":"gpt-5.6-luna","name":"GPT-5.6 Luna","family":"gpt-luna","context_window":1050000,"max_output":128000,"cost":{"input":0.2,"output":1.2,"cache_read":0.02,"cache_write":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openai/gpt-5.6-sol":{"provider":"openai","id":"gpt-5.6-sol","name":"GPT-5.6 Sol","family":"gpt-sol","context_window":1050000,"max_output":128000,"cost":{"input":4,"output":20,"cache_read":0.4,"cache_write":5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openai/gpt-5.6-terra":{"provider":"openai","id":"gpt-5.6-terra","name":"GPT-5.6 Terra","family":"gpt-terra","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openai/gpt-6-astra":{"provider":"openai","id":"gpt-6-astra","name":"GPT-6 Astra","family":"gpt-astra","context_window":1050000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-04-30","release_date":"2026-09-04"},"openai/gpt-image-1":{"provider":"openai","id":"gpt-image-1","family":"gpt-image","attachment":true,"vision":true,"release_date":"2025-04-24"},"openai/gpt-image-1-mini":{"provider":"openai","id":"gpt-image-1-mini","family":"gpt-image","attachment":true,"vision":true,"release_date":"2025-09-26"},"openai/gpt-image-1.5":{"provider":"openai","id":"gpt-image-1.5","family":"gpt-image","attachment":true,"vision":true,"release_date":"2025-11-25"},"openai/gpt-image-2":{"provider":"openai","id":"gpt-image-2","family":"gpt-image","cost":{"input":5,"output":30,"cache_read":1.25},"attachment":true,"vision":true,"release_date":"2026-04-21"},"openai/gpt-realtime-2.1":{"provider":"openai","id":"gpt-realtime-2.1","name":"GPT-Realtime-2.1","family":"gpt","context_window":128000,"max_output":32000,"cost":{"input":4,"output":24,"cache_read":0.4},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2026-07-06"},"openai/o1":{"provider":"openai","id":"o1","family":"o","context_window":200000,"max_output":100000,"cost":{"input":15,"output":60,"cache_read":7.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-12-05"},"openai/o1-pro":{"provider":"openai","id":"o1-pro","family":"o-pro","context_window":200000,"max_output":100000,"cost":{"input":150,"output":600},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2023-09","release_date":"2025-03-19"},"openai/o3":{"provider":"openai","id":"o3","family":"o","context_window":200000,"max_output":100000,"cost":{"input":2,"output":8,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-05","release_date":"2025-04-16"},"openai/o3-mini":{"provider":"openai","id":"o3-mini","family":"o-mini","context_window":200000,"max_output":100000,"cost":{"input":1.1,"output":4.4,"cache_read":0.55},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2024-05","release_date":"2024-12-20"},"openai/o3-pro":{"provider":"openai","id":"o3-pro","family":"o-pro","context_window":200000,"max_output":100000,"cost":{"input":20,"output":80},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-05","release_date":"2025-06-10"},"openai/o4-mini":{"provider":"openai","id":"o4-mini","family":"o-mini","context_window":200000,"max_output":100000,"cost":{"input":1.1,"output":4.4,"cache_read":0.275},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-05","release_date":"2025-04-16"},"openai/text-embedding-3-large":{"provider":"openai","id":"text-embedding-3-large","family":"text-embedding","context_window":8191,"max_output":3072,"cost":{"input":0.13},"knowledge_cutoff":"2024-01","release_date":"2024-01-25"},"openai/text-embedding-3-small":{"provider":"openai","id":"text-embedding-3-small","family":"text-embedding","context_window":8191,"max_output":1536,"cost":{"input":0.02},"knowledge_cutoff":"2024-01","release_date":"2024-01-25"},"openai/text-embedding-ada-002":{"provider":"openai","id":"text-embedding-ada-002","family":"text-embedding","context_window":8192,"max_output":1536,"cost":{"input":0.1},"knowledge_cutoff":"2022-12","release_date":"2022-12-15"},"opencode/big-pickle":{"provider":"opencode","id":"big-pickle","name":"Big Pickle","family":"big-pickle","context_window":200000,"max_output":32000,"reasoning":true,"tool_call":true,"knowledge_cutoff":"2025-01","release_date":"2025-10-17"},"opencode/claude-3-5-haiku":{"provider":"opencode","id":"claude-3-5-haiku","name":"Claude Haiku 3.5","family":"claude-haiku","context_window":200000,"max_output":8192,"cost":{"input":0.8,"output":4,"cache_read":0.08,"cache_write":1},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-07-31","release_date":"2024-10-22"},"opencode/claude-fable-5":{"provider":"opencode","id":"claude-fable-5","name":"Claude Fable 5","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-06-09"},"opencode/claude-fable-5-1":{"provider":"opencode","id":"claude-fable-5-1","name":"Claude Fable 5.1","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":0.25,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-06","release_date":"2026-09-01"},"opencode/claude-haiku-4-5":{"provider":"opencode","id":"claude-haiku-4-5","name":"Claude Haiku 4.5","family":"claude-haiku","context_window":200000,"max_output":64000,"cost":{"input":1,"output":5,"cache_read":0.1,"cache_write":1.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-02-28","release_date":"2025-10-15"},"opencode/claude-opus-4-1":{"provider":"opencode","id":"claude-opus-4-1","name":"Claude Opus 4.1","family":"claude-opus","context_window":200000,"max_output":32000,"cost":{"input":15,"output":75,"cache_read":1.5,"cache_write":18.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-08-05"},"opencode/claude-opus-4-5":{"provider":"opencode","id":"claude-opus-4-5","name":"Claude Opus 4.5","family":"claude-opus","context_window":200000,"max_output":64000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-11-24"},"opencode/claude-opus-4-6":{"provider":"opencode","id":"claude-opus-4-6","name":"Claude Opus 4.6","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-05-31","release_date":"2026-02-05"},"opencode/claude-opus-4-7":{"provider":"opencode","id":"claude-opus-4-7","name":"Claude Opus 4.7","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-04-16"},"opencode/claude-opus-4-8":{"provider":"opencode","id":"claude-opus-4-8","name":"Claude Opus 4.8","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01","release_date":"2026-05-28"},"opencode/claude-opus-5":{"provider":"opencode","id":"claude-opus-5","name":"Claude Opus 5","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-05","release_date":"2026-07-24"},"opencode/claude-sonnet-4":{"provider":"opencode","id":"claude-sonnet-4","name":"Claude Sonnet 4","family":"claude-sonnet","context_window":1000000,"max_output":64000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-05-22"},"opencode/claude-sonnet-4-5":{"provider":"opencode","id":"claude-sonnet-4-5","name":"Claude Sonnet 4.5","family":"claude-sonnet","context_window":1000000,"max_output":64000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-07-31","release_date":"2025-09-29"},"opencode/claude-sonnet-4-6":{"provider":"opencode","id":"claude-sonnet-4-6","name":"Claude Sonnet 4.6","family":"claude-sonnet","context_window":1000000,"max_output":64000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-17"},"opencode/claude-sonnet-5":{"provider":"opencode","id":"claude-sonnet-5","name":"Claude Sonnet 5","family":"claude-sonnet","context_window":1000000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-06-30"},"opencode/deepseek-v4-flash":{"provider":"opencode","id":"deepseek-v4-flash","name":"DeepSeek V4 Flash","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.14,"output":0.28,"cache_read":0.028},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-07-31"},"opencode/deepseek-v4-flash-free":{"provider":"opencode","id":"deepseek-v4-flash-free","name":"DeepSeek V4 Flash Free","family":"deepseek-flash","context_window":200000,"max_output":128000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-07-31"},"opencode/deepseek-v4-flash-vision-exp":{"provider":"opencode","id":"deepseek-v4-flash-vision-exp","name":"DeepSeek V4 Flash Vision Exp","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.14,"output":0.28,"cache_read":0.028},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-21"},"opencode/deepseek-v4-pro":{"provider":"opencode","id":"deepseek-v4-pro","name":"DeepSeek V4 Pro","family":"deepseek-thinking","context_window":1000000,"max_output":384000,"cost":{"input":1.74,"output":3.84,"cache_read":0.145},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-04-24"},"opencode/gemini-3-flash":{"provider":"opencode","id":"gemini-3-flash","name":"Gemini 3 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.5,"output":3,"cache_read":0.05},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-12-17"},"opencode/gemini-3-pro":{"provider":"opencode","id":"gemini-3-pro","name":"Gemini 3 Pro","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-11-18"},"opencode/gemini-3.1-pro":{"provider":"opencode","id":"gemini-3.1-pro","name":"Gemini 3.1 Pro Preview","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-19"},"opencode/gemini-3.5-flash":{"provider":"opencode","id":"gemini-3.5-flash","name":"Gemini 3.5 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":1.5,"output":9,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-19"},"opencode/gemini-3.5-flash-lite":{"provider":"opencode","id":"gemini-3.5-flash-lite","name":"Gemini 3.5 Flash Lite","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.3,"output":2.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"opencode/gemini-3.6-flash":{"provider":"opencode","id":"gemini-3.6-flash","name":"Gemini 3.6 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":1.5,"output":7.5,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"opencode/gemini-3.7-flash":{"provider":"opencode","id":"gemini-3.7-flash","name":"Gemini 3.7 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":1.5,"output":7.5,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-08-13"},"opencode/gemini-3.8-flash":{"provider":"opencode","id":"gemini-3.8-flash","name":"Gemini 3.8 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":1.5,"output":7.5,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-02"},"opencode/glm-4.6":{"provider":"opencode","id":"glm-4.6","name":"GLM-4.6","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":0.6,"output":2.2,"cache_read":0.1},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-09-30"},"opencode/glm-4.7":{"provider":"opencode","id":"glm-4.7","name":"GLM-4.7","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":0.6,"output":2.2,"cache_read":0.1},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-12-22"},"opencode/glm-4.7-free":{"provider":"opencode","id":"glm-4.7-free","name":"GLM-4.7 Free","family":"glm-free","context_window":204800,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-12-22"},"opencode/glm-5":{"provider":"opencode","id":"glm-5","name":"GLM-5","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":1,"output":3.2,"cache_read":0.2},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2026-02-11"},"opencode/glm-5-free":{"provider":"opencode","id":"glm-5-free","name":"GLM-5 Free","family":"glm-free","context_window":204800,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2026-02-11"},"opencode/glm-5.1":{"provider":"opencode","id":"glm-5.1","name":"GLM-5.1","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2026-04-07"},"opencode/glm-5.2":{"provider":"opencode","id":"glm-5.2","name":"GLM-5.2","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-13"},"opencode/glm-5.3":{"provider":"opencode","id":"glm-5.3","name":"GLM-5.3","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-14"},"opencode/glm-5.3-flash":{"provider":"opencode","id":"glm-5.3-flash","name":"GLM-5.3-Flash","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":0.15,"output":0.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"open_weights":true,"release_date":"2026-08-26"},"opencode/gpt-5":{"provider":"opencode","id":"gpt-5","name":"GPT-5","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.07,"output":8.5,"cache_read":0.107},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-08-07"},"opencode/gpt-5-codex":{"provider":"opencode","id":"gpt-5-codex","name":"GPT-5 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.07,"output":8.5,"cache_read":0.107},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-09-15"},"opencode/gpt-5-nano":{"provider":"opencode","id":"gpt-5-nano","name":"GPT-5 Nano","family":"gpt-nano","context_window":400000,"max_output":128000,"cost":{"input":0.05,"output":0.4,"cache_read":0.005},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-05-30","release_date":"2025-08-07"},"opencode/gpt-5.1":{"provider":"opencode","id":"gpt-5.1","name":"GPT-5.1","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.07,"output":8.5,"cache_read":0.107},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"opencode/gpt-5.1-codex":{"provider":"opencode","id":"gpt-5.1-codex","name":"GPT-5.1 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.07,"output":8.5,"cache_read":0.107},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"opencode/gpt-5.1-codex-max":{"provider":"opencode","id":"gpt-5.1-codex-max","name":"GPT-5.1 Codex Max","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.25,"output":10,"cache_read":0.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"opencode/gpt-5.1-codex-mini":{"provider":"opencode","id":"gpt-5.1-codex-mini","name":"GPT-5.1 Codex Mini","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":0.25,"output":2,"cache_read":0.025},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"opencode/gpt-5.2":{"provider":"opencode","id":"gpt-5.2","name":"GPT-5.2","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-11"},"opencode/gpt-5.2-codex":{"provider":"opencode","id":"gpt-5.2-codex","name":"GPT-5.2 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-01-14"},"opencode/gpt-5.3-codex":{"provider":"opencode","id":"gpt-5.3-codex","name":"GPT-5.3 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-24"},"opencode/gpt-5.3-codex-spark":{"provider":"opencode","id":"gpt-5.3-codex-spark","name":"GPT-5.3 Codex Spark","family":"gpt-codex-spark","context_window":128000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-12"},"opencode/gpt-5.4":{"provider":"opencode","id":"gpt-5.4","name":"GPT-5.4","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":2.5,"output":15,"cache_read":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-05"},"opencode/gpt-5.4-mini":{"provider":"opencode","id":"gpt-5.4-mini","name":"GPT-5.4 Mini","family":"gpt-mini","context_window":400000,"max_output":128000,"cost":{"input":0.75,"output":4.5,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"opencode/gpt-5.4-nano":{"provider":"opencode","id":"gpt-5.4-nano","name":"GPT-5.4 Nano","family":"gpt-nano","context_window":400000,"max_output":128000,"cost":{"input":0.2,"output":1.25,"cache_read":0.02},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"opencode/gpt-5.4-pro":{"provider":"opencode","id":"gpt-5.4-pro","name":"GPT-5.4 Pro","family":"gpt-pro","context_window":1050000,"max_output":128000,"cost":{"input":30,"output":180,"cache_read":30},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-05"},"opencode/gpt-5.5":{"provider":"opencode","id":"gpt-5.5","name":"GPT-5.5","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":5,"output":30,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-12-01","release_date":"2026-04-23"},"opencode/gpt-5.5-pro":{"provider":"opencode","id":"gpt-5.5-pro","name":"GPT-5.5 Pro","family":"gpt-pro","context_window":1050000,"max_output":128000,"cost":{"input":30,"output":180,"cache_read":30},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-12-01","release_date":"2026-04-24"},"opencode/gpt-5.6-luna":{"provider":"opencode","id":"gpt-5.6-luna","name":"GPT-5.6 Luna","family":"gpt-luna","context_window":1050000,"max_output":128000,"cost":{"input":0.2,"output":1.2,"cache_read":0.02,"cache_write":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"opencode/gpt-5.6-sol":{"provider":"opencode","id":"gpt-5.6-sol","name":"GPT-5.6 Sol (50% Off)","family":"gpt-sol","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"opencode/gpt-5.6-terra":{"provider":"opencode","id":"gpt-5.6-terra","name":"GPT-5.6 Terra","family":"gpt-terra","context_window":1050000,"max_output":128000,"cost":{"input":2.5,"output":15,"cache_read":0.25,"cache_write":3.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"opencode/gpt-6-astra":{"provider":"opencode","id":"gpt-6-astra","name":"GPT-6 Astra","family":"gpt-astra","context_window":1050000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-04-30","release_date":"2026-09-04"},"opencode/grok-4.5":{"provider":"opencode","id":"grok-4.5","name":"Grok 4.5","family":"grok","context_window":500000,"max_output":500000,"cost":{"input":2,"output":6,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-07-08"},"opencode/grok-4.6":{"provider":"opencode","id":"grok-4.6","name":"Grok 4.6","family":"grok","context_window":500000,"max_output":500000,"cost":{"input":2,"output":6,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2026-02-01","release_date":"2026-08-12"},"opencode/grok-build-0.1":{"provider":"opencode","id":"grok-build-0.1","name":"Grok Build 0.1","family":"grok-build","context_window":256000,"max_output":256000,"cost":{"input":1,"output":2,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-16"},"opencode/grok-code":{"provider":"opencode","id":"grok-code","name":"Grok Code Fast 1","family":"grok","context_window":256000,"max_output":256000,"reasoning":true,"tool_call":true,"release_date":"2025-08-20"},"opencode/hy3-free":{"provider":"opencode","id":"hy3-free","name":"Hy3 Free","family":"hy3-free","context_window":190000,"max_output":64000,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-06"},"opencode/hy3-preview-free":{"provider":"opencode","id":"hy3-preview-free","name":"Hy3 preview Free","family":"hy3-free","context_window":256000,"max_output":64000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-04-20"},"opencode/kimi-k2":{"provider":"opencode","id":"kimi-k2","name":"Kimi K2","family":"kimi-k2","context_window":262144,"max_output":262144,"cost":{"input":0.4,"output":2.5,"cache_read":0.4},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2025-09-05"},"opencode/kimi-k2-thinking":{"provider":"opencode","id":"kimi-k2-thinking","name":"Kimi K2 Thinking","family":"kimi-thinking","context_window":262144,"max_output":262144,"cost":{"input":0.4,"output":2.5,"cache_read":0.4},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2025-09-05"},"opencode/kimi-k2.5":{"provider":"opencode","id":"kimi-k2.5","name":"Kimi K2.5","family":"kimi-k2","context_window":262144,"max_output":65536,"cost":{"input":0.6,"output":3,"cache_read":0.08},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2026-01-27"},"opencode/kimi-k2.5-free":{"provider":"opencode","id":"kimi-k2.5-free","name":"Kimi K2.5 Free","family":"kimi-free","context_window":262144,"max_output":262144,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2026-01-27"},"opencode/kimi-k2.6":{"provider":"opencode","id":"kimi-k2.6","name":"Kimi K2.6","family":"kimi-k2","context_window":262144,"max_output":65536,"cost":{"input":0.95,"output":4,"cache_read":0.16},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2026-04-21"},"opencode/kimi-k2.7-code":{"provider":"opencode","id":"kimi-k2.7-code","name":"Kimi K2.7 Code","family":"kimi-k2","context_window":262144,"max_output":262144,"cost":{"input":0.95,"output":4,"cache_read":0.19},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-06-12"},"opencode/kimi-k3":{"provider":"opencode","id":"kimi-k3","name":"Kimi K3","family":"kimi-k3","context_window":1048576,"max_output":131072,"cost":{"input":3,"output":15,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-16"},"opencode/laguna-s-2.1-free":{"provider":"opencode","id":"laguna-s-2.1-free","name":"Laguna S 2.1 Free","family":"laguna","context_window":256000,"max_output":32000,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-21"},"opencode/ling-2.6-flash-free":{"provider":"opencode","id":"ling-2.6-flash-free","name":"Ling 2.6 Flash Free","family":"ling-flash-free","context_window":262100,"max_output":32800,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-04-21"},"opencode/ling-3.0-flash-fin-free":{"provider":"opencode","id":"ling-3.0-flash-fin-free","name":"Ling 3.0 Flash Fin Free","family":"ling","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"release_date":"2026-08-27"},"opencode/ling-3.0-flash-free":{"provider":"opencode","id":"ling-3.0-flash-free","name":"Ling-3.0-flash Free","family":"ling","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"release_date":"2026-07-23"},"opencode/ling-3.0-tiny-free":{"provider":"opencode","id":"ling-3.0-tiny-free","name":"Ling-3.0-tiny Free","family":"ling","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"release_date":"2026-08-06"},"opencode/longcat-2.0-free":{"provider":"opencode","id":"longcat-2.0-free","name":"LongCat-2.0 Free","family":"longcat","context_window":1000000,"max_output":131072,"reasoning":true,"tool_call":true,"release_date":"2026-06-30"},"opencode/mimo-v2-flash-free":{"provider":"opencode","id":"mimo-v2-flash-free","name":"MiMo V2 Flash Free","family":"mimo-flash-free","context_window":262144,"max_output":65536,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-12","release_date":"2025-12-16"},"opencode/mimo-v2-omni-free":{"provider":"opencode","id":"mimo-v2-omni-free","name":"MiMo V2 Omni Free","family":"mimo-omni-free","context_window":262144,"max_output":64000,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"open_weights":true,"knowledge_cutoff":"2024-12","release_date":"2026-03-18"},"opencode/mimo-v2-pro-free":{"provider":"opencode","id":"mimo-v2-pro-free","name":"MiMo V2 Pro Free","family":"mimo-pro-free","context_window":1048576,"max_output":64000,"reasoning":true,"tool_call":true,"attachment":true,"open_weights":true,"knowledge_cutoff":"2024-12","release_date":"2026-03-18"},"opencode/mimo-v2.5-free":{"provider":"opencode","id":"mimo-v2.5-free","name":"MiMo V2.5 Free","family":"mimo-v2.5-free","context_window":200000,"max_output":32000,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-12","release_date":"2026-04-24"},"opencode/minimax-m2.1":{"provider":"opencode","id":"minimax-m2.1","name":"MiniMax-M2.1","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.1},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2025-12-23"},"opencode/minimax-m2.1-free":{"provider":"opencode","id":"minimax-m2.1-free","name":"MiniMax-M2.1 Free","family":"minimax-free","context_window":204800,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2025-12-23"},"opencode/minimax-m2.5":{"provider":"opencode","id":"minimax-m2.5","name":"MiniMax-M2.5","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-12"},"opencode/minimax-m2.5-free":{"provider":"opencode","id":"minimax-m2.5-free","name":"MiniMax-M2.5 Free","family":"minimax-free","context_window":204800,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-12"},"opencode/minimax-m2.7":{"provider":"opencode","id":"minimax-m2.7","name":"MiniMax-M2.7","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-03-18"},"opencode/minimax-m3":{"provider":"opencode","id":"minimax-m3","name":"MiniMax-M3","family":"minimax","context_window":512000,"max_output":128000,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-01"},"opencode/minimax-m3-free":{"provider":"opencode","id":"minimax-m3-free","name":"MiniMax-M3 Free","family":"minimax-m3-free","context_window":200000,"max_output":32000,"reasoning":true,"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-31"},"opencode/muse-spark-1.2":{"provider":"opencode","id":"muse-spark-1.2","name":"Muse Spark 1.2","family":"muse","context_window":1048576,"max_output":131072,"cost":{"input":1.25,"output":4.25,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-05"},"opencode/muse-spark-1.2-contributor-free":{"provider":"opencode","id":"muse-spark-1.2-contributor-free","name":"Muse Spark 1.2 Free","family":"muse-free","context_window":1048576,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-05"},"opencode/muse-spark-1.3":{"provider":"opencode","id":"muse-spark-1.3","name":"Muse Spark 1.3","family":"muse","context_window":1048576,"max_output":131072,"cost":{"input":1.25,"output":4.25,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-02"},"opencode/muse-spark-1.3-contributor-free":{"provider":"opencode","id":"muse-spark-1.3-contributor-free","name":"Muse Spark 1.3 Free","family":"muse-free","context_window":1048576,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-02"},"opencode/nemotron-3-super-free":{"provider":"opencode","id":"nemotron-3-super-free","name":"Nemotron 3 Super Free","family":"nemotron-free","context_window":204800,"max_output":128000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2026-02","release_date":"2026-03-11"},"opencode/nemotron-3-ultra-free":{"provider":"opencode","id":"nemotron-3-ultra-free","name":"Nemotron 3 Ultra Free","family":"nemotron-free","context_window":1000000,"max_output":128000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2026-02","release_date":"2026-06-04"},"opencode/nemotron-3.5-lightning-free":{"provider":"opencode","id":"nemotron-3.5-lightning-free","name":"Nemotron 3.5 Lightning Free","family":"nemotron-free","context_window":262144,"max_output":262144,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-11"},"opencode/north-mini-code-free":{"provider":"opencode","id":"north-mini-code-free","name":"North Mini Code Free","family":"north-free","context_window":256000,"max_output":64000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-09-23","release_date":"2026-06-09"},"opencode/qwen3-coder":{"provider":"opencode","id":"qwen3-coder","name":"Qwen3 Coder","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.45,"output":1.8},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-23"},"opencode/qwen3.5-plus":{"provider":"opencode","id":"qwen3.5-plus","name":"Qwen3.5 Plus","family":"qwen3.5","context_window":262144,"max_output":65536,"cost":{"input":0.2,"output":1.2,"cache_read":0.02,"cache_write":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-02-16"},"opencode/qwen3.6-plus":{"provider":"opencode","id":"qwen3.6-plus","name":"Qwen3.6 Plus","family":"qwen3.6","context_window":262144,"max_output":65536,"cost":{"input":0.5,"output":3,"cache_read":0.05,"cache_write":0.625},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-04-02"},"opencode/qwen3.6-plus-free":{"provider":"opencode","id":"qwen3.6-plus-free","name":"Qwen3.6 Plus Free","family":"qwen-free","context_window":262144,"max_output":65536,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-04-02"},"opencode/ring-2.6-1t-free":{"provider":"opencode","id":"ring-2.6-1t-free","name":"Ring 2.6 1T Free","family":"ring-1t-free","context_window":262000,"max_output":66000,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-05-08"},"opencode/trinity-large-preview-free":{"provider":"opencode","id":"trinity-large-preview-free","name":"Trinity Large Preview","family":"trinity","context_window":131072,"max_output":131072,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-01-27"},"opencode/x-preview-f-free":{"provider":"opencode","id":"x-preview-f-free","name":"Ox Alpha Free (Unlimited)","context_window":1000000,"max_output":131072,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-21"},"openrouter/aion-labs/aion-2.0":{"provider":"openrouter","id":"aion-labs/aion-2.0","name":"Aion-2.0","context_window":131072,"max_output":32768,"cost":{"input":0.8,"output":1.6,"cache_read":0.2},"reasoning":true,"tool_call":true,"release_date":"2026-02-23"},"openrouter/aion-labs/aion-3.0":{"provider":"openrouter","id":"aion-labs/aion-3.0","name":"Aion-3.0","context_window":131072,"max_output":32768,"cost":{"input":3,"output":6,"cache_read":0.75},"reasoning":true,"tool_call":true,"release_date":"2026-07-07"},"openrouter/aion-labs/aion-3.0-mini":{"provider":"openrouter","id":"aion-labs/aion-3.0-mini","name":"Aion-3.0-Mini","context_window":131072,"max_output":32768,"cost":{"input":0.7,"output":1.4,"cache_read":0.18},"reasoning":true,"tool_call":true,"release_date":"2026-07-07"},"openrouter/aion-labs/aion-rp-llama-3.1-8b":{"provider":"openrouter","id":"aion-labs/aion-rp-llama-3.1-8b","name":"Aion-RP 1.0 (8B)","family":"llama","context_window":32768,"max_output":29491,"cost":{"input":0.8,"output":1.6},"knowledge_cutoff":"2023-12-31","release_date":"2025-02-04"},"openrouter/amazon/nova-2-lite-v1":{"provider":"openrouter","id":"amazon/nova-2-lite-v1","name":"Nova 2 Lite","family":"nova","context_window":1000000,"max_output":65535,"cost":{"input":0.3,"output":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2025-12-02"},"openrouter/amazon/nova-lite-v1":{"provider":"openrouter","id":"amazon/nova-lite-v1","name":"Nova Lite 1.0","family":"nova-lite","context_window":300000,"max_output":5120,"cost":{"input":0.06,"output":0.24},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-10-31","release_date":"2024-12-05"},"openrouter/amazon/nova-micro-v1":{"provider":"openrouter","id":"amazon/nova-micro-v1","name":"Nova Micro 1.0","family":"nova-micro","context_window":128000,"max_output":5120,"cost":{"input":0.035,"output":0.14},"tool_call":true,"knowledge_cutoff":"2024-10-31","release_date":"2024-12-05"},"openrouter/amazon/nova-premier-v1":{"provider":"openrouter","id":"amazon/nova-premier-v1","name":"Nova Premier 1.0","family":"nova","context_window":1000000,"max_output":32000,"cost":{"input":2.5,"output":12.5,"cache_read":0.625},"tool_call":true,"attachment":true,"vision":true,"release_date":"2025-10-31"},"openrouter/amazon/nova-pro-v1":{"provider":"openrouter","id":"amazon/nova-pro-v1","name":"Nova Pro 1.0","family":"nova-pro","context_window":300000,"max_output":5120,"cost":{"input":0.8,"output":3.2},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-10-31","release_date":"2024-12-05"},"openrouter/anthracite-org/magnum-v4-72b":{"provider":"openrouter","id":"anthracite-org/magnum-v4-72b","name":"Magnum v4 72B","context_window":32768,"max_output":4096,"cost":{"input":2.5,"output":5},"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2024-10-22"},"openrouter/anthropic/claude-3-haiku":{"provider":"openrouter","id":"anthropic/claude-3-haiku","name":"Claude 3 Haiku","family":"claude","context_window":200000,"max_output":4096,"cost":{"input":0.25,"output":1.25,"cache_read":0.03,"cache_write":0.3},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2023-08-31","release_date":"2024-03-13"},"openrouter/anthropic/claude-fable-5":{"provider":"openrouter","id":"anthropic/claude-fable-5","name":"Claude Fable 5","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-06-09"},"openrouter/anthropic/claude-fable-5.1":{"provider":"openrouter","id":"anthropic/claude-fable-5.1","name":"Claude Fable 5.1","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":0.25,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-06","release_date":"2026-09-01"},"openrouter/anthropic/claude-haiku-4.5":{"provider":"openrouter","id":"anthropic/claude-haiku-4.5","name":"Claude Haiku 4.5 (latest)","family":"claude-haiku","context_window":200000,"max_output":64000,"cost":{"input":1,"output":5,"cache_read":0.1,"cache_write":1.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-02-28","release_date":"2025-10-15"},"openrouter/anthropic/claude-opus-4":{"provider":"openrouter","id":"anthropic/claude-opus-4","name":"Claude Opus 4","family":"claude-opus","context_window":200000,"max_output":32000,"cost":{"input":15,"output":75,"cache_read":1.5,"cache_write":18.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01-31","release_date":"2025-05-22"},"openrouter/anthropic/claude-opus-4.1":{"provider":"openrouter","id":"anthropic/claude-opus-4.1","name":"Claude Opus 4.1 (latest)","family":"claude-opus","context_window":200000,"max_output":32000,"cost":{"input":15,"output":75,"cache_read":1.5,"cache_write":18.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-08-05"},"openrouter/anthropic/claude-opus-4.5":{"provider":"openrouter","id":"anthropic/claude-opus-4.5","name":"Claude Opus 4.5 (latest)","family":"claude-opus","context_window":200000,"max_output":64000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-05","release_date":"2025-11-24"},"openrouter/anthropic/claude-opus-4.6":{"provider":"openrouter","id":"anthropic/claude-opus-4.6","name":"Claude Opus 4.6","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-05-31","release_date":"2026-02-05"},"openrouter/anthropic/claude-opus-4.7":{"provider":"openrouter","id":"anthropic/claude-opus-4.7","name":"Claude Opus 4.7","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-04-16"},"openrouter/anthropic/claude-opus-4.8":{"provider":"openrouter","id":"anthropic/claude-opus-4.8","name":"Claude Opus 4.8","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01","release_date":"2026-05-28"},"openrouter/anthropic/claude-opus-5":{"provider":"openrouter","id":"anthropic/claude-opus-5","name":"Claude Opus 5","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-05","release_date":"2026-07-24"},"openrouter/anthropic/claude-sonnet-4":{"provider":"openrouter","id":"anthropic/claude-sonnet-4","name":"Claude Sonnet 4","family":"claude-sonnet","context_window":1000000,"max_output":64000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01-31","release_date":"2025-05-22"},"openrouter/anthropic/claude-sonnet-4.5":{"provider":"openrouter","id":"anthropic/claude-sonnet-4.5","name":"Claude Sonnet 4.5 (latest)","family":"claude-sonnet","context_window":1000000,"max_output":64000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-07-31","release_date":"2025-09-29"},"openrouter/anthropic/claude-sonnet-4.6":{"provider":"openrouter","id":"anthropic/claude-sonnet-4.6","name":"Claude Sonnet 4.6","family":"claude-sonnet","context_window":1000000,"max_output":128000,"cost":{"input":3,"output":15,"cache_read":0.3,"cache_write":3.75},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-17"},"openrouter/anthropic/claude-sonnet-5":{"provider":"openrouter","id":"anthropic/claude-sonnet-5","name":"Claude Sonnet 5","family":"claude-sonnet","context_window":1000000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-06-30"},"openrouter/arcee-ai/trinity-large-thinking":{"provider":"openrouter","id":"arcee-ai/trinity-large-thinking","name":"Trinity Large Thinking","family":"trinity","context_window":262144,"max_output":80000,"cost":{"input":0.25,"output":0.8,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-04-01"},"openrouter/auto":{"provider":"openrouter","id":"auto","name":"Auto Router","family":"auto","context_window":2000000,"max_output":2000000,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2023-11-08"},"openrouter/baidu/ernie-4.5-vl-424b-a47b":{"provider":"openrouter","id":"baidu/ernie-4.5-vl-424b-a47b","name":"ERNIE 4.5 VL 424B A47B ","family":"ernie","context_window":123000,"max_output":16000,"cost":{"input":0.42,"output":1.25},"reasoning":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-06-30"},"openrouter/bodybuilder":{"provider":"openrouter","id":"bodybuilder","name":"Body Builder (beta)","context_window":128000,"max_output":128000,"release_date":"2025-12-05"},"openrouter/bytedance-seed/seed-1.6":{"provider":"openrouter","id":"bytedance-seed/seed-1.6","name":"Seed 1.6","family":"seed","context_window":262144,"max_output":32768,"cost":{"input":0.25,"output":2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2025-12-23"},"openrouter/bytedance-seed/seed-1.6-flash":{"provider":"openrouter","id":"bytedance-seed/seed-1.6-flash","name":"Seed 1.6 Flash","family":"seed","context_window":262144,"max_output":32768,"cost":{"input":0.075,"output":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2025-12-23"},"openrouter/bytedance-seed/seed-2-1-turbo":{"provider":"openrouter","id":"bytedance-seed/seed-2-1-turbo","name":"Seed 2.1 Turbo","family":"seed","context_window":262144,"max_output":235929,"cost":{"input":0.5,"output":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-12"},"openrouter/bytedance-seed/seed-2.0-code":{"provider":"openrouter","id":"bytedance-seed/seed-2.0-code","name":"Seed 2.0 Code","family":"seed","context_window":262144,"max_output":131072,"cost":{"input":0.5,"output":3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-02-14"},"openrouter/bytedance-seed/seed-2.0-lite":{"provider":"openrouter","id":"bytedance-seed/seed-2.0-lite","name":"Seed 2.0 Lite","family":"seed","context_window":262144,"max_output":131072,"cost":{"input":0.25,"output":2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-02-14"},"openrouter/bytedance-seed/seed-2.0-mini":{"provider":"openrouter","id":"bytedance-seed/seed-2.0-mini","name":"Seed 2.0 Mini","family":"seed","context_window":262144,"max_output":131072,"cost":{"input":0.1,"output":0.4},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-02-14"},"openrouter/bytedance/ui-tars-1.5-7b":{"provider":"openrouter","id":"bytedance/ui-tars-1.5-7b","name":"UI-TARS 7B ","context_window":128000,"max_output":2048,"cost":{"input":0.1,"output":0.2,"cache_read":0.1},"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01-31","release_date":"2025-07-22"},"openrouter/cognitivecomputations/dolphin-mistral-24b-venice-edition":{"provider":"openrouter","id":"cognitivecomputations/dolphin-mistral-24b-venice-edition","name":"Uncensored","family":"mistral","context_window":128000,"max_output":8192,"cost":{"input":0.2,"output":0.9},"open_weights":true,"knowledge_cutoff":"2024-04-30","release_date":"2025-07-09"},"openrouter/cohere/command-a":{"provider":"openrouter","id":"cohere/command-a","name":"Command A","family":"command-a","context_window":256000,"max_output":8192,"cost":{"input":2.5,"output":10},"open_weights":true,"knowledge_cutoff":"2024-08-31","release_date":"2025-03-13"},"openrouter/cohere/command-r-08-2024":{"provider":"openrouter","id":"cohere/command-r-08-2024","name":"Command R","family":"command-r","context_window":128000,"max_output":4000,"cost":{"input":0.15,"output":0.6},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2024-08-30"},"openrouter/cohere/command-r-plus-08-2024":{"provider":"openrouter","id":"cohere/command-r-plus-08-2024","name":"Command R+","family":"command-r","context_window":128000,"max_output":4000,"cost":{"input":2.5,"output":10},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2024-08-30"},"openrouter/cohere/command-r7b-12-2024":{"provider":"openrouter","id":"cohere/command-r7b-12-2024","name":"Command R7B","family":"command-r","context_window":128000,"max_output":4000,"cost":{"input":0.0375,"output":0.15},"open_weights":true,"knowledge_cutoff":"2024-06-01","release_date":"2024-12-02"},"openrouter/cohere/north-mini-code:free":{"provider":"openrouter","id":"cohere/north-mini-code:free","name":"North Mini Code (free)","family":"north","context_window":256000,"max_output":64000,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-17"},"openrouter/deepseek/deepseek-chat":{"provider":"openrouter","id":"deepseek/deepseek-chat","name":"DeepSeek Chat","family":"deepseek","context_window":163840,"max_output":16000,"cost":{"input":0.2574,"output":1.0287},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-09","release_date":"2025-12-01"},"openrouter/deepseek/deepseek-chat-v3-0324":{"provider":"openrouter","id":"deepseek/deepseek-chat-v3-0324","name":"DeepSeek V3 0324","family":"deepseek","context_window":163840,"max_output":147456,"cost":{"input":0.25,"output":1},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-07-31","release_date":"2025-03-24"},"openrouter/deepseek/deepseek-chat-v3.1":{"provider":"openrouter","id":"deepseek/deepseek-chat-v3.1","name":"DeepSeek V3.1","family":"deepseek","context_window":163840,"max_output":32768,"cost":{"input":0.25,"output":0.95,"cache_read":0.13},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-08-21"},"openrouter/deepseek/deepseek-r1":{"provider":"openrouter","id":"deepseek/deepseek-r1","name":"DeepSeek-R1","family":"deepseek-thinking","context_window":64000,"max_output":16000,"cost":{"input":0.7,"output":2.5},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2025-01-20"},"openrouter/deepseek/deepseek-r1-0528":{"provider":"openrouter","id":"deepseek/deepseek-r1-0528","name":"R1 0528","family":"deepseek","context_window":163840,"max_output":32768,"cost":{"input":0.5,"output":2.15,"cache_read":0.35},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-05-28"},"openrouter/deepseek/deepseek-r1-distill-llama-70b":{"provider":"openrouter","id":"deepseek/deepseek-r1-distill-llama-70b","name":"R1 Distill Llama 70B","family":"deepseek-thinking","context_window":8192,"max_output":7372,"cost":{"input":0.8,"output":0.8},"reasoning":true,"open_weights":true,"knowledge_cutoff":"2024-07-31","release_date":"2025-01-23"},"openrouter/deepseek/deepseek-v3.1-terminus":{"provider":"openrouter","id":"deepseek/deepseek-v3.1-terminus","name":"DeepSeek V3.1 Terminus","family":"deepseek","context_window":163840,"max_output":32768,"cost":{"input":0.27,"output":1,"cache_read":0.135},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-09-22"},"openrouter/deepseek/deepseek-v3.2":{"provider":"openrouter","id":"deepseek/deepseek-v3.2","name":"DeepSeek V3.2","family":"deepseek","context_window":163840,"max_output":65536,"cost":{"input":0.269,"output":0.4,"cache_read":0.1345},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2025-12-01"},"openrouter/deepseek/deepseek-v3.2-exp":{"provider":"openrouter","id":"deepseek/deepseek-v3.2-exp","name":"DeepSeek V3.2 Exp","family":"deepseek","context_window":163840,"max_output":65536,"cost":{"input":0.27,"output":0.41},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-07-31","release_date":"2025-09-29"},"openrouter/deepseek/deepseek-v4-flash":{"provider":"openrouter","id":"deepseek/deepseek-v4-flash","name":"DeepSeek V4 Flash","family":"deepseek-flash","context_window":1048576,"max_output":384000,"cost":{"input":0.088606,"output":0.177212,"cache_read":0.017721},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-04-24"},"openrouter/deepseek/deepseek-v4-flash-0731":{"provider":"openrouter","id":"deepseek/deepseek-v4-flash-0731","name":"DeepSeek V4 Flash 0731","family":"deepseek-flash","context_window":1310720,"max_output":943718,"cost":{"input":0.06,"output":0.12,"cache_read":0.012},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-07-31"},"openrouter/deepseek/deepseek-v4-flash-vision-exp":{"provider":"openrouter","id":"deepseek/deepseek-v4-flash-vision-exp","name":"DeepSeek V4 Flash Vision Exp","family":"deepseek-flash","context_window":1048576,"max_output":943718,"cost":{"input":0.22,"output":0.66,"cache_read":0.007},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-21"},"openrouter/deepseek/deepseek-v4-pro":{"provider":"openrouter","id":"deepseek/deepseek-v4-pro","name":"DeepSeek V4 Pro","family":"deepseek-thinking","context_window":1048576,"max_output":393216,"cost":{"input":1.6,"output":3.2,"cache_read":0.135},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-04-24"},"openrouter/deepseek/deepseek-v4-pro-0813":{"provider":"openrouter","id":"deepseek/deepseek-v4-pro-0813","name":"DeepSeek V4 Pro 0813","family":"deepseek-thinking","context_window":1048576,"max_output":384000,"cost":{"input":0.9834,"output":2.9502,"cache_read":0.03278},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-12"},"openrouter/deepseek/deepseek-v4.1-flash":{"provider":"openrouter","id":"deepseek/deepseek-v4.1-flash","name":"DeepSeek V4.1 Flash","family":"deepseek-flash","context_window":1048576,"max_output":384000,"cost":{"input":0.3,"output":1.2,"cache_read":0.006},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-09-10"},"openrouter/dots-studio/dots-3-note-preview:free":{"provider":"openrouter","id":"dots-studio/dots-3-note-preview:free","name":"Dots3-Note Preview (free)","context_window":512000,"max_output":460800,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-14"},"openrouter/free":{"provider":"openrouter","id":"free","name":"Free Models Router","context_window":200000,"max_output":8000,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-02-01"},"openrouter/fusion":{"provider":"openrouter","id":"fusion","name":"Fusion","context_window":1000000,"max_output":128000,"release_date":"2026-06-13"},"openrouter/google/gemini-2.5-flash":{"provider":"openrouter","id":"google/gemini-2.5-flash","name":"Gemini 2.5 Flash","family":"gemini-flash","context_window":1048576,"max_output":65535,"cost":{"input":0.3,"output":2.5,"cache_read":0.03,"cache_write":0.083333},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-06-17"},"openrouter/google/gemini-2.5-flash-image":{"provider":"openrouter","id":"google/gemini-2.5-flash-image","name":"Nano Banana","family":"gemini-flash","context_window":32768,"max_output":8192,"cost":{"input":0.3,"output":2.5,"cache_read":0.03,"cache_write":0.083333},"attachment":true,"vision":true,"knowledge_cutoff":"2024-06","release_date":"2025-08-26"},"openrouter/google/gemini-2.5-flash-lite":{"provider":"openrouter","id":"google/gemini-2.5-flash-lite","name":"Gemini 2.5 Flash-Lite","family":"gemini-flash-lite","context_window":1048576,"max_output":65535,"cost":{"input":0.1,"output":0.4,"cache_read":0.01,"cache_write":0.083333},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-06-17"},"openrouter/google/gemini-2.5-pro":{"provider":"openrouter","id":"google/gemini-2.5-pro","name":"Gemini 2.5 Pro","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":1.25,"output":10,"cache_read":0.125,"cache_write":0.375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-06-17"},"openrouter/google/gemini-2.5-pro-preview":{"provider":"openrouter","id":"google/gemini-2.5-pro-preview","name":"Gemini 2.5 Pro Preview 06-05","family":"gemini","context_window":1048576,"max_output":65536,"cost":{"input":1.25,"output":10,"cache_read":0.125,"cache_write":0.375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01-31","release_date":"2025-06-05"},"openrouter/google/gemini-3-flash-preview":{"provider":"openrouter","id":"google/gemini-3-flash-preview","name":"Gemini 3 Flash Preview","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.5,"output":3,"cache_read":0.05,"cache_write":0.083333},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2025-12-17"},"openrouter/google/gemini-3-pro-image":{"provider":"openrouter","id":"google/gemini-3-pro-image","name":"Nano Banana Pro","family":"gemini-pro","context_window":131072,"max_output":32768,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":0.375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-28"},"openrouter/google/gemini-3-pro-image-preview":{"provider":"openrouter","id":"google/gemini-3-pro-image-preview","name":"Nano Banana Pro Preview","family":"gemini-pro","context_window":65536,"max_output":32768,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":0.375},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2025-11-20"},"openrouter/google/gemini-3.1-flash-image":{"provider":"openrouter","id":"google/gemini-3.1-flash-image","name":"Nano Banana 2","family":"gemini-flash","context_window":131072,"max_output":32768,"cost":{"input":0.5,"output":3},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-28"},"openrouter/google/gemini-3.1-flash-image-preview":{"provider":"openrouter","id":"google/gemini-3.1-flash-image-preview","name":"Nano Banana 2 Preview","family":"gemini-flash","context_window":65536,"max_output":58982,"cost":{"input":0.5,"output":3},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-26"},"openrouter/google/gemini-3.1-flash-lite":{"provider":"openrouter","id":"google/gemini-3.1-flash-lite","name":"Gemini 3.1 Flash Lite","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.25,"output":1.5,"cache_read":0.025,"cache_write":0.083333},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-07"},"openrouter/google/gemini-3.1-flash-lite-image":{"provider":"openrouter","id":"google/gemini-3.1-flash-lite-image","name":"Nano Banana 2 Lite","family":"gemini-flash-lite","context_window":65536,"max_output":58982,"cost":{"input":0.25,"output":1.5},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-01","release_date":"2026-06-30"},"openrouter/google/gemini-3.1-flash-lite-preview":{"provider":"openrouter","id":"google/gemini-3.1-flash-lite-preview","name":"Gemini 3.1 Flash Lite Preview","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.25,"output":1.5,"cache_read":0.025,"cache_write":0.083333},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-03-03"},"openrouter/google/gemini-3.1-pro-preview":{"provider":"openrouter","id":"google/gemini-3.1-pro-preview","name":"Gemini 3.1 Pro Preview","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":0.375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-19"},"openrouter/google/gemini-3.1-pro-preview-customtools":{"provider":"openrouter","id":"google/gemini-3.1-pro-preview-customtools","name":"Gemini 3.1 Pro Preview Custom Tools","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":0.375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-02-19"},"openrouter/google/gemini-3.5-flash":{"provider":"openrouter","id":"google/gemini-3.5-flash","name":"Gemini 3.5 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":1.5,"output":9,"cache_read":0.15,"cache_write":0.083333},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-05-19"},"openrouter/google/gemini-3.5-flash-lite":{"provider":"openrouter","id":"google/gemini-3.5-flash-lite","name":"Gemini 3.5 Flash Lite","family":"gemini-flash-lite","context_window":1048576,"max_output":65536,"cost":{"input":0.3,"output":2.5,"cache_read":0.03,"cache_write":0.083333},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"openrouter/google/gemini-3.6-flash":{"provider":"openrouter","id":"google/gemini-3.6-flash","name":"Gemini 3.6 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075,"cache_write":0.041667},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-07-21"},"openrouter/google/gemini-3.7-flash":{"provider":"openrouter","id":"google/gemini-3.7-flash","name":"Gemini 3.7 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075,"cache_write":0.041667},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-03","release_date":"2026-08-13"},"openrouter/google/gemini-3.8-flash":{"provider":"openrouter","id":"google/gemini-3.8-flash","name":"Gemini 3.8 Flash","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075,"cache_write":0.041667},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-02"},"openrouter/google/gemma-2-27b-it":{"provider":"openrouter","id":"google/gemma-2-27b-it","name":"Gemma 2 27B","family":"gemma","context_window":8192,"max_output":2048,"cost":{"input":0.65,"output":0.65},"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2024-07-13"},"openrouter/google/gemma-3-12b-it":{"provider":"openrouter","id":"google/gemma-3-12b-it","name":"Gemma 3 12B IT","family":"gemma","context_window":131072,"max_output":16384,"cost":{"input":0.05,"output":0.15},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-08","release_date":"2025-03-12"},"openrouter/google/gemma-3-27b-it":{"provider":"openrouter","id":"google/gemma-3-27b-it","name":"Gemma 3 27B IT","family":"gemma","context_window":131072,"max_output":117964,"cost":{"input":0.08,"output":0.45,"cache_read":0.04},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-08","release_date":"2025-03-12"},"openrouter/google/gemma-3-4b-it":{"provider":"openrouter","id":"google/gemma-3-4b-it","name":"Gemma 3 4B IT","family":"gemma","context_window":131072,"max_output":16384,"cost":{"input":0.05,"output":0.1},"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-08","release_date":"2025-03-12"},"openrouter/google/gemma-4-26b-a4b-it":{"provider":"openrouter","id":"google/gemma-4-26b-a4b-it","name":"Gemma 4 26B A4B IT","family":"gemma","context_window":262144,"max_output":235929,"cost":{"input":0.09,"output":0.3,"cache_read":0.05},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-02"},"openrouter/google/gemma-4-26b-a4b-it:free":{"provider":"openrouter","id":"google/gemma-4-26b-a4b-it:free","name":"Gemma 4 26B A4B (free)","family":"gemma","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-02"},"openrouter/google/gemma-4-31b-it":{"provider":"openrouter","id":"google/gemma-4-31b-it","name":"Gemma 4 31B IT","family":"gemma","context_window":262144,"max_output":16384,"cost":{"input":0.09,"output":0.34,"cache_read":0.05},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-02"},"openrouter/google/gemma-4-31b-it:free":{"provider":"openrouter","id":"google/gemma-4-31b-it:free","name":"Gemma 4 31B (free)","family":"gemma","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-02"},"openrouter/google/lyria-3-clip-preview":{"provider":"openrouter","id":"google/lyria-3-clip-preview","name":"Lyria 3 Clip Preview","family":"lyria","context_window":1048576,"max_output":65536,"attachment":true,"vision":true,"release_date":"2026-03-25"},"openrouter/google/lyria-3-pro-preview":{"provider":"openrouter","id":"google/lyria-3-pro-preview","name":"Lyria 3 Pro Preview","family":"lyria","context_window":1048576,"max_output":65536,"attachment":true,"vision":true,"release_date":"2026-03-25"},"openrouter/gryphe/mythomax-l2-13b":{"provider":"openrouter","id":"gryphe/mythomax-l2-13b","name":"MythoMax 13B","context_window":8192,"max_output":3686,"cost":{"input":0.06,"output":0.06},"open_weights":true,"knowledge_cutoff":"2023-06-30","release_date":"2023-07-02"},"openrouter/ibm-granite/granite-4.0-h-micro":{"provider":"openrouter","id":"ibm-granite/granite-4.0-h-micro","name":"Granite 4.0 Micro","family":"granite","context_window":131000,"max_output":117900,"cost":{"input":0.017,"output":0.112},"open_weights":true,"release_date":"2025-10-20"},"openrouter/ibm-granite/granite-4.2-8b":{"provider":"openrouter","id":"ibm-granite/granite-4.2-8b","name":"Granite 4.2 8B","family":"granite","context_window":131072,"max_output":117964,"cost":{"input":0.06,"output":0.25,"cache_read":0.015},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-31"},"openrouter/inception/mercury-2":{"provider":"openrouter","id":"inception/mercury-2","name":"Mercury 2","family":"mercury","context_window":128000,"max_output":50000,"cost":{"input":0.25,"output":0.75,"cache_read":0.025},"reasoning":true,"tool_call":true,"release_date":"2026-03-04"},"openrouter/inception/mercury-2.5":{"provider":"openrouter","id":"inception/mercury-2.5","name":"Mercury 2.5","family":"mercury","context_window":260000,"max_output":65536,"cost":{"input":0.04,"output":0.15,"cache_read":0.004},"reasoning":true,"tool_call":true,"release_date":"2026-09-08"},"openrouter/inclusionai/ling-3.0-flash":{"provider":"openrouter","id":"inclusionai/ling-3.0-flash","name":"Ling 3.0 Flash","family":"ling","context_window":262144,"max_output":32768,"cost":{"input":0.021,"output":0.063,"cache_read":0.0042},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-23"},"openrouter/inclusionai/ling-3.0-flash-fin":{"provider":"openrouter","id":"inclusionai/ling-3.0-flash-fin","name":"Ling 3.0 Flash Fin","family":"ling","context_window":262144,"max_output":235929,"cost":{"input":0.06,"output":0.18,"cache_read":0.012},"reasoning":true,"tool_call":true,"release_date":"2026-08-27"},"openrouter/inclusionai/ling-3.0-flash-fin:free":{"provider":"openrouter","id":"inclusionai/ling-3.0-flash-fin:free","name":"Ling 3.0 Flash Fin (free)","family":"ling","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"release_date":"2026-08-27"},"openrouter/inclusionai/ling-3.0-flash-sante:free":{"provider":"openrouter","id":"inclusionai/ling-3.0-flash-sante:free","name":"Ling 3.0 Flash Sante (free)","family":"ling","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"release_date":"2026-09-04"},"openrouter/inclusionai/ling-3.0-flash-vl":{"provider":"openrouter","id":"inclusionai/ling-3.0-flash-vl","name":"Ling 3.0 Flash VL","family":"ling","context_window":131072,"max_output":32768,"cost":{"input":0.06,"output":0.18,"cache_read":0.012},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-09-10"},"openrouter/inclusionai/ling-3.0-flash-vl:free":{"provider":"openrouter","id":"inclusionai/ling-3.0-flash-vl:free","name":"Ling 3.0 Flash VL (free)","family":"ling","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-09-10"},"openrouter/inference-net/schematron-v2-small":{"provider":"openrouter","id":"inference-net/schematron-v2-small","name":"Schematron V2 Small","context_window":128000,"max_output":4096,"cost":{"input":0.05,"output":0.23,"cache_read":0.05},"open_weights":true,"release_date":"2026-09-12"},"openrouter/inference-net/schematron-v2-turbo":{"provider":"openrouter","id":"inference-net/schematron-v2-turbo","name":"Schematron V2 Turbo","context_window":128000,"max_output":8192,"cost":{"input":0.03,"output":0.15,"cache_read":0.03},"open_weights":true,"release_date":"2026-09-12"},"openrouter/kwaipilot/kat-coder-pro-v2":{"provider":"openrouter","id":"kwaipilot/kat-coder-pro-v2","name":"KAT-Coder-Pro V2","family":"kat-coder","context_window":262144,"max_output":144000,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"tool_call":true,"release_date":"2026-03-27"},"openrouter/kwaipilot/kat-coder-pro-v2.5":{"provider":"openrouter","id":"kwaipilot/kat-coder-pro-v2.5","name":"KAT-Coder-Pro V2.5","family":"kat-coder","context_window":262144,"max_output":235929,"cost":{"input":0.74,"output":2.96,"cache_read":0.15},"tool_call":true,"release_date":"2026-07-10"},"openrouter/liquid/lfm-2.5-2.6b:free":{"provider":"openrouter","id":"liquid/lfm-2.5-2.6b:free","name":"LFM2.5-2.6B (free)","family":"liquid","context_window":65536,"max_output":8192,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-11"},"openrouter/mancer/weaver":{"provider":"openrouter","id":"mancer/weaver","name":"Weaver (alpha)","family":"alpha","context_window":8000,"max_output":6000,"cost":{"input":0.4,"output":0.75},"knowledge_cutoff":"2023-06-30","release_date":"2023-08-02"},"openrouter/meituan/longcat-2.0":{"provider":"openrouter","id":"meituan/longcat-2.0","name":"LongCat 2.0","family":"longcat","context_window":1048756,"max_output":262144,"cost":{"input":0.3,"output":1.2,"cache_read":0.006},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-20"},"openrouter/meta-llama/llama-3.1-70b-instruct":{"provider":"openrouter","id":"meta-llama/llama-3.1-70b-instruct","name":"Llama-3.1-70B-Instruct","family":"llama","context_window":131072,"max_output":16384,"cost":{"input":0.4,"output":0.4},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-07-23"},"openrouter/meta-llama/llama-3.1-8b-instruct":{"provider":"openrouter","id":"meta-llama/llama-3.1-8b-instruct","name":"Llama-3.1-8B-Instruct","family":"llama","context_window":131072,"max_output":117964,"cost":{"input":0.05,"output":0.08,"cache_read":0.025},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-07-23"},"openrouter/meta-llama/llama-3.2-1b-instruct":{"provider":"openrouter","id":"meta-llama/llama-3.2-1b-instruct","name":"Llama 3.2 1B Instruct","family":"llama","context_window":60000,"max_output":54000,"cost":{"input":0.027,"output":0.201},"open_weights":true,"knowledge_cutoff":"2023-12-31","release_date":"2024-09-25"},"openrouter/meta-llama/llama-3.2-3b-instruct":{"provider":"openrouter","id":"meta-llama/llama-3.2-3b-instruct","name":"Llama 3.2 3B Instruct","family":"llama","context_window":131072,"max_output":117964,"cost":{"input":0.05,"output":0.33},"open_weights":true,"knowledge_cutoff":"2023-12-31","release_date":"2024-09-25"},"openrouter/meta-llama/llama-3.3-70b-instruct":{"provider":"openrouter","id":"meta-llama/llama-3.3-70b-instruct","name":"Llama-3.3-70B-Instruct","family":"llama","context_window":131072,"max_output":16384,"cost":{"input":0.1,"output":0.32},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-12-06"},"openrouter/meta-llama/llama-4-maverick":{"provider":"openrouter","id":"meta-llama/llama-4-maverick","name":"Llama 4 Maverick","family":"llama","context_window":1048576,"max_output":16384,"cost":{"input":0.1875,"output":0.6525},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-08-31","release_date":"2025-04-05"},"openrouter/meta-llama/llama-4-scout":{"provider":"openrouter","id":"meta-llama/llama-4-scout","name":"Llama 4 Scout","family":"llama","context_window":1310720,"max_output":16384,"cost":{"input":0.1,"output":0.3},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-08-31","release_date":"2025-04-05"},"openrouter/meta-llama/llama-guard-4-12b":{"provider":"openrouter","id":"meta-llama/llama-guard-4-12b","name":"Llama Guard 4 12B","family":"llama","context_window":163840,"max_output":16384,"cost":{"input":0.18,"output":0.18},"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-08-31","release_date":"2025-04-30"},"openrouter/meta/muse-glimmer-30b":{"provider":"openrouter","id":"meta/muse-glimmer-30b","name":"Muse Glimmer 30B","family":"muse","context_window":131072,"max_output":117964,"cost":{"input":0.35,"output":1.5,"cache_read":0.04},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2026-01-04","release_date":"2026-08-10"},"openrouter/meta/muse-spark-1.1":{"provider":"openrouter","id":"meta/muse-spark-1.1","name":"Muse Spark 1.1","family":"muse","context_window":1048576,"max_output":943718,"cost":{"input":1.25,"output":4.25,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-08"},"openrouter/meta/muse-spark-1.2":{"provider":"openrouter","id":"meta/muse-spark-1.2","name":"Muse Spark 1.2","family":"muse","context_window":1048576,"max_output":943718,"cost":{"input":1.25,"output":4.25,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-05"},"openrouter/meta/muse-spark-1.2-contributor":{"provider":"openrouter","id":"meta/muse-spark-1.2-contributor","name":"Muse Spark 1.2 Contributor","family":"muse","context_window":1048576,"max_output":943718,"cost":{"input":0.1,"output":0.2,"cache_read":0.002},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-21"},"openrouter/meta/muse-spark-1.3":{"provider":"openrouter","id":"meta/muse-spark-1.3","name":"Muse Spark 1.3","family":"muse","context_window":1048576,"max_output":943718,"cost":{"input":1.25,"output":4.25,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-02"},"openrouter/meta/muse-spark-1.3-contributor":{"provider":"openrouter","id":"meta/muse-spark-1.3-contributor","name":"Muse Spark 1.3 Contributor","family":"muse","context_window":1048576,"max_output":943718,"cost":{"input":0.1,"output":0.2,"cache_read":0.002},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-02"},"openrouter/microsoft/phi-4":{"provider":"openrouter","id":"microsoft/phi-4","name":"Phi 4","family":"phi","context_window":16384,"max_output":14745,"cost":{"input":0.07,"output":0.14},"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2025-01-10"},"openrouter/microsoft/wizardlm-2-8x22b":{"provider":"openrouter","id":"microsoft/wizardlm-2-8x22b","name":"WizardLM-2 8x22B","context_window":65535,"max_output":8000,"cost":{"input":0.62,"output":0.62},"open_weights":true,"knowledge_cutoff":"2024-04-30","release_date":"2024-04-16"},"openrouter/minimax/minimax-01":{"provider":"openrouter","id":"minimax/minimax-01","name":"MiniMax-01","family":"minimax","context_window":1000192,"max_output":900172,"cost":{"input":0.2,"output":1.1},"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-03-31","release_date":"2025-01-15"},"openrouter/minimax/minimax-m1":{"provider":"openrouter","id":"minimax/minimax-m1","name":"MiniMax M1","family":"minimax","context_window":1000000,"max_output":40000,"cost":{"input":0.55,"output":2.2},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2024-06-30","release_date":"2025-06-17"},"openrouter/minimax/minimax-m2":{"provider":"openrouter","id":"minimax/minimax-m2","name":"MiniMax-M2","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.255,"output":1.02},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-10-27"},"openrouter/minimax/minimax-m2-her":{"provider":"openrouter","id":"minimax/minimax-m2-her","name":"MiniMax-M2 Her","family":"minimax","context_window":65536,"max_output":2048,"cost":{"input":0.3,"output":1.2,"cache_read":0.03},"release_date":"2026-01-23"},"openrouter/minimax/minimax-m2.1":{"provider":"openrouter","id":"minimax/minimax-m2.1","name":"MiniMax-M2.1","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.03},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-12-23"},"openrouter/minimax/minimax-m2.5":{"provider":"openrouter","id":"minimax/minimax-m2.5","name":"MiniMax-M2.5","family":"minimax","context_window":204800,"max_output":128000,"cost":{"input":0.27,"output":1.08,"cache_read":0.027},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-12"},"openrouter/minimax/minimax-m2.7":{"provider":"openrouter","id":"minimax/minimax-m2.7","name":"MiniMax-M2.7","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-03-18"},"openrouter/minimax/minimax-m3":{"provider":"openrouter","id":"minimax/minimax-m3","name":"MiniMax-M3","family":"minimax","context_window":1048576,"max_output":512000,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-01"},"openrouter/mistralai/codestral-2508":{"provider":"openrouter","id":"mistralai/codestral-2508","name":"Codestral 2508","family":"codestral","context_window":256000,"max_output":204800,"cost":{"input":0.3,"output":0.9,"cache_read":0.03},"tool_call":true,"attachment":true,"pdf":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-08-01"},"openrouter/mistralai/devstral-2512":{"provider":"openrouter","id":"mistralai/devstral-2512","name":"Devstral 2","family":"devstral","context_window":262144,"max_output":209715,"cost":{"input":0.4,"output":2,"cache_read":0.04},"tool_call":true,"attachment":true,"pdf":true,"open_weights":true,"knowledge_cutoff":"2025-12","release_date":"2025-12-09"},"openrouter/mistralai/ministral-14b-2512":{"provider":"openrouter","id":"mistralai/ministral-14b-2512","name":"Ministral 3 14B 2512","family":"ministral","context_window":262144,"max_output":209715,"cost":{"input":0.2,"output":0.2,"cache_read":0.02},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-12-02"},"openrouter/mistralai/ministral-3b-2512":{"provider":"openrouter","id":"mistralai/ministral-3b-2512","name":"Ministral 3 3B 2512","family":"ministral","context_window":131072,"max_output":104857,"cost":{"input":0.1,"output":0.1,"cache_read":0.01},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-12-02"},"openrouter/mistralai/ministral-8b-2512":{"provider":"openrouter","id":"mistralai/ministral-8b-2512","name":"Ministral 3 8B 2512","family":"ministral","context_window":262144,"max_output":209715,"cost":{"input":0.15,"output":0.15,"cache_read":0.015},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-12-02"},"openrouter/mistralai/mistral-large":{"provider":"openrouter","id":"mistralai/mistral-large","name":"Mistral Large","family":"mistral-large","context_window":128000,"max_output":102400,"cost":{"input":2,"output":6,"cache_read":0.2},"tool_call":true,"attachment":true,"pdf":true,"knowledge_cutoff":"2024-11-30","release_date":"2024-02-26"},"openrouter/mistralai/mistral-large-2407":{"provider":"openrouter","id":"mistralai/mistral-large-2407","name":"Mistral Large 2407","family":"mistral-large","context_window":131072,"max_output":104857,"cost":{"input":2,"output":6,"cache_read":0.2},"tool_call":true,"attachment":true,"pdf":true,"knowledge_cutoff":"2024-03-31","release_date":"2024-11-19"},"openrouter/mistralai/mistral-large-2512":{"provider":"openrouter","id":"mistralai/mistral-large-2512","name":"Mistral Large 3","family":"mistral-large","context_window":262144,"max_output":209715,"cost":{"input":0.5,"output":1.5,"cache_read":0.05},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"open_weights":true,"knowledge_cutoff":"2024-11","release_date":"2025-12-02"},"openrouter/mistralai/mistral-medium-3":{"provider":"openrouter","id":"mistralai/mistral-medium-3","name":"Mistral Medium 3","family":"mistral-medium","context_window":131072,"max_output":104857,"cost":{"input":0.4,"output":2,"cache_read":0.04},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-05-07"},"openrouter/mistralai/mistral-medium-3-5":{"provider":"openrouter","id":"mistralai/mistral-medium-3-5","name":"Mistral Medium 3.5","family":"mistral-medium","context_window":262144,"max_output":209715,"cost":{"input":1.5,"output":7.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-30"},"openrouter/mistralai/mistral-medium-3.1":{"provider":"openrouter","id":"mistralai/mistral-medium-3.1","name":"Mistral Medium 3.1","family":"mistral-medium","context_window":131072,"max_output":104857,"cost":{"input":0.4,"output":2,"cache_read":0.04},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-06-30","release_date":"2025-08-13"},"openrouter/mistralai/mistral-nemo":{"provider":"openrouter","id":"mistralai/mistral-nemo","name":"Mistral Nemo","family":"mistral-nemo","context_window":131072,"max_output":16384,"cost":{"input":0.019,"output":0.03},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2024-07-01"},"openrouter/mistralai/mistral-saba":{"provider":"openrouter","id":"mistralai/mistral-saba","name":"Saba","family":"mistral","context_window":32768,"max_output":26214,"cost":{"input":0.2,"output":0.6,"cache_read":0.02},"tool_call":true,"attachment":true,"pdf":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-02-17"},"openrouter/mistralai/mistral-small-24b-instruct-2501":{"provider":"openrouter","id":"mistralai/mistral-small-24b-instruct-2501","name":"Mistral Small 3","family":"mistral-small","context_window":32768,"max_output":16384,"cost":{"input":0.05,"output":0.08},"open_weights":true,"knowledge_cutoff":"2023-10-31","release_date":"2025-01-30"},"openrouter/mistralai/mistral-small-2603":{"provider":"openrouter","id":"mistralai/mistral-small-2603","name":"Mistral Small 4","family":"mistral-small","context_window":262144,"max_output":209715,"cost":{"input":0.15,"output":0.6,"cache_read":0.015},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-06","release_date":"2026-03-16"},"openrouter/mistralai/mistral-small-3.1-24b-instruct":{"provider":"openrouter","id":"mistralai/mistral-small-3.1-24b-instruct","name":"Mistral Small 3.1 24B","family":"mistral-small","context_window":128000,"max_output":102400,"cost":{"input":0.351,"output":0.555},"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2023-10-31","release_date":"2025-03-17"},"openrouter/mistralai/mistral-small-3.2-24b-instruct":{"provider":"openrouter","id":"mistralai/mistral-small-3.2-24b-instruct","name":"Mistral Small 3.2 24B","family":"mistral-small","context_window":256000,"max_output":16384,"cost":{"input":0.075,"output":0.2},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2023-10-31","release_date":"2025-06-20"},"openrouter/mistralai/mixtral-8x22b-instruct":{"provider":"openrouter","id":"mistralai/mixtral-8x22b-instruct","name":"Mixtral 8x22B Instruct","family":"mistral","context_window":65536,"max_output":52428,"cost":{"input":2,"output":6,"cache_read":0.2},"tool_call":true,"attachment":true,"pdf":true,"open_weights":true,"knowledge_cutoff":"2024-01-31","release_date":"2024-04-17"},"openrouter/mistralai/voxtral-small-24b-2507":{"provider":"openrouter","id":"mistralai/voxtral-small-24b-2507","name":"Voxtral Small 24B 2507","family":"voxtral","context_window":32768,"max_output":26214,"cost":{"input":0.1,"output":0.3,"cache_read":0.01},"tool_call":true,"attachment":true,"pdf":true,"open_weights":true,"release_date":"2025-07-15"},"openrouter/moonshotai/kimi-k2":{"provider":"openrouter","id":"moonshotai/kimi-k2","name":"Kimi K2 0711","family":"kimi-k2","context_window":131072,"max_output":98304,"cost":{"input":0.57,"output":2.3},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-12-31","release_date":"2025-07-11"},"openrouter/moonshotai/kimi-k2-0905":{"provider":"openrouter","id":"moonshotai/kimi-k2-0905","name":"Kimi K2 0905","family":"kimi-k2","context_window":262144,"max_output":98304,"cost":{"input":0.6,"output":2.5},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-12-31","release_date":"2025-09-04"},"openrouter/moonshotai/kimi-k2-thinking":{"provider":"openrouter","id":"moonshotai/kimi-k2-thinking","name":"Kimi K2 Thinking","family":"kimi-thinking","context_window":262144,"max_output":98304,"cost":{"input":0.6,"output":2.5,"cache_read":0.15},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-08","release_date":"2025-11-06"},"openrouter/moonshotai/kimi-k2.5":{"provider":"openrouter","id":"moonshotai/kimi-k2.5","name":"Kimi K2.5","family":"kimi-k2","context_window":262144,"max_output":235929,"cost":{"input":0.45,"output":2.25,"cache_read":0.07},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-01"},"openrouter/moonshotai/kimi-k2.6":{"provider":"openrouter","id":"moonshotai/kimi-k2.6","name":"Kimi K2.6","family":"kimi-k2","context_window":262144,"max_output":235929,"cost":{"input":0.95,"output":4,"cache_read":0.16},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-21"},"openrouter/moonshotai/kimi-k2.7-code":{"provider":"openrouter","id":"moonshotai/kimi-k2.7-code","name":"Kimi K2.7 Code","family":"kimi-k2","context_window":262144,"max_output":235929,"cost":{"input":0.71,"output":3.5,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-06-12"},"openrouter/moonshotai/kimi-k3":{"provider":"openrouter","id":"moonshotai/kimi-k3","name":"Kimi K3","family":"kimi-k3","context_window":1048576,"max_output":943718,"cost":{"input":2.648138,"output":13.282724,"cache_read":0.302644},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-16"},"openrouter/morph/morph-v3-fast":{"provider":"openrouter","id":"morph/morph-v3-fast","name":"Morph V3 Fast","family":"morph","context_window":81920,"max_output":38000,"cost":{"input":0.8,"output":1.2},"release_date":"2025-07-07"},"openrouter/morph/morph-v3-large":{"provider":"openrouter","id":"morph/morph-v3-large","name":"Morph V3 Large","family":"morph","context_window":262144,"max_output":131072,"cost":{"input":0.9,"output":1.9},"release_date":"2025-07-07"},"openrouter/nex-agi/nex-n2.5-mini:free":{"provider":"openrouter","id":"nex-agi/nex-n2.5-mini:free","name":"Nex-N2.5-Mini (free)","family":"agi","context_window":262144,"max_output":235929,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-09-08"},"openrouter/nex-agi/nex-n2.5-pro:free":{"provider":"openrouter","id":"nex-agi/nex-n2.5-pro:free","name":"Nex-N2.5-Pro (free)","family":"agi","context_window":262144,"max_output":235929,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-09-08"},"openrouter/nousresearch/hermes-3-llama-3.1-405b":{"provider":"openrouter","id":"nousresearch/hermes-3-llama-3.1-405b","name":"Hermes 3 405B Instruct","family":"nousresearch","context_window":131072,"max_output":16384,"cost":{"input":1,"output":1},"open_weights":true,"knowledge_cutoff":"2023-12-31","release_date":"2024-08-16"},"openrouter/nousresearch/hermes-3-llama-3.1-70b":{"provider":"openrouter","id":"nousresearch/hermes-3-llama-3.1-70b","name":"Hermes 3 70B Instruct","family":"nousresearch","context_window":131072,"max_output":16384,"cost":{"input":0.7,"output":0.7},"open_weights":true,"knowledge_cutoff":"2023-12-31","release_date":"2024-08-18"},"openrouter/nousresearch/hermes-4-405b":{"provider":"openrouter","id":"nousresearch/hermes-4-405b","name":"Hermes 4 405B","family":"hermes","context_window":131072,"max_output":117964,"cost":{"input":1,"output":3},"reasoning":true,"open_weights":true,"knowledge_cutoff":"2024-08-31","release_date":"2025-08-26"},"openrouter/nvidia/nemotron-3-nano-30b-a3b":{"provider":"openrouter","id":"nvidia/nemotron-3-nano-30b-a3b","name":"Nemotron 3 Nano 30B A3B","family":"nemotron","context_window":262144,"max_output":235929,"cost":{"input":0.05,"output":0.2,"cache_read":0.03},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-12-15"},"openrouter/nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free":{"provider":"openrouter","id":"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free","name":"Nemotron 3 Nano Omni (free)","family":"nemotron","context_window":256000,"max_output":65536,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-28"},"openrouter/nvidia/nemotron-3-super-120b-a12b":{"provider":"openrouter","id":"nvidia/nemotron-3-super-120b-a12b","name":"Nemotron 3 Super 120B A12B","family":"nemotron","context_window":262144,"max_output":235929,"cost":{"input":0.08,"output":0.45},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-03-11"},"openrouter/nvidia/nemotron-3-super-120b-a12b:free":{"provider":"openrouter","id":"nvidia/nemotron-3-super-120b-a12b:free","name":"Nemotron 3 Super (free)","family":"nemotron","context_window":262144,"max_output":235929,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-03-11"},"openrouter/nvidia/nemotron-3-ultra-550b-a55b":{"provider":"openrouter","id":"nvidia/nemotron-3-ultra-550b-a55b","name":"Nemotron 3 Ultra 550B A55B","family":"nemotron","context_window":262144,"max_output":182520,"cost":{"input":0.6,"output":2.4,"cache_read":0.12},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-04"},"openrouter/nvidia/nemotron-3-ultra-550b-a55b:free":{"provider":"openrouter","id":"nvidia/nemotron-3-ultra-550b-a55b:free","name":"Nemotron 3 Ultra (free)","family":"nemotron","context_window":1000000,"max_output":65536,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-04"},"openrouter/nvidia/nemotron-3.5-content-safety":{"provider":"openrouter","id":"nvidia/nemotron-3.5-content-safety","name":"Nemotron 3.5 Content Safety","family":"nemotron","context_window":131072,"max_output":117964,"cost":{"input":0.2,"output":0.2},"reasoning":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-04"},"openrouter/nvidia/nemotron-3.5-content-safety:free":{"provider":"openrouter","id":"nvidia/nemotron-3.5-content-safety:free","name":"Nemotron 3.5 Content Safety (free)","family":"nemotron","context_window":128000,"max_output":8192,"reasoning":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-04"},"openrouter/nvidia/nemotron-3.5-lightning":{"provider":"openrouter","id":"nvidia/nemotron-3.5-lightning","name":"Nemotron 3.5 Lightning 30B A3B","family":"nemotron","context_window":262144,"max_output":131072,"cost":{"input":0.08,"output":0.2,"cache_read":0.04},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-11"},"openrouter/nvidia/nemotron-3.5-lightning:free":{"provider":"openrouter","id":"nvidia/nemotron-3.5-lightning:free","name":"Nemotron 3.5 Lightning (free)","family":"nemotron","context_window":1000000,"max_output":65536,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-11"},"openrouter/openai/gpt-3.5-turbo":{"provider":"openrouter","id":"openai/gpt-3.5-turbo","name":"GPT-3.5-turbo","family":"gpt","context_window":16385,"max_output":4096,"cost":{"input":0.5,"output":1.5},"tool_call":true,"knowledge_cutoff":"2021-09-01","release_date":"2023-03-01"},"openrouter/openai/gpt-3.5-turbo-0613":{"provider":"openrouter","id":"openai/gpt-3.5-turbo-0613","name":"GPT-3.5 Turbo (older v0613)","family":"gpt","context_window":4095,"max_output":3685,"cost":{"input":1,"output":2},"tool_call":true,"knowledge_cutoff":"2021-09-30","release_date":"2024-01-25"},"openrouter/openai/gpt-3.5-turbo-16k":{"provider":"openrouter","id":"openai/gpt-3.5-turbo-16k","name":"GPT-3.5 Turbo 16k","family":"gpt","context_window":16385,"max_output":4096,"cost":{"input":3,"output":4},"tool_call":true,"knowledge_cutoff":"2021-09-30","release_date":"2023-08-28"},"openrouter/openai/gpt-3.5-turbo-instruct":{"provider":"openrouter","id":"openai/gpt-3.5-turbo-instruct","name":"GPT-3.5 Turbo Instruct","family":"gpt","context_window":4095,"max_output":3685,"cost":{"input":1.5,"output":2},"knowledge_cutoff":"2021-09-30","release_date":"2023-09-28"},"openrouter/openai/gpt-4":{"provider":"openrouter","id":"openai/gpt-4","name":"GPT-4","family":"gpt","context_window":8191,"max_output":4096,"cost":{"input":30,"output":60},"tool_call":true,"knowledge_cutoff":"2023-11","release_date":"2023-11-06"},"openrouter/openai/gpt-4-turbo":{"provider":"openrouter","id":"openai/gpt-4-turbo","name":"GPT-4 Turbo","family":"gpt","context_window":128000,"max_output":4096,"cost":{"input":10,"output":30},"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2023-12","release_date":"2023-11-06"},"openrouter/openai/gpt-4.1":{"provider":"openrouter","id":"openai/gpt-4.1","name":"GPT-4.1","family":"gpt","context_window":1047576,"max_output":32768,"cost":{"input":2,"output":8,"cache_read":0.5},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-04","release_date":"2025-04-14"},"openrouter/openai/gpt-4.1-mini":{"provider":"openrouter","id":"openai/gpt-4.1-mini","name":"GPT-4.1 mini","family":"gpt-mini","context_window":1047576,"max_output":32768,"cost":{"input":0.4,"output":1.6,"cache_read":0.1},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-04","release_date":"2025-04-14"},"openrouter/openai/gpt-4.1-nano":{"provider":"openrouter","id":"openai/gpt-4.1-nano","name":"GPT-4.1 nano","family":"gpt-nano","context_window":1047576,"max_output":32768,"cost":{"input":0.1,"output":0.4,"cache_read":0.025},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-04","release_date":"2025-04-14"},"openrouter/openai/gpt-4o":{"provider":"openrouter","id":"openai/gpt-4o","name":"GPT-4o","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":2.5,"output":10,"cache_read":1.25},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-05-13"},"openrouter/openai/gpt-4o-2024-05-13":{"provider":"openrouter","id":"openai/gpt-4o-2024-05-13","name":"GPT-4o (2024-05-13)","family":"gpt","context_window":128000,"max_output":4096,"cost":{"input":5,"output":15},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-05-13"},"openrouter/openai/gpt-4o-2024-08-06":{"provider":"openrouter","id":"openai/gpt-4o-2024-08-06","name":"GPT-4o (2024-08-06)","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":2.5,"output":10,"cache_read":1.25},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-08-06"},"openrouter/openai/gpt-4o-2024-11-20":{"provider":"openrouter","id":"openai/gpt-4o-2024-11-20","name":"GPT-4o (2024-11-20)","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":2.5,"output":10,"cache_read":1.25},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-11-20"},"openrouter/openai/gpt-4o-mini":{"provider":"openrouter","id":"openai/gpt-4o-mini","name":"GPT-4o mini","family":"gpt-mini","context_window":128000,"max_output":16384,"cost":{"input":0.15,"output":0.6,"cache_read":0.075},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-07-18"},"openrouter/openai/gpt-4o-mini-2024-07-18":{"provider":"openrouter","id":"openai/gpt-4o-mini-2024-07-18","name":"GPT-4o-mini (2024-07-18)","family":"o-mini","context_window":128000,"max_output":16384,"cost":{"input":0.15,"output":0.6,"cache_read":0.075},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-10-31","release_date":"2024-07-18"},"openrouter/openai/gpt-5":{"provider":"openrouter","id":"openai/gpt-5","name":"GPT-5","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.25,"output":10,"cache_read":0.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-08-07"},"openrouter/openai/gpt-5-image":{"provider":"openrouter","id":"openai/gpt-5-image","name":"GPT-5 Image","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":10,"output":10,"cache_read":1.25},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-10-01","release_date":"2025-10-14"},"openrouter/openai/gpt-5-image-mini":{"provider":"openrouter","id":"openai/gpt-5-image-mini","name":"GPT-5 Image Mini","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":2.5,"output":2,"cache_read":0.25},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2025-10-16"},"openrouter/openai/gpt-5-mini":{"provider":"openrouter","id":"openai/gpt-5-mini","name":"GPT-5 Mini","family":"gpt-mini","context_window":400000,"max_output":128000,"cost":{"input":0.25,"output":2,"cache_read":0.025},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-05-30","release_date":"2025-08-07"},"openrouter/openai/gpt-5-nano":{"provider":"openrouter","id":"openai/gpt-5-nano","name":"GPT-5 Nano","family":"gpt-nano","context_window":400000,"max_output":128000,"cost":{"input":0.05,"output":0.4,"cache_read":0.005},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-05-30","release_date":"2025-08-07"},"openrouter/openai/gpt-5-pro":{"provider":"openrouter","id":"openai/gpt-5-pro","name":"GPT-5 Pro","family":"gpt-pro","context_window":400000,"max_output":128000,"cost":{"input":15,"output":120},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-10-06"},"openrouter/openai/gpt-5.1":{"provider":"openrouter","id":"openai/gpt-5.1","name":"GPT-5.1","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.25,"output":10,"cache_read":0.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"openrouter/openai/gpt-5.1-codex":{"provider":"openrouter","id":"openai/gpt-5.1-codex","name":"GPT-5.1 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.25,"output":10,"cache_read":0.13},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"openrouter/openai/gpt-5.1-codex-max":{"provider":"openrouter","id":"openai/gpt-5.1-codex-max","name":"GPT-5.1 Codex Max","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.25,"output":10,"cache_read":0.125},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"openrouter/openai/gpt-5.1-codex-mini":{"provider":"openrouter","id":"openai/gpt-5.1-codex-mini","name":"GPT-5.1 Codex mini","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":0.25,"output":2,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2024-09-30","release_date":"2025-11-13"},"openrouter/openai/gpt-5.2":{"provider":"openrouter","id":"openai/gpt-5.2","name":"GPT-5.2","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-11"},"openrouter/openai/gpt-5.2-chat":{"provider":"openrouter","id":"openai/gpt-5.2-chat","name":"GPT-5.2 Chat","family":"gpt-codex","context_window":128000,"max_output":32000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-10"},"openrouter/openai/gpt-5.2-codex":{"provider":"openrouter","id":"openai/gpt-5.2-codex","name":"GPT-5.2 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-11"},"openrouter/openai/gpt-5.2-pro":{"provider":"openrouter","id":"openai/gpt-5.2-pro","name":"GPT-5.2 Pro","family":"gpt-pro","context_window":400000,"max_output":128000,"cost":{"input":21,"output":168},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2025-12-11"},"openrouter/openai/gpt-5.3-codex":{"provider":"openrouter","id":"openai/gpt-5.3-codex","name":"GPT-5.3 Codex","family":"gpt-codex","context_window":400000,"max_output":128000,"cost":{"input":1.75,"output":14,"cache_read":0.175},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-02-05"},"openrouter/openai/gpt-5.4":{"provider":"openrouter","id":"openai/gpt-5.4","name":"GPT-5.4","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":2.5,"output":15,"cache_read":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-05"},"openrouter/openai/gpt-5.4-image-2":{"provider":"openrouter","id":"openai/gpt-5.4-image-2","name":"GPT-5.4 Image 2","family":"gpt","context_window":272000,"max_output":128000,"cost":{"input":8,"output":15,"cache_read":2},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-21"},"openrouter/openai/gpt-5.4-mini":{"provider":"openrouter","id":"openai/gpt-5.4-mini","name":"GPT-5.4 mini","family":"gpt-mini","context_window":400000,"max_output":128000,"cost":{"input":0.75,"output":4.5,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"openrouter/openai/gpt-5.4-nano":{"provider":"openrouter","id":"openai/gpt-5.4-nano","name":"GPT-5.4 nano","family":"gpt-nano","context_window":400000,"max_output":128000,"cost":{"input":0.2,"output":1.25,"cache_read":0.02},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-17"},"openrouter/openai/gpt-5.4-pro":{"provider":"openrouter","id":"openai/gpt-5.4-pro","name":"GPT-5.4 Pro","family":"gpt-pro","context_window":1050000,"max_output":128000,"cost":{"input":30,"output":180},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-03-05"},"openrouter/openai/gpt-5.5":{"provider":"openrouter","id":"openai/gpt-5.5","name":"GPT-5.5","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":5,"output":30,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-12-01","release_date":"2026-04-23"},"openrouter/openai/gpt-5.5-pro":{"provider":"openrouter","id":"openai/gpt-5.5-pro","name":"GPT-5.5 Pro","family":"gpt-pro","context_window":1050000,"max_output":128000,"cost":{"input":30,"output":180},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-12-01","release_date":"2026-04-23"},"openrouter/openai/gpt-5.6-luna":{"provider":"openrouter","id":"openai/gpt-5.6-luna","name":"GPT-5.6 Luna","family":"gpt-luna","context_window":1050000,"max_output":128000,"cost":{"input":0.2,"output":1.2,"cache_read":0.02,"cache_write":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openrouter/openai/gpt-5.6-luna-pro":{"provider":"openrouter","id":"openai/gpt-5.6-luna-pro","name":"GPT-5.6 Luna Pro","family":"gpt-luna","context_window":1050000,"max_output":128000,"cost":{"input":0.2,"output":1.2,"cache_read":0.02,"cache_write":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openrouter/openai/gpt-5.6-sol":{"provider":"openrouter","id":"openai/gpt-5.6-sol","name":"GPT-5.6 Sol","family":"gpt-sol","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openrouter/openai/gpt-5.6-sol-pro":{"provider":"openrouter","id":"openai/gpt-5.6-sol-pro","name":"GPT-5.6 Sol Pro","family":"gpt-sol","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openrouter/openai/gpt-5.6-terra":{"provider":"openrouter","id":"openai/gpt-5.6-terra","name":"GPT-5.6 Terra","family":"gpt-terra","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openrouter/openai/gpt-5.6-terra-pro":{"provider":"openrouter","id":"openai/gpt-5.6-terra-pro","name":"GPT-5.6 Terra Pro","family":"gpt-terra","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-07-09"},"openrouter/openai/gpt-6-astra":{"provider":"openrouter","id":"openai/gpt-6-astra","name":"GPT-6 Astra","family":"gpt-astra","context_window":1050000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-04-30","release_date":"2026-09-04"},"openrouter/openai/gpt-6-astra-pro":{"provider":"openrouter","id":"openai/gpt-6-astra-pro","name":"GPT-6 Astra Pro","family":"gpt","context_window":1050000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-04"},"openrouter/openai/gpt-audio":{"provider":"openrouter","id":"openai/gpt-audio","name":"GPT Audio","family":"gpt","context_window":128000,"max_output":16384,"cost":{"input":2.5,"output":10},"tool_call":true,"attachment":true,"release_date":"2026-01-19"},"openrouter/openai/gpt-audio-mini":{"provider":"openrouter","id":"openai/gpt-audio-mini","name":"GPT Audio Mini","family":"o-mini","context_window":128000,"max_output":16384,"cost":{"input":0.6,"output":2.4},"tool_call":true,"attachment":true,"release_date":"2026-01-19"},"openrouter/openai/gpt-chat-latest":{"provider":"openrouter","id":"openai/gpt-chat-latest","name":"GPT Chat Latest","family":"gpt","context_window":400000,"max_output":128000,"cost":{"input":5,"output":30,"cache_read":0.5},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-05-05"},"openrouter/openai/gpt-oss-120b":{"provider":"openrouter","id":"openai/gpt-oss-120b","name":"GPT OSS 120B","family":"gpt-oss","context_window":131072,"max_output":117964,"cost":{"input":0.037,"output":0.17},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-08-05"},"openrouter/openai/gpt-oss-20b":{"provider":"openrouter","id":"openai/gpt-oss-20b","name":"GPT OSS 20B","family":"gpt-oss","context_window":131072,"max_output":117964,"cost":{"input":0.03,"output":0.13,"cache_read":0.03},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-08-05"},"openrouter/openai/gpt-oss-safeguard-20b":{"provider":"openrouter","id":"openai/gpt-oss-safeguard-20b","name":"GPT OSS Safeguard 20B","family":"gpt-oss","context_window":131072,"max_output":65536,"cost":{"input":0.075,"output":0.3,"cache_read":0.0375},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-10-29"},"openrouter/openai/o1":{"provider":"openrouter","id":"openai/o1","name":"o1","family":"o","context_window":200000,"max_output":100000,"cost":{"input":15,"output":60,"cache_read":7.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2024-12-05"},"openrouter/openai/o1-pro":{"provider":"openrouter","id":"openai/o1-pro","name":"o1-pro","family":"o-pro","context_window":200000,"max_output":100000,"cost":{"input":150,"output":600},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2023-09","release_date":"2025-03-19"},"openrouter/openai/o3":{"provider":"openrouter","id":"openai/o3","name":"o3","family":"o","context_window":200000,"max_output":100000,"cost":{"input":2,"output":8,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-05","release_date":"2025-04-16"},"openrouter/openai/o3-mini":{"provider":"openrouter","id":"openai/o3-mini","name":"o3-mini","family":"o-mini","context_window":200000,"max_output":100000,"cost":{"input":1.1,"output":4.4,"cache_read":0.55},"reasoning":true,"tool_call":true,"attachment":true,"pdf":true,"knowledge_cutoff":"2024-05","release_date":"2024-12-20"},"openrouter/openai/o3-mini-high":{"provider":"openrouter","id":"openai/o3-mini-high","name":"o3 Mini High","family":"o","context_window":200000,"max_output":100000,"cost":{"input":1.1,"output":4.4,"cache_read":0.55},"reasoning":true,"tool_call":true,"attachment":true,"pdf":true,"knowledge_cutoff":"2023-10-31","release_date":"2025-02-12"},"openrouter/openai/o3-pro":{"provider":"openrouter","id":"openai/o3-pro","name":"o3-pro","family":"o-pro","context_window":200000,"max_output":100000,"cost":{"input":20,"output":80},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-05","release_date":"2025-06-10"},"openrouter/openai/o4-mini":{"provider":"openrouter","id":"openai/o4-mini","name":"o4-mini","family":"o-mini","context_window":200000,"max_output":100000,"cost":{"input":1.1,"output":4.4,"cache_read":0.275},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-05","release_date":"2025-04-16"},"openrouter/openai/o4-mini-high":{"provider":"openrouter","id":"openai/o4-mini-high","name":"o4 Mini High","family":"o","context_window":200000,"max_output":100000,"cost":{"input":1.1,"output":4.4,"cache_read":0.275},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2024-06-30","release_date":"2025-04-16"},"openrouter/pareto-code":{"provider":"openrouter","id":"pareto-code","name":"Pareto Code Router","context_window":2000000,"max_output":200000,"release_date":"2026-04-21"},"openrouter/perceptron/perceptron-mk1":{"provider":"openrouter","id":"perceptron/perceptron-mk1","name":"Perceptron Mk1","context_window":32768,"max_output":8192,"cost":{"input":0.15,"output":1.5},"reasoning":true,"attachment":true,"vision":true,"release_date":"2026-05-12"},"openrouter/perplexity/sonar":{"provider":"openrouter","id":"perplexity/sonar","name":"Sonar","family":"sonar","context_window":127072,"max_output":114364,"cost":{"input":1,"output":1},"attachment":true,"vision":true,"release_date":"2025-01-27"},"openrouter/perplexity/sonar-deep-research":{"provider":"openrouter","id":"perplexity/sonar-deep-research","name":"Sonar Deep Research","family":"sonar-deep-research","context_window":128000,"max_output":115200,"cost":{"input":2,"output":8},"reasoning":true,"release_date":"2025-03-07"},"openrouter/perplexity/sonar-pro":{"provider":"openrouter","id":"perplexity/sonar-pro","name":"Sonar Pro","family":"sonar-pro","context_window":200000,"max_output":8000,"cost":{"input":3,"output":15},"attachment":true,"vision":true,"release_date":"2025-03-07"},"openrouter/perplexity/sonar-pro-search":{"provider":"openrouter","id":"perplexity/sonar-pro-search","name":"Sonar Pro Search","family":"sonar-pro","context_window":200000,"max_output":8000,"cost":{"input":3,"output":15},"reasoning":true,"attachment":true,"vision":true,"release_date":"2025-10-30"},"openrouter/perplexity/sonar-reasoning-pro":{"provider":"openrouter","id":"perplexity/sonar-reasoning-pro","name":"Sonar Reasoning Pro","family":"sonar-reasoning","context_window":128000,"max_output":115200,"cost":{"input":2,"output":8},"reasoning":true,"attachment":true,"vision":true,"release_date":"2025-03-07"},"openrouter/poolside/laguna-s-2.1":{"provider":"openrouter","id":"poolside/laguna-s-2.1","name":"Laguna S 2.1","family":"laguna-s","context_window":1048576,"max_output":131072,"cost":{"input":0.09,"output":0.18,"cache_read":0.009},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-21"},"openrouter/poolside/laguna-s-2.1:free":{"provider":"openrouter","id":"poolside/laguna-s-2.1:free","name":"Laguna S 2.1 (free)","family":"laguna-s","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-21"},"openrouter/poolside/laguna-xs-2.1":{"provider":"openrouter","id":"poolside/laguna-xs-2.1","name":"Laguna XS 2.1","family":"laguna","context_window":262144,"max_output":32768,"cost":{"input":0.06,"output":0.12,"cache_read":0.03},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-02"},"openrouter/poolside/laguna-xs-2.1:free":{"provider":"openrouter","id":"poolside/laguna-xs-2.1:free","name":"Laguna XS 2.1 (free)","family":"laguna","context_window":262144,"max_output":32768,"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-02"},"openrouter/qwen/qwen-2.5-72b-instruct":{"provider":"openrouter","id":"qwen/qwen-2.5-72b-instruct","name":"Qwen2.5 72B Instruct","family":"qwen","context_window":32768,"max_output":16384,"cost":{"input":0.36,"output":0.4},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2024-09-19"},"openrouter/qwen/qwen-2.5-7b-instruct":{"provider":"openrouter","id":"qwen/qwen-2.5-7b-instruct","name":"Qwen2.5 7B Instruct","family":"qwen","context_window":32768,"max_output":29491,"cost":{"input":0.1,"output":0.2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2024-10-16"},"openrouter/qwen/qwen-2.5-coder-32b-instruct":{"provider":"openrouter","id":"qwen/qwen-2.5-coder-32b-instruct","name":"Qwen2.5 Coder 32B Instruct","family":"qwen","context_window":32768,"max_output":29491,"cost":{"input":0.66,"output":1},"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2024-11-11"},"openrouter/qwen/qwen-plus":{"provider":"openrouter","id":"qwen/qwen-plus","name":"Qwen Plus","family":"qwen","context_window":1000000,"max_output":32768,"cost":{"input":0.26,"output":0.78,"cache_read":0.052,"cache_write":0.325},"tool_call":true,"knowledge_cutoff":"2024-04","release_date":"2024-01-25"},"openrouter/qwen/qwen-plus-2025-07-28":{"provider":"openrouter","id":"qwen/qwen-plus-2025-07-28","name":"Qwen Plus 0728","family":"qwen","context_window":1000000,"max_output":32768,"cost":{"input":0.26,"output":0.78},"tool_call":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-09-08"},"openrouter/qwen/qwen2.5-vl-72b-instruct":{"provider":"openrouter","id":"qwen/qwen2.5-vl-72b-instruct","name":"Qwen2.5 VL 72B Instruct","family":"qwen","context_window":128000,"max_output":115200,"cost":{"input":0.8,"output":1,"cache_read":0.4},"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2025-02-01"},"openrouter/qwen/qwen3-14b":{"provider":"openrouter","id":"qwen/qwen3-14b","name":"Qwen3 14B","family":"qwen","context_window":131072,"max_output":16384,"cost":{"input":0.12,"output":0.24},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-04-28"},"openrouter/qwen/qwen3-235b-a22b":{"provider":"openrouter","id":"qwen/qwen3-235b-a22b","name":"Qwen3 235B-A22B","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.455,"output":1.82},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"openrouter/qwen/qwen3-235b-a22b-2507":{"provider":"openrouter","id":"qwen/qwen3-235b-a22b-2507","name":"Qwen3 235B A22B Instruct 2507","family":"qwen","context_window":262144,"max_output":235929,"cost":{"input":0.0875,"output":0.35,"cache_read":0.0175},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06-30","release_date":"2025-07-21"},"openrouter/qwen/qwen3-235b-a22b-thinking-2507":{"provider":"openrouter","id":"qwen/qwen3-235b-a22b-thinking-2507","name":"Qwen3 235B A22B Thinking 2507","family":"qwen","context_window":131072,"max_output":117964,"cost":{"input":0.23,"output":2.3},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06-30","release_date":"2025-07-25"},"openrouter/qwen/qwen3-30b-a3b":{"provider":"openrouter","id":"qwen/qwen3-30b-a3b","name":"Qwen3 30B A3B","family":"qwen","context_window":131072,"max_output":16384,"cost":{"input":0.12,"output":0.5},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-04-28"},"openrouter/qwen/qwen3-30b-a3b-instruct-2507":{"provider":"openrouter","id":"qwen/qwen3-30b-a3b-instruct-2507","name":"Qwen3 30B A3B Instruct 2507","family":"qwen","context_window":262144,"max_output":32000,"cost":{"input":0.04815,"output":0.19305},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06-30","release_date":"2025-07-29"},"openrouter/qwen/qwen3-30b-a3b-thinking-2507":{"provider":"openrouter","id":"qwen/qwen3-30b-a3b-thinking-2507","name":"Qwen3 30B A3B Thinking 2507","family":"qwen","context_window":81920,"max_output":32768,"cost":{"input":0.2,"output":2.4},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06-30","release_date":"2025-08-28"},"openrouter/qwen/qwen3-32b":{"provider":"openrouter","id":"qwen/qwen3-32b","name":"Qwen3 32B","family":"qwen","context_window":131072,"max_output":16384,"cost":{"input":0.08,"output":0.28},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"openrouter/qwen/qwen3-8b":{"provider":"openrouter","id":"qwen/qwen3-8b","name":"Qwen3 8B","family":"qwen","context_window":131072,"max_output":8192,"cost":{"input":0.117,"output":0.455},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-04-28"},"openrouter/qwen/qwen3-coder":{"provider":"openrouter","id":"qwen/qwen3-coder","name":"Qwen3 Coder 480B A35B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.3,"output":1,"cache_read":0.1},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-06-30","release_date":"2025-07-23"},"openrouter/qwen/qwen3-coder-30b-a3b-instruct":{"provider":"openrouter","id":"qwen/qwen3-coder-30b-a3b-instruct","name":"Qwen3-Coder 30B-A3B Instruct","family":"qwen","context_window":262144,"max_output":235929,"cost":{"input":0.07,"output":0.28},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-04"},"openrouter/qwen/qwen3-coder-flash":{"provider":"openrouter","id":"qwen/qwen3-coder-flash","name":"Qwen3 Coder Flash","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.195,"output":0.975,"cache_read":0.039,"cache_write":0.24375},"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-28"},"openrouter/qwen/qwen3-coder-next":{"provider":"openrouter","id":"qwen/qwen3-coder-next","name":"Qwen3 Coder Next","family":"qwen","context_window":262144,"max_output":235929,"cost":{"input":0.12,"output":0.8,"cache_read":0.07},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-09","release_date":"2026-02-03"},"openrouter/qwen/qwen3-coder-plus":{"provider":"openrouter","id":"qwen/qwen3-coder-plus","name":"Qwen3 Coder Plus","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.65,"output":3.25,"cache_read":0.13,"cache_write":0.8125},"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-23"},"openrouter/qwen/qwen3-max":{"provider":"openrouter","id":"qwen/qwen3-max","name":"Qwen3 Max","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.78,"output":3.9,"cache_read":0.156,"cache_write":0.975},"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2025-09-23"},"openrouter/qwen/qwen3-max-thinking":{"provider":"openrouter","id":"qwen/qwen3-max-thinking","name":"Qwen3 Max Thinking","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.78,"output":3.9},"reasoning":true,"tool_call":true,"release_date":"2026-02-09"},"openrouter/qwen/qwen3-next-80b-a3b-instruct":{"provider":"openrouter","id":"qwen/qwen3-next-80b-a3b-instruct","name":"Qwen3-Next 80B-A3B Instruct","family":"qwen","context_window":262144,"max_output":16384,"cost":{"input":0.09,"output":1.1},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-09"},"openrouter/qwen/qwen3-next-80b-a3b-thinking":{"provider":"openrouter","id":"qwen/qwen3-next-80b-a3b-thinking","name":"Qwen3-Next 80B-A3B (Thinking)","family":"qwen","context_window":262144,"max_output":32768,"cost":{"input":0.15,"output":1.2},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-09"},"openrouter/qwen/qwen3-vl-235b-a22b-instruct":{"provider":"openrouter","id":"qwen/qwen3-vl-235b-a22b-instruct","name":"Qwen3 VL 235B A22B Instruct","family":"qwen","context_window":262144,"max_output":32768,"cost":{"input":0.21,"output":1.9,"cache_read":0.1},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-09-23"},"openrouter/qwen/qwen3-vl-235b-a22b-thinking":{"provider":"openrouter","id":"qwen/qwen3-vl-235b-a22b-thinking","name":"Qwen3 VL 235B A22B Thinking","family":"qwen","context_window":131072,"max_output":32768,"cost":{"input":0.4,"output":4},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-09-23"},"openrouter/qwen/qwen3-vl-30b-a3b-instruct":{"provider":"openrouter","id":"qwen/qwen3-vl-30b-a3b-instruct","name":"Qwen3 VL 30B A3B Instruct","family":"qwen","context_window":262144,"max_output":16384,"cost":{"input":0.15,"output":0.6},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-10-06"},"openrouter/qwen/qwen3-vl-30b-a3b-thinking":{"provider":"openrouter","id":"qwen/qwen3-vl-30b-a3b-thinking","name":"Qwen3 VL 30B A3B Thinking","family":"qwen","context_window":262144,"max_output":32768,"cost":{"input":0.2,"output":2.4},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-10-06"},"openrouter/qwen/qwen3-vl-32b-instruct":{"provider":"openrouter","id":"qwen/qwen3-vl-32b-instruct","name":"Qwen3 VL 32B Instruct","family":"qwen","context_window":131072,"max_output":32768,"cost":{"input":0.104,"output":0.416},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-10-23"},"openrouter/qwen/qwen3-vl-8b-instruct":{"provider":"openrouter","id":"qwen/qwen3-vl-8b-instruct","name":"Qwen3 VL 8B Instruct","family":"qwen","context_window":262144,"max_output":32768,"cost":{"input":0.117,"output":0.455},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-10-14"},"openrouter/qwen/qwen3-vl-8b-thinking":{"provider":"openrouter","id":"qwen/qwen3-vl-8b-thinking","name":"Qwen3 VL 8B Thinking","family":"qwen","context_window":131072,"max_output":32768,"cost":{"input":0.18,"output":2.1},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2025-10-14"},"openrouter/qwen/qwen3.5-122b-a10b":{"provider":"openrouter","id":"qwen/qwen3.5-122b-a10b","name":"Qwen3.5 122B-A10B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.26,"output":2.08},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"openrouter/qwen/qwen3.5-27b":{"provider":"openrouter","id":"qwen/qwen3.5-27b","name":"Qwen3.5 27B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.195,"output":1.56},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"openrouter/qwen/qwen3.5-35b-a3b":{"provider":"openrouter","id":"qwen/qwen3.5-35b-a3b","name":"Qwen3.5 35B-A3B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.1625,"output":1.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"openrouter/qwen/qwen3.5-397b-a17b":{"provider":"openrouter","id":"qwen/qwen3.5-397b-a17b","name":"Qwen3.5 397B-A17B","family":"qwen","context_window":262144,"max_output":235929,"cost":{"input":0.55,"output":3.5,"cache_read":0.225},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-15"},"openrouter/qwen/qwen3.5-9b":{"provider":"openrouter","id":"qwen/qwen3.5-9b","name":"Qwen3.5 9B","family":"qwen","context_window":262144,"max_output":235929,"cost":{"input":0.1,"output":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-02-23"},"openrouter/qwen/qwen3.5-flash-02-23":{"provider":"openrouter","id":"qwen/qwen3.5-flash-02-23","name":"Qwen3.5-Flash","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.065,"output":0.26},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-02-25"},"openrouter/qwen/qwen3.5-plus-02-15":{"provider":"openrouter","id":"qwen/qwen3.5-plus-02-15","name":"Qwen3.5 Plus 2026-02-15","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.26,"output":1.56},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-02-16"},"openrouter/qwen/qwen3.5-plus-20260420":{"provider":"openrouter","id":"qwen/qwen3.5-plus-20260420","name":"Qwen3.5 Plus 2026-04-20","family":"qwen3.5","context_window":1000000,"max_output":65536,"cost":{"input":0.3,"output":1.8,"cache_write":0.375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-04-27"},"openrouter/qwen/qwen3.6-27b":{"provider":"openrouter","id":"qwen/qwen3.6-27b","name":"Qwen3.6 27B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.3,"output":2,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-22"},"openrouter/qwen/qwen3.6-35b-a3b":{"provider":"openrouter","id":"qwen/qwen3.6-35b-a3b","name":"Qwen3.6 35B-A3B","family":"qwen","context_window":262144,"max_output":235929,"cost":{"input":0.1,"output":0.9,"cache_read":0.05},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-04-17"},"openrouter/qwen/qwen3.6-flash":{"provider":"openrouter","id":"qwen/qwen3.6-flash","name":"Qwen3.6 Flash","family":"qwen3.6","context_window":1000000,"max_output":65536,"cost":{"input":0.1875,"output":1.125,"cache_write":0.234375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-04-27"},"openrouter/qwen/qwen3.6-max-preview":{"provider":"openrouter","id":"qwen/qwen3.6-max-preview","name":"Qwen3.6 Max Preview","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":1.027,"output":6.162,"cache_write":1.28375},"reasoning":true,"tool_call":true,"knowledge_cutoff":"2025-04","release_date":"2026-04-20"},"openrouter/qwen/qwen3.6-plus":{"provider":"openrouter","id":"qwen/qwen3.6-plus","name":"Qwen3.6 Plus","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.325,"output":1.95,"cache_write":0.40625},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-04-02"},"openrouter/qwen/qwen3.7-flash":{"provider":"openrouter","id":"qwen/qwen3.7-flash","name":"Qwen3.7 Flash","family":"qwen","context_window":1000000,"max_output":65536,"cost":{"input":0.03,"output":0.13,"cache_read":0.006,"cache_write":0.038},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-07-15"},"openrouter/qwen/qwen3.7-max":{"provider":"openrouter","id":"qwen/qwen3.7-max","name":"Qwen3.7 Max","family":"qwen","context_window":1000000,"max_output":131072,"cost":{"input":1.475,"output":4.425,"cache_read":0.295,"cache_write":1.84375},"reasoning":true,"tool_call":true,"release_date":"2026-05-21"},"openrouter/qwen/qwen3.7-plus":{"provider":"openrouter","id":"qwen/qwen3.7-plus","name":"Qwen3.7 Plus","family":"qwen","context_window":1000000,"max_output":131072,"cost":{"input":0.32,"output":1.28,"cache_read":0.064,"cache_write":0.4},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-04","release_date":"2026-06-02"},"openrouter/qwen/qwen3.8-2.4t-a95b":{"provider":"openrouter","id":"qwen/qwen3.8-2.4t-a95b","name":"Qwen3.8 2.4T A95B","family":"qwen","context_window":1048576,"max_output":131072,"cost":{"input":2,"output":6,"cache_read":0.25},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-12"},"openrouter/qwen/qwen3.8-27b":{"provider":"openrouter","id":"qwen/qwen3.8-27b","name":"Qwen3.8 27B","family":"qwen","context_window":1000000,"max_output":131072,"cost":{"input":0.214,"output":2.55,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-08-14"},"openrouter/qwen/qwen3.8-flash":{"provider":"openrouter","id":"qwen/qwen3.8-flash","name":"Qwen3.8 Flash","family":"qwen","context_window":1000000,"max_output":131072,"cost":{"input":0.15,"output":0.47,"cache_read":0.016,"cache_write":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-26"},"openrouter/qwen/qwen3.8-max-0902":{"provider":"openrouter","id":"qwen/qwen3.8-max-0902","name":"Qwen3.8 Max 0902","family":"qwen","context_window":1000000,"max_output":131072,"cost":{"input":2,"output":6,"cache_read":0.25,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-09-02"},"openrouter/rekaai/reka-edge":{"provider":"openrouter","id":"rekaai/reka-edge","name":"Reka Edge","family":"reka","context_window":16384,"max_output":14745,"cost":{"input":0.1,"output":0.1},"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-03-20"},"openrouter/rekaai/reka-flash-3":{"provider":"openrouter","id":"rekaai/reka-flash-3","name":"Reka Flash 3","family":"reka","context_window":65536,"max_output":58982,"cost":{"input":0.1,"output":0.2},"reasoning":true,"open_weights":true,"knowledge_cutoff":"2025-01-31","release_date":"2025-03-12"},"openrouter/relace/relace-apply-3":{"provider":"openrouter","id":"relace/relace-apply-3","name":"Relace Apply 3","context_window":256000,"max_output":128000,"cost":{"input":0.85,"output":1.25},"release_date":"2025-09-26"},"openrouter/relace/relace-search":{"provider":"openrouter","id":"relace/relace-search","name":"Relace Search","context_window":256000,"max_output":128000,"cost":{"input":1,"output":3},"tool_call":true,"release_date":"2025-12-08"},"openrouter/sakana/fugu-max":{"provider":"openrouter","id":"sakana/fugu-max","name":"Fugu Max","family":"fugu","context_window":1000000,"max_output":128000,"cost":{"input":2,"output":6,"cache_read":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-11"},"openrouter/sakana/fugu-ultra":{"provider":"openrouter","id":"sakana/fugu-ultra","name":"Fugu Ultra","family":"fugu","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":30,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-06-15"},"openrouter/sakana/fugu-ultra-v2":{"provider":"openrouter","id":"sakana/fugu-ultra-v2","name":"Fugu Ultra v2","family":"fugu","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":30,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-08-28","release_date":"2026-09-11"},"openrouter/sakana/sakana-namazu":{"provider":"openrouter","id":"sakana/sakana-namazu","name":"Sakana Namazu","family":"sakana-namazu","context_window":262144,"max_output":65536,"cost":{"input":0.95,"output":4,"cache_read":0.15},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-03"},"openrouter/sao10k/l3-lunaris-8b":{"provider":"openrouter","id":"sao10k/l3-lunaris-8b","name":"Llama 3 8B Lunaris","family":"llama","context_window":8192,"max_output":7372,"cost":{"input":0.04,"output":0.05},"open_weights":true,"knowledge_cutoff":"2023-12-31","release_date":"2024-08-13"},"openrouter/sao10k/l3.1-euryale-70b":{"provider":"openrouter","id":"sao10k/l3.1-euryale-70b","name":"Llama 3.1 Euryale 70B v2.2","family":"llama","context_window":131072,"max_output":16384,"cost":{"input":0.85,"output":0.85},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12-31","release_date":"2024-08-28"},"openrouter/sao10k/l3.3-euryale-70b":{"provider":"openrouter","id":"sao10k/l3.3-euryale-70b","name":"Llama 3.3 Euryale 70B","family":"llama","context_window":131072,"max_output":16384,"cost":{"input":0.65,"output":0.75},"open_weights":true,"knowledge_cutoff":"2023-12-31","release_date":"2024-12-18"},"openrouter/stepfun/step-3.5-flash":{"provider":"openrouter","id":"stepfun/step-3.5-flash","name":"Step 3.5 Flash","context_window":262144,"max_output":65536,"cost":{"input":0.1,"output":0.3},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-01-29"},"openrouter/stepfun/step-3.7-flash":{"provider":"openrouter","id":"stepfun/step-3.7-flash","name":"Step 3.7 Flash","context_window":262144,"max_output":230400,"cost":{"input":0.2,"output":1.15,"cache_read":0.04},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2026-03-01","release_date":"2026-05-29"},"openrouter/tencent/hunyuan-a13b-instruct":{"provider":"openrouter","id":"tencent/hunyuan-a13b-instruct","name":"Hunyuan A13B Instruct","family":"hunyuan","context_window":131072,"max_output":117964,"cost":{"input":0.14,"output":0.57},"reasoning":true,"open_weights":true,"knowledge_cutoff":"2025-03-31","release_date":"2025-07-08"},"openrouter/tencent/hy-mt2-1.8b":{"provider":"openrouter","id":"tencent/hy-mt2-1.8b","name":"Hy-MT2-1.8B","family":"Hy","context_window":8192,"max_output":4096,"cost":{"input":0.044,"output":0.177},"open_weights":true,"release_date":"2026-08-20"},"openrouter/tencent/hy-mt2-30b-a3b":{"provider":"openrouter","id":"tencent/hy-mt2-30b-a3b","name":"Hy-MT2-30B-A3B","family":"Hy","context_window":8192,"max_output":4096,"cost":{"input":0.074,"output":0.295},"open_weights":true,"release_date":"2026-08-20"},"openrouter/tencent/hy-mt2-7b":{"provider":"openrouter","id":"tencent/hy-mt2-7b","name":"Hy-MT2-7B","family":"Hy","context_window":8192,"max_output":4096,"cost":{"input":0.074,"output":0.295},"open_weights":true,"release_date":"2026-08-19"},"openrouter/tencent/hy3":{"provider":"openrouter","id":"tencent/hy3","name":"Hy3","family":"Hy","context_window":262144,"max_output":128000,"cost":{"input":0.132,"output":0.528,"cache_read":0.033},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-07-06"},"openrouter/tencent/hy3-preview":{"provider":"openrouter","id":"tencent/hy3-preview","name":"Hy3 preview","family":"Hy","context_window":262144,"max_output":235929,"cost":{"input":0.18,"output":0.6,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-04-20"},"openrouter/tencent/hy4-preview":{"provider":"openrouter","id":"tencent/hy4-preview","name":"Hy4 preview","family":"Hy","context_window":1048576,"max_output":64000,"cost":{"input":0.834,"output":2.501,"cache_read":0.042},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-28"},"openrouter/thedrummer/cydonia-24b-v4.1":{"provider":"openrouter","id":"thedrummer/cydonia-24b-v4.1","name":"Cydonia 24B V4.1","context_window":131072,"max_output":117964,"cost":{"input":0.3,"output":0.5,"cache_read":0.15},"open_weights":true,"knowledge_cutoff":"2024-04-30","release_date":"2025-09-27"},"openrouter/thedrummer/skyfall-36b-v2":{"provider":"openrouter","id":"thedrummer/skyfall-36b-v2","name":"Skyfall 36B V2","context_window":32768,"max_output":29491,"cost":{"input":0.55,"output":0.8,"cache_read":0.25},"open_weights":true,"knowledge_cutoff":"2024-06-30","release_date":"2025-03-10"},"openrouter/thedrummer/unslopnemo-12b":{"provider":"openrouter","id":"thedrummer/unslopnemo-12b","name":"UnslopNemo 12B","context_window":1024000,"max_output":819200,"cost":{"input":0.4,"output":0.4},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-04-30","release_date":"2024-11-08"},"openrouter/thinkingmachines/inkling":{"provider":"openrouter","id":"thinkingmachines/inkling","name":"Inkling","family":"ling","context_window":1048576,"max_output":471859,"cost":{"input":1,"output":4.05,"cache_read":0.17},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-15"},"openrouter/thinkingmachines/inkling-small":{"provider":"openrouter","id":"thinkingmachines/inkling-small","name":"Inkling Small","family":"ling","context_window":1048576,"max_output":262144,"cost":{"input":0.45,"output":1.2,"cache_read":0.1},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-30"},"openrouter/thinkingmachines/inkling-small:free":{"provider":"openrouter","id":"thinkingmachines/inkling-small:free","name":"Inkling Small (free)","family":"ling","context_window":1048576,"max_output":262144,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-30"},"openrouter/thinkingmachines/inkling:free":{"provider":"openrouter","id":"thinkingmachines/inkling:free","name":"Inkling (free)","family":"ling","context_window":1048576,"max_output":262144,"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-15"},"openrouter/undi95/remm-slerp-l2-13b":{"provider":"openrouter","id":"undi95/remm-slerp-l2-13b","name":"ReMM SLERP 13B","context_window":6144,"max_output":5529,"cost":{"input":0.35,"output":0.65},"open_weights":true,"knowledge_cutoff":"2023-06-30","release_date":"2023-07-22"},"openrouter/upstage/solar-pro-3":{"provider":"openrouter","id":"upstage/solar-pro-3","name":"Solar Pro 3","family":"solar-pro","context_window":131072,"max_output":117964,"cost":{"input":0.15,"output":0.6,"cache_read":0.015},"reasoning":true,"tool_call":true,"release_date":"2026-01-27"},"openrouter/upstage/solar-pro4":{"provider":"openrouter","id":"upstage/solar-pro4","name":"Solar Pro 4","family":"solar","context_window":524288,"max_output":131072,"cost":{"input":0.09,"output":0.36,"cache_read":0.018},"reasoning":true,"tool_call":true,"release_date":"2026-08-10"},"openrouter/writer/palmyra-x5":{"provider":"openrouter","id":"writer/palmyra-x5","name":"Palmyra X5","family":"palmyra","context_window":1040000,"max_output":8192,"cost":{"input":0.6,"output":6},"release_date":"2026-01-21"},"openrouter/x-ai/grok-4.20":{"provider":"openrouter","id":"x-ai/grok-4.20","name":"Grok 4.20","family":"grok","context_window":2000000,"max_output":1800000,"cost":{"input":1.25,"output":2.5,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-09-01","release_date":"2026-03-31"},"openrouter/x-ai/grok-4.20-multi-agent":{"provider":"openrouter","id":"x-ai/grok-4.20-multi-agent","name":"Grok 4.20 Multi-Agent","family":"grok","context_window":2000000,"max_output":1800000,"cost":{"input":1.25,"output":2.5,"cache_read":0.2},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-09-01","release_date":"2026-03-31"},"openrouter/x-ai/grok-4.3":{"provider":"openrouter","id":"x-ai/grok-4.3","name":"Grok 4.3","family":"grok","context_window":1000000,"max_output":900000,"cost":{"input":1.25,"output":2.5,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-17"},"openrouter/x-ai/grok-4.5":{"provider":"openrouter","id":"x-ai/grok-4.5","name":"Grok 4.5","family":"grok","context_window":500000,"max_output":450000,"cost":{"input":2,"output":6,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-07-08"},"openrouter/x-ai/grok-4.6":{"provider":"openrouter","id":"x-ai/grok-4.6","name":"Grok 4.6","family":"grok","context_window":500000,"max_output":450000,"cost":{"input":2,"output":6,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-01","release_date":"2026-08-12"},"openrouter/x-ai/grok-build-0.1":{"provider":"openrouter","id":"x-ai/grok-build-0.1","name":"Grok Build 0.1","family":"grok-build","context_window":256000,"max_output":230400,"cost":{"input":1,"output":2,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-16"},"openrouter/xiaomi/mimo-v2.5":{"provider":"openrouter","id":"xiaomi/mimo-v2.5","name":"MiMo-V2.5","family":"mimo","context_window":1050000,"max_output":131072,"cost":{"input":0.14,"output":0.28,"cache_read":0.0028},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2024-12","release_date":"2026-04-22"},"openrouter/xiaomi/mimo-v2.5-pro":{"provider":"openrouter","id":"xiaomi/mimo-v2.5-pro","name":"MiMo-V2.5-Pro","family":"mimo","context_window":1050000,"max_output":131072,"cost":{"input":0.435,"output":0.87,"cache_read":0.0036},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-12","release_date":"2026-04-22"},"openrouter/z-ai/glm-4.5":{"provider":"openrouter","id":"z-ai/glm-4.5","name":"GLM-4.5","family":"glm","context_window":131072,"max_output":98304,"cost":{"input":0.6,"output":2.2,"cache_read":0.11},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-28"},"openrouter/z-ai/glm-4.5-air":{"provider":"openrouter","id":"z-ai/glm-4.5-air","name":"GLM-4.5-Air","family":"glm-air","context_window":131072,"max_output":98304,"cost":{"input":0.13,"output":0.85,"cache_read":0.025},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-28"},"openrouter/z-ai/glm-4.5v":{"provider":"openrouter","id":"z-ai/glm-4.5v","name":"GLM-4.5V","family":"glm","context_window":65536,"max_output":16384,"cost":{"input":0.6,"output":1.8,"cache_read":0.11},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-08-11"},"openrouter/z-ai/glm-4.6":{"provider":"openrouter","id":"z-ai/glm-4.6","name":"GLM-4.6","family":"glm","context_window":204800,"max_output":16384,"cost":{"input":0.43,"output":1.75,"cache_read":0.08},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-09-30"},"openrouter/z-ai/glm-4.6v":{"provider":"openrouter","id":"z-ai/glm-4.6v","name":"GLM-4.6V","family":"glm","context_window":131072,"max_output":32768,"cost":{"input":0.3,"output":0.9,"cache_read":0.055},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-12-08"},"openrouter/z-ai/glm-4.7":{"provider":"openrouter","id":"z-ai/glm-4.7","name":"GLM-4.7","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":0.4,"output":1.75,"cache_read":0.08},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-12-22"},"openrouter/z-ai/glm-4.7-flash":{"provider":"openrouter","id":"z-ai/glm-4.7-flash","name":"GLM-4.7-Flash","family":"glm-flash","context_window":200000,"max_output":117964,"cost":{"input":0.0605,"output":0.4},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2026-01-19"},"openrouter/z-ai/glm-5":{"provider":"openrouter","id":"z-ai/glm-5","name":"GLM-5","family":"glm","context_window":204800,"max_output":128000,"cost":{"input":0.6,"output":1.92,"cache_read":0.12},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-12"},"openrouter/z-ai/glm-5-turbo":{"provider":"openrouter","id":"z-ai/glm-5-turbo","name":"GLM-5-Turbo","family":"glm","context_window":202752,"max_output":131072,"cost":{"input":1.2,"output":4,"cache_read":0.24},"reasoning":true,"tool_call":true,"release_date":"2026-03-16"},"openrouter/z-ai/glm-5.1":{"provider":"openrouter","id":"z-ai/glm-5.1","name":"GLM-5.1","family":"glm","context_window":204800,"max_output":128000,"cost":{"input":0.966,"output":3.036,"cache_read":0.1794},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-04-07"},"openrouter/z-ai/glm-5.2":{"provider":"openrouter","id":"z-ai/glm-5.2","name":"GLM-5.2","family":"glm","context_window":1048576,"max_output":128000,"cost":{"input":1.4,"output":4.4,"cache_read":0.14},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-13"},"openrouter/z-ai/glm-5.3":{"provider":"openrouter","id":"z-ai/glm-5.3","name":"GLM-5.3","family":"glm","context_window":1310720,"max_output":943717,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-14"},"openrouter/z-ai/glm-5.3-flash":{"provider":"openrouter","id":"z-ai/glm-5.3-flash","name":"GLM-5.3-Flash","family":"glm","context_window":1310720,"max_output":131072,"cost":{"input":0.15,"output":0.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-08-26"},"openrouter/z-ai/glm-5v-turbo":{"provider":"openrouter","id":"z-ai/glm-5v-turbo","name":"GLM-5V-Turbo","family":"glm","context_window":202752,"max_output":131072,"cost":{"input":1.2,"output":4,"cache_read":0.24},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-04-01"},"openrouter/~anthropic/claude-fable-latest":{"provider":"openrouter","id":"~anthropic/claude-fable-latest","name":"Claude Fable Latest","family":"claude-fable","context_window":1000000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":0.25,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-06-09"},"openrouter/~anthropic/claude-haiku-latest":{"provider":"openrouter","id":"~anthropic/claude-haiku-latest","name":"Claude Haiku Latest","family":"claude-haiku","context_window":200000,"max_output":64000,"cost":{"input":1,"output":5,"cache_read":0.1,"cache_write":1.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-27"},"openrouter/~anthropic/claude-opus-latest":{"provider":"openrouter","id":"~anthropic/claude-opus-latest","name":"Claude Opus Latest","family":"claude-opus","context_window":1000000,"max_output":128000,"cost":{"input":5,"output":25,"cache_read":0.5,"cache_write":6.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-21"},"openrouter/~anthropic/claude-sonnet-latest":{"provider":"openrouter","id":"~anthropic/claude-sonnet-latest","name":"Claude Sonnet Latest","family":"claude-sonnet","context_window":1000000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-01-31","release_date":"2026-04-27"},"openrouter/~deepseek/deepseek-flash-latest":{"provider":"openrouter","id":"~deepseek/deepseek-flash-latest","name":"DeepSeek Flash Latest","family":"deepseek-flash","context_window":1048576,"max_output":943718,"cost":{"input":0.15,"output":0.6,"cache_read":0.015},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-09-14"},"openrouter/~deepseek/deepseek-pro-latest":{"provider":"openrouter","id":"~deepseek/deepseek-pro-latest","name":"DeepSeek Pro Latest","family":"deepseek","context_window":1048576,"max_output":943718,"cost":{"input":0.96,"output":2.88,"cache_read":0.088},"reasoning":true,"tool_call":true,"release_date":"2026-09-14"},"openrouter/~deepseek/deepseek-v4-flash-latest":{"provider":"openrouter","id":"~deepseek/deepseek-v4-flash-latest","name":"DeepSeek V4 Flash Latest","family":"deepseek","context_window":1310720,"max_output":393216,"cost":{"input":0.04,"output":0.1,"cache_read":0.01},"reasoning":true,"tool_call":true,"release_date":"2026-08-01"},"openrouter/~google/gemini-flash-latest":{"provider":"openrouter","id":"~google/gemini-flash-latest","name":"Gemini Flash Latest","family":"gemini-flash","context_window":1048576,"max_output":65536,"cost":{"input":0.75,"output":3.75,"cache_read":0.075,"cache_write":0.041667},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01-01","release_date":"2026-04-27"},"openrouter/~google/gemini-pro-latest":{"provider":"openrouter","id":"~google/gemini-pro-latest","name":"Gemini Pro Latest","family":"gemini-pro","context_window":1048576,"max_output":65536,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":0.375},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-27"},"openrouter/~moonshotai/kimi-latest":{"provider":"openrouter","id":"~moonshotai/kimi-latest","name":"Kimi Latest","family":"kimi","context_window":1048576,"max_output":943718,"cost":{"input":2.1,"output":10.95,"cache_read":0.23},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-04-27"},"openrouter/~openai/gpt-astra-latest":{"provider":"openrouter","id":"~openai/gpt-astra-latest","name":"GPT Astra Latest","family":"gpt-astra","context_window":1050000,"max_output":128000,"cost":{"input":10,"output":50,"cache_read":1,"cache_write":12.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-09-11"},"openrouter/~openai/gpt-luna-latest":{"provider":"openrouter","id":"~openai/gpt-luna-latest","name":"GPT Luna Latest","family":"gpt-luna","context_window":1050000,"max_output":128000,"cost":{"input":0.2,"output":1.2,"cache_read":0.02,"cache_write":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-09-11"},"openrouter/~openai/gpt-mini-latest":{"provider":"openrouter","id":"~openai/gpt-mini-latest","name":"GPT Mini Latest","family":"gpt-mini","context_window":400000,"max_output":128000,"cost":{"input":0.75,"output":4.5,"cache_read":0.075},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2025-08-31","release_date":"2026-04-27"},"openrouter/~openai/gpt-sol-latest":{"provider":"openrouter","id":"~openai/gpt-sol-latest","name":"GPT Sol Latest","family":"gpt-sol","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":10,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-09-11"},"openrouter/~openai/gpt-terra-latest":{"provider":"openrouter","id":"~openai/gpt-terra-latest","name":"GPT Terra Latest","family":"gpt-terra","context_window":1050000,"max_output":128000,"cost":{"input":2,"output":12,"cache_read":0.2,"cache_write":2.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-16","release_date":"2026-09-11"},"openrouter/~x-ai/grok-latest":{"provider":"openrouter","id":"~x-ai/grok-latest","name":"Grok Latest","family":"grok","context_window":500000,"max_output":450000,"cost":{"input":2,"output":6,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-07-08"},"openrouter/~z-ai/glm-flash-latest":{"provider":"openrouter","id":"~z-ai/glm-flash-latest","name":"GLM Flash Latest","family":"glm-flash","context_window":1310720,"max_output":131072,"cost":{"input":0.075,"output":0.25,"cache_read":0.015},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"release_date":"2026-08-27"},"openrouter/~z-ai/glm-latest":{"provider":"openrouter","id":"~z-ai/glm-latest","name":"GLM Latest","family":"glm","context_window":1310720,"max_output":235929,"cost":{"input":0.8775,"output":2.97,"cache_read":0.1755},"reasoning":true,"tool_call":true,"release_date":"2026-08-19"},"perplexity/sonar":{"provider":"perplexity","id":"sonar","name":"Sonar","family":"sonar","context_window":128000,"max_output":4096,"cost":{"input":1,"output":1},"knowledge_cutoff":"2025-09-01","release_date":"2024-01-01"},"perplexity/sonar-deep-research":{"provider":"perplexity","id":"sonar-deep-research","name":"Perplexity Sonar Deep Research","context_window":128000,"max_output":32768,"cost":{"input":2,"output":8},"reasoning":true,"knowledge_cutoff":"2025-01","release_date":"2025-02-01"},"perplexity/sonar-pro":{"provider":"perplexity","id":"sonar-pro","name":"Sonar Pro","family":"sonar-pro","context_window":200000,"max_output":8192,"cost":{"input":3,"output":15},"attachment":true,"vision":true,"knowledge_cutoff":"2025-09-01","release_date":"2024-01-01"},"perplexity/sonar-reasoning-pro":{"provider":"perplexity","id":"sonar-reasoning-pro","name":"Sonar Reasoning Pro","family":"sonar-reasoning","context_window":128000,"max_output":4096,"cost":{"input":2,"output":8},"reasoning":true,"attachment":true,"vision":true,"knowledge_cutoff":"2025-09-01","release_date":"2024-01-01"},"togetherai/LiquidAI/LFM2-24B-A2B":{"provider":"togetherai","id":"LiquidAI/LFM2-24B-A2B","name":"LFM2-24B-A2B","family":"liquid","context_window":32768,"max_output":32768,"cost":{"input":0.03,"output":0.12},"open_weights":true,"release_date":"2026-02-25"},"togetherai/MiniMaxAI/MiniMax-M2.5":{"provider":"togetherai","id":"MiniMaxAI/MiniMax-M2.5","name":"MiniMax-M2.5","family":"minimax","context_window":204800,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-12"},"togetherai/MiniMaxAI/MiniMax-M2.7":{"provider":"togetherai","id":"MiniMaxAI/MiniMax-M2.7","name":"MiniMax-M2.7","family":"minimax","context_window":202752,"max_output":131072,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-03-18"},"togetherai/MiniMaxAI/MiniMax-M3":{"provider":"togetherai","id":"MiniMaxAI/MiniMax-M3","name":"MiniMax-M3","family":"minimax","context_window":524288,"max_output":250000,"cost":{"input":0.3,"output":1.2,"cache_read":0.06},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-06-12"},"togetherai/Qwen/Qwen2.5-7B-Instruct-Turbo":{"provider":"togetherai","id":"Qwen/Qwen2.5-7B-Instruct-Turbo","name":"Qwen 2.5 7B Instruct Turbo","family":"qwen","context_window":32768,"max_output":32768,"cost":{"input":0.3,"output":0.3},"tool_call":true,"open_weights":true,"release_date":"2024-09-19"},"togetherai/Qwen/Qwen3-235B-A22B-Instruct-2507-tput":{"provider":"togetherai","id":"Qwen/Qwen3-235B-A22B-Instruct-2507-tput","name":"Qwen3 235B A22B Instruct 2507 FP8","family":"qwen","context_window":262144,"max_output":262144,"cost":{"input":0.2,"output":0.6},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-07","release_date":"2025-07-25"},"togetherai/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8":{"provider":"togetherai","id":"Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8","name":"Qwen3 Coder 480B A35B Instruct","family":"qwen","context_window":262144,"max_output":262144,"cost":{"input":2,"output":2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-23"},"togetherai/Qwen/Qwen3-Coder-Next-FP8":{"provider":"togetherai","id":"Qwen/Qwen3-Coder-Next-FP8","name":"Qwen3 Coder Next FP8","family":"qwen","context_window":262144,"max_output":262144,"cost":{"input":0.5,"output":1.2},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2026-02-03","release_date":"2026-02-03"},"togetherai/Qwen/Qwen3.5-397B-A17B":{"provider":"togetherai","id":"Qwen/Qwen3.5-397B-A17B","name":"Qwen3.5 397B A17B","family":"qwen","context_window":262144,"max_output":130000,"cost":{"input":0.6,"output":3.6,"cache_read":0.35},"reasoning":true,"tool_call":true,"vision":true,"open_weights":true,"release_date":"2026-02-16"},"togetherai/Qwen/Qwen3.5-9B":{"provider":"togetherai","id":"Qwen/Qwen3.5-9B","name":"Qwen3.5 9B","family":"qwen","context_window":262144,"max_output":65536,"cost":{"input":0.17,"output":0.25},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-03-03"},"togetherai/Qwen/Qwen3.6-Plus":{"provider":"togetherai","id":"Qwen/Qwen3.6-Plus","name":"Qwen3.6 Plus","family":"qwen","context_window":1000000,"max_output":500000,"cost":{"input":0.5,"output":3},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-04-30"},"togetherai/Qwen/Qwen3.7-Max":{"provider":"togetherai","id":"Qwen/Qwen3.7-Max","name":"Qwen3.7 Max","family":"qwen","context_window":1000000,"max_output":500000,"cost":{"input":1.25,"output":3.75,"cache_read":0.125},"tool_call":true,"release_date":"2026-05-21"},"togetherai/deepcogito/cogito-v2-1-671b":{"provider":"togetherai","id":"deepcogito/cogito-v2-1-671b","name":"Cogito v2.1 671B","family":"cogito","context_window":163840,"max_output":163840,"cost":{"input":1.25,"output":1.25},"reasoning":true,"release_date":"2025-11-13"},"togetherai/deepseek-ai/DeepSeek-R1":{"provider":"togetherai","id":"deepseek-ai/DeepSeek-R1","name":"DeepSeek-R1","family":"deepseek-thinking","context_window":163839,"max_output":163839,"cost":{"input":3,"output":7},"reasoning":true,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2025-01-20"},"togetherai/deepseek-ai/DeepSeek-V3":{"provider":"togetherai","id":"deepseek-ai/DeepSeek-V3","name":"DeepSeek-V3","family":"deepseek","context_window":131072,"max_output":131072,"cost":{"input":1.25,"output":1.25},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-07","release_date":"2024-12-26"},"togetherai/deepseek-ai/DeepSeek-V3-1":{"provider":"togetherai","id":"deepseek-ai/DeepSeek-V3-1","name":"DeepSeek V3.1","family":"deepseek","context_window":131072,"max_output":131072,"cost":{"input":0.6,"output":1.7},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-08","release_date":"2025-08-21"},"togetherai/deepseek-ai/DeepSeek-V4-Flash-0731":{"provider":"togetherai","id":"deepseek-ai/DeepSeek-V4-Flash-0731","name":"DeepSeek V4 Flash 0731","family":"deepseek-flash","context_window":1000000,"max_output":384000,"cost":{"input":0.14,"output":0.28,"cache_read":0.03},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-07-31"},"togetherai/deepseek-ai/DeepSeek-V4-Pro":{"provider":"togetherai","id":"deepseek-ai/DeepSeek-V4-Pro","name":"DeepSeek V4 Pro","family":"deepseek","context_window":512000,"max_output":384000,"cost":{"input":1.74,"output":3.48,"cache_read":0.2},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-04-24"},"togetherai/deepseek-ai/DeepSeek-V4-Pro-0813":{"provider":"togetherai","id":"deepseek-ai/DeepSeek-V4-Pro-0813","name":"DeepSeek V4 Pro 0813","family":"deepseek-thinking","context_window":1048576,"max_output":384000,"cost":{"input":1.32,"output":3.96,"cache_read":0.13},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-12"},"togetherai/deepseek-ai/DeepSeek-V4.1-Flash":{"provider":"togetherai","id":"deepseek-ai/DeepSeek-V4.1-Flash","name":"DeepSeek V4.1 Flash","family":"deepseek-flash","context_window":1048576,"max_output":384000,"cost":{"input":0.3,"output":1.2,"cache_read":0.006},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-05","release_date":"2026-09-10"},"togetherai/essentialai/Rnj-1-Instruct":{"provider":"togetherai","id":"essentialai/Rnj-1-Instruct","name":"Rnj-1 Instruct","family":"rnj","context_window":32768,"max_output":32768,"cost":{"input":0.15,"output":0.15},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2024-10","release_date":"2025-12-05"},"togetherai/google/gemma-3n-E4B-it":{"provider":"togetherai","id":"google/gemma-3n-E4B-it","name":"Gemma 3N E4B Instruct","family":"gemma","context_window":32768,"max_output":32768,"cost":{"input":0.06,"output":0.12},"open_weights":true,"release_date":"2025-05-20"},"togetherai/google/gemma-4-31B-it":{"provider":"togetherai","id":"google/gemma-4-31B-it","name":"Gemma 4 31B Instruct","family":"gemma","context_window":262144,"max_output":131072,"cost":{"input":0.39,"output":0.97},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-07"},"togetherai/meta-llama/Llama-3.3-70B-Instruct-Turbo":{"provider":"togetherai","id":"meta-llama/Llama-3.3-70B-Instruct-Turbo","name":"Llama 3.3 70B","family":"llama","context_window":131072,"max_output":131072,"cost":{"input":1.04,"output":1.04},"tool_call":true,"open_weights":true,"knowledge_cutoff":"2023-12","release_date":"2024-12-06"},"togetherai/meta-llama/Meta-Llama-3-8B-Instruct-Lite":{"provider":"togetherai","id":"meta-llama/Meta-Llama-3-8B-Instruct-Lite","name":"Meta Llama 3 8B Instruct Lite","family":"llama","context_window":8192,"max_output":8192,"cost":{"input":0.14,"output":0.14},"open_weights":true,"release_date":"2024-04-18"},"togetherai/moonshotai/Kimi-K2.5":{"provider":"togetherai","id":"moonshotai/Kimi-K2.5","name":"Kimi K2.5","family":"kimi-k2","context_window":262144,"max_output":262144,"cost":{"input":0.5,"output":2.8},"reasoning":true,"tool_call":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2026-01","release_date":"2026-01-27"},"togetherai/moonshotai/Kimi-K2.6":{"provider":"togetherai","id":"moonshotai/Kimi-K2.6","name":"Kimi K2.6","family":"kimi-k2","context_window":262144,"max_output":131000,"cost":{"input":1.2,"output":4.5,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-01","release_date":"2026-04-21"},"togetherai/moonshotai/Kimi-K2.7-Code":{"provider":"togetherai","id":"moonshotai/Kimi-K2.7-Code","name":"Kimi K2.7 Code","family":"kimi-k2","context_window":262144,"max_output":131072,"cost":{"input":0.95,"output":4,"cache_read":0.19},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-14"},"togetherai/moonshotai/Kimi-K3":{"provider":"togetherai","id":"moonshotai/Kimi-K3","name":"Kimi K3","family":"kimi-k3","context_window":1048576,"max_output":131072,"cost":{"input":3,"output":15,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-16"},"togetherai/nvidia/nemotron-3-ultra-550b-a55b":{"provider":"togetherai","id":"nvidia/nemotron-3-ultra-550b-a55b","name":"Nemotron 3 Ultra 550B A55B","family":"nemotron","context_window":512300,"max_output":512300,"cost":{"input":0.6,"output":3.6,"cache_read":0.2},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-04"},"togetherai/openai/gpt-oss-120b":{"provider":"togetherai","id":"openai/gpt-oss-120b","name":"GPT OSS 120B","family":"gpt-oss","context_window":131072,"max_output":131072,"cost":{"input":0.15,"output":0.6},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-08","release_date":"2025-08-05"},"togetherai/openai/gpt-oss-20b":{"provider":"togetherai","id":"openai/gpt-oss-20b","name":"GPT OSS 20B","family":"gpt-oss","context_window":131072,"max_output":131072,"cost":{"input":0.05,"output":0.2},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2025-08-05"},"togetherai/pearl-ai/gemma-4-31b-it":{"provider":"togetherai","id":"pearl-ai/gemma-4-31b-it","name":"Pearl AI Gemma 4 31B Instruct","family":"gemma","context_window":32000,"max_output":32000,"cost":{"input":0.28,"output":0.86},"reasoning":true,"release_date":"2026-04-07"},"togetherai/thinkingmachines/Inkling":{"provider":"togetherai","id":"thinkingmachines/Inkling","name":"Inkling","family":"ling","context_window":524288,"max_output":131072,"cost":{"input":1,"output":4.05,"cache_read":0.17},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-07-15"},"togetherai/zai-org/GLM-5":{"provider":"togetherai","id":"zai-org/GLM-5","name":"GLM-5","family":"glm","context_window":202752,"max_output":131072,"cost":{"input":1,"output":3.2},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-11"},"togetherai/zai-org/GLM-5.1":{"provider":"togetherai","id":"zai-org/GLM-5.1","name":"GLM-5.1","family":"glm","context_window":202752,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-11","release_date":"2026-04-07"},"togetherai/zai-org/GLM-5.2":{"provider":"togetherai","id":"zai-org/GLM-5.2","name":"GLM-5.2","family":"glm","context_window":512000,"max_output":164000,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-16"},"togetherai/zai-org/GLM-5.3":{"provider":"togetherai","id":"zai-org/GLM-5.3","name":"GLM-5.3","family":"glm","context_window":1048576,"max_output":262144,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-14"},"togetherai/zai-org/GLM-5.3-Flash":{"provider":"togetherai","id":"zai-org/GLM-5.3-Flash","name":"GLM-5.3-Flash","family":"glm","context_window":1048575,"max_output":400000,"cost":{"input":0.15,"output":0.5,"cache_read":0.03},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"release_date":"2026-08-26"},"xai/grok-4.20-0309-non-reasoning":{"provider":"xai","id":"grok-4.20-0309-non-reasoning","name":"Grok 4.20 (Non-Reasoning)","family":"grok","context_window":1000000,"max_output":30000,"cost":{"input":1.25,"output":2.5,"cache_read":0.2},"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-03-09"},"xai/grok-4.20-0309-reasoning":{"provider":"xai","id":"grok-4.20-0309-reasoning","name":"Grok 4.20 (Reasoning)","family":"grok","context_window":1000000,"max_output":30000,"cost":{"input":1.25,"output":2.5,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-03-09"},"xai/grok-4.20-multi-agent-0309":{"provider":"xai","id":"grok-4.20-multi-agent-0309","name":"Grok 4.20 Multi-Agent","family":"grok","context_window":1000000,"max_output":30000,"cost":{"input":1.25,"output":2.5,"cache_read":0.2},"reasoning":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-03-09"},"xai/grok-4.3":{"provider":"xai","id":"grok-4.3","name":"Grok 4.3","family":"grok","context_window":1000000,"max_output":30000,"cost":{"input":1.25,"output":2.5,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-17"},"xai/grok-4.5":{"provider":"xai","id":"grok-4.5","name":"Grok 4.5","family":"grok","context_window":500000,"max_output":500000,"cost":{"input":2,"output":6,"cache_read":0.3},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-07-08"},"xai/grok-4.6":{"provider":"xai","id":"grok-4.6","name":"Grok 4.6","family":"grok","context_window":500000,"max_output":500000,"cost":{"input":2,"output":6,"cache_read":0.5},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"knowledge_cutoff":"2026-02-01","release_date":"2026-08-12"},"xai/grok-build-0.1":{"provider":"xai","id":"grok-build-0.1","name":"Grok Build 0.1","family":"grok-build","context_window":256000,"max_output":256000,"cost":{"input":1,"output":2,"cache_read":0.2},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-16"},"xai/grok-imagine-image":{"provider":"xai","id":"grok-imagine-image","name":"Grok Imagine Image","family":"grok","context_window":16000,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-01-28"},"xai/grok-imagine-image-2.0":{"provider":"xai","id":"grok-imagine-image-2.0","name":"Grok Imagine Image 2.0","family":"grok","context_window":64000,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-08-07"},"xai/grok-imagine-image-quality":{"provider":"xai","id":"grok-imagine-image-quality","name":"Grok Imagine Image Quality","family":"grok","context_window":16000,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-03"},"xai/grok-imagine-video":{"provider":"xai","id":"grok-imagine-video","name":"Grok Imagine Video","family":"grok","context_window":1024,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-01-28"},"xai/grok-imagine-video-1.5":{"provider":"xai","id":"grok-imagine-video-1.5","name":"Grok Imagine Video 1.5","family":"grok","context_window":1024,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-05-30"},"zai/glm-4.5":{"provider":"zai","id":"glm-4.5","name":"GLM-4.5","family":"glm","context_window":131072,"max_output":98304,"cost":{"input":0.6,"output":2.2,"cache_read":0.11},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-28"},"zai/glm-4.5-air":{"provider":"zai","id":"glm-4.5-air","name":"GLM-4.5-Air","family":"glm-air","context_window":131072,"max_output":98304,"cost":{"input":0.2,"output":1.1,"cache_read":0.03},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-28"},"zai/glm-4.5-flash":{"provider":"zai","id":"glm-4.5-flash","name":"GLM-4.5-Flash","family":"glm-flash","context_window":131072,"max_output":98304,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-07-28"},"zai/glm-4.5v":{"provider":"zai","id":"glm-4.5v","name":"GLM-4.5V","family":"glm","context_window":64000,"max_output":16384,"cost":{"input":0.6,"output":1.8},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-08-11"},"zai/glm-4.6":{"provider":"zai","id":"glm-4.6","name":"GLM-4.6","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":0.6,"output":2.2,"cache_read":0.11},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-09-30"},"zai/glm-4.6v":{"provider":"zai","id":"glm-4.6v","name":"GLM-4.6V","family":"glm","context_window":128000,"max_output":32768,"cost":{"input":0.3,"output":0.9},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-12-08"},"zai/glm-4.7":{"provider":"zai","id":"glm-4.7","name":"GLM-4.7","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":0.6,"output":2.2,"cache_read":0.11},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2025-12-22"},"zai/glm-4.7-flash":{"provider":"zai","id":"glm-4.7-flash","name":"GLM-4.7-Flash","family":"glm-flash","context_window":200000,"max_output":131072,"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2026-01-19"},"zai/glm-4.7-flashx":{"provider":"zai","id":"glm-4.7-flashx","name":"GLM-4.7-FlashX","family":"glm-flash","context_window":200000,"max_output":131072,"cost":{"input":0.07,"output":0.4,"cache_read":0.01},"reasoning":true,"tool_call":true,"open_weights":true,"knowledge_cutoff":"2025-04","release_date":"2026-01-19"},"zai/glm-5":{"provider":"zai","id":"glm-5","name":"GLM-5","family":"glm","context_window":204800,"max_output":131072,"cost":{"input":1,"output":3.2,"cache_read":0.2},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-02-12"},"zai/glm-5-turbo":{"provider":"zai","id":"glm-5-turbo","name":"GLM-5-Turbo","family":"glm","context_window":200000,"max_output":131072,"cost":{"input":1.2,"output":4,"cache_read":0.24},"reasoning":true,"tool_call":true,"release_date":"2026-03-16"},"zai/glm-5.1":{"provider":"zai","id":"glm-5.1","name":"GLM-5.1","family":"glm","context_window":200000,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-04-07"},"zai/glm-5.2":{"provider":"zai","id":"glm-5.2","name":"GLM-5.2","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-06-13"},"zai/glm-5.3":{"provider":"zai","id":"glm-5.3","name":"GLM-5.3","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":1.4,"output":4.4,"cache_read":0.26},"reasoning":true,"tool_call":true,"open_weights":true,"release_date":"2026-08-14"},"zai/glm-5.3-flash":{"provider":"zai","id":"glm-5.3-flash","name":"GLM-5.3-Flash","family":"glm","context_window":1000000,"max_output":131072,"cost":{"input":0.075,"output":0.25,"cache_read":0.015},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"open_weights":true,"release_date":"2026-08-26"},"zai/glm-5v-turbo":{"provider":"zai","id":"glm-5v-turbo","name":"GLM-5V-Turbo","family":"glm","context_window":200000,"max_output":131072,"cost":{"input":1.2,"output":4,"cache_read":0.24},"reasoning":true,"tool_call":true,"attachment":true,"vision":true,"pdf":true,"release_date":"2026-04-01"}}} diff --git a/internal/providers/refresh.go b/internal/providers/refresh.go new file mode 100644 index 0000000..9c02542 --- /dev/null +++ b/internal/providers/refresh.go @@ -0,0 +1,323 @@ +// refresh.go maintains a live copy of the models.dev catalogue on top of the +// bundled snapshot. The bundled JSON always answers immediately (offline, +// first-run, corporate firewalls); a background pull tops it up with fresher +// data and stores the result under $XDG_CACHE_HOME/antares/models.json for +// the next process. +// +// The pattern mirrors opencode's model registry: seed from the embedded +// snapshot, load a cached copy from disk if present, then fire a +// non-blocking HTTP fetch. Runtime callers never wait — they read whichever +// table is currently swapped in. + +package providers + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "strings" + "sync" + "time" +) + +// Env vars operators can use to steer the refresh without editing config. +// Kept as flags rather than YAML fields because they are process-boot +// decisions (airgapped host, corporate proxy, offline dev) that the runtime +// config code path never needs to see. +const ( + envDisableFetch = "ANTARES_DISABLE_MODELS_FETCH" + envSourceURL = "ANTARES_MODELS_URL" + envCachePath = "ANTARES_MODELS_CACHE" +) + +// defaultSourceURL is the models.dev catalogue. Kept in sync with the sync +// script's catalogueURL by convention — this is the runtime pull, that is +// the build-time pull. +const defaultSourceURL = "https://models.dev/api.json" + +// refreshInterval bounds how often we re-pull models.dev in a long-lived +// process (the daemon can outlive the browser or TUI it serves). Matches +// opencode's 1h default — models.dev churn is measured in days, not hours, +// so anything shorter is just noise. +const refreshInterval = 1 * time.Hour + +// httpTimeout keeps a stuck fetch from pinning the goroutine. Bounded well +// under the refreshInterval so an outage never queues multiple in-flight +// requests. +const httpTimeout = 10 * time.Second + +// refreshOnce guards StartRefresh so accidental double-calls from init and +// runtime wiring only fire one goroutine per process. +var refreshOnce sync.Once + +// StartRefresh kicks off the background pull, if fetching is enabled. Safe +// to call from any goroutine; only the first call spawns the loop. Idempotent +// so unit tests and cmd/antares wiring can both invoke it without contract. +// +// The caller passes a context that scopes the goroutine's lifetime — pass +// the runtime's root context so the loop exits when the process shuts down. +// A nil context is treated as context.Background() for one-shot uses. +func StartRefresh(ctx context.Context) { + if os.Getenv(envDisableFetch) == "1" { + return + } + if ctx == nil { + ctx = context.Background() + } + refreshOnce.Do(func() { + go refreshLoop(ctx) + }) +} + +// refreshLoop performs the immediate seed-from-disk-and-fetch, then +// re-polls on refreshInterval. Errors are swallowed to stderr — the bundled +// snapshot is always a working fallback, so a failed refresh degrades +// gracefully instead of announcing itself to the operator. +func refreshLoop(ctx context.Context) { + // Disk cache first — persisted across restarts, so a warm boot on an + // offline laptop still has whatever the last online session pulled. + if raw, ok := readDiskCache(); ok { + if table, err := parseGeneratedModels(raw); err == nil { + setGeneratedModels(table) + } + } + + // Immediate first fetch so a fresh install sees live data within a few + // seconds of startup rather than waiting a whole interval. + tryRefresh(ctx) + + ticker := time.NewTicker(refreshInterval) + defer ticker.Stop() + for { + select { + case <-ctx.Done(): + return + case <-ticker.C: + tryRefresh(ctx) + } + } +} + +// tryRefresh performs one models.dev fetch and, on success, swaps the +// in-memory table + persists the payload to disk. Failures leave both +// unchanged and log at info-level via stderr; nothing is fatal because the +// bundled snapshot keeps the process useful. +func tryRefresh(ctx context.Context) { + raw, err := fetchLive(ctx) + if err != nil { + return + } + // The live models.dev payload is not shaped like our snapshot — it is + // keyed by provider, then by model, with a different field layout. Run + // it through the same extract path as the sync script so the on-disk + // cache and in-memory table both match the bundled schema. + table, err := normaliseLive(raw) + if err != nil { + return + } + setGeneratedModels(table) + + // Persist the normalised bytes, not the raw upstream, so a warm boot + // takes the fast parseGeneratedModels path without another normalise. + if blob, err := encodeSnapshot(table); err == nil { + writeDiskCache(blob) + } +} + +// fetchLive pulls the live models.dev catalogue. Bounded timeout and a +// polite user agent so operators can identify Antares in their access logs. +func fetchLive(ctx context.Context) ([]byte, error) { + url := os.Getenv(envSourceURL) + if url == "" { + url = defaultSourceURL + } + ctx, cancel := context.WithTimeout(ctx, httpTimeout) + defer cancel() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + return nil, err + } + req.Header.Set("User-Agent", "antares/models-refresh") + req.Header.Set("Accept", "application/json") + resp, err := http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + if resp.StatusCode >= 400 { + return nil, fmt.Errorf("models.dev: %s", resp.Status) + } + return io.ReadAll(io.LimitReader(resp.Body, 8<<20)) // 8 MiB cap; catalogue is ~1 MiB +} + +// normaliseLive converts the raw models.dev api.json shape into our +// snapshot table. The upstream schema evolves; anything we do not recognise +// is dropped rather than propagated as a partial entry that would confuse +// callers walking the cascade. +func normaliseLive(raw []byte) (map[string]ModelMeta, error) { + var payload map[string]struct { + ID string `json:"id"` + Name string `json:"name"` + Models map[string]struct { + ID string `json:"id"` + Name string `json:"name"` + ReleaseDate string `json:"release_date"` + KnowledgeCutoff string `json:"knowledge"` + Limit struct { + Context int `json:"context"` + Output int `json:"output"` + } `json:"limit"` + Cost struct { + Input float64 `json:"input"` + Output float64 `json:"output"` + CacheRead float64 `json:"cache_read"` + CacheWrite float64 `json:"cache_write"` + } `json:"cost"` + Modalities struct { + Input []string `json:"input"` + Output []string `json:"output"` + } `json:"modalities"` + Reasoning bool `json:"reasoning"` + ToolCall bool `json:"tool_call"` + OpenWeights bool `json:"open_weights"` + } `json:"models"` + } + if err := json.Unmarshal(raw, &payload); err != nil { + return nil, err + } + out := make(map[string]ModelMeta, 1024) + for providerID, prov := range payload { + if !providerAllowed(providerID) { + continue + } + for modelID, m := range prov.Models { + id := m.ID + if id == "" { + id = modelID + } + id = stripPrefix(providerID, id) + key := providerID + "/" + id + name := m.Name + if name == id { + name = "" + } + out[key] = ModelMeta{ + Provider: providerID, + ID: id, + Name: name, + ContextWindow: m.Limit.Context, + MaxOutput: m.Limit.Output, + Cost: Cost{Input: m.Cost.Input, Output: m.Cost.Output, CacheRead: m.Cost.CacheRead, CacheWrite: m.Cost.CacheWrite}, + Reasoning: m.Reasoning, + ToolCall: m.ToolCall, + Attachment: hasAny(m.Modalities.Input, "image", "pdf", "audio", "video"), + Vision: hasAny(m.Modalities.Input, "image"), + PDF: hasAny(m.Modalities.Input, "pdf"), + OpenWeights: m.OpenWeights, + KnowledgeCutoff: m.KnowledgeCutoff, + ReleaseDate: m.ReleaseDate, + } + } + } + return out, nil +} + +// providerAllowed mirrors scripts/sync-models-dev.go's providersOfInterest. +// Kept in a small helper here so the two don't drift silently: any provider +// the sync script would bundle, the runtime refresh should also accept. +// The list is small; a slice keeps the diff obvious. +func providerAllowed(id string) bool { + switch id { + case "anthropic", "openai", "google", "google-vertex", "azure", + "amazon-bedrock", "openrouter", "opencode", "deepseek", "mistral", + "xai", "cohere", "groq", "fireworks-ai", "together-ai", + "perplexity", "cerebras", "sambanova", "meta-llama": + return true + } + return false +} + +// stripPrefix drops a redundant "provider/" prefix some entries carry +// (e.g. models.dev sometimes ships "anthropic/claude-…" as the model id). +// The runtime key is provider + "/" + id, so a doubled prefix would miss. +func stripPrefix(provider, id string) string { + prefix := provider + "/" + if strings.HasPrefix(id, prefix) { + return strings.TrimPrefix(id, prefix) + } + return id +} + +func hasAny(haystack []string, needles ...string) bool { + for _, h := range haystack { + for _, n := range needles { + if h == n { + return true + } + } + } + return false +} + +// encodeSnapshot writes the current table in the bundled snapshot's shape, +// so writeDiskCache / parseGeneratedModels can round-trip through the same +// envelope the //go:embed asset uses. +func encodeSnapshot(table map[string]ModelMeta) ([]byte, error) { + env := generatedModelsEnvelope{Models: table} + return json.Marshal(env) +} + +// cachePath resolves the on-disk cache location. Env override wins; otherwise +// $XDG_CACHE_HOME/antares/models.json (Linux/BSD) or the OS-native cache dir. +// A blank return means the platform did not surface a cache dir — in that +// case we skip persistence rather than sprinkle files in $HOME. +func cachePath() string { + if p := strings.TrimSpace(os.Getenv(envCachePath)); p != "" { + return p + } + dir, err := os.UserCacheDir() + if err != nil || dir == "" { + return "" + } + return filepath.Join(dir, "antares", "models.json") +} + +func readDiskCache() ([]byte, bool) { + p := cachePath() + if p == "" { + return nil, false + } + raw, err := os.ReadFile(p) + if err != nil { + if !errors.Is(err, os.ErrNotExist) { + // Corrupt / permission failure — remove so a next successful + // fetch can rewrite cleanly instead of tripping over the same + // bad bytes every startup. + _ = os.Remove(p) + } + return nil, false + } + return raw, true +} + +func writeDiskCache(raw []byte) { + p := cachePath() + if p == "" { + return + } + if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { + return + } + // Atomic write via temp file + rename so a killed process never leaves + // a truncated cache the next startup would panic on. + tmp := p + ".tmp" + if err := os.WriteFile(tmp, raw, 0o644); err != nil { + return + } + _ = os.Rename(tmp, p) +} diff --git a/internal/server/handlers_config.go b/internal/server/handlers_config.go index 6fb6ffe..a723569 100644 --- a/internal/server/handlers_config.go +++ b/internal/server/handlers_config.go @@ -11,6 +11,7 @@ import ( "github.com/enowdev/antares/internal/config" "github.com/enowdev/antares/internal/llm" + "github.com/enowdev/antares/internal/providers" "github.com/enowdev/antares/internal/tools" ) @@ -262,6 +263,9 @@ func (s *Server) handleModelList(w http.ResponseWriter, r *http.Request) { writeJSON(w, http.StatusOK, out) return } + for i := range models { + models[i] = applyUserOverride(p, enrichModelInfo(id, models[i], p.Kind)) + } writeJSON(w, http.StatusOK, map[string]any{"models": models}) } @@ -330,6 +334,7 @@ func (s *Server) handleModelListAll(w http.ResponseWriter, r *http.Request) { } p := cfg.Providers[t.id] for _, m := range list { + m = applyUserOverride(p, enrichModelInfo(t.id, m, p.Kind)) m = withOfficialReasoning(p.Kind, p.BaseURL, m) models = append(models, row{ModelInfo: m, Provider: t.id, ProviderLabel: t.label}) } @@ -362,6 +367,70 @@ func withOfficialReasoning(kind, baseURL string, m llm.ModelInfo) llm.ModelInfo return m } +// enrichModelInfo fills in llm.ModelInfo fields that the provider's own +// /models endpoint left blank (context window, pricing, capability flags) by +// consulting the bundled models.dev snapshot. Provider-reported values win +// when they are non-zero, so a live API is always trusted over a stale +// snapshot. Called before withOfficialReasoning so the reasoning ladder +// layer can still overwrite the capability flag for official providers. +func enrichModelInfo(providerID string, m llm.ModelInfo, kind string) llm.ModelInfo { + meta, ok := providers.MetaByProvider(providerID, m.ID) + if !ok { + // OpenAI-compatible proxies (EnxAPI, custom endpoints, LiteLLM, …) + // re-serve official models under their real ids. When the strict + // provider/id lookup misses, fall back to searching every provider + // so the picker still shows correct context/cost — but only for + // these proxies, so a first-party provider that genuinely does not + // carry a model never inherits some unrelated entry. + if kind == "openai-compatible" || kind == "custom" { + meta, ok = providers.MetaByAnyProvider(m.ID) + } + } + if !ok { + return m + } + if m.Name == "" || m.Name == m.ID { + if meta.Name != "" { + m.Name = meta.Name + } + } + if m.ContextWindow == 0 && meta.ContextWindow > 0 { + m.ContextWindow = meta.ContextWindow + } + if m.MaxOutput == 0 && meta.MaxOutput > 0 { + m.MaxOutput = meta.MaxOutput + } + if m.InputCost == 0 && meta.Cost.Input > 0 { + m.InputCost = meta.Cost.Input + } + if m.OutputCost == 0 && meta.Cost.Output > 0 { + m.OutputCost = meta.Cost.Output + } + if !m.Vision && (meta.Vision || meta.Attachment) { + m.Vision = true + } + if !m.Tools && meta.ToolCall { + m.Tools = true + } + if !m.Reasoning && meta.Reasoning { + m.Reasoning = true + } + return m +} + +// applyUserOverride swaps in fields the user pinned in cfg.Providers[id].ModelMeta. +// Called after enrichModelInfo so the override always wins over live+generated. +func applyUserOverride(p config.Provider, m llm.ModelInfo) llm.ModelInfo { + override, ok := p.ModelMeta[m.ID] + if !ok { + return m + } + if override.ContextWindow > 0 { + m.ContextWindow = override.ContextWindow + } + return m +} + // handleOfficialReasoningCapability returns the native reasoning ladder for // one official provider+model. Custom endpoints return an empty values list. func (s *Server) handleOfficialReasoningCapability(w http.ResponseWriter, r *http.Request) { diff --git a/internal/server/handlers_providers.go b/internal/server/handlers_providers.go index 51e7b9b..dae3259 100644 --- a/internal/server/handlers_providers.go +++ b/internal/server/handlers_providers.go @@ -49,23 +49,141 @@ func (s *Server) handleProviderModelInfo(w http.ResponseWriter, r *http.Request) // then a sane default. func (s *Server) handleContextWindow(w http.ResponseWriter, r *http.Request) { cfg := s.config() - model := cfg.Model.Default - // Same precedence as the agent's contextWindowFor: per-model meta override, - // then the provider catalogue (real windows for known models like glm-5.2's - // 1M), then the configured window, then a sane default. - window := 128000 - if w := providers.ContextWindow(model); w > 0 { - window = w - } else if cfg.Model.ContextWindow > 0 { - window = cfg.Model.ContextWindow - } - for _, p := range cfg.Providers { + model := strings.TrimSpace(r.URL.Query().Get("model")) + // The dashboard ModelPicker sends "provider/model-id" (e.g. "enx/kimi-k2.6"). + // Split it so resolveContextWindow can prefer the caller-named provider + // and match against its Models/ModelMeta lists. + provider := strings.TrimSpace(r.URL.Query().Get("provider")) + if provider == "" && strings.Contains(model, "/") { + provider, model, _ = strings.Cut(model, "/") + } + if model == "" { + model = cfg.Model.Default + } + if provider == "" { + provider = cfg.Model.Provider + } + window := resolveContextWindowFor(cfg, provider, model) + writeJSON(w, http.StatusOK, map[string]any{"context_window": window, "model": model, "provider": provider}) +} + +// resolveContextWindowFor is resolveContextWindow with an explicit provider +// hint, so a caller who names the provider (dashboard picker) skips the +// heuristic that walks every provider config. Falls through to the general +// cascade when the hint is empty. +func resolveContextWindowFor(cfg *config.Config, provider, model string) int { + if cfg == nil || model == "" { + return 128000 + } + if provider != "" { + p := cfg.Providers[provider] if m, ok := p.ModelMeta[model]; ok && m.ContextWindow > 0 { - window = m.ContextWindow - break + return m.ContextWindow + } + if meta, ok := providers.MetaByProvider(provider, model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + if p.Kind == "openai-compatible" || p.Kind == "custom" { + if meta, ok := providers.MetaByAnyProvider(model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + } + } + return resolveContextWindow(cfg, model) +} + +// resolveContextWindow mirrors agent.contextWindowFor so the dashboard's +// gauge and the compaction threshold cannot disagree. Cascade: +// +// 1. Per-provider user override in cfg.Providers[…].ModelMeta — but only +// for the provider that actually declares the model, not every one. +// 2. Strict providers.MetaByProvider — for the model's owning provider. +// 3. Proxy fallback: for openai-compatible / custom providers only, +// search the whole models.dev snapshot by bare id. +// 4. Global fallback cfg.Model.ContextWindow — the Settings > Model page's +// "Context Window" field. 0 (default) means "not set" so we skip. +// 5. 128000 safety net. +// +// The earlier version iterated every provider in the config and returned the +// first hit, which caused providers.MetaByProvider's loose fallback to attribute +// the wrong context/cost to any unrelated provider — e.g. reading Anthropic's +// entry for a request against a Kimi model. +func resolveContextWindow(cfg *config.Config, model string) int { + if cfg == nil || model == "" { + return 128000 + } + candidates := candidateProviders(cfg, model) + // First pass: strict provider/id lookup for each candidate. + for _, providerID := range candidates { + p := cfg.Providers[providerID] + if m, ok := p.ModelMeta[model]; ok && m.ContextWindow > 0 { + return m.ContextWindow + } + if meta, ok := providers.MetaByProvider(providerID, model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + } + // Second pass: proxy fallback. If any candidate provider is an + // openai-compatible proxy (EnxAPI, LiteLLM, custom endpoint), consult + // the bare-id lookup — those proxies re-serve official models under + // real ids without cataloguing them anywhere models.dev can see. + for _, providerID := range candidates { + if !isProxyKind(cfg.Providers[providerID].Kind) { + continue + } + if meta, ok := providers.MetaByAnyProvider(model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + } + if cfg.Model.ContextWindow > 0 { + return cfg.Model.ContextWindow + } + return 128000 +} + +// isProxyKind reports whether a provider is an OpenAI-compatible passthrough +// that re-serves official models under real ids. Only such providers opt in +// to the bare-id metadata fallback; first-party providers (anthropic, openai, +// gemini, cursor-agent, opencode) always resolve by strict provider/id. +func isProxyKind(kind string) bool { + switch kind { + case "openai-compatible", "custom": + return true + default: + return false + } +} + +// candidateProviders returns provider ids to check for a model, in priority +// order. The active provider wins so /api/context-window (which reads the +// default model) sees the same answer as an active turn. After that, any +// provider whose Models list *or* ModelMeta keys mention the id — a provider +// that carries a per-model meta override has clearly claimed the model. +// Result is de-duplicated and never empty when a provider is configured. +func candidateProviders(cfg *config.Config, model string) []string { + seen := map[string]bool{} + var out []string + push := func(id string) { + if id == "" || seen[id] { + return + } + seen[id] = true + out = append(out, id) + } + push(cfg.Model.Provider) + for providerID, p := range cfg.Providers { + if _, ok := p.ModelMeta[model]; ok { + push(providerID) + continue + } + for _, m := range p.Models { + if m == model { + push(providerID) + break + } } } - writeJSON(w, http.StatusOK, map[string]any{"context_window": window, "model": model}) + return out } // handleAddProviderModel adds a model id to providers..models, with an diff --git a/internal/tui/commands.go b/internal/tui/commands.go index 02069e6..fb347b8 100644 --- a/internal/tui/commands.go +++ b/internal/tui/commands.go @@ -117,6 +117,7 @@ func (m *Model) cmdNew(string) (bool, tea.Cmd) { m.sessionID = "" m.title = "" m.tokensIn, m.tokensOut = 0, 0 + m.ctxUsed, m.ctxWindow = 0, 0 m.blocks = nil m.greet() m.setStatus("new session") @@ -208,8 +209,16 @@ func (m *Model) cmdStatus(string) (bool, tea.Cmd) { if sess == "" { sess = "(new)" } - m.pushSystem(fmt.Sprintf("Model: %s · %s\nSession: %s\nTokens: %d in / %d out\nReasoning: %s", - model, provider, sess, m.tokensIn, m.tokensOut, onOff(m.showReasoning))) + ctx := "—" + if m.ctxWindow > 0 { + pct := 0 + if m.ctxUsed > 0 { + pct = m.ctxUsed * 100 / m.ctxWindow + } + ctx = fmt.Sprintf("%d / %d (%d%%)", m.ctxUsed, m.ctxWindow, pct) + } + m.pushSystem(fmt.Sprintf("Model: %s · %s\nSession: %s\nContext: %s\nTokens: %d in / %d out\nReasoning: %s", + model, provider, sess, ctx, m.tokensIn, m.tokensOut, onOff(m.showReasoning))) return false, nil } diff --git a/internal/tui/pickers.go b/internal/tui/pickers.go index 32a8c40..1ff1345 100644 --- a/internal/tui/pickers.go +++ b/internal/tui/pickers.go @@ -10,6 +10,7 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/enowdev/antares/internal/config" "github.com/enowdev/antares/internal/providers" ) @@ -44,7 +45,13 @@ func (m *Model) openThemePicker() { // ---- model picker ------------------------------------------------------------ -type modelRef struct{ id, prov string } +// modelRef pairs a model id with its provider — plus the context window +// when the enrichment cascade knows it, so the picker can show a "1000K" +// badge next to the provider tag. +type modelRef struct { + id, prov string + contextWindow int +} // modelsFetchedMsg carries models pulled live from provider endpoints. type modelsFetchedMsg struct{ refs []modelRef } @@ -60,7 +67,11 @@ func (m *Model) collectConfigModels() []modelRef { return } seen[prov+"\x00"+id] = true - list = append(list, modelRef{id, prov}) + list = append(list, modelRef{ + id: id, + prov: prov, + contextWindow: providerModelWindow(m.cfg, prov, id), + }) } prov := m.cfg.Model.Provider if prov != "" { @@ -72,6 +83,29 @@ func (m *Model) collectConfigModels() []modelRef { return list } +// providerModelWindow resolves the context window for a picker row through +// the same cascade the server uses (per-provider user override → strict +// generated snapshot → proxy fallback for openai-compatible/custom). Returns +// 0 when nothing knows so the picker skips the badge instead of showing "0K". +func providerModelWindow(cfg *config.Config, provider, model string) int { + if cfg == nil || provider == "" || model == "" { + return 0 + } + p := cfg.Providers[provider] + if meta, ok := p.ModelMeta[model]; ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + if meta, ok := providers.MetaByProvider(provider, model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + if p.Kind == "openai-compatible" || p.Kind == "custom" { + if meta, ok := providers.MetaByAnyProvider(model); ok && meta.ContextWindow > 0 { + return meta.ContextWindow + } + } + return 0 +} + // fetchableProviders is the active provider alone (when it can be reached), so // the model list only ever reflects the provider currently in use. // Providers with a non-empty curated models list are skipped — that list is @@ -90,11 +124,13 @@ func (m *Model) fetchableProviders() []string { } return nil } - func (m *Model) modelItem(r modelRef) pickerItem { right := "" - if r.prov != "" { - right = lipgloss.NewStyle().Foreground(themeByName(m.themeName).Faint).Render(r.prov) + faint := lipgloss.NewStyle().Foreground(themeByName(m.themeName).Faint) + if r.contextWindow > 0 { + right = faint.Render(fmt.Sprintf("%dK ctx · %s", r.contextWindow/1000, r.prov)) + } else if r.prov != "" { + right = faint.Render(r.prov) } return pickerItem{id: r.id, label: r.id, right: right, meta: r.prov} } @@ -150,7 +186,9 @@ func (m *Model) openModelPicker() tea.Cmd { return m.fetchModelsCmd(fetch) } -// fetchModelsCmd queries the given providers' /models endpoints concurrently. +// fetchModelsCmd queries the given providers' /models endpoints concurrently, +// keeping the enriched metadata so the picker can show a context-window +// badge next to each row. func (m *Model) fetchModelsCmd(provs []string) tea.Cmd { if len(provs) == 0 || m.cfg == nil { return nil @@ -164,13 +202,17 @@ func (m *Model) fetchModelsCmd(provs []string) tea.Cmd { wg.Add(1) go func(pid string) { defer wg.Done() - ids, err := providers.FetchModels(context.Background(), cfg, pid) + infos, err := providers.FetchModelInfos(context.Background(), cfg, pid) if err != nil { return } mu.Lock() - for _, id := range ids { - refs = append(refs, modelRef{id, pid}) + for _, info := range infos { + window := info.ContextWindow + if window == 0 { + window = providerModelWindow(cfg, pid, info.ID) + } + refs = append(refs, modelRef{id: info.ID, prov: pid, contextWindow: window}) } mu.Unlock() }(pid) diff --git a/internal/tui/tui.go b/internal/tui/tui.go index 54b4493..3101475 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -77,7 +77,8 @@ type Model struct { cancel context.CancelFunc msgCh chan tea.Msg - tokensIn, tokensOut int + tokensIn, tokensOut int + ctxUsed, ctxWindow int showReasoning bool status string themeName string @@ -455,6 +456,12 @@ func (m *Model) applyEvent(e agent.Event) { m.blocks = append(m.blocks, block{kind: blockError, text: e.Err}) case agent.EventUsage: m.tokensIn, m.tokensOut = e.InputTokens, e.OutputTokens + if e.ContextTokens > 0 { + m.ctxUsed = e.ContextTokens + } + if e.ContextWindow > 0 { + m.ctxWindow = e.ContextWindow + } } } diff --git a/internal/tui/view.go b/internal/tui/view.go index 229637d..359c7bc 100644 --- a/internal/tui/view.go +++ b/internal/tui/view.go @@ -128,7 +128,7 @@ func (m *Model) mainColumn() string { if m.sessionID != "" { left += " " + m.st.headerDim.Render(shortID(m.sessionID)) } - right := m.st.headerDim.Render(fmt.Sprintf("%d↑ %d↓", m.tokensIn, m.tokensOut)) + right := m.st.headerDim.Render(m.headerUsage()) gap := w - lipgloss.Width(left) - lipgloss.Width(right) if gap < 1 { gap = 1 @@ -186,6 +186,20 @@ func (m *Model) sidebar() string { } section("Session", truncate(sess, 22)) section("Tokens", fmt.Sprintf("%d in / %d out", m.tokensIn, m.tokensOut)) + // Prefer the live event's window (arrives once a turn runs), fall back + // to the metadata cascade for the active model so a fresh session still + // shows what the model's budget will be. + window := m.ctxWindow + if window == 0 && m.cfg != nil { + window = providerModelWindow(m.cfg, m.cfg.Model.Provider, m.cfg.Model.Default) + } + if window > 0 { + pct := 0 + if m.ctxUsed > 0 { + pct = m.ctxUsed * 100 / window + } + section("Context", fmt.Sprintf("%dK / %dK (%d%%)", m.ctxUsed/1000, window/1000, pct)) + } reason := m.st.stErr.Render("off") if m.showReasoning { @@ -446,3 +460,22 @@ func max(a, b int) int { } return b } + +// headerUsage renders the token counters and — when the model's context +// window is known (from the live usage event or, before any turn, the +// metadata cascade) — a "used/window" ratio next to them. +func (m *Model) headerUsage() string { + base := fmt.Sprintf("%d↑ %d↓", m.tokensIn, m.tokensOut) + window := m.ctxWindow + if window == 0 && m.cfg != nil { + window = providerModelWindow(m.cfg, m.cfg.Model.Provider, m.cfg.Model.Default) + } + if window <= 0 { + return base + } + pct := 0 + if m.ctxUsed > 0 { + pct = m.ctxUsed * 100 / window + } + return fmt.Sprintf("%s · %dK/%dK (%d%%)", base, m.ctxUsed/1000, window/1000, pct) +} diff --git a/scripts/sync-models-dev.go b/scripts/sync-models-dev.go new file mode 100644 index 0000000..aa04b56 --- /dev/null +++ b/scripts/sync-models-dev.go @@ -0,0 +1,351 @@ +// sync-models-dev fetches the models.dev community catalogue and generates +// internal/providers/generated_models.go: a lookup table Antares uses to +// enrich provider /models responses with context windows, pricing, and +// capability flags the provider APIs themselves rarely return. +// +// Run it with `make sync-models` (or `go run scripts/sync-models-dev.go`). +// Output is deterministic — providers and models are emitted in sorted order +// so re-runs against an unchanged upstream produce a zero-diff file. +// +// Source: https://models.dev/api.json — community-curated, provider-agnostic. +// Licence: models.dev is MIT-licensed. The generated file bundles a snapshot; +// re-sync periodically to pick up new models. The manual overrides in +// internal/providers/catalog.go (contextWindows) remain the escape hatch for +// entries where upstream is missing or wrong. +package main + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "sort" + "strings" + "time" +) + +const ( + catalogueURL = "https://models.dev/api.json" + outputPath = "internal/providers/models_generated.json" +) + +// providersOfInterest selects which models.dev provider blocks land in the +// generated file. Adding a new provider to internal/providers/catalog.go is +// worth mirroring here so its models pick up metadata automatically. The set +// is intentionally conservative: it keeps the generated file bounded and +// avoids leaking niche providers that Antares users are unlikely to see. +// +// Values are the provider IDs models.dev uses. Cross-reference the models.dev +// UI or `curl https://models.dev/api.json | jq keys` when adding one. +var providersOfInterest = map[string]bool{ + "anthropic": true, + "openai": true, + "google": true, // Gemini + "openrouter": true, + "groq": true, + "xai": true, + "deepseek": true, + "zai": true, + "opencode": true, // OpenCode Zen + "ollama": true, + "mistral": true, + "cohere": true, + "perplexity": true, + "fireworks-ai": true, + "togetherai": true, + "kimi-for-coding": true, + "minimax": true, + "alibaba": true, // Qwen family + "github-copilot": true, + "nvidia": true, +} + +// apiPayload mirrors the pieces of models.dev/api.json this generator reads. +// Anything not named here is discarded — the catalogue carries a lot of fields +// (benchmarks, marketing copy, temperature ladders) that Antares does not use. +type apiPayload map[string]providerPayload + +type providerPayload struct { + ID string `json:"id"` + Name string `json:"name"` + Models map[string]modelPayload `json:"models"` +} + +type modelPayload struct { + ID string `json:"id"` + Name string `json:"name"` + Family string `json:"family"` + Attachment bool `json:"attachment"` + Reasoning bool `json:"reasoning"` + ToolCall bool `json:"tool_call"` + Knowledge string `json:"knowledge"` + ReleaseDate string `json:"release_date"` + LastUpdated string `json:"last_updated"` + OpenWeights bool `json:"open_weights"` + Modalities modalityBlock `json:"modalities"` + Limit limitBlock `json:"limit"` + Cost costBlock `json:"cost"` +} + +type modalityBlock struct { + Input []string `json:"input"` + Output []string `json:"output"` +} + +type limitBlock struct { + Context int `json:"context"` + Output int `json:"output"` +} + +type costBlock struct { + Input float64 `json:"input"` + Output float64 `json:"output"` + CacheRead float64 `json:"cache_read"` + CacheWrite float64 `json:"cache_write"` +} + +func main() { + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, "sync-models-dev:", err) + os.Exit(1) + } +} + +func run() error { + fmt.Fprintln(os.Stderr, "fetching", catalogueURL) + payload, fetchedAt, err := fetch() + if err != nil { + return err + } + + entries := extract(payload) + fmt.Fprintf(os.Stderr, "collected %d models across %d providers\n", + len(entries), countProviders(entries)) + + blob, err := renderJSON(entries, fetchedAt) + if err != nil { + return err + } + if err := os.WriteFile(outputPath, blob, 0o644); err != nil { + return fmt.Errorf("write %s: %w", outputPath, err) + } + fmt.Fprintln(os.Stderr, "wrote", outputPath) + return nil +} + +func fetch() (apiPayload, time.Time, error) { + client := &http.Client{Timeout: 30 * time.Second} + req, err := http.NewRequest(http.MethodGet, catalogueURL, nil) + if err != nil { + return nil, time.Time{}, err + } + req.Header.Set("User-Agent", "antares-sync-models-dev/1") + resp, err := client.Do(req) + if err != nil { + return nil, time.Time{}, err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, time.Time{}, fmt.Errorf("unexpected status %d from %s", resp.StatusCode, catalogueURL) + } + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, time.Time{}, err + } + var payload apiPayload + if err := json.Unmarshal(body, &payload); err != nil { + return nil, time.Time{}, fmt.Errorf("decode api.json: %w", err) + } + return payload, time.Now().UTC(), nil +} + +// entry is the flattened shape emitted to Go source. Key = "provider/model". +type entry struct { + ProviderID string + ModelID string + Name string + Family string + ContextWindow int + MaxOutput int + CostInput float64 + CostOutput float64 + CostCacheRead float64 + CostCacheWrite float64 + Reasoning bool + ToolCall bool + Attachment bool + Vision bool + PDF bool + OpenWeights bool + Knowledge string + ReleaseDate string +} + +func extract(payload apiPayload) []entry { + var out []entry + for providerID, provider := range payload { + if !providersOfInterest[providerID] { + continue + } + for modelID, m := range provider.Models { + out = append(out, entry{ + ProviderID: providerID, + ModelID: stripProviderPrefix(providerID, modelID), + Name: firstNonEmpty(m.Name, modelID), + Family: m.Family, + ContextWindow: m.Limit.Context, + MaxOutput: m.Limit.Output, + CostInput: m.Cost.Input, + CostOutput: m.Cost.Output, + CostCacheRead: m.Cost.CacheRead, + CostCacheWrite: m.Cost.CacheWrite, + Reasoning: m.Reasoning, + ToolCall: m.ToolCall, + Attachment: m.Attachment, + Vision: hasModality(m.Modalities.Input, "image"), + PDF: hasModality(m.Modalities.Input, "pdf"), + OpenWeights: m.OpenWeights, + Knowledge: m.Knowledge, + ReleaseDate: m.ReleaseDate, + }) + } + } + // Deterministic order — provider first, then model id. + sort.Slice(out, func(i, j int) bool { + if out[i].ProviderID != out[j].ProviderID { + return out[i].ProviderID < out[j].ProviderID + } + return out[i].ModelID < out[j].ModelID + }) + return out +} + +// stripProviderPrefix normalises `openrouter/anthropic/claude-...` etc. down +// to the id a caller looks up. models.dev sometimes prefixes ids with the +// provider (e.g. `subconscious/glm-5.2`); we index on the trailing model id. +func stripProviderPrefix(provider, id string) string { + if p := provider + "/"; strings.HasPrefix(id, p) { + return strings.TrimPrefix(id, p) + } + return id +} + +func countProviders(entries []entry) int { + seen := map[string]bool{} + for _, e := range entries { + seen[e.ProviderID] = true + } + return len(seen) +} + +func hasModality(list []string, want string) bool { + for _, v := range list { + if v == want { + return true + } + } + return false +} + +func firstNonEmpty(vals ...string) string { + for _, v := range vals { + if v != "" { + return v + } + } + return "" +} + +// renderJSON emits a deterministic JSON object keyed by "provider/model-id" +// carrying models.dev's snapshot fields. The Go embed at +// internal/providers/models_generated.go unmarshals this file at init time. +// A JSON asset keeps the review diff small: 300+ KB of metadata as data, +// not as Go source literals git ends up parsing every rebuild. +func renderJSON(entries []entry, fetchedAt time.Time) ([]byte, error) { + // A slice of key+value pairs keeps output order deterministic without + // having to worry about map iteration; the extract step already sorts by + // (provider, model), so the JSON diff between regenerations is minimal. + // The row shape and its tags must match providers.ModelMeta's json tags — + // the runtime consumer unmarshals straight into ModelMeta, so a rename + // here needs a matching rename there or a field silently reads as zero. + type cost struct { + Input float64 `json:"input,omitempty"` + Output float64 `json:"output,omitempty"` + CacheRead float64 `json:"cache_read,omitempty"` + CacheWrite float64 `json:"cache_write,omitempty"` + } + type row struct { + Provider string `json:"provider"` + ID string `json:"id"` + Name string `json:"name,omitempty"` + Family string `json:"family,omitempty"` + ContextWindow int `json:"context_window,omitempty"` + MaxOutput int `json:"max_output,omitempty"` + Cost *cost `json:"cost,omitempty"` + Reasoning bool `json:"reasoning,omitempty"` + ToolCall bool `json:"tool_call,omitempty"` + Attachment bool `json:"attachment,omitempty"` + Vision bool `json:"vision,omitempty"` + PDF bool `json:"pdf,omitempty"` + OpenWeights bool `json:"open_weights,omitempty"` + KnowledgeCutoff string `json:"knowledge_cutoff,omitempty"` + ReleaseDate string `json:"release_date,omitempty"` + } + type envelope struct { + Source string `json:"_source"` + FetchedAt string `json:"_fetched_at"` + Models map[string]row `json:"models"` + } + + models := make(map[string]row, len(entries)) + for _, e := range entries { + key := e.ProviderID + "/" + e.ModelID + name := e.Name + if name == e.ModelID { + name = "" // redundant with the id; omitempty drops it + } + var c *cost + if e.CostInput > 0 || e.CostOutput > 0 || e.CostCacheRead > 0 || e.CostCacheWrite > 0 { + c = &cost{ + Input: e.CostInput, + Output: e.CostOutput, + CacheRead: e.CostCacheRead, + CacheWrite: e.CostCacheWrite, + } + } + models[key] = row{ + Provider: e.ProviderID, + ID: e.ModelID, + Name: name, + Family: e.Family, + ContextWindow: e.ContextWindow, + MaxOutput: e.MaxOutput, + Cost: c, + Reasoning: e.Reasoning, + ToolCall: e.ToolCall, + Attachment: e.Attachment, + Vision: e.Vision, + PDF: e.PDF, + OpenWeights: e.OpenWeights, + KnowledgeCutoff: e.Knowledge, + ReleaseDate: e.ReleaseDate, + } + } + env := envelope{ + Source: catalogueURL, + FetchedAt: fetchedAt.Format(time.RFC3339), + Models: models, + } + // Compact form: this file is a bundled build-time snapshot, not a + // document humans read line-by-line. Compact keeps the repo diff to a + // single line so `make sync-models` runs don't churn thousands of + // lines in every PR. Runtime parse cost is identical either way + // (a few ms for 900+ entries), and reviewers who want to inspect + // individual entries can pipe through `jq`. + blob, err := json.Marshal(env) + if err != nil { + return nil, fmt.Errorf("marshal generated models: %w", err) + } + return append(blob, '\n'), nil +} diff --git a/web/src/components/chat/ModelPicker.tsx b/web/src/components/chat/ModelPicker.tsx index 3bdcc2d..576306e 100644 --- a/web/src/components/chat/ModelPicker.tsx +++ b/web/src/components/chat/ModelPicker.tsx @@ -114,6 +114,10 @@ export function ModelPicker({ d ? { ...d, active: { model: m.id, provider: m.provider } } : d, ); onModelChange?.(`${m.provider}/${m.id}`); + // Nudge subscribers (StatusPill, other poll-driven widgets) to refresh + // instead of waiting for their next polling tick — the model just + // changed and everything derived from it should update at once. + window.dispatchEvent(new CustomEvent('antares:model-changed')); setOpen(false); setQuery(""); } catch (e) { diff --git a/web/src/components/layout/StatusPill.tsx b/web/src/components/layout/StatusPill.tsx index b8171a0..912f613 100644 --- a/web/src/components/layout/StatusPill.tsx +++ b/web/src/components/layout/StatusPill.tsx @@ -1,3 +1,4 @@ +import { useEffect } from 'react' import { CheckCircle, WarningCircle, XCircle } from '@phosphor-icons/react' import { usePoll } from '@/lib/hooks' import { useI18n } from '@/lib/i18n' @@ -18,7 +19,16 @@ export interface StatusResponse { /** Compact backend health indicator shown in the sidebar. */ export function StatusPill({ className }: { className?: string }) { const { t } = useI18n() - const { data, loading, error } = usePoll('/status', 10000) + const { data, loading, error, reload } = usePoll('/status', 10000) + + // Refresh immediately when the model changes — the composer's ModelPicker + // fires 'antares:model-changed' after a successful /model/set, so the + // "Connected · " label updates within a frame instead of waiting + // up to 10 s for the next poll tick. + useEffect(() => { + window.addEventListener('antares:model-changed', reload) + return () => window.removeEventListener('antares:model-changed', reload) + }, [reload]) if (loading && !data) { return diff --git a/web/src/pages/ChatPage.tsx b/web/src/pages/ChatPage.tsx index f415821..b59e11c 100644 --- a/web/src/pages/ChatPage.tsx +++ b/web/src/pages/ChatPage.tsx @@ -209,12 +209,18 @@ export default function ChatPage() { // event or, before any turn, the active model's window fetched on mount. const [ctxUsed, setCtxUsed] = useState(0) const [ctxWindow, setCtxWindow] = useState(0) - // The model's context window, known even before the first turn. + // The model's context window, known even before the first turn. Refetched + // whenever the active model changes so the gauge reflects the new pick + // immediately — no need to wait for the first usage event. useEffect(() => { - get<{ context_window?: number }>('/context-window') - .then((d) => setCtxWindow((w) => w || Number(d.context_window ?? 0))) + const q = activeModel ? `?model=${encodeURIComponent(activeModel)}` : '' + get<{ context_window?: number }>(`/context-window${q}`) + .then((d) => { + const w = Number(d.context_window ?? 0) + if (w > 0) setCtxWindow(w) + }) .catch(() => {}) - }, []) + }, [activeModel]) // display.* prefs from config: whether to show reasoning at all, and the // live-stream character cap (trailing window). Defaults match server defaults. const [showReasoning, setShowReasoning] = useState(true) From 7b3b5d827a00e4b683d296eafee30e703a38873a Mon Sep 17 00:00:00 2001 From: review Date: Tue, 15 Sep 2026 22:07:09 +0700 Subject: [PATCH 2/2] fix(models): preserve complete metadata and resolve capabilities deterministically --- internal/providers/metadata.go | 45 ++++- internal/providers/metadata_tiebreak_test.go | 93 ++++++++++ internal/providers/refresh.go | 74 ++++++-- internal/providers/refresh_test.go | 178 +++++++++++++++++++ internal/server/enrich_vision_test.go | 50 ++++++ internal/server/handlers_config.go | 6 +- scripts/sync-models-dev.go | 97 ++++------ 7 files changed, 464 insertions(+), 79 deletions(-) create mode 100644 internal/providers/metadata_tiebreak_test.go create mode 100644 internal/providers/refresh_test.go create mode 100644 internal/server/enrich_vision_test.go diff --git a/internal/providers/metadata.go b/internal/providers/metadata.go index 7e05769..f06fb31 100644 --- a/internal/providers/metadata.go +++ b/internal/providers/metadata.go @@ -149,6 +149,7 @@ func MetaByAnyProvider(model string) (ModelMeta, bool) { } return lookupBareID(model) } + // lookupBareID scans the generated table for any entry whose bare model id // matches, with slug normalisation. Prefers first-party providers (anthropic, // openai, google) when several proxies re-list the same model so a lookup for @@ -156,19 +157,42 @@ func MetaByAnyProvider(model string) (ModelMeta, bool) { func lookupBareID(model string) (ModelMeta, bool) { variants := append([]string{model}, slugVariants(model)...) var best ModelMeta + var bestKey string + var bestExact bool var found bool - for _, m := range generatedModels() { + for key, m := range generatedModels() { if !containsAny(variants, m.ID) { continue } + exact := m.ID == model m.Source = "generated" if !found { - best = m - found = true + best, bestKey, bestExact, found = m, key, exact, true continue } - if firstPartyRank(m.Provider) < firstPartyRank(best.Provider) { - best = m + // Preference order: exact ID match > first-party provider rank > + // deterministic stored-key tie-break. Exact match wins over a slug + // variant even from a higher-ranked provider — if a caller passed + // "claude-opus-4.7" and one entry has that id verbatim while + // another only matches via the dot/dash flip, the verbatim entry + // is what the caller asked for. + // + // The final key < bestKey tie-break is load-bearing: map iteration + // is randomised, so two same-rank candidates + // (e.g. alibaba/qwen3.5-plus vs opencode/qwen3.5-plus) would flip + // winner run-to-run without it, giving callers phantom pricing + // changes on repeat lookups. + switch { + case exact && !bestExact: + best, bestKey, bestExact = m, key, exact + case exact == bestExact: + rBest, rNew := firstPartyRank(best.Provider), firstPartyRank(m.Provider) + switch { + case rNew < rBest: + best, bestKey, bestExact = m, key, exact + case rNew == rBest && key < bestKey: + best, bestKey, bestExact = m, key, exact + } } } return best, found @@ -202,7 +226,13 @@ func slugVariants(model string) []string { } // firstPartyRank returns a lower number for first-party providers so -// lookupBareID prefers them over re-listings. Unknown providers rank last. +// lookupBareID prefers them over re-listings. Unknown providers rank last; +// ties fall through to a deterministic key-based tie-break in the caller +// so lookups stay stable across map-iteration reshuffles. +// +// alibaba is the first-party home for the Qwen family — treat it as a +// well-known lab so "qwen3.5-plus" resolves to alibaba's numbers rather +// than opencode's re-listing. func firstPartyRank(provider string) int { switch provider { case "anthropic": @@ -211,7 +241,7 @@ func firstPartyRank(provider string) int { return 1 case "google": return 2 - case "xai", "deepseek", "mistral", "cohere", "groq": + case "xai", "deepseek", "mistral", "cohere", "groq", "alibaba": return 3 default: return 4 @@ -253,7 +283,6 @@ type parseErr struct{ msg string } func (e *parseErr) Error() string { return e.msg } - // legacyContextWindow bridges the old package-level contextWindows map. It // exists so metadata.go stays the single lookup surface even while callers // still expect ContextWindow() to work. The map itself lives in catalog.go diff --git a/internal/providers/metadata_tiebreak_test.go b/internal/providers/metadata_tiebreak_test.go new file mode 100644 index 0000000..eeb9060 --- /dev/null +++ b/internal/providers/metadata_tiebreak_test.go @@ -0,0 +1,93 @@ +package providers + +import "testing" + +// TestLookupBareIDStableAcrossRepeatCalls installs a table with two +// same-id entries (alibaba first-party for Qwen, opencode re-listing) and +// asserts every lookup returns alibaba. Guards the deterministic tie-break +// in lookupBareID: without it map iteration order picks the winner and +// callers see phantom pricing swaps between calls. +func TestLookupBareIDStableAcrossRepeatCalls(t *testing.T) { + restore := swapTable(t, map[string]ModelMeta{ + "alibaba/qwen3.5-plus": { + Provider: "alibaba", ID: "qwen3.5-plus", + ContextWindow: 1_000_000, + Cost: Cost{Input: 0.4, Output: 1.2}, + }, + "opencode/qwen3.5-plus": { + Provider: "opencode", ID: "qwen3.5-plus", + ContextWindow: 128_000, + Cost: Cost{Input: 5, Output: 15}, + }, + // Slug variant on a third provider to prove the exact match wins + // even when the slug-variant entry ranks the same. + "openrouter/qwen/qwen3-5-plus": { + Provider: "openrouter", ID: "qwen3-5-plus", + ContextWindow: 64_000, + }, + }) + defer restore() + + for i := 0; i < 32; i++ { + got, ok := Meta("qwen3.5-plus") + if !ok { + t.Fatalf("iter %d: Meta(qwen3.5-plus): expected hit", i) + } + if got.Provider != "alibaba" { + t.Fatalf("iter %d: expected first-party alibaba, got %q (ctx=%d)", + i, got.Provider, got.ContextWindow) + } + if got.ContextWindow != 1_000_000 { + t.Errorf("iter %d: alibaba context window swapped in wrong entry: %d", + i, got.ContextWindow) + } + } +} + +// TestLookupBareIDPrefersExactOverSlug covers the "exact ID beats slug +// variant" branch: an entry whose id matches verbatim wins over one that +// only matches after a dot/dash flip, even when the slug-variant entry +// ranks higher by provider. +func TestLookupBareIDPrefersExactOverSlug(t *testing.T) { + restore := swapTable(t, map[string]ModelMeta{ + // Exact match, mid-tier provider. + "perplexity/claude-opus-4.7": { + Provider: "perplexity", ID: "claude-opus-4.7", + ContextWindow: 200_000, + }, + // Higher-ranked provider but only matches via slug variant + // ("claude-opus-4.7" -> "claude-opus-4-7"). + "anthropic/claude-opus-4-7": { + Provider: "anthropic", ID: "claude-opus-4-7", + ContextWindow: 500_000, + }, + }) + defer restore() + + got, ok := Meta("claude-opus-4.7") + if !ok { + t.Fatalf("Meta(claude-opus-4.7): expected hit") + } + if got.Provider != "perplexity" { + t.Errorf("expected exact-match perplexity to beat slug-variant anthropic, got %q", got.Provider) + } + if got.ContextWindow != 200_000 { + t.Errorf("expected 200_000 from the exact-match entry, got %d", got.ContextWindow) + } +} + +// TestFirstPartyRankAlibaba pins the Qwen-family provider into the +// well-known-lab tier so lookupBareID prefers it over opencode's +// re-listing of the same id. Without this rank change the two entries +// would tie and fall to the key-based tie-break — still stable, but it +// happens to pick alibaba by string ordering. The rank makes the +// preference intentional rather than incidental. +func TestFirstPartyRankAlibaba(t *testing.T) { + if firstPartyRank("alibaba") >= firstPartyRank("opencode") { + t.Errorf("alibaba (%d) should rank ahead of opencode (%d)", + firstPartyRank("alibaba"), firstPartyRank("opencode")) + } + if firstPartyRank("alibaba") != firstPartyRank("mistral") { + t.Errorf("alibaba should sit in the well-known-lab tier alongside mistral et al") + } +} diff --git a/internal/providers/refresh.go b/internal/providers/refresh.go index 9c02542..5df1d93 100644 --- a/internal/providers/refresh.go +++ b/internal/providers/refresh.go @@ -82,7 +82,11 @@ func refreshLoop(ctx context.Context) { // Disk cache first — persisted across restarts, so a warm boot on an // offline laptop still has whatever the last online session pulled. if raw, ok := readDiskCache(); ok { - if table, err := parseGeneratedModels(raw); err == nil { + if table, err := parseGeneratedModels(raw); err == nil && len(table) > 0 { + // Same guard as tryRefresh: a decoded-but-empty cache would + // clobber the bundled snapshot with nothing. Leaves the embed + // in place until either a live fetch lands or a non-empty + // cache appears. setGeneratedModels(table) } } @@ -120,6 +124,14 @@ func tryRefresh(ctx context.Context) { if err != nil { return } + // An empty result (upstream returned {}, or every provider fell outside + // the allowlist) would silently blank the bundled snapshot. Keep the + // prior in-memory table and the on-disk cache — the current data is + // always more useful than none, and a real outage should degrade to the + // last-known-good, not to a lookup miss for every model. + if len(table) == 0 { + return + } setGeneratedModels(table) // Persist the normalised bytes, not the raw upstream, so a warm boot @@ -227,19 +239,57 @@ func normaliseLive(raw []byte) (map[string]ModelMeta, error) { return out, nil } -// providerAllowed mirrors scripts/sync-models-dev.go's providersOfInterest. -// Kept in a small helper here so the two don't drift silently: any provider -// the sync script would bundle, the runtime refresh should also accept. -// The list is small; a slice keeps the diff obvious. +// providerAllowed reports whether the runtime refresh should keep a +// models.dev provider block. Delegates to allowedProviders — the single +// source of truth shared with scripts/sync-models-dev.go so the runtime +// and the build-time snapshot can never disagree about which providers +// exist. func providerAllowed(id string) bool { - switch id { - case "anthropic", "openai", "google", "google-vertex", "azure", - "amazon-bedrock", "openrouter", "opencode", "deepseek", "mistral", - "xai", "cohere", "groq", "fireworks-ai", "together-ai", - "perplexity", "cerebras", "sambanova", "meta-llama": - return true + return allowedProviders[id] +} + +// allowedProviders is the shared allowlist consumed by both the runtime +// refresh loop (refresh.go) and the build-time snapshot generator +// (scripts/sync-models-dev.go). Add a provider here and both paths pick it +// up on the next build/refresh — no drift between the two. +// +// Keys are the provider ids models.dev uses. Cross-reference the +// models.dev UI or `curl https://models.dev/api.json | jq keys` when +// adding one. +var allowedProviders = map[string]bool{ + "anthropic": true, + "openai": true, + "google": true, // Gemini + "openrouter": true, + "groq": true, + "xai": true, + "deepseek": true, + "zai": true, + "opencode": true, // OpenCode Zen + "ollama": true, + "mistral": true, + "cohere": true, + "perplexity": true, + "fireworks-ai": true, + "togetherai": true, + "kimi-for-coding": true, + "minimax": true, + "alibaba": true, // Qwen family + "github-copilot": true, + "nvidia": true, +} + +// AllowedProviders returns a copy of the shared allowlist keyed by +// models.dev provider id. Callers outside this package (notably the +// build-time sync script) use it to guarantee the runtime and the +// bundled snapshot agree on which providers are supported. The copy is +// intentional: nothing external should mutate the runtime table. +func AllowedProviders() map[string]bool { + out := make(map[string]bool, len(allowedProviders)) + for k, v := range allowedProviders { + out[k] = v } - return false + return out } // stripPrefix drops a redundant "provider/" prefix some entries carry diff --git a/internal/providers/refresh_test.go b/internal/providers/refresh_test.go new file mode 100644 index 0000000..f8d1640 --- /dev/null +++ b/internal/providers/refresh_test.go @@ -0,0 +1,178 @@ +package providers + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" +) + +// TestTryRefreshKeepsPriorTableWhenLiveEmpty exercises the empty-result +// guard added to tryRefresh: a successful HTTP fetch that yields no +// supported entries (upstream returned {}, or every provider block sits +// outside allowedProviders) must leave both the in-memory table and the +// disk cache untouched. Without the guard the runtime silently blanks +// the bundled snapshot and every subsequent lookup misses. +func TestTryRefreshKeepsPriorTableWhenLiveEmpty(t *testing.T) { + cacheDir := t.TempDir() + cachePath := filepath.Join(cacheDir, "models.json") + t.Setenv(envCachePath, cachePath) + + // A canary the guard must protect; wraps a well-known provider so the + // snapshot survives the swap. + prior := map[string]ModelMeta{ + "anthropic/claude-sonnet-4-6": { + Provider: "anthropic", + ID: "claude-sonnet-4-6", + ContextWindow: 200_000, + }, + } + restore := swapTable(t, prior) + defer restore() + + // Pre-populate the disk cache so we can prove tryRefresh does not + // overwrite it either. + priorBlob, err := json.Marshal(generatedModelsEnvelope{Models: prior}) + if err != nil { + t.Fatalf("marshal prior: %v", err) + } + if err := os.WriteFile(cachePath, priorBlob, 0o644); err != nil { + t.Fatalf("seed cache: %v", err) + } + + cases := []struct { + name string + body string + }{ + {"empty object", `{}`}, + // Every provider in the payload is outside the allowlist — the + // normalised table is empty even though the fetch "succeeded". + {"only unknown providers", `{"totally-fake-provider":{"models":{"foo":{"id":"foo"}}}}`}, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json") + _, _ = w.Write([]byte(tc.body)) + })) + defer srv.Close() + t.Setenv(envSourceURL, srv.URL) + + tryRefresh(context.Background()) + + // In-memory table survives. + if _, ok := generatedModels()["anthropic/claude-sonnet-4-6"]; !ok { + t.Fatalf("prior table clobbered: canary entry gone") + } + // Disk cache survives. + got, err := os.ReadFile(cachePath) + if err != nil { + t.Fatalf("read cache: %v", err) + } + if string(got) != string(priorBlob) { + t.Errorf("cache overwritten with empty payload: got %s", string(got)) + } + }) + } +} + +// TestAllowedProvidersCoversBundledSnapshot proves the shared allowlist and +// the bundled JSON agree: every provider present in the snapshot is one the +// runtime refresh would also keep, and every allowlisted provider that is +// not purely optional (ollama has no models to catalogue) actually appears. +// Guards against the previous drift where the runtime allowlist silently +// dropped zai/alibaba/kimi-for-coding/… on live refresh. +func TestAllowedProvidersCoversBundledSnapshot(t *testing.T) { + allowed := AllowedProviders() + + // Copy defensively; nothing external should share state with the + // runtime table. + allowed["totally-not-real"] = true + if allowedProviders["totally-not-real"] { + t.Fatalf("AllowedProviders returned a live map — mutation leaked back into the runtime table") + } + allowed = AllowedProviders() + + seen := map[string]bool{} + for key := range generatedModels() { + // key = "provider/id"; take the first path segment. + for i := 0; i < len(key); i++ { + if key[i] == '/' { + seen[key[:i]] = true + break + } + } + } + for provider := range seen { + if !allowed[provider] { + t.Errorf("bundled snapshot ships %q but runtime allowlist would drop it on next refresh", provider) + } + } + // Sanity: the specific providers the drift previously omitted at + // runtime must now be present. + for _, want := range []string{ + "zai", "alibaba", "kimi-for-coding", "minimax", + "github-copilot", "nvidia", "togetherai", + } { + if !allowed[want] { + t.Errorf("shared allowlist missing %q — runtime/generator drift regressed", want) + } + } +} + +// TestNormaliseLiveVisionOnlyModality confirms normaliseLive keeps Vision +// separate from Attachment: an audio-only model must not be marked +// vision-capable just because it lists an input modality. The bug this +// guards let the picker feed image bytes to speech models. +func TestNormaliseLiveVisionOnlyModality(t *testing.T) { + raw := []byte(`{ + "openai": { + "id": "openai", + "name": "OpenAI", + "models": { + "gpt-audio-only": { + "id": "gpt-audio-only", + "modalities": {"input": ["text", "audio"], "output": ["text"]} + }, + "gpt-image": { + "id": "gpt-image", + "modalities": {"input": ["text", "image"], "output": ["text"]} + } + } + } + }`) + table, err := normaliseLive(raw) + if err != nil { + t.Fatalf("normaliseLive: %v", err) + } + audio, ok := table["openai/gpt-audio-only"] + if !ok { + t.Fatalf("expected openai/gpt-audio-only in normalised table") + } + if audio.Vision { + t.Errorf("audio-only model marked Vision=true — modality bleed regressed") + } + if !audio.Attachment { + t.Errorf("audio modality should still count as an attachment surface") + } + image, ok := table["openai/gpt-image"] + if !ok { + t.Fatalf("expected openai/gpt-image in normalised table") + } + if !image.Vision { + t.Errorf("image-input model should be Vision=true") + } +} + +// swapTable installs a controlled generated-models table for the duration +// of a test and returns a restore func the caller defers. Kept local so +// production code has no test-only hooks. +func swapTable(t *testing.T, replacement map[string]ModelMeta) func() { + t.Helper() + prior := generatedModels() + setGeneratedModels(replacement) + return func() { setGeneratedModels(prior) } +} diff --git a/internal/server/enrich_vision_test.go b/internal/server/enrich_vision_test.go new file mode 100644 index 0000000..3e68953 --- /dev/null +++ b/internal/server/enrich_vision_test.go @@ -0,0 +1,50 @@ +package server + +import ( + "testing" + + "github.com/enowdev/antares/internal/llm" + "github.com/enowdev/antares/internal/providers" +) + +// TestEnrichModelInfoVisionOnlyFromMeta covers the Vision-vs-Attachment +// distinction in enrichModelInfo: the picker's Vision flag must reflect +// meta.Vision alone. The previous code folded meta.Attachment into it — +// PDF/audio/video count as attachments in models.dev's schema — so an +// audio-only model was silently marked vision-capable, letting the picker +// feed it image bytes it will refuse. +// +// Uses live bundled snapshot entries rather than injecting synthetic +// metadata so the assertion also validates the modality classification +// upstream at normaliseLive / models_generated.json. +func TestEnrichModelInfoVisionOnlyFromMeta(t *testing.T) { + // Sanity: the bundled snapshot must actually carry the fixtures we + // rely on, otherwise the test degrades to a no-op after the next + // sync-models regeneration. + audioMeta, ok := providers.MetaByProvider("mistral", "voxtral-small-latest") + if !ok { + t.Fatalf("bundled snapshot missing mistral/voxtral-small-latest; refresh fixture") + } + if audioMeta.Vision { + t.Fatalf("fixture voxtral-small-latest has Vision=true — pick a different audio-only model") + } + if !audioMeta.Attachment { + t.Fatalf("fixture voxtral-small-latest has Attachment=false — the test needs the OR-bleed condition") + } + + got := enrichModelInfo("mistral", llm.ModelInfo{ID: "voxtral-small-latest"}, "openai") + if got.Vision { + t.Errorf("Vision leaked from Attachment for an audio-only model — regression in enrichModelInfo") + } + + // Positive control: a model with Vision=true in the snapshot must + // still get Vision=true through the enricher. + visionMeta, ok := providers.MetaByProvider("anthropic", "claude-sonnet-4-6") + if !ok || !visionMeta.Vision { + t.Fatalf("bundled snapshot missing anthropic/claude-sonnet-4-6 vision fixture") + } + visionGot := enrichModelInfo("anthropic", llm.ModelInfo{ID: "claude-sonnet-4-6"}, "anthropic") + if !visionGot.Vision { + t.Errorf("Vision=true meta should still enrich Vision=true; got false") + } +} diff --git a/internal/server/handlers_config.go b/internal/server/handlers_config.go index a723569..59e4c0c 100644 --- a/internal/server/handlers_config.go +++ b/internal/server/handlers_config.go @@ -406,7 +406,11 @@ func enrichModelInfo(providerID string, m llm.ModelInfo, kind string) llm.ModelI if m.OutputCost == 0 && meta.Cost.Output > 0 { m.OutputCost = meta.Cost.Output } - if !m.Vision && (meta.Vision || meta.Attachment) { + // Vision is a strict input-modality claim ("this model reads image + // bytes"). meta.Attachment is broader — it flips on for PDF/audio/video + // too — so folding it into Vision would mark an audio-only model as + // vision-capable and let the picker feed it images it will reject. + if !m.Vision && meta.Vision { m.Vision = true } if !m.Tools && meta.ToolCall { diff --git a/scripts/sync-models-dev.go b/scripts/sync-models-dev.go index aa04b56..4d8bdf3 100644 --- a/scripts/sync-models-dev.go +++ b/scripts/sync-models-dev.go @@ -23,6 +23,8 @@ import ( "sort" "strings" "time" + + "github.com/enowdev/antares/internal/providers" ) const ( @@ -31,35 +33,14 @@ const ( ) // providersOfInterest selects which models.dev provider blocks land in the -// generated file. Adding a new provider to internal/providers/catalog.go is -// worth mirroring here so its models pick up metadata automatically. The set -// is intentionally conservative: it keeps the generated file bounded and -// avoids leaking niche providers that Antares users are unlikely to see. +// generated file. The set is the shared runtime allowlist exported from +// internal/providers — any provider the runtime refresh keeps, the bundled +// snapshot MUST include, or a warm start pulls entries the runtime would +// then discard on the next live refresh. // -// Values are the provider IDs models.dev uses. Cross-reference the models.dev -// UI or `curl https://models.dev/api.json | jq keys` when adding one. -var providersOfInterest = map[string]bool{ - "anthropic": true, - "openai": true, - "google": true, // Gemini - "openrouter": true, - "groq": true, - "xai": true, - "deepseek": true, - "zai": true, - "opencode": true, // OpenCode Zen - "ollama": true, - "mistral": true, - "cohere": true, - "perplexity": true, - "fireworks-ai": true, - "togetherai": true, - "kimi-for-coding": true, - "minimax": true, - "alibaba": true, // Qwen family - "github-copilot": true, - "nvidia": true, -} +// To add a provider: edit allowedProviders in internal/providers/refresh.go. +// Both this generator and the runtime refresh pick it up automatically. +var providersOfInterest = providers.AllowedProviders() // apiPayload mirrors the pieces of models.dev/api.json this generator reads. // Anything not named here is discarded — the catalogue carries a lot of fields @@ -73,19 +54,19 @@ type providerPayload struct { } type modelPayload struct { - ID string `json:"id"` - Name string `json:"name"` - Family string `json:"family"` - Attachment bool `json:"attachment"` - Reasoning bool `json:"reasoning"` - ToolCall bool `json:"tool_call"` - Knowledge string `json:"knowledge"` - ReleaseDate string `json:"release_date"` - LastUpdated string `json:"last_updated"` - OpenWeights bool `json:"open_weights"` - Modalities modalityBlock `json:"modalities"` - Limit limitBlock `json:"limit"` - Cost costBlock `json:"cost"` + ID string `json:"id"` + Name string `json:"name"` + Family string `json:"family"` + Attachment bool `json:"attachment"` + Reasoning bool `json:"reasoning"` + ToolCall bool `json:"tool_call"` + Knowledge string `json:"knowledge"` + ReleaseDate string `json:"release_date"` + LastUpdated string `json:"last_updated"` + OpenWeights bool `json:"open_weights"` + Modalities modalityBlock `json:"modalities"` + Limit limitBlock `json:"limit"` + Cost costBlock `json:"cost"` } type modalityBlock struct { @@ -162,24 +143,24 @@ func fetch() (apiPayload, time.Time, error) { // entry is the flattened shape emitted to Go source. Key = "provider/model". type entry struct { - ProviderID string - ModelID string - Name string - Family string - ContextWindow int - MaxOutput int - CostInput float64 - CostOutput float64 - CostCacheRead float64 + ProviderID string + ModelID string + Name string + Family string + ContextWindow int + MaxOutput int + CostInput float64 + CostOutput float64 + CostCacheRead float64 CostCacheWrite float64 - Reasoning bool - ToolCall bool - Attachment bool - Vision bool - PDF bool - OpenWeights bool - Knowledge string - ReleaseDate string + Reasoning bool + ToolCall bool + Attachment bool + Vision bool + PDF bool + OpenWeights bool + Knowledge string + ReleaseDate string } func extract(payload apiPayload) []entry {