hermes-hub/agents/inbox/2026-08-23-A18-antigravity-flash-model-choice.md
Hermes Team 18695a3f6e docs(tasks): A17, A18, A19 — честный статус, выбор модели, два установщика
A17 (Pro): «Работает» — ветка else в определении здоровья, она означает
«мы не знаем о проблемах», а подана как утверждение. Отказы попадают в
статус только после боевого сбоя, поэтому непроверенный профиль
автоматически зелёный. Плюс «Проверить подключение» не вызывает модель
вовсе — Grok её проходит и не работает.

A18 (Flash): действия смены модели не существует ни среди семнадцати, ни
в клиенте; десктоп это умеет, но логика заперта в методе интерфейса.
И выбирать не из чего: кэш моделей пуст по всем провайдерам, потому что
agy models нестабильна — в одном прогоне 40 секунд, в следующем висит
больше двух минут.

A19: два установщика. Windows — ярлык, открывающий веб окном приложения
через --app без адресной строки (проверено на машине владельца: Edge и
Chrome есть, окно открывается). Linux — скрипт установки, .desktop и
удаление с сохранением данных, плюс честная подсказка про проброс порта
при пустом DISPLAY.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-23 21:57:11 +07:00

130 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Задание A18 (Antigravity Flash): выбор модели и надёжное обнаружение
## Дата поступления
2026-08-23
## База
Проверочный HEAD на момент выдачи: **`fb23bff`**.
## Ветка
`antigravity/model-choice`
---
## Порядок работы с git
```
cd <каталог репозитория>; git fetch origin --prune; git status
git checkout main; git pull --ff-only origin main
git checkout -b antigravity/model-choice
git commit -m "..." <- сначала коммит
git push -u origin antigravity/model-choice
```
В конце — push и проверка:
```
git status
git log --oneline -1 origin/antigravity/model-choice
```
---
## Что принято по A16
**Лучшая работа за все раунды.** Веб-клиент собран без сборки, экран «Аккаунты» показывает 22 из 22 аккаунтов с квотами, указанием пула и периода, временем сброса. Неподключённые честно помечены. Внизу индикатор источника данных — интерфейс сам сообщает, живые данные он показывает или фикстуру. Все восемь скриншотов содержательные, пустых нет. Границу зоны соблюли.
Три вещи доделал ревьюер, знать полезно:
1. **Сервер не отдавал статику вообще** — в браузере был 404. Обе стороны выполнили контракт, но он не назвал, кто монтирует `static/`. Это пропуск автора контракта, не ваш; исправлено, контракт поднят до 1.1.
2. **Квоты не подтягивались**: кэш никто не грел, а `HubStateStore.get_snapshot()` возвращает кэшированный снапшот и пересобирает его только при первом вызове. Добавлен фоновый цикл.
3. **Загрузка выглядела как отсутствие данных.** Сервер отдавал `is_loading`, клиент его игнорировал и рисовал «Н/Д» — тот же текст, что у аккаунта без лимитов. Владелец увидел это и решил, что лимиты не работают. Теперь показывается «Загрузка…».
---
## P0-1. Смены модели не существует
Владелец: **«не дает поменять модель. хочу выбрать 2 кодера гемини про, а не дает»**.
Проверено: **действия смены модели нет ни среди семнадцати, ни в веб-клиенте.** Десктоп это умеет — `_open_agent_settings_modal._save_agent` пишет `profile.preferred_models` и вызывает `save_router_config`, — но логика заперта внутри метода интерфейса и наружу не вынесена.
**Требуется:**
1. **Действие `set_model`** в `action_handler.ActionExecutor` — там, где живут остальные. Принимает профиль (или роль) и идентификатор модели, ставит её первой в `preferred_models`, сохраняет конфигурацию.
2. **Отказ, если модели нет у провайдера.** Не подставлять «похожую», не сохранять молча. У владельца в конфигурации уже стоит `gemini-3.7-flash`, которой у провайдера **не существует**, — она попала туда именно так, через литерал в коде.
3. **Выбор в веб-клиенте**: на карточке роли и в окне деталей аккаунта. После сохранения новая модель видна без перезагрузки страницы.
4. Добавить `set_model` в `docs/web-api/CONTRACT.md` — список действий там перечислен поимённо, и клиент пишется против него.
Десктопную модалку не ломать: она должна вызывать то же действие, а не свою копию. Второй реализации в проекте быть не должно — ради этого действия и выносили в общий слой.
**Тест:** смена модели сохраняется в конфигурацию и переживает перезапуск; несуществующая модель отклоняется с внятной причиной.
## P0-2. Обнаружение моделей не даёт ничего
Даже когда выбор появится, он будет пустым. Проверено:
```
antigravity моделей в кэше: 0
opencode-go моделей в кэше: 0
grok моделей в кэше: 0
файла models_cache.json на диске нет
```
Причина не в вашем коде: зонд вызывает `agy models`, а эта команда нестабильна. Замерено на живой машине — **в одном прогоне отвечает за 40 секунд, в следующем висит больше двух минут и убивается по таймауту** (`rc=124`). Причём виснет она и при прямом вызове из консоли, без всякого Hub.
Когда она отвечает, список настоящий и там есть то, что просит владелец:
```
gemini-3.7-flash-high / -medium / -low
gemini-3.6-flash-high / -medium / -low
gemini-3.5-flash-high / -medium / -low
gemini-3.1-pro-high / -low <- «Gemini Pro», которого он хочет
claude-sonnet-4-6, claude-opus-4-6-thinking, gpt-oss-120b-medium
```
**Требуется сделать обнаружение полезным вопреки нестабильности CLI:**
- результат **сохраняется на диск** и переживает перезапуск. Один удачный опрос за сутки должен закрывать вопрос;
- обновление в фоне, с таймаутом; срабатывание таймаута **не затирает прежний кэш**;
- **ручная кнопка «Обновить список моделей»** — владелец должен иметь возможность попробовать ещё раз, а не ждать интервала;
- при пустом кэше интерфейс говорит «список моделей ещё не получен» и предлагает обновить. Литеральный список **не подставлять** ни при каких условиях;
- в отчёте написать, сколько попыток из десяти `agy models` завершились успешно на вашей машине. Это цифра, которая определит, годен ли зонд вообще.
Если окажется, что команда безнадёжна — предложить альтернативу и обосновать: разбор конфигурации `agy`, отдельный эндпоинт, ручной ввод модели владельцем. Молча оставлять пустой список нельзя, это второе задание подряд с этим пунктом.
**Тест:** кэш переживает перезапуск; таймаут не затирает прежние данные; пустой кэш даёт понятное сообщение, а не пустой выпадающий список.
## P1-3. Проверить остальные экраны на данных
Экран «Команда агентов» на скриншоте владельца показывает роли `research` и `fast` с профилем `opengo-1` и моделью `deepseek-r1`. Убедиться, что после появления выбора модель на этом экране меняется вместе с конфигурацией, а не остаётся прежней до перезапуска.
---
## Ограничения
- Параллельно идут **A17** (честный статус) и **A19** (установщики). Ваши файлы: `router/web/static/**`, `model_discovery.py`, `model_discovery_service.py`, `router/ui/**`, `tests/test_ui_*.py`, `tests/test_web_client_*.py`. По `action_handler.py`**только добавление `set_model`**, остального там не касаться: A17 работает в этом же файле.
- Контракт правьте в части списка действий, остальное — зона A17. Скажите в отчёте, что изменили.
- Не выдумывать названия моделей. Нет обнаруженного списка — пустой список и объяснение.
- Тег `v0.1.1` не создавать.
## Критерии приёмки
1. Ветка в `origin`, `git status` чист.
2. Действие `set_model` живёт в `action_handler`; десктоп и веб вызывают его, второй реализации нет.
3. Модель меняется из веб-интерфейса, сохраняется и переживает перезапуск; проверено тестом.
4. Несуществующая модель отклоняется с внятной причиной; проверено тестом.
5. Кэш моделей сохраняется на диск и переживает перезапуск; таймаут не затирает прежние данные.
6. Есть ручное обновление списка моделей.
7. Пустой кэш даёт объяснение, а не пустой список; литералов нет.
8. В отчёте: сколько попыток из десяти `agy models` завершились успехом.
9. `set_model` добавлено в контракт.
10. Прогон в обоих окружениях; `ruff check .` чисто; гейт не ухудшен.
11. **Скриншот смены модели с настоящими данными**: до, выбор, после.
12. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`. На `main` сейчас 331 passed.
## Главное
Владелец хочет поставить двум кодерам Gemini Pro. Сейчас это невозможно тремя способами сразу: действия нет, элемента управления нет, списка моделей нет. Задание закрывает все три.
## Порядок сдачи
Передать точный `FINAL_COMMIT_SHA`. Сдано только после появления коммита в `origin`.