Конвеєри та автоматизація
Конвеєри — це детермінована половина Control Center. Агент вирішує, що сказати; конвеєр вирішує, що станеться далі, — і щоразу однаково. Конвеєр — це DAG із кроків, які вміють запускати агентів, виконувати скрипти, розгалужуватися за умовою, розпаралелювати роботу над колекцією й передавати дані між кроками — із збереженням стану, можливістю відновлення та обліком вартості.
Вони існують із трьох причин: щоб об’єднувати в ланцюжок повторюваний багатокроковий процес, щоб координувати кілька агентів послідовно чи паралельно та щоб реагувати на подію, яка сталася без участі людини.
Шаблони й запуски
Розділ із назвою «Шаблони й запуски»Шаблон (PipelineDefinition) — це декларативний DAG: кроки, оголошені входи
й конфігурація. Він живе у власній базі даних робочого простору. Запуск
(PipelineRun) — це одне виконання цього шаблону, яке несе змінний набір стану,
підсумки витрат і токенів та статус кожного кроку.
Один шаблон має багато запусків. Запуски переживають перезапуск: рушій перезавантажує запуски в процесі виконання й підхоплює їх там, де вони зупинилися.
Два запобіжники навмисно провалюють увесь запуск, а не відновлюють крок, бо відновлення було б гіршим за зупинку:
- Крок, який перебував у стані
suspendedдовше заsuspendedStepTimeout(типово 24 години), чекає на тікети, що ніколи не досягнуть кінцевого стану, тож його позначають як невдалий, щоб звільнити запуск. Виняток —extras['awaitApproval'] == true— це шлюз часткового схваленняorchestration.awaitApproval.human.gateпід виняток не підпадає. - Крок, оголошений як
extras: {'idempotent': false}, який був у процесі виконання, коли сервер зупинився, міг уже застосувати свій побічний ефект (squash-злиття, прибирання worktree). Повторний запуск міг би застосувати його двічі, тож рушій провалює його й залишає повторну спробу вам.
Тип планує, тіло виконує
Розділ із назвою «Тип планує, тіло виконує»Крок має дві ортогональні частини, і саме те, що їх тримають окремо, дає змогу рушію залишатися малим.
Тип (StepKind) каже рушієві коли крок стає готовим до виконання відносно
кроків, що стоять вище за потоком — це єдине, що потрібно знати планувальнику.
Їх шість: trigger, listen, join, router, forEach і terminal. Тіло
(bodyKey) — це робота, яку крок виконує, коли його заплановано. Тіла — це
замикання, зареєстровані за ключем під час запуску сервера, тож багато кроків
різних типів можуть мати спільне тіло: наприклад, кілька кроків listen, які всі
виконують conversation.promptAgent.
Оскільки семантика планування живе в шести типах, каталог поведінок може зростати, не торкаючись планувальника. Дивіться Типи кроків конвеєра, щоб побачити повний каталог типів, тіл та їхньої конфігурації.
Два наслідки реєстрового дизайну варто знати, перш ніж писати шаблон вручну:
- Крок, чий
bodyKeyне зареєстровано, видає попередження під час завантаження шаблону і потім ніколи не виконується. У час виконання ніщо не падає гучно. Крокиtriggerіterminalзвільнені від цього попередження: тригер усе одно виконує порожнє тілоpipeline.trigger, щоб спрацювали подальші слухачі; крокterminalне має тіла й слугує сторожовим елементом планувальника. - Ключі в мапі
extrasвузла зіставляються точно, інакше мовчки ігноруються. Лишеextras['spaceId']розміщує роботу кроку-агента в наявній розмові.extras['mode'](chat/plan/review) читається на вузлі, який відкриває кімнату (messaging.createSpace, типовоreview) — пізніший крок-агент не може повторно надати дозволи розмові, до якої він приєднався. Будь-яке інше написання будь-якого з цих ключів ігнорується.
Стан і потік даних
Розділ із назвою «Стан і потік даних»Кроки не викликають один одного. Вони читають зі спільного набору стану запуску
та пишуть до нього: крок читає свої входи за ключем, виконується й записує свій
вивід назад під власним outputKey. StateReducer об’єднує паралельні записи,
коли паралельні гілки пишуть в один ключ, а TemplateRenderer підставляє
плейсхолдери {{...}} у промпти та скрипти з того самого стану.
Саме тому конвеєр можна дослідити постфактум — набір стану розповідає всю історію запуску.
Що запускає конвеєр
Розділ із назвою «Що запускає конвеєр»Рядки PipelineTrigger оголошують, коли шаблон стартує автоматично. Є чотири
типи:
| Тригер | Запускає конвеєр, коли |
|---|---|
| Доменна подія | Спрацьовує відповідна доменна подія — наприклад PullRequestPublished або TicketAssigned |
| Розклад | Настає час, визначений виразом cron/інтервалу |
| Вручну | Ви запускаєте його власноруч; саме наявність увімкненого ручного тригера додає шаблон у селектор запуску |
| Вебхук | Зовнішня система надсилає POST на /webhooks/<token> на HTTP-порті сервера |
Тригери подій — це закрита множина: диспетчер знає 16 типів подій і пропонує їх у
селекторі (EventPayloadMapper.knownEventTypes), і ніщо інше не може запустити
конвеєр. Чотирнадцять із цих 16 мають зіставлення корисного навантаження. Два —
TicketCreated і TicketStatusChanged — не мають жодного, тож тригер на
будь-який із них залишається увімкненим і ніколи не спрацьовує. Дивіться
Доменні події, щоб побачити повний список.
Вебхук-токен водночас слугує секретом HMAC: заголовок запиту
X-Hub-Signature-256: sha256=<hex> перевіряється проти
HMAC-SHA256(body, token), неперевірені доставки відхиляються й не підлягають
повторному відтворенню, а дублікати відкидаються за dedupe_key. Оскільки рядки
тригерів унікальні за (робочий простір, тип події, шаблон), шаблон може мати
щонайбільше один вебхук-тригер і один тригер на кожен тип доменної події.
Вбудовані шаблони засіваються з увімкненими ручними тригерами й тригерами подій; тригери розкладу засіваються вимкненими, тож регулярний прогін завжди потрібно вмикати явно.
Шаблони, які постачаються вимкненими
Розділ із назвою «Шаблони, які постачаються вимкненими»Тринадцять шаблонів конвеєрів засіваються в кожен робочий простір, і вісім із
них постачаються вимкненими: external_pr_welcome, cross_review,
ticket_to_pr, pr_triage, pre_merge_gate, release_notes, dep_audit і
pr_digest.
Саме це найбільше дивує людей. Їхні тригери засіваються увімкненими, але
PipelineEngine.start відмовляється від вимкненого шаблону й повертає null — тож
тригер спрацьовує в порожнечу, і жоден запуск не з’являється. Перемикач — це
шаблон, а не тригер. Увімкніть його в Налаштування → Робочий простір → Шаблони конвеєрів, перш ніж
чекати, що котрийсь із цих восьми щось зробить.
Повторне засівання робочого простору зберігає все, що ви обрали: ваше
налаштування isEnabled та наявні рядки тригерів залишаються. Є рівно один
навмисний виняток — щоденний розклад pr_merged_cleanup примусово вмикається,
навіть якщо раніше був вимкнений, бо це збирання сміття. Без нього рядки
worktree, розділи графа коду та копії copy-on-write накопичуються, а це ніколи не
задумувалося як користувацький вибір.
Ще одна асиметрія, яку варто знати: вбудований pr_review навмисно більше не
публікує на GitHub. Публікація перевірки — це окремий крок, який контролює
користувач, а конвеєр, що публікував би напряму, опублікував би двічі.
cross_review, ticket_to_pr і pr_triage усе ще публікують коментар напряму в
GitHub, коли виконуються.
Що знає рушій
Розділ із назвою «Що знає рушій»PipelineEngine створює запис запуску, планує початковий вузол, що відповідає
типу події запуску, а потім обходить DAG: у міру завершення кроків він оцінює
тригери нижче за потоком, розв’язує гілки router, чекає на join, застосовує
політики повторних спроб і continue-on-fail та зберігає стан, вартість і помилки
на кожному кроці. Ребра, що виходять з іншого старту, для цього запуску
ігноруються, тож спрацьовування розкладу не чекає на умову, доступну лише вручну.
Чого він не знає — це будь-чого про тікети, диспетчеризацію, GitHub чи обмін
повідомленнями. Єдиний шов для розширення — це PipelineBodyRegistry. Саме тіла,
зареєстровані там, тримають AgentDispatchPort, MessagingPort та їхніх
супутників — тому додавання можливості до конвеєрів ніколи не означає зміни
планувальника.
Обробка помилок
Розділ із назвою «Обробка помилок»Крок, що падає, записує своє повідомлення про помилку й переходить у стан
failed. Якщо крок оголошує continueOnFail, наступні кроки продовжують
виконання, а помилка зберігається в стані запуску; інакше запуск завершується
невдачею. Крок із StepRetryPolicy спершу повторюється — з лінійною або
експоненційною затримкою, — перш ніж застосується будь-що з наведеного вище.
Дивіться також
Розділ із назвою «Дивіться також»- Доменні події: на що слухає тригер події
- Оркестрація: план, який ви схвалюєте, скомпільований в один із цих конвеєрів
- Тікети та делегування: що створюють і завершують кроки конвеєра
- Типи кроків конвеєра: повний каталог типів, тіл і конфігурації
- Зберіть свій перший конвеєр
- Створити шаблон конвеєра
- Запустити конвеєр вручну
- Моніторити запуски конвеєрів
- Налаштувати тригери конвеєра