Skip to content

fix(telegram): coalesce native drafts and preserve growing text - #133842

Open
Rinta13795 wants to merge 2 commits into
NousResearch:mainfrom
Rinta13795:codex/telegram-native-streaming
Open

Rinta13795 wants to merge 2 commits into
NousResearch:mainfrom
Rinta13795:codex/telegram-native-streaming

Conversation

@Rinta13795

Copy link
Copy Markdown

What does this PR do?

Telegram native previews currently burst after crossing the cumulative buffer threshold, rewrite unfinished Markdown, and abandon draft transport on a short flood cooldown. This change coalesces native previews into stable cumulative text and shares Telegram's draft/typing quota, while preserving the existing complete formatted final answer.

Why

A native client can animate appended characters when the same draft ID is updated. Repeated snapshot rewrites and excess requests work against that behavior. The unchanged base reproduces six calls in 250 ms with an 800 ms interval, plus cursor/fence changes to already displayed code.

Related Issue

Fixes #133841.

Related: #133804 (restart documentation), #54817 / #26157 (client flicker).

Prior work overlaps: #112949 handles interval enforcement; #53865 / #54286 handle draft flood cooldowns. This PR combines a native-draft-only cadence gate with raw prefix stability and the shared draft/typing quota. It leaves ordinary-edit cadence, default transport selection, and hard-error fallback unchanged. #110611's ordinary-message activity feature is outside this scope.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature
  • Security fix
  • Documentation update
  • Tests
  • Refactor with no behavior change

Changes Made

What

  • gateway/stream_consumer*.py: coalesce native draft updates at elapsed cadence; omit synthetic fence closures/cursors for prefix-stable adapters; keep deferred previews pending without claiming delivery or disabling draft transport.
  • plugins/platforms/telegram/telegram_drafts.py: extract draft delivery, retain raw UTF-16-bounded prefixes, reserve actual rich/plain draft and typing requests against normalized per-chat 20/5s and 40/30s windows, and retain native transport during RetryAfter.
  • plugins/platforms/telegram/adapter.py: use the extracted mixin and the shared quota for typing; omit redundant typing while a recent native draft is visible.
  • Add deterministic consumer/adapter regressions and a real-consumer/real-adapter pipeline test with a fake Bot transport. Update the preview/final formatting contract.
  • Update English and Chinese Telegram docs with configuration, cadence, client animation, final formatting, cooldown/fallback, and gateway restart instructions.

Design / Thinking

The user's local A/B prototypes throttled ordinary editable previews to 30 characters/second. The second replayed all remaining text after generation, making long answers slow. They are preserved locally for rollback and are not included in this PR.

The chosen design separates receiving content from displaying it, as client-side streaming interfaces do: retain the latest cumulative text and delegate character animation to Telegram. It adds no fixed character playback cap or completion drain. Raising ordinary edit frequency alone would still show discrete snapshots and would spend a different send/edit allowance.

A quota deferral returns a marked skipped result, not a delivered frame. A genuine endpoint rejection still uses the existing edit fallback. The complete final bypasses preview-only cooldown and uses the existing MarkdownV2/Rich Message renderer.

References: Telegram streaming and shared action quotas, sendMessageDraft.

How to Test

Result

Before: on pristine base 3b4a8911741a, the three added regression files yield 13 failing and 2 passing tests, covering cadence, prefix rewrites, UTF-16 length, shared quota, and cooldown handling.

After:

  • 24 related files: 273 passed, 0 failed, with the unrelated pre-existing image test excluded explicitly.
  • The image case tests/gateway/test_telegram_thread_fallback.py::test_send_image_upload_fallback_blocks_connect_time_rebind fails identically on pristine base and the changed branch; the initial broader run had 273 passes and that one failure. No image-upload behavior is changed here.
  • python scripts/check: 11 checks passed, no blocking/advisory health findings.
  • Real consumer + TelegramAdapter with fake Bot transport: stable ID and raw growing prefixes; burst deltas catch up without character replay; a >4,096-character rich final plus completion details is preserved; rejected draft endpoint safely falls back to the normal formatted final.
  • Local macOS gateway switched to the committed branch and Telegram connection confirmed. Only streaming configuration was changed; model/prompt/rendering settings were preserved. This confirms deployment/connection, not client animation appearance.

Run the focused contracts through the canonical isolated runner:

scripts/run_tests.sh \
  tests/gateway/test_stream_consumer_native_draft.py \
  tests/gateway/test_telegram_native_draft_budget.py \
  tests/gateway/test_telegram_native_stream_pipeline.py \
  tests/gateway/test_telegram_send_draft_format.py -q
python scripts/check

To inspect the UI, enable streaming.enabled: true, streaming.transport: draft, and edit_interval: 0.8 for a private chat, restart the gateway, and request a multi-paragraph reply containing code. Compare growing text and the completed formatted message. Use transport: edit for a client that renders native drafts poorly.

Trade-offs

Plain previews display raw Markdown temporarily; the persistent final keeps existing formatting. Telegram owns animation, so the transport tests cannot prove identical smoothness across clients. Drafts remain private-chat-only and preview text is length-bounded; the existing final delivery retains the full answer. No model, prompt, or generation-budget change is introduced by this diff.

Follow-up

Compare native animation on the user's actual Telegram client. Immediate status/activity indicators are outside this change. Ordinary edit cadence and default selection remain with the related PRs above.

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched existing PRs; overlaps are documented above
  • My PR contains only changes related to this fix
  • Full repository test suite passed (not run; focused checks and the base failure are reported above)
  • python scripts/check passes
  • I've added tests for my changes
  • I've tested on macOS 14.6 / Apple Silicon, Python 3.14.7; UI animation observation remains a follow-up

Documentation & Housekeeping

  • Updated relevant documentation and docstrings
  • Configuration example update: N/A, no new keys
  • Contributing/AGENTS workflow update: N/A
  • Considered cross-platform impact: no new OS-specific implementation
  • Tool descriptions/schemas: N/A

Screenshots / Logs

Only deterministic fake-transport receipts and sanitized deployment state are summarized above. Credentials, private conversations, and local configuration backups are excluded.

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins platform/telegram Telegram bot adapter sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Oct 6, 2026

This branch has not been deployed

No deployments
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 comp/plugins Plugin system and bundled plugins 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.

[Bug]: Telegram native drafts burst updates and rewrite streamed prefixes

2 participants