60 lines
2.0 KiB
Python
60 lines
2.0 KiB
Python
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]
|