Files
obsidian-vault/personal/projects/hermes/no-edit-segment-send-bug.md
T

65 lines
2.8 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.
---
tags:
- hermes
- bug
- gateway
- stream_consumer
- fixed
---
# No-edit (webhook) segment send bug
**Дата:** 20.06.2026
**Файл:** `gateway/stream_consumer.py` (lines 574, 581, 591)
**Статус:** ✅ Исправлено, закоммичено
## Симптом
При webhook-доставке (Zulip, Telegram через no-edit) текст, который модель генерирует между tool calls (перед tool call, после возврата результата), **не отправлялся промежуточно**. Весь текст накапливался в `_accumulated` и улетал единым куском только на `got_done`. Пользователь видел только tool calls и финальный ответ.
## Root Cause
В `stream_consumer.py` в `adapter_supports_edit=False` ветке:
```python
# Строка 574 — ДО (баг):
_has_nl = "\\\\n" in self._accumulated # ищет буквальный \n (2 символа: \ + n)
# Строка 581 — ДО (баг):
_should_send = _has_nl and _can_send # segment_break не отправляет без \n
# Строка 591 — ДО (баг):
_nl_pos = self._accumulated.rfind("\\\\n") # ищет 2 символа вместо 1
```
`"\\\\n"` в Python-файле — это **4 слеша**: Python видит `\\n` (строка из 2 символов: `\` + `n`). А `_accumulated` содержит реальные символы newline (ASCII 10, один символ). Проверка всегда возвращала `False`, поэтому:
- `_has_nl = False``_should_send = False` (даже с `got_segment_break=True`)
- Текст копился до `got_done`
## Фикс
```python
# Строка 574 — ПОСЛЕ:
_has_nl = "\\n" in self._accumulated # Python escape для newline
# Строка 581 — ПОСЛЕ:
_should_send = _can_send # segment break/got_done всегда отправляют
# Строка 591 — ПОСЛЕ:
_nl_pos = self._accumulated.rfind("\\n") # Python escape для newline
```
## Тесты
Новый файл: `tests/gateway/test_stream_consumer_no_edit.py`
Три теста:
1. `test_no_edit_sends_text_across_segment_breaks` — текст с \n, 3 сегмента → 3 sends
2. `test_no_edit_sends_text_without_newline_on_segment_break` — текст без \n, segment_break → отправляет
3. `test_no_edit_multiple_segments_are_separate_messages` — 4 сегмента → 4 sends
Все 92 существующих теста stream_consumer проходят зелеными.
## Верификация
После фикса тест с 3x вызова терминала + промежуточные фразы — все сообщения дошли до пользователя.