forked from kent/consciousness
idle: per-instance state path, extensible extra fields
Move state_path to a field on State (default thalamus-state.json) so the Claude daemon can use its own file without collision. Add a serde(flatten) extra map to Persisted so callers can round-trip additional fields (e.g. claude_pane) through save/load. save() is now &mut self. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
193a85bc05
commit
57bd5b6d8b
1 changed files with 19 additions and 6 deletions
|
|
@ -53,6 +53,8 @@ struct Persisted {
|
|||
turn_start: f64,
|
||||
#[serde(default)]
|
||||
last_nudge: f64,
|
||||
#[serde(flatten)]
|
||||
extra: serde_json::Map<String, serde_json::Value>,
|
||||
// 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<String, serde_json::Value>,
|
||||
#[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::<Persisted>(&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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue