SilverElixir commited on
Commit
fc948fd
·
unverified ·
1 Parent(s): df00367

Add files via upload

Browse files
Files changed (1) hide show
  1. README.md +22 -22
README.md CHANGED
@@ -13,25 +13,25 @@ A Telegram bot built to match Claude's tone and capabilities as closely as possi
13
 
14
  **Stack:** Python 3.13 · aiogram · FastAPI · google-genai · Docker
15
 
16
- > The YAML block above is Hugging Face Space metadata, not a mistake — this same `README.md` doubles as the Space card. Everything below it is normal GitHub documentation.
17
 
18
  ## Features
19
 
20
- - **Automatic model routing** — no `/model` command. Every message is routed to whichever provider actually has what it needs: web search and link reading go to Gemini, everything else defaults to free OpenRouter models to protect Gemini's tight daily quota.
21
- - **Streaming replies** with a self-calibrating typing-speed pacer, so answers appear to type themselves instead of landing in a few large chunks.
22
- - **Prompt-injection and identity-leak defenses** — a deterministic input filter plus output scrubbers keep the bot from revealing which model or provider is actually behind it.
23
- - **TikTok downloader** — videos, slideshows (including "live" photo slides), and original sound, without watermarks.
24
- - **Image generation** via Pollinations.ai, with the model auto-picked from the prompt (anime, fantasy, realism, quick sketch, or a general default).
25
- - **Text-to-speech** — Fish Audio first, Gemini TTS as a fallback chain.
26
- - `/draw` and `/tts` also work as plain phrases at the start of a message ("draw a cat", "read this out loud") — no slash required.
27
- - **Persistent state** — optional Upstash Redis backend, so chat history and quota counters survive redeploys.
28
- - **Error tracking** — optional Sentry integration, with secrets scrubbed before every event is sent.
29
 
30
  ## How it works
31
 
32
- Lumen is a single FastAPI + aiogram service. Telegram delivers updates to a webhook; each message is routed to a chain of candidate models (Gemini and/or OpenRouter) built on the fly from the message's content — attachments, links, and a couple of lightweight heuristics for "does this need current information" and "is this a heavy request." The first provider that answers wins; the other is tried as a fallback if its whole chain fails.
33
 
34
- The codebase is a modular monolith: `bot.py` is the orchestrator, and the rest is split into focused modules — `lumen_router_config.py` (model routing), `lumen_formatting.py` (markdown → Telegram HTML), `lumen_security.py` (injection/leak defenses), `lumen_images.py`, `lumen_tts.py`, `lumen_tiktok.py`, `lumen_telegram_transport.py`, `lumen_state_storage.py`, `lumen_typing_pace.py`.
35
 
36
  See **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** for a deeper look at routing, streaming, the security layers, and the TikTok downloader.
37
 
@@ -50,11 +50,11 @@ See **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** for a deeper look at routin
50
  curl -H "Authorization: Bearer <BOT_TOKEN>" https://<space-host>/admin_keys
51
  ```
52
 
53
- Hugging Face Spaces' outbound IPs are blocked by Telegram's API at the network level, so a small proxy is required — see [Proxy setup](#proxy-setup) below.
54
 
55
  ## Configuration
56
 
57
- Only `BOT_TOKEN` and `GEMINI_API_KEY` are required — everything else has a sane default. The full reference (proxy addresses, timeouts, storage, rate limiting, TikTok tuning) lives in **[docs/ENVIRONMENT.md](docs/ENVIRONMENT.md)**.
58
 
59
  ## Proxy setup
60
 
@@ -65,11 +65,11 @@ TELEGRAM_API_BASE_URL=https://<proxy-domain>/fetch/api.telegram.org
65
  TIKWM_API_BASE_URL=https://<proxy-domain>/fetch/www.tikwm.com
66
  ```
67
 
68
- The proxy only forwards to an explicit host allowlist (`api.telegram.org`, `www.tikwm.com`, `tikwm.com`) — see `proxy.ts` for the implementation and `proxy_test.ts` for its tests.
69
 
70
  ## Diagnostics
71
 
72
- All three endpoints below require `Authorization: Bearer <ADMIN_PANEL_KEY>`:
73
 
74
  | Endpoint | Purpose |
75
  |---|---|
@@ -81,7 +81,7 @@ All three endpoints below require `Authorization: Bearer <ADMIN_PANEL_KEY>`:
81
 
82
  ## Commands
83
 
84
- `/reset`, `/draw`, and `/tts` show up in Telegram's command menu. A few more exist but stay out of the menu on purpose:
85
 
86
  | Command | Access | Purpose |
87
  |---|---|---|
@@ -89,7 +89,7 @@ All three endpoints below require `Authorization: Bearer <ADMIN_PANEL_KEY>`:
89
  | `/stats` | bot owner, DMs only | Active chat count, process uptime, per-model quota usage. |
90
  | `/logs` | bot owner, DMs only | Sends `bot.log` with secrets redacted. |
91
 
92
- `/model`, `/provider`, and `/imgmodel` don't exist — the router and the image-model picker choose automatically on every request. See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for why.
93
 
94
  ## Testing
95
 
@@ -98,13 +98,13 @@ pip install -r requirements.txt -r requirements-dev.txt
98
  pytest -v
99
  ```
100
 
101
- Test files mirror the module split — `test_lumen_formatting.py`, `test_lumen_security.py`, `test_lumen_router_config.py`, and `test_lumen_typing_pace.py` each test their matching module directly, while `test_bot.py` covers everything defined in `bot.py` itself. `conftest.py` stubs `BOT_TOKEN`/`GEMINI_API_KEY`/`BOT_LOG_PATH` so the suite needs no real secrets.
102
 
103
  CI (`.github/workflows/ci.yml`) runs `pyflakes` + `pytest` + `pip-audit` on every push and pull request; a successful run triggers `sync-to-hf.yml`, which mirrors the commit to the Hugging Face Space.
104
 
105
  ## Known limitations
106
 
107
- - Chat history and quota counters survive redeploys only if Upstash is configured (see [docs/ENVIRONMENT.md](docs/ENVIRONMENT.md)) — otherwise they live on the container's ephemeral disk and reset on every rebuild.
108
- - YouTube downloading isn't supported — Hugging Face Spaces' outbound IPs are blocked at the TLS handshake level. Viewing and analyzing a video by link still works.
109
  - TikTok downloading depends on the unofficial TikWM API, not an official TikTok endpoint, and needs the proxy above to work from Hugging Face Spaces at all.
110
- - Streaming has only been exercised against mocked clients, not live Gemini/OpenRouter SSE traffic — see the manual smoke-test checklist in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) before touching that code path.
 
13
 
14
  **Stack:** Python 3.13 · aiogram · FastAPI · google-genai · Docker
15
 
16
+ > The YAML block above is Hugging Face Space metadata, not a mistake: this same `README.md` doubles as the Space card. Everything below it is normal GitHub documentation.
17
 
18
  ## Features
19
 
20
+ - **Automatic model routing.** No `/model` command: every message goes to whichever provider actually has what it needs. Web search and link reading always go to Gemini; everything else defaults to free OpenRouter models, protecting Gemini's tight daily quota.
21
+ - **Streaming replies** with a self-calibrating typing-speed pacer, so answers type themselves in instead of landing in a few large chunks.
22
+ - **Defenses against prompt injection and identity leaks.** A deterministic input filter plus output scrubbers keep the bot from revealing which model or provider actually answered.
23
+ - **TikTok downloads** without watermarks: video, slideshows (including "live" photo slides), and original sound.
24
+ - **Image generation** through Pollinations.ai. The model is picked from the prompt itself (anime, fantasy, realism, quick sketch, or a general default).
25
+ - **Text-to-speech**, trying Fish Audio first and falling back to Gemini TTS.
26
+ - `/draw` and `/tts` also work as plain phrases at the start of a message ("draw a cat," "read this out loud"), no slash required.
27
+ - **Persistent state.** An optional Upstash Redis backend keeps chat history and quota counters alive across redeploys.
28
+ - **Error tracking** through an optional Sentry integration that scrubs secrets before sending anything.
29
 
30
  ## How it works
31
 
32
+ Lumen is a single FastAPI + aiogram service. Telegram delivers updates to a webhook. Each message gets routed through a chain of candidate models (Gemini and/or OpenRouter), built on the fly from the message's content: attachments, links, and a couple of lightweight heuristics for "does this need current information" and "is this a heavy request." The first provider that answers wins; the other is tried as a fallback if its whole chain fails.
33
 
34
+ The codebase is a modular monolith. `bot.py` is the orchestrator; the rest is split into focused modules: `lumen_router_config.py` (model routing), `lumen_formatting.py` (markdown to Telegram HTML), `lumen_security.py` (injection and leak defenses), `lumen_images.py`, `lumen_tts.py`, `lumen_tiktok.py`, `lumen_telegram_transport.py`, `lumen_state_storage.py`, and `lumen_typing_pace.py`.
35
 
36
  See **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** for a deeper look at routing, streaming, the security layers, and the TikTok downloader.
37
 
 
50
  curl -H "Authorization: Bearer <BOT_TOKEN>" https://<space-host>/admin_keys
51
  ```
