7 documents covering stack, integrations, architecture, structure, conventions, testing, and concerns.
173 lines
8 KiB
Markdown
173 lines
8 KiB
Markdown
# External Integrations
|
||
|
||
**Analysis Date:** 2026-04-01
|
||
|
||
## Bot Platform APIs
|
||
|
||
**Telegram Bot API:**
|
||
- Purpose: Primary messaging surface for user ↔ Lambda agent interaction
|
||
- Client library: `aiogram` 3.26.0 (async, wraps Telegram Bot API v7+)
|
||
- Authentication: Bot token via `TELEGRAM_BOT_TOKEN`
|
||
- Entry point: `adapter/telegram/bot.py` (planned; aiogram worktree branch `feat/telegram-adapter`)
|
||
- Transport: Long-polling or webhook (aiogram supports both; mode not yet locked in)
|
||
- Bot API docs: https://core.telegram.org/bots/api
|
||
|
||
**Matrix Client-Server API:**
|
||
- Purpose: Secondary messaging surface (Matrix/Element clients)
|
||
- Client library: `matrix-nio` 0.25.2 (async)
|
||
- Authentication: password login or pre-existing access token (`MATRIX_ACCESS_TOKEN`)
|
||
- Login flow in `adapter/matrix/bot.py` `main()`:
|
||
- If `MATRIX_ACCESS_TOKEN` is set → assigned directly to `client.access_token`
|
||
- Else if `MATRIX_PASSWORD` is set → `client.login(password=..., device_name="surfaces-bot")`
|
||
- Sync method: `client.sync_forever(timeout=30000)` (30-second long-poll)
|
||
- E2EE store: nio file-based store at path from `MATRIX_STORE_PATH` (default: `"matrix_store"`)
|
||
- Matrix C-S API docs: https://spec.matrix.org/latest/client-server-api/
|
||
|
||
### Matrix Room Model
|
||
|
||
Rooms are mapped to Lambda chat slots (C1, C2, C3…) via `adapter/matrix/room_router.py`:
|
||
- First message in a room → assigns next chat ID (C1, C2, …) and persists mapping to store
|
||
- Room metadata stored under key `matrix_room:<room_id>` in `StateStore`
|
||
- User metadata (next chat index) stored under `matrix_user:<matrix_user_id>`
|
||
|
||
### Matrix Event Types Handled
|
||
|
||
| nio Event Class | Handler | Action |
|
||
|--------------------|-----------------------------|-------------------------------|
|
||
| `RoomMessageText` | `MatrixBot.on_room_message` | Dispatch to `EventDispatcher` |
|
||
| `ReactionEvent` | `MatrixBot.on_reaction` | Button confirmation / skill toggle |
|
||
| `InviteMemberEvent`| `MatrixBot.on_member` | Accept room invite |
|
||
| `RoomMemberEvent` | `MatrixBot.on_member` | Membership change handling |
|
||
|
||
## Lambda Platform (Internal SDK)
|
||
|
||
**Purpose:** AI agent backend — processes user messages, manages user accounts, returns responses
|
||
|
||
**Interface:** `sdk/interface.py` — `PlatformClient` Protocol
|
||
|
||
**Current Implementation:** `sdk/mock.py` — `MockPlatformClient`
|
||
- Simulates network latency (10–80 ms default, 200–600 ms for message calls)
|
||
- In-process in-memory state (users, messages, settings dicts)
|
||
- Supports webhook simulation via `simulate_agent_event()`
|
||
|
||
**Production Integration (future):**
|
||
- URL: `LAMBDA_PLATFORM_URL` (default: `http://localhost:8000`)
|
||
- Auth: `LAMBDA_SERVICE_TOKEN` (bearer token)
|
||
- Mode switch: `PLATFORM_MODE=mock` vs `PLATFORM_MODE=production`
|
||
- Swap path: replace `sdk/mock.py` only; no changes to `core/` or `adapter/`
|
||
|
||
**Platform API Methods (from `sdk/interface.py`):**
|
||
|
||
```python
|
||
async def get_or_create_user(external_id, platform, display_name) -> User
|
||
async def send_message(user_id, chat_id, text, attachments) -> MessageResponse
|
||
async def stream_message(user_id, chat_id, text, attachments) -> AsyncIterator[MessageChunk]
|
||
async def get_settings(user_id) -> UserSettings
|
||
async def update_settings(user_id, action) -> None
|
||
```
|
||
|
||
**Webhook / Push (outbound from platform → bot):**
|
||
- Interface: `WebhookReceiver` Protocol (`sdk/interface.py`)
|
||
- Registration: `MockPlatformClient.register_webhook_receiver(receiver)`
|
||
- Event types: `task_done`, `task_error`, `task_progress` (modelled in `AgentEvent`)
|
||
- Production implementation not yet wired; mock supports `simulate_agent_event()` for testing
|
||
|
||
## Data Storage
|
||
|
||
**Databases:**
|
||
|
||
*SQLite (primary persistence):*
|
||
- Client: stdlib `sqlite3` (synchronous, called from async code without `asyncio.to_thread`)
|
||
- Schema: single key-value table: `kv (key TEXT PRIMARY KEY, value TEXT NOT NULL)`
|
||
- JSON serialization for values (`json.dumps` / `json.loads`)
|
||
- Matrix bot DB path: `MATRIX_DB_PATH` (default: `"lambda_matrix.db"`)
|
||
- Telegram bot DB path: implicit `"lambda_bot.db"` (file present in repo root — development artifact)
|
||
- Implementation: `core/store.py` `SQLiteStore`
|
||
|
||
*In-Memory (testing / development):*
|
||
- `InMemoryStore` — plain Python dict, no persistence across restarts
|
||
- `MockPlatformClient` internal state — also in-memory dicts
|
||
|
||
**File Storage:**
|
||
- Matrix nio E2EE store: local filesystem directory at `MATRIX_STORE_PATH` (default: `"matrix_store/"`)
|
||
- No object storage (S3/GCS/etc.) currently; mock client has `attachment_mode` flag (`"url"` | `"binary"` | `"s3"`) reserved for future real SDK
|
||
|
||
**Caching:**
|
||
- None — no Redis or external cache layer
|
||
|
||
## Authentication & Identity
|
||
|
||
**Telegram Auth:**
|
||
- Bot token → passed to aiogram dispatcher at startup
|
||
- User identity: Telegram user ID mapped to platform `external_id`
|
||
|
||
**Matrix Auth:**
|
||
- Password or access token (see above)
|
||
- User identity: Matrix user ID (e.g. `@user:matrix.org`) mapped to platform `external_id`
|
||
|
||
**Lambda Platform User Identity:**
|
||
- `get_or_create_user(external_id, platform)` → returns `User` with internal `user_id`
|
||
- External IDs are platform-prefixed in mock: `"{platform}:{external_id}"`
|
||
|
||
## Monitoring & Observability
|
||
|
||
**Logging:**
|
||
- `structlog` 25.5.0 — structured logging (key=value pairs)
|
||
- Logger instantiation: `structlog.get_logger(__name__)` in each module
|
||
- Log calls use keyword arguments: `logger.info("event_name", key=value, ...)`
|
||
- No log shipping / aggregation configured (local stdout only)
|
||
|
||
**Error Tracking:**
|
||
- None — no Sentry, Datadog, or similar integration
|
||
|
||
**Metrics:**
|
||
- None — `MockPlatformClient.get_stats()` returns basic in-memory counters (not exported)
|
||
|
||
## CI/CD & Deployment
|
||
|
||
**Hosting:**
|
||
- Not specified — no Dockerfile, docker-compose, or cloud config files present
|
||
|
||
**CI Pipeline:**
|
||
- None detected — no `.github/workflows/`, `.gitlab-ci.yml`, etc.
|
||
|
||
## Environment Configuration
|
||
|
||
**Required variables (from `.env.example`):**
|
||
|
||
| Variable | Required | Default | Purpose |
|
||
|-----------------------|----------|--------------------|--------------------------------------|
|
||
| `TELEGRAM_BOT_TOKEN` | Yes* | — | Telegram Bot API token |
|
||
| `MATRIX_HOMESERVER` | Yes* | — | Matrix homeserver URL (e.g. `https://matrix.org`) |
|
||
| `MATRIX_USER_ID` | Yes* | — | Bot's Matrix user ID |
|
||
| `MATRIX_PASSWORD` | Cond. | — | Login password (if no access token) |
|
||
| `MATRIX_ACCESS_TOKEN` | Cond. | — | Pre-issued access token (preferred) |
|
||
| `MATRIX_DEVICE_ID` | No | `""` | Matrix device ID |
|
||
| `MATRIX_DB_PATH` | No | `"lambda_matrix.db"` | SQLite DB file path (Matrix bot) |
|
||
| `MATRIX_STORE_PATH` | No | `"matrix_store"` | nio E2EE store directory |
|
||
| `LAMBDA_PLATFORM_URL` | No** | `http://localhost:8000` | Lambda platform base URL |
|
||
| `LAMBDA_SERVICE_TOKEN`| No** | — | Service auth token for Lambda API |
|
||
| `PLATFORM_MODE` | No | `"mock"` | `"mock"` or `"production"` |
|
||
|
||
\* Required for the respective bot to function.
|
||
\*\* Only required when `PLATFORM_MODE=production`.
|
||
|
||
**Secrets location:**
|
||
- `.env` file (gitignored)
|
||
- Never committed — `.env.example` provides template
|
||
- Loaded via `python-dotenv` at module import in each `bot.py` entry point
|
||
|
||
## Webhooks & Callbacks
|
||
|
||
**Incoming (platform → bot):**
|
||
- `WebhookReceiver.on_agent_event(event: AgentEvent)` — receives async task completion notifications
|
||
- Not yet wired to an HTTP endpoint; `MockPlatformClient.simulate_agent_event()` used for testing
|
||
|
||
**Outgoing (bot → external):**
|
||
- Telegram: all via `aiogram` polling or webhook (no direct outbound HTTP beyond Telegram API)
|
||
- Matrix: all via `matrix-nio` `AsyncClient.room_send()`, `room_typing()`, etc.
|
||
- Platform: via `PlatformClient` send/stream methods
|
||
|
||
---
|
||
|
||
*Integration audit: 2026-04-01*
|