Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cortex-tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ pub struct SubagentTaskDisplay {
pub started_at: Instant,
/// Current todo items from the subagent (if any).
pub todos: Vec<SubagentTodoItem>,
/// Error message if the subagent failed.
/// Stored separately so it can be displayed even when the task is removed.
pub error_message: Option<String>,
}

impl SubagentTaskDisplay {
Expand All @@ -294,6 +297,7 @@ impl SubagentTaskDisplay {
output_preview: String::new(),
started_at: Instant::now(),
todos: Vec::new(),
error_message: None,
}
}

Expand Down
19 changes: 15 additions & 4 deletions cortex-tui/src/runner/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3419,12 +3419,23 @@ impl EventLoop {
format!("Error: {}", error),
);

// If this is a Task tool, remove the subagent from display
// If this is a Task tool, update subagent status to Failed with error message
// Keep the subagent visible so users can see what error occurred
if name == "Task" || name == "task" {
let session_id = format!("subagent_{}", id);
self.app_state.remove_subagent(&session_id);
// Stop delegation mode if no more active subagents
if !self.app_state.has_active_subagents() {
let error_clone = error.clone();
self.app_state.update_subagent(&session_id, |task| {
task.status = SubagentDisplayStatus::Failed;
task.error_message = Some(error_clone);
task.current_activity = "Failed".to_string();
});
// Stop delegation mode if no more active (non-failed) subagents
let has_running_subagents = self
.app_state
.active_subagents
.iter()
.any(|t| !t.status.is_terminal());
if !has_running_subagents {
self.app_state.streaming.stop_delegation();
}
}
Expand Down
31 changes: 29 additions & 2 deletions cortex-tui/src/views/minimal_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,35 @@ impl<'a> MinimalSessionView<'a> {
),
]));

// Display todos if any - use ⎿ prefix for first, space for rest
if !task.todos.is_empty() {
// Display error message if task failed
if task.status == SubagentDisplayStatus::Failed {
if let Some(ref error_msg) = task.error_message {
lines.push(Line::from(vec![
Span::styled(" ⎿ ", Style::default().fg(self.colors.text_muted)),
Span::styled("Error: ", Style::default().fg(self.colors.error)),
]));
// Display error message, truncate if too long
for (i, err_line) in error_msg.lines().take(5).enumerate() {
let truncated = if err_line.len() > 70 {
format!("{}...", &err_line.chars().take(67).collect::<String>())
} else {
err_line.to_string()
};
let prefix = if i == 0 { " " } else { " " };
lines.push(Line::from(vec![
Span::styled(prefix, Style::default().fg(self.colors.text_muted)),
Span::styled(truncated, Style::default().fg(self.colors.error)),
]));
}
} else {
// Fallback: no error message provided
lines.push(Line::from(vec![
Span::styled(" ⎿ ", Style::default().fg(self.colors.text_muted)),
Span::styled("Task failed", Style::default().fg(self.colors.error)),
]));
}
} else if !task.todos.is_empty() {
// Display todos if any - use ⎿ prefix for first, space for rest
for (i, todo) in task.todos.iter().enumerate() {
let (status_text, status_color) = match todo.status {
SubagentTodoStatus::Completed => ("[completed]", self.colors.success),
Expand Down
Loading