CLI-52: Fix hang on interrupt during LLM processing#609
Open
szmania wants to merge 19 commits into
Open
Conversation
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug:
ceclihangs 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 setsoutput_running=Falsebut NOTinput_running=False.Fix: A layered approach was implemented:
worker.interrupt()asyncio.waittoFIRST_COMPLETEDinterrupt_eventis cleared in_run_parallel'sfinallyblock.Files Changed:
cecli/tui/worker.pycecli/coders/base_coder.pyReference: See
.cecli.plans.mdfor full details.