use crate::memory_core::semantic_consolidation::SemanticConsolidationConfig;
use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::path::Path;
#[derive(Debug, Clone)]
pub struct DreamConfig {
pub idle_secs: u64,
pub dedup_threshold: f32,
pub prune_importance: f32,
pub max_cycle_ms: u64,
pub content_prune_enabled: bool,
pub content_prune_min_words: usize,
pub semantic: SemanticConsolidationConfig,
pub openrouter_api_key: String,
pub local_model_enabled: bool,
}
impl Default for DreamConfig {
fn default() -> Self {
Self {
idle_secs: 300,
dedup_threshold: 0.95,
prune_importance: 0.05,
max_cycle_ms: 60_000,
content_prune_enabled: true,
content_prune_min_words: 4,
semantic: SemanticConsolidationConfig::default(),
openrouter_api_key: String::new(),
local_model_enabled: true,
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct DreamStats {
pub merged: usize,
pub pruned: usize,
pub closets_updated: usize,
pub compacted: usize,
#[serde(default)]
pub content_pruned: usize,
#[serde(default)]
pub semantically_consolidated: usize,
#[serde(default)]
pub semantic_llm_calls: usize,
#[serde(default)]
pub semantic_cache_hits: usize,
pub duration_ms: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PersistedDreamStats {
pub last_run_at: chrono::DateTime<chrono::Utc>,
#[serde(flatten)]
pub stats: DreamStats,
}
impl PersistedDreamStats {
pub const FILE_NAME: &'static str = "dream_stats.json";
pub fn load(data_dir: &Path) -> Result<Option<Self>> {
let path = data_dir.join(Self::FILE_NAME);
if !path.exists() {
return Ok(None);
}
let raw =
std::fs::read_to_string(&path).with_context(|| format!("read {}", path.display()))?;
let parsed: Self =
serde_json::from_str(&raw).with_context(|| format!("parse {}", path.display()))?;
Ok(Some(parsed))
}
pub fn save(&self, data_dir: &Path) -> Result<()> {
let path = data_dir.join(Self::FILE_NAME);
let raw = serde_json::to_string_pretty(self).context("serialize dream stats")?;
std::fs::write(&path, raw).with_context(|| format!("write {}", path.display()))?;
Ok(())
}
}