From 886cbe68114103d26058ee84c82b744134d25e23 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 18 Jun 2026 17:40:29 +0600 Subject: [PATCH] =?UTF-8?q?[2026-06-18]=20eagle:=20personal/agent/Phase=20?= =?UTF-8?q?2=20=E2=80=94=20Approval=20Reactions.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agent/Phase 2 — Approval Reactions.md | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 personal/agent/Phase 2 — Approval Reactions.md diff --git a/personal/agent/Phase 2 — Approval Reactions.md b/personal/agent/Phase 2 — Approval Reactions.md new file mode 100644 index 00000000..de4b97f0 --- /dev/null +++ b/personal/agent/Phase 2 — Approval Reactions.md @@ -0,0 +1,60 @@ +# Phase 2 — Approval Reactions + +## Баг 1: Сообщения дропаются при аппрувл-прерывании (подтверждён) + +**Дата:** 2026-06-18 +**Статус:** Подтверждён, причина установлена + +### Симптом +Когда 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` не срабатывает