fix(agents): keep null in the task output schema embedded in the prompt - #6775
fix(agents): keep null in the task output schema embedded in the prompt#6775monkscode wants to merge 2 commits into
Conversation
build_task_prompt_with_schema embeds the task output schema into the prompt via generate_model_description, whose strip_null_types defaults to True. Combined with ensure_all_properties_required, an Optional[str] = None field reaches the model as a required, non-nullable string, contradicting the provider-side response schema generated from the same model. That sanitizer targets OpenAI strict function-calling schemas. This call site produces prompt prose, where those constraints do not apply. Pass strip_null_types=False, matching the existing call for tool schemas in utilities/agent_utils.py. Fixes crewAIInc#6774
📝 WalkthroughWalkthroughThe task prompt schema now preserves null types for JSON and Pydantic outputs. Tests verify that optional Pydantic fields produce schemas accepting both strings and null values. ChangesNullable task output schemas
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
lib/crewai/tests/agents/test_agent_utils.py (2)
25-27: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winCover the
output_jsonbranch.This test constructs
Taskwithoutput_pydanticonly. It never executes thetask.output_jsonbranch changed inbuild_task_prompt_with_schema. Add a matching JSON-output case or parameterize the test over both output attributes.Based on PR objectives: nullable prompt schemas must be preserved for both JSON and Pydantic outputs.
🤖 Prompt for 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. In `@lib/crewai/tests/agents/test_agent_utils.py` around lines 25 - 27, Extend the test around build_task_prompt_with_schema to cover Task configured with output_json in addition to output_pydantic, either by adding a matching JSON-output case or parameterizing both configurations. Ensure the assertions verify nullable prompt schemas are preserved for both output attributes.
33-36: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake the
anyOfassertion order-independent.The exact list comparison makes member order part of the test contract. JSON Schema alternatives are order-independent, so a valid generator change can fail this test.
Proposed assertion
- assert schema["properties"]["note"]["anyOf"] == [ - {"type": "string"}, - {"type": "null"}, - ] + assert { + entry["type"] for entry in schema["properties"]["note"]["anyOf"] + } == {"string", "null"}Based on coding guidelines: tests should focus on behavior rather than implementation details.
🤖 Prompt for 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. In `@lib/crewai/tests/agents/test_agent_utils.py` around lines 33 - 36, Update the `anyOf` assertion in the agent schema test to compare alternatives without relying on list order, while still requiring exactly the string and null schema members. Preserve the existing validation of the `note` property’s schema.Source: Coding guidelines
🤖 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.
Nitpick comments:
In `@lib/crewai/tests/agents/test_agent_utils.py`:
- Around line 25-27: Extend the test around build_task_prompt_with_schema to
cover Task configured with output_json in addition to output_pydantic, either by
adding a matching JSON-output case or parameterizing both configurations. Ensure
the assertions verify nullable prompt schemas are preserved for both output
attributes.
- Around line 33-36: Update the `anyOf` assertion in the agent schema test to
compare alternatives without relying on list order, while still requiring
exactly the string and null schema members. Preserve the existing validation of
the `note` property’s schema.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: fe8f54e9-1bab-4281-b4e9-a21ba24e21be
📒 Files selected for processing (2)
lib/crewai/src/crewai/agent/utils.pylib/crewai/tests/agents/test_agent_utils.py
build_task_prompt_with_schemaembeds the task output schema into the prompt usinggenerate_model_description, whosestrip_null_typesdefaults toTrue. Combined withensure_all_properties_required, anOptional[str] = Nonefield is presented to themodel as a required, non-nullable string — leaving it no way to express "not
applicable", and contradicting the provider-side response schema generated from the
same model.
That sanitizer targets OpenAI strict function-calling schemas. This call site produces
prompt prose, where those constraints do not apply.
This passes
strip_null_types=False, matching the existing call for tool schemas atutilities/agent_utils.py:268.requiredstill lists every property, which is thestandard strict-mode idiom once the type is nullable.
Before / after
For
class Step(BaseModel): name: str; note: Optional[str] = None:requiredis['name', 'note']in both cases — unchanged by this PR.Tests
Adds
lib/crewai/tests/agents/test_agent_utils.py. No existing test referencedbuild_task_prompt_with_schema, so the file is new; maintainers may prefer itelsewhere. It fails on
mainwithKeyError: 'anyOf'and passes with this change.Existing cassette-based tests are unaffected:
vcr_configmatches on["method", "scheme", "host", "port", "path"], not on the request body.Fixes #6774