From 2e8961316d9d9d1cf2e233613d5b7622e0cc31e4 Mon Sep 17 00:00:00 2001 From: Eric Dong Date: Wed, 21 May 2025 15:06:35 -0400 Subject: [PATCH 1/2] feat(genai): Add image generation and code execution examples --- .../imggen-mmflash-with-txt.js | 63 +++++++++++++++++++ genai/test/imggen-mmflash-with-txt.test.js | 28 +++++++++ genai/test/tools-code-exec-with-txt.test.js | 28 +++++++++ genai/tools/tools-code-exec-with-txt.js | 52 +++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 genai/image-generation/imggen-mmflash-with-txt.js create mode 100644 genai/test/imggen-mmflash-with-txt.test.js create mode 100644 genai/test/tools-code-exec-with-txt.test.js create mode 100644 genai/tools/tools-code-exec-with-txt.js diff --git a/genai/image-generation/imggen-mmflash-with-txt.js b/genai/image-generation/imggen-mmflash-with-txt.js new file mode 100644 index 0000000000..1f742a01c5 --- /dev/null +++ b/genai/image-generation/imggen-mmflash-with-txt.js @@ -0,0 +1,63 @@ +// 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_imggen_mmflash_with_txt] +const fs = require('fs'); +const {GoogleGenAI, Modality} = require('@google/genai'); + +const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; +const GOOGLE_CLOUD_LOCATION = + process.env.GOOGLE_CLOUD_LOCATION || 'us-central1'; + +async function generateContent( + projectId = GOOGLE_CLOUD_PROJECT, + location = GOOGLE_CLOUD_LOCATION +) { + const ai = new GoogleGenAI({ + vertexai: true, + project: projectId, + location: location, + }); + + const response = await ai.models.generateContentStream({ + model: 'gemini-2.0-flash-exp', + contents: + 'Generate an image of the Eiffel tower with fireworks in the background.', + config: { + responseModalities: [Modality.TEXT, Modality.IMAGE], + }, + }); + + let i = 0; + for await (const chunk of response) { + const text = chunk.text; + const data = chunk.data; + if (text) { + console.debug(text); + } else if (data) { + const fileName = `generate_content_streaming_image_${i++}.png`; + console.debug(`Writing response image to file: ${fileName}.`); + fs.writeFileSync(fileName, data); + } + } + + return 'generate_content_streaming_image'; +} +// [END googlegenaisdk_imggen_mmflash_with_txt] + +module.exports = { + generateContent, +}; diff --git a/genai/test/imggen-mmflash-with-txt.test.js b/genai/test/imggen-mmflash-with-txt.test.js new file mode 100644 index 0000000000..35076f4a6e --- /dev/null +++ b/genai/test/imggen-mmflash-with-txt.test.js @@ -0,0 +1,28 @@ +// 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 projectId = process.env.CAIP_PROJECT_ID; +const sample = require('../image-generation/imggen-mmflash-with-txt.js'); + +describe('imggen-mmflash-with-txt', async () => { + it('should generate image from a text prompt', async () => { + const output = await sample.generateContent(projectId); + assert(output.length > 0 && output.includes('image')); + }); +}); diff --git a/genai/test/tools-code-exec-with-txt.test.js b/genai/test/tools-code-exec-with-txt.test.js new file mode 100644 index 0000000000..cedd6f6b7c --- /dev/null +++ b/genai/test/tools-code-exec-with-txt.test.js @@ -0,0 +1,28 @@ +// 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 projectId = process.env.CAIP_PROJECT_ID; +const sample = require('../tools/tools-code-exec-with-txt.js'); + +describe('tools-code-exec-with-txt', async () => { + it('should generate code and execution result', async () => { + const output = await sample.generateContent(projectId); + assert(output.length > 0); + }); +}); diff --git a/genai/tools/tools-code-exec-with-txt.js b/genai/tools/tools-code-exec-with-txt.js new file mode 100644 index 0000000000..7590be8237 --- /dev/null +++ b/genai/tools/tools-code-exec-with-txt.js @@ -0,0 +1,52 @@ +// 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_tools_code_exec_with_txt] +const {GoogleGenAI} = require('@google/genai'); + +const GOOGLE_CLOUD_PROJECT = process.env.GOOGLE_CLOUD_PROJECT; +const GOOGLE_CLOUD_LOCATION = process.env.GOOGLE_CLOUD_LOCATION || 'global'; + +async function generateContent( + projectId = GOOGLE_CLOUD_PROJECT, + location = GOOGLE_CLOUD_LOCATION +) { + const ai = new GoogleGenAI({ + vertexai: true, + project: projectId, + location: location, + }); + + const response = await ai.models.generateContent({ + model: 'gemini-2.5-flash-preview-05-20', + contents: + 'What is the sum of the first 50 prime numbers? Generate and run code for the calculation, and make sure you get all 50.', + config: { + tools: [{codeExecution: {}}], + temperature: 0, + }, + }); + + console.debug(response.executableCode); + console.debug(response.codeExecutionResult); + + return response.codeExecutionResult; +} +// [END googlegenaisdk_tools_code_exec_with_txt] + +module.exports = { + generateContent, +}; From 016e7e22527e1ba46e6c12999c6704f9b81245f2 Mon Sep 17 00:00:00 2001 From: Eric Dong Date: Wed, 21 May 2025 15:46:33 -0400 Subject: [PATCH 2/2] Improve test --- genai/image-generation/imggen-mmflash-with-txt.js | 14 ++++++++++---- genai/test/imggen-mmflash-with-txt.test.js | 7 ++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/genai/image-generation/imggen-mmflash-with-txt.js b/genai/image-generation/imggen-mmflash-with-txt.js index 1f742a01c5..054a7f72d5 100644 --- a/genai/image-generation/imggen-mmflash-with-txt.js +++ b/genai/image-generation/imggen-mmflash-with-txt.js @@ -41,20 +41,26 @@ async function generateContent( }, }); - let i = 0; + const generatedFileNames = []; + let imageIndex = 0; for await (const chunk of response) { const text = chunk.text; const data = chunk.data; if (text) { console.debug(text); } else if (data) { - const fileName = `generate_content_streaming_image_${i++}.png`; + const fileName = `generate_content_streaming_image_${imageIndex++}.png`; console.debug(`Writing response image to file: ${fileName}.`); - fs.writeFileSync(fileName, data); + try { + fs.writeFileSync(fileName, data); + generatedFileNames.push(fileName); + } catch (error) { + console.error(`Failed to write image file ${fileName}:`, error); + } } } - return 'generate_content_streaming_image'; + return generatedFileNames; } // [END googlegenaisdk_imggen_mmflash_with_txt] diff --git a/genai/test/imggen-mmflash-with-txt.test.js b/genai/test/imggen-mmflash-with-txt.test.js index 35076f4a6e..09b9544093 100644 --- a/genai/test/imggen-mmflash-with-txt.test.js +++ b/genai/test/imggen-mmflash-with-txt.test.js @@ -21,8 +21,9 @@ const projectId = process.env.CAIP_PROJECT_ID; const sample = require('../image-generation/imggen-mmflash-with-txt.js'); describe('imggen-mmflash-with-txt', async () => { - it('should generate image from a text prompt', async () => { - const output = await sample.generateContent(projectId); - assert(output.length > 0 && output.includes('image')); + it('should generate images from a text prompt', async () => { + const generatedFileNames = await sample.generateContent(projectId); + assert(Array.isArray(generatedFileNames)); + assert(generatedFileNames.length > 0); }); });