Skip to content

Commit 8154885

Browse files
committed
chore: Enabled parsing nested metadata from resource. Code could be simplified?
experimental: Is the nested metadata assumption right? See line 475 in mcp.py
1 parent 41b3aa4 commit 8154885

File tree

1 file changed

+35
-14
lines changed
  • pydantic_ai_slim/pydantic_ai

1 file changed

+35
-14
lines changed

pydantic_ai_slim/pydantic_ai/mcp.py

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -272,24 +272,23 @@ async def direct_call_tool(
272272

273273
parts_with_metadata = [await self._map_tool_result_part(part) for part in result.content]
274274
parts_only = [part for part, _ in parts_with_metadata]
275-
any_part_has_metadata = any(metadata is not None for _, metadata in parts_with_metadata)
275+
# any_part_has_metadata = any(metadata is not None for _, metadata in parts_with_metadata)
276276
return_values: list[Any] = []
277277
user_contents: list[Any] = []
278278
parts_metadata: dict[int, dict[str, Any]] = {}
279279
return_metadata: dict[str, Any] = {}
280-
if any_part_has_metadata:
281-
# There is metadata in the tool result parts and there may be a metadata in the tool result, return a ToolReturn object
282-
for idx, (part, part_metadata) in enumerate(parts_with_metadata):
283-
if part_metadata is not None:
284-
parts_metadata[idx] = part_metadata
285-
# TODO: Keep updated with the multimodal content parsing in _agent_graph.py
286-
if isinstance(part, messages.BinaryContent):
287-
identifier = part.identifier
288-
289-
return_values.append(f'See file {identifier}')
290-
user_contents.append([f'This is file {identifier}:', part])
291-
else:
292-
user_contents.append(part)
280+
# if any_part_has_metadata:
281+
for idx, (part, part_metadata) in enumerate(parts_with_metadata):
282+
if part_metadata is not None:
283+
parts_metadata[idx] = part_metadata
284+
# TODO: Keep updated with the multimodal content parsing in _agent_graph.py
285+
if isinstance(part, messages.BinaryContent):
286+
identifier = part.identifier
287+
288+
return_values.append(f'See file {identifier}')
289+
user_contents.append([f'This is file {identifier}:', part])
290+
else:
291+
user_contents.append(part)
293292

294293
if len(parts_metadata) > 0:
295294
if result.meta is not None and len(result.meta) > 0:
@@ -453,6 +452,28 @@ async def _map_tool_result_part(
453452
return self._get_content(part.resource), metadata
454453
elif isinstance(part, mcp_types.ResourceLink):
455454
resource_result: mcp_types.ReadResourceResult = await self._client.read_resource(part.uri)
455+
# Check if metadata already exists. If so, merge it with nested the resource metadata.
456+
parts_metadata: dict[int, dict[str, Any]] = {}
457+
nested_metadata: dict[str, Any] = {}
458+
for idx, content in enumerate(resource_result.contents):
459+
if content.meta is not None:
460+
parts_metadata[idx] = content.meta
461+
if len(parts_metadata) > 0:
462+
if resource_result.meta is not None and len(resource_result.meta) > 0:
463+
# Merge the tool result metadata and parts metadata into the return metadata
464+
nested_metadata = {'result': resource_result.meta, 'content': parts_metadata}
465+
else:
466+
# Only parts metadata exists
467+
if len(parts_metadata) == 1:
468+
# If there is only one content metadata, unwrap it
469+
nested_metadata = parts_metadata[0]
470+
else:
471+
nested_metadata = {'content': parts_metadata}
472+
else:
473+
if resource_result.meta is not None and len(resource_result.meta) > 0:
474+
nested_metadata = resource_result.meta
475+
# FIXME: Is this a correct assumption? If metadata was read from the part then that is the same as resource_result.meta
476+
metadata = nested_metadata
456477
if len(resource_result.contents) == 1:
457478
return self._get_content(resource_result.contents[0]), metadata
458479
else:

0 commit comments

Comments
 (0)