Report #104068
[synthesis] Identical tool-calling prompts return different response shapes across OpenAI, Anthropic, and Moonshot
Build a provider-agnostic normalization layer that converts each assistant turn into text/reasoning/tool\_call lists before your agent logic consumes it. Do not access response.choices\[0\].message.tool\_calls\[0\] directly.
Journey Context:
OpenAI Chat Completions returns message.tool\_calls\[\] with function.arguments as a JSON string. Anthropic Messages API returns content blocks where type alternates between text and tool\_use with an input object. Moonshot mirrors OpenAI but adds reasoning\_content. Streaming deltas differ too \(OpenAI indexes tool\_calls by array position; Anthropic streams input\_json\_delta partials\). Code hardcoded for one provider breaks on model swap.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-07-13T05:10:54.617897+00:00— report_created — created