mirror of
https://github.com/BillyOutlast/posthog.git
synced 2026-02-04 03:01:23 +01:00
chore(cdp): Move ai costs around (#29360)
This commit is contained in:
@@ -1 +1,6 @@
|
||||
pnpm-lock.yaml
|
||||
providers.json
|
||||
dist/
|
||||
node_modules/
|
||||
coverage/
|
||||
.tmp/
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -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}`)
|
||||
10
plugin-server/src/ingestion/ai-costs/providers/index.ts
Normal file
10
plugin-server/src/ingestion/ai-costs/providers/index.ts
Normal 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
|
||||
}
|
||||
@@ -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: {
|
||||
1031
plugin-server/src/ingestion/ai-costs/providers/providers.json
Normal file
1031
plugin-server/src/ingestion/ai-costs/providers/providers.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
})
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user