Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ All notable changes to WebBrain are documented in this file.

This changelog was generated from the repository Git history and release tags. Versions without a Git tag are inferred from version-bump commits and the current `package.json` / browser manifest versions.

## [33.1.0] - 2026-08-22

### Changed
- Switched to WebBrain VL 2 450M as the local vision fallback.

## [33.0.8] - 2026-08-20

### Changed
- Changed the Chrome local vision fallback to the fine-tuned `webbrain-one/webbrain-vl-2-450M-onnx` release, with renewed opt-in consent and a versioned ready marker so older caches cannot be mistaken for the new model.
- Added a consent-gated, durable WebBrain Cloud terminal-runtime outbox so executed terminal tool results survive provider-trace export gaps and can be joined through stable de-identified references.
- fix: resume vision downloads and organize settings
- fix: require vision cache marker and isolate queued worker deadlines
Expand Down
4 changes: 2 additions & 2 deletions docs/apocalypse-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ not enable Apocalypse Mode, query the Kiwix catalog, or store article text.
Open the **☢ Apocalypse Mode** link beside **Support** in the Settings header to
opt in.

On supported Chromium browsers, local LFM2.5-VL vision is an optional fallback.
On supported Chromium browsers, WebBrain VL 2 450M is an optional local vision fallback.
Apocalypse Mode never enables or downloads it. The dedicated **Use local
fallback** control in **Settings → Multimodal → Vision** checks WebGPU support,
records explicit consent, and starts caching the approximately 770 MB model
records explicit consent, and starts caching the approximately 810 MB model
from Hugging Face. The download continues in the background, but screenshot
operations report its status and never wait for it. Wikipedia archives still
require their own confirmation. The local **text** model defaults to LFM2.5
Expand Down
4 changes: 2 additions & 2 deletions docs/providers-and-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -428,13 +428,13 @@ const vision = await providerManager.getVisionProvider();
```

On Chromium, **Settings -> Multimodal -> Vision** also offers a one-click
in-browser fallback. It runs `LiquidAI/LFM2.5-VL-450M-ONNX` through WebGPU in a
in-browser fallback. It runs `webbrain-one/webbrain-vl-2-450M-onnx` through WebGPU in a
dedicated Worker with FP16 embeddings/vision encoder and a Q4 decoder. The
model is not present in the general provider catalog and never receives agent
tools or planning turns. Local vision is disabled by default and neither
Apocalypse Mode nor a screenshot operation can enable it or start its download.
The dedicated control probes WebGPU, records versioned consent, and then downloads
approximately 770 MB of model data from Hugging Face into the browser cache. The download runs in Chrome's
approximately 810 MB of model data from Hugging Face into the browser cache. The download runs in Chrome's
offscreen extension worker, so the user may switch tabs or close Settings while
it continues, but must keep Chrome running. Screenshots stay on-device and
only the generated description is passed to the active provider. The local
Expand Down
6 changes: 3 additions & 3 deletions docs/remote-downloads.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ WebBrain is designed to minimize remote network dependencies. All downloads fall
| Component | Remote Server / Origin | Origin Description | Typical Size | Protocol / Method | Checksum & Integrity | Local Storage Destination |
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
| **WebGPU Text Model** | `huggingface.co` / Hugging Face CDN | Official Hugging Face model repository hosting ONNX / SafeTensors weights (e.g., SmolLM2, Llama-3.2) | ~1.5 – 2.5 GB | HTTPS GET (Transformers.js pipeline) | Hugging Face Git LFS SHA-256 hash | Browser Cache API & IndexedDB (`transformers-cache`) |
| **Local Vision Model** | `huggingface.co` / Hugging Face CDN | ONNX weights for local screenshot description and UI analysis (LFM2.5-VL / SmolVLM) | ~770 MB | HTTPS GET (Transformers.js pipeline) | Hugging Face Git LFS SHA-256 hash | Browser Cache API & IndexedDB (`transformers-cache`) |
| **Local Vision Model** | `huggingface.co` / Hugging Face CDN | `webbrain-one/webbrain-vl-2-450M-onnx` weights for local screenshot description and UI analysis | ~810 MB | HTTPS GET (Transformers.js pipeline) | Hugging Face Git LFS SHA-256 hash | Browser Cache API & IndexedDB (`transformers-cache`) |
| **Emergency Text Pack & SQLite Index** | `github.com/webbrain-one/emergency-box-corpus` (GitHub Releases CDN) | Release assets for curated public-domain field references, prebuilt SQLite FTS5 database, and precomputed E5 embeddings | ~245 MB (compressed ZIP) | Resumable HTTP `Range: bytes={offset}-` streaming fetch | Strict **SHA-256** hash comparison against hardcoded release descriptor before activation | OPFS (`webbrain-offline-rag/emergency-box-text/`) & IndexedDB (`webbrain_offline_rag`) |
| **Multilingual Semantic Model** | `huggingface.co` / Hugging Face CDN (`Xenova/multilingual-e5-small`) | ONNX weights for multilingual query embedding and vector search / candidate reranking | ~134 MB | HTTPS GET (ONNX Runtime Web / Transformers.js) | SHA-256 verification via Transformers.js manifest | Browser Cache API & IndexedDB (`transformers-cache`) |
| **Wikipedia ZIM Archive** | `library.kiwix.org` / `download.kiwix.org` / Wikimedia Mirrors | Kiwix openZIM archives containing compressed Wikipedia editions (e.g. Simple English) | ~50 MB – 50+ GB | Metalink XML resolution + piece-by-piece chunked HTTPS download | Chunked **SHA-256** piece verification per Metalink block boundaries | OPFS (`webbrain_apocalypse_mode`) |
Expand All @@ -41,7 +41,7 @@ When a user turns on **Apocalypse Mode** (or opens `apocalypse-mode.html` with A
flowchart TD
A["User enables Apocalypse Mode"] --> B["1. Parallel Auto-Downloads Start"]
B --> C["WebGPU Text Model (~1.5-2.5 GB)<br/><b>Hugging Face CDN</b>"]
B --> D["Local Vision Model (~770 MB)<br/><b>Hugging Face CDN</b>"]
B --> D["Local Vision Model (~810 MB)<br/><b>Hugging Face CDN</b>"]
B --> E["Emergency Text Pack (~245-502 MB)<br/><b>GitHub Releases CDN</b>"]
B --> F["Multilingual E5 Semantic Model (~134 MB)<br/><b>Hugging Face CDN</b>"]
B --> G["Simple English Wikipedia ZIM (~50-100 MB)<br/><b>Kiwix / Wikimedia Mirrors</b>"]
Expand All @@ -62,7 +62,7 @@ flowchart TD
├─► 2. Parallel Background Downloads (Active Tab + Service Worker / Offscreen):
│ ├── [WebGPU Text Model] (Offscreen document, ~1.5-2.5 GB from Hugging Face)
│ ├── [Local Vision Model] (Offscreen document, ~770 MB from Hugging Face)
│ ├── [Local Vision Model] (Offscreen document, ~810 MB from Hugging Face)
│ ├── [Emergency Text Pack] (Tab stream, ~245 MB from GitHub Releases)
│ │ └── Verify SHA-256 ──► Extract ZIP ──► Register SQLite FTS5 in OPFS SAH-pool
│ ├── [Multilingual E5 Semantic Model] (Tab stream, ~134 MB from Hugging Face)
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webbrain",
"version": "33.0.8",
"version": "33.1.0",
"description": "Open-source AI browser agent \u2014 chat with pages, automate tasks, multi-provider LLM support.",
"private": true,
"type": "module",
Expand Down
2 changes: 1 addition & 1 deletion src/chrome/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# WebBrain Chrome/Edge Extension — Architecture

> Version 33.0.8 · Manifest V3 · Service Worker background
> Version 33.1.0 · Manifest V3 · Service Worker background

## High-Level Overview

Expand Down
2 changes: 1 addition & 1 deletion src/chrome/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "WebBrain",
"version": "33.0.8",
"version": "33.1.0",
"description": "Open-source AI browser agent — chat with pages, automate tasks, multi-provider LLM support.",
"permissions": [
"sidePanel",
Expand Down
18 changes: 15 additions & 3 deletions src/chrome/src/offscreen/inference-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ const WEBGPU_TEXT_MAX_NEW_TOKENS = 256;
const WEBGPU_LFM25_MODEL_ID = 'LiquidAI/LFM2.5-2.6B-ONNX';
const WEBGPU_BONSAI27_MODEL_ID = 'prism-ml/Bonsai-27B-gguf';
const WEBGPU_LFM25_MAX_NEW_TOKENS = 2048;
const WEBGPU_VISION_READY_MARKER_VERSION = 2;
const WEBGPU_VISION_READY_MARKER_PREFIX = 'https://webbrain.one/.well-known/webgpu-vision-ready/';
function createWebGpuTextSessionOptions() {
return {
extra: {
Expand Down Expand Up @@ -127,7 +129,14 @@ function fetchTargetsActiveVisionModel(input) {
}

function visionReadyMarkerUrl(modelId) {
return `https://webbrain.one/.well-known/webgpu-vision-ready/${encodeURIComponent(String(modelId || '').trim())}`;
return `${WEBGPU_VISION_READY_MARKER_PREFIX}v${WEBGPU_VISION_READY_MARKER_VERSION}/${encodeURIComponent(String(modelId || '').trim())}`;
}

