diff --git a/agent/transports/chat_completions.py b/agent/transports/chat_completions.py index 7edb69e42c7..ed5d8b0ba43 100644 --- a/agent/transports/chat_completions.py +++ b/agent/transports/chat_completions.py @@ -122,7 +122,11 @@ class ChatCompletionsTransport(ProviderTransport): for msg in messages: if not isinstance(msg, dict): continue - if "codex_reasoning_items" in msg or "codex_message_items" in msg: + if ( + "codex_reasoning_items" in msg + or "codex_message_items" in msg + or "tool_name" in msg + ): needs_sanitize = True break tool_calls = msg.get("tool_calls") @@ -145,6 +149,7 @@ class ChatCompletionsTransport(ProviderTransport): continue msg.pop("codex_reasoning_items", None) msg.pop("codex_message_items", None) + msg.pop("tool_name", None) tool_calls = msg.get("tool_calls") if isinstance(tool_calls, list): for tc in tool_calls: diff --git a/tests/agent/transports/test_chat_completions.py b/tests/agent/transports/test_chat_completions.py index 7ed0d4da634..2e7b9da2f8d 100644 --- a/tests/agent/transports/test_chat_completions.py +++ b/tests/agent/transports/test_chat_completions.py @@ -46,6 +46,26 @@ class TestChatCompletionsBasic: assert "codex_reasoning_items" in msgs[0] assert "codex_message_items" in msgs[0] + def test_convert_messages_strips_tool_name(self, transport): + """Internal `tool_name` (used for FTS indexing in the SQLite store) is + not part of the OpenAI Chat Completions schema. Strict providers like + Moonshot/Kimi reject it with HTTP 400 'Extra inputs are not permitted'. + """ + msgs = [ + {"role": "user", "content": "hi"}, + {"role": "assistant", "content": None, + "tool_calls": [{"id": "call_1", "type": "function", + "function": {"name": "execute_code", "arguments": "{}"}}]}, + {"role": "tool", "tool_call_id": "call_1", "tool_name": "execute_code", + "content": "result"}, + ] + result = transport.convert_messages(msgs) + assert "tool_name" not in result[2] + assert result[2]["content"] == "result" + assert result[2]["tool_call_id"] == "call_1" + # Original list untouched (deepcopy-on-demand) + assert msgs[2]["tool_name"] == "execute_code" + class TestChatCompletionsBuildKwargs: