Kill UiMessage variants replaced by state-driven rendering

sync_from_agent reads directly from agent entries, so remove:
- UserInput (pending input shown from MindState.input)
- ToolCall, ToolResult (shown from entries on completion)
- ToolStarted, ToolFinished (replaced by shared active_tools)
- replay_session_to_ui (sync_from_agent handles replay)

-139 lines. Remaining variants are streaming (TextDelta, Reasoning),
status bar state, or ephemeral UI messages (Info, Debug).

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
ProofOfConcept 2026-04-05 21:21:08 -04:00
parent 306788e0f1
commit 1745e03550
5 changed files with 5 additions and 139 deletions

View file

@ -602,24 +602,6 @@ impl InteractScreen {
self.autonomous.append_text(text);
}
},
UiMessage::UserInput(text) => {
self.conversation.push_line_with_marker(text.clone(), Color::Cyan, Marker::User);
self.turn_started = Some(std::time::Instant::now());
self.needs_assistant_marker = true;
app.status.turn_tools = 0;
}
UiMessage::ToolCall { name, args_summary } => {
app.status.turn_tools += 1;
let line = if args_summary.is_empty() { format!("[{}]", name) }
else { format!("[{}] {}", name, args_summary) };
self.tools.push_line(line, Color::Yellow);
}
UiMessage::ToolResult { result, .. } => {
for line in result.lines() {
self.tools.push_line(format!(" {}", line), Color::DarkGray);
}
self.tools.push_line(String::new(), Color::Reset);
}
UiMessage::DmnAnnotation(text) => {
self.autonomous.push_line(text.clone(), Color::Yellow);
self.turn_started = Some(std::time::Instant::now());

View file

@ -459,13 +459,10 @@ pub async fn run(
idle_state.decay_ewma();
app.update_idle(&idle_state);
// One-time: replay conversation after Mind init
// One-time: mark startup done after Mind init
if !startup_done {
if let Ok(ag) = agent.try_lock() {
if !ag.entries().is_empty() {
ui_channel::replay_session_to_ui(ag.entries(), &ui_tx);
let _ = ui_tx.send(UiMessage::Info("--- restored from conversation log ---".into()));
}
// sync_from_agent handles conversation replay
let _ = ui_tx.send(UiMessage::Info(format!(" model: {}", ag.model())));
startup_done = true;
dirty = true;

View file

@ -71,54 +71,28 @@ pub struct ContextInfo {
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub enum UiMessage {
/// Streaming text delta — routed to conversation or autonomous pane
/// based on the current StreamTarget.
/// Streaming text delta — routed to conversation or autonomous pane.
TextDelta(String, StreamTarget),
/// User's input echoed to conversation pane.
UserInput(String),
/// Tool call header: [tool_name] with args summary.
ToolCall {
name: String,
args_summary: String,
},
/// Full tool result — goes to tools pane.
ToolResult {
name: String,
result: String,
},
/// DMN state annotation: [dmn: foraging (3/20)].
DmnAnnotation(String),
/// Status bar update.
StatusUpdate(StatusInfo),
/// Live activity indicator for the status bar — shows what the
/// agent is doing right now ("thinking...", "calling: bash", etc).
/// Empty string clears the indicator.
/// Live activity indicator for the status bar.
Activity(String),
/// Reasoning/thinking tokens from the model (internal monologue).
/// Routed to the autonomous pane so the user can peek at what
/// the model is thinking about during long tool chains.
Reasoning(String),
/// A tool call started — shown as a live overlay above the status bar.
ToolStarted { id: String, name: String, detail: String },
/// A tool call finished — removes it from the live overlay.
ToolFinished { id: String },
/// Debug message (only shown when POC_DEBUG is set).
Debug(String),
/// Informational message — goes to conversation pane (command output, etc).
Info(String),
/// Context loading details — stored for the debug screen (Ctrl+D).
/// Context loading details — stored for the debug screen.
ContextInfoUpdate(ContextInfo),
/// Agent cycle state update — refreshes the F2 agents screen.
@ -157,78 +131,3 @@ pub fn channel() -> (UiSender, UiReceiver) {
/// Replay a restored session into the TUI panes so the user can see
/// conversation history immediately on restart. Shows user input,
/// assistant responses, and brief tool call summaries. Skips the system
/// prompt, context message, DMN plumbing, and image injection messages.
pub fn replay_session_to_ui(entries: &[crate::agent::context::ConversationEntry], ui_tx: &UiSender) {
use crate::agent::api::types::Role;
crate::dbglog!("[replay] replaying {} entries to UI", entries.len());
for (i, e) in entries.iter().enumerate() {
let m = e.message();
let preview: String = m.content_text().chars().take(60).collect();
crate::dbglog!("[replay] [{}] {:?} mem={} tc={} tcid={:?} {:?}",
i, m.role, e.is_memory(), m.tool_calls.as_ref().map_or(0, |t| t.len()),
m.tool_call_id.as_deref(), preview);
}
let mut seen_first_user = false;
let mut target = StreamTarget::Conversation;
for entry in entries {
if entry.is_memory() { continue; }
let msg = entry.message();
match msg.role {
Role::System => {}
Role::User => {
if !seen_first_user {
seen_first_user = true;
continue;
}
let text = msg.content_text();
if text.starts_with("Your context was just compacted")
|| text.starts_with("Your context was just rebuilt")
|| text.starts_with("[Earlier in this conversation")
|| text.starts_with("Here is the image")
|| text.contains("[image aged out")
{
continue;
}
if text.starts_with("[dmn]") {
target = StreamTarget::Autonomous;
let first_line = text.lines().next().unwrap_or("[dmn]");
let _ = ui_tx.send(UiMessage::DmnAnnotation(first_line.to_string()));
} else {
target = StreamTarget::Conversation;
let _ = ui_tx.send(UiMessage::UserInput(text.to_string()));
}
}
Role::Assistant => {
if let Some(ref calls) = msg.tool_calls {
for call in calls {
let _ = ui_tx.send(UiMessage::ToolCall {
name: call.function.name.clone(),
args_summary: String::new(),
});
}
}
let text = msg.content_text();
if !text.is_empty() {
let _ = ui_tx.send(UiMessage::TextDelta(format!("{}\n", text), target));
}
}
Role::Tool => {
let text = msg.content_text();
let preview: String = text.lines().take(3).collect::<Vec<_>>().join("\n");
let truncated = if text.lines().count() > 3 {
format!("{}...", preview)
} else {
preview
};
let _ = ui_tx.send(UiMessage::ToolResult {
name: String::new(),
result: truncated,
});
}
}
}
}