Help us shape the future of Go! Take the 2026 Go Developer Survey

catalog

package
v0.1.1539 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 25, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package catalog knows which models exist. It reads the models.dev catalog (from magpie's own cache or OpenCode's), Codex's model cache, and falls back to a small built-in list so the picker is never empty.

Index

Constants

View Source
const (
	AuthXAPIKey = "x-api-key"
	AuthBearer  = "bearer"
)

Which header a key goes in, for a vendor that takes one of the two alone (provider.Provider.AuthHeader): "" sends both.

View Source
const LeastWindow = 2048

LeastWindow is the smallest context window a list is taken at its word for. Less can't hold an agent's system prompt, let alone a turn, and an agent told it compacts at once or won't send at all (H20 on Discord: hy3 and Cline's free models listed at 512, which Claude Code and Codex took as the model's window). The smallest real chat models' windows are about 4096 (gpt-3.5-turbo-instruct's 4095, mythomax's 4096): those stand.

View Source
const PageLimit = 1000

PageLimit is the page size asked of a list that pages, which Anthropic accepts: a real catalog of its own fits in one or two pages of it.

Variables

View Source
var Changed func()

Changed, when set, is told that the models magpie offers may be others now: a provider added, edited or removed, a vendor's list fetched anew. The agent package sets it, to bring the model lists agents keep in files of their own up to date.

View Source
var EffortRank = []string{"none", "minimal", "low", "medium", "high", "xhigh", "max", "ultra"}

EffortRank orders the reasoning levels agents and vendors name, weakest first.

View Source
var ErrAsked = errors.New("every list of this base was already asked for this key")

ErrAsked is what FetchAtListed says when every list URL of the base was already asked for this key and none of them answered: there is nothing left to ask there, which is not a refusal of the base and is not reported as one to the user. A caller asking several bases of one provider reads it as "this base said nothing new" and moves on.

View Source
var Forget func()

Forget, when set, is told so first: the provider package drops the catalog a request holds (provider.Hold).

View Source
var OneAuthOrder = []string{AuthXAPIKey, AuthBearer}

OneAuthOrder is the order the two headers are tried in alone when a vendor refuses both together: Anthropic's own x-api-key first.

View Source
var PublicCatalogs = map[string]string{
	"aihubmix.com": "https://aihubmix.com/api/v1/models",
}

PublicCatalogs are vendors whose /models, asked with a key, leaves out the image models the key can use: AIHubMix lists only its Gemini image models there, while gpt-image-2 and the rest draw with the same key. Its public catalog, by the host of the vendor's base URL, has them.

Functions

func APIOf added in v0.1.166

func APIOf(providerID, modelID string) string

APIOf is the API a models.dev provider's model is served on, when the catalog says it's one of its own: "responses", "anthropic" or "gemini" for a model OpenCode serves through OpenAI's, Anthropic's or Google's SDK (Gemini's generateContent: Zen's Gemini models, Go's Gemini 4 Argon Contributor, #2168), not the OpenAI-compatible one the rest of its models go through.

func AtEndpoint added in v0.1.1231

func AtEndpoint(base string) []string

AtEndpoint are the models.dev providers whose models are served at base (their "api"), in order: the catalog of a provider the user added by its endpoint alone. A trailing slash and the case of the address don't count.

func BothAuthRefused added in v0.1.1211

func BothAuthRefused(status int, body []byte) bool

BothAuthRefused is a 401 whose body says x-api-key and Authorization can't both be sent (Aloha on Discord: "鉴权 header, x-api-key 和 Authorization 不可以同时存在"), in Chinese or English.

func CachePath

func CachePath() string

CachePath is where `magpie sync` stores the models.dev catalog.

func CodexHome added in v0.1.763

func CodexHome() string

CodexHome is where Codex CLI keeps its state: $CODEX_HOME, else ~/.codex.

func CodexModelsCache added in v0.1.763

func CodexModelsCache() string

CodexModelsCache is the model list Codex CLI keeps, under CodexHome.

func ContextOf added in v0.1.54

func ContextOf(id string) int

ContextOf is the context window models.dev gives a model of this id, as most of the providers it lists serving it do, or 0 when it doesn't know the model. Like SeesImages it reaches a vendor models.dev doesn't list: a proxy serving "openai/gpt-5.4", or "gpt-5.4(high)" with the reasoning level CLIProxyAPI takes in the id, which a static model list would otherwise leave at the agent's default.

A relay's rename of a model it knows (renamed) that names its window ("[1M]", "[200K]", Claude Code's "[1m]") has the window it names: what the relay serves it at, as Claude Code takes claude-opus-5[1m] for 1M.

func DrawsID added in v0.1.338

func DrawsID(id string) bool

DrawsID is whether a model's id names one that makes images, for a model the catalog doesn't know (one typed in, or a vendor's own list's). Banana is the Nano Banana the Gemini image models are called on a relay, whatever its spelling there (#2071).

func Efforts

func Efforts(models []Model, id string) []string

Efforts returns the reasoning levels a model supports, if known.

func EffortsOf added in v0.1.59

func EffortsOf(id string) []string

EffortsOf is the reasoning levels models.dev gives a model of this id, as most of the providers giving any for it do, or nil when none does. Like ContextOf it reaches a vendor models.dev doesn't list: a custom provider serving "glm-5.3-flash" takes the levels Z.ai and the others serving it say it does, where it would otherwise be taken for a model that doesn't reason, and an agent offer no levels for it.

func EndpointAPIs added in v0.1.141

func EndpointAPIs(endpoints []string) []string

EndpointAPIs names the APIs of a model list's supported_endpoints — "chat", "responses", "anthropic" — leaving out any magpie doesn't speak (Copilot's websocket one); nil when it names none of them.

func ImagesAPI added in v0.1.384

func ImagesAPI(id string) bool

ImagesAPI is whether a model draws on an images API rather than answering in chat with pictures: gpt-image, dall-e, imagen, flux, seedream… — not gemini-*-image or gpt-5-image, which chat.

func KeepFresh added in v0.1.426

func KeepFresh()

KeepFresh fetches the catalog whenever it is stale, now and every hour after, for as long as the process runs (the app's backend, `magpie serve`). It never returns.

func KinEfforts added in v0.1.1209

func KinEfforts(providers []string, id string) ([]string, bool)

KinEfforts are the reasoning levels of a model none of the providers named lists, taken from the newest of their thinking models of the same name but for its version (gpt-6.1-sol's from gpt-6-sol, mimo-v2.7-flash's from mimo-v2.6-flash): a model newer than the catalog on this machine offers its line's levels, not none. False when none of them has one.

func Knows added in v0.1.680

func Knows(id string) bool

Knows reports whether models.dev lists a model of this id at all, under any provider, as ContextOf and EffortsOf match it.

func ListedBy added in v0.1.404

func ListedBy(providers []string, id string) ([]string, bool)

ListedBy is the reasoning levels the first of providers (models.dev ids) listing a model of this id gives it — none, for one listed with a thinking switch alone or nothing at all — and whether any of them says. One listed with a thinking budget and no levels says nothing of them (Anthropic's claude-sonnet-4-5, whose budget an effort is sent as). The id is matched as EffortsOf matches it: without a vendor's prefix, in any case. It is how a model's maker is heard before its resellers: Xiaomi lists mimo-v2.6-flash with a switch alone, where gateways reselling it give levels up to max, which Xiaomi turns away (#214).

func ListedByBorrowed added in v0.1.1233

func ListedByBorrowed(providers []string, id string) ([]string, bool)

ListedByBorrowed is ListedBy for levels borrowed from another provider: it uses the levels the catalog lists, without adding a verified provider's toggle-only off level. A provider's API accepting "none" does not verify that a relay, reseller, or another provider does too.

func Lists added in v0.1.1294

func Lists(id string) bool

Lists reports whether models.dev lists a model by this very id (its last part, any case), not one found by another spelling: claude-opus-5.5 only when that is how one of its providers spells it.

func LivePath

func LivePath(provider string) string

LivePath is where the fetched model list of one provider is kept.

func MagpieAdded added in v0.1.486

func MagpieAdded(etag, slug, description string) bool

MagpieAdded reports whether an entry of Codex's models_cache.json is one of magpie's, not Codex's own: the list Codex keeps is the one it was last handed, and handed through the gateway it has magpie's models in it too ("group/semantic", "deepseek/deepseek-v4", "codex/gpt-5.5" — magpie's ids, which Codex's slugs never look like). Read back as Codex's own, they were listed under OpenAI, and kept there after Codex was routed elsewhere.

func Missing added in v0.1.426

func Missing()

Missing says a call's model has no price: the catalog is fetched again, in the background, when it is older than six hours and wasn't tried in that time. Only in a process that keeps it fresh (KeepFresh), so a CLI command or a test never fetches on its own.

func NameOf added in v0.1.1079

func NameOf(id string) string

NameOf is the name models.dev gives a model of this id, as most of the providers it lists serving it do, matched as SeesImages matches it: without a vendor's prefix, in any case. "" when no provider names it other than by its id.

func NearestEffort added in v0.1.1214

func NearestEffort(want string, levels []string) string

NearestEffort is the level of levels nearest want in EffortRank's order, a tie going up, never "none" unless it is want; want itself when levels are none, hold it, or want is no level EffortRank knows. The gateway fits an effort to a model's levels by it on the way out (fitEffort), and Codex's catalog gives a model the effort set for new sessions by it (codexcat.ModelDefault), so the level a model starts at is the one it would be sent at.

func OneAuth added in v0.1.1211

func OneAuth(h http.Header, only string)

OneAuth leaves h with the key in the one header only names: x-api-key alone, or Authorization alone.

func OneHourFor added in v0.1.1043

func OneHourFor(id string, p *Price)

OneHourFor gives a Claude model's price its 1-hour cache write where none is given — models.dev lists none, and a price the user gives may leave it out: 2× input, as Anthropic bills it for every model, wherever the model has a (5-minute) cache write price at all. Any other model's stays unset, its writes all at the 5-minute price: only Anthropic has a 1-hour one (PAMI on Discord: gpt-6-astra was shown a $20 one that isn't).

func OpenRouterPricing added in v0.1.1440

func OpenRouterPricing(pr Price) map[string]string

OpenRouterPricing is a price as OpenRouter's model list writes it (gateway /v1/models' and an agent plugin's connect's "pricing"), the shape agents and SDKs built on that list read: USD a token, as decimal strings. prompt and completion are always there, a price set at 0 included, since the price is known; a cache read or write only when it has a price, as a part a list leaves at 0 is one it doesn't give. The base price only: a model billed more above a prompt size (Tiers) tells what it costs below it, and the 1-hour cache write has no field there.

func OutputOf added in v0.1.100

func OutputOf(id string) int

OutputOf is the most tokens a reply from a model of this id may hold, as most of the providers serving it give it, or 0 when not known.

func Paged added in v0.1.1224

func Paged(list string, page func(at string) (more bool, last string, err error)) error

Paged asks a model list that pages for every page of itself: page asks for one page, at the URL given, and says whether another page follows and the id it starts after. The first page is asked at list as it stands, so a list that does not page is asked exactly as it always was, and each page after it at the same list with limit=PageLimit and after_id set to the id the page before ended at. It stops when a page says none follows.

What does not stop it leaves the list unread, and an unread list is no answer at all, as a page of it was (#904): a page that fails, a list that pages without naming the id to carry on from, one that answers the page just asked again under that same id, and one still paging after modelPages pages. Half a list is not a list — it is missing every model of the pages after, which the caller would take for models the vendor dropped, and would then drop from the user's picks.

A caller that has to ask the list itself, for the headers it takes or the shape it reads, pages it here rather than with a rule of its own (provider.kiloModels).

func PerToken added in v0.1.1440

func PerToken(perMillion float64) string

PerToken is a price of USD a million tokens as USD a token, written as a decimal: the decimal point moved, not the float divided, so $0.3 is "0.0000003" and not 2.9999999999999997e-07.

func PointsToChat added in v0.1.1214

func PointsToChat(text string) bool

PointsToChat is PointsToImagesAPI the other way round: a refusal on the images API that names chat completions as where the model draws.

func PointsToImagesAPI added in v0.1.1214

func PointsToImagesAPI(text string) bool

PointsToImagesAPI is whether a vendor's refusal of a chat request names its images API as the one the model is asked on: Agnes answers agnes-image-2.5-flash on chat completions with 400 "Model agnes-image-2.5-flash is an image model. Use /v1/images/generations" (#1837), a model ImagesAPI can't tell by its name from gemini's -flash image ones, which chat. The vendor's own words decide it then.

func ProviderName added in v0.1.39

func ProviderName(id string) string

ProviderName is a models.dev provider's display name ("GitHub Copilot" for "github-copilot"), or "" when the catalog doesn't know it.

func Providers

func Providers() []string

Providers returns models.dev provider ids known to the catalog.

func PutUserHeader added in v0.1.1160

func PutUserHeader(h http.Header, name, value string)

PutUserHeader writes a request header the user typed (a provider's own headers) onto h. Every header already there under the same name in any case is taken off first: Header.Set keys a name by its canonical form, while the user's goes in as typed (some gateways match names case-sensitively), so a "user-agent" or "authorization" typed in lower case used to ride beside magpie's own — two of the header, magpie's first (#1487, a relay that checks the client turned the request away).

User-Agent itself is kept under its canonical name: Go's HTTP/1 writer looks only there, and adds its own Go-http-client/1.1 when it finds none, ahead of a "user-agent" written in any other case.

func Reset

func Reset()

Reset forgets the loaded catalog so the next call re-reads the cache, and tells Forget: what the provider package built of the old one (the windows and output limits of its entries) is kept between requests for a moment, and would answer for the old catalog meanwhile.

func SaveLive

func SaveLive(provider, base string, models []Model) error

SaveLive stores a fetched list; an empty list forgets it.

func SaveLiveSides added in v0.1.1224

func SaveLiveSides(provider, base string, models []Model, sides map[string][]Model) error

SaveLiveSides is SaveLive, keeping what each endpoint answered with beside the merged list (LiveSplit): a provider whose protocols sit at bases of their own asks every base, and a base that can't be asked next time has to know which of the models were its own to keep (#904).

func SeesImages added in v0.1.44

func SeesImages(id string) bool

SeesImages reports whether models.dev says a model of this id takes images, as most of the providers it lists serving it do; for a vendor it doesn't list, serving a model it knows from others ("z-ai/glm-5.3" is glm-5.3).

func Source

func Source() string

Source reports which catalog file is in use ("" when only built-ins are).

func Stale

func Stale() bool

Stale reports whether no catalog exists or the cache is older than a day (fresh.go).

func Sync

func Sync(ctx context.Context) error

Sync downloads the models.dev catalog into CachePath. It serializes with itself so a background refresh and a manual one cannot interleave writes.

func SyncIfMissing added in v0.1.1240

func SyncIfMissing(ctx context.Context) error

SyncIfMissing is Sync, but returns nil if a catalog already exists once the lock is acquired.

func Thinks added in v0.1.572

func Thinks(id string) bool

Thinks reports whether models.dev says a model of this id reasons, as most of the providers it lists serving it do, whether or not they give it levels; for a vendor it doesn't list, serving a model it knows from others.

func Touched added in v0.1.54

func Touched()

Touched tells Forget and Changed, if set.

func Unsuffixed added in v0.1.1441

func Unsuffixed(id string) (string, bool)

Unsuffixed is id with a proxy's level or speed word taken off (variantSuffix), and whether it had one. It is for borrowing levels a model has no word on alone: the vendor's own list, which may name a model so, goes first.

func Versioned added in v0.1.332

func Versioned(base string) bool

Versioned reports whether an API base URL has a version in its path — a segment like v1, v3, v4 or v1beta — and so names the vendor's API as it is, with no /v1 left out of it.

func Window added in v0.1.1214

func Window(n int) int

Window is n as a model's context window: n, or 0 — not known, for models.dev, a family's window or the agent's default to answer — when n is under LeastWindow.

func WithListAuth added in v0.1.1211

func WithListAuth(ctx context.Context, only string, learned func(string)) context.Context

WithListAuth has a model list asked under ctx send its key in the one header only names ("" both), and, sending both, ask again with each alone when the vendor refuses the two together, telling learned the one it took.

Types

type Listed added in v0.1.1224

type Listed struct {
	// contains filtered or unexported fields
}

Listed is what one fetch of a provider has asked for one key: every list URL it asked at, under the authentication it asked it with, and the models of the ones that answered. A caller asking several bases of one provider passes the same Listed to each of them (FetchAtListed), so no list is fetched twice and no request is made twice.

func NewListed added in v0.1.1224

func NewListed() *Listed

NewListed is an empty record of one fetch's model list requests.

type Model

type Model struct {
	ID          string // e.g. "claude-sonnet-5"
	Name        string // display name
	Provider    string // models.dev provider id
	Released    string // YYYY-MM-DD, used for ordering
	Efforts     []string
	Temperature *bool  // false when the model refuses temperature/top_p
	Price       *Price // USD per million tokens, when models.dev lists it
	// Keys, for a vendor whose keys each see models of their own, are the
	// keys (by fingerprint) whose list has this one; empty is every key.
	Keys []string `json:",omitempty"`
	// APIs, when the vendor says, are the APIs the model is served on
	// ("chat", "responses", "anthropic"); empty is not known.
	APIs []string `json:",omitempty"`
	// Endpoints, in magpie's own models for an agent, are the gateway
	// paths a request for it is relayed on as it is
	// (provider.NativeEndpoints, /v1/models' native_endpoints); none for a
	// group or a model translated anyway.
	Endpoints []string `json:"-"`
	// Images is set on a model that takes images as input.
	Images bool `json:",omitempty"`
	// ImageInput is the source's explicit answer; nil means it did not say.
	ImageInput *bool `json:",omitempty"`
	// InputModalities and OutputModalities are what the model takes and
	// gives (text, image, audio, video, pdf) as its source listed them;
	// nil is not said. Images (and the user's override of it) still
	// decides "image" (provider.Entry.Modalities).
	InputModalities  []string `json:",omitempty"`
	OutputModalities []string `json:",omitempty"`
	// Context is how many tokens a prompt may hold, when known: models.dev's
	// input limit, else its context window.
	Context int `json:",omitempty"`
	// MaxContext is the most a prompt may hold when asked for, above
	// Context: Codex's max_context_window (872k on GPT-6, 272k by default).
	MaxContext int `json:",omitempty"`
	// Output is the most tokens a reply may hold, when known.
	Output int `json:",omitempty"`
	// OutputSet is set when Output is a Max output the user typed for the
	// model or its provider (provider.Entry.OutputSet): an agent that trims
	// a vendor's figure for its own reasons hands this one on as it is.
	OutputSet bool `json:"-"`
	// Compact is where the user has Codex compact a conversation on this
	// model (#876), its own or its provider's (settings.ModelCompacts), or
	// Context itself when that is a window the user typed (#1809,
	// provider.CompactFor): the window it is told when Context is longer.
	// 0 is none set, for the one for every model (settings.Compact).
	Compact int `json:",omitempty"`
	// Plain, on a model of another magpie's list, is its name there alone
	// (display_name), when Name is its label there, with that magpie's
	// provider after it (magpie_label): the name Provider in model names
	// Off has here (ARNO on Discord).
	Plain string `json:",omitempty"`
	// Fast is set on a model Codex may ask for priority processing (its
	// Fast mode): one a ChatGPT account serves.
	Fast bool `json:",omitempty"`
	// Tiers, in one ChatGPT account's own model list, are the service
	// tiers its plan offers on the model ("priority", "ultrafast"); in
	// another magpie's, the tiers it offers its Codex on the model
	// (#1234); in a provider plugin's, the tiers it says its vendor serves
	// the model at (#2514).
	Tiers []string `json:",omitempty"`
	// OwnTier is set on a model of a provider the user added by its
	// address, which the gateway sends the tier Codex asks for as it is
	// (gateway Request.Tier): Codex offers it the tiers of its own entry
	// for the same model, Fast on another GPT model.
	OwnTier bool `json:",omitempty"`
	// CodexFast is set on a GPT model a ChatGPT account serves itself, not
	// through a routing group: one Codex's /fast (service_tier "priority")
	// is asked of, which OpenCode is offered as fast variants (#2379).
	// Not kept with a list: it is the provider's, worked out each time.
	CodexFast bool `json:"-"`
	// AgentsV2 is set on a model Codex is told multi-agent V2 for, so its
	// Ultra hands work to Codex's agents: one offering Ultra that no
	// ChatGPT account answers for (provider.Entry's).
	AgentsV2 bool `json:",omitempty"`
	// Draws is set on a vendor-listed model that makes images (gpt-image-1,
	// a relay's flux): kept with the list for Settings → Images, never
	// offered to agents as a model to talk to.
	Draws bool `json:",omitempty"`
	// Films is set on a model another magpie lists as one it makes videos
	// with (a Remote magpie's Grok Imagine Video): kept with the list for
	// its videos API, never offered as a model to talk to or draw with.
	Films bool `json:",omitempty"`
	// Decides marks a decision model another magpie explicitly lists,
	// including models whose ids don't name Jev.
	Decides bool `json:",omitempty"`
	// Free is set on a model a subscription serves at no cost to its
	// allowance: WorkBuddy's "credits": "x0.00".
	Free bool `json:",omitempty"`
	// Rate is what a request costs of a subscription's credits, as a
	// multiple, when its vendor lists it: Qoder's price_factor (0.5),
	// WorkBuddy's "credits": "x0.03". 0 is not listed, or Free.
	Rate float64 `json:",omitempty"`
	// RateWas is the rate before a discount running now, when the vendor
	// says it: Qoder's Qwen3.8-Flash at 0× with 0.1× struck through.
	RateWas float64 `json:",omitempty"`
	// Reasoning is set on a model that thinks, whether or not it takes
	// levels: mimo-v2.6-flash thinks with a switch alone (#402).
	Reasoning bool `json:",omitempty"`
	// WebSearch is how another magpie (a Remote magpie) searches the web
	// for the model when a web search tool is offered: "native", its own
	// provider by itself, or "magpie", with that magpie's searcher; "" it
	// doesn't, or didn't say. A plugin's model it says searches by itself
	// (m.searches) is "native" too.
	WebSearch string `json:",omitempty"`
}

Model is one entry the picker can offer.

func Chat added in v0.1.340

func Chat(ms []Model) []Model

Chat is ms without the models that draw or make videos.

func Codex

func Codex() []Model

Codex returns the models Codex itself lists, straight from the cache the Codex CLI writes; there is no compiled-in list to fall back to.

func Decorate

func Decorate(live []Model, known []Model) []Model

Decorate fills in names and reasoning levels for live models from the catalog's entry for the same id, keeping the live order.

func Drawers added in v0.1.338

func Drawers(id string) []Model

Drawers are the models of one models.dev provider that make images, newest first.

func Fetch

func Fetch(ctx context.Context, base, key string, anthropic bool, headers map[string]string) ([]Model, error)

Fetch asks an endpoint for its models. base is an API base URL of any flavour (…/v1, …/anthropic, …/api); the usual list paths are tried around it. The result keeps the server's order. anthropic sends the Anthropic version header, which the official API requires but which a dual-protocol relay like OpenRouter reads as a request for its Anthropic-flavoured catalog — namespaced, differently named ids.

func FetchAt added in v0.1.65

func FetchAt(ctx context.Context, base, key string, anthropic bool, headers map[string]string) ([]Model, string, error)

FetchAt is Fetch, and says which URL answered. An OpenAI-style base with a version in its path (…/v1, …/api/plan/v3, …/api/paas/v4, …/v1beta/openai) names the vendor's API as it is and is asked only as written, at base/models: a /v1 is looked for only around a base without one (a bare host, a relay's …/api), where it may have been left out. An Anthropic base is the root /v1/messages is asked at, so /v1/models under it is its own list. When no URL answers, the error names each one asked and what it said.

func FetchAtListed added in v0.1.1224

func FetchAtListed(ctx context.Context, base, key string, anthropic bool, headers map[string]string, listed *Listed) ([]Model, string, error)

FetchAtListed is FetchAt over a provider's several bases, and over what one of them has already asked. listed is the record of this key's requests so far (NewListed), and the key of a request is the list URL it is made at and the authentication it is made with — Bearer, or the Anthropic version header with it.

Two rules follow, and both are what make a multi-protocol vendor's models findable without asking its list twice (#1006). A list URL this key has already listed is not asked again, by any protocol: the answer is the answer, so a …/v1 base and the bare host beside it that speaks Anthropic are one /v1/models, fetched once. And a request already made is not made again — but a URL refused under one authentication is not refused under the next, so the Gemini list of a base whose Chat request was answered 401 is asked, with x-goog-api-key, instead of being taken for a list already had.

func FetchGemini added in v0.1.1125

func FetchGemini(ctx context.Context, base, key string, headers map[string]string) ([]Model, string, error)

FetchGemini lists the models at a Gemini API's base (…/v1beta), as Google's Gemini API lists them: GET models, the key in x-goog-api-key, a page at a time (nextPageToken), each named models/{id} with the methods it serves. Only those that serve generateContent are kept: the list also has embedding models (embedContent), Imagen's (predict) and Veo's (predictLongRunning), which no agent can talk to (#1346). It answers the URL it asked first.

func FetchURL added in v0.1.85

func FetchURL(ctx context.Context, url, key string, anthropic bool, headers map[string]string) ([]Model, error)

FetchURL asks for the model list at exactly url.

func Live

func Live(provider string) (models []Model, fetched time.Time, ok bool)

Live returns the model list last fetched from the provider, if any: the models to talk to, without the ones that draw (LiveDrawers).

func LiveAll added in v0.1.1218

func LiveAll(provider string) (models []Model, ok bool)

LiveAll is the whole model list last fetched from the provider, the models that draw or make videos among them, with each one's keys: what tells which of the provider's keys serves an image model (#1657), which Live, the models to talk to, leaves out.

func LiveByID added in v0.1.1269

func LiveByID(provider, model string) []Model

LiveByID are the models of Live with this id, in the list's order (a list may name one twice): what a look through Live finds, without the list copied for each model asked about.

func LiveDrawers added in v0.1.340

func LiveDrawers(provider string) []Model

LiveDrawers are the models in the provider's fetched list that make images, in the list's order.

func LiveSplit added in v0.1.1224

func LiveSplit(provider string) (sides map[string][]Model, all []Model, ok bool)

LiveSplit returns the provider's fetched list as every endpoint's own part of it: sides[base] is what that endpoint listed, and all is the whole list those parts were merged into. ok is false where there is no list at all; sides is nil for a list saved without its parts, where every endpoint answered alike.

func LiveVideomakers added in v0.1.651

func LiveVideomakers(provider string) []Model

LiveVideomakers are the models in the provider's fetched list that make videos, in the list's order.

func Named added in v0.1.1079

func Named(ms []Model, reserved ...Model) []Model

Named gives a model the list names by its id alone the name models.dev knows it by (NameOf), so one model reads the same under every provider: a GLM Coding Plan's glm-5-turbo, which Zhipu's catalog doesn't list, is GLM-5-Turbo as ZCode's is. Its id, and where requests go, stay as they are. A supplemented name shared by different ids falls back to the id. Already named models in reserved count toward collisions but stay as given.

func Provider

func Provider(id string) []Model

Provider returns the text models of one models.dev provider, newest first. The list comes from the synced models.dev catalog; nothing is compiled in. A vendor's own /models answer, once fetched, is layered over it by the provider package (see provider.Provider.Available).

func PublicDrawers added in v0.1.345

func PublicDrawers(ctx context.Context, base string) []Model

PublicDrawers are the image models the public catalog for base's host lists, marked as drawing; nil when there is none or it can't be read.

func WithDrawers added in v0.1.345

func WithDrawers(ms, drawers []Model) []Model

WithDrawers adds the drawers not already in ms.

type Price

type Price struct {
	Input      float64 `json:"input"`
	Output     float64 `json:"output"`
	CacheRead  float64 `json:"cache_read"`
	CacheWrite float64 `json:"cache_write"`
	// CacheWrite1h is what a cache write kept for an hour costs, Anthropic's
	// 1-hour TTL, which it bills at 2× input where a 5-minute write (the
	// CacheWrite above) is 1.25×. 0 is not given: such a write is then
	// counted at the 5-minute price, as no other vendor has an hour's
	// writes to bill apart; a Claude model's is 2× input (OneHourFor).
	CacheWrite1h float64 `json:"cache_write_1h,omitempty"`
	// Tiers are the prices a request is billed at, whole, once its input
	// goes over a size (OpenAI's gpt-6-astra: 2× input and cache, 1.5×
	// output above 272K), lowest first. models.dev lists them as "tiers" of
	// type "context".
	Tiers []Tier `json:"tiers,omitempty"`
}

Price is what a model costs, in USD per million tokens.

func PriceOf

func PriceOf(providerID, modelID string) (Price, bool)

PriceOf is the list price of a models.dev provider's model, if known.

func PricedBy added in v0.1.411

func PricedBy(providers []string, id string) (Price, bool)

PricedBy is the list price the first of providers (models.dev ids) pricing a model of this id gives it: by its own key first, then by its id without a path or case ("openai/GPT-6-Sol" is gpt-6-sol), a Bedrock profile's geography, a "(variant)" or a ":tag"; then with a dot taken for a dash, then as the model an entry names as its canonical_model_id (DeepSeek's deepseek-flash is deepseek-v4.1-flash).

func (Price) At added in v0.1.1032

func (p Price) At(prompt int) Price

At is the flat price a request whose input, cached and cache-written tokens included, comes to prompt tokens is billed at: that of the highest tier it is over, else the base price. OpenAI counts a request's input with its cached tokens in it, and bills the whole request at the tier.

func (Price) Cost

func (p Price) Cost(input, output, cacheRead, cacheWrite int) float64

Cost of a call at this price, every cache write a 5-minute one. Reasoning tokens are billed as output by every vendor, and are already inside the output count.

func (Price) CostSplit added in v0.1.1032

func (p Price) CostSplit(input, output, cacheRead, cacheWrite, cacheWrite1h int) float64

CostSplit is Cost where cacheWrite1h of the cacheWrite tokens were written for an hour, billed at that price, and the rest for 5 minutes. The whole call is billed at the tier its input reaches.

func (Price) OneHour added in v0.1.1032

func (p Price) OneHour() float64

OneHour is what a 1-hour cache write costs at this flat price: the price given, else the 5-minute one (a Claude model's is given, OneHourFor).

func (Price) Same added in v0.1.1032

func (p Price) Same(q Price) bool

Same is whether two prices are the same in every part and tier.

func (Price) Times added in v0.1.901

func (p Price) Times(r float64) Price

Times is the price at r times each of its parts.

func (*Price) UnmarshalJSON added in v0.1.1032

func (p *Price) UnmarshalJSON(b []byte) error

UnmarshalJSON reads a price as magpie writes it, and as models.dev does, whose tiers name their size as {"tier": {"type": "context", "size": N}} and may leave a part out, which is then the base price's. A tier of another type, or of no size, is left out.

type Tier added in v0.1.1032

type Tier struct {
	Above        int     `json:"above"`
	Input        float64 `json:"input"`
	Output       float64 `json:"output"`
	CacheRead    float64 `json:"cache_read"`
	CacheWrite   float64 `json:"cache_write"`
	CacheWrite1h float64 `json:"cache_write_1h,omitempty"`
}

Tier is a price from a request's input size on: what the whole request costs once its input, cached and cache-written tokens included, is over Above tokens.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL