Hoppa till innehåll

Pipeline-stegtyper

Ett pipelinesteg har två oberoende axlar:

  • Typ (StepKind) – hur motorn schemalägger steget i förhållande till dess triggers.
  • Kroppsnyckel (BuiltInBodyKeys) – vilken registrerad kropp som utför stegets arbete.

Definierade i packages/cc_domain/lib/features/pipelines/domain/entities/step_kind.dart.

Typ Schemaläggningssemantik
trigger Obligatorisk ingångspunkt – exakt en per mall, alltid den första noden. Utför inget arbete själv; det som startar körningen (manuellt / händelse / schema) spåras separat som rader av typen PipelineTrigger. Dess kropp är den verkanslösa pipeline.trigger.
listen Utlöses när alla källsteg (i StepTrigger.sourceStepIds) har slutförts.
join Utlöses när alla steg i waitForStepIds når ett terminalt tillstånd.
router Villkorlig förgrening – kroppen returnerar StepResult.route(key), vilket bara utlöser den nedströms kant vars routeKey matchar; ovalda grenar markeras som överhoppade.
forEach Schemaläggs som listen (utlöses när alla sourceStepIds har slutförts). Det är den registrerade kroppen flow.forEach som itererar; motorn skapar inte ett understeg per objekt.
terminal Markör för schemaläggaren utan kropp. Pipelinekörningen slutförs när ett terminalsteg är klart.

Registrerade kroppar (closures) som nycklas av konstanterna i BuiltInBodyKeys (packages/cc_domain/lib/features/pipelines/domain/templates/builtin_template_seeds.dart). Det finns 25 stycken, alla listade nedan. Konfigurationen läses från stegets PipelineNodeConfig (se nedan) om inget annat anges; ”tillståndsnycklar” läses från pipelinens tillstånd / triggerns nyttolast vid körning.

Ett steg vars bodyKey inte är registrerad ger en varning vid inläsning av mallen och körs sedan aldrig – det får inte körningen att misslyckas. Stegen trigger och terminal omfattas inte av den varningen: triggern kör fortfarande den verkanslösa kroppen pipeline.trigger; ett terminal-steg har ingen kropp.

Verkanslös kropp till den obligatoriska noden trigger – slutförs direkt så att motorn kan sprida ut arbetet till nedströms lyssnare. Ingen konfiguration.

Shellsteg utan agent (bash -c). Platshållare av typen {{key}} i skriptet ersätts från tillstånd och triggerns nyttolast med shell-escapeade värden.

Konfigurationsfält Beskrivning
script Shellkommando att köra (obligatoriskt)
outputKey Tillståndsnyckel som tar emot trimmad stdout vid exit 0

Körs med cwd <cc_root>/pipelines/<pipelineRunId>/ (delas av alla bash-steg i en körning) och GITHUB_TOKEN i miljön. Skriver även <stepId>_runDir till tillståndet. En exit-kod som inte är noll får steget att misslyckas med slutet av stderr som felmeddelande.

Generisk nod för prompt och utskick: renderar prompten, skickar ut agenten i ett samtal och pausar tills körningen är klar. Agentens nyttolast från submit_output samlas in i tillståndet under outputKey.

Konfigurationsfält Beskrivning
agentId Arbetsytebunden agent-UUID att skicka ut (obligatoriskt)
prompt Instruktionstext; stöder {{key}}-ersättning (obligatoriskt)
outputKey Tillståndsnyckel för den insamlade utdatan
outputSchema JSON-schema som utdatan måste uppfylla
label Mänsklig etikett som visas på duken
extras.spaceId Befintligt samtal att arbeta i (standard: ett dolt)
extras.conversationTitle Namngiven ström i den ytan (valfritt)
extras.mode Läses på den nod som öppnar rummet (messaging.createSpace), inte här. Standard review.

