mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 01:50:44 +08:00
fix(attachments): parse channel uploads for LLM and stop echoing user files
WhatsApp/channel binary_ref uploads now expand into text_ref/tabular summaries for the model, and outbound replies only auto-attach generated image/video media instead of lookup tool text_ref results. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
fc10560052
commit
61d54b10fd
5 changed files with 215 additions and 10 deletions
98
tests/test_binary_ref_attachments.py
Normal file
98
tests/test_binary_ref_attachments.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from runtime.application.gateway.inbound_service import _channel_attachments_for_gateway
|
||||
from runtime.chat.agent_messages import build_llm_messages
|
||||
from svc.files.attachment_assets import AttachmentAssetStore
|
||||
from svc.files.file_attachments import expand_attachment_ref
|
||||
from svc.llm.chat_models import RuleBasedChatModel
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def att_store(tmp_path, monkeypatch):
|
||||
store = AttachmentAssetStore(root_dir=tmp_path / "att")
|
||||
|
||||
def _factory(root_dir=None):
|
||||
if root_dir is None:
|
||||
return store
|
||||
return AttachmentAssetStore(root_dir=root_dir)
|
||||
|
||||
monkeypatch.setattr("svc.files.file_attachments.AttachmentAssetStore", _factory)
|
||||
monkeypatch.setattr("runtime.chat.agent_messages.AttachmentAssetStore", _factory)
|
||||
return store
|
||||
|
||||
|
||||
def _msg_text(message: dict) -> str:
|
||||
content = message.get("content")
|
||||
if isinstance(content, list):
|
||||
return "\n".join(str(x.get("text") or "") for x in content if isinstance(x, dict))
|
||||
return str(content or "")
|
||||
|
||||
|
||||
def test_expand_attachment_ref_large_txt_becomes_text_ref(att_store) -> None:
|
||||
text = ("line\n" * 5000).strip()
|
||||
data = text.encode("utf-8")
|
||||
meta = att_store.save_bytes(data, filename="sites.txt", mime="text/plain")
|
||||
got = expand_attachment_ref({"type": "binary_ref", "attachment_id": meta.attachment_id})
|
||||
types = {str(x.get("type") or "") for x in got}
|
||||
assert "text_ref" in types
|
||||
assert "text" in types
|
||||
|
||||
|
||||
def test_channel_attachments_for_gateway_parses_local_txt(tmp_path) -> None:
|
||||
p = tmp_path / "Site_List.txt"
|
||||
p.write_text("a\nb\nc\n", encoding="utf-8")
|
||||
got = _channel_attachments_for_gateway([{"local_path": str(p), "kind": "document", "mime": "text/plain"}])
|
||||
assert got
|
||||
assert any(str(x.get("type") or "") == "text" for x in got)
|
||||
|
||||
|
||||
def test_build_llm_messages_binary_ref_meta_for_historical_turn(att_store) -> None:
|
||||
data = b"hello attachment"
|
||||
meta = att_store.save_bytes(data, filename="note.txt", mime="text/plain")
|
||||
rows = [
|
||||
SimpleNamespace(
|
||||
role="user",
|
||||
event_type="user_text",
|
||||
content="first",
|
||||
attachments=[{"type": "binary_ref", "attachment_id": meta.attachment_id}],
|
||||
tool_calls=None,
|
||||
turn_uuid="t1",
|
||||
),
|
||||
SimpleNamespace(
|
||||
role="user",
|
||||
event_type="user_text",
|
||||
content="second",
|
||||
attachments=None,
|
||||
tool_calls=None,
|
||||
turn_uuid="t2",
|
||||
),
|
||||
]
|
||||
msgs = build_llm_messages(store_messages=rows, system_prompt="s", model=RuleBasedChatModel(), lang="zh")
|
||||
first_user = next(m for m in msgs if m.get("role") == "user" and "first" in _msg_text(m))
|
||||
content = _msg_text(first_user)
|
||||
assert "BinaryAttachment" in content
|
||||
assert meta.attachment_id in content
|
||||
|
||||
|
||||
def test_build_llm_messages_binary_ref_expands_on_last_turn(att_store) -> None:
|
||||
text = ("row\n" * 4000).strip()
|
||||
data = text.encode("utf-8")
|
||||
meta = att_store.save_bytes(data, filename="Site_List.txt", mime="text/plain")
|
||||
rows = [
|
||||
SimpleNamespace(
|
||||
role="user",
|
||||
event_type="user_text",
|
||||
content="帮看一下有多少数据",
|
||||
attachments=[{"type": "binary_ref", "attachment_id": meta.attachment_id}],
|
||||
tool_calls=None,
|
||||
turn_uuid="t1",
|
||||
),
|
||||
]
|
||||
msgs = build_llm_messages(store_messages=rows, system_prompt="s", model=RuleBasedChatModel(), lang="zh")
|
||||
user = msgs[-1]
|
||||
content = _msg_text(user)
|
||||
assert "LongTextAttachment" in content or "text_id" in content
|
||||
Loading…
Add table
Add a link
Reference in a new issue