diff --git a/agent/agent_runtime_helpers.py b/agent/agent_runtime_helpers.py index b777e80f69..dda9f03686 100644 --- a/agent/agent_runtime_helpers.py +++ b/agent/agent_runtime_helpers.py @@ -604,7 +604,7 @@ def _merge_consecutive_users(messages: List[Dict]) -> Tuple[List[Dict], int]: # The clean-text persist override must replace only the absorbed turn, never the # unanswered text before it; kept across replay passes (an empty turn absorbs too). if prev_content: - prev[MERGED_TURN_PREFIX] = prev_content + "\n\n" if new_content else prev_content + prev[MERGED_TURN_PREFIX] = prev_content # Merged content invalidates the api_content sidecar; drop it so replay cannot use stale bytes. drop_stale_api_content(prev) # Pop the persist marker only when the durable row actually changed: a merge that diff --git a/agent/session_persistence.py b/agent/session_persistence.py index 8835e6d79d..680eedf76b 100644 --- a/agent/session_persistence.py +++ b/agent/session_persistence.py @@ -80,11 +80,12 @@ def _override_replaces_content(msg: Dict, content: Any, override: Any) -> bool: def _content_with_turn_override(msg: Dict, content: Any, override: Any) -> Any: - """Replace only the absorbed current turn, leaving unanswered history intact.""" + """Replace only the absorbed current turn, leaving unanswered history intact. The join matches + ``_merge_consecutive_users``; a row that no longer holds the prefix takes the plain override.""" prefix = msg.get(MERGED_TURN_PREFIX) if isinstance(content, str) and isinstance(override, str) and isinstance(prefix, str): - if content.startswith(prefix): - return prefix + override + if content == prefix or content.startswith(prefix + "\n\n"): + return prefix + "\n\n" + override if override else prefix return override