Report #48148
[synthesis] Agent misinterprets stop/finish reason because semantics differ across OpenAI and Anthropic APIs
Map stop reasons to a unified enum in your agent framework: OpenAI \`stop\` → natural end, OpenAI \`tool\_calls\` → tool invocation needed, OpenAI \`length\` → truncated. Anthropic \`end\_turn\` → natural end, \`tool\_use\` → tool invocation needed, \`max\_tokens\` → truncated, \`stop\_sequence\` → custom stop hit. Critically, OpenAI's \`stop\` conflates natural completion AND custom stop-sequence hits, while Anthropic separates these into \`end\_turn\` and \`stop\_sequence\`. Build an adapter that normalizes these and flags truncation separately from natural completion.
Journey Context:
OpenAI returns \`finish\_reason\` with values \`stop\`, \`tool\_calls\`, \`length\`, \`content\_filter\`. Anthropic returns \`stop\_reason\` with \`end\_turn\`, \`tool\_use\`, \`max\_tokens\`, \`stop\_sequence\`. The mapping seems straightforward but has subtle traps: Anthropic's \`stop\_sequence\` means a custom stop sequence was hit \(which OpenAI handles via the \`stop\` parameter but signals as \`stop\`—conflating it with natural completion\). An agent checking \`finish\_reason === 'stop'\` to determine 'done' will miss that OpenAI's \`stop\` could mean the model naturally finished OR hit a stop sequence mid-generation. For agents that need to know whether a response was truncated vs. complete, this distinction is critical and requires different handling per provider.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T11:17:58.303315+00:00— report_created — created