"""A real consult over the normalized route (L9). The point is the prompt-level contract: a live model must produce something that parses against our local schema, since no API-level enforcement exists. """ import io from pathlib import Path import pytest from nisse_dev.evals import collect from nisse_dev.expert import BudgetExhausted, ExpertDesk from nisse_dev.llm import LiteLLMClient, RoleMap from nisse_dev.oplog import OpLog from nisse_dev.state import StateStore pytestmark = pytest.mark.integration @pytest.fixture def desk(tmp_path: Path, litellm: LiteLLMClient, live_model: str): def make(budget: int = 2) -> tuple[ExpertDesk, StateStore]: model = live_model roles = RoleMap(executor=model, planner=model, delegate=model, consultant=model) store = StateStore( tmp_path / "state.db", oplog=OpLog("nisse-dev", io.StringIO()) ) return ExpertDesk(litellm, store, roles, budget=budget), store return make def test_live_consult_parses_against_the_local_schema(desk) -> None: expert, store = desk() answer = expert.ask( "For a single-process agent storing a few thousand rows of task state, " "is SQLite sufficient, or is PostgreSQL warranted? Answer briefly." ) assert answer.confidence in {"high", "medium", "low"} assert len(answer.answer) > 20 # The consult is captured for L9 without any extra bookkeeping. [record] = collect(store) assert record.role == "consultant" assert record.exit_status == "answered" def test_live_budget_stops_a_circling_caller(desk) -> None: expert, _ = desk(budget=1) expert.ask("Name one advantage of WAL mode in SQLite. Be brief.") with pytest.raises(BudgetExhausted): expert.ask("And another?")