Parse function_call-wrapped and bare JSON tool calls#317
Conversation
The text tool-call fallback in WP_Agent_Provider_Turn_Result dropped tool
calls emitted as a bare JSON object (no <tool_call> tag or ```json fence)
and did not recognize the `{"type":"function_call","function_call":{...}}`
wrapper that some providers emit. Both shapes resulted in zero extracted
tool calls, so the model's tool call never executed.
Treat a trimmed message that is a single JSON object as a payload
candidate, and unwrap an inner `function_call` object before reading the
tool name and arguments. Adds smoke coverage for the wrapper shape.
|
Closing without merge. This PR widened the text tool-call scraper to absorb more malformed shapes (bare JSON objects and The real fix landed in the Claude Code provider (Extra-Chill/wp-coding-agents#197), which now declares Anthropic If we want agents-api to actively enforce the contract, the better follow-up is a |
Summary
WP_Agent_Provider_Turn_Result's text tool-call fallback dropped tool calls in two shapes that real providers emit, so the model's tool call silently never executed:<tool_call>tag and no```jsonfence.extract_json_tool_calls()only collected payloads from tags/fences, so bare JSON was never parsed.function_callwrapper —{"type":"function_call","function_call":{"name":...,"arguments":{...}}}. The parser readname/function/argumentsat the top level and never unwrapped the innerfunction_callobject, yielding an empty call.Both produced zero extracted tool calls.
Changes
extract_json_tool_calls(): when no tag/fence payloads are found, treat a trimmed message that is a single JSON object ({...}) as a payload candidate.tool_calls_from_json_payloads(): unwrap an innerfunction_callobject before reading the tool name and arguments.tests/provider-turn-adapter-smoke.phpfor thefunction_callwrapper shape.Testing
php tests/provider-turn-adapter-smoke.php→ all 49 assertions pass (2 new).tests/*-smoke.phpfiles pass by exit code.Context
Discovered while landing the
ai-provider-for-claude-codecarried provider (Extra-Chill/wp-coding-agents#197) and the writable-workspace-tools fix (Extra-Chill/homeboy-extensions#1190). With those in place, Claude Opus 4.8 correctly emitted aworkspace_writetool call, but it was dropped here because of the unrecognized shape. This is the final link making real Codebox coding tasks work.AI assistance