From d67cf4d9c834de11ca55d1ae04e460485c1fb2e6 Mon Sep 17 00:00:00 2001 From: zhao <1615063567@qq.com> Date: Sat, 25 Apr 2026 11:36:46 +0800 Subject: [PATCH] [verified] fix: avoid passing JSON schema keys to pydantic Field --- src/mcpadapt/utils/modeling.py | 22 +++++++------ tests/utils/test_modeling.py | 58 ++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 9 deletions(-) diff --git a/src/mcpadapt/utils/modeling.py b/src/mcpadapt/utils/modeling.py index 6ac704c..5d7d452 100644 --- a/src/mcpadapt/utils/modeling.py +++ b/src/mcpadapt/utils/modeling.py @@ -64,17 +64,21 @@ def process_schema(name: str, schema_def: Dict[str, Any]) -> Type[BaseModel]: for field_name, field_schema in properties.items(): field_type, default = get_field_type(field_name, field_schema, required) + field_kwargs = { + "default": default, + "description": field_schema.get("description", ""), + "title": field_schema.get("title", ""), + } + json_schema_extras = {} + for extra_key in ("items", "anyOf", "enum", "properties"): + if extra_key in field_schema: + json_schema_extras[extra_key] = field_schema[extra_key] + if json_schema_extras: + field_kwargs["json_schema_extra"] = json_schema_extras + fields[field_name] = ( field_type, - Field( - default=default, - description=field_schema.get("description", ""), - title=field_schema.get("title", ""), - items=field_schema.get("items", None), - anyOf=field_schema.get("anyOf", []), - enum=field_schema.get("enum", None), - properties=field_schema.get("properties", {}), - ), + Field(**field_kwargs), ) # Create the model diff --git a/tests/utils/test_modeling.py b/tests/utils/test_modeling.py index 5173418..5b3ab38 100644 --- a/tests/utils/test_modeling.py +++ b/tests/utils/test_modeling.py @@ -2,6 +2,8 @@ Tests for the modeling module, specifically focused on JSON Schema handling. """ +import warnings + from mcpadapt.utils.modeling import create_model_from_json_schema @@ -35,3 +37,59 @@ def test_direct_modeling_with_list_type(): # Verify the model works as expected with number instance = model(multi_type_field=42) assert instance.multi_type_field == 42 + + +def test_model_creation_does_not_pass_invalid_field_keywords(): + """Field() should not receive JSON-schema-only keys as kwargs.""" + + schema = { + "type": "object", + "properties": { + "nullable_field": { + "anyOf": [ + {"type": "string"}, + {"type": "null"}, + ], + "description": "field allowing strings or null", + }, + "array_field": { + "type": "array", + "items": {"type": "string"}, + "description": "array of strings", + }, + "status": { + "type": "string", + "enum": ["ok", "error", "unknown"], + "description": "status enum", + }, + "payload": { + "type": "object", + "properties": { + "value": {"type": "string"}, + }, + "description": "nested object payload", + }, + }, + "required": ["status"], + } + + with warnings.catch_warnings(record=True) as captured: + warnings.simplefilter("always") + model = create_model_from_json_schema(schema) + model_instance = model( + nullable_field=None, + array_field=["one", "two"], + status="ok", + payload={"value": "x"}, + ) + + deprecation_warnings = [ + warning + for warning in captured + if issubclass(warning.category, DeprecationWarning) + and "Field" in str(warning.message) + ] + assert not deprecation_warnings + assert model_instance.status == "ok" + assert model_instance.array_field == ["one", "two"] + assert model_instance.payload == {"value": "x"}