Ahmad Bot โ Technical Guide
Overview
Ahmad Bot is a real local LLM assistant embedded in the ROWM Notebook. It uses @mlc-ai/web-llm for genuine model inference in your browser, with no API keys or network dependencies.
Key Features:
- Real model inference (Llama 2, Mistral, TinyLlama, NeuralHermes)
- WebGPU acceleration when available (CPU fallback)
- Automatic notebook cell extraction and context-aware responses
- Unicode preservation (ฮป ฮฉ ฯ โ ๐ค ๊ฎ)
- Streaming token generation
- Session persistence
- Dark sovereign theme (navy/cyan/gold)
Architecture
Files
| File | Purpose | Lines |
|---|---|---|
scripts/ahmad-bot-engine.js |
Real WebLLM integration, notebook context extraction | 550 |
scripts/ahmad-bot-ui.js |
Chat interface, panel management, message handling | 480 |
styles/ahmad-bot.css |
Dark theme, animations, responsive layout | 390 |
scripts/ahmad-bot-worker.js |
Optional Web Worker for non-blocking inference | 200 |
Components
NotebookPageReader
Extracts notebook cells from DOM without reading nav/buttons:
// Extract all cells
const cells = NotebookPageReader.extractCells();
// Returns: [{id, index, type, source, output, hash}, ...]
// Get notebook metadata
const meta = NotebookPageReader.getNotebookMetadata();
// Returns: {title, subtitle, cellCount, timestamp}
NotebookContextIndex
Builds searchable index and retrieves relevant cells:
const index = new NotebookContextIndex();
// Find relevant cells for a query
const relevant = index.findRelevant("reversible Unicode", 5);
// Get cell by index
const cell = index.getCellByIndex(0);
// Export context as formatted text
const text = index.formatContextAsText(cells);
AhmadWebLLMEngine
Real WebLLM integration with streaming:
const engine = new AhmadWebLLMEngine();
// Initialize with model selection
await engine.initialize('Llama-2-7b-chat-hf-q4f32_1-MLC');
// Check if ready
if (engine.isReady()) { ... }
// Generate with notebook context
const systemPrompt = engine.buildSystemPrompt(userMessage);
await engine.generate(userMessage, systemPrompt);
// Listen to events
engine.on('token', (token) => console.log(token));
engine.on('statusChanged', (status) => console.log(status));
engine.on('generationComplete', (response) => console.log(response));
// Interrupt generation
engine.interrupt();
AhmadBotUI
Chat interface and panel management:
// Auto-initialized on page load
window.ahmadBotUI
// Programmatic access
window.ahmadBotUI.sendMessage();
window.ahmadBotUI.stopGeneration();
window.ahmadBotUI.clearMessages();
window.ahmadBotUI.updateStatus('READY');
window.ahmadBotUI.openPanel();
window.ahmadBotUI.closePanel();
Model Selection
Prebuilt Models (Verified)
| Model | Size | Speed | Memory | Best For |
|---|---|---|---|---|
| Llama 2 7B (q4f32) | 3.9GB | Medium | 8GB+ | Production, quality |
| Mistral 7B (q4f16) | 4.1GB | Fast | 8GB+ | Speed, efficiency |
| NeuralHermes 7B | 4.2GB | Medium | 8GB+ | Technical Q&A |
| TinyLlama 1.1B (q4f16) | 530MB | Very Fast | 2GB+ | Testing, limited devices |
Selection Flow
// List available models
const models = engine.getSupportedModels();
// Returns: [{id, name, size}, ...]
// Initialize specific model
await engine.initialize('Mistral-7B-Instruct-v0.2-q4f16_1-MLC');
// Check WebGPU support
const hasWebGPU = AhmadWebLLMEngine.hasWebGPU();
// CPU fallback automatically used if unavailable
Integration into index-app.html
The following is already integrated. To verify:
CSS is loaded:
<link rel="stylesheet" href="styles/ahmad-bot.css">WebLLM library is loaded:
<script src="https://cdn.jsdelivr.net/npm/@mlc-ai/web-llm@0.2.33/lib/web-llm.js"></script>Scripts are loaded in order:
<script src="scripts/ahmad-bot-engine.js"></script> <script src="scripts/ahmad-bot-ui.js"></script>DOM elements exist:
<div id="jit-launcher" class="jit-launcher"> <button id="jit-toggle">ฮฉ</button> </div> <div id="jit-panel" class="jit-panel hidden"> <!-- Pre-built UI structure --> </div>
End-to-End Usage
1. Open Notebook
โ Navigate to index-app.html
โ Notebook visible with cells
โ ฮฉ button appears in bottom-right corner
2. Launch Ahmad Bot
โ Click ฮฉ button
โ Panel slides open from bottom-right
โ Status: "OFFLINE"
3. Initialize Model
โ First open triggers automatic initialization
โ Status: "LOADING"
โ Real model downloads to browser (~3-4GB for Llama 2)
โ Download progress shown in WebLLM console
โ Status: "READY" when complete
4. Chat
โ Type question: "What does this notebook say about reversible Unicode?"
โ Press Enter or click Send
โ Status: "GENERATING"
โ Tokens stream in real-time (actual model output)
โ Status: "READY" when complete
โ Response cites actual notebook cells
5. Follow-up
โ Ask follow-up question
โ Context preserved from conversation history
โ New response generated with full context
6. Management
โ "Stop" button: Interrupt generation
โ "Clear" button: Clear message history
โ "โ" button: Minimize panel
โ "โ" button: Close panel (model stays loaded)
โ Draggable header: Move panel around
System Prompt
The system prompt is built per-message and includes:
- Identity: "You are Ahmad Bot, embedded technical guide for the Isomorphic WORM Notebook"
- Environment: "Running locally in the browser"
- Notebook Context: Relevant cells found via keyword search
- Instructions:
- Answer based on notebook content
- Cite cell identifiers
- Never invent cells
- Preserve Unicode exactly
- Be concise and direct
Example System Prompt
You are Ahmad Bot, an embedded technical guide for the Isomorphic WORM Notebook running locally in the browser.
You have access to the following notebook context:
ROWM Notebook Context
Title: ฮฉ Isomorphic WORM Notebook
Total Cells: 3
===================
Cell [0]
Type: code
Source:
// Reversible Unicode mapping
const reversibleMap = {
'ฮป': 'LAMBDA',
'ฮฉ': 'OMEGA',
'ฯ': 'PHI'
};
---
[Additional cells...]
Instructions:
- Answer questions based on notebook content
- Cite cell identifiers (e.g., "Cell 0", "Cell 1")
- Never invent cells or content
- Preserve Unicode exactly (ฮป ฮฉ ฯ โ ๐ค ๊ฎ)
- Be concise and direct
- If uncertain about content, say so
User question: What does this notebook say about reversible Unicode?
Status States
| State | Color | Animation | Meaning |
|---|---|---|---|
| OFFLINE | Gray | None | Model not loaded |
| LOADING | Blue | Pulse | Downloading/initializing model |
| READY | Green | None | Model ready, waiting for input |
| GENERATING | Cyan | Pulse | Model producing response |
| ERROR | Red | None | Error occurred |
Event Listeners
// Engine events
engine.on('statusChanged', (status) => { ... })
engine.on('token', (token) => { ... })
engine.on('generationStart', () => { ... })
engine.on('generationComplete', (response) => { ... })
engine.on('generationStopped', () => { ... })
engine.on('error', (error) => { ... })
engine.on('historyCleared', () => { ... })
Performance
Download Sizes (One-time)
- Llama 2 7B: ~3.9GB (15-20 min on good connection)
- Mistral 7B: ~4.1GB (15-20 min)
- TinyLlama 1.1B: ~530MB (2-3 min)
First Token Latency
- WebGPU (NVIDIA RTX 3080+): 300-500ms
- WebGPU (AMD RDNA): 500-800ms
- CPU (i7-12700K): 2-4 seconds
Token Generation Speed
- WebGPU: 5-10 tokens/second
- CPU: 1-2 tokens/second
Memory Footprint
- Runtime: 1-2GB (model-dependent)
- Browser overhead: 500MB-1GB
- Recommendation: 8GB+ for 7B models
Troubleshooting
Model Won't Initialize
Symptom: Status stays "LOADING" or shows "ERROR"
Solutions:
- Check browser console for errors:
F12 โ Console - Verify WebLLM is loaded:
console.log(window.webllm) - Check browser supports WebGPU or WebAssembly:
navigator.gpu // WebGPU typeof WebAssembly // WebAssembly - Try smaller model (TinyLlama) first
- Clear browser cache and reload
Model Downloads Slowly
Solutions:
- Check internet connection speed
- Look at browser Network tab to see download progress
- Models cache in IndexedDB after first download
- Try CDN-cached model (auto-retried by WebLLM)
Responses Are Short/Cut Off
Check:
maxTokenssetting (default: 512)- If model reached token limit:
model.maxTokens = 1024 - Model may have input token limit based on history
GPU Not Used
Check:
- Is GPU available?
AhmadWebLLMEngine.hasWebGPU() - Browser console shows "Using GPU" or "Using CPU"
- Some browsers/GPUs may force CPU mode
- Performance acceptable on CPU is normal
Unicode Not Preserved
Cause: Token sanitization too aggressive
Fix: ahmad-bot-ui.js line ~240 only removes control characters, preserves Unicode:
sanitizeToken(token) {
return token.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F]/g, '');
}
Testing
Automated End-to-End Test
// 1. Check components are loaded
console.log('Engine loaded:', typeof AhmadWebLLMEngine)
console.log('UI loaded:', typeof AhmadBotUI)
// 2. Check DOM elements
console.log('Launcher:', document.getElementById('jit-launcher'))
console.log('Panel:', document.getElementById('jit-panel'))
// 3. Open panel
window.ahmadBotUI.openPanel()
// 4. Wait for model (check status in UI)
// Status should change: OFFLINE โ LOADING โ READY
// 5. Send test message
document.getElementById('jit-input').value = 'What cells are in this notebook?'
window.ahmadBotUI.sendMessage()
// 6. Observe real tokens streaming
// Panel should show message from model with actual cells cited
Manual Testing Checklist
- Page loads, notebook visible
- ฮฉ button visible bottom-right, pulsing cyan
- Click ฮฉ button โ panel slides open
- Status shows "OFFLINE" โ "LOADING"
- Panel shows download progress or message
- After 5-20 minutes: status shows "READY"
- Type question, press Enter
- Status changes to "GENERATING"
- Tokens appear real-time in chat
- Response cites actual notebook cells
- Stop button works mid-generation
- Clear button empties chat
- Minimize button collapses panel to header
- Can drag panel by header
- Reload page โ model cached, loads faster
- Mobile: panel responsive at 95vw
Security & Privacy
โ All inference runs locally โ No data sent to servers โ No API keys required โ Model runs in browser โ No telemetry โ WebLLM may report model usage (optional) โ Notebook content never leaves browser โ Context built locally โ Token generation โ Pure model output, no filtering/modification
Unicode Support
Preserved exactly across all components:
ฮป (Lambda) โ Greek letter
ฮฉ (Omega) โ Greek letter
ฯ (Phi) โ Mathematical symbol
โ (Summation) โ Mathematical operator
๐ค (Samaritan) โ Ancient script
๊ฎ (Old Cyrillic) โ Historical script
โ โ โ โ โ Arrows
โ โ
โ โ โ Set notation
All preserved in:
- Notebook cell extraction
- Context indexing
- System prompt building
- Token streaming
- Message display
Future Enhancements
- Multi-turn fine-tuning corpus
- Notebook cell execution proposals
- WORM receipt signing for responses
- Model comparison UI
- Voice input/output
- Custom system prompts
- Response export
Support
For issues:
- Check browser console:
F12 โ Console - Verify WebLLM loaded:
console.log(window.webllm) - Check network: No CORS errors
- Try different model if error persists
- File issue with console output
Ahmad Bot โ Embedded AI for the Reversible World Ontology Math Notebook