Skip to main content

gonzalo_domain/
session.rs

1//! Session (conversation transcript) view.
2
3use crate::codec::RecordCodec;
4use gonzalo_core::RecordKind;
5use serde::{Deserialize, Serialize};
6
7/// One transcript turn (role + text). Kept deliberately minimal for M1;
8/// richer turn modeling tracks caliban's session schema in a later milestone.
9#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
10pub struct Turn {
11    pub role: String,
12    pub text: String,
13}
14
15/// A conversation session: an ordered, append-only list of turns.
16#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
17pub struct Session {
18    pub name: String,
19    pub turns: Vec<Turn>,
20}
21impl RecordCodec for Session {}
22impl Session {
23    pub const KIND: RecordKind = RecordKind::Session;
24}
25
26#[cfg(test)]
27mod tests {
28    use super::*;
29    use crate::codec::RecordCodec;
30
31    #[test]
32    fn session_roundtrips() {
33        let s = Session {
34            name: "research".into(),
35            turns: vec![Turn {
36                role: "user".into(),
37                text: "hi".into(),
38            }],
39        };
40        assert_eq!(Session::from_body(&s.to_body().unwrap()).unwrap(), s);
41        assert_eq!(Session::KIND, RecordKind::Session);
42    }
43}