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

Подключение приложения к Hermes (для разработчика)

Короткая выжимка: что нужно от владельца агента, как подключиться и что реализовать. Полное описание протокола — Протокол v1, практическое руководство — Как это встроить.

1. Что вы получаете от владельца агента

Что Пример Зачем
Адрес адаптера wss://agent.example.com/mobile-ws точка подключения (WebSocket)
Токен приложения 64 hex-символа авторизация подключения
Идентификатор пользователя dev-pilot под каким пользователем вас видят в Hermes
(по желанию) id устройства pilot-laptop своя сессия и адрес для доставки cron

Токен — единственный секрет. Храните его в Keychain/Keystore, не в коде и не в логах; для публичного приложения каждому устройству нужен свой токен (владелец агента добавляет его в MOBILE_EXTRA_TOKENS — в том числе как device_id=token, привязывая токен к устройству, — или выдаёт через pairing) — один общий токен в сборке приложения означает, что любой владелец APK получит доступ к агенту.

2. Проверка за минуту (без кода)

Откройте examples/web/index.html, впишите адрес и токен, нажмите «Подключиться» и отправьте сообщение. Если агент ответил — связка работает, дальше дело за приложением.

3. Подключение в приложении

npm i hermes-mobile-client
import { HermesClient } from 'hermes-mobile-client';

const client = new HermesClient({
  url: 'wss://agent.example.com/mobile-ws',
  token: '<токен>',
  device: { id: 'my-app-1', name: 'Телефон', platform: 'android', appVersion: '1.0.0' },
  user: { id: 'dev-pilot', name: 'Разработчик' },   // id, согласованный с владельцем агента
  handlers: {
    onReady: (ready) => console.log('сессия', ready.session, ready.capabilities),
    onMessage: (m) => addToChat(m.text, m.final),
    onMessageEdit: (m) => replaceById(m.id, m.text),   // потоковая выдача
    onPrompt: (p) => showButtons(p.text, p.options),   // одобрение команды / clarify
    onMedia: (media) => saveAndShow(media),
    onAvatar: (state) => avatar.setState(state),
    onTyping: () => showTyping(),
    onError: (e) => show(e.message),
  },
});
client.connect();
client.sendText('привет');

Другие рантаймы (Flutter/Dart, Swift, Kotlin) — по скетчам в Как это встроить и готовым руководствам раздела «Руководства» сайта; боты и серверные интеграции — Python-клиент sdk/python/hermes_client.py.

4. Что реализовать в интерфейсе (по приоритету)

  1. Лента и ввод — обязательный минимум.
  2. Кнопки карточек (prompt → answerPrompt(id, optionId)): одобрение опасных команд, уточняющие вопросы, подтверждение слэш-команд. Без этого агент спросит текстом, и пользователю придётся печатать /approve.
  3. Медиа в обе стороны: sendImage/sendDocument/sendVoice (клиент сам режет большие файлы на куски) и сохранение входящих media кадров.
  4. Стриминг: при message.edit = true перерисовать сообщение с тем же id.
  5. Аватар (по желанию): WebView со страницей, реализующей window.hermesAvatar.setState/speak/setVolume; URL приходит в кадре ready (avatar_url).
  6. Голос: запись WAV 16 кГц моно → sendVoice(base64, 'wav').

5. Правила, которые нельзя нарушать

  • Первым кадром — только hello; иначе соединение закроется.
  • Код закрытия 1008 — отказ в доступе (токен или устройство/пользователь не разрешены). Повторять бессмысленно.
  • id сообщения — постоянный для каждого сообщения: повтор при обрыве сети адаптер проигнорирует (защита от дублей).
  • Незнакомые кадры и поля игнорируйте — протокол расширяется только добавлениями.
  • Лимиты: сообщение ≤ 12 000 символов, файл ≤ 8 МБ, кадр ≤ 16 МБ.

6. Что происходит на стороне Hermes

Ваше приложение попадает в те же сессии, память и инструменты агента, что и остальные каналы (Telegram, CLI): история сохраняется в Hermes, а не в приложении, cron умеет доставлять сообщения и файлы на устройство (deliver=mobile:<device>), а решения пользователя (одобрение команд, ответы на вопросы) применяются родными механизмами Hermes.