chainlesschain 0.163.6 → 0.163.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DDIUofA8.js → AIOps-axqQfwv8.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-Bm-5xYRn.js → ActionButton-DV-Ro0By.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D5UH4ljI.js → Analytics-Bt72WEVu.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-D_ifjOOP.js → AppLayout-BtepG55E.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-BY1mXdC7.js → Artifacts-B7KaJ7S_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Bujr4Ml3.js → Audit-FNFaUg7A.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-sioKSTcC.js → BackgroundAgents-DFb6J2wQ.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DDOAK8RK.js → Backup-CC7YBhyj.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CtCsVVke.js → BaseInput-RkgTNVtj.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DpNj0vnd.js → Chat-hHEmGZy-.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZta3Ftr.js → ChatBubbleRenderer-CAP9YhHv.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-DoHVNSXq.js → Checkbox-z5wXOQP1.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DlVl7Qmv.js → Codegen-DVaDJnxy.js} +1 -1
- package/src/assets/web-panel/assets/{Col-GIqoPYty.js → Col-CJmaRDR5.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CIAPEVji.js → Community-DF29_2bI.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BN7JiI_h.js → Compact-DtkQkBzn.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CqUWCM9B.js → Compliance-xoHDxp7I.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-A4iPp7A4.js → Cowork-BUm-R7ht.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-B2zeXXWb.js → Cron-Cgl14ZkB.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BR2xmWr8.js → Crosschain-BNcbmoqh.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BzFDjrIv.js → DID-Bwja0Zo9.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DKtDo3yA.js → Dashboard-Bk5XjEdJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-RNx43_YG.js → Dropdown-Ci36Oitq.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-SwMt4Rcy.js → EmailListRenderer--U04ZN4q.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CsYebZ4X.js → FamilyGuardDashboard-B2gNPR2s.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BmRKvBTy.js → Federation-C4KghYn7.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CVxGTA-0.js → FormItemContext-QL7x_Q_0.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-x2iXpyB7.js → GenericCardRenderer-F3Ryltwm.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DfqbkiOP.js → Git-2HassK5k.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-RuHyyj5O.js → Governance-DoBIp7oe.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Bn7uZ7rI.js → Inference--W01QhZ-.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DlP7XefZ.js → KnowledgeGraph-DmvwqGpT.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BYNdOiCd.js → Logs-BBJ4yAel.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-aMtgN-R6.js → MarkdownRenderer-BLCZMzhJ.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-JQYmDqM8.js → Marketplace-D5lNngSI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Cyx4yZ-9.js → McpTools-CkEVOMKH.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-VDuGZTN2.js → Memory-B1Ow1xVE.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-_yKo97gi.js → MobileBridge-SgYbUfb6.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CXRXW3q7.js → MobileProjects-BWdOvQAj.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-acTGtfLH.js → Mtc-DcTXSSma.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-ClpjXfkY.js → MtcAudit-Dt3WG4oj.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-_6Tn3o96.js → Multisig-B9B38UZx.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CK7pbZzP.js → NLProgramming-B0S4GGvG.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Czy6V_P8.js → Notes-DZ5U58Ng.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-Cqx-UVv3.js → NotificationSettings-PjL5ZW34.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C69WDxGy.js → OrderTableRenderer-DrAX2ESt.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-DFnA9vLQ.js → Organization-Cv1GYs-c.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-ReZkk2yT.js → Overflow-Bbkp_PL3.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DzjSI0aI.js → P2P-BD8QUgoZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DKTf5xIP.js → PdhVaultBrowser-BO-2PeaB.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DhQ5klhR.js → Permissions-D_OPVa02.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CUL1iHrW.js → PersonalDataHub-mh-pEmaB.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-DU88iu4N.js → Pipeline-6JC2EDdb.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Bw-sYfyK.js → Privacy-CUshzUAG.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Bq3Q5y0z.js → ProjectInit-Cs2Aalri.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C8spzpho.js → ProjectSettings-1ak49tcj.js} +2 -2
- package/src/assets/web-panel/assets/Projects-BV4oApsm.js +1 -0
- package/src/assets/web-panel/assets/{Providers-Bf4eTP9W.js → Providers-CXXxvafH.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Dme9BDU1.js → QrScannerModal-PTcDsF58.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CIXfv1rE.js → QuickAsk-CDwucrJw.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CIxvdeZ-.js → Recommend-CJlLVRXR.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-C6k7MExI.js → RemoteSession-DlN-ETsO.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CISDz2bl.js → Reputation-DI23LR6m.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CdnDxXyf.js → Row-Cl7UQMrM.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C-QpRHsl.js → RssFeed-CexHNfh8.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DBjaGzSn.js → Search-BneBWvRN.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CQKukOeE.js → Security-DX7Phgrp.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DZz86jWb.js → Services-BWXO8Mte.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-jb8RMK0d.js → Skeleton-DCyOjKPJ.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CdY76fZG.js → Skills-CXqERsTB.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-C_CSiZX9.js → Sla-bhbrbz8E.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-3IPU0HBZ.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-qvimGO0O.js → SyncSettings-DBNTQLbM.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Dng5LPJC.js → Tasks-quP0bkN-.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Bwqq5Wll.js → Templates-BouWmgho.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DNWuwP7Z.js → Tenant-qv0D9s7z.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B-6Othpp.js → Terminal-BxvbE8BB.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DKpKZfzx.js → TimelineRenderer-D-IeLnJ2.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DzfGMd2J.js → Tokens-CFMKKyVG.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BXwUi74J.js → Trigger-L8as3UuJ.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BNzUq4ui.js → Trust-MxmA4VZG.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BYugxww4.js → UkeySign-C0VvJYRi.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DdauhtSJ.js → VideoEditing-Bf5QZj8N.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CSC9bCe_.js → Wallet-BIJ9riRz.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Q8AN3bTO.js → WebAuthn-B8p9Mhkw.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-d-LBGCuA.js → WorkflowEditor-BVsuaPen.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BLVDCgsZ.js → chat-BfkjoKpV.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BZlPSEHl.js → colors-DeAlsWK8.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-IWseP6R6.js → compact-item-Cs97bz5j.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DnVRV3Ao.js → createContext-BqbG60LH.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DLQZA_Wn.js → hasIn-i_RY0b1X.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_N4-Gq9.js → index-0-agYlWL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DB0MJgF_.js → index-79V_zv1s.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOZJBTWZ.js → index-B-3tEpTc.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUq0c7gq.js → index-B-JVTrpr.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dy0R5ZED.js → index-B1CbOH1i.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bxp7uDD8.js → index-B5UkyA3c.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpVrK6fr.js → index-BESLFt4q.js} +1 -1
- package/src/assets/web-panel/assets/{index-CT9vVN-X.js → index-BOVkf1K3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DOoQpuQY.js → index-BYUVuwKt.js} +1 -1
- package/src/assets/web-panel/assets/{index-CINJQEj6.js → index-BcUXAB2s.js} +1 -1
- package/src/assets/web-panel/assets/{index-CarMTIyQ.js → index-BkBi5TmC.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5dgnilC.js → index-Bm7lLR4c.js} +1 -1
- package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +1 -0
- package/src/assets/web-panel/assets/{index-CbQNL0ue.js → index-BuLQobzW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpBaJ3TD.js → index-CE2VtTlp.js} +1 -1
- package/src/assets/web-panel/assets/{index-jWb70ZgZ.js → index-CED2PL_y.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEu2lMBy.js → index-CG3PRyAL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DocEhinm.js → index-CIG8fQ2_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_LQodeJ.js → index-COdGA-8n.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZpYeqrh.js → index-CeWoNHau.js} +1 -1
- package/src/assets/web-panel/assets/{index-gt8bNefW.js → index-Cf3WCLmy.js} +1 -1
- package/src/assets/web-panel/assets/{index-N_GoWZX4.js → index-CgsqdnRV.js} +1 -1
- package/src/assets/web-panel/assets/index-ChVT0p9u.js +1 -0
- package/src/assets/web-panel/assets/{index-CZDekj7T.js → index-D2B4VPyP.js} +1 -1
- package/src/assets/web-panel/assets/{index-YSw_gxlZ.js → index-D9evtvg2.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTbxp4UH.js → index-DUUrv141.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bbj2NS_I.js → index-DiSkx4UB.js} +3 -3
- package/src/assets/web-panel/assets/{index-BZs5bBnk.js → index-Dk2qouAz.js} +1 -1
- package/src/assets/web-panel/assets/{index-DalA0TKC.js → index-Dk7-v4hP.js} +1 -1
- package/src/assets/web-panel/assets/{index-1jeAudHd.js → index-DmbfhJUP.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1ifZtXo.js → index-DqBgBpgp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhA3QEni.js → index-PT_5sBMA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BSjilZ9L.js → index-U4f5izHz.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2FqfMvU.js → index-YXgLng0K.js} +1 -1
- package/src/assets/web-panel/assets/{index-COev0W2g.js → index-ZxO_-E8a.js} +1 -1
- package/src/assets/web-panel/assets/{index-M7wxfAbm.js → index-dIHr4B_u.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjWnONdy.js → index-gyFpvL7l.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dkwsi1Kn.js → index-s1opAL-M.js} +1 -1
- package/src/assets/web-panel/assets/{index-hwVDeoC0.js → index-yObj1O4n.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Co67Kqmb.js → initDefaultProps-C9h9yKL3.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BMOxQSF_.js → motion-BvmLsPdu.js} +1 -1
- package/src/assets/web-panel/assets/{move-C5fWDw-N.js → move-CoL4ekU1.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BJevpL0e.js → mtc-parser-C4pMy6xV.js} +1 -1
- package/src/assets/web-panel/assets/{omit-BCzNU8s6.js → omit-DPuJfNxx.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CybWvDPk.js → pickAttrs-D0KEeaK2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BMWS9HnW.js → placementArrow-BpkyINxt.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BoL2UnGY.js → responsiveObserve-DQI_wOq8.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DWNfXraU.js → slide-DYfdDiRg.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-BquTM3tX.js → statusUtils-B5dtvb0D.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BEkCleim.js → styleChecker-CF310mSj.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Oecnq7EA.js → useFlexGapSupport-D1Qp4BLp.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CkDffJ4F.js → useFs-C7_iyvJK.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-qbvKXesB.js → usePersonalDataHub-DZUt_fIm.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C6v8n6mA.js → vnode-D3dsi0lZ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-4CTeFILV.js → zoom-WdbOlvdQ.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +2 -2
- package/src/commands/agent.js +90 -1
- package/src/commands/chat.js +11 -2
- package/src/commands/compact.js +106 -23
- package/src/commands/loop.js +28 -10
- package/src/commands/routine.js +1 -1
- package/src/commands/scheduler-daemon.js +359 -2
- package/src/commands/session-observability.js +305 -0
- package/src/commands/session.js +38 -0
- package/src/data/changelog.json +14 -1
- package/src/gateways/ws/ws-agent-handler.js +439 -5
- package/src/harness/jsonl-session-store.js +463 -125
- package/src/harness/prompt-compressor.js +86 -13
- package/src/harness/provider-backed-compaction.js +100 -27
- package/src/lib/advisor-runtime.js +3 -1
- package/src/lib/agent-schedule-store.js +414 -4
- package/src/lib/agent-team/team-adjudication.js +40 -1
- package/src/lib/automation-engine.js +494 -0
- package/src/lib/background-agent-supervisor.js +793 -215
- package/src/lib/background-command-argv.js +24 -0
- package/src/lib/background-interaction-journal.js +361 -52
- package/src/lib/background-interaction-resolver.js +32 -0
- package/src/lib/background-launch-profile.js +2 -0
- package/src/lib/causal-observability.js +2661 -0
- package/src/lib/chat-session-admission.js +76 -0
- package/src/lib/cost-budget.js +5 -7
- package/src/lib/cowork/ab-comparator-cli.js +11 -0
- package/src/lib/cowork/debate-review-cli.js +12 -0
- package/src/lib/cowork-adapter.js +159 -38
- package/src/lib/cowork-cron.js +357 -1
- package/src/lib/cowork-task-runner.js +112 -17
- package/src/lib/delivery-coordinator.js +142 -0
- package/src/lib/direct-model-usage.js +121 -0
- package/src/lib/file-lines.js +183 -47
- package/src/lib/llm-pricing.js +12 -17
- package/src/lib/loop.js +26 -2
- package/src/lib/routine-store.js +380 -21
- package/src/lib/runtime-usage-ledger.js +182 -0
- package/src/lib/scheduler-kernel/agenda-adapter.js +308 -3
- package/src/lib/scheduler-kernel/automation-adapter.js +410 -8
- package/src/lib/scheduler-kernel/automation-event-adapter.js +36 -0
- package/src/lib/scheduler-kernel/cowork-cron-adapter.js +285 -3
- package/src/lib/scheduler-kernel/loop-adapter.js +541 -6
- package/src/lib/scheduler-kernel/migration-admin.js +346 -0
- package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
- package/src/lib/scheduler-kernel/routine-adapter.js +394 -20
- package/src/lib/scheduler-kernel/runtime.js +63 -1
- package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
- package/src/lib/scheduler-kernel/store.js +2586 -85
- package/src/lib/session-host-lease.js +171 -2
- package/src/lib/session-host-snapshot.js +14 -3
- package/src/lib/session-persistence-failure.js +1 -0
- package/src/lib/session-tail.js +179 -34
- package/src/lib/session-transcript-structure.js +96 -0
- package/src/lib/sub-agent-context.js +328 -22
- package/src/lib/ws-agent-handler.js +4 -1
- package/src/repl/agent-repl.js +732 -91
- package/src/repl/chat-repl.js +5 -1
- package/src/runtime/agent-core.js +1272 -207
- package/src/runtime/fallback-model.js +5 -0
- package/src/runtime/headless-runner.js +324 -82
- package/src/runtime/headless-stream.js +232 -26
- package/src/runtime/policies/agent-policy.js +4 -0
- package/src/workers/background-agent-worker.js +403 -96
- package/src/assets/web-panel/assets/Projects-Dd-xuPIc.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-C7tT9iad.js +0 -1
- package/src/assets/web-panel/assets/devWarning-Jzu62CLC.js +0 -1
- package/src/assets/web-panel/assets/index-Zb2MeDSy.js +0 -1
- package/src/assets/web-panel/assets/index-fikqml4k.js +0 -1
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* adapter.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { randomUUID } from "node:crypto";
|
|
14
15
|
import { agentLoop, formatToolArgs } from "../../runtime/agent-core.js";
|
|
15
16
|
import { classifyToolSideEffect } from "../../lib/side-effect-ledger.js";
|
|
16
17
|
import { DiffReviewFollowUpTracker } from "../../lib/diff-review-follow-up.js";
|
|
@@ -37,12 +38,25 @@ import { createMcpHostRecoveryRuntime } from "../../lib/mcp-host-recovery-runtim
|
|
|
37
38
|
import { compactConversationWithProvider } from "../../harness/provider-backed-compaction.js";
|
|
38
39
|
import { projectCanonicalResumeMessages } from "../../lib/session-message-provenance.js";
|
|
39
40
|
import { feature } from "../../lib/feature-flags.js";
|
|
41
|
+
import { classifyStreamRetryReason } from "../../lib/stream-retry.js";
|
|
42
|
+
import {
|
|
43
|
+
markRuntimeLedgerPersistenceError,
|
|
44
|
+
projectRuntimeTokenUsage,
|
|
45
|
+
projectRuntimeUsageBoundary,
|
|
46
|
+
runtimeToolCallId,
|
|
47
|
+
runtimeUsageEventType,
|
|
48
|
+
} from "../../lib/runtime-usage-ledger.js";
|
|
40
49
|
import {
|
|
41
50
|
appendCompactEventIfMessagesMatch,
|
|
51
|
+
appendEvent,
|
|
52
|
+
appendLlmRetryCompact,
|
|
53
|
+
appendTokenUsage,
|
|
54
|
+
appendToolCallCompact,
|
|
42
55
|
claimWsTurnIfHead,
|
|
43
56
|
computeWsTurnInputDigest,
|
|
44
57
|
createWsTurnClaimId,
|
|
45
58
|
normalizeWsTurnRequestId,
|
|
59
|
+
readVerifiedProjection,
|
|
46
60
|
readVerifiedWsTurnState,
|
|
47
61
|
readVerifiedMessages,
|
|
48
62
|
settleWsTurnClaim,
|
|
@@ -50,6 +64,59 @@ import {
|
|
|
50
64
|
|
|
51
65
|
const CANONICAL_WS_TURN_QUEUES = new Map();
|
|
52
66
|
const CANONICAL_WS_CLAIM_CAS_ATTEMPTS = 4;
|
|
67
|
+
const CALL_LEDGER_PROTOCOL = "call-ledger";
|
|
68
|
+
const CALL_LEDGER_VERSION = 1;
|
|
69
|
+
const USAGE_LEDGER_PERSISTENCE_CODE = "CC_USAGE_LEDGER_PERSISTENCE_FAILED";
|
|
70
|
+
const USAGE_LEDGER_PERSISTENCE_MESSAGE =
|
|
71
|
+
"Canonical usage ledger persistence failed; model and tool execution is blocked";
|
|
72
|
+
|
|
73
|
+
function usageProtocolError(code, message) {
|
|
74
|
+
const error = new Error(message);
|
|
75
|
+
error.code = code;
|
|
76
|
+
return error;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function classifyCanonicalUsageProtocol(data = {}) {
|
|
80
|
+
const record =
|
|
81
|
+
data && typeof data === "object" && !Array.isArray(data) ? data : {};
|
|
82
|
+
const hasScope = Object.hasOwn(record, "observabilityScope");
|
|
83
|
+
const hasProtocol = Object.hasOwn(record, "usageTelemetryProtocol");
|
|
84
|
+
const hasVersion = Object.hasOwn(record, "usageTelemetryVersion");
|
|
85
|
+
if (!hasScope && !hasProtocol && !hasVersion) return "legacy";
|
|
86
|
+
if (!hasProtocol || !hasVersion) {
|
|
87
|
+
throw usageProtocolError(
|
|
88
|
+
"CC_USAGE_LEDGER_PROTOCOL_REQUIRED",
|
|
89
|
+
"Canonical scoped sessions require call-ledger usage telemetry before model or tool execution",
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
if (
|
|
93
|
+
record.usageTelemetryProtocol !== CALL_LEDGER_PROTOCOL ||
|
|
94
|
+
record.usageTelemetryVersion !== CALL_LEDGER_VERSION
|
|
95
|
+
) {
|
|
96
|
+
throw usageProtocolError(
|
|
97
|
+
"CC_USAGE_LEDGER_PROTOCOL_UNSUPPORTED",
|
|
98
|
+
"Canonical session usage telemetry protocol is unsupported",
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return "call-ledger";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function readCanonicalUsageProtocol(sessionId, projectionReader) {
|
|
105
|
+
if (typeof projectionReader !== "function") return "legacy";
|
|
106
|
+
return projectionReader(sessionId, () => {
|
|
107
|
+
let sessionStart = null;
|
|
108
|
+
return {
|
|
109
|
+
accept(event) {
|
|
110
|
+
if (event?.type === "session_start" && sessionStart === null) {
|
|
111
|
+
sessionStart = event.data || {};
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
finish() {
|
|
115
|
+
return classifyCanonicalUsageProtocol(sessionStart || {});
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
});
|
|
119
|
+
}
|
|
53
120
|
|
|
54
121
|
function runCanonicalWsTurnExclusive(sessionId, task) {
|
|
55
122
|
const previous = CANONICAL_WS_TURN_QUEUES.get(sessionId) || Promise.resolve();
|
|
@@ -137,17 +204,33 @@ export class WSAgentHandler {
|
|
|
137
204
|
const { chatWithTools } = await import("../../runtime/agent-core.js");
|
|
138
205
|
return chatWithTools(...args);
|
|
139
206
|
});
|
|
207
|
+
const injectedCanonicalStore = canonicalSessionStore || null;
|
|
140
208
|
this._canonicalSessionStore = {
|
|
141
209
|
appendCompactEventIfMessagesMatch,
|
|
210
|
+
appendEvent,
|
|
211
|
+
appendLlmRetryCompact,
|
|
212
|
+
appendTokenUsage,
|
|
213
|
+
appendToolCallCompact,
|
|
142
214
|
claimWsTurnIfHead,
|
|
143
215
|
computeWsTurnInputDigest,
|
|
144
216
|
createWsTurnClaimId,
|
|
145
217
|
normalizeWsTurnRequestId,
|
|
218
|
+
readVerifiedProjection,
|
|
146
219
|
readVerifiedWsTurnState,
|
|
147
220
|
readVerifiedMessages,
|
|
148
221
|
settleWsTurnClaim,
|
|
149
222
|
...(canonicalSessionStore || {}),
|
|
150
223
|
};
|
|
224
|
+
// Test/embedding stores historically injected only WS-turn CAS methods.
|
|
225
|
+
// Preserve that compatibility as legacy unless they explicitly provide a
|
|
226
|
+
// verified projection reader. The production store always supplies one.
|
|
227
|
+
this._canonicalUsageProjectionReader =
|
|
228
|
+
injectedCanonicalStore &&
|
|
229
|
+
typeof injectedCanonicalStore.readVerifiedProjection !== "function"
|
|
230
|
+
? null
|
|
231
|
+
: this._canonicalSessionStore.readVerifiedProjection;
|
|
232
|
+
this._canonicalUsageProtocol = null;
|
|
233
|
+
this._usageLedgerFailure = null;
|
|
151
234
|
const explicitHostPrefix = Array.isArray(
|
|
152
235
|
session?._canonicalHostSystemPrefix,
|
|
153
236
|
)
|
|
@@ -188,6 +271,159 @@ export class WSAgentHandler {
|
|
|
188
271
|
return this.session.messages;
|
|
189
272
|
}
|
|
190
273
|
|
|
274
|
+
_resolveCanonicalUsageProtocol() {
|
|
275
|
+
if (this.session.canonicalJsonlSession !== true) return "legacy";
|
|
276
|
+
if (this._canonicalUsageProtocol) return this._canonicalUsageProtocol;
|
|
277
|
+
|
|
278
|
+
// An embedding may attach the immutable session-start declaration directly
|
|
279
|
+
// while supplying a partial canonical store. Never ignore such a marker.
|
|
280
|
+
const attachedDeclaration = {};
|
|
281
|
+
for (const field of [
|
|
282
|
+
"observabilityScope",
|
|
283
|
+
"usageTelemetryProtocol",
|
|
284
|
+
"usageTelemetryVersion",
|
|
285
|
+
]) {
|
|
286
|
+
if (Object.hasOwn(this.session, field)) {
|
|
287
|
+
attachedDeclaration[field] = this.session[field];
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
const attachedMode = classifyCanonicalUsageProtocol(attachedDeclaration);
|
|
291
|
+
if (attachedMode !== "legacy") {
|
|
292
|
+
this._canonicalUsageProtocol = attachedMode;
|
|
293
|
+
return attachedMode;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
this._canonicalUsageProtocol = readCanonicalUsageProtocol(
|
|
297
|
+
this.session.id,
|
|
298
|
+
this._canonicalUsageProjectionReader,
|
|
299
|
+
);
|
|
300
|
+
return this._canonicalUsageProtocol;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
_usageLedgerTerminalError(cause = null) {
|
|
304
|
+
const error = new Error(USAGE_LEDGER_PERSISTENCE_MESSAGE, {
|
|
305
|
+
...(cause ? { cause } : {}),
|
|
306
|
+
});
|
|
307
|
+
error.code = USAGE_LEDGER_PERSISTENCE_CODE;
|
|
308
|
+
error.runtimeLedgerPersistence = true;
|
|
309
|
+
return error;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
_latchUsageLedgerFailure(error) {
|
|
313
|
+
const marked = markRuntimeLedgerPersistenceError(error);
|
|
314
|
+
this._usageLedgerFailure ||= Object.freeze({
|
|
315
|
+
code: USAGE_LEDGER_PERSISTENCE_CODE,
|
|
316
|
+
reason: "canonical_usage_ledger_persistence_failed",
|
|
317
|
+
});
|
|
318
|
+
return this._usageLedgerTerminalError(marked);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
_assertUsageLedgerWritable() {
|
|
322
|
+
if (this._usageLedgerFailure) throw this._usageLedgerTerminalError();
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
_callCanonicalLedgerStore(method, ...args) {
|
|
326
|
+
this._assertUsageLedgerWritable();
|
|
327
|
+
try {
|
|
328
|
+
const result = this._canonicalSessionStore[method](...args);
|
|
329
|
+
if (result && typeof result.then === "function") {
|
|
330
|
+
void Promise.resolve(result).catch(() => {});
|
|
331
|
+
throw new TypeError(
|
|
332
|
+
`Canonical usage ledger ${method} must be synchronous`,
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
return result;
|
|
336
|
+
} catch (error) {
|
|
337
|
+
throw this._latchUsageLedgerFailure(error);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
_persistCanonicalUsageBoundary(event, outcome) {
|
|
342
|
+
let projected;
|
|
343
|
+
try {
|
|
344
|
+
projected = projectRuntimeUsageBoundary(event, outcome);
|
|
345
|
+
} catch (error) {
|
|
346
|
+
throw this._latchUsageLedgerFailure(error);
|
|
347
|
+
}
|
|
348
|
+
this._callCanonicalLedgerStore(
|
|
349
|
+
"appendEvent",
|
|
350
|
+
this.session.id,
|
|
351
|
+
runtimeUsageEventType(outcome),
|
|
352
|
+
projected,
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
_persistCanonicalTokenUsage(event) {
|
|
357
|
+
let projected;
|
|
358
|
+
try {
|
|
359
|
+
projected = projectRuntimeTokenUsage(event);
|
|
360
|
+
} catch (error) {
|
|
361
|
+
throw this._latchUsageLedgerFailure(error);
|
|
362
|
+
}
|
|
363
|
+
this._callCanonicalLedgerStore(
|
|
364
|
+
"appendTokenUsage",
|
|
365
|
+
this.session.id,
|
|
366
|
+
projected,
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
_persistCanonicalUsageSettlement(event) {
|
|
371
|
+
if (event?.type === "token-usage") {
|
|
372
|
+
this._persistCanonicalTokenUsage(event);
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
this._persistCanonicalUsageBoundary(event, "unknown");
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
_beginCanonicalCompactionUsage() {
|
|
379
|
+
const call = Object.freeze({
|
|
380
|
+
callId: `ws-cmp-${randomUUID()}`,
|
|
381
|
+
provider: this.session.provider || null,
|
|
382
|
+
model: this.session.model || null,
|
|
383
|
+
source: "semantic-compaction",
|
|
384
|
+
});
|
|
385
|
+
this._persistCanonicalUsageBoundary(call, "started");
|
|
386
|
+
return call;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
_settleCanonicalCompactionUsage(call, result) {
|
|
390
|
+
if (!call) return;
|
|
391
|
+
const unknown = result?.usageUnknownEvent || null;
|
|
392
|
+
if (unknown) {
|
|
393
|
+
const reason = unknown.reason || "provider_transport_outcome_unknown";
|
|
394
|
+
this._persistCanonicalUsageBoundary(
|
|
395
|
+
{
|
|
396
|
+
...call,
|
|
397
|
+
code:
|
|
398
|
+
reason === "provider_usage_not_reported"
|
|
399
|
+
? "provider_usage_missing"
|
|
400
|
+
: unknown.code || "provider_call_failed",
|
|
401
|
+
},
|
|
402
|
+
"unknown",
|
|
403
|
+
);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (result?.usageEvent?.usage) {
|
|
407
|
+
this._persistCanonicalTokenUsage({
|
|
408
|
+
...call,
|
|
409
|
+
usage: result.usageEvent.usage,
|
|
410
|
+
});
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
this._persistCanonicalUsageBoundary(
|
|
414
|
+
{ ...call, code: "provider_usage_missing" },
|
|
415
|
+
"unknown",
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
_settleCanonicalCompactionFailure(call) {
|
|
420
|
+
if (!call) return;
|
|
421
|
+
this._persistCanonicalUsageBoundary(
|
|
422
|
+
{ ...call, code: "provider_call_failed" },
|
|
423
|
+
"unknown",
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
191
427
|
_latchCompactionSettlement({
|
|
192
428
|
code,
|
|
193
429
|
reason,
|
|
@@ -286,6 +522,10 @@ export class WSAgentHandler {
|
|
|
286
522
|
|
|
287
523
|
const before = session.messages.length;
|
|
288
524
|
const expectedMessages = [...session.messages];
|
|
525
|
+
const strictUsageTelemetry =
|
|
526
|
+
this._resolveCanonicalUsageProtocol() === "call-ledger";
|
|
527
|
+
let compactionUsageCall = null;
|
|
528
|
+
let compactionUsageSettled = false;
|
|
289
529
|
let result;
|
|
290
530
|
try {
|
|
291
531
|
this._sessionHostLease?.assert?.();
|
|
@@ -303,13 +543,35 @@ export class WSAgentHandler {
|
|
|
303
543
|
cwd: session.projectRoot,
|
|
304
544
|
sessionId: session.id,
|
|
305
545
|
},
|
|
546
|
+
...(strictUsageTelemetry
|
|
547
|
+
? {
|
|
548
|
+
onProviderCallStart: () => {
|
|
549
|
+
const call = this._beginCanonicalCompactionUsage();
|
|
550
|
+
compactionUsageCall = call;
|
|
551
|
+
return call.callId;
|
|
552
|
+
},
|
|
553
|
+
}
|
|
554
|
+
: {}),
|
|
306
555
|
maxMessages: session.compactionMaxMessages,
|
|
307
556
|
maxTokens: session.compactionMaxTokens,
|
|
308
557
|
maxOutputTokens: session.compactionMaxOutputTokens,
|
|
309
558
|
summaryInputMaxChars: session.compactionInputMaxChars,
|
|
310
559
|
});
|
|
560
|
+
if (compactionUsageCall) {
|
|
561
|
+
this._settleCanonicalCompactionUsage(compactionUsageCall, result);
|
|
562
|
+
compactionUsageSettled = true;
|
|
563
|
+
}
|
|
311
564
|
this._sessionHostLease?.assert?.();
|
|
312
565
|
} catch (error) {
|
|
566
|
+
if (
|
|
567
|
+
compactionUsageCall &&
|
|
568
|
+
!compactionUsageSettled &&
|
|
569
|
+
error?.runtimeLedgerPersistence !== true
|
|
570
|
+
) {
|
|
571
|
+
this._settleCanonicalCompactionFailure(compactionUsageCall);
|
|
572
|
+
compactionUsageSettled = true;
|
|
573
|
+
}
|
|
574
|
+
if (error?.runtimeLedgerPersistence === true) throw error;
|
|
313
575
|
if (isAbortError(error) || this._sessionHostLease?.signal?.aborted) {
|
|
314
576
|
throw error;
|
|
315
577
|
}
|
|
@@ -755,6 +1017,7 @@ export class WSAgentHandler {
|
|
|
755
1017
|
let diffReviewFollowUps = null;
|
|
756
1018
|
let runRecorded = false;
|
|
757
1019
|
let canonicalTurn = null;
|
|
1020
|
+
let strictUsageTelemetry = false;
|
|
758
1021
|
|
|
759
1022
|
try {
|
|
760
1023
|
const { session } = this;
|
|
@@ -776,6 +1039,9 @@ export class WSAgentHandler {
|
|
|
776
1039
|
inputDigest,
|
|
777
1040
|
);
|
|
778
1041
|
if (!canonicalTurn) {
|
|
1042
|
+
strictUsageTelemetry =
|
|
1043
|
+
this._resolveCanonicalUsageProtocol() === "call-ledger";
|
|
1044
|
+
if (strictUsageTelemetry) this._assertUsageLedgerWritable();
|
|
779
1045
|
const compacted =
|
|
780
1046
|
await this._compactCanonicalHistoryBeforeClaim(requestId);
|
|
781
1047
|
if (!compacted) return;
|
|
@@ -886,6 +1152,27 @@ export class WSAgentHandler {
|
|
|
886
1152
|
...(session.canonicalJsonlSession === true
|
|
887
1153
|
? { autoCompact: false }
|
|
888
1154
|
: {}),
|
|
1155
|
+
...(strictUsageTelemetry
|
|
1156
|
+
? {
|
|
1157
|
+
strictUsageTelemetry: true,
|
|
1158
|
+
onUsageBoundary: (event) =>
|
|
1159
|
+
this._persistCanonicalUsageBoundary(event, "started"),
|
|
1160
|
+
onUsageSettlement: (event) =>
|
|
1161
|
+
this._persistCanonicalUsageSettlement(event),
|
|
1162
|
+
onStreamRetry: (attempt, error, telemetry = {}) =>
|
|
1163
|
+
this._callCanonicalLedgerStore(
|
|
1164
|
+
"appendLlmRetryCompact",
|
|
1165
|
+
session.id,
|
|
1166
|
+
{
|
|
1167
|
+
attempt,
|
|
1168
|
+
durationMs: telemetry.durationMs,
|
|
1169
|
+
provider: telemetry.provider || session.provider,
|
|
1170
|
+
model: telemetry.model || activeModel,
|
|
1171
|
+
reason: classifyStreamRetryReason(error),
|
|
1172
|
+
},
|
|
1173
|
+
),
|
|
1174
|
+
}
|
|
1175
|
+
: {}),
|
|
889
1176
|
};
|
|
890
1177
|
|
|
891
1178
|
// P0-2: crash-safe side-effect ledger for the IDE/bridge path — mirrors
|
|
@@ -897,6 +1184,68 @@ export class WSAgentHandler {
|
|
|
897
1184
|
diffReviewFollowUps = new DiffReviewFollowUpTracker(sideEffectLedger);
|
|
898
1185
|
let currentSideEffectOpId = null;
|
|
899
1186
|
let currentTodoWrite = null;
|
|
1187
|
+
const activeToolCalls = new Map();
|
|
1188
|
+
const activeToolCallOrder = [];
|
|
1189
|
+
const boundedToolUseId = (value) =>
|
|
1190
|
+
typeof value === "string" &&
|
|
1191
|
+
value.trim() &&
|
|
1192
|
+
value.length <= 128 &&
|
|
1193
|
+
!/\p{Cc}/u.test(value)
|
|
1194
|
+
? value.trim()
|
|
1195
|
+
: null;
|
|
1196
|
+
const boundedToolName = (value) => {
|
|
1197
|
+
if (typeof value !== "string") return "?";
|
|
1198
|
+
const clean = value.replace(/\p{Cc}/gu, "").trim();
|
|
1199
|
+
return clean ? clean.slice(0, 160) : "?";
|
|
1200
|
+
};
|
|
1201
|
+
const beginToolUsage = (event) => {
|
|
1202
|
+
const providerId = boundedToolUseId(event.tool_use_id);
|
|
1203
|
+
const record = {
|
|
1204
|
+
id: runtimeToolCallId(providerId || undefined),
|
|
1205
|
+
providerId,
|
|
1206
|
+
tool: boundedToolName(event.tool),
|
|
1207
|
+
startedAt: Date.now(),
|
|
1208
|
+
};
|
|
1209
|
+
this._callCanonicalLedgerStore(
|
|
1210
|
+
"appendEvent",
|
|
1211
|
+
session.id,
|
|
1212
|
+
"tool_call_started",
|
|
1213
|
+
{ id: record.id, tool: record.tool },
|
|
1214
|
+
);
|
|
1215
|
+
activeToolCallOrder.push(record);
|
|
1216
|
+
if (providerId) activeToolCalls.set(providerId, record);
|
|
1217
|
+
};
|
|
1218
|
+
const settleToolUsage = (event) => {
|
|
1219
|
+
const providerId = boundedToolUseId(event.tool_use_id);
|
|
1220
|
+
const record =
|
|
1221
|
+
(providerId ? activeToolCalls.get(providerId) : null) ||
|
|
1222
|
+
activeToolCallOrder.find(
|
|
1223
|
+
(entry) => entry.tool === boundedToolName(event.tool),
|
|
1224
|
+
) ||
|
|
1225
|
+
null;
|
|
1226
|
+
if (!record) return;
|
|
1227
|
+
const durationMs =
|
|
1228
|
+
event.result?.toolTelemetryRecord?.durationMs ??
|
|
1229
|
+
Math.max(0, Date.now() - record.startedAt);
|
|
1230
|
+
this._callCanonicalLedgerStore("appendToolCallCompact", session.id, {
|
|
1231
|
+
id: record.id,
|
|
1232
|
+
tool: record.tool,
|
|
1233
|
+
isError: Boolean(event.error || event.result?.error),
|
|
1234
|
+
skill:
|
|
1235
|
+
event?.attribution?.skill ||
|
|
1236
|
+
(record.tool === "run_skill"
|
|
1237
|
+
? event.result?.skill || event.result?.skill_name || undefined
|
|
1238
|
+
: undefined),
|
|
1239
|
+
durationMs,
|
|
1240
|
+
});
|
|
1241
|
+
if (record.providerId) activeToolCalls.delete(record.providerId);
|
|
1242
|
+
const index = activeToolCallOrder.indexOf(record);
|
|
1243
|
+
if (index >= 0) activeToolCallOrder.splice(index, 1);
|
|
1244
|
+
};
|
|
1245
|
+
if (strictUsageTelemetry) {
|
|
1246
|
+
loopOptions.onToolCallBoundary = beginToolUsage;
|
|
1247
|
+
loopOptions.onToolCallSettlement = settleToolUsage;
|
|
1248
|
+
}
|
|
900
1249
|
|
|
901
1250
|
const executeAgentTurn = async () => {
|
|
902
1251
|
for await (const event of this._agentLoop(
|
|
@@ -913,6 +1262,7 @@ export class WSAgentHandler {
|
|
|
913
1262
|
break;
|
|
914
1263
|
|
|
915
1264
|
case "tool-executing":
|
|
1265
|
+
if (strictUsageTelemetry) beginToolUsage(event);
|
|
916
1266
|
this.interaction.emit("tool-executing", {
|
|
917
1267
|
requestId,
|
|
918
1268
|
tool: event.tool,
|
|
@@ -953,6 +1303,7 @@ export class WSAgentHandler {
|
|
|
953
1303
|
break;
|
|
954
1304
|
|
|
955
1305
|
case "tool-result":
|
|
1306
|
+
if (strictUsageTelemetry) settleToolUsage(event);
|
|
956
1307
|
this.interaction.emit("tool-result", {
|
|
957
1308
|
requestId,
|
|
958
1309
|
tool: event.tool,
|
|
@@ -1007,9 +1358,24 @@ export class WSAgentHandler {
|
|
|
1007
1358
|
break;
|
|
1008
1359
|
|
|
1009
1360
|
case "compaction-usage-unknown":
|
|
1361
|
+
if (strictUsageTelemetry && event.ledgerPersisted !== true) {
|
|
1362
|
+
this._persistCanonicalUsageBoundary(event, "unknown");
|
|
1363
|
+
}
|
|
1010
1364
|
this._emitCompactionUsageUnknown(requestId, event);
|
|
1011
1365
|
break;
|
|
1012
1366
|
|
|
1367
|
+
case "model-usage-started":
|
|
1368
|
+
if (strictUsageTelemetry && event.ledgerPersisted !== true) {
|
|
1369
|
+
this._persistCanonicalUsageBoundary(event, "started");
|
|
1370
|
+
}
|
|
1371
|
+
break;
|
|
1372
|
+
|
|
1373
|
+
case "model-usage-unknown":
|
|
1374
|
+
if (strictUsageTelemetry && event.ledgerPersisted !== true) {
|
|
1375
|
+
this._persistCanonicalUsageBoundary(event, "unknown");
|
|
1376
|
+
}
|
|
1377
|
+
break;
|
|
1378
|
+
|
|
1013
1379
|
case "compaction":
|
|
1014
1380
|
this.interaction.emit("compaction", {
|
|
1015
1381
|
requestId,
|
|
@@ -1018,6 +1384,9 @@ export class WSAgentHandler {
|
|
|
1018
1384
|
break;
|
|
1019
1385
|
|
|
1020
1386
|
case "token-usage":
|
|
1387
|
+
if (strictUsageTelemetry && event.ledgerPersisted !== true) {
|
|
1388
|
+
this._persistCanonicalTokenUsage(event);
|
|
1389
|
+
}
|
|
1021
1390
|
this.interaction.emit("token-usage", {
|
|
1022
1391
|
requestId,
|
|
1023
1392
|
provider: event.provider,
|
|
@@ -1122,6 +1491,12 @@ export class WSAgentHandler {
|
|
|
1122
1491
|
);
|
|
1123
1492
|
surfacedError.code = "CC_WS_TURN_SETTLEMENT_UNKNOWN";
|
|
1124
1493
|
}
|
|
1494
|
+
if (
|
|
1495
|
+
surfacedError?.runtimeLedgerPersistence === true &&
|
|
1496
|
+
surfacedError?.code !== "CC_WS_TURN_SETTLEMENT_UNKNOWN"
|
|
1497
|
+
) {
|
|
1498
|
+
surfacedError = this._usageLedgerTerminalError(surfacedError);
|
|
1499
|
+
}
|
|
1125
1500
|
if (canonicalTurn?.baseMessages && canonicalTurn.status !== "completed") {
|
|
1126
1501
|
this.session.messages = [...canonicalTurn.baseMessages];
|
|
1127
1502
|
}
|
|
@@ -1312,10 +1687,41 @@ export class WSAgentHandler {
|
|
|
1312
1687
|
break;
|
|
1313
1688
|
}
|
|
1314
1689
|
|
|
1690
|
+
let strictUsageTelemetry = false;
|
|
1691
|
+
if (session.canonicalJsonlSession === true) {
|
|
1692
|
+
try {
|
|
1693
|
+
strictUsageTelemetry =
|
|
1694
|
+
this._resolveCanonicalUsageProtocol() === "call-ledger";
|
|
1695
|
+
if (strictUsageTelemetry) this._assertUsageLedgerWritable();
|
|
1696
|
+
} catch (error) {
|
|
1697
|
+
const admission = {
|
|
1698
|
+
code: error?.code || "CC_USAGE_LEDGER_ADMISSION_FAILED",
|
|
1699
|
+
reason: "canonical_usage_telemetry_admission_failed",
|
|
1700
|
+
};
|
|
1701
|
+
this.interaction.emit("compaction-degraded", {
|
|
1702
|
+
requestId,
|
|
1703
|
+
reason: admission.reason,
|
|
1704
|
+
summaryMode: "none",
|
|
1705
|
+
code: admission.code,
|
|
1706
|
+
});
|
|
1707
|
+
this.interaction.emit("command-response", {
|
|
1708
|
+
requestId,
|
|
1709
|
+
command: cmd,
|
|
1710
|
+
result: {
|
|
1711
|
+
messageCount: session.messages.length,
|
|
1712
|
+
error: admission,
|
|
1713
|
+
},
|
|
1714
|
+
});
|
|
1715
|
+
break;
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
|
|
1315
1719
|
const before = session.messages.length;
|
|
1316
1720
|
const expectedMessages = [...session.messages];
|
|
1317
1721
|
let result = null;
|
|
1318
1722
|
let commandError = null;
|
|
1723
|
+
let compactionUsageCall = null;
|
|
1724
|
+
let compactionUsageSettled = false;
|
|
1319
1725
|
try {
|
|
1320
1726
|
this._sessionHostLease?.assert?.();
|
|
1321
1727
|
result = await compactConversationWithProvider(session.messages, {
|
|
@@ -1332,19 +1738,47 @@ export class WSAgentHandler {
|
|
|
1332
1738
|
cwd: session.projectRoot,
|
|
1333
1739
|
sessionId: session.id,
|
|
1334
1740
|
},
|
|
1741
|
+
...(strictUsageTelemetry
|
|
1742
|
+
? {
|
|
1743
|
+
onProviderCallStart: () => {
|
|
1744
|
+
const call = this._beginCanonicalCompactionUsage();
|
|
1745
|
+
compactionUsageCall = call;
|
|
1746
|
+
return call.callId;
|
|
1747
|
+
},
|
|
1748
|
+
}
|
|
1749
|
+
: {}),
|
|
1335
1750
|
maxOutputTokens: session.compactionMaxOutputTokens,
|
|
1336
1751
|
summaryInputMaxChars: session.compactionInputMaxChars,
|
|
1337
1752
|
});
|
|
1753
|
+
if (compactionUsageCall) {
|
|
1754
|
+
this._settleCanonicalCompactionUsage(compactionUsageCall, result);
|
|
1755
|
+
compactionUsageSettled = true;
|
|
1756
|
+
}
|
|
1338
1757
|
this._sessionHostLease?.assert?.();
|
|
1339
1758
|
} catch (error) {
|
|
1759
|
+
if (
|
|
1760
|
+
compactionUsageCall &&
|
|
1761
|
+
!compactionUsageSettled &&
|
|
1762
|
+
error?.runtimeLedgerPersistence !== true
|
|
1763
|
+
) {
|
|
1764
|
+
this._settleCanonicalCompactionFailure(compactionUsageCall);
|
|
1765
|
+
compactionUsageSettled = true;
|
|
1766
|
+
}
|
|
1340
1767
|
if (isAbortError(error) || this._sessionHostLease?.signal?.aborted) {
|
|
1341
1768
|
throw error;
|
|
1342
1769
|
}
|
|
1343
|
-
commandError =
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1770
|
+
commandError =
|
|
1771
|
+
error?.runtimeLedgerPersistence === true
|
|
1772
|
+
? {
|
|
1773
|
+
code: USAGE_LEDGER_PERSISTENCE_CODE,
|
|
1774
|
+
reason: "canonical_usage_ledger_persistence_failed",
|
|
1775
|
+
commitState: "usage-ledger-failed",
|
|
1776
|
+
}
|
|
1777
|
+
: this._latchCompactionSettlement({
|
|
1778
|
+
code: error?.code || "CC_COMPACTION_FAILED",
|
|
1779
|
+
reason: `compaction_failed:${String(error?.message || error).slice(0, 240)}`,
|
|
1780
|
+
commitState: "provider-outcome-unknown",
|
|
1781
|
+
});
|
|
1348
1782
|
this.interaction.emit("compaction-degraded", {
|
|
1349
1783
|
requestId,
|
|
1350
1784
|
reason: commandError.reason,
|