defs.rs: delete dead placeholders, simplify siblings

- Remove {{targets}}, {{hubs}}, {{node:KEY}}, {{latest_journal}} placeholders
- Add graph_hubs as proper RPC tool (was placeholder, now callable)
- Replace {{latest_journal}} with {{tool: journal_tail ...}} in journal.agent
- Simplify siblings/neighborhood: drop unused cross-links, use simple top-20
- Remove unused store/graph params from resolve_tool()

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-13 01:37:33 -04:00
parent de5a6672c3
commit 4cfeb9ee2f
3 changed files with 66 additions and 144 deletions

View file

@ -126,6 +126,7 @@ async fn dispatch(
"graph_normalize_strengths" => graph_normalize_strengths(&args).await,
"graph_trace" => graph_trace(&args).await,
"graph_link_impact" => graph_link_impact(&args).await,
"graph_hubs" => graph_hubs(&args).await,
"journal_tail" => journal_tail(&args).await,
"journal_new" => journal_new(agent, &args).await,
"journal_update" => journal_update(agent, &args).await,
@ -135,7 +136,7 @@ async fn dispatch(
// ── Definitions ────────────────────────────────────────────────
pub fn memory_tools() -> [super::Tool; 14] {
pub fn memory_tools() -> [super::Tool; 15] {
use super::Tool;
[
Tool { name: "memory_render", description: "Read a memory node's content and links.",
@ -188,6 +189,9 @@ pub fn memory_tools() -> [super::Tool; 14] {
Tool { name: "graph_health", description: "Show graph health report with maintenance recommendations.",
parameters_json: r#"{"type":"object","properties":{}}"#,
handler: Arc::new(|a, v| Box::pin(async move { dispatch("graph_health", &a, v).await })) },
Tool { name: "graph_hubs", description: "Show top hub nodes by degree, spread apart for diverse link targets.",
parameters_json: r#"{"type":"object","properties":{"count":{"type":"integer","description":"Number of hubs to return (default 20)"}}}"#,
handler: Arc::new(|a, v| Box::pin(async move { dispatch("graph_hubs", &a, v).await })) },
]
}
@ -713,6 +717,39 @@ async fn graph_link_impact(args: &serde_json::Value) -> Result<String> {
Ok(out)
}
async fn graph_hubs(args: &serde_json::Value) -> Result<String> {
let count = args.get("count").and_then(|v| v.as_u64()).unwrap_or(20) as usize;
let arc = cached_store().await?;
let store = arc.lock().await;
let graph = store.build_graph();
// Top hub nodes by degree, spread apart (skip neighbors of already-selected hubs)
let mut hubs: Vec<(String, usize)> = store.nodes.iter()
.filter(|(k, n)| !n.deleted && !k.starts_with('_'))
.map(|(k, _)| {
let degree = graph.neighbors(k).len();
(k.clone(), degree)
})
.collect();
hubs.sort_by(|a, b| b.1.cmp(&a.1));
let mut selected = Vec::new();
let mut seen: std::collections::HashSet<String> = std::collections::HashSet::new();
for (key, degree) in &hubs {
if seen.contains(key) { continue; }
selected.push(format!(" - {} (degree {})", key, degree));
// Mark neighbors as seen so we pick far-apart hubs
for (nbr, _) in graph.neighbors(key) {
seen.insert(nbr.clone());
}
seen.insert(key.clone());
if selected.len() >= count { break; }
}
Ok(format!("## Hub nodes (link targets)\n\n{}", selected.join("\n")))
}
async fn graph_trace(args: &serde_json::Value) -> Result<String> {
let key = get_str(args, "key")?;