fix(agent_tool_input): summarize Pydantic Optional[T] anyOf fields#3265
fix(agent_tool_input): summarize Pydantic Optional[T] anyOf fields#3265adityasingh2400 wants to merge 3 commits into
Conversation
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d6ae9a108b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if entry_type in _SIMPLE_JSON_SCHEMA_TYPES and base_type is None: | ||
| base_type = cast(str, entry_type) | ||
| continue |
There was a problem hiding this comment.
Preserve enum/const constraints in nullable anyOf
Pydantic emits Optional[Literal[...]] as anyOf with an enum/const branch that also has type: "string". This helper now accepts that branch as a bare simple type, so the schema summary says e.g. string | null instead of the allowed literals, misleading the nested agent about valid structured input.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in c22eb566: Preserve enum/const branches in the nullable anyOf summary so Optional[Literal[...]] reports the allowed literals instead of bare string | null. Test added for the literal case.
The schema summary helper rejected any field with an `anyOf` key, but
Pydantic renders `T | None` as `anyOf: [{type: T}, {type: "null"}]`.
Because `_summarize_json_schema` returns None for the whole schema when
any single field is unsupported, one Optional field would silently
suppress the entire structured-input summary - even for sibling fields
with valid types and descriptions.
Detect the 2-branch `anyOf` of a simple type and `null` and render it
as `T | null`, matching the existing `type: ["T", "null"]` path.
Other `anyOf` shapes (unions of two non-null types, anyOf with nested
objects, etc.) are still rejected.
Pydantic emits Optional[Literal[...]] as a 2-branch anyOf where one branch carries both enum/const and type: 'string'. The previous fix collapsed that to 'string | null', hiding the allowed values from the nested-agent schema summary. Prefer the enum/const label when present.
5a99059 to
c22eb56
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 64e23d389c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if "const" in entry: | ||
| base_label = _format_literal_label(entry) | ||
| continue | ||
| if entry_type in _SIMPLE_JSON_SCHEMA_TYPES: |
There was a problem hiding this comment.
Guard non-string anyOf branch types
When a supported parameter model supplies a JSON Schema anyOf branch whose type uses the valid list form, for example via Pydantic json_schema_extra as {"type": ["integer", "string"]} plus a null branch, this membership test hashes the list and raises TypeError while building the agent tool. Other unsupported schema shapes in this helper fall back to None, so this should first verify entry_type is a string before checking _SIMPLE_JSON_SCHEMA_TYPES.
Useful? React with 👍 / 👎.
Summary
anyOfkey, but Pydantic rendersT | NoneasanyOf: [{type: T}, {type: "null"}]. Because_summarize_json_schemareturnsNonefor the whole schema when any single field is unsupported, oneOptional[T]field would silently suppress the entire structured-input summary, including sibling fields with valid types and descriptions.anyOfof a simple type plusnulland render it asT | null, matching the existingtype: ["T", "null"]path.anyOfshapes (unions of two non-null types,anyOfwith nested objects, etc.) are still rejected.Repro
Test plan
test_schema_summary_handles_pydantic_optional_anyofcovers the nullableanyOfshape and confirms non-nullableanyOfunions are still rejected.main(assert None is not None) and passes with the fix.tests/test_agent_tool_input.py,tests/test_agent_tool_state.py, andtests/test_agent_as_tool.pytests still pass (60/60).