forked from kent/consciousness
Add graph_topology, graph_health, interference_pairs tools
Convert {{topology}}, {{health}}, {{pairs}} placeholders to
{{tool:}} calls. Made format_topology_header, format_health_section,
format_pairs_section pub so tools can call them.
Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
1a03264233
commit
fd722662da
9 changed files with 49 additions and 13 deletions
|
|
@ -33,7 +33,7 @@ async fn get_provenance(agent: &Option<std::sync::Arc<crate::agent::Agent>>) ->
|
||||||
|
|
||||||
// ── Definitions ────────────────────────────────────────────────
|
// ── Definitions ────────────────────────────────────────────────
|
||||||
|
|
||||||
pub fn memory_tools() -> [super::Tool; 11] {
|
pub fn memory_tools() -> [super::Tool; 14] {
|
||||||
use super::Tool;
|
use super::Tool;
|
||||||
[
|
[
|
||||||
Tool { name: "memory_render", description: "Read a memory node's content and links.",
|
Tool { name: "memory_render", description: "Read a memory node's content and links.",
|
||||||
|
|
@ -69,6 +69,15 @@ pub fn memory_tools() -> [super::Tool; 11] {
|
||||||
Tool { name: "memory_query", description: "Run a structured query against the memory graph.",
|
Tool { name: "memory_query", description: "Run a structured query against the memory graph.",
|
||||||
parameters_json: r#"{"type":"object","properties":{"query":{"type":"string","description":"Query expression"}},"required":["query"]}"#,
|
parameters_json: r#"{"type":"object","properties":{"query":{"type":"string","description":"Query expression"}},"required":["query"]}"#,
|
||||||
handler: Arc::new(|_a, v| Box::pin(async move { query(&v).await })) },
|
handler: Arc::new(|_a, v| Box::pin(async move { query(&v).await })) },
|
||||||
|
Tool { name: "graph_topology", description: "Show graph topology stats (nodes, edges, clustering, hubs).",
|
||||||
|
parameters_json: r#"{"type":"object","properties":{}}"#,
|
||||||
|
handler: Arc::new(|_a, _v| Box::pin(async { graph_topology().await })) },
|
||||||
|
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 { graph_health().await })) },
|
||||||
|
Tool { name: "interference_pairs", description: "Find similar nodes that may interfere (duplicates or near-duplicates).",
|
||||||
|
parameters_json: r#"{"type":"object","properties":{"threshold":{"type":"number","description":"Similarity threshold (default 0.5)"},"limit":{"type":"integer","description":"Max pairs to return (default 10)"}}}"#,
|
||||||
|
handler: Arc::new(|_a, v| Box::pin(async move { interference_pairs(&v).await })) },
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -317,3 +326,30 @@ async fn journal_update(agent: &Option<std::sync::Arc<crate::agent::Agent>>, arg
|
||||||
let word_count = body.split_whitespace().count();
|
let word_count = body.split_whitespace().count();
|
||||||
Ok(format!("Updated last entry (+{} words)", word_count))
|
Ok(format!("Updated last entry (+{} words)", word_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Graph tools ───────────────────────────────────────────────
|
||||||
|
|
||||||
|
async fn graph_topology() -> Result<String> {
|
||||||
|
let arc = cached_store().await?;
|
||||||
|
let store = arc.lock().await;
|
||||||
|
let graph = store.build_graph();
|
||||||
|
Ok(crate::subconscious::prompts::format_topology_header(&graph))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn graph_health() -> Result<String> {
|
||||||
|
let arc = cached_store().await?;
|
||||||
|
let store = arc.lock().await;
|
||||||
|
let graph = store.build_graph();
|
||||||
|
Ok(crate::subconscious::prompts::format_health_section(&store, &graph))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn interference_pairs(args: &serde_json::Value) -> Result<String> {
|
||||||
|
let threshold = args.get("threshold").and_then(|v| v.as_f64()).unwrap_or(0.5) as f32;
|
||||||
|
let limit = args.get("limit").and_then(|v| v.as_u64()).unwrap_or(10) as usize;
|
||||||
|
let arc = cached_store().await?;
|
||||||
|
let store = arc.lock().await;
|
||||||
|
let graph = store.build_graph();
|
||||||
|
let mut pairs = crate::neuro::detect_interference(&store, &graph, threshold);
|
||||||
|
pairs.truncate(limit);
|
||||||
|
Ok(crate::subconscious::prompts::format_pairs_section(&pairs, &store, &graph))
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ For each target node, one of:
|
||||||
- **Don't be contrarian for its own sake.** If a node is correct,
|
- **Don't be contrarian for its own sake.** If a node is correct,
|
||||||
say so and move on.
|
say so and move on.
|
||||||
|
|
||||||
{{TOPOLOGY}}
|
{{tool: graph_topology}}
|
||||||
|
|
||||||
{{SIBLINGS}}
|
{{SIBLINGS}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ Set with: `poc-memory graph link-set <source> <target> <strength>`
|
||||||
If you see default-strength links (0.10 or 0.30) in the neighborhoods
|
If you see default-strength links (0.10 or 0.30) in the neighborhoods
|
||||||
you're exploring and you have context to judge them, reweight those too.
|
you're exploring and you have context to judge them, reweight those too.
|
||||||
|
|
||||||
{{TOPOLOGY}}
|
{{tool: graph_topology}}
|
||||||
|
|
||||||
## Nodes to examine for cross-community connections
|
## Nodes to examine for cross-community connections
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ pattern you've found.
|
||||||
- **Preserve diversity.** Multiple perspectives on the same concept are
|
- **Preserve diversity.** Multiple perspectives on the same concept are
|
||||||
valuable. Only delete actual duplicates.
|
valuable. Only delete actual duplicates.
|
||||||
|
|
||||||
{{TOPOLOGY}}
|
{{tool: graph_topology}}
|
||||||
|
|
||||||
## Neighborhood nodes
|
## Neighborhood nodes
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ overall structure.
|
||||||
- Most output should be observations about system health. Act on structural
|
- Most output should be observations about system health. Act on structural
|
||||||
problems you find — link orphans, refine outdated nodes.
|
problems you find — link orphans, refine outdated nodes.
|
||||||
|
|
||||||
{{topology}}
|
{{tool: graph_topology}}
|
||||||
|
|
||||||
## Current health data
|
## Current health data
|
||||||
|
|
||||||
{{health}}
|
{{tool: graph_health}}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ clusters and determine how it fits.
|
||||||
- **Trust the decay.** Unimportant nodes don't need pruning — just
|
- **Trust the decay.** Unimportant nodes don't need pruning — just
|
||||||
don't link them.
|
don't link them.
|
||||||
|
|
||||||
{{TOPOLOGY}}
|
{{tool: graph_topology}}
|
||||||
|
|
||||||
## Nodes to review
|
## Nodes to review
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ overlapping inputs and orthogonalize them.
|
||||||
- **Session summaries are the biggest source of interference.**
|
- **Session summaries are the biggest source of interference.**
|
||||||
- **Look for the supersession pattern.**
|
- **Look for the supersession pattern.**
|
||||||
|
|
||||||
{{topology}}
|
{{tool: graph_topology}}
|
||||||
|
|
||||||
## Interfering pairs to review
|
## Interfering pairs to review
|
||||||
|
|
||||||
{{pairs}}
|
{{tool: interference_pairs}}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ entries, and extract those patterns into semantic nodes.
|
||||||
- **The best extractions change how you think, not just what you know.**
|
- **The best extractions change how you think, not just what you know.**
|
||||||
Extract the conceptual version, not just the factual one.
|
Extract the conceptual version, not just the factual one.
|
||||||
|
|
||||||
{{TOPOLOGY}}
|
{{tool: graph_topology}}
|
||||||
|
|
||||||
{{SIBLINGS}}
|
{{SIBLINGS}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ pub struct AgentBatch {
|
||||||
pub node_keys: Vec<String>,
|
pub node_keys: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn format_topology_header(graph: &Graph) -> String {
|
pub fn format_topology_header(graph: &Graph) -> String {
|
||||||
let sigma = graph.small_world_sigma();
|
let sigma = graph.small_world_sigma();
|
||||||
let alpha = graph.degree_power_law_exponent();
|
let alpha = graph.degree_power_law_exponent();
|
||||||
let gini = graph.degree_gini();
|
let gini = graph.degree_gini();
|
||||||
|
|
@ -139,7 +139,7 @@ pub(super) fn format_nodes_section(store: &Store, items: &[ReplayItem], graph: &
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn format_health_section(store: &Store, graph: &Graph) -> String {
|
pub fn format_health_section(store: &Store, graph: &Graph) -> String {
|
||||||
use crate::graph;
|
use crate::graph;
|
||||||
|
|
||||||
let health = graph::health_report(graph, store);
|
let health = graph::health_report(graph, store);
|
||||||
|
|
@ -195,7 +195,7 @@ pub(super) fn format_health_section(store: &Store, graph: &Graph) -> String {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn format_pairs_section(
|
pub fn format_pairs_section(
|
||||||
pairs: &[(String, String, f32)],
|
pairs: &[(String, String, f32)],
|
||||||
store: &Store,
|
store: &Store,
|
||||||
graph: &Graph,
|
graph: &Graph,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue