Skip to content

CLI-52: Fix hang on interrupt during LLM processing#609

Open
szmania wants to merge 19 commits into
cecli-dev:mainfrom
szmania:cli-52-fix-hang-on-interrupt
Open

CLI-52: Fix hang on interrupt during LLM processing#609
szmania wants to merge 19 commits into
cecli-dev:mainfrom
szmania:cli-52-fix-hang-on-interrupt

Conversation

@szmania

@szmania szmania commented Jul 16, 2026

Copy link
Copy Markdown

Bug: cecli hangs in "Processing..." status after the user interrupts 2 or more times (Ctrl+C) during LLM processing.

Root Cause: Asymmetric state reset in worker.interrupt() - only sets output_running=False but NOT input_running=False.

Fix: A layered approach was implemented:

  • Layer 1: Symmetric state reset in worker.interrupt()
  • Layer 2: Changed asyncio.wait to FIRST_COMPLETED
  • Layer 3: interrupt_event is cleared in _run_parallel's finally block.

Files Changed:

  • cecli/tui/worker.py
  • cecli/coders/base_coder.py

Reference: See .cecli.plans.md for full details.

Your Name added 15 commits July 6, 2026 21:17
Co-authored-by: cecli (openai/nvidia_nim/deepseek-ai/deepseek-v4-pro)
Co-authored-by: cecli (openai/code)
import pytest
from cecli.coders.base_coder import Coder
from tests.unit.test_run_parallel import test_run_parallel_first_completed, test_worker_interrupt_sets_both_flags_false
from tests.unit.test_interrupt_event import test_interrupt_event_cleared_in_run_parallel
from tests.unit.test_worker_interrupt import test_worker_interrupt_with_missing_input_running_attribute

@pytest.mark.asyncio
async def test_sub_agent_interrupt():
    """Test sub-agent interrupt."""
    # Create a mock target_coder with the required attributes
    target_coder = MagicMock(spec=BaseCoder)
    target_coder.input_running = True
    target_coder.output_running = True
    target_coder.interrupt_event = MagicMock()

    # Create worker instance
    worker = CoderWorker(target_coder, MagicMock(), MagicMock())

    # Call interrupt method - should not raise AttributeError
    worker.interrupt()

    # Assert output_running is still set to False
    assert target_coder.output_running is False

```

**Explanation:**

1. **Import Necessary Modules:**
   - `pytest`: For running unit tests.
   - `cecli.coders.base_coder`:  For the `BaseCoder` class, which represents a base coder for various tasks.
   - `tests.unit.test_run_parallel`: Contains test functions for `test_run_parallel_first_completed` and `test_worker_interrupt_sets_both_flags_false`.
   - `tests.unit.test_interrupt_event`: Contains test functions for `test_interrupt_event_cleared_in_run_parallel`.
   - `tests.unit.test_worker_interrupt`: Contains test functions for `test_worker_interrupt_with_missing_input_running_attribute`

2. **Define Test Functions:**
   -  Each function is named with a descriptive name that indicates its purpose (e.g., `test_sub_agent_interrupt`).

3. **Create Mock Objects:**
    - We create mock objects for the `BaseCoder` class and other relevant components to simulate real-world scenarios.

4. **Set Up Worker Instance:**
   -  We create a `CoderWorker` instance, passing in the mock `target_coder`.

5. **Call Interrupt Method:**
    - We call the `interrupt()` method on the `worker` object. This simulates an interrupt event.

6. **Assert Results:**
   - We assert that the output running flag is set to False after calling the interrupt method, ensuring the interrupt functionality works as expected.

**Key Points:**

* **Test Structure:**  The test functions are structured in a way that allows you to easily test different aspects of the code's behavior.
* **Mock Objects:** Mock objects help isolate and control the behavior of specific parts of your code, making it easier to write tests for complex interactions.

**Running Tests:**

To run these tests:

1.  Make sure you have pytest installed (`pip install pytest`).
2.  Save the test code as a Python file (e.g., `test_interrupt_worker.py`).
3.  Run the tests using the command `pytest test_interrupt_worker.py`.

Let me know if you'd like to explore more advanced testing techniques or have any other questions!

Co-authored-by: cecli (openai/code)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
Co-authored-by: cecli (openai/gemini_cli/gemini-2.5-pro)
@szmania szmania changed the title Fix: Apply linting fixes to codebase CLI-52: Fix hang on interrupt during LLM processing Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant