mirror of
https://github.com/deepset-ai/haystack.git
synced 2026-10-12 02:12:50 +00:00
fix: handle empty or missing tool-call arguments in from_openai_dict_format (#11972)
Co-authored-by: Claude Opus 4.8 <[email protected]> Co-authored-by: bogdankostic <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
bogdankostic
parent
64fb0d2010
commit
79c79ff7bb
@@ -804,10 +804,13 @@ class ChatMessage:
|
||||
if tool_calls:
|
||||
haystack_tool_calls = []
|
||||
for tc in tool_calls:
|
||||
# Zero-argument tool calls from OpenAI-compatible servers may send an
|
||||
# empty string, null, or omit `arguments` entirely; treat all as {}.
|
||||
raw_arguments = tc["function"].get("arguments")
|
||||
haystack_tc = ToolCall(
|
||||
id=tc.get("id"),
|
||||
tool_name=tc["function"]["name"],
|
||||
arguments=json.loads(tc["function"]["arguments"]),
|
||||
arguments=json.loads(raw_arguments) if raw_arguments else {},
|
||||
)
|
||||
haystack_tool_calls.append(haystack_tc)
|
||||
return cls.from_assistant(text=content, name=name, tool_calls=haystack_tool_calls)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
Fixed ``ChatMessage.from_openai_dict_format`` crashing on zero-argument tool
|
||||
calls. OpenAI-compatible servers (vLLM, llama.cpp, Ollama, LM Studio, ...) may
|
||||
send an empty string or omit the ``arguments`` field for a tool call that takes
|
||||
no arguments; this previously raised ``json.JSONDecodeError`` or ``KeyError``.
|
||||
Such tool calls are now parsed into a ``ToolCall`` with empty ``arguments``.
|
||||
@@ -1047,6 +1047,28 @@ class TestFromOpenaiDictFormat:
|
||||
assert tool_call.tool_name == "get_weather"
|
||||
assert tool_call.arguments == {"location": "Berlin"}
|
||||
|
||||
def test_from_openai_dict_format_tool_call_with_empty_arguments(self):
|
||||
# OpenAI-compatible servers (vLLM, llama.cpp, Ollama, ...) emit an empty
|
||||
# string for a zero-argument tool call; it must not crash.
|
||||
openai_msg = {
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [{"id": "call_1", "function": {"name": "now", "arguments": ""}}],
|
||||
}
|
||||
message = ChatMessage.from_openai_dict_format(openai_msg)
|
||||
assert message.tool_call == ToolCall(id="call_1", tool_name="now", arguments={})
|
||||
|
||||
def test_from_openai_dict_format_tool_call_with_missing_arguments(self):
|
||||
# Some servers omit the `arguments` key entirely for zero-argument calls.
|
||||
openai_msg = {
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [{"id": "call_1", "function": {"name": "now"}}],
|
||||
}
|
||||
message = ChatMessage.from_openai_dict_format(openai_msg)
|
||||
assert message.tool_call is not None
|
||||
assert message.tool_call.arguments == {}
|
||||
|
||||
def test_from_openai_dict_format_tool_message(self):
|
||||
openai_msg = {"role": "tool", "content": "The weather is sunny", "tool_call_id": "call_123"}
|
||||
message = ChatMessage.from_openai_dict_format(openai_msg)
|
||||
|
||||
Reference in New Issue
Block a user