Series-aware translation for books.
A translator reads a series, not a page. Tome is built the same way.
Translating a book page is a solved problem. Translating a series is not.
A character is named in volume 1, nicknamed in volume 3, referred to by title in volume 5, and by volume 7 a naive page-by-page translator has given them four different names in the target language. The reader notices. The story breaks.
Tome treats the series as the unit of work: a series → volume → page model, an object store for the pages themselves, and a memory layer that is meant to carry a cast of characters across the whole run.
- 📚 Library - series, volumes, reading progress, per-series settings.
- 📥 Ingest - drop an archive of scans or a digital book; the format is read from magic bytes, not the file extension.
- 🔍 Translate - a vision path (page image in, translated regions and their positions out) and an OCR path that extracts text first.
- 🗂 Metadata - title search across keyless book catalogues in any language.
- 📖 Reader - each translation set over the block it replaces, or as a column beside the original; PDF export does the same.
- 🧠 Series memory - the characters, places and relations seen so far, with how each name is rendered, given to every page and limited to what was known by that page. Correct it from the series page.
- 📊 Consistency and cost - per volume: which names drifted from the glossary and where, and what the volume cost in calls, tokens and money.
- 🗃 Whole series, one click -
Process allqueues every unfinished volume in reading order. - 🤖 Librarian - an agent with 26 tools over the library that organises uploads, links metadata and repairs what went wrong instead of describing it.
- 📤 Export - visual PDF and EPUB.
Every page goes through one model call that carries the series context: the glossary, summaries of earlier volumes, and a graph of the characters, places and relationships seen so far. The same call returns what the page adds to that context, so each volume starts from what the earlier ones learned. Everything is scoped to the page being translated, so a volume 3 prompt never sees a volume 12 spoiler, and page 1 never sees page 40.
Any OpenAI-compatible endpoint works. Tome is built and tested against
Gemma 4 (gemma4:31b, model card,
Apache 2.0) through Ollama Cloud.
git clone https://github.com/computator1200/tome && cd tome
cp .env.example .env # endpoint, key, model
python -m venv venv && ./venv/bin/pip install -r backend/requirements.txt
cd frontend && npm install && npm run build && cd ..
cd backend && ../venv/bin/uvicorn main:app --host 127.0.0.1 --port 8077Open http://127.0.0.1:8077 and add a series. Running under a subpath, the local-OCR engine and the dev loop are covered in docs/ONBOARDING.md.
Works end to end: ingest a scan archive or a digital book, classify, OCR or vision, translate with page-scoped memory, read, check, export, and resume a stopped volume from the next unfinished page. 112 tests run on every push. What shipped, and the choices made on purpose, are in docs/ROADMAP.md.
| Architecture | layout, the pipeline stage by stage, the librarian, what ships |
| Graph memory | how the series memory works, with diagrams |
| Models and agent skill | Gemma 4, swapping models, the portable librarian skill |
| Deployment | systemd, a reverse proxy, the two subpath knobs, S3 storage |
| Roadmap | what shipped, and the choices made on purpose |
| Onboarding | where to start reading, the dev loop, traps |
| Changelog | what each release changed |
The same pages are on the wiki.
See CONTRIBUTING.md for setup, conventions, tests and the rules that have already cost an afternoon. If you are touching the translation pipeline, keep the rule that a bad page never takes down a volume.
MIT. See LICENSE.