Files
digikedai-bot/docs/ARCHITECTURE.md
T

57 lines
2.6 KiB
Markdown

# 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)
1. Telegram `POST` → Hono webhook `POST /webhook/<secret>`.
2. grammY parses the update → `normalizeIncoming()``IncomingMessage`.
3. `db.saveExchange()` upserts user, opens/reuses conversation, stores the user message.
4. `Agent.respond()` builds system+business prompt (plus user-memory block when a summary exists), fetches recent history, calls LLM.
5. Reply persisted via `saveExchange()` (assistant role), returned to grammY → Telegram.
6. `Agent.updateMemoryAsync()` (fire-and-forget, never blocks the reply) writes `lang` + `last_queries` (FIFO-5) rule-based, and triggers the `MemoSummarizer` (cheap `chatSmall` call) when new facts appear → updated `summary` back into `user_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 reach `mem0-postgres` and `litellm` by container name.
- Production webhook must be HTTPS: `bot.digikedai.com` via the DSM CF-tunnel → Traefik → this container (routing added in a later step; see `docs/OPERATIONS.md`).
- PostgreSQL is never exposed publicly.