chainlesschain 0.163.6 → 0.163.7

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.
Files changed (218) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-DDIUofA8.js → AIOps-axqQfwv8.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-Bm-5xYRn.js → ActionButton-DV-Ro0By.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-D5UH4ljI.js → Analytics-Bt72WEVu.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-D_ifjOOP.js → AppLayout-BtepG55E.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BY1mXdC7.js → Artifacts-B7KaJ7S_.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-Bujr4Ml3.js → Audit-FNFaUg7A.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-sioKSTcC.js → BackgroundAgents-DFb6J2wQ.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DDOAK8RK.js → Backup-CC7YBhyj.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CtCsVVke.js → BaseInput-RkgTNVtj.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DpNj0vnd.js → Chat-hHEmGZy-.js} +4 -4
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZta3Ftr.js → ChatBubbleRenderer-CAP9YhHv.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-DoHVNSXq.js → Checkbox-z5wXOQP1.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DlVl7Qmv.js → Codegen-DVaDJnxy.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-GIqoPYty.js → Col-CJmaRDR5.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CIAPEVji.js → Community-DF29_2bI.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BN7JiI_h.js → Compact-DtkQkBzn.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CqUWCM9B.js → Compliance-xoHDxp7I.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-A4iPp7A4.js → Cowork-BUm-R7ht.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-B2zeXXWb.js → Cron-Cgl14ZkB.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BR2xmWr8.js → Crosschain-BNcbmoqh.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-BzFDjrIv.js → DID-Bwja0Zo9.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DKtDo3yA.js → Dashboard-Bk5XjEdJ.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-RNx43_YG.js → Dropdown-Ci36Oitq.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-SwMt4Rcy.js → EmailListRenderer--U04ZN4q.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CsYebZ4X.js → FamilyGuardDashboard-B2gNPR2s.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BmRKvBTy.js → Federation-C4KghYn7.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CVxGTA-0.js → FormItemContext-QL7x_Q_0.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-x2iXpyB7.js → GenericCardRenderer-F3Ryltwm.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DfqbkiOP.js → Git-2HassK5k.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-RuHyyj5O.js → Governance-DoBIp7oe.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-Bn7uZ7rI.js → Inference--W01QhZ-.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DlP7XefZ.js → KnowledgeGraph-DmvwqGpT.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-BYNdOiCd.js → Logs-BBJ4yAel.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-aMtgN-R6.js → MarkdownRenderer-BLCZMzhJ.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-JQYmDqM8.js → Marketplace-D5lNngSI.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Cyx4yZ-9.js → McpTools-CkEVOMKH.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-VDuGZTN2.js → Memory-B1Ow1xVE.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-_yKo97gi.js → MobileBridge-SgYbUfb6.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-CXRXW3q7.js → MobileProjects-BWdOvQAj.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-acTGtfLH.js → Mtc-DcTXSSma.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-ClpjXfkY.js → MtcAudit-Dt3WG4oj.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-_6Tn3o96.js → Multisig-B9B38UZx.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-CK7pbZzP.js → NLProgramming-B0S4GGvG.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-Czy6V_P8.js → Notes-DZ5U58Ng.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-Cqx-UVv3.js → NotificationSettings-PjL5ZW34.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-C69WDxGy.js → OrderTableRenderer-DrAX2ESt.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-DFnA9vLQ.js → Organization-Cv1GYs-c.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-ReZkk2yT.js → Overflow-Bbkp_PL3.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-DzjSI0aI.js → P2P-BD8QUgoZ.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-DKTf5xIP.js → PdhVaultBrowser-BO-2PeaB.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-DhQ5klhR.js → Permissions-D_OPVa02.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-CUL1iHrW.js → PersonalDataHub-mh-pEmaB.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-DU88iu4N.js → Pipeline-6JC2EDdb.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-Bw-sYfyK.js → Privacy-CUshzUAG.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-Bq3Q5y0z.js → ProjectInit-Cs2Aalri.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-C8spzpho.js → ProjectSettings-1ak49tcj.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-BV4oApsm.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-Bf4eTP9W.js → Providers-CXXxvafH.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-Dme9BDU1.js → QrScannerModal-PTcDsF58.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-CIXfv1rE.js → QuickAsk-CDwucrJw.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CIxvdeZ-.js → Recommend-CJlLVRXR.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C6k7MExI.js → RemoteSession-DlN-ETsO.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CISDz2bl.js → Reputation-DI23LR6m.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-CdnDxXyf.js → Row-Cl7UQMrM.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-C-QpRHsl.js → RssFeed-CexHNfh8.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DBjaGzSn.js → Search-BneBWvRN.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CQKukOeE.js → Security-DX7Phgrp.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-DZz86jWb.js → Services-BWXO8Mte.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-jb8RMK0d.js → Skeleton-DCyOjKPJ.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CdY76fZG.js → Skills-CXqERsTB.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-C_CSiZX9.js → Sla-bhbrbz8E.js} +1 -1
  73. package/src/assets/web-panel/assets/SpeechSettings-3IPU0HBZ.js +1 -0
  74. package/src/assets/web-panel/assets/{SyncSettings-qvimGO0O.js → SyncSettings-DBNTQLbM.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-Dng5LPJC.js → Tasks-quP0bkN-.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Bwqq5Wll.js → Templates-BouWmgho.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DNWuwP7Z.js → Tenant-qv0D9s7z.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-B-6Othpp.js → Terminal-BxvbE8BB.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DKpKZfzx.js → TimelineRenderer-D-IeLnJ2.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DzfGMd2J.js → Tokens-CFMKKyVG.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BXwUi74J.js → Trigger-L8as3UuJ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BNzUq4ui.js → Trust-MxmA4VZG.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-BYugxww4.js → UkeySign-C0VvJYRi.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DdauhtSJ.js → VideoEditing-Bf5QZj8N.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-CSC9bCe_.js → Wallet-BIJ9riRz.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Q8AN3bTO.js → WebAuthn-B8p9Mhkw.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-d-LBGCuA.js → WorkflowEditor-BVsuaPen.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BLVDCgsZ.js → chat-BfkjoKpV.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BZlPSEHl.js → colors-DeAlsWK8.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-IWseP6R6.js → compact-item-Cs97bz5j.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DnVRV3Ao.js → createContext-BqbG60LH.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DLQZA_Wn.js → hasIn-i_RY0b1X.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-B_N4-Gq9.js → index-0-agYlWL.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DB0MJgF_.js → index-79V_zv1s.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BOZJBTWZ.js → index-B-3tEpTc.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DUq0c7gq.js → index-B-JVTrpr.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Dy0R5ZED.js → index-B1CbOH1i.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-Bxp7uDD8.js → index-B5UkyA3c.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DpVrK6fr.js → index-BESLFt4q.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CT9vVN-X.js → index-BOVkf1K3.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DOoQpuQY.js → index-BYUVuwKt.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CINJQEj6.js → index-BcUXAB2s.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CarMTIyQ.js → index-BkBi5TmC.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C5dgnilC.js → index-Bm7lLR4c.js} +1 -1
  106. package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +1 -0
  107. package/src/assets/web-panel/assets/{index-CbQNL0ue.js → index-BuLQobzW.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CpBaJ3TD.js → index-CE2VtTlp.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-jWb70ZgZ.js → index-CED2PL_y.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BEu2lMBy.js → index-CG3PRyAL.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DocEhinm.js → index-CIG8fQ2_.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-D_LQodeJ.js → index-COdGA-8n.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DZpYeqrh.js → index-CeWoNHau.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-gt8bNefW.js → index-Cf3WCLmy.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-N_GoWZX4.js → index-CgsqdnRV.js} +1 -1
  116. package/src/assets/web-panel/assets/index-ChVT0p9u.js +1 -0
  117. package/src/assets/web-panel/assets/{index-CZDekj7T.js → index-D2B4VPyP.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-YSw_gxlZ.js → index-D9evtvg2.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DTbxp4UH.js → index-DUUrv141.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Bbj2NS_I.js → index-DiSkx4UB.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-BZs5bBnk.js → index-Dk2qouAz.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DalA0TKC.js → index-Dk7-v4hP.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-1jeAudHd.js → index-DmbfhJUP.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C1ifZtXo.js → index-DqBgBpgp.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BhA3QEni.js → index-PT_5sBMA.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BSjilZ9L.js → index-U4f5izHz.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-C2FqfMvU.js → index-YXgLng0K.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-COev0W2g.js → index-ZxO_-E8a.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-M7wxfAbm.js → index-dIHr4B_u.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DjWnONdy.js → index-gyFpvL7l.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Dkwsi1Kn.js → index-s1opAL-M.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-hwVDeoC0.js → index-yObj1O4n.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-Co67Kqmb.js → initDefaultProps-C9h9yKL3.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BMOxQSF_.js → motion-BvmLsPdu.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-C5fWDw-N.js → move-CoL4ekU1.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BJevpL0e.js → mtc-parser-C4pMy6xV.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-BCzNU8s6.js → omit-DPuJfNxx.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-CybWvDPk.js → pickAttrs-D0KEeaK2.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BMWS9HnW.js → placementArrow-BpkyINxt.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-BoL2UnGY.js → responsiveObserve-DQI_wOq8.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DWNfXraU.js → slide-DYfdDiRg.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BquTM3tX.js → statusUtils-B5dtvb0D.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-BEkCleim.js → styleChecker-CF310mSj.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Oecnq7EA.js → useFlexGapSupport-D1Qp4BLp.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-CkDffJ4F.js → useFs-C7_iyvJK.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-qbvKXesB.js → usePersonalDataHub-DZUt_fIm.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-C6v8n6mA.js → vnode-D3dsi0lZ.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-4CTeFILV.js → zoom-WdbOlvdQ.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +2 -2
  151. package/src/commands/agent.js +90 -1
  152. package/src/commands/chat.js +11 -2
  153. package/src/commands/compact.js +106 -23
  154. package/src/commands/loop.js +28 -10
  155. package/src/commands/routine.js +1 -1
  156. package/src/commands/scheduler-daemon.js +359 -2
  157. package/src/commands/session-observability.js +305 -0
  158. package/src/commands/session.js +38 -0
  159. package/src/data/changelog.json +14 -1
  160. package/src/gateways/ws/ws-agent-handler.js +439 -5
  161. package/src/harness/jsonl-session-store.js +463 -125
  162. package/src/harness/prompt-compressor.js +86 -13
  163. package/src/harness/provider-backed-compaction.js +100 -27
  164. package/src/lib/advisor-runtime.js +3 -1
  165. package/src/lib/agent-schedule-store.js +414 -4
  166. package/src/lib/agent-team/team-adjudication.js +40 -1
  167. package/src/lib/automation-engine.js +494 -0
  168. package/src/lib/background-agent-supervisor.js +793 -215
  169. package/src/lib/background-command-argv.js +24 -0
  170. package/src/lib/background-interaction-journal.js +361 -52
  171. package/src/lib/background-interaction-resolver.js +32 -0
  172. package/src/lib/background-launch-profile.js +2 -0
  173. package/src/lib/causal-observability.js +2661 -0
  174. package/src/lib/chat-session-admission.js +76 -0
  175. package/src/lib/cost-budget.js +5 -7
  176. package/src/lib/cowork/ab-comparator-cli.js +11 -0
  177. package/src/lib/cowork/debate-review-cli.js +12 -0
  178. package/src/lib/cowork-adapter.js +159 -38
  179. package/src/lib/cowork-cron.js +357 -1
  180. package/src/lib/cowork-task-runner.js +112 -17
  181. package/src/lib/delivery-coordinator.js +142 -0
  182. package/src/lib/direct-model-usage.js +121 -0
  183. package/src/lib/file-lines.js +183 -47
  184. package/src/lib/llm-pricing.js +12 -17
  185. package/src/lib/loop.js +26 -2
  186. package/src/lib/routine-store.js +380 -21
  187. package/src/lib/runtime-usage-ledger.js +182 -0
  188. package/src/lib/scheduler-kernel/agenda-adapter.js +308 -3
  189. package/src/lib/scheduler-kernel/automation-adapter.js +410 -8
  190. package/src/lib/scheduler-kernel/automation-event-adapter.js +36 -0
  191. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +285 -3
  192. package/src/lib/scheduler-kernel/loop-adapter.js +541 -6
  193. package/src/lib/scheduler-kernel/migration-admin.js +346 -0
  194. package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
  195. package/src/lib/scheduler-kernel/routine-adapter.js +394 -20
  196. package/src/lib/scheduler-kernel/runtime.js +63 -1
  197. package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
  198. package/src/lib/scheduler-kernel/store.js +2586 -85
  199. package/src/lib/session-host-lease.js +171 -2
  200. package/src/lib/session-host-snapshot.js +14 -3
  201. package/src/lib/session-persistence-failure.js +1 -0
  202. package/src/lib/session-tail.js +179 -34
  203. package/src/lib/session-transcript-structure.js +96 -0
  204. package/src/lib/sub-agent-context.js +328 -22
  205. package/src/lib/ws-agent-handler.js +4 -1
  206. package/src/repl/agent-repl.js +732 -91
  207. package/src/repl/chat-repl.js +5 -1
  208. package/src/runtime/agent-core.js +1272 -207
  209. package/src/runtime/fallback-model.js +5 -0
  210. package/src/runtime/headless-runner.js +324 -82
  211. package/src/runtime/headless-stream.js +232 -26
  212. package/src/runtime/policies/agent-policy.js +4 -0
  213. package/src/workers/background-agent-worker.js +403 -96
  214. package/src/assets/web-panel/assets/Projects-Dd-xuPIc.js +0 -1
  215. package/src/assets/web-panel/assets/SpeechSettings-C7tT9iad.js +0 -1
  216. package/src/assets/web-panel/assets/devWarning-Jzu62CLC.js +0 -1
  217. package/src/assets/web-panel/assets/index-Zb2MeDSy.js +0 -1
  218. package/src/assets/web-panel/assets/index-fikqml4k.js +0 -1
@@ -0,0 +1,182 @@
1
+ const MAX_LABEL_LENGTH = 160;
2
+ const MAX_CALL_ID_LENGTH = 128;
3
+ const MAX_ATTRIBUTION_ID_LENGTH = 256;
4
+ let fallbackToolSequence = 0;
5
+ const USAGE_FIELDS = Object.freeze([
6
+ ["input_tokens", "prompt_tokens"],
7
+ ["output_tokens", "completion_tokens"],
8
+ ["cache_read_input_tokens", "cache_read_tokens"],
9
+ ["cache_creation_input_tokens", "cache_creation_tokens"],
10
+ ]);
11
+ const SOURCES = new Set(["model", "semantic-compaction", "subagent"]);
12
+ const UNKNOWN_CODES = new Set([
13
+ "provider_call_failed",
14
+ "provider_usage_missing",
15
+ "provider_transport_outcome_unknown",
16
+ ]);
17
+
18
+ function cleanLabel(value, max = MAX_LABEL_LENGTH) {
19
+ if (typeof value !== "string") return null;
20
+ const clean = value.replace(/\p{Cc}/gu, "").trim();
21
+ return clean ? clean.slice(0, max) : null;
22
+ }
23
+
24
+ function tokenCount(usage, canonical, alias, { required = false } = {}) {
25
+ const hasCanonical = Object.hasOwn(usage, canonical);
26
+ const hasAlias = Object.hasOwn(usage, alias);
27
+ if (!hasCanonical && !hasAlias) {
28
+ if (required) {
29
+ throw new TypeError(
30
+ `runtime token usage requires ${canonical} or ${alias}`,
31
+ );
32
+ }
33
+ return 0;
34
+ }
35
+ if (hasCanonical && hasAlias && usage[canonical] !== usage[alias]) {
36
+ throw new TypeError("runtime token usage aliases conflict");
37
+ }
38
+ const selected = hasCanonical ? usage[canonical] : usage[alias];
39
+ if (
40
+ typeof selected !== "number" ||
41
+ !Number.isSafeInteger(selected) ||
42
+ selected < 0
43
+ ) {
44
+ throw new TypeError(
45
+ "runtime token usage must contain non-negative safe integers",
46
+ );
47
+ }
48
+ return selected;
49
+ }
50
+
51
+ function source(value, fallback = "model") {
52
+ return SOURCES.has(value) ? value : fallback;
53
+ }
54
+
55
+ function callId(value, { required = false } = {}) {
56
+ if (
57
+ typeof value !== "string" ||
58
+ !value.trim() ||
59
+ value.length > MAX_CALL_ID_LENGTH ||
60
+ /\p{Cc}/u.test(value)
61
+ ) {
62
+ if (!required && value === undefined) return null;
63
+ throw new TypeError("runtime usage boundary requires a bounded call id");
64
+ }
65
+ return value.trim();
66
+ }
67
+
68
+ function projectAttribution(value) {
69
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
70
+ const projected = {};
71
+ for (const field of [
72
+ "origin",
73
+ "skill",
74
+ "subagentId",
75
+ "role",
76
+ "parentSessionId",
77
+ ]) {
78
+ const clean = cleanLabel(value[field], MAX_ATTRIBUTION_ID_LENGTH);
79
+ if (clean) projected[field] = clean;
80
+ }
81
+ if (
82
+ typeof value.depth === "number" &&
83
+ Number.isSafeInteger(value.depth) &&
84
+ value.depth >= 0 &&
85
+ value.depth <= 64
86
+ ) {
87
+ projected.depth = value.depth;
88
+ }
89
+ return Object.keys(projected).length > 0 ? projected : null;
90
+ }
91
+
92
+ /** Project a runtime token event onto the secret-free persisted ledger schema. */
93
+ export function projectRuntimeTokenUsage(event = {}) {
94
+ if (
95
+ !event.usage ||
96
+ typeof event.usage !== "object" ||
97
+ Array.isArray(event.usage)
98
+ ) {
99
+ throw new TypeError("runtime token usage requires an object");
100
+ }
101
+ const usage = {};
102
+ for (const [index, [canonical, alias]] of USAGE_FIELDS.entries()) {
103
+ usage[canonical] = tokenCount(event.usage, canonical, alias, {
104
+ // A known settlement must prove both billable input and output counts.
105
+ // Cache counters are optional because many providers do not expose them.
106
+ required: index < 2,
107
+ });
108
+ }
109
+ if (Object.hasOwn(event.usage, "total_tokens")) {
110
+ const total = event.usage.total_tokens;
111
+ if (
112
+ typeof total !== "number" ||
113
+ !Number.isSafeInteger(total) ||
114
+ total < 0 ||
115
+ total !== usage.input_tokens + usage.output_tokens
116
+ ) {
117
+ throw new TypeError(
118
+ "runtime token usage total conflicts with components",
119
+ );
120
+ }
121
+ }
122
+ const projectedCallId = callId(event.callId);
123
+ const attribution = projectAttribution(event.attribution);
124
+ return {
125
+ provider: cleanLabel(event.provider),
126
+ model: cleanLabel(event.model),
127
+ usage,
128
+ ...(projectedCallId ? { callId: projectedCallId } : {}),
129
+ ...(event.source ? { source: source(event.source) } : {}),
130
+ ...(attribution ? { attribution } : {}),
131
+ };
132
+ }
133
+
134
+ /** Project started/unknown boundaries without retaining provider error text. */
135
+ export function projectRuntimeUsageBoundary(event = {}, outcome) {
136
+ if (outcome !== "started" && outcome !== "unknown") {
137
+ throw new TypeError(
138
+ "runtime usage boundary outcome must be started or unknown",
139
+ );
140
+ }
141
+ const projected = {
142
+ callId: callId(event.callId, { required: true }),
143
+ provider: cleanLabel(event.provider),
144
+ model: cleanLabel(event.model),
145
+ source: source(event.source),
146
+ };
147
+ const attribution = projectAttribution(event.attribution);
148
+ if (attribution) projected.attribution = attribution;
149
+ if (outcome === "unknown") {
150
+ projected.code = UNKNOWN_CODES.has(event.code)
151
+ ? event.code
152
+ : "provider_transport_outcome_unknown";
153
+ }
154
+ return projected;
155
+ }
156
+
157
+ export function runtimeUsageEventType(outcome) {
158
+ return outcome === "started" ? "model_usage_started" : "model_usage_unknown";
159
+ }
160
+
161
+ export function runtimeToolCallId(value) {
162
+ const projected = callId(value);
163
+ if (projected) return projected;
164
+ fallbackToolSequence = (fallbackToolSequence + 1) % Number.MAX_SAFE_INTEGER;
165
+ return `tool-${Date.now().toString(36)}-${fallbackToolSequence.toString(36)}`;
166
+ }
167
+
168
+ export function markRuntimeLedgerPersistenceError(error) {
169
+ if (error && (typeof error === "object" || typeof error === "function")) {
170
+ try {
171
+ error.runtimeLedgerPersistence = true;
172
+ if (error.runtimeLedgerPersistence === true) return error;
173
+ } catch {
174
+ // Frozen/non-extensible errors are wrapped below.
175
+ }
176
+ }
177
+ const wrapped = new Error("runtime usage ledger persistence failed", {
178
+ cause: error,
179
+ });
180
+ wrapped.runtimeLedgerPersistence = true;
181
+ return wrapped;
182
+ }
@@ -1,6 +1,8 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { effectiveFireAt } from "../schedule-planner.js";
3
3
  import {
4
+ agendaMigrationSourceDigest,
5
+ agendaMigrationSourceSnapshot,
4
6
  nextCronTime,
5
7
  normalizeTimeZone,
6
8
  parseCron,
@@ -13,10 +15,12 @@ import {
13
15
  normalizeJson,
14
16
  } from "./contract.js";
15
17
  import { SchedulerRuntime } from "./runtime.js";
18
+ import { schedulerMigrationSourceDigest } from "./store.js";
16
19
  import {
17
20
  bindSchedulerAuthorityPolicy,
18
21
  createSchedulerAuthorityResolver,
19
22
  } from "./authority-resolver.js";
23
+ import { canonicalSchedulerSourcePath } from "./source-locator-path.js";
20
24
 
21
25
  export const AGENDA_SCHEDULER_KIND = "agenda";
22
26
  export const AGENDA_SCHEDULER_CAPABILITY = "agent.execute";
@@ -188,6 +192,7 @@ function validateEntrySnapshot(entry) {
188
192
  const plain = { ...entry };
189
193
  delete plain.executionLease;
190
194
  delete plain.schedulerExecution;
195
+ delete plain.schedulerMigration;
191
196
  const snapshot = normalizeJson(plain, "agendaEntrySnapshot");
192
197
  snapshot.id = normalizeIdentifier(snapshot.id, "agenda.entry.id");
193
198
  if (!AGENDA_SCHEDULER_ENTRY_KINDS.includes(snapshot.kind)) {
@@ -361,6 +366,223 @@ export function syncAgendaSchedulerJob(schedulerStore, entry) {
361
366
  }
362
367
  }
363
368
 
369
+ export function migrateAgendaSchedulerEntry({
370
+ agendaStore,
371
+ schedulerStore,
372
+ entry,
373
+ }) {
374
+ const snapshot = agendaEntrySnapshot(entry);
375
+ const directory = canonicalSchedulerSourcePath(agendaStore.dir);
376
+ const sourceScope = { store: "agent-schedule", directory };
377
+ const sourceLocator = {
378
+ schemaVersion: 1,
379
+ type: "agenda-store",
380
+ directory,
381
+ };
382
+ let prepared = schedulerStore.getActiveDomainMigrationBySource({
383
+ domain: "agenda",
384
+ sourceScope,
385
+ sourceId: snapshot.id,
386
+ });
387
+ if (!prepared && agendaStore.dir !== directory) {
388
+ const ambiguousLegacy = schedulerStore.getActiveDomainMigrationBySource({
389
+ domain: "agenda",
390
+ sourceScope: {
391
+ store: "agent-schedule",
392
+ directory: agendaStore.dir,
393
+ },
394
+ sourceId: snapshot.id,
395
+ });
396
+ if (ambiguousLegacy) {
397
+ throw agendaError(
398
+ "AGENDA_SCHEDULER_MIGRATION_SOURCE_UNBOUND",
399
+ `Legacy Agenda migration uses a non-canonical path scope and cannot be bound safely: ${snapshot.id}`,
400
+ );
401
+ }
402
+ }
403
+ const desired = buildAgendaSchedulerJob(snapshot);
404
+ desired.authority = bindSchedulerAuthorityPolicy(
405
+ schedulerStore,
406
+ desired.authority,
407
+ );
408
+ const sourceDigest = agendaMigrationSourceDigest(entry);
409
+ const sourceSnapshot = agendaMigrationSourceSnapshot(entry);
410
+ if (prepared) {
411
+ const migrationEntries = prepared.entries.filter(
412
+ (candidate) =>
413
+ candidate.domain === "agenda" && candidate.sourceId === snapshot.id,
414
+ );
415
+ if (prepared.entries.length !== 1 || migrationEntries.length !== 1) {
416
+ throw agendaError(
417
+ "AGENDA_SCHEDULER_MIGRATION_DOMAIN_MISMATCH",
418
+ "Agenda entry belongs to an invalid mixed-domain migration",
419
+ );
420
+ }
421
+ const [migrationEntry] = migrationEntries;
422
+ schedulerStore.bindDomainMigrationSourceLocator({
423
+ migrationId: prepared.id,
424
+ entryId: migrationEntry.entryId,
425
+ sourceLocator,
426
+ expectedSourceDigest: migrationEntry.sourceDigest,
427
+ expectedTargetJobId: migrationEntry.targetJobId,
428
+ });
429
+ prepared = schedulerStore.getDomainMigration(prepared.id);
430
+ } else {
431
+ prepared = schedulerStore.prepareDomainMigration({
432
+ entries: [
433
+ {
434
+ domain: "agenda",
435
+ sourceId: snapshot.id,
436
+ sourceScope,
437
+ sourceLocator,
438
+ source: sourceSnapshot,
439
+ targetJob: desired,
440
+ rollbackStrategy: "disable",
441
+ },
442
+ ],
443
+ });
444
+ }
445
+ if (
446
+ prepared.entries.length !== 1 ||
447
+ prepared.entries[0].domain !== "agenda"
448
+ ) {
449
+ throw agendaError(
450
+ "AGENDA_SCHEDULER_MIGRATION_DOMAIN_MISMATCH",
451
+ "Agenda entry belongs to an invalid mixed-domain migration",
452
+ );
453
+ }
454
+ const expectedJournalDigest = schedulerMigrationSourceDigest(sourceSnapshot);
455
+ if (
456
+ prepared.entries[0].sourceDigest !== expectedJournalDigest ||
457
+ prepared.entries[0].targetJobId !== desired.id
458
+ ) {
459
+ throw agendaError(
460
+ "AGENDA_SCHEDULER_MIGRATION_SOURCE_CHANGED",
461
+ `Agenda entry changed after its scheduler migration started: ${snapshot.id}`,
462
+ );
463
+ }
464
+ let migration = prepared;
465
+ if (migration.state === "rolled_back" || migration.state === "rolling_back") {
466
+ throw agendaError(
467
+ "AGENDA_SCHEDULER_MIGRATION_STATE_CONFLICT",
468
+ `Agenda migration cannot resume from state ${migration.state}`,
469
+ );
470
+ }
471
+ if (migration.state === "retired") {
472
+ const migrationEntry = migration.entries[0];
473
+ agendaStore.retireForSchedulerMigration(snapshot.id, {
474
+ migrationId: migration.id,
475
+ sourceDigest,
476
+ targetJobId: desired.id,
477
+ retirementToken: migrationEntry.retirementToken,
478
+ });
479
+ return migration;
480
+ }
481
+ if (migration.state === "prepared") {
482
+ agendaStore.prepareSchedulerMigration(snapshot.id, {
483
+ migrationId: migration.id,
484
+ sourceDigest,
485
+ targetJobId: desired.id,
486
+ });
487
+ migration = schedulerStore.applyDomainMigration(migration.id);
488
+ }
489
+ if (migration.state === "applied") {
490
+ migration = schedulerStore.verifyDomainMigration(migration.id, {
491
+ sources: [
492
+ {
493
+ entryId: migration.entries[0].entryId,
494
+ source: agendaMigrationSourceSnapshot(entry),
495
+ },
496
+ ],
497
+ });
498
+ }
499
+ const retiring =
500
+ migration.state === "retiring"
501
+ ? migration
502
+ : schedulerStore.beginDomainMigrationRetirement(migration.id);
503
+ const retiringEntry = retiring.entries[0];
504
+ const retired = agendaStore.retireForSchedulerMigration(snapshot.id, {
505
+ migrationId: prepared.id,
506
+ sourceDigest,
507
+ targetJobId: desired.id,
508
+ retirementToken: retiringEntry.retirementToken,
509
+ });
510
+ schedulerStore.confirmDomainMigrationEntryRetired({
511
+ migrationId: prepared.id,
512
+ entryId: retiringEntry.entryId,
513
+ retirementToken: retiringEntry.retirementToken,
514
+ source: retired,
515
+ });
516
+ return schedulerStore.getDomainMigration(prepared.id);
517
+ }
518
+
519
+ export function rollbackAgendaSchedulerMigration({
520
+ agendaStore,
521
+ schedulerStore,
522
+ migrationId,
523
+ }) {
524
+ const directory = canonicalSchedulerSourcePath(agendaStore.dir);
525
+ const assertRollbackBinding = (migration) => {
526
+ if (
527
+ migration?.id !== migrationId ||
528
+ !Array.isArray(migration.entries) ||
529
+ migration.entries.length === 0 ||
530
+ migration.entries.some((entry) => entry.domain !== "agenda")
531
+ ) {
532
+ throw agendaError(
533
+ "AGENDA_SCHEDULER_MIGRATION_DOMAIN_MISMATCH",
534
+ "Agenda rollback cannot operate on a mixed-domain migration",
535
+ );
536
+ }
537
+ for (const entry of migration.entries) {
538
+ const locator = entry.sourceLocator;
539
+ if (
540
+ locator?.schemaVersion !== 1 ||
541
+ locator.type !== "agenda-store" ||
542
+ locator.directory !== directory
543
+ ) {
544
+ throw agendaError(
545
+ "AGENDA_SCHEDULER_MIGRATION_SOURCE_UNBOUND",
546
+ `Agenda rollback source locator does not match its store: ${entry.sourceId}`,
547
+ );
548
+ }
549
+ }
550
+ return migration;
551
+ };
552
+ const current = assertRollbackBinding(
553
+ schedulerStore.getDomainMigration(migrationId),
554
+ );
555
+ if (current.state === "rolled_back") {
556
+ return { ...current, deduplicated: true };
557
+ }
558
+ const migration = assertRollbackBinding(
559
+ schedulerStore.beginDomainMigrationRollback(migrationId),
560
+ );
561
+ if (migration.state === "rolled_back") return migration;
562
+ const entries = migration.entries;
563
+ for (const entry of entries) {
564
+ if (entry.state === "rolled_back") continue;
565
+ schedulerStore.restoreDomainMigrationEntrySource({
566
+ migrationId,
567
+ entryId: entry.entryId,
568
+ retirementToken: entry.retirementToken,
569
+ restoreSource: () => {
570
+ const current = agendaStore.get(entry.sourceId);
571
+ const restored = current.schedulerMigration
572
+ ? agendaStore.restoreFromSchedulerMigration(entry.sourceId, {
573
+ migrationId,
574
+ sourceDigest: agendaMigrationSourceDigest(current),
575
+ targetJobId: entry.targetJobId,
576
+ retirementToken: entry.retirementToken,
577
+ })
578
+ : current;
579
+ return agendaMigrationSourceSnapshot(restored);
580
+ },
581
+ });
582
+ }
583
+ return schedulerStore.getDomainMigration(migrationId);
584
+ }
585
+
364
586
  export function enqueueAgendaEntry(schedulerStore, entry) {
365
587
  const snapshot = agendaEntrySnapshot(entry);
366
588
  const job = syncAgendaSchedulerJob(schedulerStore, snapshot);
@@ -455,6 +677,40 @@ export function createAgendaSchedulerAdapter({
455
677
  }
456
678
  return {
457
679
  kind: AGENDA_SCHEDULER_KIND,
680
+ async adjudicate({ occurrence, adjudication }) {
681
+ const payload = occurrence.payload;
682
+ const expected = agendaEntrySnapshot(payload?.entry);
683
+ const expectedDigest = agendaEntrySnapshotDigest(expected);
684
+ if (
685
+ payload.snapshotDigest !== expectedDigest ||
686
+ typeof agendaStore.adjudicateSchedulerExecution !== "function"
687
+ ) {
688
+ throw agendaError(
689
+ "AGENDA_SCHEDULER_ADJUDICATION_UNSUPPORTED",
690
+ `Agenda adjudication cannot be applied: ${occurrence.id}`,
691
+ );
692
+ }
693
+ agendaStore.adjudicateSchedulerExecution(expected.id, {
694
+ occurrenceId: occurrence.id,
695
+ snapshotDigest: expectedDigest,
696
+ attempt: adjudication.expectedAttempt,
697
+ decision: adjudication.decision,
698
+ requestId: adjudication.requestId,
699
+ atMs: now(),
700
+ });
701
+ if (adjudication.decision === "confirmed_applied") {
702
+ return {
703
+ settled: true,
704
+ result: {
705
+ id: expected.id,
706
+ kind: expected.kind,
707
+ action: "adjudicated-applied",
708
+ adjudicationRequestId: adjudication.requestId,
709
+ },
710
+ };
711
+ }
712
+ return { continue: true };
713
+ },
458
714
  async execute({ occurrence }) {
459
715
  const payload = occurrence.payload;
460
716
  const expected = agendaEntrySnapshot(payload?.entry);
@@ -709,6 +965,7 @@ export class AgendaSchedulerBridge {
709
965
  leaseMs,
710
966
  renewIntervalMs,
711
967
  authorityResolver,
968
+ migrateLegacy = true,
712
969
  } = {}) {
713
970
  if (typeof now !== "function") {
714
971
  throw agendaError(
@@ -719,6 +976,7 @@ export class AgendaSchedulerBridge {
719
976
  this.agendaStore = agendaStore;
720
977
  this.schedulerStore = schedulerStore;
721
978
  this.now = now;
979
+ this.migrateLegacy = migrateLegacy !== false;
722
980
  this.runtime = new SchedulerRuntime({
723
981
  store: schedulerStore,
724
982
  adapters: [
@@ -750,6 +1008,31 @@ export class AgendaSchedulerBridge {
750
1008
  async runDue({ signal } = {}) {
751
1009
  const results = [];
752
1010
  const observedOccurrences = new Set();
1011
+ if (!signal?.aborted && this.migrateLegacy) {
1012
+ const sourceScope = {
1013
+ store: "agent-schedule",
1014
+ directory: canonicalSchedulerSourcePath(this.agendaStore.dir),
1015
+ };
1016
+ const candidates = this.agendaStore.list().filter((entry) => {
1017
+ const activeMigration =
1018
+ this.schedulerStore.getActiveDomainMigrationBySource({
1019
+ domain: "agenda",
1020
+ sourceScope,
1021
+ sourceId: entry.id,
1022
+ });
1023
+ if (entry.schedulerMigration) {
1024
+ return activeMigration?.state !== "retired";
1025
+ }
1026
+ return activeMigration?.state !== undefined;
1027
+ });
1028
+ for (const entry of candidates) {
1029
+ migrateAgendaSchedulerEntry({
1030
+ agendaStore: this.agendaStore,
1031
+ schedulerStore: this.schedulerStore,
1032
+ entry,
1033
+ });
1034
+ }
1035
+ }
753
1036
  const recovered = await this.runtime.runUntilIdle({
754
1037
  limit: 10_000,
755
1038
  signal,
@@ -772,9 +1055,9 @@ export class AgendaSchedulerBridge {
772
1055
 
773
1056
  const now = normalizeEpochMs(Number(this.now()), "now");
774
1057
  const due = [
775
- ...this.agendaStore.due("wakeup", now),
776
- ...this.agendaStore.due("cron", now),
777
- ...this.agendaStore.due("monitor", now),
1058
+ ...this.agendaStore.due("wakeup", now, { schedulerMigration: true }),
1059
+ ...this.agendaStore.due("cron", now, { schedulerMigration: true }),
1060
+ ...this.agendaStore.due("monitor", now, { schedulerMigration: true }),
778
1061
  ];
779
1062
  for (const entry of due) {
780
1063
  const occurrence = enqueueAgendaEntry(this.schedulerStore, entry);
@@ -790,6 +1073,28 @@ export class AgendaSchedulerBridge {
790
1073
  result,
791
1074
  });
792
1075
  }
1076
+ if (this.migrateLegacy) {
1077
+ const candidates = this.agendaStore
1078
+ .list()
1079
+ .filter(
1080
+ (entry) =>
1081
+ !entry.schedulerMigration &&
1082
+ [undefined, "succeeded"].includes(
1083
+ entry.schedulerExecution?.status,
1084
+ ) &&
1085
+ !entry.executionLease &&
1086
+ ((entry.kind === "wakeup" && entry.status === "pending") ||
1087
+ (["cron", "monitor"].includes(entry.kind) &&
1088
+ entry.status === "active")),
1089
+ );
1090
+ for (const entry of candidates) {
1091
+ migrateAgendaSchedulerEntry({
1092
+ agendaStore: this.agendaStore,
1093
+ schedulerStore: this.schedulerStore,
1094
+ entry,
1095
+ });
1096
+ }
1097
+ }
793
1098
  return results;
794
1099
  }
795
1100
  }