Appearance
Thoth
A private, offline AI index over your notes, PDFs and boards
Overview
Thoth is a private, offline knowledge base over your own content. It builds an on-device search index of the notes, task lists, PDF highlights and boards you already keep in the suite, then lets you ask a question in plain language and get an answer written from your material — with inline citations back to the sources it used. It is part of the kimtos new-tab app suite, and it is a Pro app.
Under the hood it is a retrieval-augmented generation (RAG) system, but everything a RAG pipeline usually sends to a server happens in your browser instead: the embedding model, the vector index and the language model that writes the answer all run on-device. Nothing is uploaded, there is no account, and there are no third-party calls.
Highlights
- Ask across everything you've written — one question searches your Notes pages, Tasks, PDF highlights and NotaBoard boards at once.
- Cited answers — the reply cites its sources inline as
[1],[2], and a Sources row lets you click a citation to open that item in its own app. - Grounded, not guessed — the model is instructed to answer using only the retrieved passages, and to say it doesn't have the answer when your content doesn't cover it.
- Incremental indexing — rebuilding the index only re-embeds documents that are new or changed and drops ones you deleted, so repeat builds are fast.
- Fully offline — the search model (~23 MB) and the chat model download once, are cached by the browser, and then run with no network at all.
- Available to the assistant — Thoth also exposes a
search_knowledgeagent tool, so the suite's HomeAI assistant can retrieve cited passages from your private index while answering.
What it indexes
Thoth reads only text you authored in other suite apps:
| Source app | What is indexed |
|---|---|
| Notes | Each page's title and Markdown content. |
| Tasks | Each task's title and description. |
| Your PDF highlights and their comments (labeled by page). | |
| NotaBoard | The text of a board's elements and sticky notes. |
Each indexed document keeps a link back to the exact record it came from, which is what makes a citation clickable.
Privacy model
Thoth adds no new place your data can go — it only reads from, and writes a derived index into, the same local browser storage the rest of the suite uses:
- The index (text passages and their embedding vectors) is stored in your browser's IndexedDB, alongside a small set of content hashes used to detect changes.
- The search model and the chat model are downloaded from a model host the first time you use them, then cached locally; after that, asking a question needs no network.
- Nothing you index, ask, or receive as an answer is ever uploaded, and there are no analytics.
Getting Started
Open Thoth from the dock. Using it is a two-step rhythm: build the index once (and again whenever your content changes), then ask as many questions as you like. As a Pro app, Thoth shows an upgrade wall for free users before the app itself opens.
Build the index
At the top of the app a status line shows what's indexed so far — No index yet on first run, or something like 128 passages · 34 documents indexed once you've built it.
- Click Rebuild index.
- The first build downloads the on-device search model (~23 MB) — you'll see a
Downloading search model…progress message. This happens only once; the model is cached for next time. - Thoth then reads your Notes, Tasks, PDF highlights and boards, splitting each into passages and embedding them. Progress shows as
Indexing 3/34: <title>. - When it finishes you'll see a summary, e.g.
Indexed 128 passages from 34 documents.
If you have no content to index yet, Thoth tells you so — add some notes, tasks, PDF highlights or boards first, then rebuild.
Rebuilding is incremental. After the first full build, later rebuilds only re-embed documents that are new or have changed since last time, and remove ones you've deleted. So it's cheap to click Rebuild index again after you've edited a note or highlighted a new PDF passage, to bring your answers up to date.
Ask a question
Once the index has content, type a question into the ask box — for example "What did I decide about the pricing model?" — and click Ask (or press ⌘/Ctrl+Enter).
Behind the scenes Thoth:
- Embeds your question and finds the most relevant passages in your index (the retrieval step).
- Loads the on-device chat model the first time you ask (
Downloading AI model…, thenThinking…). - Streams back an answer written only from those passages, token by token.
If nothing in your index is relevant, Thoth says so rather than inventing an answer — and if the index is empty, it reminds you to build it first.
Read the citations
The answer cites its sources inline as [1], [2], and so on. Below the answer, a Sources row lists those citations as chips like [1] Notes · Roadmap. Click a chip to open that item in its own app (Notes, Tasks, PDF or NotaBoard), so you can jump straight to the original context.
Asking from the assistant
You don't have to open Thoth to search your knowledge base. The suite's HomeAI assistant can call Thoth's search_knowledge tool to pull cited passages from your private index while it answers you. The index must be built in Thoth first — if it's empty, the assistant is told to have you click Rebuild index rather than guessing.
Architecture
Thoth is a retrieval-augmented generation (RAG) pipeline that runs entirely on-device. The code lives in extension/src/apps/thoth/, and it leans on two shared engines — one for embeddings, one for chat — plus the suite's shared IndexedDB. Every module that makes decisions (what to index, how to chunk, how to score) is kept pure and free of storage or model imports, so the plumbing and the logic can be tested and reasoned about separately.
Modules
| File | Role |
|---|---|
index.ts | The app descriptor and UI — the index-status header, Rebuild index button, the ask box, streamed answer and clickable Sources chips. Also declares the search_knowledge agent tool. |
sources.ts | Pure mappers turning a raw stored record from each source app into a KbDoc (app, docId, title, text). Defines SOURCES — the collections indexed: Notes pages, Tasks todos, PDF annotations, NotaBoard boards. |
chunk.ts | Splits a document into overlapping word-windows (default 180 words, 30 overlap) small enough to embed well but large enough to carry context. Pure. |
plan.ts | Pure indexing decisions — an FNV-1a content hashString, docKeyOf (${app}:${docId}), and planReindex, which compares current hashes against stored ones to decide what to (re)index and what to drop. |
indexer.ts | Orchestration — indexStatus, reindex (gather → plan → chunk → embed → store), and search (embed the query, cosine-match stored chunks). |
search.ts | Brute-force cosine similarity and topK over the stored chunk vectors — a linear scan, plenty fast for a personal-scale index. Pure. |
store.ts | The on-device vector store over the shared IndexedDB (dataStore): StoredChunk records in the thoth-chunks collection, plus the content-hash map. Vectors persist as Float32Array via structured clone. |
lib/engines/embed.ts | On-device embeddings via Transformers.js — Xenova/all-MiniLM-L6-v2 (ONNX/WASM), producing 384-dim L2-normalized vectors so cosine equals a dot product. |
lib/engines/homeai.ts | The on-device chat engine — a small instruction-tuned model (SmolLM2 360M by default) run in a Web Worker that streams the answer token by token. |
The RAG flow
Indexing
reindex gathers every source document, computes a content hash for each, and asks planReindex what changed. Documents that are new or changed lose any old chunks and are re-chunked and re-embedded; documents you deleted simply have their chunks removed. Unchanged documents are skipped entirely, so a rebuild after a small edit only touches what moved. Each resulting chunk is stored as a StoredChunk — { id, docKey, app, docId, title, text, vector } — where docKey (${app}:${docId}) groups all chunks of one document and docId is what a citation uses to reopen the original record. The hash map is then written back so the next build has a fresh baseline.
Retrieval and answering
Asking a question runs the two right-hand stages of the diagram. The query is embedded with the same MiniLM model, and topK does a brute-force cosine scan over every stored vector, keeping the best matches above a minimum similarity (the app retrieves 6 passages by default, dropping ones below 0.2 so unrelated chunks don't pad the context). Those passages are formatted with their [n] labels and app/title, and handed to the on-device chat model behind a system prompt that tells it to answer using only that context and cite sources inline — with a low temperature so it stays grounded. The answer streams back token by token, and the same passages populate the clickable Sources row.
The search_knowledge agent tool
The descriptor exposes one MCP-shaped tool, search_knowledge, so the suite's HomeAI assistant can retrieve from the private index. It takes a query and an optional limit (default 6, max 12), checks that the index is non-empty, embeds the query, runs the same search, and returns the matching passages formatted with [n] citations for the model to quote. It is read-only — it never modifies the index — and if the index is empty it returns a message asking the user to build it in Thoth first.