From cdac150ec3a6eea7fd95dbe08fadc1009fea3a4e Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sat, 19 Sep 2026 01:20:46 -0700 Subject: [PATCH] fix: recognise discourse-marker lead-ins before a leaked shell-JSON call MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'Next, I'll create the script.' / 'First, let me check the directory.' / 'Okay — running the tests.' followed by a closing {"cmd": ...} object were not classified as leaked tool calls because the lead-in pattern anchored the action verb at line start. Allow an optional Next/First/Then/Okay/OK/Alright marker (with comma/dash) before the existing prefixes; the 'closes the message' and 'cmd' key constraints are unchanged, so bare/explained JSON answers still pass through (#56920). --- agent/codex_responses_adapter.py | 3 ++- tests/agent/test_codex_responses_adapter.py | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/agent/codex_responses_adapter.py b/agent/codex_responses_adapter.py index d28d401cbd..a23d2a8ed1 100644 --- a/agent/codex_responses_adapter.py +++ b/agent/codex_responses_adapter.py @@ -67,7 +67,8 @@ _SHELL_JSON_LEAK_PATTERN = re.compile( ) _ACTION_VERBS = r"creat(?:e|ing)|writ(?:e|ing)|runn?(?:ing)?|execut(?:e|ing)|check(?:ing)?|verif(?:y|ying)|updat(?:e|ing)|install(?:ing)?|edit(?:ing)?|mak(?:e|ing)" _SHELL_JSON_LEAK_LEADIN_PATTERN = re.compile( - rf"^(?:sure,\s*)?(?:now\s+)?(?:let\s+me\s+|i(?:'|’)?ll\s+|i\s+will\s+|i(?:'|’)?m\s+|i\s+am\s+)?(?:{_ACTION_VERBS})\b", + rf"^(?:(?:next|first|then|okay|ok|alright)\b[\s,—–-]*)?(?:sure,\s*)?(?:now\s+)?" + rf"(?:let\s+me\s+|i(?:'|’)?ll\s+|i\s+will\s+|i(?:'|’)?m\s+|i\s+am\s+)?(?:{_ACTION_VERBS})\b", re.IGNORECASE, ) diff --git a/tests/agent/test_codex_responses_adapter.py b/tests/agent/test_codex_responses_adapter.py index add8e68596..1f773efc35 100644 --- a/tests/agent/test_codex_responses_adapter.py +++ b/tests/agent/test_codex_responses_adapter.py @@ -837,6 +837,8 @@ def _final_text_response(text): @pytest.mark.parametrize("text", [ 'Creating the PowerShell script now.\n{"cmd": "mkdir -p /c/Temp && cat > /c/Temp/x.ps1 <<\'EOF\'"}', 'Sure, let me run the tests.\n{"cmd": "pytest -q", "workdir": "/repo", "timeout": 120}', + 'Next, I\'ll create the script.\n{"cmd": "cat > x.sh"}', + 'Okay — running the tests.\n{"cmd": "pytest -q"}', "Calling tool now to=functions.terminal {\"command\": \"ls\"}", ]) def test_normalize_codex_response_treats_leaked_tool_call_text_as_incomplete(text):