learn: F6 screen — scoring stats, ActivityGuard, configurable threshold
Three changes that together reshape the F6 fine-tune-review screen: 1. Finetune scoring reports through the standard agent activity system instead of a separate finetune_progress String. The previous design ran an independent progress field that forced a cross-lock dance and bespoke UI plumbing. start_finetune_scoring now uses start_activity + activity.update, so the usual status line and notifications capture scoring progress uniformly with other background work. 2. MindState gains a FinetuneScoringStats snapshot (responses seen, above threshold, max divergence, error). The F6 empty screen shows this instead of a loading message — so after a scoring run that produced zero candidates, you can see *why* (e.g., max_divergence below threshold). 3. The divergence threshold is configurable from F6 via +/- hotkeys (scales by 10×) and persisted to ~/.consciousness/config.json5 via config_writer::set_learn_threshold. AppConfig grows a learn section with a threshold field (default 1e-7). Also: user/mod.rs no longer uses try_lock() for the per-tick unconscious/mind state sync — we fixed the locking hot paths that made try_lock necessary, so lock().await is now the right choice. And subconscious::learn::score_finetune_candidates now returns (candidates, max_divergence) so the stats can be populated. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
ac40c2cb98
commit
e5dd8312c7
5 changed files with 237 additions and 85 deletions
|
|
@ -389,7 +389,7 @@ async fn run(
|
|||
Box::new(crate::user::subconscious::SubconsciousScreen::new()),
|
||||
Box::new(crate::user::unconscious::UnconsciousScreen::new()),
|
||||
Box::new(crate::user::thalamus::ThalamusScreen::new()),
|
||||
Box::new(crate::user::learn::LearnScreen::new()),
|
||||
Box::new(crate::user::learn::LearnScreen::new(mind_tx.clone())),
|
||||
];
|
||||
let mut active_screen: usize = 1; // F-key number
|
||||
tui::set_screen_legend(tui::screen_legend_from(&*screens));
|
||||
|
|
@ -466,7 +466,8 @@ async fn run(
|
|||
idle_state.decay_ewma();
|
||||
app.update_idle(&idle_state);
|
||||
app.agent_state = mind.subconscious_snapshots().await;
|
||||
if let Ok(mut unc) = mind.unconscious.try_lock() {
|
||||
{
|
||||
let mut unc = mind.unconscious.lock().await;
|
||||
let toggles: Vec<String> = app.agent_toggles.drain(..).collect();
|
||||
for name in &toggles {
|
||||
if mind.subconscious.lock().await.toggle(name).is_none() {
|
||||
|
|
@ -480,10 +481,13 @@ async fn run(
|
|||
};
|
||||
app.unconscious_state = unc.snapshots(store_guard.as_deref());
|
||||
app.graph_health = unc.graph_health.clone();
|
||||
}
|
||||
|
||||
// Sync mind state (finetune candidates, last scoring run, etc.)
|
||||
{
|
||||
let ms = mind.shared.lock().unwrap();
|
||||
// Sync finetune candidates: add new ones, keep existing (preserves approval status)
|
||||
// Remove sent candidates (already trained, no need to keep)
|
||||
// Keep only 10 most recent rejected candidates
|
||||
// Sync finetune candidates: add new ones, keep existing (preserves approval status),
|
||||
// remove sent candidates, keep only 10 most recent rejected.
|
||||
app.finetune_candidates.retain(|c| c.status != learn::CandidateStatus::Sent);
|
||||
for c in &ms.finetune_candidates {
|
||||
let exists = app.finetune_candidates.iter()
|
||||
|
|
@ -492,7 +496,6 @@ async fn run(
|
|||
app.finetune_candidates.push(learn::FinetuneCandidate::from(c.clone()));
|
||||
}
|
||||
}
|
||||
// Limit rejected candidates to 10 most recent
|
||||
let mut rejected: Vec<_> = app.finetune_candidates.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, c)| c.status == learn::CandidateStatus::Rejected)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue