forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			115 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			115 lines
		
	
	
	
		
			3.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /**
 | |
|  * 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 { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
 | |
| 
 | |
| const lazy = {};
 | |
| XPCOMUtils.defineLazyPreferenceGetter(
 | |
|   lazy,
 | |
|   "chatEnabled",
 | |
|   "browser.ml.chat.enabled"
 | |
| );
 | |
| XPCOMUtils.defineLazyPreferenceGetter(
 | |
|   lazy,
 | |
|   "chatPromptPrefix",
 | |
|   "browser.ml.chat.prompt.prefix"
 | |
| );
 | |
| XPCOMUtils.defineLazyPreferenceGetter(
 | |
|   lazy,
 | |
|   "chatProvider",
 | |
|   "browser.ml.chat.provider"
 | |
| );
 | |
| 
 | |
| export const GenAI = {
 | |
|   /**
 | |
|    * Build prompts menu to ask chat for context menu or popup.
 | |
|    *
 | |
|    * @param {MozMenu} menu Element to update
 | |
|    * @param {nsContextMenu} context Additional menu context
 | |
|    */
 | |
|   buildAskChatMenu(menu, context) {
 | |
|     if (!lazy.chatEnabled || lazy.chatProvider == "") {
 | |
|       context.showItem(menu, false);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     menu.context = context;
 | |
|     menu.label = "Ask chatbot";
 | |
|     menu.menupopup?.remove();
 | |
|     Services.prefs.getChildList("browser.ml.chat.prompts.").forEach(pref => {
 | |
|       try {
 | |
|         let prompt = Services.prefs.getStringPref(pref);
 | |
|         try {
 | |
|           prompt = JSON.parse(prompt);
 | |
|         } catch (ex) {}
 | |
|         menu.appendItem(prompt.label ?? prompt, prompt.value ?? "");
 | |
|       } catch (ex) {
 | |
|         console.error("Failed to add menu item for " + pref, ex);
 | |
|       }
 | |
|     });
 | |
|     context.showItem(menu, menu.itemCount > 0);
 | |
|   },
 | |
| 
 | |
|   /**
 | |
|    * Build a prompt with context.
 | |
|    *
 | |
|    * @param {MozMenuItem} item Use value falling back to label
 | |
|    * @param {object} context Placeholder keys with values to replace
 | |
|    * @returns {string} Prompt with placeholders replaced
 | |
|    */
 | |
|   buildChatPrompt(item, context = {}) {
 | |
|     // Combine prompt prefix with the item then replace placeholders from the
 | |
|     // original prompt (and not from context)
 | |
|     return (lazy.chatPromptPrefix + (item.value || item.label)).replace(
 | |
|       // Handle %placeholder% as key|options
 | |
|       /\%(\w+)(?:\|([^%]+))?\%/g,
 | |
|       (placeholder, key, options) =>
 | |
|         // Currently only supporting numeric options for slice with `undefined`
 | |
|         // resulting in whole string
 | |
|         context[key]?.slice(0, options) ?? placeholder
 | |
|     );
 | |
|   },
 | |
| 
 | |
|   /**
 | |
|    * Handle selected prompt by opening tab or sidebar.
 | |
|    *
 | |
|    * @param {Event} event from menu command
 | |
|    */
 | |
|   handleAskChat({ target }) {
 | |
|     const win = target.ownerGlobal;
 | |
|     const { selectedTab } = win.gBrowser;
 | |
|     const url = new URL(lazy.chatProvider);
 | |
|     url.searchParams.set(
 | |
|       "q",
 | |
|       this.buildChatPrompt(target, {
 | |
|         currentTabTitle:
 | |
|           (selectedTab._labelIsContentTitle && selectedTab.label) || "",
 | |
|         selection: target.closest("menu").context.selectionInfo.fullText ?? "",
 | |
|       })
 | |
|     );
 | |
|     win.openWebLinkIn(url + "", "tab", { relatedToCurrent: true });
 | |
|   },
 | |
| 
 | |
|   /**
 | |
|    * Build preferences for chat such as handling providers.
 | |
|    *
 | |
|    * @param {Window} window for about:preferences
 | |
|    */
 | |
|   buildPreferences({ document, Preferences }) {
 | |
|     const providerEl = document.getElementById("genai-chat-provider");
 | |
|     if (!providerEl) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     const enabled = Preferences.get("browser.ml.chat.enabled");
 | |
|     const onEnabledChange = () => (providerEl.disabled = !enabled.value);
 | |
|     onEnabledChange();
 | |
|     enabled.on("change", onEnabledChange);
 | |
| 
 | |
|     // TODO bug 1895433 populate providers
 | |
|     Preferences.add({ id: "browser.ml.chat.provider", type: "string" });
 | |
|   },
 | |
| };
 | 
