0.167.44
Added
- Конфигурируемые пороги anti-loop детектора через settings ( — P3, аудит 2026-08-context). Пороги warn/stop (подавление повторного идентичного tool-вызова / завершение хода
loop_detected) перестали быть hardcoded 3/5: новые параметрыagent_loop_warn_threshold(default 3, min 2, max 49) иagent_loop_stop_threshold(default 5, min 3, max 50) в группе «Агент» (Settings → Advanced; UI рендерит их автоматически из ParamRegistry). Прокидывание:AgentRunner.Runчитает пороги один раз на ход из Store (по образцуtool_timeout_seconds); тексты[anti-loop]-сообщений несут актуальный порог. Валидация: per-key границы реестром + связная параstop > warnвAdvancedHandler.Update(validateLoopThresholdPair: резолв эффективной пары req → Store → дефолт, ошибка показывает источник каждого значения; сбой чтения БД/порча сохранённого значения → 500settings backend error, отмена клиента — тихий выход). Max warn = 49 (< Max stop): граничное значение warn всегда дополнимо валидным stop. Defense-in-depth вnewToolLoopDetector: per-key bump ниже min, pair-сброс к дефолтам приstop <= warn, сброс при выходе за Max — классифицированная причина в логе; пороги —atomic.Int32(lock-free чтение из parallel-ветки). ПопутноUpdateстал двухфазным: ВСЕ ключи валидируются до первой записи — невалидный ключ не оставляет частично применённый апдейт. Синхронизация констант agent-пакета с реестром — тестом (TestLoopThresholdConstantsSyncWithRegistry): ключи зарегистрированы, Min/Max/default совпадают,warnMax < stopMax. Тесты (+11): кастомные пороги 2/3 на пути Run, пороги из Store, дефолты при отсутствии, невалидная пара в Store → нормализация, нормализация всех невалидных комбинаций (таблица), pair-валидация (валидная/равная/односторонняя/per-key границы/регистрация), нечисловое значение → точная ошибка типа, двухфазность без частичных записей, сбой чтения Store → 500.
Changed
store.GetSetting(SQLite/PostgreSQL) теперь возвращает sentinelErrSettingNotFound(обёрнут через%w) вместо строковой ошибки — вызывающие могут различать «нет записи» и сбой чтения черезerrors.Is.