diff options
Diffstat (limited to 'Omni/Agent/Telegram.hs')
| -rw-r--r-- | Omni/Agent/Telegram.hs | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/Omni/Agent/Telegram.hs b/Omni/Agent/Telegram.hs index 6da1484..2f0a029 100644 --- a/Omni/Agent/Telegram.hs +++ b/Omni/Agent/Telegram.hs @@ -92,6 +92,7 @@ import qualified Omni.Agent.Tools.Email as Email import qualified Omni.Agent.Tools.Hledger as Hledger import qualified Omni.Agent.Tools.Notes as Notes import qualified Omni.Agent.Tools.Pdf as Pdf +import qualified Omni.Agent.Tools.Python as Python import qualified Omni.Agent.Tools.Todos as Todos import qualified Omni.Agent.Tools.WebReader as WebReader import qualified Omni.Agent.Tools.WebSearch as WebSearch @@ -959,7 +960,8 @@ processEngagedMessage tgConfig provider engineCfg msg uid userName chatId userMe if isEmailAuthorized userName then Email.allEmailTools else [] - tools = memoryTools <> searchTools <> webReaderTools <> pdfTools <> notesTools <> calendarTools <> todoTools <> messageTools <> hledgerTools <> emailTools + pythonTools = [Python.pythonExecTool] + tools = memoryTools <> searchTools <> webReaderTools <> pdfTools <> notesTools <> calendarTools <> todoTools <> messageTools <> hledgerTools <> emailTools <> pythonTools let agentCfg = Engine.defaultAgentConfig @@ -1000,7 +1002,9 @@ processEngagedMessage tgConfig provider engineCfg msg uid userName chatId userMe _ <- Messages.enqueueImmediate (Just uid) chatId threadId "hmm, i don't have a response for that" (Just "agent_response") Nothing pure () else do - _ <- Messages.enqueueImmediate (Just uid) chatId threadId response (Just "agent_response") Nothing + parts <- splitMessageForChat (Types.tgOpenRouterApiKey tgConfig) response + putText <| "Split response into " <> tshow (length parts) <> " parts" + enqueueMultipart (Just uid) chatId threadId parts (Just "agent_response") unless isGroup <| checkAndSummarize (Types.tgOpenRouterApiKey tgConfig) uid chatId let cost = Engine.resultTotalCost agentResult costStr = Text.pack (printf "%.2f" cost) @@ -1053,6 +1057,55 @@ checkAndSummarize openRouterKey uid chatId = do _ <- Memory.summarizeAndArchive uid chatId summary putText "Conversation summarized and archived (gemini)" +splitMessageForChat :: Text -> Text -> IO [Text] +splitMessageForChat openRouterKey message = do + if Text.length message < 200 + then pure [message] + else do + let haiku = Provider.defaultOpenRouter openRouterKey "anthropic/claude-haiku-4.5" + result <- + Provider.chat + haiku + [] + [ Provider.Message + Provider.System + ( Text.unlines + [ "Split this message into separate chat messages that feel natural in a messaging app.", + "Each part should be logically independent - a complete thought.", + "Separate parts with exactly '---' on its own line.", + "Keep the original text, just add separators. Don't add any commentary.", + "If the message is already short/simple, return it unchanged (no separators).", + "Aim for 2-4 parts maximum. Don't over-split.", + "", + "Good splits: between topics, after questions, between a statement and follow-up", + "Bad splits: mid-sentence, between closely related points" + ] + ) + Nothing + Nothing, + Provider.Message Provider.User message Nothing Nothing + ] + case result of + Left err -> do + putText <| "Message split failed: " <> err + pure [message] + Right msg -> do + let parts = map Text.strip (Text.splitOn "---" (Provider.msgContent msg)) + validParts = filter (not <. Text.null) parts + if null validParts + then pure [message] + else pure validParts + +enqueueMultipart :: Maybe Text -> Int -> Maybe Int -> [Text] -> Maybe Text -> IO () +enqueueMultipart _ _ _ [] _ = pure () +enqueueMultipart mUid chatId mThreadId parts msgType = do + forM_ (zip [0 ..] parts) <| \(i :: Int, part) -> do + if i == 0 + then void <| Messages.enqueueImmediate mUid chatId mThreadId part msgType Nothing + else do + let delaySeconds = fromIntegral (i * 2) + void <| Messages.enqueueDelayed mUid chatId mThreadId part delaySeconds msgType Nothing + shouldEngageInGroup :: Text -> Text -> IO Bool shouldEngageInGroup openRouterKey messageText = do let gemini = Provider.defaultOpenRouter openRouterKey "google/gemini-2.0-flash-001" |
