Skip to content

feat: add Google Vertex AI provider (AnthropicVertex SDK) - #55742

Open
EgorLu wants to merge 3 commits into
NousResearch:mainfrom
EgorLu:feat/vertex-provider
Open

feat: add Google Vertex AI provider (AnthropicVertex SDK)#55742
EgorLu wants to merge 3 commits into
NousResearch:mainfrom
EgorLu:feat/vertex-provider

Conversation

@EgorLu

@EgorLu EgorLu commented Jun 30, 2026

Copy link
Copy Markdown

What does this PR do?

Adds native support for running Claude models on Google Vertex AI using Anthropic's AnthropicVertex SDK adapter. Users set provider: vertex in config and authenticate via Google Application Default Credentials (ADC) — no Anthropic API key needed. Useful for corporate GCP environments where direct Anthropic API access is unavailable.

Architecture: follows the Bedrock pattern

The provider is named vertex (not vertex-anthropic) because Vertex AI is a cloud platform that hosts models from multiple vendors analogous to how Bedrock is named bedrock, not bedrock-anthropic.
The implementation mirrors Bedrock's dual-path routing:

  • Runtime resolution checks the model name via _is_anthropic_vertex_model() (mirrors is_anthropic_bedrock_model())
  • Claude modelsapi_mode: anthropic_messages + AnthropicVertex SDK for full feature parity (prompt caching, thinking budgets)
  • Non-Claude models → clear error noting Gemini/other support is planned (the routing infrastructure is ready for future expansion)

Configuration

export ANTHROPIC_VERTEX_PROJECT_ID=your-gcp-project
export CLOUD_ML_REGION=global  # optional
gcloud auth application-default login
# ~/.hermes/config.yaml
model:
  default: claude-sonnet-4-6
  provider: vertex

vertex:
  project_id: your-gcp-project
  region: global

Related Issue

Closes #13484
Closes #12639
Related: #3569, #6491 (prior attempts with smaller scope — this PR covers full CLI integration, model-based routing, docs, and tests)

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)

Changes Made

Provider registration

  • plugins/model-providers/vertex/ — ProviderProfile with gcp_adc auth type, aliases (google-vertex, gcp-vertex, vertex-ai, vertex-anthropic)
  • hermes_cli/auth.py — ProviderConfig, get_vertex_auth_status(), resolve_vertex_anthropic_runtime_credentials()
  • hermes_cli/runtime_provider.py — model-based routing with _is_anthropic_vertex_model()

CLI integration

  • hermes_cli/models.py — ProviderEntry, aliases, static model catalog
  • hermes_cli/main.py + model_setup_flows.py_model_flow_vertex() setup wizard (project ID, region, model selection)

Runtime wiring

  • agent/anthropic_adapter.pybuild_anthropic_vertex_client() (lazy-installs anthropic[vertex], excludes context-1m beta)
  • agent/agent_init.py — Vertex client construction branch (parallel to Bedrock)
  • run_agent.py_rebuild_anthropic_client Vertex dispatch
  • agent/agent_runtime_helpers.py — runtime recovery, restore, switch_model Vertex paths
  • agent/chat_completion_helpers.py — fallback activation Vertex path
  • agent/auxiliary_client.py — vision backend + auxiliary resolution for gcp_adc auth type

Dependencies

  • pyproject.tomlanthropic-vertex optional extra (anthropic[vertex]==0.87.0)
  • tools/lazy_deps.py — lazy install entry

Tests (7 new, 702 total passing)

  • tests/agent/test_anthropic_adapter.py — 2 tests (client construction, SDK requirement)
  • tests/hermes_cli/test_runtime_provider_resolution.py — 3 tests (env var precedence, fallback, missing project)
  • tests/run_agent/test_run_agent.py — 2 tests (init dispatch, rebuild dispatch)

Docs

  • website/docs/guides/vertex-ai.md — full guide (prerequisites, quick start, config, troubleshooting)
  • website/docs/integrations/providers.md — providers table entry

How to Test

  1. Set up GCP credentials:

    export ANTHROPIC_VERTEX_PROJECT_ID=your-project
    gcloud auth application-default login
  2. Run the setup wizard:

    hermes model  # choose "Google Vertex AI"
  3. Chat:

    hermes chat -q "Hello from Vertex"
  4. Run tests:

    python -m pytest tests/hermes_cli/test_runtime_provider_resolution.py::TestVertexRuntimeResolution tests/agent/test_anthropic_adapter.py tests/run_agent/test_run_agent.py::TestVertexClientSelection -v

Checklist

  • I've tested these changes locally
  • Tests pass
  • New tests added for new functionality
  • Documentation updated
  • No breaking changes to existing functionality

@EgorLu
EgorLu requested a review from a team June 30, 2026 15:54
@EgorLu

EgorLu commented Jun 30, 2026

Copy link
Copy Markdown
Author

Verified e2e functionality.
Later we can add additional models support by demand.

@rodriguez46p-ui

Copy link
Copy Markdown

Hermes Agent Review — PR #55742

Verdict: changes requested (configuration persistence bug)

Blocking finding

  • hermes_cli/model_setup_flows.py:2315-2323 saves the Vertex project and region under vertex.project_id / vertex.region in config.yaml, and website/docs/guides/vertex-ai.md:42-52 documents that as the post-setup configuration. However, hermes_cli/auth.py:6285-6291 only resolves project/region from environment variables (ANTHROPIC_VERTEX_PROJECT_ID, GOOGLE_CLOUD_PROJECT, GCLOUD_PROJECT, CLOUD_ML_REGION) and never reads the saved vertex config section. As a result, a user who completes hermes model successfully can still fail at runtime unless they also export the env vars manually.

Reproduction evidence

In a detached PR worktree, I wrote a temp HERMES_HOME/config.yaml containing:

model:
  provider: vertex
  default: claude-sonnet-4-6
vertex:
  project_id: config-project
  region: europe-west4

with all Vertex env vars cleared, then called resolve_runtime_provider(requested='vertex'). It failed with:

AuthError No Vertex Anthropic project configured. Set ANTHROPIC_VERTEX_PROJECT_ID, GOOGLE_CLOUD_PROJECT, or GCLOUD_PROJECT. missing_vertex_project

Suggested fix

Teach resolve_vertex_anthropic_runtime_credentials() to read config.yaml's vertex.project_id and vertex.region after the env-var precedence (or make the setup flow persist to the same source the resolver uses). Add a regression test that creates a temp Hermes home with only vertex.project_id / vertex.region configured and asserts resolve_runtime_provider(requested='vertex') succeeds.

Checks run

  • git diff --check origin/main...HEAD — passed.
  • Focused PR tests passed:
    • tests/hermes_cli/test_runtime_provider_resolution.py::TestVertexRuntimeResolution
    • tests/agent/test_anthropic_adapter.py::TestBuildAnthropicClient::test_vertex_client_uses_project_and_region
    • tests/run_agent/test_run_agent.py::TestVertexClientSelection
  • Additional ad-hoc config-only probe exposed the blocker above.

Reviewed by Hermes Agent hourly commander.

@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard provider/anthropic Anthropic native Messages API labels Jun 30, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Competing-implementation cluster for native Google Vertex AI support (Claude via the AnthropicVertex SDK), all currently OPEN: #3569 (earliest, canonical), #6491, #27356, and this PR. The Gemini-on-Vertex sibling is #36253. Feature issues: #13484, #12639. Per triage duplicate-discipline these are related, not duplicates of one another — a maintainer should pick one of the AnthropicVertex-Claude implementations to carry forward.

@EgorLu

EgorLu commented Jul 1, 2026

Copy link
Copy Markdown
Author

Thanks for the triage. A few notes on why this PR may be the one to carry forward:

Scope comparison:

Architecture: Named vertex (not vertex-anthropic) following the Bedrock pattern -- cloud platform name with model-based routing. Claude models use AnthropicVertex SDK; the routing infrastructure is ready for future Gemini/OpenAI-compat expansion.

Already verified: live smoke-tested against real Vertex credentials (plain text + tool calls), and the config persistence bug flagged in review is fixed.

Happy to cherry-pick any useful ideas from the other PRs if there's something I missed.

@alt-glitch alt-glitch added the area/auth Authentication, OAuth, credential pools label Jul 1, 2026
@EgorLu
EgorLu force-pushed the feat/vertex-provider branch from bac2abe to 133342c Compare July 1, 2026 13:59
@EgorLu

EgorLu commented Jul 1, 2026

Copy link
Copy Markdown
Author

@teknium1 rebased upon your PR

@balajisiva

Copy link
Copy Markdown

Local validation (enterprise GCP / ADC)

Tested branch feat/vertex-provider on macOS with Application Default Credentials against a private corporate GCP project with Vertex Claude access.

hermes auth status vertex → logged in
Plain chat with claude-sonnet-4-6, region global → success
Config-only path (vertex.project_id / vertex.region in config.yaml, Vertex env vars unset) → success (config persistence fix looks good)
Tool calling via terminal tool → success
Focused pytest suite for Vertex resolution/client selection → 24/24 passed
This unblocks our Hermes adoption for always-on agents on Vertex. Happy to help review or test follow-up commits. Details of our environment available privately if useful.

@EgorLu

EgorLu commented Jul 8, 2026

Copy link
Copy Markdown
Author

@teknium1 can we proceed with this addition?

@teknium1 teknium1 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 for carrying the AnthropicVertex implementation through runtime, switching, recovery, tests, and documentation. Current main already ships Vertex Gemini support in c73e74386, so this needs to extend that dual-provider surface rather than replace its assumptions.

Problems

  • agent/agent_init.py:455 unconditionally maps provider="vertex" to anthropic_messages when no API mode is supplied. That bypasses the PR's model-based routing for direct Gemini AIAgent construction.
  • agent/auxiliary_client.py:5137 checks auth_type == "gcp_adc", but plugins/model-providers/vertex/__init__.py:71 still defines Vertex as auth_type="vertex"; the new AnthropicVertex auxiliary branch is unreachable.
  • hermes_cli/model_setup_flows.py:2428-2445 remains Gemini-only, while website/docs/guides/vertex-ai.md:11-12 incorrectly says Gemini is unsupported. The new page is not registered in website/sidebars.ts, which still links guides/google-vertex at line 704.

Suggested changes

  • Preserve the existing Gemini OAuth/OpenAI path and make Claude-vs-Gemini routing model-aware across initialization and auxiliary clients.
  • Add focused tests for direct initialization, auxiliary resolution, and both wizard-selected model families.
  • Consolidate the docs with website/docs/guides/google-vertex.md and keep provider documentation truthful for both paths.

This is an automated hermes-sweeper review.

