Bug 1910005 - Expose chat shortcuts pref as part of experimental subitem r=tarek,fluent-reviewers,settings-reviewers,desktop-theme-reviewers,dao,mstriemer

Switch default shortcuts enabled with labs checkbox to disable and labs visibility. Add metric and event telemetry for shortcuts pref and usage. Bump pip labs ordering up one.

Differential Revision: https://phabricator.services.mozilla.com/D217782
This commit is contained in:
Ed Lee 2024-08-03 04:19:46 +00:00
Родитель acb6679fdd
Коммит 4c62bb6510
8 изменённых файлов: 266 добавлений и 29 удалений

Просмотреть файл

@ -1962,8 +1962,12 @@ pref("browser.ml.chat.prompts.0", '{"label":"Summarize","value":"Please summariz
pref("browser.ml.chat.prompts.1", '{"label":"Simplify Language","value":"Please rewrite the selection in plain, clear language suitable for a general audience without specialized knowledge. Use all of the following tactics: simple vocabulary; short sentences; active voice; headers and bulleted lists for scannability. Maintain meaning and factual accuracy.","id":"simplify"}');
pref("browser.ml.chat.prompts.2", '{"label":"Quiz Me","value":"Please quiz me on this selection. Ask me a variety of types of questions, for example multiple choice, true or false, and short answer. Wait for my response before moving on to the next question.","id":"quiz","targeting":"!provider|regExpMatch(\'gemini\')"}');
pref("browser.ml.chat.provider", "");
pref("browser.ml.chat.shortcuts", false);
pref("browser.ml.chat.shortcuts", true);
#ifdef NIGHTLY_BUILD
pref("browser.ml.chat.shortcuts.custom", true);
#else
pref("browser.ml.chat.shortcuts.custom", false);
#endif
pref("browser.ml.chat.sidebar", true);
pref("security.protectionspopup.recordEventTelemetry", true);

Просмотреть файл

@ -21,6 +21,18 @@ XPCOMUtils.defineLazyPreferenceGetter(
"chatEnabled",
"browser.ml.chat.enabled"
);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"chatHideFromLabs",
"browser.ml.chat.hideFromLabs",
false
);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"chatHideLabsShortcuts",
"browser.ml.chat.hideLabsShortcuts",
false
);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"chatHideLocalhost",
@ -61,7 +73,9 @@ XPCOMUtils.defineLazyPreferenceGetter(
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
"chatShortcuts",
"browser.ml.chat.shortcuts"
"browser.ml.chat.shortcuts",
null,
(_pref, _old, val) => onChatShortcutsChange(val)
);
XPCOMUtils.defineLazyPreferenceGetter(
lazy,
@ -175,14 +189,11 @@ export const GenAI = {
* Handle startup tasks like telemetry, adding listeners.
*/
init() {
Glean.genaiChatbot.enabled.set(lazy.chatEnabled);
Glean.genaiChatbot.provider.set(this.getProviderId());
Glean.genaiChatbot.sidebar.set(lazy.chatSidebar);
// Access getters for side effects of observing pref changes
lazy.chatHideLocalhost;
lazy.chatProvider;
lazy.chatProviders;
lazy.chatShortcuts;
// Apply initial ordering of providers
reorderChatProviders();
@ -221,6 +232,13 @@ export const GenAI = {
this.buildPreferences(content);
}
});
// Record glean metrics after applying nimbus prefs
Glean.genaiChatbot.enabled.set(lazy.chatEnabled);
Glean.genaiChatbot.provider.set(this.getProviderId());
Glean.genaiChatbot.shortcuts.set(lazy.chatShortcuts);
Glean.genaiChatbot.shortcutsCustom.set(lazy.chatShortcutsCustom);
Glean.genaiChatbot.sidebar.set(lazy.chatSidebar);
},
/**
@ -240,15 +258,17 @@ export const GenAI = {
* @param {MozBrowser} browser providing context
* @param {string} selection text
* @param {Function} itemAdder creates and returns the item
* @param {string} entry name
* @param {Function} cleanup optional on item activation
* @returns {object} context used for selecting prompts
*/
async addAskChatItems(browser, selection, itemAdder, cleanup) {
async addAskChatItems(browser, selection, itemAdder, entry, cleanup) {
// Prepare context used for both targeting and handling prompts
const window = browser.ownerGlobal;
const tab = window.gBrowser.getTabForBrowser(browser);
const uri = browser.currentURI;
const context = {
entry,
provider: lazy.chatProvider,
selection,
tabTitle: (tab._labelIsContentTitle && tab.label) || "",
@ -321,6 +341,7 @@ export const GenAI = {
button.textContent = promptObj.label;
return button;
},
"shortcuts",
hide
);
@ -346,6 +367,9 @@ export const GenAI = {
() => shortcuts.removeAttribute("active"),
{ once: true }
);
Glean.genaiChatbot.shortcutsExpanded.record({
selection: shortcuts.selection.length,
});
}
});
}
@ -355,10 +379,18 @@ export const GenAI = {
if (shortcuts.timeout) {
lazy.clearTimeout(shortcuts.timeout);
}
shortcuts.timeout = lazy.setTimeout(() => {
// Save the latest selection so it can be used by the popup
// Save the latest selection so it can be used by timeout and popup
shortcuts.selection = data.selection;
shortcuts.timeout = lazy.setTimeout(() => {
// Pref might have changed since the timeout started
if (!lazy.chatShortcuts || shortcuts.hasAttribute("shown")) {
return;
}
shortcuts.toggleAttribute("shown");
Glean.genaiChatbot.shortcutsDisplayed.record({
selection: shortcuts.selection.length,
});
// Position the shortcuts relative to the browser's top-left corner
const rect = browser.getBoundingClientRect();
@ -393,7 +425,8 @@ export const GenAI = {
await this.addAskChatItems(
nsContextMenu.browser,
nsContextMenu.selectionInfo.fullText ?? "",
promptObj => menu.appendItem(promptObj.label)
promptObj => menu.appendItem(promptObj.label),
"menu"
);
nsContextMenu.showItem(menu, menu.itemCount > 0);
},
@ -462,7 +495,11 @@ export const GenAI = {
* @param {object} context of how the prompt should be handled
*/
async handleAskChat(promptObj, context) {
Glean.genaiChatbot.contextmenuPromptClick.record({
Glean.genaiChatbot[
context.entry == "menu"
? "contextmenuPromptClick"
: "shortcutsPromptClick"
].record({
prompt: promptObj.id ?? "custom",
provider: this.getProviderId(),
selection: context.selection?.length ?? 0,
@ -507,14 +544,29 @@ export const GenAI = {
* @param {Window} window for about:preferences
*/
buildPreferences({ document, Preferences }) {
// Section can be hidden by featuregate targeting
const providerEl = document.getElementById("genai-chat-provider");
if (!providerEl) {
return;
}
// Some experiments might want to hide shortcuts
const shortcutsEl = document.getElementById("genai-chat-shortcuts");
if (lazy.chatHideLabsShortcuts || lazy.chatHideFromLabs) {
shortcutsEl.remove();
}
// Page can load (restore at startup) just before default prefs apply
if (lazy.chatHideFromLabs) {
providerEl.parentNode.remove();
document.getElementById("genai-chat").remove();
return;
}
const enabled = Preferences.get("browser.ml.chat.enabled");
const onEnabledChange = () => {
providerEl.disabled = !enabled.value;
shortcutsEl.disabled = !enabled.value;
// Update enabled telemetry
Glean.genaiChatbot.enabled.set(enabled.value);
@ -587,6 +639,23 @@ export const GenAI = {
};
onProviderChange();
provider.on("change", onProviderChange);
const shortcuts = Preferences.add({
id: "browser.ml.chat.shortcuts",
type: "bool",
});
const onShortcutsChange = () => {
// Update shortcuts telemetry
Glean.genaiChatbot.shortcuts.set(shortcuts.value);
if (onShortcutsChange.canChange) {
Glean.genaiChatbot.shortcutsCheckboxClick.record({
enabled: shortcuts.value,
});
}
onShortcutsChange.canChange = true;
};
onShortcutsChange();
shortcuts.on("change", onShortcutsChange);
},
// nsIObserver
@ -608,6 +677,21 @@ function onChatProviderChange(value) {
}
}
/**
* Ensure the chat shortcuts get hidden.
*
* @param {bool} value New pref value
*/
function onChatShortcutsChange(value) {
if (!value) {
lazy.EveryWindow.readyWindows.forEach(window =>
window.document
.querySelectorAll(".content-shortcuts")
.forEach(shortcuts => shortcuts.removeAttribute("shown"))
);
}
}
/**
* Update the ordering of chat providers Map.
*/

Просмотреть файл

@ -45,6 +45,40 @@ genai.chatbot:
send_in_pings:
- metrics
shortcuts:
type: boolean
lifetime: application
description: >
Indicates if the chatbot feature would show shortcuts on selection.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1910005
data_reviews:
- https://phabricator.services.mozilla.com/D217782
data_sensitivity:
- interaction
expires: 134
notification_emails:
- elee@mozilla.com
send_in_pings:
- metrics
shortcuts_custom:
type: boolean
lifetime: application
description: >
Indicates if the chatbot feature would show shortcuts custom input.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1910005
data_reviews:
- https://phabricator.services.mozilla.com/D217782
data_sensitivity:
- interaction
expires: 134
notification_emails:
- elee@mozilla.com
send_in_pings:
- metrics
sidebar:
type: boolean
lifetime: application
@ -108,6 +142,26 @@ genai.chatbot:
type: string
description: Which UI surface.
shortcuts_checkbox_click:
type: event
description: >
Chatbot shortcuts checkbox was clicked to enable/disable.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1910005
data_reviews:
- https://phabricator.services.mozilla.com/D217782
data_sensitivity:
- interaction
expires: 134
notification_emails:
- elee@mozilla.com
send_in_pings:
- events
extra_keys:
enabled:
type: boolean
description: New/current state is enabled.
contextmenu_prompt_click:
type: event
description: >
@ -134,6 +188,72 @@ genai.chatbot:
type: quantity
description: Selected text length.
shortcuts_displayed:
type: event
description: >
Shortcuts displayed on text selection.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1910005
data_reviews:
- https://phabricator.services.mozilla.com/D217782
data_sensitivity:
- interaction
expires: 134
notification_emails:
- elee@mozilla.com
send_in_pings:
- events
extra_keys:
selection:
type: quantity
description: Selected text length.
shortcuts_expanded:
type: event
description: >
Shortcuts expanded to show prompts.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1910005
data_reviews:
- https://phabricator.services.mozilla.com/D217782
data_sensitivity:
- interaction
expires: 134
notification_emails:
- elee@mozilla.com
send_in_pings:
- events
extra_keys:
selection:
type: quantity
description: Selected text length.
shortcuts_prompt_click:
type: event
description: >
Chatbot prompt was clicked from the shortcuts.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1910005
data_reviews:
- https://phabricator.services.mozilla.com/D217782
data_sensitivity:
- interaction
expires: 134
notification_emails:
- elee@mozilla.com
send_in_pings:
- events
extra_keys:
prompt:
type: string
description: Selected prompt id.
provider:
type: string
description: Selected provider id.
selection:
type: quantity
description: Selected text length.
sidebar_toggle:
type: event
description: >

Просмотреть файл

@ -22,6 +22,7 @@ add_task(async function test_no_shortcuts() {
* Check that shortcuts get shown on selection and open popup and sidebar
*/
add_task(async function test_show_shortcuts() {
Services.fog.testResetFOG();
await SpecialPowers.pushPrefEnv({
set: [
["browser.ml.chat.shortcuts", true],
@ -32,20 +33,33 @@ add_task(async function test_show_shortcuts() {
await SimpleTest.promiseFocus(browser);
goDoCommand("cmd_selectAll");
const shortcuts = await TestUtils.waitForCondition(() =>
document.querySelector(".content-shortcuts")
document.querySelector(".content-shortcuts[shown]")
);
Assert.ok(shortcuts, "Shortcuts added on select");
let events = Glean.genaiChatbot.shortcutsDisplayed.testGetValue();
Assert.ok(events.length, "Shortcuts shown");
Assert.equal(events[0].extra.selection, 2, "Selected hi");
const popup = document.getElementById("ask-chat-shortcuts");
Assert.equal(popup.state, "closed", "Popup is closed");
EventUtils.sendMouseEvent({ type: "mouseover" }, shortcuts);
await BrowserTestUtils.waitForEvent(popup, "popupshown");
Assert.equal(popup.state, "open", "Popup is open");
events = Glean.genaiChatbot.shortcutsExpanded.testGetValue();
Assert.equal(events.length, 1, "One shortcuts opened");
Assert.equal(events[0].extra.selection, 2, "Selected hi");
Assert.ok(!SidebarController.isOpen, "Sidebar is closed");
popup.querySelector("toolbarbutton").click();
Assert.ok(SidebarController.isOpen, "Chat opened sidebar");
events = Glean.genaiChatbot.shortcutsPromptClick.testGetValue();
Assert.equal(events.length, 1, "One shortcut clicked");
Assert.equal(events[0].extra.prompt, "summarize", "Picked summarize");
Assert.equal(events[0].extra.provider, "localhost", "With localhost");
Assert.equal(events[0].extra.selection, 2, "Selected hi");
SidebarController.hide();
});

Просмотреть файл

@ -16,6 +16,17 @@ add_task(async function test_default_telemetry() {
"none",
"Default no provider for test"
);
Assert.equal(
Glean.genaiChatbot.shortcuts.testGetValue() ?? true,
true,
"Default shortcuts for test"
);
Assert.equal(
Glean.genaiChatbot.shortcutsCustom.testGetValue() ??
AppConstants.NIGHTLY_BUILD,
AppConstants.NIGHTLY_BUILD,
"Default shortcuts_custom for test"
);
Assert.equal(
Glean.genaiChatbot.sidebar.testGetValue() ?? true,
true,

Просмотреть файл

@ -51,4 +51,8 @@
</menupopup>
</menulist>
</html:div>
<html:moz-checkbox class="indent"
data-l10n-id="genai-settings-chat-shortcuts"
id="genai-chat-shortcuts"
preference="browser.ml.chat.shortcuts"/>
</html:template>

Просмотреть файл

@ -5,11 +5,8 @@
## Generative AI (GenAI) Settings section
genai-settings-chat-title =
.label = AI Chatbot Integration
genai-settings-chat-description =
Select text on a webpage and right-click to see relevant prompts like summarize, simplify, and more. { -brand-short-name } sends the selected text, page title, and prompt to the chatbot of your choice. If you try this feature, <a data-l10n-name="connect">share your thoughts on Connect</a>.
We plan to add more chatbots as we continue to experiment.
.label = AI chatbot
genai-settings-chat-description = Adds the chatbot of your choice to the sidebar, for quick access as you browse. <a data-l10n-name="connect">Share feedback</a>
genai-settings-chat-choose = Choose a chatbot
genai-settings-chat-choose-one-menuitem =
.label = Choose one
@ -21,3 +18,6 @@ genai-settings-chat-gemini-links = By choosing Google Gemini, you agree to the <
genai-settings-chat-huggingchat-links = By choosing HuggingChat, you agree to the <a data-l10n-name="link1">HuggingChat Privacy Notice</a> and <a data-l10n-name="link2">Hugging Face Privacy Policy</a>.
genai-settings-chat-lechat-links = By choosing Le Chat Mistral, you agree to the Mistral AI <a data-l10n-name="link1">Terms of Service</a> and <a data-l10n-name="link2">Privacy Policy</a>.
genai-settings-chat-localhost-links = Bring your own private local chatbot such as <a data-l10n-name="link1">llamafile</a> from { -vendor-short-name }s Innovation group.
genai-settings-chat-shortcuts =
.description = Displays a shortcut to prompts when you select text. { -brand-short-name } sends the text, page title, and prompt to the chatbot.
.label = Show prompts on text select

Просмотреть файл

@ -23,18 +23,7 @@ restart-required = false
preference = "browser.ml.chat.enabled"
type = "boolean"
bug-numbers = [1894999]
is-public-jexl = "nightly_build"
default-value-jexl = "false"
[url-bar-ime-search]
group = "experimental-features-group-browsing"
title = "experimental-features-ime-search"
description = "experimental-features-ime-search-description"
restart-required = false
preference = "browser.urlbar.keepPanelOpenDuringImeComposition"
type = "boolean"
bug-numbers = [1673971]
is-public-jexl = "true"
is-public-jexl = "!'browser.ml.chat.hideFromLabs'|preferenceValue"
default-value-jexl = "false"
[auto-pip]
@ -48,6 +37,17 @@ bug-numbers = [1647800]
is-public-jexl = "true"
default-value-jexl = "false"
[url-bar-ime-search]
group = "experimental-features-group-browsing"
title = "experimental-features-ime-search"
description = "experimental-features-ime-search-description"
restart-required = false
preference = "browser.urlbar.keepPanelOpenDuringImeComposition"
type = "boolean"
bug-numbers = [1673971]
is-public-jexl = "true"
default-value-jexl = "false"
[webrtc-global-mute-toggles]
group = "experimental-features-group-browsing"
title = "experimental-features-webrtc-global-mute-toggles"