0.158.0
Added
- Контекст LLM: обрезка tool_call внутри хода и устойчивость к таймауту (ADR
docs/adr/2026-07-02-llm-context-toolcall-trim.md, ). При расследовании «амнезии» агента #2 (Семён) вскрыты пять связанных дефектов: внутри хода нет обрезки tool-результатов (вербаим растёт → 40-мин таймаут),budgetTokensпроигнорирован, между ходами tool-работа исчезает, таймаут не оставляет следа в БД,history_windowвытесняетсяtool_call_history. Сравнение с goclaw/zeroclaw показало, что обе режут tool-результаты каждую итерацию, а zeroclaw схлопывает группы tool-вызовов. - #245: внутри-ходовая обрезка по бюджету.
trimInLoopMessages(runner.go) перед каждымtoProviderMessages: приEstimateTokens > ContextMaxTokens×0.70→FastTrimToolResults.budgetTokensреализован (раньше_ = budgetTokens),ToolResultTrimToTokens200→1500 (≈ goclaw 6000 chars).ToolResultKeepRecentнастраиваем через settingtool_result_keep_recent.toolBudgetclamр кToolResultPruneTokens(чтобы для 200k-контекстов не размывать обрезку). - #246: схлопывание групп tool-вызовов (паттерн zeroclaw
prune_historyPhase 1).collapseToolGroups: старую группуassistant(tool_calls)+tool*Nзаменяет одним assistant-маркером[Ранее: N вызов <tool> — результаты сжаты]. Атомарность: если любой tool в keepRecent — группа пропускается. Phase 2 вtrimInLoopMessages(если после обрезки переполнение сохраняется). - #247: persist прерванного по таймауту хода.
persistTurnTimeout(actor.go): приDeadlineExceededпишет assistant-сообщение в чат («Превышено время ответа… Ход прерван») + WIP-ноту в scratchpad (wip_turn, частичный ответ агента, TTL 24h). Раньше — только эфемерное websocket-уведомление → полная амнезия.cleanupStaleWIPудаляет устаревший WIP после успешного хода. - #248: фильтр ролей в SQL для history_window. Новый метод
GetRecentDialogMessages(SQLite+PG+DualStore):role IN ('user','assistant','system','tool','memory_context'). Окно гарантированно = 50 диалоговых сообщений, а не 50 случайных строк (один ход генерит сотниtool_call_history, вытеснявших диалог). Побочный выигрыш:resolveSummaryначинает срабатывать → cross-turn dialog-summary. - #249: compact-след tool-работы между ходами.
persistToolTraceпосле успешного хода с tool-вызовами пишетrole=memory_context(tool_name=tool_trace) с маркером «использованы инструменты: exec ×12, grep ×3…». Лимит 20 записей, свежий context.enforceMemoryContextBudgetограничивает накопление в промте. Осведомлённость агента о проделанной работе, чтобы не переделывать её. - Проверки:
go test ./internal/...— 30+ новых/обновлённых тестов (обрезка, collapse, таймаут, dialog-messages, tool-trace, wip-cleanup); циклocr review— валидные замечания устранены (wip cleanup, tool trace limit+ctx, toolBudget clamр, test coverage), невалидные отклонены (DRY-стилистика; performance-оптимизация EvaluateTokens — отдельная задача; benign race — по признанию самого ocr).