Skip to content

Model Catalog

Alex Clarke edited this page Sep 21, 2026 · 3 revisions

Model Catalog

Coyote ships with a built-in catalog of models for every supported provider: context window sizes, output limits, pricing (including prompt-cache read/write rates (cache_read_price / cache_write_price) where the sources publish them), capabilities (vision, function calling, reasoning), wire-name aliases, and per-model request patches. The catalog is what powers the .model tab-completion table in the REPL, --list-models, token-budget accounting, and cost display.

This page explains where that data comes from, how it stays fresh automatically, and how to control it.

How the catalog works

The catalog has three layers, from most static to most fresh:

  1. Embedded generated floor: A full models.yaml is generated from live API data (models.dev + OpenRouter) and embedded into the Coyote binary at compile time. A scheduled GitHub workflow regenerates it twice a day and commits the result, so every release carries a recent snapshot. This layer always exists and is the fallback for everything else. Coyote never has no catalog.

  2. Local override (<config-dir>/models-override.yaml): A synced copy of the catalog written by --sync-models or by the automatic background refresh. When present and valid, it takes precedence over the embedded floor. The override is version-pinned to the Coyote version that wrote it; an override written by a different version is ignored (see Troubleshooting).

  3. TTL auto-refresh: On REPL startup, if the override is missing, unreadable, or older than sync_models_ttl_hours, Coyote fires a fire-and-forget background sync (when sync_models_auto is enabled). The running session keeps the catalog it already loaded; the next start picks up the refreshed file. Providers that yield no live data keep their embedded entries, so a partial upstream outage never shrinks your catalog.

Models you define inline in your config.yaml client blocks always win over all of the above, and unknown client:model names still work. They're created on the fly with family-level quirks applied (so a brand-new claude:claude-* model inherits the right request behavior on day zero).

By default, inline client models replace the catalog list for that client; set extend_models: true on the client entry to merge them on top of the catalog instead; see Extending vs. replacing the catalog. Never hand-edit models-override.yaml to add models: it's a machine-owned cache and every sync rewrites it wholesale.

Configuration

Three keys in config.yaml control syncing:

sync_models_url: null      # null = fetch fresh data from models.dev + OpenRouter (API mode)
                           # URL  = mirror a complete models.yaml from that URL (mirror mode)
sync_models_auto: true     # refresh the catalog in the background on REPL startup once stale
sync_models_ttl_hours: 24  # hours before the synced catalog is considered stale

API mode vs. mirror mode

  • API mode (sync_models_url: null, the default): --sync-models and the auto-refresh rebuild the catalog from live models.dev + OpenRouter data, applying the same hand-curated quirks the generator uses. You get new models as soon as the upstream catalogs list them.

  • Mirror mode (sync_models_url: <URL>): Fetches a complete, ready-made models.yaml from the URL instead of talking to the APIs. Useful for air-gapped or policy-restricted environments, or to pin your whole team to one blessed catalog. For example, to mirror the latest generated catalog from the Coyote repo:

    sync_models_url: https://raw.githubusercontent.com/Dark-Alex-17/coyote/refs/heads/main/models.yaml

CLI commands

  • coyote --sync-models: refresh the catalog now (API or mirror mode per sync_models_url) and write models-override.yaml.
  • coyote --list-models: print every chat model available with your configured clients.
  • coyote --generate-models [PATH]: regenerate a complete models.yaml from live API data (defaults to ./models.yaml). This is the maintainer-facing generator the scheduled workflow runs; it hard-fails unless both upstream sources respond, so a generated file is never built from partial data.

quirks.yaml: The hand-owned overlay

Not everything about a model is machine-discoverable. quirks.yaml (repo root, embedded at compile time) layers hand-curated knowledge on top of the API-sourced data, per provider:

  • oauth: provider OAuth configuration (client IDs, scopes).
  • exclude: glob patterns for API-listed models Coyote should drop (e.g. image-only models).
  • rules: field overlays applied to every API-sourced model whose name matches a glob (* = any run of characters, ? = exactly one): request patches, real_name wire aliases, default_reasoning_effort, require_max_tokens, no_stream, system_prompt_prefix, and friends. Only fields explicitly present in the rule are written.
  • variants: clones of matching models with a suffix appended and fields overlaid (e.g. :thinking variants).
  • models: fully hand-owned model entries for providers (or individual models) that no public catalog describes. rules never apply to them, so write them self-complete, though if a hand-owned entry shares its name with an API-sourced model, the two merge field-wise (the hand-owned field always wins; absent fields inherit the fetched values).

When the generator or a sync runs, quirks are applied on top of the fetched data, so curated behavior survives every refresh.

Capability glyphs

Model listings (.model tab-completion, --list-models) show per-model capability glyphs:

Glyph Meaning
👁 Supports vision (image input)
⚒ Supports function calling (tools)
🧠 Supports configurable reasoning effort

Sandboxes

Coyote's sandbox kit allowlists models.dev and openrouter.ai, so API-mode syncing works out of the box inside a Docker Sandbox; no extra network policy needed.

Troubleshooting

  • Stale or corrupt override: The catalog self-heals. If models-override.yaml fails to parse (or fails its version check), Coyote silently falls back to the embedded catalog, and the next REPL startup treats the override as stale and rewrites it in the background. You can always force a rewrite with coyote --sync-models, or just delete the file.

  • Upgraded Coyote and the catalog "reset"?: That's the version pin: an override written by an older Coyote is ignored by a newer one, so you're on the (fresh) embedded catalog shipped with the new binary until the first background refresh rewrites the override, usually within one REPL start. No action needed.

  • No new models appearing: Check sync_models_auto isn't false, and remember the running session keeps its loaded catalog: restart the REPL after a sync completes. In mirror mode, you only ever get what the mirror serves.

Start Here

Using Coyote

Model Providers

Tools & Function Calling

Agents

Knowledge & Automation

Configuration

Clone this wiki locally