zozo123 commented on code in PR #70096:
URL: https://github.com/apache/airflow/pull/70096#discussion_r3612552104


##########
providers/common/ai/src/airflow/providers/common/ai/utils/tool_definition.py:
##########
@@ -42,3 +43,55 @@ def return_schema_kwargs(schema: dict[str, Any]) -> 
dict[str, Any]:
     if _SUPPORTS_RETURN_SCHEMA:
         return {"return_schema": schema}
     return {}
+
+
+def _fragment_to_core_schema(fragment: dict[str, Any]) -> 
core_schema.CoreSchema:
+    any_of = fragment.get("anyOf")
+    if isinstance(any_of, list):
+        choices: list[core_schema.CoreSchema | tuple[core_schema.CoreSchema, 
str]] = [
+            _fragment_to_core_schema(choice) for choice in any_of if 
isinstance(choice, dict)
+        ]
+        return core_schema.union_schema(choices) if choices else 
core_schema.any_schema()
+
+    schema_type = fragment.get("type")
+    if isinstance(schema_type, list):
+        choices = [
+            _fragment_to_core_schema({**fragment, "type": item})
+            for item in schema_type
+            if isinstance(item, str)
+        ]
+        return core_schema.union_schema(choices) if choices else 
core_schema.any_schema()
+
+    match schema_type:
+        case "string":
+            return core_schema.str_schema()
+        case "integer":
+            return core_schema.int_schema()
+        case "number":
+            return core_schema.float_schema()
+        case "boolean":
+            return core_schema.bool_schema()
+        case "null":
+            return core_schema.none_schema()
+        case "array":
+            items = fragment.get("items")
+            return core_schema.list_schema(
+                _fragment_to_core_schema(items) if isinstance(items, dict) 
else None
+            )
+        case "object":
+            return core_schema.dict_schema()

Review Comment:
   Good call — I went ahead and made it consistent rather than leaving the 
asymmetry. `build_args_validator` and the `object` branch now share one builder 
(`_object_fragment_to_core_schema`), so nested objects with declared 
`properties` are validated recursively, exactly like arrays already recurse 
into `items`. Objects with no `properties` key (e.g. from a `dict[K, V]` 
annotation) still accept any dict, so untyped payloads aren't over-tightened. 
Added unit tests covering nested coercion, nested type/required errors, and the 
untyped-dict passthrough. Pushed in f175a10.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to