Fix input blocked during scoring: release agent lock before disk write

The scoring callback was holding the agent lock while doing a
synchronous file write (save_memory_scores). This blocked the event
loop from acquiring the lock to process user input.

Fix: collect the scores snapshot while holding the lock, drop the
lock, then write to disk.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-07 22:32:10 -04:00
parent 1be16b9f7b
commit 7c5fddcb19

View file

@ -56,9 +56,9 @@ fn load_memory_scores(section: &mut ContextSection, path: &std::path::Path) {
}
}
/// Save all memory scores to disk.
fn save_memory_scores(section: &ContextSection, path: &std::path::Path) {
let scores: std::collections::BTreeMap<String, f64> = section.entries().iter()
/// 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))
@ -66,8 +66,12 @@ fn save_memory_scores(section: &ContextSection, path: &std::path::Path) {
None
}
})
.collect();
if let Ok(json) = serde_json::to_string_pretty(&scores) {
.collect()
}
/// Save memory scores to disk.
fn save_memory_scores(scores: &std::collections::BTreeMap<String, f64>, path: &std::path::Path) {
if let Ok(json) = serde_json::to_string_pretty(scores) {
let _ = std::fs::write(path, json);
dbglog!("[scoring] saved {} scores to {}", scores.len(), path.display());
}
@ -402,6 +406,7 @@ impl Mind {
let agent = agent.clone();
let path = scores_path.clone();
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 {
@ -410,8 +415,12 @@ impl Mind {
}
}
}
save_memory_scores(&ag.context.conversation, &path);
ag.changed.notify_one();
// Snapshot scores while we have the lock
collect_memory_scores(&ag.context.conversation)
};
// Write to disk after releasing the lock
save_memory_scores(&scores_snapshot, &path);
}
},
).await;