diff --git a/samples/node/README.md b/samples/node/README.md index 4c41be4c..30d1e6e5 100644 --- a/samples/node/README.md +++ b/samples/node/README.md @@ -13,27 +13,6 @@ It’s strongly recommended that you do not check an API key into your version c This sample assumes that you're providing an `API_KEY` environment variable. -## Features - -### Simple examples - -- [`simple-text.js`](simple-text.js) - Text-only input -- [`simple-text-and-images.js`](simple-text-and-images.js) - Text-and-images input (multimodal) -- [`simple-chat.js`](simple-chat.js) - Dialog language tasks, using `ChatSession` class -- [`simple-config.js`](simple-config.js) - Configuring model parameters -- [`simple-embedding.js`](simple-embedding.js) - Embeddings, using the `embedding-001` model - -### More examples - -- [`advanced-text.js`](advanced-text.js) - Using `countTokens`, `safetySettings` and streaming with a text-only input -- [`advanced-text-and-images.js`](advanced-text-and-images.js) - Using `countTokens`, `generationConfig` and streaming with multimodal input -- [`advanced-chat.js`](advanced-chat.js) - Using `countTokens`, `generationConfig` and streaming with multi-turn conversations -- [`advanced-embeddings.js`](advanced-embeddings.js) - Using `batchEmbedContents` -- [`advanced-function-calling.js`](advanced-function-calling.js) - Using function calling -- [`advanced-code-execution.js`](advanced-code-execution.js) - Using the code execution feature -- [`content-caching.js`](content-caching.js) - Using `GoogleAICacheManager` -- [`file-upload.js`](file-upload.js) - Using `GoogleAIFileManager` - ## Documentation - [Quickstart: Get started with the Gemini API in Node.js applications](https://ai.google.dev/tutorials/node_quickstart) diff --git a/samples/node/advanced-text.js b/samples/node/advanced-text.js deleted file mode 100644 index e2577435..00000000 --- a/samples/node/advanced-text.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * @license - * Copyright 2023 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. - */ - -import { HarmBlockThreshold, HarmCategory } from "@google/generative-ai"; -import { genAI, displayTokenCount, streamToStdout } from "./utils/common.js"; - -async function run() { - const model = genAI.getGenerativeModel({ - model: "gemini-1.5-flash-latest", - safetySettings: [ - { - category: HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT, - threshold: HarmBlockThreshold.BLOCK_NONE, - }, - ], - }); - - const prompt = 'Please describe in detail the movie "Eyes wide shut"'; - - displayTokenCount(model, prompt); - - const result = await model.generateContentStream(prompt); - await streamToStdout(result.stream); - - // Display the aggregated response - const response = await result.response; - console.log(JSON.stringify(response, null, 2)); -} - -run(); diff --git a/samples/node/media/Big_Buck_Bunny.mp4 b/samples/node/media/Big_Buck_Bunny.mp4 new file mode 100644 index 00000000..07096db4 Binary files /dev/null and b/samples/node/media/Big_Buck_Bunny.mp4 differ diff --git a/samples/node/media/firefighter.jpg b/samples/node/media/firefighter.jpg new file mode 100644 index 00000000..2c674ad3 Binary files /dev/null and b/samples/node/media/firefighter.jpg differ diff --git a/samples/node/media/jetpack.jpg b/samples/node/media/jetpack.jpg new file mode 100644 index 00000000..7cd3c7f7 Binary files /dev/null and b/samples/node/media/jetpack.jpg differ diff --git a/samples/node/media/piranha.jpg b/samples/node/media/piranha.jpg new file mode 100644 index 00000000..75e54b80 Binary files /dev/null and b/samples/node/media/piranha.jpg differ diff --git a/samples/node/media/samplesmall.mp3 b/samples/node/media/samplesmall.mp3 new file mode 100644 index 00000000..32732d9a Binary files /dev/null and b/samples/node/media/samplesmall.mp3 differ diff --git a/samples/node/simple-text-and-images.js b/samples/node/simple-text-and-images.js deleted file mode 100644 index 8789b391..00000000 --- a/samples/node/simple-text-and-images.js +++ /dev/null @@ -1,37 +0,0 @@ -/** - * @license - * Copyright 2023 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. - */ - -import { genAI, fileToGenerativePart, streamToStdout } from "./utils/common.js"; - -async function run() { - const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash-latest" }); - - const prompt = "What do you see?"; - - // Note: The only accepted mime types are some image types, image/*. - const imageParts = [ - fileToGenerativePart("./utils/cat.jpg", "image/jpeg"), - fileToGenerativePart("./utils/scones.jpg", "image/jpeg"), - ]; - - const result = await model.generateContent([prompt, ...imageParts]); - const response = result.response; - const text = response.text(); - console.log(text); -} - -run(); diff --git a/samples/node/simple-text.js b/samples/node/simple-text.js deleted file mode 100644 index 1028fe4e..00000000 --- a/samples/node/simple-text.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @license - * Copyright 2023 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. - */ - -import { genAI } from "./utils/common.js"; - -async function run() { - const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash-latest" }); - - const prompt = "Write a story about a magic backpack."; - - const { totalTokens } = await model.countTokens(prompt); - console.log("Tokens count:", totalTokens); - - const result = await model.generateContent(prompt); - const response = result.response; - const text = response.text(); - console.log(text); -} - -run(); diff --git a/samples/node/text_generation.js b/samples/node/text_generation.js new file mode 100644 index 00000000..d5a2e4e9 --- /dev/null +++ b/samples/node/text_generation.js @@ -0,0 +1,305 @@ +/** + * @license + * Copyright 2024 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. + */ + +import { GoogleGenerativeAI } from "@google/generative-ai"; +import { GoogleAIFileManager, FileState } from "@google/generative-ai/server"; +import fs from "fs"; +import { dirname } from "path"; +import { fileURLToPath } from "url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const mediaPath = __dirname + "/media"; + +async function textGenTextOnlyPrompt() { + // [START text_gen_text_only_prompt] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + const prompt = "Write a story about a magic backpack."; + + const result = await model.generateContent(prompt); + const response = result.response; + const text = response.text(); + console.log(text); + // [END text_gen_text_only_prompt] +} + +async function textGenTextOnlyPromptStreaming() { + // [START text_gen_text_only_prompt_streaming] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + const prompt = "Write a story about a magic backpack."; + + const result = await model.generateContentStream(prompt); + + // Print text as it comes in. + for await (const chunk of result.stream) { + const chunkText = chunk.text(); + console.log(chunkText); + } + // [END text_gen_text_only_prompt_streaming] +} + +async function textGenMultimodalOneImagePrompt() { + // [START text_gen_multimodal_one_image_prompt] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + function fileToGenerativePart(path, mimeType) { + return { + inlineData: { + data: Buffer.from(fs.readFileSync(path)).toString("base64"), + mimeType, + }, + }; + } + + const prompt = "Describe how this product might be manufactured."; + // Note: The only accepted mime types are some image types, image/*. + const imagePart = fileToGenerativePart( + `${mediaPath}/jetpack.jpg`, + "image/jpeg", + ); + + const result = await model.generateContent([prompt, imagePart]); + const response = result.response; + const text = response.text(); + console.log(text); + // [END text_gen_multimodal_one_image_prompt] +} + +async function textGenMultimodalOneImagePromptStreaming() { + // [START text_gen_multimodal_one_image_prompt_streaming] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + function fileToGenerativePart(path, mimeType) { + return { + inlineData: { + data: Buffer.from(fs.readFileSync(path)).toString("base64"), + mimeType, + }, + }; + } + + const prompt = "Describe how this product might be manufactured."; + // Note: The only accepted mime types are some image types, image/*. + const imagePart = fileToGenerativePart( + `${mediaPath}/jetpack.jpg`, + "image/jpeg", + ); + + const result = await model.generateContentStream([prompt, imagePart]); + + // Print text as it comes in. + for await (const chunk of result.stream) { + const chunkText = chunk.text(); + console.log(chunkText); + } + // [END text_gen_multimodal_one_image_prompt_streaming] +} + +async function textGenMultimodalMultiImagePrompt() { + // [START text_gen_multimodal_multi_image_prompt] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + function fileToGenerativePart(path, mimeType) { + return { + inlineData: { + data: Buffer.from(fs.readFileSync(path)).toString("base64"), + mimeType, + }, + }; + } + + const prompt = + "Write an advertising jingle showing how the product in the" + + " first image could solve the problems shown in the second two images."; + + // Note: The only accepted mime types are some image types, image/*. + const imageParts = [ + fileToGenerativePart(`${mediaPath}/jetpack.jpg`, "image/jpeg"), + fileToGenerativePart(`${mediaPath}/piranha.jpg`, "image/jpeg"), + fileToGenerativePart(`${mediaPath}/firefighter.jpg`, "image/jpeg"), + ]; + + const result = await model.generateContent([prompt, ...imageParts]); + const response = result.response; + const text = response.text(); + console.log(text); + // [END text_gen_multimodal_multi_image_prompt] +} + +async function textGenMultimodalMultiImagePromptStreaming() { + // [START text_gen_multimodal_multi_image_prompt_streaming] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + function fileToGenerativePart(path, mimeType) { + return { + inlineData: { + data: Buffer.from(fs.readFileSync(path)).toString("base64"), + mimeType, + }, + }; + } + + const prompt = + "Write an advertising jingle showing how the product in the" + + " first image could solve the problems shown in the second two images."; + + // Note: The only accepted mime types are some image types, image/*. + const imageParts = [ + fileToGenerativePart(`${mediaPath}/jetpack.jpg`, "image/jpeg"), + fileToGenerativePart(`${mediaPath}/piranha.jpg`, "image/jpeg"), + fileToGenerativePart(`${mediaPath}/firefighter.jpg`, "image/jpeg"), + ]; + + const result = await model.generateContentStream([prompt, ...imageParts]); + + // Print text as it comes in. + for await (const chunk of result.stream) { + const chunkText = chunk.text(); + console.log(chunkText); + } + // [END text_gen_multimodal_multi_image_prompt_streaming] +} + +async function textGenMultimodalAudio() { + // [START text_gen_multimodal_audio] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + function fileToGenerativePart(path, mimeType) { + return { + inlineData: { + data: Buffer.from(fs.readFileSync(path)).toString("base64"), + mimeType, + }, + }; + } + + const prompt = "Give me a summary of this audio file."; + // Note: The only accepted mime types are some image types, image/*. + const audioPart = fileToGenerativePart( + `${mediaPath}/samplesmall.mp3`, + "audio/mp3", + ); + + const result = await model.generateContent([prompt, audioPart]); + const response = result.response; + const text = response.text(); + console.log(text); + // [END text_gen_multimodal_audio] +} + +async function textGenMultimodalVideoPrompt() { + // [START text_gen_multimodal_video_prompt] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + const fileManager = new GoogleAIFileManager(process.env.API_KEY); + + const uploadResult = await fileManager.uploadFile( + `${mediaPath}/Big_Buck_Bunny.mp4`, + { mimeType: "video/mp4" }, + ); + + let file = await fileManager.getFile(uploadResult.file.name); + while (file.state === FileState.PROCESSING) { + process.stdout.write("."); + // Sleep for 10 seconds + await new Promise((resolve) => setTimeout(resolve, 10_000)); + // Fetch the file from the API again + file = await fileManager.getFile(uploadResult.file.name); + } + + if (file.state === FileState.FAILED) { + throw new Error("Video processing failed."); + } + + const prompt = "Describe this video clip"; + const videoPart = { + fileData: { + fileUri: uploadResult.file.uri, + mimeType: uploadResult.file.mimeType, + }, + }; + + const result = await model.generateContent([prompt, videoPart]); + const response = result.response; + const text = response.text(); + console.log(text); + // [END text_gen_multimodal_video_prompt] +} + +async function textGenMultimodalVideoPromptStreaming() { + // [START text_gen_multimodal_video_prompt_streaming] + const genAI = new GoogleGenerativeAI(process.env.API_KEY); + const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" }); + + const fileManager = new GoogleAIFileManager(process.env.API_KEY); + + const uploadResult = await fileManager.uploadFile( + `${mediaPath}/Big_Buck_Bunny.mp4`, + { mimeType: "video/mp4" }, + ); + + let file = await fileManager.getFile(uploadResult.file.name); + while (file.state === FileState.PROCESSING) { + process.stdout.write("."); + // Sleep for 10 seconds + await new Promise((resolve) => setTimeout(resolve, 10_000)); + // Fetch the file from the API again + file = await fileManager.getFile(uploadResult.file.name); + } + + if (file.state === FileState.FAILED) { + throw new Error("Video processing failed."); + } + + const prompt = "Describe this video clip"; + const videoPart = { + fileData: { + fileUri: uploadResult.file.uri, + mimeType: uploadResult.file.mimeType, + }, + }; + + const result = await model.generateContent([prompt, videoPart]); + const response = result.response; + const text = response.text(); + console.log(text); + // [END text_gen_multimodal_video_prompt_streaming] +} + +async function runAll() { + // Comment out or delete any sample cases you don't want to run. + await textGenTextOnlyPrompt(); + await textGenTextOnlyPromptStreaming(); + await textGenMultimodalOneImagePrompt(); + await textGenMultimodalOneImagePromptStreaming(); + await textGenMultimodalMultiImagePrompt(); + await textGenMultimodalMultiImagePromptStreaming(); + await textGenMultimodalAudio(); + await textGenMultimodalVideoPrompt(); + await textGenMultimodalVideoPromptStreaming(); +} + +runAll(); diff --git a/samples/node/utils/cat.jpg b/samples/node/utils/cat.jpg deleted file mode 100644 index 8d2069e6..00000000 Binary files a/samples/node/utils/cat.jpg and /dev/null differ diff --git a/samples/node/utils/scones.jpg b/samples/node/utils/scones.jpg deleted file mode 100644 index ce689588..00000000 Binary files a/samples/node/utils/scones.jpg and /dev/null differ diff --git a/samples/web/README.md b/samples/web/README.md deleted file mode 100644 index 9149689a..00000000 --- a/samples/web/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# Google Generative AI Sample for Web (Javascript) - -This sample app demonstrates how to use state-of-the-art -generative AI models (like Gemini) to build AI-powered features and applications. - -To try out this sample app, you'll need a modern web browser and a local http server. - -## Requirements - -Follow the instructions on Google AI Studio [setup page](https://makersuite.google.com/app/apikey) to obtain an API key. - -It’s strongly recommended that you do not check an API key into your version control system. Instead, you should use a secrets store for your API key. - -The Node.js http server provided alonside this app (`http-server.js`) assumes that you're providing an `API_KEY` environment variable. - -## Features - -This sample showcases the following API capablilites: - -- `index.html` - demonstrates the Text and MultiModal feature from the SDK -- `chat.html` - demonstrates the Multi-turn Conversations feature from the SDK - -## Documentation - -- [Quickstart: Get started with the Gemini API in web apps](https://ai.google.dev/tutorials/web_quickstart) diff --git a/samples/web/chat.html b/samples/web/chat.html deleted file mode 100644 index 7f6987c6..00000000 --- a/samples/web/chat.html +++ /dev/null @@ -1,96 +0,0 @@ - - - -
- - - - -