agents: placeholder-based prompt templates, port remaining 4 agents

Replace the formatter dispatch with a generic {{placeholder}} lookup
system. Placeholders in prompt templates are resolved at runtime from
a table: topology, nodes, episodes, health, pairs, rename, split.

The query in the header selects what to operate on (keys for visit
tracking); placeholders pull in formatted context. Placeholders that
produce their own node selection (pairs, rename) contribute keys back.

Port health, separator, rename, and split agents to .agent files.
All 7 agents now use the config-driven path.
This commit is contained in:
ProofOfConcept 2026-03-10 15:50:54 -04:00
parent b4e674806d
commit 16c749f798
6 changed files with 436 additions and 36 deletions

View file

@ -186,6 +186,10 @@ fn format_nodes_section(store: &Store, items: &[ReplayItem], graph: &Graph) -> S
}
/// Format health data for the health agent prompt
pub fn format_health_section_pub(store: &Store, graph: &Graph) -> String {
format_health_section(store, graph)
}
fn format_health_section(store: &Store, graph: &Graph) -> String {
use crate::graph;
@ -242,6 +246,14 @@ fn format_health_section(store: &Store, graph: &Graph) -> String {
out
}
pub fn format_pairs_section_pub(
pairs: &[(String, String, f32)],
store: &Store,
graph: &Graph,
) -> String {
format_pairs_section(pairs, store, graph)
}
/// Format interference pairs for the separator agent prompt
fn format_pairs_section(
pairs: &[(String, String, f32)],
@ -278,6 +290,10 @@ fn format_pairs_section(
out
}
pub fn format_rename_candidates_pub(store: &Store, count: usize) -> (Vec<String>, String) {
format_rename_candidates_with_keys(store, count)
}
/// Format rename candidates, returning both keys and formatted section
fn format_rename_candidates_with_keys(store: &Store, count: usize) -> (Vec<String>, String) {
let mut candidates: Vec<(&str, &crate::store::Node)> = store.nodes.iter()
@ -339,6 +355,10 @@ pub fn split_candidates(store: &Store) -> Vec<String> {
}
/// Format a single node for split-plan prompt (phase 1)
pub fn format_split_plan_node_pub(store: &Store, graph: &Graph, key: &str) -> String {
format_split_plan_node(store, graph, key)
}
fn format_split_plan_node(store: &Store, graph: &Graph, key: &str) -> String {
let communities = graph.communities();
let node = match store.nodes.get(key) {