chat: state-driven sync from agent entries
InteractScreen holds agent ref, syncs conversation display from agent.entries() on each tick via blocking_lock(). Tracks generation counter and entry count to detect compactions and new entries. Agent gets a generation counter, incremented on compaction and non-last-entry mutations (age_out_images). sync_from_agent() is the single path for pane updates. UiMessage handle_ui_message still exists but will be removed once sync handles all entry types (streaming, tool calls, DMN). Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
6f000bd0f6
commit
350c447ebc
3 changed files with 57 additions and 2 deletions
|
|
@ -31,10 +31,15 @@ pub(crate) struct InteractScreen {
|
|||
pub(crate) turn_started: Option<std::time::Instant>,
|
||||
pub(crate) call_started: Option<std::time::Instant>,
|
||||
pub(crate) call_timeout_secs: u64,
|
||||
// State sync with agent
|
||||
last_generation: u64,
|
||||
last_entry_count: usize,
|
||||
/// Reference to agent for state sync
|
||||
agent: std::sync::Arc<tokio::sync::Mutex<crate::agent::Agent>>,
|
||||
}
|
||||
|
||||
impl InteractScreen {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(agent: std::sync::Arc<tokio::sync::Mutex<crate::agent::Agent>>) -> Self {
|
||||
Self {
|
||||
autonomous: PaneState::new(true),
|
||||
conversation: PaneState::new(true),
|
||||
|
|
@ -48,9 +53,51 @@ impl InteractScreen {
|
|||
turn_started: None,
|
||||
call_started: None,
|
||||
call_timeout_secs: 60,
|
||||
last_generation: 0,
|
||||
last_entry_count: 0,
|
||||
agent,
|
||||
}
|
||||
}
|
||||
|
||||
/// Sync conversation display from agent entries.
|
||||
fn sync_from_agent(&mut self) {
|
||||
let agent = self.agent.blocking_lock();
|
||||
let gen = agent.generation;
|
||||
let count = agent.entries().len();
|
||||
|
||||
if gen != self.last_generation {
|
||||
// Generation changed — full re-render
|
||||
self.conversation = PaneState::new(true);
|
||||
self.autonomous = PaneState::new(true);
|
||||
self.tools = PaneState::new(false);
|
||||
self.last_entry_count = 0;
|
||||
}
|
||||
|
||||
// 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,
|
||||
);
|
||||
}
|
||||
crate::agent::api::types::Role::Assistant => {
|
||||
self.conversation.push_line_with_marker(
|
||||
text.to_string(), Color::Reset, Marker::Assistant,
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.last_generation = gen;
|
||||
self.last_entry_count = count;
|
||||
}
|
||||
|
||||
/// Process a UiMessage — update pane state.
|
||||
pub fn handle_ui_message(&mut self, msg: &UiMessage, app: &mut App) {
|
||||
match msg {
|
||||
|
|
@ -399,6 +446,9 @@ impl ScreenView for InteractScreen {
|
|||
}
|
||||
}
|
||||
|
||||
// Sync state from agent
|
||||
self.sync_from_agent();
|
||||
|
||||
// Draw
|
||||
self.draw_main(frame, area, app);
|
||||
None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue