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:
parent
bf3e2a9b73
commit
d0d876e067
5 changed files with 99 additions and 141 deletions
|
|
@ -273,7 +273,7 @@ impl State {
|
|||
|
||||
use std::sync::Arc;
|
||||
use crate::agent::{Agent, oneshot::{AutoAgent, AutoStep}};
|
||||
use crate::agent::context::ConversationEntry;
|
||||
use crate::agent::context::{Ast, AstNode, NodeBody};
|
||||
use crate::subconscious::defs;
|
||||
|
||||
/// Names and byte-interval triggers for the built-in subconscious agents.
|
||||
|
|
@ -472,22 +472,18 @@ impl Subconscious {
|
|||
let rendered = store_guard.as_ref()
|
||||
.and_then(|s| crate::cli::node::render_node(s, key));
|
||||
if let Some(rendered) = rendered {
|
||||
let mut msg = crate::agent::api::Message::user(format!(
|
||||
"<system-reminder>\n--- {} (surfaced) ---\n{}\n</system-reminder>",
|
||||
key, rendered,
|
||||
ag.push_node(AstNode::memory(
|
||||
key,
|
||||
format!("--- {} (surfaced) ---\n{}", key, rendered),
|
||||
));
|
||||
msg.stamp();
|
||||
ag.push_entry(ConversationEntry::Memory {
|
||||
key: key.to_string(), message: msg, score: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(reflection) = outputs.get("reflection") {
|
||||
if !reflection.trim().is_empty() {
|
||||
ag.push_message(crate::agent::api::Message::user(format!(
|
||||
"<system-reminder>\n--- subconscious reflection ---\n{}\n</system-reminder>",
|
||||
ag.push_node(AstNode::dmn(format!(
|
||||
"--- subconscious reflection ---\n{}",
|
||||
reflection.trim(),
|
||||
)));
|
||||
}
|
||||
|
|
@ -496,8 +492,8 @@ impl Subconscious {
|
|||
if let Some(nudge) = outputs.get("thalamus") {
|
||||
let nudge = nudge.trim();
|
||||
if !nudge.is_empty() && nudge != "ok" {
|
||||
ag.push_message(crate::agent::api::Message::user(format!(
|
||||
"<system-reminder>\n--- thalamus ---\n{}\n</system-reminder>",
|
||||
ag.push_node(AstNode::dmn(format!(
|
||||
"--- thalamus ---\n{}",
|
||||
nudge,
|
||||
)));
|
||||
}
|
||||
|
|
@ -518,12 +514,13 @@ impl Subconscious {
|
|||
pub async fn trigger(&mut self, agent: &Arc<tokio::sync::Mutex<Agent>>) {
|
||||
let (conversation_bytes, memory_keys) = {
|
||||
let ag = agent.lock().await;
|
||||
let bytes = ag.context.conversation.entries().iter()
|
||||
.filter(|ce| !ce.entry.is_log() && !ce.entry.is_memory())
|
||||
.map(|ce| ce.entry.message().content_text().len() as u64)
|
||||
let bytes = ag.context.conversation().iter()
|
||||
.filter(|node| !matches!(node.leaf().map(|l| l.body()),
|
||||
Some(NodeBody::Log(_)) | Some(NodeBody::Memory { .. })))
|
||||
.map(|node| node.render().len() as u64)
|
||||
.sum::<u64>();
|
||||
let keys: Vec<String> = ag.context.conversation.entries().iter().filter_map(|ce| {
|
||||
if let ConversationEntry::Memory { key, .. } = &ce.entry {
|
||||
let keys: Vec<String> = ag.context.conversation().iter().filter_map(|node| {
|
||||
if let Some(NodeBody::Memory { key, .. }) = node.leaf().map(|l| l.body()) {
|
||||
Some(key.clone())
|
||||
} else { None }
|
||||
}).collect();
|
||||
|
|
@ -550,7 +547,7 @@ impl Subconscious {
|
|||
|
||||
let mut forked = conscious.fork(auto.tools.clone());
|
||||
forked.provenance = format!("agent:{}", auto.name);
|
||||
let fork_point = forked.context.conversation.len();
|
||||
let fork_point = forked.context.conversation().len();
|
||||
let shared_forked = Arc::new(tokio::sync::Mutex::new(forked));
|
||||
|
||||
self.agents[idx].forked_agent = Some(shared_forked.clone());
|
||||
|
|
|
|||
|
|
@ -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, .. } = §ion.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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue