wire up /score command and debug screen for memory importance

/score snapshots the context and client, releases the agent lock,
runs scoring in background. Only one score task at a time
(scoring_in_flight flag). Results stored on Agent and shown on
the F10 context debug screen with importance scores per memory.

ApiClient derives Clone. ContextState derives Clone.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-02 22:18:50 -04:00
parent df9b610c7f
commit c01d4a5b08
7 changed files with 64 additions and 4 deletions

View file

@ -354,6 +354,7 @@ impl Session {
("/save", "Save session to disk"),
("/retry", "Re-run last turn"),
("/model", "Show/switch model (/model <name>)"),
("/score", "Score memory importance"),
("/dmn", "Show DMN state"),
("/sleep", "Put DMN to sleep"),
("/wake", "Wake DMN to foraging"),
@ -422,6 +423,46 @@ impl Session {
}
Command::Handled
}
"/score" => {
{
let agent = self.agent.lock().await;
if agent.scoring_in_flight {
let _ = self.ui_tx.send(UiMessage::Info(
"(scoring already in progress)".into()
));
return Command::Handled;
}
}
self.agent.lock().await.scoring_in_flight = true;
let agent = self.agent.clone();
let ui_tx = self.ui_tx.clone();
tokio::spawn(async move {
let (context, client) = {
let agent = agent.lock().await;
(agent.context.clone(), agent.client_clone())
};
let result = poc_memory::thought::training::score_memories(
&context, &client, &ui_tx,
).await;
let mut agent = agent.lock().await;
agent.scoring_in_flight = false;
match result {
Ok(scores) => {
let _ = ui_tx.send(UiMessage::Info(format!(
"[memory scoring complete: {} memories scored]",
scores.memory_keys.len(),
)));
agent.memory_scores = Some(scores);
}
Err(e) => {
let _ = ui_tx.send(UiMessage::Info(format!(
"[memory scoring failed: {:#}]", e,
)));
}
}
});
Command::Handled
}
"/dmn" => {
let _ = self
.ui_tx