# retoor import json from tests.conftest import run_async from devplacepy.services.jobs.deepsearch import orchestrate as orchestrate_module from devplacepy.services.jobs.deepsearch.crawl import CrawledPage from devplacepy.services.jobs.deepsearch.orchestrate import Orchestration, orchestrate, source_diversity def _page(url, text="content " * 30): return CrawledPage(url=url, title="T", text=text, source="httpx", status=200) def test_source_diversity_empty_is_zero(): assert source_diversity([]) == 0.0 def test_source_diversity_increases_with_distinct_domains(): one = source_diversity([_page("https://a.example/1"), _page("https://a.example/2")]) many = source_diversity([_page("https://a.example/1"), _page("https://b.example/2")]) assert 0.0 < one <= 1.0 assert many > one def test_source_diversity_capped_at_one(): pages = [_page(f"https://d{i}.example") for i in range(8)] assert source_diversity(pages) <= 1.0 def test_orchestrate_with_no_pages_returns_gap(): async def fake_complete(messages, api_key, **kwargs): return {}, {}, 0 result = run_async(orchestrate("q", [], "k", lambda frame: None)) assert isinstance(result, Orchestration) assert result.source_diversity == 0.0 assert result.gaps def test_orchestrate_grounded_run_emits_agent_frames(monkeypatch): frames = [] summary_payload = json.dumps( { "summary": "A grounded answer.", "findings": [ {"title": "Finding", "detail": "Detail", "confidence": 0.7, "citations": [1]} ], } ) gaps_payload = json.dumps({"gaps": ["one open question"]}) link_payload = json.dumps({"confidence": 0.8}) replies = iter([summary_payload, gaps_payload, link_payload]) async def fake_request_completion(messages, api_key, **kwargs): return ({"choices": [{"message": {"content": next(replies)}}]}, {}, 5) monkeypatch.setattr(orchestrate_module, "request_completion", fake_request_completion) pages = [_page("https://a.example"), _page("https://b.example")] result = run_async(orchestrate("question", pages, "k", frames.append)) assert result.summary == "A grounded answer." assert result.findings and result.findings[0]["citations"] == [1] assert result.gaps == ["one open question"] assert 0.0 < result.confidence <= 1.0 assert result.source_diversity > 0.0 assert result.score > 0 agents = {f["agent"] for f in frames if f.get("type") == "agent"} assert agents == {"summarizer", "critic", "linker"} def test_orchestrate_falls_back_to_heuristic_on_failure(monkeypatch): async def boom(messages, api_key, **kwargs): raise RuntimeError("upstream down") monkeypatch.setattr(orchestrate_module, "request_completion", boom) pages = [_page("https://a.example"), _page("https://b.example")] result = run_async(orchestrate("question", pages, "k", lambda frame: None)) assert result.findings assert result.gaps assert result.source_diversity > 0.0