Ga naar inhoud

Pipeline-stapsoorten

Een pipelinestap heeft twee onafhankelijke assen:

  • Kind (StepKind) — hoe de engine de stap plant ten opzichte van zijn triggers.
  • Body-sleutel (BuiltInBodyKeys) — welke geregistreerde body-closure het werk van de stap uitvoert.

Gedefinieerd in packages/cc_domain/lib/features/pipelines/domain/entities/step_kind.dart.

Kind Planningssemantiek
trigger Verplicht ingangspunt — precies één per sjabloon, altijd de eerste node. Doet zelf geen werk; wat de run start (handmatig / gebeurtenis / schema) wordt apart bijgehouden als PipelineTrigger-rijen. De body is de no-op pipeline.trigger.
listen Gaat af wanneer alle bronstappen (in StepTrigger.sourceStepIds) klaar zijn.
join Gaat af wanneer alle stappen in waitForStepIds een eindtoestand bereiken.
router Voorwaardelijke vertakking — de body geeft StepResult.route(key) terug, waardoor alleen de stroomafwaartse rand afgaat waarvan de routeKey overeenkomt; niet-geselecteerde takken worden als overgeslagen gemarkeerd.
forEach Wordt net als listen gepland (gaat af wanneer alle sourceStepIds klaar zijn). De geregistreerde body flow.forEach is wat itereert; de engine maakt niet per item een kindstap aan.
terminal Sentinel voor de scheduler zonder body. De pipelinerun is voltooid wanneer een terminale stap klaar is.

Geregistreerde body-closures, gesleuteld op de constanten in BuiltInBodyKeys (packages/cc_domain/lib/features/pipelines/domain/templates/builtin_template_seeds.dart). Er zijn er 25, allemaal hieronder vermeld. De configuratie wordt gelezen uit de PipelineNodeConfig van de stap (zie hieronder), tenzij anders vermeld; “statussleutels” worden op uitvoeringstijd gelezen uit de pipelinestatus of de triggerpayload.

Een stap waarvan de bodyKey niet is geregistreerd, geeft een waarschuwing bij het laden van het sjabloon en wordt daarna nooit uitgevoerd — de run mislukt er niet door. trigger- en terminal-stappen vallen niet onder die waarschuwing: de trigger voert nog steeds de no-op-body pipeline.trigger uit; een terminal-stap heeft geen body.

No-op-body van de verplichte trigger-node — voltooit onmiddellijk, zodat de engine naar stroomafwaartse luisteraars uitwaaiert. Geen configuratie.

Agentloze shellstap (bash -c). {{key}}-placeholders in het script worden vervangen door shell-geëscapete waarden uit de status en de triggerpayload.

Configuratieveld Beschrijving
script Uit te voeren shellopdracht (verplicht)
outputKey Statussleutel die bij exitcode 0 de getrimde stdout ontvangt

Draait met cwd <cc_root>/pipelines/<pipelineRunId>/ (gedeeld door alle bash-stappen in een run) en GITHUB_TOKEN in de omgeving. Schrijft ook <stepId>_runDir naar de status. Een exitcode anders dan nul laat de stap mislukken met de staart van stderr.

Algemene prompt-en-dispatch-node: rendert de prompt, dispatcht de agent naar een gesprek en blijft onderbroken tot de run klaar is. De submit_output-payload van de agent wordt onder outputKey in de status opgehaald.

Configuratieveld Beschrijving
agentId Werkruimtegebonden agent-UUID om te dispatchen (verplicht)
prompt Instructietekst; ondersteunt {{key}}-substitutie (verplicht)
outputKey Statussleutel voor de opgehaalde uitvoer
outputSchema JSON Schema waaraan de uitvoer moet voldoen
label Menselijk label dat op het canvas wordt getoond
extras.spaceId Bestaand gesprek om in te werken (standaard: een verborgen gesprek)
extras.conversationTitle Benoemde stroom binnen die ruimte (optioneel)
extras.mode Wordt gelezen op de node die de ruimte opent (messaging.createSpace), niet hier. Standaard review.

