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
7 changes: 7 additions & 0 deletions cortex-tui/src/agent/system_prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ pub const SYSTEM_PROMPT_TEMPLATE: &str = r#"You are Cortex, an expert AI coding
- For shell commands, explain what they do before executing
- Call multiple tools in parallel when operations are independent

# Todo List (IMPORTANT)
For any non-trivial task that requires multiple steps:
- Use the TodoWrite tool immediately to create a todo list tracking your progress
- Update the todo list as you complete each step (mark items as in_progress or completed)
- This provides real-time visibility to the user on what you're working on
- Keep only ONE item as in_progress at a time

# Guidelines
- Always verify paths exist before operations
- Handle errors gracefully and suggest alternatives
Expand Down
40 changes: 40 additions & 0 deletions cortex-tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ pub struct StreamingState {
pub executing_tool: Option<String>,
/// When the tool started executing (for elapsed time display)
pub tool_started_at: Option<Instant>,
/// When the last user prompt was sent (for total elapsed time from user's perspective)
/// This persists across streaming restarts (e.g., after tool execution)
pub prompt_started_at: Option<Instant>,
/// Whether a subagent (Task) is currently running
pub is_delegating: bool,
}

impl Default for StreamingState {
Expand All @@ -61,6 +66,8 @@ impl Default for StreamingState {
task_started_at: None,
executing_tool: None,
tool_started_at: None,
prompt_started_at: None,
is_delegating: false,
}
}
}
Expand All @@ -71,6 +78,10 @@ impl StreamingState {
self.thinking = true;
self.current_tool = tool;
self.task_started_at = Some(Instant::now());
// Only set prompt_started_at if not already set (first call in a turn)
if self.prompt_started_at.is_none() {
self.prompt_started_at = Some(Instant::now());
}
}

/// Get the elapsed seconds since the task started
Expand All @@ -80,13 +91,40 @@ impl StreamingState {
.unwrap_or(0)
}

/// Get the elapsed seconds since the original prompt was sent
/// This is the total time from the user's perspective
pub fn prompt_elapsed_seconds(&self) -> u64 {
self.prompt_started_at
.map(|t| t.elapsed().as_secs())
.unwrap_or(0)
}

/// Reset streaming state when task completes
pub fn stop(&mut self) {
self.is_streaming = false;
self.thinking = false;
self.current_tool = None;
self.tool_status = None;
self.task_started_at = None;
// Note: prompt_started_at is NOT reset here - it persists until full_reset()
}

/// Full reset when the entire conversation turn is complete
/// (no more tool executions or continuations expected)
pub fn full_reset(&mut self) {
self.stop();
self.prompt_started_at = None;
self.is_delegating = false;
}

/// Start delegation mode (subagent is running)
pub fn start_delegation(&mut self) {
self.is_delegating = true;
}

/// Stop delegation mode
pub fn stop_delegation(&mut self) {
self.is_delegating = false;
}

/// Start tool execution in background
Expand Down Expand Up @@ -1347,6 +1385,8 @@ impl AppState {
pub fn clear_tool_calls(&mut self) {
self.tool_calls.clear();
self.clear_content_segments();
// Also clear completed/failed subagents from the previous turn
self.active_subagents.retain(|t| !t.status.is_terminal());
}

/// Advance spinner frames for all running tool calls
Expand Down
Loading
Loading