Files
obsidian-vault/personal/tech/hermes-whale-mattermost-transport.md
T

234 lines
13 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: hermes-whale — Mattermost как транспорт
created: '2026-09-29'
updated: '2026-09-29'
type: tech
namespace: personal
status: in-progress — бот и канал созданы, транспорт НЕ дописан
tags:
- hermes
- mattermost
- transport
- whale
- kraken
- lsp
related:
- '[[personal/projects/balda/mattermost-kraken-deploy.md]]'
- '[[personal/tech/kraken-host-resource-limits.md]]'
- '[[personal/tech/hermes-fork-vs-upstream.md]]'
---
# hermes-whale — Mattermost как транспорт
> Задача Alex 2026-09-29: «Добавь mattermost на кракене транспортом в hermes-whale
> и добавь в MM бота себе нового (Кит/whale)».
> Статус: **бот `whale` и канал созданы ✅, транспорт в `.env` НЕ дописан ⏳**.
## Расклад (решение)
| Компонент | Где | Почему |
|---|---|---|
| **hermes-whale gateway** | **Mac** (не Kraken) | профиль живёт на Mac; это НЕ переезд |
| **Mattermost сервер** | Kraken | уже работает, `health=healthy` |
| Связь | `https://mm.qentra.top` (Cloudflare Tunnel) | проверено 2026-09-29: `{"status":"OK"}` |
⚠️ **На Kraken транспорт НЕ разворачивается.** Там 4 ГБ RAM и история OOM
(см. [[personal/tech/kraken-host-resource-limits.md]]). Mattermost-транспорт
в контейнере `hermes-kraken` не поднимаем.
## Готовое: плагин уже существует
Код писать **не нужно** — платформа `mattermost` уже в дереве:
```
~/.hermes/hermes-agent/plugins/platforms/mattermost/adapter.py
~/.hermes/hermes-agent/plugins/platforms/mattermost/plugin.yaml
```
### Env-переменные (из `plugin.yaml`)
| Переменная | Обяз. | Смысл |
|---|---|---|
| `MATTERMOST_URL` | ✅ | URL сервера, напр. `https://mm.qentra.top` |
| `MATTERMOST_TOKEN` | ✅ | токен бота или PAT |
| `MATTERMOST_HOME_CHANNEL` | — | канал для cron/уведомлений |
| `MATTERMOST_REPLY_MODE` | — | `thread` (вложенно) или `off` (плоско). **Дефолт `off`** |
| `MATTERMOST_REQUIRE_MENTION` | — | требовать `@bot` в каналах (дефолт `true`) |
| `MATTERMOST_ALLOWED_USERS` | — | белый список user id |
| `MATTERMOST_ALLOW_ALL_USERS` | — | любой юзер триггерит бота (dev) |
| `MATTERMOST_FREE_RESPONSE_CHANNELS` | — | каналы без обязательного `@mention` |
| `MATTERMOST_ALLOWED_CHANNELS` | — | если задан — бот отвечает ТОЛЬКО в них |
📌 Адаптер читает `config.extra.{url, reply_mode}` **ИЛИ** env (`adapter.py:77-97`).
В `config.yaml` профиля есть блок `mattermost:` (пока только `channel_prompts`).
## Созданные объекты MM (2026-09-29)
| Объект | ID | Как создано |
|---|---|---|
| Бот `whale` (Кит) | `k4i3uihzp3gdxj5gx3en3tbeso` | `mmctl user create` → `mmctl user convert --bot` |
| Канал `whale` | `fnm6auyc8trz5njxrfofebkbfr` | `mmctl channel create --team qentra` |
| Команда | `qentra` = `m1iwp7t9w7no3y8gi876iw39he` | существовала |
| Владелец бота | `whale` (Owned by whale) | ⚠️ не `admin`, см. ниже |
✅ **Бот в канале** — подтверждено живой командой:
```
channel users list qentra:whale
→ k4i3uihzp3gdxj5gx3en3tbeso: whale (whale@localhost) channel_user
```
⚠️ **Бот в команде — не подтверждено.** `mmctl team users add qentra <bot_id>` вернул
`exit=0` (молчаливый успех), но проверить нечем: **`mmctl team users list`
не существует** (только `add` / `remove`). Проверять через API
`GET /api/v4/teams/{team_id}/members/{user_id}` — требует рабочего PAT.
## 🔴 Питфоллы, найденные на месте
1. **`mmctl user convert --bot` требует ШЕСТЬ флагов, не один.**
`--owner` не существует вовсе. Минимальный набор из `--help`:
```
mmctl --local user convert <user> --bot \
--email <e> --firstname <f> --lastname <l> --locale en --system-admin
```
Без `--email`/`--firstname`/`--lastname`/`--locale` конвертация не проходит.
Вывод успеха: `whale converted to bot.`
2. **`mmctl user convert` НЕ выдаёт токен.** Токен выпускается отдельно:
`mmctl --local token generate whale <desc>`. MM отдаёт значение **ровно один раз**.
3. **`mmctl channel list --json` печатает не-JSON перед JSON.** Первая строка —
`There are 4 channels on local instance`, потом `[`. `jq` падает с
`parse error: Invalid numeric literal at line 1, column 6`.
Обход: `sed -n '/^\[/,$p' | jq …`.
4. **`mmctl team users list` НЕ существует.** Есть только `add`/`remove`.
Проверка членства — только через REST API.
5. **REST `/api/v4/...` с токеном из `.adminpw` даёт 401**
(`api.context.session_expired.app_error`). `.adminpw` — пароль, не токен.
Для API нужен PAT: `mmctl --local token generate admin <desc>`,
заголовок `Authorization: Bearer <token>`. ⚠️ Заголовок `Token:` в MM 11.x не принимается.
6. **`mmctl` не имеет команды чтения состава команды** — приходится идти в API.
Постинг тоже недоступен (`post create` → `not supported in local mode`), чтение работает.
## Что осталось (следующий заход)
1. Выпустить токен бота:
```
ssh kraken "docker exec mattermost mmctl --local token generate whale whale-hermes"
```
⚠️ Значение показывается один раз — перехватить сразу, записать в 0600-файл.
2. Вписать в `/Users/admin/.hermes/hermes-whale/.env`:
```
MATTERMOST_URL=https://mm.qentra.top
MATTERMOST_TOKEN=<токен>
MATTERMOST_HOME_CHANNEL=fnm6auyc8trz5njxrfofebkbfr
MATTERMOST_REPLY_MODE=thread
MATTERMOST_REQUIRE_MENTION=true
```
3. Перезапустить gateway на Mac: `hermes gateway run --replace`.
4. **Приёмка = Alex пишет `@whale привет` в канале `whale`, видит ответ в UI.**
Не «контейнер Up», не «curl отвечает».
## Main delivery / Telegram — 🔴 ЗАБЛОКИРОВАНО
Alex: «main delivery поставь телеграм, там есть вроде бот для Кита».
**Бота для Telegram НЕТ.** Проверено: в `hermes-whale/.env` — **ни одной
`TELEGRAM_*` переменной**. Полный список ключей `.env`:
```
DEEPSEEK_API_KEY FIRECRAWL_API_URL GLM_API_KEY
ZULIP_ALLOWED_USERS ZULIP_API_KEY ZULIP_BOT_EMAIL ZULIP_DEFAULT_TOPIC
ZULIP_FREE_STREAMS ZULIP_HOME_CHANNEL ZULIP_POLLING_DISABLED
ZULIP_REQUIRE_MENTION ZULIP_URL
```
Код адаптера есть (`gateway/platforms/telegram.py`), токена нет.
🔴 **Создать Telegram-бота программно невозможно** — только через BotFather вручную.
Нужен `TELEGRAM_BOT_TOKEN` от Alex. Пока его нет — main delivery на Telegram
поставить нечем.
Действующий home-канал профиля сейчас — **Zulip** (`/master::hermes`).
## LSP-серверы — разбор (вопрос Alex)
**Что это.** Подсистема `agent/lsp/` — language-серверы, которые `write_file`/`patch`
дёргают **сразу после записи файла** для семантической проверки (pyright → `.py`,
gopls → `.go`, yaml-language-server → `.yaml`). Это те самые «auto-runs syntax checks».
**Обязательны? Нет.** Мастер-тумблер `lsp.enabled` (дефолт `true`).
**Почему их 15 и почему 2.4 ГБ.** Это **живые дети gateway pid 31763**, не осиротевшие.
Не переиспользуются: каждое открытие Go-проекта поднимает **новый** `gopls`.
```
ppid=31763 pid=99339 604MB up 3д 09:38 gopls
ppid=31763 pid=67249 383MB up 2д 10:44 gopls
ppid=31763 pid=71815 256MB up 2д 09:14 gopls
ppid=31763 pid=95153 14MB up 19:44 bash-language-server
… ещё 11 × 8-14 МБ (pyright / yaml-language-server / docker-langserver)
```
Итог: **~1.24 ГБ в трёх `gopls` + ~1.1 ГБ в node-серверах ≈ 2.4 ГБ**.
| Ручка | Что делает |
|---|---|
| `hermes lsp restart` | рвёт клиентов, при следующей правке спавнятся заново. Разово вернёт ~2 ГБ |
| `lsp.enabled: false` | выключает подсистему целиком — «no servers spawn, no background event loop, no cost» |
| `lsp.install_strategy: manual` | `auto` (дефолт) сам ставит бинари в `<HERMES_HOME>/lsp/bin/` |
| `lsp.servers.<id>.disabled: true` | отключить конкретный сервер (напр. `gopls`) |
📌 **Gating:** LSP включается только когда cwd (или файл) внутри **git-worktree**.
Вне git-репо подсистема спит, работает только in-process синтаксическая проверка —
поэтому на Kraken (контейнер, cwd не git) LSP не потребляет RAM.
📌 **На Mac 64 ГБ — не проблема.** Это зафиксировано, чтобы не «оптимизировать» зря.
## Замер памяти Hermes (2026-09-29, вопрос Alex «сколько hermes жрёт памяти»)
| Что | Где | RSS |
|---|---|---|
| **hermes-whale gateway** (этот профиль) | Mac | **165 МБ** — pid 31763 = 112 МБ, pid 2934 = 53 МБ |
| **hermes-kraken** gateway | Kraken (контейнер) | **139 МБ** (замер 2026-09-27) |
| LSP-серверы | Mac | **~2.4 ГБ** (15 процессов) — это НЕ Hermes |
⚠️ Не путать: «Hermes ест 165 МБ», а «2.4 ГБ едят LSP-процессы, порождённые gateway».
Второй pid 2934 (`up 6 дней`) — второй gateway, вероятно от другого профиля/`--replace`-инстанс.
## Бэкапы (перед правкой)
`/Users/admin/.hermes/hermes-whale/backups/20260929-105131-mm-transport/`
| Файл | md5 (совпадает с рабочим) |
|---|---|
| `config.yaml` | `7b348fa585baede4d85e4bb7057694af` |
| `env` | `6f58de78b7c882bff84bf556ca8fa67b` |
⛔ **`.env` и `config.yaml` профиля ещё НЕ изменены** — транспорт не дописан.
## Скрипты этой сессии (в `/tmp`, не переживут reboot)
`whale-mm-backup.sh` · `whale-mm-probe.sh` · `whale-mm-create.sh` ·
`whale-mm-convert.sh` · `whale-mm-membership.sh` · `whale-mm-verify.sh`
⚠️ `/tmp/whale-mm-verify.sh` остался с битым heredoc (сломан харнессом при записи) —
переписать заново перед использованием, не запускать как есть.
## Ответ на вопрос «можно ли создавать каналы и пинговать бота»
| Вопрос | Ответ |
|---|---|
| Создавать каналы | ✅ да, Alex — админ. `EnableOpenServer=false` / `EnableUserCreation=false` закрывают только **самостоятельную регистрацию чужих**, админу не мешают |
| Пинговать бота | ✅ да, но бот обязан быть **в команде И в канале**, иначе посты падают 403 `api.context.permissions.app_error` |
| Команд на MM | одна — `qentra` |
## Связанные заметки
- [[personal/projects/balda/mattermost-kraken-deploy.md]] — сам сервер MM
- [[personal/tech/kraken-host-resource-limits.md]] — почему не на Kraken
- [[personal/tech/hermes-fork-vs-upstream.md]] — платформы живут в `plugins/platforms/`