fix(codex): keep transport echoes out of durable user history
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>
This commit is contained in:
@@ -419,7 +419,15 @@ def _persist_projected_messages(agent, turn, messages: List[Dict[str, Any]]) ->
|
||||
if not turn.projected_messages:
|
||||
return
|
||||
from agent.message_metadata import append_message
|
||||
for projected_message in turn.projected_messages:
|
||||
projected_messages = turn.projected_messages
|
||||
# Turn-start persistence owns the accepted input. Codex's leading user item
|
||||
# only echoes its coerced wire text; later/nonmatching events remain real.
|
||||
submitted_user_text = getattr(turn, "submitted_user_text", None)
|
||||
first = projected_messages[0]
|
||||
if (submitted_user_text is not None and first.get("role") == "user"
|
||||
and first.get("content") == submitted_user_text):
|
||||
projected_messages = projected_messages[1:]
|
||||
for projected_message in projected_messages:
|
||||
append_message(messages, projected_message)
|
||||
if getattr(agent, "_session_db", None) is None:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user