test(fase2): assert BudgetMiddleware short-circuits a real chat call + the debate

This commit is contained in:
Kjell Tore Guttormsen 2026-06-26 00:42:51 +02:00
commit 7b08b37da3
2 changed files with 49 additions and 3 deletions

View file

@ -33,9 +33,7 @@ async def _noop() -> None:
def _resp(total: int | None) -> ChatResponse:
usage = UsageDetails(total_token_count=total) if total is not None else None
return ChatResponse(
messages=[Message(role="assistant", contents=["x"])], usage_details=usage
)
return ChatResponse(messages=[Message(role="assistant", contents=["x"])], usage_details=usage)
async def test_meter_reads_total_token_count_and_accumulates() -> None:
@ -69,6 +67,24 @@ async def test_strict_usage_none_hard_fails() -> None:
await mw.process(_Ctx(_resp(None)), _noop) # type: ignore[arg-type]
async def test_budget_middleware_fires_on_real_agent_chat(make_client_factory) -> None:
"""F8 (real-client half): registering BudgetMiddleware on a real Agent (layered chat client
that carries ChatMiddlewareLayer) and running an actual chat call short-circuits with
BudgetExceeded the middleware<->client integration the prior suite never exercised (the
minimal-base stand-in silently no-ops the middleware)."""
from agent_framework import Agent
client = make_client_factory("ok", tokens=8)("proposer") # 8 tokens/reply > cap 5
meter = TokenMeter(Budget(max_tokens=5, max_rounds=10))
agent = Agent(
client, "propose a measure", name="proposer", middleware=[BudgetMiddleware(meter)]
)
with pytest.raises(BudgetExceeded) as exc:
await agent.run("hi")
assert exc.value.kind == "tokens"
assert meter.tokens == 8 # charged from the synthetic UsageDetails via the middleware
def test_no_word_count_token_proxy_in_src() -> None:
# The meter is fed from real UsageDetails, never a len(text.split()) word-count proxy
# (research 03 Rec 3 — the Fase 1 _word_tokens anti-pattern is retired). NOTE: a bare