Skip to content

fix: send OpenAI tool results as string content - #688

Open
MukundaKatta wants to merge 1 commit into
lastmile-ai:mainfrom
MukundaKatta:codex/mcp-agent-openai-content-string
Open

fix: send OpenAI tool results as string content#688
MukundaKatta wants to merge 1 commit into
lastmile-ai:mainfrom
MukundaKatta:codex/mcp-agent-openai-content-string

Conversation

@MukundaKatta

@MukundaKatta MukundaKatta commented May 15, 2026

Copy link
Copy Markdown

Fixes #25.

Summary

  • Convert MCP tool results to string content for OpenAI tool messages instead of sending content part arrays
  • Preserve text and text resources directly, joining multiple text parts with newlines
  • Keep existing OpenAI content part conversion as the fallback for non-text content
  • Add regression coverage for execute_tool_call and multi-part text tool results

Tests

  • uv run ruff format src/mcp_agent/workflows/llm/augmented_llm_openai.py tests/workflows/llm/test_augmented_llm_openai.py
  • uv run ruff check src/mcp_agent/workflows/llm/augmented_llm_openai.py tests/workflows/llm/test_augmented_llm_openai.py
  • uv run pytest tests/workflows/llm/test_augmented_llm_openai.py -k "execute_tool_call_returns_string_content or tool_message_content_conversion_joins_text_parts" -q
  • uv run pytest tests/workflows/llm/test_augmented_llm_openai.py -q

Summary by CodeRabbit

  • Tests

    • Added test coverage for tool message content formatting and multi-part content concatenation
  • Refactor

    • Improved the formatting of tool call results to use a streamlined content conversion approach

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 15, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 517e19b6-c261-49f6-ac5b-662938ae0994

📥 Commits

Reviewing files that changed from the base of the PR and between f62d849 and 7774750.

📒 Files selected for processing (2)
  • src/mcp_agent/workflows/llm/augmented_llm_openai.py
  • tests/workflows/llm/test_augmented_llm_openai.py

📝 Walkthrough

Walkthrough

The PR addresses OpenAI API compatibility by converting tool message content from a list structure to a single string format. A new helper function flattens MCP content elements into newline-joined text, the tool call execution path integrates this helper, and tests validate the new behavior with appropriate test infrastructure.

Changes

Tool Message Content String Formatting

Layer / File(s) Summary
Tool message content conversion helper
src/mcp_agent/workflows/llm/augmented_llm_openai.py
New mcp_content_to_openai_tool_message_content function converts MCP content elements (TextContent, ImageContent, EmbeddedResource) into a single newline-joined string, extracting text directly and falling back to stringified content-part conversion for non-text types.
Execute tool call integration
src/mcp_agent/workflows/llm/augmented_llm_openai.py
execute_tool_call now uses the new helper to set ChatCompletionToolMessageParam.content as a string instead of building a list of content part objects, ensuring OpenAI API compatibility.
Test infrastructure and validation
tests/workflows/llm/test_augmented_llm_openai.py
Adds _OpenAITestLLM subclass with generate_stream override for test isolation, updates mock_llm fixture, and introduces two new tests validating string content return and newline-joined text concatenation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • lastmile-ai/mcp-agent#330: Both PRs modify OpenAIAugmentedLLM.execute_tool_call in src/mcp_agent/workflows/llm/augmented_llm_openai.py, changing how result.content is handled and converted into ChatCompletionToolMessageParam.
  • lastmile-ai/mcp-agent#341: Both PRs modify the tool-call content conversion path in src/mcp_agent/workflows/llm/augmented_llm_openai.py—this PR changes how execute_tool_call formats content as a string, while the other adjusts mcp_content_to_openai_content_part used during content-part conversion.

Suggested reviewers

  • rholinshead
  • saqadri

Poem

🐰 A list became a string, the API cried with glee,
Tool messages now flow as text—OpenAI's harmony!
No more arrays confusing DeepSeek's parsing mind,
Just newlines joining wisdom, structured and kind. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: converting OpenAI tool results to string content format instead of content arrays.
Linked Issues check ✅ Passed The PR fully addresses issue #25 by converting MCP tool results to strings for OpenAI, preserving text directly, joining multiple parts with newlines, and falling back to existing content conversion for non-text types.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue: a new helper function, modified execute_tool_call behavior, test subclass for mocking, and two targeted test cases.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

content in OpenAI ChatCompletion messages is a list, not string

1 participant