Files
WeHub Mirror 6bf8bebf51
CI / Test and Build (push) Failing after 1s
CI / Migrate Dev DB (push) Has been skipped
CI / Migrate DB (push) Has been skipped
CodeQL / Analyze actions (push) Has been cancelled
CodeQL / Analyze javascript-typescript (push) Has been cancelled
CI / Detect Version (push) Has been cancelled
CI / Detect Desktop Changes (push) Has been cancelled
CI / Build AMD64 (blacksmith-2vcpu-ubuntu-2404, ./docker/cron.Dockerfile, ubuntu-latest, ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Build AMD64 (blacksmith-2vcpu-ubuntu-2404, ./docker/db.Dockerfile, ECR_MIGRATIONS, ubuntu-latest, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (blacksmith-4vcpu-ubuntu-2404, ./docker/pii.Dockerfile, ECR_PII, ubuntu-latest, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (blacksmith-4vcpu-ubuntu-2404, ./docker/realtime.Dockerfile, ECR_REALTIME, ubuntu-latest, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build AMD64 (blacksmith-8vcpu-ubuntu-2404, ./docker/app.Dockerfile, ECR_APP, linux-x64-8-core, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/cron.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/db.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/pii.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-4vcpu-ubuntu-2404-arm, ./docker/realtime.Dockerfile, ubuntu-24.04-arm, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (blacksmith-8vcpu-ubuntu-2404-arm, ./docker/app.Dockerfile, linux-arm64-8-core, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
Helm Chart / Lint, test, and validate chart (push) Has been cancelled
Helm Chart / Chart version bumped (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Build Dev ECR (blacksmith-8vcpu-ubuntu-2404, ./docker/app.Dockerfile, ECR_APP, linux-x64-8-core) (push) Has been cancelled
CI / Promote Images (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/cron) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-2vcpu-ubuntu-2404, ./docker/db.Dockerfile, ECR_MIGRATIONS, ubuntu-latest) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-4vcpu-ubuntu-2404, ./docker/pii.Dockerfile, ECR_PII, ubuntu-latest) (push) Has been cancelled
CI / Build Dev ECR (blacksmith-4vcpu-ubuntu-2404, ./docker/realtime.Dockerfile, ECR_REALTIME, ubuntu-latest) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Check Desktop Signing Secrets (push) Has been cancelled
CI / Desktop Release (push) Has been cancelled
CI / Create Desktop Prerelease (push) Has been cancelled
CI / Desktop Prerelease Build (push) Has been cancelled
CI / Publish Desktop Prerelease (push) Has been cancelled
CI / Prune Desktop Prereleases (push) Has been cancelled
Helm Chart / Install on kind and run helm test (push) Has been cancelled
WeHub snapshot of cb28d14c6f2c081de7a0d8729a8c816c9adef67a
2026-08-10 11:17:50 +08:00

4712 lines
123 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Comprehensive provider definitions - Single source of truth
* This file contains all provider and model information including:
* - Model lists
* - Pricing information
* - Model capabilities (temperature support, etc.)
* - Provider configurations
*/
import type React from 'react'
import {
AnthropicIcon,
AzureIcon,
BasetenIcon,
BedrockIcon,
CerebrasIcon,
DeepseekIcon,
FireworksIcon,
GeminiIcon,
GroqIcon,
KimiIcon,
LitellmIcon,
MetaIcon,
MistralIcon,
NvidiaIcon,
OllamaIcon,
OpenAIIcon,
OpenRouterIcon,
SakanaIcon,
TogetherIcon,
VertexIcon,
VllmIcon,
xAIIcon,
ZaiIcon,
} from '@/components/icons'
import { LARGE_VALUE_THRESHOLD_BYTES } from '@/lib/execution/payloads/large-value-ref'
import type { ModelPricing, ProviderId } from '@/providers/types'
/** How a model's thinking appears on the agent-events stream. */
export type ThinkingStreamVisibility = 'full' | 'summary' | 'none'
export interface ModelCapabilities {
temperature?: {
min: number
max: number
}
toolUsageControl?: boolean
computerUse?: boolean
nativeStructuredOutputs?: boolean
/** Maximum supported output tokens for this model */
maxOutputTokens?: number
reasoningEffort?: {
values: string[]
}
verbosity?: {
values: string[]
}
/**
* Model accepts caller-placed prompt-cache breakpoints, so caching is a real
* opt-in with a cost tradeoff (writes carry a premium over base input).
*
* Absent for providers whose caching is automatic and free — OpenAI and
* Gemini implicit caching need no switch, and exposing one would imply a
* control that does not exist.
*/
promptCaching?: {
/** Prefixes shorter than this are silently not cached by the vendor. */
minimumCacheableTokens: number
}
thinking?: {
levels: string[]
default?: string
/**
* What this model's thinking looks like on the agent-events stream:
* `full` raw thinking deltas, `summary` summaries only, or `none` (the
* provider withholds thinking text entirely, e.g. the newest Claude
* models default to omitted thinking display). Anthropic-family models
* must set this explicitly since visibility varies per model generation —
* `bun run agent-stream-docs:check` enforces it. Other families fall back
* to the per-provider defaults in {@link getThinkingStreamVisibility}.
*/
streamed?: ThinkingStreamVisibility
}
deepResearch?: boolean
/** Whether this model supports conversation memory. Defaults to true if omitted. */
memory?: boolean
}
interface ModelDefinition {
id: string
pricing: ModelPricing
capabilities: ModelCapabilities
contextWindow?: number
/** ISO date string (YYYY-MM-DD) when the model was first publicly released */
releaseDate?: string
recommended?: boolean
speedOptimized?: boolean
/**
* Post-availability lifecycle, mirroring `BlockConfig.sunset`. `legacy` —
* superseded but still callable (amber); `deprecated` — the provider retired
* it and API calls now fail (red). `deprecated` models are hidden from pickers
* but stay {@link isKnownModelId} so existing pinned workflows still validate.
*/
sunset?: {
status: 'legacy' | 'deprecated'
}
}
export interface ProviderDefinition {
id: string
name: string
description: string
models: ModelDefinition[]
defaultModel: string
modelPatterns?: RegExp[]
icon?: React.ComponentType<{ className?: string }>
/** Brand color used in charts and visualizations (hex string) */
color?: string
/** True when this provider re-hosts other providers' models (e.g. Azure, Bedrock, OpenRouter) */
isReseller?: boolean
capabilities?: ModelCapabilities
contextInformationAvailable?: boolean
/** Agent-block file attachment limit and large-file delivery for this provider. */
fileAttachment?: ProviderFileAttachment
}
/**
* How a provider accepts agent-block attachments larger than the inline base64 threshold:
* `files-api` uploads to the provider Files API, `remote-url` passes a signed URL the
* provider fetches itself, `inline` means base64-only (no large-file path).
*/
export type ProviderFileAttachmentStrategy = 'inline' | 'files-api' | 'remote-url'
export interface ProviderFileAttachment {
/** Maximum size of a single attachment the provider accepts, in bytes. */
maxBytes: number
strategy: ProviderFileAttachmentStrategy
}
/** Inline base64 attachment cap, also the fallback limit for providers without a large-file path. */
export const INLINE_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024
/**
* Size above which an attachment should prefer the provider's Files API over base64, when the
* deployment can reach one.
*
* Set by the execution payload store, not by any provider. Base64 inflates bytes by 4/3 and a
* single stored value may not exceed {@link LARGE_VALUE_THRESHOLD_BYTES}, so past three quarters
* of that ceiling the encoded copy no longer fits the cache. Inlining still succeeds above this
* point — the cache write is skipped, not fatal — but it carries a needlessly large encoded
* payload, so an upload is preferred wherever one is available.
*/
export const LARGE_FILE_PATH_THRESHOLD_BYTES = Math.floor(LARGE_VALUE_THRESHOLD_BYTES / 4) * 3
const DEFAULT_FILE_ATTACHMENT: ProviderFileAttachment = {
maxBytes: INLINE_ATTACHMENT_MAX_BYTES,
strategy: 'inline',
}
/** Provider-level attachment limit + strategy, keyed on the granular provider id. */
export function getProviderFileAttachment(providerId: string): ProviderFileAttachment {
return PROVIDER_DEFINITIONS[providerId]?.fileAttachment ?? DEFAULT_FILE_ATTACHMENT
}
export const PROVIDER_DEFINITIONS: Record<string, ProviderDefinition> = {
fireworks: {
id: 'fireworks',
name: 'Fireworks',
description: 'Fast inference for open-source models via Fireworks AI',
defaultModel: '',
modelPatterns: [/^fireworks\//],
icon: FireworksIcon,
color: '#FF6D3A',
isReseller: true,
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
contextInformationAvailable: false,
/**
* Static Fireworks serverless entries: the sim-auto routing pool. These are
* hosted-billable (platform FIREWORKS_API_KEY) and priced at the Fireworks
* serverless rate, which differs from the vendors' native rates. Text-only:
* the Fireworks serving endpoints reject image inputs. User-configured
* `fireworks/<anything-else>` ids remain dynamic/BYO-key as before.
*/
models: [
{
id: 'fireworks/glm-5.2',
pricing: {
input: 1.4,
cachedInput: 0.14,
output: 4.4,
updatedAt: '2026-07-29',
},
capabilities: {
toolUsageControl: true,
maxOutputTokens: 131072,
},
contextWindow: 1048576,
releaseDate: '2026-06-13',
recommended: true,
},
{
id: 'fireworks/kimi-k3',
pricing: {
input: 3.0,
cachedInput: 0.3,
output: 15.0,
updatedAt: '2026-07-29',
},
capabilities: {
toolUsageControl: true,
maxOutputTokens: 1048576,
},
contextWindow: 1048576,
releaseDate: '2026-07-16',
recommended: true,
},
],
},
together: {
id: 'together',
fileAttachment: { maxBytes: 50 * 1024 * 1024, strategy: 'remote-url' },
name: 'Together AI',
description: 'Fast inference for open-source models via Together AI',
defaultModel: '',
modelPatterns: [/^together\//],
icon: TogetherIcon,
color: '#EF2CC1',
isReseller: true,
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
},
contextInformationAvailable: false,
models: [],
},
baseten: {
id: 'baseten',
fileAttachment: { maxBytes: 25 * 1024 * 1024, strategy: 'remote-url' },
name: 'Baseten',
description: 'Fast inference for open-source models via Baseten Model APIs',
defaultModel: '',
modelPatterns: [/^baseten\//],
icon: BasetenIcon,
color: '#1A1A2E',
isReseller: true,
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
contextInformationAvailable: false,
models: [],
},
openrouter: {
id: 'openrouter',
fileAttachment: { maxBytes: 50 * 1024 * 1024, strategy: 'remote-url' },
name: 'OpenRouter',
description: 'Unified access to many models via OpenRouter',
defaultModel: '',
modelPatterns: [/^openrouter\//],
icon: OpenRouterIcon,
isReseller: true,
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
contextInformationAvailable: false,
models: [],
},
'ollama-cloud': {
id: 'ollama-cloud',
name: 'Ollama Cloud',
description: 'Hosted open-source models via Ollama Cloud (bring your own key)',
defaultModel: '',
modelPatterns: [/^ollama-cloud\//],
icon: OllamaIcon,
isReseller: true,
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: false,
},
contextInformationAvailable: false,
models: [],
},
vllm: {
id: 'vllm',
fileAttachment: { maxBytes: 25 * 1024 * 1024, strategy: 'remote-url' },
name: 'vLLM',
icon: VllmIcon,
description: 'Self-hosted vLLM with an OpenAI-compatible API',
defaultModel: 'vllm/generic',
modelPatterns: [/^vllm\//],
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
models: [],
},
litellm: {
id: 'litellm',
name: 'LiteLLM',
icon: LitellmIcon,
color: '#040229',
description: 'LiteLLM proxy with an OpenAI-compatible API',
defaultModel: '',
modelPatterns: [/^litellm\//],
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
models: [],
},
openai: {
id: 'openai',
/** "each file must be under 50 MB" — decimal MB; OpenAI writes no MiB anywhere on that page. */
fileAttachment: { maxBytes: 50_000_000, strategy: 'files-api' },
name: 'OpenAI',
description: "OpenAI's models",
defaultModel: 'gpt-4.1',
modelPatterns: [/^gpt/, /^o\d/, /^text-embedding/],
icon: OpenAIIcon,
color: '#E8E8E8',
capabilities: {
toolUsageControl: true,
},
models: [
// GPT-4.1 family
{
id: 'gpt-4.1',
pricing: {
input: 2.0,
cachedInput: 0.5,
output: 8.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 32768,
},
contextWindow: 1047576,
releaseDate: '2025-04-14',
},
{
id: 'gpt-4.1-mini',
pricing: {
input: 0.4,
cachedInput: 0.1,
output: 1.6,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 32768,
},
contextWindow: 1047576,
releaseDate: '2025-04-14',
},
{
id: 'gpt-4.1-nano',
pricing: {
input: 0.1,
cachedInput: 0.025,
output: 0.4,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 32768,
},
contextWindow: 1047576,
releaseDate: '2025-04-14',
sunset: { status: 'legacy' },
},
// GPT-5.6 family
{
id: 'gpt-5.6-sol',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 30.0,
updatedAt: '2026-07-09',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh', 'max'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-07-09',
recommended: true,
},
{
id: 'gpt-5.6-terra',
pricing: {
input: 2.5,
cachedInput: 0.25,
output: 15.0,
updatedAt: '2026-07-09',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-07-09',
},
{
id: 'gpt-5.6-luna',
pricing: {
input: 1.0,
cachedInput: 0.1,
output: 6.0,
updatedAt: '2026-07-09',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-07-09',
speedOptimized: true,
},
// GPT-5.5 family
{
id: 'gpt-5.5-pro',
pricing: {
input: 30.0,
output: 180.0,
updatedAt: '2026-06-11',
},
capabilities: {
nativeStructuredOutputs: true,
reasoningEffort: {
values: ['medium', 'high', 'xhigh'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-04-23',
},
{
id: 'gpt-5.5',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 30.0,
updatedAt: '2026-06-11',
},
capabilities: {
nativeStructuredOutputs: true,
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-04-23',
},
// GPT-5.4 family
{
id: 'gpt-5.4-pro',
pricing: {
input: 30.0,
output: 180.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['medium', 'high', 'xhigh'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-03-05',
},
{
id: 'gpt-5.4',
pricing: {
input: 2.5,
cachedInput: 0.25,
output: 15.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-03-05',
},
{
id: 'gpt-5.4-mini',
pricing: {
input: 0.75,
cachedInput: 0.075,
output: 4.5,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2026-03-17',
},
{
id: 'gpt-5.4-nano',
pricing: {
input: 0.2,
cachedInput: 0.02,
output: 1.25,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2026-03-17',
speedOptimized: true,
},
// GPT-5.2 family
{
id: 'gpt-5.2-pro',
pricing: {
input: 21.0,
output: 168.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['medium', 'high', 'xhigh'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-12-11',
},
{
id: 'gpt-5.2',
pricing: {
input: 1.75,
cachedInput: 0.175,
output: 14.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high', 'xhigh'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-12-11',
},
// GPT-5.1 family
{
id: 'gpt-5.1',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-11-13',
},
// GPT-5 family
{
id: 'gpt-5-pro',
pricing: {
input: 15.0,
output: 120.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['high'],
},
maxOutputTokens: 272000,
},
contextWindow: 400000,
releaseDate: '2025-10-06',
},
{
id: 'gpt-5',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['minimal', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-08-07',
},
{
id: 'gpt-5-mini',
pricing: {
input: 0.25,
cachedInput: 0.025,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['minimal', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-08-07',
},
{
id: 'gpt-5-nano',
pricing: {
input: 0.05,
cachedInput: 0.005,
output: 0.4,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['minimal', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-08-07',
},
{
id: 'gpt-5-chat-latest',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 16384,
},
contextWindow: 128000,
releaseDate: '2025-08-07',
sunset: { status: 'legacy' },
},
// o-series reasoning models
{
id: 'o4-mini',
pricing: {
input: 1.1,
cachedInput: 0.275,
output: 4.4,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 100000,
},
contextWindow: 200000,
releaseDate: '2025-04-16',
sunset: { status: 'legacy' },
},
{
id: 'o3-pro',
pricing: {
input: 20.0,
output: 80.0,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 100000,
},
contextWindow: 200000,
releaseDate: '2025-06-10',
},
{
id: 'o3',
pricing: {
input: 2,
cachedInput: 0.5,
output: 8,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 100000,
},
contextWindow: 200000,
releaseDate: '2025-04-16',
sunset: { status: 'legacy' },
},
{
id: 'o3-mini',
pricing: {
input: 1.1,
cachedInput: 0.55,
output: 4.4,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 100000,
},
contextWindow: 200000,
releaseDate: '2025-01-31',
sunset: { status: 'legacy' },
},
{
id: 'o1',
pricing: {
input: 15.0,
cachedInput: 7.5,
output: 60,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 100000,
},
contextWindow: 200000,
releaseDate: '2024-12-17',
sunset: { status: 'legacy' },
},
// Legacy
{
id: 'gpt-4o',
pricing: {
input: 2.5,
cachedInput: 1.25,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 16384,
},
contextWindow: 128000,
releaseDate: '2024-05-13',
sunset: { status: 'legacy' },
},
],
},
anthropic: {
id: 'anthropic',
fileAttachment: { maxBytes: 50 * 1024 * 1024, strategy: 'remote-url' },
name: 'Anthropic',
description: "Anthropic's Claude models",
defaultModel: 'claude-sonnet-5',
modelPatterns: [/^claude/],
icon: AnthropicIcon,
color: '#D97757',
capabilities: {
toolUsageControl: true,
// Every Claude model accepts cache_control breakpoints; Haiku raises the
// minimum prefix and overrides this per-model.
promptCaching: { minimumCacheableTokens: 1024 },
},
models: [
{
id: 'claude-fable-5',
pricing: {
input: 10.0,
cachedInput: 1.0,
output: 50.0,
updatedAt: '2026-07-01',
},
capabilities: {
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'xhigh', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-06-09',
},
{
id: 'claude-sonnet-5',
pricing: {
input: 2.0,
cachedInput: 0.2,
output: 10.0,
updatedAt: '2026-06-30',
},
capabilities: {
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'xhigh', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-06-30',
recommended: true,
},
{
id: 'claude-opus-5',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-07-24',
},
capabilities: {
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'xhigh', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-07-24',
recommended: true,
},
{
id: 'claude-opus-4-8',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-05-28',
},
capabilities: {
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'xhigh', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-05-28',
},
{
id: 'claude-opus-4-7',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-04-16',
},
capabilities: {
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'xhigh', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-04-16',
},
{
id: 'claude-opus-4-6',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-02-05',
},
{
id: 'claude-sonnet-4-6',
pricing: {
input: 3.0,
cachedInput: 0.3,
output: 15.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-02-17',
},
{
id: 'claude-opus-4-5',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-11-24',
},
{
id: 'claude-opus-4-1',
pricing: {
input: 15.0,
cachedInput: 1.5,
output: 75.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 32000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-08-05',
sunset: { status: 'legacy' },
},
{
id: 'claude-opus-4-0',
pricing: {
input: 15.0,
cachedInput: 1.5,
output: 75.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 32000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-05-22',
sunset: { status: 'deprecated' },
},
{
id: 'claude-sonnet-4-5',
pricing: {
input: 3.0,
cachedInput: 0.3,
output: 15.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-09-29',
},
{
id: 'claude-sonnet-4-0',
pricing: {
input: 3.0,
cachedInput: 0.3,
output: 15.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 64000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-05-22',
sunset: { status: 'deprecated' },
},
{
id: 'claude-haiku-4-5',
pricing: {
input: 1.0,
cachedInput: 0.1,
output: 5.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
promptCaching: { minimumCacheableTokens: 2048 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-10-15',
speedOptimized: true,
},
{
id: 'claude-3-haiku-20240307',
pricing: {
input: 0.25,
cachedInput: 0.03,
output: 1.25,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 4096,
},
contextWindow: 200000,
releaseDate: '2024-03-13',
sunset: { status: 'deprecated' },
},
],
},
'azure-openai': {
id: 'azure-openai',
name: 'Azure OpenAI',
description: 'Microsoft Azure OpenAI Service models',
defaultModel: 'azure/gpt-5.4',
modelPatterns: [/^azure\//],
capabilities: {
toolUsageControl: true,
},
icon: AzureIcon,
isReseller: true,
models: [
{
id: 'azure/gpt-4o',
pricing: {
input: 2.5,
cachedInput: 1.25,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 16384,
},
contextWindow: 128000,
releaseDate: '2024-11-20',
sunset: { status: 'legacy' },
},
{
id: 'azure/gpt-5.4',
pricing: {
input: 2.5,
cachedInput: 0.25,
output: 15.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 1050000,
releaseDate: '2026-03-05',
},
{
id: 'azure/gpt-5.4-mini',
pricing: {
input: 0.75,
cachedInput: 0.075,
output: 4.5,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2026-03-17',
},
{
id: 'azure/gpt-5.4-nano',
pricing: {
input: 0.2,
cachedInput: 0.02,
output: 1.25,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2026-03-17',
},
{
id: 'azure/gpt-5.2',
pricing: {
input: 1.75,
cachedInput: 0.175,
output: 14.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-12-11',
},
{
id: 'azure/gpt-5.1',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-11-13',
},
{
id: 'azure/gpt-5.1-codex',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['none', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-11-13',
},
{
id: 'azure/gpt-5',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['minimal', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-08-07',
},
{
id: 'azure/gpt-5-mini',
pricing: {
input: 0.25,
cachedInput: 0.025,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['minimal', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-08-07',
},
{
id: 'azure/gpt-5-nano',
pricing: {
input: 0.05,
cachedInput: 0.005,
output: 0.4,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['minimal', 'low', 'medium', 'high'],
},
verbosity: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 128000,
},
contextWindow: 400000,
releaseDate: '2025-08-07',
},
{
id: 'azure/gpt-5-chat',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 16384,
},
contextWindow: 128000,
releaseDate: '2025-08-07',
},
{
id: 'azure/o3',
pricing: {
input: 2,
cachedInput: 0.5,
output: 8,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 100000,
},
contextWindow: 200000,
releaseDate: '2025-04-16',
},
{
id: 'azure/o4-mini',
pricing: {
input: 1.1,
cachedInput: 0.275,
output: 4.4,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
maxOutputTokens: 100000,
},
contextWindow: 200000,
releaseDate: '2025-04-16',
},
{
id: 'azure/gpt-4.1',
pricing: {
input: 2.0,
cachedInput: 0.5,
output: 8.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 32768,
},
contextWindow: 1047576,
releaseDate: '2025-04-14',
},
{
id: 'azure/gpt-4.1-mini',
pricing: {
input: 0.4,
cachedInput: 0.1,
output: 1.6,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 32768,
},
contextWindow: 1047576,
releaseDate: '2025-04-14',
},
{
id: 'azure/gpt-4.1-nano',
pricing: {
input: 0.1,
cachedInput: 0.025,
output: 0.4,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 32768,
},
contextWindow: 1047576,
releaseDate: '2025-04-14',
},
{
id: 'azure/model-router',
pricing: {
input: 2.0,
cachedInput: 0.5,
output: 8.0,
updatedAt: '2026-04-01',
},
capabilities: {},
contextWindow: 200000,
releaseDate: '2025-05-19',
},
],
},
'azure-anthropic': {
id: 'azure-anthropic',
name: 'Azure Anthropic',
description: 'Anthropic Claude models via Azure AI Foundry',
defaultModel: 'azure-anthropic/claude-sonnet-4-5',
modelPatterns: [/^azure-anthropic\//],
icon: AzureIcon,
isReseller: true,
capabilities: {
toolUsageControl: true,
// Microsoft Foundry supports the same cache_control breakpoints.
promptCaching: { minimumCacheableTokens: 1024 },
},
models: [
{
id: 'azure-anthropic/claude-opus-4-6',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 128000,
thinking: {
levels: ['low', 'medium', 'high', 'max'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 1000000,
releaseDate: '2026-02-05',
},
{
id: 'azure-anthropic/claude-opus-4-5',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-11-24',
},
{
id: 'azure-anthropic/claude-sonnet-4-5',
pricing: {
input: 3.0,
cachedInput: 0.3,
output: 15.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-09-29',
},
{
id: 'azure-anthropic/claude-opus-4-1',
pricing: {
input: 15.0,
cachedInput: 1.5,
output: 75.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 32000,
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-08-05',
sunset: { status: 'legacy' },
},
{
id: 'azure-anthropic/claude-haiku-4-5',
pricing: {
input: 1.0,
cachedInput: 0.1,
output: 5.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
promptCaching: { minimumCacheableTokens: 2048 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
streamed: 'summary',
},
},
contextWindow: 200000,
releaseDate: '2025-10-15',
},
],
},
google: {
id: 'google',
fileAttachment: { maxBytes: 50 * 1024 * 1024, strategy: 'files-api' },
name: 'Google',
description: "Google's Gemini models",
defaultModel: 'gemini-2.5-pro',
modelPatterns: [/^gemini/, /^deep-research/],
capabilities: {
toolUsageControl: true,
},
icon: GeminiIcon,
color: '#4285F4',
models: [
{
id: 'gemini-3.6-flash',
pricing: {
input: 1.5,
cachedInput: 0.15,
output: 7.5,
updatedAt: '2026-07-21',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'medium',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-07-21',
recommended: true,
},
{
id: 'gemini-3.5-flash-lite',
pricing: {
input: 0.3,
cachedInput: 0.03,
output: 2.5,
updatedAt: '2026-07-21',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'minimal',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-07-21',
speedOptimized: true,
},
{
id: 'gemini-3.5-flash',
pricing: {
input: 1.5,
cachedInput: 0.15,
output: 9.0,
updatedAt: '2026-05-19',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'medium',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-05-19',
},
{
id: 'gemini-3.1-pro-preview',
pricing: {
input: 2.0,
cachedInput: 0.2,
output: 12.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-02-19',
},
{
id: 'gemini-3.1-flash-lite',
pricing: {
input: 0.25,
cachedInput: 0.025,
output: 1.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'minimal',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-05-07',
speedOptimized: true,
},
{
id: 'gemini-3-flash-preview',
pricing: {
input: 0.5,
cachedInput: 0.05,
output: 3.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'high',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2025-12-17',
},
{
id: 'gemini-2.5-pro',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2025-03-25',
},
{
id: 'gemini-2.5-flash',
pricing: {
input: 0.3,
cachedInput: 0.03,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'medium',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2025-05-20',
},
{
id: 'gemini-2.5-flash-lite',
pricing: {
input: 0.1,
cachedInput: 0.01,
output: 0.4,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'low',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2025-06-17',
speedOptimized: true,
},
{
id: 'gemini-2.0-flash',
pricing: {
input: 0.1,
cachedInput: 0.025,
output: 0.4,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 8192,
},
contextWindow: 1048576,
releaseDate: '2025-02-05',
sunset: { status: 'deprecated' },
},
{
id: 'gemini-2.0-flash-lite',
pricing: {
input: 0.075,
output: 0.3,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 8192,
},
contextWindow: 1048576,
releaseDate: '2025-02-25',
sunset: { status: 'deprecated' },
},
{
id: 'deep-research-pro-preview-12-2025',
pricing: {
input: 2.0,
cachedInput: 0.2,
output: 12.0,
updatedAt: '2026-06-11',
},
capabilities: {
deepResearch: true,
memory: false,
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2025-12-11',
},
],
},
vertex: {
id: 'vertex',
name: 'Vertex AI',
description: "Google's Vertex AI platform for Gemini models",
defaultModel: 'vertex/gemini-2.5-pro',
modelPatterns: [/^vertex\//],
icon: VertexIcon,
isReseller: true,
capabilities: {
toolUsageControl: true,
},
models: [
{
id: 'vertex/gemini-3.5-flash',
pricing: {
input: 1.5,
cachedInput: 0.15,
output: 9.0,
updatedAt: '2026-05-19',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'medium',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-05-19',
recommended: true,
},
{
id: 'vertex/gemini-3.1-pro-preview',
pricing: {
input: 2.0,
cachedInput: 0.2,
output: 12.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-02-19',
},
{
id: 'vertex/gemini-3.1-flash-lite',
pricing: {
input: 0.25,
cachedInput: 0.025,
output: 1.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'minimal',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2026-05-07',
speedOptimized: true,
},
{
id: 'vertex/gemini-3-pro-preview',
pricing: {
input: 2.0,
cachedInput: 0.2,
output: 12.0,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
},
},
contextWindow: 1000000,
releaseDate: '2025-11-18',
sunset: { status: 'deprecated' },
},
{
id: 'vertex/gemini-3-flash-preview',
pricing: {
input: 0.5,
cachedInput: 0.05,
output: 3.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['minimal', 'low', 'medium', 'high'],
default: 'high',
},
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2025-12-17',
},
{
id: 'vertex/gemini-2.5-pro',
pricing: {
input: 1.25,
cachedInput: 0.125,
output: 10.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'high',
},
maxOutputTokens: 65535,
},
contextWindow: 1048576,
releaseDate: '2025-03-25',
},
{
id: 'vertex/gemini-2.5-flash',
pricing: {
input: 0.3,
cachedInput: 0.03,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'medium',
},
maxOutputTokens: 65535,
},
contextWindow: 1048576,
releaseDate: '2025-05-20',
},
{
id: 'vertex/gemini-2.5-flash-lite',
pricing: {
input: 0.1,
cachedInput: 0.01,
output: 0.4,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
thinking: {
levels: ['low', 'medium', 'high'],
default: 'low',
},
maxOutputTokens: 65535,
},
contextWindow: 1048576,
releaseDate: '2025-06-17',
speedOptimized: true,
},
{
id: 'vertex/gemini-2.0-flash',
pricing: {
input: 0.15,
cachedInput: 0.025,
output: 0.6,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1048576,
releaseDate: '2025-02-05',
sunset: { status: 'deprecated' },
},
{
id: 'vertex/gemini-2.0-flash-lite',
pricing: {
input: 0.075,
output: 0.3,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1048576,
releaseDate: '2025-02-25',
sunset: { status: 'deprecated' },
},
{
id: 'vertex/deep-research-pro-preview-12-2025',
pricing: {
input: 2.0,
cachedInput: 0.2,
output: 12.0,
updatedAt: '2026-06-11',
},
capabilities: {
deepResearch: true,
memory: false,
maxOutputTokens: 65536,
},
contextWindow: 1048576,
releaseDate: '2025-12-11',
},
],
},
deepseek: {
id: 'deepseek',
name: 'DeepSeek',
description: "DeepSeek's chat models",
defaultModel: 'deepseek-v4-flash',
modelPatterns: [],
icon: DeepseekIcon,
color: '#4D6BFE',
capabilities: {
toolUsageControl: true,
},
models: [
{
id: 'deepseek-v4-pro',
pricing: {
input: 0.435,
cachedInput: 0.003625,
output: 0.87,
updatedAt: '2026-06-16',
},
capabilities: {
reasoningEffort: {
values: ['high', 'max'],
},
thinking: {
levels: ['none', 'enabled'],
default: 'enabled',
},
maxOutputTokens: 384000,
},
contextWindow: 1000000,
releaseDate: '2026-04-24',
},
{
id: 'deepseek-v4-flash',
pricing: {
input: 0.14,
cachedInput: 0.0028,
output: 0.28,
updatedAt: '2026-06-16',
},
capabilities: {
temperature: { min: 0, max: 2 },
reasoningEffort: {
values: ['high', 'max'],
},
thinking: {
levels: ['none', 'enabled'],
default: 'enabled',
},
maxOutputTokens: 384000,
},
contextWindow: 1000000,
releaseDate: '2026-04-24',
},
{
id: 'deepseek-chat',
pricing: {
input: 0.14,
cachedInput: 0.0028,
output: 0.28,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 384000,
},
contextWindow: 1000000,
releaseDate: '2024-12-26',
},
{
id: 'deepseek-v3',
pricing: {
input: 0.28,
cachedInput: 0.028,
output: 0.42,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 128000,
releaseDate: '2024-12-26',
sunset: { status: 'deprecated' },
},
{
id: 'deepseek-r1',
pricing: {
input: 0.55,
cachedInput: 0.14,
output: 2.19,
updatedAt: '2026-04-01',
},
capabilities: {
thinking: {
levels: ['enabled'],
default: 'enabled',
},
},
contextWindow: 128000,
releaseDate: '2025-01-20',
sunset: { status: 'deprecated' },
},
{
id: 'deepseek-reasoner',
pricing: {
input: 0.14,
cachedInput: 0.0028,
output: 0.28,
updatedAt: '2026-06-11',
},
capabilities: {
reasoningEffort: {
values: ['high', 'max'],
},
thinking: {
levels: ['enabled'],
default: 'enabled',
},
maxOutputTokens: 384000,
},
contextWindow: 1000000,
releaseDate: '2025-01-20',
},
],
},
xai: {
id: 'xai',
fileAttachment: { maxBytes: 20 * 1024 * 1024, strategy: 'remote-url' },
name: 'xAI',
description: "xAI's Grok models",
defaultModel: 'grok-4.5',
modelPatterns: [/^grok/],
icon: xAIIcon,
color: '#555555',
capabilities: {
toolUsageControl: true,
},
models: [
{
id: 'grok-4.5',
pricing: {
input: 2.0,
output: 6.0,
updatedAt: '2026-07-08',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 500000,
releaseDate: '2026-07-08',
recommended: true,
},
{
id: 'grok-4.3',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-05-05',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2026-04-30',
},
{
id: 'grok-4-latest',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-07-09',
sunset: { status: 'deprecated' },
},
{
id: 'grok-4-0709',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-07-09',
sunset: { status: 'deprecated' },
},
{
id: 'grok-4-1-fast-reasoning',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-11-19',
sunset: { status: 'deprecated' },
},
{
id: 'grok-4-1-fast-non-reasoning',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-11-19',
sunset: { status: 'deprecated' },
},
{
id: 'grok-4-fast-reasoning',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-09-19',
sunset: { status: 'deprecated' },
},
{
id: 'grok-4-fast-non-reasoning',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-09-19',
sunset: { status: 'deprecated' },
},
{
id: 'grok-code-fast-1',
pricing: {
input: 1.0,
cachedInput: 0.2,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 256000,
releaseDate: '2025-08-28',
sunset: { status: 'deprecated' },
},
{
id: 'grok-4.20-0309-reasoning',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2026-03-10',
},
{
id: 'grok-4.20-0309-non-reasoning',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2026-03-10',
},
{
id: 'grok-4.20-multi-agent-0309',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2026-03-10',
},
{
id: 'grok-3-latest',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-02-17',
sunset: { status: 'deprecated' },
},
{
id: 'grok-3-fast-latest',
pricing: {
input: 1.25,
cachedInput: 0.2,
output: 2.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
},
contextWindow: 1000000,
releaseDate: '2025-02-17',
sunset: { status: 'deprecated' },
},
],
},
cerebras: {
id: 'cerebras',
name: 'Cerebras',
description: 'Cerebras Cloud LLMs',
defaultModel: 'cerebras/gpt-oss-120b',
modelPatterns: [/^cerebras/],
icon: CerebrasIcon,
color: '#6D5BF7',
capabilities: {
toolUsageControl: true,
},
models: [
{
id: 'cerebras/gpt-oss-120b',
pricing: {
input: 0.35,
output: 0.75,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 40000,
},
contextWindow: 131072,
releaseDate: '2025-08-05',
},
{
id: 'cerebras/llama3.1-8b',
pricing: {
input: 0.1,
output: 0.1,
updatedAt: '2026-04-01',
},
capabilities: {},
contextWindow: 32768,
releaseDate: '2024-08-27',
sunset: { status: 'deprecated' },
},
{
id: 'cerebras/qwen-3-235b-a22b-instruct-2507',
pricing: {
input: 0.6,
output: 1.2,
updatedAt: '2026-04-01',
},
capabilities: {},
contextWindow: 131072,
releaseDate: '2025-07-29',
sunset: { status: 'deprecated' },
},
{
id: 'cerebras/zai-glm-4.7',
pricing: {
input: 2.25,
output: 2.75,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 40000,
},
contextWindow: 131072,
releaseDate: '2025-12-22',
},
{
id: 'cerebras/gemma-4-31b',
pricing: {
input: 0.99,
output: 1.49,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 2 },
maxOutputTokens: 40000,
},
contextWindow: 131072,
releaseDate: '2026-04-02',
},
],
},
groq: {
id: 'groq',
fileAttachment: { maxBytes: 20 * 1024 * 1024, strategy: 'remote-url' },
name: 'Groq',
description: "Groq's LLM models with high-performance inference",
defaultModel: 'groq/llama-3.3-70b-versatile',
modelPatterns: [/^groq/],
icon: GroqIcon,
color: '#F55036',
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
models: [
{
id: 'groq/openai/gpt-oss-120b',
pricing: {
input: 0.15,
cachedInput: 0.075,
output: 0.6,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 65536,
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
},
contextWindow: 131072,
releaseDate: '2025-08-05',
recommended: true,
},
{
id: 'groq/openai/gpt-oss-20b',
pricing: {
input: 0.075,
cachedInput: 0.0375,
output: 0.3,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 65536,
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
},
contextWindow: 131072,
releaseDate: '2025-08-05',
},
{
id: 'groq/openai/gpt-oss-safeguard-20b',
pricing: {
input: 0.075,
cachedInput: 0.0375,
output: 0.3,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 65536,
reasoningEffort: {
values: ['low', 'medium', 'high'],
},
},
contextWindow: 131072,
releaseDate: '2025-10-29',
},
{
id: 'groq/qwen/qwen3-32b',
pricing: {
input: 0.29,
output: 0.59,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 40960,
thinking: {
levels: ['enabled'],
default: 'enabled',
},
},
contextWindow: 131072,
releaseDate: '2025-04-29',
sunset: { status: 'deprecated' },
},
{
id: 'groq/qwen/qwen3.6-27b',
pricing: {
input: 0.6,
output: 3.0,
updatedAt: '2026-07-10',
},
capabilities: {
maxOutputTokens: 32768,
thinking: {
levels: ['enabled'],
default: 'enabled',
},
},
contextWindow: 131072,
releaseDate: '2026-04-21',
},
{
id: 'groq/llama-3.1-8b-instant',
pricing: {
input: 0.05,
output: 0.08,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 131072,
},
contextWindow: 131072,
releaseDate: '2024-07-23',
speedOptimized: true,
},
{
id: 'groq/llama-3.3-70b-versatile',
pricing: {
input: 0.59,
output: 0.79,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 32768,
},
contextWindow: 131072,
releaseDate: '2024-12-06',
},
{
id: 'groq/meta-llama/llama-4-scout-17b-16e-instruct',
pricing: {
input: 0.11,
output: 0.34,
updatedAt: '2026-06-11',
},
capabilities: {
maxOutputTokens: 8192,
},
contextWindow: 131072,
releaseDate: '2025-04-05',
sunset: { status: 'deprecated' },
},
{
id: 'groq/moonshotai/kimi-k2-instruct-0905',
pricing: {
input: 1.0,
output: 3.0,
updatedAt: '2026-04-01',
},
capabilities: {},
contextWindow: 262144,
releaseDate: '2025-09-05',
sunset: { status: 'deprecated' },
},
],
},
sakana: {
id: 'sakana',
name: 'Sakana AI',
description: "Sakana AI's Fugu multi-agent models via an OpenAI-compatible API",
defaultModel: 'fugu',
modelPatterns: [/^fugu/],
icon: SakanaIcon,
color: '#E60000',
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
models: [
{
id: 'fugu',
pricing: {
input: 5,
cachedInput: 0.5,
output: 30,
updatedAt: '2026-06-22',
},
capabilities: {},
contextWindow: 1000000,
releaseDate: '2026-06-15',
speedOptimized: true,
},
{
id: 'fugu-ultra',
pricing: {
input: 5,
cachedInput: 0.5,
output: 30,
updatedAt: '2026-06-22',
},
capabilities: {},
contextWindow: 1000000,
releaseDate: '2026-06-15',
recommended: true,
},
],
},
nvidia: {
id: 'nvidia',
name: 'NVIDIA NIM',
description: "NVIDIA's Nemotron models via NIM's OpenAI-compatible API",
defaultModel: 'nvidia/nemotron-3-super-120b-a12b',
modelPatterns: [/^nvidia\//],
icon: NvidiaIcon,
color: '#77B900',
isReseller: true,
contextInformationAvailable: true,
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
models: [
{
id: 'nvidia/llama-3.1-nemotron-70b-instruct',
pricing: {
input: 1.2,
output: 1.2,
updatedAt: '2026-07-09',
},
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
maxOutputTokens: 4096,
},
contextWindow: 128000,
releaseDate: '2024-10-15',
},
{
id: 'nvidia/llama-3.1-nemotron-ultra-253b-v1',
pricing: {
input: 0.6,
output: 1.8,
updatedAt: '2026-07-09',
},
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
maxOutputTokens: 8192,
},
contextWindow: 131072,
releaseDate: '2025-04-07',
},
{
id: 'nvidia/llama-3.3-nemotron-super-49b-v1.5',
pricing: {
input: 0.4,
output: 0.4,
updatedAt: '2026-07-09',
},
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
maxOutputTokens: 8192,
},
contextWindow: 131072,
releaseDate: '2025-07-25',
},
{
id: 'nvidia/nemotron-3-nano-30b-a3b',
pricing: {
input: 0.05,
output: 0.2,
updatedAt: '2026-07-09',
},
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
maxOutputTokens: 8192,
},
contextWindow: 262144,
releaseDate: '2025-12-15',
speedOptimized: true,
},
{
id: 'nvidia/nemotron-3-super-120b-a12b',
pricing: {
input: 0.08,
output: 0.45,
updatedAt: '2026-07-09',
},
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
maxOutputTokens: 8192,
},
contextWindow: 1048576,
releaseDate: '2026-03-11',
recommended: true,
},
{
id: 'nvidia/nemotron-3-ultra-550b-a55b',
pricing: {
input: 0.5,
output: 2.2,
updatedAt: '2026-07-09',
},
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
maxOutputTokens: 8192,
},
contextWindow: 1048576,
releaseDate: '2026-06-04',
},
],
},
meta: {
id: 'meta',
name: 'Meta',
description: "Meta's Muse Spark models via the Meta Model API (OpenAI-compatible)",
defaultModel: 'muse-spark-1.1',
modelPatterns: [/^muse-spark/],
icon: MetaIcon,
color: '#0082FB',
capabilities: {
temperature: { min: 0, max: 2 },
toolUsageControl: true,
},
models: [
{
id: 'muse-spark-1.1',
pricing: {
input: 1.25,
cachedInput: 0.15,
output: 4.25,
updatedAt: '2026-07-09',
},
capabilities: {
reasoningEffort: {
values: ['minimal', 'low', 'medium', 'high', 'xhigh'],
},
},
contextWindow: 1048576,
releaseDate: '2026-07-09',
recommended: true,
},
],
},
kimi: {
id: 'kimi',
name: 'Kimi',
description: "Moonshot AI's Kimi models via an OpenAI-compatible API",
defaultModel: 'kimi-k2.6',
// No fallback pattern — an unscoped `/^kimi/` would overmatch Kimi weights re-hosted by
// other providers (e.g. `moonshotai/kimi-*` on aggregators) and misroute them here.
modelPatterns: [],
icon: KimiIcon,
color: '#1783FF',
contextInformationAvailable: true,
capabilities: {
toolUsageControl: true,
},
models: [
{
id: 'kimi-k3',
pricing: {
input: 3.0,
cachedInput: 0.3,
output: 15.0,
updatedAt: '2026-07-16',
},
capabilities: {
toolUsageControl: true,
maxOutputTokens: 1048576,
},
contextWindow: 1048576,
releaseDate: '2026-07-16',
recommended: true,
},
{
id: 'kimi-k2.7-code',
pricing: {
input: 0.95,
cachedInput: 0.19,
output: 4.0,
updatedAt: '2026-07-16',
},
capabilities: {
toolUsageControl: true,
},
contextWindow: 262144,
releaseDate: '2026-06-12',
},
{
id: 'kimi-k2.7-code-highspeed',
pricing: {
input: 1.9,
cachedInput: 0.38,
output: 8.0,
updatedAt: '2026-07-16',
},
capabilities: {
toolUsageControl: true,
},
contextWindow: 262144,
releaseDate: '2026-06-12',
speedOptimized: true,
},
{
id: 'kimi-k2.6',
pricing: {
input: 0.95,
cachedInput: 0.16,
output: 4.0,
updatedAt: '2026-07-16',
},
capabilities: {
toolUsageControl: true,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 262144,
},
],
},
zai: {
id: 'zai',
name: 'Z.ai',
description: "Z.ai's GLM models via an OpenAI-compatible API",
defaultModel: 'glm-4.6',
modelPatterns: [],
icon: ZaiIcon,
color: '#2D2D2D',
contextInformationAvailable: true,
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
},
models: [
{
id: 'glm-5.2',
pricing: {
input: 1.4,
output: 4.4,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 131072,
reasoningEffort: {
values: ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'],
},
},
contextWindow: 1000000,
releaseDate: '2026-06-13',
recommended: true,
},
{
id: 'glm-5.1',
pricing: {
input: 1.4,
output: 4.4,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 131072,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 200000,
releaseDate: '2026-04-07',
},
{
id: 'glm-5',
pricing: {
input: 1.0,
output: 3.2,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 131072,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 200000,
releaseDate: '2026-02-11',
},
{
id: 'glm-5-turbo',
pricing: {
input: 1.2,
output: 4.0,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 131072,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 200000,
releaseDate: '2026-03-15',
},
{
id: 'glm-4.7',
pricing: {
input: 0.6,
output: 2.2,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 131072,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 200000,
releaseDate: '2025-12-22',
},
{
id: 'glm-4.7-flashx',
pricing: {
input: 0.07,
output: 0.4,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 131072,
},
contextWindow: 200000,
releaseDate: '2025-12-22',
},
{
id: 'glm-4.6',
pricing: {
input: 0.6,
output: 2.2,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 131072,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 200000,
releaseDate: '2025-09-30',
},
{
id: 'glm-4.5',
pricing: {
input: 0.6,
output: 2.2,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 98304,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 128000,
releaseDate: '2025-07-28',
},
{
id: 'glm-4.5-air',
pricing: {
input: 0.2,
output: 1.1,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 98304,
thinking: {
levels: ['disabled', 'enabled'],
default: 'enabled',
},
},
contextWindow: 128000,
releaseDate: '2025-07-28',
},
{
id: 'glm-4.5-x',
pricing: {
input: 2.2,
output: 8.9,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 98304,
},
contextWindow: 128000,
releaseDate: '2025-07-28',
},
{
id: 'glm-4.5-airx',
pricing: {
input: 1.1,
output: 4.5,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 98304,
},
contextWindow: 128000,
releaseDate: '2025-07-28',
},
{
id: 'glm-4-32b-0414-128k',
pricing: {
input: 0.1,
output: 0.1,
updatedAt: '2026-07-10',
},
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
maxOutputTokens: 16384,
},
contextWindow: 128000,
releaseDate: '2025-04-14',
},
],
},
mistral: {
id: 'mistral',
name: 'Mistral AI',
description: "Mistral AI's language models",
defaultModel: 'mistral-large-latest',
modelPatterns: [
/^mistral/,
/^magistral/,
/^open-mistral/,
/^codestral/,
/^ministral/,
/^devstral/,
],
icon: MistralIcon,
color: '#F7D046',
capabilities: {
toolUsageControl: true,
},
models: [
{
id: 'mistral-large-latest',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
recommended: true,
},
{
id: 'mistral-large-2512',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
},
{
id: 'mistral-small-2603',
pricing: {
input: 0.15,
output: 0.6,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2026-03-16',
},
{
id: 'devstral-2512',
pricing: {
input: 0.4,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-09',
},
{
id: 'mistral-large-2411',
pricing: {
input: 2.0,
output: 6.0,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2024-11-18',
sunset: { status: 'deprecated' },
},
{
id: 'magistral-medium-latest',
pricing: {
input: 2.0,
output: 5.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-09-18',
},
{
id: 'magistral-medium-2509',
pricing: {
input: 2.0,
output: 5.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-09-18',
},
{
id: 'magistral-small-latest',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-09-18',
sunset: { status: 'legacy' },
},
{
id: 'magistral-small-2509',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-09-18',
sunset: { status: 'legacy' },
},
{
id: 'mistral-medium-latest',
pricing: {
input: 0.4,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-08-12',
},
{
id: 'mistral-medium-2604',
pricing: {
input: 1.5,
output: 7.5,
updatedAt: '2026-06-16',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2026-04-29',
},
{
id: 'mistral-medium-2508',
pricing: {
input: 0.4,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-08-12',
},
{
id: 'mistral-medium-2505',
pricing: {
input: 0.4,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-05-07',
},
{
id: 'mistral-small-latest',
pricing: {
input: 0.15,
output: 0.6,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2026-03-16',
},
{
id: 'mistral-small-2506',
pricing: {
input: 0.1,
output: 0.3,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-06-20',
sunset: { status: 'legacy' },
},
{
id: 'open-mistral-nemo',
pricing: {
input: 0.15,
output: 0.15,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2024-07-18',
},
{
id: 'codestral-latest',
pricing: {
input: 0.3,
output: 0.9,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-07-30',
},
{
id: 'codestral-2508',
pricing: {
input: 0.3,
output: 0.9,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-07-30',
},
{
id: 'devstral-latest',
pricing: {
input: 0.4,
output: 2.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-09',
},
{
id: 'devstral-small-latest',
pricing: {
input: 0.1,
output: 0.3,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-09',
sunset: { status: 'legacy' },
},
{
id: 'devstral-small-2507',
pricing: {
input: 0.1,
output: 0.3,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-07-10',
sunset: { status: 'deprecated' },
},
{
id: 'devstral-medium-2507',
pricing: {
input: 0.4,
output: 2.0,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 128000,
releaseDate: '2025-07-10',
sunset: { status: 'deprecated' },
},
{
id: 'ministral-14b-latest',
pricing: {
input: 0.2,
output: 0.2,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
speedOptimized: true,
},
{
id: 'ministral-14b-2512',
pricing: {
input: 0.2,
output: 0.2,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
speedOptimized: true,
},
{
id: 'ministral-8b-latest',
pricing: {
input: 0.15,
output: 0.15,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
speedOptimized: true,
},
{
id: 'ministral-8b-2512',
pricing: {
input: 0.15,
output: 0.15,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
speedOptimized: true,
},
{
id: 'ministral-3b-latest',
pricing: {
input: 0.1,
output: 0.1,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
speedOptimized: true,
},
{
id: 'ministral-3b-2512',
pricing: {
input: 0.1,
output: 0.1,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1.5 },
},
contextWindow: 256000,
releaseDate: '2025-12-02',
speedOptimized: true,
},
],
},
ollama: {
id: 'ollama',
name: 'Ollama',
description: 'Local LLM models via Ollama',
defaultModel: '',
modelPatterns: [],
icon: OllamaIcon,
capabilities: {
toolUsageControl: false, // Ollama does not support tool_choice parameter
},
contextInformationAvailable: false,
models: [], // Populated dynamically
},
bedrock: {
id: 'bedrock',
name: 'AWS Bedrock',
description: 'AWS Bedrock foundation models',
defaultModel: 'bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0',
modelPatterns: [/^bedrock\//],
icon: BedrockIcon,
color: '#FF9900',
isReseller: true,
capabilities: {
temperature: { min: 0, max: 1 },
toolUsageControl: true,
},
models: [
{
id: 'bedrock/anthropic.claude-opus-4-5-20251101-v1:0',
pricing: {
input: 5.0,
cachedInput: 0.5,
output: 25.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
},
contextWindow: 200000,
releaseDate: '2025-11-24',
},
{
id: 'bedrock/anthropic.claude-sonnet-4-5-20250929-v1:0',
pricing: {
input: 3.0,
cachedInput: 0.3,
output: 15.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
},
contextWindow: 200000,
releaseDate: '2025-09-29',
recommended: true,
},
{
id: 'bedrock/anthropic.claude-haiku-4-5-20251001-v1:0',
pricing: {
input: 1.0,
cachedInput: 0.1,
output: 5.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 64000,
},
contextWindow: 200000,
releaseDate: '2025-10-15',
speedOptimized: true,
},
{
id: 'bedrock/anthropic.claude-opus-4-1-20250805-v1:0',
pricing: {
input: 15.0,
cachedInput: 1.5,
output: 75.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
nativeStructuredOutputs: true,
maxOutputTokens: 32000,
},
contextWindow: 200000,
releaseDate: '2025-08-05',
sunset: { status: 'legacy' },
},
{
id: 'bedrock/amazon.nova-2-lite-v1:0',
pricing: {
input: 0.33,
cachedInput: 0.0825,
output: 2.75,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 64000,
},
contextWindow: 1000000,
releaseDate: '2025-12-02',
},
{
id: 'bedrock/amazon.nova-premier-v1:0',
pricing: {
input: 2.5,
cachedInput: 0.625,
output: 12.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 1000000,
releaseDate: '2025-04-30',
sunset: { status: 'legacy' },
},
{
id: 'bedrock/amazon.nova-pro-v1:0',
pricing: {
input: 0.8,
cachedInput: 0.2,
output: 3.2,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 5120,
},
contextWindow: 300000,
releaseDate: '2024-12-03',
},
{
id: 'bedrock/amazon.nova-lite-v1:0',
pricing: {
input: 0.06,
cachedInput: 0.015,
output: 0.24,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 5120,
},
contextWindow: 300000,
releaseDate: '2024-12-03',
},
{
id: 'bedrock/amazon.nova-micro-v1:0',
pricing: {
input: 0.035,
cachedInput: 0.00875,
output: 0.14,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 5120,
},
contextWindow: 128000,
releaseDate: '2024-12-03',
speedOptimized: true,
},
{
id: 'bedrock/meta.llama4-maverick-17b-instruct-v1:0',
pricing: {
input: 0.24,
output: 0.97,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 8192,
},
contextWindow: 1000000,
releaseDate: '2025-04-05',
},
{
id: 'bedrock/meta.llama4-scout-17b-instruct-v1:0',
pricing: {
input: 0.17,
output: 0.66,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 8192,
},
contextWindow: 10000000,
releaseDate: '2025-04-05',
},
{
id: 'bedrock/meta.llama3-3-70b-instruct-v1:0',
pricing: {
input: 0.72,
output: 0.72,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 4096,
},
contextWindow: 128000,
releaseDate: '2024-12-06',
},
{
id: 'bedrock/meta.llama3-2-90b-instruct-v1:0',
pricing: {
input: 0.72,
output: 0.72,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
releaseDate: '2024-09-25',
sunset: { status: 'deprecated' },
},
{
id: 'bedrock/meta.llama3-2-11b-instruct-v1:0',
pricing: {
input: 0.16,
output: 0.16,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
releaseDate: '2024-09-25',
sunset: { status: 'deprecated' },
},
{
id: 'bedrock/meta.llama3-2-3b-instruct-v1:0',
pricing: {
input: 0.15,
output: 0.15,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
releaseDate: '2024-09-25',
sunset: { status: 'deprecated' },
},
{
id: 'bedrock/meta.llama3-2-1b-instruct-v1:0',
pricing: {
input: 0.1,
output: 0.1,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
releaseDate: '2024-09-25',
sunset: { status: 'deprecated' },
},
{
id: 'bedrock/meta.llama3-1-405b-instruct-v1:0',
pricing: {
input: 2.4,
output: 2.4,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
sunset: { status: 'deprecated' },
},
{
id: 'bedrock/meta.llama3-1-70b-instruct-v1:0',
pricing: {
input: 0.72,
output: 0.72,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 4096,
},
contextWindow: 128000,
releaseDate: '2024-07-23',
},
{
id: 'bedrock/meta.llama3-1-8b-instruct-v1:0',
pricing: {
input: 0.22,
output: 0.22,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 4096,
},
contextWindow: 128000,
releaseDate: '2024-07-23',
},
{
id: 'bedrock/mistral.mistral-large-3-675b-instruct',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 32768,
},
contextWindow: 256000,
releaseDate: '2025-12-02',
},
{
id: 'bedrock/mistral.mistral-large-2407-v1:0',
pricing: {
input: 2.0,
output: 6.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
sunset: { status: 'legacy' },
},
{
id: 'bedrock/mistral.pixtral-large-2502-v1:0',
pricing: {
input: 2.0,
output: 6.0,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 16384,
},
contextWindow: 128000,
},
{
id: 'bedrock/mistral.magistral-small-2509',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 40000,
},
contextWindow: 128000,
},
{
id: 'bedrock/mistral.ministral-3-14b-instruct',
pricing: {
input: 0.2,
output: 0.2,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 8192,
},
contextWindow: 128000,
releaseDate: '2025-12-02',
},
{
id: 'bedrock/mistral.ministral-3-8b-instruct',
pricing: {
input: 0.15,
output: 0.15,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 8192,
},
contextWindow: 128000,
releaseDate: '2025-12-02',
},
{
id: 'bedrock/mistral.ministral-3-3b-instruct',
pricing: {
input: 0.1,
output: 0.1,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 8192,
},
contextWindow: 128000,
releaseDate: '2025-12-02',
},
{
id: 'bedrock/mistral.mixtral-8x7b-instruct-v0:1',
pricing: {
input: 0.45,
output: 0.7,
updatedAt: '2026-06-11',
},
capabilities: {
temperature: { min: 0, max: 1 },
maxOutputTokens: 4096,
},
contextWindow: 32000,
},
{
id: 'bedrock/amazon.titan-text-premier-v1:0',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 32000,
sunset: { status: 'deprecated' },
},
{
id: 'bedrock/cohere.command-r-plus-v1:0',
pricing: {
input: 3.0,
output: 15.0,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
sunset: { status: 'legacy' },
},
{
id: 'bedrock/cohere.command-r-v1:0',
pricing: {
input: 0.5,
output: 1.5,
updatedAt: '2026-04-01',
},
capabilities: {
temperature: { min: 0, max: 1 },
},
contextWindow: 128000,
sunset: { status: 'legacy' },
},
],
},
}
export function getProviderModels(providerId: string): string[] {
return PROVIDER_DEFINITIONS[providerId]?.models.map((m) => m.id) || []
}
interface ModelCatalogEntry {
providerId: string
declIndex: number
releaseTime: number
}
/**
* Lowercased model ID → catalog position metadata, built once from the static
* provider catalog. Dynamic providers contribute nothing here because their model
* lists are populated at runtime (not at module load), and only catalog models are
* ever reordered by release date.
*/
const MODEL_CATALOG_INDEX: Map<string, ModelCatalogEntry> = new Map(
Object.entries(PROVIDER_DEFINITIONS).flatMap(([providerId, provider]) =>
provider.models.map((model, declIndex): [string, ModelCatalogEntry] => {
const parsed = model.releaseDate ? Date.parse(model.releaseDate) : Number.NaN
return [
model.id.toLowerCase(),
{
providerId,
declIndex,
releaseTime: Number.isNaN(parsed) ? Number.NEGATIVE_INFINITY : parsed,
},
]
})
)
)
/**
* Reorders model IDs so that, within each provider, newer models (by release date)
* come first — while preserving the caller's existing provider grouping order. The
* relative order of providers is taken from the order they first appear in `modelIds`,
* so the cross-provider layout the user already sees is never reshuffled.
*
* Models without a known release date keep their declaration order and sort after
* dated models within the same provider. IDs not found in the catalog (e.g.
* dynamically-discovered provider models) are left in their original order at the end.
*/
export function orderModelIdsByReleaseDate(modelIds: string[]): string[] {
const groups = new Map<string, string[]>()
const unknown: string[] = []
for (const id of modelIds) {
const meta = MODEL_CATALOG_INDEX.get(id.toLowerCase())
if (!meta) {
unknown.push(id)
continue
}
const bucket = groups.get(meta.providerId)
if (bucket) bucket.push(id)
else groups.set(meta.providerId, [id])
}
const ordered: string[] = []
for (const bucket of groups.values()) {
bucket.sort((a, b) => {
const ma = MODEL_CATALOG_INDEX.get(a.toLowerCase())!
const mb = MODEL_CATALOG_INDEX.get(b.toLowerCase())!
if (ma.releaseTime !== mb.releaseTime) return mb.releaseTime - ma.releaseTime
return ma.declIndex - mb.declIndex
})
ordered.push(...bucket)
}
ordered.push(...unknown)
return ordered
}
export const DYNAMIC_MODEL_PROVIDERS = [
'ollama',
'ollama-cloud',
'vllm',
'litellm',
'openrouter',
'fireworks',
'together',
'baseten',
] as const
function getAllStaticModelIds(): string[] {
const ids: string[] = []
for (const [providerId, provider] of Object.entries(PROVIDER_DEFINITIONS)) {
if ((DYNAMIC_MODEL_PROVIDERS as readonly string[]).includes(providerId)) continue
for (const model of provider.models) ids.push(model.id)
}
return ids
}
const STATIC_MODEL_ID_SET = new Set(getAllStaticModelIds().map((id) => id.toLowerCase()))
export function isKnownModelId(modelId: string): boolean {
if (!modelId || typeof modelId !== 'string') return false
const trimmed = modelId.trim()
if (!trimmed) return false
if (STATIC_MODEL_ID_SET.has(trimmed.toLowerCase())) return true
const lowered = trimmed.toLowerCase()
for (const provider of DYNAMIC_MODEL_PROVIDERS) {
if (lowered.startsWith(`${provider}/`)) return true
}
return false
}
const MODEL_SUNSET_STATUS = new Map<string, 'legacy' | 'deprecated'>()
for (const [providerId, provider] of Object.entries(PROVIDER_DEFINITIONS)) {
if ((DYNAMIC_MODEL_PROVIDERS as readonly string[]).includes(providerId)) continue
for (const model of provider.models) {
if (model.sunset) MODEL_SUNSET_STATUS.set(model.id.toLowerCase(), model.sunset.status)
}
}
/**
* The sunset tier of a static-catalog model — `legacy` (superseded, callable) or
* `deprecated` (retired, API fails) — or `undefined` when not sunset. Mirrors
* reading `BlockConfig.sunset.status`. Dynamic-provider and unknown ids return
* `undefined` (no static catalog entry).
*/
export function getModelSunsetStatus(
modelId: string | undefined | null
): 'legacy' | 'deprecated' | undefined {
return modelId ? MODEL_SUNSET_STATUS.get(modelId.toLowerCase()) : undefined
}
/** Whether a stored model id is sunset (either tier). */
export function isModelDeprecated(modelId: string | undefined | null): boolean {
return getModelSunsetStatus(modelId) !== undefined
}
function getRecommendedModels(): string[] {
const models: string[] = []
for (const [providerId, provider] of Object.entries(PROVIDER_DEFINITIONS)) {
if ((DYNAMIC_MODEL_PROVIDERS as readonly string[]).includes(providerId)) continue
for (const model of provider.models) {
if (model.recommended) models.push(model.id)
}
}
return models
}
export function suggestModelIdsForUnknownModel(_modelId: string, limit = 5): string[] {
const recommended = getRecommendedModels()
if (recommended.length > 0) return recommended.slice(0, limit)
return [
PROVIDER_DEFINITIONS.anthropic.defaultModel,
PROVIDER_DEFINITIONS.openai.defaultModel,
PROVIDER_DEFINITIONS.google.defaultModel,
]
.filter(Boolean)
.slice(0, limit)
}
/**
* Pseudo-model id for the agent block's automatic model. Not a real catalog
* entry: at execution time the resolver (lib/model-router) classifies the task
* via mothership and swaps in a concrete model from the hosted Fireworks pool
* before any provider/pricing lookup runs. Hosted Sim only.
*/
export const SIM_AUTO_MODEL_ID = 'sim-auto'
/** True when the configured model is the sim-auto pseudo-model. */
export function isAutoModel(model: string): boolean {
return model.trim().toLowerCase() === SIM_AUTO_MODEL_ID
}
export function getBaseModelProviders(): Record<string, ProviderId> {
return Object.entries(PROVIDER_DEFINITIONS)
.filter(
([providerId]) =>
![
'ollama',
'ollama-cloud',
'vllm',
'litellm',
'openrouter',
'fireworks',
'together',
'baseten',
].includes(providerId)
)
.reduce(
(map, [providerId, provider]) => {
provider.models.forEach((model) => {
map[model.id.toLowerCase()] = providerId as ProviderId
})
return map
},
{} as Record<string, ProviderId>
)
}
export function getProviderFromModel(model: string): ProviderId {
const normalizedModel = model.toLowerCase()
for (const [providerId, provider] of Object.entries(PROVIDER_DEFINITIONS)) {
if (
provider.models.some((providerModel) => providerModel.id.toLowerCase() === normalizedModel)
) {
return providerId as ProviderId
}
}
for (const [providerId, provider] of Object.entries(PROVIDER_DEFINITIONS)) {
if (provider.modelPatterns?.some((pattern) => pattern.test(normalizedModel))) {
return providerId as ProviderId
}
}
return 'ollama'
}
export function getProviderIcon(model: string): React.ComponentType<{ className?: string }> | null {
const providerId = getProviderFromModel(model)
return PROVIDER_DEFINITIONS[providerId]?.icon || null
}
export function getProviderDefaultModel(providerId: string): string {
return PROVIDER_DEFINITIONS[providerId]?.defaultModel || ''
}
export function getModelPricing(modelId: string): ModelPricing | null {
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
const model = provider.models.find((m) => m.id.toLowerCase() === modelId.toLowerCase())
if (model) {
return model.pricing
}
}
return null
}
export function getModelCapabilities(modelId: string): ModelCapabilities | null {
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
const model = provider.models.find((m) => m.id.toLowerCase() === modelId.toLowerCase())
if (model) {
const capabilities: ModelCapabilities = { ...provider.capabilities, ...model.capabilities }
return capabilities
}
}
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
if (provider.modelPatterns) {
for (const pattern of provider.modelPatterns) {
if (pattern.test(modelId.toLowerCase())) {
return provider.capabilities || null
}
}
}
}
return null
}
export function getModelsWithTemperatureSupport(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.temperature) {
models.push(model.id)
}
}
}
return models
}
export function getModelsWithTemperatureRange(max: number): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.temperature?.max === max) {
models.push(model.id)
}
}
}
return models
}
export function getProvidersWithToolUsageControl(): string[] {
const providers: string[] = []
for (const [providerId, provider] of Object.entries(PROVIDER_DEFINITIONS)) {
if (provider.capabilities?.toolUsageControl) {
providers.push(providerId)
}
}
return providers
}
export function getHostedModels(): string[] {
return [
...getProviderModels('openai'),
...getProviderModels('anthropic'),
...getProviderModels('google'),
...getProviderModels('zai'),
...getProviderModels('xai'),
...getProviderModels('kimi'),
// The STATIC Fireworks catalog only (the sim-auto pool, platform key) —
// deliberately not the live provider list, which `updateFireworksModels`
// merges a workspace's own dynamic ids into. Those must never enter the
// hosted set: it gates both billing and the platform-key handout.
...STATIC_FIREWORKS_MODELS.map((model) => model.id),
]
}
export function getComputerUseModels(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.computerUse) {
models.push(model.id)
}
}
}
return models
}
export function supportsTemperature(modelId: string): boolean {
const capabilities = getModelCapabilities(modelId)
return !!capabilities?.temperature
}
export function getMaxTemperature(modelId: string): number | undefined {
const capabilities = getModelCapabilities(modelId)
return capabilities?.temperature?.max
}
export function supportsToolUsageControl(providerId: string): boolean {
return getProvidersWithToolUsageControl().includes(providerId)
}
export function updateOllamaModels(models: string[]): void {
PROVIDER_DEFINITIONS.ollama.models = models.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
}))
}
export function updateVLLMModels(models: string[]): void {
PROVIDER_DEFINITIONS.vllm.models = models.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
}))
}
export function updateLiteLLMModels(models: string[]): void {
PROVIDER_DEFINITIONS.litellm.models = models.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
}))
}
/**
* The static Fireworks catalog (the hosted sim-auto pool), captured at module
* load before any dynamic sync runs. Hosted billing, pricing, and the agent
* block's API-key condition all key on these ids, so a workspace's own
* Fireworks models are merged on top of them rather than replacing them —
* unlike the other dynamic providers, whose static list is empty.
*/
const STATIC_FIREWORKS_MODELS = PROVIDER_DEFINITIONS.fireworks.models
export function updateFireworksModels(models: string[]): void {
const staticIds = new Set(STATIC_FIREWORKS_MODELS.map((model) => model.id.toLowerCase()))
PROVIDER_DEFINITIONS.fireworks.models = [
...STATIC_FIREWORKS_MODELS,
...models
.filter((modelId) => !staticIds.has(modelId.toLowerCase()))
.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
})),
]
}
export function updateTogetherModels(models: string[]): void {
PROVIDER_DEFINITIONS.together.models = models.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
}))
}
export function updateBasetenModels(models: string[]): void {
PROVIDER_DEFINITIONS.baseten.models = models.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
}))
}
export function updateOllamaCloudModels(models: string[]): void {
PROVIDER_DEFINITIONS['ollama-cloud'].models = models.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
}))
}
export function updateOpenRouterModels(models: string[]): void {
PROVIDER_DEFINITIONS.openrouter.models = models.map((modelId) => ({
id: modelId,
pricing: {
input: 0,
output: 0,
updatedAt: new Date().toISOString().split('T')[0],
},
capabilities: {},
}))
}
export const EMBEDDING_MODEL_PRICING: Record<string, ModelPricing> = {
'text-embedding-3-small': {
input: 0.02, // $0.02 per 1M tokens
output: 0.0,
updatedAt: '2026-04-01',
},
'text-embedding-3-large': {
input: 0.13, // $0.13 per 1M tokens
output: 0.0,
updatedAt: '2026-04-01',
},
'text-embedding-ada-002': {
input: 0.1, // $0.1 per 1M tokens
output: 0.0,
updatedAt: '2026-04-01',
},
'gemini-embedding-001': {
input: 0.15, // $0.15 per 1M tokens
output: 0.0,
updatedAt: '2026-04-29',
},
'embed-v4.0': {
input: 0.12, // $0.12 per 1M tokens
output: 0.0,
updatedAt: '2026-08-05',
},
'mistral-embed': {
input: 0.1, // $0.1 per 1M tokens
output: 0.0,
updatedAt: '2026-08-05',
},
'codestral-embed': {
input: 0.15, // $0.15 per 1M tokens
output: 0.0,
updatedAt: '2026-08-05',
},
}
export function getEmbeddingModelPricing(modelId: string): ModelPricing | null {
return EMBEDDING_MODEL_PRICING[modelId] || null
}
/**
* Cohere rerank pricing in USD per single search unit (one query × ≤100 docs).
* Sim caps every rerank request to ≤100 documents, so each call = 1 unit.
*/
export const RERANK_MODEL_PRICING: Record<string, { perSearchUnit: number; updatedAt: string }> = {
'rerank-v4.0-pro': { perSearchUnit: 0.0025, updatedAt: '2026-04-29' },
'rerank-v4.0-fast': { perSearchUnit: 0.002, updatedAt: '2026-04-29' },
'rerank-v3.5': { perSearchUnit: 0.002, updatedAt: '2026-04-29' },
}
export function getRerankModelPricing(
modelId: string
): { perSearchUnit: number; updatedAt: string } | null {
return RERANK_MODEL_PRICING[modelId] || null
}
export function getModelsWithReasoningEffort(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.reasoningEffort) {
models.push(model.id)
}
}
}
return models
}
/**
* Get the reasoning effort values for a specific model
* Returns the valid options for that model, or null if the model doesn't support reasoning effort
*/
export function getReasoningEffortValuesForModel(modelId: string): string[] | null {
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
const model = provider.models.find((m) => m.id.toLowerCase() === modelId.toLowerCase())
if (model?.capabilities.reasoningEffort) {
return model.capabilities.reasoningEffort.values
}
}
return null
}
export function getModelsWithVerbosity(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.verbosity) {
models.push(model.id)
}
}
}
return models
}
/**
* Get the verbosity values for a specific model
* Returns the valid options for that model, or null if the model doesn't support verbosity
*/
export function getVerbosityValuesForModel(modelId: string): string[] | null {
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
const model = provider.models.find((m) => m.id.toLowerCase() === modelId.toLowerCase())
if (model?.capabilities.verbosity) {
return model.capabilities.verbosity.values
}
}
return null
}
/**
* Check if a model supports native structured outputs.
* Handles model IDs with date suffixes (e.g., claude-sonnet-4-5-20250514).
*/
export function supportsNativeStructuredOutputs(modelId: string): boolean {
const normalizedModelId = modelId.toLowerCase()
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.nativeStructuredOutputs) {
const baseModelId = model.id.toLowerCase()
// Check exact match or date-suffixed version (e.g., claude-sonnet-4-5-20250514)
if (normalizedModelId === baseModelId || normalizedModelId.startsWith(`${baseModelId}-`)) {
return true
}
}
}
}
return false
}
/**
* Check if a model supports thinking/reasoning features.
* Returns the thinking capability config if supported, null otherwise.
*/
export function getThinkingCapability(
modelId: string
): NonNullable<ModelCapabilities['thinking']> | null {
const normalizedModelId = modelId.toLowerCase()
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.thinking) {
const baseModelId = model.id.toLowerCase()
if (normalizedModelId === baseModelId || normalizedModelId.startsWith(`${baseModelId}-`)) {
return model.capabilities.thinking
}
}
}
}
return null
}
/**
* Get all models that accept caller-placed prompt-cache breakpoints.
*
* Reads merged provider+model capabilities because prompt caching is declared
* once per provider (every Claude model supports it) with per-model overrides
* only for the minimum prefix length.
*/
export function getModelsWithPromptCaching(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.promptCaching ?? provider.capabilities?.promptCaching) {
models.push(model.id)
}
}
}
return models
}
/**
* Minimum prefix length the model will cache, or `null` when the model does
* not support caller-placed breakpoints.
*/
export function getPromptCachingMinimumTokens(modelId: string): number | null {
return getModelCapabilities(modelId)?.promptCaching?.minimumCacheableTokens ?? null
}
/**
* Get all models that support thinking capability
*/
export function getModelsWithThinking(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.thinking) {
models.push(model.id)
}
}
}
return models
}
/**
* Get the thinking levels for a specific model
* Returns the valid levels for that model, or null if the model doesn't support thinking
*/
export function getThinkingLevelsForModel(modelId: string): string[] | null {
const capability = getThinkingCapability(modelId)
return capability?.levels ?? null
}
const ALL_MODEL_LEVEL_VALUES = new Set<string>()
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
for (const value of model.capabilities.reasoningEffort?.values ?? []) {
ALL_MODEL_LEVEL_VALUES.add(value)
}
for (const value of model.capabilities.verbosity?.values ?? []) {
ALL_MODEL_LEVEL_VALUES.add(value)
}
for (const level of model.capabilities.thinking?.levels ?? []) {
ALL_MODEL_LEVEL_VALUES.add(level)
}
}
}
/**
* Whether a string is a tuning level some model in the catalogue declares, regardless of which.
*
* Callers that need to put a caller-supplied level into a log or an error gate on this first.
* These fields accept variable and environment references, so an unrecognized value is not
* necessarily a mistyped level — it can be whatever that reference resolved to, up to and
* including secret content that must never be echoed.
*/
export function isKnownModelLevelValue(value: string): boolean {
return ALL_MODEL_LEVEL_VALUES.has(value)
}
/**
* Per-provider defaults for thinking stream visibility, used when a model does
* not declare `capabilities.thinking.streamed` explicitly. Gemini and OpenAI
* stream summaries only; Bedrock and Meta do not expose reasoning text;
* OpenAI-compatible vendors that expose reasoning stream the raw chain of
* thought.
*/
const PROVIDER_THINKING_STREAM_DEFAULTS: Record<string, ThinkingStreamVisibility> = {
google: 'summary',
vertex: 'summary',
openai: 'summary',
'azure-openai': 'summary',
bedrock: 'none',
meta: 'none',
}
/**
* What a reasoning-capable model's thinking looks like on the agent-events
* stream (canvas terminal, opted-in deployed chat). Returns null for models
* with no thinking or reasoning-effort capability. Explicit per-model
* `capabilities.thinking.streamed` wins over the provider default; providers
* without a default stream the raw chain of thought when the vendor emits it.
*/
export function getThinkingStreamVisibility(modelId: string): ThinkingStreamVisibility | null {
const normalizedModelId = modelId.toLowerCase()
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
const baseModelId = model.id.toLowerCase()
if (normalizedModelId !== baseModelId && !normalizedModelId.startsWith(`${baseModelId}-`)) {
continue
}
if (!model.capabilities.thinking && !model.capabilities.reasoningEffort) {
return null
}
return (
model.capabilities.thinking?.streamed ??
PROVIDER_THINKING_STREAM_DEFAULTS[provider.id] ??
'full'
)
}
}
return null
}
/**
* Get all models that support deep research capability
*/
export function getModelsWithDeepResearch(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.deepResearch) {
models.push(model.id)
}
}
}
return models
}
/**
* Get all models that explicitly disable memory support (memory: false).
* Models without this capability default to supporting memory.
*/
export function getModelsWithoutMemory(): string[] {
const models: string[] = []
for (const provider of Object.values(PROVIDER_DEFINITIONS)) {
for (const model of provider.models) {
if (model.capabilities.memory === false) {
models.push(model.id)
}
}
}
return models
}
/**
* Get the max output tokens for a specific model.
*
* @param modelId - The model ID
*/
export function getMaxOutputTokensForModel(modelId: string): number {
const normalizedModelId = modelId.toLowerCase()
const STANDARD_MAX_OUTPUT_TOKENS = 4096
const allModels = Object.values(PROVIDER_DEFINITIONS).flatMap((provider) => provider.models)
const exactMatch = allModels.find((model) => model.id.toLowerCase() === normalizedModelId)
if (exactMatch) {
return exactMatch.capabilities.maxOutputTokens || STANDARD_MAX_OUTPUT_TOKENS
}
for (const model of allModels) {
const baseModelId = model.id.toLowerCase()
if (normalizedModelId.startsWith(`${baseModelId}-`)) {
return model.capabilities.maxOutputTokens || STANDARD_MAX_OUTPUT_TOKENS
}
}
return STANDARD_MAX_OUTPUT_TOKENS
}