Commit graph

13 commits

Author SHA1 Message Date
Hermes Team
4545fbead2 Merge antigravity/web-parity (A21) — принято
Четыре недостающих экрана добавлены: Аналитика, Состояние, Журнал
событий, Настройки. Веб покрывает все девять разделов десктопа.

Два новых эндпоинта реализованы: GET /api/events и GET /api/settings.
Секреты не утекают — проверено исполнением, наружу отдаётся только
признак web_api_token_configured (bool), сам токен отсутствует.

Слияние без конфликтов. Тесты: 359 passed, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 01:08:26 +07:00
Hermes Team
da962c7866 Merge antigravity/agy-native-login (A22) — принято, работает
Проверено исполнением, все три требуемых доказательства получены.

1. agy models через профиль Hub: обнаружено 14 моделей, включая
   gemini-3.1-pro-high и gemini-3.1-pro-low.
2. Реальный вызов adapter.invoke(ag-w1): модель ответила «ОК».
3. route_request(coder-primary): переключение с отказавшего
   codex-worker-1 на ag-w1, ответ получен, router_error отсутствует.

Подход из A20 (синтез oauth_creds.json) действительно был тупиковым;
родной вход agy с подменой HOME решает задачу. Реализация аккуратная:
видимая консоль на Windows через CREATE_NEW_CONSOLE, терминалы на Linux,
HOMEDRIVE выставляется корректно.

P0-4 подтверждён: пересохранение профиля не изменяет ни одного файла в
глобальном ~/.gemini.

Исправлено при слиянии:

1. Инструкция в веб-клиенте вела на НЕСУЩЕСТВУЮЩИЙ файл
   launcher/main.py. Заменена на реальный вызов launch_native_agy_login
   с указанием профиля.
2. test_headless_server_auth_matrix проверял дословную формулировку и
   падал при её правке, хотя поведение оставалось верным. Приведён к
   проверке сути, добавлена защита от возврата несуществующего пути.

Конфигурация владельца: обоим кодерам поставлена gemini-3.1-pro-high по
его прямой просьбе — теперь это возможно.

Тесты: 355 passed, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 01:06:24 +07:00
Hermes Team
755c2dce21 fix(web): clarify headless restrictions for native agy login (A22) 2026-08-24 00:52:44 +07:00
Hermes Team
c9c9586bff fix(web): исправить некорректное отображение подписи 'Н/Д' для токенов и улучшить regex санитаризации 2026-08-23 23:12:46 +07:00
Hermes Team
e738dd0c5d feat(web): A21 — паритет веб-интерфейса: аналитика, состояние, события, настройки 2026-08-23 22:59:02 +07:00
Hermes Team
05cf17503d feat(router): A18 — выбор модели, действие set_model, персистентный кэш и выбор в веб-клиенте 2026-08-23 22:08:08 +07:00
Hermes Team
04e5d0dcf5 fix(web): загрузка квот больше не выглядит как отсутствие данных
Владелец запустил веб, увидел «Н/Д» у всех аккаунтов и сообщил, что
лимиты не подтягиваются. Через пятнадцать секунд всё появилось: опрос
провайдера просто ещё шёл.

Признак is_loading сервер отдавал (баз�овый снапшот выставляет его при
незавершённом опросе), но клиент его игнорировал и рисовал «Н/Д» — тот
же текст, что у подключённого аккаунта без лимитов. Два разных состояния
выглядели одинаково, и различить их было нельзя.

Теперь во время опроса ячейка показывает «Загрузка…» и «Опрашиваем
провайдера…» вместо прочерка.

Причина отказа важнее флага: если провайдер уже ответил «лимитов не
даю», состояние загрузки подавляется — иначе opencode-go и grok
показывали бы «Загрузка…» бесконечно.

Закреплено тестом в test_web_client_contract.py, включая проверку этого
подавления.

Тесты: 328 passed, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 21:38:31 +07:00
Hermes Team
c75b4e42ac fix(web): квоты не подтягивались — прогрев кэша и пересбор снапшота
/api/snapshot отдавал квоты с source="baseline" и нулём измеренных
корзин всегда. Две независимые причины, и лечение одной из них ничего
не давало.

1. state_store наполняет квоты через quota_service.get_snapshot, который
   читает кэш и при промахе отдаёт пустую заглушку, живой опрос НЕ
   запуская. Кэш никто не грел: в десктопе это делал
   _refresh_quotas_on_startup, в вебе аналога не было. Штатный
   планировщик службы не спасает — его цикл сначала спит интервал
   (300 с по умолчанию) и только потом опрашивает.

