Pipeline adımları
Bir pipeline adımının birbirinden bağımsız iki ekseni vardır:
- Tür (
StepKind) — motorun adımı tetikleyicilerine göre nasıl zamanladığı. - Gövde anahtarı (
BuiltInBodyKeys) — adımın işini hangi kayıtlı gövde closure’ının yürüttüğü.
Adım türleri
Bölüm başlığı “Adım türleri”packages/cc_domain/lib/features/pipelines/domain/entities/step_kind.dart içinde tanımlıdır.
| Tür | Zamanlama semantiği |
|---|---|
trigger |
Zorunlu giriş noktası — şablon başına tam olarak bir tane, her zaman ilk düğüm. Kendi başına hiçbir iş yapmaz; çalıştırmayı neyin başlattığı (elle / olay / zamanlama) ayrıca PipelineTrigger satırları olarak izlenir. Gövdesi etkisiz pipeline.trigger’dır. |
listen |
Tüm kaynak adımlar (StepTrigger.sourceStepIds içindekiler) tamamlandığında tetiklenir. |
join |
waitForStepIds içindeki tüm adımlar terminal duruma ulaştığında tetiklenir. |
router |
Koşullu dallanma — gövde StepResult.route(key) döndürür; bu yalnızca routeKey’i eşleşen alt kenarı tetikler, seçilmeyen dallar atlanmış olarak işaretlenir. |
forEach |
listen gibi zamanlanır (tüm sourceStepIds tamamlandığında tetiklenir). Yinelemeyi yapan, kayıtlı flow.forEach gövdesidir; motor her öğe için bir alt adım üretmez. |
terminal |
Gövdesi olmayan zamanlayıcı nöbetçisi. Pipeline çalıştırması, bir terminal adım bittiğinde tamamlanır. |
Adım gövdeleri
Bölüm başlığı “Adım gövdeleri”BuiltInBodyKeys içindeki sabitlerle anahtarlanan kayıtlı gövde closure’ları (packages/cc_domain/lib/features/pipelines/domain/templates/builtin_template_seeds.dart). 25 tanedir ve tümü aşağıda listelenmiştir. Aksi belirtilmedikçe yapılandırma, adımın PipelineNodeConfig öğesinden okunur (aşağıya bakın); “durum anahtarları” yürütme sırasında pipeline durumundan / tetikleyici yükünden okunur.
bodyKey’i kayıtlı olmayan bir adım, şablon yüklenirken bir uyarı üretir ve ardından hiç çalışmaz — çalıştırmayı başarısız kılmaz. trigger ve terminal adımları bu uyarıdan muaftır: tetikleyici yine de etkisiz pipeline.trigger gövdesini çalıştırır; bir terminal adımının gövdesi yoktur.
pipeline.trigger
Bölüm başlığı “pipeline.trigger”Zorunlu trigger düğümünün etkisiz gövdesi — hemen tamamlanır, böylece motor alt dinleyicilere dağılır. Yapılandırma yoktur.
pipeline.bashScript
Bölüm başlığı “pipeline.bashScript”Ajansız kabuk adımı (bash -c). Betikteki {{key}} yer tutucuları, durum + tetikleyici yükünden kabuk için kaçışlanmış değerlerle değiştirilir.
| Yapılandırma alanı | Açıklama |
|---|---|
script |
Yürütülecek kabuk komutu (zorunlu) |
outputKey |
0 çıkışında kırpılmış stdout’u alan durum anahtarı |
cwd <cc_root>/pipelines/<pipelineRunId>/ (bir çalıştırmadaki tüm bash adımları tarafından paylaşılır) ve ortamda GITHUB_TOKEN ile çalışır. Ayrıca <stepId>_runDir değerini duruma yazar. Sıfırdan farklı çıkış, adımı stderr çıktısının sonuyla başarısız kılar.
conversation.promptAgent
Bölüm başlığı “conversation.promptAgent”Genel istem ve gönderim düğümü: istemi işler, ajanı bir konuşmaya gönderir ve çalıştırma bitene kadar askıya alır. Ajanın submit_output yükü, outputKey altında duruma toplanır.
| Yapılandırma alanı | Açıklama |
|---|---|
agentId |
Gönderilecek çalışma alanına özel ajan UUID’si (zorunlu) |
prompt |
Yönerge metni; {{key}} yer tutucu değişimini destekler (zorunlu) |
outputKey |
Toplanan çıktı için durum anahtarı |
outputSchema |
Çıktının karşılaması gereken JSON Schema |
label |
Tuvalde gösterilen insan okunur etiket |
extras.spaceId |
İçinde çalışılacak mevcut konuşma (varsayılan: gizli bir konuşma) |
extras.conversationTitle |
O alan içindeki adlandırılmış akış (isteğe bağlı) |
extras.mode |
Burada değil, odayı açan düğümde (messaging.createSpace) okunur. Varsayılan review. |
pipeline.condition
Bölüm başlığı “pipeline.condition”Router gövdesi — config.extras okur, bir koşulu değerlendirir ve StepResult.route(key) döndürür. Koşullar JavaScript ifadeleri değildir; öncelik sırasına göre üç yazım biçimi desteklenir:
- Koşul ağacı (
extras.predicate) —"true"/"false"olarak yönlendiren mantıksal bir ağaç. Her düğüm, birtypeiçeren bir haritadır:{"type": "fileExists", "paths": [...], "baseKey": "repo_local_path", "negate": false, "recursive": false}— listelenen yollardan herhangi biri diskte varsa true;negatebunu tersine çevirir;recursivealt dizinlerde de arar (.git,node_modules,build,.dart_toolatlanarak). Göreli yollarstate[baseKey](varsayılanrepo_local_path) değerine göre çözümlenir; yoksa çalıştırma başına çalışma alanı dizinine göre.{"type": "comparison", "left": "{{score}}", "op": "gt", "right": 80}— operatörler:equals,notEquals,contains,exists,notExists,gt,lt; dosya sistemini değil, pipeline durumunu okur.{"type": "and" | "or", "of": [<predicate>, ...]}— mantıksal gruplar.{"type": "not", "of": <predicate>}— değilleme.
- Seçim (
extras.switchKey) —{"switchKey": "pr_class", "cases": [...], "default": "standard"}; durum değerinin büyük/küçük harf ayrımı gözetmeksizin içerdiği ilk seçeneğe, aksi haldedefault’a yönlendirir. - Karşılaştırma (eski tarz üst düzey
extras.left/extras.op/extras.right) — bircomparisonkoşuluna eşdeğerdir; ağaçtan önce yazılmış şablonlar için korunmuştur.
Düğümden çıkan kenarlar, döndürülen anahtarla eşleşmesi gereken bir routeKey taşır.
prReview.comment
Bölüm başlığı “prReview.comment”Birleştirilmiş bulguları GitHub PR istemcisi üzerinden bir PR inceleme yorumu olarak yayımlar.
| Durum anahtarı | Açıklama |
|---|---|
repo_full_name |
owner/repo (zorunlu) |
pr_number |
PR numarası — int veya sayısal dize (zorunlu) |
consolidated_findings |
Yorum gövdesi (zorunlu) |
Durumda comment_review_id ve commented_at ile StepResult.terminal döndürür.
messaging.postSpace
Bölüm başlığı “messaging.postSpace”MessagingPort üzerinden bir mesajlaşma alanına mesaj gönderir.
| Durum anahtarı | Açıklama |
|---|---|
space_id |
Hedef alan (zorunlu) |
content |
Mesaj gövdesi, durumdan olduğu gibi okunur (zorunlu) |
Duruma posted_space_id ve posted_at yazar.
team.dispatch
Bölüm başlığı “team.dispatch”Tek bir ajan yerine bütün bir ekibi gönderir, sonra üyelerin çalıştırmaları bitene kadar askıya alır.
| Yapılandırma alanı | Açıklama |
|---|---|
teamId |
Gönderilecek çalışma alanına özel ekip (zorunlu; agentId ile birbirini dışlar) |
prompt |
Hedef metni; {{key}} yer tutucu değişimini destekler (zorunlu) |
dispatchMode |
allParallel (varsayılan — üye başına bir görev) veya manager (yalnızca lideri eşgüdüm için gönder) |
outputKey |
Toplanan üye çıktıları için durum anahtarı |
outputSchema, label, extras.spaceId |
conversation.promptAgent ile aynı |
human.gate
Bölüm başlığı “human.gate”Onay kapısı. Onaylayan ajanı, kapı istemi ve bir {decision, reason} çıktı sözleşmesiyle bir konuşmaya (inceleme modu) gönderir, sonra onaylayan submit_output ile gönderene kadar askıya alır.
| Yapılandırma alanı | Açıklama |
|---|---|
agentId |
Onaylayan ajan (zorunlu) |
prompt |
Kapı istemi (isteğe bağlı; yoksa bir varsayılan kullanılır) |
outputKey |
Toplanan {decision, reason} yükü için durum anahtarı |
outputSchema |
Varsayılan olarak bir onay şeması (decision: approved / rejected, reason) |
label, extras.spaceId |
conversation.promptAgent ile aynı |
Kapı yalnızca submit_output üzerinden çözümlenir. BuiltInBodyKeys.humanGate, düğüm türü kitaplığı ve bir yerleşik şablonun istem metni, approve_step ve reject_step MCP araçlarını adlandırır; bu araçların ikisi de hiçbir paket veya kayıt defterinde yoktur.
repos.cleanup
Bölüm başlığı “repos.cleanup”Bayat yalıtılmış çalışma ağaçlarını kaldırır; modunu tetikleyici yükünden seçer. Çalıştırmanın dryRun bayrağına uyar.
| Durum anahtarı | Açıklama |
|---|---|
ticket_id |
O biletin çalışma ağaçlarını serbest bırakır |
repo_full_name + pr_number |
Geçici PR düzenleyici çalışma ağacını serbest bırakır |
space_id |
O konuşmanın çalışma ağaçlarını ve klasörünü yıkar |
| (yukarıdakilerden hiçbiri) | Çalışma alanını süpürür: kaybolmuş dizinler, ölü alanlar, sahipsiz konuşma klasörleri |
outputKey (isteğe bağlı) bir özet dizesi alır.
flow.forEach
Bölüm başlığı “flow.forEach”Bir durum koleksiyonu üzerinde eşleme / dağıtım: istemi her öğe için bir kez işler, sonra ajanı bu istemler birleştirilmiş olarak (--- ayırıcılarıyla) bir kez gönderir ve o çalıştırma bitene kadar askıya alır. Boş bir koleksiyon hemen boş bir listeyle tamamlanır. Bu, öğe başına bir paralel gönderim değildir.
| Yapılandırma alanı | Açıklama |
|---|---|
agentId |
Öğe başına gönderilecek ajan (zorunlu) |
prompt |
Öğe başına istem; {{key}} yer tutucu değişimini destekler (zorunlu) |
extras.iterableKey |
Koleksiyonu tutan durum anahtarı (zorunlu) |
extras.itemKey |
Geçerli öğenin istemde bağlandığı anahtar (varsayılan item) |
outputKey |
Toplanan çıktı için durum anahtarı (liste değil, tek gönderim) |
flow.callPipeline
Bölüm başlığı “flow.callPipeline”Başka bir pipeline şablonunu iç içe bir alt adım olarak çalıştırır (alt pipeline, parentPipelineRunId ayarlanmış bir alt çalıştırma olarak çalışır). Adım, alt çalıştırma terminal duruma ulaşana kadar askıya alınır, ardından alt çalıştırmanın son durumu outputKey altında birleştirilir.
| Yapılandırma alanı | Açıklama |
|---|---|
extras.templateId |
Çalıştırılacak alt şablon (zorunlu; bir pipeline kendini çağıramaz) |
inputKeys |
Alt çalıştırmanın tetikleyici yüküne kopyalanan durum anahtarları |
outputKey |
Alt çalıştırmanın birleştirilmiş son durumu için durum anahtarı |
code.index
Bölüm başlığı “code.index”Arka planda tree-sitter dizinleme: bir depoyu dolaşır, sembolleri/kenarları worker isolate’larında çıkarır ve bunları çalışma alanının kod grafiğine alır. İlerlemeyi adım çalıştırma satırına akıtır; kuru çalıştırmayı destekler. Tree-sitter ve dil bilgileri gerekli yerel bileşenlerdir — eksik bir dylib, sunucunun hiç açılmadığı anlamına gelir ve çalıştırma ortasında çözülemeyen bir dil bilgisi, adımı atlamak yerine başarısız kılar.
| Durum anahtarı | Açıklama |
|---|---|
repo_id |
Dizinlenecek depo (zorunlu) |
repo_local_path |
Checkout’un yerel yolu (zorunlu) |
meeting.diarize
Bölüm başlığı “meeting.diarize”Çevrimdışı konuşmacı diyarizasyonu. Toplantının saklanan sesini okur, konuşmacılara kümelendirir (Person 1, Person 2, …), transkript bölümlerini yeniden etiketler ve transcript durumunu yeniden yazar; ayrıca paralel meeting.updateTranscript adımı için diarization_spans üretir. Hiç ses saklanmadıysa veya modeller kurulu değilse transkripti değiştirmeden geçirir.
| Durum anahtarı | Açıklama |
|---|---|
meeting_id |
Diyarize edilecek toplantı (zorunlu) |
meeting.saveNotes, meeting.addActionItems, meeting.addDecisions
Bölüm başlığı “meeting.saveNotes, meeting.addActionItems, meeting.addDecisions”Toplantı özetini kalıcı hâle getiren deterministik gövdeler. Her biri, durumdan meeting_id ile ajan adımının yapılandırılmış meeting_outcome yükünü ({summary, enhancedNotes, actionItems[], decisions[]}) okur ve kendi bölümünü kendi tablosuna yazar — notlar, eylem öğeleri veya kararlar. Kusurlu bir çalıştırmada daha önce kaydedilmiş satırlar asla silinmez.
Diğer yerleşik gövdeler
Bölüm başlığı “Diğer yerleşik gövdeler”| Gövde anahtarı | Açıklama |
|---|---|
meeting.identifySpeakers |
Toplantılar arası konuşmacı tanıma: diyarize edilmiş konuşmacıları kayıtlı ses profilleriyle eşleştirir ve güvenilir eşleşmeleri otomatik uygular. Profiller/gömlemler yoksa etkisizdir. |
meeting.updateTranscript |
diarization_spans içindeki Person N etiketlerini uygular ve pencere başına parçaları konuşmacı başına turlarda birleştirir, ardından temizlenmiş transkripti kalıcı hâle getirir. Diyarizasyon hiçbir şey üretmediğinde etkisizdir. |
meeting.assemblePlayback |
Toplantının karışık oynatma parçasını, saklanan kanal başına WAV’lerden oluşturur. Hiç ses saklanmadığında etkisizdir. |
orchestration.markPhase |
İş DAG’ının sonunda, çıktısı olmayan alt biletler için başarısızlık nöbetçileri yazar ve orkestrasyonu synthesizing durumuna geçirir. |
orchestration.persistDeliverable |
Sentez çıktısını üst bilete yazar, onu tamamlar, teslimatı yayımlar ve orkestrasyonu completed olarak işaretler. |
orchestration.awaitApproval |
Kısmi onay kapısı: adımın düğüm anahtarı orkestrasyonun onaylanmış kümesindeyse hemen tamamlanır; aksi halde sonraki bir onay onu sürdürene kadar askıya alınır. extras.awaitApproval ayarını yapan tek gövde budur; bu ayar, onu 24 saatlik askıya alınmış adım zaman aşımından muaf tutar. |
messaging.createSpace |
Şablonun geri kalanının içinde çalıştığı konuşmayı açar; bu konuşma, adımın outputKey’i altında yayımlanır (yerleşikler pipeline_space_id kullanır). Boş bir repoIds listesi hiçbir şeyi checkout etmez; extras['allRepos'] tüm çalışma alanı depolarını checkout eder. extras['createConversation'] (varsayılan olarak kapalı) ayrıca adlandırılmış bir akış açar. Bir ajan adımı bir odaya KATILIR ve asla bir oda açmaz; bu yüzden bu düğüm olmadan yapılan bir dağıtım, gönderim sırasında başarısız olur — ve bunu bir kez bağlamak, her birine bir tane sağlamak yerine tüm dağıtımın tek bir checkout paylaşması anlamına gelir. |
prReview.finalize |
PR inceleme şablonunun son adımı: biriken inceleme düğümlerini uzlaşma gruplarına ayırır ve PR başına kararı hesaplar. |
skills.analyze |
Bir çalışma alanında kurulu beceriler üzerinde beceri tedarik zinciri taramasını çalıştırır ve her kararı kaydeder. |
Adım sonuçları
Bölüm başlığı “Adım sonuçları”Bir adım gövdesi bir StepResult döndürür (packages/cc_domain/lib/features/pipelines/domain/entities/step_result.dart). failed hariç tüm fabrikalar, pipeline durumuna birleştirilen isteğe bağlı bir mutatedState haritası kabul eder.
| Fabrika | İmza | Açıklama |
|---|---|---|
ok |
StepResult.ok({mutatedState}) |
Normal tamamlanma; alt dinleyiciler değerlendirilir |
route |
StepResult.route(nextRouterKey, {mutatedState}) |
Router tamamlanması; routeKey’i eşleşen alt dalı seçer |
suspendUntilEvent |
StepResult.suspendUntilEvent(eventType, {mutatedState}) |
Belirli bir alan olayı türü tetiklenene kadar duraklatır |
suspendUntilTasksComplete |
StepResult.suspendUntilTasksComplete(taskIds, {mutatedState}) |
Listelenen tüm görevler terminal duruma ulaşana kadar duraklatır |
terminal |
StepResult.terminal({mutatedState}) |
Pipeline çalıştırması bitti — başka adım yok |
failed |
StepResult.failed(errorMessage) |
Adım bir hata mesajıyla başarısız oldu |
StepRetryPolicy
Bölüm başlığı “StepRetryPolicy”Başarısız olan bir düğüm gövdesi için yeniden deneme davranışı (PipelineNodeConfig.retryPolicy; null yeniden denemeleri devre dışı bırakır).
| Alan | Tür | Açıklama |
|---|---|---|
maxAttempts |
int |
İlk deneme dahil toplam deneme sayısı (3 = 1 deneme + 2 yeniden deneme); ≥ 1 olmalıdır |
backoff |
String |
linear veya exponential (varsayılan) |
initialDelayMs |
int |
İlk yeniden denemeden önceki gecikme, milisaniye cinsinden; sonraki gecikmeler backoff’a göre artar |
PipelineNodeConfig
Bölüm başlığı “PipelineNodeConfig”Adım tanımının içinde taşınan düğüm başına yapılandırma (packages/cc_domain/lib/features/pipelines/domain/entities/pipeline_node_config.dart). Hem yerleşik hem de özel düğümler bu biçimi paylaşır; her gövde yalnızca ilgilendiği alanları okur.
| Alan | Tür | Açıklama |
|---|---|---|
prompt |
String? |
{{key}} yer tutucu değişimli istem şablonu |
script |
String? |
{{key}} yer tutucu değişimli bash betik gövdesi |
agentId |
String? |
Gönderilecek çalışma alanına özel ajan UUID’si |
inputKeys |
List<String> |
Bu düğümün girdi olarak tükettiği durum anahtarları |
repoIds |
List<String> |
messaging.createSpace düğümünün checkout ettiği depolar (<repoId> veya <repoId>@<branch>). Boş = hiçbiri; extras['allRepos'] = tüm çalışma alanı depoları. Ajan adımlarında yok sayılır. |
outputKey |
String? |
Bu düğümün çıktısının yazıldığı durum anahtarı |
label |
String? |
Tuvalde gösterilen insan okunur etiket (varsayılan: adım kimliği) |
outputSchema |
Map<String, dynamic>? |
Çıktı değerinin karşılaması gereken JSON Schema (alt küme) |
reducer |
String? |
Paralel dallar aynı outputKey’e yazdığında birleştirme stratejisi: append, mergeLists, mergeMaps, sum veya override (varsayılan) |
retryPolicy |
StepRetryPolicy? |
Gövde başarısız olduğunda yeniden deneme politikası; null = tek deneme |
continueOnFail |
bool |
True olduğunda terminal bir başarısızlık çalıştırmayı başarısız kılmaz; hata state['_stepErrors'][stepId] altında saklanır |
timeoutMs |
int? |
Düğüm gövdesi için milisaniye cinsinden duvar saati zaman aşımı; null = zaman aşımı yok |
teamId |
String? |
Gönderilecek ekip (team.dispatch düğümleri); agentId ile birbirini dışlar |
dispatchMode |
String? |
Ekip yürütme modu: allParallel veya manager |
extras |
Map<String, dynamic> |
Serbest biçimli, gövdeye özgü yapılandırma (örn. iterableKey, templateId, koşul ağaçları) |
Türetilmiş erişimciler: spaceId (extras['spaceId'] — içinde çalışılacak mevcut konuşma), createsConversation (extras['createConversation']), conversationTitle (extras['conversationTitle']), modeName (extras['mode'] — chat / review / plan, alanı açan düğümde okunur) ve runWhen (extras['runWhen'] — karşılanmadığında düğümü atlar).