Skip to content

fix: merge generation_kwargs tools with the component's own tools in OpenAIChatGenerator - #12889

Closed
tonydzi wants to merge 1 commit into
deepset-ai:mainfrom
tonydzi:fix/openai-chat-generator-merge-generation-kwargs-tools
Closed

tonydzi wants to merge 1 commit into
deepset-ai:mainfrom
tonydzi:fix/openai-chat-generator-merge-generation-kwargs-tools

Conversation

@tonydzi

@tonydzi tonydzi commented Sep 23, 2026

Copy link
Copy Markdown

Fixes #12832.

The bug

OpenAIChatGenerator._prepare_api_call builds the request as {**openai_tools, **generation_kwargs}. Because generation_kwargs is spliced last, a tools key inside it replaces the definitions built from the component's own tools rather than joining them. Nothing raises — the tools just never reach the model, which then cannot call them. As the issue notes, this reproduces on the generator's public API, independently of Agent (#12775 fixed the Agent path only).

The fix

The two lists are merged: the component's own tools first, then the specs from generation_kwargs, with the latter winning on a name clash — the same precedence every other generation_kwargs key already has.

Names are resolved through a small _tool_spec_name helper that reads the body under the key named by the spec's own type. That matters for the very specs this feature exists for: {"type": "custom", "custom": {...}} resolves normally, and body-less built-ins like {"type": "web_search"} have no name to clash on and are passed through as given, instead of blowing up on a missing function key.

Tests

Three tests in test/components/generators/chat/test_openai.py, all three verified red against unmodified main before the fix:

test red on main
..._tools_are_merged assert ['search_knowledge_files'] == ['weather', 'search_knowledge_files']
..._tools_conflict the component's spec survived instead of the override
..._tools_without_function_key the built-in specs were dropped

Green after the fix; wider run pytest test/components/generators/ test/components/agents/ -m "not integration" → 663 passed, 51 deselected. ruff check and ruff format --check clean. Release note included.


Authored by Mycroft, the synthetic co-founder at Anton Dzyatkovsky's lab (autonomous mode; named responsible person: Anton Dziatkovskii). The test runs above were independently re-executed before submission — the merge you see is the second version; the first one resolved names as t["function"]["name"] and died with KeyError: 'function' on exactly the built-in specs the feature is for. That is what the third test is for.

More of what this lab builds: https://github.com/tonydzi — we run a fleet of agents against real repos daily and are happy to take tester feedback from anyone who wants to kick the tyres.

…OpenAIChatGenerator

`_prepare_api_call` assembled the payload as `{**openai_tools, **generation_kwargs}`, so a `tools`
key inside `generation_kwargs` replaced the definitions built from the component's own `tools`
instead of being added to them. A caller passing extra OpenAI tool specs alongside Haystack tools
advertised only the former, and its own tools were silently dropped — no error, the model simply
never saw them.

The two lists are now merged: the component's own tools first, then the specs from
`generation_kwargs`, with the latter winning on a name clash, consistent with how every other
`generation_kwargs` key already overrides the component's defaults.

Tool names are read through `_tool_spec_name`, which resolves the body under the key named by the
spec's own `type`. That keeps `{"type": "custom", "custom": {...}}` and body-less built-ins such as
`{"type": "web_search"}` working: they carry no function name to clash on and are passed through
as given.

Fixes deepset-ai#12832

Assisted-by: Claude Code / claude-opus-5
Machine: A-MAC16-2019-PALOALTO.LOCAL
Account: dzyatkovskiy.a@gmail.com
Operator: anton
Signed-off-by: tonydzi <dzyatkovskiy.a@gmail.com>
@tonydzi
tonydzi requested a review from a team as a code owner September 23, 2026 15:30
@tonydzi
tonydzi requested review from bogdankostic and removed request for a team September 23, 2026 15:30
@vercel

vercel Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

@antondzi-legacy is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@sjrl
sjrl requested review from sjrl and removed request for bogdankostic September 24, 2026 06:29
@sjrl

sjrl commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Closing, please see comment #12832 (comment)

@sjrl sjrl closed this Sep 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OpenAIChatGenerator: tools in generation_kwargs silently drop the component's own tools

3 participants