chore(cdp): Move ai costs around (#29360)

This commit is contained in:
Ben White
2025-03-05 10:23:26 +01:00
committed by GitHub
parent 8112b1fe2a
commit 2eb31e3b75
22 changed files with 2373 additions and 1224 deletions

View File

@@ -1 +1,6 @@
pnpm-lock.yaml
providers.json
dist/
node_modules/
coverage/
.tmp/

View File

@@ -31,7 +31,7 @@
"services:clean": "cd .. && docker compose -f docker-compose.dev.yml rm -v",
"services": "pnpm services:stop && pnpm services:clean && pnpm services:start",
"build:cyclotron": "pnpm --filter=@posthog/cyclotron package",
"update-ai-costs": "ts-node scripts/update-ai-costs.ts"
"update-ai-costs": "ts-node src/ingestion/ai-costs/scripts/update-ai-costs.ts"
},
"bin": {
"posthog-plugin-server": "bin/posthog-plugin-server"

View File

@@ -1,133 +0,0 @@
import dotenv from 'dotenv'
import fs from 'fs'
import bigDecimal from 'js-big-decimal'
import path from 'path'
dotenv.config()
interface ModelRow {
model: string
cost: {
prompt_token: string
completion_token: string
}
}
const supportedProviderList = [
'openai',
'anthropic',
'google',
'deepseek',
'perplexity',
'cohere',
'mistralai',
'meta-llama',
]
function serializeModels(models: ModelRow[]): string {
let output = '[\n'
models.forEach((model, index) => {
output += ' {\n'
output += ` model: ${JSON.stringify(model.model)},\n`
output += ' cost: {\n'
output += ` prompt_token: ${new bigDecimal(model.cost.prompt_token)
.round(10)
.stripTrailingZero()
.getValue()},\n`
output += ` completion_token: ${new bigDecimal(model.cost.completion_token)
.round(10)
.stripTrailingZero()
.getValue()}\n`
output += ' }\n'
output += ' }'
output += index < models.length - 1 ? ',\n' : '\n'
})
output += ']'
return output
}
const main = async () => {
if (!process.env.OPENROUTER_API_KEY) {
console.error('OPENROUTER_API_KEY is not set')
return
}
const res = await fetch('https://openrouter.ai/api/v1/models', {
headers: {
Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,
},
})
if (!res.ok) {
throw new Error(`Failed to fetch models: ${res.status} ${res.statusText}`)
}
let data
try {
data = await res.json()
} catch (e) {
throw new Error('Failed to parse API response as JSON')
}
console.log(data.data)
const models = data.data
// Create main directory
const baseDir = path.join(process.cwd(), 'src/utils/ai-costs')
if (!fs.existsSync(baseDir)) {
fs.mkdirSync(baseDir)
}
// Group models by provider
const providerModels = new Map<string, ModelRow[]>()
for (const model of models) {
if (!model?.id || !model?.pricing?.prompt || !model?.pricing?.completion) {
console.warn('Skipping invalid model:', model)
continue
}
const [provider, ...modelParts] = model.id.split('/')
if (!supportedProviderList.includes(provider)) {
continue
}
if (!providerModels.has(provider)) {
providerModels.set(provider, [])
}
// Convert pricing values to numbers before using toFixed(10)
const promptPrice = new bigDecimal(model.pricing.prompt).getValue()
const completionPrice = new bigDecimal(model.pricing.completion).getValue()
const modelRow: ModelRow = {
model: modelParts.join('/'), // Only include the part after the provider
cost: {
prompt_token: promptPrice,
completion_token: completionPrice,
},
}
providerModels.get(provider)!.push(modelRow)
}
// Generate files for each provider using our custom serializer
for (const [provider, models] of providerModels.entries()) {
const fileContent = `import type { ModelRow } from './types';\n\nexport const costs: ModelRow[] = ${serializeModels(
models
)};\n`
fs.writeFileSync(path.join(baseDir, `${provider}.ts`), fileContent)
}
// Create types.ts in the base directory
const typesContent = `export interface ModelRow {
model: string;
cost: {
prompt_token: number;
completion_token: number;
};
}`
fs.writeFileSync(path.join(baseDir, 'types.ts'), typesContent)
}
;(async () => {
await main()
})().catch((e) => {
console.error('Error updating AI costs:', e)
process.exit(1)
})

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
import { PluginEvent } from '@posthog/plugin-scaffold'
import { processAiEvent } from '../../../src/worker/ingestion/event-pipeline/processAiEvent'
import { processAiEvent } from './process-ai-event'
import { costsByModel } from './providers'
describe('processAiEvent()', () => {
let event: PluginEvent
@@ -146,4 +147,16 @@ describe('processAiEvent()', () => {
expect(result.properties!.$ai_output_cost_usd).toBeUndefined()
})
})
describe('smoke test every model', () => {
it.each(Object.keys(costsByModel))('processes %s', (model) => {
event.properties!.$ai_model = model
const result = processAiEvent(event)
expect({
$ai_total_cost_usd: result.properties!.$ai_total_cost_usd,
$ai_input_cost_usd: result.properties!.$ai_input_cost_usd,
$ai_output_cost_usd: result.properties!.$ai_output_cost_usd,
}).toMatchSnapshot()
})
})
})

View File

@@ -1,8 +1,8 @@
import { PluginEvent } from '@posthog/plugin-scaffold'
import bigDecimal from 'js-big-decimal'
import { costs } from '../../../utils/ai-costs'
import { ModelRow } from '../../../utils/ai-costs/types'
import { costsByModel } from './providers'
import { ModelRow } from './providers/types'
export const processAiEvent = (event: PluginEvent): PluginEvent => {
if ((event.event !== '$ai_generation' && event.event !== '$ai_embedding') || !event.properties) {
@@ -100,14 +100,14 @@ export const extractCoreModelParams = (event: PluginEvent): PluginEvent => {
const findCostFromModel = (aiModel: string): ModelRow | undefined => {
// Check if the model is an exact match
let cost = costs.find((cost) => cost.model.toLowerCase() === aiModel.toLowerCase())
let cost: ModelRow | undefined = costsByModel[aiModel.toLowerCase()]
// Check if the model is a variant of a known model
if (!cost) {
cost = costs.find((cost) => aiModel.toLowerCase().includes(cost.model.toLowerCase()))
cost = Object.values(costsByModel).find((cost) => aiModel.toLowerCase().includes(cost.model.toLowerCase()))
}
// Check if the model is a variant of a known model
if (!cost) {
cost = costs.find((cost) => cost.model.toLowerCase().includes(aiModel.toLowerCase()))
cost = Object.values(costsByModel).find((cost) => aiModel.toLowerCase().includes(cost.model.toLowerCase()))
}
if (!cost) {
console.warn(`No cost found for model: ${aiModel}`)

View File

@@ -0,0 +1,10 @@
import { costsOverrides } from './overrides'
import generatedCosts from './providers.json'
import type { ModelRow } from './types'
export const costsByModel: Record<string, ModelRow> = {}
for (const cost of [...generatedCosts, ...costsOverrides]) {
// NOTE: This is done in a loop with overrides after ensuring that they are applied
costsByModel[cost.model] = cost
}

View File

@@ -1,6 +1,15 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
export const costsOverrides: ModelRow[] = [
// OpenAI
{
model: 'gpt-4.5',
cost: {
prompt_token: 0.000075,
completion_token: 0.00015,
},
},
// Anthropic
{
model: 'claude-3-5-haiku',
cost: {

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
import fs from 'fs'
import bigDecimal from 'js-big-decimal'
import path from 'path'
interface ModelRow {
model: string
cost: {
prompt_token: number
completion_token: number
}
}
const supportedProviderList = [
'openai',
'anthropic',
'google',
'deepseek',
'perplexity',
'cohere',
'mistralai',
'meta-llama',
]
const PATH_TO_PROVIDERS = path.join(__dirname, '../providers')
const main = async () => {
const res = await fetch('https://openrouter.ai/api/v1/models', {})
if (!res.ok) {
throw new Error(`Failed to fetch models: ${res.status} ${res.statusText}`)
}
let data
try {
data = await res.json()
} catch (e) {
throw new Error('Failed to parse API response as JSON')
}
console.log(data.data)
const models = data.data
// Create main directory
if (!fs.existsSync(PATH_TO_PROVIDERS)) {
fs.mkdirSync(PATH_TO_PROVIDERS)
}
// Group models by provider
const providerModels = new Map<string, ModelRow[]>()
for (const model of models) {
if (!model?.id || !model?.pricing?.prompt || !model?.pricing?.completion) {
console.warn('Skipping invalid model:', model)
continue
}
const [provider, ...modelParts] = model.id.split('/')
if (!supportedProviderList.includes(provider)) {
continue
}
if (!providerModels.has(provider)) {
providerModels.set(provider, [])
}
// Convert pricing values to numbers before using toFixed(10)
const promptPrice = new bigDecimal(model.pricing.prompt).getValue()
const completionPrice = new bigDecimal(model.pricing.completion).getValue()
const modelRow: ModelRow = {
model: modelParts.join('/'), // Only include the part after the provider
cost: {
prompt_token: parseFloat(promptPrice),
completion_token: parseFloat(completionPrice),
},
}
providerModels.get(provider)!.push(modelRow)
}
const allProviders = Array.from(providerModels.values()).flat()
// Write everything as a json file
fs.writeFileSync(path.join(PATH_TO_PROVIDERS, 'providers.json'), JSON.stringify(allProviders, null, 2))
}
;(async () => {
await main()
})().catch((e) => {
console.error('Error updating AI costs:', e)
process.exit(1)
})

View File

@@ -1,165 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'claude-3.7-sonnet:beta',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3.7-sonnet',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3.7-sonnet:thinking',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3.5-haiku:beta',
cost: {
prompt_token: 0.0000008,
completion_token: 0.000004,
},
},
{
model: 'claude-3.5-haiku',
cost: {
prompt_token: 0.0000008,
completion_token: 0.000004,
},
},
{
model: 'claude-3.5-haiku-20241022:beta',
cost: {
prompt_token: 0.0000008,
completion_token: 0.000004,
},
},
{
model: 'claude-3.5-haiku-20241022',
cost: {
prompt_token: 0.0000008,
completion_token: 0.000004,
},
},
{
model: 'claude-3.5-sonnet:beta',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3.5-sonnet',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3.5-sonnet-20240620:beta',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3.5-sonnet-20240620',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3-haiku:beta',
cost: {
prompt_token: 0.00000025,
completion_token: 0.00000125,
},
},
{
model: 'claude-3-haiku',
cost: {
prompt_token: 0.00000025,
completion_token: 0.00000125,
},
},
{
model: 'claude-3-sonnet:beta',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3-sonnet',
cost: {
prompt_token: 0.000003,
completion_token: 0.000015,
},
},
{
model: 'claude-3-opus:beta',
cost: {
prompt_token: 0.000015,
completion_token: 0.000075,
},
},
{
model: 'claude-3-opus',
cost: {
prompt_token: 0.000015,
completion_token: 0.000075,
},
},
{
model: 'claude-2.1:beta',
cost: {
prompt_token: 0.000008,
completion_token: 0.000024,
},
},
{
model: 'claude-2.1',
cost: {
prompt_token: 0.000008,
completion_token: 0.000024,
},
},
{
model: 'claude-2:beta',
cost: {
prompt_token: 0.000008,
completion_token: 0.000024,
},
},
{
model: 'claude-2',
cost: {
prompt_token: 0.000008,
completion_token: 0.000024,
},
},
{
model: 'claude-2.0:beta',
cost: {
prompt_token: 0.000008,
completion_token: 0.000024,
},
},
{
model: 'claude-2.0',
cost: {
prompt_token: 0.000008,
completion_token: 0.000024,
},
},
]

View File

@@ -1,60 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'command-r7b-12-2024',
cost: {
prompt_token: 0.0000000375,
completion_token: 0.00000015,
},
},
{
model: 'command-r-plus-08-2024',
cost: {
prompt_token: 0.000002375,
completion_token: 0.0000095,
},
},
{
model: 'command-r-08-2024',
cost: {
prompt_token: 0.0000001425,
completion_token: 0.00000057,
},
},
{
model: 'command-r-plus',
cost: {
prompt_token: 0.00000285,
completion_token: 0.00001425,
},
},
{
model: 'command-r-plus-04-2024',
cost: {
prompt_token: 0.00000285,
completion_token: 0.00001425,
},
},
{
model: 'command',
cost: {
prompt_token: 0.00000095,
completion_token: 0.0000019,
},
},
{
model: 'command-r',
cost: {
prompt_token: 0.000000475,
completion_token: 0.000001425,
},
},
{
model: 'command-r-03-2024',
cost: {
prompt_token: 0.000000475,
completion_token: 0.000001425,
},
},
]

View File

@@ -1,81 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'deepseek-r1-distill-llama-8b',
cost: {
prompt_token: 0.00000004,
completion_token: 0.00000004,
},
},
{
model: 'deepseek-r1-distill-qwen-1.5b',
cost: {
prompt_token: 0.00000018,
completion_token: 0.00000018,
},
},
{
model: 'deepseek-r1-distill-qwen-32b',
cost: {
prompt_token: 0.00000012,
completion_token: 0.00000018,
},
},
{
model: 'deepseek-r1-distill-qwen-14b',
cost: {
prompt_token: 0.0000016,
completion_token: 0.0000016,
},
},
{
model: 'deepseek-r1-distill-llama-70b:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'deepseek-r1-distill-llama-70b',
cost: {
prompt_token: 0.00000023,
completion_token: 0.00000069,
},
},
{
model: 'deepseek-r1:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'deepseek-r1',
cost: {
prompt_token: 0.0000008,
completion_token: 0.0000024,
},
},
{
model: 'deepseek-chat:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'deepseek-chat',
cost: {
prompt_token: 0.00000125,
completion_token: 0.00000125,
},
},
{
model: 'deepseek-chat-v2.5',
cost: {
prompt_token: 0.000002,
completion_token: 0.000002,
},
},
]

View File

@@ -1,165 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'gemini-2.0-flash-lite-001',
cost: {
prompt_token: 0.000000075,
completion_token: 0.0000003,
},
},
{
model: 'gemini-2.0-flash-001',
cost: {
prompt_token: 0.0000001,
completion_token: 0.0000004,
},
},
{
model: 'gemini-2.0-flash-lite-preview-02-05:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemini-2.0-pro-exp-02-05:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemini-2.0-flash-thinking-exp:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemini-2.0-flash-thinking-exp-1219:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemini-2.0-flash-exp:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemini-exp-1206:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'learnlm-1.5-pro-experimental:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemini-flash-1.5-8b',
cost: {
prompt_token: 0.0000000375,
completion_token: 0.00000015,
},
},
{
model: 'gemini-flash-1.5-8b-exp',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemma-2-27b-it',
cost: {
prompt_token: 0.00000027,
completion_token: 0.00000027,
},
},
{
model: 'gemma-2-9b-it:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'gemma-2-9b-it',
cost: {
prompt_token: 0.00000003,
completion_token: 0.00000006,
},
},
{
model: 'gemini-flash-1.5',
cost: {
prompt_token: 0.000000075,
completion_token: 0.0000003,
},
},
{
model: 'gemini-pro-1.5',
cost: {
prompt_token: 0.00000125,
completion_token: 0.000005,
},
},
{
model: 'gemma-7b-it',
cost: {
prompt_token: 0.00000015,
completion_token: 0.00000015,
},
},
{
model: 'gemini-pro',
cost: {
prompt_token: 0.0000005,
completion_token: 0.0000015,
},
},
{
model: 'gemini-pro-vision',
cost: {
prompt_token: 0.0000005,
completion_token: 0.0000015,
},
},
{
model: 'palm-2-chat-bison-32k',
cost: {
prompt_token: 0.000001,
completion_token: 0.000002,
},
},
{
model: 'palm-2-codechat-bison-32k',
cost: {
prompt_token: 0.000001,
completion_token: 0.000002,
},
},
{
model: 'palm-2-codechat-bison',
cost: {
prompt_token: 0.000001,
completion_token: 0.000002,
},
},
{
model: 'palm-2-chat-bison',
cost: {
prompt_token: 0.000001,
completion_token: 0.000002,
},
},
]

