fix: preserve imported session lineage visibility
This commit is contained in:
1 parent
0ea3dfbdd1
commit
8b34a79f02
4 files changed
+173
-5
No files matched your search
@@ -90,6 +90,7 @@ def test_session_import_cli_refresh_matches_messages_despite_timestamp_type_diff
|
||||
self.raw_source = "weixin"
|
||||
self.session_source = "messaging"
|
||||
self.source_label = "WeChat"
|
||||
self.parent_session_id = None
|
||||
|
||||
def compact(self):
|
||||
return {"session_id": session_id, "title": "Imported"}
|
||||
@@ -141,6 +142,7 @@ def test_session_import_cli_refresh_rejects_prefix_if_non_timing_content_diverge
|
||||
self.session_source = "messaging"
|
||||
self.source_label = "Telegram"
|
||||
self.is_cli_session = True
|
||||
self.parent_session_id = None
|
||||
|
||||
def compact(self):
|
||||
return {"session_id": session_id, "title": "Imported"}
|
||||
@@ -169,3 +171,113 @@ def test_session_import_cli_refresh_rejects_prefix_if_non_timing_content_diverge
|
||||
assert response["session"]["messages"] == existing.messages
|
||||
assert existing.messages[0]["content"] == "old-prefix"
|
||||
assert save_calls == []
|
||||
|
||||
|
||||
def test_session_import_cli_preserves_parent_metadata_on_existing_import(monkeypatch):
|
||||
"""Refreshing an already-imported CLI session must persist lineage metadata."""
|
||||
import api.routes as routes
|
||||
|
||||
session_id = "existing_parent_lineage_001"
|
||||
parent_id = "root_parent_lineage_001"
|
||||
|
||||
class FakeSession:
|
||||
def __init__(self):
|
||||
self.messages = [{"role": "user", "content": "hello", "timestamp": 1.0}]
|
||||
self.source_tag = "telegram"
|
||||
self.raw_source = "telegram"
|
||||
self.session_source = "messaging"
|
||||
self.source_label = "Telegram"
|
||||
self.parent_session_id = None
|
||||
self.is_cli_session = True
|
||||
|
||||
def compact(self):
|
||||
return {"session_id": session_id, "title": "Imported", "parent_session_id": self.parent_session_id}
|
||||
|
||||
def save(self, touch_updated_at=False):
|
||||
save_calls.append(touch_updated_at)
|
||||
|
||||
save_calls = []
|
||||
existing = FakeSession()
|
||||
|
||||
monkeypatch.setattr(routes.Session, "load", classmethod(lambda _cls, sid: existing if sid == session_id else None))
|
||||
monkeypatch.setattr(routes, "require", lambda body, *keys: None)
|
||||
monkeypatch.setattr(routes, "j", lambda _handler, payload, status=200, extra_headers=None: payload)
|
||||
monkeypatch.setattr(routes, "get_cli_session_messages", lambda sid: existing.messages if sid == session_id else [])
|
||||
monkeypatch.setattr(
|
||||
routes,
|
||||
"get_cli_sessions",
|
||||
lambda: [{
|
||||
"session_id": session_id,
|
||||
"source_tag": "telegram",
|
||||
"raw_source": "telegram",
|
||||
"session_source": "messaging",
|
||||
"source_label": "Telegram",
|
||||
"parent_session_id": parent_id,
|
||||
}],
|
||||
)
|
||||
|
||||
response = routes._handle_session_import_cli(object(), {"session_id": session_id})
|
||||
|
||||
assert response["imported"] is False
|
||||
assert existing.parent_session_id == parent_id
|
||||
assert response["session"]["parent_session_id"] == parent_id
|
||||
assert save_calls == [False]
|
||||
|
||||
|
||||
def test_read_only_import_payload_includes_parent_session_id(monkeypatch):
|
||||
"""Read-only CLI/session imports should also expose lineage in the payload."""
|
||||
import api.routes as routes
|
||||
|
||||
session_id = "readonly_parent_lineage_001"
|
||||
parent_id = "readonly_root_lineage_001"
|
||||
messages = [{"role": "user", "content": "hello", "timestamp": 1.0}]
|
||||
|
||||
monkeypatch.setattr(routes.Session, "load", classmethod(lambda _cls, sid: None))
|
||||
monkeypatch.setattr(routes, "require", lambda body, *keys: None)
|
||||
monkeypatch.setattr(routes, "bad", lambda _handler, msg, status=400: {"ok": False, "error": msg, "status": status})
|
||||
monkeypatch.setattr(routes, "j", lambda _handler, payload, status=200, extra_headers=None: payload)
|
||||
monkeypatch.setattr(routes, "get_cli_session_messages", lambda sid: messages if sid == session_id else [])
|
||||
monkeypatch.setattr(
|
||||
routes,
|
||||
"get_cli_sessions",
|
||||
lambda: [{
|
||||
"session_id": session_id,
|
||||
"title": "Read-only child",
|
||||
"model": "test-model",
|
||||
"created_at": 1.0,
|
||||
"updated_at": 2.0,
|
||||
"source_tag": "discord",
|
||||
"raw_source": "discord",
|
||||
"session_source": "messaging",
|
||||
"source_label": "Discord",
|
||||
"parent_session_id": parent_id,
|
||||
"read_only": True,
|
||||
}],
|
||||
)
|
||||
|
||||
response = routes._handle_session_import_cli(object(), {"session_id": session_id})
|
||||
|
||||
assert response["imported"] is False
|
||||
assert response["session"]["parent_session_id"] == parent_id
|
||||
assert response["session"]["messages"] == messages
|
||||
|
||||
|
||||
def test_merge_cli_sidebar_metadata_keeps_larger_sidecar_message_count():
|
||||
"""Sidebar metadata merge should not shrink repaired aggregate sidecar counts."""
|
||||
import api.routes as routes
|
||||
|
||||
merged = routes._merge_cli_sidebar_metadata(
|
||||
{"session_id": "sid", "message_count": 535, "title": "Recovered"},
|
||||
{"session_id": "sid", "message_count": 407, "source_tag": "discord"},
|
||||
)
|
||||
|
||||
assert merged["message_count"] == 535
|
||||
|
||||
|
||||
def test_messaging_session_loader_prefers_longer_sidecar_transcript():
|
||||
"""Pin the /api/session invariant that repaired sidecars can be longer than state.db segments."""
|
||||
handler = _extract_handler("handle_get")
|
||||
old = "if is_messaging_session and cli_messages:\n _all_msgs = cli_messages"
|
||||
assert old not in handler
|
||||
assert "sidecar_messages = getattr(s, \"messages\", []) or []" in handler
|
||||
assert "len(sidecar_messages) > len(cli_messages)" in handler
|
||||
Reference in new issue
Block a user