0.167.8

Fixed

  • Compaction в карточке агента выводился сырым JSON вместо читаемых данных. В раскрывающемся аккордеоне «Детали» на страницах /agents, /dashboard, /settings/agents поле Compaction показывалось как нечитаемая JSON-строка, обрезанная до 200 символов ({"enabled":true,"trigger_tokens":90000,"target_tokens":50000}). Причина: колонка compaction_config (миграция 036) хранит произвольный JSON-объект без нормализации схемы — бэкенд (internal/server/handler/agent.go:174 validateSubconfigObject) валидирует лишь, что это объект, но не схему. Поэтому в данных пользователей сосуществуют два формата порогов: абсолютные (trigger_tokens/target_tokens, старый формат) и относительные (soft_threshold_pct/hard_threshold_pct как доля 0..1, текущая Go-структура CompactConfig). Компонент AgentCard.svelte формировал строку через JSON.stringify и выводил её моноширинным шрифтом. Фикс (только фронтенд): вынесенная утилита web/src/lib/utils/compactionSummary.ts разбирает обе схемы и формирует человекочитаемую сводку в одну строку: абсолютные пороги → вкл · триггер 90.0K → цель 50.0K ток.; относительные → вкл · soft 70% · hard 85%; enabled:falseвыкл; общие параметры keep_last_messages/max_passes/protect_first_n добавляются при наличии. Робастность: пустой конфиг/{}/битый JSON/массив/null → строка не выводится; нераспознанная схема → fallback «k: v» (вложенные объекты сериализуются через JSON, чтобы избежать [object Object]); enabled:false + неизвестные поля не теряются. Поле Agent.compaction_config в web/src/lib/api/types.ts типизировано новым интерфейсом CompactionConfig (объединение обеих схем). Unit-тесты: 26 кейсов (compactionSummary.test.ts) — обе схемы, доп. параметры, пустые/невалидные значения, fallback, вложенные объекты, undefined. Убран font-mono break-all. Бэкенд не менялся (нормализация схемы — отдельная задача уровня B). Проверки: npm run check — 0 ошибок; npm test — 603/603 passed; go vet — 0; golangci-lint — 0 по проектному коду; ocr review — medium-bug (вывод [object Object]) + low (потеря данных при enabled:false) устранены, остался 1 low неактуальный (строгий === false — бэкенд Go bool всегда шлёт настоящий boolean).