View File

@@ -1,24 +0,0 @@
import { costs as anthropicCosts } from './anthropic'
import { costs as anthropicOverrides } from './anthropic_overrides'
import { costs as cohereCosts } from './cohere'
import { costs as deepseekCosts } from './deepseek'
import { costs as googleCosts } from './google'
import { costs as metaLlamaCosts } from './meta-llama'
import { costs as mistralaiCosts } from './mistralai'
import { costs as openaiCosts } from './openai'
import { costs as openaiOverrides } from './openai_overrides'
import { costs as perplexityCosts } from './perplexity'
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
...openaiCosts,
...openaiOverrides,
...anthropicCosts,
...anthropicOverrides,
...googleCosts,
...deepseekCosts,
...perplexityCosts,
...cohereCosts,
...mistralaiCosts,
...metaLlamaCosts,
]

View File

@@ -1,144 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'llama-guard-3-8b',
cost: {
prompt_token: 0.0000003,
completion_token: 0.0000003,
},
},
{
model: 'llama-3.3-70b-instruct:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'llama-3.3-70b-instruct',
cost: {
prompt_token: 0.00000012,
completion_token: 0.0000003,
},
},
{
model: 'llama-3.2-3b-instruct',
cost: {
prompt_token: 0.000000015,
completion_token: 0.000000025,
},
},
{
model: 'llama-3.2-11b-vision-instruct:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'llama-3.2-11b-vision-instruct',
cost: {
prompt_token: 0.000000055,
completion_token: 0.000000055,
},
},
{
model: 'llama-3.2-90b-vision-instruct',
cost: {
prompt_token: 0.0000008,
completion_token: 0.0000016,
},
},
{
model: 'llama-3.2-1b-instruct:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'llama-3.2-1b-instruct',
cost: {
prompt_token: 0.00000001,
completion_token: 0.00000001,
},
},
{
model: 'llama-3.1-405b',
cost: {
prompt_token: 0.000002,
completion_token: 0.000002,
},
},
{
model: 'llama-3.1-405b-instruct',
cost: {
prompt_token: 0.0000008,
completion_token: 0.0000008,
},
},
{
model: 'llama-3.1-8b-instruct:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'llama-3.1-8b-instruct',
cost: {
prompt_token: 0.00000002,
completion_token: 0.00000005,
},
},
{
model: 'llama-3.1-70b-instruct',
cost: {
prompt_token: 0.00000012,
completion_token: 0.0000003,
},
},
{
model: 'llama-guard-2-8b',
cost: {
prompt_token: 0.0000002,
completion_token: 0.0000002,
},
},
{
model: 'llama-3-8b-instruct:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'llama-3-8b-instruct',
cost: {
prompt_token: 0.00000003,
completion_token: 0.00000006,
},
},
{
model: 'llama-3-70b-instruct',
cost: {
prompt_token: 0.00000023,
completion_token: 0.0000004,
},
},
{
model: 'llama-2-13b-chat',
cost: {
prompt_token: 0.00000022,
completion_token: 0.00000022,
},
},
{
model: 'llama-2-70b-chat',
cost: {
prompt_token: 0.0000009,
completion_token: 0.0000009,
},
},
]

