9.2 KiB
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 — курсор остаётся навсегда, потому что:
- Partial шлётся с курсором (первый send)
- Edit не поддерживается → нельзя перезаписать/убрать курсор
_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:
- LLM стримит текст →
on_delta()кладёт в очередь - Стрим прерывается аппрувом (interrupt) →
got_done = False, циклrun()выходит раньше времени _send_fallback_final()не вызывается — потому что он только приgot_done(строка 580)- Накопленный
_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_MINIMALdefault)
gateway/__pycache__/stream_consumer.cpython-311.pyc:
- Был stale от June 4 — не влияет на проблему (редактируемый install работает)
Как чинить
Нужно чтобы при interrupt (аппрув-прерывание) стример отправлял накопленный текст перед выходом. Варианты:
- В
run.pyпосле прерывания стрима — вызвать_send_fallback_final(_accumulated)если есть что отправлять - В
stream_consumer.pyна interrupt path — форсироватьgot_doneили прямой вызов_send_fallback_final - Не прерывать стрим при аппруве — пусть стриминг продолжается до естественного завершения (
got_done)
История расследования
- Сначала думали что проблема в
stream_consumerс streaming enabled — но баг был ДО включения streaming - Выяснили что streaming был выключен для webhook из-за
_TIER_MINIMALвdisplay_config.py→streaming: False - После включения
display.platforms.webhook.streaming: true— стриминг пошёл - Тест с
rm -rfподтвердил: текст до аппрува не появляется у юзера - Логи подтвердили:
got_doneне вызывается →_send_fallback_finalне срабатывает
Tool progress для webhook
Статус: Исправлено ✅
Проблема
Tool progress (уведомления о tool calls) не работали для вебхука — сообщения о ходе выполнения тулов не доходили до юзера.
Почему
Два гарда в gateway/run.py:
-
Первый гард (
run.py:16992) — условие включения прогресса: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"→ прогресс выключен. -
Второй гард (
run.py:17184-17191) — проверка что у адаптера есть свойedit_message:if type(adapter).edit_message is BasePlatformAdapter.edit_message and source.platform != Platform.WEBHOOK: # очистить очередь и выйтиУ
WebhookAdapterнет своегоedit_message(наследует базовый) → прогресс скипается даже если включён.
Что сделано
- Конфиг — добавлено
display.platforms.webhook.tool_progress: all run.py:16992— изменён первый гард: разрешает tool progress для вебхука если в конфиге не"off"run.py:17215-17217— добавлен форсcan_edit=FalseдляPlatform.WEBHOOK:Прогресс-сообщения для вебхука шлются новыми сообщениями черезif source.platform == Platform.WEBHOOK: can_edit = Falseadapter.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 (подтверждено).