From 0abef6209c49adfaf544597506130eef9963f909 Mon Sep 17 00:00:00 2001 From: Brennan McEachran Date: Fri, 10 Jul 2026 17:56:50 -0400 Subject: [PATCH 1/2] feat(core): add Cloudflare AI Gateway to the model router Cloudflare AI Gateway is listed on models.dev but its entry has no api URL (the endpoint is account-scoped), so the registry generator skipped it. Add a PROVIDER_OVERRIDES entry that routes it through Cloudflare's OpenAI-compatible endpoint with URL-template env vars, list it as a gateway in the docs generator, and regenerate the provider registry and model docs. Model strings like cloudflare-ai-gateway/anthropic/claude-3-5-haiku now work with CLOUDFLARE_ACCOUNT_ID, CLOUDFLARE_GATEWAY_ID, and CLOUDFLARE_API_TOKEN. Co-Authored-By: Claude Fable 5 --- .changeset/cloudflare-ai-gateway-provider.md | 5 + .../en/models/environment-variables.mdx | 4 + .../models/gateways/cloudflare-ai-gateway.mdx | 130 +++ docs/src/content/en/models/gateways/index.mdx | 9 +- .../content/en/models/gateways/openrouter.mdx | 5 +- .../src/content/en/models/gateways/vercel.mdx | 2 +- docs/src/content/en/models/index.mdx | 8 +- .../providers/cloudflare-ai-gateway.mdx | 20 - .../en/models/providers/empiriolabs.mdx | 493 +++++++++ .../src/content/en/models/providers/index.mdx | 17 +- .../content/en/models/providers/openai.mdx | 16 +- .../content/en/models/providers/pioneer.mdx | 997 ++++++++++++++++++ .../content/en/models/providers/unorouter.mdx | 361 +++++++ docs/src/content/en/models/sidebars.js | 25 +- packages/core/scripts/generate-model-docs.ts | 25 +- .../capabilities/cloudflare-ai-gateway.json | 103 ++ .../llm/model/capabilities/empiriolabs.json | 57 + .../src/llm/model/capabilities/openai.json | 1 + .../llm/model/capabilities/openrouter.json | 1 - .../src/llm/model/capabilities/pioneer.json | 109 ++ .../src/llm/model/capabilities/unorouter.json | 35 + .../model/cloudflare-ai-gateway-url.test.ts | 75 ++ .../src/llm/model/gateways/models-dev.test.ts | 28 + .../core/src/llm/model/gateways/models-dev.ts | 8 + .../core/src/llm/model/provider-registry.json | 492 ++++++++- .../llm/model/provider-types.generated.d.ts | 221 +++- 26 files changed, 3197 insertions(+), 50 deletions(-) create mode 100644 .changeset/cloudflare-ai-gateway-provider.md create mode 100644 docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx delete mode 100644 docs/src/content/en/models/providers/cloudflare-ai-gateway.mdx create mode 100644 docs/src/content/en/models/providers/empiriolabs.mdx create mode 100644 docs/src/content/en/models/providers/pioneer.mdx create mode 100644 docs/src/content/en/models/providers/unorouter.mdx create mode 100644 packages/core/src/llm/model/capabilities/cloudflare-ai-gateway.json create mode 100644 packages/core/src/llm/model/capabilities/empiriolabs.json create mode 100644 packages/core/src/llm/model/capabilities/pioneer.json create mode 100644 packages/core/src/llm/model/capabilities/unorouter.json create mode 100644 packages/core/src/llm/model/cloudflare-ai-gateway-url.test.ts diff --git a/.changeset/cloudflare-ai-gateway-provider.md b/.changeset/cloudflare-ai-gateway-provider.md new file mode 100644 index 000000000000..69312ff82fd3 --- /dev/null +++ b/.changeset/cloudflare-ai-gateway-provider.md @@ -0,0 +1,5 @@ +--- +'@mastra/core': patch +--- + +Add Cloudflare AI Gateway to the model router. Model strings like `cloudflare-ai-gateway/anthropic/claude-3-5-haiku` now route through Cloudflare's OpenAI-compatible endpoint, configured via `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_GATEWAY_ID`, and `CLOUDFLARE_API_TOKEN`. Provider API keys are managed in the Cloudflare dashboard (BYOK) or via Unified Billing. diff --git a/docs/src/content/en/models/environment-variables.mdx b/docs/src/content/en/models/environment-variables.mdx index 9e1c0d1b8420..5b064eb7379d 100644 --- a/docs/src/content/en/models/environment-variables.mdx +++ b/docs/src/content/en/models/environment-variables.mdx @@ -43,6 +43,7 @@ List of required environment variables for each model provider and gateway suppo | [DeepSeek](/models/providers/deepseek) | `deepseek/*` | `DEEPSEEK_API_KEY` | | [DigitalOcean](/models/providers/digitalocean) | `digitalocean/*` | `DIGITALOCEAN_ACCESS_TOKEN` | | [DInference](/models/providers/dinference) | `dinference/*` | `DINFERENCE_API_KEY` | +| [EmpirioLabs AI](/models/providers/empiriolabs) | `empiriolabs/*` | `EMPIRIOLABS_API_KEY` | | [evroc](/models/providers/evroc) | `evroc/*` | `EVROC_API_KEY` | | [FastRouter](/models/providers/fastrouter) | `fastrouter/*` | `FASTROUTER_API_KEY` | | [Fireworks AI](/models/providers/fireworks-ai) | `fireworks-ai/*` | `FIREWORKS_API_KEY` | @@ -103,6 +104,7 @@ List of required environment variables for each model provider and gateway suppo | [OVHcloud AI Endpoints](/models/providers/ovhcloud) | `ovhcloud/*` | `OVHCLOUD_API_KEY` | | [Perplexity](/models/providers/perplexity) | `perplexity/*` | `PERPLEXITY_API_KEY` | | [Perplexity Agent](/models/providers/perplexity-agent) | `perplexity-agent/*` | `PERPLEXITY_API_KEY` | +| [Pioneer](/models/providers/pioneer) | `pioneer/*` | `PIONEER_API_KEY` | | [Poe](/models/providers/poe) | `poe/*` | `POE_API_KEY` | | [Poolside](/models/providers/poolside) | `poolside/*` | `POOLSIDE_API_KEY` | | [Privatemode AI](/models/providers/privatemode-ai) | `privatemode-ai/*` | `PRIVATEMODE_API_KEY` | @@ -132,6 +134,7 @@ List of required environment variables for each model provider and gateway suppo | [TrustedRouter](/models/providers/trustedrouter) | `trustedrouter/*` | `TRUSTEDROUTER_API_KEY` | | [Umans AI](/models/providers/umans-ai) | `umans-ai/*` | `UMANS_AI_API_KEY` | | [Umans AI Coding Plan](/models/providers/umans-ai-coding-plan) | `umans-ai-coding-plan/*` | `UMANS_AI_CODING_PLAN_API_KEY` | +| [UnoRouter](/models/providers/unorouter) | `unorouter/*` | `UNOROUTER_API_KEY` | | [Upstage](/models/providers/upstage) | `upstage/*` | `UPSTAGE_API_KEY` | | [Vivgrid](/models/providers/vivgrid) | `vivgrid/*` | `VIVGRID_API_KEY` | | [Vultr](/models/providers/vultr) | `vultr/*` | `VULTR_API_KEY` | @@ -151,6 +154,7 @@ List of required environment variables for each model provider and gateway suppo | [Zhipu AI](/models/providers/zhipuai) | `zhipuai/*` | `ZHIPU_API_KEY` | | [Zhipu AI Coding Plan](/models/providers/zhipuai-coding-plan) | `zhipuai-coding-plan/*` | `ZHIPU_API_KEY` | | [Azure OpenAI](/models/gateways/azure-openai) (Gateway) | `azure-openai/*` | `AZURE_API_KEY`, `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID` | +| [Cloudflare AI Gateway](/models/gateways/cloudflare-ai-gateway) (Gateway) | `cloudflare-ai-gateway/*` | `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_GATEWAY_ID`, `CLOUDFLARE_API_TOKEN` | | [Mastra](/models/gateways/mastra) (Gateway) | `mastra/*` | `MASTRA_GATEWAY_API_KEY` | | [Netlify](/models/gateways/netlify) (Gateway) | `netlify/*` | `NETLIFY_TOKEN`, `NETLIFY_SITE_ID` | | [OpenRouter](/models/gateways/openrouter) (Gateway) | `openrouter/*` | `OPENROUTER_API_KEY` | diff --git a/docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx b/docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx new file mode 100644 index 000000000000..e40f0c8b9897 --- /dev/null +++ b/docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx @@ -0,0 +1,130 @@ +--- +title: "Cloudflare AI Gateway | Models" +description: "Use AI models through Cloudflare AI Gateway." +--- + +{/* This file is auto-generated by generate-model-docs.ts - DO NOT EDIT MANUALLY */} + + + +# Cloudflare AI Gateway logoCloudflare AI Gateway + +Cloudflare AI Gateway provides unified access to multiple providers with built-in caching, rate limiting, and observability. Provider API keys are stored in your Cloudflare dashboard (BYOK) or covered by Unified Billing. Access 78 models through Mastra's model router. + +Learn more in the [Cloudflare AI Gateway documentation](https://developers.cloudflare.com/ai-gateway/). + +## Usage + +```typescript title="src/mastra/agents/my-agent.ts" +import { Agent } from "@mastra/core/agent"; + +const agent = new Agent({ + id: "my-agent", + name: "My Agent", + instructions: "You are a helpful assistant", + model: "cloudflare-ai-gateway/anthropic/claude-3-5-haiku" +}); +``` + +:::info + +Mastra uses the OpenAI-compatible `/chat/completions` endpoint. Some provider-specific features may not be available. Check the [Cloudflare AI Gateway documentation](https://developers.cloudflare.com/ai-gateway/) for details. + +::: + +## Configuration + +```bash +# Use gateway API key +CLOUDFLARE_ACCOUNT_ID=your-cloudflare-account-id +CLOUDFLARE_GATEWAY_ID=your-cloudflare-gateway-id +CLOUDFLARE_API_TOKEN=your-cloudflare-api-token + +# Provider API keys are managed in your Cloudflare dashboard +# (AI Gateway > Provider Keys) or via Unified Billing +``` + + +## Available models + +| Model | +|-------| +| `anthropic/claude-3-5-haiku` | +| `anthropic/claude-3-haiku` | +| `anthropic/claude-3-opus` | +| `anthropic/claude-3-sonnet` | +| `anthropic/claude-3.5-haiku` | +| `anthropic/claude-3.5-sonnet` | +| `anthropic/claude-fable-5` | +| `anthropic/claude-haiku-4-5` | +| `anthropic/claude-opus-4` | +| `anthropic/claude-opus-4-1` | +| `anthropic/claude-opus-4-5` | +| `anthropic/claude-opus-4-6` | +| `anthropic/claude-opus-4-7` | +| `anthropic/claude-opus-4-8` | +| `anthropic/claude-sonnet-4` | +| `anthropic/claude-sonnet-4-5` | +| `anthropic/claude-sonnet-4-6` | +| `anthropic/claude-sonnet-5` | +| `openai/gpt-3.5-turbo` | +| `openai/gpt-4` | +| `openai/gpt-4-turbo` | +| `openai/gpt-4o` | +| `openai/gpt-4o-mini` | +| `openai/gpt-5.1` | +| `openai/gpt-5.1-codex` | +| `openai/gpt-5.2` | +| `openai/gpt-5.2-codex` | +| `openai/gpt-5.3-codex` | +| `openai/gpt-5.4` | +| `openai/gpt-5.5` | +| `openai/o1` | +| `openai/o3` | +| `openai/o3-mini` | +| `openai/o3-pro` | +| `openai/o4-mini` | +| `workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B` | +| `workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it` | +| `workers-ai/@cf/baai/bge-base-en-v1.5` | +| `workers-ai/@cf/baai/bge-large-en-v1.5` | +| `workers-ai/@cf/baai/bge-m3` | +| `workers-ai/@cf/baai/bge-reranker-base` | +| `workers-ai/@cf/baai/bge-small-en-v1.5` | +| `workers-ai/@cf/deepgram/aura-2-en` | +| `workers-ai/@cf/deepgram/aura-2-es` | +| `workers-ai/@cf/deepgram/nova-3` | +| `workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b` | +| `workers-ai/@cf/facebook/bart-large-cnn` | +| `workers-ai/@cf/google/gemma-3-12b-it` | +| `workers-ai/@cf/huggingface/distilbert-sst-2-int8` | +| `workers-ai/@cf/ibm-granite/granite-4.0-h-micro` | +| `workers-ai/@cf/meta/llama-2-7b-chat-fp16` | +| `workers-ai/@cf/meta/llama-3-8b-instruct` | +| `workers-ai/@cf/meta/llama-3-8b-instruct-awq` | +| `workers-ai/@cf/meta/llama-3.1-8b-instruct` | +| `workers-ai/@cf/meta/llama-3.1-8b-instruct-awq` | +| `workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8` | +| `workers-ai/@cf/meta/llama-3.2-11b-vision-instruct` | +| `workers-ai/@cf/meta/llama-3.2-1b-instruct` | +| `workers-ai/@cf/meta/llama-3.2-3b-instruct` | +| `workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast` | +| `workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct` | +| `workers-ai/@cf/meta/llama-guard-3-8b` | +| `workers-ai/@cf/meta/m2m100-1.2b` | +| `workers-ai/@cf/mistral/mistral-7b-instruct-v0.1` | +| `workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct` | +| `workers-ai/@cf/moonshotai/kimi-k2.5` | +| `workers-ai/@cf/moonshotai/kimi-k2.6` | +| `workers-ai/@cf/myshell-ai/melotts` | +| `workers-ai/@cf/nvidia/nemotron-3-120b-a12b` | +| `workers-ai/@cf/openai/gpt-oss-120b` | +| `workers-ai/@cf/openai/gpt-oss-20b` | +| `workers-ai/@cf/pfnet/plamo-embedding-1b` | +| `workers-ai/@cf/pipecat-ai/smart-turn-v2` | +| `workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct` | +| `workers-ai/@cf/qwen/qwen3-30b-a3b-fp8` | +| `workers-ai/@cf/qwen/qwen3-embedding-0.6b` | +| `workers-ai/@cf/qwen/qwq-32b` | +| `workers-ai/@cf/zai-org/glm-4.7-flash` | + diff --git a/docs/src/content/en/models/gateways/index.mdx b/docs/src/content/en/models/gateways/index.mdx index 642bc3f9c520..cbf0d80fdeab 100644 --- a/docs/src/content/en/models/gateways/index.mdx +++ b/docs/src/content/en/models/gateways/index.mdx @@ -25,6 +25,13 @@ Create custom gateways for private LLM deployments or specialized provider integ href="/models/gateways/azure-openai" logo="https://models.dev/logos/azure-openai.svg" /> + OpenRouter -OpenRouter aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 346 models through Mastra's model router. +OpenRouter aggregates models from multiple providers with enhanced features like rate limiting and failover. Access 345 models through Mastra's model router. Learn more in the [OpenRouter documentation](https://openrouter.ai/models). @@ -36,7 +36,7 @@ Mastra uses the OpenAI-compatible `/chat/completions` endpoint. Some provider-sp ```bash # Use gateway API key -OPENROUTER_API_KEY=your-gateway-key +OPENROUTER_API_KEY=your-openrouter-api-key # Or use provider API keys directly OPENAI_API_KEY=sk-... @@ -87,7 +87,6 @@ ANTHROPIC_API_KEY=ant-... | `anthropic/claude-sonnet-5` | | `arcee-ai/coder-large` | | `arcee-ai/trinity-large-thinking` | -| `arcee-ai/trinity-mini` | | `arcee-ai/virtuoso-large` | | `baidu/ernie-4.5-vl-424b-a47b` | | `bytedance-seed/seed-1.6` | diff --git a/docs/src/content/en/models/gateways/vercel.mdx b/docs/src/content/en/models/gateways/vercel.mdx index 73fd5589bc62..e58f9acaee58 100644 --- a/docs/src/content/en/models/gateways/vercel.mdx +++ b/docs/src/content/en/models/gateways/vercel.mdx @@ -36,7 +36,7 @@ Mastra uses the OpenAI-compatible `/chat/completions` endpoint. Some provider-sp ```bash # Use gateway API key -AI_GATEWAY_API_KEY=your-gateway-key +AI_GATEWAY_API_KEY=your-ai-gateway-api-key # Or use provider API keys directly OPENAI_API_KEY=sk-... diff --git a/docs/src/content/en/models/index.mdx b/docs/src/content/en/models/index.mdx index 420c59a99f73..78224b2303ea 100644 --- a/docs/src/content/en/models/index.mdx +++ b/docs/src/content/en/models/index.mdx @@ -1,6 +1,6 @@ --- title: "Models" -description: "Access 144+ AI providers and 4683+ models through Mastra's model router." +description: "Access 148+ AI providers and 4894+ models through Mastra's model router." --- {/* This file is auto-generated by generate-model-docs.ts - DO NOT EDIT MANUALLY */} @@ -12,7 +12,7 @@ import { NetlifyLogo } from "@site/src/components/logos/NetlifyLogo"; # Model Providers -Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 4683 models from 144 providers through a single API. +Mastra provides a unified interface for working with LLMs across multiple providers, giving you access to 4894 models from 148 providers through a single API. ## Features @@ -127,7 +127,7 @@ Browse the directory of available models using the navigation on the left, or ex Vercel -
+ 2 more
+
+ 3 more
Google -
+ 136 more
+
+ 139 more
diff --git a/docs/src/content/en/models/providers/cloudflare-ai-gateway.mdx b/docs/src/content/en/models/providers/cloudflare-ai-gateway.mdx deleted file mode 100644 index d44a1ec0bf28..000000000000 --- a/docs/src/content/en/models/providers/cloudflare-ai-gateway.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Cloudflare AI Gateway" -description: "Use Cloudflare AI Gateway models via the AI SDK." ---- - -{/* This file is auto-generated by generate-model-docs.ts - DO NOT EDIT MANUALLY */} - -# Cloudflare AI Gateway logoCloudflare AI Gateway - -Cloudflare AI Gateway is available through the AI SDK. Install the provider package to use their models with Mastra. - -For detailed provider-specific documentation, see the [AI SDK Cloudflare AI Gateway provider docs](https://ai-sdk.dev/providers/community-providers/cloudflare-ai-gateway). - -To use this provider with Mastra agents, see the [Agent Overview documentation](/docs/agents/overview). - -## Installation - -```bash npm2yarn -npm install ai-gateway-provider -``` diff --git a/docs/src/content/en/models/providers/empiriolabs.mdx b/docs/src/content/en/models/providers/empiriolabs.mdx new file mode 100644 index 000000000000..b4588613fd2c --- /dev/null +++ b/docs/src/content/en/models/providers/empiriolabs.mdx @@ -0,0 +1,493 @@ +--- +title: "EmpirioLabs AI | Models" +description: "Use EmpirioLabs AI models with Mastra. 34 models available." +--- + +{/* This file is auto-generated by generate-model-docs.ts - DO NOT EDIT MANUALLY */} + +# EmpirioLabs AI logoEmpirioLabs AI + +Access 34 EmpirioLabs AI models through Mastra's model router. Authentication is handled automatically using the `EMPIRIOLABS_API_KEY` environment variable. + +Learn more in the [EmpirioLabs AI documentation](https://docs.empiriolabs.ai). + +```bash title=".env" +EMPIRIOLABS_API_KEY=your-api-key +``` + +```typescript title="src/mastra/agents/my-agent.ts" {7} +import { Agent } from "@mastra/core/agent"; + +const agent = new Agent({ + id: "my-agent", + name: "My Agent", + instructions: "You are a helpful assistant", + model: "empiriolabs/deepseek-v4-flash" +}); + +// Generate a response +const response = await agent.generate("Hello!"); + +// Stream a response +const stream = await agent.stream("Tell me a story"); +for await (const chunk of stream) { + console.log(chunk); +} +``` + +:::info + +Mastra uses the OpenAI-compatible `/chat/completions` endpoint. Some provider-specific features may not be available. Check the [EmpirioLabs AI documentation](https://docs.empiriolabs.ai) for details. + +::: + +## Models + + + +## Advanced configuration + +### Custom headers + +```typescript title="src/mastra/agents/my-agent.ts" +const agent = new Agent({ + id: "custom-agent", + name: "custom-agent", + model: { + url: "https://api.empiriolabs.ai/v1", + id: "empiriolabs/deepseek-v4-flash", + apiKey: process.env.EMPIRIOLABS_API_KEY, + headers: { + "X-Custom-Header": "value" + } + } +}); +``` + +### Dynamic model selection + +```typescript title="src/mastra/agents/my-agent.ts" +const agent = new Agent({ + id: "dynamic-agent", + name: "Dynamic Agent", + model: ({ requestContext }) => { + const useAdvanced = requestContext.task === "complex"; + return useAdvanced + ? "empiriolabs/step-3-7-flash" + : "empiriolabs/deepseek-v4-flash"; + } +}); +``` + + diff --git a/docs/src/content/en/models/providers/index.mdx b/docs/src/content/en/models/providers/index.mdx index 2a88aaf97d77..af6cf3eeb992 100644 --- a/docs/src/content/en/models/providers/index.mdx +++ b/docs/src/content/en/models/providers/index.mdx @@ -14,7 +14,7 @@ Direct access to individual AI model providers. Each provider offers unique mode OpenAI -Access 55 OpenAI models through Mastra's model router. Authentication is handled automatically using the `OPENAI_API_KEY` environment variable. +Access 56 OpenAI models through Mastra's model router. Authentication is handled automatically using the `OPENAI_API_KEY` environment variable. Learn more in the [OpenAI documentation](https://platform.openai.com/docs/models). @@ -567,6 +567,18 @@ for await (const chunk of stream) { "inputCost": 5, "outputCost": 30 }, + { + "model": "openai/gpt-realtime-2.1", + "imageInput": true, + "audioInput": true, + "videoInput": false, + "toolUsage": true, + "reasoning": true, + "contextWindow": 128000, + "maxOutput": 32000, + "inputCost": 4, + "outputCost": 24 + }, { "model": "openai/o1", "imageInput": true, diff --git a/docs/src/content/en/models/providers/pioneer.mdx b/docs/src/content/en/models/providers/pioneer.mdx new file mode 100644 index 000000000000..a0f7dca1acb0 --- /dev/null +++ b/docs/src/content/en/models/providers/pioneer.mdx @@ -0,0 +1,997 @@ +--- +title: "Pioneer | Models" +description: "Use Pioneer models with Mastra. 76 models available." +--- + +{/* This file is auto-generated by generate-model-docs.ts - DO NOT EDIT MANUALLY */} + +# Pioneer logoPioneer + +Access 76 Pioneer models through Mastra's model router. Authentication is handled automatically using the `PIONEER_API_KEY` environment variable. + +Learn more in the [Pioneer documentation](https://agent.pioneer.ai/llms.txt). + +```bash title=".env" +PIONEER_API_KEY=your-api-key +``` + +```typescript title="src/mastra/agents/my-agent.ts" {7} +import { Agent } from "@mastra/core/agent"; + +const agent = new Agent({ + id: "my-agent", + name: "My Agent", + instructions: "You are a helpful assistant", + model: "pioneer/HuggingFaceTB/SmolLM3-3B-Base" +}); + +// Generate a response +const response = await agent.generate("Hello!"); + +// Stream a response +const stream = await agent.stream("Tell me a story"); +for await (const chunk of stream) { + console.log(chunk); +} +``` + +:::info + +Mastra uses the OpenAI-compatible `/chat/completions` endpoint. Some provider-specific features may not be available. Check the [Pioneer documentation](https://agent.pioneer.ai/llms.txt) for details. + +::: + +## Models + + + +## Advanced configuration + +### Custom headers + +```typescript title="src/mastra/agents/my-agent.ts" +const agent = new Agent({ + id: "custom-agent", + name: "custom-agent", + model: { + url: "https://api.pioneer.ai/v1", + id: "pioneer/HuggingFaceTB/SmolLM3-3B-Base", + apiKey: process.env.PIONEER_API_KEY, + headers: { + "X-Custom-Header": "value" + } + } +}); +``` + +### Dynamic model selection + +```typescript title="src/mastra/agents/my-agent.ts" +const agent = new Agent({ + id: "dynamic-agent", + name: "Dynamic Agent", + model: ({ requestContext }) => { + const useAdvanced = requestContext.task === "complex"; + return useAdvanced + ? "pioneer/zai-org/GLM-5.2" + : "pioneer/HuggingFaceTB/SmolLM3-3B-Base"; + } +}); +``` + + diff --git a/docs/src/content/en/models/providers/unorouter.mdx b/docs/src/content/en/models/providers/unorouter.mdx new file mode 100644 index 000000000000..6c2c26f599d7 --- /dev/null +++ b/docs/src/content/en/models/providers/unorouter.mdx @@ -0,0 +1,361 @@ +--- +title: "UnoRouter | Models" +description: "Use UnoRouter models with Mastra. 23 models available." +--- + +{/* This file is auto-generated by generate-model-docs.ts - DO NOT EDIT MANUALLY */} + +# UnoRouter logoUnoRouter + +Access 23 UnoRouter models through Mastra's model router. Authentication is handled automatically using the `UNOROUTER_API_KEY` environment variable. + +Learn more in the [UnoRouter documentation](https://unorouter.com/models). + +```bash title=".env" +UNOROUTER_API_KEY=your-api-key +``` + +```typescript title="src/mastra/agents/my-agent.ts" {7} +import { Agent } from "@mastra/core/agent"; + +const agent = new Agent({ + id: "my-agent", + name: "My Agent", + instructions: "You are a helpful assistant", + model: "unorouter/claude-haiku-4-5-20251001" +}); + +// Generate a response +const response = await agent.generate("Hello!"); + +// Stream a response +const stream = await agent.stream("Tell me a story"); +for await (const chunk of stream) { + console.log(chunk); +} +``` + +:::info + +Mastra uses the OpenAI-compatible `/chat/completions` endpoint. Some provider-specific features may not be available. Check the [UnoRouter documentation](https://unorouter.com/models) for details. + +::: + +## Models + + + +## Advanced configuration + +### Custom headers + +```typescript title="src/mastra/agents/my-agent.ts" +const agent = new Agent({ + id: "custom-agent", + name: "custom-agent", + model: { + url: "https://api.unorouter.com/v1", + id: "unorouter/claude-haiku-4-5-20251001", + apiKey: process.env.UNOROUTER_API_KEY, + headers: { + "X-Custom-Header": "value" + } + } +}); +``` + +### Dynamic model selection + +```typescript title="src/mastra/agents/my-agent.ts" +const agent = new Agent({ + id: "dynamic-agent", + name: "Dynamic Agent", + model: ({ requestContext }) => { + const useAdvanced = requestContext.task === "complex"; + return useAdvanced + ? "unorouter/step-3.7-flash:free" + : "unorouter/claude-haiku-4-5-20251001"; + } +}); +``` + + diff --git a/docs/src/content/en/models/sidebars.js b/docs/src/content/en/models/sidebars.js index 2b127540fd26..d70621451d7d 100644 --- a/docs/src/content/en/models/sidebars.js +++ b/docs/src/content/en/models/sidebars.js @@ -34,6 +34,11 @@ const sidebars = { id: 'gateways/azure-openai', label: 'Azure OpenAI', }, + { + type: 'doc', + id: 'gateways/cloudflare-ai-gateway', + label: 'Cloudflare AI Gateway', + }, { type: 'doc', id: 'gateways/mastra', @@ -221,11 +226,6 @@ const sidebars = { id: 'providers/cloudferro-sherlock', label: 'CloudFerro Sherlock', }, - { - type: 'doc', - id: 'providers/cloudflare-ai-gateway', - label: 'Cloudflare AI Gateway', - }, { type: 'doc', id: 'providers/cloudflare-workers-ai', @@ -276,6 +276,11 @@ const sidebars = { id: 'providers/dinference', label: 'DInference', }, + { + type: 'doc', + id: 'providers/empiriolabs', + label: 'EmpirioLabs AI', + }, { type: 'doc', id: 'providers/evroc', @@ -566,6 +571,11 @@ const sidebars = { id: 'providers/perplexity-agent', label: 'Perplexity Agent', }, + { + type: 'doc', + id: 'providers/pioneer', + label: 'Pioneer', + }, { type: 'doc', id: 'providers/poe', @@ -711,6 +721,11 @@ const sidebars = { id: 'providers/umans-ai-coding-plan', label: 'Umans AI Coding Plan', }, + { + type: 'doc', + id: 'providers/unorouter', + label: 'UnoRouter', + }, { type: 'doc', id: 'providers/upstage', diff --git a/packages/core/scripts/generate-model-docs.ts b/packages/core/scripts/generate-model-docs.ts index cbd287d1a789..0c371a31a2a1 100644 --- a/packages/core/scripts/generate-model-docs.ts +++ b/packages/core/scripts/generate-model-docs.ts @@ -38,6 +38,7 @@ function formatProviderName(name: string): string { zhipuai: 'Zhipu AI', opencode: 'OpenCode', 'azure-openai': 'Azure OpenAI', + 'cloudflare-ai-gateway': 'Cloudflare AI Gateway', }; const lower = name.toLowerCase(); @@ -113,7 +114,7 @@ const __dirname = path.dirname(__filename); const POPULAR_PROVIDERS = ['openai', 'anthropic', 'google', 'deepseek', 'groq', 'mistral', 'xai']; // Providers that are actually gateways (aggregate multiple model providers) -const GATEWAY_PROVIDERS = ['netlify', 'openrouter', 'vercel', 'azure-openai']; +const GATEWAY_PROVIDERS = ['netlify', 'openrouter', 'vercel', 'azure-openai', 'cloudflare-ai-gateway']; const MANUALLY_DOCUMENTED_PROVIDERS = ['azure-openai']; const MANUALLY_DOCUMENTED_GATEWAYS = ['azure-openai', 'mastra']; @@ -516,7 +517,9 @@ function generateGatewayPage( const gatewayDescription = gatewayName === 'netlify' ? 'Netlify AI Gateway provides unified access to multiple providers with built-in caching and observability.' - : `${displayName} aggregates models from multiple providers with enhanced features like rate limiting and failover.`; + : gatewayName === 'cloudflare-ai-gateway' + ? 'Cloudflare AI Gateway provides unified access to multiple providers with built-in caching, rate limiting, and observability. Provider API keys are stored in your Cloudflare dashboard (BYOK) or covered by Unified Billing.' + : `${displayName} aggregates models from multiple providers with enhanced features like rate limiting and failover.`; const introText = docUrl ? `${gatewayDescription} Access ${totalModels} models through Mastra's model router. @@ -583,16 +586,20 @@ Mastra uses the OpenAI-compatible \`/chat/completions\` endpoint. Some provider- \`\`\`bash # Use gateway API key ${(() => { - const envVar = providers[0]?.apiKeyEnvVar; - if (Array.isArray(envVar)) { - return envVar.map(v => `${v}=your-${v.toLowerCase().replace(/_/g, '-')}`).join('\n'); - } - return `${envVar || `${gatewayName.toUpperCase()}_API_KEY`}=your-gateway-key`; + const provider = providers[0]; + const envVars = provider ? getRequiredEnvVars(provider) : [`${gatewayName.toUpperCase()}_API_KEY`]; + return envVars.map(v => `${v}=your-${v.toLowerCase().replace(/_/g, '-')}`).join('\n'); })()} - +${ + gatewayName === 'cloudflare-ai-gateway' + ? ` +# Provider API keys are managed in your Cloudflare dashboard +# (AI Gateway > Provider Keys) or via Unified Billing` + : ` # Or use provider API keys directly OPENAI_API_KEY=sk-... -ANTHROPIC_API_KEY=ant-... +ANTHROPIC_API_KEY=ant-...` +} \`\`\` ${modelTable} diff --git a/packages/core/src/llm/model/capabilities/cloudflare-ai-gateway.json b/packages/core/src/llm/model/capabilities/cloudflare-ai-gateway.json new file mode 100644 index 000000000000..8ea058b137ba --- /dev/null +++ b/packages/core/src/llm/model/capabilities/cloudflare-ai-gateway.json @@ -0,0 +1,103 @@ +{ + "attachment": [ + "anthropic/claude-3-5-haiku", + "anthropic/claude-3-haiku", + "anthropic/claude-3-opus", + "anthropic/claude-3-sonnet", + "anthropic/claude-3.5-haiku", + "anthropic/claude-3.5-sonnet", + "anthropic/claude-fable-5", + "anthropic/claude-haiku-4-5", + "anthropic/claude-opus-4", + "anthropic/claude-opus-4-1", + "anthropic/claude-opus-4-5", + "anthropic/claude-opus-4-6", + "anthropic/claude-opus-4-7", + "anthropic/claude-opus-4-8", + "anthropic/claude-sonnet-4", + "anthropic/claude-sonnet-4-5", + "anthropic/claude-sonnet-4-6", + "anthropic/claude-sonnet-5", + "openai/gpt-4", + "openai/gpt-4-turbo", + "openai/gpt-4o", + "openai/gpt-4o-mini", + "openai/gpt-5.1", + "openai/gpt-5.1-codex", + "openai/gpt-5.2", + "openai/gpt-5.2-codex", + "openai/gpt-5.3-codex", + "openai/gpt-5.4", + "openai/gpt-5.5", + "openai/o1", + "openai/o3", + "openai/o3-pro", + "openai/o4-mini", + "workers-ai/@cf/moonshotai/kimi-k2.5", + "workers-ai/@cf/moonshotai/kimi-k2.6" + ], + "temperature": [ + "anthropic/claude-3-5-haiku", + "anthropic/claude-3-haiku", + "anthropic/claude-3-opus", + "anthropic/claude-3-sonnet", + "anthropic/claude-3.5-haiku", + "anthropic/claude-3.5-sonnet", + "anthropic/claude-haiku-4-5", + "anthropic/claude-opus-4", + "anthropic/claude-opus-4-1", + "anthropic/claude-opus-4-5", + "anthropic/claude-opus-4-6", + "anthropic/claude-sonnet-4", + "anthropic/claude-sonnet-4-5", + "anthropic/claude-sonnet-4-6", + "openai/gpt-3.5-turbo", + "openai/gpt-4", + "openai/gpt-4-turbo", + "openai/gpt-4o", + "openai/gpt-4o-mini", + "workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B", + "workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it", + "workers-ai/@cf/baai/bge-base-en-v1.5", + "workers-ai/@cf/baai/bge-large-en-v1.5", + "workers-ai/@cf/baai/bge-m3", + "workers-ai/@cf/baai/bge-reranker-base", + "workers-ai/@cf/baai/bge-small-en-v1.5", + "workers-ai/@cf/deepgram/aura-2-en", + "workers-ai/@cf/deepgram/aura-2-es", + "workers-ai/@cf/deepgram/nova-3", + "workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", + "workers-ai/@cf/facebook/bart-large-cnn", + "workers-ai/@cf/google/gemma-3-12b-it", + "workers-ai/@cf/huggingface/distilbert-sst-2-int8", + "workers-ai/@cf/ibm-granite/granite-4.0-h-micro", + "workers-ai/@cf/meta/llama-2-7b-chat-fp16", + "workers-ai/@cf/meta/llama-3-8b-instruct", + "workers-ai/@cf/meta/llama-3-8b-instruct-awq", + "workers-ai/@cf/meta/llama-3.1-8b-instruct", + "workers-ai/@cf/meta/llama-3.1-8b-instruct-awq", + "workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8", + "workers-ai/@cf/meta/llama-3.2-11b-vision-instruct", + "workers-ai/@cf/meta/llama-3.2-1b-instruct", + "workers-ai/@cf/meta/llama-3.2-3b-instruct", + "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast", + "workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct", + "workers-ai/@cf/meta/llama-guard-3-8b", + "workers-ai/@cf/meta/m2m100-1.2b", + "workers-ai/@cf/mistral/mistral-7b-instruct-v0.1", + "workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct", + "workers-ai/@cf/moonshotai/kimi-k2.5", + "workers-ai/@cf/moonshotai/kimi-k2.6", + "workers-ai/@cf/myshell-ai/melotts", + "workers-ai/@cf/nvidia/nemotron-3-120b-a12b", + "workers-ai/@cf/openai/gpt-oss-120b", + "workers-ai/@cf/openai/gpt-oss-20b", + "workers-ai/@cf/pfnet/plamo-embedding-1b", + "workers-ai/@cf/pipecat-ai/smart-turn-v2", + "workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct", + "workers-ai/@cf/qwen/qwen3-30b-a3b-fp8", + "workers-ai/@cf/qwen/qwen3-embedding-0.6b", + "workers-ai/@cf/qwen/qwq-32b", + "workers-ai/@cf/zai-org/glm-4.7-flash" + ] +} diff --git a/packages/core/src/llm/model/capabilities/empiriolabs.json b/packages/core/src/llm/model/capabilities/empiriolabs.json new file mode 100644 index 000000000000..d1bfa26ec2cf --- /dev/null +++ b/packages/core/src/llm/model/capabilities/empiriolabs.json @@ -0,0 +1,57 @@ +{ + "attachment": [ + "fugu-ultra", + "gemma-4-26b-a4b", + "kimi-k2-6", + "kimi-k2-7-code", + "kimi-k2-7-code-highspeed", + "mimo-v2-5", + "minimax-m3", + "muse-spark-1-1", + "qwen3-5-122b-a10b", + "qwen3-5-27b", + "qwen3-5-35b-a3b", + "qwen3-5-397b-a17b", + "qwen3-5-4b", + "qwen3-5-9b", + "qwen3-5-plus", + "qwen3-6-27b", + "qwen3-6-flash", + "qwen3-6-plus", + "qwen3-7-plus", + "step-3-7-flash" + ], + "temperature": [ + "deepseek-v4-flash", + "deepseek-v4-pro", + "gemma-4-26b-a4b", + "glm-4-5-flash", + "glm-4-7-flash", + "glm-5-1", + "glm-5-2", + "kimi-k2-6", + "mimo-v2-5", + "mimo-v2-5-pro", + "minimax-m2-7", + "minimax-m2-7-highspeed", + "minimax-m3", + "muse-spark-1-1", + "qwen3-5-122b-a10b", + "qwen3-5-27b", + "qwen3-5-35b-a3b", + "qwen3-5-397b-a17b", + "qwen3-5-4b", + "qwen3-5-9b", + "qwen3-5-plus", + "qwen3-6-27b", + "qwen3-6-flash", + "qwen3-6-max-preview", + "qwen3-6-plus", + "qwen3-7-max", + "qwen3-7-plus", + "qwen3-max", + "step-3-5-flash", + "step-3-5-flash-2603", + "step-3-7-flash" + ] +} diff --git a/packages/core/src/llm/model/capabilities/openai.json b/packages/core/src/llm/model/capabilities/openai.json index 6bb23a7107d9..43f7b0544df9 100644 --- a/packages/core/src/llm/model/capabilities/openai.json +++ b/packages/core/src/llm/model/capabilities/openai.json @@ -42,6 +42,7 @@ "gpt-image-1-mini", "gpt-image-1.5", "gpt-image-2", + "gpt-realtime-2.1", "o1", "o1-pro", "o3", diff --git a/packages/core/src/llm/model/capabilities/openrouter.json b/packages/core/src/llm/model/capabilities/openrouter.json index 593d4e4abc10..a764cd10fc35 100644 --- a/packages/core/src/llm/model/capabilities/openrouter.json +++ b/packages/core/src/llm/model/capabilities/openrouter.json @@ -212,7 +212,6 @@ "anthropic/claude-sonnet-4.6", "arcee-ai/coder-large", "arcee-ai/trinity-large-thinking", - "arcee-ai/trinity-mini", "arcee-ai/virtuoso-large", "baidu/ernie-4.5-vl-424b-a47b", "bytedance-seed/seed-1.6", diff --git a/packages/core/src/llm/model/capabilities/pioneer.json b/packages/core/src/llm/model/capabilities/pioneer.json new file mode 100644 index 000000000000..2701c579d278 --- /dev/null +++ b/packages/core/src/llm/model/capabilities/pioneer.json @@ -0,0 +1,109 @@ +{ + "attachment": [ + "MiniMaxAI/MiniMax-M3", + "Qwen/Qwen3.6-27B", + "Qwen/Qwen3.6-35B-A3B", + "XiaomiMiMo/MiMo-V2.5", + "claude-haiku-4-5", + "claude-opus-4-1", + "claude-opus-4-5", + "claude-opus-4-6", + "claude-opus-4-7", + "claude-opus-4-8", + "claude-sonnet-4-5", + "claude-sonnet-4-6", + "gemini-3-flash", + "gemini-3.1-pro", + "gemini-3.5-flash", + "google/gemma-4-31B-it", + "google/gemma-4-E2B-it", + "google/gemma-4-E4B-it", + "gpt-4.1", + "gpt-4.1-mini", + "gpt-4.1-nano", + "gpt-4o", + "gpt-4o-mini", + "gpt-5-mini", + "gpt-5-nano", + "gpt-5.1", + "gpt-5.3-codex", + "gpt-5.4", + "gpt-5.4-mini", + "gpt-5.4-nano", + "gpt-5.5", + "meta-llama/Llama-3.3-70B-Instruct", + "mistral-medium-3.5", + "mistralai/Mistral-Small-4-119B-2603", + "moonshotai/Kimi-K2.6", + "moonshotai/Kimi-K2.7-Code", + "pioneer/auto", + "qwen3.6-flash", + "sakana/fugu-ultra" + ], + "temperature": [ + "HuggingFaceTB/SmolLM3-3B-Base", + "LiquidAI/LFM2-24B-A2B", + "MiniMaxAI/MiniMax-M2.7", + "MiniMaxAI/MiniMax-M3", + "Qwen/Qwen3-1.7B-Base", + "Qwen/Qwen3-32B", + "Qwen/Qwen3-4B-Base", + "Qwen/Qwen3-4B-Instruct-2507", + "Qwen/Qwen3-8B", + "Qwen/Qwen3.5-9B", + "Qwen/Qwen3.6-27B", + "Qwen/Qwen3.6-35B-A3B", + "XiaomiMiMo/MiMo-V2.5", + "XiaomiMiMo/MiMo-V2.5-Pro", + "claude-haiku-4-5", + "claude-opus-4-1", + "claude-opus-4-5", + "claude-opus-4-6", + "claude-sonnet-4-5", + "claude-sonnet-4-6", + "deepseek-ai/DeepSeek-V4-Flash", + "deepseek-ai/DeepSeek-V4-Pro", + "fastino/gliguard-LLMGuardrails-300M", + "fastino/gliner2-base-v1", + "fastino/gliner2-large-v1", + "fastino/gliner2-multi-large-v1", + "fastino/gliner2-multi-v1", + "fastino/gliner2-privacy-filter-PII-multi", + "gemini-3-flash", + "gemini-3.1-pro", + "gemini-3.5-flash", + "google/diffusiongemma-26B-A4B-it", + "google/gemma-3-4b-pt", + "google/gemma-4-12B-it", + "google/gemma-4-31B-it", + "google/gemma-4-E2B-it", + "google/gemma-4-E4B-it", + "gpt-4.1", + "gpt-4.1-mini", + "gpt-4.1-nano", + "gpt-4o", + "gpt-4o-mini", + "meta-llama/Llama-3.1-8B-Instruct", + "meta-llama/Llama-3.2-1B-Instruct", + "meta-llama/Llama-3.2-3B-Instruct", + "meta-llama/Llama-3.3-70B-Instruct", + "mistral-medium-3.5", + "mistralai/Mistral-7B-Instruct-v0.3", + "mistralai/Mistral-Nemo-Instruct-2407", + "mistralai/Mistral-Small-4-119B-2603", + "moonshotai/Kimi-K2.6", + "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16", + "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8", + "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-BF16", + "openai/gpt-oss-120b", + "openai/gpt-oss-20b", + "pioneer/auto", + "qwen3.6-flash", + "qwen3.6-max-preview", + "qwen3.6-plus", + "qwen3.7-max", + "qwen3.7-plus", + "zai-org/GLM-5.1", + "zai-org/GLM-5.2" + ] +} diff --git a/packages/core/src/llm/model/capabilities/unorouter.json b/packages/core/src/llm/model/capabilities/unorouter.json new file mode 100644 index 000000000000..12766692998b --- /dev/null +++ b/packages/core/src/llm/model/capabilities/unorouter.json @@ -0,0 +1,35 @@ +{ + "attachment": [ + "claude-haiku-4-5-20251001", + "claude-opus-4-8", + "claude-sonnet-5", + "gemini-3.5-flash", + "gemma-4-31b-it:free", + "gpt-5.2", + "gpt-5.4", + "gpt-5.4:free", + "gpt-5.5", + "gpt-5.5:free", + "kimi-k2.6", + "qwen3.5-397b-a17b:free", + "step-3.7-flash:free" + ], + "temperature": [ + "claude-haiku-4-5-20251001", + "deepseek-v4-flash", + "deepseek-v4-flash:free", + "deepseek-v4-pro", + "deepseek-v4-pro:free", + "gemini-3.5-flash", + "gemma-4-31b-it:free", + "glm-4.5-flash:free", + "glm-5.2", + "glm-5.2:free", + "kimi-k2.6", + "minimax-m2.7", + "minimax-m2.7:free", + "nemotron-3-ultra-550b-a55b:free", + "qwen3.5-397b-a17b:free", + "step-3.7-flash:free" + ] +} diff --git a/packages/core/src/llm/model/cloudflare-ai-gateway-url.test.ts b/packages/core/src/llm/model/cloudflare-ai-gateway-url.test.ts new file mode 100644 index 000000000000..b7db364d3678 --- /dev/null +++ b/packages/core/src/llm/model/cloudflare-ai-gateway-url.test.ts @@ -0,0 +1,75 @@ +import { convertArrayToReadableStream, MockLanguageModelV2 } from '@internal/ai-sdk-v5/test'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +vi.mock('@ai-sdk/openai-compatible-v5', async () => { + return { + createOpenAICompatible: vi.fn(), + }; +}); + +const { createOpenAICompatible } = await import('@ai-sdk/openai-compatible-v5'); +const { Agent } = await import('../../agent'); + +describe('Cloudflare AI Gateway URL interpolation', () => { + const chatModel = vi.fn( + () => + new MockLanguageModelV2({ + doGenerate: async () => ({ + rawCall: { rawPrompt: null, rawSettings: {} }, + finishReason: 'stop', + usage: { inputTokens: 1, outputTokens: 1, totalTokens: 2 }, + content: [{ type: 'text', text: 'ok' }], + warnings: [], + }), + doStream: async () => ({ + rawCall: { rawPrompt: null, rawSettings: {} }, + warnings: [], + stream: convertArrayToReadableStream([ + { type: 'stream-start', warnings: [] }, + { type: 'response-metadata', id: 'id-0', modelId: 'mock-model', timestamp: new Date(0) }, + { type: 'text-start', id: 'text-1' }, + { type: 'text-delta', id: 'text-1', delta: 'ok' }, + { type: 'text-end', id: 'text-1' }, + { type: 'finish', finishReason: 'stop', usage: { inputTokens: 1, outputTokens: 1, totalTokens: 2 } }, + ]), + }), + }), + ); + + beforeEach(() => { + process.env.CLOUDFLARE_ACCOUNT_ID = 'account-123'; + process.env.CLOUDFLARE_GATEWAY_ID = 'gateway-123'; + process.env.CLOUDFLARE_API_TOKEN = 'token-123'; + + vi.mocked(createOpenAICompatible).mockReturnValue({ + chatModel, + } as any); + }); + + afterEach(() => { + vi.clearAllMocks(); + delete process.env.CLOUDFLARE_ACCOUNT_ID; + delete process.env.CLOUDFLARE_GATEWAY_ID; + delete process.env.CLOUDFLARE_API_TOKEN; + }); + + it('passes an interpolated baseURL to the provider during agent.stream()', async () => { + const agent = new Agent({ + id: 'cf-ai-gateway-agent', + name: 'CF AI Gateway Agent', + instructions: 'Be brief.', + model: 'cloudflare-ai-gateway/anthropic/claude-3-5-haiku', + }); + + const result = await agent.stream('hello'); + await result.text; + + expect(createOpenAICompatible).toHaveBeenCalledTimes(1); + expect(vi.mocked(createOpenAICompatible).mock.calls[0]?.[0]).toMatchObject({ + baseURL: 'https://gateway.ai.cloudflare.com/v1/account-123/gateway-123/compat', + apiKey: 'token-123', + }); + // The compat endpoint expects `{provider}/{model}` as the model name + expect(chatModel).toHaveBeenCalledWith('anthropic/claude-3-5-haiku'); + }); +}); diff --git a/packages/core/src/llm/model/gateways/models-dev.test.ts b/packages/core/src/llm/model/gateways/models-dev.test.ts index 6f90bcc762c8..df4e6833dad0 100644 --- a/packages/core/src/llm/model/gateways/models-dev.test.ts +++ b/packages/core/src/llm/model/gateways/models-dev.test.ts @@ -148,6 +148,17 @@ describe('ModelsDevGateway', () => { api: 'https://generativelanguage.googleapis.com/v1beta', npm: '@ai-sdk/google', }, + 'cloudflare-ai-gateway': { + id: 'cloudflare-ai-gateway', + name: 'Cloudflare AI Gateway', + models: { + 'anthropic/claude-3-5-haiku': { name: 'Claude 3.5 Haiku' }, + 'openai/gpt-4o': { name: 'GPT-4o' }, + }, + env: ['CLOUDFLARE_API_TOKEN', 'CLOUDFLARE_ACCOUNT_ID', 'CLOUDFLARE_GATEWAY_ID'], + // No api URL on models.dev - the URL comes from PROVIDER_OVERRIDES + npm: 'ai-gateway-provider', + }, 'unknown-provider': { id: 'unknown-provider', name: 'Unknown', @@ -199,6 +210,23 @@ describe('ModelsDevGateway', () => { expect(providers.openai.url).toBe('https://api.openai.com/v1'); }); + it('should include cloudflare-ai-gateway via PROVIDER_OVERRIDES despite the missing api URL', async () => { + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockApiResponse, + }); + + const providers = await gateway.fetchProviders(); + + expect(providers['cloudflare-ai-gateway']).toBeDefined(); + expect(providers['cloudflare-ai-gateway'].url).toBe( + 'https://gateway.ai.cloudflare.com/v1/${CLOUDFLARE_ACCOUNT_ID}/${CLOUDFLARE_GATEWAY_ID}/compat', + ); + // The account and gateway IDs are URL template inputs, not auth + expect(providers['cloudflare-ai-gateway'].apiKeyEnvVar).toBe('CLOUDFLARE_API_TOKEN'); + expect(providers['cloudflare-ai-gateway'].models).toEqual(['anthropic/claude-3-5-haiku', 'openai/gpt-4o']); + }); + it('should preserve Google legacy API key fallback when generating providers', async () => { mockFetch.mockResolvedValueOnce({ ok: true, diff --git a/packages/core/src/llm/model/gateways/models-dev.ts b/packages/core/src/llm/model/gateways/models-dev.ts index 1febab218e3c..f226d5c721e3 100644 --- a/packages/core/src/llm/model/gateways/models-dev.ts +++ b/packages/core/src/llm/model/gateways/models-dev.ts @@ -111,6 +111,14 @@ const PROVIDER_OVERRIDES: Record> = { url: 'https://api.moonshot.cn/anthropic/v1', npm: '@ai-sdk/anthropic', }, + // Cloudflare AI Gateway's models.dev entry has no `api` URL because the + // endpoint is account-scoped. Route through its OpenAI-compatible endpoint, + // interpolating the account and gateway from env vars. Auth must be the API + // token; the other env vars are consumed by the URL template. + 'cloudflare-ai-gateway': { + url: 'https://gateway.ai.cloudflare.com/v1/${CLOUDFLARE_ACCOUNT_ID}/${CLOUDFLARE_GATEWAY_ID}/compat', + apiKeyEnvVar: 'CLOUDFLARE_API_TOKEN', + }, }; export class ModelsDevGateway extends MastraModelGateway { diff --git a/packages/core/src/llm/model/provider-registry.json b/packages/core/src/llm/model/provider-registry.json index a0fee6c3cd1b..123562a1f6e9 100644 --- a/packages/core/src/llm/model/provider-registry.json +++ b/packages/core/src/llm/model/provider-registry.json @@ -2024,6 +2024,7 @@ "gpt-image-1-mini", "gpt-image-1.5", "gpt-image-2", + "gpt-realtime-2.1", "o1", "o1-pro", "o3", @@ -2599,6 +2600,92 @@ "docUrl": "https://docs.near.ai/", "gateway": "models.dev" }, + "pioneer": { + "url": "https://api.pioneer.ai/v1", + "apiKeyEnvVar": "PIONEER_API_KEY", + "apiKeyHeader": "Authorization", + "name": "Pioneer", + "models": [ + "HuggingFaceTB/SmolLM3-3B-Base", + "LiquidAI/LFM2-24B-A2B", + "MiniMaxAI/MiniMax-M2.7", + "MiniMaxAI/MiniMax-M3", + "Qwen/Qwen3-1.7B-Base", + "Qwen/Qwen3-32B", + "Qwen/Qwen3-4B-Base", + "Qwen/Qwen3-4B-Instruct-2507", + "Qwen/Qwen3-8B", + "Qwen/Qwen3.5-9B", + "Qwen/Qwen3.6-27B", + "Qwen/Qwen3.6-35B-A3B", + "XiaomiMiMo/MiMo-V2.5", + "XiaomiMiMo/MiMo-V2.5-Pro", + "claude-haiku-4-5", + "claude-opus-4-1", + "claude-opus-4-5", + "claude-opus-4-6", + "claude-opus-4-7", + "claude-opus-4-8", + "claude-sonnet-4-5", + "claude-sonnet-4-6", + "deepseek-ai/DeepSeek-V4-Flash", + "deepseek-ai/DeepSeek-V4-Pro", + "fastino/gliguard-LLMGuardrails-300M", + "fastino/gliner2-base-v1", + "fastino/gliner2-large-v1", + "fastino/gliner2-multi-large-v1", + "fastino/gliner2-multi-v1", + "fastino/gliner2-privacy-filter-PII-multi", + "gemini-3-flash", + "gemini-3.1-pro", + "gemini-3.5-flash", + "google/diffusiongemma-26B-A4B-it", + "google/gemma-3-4b-pt", + "google/gemma-4-12B-it", + "google/gemma-4-31B-it", + "google/gemma-4-E2B-it", + "google/gemma-4-E4B-it", + "gpt-4.1", + "gpt-4.1-mini", + "gpt-4.1-nano", + "gpt-4o", + "gpt-4o-mini", + "gpt-5-mini", + "gpt-5-nano", + "gpt-5.1", + "gpt-5.3-codex", + "gpt-5.4", + "gpt-5.4-mini", + "gpt-5.4-nano", + "gpt-5.5", + "meta-llama/Llama-3.1-8B-Instruct", + "meta-llama/Llama-3.2-1B-Instruct", + "meta-llama/Llama-3.2-3B-Instruct", + "meta-llama/Llama-3.3-70B-Instruct", + "mistral-medium-3.5", + "mistralai/Mistral-7B-Instruct-v0.3", + "mistralai/Mistral-Nemo-Instruct-2407", + "mistralai/Mistral-Small-4-119B-2603", + "moonshotai/Kimi-K2.6", + "moonshotai/Kimi-K2.7-Code", + "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16", + "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8", + "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-BF16", + "openai/gpt-oss-120b", + "openai/gpt-oss-20b", + "pioneer/auto", + "qwen3.6-flash", + "qwen3.6-max-preview", + "qwen3.6-plus", + "qwen3.7-max", + "qwen3.7-plus", + "sakana/fugu-ultra", + "zai-org/GLM-5.1", + "zai-org/GLM-5.2" + ], + "docUrl": "https://agent.pioneer.ai/llms.txt", + "gateway": "models.dev" + }, "llmgateway": { "url": "https://api.llmgateway.io/v1", "apiKeyEnvVar": "LLMGATEWAY_API_KEY", @@ -2977,6 +3064,112 @@ "docUrl": "https://docs.ollama.com/cloud", "gateway": "models.dev" }, + "cloudflare-ai-gateway": { + "url": "https://gateway.ai.cloudflare.com/v1/${CLOUDFLARE_ACCOUNT_ID}/${CLOUDFLARE_GATEWAY_ID}/compat", + "apiKeyEnvVar": "CLOUDFLARE_API_TOKEN", + "apiKeyHeader": "Authorization", + "name": "Cloudflare AI Gateway", + "models": [ + "anthropic/claude-3-5-haiku", + "anthropic/claude-3-haiku", + "anthropic/claude-3-opus", + "anthropic/claude-3-sonnet", + "anthropic/claude-3.5-haiku", + "anthropic/claude-3.5-sonnet", + "anthropic/claude-fable-5", + "anthropic/claude-haiku-4-5", + "anthropic/claude-opus-4", + "anthropic/claude-opus-4-1", + "anthropic/claude-opus-4-5", + "anthropic/claude-opus-4-6", + "anthropic/claude-opus-4-7", + "anthropic/claude-opus-4-8", + "anthropic/claude-sonnet-4", + "anthropic/claude-sonnet-4-5", + "anthropic/claude-sonnet-4-6", + "anthropic/claude-sonnet-5", + "openai/gpt-3.5-turbo", + "openai/gpt-4", + "openai/gpt-4-turbo", + "openai/gpt-4o", + "openai/gpt-4o-mini", + "openai/gpt-5.1", + "openai/gpt-5.1-codex", + "openai/gpt-5.2", + "openai/gpt-5.2-codex", + "openai/gpt-5.3-codex", + "openai/gpt-5.4", + "openai/gpt-5.5", + "openai/o1", + "openai/o3", + "openai/o3-mini", + "openai/o3-pro", + "openai/o4-mini", + "workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B", + "workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it", + "workers-ai/@cf/baai/bge-base-en-v1.5", + "workers-ai/@cf/baai/bge-large-en-v1.5", + "workers-ai/@cf/baai/bge-m3", + "workers-ai/@cf/baai/bge-reranker-base", + "workers-ai/@cf/baai/bge-small-en-v1.5", + "workers-ai/@cf/deepgram/aura-2-en", + "workers-ai/@cf/deepgram/aura-2-es", + "workers-ai/@cf/deepgram/nova-3", + "workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", + "workers-ai/@cf/facebook/bart-large-cnn", + "workers-ai/@cf/google/gemma-3-12b-it", + "workers-ai/@cf/huggingface/distilbert-sst-2-int8", + "workers-ai/@cf/ibm-granite/granite-4.0-h-micro", + "workers-ai/@cf/meta/llama-2-7b-chat-fp16", + "workers-ai/@cf/meta/llama-3-8b-instruct", + "workers-ai/@cf/meta/llama-3-8b-instruct-awq", + "workers-ai/@cf/meta/llama-3.1-8b-instruct", + "workers-ai/@cf/meta/llama-3.1-8b-instruct-awq", + "workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8", + "workers-ai/@cf/meta/llama-3.2-11b-vision-instruct", + "workers-ai/@cf/meta/llama-3.2-1b-instruct", + "workers-ai/@cf/meta/llama-3.2-3b-instruct", + "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast", + "workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct", + "workers-ai/@cf/meta/llama-guard-3-8b", + "workers-ai/@cf/meta/m2m100-1.2b", + "workers-ai/@cf/mistral/mistral-7b-instruct-v0.1", + "workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct", + "workers-ai/@cf/moonshotai/kimi-k2.5", + "workers-ai/@cf/moonshotai/kimi-k2.6", + "workers-ai/@cf/myshell-ai/melotts", + "workers-ai/@cf/nvidia/nemotron-3-120b-a12b", + "workers-ai/@cf/openai/gpt-oss-120b", + "workers-ai/@cf/openai/gpt-oss-20b", + "workers-ai/@cf/pfnet/plamo-embedding-1b", + "workers-ai/@cf/pipecat-ai/smart-turn-v2", + "workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct", + "workers-ai/@cf/qwen/qwen3-30b-a3b-fp8", + "workers-ai/@cf/qwen/qwen3-embedding-0.6b", + "workers-ai/@cf/qwen/qwq-32b", + "workers-ai/@cf/zai-org/glm-4.7-flash" + ], + "docUrl": "https://developers.cloudflare.com/ai-gateway/", + "gateway": "models.dev", + "npm": "ai-gateway-provider", + "modelOverrides": { + "openai/gpt-5.3-codex": { + "npm": "ai-gateway-provider" + }, + "openai/gpt-5.4": { + "npm": "ai-gateway-provider" + }, + "openai/gpt-5.2-codex": { + "npm": "ai-gateway-provider" + }, + "anthropic/claude-opus-4-7": { + "npm": "@ai-sdk/anthropic" + }, + "anthropic/claude-sonnet-4-6": { + "npm": "ai-gateway-provider" + } + } + }, "moonshotai-cn": { "url": "https://api.moonshot.cn/anthropic/v1", "apiKeyEnvVar": "MOONSHOT_API_KEY", @@ -3595,6 +3788,39 @@ "gateway": "models.dev", "npm": "@ai-sdk/anthropic" }, + "unorouter": { + "url": "https://api.unorouter.com/v1", + "apiKeyEnvVar": "UNOROUTER_API_KEY", + "apiKeyHeader": "Authorization", + "name": "UnoRouter", + "models": [ + "claude-haiku-4-5-20251001", + "claude-opus-4-8", + "claude-sonnet-5", + "deepseek-v4-flash", + "deepseek-v4-flash:free", + "deepseek-v4-pro", + "deepseek-v4-pro:free", + "gemini-3.5-flash", + "gemma-4-31b-it:free", + "glm-4.5-flash:free", + "glm-5.2", + "glm-5.2:free", + "gpt-5.2", + "gpt-5.4", + "gpt-5.4:free", + "gpt-5.5", + "gpt-5.5:free", + "kimi-k2.6", + "minimax-m2.7", + "minimax-m2.7:free", + "nemotron-3-ultra-550b-a55b:free", + "qwen3.5-397b-a17b:free", + "step-3.7-flash:free" + ], + "docUrl": "https://unorouter.com/models", + "gateway": "models.dev" + }, "alibaba-coding-plan": { "url": "https://coding-intl.dashscope.aliyuncs.com/v1", "apiKeyEnvVar": "ALIBABA_CODING_PLAN_API_KEY", @@ -3986,6 +4212,50 @@ "docUrl": "https://www.scaleway.com/en/docs/generative-apis/", "gateway": "models.dev" }, + "empiriolabs": { + "url": "https://api.empiriolabs.ai/v1", + "apiKeyEnvVar": "EMPIRIOLABS_API_KEY", + "apiKeyHeader": "Authorization", + "name": "EmpirioLabs AI", + "models": [ + "deepseek-v4-flash", + "deepseek-v4-pro", + "fugu-ultra", + "gemma-4-26b-a4b", + "glm-4-5-flash", + "glm-4-7-flash", + "glm-5-1", + "glm-5-2", + "kimi-k2-6", + "kimi-k2-7-code", + "kimi-k2-7-code-highspeed", + "mimo-v2-5", + "mimo-v2-5-pro", + "minimax-m2-7", + "minimax-m2-7-highspeed", + "minimax-m3", + "muse-spark-1-1", + "qwen3-5-122b-a10b", + "qwen3-5-27b", + "qwen3-5-35b-a3b", + "qwen3-5-397b-a17b", + "qwen3-5-4b", + "qwen3-5-9b", + "qwen3-5-plus", + "qwen3-6-27b", + "qwen3-6-flash", + "qwen3-6-max-preview", + "qwen3-6-plus", + "qwen3-7-max", + "qwen3-7-plus", + "qwen3-max", + "step-3-5-flash", + "step-3-5-flash-2603", + "step-3-7-flash" + ], + "docUrl": "https://docs.empiriolabs.ai", + "gateway": "models.dev" + }, "ovhcloud": { "url": "https://oai.endpoints.kepler.ai.cloud.ovh.net/v1", "apiKeyEnvVar": "OVHCLOUD_API_KEY", @@ -4599,7 +4869,6 @@ "anthropic/claude-sonnet-5", "arcee-ai/coder-large", "arcee-ai/trinity-large-thinking", - "arcee-ai/trinity-mini", "arcee-ai/virtuoso-large", "baidu/ernie-4.5-vl-424b-a47b", "bytedance-seed/seed-1.6", @@ -7899,6 +8168,7 @@ "gpt-image-1-mini", "gpt-image-1.5", "gpt-image-2", + "gpt-realtime-2.1", "o1", "o1-pro", "o3", @@ -8350,6 +8620,84 @@ "openai/whisper-large-v3", "zai-org/GLM-5.1-FP8" ], + "pioneer": [ + "HuggingFaceTB/SmolLM3-3B-Base", + "LiquidAI/LFM2-24B-A2B", + "MiniMaxAI/MiniMax-M2.7", + "MiniMaxAI/MiniMax-M3", + "Qwen/Qwen3-1.7B-Base", + "Qwen/Qwen3-32B", + "Qwen/Qwen3-4B-Base", + "Qwen/Qwen3-4B-Instruct-2507", + "Qwen/Qwen3-8B", + "Qwen/Qwen3.5-9B", + "Qwen/Qwen3.6-27B", + "Qwen/Qwen3.6-35B-A3B", + "XiaomiMiMo/MiMo-V2.5", + "XiaomiMiMo/MiMo-V2.5-Pro", + "claude-haiku-4-5", + "claude-opus-4-1", + "claude-opus-4-5", + "claude-opus-4-6", + "claude-opus-4-7", + "claude-opus-4-8", + "claude-sonnet-4-5", + "claude-sonnet-4-6", + "deepseek-ai/DeepSeek-V4-Flash", + "deepseek-ai/DeepSeek-V4-Pro", + "fastino/gliguard-LLMGuardrails-300M", + "fastino/gliner2-base-v1", + "fastino/gliner2-large-v1", + "fastino/gliner2-multi-large-v1", + "fastino/gliner2-multi-v1", + "fastino/gliner2-privacy-filter-PII-multi", + "gemini-3-flash", + "gemini-3.1-pro", + "gemini-3.5-flash", + "google/diffusiongemma-26B-A4B-it", + "google/gemma-3-4b-pt", + "google/gemma-4-12B-it", + "google/gemma-4-31B-it", + "google/gemma-4-E2B-it", + "google/gemma-4-E4B-it", + "gpt-4.1", + "gpt-4.1-mini", + "gpt-4.1-nano", + "gpt-4o", + "gpt-4o-mini", + "gpt-5-mini", + "gpt-5-nano", + "gpt-5.1", + "gpt-5.3-codex", + "gpt-5.4", + "gpt-5.4-mini", + "gpt-5.4-nano", + "gpt-5.5", + "meta-llama/Llama-3.1-8B-Instruct", + "meta-llama/Llama-3.2-1B-Instruct", + "meta-llama/Llama-3.2-3B-Instruct", + "meta-llama/Llama-3.3-70B-Instruct", + "mistral-medium-3.5", + "mistralai/Mistral-7B-Instruct-v0.3", + "mistralai/Mistral-Nemo-Instruct-2407", + "mistralai/Mistral-Small-4-119B-2603", + "moonshotai/Kimi-K2.6", + "moonshotai/Kimi-K2.7-Code", + "nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16", + "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8", + "nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-BF16", + "openai/gpt-oss-120b", + "openai/gpt-oss-20b", + "pioneer/auto", + "qwen3.6-flash", + "qwen3.6-max-preview", + "qwen3.6-plus", + "qwen3.7-max", + "qwen3.7-plus", + "sakana/fugu-ultra", + "zai-org/GLM-5.1", + "zai-org/GLM-5.2" + ], "llmgateway": [ "auto", "claude-3-opus", @@ -8688,6 +9036,86 @@ "qwen3.5:397b", "rnj-1:8b" ], + "cloudflare-ai-gateway": [ + "anthropic/claude-3-5-haiku", + "anthropic/claude-3-haiku", + "anthropic/claude-3-opus", + "anthropic/claude-3-sonnet", + "anthropic/claude-3.5-haiku", + "anthropic/claude-3.5-sonnet", + "anthropic/claude-fable-5", + "anthropic/claude-haiku-4-5", + "anthropic/claude-opus-4", + "anthropic/claude-opus-4-1", + "anthropic/claude-opus-4-5", + "anthropic/claude-opus-4-6", + "anthropic/claude-opus-4-7", + "anthropic/claude-opus-4-8", + "anthropic/claude-sonnet-4", + "anthropic/claude-sonnet-4-5", + "anthropic/claude-sonnet-4-6", + "anthropic/claude-sonnet-5", + "openai/gpt-3.5-turbo", + "openai/gpt-4", + "openai/gpt-4-turbo", + "openai/gpt-4o", + "openai/gpt-4o-mini", + "openai/gpt-5.1", + "openai/gpt-5.1-codex", + "openai/gpt-5.2", + "openai/gpt-5.2-codex", + "openai/gpt-5.3-codex", + "openai/gpt-5.4", + "openai/gpt-5.5", + "openai/o1", + "openai/o3", + "openai/o3-mini", + "openai/o3-pro", + "openai/o4-mini", + "workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B", + "workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it", + "workers-ai/@cf/baai/bge-base-en-v1.5", + "workers-ai/@cf/baai/bge-large-en-v1.5", + "workers-ai/@cf/baai/bge-m3", + "workers-ai/@cf/baai/bge-reranker-base", + "workers-ai/@cf/baai/bge-small-en-v1.5", + "workers-ai/@cf/deepgram/aura-2-en", + "workers-ai/@cf/deepgram/aura-2-es", + "workers-ai/@cf/deepgram/nova-3", + "workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b", + "workers-ai/@cf/facebook/bart-large-cnn", + "workers-ai/@cf/google/gemma-3-12b-it", + "workers-ai/@cf/huggingface/distilbert-sst-2-int8", + "workers-ai/@cf/ibm-granite/granite-4.0-h-micro", + "workers-ai/@cf/meta/llama-2-7b-chat-fp16", + "workers-ai/@cf/meta/llama-3-8b-instruct", + "workers-ai/@cf/meta/llama-3-8b-instruct-awq", + "workers-ai/@cf/meta/llama-3.1-8b-instruct", + "workers-ai/@cf/meta/llama-3.1-8b-instruct-awq", + "workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8", + "workers-ai/@cf/meta/llama-3.2-11b-vision-instruct", + "workers-ai/@cf/meta/llama-3.2-1b-instruct", + "workers-ai/@cf/meta/llama-3.2-3b-instruct", + "workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast", + "workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct", + "workers-ai/@cf/meta/llama-guard-3-8b", + "workers-ai/@cf/meta/m2m100-1.2b", + "workers-ai/@cf/mistral/mistral-7b-instruct-v0.1", + "workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct", + "workers-ai/@cf/moonshotai/kimi-k2.5", + "workers-ai/@cf/moonshotai/kimi-k2.6", + "workers-ai/@cf/myshell-ai/melotts", + "workers-ai/@cf/nvidia/nemotron-3-120b-a12b", + "workers-ai/@cf/openai/gpt-oss-120b", + "workers-ai/@cf/openai/gpt-oss-20b", + "workers-ai/@cf/pfnet/plamo-embedding-1b", + "workers-ai/@cf/pipecat-ai/smart-turn-v2", + "workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct", + "workers-ai/@cf/qwen/qwen3-30b-a3b-fp8", + "workers-ai/@cf/qwen/qwen3-embedding-0.6b", + "workers-ai/@cf/qwen/qwq-32b", + "workers-ai/@cf/zai-org/glm-4.7-flash" + ], "moonshotai-cn": [ "kimi-k2-0711-preview", "kimi-k2-0905-preview", @@ -8991,6 +9419,31 @@ "MiniMax-M2.7-highspeed", "MiniMax-M3" ], + "unorouter": [ + "claude-haiku-4-5-20251001", + "claude-opus-4-8", + "claude-sonnet-5", + "deepseek-v4-flash", + "deepseek-v4-flash:free", + "deepseek-v4-pro", + "deepseek-v4-pro:free", + "gemini-3.5-flash", + "gemma-4-31b-it:free", + "glm-4.5-flash:free", + "glm-5.2", + "glm-5.2:free", + "gpt-5.2", + "gpt-5.4", + "gpt-5.4:free", + "gpt-5.5", + "gpt-5.5:free", + "kimi-k2.6", + "minimax-m2.7", + "minimax-m2.7:free", + "nemotron-3-ultra-550b-a55b:free", + "qwen3.5-397b-a17b:free", + "step-3.7-flash:free" + ], "alibaba-coding-plan": [ "MiniMax-M2.5", "glm-4.7", @@ -9276,6 +9729,42 @@ "voxtral-small-24b-2507", "whisper-large-v3" ], + "empiriolabs": [ + "deepseek-v4-flash", + "deepseek-v4-pro", + "fugu-ultra", + "gemma-4-26b-a4b", + "glm-4-5-flash", + "glm-4-7-flash", + "glm-5-1", + "glm-5-2", + "kimi-k2-6", + "kimi-k2-7-code", + "kimi-k2-7-code-highspeed", + "mimo-v2-5", + "mimo-v2-5-pro", + "minimax-m2-7", + "minimax-m2-7-highspeed", + "minimax-m3", + "muse-spark-1-1", + "qwen3-5-122b-a10b", + "qwen3-5-27b", + "qwen3-5-35b-a3b", + "qwen3-5-397b-a17b", + "qwen3-5-4b", + "qwen3-5-9b", + "qwen3-5-plus", + "qwen3-6-27b", + "qwen3-6-flash", + "qwen3-6-max-preview", + "qwen3-6-plus", + "qwen3-7-max", + "qwen3-7-plus", + "qwen3-max", + "step-3-5-flash", + "step-3-5-flash-2603", + "step-3-7-flash" + ], "ovhcloud": [ "gpt-oss-120b", "gpt-oss-20b", @@ -9791,7 +10280,6 @@ "anthropic/claude-sonnet-5", "arcee-ai/coder-large", "arcee-ai/trinity-large-thinking", - "arcee-ai/trinity-mini", "arcee-ai/virtuoso-large", "baidu/ernie-4.5-vl-424b-a47b", "bytedance-seed/seed-1.6", diff --git a/packages/core/src/llm/model/provider-types.generated.d.ts b/packages/core/src/llm/model/provider-types.generated.d.ts index f2d762703a20..4f47aa069bd7 100644 --- a/packages/core/src/llm/model/provider-types.generated.d.ts +++ b/packages/core/src/llm/model/provider-types.generated.d.ts @@ -1506,6 +1506,7 @@ export type ProviderModelsMap = { 'gpt-image-1-mini', 'gpt-image-1.5', 'gpt-image-2', + 'gpt-realtime-2.1', 'o1', 'o1-pro', 'o3', @@ -1957,6 +1958,84 @@ export type ProviderModelsMap = { 'openai/whisper-large-v3', 'zai-org/GLM-5.1-FP8', ]; + readonly pioneer: readonly [ + 'HuggingFaceTB/SmolLM3-3B-Base', + 'LiquidAI/LFM2-24B-A2B', + 'MiniMaxAI/MiniMax-M2.7', + 'MiniMaxAI/MiniMax-M3', + 'Qwen/Qwen3-1.7B-Base', + 'Qwen/Qwen3-32B', + 'Qwen/Qwen3-4B-Base', + 'Qwen/Qwen3-4B-Instruct-2507', + 'Qwen/Qwen3-8B', + 'Qwen/Qwen3.5-9B', + 'Qwen/Qwen3.6-27B', + 'Qwen/Qwen3.6-35B-A3B', + 'XiaomiMiMo/MiMo-V2.5', + 'XiaomiMiMo/MiMo-V2.5-Pro', + 'claude-haiku-4-5', + 'claude-opus-4-1', + 'claude-opus-4-5', + 'claude-opus-4-6', + 'claude-opus-4-7', + 'claude-opus-4-8', + 'claude-sonnet-4-5', + 'claude-sonnet-4-6', + 'deepseek-ai/DeepSeek-V4-Flash', + 'deepseek-ai/DeepSeek-V4-Pro', + 'fastino/gliguard-LLMGuardrails-300M', + 'fastino/gliner2-base-v1', + 'fastino/gliner2-large-v1', + 'fastino/gliner2-multi-large-v1', + 'fastino/gliner2-multi-v1', + 'fastino/gliner2-privacy-filter-PII-multi', + 'gemini-3-flash', + 'gemini-3.1-pro', + 'gemini-3.5-flash', + 'google/diffusiongemma-26B-A4B-it', + 'google/gemma-3-4b-pt', + 'google/gemma-4-12B-it', + 'google/gemma-4-31B-it', + 'google/gemma-4-E2B-it', + 'google/gemma-4-E4B-it', + 'gpt-4.1', + 'gpt-4.1-mini', + 'gpt-4.1-nano', + 'gpt-4o', + 'gpt-4o-mini', + 'gpt-5-mini', + 'gpt-5-nano', + 'gpt-5.1', + 'gpt-5.3-codex', + 'gpt-5.4', + 'gpt-5.4-mini', + 'gpt-5.4-nano', + 'gpt-5.5', + 'meta-llama/Llama-3.1-8B-Instruct', + 'meta-llama/Llama-3.2-1B-Instruct', + 'meta-llama/Llama-3.2-3B-Instruct', + 'meta-llama/Llama-3.3-70B-Instruct', + 'mistral-medium-3.5', + 'mistralai/Mistral-7B-Instruct-v0.3', + 'mistralai/Mistral-Nemo-Instruct-2407', + 'mistralai/Mistral-Small-4-119B-2603', + 'moonshotai/Kimi-K2.6', + 'moonshotai/Kimi-K2.7-Code', + 'nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B-BF16', + 'nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-FP8', + 'nvidia/NVIDIA-Nemotron-3-Ultra-550B-A55B-BF16', + 'openai/gpt-oss-120b', + 'openai/gpt-oss-20b', + 'pioneer/auto', + 'qwen3.6-flash', + 'qwen3.6-max-preview', + 'qwen3.6-plus', + 'qwen3.7-max', + 'qwen3.7-plus', + 'sakana/fugu-ultra', + 'zai-org/GLM-5.1', + 'zai-org/GLM-5.2', + ]; readonly llmgateway: readonly [ 'auto', 'claude-3-opus', @@ -2295,6 +2374,86 @@ export type ProviderModelsMap = { 'qwen3.5:397b', 'rnj-1:8b', ]; + readonly 'cloudflare-ai-gateway': readonly [ + 'anthropic/claude-3-5-haiku', + 'anthropic/claude-3-haiku', + 'anthropic/claude-3-opus', + 'anthropic/claude-3-sonnet', + 'anthropic/claude-3.5-haiku', + 'anthropic/claude-3.5-sonnet', + 'anthropic/claude-fable-5', + 'anthropic/claude-haiku-4-5', + 'anthropic/claude-opus-4', + 'anthropic/claude-opus-4-1', + 'anthropic/claude-opus-4-5', + 'anthropic/claude-opus-4-6', + 'anthropic/claude-opus-4-7', + 'anthropic/claude-opus-4-8', + 'anthropic/claude-sonnet-4', + 'anthropic/claude-sonnet-4-5', + 'anthropic/claude-sonnet-4-6', + 'anthropic/claude-sonnet-5', + 'openai/gpt-3.5-turbo', + 'openai/gpt-4', + 'openai/gpt-4-turbo', + 'openai/gpt-4o', + 'openai/gpt-4o-mini', + 'openai/gpt-5.1', + 'openai/gpt-5.1-codex', + 'openai/gpt-5.2', + 'openai/gpt-5.2-codex', + 'openai/gpt-5.3-codex', + 'openai/gpt-5.4', + 'openai/gpt-5.5', + 'openai/o1', + 'openai/o3', + 'openai/o3-mini', + 'openai/o3-pro', + 'openai/o4-mini', + 'workers-ai/@cf/ai4bharat/indictrans2-en-indic-1B', + 'workers-ai/@cf/aisingapore/gemma-sea-lion-v4-27b-it', + 'workers-ai/@cf/baai/bge-base-en-v1.5', + 'workers-ai/@cf/baai/bge-large-en-v1.5', + 'workers-ai/@cf/baai/bge-m3', + 'workers-ai/@cf/baai/bge-reranker-base', + 'workers-ai/@cf/baai/bge-small-en-v1.5', + 'workers-ai/@cf/deepgram/aura-2-en', + 'workers-ai/@cf/deepgram/aura-2-es', + 'workers-ai/@cf/deepgram/nova-3', + 'workers-ai/@cf/deepseek-ai/deepseek-r1-distill-qwen-32b', + 'workers-ai/@cf/facebook/bart-large-cnn', + 'workers-ai/@cf/google/gemma-3-12b-it', + 'workers-ai/@cf/huggingface/distilbert-sst-2-int8', + 'workers-ai/@cf/ibm-granite/granite-4.0-h-micro', + 'workers-ai/@cf/meta/llama-2-7b-chat-fp16', + 'workers-ai/@cf/meta/llama-3-8b-instruct', + 'workers-ai/@cf/meta/llama-3-8b-instruct-awq', + 'workers-ai/@cf/meta/llama-3.1-8b-instruct', + 'workers-ai/@cf/meta/llama-3.1-8b-instruct-awq', + 'workers-ai/@cf/meta/llama-3.1-8b-instruct-fp8', + 'workers-ai/@cf/meta/llama-3.2-11b-vision-instruct', + 'workers-ai/@cf/meta/llama-3.2-1b-instruct', + 'workers-ai/@cf/meta/llama-3.2-3b-instruct', + 'workers-ai/@cf/meta/llama-3.3-70b-instruct-fp8-fast', + 'workers-ai/@cf/meta/llama-4-scout-17b-16e-instruct', + 'workers-ai/@cf/meta/llama-guard-3-8b', + 'workers-ai/@cf/meta/m2m100-1.2b', + 'workers-ai/@cf/mistral/mistral-7b-instruct-v0.1', + 'workers-ai/@cf/mistralai/mistral-small-3.1-24b-instruct', + 'workers-ai/@cf/moonshotai/kimi-k2.5', + 'workers-ai/@cf/moonshotai/kimi-k2.6', + 'workers-ai/@cf/myshell-ai/melotts', + 'workers-ai/@cf/nvidia/nemotron-3-120b-a12b', + 'workers-ai/@cf/openai/gpt-oss-120b', + 'workers-ai/@cf/openai/gpt-oss-20b', + 'workers-ai/@cf/pfnet/plamo-embedding-1b', + 'workers-ai/@cf/pipecat-ai/smart-turn-v2', + 'workers-ai/@cf/qwen/qwen2.5-coder-32b-instruct', + 'workers-ai/@cf/qwen/qwen3-30b-a3b-fp8', + 'workers-ai/@cf/qwen/qwen3-embedding-0.6b', + 'workers-ai/@cf/qwen/qwq-32b', + 'workers-ai/@cf/zai-org/glm-4.7-flash', + ]; readonly 'moonshotai-cn': readonly [ 'kimi-k2-0711-preview', 'kimi-k2-0905-preview', @@ -2598,6 +2757,31 @@ export type ProviderModelsMap = { 'MiniMax-M2.7-highspeed', 'MiniMax-M3', ]; + readonly unorouter: readonly [ + 'claude-haiku-4-5-20251001', + 'claude-opus-4-8', + 'claude-sonnet-5', + 'deepseek-v4-flash', + 'deepseek-v4-flash:free', + 'deepseek-v4-pro', + 'deepseek-v4-pro:free', + 'gemini-3.5-flash', + 'gemma-4-31b-it:free', + 'glm-4.5-flash:free', + 'glm-5.2', + 'glm-5.2:free', + 'gpt-5.2', + 'gpt-5.4', + 'gpt-5.4:free', + 'gpt-5.5', + 'gpt-5.5:free', + 'kimi-k2.6', + 'minimax-m2.7', + 'minimax-m2.7:free', + 'nemotron-3-ultra-550b-a55b:free', + 'qwen3.5-397b-a17b:free', + 'step-3.7-flash:free', + ]; readonly 'alibaba-coding-plan': readonly [ 'MiniMax-M2.5', 'glm-4.7', @@ -2883,6 +3067,42 @@ export type ProviderModelsMap = { 'voxtral-small-24b-2507', 'whisper-large-v3', ]; + readonly empiriolabs: readonly [ + 'deepseek-v4-flash', + 'deepseek-v4-pro', + 'fugu-ultra', + 'gemma-4-26b-a4b', + 'glm-4-5-flash', + 'glm-4-7-flash', + 'glm-5-1', + 'glm-5-2', + 'kimi-k2-6', + 'kimi-k2-7-code', + 'kimi-k2-7-code-highspeed', + 'mimo-v2-5', + 'mimo-v2-5-pro', + 'minimax-m2-7', + 'minimax-m2-7-highspeed', + 'minimax-m3', + 'muse-spark-1-1', + 'qwen3-5-122b-a10b', + 'qwen3-5-27b', + 'qwen3-5-35b-a3b', + 'qwen3-5-397b-a17b', + 'qwen3-5-4b', + 'qwen3-5-9b', + 'qwen3-5-plus', + 'qwen3-6-27b', + 'qwen3-6-flash', + 'qwen3-6-max-preview', + 'qwen3-6-plus', + 'qwen3-7-max', + 'qwen3-7-plus', + 'qwen3-max', + 'step-3-5-flash', + 'step-3-5-flash-2603', + 'step-3-7-flash', + ]; readonly ovhcloud: readonly [ 'gpt-oss-120b', 'gpt-oss-20b', @@ -3398,7 +3618,6 @@ export type ProviderModelsMap = { 'anthropic/claude-sonnet-5', 'arcee-ai/coder-large', 'arcee-ai/trinity-large-thinking', - 'arcee-ai/trinity-mini', 'arcee-ai/virtuoso-large', 'baidu/ernie-4.5-vl-424b-a47b', 'bytedance-seed/seed-1.6', From ebd7d2700fdc44a52c4f5803270c988194dba979 Mon Sep 17 00:00:00 2001 From: Brennan McEachran Date: Fri, 10 Jul 2026 18:22:01 -0400 Subject: [PATCH 2/2] fix: address review feedback on Cloudflare AI Gateway integration - Drop models.dev per-model npm hints for cloudflare-ai-gateway via PROVIDER_OVERRIDES so every model stays on the OpenAI-compatible /compat endpoint (claude-opus-4-7 carried an @ai-sdk/anthropic hint that would have routed it through the wrong SDK protocol); regression test added - Use the evergreen __GATEWAY_ANTHROPIC_MODEL_HAIKU__ token in the generated gateway usage example - Sanitize the empty-provider env-var fallback in the docs generator - Add a usage example to the changeset Co-Authored-By: Claude Fable 5 --- .changeset/cloudflare-ai-gateway-provider.md | 13 ++++++++++++- .../models/gateways/cloudflare-ai-gateway.mdx | 2 +- packages/core/scripts/generate-model-docs.ts | 13 +++++++++++-- .../src/llm/model/gateways/models-dev.test.ts | 12 +++++++++++- .../core/src/llm/model/gateways/models-dev.ts | 11 +++++++++-- .../core/src/llm/model/provider-registry.json | 19 +------------------ 6 files changed, 45 insertions(+), 25 deletions(-) diff --git a/.changeset/cloudflare-ai-gateway-provider.md b/.changeset/cloudflare-ai-gateway-provider.md index 69312ff82fd3..67b6f63510f2 100644 --- a/.changeset/cloudflare-ai-gateway-provider.md +++ b/.changeset/cloudflare-ai-gateway-provider.md @@ -2,4 +2,15 @@ '@mastra/core': patch --- -Add Cloudflare AI Gateway to the model router. Model strings like `cloudflare-ai-gateway/anthropic/claude-3-5-haiku` now route through Cloudflare's OpenAI-compatible endpoint, configured via `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_GATEWAY_ID`, and `CLOUDFLARE_API_TOKEN`. Provider API keys are managed in the Cloudflare dashboard (BYOK) or via Unified Billing. +Add Cloudflare AI Gateway to the model router. Model strings route through Cloudflare's OpenAI-compatible endpoint, configured via `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_GATEWAY_ID`, and `CLOUDFLARE_API_TOKEN`. Provider API keys are managed in the Cloudflare dashboard (BYOK) or via Unified Billing. + +```ts +import { Agent } from '@mastra/core/agent'; + +const agent = new Agent({ + id: 'my-agent', + name: 'My Agent', + instructions: 'You are a helpful assistant', + model: 'cloudflare-ai-gateway/anthropic/claude-haiku-4-5', +}); +``` diff --git a/docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx b/docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx index e40f0c8b9897..6fffa7dfc511 100644 --- a/docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx +++ b/docs/src/content/en/models/gateways/cloudflare-ai-gateway.mdx @@ -22,7 +22,7 @@ const agent = new Agent({ id: "my-agent", name: "My Agent", instructions: "You are a helpful assistant", - model: "cloudflare-ai-gateway/anthropic/claude-3-5-haiku" + model: "cloudflare-ai-gateway/__GATEWAY_ANTHROPIC_MODEL_HAIKU__" }); ``` diff --git a/packages/core/scripts/generate-model-docs.ts b/packages/core/scripts/generate-model-docs.ts index 0c371a31a2a1..ab8e05e726bb 100644 --- a/packages/core/scripts/generate-model-docs.ts +++ b/packages/core/scripts/generate-model-docs.ts @@ -571,7 +571,14 @@ const agent = new Agent({ id: "my-agent", name: "My Agent", instructions: "You are a helpful assistant", - model: "${gatewayName}/${providers[0]?.models[0] || 'model-name'}" + model: "${gatewayName}/${ + // Prefer an evergreen model token (substituted at docs build time by the + // remark-model-tokens plugin) over the first catalog entry when the + // gateway carries a model matching the token's current value. + gatewayName === 'cloudflare-ai-gateway' + ? '__GATEWAY_ANTHROPIC_MODEL_HAIKU__' + : providers[0]?.models[0] || 'model-name' + }" }); \`\`\` @@ -587,7 +594,9 @@ Mastra uses the OpenAI-compatible \`/chat/completions\` endpoint. Some provider- # Use gateway API key ${(() => { const provider = providers[0]; - const envVars = provider ? getRequiredEnvVars(provider) : [`${gatewayName.toUpperCase()}_API_KEY`]; + const envVars = provider + ? getRequiredEnvVars(provider) + : [`${gatewayName.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_API_KEY`]; return envVars.map(v => `${v}=your-${v.toLowerCase().replace(/_/g, '-')}`).join('\n'); })()} ${ diff --git a/packages/core/src/llm/model/gateways/models-dev.test.ts b/packages/core/src/llm/model/gateways/models-dev.test.ts index df4e6833dad0..f116eaddfda2 100644 --- a/packages/core/src/llm/model/gateways/models-dev.test.ts +++ b/packages/core/src/llm/model/gateways/models-dev.test.ts @@ -153,6 +153,9 @@ describe('ModelsDevGateway', () => { name: 'Cloudflare AI Gateway', models: { 'anthropic/claude-3-5-haiku': { name: 'Claude 3.5 Haiku' }, + // models.dev ships a per-model npm hint here that must NOT become a + // modelOverride - it would route this model off the /compat endpoint + 'anthropic/claude-opus-4-7': { name: 'Claude Opus 4.7', provider: { npm: '@ai-sdk/anthropic' } }, 'openai/gpt-4o': { name: 'GPT-4o' }, }, env: ['CLOUDFLARE_API_TOKEN', 'CLOUDFLARE_ACCOUNT_ID', 'CLOUDFLARE_GATEWAY_ID'], @@ -224,7 +227,14 @@ describe('ModelsDevGateway', () => { ); // The account and gateway IDs are URL template inputs, not auth expect(providers['cloudflare-ai-gateway'].apiKeyEnvVar).toBe('CLOUDFLARE_API_TOKEN'); - expect(providers['cloudflare-ai-gateway'].models).toEqual(['anthropic/claude-3-5-haiku', 'openai/gpt-4o']); + expect(providers['cloudflare-ai-gateway'].models).toEqual([ + 'anthropic/claude-3-5-haiku', + 'anthropic/claude-opus-4-7', + 'openai/gpt-4o', + ]); + // models.dev per-model npm hints are dropped: every model must stay on + // the OpenAI-compatible /compat endpoint + expect(providers['cloudflare-ai-gateway'].modelOverrides).toBeUndefined(); }); it('should preserve Google legacy API key fallback when generating providers', async () => { diff --git a/packages/core/src/llm/model/gateways/models-dev.ts b/packages/core/src/llm/model/gateways/models-dev.ts index f226d5c721e3..d35b90faa952 100644 --- a/packages/core/src/llm/model/gateways/models-dev.ts +++ b/packages/core/src/llm/model/gateways/models-dev.ts @@ -115,9 +115,13 @@ const PROVIDER_OVERRIDES: Record> = { // endpoint is account-scoped. Route through its OpenAI-compatible endpoint, // interpolating the account and gateway from env vars. Auth must be the API // token; the other env vars are consumed by the URL template. + // modelOverrides is cleared because models.dev carries per-model npm + // installation hints (e.g. `@ai-sdk/anthropic`) that would route those + // models off the uniform OpenAI-compatible endpoint. 'cloudflare-ai-gateway': { url: 'https://gateway.ai.cloudflare.com/v1/${CLOUDFLARE_ACCOUNT_ID}/${CLOUDFLARE_GATEWAY_ID}/compat', apiKeyEnvVar: 'CLOUDFLARE_API_TOKEN', + modelOverrides: {}, }, }; @@ -192,13 +196,16 @@ export class ModelsDevGateway extends MastraModelGateway { // Collect per-model endpoint/shape/SDK overrides. Some providers serve // individual models over a different endpoint or request shape than the // provider default (e.g. OpenAI Responses vs chat-completions). - const modelOverrides: Record = {}; + // PROVIDER_OVERRIDES takes priority so a provider can opt out of + // models.dev per-model hints entirely. + const collectedModelOverrides: Record = {}; for (const [modelId, modelInfo] of activeModels) { const ov = modelInfo?.provider; if (ov && (ov.api || ov.shape || ov.npm)) { - modelOverrides[modelId] = { api: ov.api, shape: ov.shape, npm: ov.npm }; + collectedModelOverrides[modelId] = { api: ov.api, shape: ov.shape, npm: ov.npm }; } } + const modelOverrides = PROVIDER_OVERRIDES[normalizedId]?.modelOverrides ?? collectedModelOverrides; // Get the API URL - overrides take priority over models.dev data const url = PROVIDER_OVERRIDES[normalizedId]?.url || providerInfo.api; diff --git a/packages/core/src/llm/model/provider-registry.json b/packages/core/src/llm/model/provider-registry.json index 123562a1f6e9..4731c7067309 100644 --- a/packages/core/src/llm/model/provider-registry.json +++ b/packages/core/src/llm/model/provider-registry.json @@ -3151,24 +3151,7 @@ ], "docUrl": "https://developers.cloudflare.com/ai-gateway/", "gateway": "models.dev", - "npm": "ai-gateway-provider", - "modelOverrides": { - "openai/gpt-5.3-codex": { - "npm": "ai-gateway-provider" - }, - "openai/gpt-5.4": { - "npm": "ai-gateway-provider" - }, - "openai/gpt-5.2-codex": { - "npm": "ai-gateway-provider" - }, - "anthropic/claude-opus-4-7": { - "npm": "@ai-sdk/anthropic" - }, - "anthropic/claude-sonnet-4-6": { - "npm": "ai-gateway-provider" - } - } + "npm": "ai-gateway-provider" }, "moonshotai-cn": { "url": "https://api.moonshot.cn/anthropic/v1",