Overview

JAMES (Just A Machine, Engineered for Speech) is a browser-native AI chat interface. It runs a quantized language model entirely inside your browser using WebGPU or WASM — no server, no API, no data leaving your device.

Conversation state is persisted in IndexedDB. Model weights are cached by the browser after first download. Once cached, JAMES works completely offline.

Local inference means: every token is generated on your CPU or GPU. Response speed depends entirely on your hardware.

Model Loading

On first launch, JAMES downloads model weights from Hugging Face. This is a one-time operation — weights are cached by the browser indefinitely.

Model files are fetched in parallel chunks and cached locally, so the download can recover gracefully and load faster on future launches.

The progress bar at the top of the terminal reflects download progress. Status transitions are:

downloading → streaming → complete → done
Cached weights load much faster after the first run. The browser serves them from its cache on subsequent launches.

Backends

JAMES selects the best available execution path for your hardware and automatically falls back if a preferred backend is unavailable.

WebGPU — primary (GPU)

The preferred high-performance backend for Chrome/Edge with a compatible GPU. JAMES tries progressively larger models based on your available VRAM.

GPU models (WebGPU / q4f16):
  Qwen2.5 0.5B   — ~400 MB  (auto-select)
  SmolLM2 1.7B   — ~950 MB  (auto-select)
  Llama 3.2 1B   — ~750 MB  (auto-select)
  Qwen2.5 1.5B   — ~950 MB  (auto-select)
  Llama 3.2 3B   — ~2.1 GB  (auto-select)
  Gemma 3 1B     — ~600 MB  (manual only)
  DeepSeek-R1 1.5B — ~1 GB  (manual only)
  Phi-3.5-mini 3.8B — ~2.2 GB (manual only)

WASM — CPU fallback

Used when WebGPU is unavailable. Slower but compatible with any modern browser.

CPU models (WASM / q4 or q8):
  Llama 3.2 1B   — ~650 MB
  TinyLlama 1.1B — ~600 MB
  Qwen2.5 0.5B   — ~400 MB
  SmolLM2 1.7B   — ~950 MB
You can manually pick any model via the ⚙️ Model Settings panel at the top-right of the terminal.

Threads

Each conversation is a thread in the sidebar. Threads represent independent context histories and are saved locally.

  • Click + New Chat to start a fresh session.
  • Thread titles are derived from the first user message.
  • Use the × button to delete a thread permanently.
  • The active thread and its history are stored in IndexedDB and restored on revisit.

Stop Generation

The stop button terminates the worker and restarts generation state.

  1. Worker is terminated immediately.
  2. Partial streamed text is saved if available.
  3. The model restarts from the browser cache.
Stopping forces a fresh worker session. It may take a few seconds afterward, but no model re-download occurs.

Python Execution

JAMES can execute Python code in-browser via Pyodide. Ask JAMES to run a Python calculation and it will use the python tool automatically:

```tool:run
{"tool": "eval_python", "params": {"code": "import math; print(math.factorial(20))"}}
```

Execution results are returned into the conversation and used to answer your query. Pyodide loads on first use; subsequent calls are instant.

Tool Reference

JAMES uses model-driven tool calling. When you ask a question that needs live or external data, the model emits a tool call block, the app executes it, and feeds the result back to the model for a final answer:

```tool:run
{"tool": "weather", "params": {"location": "Tel Aviv"}}
```

Both JSON and XML formats are supported in addition to the legacy key: value format. The app auto-detects which format was used.

Information Tools

weather

Gets current weather conditions via Open-Meteo (no API key needed).

{"tool": "weather", "params": {"location": "Tel Aviv"}}
wikipedia

Fetches a Wikipedia article summary.

{"tool": "wikipedia", "params": {"query": "Bijective numeration"}}
currency

Converts currency amounts via frankfurter.app.

{"tool": "currency", "params": {"from": "USD", "to": "EUR", "amount": 100}}
time

Returns current time for an IANA timezone.

time
timezone: Asia/Jerusalem
date

Date utilities: now, diff, convert, parse.

