chainlesschain 0.165.2 → 0.165.4
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/README.md +151 -29
- package/package.json +2 -2
- package/src/assets/web-panel/assets/{AIOps-lS1R0Cza.js → AIOps-C__nnraW.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BmlgBPsj.js → ActionButton-CsKWHEZ-.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CNKczv1S.js → Analytics-BhIjfjWO.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BuZGJARQ.js → AppLayout-BjuXFzWZ.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-Dm73Sl-O.js → Artifacts-k6whDkZJ.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BGMW7A5e.js → Audit-C4FBMYRh.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BQ6M54JR.js → BackgroundAgents-C_vRrSXk.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DBzGP0bR.js → Backup-CngFZeVp.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-D1mLCoOV.js → BaseInput-B_H9EBRm.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-BUfcN7p8.js → Chat-DLEC5kt7.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-xijcWkJe.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Du0Yg5Pi.js → Checkbox-m3ClR4xh.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B2RXziHW.js → Codegen-CmLSFrgp.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DWhekOrR.js → Col-DFGQteHN.js} +1 -1
- package/src/assets/web-panel/assets/{Community-HQhrkon4.js → Community-EUUVORHE.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-izHNb4uz.js → Compact-2PSg0Yr7.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BDwLy41-.js → Compliance-CcKur7gB.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DFJhLa7K.js → Cowork-DK_Fezfa.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-DYY9RG7-.js → Cron-Dbw89xl7.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-rr7tJTtv.js → Crosschain-CH66h_Ec.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D2sfHRLi.js → DID-D1igRb17.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-q_eGdhha.js → Dashboard-DVAsrobk.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Cufrh2Bz.js → Dropdown-Dl7W8AQs.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-B-kdv10f.js → EmailListRenderer-D5tpaEQC.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-D21XjgfG.js → FamilyGuardDashboard-O_VQf8gq.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CAwRTLZH.js → Federation-BTVcgS9n.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-vx3daNDF.js → FormItemContext-BRnkJAIz.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CRWY2wU4.js → GenericCardRenderer-8OWSCkDj.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Q6SwauyD.js → Git-WXLYTQj2.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BJ1q4IQZ.js → Governance-BezaUhtc.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CSWjROgD.js → Inference-CuRay3Gu.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-fzuQsWuY.js → KnowledgeGraph-DfWLDW1m.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DVF8Mnns.js → Logs-C55y2pPY.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-hDpWdiBc.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-BQP7LOA4.js → Marketplace-Dk08Uycg.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BNlJCmNc.js → McpTools-C11fSB5V.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-DLLg5WQ4.js → Memory-mr0eZc97.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CR2skNAF.js → MobileBridge-C0iCSRbb.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BxVavObl.js → MobileProjects-CY-xMG8Z.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-B17pgqMI.js → Mtc-Bplqc_Wc.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-4UmV5cIL.js → MtcAudit-BlzwsoSM.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DoMEXEcU.js → Multisig-BBLmTty6.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-h9DMXFX4.js → NLProgramming-DtT1uf1W.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Cihn-xX8.js → Notes-DcqQAxTK.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-BE6ZGa3R.js → NotificationSettings-cb0kWoZe.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CnwojoSI.js → OrderTableRenderer-kw9HZQNN.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-B2vpwmjb.js → Organization-DlTlbkUN.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-C4z28R0-.js → Overflow-pp1qs-oY.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BVlFkwhW.js → P2P-BESLnyYz.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BXbEdL5B.js → PdhVaultBrowser-B-J1mGuf.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-C28xs4lp.js → Permissions-B36PeT1_.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-Dgl_rBjM.js → PersonalDataHub-CTK2ad-3.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-3QUIhrKI.js → Pipeline-zJNGXsac.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-8Gh33OZ5.js → Privacy-b9fz0Qf0.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BNmg4tZi.js → ProjectInit-DjZbZgiB.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-vgMfeCf9.js → ProjectSettings-C-hHJXlD.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BC9KSDM6.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CXoOa8eX.js → Providers-Dz-CAYYU.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BhfTF0oS.js → QrScannerModal-A0yoQ3-3.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-C746HEAj.js → QuickAsk-DrFgFJNC.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BSej8Eo0.js → Recommend-KC8hF1g4.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-f3gmnlG3.js → RemoteSession-DGTPIk6u.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-CyvybpkN.js → Reputation-QmbwM7Yk.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DwV2PeYn.js → Row-BxjJylia.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-11GrzjZy.js → RssFeed-B7Wda1J6.js} +3 -3
- package/src/assets/web-panel/assets/{Search-BjKXkrAY.js → Search-_plQ_YSA.js} +1 -1
- package/src/assets/web-panel/assets/{Security-eWiFb9Yk.js → Security-CD2YJZfx.js} +2 -2
- package/src/assets/web-panel/assets/{Services-CdCsMAtt.js → Services-qQE7NmwE.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-4Q2UTKQ5.js → Skeleton-DgQqkFf7.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-v4rtYrRj.js → Skills-C4C0oFFt.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CRhsFvd_.js → Sla-Px2N2B5c.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-DN6C3lQd.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-D16zonl7.js → SyncSettings-jm5aH_m7.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Xxozz0i_.js → Tasks-DlkJcv67.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-CXJpPtCT.js → Templates-DyrTHUBs.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-XRV0L1ZF.js → Tenant-mC434PtL.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-CYuO1i_w.js → Terminal-o0_s3NgK.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BXqitWsu.js → TimelineRenderer-DAGlAXOw.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BvPrDHIy.js → Tokens-BnulS_bs.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DhCrSTf5.js → Trigger-suQbVXYM.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DmsuZD6K.js → Trust-DbIJAPo5.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-D_yrts5C.js → UkeySign-CQNpbIHi.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B01ihPrm.js → VideoEditing-D8aWCERk.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-DpUjKa-N.js → Wallet-CuLpYfZc.js} +2 -2
- package/src/assets/web-panel/assets/{WebAuthn-CL07yON6.js → WebAuthn-CsfG8ZMc.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-CLMflnRr.js → WorkflowEditor-BYsEAZbd.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DtUqe8h_.js → chat-FT4Um3-I.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DPKrgVfy.js → colors-CKbS_Wlt.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BTt2GtOm.js → compact-item-CFJtzuJM.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-D_VeUc1J.js → createContext-B9kSRW6K.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DJZ0gAMu.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-1kndiylj.js → hasIn-DR-x0Xpi.js} +1 -1
- package/src/assets/web-panel/assets/{index-dVc-CXY4.js → index-7jHr_A_k.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFIZ_1Sf.js → index-B3ZX81mK.js} +1 -1
- package/src/assets/web-panel/assets/{index-fk2Rjacw.js → index-B7osrXqy.js} +3 -3
- package/src/assets/web-panel/assets/{index-CHG-KcS4.js → index-BGbPnC5x.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbbymxpj.js → index-BI5hP_qy.js} +1 -1
- package/src/assets/web-panel/assets/{index-BaZAbw9A.js → index-BK3TiKVq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CzjkKUmR.js → index-BVPU43b1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BAXfRKfG.js → index-BW-t9n-q.js} +1 -1
- package/src/assets/web-panel/assets/{index-8nz_fmlj.js → index-BfFCQHL3.js} +1 -1
- package/src/assets/web-panel/assets/index-Bizb4hkw.js +1 -0
- package/src/assets/web-panel/assets/{index-DdkplL9R.js → index-Bt4fS2eL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DG2MZQ3f.js → index-BwR7yc2h.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfKBRdSS.js → index-Bzz0C1BZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-GsoUQ2M7.js → index-C2JvmYRc.js} +1 -1
- package/src/assets/web-panel/assets/{index-l1BETrDb.js → index-CGaXUsIs.js} +1 -1
- package/src/assets/web-panel/assets/{index-4bna2_SR.js → index-CJmIQ9XR.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfGl8CqG.js → index-C_enk9I_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D95OFht7.js → index-Cr2FLUsD.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsJCDUJG.js → index-CvrCCqJt.js} +1 -1
- package/src/assets/web-panel/assets/{index-sDoMHTNA.js → index-D4LfPvWA.js} +1 -1
- package/src/assets/web-panel/assets/{index-By5n8up9.js → index-DMGmg497.js} +1 -1
- package/src/assets/web-panel/assets/{index-ocf06EVQ.js → index-DShSkww-.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bhudc_Ez.js → index-DTxNy0ZU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX81qSM4.js → index-DW4BWjTk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlDNVgBt.js → index-DWdqx7zI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcO04eDn.js → index-Dap9c3eD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dwqmtk65.js → index-DcfxhKXR.js} +1 -1
- package/src/assets/web-panel/assets/{index-2eyAXE3d.js → index-DdkIhfi-.js} +1 -1
- package/src/assets/web-panel/assets/{index-brCInrzq.js → index-DeSgw-WV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJ8vXGOa.js → index-DiNUEpSQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHpBMWCh.js → index-DjEP7WkH.js} +1 -1
- package/src/assets/web-panel/assets/{index-m31Ka8hZ.js → index-DtkFqPVA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtF7EN49.js → index-KqDaCApw.js} +1 -1
- package/src/assets/web-panel/assets/index-OHSl-xCh.js +1 -0
- package/src/assets/web-panel/assets/{index-B9KvcS7R.js → index-OSzjTzGM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CauoBQkH.js → index-QBSeNVO3.js} +1 -1
- package/src/assets/web-panel/assets/{index-FzdwcSy2.js → index-WE08gMJP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DxdTdBix.js → index-r2VI1Ikk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BepLZwgB.js → index-tqSEHPRT.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CvyYJd7z.js → initDefaultProps-Dd7n7VgI.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DYZkhUdz.js → motion-BwxouRw1.js} +1 -1
- package/src/assets/web-panel/assets/{move-slnJRVT1.js → move-DObN0PG9.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DVc0CKmy.js → mtc-parser-B3nOUQc7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BCXAtHCq.js → omit-o9WU2Nbl.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DBsemz_K.js → pickAttrs-CL_vvfQ_.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BRtkJ-nv.js → placementArrow-CYrM2tyK.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Cebq7EZn.js → responsiveObserve-k_06cQ96.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DT7qvId2.js → slide-CPKG0pxS.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-pQiITLkG.js → statusUtils-BDDEeLTw.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-c-19BVKQ.js → styleChecker-Cmb7RTh7.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DsS5-0bE.js → useFlexGapSupport-e2IedC4N.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CxGiMe5n.js → useFs-CE_gxVnm.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-D9btVID5.js → usePersonalDataHub-BkMIIKMz.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CUYFsFEN.js → vnode-DW886XV1.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CXmn_35j.js → zoom-Dwo_adaf.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +105 -35
- package/src/commands/artifacts.js +363 -33
- package/src/commands/cowork.js +202 -36
- package/src/commands/session-budget.js +155 -0
- package/src/commands/session-location.js +948 -0
- package/src/commands/session.js +72 -46
- package/src/data/changelog.json +26 -0
- package/src/gateways/ws/artifact-protocol.js +77 -13
- package/src/gateways/ws/session-protocol.js +391 -24
- package/src/gateways/ws/ws-agent-handler.js +191 -14
- package/src/gateways/ws/ws-server.js +14 -3
- package/src/gateways/ws/ws-session-gateway.js +101 -5
- package/src/harness/jsonl-session-store.js +1210 -0
- package/src/lib/agent-team/team-runner.js +43 -13
- package/src/lib/artifact-access-ledger.js +461 -0
- package/src/lib/artifact-cleanup-ledger.js +861 -0
- package/src/lib/artifact-deletion-ledger.js +677 -0
- package/src/lib/artifact-store.js +256 -51
- package/src/lib/background-agent-keeper-protocol.js +75 -4
- package/src/lib/background-agent-launch-barrier.js +74 -0
- package/src/lib/background-agent-supervisor.js +149 -5
- package/src/lib/background-turn-bootstrap-protocol.js +4 -0
- package/src/lib/command-lifecycle-report.js +8 -4
- package/src/lib/cowork-adapter.js +9 -5
- package/src/lib/cowork-task-runner.js +20 -0
- package/src/lib/cowork-workflow.js +178 -20
- package/src/lib/direct-model-usage.js +62 -22
- package/src/lib/dynamic-workflow-runtime.js +3184 -111
- package/src/lib/execution-location-result-apply.js +339 -0
- package/src/lib/execution-location-result-artifact.js +271 -0
- package/src/lib/execution-location-result-review.js +253 -0
- package/src/lib/execution-location-result-store.js +331 -0
- package/src/lib/execution-location-result.js +617 -0
- package/src/lib/execution-location-target.js +236 -1
- package/src/lib/managed-tool-checkpoint.js +47 -4
- package/src/lib/process-execution-broker/workspace-transaction.js +3 -0
- package/src/lib/session-budget-production-root.js +376 -0
- package/src/lib/session-budget-runtime.js +109 -18
- package/src/lib/session-budget-usage.js +63 -0
- package/src/lib/session-host-snapshot.js +19 -2
- package/src/lib/session-resource-budget.js +766 -105
- package/src/lib/sub-agent-context.js +69 -22
- package/src/lib/web-ui-server.js +12 -1
- package/src/lib/with-file-lock.js +175 -26
- package/src/repl/agent-repl.js +237 -16
- package/src/runtime/agent-core.js +123 -0
- package/src/runtime/headless-runner.js +135 -46
- package/src/runtime/headless-stream.js +133 -25
- package/src/runtime/policies/agent-policy.js +10 -0
- package/src/workers/background-agent-keeper.js +112 -19
- package/src/workers/background-agent-worker.js +383 -134
- package/src/workers/background-turn-bootstrap.js +13 -8
- package/src/assets/web-panel/assets/ChatBubbleRenderer-CY5m8ZHg.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-BLif4QSg.js +0 -1
- package/src/assets/web-panel/assets/Projects-BhtAVilc.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-DLjKsDVu.js +0 -1
- package/src/assets/web-panel/assets/devWarning-Bj5nUW2v.js +0 -1
- package/src/assets/web-panel/assets/index-CPcM-eqo.js +0 -1
- package/src/assets/web-panel/assets/index-xeSyVoRe.js +0 -1
package/src/repl/agent-repl.js
CHANGED
|
@@ -79,6 +79,16 @@ import {
|
|
|
79
79
|
readSessionHostResumeState,
|
|
80
80
|
} from "../lib/session-host-snapshot.js";
|
|
81
81
|
import { acquireSessionHostLease } from "../lib/session-host-lease.js";
|
|
82
|
+
import {
|
|
83
|
+
openProductionSessionBudgetRoot,
|
|
84
|
+
sessionBudgetAdmissionError,
|
|
85
|
+
} from "../lib/session-budget-production-root.js";
|
|
86
|
+
import {
|
|
87
|
+
beginSessionBudgetUsage,
|
|
88
|
+
markSessionBudgetUsageUnknown,
|
|
89
|
+
recordSessionBudgetUsage,
|
|
90
|
+
rejectSessionBudgetUsageUnknown,
|
|
91
|
+
} from "../lib/session-budget-usage.js";
|
|
82
92
|
import {
|
|
83
93
|
SideEffectLedger,
|
|
84
94
|
classifyToolSideEffect,
|
|
@@ -236,6 +246,29 @@ export function resolveReplMeteredSessionId(useJsonl, sessionId) {
|
|
|
236
246
|
return useJsonl && sessionId ? sessionId : null;
|
|
237
247
|
}
|
|
238
248
|
|
|
249
|
+
export function combineReplSignals(...signals) {
|
|
250
|
+
const active = [...new Set(signals.filter(Boolean))];
|
|
251
|
+
if (active.length === 0) return null;
|
|
252
|
+
if (active.length === 1) return active[0];
|
|
253
|
+
return AbortSignal.any(active);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export async function closeReplSessionBudgetRootScope(scope) {
|
|
257
|
+
const root = scope?.root || null;
|
|
258
|
+
if (!root) return false;
|
|
259
|
+
const closed = await root.close();
|
|
260
|
+
scope.root = null;
|
|
261
|
+
return closed;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function releaseReplSessionHostLeaseScope(scope) {
|
|
265
|
+
const lease = scope?.lease || null;
|
|
266
|
+
if (!lease) return false;
|
|
267
|
+
const released = lease.release?.();
|
|
268
|
+
scope.lease = null;
|
|
269
|
+
return released;
|
|
270
|
+
}
|
|
271
|
+
|
|
239
272
|
function attachReplCompactionLedgerMetadata(error, callId, settled) {
|
|
240
273
|
let target = error;
|
|
241
274
|
if (!target || (typeof target !== "object" && typeof target !== "function")) {
|
|
@@ -293,6 +326,7 @@ export async function runReplMeteredModelCallWithLedger({
|
|
|
293
326
|
provider,
|
|
294
327
|
model,
|
|
295
328
|
source = "model",
|
|
329
|
+
sessionBudget = null,
|
|
296
330
|
call,
|
|
297
331
|
attachErrorMetadata = false,
|
|
298
332
|
}) {
|
|
@@ -311,6 +345,7 @@ export async function runReplMeteredModelCallWithLedger({
|
|
|
311
345
|
provider,
|
|
312
346
|
model,
|
|
313
347
|
source,
|
|
348
|
+
sessionBudget,
|
|
314
349
|
call,
|
|
315
350
|
});
|
|
316
351
|
return Object.freeze({ result, callId, usageLedgerSettled });
|
|
@@ -545,7 +580,7 @@ async function _persistAlwaysAllow(tool, args) {
|
|
|
545
580
|
/**
|
|
546
581
|
* Execute a tool call — delegates to agent-core with REPL's hookDb and cwd.
|
|
547
582
|
*/
|
|
548
|
-
async function executeTool(name, args) {
|
|
583
|
+
async function executeTool(name, args, context = {}) {
|
|
549
584
|
return coreExecuteTool(name, args, {
|
|
550
585
|
hookDb: _hookDb,
|
|
551
586
|
cwd: process.cwd(),
|
|
@@ -556,6 +591,9 @@ async function executeTool(name, args) {
|
|
|
556
591
|
settingsHooks: _settingsHooks,
|
|
557
592
|
classifyAllShell: _classifyAllShell,
|
|
558
593
|
sandbox: _sandbox,
|
|
594
|
+
sessionId: context.sessionId || null,
|
|
595
|
+
sessionBudget: context.sessionBudget || null,
|
|
596
|
+
signal: context.signal || null,
|
|
559
597
|
});
|
|
560
598
|
}
|
|
561
599
|
|
|
@@ -938,6 +976,11 @@ export async function agentLoop(messages, options) {
|
|
|
938
976
|
persistTokenUsage(options.sessionId, projectRuntimeTokenUsage(event)),
|
|
939
977
|
);
|
|
940
978
|
}
|
|
979
|
+
recordSessionBudgetUsage(
|
|
980
|
+
options.sessionBudget,
|
|
981
|
+
event,
|
|
982
|
+
"REPL usage settlement",
|
|
983
|
+
);
|
|
941
984
|
} else if (
|
|
942
985
|
event.type === "model-usage-started" ||
|
|
943
986
|
event.type === "model-usage-unknown" ||
|
|
@@ -966,6 +1009,15 @@ export async function agentLoop(messages, options) {
|
|
|
966
1009
|
),
|
|
967
1010
|
);
|
|
968
1011
|
}
|
|
1012
|
+
if (event.type === "model-usage-started") {
|
|
1013
|
+
beginSessionBudgetUsage(
|
|
1014
|
+
options.sessionBudget,
|
|
1015
|
+
event,
|
|
1016
|
+
"REPL provider call",
|
|
1017
|
+
);
|
|
1018
|
+
} else if (markSessionBudgetUsageUnknown(options.sessionBudget, event)) {
|
|
1019
|
+
rejectSessionBudgetUsageUnknown(event, "REPL provider call");
|
|
1020
|
+
}
|
|
969
1021
|
} else if (event.type === "iteration-warning") {
|
|
970
1022
|
writeOut(chalk.yellow(`\n ${event.message}\n`));
|
|
971
1023
|
} else if (event.type === "iteration-budget-exhausted") {
|
|
@@ -2630,6 +2682,17 @@ export async function runReplStartupBoundary(options, startupDependencies) {
|
|
|
2630
2682
|
}
|
|
2631
2683
|
return refuseStartup(options, startupCandidate);
|
|
2632
2684
|
}
|
|
2685
|
+
if (
|
|
2686
|
+
options.sessionBudgetRoot?.enabled === true &&
|
|
2687
|
+
startupAdmission.useJsonl !== true
|
|
2688
|
+
) {
|
|
2689
|
+
throw Object.assign(
|
|
2690
|
+
new Error(
|
|
2691
|
+
"session budget root requires durable JSONL session persistence, but JSONL storage is unavailable",
|
|
2692
|
+
),
|
|
2693
|
+
{ code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
|
|
2694
|
+
);
|
|
2695
|
+
}
|
|
2633
2696
|
|
|
2634
2697
|
// Only a frozen, branded admission capability may cross into workspace,
|
|
2635
2698
|
// pipe, config, plugin, hook, MCP, model, or tool initialization.
|
|
@@ -2660,6 +2723,7 @@ export async function runReplStartupBoundary(options, startupDependencies) {
|
|
|
2660
2723
|
null,
|
|
2661
2724
|
);
|
|
2662
2725
|
const leaseScope = options._sessionHostLeaseScope || null;
|
|
2726
|
+
const budgetScope = options._sessionBudgetRootScope || null;
|
|
2663
2727
|
const leaseSessionId = startupCandidate?.sessionId || options.sessionId;
|
|
2664
2728
|
if (
|
|
2665
2729
|
leaseScope &&
|
|
@@ -2669,9 +2733,79 @@ export async function runReplStartupBoundary(options, startupDependencies) {
|
|
|
2669
2733
|
) {
|
|
2670
2734
|
leaseScope.lease = acquireHostLease(leaseSessionId, { hostKind: "repl" });
|
|
2671
2735
|
}
|
|
2736
|
+
let workspaceOptions = options;
|
|
2737
|
+
if (options.sessionBudgetRoot?.enabled === true) {
|
|
2738
|
+
if (!leaseSessionId || !leaseScope?.lease) {
|
|
2739
|
+
throw Object.assign(
|
|
2740
|
+
new Error(
|
|
2741
|
+
"session budget root requires an acquired REPL host lease for its durable session",
|
|
2742
|
+
),
|
|
2743
|
+
{ code: "CC_SESSION_BUDGET_LEASE_REQUIRED" },
|
|
2744
|
+
);
|
|
2745
|
+
}
|
|
2746
|
+
if (!budgetScope || budgetScope.root) {
|
|
2747
|
+
throw Object.assign(
|
|
2748
|
+
new Error("REPL session budget root scope is invalid"),
|
|
2749
|
+
{ code: "CC_SESSION_BUDGET_SCOPE_INVALID" },
|
|
2750
|
+
);
|
|
2751
|
+
}
|
|
2752
|
+
const openBudgetRoot = dependencyDataFunction(
|
|
2753
|
+
startupDependencies,
|
|
2754
|
+
"openProductionSessionBudgetRoot",
|
|
2755
|
+
null,
|
|
2756
|
+
);
|
|
2757
|
+
if (typeof openBudgetRoot !== "function") {
|
|
2758
|
+
throw invalidReplRecovery(
|
|
2759
|
+
"REPL session budget root dependency is missing",
|
|
2760
|
+
"CC_REPL_STARTUP_DEPENDENCY_INVALID",
|
|
2761
|
+
);
|
|
2762
|
+
}
|
|
2763
|
+
const root = openBudgetRoot(
|
|
2764
|
+
leaseSessionId,
|
|
2765
|
+
options.sessionBudgetRoot,
|
|
2766
|
+
{
|
|
2767
|
+
persist: true,
|
|
2768
|
+
signal: combineReplSignals(options.signal, leaseScope.lease.signal),
|
|
2769
|
+
table: options.sessionBudgetRoot.table,
|
|
2770
|
+
},
|
|
2771
|
+
);
|
|
2772
|
+
if (
|
|
2773
|
+
root?.enabled !== true ||
|
|
2774
|
+
!root.budget ||
|
|
2775
|
+
!root.options ||
|
|
2776
|
+
root.options.sessionBudget !== root.budget ||
|
|
2777
|
+
typeof root.close !== "function"
|
|
2778
|
+
) {
|
|
2779
|
+
try {
|
|
2780
|
+
root?.close?.();
|
|
2781
|
+
} catch {
|
|
2782
|
+
// The invalid root is rejected regardless of cleanup outcome.
|
|
2783
|
+
}
|
|
2784
|
+
throw Object.assign(new Error("REPL session budget root is invalid"), {
|
|
2785
|
+
code: "CC_SESSION_BUDGET_ROOT_INVALID",
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2788
|
+
if (root.budget.signal?.aborted === true) {
|
|
2789
|
+
const admissionError = sessionBudgetAdmissionError(
|
|
2790
|
+
root.budget.reason?.(),
|
|
2791
|
+
"REPL startup",
|
|
2792
|
+
);
|
|
2793
|
+
try {
|
|
2794
|
+
await root.close();
|
|
2795
|
+
} catch (cleanupError) {
|
|
2796
|
+
throw new AggregateError(
|
|
2797
|
+
[admissionError, cleanupError],
|
|
2798
|
+
"REPL budget admission and authority cleanup both failed",
|
|
2799
|
+
);
|
|
2800
|
+
}
|
|
2801
|
+
throw admissionError;
|
|
2802
|
+
}
|
|
2803
|
+
budgetScope.root = root;
|
|
2804
|
+
workspaceOptions = { ...options, ...root.options };
|
|
2805
|
+
}
|
|
2672
2806
|
const trustedWorkspaceRoot = readCwd();
|
|
2673
2807
|
return enterWorkspace(trustedWorkspaceRoot, () =>
|
|
2674
|
-
startWorkspace(
|
|
2808
|
+
startWorkspace(workspaceOptions, startupAdmission),
|
|
2675
2809
|
);
|
|
2676
2810
|
}
|
|
2677
2811
|
|
|
@@ -2681,26 +2815,34 @@ export function startReplJsonlSession(
|
|
|
2681
2815
|
requestedId,
|
|
2682
2816
|
meta,
|
|
2683
2817
|
observabilityScope,
|
|
2818
|
+
options = {},
|
|
2684
2819
|
) {
|
|
2820
|
+
const requireDurable =
|
|
2821
|
+
observabilityScope != null || options.requireDurable === true;
|
|
2685
2822
|
try {
|
|
2686
2823
|
const sessionId = startSession(requestedId, {
|
|
2687
2824
|
...meta,
|
|
2688
2825
|
...(observabilityScope != null ? { observabilityScope } : {}),
|
|
2689
2826
|
});
|
|
2690
2827
|
if (
|
|
2691
|
-
|
|
2828
|
+
requireDurable &&
|
|
2692
2829
|
(typeof sessionId !== "string" || !sessionId)
|
|
2693
2830
|
) {
|
|
2694
2831
|
throw new Error("JSONL session creation returned no durable session id");
|
|
2695
2832
|
}
|
|
2696
2833
|
return sessionId || null;
|
|
2697
2834
|
} catch (error) {
|
|
2698
|
-
if (
|
|
2835
|
+
if (!requireDurable) return null;
|
|
2699
2836
|
const failure = new Error(
|
|
2700
|
-
|
|
2837
|
+
observabilityScope != null
|
|
2838
|
+
? "scoped JSONL session could not be durably created"
|
|
2839
|
+
: "budgeted JSONL session could not be durably created",
|
|
2701
2840
|
{ cause: error },
|
|
2702
2841
|
);
|
|
2703
|
-
failure.code =
|
|
2842
|
+
failure.code =
|
|
2843
|
+
observabilityScope != null
|
|
2844
|
+
? "CC_OBSERVABILITY_SCOPE_START_FAILED"
|
|
2845
|
+
: "CC_SESSION_BUDGET_SESSION_START_FAILED";
|
|
2704
2846
|
throw failure;
|
|
2705
2847
|
}
|
|
2706
2848
|
}
|
|
@@ -2708,23 +2850,45 @@ export function startReplJsonlSession(
|
|
|
2708
2850
|
/** Start the agentic REPL with non-overridable production bindings. */
|
|
2709
2851
|
export async function startAgentRepl(options = {}) {
|
|
2710
2852
|
const sessionHostLeaseScope = { lease: null };
|
|
2853
|
+
const sessionBudgetRootScope = { root: null };
|
|
2711
2854
|
const runtimeOptions = {
|
|
2712
2855
|
...options,
|
|
2713
2856
|
_sessionHostLeaseScope: sessionHostLeaseScope,
|
|
2857
|
+
_sessionBudgetRootScope: sessionBudgetRootScope,
|
|
2714
2858
|
};
|
|
2715
2859
|
try {
|
|
2716
2860
|
const result = await runReplStartupBoundary(runtimeOptions, {
|
|
2717
2861
|
prepareReplStartupResume,
|
|
2718
2862
|
refuseReplStartupResume,
|
|
2719
2863
|
acquireSessionHostLease,
|
|
2864
|
+
openProductionSessionBudgetRoot,
|
|
2720
2865
|
cwd: () => process.cwd(),
|
|
2721
2866
|
runWithHostHooksV2Workspace,
|
|
2722
2867
|
startAgentReplInWorkspace,
|
|
2723
2868
|
});
|
|
2724
|
-
if (result?.started === false)
|
|
2869
|
+
if (result?.started === false) {
|
|
2870
|
+
await closeReplSessionBudgetRootScope(sessionBudgetRootScope);
|
|
2871
|
+
releaseReplSessionHostLeaseScope(sessionHostLeaseScope);
|
|
2872
|
+
}
|
|
2725
2873
|
return result;
|
|
2726
2874
|
} catch (error) {
|
|
2727
|
-
|
|
2875
|
+
const cleanupErrors = [];
|
|
2876
|
+
try {
|
|
2877
|
+
await closeReplSessionBudgetRootScope(sessionBudgetRootScope);
|
|
2878
|
+
} catch (cleanupError) {
|
|
2879
|
+
cleanupErrors.push(cleanupError);
|
|
2880
|
+
}
|
|
2881
|
+
try {
|
|
2882
|
+
releaseReplSessionHostLeaseScope(sessionHostLeaseScope);
|
|
2883
|
+
} catch (cleanupError) {
|
|
2884
|
+
cleanupErrors.push(cleanupError);
|
|
2885
|
+
}
|
|
2886
|
+
if (cleanupErrors.length > 0) {
|
|
2887
|
+
throw new AggregateError(
|
|
2888
|
+
[error, ...cleanupErrors],
|
|
2889
|
+
"REPL startup and authority cleanup both failed",
|
|
2890
|
+
);
|
|
2891
|
+
}
|
|
2728
2892
|
throw error;
|
|
2729
2893
|
}
|
|
2730
2894
|
}
|
|
@@ -2802,6 +2966,8 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
2802
2966
|
}
|
|
2803
2967
|
};
|
|
2804
2968
|
const _sessionHostLeaseScope = options._sessionHostLeaseScope || null;
|
|
2969
|
+
const _sessionBudgetRootScope = options._sessionBudgetRootScope || null;
|
|
2970
|
+
const _sessionBudget = options.sessionBudget || null;
|
|
2805
2971
|
let _sessionHostLeaseAbortListener = null;
|
|
2806
2972
|
let _sessionHostLeaseAbortSignal = null;
|
|
2807
2973
|
const _detachSessionHostLease = () => {
|
|
@@ -2840,6 +3006,35 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
2840
3006
|
return previous;
|
|
2841
3007
|
};
|
|
2842
3008
|
_attachSessionHostLease();
|
|
3009
|
+
let _sessionBudgetAbortListener = null;
|
|
3010
|
+
let _sessionBudgetAbortSignal = null;
|
|
3011
|
+
const _detachSessionBudget = () => {
|
|
3012
|
+
if (_sessionBudgetAbortListener && _sessionBudgetAbortSignal) {
|
|
3013
|
+
_sessionBudgetAbortSignal.removeEventListener(
|
|
3014
|
+
"abort",
|
|
3015
|
+
_sessionBudgetAbortListener,
|
|
3016
|
+
);
|
|
3017
|
+
}
|
|
3018
|
+
_sessionBudgetAbortListener = null;
|
|
3019
|
+
_sessionBudgetAbortSignal = null;
|
|
3020
|
+
};
|
|
3021
|
+
const _attachSessionBudget = () => {
|
|
3022
|
+
const signal = _sessionBudget?.signal;
|
|
3023
|
+
if (!signal || _sessionBudgetAbortListener) return;
|
|
3024
|
+
_sessionBudgetAbortListener = () =>
|
|
3025
|
+
_requestReplOutputClose(
|
|
3026
|
+
sessionBudgetAdmissionError(
|
|
3027
|
+
_sessionBudget.reason?.() || "session-aborted",
|
|
3028
|
+
"REPL session",
|
|
3029
|
+
),
|
|
3030
|
+
);
|
|
3031
|
+
_sessionBudgetAbortSignal = signal;
|
|
3032
|
+
signal.addEventListener("abort", _sessionBudgetAbortListener, {
|
|
3033
|
+
once: true,
|
|
3034
|
+
});
|
|
3035
|
+
if (signal.aborted) _sessionBudgetAbortListener();
|
|
3036
|
+
};
|
|
3037
|
+
_attachSessionBudget();
|
|
2843
3038
|
const _replOutputFlow = outputScope.flow;
|
|
2844
3039
|
outputScope.setFailureHandler(_requestReplOutputClose);
|
|
2845
3040
|
const _disposeReplPipeSafety = installPipeSafety(undefined, () =>
|
|
@@ -2895,7 +3090,8 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
2895
3090
|
provider: callProvider || provider,
|
|
2896
3091
|
model: callModel || model,
|
|
2897
3092
|
source,
|
|
2898
|
-
|
|
3093
|
+
sessionBudget: _sessionBudget,
|
|
3094
|
+
call: () => call({ signal: options.signal || null }),
|
|
2899
3095
|
attachErrorMetadata: includeLedgerMetadata,
|
|
2900
3096
|
});
|
|
2901
3097
|
return includeLedgerMetadata ? metered : metered.result;
|
|
@@ -2926,7 +3122,12 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
2926
3122
|
sessionId: durableSessionId,
|
|
2927
3123
|
tool,
|
|
2928
3124
|
args,
|
|
2929
|
-
execute:
|
|
3125
|
+
execute: (name, toolArgs) =>
|
|
3126
|
+
executeTool(name, toolArgs, {
|
|
3127
|
+
sessionId: durableSessionId,
|
|
3128
|
+
sessionBudget: _sessionBudget,
|
|
3129
|
+
signal: options.signal || null,
|
|
3130
|
+
}),
|
|
2930
3131
|
now: options.now || Date.now,
|
|
2931
3132
|
terminalLatch: _runtimeLedgerTerminalLatch,
|
|
2932
3133
|
});
|
|
@@ -3089,13 +3290,13 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
3089
3290
|
callModel: model,
|
|
3090
3291
|
source: "semantic-compaction",
|
|
3091
3292
|
includeLedgerMetadata: true,
|
|
3092
|
-
call: () =>
|
|
3293
|
+
call: ({ signal }) =>
|
|
3093
3294
|
chatWithTools([{ role: "user", content: prompt }], {
|
|
3094
3295
|
provider,
|
|
3095
3296
|
model,
|
|
3096
3297
|
baseUrl,
|
|
3097
3298
|
apiKey,
|
|
3098
|
-
signal
|
|
3299
|
+
signal,
|
|
3099
3300
|
enabledToolNames: [],
|
|
3100
3301
|
extraToolDefinitions: [],
|
|
3101
3302
|
hostManagedToolPolicy: null,
|
|
@@ -3535,6 +3736,7 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
3535
3736
|
options.sessionId || null,
|
|
3536
3737
|
meta,
|
|
3537
3738
|
options.observabilityScope,
|
|
3739
|
+
{ requireDurable: Boolean(_sessionBudget) },
|
|
3538
3740
|
);
|
|
3539
3741
|
if (
|
|
3540
3742
|
sessionId &&
|
|
@@ -4410,7 +4612,11 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
4410
4612
|
callProvider: request?.provider,
|
|
4411
4613
|
callModel: request?.model,
|
|
4412
4614
|
source: "model",
|
|
4413
|
-
call: () =>
|
|
4615
|
+
call: ({ signal }) =>
|
|
4616
|
+
invokeToolFreeAdvisor({
|
|
4617
|
+
...request,
|
|
4618
|
+
signal: combineReplSignals(request?.signal, signal),
|
|
4619
|
+
}),
|
|
4414
4620
|
}),
|
|
4415
4621
|
onEvent: (event) => {
|
|
4416
4622
|
if (!useJsonl || !sessionId) return;
|
|
@@ -6953,6 +7159,14 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
6953
7159
|
if (sessionArg.startsWith("resume ")) {
|
|
6954
7160
|
const resumeId = sessionArg.slice(7).trim();
|
|
6955
7161
|
try {
|
|
7162
|
+
if (_sessionBudget && resumeId !== sessionId) {
|
|
7163
|
+
throw Object.assign(
|
|
7164
|
+
new Error(
|
|
7165
|
+
"a budgeted REPL is bound to its startup session; exit and restart to resume another session",
|
|
7166
|
+
),
|
|
7167
|
+
{ code: "CC_SESSION_BUDGET_REPL_SWITCH_UNSUPPORTED" },
|
|
7168
|
+
);
|
|
7169
|
+
}
|
|
6956
7170
|
if (useJsonl) {
|
|
6957
7171
|
const initialCandidate = _prepareJsonlResumeCandidate(resumeId);
|
|
6958
7172
|
if (!initialCandidate.ok) throw initialCandidate.error;
|
|
@@ -9084,7 +9298,7 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
9084
9298
|
// of hanging forever. undefined → agent-core's 180s default (matches cc
|
|
9085
9299
|
// chat/ask); config.llm.streamStallTimeoutMs tunes or disables (0).
|
|
9086
9300
|
streamStallTimeoutMs: _streamStallTimeoutMs,
|
|
9087
|
-
signal: _turnAbort.signal,
|
|
9301
|
+
signal: combineReplSignals(_turnAbort.signal, options.signal),
|
|
9088
9302
|
// On an auto-detected image turn, switch to the vision LLM for this
|
|
9089
9303
|
// turn only (provider/baseUrl/apiKey unchanged, model → vision model).
|
|
9090
9304
|
provider: _visionLlm ? _visionLlm.provider : provider,
|
|
@@ -9200,12 +9414,13 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
9200
9414
|
callProvider: provider,
|
|
9201
9415
|
callModel: activeModel,
|
|
9202
9416
|
source: "model",
|
|
9203
|
-
call: () =>
|
|
9417
|
+
call: ({ signal }) =>
|
|
9204
9418
|
chatWithTools([{ role: "user", content: p }], {
|
|
9205
9419
|
model: activeModel,
|
|
9206
9420
|
provider,
|
|
9207
9421
|
baseUrl,
|
|
9208
9422
|
apiKey,
|
|
9423
|
+
signal,
|
|
9209
9424
|
enabledToolNames: [],
|
|
9210
9425
|
}),
|
|
9211
9426
|
});
|
|
@@ -9743,9 +9958,15 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
9743
9958
|
}
|
|
9744
9959
|
|
|
9745
9960
|
// Shutdown runtime
|
|
9961
|
+
_detachSessionBudget();
|
|
9962
|
+
try {
|
|
9963
|
+
await closeReplSessionBudgetRootScope(_sessionBudgetRootScope);
|
|
9964
|
+
} catch (error) {
|
|
9965
|
+
_replOutputFailure ||= error;
|
|
9966
|
+
}
|
|
9746
9967
|
_detachSessionHostLease();
|
|
9747
9968
|
try {
|
|
9748
|
-
_sessionHostLeaseScope
|
|
9969
|
+
releaseReplSessionHostLeaseScope(_sessionHostLeaseScope);
|
|
9749
9970
|
} catch (error) {
|
|
9750
9971
|
_replOutputFailure ||= error;
|
|
9751
9972
|
}
|
|
@@ -109,8 +109,10 @@ import { buildPermissionDecision } from "../lib/permission-decision.js";
|
|
|
109
109
|
import { resolveSandboxPolicyPath } from "../lib/agent-sandbox.js";
|
|
110
110
|
import {
|
|
111
111
|
beginManagedToolCheckpoint,
|
|
112
|
+
managedToolCheckpointBinding,
|
|
112
113
|
settleManagedToolCheckpoint,
|
|
113
114
|
} from "../lib/managed-tool-checkpoint.js";
|
|
115
|
+
import { sessionBudgetAdmissionError } from "../lib/session-budget-production-root.js";
|
|
114
116
|
import {
|
|
115
117
|
createMcpCallLedger,
|
|
116
118
|
McpEffect,
|
|
@@ -3570,6 +3572,35 @@ export async function executeTool(name, args, context = {}) {
|
|
|
3570
3572
|
}
|
|
3571
3573
|
}
|
|
3572
3574
|
|
|
3575
|
+
let sessionBudgetTool = null;
|
|
3576
|
+
if (typeof context.sessionBudget?.beginTool === "function") {
|
|
3577
|
+
const toolBinding = JSON.stringify({
|
|
3578
|
+
sessionId: context.sessionId || null,
|
|
3579
|
+
turnId: context.turnId || null,
|
|
3580
|
+
toolCallId: context.toolCallId || randomUUID(),
|
|
3581
|
+
tool: name,
|
|
3582
|
+
});
|
|
3583
|
+
const toolBudgetId = `tool:${createHash("sha256")
|
|
3584
|
+
.update(toolBinding, "utf8")
|
|
3585
|
+
.digest("hex")
|
|
3586
|
+
.slice(0, 48)}`;
|
|
3587
|
+
sessionBudgetTool = context.sessionBudget.beginTool({
|
|
3588
|
+
id: toolBudgetId,
|
|
3589
|
+
kind: String(name || "tool").slice(0, 128),
|
|
3590
|
+
});
|
|
3591
|
+
if (!sessionBudgetTool?.ok) {
|
|
3592
|
+
return {
|
|
3593
|
+
error: `Session budget blocked tool execution: ${sessionBudgetTool?.reason || "session-aborted"}`,
|
|
3594
|
+
code: "CC_SESSION_BUDGET_EXHAUSTED",
|
|
3595
|
+
budgetReason: sessionBudgetTool?.reason || "session-aborted",
|
|
3596
|
+
policy: {
|
|
3597
|
+
decision: "blocked",
|
|
3598
|
+
via: "session-budget",
|
|
3599
|
+
},
|
|
3600
|
+
};
|
|
3601
|
+
}
|
|
3602
|
+
}
|
|
3603
|
+
|
|
3573
3604
|
const startTime = Date.now();
|
|
3574
3605
|
let toolResult;
|
|
3575
3606
|
try {
|
|
@@ -3598,6 +3629,7 @@ export async function executeTool(name, args, context = {}) {
|
|
|
3598
3629
|
strictUsageTelemetry: context.strictUsageTelemetry === true,
|
|
3599
3630
|
onUsageBoundary: context.onUsageBoundary || null,
|
|
3600
3631
|
onUsageSettlement: context.onUsageSettlement || null,
|
|
3632
|
+
onProviderReceipt: context.onProviderReceipt || null,
|
|
3601
3633
|
onToolCallBoundary: context.onToolCallBoundary || null,
|
|
3602
3634
|
onToolCallSettlement: context.onToolCallSettlement || null,
|
|
3603
3635
|
backgroundUsageFailureState: context.backgroundUsageFailureState || null,
|
|
@@ -3661,6 +3693,8 @@ export async function executeTool(name, args, context = {}) {
|
|
|
3661
3693
|
}
|
|
3662
3694
|
}
|
|
3663
3695
|
throw err;
|
|
3696
|
+
} finally {
|
|
3697
|
+
sessionBudgetTool?.end?.();
|
|
3664
3698
|
}
|
|
3665
3699
|
|
|
3666
3700
|
const durationMs = Date.now() - startTime;
|
|
@@ -5014,6 +5048,7 @@ async function executeToolInner(
|
|
|
5014
5048
|
strictUsageTelemetry = false,
|
|
5015
5049
|
onUsageBoundary = null,
|
|
5016
5050
|
onUsageSettlement = null,
|
|
5051
|
+
onProviderReceipt = null,
|
|
5017
5052
|
onToolCallBoundary = null,
|
|
5018
5053
|
onToolCallSettlement = null,
|
|
5019
5054
|
backgroundUsageFailureState = null,
|
|
@@ -6763,6 +6798,7 @@ async function executeToolInner(
|
|
|
6763
6798
|
strictUsageTelemetry,
|
|
6764
6799
|
onUsageBoundary,
|
|
6765
6800
|
onUsageSettlement,
|
|
6801
|
+
onProviderReceipt,
|
|
6766
6802
|
onToolCallBoundary,
|
|
6767
6803
|
onToolCallSettlement,
|
|
6768
6804
|
backgroundUsageFailureState,
|
|
@@ -7689,6 +7725,15 @@ async function executeToolInner(
|
|
|
7689
7725
|
projectSkillUsage(event),
|
|
7690
7726
|
)
|
|
7691
7727
|
: null;
|
|
7728
|
+
const observeSkillReceipt =
|
|
7729
|
+
strictUsageTelemetry === true &&
|
|
7730
|
+
typeof onProviderReceipt === "function"
|
|
7731
|
+
? (event) =>
|
|
7732
|
+
_notifyStrictProviderReceipt(
|
|
7733
|
+
onProviderReceipt,
|
|
7734
|
+
projectSkillUsage(event),
|
|
7735
|
+
)
|
|
7736
|
+
: null;
|
|
7692
7737
|
const projectSkillTool = (event) => ({
|
|
7693
7738
|
...event,
|
|
7694
7739
|
attribution: event?.attribution || projectSkillUsage({}).attribution,
|
|
@@ -7781,6 +7826,9 @@ async function executeToolInner(
|
|
|
7781
7826
|
strictUsageTelemetry: true,
|
|
7782
7827
|
onUsageBoundary: observeSkillBoundary,
|
|
7783
7828
|
onUsageSettlement: observeSkillSettlement,
|
|
7829
|
+
...(observeSkillReceipt
|
|
7830
|
+
? { onProviderReceipt: observeSkillReceipt }
|
|
7831
|
+
: {}),
|
|
7784
7832
|
onToolCallBoundary: observeSkillToolBoundary,
|
|
7785
7833
|
onToolCallSettlement: observeSkillToolSettlement,
|
|
7786
7834
|
}
|
|
@@ -9642,6 +9690,20 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
9642
9690
|
}
|
|
9643
9691
|
}
|
|
9644
9692
|
: null;
|
|
9693
|
+
const observeSubagentReceipt =
|
|
9694
|
+
ctx.strictUsageTelemetry === true &&
|
|
9695
|
+
typeof ctx.onProviderReceipt === "function"
|
|
9696
|
+
? (event) => {
|
|
9697
|
+
try {
|
|
9698
|
+
return _notifyStrictProviderReceipt(
|
|
9699
|
+
ctx.onProviderReceipt,
|
|
9700
|
+
projectSubagentUsage(event),
|
|
9701
|
+
);
|
|
9702
|
+
} catch (error) {
|
|
9703
|
+
throw latchBackgroundUsageFailure(error);
|
|
9704
|
+
}
|
|
9705
|
+
}
|
|
9706
|
+
: null;
|
|
9645
9707
|
const projectSubagentTool = (event) => ({
|
|
9646
9708
|
...event,
|
|
9647
9709
|
attribution:
|
|
@@ -9751,6 +9813,9 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
9751
9813
|
strictUsageTelemetry: true,
|
|
9752
9814
|
onUsageBoundary: observeSubagentBoundary,
|
|
9753
9815
|
onUsageSettlement: observeSubagentSettlement,
|
|
9816
|
+
...(observeSubagentReceipt
|
|
9817
|
+
? { onProviderReceipt: observeSubagentReceipt }
|
|
9818
|
+
: {}),
|
|
9754
9819
|
onToolCallBoundary: observeSubagentToolBoundary,
|
|
9755
9820
|
onToolCallSettlement: observeSubagentToolSettlement,
|
|
9756
9821
|
}
|
|
@@ -12093,6 +12158,38 @@ function _notifyStrictUsageSettlement(observer, settlement) {
|
|
|
12093
12158
|
}
|
|
12094
12159
|
}
|
|
12095
12160
|
|
|
12161
|
+
function _notifyStrictProviderReceipt(observer, receipt) {
|
|
12162
|
+
if (typeof observer !== "function") return;
|
|
12163
|
+
let observation;
|
|
12164
|
+
try {
|
|
12165
|
+
observation = observer(receipt);
|
|
12166
|
+
} catch (error) {
|
|
12167
|
+
throw _runtimeUsageBoundaryFailure(
|
|
12168
|
+
error,
|
|
12169
|
+
"CC_USAGE_RECEIPT_PERSISTENCE_FAILED",
|
|
12170
|
+
"Child provider receipt persistence failed",
|
|
12171
|
+
);
|
|
12172
|
+
}
|
|
12173
|
+
let isThenable = false;
|
|
12174
|
+
try {
|
|
12175
|
+
isThenable = Boolean(observation && typeof observation.then === "function");
|
|
12176
|
+
} catch (error) {
|
|
12177
|
+
throw _runtimeUsageBoundaryFailure(
|
|
12178
|
+
error,
|
|
12179
|
+
"CC_USAGE_RECEIPT_OBSERVER_ASYNC",
|
|
12180
|
+
"Child provider receipt observer must be synchronous",
|
|
12181
|
+
);
|
|
12182
|
+
}
|
|
12183
|
+
if (isThenable) {
|
|
12184
|
+
void Promise.resolve(observation).catch(() => {});
|
|
12185
|
+
throw _runtimeUsageBoundaryFailure(
|
|
12186
|
+
null,
|
|
12187
|
+
"CC_USAGE_RECEIPT_OBSERVER_ASYNC",
|
|
12188
|
+
"Child provider receipt observer must be synchronous",
|
|
12189
|
+
);
|
|
12190
|
+
}
|
|
12191
|
+
}
|
|
12192
|
+
|
|
12096
12193
|
function _notifyStrictToolObserver(observer, event, phase) {
|
|
12097
12194
|
const upper = phase.toUpperCase();
|
|
12098
12195
|
if (typeof observer !== "function") {
|
|
@@ -12757,6 +12854,9 @@ export async function* agentLoop(messages, options) {
|
|
|
12757
12854
|
...(typeof options.onUsageSettlement === "function"
|
|
12758
12855
|
? { onUsageSettlement: options.onUsageSettlement }
|
|
12759
12856
|
: {}),
|
|
12857
|
+
...(typeof options.onProviderReceipt === "function"
|
|
12858
|
+
? { onProviderReceipt: options.onProviderReceipt }
|
|
12859
|
+
: {}),
|
|
12760
12860
|
...(typeof options.onStreamRetry === "function"
|
|
12761
12861
|
? { onStreamRetry: options.onStreamRetry }
|
|
12762
12862
|
: {}),
|
|
@@ -12773,6 +12873,7 @@ export async function* agentLoop(messages, options) {
|
|
|
12773
12873
|
strictUsageTelemetry: options.strictUsageTelemetry === true,
|
|
12774
12874
|
onUsageBoundary: options.onUsageBoundary || null,
|
|
12775
12875
|
onUsageSettlement: options.onUsageSettlement || null,
|
|
12876
|
+
onProviderReceipt: options.onProviderReceipt || null,
|
|
12776
12877
|
onToolCallBoundary: options.onToolCallBoundary || null,
|
|
12777
12878
|
onToolCallSettlement: options.onToolCallSettlement || null,
|
|
12778
12879
|
parentMessages: messages, // pass parent messages for sub-agent auto-condensation
|
|
@@ -13013,6 +13114,21 @@ export async function* agentLoop(messages, options) {
|
|
|
13013
13114
|
let emptyThinkingReprompted = false;
|
|
13014
13115
|
|
|
13015
13116
|
while (budget.hasRemaining()) {
|
|
13117
|
+
if (typeof toolContext.sessionBudget?.consumeTurn === "function") {
|
|
13118
|
+
const turnBudgetId = `turn:${createHash("sha256")
|
|
13119
|
+
.update(`${runId}:t${budget.consumed + 1}`, "utf8")
|
|
13120
|
+
.digest("hex")
|
|
13121
|
+
.slice(0, 48)}`;
|
|
13122
|
+
const admission = toolContext.sessionBudget.consumeTurn({
|
|
13123
|
+
id: turnBudgetId,
|
|
13124
|
+
});
|
|
13125
|
+
if (!admission?.ok) {
|
|
13126
|
+
throw sessionBudgetAdmissionError(
|
|
13127
|
+
admission?.reason,
|
|
13128
|
+
`turn ${budget.consumed + 1}`,
|
|
13129
|
+
);
|
|
13130
|
+
}
|
|
13131
|
+
}
|
|
13016
13132
|
budget.consume();
|
|
13017
13133
|
throwIfAborted(signal);
|
|
13018
13134
|
|
|
@@ -14205,6 +14321,13 @@ export async function* agentLoop(messages, options) {
|
|
|
14205
14321
|
tool_use_id: call.id,
|
|
14206
14322
|
turn_id: `${runId}:t${budget.consumed}`,
|
|
14207
14323
|
...(workflowBinding || {}),
|
|
14324
|
+
...(managedCheckpointHandle
|
|
14325
|
+
? {
|
|
14326
|
+
managedCheckpointBinding: managedToolCheckpointBinding(
|
|
14327
|
+
managedCheckpointHandle,
|
|
14328
|
+
),
|
|
14329
|
+
}
|
|
14330
|
+
: {}),
|
|
14208
14331
|
};
|
|
14209
14332
|
// The event yield is a host persistence boundary. A detached child's
|
|
14210
14333
|
// fatal usage write can settle while the consumer handles it; fence
|