diff --git a/src/telegram/bot-message-dispatch.ts b/src/telegram/bot-message-dispatch.ts index 27c6a3bfa..339dc30fa 100644 --- a/src/telegram/bot-message-dispatch.ts +++ b/src/telegram/bot-message-dispatch.ts @@ -223,6 +223,7 @@ export const dispatchTelegramMessage = async ({ chunkMode, onVoiceRecording: sendRecordVoice, linkPreview: telegramCfg.linkPreview, + notifyEmptyResponse: info.kind === "final", }); }, onError: (err, info) => { diff --git a/src/telegram/bot-native-commands.ts b/src/telegram/bot-native-commands.ts index 4cca71d14..3674b6e12 100644 --- a/src/telegram/bot-native-commands.ts +++ b/src/telegram/bot-native-commands.ts @@ -484,7 +484,7 @@ export const registerTelegramNativeCommands = ({ cfg, dispatcherOptions: { responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix, - deliver: async (payload) => { + deliver: async (payload, info) => { await deliverReplies({ replies: [payload], chatId: String(chatId), @@ -497,6 +497,7 @@ export const registerTelegramNativeCommands = ({ tableMode, chunkMode, linkPreview: telegramCfg.linkPreview, + notifyEmptyResponse: info.kind === "final", }); }, onError: (err, info) => { diff --git a/src/telegram/bot/delivery.ts b/src/telegram/bot/delivery.ts index 779c0c026..f45269a63 100644 --- a/src/telegram/bot/delivery.ts +++ b/src/telegram/bot/delivery.ts @@ -42,12 +42,15 @@ export async function deliverReplies(params: { onVoiceRecording?: () => Promise | void; /** Controls whether link previews are shown. Default: true (previews enabled). */ linkPreview?: boolean; -}) { + /** If true, send a fallback message when all replies are empty. Default: false */ + notifyEmptyResponse?: boolean; +}): Promise<{ delivered: boolean }> { const { replies, chatId, runtime, bot, replyToMode, textLimit, messageThreadId, linkPreview } = params; const chunkMode = params.chunkMode ?? "length"; const threadParams = buildTelegramThreadParams(messageThreadId); let hasReplied = false; + let skippedEmpty = 0; const chunkText = (markdown: string) => { const markdownChunks = chunkMode === "newline" @@ -75,6 +78,7 @@ export async function deliverReplies(params: { continue; } runtime.error?.(danger("reply missing text/media")); + skippedEmpty++; continue; } const replyToId = replyToMode === "off" ? undefined : resolveTelegramReplyId(reply.replyToId); @@ -255,6 +259,17 @@ export async function deliverReplies(params: { } } } + + // If all replies were empty and notifyEmptyResponse is enabled, send a fallback message + if (!hasReplied && skippedEmpty > 0 && params.notifyEmptyResponse) { + const fallbackText = "No response generated. Please try again."; + await sendTelegramText(bot, chatId, fallbackText, runtime, { + messageThreadId, + }); + hasReplied = true; + } + + return { delivered: hasReplied }; } export async function resolveMedia(