CLI: more RPC conversions, delete obsolete commands

- cmd_health: use graph_health RPC
- cmd_topology: new command using graph_topology RPC
- cmd_status: use graph_topology RPC (type counts folded into topology)
- cmd_run_agent: query resolution via memory_query RPC
- Delete cmd_bulk_rename (one-time migration, obsolete)
- Delete cmd_replay_queue, cmd_digest_links (unconscious agents handle)
- format_topology_header: add type counts, takes &Store now

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2026-04-12 23:37:05 -04:00
parent 1f6bfb5915
commit 2ab4aef19f
6 changed files with 58 additions and 173 deletions

View file

@ -209,7 +209,7 @@ fn resolve(
) -> Option<Resolved> {
match name {
"topology" => Some(Resolved {
text: super::prompts::format_topology_header(graph),
text: super::prompts::format_topology_header(store, graph),
keys: vec![],
}),

View file

@ -20,7 +20,7 @@ pub struct AgentBatch {
pub node_keys: Vec<String>,
}
pub fn format_topology_header(graph: &Graph) -> String {
pub fn format_topology_header(store: &Store, graph: &Graph) -> String {
let sigma = graph.small_world_sigma();
let alpha = graph.degree_power_law_exponent();
let gini = graph.degree_gini();
@ -28,6 +28,25 @@ pub fn format_topology_header(graph: &Graph) -> String {
let n = graph.nodes().len();
let e = graph.edge_count();
// Type counts
let mut type_counts: std::collections::HashMap<&str, usize> = std::collections::HashMap::new();
for node in store.nodes.values() {
let label = match node.node_type {
crate::store::NodeType::Semantic => "semantic",
crate::store::NodeType::EpisodicSession
| crate::store::NodeType::EpisodicDaily
| crate::store::NodeType::EpisodicWeekly
| crate::store::NodeType::EpisodicMonthly => "episodic",
};
*type_counts.entry(label).or_default() += 1;
}
let mut types: Vec<_> = type_counts.iter().collect();
types.sort_by_key(|(_, c)| std::cmp::Reverse(**c));
let type_str: String = types.iter()
.map(|(t, c)| format!("{}={}", t, c))
.collect::<Vec<_>>()
.join(" ");
// Identify saturated hubs — nodes with degree well above threshold
let threshold = graph.hub_threshold();
let mut hubs: Vec<_> = graph.nodes().iter()
@ -54,13 +73,13 @@ pub fn format_topology_header(graph: &Graph) -> String {
format!(
"## Current graph topology\n\
Nodes: {} Edges: {} Communities: {}\n\
Nodes: {} Edges: {} Communities: {} Types: {}\n\
Small-world σ: {:.1} Power-law α: {:.2} Degree Gini: {:.3}\n\
Avg clustering coefficient: {:.4}\n\n\
{}\
Each node below shows its hub-link ratio (fraction of edges to top-5% degree nodes).\n\
Use `poc-memory link-impact SOURCE TARGET` to evaluate proposed links.\n\n",
n, e, graph.community_count(), sigma, alpha, gini, avg_cc, hub_list)
n, e, graph.community_count(), type_str, sigma, alpha, gini, avg_cc, hub_list)
}
pub fn format_nodes_section(store: &Store, items: &[ReplayItem], graph: &Graph) -> String {