memory: add dispatch handlers for memory_spread and memory_search_content

The new tool definitions broke surface-observe because they had no
corresponding dispatch handlers — the agent runner saw unknown tools
and ran with no tools at all.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-03-31 18:40:15 -04:00
parent 081d40f306
commit ebc29a3674

View file

@ -6,6 +6,7 @@ use anyhow::{Context, Result};
use serde_json::json;
use crate::hippocampus::memory::MemoryNode;
use crate::store::StoreView;
use super::ToolDef;
use crate::store::Store;
@ -100,7 +101,7 @@ pub fn dispatch(name: &str, args: &serde_json::Value, provenance: Option<&str>)
store.save().map_err(|e| anyhow::anyhow!("{}", e))?;
Ok(format!("{} '{}'", result, key))
}
"memory_search" => {
"memory_search" | "memory_search_content" => {
let query = get_str(args, "query")?;
let store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
let results = crate::search::search(query, &store);
@ -113,6 +114,38 @@ pub fn dispatch(name: &str, args: &serde_json::Value, provenance: Option<&str>)
.collect::<Vec<_>>().join("\n"))
}
}
"memory_spread" => {
let keys: Vec<String> = args.get("keys")
.and_then(|v| v.as_array())
.map(|arr| arr.iter().filter_map(|v| v.as_str().map(String::from)).collect())
.unwrap_or_default();
if keys.is_empty() {
anyhow::bail!("spread requires at least one seed key");
}
let store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
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()?;
Some((resolved, 1.0))
})
.collect();
if seeds.is_empty() {
anyhow::bail!("no valid seed keys found");
}
let seed_set: std::collections::HashSet<&str> = seeds.iter()
.map(|(k, _)| k.as_str()).collect();
let results = crate::search::spreading_activation(
&seeds, &graph, &store,
params.max_hops, params.edge_decay, params.min_activation,
);
Ok(results.iter()
.filter(|(k, _)| !seed_set.contains(k.as_str()))
.take(20)
.map(|(key, score)| format!(" {:.2} {}", score, key))
.collect::<Vec<_>>().join("\n"))
}
"memory_links" => {
let key = get_str(args, "key")?;
let node = MemoryNode::load(key)