Routerbody — leest config.extras, evalueert een voorwaarde en geeft StepResult.route(key) terug. Voorwaarden zijn geen JavaScript-expressies; er worden drie schrijfvormen ondersteund, in volgorde van prioriteit:

  • Predicaatboom (extras.predicate) — een booleaanse boom die routeert naar "true" / "false". Elke node is een map met een type:
    • {"type": "fileExists", "paths": [...], "baseKey": "repo_local_path", "negate": false, "recursive": false} — waar als een van de opgegeven paden op schijf bestaat; negate keert dat om; recursive doorzoekt ook submappen (met overslaan van .git, node_modules, build, .dart_tool). Relatieve paden worden opgelost tegen state[baseKey] (standaard repo_local_path), anders tegen de werkmap van de run.
    • {"type": "comparison", "left": "{{score}}", "op": "gt", "right": 80} — operatoren equals, notEquals, contains, exists, notExists, gt, lt; leest de pipelinestatus, niet het bestandssysteem.
    • {"type": "and" | "or", "of": [<predicate>, ...]} — booleaanse groepen.
    • {"type": "not", "of": <predicate>} — negatie.
  • Schakelaar (extras.switchKey) — {"switchKey": "pr_class", "cases": [...], "default": "standard"}; routeert naar het eerste geval dat de statuswaarde zonder onderscheid van hoofdletters en kleine letters bevat, anders naar default.
  • Vergelijking (verouderde velden op het hoogste niveau extras.left / extras.op / extras.right) — gelijkwaardig aan een comparison-predicaat, behouden voor sjablonen die zijn gemaakt vóór de boom.

Randen die uit de node vertrekken, dragen een routeKey die moet overeenkomen met de teruggegeven sleutel.

Plaatst de gebundelde bevindingen als PR-reviewcommentaar via de GitHub-PR-client.

Statussleutel Beschrijving
repo_full_name owner/repo (verplicht)
pr_number PR-nummer — int of numerieke tekenreeks (verplicht)
consolidated_findings Commentaartekst (verplicht)

Geeft StepResult.terminal terug met comment_review_id en commented_at in de status.

Plaatst een bericht in een berichtenruimte via MessagingPort.

Statussleutel Beschrijving
space_id Doelruimte (verplicht)
content Berichttekst, letterlijk uit de status gelezen (verplicht)

Schrijft posted_space_id en posted_at naar de status.

Dispatcht een heel team in plaats van één agent en blijft daarna onderbroken tot de runs van de leden klaar zijn.

Configuratieveld Beschrijving
teamId Werkruimtegebonden team om te dispatchen (verplicht; wederzijds uitsluitend met agentId)
prompt Doeltekst; ondersteunt {{key}}-substitutie (verplicht)
dispatchMode allParallel (standaard — één taak per lid) of manager (dispatch alleen de leider om te coördineren)
outputKey Statussleutel voor de opgehaalde uitvoer van de leden
outputSchema, label, extras.spaceId Zoals bij conversation.promptAgent

Goedkeuringspoort. Dispatcht de goedkeurder-agent met de poortprompt naar een gesprek (reviewmodus) en met een uitvoercontract {decision, reason}, en blijft daarna onderbroken tot de goedkeurder indient via submit_output.

Configuratieveld Beschrijving
agentId De goedkeurder-agent (verplicht)
prompt Poortprompt (optioneel; bij afwezigheid wordt een standaard gebruikt)
outputKey Statussleutel voor de opgehaalde payload {decision, reason}
outputSchema Standaard een goedkeuringsschema (decision: approved / rejected, reason)
label, extras.spaceId Zoals bij conversation.promptAgent

De poort wordt uitsluitend via submit_output opgelost. BuiltInBodyKeys.humanGate, de nodetype-bibliotheek en de prompttekst van één ingebouwd sjabloon noemen allemaal de MCP-tools approve_step en reject_step; geen van beide tools bestaat in welk pakket of register dan ook.

Verwijdert verouderde geïsoleerde worktrees; kiest zijn modus op basis van de triggerpayload. Respecteert de dryRun-markering van de run.

Statussleutel Beschrijving
ticket_id Geeft de worktrees van dat ticket vrij
repo_full_name + pr_number Geeft de tijdelijke PR-editor-worktree vrij
space_id Breekt de worktrees en de map van dat gesprek af
(geen van bovenstaande) Veegt de werkruimte schoon: verdwenen mappen, dode ruimtes, verweesde gespreksmappen

outputKey (optioneel) ontvangt een samenvattende tekenreeks.

Map / fan-out over een statusverzameling: rendert de prompt één keer per item en dispatcht de agent daarna één keer met die prompts aan elkaar (gescheiden door ---), en blijft onderbroken tot die run klaar is. Een lege verzameling voltooit direct met een lege lijst. Het is geen aparte parallelle dispatch per item.

