diff options
| author | Ben Sima <ben@bensima.com> | 2025-12-13 00:54:36 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-12-13 00:54:36 -0500 |
| commit | 42dec1ddd4e83957ad4c6747067eb6e8351d3a4d (patch) | |
| tree | 25889c7a88f86ed4737688cb0299fa375e2cfcb0 /Omni | |
| parent | 6bbf81f41c318a4200156e58707c807b230a601c (diff) | |
telegram: intelligent group response (LLM decides when to speak)
- Remove mention-based filtering, bot sees all group messages
- Add response rules to system prompt for group chats:
- tool invocation = always respond
- direct question = respond
- factual correction = maybe respond
- casual banter = stay silent
- Empty response in group = intentional silence (no fallback msg)
- Add chat type context to system prompt
Diffstat (limited to 'Omni')
| -rw-r--r-- | Omni/Agent/Telegram.hs | 57 |
1 files changed, 35 insertions, 22 deletions
diff --git a/Omni/Agent/Telegram.hs b/Omni/Agent/Telegram.hs index ffad4c7..f8afcb7 100644 --- a/Omni/Agent/Telegram.hs +++ b/Omni/Agent/Telegram.hs @@ -151,9 +151,21 @@ telegramSystemPrompt = "", "use the 'recall' tool to search your memory for relevant context when needed.", "", + "## when to respond (GROUP CHATS)", + "", + "you see all messages in the group. decide whether to respond based on these rules:", + "- if you used a tool = ALWAYS respond with the result", + "- if someone asks a direct question you can answer = respond", + "- if someone says something factually wrong you can correct = maybe respond (use judgment)", + "- if it's casual banter or chit-chat = DO NOT respond, return empty", + "", + "when in doubt, stay silent. you don't need to participate in every conversation.", + "if you choose not to respond, return an empty message (just don't say anything).", + "", "## important", "", - "ALWAYS include a text response to the user after using tools. never end your turn with only tool calls." + "in private chats, ALWAYS respond. in group chats, follow the rules above.", + "when you DO respond, include a text response after using tools." ] getUpdates :: Types.TelegramConfig -> Int -> IO [Types.TelegramMessage] @@ -288,24 +300,18 @@ handleMessage :: Text -> Types.TelegramMessage -> IO () -handleMessage tgConfig provider engineCfg botUsername msg = do +handleMessage tgConfig provider engineCfg _botUsername msg = do let userName = Types.tmUserFirstName msg <> maybe "" (" " <>) (Types.tmUserLastName msg) chatId = Types.tmChatId msg usrId = Types.tmUserId msg - unless (Types.shouldRespondInGroup botUsername msg) <| do - when (Types.isGroupChat msg) - <| putText - <| "Ignoring group message (not mentioned): " - <> Text.take 50 (Types.tmText msg) - unless (Types.isUserAllowed tgConfig usrId) <| do putText <| "Unauthorized user: " <> tshow usrId <> " (" <> userName <> ")" sendMessage tgConfig chatId "sorry, you're not authorized to use this bot." - when (Types.shouldRespondInGroup botUsername msg && Types.isUserAllowed tgConfig usrId) <| do + when (Types.isUserAllowed tgConfig usrId) <| do sendTypingAction tgConfig chatId user <- Memory.getOrCreateUserByTelegramId usrId userName @@ -440,10 +446,15 @@ handleAuthorizedMessage tgConfig provider engineCfg msg uid userName chatId = do let localTime = utcToLocalTime tz now timeStr = Text.pack (formatTime defaultTimeLocale "%A, %B %d, %Y at %H:%M" localTime) - let systemPrompt = + let chatContext = + if Types.isGroupChat msg + then "\n\n## Chat Type\nThis is a GROUP CHAT. Apply the group response rules - only respond if appropriate." + else "\n\n## Chat Type\nThis is a PRIVATE CHAT. Always respond to the user." + systemPrompt = telegramSystemPrompt <> "\n\n## Current Date and Time\n" <> timeStr + <> chatContext <> "\n\n## Current User\n" <> "You are talking to: " <> userName @@ -505,18 +516,20 @@ handleAuthorizedMessage tgConfig provider engineCfg msg uid userName chatId = do if Text.null response then do - putText "Warning: empty response from agent" - sendMessage tgConfig chatId "hmm, i don't have a response for that" - else sendMessage tgConfig chatId response - - checkAndSummarize (Types.tgOpenRouterApiKey tgConfig) uid chatId - - putText - <| "Responded to " - <> userName - <> " (cost: " - <> tshow (Engine.resultTotalCost agentResult) - <> " cents)" + if Types.isGroupChat msg + then putText "Agent chose not to respond (group chat)" + else do + putText "Warning: empty response from agent" + sendMessage tgConfig chatId "hmm, i don't have a response for that" + else do + sendMessage tgConfig chatId response + checkAndSummarize (Types.tgOpenRouterApiKey tgConfig) uid chatId + putText + <| "Responded to " + <> userName + <> " (cost: " + <> tshow (Engine.resultTotalCost agentResult) + <> " cents)" maxConversationTokens :: Int maxConversationTokens = 4000 |
