feat: implement company pipeline orchestration with user commands for full, quick, and skip modes
This commit is contained in:
@@ -36,6 +36,9 @@ pub struct AgentStatus {
|
||||
pub started_at: Option<i64>,
|
||||
pub completed_at: Option<i64>,
|
||||
pub error: Option<String>,
|
||||
/// Human-readable progress message (e.g. "editing src/main.rs",
|
||||
/// "running cargo test"). Shown in the TUI panel alongside the state.
|
||||
pub progress: Option<String>,
|
||||
}
|
||||
|
||||
/// A single agent tracked within a workflow run.
|
||||
@@ -124,6 +127,7 @@ fn spawn_single_agent(
|
||||
started_at: Some(started_at),
|
||||
completed_at: None,
|
||||
error: None,
|
||||
progress: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -156,26 +160,52 @@ fn spawn_single_agent(
|
||||
// long-running agents. No abort mechanism is wired yet at this level;
|
||||
// future work can expose a kill-switch per agent via the live callback.
|
||||
|
||||
// Create an mpsc channel and drain events in a background thread so
|
||||
// run_subagent's blocking_send never blocks (previously the _rx was
|
||||
// dropped immediately, which would cause blocking_send to panic/fail
|
||||
// on a closed channel).
|
||||
// Create an mpsc channel and drain events in a background thread.
|
||||
// The drain thread also pushes intra-division progress updates to the
|
||||
// live callback (current tool being executed), so the TUI panel shows
|
||||
// real-time "editing X" or "running build" instead of just "Running…".
|
||||
let (tx, rx) = tokio::sync::mpsc::channel(64);
|
||||
let drain_agent_id = agent_id.to_string();
|
||||
let drain_agent_name = agent_name.to_string();
|
||||
let drain_live = live.cloned();
|
||||
let drain_started_at = started_at;
|
||||
let _drain_thread = std::thread::spawn(move || {
|
||||
// Drain all events so run_subagent's blocking_send never blocks.
|
||||
// Individual SubagentEvent items are not surfaced to the TUI —
|
||||
// the live state callbacks above handle coarse-grained Running /
|
||||
// Completed / Failed status. ToolCall / ToolResult / StepCompleted
|
||||
// events are traced at debug level for observability.
|
||||
use crate::app::subagent::event::SubagentEvent;
|
||||
let mut rx = rx;
|
||||
while let Some(event) = rx.blocking_recv() {
|
||||
match &event {
|
||||
SubagentEvent::ToolCall { _tool, _args } => {
|
||||
tracing::debug!("[subagent] tool call: {}", _tool);
|
||||
// Push intra-division progress: which tool is running
|
||||
if let Some(ref f) = drain_live {
|
||||
f(
|
||||
drain_agent_id.clone(),
|
||||
drain_agent_name.clone(),
|
||||
AgentStatus {
|
||||
state: AgentState::Running,
|
||||
started_at: Some(drain_started_at),
|
||||
completed_at: None,
|
||||
error: None,
|
||||
progress: Some(format!("tool: {}", _tool)),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
SubagentEvent::ToolResult { _tool, .. } => {
|
||||
tracing::debug!("[subagent] tool result: {}", _tool);
|
||||
if let Some(ref f) = drain_live {
|
||||
f(
|
||||
drain_agent_id.clone(),
|
||||
drain_agent_name.clone(),
|
||||
AgentStatus {
|
||||
state: AgentState::Running,
|
||||
started_at: Some(drain_started_at),
|
||||
completed_at: None,
|
||||
error: None,
|
||||
progress: Some(format!("done: {}", _tool)),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
SubagentEvent::StepCompleted { _step, .. } => {
|
||||
tracing::trace!("[subagent] step {} completed", _step);
|
||||
@@ -226,6 +256,7 @@ fn spawn_single_agent(
|
||||
started_at: Some(started_at),
|
||||
completed_at: Some(completed_at),
|
||||
error: None,
|
||||
progress: None,
|
||||
},
|
||||
),
|
||||
Err(e) => f(
|
||||
@@ -236,6 +267,7 @@ fn spawn_single_agent(
|
||||
started_at: Some(started_at),
|
||||
completed_at: Some(completed_at),
|
||||
error: Some(e.to_string()),
|
||||
progress: None,
|
||||
},
|
||||
),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user