mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-07 19:20:34 +00:00
fix(mcp): degrade a blob without mimeType instead of failing the tool call (#7800)
* fix(mcp): degrade a blob without mimeType instead of failing the tool call A resource link or embedded resource without mimeType made the blob guard raise, so the whole tool call failed instead of degrading the attachment. Keep the guard for genuinely unusable payloads and let a missing media type fall through to the caller's default. * Modify test for text blocks and mime type validation Update test to check for text blocks and their mime types. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * test(mcp): remove MIME assertion from text content block --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
4a53a36e32
commit
2feec9cb09
@ -604,7 +604,17 @@ def _convert_call_tool_result(
|
||||
if mime and mime.startswith("image/"):
|
||||
lc_content.append(create_image_block(base64=res.blob, mime_type=mime))
|
||||
else:
|
||||
lc_content.append(create_file_block(base64=res.blob, mime_type=mime))
|
||||
# ``BlobResourceContents.mimeType`` is optional in the MCP spec, but
|
||||
# langchain-core refuses a base64 block without one. Degrade to a
|
||||
# generic binary type instead of raising, so the rest of the result —
|
||||
# including the text blocks the server returned — survives. The
|
||||
# sibling ``ResourceLink`` branch already degrades the same way.
|
||||
lc_content.append(
|
||||
create_file_block(
|
||||
base64=res.blob,
|
||||
mime_type=mime or "application/octet-stream",
|
||||
)
|
||||
)
|
||||
else:
|
||||
lc_content.append(create_text_block(text=str(res)))
|
||||
else:
|
||||
|
||||
51
backend/tests/test_mcp_blob_missing_mime_type.py
Normal file
51
backend/tests/test_mcp_blob_missing_mime_type.py
Normal file
@ -0,0 +1,51 @@
|
||||
"""An MCP blob without a mimeType must degrade, not fail the whole tool call."""
|
||||
|
||||
import base64
|
||||
|
||||
from mcp.types import BlobResourceContents, CallToolResult, EmbeddedResource, TextContent
|
||||
|
||||
from deerflow.mcp.tools import _convert_call_tool_result
|
||||
|
||||
BLOB = base64.b64encode(b"binary payload").decode("ascii")
|
||||
|
||||
|
||||
def _result(mime_type: str | None, *, with_text: bool = True) -> CallToolResult:
|
||||
content = [TextContent(type="text", text="here is your report")] if with_text else []
|
||||
content.append(
|
||||
EmbeddedResource(
|
||||
type="resource",
|
||||
resource=BlobResourceContents(uri="file:///tmp/report.bin", blob=BLOB, mimeType=mime_type),
|
||||
)
|
||||
)
|
||||
return CallToolResult(content=content, isError=False)
|
||||
|
||||
|
||||
def test_blob_without_mime_type_degrades_to_octet_stream():
|
||||
lc_content, _artifact = _convert_call_tool_result(_result(None))
|
||||
|
||||
assert [block["type"] for block in lc_content] == ["text", "file"]
|
||||
assert lc_content[0]["text"] == "here is your report"
|
||||
assert lc_content[1]["mime_type"] == "application/octet-stream"
|
||||
assert lc_content[1]["base64"] == BLOB
|
||||
|
||||
|
||||
def test_text_blocks_survive_the_fallback():
|
||||
lc_content, _artifact = _convert_call_tool_result(_result(None))
|
||||
|
||||
assert [block["type"] for block in lc_content] == ["text", "file"]
|
||||
assert lc_content[0]["text"] == "here is your report"
|
||||
assert lc_content[1]["mime_type"] == "application/octet-stream"
|
||||
|
||||
|
||||
def test_declared_non_image_mime_type_is_preserved():
|
||||
lc_content, _artifact = _convert_call_tool_result(_result("application/pdf"))
|
||||
|
||||
assert lc_content[1]["type"] == "file"
|
||||
assert lc_content[1]["mime_type"] == "application/pdf"
|
||||
|
||||
|
||||
def test_declared_image_mime_type_still_becomes_an_image_block():
|
||||
lc_content, _artifact = _convert_call_tool_result(_result("image/png"))
|
||||
|
||||
assert [block["type"] for block in lc_content] == ["text", "image"]
|
||||
assert lc_content[1]["mime_type"] == "image/png"
|
||||
Loading…
x
Reference in New Issue
Block a user