auralynq-rag / tests /test_graphrag_communities.py
asdfasdfqrqwer's picture
sync: bring the Space up to the current GitHub tree
656439d
Raw
History Blame Contribute Delete
3.67 kB
"""GraphRAG community detection + summaries (Feature 02) — offline tests."""
from __future__ import annotations
from auralynq.config.settings import Settings
from auralynq.retrieval.graphrag import (
build_communities,
detect_communities,
load_communities,
save_communities,
)
from auralynq.retrieval.pathrag.graph import KnowledgeGraph, Provenance
from auralynq.serving.app import create_app
from fastapi.testclient import TestClient
def _two_cluster_kg() -> KnowledgeGraph:
"""Two dense triangles joined by a single weak edge → two communities."""
kg = KnowledgeGraph()
cluster_a = [("Paris", "France"), ("France", "Europe"), ("Paris", "Europe")]
cluster_b = [("Python", "Django"), ("Django", "ORM"), ("Python", "ORM")]
for src, dst in cluster_a:
kg.add_entity(src, chunk_id="ca")
kg.add_entity(dst, chunk_id="ca")
kg.add_relation(src, dst, "related", Provenance(chunk_id="ca", source="geo.txt"))
for src, dst in cluster_b:
kg.add_entity(src, chunk_id="cb")
kg.add_entity(dst, chunk_id="cb")
kg.add_relation(src, dst, "uses", Provenance(chunk_id="cb", source="tech.txt"))
# single bridge edge (weak) so the graph is connected but still two communities
kg.add_relation("Europe", "Python", "mentions", Provenance(chunk_id="ca", source="geo.txt"))
return kg
class _StubLLM:
name = "stub"
def generate(self, prompt, *, system=None, temperature=None, max_tokens=None) -> str:
return "A theme summary of the community."
def test_detect_two_communities():
comms = detect_communities(_two_cluster_kg(), min_size=3, algo="louvain")
assert len(comms) == 2
# Each community keeps its entities + internal relations.
sizes = sorted(c.size for c in comms)
assert sizes == [3, 3]
assert all(c.relations for c in comms)
def test_min_size_gate_filters_small():
kg = KnowledgeGraph()
kg.add_entity("A", chunk_id="c")
kg.add_entity("B", chunk_id="c")
kg.add_relation("A", "B", "r", Provenance(chunk_id="c", source="s.txt"))
assert detect_communities(kg, min_size=3) == []
def test_greedy_algo_also_detects():
comms = detect_communities(_two_cluster_kg(), min_size=3, algo="greedy")
assert len(comms) >= 1
def test_build_summarizes_and_persists(tmp_path):
s = Settings(data_dir=tmp_path)
s.graphrag.enabled = True
comms = build_communities(_two_cluster_kg(), llm=_StubLLM(), settings=s)
assert len(comms) == 2
assert all(c.summary == "A theme summary of the community." for c in comms)
# Persisted and reloadable.
loaded = load_communities(s.communities_path)
assert len(loaded) == 2
assert loaded[0]["summary"]
assert "geo.txt" in loaded[0]["sources"] or "tech.txt" in loaded[0]["sources"]
def test_save_load_roundtrip(tmp_path):
comms = detect_communities(_two_cluster_kg(), min_size=3)
path = tmp_path / "communities.json"
save_communities(comms, path)
loaded = load_communities(path)
assert len(loaded) == 2
assert load_communities(tmp_path / "missing.json") == []
def test_communities_endpoint(monkeypatch):
monkeypatch.setenv("AURALYNQ_GRAPHRAG__ENABLED", "1")
from auralynq.config import reload_settings
reload_settings()
from auralynq.config.settings import get_settings
s = get_settings()
build_communities(_two_cluster_kg(), llm=_StubLLM(), settings=s)
client = TestClient(create_app())
r = client.get("/graphrag/communities")
assert r.status_code == 200
body = r.json()
assert body["enabled"] is True
assert body["count"] == 2
assert body["communities"][0]["summary"]