رفتن به محتوا

گام‌های پایپ‌لاین

یک گام پایپ‌لاین دو محور مستقل دارد:

  • نوع (StepKind) — اینکه موتور گام را نسبت به تریگرهایش چگونه زمان‌بندی می‌کند.
  • کلید بدنه (BuiltInBodyKeys) — اینکه کدام بستار بدنهٔ ثبت‌شده کار گام را اجرا می‌کند.

تعریف‌شده در packages/cc_domain/lib/features/pipelines/domain/entities/step_kind.dart.

نوع معناشناسی زمان‌بندی
trigger نقطهٔ ورود اجباری — دقیقاً یکی در هر قالب، همیشه نخستین گره. خودش هیچ کاری انجام نمی‌دهد؛ اینکه چه چیزی اجرا را شروع می‌کند (دستی / رویداد / زمان‌بندی) جداگانه در ردیف‌های PipelineTrigger ردیابی می‌شود. بدنه‌اش همان pipeline.trigger بی‌اثر است.
listen هنگامی برانگیخته می‌شود که همهٔ گام‌های مبدأ (در StepTrigger.sourceStepIds) کامل شوند.
join هنگامی برانگیخته می‌شود که همهٔ گام‌های waitForStepIds به وضعیت پایانی برسند.
router شاخه‌بندی شرطی — بدنه StepResult.route(key) را برمی‌گرداند که تنها یال پایین‌دستی را برانگیخته می‌کند که routeKeyاش منطبق باشد؛ شاخه‌های انتخاب‌نشده ردشده علامت می‌خورند.
forEach مانند listen زمان‌بندی می‌شود (هنگامی برانگیخته می‌شود که همهٔ sourceStepIds کامل شوند). این بدنهٔ ثبت‌شدهٔ flow.forEach است که پیمایش را انجام می‌دهد؛ موتور به‌ازای هر آیتم یک گام فرزند نمی‌سازد.
terminal دیده‌بان زمان‌بند بدون بدنه. اجرای پایپ‌لاین هنگامی کامل می‌شود که یک گام پایانی تمام شود.

بستارهای بدنهٔ ثبت‌شده که با ثابت‌های BuiltInBodyKeys (packages/cc_domain/lib/features/pipelines/domain/templates/builtin_template_seeds.dart) کلید می‌خورند. 25 مورد وجود دارد که همه در پایین فهرست شده‌اند. پیکربندی — مگر آنکه ذکر شود — از PipelineNodeConfig گام (پایین را ببینید) خوانده می‌شود؛ «کلیدهای حالت» هنگام اجرا از حالت پایپ‌لاین / بار دادهٔ تریگر خوانده می‌شوند.

گامی که bodyKeyاش ثبت نشده باشد، هنگام بارگذاری قالب یک هشدار تولید می‌کند و پس از آن هرگز اجرا نمی‌شود — اما اجرا را ناموفق نمی‌کند. گام‌های trigger و terminal از این هشدار مستثنا هستند: تریگر همچنان بدنهٔ بی‌اثر pipeline.trigger را اجرا می‌کند؛ گام terminal بدنه ندارد.

بدنهٔ بی‌اثر گره اجباری trigger — بی‌درنگ کامل می‌شود تا موتور به شنونده‌های پایین‌دستی پخش شود. بدون پیکربندی.

گام پوستهٔ بدون عامل (bash -c). جانگهدارهای {{key}} در اسکریپت، با مقادیر اسکیپ‌شده برای پوسته از حالت + بار دادهٔ تریگر جایگزین می‌شوند.

فیلد پیکربندی توضیح
script فرمان پوسته برای اجرا (اجباری)
outputKey کلید حالتی که هنگام خروج با کد 0، stdout پیرایش‌شده را دریافت می‌کند

با دایرکتوری جاری <cc_root>/pipelines/<pipelineRunId>/ (مشترک میان همهٔ گام‌های bash در یک اجرا) و GITHUB_TOKEN در محیط اجرا می‌شود. همچنین <stepId>_runDir را در حالت می‌نویسد. خروج با کد غیرصفر، گام را با دنبالهٔ stderr ناموفق می‌کند.

گره عمومی پرامپت‌و‌اعزام: پرامپت را رندر می‌کند، عامل را در یک گفتگو اعزام می‌کند و تا پایان اجرا معلق می‌ماند. بار دادهٔ submit_output عامل زیر outputKey در حالت برداشت می‌شود.

فیلد پیکربندی توضیح
agentId UUID عامل در محدودهٔ فضای کاری برای اعزام (اجباری)
prompt متن دستور؛ از جایگزینی {{key}} پشتیبانی می‌کند (اجباری)
outputKey کلید حالت برای خروجی برداشت‌شده
outputSchema طرح‌وارهٔ JSON که خروجی باید آن را برآورده کند
label برچسب انسانی نمایش‌داده‌شده روی بوم
extras.spaceId گفتگوی موجودی که کار در آن انجام شود (پیش‌فرض: یک گفتگوی پنهان)
extras.conversationTitle جریان نام‌دار داخل آن فضا (اختیاری)
extras.mode روی همان گرهی خوانده می‌شود که اتاق را باز می‌کند (messaging.createSpace)، نه اینجا. پیش‌فرض review.

بدنهٔ router — config.extras را می‌خواند، یک شرط را ارزیابی می‌کند و StepResult.route(key) را برمی‌گرداند. شرط‌ها عبارت‌های JavaScript نیستند؛ سه شکل نوشتن — به ترتیب اولویت — پشتیبانی می‌شود:

  • درخت گزاره (extras.predicate) — درختی بولی که "true" / "false" را مسیریابی می‌کند. هر گره یک نقشه با یک type است:
    • {"type": "fileExists", "paths": [...], "baseKey": "repo_local_path", "negate": false, "recursive": false} — هنگامی درست است که هر یک از مسیرهای فهرست‌شده روی دیسک وجود داشته باشد؛ negate آن را وارونه می‌کند؛ recursive زیرشاخه‌ها را هم می‌جوید (با صرف‌نظر از .git، node_modules، build، .dart_tool). مسیرهای نسبی در برابر state[baseKey] (پیش‌فرض repo_local_path) و در غیر این صورت دایرکتوری فضای کاری هر اجرا حل می‌شوند.
    • {"type": "comparison", "left": "{{score}}", "op": "gt", "right": 80} — عملگرها equals، notEquals، contains، exists، notExists، gt، lt؛ حالت پایپ‌لاین را می‌خواند، نه فایل‌سیستم را.
    • {"type": "and" | "or", "of": [<predicate>, ...]} — گروه‌های بولی.
    • {"type": "not", "of": <predicate>} — نقیض.
  • سوییچ (extras.switchKey) — {"switchKey": "pr_class", "cases": [...], "default": "standard"}؛ به نخستین موردی مسیریابی می‌کند که مقدار حالت — بدون توجه به بزرگی و کوچکی حروف — دربر داشته باشد، و در غیر این صورت به default.
  • مقایسه (سطح‌بالای قدیمی extras.left / extras.op / extras.right) — معادل یک گزارهٔ comparison، که برای قالب‌های نوشته‌شده پیش از درخت نگه داشته شده است.

یال‌های بیرون‌آمده از گره یک routeKey حمل می‌کنند که باید با کلید برگشتی منطبق باشد.

یافته‌های تجمیع‌شده را از طریق کلاینت PR مربوط به GitHub به‌عنوان یک نظر بازبینی PR منتشر می‌کند.

کلید حالت توضیح
repo_full_name owner/repo (اجباری)
pr_number شمارهٔ PR — عدد صحیح یا رشتهٔ عددی (اجباری)
consolidated_findings متن نظر (اجباری)

StepResult.terminal را با comment_review_id و commented_at در حالت برمی‌گرداند.

پیامی را از راه MessagingPort در یک فضای پیام‌رسانی منتشر می‌کند.

کلید حالت توضیح
space_id فضای هدف (اجباری)
content متن پیام، که عیناً از حالت خوانده می‌شود (اجباری)

posted_space_id و posted_at را در حالت می‌نویسد.

به‌جای یک عامل تنها، یک تیم کامل را اعزام می‌کند و سپس تا پایان اجرای اعضا معلق می‌ماند.

فیلد پیکربندی توضیح
teamId تیم در محدودهٔ فضای کاری برای اعزام (اجباری؛ ناسازگار با agentId)
prompt متن هدف؛ از جایگزینی {{key}} پشتیبانی می‌کند (اجباری)
dispatchMode allParallel (پیش‌فرض — یک وظیفه برای هر عضو) یا manager (تنها رهبر را برای هماهنگی اعزام می‌کند)
outputKey کلید حالت برای خروجی‌های برداشت‌شدهٔ اعضا
outputSchema, label, extras.spaceId مانند conversation.promptAgent

دروازهٔ تأیید. عامل تأییدکننده را با پرامپت دروازه و قرارداد خروجی {decision, reason} در یک گفتگو (حالت review) اعزام می‌کند و سپس تا زمانی که تأییدکننده از راه submit_output تسلیم نکند معلق می‌ماند.

