From b89bafdf6b334443d574e78f71ea7bfa6232f52f Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 5 Apr 2026 19:22:31 -0400 Subject: [PATCH] chat: full entry type routing in sync_from_agent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Route agent entries to correct panes: - User messages → conversation (cyan, User marker) - Assistant text → conversation (Assistant marker) - Assistant tool_calls → tools pane (yellow) - Tool results → tools pane (truncated at 20 lines) - Memory/system-reminder entries → skipped - System role → skipped Two phases: detect generation change (reset panes if needed), then route new entries. PaneState is the rendered view of agent entries, updated incrementally. Co-Authored-By: Kent Overstreet --- src/user/chat.rs | 55 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/src/user/chat.rs b/src/user/chat.rs index d4939a3..7b213b3 100644 --- a/src/user/chat.rs +++ b/src/user/chat.rs @@ -61,6 +61,8 @@ impl InteractScreen { /// Sync conversation display from agent entries. fn sync_from_agent(&mut self) { + use crate::agent::api::types::Role; + let agent = self.agent.blocking_lock(); let gen = agent.generation; let count = agent.entries().len(); @@ -74,23 +76,54 @@ impl InteractScreen { } // Render new entries - if count > self.last_entry_count { - for entry in &agent.entries()[self.last_entry_count..] { - let msg = entry.message(); - let text = msg.content_text(); - match msg.role { - crate::agent::api::types::Role::User => { - self.conversation.push_line_with_marker( - text.to_string(), Color::Cyan, Marker::User, - ); + for entry in agent.entries().iter().skip(self.last_entry_count) { + let msg = entry.message(); + let text = msg.content_text(); + + // Skip memory/system-reminder entries — they're context, not conversation + if let crate::agent::context::ConversationEntry::Memory { .. } = entry { + continue; + } + + match msg.role { + Role::User => { + // Skip system-reminder injections + if text.starts_with("") { + continue; } - crate::agent::api::types::Role::Assistant => { + self.conversation.push_line_with_marker( + text.to_string(), Color::Cyan, Marker::User, + ); + } + Role::Assistant => { + // Tool calls show in tools pane + if let Some(ref calls) = msg.tool_calls { + for call in calls { + let line = format!("[{}] {}", call.function.name, + call.function.arguments.chars().take(80).collect::()); + self.tools.push_line(line, Color::Yellow); + } + } + // Text content to conversation + if !text.is_empty() { self.conversation.push_line_with_marker( text.to_string(), Color::Reset, Marker::Assistant, ); } - _ => {} } + Role::Tool => { + // Tool results to tools pane + for line in text.lines().take(20) { + self.tools.push_line(format!(" {}", line), Color::DarkGray); + } + if text.lines().count() > 20 { + self.tools.push_line( + format!(" ... ({} more lines)", text.lines().count() - 20), + Color::DarkGray, + ); + } + } + Role::System => {} // skip } }