Files
iris_x_hermes/gateway-plugin/ws_server.py
T
ARIA 59acf66c89 M0: toolchain, monorepo scaffold, gateway plugin skeleton, CMP app
- gateway-plugin/: android platform plugin (plugin.yaml + adapter.py
  register(ctx) + no-op AndroidAdapter) + stub modules for M1-M5
- app/: Compose Multiplatform project (shared KMP + androidApp +
  desktopApp) with Gradle wrapper; builds :androidApp:assembleDebug
  and :desktopApp:compileKotlin
- scripts/guard_hermes_agent.sh + pre-commit hook: fail if hermes-agent/
  is staged (read-only reference, never committed)
- .gitignore excludes hermes-agent/; docs/ reference library
2026-08-19 11:27:02 +02:00

24 lines
1.1 KiB
Python

"""WebSocket server, connection registry, and frame routing.
Runs on the gateway's asyncio loop (started in ``AndroidAdapter.connect()``).
Uses the ``websockets`` core dep (v15): ``websockets.serve(handler, host,
port, ssl=ctx)``.
Per-connection handler:
1. Await first frame; must be ``hello {token, device_id, device_name,
caps, fcm_token?}``. Verify token (constant-time) + allowlist. On
failure: send ``error {code:"auth"}`` and close.
2. On success: register in the connection registry (``device_id ->
{ws, caps, fcm_token}``), send ``hello.ack {server_caps, sync_cursor,
channels[]}``.
3. Loop: decode frames, dispatch to adapter inbound handlers.
4. On close: deregister; if no devices remain, ensure pending outbox
frames have push fired.
Routing: ``emit(chat_id, frame)`` broadcasts to ALL connected devices
(single-user model). Heartbeat via WS ping/pong + app-level ping/pong.
Backpressure: bounded per-connection send queue; coalesce ``message.update``
under pressure, never drop ``message``/``tool.end``/``notification``.
Milestone M1.
"""