This commit is contained in:
Frank
2025-09-12 11:57:12 -04:00
parent c3dc6d6df6
commit c294a18155
10 changed files with 1342 additions and 40 deletions

View File

@@ -1,8 +1,26 @@
import type { APIEvent } from "@solidjs/start/server"
import { handler } from "~/util/zen"
type Usage = {
prompt_tokens?: number
completion_tokens?: number
total_tokens?: number
prompt_tokens_details?: {
text_tokens?: number
audio_tokens?: number
image_tokens?: number
cached_tokens?: number
}
completion_tokens_details?: {
reasoning_tokens?: number
audio_tokens?: number
accepted_prediction_tokens?: number
rejected_prediction_tokens?: number
}
}
export function POST(input: APIEvent) {
let usage: any
let usage: Usage
return handler(input, {
modifyBody: (body: any) => ({
...body,
@@ -17,7 +35,7 @@ export function POST(input: APIEvent) {
let json
try {
json = JSON.parse(chunk.slice(6))
json = JSON.parse(chunk.slice(6)) as { usage?: Usage }
} catch (e) {
return
}
@@ -26,11 +44,11 @@ export function POST(input: APIEvent) {
usage = json.usage
},
getStreamUsage: () => usage,
normalizeUsage: (usage: any) => ({
normalizeUsage: (usage: Usage) => ({
inputTokens: usage.prompt_tokens ?? 0,
outputTokens: usage.completion_tokens ?? 0,
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? 0,
cacheReadTokens: usage.prompt_tokens_details?.cached_tokens ?? 0,
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? undefined,
cacheReadTokens: usage.prompt_tokens_details?.cached_tokens ?? undefined,
}),
})
}

View File

@@ -53,9 +53,9 @@ export function POST(input: APIEvent) {
normalizeUsage: (usage: Usage) => ({
inputTokens: usage.input_tokens ?? 0,
outputTokens: usage.output_tokens ?? 0,
cacheReadTokens: usage.cache_read_input_tokens ?? 0,
cacheWrite5mTokens: usage.cache_creation?.ephemeral_5m_input_tokens,
cacheWrite1hTokens: usage.cache_creation?.ephemeral_1h_input_tokens,
cacheReadTokens: usage.cache_read_input_tokens ?? undefined,
cacheWrite5mTokens: usage.cache_creation?.ephemeral_5m_input_tokens ?? undefined,
cacheWrite1hTokens: usage.cache_creation?.ephemeral_1h_input_tokens ?? undefined,
}),
})
}

View File

@@ -1,8 +1,20 @@
import type { APIEvent } from "@solidjs/start/server"
import { handler } from "~/util/zen"
type Usage = {
input_tokens?: number
input_tokens_details?: {
cached_tokens?: number
}
output_tokens?: number
output_tokens_details?: {
reasoning_tokens?: number
}
total_tokens?: number
}
export function POST(input: APIEvent) {
let usage: any
let usage: Usage
return handler(input, {
setAuthHeader: (headers: Headers, apiKey: string) => {
headers.set("authorization", `Bearer ${apiKey}`)
@@ -15,7 +27,7 @@ export function POST(input: APIEvent) {
let json
try {
json = JSON.parse(data.slice(6))
json = JSON.parse(data.slice(6)) as { response?: { usage?: Usage } }
} catch (e) {
return
}
@@ -24,14 +36,14 @@ export function POST(input: APIEvent) {
usage = json.response.usage
},
getStreamUsage: () => usage,
normalizeUsage: (usage: any) => {
normalizeUsage: (usage: Usage) => {
const inputTokens = usage.input_tokens ?? 0
const outputTokens = usage.output_tokens ?? 0
const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? 0
const cacheReadTokens = usage.input_tokens_details?.cached_tokens ?? 0
const reasoningTokens = usage.output_tokens_details?.reasoning_tokens ?? undefined
const cacheReadTokens = usage.input_tokens_details?.cached_tokens ?? undefined
return {
inputTokens: inputTokens - cacheReadTokens,
outputTokens: outputTokens - reasoningTokens,
inputTokens: inputTokens - (cacheReadTokens ?? 0),
outputTokens: outputTokens - (reasoningTokens ?? 0),
reasoningTokens,
cacheReadTokens,
}

View File

@@ -10,10 +10,11 @@ import { Resource } from "@opencode/cloud-resource"
type ModelCost = {
input: number
output: number
cacheRead: number
cacheWrite5m: number
cacheWrite1h: number
cacheRead?: number
cacheWrite5m?: number
cacheWrite1h?: number
}
type Model = {
id: string
auth: boolean
@@ -42,7 +43,7 @@ export async function handler(
inputTokens: number
outputTokens: number
reasoningTokens?: number
cacheReadTokens: number
cacheReadTokens?: number
cacheWrite5mTokens?: number
cacheWrite1hTokens?: number
}
@@ -129,8 +130,6 @@ export async function handler(
input: 0.00000125,
output: 0.00001,
cacheRead: 0.000000125,
cacheWrite5m: 0,
cacheWrite1h: 0,
},
headerMappings: {},
providers: {
@@ -147,9 +146,6 @@ export async function handler(
cost: {
input: 0.00000045,
output: 0.0000018,
cacheRead: 0,
cacheWrite5m: 0,
cacheWrite1h: 0,
},
headerMappings: {},
providers: {
@@ -173,9 +169,6 @@ export async function handler(
cost: {
input: 0.0000006,
output: 0.0000025,
cacheRead: 0,
cacheWrite5m: 0,
cacheWrite1h: 0,
},
headerMappings: {},
providers: {
@@ -200,8 +193,6 @@ export async function handler(
input: 0,
output: 0,
cacheRead: 0,
cacheWrite5m: 0,
cacheWrite1h: 0,
},
headerMappings: {
"x-grok-conv-id": "x-opencode-session",
@@ -222,9 +213,6 @@ export async function handler(
cost: {
input: 0.00000038,
output: 0.00000153,
cacheRead: 0,
cacheWrite5m: 0,
cacheWrite1h: 0,
},
headerMappings: {},
providers: {
@@ -438,15 +426,30 @@ export async function handler(
const inputCost = modelCost.input * inputTokens * 100
const outputCost = modelCost.output * outputTokens * 100
const reasoningCost = reasoningTokens ? modelCost.output * reasoningTokens * 100 : undefined
const cacheReadCost = modelCost.cacheRead * cacheReadTokens * 100
const cacheWrite5mCost = cacheWrite5mTokens ? modelCost.cacheWrite5m * cacheWrite5mTokens * 100 : undefined
const cacheWrite1hCost = cacheWrite1hTokens ? modelCost.cacheWrite1h * cacheWrite1hTokens * 100 : undefined
const reasoningCost = (() => {
if (!reasoningTokens) return undefined
return modelCost.output * reasoningTokens * 100
})()
const cacheReadCost = (() => {
if (!cacheReadTokens) return undefined
if (!modelCost.cacheRead) return undefined
return modelCost.cacheRead * cacheReadTokens * 100
})()
const cacheWrite5mCost = (() => {
if (!cacheWrite5mTokens) return undefined
if (!modelCost.cacheWrite5m) return undefined
return modelCost.cacheWrite5m * cacheWrite5mTokens * 100
})()
const cacheWrite1hCost = (() => {
if (!cacheWrite1hTokens) return undefined
if (!modelCost.cacheWrite1h) return undefined
return modelCost.cacheWrite1h * cacheWrite1hTokens * 100
})()
const totalCostInCent =
inputCost +
outputCost +
(reasoningCost ?? 0) +
cacheReadCost +
(cacheReadCost ?? 0) +
(cacheWrite5mCost ?? 0) +
(cacheWrite1hCost ?? 0)
@@ -460,7 +463,7 @@ export async function handler(
"cost.input": Math.round(inputCost),
"cost.output": Math.round(outputCost),
"cost.reasoning": reasoningCost ? Math.round(reasoningCost) : undefined,
"cost.cache_read": Math.round(cacheReadCost),
"cost.cache_read": cacheReadCost ? Math.round(cacheReadCost) : undefined,
"cost.cache_write_5m": cacheWrite5mCost ? Math.round(cacheWrite5mCost) : undefined,
"cost.cache_write_1h": cacheWrite1hCost ? Math.round(cacheWrite1hCost) : undefined,
"cost.total": Math.round(totalCostInCent),
@@ -480,6 +483,8 @@ export async function handler(
reasoningTokens,
cacheReadTokens,
cacheWriteTokens: (cacheWrite5mTokens ?? 0) + (cacheWrite1hTokens ?? 0),
cacheWrite5mTokens,
cacheWrite1hTokens,
cost,
})
await tx