Jenis langkah pipeline
Satu langkah pipeline mempunyai dua paksi bebas:
- Jenis (
StepKind) — cara enjin menjadualkan langkah itu berbanding pencetusnya. - Kunci badan (
BuiltInBodyKeys) — closure badan berdaftar yang manakah melaksanakan kerja langkah itu.
Jenis langkah
Bahagian bertajuk “Jenis langkah”Ditakrifkan dalam packages/cc_domain/lib/features/pipelines/domain/entities/step_kind.dart.
| Jenis | Semantik penjadualan |
|---|---|
trigger |
Titik masuk wajib — tepat satu bagi setiap templat, sentiasa nod pertama. Ia sendiri tidak melakukan sebarang kerja; perkara yang memulakan larian (manual / acara / jadual) dijejak secara berasingan sebagai baris PipelineTrigger. Badannya ialah pipeline.trigger yang tidak melakukan apa-apa. |
listen |
Terpicu apabila semua langkah sumber (dalam StepTrigger.sourceStepIds) selesai. |
join |
Terpicu apabila semua langkah dalam waitForStepIds mencapai keadaan terminal. |
router |
Pencabangan bersyarat — badan mengembalikan StepResult.route(key), yang hanya menyalakan tepi hiliran yang routeKey-nya sepadan; cabang yang tidak dipilih ditandakan sebagai dilangkau. |
forEach |
Dijadualkan seperti listen (terpicu apabila semua sourceStepIds selesai). Badan flow.forEach yang berdaftar itulah yang membuat lelaran; enjin tidak menghasilkan satu sub-langkah anak bagi setiap item. |
terminal |
Sentinel penjadual tanpa badan. Larian pipeline selesai apabila langkah terminal selesai. |
Badan langkah
Bahagian bertajuk “Badan langkah”Closure badan berdaftar yang dikunci oleh pemalar dalam BuiltInBodyKeys (packages/cc_domain/lib/features/pipelines/domain/templates/builtin_template_seeds.dart). Terdapat 25, semuanya disenaraikan di bawah. Konfigurasi dibaca daripada PipelineNodeConfig langkah itu (lihat di bawah) melainkan dinyatakan sebaliknya; “kunci keadaan” dibaca daripada keadaan pipeline / muatan pencetus pada masa pelaksanaan.
Langkah yang bodyKey-nya tidak berdaftar menghasilkan amaran semasa templat dimuatkan dan selepas itu tidak pernah dilaksanakan — ia tidak menggagalkan larian. Langkah trigger dan terminal dikecualikan daripada amaran itu: pencetus masih menjalankan badan pipeline.trigger yang tidak melakukan apa-apa; langkah terminal tiada badan.
pipeline.trigger
Bahagian bertajuk “pipeline.trigger”Badan yang tidak melakukan apa-apa bagi nod trigger yang wajib — selesai serta-merta supaya enjin menyebar kepada pendengar hiliran. Tiada konfigurasi.
pipeline.bashScript
Bahagian bertajuk “pipeline.bashScript”Langkah shell tanpa ejen (bash -c). Pemegang tempat {{key}} dalam skrip digantikan daripada keadaan + muatan pencetus dengan nilai yang di-escape untuk shell.
| Medan konfigurasi | Keterangan |
|---|---|
script |
Perintah shell untuk dilaksanakan (wajib) |
outputKey |
Kunci keadaan yang menerima stdout yang dipangkas pada keluar 0 |
Berjalan dengan cwd <cc_root>/pipelines/<pipelineRunId>/ (dikongsi oleh semua langkah bash dalam sesuatu larian) dan GITHUB_TOKEN dalam persekitaran. Juga menulis <stepId>_runDir ke keadaan. Keluar bukan sifar menggagalkan langkah itu dengan hujung stderr.
conversation.promptAgent
Bahagian bertajuk “conversation.promptAgent”Nod prompt-dan-hantar generik: menjana prompt, menghantar ejen ke dalam perbualan dan menggantung sehingga larian selesai. Muatan submit_output ejen dipungut ke dalam keadaan di bawah outputKey.
| Medan konfigurasi | Keterangan |
|---|---|
agentId |
UUID ejen berskop ruang kerja untuk dihantar (wajib) |
prompt |
Teks arahan; menyokong penggantian {{key}} (wajib) |
outputKey |
Kunci keadaan bagi output yang dipungut |
outputSchema |
Skema JSON yang mesti dipenuhi oleh output |
label |
Label yang boleh dibaca manusia, dipaparkan pada kanvas |
extras.spaceId |
Perbualan sedia ada untuk digunakan (lalai: perbualan tersembunyi) |
extras.conversationTitle |
Strim bernama dalam ruang itu (pilihan) |
extras.mode |
Dibaca pada nod yang membuka ruang itu (messaging.createSpace), bukan di sini. Lalai review. |
pipeline.condition
Bahagian bertajuk “pipeline.condition”Badan router — membaca config.extras, menilai satu syarat dan mengembalikan StepResult.route(key). Syarat bukan ungkapan JavaScript; tiga bentuk pengarangan disokong, mengikut keutamaan:
- Pokok predikat (
extras.predicate) — pokok boolean yang menghala ke"true"/"false". Setiap nod ialah peta dengantype:{"type": "fileExists", "paths": [...], "baseKey": "repo_local_path", "negate": false, "recursive": false}— benar apabila mana-mana laluan yang disenaraikan wujud pada cakera;negatemenyongsangkannya;recursiveturut mencari sub-direktori (melangkau.git,node_modules,build,.dart_tool). Laluan relatif diselesaikan terhadapstate[baseKey](lalairepo_local_path), jika tidak direktori ruang kerja bagi setiap larian.{"type": "comparison", "left": "{{score}}", "op": "gt", "right": 80}— pengendaliequals,notEquals,contains,exists,notExists,gt,lt; membaca keadaan pipeline, bukan sistem fail.{"type": "and" | "or", "of": [<predicate>, ...]}— kumpulan boolean.{"type": "not", "of": <predicate>}— penafian.
- Suis (
extras.switchKey) —{"switchKey": "pr_class", "cases": [...], "default": "standard"}; menghala ke kes pertama yang terkandung dalam nilai keadaan secara tidak sensitif huruf besar-kecil, jika tidakdefault. - Perbandingan (legasi aras atas
extras.left/extras.op/extras.right) — setara dengan predikatcomparison, dikekalkan untuk templat yang dikarang sebelum pokok itu.
Tepi yang keluar daripada nod membawa routeKey yang mesti sepadan dengan kunci yang dikembalikan.
prReview.comment
Bahagian bertajuk “prReview.comment”Menyiarkan penemuan yang dikonsolidasikan sebagai komen semakan PR melalui klien PR GitHub.
| Kunci keadaan | Keterangan |
|---|---|
repo_full_name |
owner/repo (wajib) |
pr_number |
Nombor PR — int atau rentetan angka (wajib) |
consolidated_findings |
Badan komen (wajib) |
Mengembalikan StepResult.terminal dengan comment_review_id dan commented_at dalam keadaan.
messaging.postSpace
Bahagian bertajuk “messaging.postSpace”Menyiarkan mesej ke ruang pemesejan melalui MessagingPort.
| Kunci keadaan | Keterangan |
|---|---|
space_id |
Ruang sasaran (wajib) |
content |
Badan mesej, dibaca apa adanya daripada keadaan (wajib) |
Menulis posted_space_id dan posted_at ke keadaan.
team.dispatch
Bahagian bertajuk “team.dispatch”Menghantar seluruh pasukan dan bukannya satu ejen, kemudian menggantung sehingga larian ahli selesai.
| Medan konfigurasi | Keterangan |
|---|---|
teamId |
Pasukan berskop ruang kerja untuk dihantar (wajib; saling eksklusif dengan agentId) |
prompt |
Teks matlamat; menyokong penggantian {{key}} (wajib) |
dispatchMode |
allParallel (lalai — satu tugasan setiap ahli) atau manager (hantar ketua sahaja untuk menyelaraskan) |
outputKey |
Kunci keadaan bagi output ahli yang dipungut |
outputSchema, label, extras.spaceId |
Seperti untuk conversation.promptAgent |
human.gate
Bahagian bertajuk “human.gate”Gerbang kelulusan. Menghantar ejen pelulus ke dalam perbualan (modus semakan) dengan prompt gerbang dan kontrak output {decision, reason}, kemudian menggantung sehingga pelulus menghantar melalui submit_output.
| Medan konfigurasi | Keterangan |
|---|---|
agentId |
Ejen pelulus (wajib) |
prompt |
Prompt gerbang (pilihan; nilai lalai digunakan apabila tiada) |
outputKey |
Kunci keadaan bagi muatan {decision, reason} yang dipungut |
outputSchema |
Lalai kepada skema kelulusan (decision: approved / rejected, reason) |
label, extras.spaceId |
Seperti untuk conversation.promptAgent |
Gerbang itu hanya diselesaikan melalui submit_output. BuiltInBodyKeys.humanGate, pustaka jenis nod dan teks prompt satu templat terbina dalam semuanya menamakan alat MCP approve_step dan reject_step; kedua-dua alat itu tidak wujud dalam mana-mana pakej atau registri.
repos.cleanup
Bahagian bertajuk “repos.cleanup”Membuang worktree terasing yang basi; memilih modusnya daripada muatan pencetus. Mematuhi bendera dryRun larian.
| Kunci keadaan | Keterangan |
|---|---|
ticket_id |
Lepaskan worktree tiket itu |
repo_full_name + pr_number |
Lepaskan worktree editor PR yang efemeral |
space_id |
Robohkan worktree dan folder perbualan itu |
| (tiada satu di atas) | Sapu ruang kerja: direktori yang hilang, ruang mati, folder perbualan yatim |
outputKey (pilihan) menerima rentetan ringkasan.
flow.forEach
Bahagian bertajuk “flow.forEach”Peta / sebar ke atas koleksi keadaan: menjana prompt sekali bagi setiap item, kemudian menghantar ejen sekali dengan prompt tersebut digabungkan (pemisah ---) dan menggantung sehingga larian itu selesai. Koleksi kosong selesai serta-merta dengan senarai kosong. Ia bukan satu penghantaran selari bagi setiap item.
| Medan konfigurasi | Keterangan |
|---|---|
agentId |
Ejen untuk dihantar bagi setiap item (wajib) |
prompt |
Prompt bagi setiap item; menyokong penggantian {{key}} (wajib) |
extras.iterableKey |
Kunci keadaan yang memegang koleksi (wajib) |
extras.itemKey |
Kunci yang diikat pada item semasa dalam prompt (lalai item) |
outputKey |
Kunci keadaan bagi output yang dipungut (satu penghantaran, bukan senarai) |
flow.callPipeline
Bahagian bertajuk “flow.callPipeline”Menjalankan templat pipeline lain sebagai sub-langkah bersarang (sub-pipeline berjalan sebagai larian anak dengan parentPipelineRunId ditetapkan). Langkah itu menggantung sehingga anak mencapai keadaan terminal, kemudian keadaan akhir anak digabungkan di bawah outputKey.
| Medan konfigurasi | Keterangan |
|---|---|
extras.templateId |
Templat anak untuk dijalankan (wajib; pipeline tidak boleh memanggil dirinya sendiri) |
inputKeys |
Kunci keadaan yang disalin ke dalam muatan pencetus anak |
outputKey |
Kunci keadaan bagi keadaan akhir anak yang digabungkan |
code.index
Bahagian bertajuk “code.index”Pengindeksan tree-sitter latar belakang: merentasi sesuatu repo, mengekstrak simbol/tepi dalam isolat pekerja dan menyuntiknya ke dalam graf kod ruang kerja. Menstrim kemajuan ke dalam baris larian langkah; menyokong dry-run. Tree-sitter dan tatabahasanya ialah natif yang diperlukan — dylib yang hilang bermakna pelayan tidak pernah boot, dan tatabahasa yang gagal diselesaikan semasa larian menggagalkan langkah itu dan bukannya melangkaunya.
| Kunci keadaan | Keterangan |
|---|---|
repo_id |
Repo untuk diindeks (wajib) |
repo_local_path |
Laluan setempat checkout (wajib) |
meeting.diarize
Bahagian bertajuk “meeting.diarize”Diarisasi penutur luar talian. Membaca audio mesyuarat yang disimpan, mengelompokkannya kepada penutur (Person 1, Person 2, …), melabel semula segmen transkrip dan menulis semula keadaan transcript; juga mengeluarkan diarization_spans untuk langkah meeting.updateTranscript yang selari. Melewatkan transkrip tanpa perubahan apabila tiada audio disimpan atau model tidak dipasang.
| Kunci keadaan | Keterangan |
|---|---|
meeting_id |
Mesyuarat untuk didiarisasi (wajib) |
meeting.saveNotes, meeting.addActionItems, meeting.addDecisions
Bahagian bertajuk “meeting.saveNotes, meeting.addActionItems, meeting.addDecisions”Badan penyimpanan ringkasan mesyuarat yang deterministik. Setiap satu membaca meeting_id dan muatan meeting_outcome berstruktur langkah ejen ({summary, enhancedNotes, actionItems[], decisions[]}) daripada keadaan dan menulis bahagiannya ke jadualnya sendiri — nota, item tindakan atau keputusan. Baris yang disimpan sebelum ini tidak pernah dipadam pada larian yang merosot.
Badan terbina dalam yang lain
Bahagian bertajuk “Badan terbina dalam yang lain”| Kunci badan | Keterangan |
|---|---|
meeting.identifySpeakers |
Pengecaman penutur merentas mesyuarat: memadankan penutur yang didiarisasi dengan profil suara tersimpan dan menerapkan padanan yang meyakinkan secara automatik. Tidak melakukan apa-apa tanpa profil/embedding. |
meeting.updateTranscript |
Menerapkan label Person N daripada diarization_spans dan menggabungkan serpihan setiap tetingkap menjadi giliran setiap penutur, kemudian menyimpan transkrip yang dibersihkan. Tidak melakukan apa-apa apabila diarisasi tidak menghasilkan apa-apa. |
meeting.assemblePlayback |
Menghimpunkan trek main balik bercampur mesyuarat daripada WAV setiap saluran yang disimpan. Tidak melakukan apa-apa apabila tiada audio disimpan. |
orchestration.markPhase |
Pada penghujung DAG kerja, menulis sentinel kegagalan untuk sub-tiket yang tiada output dan menukar orkestrasi kepada synthesizing. |
orchestration.persistDeliverable |
Menulis output sintesis ke tiket induk, melengkapkannya, menyiarkan dapatan dan menandakan orkestrasi completed. |
orchestration.awaitApproval |
Gerbang kelulusan separa: selesai serta-merta apabila kunci nod langkah itu berada dalam set kelulusan orkestrasi, jika tidak menggantung sehingga kelulusan kemudian menyambungnya semula. Inilah satu-satunya badan yang menetapkan extras.awaitApproval, yang mengecualikannya daripada tamat masa langkah digantung 24 jam. |
messaging.createSpace |
Membuka perbualan tempat seluruh templat selebihnya berfungsi, diterbitkan di bawah outputKey langkah itu (yang terbina dalam menggunakan pipeline_space_id). Senarai repoIds yang kosong tidak membuat checkout apa-apa; extras['allRepos'] membuat checkout setiap repo ruang kerja. extras['createConversation'] (mati secara lalai) juga membuka strim bernama. Langkah ejen MENYERTAI bilik dan tidak pernah membuka bilik, jadi sebaran tanpa nod ini gagal semasa penghantaran — dan menyambungkannya sekali bermakna seluruh sebaran berkongsi satu checkout dan bukannya menyediakan satu untuk setiap satu. |
prReview.finalize |
Langkah terakhir templat semakan PR: menyusun nod semakan yang terkumpul ke dalam kelompok konsensus dan mengira keputusan bagi setiap PR. |
skills.analyze |
Menjalankan imbasan rantaian bekalan kemahiran ke atas kemahiran yang dipasang dalam ruang kerja dan merekodkan setiap keputusan. |
Hasil langkah
Bahagian bertajuk “Hasil langkah”Badan langkah mengembalikan StepResult (packages/cc_domain/lib/features/pipelines/domain/entities/step_result.dart). Semua factory menerima peta mutatedState pilihan yang digabungkan ke dalam keadaan pipeline, kecuali failed.
| Factory | Tandatangan | Keterangan |
|---|---|---|
ok |
StepResult.ok({mutatedState}) |
Penyiapan normal; pendengar hiliran dinilai |
route |
StepResult.route(nextRouterKey, {mutatedState}) |
Penyiapan router; memilih cabang hiliran yang routeKey-nya sepadan |
suspendUntilEvent |
StepResult.suspendUntilEvent(eventType, {mutatedState}) |
Jeda sehingga jenis acara domain tertentu terpicu |
suspendUntilTasksComplete |
StepResult.suspendUntilTasksComplete(taskIds, {mutatedState}) |
Jeda sehingga semua tugasan yang tersenarai mencapai keadaan terminal |
terminal |
StepResult.terminal({mutatedState}) |
Larian pipeline sudah tamat — tiada lagi langkah |
failed |
StepResult.failed(errorMessage) |
Langkah itu gagal dengan mesej ralat |
StepRetryPolicy
Bahagian bertajuk “StepRetryPolicy”Tingkah laku cuba semula bagi badan nod yang gagal (PipelineNodeConfig.retryPolicy; null melumpuhkan cuba semula).
| Medan | Jenis | Keterangan |
|---|---|---|
maxAttempts |
int |
Jumlah percubaan termasuk yang pertama (3 = 1 cubaan + 2 cuba semula); mesti ≥ 1 |
backoff |
String |
linear atau exponential (lalai) |
initialDelayMs |
int |
Kelewatan sebelum cuba semula pertama, dalam milisaat; kelewatan seterusnya berkembang mengikut backoff |
PipelineNodeConfig
Bahagian bertajuk “PipelineNodeConfig”Konfigurasi bagi setiap nod yang dibawa dalam definisi langkah (packages/cc_domain/lib/features/pipelines/domain/entities/pipeline_node_config.dart). Kedua-dua nod terbina dalam dan tersuai berkongsi bentuk ini; setiap badan hanya membaca medan yang berkenaannya.
| Medan | Jenis | Keterangan |
|---|---|---|
prompt |
String? |
Templat prompt dengan penggantian {{key}} |
script |
String? |
Badan skrip Bash dengan penggantian {{key}} |
agentId |
String? |
UUID ejen berskop ruang kerja untuk dihantar |
inputKeys |
List<String> |
Kunci keadaan yang digunakan oleh nod ini sebagai input |
repoIds |
List<String> |
Repo yang di-checkout oleh nod messaging.createSpace (<repoId> atau <repoId>@<branch>). Kosong = tiada; extras['allRepos'] = setiap repo ruang kerja. Diabaikan pada langkah ejen. |
outputKey |
String? |
Kunci keadaan tempat output nod ini ditulis |
label |
String? |
Label yang boleh dibaca manusia, dipaparkan pada kanvas (lalai kepada ID langkah) |
outputSchema |
Map<String, dynamic>? |
Skema JSON (subset) yang mesti dipenuhi oleh nilai output |
reducer |
String? |
Strategi gabungan apabila cabang selari menulis outputKey yang sama: append, mergeLists, mergeMaps, sum atau override (lalai) |
retryPolicy |
StepRetryPolicy? |
Polisi cuba semula apabila badan gagal; null = satu percubaan |
continueOnFail |
bool |
Apabila true, kegagalan terminal tidak menggagalkan larian; ralat itu disimpan di bawah state['_stepErrors'][stepId] |
timeoutMs |
int? |
Tamat masa jam dinding untuk badan nod dalam milisaat; null = tiada tamat masa |
teamId |
String? |
Pasukan untuk dihantar (nod team.dispatch); saling eksklusif dengan agentId |
dispatchMode |
String? |
Modus pelaksanaan pasukan: allParallel atau manager |
extras |
Map<String, dynamic> |
Konfigurasi bebas khusus badan (contohnya iterableKey, templateId, pokok syarat) |
Pengakses terbitan: spaceId (extras['spaceId'] — perbualan sedia ada untuk digunakan), createsConversation (extras['createConversation']), conversationTitle (extras['conversationTitle']), modeName (extras['mode'] — chat / review / plan, dibaca pada nod yang membuka ruang) dan runWhen (extras['runWhen'] — langkau nod itu apabila tidak dipenuhi).