134 lines
5.1 KiB
Python
134 lines
5.1 KiB
Python
"""
|
|
Recollection rendering tests — hit path, zero-hit path, pending-conflict marker,
|
|
and prompt injection position.
|
|
"""
|
|
import pytest
|
|
from festinger import cache
|
|
from festinger.recollection import (
|
|
query_edges, render_hit, render_zero_hit,
|
|
build_recollection_block, inject_recollection,
|
|
)
|
|
from tests.helpers import reset_cache, add_soas, add_urd
|
|
|
|
|
|
class TestHitPath:
|
|
|
|
def setup_method(self):
|
|
reset_cache()
|
|
self.michigan = add_soas(101, "michigan", saliency=1.5)
|
|
self.usa = add_soas(102, "usa", saliency=0.8)
|
|
self.geography = add_soas(5, "geography", saliency=0.0)
|
|
self.state = add_soas(103, "state", saliency=0.7)
|
|
self.type_dim = add_soas(1, "type", saliency=0.0)
|
|
|
|
add_urd(concept_id=101, parent_id=102, dim_id=5, is_isa=False, confidence=0.9)
|
|
add_urd(concept_id=101, parent_id=103, dim_id=1, is_isa=True, confidence=0.9)
|
|
|
|
def test_query_returns_both_edges(self):
|
|
edges = query_edges(101, confidence_floor=0.5, recency_days=90)
|
|
assert len(edges) == 2
|
|
|
|
def test_render_hit_format(self):
|
|
edges = query_edges(101, confidence_floor=0.5, recency_days=90)
|
|
line = render_hit("michigan", edges, concept_id=101)
|
|
assert line.startswith("michigan:")
|
|
assert "[geography] usa" in line
|
|
assert "[type] state" in line
|
|
|
|
def test_pending_conflict_adds_question_mark(self):
|
|
cache.pending_conflicts.add(101)
|
|
edges = query_edges(101, confidence_floor=0.5, recency_days=90)
|
|
line = render_hit("michigan", edges, concept_id=101)
|
|
# All dim labels should have ? when concept has pending conflict
|
|
assert "[geography?]" in line or "[type?]" in line
|
|
|
|
def test_confidence_floor_filters_edges(self):
|
|
# Add a low-confidence edge
|
|
add_urd(concept_id=101, parent_id=5, dim_id=5, is_isa=False, confidence=0.2)
|
|
edges = query_edges(101, confidence_floor=0.6, recency_days=90)
|
|
# Should not include the 0.2 confidence edge
|
|
low_conf = [e for e in edges if e.confidence < 0.6]
|
|
assert low_conf == []
|
|
|
|
def test_block_contains_recollection_tags(self):
|
|
block = build_recollection_block([101], confidence_floor=0.5, recency_days=90)
|
|
assert block is not None
|
|
assert block.startswith("<recollection>")
|
|
assert block.endswith("</recollection>")
|
|
|
|
|
|
class TestZeroHitPath:
|
|
|
|
def setup_method(self):
|
|
reset_cache()
|
|
add_soas(201, "ramanujan", saliency=1.5)
|
|
# No URD edges for ramanujan
|
|
|
|
def test_zero_hit_render(self):
|
|
line = render_zero_hit("ramanujan")
|
|
assert "ramanujan" in line
|
|
assert "no recollection" in line
|
|
assert "gutask iknowthat" in line
|
|
|
|
def test_zero_hit_in_block(self):
|
|
block = build_recollection_block([201], confidence_floor=0.5, recency_days=90)
|
|
assert block is not None
|
|
assert "? ramanujan" in block
|
|
assert "gutask iknowthat" in block
|
|
|
|
def test_block_is_none_when_no_salient_concepts(self):
|
|
block = build_recollection_block([], confidence_floor=0.5, recency_days=90)
|
|
assert block is None
|
|
|
|
|
|
class TestPromptInjection:
|
|
|
|
def setup_method(self):
|
|
reset_cache()
|
|
add_soas(101, "michigan", saliency=1.5)
|
|
add_soas(102, "usa", saliency=0.8)
|
|
add_soas(5, "geography", saliency=0.0)
|
|
add_urd(concept_id=101, parent_id=102, dim_id=5, is_isa=False, confidence=0.9)
|
|
|
|
def _block(self):
|
|
return build_recollection_block([101], confidence_floor=0.5, recency_days=90)
|
|
|
|
def test_injected_into_existing_system_message(self):
|
|
messages = [
|
|
{"role": "system", "content": "You are a helpful assistant."},
|
|
{"role": "user", "content": "Tell me about michigan."},
|
|
]
|
|
block = self._block()
|
|
result = inject_recollection(messages, block)
|
|
|
|
system = next(m for m in result if m["role"] == "system")
|
|
assert system["content"].startswith("<recollection>")
|
|
assert "You are a helpful assistant." in system["content"]
|
|
|
|
def test_injected_at_position_0_when_no_system_message(self):
|
|
messages = [{"role": "user", "content": "Tell me about michigan."}]
|
|
block = self._block()
|
|
result = inject_recollection(messages, block)
|
|
|
|
assert result[0]["role"] == "system"
|
|
assert "<recollection>" in result[0]["content"]
|
|
assert result[1]["role"] == "user"
|
|
|
|
def test_original_messages_not_mutated(self):
|
|
original = [
|
|
{"role": "system", "content": "You are helpful."},
|
|
{"role": "user", "content": "michigan?"},
|
|
]
|
|
inject_recollection(original, self._block())
|
|
# Original list and dicts must be unchanged
|
|
assert original[0]["content"] == "You are helpful."
|
|
|
|
def test_user_message_preserved_after_injection(self):
|
|
messages = [
|
|
{"role": "system", "content": "System prompt."},
|
|
{"role": "user", "content": "michigan?"},
|
|
]
|
|
result = inject_recollection(messages, self._block())
|
|
user_msgs = [m for m in result if m["role"] == "user"]
|
|
assert user_msgs[0]["content"] == "michigan?"
|