date
action: diff, date: 2025-01-01, date2: 2026-01-01
web_search

Returns a live web search for a query.

web_search
query: best local AI models 2025
fetch_page

Reads the full content of a specific webpage or URL.

fetch_page
url: https://news.ycombinator.com
ip

Looks up IP geolocation info.

ip
target: self

Utility Tools

uuid

Generates cryptographically secure UUIDs.

uuid
count: 3
password

Creates strong random passwords.

password
length: 24, count: 1, symbols: true
timer

Starts a countdown timer with a visible widget.

timer
seconds: 1500, label: Pomodoro
calculator

Evaluates a math expression safely.

calculator
expr: (12 * 8) / 3 + sqrt(144)
convert

Converts units (length, weight, temperature, speed, etc.).

convert
value: 100, from: km, to: miles
base64

Encodes or decodes Base64 strings.

base64
mode: encode, value: Hello World
hash

Hashes a string using SHA-256, SHA-512, or MD5.

hash
algorithm: sha256, value: hello
color

Converts between HEX, RGB, and HSL color formats.

color
mode: hex2rgb, hex: #ff6b6b
random

Generates random numbers, dice rolls, or coin flips.

random
mode: dice, count: 2, sides: 6
countdown

Calculates time remaining to a target date.

countdown
target: 2027-01-01
ascii_art

Generates ASCII art text.

ascii_art
text: JAMES
python

Runs Python code in Pyodide and returns stdout output.

python
code: print('Hello from Python')
palette

Generates color palettes from a base color.

palette
base: #00ff41, scheme: triadic, count: 5
file

Processes uploaded file content.

file
filename: data.txt, content: ...
search

Searches a local Orama knowledge index seeded with JAMES documentation.

search
query: browser inference
write_note

Saves a personal fact about the user for future personalization. Runs silently and stores data in encrypted IndexedDB.

write_note
note: User's name is Alex and they are 28 years old.

Device Tools

clipboard

Reads clipboard text (requires user permission).

clipboard
location

Returns GPS coordinates (requires user permission).

location

Games ♟️

JAMES has two fully playable games built into the chat. Just say "let's play chess" or "start a game of checkers" — a live board appears right in the conversation.

start_game

Starts an interactive Chess or Checkers board inside the chat. JAMES plays as Black; you play as White by clicking pieces.

start_game
game: chess
start_game
game: checkers
make_move

Used internally by JAMES to play its own move after you move. Fires automatically — you do not call this directly.

make_move
move: e5          <!-- Chess SAN -->
make_move
move: 5,2 to 4,3  <!-- Checkers row,col -->
Chess: Full standard rules via chess.js — en passant, castling, auto-queen promotion, check & checkmate. Click a piece to see its legal moves highlighted.

Checkers (English draughts): Forced captures, multi-jump sequences, king promotion (♛), and game-over detection with a winner banner.

Architecture

Browser Main Thread
→ app.js (UI & State)
→ tools/ (Modular Tool Routing, Maps & Rules)

Web Worker (worker.js & worker-*.js)
→ Inference, Prompts & Hardware Detection
→ Transformers.js (WebGPU / WASM)

Storage
→ chat-db.js (IndexedDB)

The application is modularized for efficiency: the worker layer (split into multiple specialized worker-*.js modules) owns inference and model state. The main thread owns the UI, the modular tool routing system, and storage.

Privacy Model

JAMES is designed so no conversation data leaves your browser unless you explicitly request external information via tools.

Data Where it lives Network exposure
Conversation messages IndexedDB None
Session metadata IndexedDB / localStorage None
Model weights Browser cache One-time download
Static assets Service Worker cache One-time download
Inference compute Web Worker None
Delete your data: clear site data to remove stored threads and cached weights.

Service Worker

The service worker caches static app assets as an enhancement. Model weights bypass the SW and use the browser cache instead.

  • App logic: network-first.
  • CDN assets: cache-first.
  • Model weights: browser cache.
If the app behaves oddly, unregister the service worker and refresh.