From 8cb57dd6a1a13ae308ad037d91faeab23197c0bb Mon Sep 17 00:00:00 2001 From: Hermes Team Date: Tue, 25 Aug 2026 14:40:37 +0700 Subject: [PATCH] =?UTF-8?q?docs(agents):=20=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20A26=20=E2=80=94=20=D0=B0=D0=BA=D0=BA=D0=B0=D1=83?= =?UTF-8?q?=D0=BD=D1=82=D1=8B=20=D0=B1=D0=B5=D0=B7=20=D1=81=D0=BB=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D0=B2,=20=D1=80=D0=B0=D1=81=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=B3=D0=B8=20=D0=BA=D0=B2=D0=BE=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Владелец сформулировал, ради чего задумывался хаб: вручную распределять аккаунты по агентам и следить за квотами, подставляя другой аккаунт там, где лимит подходит к концу. Модель слотов этому мешает — она навязывает внутреннее устройство конфигурации и уже привела к тому, что подключённый аккаунт не появился в маршрутизации. Задание опирается на три факта, снятых исполнением, чтобы агенты не переписывали работающее: один профиль уже может обслуживать все шесть ролей; произвольный идентификатор профиля регистрируется, то есть потолок в три аккаунта Codex держит только зашитый список в auto_assigner; порогов квот в коде нет вовсе. Co-Authored-By: Claude Opus 5 --- .../2026-08-25-A26-accounts-without-slots.md | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 agents/inbox/2026-08-25-A26-accounts-without-slots.md diff --git a/agents/inbox/2026-08-25-A26-accounts-without-slots.md b/agents/inbox/2026-08-25-A26-accounts-without-slots.md new file mode 100644 index 0000000..f9c8a68 --- /dev/null +++ b/agents/inbox/2026-08-25-A26-accounts-without-slots.md @@ -0,0 +1,171 @@ +# Задание 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%) и при достижении этих лимитов или оповещение или автоматом переключает на резервный аккаунт». + +Это то, ради чего хаб задумывался. Требуется: + +1. **Настраиваемый порог** — общий и, если несложно, отдельный для аккаунта. Значения владельца: 10% и 5%. **В код их не зашивать**, это умолчание, а не константа. +2. **Выбор поведения** при достижении: только оповестить либо переключиться на следующий аккаунт в цепочке. Решает владелец, не код. +3. **Оповещение видно в интерфейсе** — в «Состоянии» и в журнале событий. Достаточно ли тоста — решите и обоснуйте. +4. **Переключение обратимо.** Квоты восстанавливаются по `reset_at`; отставленный по порогу аккаунт обязан вернуться в строй сам. Урок A23 уже оплачен: у `AUTH_REQUIRED` не было выхода, и шесть профилей выпали навсегда. **Повторять нельзя.** + +Данные есть: `quota_collector` собирает проценты и `reset_at`, они видны в карточках. + +Честность обязательна: порог срабатывает по **измеренной** квоте. Неизвестная квота («Н/Д») — **не** повод считать её нулевой и переключаться. Нет данных — так и сказать, поведение не менять. + +## P0-6. Аудит вторым проходом + +Для проверяющего. Список составлен из дефектов, уже проходивших мимо первого прохода. + +1. **Выдуманные значения.** Находились захардкоженные коды устройства `GRK-7842`, `CDX-9104`, запасной коммит `fb23bff` в манифесте. Здесь особый риск в P0-5: соблазн подставить «разумный» процент при отсутствии данных. +2. **Тесты, закрепляющие дефект.** `test_headless_server_auth_matrix` дважды защищал заглушку: сначала требовал неверный адрес `x.ai/device`, затем слова «Headless» и «agy», хотя вход через веб уже работал. Новые тесты должны описывать желаемое поведение. +3. **Запустить изменённое.** Импорт ничего не доказывает. На днях вложенная функция оказалась не видна части точек вызова и давала `NameError` внутри обработки успеха — поймал `ruff`, а не тест. +4. **Кэш состояния.** Только что чинилось: учётные данные сохранялись, но `refresh(force_scan=False)` состояние не обновлял, и подключённый аккаунт не появлялся никогда. Любое изменение состава аккаунтов обязано быть видно **сразу**, без перезапуска. +5. **Побочные изменения** в файлах, которых задание не касалось, — объяснить каждое. +6. **Пропущенный пункт назвать пропущенным.** + +--- + +## Ограничения + +- Десктоп (`router/ui/**`) не трогать: он выводится из обращения. +- Правило честности без исключений. Нет данных — «Н/Д» и причина. +- Действия только через существующий `action_handler`; второй реализации `assign_role`, `save_chain`, `set_model` быть не должно. +- Меняете контракт — правьте `docs/web-api/CONTRACT.md` и скажите в отчёте. +- Конфигурацию владельца литералами не править. +- Тег `v0.1.1` не создавать. + +## Критерии приёмки + +1. Ветка в `origin`, `git status` чист. +2. Подключается **пятый** аккаунт одного провайдера; проверено исполнением, вывод в отчёте. +3. «Аккаунты» показывают только подключённые; при нуле подключённых — внятное пустое состояние, а не 24 пустые карточки. +4. Аккаунт назначается агенту из «Обзора»; один аккаунт назначается **всем шести** ролям; изменение доходит до `router_profiles.yaml` и переживает перезапуск. +5. «Авто» описано по факту запуска: что делает при одном провайдере, при двух, при нескольких аккаунтах одного провайдера. +6. Порог настраивается, значение не зашито; при достижении срабатывает выбранное поведение; при неизвестной квоте не срабатывает. +7. Аккаунт, отставленный по порогу, возвращается в строй после восстановления квоты **без ручного вмешательства**; проверено тестом. +8. Изменения состава аккаунтов видны в интерфейсе сразу, без перезапуска. +9. Ни одного выдуманного значения; проверено отдельно и описано в отчёте. +10. `ruff check .` чисто; релизный гейт не ухудшен. +11. **Скриншоты:** «Аккаунты» с одним аккаунтом, «Обзор» с назначением, настройка порога. +12. Отчёт: `START_HEAD`, `FINAL_HEAD`, `origin/main`, `git status`, `X passed / Y skipped / Z failed`. На `main` сейчас **432 passed, 2 skipped**. + +## Главное + +Владелец хочет управлять аккаунтами, а не слотами: загрузил аккаунты, распределил по агентам, следит за квотами и переставляет, когда они подходят к концу. Всё остальное в задании обслуживает это. + +## Порядок сдачи +Передать точный `FINAL_COMMIT_SHA`. Сдано только после появления коммита в `origin`.