Skip to main content

adk_rs/core/
session.rs

1//! [`Session`] data model: a conversation between a user and one or more agents.
2
3use serde::{Deserialize, Serialize};
4
5use crate::core::event::Event;
6use crate::core::state::State;
7
8/// Convenience alias for session identifiers.
9pub type SessionId = String;
10
11/// A conversation, owned by a `(app_name, user_id, id)` triple.
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct Session {
14    /// Unique id (within `(app_name, user_id)`).
15    pub id: SessionId,
16    /// App name this session belongs to.
17    pub app_name: String,
18    /// User id this session belongs to.
19    pub user_id: String,
20    /// Mutable state map.
21    #[serde(default)]
22    pub state: State,
23    /// All events ever appended to this session (oldest first).
24    #[serde(default)]
25    pub events: Vec<Event>,
26    /// Last update time (seconds since epoch, float).
27    #[serde(default)]
28    pub last_update_time: f64,
29}
30
31impl Session {
32    /// Build a brand-new empty session.
33    pub fn new(
34        app_name: impl Into<String>,
35        user_id: impl Into<String>,
36        id: impl Into<String>,
37    ) -> Self {
38        Self {
39            id: id.into(),
40            app_name: app_name.into(),
41            user_id: user_id.into(),
42            state: State::default(),
43            events: Vec::new(),
44            last_update_time: now_secs(),
45        }
46    }
47}
48
49/// Metadata about a session without events/state (used by list APIs).
50#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
51pub struct SessionMeta {
52    /// Session id.
53    pub id: SessionId,
54    /// App name.
55    pub app_name: String,
56    /// User id.
57    pub user_id: String,
58    /// Last update time (seconds since epoch).
59    pub last_update_time: f64,
60}
61
62/// Seconds since the unix epoch, as `f64`.
63pub fn now_secs() -> f64 {
64    let now = std::time::SystemTime::now()
65        .duration_since(std::time::UNIX_EPOCH)
66        .unwrap_or_default();
67    // Sub-second precision retained.
68    let secs = now.as_secs() as f64;
69    let nanos = f64::from(now.subsec_nanos()) / 1_000_000_000.0;
70    secs + nanos
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn session_round_trips() {
79        let s = Session::new("a", "u", "sess");
80        let j = serde_json::to_value(&s).unwrap();
81        let back: Session = serde_json::from_value(j).unwrap();
82        assert_eq!(s, back);
83    }
84}