fix(tui): chrome cost from Nous portal headers only (F3)

The status-bar cost segment must show cost ONLY when running against the Nous
portal — per-model cache/input/output pricing is unreliable across the model
long tail, so a guessed figure is worse than none.

- New nous_header_cost_usd(agent): the chrome cost source, derived ONLY from the
  x-nous-credits-* header delta (deliberately ignores the OpenRouter usage.cost
  accumulator). _get_usage now uses it for cost_usd, so a non-Nous session
  reports no cost and the TUI hides the segment.
- The /usage accounting page is unchanged in spirit: it now reads
  real_session_cost_usd(agent) directly (both provider-reported sources) instead
  of the chrome-narrowed _get_usage cost_usd, so OpenRouter cost still shows there.

Tests: new TestNousHeaderCost (header-only, OR-accumulator ignored, clamp,
no-method); updated gateway _get_usage tests for the chrome narrowing; /usage
page test still asserts the full provider-reported figure. 316 gateway + 25 cost
tests green.
This commit is contained in:
alt-glitch 2026-06-13 19:16:44 +05:30
parent ef9232a2f7
commit e01b04de46
4 changed files with 82 additions and 11 deletions

View file

@ -919,6 +919,33 @@ def real_session_cost_usd(agent: Any) -> Optional[float]:
return total
def nous_header_cost_usd(agent: Any) -> Optional[float]:
"""Session-cumulative cost in USD derived ONLY from the Nous portal
``x-nous-credits-*`` header delta, or None.
This is the STATUS-BAR cost source (glitch 2026-06-13, F3): the TUI chrome
must show cost ONLY when the session runs against the Nous portal, because
the header delta is the one figure we can trust without re-deriving per-model
cache/input/output pricing (which is unreliable across the model long tail).
Unlike :func:`real_session_cost_usd`, this DELIBERATELY ignores the
OpenRouter ``usage.cost`` accumulator a non-Nous route reports no header,
so the chrome hides its cost segment entirely.
The ``/usage`` accounting page keeps using ``real_session_cost_usd`` (both
provider-reported sources); only the chrome bar narrows to header-only.
"""
try:
spent_micros = agent.get_credits_spent_micros()
except Exception:
return None
if spent_micros is None:
return None
try:
return max(0, int(spent_micros)) / 1_000_000
except (TypeError, ValueError):
return None
def has_known_pricing(
model_name: str,
provider: Optional[str] = None,

View file

@ -10,7 +10,7 @@ from types import SimpleNamespace
import pytest
from agent.usage_pricing import extract_provider_cost_usd, real_session_cost_usd
from agent.usage_pricing import extract_provider_cost_usd, nous_header_cost_usd, real_session_cost_usd
# ── extract_provider_cost_usd — the per-response REAL cost reader ────────────
@ -86,6 +86,32 @@ class TestRealSessionCost:
assert real_session_cost_usd(agent) is None
# ── nous_header_cost_usd — the CHROME status-bar cost (F3: header-only) ──────
class TestNousHeaderCost:
def test_header_delta_only(self):
# 123_400 micros = $0.1234 — the Nous header source feeds the chrome.
assert nous_header_cost_usd(_FakeAgent(credits_micros=123_400)) == pytest.approx(0.1234)
def test_openrouter_accumulator_ignored(self):
# The OpenRouter usage.cost accumulator must NOT feed the chrome bar:
# a non-Nous session (no header → None) reports no cost even when the
# OpenRouter accumulator has a value.
assert nous_header_cost_usd(_FakeAgent(actual=0.42)) is None
def test_no_header_is_none(self):
assert nous_header_cost_usd(_FakeAgent()) is None
def test_negative_delta_clamped(self):
# A mid-session top-up makes the delta negative — never show negative.
assert nous_header_cost_usd(_FakeAgent(credits_micros=-50_000)) == 0.0
def test_agent_without_credits_method_is_none(self):
agent = SimpleNamespace(session_actual_cost_usd=0.42)
assert nous_header_cost_usd(agent) is None
# ── Nous header fixture → real accumulator (full _capture_credits path) ─────

View file

@ -7444,11 +7444,15 @@ def test_get_usage_cost_absent_when_provider_reports_nothing(monkeypatch):
assert usage["input"] == 35_000
def test_get_usage_cost_present_when_provider_reported(monkeypatch):
def test_get_usage_cost_absent_for_openrouter_accumulator_chrome(monkeypatch):
"""F3: the chrome status bar shows cost ONLY from the Nous header delta.
An OpenRouter usage.cost accumulator alone (no x-nous-credits header) must
NOT surface cost_usd in _get_usage the chrome hides cost off-Nous. (The
/usage accounting page still counts the accumulator; that's a separate path.)
"""
agent = _usage_agent(session_actual_cost_usd=0.4321)
usage = server._get_usage(agent)
assert usage["cost_usd"] == pytest.approx(0.4321)
assert usage["cost_status"] == "actual"
assert "cost_usd" not in usage
def test_get_usage_cost_from_nous_credits_delta(monkeypatch):
@ -7456,6 +7460,7 @@ def test_get_usage_cost_from_nous_credits_delta(monkeypatch):
agent.get_credits_spent_micros = lambda: 250_000 # $0.25 real header delta
usage = server._get_usage(agent)
assert usage["cost_usd"] == pytest.approx(0.25)
assert usage["cost_status"] == "actual"
def test_compact_usage_per_model_rows_and_real_cost(monkeypatch):

View file

@ -2154,14 +2154,17 @@ def _get_usage(agent) -> dict:
usage["context_max"] = ctx_max
usage["context_percent"] = max(0, min(100, round(ctx_used / ctx_max * 100)))
usage["compressions"] = getattr(comp, "compression_count", 0) or 0
# Cost: provider-REPORTED only (OpenRouter usage.cost accumulator and/or
# the Nous x-nous-credits-* header delta). Never estimated. When nothing
# was reported `cost_usd` is ABSENT (not $0.00) and the TUI hides its
# cost segment — that's the intended UX.
# Cost (chrome status bar): Nous portal header delta ONLY (F3, glitch
# 2026-06-13). The OpenRouter usage.cost accumulator is deliberately NOT
# used here — per-model cache/input/output pricing is unreliable across the
# model long tail, so the bar shows cost ONLY on a Nous-portal session and
# hides it everywhere else. `cost_usd` is ABSENT (not $0.00) when no header
# was seen, and the TUI hides its cost segment. (The /usage accounting page
# still uses real_session_cost_usd — both provider-reported sources.)
try:
from agent.usage_pricing import real_session_cost_usd
from agent.usage_pricing import nous_header_cost_usd
real_cost = real_session_cost_usd(agent)
real_cost = nous_header_cost_usd(agent)
if real_cost is not None:
usage["cost_usd"] = real_cost
usage["cost_status"] = "actual"
@ -2234,7 +2237,17 @@ def _compact_usage_text(session: dict) -> str:
tail.append(f"compressions {u['compressions']}")
lines.append(" " + " · ".join(tail))
cost_usd = u.get("cost_usd")
# The /usage page reports the FULL provider-reported cost (OpenRouter
# usage.cost accumulator AND/OR the Nous header delta) — NOT the chrome's
# Nous-header-only figure (F3 narrowed `_get_usage["cost_usd"]` to the
# status bar). Read it straight from real_session_cost_usd here so the
# accounting page keeps both sources.
try:
from agent.usage_pricing import real_session_cost_usd
cost_usd = real_session_cost_usd(agent)
except Exception:
cost_usd = None
if cost_usd is not None:
lines.append(f" session cost: ${cost_usd:.4f} (provider-reported)")
else: