Kill TextDelta, Info — UiMessage is dead. RAII ActivityGuards replace all status feedback

Streaming text now goes directly to agent entries via append_streaming().
sync_from_agent diffs the growing entry each tick. The streaming entry
is popped when the response completes; build_response_message pushes
the final version.

All status feedback uses RAII ActivityGuards:
- push_activity() for long-running work (thinking, streaming, scoring)
- notify() for instant feedback (compacted, DMN state changes, commands)
- Guards auto-remove on Drop, appending "(complete)" and lingering 5s
- expire_activities() cleans up timed-out notifications on render tick

UiMessage enum reduced to a single Info variant with zero sends.
The channel infrastructure remains for now (Mind/Agent still take
UiSender in signatures) — mechanical cleanup for a follow-up.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-05 22:18:07 -04:00
parent e7914e3d58
commit cfddb55ed9
9 changed files with 201 additions and 186 deletions

View file

@ -17,7 +17,7 @@
use crate::agent::api::ApiClient;
use crate::agent::api::types::*;
use crate::agent::context::{ConversationEntry, ContextState};
use crate::user::ui_channel::{UiMessage, UiSender};
use crate::user::ui_channel::UiSender;
const SCORE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(120);
@ -353,7 +353,7 @@ pub async fn score_memories_incremental(
continue;
}
if let Ok(mut ag) = agent.try_lock() { ag.activity = format!("scoring memory: {}...", key); }
let _scoring = crate::agent::start_activity(agent, format!("scoring: {}", key)).await;
match score_divergence(&http, client, context, range, Filter::SkipKey(key)).await {
Ok((divs, _)) => {
let n_responses = divs.len();
@ -361,7 +361,6 @@ pub async fn score_memories_incremental(
dbglog!(
"[scoring] {} max:{:.3} ({} responses)", key, max_div, n_responses,
);
// TODO: update graph weight once normalization is figured out
results.push((key.clone(), max_div));
}
Err(e) => {
@ -372,7 +371,6 @@ pub async fn score_memories_incremental(
}
}
if let Ok(mut ag) = agent.try_lock() { ag.activity.clear(); }
Ok(results)
}