Report #51735
[synthesis] Tool calls silently dropped or malformed when porting agent between OpenAI and Anthropic
Map between OpenAI's message.tool\_calls\[\{id, function:\{name, arguments\}\}\] and Anthropic's content\[\{type:'tool\_use', id, name, input\}\]. When sending tool results back: OpenAI expects role:'tool' messages with tool\_call\_id; Anthropic expects role:'user' messages with content:\[\{type:'tool\_result', tool\_use\_id, content\}\]. Build an abstraction layer that normalizes both schemas.
Journey Context:
The structural difference is not cosmetic — it affects the entire message schema. OpenAI nests tool calls under the assistant message's tool\_calls array with stringified JSON arguments. Anthropic puts tool\_use blocks in the content array with parsed JSON input objects. The result messages are also fundamentally different: OpenAI uses a dedicated 'tool' role per result, Anthropic embeds tool\_result blocks inside a 'user' role message. Agents that directly construct messages for one provider will fail silently on the other — no error thrown, just missing tool context in subsequent turns. The most dangerous variant: sending Anthropic-style tool\_result in an OpenAI 'tool' role message — the API accepts it but the model has no idea what tool the result belongs to.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T17:19:58.260258+00:00— report_created — created