use std::sync::Arc; use chrono::Utc; use db::cache::AppCache; use db::database::AppDatabase; use models::rooms::room_message; use queue::MessageProducer; use sea_orm::{EntityTrait, Set}; use uuid::Uuid; use super::sequence::next_room_message_seq_internal; use crate::connection::RoomConnectionManager; use crate::error::RoomError; pub async fn create_and_publish_ai_message( db: &AppDatabase, cache: &AppCache, queue: &MessageProducer, room_manager: &Arc, room_id: Uuid, project_id: Uuid, _reply_to: Uuid, content: String, model_id: Uuid, model_display_name: Option, ) -> Result { let now = Utc::now(); let seq = next_room_message_seq_internal(room_id, db, cache).await?; let id = Uuid::now_v7(); let envelope = queue::RoomMessageEnvelope { id, dedup_key: Some(format!("{}:{}", room_id, id)), room_id, sender_type: "ai".to_string(), sender_id: None, model_id: Some(model_id), thread_id: None, content: content.clone(), content_type: "text".to_string(), thinking_content: None, send_at: now, seq, in_reply_to: None, display_name: model_display_name.clone(), }; room_message::Entity::insert(room_message::ActiveModel { id: Set(id), seq: Set(seq), room: Set(room_id), sender_type: Set(models::rooms::MessageSenderType::Ai), sender_id: Set(None), model_id: Set(Some(model_id)), thread: Set(None), content: Set(content.clone()), content_type: Set(models::rooms::MessageContentType::Text), thinking_content: Set(None), edited_at: Set(None), send_at: Set(now), revoked: Set(None), revoked_by: Set(None), in_reply_to: Set(None), }) .exec(db) .await?; queue.publish(room_id, envelope).await?; room_manager.metrics.messages_sent.increment(1); let event = queue::RoomMessageEvent { id, room_id, sender_type: "ai".to_string(), sender_id: None, thread_id: None, content: content.clone(), content_type: "text".to_string(), thinking_content: None, send_at: now, seq, display_name: model_display_name, in_reply_to: None, reactions: None, message_id: None, }; room_manager.broadcast(room_id, event).await; super::notifications::publish_room_event( queue, project_id, crate::RoomEventType::NewMessage, Some(room_id), Some(id), Some(seq), ); Ok(id) }