unify tool tracking: ActiveToolCall with JoinHandle

One data structure for all in-flight tool calls — metadata for
TUI display + JoinHandle for result collection and cancellation.
Agent spawns tool calls via tokio::spawn, pushes to shared
Arc<Mutex<Vec<ActiveToolCall>>>. TUI reads metadata, can abort().
No separate inflight/background collections.

Non-background: awaited after stream ends.
Background: persists, drained at next turn start.

Co-Developed-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
ProofOfConcept 2026-04-03 23:42:27 -04:00
parent 17a018ff12
commit a78f310e4d
5 changed files with 106 additions and 82 deletions

View file

@ -168,7 +168,7 @@ impl App {
)));
lines.push(Line::raw(format!(" Reasoning: {}", self.reasoning_effort)));
lines.push(Line::raw(format!(" Running processes: {}", self.running_processes)));
lines.push(Line::raw(format!(" Active tools: {}", self.active_tools.read().unwrap().len())));
lines.push(Line::raw(format!(" Active tools: {}", self.active_tools.lock().unwrap().len())));
let block = Block::default()
.title_top(Line::from(SCREEN_LEGEND).left_aligned())

View file

@ -17,7 +17,7 @@ impl App {
/// Draw the main (F1) screen — four-pane layout with status bar.
pub(crate) fn draw_main(&mut self, frame: &mut Frame, size: Rect) {
// Main layout: content area + active tools overlay + status bar
let active_tools = self.active_tools.read().unwrap();
let active_tools = self.active_tools.lock().unwrap();
let tool_lines = active_tools.len() as u16;
let main_chunks = Layout::default()
.direction(Direction::Vertical)

View file

@ -22,20 +22,14 @@ pub fn shared_context_state() -> SharedContextState {
Arc::new(RwLock::new(Vec::new()))
}
/// Active tool info for TUI display.
#[derive(Debug, Clone)]
pub struct ActiveTool {
pub id: String,
pub name: String,
pub detail: String,
pub started: std::time::Instant,
}
// ActiveToolCall lives in agent::tools — re-export for TUI access
pub use crate::agent::tools::ActiveToolCall;
/// Shared active tools — agent writes, TUI reads.
pub type SharedActiveTools = Arc<RwLock<Vec<ActiveTool>>>;
/// Shared active tool calls — agent spawns, TUI reads metadata / aborts.
pub type SharedActiveTools = Arc<std::sync::Mutex<Vec<ActiveToolCall>>>;
pub fn shared_active_tools() -> SharedActiveTools {
Arc::new(RwLock::new(Vec::new()))
Arc::new(std::sync::Mutex::new(Vec::new()))
}
/// Which pane streaming text should go to.