Configuratieveld Beschrijving
agentId Agent om per item te dispatchen (verplicht)
prompt Prompt per item; ondersteunt {{key}}-substitutie (verplicht)
extras.iterableKey Statussleutel met de verzameling (verplicht)
extras.itemKey Sleutel waaraan het huidige item in de prompt is gebonden (standaard item)
outputKey Statussleutel voor de opgehaalde uitvoer (één dispatch, geen lijst)

Voert een ander pipelinesjabloon uit als geneste substap (de subpipeline draait als kindrun met parentPipelineRunId ingesteld). De stap blijft onderbroken tot het kind een eindtoestand bereikt; daarna wordt de eindstatus van het kind onder outputKey samengevoegd.

Configuratieveld Beschrijving
extras.templateId Uit te voeren kindsjabloon (verplicht; een pipeline kan zichzelf niet aanroepen)
inputKeys Statussleutels die naar de triggerpayload van het kind worden gekopieerd
outputKey Statussleutel voor de samengevoegde eindstatus van het kind

Achtergrondindexering met tree-sitter: loopt een repo door, extraheert symbolen en randen in worker-isolates en neemt ze op in de codegraaf van de werkruimte. Streamt de voortgang naar de rij van de stap-run; ondersteunt dry-run. Tree-sitter en zijn grammatica’s zijn vereiste natives — een ontbrekende dylib betekent dat de server nooit is opgestart, en een grammatica die tijdens de run niet kan worden gevonden laat de stap mislukken in plaats van hem over te slaan.

Statussleutel Beschrijving
repo_id Te indexeren repo (verplicht)
repo_local_path Lokaal pad van de checkout (verplicht)

Offline sprekersscheiding. Leest de bewaarde audio van de vergadering, clustert die in sprekers (Person 1, Person 2, …), voorziet de transcriptsegmenten opnieuw van labels en herschrijft de status transcript; levert ook diarization_spans op voor de parallelle stap meeting.updateTranscript. Geeft het transcript ongewijzigd door wanneer er geen audio is bewaard of de modellen niet zijn geïnstalleerd.

Statussleutel Beschrijving
meeting_id Te diarizeren vergadering (verplicht)

meeting.saveNotes, meeting.addActionItems, meeting.addDecisions

Sectie getiteld “meeting.saveNotes, meeting.addActionItems, meeting.addDecisions”

Deterministische bodies om de vergaderingsamenvatting vast te leggen. Elk leest meeting_id en de gestructureerde payload meeting_outcome van de agentstap ({summary, enhancedNotes, actionItems[], decisions[]}) uit de status en schrijft zijn eigen deel naar zijn eigen tabel — notities, actiepunten of beslissingen. Eerder opgeslagen rijen worden bij een gedegradeerde run nooit gewist.

Body-sleutel Beschrijving
meeting.identifySpeakers Sprekersherkenning over vergaderingen heen: matcht gediariseerde sprekers tegen opgeslagen stemprofielen en past zekere overeenkomsten automatisch toe. No-op zonder profielen of embeddings.
meeting.updateTranscript Past de labels Person N uit diarization_spans toe, voegt fragmenten per venster samen tot beurten per spreker en legt daarna het opgeschoonde transcript vast. No-op wanneer de sprekersscheiding niets heeft opgeleverd.
meeting.assemblePlayback Stelt het gemengde afspeelspoor van de vergadering samen uit de bewaarde WAV’s per kanaal. No-op wanneer er geen audio is bewaard.
orchestration.markPhase Schrijft aan het einde van de werk-DAG mislukkings-sentinels voor subtickets zonder uitvoer en zet de orkestratie om naar synthesizing.
orchestration.persistDeliverable Schrijft de uitvoer van de synthese naar het bovenliggende ticket, rondt dat af, plaatst het eindresultaat en markeert de orkestratie als completed.
orchestration.awaitApproval Poort voor gedeeltelijke goedkeuring: voltooit onmiddellijk wanneer de nodesleutel van de stap in de goedgekeurde verzameling van de orkestratie zit, en blijft anders onderbroken tot een latere goedkeuring hem hervat. Dit is de enige body die extras.awaitApproval instelt, wat hem uitzondert van de time-out van 24 uur voor onderbroken stappen.
messaging.createSpace Opent het gesprek waarin de rest van het sjabloon werkt, gepubliceerd onder de outputKey van de stap (ingebouwde sjablonen gebruiken pipeline_space_id). Een lege lijst repoIds checkt niets uit; extras['allRepos'] checkt elke repo van de werkruimte uit. extras['createConversation'] (standaard uit) opent ook een benoemde stroom. Een agentstap VOEGT ZICH BIJ een ruimte en opent er nooit een, dus een fan-out zonder deze node mislukt bij het dispatchen — en hem één keer aansluiten betekent dat de hele fan-out één checkout deelt in plaats van dat er voor elk een wordt ingericht.
prReview.finalize De laatste stap van het PR-reviewsjabloon: sorteert de verzamelde reviewnodes in consensusgroepen en berekent het oordeel per PR.
skills.analyze Draait de toeleveringsketenscan voor skills over de geïnstalleerde skills van een werkruimte en legt elk oordeel vast.

