Files
AstrBot/tests/test_agent_runner_media_resolver.py
Weilong Liao 7c366a708b fix: unify media reference handling (#8764)
* fix: unify media reference handling

* fix: accept bare base64 record media refs

* chore: update agents.md

* fix: unify file URI handling across media components and utilities

* fix: unify media reference type handling with MediaRefStr alias

* Potential fix for pull request finding 'CodeQL / Incomplete URL substring sanitization'

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* Update astrbot/core/platform/sources/discord/discord_platform_adapter.py

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* fix: unify media handling and improve base64 decoding across components

* fix: simplify client_kwargs type definition and enhance media message handling in platform adapter

* fix: unify media utility documentation and enhance function descriptions

* perf: drop "pilk" requirement, improve audio outbound for tencent-related IM apps which using silk

* fix: unify Tencent Silk audio handling and enhance media resolver functionality

---

- Centralize media reference materialization and base64 resolution for local paths, http(s), base64://, data URIs, and legacy bare base64 payloads.
- Normalize incoming Record audio to wav and Image media to temporary jpg during preprocess, with event-scoped cleanup.
- Reuse the shared media resolver across OpenAI, Gemini, Anthropic, MiMo, DeerFlow, STT, and platform media paths while sanitizing logs and cleaning temporary conversion outputs.
- Ensure generated TTS audio is tracked for cleanup after the event finishes.

fix #8676
fix #8543
fix #7588
fix #7580
fix #8030
fix #8034
fix #7461
fix #7565
fix #6509
fix #7144
fix #7795



---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-06-14 10:37:16 +08:00

65 lines
2.0 KiB
Python

import base64
from io import BytesIO
import pytest
from PIL import Image as PILImage
from astrbot.core.agent.runners.coze.coze_agent_runner import CozeAgentRunner
from astrbot.core.agent.runners.dify.dify_agent_runner import DifyAgentRunner
def _png_data_url() -> tuple[str, bytes]:
image_buffer = BytesIO()
PILImage.new("RGBA", (1, 1), (255, 0, 0, 255)).save(image_buffer, format="PNG")
image_bytes = image_buffer.getvalue()
return (
f"data:image/png;base64,{base64.b64encode(image_bytes).decode()}",
image_bytes,
)
@pytest.mark.asyncio
async def test_dify_image_upload_uses_media_resolver_for_data_url():
image_ref, image_bytes = _png_data_url()
captured: dict[str, object] = {}
class _FakeDifyClient:
async def file_upload(self, **kwargs):
captured.update(kwargs)
return {"id": "file-1"}
runner = DifyAgentRunner.__new__(DifyAgentRunner)
runner.api_client = _FakeDifyClient()
payload = await runner._upload_image_for_dify(image_ref, "session-1")
assert payload == {
"type": "image",
"transfer_method": "local_file",
"upload_file_id": "file-1",
}
assert captured["file_data"] == image_bytes
assert captured["mime_type"] == "image/png"
assert captured["file_name"] == "image.png"
@pytest.mark.asyncio
async def test_coze_image_upload_uses_media_resolver_for_data_url():
image_ref, image_bytes = _png_data_url()
captured: dict[str, bytes] = {}
class _FakeCozeClient:
async def upload_file(self, file_data: bytes) -> str:
captured["file_data"] = file_data
return "file-1"
runner = CozeAgentRunner.__new__(CozeAgentRunner)
runner.api_client = _FakeCozeClient()
runner.file_id_cache = {}
file_id = await runner._download_and_upload_image(image_ref, "session-1")
assert file_id == "file-1"
assert captured["file_data"] == image_bytes
assert list(runner.file_id_cache["session-1"].values()) == ["file-1"]