Compare commits
No commits in common. "8099f210d1e003e35aa706ac300ac19db64fa61c" and "5cf5ffad8b32d164070d0a92bd4e02d84bedd4b7" have entirely different histories.
8099f210d1
...
5cf5ffad8b
1 changed files with 0 additions and 113 deletions
|
|
@ -1,113 +0,0 @@
|
||||||
# Modul-26-Telegram-Gateway
|
|
||||||
|
|
||||||
**Status:** FREIGEGEBEN (2026-08-21)
|
|
||||||
**Port:** 55026 (nur Docker-intern, kein öffentlicher Port)
|
|
||||||
**Container:** `Modul-26-Telegram-Gateway`
|
|
||||||
**Image:** `telegram-gateway:0.1.0`
|
|
||||||
**Netzwerk:** `trading-modules`
|
|
||||||
|
|
||||||
## Zweck
|
|
||||||
|
|
||||||
Dünner, **tool-loser** Adapter zwischen Telegram und M17 Hermes-Agent. Ermöglicht die Bedienung von Hermes vom Handy über einen eigenen Telegram-Bot. **KEINE Trading-Tools**, kein M09/M07/M08/M15-Control-Zugriff. Safety bleibt deterministisch in M17.
|
|
||||||
|
|
||||||
## Architektur
|
|
||||||
|
|
||||||
```
|
|
||||||
Telegram Bot API
|
|
||||||
│ Polling (getUpdates) — KEIN Webhook, kein öffentlicher Port
|
|
||||||
▼
|
|
||||||
Modul-26-Telegram-Gateway (Port 55026 intern)
|
|
||||||
│ Auth-Allowlist, Rate-Limit, Audit — NUR HTTP-Calls an M17, KEINE Tools
|
|
||||||
▼
|
|
||||||
Modul-17-Hermes-Agent (POST /tasks llm=true)
|
|
||||||
│ Tool-Whitelist + Task-Gates (deterministisch, UNVERÄNDERT)
|
|
||||||
▼
|
|
||||||
LLM (Cloud deepseek-v4-flash:cloud Standard / Local llama3.1:8b explizit)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Sicherheitsmodell
|
|
||||||
|
|
||||||
- **Allowlist:** Nur explizit erlaubte User-/Chat-IDs (`TELEGRAM_ALLOWED_IDS`, kommagetrennt). Unbekannte User werden **hart abgelehnt** (kein Task, Log-Eintrag, Status `REJECTED`/`UNAUTHORIZED`).
|
|
||||||
- **Rate-Limit:** Sliding-Window pro User/Chat (Default 10/min). Überschreitung → `REJECTED`/`RATE_LIMITED`.
|
|
||||||
- **Idempotenz:** `update_id` als PK in `telegram_message`. Bereits verarbeitete Updates werden übersprungen.
|
|
||||||
- **Secrets:** Bot-Token NUR via ENV/Secret (`TELEGRAM_BOT_TOKEN`), nie im Code. Keine Secrets in DB/Logs/Doku.
|
|
||||||
- **Prompt-Injection:** M17 behandelt externe Eingaben als untrusted data. Tool-Whitelist + Task-Gates hart im Code.
|
|
||||||
- **Doppelte Barriere:** Gateway ist tool-los (nur HTTP-Calls an M17) + M17-Whitelist deterministisch.
|
|
||||||
|
|
||||||
## Commands
|
|
||||||
|
|
||||||
| Command | M17 task_type | Beschreibung |
|
|
||||||
|---------|---------------|--------------|
|
|
||||||
| `/status` | — | Hermes-Health (synchron) |
|
|
||||||
| `/research` | research | Markt-/Regime-Analyse |
|
|
||||||
| `/analytics` | analytics | Portfolio-/Strategie-Analyse |
|
|
||||||
| `/backtest` | backtest | Backtest starten |
|
|
||||||
| `/optimize` | optimization | Optimierung starten |
|
|
||||||
| `/monitoring` | monitoring | Monitoring-Status |
|
|
||||||
| `/tasks` | — | Letzte Tasks (synchron) |
|
|
||||||
| `/help` | — | Hilfe |
|
|
||||||
| Freitext | research | Wird als Research-Analyse behandelt |
|
|
||||||
|
|
||||||
## Asynchrone Task-Abwicklung
|
|
||||||
|
|
||||||
Lange Tasks (Cloud 5-23s, explizit lokale Analyse bis zu Minuten) laufen asynchron:
|
|
||||||
1. Sofortige Bestätigung an denselben Chat ("⏳ *task* gestartet…").
|
|
||||||
2. Task wird in Background-Thread an M17 gesendet (`POST /tasks` mit `llm=true`).
|
|
||||||
3. Ergebnis wird später an denselben Chat zurückgesendet.
|
|
||||||
|
|
||||||
### Ergebnis-/Fehlerbehandlung
|
|
||||||
|
|
||||||
- **SUCCEEDED:** M26 sendet die finale Hermes-Analyse (`analysis`) + kompakte Tool-Liste. Tool-Fehler (z.B. 404/keine Marktdaten) **brechen den Flow nicht ab** — die finale Analyse mit Einschränkungen wird trotzdem verständlich an Telegram gesendet, einzelne Tools als `[FAILED]` gelistet.
|
|
||||||
- **FAILED:** M26 sendet eine **klare Fehlermeldung** (`🔴 *task* fehlgeschlagen (Status: FAILED)` + Fehlercode + Details) — NICHT irreführend "✅ abgeschlossen".
|
|
||||||
|
|
||||||
## Audit
|
|
||||||
|
|
||||||
DB-Tabelle `telegram_message` (Migration `001_telegram_gateway.sql`):
|
|
||||||
- `update_id` (PK), `chat_id`, `user_id`, `username`, `text`, `command`
|
|
||||||
- `task_id`, `run_id`, `status`, `error_code`, `created_at`
|
|
||||||
|
|
||||||
Nachvollziehbarkeit: **update_id → task_id → run_id → LLM-run → Tool-Calls** (via M17 hermes_llm_run + hermes_tool_call).
|
|
||||||
|
|
||||||
## API (Port 55026 intern)
|
|
||||||
|
|
||||||
- `GET /health` — Liveness
|
|
||||||
- `GET /health/ready` — Readiness (Telegram-Token + Allowlist)
|
|
||||||
- `GET /messages/recent` — Letzte Messages (Audit)
|
|
||||||
- `GET /messages/{update_id}` — Einzelne Message
|
|
||||||
- `POST /messages/test` — Test-Nachricht an konfigurierte Destination
|
|
||||||
|
|
||||||
## Konfiguration (ENV)
|
|
||||||
|
|
||||||
| Variable | Beschreibung |
|
|
||||||
|----------|--------------|
|
|
||||||
| `TELEGRAM_BOT_TOKEN` | Bot-Token (Secret, NUR ENV) |
|
|
||||||
| `TELEGRAM_ALLOWED_IDS` | Kommagetrennte erlaubte User-/Chat-IDs |
|
|
||||||
| `TELEGRAM_API_BASE` | Telegram API-Base (Default `https://api.telegram.org`; für E2E Fake-Server) |
|
|
||||||
| `M17_BASE_URL` | M17 Hermes-Agent (Default `http://Modul-17-Hermes-Agent:55017`) |
|
|
||||||
| `PG_HOST/PORT/USER/PASSWORD/DB` | PostgreSQL (Modul-01) |
|
|
||||||
|
|
||||||
## E2E-Tests
|
|
||||||
|
|
||||||
`tests/e2e_m26.py` (20/20 grün, 2026-08-21):
|
|
||||||
1. Unknown user reject
|
|
||||||
2. /status
|
|
||||||
3. /research (+ Ergebnis)
|
|
||||||
4. /analytics (+ Ergebnis)
|
|
||||||
5. /backtest (+ Ergebnis)
|
|
||||||
6. /optimize (+ Ergebnis)
|
|
||||||
7. /monitoring (+ Ergebnis)
|
|
||||||
8. /tasks
|
|
||||||
9. /help
|
|
||||||
10. Freitext → research (+ Ergebnis)
|
|
||||||
11. Safety: place_order im Prompt → keine Order
|
|
||||||
12. Rate-Limit
|
|
||||||
13. Audit: update_id → task_id → run_id
|
|
||||||
|
|
||||||
Test-Infrastruktur: `tests/fake_telegram.py` (Fake-Telegram Bot API Server mit Steuer-API für E2E).
|
|
||||||
|
|
||||||
## Wichtige Hinweise
|
|
||||||
|
|
||||||
- **M20 bleibt reserviert für Universe-Scheduler** — M26 ist separat.
|
|
||||||
- **M14 NICHT verändern** — M26 nutzt nur das FAIL-SAFE-Muster als Vorlage, koppelt nicht an M14.
|
|
||||||
- **M17 Safety-Gates unverändert** — M26 fügt nur einen dünnen Adapter hinzu.
|
|
||||||
- **Kein öffentlicher Port** — nur `expose` im Compose.
|
|
||||||
Loading…
Reference in a new issue