Documentation

Hearth is a conversation that runs on your own hardware, with optional grounded answering over your own documents. Retrieval is opt-in. With no index attached it is plain chat.

Install

Python 3.10 or newer. PyPDF2 is optional and only needed for PDF ingestion.

python -m venv .venv
.venv\Scripts\activate          # source .venv/bin/activate on macOS and Linux
pip install -r requirements.txt

Hearth is not published to a package index yet, and the repository is private. These commands assume a working copy of the source.

Conversation

# Launch with an auto-detected backend
python hearth.py

# Pin a model
python hearth.py --model mlx-community/Meta-Llama-3.1-8B-Instruct-4bit

# Force an inference backend
python hearth.py --grate mlx

# See what models are available
python hearth.py --list-models

# Resume a previous conversation
python hearth.py --resume <session-id>

Sessions are written to disk as one JSON file each, so resuming a conversation is reading a file rather than restoring a database.

Memory

Feed it documents, ask questions, and get answers drawn from your own material with every claim attributed to the file it came from.

# Index a directory or a single file
python hearth.py index my-project ./path/to/docs
python hearth.py index my-project ./notes.md

# Ask a question
python hearth.py ask my-project "How does the authentication flow work?"

# See the retrieved chunks without calling a model
python hearth.py ask my-project "authentication" --no-generate

# Interactive grounded chat
python hearth.py chat my-project

# Manage indices and sessions
python hearth.py list
python hearth.py info my-project
python hearth.py sessions

Vector storage runs on Camellia where it is available. Camellia is currently a scaffold, so Hearth falls back to keyword matching, and info reports which backend an index is actually using.

Grates

A grate is an inference backend. Hearth detects the hardware and picks one, and --grate overrides it. Plain chat and grounded answering share the same grate, so there is no second inference path to keep honest.

GrateHardware
MLXApple Silicon, via Metal
llama.cppNVIDIA (CUDA), AMD (ROCm), and CPU
CrucibleThe Grimvane inference engine

In-chat commands

CommandAction
/newStart a new conversation
/saveSave the current conversation
/loadLoad a previous conversation
/modelSwitch model without losing the session
/systemSet the system prompt
/quitExit Hearth

Supported files

GroupFormats
DocumentsMarkdown, plain text, PDF
CodePython, Go, JavaScript, TypeScript, Rust, C and C++, Java, Ruby, PHP, Lua, shell
ConfigYAML, TOML, JSON, XML, SQL
WebHTML, CSS, SCSS

HTTP API

A local FastAPI service over the same grates. The desktop app is a client of it, and so is anything else you point at it.

MethodPathPurpose
GET/healthLiveness
GET/api/configActive configuration
GET/api/modelsModels available to the current grate
GET/api/gratesGrates this machine can run
GET/api/grateWhich grate is loaded
POST/api/grate/startLoad a grate
POST/api/grate/stopUnload it
GET/api/sessionsList sessions
POST/api/sessionsCreate one
GET/api/sessions/{id}Read one
DELETE/api/sessions/{id}Delete one
GET/api/indicesList indices
POST/api/indicesBuild an index
GET/api/indices/{name}Index detail, including the active vector backend
POST/api/indices/{name}/searchRetrieve chunks without generating
POST/api/chatChat, streamed as Server-Sent Events

Streaming a reply

POST /api/chat takes message, and optionally session_id to continue a conversation and index_name to ground the answer. It replies as Server-Sent Events.

EventPayload
session session_id and title, sent once, first
token text, repeating as the answer generates
sources sources, only when the answer was grounded
done session_id and message_count
error detail, generation stopped early

Desktop build

The desktop app is a Tauri shell around a React front end talking to the HTTP API. The API is packaged as a standalone binary that Tauri launches as a sidecar, so the app carries no separate Python install to depend on.

# Build the API sidecar, named for your target triple
python scripts/build_sidecar.py

# Then build the app
cd desktop
npm install
npm run tauri build

Building the sidecar needs PyInstaller and a Rust toolchain, the latter so the build can read your target triple. Bundle targets are MSI and NSIS on Windows, DMG and .app on macOS.