summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Sima <ben@bensima.com>2025-12-12 20:42:30 -0500
committerBen Sima <ben@bensima.com>2025-12-12 20:42:30 -0500
commitfd1c5c2bda7831c6cf329f4dc272064a352609e1 (patch)
treefc2b28901955189ba15777b0e2fc4eccac7fe103
parenta9d7f9434b370f4dd79ac40c606c91d3e3d9716b (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
-rw-r--r--Omni/Agent/Memory.hs27
-rw-r--r--Omni/Agent/Telegram.hs4
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