feat(simplex): groups, native attachments, text batching, auto-accept
Salvage of PR #27978 cherry-picked onto current main, resolving conflicts with main's intervening SimpleX plugin fixes (resp-envelope normalization, health-monitor reconnect-churn fix, bare-form DM addressing). What's new: - Group support via SIMPLEX_GROUP_ALLOWED (comma-separated IDs or '*'); inbound items surface chat_id=group:<id> + chat_type=group. Disabled by default so a bot in a group doesn't process every member's traffic. - Inbound files/voice via rcvFileDescrReady (immediate /freceive) deferred through _pending_file_transfers, replayed on rcvFileComplete. Voice notes -> MessageType.VOICE. - Native outbound media: send_image (PNG/JPEG + inline thumbnail), send_voice (msgContent.type=voice), send_video, send_document. All addressed by numeric ID via /_send ... json [...]. - MEDIA:<path> tags in agent replies stripped and dispatched as voice/document. - Text-burst batching (HERMES_SIMPLEX_TEXT_BATCH_DELAY, default 0.8s). - Auto-accept contact requests (SIMPLEX_AUTO_ACCEPT, default true). - Group send path uses structured /_send #<id> json form (the bracket #[<id>] form is parsed as display-name lookup and silently drops). plugin.yaml bumped to 1.1.0; docs updated. All inside plugins/platforms/simplex/ - no core edits. Co-authored-by: Juraj Bednar <juraj@bednar.io>
This commit is contained in:
@@ -205,6 +205,13 @@ def test_corr_id_pending_set_self_trims():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_dm():
|
||||
"""DMs use the bare ``@<id> text`` chat-command form.
|
||||
|
||||
The bracketed form ``@[<id>] text`` is what the daemon's man page
|
||||
documents, but in practice both addressing styles route through
|
||||
the same chat-command parser; bare ``@<id>`` matches what every
|
||||
Hermes deployment has been using in production for months.
|
||||
"""
|
||||
from gateway.config import PlatformConfig
|
||||
cfg = PlatformConfig(enabled=True, extra={"ws_url": "ws://localhost:5225"})
|
||||
adapter = SimplexAdapter(cfg)
|
||||
@@ -222,6 +229,14 @@ async def test_send_dm():
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_send_group():
|
||||
"""Groups use the structured ``/_send #<id> json [...]`` form.
|
||||
|
||||
The bracket chat-command form ``#[<id>] text`` *looks* like an exact
|
||||
ID match in the daemon docs but is parsed as a display-name lookup
|
||||
— so messages to groups whose display name isn't literally the ID
|
||||
silently drop. The structured ``/_send`` form addresses by numeric
|
||||
ID and survives newlines/quoting through ``json.dumps``.
|
||||
"""
|
||||
from gateway.config import PlatformConfig
|
||||
cfg = PlatformConfig(enabled=True, extra={"ws_url": "ws://localhost:5225"})
|
||||
adapter = SimplexAdapter(cfg)
|
||||
@@ -231,7 +246,11 @@ async def test_send_group():
|
||||
|
||||
result = await adapter.send("group:grp-99", "Hello, group!")
|
||||
payload = json.loads(mock_ws.send.call_args[0][0])
|
||||
assert payload["cmd"] == "#[grp-99] Hello, group!"
|
||||
assert payload["cmd"].startswith("/_send #grp-99 json ")
|
||||
msg_content = json.loads(payload["cmd"].split(" json ", 1)[1])[0][
|
||||
"msgContent"
|
||||
]
|
||||
assert msg_content == {"type": "text", "text": "Hello, group!"}
|
||||
assert result.success is True
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user