fix: fix mcp tool parameter extract (#33258)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
wangxiaolei
2026-03-11 13:46:38 +08:00
committed by GitHub
parent d6721a1dd3
commit 1f4b6c84e0
2 changed files with 175 additions and 5 deletions

View File

@ -33,6 +33,8 @@ logger = logging.getLogger(__name__)
class ToolTransformService:
_MCP_SCHEMA_TYPE_RESOLUTION_MAX_DEPTH = 10
@classmethod
def get_tool_provider_icon_url(
cls, provider_type: str, provider_name: str, icon: str | Mapping[str, str]
@ -435,6 +437,46 @@ class ToolTransformService:
:return: list of ToolParameter instances
"""
def resolve_property_type(prop: dict[str, Any], depth: int = 0) -> str:
"""
Resolve a JSON schema property type while guarding against cyclic or deeply nested unions.
"""
if depth >= ToolTransformService._MCP_SCHEMA_TYPE_RESOLUTION_MAX_DEPTH:
return "string"
prop_type = prop.get("type")
if isinstance(prop_type, list):
non_null_types = [type_name for type_name in prop_type if type_name != "null"]
if non_null_types:
return non_null_types[0]
if prop_type:
return "string"
elif isinstance(prop_type, str):
if prop_type == "null":
return "string"
return prop_type
for union_key in ("anyOf", "oneOf"):
union_schemas = prop.get(union_key)
if not isinstance(union_schemas, list):
continue
for union_schema in union_schemas:
if not isinstance(union_schema, dict):
continue
union_type = resolve_property_type(union_schema, depth + 1)
if union_type != "null":
return union_type
all_of_schemas = prop.get("allOf")
if isinstance(all_of_schemas, list):
for all_of_schema in all_of_schemas:
if not isinstance(all_of_schema, dict):
continue
all_of_type = resolve_property_type(all_of_schema, depth + 1)
if all_of_type != "null":
return all_of_type
return "string"
def create_parameter(
name: str, description: str, param_type: str, required: bool, input_schema: dict[str, Any] | None = None
) -> ToolParameter:
@ -461,10 +503,7 @@ class ToolTransformService:
parameters = []
for name, prop in props.items():
current_description = prop.get("description", "")
prop_type = prop.get("type", "string")
if isinstance(prop_type, list):
prop_type = prop_type[0]
prop_type = resolve_property_type(prop)
if prop_type in TYPE_MAPPING:
prop_type = TYPE_MAPPING[prop_type]
input_schema = prop if prop_type in COMPLEX_TYPES else None