Skip to content

fix(telegram): recover final delivery after stream flood - #62253

Closed
helix4u wants to merge 1 commit into
NousResearch:mainfrom
helix4u:fix/telegram-final-delivery
Closed

fix(telegram): recover final delivery after stream flood#62253
helix4u wants to merge 1 commit into
NousResearch:mainfrom
helix4u:fix/telegram-final-delivery

Conversation

@helix4u

@helix4u helix4u commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Fixes a Telegram streaming failure where Hermes completes the final response, a turn-final edit hits flood control, and the gateway later suppresses its normal final send because streaming delivery was recorded as complete. Users can be left with only a short preview such as :( or a partial answer.

This consolidates the two final-delivery cases that are split across existing proposals:

  • Partial preview: enter fallback on the first turn-final Telegram flood error and send only the confirmed missing tail.
  • Empty internal tail: commit the complete answer as a fresh Telegram message instead of trusting a preview that may not be durable on the client.

The change is Telegram-specific through adapter capability flags. Other platforms retain the existing adaptive edit retry behavior.

It also avoids another cosmetic cursor edit after the turn-final edit is already flood-controlled, honors Telegram retry_after during fallback sends, and preserves duplicate suppression for ambiguous timeout results.

Related Issue

Related PRs: #55869, #59864, #54331

Support report: https://discord.com/channels/1053877538025386074/1524313834641297489

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Security fix
  • Documentation update
  • Tests (adding or improving test coverage)
  • Refactor (no behavior change)
  • New skill (bundled or hub)

Changes Made

  • gateway/stream_consumer.py
    • Enters fallback immediately on opted-in turn-final flood failures.
    • Sends a missing tail when only a partial preview is confirmed.
    • Sends a fresh complete final when the internal fallback tail is empty.
    • Honors retry_after for fallback delivery.
    • Distinguishes confirmed send failures from ambiguous timeout delivery.
    • Skips the redundant cursor cleanup edit on the turn-final flood path.
    • Records cursor cleanup only when the edit succeeds.
  • plugins/platforms/telegram/adapter.py
    • Enables immediate turn-final flood fallback and empty-tail final commit for Telegram.
  • tests/gateway/test_telegram_final_delivery.py
    • Covers a :( visible prefix with a longer completed final response.
    • Covers empty-tail final commit and stale preview cleanup.
    • Covers Telegram retry_after, confirmed failures, ambiguous timeouts, and non-opted adapters.

How to Test

  1. Run: python -m pytest tests/gateway/test_telegram_final_delivery.py -q
  2. Enable Telegram edit streaming and force a turn-final RetryAfter after a short preview. Confirm the missing tail is sent and the normal gateway send is suppressed only after confirmed delivery.
  3. Force a final edit failure after the complete preview was recorded. Confirm a fresh final message is sent, stale previews are cleaned up, and topic/reply metadata is retained.
  4. Confirm an adapter without the Telegram capability flag keeps the existing adaptive edit retry behavior.

Local focused verification:

  • Direct async regression harness: 7 passed
  • py_compile for the two implementation files and focused test file: passed
  • git diff --check: passed

The repository pytest suite was not run locally because this operator environment has a known host deadlock risk in its test setup. Full pytest coverage is left to GitHub CI.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched existing open and merged PRs before implementing
  • My PR contains only changes related to this fix
  • I've run pytest tests/ -q and all tests pass
  • I've added tests for the bug fix
  • I've tested on my platform: Windows 11 direct async regression harness

Documentation & Housekeeping

  • Documentation update: N/A
  • cli-config.yaml.example update: N/A
  • CONTRIBUTING.md or AGENTS.md update: N/A
  • Cross-platform impact considered
  • Tool descriptions and schemas update: N/A

Screenshots / Logs

Sanitized support evidence from Hermes 0.18.2 [9cb2a8a] on macOS with Telegram:

Telegram flood control, waiting 266.0s
MarkdownV2 edit failed, falling back to plain text: Flood control exceeded
Suppressing normal final send ... streamed=True ... content_delivered=True
response ready ... response=10839 chars

The model/provider completed the response. The failure boundary is final Telegram delivery after streamed edit flood control.

@helix4u
helix4u marked this pull request as ready for review July 10, 2026 18:56
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages P2 Medium — degraded but workaround exists labels Jul 10, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related: this consolidates the two Telegram final-delivery cases split across #55869 / #59864 / #54331, and overlaps the flood-control final-delivery family (#53865, #52933, #40162). It is a different/consolidating mechanism (immediate turn-final fallback + tail-vs-fresh-final decision in gateway/stream_consumer.py), not a duplicate. Competing with #55869 and #40162 for the same stream_consumer final-delivery path — a maintainer should pick the canonical one.

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 sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants