Skip to content

[ai] Move to Anthropic SDK 1.x and API version 2026-10-21 - #103

Merged
robinbowes merged 3 commits into
mainfrom
deps/anthropic-sdk-1
Nov 3, 2026
Merged

robinbowes merged 3 commits into
mainfrom
deps/anthropic-sdk-1

Conversation

@robinbowes

Copy link
Copy Markdown
Collaborator

Summary

@anthropic-ai/sdk moves from 0.122.0 to 1.3.0, the first major that sends API version 2026-10-21 (was 2023-06-01). Migration guide: https://platform.claude.com/docs/en/api/migration-2026-10-21

What the new API version changes, and how it reaches the kit:

Change in 2026-10-21 In the kit
temperature / top_p / top_k are a 400 on every model The anthropic adapter never sends temperature. ChatParams.temperature stays, and anthropic_compatible, openai, openai_compatible and Workers AI still get it.
A document block directly in an assistant message is a 400 None in the kit.
citations on a user text block is a 400 None in the kit. The citations matches are the research agent's own output field.
Admin / Enterprise Analytics renamed fields Not used.

The only call with a non-default value is the evals judge (temperature: 0). It now samples at the default when the judge is a pre-4.7 Claude model. On Claude 4.7 and later, which already rejected the value, nothing changes. This was agreed as the option to take.

The SDK's own breaking changes:

 services/ai/client.ts
-  provider === 'anthropic'
-    ? new Anthropic({ apiKey, baseURL, fetch, maxRetries: 2 })                 # sent X-Api-Key
-    : new Anthropic({ apiKey: null, authToken: apiKey, baseURL, fetch, … })    # sent Authorization: Bearer
+  new Anthropic({ apiKey, baseURL, fetch, maxRetries: 2 })                      # 1.x: Bearer for both
 services/ai/agent-loop.ts  withRollingCacheBreakpoints
-  { ...message, content: withBreakpoint(message.content) }
+  message.role !== 'system' ? { ...message, content: … } : message            # MessageParam is a per-role union

The SDK also adds @opentelemetry/api as a dependency, so the API bundle grows from 731 to 809 KiB gzip. That's still far below Workers' limit. The SDK's licence is now Apache-2.0 (was MIT).

Evidence

  • Before: with the bump alone, typecheck reports the MessageParam union error in agent-loop.ts, and ai-client.test.ts › "anthropic sends x-api-key…" fails, because the key now goes out as Bearer.
    After: pnpm gate passes on Node 26.13.0: api 639, the other web projects 1807 + 5 skipped, driver 13, cli 58, evals 25.
  • Tests run the real SDK against a fake transport. They assert authorization: Bearer sk-ant-secret, no x-api-key, and anthropic-version: 2026-10-21 on the Claude API, and that temperature is gone for Claude (previously 0.2 was forwarded to Claude 4.5) but still reaches an anthropic_compatible vendor. The temperature test failed before the adapter change.
  • The guide's searches, re-run after the change: every remaining temperature hit is a compatible, OpenAI or Workers AI path, and there's no anthropic-version override in the source.
  • The review gate found no defects.

Merge Danger

Door: two-way

Blast Radius: AI providers

  • A proxy in front of the API: a tenant whose anthropic provider has a baseUrl pointing at a proxy that reads X-Api-Key needs that proxy to read Authorization.
  • Compatible vendors: anthropic_compatible vendors now also receive anthropic-version: 2026-10-21. The tests stub the vendor, so a real vendor answering on the new version is unverified. A vendor that rejects the header would fail every call, and the adapter's refusal recovery doesn't cover that. The porting note flags it.

🤖 Generated with Claude Code

@anthropic-ai/sdk 0.122.0 -> 1.3.0, the first major that sends
anthropic-version 2026-10-21. On that version the Claude API rejects
temperature, top_p and top_k on every model, so the anthropic adapter no
longer sends temperature; anthropic_compatible vendors, OpenAI and
Workers AI still get it. The evals judge's temperature: 0 now samples at
the default on a pre-4.7 Claude judge (agreed with the maintainer).

The SDK sends the key as Authorization: Bearer for both Anthropic
providers, so they share one client constructor. MessageParam is a
union of per-role types: withRollingCacheBreakpoints leaves a system
message alone. The SDK adds @opentelemetry/api, and the API bundle grows
from 731 to 809 KiB gzip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@robinbowes

Copy link
Copy Markdown
Collaborator Author

@cliftonc Can you cast your eye over this and #104 and let me know what you think?

# Conflicts:
#	apps/web/package.json
#	docs/upgrades/unreleased.md

@cliftonc cliftonc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Robin, this is a really clean migration. The single constructor, the per-role MessageParam fix and the transport-level tests all look great.

I checked the compatible-vendor risk you flagged. Fireworks' docs say it ignores anthropic-version ("Not required. Fireworks ignores this header."), and Moonshot's Messages API spec doesn't list one. Both already took Bearer, so neither preset should notice.

One small nit before merge: porting step 40 ends with "then pnpm install so every package links the same drizzle-orm", which looks carried over from the postgres step. Could you drop that clause?

Happy to merge after that 👍

The SDK adds @opentelemetry/api, an optional peer of drizzle-orm, so
the lockfile resolves a second drizzle-orm. pnpm --filter add relinks
only apps/web, leaving apps/evals on the old copy and its typecheck
failing on drizzle SQL types until pnpm install runs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@robinbowes

Copy link
Copy Markdown
Collaborator Author

Thanks Robin, this is a really clean migration. The single constructor, the per-role MessageParam fix and the transport-level tests all look great.

I checked the compatible-vendor risk you flagged. Fireworks' docs say it ignores anthropic-version ("Not required. Fireworks ignores this header."), and Moonshot's Messages API spec doesn't list one. Both already took Bearer, so neither preset should notice.

One small nit before merge: porting step 40 ends with "then pnpm install so every package links the same drizzle-orm", which looks carried over from the postgres step. Could you drop that clause?

Happy to merge after that 👍

On step 40, the pnpm install is deliberate, though the step doesn't say why.

The SDK brings @opentelemetry/api, which is an optional peer of drizzle-orm, so the lock file resolves a new drizzle-orm(…)(@opentelemetry/api@1.10.0)(postgres@4.0.0). pnpm --filter web add relinks only apps/web, so apps/evals keeps the old copy and tsc there reports 11 drizzle SQL type errors. I reproduced that on a clean checkout of main.

I'll reword the step to give the reason rather than drop it.

@robinbowes
robinbowes merged commit 910b457 into main Nov 3, 2026
4 checks passed
@robinbowes
robinbowes deleted the deps/anthropic-sdk-1 branch November 3, 2026 10:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants