ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證Telegram機器人,協助說俄語的使用者撰寫自然的烏克蘭語:即時翻譯、錯誤檢查與間隔重複提醒。
AI 翻譯
Telegram bot that helps Russian speakers write natural Ukrainian: live translation, mistake checking, and spaced-repetition reminders
正在載入完整 README。 以下為已儲存的摘錄。
Ukrainian is often called «солов'їна мова», the nightingale language. A Telegram assistant for Russian speakers who are switching to Ukrainian and want to write more naturally, understand their mistakes and remember the corrections. It is a learning aid. It does not replace a professional translator or a teacher, and its model-based checks can be wrong. The screenshot is a mock-up with synthetic text, not a real conversation.檢視完整 README ↗
Try it in Telegram: @solovyinamova_bot
Ukrainian is often called «солов'їна мова», the nightingale language.
English · Українська
A Telegram assistant for Russian speakers who are switching to Ukrainian and want to write more naturally, understand their mistakes and remember the corrections.
It is a learning aid. It does not replace a professional translator or a teacher, and its model-based checks can be wrong.
The screenshot is a mock-up with synthetic text, not a real conversation.
Many people who grew up with Russian now want to use Ukrainian every day. The
hard part is not vocabulary but the small things: calques from Russian, case
government, the у/в alternation, stress. Generic translators answer
"what does it mean", not "how would a native speaker say it" or "what exactly
did I get wrong".
/start shows the mode buttons on the keyboard.мне нужно отпроситься с работы → a natural Ukrainian
phrasing, with the source of the answer and a 🔊 button.Я ходив в магазін. → the corrected text and up to
three explanations. Every correction has its own buttons:
✅ Це помилка · ❌ Тут немає помилки · ✍️ Лише стиль./practice) → up to five of those cards, answered by
typing. A match counts as Good; anything else shows the right answer and
stays due for later. /progress is the last 7 days.| Feature | How |
|---|---|
| Translation ru ⇄ uk | Claude detects the language and translates; dictionary for single known words; Google Translate / MyMemory as fallback |
/check | explanations in Ukrainian only |
| "Як сказати?" (natural phrasing) | model → MyMemory fallback |
"Перевір мене" (/check) | model returns validated JSON: max 3 corrections, error vs style, "no errors" allowed |
| Feedback per correction | stored with model name and prompt version, re-voting allowed, no duplicates |
"Мої помилки" (/mistakes) | corrections you confirmed as errors |
Review cards (/review) | Anki-like again / hard / good / easy. Deck = confirmed mistakes + words saved with 📌 or /remember |
Practice (/practice, /progress) | Up to five typed answers from cards that are due, ordered toward frequent error types. The log stores only right/wrong |
"Поясни слово" (/explain) | Ukrainian dictionary-style definition of a word or short expression, with part of speech, stress, example and synonyms; never a Russian translation |
| Photo in a private chat | Claude reads one image and explains the Ukrainian words on it. The file and caption are not stored |
| Audio | gTTS, only on button press, generated in memory (no temp files); speech synthesis, not pronunciation assessment |
| Direction | auto-detection is only a hint; unknown → the bot asks; /direction pins it |
| Privacy | /privacy, /delete_my_data, retention, no names/usernames/message history |
| Product analytics | /stats [days] for ADMIN_IDS: active/new/returning users, actions by feature, translation sources, share of "error / not an error / style" ratings, quality per model and prompt version; /export_stats sends a CSV of pseudonymous events for 30 days |
Commands: /start, /help, /tr, /say, /check, /explain, /mistakes,
/review, /practice, /progress, /remember, /direction, /privacy, /delete_my_data, /about,
/stats (admin).
In group chats the bot stays silent unless asked: it ignores ordinary
messages and answers only /tr (translate the text after the command, or the
message you reply to), /check, /say and /explain. The optional drip.py worker can
post study cards into the same group once a day, at a time drawn at random
inside a daily window.
src/bot/
main.py, app.py, config.py entry point, wiring, env validation
handlers/ Telegram only: common, translation, modes,
correction, feedback, review, admin
services/ business logic: dictionary, translation chain,
correction, tts, limits
providers/ external APIs: wiktionary, mymemory, anthropic
(shared HTTP helper with timeouts/retries)
storage/ SQLite + repositories
models/ TranslationResult, Correction, parsing
language.py, formatting.py detection, HTML escaping, message splitting
data/ dictionary + sources (see data/README.md)
scripts/ build_dictionary.py, check_secrets.py
tests/ pytest, no network
drip.py optional spaced-repetition poster for a class chat (deck hosted privately)
Every translation returns TranslationResult(text, source, confidence, metadata)
where source is the provider that actually produced the answer.
Main path (any text, direction not pinned): Claude detects whether the text is Russian or Ukrainian and translates it into the other language in one call. No language question is asked.
Single word with an exact dictionary hit: answered locally (instant, free, several meanings, part of speech) plus Wiktionary stress/definitions.
Fallback (no ANTHROPIC_API_KEY, budget exhausted, or a pinned direction):
Claude → Google Translate (official API, if GOOGLE_TRANSLATE_API_KEY is set) →
MyMemory. Every answer must look like the target language (e.g. no ы/э/ё/ъ
in a Ukrainian result), otherwise the next provider is tried. If the language
was only guessed, the opposite direction is tried too.
Як сказати?: Claude (natural phrasing) → Google Translate → MyMemory.
Providers are called one after another, never in parallel "just in case". If a provider returns the input unchanged, it is not treated as a translation.
Requires Python 3.11+.
python -m venv .venv && source .venv/bin/activate
pip install -r requirements-dev.txt
cp .env.example .env # put your own token in .env
PYTHONPATH=src python -m bot
| Variable | Required | Default | Purpose |
|---|---|---|---|
TELEGRAM_BOT_TOKEN | yes | — | from @BotFather |
ANTHROPIC_API_KEY | no (recommended) | — | Claude: main translator, /check, /explain, "Як сказати?" |
GOOGLE_TRANSLATE_API_KEY | no | — | official Google Cloud Translation API as fallback |
REDIRECT_TO_BOT | no | — | redirect mode for a retired bot: answers everything with "moved to @…" |
LLM_MODEL | no | claude-haiku-4-5-20251001 | model name (stored with each correction) |
LLM_DAILY_LIMIT | no | 500 | max paid model calls per day (all users) |
LLM_USER_DAILY_LIMIT | no | 60 | max model calls per user per day (in memory) |
ADMIN_IDS | no | — | comma-separated Telegram IDs allowed to use /stats |
DATABASE_PATH | no | data/runtime/bot.sqlite3 | SQLite file (git-ignored) |
DICTIONARY_PATH | no | data/dictionary.tsv | generated dictionary file |
STORE_RAW_TEXT | no | false | store the full checked text (off by default) |
RETENTION_DAYS | no | 180 | stored corrections are deleted after this |
MAX_INPUT_LENGTH | no | 1000 | max characters per message |
MAX_TTS_LENGTH | no | 300 | max characters for audio |
USER_RATE_LIMIT_PER_MINUTE | no | 20 | per-user request limit |
The bot exits with a clear message if TELEGRAM_BOT_TOKEN is missing; it never
prints the value.
See DEPLOY_GUIDE.md. Secrets live only in the hosting provider's variables, never in the repository.
STORE_RAW_TEXT=true).LOG_LEVEL=DEBUG); tokens/keys are redacted,
tracebacks included./delete_my_data removes everything linked to your ID; old records are
purged after RETENTION_DAYS.The project is licensed under GPL-2.0-or-later (LICENSE), because the dictionary is built from GPL-2.0 data.
data/sources/apertium/.Details: THIRD_PARTY_NOTICES.md.
ruff check . && ruff format --check .
python scripts/build_dictionary.py --check # dictionary is reproducible
pytest # no network, no real keys
pip-audit -r requirements.txt
python scripts/check_secrets.py
CI runs all of the above on every pull request (.github/workflows/ci.yml), plus gitleaks.
Out of scope for now: a full course, a voice tutor, pronunciation scoring.
MAX_CONCURRENT_REQUESTS | no | 8 | concurrent external requests |
LOG_LEVEL | no | INFO | logging level |