mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
feat(usage): track cached tokens + correct input/output/cache cost (#2209)
Normalize every provider to one cache-inclusive convention via canonicalizeUsage() before persist, and price cached + cache_creation as subsets of prompt_tokens in calculateCostFromTokens() to stop double-counting. usageRepo now delegates cost math to a single source. Surface Cached tokens/cost across dashboard (overview, tokens, cost, details). Merge Claude message_start cache with message_delta output so cache counts survive. Compatible LLM nodes now allow multiple API-key connections (key pool). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
decolua
co-authored by
Cursor
parent
960f8a0379
commit
54e3245ace
@@ -391,6 +391,11 @@ export class KiroExecutor extends BaseExecutor {
|
||||
if (metrics && typeof metrics === 'object') {
|
||||
const inputTokens = metrics.inputTokens || 0;
|
||||
const outputTokens = metrics.outputTokens || 0;
|
||||
// ponytail: Amazon Q upstream does not expose cache fields today,
|
||||
// but pick up cache_read_input_tokens / cache_creation_input_tokens
|
||||
// if the event shape grows them so cost tracking stays accurate.
|
||||
const cachedTokens = metrics.cacheReadInputTokens || metrics.cache_read_input_tokens || 0;
|
||||
const cacheCreationInputTokens = metrics.cacheCreationInputTokens || metrics.cache_creation_input_tokens || 0;
|
||||
|
||||
if (inputTokens > 0 || outputTokens > 0) {
|
||||
state.usage = {
|
||||
@@ -398,6 +403,12 @@ export class KiroExecutor extends BaseExecutor {
|
||||
completion_tokens: outputTokens,
|
||||
total_tokens: inputTokens + outputTokens
|
||||
};
|
||||
// Kiro is Claude-backed: inputTokens EXCLUDES cache (Claude convention),
|
||||
// not inclusive like OpenAI's cached_tokens. Emit cache_read_input_tokens
|
||||
// (not cached_tokens) so canonicalizeUsage takes the Claude fold path and
|
||||
// correctly adds cache back into prompt_tokens instead of undercharging.
|
||||
if (cachedTokens > 0) state.usage.cache_read_input_tokens = cachedTokens;
|
||||
if (cacheCreationInputTokens > 0) state.usage.cache_creation_input_tokens = cacheCreationInputTokens;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user