use arc_swap::{ArcSwap, ArcSwapOption};
use std::sync::Arc;
use std::time::SystemTime;
use super::execution_history::HarnessContextSnapshot;
#[derive(Clone)]
pub struct HarnessContext {
session_id: Arc<ArcSwap<String>>,
task_id: Arc<ArcSwapOption<String>>,
pub(super) decision_validator:
Arc<parking_lot::RwLock<Option<crate::core::agent::events::DecisionEvidenceValidator>>>,
}
impl std::fmt::Debug for HarnessContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("HarnessContext")
.field("session_id", &self.session_id())
.field("task_id", &self.task_id())
.finish_non_exhaustive()
}
}
impl Default for HarnessContext {
fn default() -> Self {
let session_id = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.map(|d| format!("session-{}", d.as_millis()))
.unwrap_or_else(|_| "session-unknown".to_string());
Self {
session_id: Arc::new(ArcSwap::from_pointee(session_id)),
task_id: Arc::new(ArcSwapOption::empty()),
decision_validator: Arc::default(),
}
}
}
impl HarnessContext {
pub fn with_session(session_id: impl Into<String>) -> Self {
Self {
session_id: Arc::new(ArcSwap::from_pointee(session_id.into())),
task_id: Arc::new(ArcSwapOption::empty()),
decision_validator: Arc::default(),
}
}
pub fn set_session_id(&self, session_id: impl Into<String>) {
self.session_id.store(Arc::new(session_id.into()));
}
pub fn set_task_id(&self, task_id: Option<String>) {
self.task_id.store(task_id.map(Arc::new));
}
pub fn session_id(&self) -> String {
self.session_id.load().as_ref().clone()
}
pub fn task_id(&self) -> Option<String> {
self.task_id.load_full().map(|task_id| (*task_id).clone())
}
pub fn snapshot(&self) -> HarnessContextSnapshot {
HarnessContextSnapshot::new(self.session_id(), self.task_id())
}
}