[2026-06-18] taiga-vault: personal/agent/Phase 2 — Approval Reactions.md
This commit is contained in:
@@ -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` не срабатывает
|
||||||
Reference in New Issue
Block a user