memory: add spreading activation tool

Add `poc-memory graph spread` command that takes multiple seed node keys,
runs spreading activation through the graph, and returns nodes ranked by
total activation — nodes that bridge multiple seed concepts score highest.

Expose spreading_activation() as pub from the query engine. Add
memory_spread and memory_search_content tool definitions for MCP.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-03-31 18:21:01 -04:00
parent c5b5051772
commit 6f2e0938f0
3 changed files with 49 additions and 1 deletions

View file

@ -6,6 +6,7 @@
// trace, spectral-*, organize, interference.
use crate::{store, graph, neuro, spectral};
use crate::store::StoreView;
pub fn cmd_graph() -> Result<(), String> {
let store = store::Store::load()?;
@ -109,6 +110,45 @@ pub fn cmd_normalize_strengths(apply: bool) -> Result<(), String> {
Ok(())
}
pub fn cmd_spread(keys: &[String], max_results: usize) -> Result<(), String> {
if keys.is_empty() {
return Err("spread requires at least one seed key".into());
}
let store = store::Store::load()?;
let graph = 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() {
return Err("no valid seed keys found".into());
}
let results = crate::search::spreading_activation(
&seeds, &graph, &store,
params.max_hops, params.edge_decay, params.min_activation,
);
let seed_keys: std::collections::HashSet<&str> = seeds.iter()
.map(|(k, _)| k.as_str())
.collect();
for (key, score) in results.iter()
.filter(|(k, _)| !seed_keys.contains(k.as_str()))
.take(max_results)
{
println!(" {:.2} {}", score, key);
}
Ok(())
}
pub fn cmd_link(key: &[String]) -> Result<(), String> {
if key.is_empty() {
return Err("link requires a key".into());