mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-30 08:15:31 +08:00
fix: refine token usage reporting
The old token UI mixed context pressure, cache counters, and dollar estimates. That made the percentage look precise even when provider data was incomplete or different. The composer and /cost view now show concrete counts instead of a pie percentage. Token payloads now share a smaller shape: used, inputTokens, outputTokens, and breakdown. Claude uses per-step usage where available and Codex reads total_token_usage events. Gemini reads its tokens object without inventing a context window. OpenCode reads opencode.db session totals and includes all token columns in used. The /cost backend no longer returns cache display fields or input/output dollar estimates. This avoids derived values that look reliable but are not comparable across providers. Verification: npm run typecheck; targeted eslint; OpenCode session provider test.
This commit is contained in:
@@ -174,7 +174,7 @@ const builtInCommands = [
|
||||
},
|
||||
{
|
||||
name: "/cost",
|
||||
description: "Display token usage and cost information",
|
||||
description: "Display token usage information",
|
||||
namespace: "builtin",
|
||||
metadata: { type: "builtin" },
|
||||
},
|
||||
@@ -258,7 +258,7 @@ Custom commands can be created in:
|
||||
const catalog = (await providerModelsService.getProviderModels(provider)).models;
|
||||
const model = await resolveCommandModel(provider, catalog, context?.sessionId);
|
||||
|
||||
const used =
|
||||
const reportedUsed =
|
||||
Number(
|
||||
tokenUsage.used ?? tokenUsage.totalUsed ?? tokenUsage.total_tokens ?? 0,
|
||||
) || 0;
|
||||
@@ -266,16 +266,15 @@ Custom commands can be created in:
|
||||
Number(
|
||||
tokenUsage.total ??
|
||||
tokenUsage.contextWindow ??
|
||||
parseInt(process.env.CONTEXT_WINDOW || "160000", 10),
|
||||
) || 160000;
|
||||
const percentage =
|
||||
total > 0 ? Number(((used / total) * 100).toFixed(1)) : 0;
|
||||
|
||||
0,
|
||||
) || 0;
|
||||
const inputTokensRaw =
|
||||
Number(
|
||||
tokenUsage.inputTokens ??
|
||||
tokenUsage.input ??
|
||||
tokenUsage.input_tokens ??
|
||||
tokenUsage.cumulativeInputTokens ??
|
||||
tokenUsage.breakdown?.input ??
|
||||
tokenUsage.promptTokens ??
|
||||
0,
|
||||
) || 0;
|
||||
@@ -283,37 +282,21 @@ Custom commands can be created in:
|
||||
Number(
|
||||
tokenUsage.outputTokens ??
|
||||
tokenUsage.output ??
|
||||
tokenUsage.output_tokens ??
|
||||
tokenUsage.cumulativeOutputTokens ??
|
||||
tokenUsage.breakdown?.output ??
|
||||
tokenUsage.completionTokens ??
|
||||
0,
|
||||
) || 0;
|
||||
const cacheTokens =
|
||||
Number(
|
||||
tokenUsage.cacheReadTokens ??
|
||||
tokenUsage.cacheCreationTokens ??
|
||||
tokenUsage.cacheTokens ??
|
||||
tokenUsage.cachedTokens ??
|
||||
0,
|
||||
) || 0;
|
||||
const hasTokenBreakdown = inputTokensRaw > 0 || outputTokens > 0;
|
||||
const used = reportedUsed || inputTokensRaw + outputTokens;
|
||||
|
||||
// If we only have total used tokens, treat them as input for display/estimation.
|
||||
// If we only have total used tokens, keep the list populated without guessing output.
|
||||
const inputTokens =
|
||||
inputTokensRaw > 0 || outputTokens > 0 || cacheTokens > 0
|
||||
? inputTokensRaw + cacheTokens
|
||||
hasTokenBreakdown
|
||||
? inputTokensRaw
|
||||
: used;
|
||||
|
||||
// Rough default rates by provider (USD / 1M tokens).
|
||||
const pricingByProvider = {
|
||||
claude: { input: 3, output: 15 },
|
||||
cursor: { input: 3, output: 15 },
|
||||
codex: { input: 1.5, output: 6 },
|
||||
};
|
||||
const rates = pricingByProvider[provider] || pricingByProvider.claude;
|
||||
|
||||
const inputCost = (inputTokens / 1_000_000) * rates.input;
|
||||
const outputCost = (outputTokens / 1_000_000) * rates.output;
|
||||
const totalCost = inputCost + outputCost;
|
||||
|
||||
return {
|
||||
type: "builtin",
|
||||
action: "cost",
|
||||
@@ -321,17 +304,10 @@ Custom commands can be created in:
|
||||
tokenUsage: {
|
||||
used,
|
||||
total,
|
||||
percentage,
|
||||
},
|
||||
tokenBreakdown: {
|
||||
input: inputTokens,
|
||||
output: outputTokens,
|
||||
cache: cacheTokens,
|
||||
},
|
||||
cost: {
|
||||
input: inputCost.toFixed(4),
|
||||
output: outputCost.toFixed(4),
|
||||
total: totalCost.toFixed(4),
|
||||
},
|
||||
provider,
|
||||
model,
|
||||
|
||||
Reference in New Issue
Block a user