feat(credits): report $used of $cap instead of % in the usage notice
The usage gauge is Nous subscription-cap-only (used_fraction requires a cap; non-Nous providers emit no headers, so no notice fires). A bare percentage implied a universal unit that doesn't exist, so report the absolute dollars used of the cap instead: used = cap - remaining, from micros (money-safe), clamped to [0, cap]. Still a snapshot at band-crossing (re-emits on band change, not every turn) to keep the single escalating line and stay quiet on append-only surfaces (messaging pushes one message per crossing).
This commit is contained in:
parent
b8a2b9b93e
commit
59a735b8f3
|
|
@ -316,12 +316,21 @@ def evaluate_credits_notices(
|
|||
active.discard(CREDITS_USAGE_KEY)
|
||||
if target_band is not None:
|
||||
# Belt-and-suspenders: a producer could set subscription_limit_micros
|
||||
# without subscription_limit_usd. Render "$? cap" rather than "$None cap".
|
||||
# without subscription_limit_usd. Render "$?" rather than "$None".
|
||||
_cap_usd = state.subscription_limit_usd or "?"
|
||||
_level = current_band[1] # type: ignore[index] (current_band set when target_band set)
|
||||
# Report absolute dollars used, not a bare "N% used": the percentage is
|
||||
# only meaningful against a Nous subscription cap (no cap → never fires),
|
||||
# so dollars are clearer and don't imply a universal %. Used = cap −
|
||||
# remaining (micros, money-safe), clamped to [0, cap]. Re-emits on band
|
||||
# change (50 → 75 → 90), not every turn — a snapshot, not a live ticker.
|
||||
_lim = state.subscription_limit_micros or 0
|
||||
_used_micros = max(0, min(_lim, _lim - state.subscription_micros))
|
||||
_used_usd = f"{_used_micros / 1_000_000:.2f}" if _lim else "?"
|
||||
_glyph = "⚠" if _level == "warn" else "•"
|
||||
to_show.append(
|
||||
AgentNotice(
|
||||
text=f"{'⚠' if _level == 'warn' else '•'} Credits {target_band}% used · ${_cap_usd} cap",
|
||||
text=f"{_glyph} You've used ${_used_usd} of your ${_cap_usd} cap",
|
||||
level=_level,
|
||||
kind=CREDITS_NOTICE_KIND,
|
||||
key=CREDITS_USAGE_KEY,
|
||||
|
|
|
|||
|
|
@ -569,7 +569,8 @@ class TestTopUpSuppression:
|
|||
assert latch["usage_band"] is None
|
||||
to_show, _ = evaluate_credits_notices(state_with_fraction(0.95), latch)
|
||||
n = next(n for n in to_show if n.key == "credits.usage")
|
||||
assert "90%" in n.text
|
||||
# uf 0.95 of a $20 cap → used = $19.00 (cap − remaining, clamped).
|
||||
assert "$19.00" in n.text
|
||||
assert latch["usage_band"] == 90
|
||||
|
||||
def test_grant_spent_still_fires_with_topup(self):
|
||||
|
|
@ -645,7 +646,8 @@ class TestUsageBands:
|
|||
evaluate_credits_notices(state_with_fraction(0.10), latch) # prime
|
||||
to_show, _ = evaluate_credits_notices(state_with_fraction(0.55), latch)
|
||||
n = next(n for n in to_show if n.key == "credits.usage")
|
||||
assert "50%" in n.text and n.level == "info"
|
||||
# uf 0.55 of a $20 cap → used = $11.00; band 50 fires at info level.
|
||||
assert "$11.00" in n.text and n.level == "info"
|
||||
assert latch["usage_band"] == 50
|
||||
|
||||
def test_75_band_fires_warn(self):
|
||||
|
|
@ -653,7 +655,8 @@ class TestUsageBands:
|
|||
evaluate_credits_notices(state_with_fraction(0.10), latch)
|
||||
to_show, _ = evaluate_credits_notices(state_with_fraction(0.80), latch)
|
||||
n = next(n for n in to_show if n.key == "credits.usage")
|
||||
assert "75%" in n.text and n.level == "warn"
|
||||
# uf 0.80 of a $20 cap → used = $16.00; band 75 fires at warn level.
|
||||
assert "$16.00" in n.text and n.level == "warn"
|
||||
assert latch["usage_band"] == 75
|
||||
|
||||
def test_climb_replaces_band(self):
|
||||
|
|
@ -663,15 +666,15 @@ class TestUsageBands:
|
|||
# 55% → 50 band
|
||||
evaluate_credits_notices(state_with_fraction(0.55), latch)
|
||||
assert latch["usage_band"] == 50
|
||||
# 80% → climbs to 75, clearing the 50 line
|
||||
# 80% → climbs to 75, clearing the 50 line (used = $16.00 of $20)
|
||||
to_show, to_clear = evaluate_credits_notices(state_with_fraction(0.80), latch)
|
||||
assert "credits.usage" in to_clear
|
||||
assert "75%" in self._band_text(to_show)
|
||||
assert "$16.00" in self._band_text(to_show)
|
||||
assert latch["usage_band"] == 75
|
||||
# 95% → climbs to 90
|
||||
# 95% → climbs to 90 (used = $19.00 of $20)
|
||||
to_show, to_clear = evaluate_credits_notices(state_with_fraction(0.95), latch)
|
||||
assert "credits.usage" in to_clear
|
||||
assert "90%" in self._band_text(to_show)
|
||||
assert "$19.00" in self._band_text(to_show)
|
||||
assert latch["usage_band"] == 90
|
||||
|
||||
def test_step_down_on_recovery(self):
|
||||
|
|
@ -680,13 +683,13 @@ class TestUsageBands:
|
|||
evaluate_credits_notices(state_with_fraction(0.10), latch)
|
||||
evaluate_credits_notices(state_with_fraction(0.95), latch)
|
||||
assert latch["usage_band"] == 90
|
||||
# drop to 80% → steps down to 75
|
||||
# drop to 80% → steps down to 75 (used = $16.00 of $20)
|
||||
to_show, to_clear = evaluate_credits_notices(state_with_fraction(0.80), latch)
|
||||
assert "credits.usage" in to_clear
|
||||
assert "75%" in self._band_text(to_show)
|
||||
# drop to 55% → steps down to 50
|
||||
assert "$16.00" in self._band_text(to_show)
|
||||
# drop to 55% → steps down to 50 (used = $11.00 of $20)
|
||||
to_show, _ = evaluate_credits_notices(state_with_fraction(0.55), latch)
|
||||
assert "50%" in self._band_text(to_show)
|
||||
assert "$11.00" in self._band_text(to_show)
|
||||
# drop below 50% → clears entirely
|
||||
to_show, to_clear = evaluate_credits_notices(state_with_fraction(0.10), latch)
|
||||
assert "credits.usage" in to_clear
|
||||
|
|
|
|||
Loading…
Reference in New Issue