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:
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"
],