@@ -254,51 +254,34 @@ async def direct_call_tool(
254254 ):
255255 # The MCP SDK wraps primitives and generic types like list in a `result` key, but we want to use the raw value returned by the tool function.
256256 # See https://github.com/modelcontextprotocol/python-sdk#structured-output
257- if isinstance (structured , dict ) and len (structured ) == 1 and 'result' in structured :
258- return (
259- messages .ToolReturn (return_value = structured ['result' ], metadata = result .meta )
260- if result .meta
261- else structured ['result' ]
262- )
263- return messages .ToolReturn (return_value = structured , metadata = result .meta ) if result .meta else structured
257+ return_value = (
258+ structured ['result' ]
259+ if isinstance (structured , dict ) and len (structured ) == 1 and 'result' in structured
260+ else structured
261+ )
262+ return messages .ToolReturn (return_value = return_value , metadata = result .meta ) if result .meta else return_value
264263
265- mapped_part_metadata_tuple_list = [await self ._map_tool_result_part (part ) for part in result .content ]
266- if (
267- all (mapped_part_metadata_tuple [1 ] is None for mapped_part_metadata_tuple in mapped_part_metadata_tuple_list )
268- and result .meta is None
269- ):
264+ parts_with_metadata = [await self ._map_tool_result_part (part ) for part in result .content ]
265+ parts_only = [mapped_part for mapped_part , _ in parts_with_metadata ]
266+ any_part_has_metadata = any (metadata is not None for _ , metadata in parts_with_metadata )
267+ if not any_part_has_metadata and result .meta is None :
270268 # There is no metadata in the tool result or its parts, return just the mapped values
271- return (
272- mapped_part_metadata_tuple_list [0 ][0 ]
273- if len (mapped_part_metadata_tuple_list [0 ]) == 1
274- else [mapped_part_metadata_tuple [0 ] for mapped_part_metadata_tuple in mapped_part_metadata_tuple_list ]
275- )
276- elif (
277- all (mapped_part_metadata_tuple [1 ] is None for mapped_part_metadata_tuple in mapped_part_metadata_tuple_list )
278- and result .meta is not None
279- ):
269+ return parts_only [0 ] if len (parts_only ) == 1 else parts_only
270+ elif not any_part_has_metadata and result .meta is not None :
280271 # There is no metadata in the tool result parts, but there is metadata in the tool result
281272 return messages .ToolReturn (
282- return_value = (
283- mapped_part_metadata_tuple_list [0 ][0 ]
284- if len (mapped_part_metadata_tuple_list [0 ]) == 1
285- else [
286- mapped_part_metadata_tuple [0 ] for mapped_part_metadata_tuple in mapped_part_metadata_tuple_list
287- ]
288- ),
273+ return_value = (parts_only [0 ] if len (parts_only ) == 1 else parts_only ),
289274 metadata = result .meta ,
290275 )
291276 else :
292277 # There is metadata in the tool result parts and there may be a metadata in the tool result, return a ToolReturn object
293278 return_values : list [Any ] = []
294279 user_contents : list [Any ] = []
295280 return_metadata : dict [str , Any ] = {}
296- for idx , (mapped_part , part_metadata ) in enumerate (mapped_part_metadata_tuple_list ):
281+ return_metadata .setdefault ('content' , [])
282+ for idx , (mapped_part , part_metadata ) in enumerate (parts_with_metadata ):
297283 if part_metadata is not None :
298284 # Merge the metadata dictionaries, with part metadata taking precedence
299- if return_metadata .get ('content' , None ) is None :
300- # Create an empty list if it doesn't exist yet
301- return_metadata ['content' ] = list [dict [str , Any ]]()
302285 return_metadata ['content' ].append ({str (idx ): part_metadata })
303286 if isinstance (mapped_part , messages .BinaryContent ):
304287 identifier = mapped_part .identifier
0 commit comments