mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat(gateway): add Feishu websocket ping timing overrides
Allow Feishu websocket keepalive timing to be configured via platform extra config so disconnects can be detected faster in unstable networks. New optional extra settings: - ws_ping_interval - ws_ping_timeout These values are applied only when explicitly configured. Invalid values fall back to the websocket library defaults by leaving the options unset. This complements the reconnect timing settings added previously and helps reduce total recovery time after network interruptions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7d0bf15121
commit
ea31d9077c
2 changed files with 52 additions and 0 deletions
|
|
@ -272,6 +272,8 @@ class FeishuAdapterSettings:
|
|||
webhook_path: str
|
||||
ws_reconnect_nonce: int = 30
|
||||
ws_reconnect_interval: int = 120
|
||||
ws_ping_interval: Optional[int] = None
|
||||
ws_ping_timeout: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -376,6 +378,14 @@ def _coerce_positive_int(value: Any, default: int) -> int:
|
|||
return parsed if parsed >= 1 else default
|
||||
|
||||
|
||||
def _coerce_optional_positive_int(value: Any) -> Optional[int]:
|
||||
try:
|
||||
parsed = int(value)
|
||||
except (TypeError, ValueError):
|
||||
return None
|
||||
return parsed if parsed >= 1 else None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Post payload builders and parsers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
@ -939,11 +949,23 @@ def _run_official_feishu_ws_client(ws_client: Any, adapter: Any) -> None:
|
|||
asyncio.set_event_loop(loop)
|
||||
ws_client_module.loop = loop
|
||||
adapter._ws_thread_loop = loop
|
||||
|
||||
original_connect = ws_client_module.websockets.connect
|
||||
|
||||
async def _connect_with_overrides(*args: Any, **kwargs: Any) -> Any:
|
||||
if adapter._ws_ping_interval is not None and "ping_interval" not in kwargs:
|
||||
kwargs["ping_interval"] = adapter._ws_ping_interval
|
||||
if adapter._ws_ping_timeout is not None and "ping_timeout" not in kwargs:
|
||||
kwargs["ping_timeout"] = adapter._ws_ping_timeout
|
||||
return await original_connect(*args, **kwargs)
|
||||
|
||||
ws_client_module.websockets.connect = _connect_with_overrides
|
||||
try:
|
||||
ws_client.start()
|
||||
except Exception:
|
||||
pass
|
||||
finally:
|
||||
ws_client_module.websockets.connect = original_connect
|
||||
pending = [t for t in asyncio.all_tasks(loop) if not t.done()]
|
||||
for task in pending:
|
||||
task.cancel()
|
||||
|
|
@ -1060,6 +1082,8 @@ class FeishuAdapter(BasePlatformAdapter):
|
|||
),
|
||||
ws_reconnect_nonce=_coerce_non_negative_int(extra.get("ws_reconnect_nonce"), 30),
|
||||
ws_reconnect_interval=_coerce_positive_int(extra.get("ws_reconnect_interval"), 120),
|
||||
ws_ping_interval=_coerce_optional_positive_int(extra.get("ws_ping_interval")),
|
||||
ws_ping_timeout=_coerce_optional_positive_int(extra.get("ws_ping_timeout")),
|
||||
)
|
||||
|
||||
def _apply_settings(self, settings: FeishuAdapterSettings) -> None:
|
||||
|
|
@ -1084,6 +1108,8 @@ class FeishuAdapter(BasePlatformAdapter):
|
|||
self._webhook_path = settings.webhook_path
|
||||
self._ws_reconnect_nonce = settings.ws_reconnect_nonce
|
||||
self._ws_reconnect_interval = settings.ws_reconnect_interval
|
||||
self._ws_ping_interval = settings.ws_ping_interval
|
||||
self._ws_ping_timeout = settings.ws_ping_timeout
|
||||
|
||||
def _build_event_handler(self) -> Any:
|
||||
if EventDispatcherHandler is None:
|
||||
|
|
|
|||
|
|
@ -587,6 +587,32 @@ class TestAdapterModule(unittest.TestCase):
|
|||
self.assertEqual(settings.ws_reconnect_nonce, 0)
|
||||
self.assertEqual(settings.ws_reconnect_interval, 3)
|
||||
|
||||
def test_load_settings_accepts_custom_ws_ping_values(self):
|
||||
from gateway.platforms.feishu import FeishuAdapter
|
||||
|
||||
settings = FeishuAdapter._load_settings(
|
||||
{
|
||||
"ws_ping_interval": 10,
|
||||
"ws_ping_timeout": 8,
|
||||
}
|
||||
)
|
||||
|
||||
self.assertEqual(settings.ws_ping_interval, 10)
|
||||
self.assertEqual(settings.ws_ping_timeout, 8)
|
||||
|
||||
def test_load_settings_ignores_invalid_ws_ping_values(self):
|
||||
from gateway.platforms.feishu import FeishuAdapter
|
||||
|
||||
settings = FeishuAdapter._load_settings(
|
||||
{
|
||||
"ws_ping_interval": 0,
|
||||
"ws_ping_timeout": -1,
|
||||
}
|
||||
)
|
||||
|
||||
self.assertIsNone(settings.ws_ping_interval)
|
||||
self.assertIsNone(settings.ws_ping_timeout)
|
||||
|
||||
|
||||
class TestAdapterBehavior(unittest.TestCase):
|
||||
@patch.dict(os.environ, {}, clear=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue