Stop streaming and return final content. Args: interrupted: Whether streaming was interrupted by user Returns: Final accumulated content
(self, interrupted: bool = False)
| 153 | await self._trigger_refresh() |
| 154 | |
| 155 | async def stop_streaming(self, interrupted: bool = False) -> str: |
| 156 | """Stop streaming and return final content. |
| 157 | |
| 158 | Args: |
| 159 | interrupted: Whether streaming was interrupted by user |
| 160 | |
| 161 | Returns: |
| 162 | Final accumulated content |
| 163 | """ |
| 164 | if not self.streaming_state: |
| 165 | logger.warning("No active streaming state to stop") |
| 166 | return "" |
| 167 | |
| 168 | # Mark state as complete |
| 169 | self.streaming_state.complete(interrupted=interrupted) |
| 170 | |
| 171 | # Stop refresh loop |
| 172 | await self._stop_refresh_loop() |
| 173 | |
| 174 | # Finish the live display (clear and reset state) |
| 175 | self._finish_display() |
| 176 | |
| 177 | # Show final output |
| 178 | final_content = self.streaming_state.accumulated_content |
| 179 | elapsed = self.streaming_state.elapsed_time |
| 180 | chunks_received = self.streaming_state.chunks_received |
| 181 | |
| 182 | if final_content: |
| 183 | self._show_final_response(final_content, elapsed, interrupted) |
| 184 | |
| 185 | logger.debug( |
| 186 | f"Stopped streaming: {len(final_content)} chars in {elapsed:.2f}s, " |
| 187 | f"{chunks_received} chunks" |
| 188 | ) |
| 189 | |
| 190 | # Clear streaming state to avoid any interference with subsequent tool execution |
| 191 | # This ensures the display manager is in a clean state for the next operation |
| 192 | self.streaming_state = None |
| 193 | |
| 194 | return final_content |
| 195 | |
| 196 | # ==================== TOOL EXECUTION OPERATIONS ==================== |
| 197 |