From ad30100a2d0f2d3d913fd7addf5bff997f57bd5f Mon Sep 17 00:00:00 2001 From: YEONJAE SUNG Date: Wed, 10 Dec 2025 10:44:29 +0900 Subject: [PATCH] fix(vertexai): correct URL construction for global endpoint When location is set to 'global', the plugin was incorrectly constructing the URL as https://global-aiplatform.googleapis.com, which results in 404. The correct URL for global endpoint should be https://aiplatform.googleapis.com without the location prefix. This fix applies to: - list-models.ts: Model listing endpoint - upsert_datapoints.ts: Vector search datapoint upsert endpoint - predict.ts: Prediction endpoint - evaluation/evaluator_factory.ts: Evaluation service endpoint - modelgarden/v2/llama.ts: Llama model garden endpoint Implementation uses a ternary operator for optimal performance and follows the same pattern as Google's official Gen AI SDK. Fixes #3651 --- js/plugins/vertexai/src/evaluation/evaluator_factory.ts | 6 +++++- js/plugins/vertexai/src/list-models.ts | 8 +++++++- js/plugins/vertexai/src/modelgarden/v2/llama.ts | 9 ++++++--- js/plugins/vertexai/src/predict.ts | 5 ++++- .../src/vectorsearch/vector_search/upsert_datapoints.ts | 6 +++++- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/js/plugins/vertexai/src/evaluation/evaluator_factory.ts b/js/plugins/vertexai/src/evaluation/evaluator_factory.ts index de0c0c939e..2ae508cb90 100644 --- a/js/plugins/vertexai/src/evaluation/evaluator_factory.ts +++ b/js/plugins/vertexai/src/evaluation/evaluator_factory.ts @@ -82,7 +82,11 @@ export class EvaluatorFactory { metadata.input = request; const client = await this.auth.getClient(); - const url = `https://${this.location}-aiplatform.googleapis.com/v1beta1/${locationName}:evaluateInstances`; + const baseUrl = this.location === 'global' + ? 'https://aiplatform.googleapis.com' + : `https://${this.location}-aiplatform.googleapis.com`; + + const url = `${baseUrl}/v1beta1/${locationName}:evaluateInstances`; const response = await client.request({ url, method: 'POST', diff --git a/js/plugins/vertexai/src/list-models.ts b/js/plugins/vertexai/src/list-models.ts index 0a51c7ff10..40e3e6ee8e 100644 --- a/js/plugins/vertexai/src/list-models.ts +++ b/js/plugins/vertexai/src/list-models.ts @@ -38,8 +38,14 @@ export async function listModels( ): Promise { const fetch = (await import('node-fetch')).default; const accessToken = await authClient.getAccessToken(); + + // Global endpoint uses base URL without location prefix + const baseUrl = location === 'global' + ? 'https://aiplatform.googleapis.com' + : `https://${location}-aiplatform.googleapis.com`; + const response = await fetch( - `https://${location}-aiplatform.googleapis.com/v1beta1/publishers/google/models`, + `${baseUrl}/v1beta1/publishers/google/models`, { method: 'GET', headers: { diff --git a/js/plugins/vertexai/src/modelgarden/v2/llama.ts b/js/plugins/vertexai/src/modelgarden/v2/llama.ts index 3893266f45..9dca445afa 100644 --- a/js/plugins/vertexai/src/modelgarden/v2/llama.ts +++ b/js/plugins/vertexai/src/modelgarden/v2/llama.ts @@ -146,10 +146,13 @@ async function resolveOptions( clientOptions: ClientOptions, requestConfig?: LlamaConfig ) { - const baseUrlTemplate = - clientOptions.baseUrlTemplate ?? - 'https://{location}-aiplatform.googleapis.com/v1/projects/{projectId}/locations/{location}/endpoints/openapi'; const location = requestConfig?.location || clientOptions.location; + const defaultTemplate = location === 'global' + ? 'https://aiplatform.googleapis.com/v1/projects/{projectId}/locations/{location}/endpoints/openapi' + : 'https://{location}-aiplatform.googleapis.com/v1/projects/{projectId}/locations/{location}/endpoints/openapi'; + + const baseUrlTemplate = clientOptions.baseUrlTemplate ?? defaultTemplate; + const baseURL = baseUrlTemplate .replace(/{location}/g, location) .replace(/{projectId}/g, clientOptions.projectId); diff --git a/js/plugins/vertexai/src/predict.ts b/js/plugins/vertexai/src/predict.ts index e7e932c1c0..77d26b6e5b 100644 --- a/js/plugins/vertexai/src/predict.ts +++ b/js/plugins/vertexai/src/predict.ts @@ -23,8 +23,11 @@ function endpoint(options: { location: string; model: string; }) { + const baseUrl = options.location === 'global' + ? 'https://aiplatform.googleapis.com' + : `https://${options.location}-aiplatform.googleapis.com`; return ( - `https://${options.location}-aiplatform.googleapis.com/v1/` + + `${baseUrl}/v1/` + `projects/${options.projectId}/locations/${options.location}/` + `publishers/google/models/${options.model}:predict` ); diff --git a/js/plugins/vertexai/src/vectorsearch/vector_search/upsert_datapoints.ts b/js/plugins/vertexai/src/vectorsearch/vector_search/upsert_datapoints.ts index 6e6245df59..b752d1c2e2 100644 --- a/js/plugins/vertexai/src/vectorsearch/vector_search/upsert_datapoints.ts +++ b/js/plugins/vertexai/src/vectorsearch/vector_search/upsert_datapoints.ts @@ -45,7 +45,11 @@ export async function upsertDatapoints( ): Promise { const { datapoints, authClient, projectId, location, indexId } = params; const accessToken = await authClient.getAccessToken(); - const url = `https://${location}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${location}/indexes/${indexId}:upsertDatapoints`; + const baseUrl = location === 'global' + ? 'https://aiplatform.googleapis.com' + : `https://${location}-aiplatform.googleapis.com`; + + const url = `${baseUrl}/v1/projects/${projectId}/locations/${location}/indexes/${indexId}:upsertDatapoints`; const requestBody = { datapoints: datapoints.map((dp) => {