hermes - 💡(How to fix) Fix Direct Gemini cost tracking is always $0.00 — resolve_billing_route() lacks gemini/google-gemini-cli branches + missing gemini-3.5-flash pricing entry [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Cost tracking (estimated_cost_usd) is always $0.00 for every session using provider: gemini or provider: google-gemini-cli (direct Google AI Studio / OAuth), regardless of which Gemini model is used. Token counts ARE recorded correctly (after #15253 / commit ba8337464), but the cost calculation pipeline never fires.

Root Cause

Root cause (two layers)

Fix Action

Fixed

Code Example

$ sqlite3 ~/.hermes/profiles/gemini35/state.db \
    "SELECT id, model, input_tokens, output_tokens, cache_read_tokens, \
     estimated_cost_usd, billing_provider, billing_mode, cost_status \
     FROM sessions WHERE input_tokens > 0 ORDER BY started_at DESC LIMIT 3" -header

id                       | model            | input | output | cache_read | cost | billing_provider | billing_mode | cost_status
20260525_204103_bef857   | gemini-3.5-flash | 22106 | 239    | 16266      | 0.0  | gemini           |              | unknown
20260525_204052_8ddbc3   | gemini-3.5-flash | 22121 | 234    | 16266      | 0.0  | gemini           |              | unknown

---

return BillingRoute(
    provider=provider_name or "unknown",   # → "gemini"
    model=...,
    billing_mode="unknown",                # → no pricing lookup will happen
)

---

entry = _OFFICIAL_DOCS_PRICING.get((route.provider, model))
RAW_BUFFERClick to expand / collapse

Summary

Cost tracking (estimated_cost_usd) is always $0.00 for every session using provider: gemini or provider: google-gemini-cli (direct Google AI Studio / OAuth), regardless of which Gemini model is used. Token counts ARE recorded correctly (after #15253 / commit ba8337464), but the cost calculation pipeline never fires.

Affected

  • Every direct-Gemini user, on every Gemini model (2.5-flash, 2.5-pro, 3.5-flash, etc.)
  • Not affected: users routing via OpenRouter (provider: openrouter + model: google/gemini-3.5-flash) — that path uses OpenRouter's models API for pricing and works correctly.

Evidence

Live session on Hermes v0.14.0, macOS, provider: gemini + model: gemini-3.5-flash:

$ sqlite3 ~/.hermes/profiles/gemini35/state.db \
    "SELECT id, model, input_tokens, output_tokens, cache_read_tokens, \
     estimated_cost_usd, billing_provider, billing_mode, cost_status \
     FROM sessions WHERE input_tokens > 0 ORDER BY started_at DESC LIMIT 3" -header

id                       | model            | input | output | cache_read | cost | billing_provider | billing_mode | cost_status
20260525_204103_bef857   | gemini-3.5-flash | 22106 | 239    | 16266      | 0.0  | gemini           |              | unknown
20260525_204052_8ddbc3   | gemini-3.5-flash | 22121 | 234    | 16266      | 0.0  | gemini           |              | unknown

Tokens land, billing_mode is empty, cost_status="unknown", estimated_cost_usd=0.0.

Root cause (two layers)

Layer 1: resolve_billing_route() has no gemini branch

agent/usage_pricing.py:527resolve_billing_route() has explicit branches for openai-codex, openrouter, anthropic, openai, minimax/minimax-cn, and custom/local. There is no branch for provider="gemini" or provider="google-gemini-cli". Both fall through to:

return BillingRoute(
    provider=provider_name or "unknown",   # → "gemini"
    model=...,
    billing_mode="unknown",                # → no pricing lookup will happen
)

billing_mode="unknown" means _lookup_official_docs_pricing() is never called for these routes.

Layer 2: pricing entries keyed under google, route resolved to gemini

Even if Layer 1 were fixed to call _lookup_official_docs_pricing(), the lookup at usage_pricing.py:576 is:

entry = _OFFICIAL_DOCS_PRICING.get((route.provider, model))

with no aliasing. The existing Gemini pricing entries are keyed under ("google", "gemini-2.5-flash") etc., but route.provider would be "gemini". The direct dict lookup misses.

Layer 3: no pricing entry for gemini-3.5-flash

Even with Layers 1 & 2 fixed, the _OFFICIAL_DOCS_PRICING table only has Gemini 2.5 entries. Any user on gemini-3.5-flash would still get $0 cost until pricing is added.

Reference: OpenRouter pricing for Google Gemini 3.x flash

For reference (from OpenRouter GET /api/v1/models):

ModelInput ($/M)Output ($/M)Cache read ($/M)
google/gemini-3.5-flash1.509.000.15
google/gemini-3-flash-preview0.503.000.05
google/gemini-3.1-flash-lite0.251.500.025
google/gemini-3.1-pro-preview2.0012.000.20

These pass through Google's published pricing — verify against https://ai.google.dev/pricing before merging.

Relationship to #15253

#15253 ("token counts always 0") is stale and closeable — commit ba8337464 already fixed token extraction. The remaining symptom (cost = 0) has a different root cause documented here.

Proposed fix

  1. Add gemini / google-gemini-cli branches to resolve_billing_route() that resolve to provider="google" and billing_mode="official_docs_snapshot".
  2. Add pricing entries for gemini-3.5-flash and gemini-3-flash-preview (and ideally Gemini 3.x pro/lite).
  3. End-to-end check: a gemini-3.5-flash session should record estimated_cost_usd > 0 and cost_status != "unknown".

Happy to send a PR.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING