Skip to content

Conversation

@Guiners
Copy link
Contributor

@Guiners Guiners commented Nov 20, 2025

Description

Fixes #

Note: Before submitting a pull request, please open an issue for discussion if you are not associated with Google.

Checklist

  • I have followed guidelines from CONTRIBUTING.MD and Samples Style Guide
  • Tests pass: npm test (see Testing)
  • Lint pass: npm run lint (see Style)
  • Required CI tests pass (see CI testing)
  • These samples need a new API enabled in testing projects to pass (let us know which ones)
  • These samples need a new/updated env vars in testing projects set to pass (let us know which ones)
  • This pull request is from a branch created directly off of GoogleCloudPlatform/nodejs-docs-samples. Not a fork.
  • This sample adds a new sample directory, and I updated the CODEOWNERS file with the codeowners for this sample
  • This sample adds a new sample directory, and I created GitHub Actions workflow for this sample
  • This sample adds a new Product API, and I updated the Blunderbuss issue/PR auto-assigner with the codeowners for this sample
  • Please merge this PR for me once it is approved

Note: Any check with (dev), (experimental), or (legacy) can be ignored and should not block your PR from merging (see CI testing).

@Guiners Guiners requested review from a team as code owners November 20, 2025 10:09
@snippet-bot
Copy link

snippet-bot bot commented Nov 20, 2025

Here is the summary of changes.

You are about to add 5 region tags.

This comment is generated by snippet-bot.
If you find problems with this result, please file an issue at:
https://github.com/googleapis/repo-automation-bots/issues.
To update this comment, add snippet-bot:force-run label or use the checkbox below:

  • Refresh this comment

@product-auto-label product-auto-label bot added the samples Issues that are directly related to samples. label Nov 20, 2025
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @Guiners, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the Generative AI samples for Node.js by introducing several new examples that cover a range of advanced functionalities. These additions aim to provide developers with practical demonstrations of features such as image analysis with bounding boxes, text embeddings for retrieval, direct API key authentication, managing provisioned throughput, and implementing content safety measures. The new samples enhance the documentation and provide clearer guidance for integrating these GenAI capabilities into applications.

Highlights

  • New Bounding Box Sample: Added a new sample demonstrating how to perform bounding box detection on images using the gemini-2.5-flash model, processing both text prompts and image inputs to identify and label objects. This sample utilizes canvas and node-fetch for image processing and visualization.
  • New Embeddings Sample: Introduced a new sample that illustrates generating embeddings for document retrieval tasks using the gemini-embedding-001 model, showcasing how to configure task type and output dimensionality.
  • New API Key Usage Sample: Included a new sample demonstrating the direct use of an API key for authenticating the GoogleGenAI client, providing an alternative to project and location-based authentication.
  • New Provisioned Throughput Sample: Provided a new sample showcasing how to configure and utilize provisioned throughput for generative AI models, specifically gemini-2.5-flash, by setting the X-Vertex-AI-LLM-Request-Type header.
  • New Safety Settings Sample: Added a new sample that demonstrates setting up and applying safety settings and system instructions for content generation with the gemini-2.5-flash model, allowing control over potentially harmful content.
  • Dependency Updates: Updated genai/package.json and the root package.json to include new dependencies such as canvas, node-fetch, and proxyquire, which are required by the newly added samples and their tests.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Guiners Guiners closed this Nov 20, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds several new GenAI samples and their corresponding tests. Overall, the additions are valuable, but there are several critical and high-severity issues that need to be addressed. These include a security vulnerability from a hardcoded API key placeholder, incorrect package versions in package.json that will cause installation to fail, and several bugs in the samples that could lead to crashes (e.g., when a response is blocked by safety filters). I've also noted inconsistencies in API client initialization and a misleading sample for provisioned throughput. Please review the detailed comments for specific suggestions.


// [START googlegenaisdk_vertexai_express_mode]
const {GoogleGenAI} = require('@google/genai');
const API_KEY = 'PUT HERE YOUR API KEY';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Hardcoding credential placeholders like 'PUT HERE YOUR API KEY' is a significant security risk. A developer might replace the placeholder with a real key and accidentally commit it. Secrets should always be loaded from a secure source, such as environment variables. It's also good practice to add a check inside generateWithApiKey to ensure the key is present before making an API call.

Suggested change
const API_KEY = 'PUT HERE YOUR API KEY';
const API_KEY = process.env.GOOGLE_API_KEY;

"uuid": "^10.0.0"
"uuid": "^10.0.0",
"proxyquire": "^2.1.3",
"canvas": "^3.1.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The specified version ^3.1.0 for the canvas package does not exist. The latest version of canvas is 2.11.2. Please correct the version to a valid one to prevent installation errors.

Suggested change
"canvas": "^3.1.0",
"canvas": "^2.11.2",

"typescript": "^5.0.4"
},
"dependencies": {
"canvas": "^3.1.2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The specified version ^3.1.2 for the canvas package does not exist. The latest version of canvas is 2.11.2. Please correct the version to a valid one to prevent installation errors.

Suggested change
"canvas": "^3.1.2",
"canvas": "^2.11.2",

async function generateEmbeddingsForRetrieval(
projectId = GOOGLE_CLOUD_PROJECT
) {
const client = new GoogleGenAI(projectId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This sample appears to be for Vertex AI, but the GoogleGenAI client is not initialized with vertexai: true. This will cause it to target the Google AI endpoint, which uses API keys, not project IDs. For correct functionality with a project ID, you should initialize it with an object containing vertexai: true, project: projectId, and a location. You will also need to update the function signature to accept a location and define GOOGLE_CLOUD_LOCATION at the top of the file for consistency with other samples.

// - "dedicated": Use Provisioned Throughput
// - "shared": Use pay-as-you-go
// https://cloud.google.com/vertex-ai/generative-ai/docs/use-provisioned-throughput
'X-Vertex-AI-LLM-Request-Type': 'shared',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The sample is named provisionedthroughput-with-txt.js and the comments indicate that 'dedicated' should be used for provisioned throughput. However, the code is using 'shared', which is for pay-as-you-go. This is misleading for a sample that is supposed to demonstrate provisioned throughput.

Suggested change
'X-Vertex-AI-LLM-Request-Type': 'shared',
'X-Vertex-AI-LLM-Request-Type': 'dedicated',

"commander": "^12.0.0",
"eslint": "^8.57.0"
"eslint": "^8.57.0",
"node-fetch": "^3.3.2",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

You are adding node-fetch@^3.3.2, which is an ESM-only package. The root package.json does not have "type": "module", so it defaults to CommonJS. Any attempt to require('node-fetch') will fail. If this package is needed for CommonJS code, you should use node-fetch@^2.7.0, which is what the genai sub-package correctly does.

Suggested change
"node-fetch": "^3.3.2",
"node-fetch": "^2.7.0",

ctx.fillText(bbox.label, absXMin + 8, absYMin + 20);
});

fs.writeFileSync('output.png', canvas.toBuffer('image/png'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoding the output filename to output.png can be problematic as it might overwrite an existing file in the directory where the script is run. Consider making the output filename unique, for example by including a timestamp. You'll also need to update the log message on the next line to use the dynamic filename.

Suggested change
fs.writeFileSync('output.png', canvas.toBuffer('image/png'));
fs.writeFileSync(`output-${Date.now()}.png`, canvas.toBuffer('image/png'));

Comment on lines +108 to +109
minItems: '4',
maxItems: '4',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to the JSON Schema specification, the values for minItems and maxItems should be numbers, not strings.

Suggested change
minItems: '4',
maxItems: '4',
minItems: 4,
maxItems: 4,

Comment on lines +147 to +148
const candidate = response.candidates[0].content.parts[0].text;
const boundingBoxes = JSON.parse(candidate);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Accessing nested properties directly can lead to a TypeError if the response structure is not what's expected (e.g., if candidates is empty). Using optional chaining (?.) and providing a fallback will make the code more robust.

Suggested change
const candidate = response.candidates[0].content.parts[0].text;
const boundingBoxes = JSON.parse(candidate);
const candidateText = response.candidates?.[0]?.content?.parts?.[0]?.text;
const boundingBoxes = candidateText ? JSON.parse(candidateText) : [];

it('should call generateContentStream with safety instructions', async function () {
this.timeout(50000);
const output = await sample.generateWithSafetySettings(projectId);
assert(output.text.length > 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This assertion assert(output.text.length > 0) will fail if the response is blocked due to safety settings, as accessing .text will throw an error. The test should be more robust to handle this case. You could use a try...catch block to assert that either output.text has content, or that the finishReason is 'SAFETY' in the catch block.

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

Labels

samples Issues that are directly related to samples.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant