memory: rename memory_spread → memory_search, remove keyword search

memory_search is now spreading activation — the natural way to search
a graph. Give it seed node keys and it finds conceptually related nodes.

The old keyword-based memory_search and memory_search_content are
removed; memory_query can do everything they did.

Simpler tool set, better defaults. Agents don't need to be told "use
spread not search" — search IS spread now.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-03-31 20:25:00 -04:00
parent a837e3f2e4
commit 3d62f27dfb
3 changed files with 12 additions and 37 deletions

View file

@ -19,15 +19,10 @@ pub fn definitions() -> Vec<ToolDef> {
"Create or update a memory node.",
json!({"type":"object","properties":{"key":{"type":"string","description":"Node key"},"content":{"type":"string","description":"Full content (markdown)"}},"required":["key","content"]})),
ToolDef::new("memory_search",
"Search the memory graph by keyword.",
json!({"type":"object","properties":{"query":{"type":"string","description":"Search terms"}},"required":["query"]})),
ToolDef::new("memory_search_content",
"Search the memory graph by keyword (searches node content, not just keys).",
json!({"type":"object","properties":{"query":{"type":"string","description":"Search terms"}},"required":["query"]})),
ToolDef::new("memory_spread",
"Find related nodes via spreading activation from multiple seed nodes. \
Propagates activation through the graph and returns nodes ranked by \
total activation. Use to find nodes that connect multiple concepts.",
"Search the memory graph via spreading activation. Give 2-4 seed \
node keys related to what you're looking for. Returns nodes ranked \
by how strongly they connect to your seeds bridging nodes score \
highest. This finds conceptual connections, not just keyword matches.",
json!({"type":"object","properties":{"keys":{"type":"array","items":{"type":"string"},"description":"Seed node keys to activate from"}},"required":["keys"]})),
ToolDef::new("memory_links",
"Show a node's neighbors with link strengths.",
@ -101,26 +96,13 @@ 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_content" => {
let query = get_str(args, "query")?;
let store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
let results = crate::search::search(query, &store);
if results.is_empty() {
Ok("no results".into())
} else {
Ok(results.iter().take(20)
.map(|r| format!("({:.2}) {}{}", r.activation, r.key,
r.snippet.as_deref().unwrap_or("")))
.collect::<Vec<_>>().join("\n"))
}
}
"memory_spread" => {
"memory_search" => {
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");
anyhow::bail!("memory_search requires at least one seed key");
}
let store = Store::load().map_err(|e| anyhow::anyhow!("{}", e))?;
let graph = crate::graph::build_graph_fast(&store);