A Knowledge OS: an LLM-maintained personal wiki of linked, cited Markdown pages, stored as an Open Knowledge Format v0.2 bundle.
Rust is the kernel (store, index, journal), Python runs the services (FastAPI), and a React + Vite app is the shell.
Edda is deployed from this repository and never published: the edda names on crates.io, PyPI and npm belong to
unrelated projects.
pixi install
pixi run bootstrappixi install sets up Rust, Python 3.14 and Node from conda-forge and builds the native module; bootstrap installs
the pre-commit hooks and the web app's npm packages.
pixi run devServes the API on http://127.0.0.1:8000 (OpenAPI at /docs) and the app on http://127.0.0.1:5173. The app has
three views: the Library (browse, filter, search, add a Markdown file or a web page), a Page view (the rendered page,
citations on hover, its sources and backlinks) and Review (the model's proposals, to accept, edit or reject).
Both serve .edda/dev-vault, a copy of examples/vault made on the first run and kept between runs, so what you
import or accept never changes the committed example. To start again from a fresh copy:
pixi run dev-initThe ports are uvicorn's and Vite's defaults; when either is taken, pass others, API first (dev-init takes them too):
pixi run dev 8765 5199The web dev server proxies /api to whichever API port you give, and fails rather than moving to another port.
The search index and link graph in <vault>/.edda/index are rebuilt from the files whenever they change, so
deleting them loses nothing.
Office files, PDFs and scans can be added from the Library. Office files are read by MarkItDown; PDFs and images by Docling, which keeps reading order, tables and page numbers, with OCR only for pages that have no text. Its models (about 600 MB) are downloaded once:
pixi run doc-models # Docling's layout and table models and RapidOCR's, to ~/.cache/edda/doclingEach document is kept unedited, next to the Markdown made from it; citations can name a page.
Jobs use a local model by default; nothing leaves the machine and nothing is billed.
pixi run llm-fetch # downloads Qwen3-14B (4-bit, ~9 GB) to ~/.cache/edda/models and checks its SHA-256
pixi run -e llm llm-serve # llama.cpp's llama-server on http://127.0.0.1:8080, 32k context, all layers on the GPU
pixi run llm-smoke # one tool-calling round trip against the configured modelpixi run -e llm llm-serve <model file> <port> <context> changes the defaults. The server requires the key in
~/.cache/edda/llm-key, which llm-serve creates on first use and Edda's local endpoint sends, so a web page open in
your browser cannot use your model; give the same key to any other tool you point at it. Ollama, mlx-lm or LM Studio
work too: add them under [llm.endpoints] in edda.toml with their OpenAI-compatible base_url.
Each job in [llm] names an endpoint or anthropic. Hosted models send your sources off the machine, and keys come
from the environment, never from edda.toml or the vault.
| Provider | Set a job to | Key | Model |
|---|---|---|---|
| NVIDIA (Nemotron) | "nvidia" |
NVIDIA_API_KEY, from build.nvidia.com |
nvidia/nemotron-3-ultra-550b-a55b; nvidia/nemotron-3.5-lightning-30b-a3b is faster. Which models an account can call varies |
| Anthropic (Claude) | "anthropic" |
ANTHROPIC_API_KEY, or ant auth login |
Sonnet 5.5, Opus 5.5 or Haiku 5.5 per job |
export NVIDIA_API_KEY=...
pixi run llm-smoke examples/vault nvidia # check the endpoint before setting a job to itHosted models have much larger contexts than a local one, so raise [budgets] for those jobs; Anthropic bills by the
token, and NVIDIA's terms and rate limits are theirs to set.
| Task | What it runs |
|---|---|
pixi run test |
cargo test, pytest tests/unit, vitest |
pixi run test-integration |
pytest tests/integration |
pixi run lint |
clippy -D warnings, ruff, eslint |
pixi run check |
mypy (strict), tsc |
pixi run cov |
coverage of Rust, Python and the web app, each at 90% or more |
pixi run ci |
pre-commit, build, check, lint, cov |
Apache-2.0