Compare commits

...

3 Commits

Author SHA1 Message Date
Luke Street e4e7f34154 Merge branch 'main' into fix/anthropic-nested-schema-type-conversion 2026-03-05 15:14:22 -07:00
Rohit Yanamadala 339a22e381 Merge branch 'main' into fix/anthropic-nested-schema-type-conversion 2026-02-19 11:45:29 -08:00
Luke Street 6975461c86 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.
2026-02-12 12:08:14 -07:00
2 changed files with 67 additions and 7 deletions
+4 -7
View File
@@ -233,18 +233,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,
@@ -279,6 +279,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(