from __future__ import annotations import json from pathlib import Path from relay.conversation import RECENT_TURNS_KEPT, Conversation, render_for_log def test_append_and_read_back(tmp_path: Path) -> None: convo = Conversation(tmp_path / "c.json") convo.append("user", "hello", session_id="session-1") convo.append("assistant", "hi back") assert [t.role for t in convo.turns] == ["user", "assistant"] persisted = json.loads((tmp_path / "c.json").read_text()) assert persisted[0]["session_id"] == "session-1" def test_total_chars_sums_content(tmp_path: Path) -> None: convo = Conversation(tmp_path / "c.json") convo.append("user", "abc") convo.append("assistant", "defg") assert convo.total_chars() == 7 def test_needs_summarization_threshold(tmp_path: Path) -> None: convo = Conversation(tmp_path / "c.json") convo.append("user", "x" * 100) assert not convo.needs_summarization(200) assert convo.needs_summarization(50) def test_replace_with_summary_keeps_recent_turns(tmp_path: Path) -> None: convo = Conversation(tmp_path / "c.json") for i in range(RECENT_TURNS_KEPT + 5): convo.append("user", f"u{i}") convo.append("assistant", f"a{i}") convo.replace_with_summary("SUMMARY") assert convo.turns[0].role == "assistant" assert convo.turns[0].content == "SUMMARY" assert convo.turns[0].meta == "summary" # 1 summary + RECENT_TURNS_KEPT verbatim assert len(convo.turns) == 1 + RECENT_TURNS_KEPT def test_replace_with_summary_persists(tmp_path: Path) -> None: convo = Conversation(tmp_path / "c.json") for i in range(20): convo.append("user", f"u{i}") convo.replace_with_summary("S") reloaded = Conversation(tmp_path / "c.json") assert reloaded.turns[0].content == "S" def test_to_api_messages_strips_metadata(tmp_path: Path) -> None: convo = Conversation(tmp_path / "c.json") convo.append("user", "x", session_id="s1") convo.append("assistant", "y") msgs = convo.to_api_messages() assert msgs == [{"role": "user", "content": "x"}, {"role": "assistant", "content": "y"}] def test_render_for_log_truncates_long_content(tmp_path: Path) -> None: convo = Conversation(tmp_path / "c.json") convo.append("user", "a" * 1000) rendered = render_for_log(convo.turns[0], max_chars=50) assert len(rendered["content"]) < 100 assert "more chars" in rendered["content"]