mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-02 03:55:55 +00:00
feat: Improve TelegramAdapter message handling with enhanced error management and draft message support
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
import telegram
|
import telegram
|
||||||
@@ -421,11 +420,15 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
|
|||||||
message_thread_id = getattr(effective_message, 'message_thread_id', None) if effective_message else None
|
message_thread_id = getattr(effective_message, 'message_thread_id', None) if effective_message else None
|
||||||
|
|
||||||
if chat_type == 'private':
|
if chat_type == 'private':
|
||||||
draft_id = int(time.time() * 1000)
|
import time as _time
|
||||||
self.msg_stream_id[message_id] = ('private', draft_id)
|
|
||||||
|
|
||||||
|
draft_id = int(_time.time() * 1000)
|
||||||
|
self.msg_stream_id[message_id] = ('private', draft_id)
|
||||||
args = self._build_message_args(chat_id, 'Thinking...', message_thread_id, draft_id=draft_id)
|
args = self._build_message_args(chat_id, 'Thinking...', message_thread_id, draft_id=draft_id)
|
||||||
await self.bot.send_message_draft(**args)
|
try:
|
||||||
|
await self.bot.send_message_draft(**args)
|
||||||
|
except (telegram.error.RetryAfter, telegram.error.BadRequest):
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
args = self._build_message_args(chat_id, 'Thinking...', message_thread_id)
|
args = self._build_message_args(chat_id, 'Thinking...', message_thread_id)
|
||||||
send_msg = await self.bot.send_message(**args)
|
send_msg = await self.bot.send_message(**args)
|
||||||
@@ -452,7 +455,7 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
|
|||||||
if message_id not in self.msg_stream_id:
|
if message_id not in self.msg_stream_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
chat_mode, draft_id = self.msg_stream_id[message_id]
|
chat_mode, stream_id = self.msg_stream_id[message_id]
|
||||||
components = await TelegramMessageConverter.yiri2target(message, self.bot)
|
components = await TelegramMessageConverter.yiri2target(message, self.bot)
|
||||||
|
|
||||||
if not components or components[0]['type'] != 'text':
|
if not components or components[0]['type'] != 'text':
|
||||||
@@ -463,30 +466,40 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
|
|||||||
content = components[0]['text']
|
content = components[0]['text']
|
||||||
form_data = getattr(bot_message, '_form_data', None)
|
form_data = getattr(bot_message, '_form_data', None)
|
||||||
|
|
||||||
|
if form_data and is_final:
|
||||||
|
self.msg_stream_id.pop(message_id, None)
|
||||||
|
await self._send_form_action_buttons(message_source, form_data)
|
||||||
|
return
|
||||||
|
|
||||||
if chat_mode == 'private':
|
if chat_mode == 'private':
|
||||||
if form_data and is_final:
|
# Streaming via draft (ephemeral preview in the chat input area)
|
||||||
# Suppress the streaming-text materialisation: this chunk's
|
if (msg_seq - 1) % 8 == 0 or is_final:
|
||||||
# content is just a placeholder (e.g. zero-width space, or
|
args = self._build_message_args(chat_id, content, message_thread_id, draft_id=stream_id)
|
||||||
# the display_text used to keep ResponseWrapper from dropping
|
try:
|
||||||
# the chunk). The button card below carries the real prompt.
|
await self.bot.send_message_draft(**args)
|
||||||
self.msg_stream_id.pop(message_id, None)
|
except telegram.error.BadRequest as exc:
|
||||||
await self._send_form_action_buttons(message_source, form_data)
|
if 'Message_too_long' in str(exc):
|
||||||
return
|
args['text'] = content[:4000] + '\n\n… (truncated)'
|
||||||
args = self._build_message_args(chat_id, content, message_thread_id, draft_id=draft_id)
|
try:
|
||||||
await self.bot.send_message_draft(**args)
|
await self.bot.send_message_draft(**args)
|
||||||
|
except telegram.error.RetryAfter:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
pass # Ignore other draft errors (cosmetic)
|
||||||
if is_final and bot_message.tool_calls is None:
|
if is_final and bot_message.tool_calls is None:
|
||||||
del args['draft_id']
|
# Finalise: send the real message, discard the draft
|
||||||
await self.bot.send_message(**args)
|
args = self._build_message_args(chat_id, content, message_thread_id)
|
||||||
|
try:
|
||||||
|
await self.bot.send_message(**args)
|
||||||
|
except telegram.error.BadRequest as exc:
|
||||||
|
if 'Message_too_long' in str(exc):
|
||||||
|
args['text'] = content[:4000] + '\n\n… (truncated)'
|
||||||
|
await self.bot.send_message(**args)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
self.msg_stream_id.pop(message_id)
|
self.msg_stream_id.pop(message_id)
|
||||||
else:
|
else:
|
||||||
stream_id = draft_id
|
# Streaming via edit_message_text (persistent message)
|
||||||
if form_data and is_final:
|
|
||||||
# Same suppression as the private branch — don't push the
|
|
||||||
# placeholder text into the streaming message; render the
|
|
||||||
# button card instead.
|
|
||||||
self.msg_stream_id.pop(message_id, None)
|
|
||||||
await self._send_form_action_buttons(message_source, form_data)
|
|
||||||
return
|
|
||||||
if (msg_seq - 1) % 8 == 0 or is_final:
|
if (msg_seq - 1) % 8 == 0 or is_final:
|
||||||
args = {
|
args = {
|
||||||
'message_id': stream_id,
|
'message_id': stream_id,
|
||||||
@@ -495,7 +508,14 @@ class TelegramAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter):
|
|||||||
}
|
}
|
||||||
if self.config.get('markdown_card', False):
|
if self.config.get('markdown_card', False):
|
||||||
args['parse_mode'] = 'MarkdownV2'
|
args['parse_mode'] = 'MarkdownV2'
|
||||||
await self.bot.edit_message_text(**args)
|
try:
|
||||||
|
await self.bot.edit_message_text(**args)
|
||||||
|
except telegram.error.BadRequest as exc:
|
||||||
|
if 'Message_too_long' in str(exc):
|
||||||
|
args['text'] = self._process_markdown(content[:4000] + '\n\n… (truncated)')
|
||||||
|
await self.bot.edit_message_text(**args)
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
|
||||||
if is_final and bot_message.tool_calls is None:
|
if is_final and bot_message.tool_calls is None:
|
||||||
self.msg_stream_id.pop(message_id)
|
self.msg_stream_id.pop(message_id)
|
||||||
|
|||||||
Reference in New Issue
Block a user