diff --git a/plugins/platforms/simplex/adapter.py b/plugins/platforms/simplex/adapter.py index 4046ce4910ad9..2f9dd4e493229 100644 --- a/plugins/platforms/simplex/adapter.py +++ b/plugins/platforms/simplex/adapter.py @@ -1269,8 +1269,10 @@ async def _standalone_send( ) cmd_str = f"/_send #{group_id} json {composed}" else: - # Direct contacts are addressed by display name without brackets. - cmd_str = f"@{chat_id} {message}" + composed = json.dumps( + [{"msgContent": {"type": "text", "text": message}}] + ) + cmd_str = f"/_send @{chat_id} json {composed}" payload = { "corrId": f"{_CORR_PREFIX}snd-{int(time.time() * 1000)}", diff --git a/tests/gateway/test_simplex_plugin.py b/tests/gateway/test_simplex_plugin.py index 87808f81f1bd1..1a88d56513017 100644 --- a/tests/gateway/test_simplex_plugin.py +++ b/tests/gateway/test_simplex_plugin.py @@ -298,6 +298,64 @@ async def test_standalone_send_missing_websockets(monkeypatch): sys.modules["websockets"] = saved_websockets +@pytest.mark.asyncio +async def test_standalone_send_defaults_to_local_daemon(monkeypatch): + monkeypatch.delenv("SIMPLEX_WS_URL", raising=False) + pconfig = MagicMock() + pconfig.extra = {} + + sent_payloads = [] + + class DummyWs: + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc, tb): + return None + + async def send(self, payload): + sent_payloads.append(json.loads(payload)) + + def fake_connect(url, **kwargs): + assert url == "ws://127.0.0.1:5225" + assert kwargs["open_timeout"] == 10 + assert kwargs["close_timeout"] == 5 + return DummyWs() + + import websockets + monkeypatch.setattr(websockets, "connect", fake_connect) + + result = await _standalone_send(pconfig, "contact-42", "hi") + assert result == {"success": True, "platform": "simplex", "chat_id": "contact-42"} + assert sent_payloads[0]["cmd"].startswith("/_send @contact-42 json ") + msg_content = json.loads( + sent_payloads[0]["cmd"].split(" json ", 1)[1] + )[0]["msgContent"] + assert msg_content == {"type": "text", "text": "hi"} + + +@pytest.mark.asyncio +async def test_health_monitor_does_not_reconnect_quiet_healthy_ws(monkeypatch): + from gateway.config import PlatformConfig + cfg = PlatformConfig(enabled=True, extra={"ws_url": "ws://localhost:5225"}) + adapter = SimplexAdapter(cfg) + adapter._running = True + adapter._last_ws_activity = 0 + adapter._ws = AsyncMock() + + monkeypatch.setattr(_simplex, "HEALTH_CHECK_INTERVAL", 0.01) + monkeypatch.setattr(_simplex, "HEALTH_CHECK_STALE_THRESHOLD", 0.01) + + task = asyncio.create_task(adapter._health_monitor()) + await asyncio.sleep(0.03) + adapter._running = False + await asyncio.wait_for(task, timeout=1) + + adapter._ws.close.assert_not_called() + + + + # --------------------------------------------------------------------------- # 10. register() — plugin-side metadata # ---------------------------------------------------------------------------