View File

@@ -1,172 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'mistral-saba',
cost: {
prompt_token: 0.0000002,
completion_token: 0.0000006,
},
},
{
model: 'mistral-small-24b-instruct-2501:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'mistral-small-24b-instruct-2501',
cost: {
prompt_token: 0.00000007,
completion_token: 0.00000014,
},
},
{
model: 'codestral-2501',
cost: {
prompt_token: 0.0000003,
completion_token: 0.0000009,
},
},
{
model: 'mistral-large-2411',
cost: {
prompt_token: 0.000002,
completion_token: 0.000006,
},
},
{
model: 'mistral-large-2407',
cost: {
prompt_token: 0.000002,
completion_token: 0.000006,
},
},
{
model: 'pixtral-large-2411',
cost: {
prompt_token: 0.000002,
completion_token: 0.000006,
},
},
{
model: 'ministral-8b',
cost: {
prompt_token: 0.0000001,
completion_token: 0.0000001,
},
},
{
model: 'ministral-3b',
cost: {
prompt_token: 0.00000004,
completion_token: 0.00000004,
},
},
{
model: 'pixtral-12b',
cost: {
prompt_token: 0.0000001,
completion_token: 0.0000001,
},
},
{
model: 'codestral-mamba',
cost: {
prompt_token: 0.00000025,
completion_token: 0.00000025,
},
},
{
model: 'mistral-nemo:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'mistral-nemo',
cost: {
prompt_token: 0.000000035,
completion_token: 0.00000008,
},
},
{
model: 'mistral-7b-instruct-v0.3',
cost: {
prompt_token: 0.00000003,
completion_token: 0.000000055,
},
},
{
model: 'mistral-7b-instruct:free',
cost: {
prompt_token: 0,
completion_token: 0,
},
},
{
model: 'mistral-7b-instruct',
cost: {
prompt_token: 0.00000003,
completion_token: 0.000000055,
},
},
{
model: 'mixtral-8x22b-instruct',
cost: {
prompt_token: 0.0000009,
completion_token: 0.0000009,
},
},
{
model: 'mistral-large',
cost: {
prompt_token: 0.000002,
completion_token: 0.000006,
},
},
{
model: 'mistral-tiny',
cost: {
prompt_token: 0.00000025,
completion_token: 0.00000025,
},
},
{
model: 'mistral-small',
cost: {
prompt_token: 0.0000002,
completion_token: 0.0000006,
},
},
{
model: 'mistral-medium',
cost: {
prompt_token: 0.00000275,
completion_token: 0.0000081,
},
},
{
model: 'mixtral-8x7b',
cost: {
prompt_token: 0.0000006,
completion_token: 0.0000006,
},
},
{
model: 'mixtral-8x7b-instruct',
cost: {
prompt_token: 0.00000024,
completion_token: 0.00000024,
},
},
{
model: 'mistral-7b-instruct-v0.1',
cost: {
prompt_token: 0.0000002,
completion_token: 0.0000002,
},
},
]

View File

@@ -1,200 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'o3-mini-high',
cost: {
prompt_token: 0.0000011,
completion_token: 0.0000044,
},
},
{
model: 'o3-mini',
cost: {
prompt_token: 0.0000011,
completion_token: 0.0000044,
},
},
{
model: 'o1',
cost: {
prompt_token: 0.000015,
completion_token: 0.00006,
},
},
{
model: 'gpt-4o-2024-11-20',
cost: {
prompt_token: 0.0000025,
completion_token: 0.00001,
},
},
{
model: 'o1-mini',
cost: {
prompt_token: 0.0000011,
completion_token: 0.0000044,
},
},
{
model: 'o1-preview',
cost: {
prompt_token: 0.000015,
completion_token: 0.00006,
},
},
{
model: 'o1-preview-2024-09-12',
cost: {
prompt_token: 0.000015,
completion_token: 0.00006,
},
},
{
model: 'o1-mini-2024-09-12',
cost: {
prompt_token: 0.0000011,
completion_token: 0.0000044,
},
},
{
model: 'chatgpt-4o-latest',
cost: {
prompt_token: 0.000005,
completion_token: 0.000015,
},
},
{
model: 'gpt-4o-2024-08-06',
cost: {
prompt_token: 0.0000025,
completion_token: 0.00001,
},
},
{
model: 'gpt-4o-mini-2024-07-18',
cost: {
prompt_token: 0.00000015,
completion_token: 0.0000006,
},
},
{
model: 'gpt-4o-mini',
cost: {
prompt_token: 0.00000015,
completion_token: 0.0000006,
},
},
{
model: 'gpt-4o-2024-05-13',
cost: {
prompt_token: 0.000005,
completion_token: 0.000015,
},
},
{
model: 'gpt-4o',
cost: {
prompt_token: 0.0000025,
completion_token: 0.00001,
},
},
{
model: 'gpt-4o:extended',
cost: {
prompt_token: 0.000006,
completion_token: 0.000018,
},
},
{
model: 'gpt-4-turbo',
cost: {
prompt_token: 0.00001,
completion_token: 0.00003,
},
},
{
model: 'gpt-3.5-turbo-0613',
cost: {
prompt_token: 0.000001,
completion_token: 0.000002,
},
},
{
model: 'gpt-4-turbo-preview',
cost: {
prompt_token: 0.00001,
completion_token: 0.00003,
},
},
{
model: 'gpt-4-1106-preview',
cost: {
prompt_token: 0.00001,
completion_token: 0.00003,
},
},
{
model: 'gpt-3.5-turbo-1106',
cost: {
prompt_token: 0.000001,
completion_token: 0.000002,
},
},
{
model: 'gpt-3.5-turbo-instruct',
cost: {
prompt_token: 0.0000015,
completion_token: 0.000002,
},
},
{
model: 'gpt-3.5-turbo-16k',
cost: {
prompt_token: 0.000003,
completion_token: 0.000004,
},
},
{
model: 'gpt-4-32k',
cost: {
prompt_token: 0.00006,
completion_token: 0.00012,
},
},
{
model: 'gpt-4-32k-0314',
cost: {
prompt_token: 0.00006,
completion_token: 0.00012,
},
},
{
model: 'gpt-4',
cost: {
prompt_token: 0.00003,
completion_token: 0.00006,
},
},
{
model: 'gpt-4-0314',
cost: {
prompt_token: 0.00003,
completion_token: 0.00006,
},
},
{
model: 'gpt-3.5-turbo-0125',
cost: {
prompt_token: 0.0000005,
completion_token: 0.0000015,
},
},
{
model: 'gpt-3.5-turbo',
cost: {
prompt_token: 0.0000005,
completion_token: 0.0000015,
},
},
]

View File

@@ -1,11 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'gpt-4.5',
cost: {
prompt_token: 0.000075,
completion_token: 0.00015,
},
},
]

View File

@@ -1,60 +0,0 @@
import type { ModelRow } from './types'
export const costs: ModelRow[] = [
{
model: 'r1-1776',
cost: {
prompt_token: 0.000002,
completion_token: 0.000008,
},
},
{
model: 'sonar-reasoning',
cost: {
prompt_token: 0.000001,
completion_token: 0.000005,
},
},
{
model: 'sonar',
cost: {
prompt_token: 0.000001,
completion_token: 0.000001,
},
},
{
model: 'llama-3.1-sonar-huge-128k-online',
cost: {
prompt_token: 0.000005,
completion_token: 0.000005,
},
},
{
model: 'llama-3.1-sonar-small-128k-chat',
cost: {
prompt_token: 0.0000002,
completion_token: 0.0000002,
},
},
{
model: 'llama-3.1-sonar-large-128k-online',
cost: {
prompt_token: 0.000001,
completion_token: 0.000001,
},
},
{
model: 'llama-3.1-sonar-large-128k-chat',
cost: {
prompt_token: 0.000001,
completion_token: 0.000001,
},
},
{
model: 'llama-3.1-sonar-small-128k-online',
cost: {
prompt_token: 0.0000002,
completion_token: 0.0000002,
},
},
]

View File

@@ -2,12 +2,12 @@ import { PluginEvent } from '@posthog/plugin-scaffold'
import { PreIngestionEvent } from '~/src/types'
import { processAiEvent } from '../../../ingestion/ai-costs/process-ai-event'
import { captureException } from '../../../utils/posthog'
import { status } from '../../../utils/status'
import { parseEventTimestamp } from '../timestamps'
import { captureIngestionWarning } from '../utils'
import { invalidTimestampCounter } from './metrics'
import { processAiEvent } from './processAiEvent'
import { EventPipelineRunner } from './runner'
export async function prepareEventStep(