Эксперименты
План рефакторинга унифицированного стриминга для рантаймов
Цель
Создать один общий стриминговый пайплайн для main, subagent и acp, чтобы все рантаймы получали идентичное поведение при объединении, разбиении на чанки, порядке доставки и восстановлении после сбоев.
Обоснование
- Текущее поведение разбросано по нескольким путям форматирования, специфичным для каждого рантайма.
- Ошибки форматирования/объединения могут быть исправлены в одном пути, но остаться в других.
- Согласованность доставки, подавление дубликатов и семантика восстановления сложнее для анализа.
Целевая архитектура
Единый пайплайн, адаптеры для конкретных рантаймов:
- Адаптеры рантаймов эмитируют только канонические события.
- Общий сборщик потока объединяет и финализирует события текста, инструментов и статуса.
- Общий проектор каналов применяет специфичное для канала разбиение на чанки/форматирование один раз.
- Общий журнал доставки обеспечивает идемпотентную семантику отправки/повтора.
- Исходящий адаптер канала выполняет отправку и записывает контрольные точки доставки.
Контракт канонических событий:
turn_startedtext_deltablock_finaltool_startedtool_finishedstatusturn_completedturn_failedturn_cancelled
Направления работ
1) Канонический контракт стриминга
- Определить строгую схему событий + валидацию в ядре.
- Добавить контрактные тесты для адаптеров, гарантирующие совместимость событий от каждого рантайма.
- Отклонять некорректные события рантаймов на раннем этапе и предоставлять структурированную диагностику.
2) Общий процессор потока
- Заменить логику объединения/проецирования, специфичную для каждого рантайма, на один процессор.
- Процессор управляет буферизацией текстовых дельт, сбросом при простое, разделением на максимальные чанки и сбросом при завершении.
- Перенести разрешение конфигурации ACP/main/subagent в один вспомогательный модуль, чтобы предотвратить расхождение.
3) Общее проецирование каналов
- Оставить адаптеры каналов простыми: принимают финализированные блоки и отправляют.
- Перенести специфичные для Discord особенности разбиения на чанки только в проектор каналов.
- Сохранять пайплайн независимым от канала до этапа проецирования.
4) Журнал доставки + повтор
- Добавить ID доставки для каждого хода/чанка.
- Записывать контрольные точки до и после физической отправки.
- При перезапуске идемпотентно повторять ожидающие чанки и избегать дубликатов.
5) Миграция и переход
- Фаза 1: режим теневого копирования (новый пайплайн вычисляет вывод, но отправка идет по старому пути; сравнение).
- Фаза 2: поэтапный переход по рантаймам (
acp, затемsubagent, затемmainили наоборот, в зависимости от риска). - Фаза 3: удаление устаревшего кода стриминга, специфичного для рантаймов.
Не входит в цели
- В рамках этого рефакторинга не вносятся изменения в модель политик/разрешений ACP.
- Не добавляются специфичные для каналов функции, за исключением исправлений для совместимости при проецировании.
- Не перерабатывается транспорт/бэкенд (контракт плагина acpx остается как есть, если только не требуется для обеспечения паритета событий).
Риски и меры по их снижению
- Риск: регрессии в поведении существующих путей main/subagent. Мера снижения: сравнение в режиме теневого копирования + контрактные тесты адаптеров + сквозные тесты каналов.
- Риск: дублирующие отправки при восстановлении после сбоя. Мера снижения: устойчивые ID доставки + идемпотентный повтор в адаптере доставки.
- Риск: повторное расхождение адаптеров рантаймов. Мера снижения: обязательный общий набор контрактных тестов для всех адаптеров.
Критерии приемки
- Все рантаймы проходят общие контрактные тесты стриминга.
- Discord ACP/main/subagent демонстрируют эквивалентное поведение по пробелам/разбиению на чанки для небольших дельт.
- При сбое/перезапуске повторная отправка не создает дубликатов чанков для одного и того же ID доставки.
- Устаревший путь проектора/объединителя ACP удален.
- Разрешение конфигурации стриминга является общим и не зависит от рантайма.