Skip to content

fix: recursively apply strict schema constraints for tools_strict=True#11232

Open
ArkaD171717 wants to merge 5 commits intodeepset-ai:mainfrom
ArkaD171717:tools-strict-recursive
Open

fix: recursively apply strict schema constraints for tools_strict=True#11232
ArkaD171717 wants to merge 5 commits intodeepset-ai:mainfrom
ArkaD171717:tools-strict-recursive

Conversation

@ArkaD171717
Copy link
Copy Markdown

tools_strict=True was only setting additionalProperties: false at the top
level of tool parameter schemas
OpenAI's strict mode rejects anything with nested objects that don't also have
additionalProperties: false and a complete required list
So any tool with nested params (like a ComponentTool wrapping a component that
takes ChatMessage-shaped input) would fail at the API

Adds _make_schema_strict() that walks the schema recursively: nested
properties, $defs, array items, anyOf/oneOf/allOf branches
Sets the strict constraints at every level
Replaces the single-line top-level-only fix in _prepare_api_call

Returns a copy, doesn't mutate the original schema dict

10 new tests including a 4-level-deep ComponentTool-style schema
All 37 existing tests still pass

Closes #9411

The existing code only set additionalProperties: false at the top level
of tool parameter schemas. OpenAI strict mode requires it recursively on
all nested objects, $defs, array items, and anyOf/oneOf/allOf branches.

Add _make_schema_strict() that walks the schema recursively and sets
additionalProperties: false + required on every object. Replace the
single-line top-level-only fix in _prepare_api_call.

10 new tests including a 4-level-deep ComponentTool-style schema.

Closes deepset-ai#9411
@ArkaD171717 ArkaD171717 requested a review from a team as a code owner May 2, 2026 09:31
@ArkaD171717 ArkaD171717 requested review from anakin87 and removed request for a team May 2, 2026 09:31
@vercel
Copy link
Copy Markdown

vercel Bot commented May 2, 2026

@ArkaD171717 is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 2, 2026

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added topic:tests type:documentation Improvements on the docs labels May 2, 2026
@anakin87 anakin87 self-assigned this May 4, 2026
@ArkaD171717
Copy link
Copy Markdown
Author

Fixed ruff formatting and added release note

@anakin87
Copy link
Copy Markdown
Member

anakin87 commented May 4, 2026

@sjrl, could you please take a look at this PR?

@ArkaD171717
Copy link
Copy Markdown
Author

Hey I noticed the reno check failed, it was a UID collision on the release note filename and i pushed the fix.

Comment thread haystack/components/generators/chat/openai.py Outdated
Comment thread test/components/generators/chat/test_openai.py Outdated
Comment thread haystack/components/generators/chat/openai.py
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for all of the unit tests, but could we also make one integration test that would have failed before this change? Perhaps take a complicated one like test_complex_schema_with_defs_and_combinators and make an integration test version of it as well.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a fix where I added test_prepare_api_call_strict_complex_tool; it takes the same schema structure from test_complex_schema_with_defs_and_combinators and puts it thru _prepare_api_call with tools_strict=True

Fails on the old code b/c nested objects dont have additionalProperties: false

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right thanks but we should still add an integration test so we can see if the schema is actually accepted by OpenAI. We have other integration tests in this file to see how to structure them to be skipped if an API key is missing.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test_live_run_strict_nested_tool and test_prepare_api_call_strict_component_tool

…gration test

- single backticks in docstring instead of double
- link to OpenAI structured outputs docs
- all unit tests use full dict comparison instead of checking individual keys
- added integration test with complex schema through _prepare_api_call
@ArkaD171717
Copy link
Copy Markdown
Author

Pushed fix for backtick formatting changed to full dict comparisons, added the schemas link in the docstring and added a harder integration test that wouldve failed on the old version

- test_prepare_api_call_strict_component_tool verifies ComponentTool
  with ChatMessage params gets all nested $defs strictified
- test_live_run_strict_nested_tool hits the OpenAI API with a nested
  tool schema under tools_strict=True to confirm acceptance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic:tests type:documentation Improvements on the docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Better support for tools_strict=True when using the OpenAIChatGenerator

4 participants