@@ -596,8 +596,128 @@ async def fake_persist_agent_history(*args, **kwargs):
596596
597597 config = captured ["config" ]
598598 assert config .tool_call_timeout == 77
599- assert config .provider_settings is provider_settings
599+ assert config .provider_settings is not provider_settings
600600 assert config .provider_settings ["fallback_chat_models" ] == ["fallback-provider" ]
601+ assert config .provider_settings ["request_max_retries" ] == 1
602+ assert "request_max_retries" not in provider_settings
603+
604+ @pytest .mark .asyncio
605+ async def test_woke_main_agent_allows_proactive_retry_override (
606+ self , cron_manager
607+ ):
608+ """Test active cron agent can override request retries for proactive runs."""
609+ provider_settings = {
610+ "tool_call_timeout" : 77 ,
611+ "request_max_retries" : 5 ,
612+ "proactive_capability" : {"request_max_retries" : 2 },
613+ }
614+ ctx = MagicMock ()
615+ ctx .get_config .return_value = {
616+ "admins_id" : [],
617+ "provider_settings" : provider_settings ,
618+ }
619+ cron_manager .ctx = ctx
620+
621+ conv = MagicMock ()
622+ conv .history = "[]"
623+
624+ class FakeRunner :
625+ def step_until_done (self , max_step ):
626+ async def gen ():
627+ if False :
628+ yield None
629+
630+ return gen ()
631+
632+ def get_final_llm_resp (self ):
633+ return None
634+
635+ captured = {}
636+
637+ async def fake_build_main_agent (* , event , plugin_context , config , req ):
638+ captured ["config" ] = config
639+ return MagicMock (agent_runner = FakeRunner ())
640+
641+ with (
642+ patch (
643+ "astrbot.core.astr_main_agent._get_session_conv" ,
644+ AsyncMock (return_value = conv ),
645+ ),
646+ patch (
647+ "astrbot.core.astr_main_agent.build_main_agent" ,
648+ side_effect = fake_build_main_agent ,
649+ ),
650+ patch (
651+ "astrbot.core.cron.manager.persist_agent_history" ,
652+ AsyncMock (return_value = None ),
653+ ),
654+ ):
655+ await cron_manager ._woke_main_agent (
656+ message = "run scheduled task" ,
657+ session_str = "test:FriendMessage:user123" ,
658+ extras = {"cron_job" : {"id" : "job-1" }, "cron_payload" : {}},
659+ )
660+
661+ assert captured ["config" ].provider_settings ["request_max_retries" ] == 2
662+ assert provider_settings ["request_max_retries" ] == 5
663+
664+ @pytest .mark .asyncio
665+ async def test_woke_main_agent_uses_default_when_proactive_retry_is_none (
666+ self , cron_manager
667+ ):
668+ """Test None proactive retry config falls back to the cron default."""
669+ provider_settings = {
670+ "request_max_retries" : 5 ,
671+ "proactive_capability" : {"request_max_retries" : None },
672+ }
673+ ctx = MagicMock ()
674+ ctx .get_config .return_value = {
675+ "admins_id" : [],
676+ "provider_settings" : provider_settings ,
677+ }
678+ cron_manager .ctx = ctx
679+
680+ conv = MagicMock ()
681+ conv .history = "[]"
682+
683+ class FakeRunner :
684+ def step_until_done (self , max_step ):
685+ async def gen ():
686+ if False :
687+ yield None
688+
689+ return gen ()
690+
691+ def get_final_llm_resp (self ):
692+ return None
693+
694+ captured = {}
695+
696+ async def fake_build_main_agent (* , event , plugin_context , config , req ):
697+ captured ["config" ] = config
698+ return MagicMock (agent_runner = FakeRunner ())
699+
700+ with (
701+ patch (
702+ "astrbot.core.astr_main_agent._get_session_conv" ,
703+ AsyncMock (return_value = conv ),
704+ ),
705+ patch (
706+ "astrbot.core.astr_main_agent.build_main_agent" ,
707+ side_effect = fake_build_main_agent ,
708+ ),
709+ patch (
710+ "astrbot.core.cron.manager.persist_agent_history" ,
711+ AsyncMock (return_value = None ),
712+ ),
713+ ):
714+ await cron_manager ._woke_main_agent (
715+ message = "run scheduled task" ,
716+ session_str = "test:FriendMessage:user123" ,
717+ extras = {"cron_job" : {"id" : "job-1" }, "cron_payload" : {}},
718+ )
719+
720+ assert captured ["config" ].provider_settings ["request_max_retries" ] == 1
601721
602722
603723class TestGetNextRunTime :
0 commit comments