{"owner":"anomalyco","repo":"models.dev","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Agent Guidelines for models.dev\n\nCatalog-only. This file is how to add and maintain **models** and **providers**. Nothing else.\n\n## Validate\n\n```bash\nbun validate\n```\n\nRun this after every catalog change. It must pass before a PR is mergeable.\n\n## Two concepts: lab models vs providers\n\n| | Lab model metadata | Provider model |\n| --- | --- | --- |\n| **What** | Provider-agnostic facts about a model the lab built | How a specific API host serves that model |\n| **Where** | `models/<lab-id>/<model-id>.toml` | `providers/<provider-id>/models/.../<id>.toml` |\n| **Examples** | `models/anthropic/claude-opus-4-6.toml`, `models/openai/gpt-5.4.toml` | `providers/openrouter/models/anthropic/claude-opus-4.6.toml` |\n| **Contains** | name, description, capabilities, modalities, limits, weights, … | `cost`, `reasoning_options`, `status`, request shape, and **only real overrides** |\n\n- **Labs** create models (Anthropic, OpenAI, Google, DeepSeek, Alibaba, …).\n- **Providers** host or relay them (the lab’s own API, OpenRouter, Bedrock, a random OpenAI-compatible gateway, …).\n\nFilename (minus `.toml`) is the model `id`. **Never** put an `id` field in the TOML. Schema is strict — unknown keys fail validation.\n\n## When to use `base_model` (blocker)\n\n**If the provider did not create the model, the provider entry must use `base_model`.**\n\n1. Identify the underlying lab model.\n2. If `models/<lab>/<model>.toml` is missing, **add it** under the lab that made the model, then point `base_model` at it.\n3. Provider file stays override-only (see below).\n\n```toml\nbase_model = \"anthropic/claude-opus-4-6\"\n\n[cost]\ninput = 5.00\noutput = 25.00\n```\n\n### Exceptions (full inline definition allowed)\n\nUse a full standalone provider model TOML only when:\n\n- The provider **is** the lab (first-party host of its own model), **or**\n- The model is **unique to that host** — private beta alias, custom/fine-tune, or something with no sensible shared lab identity elsewhere.\n\nIf you can name the lab model, it belongs in `models/` and the host uses `base_model`. Do not skip creating `models/` just because the file did not exist yet.\n\n### Override-only provider files\n\nAfter `base_model = \"…\"`, write **only** provider-specific fields or values that **differ** from the base. Never restate identical data.\n\n**Do not copy from base when unchanged:** `name`, `description`, `family`, `release_date`, `knowledge`, `open_weights`, `attachment`, `reasoning`, `tool_call`, `temperature`, `structured_output`, matching `[modalities]` / `[limit]`, etc.\n\n**Usually provider-authored:** `cost`, `reasoning_options`, `interleaved`, `status`, `provider`, `experimental`, plus real deltas (smaller context, PDF-only input, different display `name`).\n\nOptional:\n\n```toml\nbase_model_omit = [\"limit.input\"]  # drop inherited keys after merge\n```\n\n### Merge behavior\n\n- Plain objects (`[limit]`, `[modalities]`, …) → deep-merge\n- Arrays and primitives → child replaces parent\n- Omitted fields → inherited from `models/`\n- `base_model` / `base_model_omit` are parse-time only — they do not appear in generated JSON\n- Missing `base_model` target → validation error\n\n## Adding a provider\n\n```\nproviders/<provider-id>/\n  provider.toml\n  logo.svg                 # required\n  models/.../*.toml\n```\n\n### `provider.toml`\n\n```toml\nname = \"Example\"\nnpm = \"@ai-sdk/openai-compatible\"   # or the native AI SDK package\nenv = [\"EXAMPLE_API_KEY\"]\napi = \"https://api.example.com/v1\" # required for openai-compatible\ndoc = \"https://example.com/docs\"\n```\n\n### Logo (blocker for new providers)\n\n- Path: `providers/<provider-id>/logo.svg`\n- Use `currentColor` for fills/strokes — no hardcoded colors, no fixed width/height\n- Prefer square `viewBox` (e.g. `0 0 24 24`)\n\n```svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n  <!-- paths -->\n</svg>\n```\n\n### Sync modules (recommended, not a blocker)\n\nIf the provider has a rich catalog API that can populate model data or authoritatively remove models it no longer serves, add a sync module (see `sync.md`). Thin endpoints stay hand-authored.\n\n## Model fields\n\n### Required on lab metadata (`models/`)\n\n| Field | Notes |\n| --- | --- |\n| `name`, `description` | Schema-required |\n| `release_date`, `last_updated` | **Required on new lab entries** (hosts inherit these) |\n| `attachment`, `reasoning`, `tool_call`, `open_weights` | **Required on new lab entries** |\n| `limit`, `modalities` | **Required on new lab entries** — providers must resolve `limit.context` + `limit.output` |\n\nWhen you create `models/<lab>/<model>.toml` so a third-party host can `base_model` it, author a **complete** lab file (all rows above). Do not ship name/description-only lab stubs and expect an “override-only” host of just `cost` + `reasoning_options` to validate — missing inherited required fields fail `bun validate`.\n\n### Required on resolved provider models\n\nAfter `base_model` merge (or full inline), the provider model must have:\n\n| Field | Notes |\n| --- | --- |\n| `name`, `description` | From base or local |\n| `attachment`, `reasoning`, `tool_call`, `open_weights` | Booleans |\n| `release_date`, `last_updated` | Dates |\n| `modalities`, `limit` | `limit.context` + `limit.output` required on providers |\n| `cost` | Provider-side (unless intentionally request-only / no public price) |\n| `reasoning_options` | **Required when `reasoning = true`** |\n\nWith `base_model`, do not restate fields already correct on the lab entry. Still author `cost` and (if reasoning) `reasoning_options` on the provider file.\n\n### Strongly recommended on lab metadata\n\n| Field | Notes |\n| --- | --- |\n| `family` | Model family slug — set when known |\n| `knowledge` | Knowledge cutoff (`YYYY-MM` or `YYYY-MM-DD`) |\n| `temperature` | Whether temperature is respected |\n| `structured_output` | Whether structured/JSON output is supported |\n| `license`, `links`, `weights`, `benchmarks` | Enrichment |\n\n### Provider-only (never put these under `models/`)\n\n| Field | Notes |\n| --- | --- |\n| `cost`, `reasoning_options` | Host pricing and API controls |\n| `interleaved` | Reasoning side channel on **this** API (`reasoning_content` / `reasoning_details`, or `true`) |\n| `status` | Lifecycle on **this** host: `alpha` / `beta` / `deprecated` |\n| `provider`, `experimental` | Request-shape overrides / experimental modes |\n\n### Cost (always USD)\n\n- **All `cost` values are USD per million tokens.** Never publish EUR, CNY, CHF, etc. as if they were USD.\n- Convert other currencies and note rate/date in a **top-of-file** comment.\n- Optional keys on cost: `reasoning`, `cache_read`, `cache_write`, `input_audio`, `output_audio`.\n- **Context-based pricing → `[[cost.tiers]]`**, not `context_over_200k`.\n\n```toml\n[cost]\ninput = 2.50\noutput = 15.00\n\n[[cost.tiers]]\ntier = { type = \"context\", size = 200_000 }\ninput = 5.00\noutput = 22.50\n```\n\n- `cost.context_over_200k` is **legacy output-only**. Do **not** author it in TOML (schema rejects it on write). The generator may emit it for old consumers when a single 200k-style tier exists; **always author tiers**.\n- Tier `size` is the context threshold where that band starts. No duplicate sizes.\n\n### Comments in TOML\n\nSync re-serializes many provider files and **drops every comment except a leading header block**. Put sources/rationale **above the first key**. Short comments next to a reasoning option for exact API syntax are fine when the file is not sync-owned.\n\n## Reasoning options\n\nAny provider model with `reasoning = true` **must** set `reasoning_options` for **this host’s** API. Details: `.opencode/skills/audit-reasoning-options/SKILL.md`.\n\n### 1. Classify the host (not the npm package)\n\n| Host kind | Who | How to pick options |\n| --- | --- | --- |\n| **First-party lab** | Provider **is** the lab (OpenAI, Anthropic, DeepSeek, Alibaba, Google, …) | Match that lab’s real API and existing `providers/<lab>/` entries for the same generation. |\n| **Multi-model relay / gateway** | Hosts many labs’ models (OpenRouter, Bedrock-as-relay, random OpenAI-compat aggregators, …) | Copy the **underlying model’s** controls from the lab entry + established same-surface peers. |\n\n**`npm = \"@ai-sdk/openai-compatible\"` does not mean “gateway.”** DeepSeek and Alibaba are first-party labs that use that package with **lab-specific** fields (`thinking.type`, `enable_thinking`, `thinking_budget`, …). Classify by **who runs the API**, not by the AI SDK package name.\n\n### 2. Baseline effort = native / peer set (not a fixed enum)\n\nDo **not** invent a universal `low`/`medium`/`high` for every reasoner.\n\n1. Open `providers/<lab>/models/…` for the underlying model (and 1–2 solid peers on the same kind of host).\n2. Author **that** effort list (and toggle/budget if those entries have them and this host exposes the same kind of control).\n3. Common cases:\n   - GPT-style on relays → often `low` / `medium` / `high` (add `none` / `xhigh` only if native/peers have them)\n   - DeepSeek V4 → `toggle` + `high` / `max` (not L/M/H; lab maps low/medium→high)\n   - Always-on / no control → `[]`\n4. On relays: **do not** use `[]` just because you could not re-test this host. Empty means **no caller control**, not uncertainty.\n5. Never invent `budget_tokens` unless this host (or the lab API it clearly proxies) has a real **reasoning** budget field. Not `max_tokens`.\n\n### 3. Toggle\n\nSame model ID, on and off, via a known request field. Separate `-thinking` / instruct IDs are not a toggle.\n\n| Host control | Author |\n| --- | --- |\n| Effort includes `none` **and** other graded levels | **Only** `effort` with `none` in `values` — **no** `toggle` |\n| Separate on/off control **and** graded effort (no `none` in effort) | `toggle` **+** `effort` with the **actual** levels |\n| Binary on/off only | `toggle` alone |\n\nEvery `toggle` needs a **leading top-of-file comment** with the exact wire path (sync strips mid-file comments).\n\n```toml\n# Toggle: thinking.type = enabled|disabled\n# Effort: reasoning_effort = high|max\nname = \"DeepSeek V4 Pro\"\nreasoning_options = [\n  { type = \"toggle\" },\n  { type = \"effort\", values = [\"high\", \"max\"] },\n]\n```\n\n```toml\n# Toggle: enable_thinking true|false\n# Budget: thinking_budget (integer reasoning tokens)\nname = \"Qwen3.5 Plus\"\nreasoning_options = [\n  { type = \"toggle\" },\n  { type = \"budget_tokens\" },\n]\n```\n\n```toml\n# Off is effort=none; graded levels — no toggle\nbase_model = \"openai/gpt-5.4\"\nreasoning_options = [{ type = \"effort\", values = [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"] }]\n```\n\n## Platform naming quirks\n\n### Bedrock\n\n- Dated: `-v1:0` suffix (`anthropic.claude-3-5-sonnet-20241022-v1:0.toml`)\n- Latest/undated: bare `-v1` (`anthropic.claude-opus-4-6-v1.toml`)\n- Region prefixes: `us.`, `eu.`, `global.` (default has no prefix)\n\n### Vertex AI\n\n- Dated: `@YYYYMMDD` (`claude-opus-4-5@20251101.toml`)\n- Latest/undated: `@default` (`claude-opus-4-6@default.toml`)\n\n## Review checklist\n\n### Blockers\n\n- [ ] New provider has compliant `logo.svg`\n- [ ] Non-lab hosts use `base_model`; missing lab metadata was **added** under `models/` when needed (complete lab file, not a stub)\n- [ ] Provider `base_model` files are override-only (no duplicated identical fields; no provider-only keys under `models/`)\n- [ ] `reasoning = true` ⇒ `reasoning_options` set per policy above\n- [ ] Costs are USD/MTok\n- [ ] `bun validate` passes\n\n### Strongly recommended\n\n- [ ] PR body cites pricing/docs/API for data changes\n- [ ] Sync module if the provider catalog is rich enough (`sync.md`)\n- [ ] Leading TOML comment for sources on hand-authored files\n"},"files":{"AGENTS.md":"# Agent Guidelines for models.dev\n\nCatalog-only. This file is how to add and maintain **models** and **providers**. Nothing else.\n\n## Validate\n\n```bash\nbun validate\n```\n\nRun this after every catalog change. It must pass before a PR is mergeable.\n\n## Two concepts: lab models vs providers\n\n| | Lab model metadata | Provider model |\n| --- | --- | --- |\n| **What** | Provider-agnostic facts about a model the lab built | How a specific API host serves that model |\n| **Where** | `models/<lab-id>/<model-id>.toml` | `providers/<provider-id>/models/.../<id>.toml` |\n| **Examples** | `models/anthropic/claude-opus-4-6.toml`, `models/openai/gpt-5.4.toml` | `providers/openrouter/models/anthropic/claude-opus-4.6.toml` |\n| **Contains** | name, description, capabilities, modalities, limits, weights, … | `cost`, `reasoning_options`, `status`, request shape, and **only real overrides** |\n\n- **Labs** create models (Anthropic, OpenAI, Google, DeepSeek, Alibaba, …).\n- **Providers** host or relay them (the lab’s own API, OpenRouter, Bedrock, a random OpenAI-compatible gateway, …).\n\nFilename (minus `.toml`) is the model `id`. **Never** put an `id` field in the TOML. Schema is strict — unknown keys fail validation.\n\n## When to use `base_model` (blocker)\n\n**If the provider did not create the model, the provider entry must use `base_model`.**\n\n1. Identify the underlying lab model.\n2. If `models/<lab>/<model>.toml` is missing, **add it** under the lab that made the model, then point `base_model` at it.\n3. Provider file stays override-only (see below).\n\n```toml\nbase_model = \"anthropic/claude-opus-4-6\"\n\n[cost]\ninput = 5.00\noutput = 25.00\n```\n\n### Exceptions (full inline definition allowed)\n\nUse a full standalone provider model TOML only when:\n\n- The provider **is** the lab (first-party host of its own model), **or**\n- The model is **unique to that host** — private beta alias, custom/fine-tune, or something with no sensible shared lab identity elsewhere.\n\nIf you can name the lab model, it belongs in `models/` and the host uses `base_model`. Do not skip creating `models/` just because the file did not exist yet.\n\n### Override-only provider files\n\nAfter `base_model = \"…\"`, write **only** provider-specific fields or values that **differ** from the base. Never restate identical data.\n\n**Do not copy from base when unchanged:** `name`, `description`, `family`, `release_date`, `knowledge`, `open_weights`, `attachment`, `reasoning`, `tool_call`, `temperature`, `structured_output`, matching `[modalities]` / `[limit]`, etc.\n\n**Usually provider-authored:** `cost`, `reasoning_options`, `interleaved`, `status`, `provider`, `experimental`, plus real deltas (smaller context, PDF-only input, different display `name`).\n\nOptional:\n\n```toml\nbase_model_omit = [\"limit.input\"]  # drop inherited keys after merge\n```\n\n### Merge behavior\n\n- Plain objects (`[limit]`, `[modalities]`, …) → deep-merge\n- Arrays and primitives → child replaces parent\n- Omitted fields → inherited from `models/`\n- `base_model` / `base_model_omit` are parse-time only — they do not appear in generated JSON\n- Missing `base_model` target → validation error\n\n## Adding a provider\n\n```\nproviders/<provider-id>/\n  provider.toml\n  logo.svg                 # required\n  models/.../*.toml\n```\n\n### `provider.toml`\n\n```toml\nname = \"Example\"\nnpm = \"@ai-sdk/openai-compatible\"   # or the native AI SDK package\nenv = [\"EXAMPLE_API_KEY\"]\napi = \"https://api.example.com/v1\" # required for openai-compatible\ndoc = \"https://example.com/docs\"\n```\n\n### Logo (blocker for new providers)\n\n- Path: `providers/<provider-id>/logo.svg`\n- Use `currentColor` for fills/strokes — no hardcoded colors, no fixed width/height\n- Prefer square `viewBox` (e.g. `0 0 24 24`)\n\n```svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n  <!-- paths -->\n</svg>\n```\n\n### Sync modules (recommended, not a blocker)\n\nIf the provider has a rich catalog API that can populate model data or authoritatively remove models it no longer serves, add a sync module (see `sync.md`). Thin endpoints stay hand-authored.\n\n## Model fields\n\n### Required on lab metadata (`models/`)\n\n| Field | Notes |\n| --- | --- |\n| `name`, `description` | Schema-required |\n| `release_date`, `last_updated` | **Required on new lab entries** (hosts inherit these) |\n| `attachment`, `reasoning`, `tool_call`, `open_weights` | **Required on new lab entries** |\n| `limit`, `modalities` | **Required on new lab entries** — providers must resolve `limit.context` + `limit.output` |\n\nWhen you create `models/<lab>/<model>.toml` so a third-party host can `base_model` it, author a **complete** lab file (all rows above). Do not ship name/description-only lab stubs and expect an “override-only” host of just `cost` + `reasoning_options` to validate — missing inherited required fields fail `bun validate`.\n\n### Required on resolved provider models\n\nAfter `base_model` merge (or full inline), the provider model must have:\n\n| Field | Notes |\n| --- | --- |\n| `name`, `description` | From base or local |\n| `attachment`, `reasoning`, `tool_call`, `open_weights` | Booleans |\n| `release_date`, `last_updated` | Dates |\n| `modalities`, `limit` | `limit.context` + `limit.output` required on providers |\n| `cost` | Provider-side (unless intentionally request-only / no public price) |\n| `reasoning_options` | **Required when `reasoning = true`** |\n\nWith `base_model`, do not restate fields already correct on the lab entry. Still author `cost` and (if reasoning) `reasoning_options` on the provider file.\n\n### Strongly recommended on lab metadata\n\n| Field | Notes |\n| --- | --- |\n| `family` | Model family slug — set when known |\n| `knowledge` | Knowledge cutoff (`YYYY-MM` or `YYYY-MM-DD`) |\n| `temperature` | Whether temperature is respected |\n| `structured_output` | Whether structured/JSON output is supported |\n| `license`, `links`, `weights`, `benchmarks` | Enrichment |\n\n### Provider-only (never put these under `models/`)\n\n| Field | Notes |\n| --- | --- |\n| `cost`, `reasoning_options` | Host pricing and API controls |\n| `interleaved` | Reasoning side channel on **this** API (`reasoning_content` / `reasoning_details`, or `true`) |\n| `status` | Lifecycle on **this** host: `alpha` / `beta` / `deprecated` |\n| `provider`, `experimental` | Request-shape overrides / experimental modes |\n\n### Cost (always USD)\n\n- **All `cost` values are USD per million tokens.** Never publish EUR, CNY, CHF, etc. as if they were USD.\n- Convert other currencies and note rate/date in a **top-of-file** comment.\n- Optional keys on cost: `reasoning`, `cache_read`, `cache_write`, `input_audio`, `output_audio`.\n- **Context-based pricing → `[[cost.tiers]]`**, not `context_over_200k`.\n\n```toml\n[cost]\ninput = 2.50\noutput = 15.00\n\n[[cost.tiers]]\ntier = { type = \"context\", size = 200_000 }\ninput = 5.00\noutput = 22.50\n```\n\n- `cost.context_over_200k` is **legacy output-only**. Do **not** author it in TOML (schema rejects it on write). The generator may emit it for old consumers when a single 200k-style tier exists; **always author tiers**.\n- Tier `size` is the context threshold where that band starts. No duplicate sizes.\n\n### Comments in TOML\n\nSync re-serializes many provider files and **drops every comment except a leading header block**. Put sources/rationale **above the first key**. Short comments next to a reasoning option for exact API syntax are fine when the file is not sync-owned.\n\n## Reasoning options\n\nAny provider model with `reasoning = true` **must** set `reasoning_options` for **this host’s** API. Details: `.opencode/skills/audit-reasoning-options/SKILL.md`.\n\n### 1. Classify the host (not the npm package)\n\n| Host kind | Who | How to pick options |\n| --- | --- | --- |\n| **First-party lab** | Provider **is** the lab (OpenAI, Anthropic, DeepSeek, Alibaba, Google, …) | Match that lab’s real API and existing `providers/<lab>/` entries for the same generation. |\n| **Multi-model relay / gateway** | Hosts many labs’ models (OpenRouter, Bedrock-as-relay, random OpenAI-compat aggregators, …) | Copy the **underlying model’s** controls from the lab entry + established same-surface peers. |\n\n**`npm = \"@ai-sdk/openai-compatible\"` does not mean “gateway.”** DeepSeek and Alibaba are first-party labs that use that package with **lab-specific** fields (`thinking.type`, `enable_thinking`, `thinking_budget`, …). Classify by **who runs the API**, not by the AI SDK package name.\n\n### 2. Baseline effort = native / peer set (not a fixed enum)\n\nDo **not** invent a universal `low`/`medium`/`high` for every reasoner.\n\n1. Open `providers/<lab>/models/…` for the underlying model (and 1–2 solid peers on the same kind of host).\n2. Author **that** effort list (and toggle/budget if those entries have them and this host exposes the same kind of control).\n3. Common cases:\n   - GPT-style on relays → often `low` / `medium` / `high` (add `none` / `xhigh` only if native/peers have them)\n   - DeepSeek V4 → `toggle` + `high` / `max` (not L/M/H; lab maps low/medium→high)\n   - Always-on / no control → `[]`\n4. On relays: **do not** use `[]` just because you could not re-test this host. Empty means **no caller control**, not uncertainty.\n5. Never invent `budget_tokens` unless this host (or the lab API it clearly proxies) has a real **reasoning** budget field. Not `max_tokens`.\n\n### 3. Toggle\n\nSame model ID, on and off, via a known request field. Separate `-thinking` / instruct IDs are not a toggle.\n\n| Host control | Author |\n| --- | --- |\n| Effort includes `none` **and** other graded levels | **Only** `effort` with `none` in `values` — **no** `toggle` |\n| Separate on/off control **and** graded effort (no `none` in effort) | `toggle` **+** `effort` with the **actual** levels |\n| Binary on/off only | `toggle` alone |\n\nEvery `toggle` needs a **leading top-of-file comment** with the exact wire path (sync strips mid-file comments).\n\n```toml\n# Toggle: thinking.type = enabled|disabled\n# Effort: reasoning_effort = high|max\nname = \"DeepSeek V4 Pro\"\nreasoning_options = [\n  { type = \"toggle\" },\n  { type = \"effort\", values = [\"high\", \"max\"] },\n]\n```\n\n```toml\n# Toggle: enable_thinking true|false\n# Budget: thinking_budget (integer reasoning tokens)\nname = \"Qwen3.5 Plus\"\nreasoning_options = [\n  { type = \"toggle\" },\n  { type = \"budget_tokens\" },\n]\n```\n\n```toml\n# Off is effort=none; graded levels — no toggle\nbase_model = \"openai/gpt-5.4\"\nreasoning_options = [{ type = \"effort\", values = [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"] }]\n```\n\n## Platform naming quirks\n\n### Bedrock\n\n- Dated: `-v1:0` suffix (`anthropic.claude-3-5-sonnet-20241022-v1:0.toml`)\n- Latest/undated: bare `-v1` (`anthropic.claude-opus-4-6-v1.toml`)\n- Region prefixes: `us.`, `eu.`, `global.` (default has no prefix)\n\n### Vertex AI\n\n- Dated: `@YYYYMMDD` (`claude-opus-4-5@20251101.toml`)\n- Latest/undated: `@default` (`claude-opus-4-6@default.toml`)\n\n## Review checklist\n\n### Blockers\n\n- [ ] New provider has compliant `logo.svg`\n- [ ] Non-lab hosts use `base_model`; missing lab metadata was **added** under `models/` when needed (complete lab file, not a stub)\n- [ ] Provider `base_model` files are override-only (no duplicated identical fields; no provider-only keys under `models/`)\n- [ ] `reasoning = true` ⇒ `reasoning_options` set per policy above\n- [ ] Costs are USD/MTok\n- [ ] `bun validate` passes\n\n### Strongly recommended\n\n- [ ] PR body cites pricing/docs/API for data changes\n- [ ] Sync module if the provider catalog is rich enough (`sync.md`)\n- [ ] Leading TOML comment for sources on hand-authored files\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Agent Guidelines for models.dev\n\nCatalog-only. This file is how to add and maintain **models** and **providers**. Nothing else.\n\n## Validate\n\n```bash\nbun validate\n```\n\nRun this after every catalog change. It must pass before a PR is mergeable.\n\n## Two concepts: lab models vs providers\n\n| | Lab model metadata | Provider model |\n| --- | --- | --- |\n| **What** | Provider-agnostic facts about a model the lab built | How a specific API host serves that model |\n| **Where** | `models/<lab-id>/<model-id>.toml` | `providers/<provider-id>/models/.../<id>.toml` |\n| **Examples** | `models/anthropic/claude-opus-4-6.toml`, `models/openai/gpt-5.4.toml` | `providers/openrouter/models/anthropic/claude-opus-4.6.toml` |\n| **Contains** | name, description, capabilities, modalities, limits, weights, … | `cost`, `reasoning_options`, `status`, request shape, and **only real overrides** |\n\n- **Labs** create models (Anthropic, OpenAI, Google, DeepSeek, Alibaba, …).\n- **Providers** host or relay them (the lab’s own API, OpenRouter, Bedrock, a random OpenAI-compatible gateway, …).\n\nFilename (minus `.toml`) is the model `id`. **Never** put an `id` field in the TOML. Schema is strict — unknown keys fail validation.\n\n## When to use `base_model` (blocker)\n\n**If the provider did not create the model, the provider entry must use `base_model`.**\n\n1. Identify the underlying lab model.\n2. If `models/<lab>/<model>.toml` is missing, **add it** under the lab that made the model, then point `base_model` at it.\n3. Provider file stays override-only (see below).\n\n```toml\nbase_model = \"anthropic/claude-opus-4-6\"\n\n[cost]\ninput = 5.00\noutput = 25.00\n```\n\n### Exceptions (full inline definition allowed)\n\nUse a full standalone provider model TOML only when:\n\n- The provider **is** the lab (first-party host of its own model), **or**\n- The model is **unique to that host** — private beta alias, custom/fine-tune, or something with no sensible shared lab identity elsewhere.\n\nIf you can name the lab model, it belongs in `models/` and the host uses `base_model`. Do not skip creating `models/` just because the file did not exist yet.\n\n### Override-only provider files\n\nAfter `base_model = \"…\"`, write **only** provider-specific fields or values that **differ** from the base. Never restate identical data.\n\n**Do not copy from base when unchanged:** `name`, `description`, `family`, `release_date`, `knowledge`, `open_weights`, `attachment`, `reasoning`, `tool_call`, `temperature`, `structured_output`, matching `[modalities]` / `[limit]`, etc.\n\n**Usually provider-authored:** `cost`, `reasoning_options`, `interleaved`, `status`, `provider`, `experimental`, plus real deltas (smaller context, PDF-only input, different display `name`).\n\nOptional:\n\n```toml\nbase_model_omit = [\"limit.input\"]  # drop inherited keys after merge\n```\n\n### Merge behavior\n\n- Plain objects (`[limit]`, `[modalities]`, …) → deep-merge\n- Arrays and primitives → child replaces parent\n- Omitted fields → inherited from `models/`\n- `base_model` / `base_model_omit` are parse-time only — they do not appear in generated JSON\n- Missing `base_model` target → validation error\n\n## Adding a provider\n\n```\nproviders/<provider-id>/\n  provider.toml\n  logo.svg                 # required\n  models/.../*.toml\n```\n\n### `provider.toml`\n\n```toml\nname = \"Example\"\nnpm = \"@ai-sdk/openai-compatible\"   # or the native AI SDK package\nenv = [\"EXAMPLE_API_KEY\"]\napi = \"https://api.example.com/v1\" # required for openai-compatible\ndoc = \"https://example.com/docs\"\n```\n\n### Logo (blocker for new providers)\n\n- Path: `providers/<provider-id>/logo.svg`\n- Use `currentColor` for fills/strokes — no hardcoded colors, no fixed width/height\n- Prefer square `viewBox` (e.g. `0 0 24 24`)\n\n```svg\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n  <!-- paths -->\n</svg>\n```\n\n### Sync modules (recommended, not a blocker)\n\nIf the provider has a rich catalog API that can populate model data or authoritatively remove models it no longer serves, add a sync module (see `sync.md`). Thin endpoints stay hand-authored.\n\n## Model fields\n\n### Required on lab metadata (`models/`)\n\n| Field | Notes |\n| --- | --- |\n| `name`, `description` | Schema-required |\n| `release_date`, `last_updated` | **Required on new lab entries** (hosts inherit these) |\n| `attachment`, `reasoning`, `tool_call`, `open_weights` | **Required on new lab entries** |\n| `limit`, `modalities` | **Required on new lab entries** — providers must resolve `limit.context` + `limit.output` |\n\nWhen you create `models/<lab>/<model>.toml` so a third-party host can `base_model` it, author a **complete** lab file (all rows above). Do not ship name/description-only lab stubs and expect an “override-only” host of just `cost` + `reasoning_options` to validate — missing inherited required fields fail `bun validate`.\n\n### Required on resolved provider models\n\nAfter `base_model` merge (or full inline), the provider model must have:\n\n| Field | Notes |\n| --- | --- |\n| `name`, `description` | From base or local |\n| `attachment`, `reasoning`, `tool_call`, `open_weights` | Booleans |\n| `release_date`, `last_updated` | Dates |\n| `modalities`, `limit` | `limit.context` + `limit.output` required on providers |\n| `cost` | Provider-side (unless intentionally request-only / no public price) |\n| `reasoning_options` | **Required when `reasoning = true`** |\n\nWith `base_model`, do not restate fields already correct on the lab entry. Still author `cost` and (if reasoning) `reasoning_options` on the provider file.\n\n### Strongly recommended on lab metadata\n\n| Field | Notes |\n| --- | --- |\n| `family` | Model family slug — set when known |\n| `knowledge` | Knowledge cutoff (`YYYY-MM` or `YYYY-MM-DD`) |\n| `temperature` | Whether temperature is respected |\n| `structured_output` | Whether structured/JSON output is supported |\n| `license`, `links`, `weights`, `benchmarks` | Enrichment |\n\n### Provider-only (never put these under `models/`)\n\n| Field | Notes |\n| --- | --- |\n| `cost`, `reasoning_options` | Host pricing and API controls |\n| `interleaved` | Reasoning side channel on **this** API (`reasoning_content` / `reasoning_details`, or `true`) |\n| `status` | Lifecycle on **this** host: `alpha` / `beta` / `deprecated` |\n| `provider`, `experimental` | Request-shape overrides / experimental modes |\n\n### Cost (always USD)\n\n- **All `cost` values are USD per million tokens.** Never publish EUR, CNY, CHF, etc. as if they were USD.\n- Convert other currencies and note rate/date in a **top-of-file** comment.\n- Optional keys on cost: `reasoning`, `cache_read`, `cache_write`, `input_audio`, `output_audio`.\n- **Context-based pricing → `[[cost.tiers]]`**, not `context_over_200k`.\n\n```toml\n[cost]\ninput = 2.50\noutput = 15.00\n\n[[cost.tiers]]\ntier = { type = \"context\", size = 200_000 }\ninput = 5.00\noutput = 22.50\n```\n\n- `cost.context_over_200k` is **legacy output-only**. Do **not** author it in TOML (schema rejects it on write). The generator may emit it for old consumers when a single 200k-style tier exists; **always author tiers**.\n- Tier `size` is the context threshold where that band starts. No duplicate sizes.\n\n### Comments in TOML\n\nSync re-serializes many provider files and **drops every comment except a leading header block**. Put sources/rationale **above the first key**. Short comments next to a reasoning option for exact API syntax are fine when the file is not sync-owned.\n\n## Reasoning options\n\nAny provider model with `reasoning = true` **must** set `reasoning_options` for **this host’s** API. Details: `.opencode/skills/audit-reasoning-options/SKILL.md`.\n\n### 1. Classify the host (not the npm package)\n\n| Host kind | Who | How to pick options |\n| --- | --- | --- |\n| **First-party lab** | Provider **is** the lab (OpenAI, Anthropic, DeepSeek, Alibaba, Google, …) | Match that lab’s real API and existing `providers/<lab>/` entries for the same generation. |\n| **Multi-model relay / gateway** | Hosts many labs’ models (OpenRouter, Bedrock-as-relay, random OpenAI-compat aggregators, …) | Copy the **underlying model’s** controls from the lab entry + established same-surface peers. |\n\n**`npm = \"@ai-sdk/openai-compatible\"` does not mean “gateway.”** DeepSeek and Alibaba are first-party labs that use that package with **lab-specific** fields (`thinking.type`, `enable_thinking`, `thinking_budget`, …). Classify by **who runs the API**, not by the AI SDK package name.\n\n### 2. Baseline effort = native / peer set (not a fixed enum)\n\nDo **not** invent a universal `low`/`medium`/`high` for every reasoner.\n\n1. Open `providers/<lab>/models/…` for the underlying model (and 1–2 solid peers on the same kind of host).\n2. Author **that** effort list (and toggle/budget if those entries have them and this host exposes the same kind of control).\n3. Common cases:\n   - GPT-style on relays → often `low` / `medium` / `high` (add `none` / `xhigh` only if native/peers have them)\n   - DeepSeek V4 → `toggle` + `high` / `max` (not L/M/H; lab maps low/medium→high)\n   - Always-on / no control → `[]`\n4. On relays: **do not** use `[]` just because you could not re-test this host. Empty means **no caller control**, not uncertainty.\n5. Never invent `budget_tokens` unless this host (or the lab API it clearly proxies) has a real **reasoning** budget field. Not `max_tokens`.\n\n### 3. Toggle\n\nSame model ID, on and off, via a known request field. Separate `-thinking` / instruct IDs are not a toggle.\n\n| Host control | Author |\n| --- | --- |\n| Effort includes `none` **and** other graded levels | **Only** `effort` with `none` in `values` — **no** `toggle` |\n| Separate on/off control **and** graded effort (no `none` in effort) | `toggle` **+** `effort` with the **actual** levels |\n| Binary on/off only | `toggle` alone |\n\nEvery `toggle` needs a **leading top-of-file comment** with the exact wire path (sync strips mid-file comments).\n\n```toml\n# Toggle: thinking.type = enabled|disabled\n# Effort: reasoning_effort = high|max\nname = \"DeepSeek V4 Pro\"\nreasoning_options = [\n  { type = \"toggle\" },\n  { type = \"effort\", values = [\"high\", \"max\"] },\n]\n```\n\n```toml\n# Toggle: enable_thinking true|false\n# Budget: thinking_budget (integer reasoning tokens)\nname = \"Qwen3.5 Plus\"\nreasoning_options = [\n  { type = \"toggle\" },\n  { type = \"budget_tokens\" },\n]\n```\n\n```toml\n# Off is effort=none; graded levels — no toggle\nbase_model = \"openai/gpt-5.4\"\nreasoning_options = [{ type = \"effort\", values = [\"none\", \"low\", \"medium\", \"high\", \"xhigh\"] }]\n```\n\n## Platform naming quirks\n\n### Bedrock\n\n- Dated: `-v1:0` suffix (`anthropic.claude-3-5-sonnet-20241022-v1:0.toml`)\n- Latest/undated: bare `-v1` (`anthropic.claude-opus-4-6-v1.toml`)\n- Region prefixes: `us.`, `eu.`, `global.` (default has no prefix)\n\n### Vertex AI\n\n- Dated: `@YYYYMMDD` (`claude-opus-4-5@20251101.toml`)\n- Latest/undated: `@default` (`claude-opus-4-6@default.toml`)\n\n## Review checklist\n\n### Blockers\n\n- [ ] New provider has compliant `logo.svg`\n- [ ] Non-lab hosts use `base_model`; missing lab metadata was **added** under `models/` when needed (complete lab file, not a stub)\n- [ ] Provider `base_model` files are override-only (no duplicated identical fields; no provider-only keys under `models/`)\n- [ ] `reasoning = true` ⇒ `reasoning_options` set per policy above\n- [ ] Costs are USD/MTok\n- [ ] `bun validate` passes\n\n### Strongly recommended\n\n- [ ] PR body cites pricing/docs/API for data changes\n- [ ] Sync module if the provider catalog is rich enough (`sync.md`)\n- [ ] Leading TOML comment for sources on hand-authored files\n","category":"root","tokens":2879}]}