Kropp för routern – läser config.extras, utvärderar ett villkor och returnerar StepResult.route(key). Villkor är inte JavaScript-uttryck; tre sätt att skriva dem stöds, i prioritetsordning:

  • Predikatträd (extras.predicate) – ett booleskt träd som dirigerar "true" / "false". Varje nod är en map med ett type:
    • {"type": "fileExists", "paths": [...], "baseKey": "repo_local_path", "negate": false, "recursive": false} – sant när någon av de angivna sökvägarna finns på disken; negate vänder på det; recursive söker även i underkataloger (och hoppar över .git, node_modules, build, .dart_tool). Relativa sökvägar löses mot state[baseKey] (standard repo_local_path), annars mot arbetsytans katalog för körningen.
    • {"type": "comparison", "left": "{{score}}", "op": "gt", "right": 80} – operatorer equals, notEquals, contains, exists, notExists, gt, lt; läser pipelinens tillstånd, inte filsystemet.
    • {"type": "and" | "or", "of": [<predicate>, ...]} – booleska grupper.
    • {"type": "not", "of": <predicate>} – negation.
  • Switch (extras.switchKey) – {"switchKey": "pr_class", "cases": [...], "default": "standard"}; dirigerar till det första fall som tillståndsvärdet innehåller utan hänsyn till skiftläge, annars default.
  • Jämförelse (äldre toppnivå: extras.left / extras.op / extras.right) – likvärdig med predikatet comparison, finns kvar för mallar som skrevs innan trädet.

Kanter ut från noden bär en routeKey som måste matcha den returnerade nyckeln.

Publicerar de sammanställda fynden som en PR-granskningskommentar via GitHub-PR-klienten.

Tillståndsnyckel Beskrivning
repo_full_name owner/repo (obligatoriskt)
pr_number PR-nummer – int eller numerisk sträng (obligatoriskt)
consolidated_findings Kommentarens brödtext (obligatoriskt)

Returnerar StepResult.terminal med comment_review_id och commented_at i tillståndet.

Publicerar ett meddelande till en meddelandeyta via MessagingPort.

Tillståndsnyckel Beskrivning
space_id Målyta (obligatoriskt)
content Meddelandets brödtext, läses ordagrant från tillståndet (obligatoriskt)

Skriver posted_space_id och posted_at till tillståndet.

Skickar ut ett helt team i stället för en enskild agent och pausar sedan tills medlemmarnas körningar är klara.

Konfigurationsfält Beskrivning
teamId Arbetsytebundet team att skicka ut (obligatoriskt; ömsesidigt uteslutande mot agentId)
prompt Måltext; stöder {{key}}-ersättning (obligatoriskt)
dispatchMode allParallel (standard – en uppgift per medlem) eller manager (skicka bara ledaren, som samordnar)
outputKey Tillståndsnyckel för medlemmarnas insamlade utdata
outputSchema, label, extras.spaceId Som för conversation.promptAgent

Godkännandegrind. Skickar ut godkännaragenten i ett samtal (review-läget) med grindens prompt och ett utdatakontrakt {decision, reason} och pausar sedan tills godkännaren skickar in via submit_output.

Konfigurationsfält Beskrivning
agentId Godkännaragenten (obligatoriskt)
prompt Grindens prompt (valfritt; en standard används när det saknas)
outputKey Tillståndsnyckel för den insamlade nyttolasten {decision, reason}
outputSchema Standard är ett godkännandeschema (decision: approved / rejected, reason)
label, extras.spaceId Som för conversation.promptAgent

Grinden avgörs bara genom submit_output. BuiltInBodyKeys.humanGate, biblioteket över nodtyper och prompttexten i en av de inbyggda mallarna namnger alla MCP-verktygen approve_step och reject_step; inget av verktygen finns i något paket eller register.

Tar bort föråldrade avskilda worktrees; väljer sitt läge utifrån triggerns nyttolast. Respekterar körningens flagga dryRun.

Tillståndsnyckel Beskrivning
ticket_id Frigör ärendets worktrees
repo_full_name + pr_number Frigör den tillfälliga PR-redigerarens worktree
space_id Riv ner det samtalets worktrees och mapp
(inget av ovanstående) Svep arbetsytan: försvunna kataloger, döda ytor, föräldralösa samtalsmappar

outputKey (valfritt) tar emot en sammanfattande sträng.

Map / fan-out över en samling i tillståndet: renderar prompten en gång per objekt och skickar sedan ut agenten en gång med dessa prompter sammanfogade (--- som avgränsare) och pausar tills den körningen är klar. En tom samling slutförs direkt med en tom lista. Det är inte ett parallellt utskick per objekt.

