diff options
| author | Frank <[email protected]> | 2025-09-12 11:57:12 -0400 |
|---|---|---|
| committer | Frank <[email protected]> | 2025-09-12 11:57:14 -0400 |
| commit | c294a181559185dedf6a65e00e1db597721a815b (patch) | |
| tree | 3a9569986462b8d399d903092451dcb534f4dcb0 /cloud/app/src | |
| parent | c3dc6d6df647f8e21dfcd9aeaf4d69bc45580020 (diff) | |
| download | opencode-c294a181559185dedf6a65e00e1db597721a815b.tar.gz opencode-c294a181559185dedf6a65e00e1db597721a815b.zip | |
wip: zen
Diffstat (limited to 'cloud/app/src')
| -rw-r--r-- | cloud/app/src/routes/zen/v1/chat/completions.ts | 28 | ||||
| -rw-r--r-- | cloud/app/src/routes/zen/v1/messages.ts | 6 | ||||
| -rw-r--r-- | cloud/app/src/routes/zen/v1/responses.ts | 26 | ||||
| -rw-r--r-- | cloud/app/src/util/zen.ts | 51 |
4 files changed, 73 insertions, 38 deletions
diff --git a/cloud/app/src/routes/zen/v1/chat/completions.ts b/cloud/app/src/routes/zen/v1/chat/completions.ts index dc69bb514..13a75a4a4 100644 --- a/cloud/app/src/routes/zen/v1/chat/completions.ts +++ b/cloud/app/src/routes/zen/v1/chat/completions.ts @@ -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, }), }) } diff --git a/cloud/app/src/routes/zen/v1/messages.ts b/cloud/app/src/routes/zen/v1/messages.ts index ff399b034..b2e9e275a 100644 --- a/cloud/app/src/routes/zen/v1/messages.ts +++ b/cloud/app/src/routes/zen/v1/messages.ts @@ -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, }), }) } diff --git a/cloud/app/src/routes/zen/v1/responses.ts b/cloud/app/src/routes/zen/v1/responses.ts index 518a431ab..1bca91f52 100644 --- a/cloud/app/src/routes/zen/v1/responses.ts +++ b/cloud/app/src/routes/zen/v1/responses.ts @@ -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, } diff --git a/cloud/app/src/util/zen.ts b/cloud/app/src/util/zen.ts index 89c91c604..bff2df40e 100644 --- a/cloud/app/src/util/zen.ts +++ b/cloud/app/src/util/zen.ts @@ -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 |
