From 4d21f170cd1d1df239d7ad00fbf79427769a140f Mon Sep 17 00:00:00 2001 From: Ben Sima Date: Sat, 13 Dec 2025 13:09:32 -0500 Subject: telegram: unified message queue with async/scheduled sends - Add Messages.hs with scheduled_messages table and dispatcher loop - All outbound messages now go through the queue (1s polling) - Disable streaming responses, use runAgentWithProvider instead - Add send_message tool for delayed messages (up to 30 days) - Add list_pending_messages and cancel_message tools - Reminders now queue messages instead of sending directly - Exponential backoff retry (max 5 attempts) for failed sends --- Omni/Agent/Telegram/Reminders.hs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'Omni/Agent/Telegram/Reminders.hs') diff --git a/Omni/Agent/Telegram/Reminders.hs b/Omni/Agent/Telegram/Reminders.hs index 706f9da..cc631a0 100644 --- a/Omni/Agent/Telegram/Reminders.hs +++ b/Omni/Agent/Telegram/Reminders.hs @@ -25,7 +25,7 @@ import Alpha import Data.Time (getCurrentTime) import qualified Database.SQLite.Simple as SQL import qualified Omni.Agent.Memory as Memory -import qualified Omni.Agent.Telegram.Types as Types +import qualified Omni.Agent.Telegram.Messages as Messages import qualified Omni.Agent.Tools.Todos as Todos import qualified Omni.Test as Test @@ -78,14 +78,14 @@ lookupChatId uid = (SQL.Only uid) pure (listToMaybe (map SQL.fromOnly rows)) -reminderLoop :: Types.TelegramConfig -> (Types.TelegramConfig -> Int -> Text -> IO ()) -> IO () -reminderLoop tgConfig sendMsg = +reminderLoop :: IO () +reminderLoop = forever <| do threadDelay (5 * 60 * 1000000) - checkAndSendReminders tgConfig sendMsg + checkAndSendReminders -checkAndSendReminders :: Types.TelegramConfig -> (Types.TelegramConfig -> Int -> Text -> IO ()) -> IO () -checkAndSendReminders tgConfig sendMsg = do +checkAndSendReminders :: IO () +checkAndSendReminders = do todos <- Todos.listTodosDueForReminder forM_ todos <| \td -> do mChatId <- lookupChatId (Todos.todoUserId td) @@ -93,6 +93,7 @@ checkAndSendReminders tgConfig sendMsg = do Nothing -> pure () Just chatId -> do let title = Todos.todoTitle td + uid = Todos.todoUserId td dueStr = case Todos.todoDueDate td of Just d -> " (due: " <> tshow d <> ")" Nothing -> "" @@ -102,6 +103,6 @@ checkAndSendReminders tgConfig sendMsg = do <> "\"" <> dueStr <> "\nreply when you finish and i'll mark it complete." - sendMsg tgConfig chatId msg + _ <- Messages.enqueueImmediate (Just uid) chatId msg (Just "reminder") Nothing Todos.markReminderSent (Todos.todoId td) - putText <| "Sent reminder for todo " <> tshow (Todos.todoId td) <> " to chat " <> tshow chatId + putText <| "Queued reminder for todo " <> tshow (Todos.todoId td) <> " to chat " <> tshow chatId -- cgit v1.2.3