diff --git a/app/agent/__init__.py b/app/agent/__init__.py index ac919e5e..28a8ec75 100644 --- a/app/agent/__init__.py +++ b/app/agent/__init__.py @@ -643,14 +643,20 @@ class MoviePilotAgent: and not self._tool_context.get("user_reply_sent") ): if self.is_background: - if self.persist_output_message: - # 后台任务仅广播最终回复,带标题 - await self.send_agent_message( - final_text, title="MoviePilot助手" - ) + # 后台任务仅广播最终回复,带标题 + await self.send_agent_message( + final_text, title="MoviePilot助手" + ) else: # 非流式渠道:发送最终回复 await self.send_agent_message(final_text) + elif ( + final_text + and self.persist_output_message + and not self._tool_context.get("user_reply_sent") + ): + title = "MoviePilot助手" if self.is_background else "" + await self._save_agent_message_to_db(final_text, title=title) # 保存消息 memory_manager.save_agent_messages( diff --git a/tests/test_agent_background_output.py b/tests/test_agent_background_output.py index ab3b3674..771eba39 100644 --- a/tests/test_agent_background_output.py +++ b/tests/test_agent_background_output.py @@ -25,7 +25,7 @@ class _FakeAgent: class AgentBackgroundOutputTest(unittest.IsolatedAsyncioTestCase): - async def test_background_non_streaming_skips_send_when_output_persistence_disabled(self): + async def test_background_non_streaming_still_sends_when_reply_not_suppressed(self): agent = MoviePilotAgent(session_id="bg-test", user_id="system") agent.channel = None agent.source = None @@ -41,11 +41,43 @@ class AgentBackgroundOutputTest(unittest.IsolatedAsyncioTestCase): [AIMessage(content="后台结果")] ) agent.send_agent_message = AsyncMock() + agent._save_agent_message_to_db = AsyncMock() + + with patch.object(memory_manager, "save_agent_messages") as save_messages: + await agent._execute_agent([]) + + agent.send_agent_message.assert_awaited_once_with( + "后台结果", title="MoviePilot助手" + ) + agent._save_agent_message_to_db.assert_not_awaited() + save_messages.assert_called_once() + self.assertEqual("后台结果", agent._streamed_output) + + async def test_background_non_streaming_persists_without_sending_when_reply_suppressed(self): + agent = MoviePilotAgent(session_id="bg-test", user_id="system") + agent.channel = None + agent.source = None + agent.suppress_user_reply = True + agent.persist_output_message = True + agent._tool_context = {"user_reply_sent": False} + agent._streamed_output = "" + agent.stream_handler = SimpleNamespace( + stop_streaming=AsyncMock(return_value=(False, "")) + ) + agent._should_stream = lambda: False + agent._create_agent = lambda streaming=False: _FakeAgent( + [AIMessage(content="后台结果")] + ) + agent.send_agent_message = AsyncMock() + agent._save_agent_message_to_db = AsyncMock() with patch.object(memory_manager, "save_agent_messages") as save_messages: await agent._execute_agent([]) agent.send_agent_message.assert_not_awaited() + agent._save_agent_message_to_db.assert_awaited_once_with( + "后台结果", title="MoviePilot助手" + ) save_messages.assert_called_once() self.assertEqual("后台结果", agent._streamed_output)