Comment thread agent/agent_init.py
@@ -452,6 +452,8 @@ def init_agent(
elif (provider_name is None) and agent._base_url_hostname == "api.x.ai":
agent.api_mode = "codex_responses"
agent.provider = "xai"
elif agent.provider == "vertex":

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.

This forces every direct AIAgent(provider="vertex") construction into Anthropic mode before the model can be considered. Preserve the current Gemini chat_completions path and select AnthropicVertex only when the resolved model is Claude.

Comment thread agent/auxiliary_client.py Outdated
@@ -5134,6 +5134,40 @@ def _wrap_if_needed(client_obj, final_model_str: str, base_url_str: str = "",
return (_to_async_client(client, final_model, is_vision=is_vision) if async_mode
else (client, final_model))

elif pconfig.auth_type == "gcp_adc":

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.

This branch is unreachable for Vertex: the provider profile still declares auth_type="vertex", so resolve_provider_client("vertex", claude_model) takes the existing Gemini branch. Route Claude model selection within the existing Vertex branch and add an auxiliary-client regression test.

Comment thread website/docs/guides/vertex-ai.md Outdated

Hermes Agent supports Google Vertex AI as a native provider using Anthropic's **AnthropicVertex SDK** -- the same `.messages.create()` interface as the regular Anthropic client. This gives you full Claude feature parity (prompt caching, thinking budgets) while authenticating through Google Cloud's credential chain.

:::info Claude models only (for now)

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.

This conflicts with current main's shipped Gemini-on-Vertex path (hermes_cli/runtime_provider.py:1579-1610) and with this PR's Gemini else path. Consolidate this with the existing guides/google-vertex.md instead of documenting Vertex as Claude-only.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
@alt-glitch alt-glitch removed the sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state label Jul 15, 2026
EgorLu added 3 commits July 29, 2026 15:06
Add native support for running Claude models on Google Vertex AI using
Anthropic's AnthropicVertex SDK adapter. The provider is named 'vertex'
(following the Bedrock pattern) with model-based routing: Claude models
use the AnthropicVertex SDK for full feature parity (prompt caching,
thinking budgets), while non-Claude models raise a clear error noting
that Gemini/other model support is planned.

Configuration uses Google Application Default Credentials (ADC):

    export ANTHROPIC_VERTEX_PROJECT_ID=your-gcp-project
    export CLOUD_ML_REGION=global  # optional, defaults to 'global'
    gcloud auth application-default login

Provider registration:
- plugins/model-providers/vertex/ — ProviderProfile with gcp_adc auth
- hermes_cli/auth.py — ProviderConfig, auth status, credential resolver
- hermes_cli/runtime_provider.py — model-based routing with
  _is_anthropic_vertex_model() (mirrors is_anthropic_bedrock_model)
- hermes_cli/models.py — ProviderEntry, aliases, static model catalog
- hermes_cli/main.py + model_setup_flows.py — 'hermes model' wizard

Runtime wiring:
- agent/anthropic_adapter.py — build_anthropic_vertex_client()
- agent/agent_init.py — Vertex client construction branch
- run_agent.py — _rebuild_anthropic_client Vertex dispatch
- agent/agent_runtime_helpers.py — runtime recovery + switch_model
- agent/chat_completion_helpers.py — fallback activation
- agent/auxiliary_client.py — vision backend + auxiliary resolution

Dependencies:
- pyproject.toml — anthropic-vertex optional extra
- tools/lazy_deps.py — lazy install entry

Tests: 7 new tests covering adapter, runtime resolution, client init.
Docs: vertex-ai.md guide + providers table entry.

Aliases: google-vertex, gcp-vertex, vertex-ai, vertex-anthropic.

Closes NousResearch#13484, closes NousResearch#12639.
Related: NousResearch#3569, NousResearch#6491 (prior attempts, smaller scope).
The credential resolver only checked env vars, so a user who completed
'hermes model' successfully (which saves vertex.project_id and
vertex.region to config.yaml) could still fail at runtime unless they
also exported env vars manually.

Now resolve_vertex_anthropic_runtime_credentials() reads config.yaml's
vertex section as a fallback, mirroring how Bedrock reads bedrock.region.

Resolution order:
  1. Env vars (ANTHROPIC_VERTEX_PROJECT_ID, GOOGLE_CLOUD_PROJECT, etc.)
  2. config.yaml vertex.project_id / vertex.region
  3. Default region 'global'

Added 3 regression tests:
  - config-only path resolves from config.yaml
  - env vars take precedence over config.yaml
  - runtime resolver works with config-only credentials
…s consolidation

- agent_init.py: vertex api_mode is now model-aware (Claude→anthropic_messages,
  Gemini→chat_completions) instead of unconditionally forcing anthropic_messages
- auxiliary_client.py: merged Claude+Gemini into single auth_type=='vertex' block
  with model-based routing; removed unreachable gcp_adc branch
- auth.py: aligned auth_type from 'gcp_adc' to 'vertex' to match plugin registry;
  fixed downstream gcp_adc references
- model_setup_flows.py: confirmation message shows correct SDK path per model family
- models.py: removed duplicate ProviderEntry with stale description
- docs: consolidated vertex-ai.md into google-vertex.md (already in sidebars.ts);
  removed incorrect 'Gemini unsupported' claim; updated providers.md table
- tests: 7 new tests for direct init, auxiliary resolution, runtime provider routing
@EgorLu
EgorLu force-pushed the feat/vertex-provider branch from f4fb512 to b99adcb Compare July 29, 2026 12:08
@alt-glitch alt-glitch added comp/plugins Plugin system and bundled plugins needs-decision Awaiting maintainer decision before any implementation labels Jul 29, 2026
@EgorLu

EgorLu commented Aug 3, 2026

Copy link
Copy Markdown
Author

@teknium1 Any progress with getting this merged?
Without an official support, each user / employee of the company using Vertex is required to manually patch their installation on every update.

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

Labels

area/auth Authentication, OAuth, credential pools comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint comp/cli CLI entry point, hermes_cli/, setup wizard comp/plugins Plugin system and bundled plugins needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have provider/anthropic Anthropic native Messages API sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data type/feature New feature or request

Projects

None yet

5 participants