fix(sse): dynamically inject skills beta only when code_execution tool is present (#14200) - #14310
Conversation
|
This is a P0 fix — every tool-less request on the API-key Anthropic path is 400ing on the current tip right now, and I confirmed it directly (skills-2025-10-02 is still unconditional in ANTHROPIC_BETA_BASE). Your fix threading maybeAppendSkillsBeta/syncSkillsBeta through base.ts, default.ts, provider.ts and the CC-compatible path, plus re-syncing after transformRequest reshapes the body, is thorough — that's the part a narrower fix would have missed. Ran both your new suite and the existing #9064 regression guard locally: 13/13 pass. Merging. For the record: the same gate was first proposed in #10651 (@dpozimski, August) and closed by its author before merging; we'll add a courtesy |
…l is present (diegosouzapw#14200) Anthropic requires the 'skills-2025-10-02' beta header only when a code_execution tool is present in the request body. Statically including it in ANTHROPIC_BETA_BASE causes upstream Anthropic to reject all tool-less requests with HTTP 400: 'Skills beta requires the code_execution tool to be included in the request.' Move skills-2025-10-02 out of the static beta lists and introduce maybeAppendSkillsBeta to conditionally append it only when a code_execution tool is detected in the body, while preserving explicit client-negotiated skills betas. Signed-off-by: Minxi Hou <houminxi@gmail.com>
962f95c to
7d23bcf
Compare
6ad5f73
into
diegosouzapw:release/v3.8.51
fix(sse): dynamically inject skills beta only when code_execution tool is present (#14200)
Summary
Fixes #14200.
skills-2025-10-02beta was previously statically declared inANTHROPIC_BETA_BASE, which caused upstream Anthropic to reject all tool-less requests (such as plain text completions) with HTTP 400:This PR moves
skills-2025-10-02out of the static beta lists and injects it dynamically only when acode_executiontool is detected in the request body. It also strips the beta if forwarded by client headers when the request contains nocode_executiontool.Changes
open-sse/config/anthropicHeaders.ts:skills-2025-10-02fromANTHROPIC_BETA_BASE,ANTHROPIC_BETA_API_KEY, andANTHROPIC_BETA_CLAUDE_OAUTH.hasCodeExecutionTool(body)helper to detectcode_execution_20250825,code_executiontool types or functions.maybeAppendSkillsBeta(headers, provider, body, extraCondition)to dynamically appendskills-2025-10-02when appropriate for Anthropic family providers.syncSkillsBeta(headers, provider, body, extraCondition)andremoveAnthropicBetaHeader(headers, token)to synchronize the header with the finalized request body.mergeClientAnthropicBeta(headers, clientBeta, model, body)to dropskills-2025-10-02when client attempts to negotiate it on tool-less requests.open-sse/executors/base.ts:buildHeaders: dynamically evaluates skills beta on initial headers.execute: invokessyncSkillsBetaontransformedBodyaftertransformRequest()to guarantee headers stay in sync with the body actually sent upstream.open-sse/executors/default.ts:bodyintobuildHeaders.open-sse/services/provider.ts:open-sse/services/claudeCodeCompatible.ts:tests/unit/issue-14200-anthropic-skills-beta-toolless.test.ts:Verification
npm run typecheck:core: 0 errorsnpm run check:cycles: 0 cyclesnode --test-force-exit --import tsx/esm --test tests/unit/issue-14200-anthropic-skills-beta-toolless.test.ts ...: 34/34 passed