Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global LanguageModel */
chrome.runtime.onInstalled.addListener(() => {
chrome.contextMenus.create({
id: 'generateAltText',
Expand All @@ -7,9 +8,7 @@ chrome.runtime.onInstalled.addListener(() => {
});
async function generateAltText(imgSrc) {
// Create the model (we're not checking availability here, but will simply fail with an exception
const session = await self.LanguageModel.create({
temperature: 0.0,
topK: 1.0,
const session = await LanguageModel.create({
expectedInputs: [{ type: 'image' }]
});

Expand Down
80 changes: 38 additions & 42 deletions functional-samples/ai.gemini-on-device-calendar-mate/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,7 @@ function createGoogleCalendarUrl(eventDetails) {
}

async function parseEventDetails(text) {
const session = await LanguageModel.create({
temperature: 0,
topK: 1.0
});
const session = await LanguageModel.create();

let prompt = `
The following text describes an event. Extract "title", "start_time", "start_date", "start_year", "end_time", "end_date", "end_year", "description", "timezone" and "location" of the event. Return only JSON as result.
Expand All @@ -99,43 +96,42 @@ async function parseEventDetails(text) {

${text}`;

const result = await session.prompt(prompt);
return JSON.parse(fixCommonJSONMistakes(result), null, ' ');
}

function addCommaBetweenQuotes(str) {
return str.replace(/"([^"]*)"\s+"([^"]*)"/g, '"$1", "$2"');
}

function extractTextBetweenCurlyBraces(str) {
if (str[0] === '[') return str;
const firstBraceIndex = str.indexOf('{');
const lastBraceIndex = str.lastIndexOf('}');

if (firstBraceIndex === -1 || lastBraceIndex === -1) {
return null; // No curly braces found
}

return str.substring(firstBraceIndex, lastBraceIndex + 1);
}

function curlyToBrackets(str) {
// Check if the input is a string
if (typeof str !== 'string') {
return 'Input must be a string.';
}

// Use a regular expression to match curly braces with quoted strings inside
return str.replace(/\{("([^"]*)"(?:,\s*)?)*\}/g, function (match) {
// Remove curly braces and replace with brackets
return '[' + match.slice(1, -1) + ']';
});
}
const schema = {
type: 'object',
properties: {
title: { type: 'string' },
start_time: { type: 'string' },
start_date: { type: 'string' },
start_year: { type: 'string' },
end_time: { type: 'string' },
end_date: { type: 'string' },
end_year: { type: 'string' },
description: { type: 'string' },
timezone: { type: 'string' },
location: { type: 'string' }
},
required: [
'title',
'start_time',
'start_date',
'start_year',
'end_time',
'end_date',
'end_year',
'description',
'timezone',
'location'
]
};

const result = await session.prompt(
[
{ role: 'user', content: prompt },
{ role: 'assistant', content: '{', prefix: true }
],
{ responseConstraint: schema }
);

function fixCommonJSONMistakes(str) {
str = str.trim();
str = curlyToBrackets(str);
str = extractTextBetweenCurlyBraces(str);
str = addCommaBetweenQuotes(str);
return str;
session.destroy();
return JSON.parse('{' + result);
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async function generateSummary(text) {
length: length.value
};

const availability = await Summarizer.availability();
const availability = await Summarizer.availability(options);
let summarizer;
if (availability === 'unavailable') {
return 'Summarizer API is not available';
Expand All @@ -76,9 +76,13 @@ async function generateSummary(text) {
summarizer = await Summarizer.create(options);
} else {
// The Summarizer API can be used after the model is downloaded.
summarizer = await Summarizer.create(options);
summarizer.addEventListener('downloadprogress', (e) => {
console.log(`Downloaded ${e.loaded * 100}%`);
summarizer = await Summarizer.create({
...options,
monitor(m) {
m.addEventListener('downloadprogress', (e) => {
console.log(`Downloaded ${e.loaded * 100}%`);
});
}
});
await summarizer.ready;
}
Expand Down
17 changes: 0 additions & 17 deletions functional-samples/ai.gemini-on-device/sidepanel/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,6 @@
cols="30"
rows="5"
></textarea>
<div>
<input
type="range"
id="temperature"
name="temperature"
min="0"
max="2"
step="0.01"
/>
<label for="temperature"
>Temperature: <span id="label-temperature"></span
></label>
</div>
<div>
<input type="range" id="top-k" name="top-k" min="1" max="8" step="1" />
<label for="top-k">Top-k: <span id="label-top-k"></span></label>
</div>
<button id="button-prompt" class="primary" disabled>Run</button>
<button id="button-reset" class="secondary" disabled>Reset</button>
<div id="response" class="text" hidden></div>
Expand Down
33 changes: 1 addition & 32 deletions functional-samples/ai.gemini-on-device/sidepanel/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ const buttonReset = document.body.querySelector('#button-reset');
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 sliderTopK = document.body.querySelector('#top-k');
const labelTemperature = document.body.querySelector('#label-temperature');
const labelTopK = document.body.querySelector('#label-top-k');

let session;

Expand Down Expand Up @@ -40,25 +36,10 @@ async function reset() {
}

async function initDefaults() {
const defaults = await LanguageModel.params();
console.log('Model default:', defaults);
if (!('LanguageModel' in self)) {
showResponse('Model not available');
return;
}
sliderTemperature.value = defaults.defaultTemperature;
// Pending https://issues.chromium.org/issues/367771112.
// sliderTemperature.max = defaults.maxTemperature;
if (defaults.defaultTopK > 3) {
// limit default topK to 3
sliderTopK.value = 3;
labelTopK.textContent = 3;
} else {
sliderTopK.value = defaults.defaultTopK;
labelTopK.textContent = defaults.defaultTopK;
}
sliderTopK.max = defaults.maxTopK;
labelTemperature.textContent = defaults.defaultTemperature;
}

initDefaults();
Expand All @@ -71,16 +52,6 @@ buttonReset.addEventListener('click', () => {
buttonReset.setAttribute('disabled', '');
});

sliderTemperature.addEventListener('input', (event) => {
labelTemperature.textContent = event.target.value;
reset();
});

sliderTopK.addEventListener('input', (event) => {
labelTopK.textContent = event.target.value;
reset();
});

inputPrompt.addEventListener('input', () => {
if (inputPrompt.value.trim()) {
buttonPrompt.removeAttribute('disabled');
Expand All @@ -96,9 +67,7 @@ buttonPrompt.addEventListener('click', async () => {
const params = {
initialPrompts: [
{ role: 'system', content: 'You are a helpful and friendly assistant.' }
],
temperature: sliderTemperature.value,
topK: sliderTopK.value
]
};
const response = await runPrompt(prompt, params);
showResponse(response);
Expand Down
Loading