import asyncio from app.core.async_router import AsyncRouter from app.core.contracts import CriticScore, ExecutionDirective, PlanStep, UserTask class _FakeAdapter: def __init__(self, responses: list[str]) -> None: self._responses = responses async def generate(self, prompt: str, max_tokens: int | None = None) -> str: return self._responses.pop(0) def test_user_task_defaults() -> None: task = UserTask(input="hello") assert task.task_id assert task.session_id def test_plan_step_supports_dependencies() -> None: step = PlanStep( id="step-1", kind="tool", tool="shell_exec", description="run command", depends_on=[], ) assert step.tool == "shell_exec" def test_critic_score_bounds() -> None: score = CriticScore( correctness=1.0, usefulness=0.5, safety=0.0, memory_store=False, weight=0.2, explanation="ok", ) assert score.weight == 0.2 def test_execution_directive_defaults() -> None: directive = ExecutionDirective(type="noop") assert directive.payload == {} assert directive.confidence == 0.0 def test_router_compiles_tool_plan_even_when_classifier_says_conversation() -> None: router = AsyncRouter( thinker=_FakeAdapter([ "conversation", "ПЛАН:\nШаг 1: [shell_exec] выполнить `uptime`", ]), json_compiler=_FakeAdapter([ '{"type":"plan","payload":{"steps":[{"id":"1","tool":"shell_exec","args":{"command":"uptime"},"depends_on":[]}]}}' ]), ) directive = asyncio.run( router.decide( state={}, context={"task_summary": "Проверь аптайм ПК", "task_context": {}}, ) ) assert directive.type == "plan" assert directive.payload["steps"][0]["tool"] == "shell_exec"