tor-browser

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

commit acf7bf12d9e75775ceb1a96183bdccc3a022662b
parent 7f9ee51ed05aa2d1e7891d36e7a2bc04ed0550f3
Author: Mark Banner <standard8@mozilla.com>
Date:   Fri,  7 Nov 2025 09:20:55 +0000

Bug 1998679 - Enable TypeScript checking for Urlbar MLSuggest.sys.mjs. r=adw,gregtatum,urlbar-reviewers

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

Diffstat:
Mbrowser/components/urlbar/private/MLSuggest.sys.mjs | 92+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
Mbrowser/components/urlbar/tests/browser/browser_MLSuggest_integration.js | 2+-
Mbrowser/components/urlbar/tsconfig.json | 1-
Mtoolkit/components/ml/actors/MLEngineParent.sys.mjs | 10++++++++--
Mtoolkit/components/ml/content/EngineProcess.sys.mjs | 4++--
5 files changed, 66 insertions(+), 43 deletions(-)

diff --git a/browser/components/urlbar/private/MLSuggest.sys.mjs b/browser/components/urlbar/private/MLSuggest.sys.mjs @@ -6,15 +6,17 @@ * MLSuggest helps with ML based suggestions around intents and location. */ -const lazy = {}; +import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; -ChromeUtils.defineESModuleGetters(lazy, { +const lazy = XPCOMUtils.declareLazy({ createEngine: "chrome://global/content/ml/EngineProcess.sys.mjs", UrlbarPrefs: "moz-src:///browser/components/urlbar/UrlbarPrefs.sys.mjs", }); /** - * @typedef {Awaited<ReturnType<import("chrome://global/content/ml/EngineProcess.sys.mjs").createEngine>>} MLEngine + * @import {EngineRunRequest, EngineRunResponse, MLEntry} from "moz-src:///toolkit/components/ml/actors/MLEngineParent.sys.mjs" + * @typedef {Parameters<typeof lazy.createEngine>[0]} MLEngineOptions + * @typedef {Awaited<ReturnType<typeof lazy.createEngine>>} MLEngine */ // List of prepositions used in subject cleaning. @@ -70,9 +72,8 @@ class _MLSuggest { /** * Helper to wrap createEngine for testing purposes. * - * @param {object} options + * @param {MLEngineOptions} options * Configuration options for the ML engine. - * @returns {MLEngine} */ createEngine(options) { return lazy.createEngine(options); @@ -92,35 +93,37 @@ class _MLSuggest { } /** + * @typedef {object} MLSuggestResult + * @property {string} intent + * The predicted intent label of the query. Possible values include: + * - 'information_intent': For queries seeking general information. + * - 'yelp_intent': For queries related to local businesses or services. + * - 'navigation_intent': For queries with navigation-related actions. + * - 'travel_intent': For queries showing travel-related interests. + * - 'purchase_intent': For queries with purchase or shopping intent. + * - 'weather_intent': For queries asking about weather or forecasts. + * - 'translation_intent': For queries seeking translations. + * - 'unknown': When the intent cannot be classified with confidence. + * - '' (empty string): Returned when model probabilities for all intents + * are below the intent threshold. + * @property {?{city: ?string, state: ?string}} location + * The detected location from the query. + * @property {string} subject + * The subject of the query after location is removed. + * @property {{intent: object, ner: object}} metrics + * The combined metrics from NER model results, representing additional + * information about the model's performance. + */ + + /** * Generates ML-based suggestions by finding intent, detecting entities, and * combining locations. * * @param {string} query * The user's input query. - * @returns {object | null} + * @returns {Promise<?MLSuggestResult>} * The suggestion result including intent, location, and subject, or null if * an error occurs or query length > MAX_QUERY_LENGTH - * {string} intent - * The predicted intent label of the query. Possible values include: - * - 'information_intent': For queries seeking general information. - * - 'yelp_intent': For queries related to local businesses or services. - * - 'navigation_intent': For queries with navigation-related actions. - * - 'travel_intent': For queries showing travel-related interests. - * - 'purchase_intent': For queries with purchase or shopping intent. - * - 'weather_intent': For queries asking about weather or forecasts. - * - 'translation_intent': For queries seeking translations. - * - 'unknown': When the intent cannot be classified with confidence. - * - '' (empty string): Returned when model probabilities for all intents - * are below the intent threshold. - * - {object|null} location: The detected location from the query, which is - * an object with `city` and `state` fields: - * - {string|null} city: The detected city, or `null` if no city is found. - * - {string|null} state: The detected state, or `null` if no state is found. - * {string} subject - * The subject of the query after location is removed. - * {object} metrics - * The combined metrics from NER model results, representing additional - * information about the model's performance. */ async makeSuggestions(query) { // avoid bunch of work for very long strings @@ -174,6 +177,14 @@ class _MLSuggest { } } + /** + * Initializes a engine model. + * + * @param {MLEngineOptions} options + * Configuration options for the ML engine. + * @param {MLEngineOptions} [fallbackOptions] + * Fallback options if creating with the main options fails. + */ async #initializeModelEngine(options, fallbackOptions = null) { const featureId = options.featureId; @@ -205,10 +216,8 @@ class _MLSuggest { * * @param {string} query * The user's input query. - * @param {object} options + * @param {Omit<EngineRunRequest, "args">} [options] * The options for the engine pipeline - * @returns {object[] | null} - * The intent results or null if the model is not initialized. */ async _findIntent(query, options = {}) { const engineIntentClassifier = this.#modelEngines.get( @@ -218,6 +227,7 @@ class _MLSuggest { return null; } + /** @type {EngineRunResponse} */ let res; try { res = await engineIntentClassifier.run({ @@ -243,10 +253,8 @@ class _MLSuggest { * * @param {string} query * The user's input query. - * @param {object} options + * @param {Omit<EngineRunRequest, "args">} options * The options for the engine pipeline - * @returns {object[] | null} - * The NER results or null if the model is not initialized. */ async _findNER(query, options = {}) { const engineNER = this.#modelEngines.get(this.NER_OPTIONS.featureId); @@ -267,7 +275,7 @@ class _MLSuggest { * If the highest-scoring intent in the result exceeds the threshold, its label * is returned; otherwise, the label defaults to 'unknown'. * - * @param {object[]} intentResult + * @param {EngineRunResponse} intentResult * The result of the intent classification model, where each item includes * a `label` and `score`. * @param {number} intentThreshold @@ -292,7 +300,7 @@ class _MLSuggest { * - B-CITYSTATE, I-CITYSTATE: Identifies tokens that represent a combined * city and state. * - * @param {object[]} nerResult + * @param {EngineRunResponse} nerResult * The NER results containing tokens and their corresponding entity labels. * @param {number} nerThreshold * The confidence threshold for including entities. Tokens with a confidence @@ -349,7 +357,7 @@ class _MLSuggest { * - Handles punctuation tokens like ".", "-", or "'". * - Ensures continuity for entities split across multiple tokens. * - * @param {object} res + * @param {MLEntry} res * The NER result token to process. Should include: * - {string} word: The word or token from the NER output. * - {number} score: The confidence score for the token. @@ -408,6 +416,12 @@ class _MLSuggest { } } + /** + * Finds the subject from the query, removing the city and location words. + * + * @param {string} query + * @param {{city: ?string, state: ?string}} location + */ #findSubjectFromQuery(query, location) { // If location is null or no city/state, return the entire query if (!location || (!location.city && !location.state)) { @@ -435,8 +449,12 @@ class _MLSuggest { return subjectWords.join(" "); } + /** + * Remove trailing prepositions from the list of words + * + * @param {string[]} words + */ #cleanSubject(words) { - // Remove trailing prepositions from the list of words while (words.length && PREPOSITIONS.includes(words[words.length - 1])) { words.pop(); } diff --git a/browser/components/urlbar/tests/browser/browser_MLSuggest_integration.js b/browser/components/urlbar/tests/browser/browser_MLSuggest_integration.js @@ -249,7 +249,7 @@ add_setup(async function () { // until end-to-end engine calls work sinon .stub(MLSuggest, "_findIntent") - .returns({ label: "yelp_intent", score: 0.9 }); + .returns([{ label: "yelp_intent", score: 0.9 }]); sinon.stub(MLSuggest, "_findNER").callsFake(query => { return nerResultsMap[query] || []; }); diff --git a/browser/components/urlbar/tsconfig.json b/browser/components/urlbar/tsconfig.json @@ -4,7 +4,6 @@ "UrlbarInput.sys.mjs", "UrlbarProviderGlobalActions.sys.mjs", "UrlbarView.sys.mjs", - "private/MLSuggest.sys.mjs", "private/SuggestBackendRust.sys.mjs", "tests/UrlbarTestUtils.sys.mjs" ], diff --git a/toolkit/components/ml/actors/MLEngineParent.sys.mjs b/toolkit/components/ml/actors/MLEngineParent.sys.mjs @@ -920,10 +920,16 @@ class ResponseOrChunkResolvers { * @typedef {object} EngineRunRequest * @property {?string} [id] - The identifier for tracking this request. If not provided, an id will be auto-generated. Each inference callback will reference this id. * @property {any[]} args - The arguments to pass to the pipeline. The required arguments depend on your model. See [Hugging Face Transformers documentation](https://huggingface.co/docs/transformers.js/en/api/models) for more details. - * @property {?object} options - The generation options to pass to the model. Refer to the [GenerationConfigType documentation](https://huggingface.co/docs/transformers.js/en/api/utils/generation#module_utils/generation..GenerationConfigType) for available options. + * @property {?object} [options] - The generation options to pass to the model. Refer to the [GenerationConfigType documentation](https://huggingface.co/docs/transformers.js/en/api/utils/generation#module_utils/generation..GenerationConfigType) for available options. * @property {?Uint8Array} [data] - For the imagetoText model, this is the array containing the image data. * - * @template EngineRunResponse + * @typedef {object} MLEntry + * + * @typedef {object} MetricsResponse + * The metrics of the query + * @property {{name: string, when: number}[]} metrics + * + * @typedef {MLEntry[] & MetricsResponse} EngineRunResponse */ export class MLEngine { /** diff --git a/toolkit/components/ml/content/EngineProcess.sys.mjs b/toolkit/components/ml/content/EngineProcess.sys.mjs @@ -1125,8 +1125,8 @@ export class EngineProcess { * Creates a new `MLEngine` instance with the provided options. * * @param {object} options - Configuration options for the ML engine. - * @param {?function(ProgressAndStatusCallbackParams):void} notificationsCallback A function to call to indicate notifications. - * @param {?AbortSignal} abortSignal - AbortSignal to cancel the download. + * @param {?function(ProgressAndStatusCallbackParams):void} [notificationsCallback] - A function to call to indicate notifications. + * @param {?AbortSignal} [abortSignal] - AbortSignal to cancel the download. */ export async function createEngine( options,