feat(fase3): additive meter= seam on run_project (SC3 detach hook)
This commit is contained in:
parent
497399e0aa
commit
8b64c7f8de
2 changed files with 39 additions and 1 deletions
|
|
@ -124,6 +124,7 @@ async def run_project(
|
||||||
top_k: int = 3,
|
top_k: int = 3,
|
||||||
enable_layer1_hitl: bool = False,
|
enable_layer1_hitl: bool = False,
|
||||||
notify: Callable[[Verdict], None] | None = None,
|
notify: Callable[[Verdict], None] | None = None,
|
||||||
|
meter: TokenMeter | None = None,
|
||||||
) -> RunResult:
|
) -> RunResult:
|
||||||
"""Run the vertical slice for ONE project. ``client_factory`` is the test-injection seam
|
"""Run the vertical slice for ONE project. ``client_factory`` is the test-injection seam
|
||||||
(defaults to the real backend). ``verdict_input`` carries the expert decision/rationale
|
(defaults to the real backend). ``verdict_input`` carries the expert decision/rationale
|
||||||
|
|
@ -148,7 +149,11 @@ async def run_project(
|
||||||
# The shared meter is driven on the debate's chat calls by the BudgetMiddleware
|
# The shared meter is driven on the debate's chat calls by the BudgetMiddleware
|
||||||
# (the brief's named short-circuit mechanism); the retrieval tool exposes the
|
# (the brief's named short-circuit mechanism); the retrieval tool exposes the
|
||||||
# citation-bearing data source to the agents (no longer string-stuffed out-of-band).
|
# citation-bearing data source to the agents (no longer string-stuffed out-of-band).
|
||||||
meter = TokenMeter(Budget(max_tokens=max_tokens, max_rounds=max(max_rounds * 4, 4)))
|
meter = (
|
||||||
|
meter
|
||||||
|
if meter is not None
|
||||||
|
else TokenMeter(Budget(max_tokens=max_tokens, max_rounds=max(max_rounds * 4, 4)))
|
||||||
|
)
|
||||||
factory = client_factory if client_factory is not None else _default_factory(profile)
|
factory = client_factory if client_factory is not None else _default_factory(profile)
|
||||||
budget_mw = BudgetMiddleware(meter)
|
budget_mw = BudgetMiddleware(meter)
|
||||||
retrieval_tool = make_retrieval_tool(docs_dir, top_k=top_k)
|
retrieval_tool = make_retrieval_tool(docs_dir, top_k=top_k)
|
||||||
|
|
|
||||||
|
|
@ -199,6 +199,39 @@ async def test_h_tiny_budget_halts_via_debate_middleware(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_i_injected_meter_is_used(docs_dir, make_client_factory) -> None:
|
||||||
|
"""Step 1 (SC3 detach hook): a TokenMeter passed as ``meter=`` IS the meter the run uses —
|
||||||
|
its pre-charged tokens flow through to ``provenance.token_usage`` (run.py:179). Detaches
|
||||||
|
cleanly: reverting the run.py:151 injection makes the injected instance be ignored (a fresh
|
||||||
|
internal meter is built instead), the pre-charge vanishes, and the equality below fails.
|
||||||
|
Pattern: test_a (run_project call shape)."""
|
||||||
|
from portfolio_optimiser.budget import Budget, TokenMeter
|
||||||
|
|
||||||
|
factory = make_client_factory(_VALID)
|
||||||
|
baseline = await run_project(
|
||||||
|
"FV42-GSV-E1",
|
||||||
|
"local",
|
||||||
|
docs_dir=docs_dir,
|
||||||
|
verdict_input=_VI,
|
||||||
|
client_factory=factory,
|
||||||
|
)
|
||||||
|
pre_charged = 5000
|
||||||
|
injected = TokenMeter(Budget(max_tokens=100_000, max_rounds=max(3 * 4, 4)))
|
||||||
|
injected.charge(pre_charged)
|
||||||
|
result = await run_project(
|
||||||
|
"FV42-GSV-E1",
|
||||||
|
"local",
|
||||||
|
docs_dir=docs_dir,
|
||||||
|
verdict_input=_VI,
|
||||||
|
client_factory=factory,
|
||||||
|
meter=injected,
|
||||||
|
)
|
||||||
|
assert baseline.provenance.token_usage > 0 # the run charges a deterministic delta
|
||||||
|
# The injected instance flows through: end tokens == pre-charge + the same run delta.
|
||||||
|
assert result.provenance.token_usage == pre_charged + baseline.provenance.token_usage
|
||||||
|
assert result.provenance.token_usage > baseline.provenance.token_usage
|
||||||
|
|
||||||
|
|
||||||
async def test_f_malformed_contract_raises_before_any_chat(docs_dir, make_client_factory) -> None:
|
async def test_f_malformed_contract_raises_before_any_chat(docs_dir, make_client_factory) -> None:
|
||||||
calls = {"n": 0}
|
calls = {"n": 0}
|
||||||
base = make_client_factory(_VALID)
|
base = make_client_factory(_VALID)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue