Improve prompt API sample (#1344)

* Improve prompt API sample

* Render response as markdown
* Fix initial maxK and temperature values
* Add privacy statement (for webstore submission)
* Regenerate key and trial token

* fix formatting errors

* Update functional-samples/ai.gemini-on-device/sidepanel/index.js

Update maxTemperature

Co-authored-by: Thomas Steiner <tomac@google.com>

* Update functional-samples/ai.gemini-on-device/sidepanel/index.js

Better string comparison

Co-authored-by: Thomas Steiner <tomac@google.com>

---------

Co-authored-by: Thomas Steiner <tomac@google.com>
This commit is contained in:
Sebastian Benz
2024-11-08 15:35:27 +01:00
committed by GitHub
parent d2fd736ac0
commit 69f946b35e
10 changed files with 1577 additions and 20 deletions

1
.gitignore vendored
View File

@@ -4,4 +4,5 @@ node_modules
# Temporary directory for debugging extension samples
_debug
_metadata
dist
*.swp # vim temp files

View File

@@ -1,3 +1,4 @@
_archive
third-party
node_modules
dist

View File

@@ -0,0 +1,3 @@
dist
node_modules
*.swp

View File

@@ -1,14 +1,14 @@
{
"name": "Chrome Built-in AI Demo",
"name": "Chrome Prompt AI Demo",
"version": "0.1",
"manifest_version": 3,
"description": "Try the built-in AI preview in Chrome.",
"description": "Try Chrome's built-in prompt API.",
"background": {
"service_worker": "background.js"
},
"permissions": ["sidePanel", "aiLanguageModelOriginTrial"],
"trial_tokens": ["A6hC1yvazc5QTqSESgEo3uwIUs1KBM4VB93yiTdtgFlFlYNJjf18zmzScpaCepaYpNLaMJ4dNkDps+vbrk7oEw8AAAB9eyJvcmlnaW4iOiAiY2hyb21lLWV4dGVuc2lvbjovL2lkZm1qYmJqY21qamtoYWlvZmltbWNtY29qYmlnbmpmIiwgImZlYXR1cmUiOiAiQUlQcm9tcHRBUElGb3JFeHRlbnNpb24iLCAiZXhwaXJ5IjogMTk4OTQwNzUwMH0="],
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi99ZKuRYfZMQ80XryBYKNA4DJTHPMEiNkiF6TLqTXMp4Cb23I/DTblxlEELWyM1vDuXeFI7jqXDuM6YVHd7zTtA1hGbGgLm9w9+d763x2wCRbxud+dXIXW4IoD4CqXpCLscDD7Vrar/I5XbcmdA9jjlCXMGS2OKNRhYMjNpaVhFCi2jzWid+92DZSpPbdM9iBODGfwnFNp16tFX8/dDx3w23FneeOVHV3JjNIWO3uT60AhZWOtcQlERuMBJmEkKAgqE8T3ZjoZe4ALupfvDxI7khP29+gBXhgF/r6T0RAbB1LfxubhyLk/X7aC/sw3umCemqvc+knvKRBLHMVl1nHQIDAQAB",
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvf0O/bR3JULoj6dOpG7sDif4BNVgootUIfSybh2a7jX47BglfZFNH/aRUgDjNtcTBPinXdGbljMVIudQ7w6LiwVq9b1Ht6ZXFVtHTKOsDWtVh/rVKE/AGue9eQ7xCncHFl4zLJUaDRUIRqe5zvjHtaMr8p92I3c/6k43LmTUp1QHz0NooDJRYKRPLS77YVDX8hZc2yopIH5NIY25Ned3wxZ/NWV70GZkYqFRN+UzvMS8bJUEY23L1AMSX7YQjMThY0BCZ/MBLo8UBLs8vN11EphMpLxnBhF2Zwwj2sCPR0jn0ev8HYCtKmGx8nzOl79oK24RFIsW8YWFB2fd28fBLwIDAQAB",
"trial_tokens": ["Aozzz6KfHYqh8q5x+Khse27nSp8YM7Tftv6XZhNO7lgYcP5uQxxBEpMfRhiFbYJV+yJl1fDNzvtao7FswtZGIgQAAAB4eyJvcmlnaW4iOiJjaHJvbWUtZXh0ZW5zaW9uOi8vYWhpaWZrb2RnbWlmcGNnbmRja3BwaW1lY25wa3BkbGwiLCJmZWF0dXJlIjoiQUlQcm9tcHRBUElGb3JFeHRlbnNpb24iLCJleHBpcnkiOjE3NjA0ODYzOTl9"],
"minimum_chrome_version": "131",
"side_panel": {
"default_path": "sidepanel/index.html"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
{
"name": "Chrome Prompt API Example",
"private": true,
"version": "1.0.0",
"description": "",
"main": "background.js",
"scripts": {
"build": "rollup -c rollup.config.mjs"
},
"keywords": [],
"license": "Apache 2.0",
"devDependencies": {
"dompurify": "3.1.6",
"marked": "14.1.2",
"@rollup/plugin-commonjs": "26.0.1",
"@rollup/plugin-node-resolve": "15.2.3",
"rollup": "4.22.4",
"rollup-plugin-copy": "3.5.0"
}
}

View File

@@ -0,0 +1 @@
This extension does not collect, use or share any user data.

View File

@@ -0,0 +1,29 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import copy from 'rollup-plugin-copy';
export default [
{
input: 'sidepanel/index.js',
output: {
dir: 'dist/sidepanel',
format: 'iife',
},
plugins: [
nodeResolve({
jsnext: true,
main: true,
browser: true
}),
commonjs(),
copy({
targets: [
{
src: ['manifest.json', 'background.js', 'sidepanel', 'images'],
dest: 'dist'
}
]
})
]
}
];

View File

@@ -4,7 +4,6 @@
<link rel="stylesheet" type="text/css" href="index.css" />
</head>
<body>
<h1>Chrome built-in AI</h1>
<textarea
id="input-prompt"
placeholder='Type something, e.g. "Write a haiku about Chrome Extensions"'
@@ -25,7 +24,7 @@
></label>
</div>
<div>
<input type="range" id="top-k" name="top-k" min="1" max="50" step="1" />
<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>

View File

@@ -1,3 +1,6 @@
import DOMPurify from 'dompurify';
import { marked } from 'marked';
const inputPrompt = document.body.querySelector('#input-prompt');
const buttonPrompt = document.body.querySelector('#button-prompt');
const buttonReset = document.body.querySelector('#button-reset');
@@ -41,11 +44,19 @@ async function initDefaults() {
}
const defaults = await chrome.aiOriginTrial.languageModel.capabilities();
console.log('Model default:', defaults);
sliderTemperature.value = defaults.temperature;
sliderTopK.value = defaults.topK;
labelTopK.textContent = defaults.topK;
labelTemperature.textContent = defaults.temperature;
labelTemperature.value = defaults.temperature;
if (defaults.available !== 'readily') {
showResponse(
`Model not yet available (current state: "${defaults.available}")`
);
return;
}
sliderTemperature.value = defaults.defaultTemperature;
// sliderTemperature.max = defaults.maxTemperature;
// Pending https://issues.chromium.org/issues/367771112.
sliderTopK.value = defaults.defaultTopK;
sliderTopK.max = defaults.maxTopK;
labelTopK.textContent = defaults.defaultTopK;
labelTemperature.textContent = defaults.defaultTemperature;
}
initDefaults();
@@ -101,15 +112,7 @@ function showLoading() {
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 (const paragraph of paragraphs) {
if (paragraph) {
elementResponse.appendChild(document.createTextNode(paragraph));
}
elementResponse.appendChild(document.createElement('BR'));
}
elementResponse.innerHTML = DOMPurify.sanitize(marked.parse(response));
}
function showError(error) {