mirror of
https://github.com/GoogleChrome/chrome-extensions-samples.git
synced 2026-03-26 13:19:49 +07:00
* add Gemini API sample * Simplify configuration and fix response formatting * Update wording for gemini nano sample
128 lines
3.4 KiB
JavaScript
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', '');
|
|
}
|