Skip to content

fix(core): read tool args without Pydantic property shadowing - #4627

Merged
seratch merged 2 commits into
openai:mainfrom
hsusul:fix/function-schema-pydantic-property-shadowing
Aug 24, 2026
Merged

fix(core): read tool args without Pydantic property shadowing#4627
seratch merged 2 commits into
openai:mainfrom
hsusul:fix/function-schema-pydantic-property-shadowing

Conversation

@hsusul

@hsusul hsusul commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Summary

FuncSchema.to_call_args() used getattr() to recover tool arguments from the generated Pydantic model. For parameters named model_extra or model_fields_set, that hits BaseModel properties instead of the validated fields, so the tool is invoked with None or a set of field names even though JSON validation succeeded.

This is distinct from #3547 / #3572, which were about names that crash create_model(). These names build and validate successfully, then silently pass the wrong values.

Reproduction

from agents.function_schema import function_schema

def search(query: str, model_extra: str) -> str:
    return f"{query}:{model_extra}"

fs = function_schema(search, use_docstring_info=False)
parsed = fs.params_pydantic_model.model_validate(
    {"query": "hello", "model_extra": "gpt-4.1"}
)
args, kwargs = fs.to_call_args(parsed)
print(args)  # Before: ['hello', None]

Solution

Read instance __dict__ first so Pydantic properties cannot shadow tool parameters. Nested model objects are preserved (unlike model_dump()).

Test plan

  • Added regression tests for model_extra and model_fields_set
  • uv run pytest tests/test_function_schema.py tests/test_function_tool.py (101 passed)
  • uv run ruff format / ruff check on the changed files
  • uv run pyright on the changed files
  • git diff --check clean

Issue number

N/A — no matching open issue. Adjacent reserved-name construction failures (#3547, #3549, #3572) were closed wontfix; this path is a silent wrong-argument bug after successful schema construction.

Checks

  • I've added new tests, if relevant
  • I've run targeted format, lint, typecheck, and tests on the changed files
  • I've run .agents/skills/code-change-verification/scripts/run.sh (full make format currently fails on an unrelated pre-existing E501 in .agents/skills/implementation-final-review/scripts/test_skill_contract.py on main)
  • If using Codex, I've run /review before submitting this PR

Tool parameters named model_extra or model_fields_set validated correctly
but were invoked with the BaseModel property values instead of the parsed
field, so function tools silently received None or a set of field names.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 24, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-08-24T22:17:24.759602Z 6fc29a5 New commits
🔒 Security Review Completed 2026-08-24T22:18:25.043970Z 6fc29a5 New commits
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@seratch seratch added this to the 0.22.x milestone Aug 24, 2026
@seratch seratch changed the title fix(function_schema): read tool args without Pydantic property shadowing fix(core): read tool args without Pydantic property shadowing Aug 24, 2026
@seratch
seratch enabled auto-merge (squash) August 24, 2026 22:16
@seratch
seratch merged commit c8b0a92 into openai:main Aug 24, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants