graph_communities: new RPC tool, convert cmd_communities

Agents can use graph_communities to discover isolated knowledge
clusters that need better integration.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-12 23:09:12 -04:00
parent be9db3fb1a
commit a8d91896a2
2 changed files with 46 additions and 30 deletions

View file

@ -122,6 +122,7 @@ async fn dispatch(
"memory_query" => query(&args).await,
"graph_topology" => graph_topology().await,
"graph_health" => graph_health().await,
"graph_communities" => graph_communities(&args).await,
"journal_tail" => journal_tail(&args).await,
"journal_new" => journal_new(agent, &args).await,
"journal_update" => journal_update(agent, &args).await,
@ -573,3 +574,43 @@ async fn graph_health() -> Result<String> {
let graph = store.build_graph();
Ok(crate::subconscious::prompts::format_health_section(&store, &graph))
}
async fn graph_communities(args: &serde_json::Value) -> Result<String> {
let top_n = args.get("top_n").and_then(|v| v.as_u64()).unwrap_or(10) as usize;
let min_size = args.get("min_size").and_then(|v| v.as_u64()).unwrap_or(3) as usize;
let arc = cached_store().await?;
let store = arc.lock().await;
let g = store.build_graph();
let infos = g.community_info();
let total = infos.len();
let shown: Vec<_> = infos.into_iter()
.filter(|c| c.size >= min_size)
.take(top_n)
.collect();
use std::fmt::Write;
let mut out = String::new();
writeln!(out, "{} communities total ({} with size >= {})\n",
total, shown.len(), min_size).ok();
writeln!(out, "{:<6} {:>5} {:>7} {:>7} members", "id", "size", "iso", "cross").ok();
writeln!(out, "{}", "-".repeat(70)).ok();
for c in &shown {
let preview: Vec<&str> = c.members.iter()
.take(5)
.map(|s| s.as_str())
.collect();
let more = if c.size > 5 {
format!(" +{}", c.size - 5)
} else {
String::new()
};
writeln!(out, "{:<6} {:>5} {:>6.0}% {:>7} {}{}",
c.id, c.size, c.isolation * 100.0, c.cross_edges,
preview.join(", "), more).ok();
}
Ok(out)
}

View file

@ -354,36 +354,11 @@ pub fn cmd_organize(term: &str, key_only: bool, create_anchor: bool) -> Result<(
/// Useful for finding poorly-integrated knowledge clusters that need
/// organize agents aimed at them.
pub fn cmd_communities(top_n: usize, min_size: usize) -> Result<(), String> {
let store = store::Store::load()?;
let g = store.build_graph();
let infos = g.community_info();
let total = infos.len();
let shown: Vec<_> = infos.into_iter()
.filter(|c| c.size >= min_size)
.take(top_n)
.collect();
println!("{} communities total ({} with size >= {})\n",
total, shown.len(), min_size);
println!("{:<6} {:>5} {:>7} {:>7} members", "id", "size", "iso", "cross");
println!("{}", "-".repeat(70));
for c in &shown {
let preview: Vec<&str> = c.members.iter()
.take(5)
.map(|s| s.as_str())
.collect();
let more = if c.size > 5 {
format!(" +{}", c.size - 5)
} else {
String::new()
};
println!("{:<6} {:>5} {:>6.0}% {:>7} {}{}",
c.id, c.size, c.isolation * 100.0, c.cross_edges,
preview.join(", "), more);
}
let result = crate::mcp_server::memory_rpc(
"graph_communities",
serde_json::json!({"top_n": top_n, "min_size": min_size}),
).map_err(|e| e.to_string())?;
print!("{}", result);
Ok(())
}