feat(tui): redesign Stats day insights and usage windows - #162
Conversation
…Z.ai Kimi Code's usages endpoint sends window.timeUnit as TIME_UNIT_MINUTE, which fell through the unit match into the seconds fallback and rendered as "300s limit". Z.ai hardcoded "Session" for its (unit 3, number 5) tokens limit. Both now derive the label from the window and show "5 Hour"; Z.ai also surfaces each limit's nextResetTime as reset times. Labels and shapes verified against the live endpoints.
WalkthroughChanges用量解析与 Stats 界面
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant App
participant UsageData
participant Stats
participant Radar
User->>App: open Stats tab
App->>UsageData: refresh or load graph data
UsageData-->>App: graph dates and daily usage
App->>Stats: select today's graph cell
Stats->>UsageData: read selected day's details
UsageData-->>Stats: models, harnesses, and hourly activity
Stats->>Radar: render model share axes
Radar-->>User: display Day Insights and radar chart
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c84e0cd8f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/tokscale-cli/src/tui/ui/stats.rs (1)
35-61: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift避免在默认终端尺寸下截断 Day Insights 核心内容。
80×24 终端扣除 header/footer 后仅剩 16 行;这里分配 11 行给图表、5 行给面板,边框后 Day Insights 仅能显示日期、分隔线和 Top Model。Top Harness、活动小时数及 24 小时条均被静默丢弃,且已无滚动入口。
请增加 80×24 的完整渲染回归测试,并为低高度提供紧凑布局或可滚动内容。基于 PR 目标中 Day Insights 必须包含 Top Model、Top Harness 和 24 小时活动条的说明。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/tokscale-cli/src/tui/ui/stats.rs` around lines 35 - 61, Update the stats layout around split_graph_height and render_day_insights so the default 80×24 terminal preserves Top Model, Top Harness, and the 24-hour activity bar instead of clipping them; use a compact layout or scrolling for low heights. Add a regression test covering the full 80×24 rendering and asserting these Day Insights elements remain available.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@crates/tokscale-cli/src/tui/ui/stats.rs`:
- Around line 35-61: Update the stats layout around split_graph_height and
render_day_insights so the default 80×24 terminal preserves Top Model, Top
Harness, and the 24-hour activity bar instead of clipping them; use a compact
layout or scrolling for low heights. Add a regression test covering the full
80×24 rendering and asserting these Day Insights elements remain available.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9ea22340-6e98-407a-823a-bacff0c9ecf3
📒 Files selected for processing (6)
crates/tokscale-cli/src/commands/usage/kimi.rscrates/tokscale-cli/src/commands/usage/zai.rscrates/tokscale-cli/src/tui/app.rscrates/tokscale-cli/src/tui/ui/mod.rscrates/tokscale-cli/src/tui/ui/radar.rscrates/tokscale-cli/src/tui/ui/stats.rs
… axis The chart height stayed at the full area height when the caption flanks bound the width, stretching the cross vertically and making the shape drift with model-name length. The chart is now height-capped to stay square in braille dots and vertically centered. The Others axis is hidden when no models fold into it.
…labels Kimi Code rows now render remaining as a percentage like the other providers. Unknown window units no longer fall through to a misleading seconds label, and non-positive Z.ai reset timestamps are treated as no reset instead of resetting in 1970.
Canonical ids aggregate usage across providers, so there is no provider color to look up and the name always fell back to gray. The top model is now colored by the family provider inferred from the model id itself (e.g. gpt-* -> openai, claude-* -> anthropic), keeping neutral gray for unrecognized ids.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/tokscale-cli/src/commands/usage/kimi.rs (1)
291-300: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value避免在缺少前缀时发生双重分配(Double Allocation)
当前实现中,
unwrap_or(&normalized).to_string()会将借用的&str转换并分配为一个全新的String。由于normalized本身已经是通过to_ascii_uppercase()分配的String,当字符串不包含TIME_UNIT_前缀时,这种写法会导致无意义的二次内存分配并丢弃原字符串。建议通过
if let绑定来复用已有的String分配:♻️ 建议的代码重构
let unit = time_unit.map(|unit| { let normalized = unit.trim().to_ascii_uppercase(); - normalized - .strip_prefix("TIME_UNIT_") - .unwrap_or(&normalized) - .to_string() + if let Some(stripped) = normalized.strip_prefix("TIME_UNIT_") { + stripped.to_string() + } else { + normalized + } });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/tokscale-cli/src/commands/usage/kimi.rs` around lines 291 - 300, Update the unit normalization closure in the time_unit mapping to reuse the existing normalized String when the TIME_UNIT_ prefix is absent, and only create a new String when stripping that prefix requires it. Replace the unwrap_or(...).to_string() flow while preserving the current uppercase normalization and resulting unit values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@crates/tokscale-cli/src/commands/usage/kimi.rs`:
- Around line 291-300: Update the unit normalization closure in the time_unit
mapping to reuse the existing normalized String when the TIME_UNIT_ prefix is
absent, and only create a new String when stripping that prefix requires it.
Replace the unwrap_or(...).to_string() flow while preserving the current
uppercase normalization and resulting unit values.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: e7bc8e3f-e53a-4527-8311-d9594cf54ba6
📒 Files selected for processing (5)
crates/tokscale-cli/src/commands/usage/kimi.rscrates/tokscale-cli/src/commands/usage/zai.rscrates/tokscale-cli/src/tui/app.rscrates/tokscale-cli/src/tui/ui/radar.rscrates/tokscale-cli/src/tui/ui/stats.rs
🚧 Files skipped from review as they are similar to previous changes (4)
- crates/tokscale-cli/src/tui/ui/radar.rs
- crates/tokscale-cli/src/commands/usage/zai.rs
- crates/tokscale-cli/src/tui/app.rs
- crates/tokscale-cli/src/tui/ui/stats.rs
Summary
5 HourEscdeselection and remapping selections by date after graph rebuildsWhy
The Usage tab rendered equivalent five-hour windows with inconsistent labels, and the old Stats breakdown made day-level comparisons cumbersome. This adapts the selected Kimi branch UI changes to the fork's current Stats architecture without restoring the removed Stats Summary panel.
Design decisions
DailyModelInfo.color_key, aggregating across provider, source, and workspace projections.No detailed usage breakdown is available for this day.without inventing a ranking or radar.Validation
cargo fmt --all -- --checkcargo clippy --locked -p tokscale-cli --all-features -- -D warningscargo test -p tokscale-cli --bin tokscale— 666 passed, 1 ignoredbun run build:coreSummary by CodeRabbit