Split surface-observe into separate agents, add thalamus

- subconscious-surface: memory search + surfacing (single step)
- subconscious-observe: graph maintenance + recording (3 steps)
- subconscious-thalamus: watches conversation, nudges when stuck

Thalamus output routed as system-reminder into conscious context.
"ok" responses (nothing to say) are silently dropped.

TODO: thalamus needs inactivity timer + notification triggers,
not just post-turn firing.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-07 02:25:11 -04:00
parent f3ba7e7097
commit b7ff205841
4 changed files with 165 additions and 3 deletions

View file

@ -44,9 +44,11 @@ struct SubconsciousAgent {
/// Names and byte-interval triggers for the built-in subconscious agents.
const SUBCONSCIOUS_AGENTS: &[(&str, u64)] = &[
("subconscious-surface-observe", 0), // every trigger
("subconscious-journal", 20_000), // every ~20KB of conversation
("subconscious-reflect", 100_000), // every ~100KB of conversation
("subconscious-surface", 0), // every trigger
("subconscious-observe", 0), // every trigger (after surface)
("subconscious-thalamus", 0), // every trigger
("subconscious-journal", 20_000), // every ~20KB of conversation
("subconscious-reflect", 100_000), // every ~100KB of conversation
];
impl SubconsciousAgent {
@ -520,6 +522,18 @@ impl Mind {
}
}
// Thalamus nudge → inject into conscious agent
if let Some(nudge) = outputs.get("thalamus") {
let nudge = nudge.trim();
if !nudge.is_empty() && nudge != "ok" {
let mut ag = self.agent.lock().await;
ag.push_message(crate::agent::api::types::Message::user(format!(
"<system-reminder>\n--- thalamus ---\n{}\n</system-reminder>",
nudge,
)));
}
}
dbglog!("[mind] {} completed", name);
}
Ok(Err(e)) => dbglog!("[mind] subconscious agent failed: {}", e),