WIP: Fix mind/, dmn, UI layer — 35 errors remaining

mind/mod.rs and mind/dmn.rs fully migrated to AST types.
user/context.rs, user/widgets.rs, user/chat.rs partially migrated.
Killed working_stack tool, tokenize_conv_entry, context_old.rs.

Remaining: learn.rs (22), oneshot.rs (5), subconscious.rs (3),
chat.rs (3), widgets.rs (1), context.rs (1).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-08 15:24:49 -04:00
parent bf3e2a9b73
commit d0d876e067
5 changed files with 99 additions and 141 deletions

View file

@ -28,12 +28,9 @@ use crate::subconscious::learn;
pub use dmn::{SubconsciousSnapshot, Subconscious};
use crate::agent::context::ConversationEntry;
use crate::agent::context::{AstNode, NodeBody, Section, Ast, ContextState};
/// Load persisted memory scores from disk and apply to Memory entries.
use crate::agent::context::ContextSection;
fn load_memory_scores(section: &mut ContextSection, path: &std::path::Path) {
fn load_memory_scores(ctx: &mut ContextState, path: &std::path::Path) {
let data = match std::fs::read_to_string(path) {
Ok(d) => d,
Err(_) => return,
@ -43,11 +40,13 @@ fn load_memory_scores(section: &mut ContextSection, path: &std::path::Path) {
Err(_) => return,
};
let mut applied = 0;
for i in 0..section.len() {
if let ConversationEntry::Memory { key, .. } = &section.entries()[i].entry {
if let Some(&s) = scores.get(key.as_str()) {
section.set_score(i, Some(s));
applied += 1;
for i in 0..ctx.conversation().len() {
if let AstNode::Leaf(leaf) = &ctx.conversation()[i] {
if let NodeBody::Memory { key, .. } = leaf.body() {
if let Some(&s) = scores.get(key.as_str()) {
ctx.set_score(Section::Conversation, i, Some(s));
applied += 1;
}
}
}
}
@ -57,14 +56,15 @@ fn load_memory_scores(section: &mut ContextSection, path: &std::path::Path) {
}
/// Collect scored memory keys from conversation entries.
fn collect_memory_scores(section: &ContextSection) -> std::collections::BTreeMap<String, f64> {
section.entries().iter()
.filter_map(|ce| {
if let ConversationEntry::Memory { key, score: Some(s), .. } = &ce.entry {
Some((key.clone(), *s))
} else {
None
fn collect_memory_scores(ctx: &ContextState) -> std::collections::BTreeMap<String, f64> {
ctx.conversation().iter()
.filter_map(|node| {
if let AstNode::Leaf(leaf) = node {
if let NodeBody::Memory { key, score: Some(s), .. } = leaf.body() {
return Some((key.clone(), *s));
}
}
None
})
.collect()
}
@ -319,7 +319,7 @@ impl Mind {
// Restore persisted memory scores
let scores_path = self.config.session_dir.join("memory-scores.json");
load_memory_scores(&mut ag.context.conversation, &scores_path);
load_memory_scores(&mut ag.context, &scores_path);
ag.changed.notify_one();
drop(ag);
@ -341,7 +341,7 @@ impl Mind {
MindCommand::Compact => {
let threshold = compaction_threshold(&self.config.app) as usize;
let mut ag = self.agent.lock().await;
if ag.context.total_tokens() > threshold {
if ag.context.tokens() > threshold {
ag.compact();
ag.notify("compacted");
}
@ -408,16 +408,17 @@ impl Mind {
async move {
let scores_snapshot = {
let mut ag = agent.lock().await;
for i in 0..ag.context.conversation.len() {
if let ConversationEntry::Memory { key: k, .. } = &ag.context.conversation.entries()[i].entry {
if *k == key {
ag.context.conversation.set_score(i, Some(score));
for i in 0..ag.context.conversation().len() {
if let AstNode::Leaf(leaf) = &ag.context.conversation()[i] {
if let NodeBody::Memory { key: k, .. } = leaf.body() {
if *k == key {
ag.context.set_score(Section::Conversation, i, Some(score));
}
}
}
}
ag.changed.notify_one();
// Snapshot scores while we have the lock
collect_memory_scores(&ag.context.conversation)
collect_memory_scores(&ag.context)
};
// Write to disk after releasing the lock
save_memory_scores(&scores_snapshot, &path);
@ -437,18 +438,16 @@ impl Mind {
let mut ag = self.agent.lock().await;
match target {
StreamTarget::Conversation => {
ag.push_message(crate::agent::api::Message::user(text));
ag.push_node(AstNode::user_msg(text));
}
StreamTarget::Autonomous => {
let mut msg = crate::agent::api::Message::user(text);
msg.stamp();
ag.push_entry(crate::agent::context::ConversationEntry::Dmn(msg));
ag.push_node(AstNode::dmn(text));
}
}
// Compact if over budget before sending
let threshold = compaction_threshold(&self.config.app) as usize;
if ag.context.total_tokens() > threshold {
if ag.context.tokens() > threshold {
ag.compact();
ag.notify("compacted");
}
@ -508,12 +507,6 @@ impl Mind {
crate::user::chat::cmd_switch_model(&self.agent, &name).await;
}
// Post-turn maintenance
{
let mut ag = self.agent.lock().await;
ag.age_out_images();
}
cmds.push(MindCommand::Compact);
if !self.config.no_agents {
cmds.push(MindCommand::Score);