Skip to content

feat(ai): add Anthropic Vertex AI provider#1157

Closed
michaelpersonal wants to merge 3 commits intobadlogic:mainfrom
michaelpersonal:feat/anthropic-vertex-provider
Closed

feat(ai): add Anthropic Vertex AI provider#1157
michaelpersonal wants to merge 3 commits intobadlogic:mainfrom
michaelpersonal:feat/anthropic-vertex-provider

Conversation

@michaelpersonal
Copy link

Summary

Add support for Anthropic Claude models hosted on Google Cloud Vertex AI.

  • New anthropic-vertex API type and provider using raw fetch + GoogleAuth (ADC)
  • Shared utilities extracted to anthropic-shared.ts
  • 4 models registered: Opus 4.5, Sonnet 4, 3.5 Sonnet v2, 3.5 Haiku
  • Comprehensive test suite (6 tests)

Related to #1155

Why a separate provider?

The Anthropic SDK doesn't support Vertex AI's URL structure:

  • Direct API: https://api.anthropic.com/v1/messages
  • Vertex AI: https://{region}-aiplatform.googleapis.com/v1/projects/{project}/locations/{location}/publishers/anthropic/models/{model}:streamRawPredict

Test plan

  • Basic text generation
  • Tool calling with streaming
  • Streaming events (start, text_delta, done)
  • Multi-turn conversation
  • Token usage reporting
  • Thinking blocks (extended reasoning with Opus 4.5)
  • Integration tested with Pi coding agent extension

Code review methodology

This PR was reviewed using quiz-based comprehension verification rather than diff scanning alone. The human reviewer correctly answered 6/6 questions covering runtime behavior, auth failure modes, request body differences, conditional logic, dependency relationships, and edge case handling.

🤖 Generated with Claude Code

@badlogic
Copy link
Owner

badlogic commented Feb 2, 2026

Thanks for the PR! The approach looks solid. Few things to address before merge:

Must fix:

  1. No changelog entry. Add under ## [Unreleased] -> ### Added in packages/ai/CHANGELOG.md

  2. getEnvApiKey() in packages/ai/src/env-api-keys.ts needs anthropic-vertex support, otherwise models wont show up in available list even when credentials are configured

  3. defaultModelPerProvider in packages/coding-agent/src/core/model-resolver.ts needs an entry

  4. packages/coding-agent/docs/providers.md needs setup instructions (the existing Vertex section only covers Gemini)

Code duplication issue:

The shared utilities approach was the right call, but anthropic.ts still has its own mapStopReason, convertContentBlocks, convertTools, normalizeToolCallId implementations (lines 105, 539, 693, 711). These should be refactored to import from anthropic-shared.ts - otherwise "shared" is misleading and the two implementations will drift.

Note: convertTools in the shared module doesnt handle isOAuthToken for Claude Code tool naming, while anthropic.ts does. Need to reconcile that.

Tests:

The provider-specific tests look good. Per AGENTS.md, new providers should also be added to cross-provider-handoff.test.ts (at minimum) and ideally the other standard test suites. Can be a follow-up PR if you prefer.

Questions:

  • Is us-east5 the right default? You mentioned testing with global but the code defaults to us-east5
  • Did you verify all 4 registered models work, or just Opus 4.5?

Also add pkg:ai and pkg:coding-agent labels to the PR.

@badlogic badlogic added pkg:ai LLM API package pkg:coding-agent Coding agent CLI labels Feb 2, 2026
@michaelpersonal
Copy link
Author

Thanks for the thorough review!

Answers to your questions:

  1. Default region: Changed to global. That's what I tested with and it has broad model availability.

  2. Model verification: Only tested Opus 4.5 (claude-opus-4-5@20251101) - that's the only model we could enable in our Vertex AI project. The other 3 models use the same code path, so they should work once enabled.

Addressed feedback:

  • ✅ Added changelog entry
  • ✅ Added anthropic-vertex to getEnvApiKey()
  • ✅ Added defaultModelPerProvider entry
  • ✅ Added setup docs to providers.md
  • ✅ Refactored anthropic.ts to import mapStopReason, convertContentBlocks, normalizeToolCallId from anthropic-shared.ts
  • ✅ Added optional nameMapper parameter to shared convertTools() to handle OAuth tool naming
  • ✅ Added anthropic-vertex to cross-provider-handoff.test.ts

All 6 provider-specific tests pass. Cross-provider handoff tests pass between anthropic and anthropic-vertex.

@isaacraja
Copy link

The provider extension works well for this since the api is similar to existing anthropic provider unlike bedrock - Here is something my clanker wrote which i'm using quite sometime - https://github.com/isaacraja/pi-vertex-claude. But yeah in the core is also useful.

@skyfallsin
Copy link

skyfallsin commented Feb 5, 2026

Great work @michaelpersonal! I built a similar extension
(https://github.com/skyfallsin/pi-vertex-anthropic) with a few
additions:

  1. Interactive /login wizard - Full OAuth setup (gcloud,
    project selection, API enable)
  2. Global region fix - Current endpoint breaks with
    location="global"
  3. Sonnet 4.5 - You have Sonnet 4, but 4.5 is the latest
  4. More models - Claude 3.5 Sonnet original + 3.x family

Happy to fork your PR and add these if you'd like. Let me know!

skyfallsin pushed a commit to skyfallsin/pi-vertex-anthropic that referenced this pull request Feb 5, 2026
- PR_COMMENT.md: Comment posted to badlogic/pi-mono#1157
- FORK_WORKFLOW.md: Guide for forking and contributing
- Offering to fork their PR and add OAuth/global region/models
- Link to our repo: https://github.com/skyfallsin/pi-vertex-anthropic

Comment posted: badlogic/pi-mono#1157 (comment)
@yuting0624
Copy link

+1 for this feature!

I've tested Claude on Vertex AI (Opus 4.5 & 4.6, global region) locally using @anthropic-ai/vertex-sdk and confirmed it works great with ADC auth.

Currently using a local proxy workaround with OpenClaw, but native pi-ai support would be much cleaner.

Happy to help test if the conflicts get resolved! 🙏

@michaelpersonal michaelpersonal force-pushed the feat/anthropic-vertex-provider branch from a7d2526 to bf06172 Compare February 8, 2026 22:22
Michael Guo and others added 3 commits February 9, 2026 03:22
Add support for Anthropic Claude models hosted on Google Cloud Vertex AI.

- New `anthropic-vertex` API type and provider
- New files:
  - `anthropic-shared.ts`: Shared utilities (mapStopReason, convertTools, etc.)
  - `anthropic-vertex.ts`: Vertex AI provider using raw fetch + GoogleAuth
  - `anthropic-vertex.test.ts`: Comprehensive test suite
- Registered 4 models: Opus 4.5, Sonnet 4, 3.5 Sonnet v2, 3.5 Haiku
- Added `google-auth-library` dependency for Application Default Credentials

The Anthropic SDK doesn't support Vertex AI's URL structure:
- Direct API: `https://api.anthropic.com/v1/messages`
- Vertex AI: `https://{region}-aiplatform.googleapis.com/v1/projects/{project}/locations/{location}/publishers/anthropic/models/{model}:streamRawPredict`

All tests verified with `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION=global`:
- ✓ Basic text generation
- ✓ Tool calling with streaming
- ✓ Streaming events (start, text_delta, done)
- ✓ Multi-turn conversation
- ✓ Token usage reporting
- ✓ Thinking blocks (extended reasoning with Opus 4.5)

Additionally tested end-to-end by integrating with Pi coding agent as a
custom extension. The provider successfully powered interactive coding
sessions using Claude Opus 4.5 via Vertex AI with the global region.

This PR was reviewed using quiz-based comprehension verification rather than
diff scanning alone. The human reviewer correctly answered 6/6 questions about:
runtime behavior, auth failure modes, request body differences, conditional
logic, dependency relationships, and edge case handling.

Ref: https://michaelguoblog.vercel.app/posts/man-in-the-loop-agent-coding/

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add changelog entry under [Unreleased] -> Added
- Add anthropic-vertex to getEnvApiKey() ADC detection
- Add defaultModelPerProvider entry for anthropic-vertex
- Add Anthropic Vertex AI setup docs to providers.md
- Refactor anthropic.ts to import shared utils from anthropic-shared.ts
  (mapStopReason, convertContentBlocks, normalizeToolCallId)
- Add optional nameMapper param to shared convertTools() for OAuth compatibility
- Add anthropic-vertex to cross-provider-handoff.test.ts
- Change default region from us-east5 to global

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Run generate-models to include anthropic-vertex provider model definitions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@michaelpersonal michaelpersonal force-pushed the feat/anthropic-vertex-provider branch from 592e230 to 9b003fb Compare February 9, 2026 03:23
@michaelpersonal
Copy link
Author

@badlogic This PR is ready for review. The merge conflict has been resolved and rebased onto main.

@newme616
Copy link

+1 for this. Would be great to support different regions and projects, but I know vertex ai is painful, as they keep changing their docs and naming

@badlogic
Copy link
Owner

Sorry, took me a while to get to this. This PR has multiple issues:

  • packages/ai/src/env-api-keys.ts: anthropic-vertex availability check requires GOOGLE_CLOUD_LOCATION,
    but the provider itself defaults to "global" when no location is provided. This creates inconsistent
    behavior where runtime can work but model discovery can be hidden.
  • packages/coding-agent/README.md was not updated. The provider list still omits Anthropic Vertex support, so docs are incomplete for a user-facing feature.
  • packages/ai/src/providers/anthropic-vertex.ts can emit done even when output.stopReason becomes "error"
    (for stop reasons like refusal or sensitive). In anthropic.ts, this case is guarded and converted to an error path. Here it is not, and done.reason is force-cast. This can cause downstream consumers to treat an error as a successful completion.
  • Introducing google-auth-library into @mariozechner/pi-ai provider imports may break/browser-bloat web consumers.
  • The hard coded model list in generate-models.ts is incomplete/outdated.

I'm afraid I have to close this out. Since this barely reuses anything from anthropic.ts, this is better implemented as an extension.

@badlogic badlogic closed this Feb 12, 2026
@newme616
Copy link

Sorry, took me a while to get to this. This PR has multiple issues:

  • packages/ai/src/env-api-keys.ts: anthropic-vertex availability check requires GOOGLE_CLOUD_LOCATION,
    but the provider itself defaults to "global" when no location is provided. This creates inconsistent
    behavior where runtime can work but model discovery can be hidden.
  • packages/coding-agent/README.md was not updated. The provider list still omits Anthropic Vertex support, so docs are incomplete for a user-facing feature.
  • packages/ai/src/providers/anthropic-vertex.ts can emit done even when output.stopReason becomes "error"
    (for stop reasons like refusal or sensitive). In anthropic.ts, this case is guarded and converted to an error path. Here it is not, and done.reason is force-cast. This can cause downstream consumers to treat an error as a successful completion.
  • Introducing google-auth-library into @mariozechner/pi-ai provider imports may break/browser-bloat web consumers.
  • The hard coded model list in generate-models.ts is incomplete/outdated.

I'm afraid I have to close this out. Since this barely reuses anything from anthropic.ts, this is better implemented as an extension.

understandable, also google keeps changing their SDKs and model names like underwear, so would need a lot of maintenance

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

Labels

pkg:ai LLM API package pkg:coding-agent Coding agent CLI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants