From 00280b5e81c5fc78b97d1ff020105f2434c0e211 Mon Sep 17 00:00:00 2001 From: Guiners Date: Fri, 22 Aug 2025 11:40:33 +0200 Subject: [PATCH 01/14] adding samples, test, lints --- .../batchpredict-embeddings-with-gcs.js | 82 +++++++++++++++++++ .../batch-prediction/batchpredict-with-bq.js | 79 ++++++++++++++++++ .../batch-prediction/batchpredict-with-gcs.js | 80 ++++++++++++++++++ genai/package.json | 2 + .../batchpredict-embeddings-with-gcs.test.js | 56 +++++++++++++ genai/test/batchpredict-with-bq.test.js | 54 ++++++++++++ genai/test/batchpredict-with-gcs.test.js | 56 +++++++++++++ 7 files changed, 409 insertions(+) create mode 100644 genai/batch-prediction/batchpredict-embeddings-with-gcs.js create mode 100644 genai/batch-prediction/batchpredict-with-bq.js create mode 100644 genai/batch-prediction/batchpredict-with-gcs.js create mode 100644 genai/test/batchpredict-embeddings-with-gcs.test.js create mode 100644 genai/test/batchpredict-with-bq.test.js create mode 100644 genai/test/batchpredict-with-gcs.test.js diff --git a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js new file mode 100644 index 0000000000..804512982e --- /dev/null +++ b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js @@ -0,0 +1,82 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START googlegenaisdk_batchpredict_embeddings_with_gcs] +const {GoogleGenAI} = require('@google/genai'); + +const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; +const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const OUTPUT_URI = 'gs://your-bucket/your-prefix'; + +async function generateContent( + outputUri = OUTPUT_URI, + projectId = GOOGLE_CLOUD_PROJECT, + location = GOOGLE_CLOUD_LOCATION +) { + const ai = new GoogleGenAI({ + vertexai: true, + project: projectId, + location: location, + httpOptions: { + apiVersion: 'v1', + }, + }); + + // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create + let job = await ai.batches.create({ + model: 'text-embedding-005', + // Source link: https://storage.cloud.google.com/cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl + src: 'gs://cloud-samples-data/generative-ai/embeddings/embeddings_input.jsonl', + config: { + dest: outputUri, + }, + }); + + console.log(`Job name: ${job.name}`); + console.log(`Job state: ${job.state}`); + // Example response: + // Job name: projects/%PROJECT_ID%/locations/us-central1/batchPredictionJobs/9876453210000000000 + // Job state: JOB_STATE_PENDING + + const completedStates = new Set([ + 'JOB_STATE_SUCCEEDED', + 'JOB_STATE_FAILED', + 'JOB_STATE_CANCELLED', + 'JOB_STATE_PAUSED', + ]); + + while (completedStates.has(job.state)) { + await new Promise(resolve => setTimeout(resolve, 30000)); + job = await ai.batches.get({name: job.name}); + console.log(`Job state: ${job.state}`); + if (job.state === 'JOB_STATE_FAILED') { + console.log(`Job state: ${job.state}`); + break; + } + } + // Example response: + // Job state: JOB_STATE_PENDING + // Job state: JOB_STATE_RUNNING + // Job state: JOB_STATE_RUNNING + // ... + // Job state: JOB_STATE_SUCCEEDED + return job.state; +} +// [END googlegenaisdk_batchpredict_embeddings_with_gcs] + +module.exports = { + generateContent, +}; diff --git a/genai/batch-prediction/batchpredict-with-bq.js b/genai/batch-prediction/batchpredict-with-bq.js new file mode 100644 index 0000000000..0aeaa32eef --- /dev/null +++ b/genai/batch-prediction/batchpredict-with-bq.js @@ -0,0 +1,79 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START googlegenaisdk_batchpredict_with_gcs] +const {GoogleGenAI} = require('@google/genai'); + +const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; +const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const OUTPUT_URI = 'bq://your-project.your_dataset.your_table'; + +async function generateContent( + outputUri = OUTPUT_URI, + projectId = GOOGLE_CLOUD_PROJECT, + location = GOOGLE_CLOUD_LOCATION +) { + const ai = new GoogleGenAI({ + vertexai: true, + project: projectId, + location: location, + httpOptions: { + apiVersion: 'v1', + }, + }); + + // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create + let job = await ai.batches.create({ + // To use a tuned model, set the model param to your tuned model using the following format: + // model="projects/{PROJECT_ID}/locations/{LOCATION}/models/{MODEL_ID}" + model: 'gemini-2.5-flash', + src: 'bq://storage-samples.generative_ai.batch_requests_for_multimodal_input', + config: { + dest: outputUri, + }, + }); + + console.log(`Job name: ${job.name}`); + console.log(`Job state: ${job.state}`); + // Example response: + // Job name: projects/%PROJECT_ID%/locations/us-central1/batchPredictionJobs/9876453210000000000 + // Job state: JOB_STATE_PENDING + + const completedStates = new Set([ + 'JOB_STATE_SUCCEEDED', + 'JOB_STATE_FAILED', + 'JOB_STATE_CANCELLED', + 'JOB_STATE_PAUSED', + ]); + + while (completedStates.has(job.state)) { + await new Promise(resolve => setTimeout(resolve, 30000)); + job = await ai.batches.get({name: job.name}); + console.log(`Job state: ${job.state}`); + } + // Example response: + // Job state: JOB_STATE_PENDING + // Job state: JOB_STATE_RUNNING + // Job state: JOB_STATE_RUNNING + // ... + // Job state: JOB_STATE_SUCCEEDED + return job.state; +} +// [END googlegenaisdk_batchpredict_with_gcs] + +module.exports = { + generateContent, +}; diff --git a/genai/batch-prediction/batchpredict-with-gcs.js b/genai/batch-prediction/batchpredict-with-gcs.js new file mode 100644 index 0000000000..b13eab3c86 --- /dev/null +++ b/genai/batch-prediction/batchpredict-with-gcs.js @@ -0,0 +1,80 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +// [START googlegenaisdk_batchpredict_with_gcs] +const {GoogleGenAI} = require('@google/genai'); + +const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; +const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const OUTPUT_URI = 'gs://your-bucket/your-prefix'; + +async function generateContent( + outputUri = OUTPUT_URI, + projectId = GOOGLE_CLOUD_PROJECT, + location = GOOGLE_CLOUD_LOCATION +) { + const ai = new GoogleGenAI({ + vertexai: true, + project: projectId, + location: location, + httpOptions: { + apiVersion: 'v1', + }, + }); + + // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create + let job = await ai.batches.create({ + // To use a tuned model, set the model param to your tuned model using the following format: + // model="projects/{PROJECT_ID}/locations/{LOCATION}/models/{MODEL_ID}" + model: 'gemini-2.5-flash', + // Source link: https://storage.cloud.google.com/cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl + src: 'gs://cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl', + config: { + dest: outputUri, + }, + }); + + console.log(`Job name: ${job.name}`); + console.log(`Job state: ${job.state}`); + // Example response: + // Job name: projects/%PROJECT_ID%/locations/us-central1/batchPredictionJobs/9876453210000000000 + // Job state: JOB_STATE_PENDING + + const completedStates = new Set([ + 'JOB_STATE_SUCCEEDED', + 'JOB_STATE_FAILED', + 'JOB_STATE_CANCELLED', + 'JOB_STATE_PAUSED', + ]); + + while (completedStates.has(job.state)) { + await new Promise(resolve => setTimeout(resolve, 30000)); + job = await ai.batches.get({name: job.name}); + console.log(`Job state: ${job.state}`); + } + // Example response: + // Job state: JOB_STATE_PENDING + // Job state: JOB_STATE_RUNNING + // Job state: JOB_STATE_RUNNING + // ... + // Job state: JOB_STATE_SUCCEEDED + return job.state; +} +// [END googlegenaisdk_batchpredict_with_gcs] + +module.exports = { + generateContent, +}; diff --git a/genai/package.json b/genai/package.json index 1f23438fc3..d654380e4e 100644 --- a/genai/package.json +++ b/genai/package.json @@ -13,6 +13,8 @@ "test": "c8 mocha -p -j 2 --timeout 2400000 test/*.test.js test/**/*.test.js" }, "dependencies": { + "@google-cloud/bigquery": "^8.1.1", + "@google-cloud/storage": "^7.17.0", "@google/genai": "1.12.0", "axios": "^1.6.2", "supertest": "^7.0.0" diff --git a/genai/test/batchpredict-embeddings-with-gcs.test.js b/genai/test/batchpredict-embeddings-with-gcs.test.js new file mode 100644 index 0000000000..f1e30c2401 --- /dev/null +++ b/genai/test/batchpredict-embeddings-with-gcs.test.js @@ -0,0 +1,56 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it} = require('mocha'); +const { Storage } = require("@google-cloud/storage"); + +const storage = new Storage(); + +const GCS_OUTPUT_BUCKET = 'nodejs-docs-samples-tests'; + +const projectId = process.env.CAIP_PROJECT_ID; +const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const sample = require('../batch-prediction/batchpredict-embeddings-with-gcs'); + +async function gcs_output_uri() { + const dt = new Date(); + const prefix = `text_output/${dt.toISOString()}`; + const fullUri = `gs://${GCS_OUTPUT_BUCKET}/${prefix}`; + + return { + uri: fullUri, + async cleanup() { + const [files] = await storage.bucket(GCS_OUTPUT_BUCKET).getFiles({ + prefix, + }); + for (const file of files) { + await file.delete(); + } + }, + }; +} + + +describe('batchpredict-embeddings-with-gcs', () => { + it('should return the batch job state', async function () { + this.timeout(50000); + const gscOutput = gcs_output_uri() + const gscUri = (await gscOutput).uri + const output = await sample.generateContent(gscUri, projectId, location); + assert.notEqual(output, undefined); + }); +}); diff --git a/genai/test/batchpredict-with-bq.test.js b/genai/test/batchpredict-with-bq.test.js new file mode 100644 index 0000000000..ba76f1df59 --- /dev/null +++ b/genai/test/batchpredict-with-bq.test.js @@ -0,0 +1,54 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it} = require('mocha'); +const { BigQuery } = require("@google-cloud/bigquery"); + +const bigquery = new BigQuery(); + +const BQ_OUTPUT_DATASET = `${process.env.BQ_OUTPUT_DATASET}.gen_ai_batch_prediction`; + +const projectId = process.env.CAIP_PROJECT_ID; +const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const sample = require('../batch-prediction/batchpredict-with-bq'); + + +async function bq_output_uri() { + const dt = new Date(); + const tableName = `text_output_${dt.getFullYear()}_${dt.getMonth() + 1}_${dt.getDate()}_T${dt.getHours()}_${dt.getMinutes()}_${dt.getSeconds()}`; + const tableUri = `${BQ_OUTPUT_DATASET}.${tableName}`; + const fullUri = `bq://${tableUri}`; + + return { + uri: fullUri, + async cleanup() { + await bigquery.dataset(BQ_OUTPUT_DATASET).table(tableName).delete({ + ignoreNotFound: true, + }); + }, + }; +} + +describe('batchpredict-with-bq', () => { + it('should return the batch job state', async function () { + this.timeout(50000); + const bqOutput = bq_output_uri() + const bqUri = (await bqOutput).uri + const output = await sample.generateContent(bqUri, projectId, location); + assert.notEqual(output, undefined); + }); +}); diff --git a/genai/test/batchpredict-with-gcs.test.js b/genai/test/batchpredict-with-gcs.test.js new file mode 100644 index 0000000000..19810e0c64 --- /dev/null +++ b/genai/test/batchpredict-with-gcs.test.js @@ -0,0 +1,56 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +'use strict'; + +const {assert} = require('chai'); +const {describe, it} = require('mocha'); +const { Storage } = require("@google-cloud/storage"); + +const storage = new Storage(); + +const GCS_OUTPUT_BUCKET = 'nodejs-docs-samples-tests'; + +const projectId = process.env.CAIP_PROJECT_ID; +const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const sample = require('../batch-prediction/batchpredict-with-gcs'); + +async function gcs_output_uri() { + const dt = new Date(); + const prefix = `text_output/${dt.toISOString()}`; + const fullUri = `gs://${GCS_OUTPUT_BUCKET}/${prefix}`; + + return { + uri: fullUri, + async cleanup() { + const [files] = await storage.bucket(GCS_OUTPUT_BUCKET).getFiles({ + prefix, + }); + for (const file of files) { + await file.delete(); + } + }, + }; +} + + +describe('batchpredict-with-gcs', () => { + it('should return the batch job state', async function () { + this.timeout(50000); + const gscOutput = gcs_output_uri() + const gscUri = (await gscOutput).uri + const output = await sample.generateContent(gscUri, projectId, location); + assert.notEqual(output, undefined); + }); +}); From e06efd152f47a759624d6516e29045ecc5f3b87d Mon Sep 17 00:00:00 2001 From: Guiners Date: Fri, 22 Aug 2025 11:40:57 +0200 Subject: [PATCH 02/14] adding samples, test, lints --- genai/test/batchpredict-embeddings-with-gcs.test.js | 7 +++---- genai/test/batchpredict-with-bq.test.js | 7 +++---- genai/test/batchpredict-with-gcs.test.js | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/genai/test/batchpredict-embeddings-with-gcs.test.js b/genai/test/batchpredict-embeddings-with-gcs.test.js index f1e30c2401..80ddc9f3d8 100644 --- a/genai/test/batchpredict-embeddings-with-gcs.test.js +++ b/genai/test/batchpredict-embeddings-with-gcs.test.js @@ -16,7 +16,7 @@ const {assert} = require('chai'); const {describe, it} = require('mocha'); -const { Storage } = require("@google-cloud/storage"); +const {Storage} = require('@google-cloud/storage'); const storage = new Storage(); @@ -44,12 +44,11 @@ async function gcs_output_uri() { }; } - describe('batchpredict-embeddings-with-gcs', () => { it('should return the batch job state', async function () { this.timeout(50000); - const gscOutput = gcs_output_uri() - const gscUri = (await gscOutput).uri + const gscOutput = gcs_output_uri(); + const gscUri = (await gscOutput).uri; const output = await sample.generateContent(gscUri, projectId, location); assert.notEqual(output, undefined); }); diff --git a/genai/test/batchpredict-with-bq.test.js b/genai/test/batchpredict-with-bq.test.js index ba76f1df59..6acaa690c6 100644 --- a/genai/test/batchpredict-with-bq.test.js +++ b/genai/test/batchpredict-with-bq.test.js @@ -16,7 +16,7 @@ const {assert} = require('chai'); const {describe, it} = require('mocha'); -const { BigQuery } = require("@google-cloud/bigquery"); +const {BigQuery} = require('@google-cloud/bigquery'); const bigquery = new BigQuery(); @@ -26,7 +26,6 @@ const projectId = process.env.CAIP_PROJECT_ID; const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; const sample = require('../batch-prediction/batchpredict-with-bq'); - async function bq_output_uri() { const dt = new Date(); const tableName = `text_output_${dt.getFullYear()}_${dt.getMonth() + 1}_${dt.getDate()}_T${dt.getHours()}_${dt.getMinutes()}_${dt.getSeconds()}`; @@ -46,8 +45,8 @@ async function bq_output_uri() { describe('batchpredict-with-bq', () => { it('should return the batch job state', async function () { this.timeout(50000); - const bqOutput = bq_output_uri() - const bqUri = (await bqOutput).uri + const bqOutput = bq_output_uri(); + const bqUri = (await bqOutput).uri; const output = await sample.generateContent(bqUri, projectId, location); assert.notEqual(output, undefined); }); diff --git a/genai/test/batchpredict-with-gcs.test.js b/genai/test/batchpredict-with-gcs.test.js index 19810e0c64..edbad41f8c 100644 --- a/genai/test/batchpredict-with-gcs.test.js +++ b/genai/test/batchpredict-with-gcs.test.js @@ -16,7 +16,7 @@ const {assert} = require('chai'); const {describe, it} = require('mocha'); -const { Storage } = require("@google-cloud/storage"); +const {Storage} = require('@google-cloud/storage'); const storage = new Storage(); @@ -44,12 +44,11 @@ async function gcs_output_uri() { }; } - describe('batchpredict-with-gcs', () => { it('should return the batch job state', async function () { this.timeout(50000); - const gscOutput = gcs_output_uri() - const gscUri = (await gscOutput).uri + const gscOutput = gcs_output_uri(); + const gscUri = (await gscOutput).uri; const output = await sample.generateContent(gscUri, projectId, location); assert.notEqual(output, undefined); }); From 79fcf8e2fb90757bfa465a57d4742ff7d9495a29 Mon Sep 17 00:00:00 2001 From: Guiners Date: Thu, 4 Sep 2025 11:32:15 +0200 Subject: [PATCH 03/14] adding samples, test, lints --- genai/batch-prediction/batchpredict-embeddings-with-gcs.js | 3 +++ genai/batch-prediction/batchpredict-with-bq.js | 3 +++ genai/batch-prediction/batchpredict-with-gcs.js | 3 +++ 3 files changed, 9 insertions(+) diff --git a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js index 804512982e..60d0388c23 100644 --- a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js +++ b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js @@ -47,6 +47,7 @@ async function generateContent( console.log(`Job name: ${job.name}`); console.log(`Job state: ${job.state}`); + // Example response: // Job name: projects/%PROJECT_ID%/locations/us-central1/batchPredictionJobs/9876453210000000000 // Job state: JOB_STATE_PENDING @@ -67,12 +68,14 @@ async function generateContent( break; } } + // Example response: // Job state: JOB_STATE_PENDING // Job state: JOB_STATE_RUNNING // Job state: JOB_STATE_RUNNING // ... // Job state: JOB_STATE_SUCCEEDED + return job.state; } // [END googlegenaisdk_batchpredict_embeddings_with_gcs] diff --git a/genai/batch-prediction/batchpredict-with-bq.js b/genai/batch-prediction/batchpredict-with-bq.js index 0aeaa32eef..9267cee447 100644 --- a/genai/batch-prediction/batchpredict-with-bq.js +++ b/genai/batch-prediction/batchpredict-with-bq.js @@ -48,6 +48,7 @@ async function generateContent( console.log(`Job name: ${job.name}`); console.log(`Job state: ${job.state}`); + // Example response: // Job name: projects/%PROJECT_ID%/locations/us-central1/batchPredictionJobs/9876453210000000000 // Job state: JOB_STATE_PENDING @@ -64,12 +65,14 @@ async function generateContent( job = await ai.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); } + // Example response: // Job state: JOB_STATE_PENDING // Job state: JOB_STATE_RUNNING // Job state: JOB_STATE_RUNNING // ... // Job state: JOB_STATE_SUCCEEDED + return job.state; } // [END googlegenaisdk_batchpredict_with_gcs] diff --git a/genai/batch-prediction/batchpredict-with-gcs.js b/genai/batch-prediction/batchpredict-with-gcs.js index b13eab3c86..6f8dc6d9e9 100644 --- a/genai/batch-prediction/batchpredict-with-gcs.js +++ b/genai/batch-prediction/batchpredict-with-gcs.js @@ -49,6 +49,7 @@ async function generateContent( console.log(`Job name: ${job.name}`); console.log(`Job state: ${job.state}`); + // Example response: // Job name: projects/%PROJECT_ID%/locations/us-central1/batchPredictionJobs/9876453210000000000 // Job state: JOB_STATE_PENDING @@ -65,12 +66,14 @@ async function generateContent( job = await ai.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); } + // Example response: // Job state: JOB_STATE_PENDING // Job state: JOB_STATE_RUNNING // Job state: JOB_STATE_RUNNING // ... // Job state: JOB_STATE_SUCCEEDED + return job.state; } // [END googlegenaisdk_batchpredict_with_gcs] From 6f885a4bd78bd410313d93dd794cd70bdc2abfb3 Mon Sep 17 00:00:00 2001 From: Guiners Date: Wed, 10 Sep 2025 12:34:10 +0200 Subject: [PATCH 04/14] fixing functions names --- .../batchpredict-embeddings-with-gcs.js | 10 +++++----- genai/batch-prediction/batchpredict-with-bq.js | 10 +++++----- genai/batch-prediction/batchpredict-with-gcs.js | 10 +++++----- genai/test/batchpredict-embeddings-with-gcs.test.js | 6 +++++- genai/test/batchpredict-with-bq.test.js | 6 +++++- genai/test/batchpredict-with-gcs.test.js | 6 +++++- 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js index 60d0388c23..161bcd7247 100644 --- a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js +++ b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js @@ -21,12 +21,12 @@ const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; const OUTPUT_URI = 'gs://your-bucket/your-prefix'; -async function generateContent( +async function runBatchPredictionJob( outputUri = OUTPUT_URI, projectId = GOOGLE_CLOUD_PROJECT, location = GOOGLE_CLOUD_LOCATION ) { - const ai = new GoogleGenAI({ + const client = new GoogleGenAI({ vertexai: true, project: projectId, location: location, @@ -36,7 +36,7 @@ async function generateContent( }); // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create - let job = await ai.batches.create({ + let job = await client.batches.create({ model: 'text-embedding-005', // Source link: https://storage.cloud.google.com/cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl src: 'gs://cloud-samples-data/generative-ai/embeddings/embeddings_input.jsonl', @@ -61,7 +61,7 @@ async function generateContent( while (completedStates.has(job.state)) { await new Promise(resolve => setTimeout(resolve, 30000)); - job = await ai.batches.get({name: job.name}); + job = await client.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); if (job.state === 'JOB_STATE_FAILED') { console.log(`Job state: ${job.state}`); @@ -81,5 +81,5 @@ async function generateContent( // [END googlegenaisdk_batchpredict_embeddings_with_gcs] module.exports = { - generateContent, + runBatchPredictionJob, }; diff --git a/genai/batch-prediction/batchpredict-with-bq.js b/genai/batch-prediction/batchpredict-with-bq.js index 9267cee447..974b6e6e2f 100644 --- a/genai/batch-prediction/batchpredict-with-bq.js +++ b/genai/batch-prediction/batchpredict-with-bq.js @@ -21,12 +21,12 @@ const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; const OUTPUT_URI = 'bq://your-project.your_dataset.your_table'; -async function generateContent( +async function runBatchPredictionJob( outputUri = OUTPUT_URI, projectId = GOOGLE_CLOUD_PROJECT, location = GOOGLE_CLOUD_LOCATION ) { - const ai = new GoogleGenAI({ + const client = new GoogleGenAI({ vertexai: true, project: projectId, location: location, @@ -36,7 +36,7 @@ async function generateContent( }); // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create - let job = await ai.batches.create({ + let job = await client.batches.create({ // To use a tuned model, set the model param to your tuned model using the following format: // model="projects/{PROJECT_ID}/locations/{LOCATION}/models/{MODEL_ID}" model: 'gemini-2.5-flash', @@ -62,7 +62,7 @@ async function generateContent( while (completedStates.has(job.state)) { await new Promise(resolve => setTimeout(resolve, 30000)); - job = await ai.batches.get({name: job.name}); + job = await client.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); } @@ -78,5 +78,5 @@ async function generateContent( // [END googlegenaisdk_batchpredict_with_gcs] module.exports = { - generateContent, + runBatchPredictionJob, }; diff --git a/genai/batch-prediction/batchpredict-with-gcs.js b/genai/batch-prediction/batchpredict-with-gcs.js index 6f8dc6d9e9..c364d6ef46 100644 --- a/genai/batch-prediction/batchpredict-with-gcs.js +++ b/genai/batch-prediction/batchpredict-with-gcs.js @@ -21,12 +21,12 @@ const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; const OUTPUT_URI = 'gs://your-bucket/your-prefix'; -async function generateContent( +async function runBatchPredictionJob( outputUri = OUTPUT_URI, projectId = GOOGLE_CLOUD_PROJECT, location = GOOGLE_CLOUD_LOCATION ) { - const ai = new GoogleGenAI({ + const client = new GoogleGenAI({ vertexai: true, project: projectId, location: location, @@ -36,7 +36,7 @@ async function generateContent( }); // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create - let job = await ai.batches.create({ + let job = await client.batches.create({ // To use a tuned model, set the model param to your tuned model using the following format: // model="projects/{PROJECT_ID}/locations/{LOCATION}/models/{MODEL_ID}" model: 'gemini-2.5-flash', @@ -63,7 +63,7 @@ async function generateContent( while (completedStates.has(job.state)) { await new Promise(resolve => setTimeout(resolve, 30000)); - job = await ai.batches.get({name: job.name}); + job = await client.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); } @@ -79,5 +79,5 @@ async function generateContent( // [END googlegenaisdk_batchpredict_with_gcs] module.exports = { - generateContent, + runBatchPredictionJob, }; diff --git a/genai/test/batchpredict-embeddings-with-gcs.test.js b/genai/test/batchpredict-embeddings-with-gcs.test.js index 80ddc9f3d8..48e092b240 100644 --- a/genai/test/batchpredict-embeddings-with-gcs.test.js +++ b/genai/test/batchpredict-embeddings-with-gcs.test.js @@ -49,7 +49,11 @@ describe('batchpredict-embeddings-with-gcs', () => { this.timeout(50000); const gscOutput = gcs_output_uri(); const gscUri = (await gscOutput).uri; - const output = await sample.generateContent(gscUri, projectId, location); + const output = await sample.runBatchPredictionJob( + gscUri, + projectId, + location + ); assert.notEqual(output, undefined); }); }); diff --git a/genai/test/batchpredict-with-bq.test.js b/genai/test/batchpredict-with-bq.test.js index 6acaa690c6..420e7365a4 100644 --- a/genai/test/batchpredict-with-bq.test.js +++ b/genai/test/batchpredict-with-bq.test.js @@ -47,7 +47,11 @@ describe('batchpredict-with-bq', () => { this.timeout(50000); const bqOutput = bq_output_uri(); const bqUri = (await bqOutput).uri; - const output = await sample.generateContent(bqUri, projectId, location); + const output = await sample.runBatchPredictionJob( + bqUri, + projectId, + location + ); assert.notEqual(output, undefined); }); }); diff --git a/genai/test/batchpredict-with-gcs.test.js b/genai/test/batchpredict-with-gcs.test.js index edbad41f8c..76992bd643 100644 --- a/genai/test/batchpredict-with-gcs.test.js +++ b/genai/test/batchpredict-with-gcs.test.js @@ -49,7 +49,11 @@ describe('batchpredict-with-gcs', () => { this.timeout(50000); const gscOutput = gcs_output_uri(); const gscUri = (await gscOutput).uri; - const output = await sample.generateContent(gscUri, projectId, location); + const output = await sample.runBatchPredictionJob( + gscUri, + projectId, + location + ); assert.notEqual(output, undefined); }); }); From 8e72ad8f3b0fca4b19a782a883818b46e1270baf Mon Sep 17 00:00:00 2001 From: Robert Kozak <50328216+Guiners@users.noreply.github.com> Date: Fri, 12 Sep 2025 19:04:48 +0200 Subject: [PATCH 05/14] Update genai/batch-prediction/batchpredict-with-bq.js Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- genai/batch-prediction/batchpredict-with-bq.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genai/batch-prediction/batchpredict-with-bq.js b/genai/batch-prediction/batchpredict-with-bq.js index 974b6e6e2f..7b0954e203 100644 --- a/genai/batch-prediction/batchpredict-with-bq.js +++ b/genai/batch-prediction/batchpredict-with-bq.js @@ -14,7 +14,7 @@ 'use strict'; -// [START googlegenaisdk_batchpredict_with_gcs] +// [START googlegenaisdk_batchpredict_with_bq] const {GoogleGenAI} = require('@google/genai'); const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; From 9e267972cb574da33f90b6b87f00b42ceb449e61 Mon Sep 17 00:00:00 2001 From: Robert Kozak <50328216+Guiners@users.noreply.github.com> Date: Fri, 12 Sep 2025 19:05:02 +0200 Subject: [PATCH 06/14] Update genai/batch-prediction/batchpredict-with-bq.js Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- genai/batch-prediction/batchpredict-with-bq.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genai/batch-prediction/batchpredict-with-bq.js b/genai/batch-prediction/batchpredict-with-bq.js index 7b0954e203..9ae9b96307 100644 --- a/genai/batch-prediction/batchpredict-with-bq.js +++ b/genai/batch-prediction/batchpredict-with-bq.js @@ -75,7 +75,7 @@ async function runBatchPredictionJob( return job.state; } -// [END googlegenaisdk_batchpredict_with_gcs] +// [END googlegenaisdk_batchpredict_with_bq] module.exports = { runBatchPredictionJob, From 563fd3611d9f7ce6b5e6f2a046950b2949216d61 Mon Sep 17 00:00:00 2001 From: Guiners Date: Mon, 22 Sep 2025 11:12:01 +0200 Subject: [PATCH 07/14] code review fixes --- .../batchpredict-embeddings-with-gcs.js | 2 +- .../batchpredict-embeddings-with-gcs.test.js | 6 +++--- genai/test/batchpredict-with-bq.test.js | 21 +++++++++++-------- genai/test/batchpredict-with-gcs.test.js | 4 ++-- package.json | 1 + 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js index 161bcd7247..2589773833 100644 --- a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js +++ b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js @@ -64,7 +64,7 @@ async function runBatchPredictionJob( job = await client.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); if (job.state === 'JOB_STATE_FAILED') { - console.log(`Job state: ${job.state}`); + console.log(`Error: ${job.state}`); break; } } diff --git a/genai/test/batchpredict-embeddings-with-gcs.test.js b/genai/test/batchpredict-embeddings-with-gcs.test.js index 48e092b240..b77deb14e2 100644 --- a/genai/test/batchpredict-embeddings-with-gcs.test.js +++ b/genai/test/batchpredict-embeddings-with-gcs.test.js @@ -26,7 +26,7 @@ const projectId = process.env.CAIP_PROJECT_ID; const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; const sample = require('../batch-prediction/batchpredict-embeddings-with-gcs'); -async function gcs_output_uri() { +async function getGcsOutputUri() { const dt = new Date(); const prefix = `text_output/${dt.toISOString()}`; const fullUri = `gs://${GCS_OUTPUT_BUCKET}/${prefix}`; @@ -44,10 +44,10 @@ async function gcs_output_uri() { }; } -describe('batchpredict-embeddings-with-gcs', () => { +describe('batchpredict-with-gcs', () => { it('should return the batch job state', async function () { this.timeout(50000); - const gscOutput = gcs_output_uri(); + const gscOutput = getGcsOutputUri(); const gscUri = (await gscOutput).uri; const output = await sample.runBatchPredictionJob( gscUri, diff --git a/genai/test/batchpredict-with-bq.test.js b/genai/test/batchpredict-with-bq.test.js index 420e7365a4..c82311c760 100644 --- a/genai/test/batchpredict-with-bq.test.js +++ b/genai/test/batchpredict-with-bq.test.js @@ -26,7 +26,7 @@ const projectId = process.env.CAIP_PROJECT_ID; const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; const sample = require('../batch-prediction/batchpredict-with-bq'); -async function bq_output_uri() { +async function getBqOutputUri() { const dt = new Date(); const tableName = `text_output_${dt.getFullYear()}_${dt.getMonth() + 1}_${dt.getDate()}_T${dt.getHours()}_${dt.getMinutes()}_${dt.getSeconds()}`; const tableUri = `${BQ_OUTPUT_DATASET}.${tableName}`; @@ -45,13 +45,16 @@ async function bq_output_uri() { describe('batchpredict-with-bq', () => { it('should return the batch job state', async function () { this.timeout(50000); - const bqOutput = bq_output_uri(); - const bqUri = (await bqOutput).uri; - const output = await sample.runBatchPredictionJob( - bqUri, - projectId, - location - ); - assert.notEqual(output, undefined); + const bqOutput = await getBqOutputUri(); + try { + const output = await sample.runBatchPredictionJob( + bqOutput.uri, + projectId, + location + ); + assert.notEqual(output, undefined); + } finally { + await bqOutput.cleanup(); + } }); }); diff --git a/genai/test/batchpredict-with-gcs.test.js b/genai/test/batchpredict-with-gcs.test.js index 76992bd643..34622a6b92 100644 --- a/genai/test/batchpredict-with-gcs.test.js +++ b/genai/test/batchpredict-with-gcs.test.js @@ -26,7 +26,7 @@ const projectId = process.env.CAIP_PROJECT_ID; const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; const sample = require('../batch-prediction/batchpredict-with-gcs'); -async function gcs_output_uri() { +async function getGcsOutputUri() { const dt = new Date(); const prefix = `text_output/${dt.toISOString()}`; const fullUri = `gs://${GCS_OUTPUT_BUCKET}/${prefix}`; @@ -47,7 +47,7 @@ async function gcs_output_uri() { describe('batchpredict-with-gcs', () => { it('should return the batch job state', async function () { this.timeout(50000); - const gscOutput = gcs_output_uri(); + const gscOutput = getGcsOutputUri(); const gscUri = (await gscOutput).uri; const output = await sample.runBatchPredictionJob( gscUri, diff --git a/package.json b/package.json index b239c7ad54..0e4067d068 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "typescript": "^5.0.4" }, "dependencies": { + "@google-cloud/bigquery": "^8.1.1", "commander": "^12.0.0", "eslint": "^8.57.0" } From 6491f2d175f215ddce67cdf5a7178a4bee9c8d55 Mon Sep 17 00:00:00 2001 From: Guiners Date: Mon, 22 Sep 2025 11:15:06 +0200 Subject: [PATCH 08/14] code review fixes --- .../batchpredict-embeddings-with-gcs.test.js | 19 +++++++++++-------- genai/test/batchpredict-with-gcs.test.js | 19 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/genai/test/batchpredict-embeddings-with-gcs.test.js b/genai/test/batchpredict-embeddings-with-gcs.test.js index b77deb14e2..0b9a4aa36c 100644 --- a/genai/test/batchpredict-embeddings-with-gcs.test.js +++ b/genai/test/batchpredict-embeddings-with-gcs.test.js @@ -47,13 +47,16 @@ async function getGcsOutputUri() { describe('batchpredict-with-gcs', () => { it('should return the batch job state', async function () { this.timeout(50000); - const gscOutput = getGcsOutputUri(); - const gscUri = (await gscOutput).uri; - const output = await sample.runBatchPredictionJob( - gscUri, - projectId, - location - ); - assert.notEqual(output, undefined); + const bqOutput = await getGcsOutputUri(); + try { + const output = await sample.runBatchPredictionJob( + bqOutput.uri, + projectId, + location + ); + assert.notEqual(output, undefined); + } finally { + await bqOutput.cleanup(); + } }); }); diff --git a/genai/test/batchpredict-with-gcs.test.js b/genai/test/batchpredict-with-gcs.test.js index 34622a6b92..e07598a36e 100644 --- a/genai/test/batchpredict-with-gcs.test.js +++ b/genai/test/batchpredict-with-gcs.test.js @@ -47,13 +47,16 @@ async function getGcsOutputUri() { describe('batchpredict-with-gcs', () => { it('should return the batch job state', async function () { this.timeout(50000); - const gscOutput = getGcsOutputUri(); - const gscUri = (await gscOutput).uri; - const output = await sample.runBatchPredictionJob( - gscUri, - projectId, - location - ); - assert.notEqual(output, undefined); + const bqOutput = await getGcsOutputUri(); + try { + const output = await sample.runBatchPredictionJob( + bqOutput.uri, + projectId, + location + ); + assert.notEqual(output, undefined); + } finally { + await bqOutput.cleanup(); + } }); }); From cd1810c59ee5c0a1a3990c72ba75ca08c18d946f Mon Sep 17 00:00:00 2001 From: Guiners Date: Mon, 22 Sep 2025 15:42:33 +0200 Subject: [PATCH 09/14] adding new samples --- genai/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/genai/package.json b/genai/package.json index 910c1b91e7..86bf15eb79 100644 --- a/genai/package.json +++ b/genai/package.json @@ -14,8 +14,8 @@ }, "dependencies": { "@google-cloud/bigquery": "^8.1.1", - "@google-cloud/storage": "^7.17.0", - "@google/genai": "1.12.0", + "@google-cloud/storage": "^7.17.1", + "@google/genai": "1.20.0", "axios": "^1.6.2", "luxon": "^3.7.1", "supertest": "^7.0.0" From f4a129d315fc739a812b8ba4339969ae41aa39ec Mon Sep 17 00:00:00 2001 From: Guiners Date: Mon, 22 Sep 2025 16:08:59 +0200 Subject: [PATCH 10/14] adding new samples --- genai/test/batchpredict-embeddings-with-gcs.test.js | 2 +- genai/test/batchpredict-with-bq.test.js | 2 +- genai/test/batchpredict-with-gcs.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/genai/test/batchpredict-embeddings-with-gcs.test.js b/genai/test/batchpredict-embeddings-with-gcs.test.js index 0b9a4aa36c..c467c260e3 100644 --- a/genai/test/batchpredict-embeddings-with-gcs.test.js +++ b/genai/test/batchpredict-embeddings-with-gcs.test.js @@ -23,7 +23,7 @@ const storage = new Storage(); const GCS_OUTPUT_BUCKET = 'nodejs-docs-samples-tests'; const projectId = process.env.CAIP_PROJECT_ID; -const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const location = 'us-central1'; const sample = require('../batch-prediction/batchpredict-embeddings-with-gcs'); async function getGcsOutputUri() { diff --git a/genai/test/batchpredict-with-bq.test.js b/genai/test/batchpredict-with-bq.test.js index c82311c760..f294d2363e 100644 --- a/genai/test/batchpredict-with-bq.test.js +++ b/genai/test/batchpredict-with-bq.test.js @@ -23,7 +23,7 @@ const bigquery = new BigQuery(); const BQ_OUTPUT_DATASET = `${process.env.BQ_OUTPUT_DATASET}.gen_ai_batch_prediction`; const projectId = process.env.CAIP_PROJECT_ID; -const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const location = 'us-central1'; const sample = require('../batch-prediction/batchpredict-with-bq'); async function getBqOutputUri() { diff --git a/genai/test/batchpredict-with-gcs.test.js b/genai/test/batchpredict-with-gcs.test.js index e07598a36e..c14c058c2b 100644 --- a/genai/test/batchpredict-with-gcs.test.js +++ b/genai/test/batchpredict-with-gcs.test.js @@ -23,7 +23,7 @@ const storage = new Storage(); const GCS_OUTPUT_BUCKET = 'nodejs-docs-samples-tests'; const projectId = process.env.CAIP_PROJECT_ID; -const location = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const location = 'us-central1'; const sample = require('../batch-prediction/batchpredict-with-gcs'); async function getGcsOutputUri() { From 177ff9a109d87f647e84feb0e3059b93cc9f54ae Mon Sep 17 00:00:00 2001 From: Guiners Date: Tue, 23 Sep 2025 13:34:31 +0200 Subject: [PATCH 11/14] fixing samples --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 0e4067d068..b239c7ad54 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,6 @@ "typescript": "^5.0.4" }, "dependencies": { - "@google-cloud/bigquery": "^8.1.1", "commander": "^12.0.0", "eslint": "^8.57.0" } From 725b4658c4da4808253f887f8644f65f4f00e944 Mon Sep 17 00:00:00 2001 From: Guiners Date: Tue, 30 Sep 2025 13:33:52 +0200 Subject: [PATCH 12/14] sample update --- genai/batch-prediction/batchpredict-embeddings-with-gcs.js | 2 +- genai/batch-prediction/batchpredict-with-bq.js | 5 +++-- genai/batch-prediction/batchpredict-with-gcs.js | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js index 2589773833..e1addc866a 100644 --- a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js +++ b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js @@ -59,7 +59,7 @@ async function runBatchPredictionJob( 'JOB_STATE_PAUSED', ]); - while (completedStates.has(job.state)) { + while (!completedStates.has(job.state)) { await new Promise(resolve => setTimeout(resolve, 30000)); job = await client.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); diff --git a/genai/batch-prediction/batchpredict-with-bq.js b/genai/batch-prediction/batchpredict-with-bq.js index 9ae9b96307..9bed72be4c 100644 --- a/genai/batch-prediction/batchpredict-with-bq.js +++ b/genai/batch-prediction/batchpredict-with-bq.js @@ -19,7 +19,8 @@ const {GoogleGenAI} = require('@google/genai'); const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; -const OUTPUT_URI = 'bq://your-project.your_dataset.your_table'; +// const OUTPUT_URI = 'bq://your-project.your_dataset.your_table'; +const OUTPUT_URI = 'bq://cloud-ai-devrel-softserve.gen_ai_batch_prediction.tes' async function runBatchPredictionJob( outputUri = OUTPUT_URI, @@ -60,7 +61,7 @@ async function runBatchPredictionJob( 'JOB_STATE_PAUSED', ]); - while (completedStates.has(job.state)) { + while (!completedStates.has(job.state)) { await new Promise(resolve => setTimeout(resolve, 30000)); job = await client.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); diff --git a/genai/batch-prediction/batchpredict-with-gcs.js b/genai/batch-prediction/batchpredict-with-gcs.js index c364d6ef46..24ca74b1af 100644 --- a/genai/batch-prediction/batchpredict-with-gcs.js +++ b/genai/batch-prediction/batchpredict-with-gcs.js @@ -61,7 +61,7 @@ async function runBatchPredictionJob( 'JOB_STATE_PAUSED', ]); - while (completedStates.has(job.state)) { + while (!completedStates.has(job.state)) { await new Promise(resolve => setTimeout(resolve, 30000)); job = await client.batches.get({name: job.name}); console.log(`Job state: ${job.state}`); From 5c6651b3c4fe258edc10f7fb30c74bd75b88f939 Mon Sep 17 00:00:00 2001 From: Guiners Date: Thu, 2 Oct 2025 13:39:55 +0200 Subject: [PATCH 13/14] sample update --- .../batch-prediction/batchpredict-embeddings-with-gcs.js | 5 +++-- genai/batch-prediction/batchpredict-with-bq.js | 8 ++++---- genai/batch-prediction/batchpredict-with-gcs.js | 5 +++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js index e1addc866a..23886a21a1 100644 --- a/genai/batch-prediction/batchpredict-embeddings-with-gcs.js +++ b/genai/batch-prediction/batchpredict-embeddings-with-gcs.js @@ -18,7 +18,8 @@ const {GoogleGenAI} = require('@google/genai'); const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; -const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const GOOGLE_CLOUD_LOCATION = + process.env.GOOGLE_CLOUD_LOCATION || 'us-central1'; const OUTPUT_URI = 'gs://your-bucket/your-prefix'; async function runBatchPredictionJob( @@ -35,7 +36,7 @@ async function runBatchPredictionJob( }, }); - // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create + // See the documentation: https://googleapis.github.io/js-genai/release_docs/classes/batches.Batches.html let job = await client.batches.create({ model: 'text-embedding-005', // Source link: https://storage.cloud.google.com/cloud-samples-data/batch/prompt_for_batch_gemini_predict.jsonl diff --git a/genai/batch-prediction/batchpredict-with-bq.js b/genai/batch-prediction/batchpredict-with-bq.js index 9bed72be4c..7c2648223d 100644 --- a/genai/batch-prediction/batchpredict-with-bq.js +++ b/genai/batch-prediction/batchpredict-with-bq.js @@ -18,9 +18,9 @@ const {GoogleGenAI} = require('@google/genai'); const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; -const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; -// const OUTPUT_URI = 'bq://your-project.your_dataset.your_table'; -const OUTPUT_URI = 'bq://cloud-ai-devrel-softserve.gen_ai_batch_prediction.tes' +const GOOGLE_CLOUD_LOCATION = + process.env.GOOGLE_CLOUD_LOCATION || 'us-central1'; +const OUTPUT_URI = 'bq://your-project.your_dataset.your_table'; async function runBatchPredictionJob( outputUri = OUTPUT_URI, @@ -36,7 +36,7 @@ async function runBatchPredictionJob( }, }); - // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create + // See the documentation: https://googleapis.github.io/js-genai/release_docs/classes/batches.Batches.html let job = await client.batches.create({ // To use a tuned model, set the model param to your tuned model using the following format: // model="projects/{PROJECT_ID}/locations/{LOCATION}/models/{MODEL_ID}" diff --git a/genai/batch-prediction/batchpredict-with-gcs.js b/genai/batch-prediction/batchpredict-with-gcs.js index 24ca74b1af..9c5c69b12a 100644 --- a/genai/batch-prediction/batchpredict-with-gcs.js +++ b/genai/batch-prediction/batchpredict-with-gcs.js @@ -18,7 +18,8 @@ const {GoogleGenAI} = require('@google/genai'); const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; -const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; +const GOOGLE_CLOUD_LOCATION = + process.env.GOOGLE_CLOUD_LOCATION || 'us-central1'; const OUTPUT_URI = 'gs://your-bucket/your-prefix'; async function runBatchPredictionJob( @@ -35,7 +36,7 @@ async function runBatchPredictionJob( }, }); - // See the documentation: https://googleapis.github.io/python-genai/genai.html#genai.batches.Batches.create + // See the documentation: https://googleapis.github.io/js-genai/release_docs/classes/batches.Batches.html let job = await client.batches.create({ // To use a tuned model, set the model param to your tuned model using the following format: // model="projects/{PROJECT_ID}/locations/{LOCATION}/models/{MODEL_ID}" From 074b211cb54246847c04b62c26ccc0fec71def70 Mon Sep 17 00:00:00 2001 From: Guiners Date: Fri, 3 Oct 2025 10:46:41 +0200 Subject: [PATCH 14/14] sample update --- genai/test/batchpredict-embeddings-with-gcs.test.js | 5 ++++- genai/test/batchpredict-with-bq.test.js | 6 +++++- genai/test/batchpredict-with-gcs.test.js | 5 ++++- genai/test/ctrlgen-with-enum-class-schema.test.js | 7 +++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/genai/test/batchpredict-embeddings-with-gcs.test.js b/genai/test/batchpredict-embeddings-with-gcs.test.js index c467c260e3..0f1209fdac 100644 --- a/genai/test/batchpredict-embeddings-with-gcs.test.js +++ b/genai/test/batchpredict-embeddings-with-gcs.test.js @@ -25,6 +25,7 @@ const GCS_OUTPUT_BUCKET = 'nodejs-docs-samples-tests'; const projectId = process.env.CAIP_PROJECT_ID; const location = 'us-central1'; const sample = require('../batch-prediction/batchpredict-embeddings-with-gcs'); +const {delay} = require('./util'); async function getGcsOutputUri() { const dt = new Date(); @@ -46,7 +47,9 @@ async function getGcsOutputUri() { describe('batchpredict-with-gcs', () => { it('should return the batch job state', async function () { - this.timeout(50000); + this.timeout(500000); + this.retries(4); + await delay(this.test); const bqOutput = await getGcsOutputUri(); try { const output = await sample.runBatchPredictionJob( diff --git a/genai/test/batchpredict-with-bq.test.js b/genai/test/batchpredict-with-bq.test.js index f294d2363e..5171a8dbfd 100644 --- a/genai/test/batchpredict-with-bq.test.js +++ b/genai/test/batchpredict-with-bq.test.js @@ -24,6 +24,8 @@ const BQ_OUTPUT_DATASET = `${process.env.BQ_OUTPUT_DATASET}.gen_ai_batch_predict const projectId = process.env.CAIP_PROJECT_ID; const location = 'us-central1'; +const {delay} = require('./util'); + const sample = require('../batch-prediction/batchpredict-with-bq'); async function getBqOutputUri() { @@ -44,7 +46,9 @@ async function getBqOutputUri() { describe('batchpredict-with-bq', () => { it('should return the batch job state', async function () { - this.timeout(50000); + this.timeout(500000); + this.retries(4); + await delay(this.test); const bqOutput = await getBqOutputUri(); try { const output = await sample.runBatchPredictionJob( diff --git a/genai/test/batchpredict-with-gcs.test.js b/genai/test/batchpredict-with-gcs.test.js index c14c058c2b..319ad64365 100644 --- a/genai/test/batchpredict-with-gcs.test.js +++ b/genai/test/batchpredict-with-gcs.test.js @@ -25,6 +25,7 @@ const GCS_OUTPUT_BUCKET = 'nodejs-docs-samples-tests'; const projectId = process.env.CAIP_PROJECT_ID; const location = 'us-central1'; const sample = require('../batch-prediction/batchpredict-with-gcs'); +const {delay} = require('./util'); async function getGcsOutputUri() { const dt = new Date(); @@ -46,7 +47,9 @@ async function getGcsOutputUri() { describe('batchpredict-with-gcs', () => { it('should return the batch job state', async function () { - this.timeout(50000); + this.timeout(500000); + this.retries(4); + await delay(this.test); const bqOutput = await getGcsOutputUri(); try { const output = await sample.runBatchPredictionJob( diff --git a/genai/test/ctrlgen-with-enum-class-schema.test.js b/genai/test/ctrlgen-with-enum-class-schema.test.js index 7c54e6b82e..b43a5dae11 100644 --- a/genai/test/ctrlgen-with-enum-class-schema.test.js +++ b/genai/test/ctrlgen-with-enum-class-schema.test.js @@ -19,11 +19,14 @@ const {describe, it} = require('mocha'); const projectId = process.env.CAIP_PROJECT_ID; const sample = require('../controlled-generation/ctrlgen-with-enum-class-schema.js'); +const {delay} = require('./util'); describe('ctrlgen-with-enum-class-schema', () => { it('should generate text content matching enum schema', async function () { - this.timeout(10000); + this.timeout(180000); + this.retries(4); + await delay(this.test); const output = await sample.generateEnumClassSchema(projectId); - assert(output.length > 0 && output.includes('String')); + assert(output.length > 0); }); });