فیلد پیکربندی توضیح
agentId عامل تأییدکننده (اجباری)
prompt پرامپت دروازه (اختیاری؛ در نبودش یک پیش‌فرض به کار می‌رود)
outputKey کلید حالت برای بار دادهٔ برداشت‌شدهٔ {decision, reason}
outputSchema به‌طور پیش‌فرض یک طرح‌وارهٔ تأیید است (decision: approved / rejected، reason)
label, extras.spaceId مانند conversation.promptAgent

دروازه فقط از راه submit_output حل می‌شود. BuiltInBodyKeys.humanGate، کتابخانهٔ نوع گره و متن پرامپت یک قالب داخلی، همه ابزارهای MCP با نام approve_step و reject_step را نام می‌برند؛ هیچ‌یک از این دو ابزار در هیچ بسته یا رجیستری‌ای وجود ندارد.

worktreeهای ایزولهٔ کهنه را حذف می‌کند؛ حالتش را از بار دادهٔ تریگر برمی‌دارد. پرچم dryRun اجرا را رعایت می‌کند.

کلید حالت توضیح
ticket_id worktreeهای آن تیکت را آزاد می‌کند
repo_full_name + pr_number worktree موقت ویرایشگر PR را آزاد می‌کند
space_id worktreeها و پوشهٔ آن گفتگو را برمی‌چیند
(هیچ‌یک از موارد بالا) فضای کاری را جاروب می‌کند: دایرکتوری‌های ناپدیدشده، فضاهای مرده، پوشه‌های گفتگوی یتیم

outputKey (اختیاری) یک رشتهٔ خلاصه دریافت می‌کند.

Map / پخش روی یک مجموعهٔ حالت: پرامپت را یک بار به‌ازای هر آیتم رندر می‌کند، سپس عامل را یک بار با پرامپت‌های به‌هم‌چسبیده (--- به‌عنوان جداکننده) اعزام می‌کند و تا پایان آن اجرا معلق می‌ماند. یک مجموعهٔ خالی بی‌درنگ با فهرستی خالی کامل می‌شود. این یک اعزام موازی به‌ازای هر آیتم نیست.

فیلد پیکربندی توضیح
agentId عاملی که به‌ازای هر آیتم اعزام می‌شود (اجباری)
prompt پرامپت هر آیتم؛ از جایگزینی {{key}} پشتیبانی می‌کند (اجباری)
extras.iterableKey کلید حالتی که مجموعه را نگه می‌دارد (اجباری)
extras.itemKey کلیدی که آیتم جاری در پرامپت به آن بسته می‌شود (پیش‌فرض item)
outputKey کلید حالت برای خروجی برداشت‌شده (یک اعزام، نه یک فهرست)

قالب پایپ‌لاین دیگری را به‌عنوان زیرگامی تودرتو اجرا می‌کند (زیرپایپ‌لاین به‌عنوان یک اجرای فرزند با parentPipelineRunId تنظیم‌شده اجرا می‌شود). گام تا رسیدن فرزند به وضعیت پایانی معلق می‌ماند، سپس حالت نهایی فرزند زیر outputKey ادغام می‌شود.

فیلد پیکربندی توضیح
extras.templateId قالب فرزند برای اجرا (اجباری؛ یک پایپ‌لاین نمی‌تواند خودش را فراخوانی کند)
inputKeys کلیدهای حالتی که در بار دادهٔ تریگر فرزند کپی می‌شوند
outputKey کلید حالت برای حالت نهایی ادغام‌شدهٔ فرزند

ایندکس‌گذاری پس‌زمینهٔ tree-sitter: مخزن را می‌پیماید، نمادها/یال‌ها را در ایزوله‌های کارگر استخراج می‌کند و آن‌ها را در گراف کد فضای کاری می‌بلعد. پیشرفت را به ردیف اجرای گام جریان می‌دهد؛ از dry-run پشتیبانی می‌کند. tree-sitter و گرامرهایش از بومی‌های الزامی‌اند — نبود یک dylib یعنی سرور هرگز راه‌اندازی نشده است، و گرامری که در میانهٔ اجرا حل نشود، گام را به‌جای صرف‌نظر کردن ناموفق می‌کند.

کلید حالت توضیح
repo_id مخزن برای ایندکس‌گذاری (اجباری)
repo_local_path مسیر محلی چک‌اوت (اجباری)

