Skip to content

pricingOverrides is silently ignored for the pi subcommand (works correctly for claude) #1810

Closed

Description

@mixxer

Bug description

pricingOverrides from a config file works correctly for the claude subcommand, but is silently ignored for the pi subcommand. Prices for pi-tracked custom/local-gateway models always compute as $0.00, even when the override contains an obviously-wrong extreme value.

Reproduction

  1. Have some usage data under ~/.pi/agent/sessions/**/*.jsonl for a model that isn't in the bundled LiteLLM pricing data (e.g. a custom OpenAI-compatible gateway model).
  2. Create a config file:
{
  "$schema": "https://ccusage.com/config-schema.json",
  "defaults": {
    "pricingOverrides": {
      "[pi] my-custom-model": {
        "inputCostPerToken": 999,
        "outputCostPerToken": 999
      }
    }
  }
}
  1. Run:
ccusage --config ./config.json pi monthly --json
  1. The cost field for [pi] my-custom-model in modelBreakdowns is still 0, even with an absurd override rate of 999.

Comparison — claude subcommand works as expected

Using the same override shape but targeting a model name from claude usage data (e.g. claude-sonnet-5) and running ccusage --config ./config.json claude monthly --json DOES apply the override — the cost for that model jumps to a correspondingly huge number. So pricingOverrides itself is implemented and works; it's specifically the pi subcommand's cost calculation path that never consults it.

What I tried (all failed to move the pi subcommand's cost off zero)

  • defaults.pricingOverrides (top-level, matches the documented example)
  • pi.defaults.pricingOverrides (namespaced under the pi agent)
  • pi.commands.monthly.pricingOverrides (command-scoped)
  • All of the above simultaneously, with both [pi] <model> and bare <model> as the key
  • Extreme values (999) to rule out a rounding/precision issue rather than a total no-op

Environment

  • ccusage version: 20.0.24 (latest at time of writing)
  • Installed via npm install -g ccusage
  • Tested on both Node v22.23.2 (macOS and Linux) — same result on both
  • Also confirmed that an intentionally malformed --config file (invalid JSON) produces no error and the command still runs — suggesting config loading may be silently swallowing failures, though I couldn't confirm whether that's the same root cause as the pi-specific issue above (the claude subcommand does successfully apply overrides from a well-formed file, so config loading isn't universally broken).

Expected behavior

pricingOverrides should apply to pi subcommand cost calculations the same way it does for claude, codex, etc.

Activity

  1. pullfrog commented on Sep 27, 2026

    @pullfrog
    Contributor
  2. added
    bugSomething isn't working
    priority:mediumA normal bug or meaningful improvement.
    triage:maintainableFits the repository's maintainable scope and needs review.
    on Sep 27, 2026
  3. added
    triage:needs-reviewRequires a fresh technical or product decision.
    and removed
    triage:maintainableFits the repository's maintainable scope and needs review.
    on Sep 27, 2026
  4. github-actions commented on Sep 27, 2026

    @github-actions
    Contributor

    Pullfrog triage: priority:medium
    Kind: bug
    Maintenance fit: needs review
    Confidence: medium

    Pullfrog was not highly confident; maintainer review is required. Docs promise pricingOverrides for pi models including [pi] prefixed keys, and pi code loads overrides, but the reporter shows zero cost with extreme override values while claude works. Root cause is unconfirmed between override lookup and auto mode preferring stored display cost, plus a separate silent config load observation, so human triage is needed.

    Decision: left open for maintainer review.

  5. ryoppippi commented on Sep 27, 2026

    @ryoppippi
    Member

    @pullfrog implement a pr

  6. pullfrog commented on Sep 27, 2026

    @pullfrog
    Contributor

    Fixed pricingOverrides being ignored for the pi subcommand in Auto mode.

    Root cause: the pi parser treated any stored cost.total display cost as authoritative in Auto mode, so a [pi] model override never recalculated the cost. Claude has no stored cost for custom models, which is why it worked there.

    Changes on branch pullfrog/1810-pi-pricing-overrides-auto:

    • Added PricingMap::has_user_override in rust/crates/ccusage-core/src/pricing.rs (exact plus alias-resolved lookup).
    • In rust/adapters/pi/src/parser.rs, Auto mode now drops the stored display cost (for both cost and missing-pricing paths, default and named stores) when either the [pi]/[store] display key or raw model has a user override, so override rates win. Display mode still shows stored cost, and non-overridden models are unchanged.
    • Added regression test auto_prefers_pricing_override_over_display_cost covering default/named stores, no-override passthrough, and Display passthrough.

    Validation: ccusage-adapter-pi 33 passed, ccusage-core 183 passed, ccusage-adapter-all 48 passed, ccusage binary tests 79+11+4+3+1 passed; cargo fmt --check and clippy -D warnings clean for touched crates.

    Could not open a PR: pullfrog_push_branch failed with remote: Permission to ccusage/ccusage.git denied to github-actions[bot]. fatal: unable to access 'https://github.com/ccusage/ccusage.git/': The requested URL returned error: 403. The commit is local on pullfrog/1810-pi-pricing-overrides-auto and the working tree is clean. A maintainer with push permission can push that branch and open the PR.

    Task list (5/5 completed)
    • Understand pi vs claude pricingOverrides handling
    • Create reproduction test (red)
    • Add PricingMap::has_user_override API
    • Use it in pi parser Auto path + missing pricing
    • Run relevant tests + clippy/fmt

    Pullfrog  | View workflow run | via Pullfrog | Using Muse Spark Contributor (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:mediumA normal bug or meaningful improvement.triage:needs-reviewRequires a fresh technical or product decision.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions