Skip to content

✨ feat: Anthropic Vertex AI Support - #9798

Closed
Ziyann wants to merge 5 commits into
LibreChat-AI:mainfrom
Ziyann:feat/anthropic-vertex-ai
Closed

Ziyann wants to merge 5 commits into
LibreChat-AI:mainfrom
Ziyann:feat/anthropic-vertex-ai

Conversation

@Ziyann

@Ziyann Ziyann commented Sep 24, 2025 •

Copy link
Copy Markdown
Contributor

Summary

This PR adds support for using Anthropic models through Vertex AI, as officially supported by the Anthropic & LangChain SDK:
https://docs.claude.com/en/api/claude-on-vertex-ai
https://js.langchain.com/docs/integrations/chat/anthropic/#custom-clients

The Vertex AI API is nearly identical to the Anthropic AI, so supporting it is relatively straightforward. Most of the changes are related to configuration and service account key handling, which I mostly based on the Google client implementation.

To use Anthropic models through Vertex AI, the ANTHROPIC_USE_VERTEX env var needs to be set to true. It will follow the Google service account key config (GOOGLE_SERVICE_KEY_FILE).

Note that tslib has to overridden to version 2 to avoid this error caused by @smithy/eventstream-codec@2.2.0 and cohere-ai using a very old version of @aws-crypto/crc32, pulling in version 1:

TypeError: privateMap.get is not a function
    at __classPrivateFieldGet (LibreChat/node_modules/@aws-crypto/crc32/node_modules/tslib/tslib.js:250:27)
    at GoogleAuth.getClient (LibreChat/packages/api/dist/index.js:31449:138)
    at new AnthropicVertex (LibreChat/packages/api/dist/index.js:32177:50)
    at getLLMConfig (LibreChat/packages/api/dist/index.js:32400:34)
    at initializeClient (LibreChat/api/server/services/Endpoints/anthropic/initialize.js:74:12)
    at async initializeAgent (LibreChat/api/server/services/Endpoints/agents/agent.js:127:19)
    at async initializeClient (LibreChat/api/server/services/Endpoints/agents/initialize.js:108:25)
    at async AgentController (LibreChat/api/server/controllers/agents/request.js:136:20)
    at async controller (LibreChat/api/server/routes/agents/chat.js:38:3)

Closes #5995.

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Translation update

Testing

  1. Set env vars:
    ANTHROPIC_MODELS=claude-sonnet-4
    ANTHROPIC_USE_VERTEX=true
    ANTHROPIC_VERTEX_REGION=global
  2. Copied Google service account key to api/data/auth.json.
  3. Tested Claude Sonnet 4 manually, with text & images

Test Configuration:

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • I have made pertinent documentation changes
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes
  • Any changes dependent on mine have been merged and published in downstream modules.
  • A pull request for updating the documentation has been submitted.

@Ziyann Ziyann changed the title feat: Add Anthropic Vertex AI Support feat: Anthropic Vertex AI Support Sep 24, 2025
@Ziyann

Ziyann commented Sep 24, 2025 •

Copy link
Copy Markdown
Contributor Author

Open questions:

  • Should we hide this behind the ANTHROPIC_USE_VERTEX env var, or should automatically detect the presence of no Anthropic API key, but Google service account present?
  • Related to above, do we want to support user provided service account keys?
  • Currently, the Google client and the Anthropic client shares the service account key/configuration. Is this how we want it, or should we use a separate key configuration?

Ideally, more tests should be also added, but I wanted to wait for feedback about the approach before doing so.

throw new Error('Anthropic API key not provided. Please provide it again.');
}
if (isEnabled(process.env.ANTHROPIC_USE_VERTEX)) {
let serviceKey = {};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

You should decouple this to a dedicated function from /packages/api

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved away most of it now, except the enabled check.

Comment thread api/app/clients/AnthropicClient.js Outdated
Comment thread package.json
"axios": "1.12.1",
"elliptic": "^6.6.1",
"form-data": "^4.0.4",
"tslib": "^2.8.1",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

why the override? seems like this should be a dev dependency?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As far as I see, tslib is used by google-auth-library, which isn't playing nice with version 1, that some dependencies are pulling in - at least keyv-file and cohere-ai (updated in the latest version), and possibly some AWS libraries. Without the override, I get:

TypeError: privateMap.get is not a function
    at __classPrivateFieldGet (LibreChat/node_modules/@aws-crypto/crc32/node_modules/tslib/tslib.js:250:27)
    at GoogleAuth.getClient (LibreChat/packages/api/dist/index.js:31449:138)
    at new AnthropicVertex (LibreChat/packages/api/dist/index.js:32177:50)

Comment thread package-lock.json Outdated

const mergedOptions = Object.assign(defaultOptions, options.modelOptions);

let creds: AnthropicCredentials = {};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

All the new logic as part of this should be dedicated functions related to the vertex handling.

Note, any changes here directly affect packages/api/src/endpoints/openai/config.ts and I would use that file as reference for how to structure things.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I extracted the Vertex handling to packages/api/src/endpoints/anthropic/vertex.ts, and cleaned it up a bit, what do you think about this approach?

@Ziyann
Ziyann requested a review from danny-avila September 25, 2025 15:32
@Ziyann Ziyann changed the title feat: Anthropic Vertex AI Support ✨ feat: Anthropic Vertex AI Support Sep 25, 2025
@aron-muon aron-muon mentioned this pull request Oct 17, 2025
@snwessel

Copy link
Copy Markdown

@danny-avila is this just awaiting your re-review? I see this was last updated a month ago and just wanted to bump it in case it had fallen off your radar.

I would very much appreciate this feature. If there's anything else that needs to be updated, I'd be happy to make some changes in support of something like this getting merged in 😁

@aron-muon

aron-muon commented Nov 20, 2025 •

Copy link
Copy Markdown
Contributor

When trying web search with Claude through VertexAI I get this response:

Something went wrong. 
Here's the specific error message we encountered: An error occurred while processing the request: 400 
Troubleshooting URL: https://js.langchain.com/docs/troubleshooting/errors/INVALID_TOOL_RESULTS/
{"type":"error","error":{"type":"invalid_request_error","message":"tools.0: Input tag 'web_search_20250305' found using 'type' does not match any of the expected tags: 'bash_20250124', 'custom', 'text_editor_20250124', 'text_editor_20250429', 'text_editor_20250728'"},"request_id":"req_vrtx_011CVKkvRzPMUqrjCUtEk9RY"} 

Just by setting web search on:
image

@Ziyann

Ziyann commented Nov 21, 2025 •

Copy link
Copy Markdown
Contributor Author

When trying web search with Claude through VertexAI I get this response:

Something went wrong. 
Here's the specific error message we encountered: An error occurred while processing the request: 400 
Troubleshooting URL: https://js.langchain.com/docs/troubleshooting/errors/INVALID_TOOL_RESULTS/
{"type":"error","error":{"type":"invalid_request_error","message":"tools.0: Input tag 'web_search_20250305' found using 'type' does not match any of the expected tags: 'bash_20250124', 'custom', 'text_editor_20250124', 'text_editor_20250429', 'text_editor_20250728'"},"request_id":"req_vrtx_011CVKkvRzPMUqrjCUtEk9RY"} 

Just by setting web search on: image

For now, searching is only available as a preview/beta feature:
https://docs.cloud.google.com/vertex-ai/generative-ai/docs/partner-models/claude/web-search

When I developed this feature, it wasn't available at all yet, so I couldn't test it.
It sounds like the fix is as simple as adding this header: "anthropic-beta": "web-search-2025-03-05".

For now, I'm not working any more on this PR, as I'm unsure if Danny will ever get to review/merge it (it's been 2 months).

@aron-muon

Copy link
Copy Markdown
Contributor

When trying web search with Claude through VertexAI I get this response:

Something went wrong. 
Here's the specific error message we encountered: An error occurred while processing the request: 400 
Troubleshooting URL: https://js.langchain.com/docs/troubleshooting/errors/INVALID_TOOL_RESULTS/
{"type":"error","error":{"type":"invalid_request_error","message":"tools.0: Input tag 'web_search_20250305' found using 'type' does not match any of the expected tags: 'bash_20250124', 'custom', 'text_editor_20250124', 'text_editor_20250429', 'text_editor_20250728'"},"request_id":"req_vrtx_011CVKkvRzPMUqrjCUtEk9RY"} 

Just by setting web search on: image

For now, searching is only available as a preview/beta feature: https://docs.cloud.google.com/vertex-ai/generative-ai/docs/partner-models/claude/web-search

When I developed this feature, it wasn't available at all yet, so I couldn't test it. It sounds like the fix is as simple as adding this header: "anthropic-beta": "web-search-2025-03-05".

For now, I'm not working any more on this PR, as I'm unsure if Danny will ever get to review/merge it (it's been 2 months).

Thanks for the reference. I was able to get it working in our deployment. Would you like me to contribute back the fix to your PR?

Danny takes a while to review things. I don't think he knows the relative priority of this PR to the other initiatives.

@Ziyann

Ziyann commented Nov 22, 2025

Copy link
Copy Markdown
Contributor Author

Thanks for the reference. I was able to get it working in our deployment. Would you like me to contribute back the fix to your PR?

Danny takes a while to review things. I don't think he knows the relative priority of this PR to the other initiatives.

Nice :) And yes, any help on this is welcome.

@aron-muon

Copy link
Copy Markdown
Contributor

Thanks for the reference. I was able to get it working in our deployment. Would you like me to contribute back the fix to your PR?
Danny takes a while to review things. I don't think he knows the relative priority of this PR to the other initiatives.

Nice :) And yes, any help on this is welcome.

PR here to fix merge conflicts:
https://github.com/Ziyann/LibreChat/pull/1

PR to add the web search fix:
https://github.com/aron-muon/LibreChat/pull/1

@Ziyann
Ziyann force-pushed the feat/anthropic-vertex-ai branch from bb8ab78 to e90b898 Compare November 23, 2025 14:34
@Ziyann
Ziyann marked this pull request as ready for review November 23, 2025 14:38
@Ziyann

Ziyann commented Nov 23, 2025

Copy link
Copy Markdown
Contributor Author

Alright, the PR is rebased on top of main, and searching is now supported thanks to @aron-muon.

On a side note, there's an unrelated error, which should be fixed in a separate PR:

error: [api/server/controllers/agents/client.js #titleConvo] Error 400 {"type":"error","error":{"type":"invalid_request_error","message":"Unexpected value(s) `prompt-caching-2024-07-31` for the `anthropic-beta` header. Please consult our documentation at docs.anthropic.com or try again without the header."},"request_id":"req_vrtx_011CVQytqbBsbnazRyxQV87m"}

The prompt-caching-2024-07-31 header has been deprecated: https://platform.claude.com/docs/en/build-with-claude/prompt-caching. This error isn't specific to Vertex AI.

@aron-muon

Copy link
Copy Markdown
Contributor

@danny-avila could you review this?

1 similar comment
@aron-muon

Copy link
Copy Markdown
Contributor

@danny-avila could you review this?

@danny-avila

danny-avila commented Nov 25, 2025 •

Copy link
Copy Markdown
Collaborator

is ANTHROPIC_USE_VERTEX an override of the entire Vertex/Google endpoint? and same with location environment variable? It would be better to not make this so static to support this feature:

#10655

Copilot AI 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.

Pull request overview

This PR adds support for using Anthropic models through Google Vertex AI as an alternative to the direct Anthropic API. The implementation introduces credential handling for service account keys, adds configuration options for Vertex AI region and usage, and creates a new client initialization path when Vertex AI is enabled.

Key Changes:

  • Added Vertex AI client creation and credential loading utilities
  • Modified credential handling to support both API keys and service account keys
  • Added environment variables for Vertex AI configuration (ANTHROPIC_USE_VERTEX, ANTHROPIC_VERTEX_REGION)

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
packages/data-provider/src/config.ts Added ANTHROPIC_API_KEY auth key enum value
packages/api/src/types/anthropic.ts Defined AnthropicCredentials type to support both API key and service account credentials
packages/api/src/endpoints/anthropic/vertex.ts Created utilities for loading Vertex AI credentials, checking credential types, and creating Vertex AI clients
packages/api/src/endpoints/anthropic/llm.ts Modified getLLMConfig to accept credentials object instead of API key string, added credential parsing and Vertex AI client configuration
packages/api/src/endpoints/anthropic/index.ts Exported vertex module functions
packages/api/package.json Added @anthropic-ai/vertex-sdk peer dependency
package.json Added tslib version override to fix dependency conflicts
api/server/services/Endpoints/anthropic/initialize.js Updated initialization to conditionally load Vertex AI credentials or API key based on configuration
api/server/services/Config/EndpointService.js Modified endpoint configuration to enable Anthropic when Vertex AI is configured
api/package.json Added @anthropic-ai/vertex-sdk dependency
.env.example Added documentation for Vertex AI configuration variables

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.

function getLLMConfig(
apiKey?: string,
options: AnthropicConfigOptions = {} as AnthropicConfigOptions,
credentials: string | AnthropicCredentials | undefined,

Copilot AI Nov 25, 2025

Copy link

Choose a reason for hiding this comment

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

[nitpick] The parameter name 'credentials' is misleading when the function can accept a string API key. Consider renaming to 'credentialsOrApiKey' or handling the string case separately to make the API clearer. The string format appears to be for backward compatibility but creates ambiguity about the expected input format.

Copilot uses AI. Check for mistakes.
Comment on lines +115 to +121
const apiKey = creds[AuthKeys.ANTHROPIC_API_KEY] ?? null;

if (isAnthropicVertexCredentials(creds)) {
// Vertex AI configuration - use custom client
requestOptions.createClient = () =>
createAnthropicVertexClient(creds, requestOptions.clientOptions);
} else if (apiKey) {

Copilot AI Nov 25, 2025

Copy link

Choose a reason for hiding this comment

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

[nitpick] The apiKey is assigned but may remain null, which is then used in the conditional check at line 121. Consider using undefined instead of null for consistency with optional values, or use a more explicit check like creds[AuthKeys.ANTHROPIC_API_KEY] !== undefined.

Suggested change
const apiKey = creds[AuthKeys.ANTHROPIC_API_KEY] ?? null;
if (isAnthropicVertexCredentials(creds)) {
// Vertex AI configuration - use custom client
requestOptions.createClient = () =>
createAnthropicVertexClient(creds, requestOptions.clientOptions);
} else if (apiKey) {
const apiKey = creds[AuthKeys.ANTHROPIC_API_KEY];
if (isAnthropicVertexCredentials(creds)) {
// Vertex AI configuration - use custom client
requestOptions.createClient = () =>
createAnthropicVertexClient(creds, requestOptions.clientOptions);
} else if (apiKey !== undefined) {

Copilot uses AI. Check for mistakes.
});

return new AnthropicVertex({
region: region,

Copilot AI Nov 25, 2025

Copy link

Choose a reason for hiding this comment

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

Redundant property assignment. Use shorthand property syntax: region, instead of region: region,.

Suggested change
region: region,
region,

Copilot uses AI. Check for mistakes.

return new AnthropicVertex({
region: region,
googleAuth: googleAuth,

Copilot AI Nov 25, 2025

Copy link

Choose a reason for hiding this comment

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

Redundant property assignment. Use shorthand property syntax: googleAuth, instead of googleAuth: googleAuth,.

Suggested change
googleAuth: googleAuth,
googleAuth,

Copilot uses AI. Check for mistakes.
@Ziyann

Ziyann commented Nov 25, 2025

Copy link
Copy Markdown
Contributor Author

is ANTHROPIC_USE_VERTEX an override of the entire Vertex/Google endpoint? and same with location environment variable? It would be better to not make this so static to support this feature:

#10655

What do you have in mind? It's true that setting ANTHROPIC_USE_VERTEX will cause Anthropic models to always try to use Vertex AI. Would you like to keep support for user provided Anthropic API keys? As far as I seen, there's no other method currently to configure Anthroptic models (the linked issue highlights this as well). So I'm not really sure what to change.

@Ziyann

Ziyann commented Dec 3, 2025

Copy link
Copy Markdown
Contributor Author

Continued in #10780.

@Ziyann Ziyann closed this Dec 3, 2025
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.

[Enhancement]: Running Claude Sonnet V2 by Google VertexAI

6 participants