message ids

This commit is contained in:
dal 2025-03-05 10:31:35 -07:00
parent ce4a188e1f
commit 4fab757f2d
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
3 changed files with 141 additions and 59 deletions

View File

@ -119,7 +119,7 @@ pub async fn get_chat_handler(chat_id: &Uuid, user_id: &Uuid) -> Result<ChatWith
)?; )?;
// Transform messages into ThreadMessage format // Transform messages into ThreadMessage format
let thread_messages = messages let thread_messages: Vec<ChatMessage> = messages
.into_iter() .into_iter()
.map(|msg| { .map(|msg| {
let sender_avatar = msg let sender_avatar = msg
@ -148,15 +148,13 @@ pub async fn get_chat_handler(chat_id: &Uuid, user_id: &Uuid) -> Result<ChatWith
sender_avatar, sender_avatar,
}; };
let chat_message = ChatMessage::new_with_messages( ChatMessage::new_with_messages(
msg.id, msg.id,
request_message, request_message,
response_messages, response_messages,
reasoning, reasoning,
None, None,
); )
chat_message
}) })
.collect(); .collect();
@ -167,17 +165,14 @@ pub async fn get_chat_handler(chat_id: &Uuid, user_id: &Uuid) -> Result<ChatWith
.and_then(|v| v.as_str()) .and_then(|v| v.as_str())
.map(String::from); .map(String::from);
// Construct and return the ThreadWithMessages // Construct and return the ThreadWithMessages using new_with_messages
Ok(ChatWithMessages { Ok(ChatWithMessages::new_with_messages(
id: thread.id, thread.id,
title: thread.title, thread.title,
is_favorited: false, // Not implemented in current schema thread_messages,
messages: thread_messages, false, // is_favorited not implemented in current schema
created_at: thread.created_at.to_string(), thread.user_id.to_string(),
updated_at: thread.updated_at.to_string(), thread.user_name.unwrap_or_else(|| "Unknown".to_string()),
created_by: thread.user_email,
created_by_id: thread.user_id.to_string(),
created_by_name: thread.user_name.unwrap_or_else(|| "Unknown".to_string()),
created_by_avatar, created_by_avatar,
}) ))
} }

View File

@ -301,20 +301,23 @@ pub async fn post_chat_handler(
prepare_final_message_state(&all_transformed_containers)?; prepare_final_message_state(&all_transformed_containers)?;
// Update chat_with_messages with final state // Update chat_with_messages with final state
if let Some(chat_message) = chat_with_messages.messages.first_mut() { let message = ChatMessage::new_with_messages(
*chat_message = ChatMessage::new_with_messages( message_id,
message_id, ChatUserMessage {
chat_message.request_message.clone(), request: request.prompt.clone(),
response_messages.clone(), sender_id: user.id.clone(),
reasoning_messages.clone(), sender_name: user.name.clone().unwrap_or_default(),
None, sender_avatar: None,
); },
} response_messages.clone(),
reasoning_messages.clone(),
Some(format!("Reasoned for {} seconds", reasoning_duration).to_string()),
);
let final_reasoning_message = format!("Reasoned for {} seconds", reasoning_duration); chat_with_messages.update_message(message);
// Create and store message in the database with final state // Create and store message in the database with final state
let message = Message { let db_message = Message {
id: message_id, id: message_id,
request_message: request.prompt, request_message: request.prompt,
chat_id, chat_id,
@ -324,20 +327,20 @@ pub async fn post_chat_handler(
deleted_at: None, deleted_at: None,
response_messages: serde_json::to_value(&response_messages)?, response_messages: serde_json::to_value(&response_messages)?,
reasoning: serde_json::to_value(&reasoning_messages)?, reasoning: serde_json::to_value(&reasoning_messages)?,
final_reasoning_message, final_reasoning_message: format!("Reasoned for {} seconds", reasoning_duration),
title: title.title.clone().unwrap_or_default(), title: title.title.clone().unwrap_or_default(),
raw_llm_messages: serde_json::to_value(&raw_llm_messages)?, raw_llm_messages: serde_json::to_value(&raw_llm_messages)?,
}; };
// Insert message into database // Insert message into database
insert_into(messages::table) insert_into(messages::table)
.values(&message) .values(&db_message)
.execute(&mut conn) .execute(&mut conn)
.await?; .await?;
// First process completed files (database updates only) // First process completed files (database updates only)
let _ = let _ =
process_completed_files(&mut conn, &message, &all_messages, &user_org_id, &user.id).await?; process_completed_files(&mut conn, &db_message, &all_messages, &user_org_id, &user.id).await?;
// Then send text response messages // Then send text response messages
if let Some(tx) = &tx { if let Some(tx) = &tx {
@ -1619,8 +1622,8 @@ async fn initialize_chat(
// Get existing chat - no need to create new chat in DB // Get existing chat - no need to create new chat in DB
let mut existing_chat = get_chat_handler(&existing_chat_id, &user.id).await?; let mut existing_chat = get_chat_handler(&existing_chat_id, &user.id).await?;
// Add new message to existing chat // Create new message
existing_chat.messages.push(ChatMessage::new_with_messages( let message = ChatMessage::new_with_messages(
message_id, message_id,
ChatUserMessage { ChatUserMessage {
request: request.prompt.clone(), request: request.prompt.clone(),
@ -1631,7 +1634,10 @@ async fn initialize_chat(
Vec::new(), Vec::new(),
Vec::new(), Vec::new(),
None, None,
)); );
// Add message to existing chat
existing_chat.add_message(message);
Ok((existing_chat_id, message_id, existing_chat)) Ok((existing_chat_id, message_id, existing_chat))
} else { } else {
@ -1648,29 +1654,28 @@ async fn initialize_chat(
updated_by: user.id.clone(), updated_by: user.id.clone(),
}; };
let chat_with_messages = ChatWithMessages { // Create initial message
id: chat_id, let message = ChatMessage::new_with_messages(
title: request.prompt.clone(), message_id,
is_favorited: false, ChatUserMessage {
messages: vec![ChatMessage::new_with_messages( request: request.prompt.clone(),
message_id, sender_id: user.id.clone(),
ChatUserMessage { sender_name: user.name.clone().unwrap_or_default(),
request: request.prompt.clone(), sender_avatar: None,
sender_id: user.id.clone(), },
sender_name: user.name.clone().unwrap_or_default(), Vec::new(),
sender_avatar: None, Vec::new(),
}, None,
Vec::new(), );
Vec::new(),
None, let mut chat_with_messages = ChatWithMessages::new(
)], request.prompt.clone(),
created_at: Utc::now().to_string(), user.id.to_string(),
updated_at: Utc::now().to_string(), user.name.clone().unwrap_or_default(),
created_by: user.id.to_string(), None,
created_by_id: user.id.to_string(), );
created_by_name: user.name.clone().unwrap_or_default(), chat_with_messages.id = chat_id;
created_by_avatar: None, chat_with_messages.add_message(message);
};
// Only create new chat in DB if this is a new chat // Only create new chat in DB if this is a new chat
let mut conn = get_pg_pool().get().await?; let mut conn = get_pg_pool().get().await?;

View File

@ -1,3 +1,5 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid; use uuid::Uuid;
@ -8,7 +10,8 @@ pub struct ChatWithMessages {
pub id: Uuid, pub id: Uuid,
pub title: String, pub title: String,
pub is_favorited: bool, pub is_favorited: bool,
pub messages: Vec<ChatMessage>, pub message_ids: Vec<String>,
pub messages: HashMap<String, ChatMessage>,
pub created_at: String, pub created_at: String,
pub updated_at: String, pub updated_at: String,
pub created_by: String, pub created_by: String,
@ -17,3 +20,82 @@ pub struct ChatWithMessages {
pub created_by_avatar: Option<String>, pub created_by_avatar: Option<String>,
} }
impl ChatWithMessages {
pub fn new(
title: String,
created_by_id: String,
created_by_name: String,
created_by_avatar: Option<String>,
) -> Self {
let now = chrono::Utc::now().to_rfc3339();
Self {
id: uuid::Uuid::new_v4(),
title,
is_favorited: false,
message_ids: Vec::new(),
messages: HashMap::new(),
created_at: now.clone(),
updated_at: now,
created_by: created_by_id.clone(),
created_by_id,
created_by_name,
created_by_avatar,
}
}
pub fn new_with_messages(
id: uuid::Uuid,
title: String,
messages: Vec<ChatMessage>,
is_favorited: bool,
created_by_id: String,
created_by_name: String,
created_by_avatar: Option<String>,
) -> Self {
let now = chrono::Utc::now().to_rfc3339();
// Convert messages into a HashMap and collect their IDs
let message_ids: Vec<String> = messages.iter()
.map(|msg| msg.id.to_string())
.collect();
let messages_map: HashMap<String, ChatMessage> = messages.into_iter()
.map(|msg| (msg.id.to_string(), msg))
.collect();
Self {
id,
title,
is_favorited,
message_ids,
messages: messages_map,
created_at: now.clone(),
updated_at: now,
created_by: created_by_id.clone(),
created_by_id,
created_by_name,
created_by_avatar,
}
}
pub fn add_message(&mut self, message: ChatMessage) {
let message_id = message.id.to_string();
if !self.message_ids.contains(&message_id) {
self.message_ids.push(message_id.clone());
}
self.messages.insert(message_id, message);
self.updated_at = chrono::Utc::now().to_rfc3339();
}
pub fn update_message(&mut self, message: ChatMessage) {
let message_id = message.id.to_string();
if !self.message_ids.contains(&message_id) {
self.message_ids.push(message_id.clone());
}
self.messages.insert(message_id, message);
self.updated_at = chrono::Utc::now().to_rfc3339();
}
}