Memory nodes section in F2 context screen with scoring visibility

Build a synthetic "Memory nodes (N scored, M unscored)" section in
the context screen by extracting Memory entries from the conversation
section. Each node shows its key and score. Inserted before the
conversation section so scores are visible at a glance.

This makes it easy to see whether scoring is keeping up — if unscored
count is high relative to scored, scoring needs to run more often.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-07 21:03:05 -04:00
parent b892cae2be
commit 5523752a15

View file

@ -24,10 +24,41 @@ impl ConsciousScreen {
}
fn read_context_sections(&self) -> Vec<crate::agent::context::ContextSection> {
match self.agent.try_lock() {
Ok(ag) => ag.context_sections().iter().map(|s| (*s).clone()).collect(),
Err(_) => Vec::new(),
use crate::agent::context::{ContextSection, ContextEntry, ConversationEntry};
use crate::agent::api::Message;
let ag = match self.agent.try_lock() {
Ok(ag) => ag,
Err(_) => return Vec::new(),
};
let mut sections: Vec<ContextSection> = ag.context_sections()
.iter().map(|s| (*s).clone()).collect();
// Build a synthetic "Memory nodes" section from conversation entries
let mut mem_section = ContextSection::new("Memory nodes");
let mut scored = 0usize;
let mut unscored = 0usize;
for ce in ag.context.conversation.entries() {
if let ConversationEntry::Memory { key, score, .. } = &ce.entry {
let label = match score {
Some(s) => { scored += 1; format!("{} (score:{:.2})", key, s) }
None => { unscored += 1; key.clone() }
};
mem_section.push(ContextEntry {
entry: ConversationEntry::Message(Message::user(&label)),
tokens: ce.tokens,
timestamp: ce.timestamp,
});
}
}
if !mem_section.is_empty() {
mem_section.name = format!("Memory nodes ({} scored, {} unscored)",
scored, unscored);
sections.insert(sections.len() - 1, mem_section); // before conversation
}
sections
}
}