From e54513ee12d378ef62dba170297775f7651f369b Mon Sep 17 00:00:00 2001 From: Joel Martin Date: Wed, 11 Jun 2025 23:54:04 +0000 Subject: [PATCH] Handle None in tool/function arguments. The normal OpenAI API returns an empty string when there are no function arguments. The GitHub Copilot wrapper around the OpenAI API seems to return None instead of an empty string when there are no arguments. Treat None as an empty string. If we still have an empty string at the point that we parse the JSON for the arguments, then use "{}" instead so that we get the expected empty map. --- llm/default_plugins/openai_models.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/llm/default_plugins/openai_models.py b/llm/default_plugins/openai_models.py index 4ec71000b..ae30fefb3 100644 --- a/llm/default_plugins/openai_models.py +++ b/llm/default_plugins/openai_models.py @@ -690,6 +690,8 @@ def execute(self, prompt, stream, response, conversation=None, key=None): usage = chunk.usage.model_dump() if chunk.choices and chunk.choices[0].delta: for tool_call in chunk.choices[0].delta.tool_calls or []: + if tool_call.function.arguments is None: + tool_call.function.arguments = "" index = tool_call.index if index not in tool_calls: tool_calls[index] = tool_call @@ -711,7 +713,7 @@ def execute(self, prompt, stream, response, conversation=None, key=None): llm.ToolCall( tool_call_id=value.id, name=value.function.name, - arguments=json.loads(value.function.arguments), + arguments=json.loads(value.function.arguments or "{}"), ) ) else: @@ -728,7 +730,7 @@ def execute(self, prompt, stream, response, conversation=None, key=None): llm.ToolCall( tool_call_id=tool_call.id, name=tool_call.function.name, - arguments=json.loads(tool_call.function.arguments), + arguments=json.loads(tool_call.function.arguments or "{}"), ) ) if completion.choices[0].message.content is not None: @@ -774,6 +776,8 @@ async def execute( usage = chunk.usage.model_dump() if chunk.choices and chunk.choices[0].delta: for tool_call in chunk.choices[0].delta.tool_calls or []: + if tool_call.function.arguments is None: + tool_call.function.arguments = "" index = tool_call.index if index not in tool_calls: tool_calls[index] = tool_call @@ -794,7 +798,7 @@ async def execute( llm.ToolCall( tool_call_id=value.id, name=value.function.name, - arguments=json.loads(value.function.arguments), + arguments=json.loads(value.function.arguments or "{}"), ) ) response.response_json = remove_dict_none_values(combine_chunks(chunks)) @@ -812,7 +816,7 @@ async def execute( llm.ToolCall( tool_call_id=tool_call.id, name=tool_call.function.name, - arguments=json.loads(tool_call.function.arguments), + arguments=json.loads(tool_call.function.arguments or "{}"), ) ) if completion.choices[0].message.content is not None: