Перейти к содержанию

Как всё устроено

Адаптер — это платформа Hermes, а не отдельный сервер

hermes-mobile — плагин-адаптер, обычная платформа Hermes (такая же, как Telegram). Он поднимает WebSocket-сервер внутри процесса шлюза (hermes gateway) и превращает кадры протокола в MessageEvent, которые уходят в агента тем же путём, что и остальные каналы.

        ваше приложение                машина агента (hermes gateway)
   ┌────────────────────┐        ┌────────────────────────────────────────────┐
   │ HermesClient / SDK │        │  плагин hermes-mobile  (WS-сервер :8787/ws) │
   │  text/audio/media  │ ─────► │        │                                    │
   │  prompt (кнопки)   │        │        ▼  MessageEvent                     │
   └────────────────────┘        │   ┌─────────────────────────────┐          │
            ▲                    │   │  Hermes Agent               │          │
            │  message/media     │   │  сессии · память · tools    │          │
            │  avatar/typing     │   │  cron · биллинг · история   │          │
            └────────────────────│   └─────────────────────────────┘          │
                                 └────────────────────────────────────────────┘

Ключевой вывод: у приложения нет своего бэкенда. Нет отдельного API-слоя, второй истории, второго набора инструментов и второго биллинга. Всё, что умеет агент в Telegram/CLI, он умеет и здесь — потому что это один и тот же агент.

Сессии и идентификатор устройства

Идентификатор сессии в Hermes — mobile:<device.id>. device.id выбирает приложение и держит постоянным (например pilot-phone). От него зависят:

  • идентификатор сессии и вся история диалога (история живёт на стороне Hermes, не в приложении);
  • адрес доставки для cron и hermes send (mobile:<device.id>);
  • записи в белых списках.

Один пользователь может иметь несколько устройств — это разные сессии. Одно устройство, переподключившись, возвращается в свою же сессию: при обрыве сети достаточно снова отправить hello, и диалог продолжится.

Если device.id не задан, адаптер сгенерирует его сам (dev-<hex>), но тогда адрес для доставки меняется от подключения к подключению — задавайте device.id всегда.

Токены и белые списки — это разные вещи

Здесь легко запутаться: владельцы/пользователи и устройства — разные сущности и разные переменные.

Переменная Что перечисляет Кто проверяет Что будет, если не совпало
MOBILE_TOKEN общий токен приложения (секрет) адаптер, при рукопожатии соединение закрывается кодом 1008, кадр error → auth_failed
MOBILE_EXTRA_TOKENS дополнительные токены (на разные приложения/устройства); элемент device_id=token привязывает токен к устройству адаптер, при рукопожатии при занятом чужом device.id → кадр error → forbidden + 1008
MOBILE_DELIVER_TOKENS токены, которым разрешён служебный кадр deliver вне loopback адаптер, при кадре deliver error → forbidden
MOBILE_ALLOWED_DEVICES список device.id — устройства адаптер (дополнительный фильтр адаптера) отказ auth_failed + 1008
MOBILE_ALLOWED_USERS список пользователей — штатная авторизация и pairing Hermes сам Hermes соединение принимается (ready), но агент не отвечает — нужен pairing/одобрение
MOBILE_ALLOW_ALL_USERS 1/true — принимать любое устройство с валидным токеном сам Hermes — (снимает проверку пользователя)
MOBILE_HOME_DEVICE устройство по умолчанию для cron адаптер device_offline, если оно не в сети

Правила:

  • Пустой MOBILE_ALLOWED_DEVICES → разрешено любое устройство с валидным токеном.
  • Пустой MOBILE_TOKEN → платформа не поднимается вообще (config_missing): адаптер не бывает «открытым».
  • MOBILE_ALLOWED_USERS — это про пользователей (кто допущен к агенту), а фильтр устройств — это MOBILE_ALLOWED_DEVICES. Не путайте: одно имя не должно значить две разные вещи.

Что происходит с памятью, инструментами и cron

  • Память и история — на стороне Hermes, в профиле агента. Переустановка приложения их не теряет; несколько устройств видят свои сессии независимо.
  • Инструменты — те же, что в других каналах. Опасные команды проходят через штатное одобрение: адаптер присылает приложению карточку prompt с кнопками, а ответ резолвится родным механизмом Hermes (не как сообщение в чате).
  • Cron и hermes send — умеют доставлять сообщения и файлы на устройство. Когда шлюз работает, отдельный процесс (standalone_sender_fn) подключается к нему как служебный клиент и просит отдать кадр устройству. Мобильная доставка требует живого подключения приложения: если устройство не в сети — вернётся device_offline, а не «тихий» успех.
  • Стриминг — если включён на стороне агента, ответ сначала приходит целиком, а затем правится по id (кадры message с edit: true).

Направления движения данных

  • вверх (приложение → агент): hello, text, audio, media, prompt, typing, ping, ack, deliver.
  • вниз (агент → приложение): ready, message, media, prompt, prompt_done, avatar, typing, pong, error.

Полное описание каждого кадра — Протокол v1. Что реализовать в интерфейсе — Интерфейс приложения.