118 lines
4.1 KiB
Python
118 lines
4.1 KiB
Python
from pathlib import Path
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
import pytest
|
|
|
|
from haiku.rag.agents.research.models import ConversationalAnswer, ResearchReport
|
|
from haiku.rag.client import HaikuRAG
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def vcr_cassette_dir():
|
|
return str(Path(__file__).parent / "cassettes" / "test_client_research")
|
|
|
|
|
|
async def test_client_research_report(temp_db_path):
|
|
"""Test client.research() delegates to research graph in report mode."""
|
|
mock_report = ResearchReport(
|
|
title="Test Report",
|
|
executive_summary="Summary",
|
|
main_findings=["Finding 1"],
|
|
conclusions=["Conclusion 1"],
|
|
sources_summary="Sources",
|
|
)
|
|
|
|
with patch("haiku.rag.agents.research.graph.build_research_graph") as mock_build:
|
|
mock_graph = AsyncMock()
|
|
mock_graph.run = AsyncMock(return_value=mock_report)
|
|
mock_build.return_value = mock_graph
|
|
|
|
async with HaikuRAG(temp_db_path, create=True) as client:
|
|
result = await client.research(question="What is X?")
|
|
|
|
assert result is mock_report
|
|
mock_build.assert_called_once()
|
|
# Verify output_mode passed correctly
|
|
_, kwargs = mock_build.call_args
|
|
assert kwargs["output_mode"] == "report"
|
|
|
|
# Verify graph.run was called with correct state/deps
|
|
mock_graph.run.assert_called_once()
|
|
call_kwargs = mock_graph.run.call_args[1]
|
|
assert call_kwargs["state"].context.original_question == "What is X?"
|
|
assert isinstance(call_kwargs["deps"].client, HaikuRAG)
|
|
|
|
|
|
async def test_client_research_conversational(temp_db_path):
|
|
"""Test client.research() with conversational output mode."""
|
|
mock_answer = ConversationalAnswer(
|
|
answer="The answer is 42.",
|
|
confidence=0.95,
|
|
)
|
|
|
|
with patch("haiku.rag.agents.research.graph.build_research_graph") as mock_build:
|
|
mock_graph = AsyncMock()
|
|
mock_graph.run = AsyncMock(return_value=mock_answer)
|
|
mock_build.return_value = mock_graph
|
|
|
|
async with HaikuRAG(temp_db_path, create=True) as client:
|
|
result = await client.research(
|
|
question="What is X?",
|
|
output_mode="conversational",
|
|
)
|
|
|
|
assert result is mock_answer
|
|
_, kwargs = mock_build.call_args
|
|
assert kwargs["output_mode"] == "conversational"
|
|
|
|
|
|
async def test_client_research_passes_filter(temp_db_path):
|
|
"""Test client.research() passes filter to state."""
|
|
mock_report = ResearchReport(
|
|
title="Test",
|
|
executive_summary="Summary",
|
|
main_findings=[],
|
|
conclusions=[],
|
|
sources_summary="",
|
|
)
|
|
|
|
with patch("haiku.rag.agents.research.graph.build_research_graph") as mock_build:
|
|
mock_graph = AsyncMock()
|
|
mock_graph.run = AsyncMock(return_value=mock_report)
|
|
mock_build.return_value = mock_graph
|
|
|
|
async with HaikuRAG(temp_db_path, create=True) as client:
|
|
await client.research(
|
|
question="What is X?",
|
|
filter="uri LIKE '%test%'",
|
|
)
|
|
|
|
call_kwargs = mock_graph.run.call_args[1]
|
|
assert call_kwargs["state"].search_filter == "uri LIKE '%test%'"
|
|
|
|
|
|
async def test_client_research_uses_config(temp_db_path):
|
|
"""Test client.research() passes config to graph builder and state."""
|
|
mock_report = ResearchReport(
|
|
title="Test",
|
|
executive_summary="Summary",
|
|
main_findings=[],
|
|
conclusions=[],
|
|
sources_summary="",
|
|
)
|
|
|
|
with patch("haiku.rag.agents.research.graph.build_research_graph") as mock_build:
|
|
mock_graph = AsyncMock()
|
|
mock_graph.run = AsyncMock(return_value=mock_report)
|
|
mock_build.return_value = mock_graph
|
|
|
|
async with HaikuRAG(temp_db_path, create=True) as client:
|
|
await client.research(question="What is X?")
|
|
|
|
_, kwargs = mock_build.call_args
|
|
assert kwargs["config"] is client._config
|
|
|
|
call_kwargs = mock_graph.run.call_args[1]
|
|
state = call_kwargs["state"]
|
|
assert state.max_iterations == client._config.research.max_iterations
|
|
assert state.max_concurrency == client._config.research.max_concurrency
|