function isVisionReadyMarkerForModel(url, modelId) {
const candidate = String(url || '');
const encodedModelId = encodeURIComponent(String(modelId || '').trim());
return candidate.startsWith(WEBGPU_VISION_READY_MARKER_PREFIX)
&& candidate.endsWith(`/${encodedModelId}`);
}

async function isVisionModelCached(modelId) {
Expand All @@ -151,7 +160,10 @@ async function markVisionModelReady(modelId) {
const normalized = String(modelId || '').trim();
if (!normalized || typeof caches === 'undefined') return;
const cache = await caches.open(TRANSFORMERS_CACHE_NAME);
await cache.put(visionReadyMarkerUrl(normalized), new Response(JSON.stringify({ modelId: normalized }), {
await cache.put(visionReadyMarkerUrl(normalized), new Response(JSON.stringify({
modelId: normalized,
markerVersion: WEBGPU_VISION_READY_MARKER_VERSION,
}), {
headers: { 'content-type': 'application/json' },
}));
}
Expand Down Expand Up @@ -1083,7 +1095,7 @@ export async function clearVisionModelCache(modelId) {
const cache = await caches.open(name);
for (const request of await cache.keys()) {
const url = safeDecodedUrl(request.url);
if (url.includes(modelPath) || request.url === markerUrl) {
if (url.includes(modelPath) || isVisionReadyMarkerForModel(request.url, normalizedModelId)) {
if (await cache.delete(request)) deletedEntries++;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/chrome/src/providers/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ export class ProviderManager {
}
}

/** Return the Chrome-only LiquidAI fallback, but only when explicitly enabled and ready. */
/** Return the Chrome-only WebBrain VL fallback, but only when explicitly enabled and ready. */
async getLocalVisionFallbackProvider() {
try {
const readiness = await this.getWebgpuVisionReadiness();
Expand Down
7 changes: 4 additions & 3 deletions src/chrome/src/providers/webgpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { BaseLLMProvider } from './base.js';
import { ensureOffscreen } from '../offscreen/ensure.js';

export const WEBGPU_VISION_MODEL_ID = 'LiquidAI/LFM2.5-VL-450M-ONNX';
export const WEBGPU_VISION_MODEL_ID = 'webbrain-one/webbrain-vl-2-450M-onnx';
export const WEBGPU_MODEL_ID = 'LiquidAI/LFM2.5-2.6B-ONNX';
export const WEBGPU_LFM25_MODEL_ID = WEBGPU_MODEL_ID;
export const WEBGPU_BONSAI27_MODEL_ID = 'prism-ml/Bonsai-27B-gguf';
Expand Down Expand Up @@ -40,9 +40,10 @@ export const WEBGPU_VISION_ENABLED_KEY = 'webgpuVisionEnabled';
// remove selections made automatically by older Apocalypse Mode builds.
export const WEBGPU_VISION_AUTO_SELECTED_KEY = 'webgpuVisionAutoSelected';
export const WEBGPU_VISION_CONSENT_VERSION_KEY = 'webgpuVisionConsentVersion';
export const WEBGPU_VISION_CONSENT_VERSION = 1;
export const WEBGPU_VISION_CONSENT_VERSION = 2;
export const WEBGPU_VISION_DOWNLOAD_STATE_KEY = 'webgpuVisionDownloadState';
export const WEBGPU_VISION_DOWNLOAD_STATE_MESSAGE = 'webgpu-vision-download-state';
export const WEBGPU_VISION_READY_MARKER_VERSION = 2;
export const WEBGPU_WORKER_INIT_TIMEOUT_MS = 15_000;
export const WEBGPU_VISION_INFERENCE_TIMEOUT_MS = 90_000;
export const WEBGPU_VISION_DTYPE = Object.freeze({
Expand All @@ -52,7 +53,7 @@ export const WEBGPU_VISION_DTYPE = Object.freeze({
});

export function webgpuVisionReadyMarkerUrl(modelId = WEBGPU_VISION_MODEL_ID) {
return `https://webbrain.one/.well-known/webgpu-vision-ready/${encodeURIComponent(String(modelId || '').trim())}`;
return `https://webbrain.one/.well-known/webgpu-vision-ready/v${WEBGPU_VISION_READY_MARKER_VERSION}/${encodeURIComponent(String(modelId || '').trim())}`;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/chrome/src/ui/apocalypse-mode.html
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ <h2 data-i18n="ap.hero.title"></h2>
<svg viewBox="0 0 24 24"><path d="M2.5 12s3.5-6 9.5-6 9.5 6 9.5 6-3.5 6-9.5 6-9.5-6-9.5-6Z"/><circle cx="12" cy="12" r="2.5"/></svg>
</span>
<div class="local-model-body">
<div class="local-model-head"><strong data-i18n="ap.models.vision.title"></strong><span class="meta">~770 MB · WebGPU</span></div>
<div class="local-model-head"><strong data-i18n="ap.models.vision.title"></strong><span class="meta">~810 MB · WebGPU</span></div>
<p class="meta" data-i18n="st.vision.local.desc"></p>
<p class="meta" data-i18n="ap.vision.auto"></p>
<div id="vision-model-status" class="vision-status" role="status" aria-live="polite"></div>
Expand Down
4 changes: 2 additions & 2 deletions src/chrome/src/ui/locales/ar.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ export default {
'st.provider.field.model_loaded_hint': 'اتركه فارغًا لاستخدام النموذج المُحمَّل',

'st.vision.desc': 'إذا تم تعيينه، تُرسَل لقطات الشاشة إلى هذا النموذج لقراءة الصفحة، بينما يتولّى المزوّد النشط التخطيط واستدعاءات الأدوات. اتركه فارغًا لاستخدام المزوّد النشط للرؤية أيضًا. نقاط نهاية متوافقة مع OpenAI فقط.',
'st.vision.local.title': 'بديل محلي لـ LFM2.5-VL',
"st.vision.local.desc": "يشغّل LiquidAI/LFM2.5-VL-450M-ONNX على معالج الرسومات لديك، وتبقى لقطات الشاشة على هذا الجهاز. يؤدي اختيار «استخدام البديل المحلي» إلى فحص WebGPU وتسجيل موافقتك وبدء تنزيل نحو 770 ميغابايت من Hugging Face في الخلفية. تعرض المهام الحالة ولا تنتظر اكتمال التنزيل؛ أبقِ Chrome مفتوحًا.",
'st.vision.local.title': 'بديل محلي لـ WebBrain VL 2 450M',
"st.vision.local.desc": "يشغّل webbrain-one/webbrain-vl-2-450M-onnx على معالج الرسومات لديك، وتبقى لقطات الشاشة على هذا الجهاز. يؤدي اختيار «استخدام البديل المحلي» إلى فحص WebGPU وتسجيل موافقتك وبدء تنزيل نحو 810 ميغابايت من Hugging Face في الخلفية. تعرض المهام الحالة ولا تنتظر اكتمال التنزيل؛ أبقِ Chrome مفتوحًا.",
'st.vision.local.enable': 'استخدام البديل المحلي',
'st.vision.local.disable': 'تعطيل البديل المحلي',
'st.vision.local.saved': 'تم تفعيل بديل الرؤية المحلي.',
Expand Down
4 changes: 2 additions & 2 deletions src/chrome/src/ui/locales/bn.js
Original file line number Diff line number Diff line change
Expand Up @@ -791,8 +791,8 @@ export default {

'st.vision.heading': "দৃষ্টি",
'st.vision.desc': "সেট করা থাকলে, পৃষ্ঠা পড়ার জন্য এই মডেলে স্ক্রিনশট পাঠানো হয়, যখন সক্রিয় প্রদানকারী পরিকল্পনা এবং টুল কল পরিচালনা করে। দৃষ্টির জন্যও সক্রিয় প্রদানকারী ব্যবহার করতে ফাঁকা রাখুন। শুধুমাত্র OpenAI- সামঞ্জস্যপূর্ণ শেষ পয়েন্ট।",
'st.vision.local.title': 'LFM2.5-VL-এর স্থানীয় বিকল্প',
"st.vision.local.desc": "আপনার GPU-তে LiquidAI/LFM2.5-VL-450M-ONNX চালায় এবং স্ক্রিনশট এই ডিভাইসেই রাখে। “স্থানীয় বিকল্প ব্যবহার করুন” নির্বাচন করলে WebGPU পরীক্ষা হয়, আপনার সম্মতি নথিভুক্ত হয় এবং Hugging Face থেকে প্রায় 770 MB ব্যাকগ্রাউন্ড ডাউনলোড শুরু হয়। কাজগুলো অবস্থা দেখায়, ডাউনলোডের জন্য অপেক্ষা করে না; Chrome খোলা রাখুন।",
'st.vision.local.title': 'WebBrain VL 2 450M-এর স্থানীয় বিকল্প',
"st.vision.local.desc": "আপনার GPU-তে webbrain-one/webbrain-vl-2-450M-onnx চালায় এবং স্ক্রিনশট এই ডিভাইসেই রাখে। “স্থানীয় বিকল্প ব্যবহার করুন” নির্বাচন করলে WebGPU পরীক্ষা হয়, আপনার সম্মতি নথিভুক্ত হয় এবং Hugging Face থেকে প্রায় 810 MB ব্যাকগ্রাউন্ড ডাউনলোড শুরু হয়। কাজগুলো অবস্থা দেখায়, ডাউনলোডের জন্য অপেক্ষা করে না; Chrome খোলা রাখুন।",
'st.vision.local.enable': 'স্থানীয় বিকল্প ব্যবহার করুন',
'st.vision.local.disable': 'স্থানীয় বিকল্প বন্ধ করুন',
'st.vision.local.saved': 'স্থানীয় ভিশন বিকল্প চালু হয়েছে।',
Expand Down
4 changes: 2 additions & 2 deletions src/chrome/src/ui/locales/de.js
Original file line number Diff line number Diff line change
Expand Up @@ -731,8 +731,8 @@ export default {
// --- Vision settings ---
'st.vision.heading': 'Vision',
'st.vision.desc': 'Wenn gesetzt, werden Screenshots an dieses Modell gesendet, um die Seite zu lesen...',
'st.vision.local.title': 'Lokale LFM2.5-VL-Ausweichlösung',
"st.vision.local.desc": "Führt LiquidAI/LFM2.5-VL-450M-ONNX auf deiner GPU aus; Screenshots bleiben auf diesem Gerät. „Lokale Ausweichlösung verwenden“ prüft WebGPU, protokolliert deine Einwilligung und startet einen Hintergrunddownload von etwa 770 MB von Hugging Face. Aufgaben zeigen den Status an und warten nicht auf den Download; Chrome muss geöffnet bleiben.",
'st.vision.local.title': 'Lokale WebBrain VL 2 450M-Ausweichlösung',
"st.vision.local.desc": "Führt webbrain-one/webbrain-vl-2-450M-onnx auf deiner GPU aus; Screenshots bleiben auf diesem Gerät. „Lokale Ausweichlösung verwenden“ prüft WebGPU, protokolliert deine Einwilligung und startet einen Hintergrunddownload von etwa 810 MB von Hugging Face. Aufgaben zeigen den Status an und warten nicht auf den Download; Chrome muss geöffnet bleiben.",
'st.vision.local.enable': 'Lokale Ausweichlösung verwenden',
'st.vision.local.disable': 'Lokale Ausweichlösung deaktivieren',
'st.vision.local.saved': 'Lokale Ausweichlösung für Bilderkennung aktiviert.',
Expand Down
4 changes: 2 additions & 2 deletions src/chrome/src/ui/locales/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -792,8 +792,8 @@ export default {

'st.vision.heading': 'Vision',
'st.vision.desc': 'Choose a separate model to read screenshots while the active provider handles planning and tool calls. Leave both options unset to use the active provider for vision.',
'st.vision.local.title': 'LFM2.5-VL local fallback',
"st.vision.local.desc": "Runs LiquidAI/LFM2.5-VL-450M-ONNX on your GPU. Screenshots stay on this device. Selecting “Use local fallback” checks WebGPU, records your consent, and starts an approximately 770 MB background download from Hugging Face. Tasks report its status and never wait for it; keep Chrome open.",
'st.vision.local.title': 'WebBrain VL 2 450M local fallback',
"st.vision.local.desc": "Runs webbrain-one/webbrain-vl-2-450M-onnx on your GPU. Screenshots stay on this device. Selecting “Use local fallback” checks WebGPU, records your consent, and starts an approximately 810 MB background download from Hugging Face. Tasks report its status and never wait for it; keep Chrome open.",
'st.vision.local.enable': 'Use local fallback',
'st.vision.local.disable': 'Disable local fallback',
'st.vision.local.saved': 'Local vision fallback enabled.',
Expand Down
Loading
Loading