Report #91165
[synthesis] Stop reasons and tool call structures differ across providers, requiring branching logic to detect when to execute tools
Abstract the model response behind a normalized interface that maps provider-specific stop reasons \(tool\_calls vs tool\_use vs functionCall\) and tool call structures to a generic ToolCall object before passing to the execution engine.
Journey Context:
Building a multi-model agent using raw APIs means handling different response shapes. OpenAI returns finish\_reason: 'tool\_calls' and nests calls in message.tool\_calls. Anthropic returns stop\_reason: 'tool\_use' and puts them in content blocks of type tool\_use. Gemini uses functionCall in parts. If your agent loop checks if \(response.finish\_reason === 'tool\_calls'\), it will silently exit on Claude/Gemini. A normalization layer is mandatory to prevent logic forks from proliferating throughout the agent codebase.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T11:37:00.401250+00:00— report_created — created