Een stapbody geeft een StepResult terug (packages/cc_domain/lib/features/pipelines/domain/entities/step_result.dart). Alle factories accepteren een optionele map mutatedState die in de pipelinestatus wordt samengevoegd, behalve failed.

Factory Signatuur Beschrijving
ok StepResult.ok({mutatedState}) Normale voltooiing; stroomafwaartse luisteraars worden geëvalueerd
route StepResult.route(nextRouterKey, {mutatedState}) Voltooiing van de router; selecteert de stroomafwaartse tak waarvan de routeKey overeenkomt
suspendUntilEvent StepResult.suspendUntilEvent(eventType, {mutatedState}) Pauzeert tot een specifiek type domeingebeurtenis optreedt
suspendUntilTasksComplete StepResult.suspendUntilTasksComplete(taskIds, {mutatedState}) Pauzeert tot alle vermelde taken een eindtoestand bereiken
terminal StepResult.terminal({mutatedState}) De pipelinerun is klaar — geen verdere stappen
failed StepResult.failed(errorMessage) De stap is mislukt met een foutmelding

Herkansingsgedrag voor een mislukkende nodebody (PipelineNodeConfig.retryPolicy; null schakelt herkansingen uit).

Veld Type Beschrijving
maxAttempts int Totaal aantal pogingen inclusief de eerste (3 = 1 poging + 2 herkansingen); moet ≥ 1 zijn
backoff String linear of exponential (standaard)
initialDelayMs int Vertraging vóór de eerste herkansing, in milliseconden; latere vertragingen groeien volgens backoff

Configuratie per node, meegevoerd in de stapdefinitie (packages/cc_domain/lib/features/pipelines/domain/entities/pipeline_node_config.dart). Ingebouwde en aangepaste nodes delen deze vorm; elke body leest alleen de velden die hij nodig heeft.

Veld Type Beschrijving
prompt String? Prompttemplate met {{key}}-substitutie
script String? Body van het bash-script met {{key}}-substitutie
agentId String? Werkruimtegebonden agent-UUID om te dispatchen
inputKeys List<String> Statussleutels die deze node als invoer gebruikt
repoIds List<String> Repo’s die de node messaging.createSpace uitcheckt (<repoId> of <repoId>@<branch>). Leeg = geen enkele; extras['allRepos'] = elke repo van de werkruimte. Genegeerd op agentstappen.
outputKey String? Statussleutel waaronder de uitvoer van deze node wordt geschreven
label String? Menselijk label dat op het canvas wordt getoond (standaard de stap-ID)
outputSchema Map<String, dynamic>? JSON Schema (deelverzameling) waaraan de uitvoerwaarde moet voldoen
reducer String? Samenvoegstrategie wanneer parallelle takken naar dezelfde outputKey schrijven: append, mergeLists, mergeMaps, sum of override (standaard)
retryPolicy StepRetryPolicy? Herkansingsbeleid bij een mislukte body; null = één poging
continueOnFail bool Wanneer waar, laat een terminale mislukking de run niet mislukken; de fout wordt opgeborgen onder state['_stepErrors'][stepId]
timeoutMs int? Time-out op wandkloktijd voor de nodebody, in milliseconden; null = geen time-out
teamId String? Team om te dispatchen (team.dispatch-nodes); wederzijds uitsluitend met agentId
dispatchMode String? Uitvoeringsmodus van het team: allParallel of manager
extras Map<String, dynamic> Vrije body-specifieke configuratie (bijvoorbeeld iterableKey, templateId, voorwaardebomen)

Afgeleide accessors: spaceId (extras['spaceId'] — bestaand gesprek om in te werken), createsConversation (extras['createConversation']), conversationTitle (extras['conversationTitle']), modeName (extras['mode'] — chat / review / plan, gelezen op de ruimteopenende node) en runWhen (extras['runWhen'] — sla de node over wanneer niet voldaan).