- миграция checks: nullable input_tokens/output_tokens/total_tokens/usage_json
(идемпотентно, старые строки остаются NULL; probe мигрирует сам — cron стартует раньше uvicorn)
- probe.py и /api/check фиксируют usage ДО валидации контента: токены
сохраняются при пустом/сломанном ответе; таймауты и ответы без usage = NULL, не нули
- usage_json хранит сырой usage провайдера (OpenAI/Anthropic/camelCase форматы)
- /api/checks и сегментная история несут токены; новый /api/token_stats:
rolling 24h + all time, покрытие known/unknown, разбивка по провайдерам
(провайдер из models с fallback на префикс model_id)
- UI: статы «Токены 24h» и «Покрытие usage» в шапке, токены в тултипах
сегментов и логе проверок
- статика через __file__-относительный путь (работает и в /app/app, и локально)
- тесты (30, реальные HTTP против мока OmniRoute): миграция/идемпотентность,
NULL при missing/zero usage, usage при упавшем контенте, таймаут, агрегаты,
оба пути записи (probe.run + /api/check)
Кнопка 📋 Лог открывает /api/checks/{model_id} — все проверки модели
за период (по умолчанию 100 последних, limit через CHECKS_LIMIT) с
ok/latency_ms/checked_at/error. Заполняет history для перерисовки.
Сегмент при наведении показывает тултип: успех/провал, время
проверки, латентность и текст ошибки.
Бэкенд: в таблицу checks добавлена колонка error (миграция через
ALTER TABLE), probe.py и ручной /api/check теперь сохраняют текст
ошибки, /api/models отдаёт детали каждой проверки в history.
Каждая сегментная полоска — одна проверка модели за последние 24ч
(зелёная = успех, красная = провал), слева старее, справа свежее.
Бэкенд отдаёт историю проверок в /api/models и обновляет её
после ручного теста.