@qwen-code/qwen-code 0.20.0 → 0.20.1-nightly.20260724.7d17c44a3
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/bundled/qc-helper/docs/configuration/settings.md +1 -1
- package/bundled/qc-helper/docs/features/auto-mode.md +19 -16
- package/bundled/qc-helper/docs/features/commands.md +54 -0
- package/bundled/qc-helper/docs/features/sub-agents.md +16 -7
- package/bundled/qc-helper/docs/integration-github-action.md +1 -1
- package/bundled/qc-helper/docs/qwen-serve.md +2 -1
- package/bundled/review/DESIGN.md +2 -2
- package/bundled/review/SKILL.md +7 -5
- package/chunks/MaxSizedBox-LGRTXB47.js +84 -0
- package/chunks/{StandaloneSessionPicker-CEGO2AZX.js → StandaloneSessionPicker-H3TBU3C3.js} +68 -56
- package/chunks/{acp-startup-profiler-N3RHHXJ3.js → acp-startup-profiler-RV3IV562.js} +2 -2
- package/chunks/{acpAgent-YUR43TLG.js → acpAgent-5D7P4BB5.js} +2061 -556
- package/chunks/agent-W7UAHCCI.js +80 -0
- package/chunks/agent-headless-KTBMPRSC.js +74 -0
- package/chunks/{anthropicContentGenerator-HVKLXOOU.js → anthropicContentGenerator-ZLQ3X2HI.js} +112 -45
- package/chunks/{artifact-tool-WBCAMD3O.js → artifact-tool-OKMWONT6.js} +3 -3
- package/chunks/{askUserQuestion-6DZC4UV5.js → askUserQuestion-V6FUS23G.js} +3 -3
- package/chunks/bridge-FFC4C6VD.js +89 -0
- package/chunks/{build-SSCNEHZZ.js → build-RV63TIRH.js} +2 -3
- package/chunks/{ca-2SL2BXTK.js → ca-GKRQZ7AM.js} +612 -201
- package/chunks/{channel-worker-group-53CMOPFT.js → channel-worker-group-MA3WXWYX.js} +7 -6
- package/chunks/{channel-worker-manager-UTXILKC2.js → channel-worker-manager-TIYYYBCT.js} +189 -29
- package/chunks/{channel-worker-supervisor-ZGO2W2MD.js → channel-worker-supervisor-CXRCDA4Y.js} +6 -5
- package/chunks/{chunk-TYQMGACW.js → chunk-22C7BQ6D.js} +508 -10967
- package/chunks/{chunk-4EP2PYYL.js → chunk-2G6QIHYL.js} +5 -5
- package/chunks/{chunk-H2XVO6NE.js → chunk-2MIN6GRR.js} +1 -1
- package/chunks/chunk-2RFKHEXL.js +74 -0
- package/chunks/{chunk-7SXZC7ID.js → chunk-2WTVWAKT.js} +7 -6
- package/chunks/{chunk-TIH2ZTOC.js → chunk-32A4PI3E.js} +2 -2
- package/chunks/chunk-36HSVBBU.js +469 -0
- package/chunks/{chunk-IR46U7RB.js → chunk-3FB2Y2OE.js} +3 -3
- package/chunks/{chunk-QR6U5QPP.js → chunk-3SJ43L4W.js} +4 -0
- package/chunks/chunk-3Z43GZUQ.js +32 -0
- package/chunks/chunk-43T5WDQ7.js +127 -0
- package/chunks/chunk-46UV252V.js +128 -0
- package/chunks/{chunk-JD3MKVKL.js → chunk-4K56OJFJ.js} +1 -1
- package/chunks/{chunk-KTUQMDEP.js → chunk-4K7VDKAD.js} +1 -1
- package/chunks/{chunk-QKYTTBYW.js → chunk-4LVZNIDO.js} +1 -1
- package/chunks/{chunk-OWCALFEG.js → chunk-54R2CV2G.js} +1 -1
- package/chunks/{chunk-ZEOZL37W.js → chunk-57FIIFJN.js} +1 -1
- package/chunks/chunk-5BS3KLRP.js +6194 -0
- package/chunks/{chunk-NEEB7UEN.js → chunk-6GMVPFB2.js} +153 -72
- package/chunks/{chunk-GMGDLUC7.js → chunk-6IL7KRLE.js} +1 -1
- package/chunks/chunk-6PVPNMXU.js +29 -0
- package/chunks/chunk-6QHAUJUE.js +293 -0
- package/chunks/chunk-6VK3IRTX.js +10017 -0
- package/chunks/{chunk-BDBMYST4.js → chunk-6X4GWOPW.js} +1 -1
- package/chunks/{chunk-AYCDXHZB.js → chunk-7Z6JQEL6.js} +1 -1
- package/chunks/{chunk-FSL5W5TI.js → chunk-AFFGGOF6.js} +4 -4
- package/chunks/chunk-AMDSOFFV.js +10860 -0
- package/chunks/chunk-AXUW635Q.js +934 -0
- package/chunks/{chunk-A5LYNIW7.js → chunk-BJBUDCM3.js} +8 -8
- package/chunks/chunk-BK2UNYWD.js +29 -0
- package/chunks/{chunk-6RLROE6G.js → chunk-BLFVGB7D.js} +30 -4
- package/chunks/chunk-BPJSQIJX.js +100 -0
- package/chunks/{chunk-FLSVD6BS.js → chunk-BRTR7S7O.js} +3 -3
- package/chunks/{chunk-KG3XV6FH.js → chunk-BSNWBC33.js} +32 -2
- package/chunks/chunk-BULDBTYC.js +153 -0
- package/chunks/{chunk-PBWEWI4N.js → chunk-BW5Z5NOG.js} +83 -74
- package/chunks/{chunk-EIAK6Q2B.js → chunk-C3VHAXP2.js} +20 -3
- package/chunks/{chunk-6AFUCL3D.js → chunk-CEZB3XFD.js} +1 -1
- package/chunks/chunk-CHMENNJV.js +1832 -0
- package/chunks/{chunk-TMQ6XQCX.js → chunk-CK3IEEHR.js} +416 -291
- package/chunks/{chunk-OYZWQNWG.js → chunk-CK6UABV2.js} +2 -2
- package/chunks/{chunk-VZQUV7VK.js → chunk-CKTMY3EP.js} +1 -1
- package/chunks/{chunk-VDWBQ5AW.js → chunk-CUPAVLRY.js} +5 -2
- package/chunks/{chunk-I2PYAYFM.js → chunk-CXUFILV3.js} +3 -3
- package/chunks/chunk-DP3IHZGG.js +1498 -0
- package/chunks/{chunk-BMWMT5Y2.js → chunk-DP5GT2MW.js} +7 -375
- package/chunks/{chunk-D22SX43D.js → chunk-DWNZ6PVQ.js} +1 -1
- package/chunks/{chunk-5SCI6E3E.js → chunk-E4IMU4Y5.js} +1 -1
- package/chunks/{chunk-DP5GXXNZ.js → chunk-EL2IQ2S5.js} +5 -1
- package/chunks/{chunk-EZVDJFZ7.js → chunk-ERLGR7GI.js} +1 -1
- package/chunks/{chunk-IVPSS6EL.js → chunk-F5MBYZSU.js} +4 -4
- package/chunks/{chunk-AQIEINAY.js → chunk-F6IYL66A.js} +28 -1766
- package/chunks/{chunk-FEOZBUMT.js → chunk-FODK6UMO.js} +0 -27
- package/chunks/{chunk-PGEPSDJI.js → chunk-FWNZ7CVN.js} +24 -20
- package/chunks/{chunk-5JBR5XIK.js → chunk-G7EFBBVF.js} +220 -141
- package/chunks/chunk-GLNBDYUX.js +38 -0
- package/chunks/{chunk-ANPINBOF.js → chunk-H4YKEV2X.js} +5 -5
- package/chunks/{chunk-TDKQP3M6.js → chunk-HIJQF5B5.js} +1 -1
- package/chunks/{chunk-FQD7GFSV.js → chunk-HJJDKFL5.js} +3 -3
- package/chunks/{chunk-4N3KMAIL.js → chunk-HPWHDJID.js} +152 -35
- package/chunks/{chunk-KQNM4EO7.js → chunk-HQCSRJ3P.js} +138 -6
- package/chunks/chunk-HTR4WV6U.js +327 -0
- package/chunks/{chunk-YWEW33JY.js → chunk-HVO55LUD.js} +7 -7
- package/chunks/{chunk-MJ6S23WZ.js → chunk-HZEWYOVI.js} +5 -5
- package/chunks/chunk-IFG6TYJ2.js +16577 -0
- package/chunks/{chunk-B3KGZCQN.js → chunk-IJTOWOD7.js} +322 -202
- package/chunks/{chunk-RS7MT2QG.js → chunk-IPUUTYMV.js} +2 -4
- package/chunks/{chunk-4ILMYHEI.js → chunk-IRDZJSCL.js} +3 -3
- package/chunks/{chunk-XU457J4V.js → chunk-IRH27ZC2.js} +2 -2
- package/chunks/{chunk-33XUAINQ.js → chunk-J5UKQEFG.js} +69 -9
- package/chunks/{chunk-G45X5TRN.js → chunk-JCW2R7WC.js} +1 -72
- package/chunks/{chunk-S2XVRHDN.js → chunk-JDFBBGRD.js} +1 -1
- package/chunks/{chunk-4XNLIGVA.js → chunk-JKCALGYN.js} +1023 -383
- package/chunks/{chunk-TJTKSVIV.js → chunk-JLU636DO.js} +5 -1
- package/chunks/{chunk-VEXFOTEO.js → chunk-JYUSL2V4.js} +3 -3
- package/chunks/{chunk-S2PD3EZD.js → chunk-KJEMJWNH.js} +1 -1
- package/chunks/{chunk-E2UVIFI2.js → chunk-KRXPRVGL.js} +0 -1
- package/chunks/{chunk-CZF3E5GF.js → chunk-LA5H3LM5.js} +1 -1
- package/chunks/{chunk-NDMQLV4Y.js → chunk-LBAO2XRA.js} +4 -4
- package/chunks/{chunk-7RMOXZTC.js → chunk-LDPP5VTZ.js} +4 -4
- package/chunks/{chunk-KDC6GNQR.js → chunk-LEEWLFHW.js} +4 -4
- package/chunks/{chunk-KX6UK4VJ.js → chunk-LI4I37W4.js} +22152 -18007
- package/chunks/{chunk-OOCI5VVU.js → chunk-LIZRAKPB.js} +1 -1
- package/chunks/{chunk-AJSJ5TTU.js → chunk-LP2E4MQG.js} +1 -1
- package/chunks/chunk-LS77BEZP.js +405 -0
- package/chunks/{chunk-BRRF37CO.js → chunk-LYTBLSSW.js} +5 -5
- package/chunks/{chunk-DBE4QFZS.js → chunk-MB7ENXPR.js} +39 -37
- package/chunks/{chunk-GKY2OJ7R.js → chunk-MOHAWVLH.js} +4 -4
- package/chunks/chunk-NABLFI57.js +82 -0
- package/chunks/chunk-NBQDBANR.js +411 -0
- package/chunks/{chunk-EAUYY7SS.js → chunk-NOAAFNTJ.js} +43 -10
- package/chunks/chunk-NXS53EA7.js +1462 -0
- package/chunks/{chunk-C27BYUX6.js → chunk-OQB4EXO4.js} +14 -11
- package/chunks/{chunk-NHDKSOEY.js → chunk-P3QQPMQA.js} +5 -5
- package/chunks/{chunk-OP4MOGXF.js → chunk-P5RRUHL7.js} +23 -1
- package/chunks/{chunk-KOR3XKCA.js → chunk-PBII2NFX.js} +12 -6
- package/chunks/{chunk-O3OCNYY5.js → chunk-PDYB7HG2.js} +2 -2
- package/chunks/{chunk-2HOVDT7W.js → chunk-PFSUKTZH.js} +1 -1
- package/chunks/chunk-PKL3HGNZ.js +2299 -0
- package/chunks/{chunk-5DTTYNB7.js → chunk-PQNHRFJC.js} +16 -3
- package/chunks/{chunk-OLMETXLX.js → chunk-PXHK5ONM.js} +41 -9
- package/chunks/{chunk-PF4CHQOJ.js → chunk-Q6GU6TKM.js} +11 -10
- package/chunks/{chunk-4ODB7WIB.js → chunk-QAFKR7WR.js} +1 -1
- package/chunks/{chunk-PBATSWUQ.js → chunk-QBUDF33N.js} +1 -1
- package/chunks/{chunk-BVLROR2T.js → chunk-QLJUC7TG.js} +1 -1
- package/chunks/{chunk-UEY4AYUL.js → chunk-QNLNLENL.js} +2 -2
- package/chunks/{chunk-333CXMNJ.js → chunk-QXZTZJLX.js} +5 -5
- package/chunks/chunk-R6D2CTQR.js +289 -0
- package/chunks/{chunk-7PZ2ATFZ.js → chunk-R6SKHK3T.js} +54 -29
- package/chunks/{chunk-OONJNQ42.js → chunk-RGG6M2WF.js} +4 -4
- package/chunks/{chunk-RFIAR4YL.js → chunk-RV4C2ZFG.js} +1 -1
- package/chunks/{chunk-O3Z73NBP.js → chunk-RW2NEXYJ.js} +15 -11
- package/chunks/{chunk-HZPN55E5.js → chunk-SJEDL7DI.js} +1 -1
- package/chunks/{chunk-AKX4WPPP.js → chunk-SWBJRDYC.js} +866 -183
- package/chunks/{chunk-NBMIC7DR.js → chunk-SX4PK3FC.js} +145 -5
- package/chunks/chunk-T3452DP5.js +246 -0
- package/chunks/{chunk-TB6UDU4T.js → chunk-THJNPLI4.js} +16 -16
- package/chunks/{chunk-T4TZQJ7W.js → chunk-TWPJO254.js} +5 -16
- package/chunks/chunk-U7ZFW55U.js +2098 -0
- package/chunks/{chunk-JNWZQ27S.js → chunk-UCOJC6EB.js} +72 -23
- package/chunks/{chunk-W7H223ZZ.js → chunk-UGYMA4EI.js} +1 -1
- package/chunks/{chunk-X6YQWCIJ.js → chunk-UH3WSE5L.js} +13 -1
- package/chunks/{chunk-2LL7TXB4.js → chunk-UH7242DI.js} +3 -3
- package/chunks/{chunk-CB2HFGRV.js → chunk-UJV643E2.js} +31 -6
- package/chunks/chunk-UO7DCGEV.js +121 -0
- package/chunks/{chunk-Y2ENGUD6.js → chunk-UPF7PTBI.js} +79 -2
- package/chunks/chunk-UW5EOVUN.js +249 -0
- package/chunks/{chunk-SJMV7ZBK.js → chunk-VLVO52KC.js} +8 -8
- package/chunks/{chunk-R3VWUU2E.js → chunk-VYPFXUCB.js} +1 -1
- package/chunks/{chunk-S2W2LVDU.js → chunk-WHFK6G6U.js} +8 -9
- package/chunks/chunk-WI3KCKZ5.js +391 -0
- package/chunks/{chunk-NGFEPAE6.js → chunk-WLEFWSSC.js} +8 -6
- package/chunks/{chunk-XVVH63JG.js → chunk-WUJXJ34P.js} +3 -3
- package/chunks/{chunk-MAQQGNQ5.js → chunk-WYLPWQHJ.js} +56 -717
- package/chunks/{chunk-D2VIDMVM.js → chunk-X6N25LXS.js} +2 -2
- package/chunks/chunk-XAWJ2526.js +1049 -0
- package/chunks/{chunk-CV63PP6U.js → chunk-YCIM6O3I.js} +1 -1
- package/chunks/{chunk-OEO2ERWK.js → chunk-Z44CVEUF.js} +54 -33
- package/chunks/{chunk-TKLLK6XQ.js → chunk-ZT4POVWC.js} +11 -11
- package/chunks/{chunk-NIJEXGV6.js → chunk-ZXYUQXY5.js} +148 -10
- package/chunks/{computer-use-NIWQNUZF.js → computer-use-UJ5T34TE.js} +50 -37
- package/chunks/{config-utils-AHQ6YZ66.js → config-utils-XQRXHAN3.js} +3 -3
- package/chunks/contextCommand-CSCB4E5M.js +79 -0
- package/chunks/{create-sub-session-MGNX52P3.js → create-sub-session-55F3GOLK.js} +46 -33
- package/chunks/{create-sub-session-P26FE5GG.js → create-sub-session-JPCSYZAJ.js} +3 -3
- package/chunks/{cron-create-JWFHBDRQ.js → cron-create-CUMELMPL.js} +6 -6
- package/chunks/{cron-delete-GDX4E26G.js → cron-delete-QZFV6U3P.js} +5 -5
- package/chunks/{cron-list-USMAIWPT.js → cron-list-IDKO7ZO2.js} +5 -5
- package/chunks/{daemon-RG2MAI6T.js → daemon-7LP7R6IU.js} +500 -133
- package/chunks/daemon-status-provider-6YNZ3UAE.js +88 -0
- package/chunks/{de-I7ZIYXZC.js → de-4IBXM7CN.js} +5 -1
- package/chunks/{dist-WGTQO7F2.js → dist-376652EZ.js} +114 -28
- package/chunks/{dist-53PZYC5B.js → dist-3YCTE6HD.js} +2 -2
- package/chunks/{dist-2BHAYBKP.js → dist-D7Z3HOO7.js} +14 -2
- package/chunks/{dist-FUTEXY6A.js → dist-MEGJFGAI.js} +40 -9
- package/chunks/{dist-2MIU4UUH.js → dist-NQ436QEX.js} +1 -1
- package/chunks/{dist-AU7NQQRP.js → dist-NQNTOIEN.js} +26 -2
- package/chunks/earlyInputCapture-HPUVJ2KH.js +81 -0
- package/chunks/{edit-3QV3JZJL.js → edit-7CMAN3F4.js} +50 -39
- package/chunks/{en-XE34GKAA.js → en-SALLIJS7.js} +6 -1
- package/chunks/{enter-worktree-4GMMF7EG.js → enter-worktree-3PH4YTY2.js} +49 -36
- package/chunks/{enterPlanMode-L5UWBAUC.js → enterPlanMode-MSXLSWLI.js} +55 -37
- package/chunks/{environment-3OV7UQOT.js → environment-KS36ZHBE.js} +48 -35
- package/chunks/errors-LCPFS62A.js +87 -0
- package/chunks/{exit-worktree-DDP57JLV.js → exit-worktree-ARA4C3CK.js} +49 -36
- package/chunks/{exitPlanMode-CJBLGPIP.js → exitPlanMode-GCDIQPB7.js} +49 -36
- package/chunks/{fast-path-M6RP2ING.js → fast-path-IDHBVIT6.js} +3 -2
- package/chunks/{fr-X7KDVZIY.js → fr-WVHEBDDB.js} +5 -1
- package/chunks/{gemini-H4PHBJTL.js → gemini-2AFQJMX5.js} +141 -105
- package/chunks/{geminiContentGenerator-VURJYPWP.js → geminiContentGenerator-UDIH3YI6.js} +9 -8
- package/chunks/{getMachineId-bsd-EXV7SWPA.js → getMachineId-bsd-QFVLPUPT.js} +1 -1
- package/chunks/{getMachineId-darwin-IUOMFXU3.js → getMachineId-darwin-DGMQQE2E.js} +1 -1
- package/chunks/{getMachineId-linux-K7XJYFHL.js → getMachineId-linux-R4Z6CSWC.js} +1 -1
- package/chunks/{getMachineId-unsupported-EA5FDRJ6.js → getMachineId-unsupported-Z3SBVBUV.js} +1 -1
- package/chunks/{getMachineId-win-KBA6RAI5.js → getMachineId-win-SCK5UFDT.js} +1 -1
- package/chunks/{glob-2KUSRAVQ.js → glob-HCL7HZ67.js} +49 -36
- package/chunks/{grep-B5RXVESV.js → grep-CJLBSCTV.js} +49 -36
- package/chunks/handleAutoUpdate-Q572P3FL.js +80 -0
- package/chunks/i18n-OBB4R7SR.js +96 -0
- package/chunks/initializer-LXEY6V3C.js +85 -0
- package/chunks/installationInfo-XUAOVMEE.js +79 -0
- package/chunks/{ja-2ICT3KXF.js → ja-KY4ROZTE.js} +5 -1
- package/chunks/{keychain-token-storage-DWRJMNH3.js → keychain-token-storage-6ACJDYIB.js} +3 -3
- package/chunks/{kittyProtocolDetector-HCNNKJTI.js → kittyProtocolDetector-MBRTDRBK.js} +5 -3
- package/chunks/list-WAXY7QOU.js +88 -0
- package/chunks/list-agents-AH3P5NB7.js +80 -0
- package/chunks/loadedSettingsAdapter-OZFNBRHE.js +82 -0
- package/chunks/loggingContentGenerator-7WDTTE6G.js +1068 -0
- package/chunks/{loop-wakeup-5GLTUBHA.js → loop-wakeup-IHRW6TNB.js} +7 -7
- package/chunks/{ls-FHBY3Y7I.js → ls-ZAXZ2G2W.js} +5 -5
- package/chunks/{lsp-B6VMEW6Y.js → lsp-R4ZG3UGQ.js} +3 -3
- package/chunks/managed-npm-update-N42DO5QW.js +339 -0
- package/chunks/mcp-6SOORKTY.js +82 -0
- package/chunks/{monitor-GLJZDNPS.js → monitor-4PSVNVU4.js} +51 -37
- package/chunks/node-UUDY34IG.js +305 -0
- package/chunks/nonInteractiveCli-FBR5S7IZ.js +140 -0
- package/chunks/{notebook-edit-AVCIWS4F.js → notebook-edit-QK26632S.js} +50 -39
- package/chunks/{openaiContentGenerator-B7W24G3D.js → openaiContentGenerator-IXJS6C2U.js} +33 -20
- package/chunks/pidfile-UCFCJOAP.js +85 -0
- package/chunks/{processUtils-XZPY2PBB.js → processUtils-YL2LXON2.js} +2 -2
- package/chunks/{pt-JJ4XPIBP.js → pt-OK455PLH.js} +5 -1
- package/chunks/{qwenContentGenerator-6GUTWJIC.js → qwenContentGenerator-H6WZPJKC.js} +56 -36
- package/chunks/{qwenOAuth2-GASEEWGU.js → qwenOAuth2-HTROHKXO.js} +10 -23
- package/chunks/read-file-FOYTMUNL.js +31 -0
- package/chunks/{read-mcp-resource-AKCL7I43.js → read-mcp-resource-65BWNF3F.js} +3 -3
- package/chunks/{record-artifact-PEUB7727.js → record-artifact-2RLSOP6U.js} +3 -3
- package/chunks/resumeHistoryUtils-ZNHTWBXS.js +90 -0
- package/chunks/ripGrep-K4K4QLNJ.js +72 -0
- package/chunks/{ru-STR4KTW7.js → ru-7SPDGMGD.js} +5 -1
- package/chunks/{run-qwen-serve-OZGR3FQA.js → run-qwen-serve-XI4MCAFV.js} +343 -88
- package/chunks/runtime-4CTBU5WX.js +115 -0
- package/chunks/{scheduler-Z7QLMUWA.js → scheduler-TTEITHBF.js} +46 -33
- package/chunks/sdk-exporters-grpc-N3OLDF63.js +23214 -0
- package/chunks/sdk-exporters-http-AOHAEOMC.js +563 -0
- package/chunks/sdk-impl-TLQOC7P4.js +9193 -0
- package/chunks/{send-message-3RHE7HSM.js → send-message-GEY4CNPS.js} +47 -8
- package/chunks/serve-W7UKJTQT.js +88 -0
- package/chunks/{server-SO64U3X5.js → server-JD5PIE7A.js} +3069 -517
- package/chunks/{session-2KL2WQAH.js → session-R4BDHLYR.js} +112 -177
- package/chunks/{settings-KITVOUSV.js → settings-BXZHA6TZ.js} +50 -37
- package/chunks/shell-XYMFCGN5.js +82 -0
- package/chunks/{skill-SOQHY455.js → skill-YKXYEPOF.js} +25 -20
- package/chunks/spawnChannel-IO4HQLFS.js +81 -0
- package/chunks/{src-43LM7JLB.js → src-LKKTJ4NG.js} +382 -235
- package/chunks/standalone-update-76JG7DVN.js +91 -0
- package/chunks/{startInteractiveUI-3RGTGEX5.js → startInteractiveUI-BXWQUXAS.js} +1314 -958
- package/chunks/{syntheticOutput-FG5PQKIR.js → syntheticOutput-2WNMXEU5.js} +4 -4
- package/chunks/task-create-R5H74Y76.js +25 -0
- package/chunks/{task-list-QWSY4ZIU.js → task-list-WXAFDSRY.js} +7 -7
- package/chunks/{task-stop-GWC6UWAL.js → task-stop-CHFZP23W.js} +4 -4
- package/chunks/{task-update-NCTAB73Q.js → task-update-Z44A4GAR.js} +11 -9
- package/chunks/{team-create-FXN3PEBP.js → team-create-5Y3MCAIM.js} +49 -36
- package/chunks/{team-delete-KK37HTOG.js → team-delete-YDCMRSI4.js} +7 -7
- package/chunks/{team-plan-approval-GEIZ356Q.js → team-plan-approval-HYJJZ76T.js} +49 -36
- package/chunks/theme-manager-3YF2SUZL.js +76 -0
- package/chunks/{todoWrite-ERCAMLFS.js → todoWrite-ED2IVZJL.js} +5 -5
- package/chunks/{tool-search-XKK7DNOK.js → tool-search-3ZO2XMEP.js} +21 -17
- package/chunks/total-session-admission-NDF7EVG7.js +83 -0
- package/chunks/trustedFolders-Q7RALK4T.js +92 -0
- package/chunks/{chunk-6EFTQYW7.js → undici-3FJYTMOF.js} +24 -399
- package/chunks/{chunk-L573Z2QZ.js → undici-PYHBDDPN.js} +1 -5
- package/chunks/{update-relaunch-FMVZK6XF.js → update-relaunch-BTW5XGVT.js} +17 -17
- package/chunks/updateCheck-MXIU6DWQ.js +91 -0
- package/chunks/useAutoAcceptIndicator-BJXHJW77.js +92 -0
- package/chunks/{validateNonInterActiveAuth-PRVEB6GG.js → validateNonInterActiveAuth-FLEPF3QQ.js} +90 -76
- package/chunks/{version-AZMG6KWL.js → version-75VRONIL.js} +1 -1
- package/chunks/{web-fetch-EPGJ5OQQ.js → web-fetch-5X27LYHB.js} +101 -41
- package/chunks/web-search-IDMTBJUP.js +718 -0
- package/chunks/{workflow-UTNVPW22.js → workflow-JOD2OPFQ.js} +54 -40
- package/chunks/workspace-providers-status-WDLBDLPG.js +85 -0
- package/chunks/{workspace-registration-store-F3ZX3YHT.js → workspace-registration-store-26Z6J6P5.js} +9 -3
- package/chunks/workspace-registry-IABDATX3.js +87 -0
- package/chunks/workspace-service-BI4KDYPD.js +97 -0
- package/chunks/workspace-skills-status-OVB4LPHA.js +84 -0
- package/chunks/write-file-276AJ7KE.js +72 -0
- package/chunks/{zh-6ANG2HTL.js → zh-Q54GA5SV.js} +6 -1
- package/chunks/{zh-TW-4RR3YHNN.js → zh-TW-VOBNFOPU.js} +6 -1
- package/cli-entry.js +164 -12
- package/cli.js +19 -12
- package/locales/ca.js +773 -203
- package/locales/de.js +8 -2
- package/locales/en.js +9 -2
- package/locales/fr.js +8 -2
- package/locales/ja.js +8 -2
- package/locales/pt.js +8 -2
- package/locales/ru.js +8 -2
- package/locales/zh-TW.js +9 -2
- package/locales/zh.js +9 -2
- package/package.json +3 -3
- package/web-shell/assets/{arc-Buk1besA.js → arc-CMb7lr2P.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-B1aUKYDC.js → architectureDiagram-3BPJPVTR-D6KQ5Kwm.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-CRTdg3Zx.js → blockDiagram-GPEHLZMM-Ce7YYSf8.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-DFdRMp5g.js → c4Diagram-AAUBKEIU-DaStHfor.js} +1 -1
- package/web-shell/assets/channel-Dg4f-Kry.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-4rYQdkEI.js → chunk-2J33WTMH-CPaqadg9.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-Coi-pQJy.js → chunk-4BX2VUAB-Veh9ZGKg.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-BtBjz02t.js → chunk-55IACEB6-BPTX5n4q.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-CGYOWorl.js → chunk-727SXJPM-CtXsE_ca.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-CH5AKhqx.js → chunk-AQP2D5EJ-D8DDCJ8h.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-Cd50-w85.js → chunk-FMBD7UC4-cjMDGzHz.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-C2wF3KCK.js → chunk-ND2GUHAM-BaZ1hNhV.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-pCeRTaWi.js → chunk-QZHKN3VN-C7w-9w5-.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CT7Fo2aW.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CT7Fo2aW.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-B-_fAB6D.js → cose-bilkent-S5V4N54A-DqvBEEIe.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-ChSPNHpL.js → dagre-BM42HDAG-RkPyoMAk.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-BX7cFOF3.js → diagram-2AECGRRQ-D9b6nNyg.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BQUTW92n.js → diagram-5GNKFQAL-CiiNKUIy.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-BkYPh3e4.js → diagram-KO2AKTUF-CP1qizXd.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-Cl6jsNyx.js → diagram-LMA3HP47-BGe30TWx.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-DRWoHz8n.js → diagram-OG6HWLK6-CvoEPARH.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-CGvFcZco.js → erDiagram-TEJ5UH35-DWfLzVkV.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-vms6oVdv.js → flowDiagram-I6XJVG4X-D-dTQmo6.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-ukT_sfmi.js → ganttDiagram-6RSMTGT7-CYPHKaGY.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Bn2ZE2Ut.js → gitGraphDiagram-PVQCEYII-DA7_aQYD.js} +1 -1
- package/web-shell/assets/index-B0i-TOYM.css +5 -0
- package/web-shell/assets/index-CgCHD46L.js +1225 -0
- package/web-shell/assets/{index-wFXp7W68.js → index-DqHNAB8C.js} +1 -1
- package/web-shell/assets/{infoDiagram-5YYISTIA-DHJdSi7x.js → infoDiagram-5YYISTIA-B87ljDPa.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-DOvd2Wph.js → ishikawaDiagram-YF4QCWOH-CYSpyjaN.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CH_urMCT.js → journeyDiagram-JHISSGLW-DAL6Js6f.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-FKiBdgbH.js → kanban-definition-UN3LZRKU-_zufKGJv.js} +1 -1
- package/web-shell/assets/{linear-0ZVQFVKf.js → linear-DidhMgku.js} +1 -1
- package/web-shell/assets/{mermaid.core-DJ05ZZIK.js → mermaid.core-DAkX3h3a.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-BPuUhkUm.js → mindmap-definition-RKZ34NQL-DbZxUBEH.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-yLFKcXyG.js → pieDiagram-4H26LBE5-Du9uoqrf.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-irWqc1pE.js → quadrantDiagram-W4KKPZXB-DwjELuKm.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-B_4uMoIV.js → requirementDiagram-4Y6WPE33-BAqfVtBL.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-ciA4GPwk.js → sankeyDiagram-5OEKKPKP--hm2VpmK.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CRdZvy0U.js → sequenceDiagram-3UESZ5HK-R5MUQaIt.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-DaYIkCCn.js → stateDiagram-AJRCARHV-VsX032xQ.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-uPWLcSfy.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-oBUKv6iH.js → timeline-definition-PNZ67QCA-BqjVRXzg.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-CGW9Sdmb.js → vennDiagram-CIIHVFJN-i2tkvlkg.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-CvwKJOCm.js → wardley-L42UT6IY-Ch8G49EM.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Ipc260sN.js → wardleyDiagram-YWT4CUSO-bYpWeQNy.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-D6-CM7pK.js → xychartDiagram-2RQKCTM6-C9NhuBqB.js} +1 -1
- package/web-shell/index.html +17 -13
- package/chunks/MaxSizedBox-B5YGZSYE.js +0 -72
- package/chunks/agent-H4JIDL7S.js +0 -67
- package/chunks/agent-headless-TTBEREQV.js +0 -61
- package/chunks/bridge-VL7ITBU5.js +0 -75
- package/chunks/chunk-542SK7KV.js +0 -8293
- package/chunks/chunk-CPCVCKKF.js +0 -358
- package/chunks/chunk-SEKHYHMS.js +0 -45
- package/chunks/chunk-W7FJ3N32.js +0 -49
- package/chunks/chunk-ZFKNWQGQ.js +0 -74639
- package/chunks/contextCommand-L2COEUHS.js +0 -66
- package/chunks/daemon-status-provider-NL4IAG7B.js +0 -74
- package/chunks/earlyInputCapture-L6I2A22T.js +0 -68
- package/chunks/errors-LEOF5QG4.js +0 -74
- package/chunks/handleAutoUpdate-QQVIWXKT.js +0 -67
- package/chunks/i18n-N6OBDORT.js +0 -83
- package/chunks/initializer-6WCFNDLL.js +0 -72
- package/chunks/installationInfo-6J3WPXNS.js +0 -64
- package/chunks/list-HOWQSWP6.js +0 -75
- package/chunks/loadedSettingsAdapter-AO4YBRXZ.js +0 -69
- package/chunks/mcp-QH7QNXOH.js +0 -69
- package/chunks/nonInteractiveCli-TI7EMPXD.js +0 -126
- package/chunks/pidfile-UEHAT6DH.js +0 -72
- package/chunks/read-file-SQJONF6A.js +0 -29
- package/chunks/resumeHistoryUtils-PFQ2A23X.js +0 -78
- package/chunks/ripGrep-QCK22GDU.js +0 -59
- package/chunks/runtime-SNVAP6EH.js +0 -100
- package/chunks/serve-BT7KS6SC.js +0 -75
- package/chunks/shell-BITUVH2R.js +0 -69
- package/chunks/spawnChannel-2BU3AULL.js +0 -68
- package/chunks/standalone-update-YG5JUYCM.js +0 -78
- package/chunks/task-create-HX32YXO7.js +0 -23
- package/chunks/theme-manager-IAETOI25.js +0 -63
- package/chunks/total-session-admission-BJLDHKJN.js +0 -69
- package/chunks/trustedFolders-5XCVNEUU.js +0 -79
- package/chunks/updateCheck-YZZB7YBU.js +0 -70
- package/chunks/useAutoAcceptIndicator-ZSQX4I2H.js +0 -80
- package/chunks/workspace-providers-status-EADV364W.js +0 -72
- package/chunks/workspace-registry-W6VMFYZU.js +0 -73
- package/chunks/workspace-service-F3KIN2UN.js +0 -84
- package/chunks/workspace-skills-status-YVICUR5Y.js +0 -71
- package/chunks/write-file-CVGF2OKV.js +0 -596
- package/web-shell/assets/channel-04R0vLbG.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-Bw9SOwAV.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Bw9SOwAV.js +0 -1
- package/web-shell/assets/index-DgkKrjw3.js +0 -1187
- package/web-shell/assets/index-Rv6mOAN9.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DWBoO4UY.js +0 -1
|
@@ -12,40 +12,46 @@ import {
|
|
|
12
12
|
matchMcpServerByRef,
|
|
13
13
|
parseExtensionRef,
|
|
14
14
|
parseMcpServerRef
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-F5MBYZSU.js";
|
|
16
16
|
import {
|
|
17
17
|
getAvailableCommands,
|
|
18
18
|
handleSlashCommand,
|
|
19
19
|
insertAfterFunctionResponses,
|
|
20
20
|
isSlashCommand,
|
|
21
21
|
normalizePartList
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-BW5Z5NOG.js";
|
|
23
|
+
import {
|
|
24
|
+
collectContextData,
|
|
25
|
+
formatContextUsageText
|
|
26
|
+
} from "./chunk-BJBUDCM3.js";
|
|
23
27
|
import {
|
|
24
28
|
recomputeMcpGating
|
|
25
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-QXZTZJLX.js";
|
|
26
30
|
import {
|
|
27
31
|
appEvents,
|
|
28
32
|
buildDisabledSkillNamesProvider,
|
|
29
33
|
loadCliConfig,
|
|
30
34
|
normalizeDisabledToolList
|
|
31
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-JKCALGYN.js";
|
|
32
36
|
import {
|
|
33
37
|
getCommandSubcommandNames
|
|
34
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-SJEDL7DI.js";
|
|
35
39
|
import {
|
|
36
40
|
getEffectiveSupportedModes
|
|
37
|
-
} from "./chunk-
|
|
38
|
-
import "./chunk-5DTTYNB7.js";
|
|
39
|
-
import "./chunk-QKYTTBYW.js";
|
|
40
|
-
import {
|
|
41
|
-
collectContextData,
|
|
42
|
-
formatContextUsageText
|
|
43
|
-
} from "./chunk-A5LYNIW7.js";
|
|
41
|
+
} from "./chunk-UH7242DI.js";
|
|
44
42
|
import "./chunk-4WGODMVR.js";
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-
|
|
47
|
-
import "./chunk-
|
|
48
|
-
import
|
|
43
|
+
import "./chunk-PQNHRFJC.js";
|
|
44
|
+
import "./chunk-4LVZNIDO.js";
|
|
45
|
+
import "./chunk-7Z6JQEL6.js";
|
|
46
|
+
import {
|
|
47
|
+
beginAcpBootstrapConfigProfiling,
|
|
48
|
+
buildAndFreezeAcpStartupProfile,
|
|
49
|
+
endAcpBootstrapConfigProfiling,
|
|
50
|
+
markAcpStartup
|
|
51
|
+
} from "./chunk-HIJQF5B5.js";
|
|
52
|
+
import "./chunk-LEEWLFHW.js";
|
|
53
|
+
import "./chunk-JYUSL2V4.js";
|
|
54
|
+
import "./chunk-WHFK6G6U.js";
|
|
49
55
|
import "./chunk-YAF2MQZ6.js";
|
|
50
56
|
import {
|
|
51
57
|
GENERATION_MAX_PROMPT_BYTES,
|
|
@@ -59,13 +65,14 @@ import {
|
|
|
59
65
|
executeGeneration,
|
|
60
66
|
formatWorkspaceMemoryForgetSummary,
|
|
61
67
|
isValidServerName,
|
|
68
|
+
normalizeChannelDeliveryText,
|
|
62
69
|
redactMcpServerSecrets,
|
|
63
70
|
replayTranscriptRecordPage,
|
|
64
71
|
restoreRedactedMcpSecrets,
|
|
65
72
|
shouldSuppressRememberErrorDetails,
|
|
66
73
|
workspaceMemoryFailureCode,
|
|
67
74
|
workspaceMemoryFailureDiagnostics
|
|
68
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-G7EFBBVF.js";
|
|
69
76
|
import {
|
|
70
77
|
HistoryReplayer,
|
|
71
78
|
MessageEmitter,
|
|
@@ -75,83 +82,81 @@ import {
|
|
|
75
82
|
goalTerminalEventToHistoryItem,
|
|
76
83
|
recordGoalStatusItem,
|
|
77
84
|
restoreGoalFromHistory
|
|
78
|
-
} from "./chunk-
|
|
79
|
-
import "./chunk-
|
|
80
|
-
import "./chunk-
|
|
81
|
-
import "./chunk-
|
|
82
|
-
import "./chunk-
|
|
85
|
+
} from "./chunk-FWNZ7CVN.js";
|
|
86
|
+
import "./chunk-4K7VDKAD.js";
|
|
87
|
+
import "./chunk-IPUUTYMV.js";
|
|
88
|
+
import "./chunk-DWNZ6PVQ.js";
|
|
89
|
+
import "./chunk-2MIN6GRR.js";
|
|
83
90
|
import "./chunk-QHTIBUWB.js";
|
|
84
91
|
import {
|
|
85
92
|
isTerminalGoalStatusKind
|
|
86
93
|
} from "./chunk-QTERJVPZ.js";
|
|
87
|
-
import "./chunk-
|
|
88
|
-
import {
|
|
89
|
-
computeCpuPercent
|
|
90
|
-
} from "./chunk-HGT6JR3U.js";
|
|
91
|
-
import "./chunk-RXFQM6FQ.js";
|
|
92
|
-
import "./chunk-KOR3XKCA.js";
|
|
93
|
-
import "./chunk-6H67XLET.js";
|
|
94
|
-
import {
|
|
95
|
-
beginAcpBootstrapConfigProfiling,
|
|
96
|
-
buildAndFreezeAcpStartupProfile,
|
|
97
|
-
endAcpBootstrapConfigProfiling,
|
|
98
|
-
markAcpStartup
|
|
99
|
-
} from "./chunk-TDKQP3M6.js";
|
|
100
|
-
import "./chunk-VEXFOTEO.js";
|
|
101
|
-
import "./chunk-LXXMOYPL.js";
|
|
102
|
-
import "./chunk-NDMQLV4Y.js";
|
|
103
|
-
import "./chunk-E5Z2AVNV.js";
|
|
104
|
-
import {
|
|
105
|
-
ACP_ROUTE_ID_PREFIX,
|
|
106
|
-
buildAcpModelOptions,
|
|
107
|
-
getCurrentAcpModelId,
|
|
108
|
-
parseAcpBaseModelId,
|
|
109
|
-
parseAcpModelOption,
|
|
110
|
-
resolveAcpModelOption,
|
|
111
|
-
sanitizeProviderBaseUrl
|
|
112
|
-
} from "./chunk-NGFEPAE6.js";
|
|
113
|
-
import {
|
|
114
|
-
mapSkillConfigToStatus
|
|
115
|
-
} from "./chunk-2W3OOD4W.js";
|
|
94
|
+
import "./chunk-3Z43GZUQ.js";
|
|
116
95
|
import {
|
|
117
96
|
PERMISSION_RULE_TYPES,
|
|
118
97
|
PermissionRulesValidationError,
|
|
119
98
|
buildPermissionSettings,
|
|
120
99
|
normalizePermissionRules,
|
|
121
100
|
readPermissionRuleSet
|
|
122
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-JDFBBGRD.js";
|
|
123
102
|
import {
|
|
124
103
|
MAX_AUDIO_BYTES,
|
|
125
104
|
sanitizeVoiceErrorMessage,
|
|
126
105
|
transcribeVoiceAudio
|
|
127
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-3FB2Y2OE.js";
|
|
128
107
|
import {
|
|
129
108
|
readVoiceModel
|
|
130
|
-
} from "./chunk-
|
|
131
|
-
import "./chunk-
|
|
109
|
+
} from "./chunk-KJEMJWNH.js";
|
|
110
|
+
import "./chunk-QLJUC7TG.js";
|
|
111
|
+
import {
|
|
112
|
+
computeCpuPercent
|
|
113
|
+
} from "./chunk-HGT6JR3U.js";
|
|
114
|
+
import "./chunk-RXFQM6FQ.js";
|
|
115
|
+
import "./chunk-PBII2NFX.js";
|
|
116
|
+
import "./chunk-6H67XLET.js";
|
|
117
|
+
import {
|
|
118
|
+
createLoadedSettingsAdapter
|
|
119
|
+
} from "./chunk-LA5H3LM5.js";
|
|
120
|
+
import "./chunk-LXXMOYPL.js";
|
|
121
|
+
import "./chunk-LBAO2XRA.js";
|
|
122
|
+
import "./chunk-E5Z2AVNV.js";
|
|
132
123
|
import {
|
|
133
124
|
parseSessionSource
|
|
134
|
-
} from "./chunk-
|
|
135
|
-
import
|
|
136
|
-
|
|
125
|
+
} from "./chunk-SWBJRDYC.js";
|
|
126
|
+
import {
|
|
127
|
+
NOT_CURRENTLY_GENERATING_CANCEL_MESSAGE
|
|
128
|
+
} from "./chunk-UH3WSE5L.js";
|
|
137
129
|
import {
|
|
138
130
|
CHANNEL_STARTUP_PROFILE_META_KEY,
|
|
139
131
|
CHANNEL_STARTUP_PROFILE_VERSION,
|
|
140
132
|
CLIENT_MCP_OVER_WS_CONFIG_FLAG,
|
|
133
|
+
DAEMON_CHANNEL_DELIVERY_META_KEY,
|
|
141
134
|
LOAD_REPLAY_BULK_MODE,
|
|
142
135
|
LOAD_REPLAY_META_KEY,
|
|
143
136
|
LOAD_REPLAY_MODE_META_KEY,
|
|
144
137
|
LOAD_REPLAY_PAGE_SIZE_META_KEY,
|
|
145
138
|
LOAD_REPLAY_VERSION,
|
|
146
139
|
MID_TURN_QUEUE_DRAIN_METHOD,
|
|
140
|
+
PROMPT_CANCEL_METHOD,
|
|
147
141
|
TODO_STOP_GUARD_QUEUE_RELEASE_METHOD
|
|
148
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-3SJ43L4W.js";
|
|
143
|
+
import "./chunk-BLFVGB7D.js";
|
|
144
|
+
import "./chunk-COH43MRJ.js";
|
|
149
145
|
import {
|
|
150
146
|
ndJsonStream
|
|
151
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-YCIM6O3I.js";
|
|
152
148
|
import {
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
ACP_ROUTE_ID_PREFIX,
|
|
150
|
+
buildAcpModelOptions,
|
|
151
|
+
getCurrentAcpModelId,
|
|
152
|
+
parseAcpBaseModelId,
|
|
153
|
+
parseAcpModelOption,
|
|
154
|
+
resolveAcpModelOption,
|
|
155
|
+
sanitizeProviderBaseUrl
|
|
156
|
+
} from "./chunk-WLEFWSSC.js";
|
|
157
|
+
import {
|
|
158
|
+
mapSkillConfigToStatus
|
|
159
|
+
} from "./chunk-2W3OOD4W.js";
|
|
155
160
|
import {
|
|
156
161
|
ACP_PREFLIGHT_KINDS,
|
|
157
162
|
IDLE_HOOK_EVENTS,
|
|
@@ -159,23 +164,22 @@ import {
|
|
|
159
164
|
SERVE_STATUS_EXT_METHODS,
|
|
160
165
|
STATUS_SCHEMA_VERSION,
|
|
161
166
|
mapDomainErrorToErrorKind
|
|
162
|
-
} from "./chunk-
|
|
163
|
-
import "./chunk-
|
|
164
|
-
import "./chunk-
|
|
167
|
+
} from "./chunk-CUPAVLRY.js";
|
|
168
|
+
import "./chunk-PFSUKTZH.js";
|
|
169
|
+
import "./chunk-UJV643E2.js";
|
|
170
|
+
import "./chunk-HZEWYOVI.js";
|
|
165
171
|
import "./chunk-57OAHC2Y.js";
|
|
166
|
-
import "./chunk-
|
|
167
|
-
import "./chunk-
|
|
172
|
+
import "./chunk-HVO55LUD.js";
|
|
173
|
+
import "./chunk-QAFKR7WR.js";
|
|
168
174
|
import "./chunk-V6WHFGST.js";
|
|
169
|
-
import
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
import "./chunk-
|
|
173
|
-
import "./chunk-
|
|
174
|
-
import "./chunk-TJTKSVIV.js";
|
|
175
|
+
import "./chunk-BSNWBC33.js";
|
|
176
|
+
import "./chunk-2RFKHEXL.js";
|
|
177
|
+
import "./chunk-UPF7PTBI.js";
|
|
178
|
+
import "./chunk-JLU636DO.js";
|
|
179
|
+
import "./chunk-BK2UNYWD.js";
|
|
175
180
|
import "./chunk-M5GB774H.js";
|
|
176
|
-
import "./chunk-
|
|
177
|
-
import "./chunk-
|
|
178
|
-
import "./chunk-NIJEXGV6.js";
|
|
181
|
+
import "./chunk-RV4C2ZFG.js";
|
|
182
|
+
import "./chunk-ZXYUQXY5.js";
|
|
179
183
|
import {
|
|
180
184
|
AgentSideConnection,
|
|
181
185
|
PROTOCOL_VERSION,
|
|
@@ -184,7 +188,7 @@ import {
|
|
|
184
188
|
import {
|
|
185
189
|
assembleMcpServers,
|
|
186
190
|
loadMcpApprovals
|
|
187
|
-
} from "./chunk-
|
|
191
|
+
} from "./chunk-2WTVWAKT.js";
|
|
188
192
|
import {
|
|
189
193
|
getOutputLanguageFilePath,
|
|
190
194
|
getPersistScopeForModelSelection,
|
|
@@ -193,7 +197,7 @@ import {
|
|
|
193
197
|
resolveOutputLanguageOrPreserveAuto,
|
|
194
198
|
updateOutputLanguageFile,
|
|
195
199
|
writeOutputLanguageAndRegisterPath
|
|
196
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-J5UKQEFG.js";
|
|
197
201
|
import "./chunk-RKUWKYED.js";
|
|
198
202
|
import "./chunk-GOXKNSDZ.js";
|
|
199
203
|
import {
|
|
@@ -204,20 +208,20 @@ import {
|
|
|
204
208
|
SUPPORTED_LANGUAGES,
|
|
205
209
|
getCurrentLanguage,
|
|
206
210
|
setLanguageAsync
|
|
207
|
-
} from "./chunk-
|
|
211
|
+
} from "./chunk-ZT4POVWC.js";
|
|
208
212
|
import {
|
|
209
213
|
findEnvFiles,
|
|
210
214
|
preResolveHomeEnvOverrides,
|
|
211
215
|
reloadEnvironment
|
|
212
|
-
} from "./chunk-
|
|
216
|
+
} from "./chunk-32A4PI3E.js";
|
|
213
217
|
import "./chunk-QRUIS3DN.js";
|
|
214
|
-
import "./chunk-
|
|
218
|
+
import "./chunk-54R2CV2G.js";
|
|
215
219
|
import "./chunk-VJNBRRZG.js";
|
|
216
220
|
import {
|
|
217
221
|
isFolderTrustEnabled,
|
|
218
222
|
isWorkspaceTrusted,
|
|
219
223
|
loadTrustedFolders
|
|
220
|
-
} from "./chunk-
|
|
224
|
+
} from "./chunk-CXUFILV3.js";
|
|
221
225
|
import "./chunk-ALGGS7UH.js";
|
|
222
226
|
import "./chunk-MR3PXB6E.js";
|
|
223
227
|
import {
|
|
@@ -243,16 +247,20 @@ import {
|
|
|
243
247
|
McpServerSpawnFailedError,
|
|
244
248
|
McpTransportPool,
|
|
245
249
|
MessageDisplayDispatcher,
|
|
250
|
+
PLAN_MODE_ENTRY_SIBLING_SKIP_MESSAGE,
|
|
246
251
|
POOLED_TRANSPORTS_DEFAULT,
|
|
247
252
|
SESSION_ARTIFACT_PERSISTENCE_VERSION,
|
|
248
253
|
SESSION_TITLE_MAX_LENGTH,
|
|
249
254
|
SESSION_TRANSCRIPT_MAX_LIMIT,
|
|
250
255
|
SESSION_TRANSCRIPT_MAX_PAGE_BYTES,
|
|
256
|
+
SESSION_WRITER_RPC_CODES,
|
|
251
257
|
SessionService,
|
|
252
258
|
SessionTranscriptPageTooLargeError,
|
|
253
259
|
SessionTranscriptReader,
|
|
254
260
|
SessionTranscriptSnapshotUnavailableError,
|
|
255
261
|
SessionTranscriptTooLargeError,
|
|
262
|
+
SessionWriterError,
|
|
263
|
+
SessionWriterUnavailableError,
|
|
256
264
|
TURN_INTERRUPTION_HISTORY_TAIL_COUNT,
|
|
257
265
|
WorkspaceMcpBudget,
|
|
258
266
|
abortGoalForStopHookCap,
|
|
@@ -272,13 +280,18 @@ import {
|
|
|
272
280
|
convertToFunctionErrorResponse,
|
|
273
281
|
convertToFunctionResponse,
|
|
274
282
|
createDuplicateProviderToolCallResponse,
|
|
283
|
+
decorateClassifierUnavailableConfirmation,
|
|
284
|
+
decoratePlanModeShellConfirmation,
|
|
275
285
|
dedupeToolCallsById,
|
|
276
286
|
detectAutonomousSentinel,
|
|
277
287
|
detectLoopSentinel,
|
|
278
288
|
encodeSessionTranscriptCursor,
|
|
279
289
|
evaluateAutoMode,
|
|
280
290
|
evaluatePermissionFlow,
|
|
291
|
+
evaluatePlanModeShellPolicy,
|
|
292
|
+
finalizeToolResponses,
|
|
281
293
|
findExistingProviderModels,
|
|
294
|
+
findPlanModeEntryBatchBoundaryIndex,
|
|
282
295
|
findProviderById,
|
|
283
296
|
findRepeatedDuplicateProviderToolCall,
|
|
284
297
|
fireNotificationHook,
|
|
@@ -301,21 +314,19 @@ import {
|
|
|
301
314
|
getPlanModeSystemReminder,
|
|
302
315
|
getProviderToolCallId,
|
|
303
316
|
getScopedEnvContents,
|
|
304
|
-
|
|
317
|
+
getStopHookContinuationReason,
|
|
305
318
|
ideContextStore,
|
|
306
319
|
injectPermissionRulesIfMissing,
|
|
307
320
|
isApproveOutcome,
|
|
308
321
|
isDenialFallbackReason,
|
|
309
322
|
isGatedMcpScope,
|
|
310
323
|
isPlanModeBlocked,
|
|
311
|
-
isSystemReminderContent,
|
|
312
324
|
markDuplicateProviderToolCallResponseSent,
|
|
313
325
|
matchesAnyServerPattern,
|
|
314
326
|
mcpServerRequiresOAuth,
|
|
315
327
|
needsConfirmation,
|
|
316
328
|
normalizeEventPayload,
|
|
317
329
|
normalizeSnapshotPayload,
|
|
318
|
-
parsePositiveIntegerEnv,
|
|
319
330
|
persistPermissionOutcome,
|
|
320
331
|
readManyFiles,
|
|
321
332
|
recordAllow,
|
|
@@ -337,53 +348,79 @@ import {
|
|
|
337
348
|
shouldRunAutoModeForCall,
|
|
338
349
|
subagentGenerator,
|
|
339
350
|
unregisterGoalHook,
|
|
340
|
-
updateSetting
|
|
341
|
-
|
|
351
|
+
updateSetting,
|
|
352
|
+
validatePlanModeShellApproval,
|
|
353
|
+
validatePlanModeShellContext
|
|
354
|
+
} from "./chunk-LI4I37W4.js";
|
|
342
355
|
import "./chunk-5M6IDOMF.js";
|
|
343
|
-
import "./chunk-
|
|
356
|
+
import "./chunk-TWPJO254.js";
|
|
344
357
|
import {
|
|
345
358
|
external_exports
|
|
346
359
|
} from "./chunk-H6XPXXMH.js";
|
|
347
|
-
import "./chunk-
|
|
348
|
-
import "./chunk-
|
|
349
|
-
import "./chunk-
|
|
350
|
-
import "./chunk-
|
|
351
|
-
import "./chunk-
|
|
352
|
-
import
|
|
360
|
+
import "./chunk-NOAAFNTJ.js";
|
|
361
|
+
import "./chunk-AFFGGOF6.js";
|
|
362
|
+
import "./chunk-RGG6M2WF.js";
|
|
363
|
+
import "./chunk-X6N25LXS.js";
|
|
364
|
+
import "./chunk-KRXPRVGL.js";
|
|
365
|
+
import {
|
|
366
|
+
parsePositiveIntegerEnv
|
|
367
|
+
} from "./chunk-6PVPNMXU.js";
|
|
368
|
+
import "./chunk-UO7DCGEV.js";
|
|
369
|
+
import "./chunk-IRH27ZC2.js";
|
|
353
370
|
import "./chunk-VDDGDZMA.js";
|
|
354
|
-
import "./chunk-
|
|
371
|
+
import "./chunk-C3VHAXP2.js";
|
|
355
372
|
import "./chunk-SZRN75WQ.js";
|
|
356
373
|
import "./chunk-HTO4JFDZ.js";
|
|
357
374
|
import "./chunk-CPBF7KYF.js";
|
|
358
375
|
import {
|
|
359
376
|
APPROVAL_MODES,
|
|
360
377
|
FORK_SUBAGENT_TYPE,
|
|
378
|
+
getStartupContextLength,
|
|
379
|
+
isSystemReminderContent,
|
|
361
380
|
runWithRuntimeContentGenerator
|
|
362
|
-
} from "./chunk-
|
|
381
|
+
} from "./chunk-XAWJ2526.js";
|
|
363
382
|
import "./chunk-6AM5D4ME.js";
|
|
364
|
-
import "./chunk-
|
|
383
|
+
import "./chunk-NABLFI57.js";
|
|
365
384
|
import {
|
|
366
385
|
HookEventName,
|
|
367
386
|
createHookOutput
|
|
368
|
-
} from "./chunk-
|
|
369
|
-
import "./chunk-
|
|
370
|
-
import "./chunk-
|
|
387
|
+
} from "./chunk-QBUDF33N.js";
|
|
388
|
+
import "./chunk-JCW2R7WC.js";
|
|
389
|
+
import "./chunk-57FIIFJN.js";
|
|
390
|
+
import "./chunk-LIZRAKPB.js";
|
|
371
391
|
import {
|
|
372
392
|
clearCachedCredentialFile,
|
|
373
393
|
qwenOAuth2Events
|
|
374
|
-
} from "./chunk-
|
|
375
|
-
import "./chunk-
|
|
394
|
+
} from "./chunk-LYTBLSSW.js";
|
|
395
|
+
import "./chunk-WI3KCKZ5.js";
|
|
396
|
+
import "./chunk-DP5GT2MW.js";
|
|
376
397
|
import "./chunk-JESCGQM3.js";
|
|
398
|
+
import "./chunk-XVNQMZ2I.js";
|
|
399
|
+
import "./chunk-FODK6UMO.js";
|
|
400
|
+
import "./chunk-GLNBDYUX.js";
|
|
401
|
+
import "./chunk-DJ2GSRLV.js";
|
|
402
|
+
import "./chunk-R6D2CTQR.js";
|
|
403
|
+
import {
|
|
404
|
+
extractDaemonTraceContext,
|
|
405
|
+
registerAcpEventLoopLagGauge,
|
|
406
|
+
startEventLoopLagMonitor,
|
|
407
|
+
withDaemonSpan
|
|
408
|
+
} from "./chunk-AXUW635Q.js";
|
|
409
|
+
import "./chunk-BPJSQIJX.js";
|
|
410
|
+
import "./chunk-P3QQPMQA.js";
|
|
411
|
+
import "./chunk-6QHAUJUE.js";
|
|
412
|
+
import {
|
|
413
|
+
getToolCallPreparations
|
|
414
|
+
} from "./chunk-LS77BEZP.js";
|
|
377
415
|
import {
|
|
378
|
-
AuthType,
|
|
379
416
|
ConversationFinishedEvent,
|
|
380
417
|
DiscoveredMCPTool,
|
|
418
|
+
INVOCATION_CONTEXT_META_KEY,
|
|
381
419
|
LoopDetectedEvent,
|
|
420
|
+
PRIVATE_ACP_CAPABILITY_ENV,
|
|
421
|
+
PRIVATE_PARENT_CAPABILITY_META_KEY,
|
|
382
422
|
PromptSuggestionEvent,
|
|
383
423
|
UserPromptEvent,
|
|
384
|
-
endToolExecutionSpan,
|
|
385
|
-
endToolSpan,
|
|
386
|
-
extractDaemonTraceContext,
|
|
387
424
|
formatFullTurnVisionNotice,
|
|
388
425
|
formatVisionBridgeNotice,
|
|
389
426
|
getAllGeminiMdFilenames,
|
|
@@ -397,63 +434,66 @@ import {
|
|
|
397
434
|
logToolCall,
|
|
398
435
|
logUserPrompt,
|
|
399
436
|
normalizeParts,
|
|
400
|
-
|
|
401
|
-
runInToolSpanContext,
|
|
437
|
+
parseInvocationContext,
|
|
402
438
|
runSideQuery,
|
|
403
439
|
runVisionBridge,
|
|
440
|
+
runWithInvocationContext,
|
|
404
441
|
shouldRunVisionBridge,
|
|
405
442
|
splitImageParts,
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
startToolSpan,
|
|
409
|
-
uiTelemetryService,
|
|
410
|
-
withDaemonSpan,
|
|
411
|
-
withInteractionSpan
|
|
412
|
-
} from "./chunk-ZFKNWQGQ.js";
|
|
413
|
-
import "./chunk-4WKAA4KS.js";
|
|
414
|
-
import "./chunk-CR3C7WXL.js";
|
|
443
|
+
uiTelemetryService
|
|
444
|
+
} from "./chunk-IFG6TYJ2.js";
|
|
415
445
|
import "./chunk-VGC4I5JJ.js";
|
|
416
446
|
import {
|
|
417
447
|
getAutoMemoryRoot,
|
|
418
448
|
getUserAutoMemoryRoot
|
|
419
|
-
} from "./chunk-
|
|
420
|
-
import "./chunk-UEY4AYUL.js";
|
|
421
|
-
import "./chunk-BDBMYST4.js";
|
|
422
|
-
import "./chunk-EZVDJFZ7.js";
|
|
449
|
+
} from "./chunk-4K56OJFJ.js";
|
|
423
450
|
import {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
import "./chunk-
|
|
429
|
-
import "./chunk-FEOZBUMT.js";
|
|
430
|
-
import "./chunk-DJ2GSRLV.js";
|
|
431
|
-
import "./chunk-6EFTQYW7.js";
|
|
451
|
+
AuthType
|
|
452
|
+
} from "./chunk-36HSVBBU.js";
|
|
453
|
+
import "./chunk-46UV252V.js";
|
|
454
|
+
import "./chunk-A4UCTEB5.js";
|
|
455
|
+
import "./chunk-XWRJCPHC.js";
|
|
432
456
|
import {
|
|
433
457
|
DEFAULT_TOKEN_LIMIT,
|
|
434
|
-
getToolCallPreparations,
|
|
435
458
|
tokenLimit
|
|
436
|
-
} from "./chunk-
|
|
437
|
-
import "./chunk-
|
|
438
|
-
import "./chunk-
|
|
439
|
-
import "./chunk-
|
|
440
|
-
import
|
|
441
|
-
|
|
459
|
+
} from "./chunk-UW5EOVUN.js";
|
|
460
|
+
import "./chunk-NBQDBANR.js";
|
|
461
|
+
import "./chunk-QNLNLENL.js";
|
|
462
|
+
import "./chunk-6X4GWOPW.js";
|
|
463
|
+
import {
|
|
464
|
+
endToolExecutionSpan,
|
|
465
|
+
endToolSpan,
|
|
466
|
+
initializeTelemetry,
|
|
467
|
+
runInToolSpanContext,
|
|
468
|
+
startToolExecutionSpan,
|
|
469
|
+
startToolSpan,
|
|
470
|
+
withInteractionSpan
|
|
471
|
+
} from "./chunk-PKL3HGNZ.js";
|
|
472
|
+
import "./chunk-HTR4WV6U.js";
|
|
473
|
+
import "./chunk-BULDBTYC.js";
|
|
474
|
+
import "./chunk-U7ZFW55U.js";
|
|
475
|
+
import "./chunk-ERLGR7GI.js";
|
|
476
|
+
import {
|
|
477
|
+
ToolConfirmationOutcome,
|
|
478
|
+
ToolNames,
|
|
479
|
+
isShellProgressData
|
|
480
|
+
} from "./chunk-P5RRUHL7.js";
|
|
442
481
|
import {
|
|
443
482
|
Storage,
|
|
444
483
|
createDebugLogger,
|
|
445
484
|
getErrorMessage,
|
|
446
485
|
getErrorStatus,
|
|
447
486
|
isSubpath
|
|
448
|
-
} from "./chunk-
|
|
449
|
-
import "./chunk-
|
|
487
|
+
} from "./chunk-OQB4EXO4.js";
|
|
488
|
+
import "./chunk-CKTMY3EP.js";
|
|
450
489
|
import {
|
|
451
490
|
runExitCleanup
|
|
452
|
-
} from "./chunk-
|
|
491
|
+
} from "./chunk-EL2IQ2S5.js";
|
|
453
492
|
import "./chunk-75DOP5OR.js";
|
|
454
493
|
import "./chunk-DMTGGOSA.js";
|
|
455
494
|
import "./chunk-YQ3U5MUC.js";
|
|
456
|
-
import "./chunk-
|
|
495
|
+
import "./chunk-AMDSOFFV.js";
|
|
496
|
+
import "./chunk-THJNPLI4.js";
|
|
457
497
|
import {
|
|
458
498
|
init_esbuild_shims
|
|
459
499
|
} from "./chunk-5O2XNYP6.js";
|
|
@@ -463,7 +503,7 @@ import {
|
|
|
463
503
|
|
|
464
504
|
// packages/cli/src/acp-integration/acpAgent.ts
|
|
465
505
|
init_esbuild_shims();
|
|
466
|
-
import { randomUUID } from "node:crypto";
|
|
506
|
+
import { randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
|
|
467
507
|
import { performance } from "node:perf_hooks";
|
|
468
508
|
|
|
469
509
|
// packages/cli/src/acp-integration/authMethods.ts
|
|
@@ -841,6 +881,7 @@ __name(isInactiveExtensionSkill, "isInactiveExtensionSkill");
|
|
|
841
881
|
// packages/cli/src/acp-integration/session/Session.ts
|
|
842
882
|
init_esbuild_shims();
|
|
843
883
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
884
|
+
import { randomUUID } from "node:crypto";
|
|
844
885
|
import { existsSync as existsSync2, statSync as statSync2 } from "node:fs";
|
|
845
886
|
import * as os2 from "node:os";
|
|
846
887
|
import * as path3 from "node:path";
|
|
@@ -965,8 +1006,23 @@ function supportsHideAlwaysAllow(confirmation) {
|
|
|
965
1006
|
}
|
|
966
1007
|
__name(supportsHideAlwaysAllow, "supportsHideAlwaysAllow");
|
|
967
1008
|
function filterAlwaysAllowOptions(confirmation, options, forceHideAlwaysAllow = false) {
|
|
968
|
-
const hideAlwaysAllow = forceHideAlwaysAllow || supportsHideAlwaysAllow(confirmation) && confirmation.hideAlwaysAllow === true;
|
|
969
|
-
|
|
1009
|
+
const hideAlwaysAllow = forceHideAlwaysAllow || confirmation.autoModeFallback !== void 0 || supportsHideAlwaysAllow(confirmation) && confirmation.hideAlwaysAllow === true;
|
|
1010
|
+
const visibleOptions = hideAlwaysAllow ? options.filter((option) => option.kind !== "allow_always") : options;
|
|
1011
|
+
if (!confirmation.autoModeFallback) return visibleOptions;
|
|
1012
|
+
const switchOption = {
|
|
1013
|
+
optionId: "proceed_once_and_switch_to_default" /* ProceedOnceAndSwitchToDefault */,
|
|
1014
|
+
name: "Switch to Default Mode and allow once (recommended)",
|
|
1015
|
+
kind: "allow_once"
|
|
1016
|
+
};
|
|
1017
|
+
const rejectIndex = visibleOptions.findIndex(
|
|
1018
|
+
(option) => option.kind === "reject_once"
|
|
1019
|
+
);
|
|
1020
|
+
if (rejectIndex === -1) return [...visibleOptions, switchOption];
|
|
1021
|
+
return [
|
|
1022
|
+
...visibleOptions.slice(0, rejectIndex),
|
|
1023
|
+
switchOption,
|
|
1024
|
+
...visibleOptions.slice(rejectIndex)
|
|
1025
|
+
];
|
|
970
1026
|
}
|
|
971
1027
|
__name(filterAlwaysAllowOptions, "filterAlwaysAllowOptions");
|
|
972
1028
|
function formatExecPermissionScopeLabel(confirmation) {
|
|
@@ -994,6 +1050,22 @@ function interactionMetaFields(confirmation) {
|
|
|
994
1050
|
__name(interactionMetaFields, "interactionMetaFields");
|
|
995
1051
|
function buildPermissionRequestContent(confirmation) {
|
|
996
1052
|
const content = [];
|
|
1053
|
+
if (confirmation.autoModeFallback) {
|
|
1054
|
+
content.push({
|
|
1055
|
+
type: "content",
|
|
1056
|
+
content: {
|
|
1057
|
+
type: "text",
|
|
1058
|
+
text: confirmation.autoModeFallback.message
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
const warnings = confirmation.type === "exec" || confirmation.type === "edit" ? confirmation.warnings ?? [] : [];
|
|
1063
|
+
for (const warning of warnings) {
|
|
1064
|
+
content.push({
|
|
1065
|
+
type: "content",
|
|
1066
|
+
content: { type: "text", text: warning }
|
|
1067
|
+
});
|
|
1068
|
+
}
|
|
997
1069
|
if (confirmation.type === "edit") {
|
|
998
1070
|
content.push({
|
|
999
1071
|
type: "diff",
|
|
@@ -1014,6 +1086,56 @@ function buildPermissionRequestContent(confirmation) {
|
|
|
1014
1086
|
return content;
|
|
1015
1087
|
}
|
|
1016
1088
|
__name(buildPermissionRequestContent, "buildPermissionRequestContent");
|
|
1089
|
+
function permissionAbortError(signal) {
|
|
1090
|
+
return signal.reason instanceof Error ? signal.reason : new Error("Permission request was aborted.");
|
|
1091
|
+
}
|
|
1092
|
+
__name(permissionAbortError, "permissionAbortError");
|
|
1093
|
+
function requestPermissionWithAbort(client, params, signal) {
|
|
1094
|
+
if (signal.aborted) {
|
|
1095
|
+
return Promise.reject(permissionAbortError(signal));
|
|
1096
|
+
}
|
|
1097
|
+
return new Promise((resolve5, reject) => {
|
|
1098
|
+
let settled = false;
|
|
1099
|
+
const finish = /* @__PURE__ */ __name((callback) => {
|
|
1100
|
+
if (settled) return;
|
|
1101
|
+
settled = true;
|
|
1102
|
+
signal.removeEventListener("abort", onAbort);
|
|
1103
|
+
callback();
|
|
1104
|
+
}, "finish");
|
|
1105
|
+
const onAbort = /* @__PURE__ */ __name(() => finish(() => reject(permissionAbortError(signal))), "onAbort");
|
|
1106
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1107
|
+
let request;
|
|
1108
|
+
try {
|
|
1109
|
+
request = client.requestPermission(params);
|
|
1110
|
+
} catch (error) {
|
|
1111
|
+
finish(() => reject(error));
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
request.then(
|
|
1115
|
+
(response) => finish(() => resolve5(response)),
|
|
1116
|
+
(error) => finish(() => reject(error))
|
|
1117
|
+
);
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
__name(requestPermissionWithAbort, "requestPermissionWithAbort");
|
|
1121
|
+
function resolvePermissionOutcome(response, offeredOptions) {
|
|
1122
|
+
if (response.outcome.outcome === "cancelled") {
|
|
1123
|
+
return "cancel" /* Cancel */;
|
|
1124
|
+
}
|
|
1125
|
+
const optionId = response.outcome.optionId;
|
|
1126
|
+
if (!offeredOptions.some((option) => option.optionId === optionId)) {
|
|
1127
|
+
throw new Error(
|
|
1128
|
+
`Permission response selected unoffered option: ${optionId}`
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
if (!Object.values(ToolConfirmationOutcome).includes(
|
|
1132
|
+
optionId
|
|
1133
|
+
)) {
|
|
1134
|
+
throw new Error(`Permission response selected invalid option: ${optionId}`);
|
|
1135
|
+
}
|
|
1136
|
+
return optionId;
|
|
1137
|
+
}
|
|
1138
|
+
__name(resolvePermissionOutcome, "resolvePermissionOutcome");
|
|
1017
1139
|
function toPermissionOptions(confirmation, forceHideAlwaysAllow = false) {
|
|
1018
1140
|
switch (confirmation.type) {
|
|
1019
1141
|
case "edit":
|
|
@@ -1240,9 +1362,13 @@ var SubAgentTracker = class {
|
|
|
1240
1362
|
}, "onConfirm")
|
|
1241
1363
|
};
|
|
1242
1364
|
const { title, locations, kind } = this.toolCallEmitter.resolveToolMetadata(event.name, state?.args);
|
|
1365
|
+
const permissionOptions = toPermissionOptions(fullConfirmationDetails);
|
|
1366
|
+
const offeredPermissionOptions = permissionOptions.map((option) => ({
|
|
1367
|
+
...option
|
|
1368
|
+
}));
|
|
1243
1369
|
const params = {
|
|
1244
1370
|
sessionId: this.ctx.sessionId,
|
|
1245
|
-
options:
|
|
1371
|
+
options: permissionOptions,
|
|
1246
1372
|
toolCall: {
|
|
1247
1373
|
toolCallId: event.callId,
|
|
1248
1374
|
status: "pending",
|
|
@@ -1263,8 +1389,15 @@ var SubAgentTracker = class {
|
|
|
1263
1389
|
}
|
|
1264
1390
|
};
|
|
1265
1391
|
try {
|
|
1266
|
-
const output = await
|
|
1267
|
-
|
|
1392
|
+
const output = await requestPermissionWithAbort(
|
|
1393
|
+
this.client,
|
|
1394
|
+
params,
|
|
1395
|
+
abortSignal
|
|
1396
|
+
);
|
|
1397
|
+
const outcome = resolvePermissionOutcome(
|
|
1398
|
+
output,
|
|
1399
|
+
offeredPermissionOptions
|
|
1400
|
+
);
|
|
1268
1401
|
await event.respond(outcome, {
|
|
1269
1402
|
answers: "answers" in output ? output.answers : void 0
|
|
1270
1403
|
});
|
|
@@ -1856,6 +1989,10 @@ function maskApiKeyForDisplay(apiKey) {
|
|
|
1856
1989
|
return `${trimmed.slice(0, 3)}...${trimmed.slice(-4)}`;
|
|
1857
1990
|
}
|
|
1858
1991
|
__name(maskApiKeyForDisplay, "maskApiKeyForDisplay");
|
|
1992
|
+
function getAbortAwareEndTurnStopReason(signal) {
|
|
1993
|
+
return signal.aborted ? "cancelled" : "end_turn";
|
|
1994
|
+
}
|
|
1995
|
+
__name(getAbortAwareEndTurnStopReason, "getAbortAwareEndTurnStopReason");
|
|
1859
1996
|
var DAEMON_INVALID_TOOL_PARAMS_THRESHOLD = 3;
|
|
1860
1997
|
var PERMISSION_CANCEL_SKIP_MESSAGE = "Skipped because a permission request was cancelled before the user answered; user input is required before continuing.";
|
|
1861
1998
|
var LOOP_DETECTED_SKIP_MESSAGE = "Skipped because loop detection stopped the current turn before this tool call could run.";
|
|
@@ -2091,6 +2228,43 @@ var MidTurnDrainTimeoutError = class extends Error {
|
|
|
2091
2228
|
);
|
|
2092
2229
|
}
|
|
2093
2230
|
};
|
|
2231
|
+
function beginChannelDeliveryResponseBlock(capture) {
|
|
2232
|
+
if (!capture) return void 0;
|
|
2233
|
+
capture.finalText = "";
|
|
2234
|
+
return [];
|
|
2235
|
+
}
|
|
2236
|
+
__name(beginChannelDeliveryResponseBlock, "beginChannelDeliveryResponseBlock");
|
|
2237
|
+
function commitChannelDeliveryResponseBlock(capture, responseBlock, hasFunctionCalls) {
|
|
2238
|
+
if (capture && responseBlock && !hasFunctionCalls) {
|
|
2239
|
+
capture.finalText = responseBlock.join("");
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
__name(commitChannelDeliveryResponseBlock, "commitChannelDeliveryResponseBlock");
|
|
2243
|
+
function parsePromptChannelDelivery(params) {
|
|
2244
|
+
const meta = params._meta;
|
|
2245
|
+
const value = meta?.[DAEMON_CHANNEL_DELIVERY_META_KEY];
|
|
2246
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2247
|
+
return void 0;
|
|
2248
|
+
}
|
|
2249
|
+
const delivery = value;
|
|
2250
|
+
const target = delivery["target"];
|
|
2251
|
+
if (typeof delivery["deliveryId"] !== "string" || delivery["deliveryId"].length === 0 || typeof target !== "object" || target === null || Array.isArray(target)) {
|
|
2252
|
+
return void 0;
|
|
2253
|
+
}
|
|
2254
|
+
const targetRecord = target;
|
|
2255
|
+
if (typeof targetRecord["channelName"] !== "string" || targetRecord["channelName"].length === 0 || targetRecord["type"] !== "user" && targetRecord["type"] !== "chat" || typeof targetRecord["id"] !== "string" || targetRecord["id"].length === 0) {
|
|
2256
|
+
return void 0;
|
|
2257
|
+
}
|
|
2258
|
+
return {
|
|
2259
|
+
deliveryId: delivery["deliveryId"],
|
|
2260
|
+
target: {
|
|
2261
|
+
channelName: targetRecord["channelName"],
|
|
2262
|
+
type: targetRecord["type"],
|
|
2263
|
+
id: targetRecord["id"]
|
|
2264
|
+
}
|
|
2265
|
+
};
|
|
2266
|
+
}
|
|
2267
|
+
__name(parsePromptChannelDelivery, "parsePromptChannelDelivery");
|
|
2094
2268
|
var MAX_NOTIFICATION_QUEUE = 20;
|
|
2095
2269
|
var MAX_DEFERRED_UNRELATED_CRON_QUEUE = 20;
|
|
2096
2270
|
function isExistingFile(resolved, fileExists = existsSync2, statFile = statSync2) {
|
|
@@ -2307,7 +2481,7 @@ var Session = class {
|
|
|
2307
2481
|
this.client = client;
|
|
2308
2482
|
this.settings = settings;
|
|
2309
2483
|
this.sessionId = id;
|
|
2310
|
-
this.runtimeBaseDir =
|
|
2484
|
+
this.runtimeBaseDir = config.storage.getRuntimeBaseDir();
|
|
2311
2485
|
const todoStopGuardEnabled = this.settings.merged.experimental?.todoStopGuard === true && !this.config.getBareMode() && !this.config.isSafeMode();
|
|
2312
2486
|
this.todoStopGuard = new DaemonTodoStopGuard(todoStopGuardEnabled);
|
|
2313
2487
|
this.todoStopGuardBackgroundBaseline = todoStopGuardEnabled ? this.#captureTodoStopGuardBackgroundBaseline() : {
|
|
@@ -2338,6 +2512,7 @@ var Session = class {
|
|
|
2338
2512
|
* process termination is slow.
|
|
2339
2513
|
*/
|
|
2340
2514
|
pendingPromptCompletion = null;
|
|
2515
|
+
automaticDrainRetry = null;
|
|
2341
2516
|
/**
|
|
2342
2517
|
* Per-turn AbortController for the fire-and-forget follow-up suggestion
|
|
2343
2518
|
* generation. Aborted on the top of the next `prompt()` and on
|
|
@@ -2400,6 +2575,9 @@ var Session = class {
|
|
|
2400
2575
|
// or session reload), which would otherwise execute orphaned cron prompts
|
|
2401
2576
|
// on a session whose registries are already unregistered.
|
|
2402
2577
|
disposed = false;
|
|
2578
|
+
closing = false;
|
|
2579
|
+
closeGateCompletion = null;
|
|
2580
|
+
resolveCloseGate = null;
|
|
2403
2581
|
unsubscribeChatRecordingFailure;
|
|
2404
2582
|
// Modular components
|
|
2405
2583
|
historyReplayer;
|
|
@@ -2422,6 +2600,8 @@ var Session = class {
|
|
|
2422
2600
|
* that produces this string.
|
|
2423
2601
|
*/
|
|
2424
2602
|
pendingWorktreeNotice = null;
|
|
2603
|
+
/** One-shot model notice for background agents restored with the session. */
|
|
2604
|
+
pendingRecoveredAgentsNotice = null;
|
|
2425
2605
|
// Implement SessionContext interface
|
|
2426
2606
|
sessionId;
|
|
2427
2607
|
#prepareTodoStopGuardForPrompt(params) {
|
|
@@ -2634,7 +2814,7 @@ var Session = class {
|
|
|
2634
2814
|
* mount.
|
|
2635
2815
|
*/
|
|
2636
2816
|
startCronScheduler() {
|
|
2637
|
-
this.#
|
|
2817
|
+
this.#startCronSchedulerInRuntime().catch((error) => {
|
|
2638
2818
|
debugLogger6.warn(
|
|
2639
2819
|
`Cron scheduler startup failed [session ${this.sessionId}]: ${error}`
|
|
2640
2820
|
);
|
|
@@ -2643,8 +2823,95 @@ var Session = class {
|
|
|
2643
2823
|
getConfig() {
|
|
2644
2824
|
return this.config;
|
|
2645
2825
|
}
|
|
2826
|
+
async assertCanStartTurn() {
|
|
2827
|
+
if (this.closing) {
|
|
2828
|
+
throw RequestError.invalidParams(void 0, "Session is closing");
|
|
2829
|
+
}
|
|
2830
|
+
try {
|
|
2831
|
+
await this.config.assertCanStartTurn();
|
|
2832
|
+
} catch (error) {
|
|
2833
|
+
if (error instanceof SessionWriterError) {
|
|
2834
|
+
throw new RequestError(error.rpcCode, error.message, {
|
|
2835
|
+
errorKind: error.errorKind
|
|
2836
|
+
});
|
|
2837
|
+
}
|
|
2838
|
+
throw error;
|
|
2839
|
+
}
|
|
2840
|
+
if (this.closing) {
|
|
2841
|
+
throw RequestError.invalidParams(void 0, "Session is closing");
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2646
2844
|
isIdle() {
|
|
2647
|
-
return !this.
|
|
2845
|
+
return !this.closing && !this.#hasActiveTurn();
|
|
2846
|
+
}
|
|
2847
|
+
#hasActiveTurn() {
|
|
2848
|
+
return Boolean(
|
|
2849
|
+
this.pendingPrompt || this.pendingPromptCompletion || this.cronProcessing || this.cronAbortController || this.cronCompletion || this.notificationProcessing || this.notificationAbortController || this.notificationCompletion
|
|
2850
|
+
);
|
|
2851
|
+
}
|
|
2852
|
+
beginClose() {
|
|
2853
|
+
if (this.closing) {
|
|
2854
|
+
throw RequestError.invalidParams(
|
|
2855
|
+
void 0,
|
|
2856
|
+
"Session close is already in progress"
|
|
2857
|
+
);
|
|
2858
|
+
}
|
|
2859
|
+
this.closing = true;
|
|
2860
|
+
let resolveGate;
|
|
2861
|
+
const completion = new Promise((resolve5) => {
|
|
2862
|
+
resolveGate = resolve5;
|
|
2863
|
+
});
|
|
2864
|
+
this.closeGateCompletion = completion;
|
|
2865
|
+
this.resolveCloseGate = resolveGate;
|
|
2866
|
+
let released = false;
|
|
2867
|
+
return () => {
|
|
2868
|
+
if (released) return;
|
|
2869
|
+
released = true;
|
|
2870
|
+
if (this.closeGateCompletion === completion) {
|
|
2871
|
+
this.closeGateCompletion = null;
|
|
2872
|
+
this.resolveCloseGate = null;
|
|
2873
|
+
}
|
|
2874
|
+
resolveGate();
|
|
2875
|
+
if (this.disposed) return;
|
|
2876
|
+
this.closing = false;
|
|
2877
|
+
void this.#drainCronQueue();
|
|
2878
|
+
void this.#drainNotificationQueue();
|
|
2879
|
+
};
|
|
2880
|
+
}
|
|
2881
|
+
beginCloseIfAvailable() {
|
|
2882
|
+
if (this.disposed) {
|
|
2883
|
+
throw RequestError.invalidParams(void 0, "Session has been disposed");
|
|
2884
|
+
}
|
|
2885
|
+
return this.closing ? null : this.beginClose();
|
|
2886
|
+
}
|
|
2887
|
+
waitForCloseGateToRelease() {
|
|
2888
|
+
return this.closeGateCompletion ?? Promise.resolve();
|
|
2889
|
+
}
|
|
2890
|
+
async waitForActiveTurnsToSettle() {
|
|
2891
|
+
const pending = [
|
|
2892
|
+
this.pendingPromptCompletion,
|
|
2893
|
+
this.cronCompletion,
|
|
2894
|
+
this.notificationCompletion
|
|
2895
|
+
].filter((completion) => completion !== null);
|
|
2896
|
+
await Promise.allSettled(pending);
|
|
2897
|
+
}
|
|
2898
|
+
#deferAutomaticQueueDrainUntilTurnsSettle() {
|
|
2899
|
+
const completions = [
|
|
2900
|
+
this.pendingPromptCompletion,
|
|
2901
|
+
this.cronCompletion,
|
|
2902
|
+
this.notificationCompletion
|
|
2903
|
+
].filter((completion) => completion !== null);
|
|
2904
|
+
if (completions.length === 0) return false;
|
|
2905
|
+
if (this.automaticDrainRetry) return true;
|
|
2906
|
+
const retry = Promise.allSettled(completions).then(() => {
|
|
2907
|
+
if (this.automaticDrainRetry !== retry) return;
|
|
2908
|
+
this.automaticDrainRetry = null;
|
|
2909
|
+
if (this.disposed) return;
|
|
2910
|
+
void this.#drainCronQueue();
|
|
2911
|
+
void this.#drainNotificationQueue();
|
|
2912
|
+
});
|
|
2913
|
+
this.automaticDrainRetry = retry;
|
|
2914
|
+
return true;
|
|
2648
2915
|
}
|
|
2649
2916
|
getTurnCount() {
|
|
2650
2917
|
return this.turn;
|
|
@@ -2654,6 +2921,10 @@ var Session = class {
|
|
|
2654
2921
|
}
|
|
2655
2922
|
dispose() {
|
|
2656
2923
|
this.disposed = true;
|
|
2924
|
+
this.closing = true;
|
|
2925
|
+
this.resolveCloseGate?.();
|
|
2926
|
+
this.resolveCloseGate = null;
|
|
2927
|
+
this.closeGateCompletion = null;
|
|
2657
2928
|
this.todoStopGuardQueuedPromptPriority = false;
|
|
2658
2929
|
this.todoStopGuardDrainAutomaticQueuesWhenIdle = false;
|
|
2659
2930
|
this.todoStopGuard.clearTrust();
|
|
@@ -2670,8 +2941,9 @@ var Session = class {
|
|
|
2670
2941
|
this.cronProcessing = false;
|
|
2671
2942
|
this.cronCompletion = null;
|
|
2672
2943
|
if (this.config.isCronEnabled()) {
|
|
2673
|
-
this
|
|
2944
|
+
this.#stopCronSchedulerInRuntime();
|
|
2674
2945
|
}
|
|
2946
|
+
this.config.getBackgroundTaskRegistry().abortAll({ notify: false });
|
|
2675
2947
|
this.config.getBackgroundTaskRegistry().setNotificationCallback(void 0);
|
|
2676
2948
|
this.config.getMonitorRegistry().setNotificationCallback(void 0);
|
|
2677
2949
|
this.config.getBackgroundShellRegistry().setNotificationCallback(void 0);
|
|
@@ -2754,7 +3026,7 @@ var Session = class {
|
|
|
2754
3026
|
"targetTurnIndex must be a non-negative integer"
|
|
2755
3027
|
);
|
|
2756
3028
|
}
|
|
2757
|
-
if (this.
|
|
3029
|
+
if (this.closing || this.#hasActiveTurn()) {
|
|
2758
3030
|
throw RequestError.invalidParams(
|
|
2759
3031
|
void 0,
|
|
2760
3032
|
"Cannot rewind while a prompt is running"
|
|
@@ -2811,7 +3083,7 @@ var Session = class {
|
|
|
2811
3083
|
return count;
|
|
2812
3084
|
}
|
|
2813
3085
|
restoreHistory(history) {
|
|
2814
|
-
if (this.
|
|
3086
|
+
if (this.closing || this.#hasActiveTurn()) {
|
|
2815
3087
|
throw RequestError.invalidParams(
|
|
2816
3088
|
void 0,
|
|
2817
3089
|
"Cannot restore history while a prompt is running"
|
|
@@ -2885,17 +3157,37 @@ var Session = class {
|
|
|
2885
3157
|
const scheduler = this.config.isCronEnabled() ? this.config.getCronScheduler() : null;
|
|
2886
3158
|
if (scheduler) {
|
|
2887
3159
|
const summary = scheduler.getExitSummary();
|
|
2888
|
-
|
|
3160
|
+
this.#stopCronSchedulerInRuntime();
|
|
2889
3161
|
if (summary) {
|
|
2890
3162
|
await this.messageEmitter.emitAgentMessage(summary);
|
|
2891
3163
|
}
|
|
2892
3164
|
}
|
|
2893
3165
|
}
|
|
2894
|
-
async prompt(params) {
|
|
3166
|
+
async prompt(params, invocationContext, admissionCancellation) {
|
|
3167
|
+
if (this.closing) {
|
|
3168
|
+
throw RequestError.invalidParams(void 0, "Session is closing");
|
|
3169
|
+
}
|
|
3170
|
+
await this.assertCanStartTurn();
|
|
3171
|
+
if (admissionCancellation?.aborted) {
|
|
3172
|
+
return { stopReason: "cancelled" };
|
|
3173
|
+
}
|
|
2895
3174
|
const todoStopGuardPreparation = this.#prepareTodoStopGuardForPrompt(params);
|
|
2896
3175
|
this.pendingPrompt?.abort();
|
|
2897
3176
|
const pendingSend = new AbortController();
|
|
3177
|
+
const cancelPendingSend = /* @__PURE__ */ __name(() => pendingSend.abort(USER_CANCEL_ABORT_REASON), "cancelPendingSend");
|
|
3178
|
+
if (admissionCancellation) {
|
|
3179
|
+
admissionCancellation.addEventListener("abort", cancelPendingSend, {
|
|
3180
|
+
once: true
|
|
3181
|
+
});
|
|
3182
|
+
if (admissionCancellation.aborted) cancelPendingSend();
|
|
3183
|
+
}
|
|
2898
3184
|
this.pendingPrompt = pendingSend;
|
|
3185
|
+
const releasePendingSend = /* @__PURE__ */ __name(() => {
|
|
3186
|
+
admissionCancellation?.removeEventListener("abort", cancelPendingSend);
|
|
3187
|
+
if (this.pendingPrompt === pendingSend) {
|
|
3188
|
+
this.pendingPrompt = null;
|
|
3189
|
+
}
|
|
3190
|
+
}, "releasePendingSend");
|
|
2899
3191
|
if (this.followupAbort) {
|
|
2900
3192
|
this.followupAbort.abort();
|
|
2901
3193
|
this.followupAbort = null;
|
|
@@ -2932,6 +3224,8 @@ var Session = class {
|
|
|
2932
3224
|
}
|
|
2933
3225
|
}
|
|
2934
3226
|
if (pendingSend.signal.aborted) {
|
|
3227
|
+
releasePendingSend();
|
|
3228
|
+
this.todoStopGuard.suspend();
|
|
2935
3229
|
return { stopReason: "cancelled" };
|
|
2936
3230
|
}
|
|
2937
3231
|
if (todoStopGuardPreparation.startsWorkChain) {
|
|
@@ -2940,26 +3234,52 @@ var Session = class {
|
|
|
2940
3234
|
this.todoStopGuardBackgroundBaseline = this.#captureTodoStopGuardBackgroundBaseline();
|
|
2941
3235
|
}
|
|
2942
3236
|
this.duplicateProviderToolCallResponseIds.clear();
|
|
3237
|
+
const channelDelivery = parsePromptChannelDelivery(params);
|
|
3238
|
+
const channelDeliveryCapture = channelDelivery ? { finalText: "" } : void 0;
|
|
2943
3239
|
let resolveCompletion;
|
|
2944
3240
|
this.pendingPromptCompletion = new Promise((resolve5) => {
|
|
2945
3241
|
resolveCompletion = resolve5;
|
|
2946
3242
|
});
|
|
2947
3243
|
try {
|
|
2948
|
-
const result = await this.#executePrompt(
|
|
2949
|
-
|
|
3244
|
+
const result = await this.#executePrompt(
|
|
3245
|
+
params,
|
|
3246
|
+
pendingSend,
|
|
3247
|
+
channelDeliveryCapture,
|
|
3248
|
+
invocationContext
|
|
3249
|
+
);
|
|
3250
|
+
releasePendingSend();
|
|
2950
3251
|
void this.#drainCronQueue();
|
|
2951
3252
|
void this.#drainNotificationQueue();
|
|
2952
3253
|
this.#maybeEmitFollowupSuggestion(result);
|
|
3254
|
+
if (channelDelivery && result.stopReason === "end_turn") {
|
|
3255
|
+
this.#scheduleChannelDelivery({
|
|
3256
|
+
sessionId: this.sessionId,
|
|
3257
|
+
deliveryId: channelDelivery.deliveryId,
|
|
3258
|
+
source: "prompt",
|
|
3259
|
+
target: channelDelivery.target,
|
|
3260
|
+
text: normalizeChannelDeliveryText(
|
|
3261
|
+
channelDeliveryCapture?.finalText ?? ""
|
|
3262
|
+
),
|
|
3263
|
+
promptId: channelDelivery.deliveryId
|
|
3264
|
+
});
|
|
3265
|
+
}
|
|
2953
3266
|
return result;
|
|
3267
|
+
} catch (error) {
|
|
3268
|
+
if (error instanceof SessionWriterError) {
|
|
3269
|
+
throw new RequestError(error.rpcCode, error.message, {
|
|
3270
|
+
errorKind: error.errorKind
|
|
3271
|
+
});
|
|
3272
|
+
}
|
|
3273
|
+
throw error;
|
|
2954
3274
|
} finally {
|
|
2955
|
-
|
|
3275
|
+
releasePendingSend();
|
|
2956
3276
|
const shouldDrainAutomaticQueues = todoStopGuardPreparation.drainSupersededAutomaticQueues || this.todoStopGuardDrainAutomaticQueuesWhenIdle || this.todoStopGuard.blocksUnrelatedAutomaticTurns || this.todoStopGuard.hasCommittedContinuation || this.todoStopGuardQueuedPromptPriority;
|
|
2957
3277
|
this.todoStopGuardDrainAutomaticQueuesWhenIdle = false;
|
|
2958
3278
|
if (shouldDrainAutomaticQueues) {
|
|
2959
3279
|
void this.#drainCronQueue();
|
|
2960
3280
|
void this.#drainNotificationQueue();
|
|
2961
3281
|
}
|
|
2962
|
-
void this.#
|
|
3282
|
+
void this.#startCronSchedulerInRuntime();
|
|
2963
3283
|
resolveCompletion();
|
|
2964
3284
|
this.pendingPromptCompletion = null;
|
|
2965
3285
|
}
|
|
@@ -3082,17 +3402,31 @@ var Session = class {
|
|
|
3082
3402
|
}
|
|
3083
3403
|
})();
|
|
3084
3404
|
}
|
|
3085
|
-
async #executePrompt(params, pendingSend) {
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3405
|
+
async #executePrompt(params, pendingSend, channelDeliveryCapture, invocationContext) {
|
|
3406
|
+
const sessionId = this.config.getSessionId();
|
|
3407
|
+
if (invocationContext !== void 0 && invocationContext.sessionId !== sessionId) {
|
|
3408
|
+
throw RequestError.invalidParams(
|
|
3409
|
+
void 0,
|
|
3410
|
+
"Invocation context session does not match the active session"
|
|
3411
|
+
);
|
|
3412
|
+
}
|
|
3413
|
+
return runWithInvocationContext(
|
|
3414
|
+
invocationContext,
|
|
3415
|
+
() => sessionIdContext.run(
|
|
3416
|
+
sessionId,
|
|
3417
|
+
() => this.#executePromptInner(params, pendingSend, channelDeliveryCapture)
|
|
3418
|
+
)
|
|
3089
3419
|
);
|
|
3090
3420
|
}
|
|
3091
|
-
async #executePromptInner(params, pendingSend) {
|
|
3421
|
+
async #executePromptInner(params, pendingSend, channelDeliveryCapture) {
|
|
3092
3422
|
return Storage.runWithRuntimeBaseDir(
|
|
3093
3423
|
this.runtimeBaseDir,
|
|
3094
3424
|
this.config.getWorkingDir(),
|
|
3095
3425
|
async () => {
|
|
3426
|
+
await this.assertCanStartTurn();
|
|
3427
|
+
if (pendingSend.signal.aborted) {
|
|
3428
|
+
return { stopReason: "cancelled" };
|
|
3429
|
+
}
|
|
3096
3430
|
this.turn += 1;
|
|
3097
3431
|
const promptId = this.config.getSessionId() + "########" + this.turn;
|
|
3098
3432
|
const parentContext = extractDaemonTraceContext(params);
|
|
@@ -3156,6 +3490,7 @@ var Session = class {
|
|
|
3156
3490
|
(block) => block.type === "text"
|
|
3157
3491
|
);
|
|
3158
3492
|
const inputText = firstTextBlock?.text || "";
|
|
3493
|
+
const isSlashInput = !isContinue && isSlashCommand(inputText);
|
|
3159
3494
|
let parts;
|
|
3160
3495
|
let fullTurnModelOverride;
|
|
3161
3496
|
const onFullTurnModel = /* @__PURE__ */ __name((model) => {
|
|
@@ -3167,7 +3502,7 @@ var Session = class {
|
|
|
3167
3502
|
}, "onFullTurnModel");
|
|
3168
3503
|
if (isContinue) {
|
|
3169
3504
|
parts = continuationParts;
|
|
3170
|
-
} else if (
|
|
3505
|
+
} else if (isSlashInput) {
|
|
3171
3506
|
const slashCommandResult = await handleSlashCommand(
|
|
3172
3507
|
inputText,
|
|
3173
3508
|
pendingSend,
|
|
@@ -3251,6 +3586,17 @@ ${this.pendingWorktreeNotice}
|
|
|
3251
3586
|
parts = insertAfterFunctionResponses(parts, [noticePart]);
|
|
3252
3587
|
this.pendingWorktreeNotice = null;
|
|
3253
3588
|
}
|
|
3589
|
+
if (this.pendingRecoveredAgentsNotice && !isContinue && !isSlashInput) {
|
|
3590
|
+
const noticePart = {
|
|
3591
|
+
text: `<system-reminder>
|
|
3592
|
+
${this.pendingRecoveredAgentsNotice}
|
|
3593
|
+
</system-reminder>
|
|
3594
|
+
|
|
3595
|
+
`
|
|
3596
|
+
};
|
|
3597
|
+
parts = insertAfterFunctionResponses(parts, [noticePart]);
|
|
3598
|
+
this.pendingRecoveredAgentsNotice = null;
|
|
3599
|
+
}
|
|
3254
3600
|
let nextMessage = { role: "user", parts };
|
|
3255
3601
|
let turnCount = 0;
|
|
3256
3602
|
const toolLoopState = createDaemonToolLoopState();
|
|
@@ -3271,6 +3617,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3271
3617
|
const messageDisplay = this.#createMessageDisplayDispatcher(
|
|
3272
3618
|
pendingSend.signal
|
|
3273
3619
|
);
|
|
3620
|
+
let channelDeliveryResponseBlock;
|
|
3274
3621
|
try {
|
|
3275
3622
|
const sendResult = await this.#sendMessageStreamWithAutoCompression(
|
|
3276
3623
|
promptId,
|
|
@@ -3288,6 +3635,8 @@ ${this.pendingWorktreeNotice}
|
|
|
3288
3635
|
}
|
|
3289
3636
|
const responseStream = sendResult.responseStream;
|
|
3290
3637
|
nextMessage = null;
|
|
3638
|
+
channelDeliveryResponseBlock = beginChannelDeliveryResponseBlock(channelDeliveryCapture);
|
|
3639
|
+
const channelDeliveryCheckpoint = channelDeliveryResponseBlock?.length ?? 0;
|
|
3291
3640
|
let streamFailed = false;
|
|
3292
3641
|
try {
|
|
3293
3642
|
for await (const resp of responseStream) {
|
|
@@ -3307,6 +3656,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3307
3656
|
part.thought
|
|
3308
3657
|
);
|
|
3309
3658
|
if (!part.thought) {
|
|
3659
|
+
channelDeliveryResponseBlock?.push(part.text);
|
|
3310
3660
|
messageDisplay?.addChunk(part.text);
|
|
3311
3661
|
}
|
|
3312
3662
|
}
|
|
@@ -3322,6 +3672,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3322
3672
|
}
|
|
3323
3673
|
}
|
|
3324
3674
|
if (resp.type === "retry" /* RETRY */ || resp.type === "model_fallback" /* MODEL_FALLBACK */) {
|
|
3675
|
+
if (resp.type === "model_fallback" /* MODEL_FALLBACK */ || !resp.isContinuation) {
|
|
3676
|
+
if (channelDeliveryResponseBlock) {
|
|
3677
|
+
channelDeliveryResponseBlock.length = channelDeliveryCheckpoint;
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3325
3680
|
await finalizeToolCallPreparations(
|
|
3326
3681
|
preparationTracker,
|
|
3327
3682
|
true,
|
|
@@ -3375,6 +3730,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3375
3730
|
} finally {
|
|
3376
3731
|
await messageDisplay?.finish();
|
|
3377
3732
|
}
|
|
3733
|
+
commitChannelDeliveryResponseBlock(
|
|
3734
|
+
channelDeliveryCapture,
|
|
3735
|
+
channelDeliveryResponseBlock,
|
|
3736
|
+
functionCalls.length > 0
|
|
3737
|
+
);
|
|
3378
3738
|
if (usageMetadata) {
|
|
3379
3739
|
this.#recordPromptTokenCount(usageMetadata);
|
|
3380
3740
|
if (this.messageRewriter) {
|
|
@@ -3403,7 +3763,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3403
3763
|
toolRun,
|
|
3404
3764
|
pendingSend.signal
|
|
3405
3765
|
);
|
|
3406
|
-
return {
|
|
3766
|
+
return {
|
|
3767
|
+
stopReason: getAbortAwareEndTurnStopReason(
|
|
3768
|
+
pendingSend.signal
|
|
3769
|
+
)
|
|
3770
|
+
};
|
|
3407
3771
|
}
|
|
3408
3772
|
const nextAfterTools = await this.#buildNextMessageAfterToolRun(
|
|
3409
3773
|
toolRun,
|
|
@@ -3417,7 +3781,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3417
3781
|
toolRun,
|
|
3418
3782
|
pendingSend.signal
|
|
3419
3783
|
);
|
|
3420
|
-
return {
|
|
3784
|
+
return {
|
|
3785
|
+
stopReason: getAbortAwareEndTurnStopReason(
|
|
3786
|
+
pendingSend.signal
|
|
3787
|
+
)
|
|
3788
|
+
};
|
|
3421
3789
|
}
|
|
3422
3790
|
}
|
|
3423
3791
|
}
|
|
@@ -3430,7 +3798,8 @@ ${this.pendingWorktreeNotice}
|
|
|
3430
3798
|
hooksEnabled,
|
|
3431
3799
|
messageBus,
|
|
3432
3800
|
true,
|
|
3433
|
-
fullTurnModelOverride
|
|
3801
|
+
fullTurnModelOverride,
|
|
3802
|
+
channelDeliveryCapture
|
|
3434
3803
|
);
|
|
3435
3804
|
} finally {
|
|
3436
3805
|
logConversationFinishedEvent(
|
|
@@ -3447,7 +3816,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3447
3816
|
}
|
|
3448
3817
|
);
|
|
3449
3818
|
}
|
|
3450
|
-
async #handleStopHookLoop(pendingSend, promptId, hooksEnabled, messageBus, allowExternalHooks = true, modelOverride) {
|
|
3819
|
+
async #handleStopHookLoop(pendingSend, promptId, hooksEnabled, messageBus, allowExternalHooks = true, modelOverride, channelDeliveryCapture) {
|
|
3451
3820
|
const stopHookBlockingCap = this.config.getStopHookBlockingCap();
|
|
3452
3821
|
let stopHookIterationCount = 0;
|
|
3453
3822
|
let stopHookReasons = [];
|
|
@@ -3462,7 +3831,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3462
3831
|
while (true) {
|
|
3463
3832
|
if (pendingSend.signal.aborted) {
|
|
3464
3833
|
this.todoStopGuard.suspend();
|
|
3465
|
-
return { stopReason: "
|
|
3834
|
+
return { stopReason: "cancelled" };
|
|
3466
3835
|
}
|
|
3467
3836
|
if (this.config.getApprovalMode() === "plan" /* PLAN */) {
|
|
3468
3837
|
this.#clearTodoStopGuardTrustAndDrainAutomaticQueues();
|
|
@@ -3489,7 +3858,8 @@ ${this.pendingWorktreeNotice}
|
|
|
3489
3858
|
false,
|
|
3490
3859
|
{
|
|
3491
3860
|
onFullTurnModel,
|
|
3492
|
-
getModelOverride: /* @__PURE__ */ __name(() => modelOverride, "getModelOverride")
|
|
3861
|
+
getModelOverride: /* @__PURE__ */ __name(() => modelOverride, "getModelOverride"),
|
|
3862
|
+
channelDeliveryCapture
|
|
3493
3863
|
}
|
|
3494
3864
|
);
|
|
3495
3865
|
if (continuation2.kind === "terminal") {
|
|
@@ -3551,7 +3921,8 @@ ${this.pendingWorktreeNotice}
|
|
|
3551
3921
|
false,
|
|
3552
3922
|
{
|
|
3553
3923
|
onFullTurnModel,
|
|
3554
|
-
getModelOverride: /* @__PURE__ */ __name(() => modelOverride, "getModelOverride")
|
|
3924
|
+
getModelOverride: /* @__PURE__ */ __name(() => modelOverride, "getModelOverride"),
|
|
3925
|
+
channelDeliveryCapture
|
|
3555
3926
|
}
|
|
3556
3927
|
);
|
|
3557
3928
|
if (continuation2.kind === "terminal") {
|
|
@@ -3565,7 +3936,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3565
3936
|
await this.messageEmitter.emitAgentMessage(stopOutput.systemMessage);
|
|
3566
3937
|
}
|
|
3567
3938
|
if (stopOutput?.isBlockingDecision() || stopOutput?.shouldStopExecution()) {
|
|
3568
|
-
externalReason = stopOutput
|
|
3939
|
+
externalReason = getStopHookContinuationReason(stopOutput);
|
|
3569
3940
|
stopHookIterationCount++;
|
|
3570
3941
|
stopHookReasons = [...stopHookReasons, externalReason];
|
|
3571
3942
|
stopHookCount = response.stopHookCount ?? 1;
|
|
@@ -3632,7 +4003,8 @@ ${this.pendingWorktreeNotice}
|
|
|
3632
4003
|
), "onAutomaticContinuationValidated")
|
|
3633
4004
|
} : {},
|
|
3634
4005
|
onFullTurnModel,
|
|
3635
|
-
getModelOverride: /* @__PURE__ */ __name(() => modelOverride, "getModelOverride")
|
|
4006
|
+
getModelOverride: /* @__PURE__ */ __name(() => modelOverride, "getModelOverride"),
|
|
4007
|
+
channelDeliveryCapture
|
|
3636
4008
|
}
|
|
3637
4009
|
);
|
|
3638
4010
|
if (continuation.supersededAutomaticContinuation && externalReason) {
|
|
@@ -3675,6 +4047,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3675
4047
|
const messageDisplay = this.#createMessageDisplayDispatcher(
|
|
3676
4048
|
pendingSend.signal
|
|
3677
4049
|
);
|
|
4050
|
+
let channelDeliveryResponseBlock;
|
|
3678
4051
|
try {
|
|
3679
4052
|
const sendResult = await this.#sendMessageStreamWithAutoCompression(
|
|
3680
4053
|
promptIdForSend,
|
|
@@ -3806,6 +4179,10 @@ ${this.pendingWorktreeNotice}
|
|
|
3806
4179
|
}
|
|
3807
4180
|
const responseStream = sendResult.responseStream;
|
|
3808
4181
|
nextMessage = null;
|
|
4182
|
+
channelDeliveryResponseBlock = beginChannelDeliveryResponseBlock(
|
|
4183
|
+
options.channelDeliveryCapture
|
|
4184
|
+
);
|
|
4185
|
+
const channelDeliveryCheckpoint = channelDeliveryResponseBlock?.length ?? 0;
|
|
3809
4186
|
initialSend = false;
|
|
3810
4187
|
if (guardForThisSend) {
|
|
3811
4188
|
const guardCommitted = this.todoStopGuard.commitContinuation(
|
|
@@ -3836,7 +4213,10 @@ ${this.pendingWorktreeNotice}
|
|
|
3836
4213
|
"assistant",
|
|
3837
4214
|
part.thought
|
|
3838
4215
|
);
|
|
3839
|
-
if (!part.thought)
|
|
4216
|
+
if (!part.thought) {
|
|
4217
|
+
channelDeliveryResponseBlock?.push(part.text);
|
|
4218
|
+
messageDisplay?.addChunk(part.text);
|
|
4219
|
+
}
|
|
3840
4220
|
}
|
|
3841
4221
|
}
|
|
3842
4222
|
if (response.type === "chunk" /* CHUNK */ && response.value.usageMetadata) {
|
|
@@ -3850,6 +4230,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3850
4230
|
}
|
|
3851
4231
|
}
|
|
3852
4232
|
if (response.type === "retry" /* RETRY */ || response.type === "model_fallback" /* MODEL_FALLBACK */) {
|
|
4233
|
+
if (response.type === "model_fallback" /* MODEL_FALLBACK */ || !response.isContinuation) {
|
|
4234
|
+
if (channelDeliveryResponseBlock) {
|
|
4235
|
+
channelDeliveryResponseBlock.length = channelDeliveryCheckpoint;
|
|
4236
|
+
}
|
|
4237
|
+
}
|
|
3853
4238
|
await finalizeToolCallPreparations(
|
|
3854
4239
|
preparationTracker,
|
|
3855
4240
|
true,
|
|
@@ -3888,6 +4273,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3888
4273
|
await messageDisplay?.finish();
|
|
3889
4274
|
}
|
|
3890
4275
|
}
|
|
4276
|
+
commitChannelDeliveryResponseBlock(
|
|
4277
|
+
options.channelDeliveryCapture,
|
|
4278
|
+
channelDeliveryResponseBlock,
|
|
4279
|
+
functionCalls.length > 0
|
|
4280
|
+
);
|
|
3891
4281
|
if (usageMetadata) {
|
|
3892
4282
|
this.#recordPromptTokenCount(usageMetadata);
|
|
3893
4283
|
const durationMs = Date.now() - streamStartTime;
|
|
@@ -3912,7 +4302,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3912
4302
|
await this.#preserveStoppedToolRun(toolRun, pendingSend.signal);
|
|
3913
4303
|
return {
|
|
3914
4304
|
kind: "terminal",
|
|
3915
|
-
stopReason:
|
|
4305
|
+
stopReason: getAbortAwareEndTurnStopReason(pendingSend.signal),
|
|
3916
4306
|
...supersededAutomaticContinuation ? { supersededAutomaticContinuation: true } : {}
|
|
3917
4307
|
};
|
|
3918
4308
|
}
|
|
@@ -4007,6 +4397,19 @@ ${this.pendingWorktreeNotice}
|
|
|
4007
4397
|
};
|
|
4008
4398
|
await this.client.sessionUpdate(params);
|
|
4009
4399
|
}
|
|
4400
|
+
#scheduleChannelDelivery(params) {
|
|
4401
|
+
const timer = setTimeout(() => {
|
|
4402
|
+
void this.client.extMethod(SERVE_CONTROL_EXT_METHODS.channelDelivery, params).catch((error) => {
|
|
4403
|
+
try {
|
|
4404
|
+
debugLogger6.warn(
|
|
4405
|
+
`Channel delivery submission failed: ${error instanceof Error ? error.message : String(error)}`
|
|
4406
|
+
);
|
|
4407
|
+
} catch {
|
|
4408
|
+
}
|
|
4409
|
+
});
|
|
4410
|
+
}, 0);
|
|
4411
|
+
timer.unref();
|
|
4412
|
+
}
|
|
4010
4413
|
#getCurrentChat() {
|
|
4011
4414
|
return this.config.getGeminiClient().getChat();
|
|
4012
4415
|
}
|
|
@@ -4161,13 +4564,18 @@ ${this.pendingWorktreeNotice}
|
|
|
4161
4564
|
}
|
|
4162
4565
|
}
|
|
4163
4566
|
async #preserveStoppedToolRun(toolRun, abortSignal) {
|
|
4567
|
+
const midTurnParts = abortSignal.aborted ? await this.#buildMidTurnParts(
|
|
4568
|
+
this.#takeRecoveredMidTurnMessages(),
|
|
4569
|
+
abortSignal,
|
|
4570
|
+
{ preserveFallbackOnAbort: true }
|
|
4571
|
+
) : await this.#drainMidTurnUserMessages(abortSignal);
|
|
4164
4572
|
this.#preserveUnsentMessageHistory(
|
|
4165
4573
|
{
|
|
4166
4574
|
role: "user",
|
|
4167
4575
|
parts: [
|
|
4168
4576
|
...toolRun.parts,
|
|
4169
4577
|
...toolRun.loopDetected ? [{ text: LOOP_DETECTED_CONTEXT_MESSAGE }] : [],
|
|
4170
|
-
...
|
|
4578
|
+
...midTurnParts
|
|
4171
4579
|
]
|
|
4172
4580
|
},
|
|
4173
4581
|
true
|
|
@@ -4282,11 +4690,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4282
4690
|
const recovered = this.#takeRecoveredMidTurnMessages();
|
|
4283
4691
|
if (this.midTurnDrainUnavailable) {
|
|
4284
4692
|
return {
|
|
4285
|
-
parts: await this.#buildMidTurnParts(
|
|
4286
|
-
recovered,
|
|
4287
|
-
abortSignal,
|
|
4288
|
-
options.onFullTurnModel
|
|
4289
|
-
),
|
|
4693
|
+
parts: await this.#buildMidTurnParts(recovered, abortSignal, options),
|
|
4290
4694
|
hasQueuedPrompt: false
|
|
4291
4695
|
};
|
|
4292
4696
|
}
|
|
@@ -4314,7 +4718,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4314
4718
|
parts: await this.#buildMidTurnParts(
|
|
4315
4719
|
[...recovered, ...parseMidTurnDrainResponse(response)],
|
|
4316
4720
|
abortSignal,
|
|
4317
|
-
options
|
|
4721
|
+
options
|
|
4318
4722
|
),
|
|
4319
4723
|
hasQueuedPrompt: isRecord2(response) && response["hasQueuedPrompt"] === true
|
|
4320
4724
|
};
|
|
@@ -4334,11 +4738,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4334
4738
|
`Mid-turn queue drain ${isPermanentError ? "permanently " : ""}unavailable [session ${this.sessionId}]: ${errorMessage}`
|
|
4335
4739
|
);
|
|
4336
4740
|
return {
|
|
4337
|
-
parts: await this.#buildMidTurnParts(
|
|
4338
|
-
recovered,
|
|
4339
|
-
abortSignal,
|
|
4340
|
-
options.onFullTurnModel
|
|
4341
|
-
),
|
|
4741
|
+
parts: await this.#buildMidTurnParts(recovered, abortSignal, options),
|
|
4342
4742
|
hasQueuedPrompt: false
|
|
4343
4743
|
};
|
|
4344
4744
|
}
|
|
@@ -4398,7 +4798,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4398
4798
|
* happens on injection (here), so a message recovered from an earlier
|
|
4399
4799
|
* timed-out drain is still recorded exactly once.
|
|
4400
4800
|
*/
|
|
4401
|
-
async #buildMidTurnParts(messages, abortSignal,
|
|
4801
|
+
async #buildMidTurnParts(messages, abortSignal, options = {}) {
|
|
4402
4802
|
const parts = [];
|
|
4403
4803
|
for (const message of messages) {
|
|
4404
4804
|
const displayText = message.kind === "text" ? message.message : message.displayText;
|
|
@@ -4408,13 +4808,19 @@ ${this.pendingWorktreeNotice}
|
|
|
4408
4808
|
abortSignal,
|
|
4409
4809
|
MID_TURN_QUEUE_RESOLVE_TIMEOUT_MS,
|
|
4410
4810
|
(signal) => this.#resolvePrompt(message.content, signal, {
|
|
4411
|
-
onFullTurnModel
|
|
4811
|
+
onFullTurnModel: options.onFullTurnModel
|
|
4412
4812
|
})
|
|
4413
4813
|
);
|
|
4414
4814
|
} catch (messageError) {
|
|
4415
|
-
if (abortSignal.aborted)
|
|
4416
|
-
|
|
4417
|
-
|
|
4815
|
+
if (abortSignal.aborted && !options.preserveFallbackOnAbort) {
|
|
4816
|
+
return parts;
|
|
4817
|
+
}
|
|
4818
|
+
if (!abortSignal.aborted) {
|
|
4819
|
+
const errorMessage = this.#formatError(messageError);
|
|
4820
|
+
debugLogger6.warn(
|
|
4821
|
+
`Failed to resolve mid-turn message: ${errorMessage}`
|
|
4822
|
+
);
|
|
4823
|
+
}
|
|
4418
4824
|
rawParts = [{ text: displayText }];
|
|
4419
4825
|
if (message.kind === "structured" && hasInlineMediaContentBlock(message.content)) {
|
|
4420
4826
|
rawParts.push({ text: MID_TURN_ATTACHMENT_PROCESSING_FAILURE_TEXT });
|
|
@@ -4451,11 +4857,27 @@ ${this.pendingWorktreeNotice}
|
|
|
4451
4857
|
this.#enqueueCronPrompt({
|
|
4452
4858
|
prompt: job.prompt,
|
|
4453
4859
|
source: job.cronExpr === "@wakeup" ? "loop" : "cron",
|
|
4454
|
-
...job.id ? { taskId: job.id } : {}
|
|
4860
|
+
...job.id ? { taskId: job.id } : {},
|
|
4861
|
+
...job.lastFiredAt !== void 0 ? { firedAt: job.lastFiredAt } : {},
|
|
4862
|
+
...job.delivery ? { delivery: job.delivery } : {}
|
|
4455
4863
|
});
|
|
4456
4864
|
void this.#drainCronQueue();
|
|
4457
4865
|
});
|
|
4458
4866
|
}
|
|
4867
|
+
#startCronSchedulerInRuntime() {
|
|
4868
|
+
return Storage.runWithRuntimeBaseDir(
|
|
4869
|
+
this.runtimeBaseDir,
|
|
4870
|
+
this.config.getWorkingDir(),
|
|
4871
|
+
() => this.#startCronSchedulerIfNeeded()
|
|
4872
|
+
);
|
|
4873
|
+
}
|
|
4874
|
+
#stopCronSchedulerInRuntime() {
|
|
4875
|
+
Storage.runWithRuntimeBaseDir(
|
|
4876
|
+
this.runtimeBaseDir,
|
|
4877
|
+
this.config.getWorkingDir(),
|
|
4878
|
+
() => this.config.getCronScheduler().stop()
|
|
4879
|
+
);
|
|
4880
|
+
}
|
|
4459
4881
|
#enqueueCronPrompt(item) {
|
|
4460
4882
|
if ((this.todoStopGuard.blocksUnrelatedAutomaticTurns || this.todoStopGuardQueuedPromptPriority) && !this.#cronContinuesTodoStopGuardWorkChain(item)) {
|
|
4461
4883
|
if (item.taskId) {
|
|
@@ -4486,17 +4908,31 @@ ${this.pendingWorktreeNotice}
|
|
|
4486
4908
|
*/
|
|
4487
4909
|
async #drainCronQueue() {
|
|
4488
4910
|
if (this.disposed) return;
|
|
4911
|
+
if (this.closing) return;
|
|
4489
4912
|
if (this.cronProcessing) return;
|
|
4490
4913
|
if (this.pendingPrompt) return;
|
|
4491
4914
|
if (this.notificationProcessing) return;
|
|
4915
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4492
4916
|
if (this.#nextCronQueueIndex() < 0) return;
|
|
4493
|
-
this.cronProcessing = true;
|
|
4494
|
-
let resolveCompletion;
|
|
4495
|
-
this.cronCompletion = new Promise((resolve5) => {
|
|
4496
|
-
resolveCompletion = resolve5;
|
|
4497
|
-
});
|
|
4498
4917
|
try {
|
|
4499
|
-
|
|
4918
|
+
await this.assertCanStartTurn();
|
|
4919
|
+
} catch (error) {
|
|
4920
|
+
debugLogger6.warn(
|
|
4921
|
+
`Cron turn rejected [session ${this.sessionId}]: ${error instanceof Error ? error.message : String(error)}`
|
|
4922
|
+
);
|
|
4923
|
+
return;
|
|
4924
|
+
}
|
|
4925
|
+
if (this.disposed || this.closing || this.cronProcessing || this.pendingPrompt || this.notificationProcessing || this.#nextCronQueueIndex() < 0) {
|
|
4926
|
+
return;
|
|
4927
|
+
}
|
|
4928
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4929
|
+
this.cronProcessing = true;
|
|
4930
|
+
let resolveCompletion;
|
|
4931
|
+
this.cronCompletion = new Promise((resolve5) => {
|
|
4932
|
+
resolveCompletion = resolve5;
|
|
4933
|
+
});
|
|
4934
|
+
try {
|
|
4935
|
+
while (this.cronQueue.length > 0) {
|
|
4500
4936
|
const nextIndex = this.#nextCronQueueIndex();
|
|
4501
4937
|
if (nextIndex < 0) break;
|
|
4502
4938
|
const [item] = this.cronQueue.splice(nextIndex, 1);
|
|
@@ -4511,7 +4947,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4511
4947
|
if (this.config.isCronEnabled()) {
|
|
4512
4948
|
const scheduler = this.config.getCronScheduler();
|
|
4513
4949
|
if (!scheduler.hasPendingWork) {
|
|
4514
|
-
|
|
4950
|
+
this.#stopCronSchedulerInRuntime();
|
|
4515
4951
|
}
|
|
4516
4952
|
}
|
|
4517
4953
|
}
|
|
@@ -4550,9 +4986,12 @@ ${this.pendingWorktreeNotice}
|
|
|
4550
4986
|
* `_meta.source='cron'`, streams the model response, and handles tool calls.
|
|
4551
4987
|
*/
|
|
4552
4988
|
async #executeCronPrompt(item) {
|
|
4553
|
-
return
|
|
4554
|
-
|
|
4555
|
-
() =>
|
|
4989
|
+
return runWithInvocationContext(
|
|
4990
|
+
void 0,
|
|
4991
|
+
() => sessionIdContext.run(
|
|
4992
|
+
this.config.getSessionId(),
|
|
4993
|
+
() => this.#executeCronPromptInner(item)
|
|
4994
|
+
)
|
|
4556
4995
|
);
|
|
4557
4996
|
}
|
|
4558
4997
|
async #executeCronPromptInner(item) {
|
|
@@ -4568,6 +5007,8 @@ ${this.pendingWorktreeNotice}
|
|
|
4568
5007
|
);
|
|
4569
5008
|
const promptId = this.config.getSessionId() + "########cron" + Date.now();
|
|
4570
5009
|
let cronHadError = false;
|
|
5010
|
+
let cronCompleted = false;
|
|
5011
|
+
const channelDeliveryCapture = item.delivery ? { finalText: "" } : void 0;
|
|
4571
5012
|
await withInteractionSpan(
|
|
4572
5013
|
this.config,
|
|
4573
5014
|
{
|
|
@@ -4578,6 +5019,8 @@ ${this.pendingWorktreeNotice}
|
|
|
4578
5019
|
async () => {
|
|
4579
5020
|
let turnCount = 0;
|
|
4580
5021
|
try {
|
|
5022
|
+
await this.assertCanStartTurn();
|
|
5023
|
+
if (ac.signal.aborted) return;
|
|
4581
5024
|
const loopMode = detectLoopSentinel(prompt);
|
|
4582
5025
|
const autonomousMode = loopMode ? null : detectAutonomousSentinel(prompt);
|
|
4583
5026
|
let loopTick = null;
|
|
@@ -4666,6 +5109,8 @@ ${this.pendingWorktreeNotice}
|
|
|
4666
5109
|
return;
|
|
4667
5110
|
}
|
|
4668
5111
|
const responseStream = sendResult.responseStream;
|
|
5112
|
+
const channelDeliveryResponseBlock = beginChannelDeliveryResponseBlock(channelDeliveryCapture);
|
|
5113
|
+
const channelDeliveryCheckpoint = channelDeliveryResponseBlock?.length ?? 0;
|
|
4669
5114
|
if (loopTick && turnCount === 1) {
|
|
4670
5115
|
this.loopTickResolver?.markDelivered();
|
|
4671
5116
|
}
|
|
@@ -4690,6 +5135,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4690
5135
|
part.thought
|
|
4691
5136
|
);
|
|
4692
5137
|
if (!part.thought) {
|
|
5138
|
+
channelDeliveryResponseBlock?.push(part.text);
|
|
4693
5139
|
messageDisplay?.addChunk(part.text);
|
|
4694
5140
|
}
|
|
4695
5141
|
}
|
|
@@ -4705,6 +5151,11 @@ ${this.pendingWorktreeNotice}
|
|
|
4705
5151
|
}
|
|
4706
5152
|
}
|
|
4707
5153
|
if (resp.type === "retry" /* RETRY */ || resp.type === "model_fallback" /* MODEL_FALLBACK */) {
|
|
5154
|
+
if (resp.type === "model_fallback" /* MODEL_FALLBACK */ || !resp.isContinuation) {
|
|
5155
|
+
if (channelDeliveryResponseBlock) {
|
|
5156
|
+
channelDeliveryResponseBlock.length = channelDeliveryCheckpoint;
|
|
5157
|
+
}
|
|
5158
|
+
}
|
|
4708
5159
|
await finalizeToolCallPreparations(
|
|
4709
5160
|
preparationTracker,
|
|
4710
5161
|
true,
|
|
@@ -4727,6 +5178,11 @@ ${this.pendingWorktreeNotice}
|
|
|
4727
5178
|
await messageDisplay?.finish();
|
|
4728
5179
|
}
|
|
4729
5180
|
}
|
|
5181
|
+
commitChannelDeliveryResponseBlock(
|
|
5182
|
+
channelDeliveryCapture,
|
|
5183
|
+
channelDeliveryResponseBlock,
|
|
5184
|
+
functionCalls.length > 0
|
|
5185
|
+
);
|
|
4730
5186
|
if (usageMetadata) {
|
|
4731
5187
|
this.#recordPromptTokenCount(usageMetadata);
|
|
4732
5188
|
if (this.messageRewriter) {
|
|
@@ -4763,18 +5219,23 @@ ${this.pendingWorktreeNotice}
|
|
|
4763
5219
|
}
|
|
4764
5220
|
}
|
|
4765
5221
|
}
|
|
5222
|
+
let stopReason = "end_turn";
|
|
4766
5223
|
if (this.todoStopGuard.needsStopInspection) {
|
|
4767
5224
|
const guardStop = await this.#handleStopHookLoop(
|
|
4768
5225
|
ac,
|
|
4769
5226
|
promptId,
|
|
4770
5227
|
false,
|
|
4771
5228
|
void 0,
|
|
4772
|
-
false
|
|
5229
|
+
false,
|
|
5230
|
+
void 0,
|
|
5231
|
+
channelDeliveryCapture
|
|
4773
5232
|
);
|
|
5233
|
+
stopReason = guardStop.stopReason;
|
|
4774
5234
|
if (guardStop.stopReason === "max_tokens") {
|
|
4775
5235
|
this.#stopCronAfterTokenLimit();
|
|
4776
5236
|
}
|
|
4777
5237
|
}
|
|
5238
|
+
cronCompleted = stopReason === "end_turn" && !ac.signal.aborted;
|
|
4778
5239
|
} catch (error) {
|
|
4779
5240
|
if (ac.signal.aborted) {
|
|
4780
5241
|
this.todoStopGuard.suspend();
|
|
@@ -4802,6 +5263,19 @@ ${this.pendingWorktreeNotice}
|
|
|
4802
5263
|
},
|
|
4803
5264
|
() => ac.signal.aborted ? "cancelled" : cronHadError ? "error" : "ok"
|
|
4804
5265
|
);
|
|
5266
|
+
if (cronCompleted && item.delivery && item.taskId && item.firedAt !== void 0) {
|
|
5267
|
+
this.#scheduleChannelDelivery({
|
|
5268
|
+
sessionId: this.sessionId,
|
|
5269
|
+
deliveryId: `${item.taskId}:${item.firedAt}`,
|
|
5270
|
+
source: "scheduled",
|
|
5271
|
+
target: item.delivery.target,
|
|
5272
|
+
text: normalizeChannelDeliveryText(
|
|
5273
|
+
channelDeliveryCapture?.finalText ?? ""
|
|
5274
|
+
),
|
|
5275
|
+
taskId: item.taskId,
|
|
5276
|
+
firedAt: item.firedAt
|
|
5277
|
+
});
|
|
5278
|
+
}
|
|
4805
5279
|
}
|
|
4806
5280
|
);
|
|
4807
5281
|
}
|
|
@@ -4907,12 +5381,26 @@ ${this.pendingWorktreeNotice}
|
|
|
4907
5381
|
}
|
|
4908
5382
|
async #drainNotificationQueue() {
|
|
4909
5383
|
if (this.disposed) return;
|
|
5384
|
+
if (this.closing) return;
|
|
4910
5385
|
if (this.notificationProcessing) return;
|
|
4911
5386
|
if (this.pendingPrompt || this.cronProcessing || this.cronAbortController) {
|
|
4912
5387
|
return;
|
|
4913
5388
|
}
|
|
5389
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4914
5390
|
if (this.notificationQueue.length === 0) return;
|
|
4915
5391
|
if (this.#nextNotificationQueueIndex() < 0) return;
|
|
5392
|
+
try {
|
|
5393
|
+
await this.assertCanStartTurn();
|
|
5394
|
+
} catch (error) {
|
|
5395
|
+
debugLogger6.warn(
|
|
5396
|
+
`Notification turn rejected [session ${this.sessionId}]: ${error instanceof Error ? error.message : String(error)}`
|
|
5397
|
+
);
|
|
5398
|
+
return;
|
|
5399
|
+
}
|
|
5400
|
+
if (this.disposed || this.closing || this.notificationProcessing || this.pendingPrompt || this.cronProcessing || this.cronAbortController || this.#nextNotificationQueueIndex() < 0) {
|
|
5401
|
+
return;
|
|
5402
|
+
}
|
|
5403
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4916
5404
|
this.notificationProcessing = true;
|
|
4917
5405
|
let resolveCompletion;
|
|
4918
5406
|
this.notificationCompletion = new Promise((resolve5) => {
|
|
@@ -4927,9 +5415,12 @@ ${this.pendingWorktreeNotice}
|
|
|
4927
5415
|
if (nextIndex < 0) break;
|
|
4928
5416
|
const [item] = this.notificationQueue.splice(nextIndex, 1);
|
|
4929
5417
|
if (!item) break;
|
|
4930
|
-
await
|
|
4931
|
-
|
|
4932
|
-
() =>
|
|
5418
|
+
await runWithInvocationContext(
|
|
5419
|
+
void 0,
|
|
5420
|
+
() => sessionIdContext.run(
|
|
5421
|
+
this.config.getSessionId(),
|
|
5422
|
+
() => this.#executeBackgroundNotificationPromptInner(item)
|
|
5423
|
+
)
|
|
4933
5424
|
);
|
|
4934
5425
|
}
|
|
4935
5426
|
} finally {
|
|
@@ -4962,6 +5453,8 @@ ${this.pendingWorktreeNotice}
|
|
|
4962
5453
|
);
|
|
4963
5454
|
const promptId = this.config.getSessionId() + "########notification" + Date.now();
|
|
4964
5455
|
try {
|
|
5456
|
+
await this.assertCanStartTurn();
|
|
5457
|
+
if (ac.signal.aborted) return;
|
|
4965
5458
|
await this.#emitBackgroundNotificationDisplay(item);
|
|
4966
5459
|
const notificationParts = [{ text: item.modelText }];
|
|
4967
5460
|
this.config.getChatRecordingService()?.recordNotification(notificationParts, item.displayText);
|
|
@@ -5091,7 +5584,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5091
5584
|
if (toolRun.stopAfterPermissionCancel) {
|
|
5092
5585
|
this.todoStopGuard.suspend();
|
|
5093
5586
|
await this.#preserveStoppedToolRun(toolRun, ac.signal);
|
|
5094
|
-
await this.#emitBackgroundNotificationEndTurn(
|
|
5587
|
+
await this.#emitBackgroundNotificationEndTurn(
|
|
5588
|
+
getAbortAwareEndTurnStopReason(ac.signal)
|
|
5589
|
+
);
|
|
5095
5590
|
return;
|
|
5096
5591
|
}
|
|
5097
5592
|
const nextAfterTools = await this.#buildNextMessageAfterToolRun(
|
|
@@ -5102,7 +5597,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5102
5597
|
if (toolRun.loopDetected) {
|
|
5103
5598
|
this.todoStopGuard.suspend();
|
|
5104
5599
|
await this.#preserveStoppedToolRun(toolRun, ac.signal);
|
|
5105
|
-
await this.#emitBackgroundNotificationEndTurn(
|
|
5600
|
+
await this.#emitBackgroundNotificationEndTurn(
|
|
5601
|
+
getAbortAwareEndTurnStopReason(ac.signal)
|
|
5602
|
+
);
|
|
5106
5603
|
return;
|
|
5107
5604
|
}
|
|
5108
5605
|
}
|
|
@@ -5120,7 +5617,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5120
5617
|
false
|
|
5121
5618
|
)).stopReason;
|
|
5122
5619
|
}
|
|
5123
|
-
await this.#emitBackgroundNotificationEndTurn(
|
|
5620
|
+
await this.#emitBackgroundNotificationEndTurn(
|
|
5621
|
+
ac.signal.aborted ? "cancelled" : stopReason
|
|
5622
|
+
);
|
|
5124
5623
|
} catch (error) {
|
|
5125
5624
|
if (ac.signal.aborted) {
|
|
5126
5625
|
this.todoStopGuard.suspend();
|
|
@@ -5413,8 +5912,46 @@ ${this.pendingWorktreeNotice}
|
|
|
5413
5912
|
*/
|
|
5414
5913
|
async runToolCalls(abortSignal, promptId, functionCalls, toolLoopState) {
|
|
5415
5914
|
const dedupedFunctionCalls = dedupeToolCallsById(functionCalls);
|
|
5915
|
+
const generatedCallIdBase = randomUUID();
|
|
5916
|
+
const executionCallIds = new Map(
|
|
5917
|
+
dedupedFunctionCalls.map((functionCall, index) => [
|
|
5918
|
+
functionCall,
|
|
5919
|
+
functionCall.id ?? `${functionCall.name ?? "tool"}-${generatedCallIdBase}-${index}`
|
|
5920
|
+
])
|
|
5921
|
+
);
|
|
5922
|
+
const pendingToolResultRecords = [];
|
|
5923
|
+
let toolResultRecordSequence = 0;
|
|
5924
|
+
const queueToolResultRecord = /* @__PURE__ */ __name((fc, record) => {
|
|
5925
|
+
pendingToolResultRecords.push({
|
|
5926
|
+
...record,
|
|
5927
|
+
ordinal: dedupedFunctionCalls.indexOf(fc),
|
|
5928
|
+
sequence: toolResultRecordSequence++
|
|
5929
|
+
});
|
|
5930
|
+
}, "queueToolResultRecord");
|
|
5931
|
+
const finalizeRunToolResult = /* @__PURE__ */ __name(async (result) => {
|
|
5932
|
+
if (pendingToolResultRecords.length === 0) return result;
|
|
5933
|
+
const orderedRecords = [...pendingToolResultRecords].sort(
|
|
5934
|
+
(left, right) => left.ordinal - right.ordinal || left.sequence - right.sequence
|
|
5935
|
+
);
|
|
5936
|
+
const finalized = await finalizeToolResponses(
|
|
5937
|
+
this.config,
|
|
5938
|
+
orderedRecords.map((record) => ({
|
|
5939
|
+
callId: record.callId,
|
|
5940
|
+
toolName: record.toolName,
|
|
5941
|
+
responseParts: record.responseParts,
|
|
5942
|
+
persistedOutputFiles: record.persistedOutputFiles
|
|
5943
|
+
}))
|
|
5944
|
+
);
|
|
5945
|
+
orderedRecords.forEach((record, index) => {
|
|
5946
|
+
this.config.getChatRecordingService()?.recordToolResult(finalized[index].responseParts, record.metadata);
|
|
5947
|
+
});
|
|
5948
|
+
return {
|
|
5949
|
+
...result,
|
|
5950
|
+
parts: finalized.flatMap((entry) => entry.responseParts)
|
|
5951
|
+
};
|
|
5952
|
+
}, "finalizeRunToolResult");
|
|
5416
5953
|
let skippedToolCallCounter = 0;
|
|
5417
|
-
const recordSkippedToolCall = /* @__PURE__ */ __name(async (fc, message = PERMISSION_CANCEL_SKIP_MESSAGE, emitStart = true) => {
|
|
5954
|
+
const recordSkippedToolCall = /* @__PURE__ */ __name(async (fc, message = PERMISSION_CANCEL_SKIP_MESSAGE, emitStart = true, errorType) => {
|
|
5418
5955
|
const toolName = fc.name ?? "unknown_tool";
|
|
5419
5956
|
const callId = fc.id ?? `${toolName}-skip-${++skippedToolCallCounter}`;
|
|
5420
5957
|
const part = {
|
|
@@ -5426,12 +5963,17 @@ ${this.pendingWorktreeNotice}
|
|
|
5426
5963
|
};
|
|
5427
5964
|
const error = new Error(message);
|
|
5428
5965
|
try {
|
|
5429
|
-
|
|
5966
|
+
queueToolResultRecord(fc, {
|
|
5430
5967
|
callId,
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5968
|
+
toolName,
|
|
5969
|
+
responseParts: [part],
|
|
5970
|
+
metadata: {
|
|
5971
|
+
callId,
|
|
5972
|
+
status: "error",
|
|
5973
|
+
resultDisplay: void 0,
|
|
5974
|
+
error,
|
|
5975
|
+
errorType
|
|
5976
|
+
}
|
|
5435
5977
|
});
|
|
5436
5978
|
if (emitStart) {
|
|
5437
5979
|
await this.toolCallEmitter.emitStart({
|
|
@@ -5453,7 +5995,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5453
5995
|
toolLoopState,
|
|
5454
5996
|
dedupedFunctionCalls.length
|
|
5455
5997
|
)) {
|
|
5456
|
-
return {
|
|
5998
|
+
return await finalizeRunToolResult({
|
|
5457
5999
|
parts: await Promise.all(
|
|
5458
6000
|
dedupedFunctionCalls.map(
|
|
5459
6001
|
(fc) => recordSkippedToolCall(fc, LOOP_DETECTED_SKIP_MESSAGE, false)
|
|
@@ -5461,7 +6003,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5461
6003
|
),
|
|
5462
6004
|
stopAfterPermissionCancel: false,
|
|
5463
6005
|
loopDetected: true
|
|
5464
|
-
};
|
|
6006
|
+
});
|
|
5465
6007
|
}
|
|
5466
6008
|
const batches = [];
|
|
5467
6009
|
const handledProviderToolCallIds = new Set(
|
|
@@ -5478,13 +6020,13 @@ ${this.pendingWorktreeNotice}
|
|
|
5478
6020
|
debugLogger6.debug(
|
|
5479
6021
|
`[Session.runToolCalls] Dropping batch after repeated duplicate provider tool-call id: ${providerCallId} (tool: ${repeatedDuplicateCall.name ?? "unknown_tool"})`
|
|
5480
6022
|
);
|
|
5481
|
-
return {
|
|
6023
|
+
return await finalizeRunToolResult({
|
|
5482
6024
|
parts: [],
|
|
5483
6025
|
stopAfterPermissionCancel: false,
|
|
5484
6026
|
repeatedDuplicateProviderToolCall: true
|
|
5485
|
-
};
|
|
6027
|
+
});
|
|
5486
6028
|
}
|
|
5487
|
-
const pushDuplicateBatch = /* @__PURE__ */ __name((request) => {
|
|
6029
|
+
const pushDuplicateBatch = /* @__PURE__ */ __name((fc, request) => {
|
|
5488
6030
|
const providerCallId = request.providerCallId ?? request.callId;
|
|
5489
6031
|
markDuplicateProviderToolCallResponseSent(
|
|
5490
6032
|
providerCallId,
|
|
@@ -5494,7 +6036,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5494
6036
|
debugLogger6.debug(
|
|
5495
6037
|
`[Session.runToolCalls] Suppressing duplicate provider tool-call id: ${providerCallId} (tool: ${request.name})`
|
|
5496
6038
|
);
|
|
5497
|
-
batches.push({ kind: "duplicate", request, response });
|
|
6039
|
+
batches.push({ kind: "duplicate", fc, request, response });
|
|
5498
6040
|
}, "pushDuplicateBatch");
|
|
5499
6041
|
const emitDuplicateBatch = /* @__PURE__ */ __name(async (batch) => {
|
|
5500
6042
|
const { request, response } = batch;
|
|
@@ -5531,20 +6073,26 @@ ${this.pendingWorktreeNotice}
|
|
|
5531
6073
|
success: false
|
|
5532
6074
|
});
|
|
5533
6075
|
}
|
|
5534
|
-
|
|
6076
|
+
queueToolResultRecord(batch.fc, {
|
|
5535
6077
|
callId: response.callId,
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
6078
|
+
toolName: request.name,
|
|
6079
|
+
responseParts: response.responseParts,
|
|
6080
|
+
persistedOutputFiles: response.persistedOutputFiles,
|
|
6081
|
+
metadata: {
|
|
6082
|
+
callId: response.callId,
|
|
6083
|
+
status: "error",
|
|
6084
|
+
resultDisplay: response.resultDisplay,
|
|
6085
|
+
error: response.error,
|
|
6086
|
+
errorType: response.errorType
|
|
6087
|
+
}
|
|
5540
6088
|
});
|
|
5541
6089
|
}, "emitDuplicateBatch");
|
|
5542
6090
|
for (const fc of dedupedFunctionCalls) {
|
|
5543
6091
|
const providerCallId = getProviderToolCallId(fc) ?? fc.id;
|
|
5544
6092
|
if (providerCallId) {
|
|
5545
6093
|
if (handledProviderToolCallIds.has(providerCallId)) {
|
|
5546
|
-
const callId =
|
|
5547
|
-
pushDuplicateBatch({
|
|
6094
|
+
const callId = executionCallIds.get(fc);
|
|
6095
|
+
pushDuplicateBatch(fc, {
|
|
5548
6096
|
callId,
|
|
5549
6097
|
providerCallId,
|
|
5550
6098
|
name: fc.name ?? "unknown_tool",
|
|
@@ -5564,6 +6112,13 @@ ${this.pendingWorktreeNotice}
|
|
|
5564
6112
|
batches.push({ kind: "execute", concurrent: isAgent, calls: [fc] });
|
|
5565
6113
|
}
|
|
5566
6114
|
}
|
|
6115
|
+
const executableCalls = batches.flatMap(
|
|
6116
|
+
(batch) => batch.kind === "execute" ? batch.calls : []
|
|
6117
|
+
);
|
|
6118
|
+
const planModeEntryBoundaryIndex = findPlanModeEntryBatchBoundaryIndex(
|
|
6119
|
+
executableCalls.map((call) => call.name)
|
|
6120
|
+
);
|
|
6121
|
+
const planModeEntryBoundary = planModeEntryBoundaryIndex === void 0 ? void 0 : executableCalls[planModeEntryBoundaryIndex];
|
|
5567
6122
|
const appendSkippedAfter = /* @__PURE__ */ __name(async (parts2, fc, message = PERMISSION_CANCEL_SKIP_MESSAGE) => {
|
|
5568
6123
|
const startIndex = dedupedFunctionCalls.indexOf(fc) + 1;
|
|
5569
6124
|
for (const remainingCall of dedupedFunctionCalls.slice(startIndex)) {
|
|
@@ -5630,7 +6185,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5630
6185
|
calls[i],
|
|
5631
6186
|
onStopAfterPermissionCancel,
|
|
5632
6187
|
toolLoopState,
|
|
5633
|
-
recordSkippedToolCall
|
|
6188
|
+
recordSkippedToolCall,
|
|
6189
|
+
queueToolResultRecord,
|
|
6190
|
+
executionCallIds.get(calls[i])
|
|
5634
6191
|
);
|
|
5635
6192
|
results[i] = r;
|
|
5636
6193
|
if (r.loopDetected) {
|
|
@@ -5662,7 +6219,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5662
6219
|
calls[idx],
|
|
5663
6220
|
onStopAfterPermissionCancel,
|
|
5664
6221
|
toolLoopState,
|
|
5665
|
-
recordSkippedToolCall
|
|
6222
|
+
recordSkippedToolCall,
|
|
6223
|
+
queueToolResultRecord,
|
|
6224
|
+
executionCallIds.get(calls[idx])
|
|
5666
6225
|
).then((r) => {
|
|
5667
6226
|
results[idx] = r;
|
|
5668
6227
|
}).finally(() => {
|
|
@@ -5701,6 +6260,19 @@ ${this.pendingWorktreeNotice}
|
|
|
5701
6260
|
parts.push(...batch.response.responseParts);
|
|
5702
6261
|
continue;
|
|
5703
6262
|
}
|
|
6263
|
+
if (planModeEntryBoundary && !batch.calls.includes(planModeEntryBoundary)) {
|
|
6264
|
+
for (const fc of batch.calls) {
|
|
6265
|
+
parts.push(
|
|
6266
|
+
await recordSkippedToolCall(
|
|
6267
|
+
fc,
|
|
6268
|
+
PLAN_MODE_ENTRY_SIBLING_SKIP_MESSAGE,
|
|
6269
|
+
true,
|
|
6270
|
+
"execution_denied" /* EXECUTION_DENIED */
|
|
6271
|
+
)
|
|
6272
|
+
);
|
|
6273
|
+
}
|
|
6274
|
+
continue;
|
|
6275
|
+
}
|
|
5704
6276
|
if (batch.concurrent && batch.calls.length > 1) {
|
|
5705
6277
|
const batchAbortController = new AbortController();
|
|
5706
6278
|
let batchStopAfterPermissionCancel = false;
|
|
@@ -5744,24 +6316,24 @@ ${this.pendingWorktreeNotice}
|
|
|
5744
6316
|
batch.calls[batch.calls.length - 1],
|
|
5745
6317
|
LOOP_DETECTED_SKIP_MESSAGE
|
|
5746
6318
|
);
|
|
5747
|
-
return {
|
|
6319
|
+
return await finalizeRunToolResult({
|
|
5748
6320
|
parts,
|
|
5749
6321
|
stopAfterPermissionCancel: false,
|
|
5750
6322
|
loopDetected: true,
|
|
5751
6323
|
memoryWriteCandidates
|
|
5752
|
-
};
|
|
6324
|
+
});
|
|
5753
6325
|
}
|
|
5754
6326
|
if (shouldStop) {
|
|
5755
6327
|
await appendSkippedAfter(
|
|
5756
6328
|
parts,
|
|
5757
6329
|
batch.calls[batch.calls.length - 1]
|
|
5758
6330
|
);
|
|
5759
|
-
return {
|
|
6331
|
+
return await finalizeRunToolResult({
|
|
5760
6332
|
parts,
|
|
5761
6333
|
stopAfterPermissionCancel: true,
|
|
5762
6334
|
repeatedDuplicateProviderToolCall: false,
|
|
5763
6335
|
memoryWriteCandidates
|
|
5764
|
-
};
|
|
6336
|
+
});
|
|
5765
6337
|
}
|
|
5766
6338
|
} else {
|
|
5767
6339
|
for (const fc of batch.calls) {
|
|
@@ -5771,37 +6343,39 @@ ${this.pendingWorktreeNotice}
|
|
|
5771
6343
|
fc,
|
|
5772
6344
|
void 0,
|
|
5773
6345
|
toolLoopState,
|
|
5774
|
-
recordSkippedToolCall
|
|
6346
|
+
recordSkippedToolCall,
|
|
6347
|
+
queueToolResultRecord,
|
|
6348
|
+
executionCallIds.get(fc)
|
|
5775
6349
|
);
|
|
5776
6350
|
parts.push(...r.parts);
|
|
5777
6351
|
collectMemoryWriteCandidates(r);
|
|
5778
6352
|
if (r.loopDetected) {
|
|
5779
6353
|
await appendSkippedAfter(parts, fc, LOOP_DETECTED_SKIP_MESSAGE);
|
|
5780
|
-
return {
|
|
6354
|
+
return await finalizeRunToolResult({
|
|
5781
6355
|
parts,
|
|
5782
6356
|
stopAfterPermissionCancel: false,
|
|
5783
6357
|
loopDetected: true,
|
|
5784
6358
|
memoryWriteCandidates
|
|
5785
|
-
};
|
|
6359
|
+
});
|
|
5786
6360
|
}
|
|
5787
6361
|
if (r.stopAfterPermissionCancel) {
|
|
5788
6362
|
await appendSkippedAfter(parts, fc);
|
|
5789
|
-
return {
|
|
6363
|
+
return await finalizeRunToolResult({
|
|
5790
6364
|
parts,
|
|
5791
6365
|
stopAfterPermissionCancel: true,
|
|
5792
6366
|
repeatedDuplicateProviderToolCall: false,
|
|
5793
6367
|
memoryWriteCandidates
|
|
5794
|
-
};
|
|
6368
|
+
});
|
|
5795
6369
|
}
|
|
5796
6370
|
}
|
|
5797
6371
|
}
|
|
5798
6372
|
}
|
|
5799
|
-
return {
|
|
6373
|
+
return await finalizeRunToolResult({
|
|
5800
6374
|
parts,
|
|
5801
6375
|
stopAfterPermissionCancel: false,
|
|
5802
6376
|
repeatedDuplicateProviderToolCall: false,
|
|
5803
6377
|
memoryWriteCandidates
|
|
5804
|
-
};
|
|
6378
|
+
});
|
|
5805
6379
|
} finally {
|
|
5806
6380
|
await refreshMemoryIfNeeded();
|
|
5807
6381
|
}
|
|
@@ -5836,8 +6410,8 @@ ${this.pendingWorktreeNotice}
|
|
|
5836
6410
|
}
|
|
5837
6411
|
return reminders;
|
|
5838
6412
|
}
|
|
5839
|
-
async runTool(abortSignal, promptId, fc, onStopAfterPermissionCancel, toolLoopState, recordSkippedToolCall) {
|
|
5840
|
-
const callId = fc.id ?? `${fc.name}-${Date.now()}`;
|
|
6413
|
+
async runTool(abortSignal, promptId, fc, onStopAfterPermissionCancel, toolLoopState, recordSkippedToolCall, queueToolResultRecord, generatedCallId) {
|
|
6414
|
+
const callId = fc.id ?? generatedCallId ?? `${fc.name}-${Date.now()}`;
|
|
5841
6415
|
let args = fc.args ?? {};
|
|
5842
6416
|
if (toolLoopState?.loopDetected) {
|
|
5843
6417
|
return {
|
|
@@ -5899,12 +6473,17 @@ ${this.pendingWorktreeNotice}
|
|
|
5899
6473
|
await this.toolCallEmitter.emitError(callId, toolName2, error);
|
|
5900
6474
|
}
|
|
5901
6475
|
const errorParts = errorResponse(error);
|
|
5902
|
-
|
|
6476
|
+
queueToolResultRecord?.(fc, {
|
|
5903
6477
|
callId,
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
6478
|
+
toolName: toolName2,
|
|
6479
|
+
responseParts: errorParts,
|
|
6480
|
+
metadata: {
|
|
6481
|
+
callId,
|
|
6482
|
+
status: "error",
|
|
6483
|
+
resultDisplay: void 0,
|
|
6484
|
+
error,
|
|
6485
|
+
errorType: void 0
|
|
6486
|
+
}
|
|
5908
6487
|
});
|
|
5909
6488
|
const loopDetected = opts?.recordInvalidToolParams === true && !activeToolAbortSignal.aborted && !opts?.stopAfterPermissionCancel && recordDaemonInvalidToolParams(
|
|
5910
6489
|
this.config,
|
|
@@ -5934,19 +6513,22 @@ ${this.pendingWorktreeNotice}
|
|
|
5934
6513
|
{ recordInvalidToolParams: true }
|
|
5935
6514
|
);
|
|
5936
6515
|
}
|
|
5937
|
-
const
|
|
6516
|
+
const policyToolName = tool.name;
|
|
6517
|
+
const originalPolicyRequestArgs = policyToolName === ToolNames.SHELL || policyToolName === ToolNames.MONITOR ? structuredClone(args) : args;
|
|
6518
|
+
const toolSpan = startToolSpan(policyToolName, {
|
|
5938
6519
|
"tool.call_id": callId,
|
|
6520
|
+
"gen_ai.tool.call.id": getProviderToolCallId(fc) ?? callId,
|
|
5939
6521
|
// Dual-emit the legacy call_id/tool_name aliases like CoreToolScheduler
|
|
5940
6522
|
// (coreToolScheduler.ts) so pre-Phase-2 dashboards keyed off call_id keep
|
|
5941
6523
|
// matching daemon/ACP tool spans during the migration window.
|
|
5942
6524
|
call_id: callId,
|
|
5943
|
-
tool_name:
|
|
6525
|
+
tool_name: policyToolName
|
|
5944
6526
|
});
|
|
5945
6527
|
let spanSuccess = false;
|
|
5946
6528
|
try {
|
|
5947
6529
|
return await runInToolSpanContext(toolSpan, async () => {
|
|
5948
6530
|
const pm = this.config.getPermissionManager?.();
|
|
5949
|
-
if (pm && !await pm.isToolEnabled(
|
|
6531
|
+
if (pm && !await pm.isToolEnabled(policyToolName)) {
|
|
5950
6532
|
return earlyErrorResponse(
|
|
5951
6533
|
new Error(`Tool "${toolName}" is disabled.`),
|
|
5952
6534
|
toolName
|
|
@@ -5975,7 +6557,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5975
6557
|
}
|
|
5976
6558
|
}
|
|
5977
6559
|
const toolUseId = generateToolUseId();
|
|
5978
|
-
|
|
6560
|
+
let approvalMode = this.config.getApprovalMode();
|
|
5979
6561
|
let toolBuildSucceeded = false;
|
|
5980
6562
|
try {
|
|
5981
6563
|
const invocation = tool.build(args);
|
|
@@ -6000,12 +6582,12 @@ ${this.pendingWorktreeNotice}
|
|
|
6000
6582
|
activeToolAbortSignal
|
|
6001
6583
|
);
|
|
6002
6584
|
}
|
|
6003
|
-
const isAskUserQuestionTool =
|
|
6004
|
-
|
|
6585
|
+
const isAskUserQuestionTool = policyToolName === ToolNames.ASK_USER_QUESTION;
|
|
6586
|
+
let toolParams = invocation.params;
|
|
6005
6587
|
const flowResult = await evaluatePermissionFlow(
|
|
6006
6588
|
this.config,
|
|
6007
6589
|
invocation,
|
|
6008
|
-
|
|
6590
|
+
policyToolName,
|
|
6009
6591
|
toolParams
|
|
6010
6592
|
);
|
|
6011
6593
|
const {
|
|
@@ -6015,31 +6597,75 @@ ${this.pendingWorktreeNotice}
|
|
|
6015
6597
|
denyMessage,
|
|
6016
6598
|
requiresUserInteraction
|
|
6017
6599
|
} = flowResult;
|
|
6600
|
+
approvalMode = this.config.getApprovalMode();
|
|
6018
6601
|
const isPlanMode = approvalMode === "plan" /* PLAN */;
|
|
6602
|
+
const isPlanShellCall = isPlanMode && (policyToolName === ToolNames.SHELL || policyToolName === ToolNames.MONITOR);
|
|
6019
6603
|
if (finalPermission === "deny") {
|
|
6020
6604
|
return earlyErrorResponse(
|
|
6021
6605
|
new Error(denyMessage ?? `Tool "${toolName}" is denied.`),
|
|
6022
6606
|
toolName
|
|
6023
6607
|
);
|
|
6024
6608
|
}
|
|
6025
|
-
|
|
6609
|
+
let planShellAmbientWorkingDirectory;
|
|
6610
|
+
if (isPlanShellCall) {
|
|
6611
|
+
const directory = toolParams["directory"];
|
|
6612
|
+
planShellAmbientWorkingDirectory = typeof directory === "string" && directory.length > 0 ? void 0 : this.config.getTargetDir();
|
|
6613
|
+
invocation.params = {
|
|
6614
|
+
...structuredClone(invocation.params),
|
|
6615
|
+
directory: typeof directory === "string" && directory.length > 0 ? directory : planShellAmbientWorkingDirectory
|
|
6616
|
+
};
|
|
6617
|
+
toolParams = invocation.params;
|
|
6618
|
+
}
|
|
6619
|
+
const planShellDecision = isPlanShellCall ? await evaluatePlanModeShellPolicy({
|
|
6620
|
+
config: this.config,
|
|
6621
|
+
toolName: policyToolName,
|
|
6622
|
+
requestArgs: originalPolicyRequestArgs,
|
|
6623
|
+
invocationParams: toolParams,
|
|
6624
|
+
permissionContext: pmCtx,
|
|
6625
|
+
ambientWorkingDirectory: planShellAmbientWorkingDirectory,
|
|
6626
|
+
signal: activeToolAbortSignal
|
|
6627
|
+
}) : { classification: "not-applicable" };
|
|
6628
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6629
|
+
const initialPlanShellError = await validatePlanModeShellContext({
|
|
6630
|
+
config: this.config,
|
|
6631
|
+
decision: planShellDecision,
|
|
6632
|
+
requestArgs: args,
|
|
6633
|
+
invocationParams: invocation.params,
|
|
6634
|
+
signal: activeToolAbortSignal
|
|
6635
|
+
});
|
|
6636
|
+
if (initialPlanShellError) {
|
|
6637
|
+
return earlyErrorResponse(
|
|
6638
|
+
new Error(initialPlanShellError),
|
|
6639
|
+
toolName
|
|
6640
|
+
);
|
|
6641
|
+
}
|
|
6642
|
+
}
|
|
6643
|
+
if (planShellDecision.classification === "write") {
|
|
6644
|
+
return earlyErrorResponse(
|
|
6645
|
+
new Error(planShellDecision.writeBlockMessage),
|
|
6646
|
+
toolName
|
|
6647
|
+
);
|
|
6648
|
+
}
|
|
6649
|
+
const planShellRequiresConfirmation = planShellDecision.classification === "unknown";
|
|
6650
|
+
const forceAutoReviewForAllow = approvalMode === "auto" /* AUTO */ && (shouldForceAutoModeReviewForAllow(pmCtx, this.config.getCwd()) || shouldClassifyAllShellForAutoMode(policyToolName, this.config));
|
|
6026
6651
|
const confirmationPermission = getEffectivePermissionForConfirmation(
|
|
6027
6652
|
finalPermission,
|
|
6028
6653
|
forceAutoReviewForAllow
|
|
6029
6654
|
);
|
|
6030
6655
|
if (finalPermission === "allow" && forceAutoReviewForAllow) {
|
|
6031
6656
|
debugLogger6.info(
|
|
6032
|
-
`Auto mode: L4 allow overridden by protected-write guard for ${
|
|
6657
|
+
`Auto mode: L4 allow overridden by protected-write guard for ${policyToolName}`
|
|
6033
6658
|
);
|
|
6034
6659
|
}
|
|
6035
|
-
let autoModeAllowed = finalPermission === "allow" && !forceAutoReviewForAllow;
|
|
6660
|
+
let autoModeAllowed = finalPermission === "allow" && !forceAutoReviewForAllow && !planShellRequiresConfirmation;
|
|
6036
6661
|
if (autoModeAllowed && approvalMode === "auto" /* AUTO */) {
|
|
6037
6662
|
this.config.setAutoModeDenialState(
|
|
6038
6663
|
recordAllow(this.config.getAutoModeDenialState())
|
|
6039
6664
|
);
|
|
6040
6665
|
}
|
|
6041
|
-
let
|
|
6042
|
-
|
|
6666
|
+
let wasAutoModeManualFallback = false;
|
|
6667
|
+
let autoModeFallbackMessage;
|
|
6668
|
+
if (!autoModeAllowed && !requiresUserInteraction && shouldRunAutoModeForCall(approvalMode, policyToolName)) {
|
|
6043
6669
|
const denialState = this.config.getAutoModeDenialState();
|
|
6044
6670
|
const fallback = shouldFallback(denialState);
|
|
6045
6671
|
const messages = this.config.getGeminiClient?.()?.getHistoryTail(MAX_TRANSCRIPT_MESSAGES, false) ?? [];
|
|
@@ -6061,7 +6687,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6061
6687
|
this.config,
|
|
6062
6688
|
decision,
|
|
6063
6689
|
outcome,
|
|
6064
|
-
|
|
6690
|
+
policyToolName,
|
|
6065
6691
|
toolParams,
|
|
6066
6692
|
callId,
|
|
6067
6693
|
abortSignal
|
|
@@ -6072,17 +6698,16 @@ ${this.pendingWorktreeNotice}
|
|
|
6072
6698
|
break;
|
|
6073
6699
|
case "blocked":
|
|
6074
6700
|
debugLogger6.warn(
|
|
6075
|
-
`Auto mode blocked (${outcome.reason}): tool=${
|
|
6701
|
+
`Auto mode blocked (${outcome.reason}): tool=${policyToolName}, ` + formatDenialStateLog(denialState)
|
|
6076
6702
|
);
|
|
6077
6703
|
return earlyErrorResponse(
|
|
6078
6704
|
new Error(outcome.errorMessage),
|
|
6079
6705
|
toolName
|
|
6080
6706
|
);
|
|
6081
6707
|
case "fallback":
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
)
|
|
6085
|
-
if (wasAutoModeDenialFallback) {
|
|
6708
|
+
wasAutoModeManualFallback = isDenialFallbackReason(outcome.reason) || outcome.reason === "classifier_unavailable";
|
|
6709
|
+
autoModeFallbackMessage = outcome.message;
|
|
6710
|
+
if (wasAutoModeManualFallback) {
|
|
6086
6711
|
debugLogger6.warn(
|
|
6087
6712
|
`Auto mode fallback to manual approval (${outcome.reason}): ` + formatDenialStateLog(denialState)
|
|
6088
6713
|
);
|
|
@@ -6097,7 +6722,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6097
6722
|
let didRequestPermission = false;
|
|
6098
6723
|
let confirmationDetails;
|
|
6099
6724
|
const recordAutoModeFallbackResolution = /* @__PURE__ */ __name((outcome) => {
|
|
6100
|
-
if (approvalMode === "auto" /* AUTO */ &&
|
|
6725
|
+
if (approvalMode === "auto" /* AUTO */ && wasAutoModeManualFallback && isApproveOutcome(outcome)) {
|
|
6101
6726
|
const before = this.config.getAutoModeDenialState();
|
|
6102
6727
|
const after = recordFallbackApprove(before);
|
|
6103
6728
|
if (after === before) {
|
|
@@ -6113,14 +6738,51 @@ ${this.pendingWorktreeNotice}
|
|
|
6113
6738
|
}
|
|
6114
6739
|
}, "recordAutoModeFallbackResolution");
|
|
6115
6740
|
if (!autoModeAllowed && needsConfirmation(
|
|
6116
|
-
confirmationPermission,
|
|
6741
|
+
planShellRequiresConfirmation ? "ask" : confirmationPermission,
|
|
6117
6742
|
approvalMode,
|
|
6118
|
-
|
|
6743
|
+
policyToolName,
|
|
6119
6744
|
requiresUserInteraction
|
|
6120
6745
|
)) {
|
|
6121
|
-
confirmationDetails = await invocation.getConfirmationDetails(
|
|
6746
|
+
confirmationDetails = await invocation.getConfirmationDetails(
|
|
6747
|
+
activeToolAbortSignal
|
|
6748
|
+
);
|
|
6749
|
+
if (autoModeFallbackMessage) {
|
|
6750
|
+
confirmationDetails = decorateClassifierUnavailableConfirmation(
|
|
6751
|
+
confirmationDetails,
|
|
6752
|
+
autoModeFallbackMessage
|
|
6753
|
+
);
|
|
6754
|
+
}
|
|
6755
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6756
|
+
const preDisplayPlanShellError = await validatePlanModeShellContext({
|
|
6757
|
+
config: this.config,
|
|
6758
|
+
decision: planShellDecision,
|
|
6759
|
+
requestArgs: args,
|
|
6760
|
+
invocationParams: invocation.params,
|
|
6761
|
+
signal: activeToolAbortSignal
|
|
6762
|
+
});
|
|
6763
|
+
if (preDisplayPlanShellError) {
|
|
6764
|
+
return earlyErrorResponse(
|
|
6765
|
+
new Error(preDisplayPlanShellError),
|
|
6766
|
+
toolName
|
|
6767
|
+
);
|
|
6768
|
+
}
|
|
6769
|
+
}
|
|
6770
|
+
try {
|
|
6771
|
+
confirmationDetails = decoratePlanModeShellConfirmation(
|
|
6772
|
+
planShellDecision,
|
|
6773
|
+
confirmationDetails
|
|
6774
|
+
);
|
|
6775
|
+
} catch {
|
|
6776
|
+
if (planShellDecision.classification === "unknown") {
|
|
6777
|
+
return earlyErrorResponse(
|
|
6778
|
+
new Error(planShellDecision.noApprovalMessage),
|
|
6779
|
+
toolName
|
|
6780
|
+
);
|
|
6781
|
+
}
|
|
6782
|
+
throw new Error("Unable to prepare shell confirmation.");
|
|
6783
|
+
}
|
|
6122
6784
|
injectPermissionRulesIfMissing(confirmationDetails, pmCtx);
|
|
6123
|
-
if (isPlanModeBlocked(
|
|
6785
|
+
if (planShellDecision.classification === "not-applicable" && isPlanModeBlocked(
|
|
6124
6786
|
isPlanMode,
|
|
6125
6787
|
isExitPlanModeTool,
|
|
6126
6788
|
isAskUserQuestionTool,
|
|
@@ -6140,23 +6802,50 @@ ${this.pendingWorktreeNotice}
|
|
|
6140
6802
|
if (hooksEnabled && messageBus) {
|
|
6141
6803
|
const hookResult = await firePermissionRequestHook(
|
|
6142
6804
|
messageBus,
|
|
6143
|
-
|
|
6805
|
+
policyToolName,
|
|
6144
6806
|
args,
|
|
6145
|
-
String(approvalMode)
|
|
6807
|
+
String(approvalMode),
|
|
6808
|
+
void 0,
|
|
6809
|
+
activeToolAbortSignal
|
|
6146
6810
|
);
|
|
6147
6811
|
if (hookResult.hasDecision && (!hookResult.shouldAllow || !requiresUserInteraction)) {
|
|
6148
6812
|
hookHandled = true;
|
|
6149
6813
|
if (hookResult.shouldAllow) {
|
|
6150
|
-
if (
|
|
6151
|
-
|
|
6152
|
-
|
|
6814
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6815
|
+
const approval = await validatePlanModeShellApproval({
|
|
6816
|
+
config: this.config,
|
|
6817
|
+
decision: planShellDecision,
|
|
6818
|
+
requestArgs: args,
|
|
6819
|
+
invocationParams: invocation.params,
|
|
6820
|
+
signal: activeToolAbortSignal,
|
|
6821
|
+
outcome: "proceed_once" /* ProceedOnce */,
|
|
6822
|
+
payload: hookResult.updatedInput ? { updatedInput: hookResult.updatedInput } : void 0
|
|
6823
|
+
});
|
|
6824
|
+
await confirmationDetails.onConfirm(
|
|
6825
|
+
approval.outcome,
|
|
6826
|
+
approval.payload
|
|
6827
|
+
);
|
|
6828
|
+
if (approval.outcome === "cancel" /* Cancel */) {
|
|
6829
|
+
return earlyErrorResponse(
|
|
6830
|
+
new Error(
|
|
6831
|
+
approval.payload?.cancelMessage ?? planShellDecision.noApprovalMessage
|
|
6832
|
+
),
|
|
6833
|
+
toolName
|
|
6834
|
+
);
|
|
6835
|
+
}
|
|
6836
|
+
recordAutoModeFallbackResolution(approval.outcome);
|
|
6837
|
+
} else {
|
|
6838
|
+
if (hookResult.updatedInput) {
|
|
6839
|
+
args = hookResult.updatedInput;
|
|
6840
|
+
invocation.params = hookResult.updatedInput;
|
|
6841
|
+
}
|
|
6842
|
+
await confirmationDetails.onConfirm(
|
|
6843
|
+
"proceed_once" /* ProceedOnce */
|
|
6844
|
+
);
|
|
6845
|
+
recordAutoModeFallbackResolution(
|
|
6846
|
+
"proceed_once" /* ProceedOnce */
|
|
6847
|
+
);
|
|
6153
6848
|
}
|
|
6154
|
-
await confirmationDetails.onConfirm(
|
|
6155
|
-
"proceed_once" /* ProceedOnce */
|
|
6156
|
-
);
|
|
6157
|
-
recordAutoModeFallbackResolution(
|
|
6158
|
-
"proceed_once" /* ProceedOnce */
|
|
6159
|
-
);
|
|
6160
6849
|
} else {
|
|
6161
6850
|
return earlyErrorResponse(
|
|
6162
6851
|
new Error(
|
|
@@ -6169,11 +6858,26 @@ ${this.pendingWorktreeNotice}
|
|
|
6169
6858
|
}
|
|
6170
6859
|
if (!requiresUserInteraction && approvalMode === "auto-edit" /* AUTO_EDIT */ && (confirmationDetails.type === "edit" || confirmationDetails.type === "info")) {
|
|
6171
6860
|
} else if (!hookHandled) {
|
|
6861
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6862
|
+
const finalPreDisplayPlanShellError = await validatePlanModeShellContext({
|
|
6863
|
+
config: this.config,
|
|
6864
|
+
decision: planShellDecision,
|
|
6865
|
+
requestArgs: args,
|
|
6866
|
+
invocationParams: invocation.params,
|
|
6867
|
+
signal: activeToolAbortSignal
|
|
6868
|
+
});
|
|
6869
|
+
if (finalPreDisplayPlanShellError) {
|
|
6870
|
+
return earlyErrorResponse(
|
|
6871
|
+
new Error(finalPreDisplayPlanShellError),
|
|
6872
|
+
toolName
|
|
6873
|
+
);
|
|
6874
|
+
}
|
|
6875
|
+
}
|
|
6172
6876
|
didRequestPermission = true;
|
|
6173
6877
|
const content = buildPermissionRequestContent(confirmationDetails);
|
|
6174
6878
|
const mappedKind = this.toolCallEmitter.mapToolKind(
|
|
6175
6879
|
tool.kind,
|
|
6176
|
-
|
|
6880
|
+
policyToolName
|
|
6177
6881
|
);
|
|
6178
6882
|
if (hooksEnabled && messageBus) {
|
|
6179
6883
|
this.fireNotificationHookWithTerminalSequence(
|
|
@@ -6183,9 +6887,16 @@ ${this.pendingWorktreeNotice}
|
|
|
6183
6887
|
"Permission needed"
|
|
6184
6888
|
);
|
|
6185
6889
|
}
|
|
6890
|
+
const permissionOptions = toPermissionOptions(
|
|
6891
|
+
confirmationDetails,
|
|
6892
|
+
pmForcedAsk
|
|
6893
|
+
);
|
|
6894
|
+
const offeredPermissionOptions = permissionOptions.map(
|
|
6895
|
+
(option) => ({ ...option })
|
|
6896
|
+
);
|
|
6186
6897
|
const params = {
|
|
6187
6898
|
sessionId: this.sessionId,
|
|
6188
|
-
options:
|
|
6899
|
+
options: permissionOptions,
|
|
6189
6900
|
toolCall: {
|
|
6190
6901
|
toolCallId: callId,
|
|
6191
6902
|
status: "pending",
|
|
@@ -6204,10 +6915,12 @@ ${this.pendingWorktreeNotice}
|
|
|
6204
6915
|
}
|
|
6205
6916
|
}
|
|
6206
6917
|
};
|
|
6207
|
-
const stopAfterPermissionCancel = /* @__PURE__ */ __name(() => {
|
|
6918
|
+
const stopAfterPermissionCancel = /* @__PURE__ */ __name((message) => {
|
|
6208
6919
|
onStopAfterPermissionCancel?.();
|
|
6209
6920
|
return earlyErrorResponse(
|
|
6210
|
-
new Error(
|
|
6921
|
+
new Error(
|
|
6922
|
+
message ?? `Tool "${toolName}" was canceled by the user.`
|
|
6923
|
+
),
|
|
6211
6924
|
toolName,
|
|
6212
6925
|
{ stopAfterPermissionCancel: true }
|
|
6213
6926
|
);
|
|
@@ -6215,10 +6928,15 @@ ${this.pendingWorktreeNotice}
|
|
|
6215
6928
|
let output;
|
|
6216
6929
|
let outcome;
|
|
6217
6930
|
try {
|
|
6218
|
-
output = await
|
|
6219
|
-
|
|
6931
|
+
output = await requestPermissionWithAbort(
|
|
6932
|
+
this.client,
|
|
6933
|
+
params,
|
|
6934
|
+
activeToolAbortSignal
|
|
6935
|
+
);
|
|
6936
|
+
outcome = resolvePermissionOutcome(
|
|
6937
|
+
output,
|
|
6938
|
+
offeredPermissionOptions
|
|
6220
6939
|
);
|
|
6221
|
-
outcome = output.outcome.outcome === "cancelled" ? "cancel" /* Cancel */ : external_exports.nativeEnum(ToolConfirmationOutcome).parse(output.outcome.optionId);
|
|
6222
6940
|
} catch (error) {
|
|
6223
6941
|
debugLogger6.error(
|
|
6224
6942
|
`Permission request failed for tool ${toolName}:`,
|
|
@@ -6235,7 +6953,9 @@ ${this.pendingWorktreeNotice}
|
|
|
6235
6953
|
);
|
|
6236
6954
|
}
|
|
6237
6955
|
onStopAfterPermissionCancel?.();
|
|
6238
|
-
const permissionFailureMessage = isExitPlanModeTool ? "The host could not present plan-exit approval. Plan mode remains active; use the host mode selector or /plan exit to leave plan mode." : `
|
|
6956
|
+
const permissionFailureMessage = isExitPlanModeTool ? "The host could not present plan-exit approval. Plan mode remains active; use the host mode selector or /plan exit to leave plan mode." : planShellDecision.classification === "unknown" ? `Plan mode could not complete approval for this shell command: ${this.#formatError(
|
|
6957
|
+
error
|
|
6958
|
+
)}. The command was not run; Plan mode remains active.` : `Permission request failed for "${toolName}": ${this.#formatError(
|
|
6239
6959
|
error
|
|
6240
6960
|
)}`;
|
|
6241
6961
|
return earlyErrorResponse(
|
|
@@ -6244,11 +6964,32 @@ ${this.pendingWorktreeNotice}
|
|
|
6244
6964
|
{ stopAfterPermissionCancel: true }
|
|
6245
6965
|
);
|
|
6246
6966
|
}
|
|
6967
|
+
let confirmationPayload = {
|
|
6968
|
+
answers: output.answers
|
|
6969
|
+
};
|
|
6970
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6971
|
+
const approval = await validatePlanModeShellApproval({
|
|
6972
|
+
config: this.config,
|
|
6973
|
+
decision: planShellDecision,
|
|
6974
|
+
requestArgs: args,
|
|
6975
|
+
invocationParams: invocation.params,
|
|
6976
|
+
signal: activeToolAbortSignal,
|
|
6977
|
+
outcome,
|
|
6978
|
+
payload: confirmationPayload
|
|
6979
|
+
});
|
|
6980
|
+
outcome = approval.outcome;
|
|
6981
|
+
confirmationPayload = approval.payload;
|
|
6982
|
+
}
|
|
6983
|
+
const shouldSwitchToDefault = outcome === "proceed_once_and_switch_to_default" /* ProceedOnceAndSwitchToDefault */;
|
|
6984
|
+
if (shouldSwitchToDefault) {
|
|
6985
|
+
outcome = "proceed_once" /* ProceedOnce */;
|
|
6986
|
+
}
|
|
6247
6987
|
recordAutoModeFallbackResolution(outcome);
|
|
6248
6988
|
try {
|
|
6249
|
-
await confirmationDetails.onConfirm(
|
|
6250
|
-
|
|
6251
|
-
|
|
6989
|
+
await confirmationDetails.onConfirm(
|
|
6990
|
+
outcome,
|
|
6991
|
+
confirmationPayload
|
|
6992
|
+
);
|
|
6252
6993
|
} catch (error) {
|
|
6253
6994
|
if (outcome !== "cancel" /* Cancel */) {
|
|
6254
6995
|
throw error;
|
|
@@ -6259,21 +7000,31 @@ ${this.pendingWorktreeNotice}
|
|
|
6259
7000
|
);
|
|
6260
7001
|
return stopAfterPermissionCancel();
|
|
6261
7002
|
}
|
|
7003
|
+
if (shouldSwitchToDefault) {
|
|
7004
|
+
this.config.setApprovalMode("default" /* DEFAULT */);
|
|
7005
|
+
await this.sendCurrentModeUpdateNotification();
|
|
7006
|
+
}
|
|
6262
7007
|
if (outcome === "proceed_always" /* ProceedAlways */ || outcome === "proceed_always_project" /* ProceedAlwaysProject */ || outcome === "proceed_always_user" /* ProceedAlwaysUser */) {
|
|
6263
7008
|
await persistPermissionOutcome(
|
|
6264
7009
|
outcome,
|
|
6265
7010
|
confirmationDetails,
|
|
6266
7011
|
this.config.getOnPersistPermissionRule?.(),
|
|
6267
7012
|
this.config.getPermissionManager?.(),
|
|
6268
|
-
|
|
7013
|
+
confirmationPayload
|
|
6269
7014
|
);
|
|
6270
7015
|
}
|
|
6271
7016
|
if (confirmationDetails.type === "edit" && outcome === "proceed_always" /* ProceedAlways */) {
|
|
6272
7017
|
await this.sendCurrentModeUpdateNotification();
|
|
6273
7018
|
}
|
|
6274
7019
|
switch (outcome) {
|
|
7020
|
+
case "proceed_once_and_switch_to_default" /* ProceedOnceAndSwitchToDefault */:
|
|
7021
|
+
throw new Error(
|
|
7022
|
+
"Switch-to-Default outcome must be normalized before execution."
|
|
7023
|
+
);
|
|
6275
7024
|
case "cancel" /* Cancel */:
|
|
6276
|
-
return stopAfterPermissionCancel(
|
|
7025
|
+
return stopAfterPermissionCancel(
|
|
7026
|
+
confirmationPayload?.cancelMessage
|
|
7027
|
+
);
|
|
6277
7028
|
case "proceed_once" /* ProceedOnce */:
|
|
6278
7029
|
case "proceed_always" /* ProceedAlways */:
|
|
6279
7030
|
case "proceed_always_project" /* ProceedAlwaysProject */:
|
|
@@ -6305,7 +7056,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6305
7056
|
if (hooksEnabledForTool && messageBusForTool) {
|
|
6306
7057
|
const preHookResult = await firePreToolUseHook(
|
|
6307
7058
|
messageBusForTool,
|
|
6308
|
-
|
|
7059
|
+
policyToolName,
|
|
6309
7060
|
args,
|
|
6310
7061
|
toolUseId,
|
|
6311
7062
|
permissionMode,
|
|
@@ -6422,7 +7173,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6422
7173
|
};
|
|
6423
7174
|
const postHookResult = await firePostToolUseHook(
|
|
6424
7175
|
messageBusForTool,
|
|
6425
|
-
|
|
7176
|
+
policyToolName,
|
|
6426
7177
|
args,
|
|
6427
7178
|
toolResponse,
|
|
6428
7179
|
toolUseId,
|
|
@@ -6453,7 +7204,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6453
7204
|
const failureHookResult = await firePostToolUseFailureHook(
|
|
6454
7205
|
messageBusForTool,
|
|
6455
7206
|
toolUseId,
|
|
6456
|
-
|
|
7207
|
+
policyToolName,
|
|
6457
7208
|
args,
|
|
6458
7209
|
toolResult.error?.message ?? "Tool execution was cancelled",
|
|
6459
7210
|
isInterrupt,
|
|
@@ -6507,12 +7258,18 @@ ${this.pendingWorktreeNotice}
|
|
|
6507
7258
|
prompt_id: promptId,
|
|
6508
7259
|
tool_type: typeof tool !== "undefined" && tool instanceof DiscoveredMCPTool ? "mcp" : "native"
|
|
6509
7260
|
});
|
|
6510
|
-
|
|
7261
|
+
queueToolResultRecord?.(fc, {
|
|
6511
7262
|
callId,
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
7263
|
+
toolName,
|
|
7264
|
+
responseParts,
|
|
7265
|
+
persistedOutputFiles: toolResult.persistedOutputFiles,
|
|
7266
|
+
metadata: {
|
|
7267
|
+
callId,
|
|
7268
|
+
status,
|
|
7269
|
+
resultDisplay: toolResult.returnDisplay,
|
|
7270
|
+
error: toolResult.error ? new Error(toolResult.error.message) : void 0,
|
|
7271
|
+
errorType: toolResult.error?.type
|
|
7272
|
+
}
|
|
6516
7273
|
});
|
|
6517
7274
|
spanSuccess = succeeded;
|
|
6518
7275
|
if (toolResult.error) {
|
|
@@ -6542,7 +7299,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6542
7299
|
const failureHookResult = await firePostToolUseFailureHook(
|
|
6543
7300
|
messageBusForError,
|
|
6544
7301
|
toolUseId,
|
|
6545
|
-
|
|
7302
|
+
policyToolName,
|
|
6546
7303
|
args,
|
|
6547
7304
|
error.message,
|
|
6548
7305
|
isInterrupt,
|
|
@@ -6563,24 +7320,6 @@ ${this.pendingWorktreeNotice}
|
|
|
6563
7320
|
});
|
|
6564
7321
|
}
|
|
6565
7322
|
await this.toolCallEmitter.emitError(callId, toolName, error);
|
|
6566
|
-
const errorParts = [
|
|
6567
|
-
{
|
|
6568
|
-
functionResponse: {
|
|
6569
|
-
id: callId,
|
|
6570
|
-
name: toolName,
|
|
6571
|
-
response: { error: error.message }
|
|
6572
|
-
}
|
|
6573
|
-
}
|
|
6574
|
-
];
|
|
6575
|
-
this.config.getChatRecordingService()?.recordToolResult(errorParts, {
|
|
6576
|
-
callId,
|
|
6577
|
-
// A throw caused by abort (e.g. AbortError) is a cancellation, not
|
|
6578
|
-
// a genuine tool error — keep it consistent with the success path.
|
|
6579
|
-
status: activeToolAbortSignal.aborted ? "cancelled" : "error",
|
|
6580
|
-
resultDisplay: void 0,
|
|
6581
|
-
error,
|
|
6582
|
-
errorType: void 0
|
|
6583
|
-
});
|
|
6584
7323
|
const loopDetected = !activeToolAbortSignal.aborted && !toolBuildSucceeded && recordDaemonInvalidToolParams(
|
|
6585
7324
|
this.config,
|
|
6586
7325
|
promptId,
|
|
@@ -6589,6 +7328,18 @@ ${this.pendingWorktreeNotice}
|
|
|
6589
7328
|
error
|
|
6590
7329
|
);
|
|
6591
7330
|
const responseParts = errorResponse(error);
|
|
7331
|
+
queueToolResultRecord?.(fc, {
|
|
7332
|
+
callId,
|
|
7333
|
+
toolName,
|
|
7334
|
+
responseParts,
|
|
7335
|
+
metadata: {
|
|
7336
|
+
callId,
|
|
7337
|
+
status: activeToolAbortSignal.aborted ? "cancelled" : "error",
|
|
7338
|
+
resultDisplay: void 0,
|
|
7339
|
+
error,
|
|
7340
|
+
errorType: void 0
|
|
7341
|
+
}
|
|
7342
|
+
});
|
|
6592
7343
|
return {
|
|
6593
7344
|
parts: responseParts,
|
|
6594
7345
|
stopAfterPermissionCancel: nestedPermissionCancelled,
|
|
@@ -7149,7 +7900,8 @@ function serializeAgentTask(entry, now) {
|
|
|
7149
7900
|
at: a.at
|
|
7150
7901
|
}))
|
|
7151
7902
|
} : {},
|
|
7152
|
-
...optionalField("prompt", entry.prompt)
|
|
7903
|
+
...optionalField("prompt", entry.prompt),
|
|
7904
|
+
...optionalField("toolUseId", entry.toolUseId)
|
|
7153
7905
|
};
|
|
7154
7906
|
}
|
|
7155
7907
|
__name(serializeAgentTask, "serializeAgentTask");
|
|
@@ -7225,6 +7977,7 @@ var QWEN_ACP_LOCAL_READ_ROOTS_ENV = "QWEN_ACP_LOCAL_READ_ROOTS";
|
|
|
7225
7977
|
var POSIX_TMP_LOCAL_READ_ROOT = "/tmp";
|
|
7226
7978
|
var BTW_CHILD_TIMEOUT_MS = 55e3;
|
|
7227
7979
|
var MCP_OAUTH_START_TIMEOUT_MS = 3e4;
|
|
7980
|
+
var SESSION_DRAIN_TIMEOUT_MS = 3e4;
|
|
7228
7981
|
var WORKSPACE_MEMORY_REMEMBER_CHILD_TIMEOUT_MS = 295e3;
|
|
7229
7982
|
function createAcpSessionStartProfiler(span) {
|
|
7230
7983
|
let failedStage;
|
|
@@ -7283,6 +8036,77 @@ function workspaceMemoryErrorData(code, diagnostics) {
|
|
|
7283
8036
|
};
|
|
7284
8037
|
}
|
|
7285
8038
|
__name(workspaceMemoryErrorData, "workspaceMemoryErrorData");
|
|
8039
|
+
var SESSION_WRITER_MESSAGES = {
|
|
8040
|
+
session_writer_conflict: "This session is already open in another Qwen process.",
|
|
8041
|
+
session_writer_lost: "Write ownership for this session was lost.",
|
|
8042
|
+
session_transcript_changed: "The session transcript changed outside its active writer.",
|
|
8043
|
+
session_writer_unavailable: "Session write ownership could not be verified."
|
|
8044
|
+
};
|
|
8045
|
+
function getSessionWriterError(error) {
|
|
8046
|
+
if (!error || typeof error !== "object") return void 0;
|
|
8047
|
+
const candidate = error;
|
|
8048
|
+
const errorKind = candidate["errorKind"];
|
|
8049
|
+
if (typeof errorKind !== "string" || !(errorKind in SESSION_WRITER_RPC_CODES)) {
|
|
8050
|
+
return void 0;
|
|
8051
|
+
}
|
|
8052
|
+
const typedKind = errorKind;
|
|
8053
|
+
if (candidate["rpcCode"] !== SESSION_WRITER_RPC_CODES[typedKind]) {
|
|
8054
|
+
return void 0;
|
|
8055
|
+
}
|
|
8056
|
+
return {
|
|
8057
|
+
rpcCode: SESSION_WRITER_RPC_CODES[typedKind],
|
|
8058
|
+
errorKind: typedKind,
|
|
8059
|
+
message: SESSION_WRITER_MESSAGES[typedKind]
|
|
8060
|
+
};
|
|
8061
|
+
}
|
|
8062
|
+
__name(getSessionWriterError, "getSessionWriterError");
|
|
8063
|
+
function mapSessionWriterRequestError(error) {
|
|
8064
|
+
const writerError = getSessionWriterError(error);
|
|
8065
|
+
return writerError ? new RequestError(writerError.rpcCode, writerError.message, {
|
|
8066
|
+
errorKind: writerError.errorKind
|
|
8067
|
+
}) : error;
|
|
8068
|
+
}
|
|
8069
|
+
__name(mapSessionWriterRequestError, "mapSessionWriterRequestError");
|
|
8070
|
+
async function shutdownSessionConfig(config) {
|
|
8071
|
+
await config.shutdown({ shutdownTelemetry: false });
|
|
8072
|
+
if (config.hasSessionWriteOwnership()) {
|
|
8073
|
+
throw new SessionWriterUnavailableError();
|
|
8074
|
+
}
|
|
8075
|
+
}
|
|
8076
|
+
__name(shutdownSessionConfig, "shutdownSessionConfig");
|
|
8077
|
+
async function waitForSessionDrain(operation, timeoutMs, kind) {
|
|
8078
|
+
let timer;
|
|
8079
|
+
const timeout = new Promise((_, reject) => {
|
|
8080
|
+
timer = setTimeout(
|
|
8081
|
+
() => reject(new Error(`Session ${kind} timed out after ${timeoutMs}ms`)),
|
|
8082
|
+
timeoutMs
|
|
8083
|
+
);
|
|
8084
|
+
timer.unref();
|
|
8085
|
+
});
|
|
8086
|
+
try {
|
|
8087
|
+
await Promise.race([operation, timeout]);
|
|
8088
|
+
} finally {
|
|
8089
|
+
if (timer) clearTimeout(timer);
|
|
8090
|
+
}
|
|
8091
|
+
}
|
|
8092
|
+
__name(waitForSessionDrain, "waitForSessionDrain");
|
|
8093
|
+
async function beginSessionCloseAfterCurrentGate(session, timeoutMs) {
|
|
8094
|
+
const deadline = Date.now() + timeoutMs;
|
|
8095
|
+
while (true) {
|
|
8096
|
+
const releaseGate = session.beginCloseIfAvailable();
|
|
8097
|
+
if (releaseGate) return releaseGate;
|
|
8098
|
+
const remainingMs = deadline - Date.now();
|
|
8099
|
+
if (remainingMs <= 0) {
|
|
8100
|
+
throw new Error(`Session close timed out after ${timeoutMs}ms`);
|
|
8101
|
+
}
|
|
8102
|
+
await waitForSessionDrain(
|
|
8103
|
+
session.waitForCloseGateToRelease(),
|
|
8104
|
+
remainingMs,
|
|
8105
|
+
"close"
|
|
8106
|
+
);
|
|
8107
|
+
}
|
|
8108
|
+
}
|
|
8109
|
+
__name(beginSessionCloseAfterCurrentGate, "beginSessionCloseAfterCurrentGate");
|
|
7286
8110
|
var logWorkspaceMemoryExtractionError = createWorkspaceMemoryExtractionErrorLogger(debugLogger7);
|
|
7287
8111
|
function parseAcpLocalReadRootsEnv(raw = process.env[QWEN_ACP_LOCAL_READ_ROOTS_ENV]) {
|
|
7288
8112
|
if (!raw) return [];
|
|
@@ -7300,7 +8124,7 @@ function buildAcpLocalReadRoots(config) {
|
|
|
7300
8124
|
// local read fallback, not read_file's default permission.
|
|
7301
8125
|
config.storage.getProjectTempDir(),
|
|
7302
8126
|
path4.join(config.storage.getProjectDir(), "subagents"),
|
|
7303
|
-
|
|
8127
|
+
path4.join(config.getSessionRuntimeBaseDir(), "tmp"),
|
|
7304
8128
|
getAutoMemoryRoot(config.getTargetDir()),
|
|
7305
8129
|
getUserAutoMemoryRoot(),
|
|
7306
8130
|
...config.storage.getUserSkillsDirs(),
|
|
@@ -8785,7 +9609,9 @@ async function deliverClientMcpMessage(connection, serverName, message, sessionI
|
|
|
8785
9609
|
return payload;
|
|
8786
9610
|
}
|
|
8787
9611
|
__name(deliverClientMcpMessage, "deliverClientMcpMessage");
|
|
8788
|
-
async function runAcpAgent(config, settings, argv) {
|
|
9612
|
+
async function runAcpAgent(config, settings, argv, options) {
|
|
9613
|
+
const privateParentCapability = options === void 0 ? process.env[PRIVATE_ACP_CAPABILITY_ENV] : options.privateParentCapability;
|
|
9614
|
+
delete process.env[PRIVATE_ACP_CAPABILITY_ENV];
|
|
8789
9615
|
let acpConnection;
|
|
8790
9616
|
const bootstrapClientMcpSender = /* @__PURE__ */ __name((serverName, message) => deliverClientMcpMessage(acpConnection, serverName, message), "bootstrapClientMcpSender");
|
|
8791
9617
|
beginAcpBootstrapConfigProfiling();
|
|
@@ -8803,6 +9629,11 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
8803
9629
|
} finally {
|
|
8804
9630
|
endAcpBootstrapConfigProfiling();
|
|
8805
9631
|
}
|
|
9632
|
+
const startupWarnings = typeof config.getWarnings === "function" ? config.getWarnings() : [];
|
|
9633
|
+
for (const warning of startupWarnings) {
|
|
9634
|
+
process.stderr.write(`${warning}
|
|
9635
|
+
`);
|
|
9636
|
+
}
|
|
8806
9637
|
const eventLoopMonitor = startEventLoopLagMonitor({
|
|
8807
9638
|
onNewMaxStall: /* @__PURE__ */ __name((maxMs) => {
|
|
8808
9639
|
console.error(`[perf] acp agent event loop stall: max=${maxMs}ms`);
|
|
@@ -8817,10 +9648,33 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
8817
9648
|
console.log = console.error;
|
|
8818
9649
|
console.info = console.error;
|
|
8819
9650
|
console.debug = console.error;
|
|
8820
|
-
|
|
9651
|
+
let initializeRequestId;
|
|
9652
|
+
const stream = ndJsonStream(stdout, stdin, {
|
|
9653
|
+
onMessageObserved: /* @__PURE__ */ __name(({ direction, message }) => {
|
|
9654
|
+
if (direction === "received" && "id" in message && "method" in message && message.method === "initialize") {
|
|
9655
|
+
initializeRequestId = message.id;
|
|
9656
|
+
return;
|
|
9657
|
+
}
|
|
9658
|
+
if (direction !== "sent" || initializeRequestId === void 0 || !("id" in message) || "method" in message || message.id !== initializeRequestId) {
|
|
9659
|
+
return;
|
|
9660
|
+
}
|
|
9661
|
+
initializeRequestId = void 0;
|
|
9662
|
+
if ("result" in message) {
|
|
9663
|
+
void initializeTelemetry(config).then(() => {
|
|
9664
|
+
registerAcpEventLoopLagGauge(() => eventLoopMonitor.snapshot());
|
|
9665
|
+
});
|
|
9666
|
+
}
|
|
9667
|
+
}, "onMessageObserved")
|
|
9668
|
+
});
|
|
8821
9669
|
connection = new AgentSideConnection((conn) => {
|
|
8822
9670
|
acpConnection = conn;
|
|
8823
|
-
agentInstance = new QwenAgent(
|
|
9671
|
+
agentInstance = new QwenAgent(
|
|
9672
|
+
config,
|
|
9673
|
+
settings,
|
|
9674
|
+
argv,
|
|
9675
|
+
conn,
|
|
9676
|
+
privateParentCapability
|
|
9677
|
+
);
|
|
8824
9678
|
return agentInstance;
|
|
8825
9679
|
}, stream);
|
|
8826
9680
|
markAcpStartup("transportSetupEnd");
|
|
@@ -8828,7 +9682,6 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
8828
9682
|
eventLoopMonitor.dispose();
|
|
8829
9683
|
throw err;
|
|
8830
9684
|
}
|
|
8831
|
-
registerAcpEventLoopLagGauge(() => eventLoopMonitor.snapshot());
|
|
8832
9685
|
const drainPoolBeforeExit = /* @__PURE__ */ __name(async (label) => {
|
|
8833
9686
|
if (!agentInstance) return;
|
|
8834
9687
|
try {
|
|
@@ -8873,7 +9726,7 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
8873
9726
|
debugLogger7.debug("[ACP] Shutdown signal received, closing streams");
|
|
8874
9727
|
try {
|
|
8875
9728
|
await fireSessionEndOnce("other" /* Other */);
|
|
8876
|
-
agentInstance?.disposeSessions();
|
|
9729
|
+
await agentInstance?.disposeSessions();
|
|
8877
9730
|
try {
|
|
8878
9731
|
process.stdin.destroy();
|
|
8879
9732
|
} catch {
|
|
@@ -8900,7 +9753,7 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
8900
9753
|
await connection.closed;
|
|
8901
9754
|
await fireSessionEndOnce("prompt_input_exit" /* PromptInputExit */);
|
|
8902
9755
|
await drainPoolBeforeExit("ide_close");
|
|
8903
|
-
agentInstance?.disposeSessions();
|
|
9756
|
+
await agentInstance?.disposeSessions();
|
|
8904
9757
|
} finally {
|
|
8905
9758
|
process.off("SIGTERM", shutdownHandler);
|
|
8906
9759
|
process.off("SIGINT", shutdownHandler);
|
|
@@ -9017,11 +9870,12 @@ function parseAcpSessionListCursor(value) {
|
|
|
9017
9870
|
}
|
|
9018
9871
|
__name(parseAcpSessionListCursor, "parseAcpSessionListCursor");
|
|
9019
9872
|
var QwenAgent = class {
|
|
9020
|
-
constructor(config, settings, argv, connection) {
|
|
9873
|
+
constructor(config, settings, argv, connection, expectedPrivateParentCapability) {
|
|
9021
9874
|
this.config = config;
|
|
9022
9875
|
this.settings = settings;
|
|
9023
9876
|
this.argv = argv;
|
|
9024
9877
|
this.connection = connection;
|
|
9878
|
+
this.expectedPrivateParentCapability = expectedPrivateParentCapability;
|
|
9025
9879
|
if (process.env["QWEN_SERVE_NO_MCP_POOL"] === "1") {
|
|
9026
9880
|
this.mcpPool = void 0;
|
|
9027
9881
|
this.workspaceMcpBudget = void 0;
|
|
@@ -9052,14 +9906,18 @@ var QwenAgent = class {
|
|
|
9052
9906
|
__name(this, "QwenAgent");
|
|
9053
9907
|
}
|
|
9054
9908
|
sessions = /* @__PURE__ */ new Map();
|
|
9909
|
+
activePromptCalls = /* @__PURE__ */ new Map();
|
|
9055
9910
|
workspaceMcpDiscoveryConfig;
|
|
9056
9911
|
workspaceMcpDiscoveryPromise;
|
|
9057
9912
|
workspaceMcpDiscoveryError;
|
|
9058
9913
|
pendingMcpAuthentications = /* @__PURE__ */ new Map();
|
|
9059
9914
|
mcpAuthenticationResults = /* @__PURE__ */ new Map();
|
|
9060
9915
|
generationControllers = /* @__PURE__ */ new Map();
|
|
9916
|
+
workspaceGenerationControllers = /* @__PURE__ */ new Map();
|
|
9061
9917
|
transcriptReplayConfigCache = /* @__PURE__ */ new Map();
|
|
9918
|
+
pendingConfigCleanup = /* @__PURE__ */ new Map();
|
|
9062
9919
|
clientCapabilities;
|
|
9920
|
+
privateParentState = "uninitialized";
|
|
9063
9921
|
// CPU-usage delta baseline for the daemon's `workspaceResource` extMethod
|
|
9064
9922
|
// (Daemon Status child-resource chart). The daemon polls this at a fixed
|
|
9065
9923
|
// cadence, so successive calls form a clean delta window independent of tool
|
|
@@ -9161,21 +10019,26 @@ var QwenAgent = class {
|
|
|
9161
10019
|
async createWorkspaceMcpDiscoveryConfig(settings) {
|
|
9162
10020
|
if (this.workspaceMcpDiscoveryConfig) return;
|
|
9163
10021
|
const cwd = this.config.getTargetDir();
|
|
9164
|
-
const config = await
|
|
9165
|
-
settings
|
|
9166
|
-
{
|
|
9167
|
-
...this.argv,
|
|
9168
|
-
sessionId: "workspace-mcp-discovery",
|
|
9169
|
-
resume: void 0,
|
|
9170
|
-
continue: false
|
|
9171
|
-
},
|
|
10022
|
+
const config = await this.runWithPinnedRuntimeBaseDir(
|
|
10023
|
+
settings,
|
|
9172
10024
|
cwd,
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
10025
|
+
() => loadCliConfig(
|
|
10026
|
+
settings.merged,
|
|
10027
|
+
{
|
|
10028
|
+
...this.argv,
|
|
10029
|
+
sessionId: "workspace-mcp-discovery",
|
|
10030
|
+
resume: void 0,
|
|
10031
|
+
continue: false,
|
|
10032
|
+
chatRecording: false
|
|
10033
|
+
},
|
|
10034
|
+
cwd,
|
|
10035
|
+
void 0,
|
|
10036
|
+
{
|
|
10037
|
+
userHooks: settings.getUserHooks(),
|
|
10038
|
+
projectHooks: settings.getProjectHooks()
|
|
10039
|
+
},
|
|
10040
|
+
buildDisabledSkillNamesProvider(settings)
|
|
10041
|
+
)
|
|
9179
10042
|
);
|
|
9180
10043
|
config.setMcpTransportPool(this.mcpPool);
|
|
9181
10044
|
try {
|
|
@@ -9215,7 +10078,7 @@ var QwenAgent = class {
|
|
|
9215
10078
|
await this.createWorkspaceMcpDiscoveryConfig(settings);
|
|
9216
10079
|
});
|
|
9217
10080
|
}
|
|
9218
|
-
reloadWorkspaceMcpDiscovery() {
|
|
10081
|
+
reloadWorkspaceMcpDiscovery(options = {}) {
|
|
9219
10082
|
return this.enqueueWorkspaceMcpDiscovery("reload", async () => {
|
|
9220
10083
|
const settings = loadSettings(this.config.getTargetDir());
|
|
9221
10084
|
const discoveryConfig = this.workspaceMcpDiscoveryConfig;
|
|
@@ -9261,8 +10124,62 @@ var QwenAgent = class {
|
|
|
9261
10124
|
"Failed to synchronize MCP settings with live sessions"
|
|
9262
10125
|
);
|
|
9263
10126
|
}
|
|
10127
|
+
if (options.forceReconnectAll === true || options.forceReconnectWhich !== void 0) {
|
|
10128
|
+
await this.forceReconnectWorkspaceMcp(options.forceReconnectWhich);
|
|
10129
|
+
}
|
|
9264
10130
|
});
|
|
9265
10131
|
}
|
|
10132
|
+
async forceReconnectWorkspaceMcp(requestedServerNames) {
|
|
10133
|
+
const serverNames = /* @__PURE__ */ new Set();
|
|
10134
|
+
for (const config of [
|
|
10135
|
+
this.workspaceMcpDiscoveryConfig,
|
|
10136
|
+
this.config,
|
|
10137
|
+
...this.getActiveSessions().map((session) => session.getConfig())
|
|
10138
|
+
]) {
|
|
10139
|
+
for (const name of Object.keys(config?.getMcpServers() ?? {})) {
|
|
10140
|
+
serverNames.add(name);
|
|
10141
|
+
}
|
|
10142
|
+
}
|
|
10143
|
+
const selectedServerNames = requestedServerNames ? [...new Set(requestedServerNames)].filter(
|
|
10144
|
+
(name) => serverNames.has(name)
|
|
10145
|
+
) : [...serverNames];
|
|
10146
|
+
const errors = [];
|
|
10147
|
+
for (const serverName of selectedServerNames) {
|
|
10148
|
+
try {
|
|
10149
|
+
const poolHasEntries = (this.mcpPool?.getSnapshot().byName[serverName]?.entryCount ?? 0) > 0;
|
|
10150
|
+
if (this.mcpPool && poolHasEntries) {
|
|
10151
|
+
const results = await this.mcpPool.restartByName(serverName);
|
|
10152
|
+
const failed = results.find((result) => !result.restarted);
|
|
10153
|
+
if (failed) {
|
|
10154
|
+
throw new Error(
|
|
10155
|
+
`MCP server ${JSON.stringify(serverName)} failed to reconnect: ${failed.reason ?? "unknown error"}`
|
|
10156
|
+
);
|
|
10157
|
+
}
|
|
10158
|
+
await Promise.all(
|
|
10159
|
+
this.getLiveMcpConfigs(serverName).map(async (config) => {
|
|
10160
|
+
const geminiClient = config.getGeminiClient?.();
|
|
10161
|
+
if (geminiClient?.isInitialized?.()) {
|
|
10162
|
+
await geminiClient.setTools?.();
|
|
10163
|
+
}
|
|
10164
|
+
})
|
|
10165
|
+
);
|
|
10166
|
+
} else {
|
|
10167
|
+
await this.reconcileMcpServerAcrossLiveConfigs(
|
|
10168
|
+
serverName,
|
|
10169
|
+
"discover"
|
|
10170
|
+
);
|
|
10171
|
+
}
|
|
10172
|
+
} catch (error) {
|
|
10173
|
+
errors.push(error);
|
|
10174
|
+
}
|
|
10175
|
+
}
|
|
10176
|
+
if (errors.length > 0) {
|
|
10177
|
+
throw new AggregateError(
|
|
10178
|
+
errors,
|
|
10179
|
+
"Failed to force reconnect one or more MCP servers"
|
|
10180
|
+
);
|
|
10181
|
+
}
|
|
10182
|
+
}
|
|
9266
10183
|
/**
|
|
9267
10184
|
* Drain the workspace MCP transport pool. Called on shutdown so all
|
|
9268
10185
|
* pool entries get a coordinated SIGTERM before process.exit. No-op
|
|
@@ -9283,100 +10200,229 @@ var QwenAgent = class {
|
|
|
9283
10200
|
);
|
|
9284
10201
|
}
|
|
9285
10202
|
}
|
|
9286
|
-
async
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
const session = this.sessions.get(sessionId);
|
|
9293
|
-
if (!session) {
|
|
9294
|
-
this.mcpPool?.releaseSession(sessionId);
|
|
9295
|
-
return;
|
|
10203
|
+
async removeStoredSessionEntry(sessionId, session, cleanupErrors = [], options = {}) {
|
|
10204
|
+
if (this.sessions.get(sessionId) !== session) return;
|
|
10205
|
+
try {
|
|
10206
|
+
session.dispose();
|
|
10207
|
+
} catch (error) {
|
|
10208
|
+
cleanupErrors.push(error);
|
|
9296
10209
|
}
|
|
9297
|
-
|
|
9298
|
-
const flushRecording = /* @__PURE__ */ __name(async () => {
|
|
10210
|
+
if (options.shutdownConfig !== false) {
|
|
9299
10211
|
try {
|
|
9300
|
-
await session.getConfig().
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
debugLogger7.debug(
|
|
9304
|
-
`Session ${sessionId} chat recording flush during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
9305
|
-
);
|
|
9306
|
-
return err;
|
|
9307
|
-
}
|
|
9308
|
-
}, "flushRecording");
|
|
9309
|
-
if (requireFlush) {
|
|
9310
|
-
const preCancelFlushError = await flushRecording();
|
|
9311
|
-
if (preCancelFlushError !== void 0) {
|
|
9312
|
-
throw preCancelFlushError;
|
|
10212
|
+
await session.getConfig().shutdown({ shutdownTelemetry: false });
|
|
10213
|
+
} catch (error) {
|
|
10214
|
+
cleanupErrors.push(error);
|
|
9313
10215
|
}
|
|
9314
10216
|
}
|
|
9315
10217
|
try {
|
|
9316
|
-
|
|
9317
|
-
} catch (
|
|
9318
|
-
|
|
9319
|
-
`Session ${sessionId} cancel during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
9320
|
-
);
|
|
10218
|
+
unregisterGoalHook(session.getConfig(), sessionId);
|
|
10219
|
+
} catch (error) {
|
|
10220
|
+
cleanupErrors.push(error);
|
|
9321
10221
|
}
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
10222
|
+
try {
|
|
10223
|
+
this.mcpPool?.releaseSession(sessionId);
|
|
10224
|
+
} catch (error) {
|
|
10225
|
+
cleanupErrors.push(error);
|
|
9325
10226
|
}
|
|
9326
10227
|
try {
|
|
9327
|
-
|
|
9328
|
-
} catch (
|
|
9329
|
-
|
|
9330
|
-
`Session ${sessionId} tool registry stop during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
9331
|
-
);
|
|
10228
|
+
uiTelemetryService.removeSession(sessionId);
|
|
10229
|
+
} catch (error) {
|
|
10230
|
+
cleanupErrors.push(error);
|
|
9332
10231
|
}
|
|
9333
|
-
unregisterGoalHook(session.getConfig(), sessionId);
|
|
9334
|
-
this.mcpPool?.releaseSession(sessionId);
|
|
9335
|
-
uiTelemetryService.removeSession(sessionId);
|
|
9336
10232
|
this.sessions.delete(sessionId);
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
|
|
9340
|
-
|
|
9341
|
-
|
|
9342
|
-
const logCleanupFailure = /* @__PURE__ */ __name((action, err) => {
|
|
9343
|
-
debugLogger7.debug(
|
|
9344
|
-
`Session ${sessionId} ${action} during failed restore cleanup failed: ${err instanceof Error ? err.message : String(err)}`
|
|
10233
|
+
if (cleanupErrors.length > 0) {
|
|
10234
|
+
debugLogger7.warn(
|
|
10235
|
+
`Session ${sessionId} closed after ${cleanupErrors.length} cleanup failure(s): ${cleanupErrors.map(
|
|
10236
|
+
(error) => error instanceof Error ? error.message : String(error)
|
|
10237
|
+
).join("; ")}`
|
|
9345
10238
|
);
|
|
9346
|
-
}
|
|
10239
|
+
}
|
|
10240
|
+
}
|
|
10241
|
+
async withLiveSessionRestore(sessionId, session, operation) {
|
|
10242
|
+
await session.assertCanStartTurn();
|
|
10243
|
+
const config = session.getConfig();
|
|
10244
|
+
const releaseGate = session.beginClose();
|
|
9347
10245
|
try {
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
10246
|
+
await waitForSessionDrain(
|
|
10247
|
+
session.waitForActiveTurnsToSettle(),
|
|
10248
|
+
SESSION_DRAIN_TIMEOUT_MS,
|
|
10249
|
+
"restore"
|
|
10250
|
+
);
|
|
10251
|
+
const recorder = config.getChatRecordingService();
|
|
10252
|
+
const loadAuthoritative = /* @__PURE__ */ __name(() => config.getSessionService().loadSession(sessionId), "loadAuthoritative");
|
|
10253
|
+
const data = recorder ? await recorder.runWithWriteBarrier(loadAuthoritative) : await loadAuthoritative();
|
|
10254
|
+
if (!data) throw new SessionWriterUnavailableError();
|
|
10255
|
+
return await operation(config, data);
|
|
10256
|
+
} catch (error) {
|
|
10257
|
+
throw mapSessionWriterRequestError(error);
|
|
10258
|
+
} finally {
|
|
10259
|
+
releaseGate();
|
|
9351
10260
|
}
|
|
10261
|
+
}
|
|
10262
|
+
async cleanupUnstoredConfig(config) {
|
|
10263
|
+
const sessionId = config.getSessionId();
|
|
10264
|
+
const cleanupKey = this.pendingConfigCleanupKey(
|
|
10265
|
+
config.getSessionRuntimeBaseDir(),
|
|
10266
|
+
sessionId
|
|
10267
|
+
);
|
|
9352
10268
|
try {
|
|
9353
|
-
|
|
9354
|
-
} catch (
|
|
9355
|
-
|
|
10269
|
+
await shutdownSessionConfig(config);
|
|
10270
|
+
} catch (error) {
|
|
10271
|
+
const pending2 = this.pendingConfigCleanup.get(cleanupKey) ?? /* @__PURE__ */ new Set();
|
|
10272
|
+
pending2.add(config);
|
|
10273
|
+
this.pendingConfigCleanup.set(cleanupKey, pending2);
|
|
10274
|
+
throw mapSessionWriterRequestError(error);
|
|
10275
|
+
}
|
|
10276
|
+
const pending = this.pendingConfigCleanup.get(cleanupKey);
|
|
10277
|
+
pending?.delete(config);
|
|
10278
|
+
if (pending?.size === 0) {
|
|
10279
|
+
this.pendingConfigCleanup.delete(cleanupKey);
|
|
9356
10280
|
}
|
|
10281
|
+
}
|
|
10282
|
+
async cleanupAfterRequestFailure(error, cleanup) {
|
|
9357
10283
|
try {
|
|
10284
|
+
await cleanup();
|
|
10285
|
+
} catch (cleanupError) {
|
|
10286
|
+
debugLogger7.warn(
|
|
10287
|
+
`Session cleanup failed while preserving the original request error: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`
|
|
10288
|
+
);
|
|
10289
|
+
}
|
|
10290
|
+
throw error;
|
|
10291
|
+
}
|
|
10292
|
+
pendingConfigCleanupKey(runtimeBaseDir, sessionId) {
|
|
10293
|
+
return `${path4.resolve(runtimeBaseDir)}\0${sessionId}`;
|
|
10294
|
+
}
|
|
10295
|
+
async retryPendingConfigCleanup(runtimeBaseDir, requiredSessionId) {
|
|
10296
|
+
const resolvedRuntimeBaseDir = path4.resolve(runtimeBaseDir);
|
|
10297
|
+
const configs = /* @__PURE__ */ new Set();
|
|
10298
|
+
for (const pending of this.pendingConfigCleanup.values()) {
|
|
10299
|
+
for (const config of pending) {
|
|
10300
|
+
if (path4.resolve(config.getSessionRuntimeBaseDir()) === resolvedRuntimeBaseDir) {
|
|
10301
|
+
configs.add(config);
|
|
10302
|
+
}
|
|
10303
|
+
}
|
|
10304
|
+
}
|
|
10305
|
+
for (const config of configs) {
|
|
10306
|
+
try {
|
|
10307
|
+
await this.cleanupUnstoredConfig(config);
|
|
10308
|
+
} catch (error) {
|
|
10309
|
+
if (config.getSessionId() === requiredSessionId) throw error;
|
|
10310
|
+
debugLogger7.warn(
|
|
10311
|
+
`Deferred Config cleanup retry failed for session ${config.getSessionId()}: ${error instanceof Error ? error.message : String(error)}`
|
|
10312
|
+
);
|
|
10313
|
+
}
|
|
10314
|
+
}
|
|
10315
|
+
}
|
|
10316
|
+
async closeStoredSession(sessionId, opts) {
|
|
10317
|
+
const session = this.sessions.get(sessionId);
|
|
10318
|
+
if (!session) {
|
|
9358
10319
|
this.mcpPool?.releaseSession(sessionId);
|
|
9359
|
-
|
|
9360
|
-
|
|
10320
|
+
return;
|
|
10321
|
+
}
|
|
10322
|
+
const recorder = session.getConfig().getChatRecordingService();
|
|
10323
|
+
const requireFlush = opts?.requireFlush === true;
|
|
10324
|
+
if (requireFlush) {
|
|
10325
|
+
await recorder?.flush();
|
|
10326
|
+
}
|
|
10327
|
+
const drainTimeoutMs = opts?.drainTimeoutMs ?? SESSION_DRAIN_TIMEOUT_MS;
|
|
10328
|
+
const cancelClose = opts?.waitForCloseGate ? await beginSessionCloseAfterCurrentGate(session, drainTimeoutMs) : session.beginClose();
|
|
10329
|
+
for (const [requestId, generation] of this.generationControllers) {
|
|
10330
|
+
if (generation.sessionId !== sessionId) continue;
|
|
10331
|
+
generation.controller.abort();
|
|
10332
|
+
this.generationControllers.delete(requestId);
|
|
9361
10333
|
}
|
|
10334
|
+
let removedFromStore = false;
|
|
9362
10335
|
try {
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
10336
|
+
await waitForSessionDrain(
|
|
10337
|
+
(async () => {
|
|
10338
|
+
try {
|
|
10339
|
+
await session.cancelPendingPrompt();
|
|
10340
|
+
} catch (err) {
|
|
10341
|
+
debugLogger7.debug(
|
|
10342
|
+
`Session ${sessionId} cancel during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
10343
|
+
);
|
|
10344
|
+
}
|
|
10345
|
+
await session.waitForActiveTurnsToSettle();
|
|
10346
|
+
})(),
|
|
10347
|
+
drainTimeoutMs,
|
|
10348
|
+
"close"
|
|
10349
|
+
);
|
|
10350
|
+
recorder?.finalize();
|
|
10351
|
+
let flushError;
|
|
10352
|
+
try {
|
|
10353
|
+
await recorder?.flush();
|
|
10354
|
+
} catch (error) {
|
|
10355
|
+
flushError = error;
|
|
10356
|
+
}
|
|
10357
|
+
if (flushError !== void 0 && requireFlush) {
|
|
10358
|
+
throw flushError;
|
|
10359
|
+
}
|
|
10360
|
+
let closeError;
|
|
10361
|
+
try {
|
|
10362
|
+
await recorder?.close();
|
|
10363
|
+
} catch (error) {
|
|
10364
|
+
closeError = error;
|
|
10365
|
+
}
|
|
10366
|
+
if (recorder?.hasWriteOwnership()) {
|
|
10367
|
+
throw closeError ?? new SessionWriterUnavailableError();
|
|
10368
|
+
}
|
|
10369
|
+
const cleanupErrors = [];
|
|
10370
|
+
if (flushError !== void 0) cleanupErrors.push(flushError);
|
|
10371
|
+
if (closeError !== void 0) cleanupErrors.push(closeError);
|
|
10372
|
+
await this.removeStoredSessionEntry(sessionId, session, cleanupErrors, {
|
|
10373
|
+
shutdownConfig: opts?.shutdownConfig
|
|
10374
|
+
});
|
|
10375
|
+
removedFromStore = true;
|
|
10376
|
+
} finally {
|
|
10377
|
+
if (!removedFromStore) cancelClose();
|
|
9366
10378
|
}
|
|
9367
|
-
this.sessions.delete(sessionId);
|
|
9368
10379
|
}
|
|
9369
|
-
|
|
10380
|
+
async discardStoredSessionIfCurrent(sessionId, session, opts) {
|
|
10381
|
+
if (this.sessions.get(sessionId) !== session) {
|
|
10382
|
+
return;
|
|
10383
|
+
}
|
|
10384
|
+
await this.closeStoredSession(sessionId, opts);
|
|
10385
|
+
}
|
|
10386
|
+
async disposeSessions() {
|
|
9370
10387
|
for (const generation of this.generationControllers.values()) {
|
|
9371
10388
|
generation.controller.abort();
|
|
9372
10389
|
}
|
|
9373
10390
|
this.generationControllers.clear();
|
|
9374
|
-
for (const
|
|
9375
|
-
|
|
9376
|
-
}
|
|
9377
|
-
this.
|
|
10391
|
+
for (const controller of this.workspaceGenerationControllers.values()) {
|
|
10392
|
+
controller.abort();
|
|
10393
|
+
}
|
|
10394
|
+
this.workspaceGenerationControllers.clear();
|
|
10395
|
+
await Promise.allSettled(
|
|
10396
|
+
[...this.sessions.entries()].map(
|
|
10397
|
+
([sessionId, session]) => this.discardStoredSessionIfCurrent(sessionId, session, {
|
|
10398
|
+
waitForCloseGate: true
|
|
10399
|
+
})
|
|
10400
|
+
)
|
|
10401
|
+
);
|
|
10402
|
+
await Promise.allSettled(
|
|
10403
|
+
[...this.pendingConfigCleanup.values()].flatMap((configs) => [...configs]).map((config) => this.cleanupUnstoredConfig(config))
|
|
10404
|
+
);
|
|
9378
10405
|
this.disposeTranscriptReplayConfigs();
|
|
9379
10406
|
}
|
|
10407
|
+
runWithPinnedRuntimeBaseDir(settings, cwd, operation) {
|
|
10408
|
+
return runWithAcpRuntimeOutputDir(settings, cwd, operation);
|
|
10409
|
+
}
|
|
10410
|
+
async assertLiveSessionScope(config, settings, cwd) {
|
|
10411
|
+
if (path4.resolve(config.storage.getProjectRoot()) !== path4.resolve(cwd)) {
|
|
10412
|
+
throw RequestError.invalidParams(
|
|
10413
|
+
void 0,
|
|
10414
|
+
"The live session belongs to another workspace."
|
|
10415
|
+
);
|
|
10416
|
+
}
|
|
10417
|
+
const requestedRuntimeBaseDir = await this.runWithPinnedRuntimeBaseDir(
|
|
10418
|
+
settings,
|
|
10419
|
+
cwd,
|
|
10420
|
+
() => Storage.getRuntimeBaseDir()
|
|
10421
|
+
);
|
|
10422
|
+
if (path4.resolve(config.getSessionRuntimeBaseDir()) !== path4.resolve(requestedRuntimeBaseDir)) {
|
|
10423
|
+
throw mapSessionWriterRequestError(new SessionWriterUnavailableError());
|
|
10424
|
+
}
|
|
10425
|
+
}
|
|
9380
10426
|
/** Expose the pool's workspace-scoped budget controller for snapshot builders. */
|
|
9381
10427
|
getWorkspaceMcpBudget() {
|
|
9382
10428
|
return this.workspaceMcpBudget;
|
|
@@ -9404,9 +10450,34 @@ var QwenAgent = class {
|
|
|
9404
10450
|
}
|
|
9405
10451
|
async initialize(args) {
|
|
9406
10452
|
markAcpStartup("initializeHandlerStart");
|
|
10453
|
+
if (this.privateParentState === "rejected") {
|
|
10454
|
+
throw RequestError.invalidParams(
|
|
10455
|
+
void 0,
|
|
10456
|
+
"Invalid private ACP parent capability"
|
|
10457
|
+
);
|
|
10458
|
+
}
|
|
10459
|
+
if (this.privateParentState === "uninitialized") {
|
|
10460
|
+
const expectedCapability = this.expectedPrivateParentCapability;
|
|
10461
|
+
if (expectedCapability === void 0) {
|
|
10462
|
+
this.privateParentState = "untrusted";
|
|
10463
|
+
} else {
|
|
10464
|
+
const suppliedCapability = args._meta?.[PRIVATE_PARENT_CAPABILITY_META_KEY];
|
|
10465
|
+
const suppliedBuffer = typeof suppliedCapability === "string" ? Buffer.from(suppliedCapability) : void 0;
|
|
10466
|
+
const expectedBuffer = Buffer.from(expectedCapability);
|
|
10467
|
+
if (suppliedBuffer !== void 0 && suppliedBuffer.length === expectedBuffer.length && timingSafeEqual(suppliedBuffer, expectedBuffer)) {
|
|
10468
|
+
this.privateParentState = "trusted";
|
|
10469
|
+
} else {
|
|
10470
|
+
this.privateParentState = "rejected";
|
|
10471
|
+
throw RequestError.invalidParams(
|
|
10472
|
+
void 0,
|
|
10473
|
+
"Invalid private ACP parent capability"
|
|
10474
|
+
);
|
|
10475
|
+
}
|
|
10476
|
+
}
|
|
10477
|
+
}
|
|
9407
10478
|
this.clientCapabilities = args.clientCapabilities;
|
|
9408
10479
|
const authMethods = buildAuthMethods();
|
|
9409
|
-
const version = "0.20.
|
|
10480
|
+
const version = "0.20.1-nightly.20260724.7d17c44a3";
|
|
9410
10481
|
const response = {
|
|
9411
10482
|
protocolVersion: PROTOCOL_VERSION,
|
|
9412
10483
|
agentInfo: {
|
|
@@ -9495,15 +10566,24 @@ var QwenAgent = class {
|
|
|
9495
10566
|
"config_setup",
|
|
9496
10567
|
() => this.newSessionConfig(cwd, mcpServers, settings)
|
|
9497
10568
|
);
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
"
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
10569
|
+
let session;
|
|
10570
|
+
try {
|
|
10571
|
+
await profiler.time("auth", () => this.ensureAuthenticated(config));
|
|
10572
|
+
profiler.timeSync(
|
|
10573
|
+
"file_system_setup",
|
|
10574
|
+
() => this.setupFileSystem(config)
|
|
10575
|
+
);
|
|
10576
|
+
session = await profiler.time(
|
|
10577
|
+
"session_register",
|
|
10578
|
+
() => this.createAndStoreSession(config, settings)
|
|
10579
|
+
);
|
|
10580
|
+
} catch (error) {
|
|
10581
|
+
return this.cleanupAfterRequestFailure(error, async () => {
|
|
10582
|
+
if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
|
|
10583
|
+
await this.cleanupUnstoredConfig(config);
|
|
10584
|
+
}
|
|
10585
|
+
});
|
|
10586
|
+
}
|
|
9507
10587
|
profiler.setSessionId(session.getId());
|
|
9508
10588
|
return profiler.timeSync("response_build", () => ({
|
|
9509
10589
|
sessionId: session.getId(),
|
|
@@ -9517,7 +10597,56 @@ var QwenAgent = class {
|
|
|
9517
10597
|
}
|
|
9518
10598
|
async loadSession(params) {
|
|
9519
10599
|
const settings = loadSettingsCached(params.cwd);
|
|
9520
|
-
const
|
|
10600
|
+
const liveSession = this.sessions.get(params.sessionId);
|
|
10601
|
+
if (liveSession) {
|
|
10602
|
+
const liveConfig = liveSession.getConfig();
|
|
10603
|
+
await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
|
|
10604
|
+
return this.withLiveSessionRestore(
|
|
10605
|
+
params.sessionId,
|
|
10606
|
+
liveSession,
|
|
10607
|
+
async (config2, sessionData2) => {
|
|
10608
|
+
const response2 = {
|
|
10609
|
+
modes: this.buildModesData(config2),
|
|
10610
|
+
models: this.buildAvailableModels(config2),
|
|
10611
|
+
configOptions: this.buildConfigOptions(config2),
|
|
10612
|
+
...sessionData2.artifactSnapshot ? { artifactSnapshot: sessionData2.artifactSnapshot } : {}
|
|
10613
|
+
};
|
|
10614
|
+
const records = sessionData2.conversation.messages;
|
|
10615
|
+
if (records.length === 0) return response2;
|
|
10616
|
+
const bulkReplay2 = isBulkLoadReplayRequest(params);
|
|
10617
|
+
const replayPage = bulkReplay2 ? selectRecentHistoryRecords(records, getLoadReplayPageSize(params)) : { records, hasMore: false };
|
|
10618
|
+
const replay = await collectHistoryReplayUpdates({
|
|
10619
|
+
sessionId: params.sessionId,
|
|
10620
|
+
config: config2,
|
|
10621
|
+
records: replayPage.records,
|
|
10622
|
+
gaps: sessionData2.historyGaps,
|
|
10623
|
+
cumulativeUsage: createReplayCumulativeUsage(),
|
|
10624
|
+
logger: debugLogger7
|
|
10625
|
+
});
|
|
10626
|
+
if (!bulkReplay2) {
|
|
10627
|
+
for (const update of replay.updates) {
|
|
10628
|
+
await liveSession.sendUpdate(update);
|
|
10629
|
+
}
|
|
10630
|
+
if (replay.replayError !== void 0) {
|
|
10631
|
+
throw RequestError.internalError(void 0, replay.replayError);
|
|
10632
|
+
}
|
|
10633
|
+
return response2;
|
|
10634
|
+
}
|
|
10635
|
+
return {
|
|
10636
|
+
...response2,
|
|
10637
|
+
_meta: {
|
|
10638
|
+
[LOAD_REPLAY_META_KEY]: {
|
|
10639
|
+
v: LOAD_REPLAY_VERSION,
|
|
10640
|
+
updates: replay.updates,
|
|
10641
|
+
...replay.replayError !== void 0 ? { partial: true, replayError: replay.replayError } : {},
|
|
10642
|
+
...replayPage.hasMore ? { hasMore: true } : {}
|
|
10643
|
+
}
|
|
10644
|
+
}
|
|
10645
|
+
};
|
|
10646
|
+
}
|
|
10647
|
+
);
|
|
10648
|
+
}
|
|
10649
|
+
const exists = await this.runWithPinnedRuntimeBaseDir(
|
|
9521
10650
|
settings,
|
|
9522
10651
|
params.cwd,
|
|
9523
10652
|
async () => {
|
|
@@ -9540,17 +10669,26 @@ var QwenAgent = class {
|
|
|
9540
10669
|
params.sessionId,
|
|
9541
10670
|
true
|
|
9542
10671
|
);
|
|
9543
|
-
await this.ensureAuthenticated(config);
|
|
9544
|
-
this.setupFileSystem(config);
|
|
9545
10672
|
const sessionData = config.getResumedSessionData();
|
|
9546
10673
|
const bulkReplay = isBulkLoadReplayRequest(params);
|
|
9547
10674
|
const replayPageSize = bulkReplay ? getLoadReplayPageSize(params) : void 0;
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
10675
|
+
let session;
|
|
10676
|
+
try {
|
|
10677
|
+
await this.ensureAuthenticated(config);
|
|
10678
|
+
this.setupFileSystem(config);
|
|
10679
|
+
session = await this.createAndStoreSession(
|
|
10680
|
+
config,
|
|
10681
|
+
settings,
|
|
10682
|
+
sessionData,
|
|
10683
|
+
bulkReplay ? { replayHistory: false, startPostReplayServices: false } : {}
|
|
10684
|
+
);
|
|
10685
|
+
} catch (error) {
|
|
10686
|
+
return this.cleanupAfterRequestFailure(error, async () => {
|
|
10687
|
+
if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
|
|
10688
|
+
await this.cleanupUnstoredConfig(config);
|
|
10689
|
+
}
|
|
10690
|
+
});
|
|
10691
|
+
}
|
|
9554
10692
|
let replayEnvelope;
|
|
9555
10693
|
if (bulkReplay) {
|
|
9556
10694
|
try {
|
|
@@ -9597,11 +10735,25 @@ var QwenAgent = class {
|
|
|
9597
10735
|
session.installRewriter();
|
|
9598
10736
|
session.startCronScheduler();
|
|
9599
10737
|
} catch (err) {
|
|
9600
|
-
this.
|
|
9601
|
-
|
|
10738
|
+
return this.cleanupAfterRequestFailure(err, async () => {
|
|
10739
|
+
try {
|
|
10740
|
+
await this.discardStoredSessionIfCurrent(params.sessionId, session);
|
|
10741
|
+
} catch (cleanupError) {
|
|
10742
|
+
await this.removeStoredSessionEntry(
|
|
10743
|
+
params.sessionId,
|
|
10744
|
+
session,
|
|
10745
|
+
[cleanupError],
|
|
10746
|
+
{
|
|
10747
|
+
shutdownConfig: false
|
|
10748
|
+
}
|
|
10749
|
+
);
|
|
10750
|
+
await this.cleanupUnstoredConfig(config);
|
|
10751
|
+
}
|
|
10752
|
+
});
|
|
9602
10753
|
}
|
|
9603
10754
|
}
|
|
9604
10755
|
await this.#restoreWorktreeOnResume(config, session);
|
|
10756
|
+
await this.#restoreBackgroundAgentsOnResume(config, session);
|
|
9605
10757
|
this.#restoreGoalOnResume(config, session);
|
|
9606
10758
|
const modesData = this.buildModesData(config);
|
|
9607
10759
|
const availableModels = this.buildAvailableModels(config);
|
|
@@ -9624,7 +10776,22 @@ var QwenAgent = class {
|
|
|
9624
10776
|
}
|
|
9625
10777
|
async unstable_resumeSession(params) {
|
|
9626
10778
|
const settings = loadSettingsCached(params.cwd);
|
|
9627
|
-
const
|
|
10779
|
+
const liveSession = this.sessions.get(params.sessionId);
|
|
10780
|
+
if (liveSession) {
|
|
10781
|
+
const liveConfig = liveSession.getConfig();
|
|
10782
|
+
await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
|
|
10783
|
+
return this.withLiveSessionRestore(
|
|
10784
|
+
params.sessionId,
|
|
10785
|
+
liveSession,
|
|
10786
|
+
async (config2, sessionData2) => ({
|
|
10787
|
+
modes: this.buildModesData(config2),
|
|
10788
|
+
models: this.buildAvailableModels(config2),
|
|
10789
|
+
configOptions: this.buildConfigOptions(config2),
|
|
10790
|
+
...sessionData2.artifactSnapshot ? { artifactSnapshot: sessionData2.artifactSnapshot } : {}
|
|
10791
|
+
})
|
|
10792
|
+
);
|
|
10793
|
+
}
|
|
10794
|
+
const exists = await this.runWithPinnedRuntimeBaseDir(
|
|
9628
10795
|
settings,
|
|
9629
10796
|
params.cwd,
|
|
9630
10797
|
async () => {
|
|
@@ -9643,15 +10810,25 @@ var QwenAgent = class {
|
|
|
9643
10810
|
params.sessionId,
|
|
9644
10811
|
true
|
|
9645
10812
|
);
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
config
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
10813
|
+
let session;
|
|
10814
|
+
try {
|
|
10815
|
+
await this.ensureAuthenticated(config);
|
|
10816
|
+
this.setupFileSystem(config);
|
|
10817
|
+
session = await this.createAndStoreSession(
|
|
10818
|
+
config,
|
|
10819
|
+
settings,
|
|
10820
|
+
config.getResumedSessionData(),
|
|
10821
|
+
{ replayHistory: false }
|
|
10822
|
+
);
|
|
10823
|
+
} catch (error) {
|
|
10824
|
+
return this.cleanupAfterRequestFailure(error, async () => {
|
|
10825
|
+
if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
|
|
10826
|
+
await this.cleanupUnstoredConfig(config);
|
|
10827
|
+
}
|
|
10828
|
+
});
|
|
10829
|
+
}
|
|
9654
10830
|
await this.#restoreWorktreeOnResume(config, session);
|
|
10831
|
+
await this.#restoreBackgroundAgentsOnResume(config, session);
|
|
9655
10832
|
this.#restoreGoalOnResume(config, session);
|
|
9656
10833
|
const modesData = this.buildModesData(config);
|
|
9657
10834
|
const availableModels = this.buildAvailableModels(config);
|
|
@@ -9681,6 +10858,10 @@ var QwenAgent = class {
|
|
|
9681
10858
|
debugLogger7.warn(`ACP worktree restore failed: ${error}`);
|
|
9682
10859
|
}
|
|
9683
10860
|
}
|
|
10861
|
+
async #restoreBackgroundAgentsOnResume(config, session) {
|
|
10862
|
+
await config.loadPausedBackgroundAgents(config.getSessionId());
|
|
10863
|
+
session.pendingRecoveredAgentsNotice = config.consumePendingRecoveredAgentsNotice();
|
|
10864
|
+
}
|
|
9684
10865
|
/**
|
|
9685
10866
|
* Re-registers the `/goal` Stop hook when a resumed transcript ends on an
|
|
9686
10867
|
* unsatisfied goal — the daemon counterpart of the TUI's resume restore.
|
|
@@ -9814,7 +10995,50 @@ var QwenAgent = class {
|
|
|
9814
10995
|
if (!session) {
|
|
9815
10996
|
throw new Error(`Session not found: ${params.sessionId}`);
|
|
9816
10997
|
}
|
|
9817
|
-
|
|
10998
|
+
const sanitizedParams = { ...params };
|
|
10999
|
+
const meta = params._meta && typeof params._meta === "object" ? { ...params._meta } : {};
|
|
11000
|
+
const suppliedContext = meta[INVOCATION_CONTEXT_META_KEY];
|
|
11001
|
+
delete meta[INVOCATION_CONTEXT_META_KEY];
|
|
11002
|
+
delete meta[PRIVATE_PARENT_CAPABILITY_META_KEY];
|
|
11003
|
+
if (Object.keys(meta).length > 0) {
|
|
11004
|
+
sanitizedParams._meta = meta;
|
|
11005
|
+
} else {
|
|
11006
|
+
delete sanitizedParams._meta;
|
|
11007
|
+
}
|
|
11008
|
+
const invocationContext = this.privateParentState === "trusted" && suppliedContext !== void 0 ? parseInvocationContext(suppliedContext) : void 0;
|
|
11009
|
+
if (this.privateParentState === "trusted" && suppliedContext !== void 0 && invocationContext === void 0) {
|
|
11010
|
+
throw RequestError.invalidParams(
|
|
11011
|
+
void 0,
|
|
11012
|
+
"Invalid trusted ACP invocation context"
|
|
11013
|
+
);
|
|
11014
|
+
}
|
|
11015
|
+
let settleCall = /* @__PURE__ */ __name(() => {
|
|
11016
|
+
}, "settleCall");
|
|
11017
|
+
const call = {
|
|
11018
|
+
controller: new AbortController(),
|
|
11019
|
+
settled: new Promise((resolve5) => {
|
|
11020
|
+
settleCall = resolve5;
|
|
11021
|
+
})
|
|
11022
|
+
};
|
|
11023
|
+
let calls = this.activePromptCalls.get(params.sessionId);
|
|
11024
|
+
if (!calls) {
|
|
11025
|
+
calls = /* @__PURE__ */ new Set();
|
|
11026
|
+
this.activePromptCalls.set(params.sessionId, calls);
|
|
11027
|
+
}
|
|
11028
|
+
calls.add(call);
|
|
11029
|
+
try {
|
|
11030
|
+
return await session.prompt(
|
|
11031
|
+
sanitizedParams,
|
|
11032
|
+
invocationContext,
|
|
11033
|
+
call.controller.signal
|
|
11034
|
+
);
|
|
11035
|
+
} finally {
|
|
11036
|
+
calls.delete(call);
|
|
11037
|
+
if (calls.size === 0) {
|
|
11038
|
+
this.activePromptCalls.delete(params.sessionId);
|
|
11039
|
+
}
|
|
11040
|
+
settleCall();
|
|
11041
|
+
}
|
|
9818
11042
|
}
|
|
9819
11043
|
async cancel(params) {
|
|
9820
11044
|
const session = this.sessions.get(params.sessionId);
|
|
@@ -11564,10 +12788,48 @@ var QwenAgent = class {
|
|
|
11564
12788
|
};
|
|
11565
12789
|
}
|
|
11566
12790
|
async extMethod(method, params) {
|
|
12791
|
+
try {
|
|
12792
|
+
return await this.extMethodInternal(method, params);
|
|
12793
|
+
} catch (error) {
|
|
12794
|
+
const writerError = getSessionWriterError(error);
|
|
12795
|
+
if (writerError) {
|
|
12796
|
+
throw new RequestError(writerError.rpcCode, writerError.message, {
|
|
12797
|
+
errorKind: writerError.errorKind
|
|
12798
|
+
});
|
|
12799
|
+
}
|
|
12800
|
+
throw error;
|
|
12801
|
+
}
|
|
12802
|
+
}
|
|
12803
|
+
async extMethodInternal(method, params) {
|
|
11567
12804
|
const requestedCwd = typeof params["cwd"] === "string" ? params["cwd"] : void 0;
|
|
11568
12805
|
const cwd = requestedCwd || process.cwd();
|
|
11569
12806
|
const SESSION_ID_RE = /^[0-9a-fA-F-]{32,36}$/;
|
|
11570
12807
|
switch (method) {
|
|
12808
|
+
case PROMPT_CANCEL_METHOD: {
|
|
12809
|
+
const sessionId = params["sessionId"];
|
|
12810
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
12811
|
+
throw RequestError.invalidParams(
|
|
12812
|
+
void 0,
|
|
12813
|
+
"Invalid or missing sessionId"
|
|
12814
|
+
);
|
|
12815
|
+
}
|
|
12816
|
+
const session = this.sessions.get(sessionId);
|
|
12817
|
+
if (!session) {
|
|
12818
|
+
throw RequestError.invalidParams(
|
|
12819
|
+
void 0,
|
|
12820
|
+
`Session not found for id: ${sessionId}`
|
|
12821
|
+
);
|
|
12822
|
+
}
|
|
12823
|
+
const targetedCalls = new Set(
|
|
12824
|
+
this.activePromptCalls.get(sessionId) ?? []
|
|
12825
|
+
);
|
|
12826
|
+
if (targetedCalls.size === 0) {
|
|
12827
|
+
return { cancelled: false };
|
|
12828
|
+
}
|
|
12829
|
+
targetedCalls.forEach((call) => call.controller.abort());
|
|
12830
|
+
await Promise.all(Array.from(targetedCalls, (call) => call.settled));
|
|
12831
|
+
return { cancelled: true };
|
|
12832
|
+
}
|
|
11571
12833
|
case TODO_STOP_GUARD_QUEUE_RELEASE_METHOD: {
|
|
11572
12834
|
const sessionId = params["sessionId"];
|
|
11573
12835
|
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
@@ -11837,6 +13099,25 @@ var QwenAgent = class {
|
|
|
11837
13099
|
"Transcript cursor and record boundary are mutually exclusive"
|
|
11838
13100
|
);
|
|
11839
13101
|
}
|
|
13102
|
+
const rawDirection = params["direction"];
|
|
13103
|
+
if (rawDirection !== void 0 && rawDirection !== "backward") {
|
|
13104
|
+
throw RequestError.invalidParams(
|
|
13105
|
+
void 0,
|
|
13106
|
+
"Invalid transcript direction"
|
|
13107
|
+
);
|
|
13108
|
+
}
|
|
13109
|
+
if (rawCursor !== void 0 && rawDirection !== void 0) {
|
|
13110
|
+
throw RequestError.invalidParams(
|
|
13111
|
+
void 0,
|
|
13112
|
+
"Transcript cursor and direction are mutually exclusive"
|
|
13113
|
+
);
|
|
13114
|
+
}
|
|
13115
|
+
if (rawBeforeRecordId !== void 0 && rawDirection !== void 0) {
|
|
13116
|
+
throw RequestError.invalidParams(
|
|
13117
|
+
void 0,
|
|
13118
|
+
"Transcript record boundary and direction are mutually exclusive"
|
|
13119
|
+
);
|
|
13120
|
+
}
|
|
11840
13121
|
const rawLimit = params["limit"];
|
|
11841
13122
|
if (rawLimit !== void 0 && (!Number.isSafeInteger(rawLimit) || rawLimit < 1 || rawLimit > SESSION_TRANSCRIPT_MAX_LIMIT)) {
|
|
11842
13123
|
throw RequestError.invalidParams(
|
|
@@ -11847,10 +13128,14 @@ var QwenAgent = class {
|
|
|
11847
13128
|
try {
|
|
11848
13129
|
const settings = loadSettingsCached(cwd);
|
|
11849
13130
|
return await runWithAcpRuntimeOutputDir(settings, cwd, async () => {
|
|
13131
|
+
if (rawDirection === "backward") {
|
|
13132
|
+
await this.sessions.get(sessionId)?.getConfig().getChatRecordingService()?.flush();
|
|
13133
|
+
}
|
|
11850
13134
|
const reader = new SessionTranscriptReader(cwd);
|
|
11851
13135
|
const page = await reader.readPage(sessionId, {
|
|
11852
13136
|
...typeof rawCursor === "string" ? { cursor: rawCursor } : {},
|
|
11853
13137
|
...typeof rawBeforeRecordId === "string" ? { beforeRecordId: rawBeforeRecordId } : {},
|
|
13138
|
+
...rawDirection === "backward" ? { direction: rawDirection } : {},
|
|
11854
13139
|
...typeof rawLimit === "number" ? { limit: rawLimit } : {},
|
|
11855
13140
|
maxBytes: SESSION_TRANSCRIPT_MAX_PAGE_BYTES
|
|
11856
13141
|
});
|
|
@@ -12396,8 +13681,34 @@ var QwenAgent = class {
|
|
|
12396
13681
|
}
|
|
12397
13682
|
case SERVE_CONTROL_EXT_METHODS.workspaceMcpInitialize:
|
|
12398
13683
|
return this.initializeWorkspaceMcpDiscovery();
|
|
12399
|
-
case SERVE_CONTROL_EXT_METHODS.workspaceMcpReload:
|
|
12400
|
-
|
|
13684
|
+
case SERVE_CONTROL_EXT_METHODS.workspaceMcpReload: {
|
|
13685
|
+
const forceReconnectAll = params["forceReconnectAll"];
|
|
13686
|
+
const forceReconnectWhich = params["forceReconnectWhich"];
|
|
13687
|
+
if (forceReconnectAll !== void 0 && typeof forceReconnectAll !== "boolean") {
|
|
13688
|
+
throw RequestError.invalidParams(
|
|
13689
|
+
void 0,
|
|
13690
|
+
"forceReconnectAll must be a boolean"
|
|
13691
|
+
);
|
|
13692
|
+
}
|
|
13693
|
+
if (forceReconnectWhich !== void 0 && (!Array.isArray(forceReconnectWhich) || forceReconnectWhich.some(
|
|
13694
|
+
(serverName) => typeof serverName !== "string" || serverName.length === 0
|
|
13695
|
+
))) {
|
|
13696
|
+
throw RequestError.invalidParams(
|
|
13697
|
+
void 0,
|
|
13698
|
+
"forceReconnectWhich must be an array of server names"
|
|
13699
|
+
);
|
|
13700
|
+
}
|
|
13701
|
+
if (forceReconnectAll === true && forceReconnectWhich !== void 0) {
|
|
13702
|
+
throw RequestError.invalidParams(
|
|
13703
|
+
void 0,
|
|
13704
|
+
"forceReconnectAll and forceReconnectWhich cannot be used together"
|
|
13705
|
+
);
|
|
13706
|
+
}
|
|
13707
|
+
return this.reloadWorkspaceMcpDiscovery({
|
|
13708
|
+
forceReconnectAll: forceReconnectAll === true,
|
|
13709
|
+
forceReconnectWhich
|
|
13710
|
+
});
|
|
13711
|
+
}
|
|
12401
13712
|
case SERVE_CONTROL_EXT_METHODS.workspaceMcpManage: {
|
|
12402
13713
|
const serverName = params["serverName"];
|
|
12403
13714
|
const action = params["action"];
|
|
@@ -12649,6 +13960,52 @@ var QwenAgent = class {
|
|
|
12649
13960
|
authUrl
|
|
12650
13961
|
};
|
|
12651
13962
|
}
|
|
13963
|
+
case SERVE_CONTROL_EXT_METHODS.workspaceGenerationStart: {
|
|
13964
|
+
const requestId = params["requestId"];
|
|
13965
|
+
const prompt = params["prompt"];
|
|
13966
|
+
if (typeof requestId !== "string" || requestId.length === 0) {
|
|
13967
|
+
throw RequestError.invalidParams(
|
|
13968
|
+
void 0,
|
|
13969
|
+
"Invalid or missing requestId"
|
|
13970
|
+
);
|
|
13971
|
+
}
|
|
13972
|
+
if (typeof prompt !== "string" || !prompt.trim() || Buffer.byteLength(prompt, "utf8") > GENERATION_MAX_PROMPT_BYTES || params["purpose"] !== "text") {
|
|
13973
|
+
throw RequestError.invalidParams(
|
|
13974
|
+
void 0,
|
|
13975
|
+
"Invalid workspace generation request"
|
|
13976
|
+
);
|
|
13977
|
+
}
|
|
13978
|
+
if (this.workspaceGenerationControllers.has(requestId)) {
|
|
13979
|
+
throw RequestError.invalidParams(
|
|
13980
|
+
void 0,
|
|
13981
|
+
"Duplicate workspace generation requestId"
|
|
13982
|
+
);
|
|
13983
|
+
}
|
|
13984
|
+
const controller = new AbortController();
|
|
13985
|
+
this.workspaceGenerationControllers.set(requestId, controller);
|
|
13986
|
+
const signal = AbortSignal.any([
|
|
13987
|
+
controller.signal,
|
|
13988
|
+
AbortSignal.timeout(GENERATION_TIMEOUT_MS)
|
|
13989
|
+
]);
|
|
13990
|
+
try {
|
|
13991
|
+
const emit = /* @__PURE__ */ __name(async (event) => {
|
|
13992
|
+
await this.connection.extNotification(
|
|
13993
|
+
"qwen/notify/workspace/generation/event",
|
|
13994
|
+
{ v: 1, requestId, event }
|
|
13995
|
+
);
|
|
13996
|
+
}, "emit");
|
|
13997
|
+
const result = await executeGeneration(
|
|
13998
|
+
this.config,
|
|
13999
|
+
requestId,
|
|
14000
|
+
prompt.trim(),
|
|
14001
|
+
signal,
|
|
14002
|
+
emit
|
|
14003
|
+
);
|
|
14004
|
+
return { requestId, ...result };
|
|
14005
|
+
} finally {
|
|
14006
|
+
this.workspaceGenerationControllers.delete(requestId);
|
|
14007
|
+
}
|
|
14008
|
+
}
|
|
12652
14009
|
case SERVE_CONTROL_EXT_METHODS.workspaceAgentGenerate: {
|
|
12653
14010
|
const description = params["description"];
|
|
12654
14011
|
if (typeof description !== "string" || !description.trim() || description.length > 4096) {
|
|
@@ -12663,6 +14020,22 @@ var QwenAgent = class {
|
|
|
12663
14020
|
AbortSignal.timeout(5 * 6e4)
|
|
12664
14021
|
);
|
|
12665
14022
|
}
|
|
14023
|
+
case SERVE_CONTROL_EXT_METHODS.workspaceGenerationCancel: {
|
|
14024
|
+
const requestId = params["requestId"];
|
|
14025
|
+
if (typeof requestId !== "string" || requestId.length === 0) {
|
|
14026
|
+
throw RequestError.invalidParams(
|
|
14027
|
+
void 0,
|
|
14028
|
+
"Invalid or missing requestId"
|
|
14029
|
+
);
|
|
14030
|
+
}
|
|
14031
|
+
const controller = this.workspaceGenerationControllers.get(requestId);
|
|
14032
|
+
const cancelled = controller !== void 0;
|
|
14033
|
+
if (cancelled) {
|
|
14034
|
+
controller.abort();
|
|
14035
|
+
this.workspaceGenerationControllers.delete(requestId);
|
|
14036
|
+
}
|
|
14037
|
+
return { requestId, cancelled };
|
|
14038
|
+
}
|
|
12666
14039
|
case SERVE_CONTROL_EXT_METHODS.sessionArtifactsPersist: {
|
|
12667
14040
|
const sessionId = params["sessionId"];
|
|
12668
14041
|
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
@@ -12704,6 +14077,34 @@ var QwenAgent = class {
|
|
|
12704
14077
|
}
|
|
12705
14078
|
return { sessionId, persisted: true, kind };
|
|
12706
14079
|
}
|
|
14080
|
+
case "qwen/session/recordTextElements": {
|
|
14081
|
+
const sessionId = params["sessionId"];
|
|
14082
|
+
const content = params["content"];
|
|
14083
|
+
const textElements = params["textElements"];
|
|
14084
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
14085
|
+
throw RequestError.invalidParams(
|
|
14086
|
+
void 0,
|
|
14087
|
+
"Invalid or missing sessionId"
|
|
14088
|
+
);
|
|
14089
|
+
}
|
|
14090
|
+
if (typeof content !== "string" || !Array.isArray(textElements)) {
|
|
14091
|
+
throw RequestError.invalidParams(
|
|
14092
|
+
void 0,
|
|
14093
|
+
"Invalid user text elements payload"
|
|
14094
|
+
);
|
|
14095
|
+
}
|
|
14096
|
+
const session = this.sessionOrThrow(sessionId);
|
|
14097
|
+
await session.assertCanStartTurn();
|
|
14098
|
+
const recording = session.getConfig().getChatRecordingService();
|
|
14099
|
+
if (!recording) {
|
|
14100
|
+
throw RequestError.internalError(
|
|
14101
|
+
void 0,
|
|
14102
|
+
"Chat recording service unavailable"
|
|
14103
|
+
);
|
|
14104
|
+
}
|
|
14105
|
+
await recording.recordUserTextElements({ content, textElements });
|
|
14106
|
+
return { sessionId, persisted: true };
|
|
14107
|
+
}
|
|
12707
14108
|
case SERVE_CONTROL_EXT_METHODS.sessionTitle: {
|
|
12708
14109
|
const sessionId = params["sessionId"];
|
|
12709
14110
|
const displayName = params["displayName"];
|
|
@@ -12799,8 +14200,16 @@ var QwenAgent = class {
|
|
|
12799
14200
|
"Invalid or missing sessionId"
|
|
12800
14201
|
);
|
|
12801
14202
|
}
|
|
14203
|
+
const rawDrainTimeoutMs = params["drainTimeoutMs"];
|
|
14204
|
+
if (rawDrainTimeoutMs !== void 0 && (typeof rawDrainTimeoutMs !== "number" || !Number.isSafeInteger(rawDrainTimeoutMs) || rawDrainTimeoutMs < 1 || rawDrainTimeoutMs > 2147483647)) {
|
|
14205
|
+
throw RequestError.invalidParams(
|
|
14206
|
+
void 0,
|
|
14207
|
+
"Invalid session close drain timeout"
|
|
14208
|
+
);
|
|
14209
|
+
}
|
|
12802
14210
|
await this.closeStoredSession(sessionId, {
|
|
12803
|
-
requireFlush: params["requireFlush"] === true
|
|
14211
|
+
requireFlush: params["requireFlush"] === true,
|
|
14212
|
+
...typeof rawDrainTimeoutMs === "number" ? { drainTimeoutMs: rawDrainTimeoutMs } : {}
|
|
12804
14213
|
});
|
|
12805
14214
|
return { sessionId, closed: true };
|
|
12806
14215
|
}
|
|
@@ -12842,6 +14251,21 @@ var QwenAgent = class {
|
|
|
12842
14251
|
});
|
|
12843
14252
|
}
|
|
12844
14253
|
const canonicalPath = await fs2.realpath(targetPath);
|
|
14254
|
+
const allowedRoots = params["allowedRoots"];
|
|
14255
|
+
if (Array.isArray(allowedRoots) && allowedRoots.length > 0) {
|
|
14256
|
+
const contained = allowedRoots.some((root) => {
|
|
14257
|
+
if (typeof root !== "string") return false;
|
|
14258
|
+
const rel = path4.relative(root, canonicalPath);
|
|
14259
|
+
return !rel.startsWith("..") && !path4.isAbsolute(rel);
|
|
14260
|
+
});
|
|
14261
|
+
if (!contained) {
|
|
14262
|
+
throw new RequestError(
|
|
14263
|
+
-32004,
|
|
14264
|
+
`Path outside allowed roots: ${canonicalPath}`,
|
|
14265
|
+
{ errorKind: "containment_violation", path: canonicalPath }
|
|
14266
|
+
);
|
|
14267
|
+
}
|
|
14268
|
+
}
|
|
12845
14269
|
const previousCwd = config.getTargetDir();
|
|
12846
14270
|
if (canonicalPath === previousCwd) {
|
|
12847
14271
|
return { previousCwd, newCwd: canonicalPath, warnings: [] };
|
|
@@ -13723,16 +15147,11 @@ ${outputText}
|
|
|
13723
15147
|
let artifactSnapshot;
|
|
13724
15148
|
let artifactSnapshotUnavailable;
|
|
13725
15149
|
try {
|
|
13726
|
-
|
|
13727
|
-
const
|
|
13728
|
-
|
|
13729
|
-
|
|
13730
|
-
|
|
13731
|
-
async () => {
|
|
13732
|
-
const sessionService = new SessionService(cwd2);
|
|
13733
|
-
return sessionService.loadSession(sessionId);
|
|
13734
|
-
}
|
|
13735
|
-
);
|
|
15150
|
+
const config = session.getConfig();
|
|
15151
|
+
const recording = config.getChatRecordingService();
|
|
15152
|
+
await recording?.flush();
|
|
15153
|
+
const loadAuthoritative = /* @__PURE__ */ __name(() => config.getSessionService().loadSession(sessionId), "loadAuthoritative");
|
|
15154
|
+
const sessionData = recording ? await recording.runWithWriteBarrier(loadAuthoritative) : await loadAuthoritative();
|
|
13736
15155
|
if (sessionData === void 0) {
|
|
13737
15156
|
artifactSnapshotUnavailable = "session data unavailable after rewind";
|
|
13738
15157
|
} else if (sessionData.artifactSnapshot) {
|
|
@@ -13773,20 +15192,37 @@ ${outputText}
|
|
|
13773
15192
|
"Invalid or missing sessionId"
|
|
13774
15193
|
);
|
|
13775
15194
|
}
|
|
13776
|
-
const
|
|
13777
|
-
|
|
13778
|
-
|
|
13779
|
-
|
|
13780
|
-
|
|
13781
|
-
|
|
13782
|
-
|
|
13783
|
-
|
|
15195
|
+
const liveSession = this.sessions.get(sessionId);
|
|
15196
|
+
let replayConfig = this.config;
|
|
15197
|
+
let sessionData;
|
|
15198
|
+
if (liveSession) {
|
|
15199
|
+
const config = liveSession.getConfig();
|
|
15200
|
+
await this.assertLiveSessionScope(
|
|
15201
|
+
config,
|
|
15202
|
+
loadSettingsCached(cwd),
|
|
15203
|
+
cwd
|
|
15204
|
+
);
|
|
15205
|
+
const recording = config.getChatRecordingService();
|
|
15206
|
+
const loadAuthoritative = /* @__PURE__ */ __name(() => config.getSessionService().loadSession(sessionId), "loadAuthoritative");
|
|
15207
|
+
sessionData = recording ? await recording.runWithWriteBarrier(loadAuthoritative) : await loadAuthoritative();
|
|
15208
|
+
replayConfig = config;
|
|
15209
|
+
} else {
|
|
15210
|
+
const settings = loadSettingsCached(cwd);
|
|
15211
|
+
sessionData = await this.runWithPinnedRuntimeBaseDir(
|
|
15212
|
+
settings,
|
|
15213
|
+
cwd,
|
|
15214
|
+
async () => {
|
|
15215
|
+
const sessionService = new SessionService(cwd);
|
|
15216
|
+
return sessionService.loadSession(sessionId);
|
|
15217
|
+
}
|
|
15218
|
+
);
|
|
15219
|
+
}
|
|
13784
15220
|
if (!sessionData?.conversation) {
|
|
13785
15221
|
return { updates: [] };
|
|
13786
15222
|
}
|
|
13787
15223
|
const replay = await collectHistoryReplayUpdates({
|
|
13788
15224
|
sessionId,
|
|
13789
|
-
config:
|
|
15225
|
+
config: replayConfig,
|
|
13790
15226
|
records: sessionData.conversation.messages,
|
|
13791
15227
|
gaps: sessionData.historyGaps,
|
|
13792
15228
|
cumulativeUsage: createReplayCumulativeUsage(),
|
|
@@ -13854,56 +15290,51 @@ ${outputText}
|
|
|
13854
15290
|
sessionId
|
|
13855
15291
|
});
|
|
13856
15292
|
}
|
|
13857
|
-
const
|
|
15293
|
+
const sourceConfig = sourceSession.getConfig();
|
|
15294
|
+
const recording = sourceConfig.getChatRecordingService();
|
|
13858
15295
|
if (recording) {
|
|
13859
15296
|
await recording.flush();
|
|
13860
15297
|
}
|
|
13861
|
-
const newSessionId =
|
|
13862
|
-
|
|
13863
|
-
|
|
13864
|
-
|
|
13865
|
-
|
|
13866
|
-
|
|
13867
|
-
|
|
13868
|
-
|
|
13869
|
-
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
if (stripped && stripped.length > 0) {
|
|
13877
|
-
baseName = stripped;
|
|
13878
|
-
} else {
|
|
13879
|
-
baseName = sessionId.slice(0, 8);
|
|
13880
|
-
}
|
|
13881
|
-
}
|
|
13882
|
-
title = await computeUniqueBranchTitle(baseName, sessionService);
|
|
13883
|
-
const renamed = await sessionService.renameSession(
|
|
13884
|
-
newSessionId,
|
|
13885
|
-
title,
|
|
13886
|
-
"manual"
|
|
13887
|
-
);
|
|
13888
|
-
if (!renamed) {
|
|
13889
|
-
throw new RequestError(
|
|
13890
|
-
-32603,
|
|
13891
|
-
`Failed to set title on forked session ${newSessionId}`,
|
|
13892
|
-
{ errorKind: "internal", sessionId: newSessionId }
|
|
13893
|
-
);
|
|
13894
|
-
}
|
|
13895
|
-
} catch (err) {
|
|
13896
|
-
sessionService.removeSession(newSessionId).catch((rmErr) => {
|
|
13897
|
-
process.stderr.write(
|
|
13898
|
-
`qwen serve: failed to clean up orphan session ${newSessionId}: ${rmErr instanceof Error ? rmErr.message : rmErr}
|
|
13899
|
-
`
|
|
13900
|
-
);
|
|
13901
|
-
});
|
|
13902
|
-
throw err;
|
|
15298
|
+
const newSessionId = randomUUID2();
|
|
15299
|
+
const sessionService = sourceConfig.getSessionService();
|
|
15300
|
+
await sessionService.forkSession(sessionId, newSessionId);
|
|
15301
|
+
let title;
|
|
15302
|
+
try {
|
|
15303
|
+
let baseName;
|
|
15304
|
+
if (typeof name === "string" && name.trim().length > 0) {
|
|
15305
|
+
baseName = name.trim();
|
|
15306
|
+
} else {
|
|
15307
|
+
const existingTitle = recording?.getCurrentCustomTitle();
|
|
15308
|
+
const stripped = existingTitle?.replace(/\s*\(Branch(?:\s+\d+)?\)\s*$/, "").trim();
|
|
15309
|
+
if (stripped && stripped.length > 0) {
|
|
15310
|
+
baseName = stripped;
|
|
15311
|
+
} else {
|
|
15312
|
+
baseName = sessionId.slice(0, 8);
|
|
13903
15313
|
}
|
|
13904
|
-
return { newSessionId, title, displayName: title };
|
|
13905
15314
|
}
|
|
13906
|
-
|
|
15315
|
+
title = await computeUniqueBranchTitle(baseName, sessionService);
|
|
15316
|
+
const renamed = await sessionService.renameSession(
|
|
15317
|
+
newSessionId,
|
|
15318
|
+
title,
|
|
15319
|
+
"manual"
|
|
15320
|
+
);
|
|
15321
|
+
if (!renamed) {
|
|
15322
|
+
throw new RequestError(
|
|
15323
|
+
-32603,
|
|
15324
|
+
`Failed to set title on forked session ${newSessionId}`,
|
|
15325
|
+
{ errorKind: "internal", sessionId: newSessionId }
|
|
15326
|
+
);
|
|
15327
|
+
}
|
|
15328
|
+
} catch (err) {
|
|
15329
|
+
sessionService.removeSession(newSessionId).catch((rmErr) => {
|
|
15330
|
+
process.stderr.write(
|
|
15331
|
+
`qwen serve: failed to clean up orphan session ${newSessionId}: ${rmErr instanceof Error ? rmErr.message : rmErr}
|
|
15332
|
+
`
|
|
15333
|
+
);
|
|
15334
|
+
});
|
|
15335
|
+
throw err;
|
|
15336
|
+
}
|
|
15337
|
+
return { newSessionId, title, displayName: title };
|
|
13907
15338
|
}
|
|
13908
15339
|
case "qwen/settings/getCore": {
|
|
13909
15340
|
const settings = loadSettings(cwd);
|
|
@@ -14292,17 +15723,25 @@ ${outputText}
|
|
|
14292
15723
|
this.disposeTranscriptReplayConfig(cached.config);
|
|
14293
15724
|
}
|
|
14294
15725
|
const entry = { settings };
|
|
14295
|
-
const pending = this.newSessionConfig(
|
|
14296
|
-
|
|
14297
|
-
|
|
14298
|
-
|
|
14299
|
-
|
|
14300
|
-
|
|
14301
|
-
|
|
14302
|
-
|
|
14303
|
-
|
|
14304
|
-
|
|
14305
|
-
|
|
15726
|
+
const pending = this.newSessionConfig(
|
|
15727
|
+
cwd,
|
|
15728
|
+
[],
|
|
15729
|
+
settings,
|
|
15730
|
+
void 0,
|
|
15731
|
+
false,
|
|
15732
|
+
{
|
|
15733
|
+
skipMcpDiscovery: true,
|
|
15734
|
+
skipHooks: true,
|
|
15735
|
+
skipSkillManager: true,
|
|
15736
|
+
skipFileCheckpointing: true,
|
|
15737
|
+
// Read-only replay: tolerate tools that cannot construct without the
|
|
15738
|
+
// subsystems skipped above (e.g. SkillTool needs the SkillManager). The
|
|
15739
|
+
// registry is only consulted for optional tool_call metadata during
|
|
15740
|
+
// replay, and ToolCallEmitter falls back to the recorded tool name.
|
|
15741
|
+
lenientToolWarmup: true
|
|
15742
|
+
},
|
|
15743
|
+
false
|
|
15744
|
+
);
|
|
14306
15745
|
entry.pending = pending;
|
|
14307
15746
|
this.transcriptReplayConfigCache.set(key, entry);
|
|
14308
15747
|
try {
|
|
@@ -14330,7 +15769,34 @@ ${outputText}
|
|
|
14330
15769
|
throw error;
|
|
14331
15770
|
}
|
|
14332
15771
|
}
|
|
14333
|
-
async newSessionConfig(cwd, mcpServers, settings, sessionId, resume, initializeOptions = {}) {
|
|
15772
|
+
async newSessionConfig(cwd, mcpServers, settings, sessionId, resume, initializeOptions = {}, chatRecording) {
|
|
15773
|
+
try {
|
|
15774
|
+
return await this.runWithPinnedRuntimeBaseDir(settings, cwd, async () => {
|
|
15775
|
+
await this.retryPendingConfigCleanup(
|
|
15776
|
+
Storage.getRuntimeBaseDir(),
|
|
15777
|
+
sessionId
|
|
15778
|
+
);
|
|
15779
|
+
return this.newSessionConfigInRuntimeContext(
|
|
15780
|
+
cwd,
|
|
15781
|
+
mcpServers,
|
|
15782
|
+
settings,
|
|
15783
|
+
sessionId,
|
|
15784
|
+
resume,
|
|
15785
|
+
initializeOptions,
|
|
15786
|
+
chatRecording
|
|
15787
|
+
);
|
|
15788
|
+
});
|
|
15789
|
+
} catch (error) {
|
|
15790
|
+
const writerError = getSessionWriterError(error);
|
|
15791
|
+
if (writerError) {
|
|
15792
|
+
throw new RequestError(writerError.rpcCode, writerError.message, {
|
|
15793
|
+
errorKind: writerError.errorKind
|
|
15794
|
+
});
|
|
15795
|
+
}
|
|
15796
|
+
throw error;
|
|
15797
|
+
}
|
|
15798
|
+
}
|
|
15799
|
+
async newSessionConfigInRuntimeContext(cwd, mcpServers, settings, sessionId, resume, initializeOptions = {}, chatRecording) {
|
|
14334
15800
|
const sessionMcpServers = {};
|
|
14335
15801
|
for (const server of mcpServers) {
|
|
14336
15802
|
const stdioServer = toStdioServer(server);
|
|
@@ -14386,8 +15852,14 @@ ${outputText}
|
|
|
14386
15852
|
const sessionArg = resume === true ? { resume: sessionId, sessionId: void 0 } : { sessionId, resume: void 0 };
|
|
14387
15853
|
const argvForSession = {
|
|
14388
15854
|
...this.argv,
|
|
15855
|
+
// Docker sandbox relaunch injects a fixed --sandbox-session-id into
|
|
15856
|
+
// the ACP process argv. Without clearing it, every newSession()
|
|
15857
|
+
// inherits the same ID and the second session collides with the
|
|
15858
|
+
// first's writer lease (#7435).
|
|
15859
|
+
sandboxSessionId: void 0,
|
|
14389
15860
|
...sessionArg,
|
|
14390
|
-
continue: false
|
|
15861
|
+
continue: false,
|
|
15862
|
+
...chatRecording !== void 0 ? { chatRecording } : {}
|
|
14391
15863
|
};
|
|
14392
15864
|
const config = await loadCliConfig(
|
|
14393
15865
|
mergedSettings,
|
|
@@ -14441,15 +15913,22 @@ ${outputText}
|
|
|
14441
15913
|
});
|
|
14442
15914
|
});
|
|
14443
15915
|
}
|
|
14444
|
-
|
|
14445
|
-
|
|
14446
|
-
|
|
14447
|
-
|
|
14448
|
-
|
|
14449
|
-
|
|
14450
|
-
|
|
14451
|
-
|
|
14452
|
-
|
|
15916
|
+
try {
|
|
15917
|
+
await config.initialize({
|
|
15918
|
+
...initializeOptions,
|
|
15919
|
+
// Reverse tool channel (issue #5626, Phase 2): bind the session
|
|
15920
|
+
// manager's SDK MCP callback to the `client_mcp/message` ext-method so a
|
|
15921
|
+
// client-hosted (extension) MCP server added at runtime reaches the
|
|
15922
|
+
// daemon WS. Servers that aren't client-hosted never use this callback
|
|
15923
|
+
// (the daemon only adds SDK-type runtime servers for client MCP).
|
|
15924
|
+
sendSdkMcpMessage: this.buildClientMcpSender(wiredSessionId)
|
|
15925
|
+
});
|
|
15926
|
+
} catch (error) {
|
|
15927
|
+
return this.cleanupAfterRequestFailure(
|
|
15928
|
+
error,
|
|
15929
|
+
() => this.cleanupUnstoredConfig(config)
|
|
15930
|
+
);
|
|
15931
|
+
}
|
|
14453
15932
|
void this.surfaceMcpFailuresWhenReady(config);
|
|
14454
15933
|
return config;
|
|
14455
15934
|
}
|
|
@@ -14510,34 +15989,52 @@ ${outputText}
|
|
|
14510
15989
|
if (needsInitialize) {
|
|
14511
15990
|
await geminiClient.initialize();
|
|
14512
15991
|
}
|
|
14513
|
-
this.sessions.
|
|
15992
|
+
if (this.sessions.has(sessionId)) {
|
|
15993
|
+
throw new Error(`Session ${sessionId} is already active.`);
|
|
15994
|
+
}
|
|
14514
15995
|
const session = new Session(sessionId, config, this.connection, settings);
|
|
14515
15996
|
this.sessions.set(sessionId, session);
|
|
14516
|
-
|
|
14517
|
-
|
|
14518
|
-
|
|
14519
|
-
|
|
14520
|
-
|
|
14521
|
-
|
|
14522
|
-
|
|
14523
|
-
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
)
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
15997
|
+
try {
|
|
15998
|
+
if (sessionData?.fileHistorySnapshots?.length) {
|
|
15999
|
+
config.getFileHistoryService().restoreFromSnapshots(sessionData.fileHistorySnapshots);
|
|
16000
|
+
}
|
|
16001
|
+
if (sessionData?.conversation.messages) {
|
|
16002
|
+
config.getChatRecordingService()?.rebuildTurnBoundaries(sessionData.conversation.messages);
|
|
16003
|
+
}
|
|
16004
|
+
if (options.replayHistory !== false && sessionData?.conversation.messages) {
|
|
16005
|
+
await session.replayHistory(
|
|
16006
|
+
sessionData.conversation.messages,
|
|
16007
|
+
sessionData.historyGaps
|
|
16008
|
+
);
|
|
16009
|
+
}
|
|
16010
|
+
if (options.startPostReplayServices !== false) {
|
|
16011
|
+
session.installRewriter();
|
|
16012
|
+
session.startCronScheduler();
|
|
16013
|
+
}
|
|
16014
|
+
setTimeout(() => {
|
|
16015
|
+
void session.sendAvailableCommandsUpdate();
|
|
16016
|
+
}, 0);
|
|
16017
|
+
return session;
|
|
16018
|
+
} catch (error) {
|
|
16019
|
+
try {
|
|
16020
|
+
await this.discardStoredSessionIfCurrent(sessionId, session, {
|
|
16021
|
+
shutdownConfig: false
|
|
16022
|
+
});
|
|
16023
|
+
} catch (cleanupError) {
|
|
16024
|
+
await this.removeStoredSessionEntry(
|
|
16025
|
+
sessionId,
|
|
16026
|
+
session,
|
|
16027
|
+
[cleanupError],
|
|
16028
|
+
{ shutdownConfig: false }
|
|
16029
|
+
);
|
|
16030
|
+
}
|
|
16031
|
+
throw error;
|
|
14534
16032
|
}
|
|
14535
|
-
return session;
|
|
14536
16033
|
}
|
|
14537
16034
|
buildAvailableModels(config) {
|
|
14538
16035
|
const rawCurrentModelId = (config.getModel() || this.config.getModel() || "").trim();
|
|
14539
16036
|
const currentAuthType = config.getAuthType();
|
|
14540
|
-
const modelOptions =
|
|
16037
|
+
const modelOptions = this.buildSelectableModelOptions(config);
|
|
14541
16038
|
const activeRuntimeSnapshot = config.getActiveRuntimeModelSnapshot?.();
|
|
14542
16039
|
const currentModelId = getCurrentAcpModelId(
|
|
14543
16040
|
modelOptions,
|
|
@@ -14572,7 +16069,7 @@ ${outputText}
|
|
|
14572
16069
|
}
|
|
14573
16070
|
buildConfigOptions(config) {
|
|
14574
16071
|
const currentApprovalMode = config.getApprovalMode();
|
|
14575
|
-
const modelOptions =
|
|
16072
|
+
const modelOptions = this.buildSelectableModelOptions(config);
|
|
14576
16073
|
const rawCurrentModelId = (config.getModel() || "").trim();
|
|
14577
16074
|
const currentAuthType = config.getAuthType?.();
|
|
14578
16075
|
const activeRuntimeSnapshot = config.getActiveRuntimeModelSnapshot?.();
|
|
@@ -14612,6 +16109,14 @@ ${outputText}
|
|
|
14612
16109
|
};
|
|
14613
16110
|
return [modeConfigOption, modelConfigOption];
|
|
14614
16111
|
}
|
|
16112
|
+
buildSelectableModelOptions(config) {
|
|
16113
|
+
const currentAuthType = config.getAuthType();
|
|
16114
|
+
return buildAcpModelOptions(
|
|
16115
|
+
config.getAllConfiguredModels().filter(
|
|
16116
|
+
(model) => model.authType !== "qwen-oauth" /* QWEN_OAUTH */ || currentAuthType === "qwen-oauth" /* QWEN_OAUTH */
|
|
16117
|
+
)
|
|
16118
|
+
);
|
|
16119
|
+
}
|
|
14615
16120
|
};
|
|
14616
16121
|
function diffSettingsKeys(oldMerged, newMerged) {
|
|
14617
16122
|
const changed = /* @__PURE__ */ new Set();
|