'use strict'; function buildUsage(prompt, thinking, output, outputTokens = 0, providedPromptTokens = 0) { const reasoningTokens = estimateTokens(thinking); const completionTokens = estimateTokens(output); const finalPromptTokens = Number.isFinite(providedPromptTokens) && providedPromptTokens > 0 ? Math.trunc(providedPromptTokens) : estimateTokens(prompt); const overriddenCompletionTokens = Number.isFinite(outputTokens) && outputTokens > 0 ? Math.trunc(outputTokens) : 0; const finalCompletionTokens = overriddenCompletionTokens > 0 ? overriddenCompletionTokens : reasoningTokens + completionTokens; return { prompt_tokens: finalPromptTokens, completion_tokens: finalCompletionTokens, total_tokens: finalPromptTokens + finalCompletionTokens, completion_tokens_details: { reasoning_tokens: reasoningTokens, }, }; } function estimateTokens(text) { const t = asTokenString(text); if (!t) { return 0; } let asciiChars = 0; let nonASCIIChars = 0; for (const ch of Array.from(t)) { if (ch.charCodeAt(0) < 128) { asciiChars += 1; } else { nonASCIIChars += 1; } } const n = Math.floor(asciiChars / 4) + Math.floor((nonASCIIChars * 10 + 7) / 13); return n < 1 ? 1 : n; } function asTokenString(v) { if (typeof v === 'string') { return v; } if (Array.isArray(v)) { return asTokenString(v[0]); } if (v == null) { return ''; } return String(v); } module.exports = { buildUsage, estimateTokens, };