From 6d3d9d0baf18291e5306691b35f81e5b2e0eecb3 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Tue, 7 Jul 2026 14:33:19 +0530 Subject: [PATCH] fix: drop timestamp in handle_max_iterations' hand-built api_messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gateway user replay entries now carry a timestamp (read by the stale-confirmation expiry check). The transports already sanitize it (#47868), but handle_max_iterations hand-builds api_messages and calls chat.completions.create() directly, bypassing the transport — a strict provider would 400 on the foreign key. Mirror the transport's pop here, alongside the existing tool_name/codex_* sanitization. --- agent/chat_completion_helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/agent/chat_completion_helpers.py b/agent/chat_completion_helpers.py index 4b000372b39..d2dc4745c03 100644 --- a/agent/chat_completion_helpers.py +++ b/agent/chat_completion_helpers.py @@ -1525,8 +1525,10 @@ def handle_max_iterations(agent, messages: list, api_call_count: int) -> str: # hand-builds messages and calls chat.completions.create() directly, # bypassing the transport — so mirror that sanitization here: # tool_name (SQLite FTS bookkeeping), the codex_* reasoning carriers, + # timestamp (preserved on gateway user replay entries for the + # stale-confirmation expiry check — #47868 rejection class), # and every Hermes-internal underscore-prefixed scaffolding key. - for schema_foreign in ("tool_name", "codex_reasoning_items", "codex_message_items"): + for schema_foreign in ("tool_name", "codex_reasoning_items", "codex_message_items", "timestamp"): api_msg.pop(schema_foreign, None) for internal_key in [k for k in api_msg if isinstance(k, str) and k.startswith("_")]: api_msg.pop(internal_key, None)