Files
chrome-extensions-samples/functional-samples/ai.gemini-in-the-cloud/sidepanel/index.js
Sebastian Benz 005f7caa65 add Gemini API sample (#1240)
* add Gemini API sample

* Simplify configuration and fix response formatting

* Update wording for gemini nano sample
2024-07-25 12:08:13 +02:00

128 lines
3.4 KiB
JavaScript

import {
GoogleGenerativeAI,
HarmBlockThreshold,
HarmCategory
} from '../node_modules/@google/generative-ai/dist/index.mjs';
// Important! Do not expose your API in your extension code. You have to
// options:
//
// 1. Let users provide their own API key.
// 2. Manage API keys in your own server and proxy all calls to the Gemini
// API through your own server, where you can implement additional security
// measures such as authentification.
//
// It is only OK to put your API key into this file if you're the only
// user of your extension or for testing.
const apiKey = '...';
let genAI = null;
let model = null;
let generationConfig = {
temperature: 1
};
const inputPrompt = document.body.querySelector('#input-prompt');
const buttonPrompt = document.body.querySelector('#button-prompt');
const elementResponse = document.body.querySelector('#response');
const elementLoading = document.body.querySelector('#loading');
const elementError = document.body.querySelector('#error');
const sliderTemperature = document.body.querySelector('#temperature');
const labelTemperature = document.body.querySelector('#label-temperature');
function initModel(generationConfig) {
const safetySettings = [
{
category: HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
threshold: HarmBlockThreshold.BLOCK_NONE
}
];
genAI = new GoogleGenerativeAI(apiKey);
model = genAI.getGenerativeModel({
model: 'gemini-1.5-flash',
safetySettings,
generationConfig
});
return model;
}
async function runPrompt(prompt) {
try {
const result = await model.generateContent(prompt);
const response = await result.response;
return response.text();
} catch (e) {
console.log('Prompt failed');
console.error(e);
console.log('Prompt:', prompt);
throw e;
}
}
sliderTemperature.addEventListener('input', (event) => {
labelTemperature.textContent = event.target.value;
generationConfig.temperature = event.target.value;
});
inputPrompt.addEventListener('input', () => {
if (inputPrompt.value.trim()) {
buttonPrompt.removeAttribute('disabled');
} else {
buttonPrompt.setAttribute('disabled', '');
}
});
buttonPrompt.addEventListener('click', async () => {
const prompt = inputPrompt.value.trim();
showLoading();
try {
const generationConfig = {
temperature: sliderTemperature.value
};
initModel(generationConfig);
const response = await runPrompt(prompt, generationConfig);
showResponse(response);
} catch (e) {
showError(e);
}
});
function showLoading() {
hide(elementResponse);
hide(elementError);
show(elementLoading);
}
function showResponse(response) {
hide(elementLoading);
show(elementResponse);
// Make sure to preserve line breaks in the response
elementResponse.textContent = '';
const paragraphs = response.split(/\r?\n/);
for (let i = 0; i < paragraphs.length; i++) {
const paragraph = paragraphs[i];
if (paragraph) {
elementResponse.appendChild(document.createTextNode(paragraph));
}
// Don't add a new line after the final paragraph
if (i < paragraphs.length - 1) {
elementResponse.appendChild(document.createElement('BR'));
}
}
}
function showError(error) {
show(elementError);
hide(elementResponse);
hide(elementLoading);
elementError.textContent = error;
}
function show(element) {
element.removeAttribute('hidden');
}
function hide(element) {
element.setAttribute('hidden', '');
}