From 7e70d83c243c1f87f2bbce3c6938385b3fdeac89 Mon Sep 17 00:00:00 2001 From: Dhruv Gupta Date: Thu, 12 Feb 2026 15:24:57 -0800 Subject: [PATCH 1/2] Sanitize MCP tool output items in openai-agents-sdk template MCP tools (e.g. Genie) can return list outputs that fail Pydantic validation. Add sanitize_output_items to both invoke and stream paths. Co-Authored-By: Claude Opus 4.6 --- agent-openai-agents-sdk/agent_server/agent.py | 6 +++-- agent-openai-agents-sdk/agent_server/utils.py | 23 ++++++++++++++++++- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/agent-openai-agents-sdk/agent_server/agent.py b/agent-openai-agents-sdk/agent_server/agent.py index ddd67a7b..ef70521f 100644 --- a/agent-openai-agents-sdk/agent_server/agent.py +++ b/agent-openai-agents-sdk/agent_server/agent.py @@ -13,8 +13,10 @@ ) from agent_server.utils import ( + build_mcp_url, get_user_workspace_client, - process_agent_stream_events, build_mcp_url, + process_agent_stream_events, + sanitize_output_items, ) # NOTE: this will work for all databricks models OTHER than GPT-OSS, which uses a slightly different API @@ -48,7 +50,7 @@ async def invoke(request: ResponsesAgentRequest) -> ResponsesAgentResponse: agent = create_coding_agent(mcp_server) messages = [i.model_dump() for i in request.input] result = await Runner.run(agent, messages) - return ResponsesAgentResponse(output=[item.to_input_item() for item in result.new_items]) + return ResponsesAgentResponse(output=sanitize_output_items(result.new_items)) @stream() diff --git a/agent-openai-agents-sdk/agent_server/utils.py b/agent-openai-agents-sdk/agent_server/utils.py index 2386c3e4..c9dc83f4 100644 --- a/agent-openai-agents-sdk/agent_server/utils.py +++ b/agent-openai-agents-sdk/agent_server/utils.py @@ -1,3 +1,4 @@ +import json import logging from typing import AsyncGenerator, AsyncIterator, Optional from uuid import uuid4 @@ -29,6 +30,26 @@ def get_user_workspace_client() -> WorkspaceClient: return WorkspaceClient(token=token, auth_type="pat") +def _sanitize_item(input_item: dict) -> dict: + """Sanitize a single output item dict for Pydantic validation. + + MCP tool calls (e.g. Genie) can return items where the ``output`` field is + a *list* of content objects instead of a plain string. MLflow's Pydantic + models expect ``output`` to be a string, so this serialises any non-string + values to JSON. + + TODO: Remove once https://github.com/mlflow/mlflow/pull/20777 is released. + """ + if isinstance(input_item.get("output"), list): + input_item["output"] = json.dumps(input_item["output"]) + return input_item + + +def sanitize_output_items(items) -> list[dict]: + """Convert agent output items to dicts safe for ResponsesAgentResponse.""" + return [_sanitize_item(item.to_input_item()) for item in items] + + async def process_agent_stream_events( async_stream: AsyncIterator[StreamEvent], ) -> AsyncGenerator[ResponsesAgentStreamEvent, None]: @@ -47,5 +68,5 @@ async def process_agent_stream_events( elif event.type == "run_item_stream_event" and event.item.type == "tool_call_output_item": yield ResponsesAgentStreamEvent( type="response.output_item.done", - item=event.item.to_input_item(), + item=_sanitize_item(event.item.to_input_item()), ) From 64c35a5aaedd6d4804633d5fe028127a5dc230af Mon Sep 17 00:00:00 2001 From: Bryan Qiu Date: Thu, 12 Feb 2026 17:19:08 -0800 Subject: [PATCH 2/2] . Signed-off-by: Bryan Qiu --- agent-openai-agents-sdk/agent_server/utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/agent-openai-agents-sdk/agent_server/utils.py b/agent-openai-agents-sdk/agent_server/utils.py index c9dc83f4..e6c92378 100644 --- a/agent-openai-agents-sdk/agent_server/utils.py +++ b/agent-openai-agents-sdk/agent_server/utils.py @@ -40,8 +40,11 @@ def _sanitize_item(input_item: dict) -> dict: TODO: Remove once https://github.com/mlflow/mlflow/pull/20777 is released. """ - if isinstance(input_item.get("output"), list): - input_item["output"] = json.dumps(input_item["output"]) + if not isinstance(input_item.get("output"), str): + try: + input_item["output"] = json.dumps(input_item.get("output")) + except (TypeError, ValueError): + input_item["output"] = str(input_item.get("output")) return input_item