Skip to content

Send each function response as its own tool message - #288

Open
saarnilauri wants to merge 1 commit into
WordPress:trunkfrom
saarnilauri:fix/parallel-tool-call-function-responses
Open

Send each function response as its own tool message#288
saarnilauri wants to merge 1 commit into
WordPress:trunkfrom
saarnilauri:fix/parallel-tool-call-function-responses

Conversation

@saarnilauri

@saarnilauri saarnilauri commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

A message holding several function responses is what a parallel tool call produces, but prepareMessagesParam() only special-cased a message with exactly one function-response part. Anything more fell through to the generic branch, where getMessagePartContentData() threw "The API only allows a single function response, as the only content of the message."

The chat completions API expects one message of role 'tool' per tool call, so a message can no longer map to a single API entry. Expand a message whose parts are all function responses into one entry per response, and reject a message that mixes function responses with other content up front, where the constraint can be stated clearly.

The single-message shape itself is correct and unchanged: it is what PromptBuilder::withFunctionResponse() builds when called more than once, and what the Anthropic and Google providers already expect, both of which map function responses through their normal per-part conversion.

Fixes #286.

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Opus 5
Used for: Tracing the folded-in values through git history to confirm they were never snake_case, verifying the emitted values at runtime, and drafting these comment corrections. The final wording was reviewed and edited by me.

🤖 Generated with Claude Code

A message holding several function responses is what a parallel tool call
produces, but prepareMessagesParam() only special-cased a message with exactly
one function-response part. Anything more fell through to the generic branch,
where getMessagePartContentData() threw "The API only allows a single function
response, as the only content of the message."

The chat completions API expects one message of role 'tool' per tool call, so a
message can no longer map to a single API entry. Expand a message whose parts are
all function responses into one entry per response, and reject a message that
mixes function responses with other content up front, where the constraint can be
stated clearly.

The single-message shape itself is correct and unchanged: it is what
PromptBuilder::withFunctionResponse() builds when called more than once, and what
the Anthropic and Google providers already expect, both of which map function
responses through their normal per-part conversion.

Fixes WordPress#286.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @stefanolissa.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: stefanolissa.

Co-authored-by: saarnilauri <laurisaarni@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@codecov

codecov Bot commented Sep 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.10345% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.52%. Comparing base (20a1a6d) to head (46f11af).

Files with missing lines Patch % Lines
...on/AbstractOpenAiCompatibleTextGenerationModel.php 93.10% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##              trunk     #288      +/-   ##
============================================
- Coverage     86.54%   86.52%   -0.03%     
- Complexity     1381     1383       +2     
============================================
  Files            69       69              
  Lines          4438     4446       +8     
============================================
+ Hits           3841     3847       +6     
- Misses          597      599       +2     
Flag Coverage Δ
unit 86.52% <93.10%> (-0.03%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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.

Parallel tool call and client error

1 participant