@@ -171,6 +171,59 @@ async def _fake_wake(cls, run_context, **kwargs):
171171 assert captured ["tool_args" ]["image_urls" ] == ["https://example.com/raw.png" ]
172172
173173
174+ @pytest .mark .asyncio
175+ async def test_execute_handoff_skips_renormalize_when_image_urls_prepared (
176+ monkeypatch : pytest .MonkeyPatch ,
177+ ):
178+ captured : dict = {}
179+
180+ def _boom (_items ):
181+ raise RuntimeError ("normalize should not be called" )
182+
183+ async def _fake_get_current_chat_provider_id (_umo ):
184+ return "provider-id"
185+
186+ async def _fake_tool_loop_agent (** kwargs ):
187+ captured .update (kwargs )
188+ return SimpleNamespace (completion_text = "ok" )
189+
190+ context = SimpleNamespace (
191+ get_current_chat_provider_id = _fake_get_current_chat_provider_id ,
192+ tool_loop_agent = _fake_tool_loop_agent ,
193+ get_config = lambda ** _kwargs : {"provider_settings" : {}},
194+ )
195+ event = _DummyEvent ([])
196+ run_context = ContextWrapper (context = SimpleNamespace (event = event , context = context ))
197+ tool = SimpleNamespace (
198+ name = "transfer_to_subagent" ,
199+ provider_id = None ,
200+ agent = SimpleNamespace (
201+ name = "subagent" ,
202+ tools = [],
203+ instructions = "subagent-instructions" ,
204+ begin_dialogs = [],
205+ run_hooks = None ,
206+ ),
207+ )
208+
209+ monkeypatch .setattr (
210+ "astrbot.core.astr_agent_tool_exec.normalize_and_dedupe_strings" , _boom
211+ )
212+
213+ results = []
214+ async for result in FunctionToolExecutor ._execute_handoff (
215+ tool ,
216+ run_context ,
217+ image_urls_prepared = True ,
218+ input = "hello" ,
219+ image_urls = ["https://example.com/raw.png" ],
220+ ):
221+ results .append (result )
222+
223+ assert len (results ) == 1
224+ assert captured ["image_urls" ] == ["https://example.com/raw.png" ]
225+
226+
174227@pytest .mark .asyncio
175228async def test_collect_handoff_image_urls_keeps_extensionless_existing_event_file (
176229 monkeypatch : pytest .MonkeyPatch ,
0 commit comments