consciousness/poc-memory/src/cli/agent.rs

143 lines
5 KiB
Rust
Raw Normal View History

// cli/agent.rs — agent subcommand handlers
use crate::store;
use crate::store::StoreView;
pub fn cmd_consolidate_batch(count: usize, auto: bool, agent: Option<String>) -> Result<(), String> {
let store = store::Store::load()?;
if let Some(agent_name) = agent {
let batch = crate::agents::prompts::agent_prompt(&store, &agent_name, count)?;
println!("{}", batch.prompt);
Ok(())
} else {
crate::agents::prompts::consolidation_batch(&store, count, auto)
}
}
pub fn cmd_replay_queue(count: usize) -> Result<(), String> {
let store = store::Store::load()?;
let queue = crate::neuro::replay_queue(&store, count);
println!("Replay queue ({} items):", queue.len());
for (i, item) in queue.iter().enumerate() {
println!(" {:2}. [{:.3}] {:>10} {} (interval={}d, emotion={:.1}, spectral={:.1})",
i + 1, item.priority, item.classification, item.key,
item.interval_days, item.emotion, item.outlier_score);
}
Ok(())
}
pub fn cmd_consolidate_session() -> Result<(), String> {
let store = store::Store::load()?;
let plan = crate::neuro::consolidation_plan(&store);
println!("{}", crate::neuro::format_plan(&plan));
Ok(())
}
pub fn cmd_consolidate_full() -> Result<(), String> {
let mut store = store::Store::load()?;
crate::consolidate::consolidate_full(&mut store)
}
pub fn cmd_digest_links(do_apply: bool) -> Result<(), String> {
let store = store::Store::load()?;
let links = crate::digest::parse_all_digest_links(&store);
drop(store);
println!("Found {} unique links from digest nodes", links.len());
if !do_apply {
for (i, link) in links.iter().enumerate() {
println!(" {:3}. {}{}", i + 1, link.source, link.target);
if !link.reason.is_empty() {
println!(" ({})", &link.reason[..link.reason.len().min(80)]);
}
}
println!("\nTo apply: poc-memory digest-links --apply");
return Ok(());
}
let mut store = store::Store::load()?;
let (applied, skipped, fallbacks) = crate::digest::apply_digest_links(&mut store, &links);
println!("\nApplied: {} ({} file-level fallbacks) Skipped: {}", applied, fallbacks, skipped);
Ok(())
}
pub fn cmd_journal_enrich(jsonl_path: &str, entry_text: &str, grep_line: usize) -> Result<(), String> {
if !std::path::Path::new(jsonl_path).is_file() {
return Err(format!("JSONL not found: {}", jsonl_path));
}
let mut store = store::Store::load()?;
crate::enrich::journal_enrich(&mut store, jsonl_path, entry_text, grep_line)
}
pub fn cmd_apply_consolidation(do_apply: bool, report_file: Option<&str>) -> Result<(), String> {
let mut store = store::Store::load()?;
crate::consolidate::apply_consolidation(&mut store, do_apply, report_file)
}
pub fn cmd_knowledge_loop(max_cycles: usize, batch_size: usize, window: usize, max_depth: i32) -> Result<(), String> {
let config = crate::knowledge::KnowledgeLoopConfig {
max_cycles,
batch_size,
window,
max_depth,
..Default::default()
};
let results = crate::knowledge::run_knowledge_loop(&config)?;
eprintln!("\nCompleted {} cycles, {} total actions applied",
results.len(),
results.iter().map(|r| r.total_applied).sum::<usize>());
Ok(())
}
pub fn cmd_fact_mine(path: &str, batch: bool, dry_run: bool, output_file: Option<&str>, min_messages: usize) -> Result<(), String> {
let p = std::path::Path::new(path);
let paths: Vec<std::path::PathBuf> = if batch {
if !p.is_dir() {
return Err(format!("Not a directory: {}", path));
}
let mut files: Vec<_> = std::fs::read_dir(p)
.map_err(|e| format!("read dir: {}", e))?
.filter_map(|e| e.ok())
.map(|e| e.path())
.filter(|p| p.extension().map(|x| x == "jsonl").unwrap_or(false))
.collect();
files.sort();
eprintln!("Found {} transcripts", files.len());
files
} else {
vec![p.to_path_buf()]
};
let path_refs: Vec<&std::path::Path> = paths.iter().map(|p| p.as_path()).collect();
let facts = crate::fact_mine::mine_batch(&path_refs, min_messages, dry_run)?;
if !dry_run {
let json = serde_json::to_string_pretty(&facts)
.map_err(|e| format!("serialize: {}", e))?;
if let Some(out) = output_file {
std::fs::write(out, &json).map_err(|e| format!("write: {}", e))?;
eprintln!("\nWrote {} facts to {}", facts.len(), out);
} else {
println!("{}", json);
}
}
eprintln!("\nTotal: {} facts from {} transcripts", facts.len(), paths.len());
Ok(())
}
pub fn cmd_fact_mine_store(path: &str) -> Result<(), String> {
let path = std::path::Path::new(path);
if !path.exists() {
return Err(format!("File not found: {}", path.display()));
}
let count = crate::fact_mine::mine_and_store(path, None)?;
eprintln!("Stored {} facts", count);
Ok(())
}