edgextract
Turn markdown into a knowledge graph with an ontology you write and a cutoff you own.
Your code proposes names. Your ontology says which kinds and links are legal. A small local decision model answers one closed yes-or-no question at a time. Anything it is unsure about waits for a person instead of silently entering your graph.

Real output from a local tev1 run on 13_northwind.md: open the interactive page · full report · read the article (PDF). One of the five links in that graph is wrong (Acme ACQUIRED Northwind; the text says "invested in"). We left it in. That is what the review queue and your cutoff are for.
60-second start
Rust (native): cargo add edgextract or cargo install edgextract.
Browser WASM: npm i @raphael.mansuy/edgextract (demo: GitHub Pages · Hugging Face Space).
git clone https://github.com/raphaelmansuy/edgextract && cd edgextract
uv sync --all-extras
ollama pull tev1 # a local decision model (Ollama 0.35+)
uv run edgextract --model tev1 report data/golden/docs/13_northwind.md \
--ontology company_news --out graph.html
open graph.html
No model yet? Everything below runs offline against a stand-in model:
make test examples
Or from Python, in five lines:
from edgextract import extract_text, load_ontology_named, write_report
text = open("note.md").read()
ontology = load_ontology_named("company_news") # or "tech_docs", "conll04", or a YAML path
result = extract_text(text, ontology, model="tev1")
write_report("graph.html", text, result, ontology, title="My note")
Try it in your browser
Hosted demo: GitHub Pages · Hugging Face Space (direct app) — Chromium with WebGPU; first Load Tev1 downloads ~1 GB from Hugging Face into the browser cache (no server of ours sees your text). The hosted page does not call 127.0.0.1:11434. Optional Ollama: ?backend=ollama&host=https://your-host plus OLLAMA_ORIGINS (HTTPS required; the browser blocks mixed-content http://). Open the Space on *.hf.space, not only the Hub iframe.
The Rust crate compiles to WebAssembly, and a small Vite + TypeScript page runs the whole pipeline in a tab. Your text goes only to the decision model you name (by default Tev1 on WebGPU in this tab; Ollama is one click away), never to a server of ours.
ollama pull tev1 # Ollama already accepts pages served from localhost;
# for another origin set OLLAMA_ORIGINS before `ollama serve`
make demo # builds the wasm, then serves http://localhost:5273
# WebGPU default loads raphaelmansuy/tev1-0.8b-onnx-webgpu (~1 GB, browser cache).
# Optional: make demo-webgpu-model / make demo-webgpu-publish / make demo-webgpu-export-tev1
# Attribution: docs/THIRD_PARTY_NOTICES.md
# GitHub Pages: push to master runs .github/workflows/pages.yml (lean dist, Hub weights).

- Bring any document. Upload or drop a
.md/.txtfile, or paste text. - Bring any ontology. Pick one of seven samples (company news, tech docs, research papers, film, medicine, history, CoNLL04), start from a template, upload your own YAML, and edit it with live validation.
- Names no list knows are still read. Every capitalized name in your text is put to the model as a closed question ("is this a name this ontology can