Skip to content

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

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

fix: recursively apply strict schema constraints for tools_strict=True#11232
ArkaD171717 wants to merge 4 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 on lines +557 to +559
Sets ``additionalProperties: false`` on all objects and ensures every defined
property is listed in ``required``. Walks into nested properties, ``$defs``,
array ``items``, and ``anyOf``/``oneOf``/``allOf`` combinators.
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.

We only use single back ticks in our docstrings. The double backticks are only needed for the release note.

Comment on lines +1881 to +1882
assert result["additionalProperties"] is False
assert result["required"] == ["name"]
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.

I realize this will make it slightly more verbose but could you do a full dict comparison instead of testing a few elements. So assert result == {...} for all of the tests.


def _make_schema_strict(schema: dict[str, Any]) -> dict[str, Any]:
"""
Recursively transform a JSON schema to be OpenAI strict-mode compliant.
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.

Could we link the docs page from OpenAI explaining these requirements?

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

…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

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