agents: node:KEY placeholder, content-based report naming

- Add {{node:KEY}} placeholder resolver — agents can inline any graph
  node's content in their prompts. Used for shared instructions.
- Remove hardcoded identity preamble from defs.rs — agents now pull
  identity and instructions from the graph via {{node:core-personality}}
  and {{node:memory-instructions-core}}.
- Agent output report keys now include a content slug extracted from
  the first line of LLM output, making them human-readable
  (e.g. _consolidate-distill-20260316T014739-distillation-run-complete).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kent Overstreet 2026-03-16 17:09:41 -04:00
parent 8913eafd7a
commit 8014b1111e
2 changed files with 38 additions and 19 deletions

View file

@ -366,6 +366,28 @@ pub fn apply_action(
}
}
/// Extract a short slug from agent output for human-readable report keys.
/// Takes the first meaningful line, lowercases, keeps alphanum+hyphens, truncates.
fn make_report_slug(output: &str) -> String {
let line = output.lines()
.map(|l| l.trim())
.find(|l| !l.is_empty() && !l.starts_with('#') && !l.starts_with("```") && !l.starts_with("---"))
.unwrap_or("");
// Strip markdown bold/italic
let clean: String = line.replace("**", "").replace('*', "");
// Keep only alphanumeric, spaces, hyphens
let filtered: String = clean.chars()
.map(|c| if c.is_alphanumeric() || c == ' ' || c == '-' { c } else { ' ' })
.collect();
// Collapse whitespace, convert to kebab-case, truncate
let slug: String = filtered.split_whitespace()
.take(6)
.collect::<Vec<_>>()
.join("-")
.to_lowercase();
if slug.len() > 60 { slug[..60].to_string() } else { slug }
}
fn agent_provenance(agent: &str) -> String {
match agent {
"observation" => "agent:knowledge-observation".to_string(),
@ -647,9 +669,11 @@ pub fn run_one_agent(
let output_kb = output.len() / 1024;
log(&format!("response {}KB", output_kb));
// Store raw output for audit trail
// Store raw output for audit trail — key includes a content slug
let ts = store::compact_timestamp();
let report_key = format!("_{}-{}-{}", llm_tag, agent_name, ts);
let slug = make_report_slug(&output);
let report_key = format!("_{}-{}-{}{}", llm_tag, agent_name, ts,
if slug.is_empty() { String::new() } else { format!("-{}", slug) });
let provenance = agent_provenance(agent_name);
store.upsert_provenance(&report_key, &output, &provenance).ok();