fix(usage): cost display honesty — sub-cent labels, cost buckets, included notes

Three cost-display honesty fixes:

1. Sub-cent cost label rendering (#79220) — _format_cost_label() scales
   precision to magnitude: zero renders as '$0.00', sub-cent (< $0.01)
   renders at 4 decimal places (e.g. '~$0.0046'), normal costs keep 2dp.
   This fixes the bug where DeepSeek per-turn costs of $0.004640 rendered
   as '~$0.00' despite amount_usd carrying full Decimal precision.

2. Cost bucket surfacing (#77223) — insights format_terminal and
   format_gateway now display three cost buckets: estimated (with dollar
   figure), included (session count, labeled 'subscription — no provider
   invoice'), and unknown (session count, labeled 'no pricing data').
   Previously, included and unknown sessions silently collapsed to $0 in
   the aggregate view, hiding 315 of 473 sessions in the reporter's DB.

3. Subscription-included cost notes — estimate_usage_cost now attaches a
   'subscription-included; no provider invoice for usage' note to
   CostResult for subscription-included routes (openai-codex), so
   consumers can distinguish 'free because subscription' from 'free
   because $0 pricing'.

Fixes #79220
Fixes #77223
This commit is contained in:
kshitij
2026-08-14 00:40:54 +05:30
parent 67ab2f2968
commit ccaaca7e66
4 changed files with 219 additions and 4 deletions
+38
View File
@@ -1000,6 +1000,29 @@ class InsightsEngine:
lines.append(f" Avg msgs/session: {o['avg_messages_per_session']:.1f}")
lines.append("")
# Cost breakdown — surface the three buckets so subscription-included
# and unknown-cost sessions are visible instead of silently collapsing
# to $0. See #77223.
est_cost = o.get("estimated_cost", 0.0)
included_sessions = o.get("included_cost_sessions", 0)
unknown_sessions = o.get("unknown_cost_sessions", 0)
if est_cost > 0 or included_sessions > 0 or unknown_sessions > 0:
lines.append(" 💰 Cost")
lines.append(" " + "─" * 56)
if est_cost > 0:
lines.append(f" Estimated: ~${est_cost:.2f}")
if included_sessions > 0:
lines.append(
f" Included: {included_sessions} session(s) "
f"(subscription — no provider invoice)"
)
if unknown_sessions > 0:
lines.append(
f" Unknown: {unknown_sessions} session(s) "
f"(no pricing data)"
)
lines.append("")
# Model breakdown
if report["models"]:
lines.append(" 🤖 Models Used")
@@ -1114,6 +1137,21 @@ class InsightsEngine:
lines.append(f"**Active time:** ~{format_duration_compact(o['total_hours'] * 3600)} | **Avg session:** ~{format_duration_compact(o['avg_session_duration'])}")
lines.append("")
# Cost breakdown — surface buckets so included/unknown are visible
est_cost = o.get("estimated_cost", 0.0)
included = o.get("included_cost_sessions", 0)
unknown = o.get("unknown_cost_sessions", 0)
cost_parts: list[str] = []
if est_cost > 0:
cost_parts.append(f"~${est_cost:.2f} estimated")
if included > 0:
cost_parts.append(f"{included} included (subscription)")
if unknown > 0:
cost_parts.append(f"{unknown} unknown")
if cost_parts:
lines.append(f"**Cost:** {' | '.join(cost_parts)}")
lines.append("")
# Models (top 5)
if report["models"]:
lines.append("**🤖 Models:**")
+25 -1
View File
@@ -18,6 +18,29 @@ _ZERO = Decimal("0")
_ONE_MILLION = Decimal("1000000")
_NOUS_DEFAULT_BASE_URL = "https://inference-api.nousresearch.com/v1"
# Sub-cent cost threshold: below $0.01, render at 4 decimal places so
# the display is non-zero (e.g. $0.0046 instead of $0.00). See #79220.
_SUBCENT_THRESHOLD = Decimal("0.01")
def _format_cost_label(amount: Decimal) -> str:
"""Format a cost amount as a display label.
Scales precision to magnitude:
- Zero → "$0.00"
- Sub-cent (< $0.01) → "~$0.0046" (4 dp, always non-zero)
- Normal → "~$1.23" (2 dp)
This fixes #79220 where sub-cent per-turn costs on cheap models
(DeepSeek, etc.) rendered as "$0.00" despite amount_usd carrying
full Decimal precision.
"""
if amount == _ZERO:
return "$0.00"
if amount < _SUBCENT_THRESHOLD:
return f"~${amount:.4f}"
return f"~${amount:.2f}"
CostStatus = Literal["actual", "estimated", "included", "unknown"]
CostSource = Literal[
"provider_cost_api",
@@ -1334,6 +1357,7 @@ def estimate_usage_cost(
source="none",
label="included",
pricing_version="included-route",
notes=("subscription-included; no provider invoice for usage",),
)
entry = get_pricing_entry(model_name, provider=provider, base_url=base_url, api_key=api_key)
@@ -1378,7 +1402,7 @@ def estimate_usage_cost(
amount += Decimal(usage.request_count) * entry.request_cost
status: CostStatus = "estimated"
label = f"~${amount:.2f}"
label = _format_cost_label(amount)
if entry.source == "none" and amount == _ZERO:
status = "included"
label = "included"
+80 -3
View File
@@ -557,7 +557,9 @@ class TestTerminalFormatting:
assert "N/A" not in text
assert "custom/self-hosted" not in text
assert "Cost" not in text
# Cost section now surfaces unknown-cost sessions (#77223) instead
# of hiding them — a custom model with no pricing data should show
# "Unknown: 1 session(s)" rather than silently reporting $0.
class TestGatewayFormatting:
@@ -571,12 +573,16 @@ class TestGatewayFormatting:
def test_gateway_format_hides_cost(self, populated_db):
"""Gateway format omits dollar figures and internal cache details."""
"""Gateway format omits internal cache details.
Dollar figures now appear when there are estimated/included/unknown
cost buckets (#77223) — the old assertion that '$' is absent is no
longer correct because surfacing cost buckets is the fix.
"""
engine = InsightsEngine(populated_db)
report = engine.generate(days=30)
text = engine.format_gateway(report)
assert "$" not in text
assert "cache" not in text.lower()
@@ -670,3 +676,74 @@ class TestEdgeCases:
# Actually the condition is > 1 platforms OR non-cli, so single cli won't show
def test_cost_buckets_displayed_in_terminal_format(self, db):
"""#77223: included/estimated/unknown cost buckets surface in terminal."""
# Estimated cost session
db.create_session(session_id="est", source="cli", model="model-a")
db.update_token_counts(
"est", input_tokens=100, model="model-a",
billing_provider="custom",
estimated_cost_usd=1.50, actual_cost_usd=1.0,
cost_status="estimated", cost_source="provider", api_call_count=1,
)
# Included cost session (subscription)
db.create_session(session_id="inc", source="cli", model="gpt-5.4-mini")
db.update_token_counts(
"inc", input_tokens=200, model="gpt-5.4-mini",
billing_provider="openai-codex",
estimated_cost_usd=0.0, actual_cost_usd=0.0,
cost_status="included", cost_source="none", api_call_count=1,
)
engine = InsightsEngine(db)
report = engine.generate(days=30)
text = engine.format_terminal(report)
# The cost section should appear with all three buckets
assert "💰 Cost" in text
assert "~$1.50" in text # estimated
assert "included" in text.lower()
assert "subscription" in text.lower()
def test_cost_buckets_displayed_in_gateway_format(self, db):
"""#77223: included/estimated/unknown cost buckets surface in gateway."""
db.create_session(session_id="est", source="cli", model="model-a")
db.update_token_counts(
"est", input_tokens=100, model="model-a",
billing_provider="custom",
estimated_cost_usd=2.25, actual_cost_usd=0.0,
cost_status="estimated", cost_source="provider", api_call_count=1,
)
db.create_session(session_id="inc", source="cli", model="gpt-5.4-mini")
db.update_token_counts(
"inc", input_tokens=200, model="gpt-5.4-mini",
billing_provider="openai-codex",
estimated_cost_usd=0.0, actual_cost_usd=0.0,
cost_status="included", cost_source="none", api_call_count=1,
)
engine = InsightsEngine(db)
report = engine.generate(days=30)
text = engine.format_gateway(report)
assert "**Cost:**" in text
assert "~$2.25" in text
assert "included" in text.lower()
def test_no_cost_section_when_all_zero(self, db):
"""A session with no model still shows unknown cost bucket (#77223).
The unknown bucket is surfaced so users can see they have sessions
with no pricing data, rather than silently reporting $0.
"""
db.create_session(session_id="s1", source="cli", model="test")
db._conn.commit()
engine = InsightsEngine(db)
report = engine.generate(days=30)
text = engine.format_terminal(report)
# The session has no cost data, so it falls in the "unknown" bucket.
assert "💰 Cost" in text
assert "Unknown" in text
+76
View File
@@ -2,11 +2,13 @@ from types import SimpleNamespace
from agent.usage_pricing import (
CanonicalUsage,
_format_cost_label,
estimate_usage_cost,
get_pricing_entry,
normalize_usage,
resolve_billing_route,
)
from decimal import Decimal
@@ -370,3 +372,77 @@ def test_normalize_usage_native_anthropic_no_cache_observability(caplog):
assert result.input_tokens == 100
assert result.cache_read_tokens == 50
assert result.cache_write_tokens == 10
# ---------------------------------------------------------------------------
# Cost label formatting (#79220: sub-cent costs render as $0.00)
# ---------------------------------------------------------------------------
class TestFormatCostLabel:
"""Tests for magnitude-scaled cost label formatting."""
def test_zero_renders_as_dollar_zero(self):
assert _format_cost_label(Decimal("0")) == "$0.00"
def test_sub_cent_renders_4dp(self):
"""Costs below $0.01 render at 4 decimal places (#79220)."""
label = _format_cost_label(Decimal("0.004640"))
assert label == "~$0.0046"
# Must NOT be $0.00
assert "$0.00" != label
def test_exactly_one_cent_renders_2dp(self):
"""$0.01 renders at 2dp."""
assert _format_cost_label(Decimal("0.01")) == "~$0.01"
def test_normal_cost_renders_2dp(self):
assert _format_cost_label(Decimal("1.23")) == "~$1.23"
def test_large_cost_renders_2dp(self):
assert _format_cost_label(Decimal("42.50")) == "~$42.50"
def test_very_small_sub_cent(self):
"""Even very small costs render non-zero."""
label = _format_cost_label(Decimal("0.0001"))
assert label == "~$0.0001"
assert label != "$0.00"
def test_sub_cent_deepseek_scenario(self):
"""Reproduce the #79220 reproduction: DeepSeek at $0.004640."""
# DeepSeek V4 Pro: 8K input + 1.2K output + 32K cache read
# = $0.004640 per turn
amount = Decimal("0.004640")
label = _format_cost_label(amount)
assert "0.0046" in label
assert label != "$0.00"
assert label != "~$0.00"
# ---------------------------------------------------------------------------
# Subscription-included cost notes
# ---------------------------------------------------------------------------
class TestSubscriptionIncludedNotes:
"""Subscription-included costs should carry a note clarifying no invoice."""
def test_included_cost_has_note(self):
"""estimate_usage_cost for subscription-included route includes a note."""
# openai-codex is subscription_included
usage = CanonicalUsage(
input_tokens=1000,
output_tokens=500,
cache_read_tokens=0,
cache_write_tokens=0,
reasoning_tokens=0,
)
result = estimate_usage_cost(
"gpt-5.4-mini",
usage,
provider="openai-codex",
)
assert result.status == "included"
assert result.amount_usd == Decimal("0")
assert len(result.notes) > 0
assert any("subscription" in note.lower() for note in result.notes)