tor-browser

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

MemoriesChatSource.sys.mjs (3408B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /**
      6 * This module handles the user message extraction from chat store
      7 */
      8 
      9 import {
     10  ChatStore,
     11  MESSAGE_ROLE,
     12 } from "moz-src:///browser/components/aiwindow/ui/modules/ChatStore.sys.mjs";
     13 
     14 // Chat fetch defaults
     15 const DEFAULT_MAX_RESULTS = 50;
     16 const DEFAULT_HALF_LIFE_DAYS = 7;
     17 const MS_PER_SEC = 1_000;
     18 const SEC_PER_MIN = 60;
     19 const MINS_PER_HOUR = 60;
     20 const HOURS_PER_DAY = 24;
     21 
     22 /**
     23 * Fetch recent user chat messages from the ChatStore and compute a freshness
     24 * score for each one.
     25 *
     26 * Messages are fetched between `startTime` and "now" (Date.now()) and limited
     27 * to the most recent `maxResults` entries. A per-message `freshness_score`
     28 * in [0, 1] is computed using an exponential half-life decay over age in days.
     29 *
     30 * @param {number} [startTime=0]
     31 *        Inclusive start time in milliseconds since Unix epoch.
     32 * @param {number} [maxResults=DEFAULT_MAX_RESULTS]
     33 *        Maximum number of most recent messages to return.
     34 * @param {number} [halfLifeDays=DEFAULT_HALF_LIFE_DAYS]
     35 *        Half-life in days for the freshness decay function.
     36 * @returns {Promise<Array<{
     37 *   createdDate: number,
     38 *   role: string,
     39 *   content: any,
     40 *   pageUrl: string | null,
     41 *   freshness_score: number
     42 * }>>}
     43 *        Promise resolving to an array of mapped chat message objects.
     44 */
     45 export async function getRecentChats(
     46  startTime = 0,
     47  maxResults = DEFAULT_MAX_RESULTS,
     48  halfLifeDays = DEFAULT_HALF_LIFE_DAYS
     49 ) {
     50  // Underlying Chatstore uses Date type but MemoriesStore maintains in TS
     51  const startDate = new Date(startTime);
     52  const endDate = new Date();
     53  const chatStore = new ChatStore();
     54  const messages = await chatStore.findMessagesByDate(
     55    startDate,
     56    endDate,
     57    MESSAGE_ROLE.USER,
     58    maxResults
     59  );
     60 
     61  const chatMessages = messages.map(msg => {
     62    const createdDate = msg.createdDate;
     63    const freshness_score = computeFreshnessScore(createdDate, halfLifeDays);
     64    return {
     65      createdDate,
     66      role: msg.role,
     67      content: msg.content?.body ?? null,
     68      pageUrl: msg.pageUrl,
     69      freshness_score,
     70    };
     71  });
     72 
     73  return chatMessages;
     74 }
     75 
     76 /**
     77 * Compute a freshness score for a message based on its age, using an
     78 * exponential decay with a configurable half-life.
     79 *
     80 * The score is:
     81 *   -> 1.0 for messages with ageDays <= 0 (now or in the future)
     82 *   -> exp(-ln(2) * (ageDays / halfLifeDays)) for older messages,
     83 *   clamped into the [0, 1] range.
     84 *
     85 * @param {number|Date} createdDate
     86 *        Message creation time, either as a millisecond timestamp or a Date.
     87 * @param {number} [halfLifeDays=DEFAULT_HALF_LIFE_DAYS]
     88 *        Half-life in days; larger values decay more slowly.
     89 * @returns {number}
     90 *          Freshness score in the range [0, 1].
     91 */
     92 export function computeFreshnessScore(
     93  createdDate,
     94  halfLifeDays = DEFAULT_HALF_LIFE_DAYS
     95 ) {
     96  const now = Date.now();
     97  const createdMs =
     98    typeof createdDate === "number" ? createdDate : createdDate.getTime();
     99  const ageMs = now - createdMs;
    100  const ageDays =
    101    ageMs / (MS_PER_SEC * SEC_PER_MIN * MINS_PER_HOUR * HOURS_PER_DAY);
    102  if (ageDays <= 0) {
    103    return 1;
    104  }
    105  const raw = Math.exp(-Math.LN2 * (ageDays / halfLifeDays));
    106  return Math.max(0, Math.min(1, raw));
    107 }