use async_trait::async_trait;
use serde::{Deserialize, Serialize};
#[cfg(feature = "session")]
use chrono::{DateTime, Utc};
#[cfg(feature = "session")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Session {
pub id: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub directory: String,
pub messages: Vec<SessionMessage>,
}
#[cfg(feature = "session")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionMessage {
pub role: MessageRole,
pub content: String,
#[serde(default)]
pub tool_calls: Vec<ToolCall>,
#[serde(default)]
pub tool_results: Vec<ToolResult>,
pub timestamp: DateTime<Utc>,
}
#[cfg(feature = "session")]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum MessageRole {
User,
Assistant,
System,
}
#[cfg(feature = "session")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolCall {
pub id: String,
pub name: String,
pub input: String,
}
#[cfg(feature = "session")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ToolResult {
pub tool_use_id: String,
pub success: bool,
pub content: String,
}
#[cfg(feature = "session")]
#[async_trait]
pub trait SessionStore: Send + Sync {
async fn get_or_create_session(&self) -> Result<Session, SessionError>;
async fn get_session(&self, id: &str) -> Result<Option<Session>, SessionError>;
async fn save_session(&self, session: &Session) -> Result<(), SessionError>;
async fn list_sessions(&self) -> Result<Vec<SessionSummary>, SessionError>;
async fn delete_session(&self, id: &str) -> Result<(), SessionError>;
}
#[cfg(feature = "session")]
#[derive(Debug, Clone)]
pub struct SessionSummary {
pub id: String,
pub directory: String,
pub message_count: usize,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
}
#[derive(Debug, thiserror::Error)]
pub enum SessionError {
#[error("Storage error: {0}")]
Storage(String),
#[error("Session not found: {0}")]
NotFound(String),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
}