mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 04:07:04 +00:00
nanny economics: render the money sentence from the rounds' cost evidence
The reminder no longer asserts that every nanny round is metered API money. A positive priced delta since the baseline says the spend is metered; no provider price says the cash cost is unknown, not zero. The latest round's route is named only as context, and a fallback clause appears only when a fallback chain is actually configured. The burn phrase's unpriced branch stops calling rounds metered. Trigger, cadence and baseline are unchanged; the checkpoint event records the cost class. Co-authored-by: Ouroboros <311266734+ouroboros-agent@users.noreply.github.com>
This commit is contained in:
parent
6784af2e3c
commit
3bbf4d69e0
3 changed files with 79 additions and 3 deletions
|
|
@ -334,6 +334,37 @@ def _maybe_inject_cost_budget_milestone(
|
|||
return True
|
||||
|
||||
|
||||
def _own_round_cost_sentence(ctx: Any, cost: float) -> tuple[str, str]:
|
||||
"""The reminder's money sentence from COST EVIDENCE first: a positive priced
|
||||
delta (provider-reported or estimated cost of the nanny's own rounds) is
|
||||
metered money; no price is an unknown cash cost, never zero. The latest round's
|
||||
route is named only as context, and a fallback clause appears only when a
|
||||
fallback chain is actually configured (a paid round is no proof the next is)."""
|
||||
usage = getattr(ctx, "_accumulated_usage", None)
|
||||
meta = usage.get("_last_llm_call_meta") if isinstance(usage, dict) else None
|
||||
meta = meta if isinstance(meta, dict) else {}
|
||||
model = str(meta.get("resolved_model") or meta.get("model") or "")
|
||||
route = " / ".join(item for item in (str(meta.get("provider") or ""), model) if item)
|
||||
if cost > 0:
|
||||
cost_class, sentence = "priced", (
|
||||
"Your own rounds here reported a price, so that spend is metered money")
|
||||
else:
|
||||
cost_class, sentence = "unpriced", (
|
||||
"No provider price reached this task for your own rounds here: an unknown "
|
||||
"cash cost, not a zero one")
|
||||
sentence += f" (latest round: {route})." if route else "."
|
||||
try:
|
||||
from ouroboros.model_slots import get_fallback_models
|
||||
|
||||
fallbacks = get_fallback_models(str(meta.get("model") or ""))
|
||||
except Exception:
|
||||
fallbacks = []
|
||||
if fallbacks:
|
||||
sentence += (f" If this route stops serving, the configured fallback ({', '.join(fallbacks[:3])}) "
|
||||
"may take over, and a fallback round may be metered.")
|
||||
return cost_class, sentence
|
||||
|
||||
|
||||
def _maybe_inject_nanny_economics_reminder(
|
||||
round_idx: int,
|
||||
messages: List[Dict[str, Any]],
|
||||
|
|
@ -378,13 +409,13 @@ def _maybe_inject_nanny_economics_reminder(
|
|||
# BR1-3: never an unconditional "$0" claim — the owner's wording law is
|
||||
# typed cost classes: known-zero only on a settled $0 spend, never "free"
|
||||
# unqualified (estimated/undisclosed spend is never zero).
|
||||
cost_class, cost_sentence = _own_round_cost_sentence(ctx, cost)
|
||||
reminder = (
|
||||
"[NANNY ECONOMICS REMINDER]\n"
|
||||
f"You are a harness-dispatched NANNY and you have spent {_nanny_burn_phrase(rounds, cost)} "
|
||||
f"{since_phrase}. A subscription-lane delegated run has known-zero "
|
||||
"marginal cost only when its settled spend reports $0 (estimated or "
|
||||
"undisclosed spend is never zero); every round you think yourself is "
|
||||
"metered API money.\n"
|
||||
f"undisclosed spend is never zero). {cost_sentence}\n"
|
||||
"This is a reminder, not a stop. Consider: delegate the remaining work "
|
||||
"(delegate_start / delegate_wait — follow-up work and fixes are delegated too), "
|
||||
"and keep your own rounds for judgment: acceptance, integration, honest "
|
||||
|
|
@ -400,6 +431,7 @@ def _maybe_inject_nanny_economics_reminder(
|
|||
"round": round_idx,
|
||||
"metered_rounds_since_delegate_activity": rounds,
|
||||
"metered_cost_since_delegate_activity_usd": round(cost, 4),
|
||||
"own_round_cost_class": cost_class,
|
||||
})
|
||||
return True
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ def nanny_burn_phrase(rounds: int, cost: float) -> str:
|
|||
return f"~${cost:.2f} of your own metered spend"
|
||||
if cost > 0:
|
||||
return f"{rounds} of your own metered LLM rounds (~${cost:.2f})"
|
||||
return f"{rounds} of your own metered LLM rounds"
|
||||
return f"{rounds} of your own LLM rounds (no provider price reported: cash cost unknown, not zero)"
|
||||
|
||||
|
||||
# Compatibility spellings retained on ``ouroboros.loop`` through imports.
|
||||
|
|
|
|||
|
|
@ -904,3 +904,47 @@ def test_burn_phrase_never_claims_zero_rounds_with_real_dollars():
|
|||
assert "0 of your own metered LLM rounds" not in _nanny_burn_phrase(0, 2.45)
|
||||
assert "$2.45" in _nanny_burn_phrase(0, 2.45)
|
||||
assert "3 of your own metered LLM rounds" in _nanny_burn_phrase(3, 2.45)
|
||||
|
||||
|
||||
# -- the money sentence follows the round's own cost evidence ------------------
|
||||
|
||||
|
||||
def _fire_reminder(cost_per_round, meta, monkeypatch, fallbacks=""):
|
||||
from ouroboros.loop import _maybe_inject_nanny_economics_reminder, _note_nanny_delegate_activity
|
||||
|
||||
monkeypatch.setenv("OUROBOROS_MODEL_FALLBACKS", fallbacks)
|
||||
monkeypatch.delenv("OUROBOROS_MODEL_FALLBACK", raising=False)
|
||||
ctx = _nanny_ctx(_accumulated_usage={"_last_llm_call_meta": meta})
|
||||
tools = SimpleNamespace(_ctx=ctx)
|
||||
_note_nanny_delegate_activity(ctx, 1, {"cost": 0.0}, [_delegate_call()])
|
||||
round_idx, msgs = 1, []
|
||||
while not msgs:
|
||||
round_idx += 1
|
||||
_note_nanny_delegate_activity(ctx, round_idx, {"cost": cost_per_round * round_idx}, [])
|
||||
_maybe_inject_nanny_economics_reminder(round_idx, msgs, tools, lambda *_: None)
|
||||
return "\n".join(m.get("content", "") for m in msgs)
|
||||
|
||||
|
||||
def test_an_unpriced_round_is_an_unknown_cash_cost_never_metered_or_zero(monkeypatch):
|
||||
text = _fire_reminder(0.0, {"provider": "claudexor", "model": "codex=gpt"}, monkeypatch)
|
||||
assert "metered API money" not in text and "metered LLM rounds" not in text
|
||||
assert "cash cost unknown, not zero" in text # burn phrase, cost class 'unpriced'
|
||||
assert "claudexor / codex=gpt" in text # the route, named as context only
|
||||
assert "only when its settled spend reports $0" in text # the pinned conditional stays
|
||||
assert "fallback" not in text # no chain configured, no claim
|
||||
|
||||
|
||||
def test_a_priced_round_stays_metered_and_names_a_configured_fallback(monkeypatch):
|
||||
text = _fire_reminder(0.05, {"provider": "openrouter", "model": "anthropic/claude"},
|
||||
monkeypatch, fallbacks="openai/gpt-x, google/gem")
|
||||
assert "metered LLM rounds" in text and "that spend is metered money" in text
|
||||
assert "cash cost unknown" not in text
|
||||
assert "configured fallback (openai/gpt-x, google/gem)" in text
|
||||
|
||||
|
||||
def test_the_unpriced_burn_phrase_never_calls_rounds_metered():
|
||||
from ouroboros.loop import _nanny_burn_phrase
|
||||
|
||||
assert _nanny_burn_phrase(4, 0.0) == (
|
||||
"4 of your own LLM rounds (no provider price reported: cash cost unknown, not zero)")
|
||||
assert "4 of your own metered LLM rounds" in _nanny_burn_phrase(4, 0.5)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue