Port the exact submitted-wire-text ownership boundary from #93546 onto current topical runtime code. Do not add the candidate's mocked-result fallback or storage-level content deduplication. Preserve later distinct and identical user events, separate identical accepted turns, and keyless inputs. Add two regression invariants and offline subprocess-wire A/B. Local wire A/B: 4/8 control matrix passing on base, 8/8 after. Broader tests queued behind campaign lock; not ready for merge. Refs #104653 Original diagnosis: @gitszabolcs (#38254) Original implementation: #43127, submitted by @vashkartik Focused salvage and wire-text correction: @fancyboi999 (#93546) Current-main carry-forward considered: #104698 Co-authored-by: Xinmin Zeng <135568692+fancyboi999@users.noreply.github.com> Co-authored-by: VECTOR <vector.hq@outlook.com>
51 lines
2.6 KiB
Python
51 lines
2.6 KiB
Python
"""The accepted input owns its row; transport echoes do not own new rows."""
|
|
import threading
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
from agent.codex_runtime import _persist_projected_messages
|
|
from agent.message_metadata import append_message
|
|
from agent.session_persistence import SessionPersistenceMixin
|
|
from agent.transports.codex_event_projector import CodexEventProjector
|
|
from hermes_state import SessionDB
|
|
|
|
|
|
@pytest.mark.parametrize("platform_id", ["2146", None])
|
|
@pytest.mark.parametrize("projection", ["echo", "assistant_only", "different", "later_equal"])
|
|
def test_only_submitted_leading_echo_is_excluded(tmp_path, platform_id, projection):
|
|
db = SessionDB(tmp_path / "state.db")
|
|
try:
|
|
db.create_session(session_id="echo", source="telegram", model="codex")
|
|
agent = SessionPersistenceMixin()
|
|
agent.session_id = "echo"
|
|
agent._session_db = db
|
|
agent._session_db_created = True
|
|
agent._last_flushed_db_idx = 0
|
|
agent._session_persist_lock = threading.RLock()
|
|
messages = []
|
|
# Two independently accepted identical inputs must both survive.
|
|
for turn_index in range(2):
|
|
append_message(messages, {"role": "user", "content": "accepted", "platform_message_id": platform_id})
|
|
assert agent._flush_messages_to_session_db(messages)
|
|
projector = CodexEventProjector()
|
|
items = []
|
|
if projection != "assistant_only":
|
|
items.append({"type": "userMessage", "id": f"u{turn_index}", "content": [
|
|
{"type": "text", "text": "different" if projection == "different" else "wire caption"}]})
|
|
items.append({"type": "agentMessage", "id": f"a{turn_index}", "text": "reply"})
|
|
if projection == "later_equal":
|
|
items.append({"type": "userMessage", "id": f"s{turn_index}", "content": [
|
|
{"type": "text", "text": "wire caption"}]})
|
|
projected = []
|
|
for item in items:
|
|
projected.extend(projector.project({"method": "item/completed", "params": {"item": item}}).messages)
|
|
_persist_projected_messages(agent, SimpleNamespace(
|
|
projected_messages=projected, submitted_user_text="wire caption"), messages)
|
|
assert agent._flush_messages_to_session_db(messages)
|
|
users = [row["content"] for row in db.get_messages_as_conversation("echo") if row["role"] == "user"]
|
|
extra = {"different": ["different"], "later_equal": ["wire caption"]}.get(projection, [])
|
|
assert users == (["accepted"] + extra) * 2
|
|
finally:
|
|
db.close()
|