chainlesschain 0.163.7 → 0.163.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/assets/web-panel/assets/{AIOps-axqQfwv8.js → AIOps-CavM7W3k.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DV-Ro0By.js → ActionButton-CUvZGabQ.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Bt72WEVu.js → Analytics-DeBnWnbe.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BtepG55E.js → AppLayout-DbI5kxvd.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-B7KaJ7S_.js → Artifacts-D93bigKm.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-FNFaUg7A.js → Audit-CBNvfUZa.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DFb6J2wQ.js → BackgroundAgents-CJLyh_YU.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CC7YBhyj.js → Backup-D_0yoehD.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-RkgTNVtj.js → BaseInput-TJxmbObW.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-hHEmGZy-.js → Chat-CE0dto1q.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CAP9YhHv.js → ChatBubbleRenderer-CZ5-yYiD.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-z5wXOQP1.js → Checkbox-Ck1RVIVo.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DVaDJnxy.js → Codegen-qpoyf6DK.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CJmaRDR5.js → Col-DUyPWjIE.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DF29_2bI.js → Community-D_S1BemS.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DtkQkBzn.js → Compact-BjxeK-Gc.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-xoHDxp7I.js → Compliance-Dd3CEJsu.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BUm-R7ht.js → Cowork-B4QG7-ad.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Cgl14ZkB.js → Cron-BtZnids5.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BNcbmoqh.js → Crosschain-CHPfCBFD.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Bwja0Zo9.js → DID-DT8DCEOK.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Bk5XjEdJ.js → Dashboard-COQab5_U.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Ci36Oitq.js → Dropdown-BY1PsQuU.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer--U04ZN4q.js → EmailListRenderer-CsuAuaq3.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2gNPR2s.js → FamilyGuardDashboard-BqpinD-j.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-C4KghYn7.js → Federation-D0gkfQFv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-QL7x_Q_0.js → FormItemContext-BqgE-axK.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-F3Ryltwm.js → GenericCardRenderer-D0hJ2KvC.js} +1 -1
- package/src/assets/web-panel/assets/{Git-2HassK5k.js → Git-CmMB0uPY.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DoBIp7oe.js → Governance-BnVEI0Dk.js} +1 -1
- package/src/assets/web-panel/assets/{Inference--W01QhZ-.js → Inference-YTAMihRP.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DmvwqGpT.js → KnowledgeGraph-0ax7VHop.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BBJ4yAel.js → Logs-B9TRcokL.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-D5lNngSI.js → Marketplace-B6CSuD_H.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CkEVOMKH.js → McpTools-CjMXvOVU.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-B1Ow1xVE.js → Memory-CXRF71U3.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-SgYbUfb6.js → MobileBridge-DQgNp_oS.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BWdOvQAj.js → MobileProjects-DlPwcCbq.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DcTXSSma.js → Mtc-6hDTRPe1.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Dt3WG4oj.js → MtcAudit-BlVHU1DS.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-B9B38UZx.js → Multisig-DP9pzEbV.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-B0S4GGvG.js → NLProgramming-Djorh8EV.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DZ5U58Ng.js → Notes-oLZ-JkUg.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-PjL5ZW34.js → NotificationSettings-Cg288VH3.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DrAX2ESt.js → OrderTableRenderer-Bb1O3Ofr.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-Cv1GYs-c.js → Organization-CBdo-bHs.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Bbkp_PL3.js → Overflow-qZdnVumx.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BD8QUgoZ.js → P2P-D4kNfGNQ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BO-2PeaB.js → PdhVaultBrowser-DnlMemM7.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-D_OPVa02.js → Permissions-DHucHFBJ.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-mh-pEmaB.js → PersonalDataHub-BovlOIPR.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-6JC2EDdb.js → Pipeline-Deru3CQY.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CUshzUAG.js → Privacy-Bq5oTTbU.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Cs2Aalri.js → ProjectInit-BfzxVWAz.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-1ak49tcj.js → ProjectSettings-CKC6XBtH.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-BV4oApsm.js → Projects-CMolGhae.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-CXXxvafH.js → Providers-C_jx4TWX.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-PTcDsF58.js → QrScannerModal-BdIHeVGC.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CDwucrJw.js → QuickAsk-BwZwAcPD.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CJlLVRXR.js → Recommend-BNTt0L-m.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DlN-ETsO.js → RemoteSession-Biyn2-Ro.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DI23LR6m.js → Reputation-D6VpG32B.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Cl7UQMrM.js → Row-D_74OvQQ.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CexHNfh8.js → RssFeed-BTr0a-BQ.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BneBWvRN.js → Search-C3MCFoNU.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DX7Phgrp.js → Security-CqW9aJ6s.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BWXO8Mte.js → Services-Cw5GNaHF.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DCyOjKPJ.js → Skeleton-DZps5qeY.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CXqERsTB.js → Skills-C6NQ1znT.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-bhbrbz8E.js → Sla-DFP8G2Sh.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-3IPU0HBZ.js → SpeechSettings-ESt6MB6v.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DBNTQLbM.js → SyncSettings-BHnN98aM.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-quP0bkN-.js → Tasks-NiSCaOf-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BouWmgho.js → Templates-DsKFhW2C.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-qv0D9s7z.js → Tenant-CQ0E0ze5.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BxvbE8BB.js → Terminal-D_rBu_by.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-D-IeLnJ2.js → TimelineRenderer-D3Vm4Po4.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CFMKKyVG.js → Tokens-DNTxRH6q.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-L8as3UuJ.js → Trigger-Dgprz1ms.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-MxmA4VZG.js → Trust-B2rUnVBD.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C0VvJYRi.js → UkeySign-DEGQNc6_.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Bf5QZj8N.js → VideoEditing-jlsAx3Eh.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BIJ9riRz.js → Wallet-8jQih1ij.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-B8p9Mhkw.js → WebAuthn-XLeO6xIB.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BVsuaPen.js → WorkflowEditor-De_dgDAG.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BfkjoKpV.js → chat-CI19R_Sk.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DeAlsWK8.js → colors-DsYTOYN3.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cs97bz5j.js → compact-item-CM3-t_Qr.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BqbG60LH.js → createContext-BjxlBRZv.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-i_RY0b1X.js → hasIn-RDaWX_4i.js} +1 -1
- package/src/assets/web-panel/assets/{index-U4f5izHz.js → index-9R6BxAr0.js} +1 -1
- package/src/assets/web-panel/assets/{index-0-agYlWL.js → index-B-Z8eFUJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1CbOH1i.js → index-B0PMlbMs.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqBgBpgp.js → index-B5REnKt8.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcUXAB2s.js → index-B7WBt_4T.js} +1 -1
- package/src/assets/web-panel/assets/{index-CIG8fQ2_.js → index-B9O9YyWE.js} +1 -1
- package/src/assets/web-panel/assets/{index-gyFpvL7l.js → index-BCnZyIMA.js} +1 -1
- package/src/assets/web-panel/assets/{index-yObj1O4n.js → index-BGqqJfL0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DiSkx4UB.js → index-BHNYPO0b.js} +3 -3
- package/src/assets/web-panel/assets/{index-Bm7lLR4c.js → index-BKJr-TZp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOVkf1K3.js → index-BN6UPD2E.js} +1 -1
- package/src/assets/web-panel/assets/{index-BESLFt4q.js → index-Bi46Xu4u.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE2VtTlp.js → index-BlT2VAEK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmbfhJUP.js → index-C0yx-jtQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BYUVuwKt.js → index-C4gkzxkw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeWoNHau.js → index-CVQMeiwH.js} +1 -1
- package/src/assets/web-panel/assets/{index-PT_5sBMA.js → index-Cd3euP_4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgsqdnRV.js → index-Cd9OJhHG.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-3tEpTc.js → index-CiECJi-Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-BkBi5TmC.js → index-CjTrRt13.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2B4VPyP.js → index-CnHH7bnD.js} +1 -1
- package/src/assets/web-panel/assets/{index-dIHr4B_u.js → index-Cpqm1qfU.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5UkyA3c.js → index-CyOGN6a5.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dk7-v4hP.js → index-D0zcy54x.js} +1 -1
- package/src/assets/web-panel/assets/{index-ZxO_-E8a.js → index-D6sm5-Xq.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-JVTrpr.js → index-DIUnNOjG.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dk2qouAz.js → index-DX7tuWVJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuLQobzW.js → index-DXXtGMUJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUUrv141.js → index-DcPFB8qJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-D9evtvg2.js → index-DoQA0-52.js} +1 -1
- package/src/assets/web-panel/assets/{index-COdGA-8n.js → index-Drlnwr8F.js} +1 -1
- package/src/assets/web-panel/assets/index-Drz6yq0m.js +1 -0
- package/src/assets/web-panel/assets/{index-CED2PL_y.js → index-Dsij_KsN.js} +1 -1
- package/src/assets/web-panel/assets/{index-79V_zv1s.js → index-Dxge-xWl.js} +1 -1
- package/src/assets/web-panel/assets/{index-CG3PRyAL.js → index-DyIWssPC.js} +1 -1
- package/src/assets/web-panel/assets/{index-YXgLng0K.js → index-IeiL9RKc.js} +1 -1
- package/src/assets/web-panel/assets/{index-s1opAL-M.js → index-nAH87mQP.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf3WCLmy.js → index-pPL66J85.js} +1 -1
- package/src/assets/web-panel/assets/index-uWiUs7S_.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-C9h9yKL3.js → initDefaultProps-BTL88of4.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BvmLsPdu.js → motion-BUB2pXwB.js} +1 -1
- package/src/assets/web-panel/assets/{move-CoL4ekU1.js → move-egCkkOMm.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C4pMy6xV.js → mtc-parser-DAWhZC8c.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DPuJfNxx.js → omit-CvOxe_6d.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-D0KEeaK2.js → pickAttrs-DZUSLZ5Z.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BpkyINxt.js → placementArrow-BERxGNMY.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DQI_wOq8.js → responsiveObserve-DZuDfZ9n.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DYfdDiRg.js → slide-DO756sgI.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-B5dtvb0D.js → statusUtils-BRQlIz28.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CF310mSj.js → styleChecker-DCSfdybl.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D1Qp4BLp.js → useFlexGapSupport-LD8dWVve.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-C7_iyvJK.js → useFs-BX9uW2LK.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DZUt_fIm.js → usePersonalDataHub-BPSlPuHU.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-D3dsi0lZ.js → vnode-BmOILC9V.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-WdbOlvdQ.js → zoom-1iKowKGg.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/automation.js +103 -1
- package/src/commands/team-merge-review.js +937 -0
- package/src/commands/team.js +2 -0
- package/src/data/changelog.json +14 -1
- package/src/lib/agent-schedule-store.js +139 -28
- package/src/lib/agent-team/team-merge-review-store.js +765 -0
- package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
- package/src/lib/agent-team/team-merge-review.js +1847 -0
- package/src/lib/automation-center-incidents.js +314 -0
- package/src/lib/automation-center-runtime.js +448 -0
- package/src/lib/automation-center.js +182 -38
- package/src/lib/automation-engine.js +41 -0
- package/src/lib/automation-execution-authority.js +241 -12
- package/src/lib/automation-execution-incident.js +737 -0
- package/src/lib/cowork-cron.js +85 -14
- package/src/lib/scheduler-kernel/agenda-adapter.js +17 -7
- package/src/lib/scheduler-kernel/automation-adapter.js +105 -11
- package/src/lib/scheduler-kernel/automation-event-adapter.js +87 -11
- package/src/lib/scheduler-kernel/contract.js +91 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +12 -1
- package/src/lib/scheduler-kernel/loop-adapter.js +7 -1
- package/src/lib/scheduler-kernel/routine-adapter.js +7 -1
- package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
- package/src/lib/scheduler-kernel/runtime.js +176 -3
- package/src/lib/scheduler-kernel/store.js +1253 -45
- package/src/runtime/agent-core.js +10 -0
- package/src/runtime/mcp-config.js +81 -10
- package/src/assets/web-panel/assets/MarkdownRenderer-BLCZMzhJ.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +0 -1
- package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +0 -1
- package/src/assets/web-panel/assets/index-ChVT0p9u.js +0 -1
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
normalizeJson,
|
|
26
26
|
} from "./contract.js";
|
|
27
27
|
import { SchedulerRuntime } from "./runtime.js";
|
|
28
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
28
29
|
import { schedulerMigrationSourceDigest } from "./store.js";
|
|
29
30
|
import {
|
|
30
31
|
bindSchedulerAuthorityPolicy,
|
|
@@ -571,6 +572,7 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
571
572
|
}
|
|
572
573
|
return {
|
|
573
574
|
kind: COWORK_CRON_SCHEDULER_KIND,
|
|
575
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
574
576
|
async adjudicate({ occurrence, adjudication }) {
|
|
575
577
|
const payload = occurrence.payload;
|
|
576
578
|
const cwd = normalizedCwd(payload.cwd);
|
|
@@ -604,7 +606,7 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
604
606
|
}
|
|
605
607
|
return { continue: true };
|
|
606
608
|
},
|
|
607
|
-
async execute({ occurrence, signal }) {
|
|
609
|
+
async execute({ occurrence, signal, checkpoint }) {
|
|
608
610
|
const payload = occurrence.payload;
|
|
609
611
|
const expected = coworkCronScheduleSnapshot(payload?.schedule);
|
|
610
612
|
const expectedDigest = coworkCronScheduleDigest(expected);
|
|
@@ -662,6 +664,12 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
662
664
|
);
|
|
663
665
|
}
|
|
664
666
|
|
|
667
|
+
checkpoint({
|
|
668
|
+
deliveryId,
|
|
669
|
+
phase: "before_execution_bind",
|
|
670
|
+
scheduleId: expected.id,
|
|
671
|
+
});
|
|
672
|
+
|
|
665
673
|
current = bindSchedulerScheduleFire(cwd, expected.id, {
|
|
666
674
|
deliveryId,
|
|
667
675
|
occurrenceId: occurrence.id,
|
|
@@ -803,6 +811,9 @@ export function createCoworkCronSchedulerAdapter({ runTask, now } = {}) {
|
|
|
803
811
|
);
|
|
804
812
|
}
|
|
805
813
|
},
|
|
814
|
+
async resume(context) {
|
|
815
|
+
return this.execute(context);
|
|
816
|
+
},
|
|
806
817
|
classifyError(error) {
|
|
807
818
|
return {
|
|
808
819
|
retryable: error?.retryable === true,
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
normalizeJson,
|
|
8
8
|
} from "./contract.js";
|
|
9
9
|
import { SchedulerRuntime } from "./runtime.js";
|
|
10
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
10
11
|
import {
|
|
11
12
|
schedulerJobDefinitionDigest,
|
|
12
13
|
schedulerMigrationSourceDigest,
|
|
@@ -785,6 +786,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
785
786
|
const transientResults = new Map();
|
|
786
787
|
return {
|
|
787
788
|
kind: LOOP_SCHEDULER_KIND,
|
|
789
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
788
790
|
async adjudicate({ occurrence, adjudication }) {
|
|
789
791
|
if (adjudication.decision === "confirmed_applied") {
|
|
790
792
|
const match = /^iteration:(\d+)$/.exec(occurrence.triggerKey);
|
|
@@ -799,7 +801,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
799
801
|
}
|
|
800
802
|
return { continue: true };
|
|
801
803
|
},
|
|
802
|
-
async execute({ occurrence, signal, adjudication }) {
|
|
804
|
+
async execute({ occurrence, signal, adjudication, checkpoint }) {
|
|
803
805
|
const definition = loopExecutionSnapshot(occurrence?.payload?.definition);
|
|
804
806
|
if (
|
|
805
807
|
occurrence.payload.snapshotDigest !== loopExecutionDigest(definition)
|
|
@@ -826,6 +828,7 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
826
828
|
`Loop iteration may already have produced side effects; refusing replay: ${occurrence.id}`,
|
|
827
829
|
);
|
|
828
830
|
}
|
|
831
|
+
checkpoint({ iteration, phase: "before_runner" });
|
|
829
832
|
const result =
|
|
830
833
|
(await runIteration(iteration, { signal, definition })) || {};
|
|
831
834
|
const persisted = persistedIterationResult(iteration, result);
|
|
@@ -835,6 +838,9 @@ export function createLoopSchedulerAdapter({ runIteration } = {}) {
|
|
|
835
838
|
});
|
|
836
839
|
return persisted;
|
|
837
840
|
},
|
|
841
|
+
async resume(context) {
|
|
842
|
+
return this.execute(context);
|
|
843
|
+
},
|
|
838
844
|
classifyError() {
|
|
839
845
|
return { retryable: false };
|
|
840
846
|
},
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
normalizeIdentifier,
|
|
14
14
|
} from "./contract.js";
|
|
15
15
|
import { SchedulerRuntime } from "./runtime.js";
|
|
16
|
+
import { CHECKPOINT_V1_RUNTIME_CONTROL } from "./runtime-control-capabilities.js";
|
|
16
17
|
import { schedulerMigrationSourceDigest } from "./store.js";
|
|
17
18
|
import {
|
|
18
19
|
bindSchedulerAuthorityPolicy,
|
|
@@ -772,6 +773,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
772
773
|
}
|
|
773
774
|
return {
|
|
774
775
|
kind: ROUTINE_SCHEDULER_KIND,
|
|
776
|
+
runtimeControl: CHECKPOINT_V1_RUNTIME_CONTROL,
|
|
775
777
|
async adjudicate({ occurrence, adjudication }) {
|
|
776
778
|
const payload = occurrence.payload;
|
|
777
779
|
const expected = payload?.routine;
|
|
@@ -812,7 +814,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
812
814
|
}
|
|
813
815
|
return { continue: true };
|
|
814
816
|
},
|
|
815
|
-
async execute({ occurrence, adjudication }) {
|
|
817
|
+
async execute({ occurrence, adjudication, checkpoint }) {
|
|
816
818
|
const payload = occurrence.payload;
|
|
817
819
|
const expected = payload?.routine;
|
|
818
820
|
if (!expected) {
|
|
@@ -884,6 +886,7 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
884
886
|
`Routine was disabled before scheduled execution: ${expected.id}`,
|
|
885
887
|
);
|
|
886
888
|
}
|
|
889
|
+
checkpoint({ phase: "before_run_bind", runId: schedulerRunId });
|
|
887
890
|
const execution = await executeRoutine(
|
|
888
891
|
routineStore,
|
|
889
892
|
effectiveCurrent,
|
|
@@ -912,6 +915,9 @@ export function createRoutineSchedulerAdapter({ routineStore, runAgent } = {}) {
|
|
|
912
915
|
}
|
|
913
916
|
return execution;
|
|
914
917
|
},
|
|
918
|
+
async resume(context) {
|
|
919
|
+
return this.execute(context);
|
|
920
|
+
},
|
|
915
921
|
classifyError(error) {
|
|
916
922
|
return { retryable: error?.retryable !== false };
|
|
917
923
|
},
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RUNTIME_CONTROL_SAFE_POINTS,
|
|
3
|
+
RUNTIME_CONTROL_SCHEMA_VERSION,
|
|
4
|
+
RUNTIME_PAUSE_RESUME,
|
|
5
|
+
normalizeRuntimeControlCapability,
|
|
6
|
+
} from "./contract.js";
|
|
7
|
+
import { RUNTIME_CONTROL_JOB_KINDS } from "./store.js";
|
|
8
|
+
|
|
9
|
+
/** Canonical cooperative pause/resume declaration for production adapters. */
|
|
10
|
+
export const CHECKPOINT_V1_RUNTIME_CONTROL = normalizeRuntimeControlCapability({
|
|
11
|
+
schemaVersion: RUNTIME_CONTROL_SCHEMA_VERSION,
|
|
12
|
+
pauseResume: RUNTIME_PAUSE_RESUME.CHECKPOINT_V1,
|
|
13
|
+
safePoints: [
|
|
14
|
+
RUNTIME_CONTROL_SAFE_POINTS.BEFORE_EXECUTE,
|
|
15
|
+
RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
|
|
16
|
+
],
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const NO_RUNTIME_CONTROL = normalizeRuntimeControlCapability();
|
|
20
|
+
|
|
21
|
+
const automationCenterJobKinds = new Set(RUNTIME_CONTROL_JOB_KINDS);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Resolve Automation Center capabilities without trusting a caller-supplied
|
|
25
|
+
* adapter. Unknown kinds deliberately remain unsupported.
|
|
26
|
+
*/
|
|
27
|
+
export function resolveAutomationCenterRuntimeControl(jobKind) {
|
|
28
|
+
return automationCenterJobKinds.has(jobKind)
|
|
29
|
+
? CHECKPOINT_V1_RUNTIME_CONTROL
|
|
30
|
+
: NO_RUNTIME_CONTROL;
|
|
31
|
+
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import {
|
|
3
3
|
OCCURRENCE_STATUS,
|
|
4
|
+
RUNTIME_CONTROL_SCHEMA_VERSION,
|
|
5
|
+
RUNTIME_CONTROL_SAFE_POINTS,
|
|
6
|
+
RUNTIME_PAUSE_RESUME,
|
|
4
7
|
SchedulerKernelError,
|
|
8
|
+
canonicalJson,
|
|
5
9
|
normalizeEpochMs,
|
|
6
10
|
normalizeIdentifier,
|
|
7
11
|
normalizeJson,
|
|
12
|
+
normalizeRuntimeControlCapability,
|
|
8
13
|
} from "./contract.js";
|
|
9
14
|
|
|
10
15
|
export const DEFAULT_RUNTIME_LEASE_MS = 60_000;
|
|
@@ -17,6 +22,15 @@ const TERMINAL_OCCURRENCE_STATUSES = new Set([
|
|
|
17
22
|
OCCURRENCE_STATUS.DEAD_LETTER,
|
|
18
23
|
]);
|
|
19
24
|
|
|
25
|
+
class SchedulerPauseSignal extends Error {
|
|
26
|
+
constructor(control, checkpoint) {
|
|
27
|
+
super("Scheduler adapter reached a requested pause checkpoint");
|
|
28
|
+
this.name = "SchedulerPauseSignal";
|
|
29
|
+
this.control = control;
|
|
30
|
+
this.checkpoint = checkpoint;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
20
34
|
function runtimeError(code, message, details = undefined, cause = undefined) {
|
|
21
35
|
return new SchedulerKernelError(
|
|
22
36
|
code,
|
|
@@ -95,7 +109,21 @@ function normalizeAdapter(adapter) {
|
|
|
95
109
|
`Scheduler adapter must implement execute(): ${kind}`,
|
|
96
110
|
);
|
|
97
111
|
}
|
|
98
|
-
|
|
112
|
+
const runtimeControl = normalizeRuntimeControlCapability(
|
|
113
|
+
adapter.runtimeControl,
|
|
114
|
+
);
|
|
115
|
+
if (
|
|
116
|
+
runtimeControl.safePoints.includes(
|
|
117
|
+
RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
|
|
118
|
+
) &&
|
|
119
|
+
typeof adapter.resume !== "function"
|
|
120
|
+
) {
|
|
121
|
+
throw runtimeError(
|
|
122
|
+
"SCHEDULER_RUNTIME_INVALID_ADAPTER",
|
|
123
|
+
`Scheduler adapter must implement resume() for adapter checkpoints: ${kind}`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return { kind, adapter, runtimeControl };
|
|
99
127
|
}
|
|
100
128
|
|
|
101
129
|
function normalizeAdapters(adapters = []) {
|
|
@@ -268,6 +296,14 @@ export class SchedulerRuntime {
|
|
|
268
296
|
return this;
|
|
269
297
|
}
|
|
270
298
|
|
|
299
|
+
runtimeControlFor(jobKind) {
|
|
300
|
+
const kind = normalizeIdentifier(jobKind, "jobKind", { maxLength: 128 });
|
|
301
|
+
const adapter = this.adapters.get(kind);
|
|
302
|
+
return adapter
|
|
303
|
+
? normalizeRuntimeControlCapability(adapter.runtimeControl)
|
|
304
|
+
: normalizeRuntimeControlCapability();
|
|
305
|
+
}
|
|
306
|
+
|
|
271
307
|
async _settleRejected(occurrence, error, retryable = false) {
|
|
272
308
|
const settled = this.store.settle({
|
|
273
309
|
occurrenceId: occurrence.id,
|
|
@@ -314,6 +350,9 @@ export class SchedulerRuntime {
|
|
|
314
350
|
),
|
|
315
351
|
);
|
|
316
352
|
}
|
|
353
|
+
const runtimeControl = normalizeRuntimeControlCapability(
|
|
354
|
+
adapter.runtimeControl,
|
|
355
|
+
);
|
|
317
356
|
|
|
318
357
|
let decision;
|
|
319
358
|
let allowed = false;
|
|
@@ -368,6 +407,103 @@ export class SchedulerRuntime {
|
|
|
368
407
|
aborted.retryable = true;
|
|
369
408
|
return this._settleRejected(occurrence, aborted, true);
|
|
370
409
|
}
|
|
410
|
+
const readBoundControl = (state) => {
|
|
411
|
+
if (typeof this.store.getOccurrenceControl !== "function") return null;
|
|
412
|
+
const control = this.store.getOccurrenceControl(occurrence.id);
|
|
413
|
+
if (control?.state !== state) return null;
|
|
414
|
+
if (
|
|
415
|
+
runtimeControl.pauseResume !== RUNTIME_PAUSE_RESUME.CHECKPOINT_V1 ||
|
|
416
|
+
canonicalJson(control.capability, "runtimeControl.persisted") !==
|
|
417
|
+
canonicalJson(runtimeControl, "runtimeControl.adapter")
|
|
418
|
+
) {
|
|
419
|
+
throw runtimeError(
|
|
420
|
+
"SCHEDULER_RUNTIME_CONTROL_CAPABILITY_MISMATCH",
|
|
421
|
+
`Scheduler runtime-control evidence no longer matches adapter capability: ${occurrence.id}`,
|
|
422
|
+
{
|
|
423
|
+
capabilityDigest: control.capabilityDigest,
|
|
424
|
+
adapterPauseResume: runtimeControl.pauseResume,
|
|
425
|
+
},
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
if (control.expectedFence !== occurrence.fence) {
|
|
429
|
+
throw runtimeError(
|
|
430
|
+
"SCHEDULER_RUNTIME_CONTROL_FENCE_MISMATCH",
|
|
431
|
+
`Scheduler runtime control is not bound to this claim: ${occurrence.id}`,
|
|
432
|
+
{
|
|
433
|
+
expectedFence: control.expectedFence,
|
|
434
|
+
actualFence: occurrence.fence,
|
|
435
|
+
},
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
return control;
|
|
439
|
+
};
|
|
440
|
+
const readPendingPause = () => readBoundControl("pause_requested");
|
|
441
|
+
const readResumingControl = () => {
|
|
442
|
+
const control = readBoundControl("resumed");
|
|
443
|
+
if (!control) return null;
|
|
444
|
+
const checkpoint = control.checkpoint;
|
|
445
|
+
if (
|
|
446
|
+
!checkpoint ||
|
|
447
|
+
checkpoint.schemaVersion !== RUNTIME_CONTROL_SCHEMA_VERSION ||
|
|
448
|
+
!Object.values(RUNTIME_CONTROL_SAFE_POINTS).includes(
|
|
449
|
+
checkpoint.safePoint,
|
|
450
|
+
) ||
|
|
451
|
+
!Object.hasOwn(checkpoint, "data") ||
|
|
452
|
+
!runtimeControl.safePoints.includes(checkpoint.safePoint)
|
|
453
|
+
) {
|
|
454
|
+
throw runtimeError(
|
|
455
|
+
"SCHEDULER_RUNTIME_RESUME_CHECKPOINT_INVALID",
|
|
456
|
+
`Scheduler resume checkpoint is invalid for adapter: ${occurrence.id}`,
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
return control;
|
|
460
|
+
};
|
|
461
|
+
const acknowledgePause = (control, safePoint, checkpoint) => {
|
|
462
|
+
if (typeof this.store.ackOccurrencePause !== "function") {
|
|
463
|
+
throw runtimeError(
|
|
464
|
+
"SCHEDULER_RUNTIME_CONTROL_STORE_UNSUPPORTED",
|
|
465
|
+
"Scheduler store cannot acknowledge durable runtime controls",
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
const acknowledged = this.store.ackOccurrencePause({
|
|
469
|
+
occurrenceId: occurrence.id,
|
|
470
|
+
ownerId: this.ownerId,
|
|
471
|
+
fence: occurrence.fence,
|
|
472
|
+
requestId: control.pauseRequestId,
|
|
473
|
+
expectedRevision: control.revision,
|
|
474
|
+
safePoint,
|
|
475
|
+
checkpoint,
|
|
476
|
+
});
|
|
477
|
+
return {
|
|
478
|
+
status: "paused",
|
|
479
|
+
occurrence: acknowledged.occurrence,
|
|
480
|
+
control: acknowledged.control,
|
|
481
|
+
result: null,
|
|
482
|
+
error: null,
|
|
483
|
+
};
|
|
484
|
+
};
|
|
485
|
+
let pendingPause;
|
|
486
|
+
let resumingControl;
|
|
487
|
+
try {
|
|
488
|
+
pendingPause = readPendingPause();
|
|
489
|
+
resumingControl = readResumingControl();
|
|
490
|
+
} catch (error) {
|
|
491
|
+
linked.dispose();
|
|
492
|
+
return this._settleRejected(occurrence, error, false);
|
|
493
|
+
}
|
|
494
|
+
if (
|
|
495
|
+
pendingPause &&
|
|
496
|
+
runtimeControl.safePoints.includes(
|
|
497
|
+
RUNTIME_CONTROL_SAFE_POINTS.BEFORE_EXECUTE,
|
|
498
|
+
)
|
|
499
|
+
) {
|
|
500
|
+
linked.dispose();
|
|
501
|
+
return acknowledgePause(
|
|
502
|
+
pendingPause,
|
|
503
|
+
RUNTIME_CONTROL_SAFE_POINTS.BEFORE_EXECUTE,
|
|
504
|
+
{ adapterStarted: false },
|
|
505
|
+
);
|
|
506
|
+
}
|
|
371
507
|
let leaseError = null;
|
|
372
508
|
let renewing = false;
|
|
373
509
|
const renew = () => {
|
|
@@ -415,7 +551,26 @@ export class SchedulerRuntime {
|
|
|
415
551
|
: null,
|
|
416
552
|
signal: linked.controller.signal,
|
|
417
553
|
renewLease: renew,
|
|
554
|
+
runtimeControl,
|
|
555
|
+
resumeCheckpoint: resumingControl?.checkpoint ?? null,
|
|
556
|
+
checkpoint: (data = null) => {
|
|
557
|
+
if (
|
|
558
|
+
!runtimeControl.safePoints.includes(
|
|
559
|
+
RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
|
|
560
|
+
)
|
|
561
|
+
) {
|
|
562
|
+
return { pauseRequested: false };
|
|
563
|
+
}
|
|
564
|
+
const control = readPendingPause();
|
|
565
|
+
if (!control) return { pauseRequested: false };
|
|
566
|
+
throw new SchedulerPauseSignal(control, data);
|
|
567
|
+
},
|
|
418
568
|
};
|
|
569
|
+
const invokeAdapter = () =>
|
|
570
|
+
resumingControl?.checkpoint.safePoint ===
|
|
571
|
+
RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT
|
|
572
|
+
? adapter.resume(context, resumingControl.checkpoint)
|
|
573
|
+
: adapter.execute(context);
|
|
419
574
|
try {
|
|
420
575
|
let result;
|
|
421
576
|
if (context.adjudication?.status === "pending") {
|
|
@@ -466,9 +621,9 @@ export class SchedulerRuntime {
|
|
|
466
621
|
adjudicationRequestId: context.adjudication.requestId,
|
|
467
622
|
decision: context.adjudication.decision,
|
|
468
623
|
})
|
|
469
|
-
: await
|
|
624
|
+
: await invokeAdapter();
|
|
470
625
|
} else {
|
|
471
|
-
result = await
|
|
626
|
+
result = await invokeAdapter();
|
|
472
627
|
}
|
|
473
628
|
if (leaseError) throw leaseError;
|
|
474
629
|
if (linked.controller.signal.aborted) {
|
|
@@ -492,6 +647,13 @@ export class SchedulerRuntime {
|
|
|
492
647
|
return settledResult(settled);
|
|
493
648
|
} catch (error) {
|
|
494
649
|
if (leaseError) throw leaseError;
|
|
650
|
+
if (error instanceof SchedulerPauseSignal) {
|
|
651
|
+
return acknowledgePause(
|
|
652
|
+
error.control,
|
|
653
|
+
RUNTIME_CONTROL_SAFE_POINTS.ADAPTER_CHECKPOINT,
|
|
654
|
+
error.checkpoint,
|
|
655
|
+
);
|
|
656
|
+
}
|
|
495
657
|
let policy;
|
|
496
658
|
let settlementError = error;
|
|
497
659
|
try {
|
|
@@ -545,6 +707,17 @@ export class SchedulerRuntime {
|
|
|
545
707
|
leaseMs: this.leaseMs,
|
|
546
708
|
});
|
|
547
709
|
if (!claimed) {
|
|
710
|
+
const control =
|
|
711
|
+
typeof this.store.getOccurrenceControl === "function"
|
|
712
|
+
? this.store.getOccurrenceControl(id)
|
|
713
|
+
: null;
|
|
714
|
+
if (control?.state === "paused") {
|
|
715
|
+
return {
|
|
716
|
+
status: "paused",
|
|
717
|
+
occurrence: this.store.getOccurrence(id),
|
|
718
|
+
control,
|
|
719
|
+
};
|
|
720
|
+
}
|
|
548
721
|
return {
|
|
549
722
|
status: "busy",
|
|
550
723
|
occurrence: this.store.getOccurrence(id),
|