Inspiration
Every one of our family's recurring fights is about the same small stuff and none of it is hard. The electricity bill gets paid three days late, so we eat a ₹ 180 late fee. The dentist appointment is remembered at 10:29 AM, one minute before it was supposed to start. The fridge has eggs and milk, and no bread. Again. The passport renewal is found a week after the deadline.
None of these tasks is complex - they fail because they all live in our heads, and a human head is a terrible database for things that recur quietly, every month, forever. And to-do apps don't fix that: a to-do list is passive, and only works if you remember to look at it. We wanted the opposite - something active. Something that listens when you mumble about a bill, remembers everything forever, notices the overdue gym payment before you do, and closes the loop itself so next month is already taken care of.
An everyday agent isn't a better list. It's a better memory, plus a better sense of urgency, plus a librarian who files the next cycle before you ask. That's what we built: LifePilot.
What it does
LifePilot is a local agent that handles the four kinds of everyday chaos you keep forgetting — bills, appointments, groceries, and life admin — and talks to you in plain English:
you> dentist appointment on friday at 4pm Appointment saved: dentist · Friday 18 Sep, 16:00
Proactive daily digest -> every run (or lp watch mode) surfaces overdue bills, today's appointments, and expiring tasks before anything else. Ranked suggestions -> an urgency-scoring brain answers "what should I do right now?" instead of dumping a flat list. Self-closing loops -> pay a recurring bill and the next month's cycle is auto-scheduled; finish a recurring task and the next one appears. Zero setup, full privacy -> pure Python stdlib, one local JSON file, no accounts, no cloud, no API keys.
How we built it
Three design principles came first: proactive over passive, zero setup, and one code path for both commands and chat — every sentence, whether typed as lp add bill ... or "add a bill", flows through the same intent parser onto the same data model.
Architecture - eight small modules:
when.py -> reads human dates/times/amounts (18th, next friday, 4pm, ₹1,200) parser.py -> keyword + pattern intent classification, fully offline models.py -> four typed records: Bill, Appointment, GroceryItem, Task storage.py -> atomic JSON persistence + recurrence rolling brain.py -> urgency scoring, digest construction, suggestions, budget cli.py + ui.py -> routing, chat loop, and colour-safe terminal rendering seeds.py + test_lifepilot.py -> demo "life" and a 9-test smoke suite The math of urgency. The brain ranks bills by lead time $\Delta = d_{due} - \text{today}$ with a piecewise urgency curve - steep near the deadline.
Recurring bills use clamped month arithmetic so the 31st never lands in a 30-day month and paying a bill rolls to the month after the cycle you just settled - not "today + 1 month".
We built spine-first: data layer -> language layer -> intelligence layer -> shell layer -> demo/tests, so every piece was testable before the next existed.
Challenges we ran into
"Pay it" vs "add it." electricity bill of 1200 due 18th records a bill; pay the electricity bill resolves one. Keyword matching alone misrouted them - fixed with verb-led disambiguation (payment verbs = settlement, otherwise = intake). The recurring-bill time-travel bug. Paying a bill before its due date re-dated it to the same cycle - it became "due again in 6 days". We traced it to rolling from today instead of from the current upcoming cycle, fixed the math, and locked it in with a regression test. "Purchases" that aren't groceries. get the car checked next Saturday at 10am is an appointment, but "get/check" smell like shopping. Single keywords kept failing; the fix was requiring a time plus a date or an event-word before classifying as an appointment. Demo duplication. Re-running demo doubled every record - invisible on the first run, fatal on the second. Fixed by making demo idempotent (reset-then-load). Talking to Windows. ₹, ·, crashed the console until we enabled ANSI/VT via ctypes and reconfigured stdout to UTF-8.
Accomplishments that we're proud of
It works with your words, not syntax. "pay the wifi bill" and lp "dentist on friday at 4" just work - date, time, currency and quantity all extracted from a single sentence. The agent closes its own loops. Pay a recurring bill and next month is already filed; you literally cannot "forget" it again. A real ranking brain. The urgency curve is transparent, hand-tuneable math - a judge can squint at overdue = 100+, due today = 80 and agree it makes sense. Zero dependencies, approximately 1,900 lines. The whole agent runs on the Python standard library. No install step, no cloud, no account - your data never leaves your machine. 9 automated tests pass covering parsing, recurrence math, digests, budget, persistence and the natural-language pay flow.
What we learned
An agent's personality is its state machine. "Proactive" isn't a mood - it's roll_recurring() before every read plus a ranking that re-decides after every input. That's what makes it feel alive. Parse the real world into types, once. Converging every input onto four typed records let flag-mode and chat-mode share one code path and killed a whole bug class. Ambiguity is a feature request. Every mis-parse (get the car checked) was a specification gap - writing the parser taught us more about requirements than about regex. Edge cases are the product. Day-of-month rollover, overdue clamping, next friday on a Friday - each is either a "wow" or a "why is it broken?" at demo time. Tests are the fastest way to build fast. Our two nastiest bugs only failed on second runs - precisely where live demos die. Constraints breed elegance. "No dependencies" forced us to make dates, persistence, ranking and UI fit the standard library, and the result is simpler to trust.
What's next for LifePilot
Calendar and notifications -- .ics export, desktop/SMS/email reminders driven by the same intent parser. Household mode -- assign bills and errands to people, share one store. Real connectors -- bank feeder APIs and Google Calendar behind the existing parser and brain (they won't change). Voice input and a tiny web dashboard for the less terminal-inclined. Smarter budgets -- rolling forecasts and spend alerts before, not after, you overshoot.

Log in or sign up for Devpost to join the conversation.