[2026-09-29] eagle: personal/plans/mattermost-mention-thread-autoresponse.md personal/plans/mattermost-mention-thread-autoresponse.md.bak-mention-result personal/tech/hermes-whale-mattermost-transport.md
This commit is contained in:
1 parent
b30684ecfb
commit
e75cf79e79
3 files changed
+273
No files matched your search
@@ -0,0 +1,135 @@
|
||||
---
|
||||
tags:
|
||||
- hermes
|
||||
- mattermost
|
||||
- mention
|
||||
- adapter
|
||||
- whale
|
||||
type: plan
|
||||
namespace: personal
|
||||
status: implemented — awaiting gateway restart
|
||||
created: '2026-09-29'
|
||||
updated: '2026-09-29'
|
||||
---
|
||||
# План: MM mention-gating — авто-ответ в треде с ботом
|
||||
|
||||
**Дата:** 2026-09-29
|
||||
**Статус:** Реализовано, ждёт рестарта gateway (приёмка Alex в UI)
|
||||
|
||||
## Итог
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| Файл | `~/.hermes/hermes-agent/plugins/platforms/mattermost/adapter.py` |
|
||||
| md5 до | `9f3def29d90d00287cdbca3db000c513` |
|
||||
| md5 после | `ed8c4b7735e3371f697c20cfbd11e421` |
|
||||
| Бэкап | `~/.hermes/hermes-whale/backups/20260929-mm-mention/adapter.py` |
|
||||
| Скрипт | `/tmp/mm-thread-mention.py` (идемпотентный) |
|
||||
| Тесты | `tests/gateway/test_mattermost.py` — 46 passed (было 43, +3) |
|
||||
| Коммит hermes-agent | `9b46ba791a` feat(mattermost): allow thread replies without @mention |
|
||||
| Push | `207a1de16c..9b46ba791a main -> main` → github.com:mallexxx/hermes-agent.git |
|
||||
|
||||
### Что именно изменено
|
||||
|
||||
`_handle_ws_event`, перед mention-гейтом:
|
||||
|
||||
```python
|
||||
is_thread_reply = bool(post.get("root_id"))
|
||||
...
|
||||
if (
|
||||
require_mention
|
||||
and not is_free_channel
|
||||
and not has_mention
|
||||
and not is_thread_reply
|
||||
):
|
||||
return
|
||||
```
|
||||
|
||||
Три новых теста:
|
||||
- `test_thread_reply_without_mention_responds` — тред без меншна → ответ есть
|
||||
- `test_channel_root_without_mention_still_skipped` — корень канала без меншна → тишина
|
||||
- `test_thread_reply_with_mention_strips_mention` — меншн в треде всё ещё убирается из текста
|
||||
|
||||
Остаток: рестарт gateway. Без него патч не подхватится (адаптер импортируется при старте).
|
||||
`gateway run --replace` из активной сессии её убьёт — рестарт делает Alex.
|
||||
|
||||
## Задача (Alex, дословно)
|
||||
|
||||
> «в канале — меншен обязателен, в треде где только с ботом переписка — авто, без меншена»
|
||||
|
||||
## Проблема (подтверждена фактами)
|
||||
|
||||
`plugins/platforms/mattermost/adapter.py:734` — гейт применяется к **любому** не-DM:
|
||||
|
||||
```python
|
||||
if channel_type_raw != "D": # тред = channel_type "O" → гейт срабатывает
|
||||
...
|
||||
if require_mention and not is_free_channel and not has_mention:
|
||||
return # молча дроп, inbound не создаётся
|
||||
```
|
||||
|
||||
**Доказательство (2026-09-29, канал `hermes-maintenance` = `a6nyh77eyjbn5c1owh1i8eebee`):**
|
||||
|
||||
| Время | Пост | Меншн | inbound в gateway.log |
|
||||
|---|---|---|---|
|
||||
| 12:38:01 | `@whale` | ✅ | ✅ есть |
|
||||
| 12:38:40 | `тут, отлично. как нам сделать бэкап...` | ❌ | ❌ **нет** (ответа не было) |
|
||||
|
||||
Пост 12:38:40 — в треде `pcoiddzrqty3ipqtozgcs9ttte`, начатом ботом. Меншн не нужен, но требуется.
|
||||
|
||||
## Решение
|
||||
|
||||
Пропускать mention-гейт, когда пост находится **в треде** (`root_id` задан).
|
||||
В корне канала меншн остаётся обязательным.
|
||||
|
||||
### Критерий (выбран)
|
||||
|
||||
**Тред = `root_id` непустой.** Просто, детерминированно, не требует API-запросов.
|
||||
|
||||
Обоснование: чтобы ответить в треде, бот должен быть в канале. Треды канала — общие
|
||||
рабочие ветки; вовлечение в тред человеком = приглашение. Дополнительный критерий
|
||||
«бот уже отвечал в этом треде» требует запроса к API на каждое сообщение (латентность +
|
||||
зависимость от прав) и не даёт выигрыша: в канале бот и так отвечает на `@whale`.
|
||||
|
||||
### Правка
|
||||
|
||||
В `_handle_ws_event` перед mention-гейтом вычислить `root_id` и добавить его в условие:
|
||||
|
||||
```python
|
||||
is_thread_reply = bool(post.get("root_id"))
|
||||
...
|
||||
if require_mention and not is_free_channel and not has_mention and not is_thread_reply:
|
||||
return
|
||||
```
|
||||
|
||||
Плюс: стрип меншна выполнять как раньше (если меншн есть — убрать из текста).
|
||||
|
||||
### Что НЕ меняется
|
||||
|
||||
- Корень канала без `@whale` → по-прежнему молчит.
|
||||
- `MATTERMOST_FREE_RESPONSE_CHANNELS` — не трогаем.
|
||||
- DM — не затронуты.
|
||||
- `MATTERMOST_REQUIRE_MENTION=true` — остаётся.
|
||||
|
||||
## Шаги
|
||||
|
||||
1. Коммит ДО (`hermes-agent`, ветка `main`, HEAD `207a1de16c`).
|
||||
2. Правка adapter.py — скрипт `python3 /tmp/<name>.py`, не sed.
|
||||
3. Тест: `pytest plugins/platforms/mattermost/ tests/ -k mattermost -o "addopts="` (если есть).
|
||||
4. Коммит ПОСЛЕ.
|
||||
5. Рестарт gateway — **делает Alex** (`gateway run --replace` из этой сессии её убьёт).
|
||||
6. Приёмка Alex в UI: пост в треде без меншна → ответ есть; пост в корне канала без меншна → ответа нет.
|
||||
|
||||
## Питфоллы
|
||||
|
||||
- 🔴 `gateway run --replace` из этой сессии убивает саму сессию (инцидент 2026-09-29 11:31).
|
||||
- 🔴 Логи читать из `~/.hermes/hermes-whale/logs/`, не из `~/.hermes/logs/`.
|
||||
- Адаптер читает `config.extra.*` ИЛИ env — при правке поведение env перебивает config
|
||||
(см. `_apply_yaml_config`, строки 1108-1114).
|
||||
- Логи уровня DEBUG не пишутся — `skipping non-DM message without @mention` в `gateway.log`
|
||||
не виден (`grep -c` вернул 0 при 1.6 МБ лога). Судить по наличию/отсутствию `inbound message`.
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[personal/tech/hermes-whale-mattermost-transport.md]] — транспорт, env-ключи, инцидент с рестартом, диагностика «бот молчит в канале»
|
||||
- [[personal/tech/hermes-pairing-multi-profile.md]] — pairing
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
tags:
|
||||
- hermes
|
||||
- mattermost
|
||||
- mention
|
||||
- adapter
|
||||
- whale
|
||||
type: plan
|
||||
namespace: personal
|
||||
status: plan approved — in progress
|
||||
created: '2026-09-29'
|
||||
updated: '2026-09-29'
|
||||
---
|
||||
# План: MM mention-gating — авто-ответ в треде с ботом
|
||||
|
||||
**Дата:** 2026-09-29
|
||||
**Статус:** план утверждён Alex, выполняется
|
||||
|
||||
## Задача (Alex, дословно)
|
||||
|
||||
> «в канале — меншен обязателен, в треде где только с ботом переписка — авто, без меншена»
|
||||
|
||||
## Проблема (подтверждена фактами)
|
||||
|
||||
`plugins/platforms/mattermost/adapter.py:734` — гейт применяется к **любому** не-DM:
|
||||
|
||||
```python
|
||||
if channel_type_raw != "D": # тред = channel_type "O" → гейт срабатывает
|
||||
...
|
||||
if require_mention and not is_free_channel and not has_mention:
|
||||
return # молча дроп, inbound не создаётся
|
||||
```
|
||||
|
||||
**Доказательство (2026-09-29, канал `hermes-maintenance` = `a6nyh77eyjbn5c1owh1i8eebee`):**
|
||||
|
||||
| Время | Пост | Меншн | inbound в gateway.log |
|
||||
|---|---|---|---|
|
||||
| 12:38:01 | `@whale` | ✅ | ✅ есть |
|
||||
| 12:38:40 | `тут, отлично. как нам сделать бэкап...` | ❌ | ❌ **нет** (ответа не было) |
|
||||
|
||||
Пост 12:38:40 — в треде `pcoiddzrqty3ipqtozgcs9ttte`, начатом ботом. Меншн не нужен, но требуется.
|
||||
|
||||
## Решение
|
||||
|
||||
Пропускать mention-гейт, когда пост находится **в треде** (`root_id` задан).
|
||||
В корне канала меншн остаётся обязательным.
|
||||
|
||||
### Критерий (выбран)
|
||||
|
||||
**Тред = `root_id` непустой.** Просто, детерминированно, не требует API-запросов.
|
||||
|
||||
Обоснование: чтобы ответить в треде, бот должен быть в канале. Треды канала — общие
|
||||
рабочие ветки; вовлечение в тред человеком = приглашение. Дополнительный критерий
|
||||
«бот уже отвечал в этом треде» требует запроса к API на каждое сообщение (латентность +
|
||||
зависимость от прав) и не даёт выигрыша: в канале бот и так отвечает на `@whale`.
|
||||
|
||||
### Правка
|
||||
|
||||
В `_handle_ws_event` перед mention-гейтом вычислить `root_id` и добавить его в условие:
|
||||
|
||||
```python
|
||||
is_thread_reply = bool(post.get("root_id"))
|
||||
...
|
||||
if require_mention and not is_free_channel and not has_mention and not is_thread_reply:
|
||||
return
|
||||
```
|
||||
|
||||
Плюс: стрип меншна выполнять как раньше (если меншн есть — убрать из текста).
|
||||
|
||||
### Что НЕ меняется
|
||||
|
||||
- Корень канала без `@whale` → по-прежнему молчит.
|
||||
- `MATTERMOST_FREE_RESPONSE_CHANNELS` — не трогаем.
|
||||
- DM — не затронуты.
|
||||
- `MATTERMOST_REQUIRE_MENTION=true` — остаётся.
|
||||
|
||||
## Шаги
|
||||
|
||||
1. Коммит ДО (`hermes-agent`, ветка `main`, HEAD `207a1de16c`).
|
||||
2. Правка adapter.py — скрипт `python3 /tmp/<name>.py`, не sed.
|
||||
3. Тест: `pytest plugins/platforms/mattermost/ tests/ -k mattermost -o "addopts="` (если есть).
|
||||
4. Коммит ПОСЛЕ.
|
||||
5. Рестарт gateway — **делает Alex** (`gateway run --replace` из этой сессии её убьёт).
|
||||
6. Приёмка Alex в UI: пост в треде без меншна → ответ есть; пост в корне канала без меншна → ответа нет.
|
||||
|
||||
## Питфоллы
|
||||
|
||||
- 🔴 `gateway run --replace` из этой сессии убивает саму сессию (инцидент 2026-09-29 11:31).
|
||||
- 🔴 Логи читать из `~/.hermes/hermes-whale/logs/`, не из `~/.hermes/logs/`.
|
||||
- Адаптер читает `config.extra.*` ИЛИ env — при правке поведение env перебивает config
|
||||
(см. `_apply_yaml_config`, строки 1108-1114).
|
||||
- Логи уровня DEBUG не пишутся — `skipping non-DM message without @mention` в `gateway.log`
|
||||
не виден (`grep -c` вернул 0 при 1.6 МБ лога). Судить по наличию/отсутствию `inbound message`.
|
||||
|
||||
## Связанные заметки
|
||||
|
||||
- [[personal/tech/hermes-whale-mattermost-transport.md]] — транспорт, env-ключи, инцидент с рестартом
|
||||
- [[personal/tech/hermes-pairing-multi-profile.md]] — pairing
|
||||
@@ -260,6 +260,46 @@ ssh kraken "docker exec mm-postgres psql -U mmuser -d mattermost -t -c \
|
||||
⚠️ Без членства в канале `@whale` не работает даже при `REQUIRE_MENTION=true` —
|
||||
упоминание не создаёт доставку, оно лишь фильтр поверх уже приходящих событий.
|
||||
|
||||
### ✅ Тред-посты больше не требуют меншна (патч 2026-09-29)
|
||||
|
||||
**Проблема:** mention-гейт применялся к **любому** не-DM, включая треды. Пост в треде,
|
||||
начатом ботом, без `@whale` молча дропался (подтверждено: пост 12:38:40 в треде
|
||||
`pcoiddzrqty3ipqtozgcs9ttte` не попал в `gateway.log`).
|
||||
|
||||
**Решение (коммит `9b46ba791a`, hermes-agent):**
|
||||
|
||||
```python
|
||||
# plugins/platforms/mattermost/adapter.py, _handle_ws_event
|
||||
is_thread_reply = bool(post.get("root_id"))
|
||||
...
|
||||
if (
|
||||
require_mention
|
||||
and not is_free_channel
|
||||
and not has_mention
|
||||
and not is_thread_reply
|
||||
):
|
||||
return
|
||||
```
|
||||
|
||||
**Правило после патча:**
|
||||
|
||||
| Место поста | Меншн `@whale` |
|
||||
|---|---|
|
||||
| Корень канала | ✅ обязателен |
|
||||
| Тред (`root_id` непустой) | ❌ не нужен |
|
||||
| DM | ❌ не нужен (был и раньше) |
|
||||
|
||||
`MATTERMOST_REQUIRE_MENTION=true` остаётся; `FREE_RESPONSE_CHANNELS` не тронут.
|
||||
Если меншн в треде всё же написан — он убирается из текста перед отправкой агенту.
|
||||
|
||||
⚠️ **Патч активен только после рестарта gateway** — адаптер импортируется при старте.
|
||||
Рестарт делает Alex (`gateway run --replace` из активной сессии её убивает, см. §Инцидент).
|
||||
|
||||
**Файлы:**
|
||||
- План + итог: [[personal/plans/mattermost-mention-thread-autoresponse.md]]
|
||||
- Бэкап адаптера: `~/.hermes/hermes-whale/backups/20260929-mm-mention/adapter.py`
|
||||
- Тесты: `tests/gateway/test_mattermost.py` — 46 passed (3 новых)
|
||||
|
||||
### 📌 Питфолл диагностики: `mattermost psql`
|
||||
|
||||
В контейнере `mattermost` **нет `psql`** (`exec: "psql": executable file not found`).
|
||||
|
||||
Reference in new issue
Block a user