chainlesschain 0.166.102 → 0.166.104
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/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-CyHIMEd8.js → AIOps-Bah3HREy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-vuNxDpHm.js → ActionButton-DY2aeZMc.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D0quEM0q.js → Analytics-BFly8Xaa.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-xRSVpbCs.js → AppLayout-dp0Zz-JM.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-ktfVAZBC.js → Artifacts-DcIg09ai.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-UJW6maH4.js → Audit-DkN-lsjZ.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BYrfdCoT.js → BackgroundAgents-BjzgusLx.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-IBgsJ7BK.js → Backup-CU8S6qu9.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BmP8_zxy.js → BaseInput-B1pC2gjL.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-urkw8_BF.js → Chat-B6xFp6gD.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Cw44zZbh.js → ChatBubbleRenderer-DxNCLZ_X.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CYboo-__.js → Checkbox-QHw7Vc4U.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DaqR_Ay8.js → Codegen-gdecsfjg.js} +1 -1
- package/src/assets/web-panel/assets/{Col-04BSIj_z.js → Col-B0_JmAmc.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DxFk7Trv.js → Community-DRCcP5xR.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-mjgWlMCB.js → Compact-DZtoGzhX.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CC5ee7QV.js → Compliance-BfNTvEnT.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BK4BhHZd.js → Cowork-CDXTLm84.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-CP6jAxq0.js → Cron-Big35CbN.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DJPaViZS.js → Crosschain-C8ArrAVr.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BTLxkuOj.js → DID-D_77BI2O.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Djkiqh3d.js → Dashboard-D2SxTzEp.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-t_eUhqom.js → Dropdown-mR1-b9ud.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-7w6USx_J.js → EmailListRenderer-DPl7TE1c.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-mU5IHEk5.js → EvolutionSettings-BxRYLRSH.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BCh-VBBC.js → FamilyGuardDashboard-rnGtXJ5Z.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Be_VpjI2.js → Federation-BpxenYK8.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-D_lzQ7PI.js → FormItemContext-Cz1kDf6l.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-LYu3KapV.js → GenericCardRenderer-CGV3KN6U.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BBeF-PP4.js → Git-CIRP4UTx.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CoF8Kzg7.js → Governance-DX4r8Vmt.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-C4DLMnXS.js → Inference-DQKk02Hl.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B2mlNewk.js → KnowledgeGraph-DdD6J-By.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DMZ_44Ya.js → Logs-DA2w-1_m.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-Ck7Iv_9e.js → MarkdownRenderer-C9aSGETh.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BqDzTew_.js → Marketplace-BsJ6_6KW.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BbwSbDN9.js → McpTools-_6k30z6u.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-DAaTWgrm.js → Memory-C0_dYY0A.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BjbTGxoR.js → MobileBridge-CCTnVqiC.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DMODOBr-.js → MobileProjects-RZdxDSwC.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DT9N2rCs.js → Mtc-D4Ys8lvX.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-DagMfUVv.js → MtcAudit-BKTC--a2.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-C1BKP6nM.js → Multisig-CGR1qOe1.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-B5LFh72i.js → NLProgramming-hKKD4qWb.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Q77V3ltW.js → Notes-pCn7Ec40.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-HxdpNIBs.js → NotificationSettings-B9eEJXEs.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Dc0DpvBH.js → OrderTableRenderer-CmJuhaT2.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-QL3NZ7uW.js → Organization-CcQbrnwW.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-B_gqOKho.js → Overflow-HmD4Mn72.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BBJubU8Z.js → P2P-B7LIgx5H.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CFnGd-2E.js → PdhVaultBrowser-CXiHnBfX.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BKkznIUM.js → Permissions-CQRI3y_l.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DYK7ZAcd.js → PersonalDataHub-1EeHmsy5.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-CoeKpjoN.js → Pipeline-BFyoIdn8.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Diw4G-92.js → Privacy-BxWthXMF.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CHBOFkma.js → ProjectInit-DfigBilu.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BJIsgdOf.js → ProjectSettings-CFmIcVc-.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CR7H59v3.js +1 -0
- package/src/assets/web-panel/assets/{Providers-o8QCimor.js → Providers-2ulom-76.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-z2W-zvhW.js → QrScannerModal-BwhO07b_.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-_yubhsna.js → QuickAsk-_Wg34OwF.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CucgJwih.js → Recommend-D_jq6Svg.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-EzfIIRg1.js → RemoteSession-BlzvEfsa.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-_shttE67.js → Reputation-9CTXHfL4.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DQA_S8-9.js → Row-DlCYCN-t.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BOqWawXT.js → RssFeed-BvlInFCH.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Dx1v2xOq.js → Search-CfaUzKuL.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Bt4HHsT4.js → Security-bAWgLyve.js} +4 -4
- package/src/assets/web-panel/assets/{Services-sruHiQ-r.js → Services-C4LOGACW.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CiBxvmOJ.js → Skeleton-Dd0Uwh3_.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-De9qKODU.js → Skills-ZYF1kYCU.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-B_6yn8Wp.js → Sla-DpsmIaEo.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-C2CafExS.js → SpeechSettings-BBXoJ4yc.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Dhh3Qmb0.js → SyncSettings-SOnROi2Y.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Mvo5mTWm.js → Tasks-HFA_ZlDk.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D7WVTQQy.js → Templates-fsK-RCEc.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-7ur9Yfxd.js → Tenant-CuqYxamb.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BgzrOA6k.js → Terminal-GKlI2R5F.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-Dco20pT1.js → TimelineRenderer-DMDMHLeY.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-hN6qBPag.js → Tokens-BoV60rh3.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-C4f_twAM.js → Trigger-CE344-Ws.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Wf1SMypp.js → Trust-DENwgkVc.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DUXSyg3N.js → UkeySign-FrcM7yfm.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BvqsJaL0.js → VideoEditing-DAY9WaC2.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CgAbcjKl.js → Wallet-BuUR5i82.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DaLT0W3s.js → WebAuthn-nfSQuq85.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-CQqAXoaS.js → WorkflowEditor-DHhPOp9l.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BhlohFTB.js → chat-C4nsLzYy.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D7HqXIL8.js → colors-BwXH0Wjn.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Bqk4FCLY.js → compact-item-uApFG30S.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CEmWrWf0.js → createContext-BpyYs4fe.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Bk6HGn3N.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CDY0pFi2.js → hasIn-MXCLi00p.js} +1 -1
- package/src/assets/web-panel/assets/{index-e9oCy7_4.js → index-1LxX2IwJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEzL7s7P.js → index-61CBBrHE.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0nfNmbq.js → index-B0P1Z_oa.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiLu-ImR.js → index-B7jojVc7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqK0J4Sj.js → index-BEGMfaOo.js} +1 -1
- package/src/assets/web-panel/assets/{index-aBHlgMrq.js → index-BOhjapd5.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPBoWNwq.js → index-BaBwXpAp.js} +1 -1
- package/src/assets/web-panel/assets/index-Bb1LPYdi.js +1 -0
- package/src/assets/web-panel/assets/{index-BxXFRLTZ.js → index-Btv--Nnt.js} +1 -1
- package/src/assets/web-panel/assets/index-C-FsTuFG.js +1 -0
- package/src/assets/web-panel/assets/{index-BxYO6nde.js → index-CF0bUOP4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGKRAO61.js → index-CNjUPfJP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkjgSHVz.js → index-CRmNdEk_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CrsM-oiD.js → index-C_oOpXhP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNrvBWDS.js → index-ChUTKrOq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYcjOnDX.js → index-CiIpIYhs.js} +1 -1
- package/src/assets/web-panel/assets/{index-C02yDu4f.js → index-CwVvk2i7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmKdCWq1.js → index-D3_tj06B.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkqBoCiu.js → index-DE4W4vLO.js} +3 -3
- package/src/assets/web-panel/assets/{index-B8L3_-sG.js → index-DLxKx5_J.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dwob5XoD.js → index-DTXi_gQh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuMt3ewl.js → index-Daco83me.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpI1LqJX.js → index-DffWVpZv.js} +1 -1
- package/src/assets/web-panel/assets/{index-lBAbMOzg.js → index-Dkncxel3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRcDWMwP.js → index-Dn12gJJU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVrwozwH.js → index-Dt-nq2eF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3opQg47.js → index-Du01X9N9.js} +1 -1
- package/src/assets/web-panel/assets/{index-o_lc3eww.js → index-DucLR6YX.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cur88hoN.js → index-Gz2rGWef.js} +1 -1
- package/src/assets/web-panel/assets/{index-XErJQ1yF.js → index-IvgszJ3C.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuKGuH_y.js → index-S80LLjdx.js} +1 -1
- package/src/assets/web-panel/assets/{index-Chxt0t-A.js → index-WKbnwbKa.js} +1 -1
- package/src/assets/web-panel/assets/{index-1HBam9t1.js → index-XHBXtvqp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXRooi-O.js → index-nn22NSDK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHGOdvOQ.js → index-pCIAE2yS.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf1ha8l0.js → index-pRpMLhMt.js} +1 -1
- package/src/assets/web-panel/assets/{index-6f6n0KFR.js → index-pgHGBAoF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPmRkxeX.js → index-ugIUt5TL.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9mvnSii.js → index-xLGf7f9K.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CIeEUxIN.js → initDefaultProps-C58CkKEo.js} +1 -1
- package/src/assets/web-panel/assets/{motion-IPIj1ZtP.js → motion-BLWPO2NV.js} +1 -1
- package/src/assets/web-panel/assets/{move-BfSeXZ-f.js → move-BgrFMwYp.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DX03-Xp4.js → mtc-parser-Cq2AuGzl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-z9EannfX.js → omit-Bb-9L7if.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DXKmRkqZ.js → pickAttrs-vLmOxYr1.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-k2HV7cIU.js → placementArrow-BNySU_dJ.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-bX7CsyWy.js → responsiveObserve-xnbwagnm.js} +1 -1
- package/src/assets/web-panel/assets/{slide-NskjQLbJ.js → slide-BccbY5Cn.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-B3IoG-Er.js → statusUtils-DOp9d2-w.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DHv_UilX.js → styleChecker-Bu1w6ho9.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DEqGB5Ng.js → useFlexGapSupport-ZsUOrVdL.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Bl9CbrqZ.js → useFs-C0zpzKtO.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-O-Ukv93M.js → usePersonalDataHub-DO1OdgXK.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-hGCHTaZt.js → vnode-jTIRyhR5.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BWhIVeKQ.js → zoom-DKvS7-Qs.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +56 -20
- package/src/commands/ask.js +6 -4
- package/src/commands/batch.js +17 -12
- package/src/commands/eval.js +24 -8
- package/src/commands/team.js +28 -19
- package/src/data/changelog.json +26 -0
- package/src/harness/mcp-client.js +187 -26
- package/src/harness/prompt-compressor.js +2 -0
- package/src/lib/advisor-runtime.js +4 -2
- package/src/lib/agent-ipc-bus.js +2 -0
- package/src/lib/background-agent-keeper-client.js +3 -0
- package/src/lib/background-session-transport.js +21 -5
- package/src/lib/browser-automation.js +4 -0
- package/src/lib/cc-android-bridge.js +4 -0
- package/src/lib/chat-core.js +11 -9
- package/src/lib/cloud/cloud-client.js +10 -1
- package/src/lib/cowork-adapter.js +4 -3
- package/src/lib/decision-layer/providers.js +16 -11
- package/src/lib/decision-layer/runtime.js +180 -10
- package/src/lib/direct-model-usage.js +34 -0
- package/src/lib/evolution/agent-evolution-ingress.js +63 -7
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +10 -0
- package/src/lib/evolution/evolution-evidence-projector.js +46 -7
- package/src/lib/evolution/governed-hub-llm.js +31 -16
- package/src/lib/evolution/governed-hub-resolver.js +4 -0
- package/src/lib/evolution/governed-skill-synthesis-process-grader.js +4 -0
- package/src/lib/evolution/skill-decision-projection.js +211 -0
- package/src/lib/evolution/skill-retrieval-revocation-authority.js +17 -2
- package/src/lib/evomap-client.js +14 -2
- package/src/lib/formal-budget-authority.js +191 -59
- package/src/lib/formal-budget-contract.js +7 -13
- package/src/lib/formal-budget-errors.js +31 -0
- package/src/lib/formal-budget-lineage-registry.js +612 -0
- package/src/lib/formal-budget-provider-scope.js +143 -0
- package/src/lib/formal-budget-transport.js +235 -100
- package/src/lib/gateway-client-resilience.js +5 -0
- package/src/lib/hub-llm-client.js +25 -16
- package/src/lib/llm-connection-probe.js +17 -10
- package/src/lib/llm-providers.js +4 -1
- package/src/lib/model-failure-policy.js +2 -0
- package/src/lib/plugin-runtime/marketplace-network.js +9 -5
- package/src/lib/process-execution-broker/credential-agent.js +7 -2
- package/src/lib/process-execution-broker/credential-transport.js +4 -0
- package/src/lib/process-execution-broker/index.js +8 -0
- package/src/lib/provider-stream.js +28 -13
- package/src/lib/sandbox-egress-worker.js +3 -0
- package/src/lib/skill-loader.js +16 -0
- package/src/lib/stream-retry.js +2 -0
- package/src/lib/sub-agent-context.js +6 -3
- package/src/lib/web-fetch.js +2 -0
- package/src/lib/web-search.js +5 -0
- package/src/repl/agent-repl.js +86 -7
- package/src/runtime/agent-core.js +141 -22
- package/src/runtime/headless-runner.js +212 -22
- package/src/runtime/headless-stream.js +189 -25
- package/src/runtime/mcp-config.js +26 -17
- package/src/runtime/mcp-tool-search.js +44 -14
- package/src/assets/web-panel/assets/Projects-GJjItXIk.js +0 -1
- package/src/assets/web-panel/assets/devWarning-YPX_TU7w.js +0 -1
- package/src/assets/web-panel/assets/index-D53szVZQ.js +0 -1
- package/src/assets/web-panel/assets/index-Ub2nJbV2.js +0 -1
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
providerFetch,
|
|
3
|
+
requireUnscopedToolExecution,
|
|
4
|
+
} from "../lib/formal-budget-provider-scope.js";
|
|
5
|
+
import { isFormalBudgetError } from "../lib/formal-budget-errors.js";
|
|
1
6
|
/**
|
|
2
7
|
* Agent Core — transport-independent agentic logic
|
|
3
8
|
*
|
|
@@ -2613,6 +2618,7 @@ function snapshotApprovalPolicyAuthority(approvalGate, sessionId) {
|
|
|
2613
2618
|
* @returns {Promise<object>} tool result
|
|
2614
2619
|
*/
|
|
2615
2620
|
export async function executeTool(name, args, context = {}) {
|
|
2621
|
+
requireUnscopedToolExecution();
|
|
2616
2622
|
const liveExecutionContext = context;
|
|
2617
2623
|
try {
|
|
2618
2624
|
const executionPolicy = captureAgentExecutionPolicy(context);
|
|
@@ -7851,6 +7857,7 @@ async function executeToolInner(
|
|
|
7851
7857
|
});
|
|
7852
7858
|
return attachDescriptor(result);
|
|
7853
7859
|
} catch (err) {
|
|
7860
|
+
if (isFormalBudgetError(err)) throw err;
|
|
7854
7861
|
return attachDescriptor({ error: `web_search failed: ${err.message}` });
|
|
7855
7862
|
}
|
|
7856
7863
|
}
|
|
@@ -9172,6 +9179,7 @@ async function executeToolInner(
|
|
|
9172
9179
|
} catch (err) {
|
|
9173
9180
|
if (
|
|
9174
9181
|
isEvolutionIngressFailure(err) ||
|
|
9182
|
+
isFormalBudgetError(err) ||
|
|
9175
9183
|
err?.runtimeLedgerPersistence === true ||
|
|
9176
9184
|
err?.workflowEffectOutcomeUnknown === true
|
|
9177
9185
|
) {
|
|
@@ -9281,24 +9289,122 @@ async function executeToolInner(
|
|
|
9281
9289
|
? null
|
|
9282
9290
|
: captureSkillDecisionRuntime(skillDecisionRuntime);
|
|
9283
9291
|
if (decisionRuntime !== null && routing.candidates.length > 0) {
|
|
9284
|
-
const
|
|
9285
|
-
|
|
9286
|
-
|
|
9287
|
-
|
|
9292
|
+
const decisionInputsFor = (result, descriptors) => {
|
|
9293
|
+
const descriptorsByDigest = new Map(
|
|
9294
|
+
descriptors.map((skill) => [
|
|
9295
|
+
skill.executionIdentity?.contentDigest,
|
|
9296
|
+
skill,
|
|
9297
|
+
]),
|
|
9298
|
+
);
|
|
9299
|
+
return result.candidates.slice(0, 5).map((candidate) => {
|
|
9300
|
+
const descriptor = descriptorsByDigest.get(candidate.digest);
|
|
9288
9301
|
return {
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9302
|
+
candidate: {
|
|
9303
|
+
id: candidate.id,
|
|
9304
|
+
displayName: candidate.displayName,
|
|
9305
|
+
description: descriptor?.description || candidate.displayName,
|
|
9306
|
+
category: candidate.category,
|
|
9307
|
+
digest: candidate.digest,
|
|
9308
|
+
tags: Array.isArray(descriptor?.tags)
|
|
9309
|
+
? [...descriptor.tags]
|
|
9310
|
+
: [],
|
|
9311
|
+
},
|
|
9312
|
+
// Scope and compatibility are local routing inputs. They never
|
|
9313
|
+
// leave the process, but changes invalidate the old advice.
|
|
9314
|
+
identity: {
|
|
9315
|
+
namespace: candidate.namespace,
|
|
9316
|
+
version: candidate.version,
|
|
9317
|
+
paths: descriptor?.paths ?? null,
|
|
9318
|
+
os: descriptor?.os ?? null,
|
|
9319
|
+
capabilities: descriptor?.capabilities ?? null,
|
|
9320
|
+
},
|
|
9295
9321
|
};
|
|
9296
|
-
})
|
|
9322
|
+
});
|
|
9323
|
+
};
|
|
9324
|
+
const decisionInputs = decisionInputsFor(routing, skills);
|
|
9325
|
+
const snapshotFor = (result, inputs) =>
|
|
9326
|
+
JSON.stringify({
|
|
9327
|
+
candidates: inputs,
|
|
9328
|
+
selectedDigest: result.selected?.digest ?? null,
|
|
9329
|
+
conflicts: result.conflicts,
|
|
9330
|
+
});
|
|
9331
|
+
const decisionSnapshot = snapshotFor(routing, decisionInputs);
|
|
9332
|
+
const contextRevision = `routing-${createHash("sha256")
|
|
9333
|
+
.update(
|
|
9334
|
+
JSON.stringify({
|
|
9335
|
+
query: args.query,
|
|
9336
|
+
category: args.category ?? null,
|
|
9337
|
+
cwd,
|
|
9338
|
+
turnId: turnId || toolCallId || "list-skills",
|
|
9339
|
+
toolCallId: toolCallId ?? null,
|
|
9340
|
+
decisionSnapshot,
|
|
9341
|
+
}),
|
|
9342
|
+
)
|
|
9343
|
+
.digest("hex")}`;
|
|
9344
|
+
const decision = await decisionRuntime.suggest({
|
|
9345
|
+
query: args.query,
|
|
9346
|
+
candidates: decisionInputs.map(({ candidate }) => candidate),
|
|
9297
9347
|
turnId: turnId || toolCallId || "list-skills",
|
|
9298
|
-
contextRevision
|
|
9348
|
+
contextRevision,
|
|
9299
9349
|
signal,
|
|
9300
9350
|
});
|
|
9301
|
-
|
|
9351
|
+
signal?.throwIfAborted();
|
|
9352
|
+
// The provider result belongs to the captured candidate set. Recheck
|
|
9353
|
+
// the persisted revocations and live loader before exposing advice.
|
|
9354
|
+
await skillRetrievalRevocationReader?.refresh();
|
|
9355
|
+
signal?.throwIfAborted();
|
|
9356
|
+
const refreshedSkills =
|
|
9357
|
+
typeof skillLoader.refreshResolvedSkills === "function"
|
|
9358
|
+
? await skillLoader.refreshResolvedSkills()
|
|
9359
|
+
: skillLoader.getResolvedSkills();
|
|
9360
|
+
signal?.throwIfAborted();
|
|
9361
|
+
let currentSkills = await filterSkillsByCwd(
|
|
9362
|
+
refreshedSkills.filter(skillAllowed),
|
|
9363
|
+
cwd,
|
|
9364
|
+
);
|
|
9365
|
+
if (args.category) {
|
|
9366
|
+
currentSkills = currentSkills.filter(
|
|
9367
|
+
(s) => s.category.toLowerCase() === args.category.toLowerCase(),
|
|
9368
|
+
);
|
|
9369
|
+
}
|
|
9370
|
+
// The vector index can change while the decision provider is in
|
|
9371
|
+
// flight. Score the refreshed corpus again before comparing routing.
|
|
9372
|
+
vector =
|
|
9373
|
+
vectorAuthority === null
|
|
9374
|
+
? null
|
|
9375
|
+
: await vectorAuthority.score({
|
|
9376
|
+
query: args.query,
|
|
9377
|
+
skills: currentSkills,
|
|
9378
|
+
});
|
|
9379
|
+
signal?.throwIfAborted();
|
|
9380
|
+
const currentRouting = routeSkillDescriptors({
|
|
9381
|
+
skills: currentSkills,
|
|
9382
|
+
query: args.query,
|
|
9383
|
+
target: { os: process.platform },
|
|
9384
|
+
vectorScores: vector?.scores ?? null,
|
|
9385
|
+
outcomeMetrics: outcomeAuthority.metrics,
|
|
9386
|
+
revocationReader: skillRetrievalRevocationReader ?? null,
|
|
9387
|
+
topK: Math.min(64, Math.max(1, currentSkills.length)),
|
|
9388
|
+
});
|
|
9389
|
+
const currentByDigest = new Map(
|
|
9390
|
+
currentSkills.map((skill) => [
|
|
9391
|
+
skill.executionIdentity?.contentDigest,
|
|
9392
|
+
skill,
|
|
9393
|
+
]),
|
|
9394
|
+
);
|
|
9395
|
+
const currentDecisionSnapshot = snapshotFor(
|
|
9396
|
+
currentRouting,
|
|
9397
|
+
decisionInputsFor(currentRouting, currentSkills),
|
|
9398
|
+
);
|
|
9399
|
+
routing = currentRouting;
|
|
9400
|
+
skills = routing.candidates
|
|
9401
|
+
.map(({ digest }) => currentByDigest.get(digest))
|
|
9402
|
+
.filter(Boolean);
|
|
9403
|
+
signal?.throwIfAborted();
|
|
9404
|
+
if (
|
|
9405
|
+
decision.visible &&
|
|
9406
|
+
currentDecisionSnapshot === decisionSnapshot
|
|
9407
|
+
) {
|
|
9302
9408
|
routing = Object.freeze({
|
|
9303
9409
|
...routing,
|
|
9304
9410
|
decisionSuggestion: Object.freeze({
|
|
@@ -10643,6 +10749,7 @@ function _throwBackgroundSubAgentUsageFailure(entry) {
|
|
|
10643
10749
|
const error = entry?.outcome?.fatalError;
|
|
10644
10750
|
if (
|
|
10645
10751
|
isEvolutionIngressFailure(error) ||
|
|
10752
|
+
isFormalBudgetError(error) ||
|
|
10646
10753
|
error?.runtimeLedgerPersistence === true ||
|
|
10647
10754
|
error?.workflowEffectOutcomeUnknown === true
|
|
10648
10755
|
) {
|
|
@@ -11621,6 +11728,7 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
11621
11728
|
result: subCtx.result,
|
|
11622
11729
|
error: err.message,
|
|
11623
11730
|
...(isEvolutionIngressFailure(err) ||
|
|
11731
|
+
isFormalBudgetError(err) ||
|
|
11624
11732
|
err?.runtimeLedgerPersistence === true ||
|
|
11625
11733
|
err?.workflowEffectOutcomeUnknown === true
|
|
11626
11734
|
? { fatalError: err }
|
|
@@ -11757,6 +11865,7 @@ async function _executeSpawnSubAgent(args, ctx) {
|
|
|
11757
11865
|
|
|
11758
11866
|
if (
|
|
11759
11867
|
isEvolutionIngressFailure(err) ||
|
|
11868
|
+
isFormalBudgetError(err) ||
|
|
11760
11869
|
err?.runtimeLedgerPersistence === true ||
|
|
11761
11870
|
err?.workflowEffectOutcomeUnknown === true
|
|
11762
11871
|
) {
|
|
@@ -12000,7 +12109,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12000
12109
|
},
|
|
12001
12110
|
);
|
|
12002
12111
|
}
|
|
12003
|
-
const response = await
|
|
12112
|
+
const response = await providerFetch(apiUrl, {
|
|
12004
12113
|
method: "POST",
|
|
12005
12114
|
headers: { "Content-Type": "application/json" },
|
|
12006
12115
|
signal,
|
|
@@ -12156,7 +12265,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12156
12265
|
);
|
|
12157
12266
|
}
|
|
12158
12267
|
|
|
12159
|
-
const response = await
|
|
12268
|
+
const response = await providerFetch(`${url}/messages`, {
|
|
12160
12269
|
method: "POST",
|
|
12161
12270
|
headers: {
|
|
12162
12271
|
"Content-Type": "application/json",
|
|
@@ -12312,7 +12421,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12312
12421
|
);
|
|
12313
12422
|
}
|
|
12314
12423
|
|
|
12315
|
-
const response = await
|
|
12424
|
+
const response = await providerFetch(`${url}/responses`, {
|
|
12316
12425
|
method: "POST",
|
|
12317
12426
|
headers: {
|
|
12318
12427
|
"Content-Type": "application/json",
|
|
@@ -12390,7 +12499,7 @@ export async function chatWithTools(rawMessages, options) {
|
|
|
12390
12499
|
);
|
|
12391
12500
|
}
|
|
12392
12501
|
|
|
12393
|
-
const response = await
|
|
12502
|
+
const response = await providerFetch(`${url}/chat/completions`, {
|
|
12394
12503
|
method: "POST",
|
|
12395
12504
|
headers: {
|
|
12396
12505
|
"Content-Type": "application/json",
|
|
@@ -12627,6 +12736,7 @@ export function _streamErrorDisposition(
|
|
|
12627
12736
|
partialText,
|
|
12628
12737
|
visible = false,
|
|
12629
12738
|
) {
|
|
12739
|
+
if (isFormalBudgetError(err)) return "rethrow";
|
|
12630
12740
|
if (err?.isOutputBackpressureFailure === true) return "rethrow";
|
|
12631
12741
|
if (isAbortError(err)) return "rethrow";
|
|
12632
12742
|
if (signal && signal.aborted) return "rethrow";
|
|
@@ -12871,7 +12981,7 @@ async function _chatOllamaStreaming(
|
|
|
12871
12981
|
stallMs,
|
|
12872
12982
|
stallTimeoutMs,
|
|
12873
12983
|
) {
|
|
12874
|
-
const response = await
|
|
12984
|
+
const response = await providerFetch(apiUrl, {
|
|
12875
12985
|
method: "POST",
|
|
12876
12986
|
headers: { "Content-Type": "application/json" },
|
|
12877
12987
|
signal,
|
|
@@ -12933,7 +13043,7 @@ async function _chatAnthropicStreaming(
|
|
|
12933
13043
|
stallMs,
|
|
12934
13044
|
stallTimeoutMs,
|
|
12935
13045
|
) {
|
|
12936
|
-
const response = await
|
|
13046
|
+
const response = await providerFetch(apiUrl, {
|
|
12937
13047
|
method: "POST",
|
|
12938
13048
|
headers: { "Content-Type": "application/json", ...extraHeaders },
|
|
12939
13049
|
signal,
|
|
@@ -13000,7 +13110,7 @@ async function _chatOpenAIStreaming(
|
|
|
13000
13110
|
stallTimeoutMs,
|
|
13001
13111
|
providerRequestId = null,
|
|
13002
13112
|
) {
|
|
13003
|
-
const response = await
|
|
13113
|
+
const response = await providerFetch(apiUrl, {
|
|
13004
13114
|
method: "POST",
|
|
13005
13115
|
headers: {
|
|
13006
13116
|
"Content-Type": "application/json",
|
|
@@ -13083,7 +13193,7 @@ async function _chatOpenAIResponsesStreaming(
|
|
|
13083
13193
|
stallTimeoutMs,
|
|
13084
13194
|
providerRequestId = null,
|
|
13085
13195
|
) {
|
|
13086
|
-
const response = await
|
|
13196
|
+
const response = await providerFetch(apiUrl, {
|
|
13087
13197
|
method: "POST",
|
|
13088
13198
|
headers: {
|
|
13089
13199
|
"Content-Type": "application/json",
|
|
@@ -15479,6 +15589,7 @@ export async function* agentLoop(messages, options) {
|
|
|
15479
15589
|
}
|
|
15480
15590
|
} catch (_e) {
|
|
15481
15591
|
if (isAbortError(_e) || signal?.aborted) throw _e;
|
|
15592
|
+
if (isFormalBudgetError(_e)) throw _e;
|
|
15482
15593
|
if (_e?.runtimeLedgerPersistence === true) throw _e;
|
|
15483
15594
|
if (_e?.code === "CC_AGENT_EVOLUTION_INGRESS_FAILED") throw _e;
|
|
15484
15595
|
if (
|
|
@@ -15911,6 +16022,7 @@ export async function* agentLoop(messages, options) {
|
|
|
15911
16022
|
];
|
|
15912
16023
|
}
|
|
15913
16024
|
} catch (_e) {
|
|
16025
|
+
if (isFormalBudgetError(_e)) throw _e;
|
|
15914
16026
|
// prepareCall failures are non-critical — proceed with original messages
|
|
15915
16027
|
}
|
|
15916
16028
|
}
|
|
@@ -16511,6 +16623,7 @@ export async function* agentLoop(messages, options) {
|
|
|
16511
16623
|
: {}),
|
|
16512
16624
|
},
|
|
16513
16625
|
error: err.message,
|
|
16626
|
+
fatalError: isFormalBudgetError(err) ? err : null,
|
|
16514
16627
|
}),
|
|
16515
16628
|
);
|
|
16516
16629
|
return { call, toolArgs, workflowBinding, promise };
|
|
@@ -16518,7 +16631,12 @@ export async function* agentLoop(messages, options) {
|
|
|
16518
16631
|
for (const { call, toolArgs, workflowBinding, promise } of inflight) {
|
|
16519
16632
|
throwIfAborted(signal);
|
|
16520
16633
|
_throwBackgroundUsageFailureState(backgroundUsageFailureState);
|
|
16521
|
-
const {
|
|
16634
|
+
const {
|
|
16635
|
+
result: toolResult,
|
|
16636
|
+
error: toolError,
|
|
16637
|
+
fatalError,
|
|
16638
|
+
} = await promise;
|
|
16639
|
+
if (fatalError) throw fatalError;
|
|
16522
16640
|
throwIfAborted(signal);
|
|
16523
16641
|
const taskAdvanced = taskProgressTracker.record(
|
|
16524
16642
|
call.function.name,
|
|
@@ -16961,6 +17079,7 @@ export async function* agentLoop(messages, options) {
|
|
|
16961
17079
|
} catch (err) {
|
|
16962
17080
|
if (
|
|
16963
17081
|
isEvolutionIngressFailure(err) ||
|
|
17082
|
+
isFormalBudgetError(err) ||
|
|
16964
17083
|
err?.runtimeLedgerPersistence === true
|
|
16965
17084
|
)
|
|
16966
17085
|
throw err;
|
|
@@ -57,6 +57,7 @@ import {
|
|
|
57
57
|
appendAuthorityEvent as jsonlAppendAuthorityEvent,
|
|
58
58
|
readEvents as jsonlReadEvents,
|
|
59
59
|
readVerifiedEvents as jsonlReadVerifiedEvents,
|
|
60
|
+
readVerifiedProjection as jsonlReadVerifiedProjection,
|
|
60
61
|
findLatestEvent as jsonlFindLatestEvent,
|
|
61
62
|
rebuildMessages as jsonlRebuildMessages,
|
|
62
63
|
sessionExists as jsonlSessionExists,
|
|
@@ -137,7 +138,9 @@ import executionBroker from "../lib/process-execution-broker/index.js";
|
|
|
137
138
|
import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
|
|
138
139
|
import { formatManagedCheckpointEvent } from "../lib/managed-checkpoint-render.js";
|
|
139
140
|
import {
|
|
141
|
+
normalizeSessionBudgetRootConfig,
|
|
140
142
|
openProductionSessionBudgetRoot,
|
|
143
|
+
readProductionSessionBudget,
|
|
141
144
|
sessionBudgetAdmissionError,
|
|
142
145
|
} from "../lib/session-budget-production-root.js";
|
|
143
146
|
import {
|
|
@@ -288,6 +291,74 @@ export function resolveHeadlessSkillDecisionOptions(options = {}) {
|
|
|
288
291
|
});
|
|
289
292
|
}
|
|
290
293
|
|
|
294
|
+
function createDecisionUsageRecoveryProjection() {
|
|
295
|
+
const started = new Map();
|
|
296
|
+
const seenCallIds = new Set();
|
|
297
|
+
let blocked = false;
|
|
298
|
+
return {
|
|
299
|
+
accept(event) {
|
|
300
|
+
if (blocked) return;
|
|
301
|
+
const data = event?.data;
|
|
302
|
+
const callId = data?.callId;
|
|
303
|
+
const isDecision =
|
|
304
|
+
typeof data?.operationId === "string" &&
|
|
305
|
+
data.operationId.startsWith("decision:");
|
|
306
|
+
if (event?.type === "model_usage_started" && isDecision) {
|
|
307
|
+
if (typeof callId !== "string" || !callId || seenCallIds.has(callId)) {
|
|
308
|
+
blocked = true;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
let boundary;
|
|
312
|
+
try {
|
|
313
|
+
boundary = projectRuntimeUsageBoundary(data, "started");
|
|
314
|
+
} catch {
|
|
315
|
+
blocked = true;
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
seenCallIds.add(callId);
|
|
319
|
+
started.set(callId, boundary);
|
|
320
|
+
} else if (
|
|
321
|
+
event?.type === "model_usage_unknown" &&
|
|
322
|
+
(isDecision || started.has(callId))
|
|
323
|
+
) {
|
|
324
|
+
blocked = true;
|
|
325
|
+
} else if (event?.type === "token_usage" && started.has(callId)) {
|
|
326
|
+
let settlement;
|
|
327
|
+
try {
|
|
328
|
+
settlement = projectRuntimeTokenUsage(data);
|
|
329
|
+
} catch {
|
|
330
|
+
blocked = true;
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
const boundary = started.get(callId);
|
|
334
|
+
if (
|
|
335
|
+
settlement.callId !== boundary.callId ||
|
|
336
|
+
settlement.operationId !== boundary.operationId ||
|
|
337
|
+
settlement.provider !== boundary.provider ||
|
|
338
|
+
settlement.model !== boundary.model ||
|
|
339
|
+
settlement.source !== boundary.source
|
|
340
|
+
) {
|
|
341
|
+
blocked = true;
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
started.delete(callId);
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
finish() {
|
|
348
|
+
return blocked || started.size > 0;
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function hasUnreconciledDecisionUsage(events) {
|
|
354
|
+
if (!Array.isArray(events)) return true;
|
|
355
|
+
const projection = createDecisionUsageRecoveryProjection();
|
|
356
|
+
for (const event of events) {
|
|
357
|
+
projection.accept(event);
|
|
358
|
+
}
|
|
359
|
+
return projection.finish();
|
|
360
|
+
}
|
|
361
|
+
|
|
291
362
|
/**
|
|
292
363
|
* Resolve a --permission-mode string into the session-policy tier + a
|
|
293
364
|
* non-interactive confirmer + whether to clamp tools to the read-only set.
|
|
@@ -500,6 +571,7 @@ export function applyForkSession(opts = {}, store = {}) {
|
|
|
500
571
|
*/
|
|
501
572
|
const HEADLESS_SESSION_RESOLUTION = Symbol("headlessSessionResolution");
|
|
502
573
|
const HEADLESS_SESSION_HOST_LEASE = Symbol("headlessSessionHostLease");
|
|
574
|
+
const HEADLESS_CANONICAL_ADMISSION = Symbol("headlessCanonicalAdmission");
|
|
503
575
|
const HEADLESS_HOOK_EVENT_CLEANUP = Symbol("headlessHookEventCleanup");
|
|
504
576
|
const HOST_EVENT_BACKLOG_CODE = "CC_HOST_EVENT_BACKLOG_EXHAUSTED";
|
|
505
577
|
const HOST_EVENT_BACKLOG_ERROR =
|
|
@@ -528,6 +600,7 @@ async function withHeadlessSessionHostLease(options, deps, task) {
|
|
|
528
600
|
let lease = null;
|
|
529
601
|
let budgetRoot = null;
|
|
530
602
|
let scopedOptions = options;
|
|
603
|
+
let preflightAdmission;
|
|
531
604
|
try {
|
|
532
605
|
// Session authority/lease/budget setup can lazily initialize AppConfig and
|
|
533
606
|
// DatabaseManager. Those legacy diagnostics use console.info (stdout), and
|
|
@@ -589,13 +662,101 @@ async function withHeadlessSessionHostLease(options, deps, task) {
|
|
|
589
662
|
: lease.signal,
|
|
590
663
|
}
|
|
591
664
|
: options;
|
|
665
|
+
const canReadCanonical =
|
|
666
|
+
!hasInjectedSessionStore ||
|
|
667
|
+
typeof deps.readVerifiedEvents === "function";
|
|
668
|
+
if (
|
|
669
|
+
authoritySessionId &&
|
|
670
|
+
!canReadCanonical &&
|
|
671
|
+
(deps.sessionBudgetStore || options.sessionBudgetRoot?.enabled) &&
|
|
672
|
+
(resolution.resumeId ||
|
|
673
|
+
deps.sessionExists?.(authoritySessionId) !== false)
|
|
674
|
+
) {
|
|
675
|
+
throw Object.assign(
|
|
676
|
+
new Error("budgeted resume requires verified session events"),
|
|
677
|
+
{ code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
|
|
678
|
+
);
|
|
679
|
+
}
|
|
680
|
+
if (authoritySessionId && canReadCanonical) {
|
|
681
|
+
preflightAdmission = readSessionHostResumeState(authoritySessionId, {
|
|
682
|
+
sessionHasPersistedEvidence:
|
|
683
|
+
deps.sessionHasPersistedEvidence ||
|
|
684
|
+
(!hasInjectedSessionStore
|
|
685
|
+
? jsonlSessionHasPersistedEvidence
|
|
686
|
+
: undefined),
|
|
687
|
+
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
688
|
+
readVerifiedEvents:
|
|
689
|
+
deps.readVerifiedEvents || jsonlReadVerifiedEvents,
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
if (preflightAdmission && !preflightAdmission.snapshot.verified) {
|
|
693
|
+
// The inner runner reports the canonical failure without opening or
|
|
694
|
+
// mutating a budget sidecar for an unverified transcript.
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
const sidecar =
|
|
698
|
+
authoritySessionId &&
|
|
699
|
+
(process.platform === "linux" || deps.sessionBudgetStore)
|
|
700
|
+
? readProductionSessionBudget(authoritySessionId, {
|
|
701
|
+
store: deps.sessionBudgetStore,
|
|
702
|
+
})
|
|
703
|
+
: null;
|
|
704
|
+
if (!preflightAdmission && !hasInjectedSessionStore && sidecar) {
|
|
705
|
+
throw Object.assign(
|
|
706
|
+
new Error("budget sidecar has no canonical JSONL session"),
|
|
707
|
+
{ code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
let effectiveBudgetConfig = options.sessionBudgetRoot;
|
|
711
|
+
if (preflightAdmission) {
|
|
712
|
+
const canonicalConfig = preflightAdmission.sessionBudgetRoot;
|
|
713
|
+
const requestedConfig = options.sessionBudgetRoot?.enabled
|
|
714
|
+
? normalizeSessionBudgetRootConfig(options.sessionBudgetRoot)
|
|
715
|
+
: null;
|
|
716
|
+
if (canonicalConfig?.enabled) {
|
|
717
|
+
if (!sidecar) {
|
|
718
|
+
throw Object.assign(
|
|
719
|
+
new Error(
|
|
720
|
+
"budgeted session is missing its durable budget sidecar",
|
|
721
|
+
),
|
|
722
|
+
{ code: "CC_SESSION_BUDGET_SIDECAR_REQUIRED" },
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
if (requestedConfig) {
|
|
726
|
+
if (
|
|
727
|
+
JSON.stringify(requestedConfig) !==
|
|
728
|
+
JSON.stringify(canonicalConfig)
|
|
729
|
+
) {
|
|
730
|
+
throw Object.assign(
|
|
731
|
+
new Error(
|
|
732
|
+
"session budget does not match its JSONL declaration",
|
|
733
|
+
),
|
|
734
|
+
{ code: "CC_SESSION_BUDGET_CONFIG_MISMATCH" },
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
} else {
|
|
738
|
+
effectiveBudgetConfig = canonicalConfig;
|
|
739
|
+
}
|
|
740
|
+
} else if (requestedConfig || sidecar) {
|
|
741
|
+
throw Object.assign(
|
|
742
|
+
new Error(
|
|
743
|
+
"existing session has no canonical JSONL budget declaration",
|
|
744
|
+
),
|
|
745
|
+
{ code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
scopedOptions = {
|
|
750
|
+
...scopedOptions,
|
|
751
|
+
sessionBudgetRoot: effectiveBudgetConfig,
|
|
752
|
+
};
|
|
592
753
|
budgetRoot = openProductionSessionBudgetRoot(
|
|
593
754
|
authoritySessionId,
|
|
594
|
-
|
|
755
|
+
effectiveBudgetConfig,
|
|
595
756
|
{
|
|
596
757
|
persist: resolution.persist,
|
|
597
758
|
signal: scopedOptions.signal || null,
|
|
598
|
-
table: options.
|
|
759
|
+
table: effectiveBudgetConfig?.table || options.priceTable,
|
|
599
760
|
open: deps.openSessionBudget,
|
|
600
761
|
store: deps.sessionBudgetStore,
|
|
601
762
|
registry: deps.sessionBudgetRegistry,
|
|
@@ -609,6 +770,7 @@ async function withHeadlessSessionHostLease(options, deps, task) {
|
|
|
609
770
|
...deps,
|
|
610
771
|
[HEADLESS_SESSION_RESOLUTION]: resolution,
|
|
611
772
|
[HEADLESS_SESSION_HOST_LEASE]: lease,
|
|
773
|
+
[HEADLESS_CANONICAL_ADMISSION]: preflightAdmission,
|
|
612
774
|
});
|
|
613
775
|
} finally {
|
|
614
776
|
// Cleanup can touch the same lazy stores. Keep late diagnostics out of a
|
|
@@ -939,18 +1101,20 @@ async function runAgentHeadlessInWorkspace(
|
|
|
939
1101
|
!hasInjectedSessionStore || typeof deps.readVerifiedEvents === "function";
|
|
940
1102
|
const canonicalAdmissionId = resumeId || (persist ? sessionId : null);
|
|
941
1103
|
const canonicalAdmission =
|
|
942
|
-
|
|
943
|
-
?
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
deps.
|
|
952
|
-
|
|
953
|
-
|
|
1104
|
+
deps[HEADLESS_CANONICAL_ADMISSION] !== undefined
|
|
1105
|
+
? deps[HEADLESS_CANONICAL_ADMISSION]
|
|
1106
|
+
: canonicalAdmissionId && canReadCanonicalResume
|
|
1107
|
+
? readSessionHostResumeState(canonicalAdmissionId, {
|
|
1108
|
+
sessionHasPersistedEvidence:
|
|
1109
|
+
deps.sessionHasPersistedEvidence ||
|
|
1110
|
+
(!hasInjectedSessionStore
|
|
1111
|
+
? jsonlSessionHasPersistedEvidence
|
|
1112
|
+
: undefined),
|
|
1113
|
+
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
1114
|
+
readVerifiedEvents:
|
|
1115
|
+
deps.readVerifiedEvents || jsonlReadVerifiedEvents,
|
|
1116
|
+
})
|
|
1117
|
+
: null;
|
|
954
1118
|
if (canonicalAdmission && !canonicalAdmission.snapshot.verified) {
|
|
955
1119
|
const message =
|
|
956
1120
|
"CC_SESSION_HOST_SNAPSHOT_UNVERIFIED: canonical JSONL session is not " +
|
|
@@ -2012,6 +2176,9 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2012
2176
|
provider,
|
|
2013
2177
|
model,
|
|
2014
2178
|
observabilityScope: options.observabilityScope,
|
|
2179
|
+
...(options.sessionBudgetRoot?.enabled === true
|
|
2180
|
+
? { sessionBudgetRoot: options.sessionBudgetRoot }
|
|
2181
|
+
: {}),
|
|
2015
2182
|
executionLocation: captureAmbientExecutionLocation({
|
|
2016
2183
|
provider,
|
|
2017
2184
|
model,
|
|
@@ -2458,13 +2625,35 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2458
2625
|
const skillDecisionOptions = resolveHeadlessSkillDecisionOptions(options);
|
|
2459
2626
|
let skillDecisionRuntime = null;
|
|
2460
2627
|
if (skillDecisionOptions.mode !== "off") {
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2628
|
+
let previousUnreconciledDecisionUsage;
|
|
2629
|
+
if (
|
|
2630
|
+
!hasInjectedSessionStore ||
|
|
2631
|
+
typeof deps.readVerifiedEvents === "function"
|
|
2632
|
+
) {
|
|
2633
|
+
try {
|
|
2634
|
+
previousUnreconciledDecisionUsage = hasInjectedSessionStore
|
|
2635
|
+
? hasUnreconciledDecisionUsage(store.readVerifiedEvents(sessionId))
|
|
2636
|
+
: jsonlReadVerifiedProjection(
|
|
2637
|
+
sessionId,
|
|
2638
|
+
createDecisionUsageRecoveryProjection,
|
|
2639
|
+
);
|
|
2640
|
+
} catch {
|
|
2641
|
+
// Without a verified settlement, a resumed provider call could be paid twice.
|
|
2642
|
+
previousUnreconciledDecisionUsage = true;
|
|
2643
|
+
}
|
|
2644
|
+
} else {
|
|
2645
|
+
// Legacy injected stores cannot prove a prior call was settled. Their
|
|
2646
|
+
// explicit no-session answer still permits a fresh test/embedding run.
|
|
2647
|
+
previousUnreconciledDecisionUsage =
|
|
2648
|
+
store.sessionExists(sessionId) ||
|
|
2649
|
+
store.findLatestEvent(
|
|
2650
|
+
sessionId,
|
|
2651
|
+
"model_usage_unknown",
|
|
2652
|
+
(event) =>
|
|
2653
|
+
typeof event?.data?.operationId === "string" &&
|
|
2654
|
+
event.data.operationId.startsWith("decision:"),
|
|
2655
|
+
) != null;
|
|
2656
|
+
}
|
|
2468
2657
|
const decisionProvider =
|
|
2469
2658
|
deps.decisionProvider ||
|
|
2470
2659
|
createDecisionProvider({
|
|
@@ -2487,11 +2676,12 @@ async function runAgentHeadlessInWorkspace(
|
|
|
2487
2676
|
options.decisionTenantId || evolutionIngress?.tenantId || "cli-local",
|
|
2488
2677
|
sessionId,
|
|
2489
2678
|
provider: decisionProvider,
|
|
2679
|
+
evolutionIngress,
|
|
2490
2680
|
persist: persistDecisionEvent,
|
|
2491
2681
|
observe: (observation) =>
|
|
2492
2682
|
persistDecisionEvent("skill_decision_observation", observation),
|
|
2493
2683
|
sessionBudget: options.sessionBudget || null,
|
|
2494
|
-
initialUsageUnknown:
|
|
2684
|
+
initialUsageUnknown: previousUnreconciledDecisionUsage,
|
|
2495
2685
|
timeoutMs: skillDecisionOptions.timeoutMs,
|
|
2496
2686
|
});
|
|
2497
2687
|
}
|