1use chrono::{DateTime, Utc};
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use std::collections::HashMap;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct WorldStateSnapshot {
17 pub id: String,
19 pub timestamp: DateTime<Utc>,
21 pub nodes: Vec<StateNode>,
23 pub edges: Vec<StateEdge>,
25 pub layers: HashMap<StateLayer, bool>,
27 #[serde(default)]
29 pub metadata: HashMap<String, Value>,
30}
31
32impl WorldStateSnapshot {
33 pub fn new() -> Self {
35 Self {
36 id: uuid::Uuid::new_v4().to_string(),
37 timestamp: Utc::now(),
38 nodes: Vec::new(),
39 edges: Vec::new(),
40 layers: HashMap::new(),
41 metadata: HashMap::new(),
42 }
43 }
44
45 pub fn nodes_in_layer(&self, layer: &StateLayer) -> Vec<&StateNode> {
47 self.nodes.iter().filter(|node| node.layer == *layer).collect()
48 }
49
50 pub fn edges_for_node(&self, node_id: &str) -> Vec<&StateEdge> {
52 self.edges
53 .iter()
54 .filter(|edge| edge.from == node_id || edge.to == node_id)
55 .collect()
56 }
57
58 pub fn get_node(&self, node_id: &str) -> Option<&StateNode> {
60 self.nodes.iter().find(|node| node.id == node_id)
61 }
62}
63
64impl Default for WorldStateSnapshot {
65 fn default() -> Self {
66 Self::new()
67 }
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
75pub struct StateNode {
76 pub id: String,
78 pub label: String,
80 pub node_type: NodeType,
82 pub layer: StateLayer,
84 pub state: Option<String>,
86 #[serde(default)]
88 pub properties: HashMap<String, Value>,
89 pub created_at: DateTime<Utc>,
91 pub updated_at: DateTime<Utc>,
93}
94
95impl StateNode {
96 pub fn new(id: String, label: String, node_type: NodeType, layer: StateLayer) -> Self {
98 let now = Utc::now();
99 Self {
100 id,
101 label,
102 node_type,
103 layer,
104 state: None,
105 properties: HashMap::new(),
106 created_at: now,
107 updated_at: now,
108 }
109 }
110
111 pub fn set_property(&mut self, key: String, value: Value) {
113 self.properties.insert(key, value);
114 self.updated_at = Utc::now();
115 }
116
117 pub fn get_property(&self, key: &str) -> Option<&Value> {
119 self.properties.get(key)
120 }
121
122 pub fn set_state(&mut self, state: String) {
124 self.state = Some(state);
125 self.updated_at = Utc::now();
126 }
127}
128
129#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
131#[serde(rename_all = "snake_case")]
132pub enum NodeType {
133 Persona,
135 Entity,
137 Session,
139 Protocol,
141 Behavior,
143 Schema,
145 Recorded,
147 AiModifier,
149 System,
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
158pub struct StateEdge {
159 pub from: String,
161 pub to: String,
163 pub relationship_type: String,
165 #[serde(default)]
167 pub properties: HashMap<String, Value>,
168 pub created_at: DateTime<Utc>,
170}
171
172impl StateEdge {
173 pub fn new(from: String, to: String, relationship_type: String) -> Self {
175 Self {
176 from,
177 to,
178 relationship_type,
179 properties: HashMap::new(),
180 created_at: Utc::now(),
181 }
182 }
183
184 pub fn set_property(&mut self, key: String, value: Value) {
186 self.properties.insert(key, value);
187 }
188}
189
190#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
194#[serde(rename_all = "snake_case")]
195pub enum StateLayer {
196 Personas,
198 Lifecycle,
200 Reality,
202 Time,
204 Protocols,
206 Behavior,
208 Schemas,
210 Recorded,
212 AiModifiers,
214 System,
216}
217
218impl StateLayer {
219 pub fn all() -> Vec<Self> {
221 vec![
222 Self::Personas,
223 Self::Lifecycle,
224 Self::Reality,
225 Self::Time,
226 Self::Protocols,
227 Self::Behavior,
228 Self::Schemas,
229 Self::Recorded,
230 Self::AiModifiers,
231 Self::System,
232 ]
233 }
234
235 pub fn name(&self) -> &'static str {
237 match self {
238 Self::Personas => "Personas",
239 Self::Lifecycle => "Lifecycle",
240 Self::Reality => "Reality",
241 Self::Time => "Time",
242 Self::Protocols => "Protocols",
243 Self::Behavior => "Behavior",
244 Self::Schemas => "Schemas",
245 Self::Recorded => "Recorded",
246 Self::AiModifiers => "AI Modifiers",
247 Self::System => "System",
248 }
249 }
250}