From a767ddbfb86ee09b957912687bd8d292fd81b8d6 Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 19 Apr 2026 11:32:11 +0800 Subject: [PATCH 1/3] feat: add save_failed_agent_history config option --- astrbot/core/config/default.py | 12 ++++++++++++ .../method/agent_sub_stages/internal.py | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/astrbot/core/config/default.py b/astrbot/core/config/default.py index 527cfbf9be..bff117d5f7 100644 --- a/astrbot/core/config/default.py +++ b/astrbot/core/config/default.py @@ -134,6 +134,7 @@ "streaming_response": False, "show_tool_use_status": False, "show_tool_call_result": False, + "save_failed_agent_history": False, "sanitize_context_by_modalities": False, "max_quoted_fallback_images": 20, "quoted_message_parser": { @@ -2777,6 +2778,9 @@ class ChatProviderTemplate(TypedDict): "show_tool_call_result": { "type": "bool", }, + "save_failed_agent_history": { + "type": "bool", + }, "unsupported_streaming_strategy": { "type": "string", }, @@ -3543,6 +3547,14 @@ class ChatProviderTemplate(TypedDict): "provider_settings.show_tool_use_status": True, }, }, + "provider_settings.save_failed_agent_history": { + "description": "失败时保存本轮记录", + "type": "bool", + "hint": "启用后,当 Agent 本轮运行失败时(如模型返回空输出),也会将本轮记录保存到会话历史中,包括用户输入、工具调用记录和失败提示。", + "condition": { + "provider_settings.agent_runner_type": "local", + }, + }, "provider_settings.sanitize_context_by_modalities": { "description": "按模型能力清理历史上下文", "type": "bool", diff --git a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py index e0ba2463ca..7cb5a7985e 100644 --- a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +++ b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py @@ -67,6 +67,9 @@ async def initialize(self, ctx: PipelineContext) -> None: self.show_tool_use: bool = settings.get("show_tool_use_status", True) self.show_tool_call_result: bool = settings.get("show_tool_call_result", False) self.show_reasoning = settings.get("display_reasoning_text", False) + self.save_failed_agent_history: bool = settings.get( + "save_failed_agent_history", False + ) self.sanitize_context_by_modalities: bool = settings.get( "sanitize_context_by_modalities", False, @@ -296,6 +299,7 @@ async def process( agent_runner.run_context.messages, agent_runner.stats, user_aborted=agent_runner.was_aborted(), + save_failed_history=self.save_failed_agent_history, ) elif streaming_response and not stream_to_general: @@ -412,6 +416,7 @@ async def _save_to_history( all_messages: list[Message], runner_stats: AgentStats | None, user_aborted: bool = False, + save_failed_history: bool = False, ) -> None: if not req or not req.conversation: return @@ -433,6 +438,7 @@ async def _save_to_history( not llm_response.completion_text and not req.tool_calls_result and not user_aborted + and not save_failed_history ): logger.debug("LLM 响应为空,不保存记录。") return From d5b160a819d0b15909d76dcdb98ae617684e3e79 Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 19 Apr 2026 11:36:33 +0800 Subject: [PATCH 2/3] fix: pass save_failed_history in non-live mode and add info log --- .../process_stage/method/agent_sub_stages/internal.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py index 7cb5a7985e..a62ad91675 100644 --- a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +++ b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py @@ -373,6 +373,7 @@ async def process( agent_runner.run_context.messages, agent_runner.stats, user_aborted=agent_runner.was_aborted(), + save_failed_history=self.save_failed_agent_history, ) asyncio.create_task( @@ -443,6 +444,11 @@ async def _save_to_history( logger.debug("LLM 响应为空,不保存记录。") return + if save_failed_history and not llm_response.completion_text: + logger.info( + "Saving failed agent history as save_failed_agent_history is enabled." + ) + message_to_save = [] skipped_initial_system = False for message in all_messages: From 0c854a58f7b0f0ae0bf5756da629d37b3d6c8b77 Mon Sep 17 00:00:00 2001 From: Test User Date: Sun, 19 Apr 2026 13:20:42 +0800 Subject: [PATCH 3/3] fix: add failure marker message when saving failed history --- .../process_stage/method/agent_sub_stages/internal.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py index a62ad91675..cbc011105f 100644 --- a/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py +++ b/astrbot/core/pipeline/process_stage/method/agent_sub_stages/internal.py @@ -448,6 +448,12 @@ async def _save_to_history( logger.info( "Saving failed agent history as save_failed_agent_history is enabled." ) + all_messages.append( + Message( + role="assistant", + content="[Agent run failed. History saved for debugging.]", + ) + ) message_to_save = [] skipped_initial_system = False