diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index c28b475d..665ac4a7 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -62,48 +62,11 @@ async function fetchOpenRouterModels(): Promise { let provider = ""; let modelKey = model.id; - // Map provider prefixes to our provider names - if (model.id.startsWith("google/")) { - provider = "google"; - modelKey = model.id.replace("google/", ""); - } else if (model.id.startsWith("openai/")) { - provider = "openai"; - modelKey = model.id.replace("openai/", ""); - } else if (model.id.startsWith("anthropic/")) { - provider = "anthropic"; - modelKey = model.id.replace("anthropic/", ""); - - // Fix dot notation to dash notation for ALL Anthropic models - modelKey = modelKey.replace(/\./g, "-"); - - // Map version-less models to -latest aliases - if (modelKey === "claude-3-5-haiku") { - modelKey = "claude-3-5-haiku-latest"; - } else if (modelKey === "claude-3-5-sonnet") { - modelKey = "claude-3-5-sonnet-latest"; - } else if (modelKey === "claude-3-7-sonnet") { - modelKey = "claude-3-7-sonnet-latest"; - } else if (modelKey === "claude-3-7-sonnet:thinking") { - modelKey = "claude-3-7-sonnet-latest:thinking"; - } - // Map numbered versions to proper format - else if (modelKey === "claude-opus-4-1") { - modelKey = "claude-opus-4-1"; - } else if (modelKey === "claude-opus-4") { - modelKey = "claude-opus-4-0"; - } else if (modelKey === "claude-sonnet-4") { - modelKey = "claude-sonnet-4-0"; - } - // Map old 3.x models to their specific dates - else if (modelKey === "claude-3-haiku") { - modelKey = "claude-3-haiku-20240307"; - } else if (modelKey === "claude-3-sonnet") { - modelKey = "claude-3-sonnet-20240229"; - } else if (modelKey === "claude-3-opus") { - modelKey = "claude-3-opus-20240229"; - } else { - modelKey = modelKey.replace("\.", "-"); - } + // Skip models that we get from models.dev (Anthropic, Google, OpenAI) + if (model.id.startsWith("google/") || + model.id.startsWith("openai/") || + model.id.startsWith("anthropic/")) { + continue; } else if (model.id.startsWith("x-ai/")) { provider = "xai"; modelKey = model.id.replace("x-ai/", ""); @@ -113,8 +76,8 @@ async function fetchOpenRouterModels(): Promise { modelKey = model.id; // Keep full ID for OpenRouter } - // Skip if not one of our supported providers - if (!["google", "openai", "anthropic", "xai", "openrouter"].includes(provider)) { + // Skip if not one of our supported providers from OpenRouter + if (!["xai", "openrouter"].includes(provider)) { continue; } @@ -172,6 +135,78 @@ async function loadModelsDevData(): Promise { const models: NormalizedModel[] = []; + // Process Anthropic models + if (data.anthropic?.models) { + for (const [modelId, model] of Object.entries(data.anthropic.models)) { + const m = model as ModelsDevModel; + if (m.tool_call !== true) continue; + + models.push({ + id: modelId, + name: m.name || modelId, + provider: "anthropic", + reasoning: m.reasoning === true, + input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"], + cost: { + input: m.cost?.input || 0, + output: m.cost?.output || 0, + cacheRead: m.cost?.cache_read || 0, + cacheWrite: m.cost?.cache_write || 0, + }, + contextWindow: m.limit?.context || 4096, + maxTokens: m.limit?.output || 4096, + }); + } + } + + // Process Google models + if (data.google?.models) { + for (const [modelId, model] of Object.entries(data.google.models)) { + const m = model as ModelsDevModel; + if (m.tool_call !== true) continue; + + models.push({ + id: modelId, + name: m.name || modelId, + provider: "google", + reasoning: m.reasoning === true, + input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"], + cost: { + input: m.cost?.input || 0, + output: m.cost?.output || 0, + cacheRead: m.cost?.cache_read || 0, + cacheWrite: m.cost?.cache_write || 0, + }, + contextWindow: m.limit?.context || 4096, + maxTokens: m.limit?.output || 4096, + }); + } + } + + // Process OpenAI models + if (data.openai?.models) { + for (const [modelId, model] of Object.entries(data.openai.models)) { + const m = model as ModelsDevModel; + if (m.tool_call !== true) continue; + + models.push({ + id: modelId, + name: m.name || modelId, + provider: "openai", + reasoning: m.reasoning === true, + input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"], + cost: { + input: m.cost?.input || 0, + output: m.cost?.output || 0, + cacheRead: m.cost?.cache_read || 0, + cacheWrite: m.cost?.cache_write || 0, + }, + contextWindow: m.limit?.context || 4096, + maxTokens: m.limit?.output || 4096, + }); + } + } + // Process Groq models if (data.groq?.models) { for (const [modelId, model] of Object.entries(data.groq.models)) { @@ -231,11 +266,13 @@ async function loadModelsDevData(): Promise { } async function generateModels() { - // Fetch all models - const openRouterModels = await fetchOpenRouterModels(); + // Fetch models from both sources + // models.dev: Anthropic, Google, OpenAI, Groq, Cerebras + // OpenRouter: xAI and other providers (excluding Anthropic, Google, OpenAI) const modelsDevModels = await loadModelsDevData(); + const openRouterModels = await fetchOpenRouterModels(); - // Combine models (models.dev takes priority for Groq/Cerebras) + // Combine models (models.dev has priority) const allModels = [...modelsDevModels, ...openRouterModels]; // Group by provider and deduplicate by model ID diff --git a/packages/ai/src/models.generated.ts b/packages/ai/src/models.generated.ts index f29f39ce..8dfaccd5 100644 --- a/packages/ai/src/models.generated.ts +++ b/packages/ai/src/models.generated.ts @@ -4,6 +4,633 @@ import type { Model } from "./types.js"; export const PROVIDERS = { + anthropic: { + models: { + "claude-3-7-sonnet-20250219": { + id: "claude-3-7-sonnet-20250219", + name: "Claude Sonnet 3.7", + provider: "anthropic", + reasoning: true, + input: ["text", "image"], + cost: { + input: 3, + output: 15, + cacheRead: 0.3, + cacheWrite: 3.75, + }, + contextWindow: 200000, + maxTokens: 64000, + } satisfies Model, + "claude-opus-4-1-20250805": { + id: "claude-opus-4-1-20250805", + name: "Claude Opus 4.1", + provider: "anthropic", + reasoning: true, + input: ["text", "image"], + cost: { + input: 15, + output: 75, + cacheRead: 1.5, + cacheWrite: 18.75, + }, + contextWindow: 200000, + maxTokens: 32000, + } satisfies Model, + "claude-3-haiku-20240307": { + id: "claude-3-haiku-20240307", + name: "Claude Haiku 3", + provider: "anthropic", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.25, + output: 1.25, + cacheRead: 0.03, + cacheWrite: 0.3, + }, + contextWindow: 200000, + maxTokens: 4096, + } satisfies Model, + "claude-3-5-haiku-20241022": { + id: "claude-3-5-haiku-20241022", + name: "Claude Haiku 3.5", + provider: "anthropic", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.8, + output: 4, + cacheRead: 0.08, + cacheWrite: 1, + }, + contextWindow: 200000, + maxTokens: 8192, + } satisfies Model, + "claude-opus-4-20250514": { + id: "claude-opus-4-20250514", + name: "Claude Opus 4", + provider: "anthropic", + reasoning: true, + input: ["text", "image"], + cost: { + input: 15, + output: 75, + cacheRead: 1.5, + cacheWrite: 18.75, + }, + contextWindow: 200000, + maxTokens: 32000, + } satisfies Model, + "claude-3-5-sonnet-20241022": { + id: "claude-3-5-sonnet-20241022", + name: "Claude Sonnet 3.5 v2", + provider: "anthropic", + reasoning: false, + input: ["text", "image"], + cost: { + input: 3, + output: 15, + cacheRead: 0.3, + cacheWrite: 3.75, + }, + contextWindow: 200000, + maxTokens: 8192, + } satisfies Model, + "claude-3-5-sonnet-20240620": { + id: "claude-3-5-sonnet-20240620", + name: "Claude Sonnet 3.5", + provider: "anthropic", + reasoning: false, + input: ["text", "image"], + cost: { + input: 3, + output: 15, + cacheRead: 0.3, + cacheWrite: 3.75, + }, + contextWindow: 200000, + maxTokens: 8192, + } satisfies Model, + "claude-3-sonnet-20240229": { + id: "claude-3-sonnet-20240229", + name: "Claude Sonnet 3", + provider: "anthropic", + reasoning: false, + input: ["text", "image"], + cost: { + input: 3, + output: 15, + cacheRead: 0.3, + cacheWrite: 0.3, + }, + contextWindow: 200000, + maxTokens: 4096, + } satisfies Model, + "claude-sonnet-4-20250514": { + id: "claude-sonnet-4-20250514", + name: "Claude Sonnet 4", + provider: "anthropic", + reasoning: true, + input: ["text", "image"], + cost: { + input: 3, + output: 15, + cacheRead: 0.3, + cacheWrite: 3.75, + }, + contextWindow: 200000, + maxTokens: 64000, + } satisfies Model, + "claude-3-opus-20240229": { + id: "claude-3-opus-20240229", + name: "Claude Opus 3", + provider: "anthropic", + reasoning: false, + input: ["text", "image"], + cost: { + input: 15, + output: 75, + cacheRead: 1.5, + cacheWrite: 18.75, + }, + contextWindow: 200000, + maxTokens: 4096, + } satisfies Model, + }, + }, + google: { + models: { + "gemini-2.5-flash-preview-05-20": { + id: "gemini-2.5-flash-preview-05-20", + name: "Gemini 2.5 Flash Preview 05-20", + provider: "google", + reasoning: true, + input: ["text", "image"], + cost: { + input: 0.15, + output: 0.6, + cacheRead: 0.0375, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 65536, + } satisfies Model, + "gemini-2.5-pro": { + id: "gemini-2.5-pro", + name: "Gemini 2.5 Pro", + provider: "google", + reasoning: true, + input: ["text", "image"], + cost: { + input: 1.25, + output: 10, + cacheRead: 0.31, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 65536, + } satisfies Model, + "gemini-1.5-flash": { + id: "gemini-1.5-flash", + name: "Gemini 1.5 Flash", + provider: "google", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.075, + output: 0.3, + cacheRead: 0.01875, + cacheWrite: 0, + }, + contextWindow: 1000000, + maxTokens: 8192, + } satisfies Model, + "gemini-2.0-flash-lite": { + id: "gemini-2.0-flash-lite", + name: "Gemini 2.0 Flash Lite", + provider: "google", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.075, + output: 0.3, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 8192, + } satisfies Model, + "gemini-1.5-pro": { + id: "gemini-1.5-pro", + name: "Gemini 1.5 Pro", + provider: "google", + reasoning: false, + input: ["text", "image"], + cost: { + input: 1.25, + output: 5, + cacheRead: 0.3125, + cacheWrite: 0, + }, + contextWindow: 1000000, + maxTokens: 8192, + } satisfies Model, + "gemini-1.5-flash-8b": { + id: "gemini-1.5-flash-8b", + name: "Gemini 1.5 Flash-8B", + provider: "google", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.0375, + output: 0.15, + cacheRead: 0.01, + cacheWrite: 0, + }, + contextWindow: 1000000, + maxTokens: 8192, + } satisfies Model, + "gemini-2.5-flash": { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + provider: "google", + reasoning: true, + input: ["text", "image"], + cost: { + input: 0.3, + output: 2.5, + cacheRead: 0.075, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 65536, + } satisfies Model, + "gemini-2.5-pro-preview-06-05": { + id: "gemini-2.5-pro-preview-06-05", + name: "Gemini 2.5 Pro Preview 06-05", + provider: "google", + reasoning: true, + input: ["text", "image"], + cost: { + input: 1.25, + output: 10, + cacheRead: 0.31, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 65536, + } satisfies Model, + "gemini-2.5-pro-preview-05-06": { + id: "gemini-2.5-pro-preview-05-06", + name: "Gemini 2.5 Pro Preview 05-06", + provider: "google", + reasoning: true, + input: ["text", "image"], + cost: { + input: 1.25, + output: 10, + cacheRead: 0.31, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 65536, + } satisfies Model, + "gemini-2.0-flash": { + id: "gemini-2.0-flash", + name: "Gemini 2.0 Flash", + provider: "google", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.1, + output: 0.4, + cacheRead: 0.025, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 8192, + } satisfies Model, + "gemini-2.5-flash-lite-preview-06-17": { + id: "gemini-2.5-flash-lite-preview-06-17", + name: "Gemini 2.5 Flash Lite Preview 06-17", + provider: "google", + reasoning: true, + input: ["text", "image"], + cost: { + input: 0.1, + output: 0.4, + cacheRead: 0.025, + cacheWrite: 0, + }, + contextWindow: 65536, + maxTokens: 65536, + } satisfies Model, + "gemini-2.5-flash-preview-04-17": { + id: "gemini-2.5-flash-preview-04-17", + name: "Gemini 2.5 Flash Preview 04-17", + provider: "google", + reasoning: true, + input: ["text", "image"], + cost: { + input: 0.15, + output: 0.6, + cacheRead: 0.0375, + cacheWrite: 0, + }, + contextWindow: 1048576, + maxTokens: 65536, + } satisfies Model, + }, + }, + openai: { + models: { + "gpt-5-nano": { + id: "gpt-5-nano", + name: "GPT-5 Nano", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 0.05, + output: 0.4, + cacheRead: 0.01, + cacheWrite: 0, + }, + contextWindow: 400000, + maxTokens: 128000, + } satisfies Model, + "o3-pro": { + id: "o3-pro", + name: "o3-pro", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 20, + output: 80, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + "codex-mini-latest": { + id: "codex-mini-latest", + name: "Codex Mini", + provider: "openai", + reasoning: true, + input: ["text"], + cost: { + input: 1.5, + output: 6, + cacheRead: 0.375, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + "gpt-4.1": { + id: "gpt-4.1", + name: "GPT-4.1", + provider: "openai", + reasoning: false, + input: ["text", "image"], + cost: { + input: 2, + output: 8, + cacheRead: 0.5, + cacheWrite: 0, + }, + contextWindow: 1047576, + maxTokens: 32768, + } satisfies Model, + "gpt-4-turbo": { + id: "gpt-4-turbo", + name: "GPT-4 Turbo", + provider: "openai", + reasoning: false, + input: ["text", "image"], + cost: { + input: 10, + output: 30, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 128000, + maxTokens: 4096, + } satisfies Model, + o1: { + id: "o1", + name: "o1", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 15, + output: 60, + cacheRead: 7.5, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + "o3-deep-research": { + id: "o3-deep-research", + name: "o3-deep-research", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 10, + output: 40, + cacheRead: 2.5, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + "gpt-5": { + id: "gpt-5", + name: "GPT-5", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 1.25, + output: 10, + cacheRead: 0.13, + cacheWrite: 0, + }, + contextWindow: 400000, + maxTokens: 128000, + } satisfies Model, + "o1-pro": { + id: "o1-pro", + name: "o1-pro", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 150, + output: 600, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + o3: { + id: "o3", + name: "o3", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 8, + cacheRead: 0.5, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + "gpt-5-mini": { + id: "gpt-5-mini", + name: "GPT-5 Mini", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 0.25, + output: 2, + cacheRead: 0.03, + cacheWrite: 0, + }, + contextWindow: 400000, + maxTokens: 128000, + } satisfies Model, + "o4-mini-deep-research": { + id: "o4-mini-deep-research", + name: "o4-mini-deep-research", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 2, + output: 8, + cacheRead: 0.5, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + "gpt-4o-mini": { + id: "gpt-4o-mini", + name: "GPT-4o mini", + provider: "openai", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.15, + output: 0.6, + cacheRead: 0.08, + cacheWrite: 0, + }, + contextWindow: 128000, + maxTokens: 16384, + } satisfies Model, + "gpt-4.1-nano": { + id: "gpt-4.1-nano", + name: "GPT-4.1 nano", + provider: "openai", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.1, + output: 0.4, + cacheRead: 0.03, + cacheWrite: 0, + }, + contextWindow: 1047576, + maxTokens: 32768, + } satisfies Model, + "gpt-4.1-mini": { + id: "gpt-4.1-mini", + name: "GPT-4.1 mini", + provider: "openai", + reasoning: false, + input: ["text", "image"], + cost: { + input: 0.4, + output: 1.6, + cacheRead: 0.1, + cacheWrite: 0, + }, + contextWindow: 1047576, + maxTokens: 32768, + } satisfies Model, + "gpt-4o": { + id: "gpt-4o", + name: "GPT-4o", + provider: "openai", + reasoning: false, + input: ["text", "image"], + cost: { + input: 2.5, + output: 10, + cacheRead: 1.25, + cacheWrite: 0, + }, + contextWindow: 128000, + maxTokens: 16384, + } satisfies Model, + "gpt-4": { + id: "gpt-4", + name: "GPT-4", + provider: "openai", + reasoning: false, + input: ["text"], + cost: { + input: 30, + output: 60, + cacheRead: 0, + cacheWrite: 0, + }, + contextWindow: 8192, + maxTokens: 8192, + } satisfies Model, + "o4-mini": { + id: "o4-mini", + name: "o4-mini", + provider: "openai", + reasoning: true, + input: ["text", "image"], + cost: { + input: 1.1, + output: 4.4, + cacheRead: 0.28, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + "o3-mini": { + id: "o3-mini", + name: "o3-mini", + provider: "openai", + reasoning: true, + input: ["text"], + cost: { + input: 1.1, + output: 4.4, + cacheRead: 0.55, + cacheWrite: 0, + }, + contextWindow: 200000, + maxTokens: 100000, + } satisfies Model, + }, + }, groq: { models: { "llama-3.1-8b-instant": { @@ -2036,858 +2663,6 @@ export const PROVIDERS = { } satisfies Model, }, }, - openai: { - models: { - "gpt-4o-audio-preview": { - id: "gpt-4o-audio-preview", - name: "OpenAI: GPT-4o Audio", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 2.5, - output: 10, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 16384, - } satisfies Model, - "gpt-5": { - id: "gpt-5", - name: "OpenAI: GPT-5", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 1.25, - output: 10, - cacheRead: 0.125, - cacheWrite: 0, - }, - contextWindow: 400000, - maxTokens: 128000, - } satisfies Model, - "gpt-5-mini": { - id: "gpt-5-mini", - name: "OpenAI: GPT-5 Mini", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 0.25, - output: 2, - cacheRead: 0.024999999999999998, - cacheWrite: 0, - }, - contextWindow: 400000, - maxTokens: 128000, - } satisfies Model, - "gpt-5-nano": { - id: "gpt-5-nano", - name: "OpenAI: GPT-5 Nano", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 0.049999999999999996, - output: 0.39999999999999997, - cacheRead: 0.005, - cacheWrite: 0, - }, - contextWindow: 400000, - maxTokens: 128000, - } satisfies Model, - "gpt-oss-120b": { - id: "gpt-oss-120b", - name: "OpenAI: gpt-oss-120b", - provider: "openai", - reasoning: true, - input: ["text"], - cost: { - input: 0.072, - output: 0.28, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 131000, - maxTokens: 131000, - } satisfies Model, - "gpt-oss-20b": { - id: "gpt-oss-20b", - name: "OpenAI: gpt-oss-20b", - provider: "openai", - reasoning: true, - input: ["text"], - cost: { - input: 0.04, - output: 0.15, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 131000, - maxTokens: 131000, - } satisfies Model, - "o3-pro": { - id: "o3-pro", - name: "OpenAI: o3 Pro", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 20, - output: 80, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - "codex-mini": { - id: "codex-mini", - name: "OpenAI: Codex Mini", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 1.5, - output: 6, - cacheRead: 0.375, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - "o4-mini-high": { - id: "o4-mini-high", - name: "OpenAI: o4 Mini High", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 1.1, - output: 4.4, - cacheRead: 0.275, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - o3: { - id: "o3", - name: "OpenAI: o3", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 2, - output: 8, - cacheRead: 0.5, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - "o4-mini": { - id: "o4-mini", - name: "OpenAI: o4 Mini", - provider: "openai", - reasoning: true, - input: ["text", "image"], - cost: { - input: 1.1, - output: 4.4, - cacheRead: 0.275, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - "gpt-4.1": { - id: "gpt-4.1", - name: "OpenAI: GPT-4.1", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 2, - output: 8, - cacheRead: 0.5, - cacheWrite: 0, - }, - contextWindow: 1047576, - maxTokens: 32768, - } satisfies Model, - "gpt-4.1-mini": { - id: "gpt-4.1-mini", - name: "OpenAI: GPT-4.1 Mini", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.39999999999999997, - output: 1.5999999999999999, - cacheRead: 0.09999999999999999, - cacheWrite: 0, - }, - contextWindow: 1047576, - maxTokens: 32768, - } satisfies Model, - "gpt-4.1-nano": { - id: "gpt-4.1-nano", - name: "OpenAI: GPT-4.1 Nano", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.09999999999999999, - output: 0.39999999999999997, - cacheRead: 0.024999999999999998, - cacheWrite: 0, - }, - contextWindow: 1047576, - maxTokens: 32768, - } satisfies Model, - "o3-mini-high": { - id: "o3-mini-high", - name: "OpenAI: o3 Mini High", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 1.1, - output: 4.4, - cacheRead: 0.55, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - "o3-mini": { - id: "o3-mini", - name: "OpenAI: o3 Mini", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 1.1, - output: 4.4, - cacheRead: 0.55, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - o1: { - id: "o1", - name: "OpenAI: o1", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 15, - output: 60, - cacheRead: 7.5, - cacheWrite: 0, - }, - contextWindow: 200000, - maxTokens: 100000, - } satisfies Model, - "gpt-4o-2024-11-20": { - id: "gpt-4o-2024-11-20", - name: "OpenAI: GPT-4o (2024-11-20)", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 2.5, - output: 10, - cacheRead: 1.25, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 16384, - } satisfies Model, - "gpt-4o-2024-08-06": { - id: "gpt-4o-2024-08-06", - name: "OpenAI: GPT-4o (2024-08-06)", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 2.5, - output: 10, - cacheRead: 1.25, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 16384, - } satisfies Model, - "gpt-4o-mini": { - id: "gpt-4o-mini", - name: "OpenAI: GPT-4o-mini", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.15, - output: 0.6, - cacheRead: 0.075, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 16384, - } satisfies Model, - "gpt-4o-mini-2024-07-18": { - id: "gpt-4o-mini-2024-07-18", - name: "OpenAI: GPT-4o-mini (2024-07-18)", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.15, - output: 0.6, - cacheRead: 0.075, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 16384, - } satisfies Model, - "gpt-4o": { - id: "gpt-4o", - name: "OpenAI: GPT-4o", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 2.5, - output: 10, - cacheRead: 1.25, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 16384, - } satisfies Model, - "gpt-4o:extended": { - id: "gpt-4o:extended", - name: "OpenAI: GPT-4o (extended)", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 6, - output: 18, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 64000, - } satisfies Model, - "gpt-4o-2024-05-13": { - id: "gpt-4o-2024-05-13", - name: "OpenAI: GPT-4o (2024-05-13)", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 5, - output: 15, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 4096, - } satisfies Model, - "gpt-4-turbo": { - id: "gpt-4-turbo", - name: "OpenAI: GPT-4 Turbo", - provider: "openai", - reasoning: false, - input: ["text", "image"], - cost: { - input: 10, - output: 30, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 4096, - } satisfies Model, - "gpt-3.5-turbo-0613": { - id: "gpt-3.5-turbo-0613", - name: "OpenAI: GPT-3.5 Turbo (older v0613)", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 1, - output: 2, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 4095, - maxTokens: 4096, - } satisfies Model, - "gpt-4-turbo-preview": { - id: "gpt-4-turbo-preview", - name: "OpenAI: GPT-4 Turbo Preview", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 10, - output: 30, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 4096, - } satisfies Model, - "gpt-4-1106-preview": { - id: "gpt-4-1106-preview", - name: "OpenAI: GPT-4 Turbo (older v1106)", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 10, - output: 30, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 128000, - maxTokens: 4096, - } satisfies Model, - "gpt-3.5-turbo-16k": { - id: "gpt-3.5-turbo-16k", - name: "OpenAI: GPT-3.5 Turbo 16k", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 3, - output: 4, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 16385, - maxTokens: 4096, - } satisfies Model, - "gpt-4": { - id: "gpt-4", - name: "OpenAI: GPT-4", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 30, - output: 60, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 8191, - maxTokens: 4096, - } satisfies Model, - "gpt-4-0314": { - id: "gpt-4-0314", - name: "OpenAI: GPT-4 (older v0314)", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 30, - output: 60, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 8191, - maxTokens: 4096, - } satisfies Model, - "gpt-3.5-turbo": { - id: "gpt-3.5-turbo", - name: "OpenAI: GPT-3.5 Turbo", - provider: "openai", - reasoning: false, - input: ["text"], - cost: { - input: 0.5, - output: 1.5, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 16385, - maxTokens: 4096, - } satisfies Model, - }, - }, - anthropic: { - models: { - "claude-opus-4-1": { - id: "claude-opus-4-1", - name: "Anthropic: Claude Opus 4.1", - provider: "anthropic", - reasoning: true, - input: ["text", "image"], - cost: { - input: 15, - output: 75, - cacheRead: 1.5, - cacheWrite: 18.75, - }, - contextWindow: 200000, - maxTokens: 32000, - } satisfies Model, - "claude-opus-4-0": { - id: "claude-opus-4-0", - name: "Anthropic: Claude Opus 4", - provider: "anthropic", - reasoning: true, - input: ["text", "image"], - cost: { - input: 15, - output: 75, - cacheRead: 1.5, - cacheWrite: 18.75, - }, - contextWindow: 200000, - maxTokens: 32000, - } satisfies Model, - "claude-sonnet-4-0": { - id: "claude-sonnet-4-0", - name: "Anthropic: Claude Sonnet 4", - provider: "anthropic", - reasoning: true, - input: ["text", "image"], - cost: { - input: 3, - output: 15, - cacheRead: 0.3, - cacheWrite: 3.75, - }, - contextWindow: 1000000, - maxTokens: 64000, - } satisfies Model, - "claude-3-7-sonnet-latest": { - id: "claude-3-7-sonnet-latest", - name: "Anthropic: Claude 3.7 Sonnet", - provider: "anthropic", - reasoning: true, - input: ["text", "image"], - cost: { - input: 3, - output: 15, - cacheRead: 0.3, - cacheWrite: 3.75, - }, - contextWindow: 200000, - maxTokens: 64000, - } satisfies Model, - "claude-3-7-sonnet-latest:thinking": { - id: "claude-3-7-sonnet-latest:thinking", - name: "Anthropic: Claude 3.7 Sonnet (thinking)", - provider: "anthropic", - reasoning: true, - input: ["text", "image"], - cost: { - input: 3, - output: 15, - cacheRead: 0.3, - cacheWrite: 3.75, - }, - contextWindow: 200000, - maxTokens: 64000, - } satisfies Model, - "claude-3-5-haiku-20241022": { - id: "claude-3-5-haiku-20241022", - name: "Anthropic: Claude 3.5 Haiku (2024-10-22)", - provider: "anthropic", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.7999999999999999, - output: 4, - cacheRead: 0.08, - cacheWrite: 1, - }, - contextWindow: 200000, - maxTokens: 8192, - } satisfies Model, - "claude-3-5-haiku-latest": { - id: "claude-3-5-haiku-latest", - name: "Anthropic: Claude 3.5 Haiku", - provider: "anthropic", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.7999999999999999, - output: 4, - cacheRead: 0.08, - cacheWrite: 1, - }, - contextWindow: 200000, - maxTokens: 8192, - } satisfies Model, - "claude-3-5-sonnet-latest": { - id: "claude-3-5-sonnet-latest", - name: "Anthropic: Claude 3.5 Sonnet", - provider: "anthropic", - reasoning: false, - input: ["text", "image"], - cost: { - input: 3, - output: 15, - cacheRead: 0.3, - cacheWrite: 3.75, - }, - contextWindow: 200000, - maxTokens: 8192, - } satisfies Model, - "claude-3-5-sonnet-20240620": { - id: "claude-3-5-sonnet-20240620", - name: "Anthropic: Claude 3.5 Sonnet (2024-06-20)", - provider: "anthropic", - reasoning: false, - input: ["text", "image"], - cost: { - input: 3, - output: 15, - cacheRead: 0.3, - cacheWrite: 3.75, - }, - contextWindow: 200000, - maxTokens: 8192, - } satisfies Model, - "claude-3-haiku-20240307": { - id: "claude-3-haiku-20240307", - name: "Anthropic: Claude 3 Haiku", - provider: "anthropic", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.25, - output: 1.25, - cacheRead: 0.03, - cacheWrite: 0.3, - }, - contextWindow: 200000, - maxTokens: 4096, - } satisfies Model, - "claude-3-opus-20240229": { - id: "claude-3-opus-20240229", - name: "Anthropic: Claude 3 Opus", - provider: "anthropic", - reasoning: false, - input: ["text", "image"], - cost: { - input: 15, - output: 75, - cacheRead: 1.5, - cacheWrite: 18.75, - }, - contextWindow: 200000, - maxTokens: 4096, - } satisfies Model, - }, - }, - google: { - models: { - "gemini-2.5-flash-lite": { - id: "gemini-2.5-flash-lite", - name: "Google: Gemini 2.5 Flash Lite", - provider: "google", - reasoning: true, - input: ["text", "image"], - cost: { - input: 0.09999999999999999, - output: 0.39999999999999997, - cacheRead: 0.024999999999999998, - cacheWrite: 0.18330000000000002, - }, - contextWindow: 1048576, - maxTokens: 65535, - } satisfies Model, - "gemini-2.5-flash-lite-preview-06-17": { - id: "gemini-2.5-flash-lite-preview-06-17", - name: "Google: Gemini 2.5 Flash Lite Preview 06-17", - provider: "google", - reasoning: true, - input: ["text", "image"], - cost: { - input: 0.09999999999999999, - output: 0.39999999999999997, - cacheRead: 0.024999999999999998, - cacheWrite: 0.18330000000000002, - }, - contextWindow: 1048576, - maxTokens: 65535, - } satisfies Model, - "gemini-2.5-flash": { - id: "gemini-2.5-flash", - name: "Google: Gemini 2.5 Flash", - provider: "google", - reasoning: true, - input: ["text", "image"], - cost: { - input: 0.3, - output: 2.5, - cacheRead: 0.075, - cacheWrite: 0.3833, - }, - contextWindow: 1048576, - maxTokens: 65535, - } satisfies Model, - "gemini-2.5-pro": { - id: "gemini-2.5-pro", - name: "Google: Gemini 2.5 Pro", - provider: "google", - reasoning: true, - input: ["text", "image"], - cost: { - input: 1.25, - output: 10, - cacheRead: 0.31, - cacheWrite: 1.625, - }, - contextWindow: 1048576, - maxTokens: 65536, - } satisfies Model, - "gemini-2.5-pro-preview": { - id: "gemini-2.5-pro-preview", - name: "Google: Gemini 2.5 Pro Preview 06-05", - provider: "google", - reasoning: true, - input: ["text", "image"], - cost: { - input: 1.25, - output: 10, - cacheRead: 0.31, - cacheWrite: 1.625, - }, - contextWindow: 1048576, - maxTokens: 65536, - } satisfies Model, - "gemini-2.5-pro-preview-05-06": { - id: "gemini-2.5-pro-preview-05-06", - name: "Google: Gemini 2.5 Pro Preview 05-06", - provider: "google", - reasoning: true, - input: ["text", "image"], - cost: { - input: 1.25, - output: 10, - cacheRead: 0.31, - cacheWrite: 1.625, - }, - contextWindow: 1048576, - maxTokens: 65535, - } satisfies Model, - "gemini-2.5-pro-exp-03-25": { - id: "gemini-2.5-pro-exp-03-25", - name: "Google: Gemini 2.5 Pro Experimental", - provider: "google", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 1048576, - maxTokens: 65535, - } satisfies Model, - "gemini-2.0-flash-lite-001": { - id: "gemini-2.0-flash-lite-001", - name: "Google: Gemini 2.0 Flash Lite", - provider: "google", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.075, - output: 0.3, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 1048576, - maxTokens: 8192, - } satisfies Model, - "gemini-2.0-flash-001": { - id: "gemini-2.0-flash-001", - name: "Google: Gemini 2.0 Flash", - provider: "google", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.09999999999999999, - output: 0.39999999999999997, - cacheRead: 0.024999999999999998, - cacheWrite: 0.18330000000000002, - }, - contextWindow: 1048576, - maxTokens: 8192, - } satisfies Model, - "gemini-2.0-flash-exp:free": { - id: "gemini-2.0-flash-exp:free", - name: "Google: Gemini 2.0 Flash Experimental (free)", - provider: "google", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0, - output: 0, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 1048576, - maxTokens: 8192, - } satisfies Model, - "gemini-flash-1.5-8b": { - id: "gemini-flash-1.5-8b", - name: "Google: Gemini 1.5 Flash 8B", - provider: "google", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.0375, - output: 0.15, - cacheRead: 0.01, - cacheWrite: 0.0583, - }, - contextWindow: 1000000, - maxTokens: 8192, - } satisfies Model, - "gemini-flash-1.5": { - id: "gemini-flash-1.5", - name: "Google: Gemini 1.5 Flash ", - provider: "google", - reasoning: false, - input: ["text", "image"], - cost: { - input: 0.075, - output: 0.3, - cacheRead: 0.01875, - cacheWrite: 0.1583, - }, - contextWindow: 1000000, - maxTokens: 8192, - } satisfies Model, - "gemini-pro-1.5": { - id: "gemini-pro-1.5", - name: "Google: Gemini 1.5 Pro", - provider: "google", - reasoning: false, - input: ["text", "image"], - cost: { - input: 1.25, - output: 5, - cacheRead: 0, - cacheWrite: 0, - }, - contextWindow: 2000000, - maxTokens: 8192, - } satisfies Model, - }, - }, } as const; // Helper type to extract models for each provider diff --git a/packages/ai/src/providers/google.ts b/packages/ai/src/providers/google.ts index c304cf84..ef580b25 100644 --- a/packages/ai/src/providers/google.ts +++ b/packages/ai/src/providers/google.ts @@ -6,7 +6,6 @@ import { type GenerateContentParameters, GoogleGenAI, type Part, - setDefaultBaseUrls, } from "@google/genai"; import { calculateCost } from "../models.js"; import type { diff --git a/packages/ai/src/providers/openai-responses.ts b/packages/ai/src/providers/openai-responses.ts index 271082ab..70cec404 100644 --- a/packages/ai/src/providers/openai-responses.ts +++ b/packages/ai/src/providers/openai-responses.ts @@ -93,12 +93,32 @@ export class OpenAIResponsesLLM implements LLM { } // Add reasoning options for models that support it - if (this.modelInfo?.reasoning && (options?.reasoningEffort || options?.reasoningSummary)) { - params.reasoning = { - effort: options?.reasoningEffort || "medium", - summary: options?.reasoningSummary || "auto", - }; - params.include = ["reasoning.encrypted_content"]; + if (this.modelInfo?.reasoning) { + if (options?.reasoningEffort || options?.reasoningSummary) { + params.reasoning = { + effort: options?.reasoningEffort || "medium", + summary: options?.reasoningSummary || "auto", + }; + params.include = ["reasoning.encrypted_content"]; + } else { + params.reasoning = { + effort: this.modelInfo.name.startsWith("gpt-5") ? "minimal" : null, + summary: null, + }; + + if (this.modelInfo.name.startsWith("gpt-5")) { + // Jesus Christ, see https://community.openai.com/t/need-reasoning-false-option-for-gpt-5/1351588/7 + input.push({ + role: "developer", + content: [ + { + type: "input_text", + text: "# Juice: 0 !important", + }, + ], + }); + } + } } const stream = await this.client.responses.create(params, { diff --git a/packages/ai/test/abort.test.ts b/packages/ai/test/abort.test.ts index d55ef412..ab94b197 100644 --- a/packages/ai/test/abort.test.ts +++ b/packages/ai/test/abort.test.ts @@ -114,7 +114,7 @@ describe("AI Providers Abort Tests", () => { let llm: AnthropicLLM; beforeAll(() => { - llm = new AnthropicLLM(getModel("anthropic", "claude-opus-4-1")!, process.env.ANTHROPIC_OAUTH_TOKEN!); + llm = new AnthropicLLM(getModel("anthropic", "claude-opus-4-1-20250805")!, process.env.ANTHROPIC_OAUTH_TOKEN!); }); it("should abort mid-stream", async () => { diff --git a/packages/ai/test/handoff.test.ts b/packages/ai/test/handoff.test.ts index 6300b76f..2970f0c4 100644 --- a/packages/ai/test/handoff.test.ts +++ b/packages/ai/test/handoff.test.ts @@ -4,7 +4,7 @@ import { OpenAICompletionsLLM } from "../src/providers/openai-completions.js"; import { OpenAIResponsesLLM } from "../src/providers/openai-responses.js"; import { AnthropicLLM } from "../src/providers/anthropic.js"; import type { LLM, Context, AssistantMessage, Tool, Message } from "../src/types.js"; -import { getModel } from "../src/models.js"; +import { createLLM, getModel } from "../src/models.js"; // Tool for testing const weatherTool: Tool = { diff --git a/packages/ai/test/models.ts b/packages/ai/test/models.ts new file mode 100644 index 00000000..745ecbec --- /dev/null +++ b/packages/ai/test/models.ts @@ -0,0 +1,31 @@ +import { GoogleGenAI } from "@google/genai"; +import OpenAI from "openai"; + +const ai = new GoogleGenAI({}); + +async function main() { + /*let pager = await ai.models.list(); + do { + for (const model of pager.page) { + console.log(JSON.stringify(model, null, 2)); + console.log("---"); + } + if (!pager.hasNextPage()) break; + await pager.nextPage(); + } while (true);*/ + + const openai = new OpenAI(); + const response = await openai.models.list(); + do { + const page = response.data; + for (const model of page) { + const info = await openai.models.retrieve(model.id); + console.log(JSON.stringify(model, null, 2)); + console.log("---"); + } + if (!response.hasNextPage()) break; + await response.getNextPage(); + } while (true); +} + +await main(); \ No newline at end of file diff --git a/packages/ai/test/providers.test.ts b/packages/ai/test/providers.test.ts index 36e20b91..fa072d14 100644 --- a/packages/ai/test/providers.test.ts +++ b/packages/ai/test/providers.test.ts @@ -340,11 +340,11 @@ describe("AI Providers E2E Tests", () => { }); }); - describe.skipIf(!process.env.ANTHROPIC_OAUTH_TOKEN)("Anthropic Provider (claude-sonnet-4-0)", () => { + describe.skipIf(!process.env.ANTHROPIC_OAUTH_TOKEN)("Anthropic Provider (claude-sonnet-4-20250514)", () => { let llm: AnthropicLLM; beforeAll(() => { - llm = new AnthropicLLM(getModel("anthropic", "claude-sonnet-4-0")!, process.env.ANTHROPIC_OAUTH_TOKEN!); + llm = new AnthropicLLM(getModel("anthropic", "claude-sonnet-4-20250514")!, process.env.ANTHROPIC_OAUTH_TOKEN!); }); it("should complete basic text generation", async () => {