Skip to content

fix(agent_tool_input): summarize Pydantic Optional[T] anyOf fields#3265

Draft
adityasingh2400 wants to merge 1 commit intoopenai:mainfrom
adityasingh2400:fix/ati-audit
Draft

fix(agent_tool_input): summarize Pydantic Optional[T] anyOf fields#3265
adityasingh2400 wants to merge 1 commit intoopenai:mainfrom
adityasingh2400:fix/ati-audit

Conversation

@adityasingh2400
Copy link
Copy Markdown
Contributor

Summary

  • 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[T] field would silently suppress the entire structured-input summary, including sibling fields with valid types and descriptions.
  • Detect the 2-branch anyOf of a simple type plus 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.

Repro

from pydantic import BaseModel, TypeAdapter
from agents.agent_tool_input import build_structured_input_schema_info

class Args(BaseModel):
    count: int | None = None  # Pydantic emits anyOf: [{type:integer},{type:null}]
    name: str  # has a description in the rendered schema

schema = TypeAdapter(Args).json_schema()
# add descriptions for the demo
schema["properties"]["count"]["description"] = "Optional count."
schema["properties"]["name"]["description"] = "A name."

print(build_structured_input_schema_info(schema, include_json_schema=False).summary)
# Before: None  (entire summary dropped)
# After:
#   - count (integer | null, optional) - Optional count.
#   - name (string, required) - A name.

Test plan

  • New test test_schema_summary_handles_pydantic_optional_anyof covers the nullable anyOf shape and confirms non-nullable anyOf unions are still rejected.
  • Test fails on main (assert None is not None) and passes with the fix.
  • All existing tests/test_agent_tool_input.py, tests/test_agent_tool_state.py, and tests/test_agent_as_tool.py tests still pass (60/60).

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.
@github-actions github-actions Bot added bug Something isn't working feature:core labels May 8, 2026
@seratch
Copy link
Copy Markdown
Member

seratch commented May 8, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 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".

Comment on lines +272 to +274
if entry_type in _SIMPLE_JSON_SCHEMA_TYPES and base_type is None:
base_type = cast(str, entry_type)
continue
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@seratch seratch marked this pull request as draft May 8, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working feature:core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants