[2026-06-21] taiga-vault: family/how-to/htpc-emulators-setup.md personal/agent/Phase 2 — Approval Reactions.md personal/creative/songs/Рыба.md personal/projects/balda/balda-valera.md personal/projects/balda/fast-rlm-integration.md personal/projects/hermes/hermes-gateway-stream-consumer-text-loss.md personal/projects/hermes/no-edit-segment-send-bug.md personal/projects/zulip-router-approval-reactions.md personal/projects/zulip-router.md

This commit is contained in:
Taiga
2026-06-21 05:30:47 +00:00
parent 54c631d61b
commit 185ba67062
9 changed files with 599 additions and 118 deletions
@@ -0,0 +1,64 @@
---
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 вызова терминала + промежуточные фразы — все сообщения дошли до пользователя.