mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-09-27 18:42:20 +02:00
Squash Odysseus development history
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
"""replace_messages must persist readable, path-free multimodal history.
|
||||
|
||||
Live model input may contain provider-specific media blocks and inline data
|
||||
URLs. Compaction uses replace_messages for the retained transcript, which must
|
||||
store readable text plus stable structured attachment references without
|
||||
copying raw base64 payloads into ChatMessage.content.
|
||||
"""
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
|
||||
import core.database as cdb
|
||||
from core.models import ChatMessage
|
||||
from tests.helpers.sqlite_db import make_temp_sqlite
|
||||
|
||||
_TS, _ENGINE, _TMPDB = make_temp_sqlite(cdb.Base.metadata)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def manager(monkeypatch):
|
||||
import core.session_manager as sm
|
||||
monkeypatch.setattr(sm, "SessionLocal", _TS)
|
||||
mgr = sm.SessionManager.__new__(sm.SessionManager)
|
||||
mgr.sessions = {}
|
||||
mgr.upload_handler = None
|
||||
return mgr
|
||||
|
||||
|
||||
def _make_session(sid, owner="alice"):
|
||||
db = _TS()
|
||||
try:
|
||||
db.add(cdb.Session(id=sid, owner=owner, name="chat", model="gpt-4o",
|
||||
endpoint_url="http://localhost:11434",
|
||||
archived=False, message_count=1))
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_multimodal_content_persists_text_and_attachment_ref_without_payload(manager):
|
||||
sid = "sess-" + uuid.uuid4().hex[:8]
|
||||
_make_session(sid)
|
||||
|
||||
upload_id = "a" * 32 + ".png"
|
||||
multimodal = [
|
||||
{"type": "text", "text": "what is this?"},
|
||||
{"type": "image_url", "image_url": {"url": "data:image/png;base64,AAAA"}},
|
||||
]
|
||||
msgs = [ChatMessage(
|
||||
role="user",
|
||||
content=multimodal,
|
||||
metadata={
|
||||
"attachments": [{
|
||||
"id": upload_id,
|
||||
"name": "diagram.png",
|
||||
"mime": "image/png",
|
||||
"size": 4,
|
||||
"checksum_sha256": "sha256-digest",
|
||||
}]
|
||||
},
|
||||
)]
|
||||
assert manager.replace_messages(sid, msgs) is True
|
||||
|
||||
expected = (
|
||||
"what is this?\n"
|
||||
"[1 inline media payload omitted]\n"
|
||||
f"[Attachment: diagram.png | id={upload_id} | mime=image/png | "
|
||||
"size=4 bytes | sha256=sha256-digest]"
|
||||
)
|
||||
|
||||
db = _TS()
|
||||
try:
|
||||
stored = db.query(cdb.ChatMessage).filter_by(session_id=sid).one()
|
||||
assert stored.content == expected
|
||||
assert "data:image/png;base64,AAAA" not in stored.content
|
||||
assert "base64" not in stored.content
|
||||
assert "AAAA" not in stored.content
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
# Drop the in-memory cache so the next read hydrates from the DB.
|
||||
manager.sessions.clear()
|
||||
reloaded = manager.get_session(sid)
|
||||
assert len(reloaded.history) == 1
|
||||
persisted = reloaded.history[0].content
|
||||
assert isinstance(persisted, str)
|
||||
assert persisted == expected
|
||||
assert reloaded.history[0].metadata["attachments"][0]["id"] == upload_id
|
||||
assert (
|
||||
reloaded.history[0].metadata["attachments"][0]["checksum_sha256"]
|
||||
== "sha256-digest"
|
||||
)
|
||||
|
||||
|
||||
def test_jsonlike_plain_string_content_still_round_trips(manager):
|
||||
sid = "sess-" + uuid.uuid4().hex[:8]
|
||||
_make_session(sid)
|
||||
text = '[{"type": "object", "name": "foo"}]'
|
||||
msgs = [ChatMessage(role="user", content=text)]
|
||||
assert manager.replace_messages(sid, msgs) is True
|
||||
manager.sessions.clear()
|
||||
reloaded = manager.get_session(sid)
|
||||
assert isinstance(reloaded.history[0].content, str)
|
||||
assert reloaded.history[0].content == text
|
||||
|
||||
|
||||
def test_replace_messages_keeps_history_alias_for_context_messages(manager):
|
||||
sid = "sess-" + uuid.uuid4().hex[:8]
|
||||
_make_session(sid)
|
||||
msgs = [ChatMessage(role="user", content="original")]
|
||||
assert manager.replace_messages(sid, msgs) is True
|
||||
|
||||
session = manager.sessions[sid]
|
||||
assert session.history is session._history
|
||||
|
||||
session.history.append(ChatMessage(role="user", content="after direct mutation"))
|
||||
assert session.get_context_messages()[-1]["content"] == "after direct mutation"
|
||||
Reference in New Issue
Block a user