chainlesschain 0.163.6 → 0.163.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/assets/web-panel/assets/{AIOps-DDIUofA8.js → AIOps-CavM7W3k.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Bm-5xYRn.js → ActionButton-CUvZGabQ.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D5UH4ljI.js → Analytics-DeBnWnbe.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-D_ifjOOP.js → AppLayout-DbI5kxvd.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-BY1mXdC7.js → Artifacts-D93bigKm.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Bujr4Ml3.js → Audit-CBNvfUZa.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-sioKSTcC.js → BackgroundAgents-CJLyh_YU.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DDOAK8RK.js → Backup-D_0yoehD.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CtCsVVke.js → BaseInput-TJxmbObW.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DpNj0vnd.js → Chat-CE0dto1q.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZta3Ftr.js → ChatBubbleRenderer-CZ5-yYiD.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DoHVNSXq.js → Checkbox-Ck1RVIVo.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DlVl7Qmv.js → Codegen-qpoyf6DK.js} +1 -1
- package/src/assets/web-panel/assets/{Col-GIqoPYty.js → Col-DUyPWjIE.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CIAPEVji.js → Community-D_S1BemS.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BN7JiI_h.js → Compact-BjxeK-Gc.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CqUWCM9B.js → Compliance-Dd3CEJsu.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-A4iPp7A4.js → Cowork-B4QG7-ad.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-B2zeXXWb.js → Cron-BtZnids5.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BR2xmWr8.js → Crosschain-CHPfCBFD.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BzFDjrIv.js → DID-DT8DCEOK.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DKtDo3yA.js → Dashboard-COQab5_U.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-RNx43_YG.js → Dropdown-BY1PsQuU.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-SwMt4Rcy.js → EmailListRenderer-CsuAuaq3.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CsYebZ4X.js → FamilyGuardDashboard-BqpinD-j.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BmRKvBTy.js → Federation-D0gkfQFv.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CVxGTA-0.js → FormItemContext-BqgE-axK.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-x2iXpyB7.js → GenericCardRenderer-D0hJ2KvC.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DfqbkiOP.js → Git-CmMB0uPY.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-RuHyyj5O.js → Governance-BnVEI0Dk.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Bn7uZ7rI.js → Inference-YTAMihRP.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DlP7XefZ.js → KnowledgeGraph-0ax7VHop.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BYNdOiCd.js → Logs-B9TRcokL.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-JQYmDqM8.js → Marketplace-B6CSuD_H.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Cyx4yZ-9.js → McpTools-CjMXvOVU.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-VDuGZTN2.js → Memory-CXRF71U3.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-_yKo97gi.js → MobileBridge-DQgNp_oS.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CXRXW3q7.js → MobileProjects-DlPwcCbq.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-acTGtfLH.js → Mtc-6hDTRPe1.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-ClpjXfkY.js → MtcAudit-BlVHU1DS.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-_6Tn3o96.js → Multisig-DP9pzEbV.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CK7pbZzP.js → NLProgramming-Djorh8EV.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Czy6V_P8.js → Notes-oLZ-JkUg.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-Cqx-UVv3.js → NotificationSettings-Cg288VH3.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C69WDxGy.js → OrderTableRenderer-Bb1O3Ofr.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DFnA9vLQ.js → Organization-CBdo-bHs.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-ReZkk2yT.js → Overflow-qZdnVumx.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DzjSI0aI.js → P2P-D4kNfGNQ.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-DnlMemM7.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-DhQ5klhR.js → Permissions-DHucHFBJ.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-CUL1iHrW.js → PersonalDataHub-BovlOIPR.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-DU88iu4N.js → Pipeline-Deru3CQY.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Bw-sYfyK.js → Privacy-Bq5oTTbU.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Bq3Q5y0z.js → ProjectInit-BfzxVWAz.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C8spzpho.js → ProjectSettings-CKC6XBtH.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CMolGhae.js +1 -0
- package/src/assets/web-panel/assets/{Providers-Bf4eTP9W.js → Providers-C_jx4TWX.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Dme9BDU1.js → QrScannerModal-BdIHeVGC.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CIXfv1rE.js → QuickAsk-BwZwAcPD.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CIxvdeZ-.js → Recommend-BNTt0L-m.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C6k7MExI.js → RemoteSession-Biyn2-Ro.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CISDz2bl.js → Reputation-D6VpG32B.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CdnDxXyf.js → Row-D_74OvQQ.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C-QpRHsl.js → RssFeed-BTr0a-BQ.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DBjaGzSn.js → Search-C3MCFoNU.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CQKukOeE.js → Security-CqW9aJ6s.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DZz86jWb.js → Services-Cw5GNaHF.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-jb8RMK0d.js → Skeleton-DZps5qeY.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CdY76fZG.js → Skills-C6NQ1znT.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-C_CSiZX9.js → Sla-DFP8G2Sh.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-ESt6MB6v.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-qvimGO0O.js → SyncSettings-BHnN98aM.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Dng5LPJC.js → Tasks-NiSCaOf-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Bwqq5Wll.js → Templates-DsKFhW2C.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DNWuwP7Z.js → Tenant-CQ0E0ze5.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B-6Othpp.js → Terminal-D_rBu_by.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DKpKZfzx.js → TimelineRenderer-D3Vm4Po4.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DzfGMd2J.js → Tokens-DNTxRH6q.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BXwUi74J.js → Trigger-Dgprz1ms.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BNzUq4ui.js → Trust-B2rUnVBD.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BYugxww4.js → UkeySign-DEGQNc6_.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DdauhtSJ.js → VideoEditing-jlsAx3Eh.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CSC9bCe_.js → Wallet-8jQih1ij.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Q8AN3bTO.js → WebAuthn-XLeO6xIB.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-d-LBGCuA.js → WorkflowEditor-De_dgDAG.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BLVDCgsZ.js → chat-CI19R_Sk.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BZlPSEHl.js → colors-DsYTOYN3.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-IWseP6R6.js → compact-item-CM3-t_Qr.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DnVRV3Ao.js → createContext-BjxlBRZv.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DLQZA_Wn.js → hasIn-RDaWX_4i.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSjilZ9L.js → index-9R6BxAr0.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_N4-Gq9.js → index-B-Z8eFUJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dy0R5ZED.js → index-B0PMlbMs.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1ifZtXo.js → index-B5REnKt8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CINJQEj6.js → index-B7WBt_4T.js} +1 -1
- package/src/assets/web-panel/assets/{index-DocEhinm.js → index-B9O9YyWE.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjWnONdy.js → index-BCnZyIMA.js} +1 -1
- package/src/assets/web-panel/assets/{index-hwVDeoC0.js → index-BGqqJfL0.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bbj2NS_I.js → index-BHNYPO0b.js} +3 -3
- package/src/assets/web-panel/assets/{index-C5dgnilC.js → index-BKJr-TZp.js} +1 -1
- package/src/assets/web-panel/assets/{index-CT9vVN-X.js → index-BN6UPD2E.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpVrK6fr.js → index-Bi46Xu4u.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpBaJ3TD.js → index-BlT2VAEK.js} +1 -1
- package/src/assets/web-panel/assets/{index-1jeAudHd.js → index-C0yx-jtQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DOoQpuQY.js → index-C4gkzxkw.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZpYeqrh.js → index-CVQMeiwH.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhA3QEni.js → index-Cd3euP_4.js} +1 -1
- package/src/assets/web-panel/assets/{index-N_GoWZX4.js → index-Cd9OJhHG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOZJBTWZ.js → index-CiECJi-Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-CarMTIyQ.js → index-CjTrRt13.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZDekj7T.js → index-CnHH7bnD.js} +1 -1
- package/src/assets/web-panel/assets/{index-M7wxfAbm.js → index-Cpqm1qfU.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bxp7uDD8.js → index-CyOGN6a5.js} +1 -1
- package/src/assets/web-panel/assets/{index-DalA0TKC.js → index-D0zcy54x.js} +1 -1
- package/src/assets/web-panel/assets/{index-COev0W2g.js → index-D6sm5-Xq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUq0c7gq.js → index-DIUnNOjG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZs5bBnk.js → index-DX7tuWVJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbQNL0ue.js → index-DXXtGMUJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTbxp4UH.js → index-DcPFB8qJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-YSw_gxlZ.js → index-DoQA0-52.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_LQodeJ.js → index-Drlnwr8F.js} +1 -1
- package/src/assets/web-panel/assets/index-Drz6yq0m.js +1 -0
- package/src/assets/web-panel/assets/{index-jWb70ZgZ.js → index-Dsij_KsN.js} +1 -1
- package/src/assets/web-panel/assets/{index-DB0MJgF_.js → index-Dxge-xWl.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEu2lMBy.js → index-DyIWssPC.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2FqfMvU.js → index-IeiL9RKc.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dkwsi1Kn.js → index-nAH87mQP.js} +1 -1
- package/src/assets/web-panel/assets/{index-gt8bNefW.js → index-pPL66J85.js} +1 -1
- package/src/assets/web-panel/assets/index-uWiUs7S_.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-Co67Kqmb.js → initDefaultProps-BTL88of4.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BMOxQSF_.js → motion-BUB2pXwB.js} +1 -1
- package/src/assets/web-panel/assets/{move-C5fWDw-N.js → move-egCkkOMm.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BJevpL0e.js → mtc-parser-DAWhZC8c.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BCzNU8s6.js → omit-CvOxe_6d.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CybWvDPk.js → pickAttrs-DZUSLZ5Z.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BMWS9HnW.js → placementArrow-BERxGNMY.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BoL2UnGY.js → responsiveObserve-DZuDfZ9n.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DWNfXraU.js → slide-DO756sgI.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BquTM3tX.js → statusUtils-BRQlIz28.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BEkCleim.js → styleChecker-DCSfdybl.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Oecnq7EA.js → useFlexGapSupport-LD8dWVve.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CkDffJ4F.js → useFs-BX9uW2LK.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-qbvKXesB.js → usePersonalDataHub-BPSlPuHU.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C6v8n6mA.js → vnode-BmOILC9V.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-4CTeFILV.js → zoom-1iKowKGg.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +5 -5
- package/src/commands/agent.js +90 -1
- package/src/commands/automation.js +103 -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/commands/team-merge-review.js +937 -0
- package/src/commands/team.js +2 -0
- package/src/data/changelog.json +27 -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 +549 -28
- package/src/lib/agent-team/team-adjudication.js +40 -1
- package/src/lib/agent-team/team-merge-review-store.js +765 -0
- package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
- package/src/lib/agent-team/team-merge-review.js +1847 -0
- package/src/lib/automation-center-incidents.js +314 -0
- package/src/lib/automation-center-runtime.js +448 -0
- package/src/lib/automation-center.js +182 -38
- package/src/lib/automation-engine.js +535 -0
- package/src/lib/automation-execution-authority.js +241 -12
- package/src/lib/automation-execution-incident.js +737 -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 +442 -15
- 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 +325 -10
- package/src/lib/scheduler-kernel/automation-adapter.js +514 -18
- package/src/lib/scheduler-kernel/automation-event-adapter.js +123 -11
- package/src/lib/scheduler-kernel/contract.js +91 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +297 -4
- package/src/lib/scheduler-kernel/loop-adapter.js +547 -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 +400 -20
- package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
- package/src/lib/scheduler-kernel/runtime.js +237 -2
- package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
- package/src/lib/scheduler-kernel/store.js +3957 -248
- 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 +1282 -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/mcp-config.js +81 -10
- package/src/runtime/policies/agent-policy.js +4 -0
- package/src/workers/background-agent-worker.js +403 -96
- package/src/assets/web-panel/assets/MarkdownRenderer-aMtgN-R6.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-DKTf5xIP.js +0 -7
- 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
|
@@ -263,6 +263,11 @@ export function makeFallbackChatFn(opts = {}) {
|
|
|
263
263
|
try {
|
|
264
264
|
return await baseChatFn(messages, options);
|
|
265
265
|
} catch (firstErr) {
|
|
266
|
+
// A strict call-ledger boundary identifies exactly one provider/model
|
|
267
|
+
// transport. Retrying behind that boundary would either attribute the
|
|
268
|
+
// fallback's usage to the primary identity or lose the failed attempt's
|
|
269
|
+
// possible spend, so surface the primary error without another call.
|
|
270
|
+
if (options.strictUsageTelemetry === true) throw firstErr;
|
|
266
271
|
let err = firstErr;
|
|
267
272
|
let lastTried = options.model;
|
|
268
273
|
for (const candidate of models) {
|
|
@@ -74,7 +74,10 @@ import {
|
|
|
74
74
|
} from "../lib/mcp-call-ledger-store.js";
|
|
75
75
|
import { createMcpHostRecoveryRuntime } from "../lib/mcp-host-recovery-runtime.js";
|
|
76
76
|
import { readSessionHostResumeState } from "../lib/session-host-snapshot.js";
|
|
77
|
-
import {
|
|
77
|
+
import {
|
|
78
|
+
acquireSessionHostLease,
|
|
79
|
+
createSessionHostWriteDelegation,
|
|
80
|
+
} from "../lib/session-host-lease.js";
|
|
78
81
|
import { TurnBindingLog, createTurnBindingFeed } from "../lib/turn-binding.js";
|
|
79
82
|
import { TURN_BINDING_EVENT } from "../lib/turn-binding-store.js";
|
|
80
83
|
import { operationIdempotencyKey } from "../lib/idempotency.js";
|
|
@@ -122,6 +125,13 @@ export const _goalProcessDeps = {
|
|
|
122
125
|
run: goalBrokerRunner,
|
|
123
126
|
};
|
|
124
127
|
|
|
128
|
+
export const RUNTIME_LEDGER_PERSISTENCE_FAILURE_MESSAGE =
|
|
129
|
+
"CC_RUNTIME_USAGE_LEDGER_FAILED: runtime usage telemetry was not durably persisted";
|
|
130
|
+
|
|
131
|
+
export function resolveHeadlessMeteredSessionId(persist, sessionId) {
|
|
132
|
+
return persist && sessionId ? sessionId : null;
|
|
133
|
+
}
|
|
134
|
+
|
|
125
135
|
function runHeadlessGoalCommand(command, options = {}) {
|
|
126
136
|
return _goalProcessDeps.run(command, [], {
|
|
127
137
|
...options,
|
|
@@ -172,6 +182,14 @@ import {
|
|
|
172
182
|
createSessionPersistenceFailure,
|
|
173
183
|
projectSessionPersistenceFailure,
|
|
174
184
|
} from "../lib/session-persistence-failure.js";
|
|
185
|
+
import {
|
|
186
|
+
markRuntimeLedgerPersistenceError,
|
|
187
|
+
projectRuntimeTokenUsage,
|
|
188
|
+
projectRuntimeUsageBoundary,
|
|
189
|
+
runtimeUsageEventType,
|
|
190
|
+
runtimeToolCallId,
|
|
191
|
+
} from "../lib/runtime-usage-ledger.js";
|
|
192
|
+
import { runMeteredDirectModelCall } from "../lib/direct-model-usage.js";
|
|
175
193
|
|
|
176
194
|
/**
|
|
177
195
|
* Normalize a public --permission-mode spelling to the canonical internal mode.
|
|
@@ -289,14 +307,20 @@ export function parseToolList(value) {
|
|
|
289
307
|
* still REPLAYS prior history into context, but nothing new is written — the
|
|
290
308
|
* deterministic-CI shape ("read context, leave no trace").
|
|
291
309
|
*
|
|
292
|
-
* @param {object} options { resume, continueSession, sessionId, persistSession, ephemeral }
|
|
310
|
+
* @param {object} options { resume, continueSession, sessionId, persistSession, ephemeral, observabilityScope }
|
|
293
311
|
* @param {object} store { getLastSessionId } (injection seam)
|
|
294
312
|
* @param {string} fallbackId used when nothing is being resumed
|
|
295
313
|
* @returns {{ sessionId:string, resumeId:string|null, persist:boolean, wantLatest:boolean }}
|
|
296
314
|
*/
|
|
297
315
|
export function resolveHeadlessSession(options = {}, store = {}, fallbackId) {
|
|
298
|
-
const {
|
|
299
|
-
|
|
316
|
+
const {
|
|
317
|
+
resume,
|
|
318
|
+
continueSession,
|
|
319
|
+
sessionId,
|
|
320
|
+
persistSession,
|
|
321
|
+
ephemeral,
|
|
322
|
+
observabilityScope,
|
|
323
|
+
} = options;
|
|
300
324
|
const wantLatest = continueSession === true || resume === true;
|
|
301
325
|
let resumeId = null;
|
|
302
326
|
if (wantLatest) {
|
|
@@ -323,7 +347,10 @@ export function resolveHeadlessSession(options = {}, store = {}, fallbackId) {
|
|
|
323
347
|
const persist =
|
|
324
348
|
ephemeral === true
|
|
325
349
|
? false
|
|
326
|
-
: persistSession === true ||
|
|
350
|
+
: persistSession === true ||
|
|
351
|
+
resumeId != null ||
|
|
352
|
+
wantLatest ||
|
|
353
|
+
observabilityScope != null;
|
|
327
354
|
const id = resumeId || sessionId || fallbackId;
|
|
328
355
|
return { sessionId: id, resumeId, persist, wantLatest };
|
|
329
356
|
}
|
|
@@ -403,6 +430,11 @@ async function withHeadlessSessionHostLease(options, deps, task) {
|
|
|
403
430
|
"runAgentHeadless requires a non-empty prompt (use -p, a positional arg, or pipe stdin).",
|
|
404
431
|
);
|
|
405
432
|
}
|
|
433
|
+
if (options.observabilityScope != null && options.ephemeral === true) {
|
|
434
|
+
throw new Error(
|
|
435
|
+
"observability scope requires durable session persistence and cannot be combined with ephemeral mode",
|
|
436
|
+
);
|
|
437
|
+
}
|
|
406
438
|
const outputFormat = options.outputFormat || "text";
|
|
407
439
|
if (!VALID_OUTPUT_FORMATS.includes(outputFormat)) {
|
|
408
440
|
throw new Error(
|
|
@@ -657,6 +689,19 @@ async function runAgentHeadlessInWorkspace(
|
|
|
657
689
|
// but it does not opt into replaying the target's prior conversation.
|
|
658
690
|
const canonicalResume = resumeId ? canonicalAdmission : null;
|
|
659
691
|
|
|
692
|
+
if (options.observabilityScope != null && canonicalAdmission) {
|
|
693
|
+
const message =
|
|
694
|
+
"CC_OBSERVABILITY_SCOPE_IMMUTABLE: an existing session scope cannot be overwritten; create a new scoped session";
|
|
695
|
+
emitHeadlessError(message);
|
|
696
|
+
writeErr(`${message}\n`);
|
|
697
|
+
return {
|
|
698
|
+
exitCode: 1,
|
|
699
|
+
result: message,
|
|
700
|
+
isError: true,
|
|
701
|
+
sessionSnapshot: canonicalAdmission.snapshot,
|
|
702
|
+
};
|
|
703
|
+
}
|
|
704
|
+
|
|
660
705
|
// `let` (not const): a custom-command macro's `model:` frontmatter may
|
|
661
706
|
// override it below (when the user passed no explicit --model), mirroring
|
|
662
707
|
// `cc command run`.
|
|
@@ -898,6 +943,23 @@ async function runAgentHeadlessInWorkspace(
|
|
|
898
943
|
deps.verifySession ||
|
|
899
944
|
(hasInjectedSessionStore ? () => null : jsonlVerifySession),
|
|
900
945
|
};
|
|
946
|
+
if (options.observabilityScope != null) {
|
|
947
|
+
let existingSession;
|
|
948
|
+
try {
|
|
949
|
+
existingSession = store.sessionExists(sessionId);
|
|
950
|
+
} catch {
|
|
951
|
+
existingSession = null;
|
|
952
|
+
}
|
|
953
|
+
if (existingSession !== false) {
|
|
954
|
+
const message =
|
|
955
|
+
existingSession === true
|
|
956
|
+
? "CC_OBSERVABILITY_SCOPE_IMMUTABLE: an existing session scope cannot be overwritten; create a new scoped session"
|
|
957
|
+
: "CC_OBSERVABILITY_SCOPE_AUTHORITY_UNAVAILABLE: existing session authority could not be excluded";
|
|
958
|
+
emitHeadlessError(message);
|
|
959
|
+
writeErr(`${message}\n`);
|
|
960
|
+
return { exitCode: 1, result: message, isError: true };
|
|
961
|
+
}
|
|
962
|
+
}
|
|
901
963
|
// ── Headless `/config` directive (Claude-Code 2.1.181: /config in -p mode) ──
|
|
902
964
|
// A leading `/config …` prompt is a one-shot config get/set/show, not a task
|
|
903
965
|
// for the LLM — handled before bootstrap/session/model so it never spends a
|
|
@@ -1163,9 +1225,15 @@ async function runAgentHeadlessInWorkspace(
|
|
|
1163
1225
|
: null;
|
|
1164
1226
|
const _backgroundInteraction = _bgPhase.enabled
|
|
1165
1227
|
? deps.backgroundInteractionClient ||
|
|
1166
|
-
|
|
1228
|
+
(
|
|
1229
|
+
deps.createBackgroundInteractionClient ||
|
|
1230
|
+
createBackgroundInteractionClient
|
|
1231
|
+
)({
|
|
1167
1232
|
backgroundAgentId: process.env.CC_BACKGROUND_AGENT_ID,
|
|
1168
1233
|
sessionId,
|
|
1234
|
+
sessionHostWriteDelegation: sessionHostLease?.leaseId
|
|
1235
|
+
? createSessionHostWriteDelegation(sessionHostLease)
|
|
1236
|
+
: null,
|
|
1169
1237
|
// One headless invocation is one user turn even when its model/tool
|
|
1170
1238
|
// loop contains several internal iterations.
|
|
1171
1239
|
turnId: options.turnId || sideEffectRunNonce,
|
|
@@ -1650,6 +1718,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
1650
1718
|
title: prompt.slice(0, 60),
|
|
1651
1719
|
provider,
|
|
1652
1720
|
model,
|
|
1721
|
+
observabilityScope: options.observabilityScope,
|
|
1653
1722
|
});
|
|
1654
1723
|
}
|
|
1655
1724
|
// Persist the expanded content so a resumed session faithfully replays
|
|
@@ -2045,6 +2114,18 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2045
2114
|
};
|
|
2046
2115
|
persistContextSources();
|
|
2047
2116
|
|
|
2117
|
+
// Scoped call-ledger writes are safety boundaries, not best-effort
|
|
2118
|
+
// diagnostics. Normalize every persistence failure so the outer host aborts
|
|
2119
|
+
// this turn and cannot begin another paid model/tool call.
|
|
2120
|
+
const persistRuntimeLedgerWrite = (action) => {
|
|
2121
|
+
try {
|
|
2122
|
+
return action();
|
|
2123
|
+
} catch (error) {
|
|
2124
|
+
throw markRuntimeLedgerPersistenceError(error);
|
|
2125
|
+
}
|
|
2126
|
+
};
|
|
2127
|
+
|
|
2128
|
+
const childToolExecs = new Map();
|
|
2048
2129
|
const loopOptions = {
|
|
2049
2130
|
model,
|
|
2050
2131
|
provider,
|
|
@@ -2164,19 +2245,85 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2164
2245
|
onStreamRetry: (attempt, error, telemetry = {}) => {
|
|
2165
2246
|
writeErr(` ⟳ connection dropped — retrying (attempt ${attempt})…\n`);
|
|
2166
2247
|
if (persist) {
|
|
2167
|
-
|
|
2248
|
+
persistRuntimeLedgerWrite(() =>
|
|
2168
2249
|
store.appendLlmRetryCompact(sessionId, {
|
|
2169
2250
|
attempt,
|
|
2170
2251
|
durationMs: telemetry.durationMs,
|
|
2171
2252
|
provider: telemetry.provider || provider,
|
|
2172
2253
|
model: telemetry.model || model,
|
|
2173
2254
|
reason: classifyStreamRetryReason(error),
|
|
2174
|
-
})
|
|
2175
|
-
|
|
2176
|
-
/* usage telemetry is best-effort */
|
|
2177
|
-
}
|
|
2255
|
+
}),
|
|
2256
|
+
);
|
|
2178
2257
|
}
|
|
2179
2258
|
},
|
|
2259
|
+
onUsageBoundary: persist
|
|
2260
|
+
? (event) => {
|
|
2261
|
+
persistRuntimeLedgerWrite(() =>
|
|
2262
|
+
store.appendEvent(
|
|
2263
|
+
sessionId,
|
|
2264
|
+
runtimeUsageEventType("started"),
|
|
2265
|
+
projectRuntimeUsageBoundary(event, "started"),
|
|
2266
|
+
),
|
|
2267
|
+
);
|
|
2268
|
+
}
|
|
2269
|
+
: undefined,
|
|
2270
|
+
onUsageSettlement: persist
|
|
2271
|
+
? (event) => {
|
|
2272
|
+
if (event?.type === "token-usage") {
|
|
2273
|
+
persistRuntimeLedgerWrite(() =>
|
|
2274
|
+
store.appendTokenUsage(
|
|
2275
|
+
sessionId,
|
|
2276
|
+
projectRuntimeTokenUsage(event),
|
|
2277
|
+
),
|
|
2278
|
+
);
|
|
2279
|
+
return;
|
|
2280
|
+
}
|
|
2281
|
+
persistRuntimeLedgerWrite(() =>
|
|
2282
|
+
store.appendEvent(
|
|
2283
|
+
sessionId,
|
|
2284
|
+
runtimeUsageEventType("unknown"),
|
|
2285
|
+
projectRuntimeUsageBoundary(event, "unknown"),
|
|
2286
|
+
),
|
|
2287
|
+
);
|
|
2288
|
+
}
|
|
2289
|
+
: undefined,
|
|
2290
|
+
onToolCallBoundary: persist
|
|
2291
|
+
? (event) => {
|
|
2292
|
+
const id = runtimeToolCallId(event?.tool_use_id);
|
|
2293
|
+
childToolExecs.set(id, {
|
|
2294
|
+
tool: event?.tool || "?",
|
|
2295
|
+
startedAt: deps.now ? deps.now() : Date.now(),
|
|
2296
|
+
});
|
|
2297
|
+
persistRuntimeLedgerWrite(() =>
|
|
2298
|
+
store.appendEvent(sessionId, "tool_call_started", {
|
|
2299
|
+
id,
|
|
2300
|
+
tool: event?.tool || "?",
|
|
2301
|
+
}),
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
: undefined,
|
|
2305
|
+
onToolCallSettlement: persist
|
|
2306
|
+
? (event) => {
|
|
2307
|
+
const id = runtimeToolCallId(event?.tool_use_id);
|
|
2308
|
+
const started = childToolExecs.get(id);
|
|
2309
|
+
childToolExecs.delete(id);
|
|
2310
|
+
persistRuntimeLedgerWrite(() =>
|
|
2311
|
+
store.appendToolCallCompact(sessionId, {
|
|
2312
|
+
id,
|
|
2313
|
+
tool: event?.tool || started?.tool || "?",
|
|
2314
|
+
isError: Boolean(event?.error || event?.result?.error),
|
|
2315
|
+
skill: event?.attribution?.skill,
|
|
2316
|
+
durationMs: started
|
|
2317
|
+
? Math.max(
|
|
2318
|
+
0,
|
|
2319
|
+
(deps.now ? deps.now() : Date.now()) - started.startedAt,
|
|
2320
|
+
)
|
|
2321
|
+
: undefined,
|
|
2322
|
+
}),
|
|
2323
|
+
);
|
|
2324
|
+
}
|
|
2325
|
+
: undefined,
|
|
2326
|
+
strictUsageTelemetry: persist,
|
|
2180
2327
|
onStall: (ms, timeoutMs) => {
|
|
2181
2328
|
const silent = Math.round(ms / 1000);
|
|
2182
2329
|
const retryIn = timeoutMs > ms ? Math.round((timeoutMs - ms) / 1000) : 0;
|
|
@@ -2249,9 +2396,10 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2249
2396
|
const toolCalls = [];
|
|
2250
2397
|
// The core normally attaches a precise toolTelemetryRecord on success.
|
|
2251
2398
|
// Keep an event-boundary fallback for denials/early throws that settle
|
|
2252
|
-
// before that record is produced.
|
|
2253
|
-
//
|
|
2254
|
-
|
|
2399
|
+
// before that record is produced. Read-only batches can run concurrently,
|
|
2400
|
+
// so timestamps and result pairing are keyed by provider tool-call id.
|
|
2401
|
+
const activeToolCalls = new Map();
|
|
2402
|
+
const toolStartedAt = new Map();
|
|
2255
2403
|
// Policy denials (blocked tool calls) collected for an end-of-run summary,
|
|
2256
2404
|
// so a non-interactive run surfaces what got blocked the way the REPL's
|
|
2257
2405
|
// `/permissions denials` does (Claude-Code 2.1.193 denial reasons).
|
|
@@ -2263,15 +2411,10 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2263
2411
|
cache_read_input_tokens: 0,
|
|
2264
2412
|
cache_creation_input_tokens: 0,
|
|
2265
2413
|
};
|
|
2266
|
-
// 用量归因: attributed child-loop usage (spawn_sub_agent / isolated
|
|
2267
|
-
// run_skill). Kept OUT of the `usage` accumulator above so the result
|
|
2268
|
-
// envelope and the end-of-run aggregate token_usage event keep their
|
|
2269
|
-
// long-standing "main loop only" semantics — the attributed records are
|
|
2270
|
-
// persisted as their own token_usage events instead (no double count).
|
|
2271
|
-
const attributedUsage = [];
|
|
2272
2414
|
let finalText = "";
|
|
2273
2415
|
let endReason = "complete";
|
|
2274
2416
|
let stopForCost = false;
|
|
2417
|
+
let stopForCompactionUsageUnknown = false;
|
|
2275
2418
|
|
|
2276
2419
|
const emitStream = (obj) => {
|
|
2277
2420
|
if (isStream) writeOut(JSON.stringify(obj) + "\n");
|
|
@@ -2388,12 +2531,22 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2388
2531
|
`Condition: ${cond.text || cond.source}\n\n` +
|
|
2389
2532
|
`Latest assistant output:\n${String(transcript.finalText || "").slice(0, 2000)}\n\n` +
|
|
2390
2533
|
`Reply with STRICT JSON only: {"met": true|false, "reason": "<short>"}.`;
|
|
2391
|
-
const r = await
|
|
2392
|
-
|
|
2534
|
+
const r = await runMeteredDirectModelCall({
|
|
2535
|
+
sessionId: resolveHeadlessMeteredSessionId(persist, sessionId),
|
|
2536
|
+
persist: persist
|
|
2537
|
+
? (type, data) => store.appendEvent(sessionId, type, data)
|
|
2538
|
+
: null,
|
|
2393
2539
|
provider,
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2540
|
+
model,
|
|
2541
|
+
source: "model",
|
|
2542
|
+
call: () =>
|
|
2543
|
+
chatWithTools([{ role: "user", content: judgePrompt }], {
|
|
2544
|
+
model,
|
|
2545
|
+
provider,
|
|
2546
|
+
baseUrl,
|
|
2547
|
+
apiKey,
|
|
2548
|
+
enabledToolNames: [],
|
|
2549
|
+
}),
|
|
2397
2550
|
});
|
|
2398
2551
|
const text = r?.message?.content || "";
|
|
2399
2552
|
let met = false;
|
|
@@ -2557,7 +2710,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2557
2710
|
break;
|
|
2558
2711
|
}
|
|
2559
2712
|
case "tool-executing": {
|
|
2560
|
-
|
|
2713
|
+
const telemetryToolId = runtimeToolCallId(event.tool_use_id);
|
|
2561
2714
|
const line = ` [${event.tool}] ${formatToolArgs(event.tool, event.args)}`;
|
|
2562
2715
|
if (isText) writeErr(line + "\n");
|
|
2563
2716
|
emitStream({
|
|
@@ -2566,11 +2719,27 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2566
2719
|
tool: event.tool,
|
|
2567
2720
|
args: event.args,
|
|
2568
2721
|
});
|
|
2569
|
-
|
|
2570
|
-
|
|
2722
|
+
const toolCall = {
|
|
2723
|
+
id: telemetryToolId,
|
|
2571
2724
|
tool: event.tool,
|
|
2572
2725
|
args: event.args,
|
|
2573
|
-
}
|
|
2726
|
+
};
|
|
2727
|
+
toolCalls.push(toolCall);
|
|
2728
|
+
toolStartedAt.set(
|
|
2729
|
+
telemetryToolId,
|
|
2730
|
+
deps.now ? deps.now() : Date.now(),
|
|
2731
|
+
);
|
|
2732
|
+
if (event.tool_use_id) {
|
|
2733
|
+
activeToolCalls.set(event.tool_use_id, toolCall);
|
|
2734
|
+
}
|
|
2735
|
+
if (persist) {
|
|
2736
|
+
persistRuntimeLedgerWrite(() =>
|
|
2737
|
+
store.appendEvent(sessionId, "tool_call_started", {
|
|
2738
|
+
id: telemetryToolId,
|
|
2739
|
+
tool: event.tool,
|
|
2740
|
+
}),
|
|
2741
|
+
);
|
|
2742
|
+
}
|
|
2574
2743
|
// P0-2: record an irreversible effect as STARTED (persisted before
|
|
2575
2744
|
// it settles) so a crash before the matching tool-result leaves a
|
|
2576
2745
|
// reconcilable "in flight" marker instead of a silent replay.
|
|
@@ -2647,35 +2816,66 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2647
2816
|
? { permission_decision: event.permission_decision }
|
|
2648
2817
|
: {}),
|
|
2649
2818
|
});
|
|
2650
|
-
|
|
2651
|
-
|
|
2819
|
+
const settledCall =
|
|
2820
|
+
(event.tool_use_id
|
|
2821
|
+
? activeToolCalls.get(event.tool_use_id)
|
|
2822
|
+
: null) ||
|
|
2823
|
+
[...toolCalls]
|
|
2824
|
+
.reverse()
|
|
2825
|
+
.find(
|
|
2826
|
+
(call) =>
|
|
2827
|
+
!call._runtimeSettled &&
|
|
2828
|
+
(!event.tool || call.tool === event.tool),
|
|
2829
|
+
) ||
|
|
2830
|
+
null;
|
|
2831
|
+
if (settledCall) {
|
|
2652
2832
|
settledCall.is_error = Boolean(err);
|
|
2653
2833
|
settledCall.durationMs =
|
|
2654
2834
|
event.result?.toolTelemetryRecord?.durationMs ??
|
|
2655
|
-
(
|
|
2835
|
+
(toolStartedAt.get(settledCall.id) === undefined
|
|
2656
2836
|
? undefined
|
|
2657
2837
|
: Math.max(
|
|
2658
2838
|
0,
|
|
2659
2839
|
(deps.now ? deps.now() : Date.now()) -
|
|
2660
|
-
|
|
2840
|
+
toolStartedAt.get(settledCall.id),
|
|
2661
2841
|
));
|
|
2662
2842
|
Object.assign(
|
|
2663
2843
|
settledCall,
|
|
2664
2844
|
extractPluginUsageAttribution(event.result),
|
|
2665
2845
|
);
|
|
2846
|
+
Object.defineProperty(settledCall, "_runtimeSettled", {
|
|
2847
|
+
configurable: true,
|
|
2848
|
+
value: true,
|
|
2849
|
+
});
|
|
2850
|
+
toolStartedAt.delete(settledCall.id);
|
|
2851
|
+
if (event.tool_use_id) activeToolCalls.delete(event.tool_use_id);
|
|
2852
|
+
}
|
|
2853
|
+
if (persist && settledCall) {
|
|
2854
|
+
persistRuntimeLedgerWrite(() =>
|
|
2855
|
+
store.appendToolCallCompact(sessionId, {
|
|
2856
|
+
id: settledCall.id || `tool-${toolCalls.length}`,
|
|
2857
|
+
tool: settledCall.tool,
|
|
2858
|
+
isError: Boolean(settledCall.is_error),
|
|
2859
|
+
skill:
|
|
2860
|
+
settledCall.tool === "run_skill"
|
|
2861
|
+
? settledCall.args?.skill_name || null
|
|
2862
|
+
: undefined,
|
|
2863
|
+
plugin: settledCall.plugin || undefined,
|
|
2864
|
+
pluginVersion: settledCall.pluginVersion || undefined,
|
|
2865
|
+
durationMs: settledCall.durationMs,
|
|
2866
|
+
}),
|
|
2867
|
+
);
|
|
2666
2868
|
}
|
|
2667
|
-
currentToolStartedAt = null;
|
|
2668
2869
|
// Track policy denials (not plain tool failures) for the end-of-run
|
|
2669
2870
|
// summary. The preceding tool-executing pushed the args.
|
|
2670
2871
|
if (err) {
|
|
2671
|
-
const last = toolCalls[toolCalls.length - 1];
|
|
2672
2872
|
const denial = classifyDenial({
|
|
2673
2873
|
tool: event.tool,
|
|
2674
2874
|
result: event.result,
|
|
2675
2875
|
error: event.error,
|
|
2676
2876
|
argsSummary:
|
|
2677
|
-
|
|
2678
|
-
? formatToolArgs(event.tool,
|
|
2877
|
+
settledCall && settledCall.tool === event.tool
|
|
2878
|
+
? formatToolArgs(event.tool, settledCall.args)
|
|
2679
2879
|
: "",
|
|
2680
2880
|
});
|
|
2681
2881
|
if (denial) {
|
|
@@ -2704,19 +2904,51 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2704
2904
|
emitStream({ ...event, reason });
|
|
2705
2905
|
break;
|
|
2706
2906
|
}
|
|
2707
|
-
case "
|
|
2708
|
-
if (event.
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2907
|
+
case "model-usage-started": {
|
|
2908
|
+
if (persist && event.ledgerPersisted !== true) {
|
|
2909
|
+
persistRuntimeLedgerWrite(() =>
|
|
2910
|
+
store.appendEvent(
|
|
2911
|
+
sessionId,
|
|
2912
|
+
runtimeUsageEventType("started"),
|
|
2913
|
+
projectRuntimeUsageBoundary(event, "started"),
|
|
2914
|
+
),
|
|
2915
|
+
);
|
|
2916
|
+
}
|
|
2917
|
+
break;
|
|
2918
|
+
}
|
|
2919
|
+
case "model-usage-unknown":
|
|
2920
|
+
case "compaction-usage-unknown": {
|
|
2921
|
+
if (persist && event.ledgerPersisted !== true) {
|
|
2922
|
+
persistRuntimeLedgerWrite(() =>
|
|
2923
|
+
store.appendEvent(
|
|
2924
|
+
sessionId,
|
|
2925
|
+
runtimeUsageEventType("unknown"),
|
|
2926
|
+
projectRuntimeUsageBoundary(event, "unknown"),
|
|
2927
|
+
),
|
|
2928
|
+
);
|
|
2929
|
+
}
|
|
2930
|
+
if (event.type === "compaction-usage-unknown") {
|
|
2931
|
+
endReason = "compaction-usage-unknown";
|
|
2932
|
+
stopForCompactionUsageUnknown = true;
|
|
2933
|
+
emitStream({
|
|
2934
|
+
type: "compaction_usage_unknown",
|
|
2935
|
+
provider: event.provider,
|
|
2936
|
+
model: event.model,
|
|
2937
|
+
source: event.source || "semantic-compaction",
|
|
2938
|
+
reason: event.reason || "provider_transport_outcome_unknown",
|
|
2939
|
+
usage_outcome: "unknown",
|
|
2718
2940
|
});
|
|
2719
|
-
}
|
|
2941
|
+
}
|
|
2942
|
+
break;
|
|
2943
|
+
}
|
|
2944
|
+
case "token-usage": {
|
|
2945
|
+
const persistedUsage = projectRuntimeTokenUsage(event);
|
|
2946
|
+
if (persist && event.ledgerPersisted !== true) {
|
|
2947
|
+
persistRuntimeLedgerWrite(() =>
|
|
2948
|
+
store.appendTokenUsage(sessionId, persistedUsage),
|
|
2949
|
+
);
|
|
2950
|
+
}
|
|
2951
|
+
if (!event.attribution) {
|
|
2720
2952
|
usage.input_tokens += event.usage?.input_tokens || 0;
|
|
2721
2953
|
usage.output_tokens += event.usage?.output_tokens || 0;
|
|
2722
2954
|
// Carry prompt-cache tokens into accumulated usage (cost accuracy).
|
|
@@ -2808,7 +3040,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2808
3040
|
await deps.outputFlow?.wait?.();
|
|
2809
3041
|
// Hard cost cap reached: stop consuming the loop so no further paid LLM
|
|
2810
3042
|
// call is made (break out of the for-await, not just the switch).
|
|
2811
|
-
if (stopForCost) break;
|
|
3043
|
+
if (stopForCost || stopForCompactionUsageUnknown) break;
|
|
2812
3044
|
}
|
|
2813
3045
|
// P1 turn→checkpoint binding: the turn settled — persist the explicit
|
|
2814
3046
|
// table (latest snapshot wins on load; no-op when nothing was recorded).
|
|
@@ -2918,6 +3150,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2918
3150
|
});
|
|
2919
3151
|
}
|
|
2920
3152
|
} catch (err) {
|
|
3153
|
+
if (err?.runtimeLedgerPersistence === true) throw err;
|
|
2921
3154
|
evaluation = {
|
|
2922
3155
|
met: false,
|
|
2923
3156
|
reason: `goal check failed: ${err.message}`,
|
|
@@ -2966,11 +3199,18 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2966
3199
|
break;
|
|
2967
3200
|
}
|
|
2968
3201
|
} catch (err) {
|
|
2969
|
-
const
|
|
3202
|
+
const runtimeLedgerPersistenceFailed =
|
|
3203
|
+
err?.runtimeLedgerPersistence === true;
|
|
3204
|
+
const message = runtimeLedgerPersistenceFailed
|
|
3205
|
+
? RUNTIME_LEDGER_PERSISTENCE_FAILURE_MESSAGE
|
|
3206
|
+
: err?.message || String(err);
|
|
3207
|
+
const errorSubtype = runtimeLedgerPersistenceFailed
|
|
3208
|
+
? "error_persistence"
|
|
3209
|
+
: "error";
|
|
2970
3210
|
if (isStream) {
|
|
2971
3211
|
emitStream({
|
|
2972
3212
|
type: "result",
|
|
2973
|
-
subtype:
|
|
3213
|
+
subtype: errorSubtype,
|
|
2974
3214
|
is_error: true,
|
|
2975
3215
|
error: message,
|
|
2976
3216
|
});
|
|
@@ -2978,7 +3218,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2978
3218
|
writeOut(
|
|
2979
3219
|
JSON.stringify(
|
|
2980
3220
|
buildResultEnvelope({
|
|
2981
|
-
subtype:
|
|
3221
|
+
subtype: errorSubtype,
|
|
2982
3222
|
isError: true,
|
|
2983
3223
|
result: message,
|
|
2984
3224
|
sessionId,
|
|
@@ -2997,7 +3237,7 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2997
3237
|
// Provider/transport failures get their own exit code (5) so CI can tell
|
|
2998
3238
|
// "the model call failed" from "the run itself errored" (1).
|
|
2999
3239
|
loopFailureOutcome = {
|
|
3000
|
-
exitCode: classifyLoopError(err),
|
|
3240
|
+
exitCode: runtimeLedgerPersistenceFailed ? 1 : classifyLoopError(err),
|
|
3001
3241
|
result: message,
|
|
3002
3242
|
isError: true,
|
|
3003
3243
|
};
|
|
@@ -3184,26 +3424,6 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3184
3424
|
if (persist && !isError) {
|
|
3185
3425
|
try {
|
|
3186
3426
|
if (finalText) store.appendAssistantMessage(sessionId, finalText);
|
|
3187
|
-
// 用量归因: compact per-tool records (name + error flag + skill hint —
|
|
3188
|
-
// never args) so `cc session usage --by tool|mcp` can aggregate
|
|
3189
|
-
// headless sessions too.
|
|
3190
|
-
for (const tc of toolCalls) {
|
|
3191
|
-
store.appendToolCallCompact(sessionId, {
|
|
3192
|
-
tool: tc.tool,
|
|
3193
|
-
isError: Boolean(tc.is_error),
|
|
3194
|
-
skill:
|
|
3195
|
-
tc.tool === "run_skill" ? tc.args?.skill_name || null : undefined,
|
|
3196
|
-
plugin: tc.plugin || undefined,
|
|
3197
|
-
pluginVersion: tc.pluginVersion || undefined,
|
|
3198
|
-
durationMs: tc.durationMs,
|
|
3199
|
-
});
|
|
3200
|
-
}
|
|
3201
|
-
// Attributed child-loop usage first (chronology: it happened during
|
|
3202
|
-
// the run), then the unchanged main-loop aggregate.
|
|
3203
|
-
for (const au of attributedUsage) {
|
|
3204
|
-
store.appendTokenUsage(sessionId, au);
|
|
3205
|
-
}
|
|
3206
|
-
store.appendTokenUsage(sessionId, usage);
|
|
3207
3427
|
} catch (error) {
|
|
3208
3428
|
const persistenceError = createSessionPersistenceFailure(error, {
|
|
3209
3429
|
sessionId,
|
|
@@ -3233,8 +3453,9 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3233
3453
|
|
|
3234
3454
|
// Run-end goal self-assessment (cc goal Phase 2, opt-in via --goal-assess).
|
|
3235
3455
|
// Spends one extra completion to judge whether the run advanced the bound
|
|
3236
|
-
// goal, then persists progress / key-result / drift updates.
|
|
3237
|
-
//
|
|
3456
|
+
// goal, then persists progress / key-result / drift updates. Ordinary
|
|
3457
|
+
// assessment failures are best-effort; a usage-ledger durability failure is
|
|
3458
|
+
// terminal because reporting the extra paid call as successful is unsafe.
|
|
3238
3459
|
if (options.goalAssess && boundGoalId && !isError) {
|
|
3239
3460
|
try {
|
|
3240
3461
|
const { getGoal } = await import("../lib/goal-store.js");
|
|
@@ -3246,10 +3467,23 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3246
3467
|
deps.assessChat ||
|
|
3247
3468
|
(async (assessPrompt) => {
|
|
3248
3469
|
const { chatWithTools } = await import("./agent-core.js");
|
|
3249
|
-
const r = await
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3470
|
+
const r = await runMeteredDirectModelCall({
|
|
3471
|
+
sessionId: resolveHeadlessMeteredSessionId(persist, sessionId),
|
|
3472
|
+
persist: persist
|
|
3473
|
+
? (type, data) => store.appendEvent(sessionId, type, data)
|
|
3474
|
+
: null,
|
|
3475
|
+
provider,
|
|
3476
|
+
model,
|
|
3477
|
+
source: "model",
|
|
3478
|
+
call: () =>
|
|
3479
|
+
chatWithTools([{ role: "user", content: assessPrompt }], {
|
|
3480
|
+
model,
|
|
3481
|
+
provider,
|
|
3482
|
+
baseUrl,
|
|
3483
|
+
apiKey,
|
|
3484
|
+
enabledToolNames: [],
|
|
3485
|
+
}),
|
|
3486
|
+
});
|
|
3253
3487
|
return r?.message?.content || "";
|
|
3254
3488
|
});
|
|
3255
3489
|
const { assessment } = await doAssess({
|
|
@@ -3276,8 +3510,16 @@ async function runAgentHeadlessInWorkspace(
|
|
|
3276
3510
|
});
|
|
3277
3511
|
}
|
|
3278
3512
|
}
|
|
3279
|
-
} catch {
|
|
3280
|
-
|
|
3513
|
+
} catch (error) {
|
|
3514
|
+
if (error?.runtimeLedgerPersistence === true) {
|
|
3515
|
+
isError = true;
|
|
3516
|
+
subtype = "error_persistence";
|
|
3517
|
+
finalText = RUNTIME_LEDGER_PERSISTENCE_FAILURE_MESSAGE;
|
|
3518
|
+
if (isText) {
|
|
3519
|
+
writeErr(`${RUNTIME_LEDGER_PERSISTENCE_FAILURE_MESSAGE}\n`);
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
// Non-ledger assessment failures remain best-effort.
|
|
3281
3523
|
}
|
|
3282
3524
|
}
|
|
3283
3525
|
|