deerflow2/backend/app/channels
DanielWalnut 839fa99237
feat(telegram): stream agent replies by editing the placeholder message in place (#3534)
* docs(spec): telegram streaming output design

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(plan): telegram streaming implementation plan

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(telegram): report streaming support for telegram channel

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(channels): use slack as the non-streaming sample channel in manager tests

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(telegram): register running-reply placeholder as stream target

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(telegram): pin last_edit_at sentinel in placeholder registration test

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(telegram): extract _send_new_message from send()

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(telegram): edit streamed message in place for non-final updates

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(telegram): finalize streamed message with overflow splitting

When is_final=True arrives and stream state exists, pop the state, edit
the streamed placeholder with the final text, split overflow into follow-up
send_message calls, update _last_bot_message, and clear stream state.
Falls back to _send_new_message when no stream state is registered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(telegram): exercise the not-modified handler in final edit path

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: telegram channel now streams replies via message editing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(telegram): harden final-delivery path with guarded retry and chunk retries

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(channels): accept runtime 'messages' SSE event for streaming text accumulation

The embedded runtime (matching LangGraph Platform semantics) emits SSE
event name 'messages' for the requested 'messages-tuple' stream mode,
so the manager never accumulated token deltas and streaming channels
only updated from end-of-step 'values' snapshots — on Telegram this
looked like 'Working on it...' followed by the full answer in one block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(telegram): widen stream-edit throttle to 3s in group chats

Telegram caps bots at 20 messages/minute per group, stricter than the
1 msg/s per-chat guideline. Groups have negative chat ids, so pick the
interval by sign.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(telegram): address review findings — thread fallback messages, bound stream registry, share stream-event constants

- Fallback/new stream messages now carry reply_to_message_id parsed from
  thread_ts so they stay nested under the user's message (finding 1)
- STREAM_MODES / MESSAGE_STREAM_EVENTS constants link the requested
  stream modes to the SSE event names they arrive under (finding 2)
- _register_stream_message bounds the in-flight registry at 256 entries,
  evicting oldest, guarding against leaks when a final never arrives (finding 4)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 08:38:28 +08:00
..
__init__.py Refactor DeerFlow to use Gateway's LangGraph-compatible API 2026-04-26 20:38:34 +08:00
base.py feat(channels): add DingTalk channel integration (#2628) 2026-04-30 11:25:33 +08:00
commands.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
connection_identity.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
dingtalk.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
discord.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
feishu.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
manager.py feat(telegram): stream agent replies by editing the placeholder message in place (#3534) 2026-06-13 08:38:28 +08:00
message_bus.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
runtime_config_store.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
service.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
slack.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
store.py refactor: split backend into harness (deerflow.*) and app (app.*) (#1131) 2026-03-14 22:55:52 +08:00
telegram.py feat(telegram): stream agent replies by editing the placeholder message in place (#3534) 2026-06-13 08:38:28 +08:00
wechat.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00
wecom.py feat(im): Add user-owned IM channel connections (#3487) 2026-06-12 15:24:58 +08:00