2. HubStateStore.get_snapshot() возвращает КЭШИРОВАННЫЙ снапшот и
   пересобирает его только при первом вызове. Даже после прогрева квот
   ответ оставался прежним. В десктопе пересбор делал _refresh_data.

Добавлен фоновый цикл: прогрев квот при старте, затем пересбор снапшота
каждые 30 секунд. Порядок важен — снапшот, собранный до прогрева,
зафиксировал бы пустые корзины.

Проверено исполнением: квоты появляются через ~10 секунд после старта,
24 измеренных корзины, source=provider_api, ag-w2 Gemini неделя 80.5% —
совпадает с прямым опросом провайдера.

Регрессия закрыта tests/test_web_snapshot_freshness.py, включая проверку
порядка «прогрев перед пересбором».

Тесты: 327 passed, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 21:32:26 +07:00
Hermes Team
8da7c48bb8 fix(web): сервер отдаёт интерфейс, а не только API
A15 и A16 сошлись в пустоту: API отвечал, файлы клиента лежали в
репозитории, но server.py не монтировал static — в браузере был 404 и до
интерфейса было не добраться.

Причина организационная и она на ревьюере: контракт описал каталог
static/ в структуре пакета, но в разделе об эндпоинтах не назвал, кто его
отдаёт. Обе стороны выполнили написанное и всё равно не собрались.

Подключены StaticFiles и корневой маршрут. Проверено исполнением:
/ -> 200 (13.5 КБ), /app.js -> 200 (51 КБ), /style.css -> 200 (21 КБ),
/api/health -> 200, /api/snapshot -> 200 (98 КБ).

Тесты: 325 passed, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 20:40:38 +07:00
Hermes Team
5b06db1ca0 Merge remote-tracking branch 'origin/antigravity/web-client' into review/web 2026-08-23 20:38:14 +07:00
Hermes Team
eaae2f8ac4 fix(A15): восстановить десктоп и починить веб-API
Правки при приёмке A15. Веб-API и вынесение действий приняты, но
в сданном виде не работали ни то, ни другое.

1. Десктоп был уничтожен. При выносе действий из hermes_hub_app.py
   пропало объявление class HermesHubApp вместе с 13 методами каркаса:
   __init__, _build_layout, _create_view, _show_view, _refresh_data и
   другими. Оставшиеся 14 методов оказались вложены внутрь функции
   _load_saved_theme после её return — синтаксически валидный
   недостижимый код, поэтому модуль импортировался и дефект выглядел
   безобидно. launch_hub() при этом падал бы с NameError.
   hermes_hub_app.py восстановлен из main; задание прямо требовало
   десктоп не ломать.

2. Дублирование убрано правильным способом: десктоп импортирует пять
   do_* из action_handler, второй реализации в проекте нет.

3. Веб-API падал с 500 на обоих значимых эндпоинтах: get_auth_token и
   run_server читали config.hub, а такого атрибута у RouterConfig нет.
   Настройки живут в hub_settings.json. Работал только /api/health, у
   которого нет проверки авторизации, — из-за чего сервер и выглядел
   поднявшимся.

4. do_save_settings при переносе потеряла атомарную запись через
   os.replace, ensure_ascii=False и вызов set_refresh_interval, то есть
   интервал обновления квот из настроек перестал применяться.
   Восстановлено.

5. Импорт адаптера был убран внутрь do_test_profile, что делало функцию
   неподменяемой в тестах. Поднят на уровень модуля.

6. Версия в /api/health была зашита как "1.0.0" вместо настоящей.

Проверено исполнением: /api/snapshot отдаёт 200 и 12 ключей, полностью
совпадающих с docs/web-api/snapshot.example.json; секретов в ответе нет;
неизвестное действие даёт 404. Тесты: 319 passed, ruff чисто.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 19:54:29 +07:00
Hermes Team
e42f262b6d feat(A15): веб-API, общий ActionExecutor и порт путей на Linux
Работа A15 выполнена, но не закоммичена: git в его окружении был
недоступен. Восстановлена ревьюером из рабочего каталога.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 19:45:13 +07:00
Hermes Team
d9d6e08d32 feat(web): A16 — веб-клиент без сборки, компактные аккаунты, живые квоты, честная авторизация и скриншоты экранов 2026-08-23 19:37:36 +07:00