diff options
| author | Ben Sima <ben@bensima.com> | 2025-12-12 20:42:30 -0500 |
|---|---|---|
| committer | Ben Sima <ben@bensima.com> | 2025-12-12 20:42:30 -0500 |
| commit | fd1c5c2bda7831c6cf329f4dc272064a352609e1 (patch) | |
| tree | fc2b28901955189ba15777b0e2fc4eccac7fe103 /Omni/Agent | |
| parent | a9d7f9434b370f4dd79ac40c606c91d3e3d9716b (diff) | |
Add sender_name to conversation messages for group chat support
- Add sender_name column to conversation_messages table
- Migrate existing messages to set sender_name='bensima'
- Show sender names in conversation context (e.g., 'bensima: hello')
- Pass userName when saving user messages in Telegram bot
Diffstat (limited to 'Omni/Agent')
| -rw-r--r-- | Omni/Agent/Memory.hs | 27 | ||||
| -rw-r--r-- | Omni/Agent/Telegram.hs | 4 |
2 files changed, 23 insertions, 8 deletions
diff --git a/Omni/Agent/Memory.hs b/Omni/Agent/Memory.hs index 8337baf..d40bb34 100644 --- a/Omni/Agent/Memory.hs +++ b/Omni/Agent/Memory.hs @@ -364,6 +364,7 @@ data ConversationMessage = ConversationMessage cmUserId :: Text, cmChatId :: Int, cmRole :: MessageRole, + cmSenderName :: Maybe Text, cmContent :: Text, cmTokensEstimate :: Int, cmCreatedAt :: UTCTime @@ -377,6 +378,7 @@ instance Aeson.ToJSON ConversationMessage where "user_id" .= cmUserId m, "chat_id" .= cmChatId m, "role" .= cmRole m, + "sender_name" .= cmSenderName m, "content" .= cmContent m, "tokens_estimate" .= cmTokensEstimate m, "created_at" .= cmCreatedAt m @@ -389,6 +391,7 @@ instance SQL.FromRow ConversationMessage where <*> SQL.field <*> (parseRole </ SQL.field) <*> SQL.field + <*> SQL.field <*> (fromMaybe 0 </ SQL.field) <*> SQL.field where @@ -492,6 +495,7 @@ initMemoryDb conn = do \ user_id TEXT NOT NULL REFERENCES users(id),\ \ chat_id INTEGER NOT NULL,\ \ role TEXT NOT NULL,\ + \ sender_name TEXT,\ \ content TEXT NOT NULL,\ \ tokens_estimate INTEGER,\ \ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP\ @@ -499,6 +503,7 @@ initMemoryDb conn = do SQL.execute_ conn "CREATE INDEX IF NOT EXISTS idx_conv_user_chat ON conversation_messages(user_id, chat_id)" + migrateConversationMessages conn SQL.execute_ conn "CREATE TABLE IF NOT EXISTS conversation_summaries (\ @@ -529,6 +534,15 @@ initMemoryDb conn = do conn "CREATE INDEX IF NOT EXISTS idx_notes_topic ON notes(user_id, topic)" +-- | Migrate conversation_messages to add sender_name column. +migrateConversationMessages :: SQL.Connection -> IO () +migrateConversationMessages conn = do + columns <- SQL.query_ conn "PRAGMA table_info(conversation_messages)" :: IO [(Int, Text, Text, Int, Maybe Text, Int)] + let columnNames = map (\(_, name, _, _, _, _) -> name) columns + unless ("sender_name" `elem` columnNames) <| do + SQL.execute_ conn "ALTER TABLE conversation_messages ADD COLUMN sender_name TEXT" + SQL.execute_ conn "UPDATE conversation_messages SET sender_name = 'bensima' WHERE role = 'user' AND sender_name IS NULL" + -- | Create a new user. createUser :: Text -> Maybe Int -> IO User createUser name telegramId = do @@ -896,15 +910,15 @@ estimateTokens :: Text -> Int estimateTokens t = max 1 (Text.length t `div` 4) -- | Save a message to conversation history. -saveMessage :: Text -> Int -> MessageRole -> Text -> IO ConversationMessage -saveMessage uid chatId role content = do +saveMessage :: Text -> Int -> MessageRole -> Maybe Text -> Text -> IO ConversationMessage +saveMessage uid chatId role senderName content = do now <- getCurrentTime let tokens = estimateTokens content withMemoryDb <| \conn -> do SQL.execute conn - "INSERT INTO conversation_messages (user_id, chat_id, role, content, tokens_estimate, created_at) VALUES (?, ?, ?, ?, ?, ?)" - (uid, chatId, roleToText role, content, tokens, now) + "INSERT INTO conversation_messages (user_id, chat_id, role, sender_name, content, tokens_estimate, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)" + (uid, chatId, roleToText role, senderName, content, tokens, now) rowId <- SQL.lastInsertRowId conn pure ConversationMessage @@ -912,6 +926,7 @@ saveMessage uid chatId role content = do cmUserId = uid, cmChatId = chatId, cmRole = role, + cmSenderName = senderName, cmContent = content, cmTokensEstimate = tokens, cmCreatedAt = now @@ -926,7 +941,7 @@ getRecentMessages uid chatId limit = withMemoryDb <| \conn -> SQL.query conn - "SELECT id, user_id, chat_id, role, content, tokens_estimate, created_at \ + "SELECT id, user_id, chat_id, role, sender_name, content, tokens_estimate, created_at \ \FROM conversation_messages \ \WHERE user_id = ? AND chat_id = ? \ \ORDER BY created_at DESC LIMIT ?" @@ -981,7 +996,7 @@ getConversationContext uid chatId maxTokens = do formatMsg m = let prefix = case cmRole m of - UserRole -> "User: " + UserRole -> fromMaybe "User" (cmSenderName m) <> ": " AssistantRole -> "Assistant: " in prefix <> cmContent m diff --git a/Omni/Agent/Telegram.hs b/Omni/Agent/Telegram.hs index b28405e..9142b4a 100644 --- a/Omni/Agent/Telegram.hs +++ b/Omni/Agent/Telegram.hs @@ -659,7 +659,7 @@ handleAuthorizedMessage tgConfig provider engineCfg msg uid userName chatId = do in prefix <> pdfText Nothing -> tmText msg - _ <- Memory.saveMessage uid chatId Memory.UserRole userMessage + _ <- Memory.saveMessage uid chatId Memory.UserRole (Just userName) userMessage (conversationContext, contextTokens) <- Memory.getConversationContext uid chatId maxConversationTokens putText <| "Conversation context: " <> tshow contextTokens <> " tokens" @@ -725,7 +725,7 @@ handleAuthorizedMessage tgConfig provider engineCfg msg uid userName chatId = do let response = Engine.resultFinalMessage agentResult putText <| "Response text: " <> Text.take 200 response - _ <- Memory.saveMessage uid chatId Memory.AssistantRole response + _ <- Memory.saveMessage uid chatId Memory.AssistantRole Nothing response if Text.null response then do |
