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,4 +1,5 @@
|
|
|
1
1
|
import { isAbortError } from "./abort-utils.js";
|
|
2
|
+
import { isFormalBudgetError } from "./formal-budget-errors.js";
|
|
2
3
|
|
|
3
4
|
export function isEvolutionIngressFailure(error) {
|
|
4
5
|
const visited = new Set();
|
|
@@ -21,6 +22,7 @@ export function isTerminalModelFailure(error) {
|
|
|
21
22
|
current.code === "CC_AGENT_EVOLUTION_INGRESS_FAILED" ||
|
|
22
23
|
current.runtimeLedgerPersistence === true ||
|
|
23
24
|
current.workflowEffectOutcomeUnknown === true ||
|
|
25
|
+
isFormalBudgetError(current) ||
|
|
24
26
|
/^(?:CC|ERR)_SESSION_BUDGET_/u.test(current.code || "") ||
|
|
25
27
|
isAbortError(current)
|
|
26
28
|
) {
|
|
@@ -3,6 +3,10 @@ import fs from "node:fs";
|
|
|
3
3
|
import tls from "node:tls";
|
|
4
4
|
import { Worker } from "node:worker_threads";
|
|
5
5
|
import { Agent, ProxyAgent, fetch as undiciFetch } from "undici";
|
|
6
|
+
import {
|
|
7
|
+
requireUnscopedDescendantControl,
|
|
8
|
+
requireUnscopedExternalToolAccess,
|
|
9
|
+
} from "../formal-budget-provider-scope.js";
|
|
6
10
|
|
|
7
11
|
export const MAX_MARKETPLACE_CA_BUNDLE_BYTES = 1024 * 1024;
|
|
8
12
|
export const MAX_MARKETPLACE_PROXY_URL_LENGTH = 4096;
|
|
@@ -15,6 +19,7 @@ export const DEFAULT_MARKETPLACE_PAC_TIMEOUT_MS = 2_000;
|
|
|
15
19
|
* deliberately ignored: callers pass CLI flags or CC_PLUGIN_REGISTRY_* values.
|
|
16
20
|
*/
|
|
17
21
|
export function createMarketplaceNetworkTransport(options = {}) {
|
|
22
|
+
requireUnscopedExternalToolAccess();
|
|
18
23
|
const proxy = normalizeProxyUrl(options.proxyUrl);
|
|
19
24
|
const pac = options.pacFile ? readMarketplacePacFile(options.pacFile) : null;
|
|
20
25
|
if (proxy && pac) {
|
|
@@ -49,6 +54,7 @@ export function createMarketplaceNetworkTransport(options = {}) {
|
|
|
49
54
|
|
|
50
55
|
return {
|
|
51
56
|
fetch: async (url, fetchOptions = {}) => {
|
|
57
|
+
requireUnscopedExternalToolAccess();
|
|
52
58
|
const route = pac
|
|
53
59
|
? parsePacResult(
|
|
54
60
|
await resolveMarketplacePac(pac.script, url, {
|
|
@@ -99,11 +105,9 @@ export function readMarketplacePacFile(file) {
|
|
|
99
105
|
};
|
|
100
106
|
}
|
|
101
107
|
|
|
102
|
-
export function resolveMarketplacePac(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
{ timeoutMs = DEFAULT_MARKETPLACE_PAC_TIMEOUT_MS } = {},
|
|
106
|
-
) {
|
|
108
|
+
export function resolveMarketplacePac(script, url, options = {}) {
|
|
109
|
+
requireUnscopedDescendantControl();
|
|
110
|
+
const { timeoutMs = DEFAULT_MARKETPLACE_PAC_TIMEOUT_MS } = options;
|
|
107
111
|
const timeout = Number(timeoutMs);
|
|
108
112
|
if (!Number.isInteger(timeout) || timeout < 100 || timeout > 10_000) {
|
|
109
113
|
throw new Error("Marketplace PAC timeout must be between 100 and 10000 ms");
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import crypto from "node:crypto";
|
|
16
16
|
import { CredentialTransport } from "./credential-transport.js";
|
|
17
|
+
import { requireUnscopedDescendantControl } from "../formal-budget-provider-scope.js";
|
|
17
18
|
|
|
18
19
|
const REDACTED_VALUE = "***REDACTED***";
|
|
19
20
|
const DEFAULT_TTL_MS = 60_000;
|
|
@@ -644,6 +645,7 @@ class CredentialAgent {
|
|
|
644
645
|
* self-asserted approval metadata.
|
|
645
646
|
*/
|
|
646
647
|
issueCredentialRef(request = {}) {
|
|
648
|
+
requireUnscopedDescendantControl();
|
|
647
649
|
if (!this.isEnabled()) {
|
|
648
650
|
this._recordAudit({
|
|
649
651
|
event: "credential_ref_issue",
|
|
@@ -842,6 +844,7 @@ class CredentialAgent {
|
|
|
842
844
|
* request object; child-provided claims are not sufficient attestation.
|
|
843
845
|
*/
|
|
844
846
|
resolveCredentialRef(refId, request = {}) {
|
|
847
|
+
requireUnscopedDescendantControl();
|
|
845
848
|
const refFingerprint = this._fingerprint(refId);
|
|
846
849
|
if (!this.isEnabled()) {
|
|
847
850
|
this._recordAudit({
|
|
@@ -1002,8 +1005,8 @@ class CredentialAgent {
|
|
|
1002
1005
|
_canIssueForContext(context) {
|
|
1003
1006
|
return Boolean(
|
|
1004
1007
|
context?.approved === true &&
|
|
1005
|
-
|
|
1006
|
-
|
|
1008
|
+
context.approvalId &&
|
|
1009
|
+
normalizeProcessTarget(context.target?.process ?? context.process),
|
|
1007
1010
|
);
|
|
1008
1011
|
}
|
|
1009
1012
|
|
|
@@ -1025,6 +1028,7 @@ class CredentialAgent {
|
|
|
1025
1028
|
* Strip sensitive and reserved environment variables from spawn options.
|
|
1026
1029
|
*/
|
|
1027
1030
|
filterEnvironment(env = process.env, context = null) {
|
|
1031
|
+
requireUnscopedDescendantControl();
|
|
1028
1032
|
const safeEnv = {};
|
|
1029
1033
|
const redacted = [];
|
|
1030
1034
|
const reservedRemoved = [];
|
|
@@ -1232,6 +1236,7 @@ class CredentialAgent {
|
|
|
1232
1236
|
* Apply filtering and issue references for a broker-approved spawn.
|
|
1233
1237
|
*/
|
|
1234
1238
|
applyWithReport(spawnOptions) {
|
|
1239
|
+
requireUnscopedDescendantControl();
|
|
1235
1240
|
if (!spawnOptions || typeof spawnOptions !== "object") {
|
|
1236
1241
|
throw credentialError(
|
|
1237
1242
|
CREDENTIAL_ERROR_CODES.INVALID_REQUEST,
|
|
@@ -10,6 +10,7 @@ import net from "node:net";
|
|
|
10
10
|
import os from "node:os";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import { Worker } from "node:worker_threads";
|
|
13
|
+
import { requireUnscopedDescendantControl } from "../formal-budget-provider-scope.js";
|
|
13
14
|
|
|
14
15
|
const TRANSPORT_VERSION = "local-ipc-v1";
|
|
15
16
|
const DEFAULT_TIMEOUT_MS = 5000;
|
|
@@ -34,6 +35,7 @@ export function credentialTransportEndpoint(agentId, options = {}) {
|
|
|
34
35
|
|
|
35
36
|
export class CredentialTransport {
|
|
36
37
|
constructor(options = {}) {
|
|
38
|
+
requireUnscopedDescendantControl();
|
|
37
39
|
if (!options.agentId) {
|
|
38
40
|
throw transportError(
|
|
39
41
|
"CC_CREDENTIAL_INVALID_REQUEST",
|
|
@@ -156,6 +158,7 @@ export class CredentialTransport {
|
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
registerCredential(record) {
|
|
161
|
+
requireUnscopedDescendantControl();
|
|
159
162
|
if (!this.isAvailable()) {
|
|
160
163
|
throw (
|
|
161
164
|
this.error ||
|
|
@@ -265,6 +268,7 @@ async function connectWithRetry(endpoint, deadline) {
|
|
|
265
268
|
* approved target process.
|
|
266
269
|
*/
|
|
267
270
|
export async function resolveCredentialRefOverTransport(refId, options = {}) {
|
|
271
|
+
requireUnscopedDescendantControl();
|
|
268
272
|
const env = options.env || process.env;
|
|
269
273
|
const endpoint = options.endpoint || env.CC_CREDENTIAL_ENDPOINT;
|
|
270
274
|
const capabilityToken =
|
|
@@ -30,6 +30,7 @@ import * as fs from "node:fs";
|
|
|
30
30
|
import * as tty from "node:tty";
|
|
31
31
|
import { createRequire } from "node:module";
|
|
32
32
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
33
|
+
import { requireUnscopedDescendantControl } from "../formal-budget-provider-scope.js";
|
|
33
34
|
|
|
34
35
|
const require = createRequire(import.meta.url);
|
|
35
36
|
|
|
@@ -4692,6 +4693,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
4692
4693
|
}
|
|
4693
4694
|
|
|
4694
4695
|
spawn(command, args, options = {}) {
|
|
4696
|
+
requireUnscopedDescendantControl();
|
|
4695
4697
|
assertProcessOwnershipAvailable();
|
|
4696
4698
|
options = this._withAmbientProcessContext(command, options);
|
|
4697
4699
|
const executionId = crypto.randomUUID();
|
|
@@ -5156,6 +5158,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
5156
5158
|
}
|
|
5157
5159
|
|
|
5158
5160
|
spawnSync(command, args, options = {}) {
|
|
5161
|
+
requireUnscopedDescendantControl();
|
|
5159
5162
|
assertProcessOwnershipAvailable();
|
|
5160
5163
|
options = this._withAmbientProcessContext(command, options);
|
|
5161
5164
|
const executionId = crypto.randomUUID();
|
|
@@ -5745,6 +5748,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
5745
5748
|
}
|
|
5746
5749
|
|
|
5747
5750
|
exec(command, options, callback) {
|
|
5751
|
+
requireUnscopedDescendantControl();
|
|
5748
5752
|
const opts = typeof options === "function" ? {} : options;
|
|
5749
5753
|
const cb = typeof options === "function" ? options : callback;
|
|
5750
5754
|
if (this._requiresExplicitLinuxWorkspaceShell(opts.cwd || process.cwd())) {
|
|
@@ -5763,6 +5767,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
5763
5767
|
}
|
|
5764
5768
|
|
|
5765
5769
|
execSync(command, options = {}) {
|
|
5770
|
+
requireUnscopedDescendantControl();
|
|
5766
5771
|
if (
|
|
5767
5772
|
this._requiresExplicitLinuxWorkspaceShell(options.cwd || process.cwd())
|
|
5768
5773
|
) {
|
|
@@ -5804,6 +5809,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
5804
5809
|
}
|
|
5805
5810
|
|
|
5806
5811
|
execFile(file, args, options, callback) {
|
|
5812
|
+
requireUnscopedDescendantControl();
|
|
5807
5813
|
if (typeof args === "function") {
|
|
5808
5814
|
callback = args;
|
|
5809
5815
|
args = [];
|
|
@@ -5897,6 +5903,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
5897
5903
|
}
|
|
5898
5904
|
|
|
5899
5905
|
execFileSync(file, args, options = {}) {
|
|
5906
|
+
requireUnscopedDescendantControl();
|
|
5900
5907
|
if (!Array.isArray(args)) {
|
|
5901
5908
|
options = args || {};
|
|
5902
5909
|
args = [];
|
|
@@ -5917,6 +5924,7 @@ class ProcessExecutionBroker extends EventEmitter {
|
|
|
5917
5924
|
}
|
|
5918
5925
|
|
|
5919
5926
|
fork(modulePath, args, options = {}) {
|
|
5927
|
+
requireUnscopedDescendantControl();
|
|
5920
5928
|
return this.spawn(process.execPath, [modulePath, ...(args || [])], {
|
|
5921
5929
|
...options,
|
|
5922
5930
|
origin: options.origin || "fork",
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hasFormalBudgetProviderScope,
|
|
3
|
+
providerFetch,
|
|
4
|
+
} from "./formal-budget-provider-scope.js";
|
|
1
5
|
/**
|
|
2
6
|
* Provider streaming adapters — shared by `cc stream` and the Hosted Session
|
|
3
7
|
* API `stream.run` WS route. Each builder returns an AsyncIterable<string>
|
|
@@ -47,16 +51,19 @@ export async function* ollamaTokenStream({
|
|
|
47
51
|
signal,
|
|
48
52
|
requireCompletion = false,
|
|
49
53
|
}) {
|
|
50
|
-
const res = await
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
54
|
+
const res = await providerFetch(
|
|
55
|
+
`${baseUrl}/api/${messages ? "chat" : "generate"}`,
|
|
56
|
+
{
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: { "Content-Type": "application/json" },
|
|
59
|
+
body: JSON.stringify(
|
|
60
|
+
messages
|
|
61
|
+
? { model, messages, stream: true }
|
|
62
|
+
: { model, prompt, stream: true },
|
|
63
|
+
),
|
|
64
|
+
signal,
|
|
65
|
+
},
|
|
66
|
+
);
|
|
60
67
|
if (!res.ok || !res.body) {
|
|
61
68
|
throw new Error(`Ollama ${res.status} ${res.statusText}`);
|
|
62
69
|
}
|
|
@@ -88,7 +95,8 @@ export async function* openAIStream({
|
|
|
88
95
|
signal,
|
|
89
96
|
requireCompletion = false,
|
|
90
97
|
}) {
|
|
91
|
-
const
|
|
98
|
+
const governed = hasFormalBudgetProviderScope();
|
|
99
|
+
const res = await providerFetch(`${baseUrl}/chat/completions`, {
|
|
92
100
|
method: "POST",
|
|
93
101
|
headers: {
|
|
94
102
|
"Content-Type": "application/json",
|
|
@@ -98,17 +106,24 @@ export async function* openAIStream({
|
|
|
98
106
|
model,
|
|
99
107
|
messages: messages ?? [{ role: "user", content: prompt }],
|
|
100
108
|
stream: true,
|
|
109
|
+
...(governed ? { stream_options: { include_usage: true } } : {}),
|
|
101
110
|
}),
|
|
102
111
|
signal,
|
|
103
112
|
});
|
|
104
113
|
if (!res.ok || !res.body) {
|
|
105
114
|
throw new Error(`${res.status} ${res.statusText}`);
|
|
106
115
|
}
|
|
116
|
+
let completed = false;
|
|
107
117
|
for await (const raw of responseLines(res.body)) {
|
|
108
118
|
const line = raw.trim();
|
|
109
119
|
if (!line || !line.startsWith("data:")) continue;
|
|
110
120
|
const payload = line.slice(5).trim();
|
|
111
|
-
if (payload === "[DONE]")
|
|
121
|
+
if (payload === "[DONE]") {
|
|
122
|
+
completed = true;
|
|
123
|
+
if (!governed) return;
|
|
124
|
+
// A governed stream must reach EOF so durable accounting can settle.
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
112
127
|
try {
|
|
113
128
|
const obj = JSON.parse(payload);
|
|
114
129
|
if (requireCompletion && obj.error)
|
|
@@ -120,7 +135,7 @@ export async function* openAIStream({
|
|
|
120
135
|
/* skip */
|
|
121
136
|
}
|
|
122
137
|
}
|
|
123
|
-
if (requireCompletion)
|
|
138
|
+
if (requireCompletion && !completed)
|
|
124
139
|
throw new Error("OpenAI stream ended before its completion marker");
|
|
125
140
|
}
|
|
126
141
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Worker } from "node:worker_threads";
|
|
7
7
|
import path from "node:path";
|
|
8
|
+
import { requireUnscopedDescendantControl } from "./formal-budget-provider-scope.js";
|
|
8
9
|
|
|
9
10
|
const RESPONSE_TIMEOUT_MS = 10_000;
|
|
10
11
|
|
|
@@ -15,6 +16,7 @@ function workerError(code) {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export async function startEgressProxyWorker(policy, options = {}) {
|
|
19
|
+
requireUnscopedDescendantControl();
|
|
18
20
|
const bindHost = options.bindHost || "127.0.0.1";
|
|
19
21
|
const socketPath = options.socketPath || null;
|
|
20
22
|
if (socketPath) {
|
|
@@ -156,6 +158,7 @@ export async function startEgressProxyWorker(policy, options = {}) {
|
|
|
156
158
|
return revision;
|
|
157
159
|
},
|
|
158
160
|
async updatePolicy(nextPolicy, expectedRevision) {
|
|
161
|
+
requireUnscopedDescendantControl();
|
|
159
162
|
const response = await request("update", {
|
|
160
163
|
policy: nextPolicy,
|
|
161
164
|
expectedRevision,
|
package/src/lib/skill-loader.js
CHANGED
|
@@ -392,6 +392,7 @@ export class CLISkillLoader {
|
|
|
392
392
|
throw new TypeError("reauthorizeSkill must be a function or null");
|
|
393
393
|
}
|
|
394
394
|
this._cache = null;
|
|
395
|
+
this._lastLoadOptions = null;
|
|
395
396
|
bindSkillRuntimeAdmission(this, skillRuntimeAdmission, {
|
|
396
397
|
required: skillRuntimeAdmissionRequired,
|
|
397
398
|
});
|
|
@@ -1264,6 +1265,12 @@ export class CLISkillLoader {
|
|
|
1264
1265
|
*/
|
|
1265
1266
|
loadAll(options = {}) {
|
|
1266
1267
|
this._cacheStats.descriptorScans += 1;
|
|
1268
|
+
// Preserve explicit layer policy for a later freshness scan. In particular,
|
|
1269
|
+
// refreshing an opt-in decision must not re-enable a disabled skill layer.
|
|
1270
|
+
this._lastLoadOptions = {
|
|
1271
|
+
...options,
|
|
1272
|
+
...(options.env ? { env: { ...options.env } } : {}),
|
|
1273
|
+
};
|
|
1267
1274
|
// `cc agent --bare` (CC_SKILLS=0): no skill layer loads at all — cache the
|
|
1268
1275
|
// empty result so getResolvedSkills stays cheap on every call.
|
|
1269
1276
|
if (allSkillsDisabled(options)) {
|
|
@@ -1336,6 +1343,14 @@ export class CLISkillLoader {
|
|
|
1336
1343
|
return this.loadAll();
|
|
1337
1344
|
}
|
|
1338
1345
|
|
|
1346
|
+
/** Rescan the same layers under the options used for the current cache. */
|
|
1347
|
+
refreshResolvedSkills() {
|
|
1348
|
+
// A failed scan must not leave a previous descriptor set available as if
|
|
1349
|
+
// it were current on the next lookup.
|
|
1350
|
+
this._cache = null;
|
|
1351
|
+
return this.loadAll(this._lastLoadOptions ?? {});
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1339
1354
|
/**
|
|
1340
1355
|
* Get auto-activated persona skills
|
|
1341
1356
|
* @returns {object[]} skills with category "persona" and activation "auto"
|
|
@@ -1367,6 +1382,7 @@ export class CLISkillLoader {
|
|
|
1367
1382
|
*/
|
|
1368
1383
|
clearCache() {
|
|
1369
1384
|
this._cache = null;
|
|
1385
|
+
this._lastLoadOptions = null;
|
|
1370
1386
|
this._bodyCache.clear();
|
|
1371
1387
|
this._cacheStats = {
|
|
1372
1388
|
descriptorScans: 0,
|
package/src/lib/stream-retry.js
CHANGED
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
raceWithAbort,
|
|
19
19
|
throwIfAborted,
|
|
20
20
|
} from "./abort-utils.js";
|
|
21
|
+
import { isFormalBudgetError } from "./formal-budget-errors.js";
|
|
21
22
|
|
|
22
23
|
/** Bounded auto-retry budget for streaming connection drops (Claude-Code 2.1.181). */
|
|
23
24
|
export const STREAM_RETRY_MAX = 2;
|
|
@@ -243,6 +244,7 @@ export function resolveStreamRetryMax(env = process.env) {
|
|
|
243
244
|
* @returns {boolean}
|
|
244
245
|
*/
|
|
245
246
|
export function isRetryableStreamError(err, signal) {
|
|
247
|
+
if (isFormalBudgetError(err)) return false;
|
|
246
248
|
if (isAbortError(err)) return false;
|
|
247
249
|
if (signal && signal.aborted) return false;
|
|
248
250
|
if (!err) return false;
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from "../runtime/agent-core.js";
|
|
22
22
|
import { feature } from "./feature-flags.js";
|
|
23
23
|
import { isEvolutionIngressFailure } from "./model-failure-policy.js";
|
|
24
|
+
import { isFormalBudgetError } from "./formal-budget-errors.js";
|
|
24
25
|
import { captureAgentEvolutionIngress } from "./evolution/agent-evolution-ingress.js";
|
|
25
26
|
import {
|
|
26
27
|
createWorktree,
|
|
@@ -609,6 +610,7 @@ export class SubAgentContext {
|
|
|
609
610
|
} catch (err) {
|
|
610
611
|
if (
|
|
611
612
|
isEvolutionIngressFailure(err) ||
|
|
613
|
+
isFormalBudgetError(err) ||
|
|
612
614
|
err?.runtimeLedgerPersistence === true ||
|
|
613
615
|
this._workflowEffectId
|
|
614
616
|
) {
|
|
@@ -1212,6 +1214,7 @@ export class SubAgentContext {
|
|
|
1212
1214
|
} catch (err) {
|
|
1213
1215
|
if (
|
|
1214
1216
|
isEvolutionIngressFailure(err) ||
|
|
1217
|
+
isFormalBudgetError(err) ||
|
|
1215
1218
|
err?.runtimeLedgerPersistence === true ||
|
|
1216
1219
|
this._workflowEffectId
|
|
1217
1220
|
) {
|
|
@@ -1543,9 +1546,9 @@ export class SubAgentContext {
|
|
|
1543
1546
|
isAborted() {
|
|
1544
1547
|
return Boolean(
|
|
1545
1548
|
this._signal?.aborted ||
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
+
this._abortController.signal.aborted ||
|
|
1550
|
+
this._runAbortController?.signal.aborted ||
|
|
1551
|
+
this.sessionBudget?.signal?.aborted,
|
|
1549
1552
|
);
|
|
1550
1553
|
}
|
|
1551
1554
|
|
package/src/lib/web-fetch.js
CHANGED
|
@@ -12,6 +12,7 @@ import { URL } from "node:url";
|
|
|
12
12
|
import { createHash } from "node:crypto";
|
|
13
13
|
import { StringDecoder } from "node:string_decoder";
|
|
14
14
|
import { webFetchSnapshots } from "./web-fetch-snapshots.js";
|
|
15
|
+
import { requireUnscopedExternalToolAccess } from "./formal-budget-provider-scope.js";
|
|
15
16
|
|
|
16
17
|
const DEFAULT_MAX_BYTES = 10_000_000;
|
|
17
18
|
const DEFAULT_MAX_CHARS = 20_000;
|
|
@@ -343,6 +344,7 @@ async function _doRequest(
|
|
|
343
344
|
}
|
|
344
345
|
|
|
345
346
|
export async function webFetch(url, options = {}) {
|
|
347
|
+
requireUnscopedExternalToolAccess();
|
|
346
348
|
const {
|
|
347
349
|
format = "markdown",
|
|
348
350
|
maxBytes = DEFAULT_MAX_BYTES,
|
package/src/lib/web-search.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import http from "http";
|
|
15
15
|
import https from "https";
|
|
16
16
|
import { URL } from "url";
|
|
17
|
+
import { requireUnscopedPaidService } from "./formal-budget-provider-scope.js";
|
|
17
18
|
|
|
18
19
|
const DEFAULT_MAX_BYTES = 10_000_000;
|
|
19
20
|
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
@@ -510,6 +511,10 @@ export async function webSearch(query, options = {}) {
|
|
|
510
511
|
const q = String(query || "").trim();
|
|
511
512
|
if (!q) return { error: "web_search: empty query" };
|
|
512
513
|
|
|
514
|
+
// A model-token reservation does not price API search or configured proxy
|
|
515
|
+
// services. Reject before resolving keys or opening an HTTP request.
|
|
516
|
+
requireUnscopedPaidService();
|
|
517
|
+
|
|
513
518
|
const config = options.config || {};
|
|
514
519
|
const provider = resolveProvider(options, config);
|
|
515
520
|
let maxResults = normalizeMaxResults(options.maxResults ?? config.maxResults);
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -86,7 +86,9 @@ import {
|
|
|
86
86
|
} from "../lib/session-host-snapshot.js";
|
|
87
87
|
import { acquireSessionHostLease } from "../lib/session-host-lease.js";
|
|
88
88
|
import {
|
|
89
|
+
normalizeSessionBudgetRootConfig,
|
|
89
90
|
openProductionSessionBudgetRoot,
|
|
91
|
+
readProductionSessionBudget,
|
|
90
92
|
sessionBudgetAdmissionError,
|
|
91
93
|
} from "../lib/session-budget-production-root.js";
|
|
92
94
|
import {
|
|
@@ -2265,9 +2267,25 @@ export function prepareReplJsonlResumeCandidate(sessionId, dependencies = {}) {
|
|
|
2265
2267
|
error.code = "CC_REPL_SESSION_AUTHORITY_MISMATCH";
|
|
2266
2268
|
throw error;
|
|
2267
2269
|
}
|
|
2270
|
+
const declaredBudget = dataDescriptorValue(
|
|
2271
|
+
stateDescriptors,
|
|
2272
|
+
"sessionBudgetRoot",
|
|
2273
|
+
"REPL session host resume state",
|
|
2274
|
+
{ required: false },
|
|
2275
|
+
);
|
|
2276
|
+
const sessionBudgetRoot =
|
|
2277
|
+
declaredBudget == null
|
|
2278
|
+
? null
|
|
2279
|
+
: normalizeSessionBudgetRootConfig(
|
|
2280
|
+
snapshotReplMessageValue(
|
|
2281
|
+
declaredBudget,
|
|
2282
|
+
"REPL session budget declaration",
|
|
2283
|
+
),
|
|
2284
|
+
);
|
|
2268
2285
|
return brandedFrozenCandidate(REPL_JSONL_RESUME_CANDIDATES, {
|
|
2269
2286
|
ok: true,
|
|
2270
2287
|
sessionId,
|
|
2288
|
+
sessionBudgetRoot,
|
|
2271
2289
|
rebuiltMessages,
|
|
2272
2290
|
replayMessages: normalizedReplay.replayMessages,
|
|
2273
2291
|
canonicalSystemMessages: normalizedReplay.canonicalSystemMessages,
|
|
@@ -2786,8 +2804,60 @@ export async function runReplStartupBoundary(options, startupDependencies) {
|
|
|
2786
2804
|
) {
|
|
2787
2805
|
leaseScope.lease = acquireHostLease(leaseSessionId, { hostKind: "repl" });
|
|
2788
2806
|
}
|
|
2789
|
-
|
|
2790
|
-
|
|
2807
|
+
const injectedBudgetReader = dependencyDataFunction(
|
|
2808
|
+
startupDependencies,
|
|
2809
|
+
"readProductionSessionBudget",
|
|
2810
|
+
null,
|
|
2811
|
+
);
|
|
2812
|
+
const sidecar =
|
|
2813
|
+
leaseSessionId &&
|
|
2814
|
+
(process.platform === "linux" || injectedBudgetReader !== null)
|
|
2815
|
+
? synchronousReplRecoveryValue(
|
|
2816
|
+
(injectedBudgetReader || readProductionSessionBudget)(leaseSessionId),
|
|
2817
|
+
"REPL budget sidecar",
|
|
2818
|
+
)
|
|
2819
|
+
: null;
|
|
2820
|
+
let effectiveBudgetConfig = options.sessionBudgetRoot;
|
|
2821
|
+
const declaredBudgetConfig = startupCandidate?.sessionBudgetRoot;
|
|
2822
|
+
const requestedBudgetConfig = options.sessionBudgetRoot?.enabled
|
|
2823
|
+
? normalizeSessionBudgetRootConfig(options.sessionBudgetRoot)
|
|
2824
|
+
: null;
|
|
2825
|
+
if (startupCandidate?.ok === true) {
|
|
2826
|
+
if (declaredBudgetConfig?.enabled) {
|
|
2827
|
+
if (!sidecar) {
|
|
2828
|
+
throw Object.assign(
|
|
2829
|
+
new Error("budgeted REPL session is missing its budget sidecar"),
|
|
2830
|
+
{ code: "CC_SESSION_BUDGET_SIDECAR_REQUIRED" },
|
|
2831
|
+
);
|
|
2832
|
+
}
|
|
2833
|
+
if (
|
|
2834
|
+
requestedBudgetConfig &&
|
|
2835
|
+
JSON.stringify(requestedBudgetConfig) !==
|
|
2836
|
+
JSON.stringify(declaredBudgetConfig)
|
|
2837
|
+
) {
|
|
2838
|
+
throw Object.assign(
|
|
2839
|
+
new Error("REPL budget does not match its JSONL declaration"),
|
|
2840
|
+
{ code: "CC_SESSION_BUDGET_CONFIG_MISMATCH" },
|
|
2841
|
+
);
|
|
2842
|
+
}
|
|
2843
|
+
effectiveBudgetConfig = declaredBudgetConfig;
|
|
2844
|
+
} else if (requestedBudgetConfig || sidecar) {
|
|
2845
|
+
throw Object.assign(
|
|
2846
|
+
new Error("existing REPL session has no canonical budget declaration"),
|
|
2847
|
+
{ code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
|
|
2848
|
+
);
|
|
2849
|
+
}
|
|
2850
|
+
} else if (sidecar) {
|
|
2851
|
+
throw Object.assign(
|
|
2852
|
+
new Error("budget sidecar has no canonical REPL session"),
|
|
2853
|
+
{ code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
|
|
2854
|
+
);
|
|
2855
|
+
}
|
|
2856
|
+
let workspaceOptions = {
|
|
2857
|
+
...options,
|
|
2858
|
+
sessionBudgetRoot: effectiveBudgetConfig,
|
|
2859
|
+
};
|
|
2860
|
+
if (effectiveBudgetConfig?.enabled === true) {
|
|
2791
2861
|
if (!leaseSessionId || !leaseScope?.lease) {
|
|
2792
2862
|
throw Object.assign(
|
|
2793
2863
|
new Error(
|
|
@@ -2813,10 +2883,10 @@ export async function runReplStartupBoundary(options, startupDependencies) {
|
|
|
2813
2883
|
"CC_REPL_STARTUP_DEPENDENCY_INVALID",
|
|
2814
2884
|
);
|
|
2815
2885
|
}
|
|
2816
|
-
const root = openBudgetRoot(leaseSessionId,
|
|
2886
|
+
const root = openBudgetRoot(leaseSessionId, effectiveBudgetConfig, {
|
|
2817
2887
|
persist: true,
|
|
2818
2888
|
signal: combineReplSignals(options.signal, leaseScope.lease.signal),
|
|
2819
|
-
table:
|
|
2889
|
+
table: effectiveBudgetConfig.table,
|
|
2820
2890
|
});
|
|
2821
2891
|
if (
|
|
2822
2892
|
root?.enabled !== true ||
|
|
@@ -2850,7 +2920,7 @@ export async function runReplStartupBoundary(options, startupDependencies) {
|
|
|
2850
2920
|
throw admissionError;
|
|
2851
2921
|
}
|
|
2852
2922
|
budgetScope.root = root;
|
|
2853
|
-
workspaceOptions = { ...
|
|
2923
|
+
workspaceOptions = { ...workspaceOptions, ...root.options };
|
|
2854
2924
|
}
|
|
2855
2925
|
const trustedWorkspaceRoot = readCwd();
|
|
2856
2926
|
return enterWorkspace(trustedWorkspaceRoot, () =>
|
|
@@ -2867,11 +2937,17 @@ export function startReplJsonlSession(
|
|
|
2867
2937
|
options = {},
|
|
2868
2938
|
) {
|
|
2869
2939
|
const requireDurable =
|
|
2870
|
-
observabilityScope != null ||
|
|
2940
|
+
observabilityScope != null ||
|
|
2941
|
+
options.requireDurable === true ||
|
|
2942
|
+
options.sessionBudgetRoot?.enabled === true;
|
|
2871
2943
|
try {
|
|
2944
|
+
const budgetDeclaration = options.sessionBudgetRoot?.enabled
|
|
2945
|
+
? normalizeSessionBudgetRootConfig(options.sessionBudgetRoot)
|
|
2946
|
+
: null;
|
|
2872
2947
|
const sessionId = startSession(requestedId, {
|
|
2873
2948
|
...meta,
|
|
2874
2949
|
...(observabilityScope != null ? { observabilityScope } : {}),
|
|
2950
|
+
...(budgetDeclaration ? { sessionBudgetRoot: budgetDeclaration } : {}),
|
|
2875
2951
|
});
|
|
2876
2952
|
if (requireDurable && (typeof sessionId !== "string" || !sessionId)) {
|
|
2877
2953
|
throw new Error("JSONL session creation returned no durable session id");
|
|
@@ -3966,7 +4042,10 @@ async function startAgentReplInWorkspaceOwned(
|
|
|
3966
4042
|
options.sessionId || null,
|
|
3967
4043
|
meta,
|
|
3968
4044
|
options.observabilityScope,
|
|
3969
|
-
{
|
|
4045
|
+
{
|
|
4046
|
+
requireDurable: Boolean(_sessionBudget),
|
|
4047
|
+
sessionBudgetRoot: options.sessionBudgetRoot,
|
|
4048
|
+
},
|
|
3970
4049
|
);
|
|
3971
4050
|
if (
|
|
3972
4051
|
sessionId &&
|