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:
parent
306788e0f1
commit
1745e03550
5 changed files with 5 additions and 139 deletions
|
|
@ -651,10 +651,6 @@ pub async fn collect_stream(
|
|||
let args: serde_json::Value =
|
||||
serde_json::from_str(&call.function.arguments).unwrap_or_default();
|
||||
let args_summary = summarize_args(&call.function.name, &args);
|
||||
let _ = ui_tx.send(UiMessage::ToolCall {
|
||||
name: call.function.name.clone(),
|
||||
args_summary: args_summary.clone(),
|
||||
});
|
||||
let is_background = args.get("run_in_background")
|
||||
.and_then(|v| v.as_bool())
|
||||
.unwrap_or(false);
|
||||
|
|
|
|||
|
|
@ -510,10 +510,6 @@ impl Agent {
|
|||
|
||||
let args_summary = summarize_args(&call.function.name, &args);
|
||||
let _ = ui_tx.send(UiMessage::Activity(format!("calling: {}", call.function.name)));
|
||||
let _ = ui_tx.send(UiMessage::ToolCall {
|
||||
name: call.function.name.clone(),
|
||||
args_summary: args_summary.clone(),
|
||||
});
|
||||
|
||||
// Spawn tool, track it
|
||||
let call_clone = call.clone();
|
||||
|
|
@ -561,10 +557,6 @@ impl Agent {
|
|||
ds.tool_errors += 1;
|
||||
}
|
||||
|
||||
let _ = ui_tx.send(UiMessage::ToolResult {
|
||||
name: call.function.name.clone(),
|
||||
result: output.clone(),
|
||||
});
|
||||
self.active_tools.lock().unwrap().retain(|t| t.id != call.id);
|
||||
|
||||
// Tag memory_render results for context deduplication
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue