refactor(agent): share the hidden interrupt placeholder row

message_sanitization.close_interrupted_tool_sequence and the
turn_api_call repetition-loop exit each spelled the same hidden
assistant row literal (content "", display_kind hidden, api_content
_INTERRUPTED_PLACEHOLDER), and the conversation loop's redirect built it
field by field. Add hidden_interrupt_placeholder_row() to the leaf
placeholders module and use it at all three sites so the shape cannot
drift between them.

Gate rP finding 6 (reuse).
This commit is contained in:
kshitijk4poor
2026-10-07 17:16:36 +05:30
committed by kshitij
parent 7c493cd2a1
commit 714fc8071c
4 changed files with 14 additions and 21 deletions

View File

@@ -18,3 +18,9 @@ _INTERRUPTED_PLACEHOLDER = "[interrupt: no assistant output for this turn]"
# The spelling shipped before #132949. Models reproduce it verbatim, so rows already carrying it
# stay poisoned after the wording change; the replay filters reference this name to retire them.
_LEGACY_INTERRUPTED_PLACEHOLDER = "[response interrupted]"
def hidden_interrupt_placeholder_row() -> dict:
"""A fresh assistant row that is invisible in transcripts but carries the placeholder as its
non-empty ``api_content``, so the pre-call sanitizer does not re-heal it every call (#88955)."""
return {"role": "assistant", "content": "", "display_kind": "hidden", "api_content": _INTERRUPTED_PLACEHOLDER}

View File

@@ -343,15 +343,10 @@ def _apply_active_turn_redirect(agent: Any, messages: List[Dict[str, Any]], text
# preserves alternation only — scaffold bytes must never land in it, since api_content
# is substituted back into content on replay (#81841).
if not (messages and messages[-1].get("role") == "assistant"):
placeholder: Dict[str, Any] = {"role": "assistant", "content": visible or ""}
if not visible:
placeholder["display_kind"] = "hidden"
# Hidden row, but a non-empty neutral api_content so the pre-call sanitizer
# does not re-heal it every call (#88955). Never _INTERRUPT_SCAFFOLD_MARKER:
# as assistant text the model echoes it (#81841).
from agent.agent_runtime_helpers_placeholders import _INTERRUPTED_PLACEHOLDER
placeholder["api_content"] = _INTERRUPTED_PLACEHOLDER
append_message(messages, placeholder)
# Hidden row with a neutral api_content (#88955). Never _INTERRUPT_SCAFFOLD_MARKER:
# as assistant text the model echoes it (#81841).
from agent.agent_runtime_helpers_placeholders import hidden_interrupt_placeholder_row
append_message(messages, {"role": "assistant", "content": visible} if visible else hidden_interrupt_placeholder_row())
# Transcript shows the user's own words; the provider replays the scaffolded form.
append_message(messages, {"role": "user", "content": text, "api_content": correction})

View File

@@ -302,16 +302,11 @@ def close_interrupted_tool_sequence(messages: list, final_response: Any = None)
return False
text = final_response if isinstance(final_response, str) else ""
from agent.message_metadata import append_message
from agent.agent_runtime_helpers_placeholders import _INTERRUPTED_PLACEHOLDER
from agent.agent_runtime_helpers_placeholders import _INTERRUPTED_PLACEHOLDER, hidden_interrupt_placeholder_row
stripped = text.strip()
if not stripped or stripped == _INTERRUPTED_PLACEHOLDER:
append_message(messages, {
"role": "assistant",
"content": "",
"display_kind": "hidden",
"api_content": _INTERRUPTED_PLACEHOLDER,
})
append_message(messages, hidden_interrupt_placeholder_row())
else:
append_message(messages, {"role": "assistant", "content": stripped})
return True

View File

@@ -15,7 +15,7 @@ import time
from typing import Any, Dict, Optional
from agent.error_classifier import FailoverReason
from agent.agent_runtime_helpers_placeholders import _INTERRUPTED_PLACEHOLDER
from agent.agent_runtime_helpers_placeholders import hidden_interrupt_placeholder_row
from agent.message_metadata import append_message
from agent.repetition_guard import REPETITION_LOOP_INTERRUPTED, is_runaway_repetition
from agent.turn_failure_copy import site_copy, stamp_failure
@@ -198,10 +198,7 @@ def handle_api_interrupt(
# The interrupted row is replayed next turn; looped bytes there re-seed the loop
# (#112764). Same hidden shape as the redirect placeholder: nothing visible in the
# transcript, a neutral api_content so the pre-call sanitizer does not re-heal it.
append_message(messages, {
"role": "assistant", "content": "", "display_kind": "hidden",
"api_content": _INTERRUPTED_PLACEHOLDER,
})
append_message(messages, hidden_interrupt_placeholder_row())
final_response = REPETITION_LOOP_INTERRUPTED
elif _partial:
append_message(messages, {