code_mesh_core/session/
manager.rs

1//! Session management implementation
2
3use super::{Session, Message, MessageRole};
4use crate::storage::Storage;
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8/// Session manager for handling multiple sessions
9pub struct SessionManager {
10    storage: Box<dyn Storage>,
11    active_sessions: HashMap<String, Session>,
12}
13
14impl SessionManager {
15    pub fn new(storage: Box<dyn Storage>) -> Self {
16        Self {
17            storage,
18            active_sessions: HashMap::new(),
19        }
20    }
21    
22    /// Create a new session
23    pub async fn create_session(&mut self) -> crate::Result<Session> {
24        let session = Session::new();
25        self.active_sessions.insert(session.id.clone(), session.clone());
26        
27        // Persist to storage
28        self.save_session(&session).await?;
29        
30        Ok(session)
31    }
32    
33    /// Get a session by ID
34    pub async fn get_session(&mut self, id: &str) -> crate::Result<Option<Session>> {
35        // Check active sessions first
36        if let Some(session) = self.active_sessions.get(id) {
37            return Ok(Some(session.clone()));
38        }
39        
40        // Try loading from storage
41        if let Some(data) = self.storage.get(&format!("session:{}", id)).await? {
42            let session: Session = serde_json::from_slice(&data)?;
43            self.active_sessions.insert(id.to_string(), session.clone());
44            Ok(Some(session))
45        } else {
46            Ok(None)
47        }
48    }
49    
50    /// List all sessions
51    pub async fn list_sessions(&self) -> crate::Result<Vec<SessionInfo>> {
52        let keys = self.storage.list(Some("session:")).await?;
53        let mut sessions = Vec::new();
54        
55        for key in keys {
56            if let Some(data) = self.storage.get(&key).await? {
57                if let Ok(session) = serde_json::from_slice::<Session>(&data) {
58                    sessions.push(SessionInfo {
59                        id: session.id.clone(),
60                        created_at: session.created_at,
61                        updated_at: session.updated_at,
62                        title: session.metadata.title.clone(),
63                        message_count: session.messages.len(),
64                    });
65                }
66            }
67        }
68        
69        sessions.sort_by(|a, b| b.updated_at.cmp(&a.updated_at));
70        Ok(sessions)
71    }
72    
73    /// Add a message to a session
74    pub async fn add_message(
75        &mut self,
76        session_id: &str,
77        role: MessageRole,
78        content: String,
79    ) -> crate::Result<Message> {
80        let message = Message::new(role, content);
81        
82        // Update session
83        {
84            let session = self.get_session_mut(session_id)?;
85            session.add_message(message.clone());
86        }
87        
88        // Persist changes
89        if let Some(session) = self.active_sessions.get(session_id) {
90            self.save_session(session).await?;
91        }
92        
93        Ok(message)
94    }
95    
96    /// Continue the last session
97    pub async fn continue_last_session(&mut self) -> crate::Result<Option<Session>> {
98        let sessions = self.list_sessions().await?;
99        if let Some(info) = sessions.first() {
100            self.get_session(&info.id).await
101        } else {
102            Ok(None)
103        }
104    }
105    
106    /// Save session to storage
107    async fn save_session(&self, session: &Session) -> crate::Result<()> {
108        let key = format!("session:{}", session.id);
109        let data = serde_json::to_vec(session)?;
110        self.storage.set(&key, &data).await?;
111        Ok(())
112    }
113    
114    /// Get mutable session reference
115    fn get_session_mut(&mut self, id: &str) -> crate::Result<&mut Session> {
116        self.active_sessions.get_mut(id)
117            .ok_or_else(|| crate::Error::Session(format!("Session {} not found", id)))
118    }
119}
120
121/// Session summary information
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct SessionInfo {
124    pub id: String,
125    pub created_at: chrono::DateTime<chrono::Utc>,
126    pub updated_at: chrono::DateTime<chrono::Utc>,
127    pub title: Option<String>,
128    pub message_count: usize,
129}