2.6 KiB
2.6 KiB
Architecture
Multi-channel AI messaging platform. Telegram is the first adapter, not the definition of the system.
Layering
CHANNEL LAYER
+-------+-------+-------+
|Telegram|Shopee |Lazada|
|adapter |adapter|adapter|
+-------+-------+-------+
|
APPLICATION CORE (channel-agnostic message contract)
|
+--------+--------+
| | |
AI/Agent n8n Tools (integrations)
| |
Memory PostgreSQL
| |
pgvector (Phase 3)
|
LLM APIs (LiteLLM → OpenAI/OpenRouter)
Responsibilities
| Layer | Owns | Must NOT own |
|---|---|---|
Channel adapter (src/channels/*) |
Native event parsing, platform formatting/IDs, buttons, webhook setup | Business rules, prompt construction, DB schema |
Application core (src/core) |
Normalized message contract, capabilities flags | Telegram-only assumptions |
AI layer (src/ai) |
Prompt assembly, agent orchestration, memory/retrieval interfaces | Platform transport |
DB (src/db) |
Users, conversations, messages, migration | Transient in-process state |
n8n (src/integrations/n8n) |
Automation/tool calls with schema validation | Core conversational state |
Data flow (one message)
- Telegram
POST→ Hono webhookPOST /webhook/<secret>. - grammY parses the update →
normalizeIncoming()→IncomingMessage. db.saveExchange()upserts user, opens/reuses conversation, stores the user message.Agent.respond()builds system+business prompt (plus user-memory block when a summary exists), fetches recent history, calls LLM.- Reply persisted via
saveExchange()(assistant role), returned to grammY → Telegram. Agent.updateMemoryAsync()(fire-and-forget, never blocks the reply) writeslang+last_queries(FIFO-5) rule-based, and triggers theMemoSummarizer(cheapchatSmallcall) when new facts appear → updatedsummaryback intouser_memory.
Key contracts
IncomingMessage/OutgoingMessage(src/core/messages.ts) — the single normalized shape every adapter translates to/from.ChannelCapabilities— flags (supportsButtons, etc.) so the core never assumes a feature exists on every channel.- Provider/retriever/memory interfaces — defined now, no-op until justified (Phases 2/3).
Networking
- The bot container joins the existing
mem0_net(external) to reachmem0-postgresandlitellmby container name. - Production webhook must be HTTPS:
bot.digikedai.comvia the DSM CF-tunnel → Traefik → this container (routing added in a later step; seedocs/OPERATIONS.md). - PostgreSQL is never exposed publicly.