mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(photon): ignore iMessage media placeholders
Cherry-picked from PR #54514; dropped frozen AUTHOR_MAP hunk in scripts/release.py, contributor mapping added instead.
This commit is contained in:
parent
be05741349
commit
fd4f756492
3 changed files with 32 additions and 0 deletions
1
contributors/emails/kelsia014@gmail.com
Normal file
1
contributors/emails/kelsia014@gmail.com
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
kelsia14
|
||||||
|
|
@ -726,6 +726,19 @@ class PhotonAdapter(BasePlatformAdapter):
|
||||||
)
|
)
|
||||||
|
|
||||||
ctype = content.get("type")
|
ctype = content.get("type")
|
||||||
|
if ctype == "text":
|
||||||
|
raw_text = content.get("text") or ""
|
||||||
|
# iMessage emits U+FFFC OBJECT REPLACEMENT CHARACTER as a transient
|
||||||
|
# placeholder for some media bubbles (notably voice notes). Photon
|
||||||
|
# can then deliver the real attachment/voice event immediately
|
||||||
|
# afterwards with a different message id. If we dispatch the
|
||||||
|
# placeholder as a standalone text turn, the subsequent media event
|
||||||
|
# arrives while that turn is active and the gateway sends a bogus
|
||||||
|
# "Interrupting current task" busy ack. Drop placeholder-only text
|
||||||
|
# at the platform boundary; the real media event carries the bytes.
|
||||||
|
if raw_text.strip() == "\ufffc":
|
||||||
|
logger.debug("[photon] ignoring iMessage object-placeholder text event")
|
||||||
|
return
|
||||||
if ctype == "reaction":
|
if ctype == "reaction":
|
||||||
# Route only tapbacks on messages WE sent — those are implicitly
|
# Route only tapbacks on messages WE sent — those are implicitly
|
||||||
# addressed to the bot (feishu precedent: synthetic text event).
|
# addressed to the bot (feishu precedent: synthetic text event).
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,24 @@ async def test_dispatch_text_dm(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
assert src.user_id == "+15551234567"
|
assert src.user_id == "+15551234567"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_dispatch_ignores_imessage_object_placeholder_text(
|
||||||
|
monkeypatch: pytest.MonkeyPatch,
|
||||||
|
) -> None:
|
||||||
|
"""Voice notes may arrive as U+FFFC placeholder text followed by media.
|
||||||
|
|
||||||
|
Dispatching the placeholder starts a bogus text turn; the real voice event
|
||||||
|
then lands during that turn and triggers the gateway's busy interrupt ack.
|
||||||
|
Drop placeholder-only text so only the actual voice/attachment is processed.
|
||||||
|
"""
|
||||||
|
adapter = _make_adapter(monkeypatch)
|
||||||
|
captured = _capture(adapter, monkeypatch)
|
||||||
|
|
||||||
|
await adapter._dispatch_inbound(_dm_event("\ufffc", msg_id="placeholder"))
|
||||||
|
|
||||||
|
assert captured == []
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_dispatch_group_type(monkeypatch: pytest.MonkeyPatch) -> None:
|
async def test_dispatch_group_type(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||||
adapter = _make_adapter(monkeypatch)
|
adapter = _make_adapter(monkeypatch)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue