starweaver_session/
store.rs1mod contract;
4mod memory;
5
6use std::sync::Arc;
7
8use async_trait::async_trait;
9use starweaver_context::{
10 AgentCheckpoint, AgentExecutionDecision, AgentExecutor, AgentExecutorError,
11};
12use starweaver_core::SessionId;
13
14use crate::RunAdmissionLease;
15
16pub use contract::{
17 InteractionPage, InteractionPageKey, InteractionPageQuery, MAX_STABLE_PAGE_SIZE, SessionFilter,
18 SessionPage, SessionPageKey, SessionPageQuery, SessionStore,
19};
20pub use memory::InMemorySessionStore;
21
22#[derive(Clone)]
24pub struct SessionStoreExecutor {
25 store: Arc<dyn SessionStore>,
26 session_id: SessionId,
27 admission_lease: Option<RunAdmissionLease>,
28}
29
30impl SessionStoreExecutor {
31 #[must_use]
33 pub fn new(store: Arc<dyn SessionStore>, session_id: SessionId) -> Self {
34 Self {
35 store,
36 session_id,
37 admission_lease: None,
38 }
39 }
40
41 #[must_use]
43 pub fn new_fenced(
44 store: Arc<dyn SessionStore>,
45 session_id: SessionId,
46 admission_lease: RunAdmissionLease,
47 ) -> Self {
48 Self {
49 store,
50 session_id,
51 admission_lease: Some(admission_lease),
52 }
53 }
54
55 #[must_use]
57 pub const fn session_id(&self) -> &SessionId {
58 &self.session_id
59 }
60}
61
62#[async_trait]
63impl AgentExecutor for SessionStoreExecutor {
64 fn requires_durable_hitl_preparation(&self) -> bool {
65 true
66 }
67
68 async fn checkpoint(
69 &self,
70 checkpoint: AgentCheckpoint,
71 ) -> Result<AgentExecutionDecision, AgentExecutorError> {
72 if let Some(lease) = self.admission_lease.as_ref() {
73 self.store
74 .commit_checkpoint_fenced(lease, checkpoint)
75 .await?;
76 } else {
77 self.store
78 .commit_checkpoint(&self.session_id, checkpoint)
79 .await?;
80 }
81 Ok(AgentExecutionDecision::Continue)
82 }
83}