fix(types): normalize stream usage before cost calculation (#9977)

This commit is contained in:
backryun
2026-08-10 12:28:37 +09:00
committed by GitHub
parent 4cd9c8e39c
commit 160fd55a6d
2 changed files with 17 additions and 2 deletions

View File

@@ -8,6 +8,7 @@ import {
logUsage,
addBufferToUsage,
filterUsageForFormat,
normalizeUsage as normalizeTokenUsage,
} from "./usageTracking.ts";
import {
parseSSELine,
@@ -1012,7 +1013,9 @@ export function createSSEStream(options: StreamOptions = {}) {
// JSON.parse every SSE line will crash on `: x-omniroute-*` comment lines.
if (!sseCommentsEnabled()) return;
const costUsd = finalUsage ? await calculateCost(provider, model, finalUsage) : 0;
const costUsd = finalUsage
? await calculateCost(provider, model, normalizeTokenUsage(finalUsage))
: 0;
const comment = buildOmniRouteSseMetadataComment({
provider,
model,

View File

@@ -2,7 +2,19 @@ import test from "node:test";
import assert from "node:assert/strict";
const { extractUsageFromResponse } = await import("../../open-sse/handlers/usageExtractor.ts");
const { extractUsage } = await import("../../open-sse/utils/usageTracking.ts");
const { extractUsage, normalizeUsage } = await import("../../open-sse/utils/usageTracking.ts");
test("normalizeUsage keeps only finite numeric fields for stream cost calculation", () => {
assert.deepEqual(
normalizeUsage({
input_tokens: "12",
output_tokens: 3,
total_tokens: Number.POSITIVE_INFINITY,
input_tokens_details: { cached_tokens: 2 },
}),
{ input_tokens: 12, output_tokens: 3 }
);
});
test("extractUsageFromResponse reads OpenAI chat completion usage", () => {
const usage = extractUsageFromResponse(