mod atomic;
mod checksum;
mod recovery;
mod retry;
mod writer;
pub use atomic::AtomicFileWriter;
pub use checksum::ChecksumUtils;
pub use recovery::CrashRecovery;
pub use retry::{
ErrorCategory, ErrorRecovery, FallbackStrategy, InterruptedSession, RecoveryAction,
RecoveryLayer, RecoveryResult, RetryPolicy, SessionRecovery,
};
pub use writer::CheckpointWriter;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use std::path::Path;
use crate::types::{CheckpointId, CheckpointMeta, Layer2Result, SessionId};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CheckpointData {
pub checkpoint_id: CheckpointId,
pub session_id: SessionId,
pub created_at: chrono::DateTime<chrono::Utc>,
pub trigger: String,
pub iteration: i32,
pub messages: Vec<serde_json::Value>,
pub tool_calls_pending: Vec<serde_json::Value>,
pub tool_results: serde_json::Value,
pub tokens_used: i64,
pub cost_estimate: f64,
pub resume_hint: Option<String>,
}
#[async_trait]
pub trait CheckpointSystemTrait: Send + Sync {
async fn save(&self, data: &CheckpointData) -> Layer2Result<CheckpointId>;
async fn load(
&self,
session_id: &SessionId,
checkpoint_id: Option<&CheckpointId>,
) -> Layer2Result<Option<CheckpointData>>;
async fn list(&self, session_id: &SessionId) -> Layer2Result<Vec<CheckpointMeta>>;
async fn delete(
&self,
session_id: &SessionId,
checkpoint_id: &CheckpointId,
) -> Layer2Result<bool>;
fn verify(&self, path: &Path) -> Layer2Result<bool>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_checkpoint_data_creation() {
let data = CheckpointData {
checkpoint_id: CheckpointId::new(),
session_id: SessionId::new(),
created_at: chrono::Utc::now(),
trigger: "manual".to_string(),
iteration: 0,
messages: Vec::new(),
tool_calls_pending: Vec::new(),
tool_results: serde_json::Value::Null,
tokens_used: 0,
cost_estimate: 0.0,
resume_hint: None,
};
assert_eq!(data.trigger, "manual");
}
}