Skip to content

Commit fb9f5d1

Browse files
committed
Assert structured content for typing.Dict and NewType returns
1 parent 9d07811 commit fb9f5d1

2 files changed

Lines changed: 11 additions & 4 deletions

File tree

‎docs/servers/structured-output.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ Ask for a two-day forecast and `structured_content` is `{"result": [{...}, {...}
149149

150150
## Dictionaries
151151

152-
`dict[str, ...]` is the one generic that already *is* a JSON object, so it isn't wrapped:
152+
`dict[str, ...]` (or `typing.Dict[str, ...]`) is the one generic that already *is* a JSON object, so it isn't wrapped:
153153

154154
```python title="server.py" hl_lines="9"
155155
--8<-- "docs_src/structured_output/tutorial006.py"

‎tests/server/mcpserver/test_func_metadata.py‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,14 +296,18 @@ def func_dict_list() -> dict[str, list[int]]: # pragma: no cover
296296
"title": "func_dict_listDictOutput",
297297
}
298298

299-
def func_typing_dict() -> typing.Dict[str, str]: # noqa: UP006 # pragma: no cover
299+
def func_typing_dict() -> typing.Dict[str, str]: # noqa: UP006
300300
return {"name": "John"}
301301

302-
assert func_metadata(func_typing_dict).output_schema == {
302+
meta = func_metadata(func_typing_dict)
303+
assert meta.output_schema == {
303304
"type": "object",
304305
"additionalProperties": {"type": "string"},
305306
"title": "func_typing_dictDictOutput",
306307
}
308+
result = meta.convert_result(func_typing_dict())
309+
assert isinstance(result, CallToolResult)
310+
assert result.structured_content == {"name": "John"}
307311

308312
# Test dict[int, str] - should be wrapped since key is not str
309313
def func_dict_int_key() -> dict[int, str]: # pragma: no cover
@@ -786,7 +790,7 @@ def func_optional() -> str | None: # pragma: no cover
786790

787791
UserId = typing.NewType("UserId", int)
788792

789-
def func_new_type() -> UserId: # pragma: no cover
793+
def func_new_type() -> UserId:
790794
return UserId(1)
791795

792796
meta = func_metadata(func_new_type)
@@ -796,6 +800,9 @@ def func_new_type() -> UserId: # pragma: no cover
796800
"required": ["result"],
797801
"title": "func_new_typeOutput",
798802
}
803+
result = meta.convert_result(func_new_type())
804+
assert isinstance(result, CallToolResult)
805+
assert result.structured_content == {"result": 1}
799806

800807

801808
def test_structured_output_dataclass():

0 commit comments

Comments
 (0)