code_mesh_core/session/
mod.rs

1//! Session management for Code Mesh
2
3use crate::llm::Message as LlmMessage;
4use serde::{Deserialize, Serialize};
5use uuid::Uuid;
6use chrono::{DateTime, Utc};
7
8pub mod manager;
9pub use manager::{SessionManager, SessionInfo};
10
11/// Session represents a conversation with the AI
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct Session {
14    pub id: String,
15    pub created_at: DateTime<Utc>,
16    pub updated_at: DateTime<Utc>,
17    pub messages: Vec<Message>,
18    pub metadata: SessionMetadata,
19}
20
21impl Session {
22    /// Create a new session
23    pub fn new() -> Self {
24        let now = Utc::now();
25        Self {
26            id: format!("session_{}", Uuid::new_v4()),
27            created_at: now,
28            updated_at: now,
29            messages: Vec::new(),
30            metadata: SessionMetadata::default(),
31        }
32    }
33    
34    /// Add a message to the session
35    pub fn add_message(&mut self, message: Message) {
36        self.messages.push(message);
37        self.updated_at = Utc::now();
38    }
39    
40    /// Get messages as LLM format
41    pub fn to_llm_messages(&self) -> Vec<LlmMessage> {
42        self.messages.iter().map(|m| m.to_llm_message()).collect()
43    }
44}
45
46impl Default for Session {
47    fn default() -> Self {
48        Self::new()
49    }
50}
51
52/// Message in a session
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct Message {
55    pub id: String,
56    pub role: MessageRole,
57    pub content: String,
58    pub timestamp: DateTime<Utc>,
59    pub metadata: MessageMetadata,
60}
61
62impl Message {
63    pub fn new(role: MessageRole, content: String) -> Self {
64        Self {
65            id: format!("msg_{}", Uuid::new_v4()),
66            role,
67            content,
68            timestamp: Utc::now(),
69            metadata: MessageMetadata::default(),
70        }
71    }
72    
73    pub fn to_llm_message(&self) -> LlmMessage {
74        LlmMessage {
75            role: match self.role {
76                MessageRole::System => crate::llm::MessageRole::System,
77                MessageRole::User => crate::llm::MessageRole::User,
78                MessageRole::Assistant => crate::llm::MessageRole::Assistant,
79                MessageRole::Tool => crate::llm::MessageRole::Tool,
80            },
81            content: crate::llm::MessageContent::Text(self.content.clone()),
82            name: None,
83            tool_calls: None,
84            tool_call_id: None,
85        }
86    }
87}
88
89#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
90#[serde(rename_all = "lowercase")]
91pub enum MessageRole {
92    System,
93    User,
94    Assistant,
95    Tool,
96}
97
98#[derive(Debug, Clone, Default, Serialize, Deserialize)]
99pub struct SessionMetadata {
100    pub title: Option<String>,
101    pub mode: Option<String>,
102    pub model: Option<String>,
103    pub provider: Option<String>,
104    pub tags: Vec<String>,
105}
106
107#[derive(Debug, Clone, Default, Serialize, Deserialize)]
108pub struct MessageMetadata {
109    pub tokens_used: Option<TokenUsage>,
110    pub tool_calls: Vec<ToolCall>,
111    pub error: Option<String>,
112}
113
114#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
115pub struct TokenUsage {
116    pub prompt: u32,
117    pub completion: u32,
118    pub total: u32,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct ToolCall {
123    pub id: String,
124    pub name: String,
125    pub arguments: serde_json::Value,
126    pub result: Option<serde_json::Value>,
127}