fix: retry when LLM returns text instead of calling final_response#3850
fix: retry when LLM returns text instead of calling final_response#3850
Conversation
Instead of raising RuntimeError immediately when the LLM returns a text response instead of calling the `final_response` tool for structured output, retry up to 3 times with an explicit nudge message asking the model to use the tool. This mirrors the existing retry behavior for validation errors but with a separate, smaller cap. Fixes #3847 Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Tests cover: - Text response followed by successful final_response (retry works) - Text response exceeding max retries (raises RuntimeError) - Nudge message appended to history on retry - No retry when result_type is None (text is valid) Addresses review feedback from PR review tool (v1 flagged missing tests as high severity). Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Remove test_nudge_message_in_history (implementation detail). Reduce boilerplate in remaining 3 tests. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Test Failure AnalysisSummary: The Root Cause: In Suggested Solution: Run # Before (current)
ToolUseContent(
type="tool_use", id="c1", name="final_response", input={"value": value}
)
# After (ruff-formatted)
ToolUseContent(
type="tool_use",
id="c1",
name="final_response",
input={"value": value},
)Detailed AnalysisFailed hook: Workflow run: #24292594795, job Relevant log excerpt: Related Files
|
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The merge of PrefectHQ#3850 and PrefectHQ#3851 dropped the variable initialization. text_response_retries was used at line 707 but never assigned. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
jlowin
left a comment
There was a problem hiding this comment.
Mirrors the existing validation-retry convention and handles the real UX cliff where some models ignore tool_choice=required. Bounded at 3 retries.
Fixes #3847
Problem
sample_implat line 685 raisesRuntimeErrorimmediately when structured output is expected but the LLM returns text instead of callingfinal_response. No retry, no nudge — just a crash.This contrasts with validation errors (lines 657-679) which append feedback to history and retry. Some models occasionally ignore
tool_choice="required"and return text, especially on later iterations of the tool loop after gathering information.Fix
Add a retry loop (capped at 3 attempts) that appends a nudge message asking the model to use the
final_responsetool, matching the existing pattern for validation error retries.After exhausting retries, raises
RuntimeErrorwith the attempt count.Tests
3 tests: retry-then-succeed, exceed-max-retries, and no-retry-when-result_type-is-None.
🤖 Generated with Claude Code