A Telegram-based AI assistant ("Labbu") for managing a Namkeen (Indian snack) factory's books: sales ledger, customer-credit tracking, production log, and cash flow — operated in Hindi / Hinglish / English.
| Aspect | Value |
|---|---|
| User | Factory owner's father (non-English speaker) |
| Interface | Telegram (text; voice planned) |
| LLM | Gemini → Groq → Cerebras fallback chain (Groq is the workhorse) |
| Data | PostgreSQL on Supabase |
| Deployment | Fly.io (free, always-on, Mumbai region) |
- Sales — each shop's purchases (qty, rate, paid/credited)
- Customer credit — outstanding balance per shop
- Production — daily output
- Cash flow — all cash in/out (paid sales & payments auto-generated by DB triggers)
- Parse → Confirm → Write — every write shows an inline
[✅][❌]card before the DB is touched. LLMs misparse; the user approves first. - Fuzzy customer matching — "Sharma" → "Sharma Namkeen"; ambiguous matches show a numbered picker.
- Audit trail — every write stores the original message, timestamp, and user.
- Soft deletes — recoverable; views auto-exclude deleted rows.
- Bounded, in-memory sessions — TTL cache + per-user rate limiting.
- Retried DB calls — transient connection errors back off and retry.
python -m venv venv
venv\Scripts\activate # Windows (source venv/bin/activate on macOS/Linux)
pip install -e ".[dev]"
cp config/.env.example .env # fill in GROQ_API_KEY, TELEGRAM_BOT_TOKEN, SUPABASE_URL, SUPABASE_KEY
# Run database/schema.sql in the Supabase SQL editor
python main.pyFull walkthrough — local setup, Fly.io deploy, and secret safety — is in docs/DEPLOYMENT.md. Read the secret-safety section before deploying.
python -m pytest # 137 tests, ~2s; Groq + Supabase mocked, no networkDependency order (top imports bottom):
config → utils → db → tools → providers → pending → session → agent → bot → main
The package map and dependency diagram live in
src/__init__.py. For the full design — the
Parse→Confirm→Write mechanism, the 17 tools, the provider fallback, and the data
model — see docs/ARCHITECTURE.md.
- docs/ARCHITECTURE.md — design, data flow, tools, schema summary, and the safety model.
- docs/DEPLOYMENT.md — local setup, Fly.io deploy, secret safety.
database/schema.sql— the authoritative DB schema (7 tables, 2 views, 2 triggers).
.
├── README.md # this file
├── main.py # entry point — DB ping, build app, run polling
├── pyproject.toml # metadata + ruff/pyright/pytest config
├── fly.toml # Fly.io config (no secrets)
├── config/.env.example # env var template
├── database/schema.sql # PostgreSQL DDL (tables, views, triggers)
├── deploy/Dockerfile # container image
├── docs/ # ARCHITECTURE.md, DEPLOYMENT.md
├── prompts/ # system_prompt.md, tool_descriptions.md, ui_strings/
├── src/ # application code (see src/__init__.py for the map)
└── tests/ # pytest suite (mocked Groq + Supabase)
- Raw Python agent loop, not LangChain/CrewAI — transparency and control over the confirm-before-write flow, without framework abstraction.
- Supabase, not SQLite — cloud-accessible from the bot, multi-user-ready, free tier, automatic backups.
- Parse → Confirm → Write — LLMs hallucinate; "50 kg" must never silently become "500 kg" in the ledger.
- Customer by ID, fuzzy-matched — "Sharma" / "Sharma Namkeen" / "Sharma wale"
are one customer; resolve to a single ID via
search_customer. - Cash flow, not just expenses — captures both directions for a full picture; paid sales and payments are auto-logged by DB triggers.
- v1 — shipped · all four ledgers, confirm-before-write, fuzzy matching, audit trail, soft deletes, Fly.io deploy.
- v1.1 — shipped · multi-provider LLM fallback, bounded TTL sessions, per-user rate limiting, retried DB calls, structured logging.
- v1.2 — next · per-user data isolation (reads currently aren't scoped by user; a second Telegram user could see the owner's ledger).
- v2 · voice messages (Whisper → text → same pipeline).
- v3 · daily summaries, credit-limit alerts, scheduled reports.
- v4 · PDF/CSV exports, admin audit views.
- Logs — stdout (
fly logs). SDK loggers are silenced so the bot token never appears; see docs/DEPLOYMENT.md §3. - Audit — query the
audit_logtable in Supabase to see every parsed write. - Recovery — soft-deleted rows (
is_deleted = TRUE) are restorable with a singleUPDATE; see docs/ARCHITECTURE.md §7.