Repository navigation
feat(cli): weight cache reads in the limits usage bar - #56
Merged
Merged
Conversation
UsageWindowSummary now carries a CostBreakdown (input, output, cache read, cache write) and EstimatedCost is its total, so the cost has one source of truth. CostCalculator.EstimateCostBreakdown prices each kind separately and EstimateCost is defined as its total; the breakdown is not serialized with a derived Total. This lets callers weigh the kinds of token differently, which the limits view needs because the subscription quota is not metered at API list prices.
The usage-progress bar of `watch --view limits` ran ahead of the percentage Claude shows, because it was measured in API list-price cost and cache reads make up most of that cost in a long session while the subscription quota does not weigh them that way. - Measure the bar in a quota-weighted cost: the cache-read part is scaled by --cache-read-weight (default 0.1, a heuristic). --reset-cache-read-weight forgets a saved weight. - Save the reading each limit is derived from (the percentage read off Claude plus the cost counted at that moment) instead of the derived limit, so the weight can be tuned without reading /usage again. Limits saved by an older version cannot be carried over and are reported once. - Ignore a percentage given while nothing is counted for the window instead of replacing a working calibration, and reject NaN, infinite and out-of-range percentages. - Show what the bar is made of below the table, and show startup and recalibration notices in the view, because anything printed is cleared with the screen. - Move the startup decisions into LimitsStartup so they can be tested without a terminal.
Document the cache read weight and its reset flag in the README (English and Chinese), and record in CLAUDE.md where the limits startup decisions live and that messages for the user must go through the notices list instead of being printed, since the screen is cleared right after startup.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The usage-progress bar of
aimon watch --view limitsran ahead of the percentage Claude shows (seen with Sonnet 5.5 at high effort).The bar was
list-price cost / limit, where the limit was derived once from a/usagepercentage. Cache reads dominate a long agentic session: in the author's transcripts they were about 98% of all tokens and about 65% of the list-price cost. The subscription quota is not metered at API list prices, so counting cache reads in full made the bar run fast. Deduplication, thinking tokens and the window placement were checked and are not the cause.Changes
UsageWindowSummarycarries aCostBreakdown(input / output / cache read / cache write);EstimatedCostis now its total, so the cost has a single source.CostCalculator.EstimateCostBreakdownprices each kind separately.Totalis not serialized.--cache-read-weight(default0.1).--reset-cache-read-weightforgets a saved weight; the two options cannot be combined (rejected at parse time).UsageCalibration), and the limit is derived from it under the weight in effect. Tuning the weight therefore does not need/usageto be read again.rnotices are drawn in the view throughSpectreRenderer.WithNotices, because anything printed is cleared with the screen.LimitsStartup, which takesinputRedirectedand never reads the terminal state itself.Behaviour change to be aware of
Settings written by the previous version store a derived limit, which cannot be re-derived under another cache read weight. It is ignored on load, reported once when it leaves a window without a calibration and input is redirected, and cleared on the next save. In an interactive terminal the percentages are prompted for once.
Caveat
The default weight of
0.1is a heuristic, not a measured or published figure; I could not compare against Claude's real percentage. The help text, README andCLAUDE.mdsay so. Tune it with--cache-read-weightagainst/usage.Not done
PromptAndSaveBoth,PromptForCalibration): they use the console and the real settings file.claude-sonnet-5-5still resolves to thesonnet-5entry.Test plan
dotnet build AIUsageMonitor.slnx(0 warnings, 0 errors)dotnet test AIUsageMonitor.slnx(475 passed)aimon watch --view limits, pressr, enter the/usagepercentage, and compare the bar with/usageafter a while; adjust--cache-read-weightif needed