diff --git a/src/cortex-tui/src/app/streaming.rs b/src/cortex-tui/src/app/streaming.rs index cd09013..03f5eb1 100644 --- a/src/cortex-tui/src/app/streaming.rs +++ b/src/cortex-tui/src/app/streaming.rs @@ -4,6 +4,9 @@ use std::time::Instant; #[derive(Debug, Clone, Default)] pub struct StreamingState { pub is_streaming: bool, + /// Whether we are actively receiving tokens from the LLM. + /// False when waiting for first token (processing), true when streaming. + pub is_actively_streaming: bool, pub current_tool: Option, pub tool_status: Option, pub thinking: bool, @@ -29,6 +32,7 @@ impl StreamingState { /// If false, preserves existing timer (use for tool continuations). pub fn start(&mut self, tool: Option, reset_timer: bool) { self.is_streaming = true; + self.is_actively_streaming = false; // Not yet receiving tokens self.thinking = true; self.current_tool = tool; self.task_started_at = Some(Instant::now()); @@ -39,6 +43,12 @@ impl StreamingState { } } + /// Mark that we started actively receiving tokens from the LLM. + /// This transitions from "Execute" (waiting) to "Streaming.." state. + pub fn start_active_streaming(&mut self) { + self.is_actively_streaming = true; + } + /// Get the elapsed seconds since the task started pub fn elapsed_seconds(&self) -> u64 { self.task_started_at @@ -57,6 +67,7 @@ impl StreamingState { /// Reset streaming state when task completes pub fn stop(&mut self) { self.is_streaming = false; + self.is_actively_streaming = false; self.thinking = false; self.current_tool = None; self.tool_status = None; diff --git a/src/cortex-tui/src/runner/event_loop/streaming.rs b/src/cortex-tui/src/runner/event_loop/streaming.rs index 25e5b8c..82ca818 100644 --- a/src/cortex-tui/src/runner/event_loop/streaming.rs +++ b/src/cortex-tui/src/runner/event_loop/streaming.rs @@ -305,6 +305,8 @@ impl EventLoop { match event { StreamEvent::Delta(delta) => { self.stream_controller.append_text(&delta); + // Mark that we are now actively receiving tokens (transition from Execute to Streaming..) + self.app_state.streaming.start_active_streaming(); // Track text for interleaved display self.app_state.append_streaming_text(&delta); // Keep scroll at bottom if pinned (user hasn't scrolled up) diff --git a/src/cortex-tui/src/views/minimal_session/view.rs b/src/cortex-tui/src/views/minimal_session/view.rs index 725dd0e..9f48953 100644 --- a/src/cortex-tui/src/views/minimal_session/view.rs +++ b/src/cortex-tui/src/views/minimal_session/view.rs @@ -402,7 +402,12 @@ impl<'a> MinimalSessionView<'a> { } else if self.app_state.streaming.thinking && self.app_state.thinking_budget.is_some() { "Thinking".to_string() } else if self.app_state.streaming.is_streaming { - "Working".to_string() + // Differentiate between waiting for first token and actively streaming + if self.app_state.streaming.is_actively_streaming { + "Streaming..".to_string() + } else { + "Execute".to_string() + } } else { "Idle".to_string() }