Skip to content

Commit ed178e5

Browse files
committed
refactor: honor prepared handoff image urls contract
1 parent 4319c51 commit ed178e5

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

astrbot/core/astr_agent_tool_exec.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,15 @@ async def _execute_handoff(
247247
tool_args = dict(tool_args)
248248
input_ = tool_args.get("input")
249249
if image_urls_prepared:
250-
image_urls = normalize_and_dedupe_strings(tool_args.get("image_urls"))
250+
prepared_image_urls = tool_args.get("image_urls")
251+
if isinstance(prepared_image_urls, list):
252+
image_urls = prepared_image_urls
253+
else:
254+
logger.debug(
255+
"Expected prepared handoff image_urls as list[str], got %s.",
256+
type(prepared_image_urls).__name__,
257+
)
258+
image_urls = []
251259
else:
252260
image_urls = await cls._collect_handoff_image_urls(
253261
run_context,

tests/unit/test_astr_agent_tool_exec.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
175228
async def test_collect_handoff_image_urls_keeps_extensionless_existing_event_file(
176229
monkeypatch: pytest.MonkeyPatch,

0 commit comments

Comments
 (0)