fix(reflect): thread max_completion_tokens into the structured-output extraction call (#2431) - #2486
Merged
nicoloboschi merged 2 commits intoJul 20, 2026
Conversation
…raction vectorize-io#2433 capped the structured retry budget but the structured second pass never received an output-token budget, so on reasoning/preamble models the provider default is exhausted before JSON is emitted (finish_reason=length, empty content) and structured reflect degrades to None. Thread the reflect max_tokens through _generate_structured_output (and _process_done_tool) as max_completion_tokens, mirroring the plain reflect calls. Fixes vectorize-io#2431.
3 tasks
nicoloboschi
approved these changes
Jul 20, 2026
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.
Summary
User-reported #2431: structured reflect (
response_schema) reproducibly returns empty message content withfinish_reason=lengthand times out, while plain reflect succeeds for the same bank/query shape. #2433 (merged) capped the structured retry budget so it fails fast rather than hanging, but the underlying cause remained: the second-pass structured-extraction call never received an output-token budget.Every plain reflect call passes
max_completion_tokens=max_tokens, but_generate_structured_outputdid not. On reasoning/preamble models the provider's small default budget is consumed before any JSON is emitted (finish_reason=length, empty content), so structured reflect silently degrades toNone. WuKavin's follow-up (switching the reflect model) is consistent with this: the failing model needs an explicit budget the plain path already grants.Change
Thread the reflect
max_tokensbudget into_generate_structured_output(and through_process_done_tool), forwarding it asmax_completion_tokens— mirroring the five plain reflect calls. When unset it forwardsNone, whichLLMProvider.callomits (unchanged behavior for callers that do not request a budget).Tests
test_structured_output_forwards_max_tokens— the budget reaches the structured calltest_structured_output_omits_budget_when_unset— the default path forwardsNone(provider omits it)Follow-up to merged #2433; fixes #2431.