fix(core): support tool parameters named like BaseModel members - #4715
Closed
abhay-codes07 wants to merge 1 commit into
Closed
fix(core): support tool parameters named like BaseModel members#4715abhay-codes07 wants to merge 1 commit into
abhay-codes07 wants to merge 1 commit into
Conversation
A function tool whose parameter shadows a Pydantic BaseModel member crashed at tool-definition time inside function_schema's create_model: model_dump / model_validate / model_json_schema (and other model_* methods) raised an opaque ValueError, and model_config raised TypeError: 'FieldInfo' object is not iterable. Build the generated args model on a base whose model_config sets protected_namespaces=(), so method-shadowing parameter names no longer trip Pydantic's guard. The runtime call layer already reads argument values from instance __dict__ (see openai#4627), so a field shadowing a model member is resolved correctly. model_config cannot be a field name -- create_model reserves that keyword for configuration -- so it is rejected with an actionable UserError instead of an opaque crash.
Member
|
Thanks for investigating these Pydantic name collisions. The previously closed reports asked for an actionable failure, not for every BaseModel member name to become a supported tool parameter. Disabling protected_namespaces for every generated argument model creates a broad new contract and leaves model instances with fields shadowing methods such as model_dump and model_validate. Renaming the parameter or using a wrapper function remains a reasonable supported alternative. The narrower silent-value corruption for already constructible models was fixed separately in #4627. I am closing this broader support change. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A function tool whose parameter name shadows a Pydantic
BaseModelmember crashes at tool-definition time, deep insidefunction_schema'screate_modelcall, with an error that gives no hint about the real cause:model_dump,model_validate,model_dump_json,model_json_schemaand the othermodel_*methods raise aValueErrorfrom Pydantic's protected-namespace guard;model_configraises aTypeErrorbecausecreate_modeltreats amodel_configkeyword as configuration.This completes #4627, which taught the runtime call layer to read argument values from instance
__dict__(rather than by attribute access) precisely so parameters can shadowBaseModelmembers likemodel_extra/model_fields_set— but those names still had to be definable first, and themodel_*methods crash before that support is ever reached.Change: build the generated args model on a small base whose
model_configsetsprotected_namespaces=(), so method-shadowing parameter names no longer trip Pydantic's guard. Because the call layer already resolves values via__dict__, a field that shadows a model member is still passed to the tool correctly.model_configitself cannot be a Pydantic field name, so it is rejected with an actionableUserError("Rename the parameter…") instead of an opaqueTypeError.Test plan
test_parameter_named_like_a_basemodel_method_is_supported(parametrized overmodel_dump,model_dump_json,model_validate,model_validate_json,model_json_schema): the tool is defined, validates input, and round-trips throughto_call_argsto the original function.test_parameter_named_model_config_raises_actionable_error:model_configraises aUserErrormentioning the parameter, not aTypeError.mainwithout the source change.model_extra/model_fields_settests still pass unchanged.uv run pytest tests/test_function_schema.py tests/test_function_tool_decorator.py tests/test_tool_converter.py tests/test_released_api_contract.py→ 231 passed.ruff format --check,ruff check, andmypyon the changed file pass.Issue number
Follows up #4627 (closed #3547 / #3549 covered the same crash; the runtime shadowing was fixed there, the definition-time crash remained).
Checks
make lint,make formatandmake tests(ran targeted lint/format/typecheck and the tool suites locally)/reviewbefore submitting this PR