Q65: every call path records real tokens, cache, reasoning and cost

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-10-08 11:24:54 -04:00
1 parent 1367a8900e
commit c2f8e656f6
15 files changed
+187 -37

No files matched your search

+9 -1
View File
@@ -3,7 +3,8 @@ import type { JsonRecord, ProviderEventStreamMessage } from "./provider-http";
import { isRecord } from "./provider-http";
export interface ProviderStreamEvent {
type: "message_start" | "text_delta" | "message_stop" | "error";
/** usage: a chunk that only reports token usage; it is recorded, never shown. */
type: "message_start" | "text_delta" | "message_stop" | "error" | "usage";
textDelta: string | null;
providerResponseId: string | null;
rawEventJson: string;
@@ -71,6 +72,8 @@ export async function* mapOpenAiChatCompletionStream(messages: AsyncIterable<Pro
yield streamEvent("message_start", null, message);
}
yield streamEvent("message_stop", null, message);
} else if (!delta && isRecord(message.data.usage)) {
yield streamEvent("usage", null, message);
}
}
}
@@ -84,6 +87,11 @@ export async function* mapAnthropicMessageStream(messages: AsyncIterable<Provide
yield streamEvent("message_start", null, message);
continue;
}
// Anthropic reports output tokens on message_delta, input tokens on message_start.
if (type === "message_delta") {
yield streamEvent("usage", null, message);
continue;
}
if (type === "content_block_delta") {
const delta = readAnthropicTextDelta(message.data);
if (delta) {