52
 
53
+ Hugging Face Spaces' outbound IPs are blocked by Telegram's API at the network level, so a small proxy is required. See [Proxy setup](#proxy-setup) below.
54
 
55
  ## Configuration
56
 
57
+ Only `BOT_TOKEN` and `GEMINI_API_KEY` are required. Everything else has a sane default; the full reference (proxy addresses, timeouts, storage, rate limiting, TikTok tuning) lives in **[docs/ENVIRONMENT.md](docs/ENVIRONMENT.md)**.
58
 
59
  ## Proxy setup
60
 
 
65
  TIKWM_API_BASE_URL=https://<proxy-domain>/fetch/www.tikwm.com
66
  ```
67
 
68
+ The proxy only forwards to an explicit host allowlist (`api.telegram.org`, `www.tikwm.com`, `tikwm.com`). See `proxy.ts` for the implementation and `proxy_test.ts` for its tests.
69
 
70
  ## Diagnostics
71
 
72
+ All three endpoints below require `Authorization: Bearer <ADMIN_PANEL_KEY>` (`/admin_keys`, covered in the deploy steps above, uses `BOT_TOKEN` instead):
73
 
74
  | Endpoint | Purpose |
75
  |---|---|
 
81
 
82
  ## Commands
83
 
84
+ `/start`, `/reset`, `/draw`, and `/tts` show up in Telegram's command menu. A few more exist but stay out of the menu on purpose:
85
 
86
  | Command | Access | Purpose |
87
  |---|---|---|
 
89
  | `/stats` | bot owner, DMs only | Active chat count, process uptime, per-model quota usage. |
90
  | `/logs` | bot owner, DMs only | Sends `bot.log` with secrets redacted. |
91
 
92
+ `/model`, `/provider`, and `/imgmodel` don't exist. The router and the image-model picker choose automatically on every request; see [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for why.
93
 
94
  ## Testing
95
 
 
98
  pytest -v
99
  ```
100
 
101
+ Test files mirror the module split: `test_lumen_formatting.py`, `test_lumen_security.py`, `test_lumen_router_config.py`, and `test_lumen_typing_pace.py` each test their matching module directly, while `test_bot.py` covers everything defined in `bot.py` itself. `conftest.py` stubs `BOT_TOKEN`/`GEMINI_API_KEY`/`BOT_LOG_PATH` so the suite needs no real secrets.
102
 
103
  CI (`.github/workflows/ci.yml`) runs `pyflakes` + `pytest` + `pip-audit` on every push and pull request; a successful run triggers `sync-to-hf.yml`, which mirrors the commit to the Hugging Face Space.
104
 
105
  ## Known limitations
106
 
107
+ - Chat history and quota counters survive redeploys only if Upstash is configured (see [docs/ENVIRONMENT.md](docs/ENVIRONMENT.md)); otherwise they live on the container's ephemeral disk and reset on every rebuild.
108
+ - YouTube downloading isn't supported, because Hugging Face Spaces' outbound IPs are blocked at the TLS handshake level. Viewing and analyzing a video by link still works.
109
  - TikTok downloading depends on the unofficial TikWM API, not an official TikTok endpoint, and needs the proxy above to work from Hugging Face Spaces at all.
110
+ - Streaming has only been exercised against mocked clients, not live Gemini/OpenRouter SSE traffic. See the manual smoke-test checklist in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) before touching that code path.