Bug 1954815 - add first usage message, feedback link, visit page link r=txia,firefox-ai-ml-reviewers,atossou
Hardcode some text that gets shown on first time and additional links Differential Revision: https://phabricator.services.mozilla.com/D242045
This commit is contained in:
@@ -24,6 +24,8 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
||||
);
|
||||
|
||||
export const LinkPreview = {
|
||||
// Shared downloading state to use across multiple previews
|
||||
downloadingModel: false,
|
||||
keyboardComboActive: false,
|
||||
_windowStates: new Map(),
|
||||
linkPreviewPanelId: "link-preview-panel",
|
||||
@@ -189,6 +191,8 @@ export const LinkPreview = {
|
||||
createOGCard(doc, pageData) {
|
||||
const ogCard = doc.createElement("link-preview-card");
|
||||
ogCard.pageData = pageData;
|
||||
// Assume we need to wait if another generate is downloading.
|
||||
ogCard.showWait = this.downloadingModel;
|
||||
|
||||
if (pageData.article.textContent) {
|
||||
this.generateKeyPoints(ogCard);
|
||||
@@ -222,8 +226,14 @@ export const LinkPreview = {
|
||||
await lazy.LinkPreviewModel.generateTextAI(
|
||||
ogCard.pageData.article.textContent,
|
||||
{
|
||||
onDownload: state => {
|
||||
ogCard.showWait = state;
|
||||
this.downloadingModel = state;
|
||||
},
|
||||
onError: console.error,
|
||||
onText(text) {
|
||||
onText: text => {
|
||||
// Clear waiting in case a different generate handled download.
|
||||
ogCard.showWait = false;
|
||||
ogCard.addKeyPoint(text);
|
||||
if (--expected == 0) {
|
||||
ogCard.generating = false;
|
||||
|
||||
@@ -19,6 +19,7 @@ const MIN_WORD_COUNT = 5;
|
||||
const lazy = {};
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
createEngine: "chrome://global/content/ml/EngineProcess.sys.mjs",
|
||||
Progress: "chrome://global/content/ml/Utils.sys.mjs",
|
||||
});
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
lazy,
|
||||
@@ -233,10 +234,11 @@ export const LinkPreviewModel = {
|
||||
*
|
||||
* @param {string} inputText
|
||||
* @param {object} callbacks for progress and error
|
||||
* @param {Function} callbacks.onDownload optional for download active
|
||||
* @param {Function} callbacks.onText optional for text chunks
|
||||
* @param {Function} callbacks.onError optional for error
|
||||
*/
|
||||
async generateTextAI(inputText, { onText, onError } = {}) {
|
||||
async generateTextAI(inputText, { onDownload, onText, onError } = {}) {
|
||||
const processedInput = this.preprocessText(inputText);
|
||||
// Asssume generated text is approximately the same length as the input.
|
||||
const nPredict = Math.ceil(processedInput.length / CHARACTERS_PER_TOKEN);
|
||||
@@ -251,7 +253,8 @@ export const LinkPreviewModel = {
|
||||
|
||||
let engine;
|
||||
try {
|
||||
engine = await lazy.createEngine({
|
||||
engine = await lazy.createEngine(
|
||||
{
|
||||
backend: "wllama",
|
||||
engineId: "wllamapreview",
|
||||
kvCacheDtype: "q8_0",
|
||||
@@ -269,7 +272,15 @@ export const LinkPreviewModel = {
|
||||
useMlock: false,
|
||||
useMmap: true,
|
||||
...JSON.parse(lazy.config),
|
||||
});
|
||||
},
|
||||
data => {
|
||||
if (data.type == lazy.Progress.ProgressType.DOWNLOAD) {
|
||||
onDownload?.(
|
||||
data.statusText != lazy.Progress.ProgressStatusText.DONE
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const postProcessor = new SentencePostProcessor();
|
||||
for await (const val of engine.runWithGenerator({
|
||||
|
||||
@@ -12,6 +12,10 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
BrowserUtils: "resource://gre/modules/BrowserUtils.sys.mjs",
|
||||
});
|
||||
|
||||
// TODO put in actual link probably same as labs bug 1951144
|
||||
const FEEDBACK_LINK =
|
||||
"https://docs.google.com/spreadsheets/d/1hsG7UXGJRN8D4ViaETICDyA0gbBArzmib1qTylmIu8M";
|
||||
|
||||
/**
|
||||
* Class representing a link preview element.
|
||||
*
|
||||
@@ -19,9 +23,10 @@ ChromeUtils.defineESModuleGetters(lazy, {
|
||||
*/
|
||||
class LinkPreviewCard extends MozLitElement {
|
||||
static properties = {
|
||||
generating: { type: Number },
|
||||
generating: { type: Number }, // 0 = off, 1-4 = generating & dots state
|
||||
keyPoints: { type: Array },
|
||||
pageData: { type: Object },
|
||||
showWait: { type: Boolean },
|
||||
};
|
||||
|
||||
constructor() {
|
||||
@@ -61,11 +66,13 @@ class LinkPreviewCard extends MozLitElement {
|
||||
updated(properties) {
|
||||
if (properties.has("generating")) {
|
||||
if (this.generating > 0) {
|
||||
// Count up to 4 so that we can show 0 to 3 dots.
|
||||
this.dotsTimeout = setTimeout(
|
||||
() => (this.generating = (this.generating % 3) + 1),
|
||||
() => (this.generating = (this.generating % 4) + 1),
|
||||
500
|
||||
);
|
||||
} else {
|
||||
// Setting to false or 0 means we're done generating.
|
||||
clearTimeout(this.dotsTimeout);
|
||||
}
|
||||
}
|
||||
@@ -87,15 +94,14 @@ class LinkPreviewCard extends MozLitElement {
|
||||
metaData["og:title"] ||
|
||||
metaData["twitter:title"] ||
|
||||
metaData["html:title"] ||
|
||||
pageUrl ||
|
||||
"";
|
||||
"This link can’t be previewed";
|
||||
|
||||
const description =
|
||||
articleData.excerpt ||
|
||||
metaData["og:description"] ||
|
||||
metaData["twitter:description"] ||
|
||||
metaData.description ||
|
||||
"";
|
||||
"No Reason. Just ’cause. (better error handling incoming)";
|
||||
|
||||
const imageUrl =
|
||||
metaData["og:image"] || metaData["twitter:image:src"] || "";
|
||||
@@ -136,14 +142,31 @@ class LinkPreviewCard extends MozLitElement {
|
||||
? html`
|
||||
<div class="ai-content">
|
||||
<h3>
|
||||
Generat${this.generating ? "ing" : "ed"} key
|
||||
points${".".repeat(this.generating)}
|
||||
${this.generating
|
||||
? "Generating key points" + ".".repeat(this.generating - 1)
|
||||
: "Key points"}
|
||||
</h3>
|
||||
<ul>
|
||||
${this.keyPoints.map(item => html`<li>${item}</li>`)}
|
||||
</ul>
|
||||
<hr />
|
||||
<p>AI-generated content may be inaccurate</p>
|
||||
${this.showWait
|
||||
? html`<p>
|
||||
This may take a moment the first time you preview a link.
|
||||
Key points should appear more quickly next time.
|
||||
</p>`
|
||||
: ""}
|
||||
<p>
|
||||
Key points are AI-generated and may be wrong.
|
||||
<a @click=${this.handleLink} href=${FEEDBACK_LINK}>
|
||||
Foxfooding feedback
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<a @click=${this.handleLink} href=${pageUrl}>
|
||||
Visit original page
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
const { LinkPreview } = ChromeUtils.importESModule(
|
||||
"moz-src:///browser/components/genai/LinkPreview.sys.mjs"
|
||||
);
|
||||
const { LinkPreviewModel } = ChromeUtils.importESModule(
|
||||
"moz-src:///browser/components/genai/LinkPreviewModel.sys.mjs"
|
||||
);
|
||||
const { sinon } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/Sinon.sys.mjs"
|
||||
);
|
||||
@@ -110,7 +113,15 @@ add_task(async function test_link_preview_panel_shown() {
|
||||
set: [["browser.ml.linkPreview.enabled", true]],
|
||||
});
|
||||
|
||||
const stub = sinon.stub(LinkPreview, "generateKeyPoints");
|
||||
let onDownload, toResolve;
|
||||
const stub = sinon
|
||||
.stub(LinkPreviewModel, "generateTextAI")
|
||||
.callsFake(async (text, options) => {
|
||||
onDownload = options.onDownload;
|
||||
toResolve = Promise.withResolvers();
|
||||
return toResolve.promise;
|
||||
});
|
||||
|
||||
window.dispatchEvent(
|
||||
new KeyboardEvent("keydown", {
|
||||
bubbles: true,
|
||||
@@ -129,6 +140,28 @@ add_task(async function test_link_preview_panel_shown() {
|
||||
|
||||
is(stub.callCount, 1, "would have generated key points");
|
||||
|
||||
const card = panel.querySelector("link-preview-card");
|
||||
ok(card, "card created for link preview");
|
||||
ok(card.generating, "initially marked as generating");
|
||||
ok(!card.showWait, "initially assume not waiting");
|
||||
ok(!LinkPreview.downloadingModel, "initially assume not downloading");
|
||||
|
||||
onDownload(true);
|
||||
|
||||
ok(card.showWait, "switched to waiting when download initiates");
|
||||
ok(LinkPreview.downloadingModel, "shared waiting for download");
|
||||
|
||||
onDownload(false);
|
||||
|
||||
ok(!card.showWait, "no longer waiting after download complete");
|
||||
ok(!LinkPreview.downloadingModel, "downloading updated");
|
||||
ok(card.generating, "still generating");
|
||||
|
||||
toResolve.resolve();
|
||||
await LinkPreview.lastRequest;
|
||||
|
||||
ok(!card.generating, "done generating");
|
||||
|
||||
panel.remove();
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user