1use crate::ids::*;
4use chrono::{DateTime, Utc};
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct SessionManifest {
10 pub session_id: SessionId,
11 pub owner: String,
12 pub created_at: DateTime<Utc>,
13 pub workspace_root: String,
14 pub model_routing: ModelRouting,
15 pub policy: serde_json::Value,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct ModelRouting {
21 pub primary_model: String,
22 pub fallback_models: Vec<String>,
23 pub temperature: f32,
24}
25
26impl Default for ModelRouting {
27 fn default() -> Self {
28 Self {
29 primary_model: "claude-sonnet-4-5-20250929".to_owned(),
30 fallback_models: vec!["gpt-4.1".to_owned()],
31 temperature: 0.2,
32 }
33 }
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct BranchInfo {
39 pub branch_id: BranchId,
40 pub parent_branch: Option<BranchId>,
41 pub fork_sequence: u64,
42 pub head_sequence: u64,
43 pub merged_into: Option<BranchId>,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize)]
48pub struct BranchMergeResult {
49 pub source_branch: BranchId,
50 pub target_branch: BranchId,
51 pub source_head_sequence: u64,
52 pub target_head_sequence: u64,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct CheckpointManifest {
58 pub checkpoint_id: CheckpointId,
59 pub session_id: SessionId,
60 pub branch_id: BranchId,
61 pub created_at: DateTime<Utc>,
62 pub event_sequence: u64,
63 pub state_hash: String,
64 pub note: String,
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn model_routing_default() {
73 let mr = ModelRouting::default();
74 assert!(mr.primary_model.contains("claude"));
75 assert_eq!(mr.temperature, 0.2);
76 }
77
78 #[test]
79 fn session_manifest_serde_roundtrip() {
80 let manifest = SessionManifest {
81 session_id: SessionId::from_string("S1"),
82 owner: "test".into(),
83 created_at: Utc::now(),
84 workspace_root: "/tmp/test".into(),
85 model_routing: ModelRouting::default(),
86 policy: serde_json::json!({}),
87 };
88 let json = serde_json::to_string(&manifest).unwrap();
89 let back: SessionManifest = serde_json::from_str(&json).unwrap();
90 assert_eq!(back.session_id.as_str(), "S1");
91 }
92}