diff --git a/crates/goose/src/context_mgmt/auto_compact.rs b/crates/goose/src/context_mgmt/auto_compact.rs index 01941af6141c..8977a3fd5897 100644 --- a/crates/goose/src/context_mgmt/auto_compact.rs +++ b/crates/goose/src/context_mgmt/auto_compact.rs @@ -317,8 +317,8 @@ mod tests { id: "test_session".to_string(), working_dir: PathBuf::from(working_dir), description: "Test session".to_string(), - created_at: "2024-01-01T00:00:00Z".to_string(), - updated_at: "2024-01-01T00:00:00Z".to_string(), + created_at: Default::default(), + updated_at: Default::default(), schedule_id: Some("test_job".to_string()), recipe: None, total_tokens: Some(100), diff --git a/crates/goose/src/session/legacy.rs b/crates/goose/src/session/legacy.rs index 3de432ce8228..ad05356fcbcf 100644 --- a/crates/goose/src/session/legacy.rs +++ b/crates/goose/src/session/legacy.rs @@ -1,7 +1,7 @@ use crate::conversation::Conversation; use crate::session::Session; use anyhow::Result; -use chrono::NaiveDateTime; +use chrono::{DateTime, Local, NaiveDateTime, TimeZone, Utc}; use std::fs; use std::io::{self, BufRead}; use std::path::{Path, PathBuf}; @@ -65,9 +65,9 @@ pub fn load_session(session_name: &str, session_path: &Path) -> Result if let Some(obj) = metadata_json.as_object_mut() { obj.entry("id").or_insert(serde_json::json!(session_name)); obj.entry("created_at") - .or_insert(serde_json::json!(format_timestamp(created_time)?)); + .or_insert(serde_json::json!(DateTime::::from(created_time))); obj.entry("updated_at") - .or_insert(serde_json::json!(format_timestamp(modified_time)?)); + .or_insert(serde_json::json!(DateTime::::from(modified_time))); obj.entry("extension_data").or_insert(serde_json::json!({})); obj.entry("message_count").or_insert(serde_json::json!(0)); @@ -97,17 +97,9 @@ pub fn load_session(session_name: &str, session_path: &Path) -> Result Ok(session) } -fn format_timestamp(time: SystemTime) -> Result { - let duration = time.duration_since(std::time::UNIX_EPOCH)?; - let timestamp = chrono::DateTime::from_timestamp(duration.as_secs() as i64, 0) - .unwrap_or_default() - .format("%Y-%m-%d %H:%M:%S") - .to_string(); - Ok(timestamp) -} - fn parse_session_timestamp(session_name: &str) -> Option { NaiveDateTime::parse_from_str(session_name, "%Y%m%d_%H%M%S") .ok() - .map(|dt| SystemTime::from(dt.and_utc())) + .and_then(|dt| Local.from_local_datetime(&dt).single()) + .map(SystemTime::from) } diff --git a/crates/goose/src/session/session_manager.rs b/crates/goose/src/session/session_manager.rs index 9a31c4ea43e0..beee202bb686 100644 --- a/crates/goose/src/session/session_manager.rs +++ b/crates/goose/src/session/session_manager.rs @@ -5,6 +5,7 @@ use crate::providers::base::{Provider, MSG_COUNT_FOR_SESSION_NAME_GENERATION}; use crate::recipe::Recipe; use crate::session::extension_data::ExtensionData; use anyhow::Result; +use chrono::{DateTime, Utc}; use etcetera::{choose_app_strategy, AppStrategy}; use rmcp::model::Role; use serde::{Deserialize, Serialize}; @@ -27,8 +28,8 @@ pub struct Session { #[schema(value_type = String)] pub working_dir: PathBuf, pub description: String, - pub created_at: String, - pub updated_at: String, + pub created_at: DateTime, + pub updated_at: DateTime, pub extension_data: ExtensionData, pub total_tokens: Option, pub input_tokens: Option, @@ -279,8 +280,8 @@ impl Default for Session { id: String::new(), working_dir: std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")), description: String::new(), - created_at: String::new(), - updated_at: String::new(), + created_at: Default::default(), + updated_at: Default::default(), extension_data: ExtensionData::default(), total_tokens: None, input_tokens: None, @@ -510,8 +511,8 @@ impl SessionStorage { .bind(&session.id) .bind(&session.description) .bind(session.working_dir.to_string_lossy().as_ref()) - .bind(&session.created_at) - .bind(&session.updated_at) + .bind(session.created_at) + .bind(session.updated_at) .bind(serde_json::to_string(&session.extension_data)?) .bind(session.total_tokens) .bind(session.input_tokens) diff --git a/crates/goose/src/temporal_scheduler.rs b/crates/goose/src/temporal_scheduler.rs index 955443453279..d10061efc185 100644 --- a/crates/goose/src/temporal_scheduler.rs +++ b/crates/goose/src/temporal_scheduler.rs @@ -851,25 +851,18 @@ impl TemporalScheduler { if let Some(session_info) = all_sessions.iter().find(|s| s.id == session_id) { - // Parse the updated_at timestamp from the database - if let Ok(modified_dt) = DateTime::parse_from_str( - &session_info.updated_at, - "%Y-%m-%d %H:%M:%S UTC", - ) { - let modified_utc = modified_dt.with_timezone(&Utc); - let now = Utc::now(); - let time_diff = now.signed_duration_since(modified_utc); - - // Increased tolerance to 5 minutes to reduce false positives - if time_diff.num_minutes() < 5 { - has_active_session = true; - tracing::debug!( + let now = Utc::now(); + let time_diff = now.signed_duration_since(session_info.updated_at); + + // Increased tolerance to 5 minutes to reduce false positives + if time_diff.num_minutes() < 5 { + has_active_session = true; + tracing::debug!( "Found active session for job '{}' modified {} minutes ago", job.id, time_diff.num_minutes() ); - break; - } + break; } } } diff --git a/crates/goose/tests/test_support.rs b/crates/goose/tests/test_support.rs index d53319477ddf..c84ecd3e8eb1 100644 --- a/crates/goose/tests/test_support.rs +++ b/crates/goose/tests/test_support.rs @@ -382,7 +382,7 @@ pub fn create_test_session_metadata(message_count: usize, working_dir: &str) -> id: "".to_string(), working_dir: PathBuf::from(working_dir), description: "Test session".to_string(), - created_at: "".to_string(), + created_at: Default::default(), schedule_id: Some("test_job".to_string()), recipe: None, total_tokens: Some(100), @@ -392,7 +392,7 @@ pub fn create_test_session_metadata(message_count: usize, working_dir: &str) -> accumulated_input_tokens: Some(50), accumulated_output_tokens: Some(50), extension_data: Default::default(), - updated_at: "".to_string(), + updated_at: Default::default(), conversation: None, message_count, } diff --git a/ui/desktop/openapi.json b/ui/desktop/openapi.json index 296ec589f14f..702866d6b8cb 100644 --- a/ui/desktop/openapi.json +++ b/ui/desktop/openapi.json @@ -3590,7 +3590,8 @@ "nullable": true }, "created_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "description": { "type": "string" @@ -3633,7 +3634,8 @@ "nullable": true }, "updated_at": { - "type": "string" + "type": "string", + "format": "date-time" }, "working_dir": { "type": "string"