Wire the guarded conversational RAG answer layer end-to-end

This commit is contained in:
2026-08-05 14:33:13 +07:00
parent 834d9e51b0
commit ef08b4929e
127 changed files with 37921 additions and 169 deletions
@@ -0,0 +1,50 @@
from rag.conversation import (
ConversationState,
DeterministicSummariser,
InMemoryConversationStore,
Turn,
)
def test_store_returns_fresh_state_for_unknown_id():
store = InMemoryConversationStore()
state = store.load("conv-new")
assert state.conversation_id == "conv-new"
assert state.turn_count == 0
assert state.recent == ()
def test_store_round_trips_saved_state():
store = InMemoryConversationStore()
state = ConversationState("conv-1", summary="s", turn_count=3)
store.save(state)
assert store.load("conv-1") is state
def test_summariser_records_topic_labels_only():
s = DeterministicSummariser()
dropped = (
Turn("user", "Chống chỉ định của metformin?", "t0",
drug_id="metformin", section_key="chong_chi_dinh"),
Turn("assistant", "Quá mẫn với metformin, suy thận Clcr < 60...", "t1",
drug_id="metformin", section_key="chong_chi_dinh"),
)
out = s.fold("", dropped)
# The label line is present...
assert "chong_chi_dinh của metformin" in out
# ...and no clinical value leaked from the assistant turn.
assert "Clcr" not in out
assert "60" not in out
def test_summariser_stays_within_budget_dropping_oldest():
s = DeterministicSummariser()
dropped = tuple(
Turn("user", f"q{i}", f"t{i}", drug_id=f"drug{i}", section_key="lieu_luong")
for i in range(400)
)
out = s.fold("", dropped)
assert len(out) <= DeterministicSummariser.MAX_CHARS
# Most-recent topic survives, oldest is dropped.
assert "drug399" in out
assert "drug0 " not in out