Dedup surfaced memories: skip keys already in conversation context

collect_results now checks existing Memory nodes in the conversation
before surfacing. Prevents the same memory from being pushed every
time the surface agent runs.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-08 20:51:28 -04:00
parent e6f4e9ae04
commit 4db7eca275

View file

@ -483,12 +483,25 @@ impl Subconscious {
|| self.state.contains_key("thalamus"); || self.state.contains_key("thalamus");
if has_outputs { if has_outputs {
if let Some(surface_str) = self.state.get("surface").cloned() { if let Some(surface_str) = self.state.get("surface").cloned() {
// Collect keys already in context to avoid duplicates
let existing: std::collections::HashSet<String> = {
let ctx = agent.context.lock().await;
ctx.conversation().iter()
.filter_map(|n| n.leaf())
.filter_map(|l| match l.body() {
NodeBody::Memory { key, .. } => Some(key.clone()),
_ => None,
})
.collect()
};
let store = crate::store::Store::cached().await.ok(); let store = crate::store::Store::cached().await.ok();
let store_guard = match &store { let store_guard = match &store {
Some(s) => Some(s.lock().await), Some(s) => Some(s.lock().await),
None => None, None => None,
}; };
for key in surface_str.lines().map(|l| l.trim()).filter(|l| !l.is_empty()) { for key in surface_str.lines().map(|l| l.trim()).filter(|l| !l.is_empty()) {
if existing.contains(key) { continue; }
let rendered = store_guard.as_ref() let rendered = store_guard.as_ref()
.and_then(|s| crate::cli::node::render_node(s, key)); .and_then(|s| crate::cli::node::render_node(s, key));
if let Some(rendered) = rendered { if let Some(rendered) = rendered {