From 4482194835d6215272c751720d3eec67d161cde8 Mon Sep 17 00:00:00 2001 From: bin zhang Date: Sat, 18 Jan 2025 16:04:14 +0800 Subject: [PATCH] Refines pricing calculation for token-based services Updates pricing calculation to account for maximum output tokens Improves price conversion from per-million to per-token basis Removes unused tap import and cleans up variable naming The new calculation provides more accurate pricing based on actual token limits and better handles conversion from million-token pricing to per-token costs. --- packages/ai/llm/getPricing.ts | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/ai/llm/getPricing.ts b/packages/ai/llm/getPricing.ts index 526e7f0a..230d450e 100644 --- a/packages/ai/llm/getPricing.ts +++ b/packages/ai/llm/getPricing.ts @@ -1,6 +1,6 @@ -// ai/llm/getPrice +// ai/llm/getPrice.ts import { getModelsByProvider } from "ai/llm/providers"; -import { pipe, tap } from "rambda"; +import { pipe } from "rambda"; interface ModelPricing { inputPrice: number; @@ -15,23 +15,24 @@ interface Prices { serverOutput: number; } +const MAX_OUTPUT_TOKENS = 8192 * 3; // Maximum tokens for single output + export const getModelPricing = ( provider: string, modelName: string ): ModelPricing | null => { const models = getModelsByProvider(provider); + const model = models.find((m) => m.name === modelName); - const selectedModel = models.find((model) => model.name === modelName); + if (!model?.price) return null; - if (!selectedModel?.price) { - return null; - } return { - inputPrice: selectedModel.price.input, - inputCacheHitPrice: selectedModel.price.inputCacheHit, - outputPrice: selectedModel.price.output, + inputPrice: model.price.input, + inputCacheHitPrice: model.price.inputCacheHit, + outputPrice: model.price.output, }; }; + export const getPrices = (config: any, serverPrices: any): Prices => ({ cybotInput: Number(config?.inputPrice ?? 0), cybotOutput: Number(config?.outputPrice ?? 0), @@ -39,10 +40,19 @@ export const getPrices = (config: any, serverPrices: any): Prices => ({ serverOutput: Number(serverPrices?.outputPrice ?? 0), }); -export const getFinalPrice = (prices: Prices): number => - pipe( +export const getFinalPrice = (prices: Prices): number => { + // Find the highest price per token among all valid prices + // These prices are originally based on 1M tokens cost + const maxPricePerMillion = pipe( Object.values, (values) => values.filter((v) => !isNaN(v) && v !== null), (values) => values.length ? values.reduce((acc, curr) => Math.max(acc, curr), 0) : 0 )(prices); + + // Convert price from per 1M tokens to per token + const maxPricePerToken = maxPricePerMillion / 1_000_000; + + // Calculate final price for maximum output tokens (8192 * 3) + return maxPricePerToken * MAX_OUTPUT_TOKENS; +};