Konfigurationsfält Beskrivning
agentId Agent att skicka ut per objekt (obligatoriskt)
prompt Prompt per objekt; stöder {{key}}-ersättning (obligatoriskt)
extras.iterableKey Tillståndsnyckel som innehåller samlingen (obligatoriskt)
extras.itemKey Nyckeln som det aktuella objektet binds till i prompten (standard item)
outputKey Tillståndsnyckel för den insamlade utdatan (ett utskick, inte en lista)

Kör en annan pipelinemall som ett nästlat delsteg (underpipelines körs som en barnkörning med parentPipelineRunId satt). Steget pausar tills barnet når ett terminalt tillstånd; därefter slås barnets sluttillstånd ihop under outputKey.

Konfigurationsfält Beskrivning
extras.templateId Barnmall att köra (obligatoriskt; en pipeline kan inte anropa sig själv)
inputKeys Tillståndsnycklar som kopieras in i barnets triggernyttolast
outputKey Tillståndsnyckel för barnets sammanslagna sluttillstånd

Bakgrundsindexering med tree-sitter: går igenom ett repo, extraherar symboler/kanter i worker-isolates och matar in dem i arbetsytans kodgraf. Strömmar förlopp till stegets körningsrad; stöder dry-run. Tree-sitter och dess grammatiker är nödvändiga native-bibliotek – en saknad dylib betyder att servern aldrig startade, och en grammatik som inte kan lösas upp mitt i körningen får steget att misslyckas i stället för att hoppas över.

Tillståndsnyckel Beskrivning
repo_id Repo att indexera (obligatoriskt)
repo_local_path Lokal sökväg till utcheckningen (obligatoriskt)

Offline-talarseparation. Läser mötets bevarade ljud, klustrar det till talare (Person 1, Person 2, …), märker om transkriptets segment och skriver om tillståndet transcript; avger även diarization_spans till det parallella steget meeting.updateTranscript. Skickar transkriptet oförändrat vidare när inget ljud bevarades eller modellerna inte är installerade.

Tillståndsnyckel Beskrivning
meeting_id Möte att separera talare i (obligatoriskt)

meeting.saveNotes, meeting.addActionItems, meeting.addDecisions

Avsnitt med rubriken “meeting.saveNotes, meeting.addActionItems, meeting.addDecisions”

Deterministiska kroppar som sparar mötessammanfattningen. Var och en läser meeting_id och agentstegets strukturerade nyttolast meeting_outcome ({summary, enhancedNotes, actionItems[], decisions[]}) från tillståndet och skriver sin del till sin egen tabell – anteckningar, åtgärdspunkter eller beslut. Rader som sparats tidigare raderas aldrig vid en degraderad körning.

Kroppsnyckel Beskrivning
meeting.identifySpeakers Taligenkänning över möten: matchar separerade talare mot sparade röstprofiler och tillämpar säkra matchningar automatiskt. Verkar inte utan profiler/embeddingar.
meeting.updateTranscript Tillämpar etiketterna Person N från diarization_spans och slår ihop fragment per fönster till turer per talare och sparar sedan det rensade transkriptet. Verkar inte när talarseparationen inte gav något.
meeting.assemblePlayback Sätter ihop mötets mixade uppspelningsspår från bevarade WAV-filer per kanal. Verkar inte när inget ljud bevarades.
orchestration.markPhase I slutet av arbets-DAG:en skriver den felmarkörer för underärenden utan utdata och växlar orkestreringen till synthesizing.
orchestration.persistDeliverable Skriver syntesutdatan till föräldraärendet, slutför det, publicerar leveransen och markerar orkestreringen som completed.
orchestration.awaitApproval Grind för delgodkännande: slutförs direkt när stegets nodnyckel finns i orkestreringens godkända mängd, annars pausar den tills ett senare godkännande återupptar den. Detta är den enda kroppen som sätter extras.awaitApproval, vilket befriar den från timeoutern på 24 timmar för pausade steg.
messaging.createSpace Öppnar samtalet som resten av mallen arbetar i, publicerat under stegets outputKey (inbyggda använder pipeline_space_id). En tom lista repoIds checkar inte ut något; extras['allRepos'] checkar ut alla arbetsytans repos. extras['createConversation'] (av som standard) öppnar dessutom en namngiven ström. Ett agentsteg GÅR MED i ett rum och öppnar aldrig ett, så en fan-out utan den här noden misslyckas vid utskicket – och kopplar du in den en gång delar hela fan-outen på en utcheckning i stället för att skaffa en var.
prReview.finalize Det sista steget i PR-granskningsmallen: sorterar de ackumulerade granskningsnoderna i konsensusgrupper och beräknar utlåtandet för PR:en.
skills.analyze Kör leverantörskedjeskanningen av en arbetsytas installerade skills och registrerar varje utlåtande.

