use anyhow::Result;
use chrono::{DateTime, Utc};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::time::Duration;
use uuid::Uuid;
use super::traits::*;
use crate::agent::{Task, TaskResult};
pub struct BaseSession {
id: String,
session_type: String,
status: SessionStatus,
created_at: DateTime<Utc>,
last_activity: DateTime<Utc>,
working_directory: PathBuf,
env_vars: HashMap<String, String>,
stats: EfficiencyStats,
tasks_completed: usize,
}
impl BaseSession {
pub fn new(config: SessionConfig) -> Self {
let id = format!("session-{}", Uuid::new_v4());
let working_directory = config
.working_directory
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("."));
let mut env_vars = config.env_vars;
env_vars.extend(<Self as SessionEnvironment>::create_env_vars(
&config.agent_id,
&id,
));
Self {
id,
session_type: "base".to_string(),
status: SessionStatus::Initializing,
created_at: Utc::now(),
last_activity: Utc::now(),
working_directory,
env_vars,
stats: EfficiencyStats::default(),
tasks_completed: 0,
}
}
pub fn set_session_type(&mut self, session_type: String) {
self.session_type = session_type;
}
}
impl SessionLifecycle for BaseSession {
async fn initialize(&mut self) -> Result<()> {
self.status = SessionStatus::Active;
self.touch();
Ok(())
}
async fn shutdown(&mut self) -> Result<()> {
self.status = SessionStatus::Terminating;
self.status = SessionStatus::Terminated;
Ok(())
}
fn get_status(&self) -> SessionStatus {
self.status
}
fn update_status(&mut self, status: SessionStatus) {
self.status = status;
self.touch();
}
}
#[async_trait::async_trait]
impl TaskExecutor for BaseSession {
async fn execute_task(&mut self, task: Task) -> Result<TaskResult> {
self.update_status(SessionStatus::Busy);
let start_time = std::time::Instant::now();
tokio::time::sleep(Duration::from_millis(100)).await;
let result = TaskResult {
success: true,
output: serde_json::json!({
"task_id": task.id,
"message": "Task completed"
}),
error: None,
duration: start_time.elapsed(),
};
let duration = start_time.elapsed();
self.update_task_stats(&result, duration);
self.update_status(SessionStatus::Active);
Ok(result)
}
}
impl SessionMetadata for BaseSession {
fn get_id(&self) -> &str {
&self.id
}
fn get_created_at(&self) -> DateTime<Utc> {
self.created_at
}
fn get_last_activity(&self) -> DateTime<Utc> {
self.last_activity
}
fn touch(&mut self) {
self.last_activity = Utc::now();
}
fn get_session_type(&self) -> &str {
&self.session_type
}
}
impl SessionEnvironment for BaseSession {
fn get_working_directory(&self) -> &Path {
&self.working_directory
}
fn get_env_vars(&self) -> &HashMap<String, String> {
&self.env_vars
}
}
impl SessionStatistics for BaseSession {
fn get_tasks_completed(&self) -> usize {
self.tasks_completed
}
fn get_efficiency_stats(&self) -> EfficiencyStats {
self.stats.clone()
}
fn update_task_stats(&mut self, result: &TaskResult, duration: Duration) {
self.stats.total_tasks += 1;
if result.success {
self.stats.successful_tasks += 1;
} else {
self.stats.failed_tasks += 1;
}
self.stats.total_duration += duration;
if self.stats.total_tasks > 0 {
self.stats.average_task_duration =
self.stats.total_duration / self.stats.total_tasks as u32;
}
self.tasks_completed += 1;
self.touch();
}
fn reset_stats(&mut self) {
self.stats = EfficiencyStats::default();
self.tasks_completed = 0;
}
}
impl Session for BaseSession {}
pub struct GenericSessionManager<S: Session + 'static> {
_sessions:
std::sync::Arc<tokio::sync::Mutex<HashMap<String, std::sync::Arc<tokio::sync::Mutex<S>>>>>,
_phantom: std::marker::PhantomData<S>,
}
impl<S: Session + 'static> GenericSessionManager<S> {
pub fn new() -> Self {
Self {
_sessions: std::sync::Arc::new(tokio::sync::Mutex::new(HashMap::new())),
_phantom: std::marker::PhantomData,
}
}
}
impl<S: Session + 'static> Default for GenericSessionManager<S> {
fn default() -> Self {
Self::new()
}
}