Skip to content

feat: add configurable output validation retry for output_pydantic#6598

Open
h1jj wants to merge 3 commits into
crewAIInc:mainfrom
h1jj:feat/output-validation-retry
Open

feat: add configurable output validation retry for output_pydantic#6598
h1jj wants to merge 3 commits into
crewAIInc:mainfrom
h1jj:feat/output-validation-retry

Conversation

@h1jj

@h1jj h1jj commented Jul 20, 2026

Copy link
Copy Markdown

Summary

Add configurable LLM-based retry mechanism for output_pydantic validation.

Changes

  • converter.py: added _handle_and_retry, _convert_with_retry helpers (sync + async)
  • task.py: added output_validation_max_retries field
  • tests: 5 new tests covering success, exhaustion, zero-retry (no LLM), zero-retry (converter_cls), and error context injection

Test Plan

  • 5 new tests pass
  • All 50 existing converter tests pass
  • Backward compatible

Add `max_retries` parameter to `convert_to_model` and
`output_validation_max_retries` field to Task, enabling LLM-based
retry when Pydantic validation of agent output fails.

Each retry feeds the validation error back to the LLM so it can
self-correct. Defaults to 0 (backward compatible, no behavior change).

- converter.py: add `_handle_and_retry`, `_convert_with_retry` helpers
  (sync + async) with error accumulation across retry attempts
- task.py: add `output_validation_max_retries` configuration field
- tests: 4 new tests covering retry success, exhaustion, no-LLM mode,
  and error context injection

Closes: crewAIInc#4389 (related: converter robustness)
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds Task.output_validation_max_retries, defaults it to zero, propagates it through synchronous and asynchronous output conversion, and implements retry handling with validation-error feedback. Converter tests cover successful retries, exhausted retries, disabled retries, and prompt error details.

Changes

Output validation retries

Layer / File(s) Summary
Synchronous conversion retry flow
lib/crewai/src/crewai/utilities/converter.py, lib/crewai/tests/utilities/test_converter.py
convert_to_model supports max_retries, retries failed validation through convert_with_instructions, and includes validation errors in retry prompts. Tests cover success, exhaustion, zero retries, prompt contents, and converter dispatch.
Asynchronous conversion retry flow
lib/crewai/src/crewai/utilities/converter.py
async_convert_to_model mirrors the synchronous retry flow using asynchronous parsing and conversion helpers.
Task retry configuration wiring
lib/crewai/src/crewai/task.py, pr-body.md
Task exposes output_validation_max_retries and passes it to both synchronous and asynchronous output conversion. The PR documentation describes configuration and retry-focused tests.

Sequence Diagram(s)

sequenceDiagram
  participant Task
  participant convert_to_model
  participant handle_partial_json
  participant convert_with_instructions
  Task->>convert_to_model: output and max_retries
  convert_to_model->>handle_partial_json: parse and validate output
  handle_partial_json-->>convert_to_model: validation result
  convert_to_model->>convert_with_instructions: retry with validation error
  convert_with_instructions-->>convert_to_model: corrected output or ConverterError
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely summarizes the main change: configurable output validation retries for output_pydantic.
Description check ✅ Passed The description is directly related to the changeset and accurately summarizes the retry mechanism, task field, and tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/crewai/src/crewai/utilities/converter.py`:
- Around line 224-232: The retry loops currently skip conversion when
max_retries is zero. In lib/crewai/src/crewai/utilities/converter.py lines
224-232 and 558-566, update _convert_with_retry and _async_convert_with_retry so
their attempt ranges always execute at least once, while preserving additional
retries when configured.
- Around line 663-666: Update the async output-validation log in the converter
helper to use the same attempt and retry totals as the sync helper and injected
prompt: format the message with attempt and max_retries directly, removing both
+1 offsets while preserving the existing error context.

In `@lib/crewai/tests/utilities/test_converter.py`:
- Around line 1015-1110: Add coverage for the converter_cls dispatch path in the
retry tests, using a configured converter class rather than converter_cls=None.
Add a max_retries=0 case that invokes the converter and asserts the expected
conversion behavior, ensuring the direct _convert_with_retry path does not
incorrectly skip the converter; keep assertions focused on observable behavior
rather than internal calls.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 338b1dc5-c9f8-4827-94ba-442181e4c388

📥 Commits

Reviewing files that changed from the base of the PR and between 69c0308 and 4dd8ab1.

📒 Files selected for processing (3)
  • lib/crewai/src/crewai/task.py
  • lib/crewai/src/crewai/utilities/converter.py
  • lib/crewai/tests/utilities/test_converter.py

Comment thread lib/crewai/src/crewai/utilities/converter.py
Comment thread lib/crewai/src/crewai/utilities/converter.py
Comment thread lib/crewai/tests/utilities/test_converter.py
Address code review feedback from CodeRabbit:

1. (CRITICAL) Fix _convert_with_retry loop to always run at least one
   iteration when converter_cls is set. Changed range(1, max_retries+1)
   to range(1, max(max_retries, 1)+1) in both sync and async versions.

2. (MINOR) Align async log attempt numbering with sync format:
   attempt/max_retries instead of attempt+1/max_retries+1.

3. (TEST) Add test_converter_cls_path_still_called_with_zero_retries
   to cover the converter_cls dispatch path when max_retries=0.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pr-body.md`:
- Line 10: Update the test coverage summary and repeated test-plan entry in
pr-body.md to match the actual TestConvertToModelWithRetry tests, including the
converter_cls path with max_retries=0. Correct the reported count and explicitly
list all covered scenarios, including success, exhaustion, zero-retry
converter_cls behavior, and error context injection.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d579f656-edea-4dea-a932-1b1ba46d2d21

📥 Commits

Reviewing files that changed from the base of the PR and between 4dd8ab1 and 36adf1b.

📒 Files selected for processing (3)
  • lib/crewai/src/crewai/utilities/converter.py
  • lib/crewai/tests/utilities/test_converter.py
  • pr-body.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • lib/crewai/tests/utilities/test_converter.py
  • lib/crewai/src/crewai/utilities/converter.py

Comment thread pr-body.md Outdated
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.

1 participant