diff --git a/src/agent/tools/memory.rs b/src/agent/tools/memory.rs index 739784d..1bf69bc 100644 --- a/src/agent/tools/memory.rs +++ b/src/agent/tools/memory.rs @@ -8,7 +8,6 @@ use anyhow::{Context, Result}; use std::sync::OnceLock; use crate::hippocampus::memory::MemoryNode; -use crate::store::StoreView; use crate::store::Store; // ── Store handle ─────────────────────────────────────────────── @@ -142,7 +141,7 @@ pub fn memory_tools() -> [super::Tool; 14] { parameters_json: r#"{"type":"object","properties":{"key":{"type":"string","description":"Node key"},"content":{"type":"string","description":"Full content (markdown)"}},"required":["key","content"]}"#, handler: Arc::new(|a, v| Box::pin(async move { dispatch("memory_write", &a, v).await })) }, Tool { name: "memory_search", description: "Search the memory graph via spreading activation. Give 2-4 seed node keys.", - parameters_json: r#"{"type":"object","properties":{"keys":{"type":"array","items":{"type":"string"},"description":"Seed node keys to activate from"}},"required":["keys"]}"#, + parameters_json: r#"{"type":"object","properties":{"keys":{"type":"array","items":{"type":"string"},"description":"Seed node keys to activate from"},"max_hops":{"type":"integer","description":"Max graph hops (default 3)"},"edge_decay":{"type":"number","description":"Decay per hop (default 0.3)"},"min_activation":{"type":"number","description":"Cutoff threshold (default 0.01)"},"limit":{"type":"integer","description":"Max results (default 20)"}},"required":["keys"]}"#, handler: Arc::new(|a, v| Box::pin(async move { dispatch("memory_search", &a, v).await })) }, Tool { name: "memory_links", description: "Show a node's neighbors with link strengths.", parameters_json: r#"{"type":"object","properties":{"key":{"type":"string","description":"Node key"}},"required":["key"]}"#, @@ -264,10 +263,16 @@ async fn search(args: &serde_json::Value) -> Result { if keys.is_empty() { anyhow::bail!("memory_search requires at least one seed key"); } + + // Optional params with defaults + let max_hops = args.get("max_hops").and_then(|v| v.as_u64()).unwrap_or(3) as u32; + let edge_decay = args.get("edge_decay").and_then(|v| v.as_f64()).unwrap_or(0.3); + let min_activation = args.get("min_activation").and_then(|v| v.as_f64()).unwrap_or(0.01); + let limit = args.get("limit").and_then(|v| v.as_u64()).unwrap_or(20) as usize; + let arc = cached_store().await?; let store = arc.lock().await; let graph = crate::graph::build_graph_fast(&*store); - let params = store.params(); let seeds: Vec<(String, f64)> = keys.iter() .filter_map(|k| { let resolved = store.resolve_key(k).ok()?; @@ -281,11 +286,11 @@ async fn search(args: &serde_json::Value) -> Result { .map(|(k, _)| k.as_str()).collect(); let results = crate::search::spreading_activation( &seeds, &graph, &*store, - params.max_hops, params.edge_decay, params.min_activation, + max_hops, edge_decay, min_activation, ); Ok(results.iter() .filter(|(k, _)| !seed_set.contains(k.as_str())) - .take(20) + .take(limit) .map(|(key, score)| format!(" {:.2} {}", score, key)) .collect::>().join("\n")) }