Repository navigation
fix(hermes): price subscription-included sessions - #1113
Conversation
calculate_hermes_cost short-circuits on any Some(cost) read from state.db, so sessions where Hermes wrote estimated_cost_usd = 0.0 (subscription_included billing, e.g. ChatGPT Plus/Pro via the codex backend) report $0 even when token usage is non-zero. Only short-circuit on strictly positive recorded cost; fall through to pricing-based calculation otherwise, matching how the codex adapter handles the same models. Closes ccusage#1112
|
This PR was auto-closed. Only contributors approved with Maintainers review auto-closed issues and reopen worthwhile ones. Issues that do not meet the quality bar in CONTRIBUTING.md may not be reopened or receive a reply. If a maintainer replies See CONTRIBUTING.md. |
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughThe adapter fixes a bug where Hermes-recorded zero costs (used for subscription-based billing) were returned without fallback to pricing calculation. The code now filters recorded costs to accept only strictly positive values, rejects zero, and falls back to pricing-token calculation when needed. Pricing-derived costs now require strictly positive finite values. ChangesHermes Cost Fallback Logic
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
✨ Finishing Touches🧪 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 |
|
@coderabbitai review it |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 26906
Review SummaryOverall: ✅ Looks good — the fix is correct, minimal, and well-motivated. Core logic change// Before — short-circuits on any recorded cost, including 0.0
if let Some(cost) = entry.cost_usd {
return cost;
}
// After — only short-circuits on a strictly positive recorded cost
if let Some(cost) = entry.cost_usd.filter(|cost| *cost > 0.0) {
return cost;
}The one-liner
The secondary cleanup removing the dead TestsBoth new tests cover the right invariants:
Minor nit — float equality in assert_eq!(calculate_hermes_cost(&entry, &pricing), 0.42);This works correctly here because the value is stored and returned with no arithmetic, so the bits are preserved exactly. It's not wrong, but if this pattern is extended to cases where arithmetic is applied, it could silently break. A small defensive alternative for future readers: let cost = calculate_hermes_cost(&entry, &pricing);
assert!((cost - 0.42).abs() < f64::EPSILON, "expected ~0.42, got {cost}");Not a blocker — just worth keeping in mind if the test is ever expanded. Coverage gap (non-blocking)There's no explicit test for The fix is correct and the PR is in good shape. 🐇 |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 56837
Review of
|
| Fix correctness | ✅ |
Edge cases (NaN, negative, None) |
✅ handled upstream |
| Redundant check removed | ✅ |
| Tests coverage | ✅ both branches covered |
Pre-existing data.cost_usd inconsistency |
The PR is good to merge. The data.cost_usd inconsistency is a separate concern worth a follow-up issue if it affects any output path.
|
@cubic-dev-ai review this |
@ryoppippi I have started the AI code review. It will take a few minutes to complete. |
|
Historical audit: this pull request was auto-closed by the legacy contributor gate. That closure did not assess technical importance. Audit result: resolved. A later merged change or the current |
Summary
calculate_hermes_costinrust/crates/ccusage/src/adapter/hermes.rsshort-circuits on anySome(cost)read from Hermes'state.db, so sessions where Hermes wroteestimated_cost_usd = 0.0(subscription-included billing, e.g. ChatGPT Plus/Pro via the codex backend) report$0even when token usage is non-zero. The codex adapter doesn't have this short-circuit and prices the samegpt-5.5model correctly, so on the same machineccusage codex dailyshows a real cost whileccusage hermes dailyshows$0.00.This change only short-circuits on a strictly positive recorded cost and falls through to pricing-based calculation otherwise, matching how the codex adapter handles the same models. A recorded positive cost is still trusted as-is.
Closes #1112.
Changes
rust/crates/ccusage/src/adapter/hermes.rscalculate_hermes_cost: only return early whenentry.cost_usd > 0.0; otherwise fall through to the existing pricing-based candidate loop.cost >= 0.0check inside the candidate loop (the subsequentcost > 0.0already implies it).recorded_zero_cost_falls_back_to_pricing_calculation— reproduces the bug with real-world numbers (gpt-5.5,Some(0.0), non-zero tokens) and asserts cost > 0.recorded_positive_cost_is_trusted— guards against accidentally pricing sessions where Hermes already recorded a real cost.Test plan
cargo test— 219/219 pass, including the two new testsrustfmt --checkcleanSummary by cubic
Fixes Hermes cost calculation so subscription-included sessions with a recorded
0.0cost are priced from token usage. Only trust a recorded cost when it’s strictly positive, matching thecodexadapter.calculate_hermes_cost, early-return only whencost_usd > 0.0; otherwise compute via pricing.cost >= 0.0check.0.0costs and trusting positive recorded costs.Written for commit 2432620. Summary will update on new commits. Review in cubic
Summary by CodeRabbit
Bug Fixes