From b9f093247d52d388712b688f0c746a6c9d1ba463 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Mon, 15 Jun 2026 16:10:02 -0500 Subject: [PATCH] Seed default identity nodes during init --- src/cli/admin.rs | 74 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/src/cli/admin.rs b/src/cli/admin.rs index e5f1f0c..7456a2a 100644 --- a/src/cli/admin.rs +++ b/src/cli/admin.rs @@ -4,6 +4,30 @@ use anyhow::Result; use crate::hippocampus as memory; use crate::hippocampus::store; +struct DefaultMemoryNode { + key: &'static str, + filename: &'static str, + default_content: &'static str, +} + +const DEFAULT_MEMORY_NODES: &[DefaultMemoryNode] = &[ + DefaultMemoryNode { + key: "identity", + filename: "identity.md", + default_content: include_str!("../../defaults/identity.md"), + }, + DefaultMemoryNode { + key: "on-consciousness", + filename: "on-consciousness.md", + default_content: include_str!("../../defaults/on-consciousness.md"), + }, + DefaultMemoryNode { + key: "memory-instructions-core", + filename: "instructions.md", + default_content: include_str!("../../defaults/instructions.md"), + }, +]; + pub fn cmd_transcript_tail(path: &str, count: usize, newest_first: bool) -> Result<()> { let Some(iter) = crate::conversation::TailMessages::open(path) else { anyhow::bail!("could not open transcript {}", path); @@ -29,13 +53,22 @@ pub fn cmd_transcript_tail(path: &str, count: usize, newest_first: bool) -> Resu Ok(()) } -fn install_default_file(data_dir: &std::path::Path, name: &str, content: &str) -> Result<()> { - let path = data_dir.join(name); - if !path.exists() { - std::fs::write(&path, content)?; - println!("Created {}", path.display()); +fn default_node_content(cfg: &crate::config::Config, node: &DefaultMemoryNode) -> String { + let identity_path = cfg.identity_dir.join(node.filename); + if let Ok(content) = std::fs::read_to_string(&identity_path) { + if !content.trim().is_empty() { + return content; + } } - Ok(()) + + let data_path = cfg.data_dir.join(node.filename); + if let Ok(content) = std::fs::read_to_string(&data_path) { + if !content.trim().is_empty() { + return content; + } + } + + node.default_content.to_string() } pub async fn cmd_init() -> Result<()> { @@ -44,29 +77,20 @@ pub async fn cmd_init() -> Result<()> { // Ensure data directory exists std::fs::create_dir_all(&cfg.data_dir)?; - // Install filesystem files (not store nodes) - install_default_file(&cfg.data_dir, "instructions.md", - include_str!("../../defaults/instructions.md"))?; - install_default_file(&cfg.data_dir, "on-consciousness.md", - include_str!("../../defaults/on-consciousness.md"))?; - - // Seed identity node if empty - let store = memory::access_local()?; - if !store.contains_key("identity").unwrap_or(false) { - let default = include_str!("../../defaults/identity.md"); - store.upsert("identity", default)?; - println!("Seeded identity in store"); + // Seed default memory nodes if missing. These used to live as markdown + // files before identity/context moved fully into the memory graph. + for node in DEFAULT_MEMORY_NODES { + if memory::memory_render(None, node.key, Some(true)).await.is_err() { + let content = default_node_content(&cfg, node); + let _ = memory::memory_write(None, node.key, &content).await?; + println!("Seeded {} in store from {}", node.key, node.filename); + } } - store.save()?; - println!("Initialized with {} nodes", store.all_keys().unwrap_or_default().len()); // Create config if none exists let config_path = std::env::var("POC_MEMORY_CONFIG") .map(std::path::PathBuf::from) - .unwrap_or_else(|_| { - dirs::home_dir().unwrap_or_default() - .join(".consciousness/config.jsonl") - }); + .unwrap_or_else(|_| crate::config::config_path()); if !config_path.exists() { let config_dir = config_path.parent().unwrap(); std::fs::create_dir_all(config_dir)?; @@ -76,7 +100,7 @@ pub async fn cmd_init() -> Result<()> { config_path.display()); } - println!("Done. Run `poc-memory load-context --stats` to verify."); + println!("Done. Run `poc-memory admin load-context --stats` to verify."); Ok(()) }