Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions quickstarts-js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Stay tuned, more JavaScript notebooks are on the way!
| Get Started | A comprehensive introduction to the Gemini JS/TS SDK, demonstrating features such as text and multimodal prompting, token counting, system instructions, safety filters, multi-turn chat, output control, function calling, content streaming, file uploads, and using URL or YouTube video context. | Explore core Gemini capabilities in JS/TS | [![Open in AI Studio](https://storage.googleapis.com/generativeai-downloads/images/Open_in_AIStudio.svg)](https://aistudio.google.com/apps/bundled/get_started?showPreview=true) | <img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg" alt="JS" width="20"/> [Get_Started.js](./Get_Started.js) |
| Counting Tokens | Learn how tokens work in Gemini, how to count them, and how context windows affect requests. Includes text, image, and audio tokenization. | Token counting, context windows, multimodal tokens | [![Open in AI Studio](https://storage.googleapis.com/generativeai-downloads/images/Open_in_AIStudio.svg)](https://aistudio.google.com/apps/bundled/counting_tokens?showPreview=true) | <img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg" alt="JS" width="20"/> [Counting_Tokens.js](./Counting_Tokens.js) |
| Image Output | Generate and iterate on images using Gemini’s multimodal capabilities. Learn to use text+image responses, edit images mid-conversation, and handle multiple image outputs with chat-style prompting. | Image generation, multimodal output, image editing, iterative refinement | [![Open in AI Studio](https://storage.googleapis.com/generativeai-downloads/images/Open_in_AIStudio.svg)](https://aistudio.google.com/apps/bundled/get_started_image_out?showPreview=true) | <img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg" alt="JS" width="20"/> [ImageOutput.js](./ImageOutput.js) |
| Safety | Demonstrates how to use and adjust the API's safety settings to handle potentially harmful prompts and understand safety feedback. | Safety settings, content filtering, HarmBlockThreshold | [![Open in AI Studio](https://storage.googleapis.com/generativeai-downloads/images/Open_in_AIStudio.svg)](https://aistudio.google.com/apps/bundled/safety?showPreview=true) | <img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg" alt="JS" width="20"/> [Safety.js](./Safety.js) |
| File API | Learn how to upload, use, retrieve, and delete files (text, image, audio, code) with the Gemini File API for multimodal prompts. | File upload, multimodal prompts, text/code/media files | [![Open in AI Studio](https://storage.googleapis.com/generativeai-downloads/images/Open_in_AIStudio.svg)](https://aistudio.google.com/apps/bundled/file_api?showPreview=true) | <img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg" alt="JS" width="20"/> [File_API.js](./File_API.js) |
| Audio | Demonstrates how to use audio files with Gemini: upload, prompt, summarize, transcribe, and analyze audio and YouTube content. | Audio file upload, inline audio, transcription, YouTube analysis | [![Open in AI Studio](https://storage.googleapis.com/generativeai-downloads/images/Open_in_AIStudio.svg)](https://aistudio.google.com/apps/bundled/audio?showPreview=true) | <img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg" alt="JS" width="20"/> [Audio.js](./Audio.js) |
| Get Started LearnLM | Explore LearnLM, an experimental model for AI tutoring, with examples of system instructions for test prep, concept teaching, learning activities, and homework help. | AI tutoring, system instructions, adaptive learning, education | [![Open in AI Studio](https://storage.googleapis.com/generativeai-downloads/images/Open_in_AIStudio.svg)](https://aistudio.google.com/apps/bundled/get_started_learnlm?showPreview=true) | <img src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/javascript/javascript-original.svg" alt="JS" width="20"/> [Get_started_LearnLM.js](./Get_started_LearnLM.js) |
138 changes: 138 additions & 0 deletions quickstarts-js/Safety.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* 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
*
* http://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.
*/

/* Markdown (render)
# Gemini API: Safety Quickstart

The Gemini API has adjustable safety settings. This guide walks you through how to use them. You'll write a prompt that might be blocked, see the reason why, and then adjust the filters to unblock it.

Safety is an important topic, and you can learn more with the links at the end of this guide. Here, you will focus on the code.
*/

/* Markdown (render)
## Setup
### Install SDK and set-up the client

### API Key Configuration

To ensure security, avoid hardcoding the API key in frontend code. Instead, set it as an environment variable on the server or local machine.

When using the Gemini API client libraries, the key will be automatically detected if set as either `GEMINI_API_KEY` or `GOOGLE_API_KEY`. If both are set, `GOOGLE_API_KEY` takes precedence.

For instructions on setting environment variables across different operating systems, refer to the official documentation: [Set API Key as Environment Variable](https://ai.google.dev/gemini-api/docs/api-key#set-api-env-var)

In code, the key can then be accessed as:

```js
ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
*/

// [CODE STARTS]
const module = await import("https://esm.sh/@google/genai@1.4.0");
const { GoogleGenAI, HarmCategory, HarmBlockThreshold } = module;

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const MODEL_ID = "gemini-2.5-flash-lite";
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 SDK import and initialization are incorrect and will prevent the code from running.

  1. The correct package is @google/generative-ai, not @google/genai.
  2. The version 1.4.0 does not exist for this package. You should use a recent, valid version like 0.14.0.
  3. The class name is GoogleGenerativeAI, not GoogleGenAI.
  4. The GoogleGenerativeAI constructor takes the API key as a string directly, not in an options object.
  5. The standard API pattern is to get a model instance using getGenerativeModel() and then call methods on it. The ai.models property you are using does not exist.
const { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold } = await import("https://esm.sh/@google/generative-ai@0.14.0");

const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
const MODEL_ID = "gemini-2.5-flash-lite";
const model = genAI.getGenerativeModel({ model: MODEL_ID });

// [CODE ENDS]

/* Markdown (render)
Send your prompt request to Gemini

Pick a prompt to test the safety filters. This example uses a prompt that could trigger the HARM_CATEGORY_HARASSMENT filter.
*/

// [CODE STARTS]
const unsafePrompt =
"I support Martians Soccer Club and I think Jupiterians Football Club sucks! Write an ironic phrase about them.";

try {
const response = await ai.models.generateContent({
model: MODEL_ID,
contents: unsafePrompt,
});
console.log(response.text);
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

Following the setup correction, this API call to generateContent is incorrect. It should be called on the model instance. The method returns a GenerateContentResult object, and the text content is accessed via the text() method on the response property.

  const result = await model.generateContent(unsafePrompt);
  const response = result.response;
  console.log(response.text());

} catch (e) {
console.log("Request was blocked.", e.message);
// If the prompt is blocked, the response will be empty.
// We can inspect the error to see the reason.
if (e.response) {
console.log("Finish Reason:", e.response.candidates[0].finishReason);
console.log("Safety Ratings:", e.response.candidates[0].safetyRatings);
}
}
// [CODE ENDS]

/* Output Sample
Request was blocked. [GoogleGenerativeAI Error]: Text generation failed.
Finish Reason: SAFETY
Safety Ratings: [
{ category: 'HARM_CATEGORY_HATE_SPEECH', probability: 'NEGLIGIBLE' },
{ category: 'HARM_CATEGORY_DANGEROUS_CONTENT', probability: 'NEGLIGIBLE' },
{ category: 'HARM_CATEGORY_HARASSMENT', probability: 'LOW' },
{ category: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', probability: 'NEGLIGIBLE' }
]
*/

/* Markdown (render)
The finishReason is SAFETY, which means the request was blocked. You can inspect the safetyRatings to see which category was triggered. In this case, HARM_CATEGORY_HARASSMENT was rated as LOW.

Because the request was blocked, the response text is empty.
*/

/* Markdown (render)
Customizing safety settings

Depending on your use case, you might need to adjust the safety filters. You can customize the safetySettings in your request. In this example, we'll set the harassment filter to BLOCK_LOW_AND_ABOVE.

Important: Only adjust safety settings if you are sure it is necessary for your use case.
*/

// [CODE STARTS]
const safetySettings = [
{
category: HarmCategory.HARM_CATEGORY_HARASSMENT,
threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
},
];

try {
const responseWithSettings = await ai.models.generateContent({
model: MODEL_ID,
contents: unsafePrompt,
config: {
safetySettings: safetySettings,
},
});
console.log("Finish Reason:", responseWithSettings.candidates[0].finishReason);
console.log(responseWithSettings.text);
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

This API call is also incorrect and needs to be updated to use the model instance.

  1. The safetySettings should be passed as a top-level property in the request object, not nested under config.
  2. When passing safetySettings, you must use the object form for the request, which requires structuring contents as an array of Content objects.
  3. The result of generateContent is a GenerateContentResult. The actual response is in result.response. You need to access properties like candidates and the text() method from there.
  const result = await model.generateContent({
    contents: [{ parts: [{ text: unsafePrompt }] }],
    safetySettings,
  });
  const responseWithSettings = result.response;
  console.log("Finish Reason:", responseWithSettings.candidates[0].finishReason);
  console.log(responseWithSettings.text());

} catch (e) {
console.log("Request was blocked.", e.message);
}
// [CODE ENDS]

/* Output Sample
Request was blocked. [GoogleGenerativeAI Error]: Text generation failed.
*/

/* Markdown (render)
Even with the adjusted settings, this prompt might still be blocked depending on the model's current safety calibration. If it is, the finishReason will still be SAFETY. If it succeeds, the finishReason will be STOP and you will see the generated text.
*/

/* Markdown (render)
Learning more

Learn more with these articles on safety guidance and safety settings.
*/