feat(H): H-EXT/H-ENT/H-AUTO/H-CONF — LLM knowledge extraction (entities, relationships, auto-create in GraphRAG, confidence scoring with review queue), 31 tests passing
This commit is contained in:
@@ -275,3 +275,103 @@ class TestEvidenceReferences:
|
||||
|
||||
refs = build_evidence_references([])
|
||||
assert refs == []
|
||||
|
||||
|
||||
# ─── H-EXT/H-ENT/H-AUTO/H-CONF: Knowledge Extraction ─────────────────────────
|
||||
|
||||
|
||||
class TestKnowledgeExtraction:
|
||||
"""Test the knowledge extraction module (H-EXT, H-ENT, H-AUTO, H-CONF)."""
|
||||
|
||||
def test_extracted_entity_dataclass(self):
|
||||
"""ExtractedEntity dataclass works correctly."""
|
||||
from app.ai.knowledge_extraction import ExtractedEntity
|
||||
|
||||
entity = ExtractedEntity(name="John Doe", entity_type="person", confidence=0.9)
|
||||
assert entity.name == "John Doe"
|
||||
assert entity.entity_type == "person"
|
||||
assert entity.confidence == 0.9
|
||||
assert entity.mentions == []
|
||||
assert entity.metadata == {}
|
||||
|
||||
def test_extracted_relationship_dataclass(self):
|
||||
"""ExtractedRelationship dataclass works correctly."""
|
||||
from app.ai.knowledge_extraction import ExtractedRelationship
|
||||
|
||||
rel = ExtractedRelationship(
|
||||
source_entity="John Doe", source_type="person",
|
||||
target_entity="Acme Corp", target_type="company",
|
||||
relationship_type="works_for", confidence=0.85,
|
||||
evidence="John works at Acme",
|
||||
)
|
||||
assert rel.source_entity == "John Doe"
|
||||
assert rel.relationship_type == "works_for"
|
||||
assert rel.confidence == 0.85
|
||||
assert rel.evidence == "John works at Acme"
|
||||
|
||||
def test_extraction_result_dataclass(self):
|
||||
"""ExtractionResult dataclass works correctly."""
|
||||
from app.ai.knowledge_extraction import ExtractionResult
|
||||
|
||||
result = ExtractionResult(source_type="wiki", source_id="abc", tenant_id="123")
|
||||
assert result.entities == []
|
||||
assert result.relationships == []
|
||||
assert result.overall_confidence == 0.0
|
||||
|
||||
def test_is_low_confidence(self):
|
||||
"""is_low_confidence correctly identifies low confidence scores."""
|
||||
from app.ai.knowledge_extraction import is_low_confidence, LOW_CONFIDENCE_THRESHOLD
|
||||
|
||||
assert is_low_confidence(0.3) is True
|
||||
assert is_low_confidence(0.5) is True
|
||||
assert is_low_confidence(0.59) is True
|
||||
assert is_low_confidence(0.6) is False
|
||||
assert is_low_confidence(0.9) is False
|
||||
assert LOW_CONFIDENCE_THRESHOLD == 0.6
|
||||
|
||||
def test_filter_high_confidence(self):
|
||||
"""filter_high_confidence splits relationships correctly."""
|
||||
from app.ai.knowledge_extraction import filter_high_confidence, ExtractedRelationship
|
||||
|
||||
rels = [
|
||||
ExtractedRelationship("A", "person", "B", "company", "works_for", 0.9),
|
||||
ExtractedRelationship("C", "person", "D", "company", "related_to", 0.3),
|
||||
ExtractedRelationship("E", "person", "F", "company", "knows", 0.7),
|
||||
ExtractedRelationship("G", "person", "H", "company", "met", 0.5),
|
||||
]
|
||||
high, low = filter_high_confidence(rels)
|
||||
assert len(high) == 2 # 0.9 and 0.7
|
||||
assert len(low) == 2 # 0.3 and 0.5
|
||||
assert high[0].confidence == 0.9
|
||||
assert high[1].confidence == 0.7
|
||||
|
||||
def test_filter_high_confidence_custom_threshold(self):
|
||||
"""filter_high_confidence respects custom threshold."""
|
||||
from app.ai.knowledge_extraction import filter_high_confidence, ExtractedRelationship
|
||||
|
||||
rels = [
|
||||
ExtractedRelationship("A", "person", "B", "company", "works_for", 0.8),
|
||||
ExtractedRelationship("C", "person", "D", "company", "related_to", 0.7),
|
||||
]
|
||||
high, low = filter_high_confidence(rels, threshold=0.75)
|
||||
assert len(high) == 1 # 0.8
|
||||
assert len(low) == 1 # 0.7
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_extract_knowledge_empty_text(self):
|
||||
"""extract_knowledge returns empty result for empty text."""
|
||||
from app.ai.knowledge_extraction import extract_knowledge
|
||||
|
||||
result = await extract_knowledge("", uuid.uuid4())
|
||||
assert result.entities == []
|
||||
assert result.relationships == []
|
||||
assert result.overall_confidence == 0.0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_extract_knowledge_short_text(self):
|
||||
"""extract_knowledge returns empty result for very short text."""
|
||||
from app.ai.knowledge_extraction import extract_knowledge
|
||||
|
||||
result = await extract_knowledge("Hi", uuid.uuid4())
|
||||
assert result.entities == []
|
||||
assert result.relationships == []
|
||||
|
||||
Reference in New Issue
Block a user