feat(stats): add model cost estimation to /stats model (#3780)#219
Conversation
Cherry-picks upstream qwen-code PR QwenLM#3780. Skips the source-attribution features (`bySource`, `flattenModelsBySource`, MAIN_SOURCE) that came along for the ride — those depend on a separate un-ported subagent attribution PR. What's in: - `costCalculator` util — pure function, takes input/output tokens + per-model `ModelPricing` ({inputPerMillionTokens, outputPerMillionTokens}), returns null when pricing is absent or total cost is zero. - `ui.modelPricing` setting — a `Record<string, ModelPricing>` keyed by model name. When set, the `/stats model` TUI shows a Cost section, and `/stats model` in non-interactive mode appends "Estimated cost" per model. - `ModelStatsDisplay` adds a Cost section after Tokens, gated on at least one model having computable cost (`hasPricing`). - `statsCommand` model subcommand: in non-interactive/ACP modes, returns a text message including per-model Estimated cost lines. Conflict-resolution notes: - Dropped `supportedModes` field — un-ported metadata, single consumer, no enforcement in our slash system. - Dropped upstream's expanded non-interactive output for top-level /stats and /stats tools (depends on `metrics.files.totalLinesAdded` which our SessionMetrics doesn't have). Kept just the model-cost path, which is the headline feature. - Rewrote `ModelStatsDisplay` cost row from scratch against our HEAD shape (no `bySource`, no `key.split('::')`) instead of taking upstream's full re-render. - Gate non-interactive path on explicit `=== 'non_interactive' || === 'acp'` rather than `!== 'interactive'`, so undefined defaults to interactive and existing tests keep working. - vscode-ide-companion settings.schema.json: deleted in our fork, removed from cherry-pick. Tests: 32 new tests pass (costCalculator, statsCommand model cost in non-interactive, ModelStatsDisplay cost row). Broader sweep of 1186 tests across packages/cli/src/ui/{commands,components} all pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (7)
✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 0/5 reviews remaining, refill in 5 minutes and 44 seconds. Comment |
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
Summary
/stats model(TUI cost row + non-interactive Estimated cost lines)bySource/flattenModelsBySource/MAIN_SOURCE) — those depend on a separate un-ported subagent attribution PRmetrics.files.totalLinesAddedwhich our SessionMetrics doesn't haveWhat's in
costCalculatorutil — pure function, takes input/output tokens +ModelPricing({inputPerMillionTokens, outputPerMillionTokens}); returns null when pricing absent or total cost is zeroui.modelPricingsetting —Record<string, ModelPricing>keyed by model name. When set, the TUI shows a Cost section and the non-interactive/stats modelappends Estimated cost per modelModelStatsDisplayadds a Cost section after Tokens, gated onhasPricingstatsCommandmodel subcommand non-interactive/ACP path returns text with per-model Estimated cost linesConflict-resolution notes
supportedModesfield — un-ported metadata, no enforcement in our slash systemModelStatsDisplaycost row from scratch against our HEAD shape (nobySource, nokey.split('::')) instead of taking upstream's full re-render=== 'non_interactive' || === 'acp'rather than!== 'interactive', so undefined defaults to interactive (existing tests still pass)Configuration
Add to settings.json:
```json
{
"ui": {
"modelPricing": {
"qwen3-coder-plus": {
"inputPerMillionTokens": 0.30,
"outputPerMillionTokens": 1.20
}
}
}
}
```
Test plan
🤖 Generated with Claude Code