|
19 | 19 |
|
20 | 20 |
|
21 | 21 | def adk_to_mcp_tool_type(tool: BaseTool) -> mcp_types.Tool:
|
22 |
| - """Convert a Tool in ADK into MCP tool type. |
23 |
| -
|
24 |
| - This function transforms an ADK tool definition into its equivalent |
25 |
| - representation in the MCP (Model Context Protocol) system. |
26 |
| -
|
27 |
| - Args: |
28 |
| - tool: The ADK tool to convert. It should be an instance of a class derived |
29 |
| - from `BaseTool`. |
30 |
| -
|
31 |
| - Returns: |
32 |
| - An object of MCP Tool type, representing the converted tool. |
33 |
| -
|
34 |
| - Examples: |
35 |
| - # Assuming 'my_tool' is an instance of a BaseTool derived class |
36 |
| - mcp_tool = adk_to_mcp_tool_type(my_tool) |
37 |
| - print(mcp_tool) |
38 |
| - """ |
39 |
| - tool_declaration = tool._get_declaration() |
40 |
| - if not tool_declaration: |
41 |
| - input_schema = {} |
42 |
| - else: |
43 |
| - input_schema = gemini_to_json_schema(tool._get_declaration().parameters) |
44 |
| - return mcp_types.Tool( |
45 |
| - name=tool.name, |
46 |
| - description=tool.description, |
47 |
| - inputSchema=input_schema, |
48 |
| - ) |
| 22 | + """Convert a Tool in ADK into MCP tool type. |
| 23 | +
|
| 24 | + This function transforms an ADK tool definition into its equivalent |
| 25 | + MCP (Model Context Protocol) representation. |
| 26 | +
|
| 27 | + Args: |
| 28 | + tool: The ADK tool to convert. It should be an instance of a class derived |
| 29 | + from `BaseTool`. |
| 30 | +
|
| 31 | + Returns: |
| 32 | + An object of MCP Tool type, representing the converted tool. |
| 33 | +
|
| 34 | + Examples: |
| 35 | + # Assuming 'my_tool' is an instance of a BaseTool derived class |
| 36 | + mcp_tool = adk_to_mcp_tool_type(my_tool) |
| 37 | + print(mcp_tool) |
| 38 | + """ |
| 39 | + tool_declaration = tool._get_declaration() |
| 40 | + if not tool_declaration: |
| 41 | + input_schema = {} |
| 42 | + else: |
| 43 | + input_schema = gemini_to_json_schema(tool._get_declaration().parameters) |
| 44 | + return mcp_types.Tool( |
| 45 | + name=tool.name, |
| 46 | + description=tool.description, |
| 47 | + inputSchema=input_schema, |
| 48 | + ) |
49 | 49 |
|
50 | 50 |
|
51 | 51 | def gemini_to_json_schema(gemini_schema: Schema) -> Dict[str, Any]:
|
52 |
| - """Converts a Gemini Schema object into a JSON Schema dictionary. |
53 |
| -
|
54 |
| - Args: |
55 |
| - gemini_schema: An instance of the Gemini Schema class. |
56 |
| -
|
57 |
| - Returns: |
58 |
| - A dictionary representing the equivalent JSON Schema. |
59 |
| -
|
60 |
| - Raises: |
61 |
| - TypeError: If the input is not an instance of the expected Schema class. |
62 |
| - ValueError: If an invalid Gemini Type enum value is encountered. |
63 |
| - """ |
64 |
| - if not isinstance(gemini_schema, Schema): |
65 |
| - raise TypeError( |
66 |
| - f"Input must be an instance of Schema, got {type(gemini_schema)}" |
67 |
| - ) |
68 |
| - |
69 |
| - json_schema_dict: Dict[str, Any] = {} |
70 |
| - |
71 |
| - # Map Type |
72 |
| - gemini_type = getattr(gemini_schema, "type", None) |
73 |
| - if gemini_type and gemini_type != Type.TYPE_UNSPECIFIED: |
74 |
| - json_schema_dict["type"] = gemini_type.lower() |
75 |
| - else: |
76 |
| - json_schema_dict["type"] = "null" |
77 |
| - |
78 |
| - # Map Nullable |
79 |
| - if getattr(gemini_schema, "nullable", None) == True: |
80 |
| - json_schema_dict["nullable"] = True |
81 |
| - |
82 |
| - # --- Map direct fields --- |
83 |
| - direct_mappings = { |
84 |
| - "title": "title", |
85 |
| - "description": "description", |
86 |
| - "default": "default", |
87 |
| - "enum": "enum", |
88 |
| - "format": "format", |
89 |
| - "example": "example", |
90 |
| - } |
91 |
| - for gemini_key, json_key in direct_mappings.items(): |
92 |
| - value = getattr(gemini_schema, gemini_key, None) |
93 |
| - if value is not None: |
94 |
| - json_schema_dict[json_key] = value |
95 |
| - |
96 |
| - # String validation |
97 |
| - if gemini_type == Type.STRING: |
98 |
| - str_mappings = { |
99 |
| - "pattern": "pattern", |
100 |
| - "min_length": "minLength", |
101 |
| - "max_length": "maxLength", |
102 |
| - } |
103 |
| - for gemini_key, json_key in str_mappings.items(): |
104 |
| - value = getattr(gemini_schema, gemini_key, None) |
105 |
| - if value is not None: |
106 |
| - json_schema_dict[json_key] = value |
107 |
| - |
108 |
| - # Number/Integer validation |
109 |
| - if gemini_type in (Type.NUMBER, Type.INTEGER): |
110 |
| - num_mappings = { |
111 |
| - "minimum": "minimum", |
112 |
| - "maximum": "maximum", |
113 |
| - } |
114 |
| - for gemini_key, json_key in num_mappings.items(): |
115 |
| - value = getattr(gemini_schema, gemini_key, None) |
116 |
| - if value is not None: |
117 |
| - json_schema_dict[json_key] = value |
118 |
| - |
119 |
| - # Array validation (Recursive call for items) |
120 |
| - if gemini_type == Type.ARRAY: |
121 |
| - items_schema = getattr(gemini_schema, "items", None) |
122 |
| - if items_schema is not None: |
123 |
| - json_schema_dict["items"] = gemini_to_json_schema(items_schema) |
124 |
| - |
125 |
| - arr_mappings = { |
126 |
| - "min_items": "minItems", |
127 |
| - "max_items": "maxItems", |
128 |
| - } |
129 |
| - for gemini_key, json_key in arr_mappings.items(): |
130 |
| - value = getattr(gemini_schema, gemini_key, None) |
131 |
| - if value is not None: |
132 |
| - json_schema_dict[json_key] = value |
133 |
| - |
134 |
| - # Object validation (Recursive call for properties) |
135 |
| - if gemini_type == Type.OBJECT: |
136 |
| - properties_dict = getattr(gemini_schema, "properties", None) |
137 |
| - if properties_dict is not None: |
138 |
| - json_schema_dict["properties"] = { |
139 |
| - prop_name: gemini_to_json_schema(prop_schema) |
140 |
| - for prop_name, prop_schema in properties_dict.items() |
141 |
| - } |
142 |
| - |
143 |
| - obj_mappings = { |
144 |
| - "required": "required", |
145 |
| - "min_properties": "minProperties", |
146 |
| - "max_properties": "maxProperties", |
147 |
| - # Note: Ignoring 'property_ordering' as it's not standard JSON Schema |
| 52 | + """Converts a Gemini Schema object into a JSON Schema dictionary. |
| 53 | +
|
| 54 | + Args: |
| 55 | + gemini_schema: An instance of the Gemini Schema class. |
| 56 | +
|
| 57 | + Returns: |
| 58 | + A dictionary representing the equivalent JSON Schema. |
| 59 | +
|
| 60 | + Raises: |
| 61 | + TypeError: If the input is not an instance of the expected Schema class. |
| 62 | + ValueError: If an invalid Gemini Type enum value is encountered. |
| 63 | + """ |
| 64 | + if not isinstance(gemini_schema, Schema): |
| 65 | + raise TypeError( |
| 66 | + f"Input must be an instance of Schema, got {type(gemini_schema)}" |
| 67 | + ) |
| 68 | + |
| 69 | + json_schema_dict: Dict[str, Any] = {} |
| 70 | + |
| 71 | + # Map Type |
| 72 | + gemini_type = getattr(gemini_schema, "type", None) |
| 73 | + if gemini_type and gemini_type != Type.TYPE_UNSPECIFIED: |
| 74 | + json_schema_dict["type"] = gemini_type.lower() |
| 75 | + else: |
| 76 | + json_schema_dict["type"] = "null" |
| 77 | + |
| 78 | + # Map Nullable |
| 79 | + if getattr(gemini_schema, "nullable", None) == True: |
| 80 | + json_schema_dict["nullable"] = True |
| 81 | + |
| 82 | + # --- Map direct fields --- |
| 83 | + direct_mappings = { |
| 84 | + "title": "title", |
| 85 | + "description": "description", |
| 86 | + "default": "default", |
| 87 | + "enum": "enum", |
| 88 | + "format": "format", |
| 89 | + "example": "example", |
148 | 90 | }
|
149 |
| - for gemini_key, json_key in obj_mappings.items(): |
150 |
| - value = getattr(gemini_schema, gemini_key, None) |
151 |
| - if value is not None: |
152 |
| - json_schema_dict[json_key] = value |
153 |
| - |
154 |
| - # Map anyOf (Recursive call for subschemas) |
155 |
| - any_of_list = getattr(gemini_schema, "any_of", None) |
156 |
| - if any_of_list is not None: |
157 |
| - json_schema_dict["anyOf"] = [ |
158 |
| - gemini_to_json_schema(sub_schema) for sub_schema in any_of_list |
159 |
| - ] |
160 |
| - |
161 |
| - return json_schema_dict |
| 91 | + for gemini_key, json_key in direct_mappings.items(): |
| 92 | + value = getattr(gemini_schema, gemini_key, None) |
| 93 | + if value is not None: |
| 94 | + json_schema_dict[json_key] = value |
| 95 | + |
| 96 | + # String validation |
| 97 | + if gemini_type == Type.STRING: |
| 98 | + str_mappings = { |
| 99 | + "pattern": "pattern", |
| 100 | + "min_length": "minLength", |
| 101 | + "max_length": "maxLength", |
| 102 | + } |
| 103 | + for gemini_key, json_key in str_mappings.items(): |
| 104 | + value = getattr(gemini_schema, gemini_key, None) |
| 105 | + if value is not None: |
| 106 | + json_schema_dict[json_key] = value |
| 107 | + |
| 108 | + # Number/Integer validation |
| 109 | + if gemini_type in (Type.NUMBER, Type.INTEGER): |
| 110 | + num_mappings = { |
| 111 | + "minimum": "minimum", |
| 112 | + "maximum": "maximum", |
| 113 | + } |
| 114 | + for gemini_key, json_key in num_mappings.items(): |
| 115 | + value = getattr(gemini_schema, gemini_key, None) |
| 116 | + if value is not None: |
| 117 | + json_schema_dict[json_key] = value |
| 118 | + |
| 119 | + # Array validation (Recursive call for items) |
| 120 | + if gemini_type == Type.ARRAY: |
| 121 | + items_schema = getattr(gemini_schema, "items", None) |
| 122 | + if items_schema is not None: |
| 123 | + json_schema_dict["items"] = gemini_to_json_schema(items_schema) |
| 124 | + |
| 125 | + arr_mappings = { |
| 126 | + "min_items": "minItems", |
| 127 | + "max_items": "maxItems", |
| 128 | + } |
| 129 | + for gemini_key, json_key in arr_mappings.items(): |
| 130 | + value = getattr(gemini_schema, gemini_key, None) |
| 131 | + if value is not None: |
| 132 | + json_schema_dict[json_key] = value |
| 133 | + |
| 134 | + # Object validation (Recursive call for properties) |
| 135 | + if gemini_type == Type.OBJECT: |
| 136 | + properties_dict = getattr(gemini_schema, "properties", None) |
| 137 | + if properties_dict is not None: |
| 138 | + json_schema_dict["properties"] = { |
| 139 | + prop_name: gemini_to_json_schema(prop_schema) |
| 140 | + for prop_name, prop_schema in properties_dict.items() |
| 141 | + } |
| 142 | + |
| 143 | + obj_mappings = { |
| 144 | + "required": "required", |
| 145 | + "min_properties": "minProperties", |
| 146 | + "max_properties": "maxProperties", |
| 147 | + # Note: Ignoring 'property_ordering' as it's not standard JSON Schema |
| 148 | + } |
| 149 | + for gemini_key, json_key in obj_mappings.items(): |
| 150 | + value = getattr(gemini_schema, gemini_key, None) |
| 151 | + if value is not None: |
| 152 | + json_schema_dict[json_key] = value |
| 153 | + |
| 154 | + # Map anyOf (Recursive call for subschemas) |
| 155 | + any_of_list = getattr(gemini_schema, "any_of", None) |
| 156 | + if any_of_list is not None: |
| 157 | + json_schema_dict["anyOf"] = [ |
| 158 | + gemini_to_json_schema(sub_schema) for sub_schema in any_of_list |
| 159 | + ] |
| 160 | + |
| 161 | + return json_schema_dict |
0 commit comments