Repository navigation
fix(runtime): отказ модели пересказать историю больше не останавливает чат (#331) - #356
Conversation
…т чат навсегда #331: если модель отклоняла сам запрос на пересказ старой части истории (окно по её счёту, отказ провайдера), ход падал, история не менялась, и следующее сообщение отправляло тот же запрос с тем же результатом — чат замолкал навсегда. Выход — со следующего сообщения, без повтора внутри хода (решение владельца 08.10.2026): - отказ на пересказ (не временная недоступность и не отмена хода) записывается в состояние сессии отдельной транзакцией: compaction_summary_refusals, миграция 130; - каждый отказ вдвое уменьшает бюджет следующего пересказа, и бюджет становится жёстким: что не спасает обрезка, отдают старейшие сообщения с пометкой, сколько их выпало; - после четырёх отказов подряд старая часть заменяется пометкой «не удалось пересказать» без вызова модели — путь выхода гарантирован; - удачное сжатие обнуляет счётчик; строка AGENT_COMPACTION_SUMMARY_REFUSED с числом отказов. Обычное сжатие без отказов работает как раньше. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (11)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. WalkthroughДобавлены учёт отказов модели при суммаризации истории и обработка повторных отказов. Последующие запросы сводки используют меньший бюджет. После четырёх отказов система исключает старую часть истории и добавляет уведомление. ChangesОбработка отказов при суммаризации
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant TurnLoop
participant HistoryRepository
participant compactIfNeeded
participant Model
participant isRequestRefusal
TurnLoop->>HistoryRepository: загружает историю и счётчик отказов
HistoryRepository-->>TurnLoop: возвращает состояние сессии
TurnLoop->>compactIfNeeded: передаёт историю и счётчик
compactIfNeeded->>Model: отправляет запрос сводки с текущим бюджетом
Model-->>compactIfNeeded: возвращает отказ
compactIfNeeded->>isRequestRefusal: классифицирует ошибку
isRequestRefusal-->>compactIfNeeded: подтверждает отказ
compactIfNeeded->>HistoryRepository: увеличивает счётчик отказов
compactIfNeeded-->>TurnLoop: возвращает AGENT_COMPACTION_SUMMARY_REFUSED
Merge Risk: ⚪ Minimal · up to The refusal-recovery change is mergeable after normal checks; transient model errors do not consume the refusal counter. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 78.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 10 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
По ревью #331. Ошибка ключа, оплаты, пропавшая модель или модель, не ответившая вовремя, валят любой запрос, а не этот пересказ. Раньше они тоже засчитывались как отказ: четыре сообщения во время такой аварии молча выбросили бы старую часть истории. Отказом теперь считаются только переполнение окна, пустой ответ и отклонённый запрос без статусов доступа (401, 402, 403, 404). Когда старая часть истории выбрасывается после четырёх отказов, принятая раньше сводка остаётся. Ход падает с понятным кодом AGENT_COMPACTION_SUMMARY_REFUSED и сообщением, что следующее сообщение сожмёт историю сильнее, вместо «повтор не поможет». Если счётчик отказов записать не удалось, это уходит в лог, а ход падает с исходным отказом. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Что меняется
Если модель отклоняла сам запрос на пересказ старой части истории, чат застревал навсегда: каждое следующее сообщение отправляло тот же запрос с тем же отказом.
Теперь выход начинается со следующего сообщения, без повтора внутри хода (решение владельца 08.10):
compaction_summary_refusals, миграция 130);AGENT_COMPACTION_SUMMARY_REFUSEDс числом отказов.Обычное сжатие без отказов не меняется.
Проверено
Модульные тесты сжатия и интеграционный тест хода: временный сбой не считается отказом, отказ запоминается, следующий пересказ меньше, после успеха счётчик обнулён. Все тесты
agent/runtime(246) и проверка типов зелёные.Closes #331
🤖 Generated with Claude Code
Изменения
130_compaction_summary_refusals.sqlсоздаёт для него поле со значением по умолчанию0.AGENT_COMPACTION_SUMMARY_REFUSEDи записывает предупреждение. Ошибка сохранения счётчика не заменяет исходный отказ.Проверки
Добавлены тесты классификации отказов, компактизации и восстановления в следующем ходе. Результаты запуска тестов и проверки типов не указаны.