mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-11 12:10:45 +08:00
统一图片附件在聊天与通道回送链路的可见性与可发送性。
支持 tool_result 的 image_ref 前端渲染,并在微信/WhatsApp 回送时将 attachment 引用自动展开为可发送媒体,补齐回归测试。 Made-with: Cursor
This commit is contained in:
parent
957c67954f
commit
2edd78ac3b
3 changed files with 218 additions and 4 deletions
|
|
@ -4,6 +4,9 @@ from dataclasses import dataclass
|
|||
|
||||
from oclaw.runtime.application.gateway.inbound_service import (
|
||||
_collect_reply_attachments_from_history,
|
||||
_collect_recent_tool_attachments,
|
||||
_maybe_add_media_path_for_wechat_reply,
|
||||
_maybe_expand_reply_attachments_for_channel,
|
||||
_parse_message_attachments,
|
||||
_should_suppress_channel_reply,
|
||||
)
|
||||
|
|
@ -51,3 +54,75 @@ def test_collect_reply_attachments_prefers_matching_assistant_text() -> None:
|
|||
assert len(out) == 1
|
||||
assert out[0].get("attachment_id") == "new"
|
||||
|
||||
|
||||
def test_collect_recent_tool_attachments_falls_back_to_tool_media() -> None:
|
||||
rows = [
|
||||
_Row(role="assistant", content="x", attachments=None),
|
||||
_Row(role="tool", content="{}", attachments='[{"type":"image_ref","attachment_id":"a1"}]'),
|
||||
]
|
||||
out = _collect_recent_tool_attachments(store=_FakeStore(rows), session_id="s1")
|
||||
assert len(out) == 1
|
||||
assert out[0].get("attachment_id") == "a1"
|
||||
|
||||
|
||||
def test_maybe_add_media_path_for_wechat_reply_sets_media_path(monkeypatch) -> None:
|
||||
# Avoid touching disk: stub AttachmentAssetStore.get_local_path.
|
||||
from pathlib import Path
|
||||
|
||||
def _fake_get_local_path(self, attachment_id: str): # noqa: ANN001
|
||||
assert attachment_id == "a1"
|
||||
return Path("D:/tmp/fake.png")
|
||||
|
||||
monkeypatch.setattr(
|
||||
"oclaw.platform.files.attachment_assets.AttachmentAssetStore.get_local_path",
|
||||
_fake_get_local_path,
|
||||
)
|
||||
r = {"channel": "wechat", "text": "hi", "attachments": [{"type": "image_ref", "attachment_id": "a1"}]}
|
||||
_maybe_add_media_path_for_wechat_reply(r)
|
||||
assert r.get("media_path") in {"D:/tmp/fake.png", "D:\\tmp\\fake.png"}
|
||||
|
||||
|
||||
def test_maybe_expand_reply_attachments_for_channel_converts_ref_to_base64(monkeypatch) -> None:
|
||||
import base64
|
||||
|
||||
class _Meta:
|
||||
mime = "image/png"
|
||||
name = "x.png"
|
||||
|
||||
def _fake_load_bytes(self, attachment_id: str): # noqa: ANN001
|
||||
assert attachment_id == "a1"
|
||||
return b"abc", _Meta()
|
||||
|
||||
monkeypatch.setattr(
|
||||
"oclaw.platform.files.attachment_assets.AttachmentAssetStore.load_bytes",
|
||||
_fake_load_bytes,
|
||||
)
|
||||
r = {"channel": "wechat", "attachments": [{"type": "image_ref", "attachment_id": "a1"}]}
|
||||
_maybe_expand_reply_attachments_for_channel(r)
|
||||
out = r.get("attachments")
|
||||
assert isinstance(out, list) and len(out) == 1
|
||||
assert out[0].get("data_base64") == base64.b64encode(b"abc").decode("ascii")
|
||||
assert out[0].get("mime") == "image/png"
|
||||
|
||||
|
||||
def test_maybe_expand_reply_attachments_for_channel_works_for_whatsapp(monkeypatch) -> None:
|
||||
import base64
|
||||
|
||||
class _Meta:
|
||||
mime = "image/png"
|
||||
name = "wa.png"
|
||||
|
||||
def _fake_load_bytes(self, attachment_id: str): # noqa: ANN001
|
||||
assert attachment_id == "wa1"
|
||||
return b"wa", _Meta()
|
||||
|
||||
monkeypatch.setattr(
|
||||
"oclaw.platform.files.attachment_assets.AttachmentAssetStore.load_bytes",
|
||||
_fake_load_bytes,
|
||||
)
|
||||
r = {"channel": "whatsapp", "attachments": [{"type": "image_ref", "attachment_id": "wa1"}]}
|
||||
_maybe_expand_reply_attachments_for_channel(r)
|
||||
out = r.get("attachments")
|
||||
assert isinstance(out, list) and len(out) == 1
|
||||
assert out[0].get("data_base64") == base64.b64encode(b"wa").decode("ascii")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue