diff --git a/packages/app/server/src/env.ts b/packages/app/server/src/env.ts index da23dd994..55e345b74 100644 --- a/packages/app/server/src/env.ts +++ b/packages/app/server/src/env.ts @@ -45,6 +45,7 @@ export const env = createEnv({ GROQ_API_KEY: z.string().optional(), XAI_API_KEY: z.string().optional(), OPENROUTER_API_KEY: z.string().optional(), + AI_GATEWAY_API_KEY: z.string().optional(), TAVILY_API_KEY: z.string().optional(), E2B_API_KEY: z.string().optional(), GOOGLE_SERVICE_ACCOUNT_KEY_ENCODED: z.string().optional(), diff --git a/packages/app/server/src/providers/ProviderFactory.ts b/packages/app/server/src/providers/ProviderFactory.ts index 8bc01e719..2730a86d2 100644 --- a/packages/app/server/src/providers/ProviderFactory.ts +++ b/packages/app/server/src/providers/ProviderFactory.ts @@ -21,6 +21,7 @@ import { OpenAIImageProvider } from './OpenAIImageProvider'; import { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; import { OpenRouterProvider } from './OpenRouterProvider'; import { ProviderType } from './ProviderType'; +import { VercelAIGatewayProvider } from './VercelAIGatewayProvider'; import { XAIProvider } from './XAIProvider'; import { VertexAIProvider, @@ -58,6 +59,10 @@ const createChatModelToProviderMapping = (): Record => { case 'Xai': mapping[modelConfig.model_id] = ProviderType.XAI; break; + case 'Vercel AI Gateway': + case 'Vercel': + mapping[modelConfig.model_id] = ProviderType.VERCEL_AI_GATEWAY; + break; // Add other providers as needed default: // Skip models with unsupported providers @@ -192,6 +197,8 @@ export const getProvider = ( return new GroqProvider(stream, model); case ProviderType.XAI: return new XAIProvider(stream, model); + case ProviderType.VERCEL_AI_GATEWAY: + return new VercelAIGatewayProvider(stream, model); default: throw new Error(`Unknown provider type: ${type}`); } diff --git a/packages/app/server/src/providers/ProviderType.ts b/packages/app/server/src/providers/ProviderType.ts index b2514ac80..41ded7703 100644 --- a/packages/app/server/src/providers/ProviderType.ts +++ b/packages/app/server/src/providers/ProviderType.ts @@ -12,4 +12,5 @@ export enum ProviderType { OPENAI_VIDEOS = 'OPENAI_VIDEOS', GROQ = 'GROQ', XAI = 'XAI', + VERCEL_AI_GATEWAY = 'VERCEL_AI_GATEWAY', } diff --git a/packages/app/server/src/providers/VercelAIGatewayProvider.ts b/packages/app/server/src/providers/VercelAIGatewayProvider.ts new file mode 100644 index 000000000..5da2f4e80 --- /dev/null +++ b/packages/app/server/src/providers/VercelAIGatewayProvider.ts @@ -0,0 +1,259 @@ +import { LlmTransactionMetadata, Transaction } from '../types'; +import { getCostPerToken } from '../services/AccountingService'; +import { BaseProvider } from './BaseProvider'; +import { ProviderType } from './ProviderType'; +import { parseSSEGPTFormat } from './GPTProvider'; +import logger from '../logger'; +import { env } from '../env'; + +interface AIGatewayUsage { + inputTokens?: number; + outputTokens?: number; + totalTokens?: number; +} + +interface OpenAICompatibleUsage { + prompt_tokens?: number; + completion_tokens?: number; + total_tokens?: number; +} + +interface AIGatewayResponseBody { + id?: string; + response?: { + id?: string; + }; + usage?: AIGatewayUsage | OpenAICompatibleUsage; +} + +interface AIGatewayStreamPart { + type?: string; + id?: string; + response?: { + id?: string; + }; + usage?: AIGatewayUsage; +} + +const ECHO_VERCEL_MODEL_PREFIX = 'vercel/'; + +function toVercelModelId(model: string): string { + return model.startsWith(ECHO_VERCEL_MODEL_PREFIX) + ? model.slice(ECHO_VERCEL_MODEL_PREFIX.length) + : model; +} + +function isAIGatewayUsage( + usage: AIGatewayUsage | OpenAICompatibleUsage | undefined +): usage is AIGatewayUsage { + return ( + usage !== undefined && + ('inputTokens' in usage || + 'outputTokens' in usage || + 'totalTokens' in usage) + ); +} + +function parseSSEJsonObjects(data: string): unknown[] { + const chunks: unknown[] = []; + + for (const event of data.split('\n\n')) { + const dataLines = event + .split('\n') + .filter(line => line.startsWith('data: ')) + .map(line => line.slice(6)); + + if (dataLines.length === 0) { + continue; + } + + const payload = dataLines.join('\n').trim(); + if (!payload || payload === '[DONE]') { + continue; + } + + try { + chunks.push(JSON.parse(payload)); + } catch (error) { + logger.error(`Error parsing Vercel AI Gateway SSE chunk: ${error}`); + } + } + + return chunks; +} + +export class VercelAIGatewayProvider extends BaseProvider { + private readonly VERCEL_AI_GATEWAY_OPENAI_BASE_URL = + 'https://ai-gateway.vercel.sh/v1'; + private readonly VERCEL_AI_GATEWAY_AI_SDK_BASE_URL = + 'https://ai-gateway.vercel.sh/v1/ai'; + + getType(): ProviderType { + return ProviderType.VERCEL_AI_GATEWAY; + } + + getBaseUrl(reqPath?: string): string { + if ( + reqPath?.includes('/language-model') || + reqPath?.includes('/embedding-model') || + reqPath?.endsWith('/config') + ) { + return this.VERCEL_AI_GATEWAY_AI_SDK_BASE_URL; + } + + return this.VERCEL_AI_GATEWAY_OPENAI_BASE_URL; + } + + override formatUpstreamUrl(req: { path: string; url: string }): string { + const query = req.url.includes('?') + ? req.url.substring(req.url.indexOf('?')) + : ''; + + if (req.path.endsWith('/language-model')) { + return `${this.VERCEL_AI_GATEWAY_AI_SDK_BASE_URL}/language-model${query}`; + } + if (req.path.endsWith('/embedding-model')) { + return `${this.VERCEL_AI_GATEWAY_AI_SDK_BASE_URL}/embedding-model${query}`; + } + if (req.path.endsWith('/config')) { + return `${this.VERCEL_AI_GATEWAY_AI_SDK_BASE_URL}/config${query}`; + } + + return `${this.getBaseUrl(req.path)}${req.path}${query}`; + } + + getApiKey(): string | undefined { + return env.AI_GATEWAY_API_KEY; + } + + override async formatAuthHeaders( + headers: Record + ): Promise> { + const formattedHeaders = await super.formatAuthHeaders(headers); + + delete formattedHeaders['AI-Language-Model-Id']; + delete formattedHeaders['ai-language-model-id']; + formattedHeaders['ai-language-model-id'] = toVercelModelId(this.getModel()); + + return formattedHeaders; + } + + override ensureStreamUsage( + reqBody: Record, + reqPath: string + ): Record { + if (reqPath.includes('/language-model')) { + return reqBody; + } + + return super.ensureStreamUsage(reqBody, reqPath); + } + + override transformRequestBody( + reqBody: Record + ): Record { + if (typeof reqBody.model === 'string') { + return { + ...reqBody, + model: toVercelModelId(reqBody.model), + }; + } + + return reqBody; + } + + override supportsStream(): boolean { + return true; + } + + private getUsageFromAIResponse(usage: AIGatewayUsage | undefined): { + promptTokens: number; + completionTokens: number; + totalTokens: number; + } { + const promptTokens = usage?.inputTokens ?? 0; + const completionTokens = usage?.outputTokens ?? 0; + const totalTokens = usage?.totalTokens ?? promptTokens + completionTokens; + + return { promptTokens, completionTokens, totalTokens }; + } + + async handleBody(data: string): Promise { + try { + let prompt_tokens = 0; + let completion_tokens = 0; + let total_tokens = 0; + let providerId = 'null'; + + if (this.getIsStream()) { + const chunks = parseSSEJsonObjects(data); + + for (const chunk of chunks) { + const streamPart = chunk as AIGatewayStreamPart; + + if (streamPart.type === 'finish' && streamPart.usage) { + const usage = this.getUsageFromAIResponse(streamPart.usage); + prompt_tokens += usage.promptTokens; + completion_tokens += usage.completionTokens; + total_tokens += usage.totalTokens; + } + + providerId = streamPart.response?.id ?? streamPart.id ?? providerId; + } + + if (total_tokens === 0) { + for (const chunk of parseSSEGPTFormat(data)) { + if (chunk.usage !== null) { + prompt_tokens += chunk.usage.prompt_tokens; + completion_tokens += chunk.usage.completion_tokens; + total_tokens += chunk.usage.total_tokens; + } + providerId = chunk.id || providerId; + } + } + } else { + const parsed = JSON.parse(data) as AIGatewayResponseBody; + + if (isAIGatewayUsage(parsed.usage)) { + const usage = this.getUsageFromAIResponse(parsed.usage); + prompt_tokens += usage.promptTokens; + completion_tokens += usage.completionTokens; + total_tokens += usage.totalTokens; + providerId = parsed.response?.id ?? parsed.id ?? 'null'; + } else if (parsed.usage) { + prompt_tokens += parsed.usage.prompt_tokens ?? 0; + completion_tokens += parsed.usage.completion_tokens ?? 0; + total_tokens += + parsed.usage.total_tokens ?? prompt_tokens + completion_tokens; + providerId = parsed.id || 'null'; + } else { + providerId = parsed.response?.id ?? parsed.id ?? 'null'; + } + } + + const cost = getCostPerToken( + this.getModel(), + prompt_tokens, + completion_tokens + ); + + const metadata: LlmTransactionMetadata = { + providerId, + provider: this.getType(), + model: this.getModel(), + inputTokens: prompt_tokens, + outputTokens: completion_tokens, + totalTokens: total_tokens, + }; + + return { + rawTransactionCost: cost, + metadata, + status: 'success', + }; + } catch (error) { + logger.error(`Error processing data: ${error}`); + throw error; + } + } +} diff --git a/packages/app/server/src/services/AccountingService.ts b/packages/app/server/src/services/AccountingService.ts index 02e51e14e..242a78272 100644 --- a/packages/app/server/src/services/AccountingService.ts +++ b/packages/app/server/src/services/AccountingService.ts @@ -7,9 +7,11 @@ import { OpenAIImageModels, SupportedOpenAIResponseToolPricing, SupportedModel, + TokenPricingTier, SupportedImageModel, SupportedVideoModel, XAIModels, + VercelAIGatewayModels, } from '@merit-systems/echo-typescript-sdk'; import { Decimal } from '@prisma/client/runtime/library'; @@ -30,6 +32,7 @@ export const ALL_SUPPORTED_MODELS: SupportedModel[] = [ ...OpenRouterModels, ...GroqModels, ...XAIModels, + ...VercelAIGatewayModels, ]; // Handle image models separately since they have different pricing structure @@ -67,6 +70,8 @@ export const getModelPrice = (model: string) => { return { input_cost_per_token: supportedModel.input_cost_per_token, output_cost_per_token: supportedModel.output_cost_per_token, + input_cost_per_token_tiers: supportedModel.input_cost_per_token_tiers, + output_cost_per_token_tiers: supportedModel.output_cost_per_token_tiers, provider: supportedModel.provider, model: supportedModel.model_id, }; @@ -135,9 +140,17 @@ export const getCostPerToken = ( throw new Error(`Invalid pricing for model: ${model}`); } - const cost = new Decimal(modelPrice.input_cost_per_token) - .mul(inputTokens) - .plus(new Decimal(modelPrice.output_cost_per_token).mul(outputTokens)); + const cost = getTieredTokenCost( + inputTokens, + modelPrice.input_cost_per_token, + modelPrice.input_cost_per_token_tiers + ).plus( + getTieredTokenCost( + outputTokens, + modelPrice.output_cost_per_token, + modelPrice.output_cost_per_token_tiers + ) + ); if (cost.lessThan(0)) { throw new Error(`Invalid cost for model: ${model}`); @@ -146,6 +159,44 @@ export const getCostPerToken = ( return cost; }; +export function getTieredTokenRate( + tokens: number, + fallbackRate: number, + tiers?: TokenPricingTier[] +): number { + if (!tiers || tiers.length === 0) { + return fallbackRate; + } + + return ( + tiers.find( + tier => + tokens >= tier.min && (tier.max === undefined || tokens < tier.max) + )?.cost ?? fallbackRate + ); +} + +export function getMaxTokenRate( + fallbackRate: number, + tiers?: TokenPricingTier[] +): number { + if (!tiers || tiers.length === 0) { + return fallbackRate; + } + + return Math.max(fallbackRate, ...tiers.map(tier => tier.cost)); +} + +function getTieredTokenCost( + tokens: number, + fallbackRate: number, + tiers?: TokenPricingTier[] +): Decimal { + return new Decimal(getTieredTokenRate(tokens, fallbackRate, tiers)).mul( + tokens + ); +} + export const getImageModelCost = ( model: string, textTokens: number, diff --git a/packages/app/server/src/services/PricingService.ts b/packages/app/server/src/services/PricingService.ts index ca9022ba0..349acbe0f 100644 --- a/packages/app/server/src/services/PricingService.ts +++ b/packages/app/server/src/services/PricingService.ts @@ -7,6 +7,7 @@ import { isValidVideoModel, calculateToolCost, getImageModelPrice, + getMaxTokenRate, } from './AccountingService'; import { Decimal } from '@prisma/client/runtime/library'; import { extractMaxOutputTokens } from './RequestDataService'; @@ -84,10 +85,16 @@ export function getRequestMaxCost( throw new UnknownModelError(`Invalid model: ${provider.getModel()}`); } const maxInputCost = new Decimal(maxInputTokens).mul( - modelWithPricing.input_cost_per_token + getMaxTokenRate( + modelWithPricing.input_cost_per_token, + modelWithPricing.input_cost_per_token_tiers + ) ); const maxOutputCost = new Decimal(maxOutputTokens).mul( - modelWithPricing.output_cost_per_token + getMaxTokenRate( + modelWithPricing.output_cost_per_token, + modelWithPricing.output_cost_per_token_tiers + ) ); // Tool cost for OpenAI Responses API const toolCost = predictMaxToolCost(req, provider); diff --git a/packages/app/server/src/services/RequestDataService.ts b/packages/app/server/src/services/RequestDataService.ts index 2d8c99c3c..8f94b61b2 100644 --- a/packages/app/server/src/services/RequestDataService.ts +++ b/packages/app/server/src/services/RequestDataService.ts @@ -13,6 +13,11 @@ export function extractModelName(req: Request): string | undefined { return model; } + const gatewayModel = req.headers['ai-language-model-id']; + if (typeof gatewayModel === 'string' && gatewayModel.length > 0) { + return gatewayModel; + } + const modelFromPath = extractGeminiModelName(req); if (modelFromPath && modelFromPath !== undefined) { @@ -28,6 +33,11 @@ export function extractMaxOutputTokens(req: Request): number { if (maxOutputTokens && maxOutputTokens !== undefined) { return maxOutputTokens; } + // AI SDK Gateway protocol + const aiSdkMaxOutputTokens = req.body.maxOutputTokens; + if (aiSdkMaxOutputTokens && aiSdkMaxOutputTokens !== undefined) { + return aiSdkMaxOutputTokens; + } // Anthropic Format const maxTokens = req.body.max_tokens; if (maxTokens && maxTokens !== undefined) { @@ -55,6 +65,11 @@ export function extractIsStream(req: Request): boolean { return stream; } + const aiSdkGatewayStream = req.headers['ai-language-model-streaming']; + if (typeof aiSdkGatewayStream === 'string') { + return aiSdkGatewayStream === 'true'; + } + if (isGeminiStreamingPath(req.path)) { return true; } diff --git a/packages/app/server/src/types.ts b/packages/app/server/src/types.ts index e6febc9d0..b42182411 100644 --- a/packages/app/server/src/types.ts +++ b/packages/app/server/src/types.ts @@ -163,7 +163,7 @@ type TokenAmount = string; type Url = string; type Nonce = string; -interface ExactEvmPayloadAuthorization { +export interface ExactEvmPayloadAuthorization { from: Address; to: Address; value: TokenAmount; diff --git a/packages/sdk/next/src/ai-providers/vercel.ts b/packages/sdk/next/src/ai-providers/vercel.ts new file mode 100644 index 000000000..bb995f105 --- /dev/null +++ b/packages/sdk/next/src/ai-providers/vercel.ts @@ -0,0 +1,14 @@ +import { getEchoToken } from '../auth/token-manager'; +import { + createEchoVercelAIGateway as createEchoVercelAIGatewayBase, + EchoConfig, + VercelAIGatewayProvider, +} from '@merit-systems/echo-typescript-sdk'; + +export function createEchoVercelAIGateway( + config: EchoConfig +): VercelAIGatewayProvider { + return createEchoVercelAIGatewayBase(config, async () => + getEchoToken(config) + ); +} diff --git a/packages/sdk/next/src/index.ts b/packages/sdk/next/src/index.ts index 3417a75b8..2da1387e5 100644 --- a/packages/sdk/next/src/index.ts +++ b/packages/sdk/next/src/index.ts @@ -9,6 +9,7 @@ import { createEchoOpenAI } from 'ai-providers/openai'; import { createEchoOpenRouter } from 'ai-providers/openrouter'; import { createEchoGroq } from 'ai-providers/groq'; import { createEchoXAI } from 'ai-providers/xai'; +import { createEchoVercelAIGateway } from 'ai-providers/vercel'; import { CreateOauthTokenResponse, @@ -118,5 +119,6 @@ export default function Echo(config: EchoConfig): EchoResult { groq: createEchoGroq(config), openrouter: createEchoOpenRouter(config), xai: createEchoXAI(config), + vercel: createEchoVercelAIGateway(config), }; } diff --git a/packages/sdk/next/src/types.ts b/packages/sdk/next/src/types.ts index 5738bc5b8..346492646 100644 --- a/packages/sdk/next/src/types.ts +++ b/packages/sdk/next/src/types.ts @@ -6,6 +6,7 @@ import { GroqProvider, OpenRouterProvider, XaiProvider, + VercelAIGatewayProvider, } from '@merit-systems/echo-typescript-sdk'; import { NextRequest } from 'next/server'; @@ -52,4 +53,5 @@ export type EchoResult = { groq: GroqProvider; openrouter: OpenRouterProvider; xai: XaiProvider; + vercel: VercelAIGatewayProvider; }; diff --git a/packages/sdk/react/src/hooks/useEchoModelProviders.ts b/packages/sdk/react/src/hooks/useEchoModelProviders.ts index c11631ce5..6d29249ae 100644 --- a/packages/sdk/react/src/hooks/useEchoModelProviders.ts +++ b/packages/sdk/react/src/hooks/useEchoModelProviders.ts @@ -4,6 +4,7 @@ import { createEchoGroq, createEchoOpenAI, createEchoOpenRouter, + createEchoVercelAIGateway, createEchoXAI, } from '@merit-systems/echo-typescript-sdk'; import { useMemo } from 'react'; @@ -30,6 +31,11 @@ export const useEchoModelProviders = () => { onInsufficientFunds ), groq: createEchoGroq(baseConfig, getToken, onInsufficientFunds), + vercel: createEchoVercelAIGateway( + baseConfig, + getToken, + onInsufficientFunds + ), xai: createEchoXAI(baseConfig, getToken, onInsufficientFunds), }; }, [getToken, config.appId, config.baseRouterUrl, setIsInsufficientFunds]); diff --git a/packages/sdk/ts/package.json b/packages/sdk/ts/package.json index f2a7f1066..b992d4935 100644 --- a/packages/sdk/ts/package.json +++ b/packages/sdk/ts/package.json @@ -29,7 +29,8 @@ "update-models:gemini": "tsx scripts/update-gemini-models.ts", "update-models:openrouter": "tsx scripts/update-openrouter-models.ts", "update-models:groq": "tsx scripts/update-groq-models.ts", - "update-all-models": "pnpm run update-models:openai && pnpm run update-models:anthropic && pnpm run update-models:gemini && pnpm run update-models:openrouter && pnpm run update-models:groq", + "update-models:vercel": "tsx scripts/update-vercel-models.ts", + "update-all-models": "pnpm run update-models:openai && pnpm run update-models:anthropic && pnpm run update-models:gemini && pnpm run update-models:openrouter && pnpm run update-models:groq && pnpm run update-models:vercel", "prepublishOnly": "pnpm run build" }, "keywords": [ @@ -41,7 +42,6 @@ "author": "Merit Systems", "license": "MIT", "devDependencies": { - "@ai-sdk/gateway": "^1.0.12", "@types/node": "^24.3.1", "@typescript-eslint/eslint-plugin": "^8.34.1", "@typescript-eslint/parser": "^8.34.1", @@ -58,6 +58,7 @@ ], "dependencies": { "@ai-sdk/anthropic": "2.0.17", + "@ai-sdk/gateway": "^1.0.12", "@ai-sdk/google": "2.0.14", "@ai-sdk/groq": "2.0.17", "@ai-sdk/openai": "2.0.32", diff --git a/packages/sdk/ts/scripts/update-models.md b/packages/sdk/ts/scripts/update-models.md index c1e9ff619..df8584abb 100644 --- a/packages/sdk/ts/scripts/update-models.md +++ b/packages/sdk/ts/scripts/update-models.md @@ -11,6 +11,7 @@ pnpm run update-models:anthropic pnpm run update-models:gemini pnpm run update-models:openrouter pnpm run update-models:groq +pnpm run update-models:vercel # Update all providers at once pnpm run update-all-models @@ -26,6 +27,8 @@ Set environment variables for provider API keys: - `OPENROUTER_API_KEY` - `GROQ_API_KEY` +`update-models:vercel` uses the public Vercel AI Gateway model endpoint and does not require an API key. + ## What it does 1. Fetches latest models from each provider's API diff --git a/packages/sdk/ts/scripts/update-models.ts b/packages/sdk/ts/scripts/update-models.ts index 834634385..91c05381c 100644 --- a/packages/sdk/ts/scripts/update-models.ts +++ b/packages/sdk/ts/scripts/update-models.ts @@ -10,9 +10,17 @@ export interface SupportedModel { model_id: string; input_cost_per_token: number; output_cost_per_token: number; + input_cost_per_token_tiers?: TokenPricingTier[]; + output_cost_per_token_tiers?: TokenPricingTier[]; provider: string; } +export interface TokenPricingTier { + cost: number; + min: number; + max?: number; +} + export interface ProviderConfig { name: string; gatewayPrefix: string; diff --git a/packages/sdk/ts/scripts/update-vercel-models.ts b/packages/sdk/ts/scripts/update-vercel-models.ts new file mode 100644 index 000000000..1cbf8f4a2 --- /dev/null +++ b/packages/sdk/ts/scripts/update-vercel-models.ts @@ -0,0 +1,177 @@ +#!/usr/bin/env node + +import { writeFileSync } from 'fs'; +import { join } from 'path'; +import type { SupportedModel, TokenPricingTier } from './update-models'; + +const VERCEL_MODELS_URL = 'https://ai-gateway.vercel.sh/v1/models'; +const ECHO_MODEL_PREFIX = 'vercel/'; + +interface VercelModel { + id: string; + type?: string; + modelType?: string; + pricing?: { + input?: string; + output?: string; + input_tiers?: VercelPricingTier[]; + output_tiers?: VercelPricingTier[]; + inputTiers?: VercelPricingTier[]; + outputTiers?: VercelPricingTier[]; + }; +} + +interface VercelPricingTier { + cost: string; + min: number; + max?: number; +} + +interface VercelModelsResponse { + data?: VercelModel[]; + models?: VercelModel[]; +} + +function parseTier(tier: VercelPricingTier): TokenPricingTier { + return { + cost: Number(tier.cost), + min: tier.min, + ...(tier.max !== undefined ? { max: tier.max } : {}), + }; +} + +function parsePricingTiers( + tiers: VercelPricingTier[] | undefined +): TokenPricingTier[] | undefined { + if (!tiers || tiers.length === 0) { + return undefined; + } + + const parsed = tiers.map(parseTier).filter(tier => !Number.isNaN(tier.cost)); + return parsed.length > 0 ? parsed : undefined; +} + +function generateVercelModelFile(models: SupportedModel[]): string { + const sortedModels = models.sort((a, b) => + a.model_id.localeCompare(b.model_id) + ); + + const unionType = sortedModels + .map(model => ` | '${model.model_id}'`) + .join('\n'); + + const modelObjects = sortedModels + .map(model => { + const fields = [ + ` model_id: '${model.model_id}',`, + ` input_cost_per_token: ${model.input_cost_per_token},`, + ` output_cost_per_token: ${model.output_cost_per_token},`, + ]; + + if (model.input_cost_per_token_tiers) { + fields.push( + ` input_cost_per_token_tiers: ${JSON.stringify( + model.input_cost_per_token_tiers + )},` + ); + } + + if (model.output_cost_per_token_tiers) { + fields.push( + ` output_cost_per_token_tiers: ${JSON.stringify( + model.output_cost_per_token_tiers + )},` + ); + } + + fields.push(` provider: 'Vercel AI Gateway',`); + + return ` {\n${fields.join('\n')}\n }`; + }) + .join(',\n'); + + return `import { SupportedModel } from '../types'; + +// Union type of all Echo model IDs routed through Vercel AI Gateway. +// Strip the leading "${ECHO_MODEL_PREFIX}" before forwarding to Vercel. +export type VercelAIGatewayModel = +${unionType}; + +export const VercelAIGatewayModels: SupportedModel[] = [ +${modelObjects} +]; +`; +} + +async function fetchVercelModels(): Promise { + const response = await fetch(VERCEL_MODELS_URL); + if (!response.ok) { + throw new Error( + `Failed to fetch Vercel AI Gateway models: ${response.status} ${response.statusText}` + ); + } + + const data = (await response.json()) as VercelModelsResponse; + const models = data.data ?? data.models ?? []; + + return models + .filter(model => (model.type ?? model.modelType) === 'language') + .map(model => { + const inputCost = Number(model.pricing?.input); + const outputCost = Number(model.pricing?.output); + if ( + !model.id || + Number.isNaN(inputCost) || + Number.isNaN(outputCost) || + inputCost <= 0 || + outputCost <= 0 + ) { + return null; + } + + const supportedModel: SupportedModel = { + model_id: `${ECHO_MODEL_PREFIX}${model.id}`, + input_cost_per_token: inputCost, + output_cost_per_token: outputCost, + provider: 'Vercel AI Gateway', + }; + + const inputTiers = parsePricingTiers( + model.pricing?.input_tiers ?? model.pricing?.inputTiers + ); + if (inputTiers) { + supportedModel.input_cost_per_token_tiers = inputTiers; + } + + const outputTiers = parsePricingTiers( + model.pricing?.output_tiers ?? model.pricing?.outputTiers + ); + if (outputTiers) { + supportedModel.output_cost_per_token_tiers = outputTiers; + } + + return supportedModel; + }) + .filter((model): model is SupportedModel => model !== null); +} + +async function updateVercelModels(): Promise { + try { + console.log('Starting Vercel AI Gateway model update process...'); + const models = await fetchVercelModels(); + + if (models.length === 0) { + throw new Error('No compatible Vercel AI Gateway language models found'); + } + + const fullPath = join(process.cwd(), 'src/supported-models/chat/vercel.ts'); + writeFileSync(fullPath, generateVercelModelFile(models), 'utf8'); + + console.log(`Updated vercel.ts with ${models.length} models`); + } catch (error) { + console.error('Error updating Vercel AI Gateway models:', error); + process.exit(1); + } +} + +updateVercelModels(); diff --git a/packages/sdk/ts/src/index.ts b/packages/sdk/ts/src/index.ts index 521a30f93..8828972fd 100644 --- a/packages/sdk/ts/src/index.ts +++ b/packages/sdk/ts/src/index.ts @@ -22,6 +22,7 @@ export type { ImageDimensions, WebSearchModel, SupportedTool, + TokenPricingTier, ImageGenerationQualityPricing, ImageGenerationModelPricing, ImageGenerationPricing, @@ -49,6 +50,8 @@ export { GroqModels } from './supported-models/chat/groq'; export type { GroqModel } from './supported-models/chat/groq'; export { XAIModels } from './supported-models/chat/xai'; export type { XAIModel } from './supported-models/chat/xai'; +export { VercelAIGatewayModels } from './supported-models/chat/vercel'; +export type { VercelAIGatewayModel } from './supported-models/chat/vercel'; export { OpenAIImageModels } from './supported-models/image/openai'; export type { OpenAIImageModel } from './supported-models/image/openai'; export { GeminiVideoModels } from './supported-models/video/gemini'; diff --git a/packages/sdk/ts/src/providers/index.ts b/packages/sdk/ts/src/providers/index.ts index 62f54fac8..d4f428712 100644 --- a/packages/sdk/ts/src/providers/index.ts +++ b/packages/sdk/ts/src/providers/index.ts @@ -4,6 +4,7 @@ export * from './groq'; export * from './xai'; export * from './openai'; export * from './openrouter'; +export * from './vercel'; export function echoFetch( originalFetch: typeof fetch, @@ -63,3 +64,4 @@ export { type GroqProvider } from '@ai-sdk/groq'; export { type OpenAIProvider } from '@ai-sdk/openai'; export { type OpenRouterProvider } from '@openrouter/ai-sdk-provider'; export { type XaiProvider } from '@ai-sdk/xai'; +export { type GatewayProvider as VercelAIGatewayProvider } from '@ai-sdk/gateway'; diff --git a/packages/sdk/ts/src/providers/vercel.ts b/packages/sdk/ts/src/providers/vercel.ts new file mode 100644 index 000000000..ab51e6855 --- /dev/null +++ b/packages/sdk/ts/src/providers/vercel.ts @@ -0,0 +1,79 @@ +import { + createGateway, + GatewayLanguageModelEntry, + GatewayProvider, + GatewayProviderSettings, +} from '@ai-sdk/gateway'; +import { ROUTER_BASE_URL } from 'config'; +import { VercelAIGatewayModels } from '../supported-models/chat/vercel'; +import { EchoConfig } from '../types'; +import { validateAppId } from '../utils/validation'; +import { echoFetch } from './index'; + +export const ECHO_VERCEL_AI_GATEWAY_MODEL_PREFIX = 'vercel/'; + +export function toEchoVercelAIGatewayModelId(modelId: string): string { + return modelId.startsWith(ECHO_VERCEL_AI_GATEWAY_MODEL_PREFIX) + ? modelId + : `${ECHO_VERCEL_AI_GATEWAY_MODEL_PREFIX}${modelId}`; +} + +function toGatewayBaseUrl(baseRouterUrl: string): string { + const normalized = baseRouterUrl.replace(/\/+$/, ''); + return normalized.endsWith('/v1/ai') ? normalized : `${normalized}/v1/ai`; +} + +function toGatewayModelEntry(modelId: string): GatewayLanguageModelEntry { + const model = VercelAIGatewayModels.find(m => m.model_id === modelId); + return { + id: modelId, + name: modelId.replace(ECHO_VERCEL_AI_GATEWAY_MODEL_PREFIX, ''), + pricing: model + ? { + input: String(model.input_cost_per_token), + output: String(model.output_cost_per_token), + } + : null, + specification: { + specificationVersion: 'v2', + provider: 'gateway', + modelId, + }, + modelType: 'language', + }; +} + +export function createEchoVercelAIGateway( + { appId, baseRouterUrl = ROUTER_BASE_URL }: EchoConfig, + getTokenFn: (appId: string) => Promise, + onInsufficientFunds?: () => void, + settings: Omit = {} +): GatewayProvider { + validateAppId(appId, 'createEchoVercelAIGateway'); + + const gateway = createGateway({ + ...settings, + baseURL: toGatewayBaseUrl(baseRouterUrl), + apiKey: 'placeholder_replaced_by_echoFetch', + fetch: echoFetch( + fetch, + async () => await getTokenFn(appId), + onInsufficientFunds + ), + }); + + const echoGateway = ((modelId: string) => + gateway(toEchoVercelAIGatewayModelId(modelId))) as GatewayProvider; + + Object.assign(echoGateway, gateway, { + languageModel: (modelId: string) => + gateway.languageModel(toEchoVercelAIGatewayModelId(modelId)), + getAvailableModels: async () => ({ + models: VercelAIGatewayModels.map(model => + toGatewayModelEntry(model.model_id) + ), + }), + }); + + return echoGateway; +} diff --git a/packages/sdk/ts/src/resources/models.ts b/packages/sdk/ts/src/resources/models.ts index ee4064d98..cb727f5eb 100644 --- a/packages/sdk/ts/src/resources/models.ts +++ b/packages/sdk/ts/src/resources/models.ts @@ -5,6 +5,7 @@ import { AnthropicModels, GeminiModels, OpenRouterModels, + VercelAIGatewayModels, OpenAIImageModels, SupportedModel, SupportedImageModel, @@ -26,6 +27,7 @@ export class ModelsResource extends BaseResource { ...AnthropicModels, ...GeminiModels, ...OpenRouterModels, + ...VercelAIGatewayModels, ]; return allModels; diff --git a/packages/sdk/ts/src/supported-models/chat/vercel.ts b/packages/sdk/ts/src/supported-models/chat/vercel.ts new file mode 100644 index 000000000..61d91a2d5 --- /dev/null +++ b/packages/sdk/ts/src/supported-models/chat/vercel.ts @@ -0,0 +1,1555 @@ +import { SupportedModel } from '../types'; + +// Union type of all Echo model IDs routed through Vercel AI Gateway. +// Strip the leading "vercel/" before forwarding to Vercel. +export type VercelAIGatewayModel = + | 'vercel/alibaba/qwen-3-14b' + | 'vercel/alibaba/qwen-3-235b' + | 'vercel/alibaba/qwen-3-30b' + | 'vercel/alibaba/qwen-3-32b' + | 'vercel/alibaba/qwen-3.6-max-preview' + | 'vercel/alibaba/qwen3-235b-a22b-thinking' + | 'vercel/alibaba/qwen3-coder' + | 'vercel/alibaba/qwen3-coder-30b-a3b' + | 'vercel/alibaba/qwen3-coder-next' + | 'vercel/alibaba/qwen3-coder-plus' + | 'vercel/alibaba/qwen3-max' + | 'vercel/alibaba/qwen3-max-preview' + | 'vercel/alibaba/qwen3-max-thinking' + | 'vercel/alibaba/qwen3-next-80b-a3b-instruct' + | 'vercel/alibaba/qwen3-next-80b-a3b-thinking' + | 'vercel/alibaba/qwen3-vl-instruct' + | 'vercel/alibaba/qwen3-vl-thinking' + | 'vercel/alibaba/qwen3.5-flash' + | 'vercel/alibaba/qwen3.5-plus' + | 'vercel/alibaba/qwen3.6-plus' + | 'vercel/amazon/nova-2-lite' + | 'vercel/amazon/nova-lite' + | 'vercel/amazon/nova-micro' + | 'vercel/amazon/nova-pro' + | 'vercel/anthropic/claude-3-haiku' + | 'vercel/anthropic/claude-3.5-haiku' + | 'vercel/anthropic/claude-3.7-sonnet' + | 'vercel/anthropic/claude-haiku-4.5' + | 'vercel/anthropic/claude-opus-4' + | 'vercel/anthropic/claude-opus-4.1' + | 'vercel/anthropic/claude-opus-4.5' + | 'vercel/anthropic/claude-opus-4.6' + | 'vercel/anthropic/claude-opus-4.7' + | 'vercel/anthropic/claude-sonnet-4' + | 'vercel/anthropic/claude-sonnet-4.5' + | 'vercel/anthropic/claude-sonnet-4.6' + | 'vercel/arcee-ai/trinity-large-preview' + | 'vercel/arcee-ai/trinity-large-thinking' + | 'vercel/arcee-ai/trinity-mini' + | 'vercel/bytedance/seed-1.6' + | 'vercel/bytedance/seed-1.8' + | 'vercel/cohere/command-a' + | 'vercel/deepseek/deepseek-r1' + | 'vercel/deepseek/deepseek-v3' + | 'vercel/deepseek/deepseek-v3.1' + | 'vercel/deepseek/deepseek-v3.1-terminus' + | 'vercel/deepseek/deepseek-v3.2' + | 'vercel/deepseek/deepseek-v3.2-thinking' + | 'vercel/deepseek/deepseek-v4-flash' + | 'vercel/deepseek/deepseek-v4-pro' + | 'vercel/google/gemini-2.0-flash' + | 'vercel/google/gemini-2.0-flash-lite' + | 'vercel/google/gemini-2.5-flash' + | 'vercel/google/gemini-2.5-flash-image' + | 'vercel/google/gemini-2.5-flash-lite' + | 'vercel/google/gemini-2.5-pro' + | 'vercel/google/gemini-3-flash' + | 'vercel/google/gemini-3-pro-image' + | 'vercel/google/gemini-3-pro-preview' + | 'vercel/google/gemini-3.1-flash-image-preview' + | 'vercel/google/gemini-3.1-flash-lite-preview' + | 'vercel/google/gemini-3.1-pro-preview' + | 'vercel/google/gemma-4-26b-a4b-it' + | 'vercel/google/gemma-4-31b-it' + | 'vercel/inception/mercury-2' + | 'vercel/inception/mercury-coder-small' + | 'vercel/kwaipilot/kat-coder-pro-v1' + | 'vercel/kwaipilot/kat-coder-pro-v2' + | 'vercel/meta/llama-3.1-70b' + | 'vercel/meta/llama-3.1-8b' + | 'vercel/meta/llama-3.2-11b' + | 'vercel/meta/llama-3.2-1b' + | 'vercel/meta/llama-3.2-3b' + | 'vercel/meta/llama-3.2-90b' + | 'vercel/meta/llama-3.3-70b' + | 'vercel/meta/llama-4-maverick' + | 'vercel/meta/llama-4-scout' + | 'vercel/minimax/minimax-m2' + | 'vercel/minimax/minimax-m2.1' + | 'vercel/minimax/minimax-m2.1-lightning' + | 'vercel/minimax/minimax-m2.5' + | 'vercel/minimax/minimax-m2.5-highspeed' + | 'vercel/minimax/minimax-m2.7' + | 'vercel/minimax/minimax-m2.7-highspeed' + | 'vercel/mistral/codestral' + | 'vercel/mistral/devstral-2' + | 'vercel/mistral/devstral-small' + | 'vercel/mistral/devstral-small-2' + | 'vercel/mistral/magistral-medium' + | 'vercel/mistral/magistral-small' + | 'vercel/mistral/ministral-14b' + | 'vercel/mistral/ministral-3b' + | 'vercel/mistral/ministral-8b' + | 'vercel/mistral/mistral-large-3' + | 'vercel/mistral/mistral-medium' + | 'vercel/mistral/mistral-nemo' + | 'vercel/mistral/mistral-small' + | 'vercel/mistral/mixtral-8x22b-instruct' + | 'vercel/mistral/pixtral-12b' + | 'vercel/mistral/pixtral-large' + | 'vercel/moonshotai/kimi-k2' + | 'vercel/moonshotai/kimi-k2-0905' + | 'vercel/moonshotai/kimi-k2-thinking' + | 'vercel/moonshotai/kimi-k2-thinking-turbo' + | 'vercel/moonshotai/kimi-k2-turbo' + | 'vercel/moonshotai/kimi-k2.5' + | 'vercel/moonshotai/kimi-k2.6' + | 'vercel/morph/morph-v3-fast' + | 'vercel/morph/morph-v3-large' + | 'vercel/nvidia/nemotron-3-nano-30b-a3b' + | 'vercel/nvidia/nemotron-3-super-120b-a12b' + | 'vercel/nvidia/nemotron-nano-12b-v2-vl' + | 'vercel/nvidia/nemotron-nano-9b-v2' + | 'vercel/openai/gpt-3.5-turbo' + | 'vercel/openai/gpt-3.5-turbo-instruct' + | 'vercel/openai/gpt-4-turbo' + | 'vercel/openai/gpt-4.1' + | 'vercel/openai/gpt-4.1-mini' + | 'vercel/openai/gpt-4.1-nano' + | 'vercel/openai/gpt-4o' + | 'vercel/openai/gpt-4o-mini' + | 'vercel/openai/gpt-4o-mini-search-preview' + | 'vercel/openai/gpt-5' + | 'vercel/openai/gpt-5-chat' + | 'vercel/openai/gpt-5-codex' + | 'vercel/openai/gpt-5-mini' + | 'vercel/openai/gpt-5-nano' + | 'vercel/openai/gpt-5-pro' + | 'vercel/openai/gpt-5.1-codex' + | 'vercel/openai/gpt-5.1-codex-max' + | 'vercel/openai/gpt-5.1-codex-mini' + | 'vercel/openai/gpt-5.1-instant' + | 'vercel/openai/gpt-5.1-thinking' + | 'vercel/openai/gpt-5.2' + | 'vercel/openai/gpt-5.2-chat' + | 'vercel/openai/gpt-5.2-codex' + | 'vercel/openai/gpt-5.2-pro' + | 'vercel/openai/gpt-5.3-chat' + | 'vercel/openai/gpt-5.3-codex' + | 'vercel/openai/gpt-5.4' + | 'vercel/openai/gpt-5.4-mini' + | 'vercel/openai/gpt-5.4-nano' + | 'vercel/openai/gpt-5.4-pro' + | 'vercel/openai/gpt-5.5' + | 'vercel/openai/gpt-5.5-pro' + | 'vercel/openai/gpt-oss-120b' + | 'vercel/openai/gpt-oss-20b' + | 'vercel/openai/gpt-oss-safeguard-20b' + | 'vercel/openai/o1' + | 'vercel/openai/o3' + | 'vercel/openai/o3-deep-research' + | 'vercel/openai/o3-mini' + | 'vercel/openai/o3-pro' + | 'vercel/openai/o4-mini' + | 'vercel/prime-intellect/intellect-3' + | 'vercel/xai/grok-3' + | 'vercel/xai/grok-3-fast' + | 'vercel/xai/grok-3-mini' + | 'vercel/xai/grok-3-mini-fast' + | 'vercel/xai/grok-4' + | 'vercel/xai/grok-4-fast-non-reasoning' + | 'vercel/xai/grok-4-fast-reasoning' + | 'vercel/xai/grok-4.1-fast-non-reasoning' + | 'vercel/xai/grok-4.1-fast-reasoning' + | 'vercel/xai/grok-4.20-multi-agent' + | 'vercel/xai/grok-4.20-multi-agent-beta' + | 'vercel/xai/grok-4.20-non-reasoning' + | 'vercel/xai/grok-4.20-non-reasoning-beta' + | 'vercel/xai/grok-4.20-reasoning' + | 'vercel/xai/grok-4.20-reasoning-beta' + | 'vercel/xai/grok-code-fast-1' + | 'vercel/xiaomi/mimo-v2-flash' + | 'vercel/xiaomi/mimo-v2-pro' + | 'vercel/zai/glm-4.5' + | 'vercel/zai/glm-4.5-air' + | 'vercel/zai/glm-4.5v' + | 'vercel/zai/glm-4.6' + | 'vercel/zai/glm-4.6v' + | 'vercel/zai/glm-4.7' + | 'vercel/zai/glm-4.7-flash' + | 'vercel/zai/glm-4.7-flashx' + | 'vercel/zai/glm-5' + | 'vercel/zai/glm-5-turbo' + | 'vercel/zai/glm-5.1' + | 'vercel/zai/glm-5v-turbo'; + +export const VercelAIGatewayModels: SupportedModel[] = [ + { + model_id: 'vercel/alibaba/qwen-3-14b', + input_cost_per_token: 1.2e-7, + output_cost_per_token: 2.4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen-3-235b', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen-3-30b', + input_cost_per_token: 8e-8, + output_cost_per_token: 2.9e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen-3-32b', + input_cost_per_token: 1.6e-7, + output_cost_per_token: 6.4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen-3.6-max-preview', + input_cost_per_token: 0.0000013, + output_cost_per_token: 0.0000078, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-235b-a22b-thinking', + input_cost_per_token: 2.3e-7, + output_cost_per_token: 0.0000023, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-coder', + input_cost_per_token: 0.0000015, + output_cost_per_token: 0.0000075, + input_cost_per_token_tiers: [ + { cost: 0.0000015, min: 0, max: 32001 }, + { cost: 0.0000027, min: 32001, max: 128001 }, + { cost: 0.0000045, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.0000075, min: 0, max: 32001 }, + { cost: 0.0000135, min: 32001, max: 128001 }, + { cost: 0.0000225, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-coder-30b-a3b', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 6e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-coder-next', + input_cost_per_token: 5e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-coder-plus', + input_cost_per_token: 0.000001, + output_cost_per_token: 0.000005, + input_cost_per_token_tiers: [ + { cost: 0.000001, min: 0, max: 32001 }, + { cost: 0.0000018, min: 32001, max: 128001 }, + { cost: 0.000003, min: 128001, max: 256001 }, + { cost: 0.000006, min: 256001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000005, min: 0, max: 32001 }, + { cost: 0.000009, min: 32001, max: 128001 }, + { cost: 0.000015, min: 128001, max: 256001 }, + { cost: 0.00006, min: 256001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-max', + input_cost_per_token: 0.0000012, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.0000012, min: 0, max: 32001 }, + { cost: 0.0000024, min: 32001, max: 128001 }, + { cost: 0.000003, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 32001 }, + { cost: 0.000012, min: 32001, max: 128001 }, + { cost: 0.000015, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-max-preview', + input_cost_per_token: 0.0000012, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.0000012, min: 0, max: 32001 }, + { cost: 0.0000024, min: 32001, max: 128001 }, + { cost: 0.000003, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 32001 }, + { cost: 0.000012, min: 32001, max: 128001 }, + { cost: 0.000015, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-max-thinking', + input_cost_per_token: 0.0000012, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.0000012, min: 0, max: 32001 }, + { cost: 0.0000024, min: 32001, max: 128001 }, + { cost: 0.000003, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 32001 }, + { cost: 0.000012, min: 32001, max: 128001 }, + { cost: 0.000015, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-next-80b-a3b-instruct', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-next-80b-a3b-thinking', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-vl-instruct', + input_cost_per_token: 4e-7, + output_cost_per_token: 0.0000016, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3-vl-thinking', + input_cost_per_token: 4e-7, + output_cost_per_token: 0.000004, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3.5-flash', + input_cost_per_token: 1e-7, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3.5-plus', + input_cost_per_token: 4e-7, + output_cost_per_token: 0.0000024, + input_cost_per_token_tiers: [ + { cost: 4e-7, min: 0, max: 256001 }, + { cost: 0.0000012, min: 256001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.0000024, min: 0, max: 256001 }, + { cost: 0.0000072, min: 256001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/alibaba/qwen3.6-plus', + input_cost_per_token: 5e-7, + output_cost_per_token: 0.000003, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/amazon/nova-2-lite', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/amazon/nova-lite', + input_cost_per_token: 6e-8, + output_cost_per_token: 2.4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/amazon/nova-micro', + input_cost_per_token: 3.5e-8, + output_cost_per_token: 1.4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/amazon/nova-pro', + input_cost_per_token: 8e-7, + output_cost_per_token: 0.0000032, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-3-haiku', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.00000125, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-3.5-haiku', + input_cost_per_token: 8e-7, + output_cost_per_token: 0.000004, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-3.7-sonnet', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-haiku-4.5', + input_cost_per_token: 0.000001, + output_cost_per_token: 0.000005, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-opus-4', + input_cost_per_token: 0.000015, + output_cost_per_token: 0.000075, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-opus-4.1', + input_cost_per_token: 0.000015, + output_cost_per_token: 0.000075, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-opus-4.5', + input_cost_per_token: 0.000005, + output_cost_per_token: 0.000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-opus-4.6', + input_cost_per_token: 0.000005, + output_cost_per_token: 0.000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-opus-4.7', + input_cost_per_token: 0.000005, + output_cost_per_token: 0.000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-sonnet-4', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + input_cost_per_token_tiers: [ + { cost: 0.000003, min: 0, max: 200001 }, + { cost: 0.000006, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000015, min: 0, max: 200001 }, + { cost: 0.0000225, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-sonnet-4.5', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + input_cost_per_token_tiers: [ + { cost: 0.000003, min: 0, max: 200001 }, + { cost: 0.000006, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000015, min: 0, max: 200001 }, + { cost: 0.0000225, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/anthropic/claude-sonnet-4.6', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/arcee-ai/trinity-large-preview', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.000001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/arcee-ai/trinity-large-thinking', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 9e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/arcee-ai/trinity-mini', + input_cost_per_token: 4.5e-8, + output_cost_per_token: 1.5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/bytedance/seed-1.6', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.000002, + input_cost_per_token_tiers: [ + { cost: 2.5e-7, min: 0, max: 128001 }, + { cost: 5e-7, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 128001 }, + { cost: 0.000004, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/bytedance/seed-1.8', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.000002, + input_cost_per_token_tiers: [ + { cost: 2.5e-7, min: 0, max: 128001 }, + { cost: 5e-7, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 128001 }, + { cost: 0.000004, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/cohere/command-a', + input_cost_per_token: 0.0000025, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-r1', + input_cost_per_token: 0.00000135, + output_cost_per_token: 0.0000054, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-v3', + input_cost_per_token: 7.7e-7, + output_cost_per_token: 7.7e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-v3.1', + input_cost_per_token: 5.6e-7, + output_cost_per_token: 0.00000168, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-v3.1-terminus', + input_cost_per_token: 2.7e-7, + output_cost_per_token: 0.000001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-v3.2', + input_cost_per_token: 2.8e-7, + output_cost_per_token: 4.2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-v3.2-thinking', + input_cost_per_token: 2.8e-7, + output_cost_per_token: 4.2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-v4-flash', + input_cost_per_token: 1.4e-7, + output_cost_per_token: 2.8e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/deepseek/deepseek-v4-pro', + input_cost_per_token: 0.00000174, + output_cost_per_token: 0.00000348, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-2.0-flash', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 6e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-2.0-flash-lite', + input_cost_per_token: 7.5e-8, + output_cost_per_token: 3e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-2.5-flash', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-2.5-flash-image', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-2.5-flash-lite', + input_cost_per_token: 1e-7, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-2.5-pro', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + input_cost_per_token_tiers: [ + { cost: 0.00000125, min: 0, max: 200001 }, + { cost: 0.0000025, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.00001, min: 0, max: 200001 }, + { cost: 0.000015, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-3-flash', + input_cost_per_token: 5e-7, + output_cost_per_token: 0.000003, + input_cost_per_token_tiers: [ + { cost: 5e-7, min: 0, max: 200001 }, + { cost: 5e-7, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000003, min: 0, max: 200001 }, + { cost: 0.000003, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-3-pro-image', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-3-pro-preview', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000012, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000012, min: 0, max: 200001 }, + { cost: 0.000018, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-3.1-flash-image-preview', + input_cost_per_token: 5e-7, + output_cost_per_token: 0.000003, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-3.1-flash-lite-preview', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.0000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemini-3.1-pro-preview', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000012, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000012, min: 0, max: 200001 }, + { cost: 0.000018, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemma-4-26b-a4b-it', + input_cost_per_token: 1.3e-7, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/google/gemma-4-31b-it', + input_cost_per_token: 1.4e-7, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/inception/mercury-2', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 7.5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/inception/mercury-coder-small', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.000001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/kwaipilot/kat-coder-pro-v1', + input_cost_per_token: 3e-8, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/kwaipilot/kat-coder-pro-v2', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-3.1-70b', + input_cost_per_token: 7.2e-7, + output_cost_per_token: 7.2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-3.1-8b', + input_cost_per_token: 2.2e-7, + output_cost_per_token: 2.2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-3.2-11b', + input_cost_per_token: 1.6e-7, + output_cost_per_token: 1.6e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-3.2-1b', + input_cost_per_token: 1e-7, + output_cost_per_token: 1e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-3.2-3b', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 1.5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-3.2-90b', + input_cost_per_token: 7.2e-7, + output_cost_per_token: 7.2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-3.3-70b', + input_cost_per_token: 7.2e-7, + output_cost_per_token: 7.2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-4-maverick', + input_cost_per_token: 2.4e-7, + output_cost_per_token: 9.7e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/meta/llama-4-scout', + input_cost_per_token: 1.7e-7, + output_cost_per_token: 6.6e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/minimax/minimax-m2', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/minimax/minimax-m2.1', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/minimax/minimax-m2.1-lightning', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000024, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/minimax/minimax-m2.5', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/minimax/minimax-m2.5-highspeed', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000024, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/minimax/minimax-m2.7', + input_cost_per_token: 3e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/minimax/minimax-m2.7-highspeed', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000024, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/codestral', + input_cost_per_token: 3e-7, + output_cost_per_token: 9e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/devstral-2', + input_cost_per_token: 4e-7, + output_cost_per_token: 0.000002, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/devstral-small', + input_cost_per_token: 1e-7, + output_cost_per_token: 3e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/devstral-small-2', + input_cost_per_token: 1e-7, + output_cost_per_token: 3e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/magistral-medium', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000005, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/magistral-small', + input_cost_per_token: 5e-7, + output_cost_per_token: 0.0000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/ministral-14b', + input_cost_per_token: 2e-7, + output_cost_per_token: 2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/ministral-3b', + input_cost_per_token: 1e-7, + output_cost_per_token: 1e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/ministral-8b', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 1.5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/mistral-large-3', + input_cost_per_token: 5e-7, + output_cost_per_token: 0.0000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/mistral-medium', + input_cost_per_token: 4e-7, + output_cost_per_token: 0.000002, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/mistral-nemo', + input_cost_per_token: 2e-8, + output_cost_per_token: 4e-8, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/mistral-small', + input_cost_per_token: 1e-7, + output_cost_per_token: 3e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/mixtral-8x22b-instruct', + input_cost_per_token: 0.0000012, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/pixtral-12b', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 1.5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/mistral/pixtral-large', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000006, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/moonshotai/kimi-k2', + input_cost_per_token: 5.7e-7, + output_cost_per_token: 0.0000023, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/moonshotai/kimi-k2-0905', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/moonshotai/kimi-k2-thinking', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/moonshotai/kimi-k2-thinking-turbo', + input_cost_per_token: 0.00000115, + output_cost_per_token: 0.000008, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/moonshotai/kimi-k2-turbo', + input_cost_per_token: 0.00000115, + output_cost_per_token: 0.000008, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/moonshotai/kimi-k2.5', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.000003, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/moonshotai/kimi-k2.6', + input_cost_per_token: 9.5e-7, + output_cost_per_token: 0.000004, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/morph/morph-v3-fast', + input_cost_per_token: 8e-7, + output_cost_per_token: 0.0000012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/morph/morph-v3-large', + input_cost_per_token: 9e-7, + output_cost_per_token: 0.0000019, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/nvidia/nemotron-3-nano-30b-a3b', + input_cost_per_token: 5e-8, + output_cost_per_token: 2.4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/nvidia/nemotron-3-super-120b-a12b', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 6.5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/nvidia/nemotron-nano-12b-v2-vl', + input_cost_per_token: 2e-7, + output_cost_per_token: 6e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/nvidia/nemotron-nano-9b-v2', + input_cost_per_token: 6e-8, + output_cost_per_token: 2.3e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-3.5-turbo', + input_cost_per_token: 5e-7, + output_cost_per_token: 0.0000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-3.5-turbo-instruct', + input_cost_per_token: 0.0000015, + output_cost_per_token: 0.000002, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-4-turbo', + input_cost_per_token: 0.00001, + output_cost_per_token: 0.00003, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-4.1', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000008, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-4.1-mini', + input_cost_per_token: 4e-7, + output_cost_per_token: 0.0000016, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-4.1-nano', + input_cost_per_token: 1e-7, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-4o', + input_cost_per_token: 0.0000025, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-4o-mini', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 6e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-4o-mini-search-preview', + input_cost_per_token: 1.5e-7, + output_cost_per_token: 6e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5-chat', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5-codex', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5-mini', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.000002, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5-nano', + input_cost_per_token: 5e-8, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5-pro', + input_cost_per_token: 0.000015, + output_cost_per_token: 0.00012, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.1-codex', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.1-codex-max', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.1-codex-mini', + input_cost_per_token: 2.5e-7, + output_cost_per_token: 0.000002, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.1-instant', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.1-thinking', + input_cost_per_token: 0.00000125, + output_cost_per_token: 0.00001, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.2', + input_cost_per_token: 0.00000175, + output_cost_per_token: 0.000014, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.2-chat', + input_cost_per_token: 0.00000175, + output_cost_per_token: 0.000014, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.2-codex', + input_cost_per_token: 0.00000175, + output_cost_per_token: 0.000014, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.2-pro', + input_cost_per_token: 0.000021, + output_cost_per_token: 0.000168, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.3-chat', + input_cost_per_token: 0.00000175, + output_cost_per_token: 0.000014, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.3-codex', + input_cost_per_token: 0.00000175, + output_cost_per_token: 0.000014, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.4', + input_cost_per_token: 0.0000025, + output_cost_per_token: 0.000015, + input_cost_per_token_tiers: [ + { cost: 0.0000025, min: 0, max: 272000 }, + { cost: 0.000005, min: 272000 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000015, min: 0, max: 272000 }, + { cost: 0.0000225, min: 272000 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.4-mini', + input_cost_per_token: 7.5e-7, + output_cost_per_token: 0.0000045, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.4-nano', + input_cost_per_token: 2e-7, + output_cost_per_token: 0.00000125, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.4-pro', + input_cost_per_token: 0.00003, + output_cost_per_token: 0.00018, + input_cost_per_token_tiers: [ + { cost: 0.00003, min: 0, max: 272000 }, + { cost: 0.00006, min: 272000 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.00018, min: 0, max: 272000 }, + { cost: 0.00027, min: 272000 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.5', + input_cost_per_token: 0.000005, + output_cost_per_token: 0.00003, + input_cost_per_token_tiers: [ + { cost: 0.000005, min: 0, max: 272000 }, + { cost: 0.00001, min: 272000 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.00003, min: 0, max: 272000 }, + { cost: 0.000045, min: 272000 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-5.5-pro', + input_cost_per_token: 0.00003, + output_cost_per_token: 0.00018, + input_cost_per_token_tiers: [ + { cost: 0.00003, min: 0, max: 272000 }, + { cost: 0.00006, min: 272000 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.00018, min: 0, max: 272000 }, + { cost: 0.00027, min: 272000 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-oss-120b', + input_cost_per_token: 3.5e-7, + output_cost_per_token: 7.5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-oss-20b', + input_cost_per_token: 5e-8, + output_cost_per_token: 2e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/gpt-oss-safeguard-20b', + input_cost_per_token: 7.5e-8, + output_cost_per_token: 3e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/o1', + input_cost_per_token: 0.000015, + output_cost_per_token: 0.00006, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/o3', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000008, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/o3-deep-research', + input_cost_per_token: 0.00001, + output_cost_per_token: 0.00004, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/o3-mini', + input_cost_per_token: 0.0000011, + output_cost_per_token: 0.0000044, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/o3-pro', + input_cost_per_token: 0.00002, + output_cost_per_token: 0.00008, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/openai/o4-mini', + input_cost_per_token: 0.0000011, + output_cost_per_token: 0.0000044, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/prime-intellect/intellect-3', + input_cost_per_token: 2e-7, + output_cost_per_token: 0.0000011, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-3', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-3-fast', + input_cost_per_token: 0.000005, + output_cost_per_token: 0.000025, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-3-mini', + input_cost_per_token: 3e-7, + output_cost_per_token: 5e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-3-mini-fast', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.000004, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4', + input_cost_per_token: 0.000003, + output_cost_per_token: 0.000015, + input_cost_per_token_tiers: [ + { cost: 0.000003, min: 0, max: 128001 }, + { cost: 0.000006, min: 128000 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000015, min: 0, max: 128001 }, + { cost: 0.00003, min: 128000 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4-fast-non-reasoning', + input_cost_per_token: 2e-7, + output_cost_per_token: 5e-7, + input_cost_per_token_tiers: [ + { cost: 2e-7, min: 0, max: 128001 }, + { cost: 4e-7, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 5e-7, min: 0, max: 128001 }, + { cost: 0.000001, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4-fast-reasoning', + input_cost_per_token: 2e-7, + output_cost_per_token: 5e-7, + input_cost_per_token_tiers: [ + { cost: 2e-7, min: 0, max: 128001 }, + { cost: 4e-7, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 5e-7, min: 0, max: 128001 }, + { cost: 0.000001, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.1-fast-non-reasoning', + input_cost_per_token: 2e-7, + output_cost_per_token: 5e-7, + input_cost_per_token_tiers: [ + { cost: 2e-7, min: 0, max: 128001 }, + { cost: 4e-7, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 5e-7, min: 0, max: 128001 }, + { cost: 0.000001, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.1-fast-reasoning', + input_cost_per_token: 2e-7, + output_cost_per_token: 5e-7, + input_cost_per_token_tiers: [ + { cost: 2e-7, min: 0, max: 128001 }, + { cost: 4e-7, min: 128001 }, + ], + output_cost_per_token_tiers: [ + { cost: 5e-7, min: 0, max: 128001 }, + { cost: 0.000001, min: 128001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.20-multi-agent', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 200001 }, + { cost: 0.000012, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.20-multi-agent-beta', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 200001 }, + { cost: 0.000012, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.20-non-reasoning', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 200001 }, + { cost: 0.000012, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.20-non-reasoning-beta', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 200001 }, + { cost: 0.000012, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.20-reasoning', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 200001 }, + { cost: 0.000012, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-4.20-reasoning-beta', + input_cost_per_token: 0.000002, + output_cost_per_token: 0.000006, + input_cost_per_token_tiers: [ + { cost: 0.000002, min: 0, max: 200001 }, + { cost: 0.000004, min: 200001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000006, min: 0, max: 200001 }, + { cost: 0.000012, min: 200001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xai/grok-code-fast-1', + input_cost_per_token: 2e-7, + output_cost_per_token: 0.0000015, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xiaomi/mimo-v2-flash', + input_cost_per_token: 1e-7, + output_cost_per_token: 3e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/xiaomi/mimo-v2-pro', + input_cost_per_token: 0.000001, + output_cost_per_token: 0.000003, + input_cost_per_token_tiers: [ + { cost: 0.000001, min: 0, max: 256001 }, + { cost: 0.000002, min: 256001 }, + ], + output_cost_per_token_tiers: [ + { cost: 0.000003, min: 0, max: 256001 }, + { cost: 0.000006, min: 256001 }, + ], + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.5', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000022, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.5-air', + input_cost_per_token: 2e-7, + output_cost_per_token: 0.0000011, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.5v', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000018, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.6', + input_cost_per_token: 6e-7, + output_cost_per_token: 0.0000022, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.6v', + input_cost_per_token: 3e-7, + output_cost_per_token: 9e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.7', + input_cost_per_token: 0.00000225, + output_cost_per_token: 0.00000275, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.7-flash', + input_cost_per_token: 7e-8, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-4.7-flashx', + input_cost_per_token: 6e-8, + output_cost_per_token: 4e-7, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-5', + input_cost_per_token: 0.000001, + output_cost_per_token: 0.0000032, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-5-turbo', + input_cost_per_token: 0.0000012, + output_cost_per_token: 0.000004, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-5.1', + input_cost_per_token: 0.0000014, + output_cost_per_token: 0.0000044, + provider: 'Vercel AI Gateway', + }, + { + model_id: 'vercel/zai/glm-5v-turbo', + input_cost_per_token: 0.0000012, + output_cost_per_token: 0.000004, + provider: 'Vercel AI Gateway', + }, +]; diff --git a/packages/sdk/ts/src/supported-models/index.ts b/packages/sdk/ts/src/supported-models/index.ts index 3f641501d..2a6f2f40a 100644 --- a/packages/sdk/ts/src/supported-models/index.ts +++ b/packages/sdk/ts/src/supported-models/index.ts @@ -4,6 +4,7 @@ export * from './chat/anthropic'; export * from './chat/gemini'; export * from './chat/openai'; export * from './chat/openrouter'; +export * from './chat/vercel'; export * from './image/openai'; export * from './responses/openai'; export * from './video/gemini'; diff --git a/packages/sdk/ts/src/supported-models/types.ts b/packages/sdk/ts/src/supported-models/types.ts index 715f37664..5449d5a4a 100644 --- a/packages/sdk/ts/src/supported-models/types.ts +++ b/packages/sdk/ts/src/supported-models/types.ts @@ -2,9 +2,17 @@ export interface SupportedModel { model_id: string; input_cost_per_token: number; output_cost_per_token: number; + input_cost_per_token_tiers?: TokenPricingTier[]; + output_cost_per_token_tiers?: TokenPricingTier[]; provider: string; } +export interface TokenPricingTier { + cost: number; + min: number; + max?: number; +} + export interface SupportedImageModel { model_id: string; text_input_cost_per_token: number; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 06985ade8..3ded3ffea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1197,6 +1197,9 @@ importers: '@ai-sdk/anthropic': specifier: 2.0.17 version: 2.0.17(zod@4.1.11) + '@ai-sdk/gateway': + specifier: ^1.0.12 + version: 1.0.24(zod@4.1.11) '@ai-sdk/google': specifier: 2.0.14 version: 2.0.14(zod@4.1.11) @@ -1216,9 +1219,6 @@ importers: specifier: 5.0.47 version: 5.0.47(zod@4.1.11) devDependencies: - '@ai-sdk/gateway': - specifier: ^1.0.12 - version: 1.0.24(zod@4.1.11) '@types/node': specifier: ^24.3.1 version: 24.3.1