Skip to content

Commit 1cc6696

Browse files
committed
fix(tools): support draft-07 schema definitions
1 parent a7ceb3f commit 1cc6696

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

‎src/google/adk/tools/_gemini_schema_util.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ def _sanitize_schema_type(
106106
def _dereference_schema(schema: dict[str, Any]) -> dict[str, Any]:
107107
"""Resolves $ref pointers in a JSON schema."""
108108

109-
defs = schema.get("$defs", {})
109+
defs = {}
110+
if isinstance(schema.get("definitions"), dict):
111+
defs.update(schema["definitions"])
112+
if isinstance(schema.get("$defs"), dict):
113+
defs.update(schema["$defs"])
110114

111115
def _resolve_refs(sub_schema: Any, path_refs: frozenset[str]) -> Any:
112116
if isinstance(sub_schema, dict):
@@ -151,6 +155,8 @@ def _resolve_refs(sub_schema: Any, path_refs: frozenset[str]) -> Any:
151155
# Remove the definitions block after resolving.
152156
if "$defs" in dereferenced_schema:
153157
del dereferenced_schema["$defs"]
158+
if "definitions" in dereferenced_schema:
159+
del dereferenced_schema["definitions"]
154160
return dereferenced_schema
155161

156162

‎tests/unittests/tools/test_gemini_schema_util.py‎

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,55 @@ def test_to_gemini_schema_nested_dict_with_defs_and_ref(self):
337337
]
338338
assert gemini_schema.properties["payload"].required == ["adDomain"]
339339

340+
def test_to_gemini_schema_nested_dict_with_draft07_definitions_and_ref(self):
341+
openapi_schema = {
342+
"$schema": "http://json-schema.org/draft-07/schema#",
343+
"definitions": {
344+
"DeviceEnum": {
345+
"enum": ["GLOBAL", "desktop", "mobile"],
346+
"type": "string",
347+
},
348+
"DomainPayload": {
349+
"properties": {
350+
"adDomain": {
351+
"items": {"type": "string"},
352+
"type": "array",
353+
},
354+
"device": {
355+
"$ref": "#/definitions/DeviceEnum",
356+
"default": "GLOBAL",
357+
},
358+
},
359+
"required": ["adDomain"],
360+
"type": "object",
361+
},
362+
},
363+
"properties": {"payload": {"$ref": "#/definitions/DomainPayload"}},
364+
"required": ["payload"],
365+
"type": "object",
366+
}
367+
gemini_schema = _to_gemini_schema(openapi_schema)
368+
assert gemini_schema.type == Type.OBJECT
369+
assert gemini_schema.properties["payload"].type == Type.OBJECT
370+
assert (
371+
gemini_schema.properties["payload"].properties["adDomain"].type
372+
== Type.ARRAY
373+
)
374+
assert (
375+
gemini_schema.properties["payload"].properties["adDomain"].items.type
376+
== Type.STRING
377+
)
378+
assert (
379+
gemini_schema.properties["payload"].properties["device"].type
380+
== Type.STRING
381+
)
382+
assert gemini_schema.properties["payload"].properties["device"].enum == [
383+
"GLOBAL",
384+
"desktop",
385+
"mobile",
386+
]
387+
assert gemini_schema.properties["payload"].required == ["adDomain"]
388+
340389
def test_sanitize_integer_formats(self):
341390
"""Test that int32 and int64 formats are preserved for integer types"""
342391
openapi_schema = {

0 commit comments

Comments
 (0)