Skip to content

fix: preserve tool-call and tool-result parts in gen_ai.input.messages#890

Open
obs-gh-trevorColby wants to merge 2 commits intotraceloop:mainfrom
obs-gh-trevorColby:fix/preserve-tool-call-parts-in-input-messages
Open

fix: preserve tool-call and tool-result parts in gen_ai.input.messages#890
obs-gh-trevorColby wants to merge 2 commits intotraceloop:mainfrom
obs-gh-trevorColby:fix/preserve-tool-call-parts-in-input-messages

Conversation

@obs-gh-trevorColby
Copy link

@obs-gh-trevorColby obs-gh-trevorColby commented Feb 24, 2026

Summary

This PR fixes an issue where the transformPrompts function was converting all message content to text-only parts, which lost important tool call information in the gen_ai.input.messages attribute.

Problem

When using the Vercel AI SDK with traceloop instrumentation, tool interactions are captured in the prompt messages with different part types:

  • tool-call parts in assistant messages (containing tool name and arguments)
  • tool-result parts in tool messages (containing the tool output)

However, the current transformPrompts function uses processMessageContent() which extracts only text, losing all tool-call and tool-result information. This makes it impossible for observability tools to see:

  • Which tools were called
  • What arguments were passed to tools
  • What results were returned from tools

Solution

This PR adds a new processMessageParts function that properly preserves all part types:

  • Text parts: { type: "text", content: "..." }
  • Tool-call parts: { type: "tool_call", tool_call: { id, name, arguments } }
  • Tool-result parts: { type: "tool_result", tool_call_id, tool_name, content }

The transformPrompts function now uses processMessageParts(msg.content) instead of creating text-only parts.

Example

Before (broken)

[
  {"role": "user", "parts": [{"type": "text", "content": "What's the weather?"}]},
  {"role": "assistant", "parts": [{"type": "text", "content": ""}]},
  {"role": "tool", "parts": [{"type": "text", "content": "tool-result"}]}
]

After (fixed)

[
  {"role": "user", "parts": [{"type": "text", "content": "What's the weather?"}]},
  {"role": "assistant", "parts": [{"type": "tool_call", "tool_call": {"id": "call_123", "name": "getWeather", "arguments": "{\"city\": \"Seattle\"}"}}]},
  {"role": "tool", "parts": [{"type": "tool_result", "tool_call_id": "call_123", "tool_name": "getWeather", "content": "{\"temp\": 65, \"conditions\": \"sunny\"}"}]}
]

Backwards Compatibility

  • The existing processMessageContent function is unchanged (used for gen_ai.prompt.X.content)
  • Text-only messages continue to work as before
  • Messages without recognizable part types are serialized as text (fallback behavior)

Related Issue

Fixes #889


Pull Request opened by Augment Code with guidance from the PR author


Important

Fixes transformPrompts to preserve tool-call and tool-result parts using new processMessageParts function.

  • Behavior:
    • transformPrompts now uses processMessageParts to preserve tool-call and tool-result parts in gen_ai.input.messages.
    • processMessageParts handles text, tool-call, and tool-result parts, ensuring all are preserved.
  • Functions:
    • Adds processMessageParts to handle message content, preserving tool interaction data.
    • Modifies transformPrompts to use processMessageParts instead of processMessageContent.
  • Misc:
    • Adds TYPE_TOOL_RESULT constant for consistency in part type handling.

This description was created by Ellipsis for 1a9ce66. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • Improvements
    • Enhanced message content handling to better preserve tool-related information with increased fidelity during processing.

The transformPrompts function was converting all message content to text-only
parts, which lost important tool call information. This fix adds a new
processMessageParts function that properly preserves:

- Text parts: { type: "text", content: "..." }
- Tool-call parts: { type: "tool_call", tool_call: { id, name, arguments } }
- Tool-result parts: { type: "tool_result", tool_call_id, tool_name, content }

This allows observability tools to see the full context of tool interactions
in the gen_ai.input.messages attribute, including:
- Which tools were called (tool-call parts)
- What arguments were passed to tools
- What results were returned (tool-result parts)

Fixes traceloop#889
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 24, 2026

Warning

Rate limit exceeded

@obs-gh-trevorColby has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 30 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 1a9ce66 and 9f0e109.

📒 Files selected for processing (1)
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
📝 Walkthrough

Walkthrough

The changes introduce a new processMessageParts helper function that preserves tool_call and tool_result parts in message content processing. The helper handles multiple content formats and integrates into the message construction logic for both AI_PROMPT_MESSAGES and AI_PROMPT flows, supporting v4 and v5 tool structures.

Changes

Cohort / File(s) Summary
AI SDK Transformations
packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts
New processMessageParts helper transforms content into structured parts arrays while preserving tool_call and tool_result parts (previously stripped to text-only). Supports v4/v5 format variations, handles JSON-encoded arrays, and ensures at least one text part exists. Integrated into message construction for both AI_PROMPT_MESSAGES and AI_PROMPT flows.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Oh what joy! No more lost tool calls,
In message parts they stand so tall,
From v4 to v5, we preserve the way,
Tool results and calls now here to stay!
The SDK's heart beats true once more,
With parts complete, what's not to adore? ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: preserve tool-call and tool-result parts in gen_ai.input.messages' directly matches the main objective of the PR, which is to preserve tool-call and tool-result parts in messages.
Linked Issues check ✅ Passed The PR successfully addresses all coding requirements from issue #889: introduces processMessageParts function to preserve tool-call and tool-result message parts, supports both v4 and v5 AI SDK formats, integrates into gen_ai.input.messages construction, and ensures tool call visibility in conversation history.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #889 requirements: the new processMessageParts function and its integration into transformPrompts are focused solely on preserving message part types for gen_ai.input.messages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Copy link
Contributor

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

Looks good to me! 👍

Reviewed everything up to 1a9ce66 in 12 seconds. Click for details.
  • Reviewed 126 lines of code in 1 files
  • Skipped 0 files when reviewing.
  • Skipped posting 0 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.

Workflow ID: wflow_XT7Ge0XEfelftzf0

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts`:
- Around line 253-276: In processMessageParts, the v4/v5 precedence is reversed
and a hyphenated-only check is missing for results: change the tool-call
handling to prefer v5 fields (use item.input ?? item.args instead of item.args
?? item.input) and change the tool-result handling to prefer v5 output (use
item.output ?? item.result instead of item.result ?? item.output); also make the
"tool-result" branch accept both "tool-result" and "tool_result" like the
tool-call branch so tool_result is handled symmetrically (update checks around
TYPE_TOOL_CALL / TYPE_TOOL_RESULT and the code that builds tool_call/tool_result
objects).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ddb1241 and 1a9ce66.

📒 Files selected for processing (1)
  • packages/traceloop-sdk/src/lib/tracing/ai-sdk-transformations.ts

- Prefer v5 input over v4 args (item.input ?? item.args)
- Prefer v5 output over v4 result (item.output ?? item.result)
- Accept both 'tool-result' and 'tool_result' type values for symmetry
  with tool-call handling
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.

gen_ai.input.messages strips tool-call parts from assistant messages

2 participants