Files
obsidian-vault/personal/agent/Phase 2 — Approval Reactions.md
T

150 lines
9.2 KiB
Markdown
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.
# Phase 2 — Approval Reactions
## Баг 1: Сообщения дропаются при аппрувл-прерывании (подтверждён)
**Дата:** 2026-06-18
**Статус:** Исправлен — добавлен streaming через `display.platforms.webhook.streaming: true`
## Баг 2: `▉` курсор в стриминге для webhook/Zulip (активный)
**Дата:** 2026-06-18
**Статус:** Диагностируется
### Симптом
При стриминге через webhook (Zulip) — каждое partial сообщение содержит `▉` курсор в конце. Zulip не поддерживает редактирование сообщений, курсор добавляется и никогда не убирается.
### Почему
`GatewayStreamConsumer` добавляет курсор `▉` к каждому partial сообщению (`on_delta``_send_or_edit`). Когда `adapter_supports_edit == False` — курсор остаётся навсегда, потому что:
1. Partial шлётся с курсором (первый send)
2. Edit не поддерживается → нельзя перезаписать/убрать курсор
3. `_send_fallback_final` при `got_done` — должен убрать курсор, но если edit не поддерживается — не может
### Что сделано
**Конфиг (`~/.hermes/hermes-whale/config.yaml`):**
- Добавлено `display.platforms.webhook.streaming: true` — стриминг для webhook
- Добавлено `platforms.webhook.extra.supports_message_editing: false` — указание что webhook не поддерживает edit
**Код (`gateway/run.py`):**
- Добавлено чтение `platforms.{platform}.extra.supports_message_editing` из конфига (строка 16712-16718)
- Если в конфиге `supports_message_editing: false``_adapter_supports_edit = False``_effective_cursor = ""` → курсор не добавляется
**Текущий статус:** `supports_message_editing: false` в конфиге есть, но логи всё ещё показывают `adapter_edit=True`. Причина выясняется.
### Логи (актуальные)
```
[whale-cursor] add cursor: ... adapter_edit=True
[whale-send] send_or_edit allowed: ... adapter_edit=True
```
Все логи показывают `adapter_edit=True` — настройка не применяется.
### Версии
- PID 17593 (Кит, порт 8645)
- Gateway запущен `python -m hermes_cli.main gateway run --replace`
- Логи: `~/.hermes/hermes-whale/logs/gateway.log`
- Конфиг: `~/.hermes/hermes-whale/config.yaml`
### Симптом
Когда LLM пишет текст (через стриминг), потом делает tool call с опасной командой — аппрув-промпт прерывает стрим. Весь текст, который LLM уже сказала ДО опасной команды, **не доходит до юзера**. Юзер видит только аппрув-промпт и финальный ответ (если он есть).
### Почему
Причина в **GatewayStreamConsumer** (`gateway/stream_consumer.py`).
При `streaming.enabled: true` для webhook/Zulip:
1. LLM стримит текст → `on_delta()` кладёт в очередь
2. Стрим прерывается аппрувом (interrupt) → `got_done = False`, цикл `run()` выходит раньше времени
3. `_send_fallback_final()` не вызывается — потому что он только при `got_done` (строка 580)
4. Накопленный `_accumulated` текст **теряется**
Дополнительно: `edit_supported=False` для Zulip/Webhook — стример не может редактировать, fallback mode активируется, но не успевает отработать.
### Логи из теста
```
[KIT-stream2] path=webhook streaming_enabled=True want_deltas=N/A _scfg.enabled=True transport=auto
[consumer] on_delta: 1 chars, queue=1
[send_or_edit] enter: ... edit_supported=False fallback_final=True ... (10+ раз, зациклен)
— got_done NOT FOUND в логах —
```
### Что меняли для диагностики
**`gateway/stream_consumer.py`:**
- `logger.debug``logger.warning` в `_send_or_edit` (enter, cursor-only)
- `logger.debug``logger.warning` в `_send_fallback_final` (enter)
- Добавлен `warnings.warn` на уровне импорта (для проверки загрузки модуля)
**`gateway/run.py`:**
- `[KIT] GatewayRunner.__init__ called` — проверка что run.py подхватывается
- `[KIT-stream] entering streaming setup` — первый path (не для webhook)
- `[KIT-stream2] path=webhook streaming_enabled=...` — второй path (для webhook)
**`/Users/admin/.hermes/hermes-whale/config.yaml`:**
- Добавлено `display.platforms.webhook.streaming: true` — чтобы стриминг работал для вебхука (был `_TIER_MINIMAL` default)
**`gateway/__pycache__/stream_consumer.cpython-311.pyc`:**
- Был stale от June 4 — не влияет на проблему (редактируемый install работает)
### Как чинить
Нужно чтобы при interrupt (аппрув-прерывание) стример **отправлял накопленный текст** перед выходом. Варианты:
1. **В `run.py` после прерывания стрима** — вызвать `_send_fallback_final(_accumulated)` если есть что отправлять
2. **В `stream_consumer.py` на interrupt path** — форсировать `got_done` или прямой вызов `_send_fallback_final`
3. **Не прерывать стрим при аппруве** — пусть стриминг продолжается до естественного завершения (`got_done`)
### История расследования
1. Сначала думали что проблема в `stream_consumer` с streaming enabled — но баг был ДО включения streaming
2. Выяснили что streaming был выключен для webhook из-за `_TIER_MINIMAL` в `display_config.py``streaming: False`
3. После включения `display.platforms.webhook.streaming: true` — стриминг пошёл
4. Тест с `rm -rf` подтвердил: текст до аппрува **не появляется** у юзера
5. Логи подтвердили: `got_done` не вызывается → `_send_fallback_final` не срабатывает
---
## Tool progress для webhook
**Статус:** Исправлено ✅
### Проблема
Tool progress (уведомления о tool calls) не работали для вебхука — сообщения о ходе выполнения тулов не доходили до юзера.
### Почему
Два гарда в `gateway/run.py`:
1. **Первый гард** (`run.py:16992`) — условие включения прогресса:
```python
tool_progress_enabled = progress_mode != "off" and (
source.platform != Platform.WEBHOOK
or cfg.display.platforms.get("webhook", {}).get("tool_progress", "off") != "off"
)
```
По умолчанию `display.platforms.webhook.tool_progress` не было в конфиге → `"off"` → прогресс выключен.
2. **Второй гард** (`run.py:17184-17191`) — проверка что у адаптера есть свой `edit_message`:
```python
if type(adapter).edit_message is BasePlatformAdapter.edit_message
and source.platform != Platform.WEBHOOK:
# очистить очередь и выйти
```
У `WebhookAdapter` нет своего `edit_message` (наследует базовый) → прогресс скипается даже если включён.
### Что сделано
1. **Конфиг** — добавлено `display.platforms.webhook.tool_progress: all`
2. **`run.py:16992`** — изменён первый гард: разрешает tool progress для вебхука если в конфиге не `"off"`
3. **`run.py:17215-17217`** — добавлен форс `can_edit=False` для `Platform.WEBHOOK`:
```python
if source.platform == Platform.WEBHOOK:
can_edit = False
```
Прогресс-сообщения для вебхука шлются новыми сообщениями через `adapter.send()`, не `edit_message()`.
### Коммиты
| Дата | Коммит | Описание |
|------|--------|----------|
| 2026-06-18 | `714026a6e` | Исправлен первый гард — разрешён tool progress для webhook |
| 2026-06-18 | (config) | Добавлен `display.platforms.webhook.tool_progress: all` |
| 2026-06-18 | `a92840dcd` | force `can_edit=False` для webhook — прогресс через `send()`, не `edit_message()` |
### Проверка
Tool progress ходит через вебхук — юзер видит уведомления о tool calls (подтверждено).