Skip to content

Cloudflare Anthropic provider ignores forceAdaptiveThinking, sends incompatible thinking config #616

Description

@zeke

Describe the Bug

streamCloudflareAnthropicAi in @flue/runtime's dist/cloudflare/workers-ai-provider.mjs always sets:

thinkingEnabled: Boolean(options?.reasoning)

That sends Anthropic's older budget-based thinking.type.enabled shape. Some models need Anthropic's newer adaptive-thinking API instead (thinking.type.adaptive plus output_config.effort), and for those, this fails every time.

claude-sonnet-5 is one of them. It's registered in @earendil-works/pi-ai's model catalog (dist/providers/data/anthropic.json) with "compat":{"forceAdaptiveThinking":true}. The other two code paths in the same file, the direct Anthropic API path and streamCloudflareResponsesAi/applyResponsesReasoning, both check that flag correctly. Only the Cloudflare AI Gateway path for Anthropic models skips it.

Here's what actually comes back, calling useModel('cloudflare/anthropic/claude-sonnet-5') through the Cloudflare env.AI binding:

Cloudflare AI binding request failed with 400 Bad Request: {"success":false,"result":[],"messages":[],"error":[{"code":7003,"message":"Model execution failed (User Input Error): \"thinking.type.enabled\" is not supported for this model. Use \"thinking.type.adaptive\" and \"output_config.effort\" to control thinking behavior."}] ...}

Expected Behavior

streamCloudflareAnthropicAi should check compat.forceAdaptiveThinking the same way the other two paths in this file already do, and send thinking.type.adaptive plus output_config.effort for models that need it.

Steps to Reproduce

  1. In a Cloudflare-target Flue app with an ai binding in wrangler.jsonc, define an agent:
    'use agent';
    import { useModel } from '@flue/runtime';
    
    export function Extract() {
      useModel('cloudflare/anthropic/claude-sonnet-5');
      return 'Say hello.';
    }
  2. Dispatch it against a deployed Worker with Workers AI Billing on the AI Gateway set to Unified billing, so a 402 billing error isn't muddying the picture.
  3. Watch it 400 with the error above. It never completes.

Workaround

Turning off thinking entirely dodges the bad payload, at the cost of losing extended thinking for this model:

useModel('cloudflare/anthropic/claude-sonnet-5', { thinkingLevel: 'off' });

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions