diff --git a/src/mind/mod.rs b/src/mind/mod.rs index 90c711a..9bf9677 100644 --- a/src/mind/mod.rs +++ b/src/mind/mod.rs @@ -396,26 +396,28 @@ impl Mind { ag.memory_scoring_in_flight = true; (ag.context.clone(), ag.client_clone()) }; - let result = learn::score_memories_incremental( + let _result = learn::score_memories_incremental( &context, max_age as i64, response_window, &client, &agent, + |key: String, score: f64| { + let agent = agent.clone(); + let path = scores_path.clone(); + async move { + 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)); + } + } + } + save_memory_scores(&ag.context.conversation, &path); + ag.changed.notify_one(); + } + }, ).await; { let mut ag = agent.lock().await; ag.memory_scoring_in_flight = false; - if let Ok(ref scores) = result { - // Write scores onto Memory entries - for (key, weight) in scores { - 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(*weight)); - } - } - } - } - // Persist all scores to disk - save_memory_scores(&ag.context.conversation, &scores_path); - } } let _ = bg_tx.send(BgEvent::ScoringDone); }); diff --git a/src/subconscious/learn.rs b/src/subconscious/learn.rs index b6e293e..cc4d614 100644 --- a/src/subconscious/learn.rs +++ b/src/subconscious/learn.rs @@ -299,13 +299,18 @@ pub async fn score_memory( /// Updates the graph weight (EWMA) and last_scored after each. /// /// Returns the number of nodes scored and their (key, score) pairs. -pub async fn score_memories_incremental( +pub async fn score_memories_incremental( context: &ContextState, max_age_secs: i64, response_window: usize, client: &ApiClient, agent: &std::sync::Arc>, -) -> anyhow::Result> { + mut on_score: F, +) -> anyhow::Result +where + F: FnMut(String, f64) -> Fut, + Fut: std::future::Future, +{ let now = chrono::Utc::now().timestamp(); // Collect unique memory keys with their first position @@ -330,7 +335,7 @@ pub async fn score_memories_incremental( candidates.sort_by_key(|&(_, _, last)| last); let http = http_client(); - let mut results = Vec::new(); + let mut scored = 0; let total_entries = context.conversation.entries().len(); let first_quarter = total_entries / 4; @@ -355,7 +360,8 @@ pub async fn score_memories_incremental( dbglog!( "[scoring] {} max:{:.3} ({} responses)", key, max_div, n_responses, ); - results.push((key.clone(), max_div)); + on_score(key.clone(), max_div).await; + scored += 1; } Err(e) => { dbglog!( @@ -365,7 +371,7 @@ pub async fn score_memories_incremental( } } - Ok(results) + Ok(scored) } // ── Fine-tuning scoring ─────────────────────────────────────────