Skip to content

Support ImageContent and AudioContent in Message class#3396

Merged
jlowin merged 2 commits intoPrefectHQ:mainfrom
ericrobinson-indeed:fix-prompts-get-with-image-compatibility
Mar 6, 2026
Merged

Support ImageContent and AudioContent in Message class#3396
jlowin merged 2 commits intoPrefectHQ:mainfrom
ericrobinson-indeed:fix-prompts-get-with-image-compatibility

Conversation

@ericrobinson-indeed
Copy link
Copy Markdown
Contributor

Description

Message.content now accepts ImageContent and AudioContent in addition to TextContent and EmbeddedResource, matching MCP's ContentBlock type. This fixes ProxyPrompt.render() silently JSON-serializing image/audio content instead of preserving it.

🤖 Generated with Claude Code

Contributors Checklist

Review Checklist

  • [ X ] I have self-reviewed my changes
  • [ X ] My Pull Request is ready for review

Message.content now accepts ImageContent and AudioContent in addition to
TextContent and EmbeddedResource, matching MCP's ContentBlock type. This
fixes ProxyPrompt.render() silently JSON-serializing image/audio content
instead of preserving it.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@marvin-context-protocol
Copy link
Copy Markdown
Contributor

marvin-context-protocol Bot commented Mar 5, 2026

Test Failure Analysis

✏️ Edited to reflect the latest analysis (previous failure was a GitHub infrastructure issue; this is a real code failure).

Summary: The ty type checker fails because CachableMessage.content in src/fastmcp/server/middleware/caching.py is too narrow — it only accepts TextContent | EmbeddedResource, but this PR expanded Message.content to also include ImageContent | AudioContent.

Root Cause: CachableMessage (used for caching prompt results) was not updated alongside the Message class. When CachablePromptResult.wrap() constructs CachableMessage instances from Message objects (line 121), ty correctly flags that ImageContent and AudioContent cannot be assigned to the narrower TextContent | EmbeddedResource union.

Suggested Solution: Update CachableMessage.content in src/fastmcp/server/middleware/caching.py (line 104) to match the expanded union:

# Before
content: mcp.types.TextContent | mcp.types.EmbeddedResource

# After
content: mcp.types.TextContent | mcp.types.ImageContent | mcp.types.AudioContent | mcp.types.EmbeddedResource

Also check whether the # type: ignore[arg-type] on line 133 (in unwrap()) can be removed after this fix.

Detailed Analysis

The ty check step failed with:

error[invalid-argument-type]: Argument is incorrect
   --> src/fastmcp/server/middleware/caching.py:121:46
    |
119 |         return cls(
120 |             messages=[
121 |                 CachableMessage(role=m.role, content=m.content) for m in value.messages
    |                                              ^^^^^^^^^^^^^^^^^ Expected `TextContent | EmbeddedResource`, found `TextContent | ImageContent | AudioContent | EmbeddedResource`
    |
info: Union elements `ImageContent` and `AudioContent` are not assignable to `TextContent | EmbeddedResource`

The root: CachableMessage at line 104 of caching.py still has the old narrow type, while Message.content was expanded by this PR. The CachableMessage class exists solely as a serializable wrapper around Message for caching, so its content field should mirror Message.content exactly.

Related Files
  • src/fastmcp/server/middleware/caching.py:104CachableMessage.content type needs to include ImageContent and AudioContent
  • src/fastmcp/prompts/prompt.pyMessage.content was expanded by this PR (the intended change)

Copy link
Copy Markdown
Member

@jlowin jlowin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@jlowin jlowin merged commit 72d04d7 into PrefectHQ:main Mar 6, 2026
7 checks passed
@jlowin jlowin added the enhancement Improvement to existing functionality. For issues and smaller PR improvements. label Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement to existing functionality. For issues and smaller PR improvements.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression: Conformance test prompts-get-with-image fails in 3.X

2 participants