Skip to content

fix(telegram): report truncated mid-stream preview as partial delivery - #60127

Open
cober-sky wants to merge 1 commit into
NousResearch:mainfrom
cober-sky:fix/telegram-stream-preview-partial-overflow
Open

fix(telegram): report truncated mid-stream preview as partial delivery#60127
cober-sky wants to merge 1 commit into
NousResearch:mainfrom
cober-sky:fix/telegram-stream-preview-partial-overflow

Conversation

@cober-sky

Copy link
Copy Markdown

Problem

During streaming (finalize=False), edit_message truncates oversized previews to fit Telegram's 4096 UTF-16 limit (#48648) but returns success=True with no truncation marker — including from the saturated-preview dedup skips. The stream consumer then records the full accumulated text in _last_sent_text, has_delivered_text() matches the final response against that stale bookkeeping, and the gateway suppresses the normal final send:

Suppressing normal final send ... (streamed=True previewed=True content_delivered=False)

The truncated preview becomes the only delivery the user ever sees — long answers arrive permanently cut off.

Fix

Reuse the existing partial_overflow contract (already documented on SendResult.raw_response): return success=False with raw_response={"partial_overflow": True, "delivered_prefix": ..., "last_message_id": ...} from every mid-stream truncation site:

  • pre-flight truncation,
  • the saturated-preview dedup skip,
  • the reactive message too long retry,
  • message is not modified on an already-truncated preview.

The consumer's existing partial_overflow branch switches into fallback-final mode and delivers the missing tail on completion — no consumer changes needed.

This also composes well with the saturated-preview dedup: the consumer stops progressive edits after the first partial result, so saturated previews no longer burn flood budget at all.

Tests

Existing truncation/dedup/reactive tests updated to the partial-delivery contract; new test covers the not-modified path. tests/gateway/test_telegram_format.py (110), tests/gateway/test_stream_consumer.py + tests/gateway/test_telegram_overflow_partial.py (126) — all pass.

Found and battle-tested running the Telegram gateway against a local Ollama brain with streaming enabled.

During streaming (finalize=False), edit_message truncates oversized
previews to fit Telegram's 4096 UTF-16 limit (NousResearch#48648) but returned
success=True with no truncation marker — including from the
saturated-preview dedup skips. The stream consumer then recorded the
full accumulated text as visible, has_delivered_text() matched the
final response against that stale bookkeeping, and the gateway
suppressed the normal final send. The truncated preview became the
only delivery the user ever saw:

    Suppressing normal final send ... (streamed=True previewed=True
    content_delivered=False)

Reuse the existing partial_overflow contract (documented on
SendResult.raw_response): report success=False with
raw_response={partial_overflow, delivered_prefix, last_message_id}
from every mid-stream truncation site — pre-flight truncation, the
saturated-preview dedup skip, the reactive message-too-long retry,
and "message is not modified" on an already-truncated preview. The
consumer's existing partial_overflow branch switches into
fallback-final mode and delivers the missing tail on completion; no
consumer changes are needed.

This also composes well with the saturated-preview dedup: the
consumer stops progressive edits after the first partial result, so
saturated previews no longer burn flood budget at all.

Tests: existing truncation/dedup/reactive tests updated to the
partial-delivery contract; new test covers the not-modified path.
@alt-glitch alt-glitch added type/bug Something isn't working platform/telegram Telegram bot adapter comp/gateway Gateway runner, session dispatch, delivery sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages P2 Medium — degraded but workaround exists labels Jul 7, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for tracing this through the adapter and stream-consumer contracts. The premise is confirmed on current main: plugins/platforms/telegram/adapter.py:4293, :4309, :4358, and :4365 report successful delivery after a truncated preview, while gateway/stream_consumer.py:1804 records the full accumulated input on successful edits. gateway/stream_consumer.py:1827-1853 already consumes the proposed partial_overflow metadata and enables the fallback-final path.

The PR's four producer-site changes align with that existing contract, and its updated adapter regressions cover the pre-flight, dedup, reactive-overflow, and not-modified paths. The current surrounding code retains the same target blocks, so salvage should be mechanical despite line movement since the PR base.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/streaming Streaming responses: gateway delivery, provider wire labels Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/streaming Streaming responses: gateway delivery, provider wire comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform 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.

3 participants