-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move node samples to top level, restore web samples (#206)
- Loading branch information
Showing
31 changed files
with
546 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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`, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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": "*" | ||
} | ||
} |
Oops, something went wrong.