Make the AI extraction schema valid for strict structured outputs - #1540
Open
killecaptron wants to merge 1 commit into
Open
Make the AI extraction schema valid for strict structured outputs#1540killecaptron wants to merge 1 commit into
killecaptron wants to merge 1 commit into
Conversation
The schema which the AI extractor sends along with its request is
declared as a strict one, but does not follow the two rules a schema has
to follow to be accepted as such: every object must forbid additional
properties, and must list all of its properties as required. A provider
of the OpenAI family therefore refuses the request outright:
Invalid schema for response_format 'part_detail': In context=
('properties', 'parameters', 'items'), 'additionalProperties' is
required to be supplied and to be false.
Which means the AI extractor cannot work with those models at all. Going
through a gateway makes it harder to see: OpenRouter answers with its
own "Provider returned error" and keeps the reason in a field which is
not part of the exception, so the failure looks like a configuration
mistake on the user's side.
Rather than sprinkling the two rules over a nested array literal, they
are applied to the finished schema by walking it. The schema stays
readable, and a property added later cannot forget them.
Requiring every property is only acceptable because the schema already
expresses an optional value by allowing null in its type, which the
second test pins down alongside the rules themselves.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1540 +/- ##
============================================
+ Coverage 62.39% 62.66% +0.26%
- Complexity 9879 9885 +6
============================================
Files 736 736
Lines 31779 31789 +10
============================================
+ Hits 19829 19919 +90
+ Misses 11950 11870 -80 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The schema which the AI extractor sends along with its request is declared as a strict one (
'strict' => truein
DTOJsonSchemaConverter), but it does not follow the two rules a schema has to follow to be accepted assuch: every object must forbid additional properties, and must list all of its properties as required. A
provider of the OpenAI family therefore refuses the request outright:
Which means the AI extractor cannot work with those models at all - "Create part from URL" fails every time.
Going through a gateway makes it harder to see: OpenRouter answers with its own "Provider returned error" and
keeps the reason in a field which is not part of the exception, so the failure looks like a misconfiguration on
the user's side. (I only got at the message above with #1539; the two are otherwise independent.)
Rather than sprinkling the two rules over a nested array literal, they are applied to the finished schema by
walking it. The schema stays as readable as it is now, and a property added later cannot forget them.
Requiring every property is only acceptable because the schema already expresses an optional value by allowing
null in its type, which the second test pins down alongside the rules themselves.
Verified on a real instance: with this change the extraction runs through against
openai/gpt-5.6-lunaviaOpenRouter, where it failed on every attempt before.