Skip to content

Commit

Permalink
Move node samples to top level, restore web samples (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
hsubox76 authored Jul 11, 2024
1 parent 23f5fdb commit 02a9a26
Show file tree
Hide file tree
Showing 31 changed files with 546 additions and 9 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const { GoogleGenerativeAI } = require("@google/generative-ai");

const genAI = new GoogleGenerativeAI(process.env.API_KEY);

const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash-latest" });
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
```

1. Run a prompt
Expand Down Expand Up @@ -72,11 +72,14 @@ access and utilize the Gemini model for various use cases.
1. [Obtain an API key](https://makersuite.google.com/app/apikey) to use with
the Google AI SDKs.

1. cd into the `samples/node` folder and run `npm install`.
2. cd into the `samples` folder and run `npm install`.

1. Assign your API key to an environment variable: `export API_KEY=MY_API_KEY`.
3. Assign your API key to an environment variable: `export API_KEY=MY_API_KEY`.

1. Run the sample file you're interested in. Example: `node simple-text.js`.
4. Open the sample file you're interested in. Example: `text_generation.js`.
In the `runAll()` function, comment out any samples you don't want to run.

5. Run the sample file. Example: `node text_generation.js`.

## Documentation

Expand Down
11 changes: 7 additions & 4 deletions packages/main/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const { GoogleGenerativeAI } = require("@google/generative-ai");

const genAI = new GoogleGenerativeAI(process.env.API_KEY);

const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash-latest" });
const model = genAI.getGenerativeModel({ model: "gemini-1.5-flash" });
```

1. Run a prompt
Expand Down Expand Up @@ -72,11 +72,14 @@ access and utilize the Gemini model for various use cases.
1. [Obtain an API key](https://makersuite.google.com/app/apikey) to use with
the Google AI SDKs.

1. cd into the `samples/node` folder and run `npm install`.
2. cd into the `samples` folder and run `npm install`.

1. Assign your API key to an environment variable: `export API_KEY=MY_API_KEY`.
3. Assign your API key to an environment variable: `export API_KEY=MY_API_KEY`.

1. Run the sample file you're interested in. Example: `node simple-text.js`.
4. Open the sample file you're interested in. Example: `text_generation.js`.
In the `runAll()` function, comment out any samples you don't want to run.

5. Run the sample file. Example: `node text_generation.js`.

## Documentation

Expand Down
4 changes: 3 additions & 1 deletion samples/node/README.md → samples/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Google Generative AI Sample for Node.js (Javascript)
# Google Generative AI Samples for JavaScript

These samples demonstrate how to use state-of-the-art
generative AI models (like Gemini) to build AI-powered features and applications.

To try out these samples, you'll need Node.js v18+.

For some samples of how to adapt this to web, see the `web/` subdirectory.

## Requirements

Follow the instructions on Google AI Studio [setup page](https://makersuite.google.com/app/apikey) to obtain an API key.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
25 changes: 25 additions & 0 deletions samples/web/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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)
96 changes: 96 additions & 0 deletions samples/web/chat.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<!doctype html>
<!--
* @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.
-->
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" type="image/svg+xml" href="favicon.svg" />
<link rel="stylesheet" href="utils/main.css" />
<link
href="https://fonts.googleapis.com/css?family=Roboto:400,700"
rel="stylesheet"
type="text/css"
/>
<title>Generative AI - Chat</title>
</head>

<body>
<header>Generative AI - Chat</header>
<div class="container">
<div id="chat-history"></div>
</div>
<div class="form-container">
<form id="form">
<input id="prompt" />
<button type="submit">Send</button>
</form>
<template id="thumb-template">
<img class="thumb" />
</template>
</div>

<script type="module">
import {
getGenerativeModel,
scrollToDocumentBottom,
updateUI,
} from "./utils/shared.js";

const promptInput = document.querySelector("#prompt");
const historyElement = document.querySelector("#chat-history");
let chat;

document
.querySelector("#form")
.addEventListener("submit", async (event) => {
event.preventDefault();

if (!chat) {
const model = await getGenerativeModel({ model: "gemini-1.5-flash" });
chat = model.startChat({
generationConfig: {
maxOutputTokens: 100,
},
});
}

const userMessage = promptInput.value;
promptInput.value = "";

// Create UI for the new user / assistant messages pair
historyElement.innerHTML += `<div class="history-item user-role">
<div class="name">User</div>
<blockquote>${userMessage}</blockquote>
</div>
<div class="history-item model-role">
<div class="name">Model</div>
<blockquote></blockquote>
</div>`;

scrollToDocumentBottom();
const resultEls = document.querySelectorAll(
".model-role > blockquote",
);
await updateUI(
resultEls[resultEls.length - 1],
() => chat.sendMessageStream(userMessage),
true,
);
});
</script>
</body>
</html>
1 change: 1 addition & 0 deletions samples/web/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
87 changes: 87 additions & 0 deletions samples/web/http-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* @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 fs from "fs";
import http from "http";
import path from "path";
import url from "url";

// Local port for http server to listen on
const PORT = 9000;

// Get your API key from https://makersuite.google.com/app/apikey
// Access your API key as an environment variable
const API_KEY = process.env.API_KEY;

if (!API_KEY) {
throw new Error("API_KEY environment variable not set");
}

// Maps file extention to MIME types
// Full list can be found here: https://www.freeformatter.com/mime-types-list.html
const mimeType = {
".html": "text/html",
".js": "text/javascript",
".mjs": "text/javascript",
".css": "text/css",
};

http
.createServer((req, res) => {
console.log(` ${req.method} ${req.url}`);

// Parse URL
const parsedUrl = url.parse(req.url);

// Extract URL path
// Avoid https://en.wikipedia.org/wiki/Directory_traversal_attack
let sanitizedPath = path
.normalize(parsedUrl.pathname)
.replace(/^(\.\.[\/\\])+/, "")
.substring(1);

if (sanitizedPath === "API_KEY") {
res.end(API_KEY);
return;
}

if (sanitizedPath === "") {
sanitizedPath = "index.html";
}

// based on the URL path, extract the file extention. e.g. .js, .doc, ...
const ext = path.parse(sanitizedPath).ext;

try {
const data = fs.readFileSync(sanitizedPath);

// If the file is found, set Content-Type and send data
if (mimeType[ext]) {
res.setHeader("Content-Type", mimeType[ext]);
}
res.end(data);
} catch (err) {
// If the file is not found, return 404
res.statusCode = 404;
res.end();
}
})
.listen(parseInt(PORT));

console.log(
`Server listening. Pages:\n - http://localhost:${PORT}\n - http://localhost:${PORT}/chat.html`,
);
91 changes: 91 additions & 0 deletions samples/web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<!doctype html>
<!--
* @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.
-->
<html>
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" type="image/svg+xml" href="favicon.svg" />
<link rel="stylesheet" href="utils/main.css" />
<link
href="https://fonts.googleapis.com/css?family=Roboto:400,700"
rel="stylesheet"
type="text/css"
/>
<title>Generative AI - Text and Image</title>
</head>

<body>
<header>Generative AI - Text and Image</header>
<div class="form-container">
<form id="form">
<input type="file" id="file'" multiple />
<input id="prompt" />
<button type="submit">Send</button>
</form>
<div id="thumbnails"></div>
</div>
<div class="container">
<blockquote id="result"></blockquote>
</div>

<script type="module">
import {
getGenerativeModel,
fileToGenerativePart,
updateUI,
} from "./utils/shared.js";

async function run(prompt, files) {
const imageParts = await Promise.all(
[...files].map(fileToGenerativePart),
);

const model = await getGenerativeModel({
model: "gemini-1.5-flash",
});

return model.generateContentStream([...imageParts, prompt]);
}

const fileInputEl = document.querySelector("input[type=file]");
const thumbnailsEl = document.querySelector("#thumbnails");

fileInputEl.addEventListener("input", () => {
thumbnailsEl.innerHTML = "";
for (const file of fileInputEl.files) {
const url = URL.createObjectURL(file);
thumbnailsEl.innerHTML += `<img class="thumb" src="${url}" onload="window.URL.revokeObjectURL(this.src)" />`;
}
});

document
.querySelector("#form")
.addEventListener("submit", async (event) => {
event.preventDefault();

const promptEl = document.querySelector("#prompt");
const resultEl = document.querySelector("#result");

updateUI(
resultEl,
() => run(promptEl.value, fileInputEl.files),
true,
);
});
</script>
</body>
</html>
10 changes: 10 additions & 0 deletions samples/web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"type": "module",
"scripts": {
"start": "node http-server.js",
"http-server": "node http-server.js"
},
"dependencies": {
"@google/generative-ai": "*"
}
}
Loading

0 comments on commit 02a9a26

Please sign in to comment.