tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 2c4f7ccc297e53f50489ef591763c1dbcab7cb2f
parent 99a822346241d9938df5016f6738f0976def21c3
Author: Yubin Jamora <yjamora@mozilla.com>
Date:   Fri,  9 Jan 2026 21:26:34 +0000

Bug 2006250 -Add AI Window section within AI Features about:preferences r=mstriemer,fluent-reviewers,flod

Differential Revision: https://phabricator.services.mozilla.com/D277455

Diffstat:
Mbrowser/app/profile/firefox.js | 1+
Mbrowser/components/preferences/config/aiFeatures.mjs | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mbrowser/components/preferences/preferences.js | 2+-
Mbrowser/components/preferences/tests/browser_aiFeatures.js | 81++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mbrowser/locales-preview/aiFeatures.ftl | 10++++++++++
5 files changed, 151 insertions(+), 11 deletions(-)

diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js @@ -2275,6 +2275,7 @@ pref("browser.aiwindow.memoriesLogLevel", "Warn"); pref("browser.aiwindow.firstrun.autoAdvanceMS", 3000); pref("browser.aiwindow.firstrun.modelChoice", ""); pref("browser.aiwindow.model", "qwen3-235b-a22b-instruct-2507-maas"); +pref("browser.aiwindow.preferences.enabled", false); // Block insecure active content on https pages pref("security.mixed_content.block_active_content", true); diff --git a/browser/components/preferences/config/aiFeatures.mjs b/browser/components/preferences/config/aiFeatures.mjs @@ -12,7 +12,11 @@ const lazy = XPCOMUtils.declareLazy({ GenAI: "resource:///modules/GenAI.sys.mjs", }); -Preferences.addAll([{ id: "browser.ml.chat.provider", type: "string" }]); +Preferences.addAll([ + { id: "browser.ml.chat.provider", type: "string" }, + { id: "browser.aiwindow.enabled", type: "bool" }, + { id: "browser.aiwindow.preferences.enabled", type: "bool" }, +]); Preferences.addSetting({ id: "chatbotProviderItem" }); Preferences.addSetting({ @@ -50,6 +54,39 @@ Preferences.addSetting({ }, }); +Preferences.addSetting({ + id: "AIWindowEnabled", + pref: "browser.aiwindow.enabled", +}); + +Preferences.addSetting({ + id: "AIWindowPreferencesEnabled", + pref: "browser.aiwindow.preferences.enabled", +}); + +// Only show the feature settings if the prefs are allowed to show and the +// feature isn't enabled. +Preferences.addSetting({ + id: "AIWindowItem", + deps: ["AIWindowEnabled", "AIWindowPreferencesEnabled"], + visible: deps => { + return deps.AIWindowPreferencesEnabled.value && !deps.AIWindowEnabled.value; + }, +}); +Preferences.addSetting({ id: "AIWindowHeader" }); +Preferences.addSetting({ id: "AIWindowActivateLink" }); + +// Only show the AI Window features if the prefs are allowed to show and the +// feature is enabled. +// TODO: Enable when Model and Insight options are added +Preferences.addSetting({ + id: "aiFeaturesAIWindowGroup", + deps: ["AIWindowEnabled", "AIWindowPreferencesEnabled"], + visible: deps => { + return deps.AIWindowPreferencesEnabled.value && deps.AIWindowEnabled.value; + }, +}); + SettingGroupManager.registerGroups({ aiFeatures: { l10nId: "try-ai-features-group", @@ -72,6 +109,35 @@ SettingGroupManager.registerGroups({ }, ], }, + { + id: "AIWindowItem", + control: "moz-box-group", + items: [ + { + id: "AIWindowHeader", + l10nId: "try-ai-features-ai-window", + control: "moz-box-item", + }, + { + id: "AIWindowActivateLink", + l10nId: "try-ai-features-ai-window-activate-link", + control: "moz-box-link", + }, + ], + }, + ], + }, + aiWindowFeatures: { + l10nId: "ai-window-features-group", + headingLevel: 2, + items: [ + { + id: "aiFeaturesAIWindowGroup", + control: "moz-box-group", + // TODO: Add Model and Insight list + // options: [ + // ], + }, ], }, }); diff --git a/browser/components/preferences/preferences.js b/browser/components/preferences/preferences.js @@ -281,7 +281,7 @@ const CONFIG_PANES = Object.freeze({ }, aiFeatures: { l10nId: "preferences-ai-features-header", - groupIds: ["aiFeatures"], + groupIds: ["aiFeatures", "aiWindowFeatures"], module: "chrome://browser/content/preferences/config/aiFeatures.mjs", visible: () => srdSectionEnabled("aiFeatures"), }, diff --git a/browser/components/preferences/tests/browser_aiFeatures.js b/browser/components/preferences/tests/browser_aiFeatures.js @@ -8,10 +8,7 @@ describe("settings ai features", () => { beforeEach(async function setup() { await SpecialPowers.pushPrefEnv({ - set: [ - ["browser.ml.chat.provider", ""], - ["browser.settings-redesign.aiFeatures.enabled", true], - ], + set: [["browser.settings-redesign.aiFeatures.enabled", true]], }); await openPreferencesViaOpenPreferencesAPI("general", { leaveOpen: true }); doc = gBrowser.selectedBrowser.contentDocument; @@ -20,10 +17,21 @@ describe("settings ai features", () => { afterEach(() => { BrowserTestUtils.removeTab(gBrowser.selectedTab); - gBrowser.ownerGlobal.SidebarController.hide(); }); + async function openAiFeaturePanel() { + const paneLoaded = waitForPaneChange("aiFeatures"); + const categoryButton = doc.getElementById("category-ai-features"); + categoryButton.scrollIntoView(); + EventUtils.synthesizeMouseAtCenter(categoryButton, {}, win); + await paneLoaded; + } + it("can change the chatbot provider value", async () => { + await SpecialPowers.pushPrefEnv({ + set: [["browser.ml.chat.provider", ""]], + }); + const categoryButton = doc.getElementById("category-ai-features"); Assert.ok(categoryButton, "category exists"); Assert.ok( @@ -31,10 +39,7 @@ describe("settings ai features", () => { "category is visible" ); - const paneLoaded = waitForPaneChange("aiFeatures"); - categoryButton.scrollIntoView(); - EventUtils.synthesizeMouseAtCenter(categoryButton, {}, win); - await paneLoaded; + await openAiFeaturePanel(); const providerControl = doc.getElementById("chatbotProvider"); Assert.ok(providerControl, "control exists"); @@ -67,5 +72,63 @@ describe("settings ai features", () => { "", "Pref is not empty" ); + + await gBrowser.ownerGlobal.SidebarController.hide(); + }); + + it("hides AI Window when preferences not enabled", async () => { + await SpecialPowers.pushPrefEnv({ + set: [["browser.aiwindow.preferences.enabled", false]], + }); + + await openAiFeaturePanel(); + + const aiWindowItem = doc.getElementById("AIWindowItem"); + const aiWindowFeatures = doc.getElementById("aiFeaturesAIWindowGroup"); + + Assert.ok( + !BrowserTestUtils.isVisible(aiWindowItem), + "AIWindowItem is hidden when preferences not enabled" + ); + Assert.ok( + !BrowserTestUtils.isVisible(aiWindowFeatures), + "aiWindowFeatures is hidden when preferences not enabled" + ); + }); + + it("shows AI Window activate when preferences enabled and feature not enabled", async () => { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.aiwindow.preferences.enabled", true], + ["browser.aiwindow.enabled", false], + ], + }); + + await openAiFeaturePanel(); + + const aiWindowItem = doc.getElementById("AIWindowItem"); + Assert.ok( + BrowserTestUtils.isVisible(aiWindowItem), + "AIWindowItem is visible when preferences enabled and feature not enabled" + ); + }); + + it("hides AI Window activate when feature enabled", async () => { + await SpecialPowers.pushPrefEnv({ + set: [ + ["browser.aiwindow.preferences.enabled", true], + ["browser.aiwindow.enabled", true], + ], + }); + + await openAiFeaturePanel(); + + const aiWindowItem = doc.getElementById("AIWindowItem"); + Assert.ok( + !BrowserTestUtils.isVisible(aiWindowItem), + "AIWindowItem is hidden when feature enabled" + ); }); + + // TODO: Add tests for aiFeaturesAIWindowGroup when Model and Insight options are added }); diff --git a/browser/locales-preview/aiFeatures.ftl b/browser/locales-preview/aiFeatures.ftl @@ -19,3 +19,13 @@ try-ai-features-chatbot-provider = # This labels the unset option for AI Chatbot selection, the other options are brand names like "ChatGPT" and "Anthropic Claude" try-ai-features-chatbot-choose-label = .label = Choose provider + +try-ai-features-ai-window = + .label = AI Window + .description = A separate window that learns as you browse. Get quick answers about your tabs and a more personalized experience. +try-ai-features-ai-window-activate-link = + .label = Activate AI Window + +ai-window-features-group = + .label = AI Window + .description = Choose which model powers the assistant and control what AI Window learns from your activity.