ChatUtils.sys.mjs (4702B)
1 /* 2 This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 5 6 const lazy = {}; 7 8 ChromeUtils.defineESModuleGetters(lazy, { 9 CryptoUtils: "moz-src:///services/crypto/modules/utils.sys.mjs", 10 }); 11 12 import { MESSAGE_ROLE } from "./ChatConstants.sys.mjs"; 13 import { ChatConversation } from "./ChatConversation.sys.mjs"; 14 import { ChatMessage, ChatHistoryResult } from "./ChatMessage.sys.mjs"; 15 16 /** 17 * Creates a 12 characters GUID with 72 bits of entropy. 18 * 19 * @returns {string} A base64url encoded GUID. 20 */ 21 export function makeGuid() { 22 return ChromeUtils.base64URLEncode(lazy.CryptoUtils.generateRandomBytes(9), { 23 pad: false, 24 }); 25 } 26 27 /** 28 * Parse a conversation row from the database into a ChatConversation 29 * object. 30 * 31 * @param {object} row - The database row to parse. 32 * @returns {ChatConversation} The parsed conversation object. 33 */ 34 export function parseConversationRow(row) { 35 return new ChatConversation({ 36 id: row.getResultByName("conv_id"), 37 title: row.getResultByName("title"), 38 description: row.getResultByName("description"), 39 pageUrl: URL.parse(row.getResultByName("page_url")), 40 pageMeta: parseJSONOrNull(row.getResultByName("page_meta")), 41 createdDate: row.getResultByName("created_date"), 42 updatedDate: row.getResultByName("updated_date"), 43 status: row.getResultByName("status"), 44 }); 45 } 46 47 /** 48 * Parse message rows from the database into an array of ChatMessage 49 * objects. 50 * 51 * @param {object} rows - The database rows to parse. 52 * @returns {Array<ChatMessage>} The parsed message objects. 53 */ 54 export function parseMessageRows(rows) { 55 return rows.map(row => { 56 return new ChatMessage({ 57 id: row.getResultByName("message_id"), 58 createdDate: row.getResultByName("created_date"), 59 parentMessageId: row.getResultByName("parent_message_id"), 60 revisionRootMessageId: row.getResultByName("revision_root_message_id"), 61 ordinal: row.getResultByName("ordinal"), 62 isActiveBranch: !!row.getResultByName("is_active_branch"), 63 role: row.getResultByName("role"), 64 modelId: row.getResultByName("model_id"), 65 params: parseJSONOrNull(row.getResultByName("params")), 66 usage: parseJSONOrNull(row.getResultByName("usage")), 67 content: parseJSONOrNull(row.getResultByName("content")), 68 convId: row.getResultByName("conv_id"), 69 pageUrl: URL.parse(row.getResultByName("page_url")), 70 turnIndex: row.getResultByName("turn_index"), 71 insightsEnabled: row.getResultByName("insights_enabled"), 72 insightsFlagSource: row.getResultByName("insights_flag_source"), 73 insightsApplied: parseJSONOrNull(row.getResultByName("insights_applied")), 74 webSearchQueries: parseJSONOrNull( 75 row.getResultByName("web_search_queries") 76 ), 77 }); 78 }); 79 } 80 81 /** 82 * Parse conversation rows from the database into an array of ChatHistoryResult 83 * objects. 84 * 85 * @param {Array<object>} rows - The database rows to parse. 86 * @returns {Array<ChatHistoryResult>} The parsed chat history result entries 87 */ 88 export function parseChatHistoryViewRows(rows) { 89 return rows.map(row => { 90 return new ChatHistoryResult({ 91 convId: row.getResultByName("conv_id"), 92 title: row.getResultByName("title"), 93 createdDate: row.getResultByName("created_date"), 94 updatedDate: row.getResultByName("updated_date"), 95 urls: row 96 .getResultByName("urls") 97 .split(",") 98 .map(url => new URL(url)), 99 }); 100 }); 101 } 102 103 /** 104 * Try to parse a JSON string, returning null if it fails or the value is falsy. 105 * 106 * @param {string} value - The JSON string to parse. 107 * @returns {object|null} The parsed object or null. 108 */ 109 export function parseJSONOrNull(value) { 110 if (!value) { 111 return null; 112 } 113 try { 114 return JSON.parse(value); 115 } catch (e) { 116 return null; 117 } 118 } 119 120 /** 121 * Try to stringify a value if it is truthy, otherwise return null. 122 * 123 * @param {*} value - A value to JSON.stringify() 124 * 125 * @returns {string|null} - JSON string 126 */ 127 export function toJSONOrNull(value) { 128 return value ? JSON.stringify(value) : null; 129 } 130 131 /** 132 * Converts the different types of message roles from 133 * the database numeric type to a string label 134 * 135 * @param {number} role - The database numeric role type 136 * @returns {string} - A human readable role label 137 */ 138 export function getRoleLabel(role) { 139 switch (role) { 140 case MESSAGE_ROLE.USER: 141 return "User"; 142 143 case MESSAGE_ROLE.ASSISTANT: 144 return "Assistant"; 145 146 case MESSAGE_ROLE.SYSTEM: 147 return "System"; 148 149 case MESSAGE_ROLE.TOOL: 150 return "Tool"; 151 } 152 153 return ""; 154 }