Kill StatusUpdate, Activity, DmnAnnotation, ContextInfoUpdate, AgentUpdate

Status bar reads directly from Agent and MindState on each render tick.
Activity is now a field on Agent — set by agent code directly, read by
UI via try_lock. DmnAnnotation, ContextInfoUpdate, AgentUpdate were
already dead (no senders).

UiMessage down to 4 variants: TextDelta, Reasoning, Debug, Info.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-05 21:34:27 -04:00
parent 1745e03550
commit eafc2887a3
7 changed files with 32 additions and 76 deletions

View file

@ -638,7 +638,7 @@ pub async fn collect_stream(
match event {
StreamEvent::Content(text) => {
if first_content {
let _ = ui_tx.send(UiMessage::Activity("streaming...".into()));
if let Ok(mut ag) = agent.try_lock() { ag.activity = "streaming...".into(); }
first_content = false;
}
content.push_str(&text);

View file

@ -28,7 +28,7 @@ use context::{ConversationEntry, ContextState, ContextBudget};
use tools::{summarize_args, working_stack};
use crate::mind::log::ConversationLog;
use crate::user::ui_channel::{ContextSection, SharedContextState, StreamTarget, StatusInfo, UiMessage, UiSender};
use crate::user::ui_channel::{ContextSection, SharedContextState, StreamTarget, UiMessage, UiSender};
use crate::subconscious::learn;
/// Result of a single agent turn.
@ -77,6 +77,8 @@ pub struct Agent {
pub temperature: f32,
pub top_p: f32,
pub top_k: u32,
/// Live activity indicator — read by UI on render tick.
pub activity: String,
/// Control tool flags — set by tool handlers, consumed by turn loop.
pub pending_yield: bool,
pub pending_model_switch: Option<String>,
@ -145,6 +147,7 @@ impl Agent {
temperature: 0.6,
top_p: 0.95,
top_k: 20,
activity: String::new(),
pending_yield: false,
pending_model_switch: None,
pending_dmn_pause: false,
@ -294,7 +297,6 @@ impl Agent {
me.apply_tool_result(&call, output, ui_tx, &mut bg_ds);
}
me.push_message(Message::user(user_input));
let _ = ui_tx.send(UiMessage::AgentUpdate(me.agent_cycles.snapshots()));
}
tools
@ -305,11 +307,10 @@ impl Agent {
let mut ds = DispatchState::new();
loop {
let _ = ui_tx.send(UiMessage::Activity("thinking...".into()));
// --- Lock 2: assemble messages, start stream ---
let (mut rx, _stream_guard) = {
let me = agent.lock().await;
let mut me = agent.lock().await;
me.activity = "thinking...".into();
let api_messages = me.assemble_api_messages();
let sampling = api::SamplingParams {
temperature: me.temperature,
@ -363,13 +364,13 @@ impl Agent {
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
continue;
}
let _ = ui_tx.send(UiMessage::Activity(String::new()));
me.activity.clear();
return Err(err);
}
if finish_reason.as_deref() == Some("error") {
let detail = if content.is_empty() { "no details".into() } else { content };
let _ = ui_tx.send(UiMessage::Activity(String::new()));
me.activity.clear();
return Err(anyhow::anyhow!("model stream error: {}", detail));
}
@ -386,16 +387,6 @@ impl Agent {
if let Some(usage) = &usage {
me.last_prompt_tokens = usage.prompt_tokens;
me.publish_context_state();
let _ = ui_tx.send(UiMessage::StatusUpdate(StatusInfo {
dmn_state: String::new(),
dmn_turns: 0,
dmn_max_turns: 0,
prompt_tokens: usage.prompt_tokens,
completion_tokens: usage.completion_tokens,
model: me.client.model.clone(),
turn_tools: 0,
context_budget: me.budget().status_string(),
}));
}
// Empty response — nudge and retry
@ -468,8 +459,8 @@ impl Agent {
// Genuinely text-only response
let text = msg.content_text().to_string();
let _ = ui_tx.send(UiMessage::Activity(String::new()));
let mut me = agent.lock().await;
me.activity.clear();
me.push_message(msg);
// Drain pending control flags
@ -501,15 +492,15 @@ impl Agent {
Ok(v) => v,
Err(e) => {
let err = format!("Error: malformed tool call arguments: {e}");
let _ = ui_tx.send(UiMessage::Activity(format!("rejected: {} (bad args)", call.function.name)));
let mut me = agent.lock().await;
me.activity = format!("rejected: {} (bad args)", call.function.name);
me.apply_tool_result(call, err, ui_tx, ds);
return;
}
};
let args_summary = summarize_args(&call.function.name, &args);
let _ = ui_tx.send(UiMessage::Activity(format!("calling: {}", call.function.name)));
agent.lock().await.activity = format!("calling: {}", call.function.name);
// Spawn tool, track it
let call_clone = call.clone();