fix(telegram): report truncated mid-stream preview as partial delivery - #60127
fix(telegram): report truncated mid-stream preview as partial delivery#60127cober-sky wants to merge 1 commit into
Conversation
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.
|
Thanks for tracing this through the adapter and stream-consumer contracts. The premise is confirmed on current main: 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. |
Problem
During streaming (
finalize=False),edit_messagetruncates oversized previews to fit Telegram's 4096 UTF-16 limit (#48648) but returnssuccess=Truewith 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:The truncated preview becomes the only delivery the user ever sees — long answers arrive permanently cut off.
Fix
Reuse the existing
partial_overflowcontract (already documented onSendResult.raw_response): returnsuccess=Falsewithraw_response={"partial_overflow": True, "delivered_prefix": ..., "last_message_id": ...}from every mid-stream truncation site:message too longretry,message is not modifiedon an already-truncated preview.The consumer's existing
partial_overflowbranch 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.