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

9.2 KiB
Raw Blame History

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.debuglogger.warning в _send_or_edit (enter, cursor-only)
  • logger.debuglogger.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.pystreaming: 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) — условие включения прогресса:

    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:

    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:
    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 (подтверждено).