refactor(claude-to-openai): simplify usage token calculation and final chunk assembly
Made-with: Cursor
This commit is contained in:
@@ -111,24 +111,22 @@ export function claudeToOpenAIResponse(chunk, state) {
|
|||||||
const outputTokens = typeof chunk.usage.output_tokens === "number" ? chunk.usage.output_tokens : 0;
|
const outputTokens = typeof chunk.usage.output_tokens === "number" ? chunk.usage.output_tokens : 0;
|
||||||
const cacheReadTokens = typeof chunk.usage.cache_read_input_tokens === "number" ? chunk.usage.cache_read_input_tokens : 0;
|
const cacheReadTokens = typeof chunk.usage.cache_read_input_tokens === "number" ? chunk.usage.cache_read_input_tokens : 0;
|
||||||
const cacheCreationTokens = typeof chunk.usage.cache_creation_input_tokens === "number" ? chunk.usage.cache_creation_input_tokens : 0;
|
const cacheCreationTokens = typeof chunk.usage.cache_creation_input_tokens === "number" ? chunk.usage.cache_creation_input_tokens : 0;
|
||||||
|
|
||||||
// Use OpenAI format keys for consistent logging in stream.js
|
// prompt_tokens = input_tokens + cache_read + cache_creation (all prompt-side tokens)
|
||||||
|
const promptTokens = inputTokens + cacheReadTokens + cacheCreationTokens;
|
||||||
|
|
||||||
state.usage = {
|
state.usage = {
|
||||||
prompt_tokens: inputTokens,
|
prompt_tokens: promptTokens,
|
||||||
completion_tokens: outputTokens,
|
completion_tokens: outputTokens,
|
||||||
|
total_tokens: promptTokens + outputTokens,
|
||||||
input_tokens: inputTokens,
|
input_tokens: inputTokens,
|
||||||
output_tokens: outputTokens
|
output_tokens: outputTokens
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store cache tokens if present
|
if (cacheReadTokens > 0) state.usage.cache_read_input_tokens = cacheReadTokens;
|
||||||
if (cacheReadTokens > 0) {
|
if (cacheCreationTokens > 0) state.usage.cache_creation_input_tokens = cacheCreationTokens;
|
||||||
state.usage.cache_read_input_tokens = cacheReadTokens;
|
|
||||||
}
|
|
||||||
if (cacheCreationTokens > 0) {
|
|
||||||
state.usage.cache_creation_input_tokens = cacheCreationTokens;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk.delta?.stop_reason) {
|
if (chunk.delta?.stop_reason) {
|
||||||
state.finishReason = convertStopReason(chunk.delta.stop_reason);
|
state.finishReason = convertStopReason(chunk.delta.stop_reason);
|
||||||
const finalChunk = {
|
const finalChunk = {
|
||||||
@@ -136,45 +134,25 @@ export function claudeToOpenAIResponse(chunk, state) {
|
|||||||
object: "chat.completion.chunk",
|
object: "chat.completion.chunk",
|
||||||
created: Math.floor(Date.now() / 1000),
|
created: Math.floor(Date.now() / 1000),
|
||||||
model: state.model,
|
model: state.model,
|
||||||
choices: [{
|
choices: [{ index: 0, delta: {}, finish_reason: state.finishReason }]
|
||||||
index: 0,
|
|
||||||
delta: {},
|
|
||||||
finish_reason: state.finishReason
|
|
||||||
}]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Include usage in final chunk if available
|
if (state.usage) {
|
||||||
if (state.usage && typeof state.usage === "object") {
|
|
||||||
const inputTokens = state.usage.input_tokens || 0;
|
|
||||||
const outputTokens = state.usage.output_tokens || 0;
|
|
||||||
const cachedTokens = state.usage.cache_read_input_tokens || 0;
|
|
||||||
const cacheCreationTokens = state.usage.cache_creation_input_tokens || 0;
|
|
||||||
|
|
||||||
// prompt_tokens = input_tokens + cache_read + cache_creation (all prompt-side tokens)
|
|
||||||
// completion_tokens = output_tokens
|
|
||||||
// total_tokens = prompt_tokens + completion_tokens
|
|
||||||
const promptTokens = inputTokens + cachedTokens + cacheCreationTokens;
|
|
||||||
const completionTokens = outputTokens;
|
|
||||||
const totalTokens = promptTokens + completionTokens;
|
|
||||||
|
|
||||||
finalChunk.usage = {
|
finalChunk.usage = {
|
||||||
prompt_tokens: promptTokens,
|
prompt_tokens: state.usage.prompt_tokens,
|
||||||
completion_tokens: completionTokens,
|
completion_tokens: state.usage.completion_tokens,
|
||||||
total_tokens: totalTokens
|
total_tokens: state.usage.total_tokens
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add prompt_tokens_details if cached tokens exist
|
const cacheRead = state.usage.cache_read_input_tokens;
|
||||||
if (cachedTokens > 0 || cacheCreationTokens > 0) {
|
const cacheCreate = state.usage.cache_creation_input_tokens;
|
||||||
|
if (cacheRead > 0 || cacheCreate > 0) {
|
||||||
finalChunk.usage.prompt_tokens_details = {};
|
finalChunk.usage.prompt_tokens_details = {};
|
||||||
if (cachedTokens > 0) {
|
if (cacheRead > 0) finalChunk.usage.prompt_tokens_details.cached_tokens = cacheRead;
|
||||||
finalChunk.usage.prompt_tokens_details.cached_tokens = cachedTokens;
|
if (cacheCreate > 0) finalChunk.usage.prompt_tokens_details.cache_creation_tokens = cacheCreate;
|
||||||
}
|
|
||||||
if (cacheCreationTokens > 0) {
|
|
||||||
finalChunk.usage.prompt_tokens_details.cache_creation_tokens = cacheCreationTokens;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results.push(finalChunk);
|
results.push(finalChunk);
|
||||||
state.finishReasonSent = true;
|
state.finishReasonSent = true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user