from __future__ import annotations from dataclasses import dataclass from datetime import datetime, timezone import json import pytest import aura.agents.iris.tools as iris from aura.core.config import AppConfig, FeatureFlags, ModelSettings, PathsSettings import aura.memory.mneme.tools as mneme_tools @dataclass class FakeResponse: content: str class FakeRouter: def generate(self, prompt: str) -> FakeResponse: return FakeResponse(content="Synthesized answer") @pytest.fixture() def iris_config(tmp_path): config = AppConfig( name="AURA", offline_mode=True, log_level="INFO", primary_model=ModelSettings(provider="ollama", name="llama3", host="http://127.0.0.1:11434"), fallback_models=[], paths=PathsSettings( allowed_roots=[tmp_path], data_dir=tmp_path, log_dir=tmp_path / "logs", memory_dir=tmp_path / "memory", ipc_socket=tmp_path / "aura.sock", ), features=FeatureFlags(hotkey=True, tray=True, ipc=True, api=True), source_path=tmp_path / "config.yaml", ) mneme_tools.set_config(config) iris.set_config(config) iris.set_router(FakeRouter()) return config def test_web_search_caches_and_summarizes(monkeypatch, iris_config, tmp_path): calls = {"count": 0} def fake_search(query, num_results, date_filter): calls["count"] += 1 return [iris.SearchResult(title="Doc", url=str(tmp_path / "page.html"), snippet="Snippet", source_domain="example.com", relevance_score=1.0)] page = tmp_path / "page.html" page.write_text("Doc

Alpha

Beta.

", encoding="utf-8") monkeypatch.setattr(iris, "_search_backend", fake_search) first = iris.web_search("alpha", num_results=1) second = iris.web_search("alpha", num_results=1) summary = iris.summarize_content(str(page)) assert calls["count"] == 1 assert first[0].title == "Doc" assert second[0].title == "Doc" assert summary.summary_text def test_deep_research_and_fact_check(monkeypatch, iris_config, tmp_path): page = tmp_path / "source.html" page.write_text("

Python is a language.

", encoding="utf-8") monkeypatch.setattr(iris, "web_search", lambda query, num_results=10, date_filter=None, safe_search=True: [iris.SearchResult(title="S", url=str(page), snippet="Python is a language", source_domain="example.com", relevance_score=1.0)]) monkeypatch.setattr(iris, "fetch_url", lambda url, extract_main_content=True: iris.PageContent(url=url, title="S", main_text="Python is a language.", word_count=4, fetched_at=datetime.now(timezone.utc), links=[])) deep = iris.deep_research("python") fact = iris.fact_check("Python is a language") papers = iris.search_academic("neural nets", source="arxiv", max_results=1) assert deep.synthesized_answer assert fact.verdict in {"supported", "contradicted", "unverified"} assert isinstance(papers, list) def test_compare_and_citations(monkeypatch, iris_config, tmp_path): page = tmp_path / "compare.html" page.write_text("

Reference 2024. Doe, J.

", encoding="utf-8") monkeypatch.setattr(iris, "fetch_url", lambda url, extract_main_content=True: iris.PageContent(url=url, title="T", main_text="Reference 2024. Doe, J.", word_count=4, fetched_at=datetime.now(timezone.utc), links=[])) compare = iris.compare_sources([str(page)], "question") citations = iris.extract_citations("Reference 2024. Doe, J.") assert compare.sources == [str(page)] assert citations class FakeHTTPResponse: def __init__(self, payload: bytes, status: int = 200): self._payload = payload self.status = status def read(self): return self._payload def __enter__(self): return self def __exit__(self, exc_type, exc, tb): return False def test_fetch_and_academic_search(monkeypatch, iris_config, tmp_path): page = tmp_path / "raw.html" page.write_text("RawBody text", encoding="utf-8") raw = iris.fetch_url(page.as_uri(), extract_main_content=False) assert raw.title == "Raw" assert "Body text" in raw.main_text arxiv_xml = b""" Paper One Abstract one http://arxiv.org/abs/1234.5678 Alice """ sem_json = json.dumps({"data": [{"title": "Paper Two", "abstract": "Abstract two", "authors": [{"name": "Bob"}], "url": "https://example.com", "year": 2024, "citationCount": 5}]}).encode("utf-8") def fake_urlopen(url, timeout=20): if "arxiv" in url: return FakeHTTPResponse(arxiv_xml) return FakeHTTPResponse(sem_json) monkeypatch.setattr(iris.urllib.request, "urlopen", fake_urlopen) papers = iris.search_academic("neural nets", source="both", max_results=2) assert len(papers) == 2 assert {paper.source for paper in papers} == {"arxiv", "semantic_scholar"}