diff --git a/src/thalamus/idle.rs b/src/thalamus/idle.rs index ad16f7e..3af43cf 100644 --- a/src/thalamus/idle.rs +++ b/src/thalamus/idle.rs @@ -53,6 +53,8 @@ struct Persisted { turn_start: f64, #[serde(default)] last_nudge: f64, + #[serde(flatten)] + extra: serde_json::Map, // Human-readable mirrors #[serde(default, skip_deserializing)] last_user_msg_time: String, @@ -66,8 +68,8 @@ struct Persisted { uptime: f64, } -fn state_path() -> std::path::PathBuf { - home().join(".consciousness/daemon-state.json") +pub fn default_state_path() -> std::path::PathBuf { + home().join(".consciousness/thalamus-state.json") } /// Compute EWMA decay factor: 0.5^(elapsed / half_life). @@ -113,6 +115,10 @@ pub struct State { #[serde(skip)] pub start_time: f64, #[serde(skip)] + pub state_path: std::path::PathBuf, + #[serde(skip)] + pub extra: serde_json::Map, + #[serde(skip)] pub notifications: notify::NotifyState, } @@ -137,12 +143,14 @@ impl State { last_nudge: 0.0, running: true, start_time: now(), + state_path: default_state_path(), + extra: serde_json::Map::new(), notifications: notify::NotifyState::new(), } } pub fn load(&mut self) { - if let Ok(data) = fs::read_to_string(state_path()) { + if let Ok(data) = fs::read_to_string(&self.state_path) { if let Ok(p) = serde_json::from_str::(&data) { self.sleep_until = p.sleep_until; if p.idle_timeout > 0.0 { @@ -163,12 +171,17 @@ impl State { self.in_turn = p.in_turn; self.turn_start = p.turn_start; self.last_nudge = p.last_nudge; + // Filter out known Persisted fields that leak into extra via flatten + self.extra = p.extra; + for key in ["last_user_msg_time", "last_response_time", "saved_at", "fired", "uptime"] { + self.extra.remove(key); + } info!("loaded idle state"); } } } - pub fn save(&self) { + pub fn save(&mut self) { let p = Persisted { last_user_msg: self.last_user_msg, last_response: self.last_response, @@ -181,15 +194,15 @@ impl State { in_turn: self.in_turn, turn_start: self.turn_start, last_nudge: self.last_nudge, + extra: self.extra.clone(), last_user_msg_time: epoch_to_iso(self.last_user_msg), last_response_time: epoch_to_iso(self.last_response), saved_at: epoch_to_iso(now()), fired: self.fired, uptime: now() - self.start_time, - ..Default::default() }; if let Ok(json) = serde_json::to_string_pretty(&p) { - let _ = fs::write(state_path(), json); + let _ = fs::write(&self.state_path, json); } }