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.
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DDIUofA8.js → AIOps-axqQfwv8.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Bm-5xYRn.js → ActionButton-DV-Ro0By.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D5UH4ljI.js → Analytics-Bt72WEVu.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-D_ifjOOP.js → AppLayout-BtepG55E.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-BY1mXdC7.js → Artifacts-B7KaJ7S_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Bujr4Ml3.js → Audit-FNFaUg7A.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-sioKSTcC.js → BackgroundAgents-DFb6J2wQ.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DDOAK8RK.js → Backup-CC7YBhyj.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CtCsVVke.js → BaseInput-RkgTNVtj.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DpNj0vnd.js → Chat-hHEmGZy-.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZta3Ftr.js → ChatBubbleRenderer-CAP9YhHv.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DoHVNSXq.js → Checkbox-z5wXOQP1.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DlVl7Qmv.js → Codegen-DVaDJnxy.js} +1 -1
- package/src/assets/web-panel/assets/{Col-GIqoPYty.js → Col-CJmaRDR5.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CIAPEVji.js → Community-DF29_2bI.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BN7JiI_h.js → Compact-DtkQkBzn.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CqUWCM9B.js → Compliance-xoHDxp7I.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-A4iPp7A4.js → Cowork-BUm-R7ht.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-B2zeXXWb.js → Cron-Cgl14ZkB.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BR2xmWr8.js → Crosschain-BNcbmoqh.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BzFDjrIv.js → DID-Bwja0Zo9.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DKtDo3yA.js → Dashboard-Bk5XjEdJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-RNx43_YG.js → Dropdown-Ci36Oitq.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-SwMt4Rcy.js → EmailListRenderer--U04ZN4q.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CsYebZ4X.js → FamilyGuardDashboard-B2gNPR2s.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BmRKvBTy.js → Federation-C4KghYn7.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CVxGTA-0.js → FormItemContext-QL7x_Q_0.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-x2iXpyB7.js → GenericCardRenderer-F3Ryltwm.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DfqbkiOP.js → Git-2HassK5k.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-RuHyyj5O.js → Governance-DoBIp7oe.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Bn7uZ7rI.js → Inference--W01QhZ-.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DlP7XefZ.js → KnowledgeGraph-DmvwqGpT.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BYNdOiCd.js → Logs-BBJ4yAel.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-aMtgN-R6.js → MarkdownRenderer-BLCZMzhJ.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-JQYmDqM8.js → Marketplace-D5lNngSI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Cyx4yZ-9.js → McpTools-CkEVOMKH.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-VDuGZTN2.js → Memory-B1Ow1xVE.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-_yKo97gi.js → MobileBridge-SgYbUfb6.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CXRXW3q7.js → MobileProjects-BWdOvQAj.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-acTGtfLH.js → Mtc-DcTXSSma.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-ClpjXfkY.js → MtcAudit-Dt3WG4oj.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-_6Tn3o96.js → Multisig-B9B38UZx.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CK7pbZzP.js → NLProgramming-B0S4GGvG.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Czy6V_P8.js → Notes-DZ5U58Ng.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-Cqx-UVv3.js → NotificationSettings-PjL5ZW34.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C69WDxGy.js → OrderTableRenderer-DrAX2ESt.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DFnA9vLQ.js → Organization-Cv1GYs-c.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-ReZkk2yT.js → Overflow-Bbkp_PL3.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DzjSI0aI.js → P2P-BD8QUgoZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DKTf5xIP.js → PdhVaultBrowser-BO-2PeaB.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DhQ5klhR.js → Permissions-D_OPVa02.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CUL1iHrW.js → PersonalDataHub-mh-pEmaB.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-DU88iu4N.js → Pipeline-6JC2EDdb.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Bw-sYfyK.js → Privacy-CUshzUAG.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Bq3Q5y0z.js → ProjectInit-Cs2Aalri.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C8spzpho.js → ProjectSettings-1ak49tcj.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BV4oApsm.js +1 -0
- package/src/assets/web-panel/assets/{Providers-Bf4eTP9W.js → Providers-CXXxvafH.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Dme9BDU1.js → QrScannerModal-PTcDsF58.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CIXfv1rE.js → QuickAsk-CDwucrJw.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CIxvdeZ-.js → Recommend-CJlLVRXR.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C6k7MExI.js → RemoteSession-DlN-ETsO.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CISDz2bl.js → Reputation-DI23LR6m.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CdnDxXyf.js → Row-Cl7UQMrM.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C-QpRHsl.js → RssFeed-CexHNfh8.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DBjaGzSn.js → Search-BneBWvRN.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CQKukOeE.js → Security-DX7Phgrp.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DZz86jWb.js → Services-BWXO8Mte.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-jb8RMK0d.js → Skeleton-DCyOjKPJ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CdY76fZG.js → Skills-CXqERsTB.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-C_CSiZX9.js → Sla-bhbrbz8E.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-3IPU0HBZ.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-qvimGO0O.js → SyncSettings-DBNTQLbM.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Dng5LPJC.js → Tasks-quP0bkN-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Bwqq5Wll.js → Templates-BouWmgho.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DNWuwP7Z.js → Tenant-qv0D9s7z.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B-6Othpp.js → Terminal-BxvbE8BB.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DKpKZfzx.js → TimelineRenderer-D-IeLnJ2.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DzfGMd2J.js → Tokens-CFMKKyVG.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BXwUi74J.js → Trigger-L8as3UuJ.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BNzUq4ui.js → Trust-MxmA4VZG.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BYugxww4.js → UkeySign-C0VvJYRi.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DdauhtSJ.js → VideoEditing-Bf5QZj8N.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CSC9bCe_.js → Wallet-BIJ9riRz.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Q8AN3bTO.js → WebAuthn-B8p9Mhkw.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-d-LBGCuA.js → WorkflowEditor-BVsuaPen.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BLVDCgsZ.js → chat-BfkjoKpV.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BZlPSEHl.js → colors-DeAlsWK8.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-IWseP6R6.js → compact-item-Cs97bz5j.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DnVRV3Ao.js → createContext-BqbG60LH.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DLQZA_Wn.js → hasIn-i_RY0b1X.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_N4-Gq9.js → index-0-agYlWL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DB0MJgF_.js → index-79V_zv1s.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOZJBTWZ.js → index-B-3tEpTc.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUq0c7gq.js → index-B-JVTrpr.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dy0R5ZED.js → index-B1CbOH1i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bxp7uDD8.js → index-B5UkyA3c.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpVrK6fr.js → index-BESLFt4q.js} +1 -1
- package/src/assets/web-panel/assets/{index-CT9vVN-X.js → index-BOVkf1K3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DOoQpuQY.js → index-BYUVuwKt.js} +1 -1
- package/src/assets/web-panel/assets/{index-CINJQEj6.js → index-BcUXAB2s.js} +1 -1
- package/src/assets/web-panel/assets/{index-CarMTIyQ.js → index-BkBi5TmC.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5dgnilC.js → index-Bm7lLR4c.js} +1 -1
- package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +1 -0
- package/src/assets/web-panel/assets/{index-CbQNL0ue.js → index-BuLQobzW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpBaJ3TD.js → index-CE2VtTlp.js} +1 -1
- package/src/assets/web-panel/assets/{index-jWb70ZgZ.js → index-CED2PL_y.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEu2lMBy.js → index-CG3PRyAL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DocEhinm.js → index-CIG8fQ2_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_LQodeJ.js → index-COdGA-8n.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZpYeqrh.js → index-CeWoNHau.js} +1 -1
- package/src/assets/web-panel/assets/{index-gt8bNefW.js → index-Cf3WCLmy.js} +1 -1
- package/src/assets/web-panel/assets/{index-N_GoWZX4.js → index-CgsqdnRV.js} +1 -1
- package/src/assets/web-panel/assets/index-ChVT0p9u.js +1 -0
- package/src/assets/web-panel/assets/{index-CZDekj7T.js → index-D2B4VPyP.js} +1 -1
- package/src/assets/web-panel/assets/{index-YSw_gxlZ.js → index-D9evtvg2.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTbxp4UH.js → index-DUUrv141.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bbj2NS_I.js → index-DiSkx4UB.js} +3 -3
- package/src/assets/web-panel/assets/{index-BZs5bBnk.js → index-Dk2qouAz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DalA0TKC.js → index-Dk7-v4hP.js} +1 -1
- package/src/assets/web-panel/assets/{index-1jeAudHd.js → index-DmbfhJUP.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1ifZtXo.js → index-DqBgBpgp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhA3QEni.js → index-PT_5sBMA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSjilZ9L.js → index-U4f5izHz.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2FqfMvU.js → index-YXgLng0K.js} +1 -1
- package/src/assets/web-panel/assets/{index-COev0W2g.js → index-ZxO_-E8a.js} +1 -1
- package/src/assets/web-panel/assets/{index-M7wxfAbm.js → index-dIHr4B_u.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjWnONdy.js → index-gyFpvL7l.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dkwsi1Kn.js → index-s1opAL-M.js} +1 -1
- package/src/assets/web-panel/assets/{index-hwVDeoC0.js → index-yObj1O4n.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Co67Kqmb.js → initDefaultProps-C9h9yKL3.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BMOxQSF_.js → motion-BvmLsPdu.js} +1 -1
- package/src/assets/web-panel/assets/{move-C5fWDw-N.js → move-CoL4ekU1.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BJevpL0e.js → mtc-parser-C4pMy6xV.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BCzNU8s6.js → omit-DPuJfNxx.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CybWvDPk.js → pickAttrs-D0KEeaK2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BMWS9HnW.js → placementArrow-BpkyINxt.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BoL2UnGY.js → responsiveObserve-DQI_wOq8.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DWNfXraU.js → slide-DYfdDiRg.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BquTM3tX.js → statusUtils-B5dtvb0D.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BEkCleim.js → styleChecker-CF310mSj.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Oecnq7EA.js → useFlexGapSupport-D1Qp4BLp.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CkDffJ4F.js → useFs-C7_iyvJK.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-qbvKXesB.js → usePersonalDataHub-DZUt_fIm.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C6v8n6mA.js → vnode-D3dsi0lZ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-4CTeFILV.js → zoom-WdbOlvdQ.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +2 -2
- package/src/commands/agent.js +90 -1
- package/src/commands/chat.js +11 -2
- package/src/commands/compact.js +106 -23
- package/src/commands/loop.js +28 -10
- package/src/commands/routine.js +1 -1
- package/src/commands/scheduler-daemon.js +359 -2
- package/src/commands/session-observability.js +305 -0
- package/src/commands/session.js +38 -0
- package/src/data/changelog.json +14 -1
- package/src/gateways/ws/ws-agent-handler.js +439 -5
- package/src/harness/jsonl-session-store.js +463 -125
- package/src/harness/prompt-compressor.js +86 -13
- package/src/harness/provider-backed-compaction.js +100 -27
- package/src/lib/advisor-runtime.js +3 -1
- package/src/lib/agent-schedule-store.js +414 -4
- package/src/lib/agent-team/team-adjudication.js +40 -1
- package/src/lib/automation-engine.js +494 -0
- package/src/lib/background-agent-supervisor.js +793 -215
- package/src/lib/background-command-argv.js +24 -0
- package/src/lib/background-interaction-journal.js +361 -52
- package/src/lib/background-interaction-resolver.js +32 -0
- package/src/lib/background-launch-profile.js +2 -0
- package/src/lib/causal-observability.js +2661 -0
- package/src/lib/chat-session-admission.js +76 -0
- package/src/lib/cost-budget.js +5 -7
- package/src/lib/cowork/ab-comparator-cli.js +11 -0
- package/src/lib/cowork/debate-review-cli.js +12 -0
- package/src/lib/cowork-adapter.js +159 -38
- package/src/lib/cowork-cron.js +357 -1
- package/src/lib/cowork-task-runner.js +112 -17
- package/src/lib/delivery-coordinator.js +142 -0
- package/src/lib/direct-model-usage.js +121 -0
- package/src/lib/file-lines.js +183 -47
- package/src/lib/llm-pricing.js +12 -17
- package/src/lib/loop.js +26 -2
- package/src/lib/routine-store.js +380 -21
- package/src/lib/runtime-usage-ledger.js +182 -0
- package/src/lib/scheduler-kernel/agenda-adapter.js +308 -3
- package/src/lib/scheduler-kernel/automation-adapter.js +410 -8
- package/src/lib/scheduler-kernel/automation-event-adapter.js +36 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +285 -3
- package/src/lib/scheduler-kernel/loop-adapter.js +541 -6
- package/src/lib/scheduler-kernel/migration-admin.js +346 -0
- package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
- package/src/lib/scheduler-kernel/routine-adapter.js +394 -20
- package/src/lib/scheduler-kernel/runtime.js +63 -1
- package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
- package/src/lib/scheduler-kernel/store.js +2586 -85
- package/src/lib/session-host-lease.js +171 -2
- package/src/lib/session-host-snapshot.js +14 -3
- package/src/lib/session-persistence-failure.js +1 -0
- package/src/lib/session-tail.js +179 -34
- package/src/lib/session-transcript-structure.js +96 -0
- package/src/lib/sub-agent-context.js +328 -22
- package/src/lib/ws-agent-handler.js +4 -1
- package/src/repl/agent-repl.js +732 -91
- package/src/repl/chat-repl.js +5 -1
- package/src/runtime/agent-core.js +1272 -207
- package/src/runtime/fallback-model.js +5 -0
- package/src/runtime/headless-runner.js +324 -82
- package/src/runtime/headless-stream.js +232 -26
- package/src/runtime/policies/agent-policy.js +4 -0
- package/src/workers/background-agent-worker.js +403 -96
- package/src/assets/web-panel/assets/Projects-Dd-xuPIc.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-C7tT9iad.js +0 -1
- package/src/assets/web-panel/assets/devWarning-Jzu62CLC.js +0 -1
- package/src/assets/web-panel/assets/index-Zb2MeDSy.js +0 -1
- package/src/assets/web-panel/assets/index-fikqml4k.js +0 -1
|
@@ -21,6 +21,8 @@ import {
|
|
|
21
21
|
worktreeLog,
|
|
22
22
|
} from "./worktree-isolator.js";
|
|
23
23
|
import { isGitRepo } from "./git-integration.js";
|
|
24
|
+
import { markRuntimeLedgerPersistenceError } from "./runtime-usage-ledger.js";
|
|
25
|
+
import { IterationBudget } from "./iteration-budget.js";
|
|
24
26
|
|
|
25
27
|
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
26
28
|
|
|
@@ -30,6 +32,85 @@ const SUMMARY_SECTION_PATTERN =
|
|
|
30
32
|
/^##\s*(Summary|Result|Output|Conclusion|Answer)/im;
|
|
31
33
|
const TRUNCATE_LENGTH = 500;
|
|
32
34
|
|
|
35
|
+
function runtimeUsageObserverFailure(error, code, message) {
|
|
36
|
+
const failure =
|
|
37
|
+
error && (typeof error === "object" || typeof error === "function")
|
|
38
|
+
? markRuntimeLedgerPersistenceError(error)
|
|
39
|
+
: markRuntimeLedgerPersistenceError(new Error(message));
|
|
40
|
+
try {
|
|
41
|
+
if (!failure.code) failure.code = code;
|
|
42
|
+
} catch {
|
|
43
|
+
// A frozen error was already wrapped by markRuntimeLedgerPersistenceError.
|
|
44
|
+
}
|
|
45
|
+
return failure;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function assertSyncUsageObserver(observer, phase) {
|
|
49
|
+
if (typeof observer === "function") return;
|
|
50
|
+
const upper = phase.toUpperCase();
|
|
51
|
+
throw runtimeUsageObserverFailure(
|
|
52
|
+
null,
|
|
53
|
+
`CC_USAGE_${upper}_OBSERVER_REQUIRED`,
|
|
54
|
+
`Strict child usage telemetry requires a synchronous ${phase} observer`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function requireSyncUsageObserver(observer, event, phase) {
|
|
59
|
+
const upper = phase.toUpperCase();
|
|
60
|
+
assertSyncUsageObserver(observer, phase);
|
|
61
|
+
let observation;
|
|
62
|
+
try {
|
|
63
|
+
observation = observer(event);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
throw runtimeUsageObserverFailure(
|
|
66
|
+
error,
|
|
67
|
+
`CC_USAGE_${upper}_PERSISTENCE_FAILED`,
|
|
68
|
+
`Child usage ${phase} persistence failed`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
let isThenable = false;
|
|
72
|
+
try {
|
|
73
|
+
isThenable = Boolean(observation && typeof observation.then === "function");
|
|
74
|
+
} catch (error) {
|
|
75
|
+
throw runtimeUsageObserverFailure(
|
|
76
|
+
error,
|
|
77
|
+
`CC_USAGE_${upper}_OBSERVER_ASYNC`,
|
|
78
|
+
`Child usage ${phase} observer must be synchronous`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (isThenable) {
|
|
82
|
+
void Promise.resolve(observation).catch(() => {});
|
|
83
|
+
throw runtimeUsageObserverFailure(
|
|
84
|
+
null,
|
|
85
|
+
`CC_USAGE_${upper}_OBSERVER_ASYNC`,
|
|
86
|
+
`Child usage ${phase} observer must be synchronous`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function requireUsageCallId(event, phase) {
|
|
92
|
+
if (typeof event?.callId === "string" && event.callId.trim()) {
|
|
93
|
+
return event.callId;
|
|
94
|
+
}
|
|
95
|
+
const upper = phase.toUpperCase();
|
|
96
|
+
throw runtimeUsageObserverFailure(
|
|
97
|
+
null,
|
|
98
|
+
`CC_USAGE_${upper}_CALL_ID_REQUIRED`,
|
|
99
|
+
`Strict child usage ${phase} requires a real callId`,
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function requireToolCallId(event, phase) {
|
|
104
|
+
const value = event?.tool_use_id ?? event?.callId ?? event?.id;
|
|
105
|
+
if (typeof value === "string" && value.trim()) return value;
|
|
106
|
+
const upper = phase.toUpperCase();
|
|
107
|
+
throw runtimeUsageObserverFailure(
|
|
108
|
+
null,
|
|
109
|
+
`CC_TOOL_${upper}_CALL_ID_REQUIRED`,
|
|
110
|
+
`Strict child tool ${phase} requires a real provider call id`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
33
114
|
// ─── SubAgentContext ────────────────────────────────────────────────────────
|
|
34
115
|
|
|
35
116
|
export class SubAgentContext {
|
|
@@ -53,6 +134,15 @@ export class SubAgentContext {
|
|
|
53
134
|
* @param {object} [options.llmOptions] - LLM provider/model/key options
|
|
54
135
|
* @param {string} [options.cwd] - Working directory
|
|
55
136
|
* @param {boolean} [options.useWorktree] - Force worktree isolation (overrides flag)
|
|
137
|
+
* @param {function} [options.onUsageBoundary] - Synchronous observer for
|
|
138
|
+
* real child model-usage-started events. A failure is terminal so provider
|
|
139
|
+
* work cannot begin without a durable parent boundary.
|
|
140
|
+
* @param {function} [options.onUsageSettlement] - Synchronous observer for
|
|
141
|
+
* real child token-usage/model-usage-unknown settlements.
|
|
142
|
+
* @param {function} [options.onToolCallBoundary] - Synchronous observer for
|
|
143
|
+
* real child tool-executing boundaries.
|
|
144
|
+
* @param {function} [options.onToolCallSettlement] - Synchronous observer for
|
|
145
|
+
* matching child tool-result settlements.
|
|
56
146
|
* @returns {SubAgentContext}
|
|
57
147
|
*/
|
|
58
148
|
static create(options = {}) {
|
|
@@ -158,6 +248,23 @@ export class SubAgentContext {
|
|
|
158
248
|
// the parent loop can re-yield attributed `token-usage` events.
|
|
159
249
|
this._onUsage =
|
|
160
250
|
typeof options.onUsage === "function" ? options.onUsage : null;
|
|
251
|
+
this._onUsageBoundary =
|
|
252
|
+
typeof options.onUsageBoundary === "function"
|
|
253
|
+
? options.onUsageBoundary
|
|
254
|
+
: null;
|
|
255
|
+
this._onUsageSettlement =
|
|
256
|
+
typeof options.onUsageSettlement === "function"
|
|
257
|
+
? options.onUsageSettlement
|
|
258
|
+
: null;
|
|
259
|
+
this._onToolCallBoundary =
|
|
260
|
+
typeof options.onToolCallBoundary === "function"
|
|
261
|
+
? options.onToolCallBoundary
|
|
262
|
+
: null;
|
|
263
|
+
this._onToolCallSettlement =
|
|
264
|
+
typeof options.onToolCallSettlement === "function"
|
|
265
|
+
? options.onToolCallSettlement
|
|
266
|
+
: null;
|
|
267
|
+
this._strictUsageTelemetry = options.strictUsageTelemetry === true;
|
|
161
268
|
|
|
162
269
|
// Optional EXTERNAL abort signal for cancellation (e.g. a parent-provided
|
|
163
270
|
// AbortSignal). In addition, every context owns an INTERNAL controller so a
|
|
@@ -439,6 +546,7 @@ export class SubAgentContext {
|
|
|
439
546
|
}
|
|
440
547
|
return result;
|
|
441
548
|
} catch (err) {
|
|
549
|
+
if (err?.runtimeLedgerPersistence === true) throw err;
|
|
442
550
|
// If worktree creation fails (e.g. not a git repo), fall back to direct
|
|
443
551
|
this.status = "failed";
|
|
444
552
|
this.completedAt = new Date().toISOString();
|
|
@@ -525,8 +633,103 @@ export class SubAgentContext {
|
|
|
525
633
|
if (authority.unattendedActionPolicy) {
|
|
526
634
|
options.unattendedActionPolicy = authority.unattendedActionPolicy;
|
|
527
635
|
}
|
|
528
|
-
|
|
529
|
-
|
|
636
|
+
// Let agentLoop enforce model-turn admission at its real provider boundary.
|
|
637
|
+
// The former event-count guard could stop immediately after a yielded
|
|
638
|
+
// model/tool `started` event and strand it without a settlement.
|
|
639
|
+
options.iterationBudget =
|
|
640
|
+
this.iterationBudget ||
|
|
641
|
+
new IterationBudget({ limit: this.maxIterations, owner: this.id });
|
|
642
|
+
const strictUsageTelemetry =
|
|
643
|
+
this._strictUsageTelemetry || options.strictUsageTelemetry === true;
|
|
644
|
+
const pendingUsageCalls = new Set();
|
|
645
|
+
const pendingToolCalls = new Map();
|
|
646
|
+
let observeUsageBoundary = null;
|
|
647
|
+
let observeUsageSettlement = null;
|
|
648
|
+
let observeToolBoundary = null;
|
|
649
|
+
let observeToolSettlement = null;
|
|
650
|
+
if (strictUsageTelemetry) {
|
|
651
|
+
// Presence is checked without invoking either observer. In particular,
|
|
652
|
+
// do not manufacture a null "validation event" that a durable writer
|
|
653
|
+
// could mistake for a real provider-call boundary.
|
|
654
|
+
assertSyncUsageObserver(this._onUsageBoundary, "boundary");
|
|
655
|
+
assertSyncUsageObserver(this._onUsageSettlement, "settlement");
|
|
656
|
+
|
|
657
|
+
observeUsageBoundary = (event) => {
|
|
658
|
+
const callId = requireUsageCallId(event, "boundary");
|
|
659
|
+
if (pendingUsageCalls.has(callId)) {
|
|
660
|
+
throw runtimeUsageObserverFailure(
|
|
661
|
+
null,
|
|
662
|
+
"CC_USAGE_BOUNDARY_CALL_ID_DUPLICATE",
|
|
663
|
+
`Duplicate child usage boundary callId: ${callId}`,
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
requireSyncUsageObserver(this._onUsageBoundary, event, "boundary");
|
|
667
|
+
pendingUsageCalls.add(callId);
|
|
668
|
+
};
|
|
669
|
+
observeUsageSettlement = (event) => {
|
|
670
|
+
const callId = requireUsageCallId(event, "settlement");
|
|
671
|
+
if (!pendingUsageCalls.has(callId)) {
|
|
672
|
+
throw runtimeUsageObserverFailure(
|
|
673
|
+
null,
|
|
674
|
+
"CC_USAGE_SETTLEMENT_BOUNDARY_MISSING",
|
|
675
|
+
`Child usage settlement has no matching boundary: ${callId}`,
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
requireSyncUsageObserver(this._onUsageSettlement, event, "settlement");
|
|
679
|
+
pendingUsageCalls.delete(callId);
|
|
680
|
+
};
|
|
681
|
+
|
|
682
|
+
// agentLoop yields model-usage-started before provider work. Its consumer
|
|
683
|
+
// runs synchronously before requesting the next event, so a durable host
|
|
684
|
+
// write failure prevents the child provider call from starting.
|
|
685
|
+
// Automatic semantic compaction invokes this same wrapped boundary seam
|
|
686
|
+
// directly, before its provider query, rather than yielding a start event.
|
|
687
|
+
options.onUsageBoundary = observeUsageBoundary;
|
|
688
|
+
options.onUsageSettlement = observeUsageSettlement;
|
|
689
|
+
options.strictUsageTelemetry = true;
|
|
690
|
+
|
|
691
|
+
observeToolBoundary = (event) => {
|
|
692
|
+
const callId = requireToolCallId(event, "boundary");
|
|
693
|
+
if (pendingToolCalls.has(callId)) {
|
|
694
|
+
throw runtimeUsageObserverFailure(
|
|
695
|
+
null,
|
|
696
|
+
"CC_TOOL_BOUNDARY_CALL_ID_DUPLICATE",
|
|
697
|
+
`Duplicate child tool boundary callId: ${callId}`,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
requireSyncUsageObserver(
|
|
701
|
+
this._onToolCallBoundary,
|
|
702
|
+
event,
|
|
703
|
+
"tool_boundary",
|
|
704
|
+
);
|
|
705
|
+
pendingToolCalls.set(callId, event.tool || null);
|
|
706
|
+
};
|
|
707
|
+
observeToolSettlement = (event) => {
|
|
708
|
+
const callId = requireToolCallId(event, "settlement");
|
|
709
|
+
if (!pendingToolCalls.has(callId)) {
|
|
710
|
+
throw runtimeUsageObserverFailure(
|
|
711
|
+
null,
|
|
712
|
+
"CC_TOOL_SETTLEMENT_BOUNDARY_MISSING",
|
|
713
|
+
`Child tool settlement has no matching boundary: ${callId}`,
|
|
714
|
+
);
|
|
715
|
+
}
|
|
716
|
+
const startedTool = pendingToolCalls.get(callId);
|
|
717
|
+
if (startedTool && event.tool && startedTool !== event.tool) {
|
|
718
|
+
throw runtimeUsageObserverFailure(
|
|
719
|
+
null,
|
|
720
|
+
"CC_TOOL_SETTLEMENT_IDENTITY_CHANGED",
|
|
721
|
+
`Child tool settlement changed tool identity for ${callId}`,
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
requireSyncUsageObserver(
|
|
725
|
+
this._onToolCallSettlement,
|
|
726
|
+
event,
|
|
727
|
+
"tool_settlement",
|
|
728
|
+
);
|
|
729
|
+
pendingToolCalls.delete(callId);
|
|
730
|
+
};
|
|
731
|
+
options.onToolCallBoundary = observeToolBoundary;
|
|
732
|
+
options.onToolCallSettlement = observeToolSettlement;
|
|
530
733
|
}
|
|
531
734
|
|
|
532
735
|
// Forward MCP / external tool plumbing into the agent loop
|
|
@@ -605,9 +808,32 @@ export class SubAgentContext {
|
|
|
605
808
|
}
|
|
606
809
|
|
|
607
810
|
if (event.type === "token-usage") {
|
|
811
|
+
const forwardedUsage = {
|
|
812
|
+
type: "token-usage",
|
|
813
|
+
...(event.callId ? { callId: event.callId } : {}),
|
|
814
|
+
provider: event.provider || null,
|
|
815
|
+
model: event.model || null,
|
|
816
|
+
usage: event.usage || null,
|
|
817
|
+
...(event.source ? { source: event.source } : {}),
|
|
818
|
+
attribution: event.attribution || null,
|
|
819
|
+
...(event.boundaryNotified === true ||
|
|
820
|
+
event.ledgerPersisted === true
|
|
821
|
+
? { boundaryNotified: true }
|
|
822
|
+
: {}),
|
|
823
|
+
...(event.ledgerPersisted === true
|
|
824
|
+
? { ledgerPersisted: true }
|
|
825
|
+
: {}),
|
|
826
|
+
};
|
|
827
|
+
if (strictUsageTelemetry && event.ledgerPersisted !== true) {
|
|
828
|
+
forwardedUsage.boundaryNotified = true;
|
|
829
|
+
observeUsageSettlement(forwardedUsage);
|
|
830
|
+
forwardedUsage.ledgerPersisted = true;
|
|
831
|
+
}
|
|
832
|
+
// Close the durable provider-call row before any secondary budget
|
|
833
|
+
// projection can fail. A budget writer error must never turn a paid
|
|
834
|
+
// call into a permanently open `started` row.
|
|
608
835
|
// Attributed usage was already charged by the nested child sharing
|
|
609
|
-
// this same authority
|
|
610
|
-
// child-of-child would be counted once at every ancestor level.
|
|
836
|
+
// this same authority, so only direct usage is folded here.
|
|
611
837
|
if (!event.attribution && this.sessionBudget?.recordUsage) {
|
|
612
838
|
this.sessionBudget.recordUsage({
|
|
613
839
|
provider: event.provider || null,
|
|
@@ -618,16 +844,81 @@ export class SubAgentContext {
|
|
|
618
844
|
if (this._onUsage) {
|
|
619
845
|
// Forward real usage to the spawner. A nested child's event already
|
|
620
846
|
// carries its own attribution frame — preserve it (deepest wins).
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
847
|
+
if (strictUsageTelemetry) {
|
|
848
|
+
requireSyncUsageObserver(
|
|
849
|
+
this._onUsage,
|
|
850
|
+
forwardedUsage,
|
|
851
|
+
"forwarding",
|
|
852
|
+
);
|
|
853
|
+
} else {
|
|
854
|
+
try {
|
|
855
|
+
this._onUsage(forwardedUsage);
|
|
856
|
+
} catch {
|
|
857
|
+
// Legacy attribution forwarding remains best-effort.
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
if (event.type === "model-usage-started") {
|
|
864
|
+
if (strictUsageTelemetry) {
|
|
865
|
+
if (
|
|
866
|
+
event.boundaryNotified === true ||
|
|
867
|
+
event.ledgerPersisted === true
|
|
868
|
+
) {
|
|
869
|
+
pendingUsageCalls.add(requireUsageCallId(event, "boundary"));
|
|
870
|
+
} else {
|
|
871
|
+
observeUsageBoundary(event);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
if (event.type === "tool-executing" && strictUsageTelemetry) {
|
|
877
|
+
observeToolBoundary(event);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
if (
|
|
881
|
+
event.type === "model-usage-unknown" ||
|
|
882
|
+
event.type === "compaction-usage-unknown"
|
|
883
|
+
) {
|
|
884
|
+
const forwardedUnknown = {
|
|
885
|
+
type: "model-usage-unknown",
|
|
886
|
+
callId: event.callId,
|
|
887
|
+
provider: event.provider || null,
|
|
888
|
+
model: event.model || null,
|
|
889
|
+
source:
|
|
890
|
+
event.source ||
|
|
891
|
+
(event.type === "compaction-usage-unknown"
|
|
892
|
+
? "semantic-compaction"
|
|
893
|
+
: "model"),
|
|
894
|
+
code: event.code || "provider_transport_outcome_unknown",
|
|
895
|
+
attribution: event.attribution || null,
|
|
896
|
+
...(event.boundaryNotified === true ||
|
|
897
|
+
event.ledgerPersisted === true
|
|
898
|
+
? { boundaryNotified: true }
|
|
899
|
+
: {}),
|
|
900
|
+
...(event.ledgerPersisted === true
|
|
901
|
+
? { ledgerPersisted: true }
|
|
902
|
+
: {}),
|
|
903
|
+
};
|
|
904
|
+
if (strictUsageTelemetry && event.ledgerPersisted !== true) {
|
|
905
|
+
forwardedUnknown.boundaryNotified = true;
|
|
906
|
+
observeUsageSettlement(forwardedUnknown);
|
|
907
|
+
forwardedUnknown.ledgerPersisted = true;
|
|
908
|
+
}
|
|
909
|
+
if (this._onUsage) {
|
|
910
|
+
if (strictUsageTelemetry) {
|
|
911
|
+
requireSyncUsageObserver(
|
|
912
|
+
this._onUsage,
|
|
913
|
+
forwardedUnknown,
|
|
914
|
+
"forwarding",
|
|
915
|
+
);
|
|
916
|
+
} else {
|
|
917
|
+
try {
|
|
918
|
+
this._onUsage(forwardedUnknown);
|
|
919
|
+
} catch {
|
|
920
|
+
// Legacy attribution forwarding remains best-effort.
|
|
921
|
+
}
|
|
631
922
|
}
|
|
632
923
|
}
|
|
633
924
|
}
|
|
@@ -637,6 +928,9 @@ export class SubAgentContext {
|
|
|
637
928
|
}
|
|
638
929
|
|
|
639
930
|
if (event.type === "tool-result") {
|
|
931
|
+
if (strictUsageTelemetry && event.tool_use_id) {
|
|
932
|
+
observeToolSettlement(event);
|
|
933
|
+
}
|
|
640
934
|
// Store large tool results as artifacts
|
|
641
935
|
const resultStr = JSON.stringify(event.result);
|
|
642
936
|
// Estimate token count from tool result (~4 chars per token)
|
|
@@ -672,7 +966,10 @@ export class SubAgentContext {
|
|
|
672
966
|
}
|
|
673
967
|
|
|
674
968
|
// Check abort signal (external OR this context's own `abort()`)
|
|
675
|
-
|
|
969
|
+
const providerOrToolBoundaryPending =
|
|
970
|
+
event.type === "model-usage-started" ||
|
|
971
|
+
event.type === "tool-executing";
|
|
972
|
+
if (this.isAborted() && !providerOrToolBoundaryPending) {
|
|
676
973
|
this.forceComplete(this._cancelReason || "cancelled", {
|
|
677
974
|
partialContent: lastContent,
|
|
678
975
|
artifacts,
|
|
@@ -681,21 +978,30 @@ export class SubAgentContext {
|
|
|
681
978
|
}
|
|
682
979
|
|
|
683
980
|
// Enforce token budget
|
|
684
|
-
if (
|
|
981
|
+
if (
|
|
982
|
+
this.tokenBudget &&
|
|
983
|
+
this._tokenCount >= this.tokenBudget &&
|
|
984
|
+
!providerOrToolBoundaryPending
|
|
985
|
+
) {
|
|
685
986
|
this.forceComplete("token-budget-exceeded", {
|
|
686
987
|
partialContent: lastContent,
|
|
687
988
|
artifacts,
|
|
688
989
|
});
|
|
689
990
|
break;
|
|
690
991
|
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
992
|
+
}
|
|
993
|
+
if (
|
|
994
|
+
strictUsageTelemetry &&
|
|
995
|
+
(pendingUsageCalls.size > 0 || pendingToolCalls.size > 0)
|
|
996
|
+
) {
|
|
997
|
+
throw runtimeUsageObserverFailure(
|
|
998
|
+
null,
|
|
999
|
+
"CC_CHILD_CALL_SETTLEMENT_INCOMPLETE",
|
|
1000
|
+
"Strict child execution ended with an unsettled provider or tool call",
|
|
1001
|
+
);
|
|
697
1002
|
}
|
|
698
1003
|
} catch (err) {
|
|
1004
|
+
if (err?.runtimeLedgerPersistence === true) throw err;
|
|
699
1005
|
if (this.isAborted()) {
|
|
700
1006
|
this.forceComplete(this._cancelReason || "cancelled", {
|
|
701
1007
|
partialContent: lastContent,
|