feat(usage): multi-provider equivalent cost table
This commit is contained in:
@@ -1165,19 +1165,22 @@ def test_usage_block_shows_equivalent_provider_cost():
|
||||
"cache_read": 0, "cache_write": 0, "total": 204000,
|
||||
"cost": 0.0, "steps": 6, "duration_s": 100.0}
|
||||
sec = ai_review._render_collapsible_usage(usage, "glm-5.2:cloud", config=None)
|
||||
# Two cost lines now: an equivalent (default Sonnet 5) AND the $0 actual.
|
||||
# New layout: equivalent-cost table instead of a single "Est. cost on …"
|
||||
# line. The default compare_against is sonnet-5, gpt-5, gemini-2.5-pro,
|
||||
# grok-4.5; cost_target defaults to sonnet-5 (bolded).
|
||||
assert "🔋 AI Usage & Run Details" in sec
|
||||
assert "**Est. cost on Claude Sonnet 5**" in sec
|
||||
assert "**Actual**: $0.00" in sec
|
||||
assert "free tier" in sec
|
||||
# Equivalent should be > 0 for non-trivial token counts.
|
||||
assert "$0.00" in sec # the actual line
|
||||
# And a non-zero one for the equivalent.
|
||||
import re
|
||||
cost_lines = [ln for ln in sec.splitlines() if "cost on" in ln]
|
||||
assert len(cost_lines) == 1
|
||||
assert re.search(r"\$\d", cost_lines[0]) is not None
|
||||
assert "$0.00" not in cost_lines[0]
|
||||
# Multi-provider table header present, default roster rendered, default
|
||||
# cost_target (Sonnet 5) is the bolded row.
|
||||
assert "| Provider | Cost |" in sec
|
||||
assert "**Claude Sonnet 5**" in sec
|
||||
assert "GPT-5" in sec
|
||||
assert "Gemini 2.5 Pro" in sec
|
||||
assert "Grok 4.5" in sec
|
||||
# 200k * $2/MTok + 4k * $10/MTok → $0.44
|
||||
assert "$0.44" in sec
|
||||
|
||||
|
||||
def test_usage_block_honors_cost_target(monkeypatch):
|
||||
@@ -1204,17 +1207,22 @@ def test_usage_block_respects_repo_config_cost_target(monkeypatch):
|
||||
assert "$0.0075" in sec
|
||||
|
||||
|
||||
def test_usage_block_reports_unknown_price_target():
|
||||
def test_usage_block_reports_unknown_price_target(capsys):
|
||||
usage = {"input": 100, "output": 100, "reasoning": 0,
|
||||
"cache_read": 0, "cache_write": 0, "total": 200,
|
||||
"cost": 0.0, "steps": 1, "duration_s": 1.0}
|
||||
sec = ai_review._render_collapsible_usage(
|
||||
usage, "glm-5.2:cloud", config={"cost_target": "bogus-model"}
|
||||
)
|
||||
# Falls back to default + surfaces the error in the line.
|
||||
# Falls back to default. The error now goes to stderr (otherwise it would
|
||||
# land mid-table and look like a model error in the posted summary).
|
||||
assert "Claude Sonnet 5" in sec
|
||||
assert "unknown price target" in sec
|
||||
assert "bogus-model" in sec
|
||||
assert "**Claude Sonnet 5**" in sec # bolded as the resolved cost_target
|
||||
assert "bogus-model" not in sec
|
||||
assert "unknown price target" not in sec
|
||||
err = capsys.readouterr().err
|
||||
assert "unknown price target" in err
|
||||
assert "bogus-model" in err
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@@ -1769,6 +1777,50 @@ def test_collapsible_usage_renders_humanized_tokens():
|
||||
assert "17,303 (17.3K) out" in block
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Multi-provider equivalent-cost table — Task 10
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def test_collapsible_usage_renders_multi_provider_table():
|
||||
usage = {"input": 1_000_000, "output": 1000, "reasoning": 0,
|
||||
"cache_read": 0, "cache_write": 0, "total": 1_001_000,
|
||||
"cost": 0.0, "steps": 1, "duration_s": 10.0}
|
||||
block = _render_collapsible_usage(usage, "glm-5.2:cloud", config={"compare_against": ["claude-sonnet-5", "gpt-5"]})
|
||||
assert "Claude Sonnet 5" in block
|
||||
assert "GPT-5" in block
|
||||
assert "| Provider | Cost |" in block
|
||||
|
||||
|
||||
def test_collapsible_usage_uses_default_compare_against_when_absent():
|
||||
usage = {"input": 1_000_000, "output": 0, "reasoning": 0,
|
||||
"cache_read": 0, "cache_write": 0, "total": 1_000_000,
|
||||
"cost": 0.0, "steps": 1, "duration_s": 5.0}
|
||||
block = _render_collapsible_usage(usage, "glm-5.2:cloud", config={})
|
||||
assert "Claude Sonnet 5" in block
|
||||
assert "GPT-5" in block
|
||||
assert "Gemini 2.5 Pro" in block
|
||||
assert "Grok 4.5" in block
|
||||
|
||||
|
||||
def test_collapsible_usage_bolds_cost_target_row():
|
||||
usage = {"input": 1_000_000, "output": 0, "reasoning": 0,
|
||||
"cache_read": 0, "cache_write": 0, "total": 1_000_000,
|
||||
"cost": 0.0, "steps": 1, "duration_s": 5.0}
|
||||
block = _render_collapsible_usage(usage, "glm-5.2:cloud", config={"cost_target": "gpt-5"})
|
||||
assert "**GPT-5**" in block
|
||||
assert "Claude Sonnet 5" in block # still in default compare set
|
||||
|
||||
|
||||
def test_collapsible_usage_skips_zero_cost_rows():
|
||||
usage = {"input": 0, "output": 0, "reasoning": 0,
|
||||
"cache_read": 0, "cache_write": 0, "total": 0,
|
||||
"cost": 0.0, "steps": 1, "duration_s": 1.0}
|
||||
block = _render_collapsible_usage(usage, "glm-5.2:cloud", config={})
|
||||
# With zero tokens, all costs are $0 — skip the entire table.
|
||||
assert "| Provider | Cost |" not in block
|
||||
|
||||
|
||||
def test_inline_comment_body_humanized_tokens():
|
||||
# Value chosen > 1000 so fmt_tokens actually adds the comma + short suffix;
|
||||
# the plan's 362 would render identically with or without fmt_tokens.
|
||||
|
||||
Reference in New Issue
Block a user