Adopts the graph half of the 104-point n8n-derived brief and states plainly what is excluded: n8n's canvas edits its own workflow execution engine, while Hermes Hub's engine resolves a role into a provider/account/model for a single call. Execution trees, agent-as-tool contracts, cancellation and review loops have no layer to sit on here. Adds the requirement that has been missing all along: screenshots taken with a live connected account, not an empty configuration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
14 KiB
Задание B6 (Codex): рабочий Hub и граф над маршрутизацией
Дата поступления
2026-08-21
База
Проверочный HEAD: 09d5e5d, origin/main = 09d5e5d. git fetch, зафиксировать BASE_SHA, работать от свежего main.
Ветка
codex/routing-graph
Что принято по B5
Проверено исполнением и по скриншотам:
- макет воспроизведён — левая навигация, верхняя строка с поиском и
Ctrl + K, ряд KPI, схема маршрутизации, правая панель, лента событий; - три темы работают, переключение перекрашивает всё приложение;
- дисциплина честности выдержана: на скриншоте «Обзора» стоят
Н/Дс пояснением причины там, где данных нет, и реальные значения там, где есть. Ни одного выдуманного числа; - четыре действия вернулись на карточку аккаунта через
MANAGEMENT_ACTIONS; - 33 скриншота, тесты 193 headless / 249 с UI-зависимостями, ruff чисто.
Это лучшая работа по интерфейсу за все раунды.
Про исходный документ «Agent Graph / n8n»
Документ на 104 пункта прочитан и разобран. Реализуется только часть, и это осознанное решение владельца.
Причина: n8n — это Node.js/TypeScript с собственным движком исполнения workflow и базой данных; канва там редактирует то, что движок исполняет. У Hermes Hub движок другой — маршрутизации: он выбирает провайдера, аккаунт и модель для одного вызова. Агентов, которые исполняются, делегируют задачи и возвращают артефакты, в Hub нет — они живут в Hermes Agent, внутри которого Hub работает плагином.
Исключено из задания (требует несуществующего слоя исполнения):
| Пункт документа | Причина |
|---|---|
| §3 Hermes Execution Engine, §66 Execution Planner | движка исполнения агентов в Hub нет |
| §12 Execution Tree, §56 snapshot execution | нечего вкладывать: route_request — один вызов, один ответ |
| §31–35 Agent as Tool, input/output schema | межагентных вызовов не существует |
| §37 отмена дерева, §38 таймауты на 4 уровнях | нечего отменять |
| §39 failure propagation, §40–41 REVIEW и цикл доработки | требует исполнения ролей |
| §1, §96 БД и миграции | БД нет, конфигурация в YAML/JSON |
| §69 React graph-библиотека | стек — Python + CustomTkinter |
| §61 permissions | системы прав нет |
Берётся из документа: §68 (разделение слоёв), §30 (topology не меняется при provider fallback), §28 (не делать второй редактор маршрутизации), §43–44 (персистентность и версия схемы), §46–47 (валидация с показом на графе), §48–53 (layout, zoom, minimap, поиск), §58 (без выдуманных метрик), §60 (без секретов в графе), §62 (миграция текущих ролей), §72–75 (клавиатура, undo/redo, несохранённые изменения), §80–81 (различать типы связей не только цветом).
P0-1. Hub должен быть демонстрируемо рабочим
Главное требование задания. Приложение ни разу не проходило полный путь с живым аккаунтом: все скриншоты сняты на пустой конфигурации, где везде Н/Д и «Критическое состояние».
Что проверить и починить:
-
Мастер потерял назначение роли.
add_account_wizard._finish(строка 1451) теперь только пишет событие в журнал и вызываетon_complete. ВызоваAutoAssigner.assign_profile_to_roleтам больше нет. Разобраться: достаточно ли того, что слот уже входит в цепочку роли по умолчанию, или подключённый аккаунт остаётся вне маршрутизации. Если достаточно — описать это в отчёте; если нет — вернуть назначение. -
Пустое состояние должно вести пользователя. Сейчас на «Обзоре» при отсутствии аккаунтов — «Критическое состояние» и пять
Н/Д, без единой подсказки, что делать. Первый экран нового пользователя обязан объяснять следующий шаг и давать кнопку к нему. -
Ручная проверка с настоящим аккаунтом — обязательна. Подключить один реальный аккаунт (любого провайдера), убедиться, что он появился в «Аккаунтах», получил роль, виден на «Маршрутизации», и что тест профиля проходит. Приложить скриншоты этих состояний, а не пустых.
Без пункта 3 задание не принимается. Скриншоты пустого приложения доказывают вёрстку, но не работоспособность.
P0-2. «Команда» становится графом маршрутизации
Превратить экран «Команда» в визуальный редактор на CTkCanvas.
Модель. Узел = логическая роль из config.roles (orchestrator, coder-primary, coder-secondary, reviewer, research, fast) плюс узел оркестратора. Связь = позиция в цепочке отказоустойчивости: основной → резерв 1 → резерв 2. Типы связей минимально: PRIMARY, FALLBACK, DELEGATE.
Ключевой принцип (§68 документа): граф описывает роли и их отношения. Какой провайдер, аккаунт и модель исполнят роль — решает существующий роутер. Смена провайдера при отказе не меняет граф.
Что должно работать:
- перемещение узлов, создание и удаление связей, изменение типа связи;
- изменение графа реально меняет цепочки в
router_profiles.yamlчерезAutoAssigner.assign_profile_to_role— это не картинка (§64 документа); - сохранение позиций, масштаба и области просмотра рядом с конфигурацией, с полем версии схемы;
- миграция текущих шести ролей в граф по умолчанию при первом открытии;
- автовыравнивание (иерархическое), после него ручные координаты не перезатираются;
- zoom, вписать в экран, minimap для больших графов;
- undo/redo для перемещения, добавления и удаления узлов и связей;
- отметка «есть несохранённые изменения», без молчаливой потери.
Валидация перед сохранением с показом ошибок прямо на графе: отсутствующий оркестратор, роль без профилей, недостижимый узел, ссылка на несуществующий профиль, дубли.
P0-3. Инспектор узла
При выборе роли справа: назначенные профили в порядке цепочки, текущий активный, провайдер, аккаунт, модель, состояние квоты, причина последнего переключения. Кнопка «Открыть маршрутизацию» ведёт в существующий раздел с выбранной ролью — второй редактор маршрутизации не создавать (§28).
P1-4. Живая подсветка на реальных данных
Данные уже есть, выдумывать ничего не нужно:
| Что показать | Откуда |
|---|---|
| активный узел и связь | PipelineNode.is_active, RolePipeline.active_profile_id |
| причина переключения | PipelineNode.failover_reason |
| почему выбран провайдер | selection_trace в метаданных ответа |
| нагрузка по ролям | телеметрия by_role, total_calls |
| состояние квоты узла | quota_status |
Обновлять по событиям EventBus (ROUTING_UPDATED, QUOTA_UPDATED, ACCOUNT_*), а не полным пересбором канвы на каждое событие (§95).
Где данных нет — узел не подсвечивается, метка не рисуется. Н/Д вместо чисел, правило прежнее.
Ограничения
- Граница: ваша зона —
src/antigravity_provider/router/ui/**,hermes_hub_app.py,tests/test_ui_*.py. Модель графа и её сохранение — тоже в UI-слое, поскольку это конфигурация представления; изменение цепочек идёт через существующийAutoAssigner. - Не создавать параллельные сущности: роли, профили, цепочки уже есть в
router_config. - Не трогать движок маршрутизации, адаптеры, телеметрию.
- Сеть и подпроцессы — не в UI-потоке.
- Три темы сохранить,
#FFFFFFфоном не использовать. - Логотип Hermes использовать существующий, псевдологотипы агентам не генерировать.
- Тег
v0.1.1не создавать.
Критерии приёмки
- Ни один файл чужой зоны не изменён.
- Скриншоты с подключённым живым аккаунтом: «Обзор», «Аккаунты», «Команда», «Маршрутизация» — с реальными данными, а не
Н/Д. - Пустое состояние на «Обзоре» объясняет следующий шаг и ведёт к нему.
- В отчёте сказано, попадает ли подключённый через мастер аккаунт в маршрутизацию, и на основании чего это установлено.
- Изменение графа отражается в
router_profiles.yamlи переживает перезапуск вместе с позициями и масштабом; проверено тестом. - Миграция шести существующих ролей в граф выполняется без потери цепочек.
- Валидация ловит цикл, недостижимый узел и ссылку на несуществующий профиль; ошибки видны на графе.
- Живая подсветка работает от событий, без полного пересбора канвы.
- Приложение запускается, все разделы открываются; граф держит не менее 20 узлов без заметных задержек.
- Прогон в обоих окружениях — без UI-зависимостей и с
customtkinter/pillow/psutil; обе команды и оба результата в отчёте. ruff check .чисто; release gate не ухудшен.- Отчёт:
BASE_SHA,FINAL_SHA, изменённые файлы, что из документа реализовано, что исключено и почему, известные ограничения.
Главное
Задача — не нарисовать красивый граф, а сделать так, чтобы владелец установил Hub, подключил аккаунт, увидел свою команду ролей, понял, кто чем исполняется и куда уйдёт запрос при исчерпании квоты. Граф — способ это показать и настроить, а не самоцель.
Порядок сдачи
Передать точный FINAL_COMMIT_SHA.