# PRE 2.0 — Personal Reasoning Engine

[![CI](https://github.com/sunkencity999/pre/actions/workflows/ci.yml/badge.svg)](https://github.com/sunkencity999/pre/actions/workflows/ci.yml)

> A local AI operating system for macOS, Windows, and Linux. 79 tools, autonomous background agents, multi-model routing, self-improving calibration, knowledge graph, desktop automation, document intelligence, voice interface, event-driven triggers, 16 enterprise integrations, persistent memory, self-architecting virtual tools, and a full management GUI — running entirely on your hardware by default. No cloud required. Optionally connect any OpenAI-compatible API, Azure AI Foundry, or Anthropic endpoint for cloud-powered inference while keeping all tools, memory, and data local.

PRE is not a chatbot with tools bolted on. It is a **purpose-built agentic platform** — engineered from the ground up around one specific model on one specific hardware target, then generalized across platforms. Every architectural decision, from socket-level I/O to dynamic memory allocation to prompt compression, exists to make **Google Gemma 4 26B-A4B** run at its absolute ceiling on Apple Silicon. The result is a local agent that doesn't feel local: **~73 tokens/second**, sub-second time to first token, 128K context window, 79 integrated tools, persistent memory, local RAG, local image generation, autonomous scheduling, event-driven triggers, voice interface, a built-in web GUI, and real agentic workflows — all running on your hardware.

**PRE 2.0** adds four pillars that bring capabilities previously exclusive to frontier cloud agents:

| Pillar | What It Does | Why It Matters |
|--------|-------------|----------------|
| **Multi-Model Router** | Classifies messages by complexity and routes to fast, standard, or frontier models | Get instant answers for simple queries, full reasoning for complex ones — like Claude's model routing, but you control the tiers |
| **Autonomous Background Agents** | Fire-and-forget agents that run in parallel, survive sleep/hibernate/reboot, checkpoint every tool turn | Long-running research, code generation, and analysis tasks run autonomously while you work — something no other local agent offers |
| **Learning from Experience** | Calibrated self-knowledge, skill effectiveness tracking, knowledge graph, and training data export for personal fine-tuning | PRE knows what it's good at, understands how its knowledge connects, improves over time, and can export its experience as fine-tuning data — a closed feedback loop no cloud agent provides |
| **Self-Awareness** | Runtime operational state summary injected into every prompt — confidence, agents, triggers, graph stats | PRE knows exactly what it has running, where it's strong, and how much it's learned — no other local agent has introspective context |

PRE has two interfaces: a **CLI** (macOS Apple Silicon only, Objective-C) and a **Web GUI** (Node.js) that runs on **macOS (Apple Silicon + Intel with eGPU), Windows, and Linux**. The Web GUI provides full access to all 79 tools with platform-native implementations on each OS.

The reference system is a **MacBook Pro with an M4 Max (128 GB unified memory)**. Windows and Linux systems require an **NVIDIA GPU** (Linux also supports AMD via ROCm). Intel Macs are supported via **eGPU** (NVIDIA Ampere+ or AMD RDNA3+) using the [TinyGPU driver](https://docs.tinygrad.org/tinygpu/). All three installers auto-detect GPU VRAM and select the optimal quantization (28+ GB VRAM for q8_0, otherwise q4_K_M).

---

<p align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="docs/pre_poster.svg">
    <source media="(prefers-color-scheme: light)" srcset="docs/pre_poster.svg">
    <img alt="PRE Architecture Overview" src="docs/pre_poster_4x.png" width="800">
  </picture>
</p>

---

## Why This Exists

Most local AI tools follow a generic pattern: wrap an OpenAI-compatible API, connect a few tools, hope for the best. The result is sluggish, fragile, and useful mainly as a novelty. PRE takes the opposite approach — it is a **model-specific, platform-specific, vertically integrated agent** — and that specificity is what makes it competitive with cloud-based offerings like ChatGPT Pro, Claude Code, and Gemini Advanced, while keeping everything private and running on your own hardware.

### Where PRE 2.0 Matches or Exceeds Frontier Agents

| Capability | PRE 2.0 | Claude Code / ChatGPT Pro | Advantage |
|-----------|---------|--------------------------|-----------|
| **Tool count** | 79 (desktop, enterprise, creative, voice, RAG, training, knowledge graph) | ~10-20 (file, bash, web, browser) | 4-8x more tool coverage |
| **Background agents** | Fire-and-forget with sleep/reboot recovery | Not available (session-bound) | Run multi-hour tasks unattended |
| **Multi-model routing** | Fast/standard/frontier tiers, configurable | Fixed model per session | Optimize cost and speed per query |
| **Self-knowledge** | Calibrated confidence per tool category | None | PRE knows where it struggles and warns you |
| **Training data export** | Export your sessions as fine-tuning data (ChatML/Alpaca/ShareGPT/DPO) | Not available | Personal LoRA from your own usage |
| **On-device fine-tuning** | LoRA training on eGPU via tinygrad with live progress tracking | Not available | Train adapters locally without cloud |
| **GPU hot-plug** | Runtime eGPU detection, auto-start inference + training | Static config only | Plug in GPU anytime, PRE adapts |
| **Desktop automation** | Full Computer Use + workflow recording + replay | Limited or none | Automate any GUI application |
| **Enterprise integrations** | 16 services, native macOS/Windows apps | Varies; typically needs plugins | One interface for everything |
| **Privacy** | Everything local; data never leaves your machine | Cloud-only; data on provider servers | ITAR-safe, HIPAA-compatible |
| **Cost** | Zero marginal cost — unlimited prompts, agents, cron jobs | $20-200/month with rate limits | No per-token fees, no seat limits |
| **Scheduling** | Cron + event triggers + polling monitors | Not available | Autonomous tasks 24/7 |
| **Memory** | Persistent, auto-extracted, embedding-ranked, age-tracked | Session-scoped or limited persistence | Long-term learning across sessions |

### The Right Model for Agency

**Gemma 4 26B-A4B** is a Mixture-of-Experts (MoE) architecture: 26 billion total parameters, but only **3.8 billion active per token** (128 experts, 8 active per forward pass). This is the key to the entire system:

- **Speed without sacrifice.** 26B-parameter quality at ~4B computational cost. On Apple Silicon with q8_0 quantization (~28 GB, near-lossless), this means **~73 tokens/second** — fast enough that the agent's tool-call-execute-respond loop feels interactive, not glacial.

- **Context without collapse.** Gemma 4 supports up to 262K tokens natively. PRE allocates a **128K token window** — large enough for deep multi-step workflows (read 20 files, chain tool calls, iterate across 79 tools) while cold-loading in under 5 seconds. Auto-compaction at 75% extends effective session length indefinitely.

- **Strong instruction following.** Gemma 4 handles PRE's `<tool_call>` JSON format consistently — it doesn't hallucinate partial calls, forget to stop after calling a tool, or mangle JSON arguments. This sounds basic, but it's the #1 failure mode that makes local agents unusable.

- **Native multimodal input.** Gemma 4 accepts images natively — screenshot a UI bug, paste it in, and ask the model to analyze it. No separate vision model, no preprocessing pipeline.

### Platform-Specific Engineering

PRE doesn't abstract away the hardware — it leans into it:

| Layer | Optimization | Effect |
|-------|-------------|--------|
| **Streaming I/O** | Raw `recv()` with 64KB ring buffer, `memchr()` line scan | Zero-latency token delivery |
| **Context allocation** | `num_ctx` auto-sized from RAM, synced via `~/.pre/context` | ~5s cold load, no runtime reload penalty |
| **Prefix cache** | Stable system prompt prefix (identity + rules) separated from dynamic suffix (memory, date, cwd) | Prefix cache survives across requests — free prefill after turn 1 |
| **Parallel inference** | 2-slot inference queue: user requests get priority, background agents run in secondary slot | Background agents no longer block user chat on high-VRAM systems |
| **Structured output repair** | JSON Schema-constrained repair via Ollama `format` parameter as 4th-level fallback | Near-zero tool call failures from malformed JSON |
| **Dual backend** | Ollama (default) or llama.cpp server — installer auto-selects based on GPU type | NVIDIA users get Flash Attention + grammar constraints via llama.cpp |
| **Prompt compression** | Function-signature tool format (~8K tokens for 79 tools) | ~8% of 128K context, leaves 92% for conversation |
| **Model pre-warming** | `keep_alive: "24h"` + real warmup request at launch | Full KV cache pre-allocated, sub-second TTFT |
| **Server metrics** | Ollama-reported `eval_duration` / `prompt_eval_duration` | Ground-truth tok/s and TTFT numbers |

### What Makes It an Agent, Not a Chatbot

The difference is the **tool-call loop**. A chatbot generates text. An agent generates text, decides it needs more information, calls a tool, reads the result, decides what to do next, and repeats until the task is done. PRE delivers:

1. **Reliable tool calling** via Ollama's native structured function calling
2. **Fast execution** — each round-trip completes in 1-3 seconds for typical tools
3. **Sufficient context** — 128K window with auto-compaction holds extended multi-step sessions
4. **Autonomous scheduling** — cron jobs execute server-side, even when you're not at the computer
5. **Background autonomy** — fire-and-forget agents that survive sleep, hibernate, and reboot (PRE 2.0)
6. **Self-awareness** — runtime operational state (confidence scores, agent counts, trigger status, memory stats, knowledge graph) injected into every system prompt so PRE knows exactly what it has and where it's strong (PRE 2.0)
7. **Intelligent routing** — messages classified by complexity and dispatched to the right model tier (PRE 2.0)
8. **Knowledge graph** — entity-relationship graph layered over flat memory, with LLM-powered extraction and embedding-based traversal, so PRE understands how concepts connect — not just what it remembers (PRE 2.0)

This means PRE can:

- Read a stack trace, search the codebase, identify the bug, edit the fix, run the tests, and report the result — all from a single prompt
- Search your Gmail, summarize a thread, draft a reply, and save it — without you touching a browser
- Generate images locally, create documents, build artifacts, and export PDFs
- Run recurring tasks on a schedule — morning briefings, system checks, report generation — and deliver results via desktop notification and Telegram
- Manage Jira tickets, search Confluence wikis, update Smartsheet rows, and send Slack messages
- Delegate prompts to frontier AI models (Claude, Codex, Gemini) when cloud-level intelligence is needed — PRE becomes an agentic orchestration layer
- **Spawn background agents** for multi-hour research or analysis tasks that run autonomously, checkpoint their progress, and survive your laptop going to sleep (PRE 2.0)
- **Route simple queries to a fast model** ("what time is it in Tokyo?") and complex ones to your primary or frontier model — automatically, based on message classification (PRE 2.0)
- **Export your usage history as fine-tuning data** in ChatML, Alpaca, ShareGPT, or DPO formats — train a personal LoRA from your own workflows (PRE 2.0)
- **Fine-tune Llama models on your eGPU** using tinygrad's LoRA training backend — plug in an eGPU, PRE auto-detects it, and you can train adapters from your exported data without touching the cloud (PRE 2.0)
- **Run Llama inference on a dedicated eGPU** via tinygrad's OpenAI-compatible server — supplementary inference that auto-starts when GPU is detected and gracefully falls back to Ollama when unplugged (PRE 2.0)
- **Build a knowledge graph from its own memory** — entities (people, projects, tools, concepts) and typed relationships extracted automatically, with graph traversal queries that surface connections flat search would miss (PRE 2.0)

---

## Table of Contents

- [Quick Start](#quick-start)
- [What PRE Can Do](#what-pre-can-do)
- [What's New in 2.0](#whats-new-in-20)
- [What No Other Agent Does](#what-no-other-agent-does)
- [Installation](#installation)
- [Documentation](#documentation)
  - [Commands](#commands)
  - [Tools](#tools)
  - [Memory System](#memory-system)
  - [Projects & PRE.md](#projects--premd)
  - [Channels](#channels)
  - [Connections](#connections)
  - [Scheduling (Cron)](#scheduling-cron)
  - [Context Management](#context-management)
- [Best Practices](#best-practices)
- [Performance & Optimization](#performance--optimization)
- [Web GUI](#web-gui)
- [Frontier AI Delegation](#frontier-ai-delegation)
- [Remote Model Providers](#remote-model-providers)
- [Multi-Model Router](#multi-model-router)
- [Background Agents](#background-agents)
- [Learning from Experience](#learning-from-experience)
- [eGPU & tinygrad Integration](#egpu--tinygrad-integration)
- [Experience Ledger](#experience-ledger)
- [Chronos (Temporal Awareness)](#chronos-temporal-awareness)
- [MCP Server Support](#mcp-server-support)
- [Hooks System](#hooks-system)
- [Browser Agent](#browser-agent)
- [Telegram Integration](#telegram-integration)
- [Architecture](#architecture)

- [Configuration](#configuration)
- [Project Structure](#project-structure)
- [Contributing](#contributing)
- [License](#license)

---

## Quick Start

### macOS

```bash
git clone https://github.com/sunkencity999/pre.git
cd pre
./install.sh

# Launch (starts Ollama, CLI, and Web GUI)
pre-launch
```

The installer checks system requirements, installs Ollama if needed, pulls the base model (~28 GB), creates the optimized `pre-gemma4` model, builds the PRE binary, sets up the web GUI, installs `terminal-notifier` for clickable notifications, creates data directories, auto-sizes the context window based on your Mac's RAM, configures Ollama performance optimizations, pre-warms the model into GPU memory, and optionally enables auto-start at login. Pass `--yes` for a fully non-interactive install.

### Windows

```powershell
git clone https://github.com/sunkencity999/pre.git
cd pre
powershell -ExecutionPolicy Bypass -File install.ps1

# Launch the Web GUI
powershell -File web\pre-server.ps1
```

The Windows installer checks system requirements (Windows 10+, NVIDIA GPU, 16+ GB RAM), installs Ollama and Node.js via `winget` if needed, pulls the model, creates data directories, auto-sizes the context window, and optionally enables auto-start at login. Quantization is selected based on GPU VRAM: 28+ GB VRAM uses q8_0 (near-lossless, ~28 GB); smaller GPUs use q4_K_M (~15 GB) to keep the model fully on the GPU for maximum speed. Pass `-Yes` for non-interactive mode. The Web GUI runs at `http://localhost:7749`.

### Linux

```bash
git clone https://github.com/sunkencity999/pre.git
cd pre
./install-linux.sh

# Launch the Web GUI
cd web && ./pre-server.sh
```

The Linux installer supports Ubuntu 20.04+, Fedora 38+, and Arch-based distributions with an NVIDIA GPU (CUDA). It installs Ollama and Node.js via the system package manager, pulls the model, configures GNOME Evolution Data Server integration for calendar/contacts/tasks, sets up desktop automation via `xdotool`/`scrot`, and auto-sizes the context window. Pass `--yes` for non-interactive mode.

### What the installer does

All three installers follow the same pattern: check prerequisites, install missing dependencies, pull the Gemma 4 model from Ollama, auto-select quantization based on available memory, create `~/.pre/` data directories, size the context window, set up the Web GUI, and optionally configure auto-start. Everything stays local — no accounts, no cloud setup, no telemetry. The install is idempotent: running it again updates without breaking your existing data.

PRE detects your project, loads memories, and drops you into an interactive prompt:

```
╔══════════════════════════════════════════════════╗
║  Personal Reasoning Engine (PRE) 2.0            ║
║  Gemma 4 26B-A4B                                ║
╚══════════════════════════════════════════════════╝
  Server:  http://localhost:11434
  Web GUI: http://localhost:7749
  Project: my-project  /Users/you/my-project
  Channel: #general
  Memory:  3 entries loaded
  Type /help for commands

my-project #general>
```

---

## What PRE Can Do

PRE is a local AI operating system with 79 tools across six capability layers.

### Desktop Automation

**Control any application** — Computer Use sees your screen via vision and operates any GUI: click, type, scroll, drag, press key combos. No API needed — if you can see it, PRE can use it.

**Record and replay workflows** — Capture sequences of desktop actions and replay them on demand at configurable speed. Automate repetitive GUI tasks by doing them once. Manage saved workflows from the GUI panel.

**Control a browser** — Headless Chrome automation with vision feedback. Navigate, screenshot, click, type, scroll, read content, run JavaScript — all vision-aware.

### Document Intelligence

**Search documents semantically** — Local RAG indexes your files and searches by meaning. Ask "what files discuss authentication?" and get ranked results even when the exact word never appears. Powered by `nomic-embed-text` embeddings, fully local. Manage indexes from the GUI panel.

**Grow smarter over time** — An Experience Ledger captures lessons from past tasks and retrieves them via semantic similarity when relevant future tasks arise. Chronos temporal awareness flags stale memories and keeps the knowledge base current. Relevance-ranked memory injection uses embeddings to surface the most useful context for each query, not just the most recent.

**Extend itself** — Dynamic virtual tools let PRE create new reusable tools at runtime from prompt templates, recorded workflows, or multi-step chains. PRE architects its own capabilities as needed.

### Voice & Natural Input

**Talk to PRE** — Hold the microphone button in the GUI to record; release to transcribe via local Whisper. Text appears in the input box, ready to send. TTS speaks responses aloud (macOS `say` or Windows SAPI). No audio leaves your machine.

**Upload files and images** — Drag-and-drop, clipboard paste, or file picker. Gemma 4's native vision analyzes screenshots, diagrams, photos, CSVs, and code files.

### Reactive & Autonomous

**React to events** — File watchers, webhooks, and polling monitors fire prompts automatically when files change, HTTP requests arrive, or connected services have new activity. PRE handles it with the same tool loop it uses for everything else. Manage triggers from the GUI panel.

**Schedule recurring tasks** — Cron jobs with natural language input ("every weekday at 9am") run server-side even when the browser is closed. Results delivered via desktop notification, Telegram, and in-browser toast. Manage jobs from the GUI panel.

**Spawn sub-agents** — Delegate research tasks to autonomous sub-agents that run in parallel, each with restricted tool access and up to 10 tool calls.

**Launch background agents** (PRE 2.0) — Fire-and-forget autonomous agents that run long tasks (research, code generation, analysis) in the background while you continue working. Each agent gets its own session, checkpoints every tool turn, and survives system sleep, hibernation, and even reboots. Monitor status, cancel, and view results from the Agent Feed panel. No other local AI agent offers this.

**Monitor background processes** — Start long-running commands (builds, servers, log tails), check their output periodically, and stop them when done — without blocking the conversation.

**Argus companion** — An interactive session observer that watches PRE work in real time. Diagnoses errors with root-cause analysis and fix suggestions, relates observations to your stated goal (not just tool actions), filters out low-value noise with paraphrase detection, and supports reply-to-reaction micro-conversations where you can ask Argus to elaborate.

**Live dashboards** — Create HTML artifacts that auto-refresh with real-time data from Calendar, Mail, Reminders, and system stats via built-in `/api/live/*` endpoints.

### Enterprise Integrations

**16 services in one interface** — Jira, Confluence, SharePoint, Smartsheet, Slack, Linear, Zoom, Figma, Asana, Dynamics 365, Gmail, Google Drive, Google Docs, GitHub, Telegram, Brave Search, and Wolfram Alpha. Search Jira, cross-reference Confluence, pull a file from SharePoint, and post a summary to Slack — in one conversation.

**Native app integrations (zero config)** — Mail, Calendar, Contacts, Reminders, Notes, and Spotlight work immediately with whatever accounts you've configured. On macOS, uses Mail.app, Calendar.app, Contacts.app, Reminders.app, and Notes.app via AppleScript/EventKit. On Windows, uses Outlook COM for mail, calendar, contacts, and tasks, plus local markdown notes. Spotlight uses Windows Search on Windows. No API keys, no OAuth on either platform.

### Memory & Intelligence

**Remember across sessions** — Persistent memory auto-extracts from conversations, tracks age, and injects relevant context. Four types: user, feedback, project, reference. Browse and manage from the GUI panel.

**Know its own strengths** (PRE 2.0) — Calibrated self-knowledge tracks tool outcomes across 12 categories. High-confidence areas are surfaced as strengths; low-confidence areas trigger caution advisories. This is injected into every system prompt so PRE approaches tasks with appropriate confidence — something no frontier agent does.

**Learn and improve** (PRE 2.0) — PRE auto-discovers reusable skill patterns from your tool chains, generates behavioral guidance for each (decision trees, failure handling, quality criteria), tracks effectiveness over time, and recommends relevant skills via progressive disclosure — full guidance for strong matches, one-liners for partial matches, nothing for irrelevant tasks. Export your entire session history as fine-tuning data (ChatML, Alpaca, ShareGPT, DPO) to train a personal LoRA that captures your workflows.

**Route intelligently** (PRE 2.0) — The multi-model router classifies incoming messages by complexity and routes them to the optimal model: fast models for quick lookups, your primary model for standard work, frontier models for the hardest problems. Configurable tiers with automatic fallback.

**Run commands autonomously** — Nearly all 79 tools auto-execute; only genuinely destructive operations ask for confirmation.

**Read and modify your codebase** — Read files, glob/grep search, write and edit with checkpointed undo.

### Platform & Orchestration

**Full GUI management** — Every major capability has a sidebar panel: triggers, RAG indexes, workflows, memory, cron jobs, and settings. No CLI needed.

**Delegate to frontier AI** — Route prompts to Claude, Codex, or Gemini via dropdown. PRE detects installed CLIs, streams responses in real-time, and stores results alongside local messages.

**MCP server** — Frontier models can delegate execution-heavy tasks to PRE, saving API tokens. A 15-turn tool loop that would cost ~$2 in Claude tokens runs free on local hardware.

**Generate images** — Photorealistic images via ComfyUI on Apple Silicon. Juggernaut XL v9 (1024x1024) or SDXL Turbo (512x512). No cloud API.

**Create documents** — DOCX, XLSX, PDF, TXT, CSV, HTML artifacts. Download, open, or reveal in Finder.

**Extend with MCP servers** — Connect external MCP tool servers; their tools are automatically available to the model.

**Customize with hooks** — Pre/post tool execution hooks for auditing, safety guardrails, and workflow automation.

**Chat from your phone** — Telegram bot with full system access — same tools, same memory, same workflows.

**Respect your privacy** — Everything runs locally. Connection-dependent tools make API calls to their respective services; all other tools are fully local.

---

## What's New in 2.0

PRE 2.0 is a major release that adds three capability pillars previously available only in frontier cloud agents — or not available anywhere at all.

### Pillar 1: Multi-Model Router

PRE now classifies every incoming message by complexity and routes it to the optimal model tier:

| Tier | When | Example |
|------|------|---------|
| **Fast** | Simple lookups, time checks, greetings | "What time is it in Tokyo?" |
| **Standard** | Normal tool-using tasks, code work | "Read config.json and add a new field" |
| **Frontier** | Complex reasoning, architecture, multi-file analysis | "Refactor the auth system to use JWT" |

Configure via Settings or `/api/router`. The default fast model is **`pre-gemma4-fast`** (Gemma 4 E2B, 2B parameters, ~140 tok/s) — same model family as the main model with thinking disabled for instant responses. Standard uses `pre-gemma4`, and frontier delegates to Claude/Codex/Gemini. Classification happens in <100ms — faster than the model's time-to-first-token.

**No cloud agent offers this.** Claude Code and ChatGPT use a fixed model for every prompt. PRE adapts per-message.

### Pillar 2: Autonomous Background Agents

Spawn fire-and-forget agents for long-running tasks:

```
"Research all open GitHub issues, categorize them by severity, and write a summary report"
```

The agent runs in the background with its own session while you keep working. Key features:

- **GPU-serialized queue** — agents wait their turn for the GPU, no memory thrashing
- **Turn-level checkpointing** — every completed tool turn is checkpointed to disk
- **Sleep/hibernate recovery** — if your laptop sleeps, agents pause and resume automatically when it wakes
- **Reboot recovery** — if the process dies, agents resume from their last checkpoint on next startup
- **Agent Feed panel** — monitor all agents with colored status badges (Queued, Running, Completed, Failed, Paused, Interrupted), cancel buttons, and session links
- **WebSocket notifications** — toast alerts when agents complete or fail

**No other local AI agent offers background autonomy with crash recovery.** Even Claude Code and Cursor require an active session.

### Pillar 3: Learning from Experience

PRE 2.0 closes the feedback loop between usage and improvement:

**Calibrated Self-Knowledge** — Every tool call outcome (success/failure) and every user correction ("no, that's wrong") is tracked across 12 categories (file ops, bash, web, memory, code, calendar, email, cloud, image, documents, RAG, computer). Confidence scores are injected into the system prompt:

- Categories >=85% confidence appear as **strengths** — PRE approaches these tasks confidently
- Categories <60% appear as **caution areas** — PRE warns you and proceeds carefully
- User corrections are penalized at 2x weight — a single "that's wrong" matters more than a silent success

**Skill Effectiveness with Behavioral Guidance** — PRE auto-discovers reusable skill patterns from completed tool chains and generates behavioral guidance for each — decision trees, failure handling, quality criteria, and common pitfalls. Skills are tracked by outcome (success, failure, user correction) and recommended in context via progressive disclosure: high-confidence matches inject full guidance into the system prompt, partial matches show a one-liner, and irrelevant skills add nothing. Low-performing skills are automatically filtered out.

**Training Data Export** — Export your session history as fine-tuning data:

| Format | Use Case |
|--------|----------|
| **ChatML** | OpenAI fine-tuning API |
| **Alpaca** | Instruction tuning (LLaMA, Mistral) |
| **ShareGPT** | Multi-turn conversation fine-tuning |
| **DPO** | Preference optimization from your corrections |

Quality filtering ensures only substantive interactions (2+ tool calls, 50+ char responses, <30% error rate) make it into the export. Experience ledger entries are converted to instruction/output pairs. The result: a personal LoRA trained on exactly how you work.

**On-Device Fine-Tuning** — PRE 2.0 completes the loop with tinygrad-powered LoRA training on your eGPU. Export your sessions, start a training job from the GUI or via the `finetune` tool, and produce a personal LoRA adapter — all without touching the cloud. GPU hot-plug detection means you can plug in an eGPU anytime; PRE activates tinygrad inference and training automatically, and falls back to Ollama when unplugged.

**Knowledge Graph** — PRE automatically extracts entities (people, projects, tools, systems, concepts) and typed relationships from conversations, memories, and experiences. The graph is stored at `~/.pre/knowledge-graph.json` and grows incrementally every 6 conversation turns. When the model receives a query, an embedding-based graph traversal finds related entities and injects their connections into the system prompt — surfacing relationships that flat keyword search would miss. Query the graph directly with the `knowledge_graph` tool (neighbors, subgraph, stats), or let PRE build it from all existing memories in one pass.

**Runtime Self-Awareness** — Every system prompt includes a `<self_awareness>` block that tells PRE its current operational state: which tool categories it's strong in (with confidence percentages), how many background agents are running, which triggers and cron jobs are active, how many memories, experiences, training exports, and knowledge graph entities it has, and what the router is doing. The model doesn't have to ask — it already knows what it has.

**No cloud agent provides a feedback loop from usage to fine-tuning.** Your ChatGPT history trains OpenAI's models, not yours. With PRE, your experience stays yours — and your training runs on your hardware.

---

## What No Other Agent Does

The AI agent landscape in 2025 includes dozens of tools — Claude Code, OpenAI Codex CLI, Cursor, Windsurf, Aider, Continue.dev, Goose, and more. Each is capable within its niche. But they all share common architectural constraints that PRE was specifically built to overcome. This section maps PRE's unique capabilities against the field.

### Head-to-Head Comparison

| Capability | PRE | Claude Code | Codex CLI | Cursor | Windsurf | Aider | Goose |
|-----------|-----|------------|-----------|--------|----------|-------|-------|
| **Local inference (zero cost)** | Default | No (cloud API) | No (cloud API) | No (cloud) | No (cloud) | Optional | Optional |
| **Tool count** | 79 | ~15 | ~10 | ~25 | ~12 | ~10 | ~10 |
| **Background agents w/ crash recovery** | Yes | No | No | Partial | Partial | No | No |
| **Cron scheduling** | Yes | No | No | No | No | No | No |
| **Event-driven triggers** | Yes | No | No | No | No | No | No |
| **Self-improving calibration** | Yes | No | No | No | No | No | No |
| **Skill auto-discovery + behavioral guidance** | Yes | No | No | No | No | No | No |
| **Training data export** | Yes | No | No | No | No | No | No |
| **Native OS app integration** | Yes (Mail, Calendar, Contacts, Reminders, Notes) | No | No | No | No | No | No |
| **Desktop automation + workflow replay** | Yes | No | Limited | No | No | No | No |
| **16 enterprise integrations** | Yes | No (MCP only) | No | No | No | No | MCP only |
| **Local RAG (semantic search)** | Yes | No | No | Codebase only | Codebase only | Codebase map | No |
| **Local image generation** | Yes (ComfyUI) | No | No | No | No | No | No |
| **Voice interface** | Yes (Whisper + TTS) | No | No | No | No | Voice input only | No |
| **Persistent memory (auto-extracted, embedding-ranked)** | Yes | Project-scoped | No | Limited | No | No | No |
| **Multi-model routing** | Yes | No | No | Manual model picker | No | Manual | Manual |
| **Full management GUI** | Yes | CLI primary | CLI only | IDE-bound | IDE-bound | CLI only | Desktop app |
| **Monthly cost** | $0 | $20-200+ | API billing | $20+ | $15+ | API billing | Free + API |

### Seven Things Only PRE Does

**1. Self-Improving Intelligence**

PRE is the only agent that learns from its own performance. The calibration system tracks every tool call outcome across 12 categories and injects confidence scores into the system prompt — so PRE literally knows what it's good at and what it should be careful with. The skills engine auto-discovers reusable workflows from your usage, generates behavioral guidance (decision trees, failure handling, quality criteria) for each, and tracks effectiveness over time. Low-performing skills are filtered out; high-performing ones are recommended in context. No other agent — local or cloud — has a closed feedback loop from execution to self-knowledge.

And it goes further: export your entire session history as fine-tuning data in ChatML, Alpaca, ShareGPT, or DPO format. Train a personal LoRA that captures your specific workflows. Your usage data trains your model, not someone else's.

**2. True Autonomous Operation**

Most agents require an active session. PRE runs without you. Background agents execute multi-hour tasks, checkpoint every tool turn to disk, and survive system sleep, hibernation, and even full reboots — picking up exactly where they left off. Cron jobs fire server-side on a schedule (morning briefings, system health checks, competitive monitoring) and deliver results via desktop notification, Telegram, and browser toast. Event-driven triggers watch for file changes, listen for webhooks, and poll connected services on an interval. PRE is the only local agent that operates as a persistent service, not a session.

**3. Platform-Native OS Integration**

PRE directly integrates with your operating system's native applications — not through APIs, not through browser automation, but through the actual app frameworks:

- **macOS:** Mail.app (AppleScript), Calendar.app (EventKit/Swift), Contacts.app (AppleScript), Reminders.app (EventKit/Swift), Notes.app (AppleScript), Spotlight (mdfind)
- **Windows:** Outlook COM (mail, calendar, contacts, tasks), Windows Search, local markdown notes
- **Linux:** Evolution Data Server (GNOME calendar, contacts, tasks), local markdown notes

This means PRE accesses all your configured accounts — iCloud, Exchange, Gmail, IMAP — whatever you've set up in your OS. No API keys, no OAuth flows, no per-service configuration. No other AI agent touches native OS apps.

**4. Desktop Automation with Workflow Memory**

PRE doesn't just have Computer Use — it has Computer Use with institutional memory. Record a sequence of desktop actions (click, type, scroll, drag) and replay them on demand with configurable speed. Chain workflows into reusable custom tools. The vision loop (screenshot, interpret, act, verify) works on any GUI application on any platform. Other agents may offer basic Computer Use, but none combine it with workflow recording, replay, and tool composition.

**5. 79 Tools in a Single Interface**

Most AI agents ship with 10-25 tools focused on code editing. PRE ships with 79 spanning seven capability layers: file/code operations, desktop automation, document intelligence, voice I/O, enterprise integrations (Jira, Confluence, SharePoint, Smartsheet, Slack, Linear, Zoom, Figma, Asana, Dynamics 365, Gmail, Google Drive, GitHub, Telegram), reactive automation, GPU-accelerated training, and a knowledge graph. Search a Jira board, cross-reference a Confluence wiki, pull a file from SharePoint, draft a report, generate an image, and send it to Slack — in a single conversation. No context switching, no tab juggling.

**6. Zero Marginal Cost**

Cloud agents charge per token. A 15-turn agentic loop with tool calls costs $0.50-2.00 on Claude or GPT-4o. Run that 20 times a day and you're spending $300-1,200/month. PRE runs on your hardware with zero marginal cost — unlimited prompts, unlimited agents, unlimited cron jobs, unlimited everything. The economics change what's practical: you can run speculative research agents, schedule hourly monitoring jobs, and spawn parallel background agents without watching a billing dashboard.

**7. Privacy by Architecture**

PRE doesn't have a privacy policy — it has a privacy architecture. Inference runs on your GPU. Memory stays in `~/.pre/`. Sessions are JSONL files on your disk. Tool execution happens locally. Connection-dependent tools make API calls to their respective services (Jira, GitHub, etc.), but the model itself never sees a cloud server. This isn't a toggle or a setting — it's the default architecture. For organizations working under ITAR, HIPAA, or similar data sovereignty requirements, this matters: there is no data residency question because the data never leaves.

### What About Skills?

Anthropic's Claude ecosystem introduced a "Skills" concept — static instruction files (SKILL.md) that teach Claude how to perform specific workflows. It's a good idea, but it's manual: someone writes the skill, tests it, distributes it.

PRE takes this further with **progressive skill intelligence**:

1. **Auto-discovery** — PRE analyzes completed tool chains and automatically identifies reusable patterns worth saving as skills. No manual authoring required.
2. **Behavioral guidance** — Each auto-generated skill includes not just the mechanical steps (call X, then Y) but behavioral instructions: when to use it vs. alternatives, how to handle failures, quality criteria, common pitfalls. This teaches the model *how to think* about a domain, not just what tools to run.
3. **Progressive disclosure** — Skill context is injected into the system prompt proportionally to relevance. A strong match (>80%) gets full behavioral guidance. A partial match gets a one-liner. No match adds nothing. This prevents token waste while ensuring rich context when it matters.
4. **Effectiveness tracking** — Every skill execution is tracked by outcome (success, failure, user correction). Low-performing skills are automatically filtered from recommendations. High-performing skills surface more often. The system improves without intervention.

Static skills are a starting point. PRE's skills are alive — they emerge from usage, evolve with feedback, and die when they stop working.

---

## Installation

### macOS Prerequisites (Apple Silicon)

| Component | Required |
|-----------|----------|
| **macOS** | 14.0+ (Sonoma or later) |
| **Chip** | Apple Silicon (M1 or later) |
| **RAM** | 32 GB minimum, 64+ GB recommended |
| **Disk** | ~28 GB for model, +8 GB for image generation (optional) |
| **Ollama** | [ollama.ai](https://ollama.ai) or `brew install ollama` |
| **Xcode CLI** | `xcode-select --install` |
| **Node.js 18+** | For web GUI (`brew install node`) |
| **Python 3.10-3.13** | Optional — for ComfyUI image generation |

### macOS Prerequisites (Intel + eGPU)

| Component | Required |
|-----------|----------|
| **macOS** | 12.1+ (Monterey or later) |
| **Chip** | Intel x86_64 |
| **eGPU** | NVIDIA Ampere+ (RTX 3000+) or AMD RDNA3+ via Thunderbolt/USB4 |
| **TinyGPU** | [tinygrad TinyGPU driver](https://docs.tinygrad.org/tinygpu/) (Apple-signed) |
| **Docker Desktop** | Required for NVIDIA CUDA path ([docker.com](https://www.docker.com/products/docker-desktop/)) |
| **RAM** | 16 GB minimum (model runs on eGPU VRAM) |
| **eGPU VRAM** | 16+ GB (q4_K_M); 28+ GB for q8_0 |
| **Disk** | ~15 GB (q4_K_M) or ~28 GB (q8_0) for model |
| **Ollama 0.4+** | [ollama.ai](https://ollama.ai) (auto-detects TinyGPU) |
| **Node.js 18+** | For web GUI (`brew install node`) |

> **Note:** Intel Macs run the Web GUI only (CLI requires Apple Silicon). PRE detects eGPU connections at runtime (30-second polling) — you can plug in an eGPU after PRE is already running and it will be detected automatically.

### Windows Prerequisites

| Component | Required |
|-----------|----------|
| **Windows** | 10 or 11 |
| **GPU** | NVIDIA (for Ollama GPU inference) |
| **RAM** | 16 GB minimum, 64+ GB recommended for large context windows |
| **GPU VRAM** | 16+ GB (q4_K_M); 28+ GB for q8_0 — model must fit in VRAM for full speed |
| **Disk** | ~15 GB (q4_K_M) or ~28 GB (q8_0) for model |
| **Ollama** | [ollama.ai](https://ollama.ai) or installed via `winget` by the installer |
| **Node.js 18+** | Installed via `winget` by the installer |

### Linux Prerequisites

| Component | Required |
|-----------|----------|
| **Distro** | Ubuntu 22.04+, Debian 12+, Fedora 38+ (Arch best-effort) |
| **GPU** | NVIDIA with CUDA (for Ollama GPU inference); AMD ROCm future |
| **RAM** | 16 GB minimum, 64+ GB recommended for large context windows |
| **GPU VRAM** | 16+ GB (q4_K_M); 28+ GB for q8_0 — model must fit in VRAM for full speed |
| **Disk** | ~15 GB (q4_K_M) or ~28 GB (q8_0) for model |
| **Ollama** | Installed via official script by the installer |
| **Node.js 18+** | Via nvm, nodesource, or distro package |

**Optional:** `evolution-data-server` (calendar/contacts/reminders via GNOME EDS), `xdotool` + `scrot` (desktop automation, X11), `espeak-ng` (TTS), `xclip` (clipboard).

### macOS Install

```bash
git clone https://github.com/sunkencity999/pre.git
cd pre
./install.sh
```

The installer handles everything: system validation, Ollama, model pull, binary compilation, web GUI dependencies, terminal-notifier, ComfyUI (optional), data directories, RAM-based context window sizing, MCP auto-setup for Claude/Codex/Antigravity, model pre-warming, fast tier model creation (`pre-gemma4-fast`), inference backend selection (Ollama vs llama.cpp), and optional auto-start at login.

**Inference backend:** The installer auto-selects the best backend for your hardware. NVIDIA GPU users (via eGPU) get **llama.cpp** (Flash Attention + GBNF grammar constraints). Apple Silicon users get **Ollama** (simpler model management, similar performance). You can switch backends anytime from Settings.

```bash
./install.sh --yes   # Non-interactive — accepts all defaults
```

Or install manually:

```bash
# Pull the base model (~28 GB)
ollama pull gemma4:26b-a4b-it-q8_0

# Create the optimized model
cd pre/engine
ollama create pre-gemma4 -f Modelfile

# Build PRE CLI + Telegram bot
make pre telegram

# Web GUI
cd ../web && npm install

# Optional: clickable cron notifications
brew install terminal-notifier

# Add to PATH
make install
# or: ln -sf "$(pwd)/pre-launch" ~/.local/bin/pre-launch
```

### Windows Install

```powershell
git clone https://github.com/sunkencity999/pre.git
cd pre
```

**Easiest:** Double-click `install.cmd` in the `pre` folder. This handles execution policy automatically.

**From a terminal:**
```powershell
powershell -ExecutionPolicy Bypass -File install.ps1
powershell -ExecutionPolicy Bypass -File install.ps1 -Yes   # Non-interactive
```

The installer checks system requirements, installs Ollama and Node.js via `winget`, pulls the model, creates the fast tier model (`pre-gemma4-fast`), creates `~/.pre/` directories, auto-sizes the context window based on RAM, offers **llama.cpp** as the default backend for NVIDIA GPUs (with Ollama as fallback for embeddings), configures Ollama environment variables, and optionally enables auto-start at login.

> **Note:** The Windows installer sets up the **Web GUI only**. The CLI engine (`pre.m`) is an Objective-C application that requires macOS. The Telegram bot is included in the Web GUI and works on all platforms.

### Linux Install

```bash
git clone https://github.com/sunkencity999/pre.git
cd pre
./install-linux.sh
```

The installer detects your distro and package manager (apt/dnf/pacman), checks NVIDIA VRAM via `nvidia-smi`, installs Ollama, pulls the model with VRAM-aware quant selection, creates the fast tier model (`pre-gemma4-fast`), offers **llama.cpp** as the default backend for NVIDIA GPUs, installs Node.js dependencies, auto-sizes the context window, and optionally installs voice tools, GNOME PIM integration (evolution-data-server), desktop automation tools (xdotool/scrot), and systemd autostart.

> **Note:** Linux runs the **Web GUI only**. The CLI engine requires macOS. Native app integration (calendar, contacts, reminders) requires GNOME with Evolution Data Server.

### Launch (macOS)

**Easiest:** Double-click `Launch PRE.command` in the repo root. Starts Ollama, launches the server, and opens your browser.

**Menu bar app:** `PRE.app` (built via `make menubar`) sits in the macOS menu bar with a status indicator, start/stop/restart controls, and quick browser launch.

**From a terminal:**
```bash
pre-launch                         # From any directory
pre-launch --dir /path/to/project  # Override working directory
pre-launch --show-think            # Start with visible reasoning
pre-launch --max-tokens 16384      # Allow longer responses
```

The launcher checks Ollama, creates `pre-gemma4` if needed, pre-warms the model into GPU memory, starts the web GUI on port 7749, and launches the PRE CLI.

### Launch (Windows)

**Easiest:** Double-click `Launch PRE.cmd` in the repo root. Starts Ollama, launches the server, and opens your browser.

**System tray:** Double-click `PRE Tray.cmd` for a notification area icon with start/stop/restart controls, status indicator, and quick browser launch. Right-click the tray icon for options.

**From a terminal:**
```powershell
powershell -File web\pre-server.ps1           # Start Web GUI server
powershell -File web\pre-server.ps1 --status  # Check if running
powershell -File web\pre-server.ps1 --stop    # Stop the server
```

The Windows launcher starts Ollama if needed, pre-warms the model, and starts the Web GUI on port 7749. Open `http://localhost:7749` in your browser.

### Launch (Linux)

```bash
cd pre/web
./pre-server.sh                  # Start server
./pre-server.sh --status         # Check if running
./pre-server.sh --stop           # Stop
```

Or directly: `cd web && node server.js`. If installed with systemd autostart, the server starts at login automatically. Open `http://localhost:7749` in your browser.

### Updating

PRE includes update scripts that detect your install type (git clone vs. zip download) and update accordingly. User data in `~/.pre/` is never touched.

**macOS:**
```bash
# Double-click "Update PRE.command" in Finder, or from a terminal:
bash update.sh
bash update.sh --yes   # Non-interactive
```

**Windows:**
```powershell
# Double-click "Update PRE.cmd", or from a terminal:
powershell -ExecutionPolicy Bypass -File update.ps1
powershell -ExecutionPolicy Bypass -File update.ps1 -Yes   # Non-interactive
```

The update script compares your local `VERSION` file against the latest release on GitHub, stops the server if running, pulls changes (git) or downloads a fresh zip (non-git installs), runs `npm install`, detects Modelfile changes, and restarts the server if it was running.

---

## Documentation

### Commands

Type `/help` for the full list, or `/help <topic>` for detailed guides.

#### Chat & Input

| Command | Description |
|---------|-------------|
| *(type a message)* | Send to the model |
| `!command` | Run a shell command (output stays local) |
| `/edit` | Open `$EDITOR` for multi-line prompts |
| `/file <path>` | Attach a file to next message |
| `/run <cmd>` | Run a command, optionally feed output to model |

#### Session Management

| Command | Description |
|---------|-------------|
| `/new` | Fresh session in current channel |
| `/sessions` | List all saved sessions |
| `/resume <id>` | Resume a previous session |
| `/rename <name>` | Name the current session |
| `/rewind [N]` | Remove last N turns (default: 1) |
| `/save <path>` | Save last response to a file |
| `/export [path]` | Export conversation to markdown |
| `/summary` | Model-generated session summary |

#### Navigation & Project

| Command | Description |
|---------|-------------|
| `/cd <path>` | Change directory (re-detects project) |
| `/ls [path]` | List directory |
| `/tree [path]` | Directory tree (depth 3) |
| `/project` | Show detected project info |
| `/channel [name]` | List or switch channels |

#### Memory & Status

| Command | Description |
|---------|-------------|
| `/memory [query]` | List or search memories |
| `/forget <query>` | Delete a memory |
| `/context` | Context window usage bar |
| `/status` | Current state overview |
| `/stats` | Detailed session statistics |
| `/undo` | Revert last file change |
| `/think` | Toggle reasoning visibility |
| `/name <name>` | Rename your agent |
| `/pdf [title]` | Export artifact to PDF |

#### Scheduling

| Command | Description |
|---------|-------------|
| `/cron add <schedule> <prompt>` | Schedule a recurring task |
| `/cron list` | List all scheduled tasks |
| `/cron rm <id>` | Remove a scheduled task |

---

### Tools

PRE has 79 tools that the model calls autonomously. Nearly all auto-execute without confirmation:

- **Auto** — executes immediately (55+ tools)
- **Confirm always** — asks every time (3 tools: `process_kill`, `memory_delete`, `applescript`)
- **Hook-controlled** — optional pre/post hooks can block or audit any tool call

#### File & Code

| Tool | Args | Description |
|------|------|-------------|
| `read_file` | `path` | Read file contents |
| `list_dir` | `path` | List directory contents |
| `glob` | `pattern`, `path`? | Find files by glob pattern |
| `grep` | `pattern`, `path`?, `include`? | Search file contents (regex) |
| `file_write` | `path`, `content` | Create or overwrite a file (checkpointed, `/undo`-able) |
| `file_edit` | `path`, `old_string`, `new_string` | Find-and-replace in a file (checkpointed, `/undo`-able) |

#### Shell & Process

| Tool | Args | Description |
|------|------|-------------|
| `bash` | `command` | Execute a shell command |
| `process_list` | `filter`? | List running processes |
| `process_kill` | `pid` | Send SIGTERM to a process *(confirm always)* |

#### System Inspection

| Tool | Args | Description |
|------|------|-------------|
| `system_info` | *(none)* | CPU, memory, disk, battery overview |
| `hardware_info` | *(none)* | Detailed hardware, thermal sensors, GPU info |
| `disk_usage` | `path`? | Volume and directory usage |
| `display_info` | *(none)* | Display resolution and GPU details |

#### Network

| Tool | Args | Description |
|------|------|-------------|
| `net_info` | *(none)* | Interfaces, IPs, DNS, routes |
| `net_connections` | `filter`? | TCP connections (listening/established/port) |
| `service_status` | `service`? | List or search launchd services |

#### Desktop Integration

| Tool | Args | Description |
|------|------|-------------|
| `computer` | `action`, `coordinate`?, `text`?, `key`? | Desktop automation via screenshot → vision → click/type/scroll loop (macOS: `cliclick`; Windows: user32.dll) |
| `screenshot` | `region`? | Capture screen (full/window/region/x,y,w,h) |
| `window_list` | *(none)* | List open windows with positions |
| `window_focus` | `app` | Bring an app to front |
| `clipboard_read` | *(none)* | Read clipboard contents |
| `clipboard_write` | `content` | Write to clipboard |
| `open_app` | `target` | Open files/apps/URLs (macOS `open` / Windows `start`) |
| `notify` | `title`, `message` | Show a desktop notification (macOS osascript / Windows PowerShell toast) |
| `applescript` | `script` | Run arbitrary AppleScript *(confirm always, macOS only)* |

#### Native macOS Apps *(macOS only)*

| Tool | Args | Description |
|------|------|-------------|
| `apple_mail` | `action`, `to`?, `subject`?, `body`? | macOS: Mail.app via AppleScript; Windows: Outlook COM — search, read, send, reply |
| `apple_calendar` | `action`, `title`?, `start`?, `end`? | macOS: Calendar.app via EventKit/Swift; Windows: Outlook COM — list, create, delete events |
| `apple_contacts` | `action`, `query`? | macOS: Contacts.app via AppleScript; Windows: Outlook COM — search, read contacts |
| `apple_reminders` | `action`, `title`?, `list`? | macOS: Reminders.app via EventKit/Swift; Windows: Outlook Tasks COM — list, create, complete, delete |
| `apple_notes` | `action`, `title`?, `body`? | macOS: Notes.app via AppleScript; Windows: local markdown files in `~/.pre/notes/` |

> On macOS, these tools use AppleScript and EventKit with whatever accounts are configured in System Settings. On Windows, they use Outlook COM automation (requires Outlook installed) for mail, calendar, contacts, and tasks; notes use local markdown files.

#### File Search

| Tool | Args | Description |
|------|------|-------------|
| `spotlight` | `query`, `kind`?, `scope`? | Full-text file search (macOS: Spotlight/mdfind; Windows: Windows Search with Get-ChildItem fallback) |

#### Web

| Tool | Args | Description |
|------|------|-------------|
| `web_fetch` | `url` | Fetch a URL (HTML to text conversion) |

#### Creative & Export

| Tool | Args | Description |
|------|------|-------------|
| `artifact` | `title`, `content`, `type`, `append_to`? | Create/append rich HTML artifacts |
| `document` | `title`, `format`, `sheets`? | Generate DOCX, XLSX, TXT, CSV, HTML documents |
| `image_generate` | `prompt`, `width`?, `height`?, `style`? | Generate images via ComfyUI (MPS) |

#### Memory

| Tool | Args | Description |
|------|------|-------------|
| `memory_save` | `name`, `type`, `description`, `content` | Save a persistent memory |
| `memory_search` | `query`? | Search saved memories |
| `memory_list` | *(none)* | List all memories |
| `memory_delete` | `query` | Delete a memory *(confirm always)* |

#### Experience & Temporal Awareness

| Tool | Args | Description |
|------|------|-------------|
| `experience_search` | `query` | Search the experience ledger for lessons from past tasks (semantic similarity) |
| `experience_list` | *(none)* | List all experience ledger entries |
| `memory_health` | *(none)* | Check memory staleness, aging warnings, and overall health |

The experience ledger builds automatically — after each task with 2+ tool calls, PRE reflects on what happened and extracts reusable lessons. Semantic search uses `nomic-embed-text` embeddings (768-dim) so queries match on meaning, not just keywords.

#### Browser Automation

| Tool | Args | Description |
|------|------|-------------|
| `browser` | `action`, `url`?, `selector`?, `text`?, `x`?, `y`?, `key`?, `script`? | Control headless Chrome: navigate, screenshot, click, type, press, scroll, read, evaluate, select, back, forward, wait, close |

The browser tool returns screenshots as base64 images after each action, enabling the model to visually understand and interact with web pages. The `select` action lists all interactive elements with their coordinates, making it easy for the model to target specific UI elements.

#### Sub-Agents

| Tool | Args | Description |
|------|------|-------------|
| `spawn_agent` | `task` | Spawn an autonomous research agent with restricted tool access |
| `spawn_multi` | `tasks` (JSON array) | Run up to 5 research agents in parallel with progress streaming |
| `list_agents` | *(none)* | List all spawned agents and their status |
| `monitor` | `action`, `command`?, `name`?, `id`?, `tail`? | Background process monitor: start, read, stop, or list long-running commands |

Sub-agents run independently with access to read-only tools (bash, files, web, memory, system info) plus any connected MCP tools. Each agent gets up to 10 tool turns and returns a concise summary. `spawn_multi` launches all agents concurrently via `Promise.all` — tool I/O runs in parallel even though Ollama serializes model inference.

#### Background Agents (PRE 2.0)

| Tool | Args | Description |
|------|------|-------------|
| `background_agent` | `action`, `task`?, `id`? | Spawn fire-and-forget autonomous agents. Actions: `spawn` (start a new agent), `status` (check one agent), `list` (all agents), `result` (get output), `cancel` (stop an agent) |

Background agents run in dedicated sessions under the "Background Agents" project, GPU-serialized to prevent memory thrashing. Each agent checkpoints every tool turn to disk and survives sleep, hibernate, and reboot. Monitor from the Agent Feed panel in the GUI.

#### Learning & Self-Knowledge (PRE 2.0)

| Tool | Args | Description |
|------|------|-------------|
| `training_export` | `action`, `format`?, `project`?, `min_tool_calls`?, `include_experience`? | Export session history as fine-tuning data. Actions: `preview` (stats without exporting), `export` (write JSONL), `list` (show previous exports). Formats: `chatml`, `alpaca`, `sharegpt`, `dpo` |
| `finetune` | `action`, `base_model`?, `training_data`?, `name`?, `id`?, `format`?, `lora_rank`?, `epochs`?, `quantization`? | LoRA fine-tuning on eGPU via tinygrad. Actions: `start` (begin training), `status` (check progress), `list` (all jobs), `cancel` (stop job), `adapters` (list saved adapters). Requires NVIDIA GPU. |
| `calibration` | `action` | View or reset self-knowledge data. Actions: `report` (show confidence per category with visual bar chart), `reset` (clear all calibration data) |

Aliases: `training`, `export_training`, `training_data` resolve to `training_export`. `lora`, `fine_tune`, `lora_train` resolve to `finetune`. `confidence`, `self_knowledge`, `accuracy` resolve to `calibration`.

#### Scheduling

| Tool | Args | Description |
|------|------|-------------|
| `cron` | `action`, `schedule`?, `prompt`?, `id`? | Manage recurring scheduled tasks |

#### Connection-Dependent Tools

These require API keys or OAuth setup via `/connections` or the web GUI Settings panel.

| Tool | Connection | Description |
|------|------------|-------------|
| `web_search` | Brave Search (or DuckDuckGo fallback) | Web search — uses Brave API if configured, DuckDuckGo otherwise |
| `github` | GitHub | Search repos, issues, PRs, user info |
| `gmail` | Google | Search, read, send, draft, trash, labels |
| `gdrive` | Google | List, search, download, upload, share |
| `gdocs` | Google | Create, read, append documents |
| `telegram` | Telegram | Send messages, photos, check updates |
| `jira` | Jira | Search issues, create, update, transition |
| `confluence` | Confluence | Search pages, read, create, update |
| `smartsheet` | Smartsheet | List sheets, search rows, add/update rows |
| `slack` | Slack | Send messages, list channels, reply, react |
| `linear` | Linear | Search/create/update issues, manage cycles and projects |
| `zoom` | Zoom | Create/list meetings, manage recordings |
| `figma` | Figma | Inspect files, export images, post comments |
| `asana` | Asana | List/create/search tasks, manage projects |
| `sharepoint` | Microsoft 365 | List sites, search/upload/download files |
| `dynamics365` | Dynamics 365 | Search, records (CRUD), entity metadata, OData queries |
| `wolfram` | Wolfram Alpha | Computation, math, science, data queries |

#### Local RAG (Document Intelligence)

| Tool | Args | Description |
|------|------|-------------|
| `rag` | `action`, `path`?, `query`?, `index_name`?, `top_k`? | Index directories and search them semantically using `nomic-embed-text` embeddings. Actions: `index`, `search`, `list`, `status`, `delete` |

Indexes directories of text files, splits them into chunks at paragraph boundaries, generates 768-dim embeddings via Ollama, and searches by cosine similarity. Incremental re-indexing skips unchanged files. Storage: `~/.pre/rag/{index_name}/`.

#### Event-Driven Triggers

| Tool | Args | Description |
|------|------|-------------|
| `trigger` | `action`, `type`?, `path`?, `prompt`?, `name`?, `glob`?, `secret`?, `services`?, `interval_minutes`? | Create file watchers, webhooks, and polling monitors that fire prompts automatically. Actions: `add`, `list`, `remove`, `enable`, `disable` |

File watchers monitor directories for changes (debounced, glob-filtered). Webhooks listen at `/api/triggers/webhook/:id` with optional secret verification. Polling monitors check connected services (GitHub, Gmail, Jira, Slack, Calendar) on a configurable interval (default 60 min, minimum 15 min) and generate briefings. All three types use the same execution pipeline as cron — triggers create sessions, run tool loops, and deliver notifications.

#### Voice Interface

| Tool | Args | Description |
|------|------|-------------|
| `voice` | `action`, `text`?, `path`?, `audio_base64`?, `voice`?, `rate`? | Speech-to-text via Whisper (local) and text-to-speech (macOS `say` / Windows SAPI). Actions: `transcribe`, `speak`, `voices`, `status` |

Requires `pip install openai-whisper` for STT. TTS uses macOS built-in `say` (25+ English voices) or Windows SAPI (`System.Speech.Synthesis`). Browser-side recording via Web Audio API → base64 → local Whisper transcription.

#### Workflow Capture and Replay

| Tool | Args | Description |
|------|------|-------------|
| `workflow` | `action`, `name`?, `description`?, `speed`? | Record Computer Use action sequences and replay them. Actions: `record`, `stop`, `status`, `list`, `replay`, `show`, `delete`, `export` |

Records click/type/key/scroll/drag actions during Computer Use with inter-step timing. Replay re-executes steps with configurable speed multiplier. Observation-only actions (screenshot, screen_size) are filtered out. Storage: `~/.pre/workflows/`.

#### Dynamic Virtual Tools (Self-Architecting)

| Tool | Args | Description |
|------|------|-------------|
| `custom_tool` | `action`, `name`?, `description`?, `template`?, `steps`?, `parameters`?, `workflow_name`?, `guidance`? | Create, manage, and execute self-defined virtual tools at runtime. Actions: `create`, `list`, `show`, `delete`, `from_workflow` |

Build reusable parameterized tools from prompt templates (`${param}` substitution), recorded workflows, or multi-step tool chains. Created tools appear as `custom_<name>` in the tool list and can be called by the model like any built-in tool. Chain steps can reference previous results via `${step1}`, `${step2}`, etc. The optional `guidance` field (Markdown) attaches behavioral instructions — decision trees, failure handling, quality criteria — that teach the model *how to think* about using the tool, not just what steps to run. Guidance is injected into the system prompt via progressive disclosure: full instructions for strong matches, one-liner for partial matches, nothing for irrelevant tasks. Storage: `~/.pre/custom_tools/`.

---

### Memory System

PRE has persistent, file-based memory that survives across sessions and restarts.

#### How It Works

Memories are markdown files with YAML frontmatter stored in `~/.pre/memory/` (global) or `~/.pre/projects/{name}/memory/` (project-scoped). Relevant memories are injected into context at the start of each session.

#### Memory Types

| Type | Purpose | Example |
|------|---------|---------|
| `user` | About you — role, preferences, expertise | "Senior Python dev, prefers type hints" |
| `feedback` | How to work — corrections and confirmations | "Don't add docstrings to unchanged code" |
| `project` | Current work — decisions, deadlines, context | "Auth rewrite driven by compliance" |
| `reference` | External pointers — where info lives | "Bugs tracked in Linear project INGEST" |

#### Three Ways Memories Are Created

1. **Auto-extraction** — The web GUI analyzes conversations and automatically saves important facts (throttled: every 3 turns, 60-second cooldown)
2. **Model-initiated** — The model saves memories proactively when it learns something important
3. **Explicit** — Tell PRE what to remember: "Remember that I prefer functional style over classes"

#### Managing Memories

```
/memory              # List all memories
/memory auth         # Search for "auth" in memories
/forget "old rule"   # Delete a memory (with confirmation)
```

The web GUI includes a **Memory Browser** panel (book icon in sidebar footer) for viewing and managing memories visually.

---

### Projects & PRE.md

#### Auto-Detection

PRE detects project boundaries by walking up from your working directory looking for:

`.git` · `package.json` · `pyproject.toml` · `Cargo.toml` · `go.mod` · `Makefile` · `CMakeLists.txt` · `pom.xml` · `PRE.md`

When a project is detected, PRE loads project-scoped memories, scopes channels to the project, and shows the project name in the prompt.

#### PRE.md — Project Configuration

Place a `PRE.md` file in your project root to give the model project-specific instructions:

```markdown
# My API Service

FastAPI application with PostgreSQL and Redis.

## Conventions
- Use async/await for all I/O
- Type hints required on all public functions
- Tests in tests/ — run with: pytest -xvs
```

The web GUI supports **Projects** with drag-and-drop session organization — group related sessions under a named project.

---

### Channels

Channels are named conversation threads scoped to a project. Each channel has its own message history and context.

```
/channel                 # List channels
/channel refactor        # Switch to #refactor
/channel debug-auth      # Separate thread for debugging
/new                     # Fresh session in current channel
```

Long conversations accumulate context. Switching channels gives you a clean context without losing your previous thread.

---

### Connections

PRE integrates with external services via API keys and OAuth. Configure via `/connections` in the CLI or the **Settings** panel in the web GUI.

| Service | Auth Type | Tools Unlocked |
|---------|-----------|----------------|
| **Google** | Built-in OAuth 2.0 | `gmail`, `gdrive`, `gdocs` |
| **Telegram** | Bot token (@BotFather) | Phone access + cron delivery |
| **Slack** | Bot OAuth token (xoxb-) | `slack` |
| **Brave Search** | API key | `web_search` (enhanced — DuckDuckGo fallback works without config) |
| **GitHub** | Personal access token | `github` |
| **Jira** | URL + API token | `jira` |
| **Confluence** | URL + API token | `confluence` |
| **Smartsheet** | API token | `smartsheet` |
| **Linear** | API key | `linear` |
| **Zoom** | Server-to-Server OAuth (Account ID + Client ID + Secret) | `zoom` |
| **Figma** | Personal access token | `figma` |
| **Asana** | Personal access token | `asana` |
| **Microsoft 365** | Client ID + refresh token | `sharepoint` |
| **Dynamics 365** | URL + Client ID + Client Secret + Tenant ID | `dynamics365` |
| **Wolfram Alpha** | API key | `wolfram` |

**Google** uses built-in OAuth — just sign in via your browser. No Google Cloud Console setup required. Multi-account supported: `/connections add google work`.

**Telegram** automatically starts as a background process when PRE launches.

All tokens are stored locally in `~/.pre/connections.json` and refreshed automatically.

---

### Scheduling (Cron)

PRE includes a full cron scheduling system for recurring autonomous tasks. Jobs execute **server-side** — no browser or terminal needs to be open.

#### How It Works

1. **Create a job** — via the web GUI cron panel (clock icon in sidebar) or the CLI (`/cron add`)
2. **Natural language scheduling** — type "every morning at 9am" or "weekdays at 8:30am" instead of raw cron expressions
3. **Server-side execution** — when a job fires, the server runs the prompt through the full agent tool loop headlessly
4. **Dedicated sessions** — each run creates its own chat session you can review, continue, or reference
5. **Multi-channel delivery** — results are delivered via all configured channels:

| Channel | Behavior |
|---------|----------|
| **Desktop notification** | Always sent. On macOS, uses `terminal-notifier` for clickable notifications. On Windows, uses PowerShell toast notifications. |
| **Telegram** | Sent if bot token is configured. Full result preview in your Telegram chat. |
| **GUI toast** | Shown if the browser is open. Slide-in notification with "View Result" button. |

#### Natural Language Schedule Input

The web GUI accepts plain English for scheduling:

| Input | Cron Expression | Description |
|-------|----------------|-------------|
| "every morning at 9am" | `0 9 * * *` | Daily at 9:00 AM |
| "weekdays at 8:30am" | `30 8 * * 1-5` | Weekdays at 8:30 AM |
| "every 15 minutes" | `*/15 * * * *` | Every 15 minutes |
| "monday and friday at 3pm" | `0 15 * * 1,5` | Mon & Fri at 3:00 PM |
| "monthly on the 1st at 10am" | `0 10 1 * *` | 1st of each month |
| "twice a day" | `0 9,17 * * *` | 9 AM and 5 PM |
| "every half hour" | `*/30 * * * *` | Every 30 minutes |

Raw cron expressions (e.g. `0 */2 * * 1-5`) are also accepted with passthrough.

#### Use Cases

- **Morning briefing** — "Summarize my calendar and top priorities for today"
- **System health check** — "Check disk usage, memory, and running services. Alert if anything is abnormal."
- **Competitive monitoring** — "Search for news about [company] and summarize findings"
- **Report generation** — "Generate a weekly project status report from git activity"
- **Data pipeline monitoring** — "Check the ETL job status and report any failures"

#### Managing Jobs

| Method | How |
|--------|-----|
| **Web GUI** | Clock icon in sidebar footer — visual panel with live preview, enable/disable toggle, run now, view last result |
| **CLI** | `/cron add "0 9 * * 1-5" "Morning briefing"`, `/cron list`, `/cron rm <id>` |
| **Model tool** | The model can create cron jobs autonomously via the `cron` tool |

---

### Context Management

PRE manages Gemma 4's context window with a **consistent token allocation** set once at install time and synced across all components.

**How it works:** The installer detects your Mac's RAM and writes the optimal context size to `~/.pre/context`. The CLI, web GUI, and launcher all read this file at startup — no manual sync needed. Changing `num_ctx` at runtime triggers a full model unload/reload in Ollama (300+ seconds), so consistency matters.

| RAM | Context Window |
|-----|---------------|
| 128GB+ | 128K (131,072) |
| 64–95GB | 64K (65,536) |
| 48–63GB | 32K (32,768) |
| 36–47GB | 16K (16,384) |
| <36GB | 8K (8,192) |

Override by editing `~/.pre/context` directly (any value from 2048 to 262144).

- **Context bar** — Shown after every response (color-coded: grey > yellow at 50% > red at 75%). Also visible in the web GUI topbar.
- **Auto-compaction** — At 75% usage (~98K tokens), older turns are summarized and compressed. The last 6 exchanges are kept intact.
- **Tool response cap** — Tool outputs truncated to 8KB to prevent context blowout.
- **Rewind** — `/rewind N` removes the last N turns to free space.
- **Channels** — Separate channels for separate tasks to avoid context pollution.

---

## Best Practices

### Getting Good Results

1. **Be specific.** "Review auth.py for SQL injection" > "check my code"
2. **Attach files.** `/file src/main.py` (CLI) or drag-and-drop (web GUI) then ask your question.
3. **Use PRE.md.** A project config file saves you from re-explaining your stack every session.
4. **Watch the thinking.** `/think` toggles the model's reasoning — useful for understanding its approach.
5. **Upload images.** Paste screenshots, drag photos — Gemma 4 analyzes them natively.

### Managing Context

1. **Check context regularly.** `/context` or the topbar bar in the web GUI.
2. **Use channels for separate tasks.** Don't mix debugging and feature work.
3. **Rewind noisy turns.** `/rewind` removes turns that added bulk without value.
4. **Let auto-compaction work.** It preserves recent context while compressing old turns.

### Scheduling

1. **Start simple.** "every day at 9am" — verify results before adding complex schedules.
2. **Be specific in prompts.** Good: "Check disk usage on / and /Users, alert if >80%". Bad: "check things".
3. **Use the Result button.** Each cron job run is a full chat session you can review and continue.
4. **Configure delivery channels.** Add Telegram and/or Slack tokens for push notifications even when away from the computer.

---

## Performance & Optimization

PRE is tuned for maximum quality and speed on Apple Silicon. Every configuration choice has been individually benchmarked on an M4 Max (128 GB).

### Model Quantization

| Quantization | Size | Decode Speed | Quality Loss vs FP16 | Status |
|-------------|------|-------------|----------------------|--------|
| **q8_0** | ~28 GB | ~73 tok/s | <1% (near-lossless) | **Active** |
| q4_K_M | ~17 GB | ~88 tok/s | ~3.3% | Replaced |

PRE uses **q8_0** — the highest practical quantization for 128 GB unified memory. The ~17% speed reduction versus q4_K_M is a worthwhile trade for near-lossless output quality, especially for complex agentic tasks where reasoning accuracy directly affects tool-call success rates.

### Ollama Environment Tuning

Each optimization was benchmarked individually. Four changes were kept; two were tested and rejected:

| Setting | Value | Effect | Benchmark Result |
|---------|-------|--------|-----------------|
| `OLLAMA_FLASH_ATTENTION` | `0` (disabled) | Gemma 4 uses hybrid attention (50 sliding-window + 10 global layers). Flash Attention is slower and unstable with this architecture on Apple Silicon. | Measurably faster with FA off |
| `OLLAMA_KEEP_ALIVE` | `24h` | Model stays loaded in GPU memory. Avoids 5+ second cold-load between requests. | Sub-second TTFT on warm cache |
| `OLLAMA_NUM_PARALLEL` | `2` | Two inference slots: priority slot for user chat, secondary slot for background agents/cron. Enabled when RAM headroom ≥16 GB. | Background agents no longer block user requests |
| `OLLAMA_MAX_LOADED_MODELS` | `2` | Allows main model + embedding model (nomic-embed-text, ~274 MB) simultaneously. | No reload thrashing between inference and RAG embedding |

**Tested and rejected:**

| Setting | Why Rejected |
|---------|-------------|
| `OLLAMA_KV_CACHE_TYPE=q8_0` | Saved ~2 GB but cost 7% decode speed (81.6 vs 88 tok/s). Not worth it with 128 GB RAM. |
| Explicit `<\|think\|>` token | Gemma 4 already has thinking enabled by default in Ollama's chat template renderer. Adding it manually is redundant. |

### Sampling Parameters

Configured in `engine/Modelfile` and applied to every request:

| Parameter | Value | Rationale |
|-----------|-------|-----------|
| `temperature` | `1.0` | Google's recommended default for Gemma 4 |
| `top_k` | `64` | Google's recommended default |
| `top_p` | `0.95` | Google's recommended default |
| `min_p` | `0.05` | Emerging best practice — cuts the absolute bottom of the probability distribution, improving diversity without sacrificing coherence |

### Speed Profile (M4 Max, 128 GB)

| Metric | Value |
|--------|-------|
| **Decode speed** | ~73 tok/s |
| **Prompt eval speed** | ~800 tok/s |
| **Time to first token** | <1s (warm cache) |
| **Cold load time** | ~5s |
| **Context window** | Auto-sized from RAM (8K–128K); 128K on 128GB systems |
| **KV cache allocation** | ~5s for full context on first request |

### Why Not Smaller / Why Not Bigger?

- **Why not q4_K_M (~17 GB, ~88 tok/s)?** — The 3.3% quality loss measurably degrades multi-step reasoning and tool-call accuracy. For an agentic system where the model chains 10-35 tool calls per task, compounding small errors matters more than raw speed.
- **Why not FP16 (~52 GB)?** — Would leave insufficient headroom for KV cache at large context. The q8_0 quantization is <1% quality loss — effectively indistinguishable from FP16 in practice.
- **Why auto-sized context?** — Gemma 4 supports 262K natively, but KV cache memory scales with context size. The installer picks the largest context your RAM can comfortably support (see [Context Management](#context-management)). On 128GB systems, this is 128K — balancing deep multi-step workflows with memory headroom for model weights and OS.

---

## Web GUI

PRE includes a built-in browser interface at `http://localhost:7749` that provides full access to all features through a modern, responsive web application.

### How It Works

**Node.js (Express + WebSocket) backend** with a **vanilla JS SPA frontend** — no React, no Vue, no bundler. It supports two local inference backends — **Ollama** (default, simpler model management) and **llama.cpp server** (direct, with Flash Attention and grammar constraints for NVIDIA GPUs) — plus remote providers (OpenAI, Azure, Anthropic). The installer auto-selects the best backend for your GPU. Sessions are fully interchangeable between CLI and web.

### Features

- **Real-time streaming** — tokens appear as the model generates them, with thinking blocks, streaming cursor, and live tool status cards
- **Full tool execution** — all 79 tools run server-side with the same multi-turn tool loop as the CLI (up to 35 autonomous tool calls per prompt)
- **Sub-agent spawning** — the model can delegate research tasks to autonomous sub-agents that run in parallel, each with their own Ollama session
- **Browser automation** — headless Chrome control with vision-aware screenshot feedback. Navigate, click, type, scroll, and read web pages.
- **MCP server support** — connect external MCP tool servers; their tools are automatically discovered and available to the model
- **Argus companion** — interactive session observer with goal-aware reactions, error diagnostics, cross-event pattern recognition, typing indicator, and reply-to-reaction conversations
- **Hooks** — pre/post tool execution hooks for auditing, safety guardrails, and workflow automation
- **File and image upload** — drag-and-drop, clipboard paste (Ctrl/Cmd+V), or file picker button. Images sent to model for analysis; text files included as context.
- **Image generation** — generates images locally via ComfyUI. Results display inline with Full Size, Download, and Show in Finder actions.
- **Document generation** — creates DOCX, XLSX, TXT, CSV, HTML documents. Download or open directly from the chat.
- **Artifact viewer** — rich HTML artifacts render in a slide-out right panel. Download or reveal in Finder.
- **Frontier AI delegation** — toggle between PRE (local), Claude, Codex, or Gemini via a dropdown next to the input. Unavailable CLIs are auto-hidden. Responses stream in real-time with color-coded model badges. Sessions preserve which model generated each message.
- **Voice input** — hold-to-record microphone button in the chat input; local Whisper transcription puts text in the input box. macOS `say` speaks responses aloud.
- **Triggers panel** — create and manage file watchers, webhooks, and polling monitors from the sidebar. Visual add form with type selector, path/glob/secret/services fields, and variable hints.
- **RAG panel** — index directories, run semantic searches, and manage document indexes from the sidebar. Search results show matched content chunks ranked by relevance.
- **Workflow panel** — list, inspect, replay, and delete recorded desktop workflows from the sidebar.
- **Cron scheduler** — visual panel for managing recurring jobs with natural language input, live cron preview, enable/disable toggles, and run-now buttons. Results delivered via macOS notification, Telegram, and in-browser toast.
- **Session management** — sidebar with searchable session list, create/rename/delete sessions, project organization with drag-and-drop
- **Memory browser** — view, search, and manage persistent memories from a dedicated panel, grouped by type with color coding
- **Connection manager** — configure all 15 external services from the Settings panel (API keys, OAuth)
- **Context tracking** — live context window usage bar in the topbar
- **Tool confirmation** — dangerous tools show a confirmation dialog before executing
- **Two themes** — Dark (`#0a0a0a` background, blue primary) and Light (`#fafafa` background, blue primary)
- **Calendas Plus typography** — serif display font for headings, system-ui stack for body text
- **Auto-generated titles** — sessions are automatically named based on the first message
- **Responsive layout** — three-panel design (sidebar, chat, artifact panel) with mobile hamburger drawer

### Auto-Launch

The web GUI starts automatically when you run `pre-launch` (requires Node.js 18+). It runs in the background on port **7749** (configurable via `PRE_WEB_PORT`).

### Auto-Start at Login

PRE can optionally start the web GUI server at login, so it's always available at `http://localhost:7749` without manually running anything.

**Enable from the GUI:** Settings (gear icon) → **System** section → toggle **Start at Login**.

**Enable from the installer:** Both `install.sh` and `install.ps1` offer auto-start during installation.

**macOS:** A LaunchAgent (`com.pre.server`) runs `web/pre-server.sh` at login. It ensures Ollama is running, pre-warms the model, and starts the Node.js server. If the server crashes, launchd restarts it automatically.

```bash
web/pre-server.sh --status   # Check if server and model are running
web/pre-server.sh --stop     # Stop the server (unloads LaunchAgent if active)
```

**Windows:** A VBScript wrapper in the Startup folder launches either `web/pre-tray.ps1` (system tray icon with status indicator and controls) or `web/pre-server.ps1` (headless) at login. The installer asks which mode to use. The tray icon sits in the Windows notification area and provides start/stop/restart, status monitoring, and quick browser launch -- mirroring the macOS menu bar app.

```powershell
powershell -File web\pre-server.ps1 --status   # Check if running
powershell -File web\pre-server.ps1 --stop     # Stop the server
```

### Manual Launch

```bash
cd pre/web
npm install          # First time only
node server.js       # Starts on http://localhost:7749

# With custom settings:
PRE_WEB_PORT=8080 PRE_CWD=/path/to/project node server.js
```

---

## Frontier AI Delegation

PRE can delegate prompts to frontier AI models when cloud-level intelligence is needed, turning it into an **agentic orchestration layer** — use local inference for everyday tasks and escalate to the most powerful models on demand.

### Supported Models

| Delegate | CLI | Install |
|----------|-----|---------|
| **Claude** (Anthropic) | `claude` | `npm install -g @anthropic-ai/claude-code` |
| **Codex** (OpenAI) | `codex` | `npm install -g @openai/codex` |
| **Gemini** (Google) | `gemini` | `npm install -g @anthropic-ai/gemini-cli` |

### How It Works

1. PRE detects which CLIs are installed at startup and hides unavailable options
2. In the GUI, click the **delegate toggle** (next to the attachment button) to switch between PRE, Claude, Codex, or Gemini
3. Your prompt is sent to the selected CLI in text-only mode (no tool use) and the response streams back in real-time
4. Responses display with a **color-coded model badge** (orange for Claude, green for Codex, blue for Gemini)
5. Session history preserves which model generated each message — badges render on reload

The delegates run in non-interactive mode with tool use disabled (`claude --tools ""`, `codex -a suggest`, `gemini -o text`) so they return text responses only. The frontier model thinks; PRE acts.

---

## Remote Model Providers

PRE runs locally by default with Gemma 4 on Ollama, but you can point it at **any OpenAI-compatible API**, **Azure AI Foundry**, or **Anthropic Messages API** endpoint — giving resource-constrained machines access to the full agent harness (79 tools, memory, experience, scheduling, all of it) powered by cloud models.

### Supported Providers

| Provider | Base URL | Suggested Model |
|----------|----------|-----------------|
| **OpenAI** | `https://api.openai.com/v1` | `gpt-4o` |
| **Groq** | `https://api.groq.com/openai/v1` | `llama-3.3-70b-versatile` |
| **Together AI** | `https://api.together.xyz/v1` | `meta-llama/Llama-3.3-70B-Instruct-Turbo` |
| **OpenRouter** | `https://openrouter.ai/api/v1` | `anthropic/claude-sonnet-4` |
| **Azure AI Foundry (OpenAI)** | `https://{resource}.openai.azure.com/openai/deployments/{deployment}/chat/completions` | (deployment determines model) |
| **Azure AI Foundry (Anthropic)** | `https://{resource}.services.ai.azure.com/anthropic/v1/messages` | (deployment name as model) |
| **Anthropic (direct)** | `https://api.anthropic.com/v1/messages` | `claude-sonnet-4-20250514` |
| **vLLM / LM Studio** | `http://localhost:8000/v1` | (your model) |

Any endpoint that implements the OpenAI `/chat/completions` streaming API works — including self-hosted vLLM, TGI, and Ollama running on a remote machine. Azure and Anthropic use their own authentication and streaming protocols, which PRE handles natively.

### How to Configure

Open the **Settings** panel in the web GUI (gear icon in sidebar). The **Model Provider** section at the top offers four modes:

1. **Local (Ollama)** — the default, uses `pre-gemma4` on your hardware
2. **Remote (OpenAI)** — select a preset or enter a custom OpenAI-compatible endpoint
3. **Azure AI Foundry** — connect to an Azure OpenAI deployment
4. **Anthropic** — connect to Anthropic's Messages API (direct or via Azure)

**For OpenAI-compatible providers**, fill in:
- **Base URL** — the API endpoint (presets auto-fill this)
- **API Key** — your provider's API key
- **Model** — which model to use (presets suggest one)
- **Max Tokens** — per-response cap to control costs (default: 4096)

**For Azure AI Foundry (OpenAI models)**, fill in:
- **Deployment Endpoint** — the full Target URI from Azure AI Foundry > Deployments > your model
- **API Key** — your Azure API key (from the Keys section in your resource)
- **API Version** — defaults to `2024-10-21` (latest stable)
- **Model Name** — optional, for display purposes (the deployment determines the actual model)
- **Max Tokens** — per-response cap to control costs (default: 4096)

**For Anthropic (direct or Azure)**, fill in:
- **Messages Endpoint** — `https://api.anthropic.com/v1/messages` for direct, or the Azure endpoint URL
- **API Key** — your Anthropic API key or Azure API key (sent as `x-api-key` header)
- **API Version** — defaults to `2023-06-01`
- **Model / Deployment Name** — e.g. `claude-sonnet-4-20250514` or Azure deployment name
- **Max Tokens** — per-response cap to control costs (default: 4096)

Click **Test Connection** to verify before saving.

### What Stays Local

Even with a remote provider, these always use local Ollama:

| Component | Why |
|-----------|-----|
| **Memory embeddings** | `nomic-embed-text` (274 MB) — fast, private, no API cost |
| **RAG vector search** | Same local embedding model |
| **Experience ledger search** | Semantic similarity via local embeddings |
| **Session storage** | All conversations stay in `~/.pre/sessions/` |
| **Tool execution** | All 79 tools run locally on your machine |

The remote provider handles only the **inference** (generating responses and deciding which tools to call). Your files, credentials, and data never leave your machine.

### Cost Safety

- **Max Tokens cap** — every request is capped to your configured limit (default 4096 tokens per response)
- **No auto-retry on rate limits** — errors surface to the user, not retried silently
- **Thinking disabled** — extended thinking is disabled for remote providers to avoid unnecessary token consumption
- **Revert anytime** — click "Revert to Local" in Settings to switch back instantly

---

## Multi-Model Router

PRE 2.0 introduces intelligent message routing across multiple models. Instead of sending every message to the same model, the router classifies messages by complexity and dispatches to the optimal tier.

### How It Works

1. **Message classification** — each incoming message is analyzed for complexity indicators (question length, tool keywords, reasoning requirements)
2. **Tier assignment** — messages are routed to one of three tiers:
   - **Fast** — simple queries, greetings, time checks → `pre-gemma4-fast` (Gemma 4 E2B, ~140 tok/s, thinking disabled)
   - **Standard** — normal tool-using tasks → `pre-gemma4` (26B MoE, full tool access)
   - **Frontier** — complex reasoning, multi-file analysis → delegate to Claude/Codex/Gemini
3. **Execution** — the selected model handles the request through the same tool loop
4. **Fallback** — if the assigned model is unavailable, falls back to the next tier

### Configuration

Open **Settings** → **Router** in the GUI, or use the REST API:

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/router` | Current router configuration |
| `POST` | `/api/router` | Update router settings |
| `DELETE` | `/api/router` | Disable router (all messages go to primary model) |
| `GET` | `/api/router/models` | List available models for each tier |

### Why This Matters

Cloud agents use one model for everything — you pay frontier prices for "what time is it?" PRE routes each message to the right model: fast and cheap for simple queries, full reasoning power only when needed. You control the tiers, the models, and the classification thresholds.

---

## Background Agents

PRE 2.0 adds fire-and-forget autonomous agents that run long tasks in the background while you continue working. This is the first local AI agent with crash-resilient background execution.

### How It Works

1. **Spawn** — tell PRE to run a task in the background (via the `background_agent` tool or the GUI)
2. **Queue** — the agent enters a GPU-serialized queue (one agent at a time on the GPU to prevent memory thrashing)
3. **Execute** — the agent runs through the full tool loop in its own session under the "Background Agents" project
4. **Checkpoint** — after every completed tool turn, a checkpoint is saved to `~/.pre/agent-checkpoints/`
5. **Complete** — when done, results are saved and a WebSocket notification + toast alert is sent

### Smart Interrupt (Sleep/Reboot Recovery)

Background agents survive anything your laptop can throw at them:

| Event | What Happens |
|-------|-------------|
| **System sleep** | A 10-second heartbeat timer detects sleep via drift (>30s gap). Running agents are paused. On wake: Ollama health check with exponential backoff → agents resume from their last checkpoint. |
| **System hibernate** | Same as sleep — the heartbeat timer detects the gap on wake. |
| **Process crash / reboot** | Agent state is persisted to `~/.pre/agent-state.json` on every state change. On next startup, `bgAgents.init()` re-queues interrupted agents from their checkpoints. |
| **Ollama crash** | Health check with exponential backoff (1s, 2s, 4s... up to 60s). If Ollama recovers, agents resume. If not, agents are marked `interrupted` for manual retry. |

### Agent Lifecycle

Agents can be in one of seven states:

`queued` → `running` → `completed` | `failed` | `cancelled` | `paused` → `interrupted`

### REST API

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/agents` | List all background agents |
| `GET` | `/api/agents/:id` | Get one agent's status |
| `GET` | `/api/agents/:id/result` | Get completed agent's output |
| `DELETE` | `/api/agents/:id` | Cancel a running or queued agent |

### GUI: Agent Feed Panel

The Agent Feed panel (in the sidebar) shows all agent activity — cron jobs, trigger executions, blocking sub-agents, and background agents. Background agents display:

- Color-coded status badges (yellow=Queued, blue=Running, green=Completed, red=Failed, grey=Cancelled, purple=Paused, orange=Interrupted)
- Cancel buttons for active agents
- Session links to view the agent's full conversation
- Toast notifications on completion or failure

---

## Learning from Experience

PRE 2.0 introduces a closed-loop learning system that tracks performance, recommends approaches, and exports training data — capabilities no frontier cloud agent provides.

### Calibrated Self-Knowledge

Every tool call is tracked: which tool, whether it succeeded, and whether the user corrected the result. Outcomes are aggregated across 12 categories:

`file_ops` · `bash` · `web` · `memory` · `code` · `calendar` · `email` · `cloud` · `image` · `documents` · `rag` · `computer`

Confidence scores (0.0–1.0) are computed per category:
- User corrections are penalized at **2x weight** — a single "no, that's wrong" counts as much as two failures
- Categories need **5+ observations** before a score is computed (avoiding noisy early estimates)
- Scores **>=85%** are injected into the system prompt as strengths
- Scores **<60%** are flagged as caution areas

**Automatic feedback detection**: When your message follows tool use, PRE checks for positive patterns ("perfect", "exactly", "great job") or negative patterns ("no", "wrong", "try again") and auto-records outcomes — no explicit feedback needed.

### Skill Effectiveness

Skills (reusable tool-chain approaches) are tracked by outcome. When a new task arrives, PRE checks for skills with overlapping tool chains and recommends the most effective ones. Low-effectiveness skills are filtered out.

### Training Data Export

Export your session history as fine-tuning data in four formats:

| Format | Output | Use Case |
|--------|--------|----------|
| **ChatML** | `{"messages": [{"role": "system", ...}, {"role": "user", ...}, {"role": "assistant", ...}]}` | OpenAI fine-tuning API |
| **Alpaca** | `{"instruction": "...", "input": "...", "output": "..."}` | Instruction tuning (LLaMA, Mistral) |
| **ShareGPT** | `{"conversations": [{"from": "human", ...}, {"from": "gpt", ...}]}` | Multi-turn conversation tuning |
| **DPO** | `{"prompt": "...", "chosen": "...", "rejected": "..."}` | Direct Preference Optimization from your corrections |

Quality filtering ensures only substantive rounds make it into the export:
- Minimum 2 tool calls per round
- Minimum 50-character assistant response
- Less than 30% error rate per round
- Corrections excluded by default (or included for DPO pairs)

Experience ledger entries are also converted to instruction/output training pairs.

### Knowledge Graph

PRE automatically extracts entities and typed relationships from every conversation, memory, and experience ledger entry, building a graph that captures how your world connects — not just what was said.

**Entity types:** person, project, system, tool, concept, organization, location, file, model

**Relationship types:** works_on, uses, depends_on, part_of, related_to, created_by, located_at, runs_on, trained_on, mentions

**How it works:**
- Every 6 conversation turns, the LLM scans recent messages for extractable entities and relationships
- When you query the model, embedding-based graph traversal finds related entities and injects their connections into the system prompt
- Direct graph interaction via the `knowledge_graph` tool: query entities, add relationships, explore subgraphs, or build the full graph from existing memories

**Why this matters:** Flat memory search finds documents that contain a keyword. Graph traversal finds that "Joby Aviation" is an organization where "Christopher Bradford" works, that it uses "Azure" and "Jira", and that the "IT Service Desk" project depends on "Confluence" — even if no single memory contains all of those facts.

### Runtime Self-Awareness

Every system prompt includes a `<self_awareness>` block that summarizes PRE's current operational state:

- **Calibration confidence** — which tool categories PRE is strong in, with percentages
- **Active infrastructure** — how many background agents, triggers, and cron jobs are running
- **Knowledge scale** — memory count, experience entries, training exports, knowledge graph size
- **Router state** — which models are active, whether frontier routing is on

This means the model never has to ask "what can I do?" — it already knows. It can make informed decisions about which tools to use, when to be cautious, and what capabilities are available.

### On-Device LoRA Fine-Tuning (eGPU)

PRE 2.0 doesn't just export training data — it can train LoRA adapters directly on your eGPU using tinygrad. This closes the full loop: use PRE, export your sessions as training data, fine-tune a Llama model with your personal workflows, and use the adapted model for inference. No cloud services, no API fees, no data leaving your machine.

See [eGPU & tinygrad Integration](#egpu--tinygrad-integration) for the complete walkthrough.

### REST API

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/training/preview` | Preview export stats without writing |
| `POST` | `/api/training/export` | Export to JSONL file |
| `GET` | `/api/training/exports` | List previous exports |
| `GET` | `/api/training/jobs` | List all fine-tuning jobs |
| `POST` | `/api/training/finetune` | Start a LoRA fine-tuning job |
| `GET` | `/api/training/jobs/:id` | Get job status and progress |
| `DELETE` | `/api/training/jobs/:id` | Cancel a running job |
| `GET` | `/api/training/adapters` | List saved LoRA adapters |
| `GET` | `/api/gpu/status` | Current GPU detection state |
| `GET` | `/api/tinygrad/status` | tinygrad inference server status |
| `POST` | `/api/tinygrad/start` | Start tinygrad inference server |
| `POST` | `/api/tinygrad/stop` | Stop tinygrad inference server |
| `GET` | `/api/calibration` | Full confidence report |
| `DELETE` | `/api/calibration` | Reset all calibration data |
| `GET` | `/api/skills/effectiveness` | Skill effectiveness report |
| `GET` | `/api/graph/stats` | Knowledge graph statistics |
| `GET` | `/api/graph/entities` | List all entities (optional `?type=` filter) |
| `GET` | `/api/graph/query?q=` | Search entities and return connection context |
| `GET` | `/api/graph/entity/:name` | Get entity with neighbors |
| `GET` | `/api/graph/subgraph/:name` | Get N-hop subgraph around entity |
| `POST` | `/api/graph/build` | Build graph from all memories + experiences |

---

## eGPU & tinygrad Integration

PRE 2.0 adds full GPU hot-plug detection and tinygrad integration, enabling two capabilities previously unavailable in any local AI agent: **Llama model inference on a dedicated eGPU** and **on-device LoRA fine-tuning** from your own training data.

### Overview

| Component | What It Does |
|-----------|-------------|
| **GPU Hot-Plug Detection** | Polls every 30 seconds for eGPU connect/disconnect. Events propagate to all GPU-dependent modules. |
| **tinygrad Inference Server** | Serves Llama 1/2/3 models via an OpenAI-compatible API on your eGPU. Auto-starts when GPU detected. |
| **tinygrad Training Backend** | LoRA fine-tuning jobs managed from the GUI or via the `finetune` tool. Progress tracked in real-time via WebSocket. |
| **Graceful Degradation** | GPU utilized when available, ignored when not. Inference falls back to Ollama seamlessly. |

### How GPU Detection Works

PRE uses the same three-method detection as the installer, but runs it continuously at runtime:

1. **systemextensionsctl** — checks if the TinyGPU DriverKit extension is loaded (macOS)
2. **TinyGPU.app** — checks for the application in /Applications or ~/Applications (macOS)
3. **nvidia-smi** — queries GPU name and VRAM directly (Linux, Windows) or via Docker (macOS + TinyGPU)
4. **Thunderbolt scan** — fallback via `system_profiler SPThunderboltDataType` for device names (macOS)

State is persisted to `~/.pre/gpu-state.json` and broadcast via WebSocket. The sidebar GPU badge turns green when a GPU is detected.

```
GPU State Shape:
{
  available: true,
  vendor: "nvidia",
  name: "NVIDIA RTX 4090",
  vram_gb: 24,
  backend: "cuda",
  driver: "tinygpu",    // macOS eGPU
  lastCheck: 1747340000000
}
```

### PRE Academy: tinygrad Inference Walkthrough

Use your eGPU for Llama model inference alongside Ollama's Gemma 4. This is useful for running a second model (e.g., Llama 3 8B for fast tasks) on dedicated GPU hardware while Gemma 4 runs on Apple Silicon.

**Step 1: Connect your eGPU**

Plug in your Thunderbolt/USB4 eGPU. Within 30 seconds, PRE detects it and the GPU badge in the sidebar turns green.

**Step 2: Install tinygrad (if not done by installer)**

```bash
pip3 install tinygrad
```

Verify GPU access:
```bash
DEV=NV python3 -c "from tinygrad import Device; print(Device.DEFAULT)"
# Should print: NV
```

**Step 3: Download a Llama model**

Download Llama 3 8B weights in safetensors format from Hugging Face or another source. Place them anywhere accessible (e.g., `~/models/llama3-8b/`).

**Step 4: Configure tinygrad as a provider**

Open PRE Web GUI (http://localhost:7749) and go to **Settings** (gear icon in sidebar footer).

1. Under **Model Provider**, select **tinygrad (eGPU)**
2. Fill in:
   - **Model Path**: `/path/to/your/llama3-8b` (directory containing safetensors)
   - **Quantization**: `int8` (recommended for 16GB+ VRAM) or `nf4` (for smaller GPUs)
   - **Port**: `8091` (default)
   - **Context Size**: `8192` (adjust based on your VRAM)
   - **Auto-start**: Enable to automatically start when GPU is detected
3. Click **Save**

**Step 5: Start the server**

Click the **Start** button in the tinygrad settings panel, or PRE starts it automatically if auto-start is enabled. The health indicator turns green when the server is ready (model loading takes 30-120 seconds depending on size).

**Step 6: Chat**

Send a message. PRE routes it through tinygrad's OpenAI-compatible endpoint. The response streams back exactly like Ollama — same UI, same tool calling, same experience.

**Step 7: Unplug and go**

Disconnect the eGPU. PRE detects the change within 30 seconds, stops the tinygrad server, and falls back to Ollama. Your conversation continues without interruption.

> **Note:** tinygrad supports Llama 1/2/3 models only (not Gemma 4). Primary inference stays on Ollama. tinygrad provides supplementary Llama inference and the exclusive training backend.

### PRE Academy: LoRA Fine-Tuning Walkthrough

Train a personal LoRA adapter from your PRE session history. The complete pipeline: export training data from your conversations, then fine-tune a Llama model on your eGPU, producing an adapter that captures your specific workflows and preferences.

**Prerequisites:**
- NVIDIA eGPU connected (or discrete NVIDIA GPU on Linux/Windows)
- tinygrad installed (`pip3 install tinygrad`)
- Base Llama model weights (safetensors format)
- Training data exported from PRE (or any ChatML/Alpaca JSONL)

#### Phase 1: Export Training Data

First, generate training data from your PRE session history.

**Option A: Via the GUI**

Open Settings, scroll to the Training section, and use the export controls. Select a format (ChatML recommended for LoRA), optionally filter by project, and click Export.

**Option B: Via chat (tool call)**

```
Export my session history as ChatML training data
```

PRE runs the `training_export` tool:
```
Training Data Preview:
Sessions scanned: 47
Total conversation rounds: 312
Quality rounds (meeting filters): 89
User corrections (DPO pairs): 12
Experience ledger entries: 23
Estimated export total: 112
```

Then:
```
Export it
```

The JSONL file lands in `~/.pre/training/exports/`. Each line is a ChatML conversation:
```json
{"messages": [{"role": "system", "content": "..."}, {"role": "user", "content": "Read config.json and add a logging field"}, {"role": "assistant", "content": "I'll read the file and add the field..."}]}
```

**Option C: Via REST API**

```bash
# Preview what would be exported
curl http://localhost:7749/api/training/preview

# Export as ChatML
curl -X POST http://localhost:7749/api/training/export \
  -H "Content-Type: application/json" \
  -d '{"format": "chatml"}'

# List past exports
curl http://localhost:7749/api/training/exports
```

#### Phase 2: Start a Fine-Tuning Job

With your training data exported and your GPU connected, start a LoRA training job.

**Option A: Via chat (tool call)**

```
Fine-tune llama3-8b with my latest training export using LoRA rank 16 for 3 epochs
```

PRE runs the `finetune` tool:
```
Training job started.
Job ID: train_1
Status: running

Use finetune action=status id=train_1 to check progress.
```

**Option B: Via REST API**

```bash
curl -X POST http://localhost:7749/api/training/finetune \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-personal-lora",
    "base_model": "/path/to/llama3-8b",
    "training_data": "~/.pre/training/exports/chatml-2026-05-15.jsonl",
    "format": "chatml",
    "lora_rank": 16,
    "lora_alpha": 32,
    "learning_rate": 2e-4,
    "epochs": 3,
    "batch_size": 4,
    "max_seq_len": 2048,
    "quantization": "int8"
  }'
```

#### Phase 3: Monitor Progress

Training progress streams to the Web GUI via WebSocket. You'll see real-time updates:

```
Epoch 1/3 | Step 45/120 | Loss: 0.4231 | Elapsed: 2m 15s
Epoch 1/3 | Step 46/120 | Loss: 0.4198 | Elapsed: 2m 18s
...
Epoch 3/3 complete | Avg Loss: 0.2847 | Elapsed: 8m 42s
```

**Check status via chat:**
```
What's the status of my training job?
```

**Check via REST API:**
```bash
# Get specific job
curl http://localhost:7749/api/training/jobs/train_1

# List all jobs
curl http://localhost:7749/api/training/jobs
```

#### Phase 4: Use Your Adapter

When training completes, the LoRA adapter is saved to `~/.pre/training/adapters/<name>/`:

```
~/.pre/training/adapters/my-personal-lora/
  adapter.safetensors     # LoRA weights
  adapter_config.json     # LoRA configuration (rank, alpha, target modules)
  metadata.json           # Training metadata (loss, samples, duration)
  checkpoint-epoch1.safetensors
  checkpoint-epoch2.safetensors
  checkpoint-epoch3.safetensors
```

**List your adapters:**
```
List my LoRA adapters
```

Or via API:
```bash
curl http://localhost:7749/api/training/adapters
```

The adapter can be loaded alongside the base Llama model for inference using tinygrad.

#### Training Parameters Reference

| Parameter | Default | Description |
|-----------|---------|-------------|
| `lora_rank` | 16 | Rank of the low-rank adaptation matrices. Higher = more capacity, more VRAM. Common values: 8, 16, 32, 64. |
| `lora_alpha` | 32 | Scaling factor (typically 2x rank). Controls the magnitude of LoRA updates. |
| `learning_rate` | 2e-4 | Step size for optimizer. Lower = more stable but slower convergence. |
| `epochs` | 3 | Full passes through the training data. More epochs risk overfitting on small datasets. |
| `batch_size` | 4 | Samples per gradient update. Larger = smoother gradients, more VRAM. |
| `max_seq_len` | 2048 | Maximum token sequence length. Longer = more context per sample, more VRAM. |
| `quantization` | int8 | Base model quantization during training: `int8` (recommended), `nf4` (less VRAM), `fp8`, `none` (full precision). |

#### VRAM Guidelines

| GPU VRAM | Recommended Settings |
|----------|---------------------|
| **8 GB** | `lora_rank=8`, `batch_size=1`, `max_seq_len=512`, `quantization=nf4` |
| **16 GB** | `lora_rank=16`, `batch_size=2`, `max_seq_len=1024`, `quantization=int8` |
| **24 GB** | `lora_rank=16`, `batch_size=4`, `max_seq_len=2048`, `quantization=int8` |
| **48 GB+** | `lora_rank=32`, `batch_size=8`, `max_seq_len=4096`, `quantization=int8` or `none` |

#### Cancel a Job

```
Cancel training job train_1
```

Or via API:
```bash
curl -X DELETE http://localhost:7749/api/training/jobs/train_1
```

### Architecture: GPU + tinygrad Stack

```
                                ┌─────────────────────────┐
                                │     gpu-detect.js       │
                                │   (30s polling loop)     │
                                │   3-method TinyGPU scan  │
                                └────┬──────────┬─────────┘
                    gpu-available    │          │   gpu-unavailable
                    ┌────────────────┘          └────────────────┐
                    ▼                                            ▼
           ┌────────────────┐                           ┌───────────────┐
           │  tinygrad.js   │                           │ Graceful stop │
           │ (server mgr)   │◄── auto-start ──►        │ + fallback to │
           │ Start llama3.py│                           │    Ollama     │
           │ port 8091      │                           └───────────────┘
           └───────┬────────┘
                   │ OpenAI-compatible SSE
                   ▼
           ┌────────────────┐     ┌──────────────────────┐
           │   ollama.js    │     │  tinygrad-train.js   │
           │ streamChat()   │     │  (training manager)   │
           │ provider:      │     │  Job queue, progress   │
           │  tinygrad →    │     │  WebSocket broadcast   │
           │  _streamChat   │     └──────────┬───────────┘
           │   OpenAI()     │                │ spawn
           └────────────────┘                ▼
                                    ┌──────────────────────┐
                                    │ tinygrad-train-      │
                                    │   worker.py          │
                                    │ (Python child proc)  │
                                    │ LoRA fine-tuning     │
                                    │ JSON progress stdout │
                                    └──────────────────────┘
                                             │
                                             ▼
                                    ~/.pre/training/adapters/
                                       adapter.safetensors
                                       metadata.json
```

### REST API (GPU & tinygrad)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/gpu/status` | Current GPU state (name, VRAM, vendor, availability) |
| `GET` | `/api/tinygrad/status` | tinygrad server status (running, PID, model, GPU info) |
| `POST` | `/api/tinygrad/start` | Start tinygrad inference server |
| `POST` | `/api/tinygrad/stop` | Stop tinygrad inference server |
| `GET` | `/api/escalation/status` | Escalation availability (`{ available, runtime, model, label, reason }`) |
| `POST` | `/api/escalation/probe` | Force a re-probe of the escalation runtime + broadcast |
| `GET` | `/api/training/jobs` | List all fine-tuning jobs |
| `POST` | `/api/training/finetune` | Start a new LoRA training job |
| `GET` | `/api/training/jobs/:id` | Get job status and progress |
| `DELETE` | `/api/training/jobs/:id` | Cancel a running training job |
| `GET` | `/api/training/adapters` | List saved LoRA adapters with metadata |

### Per-Message Escalation

Beyond the always-on auto-router (fast/standard/frontier), PRE offers an **explicit per-message escalation** to a larger model on the eGPU. This is separate from the API-frontier path — it stays local, just on bigger iron.

**How to use it:**

- **↑ toggle** in the chat input area — arm it, send a message, it sends through the escalation runtime once, then disarms. Visual: the toggle button glows green when armed.
- **`/escalate` prefix** — type `/escalate write me a function that…` and PRE strips the prefix and routes that single message to the escalation runtime.

The assistant bubble for an escalated turn shows a teal "↑ eGPU · {model}" pill so it's clear which model answered.

**Runtime per platform:**

| Platform | Runtime | What happens |
|----------|---------|--------------|
| macOS    | tinygrad subprocess on the eGPU | Same physical tinygrad server hosts the escalation model; one model per boot (one-shot-per-boot NV constraint) |
| Linux / Windows | Second Ollama model on the same instance | Installer registers it as `pre-escalate` alongside `pre-gemma4`; escalation just swaps the model name on the request |

**VRAM-tiered default model** (picked by `install.sh` / `install-linux.sh` from detected VRAM):

| VRAM (GB) | Recommended model | Quant | Approx size |
|----------:|-------------------|-------|------------:|
| ≥ 80 | Llama-3.3-70B-Instruct | Q6_K  | ~57 GB |
| 48–79 | Llama-3.3-70B-Instruct | Q4_K_M | ~42 GB |
| 24–47 | GLM-4-32B-0414 | Q4_K_M | ~20 GB |
| 16–23 | DeepSeek-Coder-V2-Lite-Instruct | Q4_K_M | ~10 GB |
| < 16 | (skipped — Gemma-only) | — | — |

Sidebar footer carries a small status badge: `● tinygrad` (macOS) or `● eGPU` (Linux/Windows) — green when the runtime is healthy and the model is loaded, muted otherwise. Hover shows the configured model and the reason if unavailable.

### Supported Hardware

| Platform | GPU | Driver | Detection Method |
|----------|-----|--------|-----------------|
| macOS (Apple Silicon) | NVIDIA eGPU via Thunderbolt/USB4 | TinyGPU | systemextensionsctl + Docker nvidia-smi |
| macOS (Intel) | NVIDIA eGPU via Thunderbolt | TinyGPU | systemextensionsctl + Docker nvidia-smi |
| Linux | NVIDIA discrete or eGPU | Native CUDA | nvidia-smi |
| Windows | NVIDIA discrete | Native CUDA | nvidia-smi |

---

## Experience Ledger

PRE doesn't just execute tasks — it **learns from them**. After each task completes, a reflection step extracts lessons learned and saves them to a permanent experience ledger at `~/.pre/memory/experience/`.

### How It Works

1. **Automatic reflection** — After a tool loop finishes (2+ tool calls, 2-minute cooldown), PRE runs a lightweight reflection prompt
2. **Structured extraction** — Each lesson captures: task (what was being done), approach (what was tried), outcome (what happened), and lesson (the reusable insight)
3. **Embedding-based dedup** — New lessons are compared to existing ones using `nomic-embed-text` cosine similarity (threshold: 0.85) to avoid duplicates
4. **Semantic retrieval** — The `experience_search` tool finds relevant lessons by meaning, not just keywords
5. **Context injection** — The 10 most recent lessons are included in the system prompt

### Example

After PRE uses `grep` to find all files importing a module:

```
Lesson: "grep_for_discovery"
Task: locating specific imports or patterns in a codebase
Approach: using grep to identify all files containing a specific string
Outcome: success
Lesson: Use grep as a primary discovery/filtering layer — more efficient
than reading files individually
```

Next time, searching for "how to find dependencies in source code" retrieves this lesson via semantic similarity (0.56), even though the words are completely different.

### REST API

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/experience` | List all experience entries |
| `GET` | `/api/experience?q=query` | Semantic search experiences |

---

## Chronos (Temporal Awareness)

PRE tracks the age and freshness of its memories, flags stale information, and can run self-maintenance to keep its knowledge base current.

### Staleness Thresholds

Each memory type has a different staleness threshold:

| Type | Threshold | Rationale |
|------|-----------|-----------|
| `project` | 14 days | Project context changes fast |
| `reference` | 60 days | External resources may move |
| `feedback` | 90 days | Work preferences are relatively stable |
| `experience` | 120 days | Tool strategies may change with updates |
| `user` | 180 days | User profile changes slowly |

### Memory Verification

Memories have a `verified` frontmatter field. When a memory is verified (manually or by maintenance), the date is updated. Staleness is measured from the last verification, not just modification.

### Self-Maintenance

Run maintenance manually via `POST /api/chronos/maintenance` or schedule it as a cron job:

> "Review your memory health. Run memory_health and report any stale or aging memories."

The maintenance system reviews stale memories and recommends: **keep** (re-verify), **update** (content needs correction), or **flag for deletion** (no longer relevant). It never auto-deletes — flagged items are presented for user review.

### REST API

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/chronos/health` | Memory health summary (% fresh, counts) |
| `GET` | `/api/chronos/staleness` | Full staleness report |
| `POST` | `/api/chronos/verify/:filename` | Mark a memory as verified |
| `POST` | `/api/chronos/maintenance` | Run automated maintenance |

---

## MCP Server Support

PRE supports the [Model Context Protocol](https://modelcontextprotocol.io/) (MCP), allowing you to connect external tool servers and make their capabilities available to the model.

### Configuration

MCP servers are configured in `~/.pre/mcp.json`:

```json
{
  "servers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/projects"],
      "env": {}
    },
    "remote-api": {
      "url": "https://mcp.example.com/api"
    }
  }
}
```

Two transport types are supported:
- **Stdio** — spawns a local process (`command` + `args`)
- **HTTP** — connects to a remote endpoint (`url`)

### How It Works

1. **Auto-connect at startup** — PRE connects to all configured MCP servers when the web GUI starts
2. **Tool discovery** — each server's tools are discovered via `tools/list` and merged into the model's available tools
3. **Namespaced routing** — MCP tools are prefixed as `mcp__servername__toolname` to avoid collisions
4. **Transparent execution** — the model calls MCP tools the same way it calls built-in tools

### REST API

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/mcp` | Status of all configured/connected servers |
| `POST` | `/api/mcp/add` | Add a new MCP server (auto-connects) |
| `POST` | `/api/mcp/connect` | Connect to a configured server |
| `POST` | `/api/mcp/disconnect` | Disconnect a server |
| `DELETE` | `/api/mcp/:name` | Remove a server from config |

---

## Hooks System

Hooks let you run shell commands before or after tool execution. Use them for auditing, policy enforcement, or workflow automation.

### Configuration

Hooks are defined in `~/.pre/hooks.json`:

```json
{
  "hooks": [
    {
      "id": "audit-all",
      "event": "pre_tool",
      "tool": "*",
      "command": "echo \"$(date) $PRE_TOOL_NAME $PRE_TOOL_ARGS\" >> ~/.pre/audit.log",
      "description": "Audit all tool calls",
      "enabled": true,
      "can_block": false,
      "timeout": 5000
    },
    {
      "id": "block-destructive",
      "event": "pre_tool",
      "tool": "bash",
      "command": "echo \"$PRE_TOOL_ARGS\" | grep -qE 'rm -rf|mkfs|dd if=' && exit 1 || exit 0",
      "description": "Block destructive bash commands",
      "enabled": true,
      "can_block": true,
      "timeout": 5000
    }
  ]
}
```

### Hook Events

| Event | When | Can Block? |
|-------|------|------------|
| `pre_tool` | Before a tool executes | Yes (non-zero exit blocks the call) |
| `post_tool` | After a tool completes | No (logging/auditing only) |
| `pre_message` | Before a user message is processed | Yes |
| `post_message` | After the model responds | No |

### Environment Variables

Hooks receive context via environment variables:

| Variable | Description |
|----------|-------------|
| `PRE_HOOK_EVENT` | Event type (pre_tool, post_tool, etc.) |
| `PRE_TOOL_NAME` | Tool being called (e.g., "bash") |
| `PRE_TOOL_ARGS` | JSON-encoded tool arguments |
| `PRE_TOOL_OUTPUT` | Tool output (post_tool only) |
| `PRE_SESSION_ID` | Current session ID |
| `PRE_CWD` | Working directory |

### REST API

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/hooks` | List all hooks |
| `POST` | `/api/hooks` | Add a new hook |
| `PATCH` | `/api/hooks/:id/toggle` | Enable/disable a hook |
| `DELETE` | `/api/hooks/:id` | Remove a hook |

### Use Cases

- **Audit logging** — log every tool call to a file or external system
- **Safety guardrails** — block destructive commands (rm -rf, DROP TABLE, etc.)
- **Workflow triggers** — notify Slack when the agent creates a file, send a webhook after image generation
- **Compliance** — enforce policies on what the agent can do in different contexts

---

## Browser Agent

PRE includes a vision-aware browser automation tool powered by headless Chrome (via Puppeteer). The model can navigate web pages, see screenshots, and interact with page elements autonomously.

### Requirements

- Google Chrome installed (auto-detected on macOS and Windows)
- `puppeteer-core` npm package (installed with the web GUI)

### How It Works

1. The model calls the `browser` tool with an action (navigate, click, type, etc.)
2. PRE executes the action in headless Chrome
3. A screenshot is taken and returned to the model as a base64 image
4. The model sees the screenshot via Gemma 4's native vision and decides the next action
5. The loop repeats until the task is complete

### Available Actions

| Action | Args | Description |
|--------|------|-------------|
| `navigate` | `url` | Go to a URL, return screenshot |
| `screenshot` | `full_page`? | Capture current page |
| `click` | `selector` or `text` or `x,y` | Click an element |
| `type` | `selector`?, `text`, `clear`? | Type text into a field |
| `press` | `key` | Press a key (Enter, Tab, Escape, etc.) |
| `scroll` | `direction`, `amount`? | Scroll up or down |
| `read` | *(none)* | Extract visible text content |
| `evaluate` | `script` | Run JavaScript in page context |
| `select` | *(none)* | List all interactive elements with coordinates |
| `back` / `forward` | *(none)* | Browser history navigation |
| `wait` | `selector`?, `timeout`? | Wait for an element or duration |
| `close` | *(none)* | Close the browser |

### Example Workflow

Ask PRE: "Go to Hacker News and find the top story about AI"

The model will:
1. `browser navigate https://news.ycombinator.com` — sees the homepage
2. `browser select` — discovers clickable links with coordinates
3. `browser read` — extracts article titles
4. Return a summary of what it found

---

## Telegram Integration

PRE includes a built-in Telegram bot for full agent access from your phone. The bot runs as part of the Web GUI and works on both macOS and Windows — no additional setup required beyond adding your bot token.

### Setup

1. Message [@BotFather](https://t.me/BotFather) on Telegram and create a new bot
2. In PRE, run `/connections add telegram` and paste the bot token
3. Restart PRE — the Telegram bot starts automatically

### How It Works

The bot long-polls the Telegram API (no webhook, no public URL required) and routes messages through the same Ollama instance. Full system access — all tools, same memory, same agentic workflows.

- **Owner authorization** — the first user to message becomes the owner
- **Cron delivery** — scheduled job results are sent to your Telegram chat
- **Automatic lifecycle** — starts with PRE, stops with PRE (Ctrl+C kills both)

### Bot Commands

| Command | Description |
|---------|-------------|
| `/start` | Welcome message |
| `/new` | New conversation |
| `/status` | Bot status |
| `/memory` | List saved memories |
| `/help` | Show commands |

---

## Architecture

### System Diagram

```
┌─────────────┐    Ollama Native    ┌─────────────────┐
│   PRE CLI   │  ◄─ /api/chat ──►  │     Ollama       │
│  (pre.m)    │   raw recv() NDJSON │  localhost:11434  │
│ ~10000 lines│                     │  Gemma 4 26B-A4B  │
│  Obj-C / C  │                     │  MoE, q8_0         │
└──┬──────┬───┘                     │  NUM_PARALLEL=2    │
   │      │                         │  ~73 t/s           │
   │      │ fork/exec               └──────────▲────────┘
   │      │                                    │
   │  ┌───▼──────────┐  /api/chat (non-stream) │
   │  │ pre-telegram  │ ───────────────────────┘
   │  │ (telegram.m)  │                         │
   │  │ Telegram Bot  │  ◄──► Telegram Bot API  │
   │  └───────────────┘       (long-poll)       │
   │                                            │
   │ auto-start/stop                            │
   │                    ┌───────────────────────┘
┌──▼──────────────┐  ┌──┴──────────────┐  ┌─────────────────┐
│    ComfyUI      │  │   PRE Web GUI   │  │  llama.cpp       │
│ Juggernaut XL   │  │  (Node.js/WS)   │  │  server          │
│  (MPS/Metal)    │  │  vanilla JS SPA  │  │  (alternative    │
│ 25-step, 1024px │  │  79 tools        │  │   backend for    │
└─────────────────┘  │  2-slot queue    │  │   NVIDIA GPUs)   │
                     │  dual backend    │  │  Flash Attention  │
                     └──┬───────────────┘  │  GBNF grammar    │
                        │ localhost:7749   └─────────────────┘
                        │
       ┌────────────────┼────────────────────┐
       │                │                    │
       ▼                ▼                    ▼
┌──────────────┐ ┌──────────────┐  ┌─────────────────────┐
│ gpu-detect.js│ │ tinygrad.js  │  │ tinygrad-train.js   │
│ 30s poll     │ │ Llama server │  │ LoRA fine-tuning    │
│ hot-plug     │ │ port 8091    │  │ job queue + progress│
│ events ──────┤►│ auto-start   │  │ Python worker proc  │
│              │ │ OpenAI SSE   │  │ → adapters/         │
└──────────────┘ └──────────────┘  └─────────────────────┘
                     eGPU (NVIDIA via TinyGPU / native CUDA)

  ~/.pre/
  ├── identity.json       # Agent name
  ├── connections.json    # API keys and OAuth tokens
  ├── context             # Context window size (written by installer, read at runtime)
  ├── cron.json           # Scheduled recurring tasks
  ├── hooks.json          # Pre/post tool execution hooks
  ├── mcp.json            # MCP server configuration
  ├── server.log          # Web GUI server log (when running via LaunchAgent)
  ├── sessions/           # Conversation JSONL (shared by CLI + web + cron)
  ├── history             # Input history (arrow-key recall)
  ├── checkpoints/        # File backups for /undo
  ├── artifacts/          # HTML artifacts, documents, and generated images
  ├── comfyui.json        # ComfyUI configuration (if installed)
  ├── comfyui/            # ComfyUI installation (if installed)
  ├── comfyui-venv/       # Python venv for ComfyUI (if installed)
  ├── triggers.json       # Event-driven triggers (file watchers, webhooks)
  ├── rag/                # RAG indexes (per-index: meta, chunks, vectors)
  ├── workflows/          # Recorded workflow sequences (JSON files)
  ├── agent-state.json    # Background agent registry (crash recovery)
  ├── agent-checkpoints/  # Turn-level checkpoints for background agents
  ├── calibration.json    # Tool outcome tracking per category (self-knowledge)
  ├── skill-effectiveness.json # Per-skill outcome tracking
  ├── training/exports/   # Exported fine-tuning data (JSONL)
  ├── training/adapters/  # Saved LoRA adapters (safetensors + metadata)
  ├── training/jobs.json  # Fine-tuning job registry
  ├── gpu-state.json      # Cached GPU detection state (30s polling)
  ├── tinygrad-status.json # tinygrad install verification (written by installer)
  ├── tinygrad-server.log # tinygrad inference server log
  ├── router.json         # Multi-model router config
  ├── models/             # GGUF model files for llama.cpp backend (optional)
  ├── telegram.log        # Telegram bot output
  ├── telegram_owner      # Authorized Telegram user ID
  ├── memory/             # Global persistent memories
  │   ├── index.md
  │   └── *.md
  └── projects/
      └── {name}/
          ├── memory/     # Project-scoped memories
          └── channels/   # Channel metadata
```

### The PRE Binary

**PRE CLI** (`pre.m`) is a single-file Objective-C/C application (~10,000 lines) handling:
- Raw `recv()` NDJSON streaming with 64KB ring buffer
- Dynamic `num_ctx` from `~/.pre/context` — auto-sized by installer, synced across CLI and Web GUI (avoids Ollama reload)
- 79 tool implementations with two-tier permissions + hook-based policy enforcement
- Hybrid tool calling: native Ollama `tools` API + text-based `<tool_call>` fallback
- Local image generation via ComfyUI (checkpoint-adaptive workflow)
- Multi-part artifacts with incremental append
- PDF export via native WebKit rendering
- Cron registry for recurring tasks
- Built-in Google OAuth 2.0 with multi-account support
- Persistent memory with per-project scoping
- Context compaction and token budget management
- File checkpointing and undo
- Ctrl+V image paste for multimodal queries
- linenoise-based line editor with tab completion

**Web GUI** (`web/`) is a Node.js Express + WebSocket server with vanilla JS SPA (**cross-platform: macOS + Windows + Linux**):
- Dual local backend: Ollama (NDJSON) or llama.cpp server (OpenAI-compatible SSE with GBNF grammar constraints)
- Remote providers: OpenAI/Azure (SSE) + Anthropic (event-based SSE)
- 2-slot inference queue: user requests get priority, background agents/cron run in secondary slot
- Structured output repair: JSON Schema-constrained 4th-level fallback for malformed tool calls
- Stable system prompt prefix for KV cache persistence across requests
- Server-side tool execution (same tool loop as CLI)
- Cross-platform abstraction layer (`platform.js`) — all OS-specific operations route through a single module
- GUI management panels: triggers, RAG indexes, workflows, memory, cron, agent feed, settings
- Multi-model router with fast/standard/frontier tiers (PRE 2.0)
- Autonomous background agents with GPU queue, checkpointing, and sleep/reboot recovery (PRE 2.0)
- Calibrated self-knowledge with per-category confidence scoring (PRE 2.0)
- Training data export pipeline for personal fine-tuning (PRE 2.0)
- Skill effectiveness tracking and recommendation (PRE 2.0)
- Voice input: hold-to-record microphone with local Whisper transcription
- MCP client manager with stdio/HTTP transports and auto-discovery
- Sub-agent spawning with parallel execution
- Headless Chrome browser automation with vision feedback
- Event-driven trigger engine (file watchers, webhooks)
- Local RAG with semantic search over indexed documents
- Hook system for pre/post tool execution policies
- Headless cron runner with multi-channel notification delivery
- Session JSONL read/write (shared format with CLI)
- File/image upload (drag-and-drop, clipboard paste, file picker)
- Document generation (DOCX, XLSX via docx/exceljs, PDF via pdfkit)
- Two themes with CSS custom properties (Dark, Light)
- No framework, no bundler — vanilla JS SPA

**Telegram Bot** (`telegram.m`) is a companion binary (~2000 lines):
- Long-polling (no webhook needed)
- Full tool access matching CLI
- Owner-based authorization
- Automatic lifecycle management

---

## Configuration

### Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `PRE_PORT` | `11434` | Ollama server port |
| `PRE_WEB_PORT` | `7749` | Web GUI server port |
| `EDITOR` | `vi` | Editor for `/edit` command |
| `OLLAMA_FLASH_ATTENTION` | `0` | Disabled — Gemma 4 hybrid attention is slower/unstable with FA on Apple Silicon |
| `OLLAMA_KEEP_ALIVE` | `24h` | Keep model loaded in GPU memory between requests |
| `OLLAMA_NUM_PARALLEL` | `2` | Two inference slots — user chat + background agents/cron (when headroom ≥16 GB) |
| `OLLAMA_MAX_LOADED_MODELS` | `2` | Main model + embedding model (nomic-embed-text) loaded simultaneously |

### CLI Options

```bash
pre-launch [options]
  --port N          Override Ollama port
  --max-tokens N    Max response tokens (default: 8192)
  --show-think      Show reasoning blocks by default
  --resume ID       Resume a previous session
  --sessions        List saved sessions and exit
  --dir PATH        Override working directory
```

### Data Location

All PRE data lives in `~/.pre/`:

```
~/.pre/
├── identity.json       # Agent name
├── connections.json    # API keys, OAuth tokens, model provider config (chmod 600)
├── cron.json           # Scheduled recurring tasks
├── hooks.json          # Pre/post tool execution hooks
├── mcp.json            # MCP server configuration
├── sessions/           # Conversation JSONL (one per session)
├── history             # Readline history
├── checkpoints/        # File backups (auto-cleaned)
├── artifacts/          # Generated documents, images, artifacts
├── context             # Context window size (auto-sized from RAM)
├── comfyui.json        # ComfyUI config (optional)
├── triggers.json       # Event-driven triggers (file watchers, webhooks)
├── rag/                # RAG indexes (per-index: meta, chunks, vectors)
├── workflows/          # Recorded workflow sequences
├── router.json         # Multi-model router config [2.0]
├── models/             # GGUF model files for llama.cpp backend (optional)
├── agent-state.json    # Background agent registry (crash recovery) [2.0]
├── agent-checkpoints/  # Turn-level checkpoints for background agents [2.0]
├── calibration.json    # Tool outcome tracking per category [2.0]
├── skill-effectiveness.json # Per-skill outcome tracking [2.0]
├── training/exports/   # Exported fine-tuning data (JSONL) [2.0]
├── training/adapters/  # Saved LoRA adapters (safetensors + metadata) [2.0]
├── training/jobs.json  # Fine-tuning job registry [2.0]
├── gpu-state.json      # Cached GPU detection state (30s polling) [2.0]
├── tinygrad-status.json # tinygrad install verification [2.0]
├── tinygrad-server.log # tinygrad inference server log [2.0]
├── server.log          # Web GUI server log (LaunchAgent mode)
├── telegram.log        # Telegram bot output
├── telegram_owner      # Authorized Telegram user ID
├── memory/
│   ├── index.md        # Memory index
│   └── *.md            # Individual memory files
└── projects/
    └── {project-id}/
        ├── memory/     # Project-scoped memories
        └── channels/   # Channel metadata
```

---

## Project Structure

```
pre/
├── README.md               # This file
├── install.sh              # macOS automated installer
├── Install PRE.command     # macOS double-click installer (Finder)
├── install-linux.sh        # Linux automated installer
├── install.ps1             # Windows automated installer (PowerShell)
├── install.cmd             # Windows double-click installer
├── Launch PRE.command      # macOS double-click launcher (Finder)
├── Launch PRE.cmd          # Windows double-click launcher
├── PRE Tray.cmd            # Windows system tray launcher
├── VERSION                 # Version tracking for update scripts
├── update.sh               # macOS update script (git or zip)
├── update.ps1              # Windows update script (PowerShell)
├── Update PRE.command      # macOS double-click updater (Finder)
├── Update PRE.cmd          # Windows double-click updater
├── system.md               # Model system prompt reference
├── benchmark.sh            # Performance benchmarking tool
├── engine/
│   ├── pre.m               # PRE CLI (single-file, ~10000 lines)
│   ├── telegram.m          # Telegram bot bridge (~2000 lines)
│   ├── linenoise.c/h       # Terminal line editor (patched)
│   ├── Makefile             # Build: make pre telegram
│   ├── Modelfile            # Ollama model config (base num_ctx=8192, overridden per-request)
│   ├── Modelfile.fast       # Fast tier model (Gemma 4 E2B, thinking disabled)
│   ├── pre-launch           # Universal launcher script
│   └── launch-telegram      # Standalone Telegram launcher
├── web/                     # Web GUI (Node.js + vanilla JS)
│   ├── server.js            # Express + WebSocket + MCP server
│   ├── pre-server.sh        # macOS headless launcher for LaunchAgent auto-start
│   ├── pre-server.ps1       # Windows headless launcher for Startup folder auto-start
│   ├── pre-tray.ps1         # Windows system tray app (notification area icon)
│   ├── package.json
│   ├── src/
│   │   ├── ollama.js        # Inference client: Ollama NDJSON + OpenAI/Azure SSE + Anthropic SSE + llama.cpp
│   │   ├── llamacpp.js      # llama.cpp server lifecycle manager (start/stop/health)
│   │   ├── llamacpp-model.js # GGUF model resolver (Ollama store + direct paths)
│   │   ├── grammar.js       # GBNF grammar builder (JSON Schema → grammar for llama.cpp)
│   │   ├── inference-queue.js # 2-slot inference queue (user priority + background)
│   │   ├── sessions.js      # JSONL read/write (shared with CLI)
│   │   ├── tools.js         # Tool dispatcher + execution loop
│   │   ├── tools-defs.js    # 79 tool definitions for Ollama
│   │   ├── context.js       # System prompt builder (stable prefix + dynamic suffix)
│   │   ├── memory.js        # Auto-extraction engine
│   │   ├── connections.js   # Credential management + provider config (Ollama/llama.cpp/remote)
│   │   ├── platform.js      # Cross-platform abstraction (IS_WIN, IS_MAC, shell, clipboard, etc.)
│   │   ├── constants.js     # MODEL_CTX (from ~/.pre/context), paths
│   │   ├── cron-runner.js   # Headless cron execution + notifications
│   │   ├── mcp.js           # MCP client manager (stdio + HTTP)
│   │   ├── hooks.js         # Pre/post tool execution hooks
│   │   ├── experience.js   # Experience ledger (post-task reflection + embeddings)
│   │   ├── chronos.js      # Temporal awareness + memory staleness
│   │   ├── triggers.js     # Event-driven trigger engine (file watchers, webhooks, polling)
│   │   ├── custom-tools.js # Dynamic virtual tool system (create, execute, manage)
│   │   ├── router.js       # Multi-model router (fast/standard/frontier tiers) [2.0]
│   │   ├── background-agents.js # Autonomous background agents with Smart Interrupt [2.0]
│   │   ├── training.js     # Training data export pipeline (ChatML/Alpaca/ShareGPT/DPO) [2.0]
│   │   ├── calibration.js  # Calibrated self-knowledge (12 categories, confidence scoring) [2.0]
│   │   ├── skills.js       # Skill auto-discovery, behavioral guidance, progressive disclosure [2.0]
│   │   ├── gpu-detect.js   # GPU hot-plug detection (30s polling, EventEmitter) [2.0]
│   │   ├── tinygrad.js     # tinygrad inference server lifecycle manager [2.0]
│   │   ├── tinygrad-train.js     # LoRA fine-tuning job manager [2.0]
│   │   ├── tinygrad-train-worker.py  # Python training worker (LoRA via tinygrad) [2.0]
│   │   ├── routes/          # Express Router modules (13 files, extracted from server.js)
│   │   └── tools/           # Tool implementations (40 modules)
│   │       ├── bash.js      # Shell execution
│   │       ├── files.js     # File operations
│   │       ├── web.js       # Web fetch/search
│   │       ├── memory.js    # Memory CRUD
│   │       ├── system.js    # System inspection + desktop
│   │       ├── artifact.js  # HTML artifact generation
│   │       ├── document.js  # DOCX/XLSX/PDF/TXT/CSV generation
│   │       ├── image.js     # ComfyUI image generation
│   │       ├── cron.js      # Cron job management
│   │       ├── computer.js  # Desktop automation (macOS: cliclick; Windows: user32.dll)
│       ├── computer-win32.js # Windows desktop automation helpers (PowerShell + .NET)
│   │       ├── browser.js   # Headless Chrome automation (Puppeteer)
│   │       ├── mail.js      # Mail.app via AppleScript
│   │       ├── calendar.js  # Calendar.app via EventKit/Swift
│   │       ├── contacts.js  # Contacts.app via AppleScript
│   │       ├── reminders.js # Reminders.app via EventKit/Swift
│   │       ├── notes.js     # Notes.app via AppleScript
│   │       ├── spotlight.js # File search (macOS: mdfind; Windows: Windows Search)
│   │       ├── github.js    # GitHub API
│   │       ├── google.js    # Gmail, Drive, Docs
│   │       ├── telegram.js  # Telegram Bot API
│   │       ├── jira.js      # Jira API
│   │       ├── confluence.js # Confluence API
│   │       ├── smartsheet.js # Smartsheet API
│   │       ├── slack.js     # Slack API
│   │       ├── linear.js    # Linear API
│   │       ├── zoom.js      # Zoom API (S2S OAuth)
│   │       ├── figma.js     # Figma API
│   │       ├── asana.js     # Asana API
│   │       ├── sharepoint.js # Microsoft 365 / SharePoint
│   │       ├── dynamics365.js # Dynamics 365 / Dataverse
│   │       ├── agents.js    # Sub-agent spawning + parallel execution
│   │       ├── monitor.js   # Background process monitor (start, read, stop, list)
│   │       ├── delegate.js  # Frontier AI delegation (Claude/Codex/Gemini)
│   │       ├── rag.js       # Local RAG (directory indexing + semantic search)
│   │       ├── voice.js     # Voice interface (Whisper STT + TTS: macOS say / Windows SAPI)
│   │       └── workflow.js  # Workflow capture and replay
│   └── public/
│       ├── index.html       # SPA shell
│       ├── favicon.svg
│       ├── fonts/           # Calendas Plus (regular, italic, bold)
│       ├── css/             # base, themes, chat, sidebar, components, animations
│       └── js/
│           ├── pre-state.js # Shared state namespace (window.PRE) + event bus
│           ├── app.js       # Core: init, WebSocket, chat, sidebar, sessions
│           ├── ws.js, chat.js, markdown.js, themes.js
│           └── panels/      # Per-panel IIFE modules (11 files: settings, cron, dashboard, etc.)
└── docs/
    └── *.md                 # Research notes
```

---

## Contributing

PRE is built and maintained by **Christopher Bradford** — systems administrator at Joby Aviation and AI engineer.

**How to contribute:**
1. Fork and create a branch
2. Make changes
3. Open a pull request

**Contact:**
- GitHub: [@sunkencity999](https://github.com/sunkencity999)

---

## Acknowledgments

- **Google** for the Gemma 4 model family
- **Ollama** for making local model serving effortless
- **Apple** for unified memory architecture that makes this possible
- **NVIDIA** for GPU acceleration on Windows

## License

MIT License. See [LICENSE](LICENSE) for details.

The Gemma 4 model weights are subject to the [Gemma Terms of Use](https://ai.google.dev/gemma/terms).
