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 <noreply@anthropic.com>
This commit is contained in:
parent
fc8ade3c03
commit
c7811fa774
@ -189,11 +189,17 @@ class SWEAgenticEnvironment(Environment):
|
|||||||
total_usage = total_usage + out.usage
|
total_usage = total_usage + out.usage
|
||||||
text = out.text or ''
|
text = out.text or ''
|
||||||
if SENTINEL in text:
|
if SENTINEL in text:
|
||||||
# payload after the sentinel echo = `cat patch.txt` output.
|
# the model MENTIONED the sentinel in prose OR ran it.
|
||||||
# A unified diff must end with a newline; a stripped
|
# Never split on the mention -- the model discusses the
|
||||||
# payload fails git apply with 'corrupt patch at line N'
|
# command and that chatter became the "patch" (145B of
|
||||||
patch = text.split(SENTINEL, 1)[1].strip() + '\n'
|
# conversational English). Read the ACTUAL file the agent
|
||||||
break
|
# 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:
|
if out.tool_calls:
|
||||||
messages.append(ChatMessage(role='assistant', content=text))
|
messages.append(ChatMessage(role='assistant', content=text))
|
||||||
for tc in out.tool_calls:
|
for tc in out.tool_calls:
|
||||||
@ -203,8 +209,12 @@ class SWEAgenticEnvironment(Environment):
|
|||||||
role='user',
|
role='user',
|
||||||
content=f"exit={res['exit']}\n{res['out']}"))
|
content=f"exit={res['exit']}\n{res['out']}"))
|
||||||
if SENTINEL in res['out']:
|
if SENTINEL in res['out']:
|
||||||
# sentinel appeared in command output: capture patch
|
# sentinel in command output: the `cat patch.txt`
|
||||||
patch = res['out'].split(SENTINEL, 1)[1].strip() + '\n'
|
# 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:
|
else:
|
||||||
# no tool call: nudge per protocol
|
# no tool call: nudge per protocol
|
||||||
messages.append(ChatMessage(role='assistant', content=text))
|
messages.append(ChatMessage(role='assistant', content=text))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user