diff --git a/agents/inbox/2026-08-23-A10-antigravity-all-remaining.md b/agents/inbox/2026-08-23-A10-antigravity-all-remaining.md deleted file mode 100644 index 03e62b5..0000000 --- a/agents/inbox/2026-08-23-A10-antigravity-all-remaining.md +++ /dev/null @@ -1,178 +0,0 @@ -# Задание A10 (Antigravity): всё оставшееся — backend и интерфейс - -## Дата поступления -2026-08-23 - -## База -Проверочный HEAD на момент выдачи: **`0165434`**. Обязательно обновить локальную копию — см. следующий раздел. - -## Ветка -`antigravity/all-remaining` - ---- - -## Главное изменение: границы зон больше нет - -У Codex закончились лимиты. **Вся работа переходит к вам, включая интерфейс.** Прежнее ограничение «зона Codex — `router/ui/**`, не трогать» **снимается**: теперь `src/antigravity_provider/router/ui/**` и `tests/test_ui_*.py` ваши. - -Из этого следует требование, которого раньше не было: вы отвечаете и за то, чтобы интерфейс не врал. Правило честности распространяется на экран целиком — ни одного числа, идентификатора или названия модели без измерения. - ---- - -## Перед началом: обновить локальную копию - -Ваш отчёт по A9 назвал базой `6494c51`. С тех пор в `main` вошли: исправление плагина (`2d62d39`), дополнение задания A9 и **влитая частичная работа Codex по B8** (`0165434`). - -``` -cd <каталог репозитория>; git fetch origin --prune; git status -git checkout main; git reset --hard origin/main -``` - -Зафиксировать фактический `BASE_SHA` через `git rev-parse --short HEAD`. - ---- - -## О статусе A9 - -Отчёт по A9 получен и прочитан. **Ни одной строки этой работы в репозитории нет.** Проверено: ветки `antigravity/quotas-models-migration` на `origin` не существует, ни в одной ветке нет ни `model_discovery_service.py`, ни `test_a9_migration_quotas_models.py`, ни миграции в `router_config.py`. - -Работа осталась на вашей машине. Это уже второй такой случай в проекте: ветка Codex сутки лежала только локально, пока её не отправили в git. - -**Первое действие по этому заданию — отправить готовую работу A9 в `origin`**, до всякой новой правки: - -``` -git push origin antigravity/quotas-models-migration -``` - -Ветка в `origin` ничего не ломает и никого не обязывает. Несохранённая работа теряется вместе с диском. - -Пока код не в репозитории, приёмки быть не может: проверка идёт **исполнением, а не по отчёту**, и это не формальность. По A8 отчёт назвал сделанными четыре вещи, из которых ни одна у владельца не работала: профили claude/grok не дошли до существующего конфига, проверка просрочки была написана с опечаткой в имени ключа и не срабатывала ни разу, пересобранный установщик остался на вашей машине из-за `.gitignore`, флаг `/reinstall` не использовался в коде вообще. - -Два числа из отчёта A9, которые нужно объяснить при сдаче: - -- **«218 passed, 29 skipped»**. На `main` в venv Hermes набор даёт **290 passed, 2 skipped**. Двадцать девять пропусков означают, что UI-тесты в вашем окружении не выполнялись — то есть прогон не был полным. Требуется прогон в окружении **с** `customtkinter`, `pillow`, `psutil`. -- **«Release Gate 7/7 PASSED»**. Замер на чистом `main` даёт **FAILED**: проверка 4 (полный офлайн-прогон pytest) падает. Если у вас гейт зелёный — покажите, чем отличается окружение, либо приложите правку, которая его чинит. - ---- - -## P0-1. Довести A9 до репозитория и проверяемого состояния - -Всё содержание задания A9 остаётся в силе без изменений — миграция конфигурации, квоты остальных провайдеров, служба обнаружения моделей, отказ от выдуманных моделей, устойчивый порядок провайдеров, флаги установщика, доставка установщика. Читайте A9 как часть этого задания. - -Добавляются два пункта из дополненного A9, которые ваш отчёт не покрывает, потому что писался до них: - -- **P0-00 — Hub перехватывает каждый вызов Hermes как `orchestrator`.** Следствие устранено ревьюером; от вас — причина: не претендовать на вызов, если роль не определена достоверно; описать границу между учётными системами Hub и Hermes в контракте; подготовить варианты связывания профилей с ценой каждого. -- **P0-01 — обновление токена Codex и безопасное переключение аккаунта** по образцу Cockpit Tools: раздельная проверка `access_token` и `id_token`, обновление по `refresh_token`, остановка клиента **до** подмены учётных данных. - -## P0-2. Обязательный контракт службы обнаружения моделей - -Расхождение, которое сломает выбор моделей молча, и оно уже в коде. - -Codex в `ui/model_catalog.py` импортирует: - -```python -from antigravity_provider.router.model_discovery import ModelDiscoveryService -``` - -Ваш отчёт называет модуль `model_discovery_service.py`. Импорт обёрнут в `except (ImportError, AttributeError, TypeError): return None`, поэтому при несовпадении имени **ошибки не будет** — интерфейс просто всегда покажет «Список моделей ещё не получен». - -Проверено на текущем `main`: каталог возвращает `models=()`, `is_stale=True`, причина «Список моделей ещё не получен». Выбор модели подключён и пуст. - -**Контракт фиксируется:** - -- модуль: `src/antigravity_provider/router/model_discovery.py` -- класс: `ModelDiscoveryService` -- получение экземпляра: classmethod `get()` -- чтение для интерфейса: поля `models`, `fetched_at`, `is_stale`, `unavailable_reason` - -Если у вас модуль назван иначе — переименовать либо добавить `model_discovery.py` точкой входа. - -**Тест обязателен, и он должен падать при несовпадении пути.** Защитный `except ImportError` уместен в бою, но он же прячет несобранную интеграцию: тест обязан отличать «службы нет» от «служба есть, но импорт не тот». - -## P0-3. Компактные карточки аккаунтов - -Codex до этого не дошёл — `accounts_view.py` не менялся. - -Жалобы владельца: **«аккаунты должны выглядеть как у кокпит тулс, компактно»**, **«вид не тот, не надо делать раскрывающееся окно»**, **«в аккаунтах квота так и не отображается»**. - -Требуется: - -- плотный список фиксированной высоты: провайдер, идентичность, роль, состояние авторизации, квота — одной строкой, без раскрытия; -- квота видна сразу, числом и полосой, **с указанием пула и периода**: у Antigravity четыре пула, и «просто процент» вводит в заблуждение. Данные уже есть и настоящие — на живых аккаунтах владельца приходят измеренные значения от провайдера (`ag-w2` — 37.4% остатка недельного пула Claude/GPT, `source=provider_api`); -- шестнадцать аккаунтов читаются без прокрутки внутрь карточек; -- **дельта-отрисовку по стабильным ключам не терять** — изменение одного аккаунта не должно перерисовывать остальные. Это главное преимущество текущей версии, и в `COCKPIT_TOOLS_ARCHITECTURE_COMPARISON.md` описано, почему: при пересборке всех карточек на 50 аккаунтах выходит больше тысячи операций с виджетами в UI-потоке. - -Документ в корне репозитория — архитектурное сравнение, а не макет. Берите из него принцип обновления и плотность, не буквальную вёрстку. - -## P0-4. Разобрать дублирующие разделы - -Codex до этого не дошёл — `quotas_view.py` не менялся. - -Жалоба: **«провайдеры и квоты и лимиты вообще не понятно для чего нужны, там всё то же, что и в аккаунты»**. - -Владелец прав: после появления квот в карточках аккаунтов отдельный раздел квот потерял смысл. Нужно решение, а не сохранение обоих на всякий случай. - -- **«Квоты и лимиты»** — убрать из навигации либо оставить только то, чего нет в «Аккаунтах»: сводка по провайдеру целиком, история расхода, ближайшие сбросы. -- **«Провайдеры»** — оставить относящееся к провайдеру, а не к аккаунту: доступность runtime, обнаруженные модели, версия CLI, состояние авторизации в целом. - -В отчёте перечислить перенесённое и удалённое. Пустой раздел не оставлять. - -## P0-5. Причина у каждого Н/Д - -Жалоба: **«что означает н/д в маршрутизация запросов»**. - -Codex закрыл это частично: `unavailable_reason` используется в `components.py` и на «Обзоре», но не везде. - -Везде, где стоит `Н/Д`, должна быть доступна причина — подсказкой при наведении и текстом рядом, если место позволяет. Формулировки конкретные: «нет телеметрии: роль ещё не вызывалась», «провайдер не отдаёт лимиты», «аккаунт не подключён». Данные для этого есть. - -## P1-6. Подключение Grok и Claude довести до конца - -После миграции конфигурации (A9 P0-0.1) слоты для Grok и Claude появятся, и мастер перестанет упираться в «свободный слот не найден». Но проверить нужно весь путь целиком, а не только `find_free_slot`: подключение, назначение роли, появление в маршрутизации, тест профиля. - -Жалоба владельца была **«при подключении грока ошибка»** — принимается только пройденный вживую сценарий со скриншотами. - ---- - -## Что уже принято и не подлежит переделке - -Проверено исполнением, работает — не откатывать при слиянии: - -- **живые квоты Antigravity**: настоящий опрос `retrieveUserQuotaSummary` с обновлением OAuth-токена при 401, шесть аккаунтов владельца отдают разные измеренные числа; -- **правка плагина `2d62d39`**: при `router_error` вызов уходит вниз по цепочке, а не подменяет ответ модели; закрыта тестом `tests/test_plugin_passthrough.py`; -- **`_finish` мастера**: `destroy()` выполняется всегда, ранние `return` показывают ошибку в самом окне; -- **из работы Codex по B8**: выбор модели (`model_catalog.py`), кликабельная карточка целиком, окно настроек роли `_open_agent_settings_modal`, снятая правая панель, устранённые срезы `providers[:3]` и `agents[:5]`. - ---- - -## Ограничения - -- Границы зон нет — весь репозиторий ваш. Ответственность за честность интерфейса теперь тоже ваша. -- Не выдумывать числа, идентификаторы и названия моделей. Нет данных — `None` в модели, `Н/Д` с причиной на экране. -- Три темы сохранить, дельта-отрисовку не терять. -- Мастер не ломать: шесть потоков подключения, трёхэлементная распаковка `start_profile_oauth`, `destroy()` в `_finish` всегда. -- Сеть и подпроцессы — не в UI-потоке. Замерено: `agy models` в одном прогоне отвечает за 40 секунд, в следующем висит больше двух минут. -- Тег `v0.1.1` не создавать. -- **Ветку пушить сразу после первого коммита.** - -## Критерии приёмки - -1. Работа A9 находится в `origin` и проверяема исполнением. -2. Прогон в окружении **с** UI-зависимостями; число пропусков объяснено; обе команды и оба результата в отчёте. -3. Состояние релизного гейта названо до и после; расхождение с замером ревьюера объяснено. -4. Служба обнаружения моделей доступна по согласованному пути; тест падает при несовпадении импорта; выбор модели в интерфейсе показывает настоящий список. -5. Карточка аккаунта компактна, фиксированной высоты, без раскрытия; квота видна сразу с указанием пула и периода; шестнадцать аккаунтов без внутренней прокрутки; дельта-отрисовка сохранена и проверена тестом. -6. Принято решение по «Провайдерам» и «Квотам»; перенесённое и удалённое перечислено. -7. У каждого `Н/Д` доступна причина. -8. Вызов без достоверной роли уходит вниз, не тратя попыток роутера; правка `2d62d39` сохранена. -9. Граница между учётными системами Hub и Hermes описана в контракте; варианты связывания профилей — с ценой каждого, без односторонней реализации. -10. Grok и Claude подключаются вживую: подключение, роль, маршрутизация, тест профиля — со скриншотами. -11. `ruff check .` чисто. -12. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`. -13. **Скриншоты живого сценария с настоящими данными.** Пустых состояний не присылать. - -## Главное - -Владелец сказал: «надо чтобы хаб уже заработал». Ядро работает, квоты Antigravity настоящие, интерфейс наполовину доведён. Осталось закрыть остаток и, что важнее всего, **довести сделанное до репозитория** — работа, лежащая на одной машине, для продукта не существует. - -## Порядок сдачи -Передать точный `FINAL_COMMIT_SHA`. diff --git a/agents/inbox/2026-08-23-A11-antigravity-pro-integration.md b/agents/inbox/2026-08-23-A11-antigravity-pro-integration.md new file mode 100644 index 0000000..911d4f4 --- /dev/null +++ b/agents/inbox/2026-08-23-A11-antigravity-pro-integration.md @@ -0,0 +1,252 @@ +# Задание A11 (Antigravity Pro, этот ПК): интеграция с Hermes и учётные данные + +## Дата поступления +2026-08-23 + +## База +Проверочный HEAD на момент выдачи: **`cdfd9f1`**. + +## Ветка +`antigravity/hermes-integration` + +## Кому +Тяжёлая ветка работ: разбор чужого кода, обратная разработка эндпоинтов, проектные решения. Механических правок здесь нет. + +--- + +## Порядок работы с git + +**В начале — обновить локальную копию:** + +``` +cd <каталог репозитория>; git fetch origin --prune; git status +git checkout main; git pull --ff-only origin main +git checkout -b antigravity/hermes-integration +``` + +Зафиксировать фактический `BASE_SHA` через `git rev-parse --short HEAD`. Не считать `cdfd9f1` актуальным автоматически — параллельно идёт задание A12. + +**Ветку отправить в `origin` сразу после первого коммита**, не дожидаясь готовности: + +``` +git push -u origin antigravity/hermes-integration +``` + +**В конце — обязательный push:** + +``` +git push origin antigravity/hermes-integration +``` + +Работа, которой нет в `origin`, для проекта не существует: проверка идёт исполнением, а не по отчёту. + +--- + +## Параллельная работа: строгая граница по файлам + +Одновременно выполняется **A12** вторым исполнителем. + +**Ваши файлы:** + +``` +src/antigravity_provider/hermes_plugin.py +src/antigravity_provider/router/router_engine.py +src/antigravity_provider/router/codex_oauth.py +src/antigravity_provider/router/profile_manager.py +src/antigravity_provider/router/quota_collector.py +src/antigravity_provider/router/adapters/** +src/antigravity_provider/agy_subprocess.py +docs/UI_STATE_CONTRACT.md +tests/test_integration_*.py (новые файлы) +``` + +**Не ваши** (зона A12): `router/ui/**`, `router/model_discovery.py`, `router/model_discovery_service.py`, `router/router_config.py`, `installer/**`, `tests/test_ui_*.py`. + +Понадобился чужой файл — скажите, будет заказан. Молча не трогать: в проекте уже был случай, когда два исполнителя переписали один файл и слияние дало конфликт в двух местах. + +--- + +## Что принято по A9 + +Проверено исполнением на живой машине владельца — работа хорошая: + +- **миграция конфигурации работает**: 16 → 22 профиля, `claude` и `grok` получили по три слота, `find_free_slot` возвращает существующие профили по всем пяти провайдерам. Это снимает корень жалобы «при подключении грока ошибка»; +- резервная копия `router_profiles.yaml.bak_` создаётся, **десять профилей antigravity не изменены ни в одном поле**, комментарии не потеряны; +- квоты `grok` и `opencode-go` честно отдают `None` с причиной вместо правдоподобных чисел; +- флаг `/repair` и `/reinstall` задействован, предупреждение CS0219 исчезло; +- граница зоны Codex не нарушена, правка плагина `2d62d39` сохранена. + +**Исправлено ревьюером при слиянии** — переделывать не нужно, но знать полезно: + +1. Служба обнаружения моделей была **недостижима**. Создан `model_discovery_service.py`, а интерфейс импортирует `model_discovery`. Импорт обёрнут в `except ImportError`, поэтому расхождение не давало ошибки — выбор моделей просто оставался пустым навсегда. Добавлена согласованная точка входа. +2. Служба отдаёт `discovered_at`, каталог искал `fetched_at`. Сведено. +3. Тест `test_ui_routing_graph.py` закреплял выдуманный список `grok-3`; вы верно убрали литералы, и тест начал падать. Приведён к честному поведению. + +Урок на будущее: **защитный `except ImportError` прячет несобранную интеграцию.** Когда пишете модуль для чужого потребителя — согласуйте путь и проверьте импорт исполнением, а не глазами. + +Два числа из отчёта A9, которые не сошлись: «218 passed, 29 skipped» против **307 passed, 2 skipped** на слитом `main`, и «Release Gate 7/7 PASSED» против **FAILED** в моём замере. Двадцать девять пропусков означают, что UI-тесты у вас не выполнялись. Прогон обязателен в окружении **с** `customtkinter`, `pillow`, `psutil`. + +--- + +## P0-1. Hub перехватывает каждый вызов Hermes и назначает ему роль `orchestrator` + +Самое важное в задании. + +Владелец сообщил: «зашёл в Гермеса, а там наш хаб не работает, основной оркестратор не выбрался», и заключил, что Hub к Hermes не привязан. Заключение неверное, положение хуже: **Hub привязан и активно ломал Hermes.** + +Установлено разбором кода Hermes и его журналов: + +1. Плагин регистрируется штатно. `hermes_cli/plugins.py:4789` берёт `register` у модуля, корневой `__init__.py` его экспортирует, `ctx.register_middleware("llm_execution", …)` — допустимое имя (`hermes_cli/middleware.py:23`). Перехватчик **срабатывает на каждом обращении к модели**, это видно в трейсбеке `agent.log`. + +2. **Hermes не передаёт роль.** `agent/conversation_loop.py:2950` передаёт `task_id`, `turn_id`, `api_request_id`, `session_id`, `platform`, `model`, `provider`, `base_url`, `api_mode`, `api_call_count`. Ключа `role` нет. + +3. `resolve_role` доходит до последней строки и возвращает `config.default_role`. **Каждый вызов Hermes идёт как `orchestrator`.** + +4. Цепочка `orchestrator` у владельца исчерпана целиком: + +``` +ag-orch-fallback skipped_unhealthy +codex-orch 429: Your account is not active, please check your billing details +opengo-3 No API key found for OpenCode Go profile 'opengo-3' +ag-w1, ag-w3 Antigravity error: agy error: authentication failed or timed out +``` + +5. Роутер возвращал «⚠️ Hermes Router Failover Exhausted» **как ответ ассистента**, и Hermes показывал это вместо ответа модели, хотя его собственный провайдер работал. + +Следствие устранено ревьюером (`2d62d39`): при `router_error` вызов уходит вниз через `next_call`, отказ пишется в журнал уровнем `warning`. Закрыто тестом `tests/test_plugin_passthrough.py`. **Правку не откатывать.** + +Принцип, который она закрепляет: **плагин может улучшить маршрутизацию, но не имеет права сделать Hermes хуже, чем без него.** + +**От вас — причина.** Сейчас Hub на каждом вызове Hermes сначала пробует цепочку `orchestrator`: лишняя задержка и расход квоты не той роли даже там, где пропуск сработал верно. + +1. **Определить роль честно.** Разобрать, что из переданного Hermes пригодно как признак: `task_id`, `session_id`, `platform`, `model`, `provider`. Надёжного признака нет — **не угадывать**. Эвристика в `resolve_role`, ищущая в системном сообщении подстроки «developer», «coding agent», «review agent», — это гадание по тексту промпта, и оно тоже подлежит пересмотру. + +2. **Не претендовать на вызов без роли.** Роль не определена достоверно — пропускать вниз сразу, не тратя попыток. Роль по умолчанию для внешнего перехвата — неверная модель поведения. + +**Тесты:** вызов без определяемой роли уходит вниз, не тратя попыток роутера; вызов с определённой ролью маршрутизируется; отказ цепочки никогда не возвращается как ответ ассистента. + +## P0-2. Граница между учётными системами Hub и Hermes + +Владелец прав по существу: Hub профилями Hermes не управляет. + +Hermes ведёт собственные профили в каталоге `profiles` своего домашнего каталога: + +``` +agy-01 … agy-06, worker-fast, worker-research, worker-review, +worker-code, worker-code-2, deepseek +``` + +и настраивает `delegate_task` отдельно (`max_concurrent_children=3`, `provider=opencode-go`, `model=kimi-k2.7-code`). + +Профили Hub — `ag-w1`, `ag-orch-fallback`, `codex-orch`, `opengo-*` — **другое множество идентификаторов**. Один и тот же аккаунт Google живёт в двух учётных системах под разными именами. + +**Требуется:** + +1. Раздел в `docs/UI_STATE_CONTRACT.md`: что Hub видит от Hermes, чего не видит, чем управляет и чем не управляет. Без этого интерфейс, показывающий «команду агентов», вводит владельца в заблуждение — он видит роли, которых Hermes не спрашивает. + +2. **Варианты связывания профилей с оценкой цены каждого:** сопоставление по идентичности аккаунта (email из `id_token`), чтение профилей Hermes как источника, либо явная таблица соответствия. **Решение принимает владелец — вам подготовить варианты, не реализовывать молча.** + +## P0-3. Codex: обновление токена и безопасное переключение аккаунта + +Владелец прислал, как это делает Cockpit Tools, и просит так же: + +``` +1. Прочитать данные аккаунта access_token · id_token · refresh_token +2. Проверить access_token действителен до 28.08, обновление не требуется +3. Проверить id_token истёк 5 дней назад — нужно обновление +4. Обновить данные входа полный набор обновлён и сохранён +5. Остановить прежний процесс безопасная остановка ChatGPT/Codex и app-server +6. Записать данные клиента +7. Синхронизировать настройки +8. Запустить клиент Codex +``` + +Ключевое: токены проверяются **по отдельности**, и клиент останавливается **до** подмены учётных данных. + +В отчёте A9 упомянуты токены Codex, но проверить это исполнением не удалось: у профилей Codex на машине владельца нет авторизации. Поэтому пункт остаётся открытым и должен быть закрыт **тестами**, а не только кодом: + +1. Обновление токена по `refresh_token` с сохранением полного набора и понятной ошибкой, когда `refresh_token` отсутствует или отвергнут. +2. Раздельная проверка срока `access_token` и `id_token` с запасом по времени; в статусе профиля видно, что именно просрочено. +3. Переключение аккаунта как наблюдаемая последовательность: остановка клиента → запись учётных данных → синхронизация → запуск. Каждый шаг сообщает о себе, чтобы интерфейс (зона A12) показал прогресс. +4. Сбой на любом шаге не оставляет промежуточного состояния: либо переключено полностью, либо возврат к прежнему. + +**Тесты:** просроченный `access_token` при живом `refresh_token` обновляется без повторного входа; отсутствие `refresh_token` даёт понятную ошибку, а не молчаливый провал; прерывание на середине не оставляет смешанных учётных данных. + +## P0-4. Обнаружение моделей Antigravity устроено неверно + +Служба кэширования из A9 работает, но зонд для Antigravity не возвращает ничего. Проверено: + +``` +discover_models failed: agy.exe -p x --model __invalid_probe__ ... timed out after 20 seconds +обнаружено моделей: 0 +``` + +`agy_subprocess.py:122` запускает `agy` с **заведомо неверной моделью** и разбирает текст ошибки, надеясь выудить из неё список. Это отказало: команда просто виснет на 20 секунд. + +При этом у CLI есть штатная команда. Проверено вручную — `agy models` возвращает четырнадцать настоящих моделей, разделитель табуляция: + +``` +gemini-3.7-flash-high Gemini 3.7 Flash (High) +gemini-3.1-pro-high Gemini 3.1 Pro (High) +claude-sonnet-4-6 Claude Sonnet 4.6 (Thinking) +gpt-oss-120b-medium GPT-OSS 120B (Medium) +``` + +**Требуется** заменить зонд на `agy models` с разбором табулированного вывода. + +Осторожно с таймаутом: **та же команда в одном прогоне отвечает за 40 секунд, а в следующем висит больше двух минут.** Это замерено, не предположение. Жёсткий таймаут обязателен, при его срабатывании прежний кэш сохраняется. + +Заодно убрать выдуманный запасной список в `antigravity_adapter.py:144`: + +```python +return list(profile.preferred_models or ["gemini-2.5-pro", "gemini-2.5-flash", "gemini-2.5-flash-thinking"]) +``` + +Моделей `gemini-2.5-*` у провайдера **не существует** — настоящие начинаются с `gemini-3`. Это тот же класс дефекта, из-за которого в конфигурацию владельца попал несуществующий `gemini-3.7-flash`, стоящий сейчас у роли `orchestrator` как `default_model`. Нет обнаруженного списка — возвращать пустой. + +**Тест:** зонд возвращает непустой список на подготовленном выводе `agy models`; при таймауте прежний кэш не затирается; запасного литерала в адаптере нет. + +## P1-5. Квоты: `source` не должен опережать данные + +Мелочь, но она из того же семейства, с которым боремся весь проект: + +``` +opencode-go:opengo-1 source=provider_api + Общий 5 часов / Недельный / Месячный: remaining=None +``` + +`source="provider_api"` заявляет измерение, которого не было — все корзины пусты. Либо `source="baseline"`, когда чисел нет, либо отдельное поле, различающее «провайдер ответил, но лимитов не даёт» и «провайдер не ответил». Причина уже пишется правильно, расходится только `source`. + +--- + +## Что принято и переделке не подлежит + +Не откатывать при слиянии: + +- живые квоты Antigravity (`retrieveUserQuotaSummary` с обновлением токена при 401): шесть аккаунтов владельца отдают разные измеренные числа; +- правка плагина `2d62d39` и тест `tests/test_plugin_passthrough.py`; +- `_finish` мастера: `destroy()` выполняется всегда; +- исправление `is_expired` в `do_test_profile`; +- миграция конфигурации из A9 и точка входа `model_discovery.py`. + +## Ограничения + +- Строгая граница по файлам — см. выше. +- Никаких чисел, идентификаторов и названий моделей без измерения. +- Сеть и подпроцессы — не в UI-потоке. +- Тег `v0.1.1` не создавать. + +## Критерии приёмки + +1. Ветка в `origin`. Ни один файл зоны A12 не изменён. +2. Вызов без достоверно определённой роли уходит вниз, не тратя попыток роутера; отказ цепочки никогда не возвращается как ответ ассистента; правка `2d62d39` сохранена. +3. Граница между учётными системами Hub и Hermes описана в контракте; варианты связывания профилей поданы с ценой каждого, без односторонней реализации. +4. Токен Codex обновляется по `refresh_token`; переключение останавливает клиент до подмены учётных данных и не оставляет промежуточного состояния; закрыто тестами. +5. `agy models` используется как зонд; обнаружение возвращает непустой список; при таймауте кэш сохраняется; выдуманного запасного списка в адаптере нет. +6. `source` квоты не заявляет измерения там, где чисел нет. +7. Прогон **в окружении с UI-зависимостями**; число пропусков объяснено. На `main` набор даёт 307 passed, 2 skipped. +8. `ruff check .` чисто. Релизный гейт: назвать состояние до и после, объяснить расхождение с замером ревьюера; ухудшать нельзя. +9. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`. + +## Порядок сдачи +Передать точный `FINAL_COMMIT_SHA`. **Сдано только после появления ветки в `origin`.** diff --git a/agents/inbox/2026-08-23-A12-antigravity-flash-interface.md b/agents/inbox/2026-08-23-A12-antigravity-flash-interface.md new file mode 100644 index 0000000..7cd46c9 --- /dev/null +++ b/agents/inbox/2026-08-23-A12-antigravity-flash-interface.md @@ -0,0 +1,220 @@ +# Задание A12 (Antigravity Flash, другой ПК): интерфейс и чистка разделов + +## Дата поступления +2026-08-23 + +## База +Проверочный HEAD на момент выдачи: **`cdfd9f1`**. + +## Ветка +`antigravity/interface-cleanup` + +## Кому +Быстрая ветка работ. Задачи описаны подробно и не требуют проектных решений — только аккуратное исполнение. + +--- + +## Порядок работы с git — читать первым + +Прошлый раз работа A9 была готова, но **не отправлена в `origin`**, и трое суток её не существовало для проекта. Чтобы это не повторилось, порядок жёсткий. + +**Шаг 1. В самом начале — обновить локальную копию из git:** + +``` +cd <каталог репозитория>; git fetch origin --prune; git status +``` + +Если рабочее дерево чистое: + +``` +git checkout main; git pull --ff-only origin main +``` + +Если есть незакоммиченные правки — сначала сохранить их отдельной веткой, вслепую сбрасывать нельзя. + +**Шаг 2. Создать ветку от свежего `main` и сразу отправить её:** + +``` +git checkout -b antigravity/interface-cleanup +git push -u origin antigravity/interface-cleanup +``` + +Пустая ветка в `origin` ничего не ломает и никого не обязывает. Зато с этого момента работа перестаёт зависеть от одного диска. + +**Шаг 3. Пушить после каждого осмысленного коммита**, не копить. + +**Шаг 4. В самом конце — обязательный финальный push и проверка, что он прошёл:** + +``` +git push origin antigravity/interface-cleanup +git status +git log --oneline -1 origin/antigravity/interface-cleanup +``` + +Последняя команда должна показать ваш финальный коммит. Если не показывает — push не прошёл, повторить. + +Зафиксировать фактический `BASE_SHA` через `git rev-parse --short HEAD` и указать его в отчёте. Не считать `cdfd9f1` актуальным автоматически — параллельно идёт A11. + +--- + +## Параллельная работа: строгая граница по файлам + +Одновременно выполняется **A11** вторым исполнителем. + +**Ваши файлы:** + +``` +src/antigravity_provider/router/ui/** +src/antigravity_provider/router/model_discovery.py +src/antigravity_provider/router/model_discovery_service.py +src/antigravity_provider/router/router_config.py +src/antigravity_provider/router/auto_assigner.py +src/antigravity_provider/router/unified_health.py +installer/** +tests/test_ui_*.py +``` + +**Не ваши** (зона A11): `hermes_plugin.py`, `router_engine.py`, `codex_oauth.py`, `profile_manager.py`, `quota_collector.py`, `adapters/**`, `agy_subprocess.py`, `docs/UI_STATE_CONTRACT.md`. + +Понадобился чужой файл — скажите, будет заказан отдельно. + +--- + +## Что принято по A9 + +Проверено исполнением, работа хорошая: миграция конфигурации подняла 16 профилей до 22, `claude` и `grok` получили слоты, резервная копия создаётся, десять профилей владельца не тронуты, комментарии не потеряны, флаг `/reinstall` заработал, предупреждение CS0219 исчезло. + +**Один урок, который стоит запомнить.** Служба обнаружения моделей была написана правильно, но **недостижима**: файл назван `model_discovery_service.py`, а интерфейс импортирует `model_discovery`. Импорт в `ui/model_catalog.py` обёрнут в `except ImportError`, поэтому ошибки не возникало — выбор моделей просто оставался пустым навсегда, с надписью «Список моделей ещё не получен». Ревьюер добавил точку входа при слиянии. + +Защитный `except ImportError` уместен в бою, но он же прячет несобранную интеграцию. Пишете модуль для чужого потребителя — проверьте импорт **исполнением**, а не глазами. + +--- + +## Что уже сделал Codex и переделывать не нужно + +У Codex закончились лимиты, его работа влита частично. Не откатывайте: + +- выбор модели: `ui/model_catalog.py` с честным пустым состоянием; +- **карточка кликабельна целиком** (`cursor="hand2"` + привязка ``), «три точки» перестали быть единственным входом; +- **окно настроек роли**: `_open_agent_settings_modal`; +- **правая панель «Статус в реальном времени» убрана**, центр расширен; +- жёсткие срезы `providers[:3]` и `agents[:5]` в диаграмме устранены; +- причины у части `Н/Д` через `unavailable_reason`. + +Codex остановился ровно перед двумя пунктами ниже — они и есть основная работа задания. + +--- + +## P0-1. Компактные карточки аккаунтов + +`accounts_view.py` не менялся вообще. Это самый заметный для владельца пункт. + +Жалобы дословно: **«аккаунты должны выглядеть как у кокпит тулс, компактно»**, **«вид не тот, не надо делать раскрывающееся окно»**, **«в аккаунтах квота так и не отображается»**. + +Требуется: + +- плотный список фиксированной высоты: провайдер, идентичность, роль, состояние авторизации, квота — одной строкой, **без раскрытия**; +- **квота видна сразу**, числом и полосой, с указанием пула и периода. У Antigravity четыре пула, и «просто процент» вводит в заблуждение; +- шестнадцать аккаунтов читаются без прокрутки внутрь карточек; +- **дельта-отрисовку по стабильным ключам не терять** — изменение одного аккаунта не перерисовывает остальные. + +Данные для квоты **уже есть и настоящие**. На живых аккаунтах владельца приходят измеренные значения от провайдера: + +``` +ag-w2 Claude/GPT — неделя осталось 37.4% source=provider_api +ag-w3 Claude/GPT — неделя осталось 90.1% source=provider_api +ag-w1 Gemini — неделя осталось 99.7% source=provider_api +``` + +Где данных нет — `Н/Д` с причиной, а не ноль и не прочерк без объяснения. У `opencode-go` и `grok` провайдер лимитов не отдаёт, и причина уже заполняется в `unavailable_reason`. + +Про дельта-отрисовку: в корне репозитория лежит `COCKPIT_TOOLS_ARCHITECTURE_COMPARISON.md` — там описано, почему это важно: при пересборке всех карточек на 50 аккаунтах выходит больше тысячи операций с виджетами в UI-потоке, и окно заметно подвисает. Документ — архитектурное сравнение, а не макет: берите принцип обновления и плотность, не буквальную вёрстку. + +**Тест:** изменение квоты одного аккаунта не пересоздаёт виджеты остальных. + +## P0-2. Разобрать дублирующие разделы + +`quotas_view.py` не менялся, `providers_view.py` тронут на девять строк. + +Жалоба: **«провайдеры и квоты и лимиты вообще не понятно для чего нужны, там всё то же, что и в аккаунты»**. + +Владелец прав: после появления квот в карточках аккаунтов отдельный раздел квот потерял смысл. Нужно **решение**, а не сохранение обоих на всякий случай. + +- **«Квоты и лимиты»** — убрать из навигации либо оставить только то, чего нет в «Аккаунтах»: сводка по провайдеру целиком, история расхода, ближайшие сбросы. Нет такого содержания — убрать раздел. +- **«Провайдеры»** — оставить относящееся к провайдеру, а не к аккаунту: доступность runtime, обнаруженные модели, версия CLI, состояние авторизации в целом. + +В отчёте перечислить, что перенесено, что удалено и почему. Пустой раздел не оставлять: либо содержание, либо нет пункта навигации. + +## P0-3. Причина у каждого Н/Д + +Жалоба: **«что означает н/д в маршрутизация запросов»**. + +Codex закрыл частично: `unavailable_reason` используется в `components.py` и на «Обзоре», но не везде. + +Везде, где стоит `Н/Д`, причина должна быть доступна — подсказкой при наведении и текстом рядом, если место позволяет. Формулировки конкретные: «нет телеметрии: роль ещё не вызывалась», «провайдер не отдаёт лимиты», «аккаунт не подключён». Данные для этого есть. + +Это претензия не к честности, а к молчаливости: владелец видит прочерк и не знает, это поломка, ненастроенное или неизмеримое. + +## P0-4. Тест на достижимость службы обнаружения моделей + +Ревьюер добавил точку входа `router/model_discovery.py`, и выбор моделей снова собран. Но защита от повторения этой ошибки отсутствует. + +Требуется тест, который **падает**, если служба недостижима по согласованному пути: + +- модуль: `src/antigravity_provider/router/model_discovery.py` +- класс: `ModelDiscoveryService` +- получение экземпляра: classmethod `get()` + +Тест обязан отличать «службы нет» от «служба есть, но импорт не тот». Проверять через `ui/model_catalog` недостаточно — там `except ImportError` всё проглотит; импортируйте модуль напрямую. + +## P0-5. Подключение Grok и Claude довести до конца + +После миграции из A9 слоты появились, проверено: + +``` +find_free_slot(grok) -> grok-worker-1 +find_free_slot(claude) -> claude-orch +``` + +Мастер больше не должен упираться в «свободный слот не найден». Но проверить нужно **весь путь**, а не только выдачу слота: подключение, назначение роли, появление в маршрутизации, тест профиля. + +Жалоба владельца была **«при подключении грока ошибка»**. Принимается только пройденный вживую сценарий со скриншотами. + +## P1-6. Порядок провайдеров в диаграмме + +A9 задал детерминированный порядок провайдеров в `unified_health.get_provider_summaries()` (по числу авторизованных профилей, затем по общему числу слотов, затем по имени) и привёл `total_providers` к пяти. + +Убедиться, что диаграмма на «Обзоре» этот порядок соблюдает и показывает всех пятерых, а не первых трёх. Срезы Codex убрал, но проверить связку целиком стоит — раньше `claude` и `grok` молча отбрасывались. + +--- + +## Ограничения + +- Строгая граница по файлам — см. выше. +- Не выдумывать числа, идентификаторы и названия моделей. Нет данных — `Н/Д` с причиной либо блок отсутствует. +- Три темы сохранить, дельта-отрисовку не терять. +- Мастер не ломать: шесть потоков подключения, трёхэлементная распаковка `start_profile_oauth`, `destroy()` в `_finish` выполняется всегда. +- Сеть и подпроцессы — не в UI-потоке. Замерено: `agy models` в одном прогоне отвечает за 40 секунд, в следующем висит больше двух минут. +- Тег `v0.1.1` не создавать. + +## Критерии приёмки + +1. **Ветка в `origin`**, финальный коммит виден через `git log origin/antigravity/interface-cleanup`. Ни один файл зоны A11 не изменён. +2. Карточка аккаунта компактна, фиксированной высоты, без раскрытия; квота видна сразу с указанием пула и периода; шестнадцать аккаунтов без внутренней прокрутки. +3. Дельта-отрисовка сохранена: изменение одного аккаунта не пересоздаёт виджеты остальных; проверено тестом. +4. Принято решение по «Провайдерам» и «Квотам»; перенесённое и удалённое перечислено; пустых разделов нет. +5. У каждого `Н/Д` доступна причина. +6. Есть тест, падающий при недостижимости `router/model_discovery.ModelDiscoveryService`. +7. Grok и Claude подключаются вживую: подключение, роль, маршрутизация, тест профиля. +8. Диаграмма показывает всех пятерых провайдеров в заданном порядке. +9. Прогон **в обоих окружениях** — без UI-зависимостей и с `customtkinter`/`pillow`/`psutil`; обе команды и оба результата в отчёте. На `main` полный набор даёт 307 passed, 2 skipped. +10. `ruff check .` чисто. Релизный гейт не ухудшен. +11. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, точный `X passed / Y skipped / Z failed`. +12. **Скриншоты живого сценария с настоящими данными**: «Аккаунты» с видимыми квотами, подключение Grok, окно роли. Пустых состояний не присылать. + +## Главное + +Владелец сказал: «надо чтобы хаб уже заработал». Квоты настоящие, роли настраиваются, подключение Grok разблокировано. Осталось, чтобы шестнадцать аккаунтов читались с одного взгляда и в каждом непонятном месте был ответ, почему там прочерк. + +## Порядок сдачи +Передать точный `FINAL_COMMIT_SHA`. **Сдано только после появления ветки в `origin`** — проверьте это командой перед тем, как отчитаться.