Skip to content

fix(telegram): address 5 post-merge audit follow-ups#28681

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-6063e704
May 19, 2026
Merged

fix(telegram): address 5 post-merge audit follow-ups#28681
teknium1 merged 1 commit into
mainfrom
hermes/hermes-6063e704

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Fixes 5 small issues filed during the post-merge salvage audit. Single PR because each fix is small and they touch related files.

Resolves

Changes

#28670 — anchor + length-cap the provider-error sanitizer

_looks_like_gateway_provider_error now uses an anchored regex (^\s*(\W*\s*)?...) and refuses to rewrite messages over 400 chars or 4+ lines. A user asking 'what does HTTP 404 mean?' on Telegram no longer has their entire reply replaced with the provider-error template; the rewrite still fires on actual short provider error envelopes that lead with 'HTTP 503' / 'API call failed' / etc.

#28672 — drop the 1s sleep, keep the retry

The original code did asyncio.sleep(1) then retried with the same message_thread_id. The sleep added latency on every thread-not-found error; the retry IS sometimes useful (Telegram has a one-off thread-not-found flake mode exercised by test_send_retries_transient_thread_not_found_before_fallback), so I kept the retry but removed the sleep.

#28674 — extend DM-topic retry predicate

_should_retry_without_dm_topic_reply_anchor previously required reply_to_message_id is not None, so synthetic / resumed sends that route via direct_messages_topic_id (no anchor) had no retry path if Bot API rejected the topic id. Predicate now also fires when direct_messages_topic_id is set and the BadRequest mentions a topic/thread routing failure. The retry path already correctly strips both fields together — only the trigger needed widening.

#28676 — remove dead branch

Lines 4947-4960 of gateway/platforms/telegram.py checked ext in SUPPORTED_IMAGE_DOCUMENT_TYPES for .png/.jpg/.jpeg/.webp/.gif. The earlier branch at line 4896 (bd0c54d17 fix: route Telegram image documents through photo handling) already handles the exact same extension set and returns before reaching here. Replaced the dead block with a comment.

#28678 — chat-scoped auth covers channels

source.chat_type in {'group', 'forum'} extended to {'group', 'forum', 'channel'} for the chat-scoped allowlist in _is_user_authorized. Operators can now put a channel id in TELEGRAM_GROUP_ALLOWED_CHATS and channel posts get authorized correctly. Previously the only paths that worked for channels were either listing the channel id in TELEGRAM_ALLOWED_USERS (because _build_message_event synthesizes user_id = chat.id for channel posts) or GATEWAY_ALLOW_ALL_USERS=true.

Validation

scripts/run_tests.sh tests/gateway/test_telegram_thread_fallback.py -q    → 41/41
scripts/run_tests.sh tests/cron/test_scheduler.py -q                      → 127/127
scripts/run_tests.sh tests/gateway/test_telegram_thread_fallback.py tests/gateway/test_telegram_documents.py tests/gateway/test_telegram_channel_posts.py tests/gateway/test_unauthorized_dm_behavior.py tests/gateway/test_telegram_noise_filter.py tests/gateway/test_telegram_group_gating.py -q  → 144/147

The 3 failures in the broader set are pre-existing test-pollution failures that reproduce on plain main without these changes.

…28674, #28676, #28678)

Five small fixes against issues filed during the post-merge salvage audit:

* #28670: `_GATEWAY_PROVIDER_ERROR_RE` false-positives on legitimate prose.
  Replace the regex with an anchored `_GATEWAY_PROVIDER_ERROR_SHAPE_RE` and
  add a length-cap heuristic to `_looks_like_gateway_provider_error`:
  short envelope at the start of the message → real provider error; long
  prose containing 'HTTP 404' → assistant answer, leave alone.

* #28672: drop the pointless 1s asyncio.sleep on Telegram thread-not-found
  retries. The same-thread retry is preserved (catches Telegram's
  occasional transient flake exercised by
  test_send_retries_transient_thread_not_found_before_fallback) but with
  no artificial delay.

* #28674: broaden `_should_retry_without_dm_topic_reply_anchor` to also
  fire when Bot API rejects `direct_messages_topic_id` for synthetic /
  resumed sends that have no reply anchor. Avoids dropping post-resume
  background notifications if the topic id goes stale.

* #28676: delete the dead image-document branch superseded by bd0c54d
  (which returns early on the same extension set).

* #28678: extend chat-scoped allowlist (`TELEGRAM_GROUP_ALLOWED_CHATS`)
  to also cover `chat_type == 'channel'`, so operators can authorize
  channel posts by chat id without falling back to per-user allowlists.

Tests:
- scripts/run_tests.sh tests/gateway/test_telegram_thread_fallback.py -q  → 41/41
- scripts/run_tests.sh tests/cron/test_scheduler.py -q                    → 127/127
- broader test set: same 3 pre-existing test-pollution failures reproduce
  on plain main.
@teknium1 teknium1 merged commit a3c7531 into main May 19, 2026
16 of 17 checks passed
@teknium1 teknium1 deleted the hermes/hermes-6063e704 branch May 19, 2026 10:16
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: hermes/hermes-6063e704 vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 8945 on HEAD, 8945 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 4701 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@alt-glitch alt-glitch added type/bug Something isn't working platform/telegram Telegram bot adapter comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists labels May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter type/bug Something isn't working

Projects

None yet

2 participants