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
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readVerifiedProjection,
|
|
3
|
+
resolveSessionAuthority,
|
|
4
|
+
} from "../harness/jsonl-session-store.js";
|
|
5
|
+
|
|
6
|
+
export const CHAT_CALL_LEDGER_UNSUPPORTED = "CC_CHAT_CALL_LEDGER_UNSUPPORTED";
|
|
7
|
+
export const CHAT_SESSION_NOT_FOUND = "CC_CHAT_SESSION_NOT_FOUND";
|
|
8
|
+
export const CHAT_SESSION_UNAVAILABLE = "CC_CHAT_SESSION_UNAVAILABLE";
|
|
9
|
+
|
|
10
|
+
function admissionError(code, message) {
|
|
11
|
+
const error = new Error(message);
|
|
12
|
+
error.code = code;
|
|
13
|
+
return error;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function sessionDeclaresProtectedUsage(sessionId, projectionReader) {
|
|
17
|
+
return projectionReader(sessionId, () => {
|
|
18
|
+
let protectedUsage = false;
|
|
19
|
+
let sessionStartSeen = false;
|
|
20
|
+
return {
|
|
21
|
+
accept(event) {
|
|
22
|
+
if (event?.type !== "session_start" || sessionStartSeen) return;
|
|
23
|
+
sessionStartSeen = true;
|
|
24
|
+
const data =
|
|
25
|
+
event.data &&
|
|
26
|
+
typeof event.data === "object" &&
|
|
27
|
+
!Array.isArray(event.data)
|
|
28
|
+
? event.data
|
|
29
|
+
: {};
|
|
30
|
+
protectedUsage = [
|
|
31
|
+
"observabilityScope",
|
|
32
|
+
"usageTelemetryProtocol",
|
|
33
|
+
"usageTelemetryVersion",
|
|
34
|
+
].some((field) => Object.hasOwn(data, field));
|
|
35
|
+
},
|
|
36
|
+
finish() {
|
|
37
|
+
return protectedUsage;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Admit only an explicitly present, readable and fully verified legacy session.
|
|
45
|
+
* Interactive chat cannot yet durably bracket its provider calls, so any scope
|
|
46
|
+
* or call-ledger declaration must fail before the REPL appends or spends.
|
|
47
|
+
*/
|
|
48
|
+
export function assertChatSessionUsageAdmission(
|
|
49
|
+
sessionReference,
|
|
50
|
+
{
|
|
51
|
+
resolveAuthority = resolveSessionAuthority,
|
|
52
|
+
readProjection = readVerifiedProjection,
|
|
53
|
+
} = {},
|
|
54
|
+
) {
|
|
55
|
+
if (!sessionReference) return;
|
|
56
|
+
const authority = resolveAuthority(sessionReference);
|
|
57
|
+
if (!authority) {
|
|
58
|
+
throw admissionError(
|
|
59
|
+
CHAT_SESSION_NOT_FOUND,
|
|
60
|
+
"Interactive chat session was not found",
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
if (!authority.readable) {
|
|
64
|
+
throw admissionError(
|
|
65
|
+
CHAT_SESSION_UNAVAILABLE,
|
|
66
|
+
"Interactive chat session is not readable and cannot be resumed safely",
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (!sessionDeclaresProtectedUsage(authority.id, readProjection)) {
|
|
70
|
+
return authority.id;
|
|
71
|
+
}
|
|
72
|
+
throw admissionError(
|
|
73
|
+
CHAT_CALL_LEDGER_UNSUPPORTED,
|
|
74
|
+
"Scoped call-ledger sessions are not supported by interactive chat; use agent mode or an IDE host with usage-ledger support",
|
|
75
|
+
);
|
|
76
|
+
}
|
package/src/lib/cost-budget.js
CHANGED
|
@@ -19,11 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
import { estimateCost } from "./llm-pricing.js";
|
|
21
21
|
|
|
22
|
-
const round = (n, dp = 6) => {
|
|
23
|
-
const f = Math.pow(10, dp);
|
|
24
|
-
return Math.round((Number(n) + Number.EPSILON) * f) / f;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
22
|
/** Parse a `--max-budget-usd` value into a positive number, or null when unset. */
|
|
28
23
|
export function parseBudgetUsd(value) {
|
|
29
24
|
if (value == null || value === "") return null;
|
|
@@ -94,7 +89,10 @@ export class CostBudget {
|
|
|
94
89
|
// otherwise treat the record as unpriced.
|
|
95
90
|
const cost = Number(est.totalCost);
|
|
96
91
|
if (Number.isFinite(cost) && cost >= 0) {
|
|
97
|
-
|
|
92
|
+
// Preserve sub-microdollar charges. Formatting belongs at the UI edge;
|
|
93
|
+
// rounding here can turn a positive paid call into zero and disable a
|
|
94
|
+
// sufficiently small hard budget.
|
|
95
|
+
this.spentUsd += cost;
|
|
98
96
|
this.priced = true;
|
|
99
97
|
} else {
|
|
100
98
|
this.sawUnpriced = true;
|
|
@@ -114,7 +112,7 @@ export class CostBudget {
|
|
|
114
112
|
remaining() {
|
|
115
113
|
return this.limitUsd == null
|
|
116
114
|
? Infinity
|
|
117
|
-
: Math.max(0,
|
|
115
|
+
: Math.max(0, this.limitUsd - this.spentUsd);
|
|
118
116
|
}
|
|
119
117
|
|
|
120
118
|
/**
|
|
@@ -10,6 +10,10 @@ import { runPeerGroup } from "./agent-group-runner.js";
|
|
|
10
10
|
|
|
11
11
|
const DEFAULT_CRITERIA = ["quality", "performance", "readability"];
|
|
12
12
|
|
|
13
|
+
function throwRuntimeLedgerFailure(error) {
|
|
14
|
+
if (error?.runtimeLedgerPersistence === true) throw error;
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
const VARIANT_PROFILES = [
|
|
14
18
|
{
|
|
15
19
|
name: "conservative",
|
|
@@ -84,6 +88,12 @@ export async function compare({
|
|
|
84
88
|
},
|
|
85
89
|
});
|
|
86
90
|
|
|
91
|
+
// Ordinary variant failures remain comparable, but a host ledger failure
|
|
92
|
+
// must escape before judging can spend again or a partial result is emitted.
|
|
93
|
+
for (const outcome of runResult.results) {
|
|
94
|
+
throwRuntimeLedgerFailure(outcome.error);
|
|
95
|
+
}
|
|
96
|
+
|
|
87
97
|
const generatedVariants = runResult.results.map((r) => {
|
|
88
98
|
if (r.ok) return r.value;
|
|
89
99
|
const profile = r.peer.payload.profile;
|
|
@@ -135,6 +145,7 @@ REASON: (1-2 sentence justification)`;
|
|
|
135
145
|
winner = parseWinner(judgement) || generatedVariants[0]?.name || "unknown";
|
|
136
146
|
reason = parseReason(judgement) || "See detailed scores above.";
|
|
137
147
|
} catch (err) {
|
|
148
|
+
throwRuntimeLedgerFailure(err);
|
|
138
149
|
reason = `Scoring error: ${err.message}`;
|
|
139
150
|
}
|
|
140
151
|
|
|
@@ -10,6 +10,10 @@ import { runPeerGroup } from "./agent-group-runner.js";
|
|
|
10
10
|
|
|
11
11
|
const DEFAULT_PERSPECTIVES = ["performance", "security", "maintainability"];
|
|
12
12
|
|
|
13
|
+
function throwRuntimeLedgerFailure(error) {
|
|
14
|
+
if (error?.runtimeLedgerPersistence === true) throw error;
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
const PERSPECTIVE_PROMPTS = {
|
|
14
18
|
performance: {
|
|
15
19
|
role: "Performance Reviewer",
|
|
@@ -96,6 +100,13 @@ export async function startDebate({
|
|
|
96
100
|
},
|
|
97
101
|
});
|
|
98
102
|
|
|
103
|
+
// Peer groups intentionally turn ordinary reviewer failures into result
|
|
104
|
+
// rows. A durable usage-ledger failure is host-terminal, not review content:
|
|
105
|
+
// let the REPL latch stop this and every later paid call.
|
|
106
|
+
for (const outcome of runResult.results) {
|
|
107
|
+
throwRuntimeLedgerFailure(outcome.error);
|
|
108
|
+
}
|
|
109
|
+
|
|
99
110
|
const reviews = runResult.results.map((r) => {
|
|
100
111
|
if (r.ok) return r.value;
|
|
101
112
|
return {
|
|
@@ -142,6 +153,7 @@ export async function startDebate({
|
|
|
142
153
|
finalVerdict = extractVerdict(summary);
|
|
143
154
|
consensusScore = extractConsensusScore(summary);
|
|
144
155
|
} catch (err) {
|
|
156
|
+
throwRuntimeLedgerFailure(err);
|
|
145
157
|
summary = `Moderator error: ${err.message}`;
|
|
146
158
|
}
|
|
147
159
|
|
|
@@ -11,6 +11,86 @@ import { LLMProviderRegistry, BUILT_IN_PROVIDERS } from "./llm-providers.js";
|
|
|
11
11
|
import { loadConfig } from "./config-manager.js";
|
|
12
12
|
import { applyConfigLlmDefaults } from "./llm-config-defaults.js";
|
|
13
13
|
|
|
14
|
+
function plainUsage(value) {
|
|
15
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
16
|
+
? value
|
|
17
|
+
: null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function normalizeOllamaUsage(data) {
|
|
21
|
+
if (
|
|
22
|
+
!Object.hasOwn(data, "prompt_eval_count") ||
|
|
23
|
+
!Object.hasOwn(data, "eval_count")
|
|
24
|
+
) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
input_tokens: data.prompt_eval_count,
|
|
29
|
+
output_tokens: data.eval_count,
|
|
30
|
+
cache_read_input_tokens: 0,
|
|
31
|
+
cache_creation_input_tokens: 0,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeAnthropicUsage(value) {
|
|
36
|
+
const usage = plainUsage(value);
|
|
37
|
+
if (!usage) return null;
|
|
38
|
+
// Keep malformed provider fields malformed so the canonical ledger projects
|
|
39
|
+
// the call as unknown instead of manufacturing a known zero settlement.
|
|
40
|
+
return {
|
|
41
|
+
input_tokens: usage.input_tokens,
|
|
42
|
+
output_tokens: usage.output_tokens,
|
|
43
|
+
cache_read_input_tokens: Object.hasOwn(usage, "cache_read_input_tokens")
|
|
44
|
+
? usage.cache_read_input_tokens
|
|
45
|
+
: 0,
|
|
46
|
+
cache_creation_input_tokens: Object.hasOwn(
|
|
47
|
+
usage,
|
|
48
|
+
"cache_creation_input_tokens",
|
|
49
|
+
)
|
|
50
|
+
? usage.cache_creation_input_tokens
|
|
51
|
+
: 0,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function normalizeOpenAiUsage(value) {
|
|
56
|
+
const usage = plainUsage(value);
|
|
57
|
+
if (!usage) return null;
|
|
58
|
+
// OpenAI/volcengine report cached prompt tokens under the nested detail;
|
|
59
|
+
// DeepSeek reports the same quantity as prompt_cache_hit_tokens. In both
|
|
60
|
+
// cases prompt_tokens includes the cached prefix, so persist only the
|
|
61
|
+
// uncached remainder as input_tokens.
|
|
62
|
+
const detailed = Number(usage.prompt_tokens_details?.cached_tokens);
|
|
63
|
+
const deepseek = Number(usage.prompt_cache_hit_tokens);
|
|
64
|
+
const cached =
|
|
65
|
+
Number.isFinite(detailed) && detailed > 0
|
|
66
|
+
? detailed
|
|
67
|
+
: Number.isFinite(deepseek) && deepseek > 0
|
|
68
|
+
? deepseek
|
|
69
|
+
: 0;
|
|
70
|
+
const input =
|
|
71
|
+
typeof usage.prompt_tokens === "number" && typeof cached === "number"
|
|
72
|
+
? usage.prompt_tokens - cached
|
|
73
|
+
: usage.prompt_tokens;
|
|
74
|
+
return {
|
|
75
|
+
input_tokens: input,
|
|
76
|
+
output_tokens: usage.completion_tokens,
|
|
77
|
+
cache_read_input_tokens: cached,
|
|
78
|
+
cache_creation_input_tokens: 0,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function chatEnvelope(content, usage = null) {
|
|
83
|
+
return {
|
|
84
|
+
content: typeof content === "string" ? content : "",
|
|
85
|
+
...(usage ? { usage } : {}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function invokeChatCall(callWrapper, provider, model, call) {
|
|
90
|
+
if (!callWrapper) return call();
|
|
91
|
+
return callWrapper({ call, provider, model });
|
|
92
|
+
}
|
|
93
|
+
|
|
14
94
|
/**
|
|
15
95
|
* Create a chat completion function that routes through the active LLM provider.
|
|
16
96
|
*
|
|
@@ -26,6 +106,10 @@ import { applyConfigLlmDefaults } from "./llm-config-defaults.js";
|
|
|
26
106
|
* @param {string} [options.model] - Model name override
|
|
27
107
|
* @param {string} [options.baseUrl] - Base URL override
|
|
28
108
|
* @param {string} [options.apiKey] - API key override
|
|
109
|
+
* @param {(request: {call: function, provider: string, model: string}) => Promise<object>} [options.callWrapper]
|
|
110
|
+
* Optional host boundary around each real provider call. The callback
|
|
111
|
+
* resolves to a private `{content, usage?}` envelope; callers still
|
|
112
|
+
* receive only the response string.
|
|
29
113
|
* @returns {(messages: object[], opts?: object) => Promise<string>}
|
|
30
114
|
*/
|
|
31
115
|
export function createChatFn(options = {}) {
|
|
@@ -47,25 +131,40 @@ export function createChatFn(options = {}) {
|
|
|
47
131
|
const model =
|
|
48
132
|
resolved.model || process.env.LLM_MODEL || providerDef.models[0];
|
|
49
133
|
const baseUrl = resolved.baseUrl || providerDef.baseUrl;
|
|
134
|
+
const callWrapper = resolved.callWrapper || null;
|
|
135
|
+
if (callWrapper !== null && typeof callWrapper !== "function") {
|
|
136
|
+
throw new TypeError("cowork callWrapper must be a function");
|
|
137
|
+
}
|
|
50
138
|
|
|
51
139
|
return async function chat(messages, opts = {}) {
|
|
52
140
|
const currentModel = opts.model || model;
|
|
53
141
|
const maxTokens = opts.maxTokens || 2048;
|
|
54
142
|
|
|
55
143
|
if (provider === "ollama") {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
144
|
+
const envelope = await invokeChatCall(
|
|
145
|
+
callWrapper,
|
|
146
|
+
provider,
|
|
147
|
+
currentModel,
|
|
148
|
+
async () => {
|
|
149
|
+
const res = await fetch(`${baseUrl}/api/chat`, {
|
|
150
|
+
method: "POST",
|
|
151
|
+
headers: { "Content-Type": "application/json" },
|
|
152
|
+
body: JSON.stringify({
|
|
153
|
+
model: currentModel,
|
|
154
|
+
messages,
|
|
155
|
+
stream: false,
|
|
156
|
+
options: { num_predict: maxTokens },
|
|
157
|
+
}),
|
|
158
|
+
});
|
|
159
|
+
if (!res.ok) throw new Error(`Ollama error: ${res.status}`);
|
|
160
|
+
const data = await res.json();
|
|
161
|
+
return chatEnvelope(
|
|
162
|
+
data.message?.content,
|
|
163
|
+
normalizeOllamaUsage(data),
|
|
164
|
+
);
|
|
165
|
+
},
|
|
166
|
+
);
|
|
167
|
+
return typeof envelope === "string" ? envelope : envelope?.content || "";
|
|
69
168
|
}
|
|
70
169
|
|
|
71
170
|
if (provider === "anthropic") {
|
|
@@ -82,39 +181,61 @@ export function createChatFn(options = {}) {
|
|
|
82
181
|
if (systemMsgs.length > 0) {
|
|
83
182
|
body.system = systemMsgs.map((m) => m.content).join("\n");
|
|
84
183
|
}
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
184
|
+
const envelope = await invokeChatCall(
|
|
185
|
+
callWrapper,
|
|
186
|
+
provider,
|
|
187
|
+
currentModel,
|
|
188
|
+
async () => {
|
|
189
|
+
const res = await fetch(`${baseUrl}/messages`, {
|
|
190
|
+
method: "POST",
|
|
191
|
+
headers: {
|
|
192
|
+
"Content-Type": "application/json",
|
|
193
|
+
"x-api-key": key,
|
|
194
|
+
"anthropic-version": "2023-06-01",
|
|
195
|
+
},
|
|
196
|
+
body: JSON.stringify(body),
|
|
197
|
+
});
|
|
198
|
+
if (!res.ok) throw new Error(`Anthropic error: ${res.status}`);
|
|
199
|
+
const data = await res.json();
|
|
200
|
+
return chatEnvelope(
|
|
201
|
+
data.content?.[0]?.text,
|
|
202
|
+
normalizeAnthropicUsage(data.usage),
|
|
203
|
+
);
|
|
91
204
|
},
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (!res.ok) throw new Error(`Anthropic error: ${res.status}`);
|
|
95
|
-
const data = await res.json();
|
|
96
|
-
return data.content?.[0]?.text || "";
|
|
205
|
+
);
|
|
206
|
+
return typeof envelope === "string" ? envelope : envelope?.content || "";
|
|
97
207
|
}
|
|
98
208
|
|
|
99
209
|
// OpenAI-compatible (openai, deepseek, dashscope, mistral, gemini)
|
|
100
210
|
const key = resolved.apiKey || process.env[providerDef.apiKeyEnv];
|
|
101
211
|
if (!key) throw new Error(`${providerDef.apiKeyEnv} not set`);
|
|
102
212
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
213
|
+
const envelope = await invokeChatCall(
|
|
214
|
+
callWrapper,
|
|
215
|
+
provider,
|
|
216
|
+
currentModel,
|
|
217
|
+
async () => {
|
|
218
|
+
const res = await fetch(`${baseUrl}/chat/completions`, {
|
|
219
|
+
method: "POST",
|
|
220
|
+
headers: {
|
|
221
|
+
"Content-Type": "application/json",
|
|
222
|
+
Authorization: `Bearer ${key}`,
|
|
223
|
+
},
|
|
224
|
+
body: JSON.stringify({
|
|
225
|
+
model: currentModel,
|
|
226
|
+
messages,
|
|
227
|
+
max_tokens: maxTokens,
|
|
228
|
+
}),
|
|
229
|
+
});
|
|
230
|
+
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
231
|
+
const data = await res.json();
|
|
232
|
+
return chatEnvelope(
|
|
233
|
+
data.choices?.[0]?.message?.content,
|
|
234
|
+
normalizeOpenAiUsage(data.usage),
|
|
235
|
+
);
|
|
108
236
|
},
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
messages,
|
|
112
|
-
max_tokens: maxTokens,
|
|
113
|
-
}),
|
|
114
|
-
});
|
|
115
|
-
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
116
|
-
const data = await res.json();
|
|
117
|
-
return data.choices?.[0]?.message?.content || "";
|
|
237
|
+
);
|
|
238
|
+
return typeof envelope === "string" ? envelope : envelope?.content || "";
|
|
118
239
|
};
|
|
119
240
|
}
|
|
120
241
|
|