Pipelines och automatisering
Pipelines är den deterministiska halvan av Control Center. En agent bestämmer vad som ska sägas; en pipeline bestämmer vad som händer härnäst, på samma sätt varje gång. En pipeline är en DAG av steg som kan skicka ut agenter, köra skript, förgrena på ett villkor, sprida ut över en samling och föra data mellan steg – beständig, återupptagbar och kostnadsberäknad.
De finns av tre skäl: att kedja ihop en repetitiv process med flera steg, att samordna flera agenter i följd eller parallellt och att reagera på något som har hänt utan att en människa är närvarande.
Mallar och körningar
Avsnitt med rubriken “Mallar och körningar”En mall (PipelineDefinition) är den deklarativa DAG:en: steg, deklarerade
indata och konfiguration. Den bor i arbetsytans egen databas. En körning
(PipelineRun) är en enskild körning av den mallen, och bär en föränderlig
tillståndsbehållare, summor för kostnad och tokens samt status per steg.
En mall har många körningar. Körningar överlever en omstart: motorn läser in pågående körningar igen och plockar upp dem där de stannade.
Två skyddsnät låter avsiktligt hela körningen misslyckas i stället för att återuppta ett steg, eftersom en återupptagning skulle vara värre än att stoppa:
- Ett steg som har varit
suspendedlängre änsuspendedStepTimeout(24 timmar som standard) väntar på ärenden som aldrig når ett terminalt tillstånd, och därför misslyckas det för att frigöra körningen. Undantaget ärextras['awaitApproval'] == true– det är grinden för delgodkännande,orchestration.awaitApproval.human.gateomfattas inte av undantaget. - Ett steg som deklarerats med
extras: {'idempotent': false}och som var mitt i körningen när servern stoppades kan redan ha tillämpat sin sidoeffekt (en squash-merge, en worktree-städning). Att köra om det skulle kunna tillämpa effekten två gånger, så motorn låter det misslyckas och lämnar återförsöket till dig.
Typen schemalägger, kroppen arbetar
Avsnitt med rubriken “Typen schemalägger, kroppen arbetar”Ett steg har två ortogonala delar, och att hålla dem åtskilda är det som gör att motorn kan förbli liten.
Typen (StepKind) talar om för motorn när ett steg blir körbart i
förhållande till sina uppströmssteg – det är det enda schemaläggaren behöver
veta. Det finns sex stycken: trigger, listen, join, router, forEach och
terminal. Kroppen (bodyKey) är det arbete steget utför när det väl har
schemalagts. Kroppar är closures som registreras per nyckel vid serverstart, så
många steg av olika typ kan dela på en kropp: flera listen-steg som alla kör
conversation.promptAgent, till exempel.
Eftersom schemaläggningssemantiken bor i sex typer kan katalogen av beteenden växa utan att någon rör schemaläggaren. Se Pipeline-stegtyper för den fullständiga katalogen över typer, kroppar och deras konfiguration.
Två konsekvenser av registerdesignen är värda att känna till innan du skriver en mall för hand:
- Ett steg vars
bodyKeyinte är registrerad ger en varning vid inläsning av mallen och körs sedan aldrig. Inget misslyckas högljutt vid körning.trigger- ochterminal-steg omfattas inte av den varningen: triggern kör fortfarande den verkanslösa kroppenpipeline.triggerså att nedströms lyssnare utlöses; ettterminal-steg har ingen kropp och är en markör för schemaläggaren. - Nycklar i en nods
extras-mapp matchas exakt och ignoreras i övrigt tyst. Baraextras['spaceId']placerar ett agentstegs arbete i ett befintligt samtal.extras['mode'](chat/plan/review) läses på den nod som öppnar rummet (messaging.createSpace, standardreview) – ett senare agentsteg kan inte ändra behörigheterna för ett samtal det har anslutit till. Varje annan stavning av någon av nycklarna ignoreras.
Tillstånd och dataflöde
Avsnitt med rubriken “Tillstånd och dataflöde”Steg anropar inte varandra. De läser från och skriver till en delad
tillståndsbehållare på körningen: ett steg läser sina indata per nyckel, kör och
skriver tillbaka sin utdata under sin egen outputKey. En StateReducer slår
ihop samtidiga skrivningar när parallella grenar riktar sig mot samma nyckel, och
en TemplateRenderer ersätter {{...}}-platshållare i prompter och skript med
värden från samma tillstånd.
Det är därför en pipeline går att granska i efterhand – tillståndsbehållaren är hela historien om körningen.
Vad som startar en körning
Avsnitt med rubriken “Vad som startar en körning”Rader av typen PipelineTrigger deklarerar när en mall startar automatiskt. Det
finns fyra typer:
| Trigger | Startar en körning när |
|---|---|
| Domänhändelse | En matchande domänhändelse utlöses – till exempel PullRequestPublished eller TicketAssigned |
| Schema | Ett cron- eller intervalluttryck blir dags |
| Manuell körning | Du kör den för hand; förekomsten av en aktiverad manuell trigger är det som gör att mallen dyker upp i körningsväljaren |
| Webhook | Ett externt system gör en POST till /webhooks/<token> på serverns HTTP-port |
Händelsetriggers är en sluten uppsättning: 16 händelsetyper är kända för
dispatcharen och erbjuds i väljaren (EventPayloadMapper.knownEventTypes), och
inget annat kan starta en pipeline. Fjorton av de 16 har en nyttolastsmappning.
Två – TicketCreated och TicketStatusChanged – har ingen, så en trigger på
någon av dem ligger aktiverad och utlöses aldrig. Se
Domänhändelser för hela listan.
Webhook-token fungerar även som HMAC-hemligheten: begärans header
X-Hub-Signature-256: sha256=<hex> verifieras mot HMAC-SHA256(body, token),
overifierade leveranser avvisas och kan inte spelas upp igen, och dubbletter
filtreras bort med dedupe_key. Eftersom triggerrader är unika på (arbetsyta,
händelsetyp, mall) kan en mall ha högst en webhook-trigger och en trigger per
domänhändelsetyp.
De inbyggda mallarna sås med manuella och händelsebaserade triggers aktiverade; schemalagda triggers sås inaktiverade, så ett återkommande svep är alltid opt-in.
Mallarna som levereras inaktiverade
Avsnitt med rubriken “Mallarna som levereras inaktiverade”Tretton pipelinemallar sås in i varje arbetsyta och åtta av dem levereras
inaktiverade: external_pr_welcome, cross_review, ticket_to_pr,
pr_triage, pre_merge_gate, release_notes, dep_audit och pr_digest.
Det här är delen som förvånar folk. Deras triggers sås aktiverade, men
PipelineEngine.start vägrar en inaktiverad mall och returnerar null – så
triggern utlöses i tomma intet och ingen körning dyker upp. Det är mallen, inte
triggern, som är strömbrytaren. Aktivera den under Inställningar → Arbetsyta →
Pipelinemallar innan du förväntar dig att någon av de åtta ska göra något.
Att så om en arbetsyta bevarar det du har valt: din inställning isEnabled och
dina befintliga triggerrader överlever. Det finns exakt ett medvetet undantag –
pr_merged_cleanups dagliga schema tvingas aktiverat även om det tidigare var
avstängt, eftersom det är skräpsamling. Worktree-rader, kodgrafspartitioner och
copy-on-write-kopior ackumuleras utan det, och det var aldrig tänkt som ett
användarval.
Ännu en asymmetri värd att känna till: den inbyggda pr_review publicerar
medvetet inte längre till GitHub. Att publicera en granskning är ett separat steg
som en användare styr, och en pipeline som publicerade direkt skulle
dubbelpublicera. cross_review, ticket_to_pr och pr_triage publicerar
fortfarande en kommentar direkt till GitHub när de körs.
Vad motorn känner till
Avsnitt med rubriken “Vad motorn känner till”PipelineEngine skapar körningsposten, schemalägger startnoden som matchar
körningens händelsetyp och vandrar sedan genom DAG:en: i takt med att steg
slutförs utvärderar den nedströms triggers, löser upp routergrenar, väntar på
joins, tillämpar återförsökspolicyer och continue-on-fail samt sparar tillstånd,
kostnad och fel vid varje steg. Kanter som lämnar en annan start ignoreras för
den körningen, så en schemautlösning väntar inte på ett villkor som bara gäller
manuell körning.
Vad den inte känner till är något om ärenden, dispatch, GitHub eller
meddelanden. Dess enda utökningssöm är PipelineBodyRegistry. Det är kropparna
som registreras där som håller AgentDispatchPort, MessagingPort och deras
syskon – vilket är varför en ny förmåga i pipelines aldrig innebär att
schemaläggaren behöver ändras.
Felhantering
Avsnitt med rubriken “Felhantering”Ett steg som misslyckas registrerar sitt felmeddelande och går till failed. Om
steget deklarerar continueOnFail fortsätter nedströms steg och felet sparas
undan i körningens tillstånd; annars misslyckas körningen. Ett steg med en
StepRetryPolicy görs om först, med linjär eller exponentiell backoff, innan
något av det andra träder in.
- Domänhändelser: vad en händelsetrigger lyssnar på
- Orkestrering: en plan du godkänner, kompilerad till en pipeline av det här slaget
- Ärenden och delegering: vad pipeline-steg skapar och slutför
- Pipeline-stegtyper: den fullständiga katalogen över typer, kroppar och konfiguration
- Bygg din första pipeline
- Skapa en pipelinemall
- Kör en pipeline manuellt
- Övervaka pipelinekörningar
- Ställ in pipelinetriggers