You've already forked adk-python
mirror of
https://github.com/encounter/adk-python.git
synced 2026-07-09 18:19:28 -07:00
fix: recurse into object properties in _update_type_string for Anthropic adapter
`_update_type_string` lowercases Gemini-style type strings (e.g. "STRING" -> "string") for Anthropic API compatibility. It already recursed into `items` (arrays) and `items.properties` (arrays of objects), but not into top-level `properties` of object types. This caused tool schemas with nested object parameters (e.g. Pydantic models) to produce invalid JSON Schema with uppercase type strings, resulting in Anthropic API 400 errors. Recurse into `properties` at every level, which also subsumes the existing `items.properties` handling.
This commit is contained in:
@@ -218,18 +218,15 @@ def _update_type_string(value_dict: dict[str, Any]):
|
||||
if "type" in value_dict:
|
||||
value_dict["type"] = value_dict["type"].lower()
|
||||
|
||||
if "properties" in value_dict:
|
||||
for _, value in value_dict["properties"].items():
|
||||
_update_type_string(value)
|
||||
|
||||
if "items" in value_dict:
|
||||
# 'type' field could exist for items as well, this would be the case if
|
||||
# items represent primitive types.
|
||||
_update_type_string(value_dict["items"])
|
||||
|
||||
if "properties" in value_dict["items"]:
|
||||
# There could be properties as well on the items, especially if the items
|
||||
# are complex object themselves. We recursively traverse each individual
|
||||
# property as well and fix the "type" value.
|
||||
for _, value in value_dict["items"]["properties"].items():
|
||||
_update_type_string(value)
|
||||
|
||||
|
||||
def function_declaration_to_tool_param(
|
||||
function_declaration: types.FunctionDeclaration,
|
||||
|
||||
@@ -275,6 +275,69 @@ function_declaration_test_cases = [
|
||||
},
|
||||
),
|
||||
),
|
||||
(
|
||||
"function_with_nested_object_parameter",
|
||||
types.FunctionDeclaration(
|
||||
name="update_profile",
|
||||
description="Updates a user profile.",
|
||||
parameters=types.Schema(
|
||||
type=types.Type.OBJECT,
|
||||
properties={
|
||||
"profile": types.Schema(
|
||||
type=types.Type.OBJECT,
|
||||
description="The profile data",
|
||||
properties={
|
||||
"name": types.Schema(
|
||||
type=types.Type.STRING,
|
||||
description="Full name",
|
||||
),
|
||||
"address": types.Schema(
|
||||
type=types.Type.OBJECT,
|
||||
description="Mailing address",
|
||||
properties={
|
||||
"city": types.Schema(
|
||||
type=types.Type.STRING,
|
||||
),
|
||||
"state": types.Schema(
|
||||
type=types.Type.STRING,
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
),
|
||||
},
|
||||
required=["profile"],
|
||||
),
|
||||
),
|
||||
anthropic_types.ToolParam(
|
||||
name="update_profile",
|
||||
description="Updates a user profile.",
|
||||
input_schema={
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"profile": {
|
||||
"type": "object",
|
||||
"description": "The profile data",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "Full name",
|
||||
},
|
||||
"address": {
|
||||
"type": "object",
|
||||
"description": "Mailing address",
|
||||
"properties": {
|
||||
"city": {"type": "string"},
|
||||
"state": {"type": "string"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"required": ["profile"],
|
||||
},
|
||||
),
|
||||
),
|
||||
(
|
||||
"function_with_parameters_json_schema",
|
||||
types.FunctionDeclaration(
|
||||
|
||||
Reference in New Issue
Block a user