diff --git a/src/channels/telegram.ts b/src/channels/telegram.ts index a676fac..2500829 100644 --- a/src/channels/telegram.ts +++ b/src/channels/telegram.ts @@ -501,8 +501,14 @@ export class TelegramAdapter implements ChannelAdapter { async editMessage(chatId: string, messageId: string, text: string): Promise { const { markdownToTelegramV2 } = await import('./telegram-format.js'); - const formatted = await markdownToTelegramV2(text); - await this.bot.api.editMessageText(chatId, Number(messageId), formatted, { parse_mode: 'MarkdownV2' }); + try { + const formatted = await markdownToTelegramV2(text); + await this.bot.api.editMessageText(chatId, Number(messageId), formatted, { parse_mode: 'MarkdownV2' }); + } catch (e) { + // If MarkdownV2 fails, fall back to plain text (mirrors sendMessage fallback) + console.warn('[Telegram] MarkdownV2 edit failed, falling back to raw text:', e); + await this.bot.api.editMessageText(chatId, Number(messageId), text); + } } async addReaction(chatId: string, messageId: string, emoji: string): Promise { diff --git a/src/core/bot.ts b/src/core/bot.ts index 216e674..2f102e7 100644 --- a/src/core/bot.ts +++ b/src/core/bot.ts @@ -633,8 +633,10 @@ export class LettaBot implements AgentSession { messageId = result.messageId; sentAnyMessage = true; } - } catch { - // Ignore edit errors (e.g. rate limits) + } catch (editErr) { + // Log but don't fail - streaming edits are best-effort + // (e.g. rate limits, MarkdownV2 formatting issues mid-stream) + console.warn('[Bot] Streaming edit failed:', editErr instanceof Error ? editErr.message : editErr); } lastUpdate = Date.now(); } @@ -729,15 +731,15 @@ export class LettaBot implements AgentSession { console.log(`[Bot] Sent: "${preview}"`); } catch (sendError) { console.error('[Bot] Error sending response:', sendError); - if (!messageId) { - try { - await adapter.sendMessage({ chatId: msg.chatId, text: response, threadId: msg.threadId }); - sentAnyMessage = true; - // Reset recovery counter on successful response - this.store.resetRecoveryAttempts(); - } catch (retryError) { - console.error('[Bot] Retry send also failed:', retryError); - } + // If edit failed (messageId exists), send the complete response as a new message + // so the user isn't left with a truncated streaming edit + try { + await adapter.sendMessage({ chatId: msg.chatId, text: response, threadId: msg.threadId }); + sentAnyMessage = true; + // Reset recovery counter on successful response + this.store.resetRecoveryAttempts(); + } catch (retryError) { + console.error('[Bot] Retry send also failed:', retryError); } } }