Skip to content

Commit 741ce5d

Browse files
authored
fix: OpenAIChatGenerator - do not pass tools to the OpenAI client when none are provided (#8702)
* do not pass tools to OpenAI client if None * release note * fix release note
1 parent 08cf09f commit 741ce5d

File tree

3 files changed

+19
-4
lines changed

3 files changed

+19
-4
lines changed

haystack/components/generators/chat/openai.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,13 @@ def _prepare_api_call( # noqa: PLR0913
286286
tools_strict = tools_strict if tools_strict is not None else self.tools_strict
287287
_check_duplicate_tool_names(tools)
288288

289-
openai_tools = None
289+
openai_tools = {}
290290
if tools:
291-
openai_tools = [
291+
tool_definitions = [
292292
{"type": "function", "function": {**t.tool_spec, **({"strict": tools_strict} if tools_strict else {})}}
293293
for t in tools
294294
]
295+
openai_tools = {"tools": tool_definitions}
295296

296297
is_streaming = streaming_callback is not None
297298
num_responses = generation_kwargs.pop("n", 1)
@@ -302,8 +303,8 @@ def _prepare_api_call( # noqa: PLR0913
302303
"model": self.model,
303304
"messages": openai_formatted_messages, # type: ignore[arg-type] # openai expects list of specific message types
304305
"stream": streaming_callback is not None,
305-
"tools": openai_tools, # type: ignore[arg-type]
306306
"n": num_responses,
307+
**openai_tools,
307308
**generation_kwargs,
308309
}
309310

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
fixes:
3+
- |
4+
OpenAIChatGenerator no longer passes tools to the OpenAI client if none are provided.
5+
Previously, a null value was passed.
6+
This change improves compatibility with OpenAI-compatible APIs that do not support tools.

test/components/generators/chat/test_openai.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ def test_run_with_params(self, chat_messages, openai_mock_chat_completion):
293293
assert kwargs["max_tokens"] == 10
294294
assert kwargs["temperature"] == 0.5
295295

296+
# check that the tools are not passed to the OpenAI API (the generator is initialized without tools)
297+
assert "tools" not in kwargs
298+
296299
# check that the component returns the correct response
297300
assert isinstance(response, dict)
298301
assert "replies" in response
@@ -400,9 +403,14 @@ def test_run_with_tools(self, tools):
400403

401404
mock_chat_completion_create.return_value = completion
402405

403-
component = OpenAIChatGenerator(api_key=Secret.from_token("test-api-key"), tools=tools)
406+
component = OpenAIChatGenerator(api_key=Secret.from_token("test-api-key"), tools=tools, tools_strict=True)
404407
response = component.run([ChatMessage.from_user("What's the weather like in Paris?")])
405408

409+
# ensure that the tools are passed to the OpenAI API
410+
assert mock_chat_completion_create.call_args[1]["tools"] == [
411+
{"type": "function", "function": {**tools[0].tool_spec, "strict": True}}
412+
]
413+
406414
assert len(response["replies"]) == 1
407415
message = response["replies"][0]
408416

0 commit comments

Comments
 (0)