* 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>