[2026-09-29] eagle: personal/projects/balda/mattermost-kraken-deploy.md personal/tech/hermes-whale-mattermost-transport.md
This commit is contained in:
1 parent
dae4d91fcf
commit
d9aa3abc79
2 files changed
+264
No files matched your search
@@ -0,0 +1,233 @@
|
||||
---
|
||||
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/`
|
||||
Reference in new issue
Block a user