tor-browser

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

commit 3511c2af06c0559a9df0129f9db41a6418d70f1f
parent 22aa0b8ee0758bf8a05d3057c873152201c694c8
Author: frankjc2022 <frankjc2022@gmail.com>
Date:   Fri, 19 Dec 2025 19:11:30 +0000

Bug 2006423 - Remove timezone handling in tools config while maintaining accuracy r=tzhang,ai-models-reviewers

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

Diffstat:
Mbrowser/components/aiwindow/models/ChatUtils.sys.mjs | 16++++++----------
Mbrowser/components/aiwindow/models/SearchBrowsingHistory.sys.mjs | 4++--
Mbrowser/components/aiwindow/models/Tools.sys.mjs | 37++++++++++++-------------------------
Mbrowser/components/aiwindow/models/prompts/AssistantPrompts.sys.mjs | 18++++++++----------
Mbrowser/components/aiwindow/models/tests/xpcshell/test_ChatUtils.js | 4++--
5 files changed, 30 insertions(+), 49 deletions(-)

diff --git a/browser/components/aiwindow/models/ChatUtils.sys.mjs b/browser/components/aiwindow/models/ChatUtils.sys.mjs @@ -24,17 +24,11 @@ ChromeUtils.defineESModuleGetters(lazy, { export function getLocalIsoTime() { try { const date = new Date(); - const tzOffsetMinutes = date.getTimezoneOffset(); - const adjusted = new Date(date.getTime() - tzOffsetMinutes * 60000) - .toISOString() - .slice(0, 19); // Keep up to seconds - const sign = tzOffsetMinutes <= 0 ? "+" : "-"; - const hours = String(Math.floor(Math.abs(tzOffsetMinutes) / 60)).padStart( - 2, - "0" + const pad = n => String(n).padStart(2, "0"); + return ( + `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` + + `T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}` ); - const minutes = String(Math.abs(tzOffsetMinutes) % 60).padStart(2, "0"); - return `${adjusted}${sign}${hours}:${minutes}`; } catch { return null; } @@ -90,6 +84,7 @@ export async function constructRealTimeInfoInjectionMessage(depsOverride) { const isoTimestamp = getLocalIsoTime(); const datePart = isoTimestamp?.split("T")[0] ?? ""; const locale = Services.locale.appLocaleAsBCP47; + const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; const hasTabInfo = Boolean(url || title || description); const tabSection = hasTabInfo ? [ @@ -103,6 +98,7 @@ export async function constructRealTimeInfoInjectionMessage(depsOverride) { const content = [ `Below are some real-time context details you can use to inform your response:`, `Locale: ${locale}`, + `Timezone: ${timezone}`, `Current date & time in ISO format: ${isoTimestamp}`, `Today's date: ${datePart || "Unavailable"}`, ``, diff --git a/browser/components/aiwindow/models/SearchBrowsingHistory.sys.mjs b/browser/components/aiwindow/models/SearchBrowsingHistory.sys.mjs @@ -350,9 +350,9 @@ async function searchBrowsingHistoryBasic({ searchTerm, historyLimit }) { * The search string. If null or empty, semantic search is skipped and * results are filtered by time range and sorted by last_visit_date and frecency. * @param {string|null} params.startTs - * Optional ISO-8601 start timestamp (e.g. "2025-11-07T09:00:00-05:00"). + * Optional local ISO-8601 start timestamp (e.g. "2025-11-07T09:00:00"). * @param {string|null} params.endTs - * Optional ISO-8601 end timestamp (e.g. "2025-11-07T09:00:00-05:00"). + * Optional local ISO-8601 end timestamp (e.g. "2025-11-07T09:00:00"). * @param {number} params.historyLimit * Maximum number of history results to return. * @returns {Promise<object>} diff --git a/browser/components/aiwindow/models/Tools.sys.mjs b/browser/components/aiwindow/models/Tools.sys.mjs @@ -44,43 +44,30 @@ export const toolsConfig = [ function: { name: SEARCH_BROWSING_HISTORY, description: - "Refind pages from the user's PAST BROWSING HISTORY. Use this whenever the " + - "user wants to recall, review, list, or see pages they visited earlier (for a " + - "topic, site, or time period). Also use this when the user requests all pages " + - 'from a past time period (e.g., "yesterday", "last week"), even if no topic is ' + - "specified. Do NOT use for open tabs, completely general web questions, or " + - 'abstract questions about "history" or habits.', + "Retrieve pages from the user's past browsing history, optionally filtered by " + + "topic and/or time range.", parameters: { type: "object", properties: { searchTerm: { type: "string", description: - "A detailed, noun-heavy phrase (~2-12 meaningful tokens) summarizing " + - "the user's intent for semantic retrieval. Include the main entity/topic " + - "plus 1-3 contextual qualifiers (e.g., library name, purpose, site, or " + - "timeframe). Avoid vague or single-word queries.", + "A concise phrase describing what the user is trying to find in their " + + "browsing history (topic, site, or purpose).", }, startTs: { type: "string", description: - "Inclusive lower bound of the time window as an ISO 8601 datetime string " + - "(e.g., '2025-11-07T09:00:00-05:00'). Use when the user asks for results " + - "within a time or range start, such as 'last week', 'since yesterday', or" + - "'last night'. This must be before the user's current datetime.", - default: null, + "Inclusive start of the time range as a local ISO 8601 datetime " + + "('YYYY-MM-DDTHH:mm:ss', no timezone).", }, endTs: { type: "string", description: - "Inclusive upper bound of the time window as an ISO 8601 datetime string " + - "(e.g., '2025-11-07T21:00:00-05:00'). Use when the user asks for results " + - "within a time or range end, such as 'last week', 'between 2025-10-01 and " + - "2025-10-31', or 'before Monday'. This must be before the user's current datetime.", - default: null, + "Inclusive end of the time range as a local ISO 8601 datetime " + + "('YYYY-MM-DDTHH:mm:ss', no timezone).", }, }, - required: [], }, }, }, @@ -166,8 +153,8 @@ export async function getOpenTabs(n = 15) { * * Parameters (defaults shown): * - searchTerm: "" - string used for search - * - startTs: null - ISO timestamp lower bound, or null - * - endTs: null - ISO timestamp upper bound, or null + * - startTs: null - local ISO timestamp lower bound, or null + * - endTs: null - local ISO timestamp upper bound, or null * - historyLimit: 15 - max number of results * * Detailed behavior and implementation are in SearchBrowsingHistory.sys.mjs. @@ -178,9 +165,9 @@ export async function getOpenTabs(n = 15) { * The search string. If null or empty, semantic search is skipped and * results are filtered by time range and sorted by last_visit_date and frecency. * @param {string|null} toolParams.startTs - * Optional ISO-8601 start timestamp (e.g. "2025-11-07T09:00:00-05:00"). + * Optional local ISO-8601 start timestamp (e.g. "2025-11-07T09:00:00"). * @param {string|null} toolParams.endTs - * Optional ISO-8601 end timestamp (e.g. "2025-11-07T09:00:00-05:00"). + * Optional local ISO-8601 end timestamp (e.g. "2025-11-07T09:00:00"). * @param {number} toolParams.historyLimit * Maximum number of history results to return. * @returns {Promise<object>} diff --git a/browser/components/aiwindow/models/prompts/AssistantPrompts.sys.mjs b/browser/components/aiwindow/models/prompts/AssistantPrompts.sys.mjs @@ -63,16 +63,14 @@ Stay predictable, supportive, and context-aware. # Tool Usage -- Use search_browsing_history to refind pages from the user's past browsing activity. -- If the request refers to something the user saw earlier, visited previously, or spans a past time period ("yesterday", "earlier today", "last week"), default to using search_browsing_history unless it clearly concerns open tabs. -- If the user explicitly mentions "history", "what I visited", "what I was reading/watching", or "what I opened" in the past, you should almost always use search_browsing_history at least once. -- If the request is clearly about open tabs right now, use get_open_tabs. -- If the user wants the content of a specific open page by URL, use get_page_content. -- If the user is asking a general question that does not depend on their own browsing activity, you can answer directly without tools. -- Before answering, quickly check: "Is the user asking about their own past browsing activity?" If yes, you should usually use search_browsing_history. -- Never output XML-like tags or raw JSON for tools; the system handles tool invocation. - -(Queries like "show my browsing from last week" or "what pages did I visit earlier today" use search_browsing_history.) +search_browsing_history: +when to call +- call when the user intent is to recover, refind, or recall previously visited pages +- do NOT call for general questions or ongoing conversation that don't require page recovery +how to call +- build searchTerm as a concise, descriptive query; rewrite vague requests into title-like phrases and do not invent unrelated tokens +- if the user requests a time period without a topic, call the tool with no searchTerm and only the time filter +- extract temporal intent if present and map it to concrete ISO 8601 startTs/endTs using the smallest reasonable calendar span; otherwise set both to null # Tool Call Rules diff --git a/browser/components/aiwindow/models/tests/xpcshell/test_ChatUtils.js b/browser/components/aiwindow/models/tests/xpcshell/test_ChatUtils.js @@ -94,8 +94,8 @@ add_task(function test_getLocalIsoTime_returns_offset_timestamp() { "Should return a non-empty string" ); Assert.ok( - /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$/.test(iso), - "Should include date, time (up to seconds), and timezone offset" + /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/.test(iso), + "Should include date, time (up to seconds), without timezone offset" ); } finally { clock.restore();