from datetime import datetime import pytest from app.ai.tool_registry import ToolRegistry from app.domain.schemas import PlannerDecision, ToolDefinition, TranscriptChunk from app.planner.llm_planner import HybridPlanner from app.validation.action_validator import ActionValidator from app.validation.policy_engine import PolicyEngine @pytest.mark.asyncio async def test_fallback_planner_extracts_task(): planner = HybridPlanner() chunk = TranscriptChunk(speaker="Bride", timestamp=datetime(2026, 6, 26, 12, 0), text="Create a task for Maria to confirm the photographer.") decision = await planner.plan(chunk, {}, [], []) assert decision.tool == "create_task" assert decision.extracted_entities["assignee"] == "Maria" assert decision.arguments["is_completed"] is False assert "Suggested owner: Maria" in decision.arguments["description"] assert "photographer" in decision.arguments["title"].lower() def test_validator_rejects_hallucinated_parameters(): registry = ToolRegistry( [ ToolDefinition( name="create_task", description="Create task", method="POST", path="/tasks", schema={"type": "object", "required": ["title"], "properties": {"title": {"type": "string"}}}, required=["title"], ) ] ) decision = PlannerDecision( intent="create_task", confidence=0.9, reasoning="test", tool="create_task", arguments={"title": "Confirm photographer", "unexpected": True}, ) result = ActionValidator(registry).validate(decision) assert not result.valid assert "Hallucinated" in result.errors[0] def test_policy_rejects_low_confidence(): decision = PlannerDecision(intent="create_note", confidence=0.2, reasoning="weak", tool="create_note", arguments={"content": "x"}) result = PolicyEngine().evaluate(decision) assert not result.allowed assert "below threshold" in result.reasons[0]