Skip to content

feat(google): add Google Vertex AI provider with ADC auth and global endpoint routing#60860

Closed
PewterZz wants to merge 12 commits into
openclaw:mainfrom
PewterZz:feat/google-vertex-provider
Closed

feat(google): add Google Vertex AI provider with ADC auth and global endpoint routing#60860
PewterZz wants to merge 12 commits into
openclaw:mainfrom
PewterZz:feat/google-vertex-provider

Conversation

@PewterZz

@PewterZz PewterZz commented Apr 4, 2026

Copy link
Copy Markdown

Summary

  • Registers a new google-vertex provider in the Google plugin that routes to aiplatform.googleapis.com using Application Default Credentials (ADC), separate from the existing google-gemini-cli OAuth path
  • Adds vertex-region.ts for region/project/baseUrl resolution (env vars + ADC file fallback), with global location producing the unprefixed aiplatform.googleapis.com endpoint
  • Adds vertex-provider-catalog.ts with the Gemini 3.x model catalog for Vertex AI
  • Updates the Google transport stream to detect Vertex endpoints and construct the correct project/location URL path (/v1/projects/{project}/locations/{location}/publishers/google/models/{model}:streamGenerateContent)
  • Exchanges ADC refresh token for a Bearer token at request time, handling the pi-ai "<authenticated>" sentinel that was previously sent as a literal API key causing 401s
  • Captures thought_signature from Gemini 3 thinking-mode tool call responses so multi-turn conversations replay correctly (fixes 400 INVALID_ARGUMENT on second turn)
  • Adds GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER sentinel and registers google-vertex in openclaw.plugin.json

Closes #49039
Closes #56253
Closes #58775
Closes #60736

Test plan

  • pnpm test extensions/google/vertex-region.test.ts — 20 cases, all pass
  • pnpm test extensions/google/vertex-provider-catalog.test.ts — 7 cases, all pass
  • pnpm test src/infra/gemini-auth.test.ts — 5 cases, all pass
  • Live: google-vertex/gemini-3-flash-preview with GOOGLE_CLOUD_LOCATION=global and GOOGLE_CLOUD_PROJECT set — correct Vertex URL, Bearer auth, successful response

@PewterZz
PewterZz requested a review from a team as a code owner April 4, 2026 12:47
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: L labels Apr 4, 2026
@greptile-apps

greptile-apps Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a google-vertex provider to the Google plugin, routing to aiplatform.googleapis.com via Application Default Credentials (ADC), with separate region/project resolution, a Gemini 3.x model catalog, Vertex URL path construction, and thought_signature capture for multi-turn tool call replay.

  • P1: src/agents/model-auth-env.ts gates google-vertex on hasAnthropicVertexAvailableAuth, which returns true when ANTHROPIC_VERTEX_USE_GCP_METADATA=1 even without an ADC file. This causes the sentinel to be issued when no real token can be fetched, producing a silent auth failure at request time. The check should mirror hasGoogleVertexAvailableAuth (ADC file readable only), not the Anthropic-specific function.

Confidence Score: 4/5

Safe to merge after fixing the wrong auth-presence predicate in model-auth-env.ts; all other concerns are minor.

One P1 defect: google-vertex availability is gated by the Anthropic Vertex auth check (ANTHROPIC_VERTEX_USE_GCP_METADATA=1 without an ADC file returns the sentinel but fails at token-fetch time). The rest of the implementation — Vertex URL routing, ADC token exchange, thought_signature capture, provider registration — looks correct.

src/agents/model-auth-env.ts — wrong auth-presence function used for google-vertex

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/model-auth-env.ts
Line: 45-46

Comment:
**Wrong auth-presence check for `google-vertex`**

`hasAnthropicVertexAvailableAuth` is imported from `anthropic-vertex-auth-presence.ts` and returns `true` when `ANTHROPIC_VERTEX_USE_GCP_METADATA=1` *even with no ADC file on disk*. If a user sets that env var (for their Anthropic Vertex setup) but has no `application_default_credentials.json`, this block returns the `GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER` sentinel — but `resolveGoogleVertexAccessToken` in `google-vertex-adc.ts` then reads the ADC file, gets `null`, and the request fails at runtime with no helpful error.

The equivalent check for Google's ADC presence is `hasGoogleVertexAvailableAuth` (already exported from `extensions/google/vertex-region.ts`), but since that lives in the extension package it can't be imported here directly. The same gating logic that the extension's catalog uses (`canReadAdc`) should be replicated in core — similar to how `canReadAnthropicVertexAdc` is defined locally in `anthropic-vertex-auth-presence.ts`. A minimal fix is to inline an ADC-file-readable check here, or add a dedicated `hasGoogleVertexAdcAvailableAuth` helper in a new `google-vertex-auth-presence.ts` alongside its Anthropic sibling.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/agents/google-vertex-adc.ts
Line: 81-98

Comment:
**Service-account ADC type silently falls through**

Only `authorized_user` credentials are exchanged for a token; all other ADC types (most commonly `service_account` JSON key files) reach the final `return null` with no diagnostic. Production GCP workloads typically use service-account keys, so this creates a confusing silent failure. Consider throwing or logging a clear message when the ADC file is present but its `type` is unhandled, so users aren't left wondering why auth is failing.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: extensions/google/vertex-provider-catalog.ts
Line: 13

Comment:
**Duplicated marker constant**

`GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER` is defined as a private constant in both this file and `vertex-region.ts` (and exported from `src/agents/model-auth-markers.ts`). Within the extension package, `vertex-provider-catalog.ts` could import it from `./vertex-region.js` if it were exported there, avoiding silent value drift if the marker is ever renamed.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(google): add Google Vertex AI provi..." | Re-trigger Greptile

Re-review progress:

Comment thread src/agents/model-auth-env.ts Outdated
Comment on lines +45 to +46
if (hasAnthropicVertexAvailableAuth(env)) {
return { apiKey: GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER, source: "gcloud 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.

P1 Wrong auth-presence check for google-vertex

hasAnthropicVertexAvailableAuth is imported from anthropic-vertex-auth-presence.ts and returns true when ANTHROPIC_VERTEX_USE_GCP_METADATA=1 even with no ADC file on disk. If a user sets that env var (for their Anthropic Vertex setup) but has no application_default_credentials.json, this block returns the GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER sentinel — but resolveGoogleVertexAccessToken in google-vertex-adc.ts then reads the ADC file, gets null, and the request fails at runtime with no helpful error.

The equivalent check for Google's ADC presence is hasGoogleVertexAvailableAuth (already exported from extensions/google/vertex-region.ts), but since that lives in the extension package it can't be imported here directly. The same gating logic that the extension's catalog uses (canReadAdc) should be replicated in core — similar to how canReadAnthropicVertexAdc is defined locally in anthropic-vertex-auth-presence.ts. A minimal fix is to inline an ADC-file-readable check here, or add a dedicated hasGoogleVertexAdcAvailableAuth helper in a new google-vertex-auth-presence.ts alongside its Anthropic sibling.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/model-auth-env.ts
Line: 45-46

Comment:
**Wrong auth-presence check for `google-vertex`**

`hasAnthropicVertexAvailableAuth` is imported from `anthropic-vertex-auth-presence.ts` and returns `true` when `ANTHROPIC_VERTEX_USE_GCP_METADATA=1` *even with no ADC file on disk*. If a user sets that env var (for their Anthropic Vertex setup) but has no `application_default_credentials.json`, this block returns the `GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER` sentinel — but `resolveGoogleVertexAccessToken` in `google-vertex-adc.ts` then reads the ADC file, gets `null`, and the request fails at runtime with no helpful error.

The equivalent check for Google's ADC presence is `hasGoogleVertexAvailableAuth` (already exported from `extensions/google/vertex-region.ts`), but since that lives in the extension package it can't be imported here directly. The same gating logic that the extension's catalog uses (`canReadAdc`) should be replicated in core — similar to how `canReadAnthropicVertexAdc` is defined locally in `anthropic-vertex-auth-presence.ts`. A minimal fix is to inline an ADC-file-readable check here, or add a dedicated `hasGoogleVertexAdcAvailableAuth` helper in a new `google-vertex-auth-presence.ts` alongside its Anthropic sibling.

How can I resolve this? If you propose a fix, please make it concise.

Comment thread src/agents/google-vertex-adc.ts Outdated
Comment on lines +81 to +98
adc.project_id ||
undefined;

if (adc.type === "authorized_user") {
const result = await refreshAuthorizedUserToken(adc as AdcAuthorizedUser);
cachedToken = {
accessToken: result.access_token,
projectId,
expiresAt: Date.now() + result.expires_in * 1000,
};
return cachedToken;
}

return null;
}

export function clearGoogleVertexTokenCache(): void {
cachedToken = null;

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.

P2 Service-account ADC type silently falls through

Only authorized_user credentials are exchanged for a token; all other ADC types (most commonly service_account JSON key files) reach the final return null with no diagnostic. Production GCP workloads typically use service-account keys, so this creates a confusing silent failure. Consider throwing or logging a clear message when the ADC file is present but its type is unhandled, so users aren't left wondering why auth is failing.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/google-vertex-adc.ts
Line: 81-98

Comment:
**Service-account ADC type silently falls through**

Only `authorized_user` credentials are exchanged for a token; all other ADC types (most commonly `service_account` JSON key files) reach the final `return null` with no diagnostic. Production GCP workloads typically use service-account keys, so this creates a confusing silent failure. Consider throwing or logging a clear message when the ADC file is present but its `type` is unhandled, so users aren't left wondering why auth is failing.

How can I resolve this? If you propose a fix, please make it concise.


export const GOOGLE_VERTEX_DEFAULT_MODEL_ID = "gemini-3.1-pro-preview";
const GOOGLE_VERTEX_DEFAULT_CONTEXT_WINDOW = 1_000_000;
const GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER = "gcp-vertex-google-credentials";

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.

P2 Duplicated marker constant

GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER is defined as a private constant in both this file and vertex-region.ts (and exported from src/agents/model-auth-markers.ts). Within the extension package, vertex-provider-catalog.ts could import it from ./vertex-region.js if it were exported there, avoiding silent value drift if the marker is ever renamed.

Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/google/vertex-provider-catalog.ts
Line: 13

Comment:
**Duplicated marker constant**

`GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER` is defined as a private constant in both this file and `vertex-region.ts` (and exported from `src/agents/model-auth-markers.ts`). Within the extension package, `vertex-provider-catalog.ts` could import it from `./vertex-region.js` if it were exported there, avoiding silent value drift if the marker is ever renamed.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ebab852f19

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/google-vertex-adc.ts Outdated
Comment on lines +84 to +88
if (adc.type === "authorized_user") {
const result = await refreshAuthorizedUserToken(adc as AdcAuthorizedUser);
cachedToken = {
accessToken: result.access_token,
projectId,

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.

P1 Badge Support non-user ADC credentials for Vertex auth

The new Vertex token resolver only exchanges tokens when the ADC file is type: "authorized_user"; all other ADC types fall through with no token. In environments that use service-account ADC (GOOGLE_APPLICATION_CREDENTIALS in CI/GKE/Cloud Run), this makes runtime auth unresolved and requests end up unauthenticated (or sent with the marker as an API key), causing Vertex calls to fail consistently. Please add token minting for service-account/metadata ADC or refuse to advertise Vertex auth when the ADC type is unsupported.

Useful? React with 👍 / 👎.

Comment thread src/agents/model-auth-env.ts Outdated
Comment on lines +45 to +46
if (hasAnthropicVertexAvailableAuth(env)) {
return { apiKey: GCP_VERTEX_GOOGLE_CREDENTIALS_MARKER, source: "gcloud 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.

P2 Badge Gate google-vertex env auth with the correct capability check

The google-vertex branch uses hasAnthropicVertexAvailableAuth, which can return true via Anthropic-specific metadata opt-in even when Google Vertex cannot actually resolve a token in this implementation. That emits the gcp-vertex-google-credentials marker and leads to failed runtime auth for google-vertex configs without readable Google ADC credentials. This should use a Google-specific availability predicate that matches what the Google resolver can truly handle.

Useful? React with 👍 / 👎.

Comment on lines +108 to +110
return {
...implicit,
...existing,

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.

P2 Badge Recompute Vertex location when baseUrl is overridden

Merging implicit and configured provider settings allows existing.baseUrl to override the implicit endpoint, but the region/header state is not recomputed from that effective URL. As a result, users who set models.providers.google-vertex.baseUrl to another region can still send /locations/us-central1/... paths, which causes Vertex INVALID_ARGUMENT request routing failures. The merge should derive location from the final base URL (or synchronize headers accordingly).

Useful? React with 👍 / 👎.

@PewterZz
PewterZz force-pushed the feat/google-vertex-provider branch from ebab852 to 72aece9 Compare April 4, 2026 12:52

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4e0c16151e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/google-transport-stream.ts Outdated
Comment on lines +202 to +206
const origin = baseUrl.replace(/\/+$/, "");
const modelPath = modelId.startsWith("publishers/")
? modelId
: `publishers/google/models/${modelId}`;
return `${origin}/v1/projects/${projectId}/locations/${location}/${modelPath}:streamGenerateContent?alt=sse`;

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.

P2 Badge Strip path from Vertex baseUrl before composing request URL

This URL builder uses the full configured baseUrl as the prefix and then appends /v1/projects/..., so a valid override like https://us-central1-aiplatform.googleapis.com/v1 produces .../v1/v1/projects/... and Vertex requests fail. This commit newly supports google-vertex baseUrl overrides, so users who copy a /v1 endpoint form will get hard request failures until the builder normalizes to URL origin (or strips an existing /v1) before appending the path.

Useful? React with 👍 / 👎.

Comment on lines +116 to +119
if (params.model.provider === "google-vertex") {
const boundaryAwareStreamFn = createBoundaryAwareStreamFnForModel(params.model);
if (boundaryAwareStreamFn) {
return boundaryAwareStreamFn;

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.

P2 Badge Preserve explicit session streamFn for google-vertex models

This new provider-specific branch returns a boundary-aware stream function before the existing custom-stream fallback, so any explicitly supplied currentStreamFn is ignored whenever model.provider === "google-vertex". That is a behavior regression for integrations that attach custom stream wrappers (for telemetry, retries, policy checks, etc.), because those wrappers now silently stop running for Vertex models.

Useful? React with 👍 / 👎.

@PewterZz
PewterZz force-pushed the feat/google-vertex-provider branch from f89cdae to e47140a Compare April 4, 2026 13:43

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 39e250c4ea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/google-transport-stream.ts Outdated
Comment on lines +203 to +205
const modelPath = modelId.startsWith("publishers/")
? modelId
: `publishers/google/models/${modelId}`;

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.

P2 Badge Preserve prequalified Vertex model IDs in request paths

The Vertex URL builder always prefixes non-publishers/ model IDs with publishers/google/models/, so inputs like models/gemini-2.5-pro or tunedModels/... become invalid paths such as .../publishers/google/models/models/.... This causes Vertex requests to fail for model ID formats that are already accepted in the non-Vertex Google path logic, so the builder should treat already-qualified IDs as complete instead of blindly prefixing.

Useful? React with 👍 / 👎.

Comment thread src/agents/google-vertex-adc.ts Outdated
Comment on lines +80 to +81
("quota_project_id" in adc ? adc.quota_project_id : undefined) ||
adc.project_id ||

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.

P2 Badge Prefer ADC project_id over quota_project_id for routing

This resolves the ADC project as quota_project_id before project_id, which conflicts with the implicit provider project resolution (in extensions/google/vertex-region.ts) that prefers project_id first. Because request URL construction prioritizes the token-derived project, ADC files containing both fields can route calls to the quota/billing project instead of the intended Vertex project, leading to avoidable permission or not-found failures.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a98d4fd690

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/google-transport-stream.ts Outdated
Comment on lines +229 to +230
const normalizedBaseUrl = normalizeGoogleApiBaseUrl(model.baseUrl);
return `${normalizedBaseUrl}/${resolveGoogleModelPath(model.id)}:streamGenerateContent?alt=sse`;

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.

P2 Badge Fail fast when Vertex project ID is unavailable

When baseUrl is a Vertex endpoint but no project id can be resolved (no GOOGLE_CLOUD_PROJECT, no provider header, and no ADC-derived project), this code falls back to the generic Gemini URL shape (.../models/...) on the Vertex host instead of returning a clear configuration error. That request shape is invalid for Vertex and will fail at runtime with a confusing API error, so users with ADC credentials lacking project metadata get broken requests rather than actionable guidance.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a4d659ee6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/google-transport-stream.ts Outdated
Comment on lines +666 to +670
const location =
model.headers?.["x-openclaw-vertex-location"] ||
process.env.GOOGLE_CLOUD_LOCATION ||
"us-central1";
return JSON.stringify({

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.

P2 Badge Let Vertex request URL infer location from endpoint

When ADC is used, this helper always injects a location field and defaults it to "us-central1"; later buildGoogleRequestUrl prioritizes that value over the endpoint-derived region. In configs that point baseUrl at another Vertex region (or the global host) without explicitly setting x-openclaw-vertex-location, requests are routed to /locations/us-central1/... on the wrong endpoint and fail with Vertex routing/INVALID_ARGUMENT errors. Leave location unset unless it is explicitly known so URL construction can fall back to the base URL region.

Useful? React with 👍 / 👎.

@PewterZz
PewterZz force-pushed the feat/google-vertex-provider branch from 9a4d659 to 36f9839 Compare April 10, 2026 17:17

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0f72b5396c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/google/index.ts Outdated
normalizeModelId: ({ modelId }) => normalizeGoogleModelId(modelId),
resolveDynamicModel: (ctx) =>
resolveGoogle31ForwardCompatModel({ providerId: "google-vertex", ctx }),
...GOOGLE_GEMINI_PROVIDER_HOOKS_WITH_TOOL_COMPAT,

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.

P1 Badge Import Vertex hook bundle before provider registration

This spread references GOOGLE_GEMINI_PROVIDER_HOOKS_WITH_TOOL_COMPAT, but that identifier is never defined or imported in this module. When register(api) runs, evaluating this object literal throws a ReferenceError, which aborts Google plugin registration and prevents the new Vertex provider from being registered at runtime. Please import the hook bundle (and the other newly referenced helpers below) before constructing this provider object.

Useful? React with 👍 / 👎.

@PewterZz
PewterZz force-pushed the feat/google-vertex-provider branch from 0f72b53 to d4f4595 Compare April 10, 2026 19:17

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4f4595451

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/google/index.ts Outdated
@@ -115,5 +133,73 @@ export default definePluginEntry({
api.registerMusicGenerationProvider(buildGoogleMusicGenerationProvider());
api.registerVideoGenerationProvider(buildGoogleVideoGenerationProvider());
api.registerWebSearchProvider(createGeminiWebSearchProvider());
api.registerProvider({
id: "google-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.

P2 Badge Prefer exact provider ownership for google-vertex hooks

Registering a real google-vertex provider here collides with the existing google hook alias (hookAliases: ["google-vertex"] in extensions/google/provider-registration.ts), and runtime hook resolution uses first-match semantics (resolveProviderRuntimePlugin(...).find(matchesProviderId)). In that ordering, google can claim google-vertex first, so this provider's custom hooks (especially formatApiKey and refreshOAuth) are skipped; in auth-profile flows that means the raw OAuth access token is used instead of the JSON Bearer payload expected by parseGeminiAuth, leading to malformed Vertex auth. Ensure exact provider-id matches win (or remove the legacy alias) when google-vertex is registered.

Useful? React with 👍 / 👎.

@clawsweeper

clawsweeper Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 3, 2026, 2:00 AM ET / 06:00 UTC.

Summary
The branch adds a separate Google Vertex provider path with ADC bearer auth, Vertex endpoint/catalog helpers, thought-signature replay handling, tests, and unrelated oc-path formatting churn.

PR surface: Source +661, Tests +289. Total +950 across 29 files.

Reproducibility: yes. at source level for the merge blockers: the PR head gates google-vertex transport on file-readable ADC and rejects external_account ADC, while current main routes to Vertex before request-time ADC probing and delegates production ADC modes to google-auth-library.

Review metrics: 2 noteworthy metrics.

  • Auth/provider surfaces: 1 provider registration added, 1 hook alias removed, 2 manifest marker entries added. These surfaces decide provider ownership and auth discovery for existing google-vertex users before request-time credentials are tested.
  • Unrelated non-Google churn: 16 files outside extensions/google changed. The extra oc-path and agent formatting edits add conflict and review cost without helping the Vertex behavior.

Stored data model
Persistent data-model change detected: serialized state: extensions/google/transport-stream.test.ts, serialized state: extensions/google/vertex-adc.test.ts, serialized state: extensions/google/vertex-adc.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #60736
Summary: This PR is an older broad candidate in the Google Vertex OAuth, ADC, endpoint-routing, catalog, and setup cluster; current main implements important transport/ADC pieces while open follow-ups still own setup and hardening paths.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🧂 unranked krab
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted exact-head Vertex request/response proof if this branch is revived.
  • Rebase and preserve current main's metadata-server and external_account ADC behavior.
  • Drop unrelated oc-path and agent formatting churn.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body claims a live run and comments provide workaround context, but there is no inspectable redacted exact-head terminal output, log, screenshot, recording, or linked artifact for this branch. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Merging this branch as-is can make valid GCE, GKE, and Cloud Run metadata-server ADC setups miss the Vertex transport because the PR head gates google-vertex on synchronous file-readable credentials.
  • [P1] Merging this branch as-is can regress external_account Workload Identity Federation ADC files that current main delegates to google-auth-library.
  • [P1] The branch changes provider ownership, hook aliases, manifest auth evidence, catalog/config behavior, and provider routing, so existing google-vertex configs and auth profiles need explicit upgrade review.
  • [P1] The branch includes unrelated oc-path and agent formatting churn, increasing conflict and review cost without advancing the Google Vertex fix.
  • [P1] The PR still lacks inspectable exact-head real behavior proof; the linked comments are useful workaround context but do not prove this branch after the current fixes.

Maintainer options:

  1. Split A Narrow Salvage (recommended)
    Rebase only any still-useful service-account or token-response handling onto current main, preserve metadata-server and external_account ADC, and drop unrelated oc-path churn before review.
  2. Use The Active Onboarding Path
    Keep fix(google-vertex): add Google Vertex AI onboarding wizard, fix ADC auth, add provider docs #87800 as the setup/onboarding candidate while this broad provider split remains paused.
  3. Retire After Pair Review
    A maintainer can close this PR once the paired issue and remaining canonical follow-up are explicitly resolved or superseded.

Next step before merge

  • [P1] Manual review is needed because the PR is paired with an open same-author canonical issue and overlaps both shipped fixes and an active follow-up PR; automation cannot decide whether to retire or salvage the provider split.

Security
Cleared: No concrete secret leak or supply-chain blocker was found; the blocking concerns are auth-provider compatibility, upgrade behavior, unrelated churn, and missing exact-head proof.

Review findings

  • [P1] Preserve metadata-server ADC for Vertex transport — extensions/google/provider-registration.ts:60-61
  • [P1] Keep external_account ADC support — extensions/google/vertex-adc.ts:182-185
Review details

Best possible solution:

Preserve current main's Google Vertex ADC and routing path, let #87800 and #60736 carry the remaining setup/product work, and only salvage this branch as a narrow rebased patch if maintainers still want a distinct provider split.

Do we have a high-confidence way to reproduce the issue?

Yes, at source level for the merge blockers: the PR head gates google-vertex transport on file-readable ADC and rejects external_account ADC, while current main routes to Vertex before request-time ADC probing and delegates production ADC modes to google-auth-library.

Is this the best way to solve the issue?

No. This broad branch is not the best current fix as-is; the maintainable path is a narrow current-main salvage of any unique work plus the active proof-supplied onboarding PR for setup behavior.

Full review comments:

  • [P1] Preserve metadata-server ADC for Vertex transport — extensions/google/provider-registration.ts:60-61
    This branch only returns the Vertex stream when hasGoogleVertexCredentials() can read a local ADC file, but current main wires the Vertex transport before ADC probing so GCE, GKE, and Cloud Run metadata-server ADC can resolve at request time. Merging this guard would make valid production ADC setups fall through before the working bearer-auth path can run.
    Confidence: 0.9
  • [P1] Keep external_account ADC support — extensions/google/vertex-adc.ts:182-185
    hasGoogleVertexCredentials() accepts any readable ADC file, but the token resolver then throws for external_account credentials. Current main delegates non-user ADC to google-auth-library, which supports external_account and service-account ADC, so this would break Workload Identity Federation setups that already have a supported request-time path.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.88

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against c5afa92c1f8a.

Label changes

Label justifications:

  • P2: This is a normal-priority Google Vertex provider/auth improvement with real user impact but provider-specific blast radius and active follow-up work.
  • merge-risk: 🚨 compatibility: The branch changes provider ownership, hook aliases, manifest auth evidence, generated catalog/config behavior, and unrelated extension files that existing users may rely on.
  • merge-risk: 🚨 auth-provider: The branch changes Google Vertex ADC bearer auth, credential marker handling, provider routing, model API selection, and API-key versus ADC behavior.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🧂 unranked krab.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body claims a live run and comments provide workaround context, but there is no inspectable redacted exact-head terminal output, log, screenshot, recording, or linked artifact for this branch. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +661, Tests +289. Total +950 across 29 files.

View PR surface stats
Area Files Added Removed Net
Source 21 1158 497 +661
Tests 8 395 106 +289
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 29 1553 603 +950

What I checked:

Likely related people:

  • damianFelixPago: Auth history shows this account authored the merged production ADC support that current main relies on for metadata-server, external_account, and service-account Vertex auth. (role: ADC feature contributor; confidence: high; commits: f09b4ebe314e; files: extensions/google/vertex-adc.ts, extensions/google/transport-stream.ts, extensions/google/provider-registration.ts)
  • 849261680: This account authored the merged fix that preserves Google Vertex ADC markers in generated catalog and model config paths. (role: catalog/auth marker contributor; confidence: high; commits: a4f7e4cbb946; files: extensions/google/provider-discovery.ts, src/agents/models-config.providers.implicit.ts, src/agents/models-config.providers.secret-helpers.ts)
  • shakkernerd: Commit history ties this account to the Google Vertex manifest auth-evidence metadata that current marker resolution builds on. (role: introduced auth-evidence behavior; confidence: medium; commits: dec5de8a2cda; files: extensions/google/openclaw.plugin.json, src/agents/model-auth-env.ts)
  • bymle: This account authored the merged provider-prefix routing fix in the Google Vertex request URL path adjacent to this PR's routing changes. (role: recent Vertex routing contributor; confidence: medium; commits: 22069bcc56b7; files: extensions/google/transport-stream.ts, extensions/google/transport-stream.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

PewterZz added 5 commits May 2, 2026 04:24
… routing

Registers a new google-vertex provider in the Google plugin that routes to
aiplatform.googleapis.com using Application Default Credentials (ADC). The
existing GCP_VERTEX_CREDENTIALS_MARKER and main's google-vertex auth-presence
check in src/agents/model-auth-env.ts are reused; no new core marker or
hard-coded provider branch is added.

Provider follows the anthropic-vertex pattern with resolveSyntheticAuth(),
manifest-declared nonSecretAuthMarkers, and an implicit catalog from
buildGoogleVertexProvider(). hookAliases:[google-vertex] is removed from
the Google AI Studio provider so the new provider's hooks own google-vertex
configs.

ADC token exchange supports both authorized_user (gcloud login) and
service_account (CI/CD JSON keys) types; unsupported ADC types throw a clear
error rather than silently falling through.

Vertex URL builder strips trailing /v1 from custom baseUrls, preserves
already-qualified model paths (publishers/.../, tunedModels/, projects/),
infers the location from the configured baseUrl when set, and fails fast
when no project ID is resolvable.

Closes openclaw#49039
Closes openclaw#56253
Closes openclaw#58775
Closes openclaw#60736
Adds vertex-adc.test.ts with coverage for: missing ADC file, authorized_user
refresh, service_account JWT-bearer minting, unsupported ADC type rejection,
token endpoint error surfacing, in-memory cache reuse, and env project
override over the ADC project_id.
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jun 19, 2026
@rboy1

rboy1 commented Jun 22, 2026

Copy link
Copy Markdown

Does openclaw support using the Vertex (Enterprise AI) Standard API (not AI Studio API) instead of ADC ? It used to work in versions <= 2026.5.20 but doesn't seem to work anymore with newer versions. Has something changed or is it just not supported anymore?

@clawsweeper clawsweeper Bot removed the merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. label Jun 23, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence. label Jun 23, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. proof: sufficient ClawSweeper judged the real behavior proof convincing. labels Jun 23, 2026
@steipete

Copy link
Copy Markdown
Contributor

Thanks @PewterZz — this was valuable work when opened, but current main now contains same-or-better Vertex support through #83971, #90609, and the landed catalog, routing, and thought-signature fixes. This branch would regress metadata-server and Workload Identity Federation ADC support, carries unrelated oc-path churn, and uses retired catalog defaults.

Remaining onboarding and docs work stays tracked in #60736 and #87800. Closing this superseded implementation; thank you for pushing the Vertex path forward.

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

Labels

agents Agent runtime and tooling extensions: google extensions: oc-path merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-pr-context Candidate: external PR body lacks required problem context or evidence.

Projects

None yet

4 participants