use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use crate::error::Result;
use crate::genai_types::Part;
use crate::core::artifact::ArtifactKey;
use crate::core::event::Event;
use crate::core::memory::SearchMemoryResponse;
use crate::core::session::{Session, SessionId, SessionMeta};
use crate::core::state::State;
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct GetSessionConfig {
pub num_recent_events: Option<usize>,
pub after_timestamp: Option<f64>,
}
pub type SessionsMeta = ListSessionsResponse;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ListSessionsResponse {
pub sessions: Vec<SessionMeta>,
}
#[async_trait]
pub trait SessionService: Send + Sync + std::fmt::Debug + 'static {
async fn create_session(
&self,
app_name: &str,
user_id: &str,
state: Option<State>,
id: Option<&str>,
) -> Result<Session>;
async fn get_session(
&self,
app_name: &str,
user_id: &str,
session_id: &str,
config: GetSessionConfig,
) -> Result<Option<Session>>;
async fn list_sessions(&self, app_name: &str, user_id: &str) -> Result<ListSessionsResponse>;
async fn delete_session(&self, app_name: &str, user_id: &str, session_id: &str) -> Result<()>;
async fn append_event(&self, session: &mut Session, event: Event) -> Result<Event> {
let event = apply_event_to_session(session, event);
Ok(event)
}
async fn append_event_locked(
&self,
session_lock: &std::sync::Arc<parking_lot::Mutex<Session>>,
event: Event,
) -> Result<Event> {
if event.partial == Some(true) {
return Ok(event);
}
let event = {
let mut sess = session_lock.lock();
apply_event_to_session(&mut sess, event)
};
Ok(event)
}
async fn flush(&self) -> Result<()> {
Ok(())
}
}
pub fn apply_event_to_session(session: &mut Session, mut event: Event) -> Event {
if event.partial == Some(true) {
return event;
}
for (k, v) in &event.actions.state_delta {
if crate::core::state::StateScope::of(k) == crate::core::state::StateScope::Temp {
session.state.set(k.clone(), v.clone());
}
}
event.actions.state_delta = State::trim_temp_keys(&event.actions.state_delta);
session.state.apply(&event.actions.state_delta);
session.last_update_time = crate::core::session::now_secs();
session.events.push(event.clone());
event
}
#[async_trait]
pub trait ArtifactService: Send + Sync + std::fmt::Debug + 'static {
async fn save_artifact(&self, key: ArtifactKey, part: Part) -> Result<u64>;
async fn load_artifact(&self, key: ArtifactKey, version: Option<u64>) -> Result<Option<Part>>;
async fn list_artifact_keys(
&self,
app_name: &str,
user_id: &str,
session_id: &str,
) -> Result<Vec<String>>;
async fn delete_artifact(&self, key: ArtifactKey) -> Result<()>;
async fn list_versions(&self, key: ArtifactKey) -> Result<Vec<u64>>;
}
#[async_trait]
pub trait MemoryService: Send + Sync + std::fmt::Debug + 'static {
async fn add_session_to_memory(&self, session: &Session) -> Result<()>;
async fn search_memory(
&self,
app_name: &str,
user_id: &str,
query: &str,
) -> Result<SearchMemoryResponse>;
}
pub use crate::auth::CredentialService;
pub fn new_session_id() -> SessionId {
uuid::Uuid::new_v4().to_string()
}