[object Object]

← back to Exo

feat: add Firefox AI sidebar (?q=) support to dashboard (#1814)

10ef7ec9e89c25cb3b38f85648292ed8c7e82fea · 2026-03-30 12:02:35 +0200 · ArvidSU

This PR builds on https://github.com/exo-explore/exo/pull/1677 to enable
custom prompts sent from Firefox `browser.ml.chat` to EXO dashboard
using URL parameters in sidebar for summary and other browser
interactions. See "Summarize page" example below.

## Summary
- Parse `?q=<encoded prompt>` URL parameter on page load and auto-submit
it as a chat message
- Clean up the URL with `history.replaceState` to prevent re-submission
on refresh
- Defer auto-send until both cluster state and model list are loaded so
model auto-selection works correctly

## Context
Firefox's built-in AI sidebar (`about:config: browser.ml.chat.enabled`)
integrates with chat providers by appending the user's prompt as
`?q=<URL-encoded prompt>`. Previously the exo dashboard ignored this
parameter. Users can now configure `http://localhost:52415` as a Firefox
AI chatbot provider.

See: https://support.mozilla.org/en-US/kb/ai-chatbot

## Technical notes
- Frontend-only change in `dashboard/src/routes/+page.svelte`
- Uses a Svelte `$effect` that reacts to `pendingFirefoxQuery`, `data`
(cluster state), and `models.length` — fires exactly once when all three
are ready
- If no model is selected, `handleAutoSend` auto-picks the best
available model; if no model fits memory, a toast is shown
- If a model is selected but not running, the message is queued until
the model loads

## Testing
```
http://localhost:52415/?q=Hello+world
http://localhost:52415/?q=Summarize+this+page%3A+%5Bpage+title%5D+%5Bpage+url%5D
```

<img width="2056" height="1329" alt="image"
src="https://github.com/user-attachments/assets/74463eb4-ca1a-400d-806a-c19ba93147b9"
/>

Files touched

Diff

commit 10ef7ec9e89c25cb3b38f85648292ed8c7e82fea
Author: ArvidSU <45108382+ArvidSU@users.noreply.github.com>
Date:   Mon Mar 30 12:02:35 2026 +0200

    feat: add Firefox AI sidebar (?q=) support to dashboard (#1814)
    
    This PR builds on https://github.com/exo-explore/exo/pull/1677 to enable
    custom prompts sent from Firefox `browser.ml.chat` to EXO dashboard
    using URL parameters in sidebar for summary and other browser
    interactions. See "Summarize page" example below.
    
    ## Summary
    - Parse `?q=<encoded prompt>` URL parameter on page load and auto-submit
    it as a chat message
    - Clean up the URL with `history.replaceState` to prevent re-submission
    on refresh
    - Defer auto-send until both cluster state and model list are loaded so
    model auto-selection works correctly
    
    ## Context
    Firefox's built-in AI sidebar (`about:config: browser.ml.chat.enabled`)
    integrates with chat providers by appending the user's prompt as
    `?q=<URL-encoded prompt>`. Previously the exo dashboard ignored this
    parameter. Users can now configure `http://localhost:52415` as a Firefox
    AI chatbot provider.
    
    See: https://support.mozilla.org/en-US/kb/ai-chatbot
    
    ## Technical notes
    - Frontend-only change in `dashboard/src/routes/+page.svelte`
    - Uses a Svelte `$effect` that reacts to `pendingFirefoxQuery`, `data`
    (cluster state), and `models.length` — fires exactly once when all three
    are ready
    - If no model is selected, `handleAutoSend` auto-picks the best
    available model; if no model fits memory, a toast is shown
    - If a model is selected but not running, the message is queued until
    the model loads
    
    ## Testing
    ```
    http://localhost:52415/?q=Hello+world
    http://localhost:52415/?q=Summarize+this+page%3A+%5Bpage+title%5D+%5Bpage+url%5D
    ```
    
    <img width="2056" height="1329" alt="image"
    src="https://github.com/user-attachments/assets/74463eb4-ca1a-400d-806a-c19ba93147b9"
    />
---
 dashboard/src/routes/+page.svelte | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/dashboard/src/routes/+page.svelte b/dashboard/src/routes/+page.svelte
index 751ba51d..965482e6 100644
--- a/dashboard/src/routes/+page.svelte
+++ b/dashboard/src/routes/+page.svelte
@@ -265,6 +265,7 @@
 
   let mounted = $state(false);
   let localNodeId = $state<string | null>(null);
+  let pendingFirefoxQuery = $state<string | null>(null); // ?q= param deferred until state loads
 
   // ── Onboarding wizard state ──
   const ONBOARDING_COMPLETE_KEY = "exo-onboarding-complete";
@@ -1309,6 +1310,20 @@
       return;
     }
 
+    // Firefox AI sidebar integration: handle ?q= query parameter
+    // Firefox's built-in AI sidebar (about:config: browser.ml.chat.enabled) sends
+    // the user's prompt as ?q=<URL-encoded prompt> to the configured provider URL.
+    // See: https://support.mozilla.org/en-US/kb/ai-chatbot
+    const queryParam = params.get("q");
+    if (queryParam) {
+      // Clean up the URL to prevent re-submission on page refresh
+      window.history.replaceState({}, "", window.location.pathname);
+      // Defer the auto-send until cluster state is loaded (topologyData,
+      // instances, availableMemory) so that model auto-selection works
+      // correctly. The $effect below will pick this up once data is ready.
+      pendingFirefoxQuery = queryParam;
+    }
+
     // Check server-side onboarding state (persisted in ~/.exo)
     try {
       const res = await fetch("/onboarding");
@@ -1329,6 +1344,18 @@
     }
   });
 
+  // Deferred Firefox AI sidebar auto-send: wait for cluster state and model
+  // list before submitting. Both data (from /state polling) and models (from
+  // the async /models fetch in onMount) must be loaded for handleAutoSend to
+  // correctly auto-select a model.
+  $effect(() => {
+    if (pendingFirefoxQuery && data && models.length > 0) {
+      const query = pendingFirefoxQuery;
+      pendingFirefoxQuery = null;
+      handleChatSend(query);
+    }
+  });
+
   async function fetchModels() {
     try {
       const response = await fetch("/models");

← 1e51dc89 chore: bump exo-version with release version (#1807)  ·  back to Exo  ·  feat: /state/paths (#1796) c6c5a3e7 →