🤖 AI-агенты для бизнеса

19. Виджет и каналы ввода/вывода

🔵 Как пользователи и внешние системы общаются с агентами. Это не «API» в программном смысле, а каналы — готовые точки входа/выхода, которые агент получает из конфигурации.

Канал Где настраивается Характер
Виджет (веб) server.yaml → widget + встраивание widget.js встраиваемый чат на сайте
Telegram-бот agent.yaml → telegram (на агента) long-polling, личные чаты
VK-бот сообщества agent.yaml → vk (на агента) Long Poll, сообщения сообщества
Email (IMAP→SMTP) agent.yaml → email (на агента) входящие письма + ответ
HTTP API (SSE) без конфига POST /v1/chat/completions (§8)
Входящий webhook server.yaml → inbound POST /v1/inbound/:template (§8.8)
Sink'и (выход) notify в cron/email/workflow log/webhook/telegram/messages_db/agent/email/workflow (§11)

19.1 Виджет (веб)

Встраиваемый чат-интерфейс, который общается с агентом через /v1/chat/completions (SSE) и закрывает сессию через POST /v1/sessions/:id.

Встраивание

На любую страницу сайта:

<script src="http://127.0.0.1:3000/widget.js"></script>

Сервируемые маршруты: /widget (страница), /widget.js (лоадер), /dist/* (ассеты).

Какой агент открывается

Виджет разрешает модель в таком порядке (последний выигрывает):

  1. widget.default_model (из server.yaml);
  2. window.AGENTOS_MODEL — переменная родительского фрейма;
  3. ?model= в URL (/widget?model=felix).

Конфигурация в server.yaml:

widget:
  default_model: "drom-agent"   # агент по умолчанию

Базовый URL виджет берёт из window.AGENTOS_BASE_URL (пусто = тот же origin) — нужно при хостинге виджета на другом домене.

Готовые демо-страницы

URL Что
/widget?model=felix виджет с конкретным агентом
/demo/overlay виджет поверх живых сайтов (вкладки из config/demo.yaml)
/demo демо виджета

Вкладки /demo/overlay задаются в config/demo.yaml (tabs: [{label, url, model}], hot-reload'ится на лету).

Визуальные блоки в виджете

Инструменты могут вернуть визуальный слой (графики chart, таблицы table, текст) — виджет рендерит их inline (Chart.js + таблицы). Формат блоков и пагинация — общие поля.


19.2 Telegram

Один long-polling бот на шаблон; запускается при старте сервера, если задан token_env. Токен читается из env (никогда не в YAML).

telegram:
  token_env: MY_TG_BOT_TOKEN      # имя env с токеном бота
  allowed_user_ids: []            # пусто = любой; список = только эти Telegram user id
  show_typing: true               # индикатор «печатает…» во время работы
  show_tool_calls: true           # компактные строки статуса tool-вызовов
Поле По умолч. Описание
token_env пусто имя env с токеном; пусто = бот выключен
allowed_user_ids [] ограничение отправителей по Telegram user id
show_typing true показывать typing-индикатор
show_tool_calls true эхо tool-вызовов в чат

Визуальные блоки на Telegram: график → PNG (sendPhoto), таблица → markdown-строки.


19.3 VK (сообщество)

Бот сообщества на Long Poll API — не нужен публичный HTTPS. Один бот на шаблон; запускается при старте сервера, если задан token_env. Токен сообщества читается из env (никогда не в YAML).

vk:
  token_env: VK_GROUP_TOKEN     # имя env с group access token
  group_id: 123456789           # id сообщества (для longpoll и сообщений от имени группы)
  allowed_user_ids: []          # пусто = любой; список = только эти VK user id
  show_typing: true             # индикатор «печатает…» (messages.setActivity)
  show_tool_calls: true         # эхо tool-вызовов в чат
  poll_wait: 25                 # wait для longpoll (сек, 1..25)
Поле По умолч. Описание
token_env пусто имя env с токеном; пусто = бот выключен
group_id 0 id сообщества; 0 = вывести из токена
allowed_user_ids [] ограничение отправителей по VK user id
show_typing true показывать typing-индикатор
show_tool_calls true эхо tool-вызовов в чат
poll_wait 25 интервал ожидания longpoll-запроса (сек)

Сессия — vk:{template}:{peer_id} (для беседы peer_id = 2000000000 + chat_id). Права токена: messagesphotos/docs для загрузки медиа). Визуальные блоки: график → PNG через photos.getMessagesUploadServer, таблица → текстовые строки, файл → документ через docs.getMessagesUploadServer.

Настройка сообщества

Чтобы бот получал сообщения, в сообществе нужно сделать две вещи:

  1. Включить Long Poll API (Управление → API → Long Poll API → «Включён»).
  2. Включить тип события «Новые сообщения» — по умолчанию VK включает Long Poll, но все типы событий выключены (message_new: 0), поэтому бот не получает ничего. В UI — галочка «Новые сообщения» в Long Poll API; или через API:
curl -X POST "https://api.vk.com/method/groups.setLongPollSettings" \
  -d "group_id=<id>&access_token=<token>&v=5.199" \
  -d "message_new=1&message_reply=1&message_edit=1&message_allow=1&message_deny=1&message_typing_state=1"

Проверить текущие настройки: groups.getLongPollSettings (поле events.message_new).


19.4 Email

Опрос IMAP-ящика: каждое новое письмо запускает one-shot ход и отвечает по SMTP. Контекст между письмами — через долгую память (хук memory), ключ — канонический user id отправителя.

email:
  imap_host: imap.example.com
  imap_port: 993
  imap_username: support@example.com
  imap_password_env: EMAIL_PASSWORD   # пароль из env, не в YAML
  allowed_senders: []                 # пусто = любой; "@domain" = весь домен
  smtp:                               # reply-настройки (опусти = только обработка)
    host: smtp.example.com
    username: support@example.com
    password_env: SMTP_PASSWORD
    from: support@example.com
  notify: []                          # доп. sink'и (как у cron)
  poll_secs: 60
Поле По умолч. Описание
imap_host пусто IMAP-хост; пусто = канал выключен
imap_port 993 порт IMAP (implicit TLS)
imap_username пусто логин (обычно адрес ящика)
imap_password_env пусто имя env с паролем IMAP
allowed_senders [] разрешённые отправители (точный адрес или @домен)
smtp нет SMTP для ответа: host, username, password_env, from, tls, port
notify [] доп. sink'и результата
poll_secs 60 интервал опроса ящика

19.5 Программные каналы (указатели)