En stegkropp returnerar en StepResult (packages/cc_domain/lib/features/pipelines/domain/entities/step_result.dart). Alla fabriker tar emot en valfri mutatedState-map som slås ihop med pipelinens tillstånd, utom failed.

Fabrik Signatur Beskrivning
ok StepResult.ok({mutatedState}) Normalt slutförande; nedströms lyssnare utvärderas
route StepResult.route(nextRouterKey, {mutatedState}) Routerns slutförande; väljer den nedströms gren vars routeKey matchar
suspendUntilEvent StepResult.suspendUntilEvent(eventType, {mutatedState}) Pausar tills en specifik domänhändelsetyp utlöses
suspendUntilTasksComplete StepResult.suspendUntilTasksComplete(taskIds, {mutatedState}) Pausar tills alla angivna uppgifter når ett terminalt tillstånd
terminal StepResult.terminal({mutatedState}) Pipelinekörningen är klar – inga fler steg
failed StepResult.failed(errorMessage) Steget misslyckades med ett felmeddelande

Återförsöksbeteende för en nodkropp som misslyckas (PipelineNodeConfig.retryPolicy; null stänger av återförsök).

Fält Typ Beskrivning
maxAttempts int Totalt antal försök inklusive det första (3 = 1 försök + 2 återförsök); måste vara ≥ 1
backoff String linear eller exponential (standard)
initialDelayMs int Fördröjning före första återförsöket, i millisekunder; senare fördröjningar växer enligt backoff

Konfiguration per nod som bärs inuti stegdefinitionen (packages/cc_domain/lib/features/pipelines/domain/entities/pipeline_node_config.dart). Både inbyggda och anpassade noder delar den här formen; varje kropp läser bara de fält den bryr sig om.

Fält Typ Beskrivning
prompt String? Promptmall med {{key}}-ersättning
script String? Bash-skriptets kropp med {{key}}-ersättning
agentId String? Arbetsytebunden agent-UUID att skicka ut
inputKeys List<String> Tillståndsnycklar som noden konsumerar som indata
repoIds List<String> Repos som noden messaging.createSpace checkar ut (<repoId> eller <repoId>@<branch>). Tom = inga; extras['allRepos'] = alla arbetsytans repos. Ignoreras på agentsteg.
outputKey String? Tillståndsnyckel som nodens utdata skrivs under
label String? Mänsklig etikett som visas på duken (standard: stegets id)
outputSchema Map<String, dynamic>? JSON-schema (delmängd) som utdatavärdet måste uppfylla
reducer String? Sammanfogningsstrategi när parallella grenar skriver till samma outputKey: append, mergeLists, mergeMaps, sum eller override (standard)
retryPolicy StepRetryPolicy? Återförsökspolicy vid kroppsfel; null = ett enda försök
continueOnFail bool När sant får ett terminalt fel inte körningen att misslyckas; felet sparas undan under state['_stepErrors'][stepId]
timeoutMs int? Timeout i klocktid för nodkroppen i millisekunder; null = ingen timeout
teamId String? Team att skicka ut (team.dispatch-noder); ömsesidigt uteslutande mot agentId
dispatchMode String? Teamets körningsläge: allParallel eller manager
extras Map<String, dynamic> Fri kroppsspecifik konfiguration (t.ex. iterableKey, templateId, villkorsträd)

Härledda accessorer: spaceId (extras['spaceId'] – befintligt samtal att arbeta i), createsConversation (extras['createConversation']), conversationTitle (extras['conversationTitle']), modeName (extras['mode'] – chat / review / plan, läses på den ytöppnande noden) och runWhen (extras['runWhen'] – hoppa över noden när villkoret inte är uppfyllt).