diff --git a/astrbot/core/agent/context/compressor.py b/astrbot/core/agent/context/compressor.py index 31a0b0b48d..d4642bc506 100644 --- a/astrbot/core/agent/context/compressor.py +++ b/astrbot/core/agent/context/compressor.py @@ -218,11 +218,15 @@ async def __call__(self, messages: list[Message]) -> list[Message]: # generate summary try: response = await self.provider.text_chat(contexts=llm_payload) - summary_content = response.completion_text + summary_content = (response.completion_text or "").strip() except Exception as e: logger.error(f"Failed to generate summary: {e}") return messages + if not summary_content: + logger.warning("LLM context compression returned an empty summary.") + return messages + # build result result = [] result.extend(system_messages) diff --git a/tests/agent/test_context_manager.py b/tests/agent/test_context_manager.py index 0b955ff401..1685947b0a 100644 --- a/tests/agent/test_context_manager.py +++ b/tests/agent/test_context_manager.py @@ -94,6 +94,25 @@ def test_init_with_truncate_compressor(self): assert isinstance(manager.compressor, TruncateByTurnsCompressor) + @pytest.mark.asyncio + async def test_llm_compressor_keeps_history_when_summary_is_empty(self): + from astrbot.core.agent.context.compressor import LLMSummaryCompressor + + provider = MockProvider() + provider.text_chat = AsyncMock( + return_value=LLMResponse(role="assistant", completion_text=" ") + ) + compressor = LLMSummaryCompressor(provider=provider, keep_recent=2) # type: ignore[arg-type] + messages = self.create_messages(6) + + with patch("astrbot.core.agent.context.compressor.logger") as mock_logger: + result = await compressor(messages) + + assert result == messages + mock_logger.warning.assert_called_once_with( + "LLM context compression returned an empty summary." + ) + # ==================== Empty and Edge Cases ==================== @pytest.mark.asyncio