@@ -63,50 +63,54 @@ def validate_tool_use_name(tool: ToolUse) -> None:
63
63
raise InvalidToolUseNameException (message )
64
64
65
65
66
+ def _normalize_property (prop_name : str , prop_def : Any ) -> Dict [str , Any ]:
67
+ """Normalize a single property definition.
68
+
69
+ Args:
70
+ prop_name: The name of the property.
71
+ prop_def: The property definition to normalize.
72
+
73
+ Returns:
74
+ The normalized property definition.
75
+ """
76
+ if not isinstance (prop_def , dict ):
77
+ return {"type" : "string" , "description" : f"Property { prop_name } " }
78
+
79
+ if prop_def .get ("type" ) == "object" and "properties" in prop_def :
80
+ return normalize_schema (prop_def ) # Recursive call
81
+
82
+ # Copy existing property, ensuring defaults
83
+ normalized_prop = prop_def .copy ()
84
+ normalized_prop .setdefault ("type" , "string" )
85
+ normalized_prop .setdefault ("description" , f"Property { prop_name } " )
86
+ return normalized_prop
87
+
88
+
66
89
def normalize_schema (schema : Dict [str , Any ]) -> Dict [str , Any ]:
67
90
"""Normalize a JSON schema to match expectations.
68
91
92
<
10000
code class="diff-text syntax-highlighted-line addition">+ This function recursively processes nested objects to preserve the complete schema structure.
93
+ Uses a copy-then-normalize approach to preserve all original schema properties.
94
+
69
95
Args:
70
96
schema: The schema to normalize.
71
97
72
98
Returns:
73
99
The normalized schema.
74
100
"""
75
- normalized = {"type" : schema .get ("type" , "object" ), "properties" : {}}
76
-
77
- # Handle properties
78
- if "properties" in schema :
79
- for prop_name , prop_def in schema ["properties" ].items ():
80
- if isinstance (prop_def , dict ):
81
- normalized_prop = {
82
- "type" : prop_def .get ("type" , "string" ),
83
- "description" : prop_def .get ("description" , f"Property { prop_name } " ),
84
- }
85
-
86
- # Handle enum values correctly
87
- if "enum" in prop_def :
88
- normalized_prop ["enum" ] = prop_def ["enum" ]
89
-
90
- # Handle numeric constraints
91
- if prop_def .get ("type" ) in ["number" , "integer" ]:
92
- if "minimum" in prop_def :
93
- normalized_prop ["minimum" ] = prop_def ["minimum" ]
94
- if "maximum" in prop_def :
95
- normalized_prop ["maximum" ] = prop_def ["maximum" ]
96
-
97
- normalized ["properties" ][prop_name ] = normalized_prop
98
- else :
99
- # Handle non-dict property definitions (like simple strings)
100
- normalized ["properties" ][prop_name ] = {
101
- "type" : "string" ,
102
- "description" : f"Property { prop_name } " ,
103
- }
104
-
105
- # Required fields
106
- if "required" in schema :
107
- normalized ["required" ] = schema ["required" ]
108
- else :
109
- normalized ["required" ] = []
101
+ # Start with a complete copy to preserve a
8D0B
ll existing properties
102
+ normalized = schema .copy ()
103
+
104
+ # Ensure essential structure exists
105
+ normalized .setdefault ("type" , "object" )
106
+ normalized .setdefault ("properties" , {})
107
+ normalized .setdefault ("required" , [])
108
+
109
+ # Process properties recursively
110
+ if "properties" in normalized :
111
+ properties = normalized ["properties" ]
112
+ for prop_name , prop_def in properties .items ():
113
+ normalized ["properties" ][prop_name ] = _normalize_property (prop_name , prop_def )
110
114
111
115
return normalized
112
116
0 commit comments