Skip to main content

a3s_code_core/store/
mod.rs

1//! Session persistence layer
2//!
3//! Provides pluggable session storage via the `SessionStore` trait.
4//!
5//! ## Default Implementation
6//!
7//! `FileSessionStore` stores each session as a JSON file:
8//! - Session metadata (id, name, timestamps)
9//! - Configuration (system prompt, policies)
10//! - Conversation history (messages)
11//! - Context usage statistics
12//!
13//! ## Custom Backends
14//!
15//! Implement `SessionStore` trait for custom backends (Redis, PostgreSQL, etc.):
16//!
17//! ```ignore
18//! use a3s_code::store::{SessionStore, SessionData};
19//!
20//! struct RedisStore { /* ... */ }
21//!
22//! #[async_trait::async_trait]
23//! impl SessionStore for RedisStore {
24//!     async fn save(&self, session: &SessionData) -> Result<()> { /* ... */ }
25//!     async fn load(&self, id: &str) -> Result<Option<SessionData>> { /* ... */ }
26//!     async fn delete(&self, id: &str) -> Result<()> { /* ... */ }
27//!     async fn list(&self) -> Result<Vec<String>> { /* ... */ }
28//!     async fn exists(&self, id: &str) -> Result<bool> { /* ... */ }
29//! }
30//! ```
31
32mod file_store;
33mod memory_store;
34mod session_data;
35
36#[cfg(test)]
37mod tests;
38
39pub use file_store::FileSessionStore;
40pub use memory_store::MemorySessionStore;
41pub use session_data::{
42    ContextUsage, LlmConfigData, SessionConfig, SessionData, SessionState,
43    DEFAULT_AUTO_COMPACT_THRESHOLD,
44};
45
46use crate::run::RunRecord;
47use crate::tools::ArtifactStore;
48use crate::trace::TraceEvent;
49use crate::verification::VerificationReport;
50use anyhow::Result;
51
52// ============================================================================
53// Session Store Trait
54// ============================================================================
55
56/// Session storage trait
57#[async_trait::async_trait]
58pub trait SessionStore: Send + Sync {
59    /// Save session data
60    async fn save(&self, session: &SessionData) -> Result<()>;
61
62    /// Load session data by ID
63    async fn load(&self, id: &str) -> Result<Option<SessionData>>;
64
65    /// Delete session data
66    async fn delete(&self, id: &str) -> Result<()>;
67
68    /// List all session IDs
69    async fn list(&self) -> Result<Vec<String>>;
70
71    /// Check if session exists
72    async fn exists(&self, id: &str) -> Result<bool>;
73
74    /// Save artifacts associated with a session.
75    async fn save_artifacts(&self, _id: &str, _artifacts: &ArtifactStore) -> Result<()> {
76        Ok(())
77    }
78
79    /// Load artifacts associated with a session.
80    async fn load_artifacts(&self, _id: &str) -> Result<Option<ArtifactStore>> {
81        Ok(None)
82    }
83
84    /// Save compact trace events associated with a session.
85    async fn save_trace_events(&self, _id: &str, _events: &[TraceEvent]) -> Result<()> {
86        Ok(())
87    }
88
89    /// Load compact trace events associated with a session.
90    async fn load_trace_events(&self, _id: &str) -> Result<Option<Vec<TraceEvent>>> {
91        Ok(None)
92    }
93
94    /// Save run snapshots and replayable runtime events associated with a session.
95    async fn save_run_records(&self, _id: &str, _records: &[RunRecord]) -> Result<()> {
96        Ok(())
97    }
98
99    /// Load run snapshots and replayable runtime events associated with a session.
100    async fn load_run_records(&self, _id: &str) -> Result<Option<Vec<RunRecord>>> {
101        Ok(None)
102    }
103
104    /// Save structured verification reports associated with a session.
105    async fn save_verification_reports(
106        &self,
107        _id: &str,
108        _reports: &[VerificationReport],
109    ) -> Result<()> {
110        Ok(())
111    }
112
113    /// Load structured verification reports associated with a session.
114    async fn load_verification_reports(
115        &self,
116        _id: &str,
117    ) -> Result<Option<Vec<VerificationReport>>> {
118        Ok(None)
119    }
120
121    /// Health check — verify the store backend is reachable and operational
122    async fn health_check(&self) -> Result<()> {
123        Ok(())
124    }
125
126    /// Backend name for diagnostics
127    fn backend_name(&self) -> &str {
128        "unknown"
129    }
130}