Files
tubestation/browser/components/urlbar/UrlbarProviderSemanticHistorySearch.sys.mjs

148 lines
4.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* 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/. */
/**
* This module exports a provider that offers search history suggestions
* based on embeddings and semantic search techniques using semantic
* history
*/
import {
UrlbarProvider,
UrlbarUtils,
} from "resource:///modules/UrlbarUtils.sys.mjs";
import { PlacesSemanticHistoryManager } from "resource://gre/modules/PlacesSemanticHistoryManager.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
UrlbarResult: "resource:///modules/UrlbarResult.sys.mjs",
UrlbarPrefs: "resource:///modules/UrlbarPrefs.sys.mjs",
});
/**
* Class representing the Semantic History Search provider for the URL bar.
*
* This provider queries a semantic database created using history.
* It performs semantic search using embeddings generated
* by an ML model and retrieves results ranked by cosine similarity to the
* query's embedding.
*
* @class
*/
class ProviderSemanticHistorySearch extends UrlbarProvider {
#semanticManager;
/**
* Lazily creates (on first call) and returns the
* {@link PlacesSemanticHistoryManager} instance backing this provider.
*
* The manager is instantiated only once and cached in the private
* `#semanticManager` field. It is configured with sensible defaults for
* semantic history search:
* • `embeddingSize`: 384 dimensionality of vector embeddings
* • `rowLimit`: 10000 maximum rows pulled from Places
* • `samplingAttrib`: "frecency" column used when down-sampling
* • `changeThresholdCount`: 3 restart inference after this many DB changes
* • `distanceThreshold`: 0.75 cosine-distance cut-off for matches
*
* @returns {PlacesSemanticHistoryManager}
* The shared, initialized semantic-history manager instance.
*/
ensureSemanticManagerInitialized() {
if (!this.#semanticManager) {
this.#semanticManager = new PlacesSemanticHistoryManager({
embeddingSize: 384,
rowLimit: 10000,
samplingAttrib: "frecency",
changeThresholdCount: 3,
distanceThreshold: 0.75,
});
}
return this.#semanticManager;
}
get name() {
return "SemanticHistorySearch";
}
/**
* @returns {Values<typeof UrlbarUtils.PROVIDER_TYPE>}
*/
get type() {
return UrlbarUtils.PROVIDER_TYPE.PROFILE;
}
/**
* Determines if the provider is active for the given query context.
*
* @param {object} queryContext
* The context of the query, including the search string.
* @returns {boolean}
* `true` if the provider is active; `false` otherwise.
*/
isActive(queryContext) {
const semanticHistoryFlag = lazy.UrlbarPrefs.get("suggest.semanticHistory");
const minSearchStringLength = lazy.UrlbarPrefs.get(
"suggest.semanticHistory.minLength"
);
if (
semanticHistoryFlag &&
queryContext.searchString.length >= minSearchStringLength
) {
const semanticManager = this.ensureSemanticManagerInitialized();
return semanticManager?.canUseSemanticSearch ?? false;
}
return false;
}
/**
* Starts a semantic search query.
*
* @param {object} queryContext
* The query context, including the search string.
* @param {Function} addCallback
* Callback to add results to the URL bar.
*/
async startQuery(queryContext, addCallback) {
let instance = this.queryInstance;
if (!this.#semanticManager) {
throw new Error(
"SemanticManager must be initialized via isActive() before calling startQuery()"
);
}
let resultObject = await this.#semanticManager.infer(queryContext);
let results = resultObject.results;
if (!results || instance != this.queryInstance) {
return;
}
for (let res of results) {
const result = new lazy.UrlbarResult(
UrlbarUtils.RESULT_TYPE.URL,
UrlbarUtils.RESULT_SOURCE.HISTORY,
...lazy.UrlbarResult.payloadAndSimpleHighlights(queryContext.tokens, {
title: [res.title, UrlbarUtils.HIGHLIGHT.NONE],
url: [res.url, UrlbarUtils.HIGHLIGHT.NONE],
icon: UrlbarUtils.getIconForUrl(res.url),
})
);
result.resultGroup = UrlbarUtils.RESULT_GROUP.HISTORY_SEMANTIC;
addCallback(this, result);
}
}
/**
* Gets the priority of this provider relative to other providers.
*
* @returns {number} The priority of this provider.
*/
getPriority() {
return 0;
}
}
export var UrlbarProviderSemanticHistorySearch =
new ProviderSemanticHistorySearch();