Skip to content

Repository files navigation

LifeOS

A self-hosted personal organiser you talk to. Say "gym Monday, Wednesday and Friday at three, and remind me to call the dentist tomorrow" and a language model running on your own hardware turns it into tasks, events, journal entries, expenses, weigh-ins and meals. Anything it is sure about happens straight away and can be undone. Anything ambiguous waits as a card you approve, edit or throw out. Reminders reach your phone with the app closed.

LifeOS Today on a phone: the day's heading, a card proposing an event with Edit, Approve and Dismiss, a card asking which event to move, and the capture bar under the tab bar LifeOS Today on a desktop: the rail down the left, the same two cards in the reading column, spending, weight and a logging streak in the aside, and the day's schedule below

There is no chat window, no web search and no memory beyond your own data. The model reads what you said and proposes rows; the app checks every one of them before anything is written, and each card quotes the words it came from.

It runs on one machine, for one person, out of a single SQLite file. Nothing leaves the box except what you point it at.

How it works

voice ──▶ faster-whisper ──▶ transcript ─┐
                                         ├─▶ extraction (your model) ──▶ actions
typed text ──────────────────────────────┘                                 │
                                                ┌──────────────────────────┴──────┐
                                                ▼                                 ▼
                                     execute → database                  confirm → a card
                                     (always undoable)                   (approve / edit / dismiss)
                                                │
                                                ▼
                              reminders: WebSocket · Web Push · Google Calendar

The extraction prompt (prompts/extract_v1.md) asks for JSON under a schema the model server enforces. Python then validates every action by type: dates have to parse, recurrence rules have to be legal, categories have to come from your own list, required fields have to be present. Anything that fails becomes a confirmation card carrying the reason instead of a row in the database. A 93-case regression suite guards the prompt, and a harness runs that suite against any model so you can see how it does before trusting it with your notes.

What is in it

Area
Today what needs a look, what is next, open tasks, the month's spend, your weight, the week's consistency
Life tasks, recurring events (RRULE, with DST handled by the zone), a rolling agenda, a journal with mood and tags
Money expenses in a closed category vocabulary, standing and monthly budgets, income, transfers, savings goals with pace, month-by-month history
Health weigh-ins with trend, weight goals, calories in (a bundled USDA subset plus your own presets), calories out (a MET table plus your own activities), the day's energy balance
Reminders a durable ledger with three senders: the open app, Web Push to the installed phone app, and an optional Google Calendar projection
The app installable PWA, phone and desktop layouts, four accents in dark and light, search, a skippable first-run setup, edit wherever approve exists

Requirements

  • Python 3.11 or 3.12. Not 3.13 yet: CTranslate2 has no wheels for it.
  • An OpenAI-compatible chat endpoint. llama-server, LM Studio, Ollama, vLLM or a hosted API. The reference model is Qwen3.8-27B at Q8, which wants roughly 30 GB of VRAM. Its results ship as the baseline, and the harness will tell you what a smaller model gives up.
  • Speech-to-text needs nothing extra. faster-whisper runs on CPU, and an NVIDIA GPU makes it quick. Typing works as well as talking, so you can skip voice entirely.
  • HTTPS if you want it on your phone. Browsers only expose the microphone and allow an installable app on a secure origin. One tailscale serve command is the documented route; any reverse proxy with a certificate does the same job.
  • No Node required. The built web app ships in the repository.

Quick start

git clone https://github.com/Inovello/lifeos.git && cd lifeos/backend
python -m venv .venv && . .venv/bin/activate      # Windows: .venv\Scripts\Activate.ps1
pip install -e .
python -m alembic upgrade head
cp ../config.local.example.yaml ../config.local.yaml   # then set timezone, token, model endpoint
python -m lifeos.main

Open http://127.0.0.1:8080, enter the token, and type a note. docs/setup.md covers the rest, including how to reach it from a phone and how to run it as a service.

Trying a different model

lifeos-harness serve

That opens a page on http://127.0.0.1:8090. Give it an endpoint and a model name, run the 93 cases (roughly ten minutes on a 27B model, less on a small one), and read what the model actually produced next to what the case expected. Any run can be compared against the saved baseline.

Strict APIs reject the extra sampling fields llama.cpp accepts, so those need the openai compat profile. An HTTP 400 on the very first case is usually that rather than the model. See docs/harness.md.

Security

Read SECURITY.md before you expose the app beyond your own computer. In short: there is one shared token, the app binds to loopback until you open it, and it refuses to listen on the network without a token set. Your notes travel to whatever llm.base_url points at, so that choice is yours to make deliberately. Nothing the model returns is trusted; it is validated first and stays reversible afterwards.

Layout

config.yaml                  every key, documented; overlay it rather than edit it
config.local.example.yaml    copy to config.local.yaml (gitignored)
prompts/                     the extraction prompt, versioned
backend/lifeos/              FastAPI + SQLAlchemy + faster-whisper
  api/                       routes
  pipeline/                  audio → transcript → actions → database
  services/                  LLM client, extraction + validation, executors,
                             reminders, Google Calendar, Web Push
  harness/                   the model qualification harness and its cases
  alembic/                   migrations
frontend/                    Vite + React + TypeScript + Tailwind; dist/ is committed
tests/                       unit, API, live-LLM and acceptance suites
scripts/                     deploy, publish
docs/                        setup, deploy, harness, engineering notes

Tests and gates

backend/.venv/bin/python -m pytest -q -m "not live_llm and not live_stt and not live_gcal"
backend/.venv/bin/python -m ruff check backend tests
cd frontend && npm test && npx tsc --noEmit

The live_llm tests run the extraction suite against your configured endpoint and skip with a reason when it is unreachable. The phone verifier (frontend/scripts/verify-record-mobile.mjs) walks every surface at 390 px with a touch profile, populated, in both themes. Every check in it was made to fail on purpose before it was allowed to count, which docs/engineering.md explains along with the rest of what building this cost.

Documents

License

LifeOS is free software under the GNU Affero General Public License, version 3 or later. Running it for yourself carries no obligation to anyone, whether you have modified it or not. The Affero clause only applies if you modify LifeOS and then let other people use your modified version over a network: those users have to be able to get your changes under the same licence.

Bundled third-party material and the licences of every dependency are listed in NOTICE. The fonts are under the SIL Open Font License and the USDA FoodData Central subset is public domain.

About

Self-hosted personal organiser you talk to. Voice or typed notes become tasks, events, spending and health entries via a local LLM. Nothing leaves your machine.

Resources

Security policy

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages