Архитектура Gateway

Последнее обновление: 2026-01-22

Обзор

  • Один долгоживущий Gateway владеет всеми поверхностями обмена сообщениями (WhatsApp через Baileys, Telegram через grammY, Slack, Discord, Signal, iMessage, WebChat).
  • Клиенты контрольной плоскости (приложение macOS, CLI, веб-интерфейс, автоматизации) подключаются к Gateway через WebSocket на настроенном хосте привязки (по умолчанию 127.0.0.1:18789).
  • Узлы (macOS/iOS/Android/headless) также подключаются через WebSocket, но объявляют role: node с явными возможностями/командами.
  • Один Gateway на хост; это единственное место, которое открывает сессию WhatsApp.
  • canvas host (по умолчанию 18793) обслуживает редактируемый агентом HTML и A2UI.

Компоненты и потоки

Gateway (демон)

  • Поддерживает соединения провайдеров.
  • Предоставляет типизированный WS API (запросы, ответы, события server-push).
  • Валидирует входящие фреймы по JSON Schema.
  • Генерирует события типа agent, chat, presence, health, heartbeat, cron.

Клиенты (приложение mac / CLI / веб-админ)

  • Одно WS-соединение на клиент.
  • Отправляют запросы (health, status, send, agent, system-presence).
  • Подписываются на события (tick, agent, presence, shutdown).

Узлы (macOS / iOS / Android / headless)

  • Подключаются к тому же WS-серверу с role: node.
  • Предоставляют идентификатор устройства в connect; сопряжение на основе устройства (роль node) и одобрение хранится в хранилище сопряжений устройств.
  • Предоставляют команды типа canvas.*, camera.*, screen.record, location.get.

Детали протокола:

WebChat

  • Статический UI, который использует WS API Gateway для истории чатов и отправок.
  • В удаленных настройках подключается через тот же SSH/Tailscale туннель, что и другие клиенты.

Жизненный цикл соединения (один клиент)

Клиент                    Gateway
  |                          |
  |---- req:connect -------->|
  |<------ res (ok) ---------|   (или res error + close)
  |   (payload=hello-ok содержит снапшот: presence + health)
  |                          |
  |<------ event:presence ---|
  |<------ event:tick -------|
  |                          |
  |------- req:agent ------->|
  |<------ res:agent --------|   (ack: \{runId,status:"accepted"\})
  |<------ event:agent ------|   (потоковая передача)
  |<------ res:agent --------|   (финал: \{runId,status,summary\})
  |                          |

Протокол связи (краткое описание)

  • Транспорт: WebSocket, текстовые фреймы с JSON-пейлоадами.
  • Первый фрейм должен быть connect.
  • После рукопожатия:
    • Запросы: {type:"req", id, method, params}{type:"res", id, ok, payload|error}
    • События: {type:"event", event, payload, seq?, stateVersion?}
  • Если установлен OPENCLAW_GATEWAY_TOKEN (или --token), connect.params.auth.token должен совпадать, иначе сокет закрывается.
  • Ключи идемпотентности требуются для методов с побочными эффектами (send, agent) для безопасного повтора; сервер хранит краткосрочный дедупликационный кеш.
  • Узлы должны включать role: "node" плюс возможности/команды/разрешения в connect.

Сопряжение + локальное доверие

  • Все WS-клиенты (операторы + узлы) включают идентификатор устройства в connect.
  • Новые ID устройств требуют одобрения сопряжения; Gateway выдает токен устройства для последующих подключений.
  • Локальные подключения (loopback или собственный tailnet-адрес хоста gateway) могут быть автоматически одобрены для поддержания плавного UX на том же хосте.
  • Не-локальные подключения должны подписать nonce connect.challenge и требуют явного одобрения.
  • Аутентификация Gateway (gateway.auth.*) все равно применяется ко всем соединениям, локальным или удаленным.

Детали: Протокол Gateway, Сопряжение, Безопасность.

Типизация протокола и кодогенерация

  • Схемы TypeBox определяют протокол.
  • JSON Schema генерируется из этих схем.
  • Swift-модели генерируются из JSON Schema.

Удаленный доступ

  • Предпочтительно: Tailscale или VPN.
  • Альтернатива: SSH-туннель
    ssh -N -L 18789:127.0.0.1:18789 user@host
    
  • То же рукопожатие + токен аутентификации применяются через туннель.
  • TLS + опциональное пиннинг можно включить для WS в удаленных настройках.

Снапшот операций

  • Запуск: openclaw gateway (на переднем плане, логи в stdout).
  • Проверка здоровья: health через WS (также включено в hello-ok).
  • Супервизор: launchd/systemd для автоперезапуска.

Инварианты

  • Ровно один Gateway контролирует одну Baileys-сессию на хост.
  • Рукопожатие обязательно; любой не-JSON или не-connect первый фрейм — это жесткое закрытие.
  • События не воспроизводятся; клиенты должны обновляться при пропусках.