From af0c214a34e27c3013292d384a082665b57d8228 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 18 May 2026 21:11:34 -0700 Subject: [PATCH 1/4] cli-23: auto compaction disabled when exit or /clear --- cecli/coders/base_coder.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cecli/coders/base_coder.py b/cecli/coders/base_coder.py index 28a072738c9..10f18a35aa1 100755 --- a/cecli/coders/base_coder.py +++ b/cecli/coders/base_coder.py @@ -1573,9 +1573,14 @@ async def generate(self, user_message, preproc): try: if self.enable_context_compaction: - self.compact_context_completed = False - await self.compact_context_if_needed() - self.compact_context_completed = True + # Skip compaction if the user wants to clear or exit + # Compacting is wasteful since /clear will clear everything + # and /exit will exit the application + stripped = user_message.strip() + if stripped not in ("/clear", "/exit", "/quit"): + self.compact_context_completed = False + await self.compact_context_if_needed() + self.compact_context_completed = True self.run_one_completed = False await self.run_one(user_message, preproc) From 39b12ed1cfb62f2be21d2953abad6043410b717d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 19 May 2026 11:53:39 -0700 Subject: [PATCH 2/4] test: add tests for compaction skipping in coder.generate --- tests/commands/test_compaction.py | 105 ++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 tests/commands/test_compaction.py diff --git a/tests/commands/test_compaction.py b/tests/commands/test_compaction.py new file mode 100644 index 00000000000..3bdfbda48c9 --- /dev/null +++ b/tests/commands/test_compaction.py @@ -0,0 +1,105 @@ +import asyncio +import pytest +from unittest.mock import AsyncMock, MagicMock + +# It's better to patch the Coder class where it's used if possible, +# but for this test, we will instantiate it and mock its methods. +from cecli.coders.base_coder import Coder +from cecli.io import InputOutput + + +@pytest.fixture +def mock_io(): + """Fixture for a mocked InputOutput object.""" + return MagicMock(spec=InputOutput) + + +@pytest.fixture +def mock_model(): + """Fixture for a mocked model object.""" + model = MagicMock() + model.info = {"max_input_tokens": 10000} + # Mock the name attribute that is used in Coder.create + model.name = "mock_model" + model.edit_format = "wholefile" + return model + + +@pytest.mark.asyncio +async def test_generate_skips_compaction_for_clear_command(mock_io, mock_model): + """ + Verify that compact_context_if_needed is NOT called for the /clear command. + """ + # Arrange + coder = await Coder.create(main_model=mock_model, io=mock_io, edit_format="wholefile") + coder.enable_context_compaction = True + coder.compact_context_if_needed = AsyncMock() + coder.run_one = AsyncMock() + user_message = "/clear" + + # Act + await coder.generate(user_message, preproc=True) + + # Assert + coder.compact_context_if_needed.assert_not_called() + coder.run_one.assert_called_once_with(user_message, True) + + +@pytest.mark.asyncio +async def test_generate_skips_compaction_for_exit_command(mock_io, mock_model): + """ + Verify that compact_context_if_needed is NOT called for the /exit command. + """ + # Arrange + coder = await Coder.create(main_model=mock_model, io=mock_io, edit_format="wholefile") + coder.enable_context_compaction = True + coder.compact_context_if_needed = AsyncMock() + coder.run_one = AsyncMock() + user_message = "/exit" + + # Act + await coder.generate(user_message, preproc=True) + + # Assert + coder.compact_context_if_needed.assert_not_called() + coder.run_one.assert_called_once_with(user_message, True) + + +@pytest.mark.asyncio +async def test_generate_skips_compaction_for_quit_command(mock_io, mock_model): + """ + Verify that compact_context_if_needed is NOT called for the /quit command. + """ + # Arrange + coder = await Coder.create(main_model=mock_model, io=mock_io, edit_format="wholefile") + coder.enable_context_compaction = True + coder.compact_context_if_needed = AsyncMock() + coder.run_one = AsyncMock() + user_message = "/quit" + + # Act + await coder.generate(user_message, preproc=True) + + # Assert + coder.compact_context_if_needed.assert_not_called() + coder.run_one.assert_called_once_with(user_message, True) + + +@pytest.mark.asyncio +async def test_generate_runs_compaction_for_regular_message(mock_io, mock_model): + """ + Verify that compact_context_if_needed IS called for a regular message. + """ + # Arrange + coder = await Coder.create(main_model=mock_model, io=mock_io, edit_format="wholefile") + coder.enable_context_compaction = True + coder.compact_context_if_needed = AsyncMock() + coder.run_one = AsyncMock() + user_message = "This is a regular message" + + # Act + await coder.generate(user_message, preproc=True) + + # Assert + coder.compact_context_if_needed.assert_called_once() + coder.run_one.assert_called_once_with(user_message, True) From 2ecfca74f418fb86c9b3fb32657af3c91f70eb65 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 19 May 2026 11:53:42 -0700 Subject: [PATCH 3/4] fix: Remove unused asyncio import in test_compaction.py Co-authored-by: cecli (openai/nvidia_nim/deepseek-ai/deepseek-v4-pro) --- tests/commands/test_compaction.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/commands/test_compaction.py b/tests/commands/test_compaction.py index 3bdfbda48c9..4bfc00a9e24 100644 --- a/tests/commands/test_compaction.py +++ b/tests/commands/test_compaction.py @@ -1,4 +1,3 @@ -import asyncio import pytest from unittest.mock import AsyncMock, MagicMock From 5fb1a45a9e7092421a4de4021bdde57a08e65dcf Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 19 May 2026 13:07:29 -0700 Subject: [PATCH 4/4] cli-23: fix isort --- tests/commands/test_compaction.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/commands/test_compaction.py b/tests/commands/test_compaction.py index 4bfc00a9e24..3d17cfd4993 100644 --- a/tests/commands/test_compaction.py +++ b/tests/commands/test_compaction.py @@ -1,6 +1,7 @@ -import pytest from unittest.mock import AsyncMock, MagicMock +import pytest + # It's better to patch the Coder class where it's used if possible, # but for this test, we will instantiate it and mock its methods. from cecli.coders.base_coder import Coder