feat(bot): unified topic processor replacing router+interpreter stack

Replace 3-layer architecture (gpt-5-nano router + gpt-4o-mini interpreter) with
single unified topic processor (gpt-4o-mini) for simplified message handling.

New components:
- HouseholdContextCache: TTL-based caching (5 min) for household config data
- TopicProcessor: Unified classification + parsing with structured JSON output

Key changes:
- Renamed ASSISTANT_ROUTER_MODEL → TOPIC_PROCESSOR_MODEL
- Added TOPIC_PROCESSOR_TIMEOUT_MS (default 10s)
- Refactored save() → saveWithInterpretation() for pre-parsed interpretations
- Removed deprecated createOpenAiTopicMessageRouter and ~300 lines legacy code
- Fixed typing indicator to only start when needed (purchase routes)
- Fixed amount formatting: convert minor units to major for rawText

Routes: silent, chat_reply, purchase, purchase_clarification, payment,
payment_clarification, topic_helper, dismiss_workflow

All 212 bot tests pass. Typecheck, lint, format, build clean.
This commit is contained in:
2026-03-14 13:33:57 +04:00
parent 9c3bb100e3
commit f38ee499ae
14 changed files with 1554 additions and 854 deletions

View File

@@ -11,7 +11,7 @@ This is not a toy Telegram bot repo with a thin webhook and some string parsing.
- deterministic money-safe settlement logic with integer minor-unit math
- a hexagonal TypeScript monorepo with explicit domain / application / ports / adapter boundaries
- real operational concerns: idempotency, onboarding flows, localized UX, bot topic setup, reminder scheduling, Terraform-managed infrastructure
- a layered LLM architecture: a cheap first-pass topic router (`gpt-5-nano`) decides whether to stay silent, reply lightly, continue a workflow, or invoke a heavier helper
- a unified topic processor (`gpt-4o-mini`) that classifies messages and extracts structured data in a single LLM call
- a product that mixes structured command flows with LLM-assisted parsing while keeping writes deterministic
## Current Product Scope
@@ -139,7 +139,7 @@ For a fuller setup walkthrough, see the [development setup runbook](docs/runbook
Some product choices here are intentional:
- LLMs help interpret messy purchase/payment phrasing, but final writes are still explicit, structured, and confirmable.
- The bot uses a separate first-pass AI router, defaulting to `gpt-5-nano`, to classify topic messages before invoking the fuller assistant or parser models. That keeps casual chatter, jokes, and ambiguous messages from unnecessarily hitting heavier paths, while still letting the bot respond naturally when it is directly addressed.
- The bot uses a unified topic processor (`gpt-4o-mini`) that classifies messages and extracts purchase/payment data in a single call. This simplifies the architecture while keeping casual chatter from hitting heavier paths.
- Topic-specific ingestion stays separate from the general assistant so finance actions do not degrade into vague chat behavior.
- Telegram UX is treated as a real product surface: onboarding, confirmation buttons, topic setup, tagged replies, and localization are part of the design, not afterthoughts.
- Infra is versioned alongside the app so deployability, alerts, and runtime configuration are reviewable in the same repo.