Skip to content

Comments

fix: accumulate tool_call_message arguments across streaming chunks#55

Merged
cpacker merged 2 commits intomainfrom
fix/tool-call-args-accumulation
Feb 24, 2026
Merged

fix: accumulate tool_call_message arguments across streaming chunks#55
cpacker merged 2 commits intomainfrom
fix/tool-call-args-accumulation

Conversation

@cpfiffer
Copy link
Contributor

Summary

  • Bug: SDKToolCallMessage.toolInput was always {} (empty object) for tool calls streamed from the CLI
  • Root cause: The CLI streams tool_call_message in chunks with partial arguments. The SDK's transformMessage() parsed each chunk independently -- JSON.parse("{}") on the first chunk yielded {}, and subsequent chunks with partial JSON either threw or produced { raw: "..." }
  • Fix: The background pump now buffers tool_call_message chunks by tool_call_id, concatenating arguments across chunks. The complete message is flushed and transformed when a different message type arrives (e.g., tool_return_message, assistant_message) or the pump ends

Before

{ type: "tool_call", toolName: "web_search", toolInput: {} }

After

{ type: "tool_call", toolName: "web_search", toolInput: { query: "Prime Intellect AI news" } }

Impact

Any SDK consumer that reads toolInput now gets the actual arguments. This was discovered while building tool call display in lettabot -- the display needed to show what arguments tools were called with, but toolInput was always empty.

Test plan

  • All 121 existing tests pass (bun test)
  • Type-check clean (bun run check)
  • Manual test: linked into lettabot via npm link, confirmed toolInput now populated for web_search, conversation_search, Bash, and other tools

Written by Cameron and Letta Code

"The best way to predict the future is to invent it." -- Alan Kay

The CLI streams tool_call_message in chunks with partial `arguments`.
Previously, transformMessage() parsed each chunk independently, yielding
`toolInput: {}` from the first chunk. SDK consumers never saw the actual
tool call arguments.

Now the background pump buffers tool_call_message chunks by tool_call_id,
concatenating `arguments` across chunks. The complete message is flushed
and transformed when a different message type arrives or the pump ends.

Written by Cameron and Letta Code

"The best way to predict the future is to invent it." -- Alan Kay
@cpacker cpacker self-requested a review February 24, 2026 01:33
@cpacker cpacker merged commit 317d0e1 into main Feb 24, 2026
2 checks passed
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.

2 participants