split out src/mind
This commit is contained in:
parent
ce04568454
commit
79e384f005
21 changed files with 1865 additions and 2175 deletions
|
|
@ -288,6 +288,79 @@ pub async fn score_memory(
|
|||
Ok(divs.iter().sum())
|
||||
}
|
||||
|
||||
// ── Background memory scoring ───────────────────────────────────
|
||||
|
||||
/// Incrementally score memories through the conversation.
|
||||
///
|
||||
/// Walks memory entries in conversation order starting from `cursor`.
|
||||
/// For each memory with a full WINDOW after it, calls score_memory()
|
||||
/// and yields the result. Stops at the first memory that doesn't have
|
||||
/// enough messages yet — the conversation needs to grow before we can
|
||||
/// score it.
|
||||
///
|
||||
/// Returns the updated cursor (entry index to resume from next time)
|
||||
/// and the scores for each memory that was scored this round.
|
||||
pub async fn score_memories_incremental(
|
||||
context: &ContextState,
|
||||
cursor: usize,
|
||||
client: &ApiClient,
|
||||
ui_tx: &UiSender,
|
||||
) -> anyhow::Result<(usize, Vec<(String, f64)>)> {
|
||||
const WINDOW: usize = 50;
|
||||
|
||||
// Collect unique memory keys with their first position, starting from cursor
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
let mut to_score: Vec<(usize, String)> = Vec::new();
|
||||
|
||||
for (i, entry) in context.entries.iter().enumerate().skip(cursor) {
|
||||
if let ConversationEntry::Memory { key, .. } = entry {
|
||||
if seen.insert(key.clone()) {
|
||||
to_score.push((i, key.clone()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let http = http_client();
|
||||
let mut new_cursor = cursor;
|
||||
let mut results = Vec::new();
|
||||
|
||||
for (pos, key) in &to_score {
|
||||
let end = pos + WINDOW;
|
||||
|
||||
// Not enough conversation after this memory yet — stop here
|
||||
if end > context.entries.len() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Need at least one assistant response in the window
|
||||
let range = *pos..end;
|
||||
if !context.entries[range.clone()].iter().any(|e| e.message().role == Role::Assistant) {
|
||||
new_cursor = end;
|
||||
continue;
|
||||
}
|
||||
|
||||
let _ = ui_tx.send(UiMessage::Activity(format!("scoring memory: {}...", key)));
|
||||
match score_divergence(&http, client, context, range, Filter::SkipKey(key)).await {
|
||||
Ok((divs, _)) => {
|
||||
let importance: f64 = divs.iter().sum();
|
||||
let _ = ui_tx.send(UiMessage::Debug(format!(
|
||||
"[scoring] {} → {:.2}", key, importance,
|
||||
)));
|
||||
results.push((key.clone(), importance));
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = ui_tx.send(UiMessage::Debug(format!(
|
||||
"[scoring] {} FAILED: {:#}", key, e,
|
||||
)));
|
||||
}
|
||||
}
|
||||
new_cursor = end;
|
||||
}
|
||||
|
||||
let _ = ui_tx.send(UiMessage::Activity(String::new()));
|
||||
Ok((new_cursor, results))
|
||||
}
|
||||
|
||||
// ── Fine-tuning scoring ─────────────────────────────────────────
|
||||
|
||||
/// Score which recent responses are candidates for fine-tuning.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue