modelsdev

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 10, 2026 License: MPL-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package modelsdev is a reusable client for models.dev, the community database of model specifications, pricing, and capabilities. It fetches the static catalog.json, merges the per-provider and provider-agnostic maps into a single enriched view, validates against gross schema drift, and caches with stale-on-failure semantics. The package is a leaf: it imports no agentdex internal package, so external consumers can depend on it directly.

Index

Constants

View Source
const DefaultHTTPTimeout = 30 * time.Second

DefaultHTTPTimeout bounds a single catalog fetch end to end. The shared single-flight fetch detaches from any one caller's cancellation, so without an overall timeout a stalled endpoint would wedge the Client permanently. WithHTTPClient overrides it.

View Source
const DefaultTTL = 24 * time.Hour

DefaultTTL is how long a cached catalog.json is served before a refetch is attempted. On a failed refetch the stale copy is still served.

View Source
const DefaultURL = "https://models.dev/catalog.json"

DefaultURL is the published models.dev catalog fetched unless overridden.

Variables

View Source
var ErrModelsSchema = errors.New("models.dev schema unrecognised")

ErrModelsSchema signals that models.dev data does not match the expected shape: empty top-level maps (gross drift, every fetch) or a requested provider with a malformed model (per-model, in Provider and Models). models.dev is unversioned community JSON, so validation is the only drift signal; this error makes drift loud rather than silent blanks. Model-resolution failures are the consuming layer's concern, not this package's.

Functions

func Newer

func Newer(a, b Model) bool

Newer reports whether a sorts before b in a newest-first listing: later release date first (ISO dates compare lexically), undated last, ties broken by id. Shared presentation order; Client.Models remains sorted by id.

func SortByRelease

func SortByRelease(models []Model)

SortByRelease orders models newest release first, in place, via Newer.

Types

type Benchmark

type Benchmark struct {
	Name    string  `json:"name"`
	Score   float64 `json:"score"`
	Metric  string  `json:"metric"`
	Source  string  `json:"source"`
	Harness string  `json:"harness"`
	Dataset string  `json:"dataset"`
	Version string  `json:"version"`
	Date    string  `json:"date"`
	Variant string  `json:"variant"`
}

Benchmark is a published benchmark result for a model. Upstream it lives only in the provider-agnostic map and is merged onto the matching provider model.

type Catalog

type Catalog struct {
	Models    map[string]Model    `json:"models"`    // provider-agnostic, keyed by path-style model id
	Providers map[string]Provider `json:"providers"` // keyed by provider id
}

Catalog is the merged result of fetching models.dev catalog.json: the provider-agnostic model map plus the per-provider map, mirroring the upstream { models, providers } shape. Distinct from agentdex's index of known coding agents.

type Client

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

Client fetches, caches, merges, and serves the models.dev catalog. Fetch, decode, and merge happen once per Client; the merged catalog is memoised in memory. A long-lived Client never re-merges — refresh needs a new Client. Methods are safe for concurrent use.

func New

func New(opts ...ClientOption) *Client

New constructs a Client with built-in defaults: the published catalog URL, the cache directory under $XDG_CACHE_HOME, a 24h TTL, and a package-owned HTTP client. Options override any of these.

func (*Client) Catalog

func (c *Client) Catalog(ctx context.Context) (*Catalog, error)

Catalog returns the merged catalog. The first call fetches, caches, and merges; later calls return the memoised copy. The returned pointer is shared and must be treated as read-only.

func (*Client) Models

func (c *Client) Models(ctx context.Context, providerIDs ...string) ([]Model, error)

Models returns the merged models of the named providers, sorted by id. The per-model check is applied only to those providers; a malformed model raises ErrModelsSchema. Unknown provider ids are skipped. Returned models alias the memoised catalog and must be treated as read-only.

func (*Client) Provider

func (c *Client) Provider(ctx context.Context, id string) (Provider, bool, error)

Provider returns one provider by id, whether it was found, and any error. found reports existence only and is independent of the error. A provider that exists but carries a malformed model returns found true with ErrModelsSchema, so branching on found alone cannot swallow schema drift as absence. The per-model check is applied to that provider only. The returned Provider shares the memoised catalog and must be treated as read-only.

func (*Client) Stale

func (c *Client) Stale() bool

Stale reports whether the memoised catalog was served from the stale-fallback path: a network fetch failed and a previously cached copy was re-decoded. Meaningful only after a successful load; before any load, and after a failed load with no cache, it returns false. Within-TTL hit and fresh fetch both report false.

type ClientOption

type ClientOption func(*Client)

ClientOption configures a Client.

func WithCacheDir

func WithCacheDir(dir string) ClientOption

WithCacheDir overrides the stale-cache directory.

func WithForceRefresh

func WithForceRefresh() ClientOption

WithForceRefresh makes the next load fetch fresh bytes, ignore the cache TTL, and report fetch/decode failure rather than fall back to stale cache. Honest mode for explicit refresh: the caller learns whether fresh data was fetched. A successful fetch still updates the on-disk cache.

func WithHTTPClient

func WithHTTPClient(hc *http.Client) ClientOption

WithHTTPClient overrides the package-owned HTTP client, replacing the default timeout backstop. A consumer that supplies a client without a timeout takes on responsibility for bounding the fetch through the request context.

func WithTTL

func WithTTL(ttl time.Duration) ClientOption

WithTTL overrides the cache TTL.

func WithURL

func WithURL(url string) ClientOption

WithURL overrides the catalog URL (mirror or frozen snapshot).

type Cost

type Cost struct {
	Input           float64 `json:"input"`
	Output          float64 `json:"output"`
	Reasoning       float64 `json:"reasoning"`
	CacheRead       float64 `json:"cache_read"`
	CacheWrite      float64 `json:"cache_write"`
	InputAudio      float64 `json:"input_audio"`
	OutputAudio     float64 `json:"output_audio"`
	ContextOver200K *Cost   `json:"context_over_200k"` // nil when flat
	Tiers           []Tier  `json:"tiers"`             // nil when flat
}

Cost is per-token pricing in USD per 1,000,000 tokens.

type Limit

type Limit struct {
	Context int `json:"context"`
	Input   int `json:"input"`
	Output  int `json:"output"`
}

Limit holds a model's token limits. An absent upstream limit decodes to the zero value, legitimate for media-generation models that carry no token limit.

type Modalities

type Modalities struct {
	Input  []string `json:"input"`
	Output []string `json:"output"`
}

Modalities lists the input and output media a model accepts and produces, each element one of text|audio|image|video|pdf.

type Model

type Model 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"`
	StructuredOutput bool        `json:"structured_output"`
	Temperature      bool        `json:"temperature"`
	Knowledge        string      `json:"knowledge"` // YYYY-MM or YYYY-MM-DD
	ReleaseDate      string      `json:"release_date"`
	LastUpdated      string      `json:"last_updated"`
	Modalities       Modalities  `json:"modalities"`
	OpenWeights      bool        `json:"open_weights"`
	Limit            Limit       `json:"limit"`
	Cost             *Cost       `json:"cost"`   // USD per 1,000,000 tokens; nil if unknown
	Status           string      `json:"status"` // alpha|beta|deprecated
	Benchmarks       []Benchmark `json:"benchmarks"`
	Weights          []Weight    `json:"weights"`
}

Model is one model entry. The same type serves both maps: in Catalog.Models its ID is the path-style provider-agnostic id; within a Provider.Models it is the short id local to that provider. ID is never normalised across the two.

type Provider

type Provider struct {
	ID     string           `json:"id"`
	Name   string           `json:"name"`
	Doc    string           `json:"doc"`
	NPM    string           `json:"npm"`
	API    string           `json:"api"`
	Env    []string         `json:"env"` // API-key env var names
	Models map[string]Model `json:"models"`
}

Provider is one models.dev provider and the models it offers.

type Tier

type Tier struct {
	Input      float64       `json:"input"`
	Output     float64       `json:"output"`
	CacheRead  float64       `json:"cache_read"`
	CacheWrite float64       `json:"cache_write"`
	Tier       TierDimension `json:"tier"`
}

Tier is one entry in a model's tiered pricing: a per-token cost subset plus the dimension and threshold at which it applies. Upstream nests the dimension under a "tier" object.

type TierDimension

type TierDimension struct {
	Type string `json:"type"` // e.g. "context"
	Size int    `json:"size"` // threshold, e.g. 200000
}

TierDimension is the nested "tier" object on each tiered-pricing entry.

type Weight

type Weight struct {
	Label string `json:"label"`
	URL   string `json:"url"`
}

Weight is a link to a model's published weights. Like Benchmark it lives only in the provider-agnostic map and is merged onto the matching provider model.

Jump to

Keyboard shortcuts

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