Skip to content

feat(ai-anthropic): choose the credential kind with auth, and read the environment only in anthropicText - #1688

Merged
AlemTuzlak merged 2 commits into
mainfrom
feat/anthropic-auth-kind
Oct 9, 2026
Merged

AlemTuzlak merged 2 commits into
mainfrom
feat/anthropic-auth-kind

Conversation

@AlemTuzlak

@AlemTuzlak AlemTuzlak commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

The Anthropic adapters now follow the same factory pattern as every other adapter. createAnthropicChat(model, credential, config?) reads nothing from the environment, and anthropicText(model, config?) reads the credential from the environment. #1679 had mixed the two: the client read ANTHROPIC_* by itself, and anthropicText took credentials in its config. #1679 is not released yet, so this PR changes its API before anyone uses it.

🎯 Changes

  • A new auth?: 'api-key' | 'bearer' | 'oauth' option replaces the authToken and oauth options from feat(ai-anthropic): support Bearer tokens and Claude OAuth tokens #1679:
  • createAnthropicChat, createAnthropicSummarize, and createAnthropicFiles take the credential as an argument, and apiKey is a required string again.
    • They read no credential from the environment.
    • The client passes explicit nulls, so the Anthropic SDK does not read ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN by itself.
  • anthropicText, anthropicSummarize, and anthropicFiles read the credential with one helper, getAnthropicCredentialFromEnv(), from window.env or process.env. The order is ANTHROPIC_AUTH_TOKEN, then ANTHROPIC_OAUTH_TOKEN, then ANTHROPIC_API_KEY. They throw when none is set. Their config has no apiKey. A config auth wins over the detected kind.
  • resolveAnthropicCredentials and the internal getAnthropicApiKeyFromEnv are removed. Neither was a public export.
  • Docs: "Bearer and OAuth tokens", "Environment Variables", and "API Reference" in adapters/anthropic.md, plus line 21 of advanced/files-api.md.
  • Changeset: the pending .changeset/anthropic-bearer-oauth.md from feat(ai-anthropic): support Bearer tokens and Claude OAuth tokens #1679 is rewritten for the final API. There is no second changeset.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with pnpm run test:pr, or these tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.
  • Docs: I updated docs/ for this change, or this change is not user-facing.
  • Changeset: I added a changeset (pnpm changeset), or this PR does not change a published package.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Testing

Commands run

  • vitest run in packages/ai-anthropic, after the merge with main (8caa6b0d): 216 tests pass. tests/auth-parity.test.ts now has 22 tests.
  • test:types, test:oxlint, and knip for ai-anthropic: clean.
  • pnpm test:docs: no broken links. kiira check on the two pages: 30 snippets pass.
  • tsc on testing/e2e: no errors in the changed files.
  • Not run locally: pnpm test:pr and the E2E suite. CI runs them.

Manual test

  1. Run pnpm --dir packages/ai-anthropic exec vitest run tests/auth-parity.test.ts.
  2. Check these cases:
    • createAnthropicChat sends x-api-key with the explicit key even when ANTHROPIC_AUTH_TOKEN is set.
    • auth: 'bearer' sends Authorization: Bearer.
    • An sk-ant-oat token turns on OAuth.
    • A config auth wins over detection.
    • anthropicText follows the env order and throws when nothing is set.
    • The @ts-expect-error lines reject apiKey on the env factories, and they show that authToken and oauth are gone.

How this PR makes testing easy

  • Unit tests for each rule, including the summarize and files factories.
  • E2E: anthropic-auth-wire.spec.ts and its route now use createAnthropicChat with auth: 'api-key' | 'bearer' | 'oauth'.

Risk / rollback

To undo, revert this PR.

Public API change

Before (#1679 on main, not released)

anthropicText('claude-sonnet-5-5', { authToken: token })
anthropicText('claude-sonnet-5-5', { authToken: token, oauth: true })
createAnthropicChat('claude-sonnet-5-5', '') // read ANTHROPIC_* from the environment

After

createAnthropicChat('claude-sonnet-5-5', apiKey)                     // x-api-key
createAnthropicChat('claude-sonnet-5-5', token, { auth: 'bearer' })  // Authorization: Bearer
createAnthropicChat('claude-sonnet-5-5', oauthToken)                 // sk-ant-oat → OAuth
anthropicText('claude-sonnet-5-5') // ANTHROPIC_AUTH_TOKEN → ANTHROPIC_OAUTH_TOKEN → ANTHROPIC_API_KEY

Summary by CodeRabbit

  • New Features
    • Anthropic integrations now support explicit API-key, bearer-token, and OAuth authentication modes. OAuth tokens are detected automatically unless you choose a mode.
    • Environment-based integrations select credentials in this order: ANTHROPIC_AUTH_TOKEN, ANTHROPIC_OAUTH_TOKEN, then ANTHROPIC_API_KEY. They report an error if no credential is available; direct factory integrations use the credential you provide.
    • OAuth requests include the required identity and beta headers.
  • Documentation
    • Updated Anthropic integration and Files API guides with authentication options and credential-selection details.

…vironment only in anthropicText

createAnthropicChat, createAnthropicSummarize, and createAnthropicFiles take the
credential as an argument and read no credential from the environment. The new
auth option ('api-key' | 'bearer' | 'oauth') sets how the credential goes out.
The default is 'oauth' for an sk-ant-oat credential, else 'api-key'.

anthropicText, anthropicSummarize, and anthropicFiles read ANTHROPIC_AUTH_TOKEN,
then ANTHROPIC_OAUTH_TOKEN, then ANTHROPIC_API_KEY, and throw when none is set.
A config auth wins over the detected kind.

The authToken and oauth config fields are removed.
@changeset-bot

changeset-bot Bot commented Oct 9, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 4387263

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes changesets to release 1 package
Name Type
@tanstack/ai-anthropic Minor

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@AlemTuzlak
AlemTuzlak enabled auto-merge (squash) October 9, 2026 10:34
@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: TanStack/ai/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ce748183-0c5c-4270-aa51-77b79604b78b

📥 Commits

Reviewing files that changed from the base of the PR and between 13ba1b0 and 4387263.


📒 Files selected for processing (10)
  • .changeset/anthropic-bearer-oauth.md
  • docs/adapters/anthropic.md
  • docs/advanced/files-api.md
  • packages/ai-anthropic/src/adapters/files.ts
  • packages/ai-anthropic/src/adapters/summarize.ts
  • packages/ai-anthropic/src/adapters/text.ts
  • packages/ai-anthropic/src/utils/client.ts
  • packages/ai-anthropic/tests/auth-parity.test.ts
  • testing/e2e/src/routes/api.anthropic-auth-wire.ts
  • testing/e2e/tests/anthropic-auth-wire.spec.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 2 remain after this review.



📝 Walkthrough

Walkthrough

Anthropic authentication now uses explicit api-key, bearer, and oauth modes. Direct adapters use supplied credentials, while convenience factories select credentials from the environment. Tests and documentation cover the updated modes and selection rules.

Changes

Anthropic authentication

Layer / File(s) Summary
Auth modes and client transport
packages/ai-anthropic/src/utils/client.ts, packages/ai-anthropic/src/adapters/text.ts
The client resolves explicit auth settings or detects OAuth from credentials containing sk-ant-oat. The text adapter passes the resolved auth mode to client creation.
Environment-backed adapter factories
packages/ai-anthropic/src/adapters/text.ts, packages/ai-anthropic/src/adapters/files.ts, packages/ai-anthropic/src/adapters/summarize.ts
The environment helper checks credential variables in a defined order and throws if none is set. The convenience factories pass the selected credential and auth mode to their explicit-credential adapters.
Authentication coverage and documentation
packages/ai-anthropic/tests/auth-parity.test.ts, testing/e2e/src/routes/api.anthropic-auth-wire.ts, testing/e2e/tests/anthropic-auth-wire.spec.ts, .changeset/anthropic-bearer-oauth.md, docs/adapters/anthropic.md, docs/advanced/files-api.md
Tests cover auth modes, environment selection, overrides, request headers, and missing credentials. The E2E route, changeset, and documentation describe the updated options and credential sources.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant anthropicText
  participant getAnthropicCredentialFromEnv
  participant createAnthropicChat
  participant createAnthropicClient
  anthropicText->>getAnthropicCredentialFromEnv: Read credential and detected auth
  anthropicText->>createAnthropicChat: Pass credential and selected auth
  createAnthropicChat->>createAnthropicClient: Create client with credential and auth
Loading

Suggested reviewers: tombeckenham


Merge Risk: ⚪ Minimal · up to 43872

No actionable issue remains that should prevent merging after normal checks.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 78.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 7 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check Passed The title clearly identifies the Anthropic authentication change and environment-based factory behavior. It is somewhat incomplete because anthropicSummarize and anthropicFiles also read credentia…
Description check Passed The description includes all required template sections, explains the API and authentication changes, documents testing results and limitations, and records release impact and rollback information. Th…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.

Full details: Docstring Coverage

Explanation

Docstring coverage is 78.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 7 files. (3 skipped: 3 unsupported.)



  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR


  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nx-cloud

nx-cloud Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit 4387263

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 2m 4s View ↗
nx run-many --targets=build --exclude=examples/... ✅ Succeeded 3s View ↗
nx run-many --targets=test:coverage --projects=... ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-10-09 10:39:40 UTC

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Coverage

✅ Coverage held across 2 compared package(s).

Each package is measured twice in this job — on this PR and on its merge-base with main — and compared. A metric fails only when it is at or above 60% on the merge-base and under 60% on this PR. Other drops are listed but do not fail. Packages your PR doesn't affect are not measured and not listed.

package statements branches functions lines
ai-anthropic 90.21% (+0.64) 82.55% (+0.37) 94.31% (+3.41) 90.52% (+0.65) ok
ai-code-mode-snippets 87.13% (0.00) 75.67% (0.00) 91.11% (0.00) 88.39% (0.00) ok

@pkg-pr-new

pkg-pr-new Bot commented Oct 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@1688

@tanstack/ai-acp

npm i https://pkg.pr.new/@tanstack/ai-acp@1688

@tanstack/ai-angular

npm i https://pkg.pr.new/@tanstack/ai-angular@1688

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@1688

@tanstack/ai-bedrock

npm i https://pkg.pr.new/@tanstack/ai-bedrock@1688

@tanstack/ai-byteplus

npm i https://pkg.pr.new/@tanstack/ai-byteplus@1688

@tanstack/ai-claude-code

npm i https://pkg.pr.new/@tanstack/ai-claude-code@1688

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@1688

@tanstack/ai-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-cloudflare@1688

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@1688

@tanstack/ai-code-mode-snippets

npm i https://pkg.pr.new/@tanstack/ai-code-mode-snippets@1688

@tanstack/ai-codex

npm i https://pkg.pr.new/@tanstack/ai-codex@1688

@tanstack/ai-cohere

npm i https://pkg.pr.new/@tanstack/ai-cohere@1688

@tanstack/ai-compaction

npm i https://pkg.pr.new/@tanstack/ai-compaction@1688

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@1688

@tanstack/ai-durable-stream

npm i https://pkg.pr.new/@tanstack/ai-durable-stream@1688

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@1688

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@1688

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@1688

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@1688

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@1688

@tanstack/ai-grok-build

npm i https://pkg.pr.new/@tanstack/ai-grok-build@1688

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@1688

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@1688

@tanstack/ai-isolate-daytona

npm i https://pkg.pr.new/@tanstack/ai-isolate-daytona@1688

@tanstack/ai-isolate-e2b

npm i https://pkg.pr.new/@tanstack/ai-isolate-e2b@1688

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@1688

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@1688

@tanstack/ai-isolate-quickjs-bun

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs-bun@1688

@tanstack/ai-llmgateway

npm i https://pkg.pr.new/@tanstack/ai-llmgateway@1688

@tanstack/ai-lovable

npm i https://pkg.pr.new/@tanstack/ai-lovable@1688

@tanstack/ai-mcp

npm i https://pkg.pr.new/@tanstack/ai-mcp@1688

@tanstack/ai-memory

npm i https://pkg.pr.new/@tanstack/ai-memory@1688

@tanstack/ai-mistral

npm i https://pkg.pr.new/@tanstack/ai-mistral@1688

@tanstack/ai-octane

npm i https://pkg.pr.new/@tanstack/ai-octane@1688

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@1688

@tanstack/ai-ollaya

npm i https://pkg.pr.new/@tanstack/ai-ollaya@1688

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@1688

@tanstack/ai-opencode

npm i https://pkg.pr.new/@tanstack/ai-opencode@1688

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@1688

@tanstack/ai-perplexity

npm i https://pkg.pr.new/@tanstack/ai-perplexity@1688

@tanstack/ai-persistence

npm i https://pkg.pr.new/@tanstack/ai-persistence@1688

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@1688

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@1688

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@1688

@tanstack/ai-reactor

npm i https://pkg.pr.new/@tanstack/ai-reactor@1688

@tanstack/ai-remix

npm i https://pkg.pr.new/@tanstack/ai-remix@1688

@tanstack/ai-sandbox

npm i https://pkg.pr.new/@tanstack/ai-sandbox@1688

@tanstack/ai-sandbox-blaxel

npm i https://pkg.pr.new/@tanstack/ai-sandbox-blaxel@1688

@tanstack/ai-sandbox-boxd

npm i https://pkg.pr.new/@tanstack/ai-sandbox-boxd@1688

@tanstack/ai-sandbox-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-sandbox-cloudflare@1688

@tanstack/ai-sandbox-daytona

npm i https://pkg.pr.new/@tanstack/ai-sandbox-daytona@1688

@tanstack/ai-sandbox-docker

npm i https://pkg.pr.new/@tanstack/ai-sandbox-docker@1688

@tanstack/ai-sandbox-e2b

npm i https://pkg.pr.new/@tanstack/ai-sandbox-e2b@1688

@tanstack/ai-sandbox-local-process

npm i https://pkg.pr.new/@tanstack/ai-sandbox-local-process@1688

@tanstack/ai-sandbox-railway

npm i https://pkg.pr.new/@tanstack/ai-sandbox-railway@1688

@tanstack/ai-sandbox-sprites

npm i https://pkg.pr.new/@tanstack/ai-sandbox-sprites@1688

@tanstack/ai-sandbox-upstash-box

npm i https://pkg.pr.new/@tanstack/ai-sandbox-upstash-box@1688

@tanstack/ai-sandbox-vercel

npm i https://pkg.pr.new/@tanstack/ai-sandbox-vercel@1688

@tanstack/ai-skills

npm i https://pkg.pr.new/@tanstack/ai-skills@1688

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@1688

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@1688

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@1688

@tanstack/ai-typesafe

npm i https://pkg.pr.new/@tanstack/ai-typesafe@1688

@tanstack/ai-utils

npm i https://pkg.pr.new/@tanstack/ai-utils@1688

@tanstack/ai-vercel-gateway

npm i https://pkg.pr.new/@tanstack/ai-vercel-gateway@1688

@tanstack/ai-vertex

npm i https://pkg.pr.new/@tanstack/ai-vertex@1688

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@1688

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@1688

@tanstack/ai-worldlabs

npm i https://pkg.pr.new/@tanstack/ai-worldlabs@1688

@tanstack/openai-base

npm i https://pkg.pr.new/@tanstack/openai-base@1688

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@1688

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@1688

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@1688

@tanstack/svelte-ai-devtools

npm i https://pkg.pr.new/@tanstack/svelte-ai-devtools@1688

commit: 4387263

@github-actions
github-actions Bot requested a review from jherr October 9, 2026 10:41
@github-actions github-actions Bot added the waiting-on: maintainer The ball is in the maintainers’ court label Oct 9, 2026
@AlemTuzlak
AlemTuzlak merged commit 39e23c0 into main Oct 9, 2026
15 checks passed
@AlemTuzlak
AlemTuzlak deleted the feat/anthropic-auth-kind branch October 9, 2026 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

waiting-on: maintainer The ball is in the maintainers’ court

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants