Files
obsidian-vault/personal/plans/mattermost-mention-thread-autoresponse.md
T

136 lines
6.4 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.
---
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