Skip to content

Commit dfe81b6

Browse files
committed
chore: Added code to handle multi-modal content and metadata.
todo: Exhaustive tests to improve coverage.
1 parent ad73591 commit dfe81b6

File tree

1 file changed

+56
-8
lines changed
  • pydantic_ai_slim/pydantic_ai

1 file changed

+56
-8
lines changed

pydantic_ai_slim/pydantic_ai/mcp.py

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -403,23 +403,71 @@ async def _map_tool_result_part(
403403
pass
404404
return text if metadata is None else messages.ToolReturn(return_value=text, metadata=metadata)
405405
elif isinstance(part, mcp_types.ImageContent):
406-
return messages.BinaryContent(data=base64.b64decode(part.data), media_type=part.mimeType)
406+
binary_response = messages.BinaryContent(data=base64.b64decode(part.data), media_type=part.mimeType)
407+
return (
408+
binary_response
409+
if metadata is None
410+
else messages.ToolReturn(
411+
return_value=f'See file {binary_response.identifier}',
412+
content=[f'This is file {binary_response.identifier}:', binary_response],
413+
metadata=metadata,
414+
)
415+
)
407416
elif isinstance(part, mcp_types.AudioContent):
408417
# NOTE: The FastMCP server doesn't support audio content.
409418
# See <https://github.com/modelcontextprotocol/python-sdk/issues/952> for more details.
410-
return messages.BinaryContent(
419+
binary_response = messages.BinaryContent(
411420
data=base64.b64decode(part.data), media_type=part.mimeType
412421
) # pragma: no cover
422+
return (
423+
binary_response
424+
if metadata is None
425+
else messages.ToolReturn(
426+
return_value=f'See file {binary_response.identifier}',
427+
content=[f'This is file {binary_response.identifier}:', binary_response],
428+
metadata=metadata,
429+
)
430+
)
413431
elif isinstance(part, mcp_types.EmbeddedResource):
414432
resource = part.resource
415-
return self._get_content(resource)
416-
elif isinstance(part, mcp_types.ResourceLink):
417-
resource_result: mcp_types.ReadResourceResult = await self._client.read_resource(part.uri)
433+
response = self._get_content(resource)
418434
return (
419-
self._get_content(resource_result.contents[0])
420-
if len(resource_result.contents) == 1
421-
else [self._get_content(resource) for resource in resource_result.contents]
435+
response
436+
if metadata is None
437+
else messages.ToolReturn(
438+
return_value=response if isinstance(response, str) else f'See file {response.identifier}',
439+
content=None if isinstance(response, str) else [f'This is file {response.identifier}:', response],
440+
metadata=metadata,
441+
)
422442
)
443+
elif isinstance(part, mcp_types.ResourceLink):
444+
resource_result: mcp_types.ReadResourceResult = await self._client.read_resource(part.uri)
445+
if len(resource_result.contents) == 1:
446+
response = self._get_content(resource_result.contents[0])
447+
return (
448+
response
449+
if metadata is None
450+
else messages.ToolReturn(
451+
return_value=response if isinstance(response, str) else f'See file {response.identifier}',
452+
content=None
453+
if isinstance(response, str)
454+
else [f'This is file {response.identifier}:', response],
455+
metadata=metadata,
456+
)
457+
)
458+
else:
459+
responses = [self._get_content(resource) for resource in resource_result.contents]
460+
return [
461+
response
462+
if isinstance(response, str)
463+
else messages.ToolReturn(
464+
return_value=response if isinstance(response, str) else f'See file {response.identifier}',
465+
content=None
466+
if isinstance(response, str)
467+
else [f'This is file {response.identifier}:', response],
468+
)
469+
for response in responses
470+
]
423471
else:
424472
assert_never(part)
425473

0 commit comments

Comments
 (0)