Skip to content

fix(reflect): thread max_completion_tokens into the structured-output extraction call (#2431) - #2486

Merged
nicoloboschi merged 2 commits into
vectorize-io:mainfrom
r266-tech:fix/reflect-structured-max-tokens-2431
Jul 20, 2026
Merged

fix(reflect): thread max_completion_tokens into the structured-output extraction call (#2431)#2486
nicoloboschi merged 2 commits into
vectorize-io:mainfrom
r266-tech:fix/reflect-structured-max-tokens-2431

Conversation

@r266-tech

Copy link
Copy Markdown
Contributor

Summary

User-reported #2431: structured reflect (response_schema) reproducibly returns empty message content with finish_reason=length and 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_output did 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 to None. 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_tokens budget into _generate_structured_output (and through _process_done_tool), forwarding it as max_completion_tokens — mirroring the five plain reflect calls. When unset it forwards None, which LLMProvider.call omits (unchanged behavior for callers that do not request a budget).

Tests

  • test_structured_output_forwards_max_tokens — the budget reaches the structured call
  • test_structured_output_omits_budget_when_unset — the default path forwards None (provider omits it)

Follow-up to merged #2433; fixes #2431.

r266-tech added 2 commits July 1, 2026 09:10
…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.
@nicoloboschi
nicoloboschi merged commit 54354e4 into vectorize-io:main Jul 20, 2026
86 of 87 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Structured reflect with response_schema times out while plain reflect succeeds (empty message content, finish_reason=length)

2 participants