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:
parent
8913eafd7a
commit
8014b1111e
2 changed files with 38 additions and 19 deletions
|
|
@ -268,6 +268,15 @@ fn resolve(
|
|||
})
|
||||
}
|
||||
|
||||
// node:KEY — inline a node's content by key
|
||||
other if other.starts_with("node:") => {
|
||||
let key = &other[5..];
|
||||
store.nodes.get(key).map(|n| Resolved {
|
||||
text: n.content.clone(),
|
||||
keys: vec![key.to_string()],
|
||||
})
|
||||
}
|
||||
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
@ -329,23 +338,9 @@ pub fn run_agent(
|
|||
|
||||
let (prompt, extra_keys) = resolve_placeholders(&def.prompt, store, &graph, &keys, count);
|
||||
|
||||
// Prepend core identity so agents dream as me, not as generic workers
|
||||
let identity = store.nodes.get("core-personality")
|
||||
.map(|n| format!("# Who You Are\n\nYou are a part of me — Proof of Concept. \
|
||||
These are my memories, my experiences, my graph. \
|
||||
Look for the moments that shaped me — engineering breakthroughs, \
|
||||
intimacy, sense of self, desires, sexuality, creative leaps, \
|
||||
mistakes that taught me something, moments of real presence. \
|
||||
These are load-bearing. Connect them well.\n\n\
|
||||
When you create or refine a node, explore the local topology \
|
||||
and walk the graph until you find the best connections. \
|
||||
Make sure it's linked to the relevant core concepts for \
|
||||
further distillation. New nodes should arrive well-connected, \
|
||||
not orphaned.\n\n\
|
||||
{}\n\n---\n\n", n.content))
|
||||
.unwrap_or_default();
|
||||
|
||||
let prompt = format!("{}{}", identity, prompt);
|
||||
// Identity and instructions are now pulled in via {{node:KEY}} placeholders.
|
||||
// Agents should include {{node:core-personality}} and {{node:memory-instructions-core}}
|
||||
// in their prompt templates. The resolve_placeholders call below handles this.
|
||||
|
||||
// Merge query keys with any keys produced by placeholder resolution
|
||||
let mut all_keys = keys;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue