chainlesschain 0.162.193 → 0.162.198
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/README.md +29 -6
- package/completions/_cc +2 -2
- package/completions/cc.bash +2 -2
- package/completions/cc.fish +2 -2
- package/completions/cc.ps1 +2 -2
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-DBLkaTje.js → AIOps-CSN-D2xb.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BAy-Qebo.js → ActionButton-CBSMlGzv.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Dfb1Mlau.js → Analytics-3yr3Nt2t.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-BbFkN8m0.js → AppLayout-1b-o3lMH.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-kM4-cEEH.js → Artifacts-Dr8rJi17.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BSQfYWf3.js → Audit-2V689HC2.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-CWDbI_fG.js → BackgroundAgents-DIxkNrD_.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BxLPbq_Q.js → Backup-Pg6BcwrE.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DuIbdrp6.js → BaseInput-CLUpqyfH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-NEmjGahU.js → Chat-qVS8rD4G.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-DfJEo-5_.js → ChatBubbleRenderer-ti49X12Q.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CaoeG3Ns.js → Checkbox-Bs9AaEay.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BFf_g3xY.js → Codegen-Dvc1mq8q.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CNOd8mdQ.js → Col-C4_biO7A.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BhpDqz-i.js → Community-al25XQUV.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CQ42T7Z6.js → Compact-D-ZDB8M1.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DI5PcLMN.js → Compliance-6lIfDz1W.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-wYYZe0wR.js → Cowork-DdI48XMJ.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-Dlq03DD_.js → Cron-DF5HZd2g.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BzqS8PP3.js → Crosschain-DuxeSvt3.js} +1 -1
- package/src/assets/web-panel/assets/{DID-It55Yem7.js → DID-B9yHkUTd.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-9HkH6oxn.js → Dashboard-Z5EuI3IM.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-00e2YWRB.js → Dropdown-vuRfO3dY.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-By-ugRDL.js → EmailListRenderer-QFLCc1uL.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-C396yu5m.js → FamilyGuardDashboard-BZ7EXkFJ.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BME5sbZY.js → Federation-DycIEg2s.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-B4TEZCr-.js → FormItemContext-Ba0H_7yG.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-_9CX9ieY.js → GenericCardRenderer--JgSTK-C.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BrS6WVSr.js → Git-DEvTbldE.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BMdCWnKF.js → Governance-BJIljy18.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Bcp3vzcA.js → Inference-CVyW3G3q.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DlLuqGY5.js → KnowledgeGraph-v8-borge.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-D-W_6x09.js → Logs-BCdS7gGo.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DElGPxCZ.js → MarkdownRenderer-CU-JB2Ns.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-Dzn2guvI.js → Marketplace-AN6tGA2B.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-uPict-KL.js → McpTools-DGViXASN.js} +6 -6
- package/src/assets/web-panel/assets/{Memory-BCw43kOb.js → Memory-Bpvmx9X4.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DmV8Wv7F.js → MobileBridge-CTP-DOTC.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-C-HaCmSM.js → MobileProjects-C8qfktxn.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-C6jxJ34Y.js → Mtc-ndYr0M1s.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-Za8ExwhQ.js → MtcAudit-Ci0-YK7W.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-KKDbuEgb.js → Multisig-BehSTFW7.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Dj97zbCk.js → NLProgramming-B91_YBLv.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DBXvMraU.js → Notes-BQlJ0-gq.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-DOxITLYl.js → NotificationSettings-CDgYMjYK.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-7DVjZwMM.js → OrderTableRenderer-BJkSlKeH.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-D1i73mjb.js → Organization-B-b3cWCp.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-kW6Q3rvg.js → Overflow-CILUL4nL.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-C-v_8p2v.js → P2P-BTCFBkF0.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-tUbbY64W.js → PdhVaultBrowser-BAR6AUx5.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-DkHxEZ58.js → Permissions-RRf6HbWJ.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DWuMPGrK.js → PersonalDataHub-BGTMiICa.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-30IYXWWm.js → Pipeline-945qY9YF.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DZNQ4RrH.js → Privacy-DPZwI6lJ.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-De2MCElf.js → ProjectInit-BPH2NRKc.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-5uHk9wsC.js → ProjectSettings-BZCRNCvb.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-XjDfrFLb.js → Projects-BTI__tBt.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-Bgwj6gcE.js → Providers-DDCf_nIw.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-gKql9umv.js → QrScannerModal-N6rbqt1r.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BWvmwkh7.js → QuickAsk-DrwjPS7M.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Uok4hZPd.js → Recommend-Cog9Wd99.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DLJzTk9a.js → RemoteSession-DC9pynjM.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-ZVwIPMSO.js → Reputation-D4th4gKS.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CN04HxWR.js → Row-ogiWR6v9.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BdSrEG4g.js → RssFeed-uYlk-2Oj.js} +3 -3
- package/src/assets/web-panel/assets/{Search-5PwVd0IR.js → Search-DYzzwvtM.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DdBo4zjN.js → Security-Da7YOyX6.js} +4 -4
- package/src/assets/web-panel/assets/{Services-D3letU7M.js → Services-CLI1VM1X.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton--Jb83f1v.js → Skeleton-DK77dzDC.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-Bg-CulHX.js → Skills-C_z7Lmhl.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-7QOa7S-X.js → Sla-D6413Q8L.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DQwppjRw.js → SpeechSettings-C07ydbj2.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-dNPQGL-s.js → SyncSettings-DGOm2W22.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Ggs-Z48q.js → Tasks-Cr_PVyLM.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-78TYHgRO.js → Templates-BhL2mZ0t.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-xHwwv9vO.js → Tenant-CPk5oyUr.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BJXSJfm4.js → Terminal-ClhqUsqV.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-fLbjRhJw.js → TimelineRenderer-BCC7MV5a.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-oMSBSBmB.js → Tokens-DD1Jt4oO.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-CfnY_wX_.js → Trigger-BCydFvN2.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-AdyTgYKO.js → Trust-DDHT1noa.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C5K_81dS.js → UkeySign-CWPZC7oI.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-vcGVDqki.js → VideoEditing-9Ea0nJR0.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-hhOc3hlY.js → Wallet-BjxhLxTf.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CVloC11s.js → WebAuthn-C6uCye67.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-CYeE32R5.js → WorkflowEditor-d2g4reYo.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CNROR5bN.js → chat-frTc6ScX.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Cjx-cnwU.js → colors-B5K6lG3v.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DOIfelvD.js → compact-item-Cdn46r8D.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DfA7UZ8u.js → createContext-DU1jqVQi.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CP-jEUyw.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BMSCzcfM.js → hasIn-DdNH-aW_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAnvhwg6.js → index-32ajXmTb.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEMwBBHk.js → index-7ehytj1K.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVL27kXC.js → index-BC4eGkar.js} +1 -1
- package/src/assets/web-panel/assets/{index-FBc_CJBd.js → index-BVLL-mq_.js} +1 -1
- package/src/assets/web-panel/assets/{index-dCd8cSUq.js → index-BXKhhx9V.js} +1 -1
- package/src/assets/web-panel/assets/{index-BemJ2u_E.js → index-BcGwGIaR.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVm1_i3t.js → index-Be4OtL-N.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cs6l7uRu.js → index-BoFak7le.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPAWBrMf.js → index-BwlIxAmX.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLmn0BoK.js → index-CGiwfwB9.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7gf77CJ.js → index-CHmkkdfT.js} +1 -1
- package/src/assets/web-panel/assets/{index-m2vG9gG_.js → index-CQorP1Ng.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClNMrqEY.js → index-CUoNAmE8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHtpHZAQ.js → index-Cj6P9Nst.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2K9SNVX.js → index-CtRPi4YC.js} +1 -1
- package/src/assets/web-panel/assets/index-CzrCHrFy.js +1 -0
- package/src/assets/web-panel/assets/{index-BolaOQxx.js → index-D1qIC4GR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BM1y_9hM.js → index-D23xGYjM.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cyweh0Hy.js → index-D4l82Me1.js} +1 -1
- package/src/assets/web-panel/assets/{index-By61ojUx.js → index-D4miNkWv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbQ2eQ8H.js → index-DIVyTmZ3.js} +1 -1
- package/src/assets/web-panel/assets/{index-Icdoqmzt.js → index-DM5FmPZU.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjEsxO5h.js → index-DRzBBdQ0.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4iYzpkL.js → index-Dca_i7H8.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3L5gdiD.js → index-DftZuyA7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdYBye8B.js → index-DtBCCkC4.js} +1 -1
- package/src/assets/web-panel/assets/{index-AWg-0M1S.js → index-HjCvXHf5.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEKMcOyU.js → index-LaivuXyF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxOk9vkG.js → index-MM4Zz2OE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNC5onm4.js → index-NmEXVjzt.js} +1 -1
- package/src/assets/web-panel/assets/index-OJsGskZw.js +1 -0
- package/src/assets/web-panel/assets/{index-BUonmKSE.js → index-PjAS0sIZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5Udeb_6.js → index-VDM2KKo9.js} +1 -1
- package/src/assets/web-panel/assets/{index-5-HXgOX5.js → index-cYaWV4Mq.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBpWXFed.js → index-gg3QPC3i.js} +3 -3
- package/src/assets/web-panel/assets/{index-C7xn0Nub.js → index-kVO_MDm-.js} +1 -1
- package/src/assets/web-panel/assets/{index-ti_lnTWl.js → index-mgU3Q-lN.js} +1 -1
- package/src/assets/web-panel/assets/{index-CshQbilz.js → index-t_OBzIP4.js} +1 -1
- package/src/assets/web-panel/assets/{index-mTpHoEzr.js → index-yZRuZpwK.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Bu8k7H1Y.js → initDefaultProps-DwLTRNdo.js} +1 -1
- package/src/assets/web-panel/assets/{motion-s3iVK41k.js → motion-BchZDXnh.js} +1 -1
- package/src/assets/web-panel/assets/{move-B6B-E5Jz.js → move-e8M-zZFl.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BiYgTidA.js → mtc-parser-Ci40fQb3.js} +1 -1
- package/src/assets/web-panel/assets/{omit-pU1RdUDA.js → omit-C7110_f2.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Cdoq_SeM.js → pickAttrs-skteMgnM.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DIuvAn2K.js → placementArrow-MGZ-lh2B.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-8w16YR2D.js → responsiveObserve-N4Sd7uy-.js} +1 -1
- package/src/assets/web-panel/assets/{slide-VZ01cZe3.js → slide-C7HDGRaa.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-lh8YMN8Z.js → statusUtils-BhRexlgy.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CmDyreec.js → styleChecker-ChEoQkN2.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-hiJWMU5y.js → useFlexGapSupport-CDbG1s2Y.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Thnu-Iaj.js → useFs-CUIx0tcJ.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-LBdOxjwY.js → usePersonalDataHub-bkO7L7ec.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Cg6lFY_X.js → vnode-B_ZvABIG.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DVfsR1YO.js → zoom-D5shjpS8.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +4 -4
- package/src/command-manifest.json +214 -50
- package/src/command-surface-policy.js +115 -0
- package/src/commands/agent.js +3 -3
- package/src/commands/background-session.js +145 -0
- package/src/commands/mcp.js +125 -7
- package/src/commands/serve.js +1 -1
- package/src/commands/session-show.js +131 -0
- package/src/commands/session.js +50 -106
- package/src/commands/skill.js +87 -50
- package/src/data/changelog.json +18 -5
- package/src/gateways/ws/ws-agent-handler.js +8 -1
- package/src/harness/jsonl-session-store.js +428 -25
- package/src/harness/mcp-client.js +2652 -404
- package/src/harness/session-list-index.js +65 -7
- package/src/lazy-dispatch.js +76 -8
- package/src/lib/abort-utils.js +68 -0
- package/src/lib/agent-core.js +1 -59
- package/src/lib/chat-core.js +24 -6
- package/src/lib/cowork-mcp-tools.js +47 -2
- package/src/lib/cowork-task-runner.js +11 -3
- package/src/lib/doctor-checkup.js +9 -7
- package/src/lib/learning/skill-improver.js +21 -2
- package/src/lib/mcp-call-ledger-store.js +116 -3
- package/src/lib/mcp-call-ledger.js +59 -14
- package/src/lib/mcp-client.js +1 -0
- package/src/lib/mcp-stdio-executable-identity.js +598 -0
- package/src/lib/mcp-stdio-execution-authority.js +363 -0
- package/src/lib/mcp-tool-metadata.js +436 -0
- package/src/lib/mcp-tool-result.js +367 -0
- package/src/lib/observability/index.js +71 -0
- package/src/lib/pr-link-ledger.js +8 -27
- package/src/lib/pr-link-store.js +26 -0
- package/src/lib/process-execution-broker/index.js +14 -0
- package/src/lib/process-tree-termination.js +253 -0
- package/src/lib/public-ide-capability-manifest.js +6 -0
- package/src/lib/session-host-snapshot.js +9 -5
- package/src/lib/session-projection.js +5 -1
- package/src/lib/session-tail.js +31 -1
- package/src/lib/skill-budget.js +222 -0
- package/src/lib/skill-execution-authority.js +381 -0
- package/src/lib/skill-execution-identity.js +39 -2
- package/src/lib/skill-loader.js +322 -86
- package/src/lib/skill-mcp.js +43 -1
- package/src/repl/agent-repl.js +349 -46
- package/src/repl/bg-dashboard.js +81 -28
- package/src/repl/chat-repl.js +77 -12
- package/src/repl/prompt-interactions.js +67 -7
- package/src/repl/slash-command-registry.js +3 -4
- package/src/runtime/agent-core.js +340 -108
- package/src/runtime/agent-runtime.js +26 -3
- package/src/runtime/headless-runner.js +150 -23
- package/src/runtime/headless-stream.js +309 -59
- package/src/runtime/mcp-config.js +157 -10
- package/src/runtime/mcp-tool-search.js +0 -0
- package/src/runtime/output-backpressure.js +366 -0
- package/src/runtime/pipe-safety.js +56 -21
- package/src/assets/web-panel/assets/devWarning-ChcCBGs7.js +0 -1
- package/src/assets/web-panel/assets/index-Q2IajL54.js +0 -1
- package/src/assets/web-panel/assets/index-bRkHgOMc.js +0 -1
- package/src/lib/skill-process-broker.js +0 -85
|
@@ -36,6 +36,11 @@ import {
|
|
|
36
36
|
} from "../lib/lsp/workspace-roots.js";
|
|
37
37
|
import { getPlanModeManager } from "../lib/plan-mode.js";
|
|
38
38
|
import { CLISkillLoader } from "../lib/skill-loader.js";
|
|
39
|
+
import {
|
|
40
|
+
admitSkillPrompt,
|
|
41
|
+
debitSkillPromptBudget,
|
|
42
|
+
resolveSkillLimits,
|
|
43
|
+
} from "../lib/skill-budget.js";
|
|
39
44
|
import { executeHooks, HookEvents } from "../lib/hook-manager.js";
|
|
40
45
|
import { detectPython } from "../lib/cli-anything-bridge.js";
|
|
41
46
|
import { findProjectRoot, loadProjectConfig } from "../lib/project-detector.js";
|
|
@@ -52,7 +57,11 @@ import {
|
|
|
52
57
|
} from "./coding-agent-contract.js";
|
|
53
58
|
import { createToolContext } from "../tools/tool-context.js";
|
|
54
59
|
import { createToolTelemetryRecord } from "../tools/tool-telemetry.js";
|
|
55
|
-
import {
|
|
60
|
+
import {
|
|
61
|
+
isAbortError,
|
|
62
|
+
raceWithAbort,
|
|
63
|
+
throwIfAborted,
|
|
64
|
+
} from "../lib/abort-utils.js";
|
|
56
65
|
import {
|
|
57
66
|
classifyEditReplay,
|
|
58
67
|
editIdempotencyKey,
|
|
@@ -100,6 +109,10 @@ import {
|
|
|
100
109
|
McpEffect,
|
|
101
110
|
snapshotMcpJsonRpcInput,
|
|
102
111
|
} from "../lib/mcp-call-ledger.js";
|
|
112
|
+
import {
|
|
113
|
+
admitMcpToolResult,
|
|
114
|
+
isMcpToolResultAdmissionError,
|
|
115
|
+
} from "../lib/mcp-tool-result.js";
|
|
103
116
|
import {
|
|
104
117
|
MCP_OUTCOME_UNKNOWN_CODE,
|
|
105
118
|
markMcpLedgerOutcomeUnknown,
|
|
@@ -112,6 +125,7 @@ import {
|
|
|
112
125
|
buildExtractiveHandoff,
|
|
113
126
|
formatStructuredHandoff,
|
|
114
127
|
} from "../harness/structured-handoff.js";
|
|
128
|
+
import { isMcpRpcError } from "../harness/mcp-client.js";
|
|
115
129
|
import { projectCanonicalResumeMessages } from "../lib/session-message-provenance.js";
|
|
116
130
|
|
|
117
131
|
export { formatProviderHttpError };
|
|
@@ -968,11 +982,16 @@ export function getAgentToolDescriptors(options = {}) {
|
|
|
968
982
|
const _defaultSkillLoader = new CLISkillLoader();
|
|
969
983
|
|
|
970
984
|
/**
|
|
971
|
-
* Re-scan all skill layers (Claude-Code `/reload-skills` parity):
|
|
972
|
-
*
|
|
973
|
-
*
|
|
985
|
+
* Re-scan all skill layers (Claude-Code `/reload-skills` parity): revokes this
|
|
986
|
+
* process's Skill execution generation, then drops the default loader cache so
|
|
987
|
+
* newly added/edited SKILL.md dirs are picked up without restarting. Returns
|
|
988
|
+
* the resolved skill count.
|
|
974
989
|
*/
|
|
975
990
|
export function reloadSkills() {
|
|
991
|
+
_defaultSkillLoader.revokeExecutionAuthorizations({
|
|
992
|
+
message: "Skill execution authorization was revoked by /reload-skills",
|
|
993
|
+
reasonCode: "reload-skills",
|
|
994
|
+
});
|
|
976
995
|
_defaultSkillLoader.clearCache();
|
|
977
996
|
return _defaultSkillLoader.loadAll().length;
|
|
978
997
|
}
|
|
@@ -1246,13 +1265,34 @@ export function buildSystemPrompt(cwd, opts = {}) {
|
|
|
1246
1265
|
turnId: opts.turnId,
|
|
1247
1266
|
loadedBecause: "persona_auto",
|
|
1248
1267
|
});
|
|
1268
|
+
// Re-admit custom/injected loader output at the final model boundary. Do
|
|
1269
|
+
// the complete aggregate pass before appending anything so an oversized
|
|
1270
|
+
// later persona cannot leave an earlier partial projection in the prompt.
|
|
1271
|
+
const limits = resolveSkillLimits(loader.getLimits?.());
|
|
1272
|
+
const promptBudget = { limits, bytes: 0, tokens: 0 };
|
|
1273
|
+
const personaProjections = [];
|
|
1274
|
+
for (const personaSkill of personaSkills) {
|
|
1275
|
+
const displayName =
|
|
1276
|
+
typeof personaSkill?.displayName === "string"
|
|
1277
|
+
? personaSkill.displayName
|
|
1278
|
+
: typeof personaSkill?.id === "string"
|
|
1279
|
+
? personaSkill.id
|
|
1280
|
+
: "Skill";
|
|
1281
|
+
const body = personaSkill?.body;
|
|
1282
|
+
admitSkillPrompt(body, limits);
|
|
1283
|
+
if (!body.trim()) continue;
|
|
1284
|
+
const projection = `\n\n## Persona: ${displayName}\n${body}`;
|
|
1285
|
+
debitSkillPromptBudget(
|
|
1286
|
+
promptBudget,
|
|
1287
|
+
admitSkillPrompt(projection, limits),
|
|
1288
|
+
);
|
|
1289
|
+
personaProjections.push(projection);
|
|
1290
|
+
}
|
|
1249
1291
|
if (typeof opts.onSkillsLoaded === "function") {
|
|
1250
1292
|
opts.onSkillsLoaded(personaSkills, loader.getCacheLedger());
|
|
1251
1293
|
}
|
|
1252
|
-
for (const
|
|
1253
|
-
|
|
1254
|
-
prompt += `\n\n## Persona: ${p.displayName}\n${p.body}`;
|
|
1255
|
-
}
|
|
1294
|
+
for (const projection of personaProjections) {
|
|
1295
|
+
prompt += projection;
|
|
1256
1296
|
}
|
|
1257
1297
|
} catch {
|
|
1258
1298
|
// Non-critical — skill loader may not be available
|
|
@@ -3354,21 +3394,41 @@ const MCP_PROTOCOL_RESULT_INVALID_CODE = "CC_MCP_PROTOCOL_RESULT_INVALID";
|
|
|
3354
3394
|
const MCP_RESULT_PROJECTION_FAILED_CODE = "CC_MCP_RESULT_PROJECTION_FAILED";
|
|
3355
3395
|
|
|
3356
3396
|
function safeMcpProperty(value, property) {
|
|
3397
|
+
if (!value || (typeof value !== "object" && typeof value !== "function")) {
|
|
3398
|
+
return undefined;
|
|
3399
|
+
}
|
|
3357
3400
|
try {
|
|
3358
|
-
return
|
|
3401
|
+
if (isProxy(value)) return undefined;
|
|
3402
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, property);
|
|
3403
|
+
return descriptor && Object.hasOwn(descriptor, "value")
|
|
3404
|
+
? descriptor.value
|
|
3405
|
+
: undefined;
|
|
3359
3406
|
} catch {
|
|
3360
3407
|
return undefined;
|
|
3361
3408
|
}
|
|
3362
3409
|
}
|
|
3363
3410
|
|
|
3364
3411
|
function safeMcpErrorMessage(error) {
|
|
3412
|
+
if (safeMcpProperty(error, "mcpErrorCode") === "CC_MCP_RPC_ERROR") {
|
|
3413
|
+
const rpcCode = safeMcpProperty(error, "rpcCode");
|
|
3414
|
+
return Number.isSafeInteger(rpcCode)
|
|
3415
|
+
? `MCP server returned a JSON-RPC error (code ${rpcCode})`
|
|
3416
|
+
: "MCP server returned a JSON-RPC error";
|
|
3417
|
+
}
|
|
3418
|
+
// HTTP status bodies are peer-controlled. The production transport omits
|
|
3419
|
+
// them at source, and this boundary independently prevents any MCP client
|
|
3420
|
+
// honoring the stable transport error code from projecting one into tool
|
|
3421
|
+
// results, models, or sessions.
|
|
3422
|
+
if (safeMcpProperty(error, "code") === "CC_MCP_HTTP_STATUS") {
|
|
3423
|
+
const status = safeMcpProperty(error, "status");
|
|
3424
|
+
return Number.isInteger(status) && status >= 100 && status <= 599
|
|
3425
|
+
? `MCP HTTP request failed with status ${status}`
|
|
3426
|
+
: "MCP HTTP request failed";
|
|
3427
|
+
}
|
|
3365
3428
|
const message = safeMcpProperty(error, "message");
|
|
3366
3429
|
if (typeof message === "string" && message) return message;
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
} catch {
|
|
3370
|
-
return "unknown error";
|
|
3371
|
-
}
|
|
3430
|
+
if (typeof error === "string" && error) return error;
|
|
3431
|
+
return "unknown error";
|
|
3372
3432
|
}
|
|
3373
3433
|
|
|
3374
3434
|
function safeMcpErrorCode(error, fallback) {
|
|
@@ -3376,6 +3436,15 @@ function safeMcpErrorCode(error, fallback) {
|
|
|
3376
3436
|
return typeof code === "string" && code ? code : fallback;
|
|
3377
3437
|
}
|
|
3378
3438
|
|
|
3439
|
+
function projectMcpCallError(error) {
|
|
3440
|
+
const projected = new Error(safeMcpErrorMessage(error));
|
|
3441
|
+
const code = isMcpRpcError(error)
|
|
3442
|
+
? "CC_MCP_RPC_ERROR"
|
|
3443
|
+
: safeMcpErrorCode(error, null);
|
|
3444
|
+
if (code) projected.code = code;
|
|
3445
|
+
return projected;
|
|
3446
|
+
}
|
|
3447
|
+
|
|
3379
3448
|
function invalidMcpProtocolResult(cause) {
|
|
3380
3449
|
const error = new TypeError("MCP result could not be inspected safely", {
|
|
3381
3450
|
cause,
|
|
@@ -5654,10 +5723,16 @@ async function executeToolInner(
|
|
|
5654
5723
|
}
|
|
5655
5724
|
|
|
5656
5725
|
case "run_skill": {
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5726
|
+
throwIfAborted(signal, "run_skill interrupted before discovery");
|
|
5727
|
+
const allSkills = await raceWithAbort(
|
|
5728
|
+
filterSkillsByCwd(
|
|
5729
|
+
skillLoader.getResolvedSkills().filter(skillAllowed),
|
|
5730
|
+
cwd,
|
|
5731
|
+
),
|
|
5732
|
+
signal,
|
|
5733
|
+
"run_skill interrupted during discovery",
|
|
5660
5734
|
);
|
|
5735
|
+
throwIfAborted(signal, "run_skill interrupted during discovery");
|
|
5661
5736
|
if (allSkills.length === 0) {
|
|
5662
5737
|
return attachDescriptor({
|
|
5663
5738
|
error: _skillAllowlist
|
|
@@ -5668,28 +5743,57 @@ async function executeToolInner(
|
|
|
5668
5743
|
let match = allSkills.find(
|
|
5669
5744
|
(s) => s.id === args.skill_name || s.dirName === args.skill_name,
|
|
5670
5745
|
);
|
|
5746
|
+
let admittedSkillBody = "";
|
|
5671
5747
|
if (!match || !match.hasHandler) {
|
|
5672
5748
|
return attachDescriptor({
|
|
5673
5749
|
error: `Skill "${args.skill_name}" not found or has no handler. Use list_skills to see available skills.`,
|
|
5674
5750
|
});
|
|
5675
5751
|
}
|
|
5752
|
+
const skillExecutionLease = skillLoader.acquireSkillExecution?.(match, {
|
|
5753
|
+
signal,
|
|
5754
|
+
});
|
|
5755
|
+
const skillExecutionSignal = skillExecutionLease?.signal || signal;
|
|
5676
5756
|
try {
|
|
5757
|
+
skillExecutionLease?.assertActive?.();
|
|
5677
5758
|
if (typeof skillLoader.materializeSkillForExecution === "function") {
|
|
5678
|
-
match = await
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5759
|
+
match = await raceWithAbort(
|
|
5760
|
+
skillLoader.materializeSkillForExecution(match, {
|
|
5761
|
+
sessionId,
|
|
5762
|
+
turnId,
|
|
5763
|
+
loadedBecause: "run_skill",
|
|
5764
|
+
bodyIncluded: true,
|
|
5765
|
+
signal: skillExecutionSignal,
|
|
5766
|
+
}),
|
|
5767
|
+
skillExecutionSignal,
|
|
5768
|
+
"run_skill interrupted during authorization",
|
|
5769
|
+
);
|
|
5684
5770
|
} else if (typeof skillLoader.materializeSkill === "function") {
|
|
5685
5771
|
match = skillLoader.materializeSkill(match, {
|
|
5686
5772
|
sessionId,
|
|
5687
5773
|
turnId,
|
|
5688
5774
|
loadedBecause: "run_skill",
|
|
5689
|
-
bodyIncluded:
|
|
5775
|
+
bodyIncluded: true,
|
|
5776
|
+
signal: skillExecutionSignal,
|
|
5690
5777
|
});
|
|
5691
5778
|
}
|
|
5779
|
+
skillExecutionLease?.assertActive?.();
|
|
5780
|
+
throwIfAborted(
|
|
5781
|
+
skillExecutionSignal,
|
|
5782
|
+
"run_skill interrupted during materialization",
|
|
5783
|
+
);
|
|
5784
|
+
// A custom loader is not an authority to raise host model-input caps.
|
|
5785
|
+
// Re-admit at the final consumer before constructing the child task.
|
|
5786
|
+
admittedSkillBody = match?.body;
|
|
5787
|
+
admitSkillPrompt(admittedSkillBody, skillLoader.getLimits?.());
|
|
5692
5788
|
} catch (error) {
|
|
5789
|
+
skillExecutionLease?.release?.();
|
|
5790
|
+
if (
|
|
5791
|
+
signal?.aborted ||
|
|
5792
|
+
skillExecutionSignal?.aborted ||
|
|
5793
|
+
isAbortError(error)
|
|
5794
|
+
) {
|
|
5795
|
+
throw error;
|
|
5796
|
+
}
|
|
5693
5797
|
return attachDescriptor({
|
|
5694
5798
|
error: `Skill "${args.skill_name}" body could not be loaded: ${error.message}`,
|
|
5695
5799
|
...(error?.code ? { code: error.code } : {}),
|
|
@@ -5721,67 +5825,84 @@ async function executeToolInner(
|
|
|
5721
5825
|
: null;
|
|
5722
5826
|
let skillSubRef = null;
|
|
5723
5827
|
// Run skill through isolated sub-agent context
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
|
|
5727
|
-
|
|
5728
|
-
`
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
5745
|
-
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
: {}),
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
5756
|
-
|
|
5757
|
-
?
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5763
|
-
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5828
|
+
let subCtx;
|
|
5829
|
+
try {
|
|
5830
|
+
skillExecutionLease?.assertActive?.();
|
|
5831
|
+
subCtx = SubAgentContext.create({
|
|
5832
|
+
role: `skill-${args.skill_name}`,
|
|
5833
|
+
task:
|
|
5834
|
+
`Execute the "${args.skill_name}" skill using only the approved tools.\n\n` +
|
|
5835
|
+
`Authoritative skill instructions:\n${admittedSkillBody}\n\n` +
|
|
5836
|
+
`User input:\n${String(args.input || "").substring(0, 8000)}`,
|
|
5837
|
+
allowedTools: isolatedSkillTools,
|
|
5838
|
+
hookParentTraceId: hookTraceId || null,
|
|
5839
|
+
signal: skillExecutionSignal,
|
|
5840
|
+
toolAdmission,
|
|
5841
|
+
cwd,
|
|
5842
|
+
llmOptions: llmOptions || null,
|
|
5843
|
+
...(sessionBudget ? { sessionBudget } : {}),
|
|
5844
|
+
...(permissionRules ? { permissionRules } : {}),
|
|
5845
|
+
...(hostManagedToolPolicy
|
|
5846
|
+
? {
|
|
5847
|
+
hostManagedToolPolicy: {
|
|
5848
|
+
...hostManagedToolPolicy,
|
|
5849
|
+
toolDefinitions: [],
|
|
5850
|
+
},
|
|
5851
|
+
}
|
|
5852
|
+
: {}),
|
|
5853
|
+
...(planManager ? { planManager } : {}),
|
|
5854
|
+
...(sandbox ? { sandbox } : {}),
|
|
5855
|
+
...(Array.isArray(additionalDirectories)
|
|
5856
|
+
? { additionalDirectories: [...additionalDirectories] }
|
|
5857
|
+
: {}),
|
|
5858
|
+
...(approvalGate ? { approvalGate } : {}),
|
|
5859
|
+
...(shellPolicyOverrides ? { shellPolicyOverrides } : {}),
|
|
5860
|
+
...(classifyAllShell ? { classifyAllShell: true } : {}),
|
|
5861
|
+
...(unattendedActionPolicy ? { unattendedActionPolicy } : {}),
|
|
5862
|
+
...(mcpCallLedger ? { mcpCallLedger } : {}),
|
|
5863
|
+
...(mcpConflictScheduler ? { mcpConflictScheduler } : {}),
|
|
5864
|
+
onUsage: skillUsageSink
|
|
5865
|
+
? (u) => {
|
|
5866
|
+
try {
|
|
5867
|
+
skillUsageSink.push(
|
|
5868
|
+
u && u.attribution
|
|
5869
|
+
? u
|
|
5870
|
+
: {
|
|
5871
|
+
provider: u?.provider ?? null,
|
|
5872
|
+
model: u?.model ?? null,
|
|
5873
|
+
usage: u?.usage || null,
|
|
5874
|
+
...(u?.source ? { source: u.source } : {}),
|
|
5875
|
+
attribution: {
|
|
5876
|
+
origin: "skill",
|
|
5877
|
+
skill: args.skill_name,
|
|
5878
|
+
subagentId: skillSubRef?.id || null,
|
|
5879
|
+
parentSessionId: sessionId || null,
|
|
5880
|
+
depth: (subAgentDepth || 0) + 1,
|
|
5881
|
+
},
|
|
5773
5882
|
},
|
|
5774
|
-
|
|
5775
|
-
)
|
|
5776
|
-
|
|
5777
|
-
|
|
5883
|
+
);
|
|
5884
|
+
} catch (_e) {
|
|
5885
|
+
// usage forwarding is best-effort
|
|
5886
|
+
}
|
|
5778
5887
|
}
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
})
|
|
5888
|
+
: null,
|
|
5889
|
+
});
|
|
5890
|
+
} catch (error) {
|
|
5891
|
+
skillExecutionLease?.release?.();
|
|
5892
|
+
throw error;
|
|
5893
|
+
}
|
|
5782
5894
|
skillSubRef = subCtx;
|
|
5783
5895
|
try {
|
|
5784
|
-
const result = await
|
|
5896
|
+
const result = await raceWithAbort(
|
|
5897
|
+
subCtx.run(args.input),
|
|
5898
|
+
skillExecutionSignal,
|
|
5899
|
+
"run_skill interrupted while the isolated child was running",
|
|
5900
|
+
);
|
|
5901
|
+
skillExecutionLease?.assertActive?.();
|
|
5902
|
+
throwIfAborted(
|
|
5903
|
+
skillExecutionSignal,
|
|
5904
|
+
"run_skill interrupted before child handoff",
|
|
5905
|
+
);
|
|
5785
5906
|
const resolvedFailure =
|
|
5786
5907
|
subCtx.status === "failed" ||
|
|
5787
5908
|
result?.success === false ||
|
|
@@ -5809,6 +5930,13 @@ async function executeToolInner(
|
|
|
5809
5930
|
toolsUsed: result.toolsUsed,
|
|
5810
5931
|
});
|
|
5811
5932
|
} catch (err) {
|
|
5933
|
+
if (
|
|
5934
|
+
signal?.aborted ||
|
|
5935
|
+
skillExecutionSignal?.aborted ||
|
|
5936
|
+
isAbortError(err)
|
|
5937
|
+
) {
|
|
5938
|
+
throw err;
|
|
5939
|
+
}
|
|
5812
5940
|
return attachDescriptor({
|
|
5813
5941
|
success: false,
|
|
5814
5942
|
isolated: true,
|
|
@@ -5816,6 +5944,8 @@ async function executeToolInner(
|
|
|
5816
5944
|
code: err?.code || "CC_SKILL_ISOLATED_EXECUTION_FAILED",
|
|
5817
5945
|
error: `Isolated skill execution failed: ${err.message}`,
|
|
5818
5946
|
});
|
|
5947
|
+
} finally {
|
|
5948
|
+
skillExecutionLease?.release?.();
|
|
5819
5949
|
}
|
|
5820
5950
|
}
|
|
5821
5951
|
|
|
@@ -5823,6 +5953,7 @@ async function executeToolInner(
|
|
|
5823
5953
|
// reaching here. Keep the runtime fence explicit so a custom/legacy
|
|
5824
5954
|
// loader can never re-enable arbitrary handler.js imports in the CLI
|
|
5825
5955
|
// process or hand a Skill the raw MCP client/process broker.
|
|
5956
|
+
skillExecutionLease?.release?.();
|
|
5826
5957
|
return attachDescriptor({
|
|
5827
5958
|
error: `Skill "${args.skill_name}" cannot execute handler.js directly. Add isolation: true and use the controlled agent-tool path.`,
|
|
5828
5959
|
code: "CC_SKILL_DIRECT_HANDLER_BLOCKED",
|
|
@@ -5907,13 +6038,15 @@ async function executeToolInner(
|
|
|
5907
6038
|
error: `Could not resolve which MCP server owns resource "${uri}". Pass 'server' explicitly.`,
|
|
5908
6039
|
});
|
|
5909
6040
|
}
|
|
5910
|
-
const result =
|
|
6041
|
+
const result = signal
|
|
6042
|
+
? await mcpClient.readResource(server, uri, { signal })
|
|
6043
|
+
: await mcpClient.readResource(server, uri);
|
|
5911
6044
|
return attachDescriptor(
|
|
5912
6045
|
result && typeof result === "object" ? result : { result },
|
|
5913
6046
|
);
|
|
5914
6047
|
} catch (err) {
|
|
5915
6048
|
return attachDescriptor({
|
|
5916
|
-
error: `MCP resource access failed: ${err
|
|
6049
|
+
error: `MCP resource access failed: ${safeMcpErrorMessage(err)}`,
|
|
5917
6050
|
});
|
|
5918
6051
|
}
|
|
5919
6052
|
}
|
|
@@ -6015,19 +6148,31 @@ async function executeToolInner(
|
|
|
6015
6148
|
});
|
|
6016
6149
|
}
|
|
6017
6150
|
|
|
6018
|
-
const transportFailure = async (callError) => {
|
|
6019
|
-
|
|
6151
|
+
const transportFailure = async (callError, phase = "call") => {
|
|
6152
|
+
const definitiveRpcFailure = isMcpRpcError(callError);
|
|
6153
|
+
if (
|
|
6154
|
+
mcpTransportOutcomeIsUnsafe(ledgerEffectContract) &&
|
|
6155
|
+
!definitiveRpcFailure
|
|
6156
|
+
) {
|
|
6157
|
+
const resultAdmissionFailure =
|
|
6158
|
+
isMcpToolResultAdmissionError(callError);
|
|
6020
6159
|
return attachDescriptor(
|
|
6021
6160
|
mcpOutcomeUnknownPayload(ledger, ledgerTicket, {
|
|
6022
|
-
phase
|
|
6023
|
-
reasonCode:
|
|
6161
|
+
phase,
|
|
6162
|
+
reasonCode: resultAdmissionFailure
|
|
6163
|
+
? safeMcpErrorCode(
|
|
6164
|
+
callError,
|
|
6165
|
+
MCP_PROTOCOL_RESULT_INVALID_CODE,
|
|
6166
|
+
)
|
|
6167
|
+
: MCP_TRANSPORT_OUTCOME_UNKNOWN_CODE,
|
|
6024
6168
|
}),
|
|
6025
6169
|
);
|
|
6026
6170
|
}
|
|
6171
|
+
const projectedError = projectMcpCallError(callError);
|
|
6027
6172
|
try {
|
|
6028
6173
|
await ledgerTicket.settle({
|
|
6029
6174
|
status: "failed",
|
|
6030
|
-
error:
|
|
6175
|
+
error: projectedError,
|
|
6031
6176
|
});
|
|
6032
6177
|
} catch (ledgerError) {
|
|
6033
6178
|
return attachDescriptor(
|
|
@@ -6041,20 +6186,29 @@ async function executeToolInner(
|
|
|
6041
6186
|
);
|
|
6042
6187
|
}
|
|
6043
6188
|
return attachDescriptor({
|
|
6044
|
-
error: `MCP tool execution failed: ${
|
|
6189
|
+
error: `MCP tool execution failed: ${projectedError.message}`,
|
|
6045
6190
|
mcpLedgerId: safeMcpProperty(ledgerTicket, "ledgerId") || null,
|
|
6046
6191
|
});
|
|
6047
6192
|
};
|
|
6048
6193
|
|
|
6049
6194
|
let pendingResult;
|
|
6050
6195
|
try {
|
|
6051
|
-
|
|
6196
|
+
const callArguments = [
|
|
6052
6197
|
localToolExecutor.serverName,
|
|
6053
6198
|
localToolExecutor.toolName,
|
|
6054
6199
|
mcpWireInput,
|
|
6055
|
-
]
|
|
6200
|
+
];
|
|
6201
|
+
if (signal) callArguments.push({ signal });
|
|
6202
|
+
pendingResult = Reflect.apply(
|
|
6203
|
+
mcpClient.callTool,
|
|
6204
|
+
mcpClient,
|
|
6205
|
+
callArguments,
|
|
6206
|
+
);
|
|
6056
6207
|
} catch (callError) {
|
|
6057
|
-
return await transportFailure(
|
|
6208
|
+
return await transportFailure(
|
|
6209
|
+
callError,
|
|
6210
|
+
isMcpToolResultAdmissionError(callError) ? "result" : "call",
|
|
6211
|
+
);
|
|
6058
6212
|
}
|
|
6059
6213
|
|
|
6060
6214
|
let result;
|
|
@@ -6091,7 +6245,10 @@ async function executeToolInner(
|
|
|
6091
6245
|
try {
|
|
6092
6246
|
result = await pendingResult;
|
|
6093
6247
|
} catch (callError) {
|
|
6094
|
-
return await transportFailure(
|
|
6248
|
+
return await transportFailure(
|
|
6249
|
+
callError,
|
|
6250
|
+
isMcpToolResultAdmissionError(callError) ? "result" : "call",
|
|
6251
|
+
);
|
|
6095
6252
|
}
|
|
6096
6253
|
} else {
|
|
6097
6254
|
let then;
|
|
@@ -6136,6 +6293,16 @@ async function executeToolInner(
|
|
|
6136
6293
|
result = pendingResult;
|
|
6137
6294
|
}
|
|
6138
6295
|
|
|
6296
|
+
try {
|
|
6297
|
+
result = admitMcpToolResult(
|
|
6298
|
+
localToolExecutor.serverName,
|
|
6299
|
+
result,
|
|
6300
|
+
localToolExecutor.toolResultConfig,
|
|
6301
|
+
).result;
|
|
6302
|
+
} catch (resultError) {
|
|
6303
|
+
return await transportFailure(resultError, "result");
|
|
6304
|
+
}
|
|
6305
|
+
|
|
6139
6306
|
let protocolError;
|
|
6140
6307
|
try {
|
|
6141
6308
|
if (
|
|
@@ -6683,12 +6850,21 @@ export const MAX_SUB_AGENTS_PER_RUN = 32;
|
|
|
6683
6850
|
* `substring(0, 5000)` that sliced mid-content with no marker and undercut even
|
|
6684
6851
|
* read_file's own 50k self-limit. Tools that self-limit (read_file, notebook
|
|
6685
6852
|
* render) stay below this; it is the final safety net for the ones that don't
|
|
6686
|
-
* (run_shell, search_files, run_code, MCP).
|
|
6853
|
+
* (run_shell, search_files, run_code, MCP). CC_MAX_TOOL_RESULT_CHARS may only
|
|
6854
|
+
* tighten the host ceiling; it cannot raise or disable it.
|
|
6687
6855
|
*/
|
|
6688
|
-
export const
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6856
|
+
export const MAX_TOOL_RESULT_CHARS_HARD_LIMIT = 50000;
|
|
6857
|
+
|
|
6858
|
+
export function resolveMaxToolResultChars(configured) {
|
|
6859
|
+
const value = Number(configured);
|
|
6860
|
+
return Number.isFinite(value) && value > 0
|
|
6861
|
+
? Math.min(MAX_TOOL_RESULT_CHARS_HARD_LIMIT, Math.max(1, Math.floor(value)))
|
|
6862
|
+
: MAX_TOOL_RESULT_CHARS_HARD_LIMIT;
|
|
6863
|
+
}
|
|
6864
|
+
|
|
6865
|
+
export const MAX_TOOL_RESULT_CHARS = resolveMaxToolResultChars(
|
|
6866
|
+
process.env.CC_MAX_TOOL_RESULT_CHARS,
|
|
6867
|
+
);
|
|
6692
6868
|
|
|
6693
6869
|
/**
|
|
6694
6870
|
* Cap a serialized tool result to `max` chars, appending a visible truncation
|
|
@@ -6698,10 +6874,11 @@ export const MAX_TOOL_RESULT_CHARS = (() => {
|
|
|
6698
6874
|
*/
|
|
6699
6875
|
export function capToolResultString(serialized, max = MAX_TOOL_RESULT_CHARS) {
|
|
6700
6876
|
const s = String(serialized ?? "");
|
|
6701
|
-
|
|
6877
|
+
const effectiveMax = resolveMaxToolResultChars(max);
|
|
6878
|
+
if (s.length <= effectiveMax) return s;
|
|
6702
6879
|
return (
|
|
6703
|
-
s.slice(0,
|
|
6704
|
-
`\n…[tool output truncated: showing the first ${
|
|
6880
|
+
s.slice(0, effectiveMax) +
|
|
6881
|
+
`\n…[tool output truncated: showing the first ${effectiveMax} of ${s.length} chars` +
|
|
6705
6882
|
` — narrow the request (read a line range, grep, or paginate) to see the rest]`
|
|
6706
6883
|
);
|
|
6707
6884
|
}
|
|
@@ -8143,6 +8320,42 @@ function _ollamaInitState() {
|
|
|
8143
8320
|
};
|
|
8144
8321
|
}
|
|
8145
8322
|
|
|
8323
|
+
function _streamUiCallbacks(onToken, onThinking) {
|
|
8324
|
+
let pending = [];
|
|
8325
|
+
const capture = (callback) =>
|
|
8326
|
+
typeof callback === "function"
|
|
8327
|
+
? (value) => {
|
|
8328
|
+
try {
|
|
8329
|
+
const result = callback(value);
|
|
8330
|
+
if (result && typeof result.then === "function") {
|
|
8331
|
+
pending.push(Promise.resolve(result));
|
|
8332
|
+
}
|
|
8333
|
+
} catch (error) {
|
|
8334
|
+
pending.push(Promise.reject(error));
|
|
8335
|
+
}
|
|
8336
|
+
}
|
|
8337
|
+
: callback;
|
|
8338
|
+
return {
|
|
8339
|
+
onToken: capture(onToken),
|
|
8340
|
+
onThinking: capture(onThinking),
|
|
8341
|
+
async settle() {
|
|
8342
|
+
if (pending.length === 0) return;
|
|
8343
|
+
const current = pending;
|
|
8344
|
+
pending = [];
|
|
8345
|
+
const outcomes = await Promise.allSettled(current);
|
|
8346
|
+
const fatal = outcomes.find(
|
|
8347
|
+
(outcome) =>
|
|
8348
|
+
outcome.status === "rejected" &&
|
|
8349
|
+
outcome.reason?.isOutputBackpressureFailure === true,
|
|
8350
|
+
);
|
|
8351
|
+
if (fatal) throw fatal.reason;
|
|
8352
|
+
// Generic UI callback failures retain their historical best-effort
|
|
8353
|
+
// semantics. Branded output failures are lifecycle failures and abort the
|
|
8354
|
+
// provider stream instead of allowing its terminal queue to grow.
|
|
8355
|
+
},
|
|
8356
|
+
};
|
|
8357
|
+
}
|
|
8358
|
+
|
|
8146
8359
|
function _ollamaReduceLine(state, line, onToken) {
|
|
8147
8360
|
const s = (line || "").trim();
|
|
8148
8361
|
if (!s) return state;
|
|
@@ -8213,6 +8426,7 @@ export function _accumulateOllamaStream(lines, onToken) {
|
|
|
8213
8426
|
* showing raw errors"). Pure + exported for unit tests.
|
|
8214
8427
|
*/
|
|
8215
8428
|
export function _streamErrorDisposition(err, signal, partialText) {
|
|
8429
|
+
if (err?.isOutputBackpressureFailure === true) return "rethrow";
|
|
8216
8430
|
if (isAbortError(err)) return "rethrow";
|
|
8217
8431
|
if (signal && signal.aborted) return "rethrow";
|
|
8218
8432
|
if (typeof partialText === "string" && partialText.trim()) return "preserve";
|
|
@@ -8427,6 +8641,7 @@ async function _chatOllamaStreaming(
|
|
|
8427
8641
|
throw new Error(await formatProviderResponseError("ollama", response));
|
|
8428
8642
|
}
|
|
8429
8643
|
const state = _ollamaInitState();
|
|
8644
|
+
const ui = _streamUiCallbacks(onToken);
|
|
8430
8645
|
const reader = response.body.getReader();
|
|
8431
8646
|
const decoder = new TextDecoder();
|
|
8432
8647
|
let buf = "";
|
|
@@ -8439,11 +8654,15 @@ async function _chatOllamaStreaming(
|
|
|
8439
8654
|
buf += decoder.decode(value, { stream: true });
|
|
8440
8655
|
let idx;
|
|
8441
8656
|
while ((idx = buf.indexOf("\n")) >= 0) {
|
|
8442
|
-
_ollamaReduceLine(state, buf.slice(0, idx), onToken);
|
|
8657
|
+
_ollamaReduceLine(state, buf.slice(0, idx), ui.onToken);
|
|
8658
|
+
await ui.settle();
|
|
8443
8659
|
buf = buf.slice(idx + 1);
|
|
8444
8660
|
}
|
|
8445
8661
|
}
|
|
8446
|
-
if (buf.trim())
|
|
8662
|
+
if (buf.trim()) {
|
|
8663
|
+
_ollamaReduceLine(state, buf, ui.onToken);
|
|
8664
|
+
await ui.settle();
|
|
8665
|
+
}
|
|
8447
8666
|
} catch (err) {
|
|
8448
8667
|
if (_streamErrorDisposition(err, signal, state.content) === "rethrow")
|
|
8449
8668
|
throw err;
|
|
@@ -8613,6 +8832,7 @@ async function _chatAnthropicStreaming(
|
|
|
8613
8832
|
throw new Error(await formatProviderResponseError("anthropic", response));
|
|
8614
8833
|
}
|
|
8615
8834
|
const state = _anthropicInitState();
|
|
8835
|
+
const ui = _streamUiCallbacks(onToken, onThinking);
|
|
8616
8836
|
const reader = response.body.getReader();
|
|
8617
8837
|
const decoder = new TextDecoder();
|
|
8618
8838
|
let buf = "";
|
|
@@ -8625,10 +8845,15 @@ async function _chatAnthropicStreaming(
|
|
|
8625
8845
|
buf += decoder.decode(value, { stream: true });
|
|
8626
8846
|
const lines = buf.split("\n");
|
|
8627
8847
|
buf = lines.pop() || "";
|
|
8628
|
-
for (const line of lines)
|
|
8629
|
-
_anthropicReduceLine(state, line, onToken, onThinking);
|
|
8848
|
+
for (const line of lines) {
|
|
8849
|
+
_anthropicReduceLine(state, line, ui.onToken, ui.onThinking);
|
|
8850
|
+
await ui.settle();
|
|
8851
|
+
}
|
|
8852
|
+
}
|
|
8853
|
+
if (buf.trim()) {
|
|
8854
|
+
_anthropicReduceLine(state, buf, ui.onToken, ui.onThinking);
|
|
8855
|
+
await ui.settle();
|
|
8630
8856
|
}
|
|
8631
|
-
if (buf.trim()) _anthropicReduceLine(state, buf, onToken, onThinking);
|
|
8632
8857
|
} catch (err) {
|
|
8633
8858
|
if (_streamErrorDisposition(err, signal, state.text) === "rethrow")
|
|
8634
8859
|
throw err;
|
|
@@ -8765,6 +8990,7 @@ async function _chatOpenAIStreaming(
|
|
|
8765
8990
|
throw new Error(await formatProviderResponseError(provider, response));
|
|
8766
8991
|
}
|
|
8767
8992
|
const state = _openaiInitState();
|
|
8993
|
+
const ui = _streamUiCallbacks(onToken);
|
|
8768
8994
|
const reader = response.body.getReader();
|
|
8769
8995
|
const decoder = new TextDecoder();
|
|
8770
8996
|
let buf = "";
|
|
@@ -8777,9 +9003,15 @@ async function _chatOpenAIStreaming(
|
|
|
8777
9003
|
buf += decoder.decode(value, { stream: true });
|
|
8778
9004
|
const lines = buf.split("\n");
|
|
8779
9005
|
buf = lines.pop() || "";
|
|
8780
|
-
for (const line of lines)
|
|
9006
|
+
for (const line of lines) {
|
|
9007
|
+
_openaiReduceLine(state, line, ui.onToken);
|
|
9008
|
+
await ui.settle();
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
if (buf.trim()) {
|
|
9012
|
+
_openaiReduceLine(state, buf, ui.onToken);
|
|
9013
|
+
await ui.settle();
|
|
8781
9014
|
}
|
|
8782
|
-
if (buf.trim()) _openaiReduceLine(state, buf, onToken);
|
|
8783
9015
|
} catch (err) {
|
|
8784
9016
|
if (_streamErrorDisposition(err, signal, state.text) === "rethrow")
|
|
8785
9017
|
throw err;
|