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>
130 lines
11 KiB
Markdown
130 lines
11 KiB
Markdown
# Задание 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`.
|