Background loop that refreshes the display. Runs at 10 Hz (100ms interval) for smooth animation. Priority order: 1. Tool execution (highest priority - shows what's actively happening) 2. Streaming status (shows LLM response progress)
(self)
| 362 | logger.debug("Stopped refresh loop") |
| 363 | |
| 364 | async def _refresh_loop(self) -> None: |
| 365 | """Background loop that refreshes the display. |
| 366 | |
| 367 | Runs at 10 Hz (100ms interval) for smooth animation. |
| 368 | |
| 369 | Priority order: |
| 370 | 1. Tool execution (highest priority - shows what's actively happening) |
| 371 | 2. Streaming status (shows LLM response progress) |
| 372 | """ |
| 373 | try: |
| 374 | while self._refresh_active: |
| 375 | # Tool execution takes priority over streaming |
| 376 | # because we want to show what's actively happening |
| 377 | if self.tool_execution and not self.tool_execution.completed: |
| 378 | await self._render_tool_status() |
| 379 | elif self.streaming_state and self.streaming_state.is_active: |
| 380 | await self._render_streaming_status() |
| 381 | # If neither condition is met, don't render anything |
| 382 | # This prevents stale state from interfering |
| 383 | |
| 384 | await asyncio.sleep(0.1) # 10 Hz refresh |
| 385 | except asyncio.CancelledError: |
| 386 | # Expected when stopping the loop |
| 387 | pass |
| 388 | except Exception as e: |
| 389 | logger.error(f"Error in refresh loop: {e}", exc_info=True) |
| 390 | |
| 391 | async def _trigger_refresh(self) -> None: |
| 392 | """Trigger an immediate refresh (for new content).""" |
no test coverage detected