Владелец сформулировал, ради чего задумывался хаб: вручную распределять аккаунты по агентам и следить за квотами, подставляя другой аккаунт там, где лимит подходит к концу. Модель слотов этому мешает — она навязывает внутреннее устройство конфигурации и уже привела к тому, что подключённый аккаунт не появился в маршрутизации. Задание опирается на три факта, снятых исполнением, чтобы агенты не переписывали работающее: один профиль уже может обслуживать все шесть ролей; произвольный идентификатор профиля регистрируется, то есть потолок в три аккаунта Codex держит только зашитый список в auto_assigner; порогов квот в коде нет вовсе. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
16 KiB
Задание A26: аккаунты без слотов, распределение по агентам и пороги квот
Дата поступления
2026-08-25
База
Проверочный HEAD на момент выдачи: d4b99a4.
Ветка
antigravity/accounts-without-slots
Порядок исполнения
Два прохода: Flash реализует, Pro проводит аудит. Пункт P0-6 написан для аудитора.
Порядок работы с git
cd <каталог репозитория>; git fetch origin --prune; git status
git checkout main; git pull --ff-only origin main
git checkout -b antigravity/accounts-without-slots
git commit -m "..." <- сначала коммит
git push -u origin antigravity/accounts-without-slots
В main напрямую не пушить. В конце — push и проверка git log --oneline -1, git status чистый.
Ради чего это всё
Дословно от владельца:
«вот для этого хаб и делался. чтобы вручную правильно распределять аккаунты и играться с лимитами. где подзаканчиваются, там ставить другой аккаунт»
Сейчас продукт этого не даёт. Модель «слотов» — десять предсозданных ячеек Antigravity, три Codex, три OpenCode — навязывает пользователю внутреннее устройство конфигурации. Владелец выбирает слот, ничего не зная о последствиях, и получает результат, которого не ожидал: аккаунт подключён, а на экранах его нет, потому что слот не входит ни в одну цепочку. Это уже случилось вживую.
Нужен обратный порядок: сначала аккаунты, потом назначение.
Что уже проверено исполнением — заново не выясняйте
Три факта, снятые ревьюером на d4b99a4. Они сильно сокращают работу.
1. Один профиль может обслуживать все шесть ролей. Движок это держит уже сейчас:
persist_role_chain(role, ['ag-w1']) для всех шести ролей -> True
конфигурация: все шесть цепочек равны ['ag-w1']
Значит требование «если есть только Antigravity, он встаёт во всех агентах» не требует изменений в маршрутизаторе. Не переписывайте router_engine.
2. Произвольный идентификатор профиля регистрируется.
ensure_profile_definition('openai-codex', 'codex-worker-9') -> True
'codex-worker-9' in load_router_config().profiles -> True
Значит потолок «три аккаунта Codex» — это только зашитый список provider_slots в auto_assigner.py:144, а не структурное ограничение. Снятие потолка не требует переделки формата конфигурации.
3. Порогов квот в коде нет вообще. Поиск по threshold|min_quota|quota_floor|switch_at в router/ не даёт ни одного совпадения. Это делается с нуля.
P0-1. Снять потолок на число аккаунтов
Дословно: «например у меня есть 4 кодекса, и их все я хочу добавить. или 5 опенкодов».
Сейчас AutoAssigner.find_free_slot (auto_assigner.py:140) перебирает жёсткий список и возвращает None, когда список кончился. Четвёртый Codex подключить невозможно.
Требуется: число аккаунтов провайдера ничем не ограничено. Когда предопределённые имена кончились, идентификатор выдаётся автоматически по понятной схеме (codex-4, codex-5, …), с проверкой, что такого ещё нет.
Идентификатор — деталь реализации, и в интерфейсе он не должен быть главным. Владелец мыслит аккаунтами и почтами, а не слотами.
P0-2. «Аккаунты» показывают только настоящие аккаунты
Дословно: «надо убрать все ячейки со вкладки аккаунты. как добавляю аккаунт, тогда он там появляется. не надо захламлять страницу».
Сейчас в умолчаниях предсозданы 24 профиля, и страница показывает их все, включая никогда не подключённые: «Аккаунт не добавлен», «Холодный резерв». У владельца это 24 карточки при одном реальном аккаунте.
Требуется показывать только подключённые.
Осторожно: не удаляйте профили из конфигурации молча — на них ссылаются цепочки ролей. Речь о том, что показывать, а не о том, что хранить. Решите чистить и конфигурацию — обоснуйте в отчёте и сохраните работоспособность цепочек.
P0-3. Назначение аккаунта агенту — в «Обзоре»
Дословно: «просто загрузка аккаунтов, а уже в обзоре прикреплять нужный аккаунт к агенту».
На «Обзоре» уже есть схема ролей и выбор модели в узле (A24). Добавить туда выбор аккаунта: какой обслуживает эту роль и в каком порядке резервирования.
Действия существуют — assign_role, save_chain, reorder_chain; второй реализации не заводить.
Ключевое требование, вытекающее из факта №1: один аккаунт можно назначить сразу нескольким агентам, вплоть до всех шести. Интерфейс не должен этому препятствовать и не должен считать это ошибкой.
P0-4. Кнопка «Авто»
Дословно: «или при нажатии авто, сам распределяет аккаунты согласно маршрутизации».
Действие auto_assign_all существует (action_handler.py:509), но что оно делает и совпадает ли с ожиданием владельца — проверьте исполнением и опишите в отчёте. Отчёт без запуска не принимается.
Ожидаемое поведение:
- Один провайдер. Есть только Antigravity — он встаёт во все шесть ролей. Владелец дальше сам меняет модель у каждого агента. Это нормальный режим, а не вырожденный случай.
- Несколько провайдеров. Распределение идёт по назначению роли: «оркестратор у меня первый кодекс, а кодер антигравити» — у каждой роли есть предпочтительный провайдер, и авто-распределение ему следует, а не раскладывает аккаунты подряд.
- Несколько аккаунтов одного провайдера разводятся по разным ролям, чтобы не жечь квоту одного на всё сразу.
Порядок предпочтений по ролям возьмите из текущего config/router_profiles.example.yaml — он и выражает замысел владельца. Решите его менять — сначала спросите в отчёте, молча не меняйте.
P0-5. Пороги квот: предупреждение или переключение
Дословно: «выставлять минимальные лимиты (например 10% или 5%) и при достижении этих лимитов или оповещение или автоматом переключает на резервный аккаунт».
Это то, ради чего хаб задумывался. Требуется:
- Настраиваемый порог — общий и, если несложно, отдельный для аккаунта. Значения владельца: 10% и 5%. В код их не зашивать, это умолчание, а не константа.
- Выбор поведения при достижении: только оповестить либо переключиться на следующий аккаунт в цепочке. Решает владелец, не код.
- Оповещение видно в интерфейсе — в «Состоянии» и в журнале событий. Достаточно ли тоста — решите и обоснуйте.
- Переключение обратимо. Квоты восстанавливаются по
reset_at; отставленный по порогу аккаунт обязан вернуться в строй сам. Урок A23 уже оплачен: уAUTH_REQUIREDне было выхода, и шесть профилей выпали навсегда. Повторять нельзя.
Данные есть: quota_collector собирает проценты и reset_at, они видны в карточках.
Честность обязательна: порог срабатывает по измеренной квоте. Неизвестная квота («Н/Д») — не повод считать её нулевой и переключаться. Нет данных — так и сказать, поведение не менять.
P0-6. Аудит вторым проходом
Для проверяющего. Список составлен из дефектов, уже проходивших мимо первого прохода.
- Выдуманные значения. Находились захардкоженные коды устройства
GRK-7842,CDX-9104, запасной коммитfb23bffв манифесте. Здесь особый риск в P0-5: соблазн подставить «разумный» процент при отсутствии данных. - Тесты, закрепляющие дефект.
test_headless_server_auth_matrixдважды защищал заглушку: сначала требовал неверный адресx.ai/device, затем слова «Headless» и «agy», хотя вход через веб уже работал. Новые тесты должны описывать желаемое поведение. - Запустить изменённое. Импорт ничего не доказывает. На днях вложенная функция оказалась не видна части точек вызова и давала
NameErrorвнутри обработки успеха — поймалruff, а не тест. - Кэш состояния. Только что чинилось: учётные данные сохранялись, но
refresh(force_scan=False)состояние не обновлял, и подключённый аккаунт не появлялся никогда. Любое изменение состава аккаунтов обязано быть видно сразу, без перезапуска. - Побочные изменения в файлах, которых задание не касалось, — объяснить каждое.
- Пропущенный пункт назвать пропущенным.
Ограничения
- Десктоп (
router/ui/**) не трогать: он выводится из обращения. - Правило честности без исключений. Нет данных — «Н/Д» и причина.
- Действия только через существующий
action_handler; второй реализацииassign_role,save_chain,set_modelбыть не должно. - Меняете контракт — правьте
docs/web-api/CONTRACT.mdи скажите в отчёте. - Конфигурацию владельца литералами не править.
- Тег
v0.1.1не создавать.
Критерии приёмки
- Ветка в
origin,git statusчист. - Подключается пятый аккаунт одного провайдера; проверено исполнением, вывод в отчёте.
- «Аккаунты» показывают только подключённые; при нуле подключённых — внятное пустое состояние, а не 24 пустые карточки.
- Аккаунт назначается агенту из «Обзора»; один аккаунт назначается всем шести ролям; изменение доходит до
router_profiles.yamlи переживает перезапуск. - «Авто» описано по факту запуска: что делает при одном провайдере, при двух, при нескольких аккаунтах одного провайдера.
- Порог настраивается, значение не зашито; при достижении срабатывает выбранное поведение; при неизвестной квоте не срабатывает.
- Аккаунт, отставленный по порогу, возвращается в строй после восстановления квоты без ручного вмешательства; проверено тестом.
- Изменения состава аккаунтов видны в интерфейсе сразу, без перезапуска.
- Ни одного выдуманного значения; проверено отдельно и описано в отчёте.
ruff check .чисто; релизный гейт не ухудшен.- Скриншоты: «Аккаунты» с одним аккаунтом, «Обзор» с назначением, настройка порога.
- Отчёт:
START_HEAD,FINAL_HEAD,origin/main,git status,X passed / Y skipped / Z failed. Наmainсейчас 432 passed, 2 skipped.
Главное
Владелец хочет управлять аккаунтами, а не слотами: загрузил аккаунты, распределил по агентам, следит за квотами и переставляет, когда они подходят к концу. Всё остальное в задании обслуживает это.
Порядок сдачи
Передать точный FINAL_COMMIT_SHA. Сдано только после появления коммита в origin.