tor-browser

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

commit c63169e41447ec00756df9dddd048b8c70e1b29d
parent f30a4105039de478a5d60909ee427f792851b6a8
Author: Mark Striemer <mstriemer@mozilla.com>
Date:   Fri,  9 Jan 2026 23:03:58 +0000

Bug 2009269 - Stub out on-device model management API for settings r=fluent-reviewers,tgiles,bolsson

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

Diffstat:
Abrowser/components/preferences/OnDeviceModelManager.mjs | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbrowser/components/preferences/config/aiFeatures.mjs | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbrowser/components/preferences/jar.mn | 1+
Mbrowser/components/preferences/preferences.js | 2+-
Mbrowser/locales-preview/aiFeatures.ftl | 11+++++++++++
Mtools/@types/generated/tspaths.json | 3+++
6 files changed, 205 insertions(+), 1 deletion(-)

diff --git a/browser/components/preferences/OnDeviceModelManager.mjs b/browser/components/preferences/OnDeviceModelManager.mjs @@ -0,0 +1,95 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * @import { ModelHub } from "chrome://global/content/ml/ModelHub.sys.mjs" + */ + +/** + * Helpers for managing the install and uninstall of on-device AI models. This + * could be a .sys.mjs module if that makes more sense, but any feature-specific + * helpers could be imported here too. + */ + +const XPCOMUtils = ChromeUtils.importESModule( + "resource://gre/modules/XPCOMUtils.sys.mjs" +).XPCOMUtils; +const lazy = XPCOMUtils.declareLazy({ + ModelHub: "chrome://global/content/ml/ModelHub.sys.mjs", + log: () => + console.createInstance({ + prefix: "OnDeviceModelManager", + maxLogLevel: "Info", + }), +}); + +/** @typedef {typeof OnDeviceModelFeatures[keyof typeof OnDeviceModelFeatures]} OnDeviceModelFeaturesEnum */ + +/** + * Features that support on-device AI models. + */ +const OnDeviceModelFeatures = Object.freeze({ + // NOTE: Feel free to change the values here to whatever makes sense. + TabGroups: "tabgroups", + KeyPoints: "keypoints", + PdfAltText: "pdfalttext", +}); + +export const OnDeviceModelManager = { + features: OnDeviceModelFeatures, + + /** @type {ModelHub} */ + _modelHub: null, + get modelHub() { + if (!this._modelHub) { + this._modelHub = new lazy.ModelHub(); + } + return this._modelHub; + }, + + /** + * Install the models for a specific feature. This should be used when a user + * explicitly enables a feature, so it's ready when they go to use it. + * + * @param {OnDeviceModelFeaturesEnum} feature The feature key to install. + */ + async install(feature) { + switch (feature) { + case OnDeviceModelFeatures.TabGroups: + lazy.log.info("install TabGroups"); + return; + case OnDeviceModelFeatures.KeyPoints: + lazy.log.info("install KeyPoints"); + return; + case OnDeviceModelFeatures.PdfAltText: + lazy.log.info("install PdfAltText"); + return; + default: + throw new Error(`Unknown on-device model feature "${feature}"`); + } + }, + + /** + * Uninstall the models for a specific feature. + * + * @param {OnDeviceModelFeaturesEnum} feature The feature key to uninstall. + */ + async uninstall(feature) { + // TODO: Maybe something like this? + // this.modelHub.deleteFilesByEngine(feature); + switch (feature) { + case OnDeviceModelFeatures.TabGroups: + lazy.log.info("uninstall TabGroups"); + return; + case OnDeviceModelFeatures.KeyPoints: + lazy.log.info("uninstall KeyPoints"); + return; + case OnDeviceModelFeatures.PdfAltText: + lazy.log.info("uninstall PdfAltText"); + return; + default: + throw new Error(`Unknown on-device model feature "${feature}"`); + } + }, +}; diff --git a/browser/components/preferences/config/aiFeatures.mjs b/browser/components/preferences/config/aiFeatures.mjs @@ -4,12 +4,22 @@ import { Preferences } from "chrome://global/content/preferences/Preferences.mjs"; import { SettingGroupManager } from "chrome://browser/content/preferences/config/SettingGroupManager.mjs"; +import { OnDeviceModelManager } from "chrome://browser/content/preferences/OnDeviceModelManager.mjs"; + +/** + * @import { OnDeviceModelFeaturesEnum } from "chrome://browser/content/preferences/OnDeviceModelManager.mjs" + */ const XPCOMUtils = ChromeUtils.importESModule( "resource://gre/modules/XPCOMUtils.sys.mjs" ).XPCOMUtils; const lazy = XPCOMUtils.declareLazy({ GenAI: "resource:///modules/GenAI.sys.mjs", + log: () => + console.createInstance({ + prefix: "aiFeatures", + maxLogLevel: "Info", + }), }); Preferences.addAll([ @@ -53,6 +63,65 @@ Preferences.addSetting({ }; }, }); +Preferences.addSetting( + /** @type {{ selected: string } & SettingConfig} */ ({ + id: "onDeviceModel", + selected: Object.values(OnDeviceModelManager.features)[0], + getControlConfig(config) { + if (!config.options) { + config.options = Object.entries(OnDeviceModelManager.features).map( + ([key, value]) => ({ + value, + controlAttrs: { label: key }, + }) + ); + } + return config; + }, + get() { + return this.selected; + }, + set(val) { + this.selected = String(val); + }, + }) +); +Preferences.addSetting({ + id: "onDeviceModelInstall", + deps: ["onDeviceModel"], + async onUserClick(_, deps) { + let feature = /** @type {OnDeviceModelFeaturesEnum} */ ( + deps.onDeviceModel.value + ); + lazy.log.info("Will install: ", feature); + await OnDeviceModelManager.install(feature); + lazy.log.info("Done install: ", feature); + }, +}); +Preferences.addSetting({ + id: "onDeviceModelUninstall", + deps: ["onDeviceModel"], + async onUserClick(_, deps) { + let feature = /** @type {OnDeviceModelFeaturesEnum} */ ( + deps.onDeviceModel.value + ); + lazy.log.info("Will uninstall: ", feature); + await OnDeviceModelManager.uninstall(feature); + lazy.log.info("Done uninstall: ", feature); + }, +}); +Preferences.addSetting({ + id: "onDeviceModelUninstallAll", + async onUserClick() { + lazy.log.info("Will uninstall: ALL"); + await Promise.all( + Object.values(OnDeviceModelManager.features).map(feature => + OnDeviceModelManager.uninstall(feature) + ) + ); + lazy.log.info("Done uninstall: ALL"); + }, +}); Preferences.addSetting({ id: "AIWindowEnabled", @@ -88,6 +157,31 @@ Preferences.addSetting({ }); SettingGroupManager.registerGroups({ + debugModelManagement: { + l10nId: "debug-model-management-group", + items: [ + { + id: "onDeviceModel", + control: "moz-select", + l10nId: "debug-model-management-feature", + }, + { + id: "onDeviceModelInstall", + control: "moz-button", + l10nId: "debug-model-management-install", + }, + { + id: "onDeviceModelUninstall", + control: "moz-button", + l10nId: "debug-model-management-uninstall", + }, + { + id: "onDeviceModelUninstallAll", + control: "moz-button", + l10nId: "debug-model-management-uninstall-all", + }, + ], + }, aiFeatures: { l10nId: "try-ai-features-group", items: [ diff --git a/browser/components/preferences/jar.mn b/browser/components/preferences/jar.mn @@ -25,6 +25,7 @@ browser.jar: content/browser/preferences/web-appearance-light.svg content/browser/preferences/etp-toggle-promo.svg content/browser/preferences/etp-advanced-banner.svg + content/browser/preferences/OnDeviceModelManager.mjs content/browser/preferences/config/aiFeatures.mjs (config/aiFeatures.mjs) content/browser/preferences/config/SettingGroupManager.mjs (config/SettingGroupManager.mjs) content/browser/preferences/widgets/dialog-button.mjs (widgets/dialog-button/dialog-button.mjs) 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", "aiWindowFeatures"], + groupIds: ["debugModelManagement", "aiFeatures", "aiWindowFeatures"], module: "chrome://browser/content/preferences/config/aiFeatures.mjs", visible: () => srdSectionEnabled("aiFeatures"), }, diff --git a/browser/locales-preview/aiFeatures.ftl b/browser/locales-preview/aiFeatures.ftl @@ -2,6 +2,17 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +debug-model-management-group = + .label = DEBUG model management +debug-model-management-feature = + .label = features +debug-model-management-install = + .label = install feature +debug-model-management-uninstall = + .label = uninstall feature +debug-model-management-uninstall-all = + .label = uninstall all features + pane-ai-features-title = AI Features category-ai-features = .tooltiptext = { pane-ai-features-title } diff --git a/tools/@types/generated/tspaths.json b/tools/@types/generated/tspaths.json @@ -116,6 +116,9 @@ "chrome://browser/content/nsContextMenu.sys.mjs": [ "browser/base/content/nsContextMenu.sys.mjs" ], + "chrome://browser/content/preferences/OnDeviceModelManager.mjs": [ + "browser/components/preferences/OnDeviceModelManager.mjs" + ], "chrome://browser/content/preferences/config/SettingGroupManager.mjs": [ "browser/components/preferences/config/SettingGroupManager.mjs" ],