obsidian-llm-wiki
LLM wiki kit
First committed by kytmanov
Published in kytmanov/obsidian-llm-wiki-local. Publisher page
849 GitHub stars
What it is
Karpathy’s LLM Wiki, 100% local with Ollama. Drop Markdown notes → AI extracts concepts → your Obsidian wiki auto-links and grows. Zero sharing. Your notes stay yours.
AutoGineer overview, from the brain’s own files
obsidian-llm-wiki is a practical implementation of the LLM Wiki pattern, designed to turn unstructured notes into a structured, persistent knowledge base. It operates by treating raw Markdown files as source material, which an LLM then synthesizes into interlinked wiki articles. The system is built for local-first operation, defaulting to Ollama for privacy, though it supports various OpenAI-compatible endpoints. It features incremental compilation, meaning only notes affected by changes are reprocessed, and it preserves manual edits by detecting content changes. The tool includes a file watcher for background processing, interactive draft reviews with feedback loops, and query capabilities that synthesize answers from the wiki without requiring vector databases.
How it works
Memory model: LLM wiki
AutoGineer overview, from the brain’s own files
The system processes notes in three stages. First, the ingest stage uses a fast LLM to analyze raw Markdown files, extract concepts, and create source summary pages. Second, the compile stage uses a heavier LLM to gather source notes for each concept and generate wiki articles with internal links, which are saved as drafts. Finally, the review stage allows users to approve or reject drafts, with rejections providing feedback that informs future compilations. The system uses a SQLite database to track the lifecycle of notes and concepts, and it maintains the wiki structure directly within an Obsidian vault.
| Folder | Role | Files |
|---|---|---|
| .github | agent-config | 4 |
| docs | docs | 2 |
| scripts | scripts | 4 |
| src | source-code | 36 |
| tests | tests | 59 |
The agent writes
- update_in_place evidence: CLAUDE.md
- save_with_suffix evidence: README.md
Requirements
Runtimes: Python >=3.11
Databases: SQLite
API keys (by name): GROQ_API_KEY, OLW_API_KEY
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Google Antigravity, Kiro, OpenCode, Amp, Roo Code, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
This brain runs code automatically: 1 script. Review install.py before opening the folder in Claude Code. No step below turns a hook on for you.
install.py:python install.py
Clone the repository at the commit AutoGineer scanned:
git clone https://github.com/kytmanov/obsidian-llm-wiki-local.git && cd obsidian-llm-wiki-local && git checkout ad2e425f20f348154dde19d7c895b9bba69b7ad5Claude Code reads CLAUDE.md from this folder automatically.
cd obsidian-llm-wiki-local && claude
AutoGineer scanned these files at commit ad2e425.
- Not scanned by AutoGineerThe author’s README also describes installing it from a clone of its repository. Read its install section: AutoGineer did not scan that path. https://github.com/kytmanov/obsidian-llm-wiki-local/blob/ad2e425f20f348154dde19d7c895b9bba69b7ad5/README.md#1-install
- Not scanned by AutoGineerThe author’s README also describes installing it from a clone of its repository. Read its install section: AutoGineer did not scan that path. https://github.com/kytmanov/obsidian-llm-wiki-local/blob/ad2e425f20f348154dde19d7c895b9bba69b7ad5/README.md#running-the-tests
- Not scanned by AutoGineerIts dependencies are installed by pip or uv when you run it and were not scanned by AutoGineer (7 declared). https://pypi.org/project/obsidian-llm-wiki/
First committed by kytmanov. Published in kytmanov/obsidian-llm-wiki-local. Licence: MIT License.
Usage
AutoGineer overview, from the brain’s own files
- Automating the creation of a structured wiki from raw notes.
- Maintaining a personal knowledge base that grows and links concepts automatically.
- Querying a local knowledge base to synthesize answers from existing notes.
- Managing knowledge locally without relying on cloud-based vector databases or embeddings.
- Iteratively refining wiki content through an interactive review and feedback process.
- “olw watch”
- Starts a background process that automatically ingests and compiles any new Markdown files dropped into the raw/ folder.
- “olw query "What is backpropagation?"”
- Generates an answer based on the existing wiki content without using embeddings or a vector database.
- “olw review”
- Opens an interactive menu to approve or reject generated wiki drafts, allowing for manual refinement.
- “olw compare --heavy-model qwen2.5:14b”
- Builds an isolated preview vault to test how a different model performs before committing to a configuration change.
Documentation by kytmanov
obsidian-llm-wiki
<p align="center"> <a href="https://pepy.tech/projects/obsidian-llm-wiki"><img src="https://static.pepy.tech/personalized-badge/obsidian-llm-wiki?period=total&units=NONE&left_color=BLACK&right_color=GREEN&left_text=downloads" alt="PyPI Downloads"></a> <a href="https://github.com/kytmanov/obsidian-llm-wiki-local/stargazers"><img alt="GitHub stars" src="https://img.shields.io/github/stars/kytmanov/obsidian-llm-wiki-local?style=flat"></a> <a href="https://github.com/kytmanov/obsidian-llm-wiki-local/network/members"><img alt="GitHub forks" src="https://img.shields.io/github/forks/kytmanov/obsidian-llm-wiki-local?style=flat"></a> <a href="https://github.com/kytmanov/obsidian-llm-wiki-local/commits/master"><img alt="GitHub last commit" src="https://img.shields.io/github/last-commit/kytmanov/obsidian-llm-wiki-local?style=flat"></a> <a href="https://github.com/kytmanov/obsidian-llm-wiki-local/actions/workflows/ci.yml"><img alt="CI status" src="https://img.shields.io/github/actions/workflow/status/kytmanov/obsidian-llm-wiki-local/ci.yml?style=flat&label=CI"></a> <a href="https://pypi.org/project/obsidian-llm-wiki/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/obsidian-llm-wiki?style=flat"></a> </p>
Turn your raw notes into a self-improving, interlinked wiki — powered by a local LLM.
Drop a markdown file into a folder. The pipeline reads it, extracts concepts, and creates or updates wiki articles. If a draft is wrong, reject it and explain why; the next compile addresses your feedback. Over time, every note you add and every draft you review makes the wiki smarter.
Local-first, provider-flexible. Runs 100% locally with Ollama by default. Also works with any OpenAI-compatible endpoint — Groq, Together AI, LM Studio, vLLM, Azure OpenAI, and more.
NOTE
obsidian-llm-wiki is now in maintenance mode. → Check out SyntoBug fixes will continue. New features are being developed in Synto — the successor with a broader scope than the Obsidian LLM wiki pattern.
Migration is handled by Synto's migration command: point it at your existing vault and it converts the project to Synto's format. Your notes and wiki content remain the source of truth. If you're happy with what this tool does today, it keeps working; when you're ready for more, Synto provides the upgrade path.
<p align="center"> <img width="400" height="390" alt="image" src="https://github.com/user-attachments/assets/0b3998bd-af4d-4f3f-a2da-8334a0e81711"/> </p>
The idea (Karpathy's LLM Wiki)
This project is a practical implementation of the pattern described by Andrej Karpathy in "The LLM Wiki" — a vision for a personal knowledge base where:
"The LLM doesn't just store what you tell it — it synthesizes, cross-references, and keeps everything current. You add raw material; it does the bookkeeping."
The key insight: treat your notes as source material, not as the final artifact. The LLM compiles them into a structured wiki that grows smarter as you add more. Unlike a chatbot that forgets, the wiki persists and compounds.
You write raw notes → LLM extracts concepts → Wiki articles created/updated
raw/ (automatic) wiki/
quantum.md "Qubit", "Superposition" Qubit.md ←──┐
ml-basics.md "Neural Network", "SGD" Superposition.md │
physics.md "Qubit" (again!) Neural Network.md │
↑ linked via [[wikilinks]]The wiki lives in Obsidian, so you get the graph view, backlinks, and Dataview queries for free.
Features
Incremental compiles. Each concept gets its own article. When you change a source note, only the articles tied to that note recompile, not the whole vault.
File watcher. Run olw watch once and it processes anything you drop into raw/ automatically. Ingest and compile run in the background, so the wiki keeps improving while you keep writing notes.
Rejection feedback. Reject a draft and attach a reason. The next compile of that concept includes your feedback in the prompt, so the model can address it. Five rejections without an approval auto-blocks the concept until you re-enable it.
Hand-edits are preserved. Edit an article in Obsidian and the compiler will detect the change on the next run and skip it. Your edits aren't overwritten by regeneration.
Query and synthesize. olw query "what is X?" answers from your published wiki without embeddings or a vector DB. With --synthesize it saves the answer as a permanent wiki page, complete with source hashes and the same hand-edit protection.
Self-maintenance. Aliases like PC for Program Counter are extracted at ingest and used to repair broken wikilinks. olw lint reports orphans and stale articles; olw maintain --fix rewrites alias links and creates stubs for missing targets.
Provider-flexible. Ollama by default, fully offline. You can also point it at Groq, Together AI, LM Studio, vLLM, Azure OpenAI, or any OpenAI-compatible endpoint via olw setup. olw compare previews a switch in isolated vaults so you can decide before editing wiki.toml.
Multi-language. Each note's language is auto-detected at ingest and the article is written in that language. Extraction rules don't depend on hard-coded word lists, so any language works.
Git-aware. Every automatic action commits with an [olw] prefix, and olw undo reverts the last one. Raw notes are never modified; olw only writes to wiki/ and .olw/.
Quick start
1. Install
From PyPI (recommended):
pip install obsidian-llm-wikiOr with uv:
uv tool install obsidian-llm-wikiFrom source (latest development version):
git clone https://github.com/kytmanov/obsidian-llm-wiki-local
cd obsidian-llm-wiki-local
python install.pyinstall.py detects uv or falls back to pip, verifies the install, and tells you to run the next step.
2. Install and start Ollama
# Install Ollama: https://ollama.com/download
ollama pull gemma4:e4b # fast model — analysis and routing
ollama pull qwen2.5:14b # heavy model — article writing (optional, 7B+ recommended)Minimal setup: pull only
gemma4:e4band set bothfastandheavyto it in the wizard.
3. Run the setup wizard
olw setupAn interactive wizard selects a provider, configures the URL and optional API key, picks fast and heavy models, sets an optional default vault, and offers experimental features. Takes ~30 seconds.
╭──────────────────────────────────────────────────╮
│ obsidian-llm-wiki · setup │
╰──────────────────────────────────────────────────╯
Step 1 Provider
Local (no API key needed):
1. Ollama http://localhost:11434 [default]
2. LM Studio http://localhost:1234/v1
3. vLLM http://localhost:8000/v1
...
Cloud (API key required):
10. Groq https://api.groq.com/openai/v1
11. Together AI https://api.together.xyz/v1
...
Select provider (number or name) [1]: _
Step 2 URL
Base URL [http://localhost:11434]: _
✓ connected
Step 3 Fast model (analysis & routing · 3–8B recommended)
# Model Size
1 gemma4:e4b 9.6 GB
2 phi4-mini 2.5 GB
Select (number or name) [1]: _
...Settings are saved to ~/.config/olw/config.toml (Mac/Linux) or %APPDATA%\olw\config.toml (Windows). API keys are stored only in this user-private file, never in wiki.toml.
Experimental setup choices are saved only as defaults for new vaults. Runtime behavior is controlled by each vault's wiki.toml.
4. Set up your vault
olw init ~/my-wikiThis creates the folder structure and a wiki.toml pre-filled with your setup wizard choices.
To enable experimental inline source citations for an existing vault:
olw config inline-source-citations on --vault ~/my-wiki
olw config inline-source-citations status --vault ~/my-wikiTurn them off at any time with:
olw config inline-source-citations off --vault ~/my-wikiManual fallback:
[pipeline]
inline_source_citations = true5. Add some notes
Drop any .md files into ~/my-wiki/raw/. Web clips, book notes, meeting notes, anything.
~/my-wiki/raw/
quantum-computing.md
ml-fundamentals.md
physics-lecture.md6. Run the full pipeline
# One command: ingest + compile + lint + optional auto-approve
olw run
# Or step by step:
olw ingest --all
olw compile
olw review # interactive draft reviewIf you set a default vault in olw setup, the --vault flag is optional. Otherwise use --vault ~/my-wiki or export OLW_VAULT=~/my-wiki.
Open ~/my-wiki as an Obsidian vault. The graph view shows your connected wiki.
Before approving drafts, use a draft-review graph filter:
-path:raw -path:wiki/sources -path:_resources -file:WelcomeAfter approving drafts, use a published-only graph filter:
-path:raw -path:wiki/sources -path:wiki/.drafts -path:_resources -file:WelcomeThe published-only filter hides wiki/.drafts, so it will look empty until drafts are approved. Run olw doctor to print graph guidance for the current vault.
Want to preview a model or provider switch before changing wiki.toml?
olw compare --heavy-model qwen2.5:14bolw compare rebuilds isolated preview vaults from the same raw/ notes and tells you whether to switch, keep your current config, or review the diffs manually.
7. Keep it running (optional)
olw watch
# Drop a file in raw/ → ingest + compile happen automatically (selective: only linked concepts)Query synthesis
olw query answers from the published wiki without embeddings. Use --save to keep a dated Q&A note in wiki/queries/, or --synthesize to publish a reusable synthesis page in wiki/synthesis/.
# Just answer in the terminal
olw query "What is backpropagation?"
# Save a dated Q&A note under wiki/queries/
olw query "What is backpropagation?" --save
# Save a reusable synthesis article under wiki/synthesis/
olw query "What is backpropagation?" --synthesizeSynthesis behavior:
synthesis pages are published notes tagged with
synthesisthey store the source question, selected source pages, and source page body hashes in frontmatter
wiki/index.mdincludes a capped## Synthesissection sourced from the DB, ordered by newest first and then titlecompare runs stay side-effect-free: query evaluation never writes to the active vault during
olw comparequery-time synthesis does not create a new
[olw]git commit
Duplicate handling:
default behavior is
keep_existingfor the same normalized questioninteractive terminals only prompt for a strategy when a duplicate already exists
save_with_suffixkeeps the existing page and writes a new suffixed fileupdate_in_placerewrites the existing synthesis only when its body still matches the DB-tracked hashif the existing synthesis was manually edited,
update_in_placerefuses to overwrite itsynthesis pages cannot cite another synthesis page as a source
Compare a new model or provider
olw compare is a vault switch advisor, not a benchmark harness. It compares your
current vault config against one challenger config using the same active vault and
the same raw/ notes.
# Same provider, different heavy model
olw compare --heavy-model qwen2.5:14b
# Try a different local provider
olw compare \
--provider lm_studio \
--provider-url http://localhost:1234/v1 \
--fast-model google/gemma-4-e4b \
--heavy-model google/gemma-4-e4b
# Quick spot-check on a large vault
olw compare --heavy-model qwen2.5:14b --sample-n 20What it does:
rebuilds the current config and challenger config in isolated preview vaults
writes reports under
.olw/compare/<run_id>/leaves your active
raw/andwiki/untouched and does not modify active.olw/state outside.olw/compare/returns one verdict:
switch,keep_current, ormanual_review
Useful options:
--queries path/to/queries.tomladds a few representative questions to the comparison--out /tmp/my-comparewrites artifacts outside the vault if you want to inspect them elsewhere--keep-artifactsretains the ephemeral preview vaults instead of deleting them after the run--sample-n Nlimits the preview to the firstNraw notes for a fast spot-check--allow-cloud-uploadis required when the challenger uses a cloud provider
Notes:
compare previews automated generated output, not the final curated vault after human review
the report includes a ready-to-copy
wiki.tomlsnippet for the challenger when the verdict isswitch
Minimal queries.toml example:
[[query]]
id = "backprop"
question = "What is backpropagation?"
expected_contains = ["chain rule"]Reports are written as Markdown and JSON by default:
report.md— recommendation-first summary with next stepsreport.json— full machine-readable reportsummary.json— compact verdict and reason summary
How it works
The pipeline has three stages, each using the LLM for a different purpose:
raw/note.md
│
▼ olw ingest (or olw run)
Fast LLM (3B–8B)
• Reads note
• Extracts concept names
• Preserves explicitly evidenced named references as knowledge item candidates
• Writes quality score + summary to state.db
• Creates wiki/sources/Note.md (source summary page)
│
▼ olw compile
Heavy LLM (7B–14B)
• For each concept: gathers all source notes that mention it
• Injects rejection feedback from previous reviews into the prompt
• Writes a wiki article with [[wikilinks]] to related concepts
• Adds quality annotations if confidence is low or sources are sparse
• Lands in wiki/.drafts/ for review
│
▼ olw review (or olw approve)
• Interactive numbered menu — approve / reject / diff / edit
• Rejection feedback stored and injected into next compile
• On approve: annotations stripped, article published to wiki/
• Updates wiki/index.md (navigation layer)
• Git commits the changeNo vector databases, no embeddings. wiki/index.md acts as the routing layer for olw query. This keeps the setup simple and works well up to ~100 source notes.
The pipeline is intentionally conservative. Strong concepts become draft articles; explicitly evidenced named references become auditable knowledge item candidates. This keeps source-specific names visible without generating low-evidence articles from them.
Multi-language support
olw detects the language of each raw note during ingest and stores it. At compile time, the article is written in that language — no configuration needed.
Extraction and cleanup are designed to be language-agnostic. The pipeline avoids hard-coded natural-language word lists for title/entity promotion. Instead, it uses structural evidence, explicit source evidence, and conservative confidence levels so notes in any language follow the same rules.
How it works:
Ingest — the fast model detects the primary language and stores an ISO 639-1 code (
en,fr,de, …) per note in the state DB.Compile — when all source notes for a concept share the same language, the heavy model is instructed to write the article in that language. If sources are mixed, it falls back to matching the source text.
Config override — set
languageinwiki.tomlto force a specific output language for the whole vault, regardless of what the model detected.
[pipeline]
language = "fr" # all articles will be written in FrenchLeave language unset (the default) to let auto-detection drive it per concept.
Example: a French note ingested alongside English notes produces a French article for French-only concepts and an English article for concepts sourced from English notes. Setting language = "en" forces everything to English.
This language setting controls generated article language only. It does not enable language-specific concept merging or ontology decisions.
Knowledge item candidates
Not every useful reference deserves a wiki article. During ingest, olw keeps a separate knowledge item ledger for ambiguous, low-evidence references found explicitly in notes:
LLM-proposed named references accepted only when the exact text appears in the title, filename, or body
structurally prominent quoted titles, such as
"A Practical Guide To Notes"confirmed concepts mirrored into the ledger as confirmed knowledge items
These items are not compiled into articles by default. They are preserved for later review, classification, or future evidence accumulation.
olw items audit
olw items show "Example Reference"This is deliberately conservative: a named reference should not become a concept article unless the source content supports it. The item ledger keeps the reference from disappearing while avoiding hallucinated articles.
Rejection feedback loop
When you reject a draft:
olw review
# Select draft → [r]eject → "The overview section is too vague, needs concrete examples"The feedback is stored in the state database. On the next compile of that concept, the prompt includes:
PREVIOUS REJECTIONS — address these issues:
- The overview section is too vague, needs concrete examplesAfter 5 rejections of the same concept without an approval, the concept is auto-blocked and excluded from future compiles until you explicitly re-enable it:
olw unblock "Quantum Computing"Draft annotations
Drafts with low confidence or sparse sources are annotated with HTML comments that are invisible in Obsidian's preview but visible in the editor:
<!-- olw-auto: low-confidence (0.32) — verify before publishing -->
<!-- olw-auto: single-source — cross-reference recommended -->
## Overview
...Annotations are stripped automatically when you approve a draft. olw review surfaces them as a warning in the draft list.
Vault structure
my-wiki/
├── raw/ ← YOUR NOTES (never modified by olw)
│ ├── quantum-computing.md
│ └── ml-fundamentals.md
├── wiki/
│ ├── Quantum Computing.md ← concept articles (flat, one per concept)
│ ├── Machine Learning.md
│ ├── sources/ ← auto-generated source summaries
│ │ ├── Quantum Computing Fundamentals.md
│ │ └── ML Fundamentals.md
│ ├── queries/ ← saved Q&A answers (olw query --save)
│ ├── synthesis/ ← saved synthesis articles (olw query --synthesize)
│ ├── .drafts/ ← pending human review
│ ├── index.md ← auto-generated navigation + routing layer
│ └── log.md ← append-only operation history
├── vault-schema.md ← LLM context: conventions for this vault
├── wiki.toml ← configuration
└── .olw/
├── compare/ ← compare reports + optional preview vault artifacts
├── state.db ← SQLite: notes, concepts, articles, items, rejections, stubs
└── pipeline.lock ← advisory lock (auto-released when the holding process exits)raw/ is immutable — olw never writes to it. All metadata lives in state.db.
Configuration
wiki.toml (created by olw init):
[models]
fast = "gemma4:e4b" # extraction, analysis, query routing
heavy = "qwen2.5:14b" # article generation, Q&A answers
# Single-model: set heavy = fast
# ── Local Ollama (default) ────────────────────────────────────────────────────
[ollama]
url = "http://localhost:11434" # supports LAN: http://192.168.1.x:11434
timeout = 600
fast_ctx = 16384 # context window for fast model (tokens)
heavy_ctx = 32768 # context window for heavy model (tokens)
# ── Any other provider (replaces [ollama] when present) ──────────────────────
# [provider]
# name = "groq" # or lm_studio, vllm, together, azure, custom …
# url = "https://api.groq.com/openai/v1"
# timeout = 120
# fast_ctx = 8192
# heavy_ctx = 32768
# azure_api_version = "2024-02-15-preview" # Azure only
[pipeline]
auto_approve = false # true = skip draft review
auto_commit = true # git commit after each operation
auto_maintain = false # true = run maintain checks after each compile
max_concepts_per_source = 8 # limit concepts extracted per note
watch_debounce = 3.0 # seconds after last file event before processing
ingest_parallel = false # true = parallel chunk analysis (needs OLLAMA_NUM_PARALLEL>=4)
# language = "en" # ISO 639-1 output language; autodetects from notes if unset
# inline_source_citations = false
# source_citation_style = "legend-only" # legend-only | inline-wikilink
# draft_media = "reference" # reference | embed | omitAPI keys are never stored in
wiki.toml. They are read at runtime from the provider-specific env var (e.g.GROQ_API_KEY), the genericOLW_API_KEYenv var, or theapi_keyfield in~/.config/olw/config.toml(written byolw setup).
Tuning context windows
heavy_ctx controls how much source material the heavy model reads when writing articles (source budget = heavy_ctx / 2 chars) and how long the generated article can be. Defaults target 16 GB VRAM. If you use a model with a large context window (e.g. gemma4:e4b supports 128K), increase it.
| VRAM | Recommended heavy_ctx | Source budget | Notes |
|---|---|---|---|
| 8 GB | 8192 | ~4K chars | Minimum; short articles |
| 16 GB | 32768 | ~16K chars | Default |
| 32 GB+ | 65536 | ~32K chars | Rich multi-source articles |
fast_ctx controls ingest analysis. Notes longer than fast_ctx / 2 chars are automatically split into chunks and analyzed in sequence — all content is covered, no truncation.
| VRAM | Recommended fast_ctx | Notes per chunk |
|---|---|---|
| 8 GB | 8192 | ~4K chars |
| 16 GB | 16384 | ~8K chars — Default |
| 32 GB+ | 32768 | ~16K chars |
Speeding up long-note ingest
For vaults with many long notes (>8K chars), enable parallel chunk analysis:
[pipeline]
ingest_parallel = true # requires OLLAMA_NUM_PARALLEL>=4Also set in your shell before starting Ollama:
OLLAMA_NUM_PARALLEL=4 ollama serveThis lets Ollama process multiple chunks simultaneously. On 16 GB VRAM with gemma4:e4b (9.6 GB), 4 parallel slots fit comfortably (~12.8 GB total). Wall time for a 25K-char note drops from ~39s to ~14s.
After editing wiki.toml, no reinstall is needed. Run olw compile --force to regenerate articles with the new context budget.
Commands
| Command | Description |
|---|---|
olw setup | Interactive setup wizard: pick provider, models, vault |
olw init PATH | Create vault structure and git repo |
olw init PATH --existing | Adopt an existing Obsidian vault |
olw doctor | Check provider connectivity, models, vault structure |
olw run | Full pipeline: ingest → compile → lint → [approve] |
olw run --auto-approve | Full pipeline, publish without review |
olw run --dry-run | Report what would happen, make no changes |
olw compare --heavy-model MODEL | Compare current vault config against one challenger model |
olw compare --provider NAME --provider-url URL ... | Compare a provider switch safely in isolated preview vaults |
olw ingest --all | Analyze all raw notes |
olw ingest FILE | Analyze one note |
olw compile | Generate wiki articles → .drafts/ |
olw compile --retry-failed | Retry previously failed notes |
olw review | Interactive draft review (approve / reject / diff) |
olw approve --all | Publish all drafts without review |
olw approve FILE | Publish one draft |
olw reject FILE | Discard a draft (prompts for feedback) |
olw reject FILE --feedback "..." | Discard with feedback for next compile |
olw reject --all | Discard all drafts (prompts once for shared feedback) |
olw reject --all --feedback "..." | Discard all drafts with feedback |
olw unblock "Concept" | Re-enable a concept blocked after 5 rejections |
olw maintain | Health check + stubs + orphan and merge suggestions |
olw maintain --fix | Repair broken alias links, create stubs, normalize alias wikilinks |
olw maintain --dry-run | Report issues without making changes |
olw items audit | Show preserved non-concept knowledge item candidates |
olw items show NAME | Show one knowledge item and its source mentions |
olw status | Show pipeline state and pending drafts |
olw status --failed | List failed notes with error messages |
olw query "question" | Answer from your wiki |
olw query "..." --save | Answer and save to wiki/queries/ |
olw query "..." --synthesize | Answer and save a synthesis article to wiki/synthesis/ |
olw lint | Health check: orphans, broken links, stale articles |
olw lint --fix | Auto-fix missing frontmatter fields |
olw watch | File watcher — auto-pipeline on new notes |
olw watch --auto-approve | Watch + auto-publish (no manual review) |
olw undo | Revert last [olw] git commit |
olw clean | Clear state DB + wiki/, keep raw/ notes |
All commands accept --vault PATH or the env var OLW_VAULT.
Providers
Run olw setup to pick a provider interactively. All providers are also configurable directly in wiki.toml.
| Provider | Type | Embeddings | Notes |
|---|---|---|---|
| Ollama | local | ✓ | default; full offline |
| LM Studio | local | ✓ | |
| vLLM | local | ✓ | |
| llama.cpp | local | — | |
| LocalAI | local | ✓ | |
| TGI | local | — | |
| SGLang | local | ✓ | |
| Llamafile | local | — | |
| Lemonade | local | — | |
| Groq | cloud | — | fast inference, free tier |
| Together AI | cloud | ✓ | |
| Fireworks AI | cloud | ✓ | |
| DeepInfra | cloud | ✓ | |
| OpenRouter | cloud | — | routes to many models |
| Mistral AI | cloud | ✓ | |
| DeepSeek | cloud | — | |
| SiliconFlow | cloud | ✓ | |
| Perplexity | cloud | — | |
| xAI (Grok) | cloud | — | |
| Azure OpenAI | cloud | ✓ | see azure_api_version |
| Custom | any | — | enter URL manually |
RAG (embeddings) requires a provider that supports /v1/embeddings. The default index-based query works with all providers.
Model recommendations
| Role | Ollama | Cloud |
|---|---|---|
| Fast (analysis + routing) | gemma4:e4b, llama3.2:3b | llama-3.1-8b-instant (Groq), mistral-7b |
| Heavy (article writing) | qwen2.5:14b, llama3.1:8b | llama-3.3-70b (Groq), mistral-large |
| Single model (everything) | llama3.1:8b, mistral:7b | any 7B+ |
Any model with JSON format / response_format: json_object support works. The tool degrades gracefully with smaller models.
Obsidian tips
Graph view — concept pages link to source pages and each other via
[[wikilinks]]; before approval use-path:raw -path:wiki/sources -path:_resources -file:Welcome, after approval add-path:wiki/.draftsSource citations — when inline citations are enabled, the default style stays graph-quiet as
[S1](#Sources)links while source pages link once in## Sources; setsource_citation_style = "inline-wikilink"if you want every citation to create a source edgeMedia — source pages preserve
![[media]]embeds; generated drafts default to plain media references to avoid attachment nodes dominating the graph (draft_media = "reference")Draft review — drafts live in
wiki/.drafts/and may not appear in Obsidian's default graph filters; useolw doctorfor the recommended draft-review and published-only filtersDataview — query by
status: published,confidence: > 0.7,tags: [physics], etc.Backlinks — every concept page shows which source pages mention it
Web Clipper — save web articles directly to
raw/(see docs/web-clipper-setup.md)
Quality principles for contributors and AI agents
Prefer deterministic, auditable cleanup over broad LLM-driven merging.
Do not use LLM aliases as automatic merge authority; aliases are weak evidence.
Keep concept extraction language-agnostic. Avoid hard-coded English or other language-specific word lists unless the feature is explicitly scoped to that language.
Preserve weak entity references as knowledge item candidates rather than generating unsupported concept articles.
Source pages and
[S1](#Sources)citations should remain graph-quiet by default; source-page edges belong in## Sources.Generated drafts should avoid media embeds by default. Source pages can preserve embeds; draft articles should usually contain plain media references.
Raw notes are immutable. All generated state belongs under
wiki/and.olw/.
Running the tests
All tests are offline — no Ollama required.
git clone https://github.com/kytmanov/obsidian-llm-wiki-local
cd obsidian-llm-wiki-local
uv sync --group dev
uv run pytestFor the full end-to-end smoke test (requires a running provider):
# Ollama (default)
bash scripts/smoke_test.sh
# LM Studio or any other OpenAI-compatible endpoint
PROVIDER=lm_studio bash scripts/smoke_test.sh
# LM Studio with the validated local baseline model
PROVIDER=lm_studio FAST_MODEL=gemma4:e4b HEAVY_MODEL=gemma4:e4b \
bash scripts/smoke_test.sh
# Compare smoke test
PROVIDER=lm_studio FAST_MODEL=gemma4:e4b HEAVY_MODEL=gemma4:e4b \
bash scripts/compare_smoke.shIf LM Studio rejects the short alias, use the exact loaded model id it reports, for example google/gemma-4-e4b.
FAQ
Q: I ran olw compile but nothing appears in Obsidian.
Drafts land in wiki/.drafts/ — Obsidian hides dotfolders by default so they won't show in the graph yet. Run:
olw review # interactive review
# or
olw approve --allArticles move to wiki/ and become fully visible.
Q: Compile says "2 article(s) failed: Methodology, Sprints" — what do I do?
Failed concepts are retried automatically on the next run. Or force a retry:
olw compile --retry-failedIf the same concepts keep failing, the LLM is likely struggling with JSON output for those specific titles. Try increasing heavy_ctx in wiki.toml (see Tuning context windows).
Q: I see structured_output attempt N failed messages during compile — is something broken?
No. This is the built-in 3-tier retry system working as designed. The model occasionally echoes the JSON schema structure instead of flat output — the retry corrects it. Articles are still generated. A real failure surfaces as article(s) failed: ... in the summary line.
Q: olw ingest --all && olw compile gives "Missing option '--vault'".
Run olw setup first to configure a default vault, or pass it explicitly:
export OLW_VAULT=~/my-wiki
olw ingest --all && olw compileQ: I changed models in olw setup but olw compile still uses the old model.
Re-run olw init on your vault — it syncs the model settings from your global config into wiki.toml:
olw init ~/my-wikiQ: A concept keeps getting rejected — how do I stop it from recompiling?
After 5 rejections with feedback (olw reject --feedback "…"), the concept is auto-blocked and excluded from future compiles. olw status lists blocked concepts. To re-enable one:
olw unblock "Concept Name"Q: Can I use a cloud provider like Groq or Together AI instead of Ollama?
Yes. Run olw setup and select the provider from the numbered list. Enter your API key when prompted — it is stored only in ~/.config/olw/config.toml. Alternatively set the provider-specific env var before each command:
export GROQ_API_KEY=gsk_...
olw runThe pipeline, vault structure, and all olw commands work identically regardless of provider.
Q: I changed providers in olw setup but wiki.toml still shows [ollama].
Re-run olw init on your vault to sync the global config into wiki.toml:
olw init ~/my-wikiFor existing vaults with a [ollama] section you can also add a [provider] block manually — it takes precedence over [ollama] when present.
Why not just use a chatbot?
Chatbots forget. Every conversation starts fresh. This tool builds a persistent artifact — a wiki that grows with every note you add, that you can open in Obsidian, search, query, and edit by hand.
The LLM is a compiler, not a conversation partner. You give it raw material; it produces structured knowledge. The output is plain markdown files you own forever.
Feedback
olw does not collect telemetry.
If something was confusing, useful, annoying, or missing, please tell us:
Bug reports: https://github.com/kytmanov/obsidian-llm-wiki-local/issues
Suggestions and experience reports: https://github.com/kytmanov/obsidian-llm-wiki-local/discussions
Source code: https://github.com/kytmanov/obsidian-llm-wiki-local
License
MIT — see LICENSE.
CHANGELOG.md
Changelog
[Unreleased]
Notice
obsidian-llm-wiki is entering maintenance mode. Bug fixes will continue to be released here. New features and capabilities are being built in Synto, the successor project. See the README for migration details.
[0.8.5] - 2026-05-16
Fixed
Malformed LaTeX in LLM output —
\[ ... \]display-math delimiters and bare LaTeX lines (e.g.\frac{a}{b}) are now automatically converted to Obsidian-compatible$$ ... $$notation in both the compile and query pipelines. Existing code blocks and math regions are protected from rewriting. Closes #67.
[0.8.4] - 2026-05-16
Fixed
API key prompt for local providers in setup wizard — vLLM, LM Studio, and other non-Ollama local providers can be deployed with key verification in enterprise environments. The setup wizard now shows the optional API key prompt for all non-Ollama providers, not only cloud or custom ones. Closes #64.
[0.8.3] - 2026-05-08
Fixed
Release metadata alignment — the published package version, runtime
__version__, and changelog are now aligned again afterv0.8.2was tagged from code that still declared0.8.1, which prevented a new PyPI release from being uploaded.
[0.8.1] - 2026-05-07
Added
Added internal foundation types and reader/engine interfaces for future source-aware and pack-oriented features. These are additive and are not wired into runtime behavior yet.
Fixed
Saved query/link hygiene — query and synthesis outputs now strip invented
[[wikilinks]]that do not resolve to existing pages, preventing broken links from being written intowiki/queries/andwiki/synthesis/.Compile overflow diagnostics — prompt-context retry failures now preserve the
context_too_largefailure category instead of degrading tootherwhen reduced retry budgets still cannot fit within the configured context window.LM Studio smoke/runtime robustness — smoke model resolution and compile fallback handling were hardened so prompt/context overflow scenarios are more recoverable and easier to diagnose.
Changed
Schema migration v7 -> v8 (additive).
raw_notesgains six new columns:source_type(default'notes'),origin_uri,imported_at,normalized_hash,extractor_version,prompt_version. Existing rows get the default forsource_typeandNULLelsewhere. No code path reads the new columns yet. v0.8 behavior is unchanged.
Migration notes
On first run with this version,
state.dbupgrades from v7 to v8 automatically. Recommended: back up.olw/state.dbfirst (cp .olw/state.db .olw/state.db.bak.v7). The upgrade is one-way: downgrading the package after upgrading the DB leaves aversion=8row. Older code paths still function but are not regression-tested against future schemas.
[0.8.0] - 2026-05-02
Highlights
v0.8.0 adds query synthesis as a first-class workflow. You can now save grounded answers as durable synthesis articles in wiki/synthesis/, deduplicate them by normalized question hash, and keep compare runs isolated from active query and synthesis content.
New Features
olw query --synthesize— answer a question from the wiki and save the result as a published synthesis article inwiki/synthesis/.Question-hash deduplication — repeated synthesis requests for the same normalized question reuse the existing article instead of creating duplicates.
Saved query outputs — query answers can be persisted in
wiki/queries/alongside synthesis articles for later review.
Changes
Safer synthesis bookkeeping — synthesis articles are tracked in state with
kind,question_hash, and source hashes so duplicate detection and update-in-place behavior stay deterministic.Query/link hygiene — query resolution now understands
sources/...links and lint flags synthesis-to-synthesis source chains as advisory issues instead of silently allowing them.Compare safety coverage — compare runs explicitly avoid mutating active
wiki/queries/andwiki/synthesis/, with smoke coverage for those guarantees.Docs refresh — README and smoke guidance now cover query synthesis, LM Studio flows, and the latest support links.
[0.7.2] - 2026-05-01
Highlights
Fixes silent compile failures on local LLM providers (#48). Articles whose generated output exceeded article_max_tokens previously surfaced as confusing JSON-parse errors with empty model responses on llama.cpp/LM Studio. Truncation is now detected at the HTTP layer and surfaced as LLMTruncatedError with an actionable message naming the exact config knob to raise.
Bug Fixes
Legacy compile path respects
article_max_tokens(#48) —compile_notes(the--legacypath) was hardcoded to 4096 tokens and ignoredpipeline.article_max_tokens. It now uses the same_article_num_predictbudget as the primarycompile_conceptspath.Truncation detection in HTTP clients — both
OpenAICompatClientandOllamaClientnow inspectfinish_reason/done_reasonand raiseLLMTruncatedErrorinstead of returning empty content, eliminating the silent JSON-parse failure mode.Cloud max_tokens auto-downgrade — providers that reject
max_tokensas exceeding the model's hard output limit (e.g. legacy gpt-4-turbo with 4096-output models) now trigger a single halve-and-retry instead of bubbling an HTTP 400 to the user.Pre-flight context-budget guard —
_article_num_predictraisesValueError(caught per-concept) when source content fillsheavy_ctxpast the floor needed for reliable JSON generation, instead of silently sendingnum_predict=0.
Changes
pipeline.article_max_tokensdefault raised to 16384 (was 4096). Restores the originalheavy_ctx // 2design that was lowered defensively to dodge an LM Studio HTTP 400 already covered by an existing auto-downgrade.PipelineConfig.article_max_tokensvalidator rejects values below 512 (the floor required for structured generation).olw lintsurfaces aconfig_outdatedissue whenarticle_max_tokens == 4096, guiding existing users whosewiki.tomlstill pins the legacy default.Compile failure summary logs a per-category count (
truncated,bad_request,structured_output,context_too_large) at the end of each compile run, distinguishing truncation issues from JSON-schema or no-source failures.n_keep > n_ctxauto-downgrade now logs at WARNING (was DEBUG), surfacing the silent context-mismatch fallback to the user.
Migration
If your wiki.toml was generated by an earlier olw setup it likely contains article_max_tokens = 4096. Either delete the line to pick up the new default or raise it explicitly:
[pipeline]
article_max_tokens = 16384olw lint will flag this until corrected.
[0.7.1] - 2026-04-28
Highlights
v0.7.1 hardens long-note recovery and concept compile retries. Interrupted chunked ingest can now resume from saved progress, and failed concept articles remain retryable instead of disappearing behind source-level completion state.
Bug Fixes
Resumable chunked ingest (#44) — long notes persist successful chunk analyses as checkpoints and reruns skip completed chunks instead of starting over after an intermittent LLM failure.
Failed concept compile recovery (#42) — compile scheduling now tracks status per concept/source pair, so partial success no longer marks an entire raw note done while some concepts are still failed.
Changed compiled notes re-ingest correctly —
olw ingestnow skips previously ingested/compiled notes only when the stored content hash still matches the file on disk.Checkpoint cleanup for shortened notes — stale chunk checkpoints are purged when a note no longer needs chunking.
Safer compile token budget — article generation now clamps
num_predictto the true remaining context budget instead of forcing a minimum that can exceed provider limits.Published article link hygiene — generated output cleanup removes malformed empty wikilinks before publication.
Changes
Targeted concept compile —
olw compile --concept NAMEcan compile a specific concept even when it is not currently pending.Failed concept retry CLI —
olw compile --retry-failednow retries failed concept compiles in addition to failed raw-note ingest records.Article output budget config —
pipeline.article_max_tokenscan tune the soft article-generation output cap while still respecting provider context limits.
[0.7.0] - 2026-04-26
Highlights
v0.7.0 improves draft hygiene, graph behavior, and language-agnostic knowledge preservation. Source citations can stay graph-quiet, generated drafts are less likely to leak malformed media/link syntax, and ambiguous named references are preserved only when explicitly evidenced in the source note rather than inferred from Latin-script regexes.
New Features
Knowledge item audit —
olw items auditandolw items show NAMEexpose ambiguous named references and prominent quoted titles without compiling them into concept articles by default.Evidence-gated named references — ingest now asks the fast model for exact named references copied from the note and stores them only when the text appears in the title, filename, or body. These references use the generic
named_referencesubtype instead of language-specific person/product/org regex classification.Graph-quiet citation controls — inline source citations can use local
[S1](#Sources)markers while the canonical source page links remain in the## Sourceslegend.
Changes
More conservative concept handling — concept extraction no longer uses test-vault-specific weak-concept denylists or LLM aliases as automatic merge authority.
Better generated draft cleanup — compile post-processing repairs malformed media references, removes dangling markdown-link fragments, and trims quote/citation debris from wikilinks before lint runs.
Improved lint coverage — lint ignores wikilinks inside inline code, catches dangling markdown brackets, and reports draft/published graph filters more clearly.
README refresh — documentation now describes the language-agnostic evidence rules, item audit workflow, source citation styles, draft media behavior, and current LM Studio smoke-test guidance.
Bug Fixes
Structured output resilience —
AnalysisResulttoleratessummary: nullfrom small local models and synthesizes a fallback summary instead of failing ingest.Language-agnostic item extraction — removed Latin-script-only person, product, and CamelCase organization regexes from the knowledge-item path.
Draft media hygiene — malformed escaped media references such as
!\[...jpeg\]are normalized before drafts are reviewed or published.
Known Limitations
Concept extraction may still overproduce drafts for ambiguous or single-source notes. v0.7.1 is expected to focus on semantic concept filtering, concept-name cleanup, and better item-audit ranking.
Source-supported named references are intentionally preserved as low-confidence candidates and may include noisy one-off handles or names. Review
olw items auditbefore promoting them.
[0.6.0] - 2026-04-21
Highlights
v0.6.0 adds olw compare, a safe way to preview a model or provider switch before changing your vault config. Instead of benchmarking abstract prompt quality, olw compare rebuilds isolated previews from your current vault's raw/ notes, compares the current setup against one challenger, and tells you whether to switch, keep the current config, or inspect the results manually.
New Features
olw compare— compare the active vault config against a single challenger model/provider configuration using the same source notes. The command produces a recommendation-first report and shows the exactwiki.tomlconfig needed to reproduce the challenger setup.
Changes
Safer preview runs — compare never mutates the active vault outside
.olw/compare/, rejects unsafe path/symlink inputs, and requires explicit acknowledgement before sending vault content to a cloud provider.Better compare guidance — reports now include clearer verdicts, config-change instructions, and artifact output designed for manual review instead of benchmark-style winner framing.
Docs and smoke coverage — README and smoke tests now cover the new compare workflow, including LM Studio / OpenAI-compatible local backends.
[0.5.1] - 2026-04-19
Highlights
v0.5.1 hardens the pipeline against a common quirk of small local models. When the fast model returns concepts as a flat list of strings instead of {name, aliases} objects, ingest no longer fails — the payload is coerced transparently and the note proceeds. The root cause, an over-literal JSON template passed to the model, is also fixed so every list[Model] field benefits from the same resilience.
Bug Fixes
String-concept tolerance (#32) —
AnalysisResultaccepts a flat list of concept strings from the LLM and wraps them intoConceptobjects with empty aliases. Mixed payloads (some strings, some dicts) also validate. Alog.debugline fires when coercion triggers, so the signal stays observable for prompt-tuning.Structured-output template renders nested objects — the fill-in JSON example passed to the fast model now expands
list[Concept],list[ArticlePlan], andlist[LintIssue]into their real shape, including enum discriminator values. Previously the model saw only the array's description string and sometimes produced wrong item types.Optional[...]fields still carry their outer description throughanyOf.
Changes
Cleaner error when the vault path is missing —
olw <cmd>now prints a short, actionable message pointing atolw initorolw setupinstead of surfacing a raw config-loading traceback.Smoke test: new pre-LLM "Structured output resilience" block pins the validator + template +
request_structuredend-to-end against a stub client, so the class of failure above is caught in the installed artifact without requiring a running model.README: concept-block rejection /
olw unblocksection trimmed and clarified.
[0.5.0] - 2026-04-18
Highlights
v0.5 makes the wiki resilient to the natural way humans refer to concepts. When you write about "Program Counter" once and later mention "PC", olw now recognizes they're the same thing. Aliases are extracted at ingest, stored alongside articles, and used everywhere the pipeline resolves a concept name — so broken links to common abbreviations get repaired automatically, and queries using either form land on the right article.
New Features
Concept aliases — during ingest, the fast model extracts short aliases for each concept (e.g. "Program Counter (PC)" → alias
PC). Aliases are stored in the state DB and written into each article'saliases:frontmatter, so Obsidian picks them up for its own link suggestions.Alias-aware link repair —
olw maintain --fixnow rewrites broken[[Alias]]wikilinks to[[Canonical|Alias]]when an unambiguous alias is known. Links inside code fences are left untouched. Still-unresolvable targets fall through to stub creation as before.Alias-aware queries and health checks —
olw queryresolves page routes through the alias map when the canonical name misses, andolw lintcounts alias forms as valid links so they don't get flagged as broken.olw status --failed— filter the status report to only failed notes with their error messages. Useful when triaging after a bulk ingest.
Changes
The auto-generated wiki index is now
wiki/index.md(lowercase). Vaults created before v0.5 withwiki/INDEX.mdare handled transparently — no manual rename needed.Smoke test suite expanded: 105 end-to-end assertions now cover lint issue-type coverage,
maintain --fixidempotency, stub frontmatter shape, legacy-compile bit-rot, and thestatus --failedfilter.
Breaking Changes
None. Existing vaults upgrade automatically on first olw run: the DB gains a concept_aliases table, aliases are backfilled from current concept titles (deterministic, no LLM calls), and any legacy INDEX.md is treated like the new lowercase form.
[0.4.0] - 2026-04-16
Highlights
v0.4 makes olw smarter about where you are and what you're writing. Notes are now analyzed in the language they were written in, and articles are compiled in the same language — no more English-only output in a multilingual vault. You can also reject an entire batch of drafts in one go. Two usability papercuts are fixed: the tool now finds your vault automatically when you're already inside it, and the review menu works correctly in all terminals.
New Features
Multi-language support —
olw ingestdetects the language of each note and stores it.olw compilethen writes each article in the appropriate language: the detected language if all sources agree, or the vault-widelanguagesetting fromwiki.tomlif configured. French notes produce French articles, Japanese notes produce Japanese articles, and so on.olw reject --all— Reject every pending draft in one step with a shared feedback message. Useful when a bad prompt version or wrong model produced a full batch of unusable drafts.Vault auto-detection — Commands no longer fail when
--vaultis not passed and no default was saved inolw setup. If you're inside a vault directory (or any subdirectory),olwfinds it automatically by walking up to the nearestwiki.toml. The "press Enter to skip" flow in setup now actually makes sense.
Bug Fixes
Review menu shortcuts were invisible in some terminals — The
olw reviewaction menu ([a]pprove,[r]eject, etc.) used Rich markup that silently ate the first letter of each word in terminals with limited style support, showingpprove eject ditinstead. Prompts now render as plain text (a=approve, r=reject, e=edit, ...) and work correctly everywhere.
[0.3.0] - 2026-04-15
Highlights
v0.3 opens the pipeline to any LLM provider. Ollama stays the default, but you can now point olw at Groq, Together AI, Mistral, LM Studio, vLLM, Azure OpenAI, or any other OpenAI-compatible endpoint — local or cloud. The setup wizard gained a provider selection step, API keys are stored securely in the global config (never in wiki.toml), and all pipeline internals use a shared protocol so adding new providers requires no pipeline changes.
New Features
Multi-provider support —
olw setupnow presents a numbered provider menu covering 9 local runtimes (LM Studio, vLLM, llama.cpp, LocalAI, TGI, SGLang, Llamafile, Lemonade, Ollama) and 11 cloud providers (Groq, Together AI, Fireworks AI, DeepInfra, OpenRouter, Mistral AI, DeepSeek, SiliconFlow, Perplexity, xAI / Grok, Azure OpenAI) plus a free-form Custom option. Select by number or name.OpenAI-compatible client (
openai_compat_client.py) — thinhttpxwrapper matching theOllamaClientinterface. Handles bearer auth, Azureapi-keyheader +?api-version=query param, JSON mode with auto-downgrade on HTTP 400, and ordered embedding responses.[provider]section inwiki.toml— non-Ollama vaults use a[provider]block withname,url,timeout,fast_ctx,heavy_ctx(andazure_api_versionfor Azure). The[ollama]section still works unchanged — existing vaults need no migration.API key security — keys are stored in
~/.config/olw/config.toml(user-private global config) and resolved at runtime from the provider-specific env var (e.g.GROQ_API_KEY), the genericOLW_API_KEYenv var, or the global configapi_keyfield. They are never written towiki.toml.LLMClientProtocol— structural interface (typing.Protocol) that bothOllamaClientandOpenAICompatClientsatisfy. All pipeline stages (ingest,compile,query,orchestrator,structured_output) now depend on the protocol, not the concrete Ollama class.build_client()factory — resolves the correct client fromconfig.effective_provider. Pipelines and tests need no awareness of which provider is active.
Improvements
olw doctoris now provider-aware: shows the active provider name and URL, and gives provider-appropriate hints for missing modelsolw setuptemp client correctly passesazure=Trueandsupports_embeddingsflags so the health probe uses the right auth headerEmpty URL for
customorazureprovider now exits with a clear error instead of producing cryptic HTTP failures laterazure_api_versionflows fromolw setup→ global config →wiki.toml(Azure vaults) so each vault can override the API version independentlyembed_batchnow catchesTimeoutExceptionand wraps it asLLMError(previously onlygeneratedid)LLMClientProtocoldeclares__enter__/__exit__so type checkers recognise both clients as context managers
Breaking Changes
None. Ollama remains the default. Existing wiki.toml files with [ollama] sections work without modification.
[0.2.0] - 2026-04-11
Highlights
v0.2 turns the wiki into a self-improving system. Drafts can be rejected with feedback, and the next compile automatically addresses it. A new review interface makes approving and rejecting drafts fast. Maintenance tooling keeps the wiki healthy over time.
New Features
Rejection feedback loop — Reject a draft with a reason (
olw review), and the next compile injects that feedback into the prompt. Concepts rejected 5+ times are blocked and surfaced inolw status.Draft review interface (
olw review) — Interactive numbered menu for reviewing drafts. Approve, reject with feedback, edit in$EDITOR, diff against published version, or view rejection diff vs previous attempt.Pipeline orchestrator (
olw run) — Single command runs the full ingest → compile → lint → approve sequence. Handles selective recompile (only concepts linked to changed notes), transient failure retry, and optional auto-approve.Self-maintenance (
olw maintain) — Detects broken wikilinks and auto-creates stub articles for them. Reports orphan articles, near-duplicate concept suggestions, and source quality warnings.Inline draft annotations — Low-confidence drafts get HTML comment annotations (
<!-- olw-auto: ... -->) flagging single-source articles, low-quality sources, or uncertain content. Annotations are stripped automatically on approve.Long-note chunked ingest — Notes larger than the context window are split into chunks, analyzed in parallel (with
ingest_parallel = true), and merged. Enables processing notes of any length without truncation.Pipeline concurrency lock —
olw watchand manualolw runno longer race. Advisory file lock (fcntl.flock) prevents concurrent pipeline runs from corrupting state.
Improvements
Per-concept compile timings in
olw runoutput (avg + top-3 slowest)olw setupshows installed version in headerStructured output uses fill-in templates instead of raw JSON Schema — reduces model confusion and schema-echo failures
Ollama requests now set
num_predictto prevent mid-article JSON truncationSchema versioning added — future DB migrations are ordered and transactional
Bug Fixes
httpx.ReadTimeoutduring compile now caught and classified as a transient failure (concept is retried, pipeline continues)Re-approving a previously published article no longer raises a UNIQUE constraint violation
reject_draftpath resolution fixed on macOS
[0.1.3] - 2026-04-08
CI: add PyPI publish job to release workflow
[0.1.2] - 2026-04-08
Fix release script — bump version via PR branch, push tag after merge
[0.1.1] - 2026-04-07
Initial public release
116 files · 107 not served here
- .github/FUNDING.yml (not served here)
- .github/workflows/benchmark.yml (not served here)
- .github/workflows/ci.yml (not served here)
- .github/workflows/release.yml (not served here)
- .gitignore (not served here)
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- CHANGELOG.md
- CLAUDE.md
- LICENSE
- README.md
- RELEASE.md
- docs/issue-30-inline-source-citations-plan.md
- docs/web-clipper-setup.md
- install.py (not served here)
- pyproject.toml (not served here)
- scripts/benchmark.sh (not served here)
- scripts/compare_smoke.sh (not served here)
- scripts/release.sh (not served here)
- scripts/smoke_test.sh (not served here)
- src/obsidian_llm_wiki/__init__.py (not served here)
- src/obsidian_llm_wiki/cli.py (not served here)
- src/obsidian_llm_wiki/client_factory.py (not served here)
- src/obsidian_llm_wiki/compare/__init__.py (not served here)
- src/obsidian_llm_wiki/compare/metrics.py (not served here)
- src/obsidian_llm_wiki/compare/models.py (not served here)
- src/obsidian_llm_wiki/compare/report.py (not served here)
- src/obsidian_llm_wiki/compare/runner.py (not served here)
- src/obsidian_llm_wiki/config.py (not served here)
- src/obsidian_llm_wiki/engines.py (not served here)
- src/obsidian_llm_wiki/git_ops.py (not served here)
- src/obsidian_llm_wiki/global_config.py (not served here)
- src/obsidian_llm_wiki/indexer.py (not served here)
- src/obsidian_llm_wiki/markdown_math.py (not served here)
- src/obsidian_llm_wiki/models.py (not served here)
- src/obsidian_llm_wiki/ollama_client.py (not served here)
- src/obsidian_llm_wiki/openai_compat_client.py (not served here)
- src/obsidian_llm_wiki/pipeline/__init__.py (not served here)
- src/obsidian_llm_wiki/pipeline/compile.py (not served here)
- src/obsidian_llm_wiki/pipeline/ingest.py (not served here)
- src/obsidian_llm_wiki/pipeline/items.py (not served here)
- src/obsidian_llm_wiki/pipeline/lint.py (not served here)
- src/obsidian_llm_wiki/pipeline/lock.py (not served here)
- src/obsidian_llm_wiki/pipeline/maintain.py (not served here)
- src/obsidian_llm_wiki/pipeline/orchestrator.py (not served here)
- src/obsidian_llm_wiki/pipeline/query.py (not served here)
- src/obsidian_llm_wiki/pipeline/review.py (not served here)
- src/obsidian_llm_wiki/protocols.py (not served here)
- src/obsidian_llm_wiki/providers.py (not served here)
- src/obsidian_llm_wiki/readers.py (not served here)
- src/obsidian_llm_wiki/sanitize.py (not served here)
- src/obsidian_llm_wiki/state.py (not served here)
- src/obsidian_llm_wiki/structured_output.py (not served here)
- src/obsidian_llm_wiki/telemetry.py (not served here)
- src/obsidian_llm_wiki/vault.py (not served here)
- src/obsidian_llm_wiki/watcher.py (not served here)
- tests/compare_corpus/corpus.toml (not served here)
- tests/compare_corpus/notes/ambiguous_entity.md (not served here)
- tests/compare_corpus/notes/cross_reference.md (not served here)
- tests/compare_corpus/notes/data_heavy_table.md (not served here)
- tests/compare_corpus/notes/edge_empty_list.md (not served here)
- tests/compare_corpus/notes/long_dense_technical.md (not served here)
- tests/compare_corpus/notes/moderate_overlap.md (not served here)
- tests/compare_corpus/notes/multi_concept_overlap.md (not served here)
- tests/compare_corpus/notes/narrative_essay.md (not served here)
- tests/compare_corpus/notes/noisy_low_quality.md (not served here)
- tests/compare_corpus/notes/short_factual.md (not served here)
- tests/compare_corpus/queries.toml (not served here)
- tests/conftest.py (not served here)
- tests/fixtures/analysis_valid.json (not served here)
- tests/fixtures/compile_plan_valid.json (not served here)
- tests/fixtures/single_article_valid.json (not served here)
- tests/test_benchmarks.py (not served here)
- tests/test_cli_compile.py (not served here)
- tests/test_cli_model_flags.py (not served here)
- tests/test_cli_query.py (not served here)
- tests/test_cli_reject.py (not served here)
- tests/test_cli_status.py (not served here)
- tests/test_cli_support.py (not served here)
- tests/test_compare_cli.py (not served here)
- tests/test_compare_metrics.py (not served here)
- tests/test_compare_report.py (not served here)
- tests/test_compare_runner.py (not served here)
- tests/test_compare_safety.py (not served here)
- tests/test_compile.py (not served here)
- tests/test_compile_v2.py (not served here)
- tests/test_config.py (not served here)
- tests/test_indexer.py (not served here)
- tests/test_ingest.py (not served here)
- tests/test_items.py (not served here)
- tests/test_lint.py (not served here)
- tests/test_lock.py (not served here)
- tests/test_maintain.py (not served here)
- tests/test_markdown_math.py (not served here)
- tests/test_ollama_client.py (not served here)
- tests/test_openai_compat_client.py (not served here)
- tests/test_orchestrator.py (not served here)
- tests/test_phase0_engines.py (not served here)
- tests/test_phase0_migration_v8.py (not served here)
- tests/test_phase0_readers.py (not served here)
- tests/test_phase0_schemas.py (not served here)
- tests/test_pipeline_language.py (not served here)
- tests/test_pipeline_reject_all.py (not served here)
- tests/test_providers.py (not served here)
- tests/test_query.py (not served here)
- tests/test_query_git_behavior.py (not served here)
- tests/test_query_synthesize.py (not served here)
- tests/test_review.py (not served here)
- tests/test_sanitize.py (not served here)
- tests/test_setup.py (not served here)
- tests/test_state.py (not served here)
- tests/test_structured_output.py (not served here)
- tests/test_telemetry.py (not served here)
- tests/test_vault.py (not served here)
- tests/test_watcher.py (not served here)
- uv.lock (not served here)
Advantages
- Operates 100% locally with Ollama, ensuring data privacy and no external dependency for processing. evidence: README.md
- Preserves manual edits made to wiki articles by detecting content changes and skipping them during recompilation. evidence: README.md
- Supports incremental compilation, which optimizes performance by only updating articles linked to modified source notes. evidence: README.md
- Provides an interactive feedback loop where rejected drafts incorporate user feedback into future model prompts. evidence: README.md
Limitations
- The system is currently in maintenance mode, with new features being developed in a successor project called Synto. evidence: README.md
- The query synthesis feature is optimized for smaller vaults and may be less efficient as the number of source notes grows significantly beyond 100. evidence: README.md
Security
Risk level: Low risk
This brain runs
Agent instructions that run or fetch something (11)
CLAUDE.md:# Install (editable, auto-detects uv/pip)CLAUDE.md:python install.pyCLAUDE.md:uv sync --group devCLAUDE.md:uv run pytestCLAUDE.md:uv run pytest tests/test_ingest.py::test_function_name -v # single testCLAUDE.md:uv run pytest --cov=src/obsidian_llm_wiki # with coverageCLAUDE.md:uv run ruff check src/ tests/CLAUDE.md:uv run ruff format --check src/ tests/CLAUDE.md:uv run ruff format src/ tests/ # auto-fixCLAUDE.md:# Smoke tests (user preference: run against LM Studio with gemma4:e4b)CLAUDE.md:`git_ops.py` — Auto-commit with `[olw]` prefix, safe undo via `git revert`
Install scripts (1)
install.py:python install.py
- Low risk: scripts-present (install.py)
- Low risk: scripts-present (scripts/compare_smoke.sh)
- Low risk: scripts-present (scripts/smoke_test.sh)
Attribution and licence
- First committed by
kytmanov
- Declared authors
- kytmanov (declared in pyproject.toml)
- Publisher
- Alexander (Community)
- Source
- kytmanov/obsidian-llm-wiki-local · commit ad2e425
- Licence
- MIT License (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- kytmanov, ys-qb
AutoGineer is not affiliated with or endorsed by kytmanov.
Install from source
107 of its files are not served here, so there is no ZIP. kytmanov/obsidian-llm-wiki-local at ad2e425