Jeremiah Lowin commited on
Commit
51336fb
·
unverified ·
1 Parent(s): 4a12d22

Add unit test for sampling with image messages (#1329)

Browse files
Files changed (1) hide show
  1. tests/client/test_sampling.py +59 -4
tests/client/test_sampling.py CHANGED
@@ -1,10 +1,12 @@
1
- from typing import cast
2
 
3
  import pytest
4
  from mcp.types import TextContent
 
5
 
6
  from fastmcp import Client, Context, FastMCP
7
  from fastmcp.client.sampling import RequestContext, SamplingMessage, SamplingParams
 
8
 
9
 
10
  @pytest.fixture
@@ -14,12 +16,12 @@ def fastmcp_server():
14
  @mcp.tool
15
  async def simple_sample(message: str, context: Context) -> str:
16
  result = await context.sample("Hello, world!")
17
- return cast(TextContent, result).text
18
 
19
  @mcp.tool
20
  async def sample_with_system_prompt(message: str, context: Context) -> str:
21
  result = await context.sample("Hello, world!", system_prompt="You love FastMCP")
22
- return cast(TextContent, result).text
23
 
24
  @mcp.tool
25
  async def sample_with_messages(message: str, context: Context) -> str:
@@ -34,7 +36,25 @@ def fastmcp_server():
34
  ),
35
  ]
36
  )
37
- return cast(TextContent, result).text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  return mcp
40
 
@@ -80,3 +100,38 @@ async def test_sampling_with_messages(fastmcp_server: FastMCP):
80
  "sample_with_messages", {"message": "Hello, world!"}
81
  )
82
  assert result.data == "I need to think."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
 
3
  import pytest
4
  from mcp.types import TextContent
5
+ from pydantic_core import to_json
6
 
7
  from fastmcp import Client, Context, FastMCP
8
  from fastmcp.client.sampling import RequestContext, SamplingMessage, SamplingParams
9
+ from fastmcp.utilities.types import Image
10
 
11
 
12
  @pytest.fixture
 
16
  @mcp.tool
17
  async def simple_sample(message: str, context: Context) -> str:
18
  result = await context.sample("Hello, world!")
19
+ return result.text # type: ignore[attr-defined]
20
 
21
  @mcp.tool
22
  async def sample_with_system_prompt(message: str, context: Context) -> str:
23
  result = await context.sample("Hello, world!", system_prompt="You love FastMCP")
24
+ return result.text # type: ignore[attr-defined]
25
 
26
  @mcp.tool
27
  async def sample_with_messages(message: str, context: Context) -> str:
 
36
  ),
37
  ]
38
  )
39
+ return result.text # type: ignore[attr-defined]
40
+
41
+ @mcp.tool
42
+ async def sample_with_image(image_bytes: bytes, context: Context) -> str:
43
+ image = Image(data=image_bytes)
44
+
45
+ result = await context.sample(
46
+ [
47
+ SamplingMessage(
48
+ content=TextContent(type="text", text="What's in this image?"),
49
+ role="user",
50
+ ),
51
+ SamplingMessage(
52
+ content=image.to_image_content(),
53
+ role="user",
54
+ ),
55
+ ]
56
+ )
57
+ return result.text # type: ignore[attr-defined]
58
 
59
  return mcp
60
 
 
100
  "sample_with_messages", {"message": "Hello, world!"}
101
  )
102
  assert result.data == "I need to think."
103
+
104
+
105
+ async def test_sampling_with_image(fastmcp_server: FastMCP):
106
+ def sampling_handler(
107
+ messages: list[SamplingMessage], params: SamplingParams, ctx: RequestContext
108
+ ) -> str:
109
+ assert len(messages) == 2
110
+ return to_json(messages).decode()
111
+
112
+ async with Client(fastmcp_server, sampling_handler=sampling_handler) as client:
113
+ image_bytes = b"abc123"
114
+ result = await client.call_tool(
115
+ "sample_with_image", {"image_bytes": image_bytes}
116
+ )
117
+ assert json.loads(result.data) == [
118
+ {
119
+ "role": "user",
120
+ "content": {
121
+ "type": "text",
122
+ "text": "What's in this image?",
123
+ "annotations": None,
124
+ "_meta": None,
125
+ },
126
+ },
127
+ {
128
+ "role": "user",
129
+ "content": {
130
+ "type": "image",
131
+ "data": "YWJjMTIz",
132
+ "mimeType": "image/png",
133
+ "annotations": None,
134
+ "_meta": None,
135
+ },
136
+ },
137
+ ]