Merge remote-tracking branch 'origin/main' into review/a7
This commit is contained in:
commit
8cddc9fee2
1 changed files with 137 additions and 0 deletions
137
agents/inbox/2026-08-21-B6-codex-routing-graph.md
Normal file
137
agents/inbox/2026-08-21-B6-codex-routing-graph.md
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
# Задание 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 должен быть демонстрируемо рабочим
|
||||
|
||||
Главное требование задания. Приложение ни разу не проходило полный путь с живым аккаунтом: все скриншоты сняты на пустой конфигурации, где везде `Н/Д` и «Критическое состояние».
|
||||
|
||||
**Что проверить и починить:**
|
||||
|
||||
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`.
|
||||
Loading…
Reference in a new issue