Replace Result<_, String> with anyhow::Result throughout: - hippocampus/store module (persist, ops, types, view, mod) - CLI modules (admin, agent, graph, journal, node) - Run trait in main.rs Use .context() and .with_context() instead of .map_err(|e| format!(...)) patterns. Add bail!() for early error returns. Add access_local() helper in hippocampus/mod.rs that returns Result<Arc<Mutex<Store>>> for direct local store access. Fix store access patterns to properly lock Arc<Mutex<Store>> before accessing fields in mind/unconscious.rs, mind/mod.rs, subconscious/learn.rs, and hippocampus/memory.rs. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
63 lines
2.4 KiB
Rust
63 lines
2.4 KiB
Rust
// cli/agent.rs — agent subcommand handlers
|
|
|
|
use anyhow::{bail, Context, Result};
|
|
use crate::hippocampus as memory;
|
|
|
|
pub async fn cmd_run_agent(agent: &str, count: usize, target: &[String], query: Option<&str>, dry_run: bool, _local: bool, state_dir: Option<&str>) -> Result<()> {
|
|
// Mark as agent so tool calls (e.g. poc-memory render) don't
|
|
// pollute the user's seen set as a side effect
|
|
// SAFETY: single-threaded at this point (CLI startup, before any agent work)
|
|
unsafe { std::env::set_var("POC_AGENT", "1"); }
|
|
|
|
// Override agent output/state directory if specified
|
|
if let Some(dir) = state_dir {
|
|
std::fs::create_dir_all(dir).context("create state dir")?;
|
|
unsafe { std::env::set_var("POC_AGENT_OUTPUT_DIR", dir); }
|
|
}
|
|
|
|
if dry_run {
|
|
unsafe { std::env::set_var("POC_MEMORY_DRY_RUN", "1"); }
|
|
}
|
|
|
|
// Resolve targets: explicit --target, --query, or agent's default query
|
|
let resolved_targets: Vec<String> = if !target.is_empty() {
|
|
target.to_vec()
|
|
} else if let Some(q) = query {
|
|
// Resolve query via typed API
|
|
let q_str = format!("{} | limit:{}", q, count);
|
|
let result = memory::memory_query(None, &q_str, None).await?;
|
|
let keys: Vec<String> = result.lines()
|
|
.filter(|l| !l.is_empty() && *l != "no results")
|
|
.map(|s| s.to_string())
|
|
.collect();
|
|
if keys.is_empty() {
|
|
bail!("query returned no results: {}", q);
|
|
}
|
|
println!("[{}] query matched {} nodes", agent, keys.len());
|
|
keys
|
|
} else {
|
|
vec![] // use agent's built-in query
|
|
};
|
|
|
|
let arc = memory::access_local()?;
|
|
|
|
if !resolved_targets.is_empty() {
|
|
for (i, key) in resolved_targets.iter().enumerate() {
|
|
println!("[{}] [{}/{}] {}", agent, i + 1, resolved_targets.len(), key);
|
|
let mut store = arc.lock().await;
|
|
if let Err(e) = crate::agent::oneshot::run_one_agent(
|
|
&mut store, agent, count, Some(&[key.clone()]),
|
|
).await {
|
|
println!("[{}] ERROR on {}: {}", agent, key, e);
|
|
}
|
|
}
|
|
} else {
|
|
// Local execution (--local, --debug, dry-run, or daemon unavailable)
|
|
let mut store = arc.lock().await;
|
|
crate::agent::oneshot::run_one_agent(
|
|
&mut store, agent, count, None,
|
|
).await.map_err(|e| anyhow::anyhow!("{}", e))?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|