تفکیک گویندهٔ برون‌خط. صدای نگه‌داشته‌شدهٔ جلسه را می‌خواند، آن را در گوینده‌ها خوشه‌بندی می‌کند (Person 1، Person 2، …)، قطعه‌های رونویسی را دوباره برچسب می‌زند و حالت transcript را بازنویسی می‌کند؛ همچنین diarization_spans را برای گام موازی meeting.updateTranscript منتشر می‌کند. هنگامی که صدایی نگه داشته نشده باشد یا مدل‌ها نصب نباشند، رونویسی را بدون تغییر عبور می‌دهد.

کلید حالت توضیح
meeting_id جلسه برای تفکیک گوینده (اجباری)

meeting.saveNotes, meeting.addActionItems, meeting.addDecisions

بخش با عنوان “meeting.saveNotes, meeting.addActionItems, meeting.addDecisions”

بدنه‌های قطعی ماندگارسازی خلاصهٔ جلسه. هرکدام meeting_id و بار دادهٔ ساختاریافتهٔ meeting_outcome گام عامل ({summary, enhancedNotes, actionItems[], decisions[]}) را از حالت می‌خواند و بخش خودش را در جدول خودش می‌نویسد — یادداشت‌ها، آیتم‌های کنشی یا تصمیم‌ها. ردیف‌های پیش‌تر ذخیره‌شده هرگز در یک اجرای تنزل‌کرده پاک نمی‌شوند.

کلید بدنه توضیح
meeting.identifySpeakers بازشناسی گوینده میان جلسه‌ها: گوینده‌های تفکیک‌شده را با نمایه‌های صوتی ذخیره‌شده تطبیق می‌دهد و تطبیق‌های مطمئن را خودکار اعمال می‌کند. بدون نمایه‌ها/تعبیه‌ها بی‌اثر است.
meeting.updateTranscript برچسب‌های Person N را از diarization_spans اعمال می‌کند و قطعه‌های هر پنجره را در نوبت‌های هر گوینده ادغام می‌کند، سپس رونویسی پاک‌سازی‌شده را ماندگار می‌کند. هنگامی که تفکیک گوینده چیزی تولید نکرده باشد بی‌اثر است.
meeting.assemblePlayback ترک پخش میکس‌شدهٔ جلسه را از WAVهای نگه‌داشته‌شدهٔ هر کانال می‌سازد. هنگامی که صدایی نگه داشته نشده باشد بی‌اثر است.
orchestration.markPhase در پایان DAG کار، برای زیرتیکت‌های بدون خروجی نشانه‌های شکست می‌نویسد و ارکستراسیون را به synthesizing می‌چرخاند.
orchestration.persistDeliverable خروجی سنتز را در تیکت والد می‌نویسد، آن را کامل می‌کند، تحویل‌دادنی را منتشر می‌کند و ارکستراسیون را completed علامت می‌زند.
orchestration.awaitApproval دروازهٔ تأیید جزئی: هنگامی که کلید گره گام در مجموعهٔ تأییدشدهٔ ارکستراسیون باشد بی‌درنگ کامل می‌شود، و در غیر این صورت تا زمانی که تأییدی بعدی آن را از سر بگیرد معلق می‌ماند. این تنها بدنه‌ای است که extras.awaitApproval را تنظیم می‌کند و همین آن را از مهلت 24 ساعتهٔ گام معلق مستثنا می‌کند.
messaging.createSpace گفتگویی را باز می‌کند که بقیهٔ قالب در آن کار می‌کند و زیر outputKey گام منتشر می‌شود (قالب‌های داخلی از pipeline_space_id استفاده می‌کنند). فهرست خالی repoIds هیچ چیز را چک‌اوت نمی‌کند؛ extras['allRepos'] هر مخزن فضای کاری را چک‌اوت می‌کند. extras['createConversation'] (به‌طور پیش‌فرض خاموش) یک جریان نام‌دار هم باز می‌کند. یک گام عامل به یک اتاق می‌پیوندد و هرگز یکی باز نمی‌کند، پس یک پخش بدون این گره هنگام اعزام ناموفق می‌شود — و سیم‌کشی یک‌بارهٔ آن یعنی کل پخش یک چک‌اوت مشترک دارد به‌جای آنکه برای هرکدام یکی تدارک دیده شود.
prReview.finalize آخرین گام قالب بازبینی PR: گره‌های بازبینی انباشته‌شده را در سطل‌های اجماع مرتب می‌کند و حکم هر PR را محاسبه می‌کند.
skills.analyze اسکن زنجیرهٔ تأمین مهارت‌ها را روی مهارت‌های نصب‌شدهٔ یک فضای کاری اجرا می‌کند و حکم هرکدام را ثبت می‌کند.

بدنهٔ یک گام یک StepResult (packages/cc_domain/lib/features/pipelines/domain/entities/step_result.dart) برمی‌گرداند. همهٔ سازنده‌ها یک نقشهٔ اختیاری mutatedState می‌پذیرند که در حالت پایپ‌لاین ادغام می‌شود، به‌جز failed.

سازنده امضا توضیح
ok StepResult.ok({mutatedState}) کامل‌شدن عادی؛ شنونده‌های پایین‌دستی ارزیابی می‌شوند
route StepResult.route(nextRouterKey, {mutatedState}) کامل‌شدن router؛ شاخهٔ پایین‌دستی‌ای را انتخاب می‌کند که routeKeyاش منطبق باشد
suspendUntilEvent StepResult.suspendUntilEvent(eventType, {mutatedState}) توقف تا زمانی که نوع رویداد دامنهٔ مشخصی برانگیخته شود
suspendUntilTasksComplete StepResult.suspendUntilTasksComplete(taskIds, {mutatedState}) توقف تا زمانی که همهٔ وظیفه‌های فهرست‌شده به وضعیت پایانی برسند
terminal StepResult.terminal({mutatedState}) اجرای پایپ‌لاین تمام شده است — دیگر گامی نیست
failed StepResult.failed(errorMessage) گام با یک پیام خطا ناموفق شد

رفتار تلاش دوباره برای بدنهٔ گرهی ناموفق (PipelineNodeConfig.retryPolicy؛ مقدار null تلاش‌های دوباره را غیرفعال می‌کند).

فیلد نوع توضیح
maxAttempts int مجموع تلاش‌ها با احتساب تلاش نخست (3 = 1 تلاش + 2 تلاش دوباره)؛ باید ≥ 1 باشد
backoff String linear یا exponential (پیش‌فرض)
initialDelayMs int تأخیر پیش از نخستین تلاش دوباره، به میلی‌ثانیه؛ تأخیرهای بعدی بر پایهٔ backoff رشد می‌کنند

پیکربندی هر گره که درون تعریف گام حمل می‌شود (packages/cc_domain/lib/features/pipelines/domain/entities/pipeline_node_config.dart). گره‌های داخلی و سفارشی هر دو این شکل را به اشتراک می‌گذارند؛ هر بدنه تنها فیلدهایی را می‌خواند که برایش مهم‌اند.

فیلد نوع توضیح
prompt String? قالب پرامپت با جایگزینی {{key}}
script String? بدنهٔ اسکریپت Bash با جایگزینی {{key}}
agentId String? UUID عامل در محدودهٔ فضای کاری برای اعزام
inputKeys List<String> کلیدهای حالتی که این گره به‌عنوان ورودی مصرف می‌کند
repoIds List<String> مخزن‌هایی که گره messaging.createSpace چک‌اوت می‌کند (<repoId> یا <repoId>@<branch>). خالی = هیچ‌کدام؛ extras['allRepos'] = هر مخزن فضای کاری. در گام‌های عامل نادیده گرفته می‌شود.
outputKey String? کلید حالتی که خروجی این گره زیر آن نوشته می‌شود
label String? برچسب انسانی نمایش‌داده‌شده روی بوم (به‌طور پیش‌فرض شناسهٔ گام)
outputSchema Map<String, dynamic>? طرح‌وارهٔ JSON (زیرمجموعه) که مقدار خروجی باید برآورده کند
reducer String? راهبرد ادغام هنگامی که شاخه‌های موازی همان outputKey را می‌نویسند: append، mergeLists، mergeMaps، sum یا override (پیش‌فرض)
retryPolicy StepRetryPolicy? سیاست تلاش دوباره در شکست بدنه؛ null = یک تلاش
continueOnFail bool هنگامی که true باشد، یک شکست پایانی اجرا را ناموفق نمی‌کند؛ خطا زیر state['_stepErrors'][stepId] انبار می‌شود
timeoutMs int? مهلت واقعی برای بدنهٔ گره به میلی‌ثانیه؛ null = بدون مهلت
teamId String? تیم برای اعزام (گره‌های team.dispatch)؛ ناسازگار با agentId
dispatchMode String? حالت اجرای تیم: allParallel یا manager
extras Map<String, dynamic> پیکربندی آزاد و مخصوص بدنه (مثلاً iterableKey، templateId، درخت‌های شرط)

دسترس‌گرهای مشتق: spaceId (extras['spaceId'] — گفتگوی موجودی که کار در آن انجام می‌شود)، createsConversation (extras['createConversation'])، conversationTitle (extras['conversationTitle'])، modeName (extras['mode'] — chat / review / plan، روی گرهٔ بازکنندهٔ فضا خوانده می‌شود) و runWhen (extras['runWhen'] — در صورت برآورده نشدن، گره را رد می‌کند).