Fix chat display: restore incremental sync with change detection
sync_from_agent now detects changed entries by comparing token counts (cheap proxy for content changes during streaming). Changed entries get popped and re-pushed. Extracted push_routed/pop_routed helpers. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
31e813f57d
commit
5f5a8a807c
1 changed files with 61 additions and 25 deletions
|
|
@ -456,6 +456,43 @@ impl InteractScreen {
|
|||
}
|
||||
}
|
||||
|
||||
fn push_routed(&mut self, node: &AstNode) {
|
||||
for (target, text, marker) in Self::route_node(node) {
|
||||
match target {
|
||||
PaneTarget::Conversation => {
|
||||
self.conversation.current_color = Color::Cyan;
|
||||
self.conversation.append_text(&text);
|
||||
self.conversation.pending_marker = marker;
|
||||
self.conversation.flush_pending();
|
||||
},
|
||||
PaneTarget::ConversationAssistant => {
|
||||
self.conversation.current_color = Color::Reset;
|
||||
self.conversation.append_text(&text);
|
||||
self.conversation.pending_marker = marker;
|
||||
self.conversation.flush_pending();
|
||||
},
|
||||
PaneTarget::Tools =>
|
||||
self.tools.push_line(text, Color::Yellow),
|
||||
PaneTarget::ToolResult => {
|
||||
for line in text.lines().take(20) {
|
||||
self.tools.push_line(format!(" {}", line), Color::DarkGray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_routed(&mut self, node: &AstNode) {
|
||||
for (target, _, _) in Self::route_node(node) {
|
||||
match target {
|
||||
PaneTarget::Conversation | PaneTarget::ConversationAssistant
|
||||
=> self.conversation.pop_line(),
|
||||
PaneTarget::Tools | PaneTarget::ToolResult
|
||||
=> self.tools.pop_line(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn sync_from_agent(&mut self) {
|
||||
for _ in 0..self.pending_display_count {
|
||||
self.conversation.pop_line();
|
||||
|
|
@ -476,38 +513,37 @@ impl InteractScreen {
|
|||
(generation, ctx.conversation().to_vec())
|
||||
};
|
||||
|
||||
if generation != self.last_generation || entries.len() < self.last_entries.len() {
|
||||
// Full reset on generation change
|
||||
if generation != self.last_generation {
|
||||
self.conversation = PaneState::new(true);
|
||||
self.autonomous = PaneState::new(true);
|
||||
self.tools = PaneState::new(false);
|
||||
self.last_entries.clear();
|
||||
}
|
||||
|
||||
let start = self.last_entries.len();
|
||||
for node in entries.iter().skip(start) {
|
||||
for (target, text, marker) in Self::route_node(node) {
|
||||
match target {
|
||||
PaneTarget::Conversation => {
|
||||
self.conversation.current_color = Color::Cyan;
|
||||
self.conversation.append_text(&text);
|
||||
self.conversation.pending_marker = marker;
|
||||
self.conversation.flush_pending();
|
||||
},
|
||||
PaneTarget::ConversationAssistant => {
|
||||
self.conversation.current_color = Color::Reset;
|
||||
self.conversation.append_text(&text);
|
||||
self.conversation.pending_marker = marker;
|
||||
self.conversation.flush_pending();
|
||||
},
|
||||
PaneTarget::Tools =>
|
||||
self.tools.push_line(text, Color::Yellow),
|
||||
PaneTarget::ToolResult => {
|
||||
for line in text.lines().take(20) {
|
||||
self.tools.push_line(format!(" {}", line), Color::DarkGray);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Detect changed entries (streaming updates mutate the last entry)
|
||||
// Walk backwards from the end, pop any that differ
|
||||
let mut pop_from = self.last_entries.len();
|
||||
for i in (0..self.last_entries.len()).rev() {
|
||||
if i >= entries.len() {
|
||||
pop_from = i;
|
||||
continue;
|
||||
}
|
||||
// Compare token count as a cheap change detector
|
||||
if self.last_entries[i].tokens() != entries[i].tokens() {
|
||||
pop_from = i;
|
||||
} else {
|
||||
break; // entries before this haven't changed
|
||||
}
|
||||
}
|
||||
while self.last_entries.len() > pop_from {
|
||||
let popped = self.last_entries.pop().unwrap();
|
||||
self.pop_routed(&popped);
|
||||
}
|
||||
|
||||
// Push new/changed entries
|
||||
for node in entries.iter().skip(self.last_entries.len()) {
|
||||
self.push_routed(node);
|
||||
self.last_entries.push(node.clone());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue