From c7811fa774baaa3ee703bc20169de70e71a3b3ba Mon Sep 17 00:00:00 2001 From: sora <2075279110@qq.com> Date: Fri, 18 Sep 2026 10:35:39 +0000 Subject: [PATCH] swe_agentic: sentinel patch from container file, not text split The model DISCUSSES the sentinel command in prose; splitting on the first occurrence captured conversational English as the 'patch' (145B of chatter instead of the diff). On sentinel detection we now read /testbed/patch.txt directly from the container -- the file the agent actually created. Empty/missing file falls through to git diff. Co-Authored-By: Claude --- evalharness/agent/envs/swe_agentic.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/evalharness/agent/envs/swe_agentic.py b/evalharness/agent/envs/swe_agentic.py index 3700ecd..5ee0245 100644 --- a/evalharness/agent/envs/swe_agentic.py +++ b/evalharness/agent/envs/swe_agentic.py @@ -189,11 +189,17 @@ class SWEAgenticEnvironment(Environment): total_usage = total_usage + out.usage text = out.text or '' if SENTINEL in text: - # payload after the sentinel echo = `cat patch.txt` output. - # A unified diff must end with a newline; a stripped - # payload fails git apply with 'corrupt patch at line N' - patch = text.split(SENTINEL, 1)[1].strip() + '\n' - break + # the model MENTIONED the sentinel in prose OR ran it. + # Never split on the mention -- the model discusses the + # command and that chatter became the "patch" (145B of + # conversational English). Read the ACTUAL file the agent + # created in the container. + r3 = await asyncio.to_thread( + self._exec, 'cat /testbed/patch.txt') + if r3['exit'] == 0 and r3['out'].strip(): + patch = r3['out'].strip() + '\n' + break + # patch.txt empty/missing: keep looping, git-diff at end if out.tool_calls: messages.append(ChatMessage(role='assistant', content=text)) for tc in out.tool_calls: @@ -203,8 +209,12 @@ class SWEAgenticEnvironment(Environment): role='user', content=f"exit={res['exit']}\n{res['out']}")) if SENTINEL in res['out']: - # sentinel appeared in command output: capture patch - patch = res['out'].split(SENTINEL, 1)[1].strip() + '\n' + # sentinel in command output: the `cat patch.txt` + # already ran -- read the actual file + r2 = await asyncio.to_thread( + self._exec, 'cat /testbed/patch.txt') + if r2['exit'] == 0 and r2['out'].strip(): + patch = r2['out'].strip() + '\n' else: # no tool call: nudge per protocol messages.append(ChatMessage(role='assistant', content=text))