hermes-hub/agents/inbox/2026-08-21-B6-codex-routing-graph.md
Hermes Team 35101d1043 docs(task): B6 — routing graph on the Team screen, and a Hub that demonstrably works
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>
2026-08-21 22:25:40 +07:00

137 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Задание 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` — один вызов, один ответ |
| §3135 Agent as Tool, input/output schema | межагентных вызовов не существует |
| §37 отмена дерева, §38 таймауты на 4 уровнях | нечего отменять |
| §39 failure propagation, §4041 REVIEW и цикл доработки | требует исполнения ролей |
| §1, §96 БД и миграции | БД нет, конфигурация в YAML/JSON |
| §69 React graph-библиотека | стек — Python + CustomTkinter |
| §61 permissions | системы прав нет |
**Берётся из документа**: §68 (разделение слоёв), §30 (topology не меняется при provider fallback), §28 (не делать второй редактор маршрутизации), §4344 (персистентность и версия схемы), §4647 (валидация с показом на графе), §4853 (layout, zoom, minimap, поиск), §58 (без выдуманных метрик), §60 (без секретов в графе), §62 (миграция текущих ролей), §7275 (клавиатура, undo/redo, несохранённые изменения), §8081 (различать типы связей не только цветом).
---
## P0-1. Hub должен быть демонстрируемо рабочим
Главное требование задания. Приложение ни разу не проходило полный путь с живым аккаунтом: все скриншоты сняты на пустой конфигурации, где везде `Н/Д` и «Критическое состояние».
**Что проверить и починить:**
1. **Мастер потерял назначение роли.** `add_account_wizard._finish` (строка 1451) теперь только пишет событие в журнал и вызывает `on_complete`. Вызова `AutoAssigner.assign_profile_to_role` там больше нет. Разобраться: достаточно ли того, что слот уже входит в цепочку роли по умолчанию, или подключённый аккаунт остаётся вне маршрутизации. Если достаточно — описать это в отчёте; если нет — вернуть назначение.
2. **Пустое состояние должно вести пользователя.** Сейчас на «Обзоре» при отсутствии аккаунтов — «Критическое состояние» и пять `Н/Д`, без единой подсказки, что делать. Первый экран нового пользователя обязан объяснять следующий шаг и давать кнопку к нему.
3. **Ручная проверка с настоящим аккаунтом — обязательна.** Подключить один реальный аккаунт (любого провайдера), убедиться, что он появился в «Аккаунтах», получил роль, виден на «Маршрутизации», и что тест профиля проходит. Приложить скриншоты **этих** состояний, а не пустых.
Без пункта 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` не создавать.
## Критерии приёмки
1. Ни один файл чужой зоны не изменён.
2. **Скриншоты с подключённым живым аккаунтом**: «Обзор», «Аккаунты», «Команда», «Маршрутизация» — с реальными данными, а не `Н/Д`.
3. Пустое состояние на «Обзоре» объясняет следующий шаг и ведёт к нему.
4. В отчёте сказано, попадает ли подключённый через мастер аккаунт в маршрутизацию, и на основании чего это установлено.
5. Изменение графа отражается в `router_profiles.yaml` и переживает перезапуск вместе с позициями и масштабом; проверено тестом.
6. Миграция шести существующих ролей в граф выполняется без потери цепочек.
7. Валидация ловит цикл, недостижимый узел и ссылку на несуществующий профиль; ошибки видны на графе.
8. Живая подсветка работает от событий, без полного пересбора канвы.
9. Приложение запускается, все разделы открываются; граф держит не менее 20 узлов без заметных задержек.
10. Прогон **в обоих окружениях** — без UI-зависимостей и с `customtkinter`/`pillow`/`psutil`; обе команды и оба результата в отчёте.
11. `ruff check .` чисто; release gate не ухудшен.
12. Отчёт: `BASE_SHA`, `FINAL_SHA`, изменённые файлы, что из документа реализовано, что исключено и почему, известные ограничения.
## Главное
Задача — не нарисовать красивый граф, а сделать так, чтобы владелец установил Hub, подключил аккаунт, увидел свою команду ролей, понял, кто чем исполняется и куда уйдёт запрос при исчерпании квоты. Граф — способ это показать и настроить, а не самоцель.
## Порядок сдачи
Передать точный `FINAL_COMMIT_SHA`.