← back to projects
aioperational
LifeOS — a self-hosted AI assistant
#ai#llm#self-hosted#automation
A personal AI assistant I'm building for myself: a FastAPI backend behind a Telegram bot and a small React web app, routing between a local Ollama model and OpenRouter depending on the task.
- ›Handles goals, calendar, and budget tracking through conversation, with voice input/output and Google Calendar integration.
- ›Self-hosted on a k3s cluster on Oracle Cloud, Terraform-provisioned with CI/CD deploying on every push to main — started as a WSL2 box at home, now kept running as a cold-standby rollback instead of being torn down.
- ›Custom domain (lifeos.michalzawadzki.dev) backed by a Terraform-managed Cloudflare DNS record — imported from a hand-created one into IaC rather than left undocumented, DNS-only/unproxied so cert-manager's HTTP-01 challenge and the app's SSE/voice streaming don't pick up an extra proxying layer.
- ›Routes per-request, not per-conversation: a local Ollama model handles transactional tool-calling (expenses, calendar, health logs), and a purpose-built redaction gateway strips household names before anything genuinely open-ended gets handed off to a cloud model.
- ›90 pytest tests and GitHub Actions CI cover the tool-dispatch table, the finance/calendar/health clients (mocked against real API responses), and the full session API — caught real bugs before they shipped, including a units mismatch that inflated a day's tracked calories by 7x.
- ›Health data syncs itself: an iPhone automation (Health Auto Export) pushes a JSON payload to a bearer-token-gated endpoint whenever new data lands, parsed into daily metrics and workouts so the model can pull it into a morning/evening brief or answer "how was my week" on demand — no manual export step.
- ›Security is scoped deliberately, not bolted on: Google OAuth behind an email allow-list with a signed session cookie, a constant-time bearer-token check gating the one webhook exposed on the public tunnel (the health sync endpoint above), a redaction gateway with its own test suite, and the DB admin UI (Adminer) bound to localhost only, never routed through the tunnel.
Screenshots
Desktop
Mobile
Working on something similar? I'd like to hear about it
collaborate →