shared active tools: Agent writes, TUI reads directly

Move active tool tracking from TUI message-passing to shared
Arc<RwLock> state. Agent pushes on dispatch, removes on
apply_tool_result. TUI reads during render. Background tasks
show as active until drained at next turn start.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
ProofOfConcept 2026-04-03 22:57:46 -04:00
parent d25033b9f4
commit 474b66c834
6 changed files with 62 additions and 49 deletions

View file

@ -308,12 +308,8 @@ pub(crate) fn parse_markdown(md: &str) -> Vec<Line<'static>> {
}
/// A tool call currently in flight — shown above the status bar.
pub(crate) struct ActiveTool {
pub(crate) id: String,
pub(crate) name: String,
pub(crate) detail: String,
pub(crate) started: std::time::Instant,
}
// ActiveTool moved to ui_channel — shared between Agent and TUI
pub(crate) use crate::user::ui_channel::ActiveTool;
/// Main TUI application state.
pub struct App {
@ -335,7 +331,7 @@ pub struct App {
pub running_processes: u32,
/// Current reasoning effort level (for status display).
pub reasoning_effort: String,
pub(crate) active_tools: Vec<ActiveTool>,
pub(crate) active_tools: crate::user::ui_channel::SharedActiveTools,
pub(crate) active_pane: ActivePane,
/// User input editor (handles wrapping, cursor positioning).
pub textarea: tui_textarea::TextArea<'static>,
@ -422,7 +418,7 @@ pub enum HotkeyAction {
}
impl App {
pub fn new(model: String, shared_context: SharedContextState) -> Self {
pub fn new(model: String, shared_context: SharedContextState, active_tools: crate::user::ui_channel::SharedActiveTools) -> Self {
Self {
autonomous: PaneState::new(true), // markdown
conversation: PaneState::new(true), // markdown
@ -444,7 +440,7 @@ impl App {
needs_assistant_marker: false,
running_processes: 0,
reasoning_effort: "none".to_string(),
active_tools: Vec::new(),
active_tools,
active_pane: ActivePane::Conversation,
textarea: new_textarea(vec![String::new()]),
input_history: Vec::new(),
@ -548,17 +544,8 @@ impl App {
self.autonomous.current_color = Color::DarkGray;
self.autonomous.append_text(&text);
}
UiMessage::ToolStarted { id, name, detail } => {
self.active_tools.push(ActiveTool {
id,
name,
detail,
started: std::time::Instant::now(),
});
}
UiMessage::ToolFinished { id } => {
self.active_tools.retain(|t| t.id != id);
}
UiMessage::ToolStarted { .. } => {} // handled by shared active_tools
UiMessage::ToolFinished { .. } => {}
UiMessage::Debug(text) => {
self.tools.push_line(format!("[debug] {}", text), Color::DarkGray);
}