@qwen-code/qwen-code 0.20.1-preview.7215 → 0.20.2-gdpval-vl-agent.0
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 +4 -4
- package/chunks/{MaxSizedBox-EH6G5AEH.js → MaxSizedBox-KYNG7EN7.js} +38 -35
- package/chunks/{StandaloneSessionPicker-264A3TEA.js → StandaloneSessionPicker-7XN4WVVG.js} +55 -52
- package/chunks/{acpAgent-6RBIJFDI.js → acpAgent-FTFFYP5G.js} +1536 -512
- package/chunks/{agent-QURXGAA3.js → agent-Y76LTTOT.js} +34 -31
- package/chunks/{agent-headless-CRGX4ICQ.js → agent-headless-IVAEQPK6.js} +34 -31
- package/chunks/{anthropicContentGenerator-BWBAZGTW.js → anthropicContentGenerator-HGWAHO24.js} +11 -13
- package/chunks/{artifact-tool-IUJ7QWCX.js → artifact-tool-56T5IMBP.js} +3 -3
- package/chunks/{askUserQuestion-IUMUUTDQ.js → askUserQuestion-E25OBIC2.js} +3 -3
- package/chunks/{bridge-MNFVKPMI.js → bridge-4M77KUEV.js} +39 -36
- package/chunks/{build-SSCNEHZZ.js → build-GHIZ4MSZ.js} +1 -1
- package/chunks/{ca-2SL2BXTK.js → ca-N6VVUFVB.js} +611 -201
- package/chunks/{channel-worker-group-53CMOPFT.js → channel-worker-group-QZV2SP5U.js} +4 -4
- package/chunks/{channel-worker-manager-UTXILKC2.js → channel-worker-manager-3GMAU45H.js} +4 -4
- package/chunks/{channel-worker-supervisor-ZGO2W2MD.js → channel-worker-supervisor-QCXSXCRY.js} +3 -3
- package/chunks/{chunk-UQES76OO.js → chunk-2HGTVAOW.js} +6 -6
- package/chunks/{chunk-2HOVDT7W.js → chunk-2LI23QA6.js} +1 -1
- package/chunks/{chunk-ANHT55MR.js → chunk-2P6CNEHB.js} +1 -1
- package/chunks/chunk-2RFKHEXL.js +74 -0
- package/chunks/{chunk-BF32GYSY.js → chunk-3IABAQR6.js} +1 -1
- package/chunks/chunk-3Z43GZUQ.js +32 -0
- package/chunks/chunk-43T5WDQ7.js +127 -0
- package/chunks/{chunk-DA7OOKVN.js → chunk-4CTP6VR6.js} +29 -2
- 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-ZEOZL37W.js → chunk-57FIIFJN.js} +1 -1
- package/chunks/{chunk-7YBZGNEC.js → chunk-5G3ZVADU.js} +308 -199
- package/chunks/{chunk-X4CGDBKA.js → chunk-6GEJX3LE.js} +3 -3
- package/chunks/{chunk-6GUTHAN7.js → chunk-6HOCJNO5.js} +1 -1
- package/chunks/{chunk-GMGDLUC7.js → chunk-6IL7KRLE.js} +1 -1
- package/chunks/chunk-6PVPNMXU.js +29 -0
- package/chunks/{chunk-BDBMYST4.js → chunk-6X4GWOPW.js} +1 -1
- package/chunks/{chunk-4ODB7WIB.js → chunk-6ZBPS62S.js} +1 -1
- package/chunks/{chunk-AYCDXHZB.js → chunk-7Z6JQEL6.js} +1 -1
- package/chunks/{chunk-WAX3ITOA.js → chunk-A3TAEAHX.js} +1 -1
- package/chunks/{chunk-OLMETXLX.js → chunk-ACW3VNUE.js} +2 -2
- package/chunks/{chunk-IB35C3IL.js → chunk-AVQ6EX4J.js} +1 -1
- package/chunks/{chunk-TTSKHF43.js → chunk-BK6UOUJ2.js} +2 -2
- package/chunks/{chunk-6OH6A5EX.js → chunk-BLAEKN6K.js} +20603 -17709
- package/chunks/chunk-BULDBTYC.js +153 -0
- package/chunks/{chunk-XNP57UDV.js → chunk-C3EXYVFX.js} +2 -2
- package/chunks/{chunk-FVS747N7.js → chunk-C54UTDOC.js} +23 -19
- package/chunks/{chunk-MAQQGNQ5.js → chunk-CBOQ3HY7.js} +466 -10
- package/chunks/{chunk-VFAE4AGH.js → chunk-CGZ5SV23.js} +72 -67
- package/chunks/{chunk-WKRXIHD6.js → chunk-COAARUPK.js} +8 -8
- package/chunks/{chunk-GA7VRJVN.js → chunk-E2ZK5M4P.js} +5 -5
- package/chunks/{chunk-5SCI6E3E.js → chunk-E4IMU4Y5.js} +1 -1
- package/chunks/{chunk-E5GIFWE3.js → chunk-EEFRJ5CT.js} +54 -33
- package/chunks/{chunk-WXAXH7IJ.js → chunk-ESQHGKPJ.js} +1 -1
- package/chunks/{chunk-NEEB7UEN.js → chunk-FFFM6NJV.js} +1 -2
- package/chunks/{chunk-Z5R4JMOL.js → chunk-FJ2IUWNQ.js} +4 -4
- package/chunks/{chunk-JVTCARQ6.js → chunk-FQI7LT7T.js} +4 -4
- package/chunks/{chunk-BRXIO5WY.js → chunk-FTNI3D7D.js} +7 -7
- package/chunks/{chunk-OMH3276Y.js → chunk-GHRSKGHF.js} +7 -7
- package/chunks/{chunk-OONJNQ42.js → chunk-GPSKDNEE.js} +3 -3
- package/chunks/{chunk-KPZNOZPC.js → chunk-GWM4PDYK.js} +19 -19
- package/chunks/{chunk-NBMIC7DR.js → chunk-H24SOJIQ.js} +2 -2
- package/chunks/{chunk-FNGK2Z5B.js → chunk-H4AR2JQF.js} +3 -3
- package/chunks/{chunk-WOT64EP2.js → chunk-HCJQORKC.js} +2 -2
- package/chunks/{chunk-7KDI2IB2.js → chunk-HDATOR4J.js} +4 -4
- package/chunks/{chunk-IE4JSQ5L.js → chunk-HIYP7IR4.js} +39 -37
- package/chunks/{chunk-N6YTEVLV.js → chunk-HL6AKUGD.js} +10 -4
- package/chunks/{chunk-BAIEQKR5.js → chunk-HPQFGWOD.js} +5 -5
- package/chunks/chunk-HTR4WV6U.js +327 -0
- package/chunks/{chunk-SDXIH6OA.js → chunk-IFUNDCQ6.js} +137 -5
- package/chunks/{chunk-Z6UEAQTP.js → chunk-IFVECEIK.js} +178 -61
- package/chunks/{chunk-QOK6RMIP.js → chunk-IKP54WUL.js} +4 -4
- package/chunks/{chunk-IUSNI6IX.js → chunk-ISMD2AB3.js} +1 -1
- package/chunks/{chunk-G45X5TRN.js → chunk-JCW2R7WC.js} +1 -72
- package/chunks/{chunk-LZYWWWCZ.js → chunk-KF6CTNTJ.js} +8 -9
- package/chunks/{chunk-EIAK6Q2B.js → chunk-KHOVYUHX.js} +2 -2
- package/chunks/chunk-KWK7UE6L.js +6194 -0
- package/chunks/{chunk-WBTZGWQ6.js → chunk-L5F3T6TQ.js} +1 -1
- package/chunks/{chunk-RELYEO3R.js → chunk-L7ASZD66.js} +244 -1607
- package/chunks/{chunk-UJEZQ562.js → chunk-LESHKUWF.js} +3 -5
- package/chunks/{chunk-OOCI5VVU.js → chunk-LIZRAKPB.js} +1 -1
- package/chunks/{chunk-Q3ZBFXK4.js → chunk-LKB5YL5T.js} +143 -36
- package/chunks/{chunk-MKLKHZAK.js → chunk-LU3RXCM7.js} +1 -1
- package/chunks/{chunk-B453NMZJ.js → chunk-M3EQ3GZC.js} +3 -3
- package/chunks/{chunk-TCKTNY66.js → chunk-M4VFMLQK.js} +6 -6
- package/chunks/{chunk-26LLB6FM.js → chunk-MDZTPSXO.js} +2 -2
- package/chunks/{chunk-4SLLEAQP.js → chunk-MJPBB2GK.js} +591 -316
- package/chunks/chunk-NABLFI57.js +82 -0
- package/chunks/{chunk-T7DDD7CZ.js → chunk-NAXEEGJU.js} +4 -4
- package/chunks/{chunk-467G3SV5.js → chunk-NPQDJGKU.js} +1 -1
- package/chunks/{chunk-FLTN6NRU.js → chunk-O4OT3DM3.js} +5 -1
- package/chunks/{chunk-3EUZWNWA.js → chunk-OPDZT2VG.js} +1 -1
- package/chunks/chunk-OQ5SYCPE.js +10017 -0
- package/chunks/{chunk-C27BYUX6.js → chunk-OQB4EXO4.js} +14 -11
- package/chunks/{chunk-V25Z5UUB.js → chunk-P6PBZL3N.js} +7 -6
- package/chunks/{chunk-5NWV4NFB.js → chunk-PRAUGUNM.js} +3 -3
- package/chunks/{chunk-MC2DOZS7.js → chunk-PVT6E3ZI.js} +3 -3
- package/chunks/{chunk-KXEGCGUG.js → chunk-Q22WWVR6.js} +31 -6
- package/chunks/{chunk-JDI67JFB.js → chunk-Q2YKNMLS.js} +3 -3
- package/chunks/{chunk-PBATSWUQ.js → chunk-QBUDF33N.js} +1 -1
- package/chunks/{chunk-Y2ENGUD6.js → chunk-QKTHJXCS.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-OKWRU4NO.js → chunk-RC7A7SSL.js} +3 -3
- package/chunks/chunk-RCUEYZDE.js +2290 -0
- package/chunks/{chunk-EVSTCA7S.js → chunk-RMY5SX7S.js} +368 -113
- package/chunks/{chunk-4WUAQ2DO.js → chunk-RTQSXHS7.js} +2 -2
- package/chunks/{chunk-RFIAR4YL.js → chunk-RV4C2ZFG.js} +1 -1
- package/chunks/{chunk-NIJEXGV6.js → chunk-RVLZCXEE.js} +79 -10
- package/chunks/{chunk-Q4RBU7WX.js → chunk-S333CBIA.js} +6 -6
- package/chunks/{chunk-JNWZQ27S.js → chunk-SP5WRGVG.js} +3 -3
- package/chunks/{chunk-FSL5W5TI.js → chunk-T2L47JJK.js} +3 -3
- package/chunks/{chunk-PWVTCGBP.js → chunk-TA4S377U.js} +30 -20
- package/chunks/{chunk-TB6UDU4T.js → chunk-THJNPLI4.js} +16 -16
- package/chunks/chunk-U6TQGUNB.js +20687 -0
- package/chunks/chunk-U7ZFW55U.js +2098 -0
- package/chunks/{chunk-W7H223ZZ.js → chunk-UGYMA4EI.js} +1 -1
- package/chunks/{chunk-X6YQWCIJ.js → chunk-UH3WSE5L.js} +13 -1
- package/chunks/{chunk-P2YAOGJD.js → chunk-UKU3NGW6.js} +3 -3
- package/chunks/{chunk-NOWTNYC7.js → chunk-UVFCANV5.js} +8 -8
- package/chunks/{chunk-CVDW42JT.js → chunk-V4AKJQ26.js} +1 -1
- package/chunks/{chunk-Z5Q65RVH.js → chunk-VJPRLNLR.js} +1 -1
- package/chunks/{chunk-Y4CRUWFZ.js → chunk-VTXX72XS.js} +60 -35
- package/chunks/{chunk-R3VWUU2E.js → chunk-VYPFXUCB.js} +1 -1
- package/chunks/chunk-WHGVTP7Q.js +1049 -0
- package/chunks/{chunk-IKP5DXZY.js → chunk-WOWQQGGN.js} +5 -5
- package/chunks/{chunk-D2VIDMVM.js → chunk-X6N25LXS.js} +2 -2
- package/chunks/chunk-XHATNRQA.js +1500 -0
- package/chunks/{chunk-2DXOIVUI.js → chunk-YLSB23Y2.js} +11 -11
- package/chunks/{chunk-S35ZDXOS.js → chunk-YM3SZTH4.js} +2 -1
- package/chunks/{chunk-OF2BBLYQ.js → chunk-YNWJAOPL.js} +2 -2
- package/chunks/{chunk-GKY2OJ7R.js → chunk-ZHERRXZJ.js} +1 -1
- package/chunks/{chunk-AR27OPIU.js → chunk-ZKFJKN23.js} +2 -2
- package/chunks/{computer-use-R7KA6UJ6.js → computer-use-UKQBH7UM.js} +39 -36
- package/chunks/{config-utils-6FXFJUYB.js → config-utils-FYTBZLCJ.js} +3 -3
- package/chunks/{contextCommand-KAQQPHZ4.js → contextCommand-ESHGAVWX.js} +36 -33
- package/chunks/{create-sub-session-TDPDBU4K.js → create-sub-session-574EPZUU.js} +34 -31
- package/chunks/{create-sub-session-X5RVIHCK.js → create-sub-session-AZ77LBL3.js} +3 -3
- package/chunks/{cron-create-AC5FFLN7.js → cron-create-KTWJM7QT.js} +5 -5
- package/chunks/{cron-delete-JEB3FAHA.js → cron-delete-2P3I5ULL.js} +5 -5
- package/chunks/{cron-list-NBYPCNIB.js → cron-list-PXDPGEDQ.js} +5 -5
- package/chunks/{daemon-RG2MAI6T.js → daemon-GJRFILYS.js} +323 -99
- package/chunks/daemon-status-provider-GZXZP3NU.js +80 -0
- package/chunks/{de-I7ZIYXZC.js → de-4IBXM7CN.js} +5 -1
- package/chunks/{dist-AU7NQQRP.js → dist-OAV7LJGJ.js} +1 -1
- package/chunks/{dist-FUTEXY6A.js → dist-OMW6WDEO.js} +1 -1
- package/chunks/{dist-2MIU4UUH.js → dist-PJLG2XYX.js} +1 -1
- package/chunks/{dist-53PZYC5B.js → dist-UIFWIFRO.js} +2 -2
- package/chunks/{dist-2BHAYBKP.js → dist-XBJVSWS2.js} +1 -1
- package/chunks/{dist-WGTQO7F2.js → dist-XRYV6TJP.js} +65 -25
- package/chunks/{earlyInputCapture-WC7RI5HV.js → earlyInputCapture-GI3HGQIT.js} +35 -32
- package/chunks/{edit-6MHKCJCM.js → edit-EBJK74B3.js} +42 -41
- package/chunks/{en-XE34GKAA.js → en-USMCCJAJ.js} +5 -1
- package/chunks/{enter-worktree-O7VJ2E7A.js → enter-worktree-2ETY5CSV.js} +39 -36
- package/chunks/{enterPlanMode-5XYAALIO.js → enterPlanMode-NY4U2727.js} +45 -37
- package/chunks/{environment-LSKFNLBU.js → environment-33IR3NOU.js} +36 -33
- package/chunks/{errors-ZFVCY6HG.js → errors-2OCY23IC.js} +36 -33
- package/chunks/{exit-worktree-MYIK66T7.js → exit-worktree-Y4ULJ45U.js} +39 -36
- package/chunks/{exitPlanMode-7MBNU76O.js → exitPlanMode-SECI2EQ6.js} +39 -36
- package/chunks/{fast-path-RNLIB64C.js → fast-path-6Z7RW5J5.js} +3 -2
- package/chunks/{fr-X7KDVZIY.js → fr-WVHEBDDB.js} +5 -1
- package/chunks/{gemini-WK5ISEAQ.js → gemini-XLGLUGSU.js} +93 -89
- package/chunks/{geminiContentGenerator-NUJQBZBW.js → geminiContentGenerator-NNZZDH24.js} +5 -5
- 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-7P6RYY4L.js → glob-KZA64SSV.js} +41 -38
- package/chunks/{grep-V3QHNP2J.js → grep-ONHQMY3V.js} +41 -38
- package/chunks/handleAutoUpdate-PRTJISXQ.js +73 -0
- package/chunks/{i18n-B7IO7WQT.js → i18n-ZTKKG5R5.js} +35 -32
- package/chunks/{initializer-E5TIC3CW.js → initializer-FPPZGBYN.js} +40 -37
- package/chunks/{installationInfo-XLPNAISK.js → installationInfo-DV2C27HT.js} +37 -32
- 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/{list-3CZR5I42.js → list-KEHCNUAK.js} +42 -39
- package/chunks/{loadedSettingsAdapter-X5BSC6CE.js → loadedSettingsAdapter-7RZ6M3WH.js} +39 -36
- package/chunks/{loop-wakeup-HMHCT5GU.js → loop-wakeup-RNMRVA66.js} +6 -6
- package/chunks/{ls-IW5HYDG4.js → ls-J2ZI5XYK.js} +5 -5
- package/chunks/{lsp-4RL52YIZ.js → lsp-UMS3NUB5.js} +3 -3
- package/chunks/managed-npm-update-EBKNOG37.js +332 -0
- package/chunks/{mcp-4C4HWXAR.js → mcp-NHXKZRRP.js} +39 -36
- package/chunks/{monitor-3CJDNZB2.js → monitor-FMUAIFFH.js} +39 -36
- package/chunks/nonInteractiveCli-I2GPZNTP.js +132 -0
- package/chunks/{notebook-edit-MX366HCT.js → notebook-edit-V7RNXKVL.js} +43 -42
- package/chunks/{openaiContentGenerator-KRPNNJGZ.js → openaiContentGenerator-IBVUUZDH.js} +19 -18
- package/chunks/{pidfile-K7T2JLUJ.js → pidfile-AMTGL2H2.js} +35 -32
- package/chunks/{processUtils-YXL3VIBR.js → processUtils-3ZT2JF6D.js} +2 -2
- package/chunks/{pt-JJ4XPIBP.js → pt-OK455PLH.js} +5 -1
- package/chunks/{qwenContentGenerator-GJVXFZ3U.js → qwenContentGenerator-E72VVWS3.js} +41 -38
- package/chunks/{qwenOAuth2-UZTIBQLY.js → qwenOAuth2-YCC3HP24.js} +17 -16
- package/chunks/{read-file-S5XQSYOW.js → read-file-5EWNGUXN.js} +13 -11
- package/chunks/{read-mcp-resource-OIBCNIX7.js → read-mcp-resource-F6HYMDUY.js} +3 -3
- package/chunks/{record-artifact-HDMK4LHG.js → record-artifact-7GCFLDD7.js} +3 -3
- package/chunks/{resumeHistoryUtils-IKR6XD2S.js → resumeHistoryUtils-IH4RNB76.js} +41 -38
- package/chunks/{ripGrep-H65GRSQX.js → ripGrep-B6A6N7GI.js} +34 -31
- package/chunks/{ru-STR4KTW7.js → ru-7SPDGMGD.js} +5 -1
- package/chunks/{run-qwen-serve-7SKAQOAA.js → run-qwen-serve-6PKSMF6Z.js} +115 -74
- package/chunks/{runtime-I2STBGPR.js → runtime-ASRANXO6.js} +45 -40
- package/chunks/{scheduler-6F7HETNO.js → scheduler-IABM76UZ.js} +34 -31
- package/chunks/sdk-exporters-grpc-ETLH47EP.js +23214 -0
- package/chunks/sdk-exporters-http-6MCQH335.js +563 -0
- package/chunks/sdk-impl-HOLWAXC6.js +9193 -0
- package/chunks/{send-message-WXVVK4DB.js → send-message-KBO6X4ZS.js} +7 -5
- package/chunks/{serve-4ATEWSEA.js → serve-A4DT5D32.js} +39 -36
- package/chunks/{server-YPUPFV2O.js → server-DZ5ZSVRE.js} +2317 -472
- package/chunks/{session-AZFIERIY.js → session-G2R3CYU6.js} +87 -172
- package/chunks/{settings-EFQHLTM3.js → settings-7TNSXUTO.js} +43 -40
- package/chunks/{shell-FWXWBJ4Q.js → shell-5BRFGEMK.js} +34 -31
- package/chunks/{skill-A634MNCD.js → skill-3SWYEK7M.js} +24 -20
- package/chunks/{spawnChannel-KKBGGR47.js → spawnChannel-GGN2WVWW.js} +36 -33
- package/chunks/{src-BVROLD6N.js → src-5BPBNQ5S.js} +314 -236
- package/chunks/{standalone-update-ERLA3BDC.js → standalone-update-AHOZ56LS.js} +37 -34
- package/chunks/{startInteractiveUI-3VZ23WAY.js → startInteractiveUI-TLGOQVV7.js} +1105 -906
- package/chunks/{syntheticOutput-HCUFXSIA.js → syntheticOutput-H7RTI5KL.js} +4 -4
- package/chunks/{task-create-RIY5JTFC.js → task-create-7474AJJD.js} +10 -8
- package/chunks/{task-list-XBUCV3CO.js → task-list-633HGOIB.js} +6 -6
- package/chunks/{task-stop-QDFCCYR5.js → task-stop-MNUGHPIA.js} +3 -3
- package/chunks/{task-update-7PXKJQOI.js → task-update-66GQB5LI.js} +10 -8
- package/chunks/{team-create-ZZO7QFQ7.js → team-create-XHDF7UKM.js} +42 -39
- package/chunks/{team-delete-TNSSE2S5.js → team-delete-BB3CG3QF.js} +6 -6
- package/chunks/{team-plan-approval-3BZBJ46K.js → team-plan-approval-XKSBXWMH.js} +39 -36
- package/chunks/{theme-manager-FSFWNXFJ.js → theme-manager-6ZKLBFAN.js} +35 -32
- package/chunks/{todoWrite-OMAIGB6V.js → todoWrite-KRAUN54W.js} +5 -5
- package/chunks/{tool-search-VYXAAIDW.js → tool-search-UDNJCXYS.js} +21 -17
- package/chunks/{total-session-admission-PSMLQICS.js → total-session-admission-VWRCCDYM.js} +40 -37
- package/chunks/{tree-sitter-4D7QS7F6.js → tree-sitter-L5BFT64K.js} +1 -1
- package/chunks/{tree-sitter-bash-VEJGF5XF.js → tree-sitter-bash-ZKDNQGID.js} +1 -1
- package/chunks/{trustedFolders-QA3RK2NV.js → trustedFolders-TJI6OLAN.js} +35 -32
- package/chunks/{chunk-6EFTQYW7.js → undici-3FJYTMOF.js} +24 -399
- package/chunks/{chunk-L573Z2QZ.js → undici-PYHBDDPN.js} +1 -5
- package/chunks/{update-relaunch-LNLZFX3J.js → update-relaunch-RS5GB74A.js} +17 -17
- package/chunks/updateCheck-T4EEA5YR.js +88 -0
- package/chunks/{useAutoAcceptIndicator-DIWN27LT.js → useAutoAcceptIndicator-LLWMXC7F.js} +44 -41
- package/chunks/{validateNonInterActiveAuth-LOEOFCAF.js → validateNonInterActiveAuth-OJ3KYXAR.js} +74 -71
- package/chunks/{version-HBF2VBLE.js → version-ZCEUV5DO.js} +1 -1
- package/chunks/{web-fetch-BWGSD2BD.js → web-fetch-KQF4YFCI.js} +99 -42
- package/chunks/{web-search-OOHTCVR3.js → web-search-QDDGFGKI.js} +113 -61
- package/chunks/{workflow-LJAJBOR4.js → workflow-GIRKCX4P.js} +47 -43
- package/chunks/{workspace-providers-status-FYV7TTHA.js → workspace-providers-status-UTMAVTNE.js} +42 -39
- package/chunks/{workspace-registration-store-4EHGQW4Y.js → workspace-registration-store-EYJMJFZU.js} +8 -2
- package/chunks/{workspace-registry-BKD7VC4Y.js → workspace-registry-4W4UW6MY.js} +40 -37
- package/chunks/{workspace-service-75RHX6KR.js → workspace-service-DJCPY6ZN.js} +46 -43
- package/chunks/{workspace-skills-status-WBZBZI6A.js → workspace-skills-status-VQ2LKXXX.js} +40 -37
- package/chunks/write-file-PLK6RQ7M.js +65 -0
- package/chunks/{zh-TW-4RR3YHNN.js → zh-TW-BM47YBFH.js} +5 -1
- package/chunks/{zh-6ANG2HTL.js → zh-WY5DWYZD.js} +5 -1
- package/cli-entry.js +164 -12
- package/cli.js +18 -11
- package/locales/ca.js +772 -203
- package/locales/de.js +8 -2
- package/locales/en.js +8 -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 +8 -2
- package/locales/zh.js +8 -2
- package/package.json +3 -3
- package/web-shell/assets/{arc-Buk1besA.js → arc-DIQrcXXh.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-B1aUKYDC.js → architectureDiagram-3BPJPVTR-CbPd-DSw.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-CRTdg3Zx.js → blockDiagram-GPEHLZMM-yzBIVhMX.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-DFdRMp5g.js → c4Diagram-AAUBKEIU-B88Swcsu.js} +1 -1
- package/web-shell/assets/channel-BaTMUesZ.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-4rYQdkEI.js → chunk-2J33WTMH-BbOLo6NX.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-Coi-pQJy.js → chunk-4BX2VUAB-Bg6in0r0.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-BtBjz02t.js → chunk-55IACEB6-Bv9QRyLI.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-CGYOWorl.js → chunk-727SXJPM-CFokiv61.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-CH5AKhqx.js → chunk-AQP2D5EJ-DS2Oxf6L.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-Cd50-w85.js → chunk-FMBD7UC4-D2NkHD3B.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-C2wF3KCK.js → chunk-ND2GUHAM-BsT_UC5B.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-pCeRTaWi.js → chunk-QZHKN3VN-tnJo3zln.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CyBPzWud.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CyBPzWud.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-B-_fAB6D.js → cose-bilkent-S5V4N54A-BTMa6DAZ.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-ChSPNHpL.js → dagre-BM42HDAG-ujGX7Owg.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-BX7cFOF3.js → diagram-2AECGRRQ-fU4-dbPa.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BQUTW92n.js → diagram-5GNKFQAL-Bdm-TYSA.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-BkYPh3e4.js → diagram-KO2AKTUF-Bkhz85Z9.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-Cl6jsNyx.js → diagram-LMA3HP47-Bzu3q26p.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-DRWoHz8n.js → diagram-OG6HWLK6-CZrXbG5Q.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-CGvFcZco.js → erDiagram-TEJ5UH35-BjozEAYu.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-vms6oVdv.js → flowDiagram-I6XJVG4X-B3a2I8c-.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-ukT_sfmi.js → ganttDiagram-6RSMTGT7-CIMn9fNm.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Bn2ZE2Ut.js → gitGraphDiagram-PVQCEYII-DlFy9KRx.js} +1 -1
- package/web-shell/assets/{index-wFXp7W68.js → index-BODUAzQA.js} +1 -1
- package/web-shell/assets/index-C54DNMF7.js +1209 -0
- package/web-shell/assets/index-lWqBfc78.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-DHJdSi7x.js → infoDiagram-5YYISTIA-BmKjQgCy.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-DOvd2Wph.js → ishikawaDiagram-YF4QCWOH-BrQEMZz2.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CH_urMCT.js → journeyDiagram-JHISSGLW-D-2r7Xrt.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-FKiBdgbH.js → kanban-definition-UN3LZRKU-CndsFHCX.js} +1 -1
- package/web-shell/assets/{linear-0ZVQFVKf.js → linear-D-IwNnKx.js} +1 -1
- package/web-shell/assets/{mermaid.core-DJ05ZZIK.js → mermaid.core-4ll09sri.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-BPuUhkUm.js → mindmap-definition-RKZ34NQL-maMRIxjo.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-yLFKcXyG.js → pieDiagram-4H26LBE5-aunUDhrJ.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-irWqc1pE.js → quadrantDiagram-W4KKPZXB-D3K0P1NZ.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-B_4uMoIV.js → requirementDiagram-4Y6WPE33-CX2X9HRc.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-ciA4GPwk.js → sankeyDiagram-5OEKKPKP-CDroWk7l.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CRdZvy0U.js → sequenceDiagram-3UESZ5HK-DTk-2b16.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-DaYIkCCn.js → stateDiagram-AJRCARHV-Cud64hQr.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-g-uUpecT.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-oBUKv6iH.js → timeline-definition-PNZ67QCA-DfD5okf_.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-CGW9Sdmb.js → vennDiagram-CIIHVFJN-BYl8ay25.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-CvwKJOCm.js → wardley-L42UT6IY-BZFAt10J.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Ipc260sN.js → wardleyDiagram-YWT4CUSO-BIWn0GA7.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-D6-CM7pK.js → xychartDiagram-2RQKCTM6-1_H4xblT.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-ETD6K42I.js +0 -358
- package/chunks/chunk-I5NLVPZJ.js +0 -45
- package/chunks/chunk-ONWW74X6.js +0 -74639
- package/chunks/chunk-W7FJ3N32.js +0 -49
- package/chunks/daemon-status-provider-LVTVJGAD.js +0 -77
- package/chunks/handleAutoUpdate-AAQ6PL3E.js +0 -70
- package/chunks/nonInteractiveCli-QTEHDDFH.js +0 -129
- package/chunks/updateCheck-JJEUQ54U.js +0 -73
- package/chunks/write-file-M2DTFILF.js +0 -599
- 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
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
+
import {
|
|
4
|
+
recomputeMcpGating
|
|
5
|
+
} from "./chunk-E2ZK5M4P.js";
|
|
3
6
|
import {
|
|
4
7
|
classifyApiError
|
|
5
8
|
} from "./chunk-V7RNNPGC.js";
|
|
@@ -12,42 +15,37 @@ import {
|
|
|
12
15
|
matchMcpServerByRef,
|
|
13
16
|
parseExtensionRef,
|
|
14
17
|
parseMcpServerRef
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-FJ2IUWNQ.js";
|
|
16
19
|
import {
|
|
17
20
|
getAvailableCommands,
|
|
18
21
|
handleSlashCommand,
|
|
19
22
|
insertAfterFunctionResponses,
|
|
20
23
|
isSlashCommand,
|
|
21
24
|
normalizePartList
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import {
|
|
24
|
-
recomputeMcpGating
|
|
25
|
-
} from "./chunk-GA7VRJVN.js";
|
|
25
|
+
} from "./chunk-CGZ5SV23.js";
|
|
26
26
|
import {
|
|
27
27
|
appEvents,
|
|
28
28
|
buildDisabledSkillNamesProvider,
|
|
29
29
|
loadCliConfig,
|
|
30
30
|
normalizeDisabledToolList
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-MJPBB2GK.js";
|
|
32
32
|
import {
|
|
33
33
|
getCommandSubcommandNames
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-OPDZT2VG.js";
|
|
35
35
|
import {
|
|
36
36
|
getEffectiveSupportedModes
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-HCJQORKC.js";
|
|
38
38
|
import "./chunk-5DTTYNB7.js";
|
|
39
|
-
import "./chunk-
|
|
39
|
+
import "./chunk-4LVZNIDO.js";
|
|
40
40
|
import {
|
|
41
41
|
collectContextData,
|
|
42
42
|
formatContextUsageText
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-UVFCANV5.js";
|
|
44
44
|
import "./chunk-4WGODMVR.js";
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-
|
|
47
|
-
import "./chunk-P2YAOGJD.js";
|
|
48
|
-
import "./chunk-DA7OOKVN.js";
|
|
49
|
-
import "./chunk-LZYWWWCZ.js";
|
|
45
|
+
import "./chunk-IKP54WUL.js";
|
|
46
|
+
import "./chunk-KF6CTNTJ.js";
|
|
50
47
|
import "./chunk-YAF2MQZ6.js";
|
|
48
|
+
import "./chunk-7Z6JQEL6.js";
|
|
51
49
|
import {
|
|
52
50
|
GENERATION_MAX_PROMPT_BYTES,
|
|
53
51
|
GENERATION_TIMEOUT_MS,
|
|
@@ -66,7 +64,7 @@ import {
|
|
|
66
64
|
shouldSuppressRememberErrorDetails,
|
|
67
65
|
workspaceMemoryFailureCode,
|
|
68
66
|
workspaceMemoryFailureDiagnostics
|
|
69
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-BK6UOUJ2.js";
|
|
70
68
|
import {
|
|
71
69
|
HistoryReplayer,
|
|
72
70
|
MessageEmitter,
|
|
@@ -76,21 +74,21 @@ import {
|
|
|
76
74
|
goalTerminalEventToHistoryItem,
|
|
77
75
|
recordGoalStatusItem,
|
|
78
76
|
restoreGoalFromHistory
|
|
79
|
-
} from "./chunk-
|
|
80
|
-
import "./chunk-
|
|
77
|
+
} from "./chunk-C54UTDOC.js";
|
|
78
|
+
import "./chunk-4K7VDKAD.js";
|
|
79
|
+
import "./chunk-V4AKJQ26.js";
|
|
81
80
|
import "./chunk-RS7MT2QG.js";
|
|
82
|
-
import "./chunk-CVDW42JT.js";
|
|
83
81
|
import "./chunk-H2XVO6NE.js";
|
|
82
|
+
import "./chunk-QHTIBUWB.js";
|
|
84
83
|
import {
|
|
85
84
|
isTerminalGoalStatusKind
|
|
86
85
|
} from "./chunk-QTERJVPZ.js";
|
|
87
|
-
import "./chunk-
|
|
88
|
-
import "./chunk-L573Z2QZ.js";
|
|
86
|
+
import "./chunk-3Z43GZUQ.js";
|
|
89
87
|
import {
|
|
90
88
|
computeCpuPercent
|
|
91
89
|
} from "./chunk-HGT6JR3U.js";
|
|
92
90
|
import "./chunk-RXFQM6FQ.js";
|
|
93
|
-
import "./chunk-
|
|
91
|
+
import "./chunk-HL6AKUGD.js";
|
|
94
92
|
import "./chunk-6H67XLET.js";
|
|
95
93
|
import {
|
|
96
94
|
beginAcpBootstrapConfigProfiling,
|
|
@@ -98,32 +96,10 @@ import {
|
|
|
98
96
|
endAcpBootstrapConfigProfiling,
|
|
99
97
|
markAcpStartup
|
|
100
98
|
} from "./chunk-TDKQP3M6.js";
|
|
101
|
-
import
|
|
102
|
-
createLoadedSettingsAdapter
|
|
103
|
-
} from "./chunk-Z5Q65RVH.js";
|
|
99
|
+
import "./chunk-UKU3NGW6.js";
|
|
104
100
|
import "./chunk-LXXMOYPL.js";
|
|
105
|
-
import "./chunk-
|
|
101
|
+
import "./chunk-HDATOR4J.js";
|
|
106
102
|
import "./chunk-E5Z2AVNV.js";
|
|
107
|
-
import {
|
|
108
|
-
parseSessionSource
|
|
109
|
-
} from "./chunk-EVSTCA7S.js";
|
|
110
|
-
import "./chunk-6RLROE6G.js";
|
|
111
|
-
import "./chunk-COH43MRJ.js";
|
|
112
|
-
import {
|
|
113
|
-
CHANNEL_STARTUP_PROFILE_META_KEY,
|
|
114
|
-
CHANNEL_STARTUP_PROFILE_VERSION,
|
|
115
|
-
CLIENT_MCP_OVER_WS_CONFIG_FLAG,
|
|
116
|
-
LOAD_REPLAY_BULK_MODE,
|
|
117
|
-
LOAD_REPLAY_META_KEY,
|
|
118
|
-
LOAD_REPLAY_MODE_META_KEY,
|
|
119
|
-
LOAD_REPLAY_PAGE_SIZE_META_KEY,
|
|
120
|
-
LOAD_REPLAY_VERSION,
|
|
121
|
-
MID_TURN_QUEUE_DRAIN_METHOD,
|
|
122
|
-
TODO_STOP_GUARD_QUEUE_RELEASE_METHOD
|
|
123
|
-
} from "./chunk-QR6U5QPP.js";
|
|
124
|
-
import {
|
|
125
|
-
ndJsonStream
|
|
126
|
-
} from "./chunk-6GUTHAN7.js";
|
|
127
103
|
import {
|
|
128
104
|
ACP_ROUTE_ID_PREFIX,
|
|
129
105
|
buildAcpModelOptions,
|
|
@@ -132,7 +108,7 @@ import {
|
|
|
132
108
|
parseAcpModelOption,
|
|
133
109
|
resolveAcpModelOption,
|
|
134
110
|
sanitizeProviderBaseUrl
|
|
135
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-M4VFMLQK.js";
|
|
136
112
|
import {
|
|
137
113
|
mapSkillConfigToStatus
|
|
138
114
|
} from "./chunk-2W3OOD4W.js";
|
|
@@ -142,19 +118,48 @@ import {
|
|
|
142
118
|
buildPermissionSettings,
|
|
143
119
|
normalizePermissionRules,
|
|
144
120
|
readPermissionRuleSet
|
|
145
|
-
} from "./chunk-
|
|
121
|
+
} from "./chunk-A3TAEAHX.js";
|
|
146
122
|
import {
|
|
147
123
|
MAX_AUDIO_BYTES,
|
|
148
124
|
sanitizeVoiceErrorMessage,
|
|
149
125
|
transcribeVoiceAudio
|
|
150
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-M3EQ3GZC.js";
|
|
151
127
|
import {
|
|
152
128
|
readVoiceModel
|
|
153
|
-
} from "./chunk-
|
|
154
|
-
import "./chunk-
|
|
129
|
+
} from "./chunk-AVQ6EX4J.js";
|
|
130
|
+
import "./chunk-QLJUC7TG.js";
|
|
131
|
+
import {
|
|
132
|
+
parseSessionSource
|
|
133
|
+
} from "./chunk-RMY5SX7S.js";
|
|
134
|
+
import "./chunk-6RLROE6G.js";
|
|
135
|
+
import "./chunk-COH43MRJ.js";
|
|
136
|
+
import {
|
|
137
|
+
CHANNEL_STARTUP_PROFILE_META_KEY,
|
|
138
|
+
CHANNEL_STARTUP_PROFILE_VERSION,
|
|
139
|
+
CLIENT_MCP_OVER_WS_CONFIG_FLAG,
|
|
140
|
+
LOAD_REPLAY_BULK_MODE,
|
|
141
|
+
LOAD_REPLAY_META_KEY,
|
|
142
|
+
LOAD_REPLAY_MODE_META_KEY,
|
|
143
|
+
LOAD_REPLAY_PAGE_SIZE_META_KEY,
|
|
144
|
+
LOAD_REPLAY_VERSION,
|
|
145
|
+
MID_TURN_QUEUE_DRAIN_METHOD,
|
|
146
|
+
TODO_STOP_GUARD_QUEUE_RELEASE_METHOD
|
|
147
|
+
} from "./chunk-QR6U5QPP.js";
|
|
155
148
|
import {
|
|
156
149
|
NOT_CURRENTLY_GENERATING_CANCEL_MESSAGE
|
|
157
|
-
} from "./chunk-
|
|
150
|
+
} from "./chunk-UH3WSE5L.js";
|
|
151
|
+
import "./chunk-Q22WWVR6.js";
|
|
152
|
+
import "./chunk-FQI7LT7T.js";
|
|
153
|
+
import "./chunk-57OAHC2Y.js";
|
|
154
|
+
import "./chunk-GHRSKGHF.js";
|
|
155
|
+
import "./chunk-6ZBPS62S.js";
|
|
156
|
+
import "./chunk-V6WHFGST.js";
|
|
157
|
+
import {
|
|
158
|
+
createLoadedSettingsAdapter
|
|
159
|
+
} from "./chunk-VJPRLNLR.js";
|
|
160
|
+
import {
|
|
161
|
+
ndJsonStream
|
|
162
|
+
} from "./chunk-6HOCJNO5.js";
|
|
158
163
|
import {
|
|
159
164
|
ACP_PREFLIGHT_KINDS,
|
|
160
165
|
IDLE_HOOK_EVENTS,
|
|
@@ -162,29 +167,23 @@ import {
|
|
|
162
167
|
SERVE_STATUS_EXT_METHODS,
|
|
163
168
|
STATUS_SCHEMA_VERSION,
|
|
164
169
|
mapDomainErrorToErrorKind
|
|
165
|
-
} from "./chunk-
|
|
166
|
-
import "./chunk-
|
|
167
|
-
import "./chunk-
|
|
168
|
-
import "./chunk-57OAHC2Y.js";
|
|
169
|
-
import "./chunk-OMH3276Y.js";
|
|
170
|
-
import "./chunk-4ODB7WIB.js";
|
|
171
|
-
import "./chunk-V6WHFGST.js";
|
|
172
|
-
import {
|
|
173
|
-
assembleMcpServers,
|
|
174
|
-
loadMcpApprovals
|
|
175
|
-
} from "./chunk-V25Z5UUB.js";
|
|
176
|
-
import "./chunk-W7FJ3N32.js";
|
|
177
|
-
import "./chunk-Y2ENGUD6.js";
|
|
170
|
+
} from "./chunk-ESQHGKPJ.js";
|
|
171
|
+
import "./chunk-2RFKHEXL.js";
|
|
172
|
+
import "./chunk-QKTHJXCS.js";
|
|
178
173
|
import "./chunk-TJTKSVIV.js";
|
|
179
174
|
import "./chunk-M5GB774H.js";
|
|
180
|
-
import "./chunk-
|
|
181
|
-
import "./chunk-
|
|
182
|
-
import "./chunk-
|
|
175
|
+
import "./chunk-RV4C2ZFG.js";
|
|
176
|
+
import "./chunk-2LI23QA6.js";
|
|
177
|
+
import "./chunk-RVLZCXEE.js";
|
|
183
178
|
import {
|
|
184
179
|
AgentSideConnection,
|
|
185
180
|
PROTOCOL_VERSION,
|
|
186
181
|
RequestError
|
|
187
182
|
} from "./chunk-UDXSXLER.js";
|
|
183
|
+
import {
|
|
184
|
+
assembleMcpServers,
|
|
185
|
+
loadMcpApprovals
|
|
186
|
+
} from "./chunk-P6PBZL3N.js";
|
|
188
187
|
import {
|
|
189
188
|
getOutputLanguageFilePath,
|
|
190
189
|
getPersistScopeForModelSelection,
|
|
@@ -193,38 +192,39 @@ import {
|
|
|
193
192
|
resolveOutputLanguageOrPreserveAuto,
|
|
194
193
|
updateOutputLanguageFile,
|
|
195
194
|
writeOutputLanguageAndRegisterPath
|
|
196
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-GWM4PDYK.js";
|
|
197
196
|
import "./chunk-RKUWKYED.js";
|
|
198
|
-
import "./chunk-GOXKNSDZ.js";
|
|
199
|
-
import {
|
|
200
|
-
getSystemDefaultsPath,
|
|
201
|
-
getSystemSettingsPath
|
|
202
|
-
} from "./chunk-IDS7MSUP.js";
|
|
203
197
|
import {
|
|
204
198
|
SUPPORTED_LANGUAGES,
|
|
205
199
|
getCurrentLanguage,
|
|
206
200
|
setLanguageAsync
|
|
207
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-YLSB23Y2.js";
|
|
208
202
|
import {
|
|
209
203
|
findEnvFiles,
|
|
210
204
|
preResolveHomeEnvOverrides,
|
|
211
205
|
reloadEnvironment
|
|
212
|
-
} from "./chunk-
|
|
206
|
+
} from "./chunk-YNWJAOPL.js";
|
|
207
|
+
import "./chunk-4CTP6VR6.js";
|
|
208
|
+
import "./chunk-GOXKNSDZ.js";
|
|
209
|
+
import {
|
|
210
|
+
getSystemDefaultsPath,
|
|
211
|
+
getSystemSettingsPath
|
|
212
|
+
} from "./chunk-IDS7MSUP.js";
|
|
213
213
|
import "./chunk-QRUIS3DN.js";
|
|
214
|
-
import "./chunk-
|
|
214
|
+
import "./chunk-XFSFZCM5.js";
|
|
215
|
+
import "./chunk-ISMD2AB3.js";
|
|
215
216
|
import "./chunk-VJNBRRZG.js";
|
|
216
217
|
import {
|
|
217
218
|
isFolderTrustEnabled,
|
|
218
219
|
isWorkspaceTrusted,
|
|
219
220
|
loadTrustedFolders
|
|
220
|
-
} from "./chunk-
|
|
221
|
+
} from "./chunk-PVT6E3ZI.js";
|
|
221
222
|
import "./chunk-ALGGS7UH.js";
|
|
222
223
|
import "./chunk-MR3PXB6E.js";
|
|
223
224
|
import {
|
|
224
225
|
writeStderrLine,
|
|
225
226
|
writeStderrLineSafe
|
|
226
227
|
} from "./chunk-OWAK7LMW.js";
|
|
227
|
-
import "./chunk-XFSFZCM5.js";
|
|
228
228
|
import {
|
|
229
229
|
ALL_PROVIDERS,
|
|
230
230
|
APPROVAL_MODE_INFO,
|
|
@@ -243,16 +243,20 @@ import {
|
|
|
243
243
|
McpServerSpawnFailedError,
|
|
244
244
|
McpTransportPool,
|
|
245
245
|
MessageDisplayDispatcher,
|
|
246
|
+
PLAN_MODE_ENTRY_SIBLING_SKIP_MESSAGE,
|
|
246
247
|
POOLED_TRANSPORTS_DEFAULT,
|
|
247
248
|
SESSION_ARTIFACT_PERSISTENCE_VERSION,
|
|
248
249
|
SESSION_TITLE_MAX_LENGTH,
|
|
249
250
|
SESSION_TRANSCRIPT_MAX_LIMIT,
|
|
250
251
|
SESSION_TRANSCRIPT_MAX_PAGE_BYTES,
|
|
252
|
+
SESSION_WRITER_RPC_CODES,
|
|
251
253
|
SessionService,
|
|
252
254
|
SessionTranscriptPageTooLargeError,
|
|
253
255
|
SessionTranscriptReader,
|
|
254
256
|
SessionTranscriptSnapshotUnavailableError,
|
|
255
257
|
SessionTranscriptTooLargeError,
|
|
258
|
+
SessionWriterError,
|
|
259
|
+
SessionWriterUnavailableError,
|
|
256
260
|
TURN_INTERRUPTION_HISTORY_TAIL_COUNT,
|
|
257
261
|
WorkspaceMcpBudget,
|
|
258
262
|
abortGoalForStopHookCap,
|
|
@@ -260,6 +264,7 @@ import {
|
|
|
260
264
|
applyAutoModeDecision,
|
|
261
265
|
applyProviderInstallPlan,
|
|
262
266
|
approxBase64Bytes,
|
|
267
|
+
bridgeToolResultImages,
|
|
263
268
|
buildBackgroundEntryLabel,
|
|
264
269
|
buildBtwCacheSafeParams,
|
|
265
270
|
buildBtwPrompt,
|
|
@@ -272,13 +277,18 @@ import {
|
|
|
272
277
|
convertToFunctionErrorResponse,
|
|
273
278
|
convertToFunctionResponse,
|
|
274
279
|
createDuplicateProviderToolCallResponse,
|
|
280
|
+
decorateClassifierUnavailableConfirmation,
|
|
281
|
+
decoratePlanModeShellConfirmation,
|
|
275
282
|
dedupeToolCallsById,
|
|
276
283
|
detectAutonomousSentinel,
|
|
277
284
|
detectLoopSentinel,
|
|
278
285
|
encodeSessionTranscriptCursor,
|
|
279
286
|
evaluateAutoMode,
|
|
280
287
|
evaluatePermissionFlow,
|
|
288
|
+
evaluatePlanModeShellPolicy,
|
|
289
|
+
finalizeToolResponses,
|
|
281
290
|
findExistingProviderModels,
|
|
291
|
+
findPlanModeEntryBatchBoundaryIndex,
|
|
282
292
|
findProviderById,
|
|
283
293
|
findRepeatedDuplicateProviderToolCall,
|
|
284
294
|
fireNotificationHook,
|
|
@@ -301,21 +311,19 @@ import {
|
|
|
301
311
|
getPlanModeSystemReminder,
|
|
302
312
|
getProviderToolCallId,
|
|
303
313
|
getScopedEnvContents,
|
|
304
|
-
|
|
314
|
+
getStopHookContinuationReason,
|
|
305
315
|
ideContextStore,
|
|
306
316
|
injectPermissionRulesIfMissing,
|
|
307
317
|
isApproveOutcome,
|
|
308
318
|
isDenialFallbackReason,
|
|
309
319
|
isGatedMcpScope,
|
|
310
320
|
isPlanModeBlocked,
|
|
311
|
-
isSystemReminderContent,
|
|
312
321
|
markDuplicateProviderToolCallResponseSent,
|
|
313
322
|
matchesAnyServerPattern,
|
|
314
323
|
mcpServerRequiresOAuth,
|
|
315
324
|
needsConfirmation,
|
|
316
325
|
normalizeEventPayload,
|
|
317
326
|
normalizeSnapshotPayload,
|
|
318
|
-
parsePositiveIntegerEnv,
|
|
319
327
|
persistPermissionOutcome,
|
|
320
328
|
readManyFiles,
|
|
321
329
|
recordAllow,
|
|
@@ -337,45 +345,57 @@ import {
|
|
|
337
345
|
shouldRunAutoModeForCall,
|
|
338
346
|
subagentGenerator,
|
|
339
347
|
unregisterGoalHook,
|
|
340
|
-
updateSetting
|
|
341
|
-
|
|
342
|
-
|
|
348
|
+
updateSetting,
|
|
349
|
+
validatePlanModeShellApproval,
|
|
350
|
+
validatePlanModeShellContext
|
|
351
|
+
} from "./chunk-BLAEKN6K.js";
|
|
343
352
|
import "./chunk-T4TZQJ7W.js";
|
|
344
353
|
import {
|
|
345
354
|
external_exports
|
|
346
355
|
} from "./chunk-H6XPXXMH.js";
|
|
347
|
-
import "./chunk-
|
|
348
|
-
import "./chunk-
|
|
356
|
+
import "./chunk-5M6IDOMF.js";
|
|
357
|
+
import "./chunk-T2L47JJK.js";
|
|
358
|
+
import "./chunk-GPSKDNEE.js";
|
|
359
|
+
import "./chunk-X6N25LXS.js";
|
|
360
|
+
import "./chunk-E2UVIFI2.js";
|
|
361
|
+
import "./chunk-L5F3T6TQ.js";
|
|
362
|
+
import "./chunk-Q2YKNMLS.js";
|
|
349
363
|
import "./chunk-XU457J4V.js";
|
|
350
364
|
import "./chunk-VDDGDZMA.js";
|
|
351
|
-
import "./chunk-
|
|
352
|
-
import "./chunk-FSL5W5TI.js";
|
|
353
|
-
import "./chunk-D2VIDMVM.js";
|
|
354
|
-
import "./chunk-E2UVIFI2.js";
|
|
355
|
-
import "./chunk-WBTZGWQ6.js";
|
|
365
|
+
import "./chunk-KHOVYUHX.js";
|
|
356
366
|
import "./chunk-SZRN75WQ.js";
|
|
357
|
-
import
|
|
367
|
+
import {
|
|
368
|
+
parsePositiveIntegerEnv
|
|
369
|
+
} from "./chunk-6PVPNMXU.js";
|
|
358
370
|
import "./chunk-CPBF7KYF.js";
|
|
371
|
+
import "./chunk-NABLFI57.js";
|
|
372
|
+
import {
|
|
373
|
+
HookEventName,
|
|
374
|
+
createHookOutput
|
|
375
|
+
} from "./chunk-QBUDF33N.js";
|
|
376
|
+
import "./chunk-LIZRAKPB.js";
|
|
359
377
|
import {
|
|
360
378
|
APPROVAL_MODES,
|
|
361
379
|
FORK_SUBAGENT_TYPE,
|
|
380
|
+
getStartupContextLength,
|
|
381
|
+
isSystemReminderContent,
|
|
362
382
|
runWithRuntimeContentGenerator
|
|
363
|
-
} from "./chunk-
|
|
383
|
+
} from "./chunk-WHGVTP7Q.js";
|
|
364
384
|
import "./chunk-6AM5D4ME.js";
|
|
365
|
-
import "./chunk-
|
|
366
|
-
import
|
|
367
|
-
|
|
368
|
-
createHookOutput
|
|
369
|
-
} from "./chunk-PBATSWUQ.js";
|
|
370
|
-
import "./chunk-ZEOZL37W.js";
|
|
371
|
-
import "./chunk-OOCI5VVU.js";
|
|
385
|
+
import "./chunk-JCW2R7WC.js";
|
|
386
|
+
import "./chunk-57FIIFJN.js";
|
|
387
|
+
import "./chunk-HTO4JFDZ.js";
|
|
372
388
|
import {
|
|
373
389
|
clearCachedCredentialFile,
|
|
374
390
|
qwenOAuth2Events
|
|
375
|
-
} from "./chunk-
|
|
376
|
-
import "./chunk-OKWRU4NO.js";
|
|
377
|
-
import "./chunk-XNP57UDV.js";
|
|
391
|
+
} from "./chunk-2HGTVAOW.js";
|
|
378
392
|
import "./chunk-JESCGQM3.js";
|
|
393
|
+
import "./chunk-RC7A7SSL.js";
|
|
394
|
+
import "./chunk-C3EXYVFX.js";
|
|
395
|
+
import "./chunk-XVNQMZ2I.js";
|
|
396
|
+
import "./chunk-FODK6UMO.js";
|
|
397
|
+
import "./chunk-GLNBDYUX.js";
|
|
398
|
+
import "./chunk-DJ2GSRLV.js";
|
|
379
399
|
import {
|
|
380
400
|
AuthType,
|
|
381
401
|
ConversationFinishedEvent,
|
|
@@ -383,8 +403,6 @@ import {
|
|
|
383
403
|
LoopDetectedEvent,
|
|
384
404
|
PromptSuggestionEvent,
|
|
385
405
|
UserPromptEvent,
|
|
386
|
-
endToolExecutionSpan,
|
|
387
|
-
endToolSpan,
|
|
388
406
|
extractDaemonTraceContext,
|
|
389
407
|
formatFullTurnVisionNotice,
|
|
390
408
|
formatVisionBridgeNotice,
|
|
@@ -400,63 +418,63 @@ import {
|
|
|
400
418
|
logUserPrompt,
|
|
401
419
|
normalizeParts,
|
|
402
420
|
registerAcpEventLoopLagGauge,
|
|
403
|
-
runInToolSpanContext,
|
|
404
421
|
runSideQuery,
|
|
405
422
|
runVisionBridge,
|
|
406
423
|
shouldRunVisionBridge,
|
|
407
424
|
splitImageParts,
|
|
408
425
|
startEventLoopLagMonitor,
|
|
409
|
-
startToolExecutionSpan,
|
|
410
|
-
startToolSpan,
|
|
411
426
|
uiTelemetryService,
|
|
412
|
-
withDaemonSpan
|
|
413
|
-
|
|
414
|
-
} from "./chunk-ONWW74X6.js";
|
|
415
|
-
import "./chunk-4WKAA4KS.js";
|
|
416
|
-
import "./chunk-CR3C7WXL.js";
|
|
427
|
+
withDaemonSpan
|
|
428
|
+
} from "./chunk-U6TQGUNB.js";
|
|
417
429
|
import "./chunk-VGC4I5JJ.js";
|
|
418
430
|
import {
|
|
419
431
|
getAutoMemoryRoot,
|
|
420
432
|
getUserAutoMemoryRoot
|
|
421
|
-
} from "./chunk-
|
|
422
|
-
import "./chunk-UEY4AYUL.js";
|
|
423
|
-
import "./chunk-BDBMYST4.js";
|
|
424
|
-
import "./chunk-467G3SV5.js";
|
|
425
|
-
import {
|
|
426
|
-
ToolConfirmationOutcome,
|
|
427
|
-
ToolNames,
|
|
428
|
-
isShellProgressData
|
|
429
|
-
} from "./chunk-S35ZDXOS.js";
|
|
430
|
-
import "./chunk-XVNQMZ2I.js";
|
|
431
|
-
import "./chunk-FODK6UMO.js";
|
|
432
|
-
import "./chunk-GLNBDYUX.js";
|
|
433
|
-
import "./chunk-DJ2GSRLV.js";
|
|
434
|
-
import "./chunk-6EFTQYW7.js";
|
|
433
|
+
} from "./chunk-4K56OJFJ.js";
|
|
435
434
|
import {
|
|
436
435
|
DEFAULT_TOKEN_LIMIT,
|
|
437
436
|
getToolCallPreparations,
|
|
438
437
|
tokenLimit
|
|
439
|
-
} from "./chunk-
|
|
438
|
+
} from "./chunk-CBOQ3HY7.js";
|
|
440
439
|
import "./chunk-A4UCTEB5.js";
|
|
441
440
|
import "./chunk-XWRJCPHC.js";
|
|
441
|
+
import "./chunk-QNLNLENL.js";
|
|
442
|
+
import "./chunk-6X4GWOPW.js";
|
|
442
443
|
import "./chunk-TYQMGACW.js";
|
|
443
444
|
import "./chunk-TYAMGABM.js";
|
|
444
445
|
import "./chunk-FCMNKVXT.js";
|
|
446
|
+
import {
|
|
447
|
+
endToolExecutionSpan,
|
|
448
|
+
endToolSpan,
|
|
449
|
+
runInToolSpanContext,
|
|
450
|
+
startToolExecutionSpan,
|
|
451
|
+
startToolSpan,
|
|
452
|
+
withInteractionSpan
|
|
453
|
+
} from "./chunk-RCUEYZDE.js";
|
|
454
|
+
import "./chunk-HTR4WV6U.js";
|
|
455
|
+
import "./chunk-BULDBTYC.js";
|
|
456
|
+
import "./chunk-U7ZFW55U.js";
|
|
457
|
+
import "./chunk-NPQDJGKU.js";
|
|
458
|
+
import {
|
|
459
|
+
ToolConfirmationOutcome,
|
|
460
|
+
ToolNames,
|
|
461
|
+
isShellProgressData
|
|
462
|
+
} from "./chunk-YM3SZTH4.js";
|
|
445
463
|
import {
|
|
446
464
|
Storage,
|
|
447
465
|
createDebugLogger,
|
|
448
466
|
getErrorMessage,
|
|
449
467
|
getErrorStatus,
|
|
450
468
|
isSubpath
|
|
451
|
-
} from "./chunk-
|
|
452
|
-
import "./chunk-
|
|
469
|
+
} from "./chunk-OQB4EXO4.js";
|
|
470
|
+
import "./chunk-LU3RXCM7.js";
|
|
453
471
|
import {
|
|
454
472
|
runExitCleanup
|
|
455
|
-
} from "./chunk-
|
|
473
|
+
} from "./chunk-O4OT3DM3.js";
|
|
456
474
|
import "./chunk-75DOP5OR.js";
|
|
457
475
|
import "./chunk-DMTGGOSA.js";
|
|
458
476
|
import "./chunk-YQ3U5MUC.js";
|
|
459
|
-
import "./chunk-
|
|
477
|
+
import "./chunk-THJNPLI4.js";
|
|
460
478
|
import {
|
|
461
479
|
init_esbuild_shims
|
|
462
480
|
} from "./chunk-5O2XNYP6.js";
|
|
@@ -466,7 +484,7 @@ import {
|
|
|
466
484
|
|
|
467
485
|
// packages/cli/src/acp-integration/acpAgent.ts
|
|
468
486
|
init_esbuild_shims();
|
|
469
|
-
import { randomUUID } from "node:crypto";
|
|
487
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
470
488
|
import { performance } from "node:perf_hooks";
|
|
471
489
|
|
|
472
490
|
// packages/cli/src/acp-integration/authMethods.ts
|
|
@@ -844,6 +862,7 @@ __name(isInactiveExtensionSkill, "isInactiveExtensionSkill");
|
|
|
844
862
|
// packages/cli/src/acp-integration/session/Session.ts
|
|
845
863
|
init_esbuild_shims();
|
|
846
864
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
865
|
+
import { randomUUID } from "node:crypto";
|
|
847
866
|
import { existsSync as existsSync2, statSync as statSync2 } from "node:fs";
|
|
848
867
|
import * as os2 from "node:os";
|
|
849
868
|
import * as path3 from "node:path";
|
|
@@ -968,8 +987,23 @@ function supportsHideAlwaysAllow(confirmation) {
|
|
|
968
987
|
}
|
|
969
988
|
__name(supportsHideAlwaysAllow, "supportsHideAlwaysAllow");
|
|
970
989
|
function filterAlwaysAllowOptions(confirmation, options, forceHideAlwaysAllow = false) {
|
|
971
|
-
const hideAlwaysAllow = forceHideAlwaysAllow || supportsHideAlwaysAllow(confirmation) && confirmation.hideAlwaysAllow === true;
|
|
972
|
-
|
|
990
|
+
const hideAlwaysAllow = forceHideAlwaysAllow || confirmation.autoModeFallback !== void 0 || supportsHideAlwaysAllow(confirmation) && confirmation.hideAlwaysAllow === true;
|
|
991
|
+
const visibleOptions = hideAlwaysAllow ? options.filter((option) => option.kind !== "allow_always") : options;
|
|
992
|
+
if (!confirmation.autoModeFallback) return visibleOptions;
|
|
993
|
+
const switchOption = {
|
|
994
|
+
optionId: "proceed_once_and_switch_to_default" /* ProceedOnceAndSwitchToDefault */,
|
|
995
|
+
name: "Switch to Default Mode and allow once (recommended)",
|
|
996
|
+
kind: "allow_once"
|
|
997
|
+
};
|
|
998
|
+
const rejectIndex = visibleOptions.findIndex(
|
|
999
|
+
(option) => option.kind === "reject_once"
|
|
1000
|
+
);
|
|
1001
|
+
if (rejectIndex === -1) return [...visibleOptions, switchOption];
|
|
1002
|
+
return [
|
|
1003
|
+
...visibleOptions.slice(0, rejectIndex),
|
|
1004
|
+
switchOption,
|
|
1005
|
+
...visibleOptions.slice(rejectIndex)
|
|
1006
|
+
];
|
|
973
1007
|
}
|
|
974
1008
|
__name(filterAlwaysAllowOptions, "filterAlwaysAllowOptions");
|
|
975
1009
|
function formatExecPermissionScopeLabel(confirmation) {
|
|
@@ -997,6 +1031,22 @@ function interactionMetaFields(confirmation) {
|
|
|
997
1031
|
__name(interactionMetaFields, "interactionMetaFields");
|
|
998
1032
|
function buildPermissionRequestContent(confirmation) {
|
|
999
1033
|
const content = [];
|
|
1034
|
+
if (confirmation.autoModeFallback) {
|
|
1035
|
+
content.push({
|
|
1036
|
+
type: "content",
|
|
1037
|
+
content: {
|
|
1038
|
+
type: "text",
|
|
1039
|
+
text: confirmation.autoModeFallback.message
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
const warnings = confirmation.type === "exec" || confirmation.type === "edit" ? confirmation.warnings ?? [] : [];
|
|
1044
|
+
for (const warning of warnings) {
|
|
1045
|
+
content.push({
|
|
1046
|
+
type: "content",
|
|
1047
|
+
content: { type: "text", text: warning }
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1000
1050
|
if (confirmation.type === "edit") {
|
|
1001
1051
|
content.push({
|
|
1002
1052
|
type: "diff",
|
|
@@ -1017,6 +1067,56 @@ function buildPermissionRequestContent(confirmation) {
|
|
|
1017
1067
|
return content;
|
|
1018
1068
|
}
|
|
1019
1069
|
__name(buildPermissionRequestContent, "buildPermissionRequestContent");
|
|
1070
|
+
function permissionAbortError(signal) {
|
|
1071
|
+
return signal.reason instanceof Error ? signal.reason : new Error("Permission request was aborted.");
|
|
1072
|
+
}
|
|
1073
|
+
__name(permissionAbortError, "permissionAbortError");
|
|
1074
|
+
function requestPermissionWithAbort(client, params, signal) {
|
|
1075
|
+
if (signal.aborted) {
|
|
1076
|
+
return Promise.reject(permissionAbortError(signal));
|
|
1077
|
+
}
|
|
1078
|
+
return new Promise((resolve5, reject) => {
|
|
1079
|
+
let settled = false;
|
|
1080
|
+
const finish = /* @__PURE__ */ __name((callback) => {
|
|
1081
|
+
if (settled) return;
|
|
1082
|
+
settled = true;
|
|
1083
|
+
signal.removeEventListener("abort", onAbort);
|
|
1084
|
+
callback();
|
|
1085
|
+
}, "finish");
|
|
1086
|
+
const onAbort = /* @__PURE__ */ __name(() => finish(() => reject(permissionAbortError(signal))), "onAbort");
|
|
1087
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
1088
|
+
let request;
|
|
1089
|
+
try {
|
|
1090
|
+
request = client.requestPermission(params);
|
|
1091
|
+
} catch (error) {
|
|
1092
|
+
finish(() => reject(error));
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
request.then(
|
|
1096
|
+
(response) => finish(() => resolve5(response)),
|
|
1097
|
+
(error) => finish(() => reject(error))
|
|
1098
|
+
);
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
__name(requestPermissionWithAbort, "requestPermissionWithAbort");
|
|
1102
|
+
function resolvePermissionOutcome(response, offeredOptions) {
|
|
1103
|
+
if (response.outcome.outcome === "cancelled") {
|
|
1104
|
+
return "cancel" /* Cancel */;
|
|
1105
|
+
}
|
|
1106
|
+
const optionId = response.outcome.optionId;
|
|
1107
|
+
if (!offeredOptions.some((option) => option.optionId === optionId)) {
|
|
1108
|
+
throw new Error(
|
|
1109
|
+
`Permission response selected unoffered option: ${optionId}`
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
if (!Object.values(ToolConfirmationOutcome).includes(
|
|
1113
|
+
optionId
|
|
1114
|
+
)) {
|
|
1115
|
+
throw new Error(`Permission response selected invalid option: ${optionId}`);
|
|
1116
|
+
}
|
|
1117
|
+
return optionId;
|
|
1118
|
+
}
|
|
1119
|
+
__name(resolvePermissionOutcome, "resolvePermissionOutcome");
|
|
1020
1120
|
function toPermissionOptions(confirmation, forceHideAlwaysAllow = false) {
|
|
1021
1121
|
switch (confirmation.type) {
|
|
1022
1122
|
case "edit":
|
|
@@ -1243,9 +1343,13 @@ var SubAgentTracker = class {
|
|
|
1243
1343
|
}, "onConfirm")
|
|
1244
1344
|
};
|
|
1245
1345
|
const { title, locations, kind } = this.toolCallEmitter.resolveToolMetadata(event.name, state?.args);
|
|
1346
|
+
const permissionOptions = toPermissionOptions(fullConfirmationDetails);
|
|
1347
|
+
const offeredPermissionOptions = permissionOptions.map((option) => ({
|
|
1348
|
+
...option
|
|
1349
|
+
}));
|
|
1246
1350
|
const params = {
|
|
1247
1351
|
sessionId: this.ctx.sessionId,
|
|
1248
|
-
options:
|
|
1352
|
+
options: permissionOptions,
|
|
1249
1353
|
toolCall: {
|
|
1250
1354
|
toolCallId: event.callId,
|
|
1251
1355
|
status: "pending",
|
|
@@ -1266,8 +1370,15 @@ var SubAgentTracker = class {
|
|
|
1266
1370
|
}
|
|
1267
1371
|
};
|
|
1268
1372
|
try {
|
|
1269
|
-
const output = await
|
|
1270
|
-
|
|
1373
|
+
const output = await requestPermissionWithAbort(
|
|
1374
|
+
this.client,
|
|
1375
|
+
params,
|
|
1376
|
+
abortSignal
|
|
1377
|
+
);
|
|
1378
|
+
const outcome = resolvePermissionOutcome(
|
|
1379
|
+
output,
|
|
1380
|
+
offeredPermissionOptions
|
|
1381
|
+
);
|
|
1271
1382
|
await event.respond(outcome, {
|
|
1272
1383
|
answers: "answers" in output ? output.answers : void 0
|
|
1273
1384
|
});
|
|
@@ -1859,6 +1970,10 @@ function maskApiKeyForDisplay(apiKey) {
|
|
|
1859
1970
|
return `${trimmed.slice(0, 3)}...${trimmed.slice(-4)}`;
|
|
1860
1971
|
}
|
|
1861
1972
|
__name(maskApiKeyForDisplay, "maskApiKeyForDisplay");
|
|
1973
|
+
function getAbortAwareEndTurnStopReason(signal) {
|
|
1974
|
+
return signal.aborted ? "cancelled" : "end_turn";
|
|
1975
|
+
}
|
|
1976
|
+
__name(getAbortAwareEndTurnStopReason, "getAbortAwareEndTurnStopReason");
|
|
1862
1977
|
var DAEMON_INVALID_TOOL_PARAMS_THRESHOLD = 3;
|
|
1863
1978
|
var PERMISSION_CANCEL_SKIP_MESSAGE = "Skipped because a permission request was cancelled before the user answered; user input is required before continuing.";
|
|
1864
1979
|
var LOOP_DETECTED_SKIP_MESSAGE = "Skipped because loop detection stopped the current turn before this tool call could run.";
|
|
@@ -2310,7 +2425,7 @@ var Session = class {
|
|
|
2310
2425
|
this.client = client;
|
|
2311
2426
|
this.settings = settings;
|
|
2312
2427
|
this.sessionId = id;
|
|
2313
|
-
this.runtimeBaseDir =
|
|
2428
|
+
this.runtimeBaseDir = config.storage.getRuntimeBaseDir();
|
|
2314
2429
|
const todoStopGuardEnabled = this.settings.merged.experimental?.todoStopGuard === true && !this.config.getBareMode() && !this.config.isSafeMode();
|
|
2315
2430
|
this.todoStopGuard = new DaemonTodoStopGuard(todoStopGuardEnabled);
|
|
2316
2431
|
this.todoStopGuardBackgroundBaseline = todoStopGuardEnabled ? this.#captureTodoStopGuardBackgroundBaseline() : {
|
|
@@ -2341,6 +2456,7 @@ var Session = class {
|
|
|
2341
2456
|
* process termination is slow.
|
|
2342
2457
|
*/
|
|
2343
2458
|
pendingPromptCompletion = null;
|
|
2459
|
+
automaticDrainRetry = null;
|
|
2344
2460
|
/**
|
|
2345
2461
|
* Per-turn AbortController for the fire-and-forget follow-up suggestion
|
|
2346
2462
|
* generation. Aborted on the top of the next `prompt()` and on
|
|
@@ -2403,6 +2519,9 @@ var Session = class {
|
|
|
2403
2519
|
// or session reload), which would otherwise execute orphaned cron prompts
|
|
2404
2520
|
// on a session whose registries are already unregistered.
|
|
2405
2521
|
disposed = false;
|
|
2522
|
+
closing = false;
|
|
2523
|
+
closeGateCompletion = null;
|
|
2524
|
+
resolveCloseGate = null;
|
|
2406
2525
|
unsubscribeChatRecordingFailure;
|
|
2407
2526
|
// Modular components
|
|
2408
2527
|
historyReplayer;
|
|
@@ -2637,7 +2756,7 @@ var Session = class {
|
|
|
2637
2756
|
* mount.
|
|
2638
2757
|
*/
|
|
2639
2758
|
startCronScheduler() {
|
|
2640
|
-
this.#
|
|
2759
|
+
this.#startCronSchedulerInRuntime().catch((error) => {
|
|
2641
2760
|
debugLogger6.warn(
|
|
2642
2761
|
`Cron scheduler startup failed [session ${this.sessionId}]: ${error}`
|
|
2643
2762
|
);
|
|
@@ -2646,8 +2765,95 @@ var Session = class {
|
|
|
2646
2765
|
getConfig() {
|
|
2647
2766
|
return this.config;
|
|
2648
2767
|
}
|
|
2768
|
+
async assertCanStartTurn() {
|
|
2769
|
+
if (this.closing) {
|
|
2770
|
+
throw RequestError.invalidParams(void 0, "Session is closing");
|
|
2771
|
+
}
|
|
2772
|
+
try {
|
|
2773
|
+
await this.config.assertCanStartTurn();
|
|
2774
|
+
} catch (error) {
|
|
2775
|
+
if (error instanceof SessionWriterError) {
|
|
2776
|
+
throw new RequestError(error.rpcCode, error.message, {
|
|
2777
|
+
errorKind: error.errorKind
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
throw error;
|
|
2781
|
+
}
|
|
2782
|
+
if (this.closing) {
|
|
2783
|
+
throw RequestError.invalidParams(void 0, "Session is closing");
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2649
2786
|
isIdle() {
|
|
2650
|
-
return !this.
|
|
2787
|
+
return !this.closing && !this.#hasActiveTurn();
|
|
2788
|
+
}
|
|
2789
|
+
#hasActiveTurn() {
|
|
2790
|
+
return Boolean(
|
|
2791
|
+
this.pendingPrompt || this.pendingPromptCompletion || this.cronProcessing || this.cronAbortController || this.cronCompletion || this.notificationProcessing || this.notificationAbortController || this.notificationCompletion
|
|
2792
|
+
);
|
|
2793
|
+
}
|
|
2794
|
+
beginClose() {
|
|
2795
|
+
if (this.closing) {
|
|
2796
|
+
throw RequestError.invalidParams(
|
|
2797
|
+
void 0,
|
|
2798
|
+
"Session close is already in progress"
|
|
2799
|
+
);
|
|
2800
|
+
}
|
|
2801
|
+
this.closing = true;
|
|
2802
|
+
let resolveGate;
|
|
2803
|
+
const completion = new Promise((resolve5) => {
|
|
2804
|
+
resolveGate = resolve5;
|
|
2805
|
+
});
|
|
2806
|
+
this.closeGateCompletion = completion;
|
|
2807
|
+
this.resolveCloseGate = resolveGate;
|
|
2808
|
+
let released = false;
|
|
2809
|
+
return () => {
|
|
2810
|
+
if (released) return;
|
|
2811
|
+
released = true;
|
|
2812
|
+
if (this.closeGateCompletion === completion) {
|
|
2813
|
+
this.closeGateCompletion = null;
|
|
2814
|
+
this.resolveCloseGate = null;
|
|
2815
|
+
}
|
|
2816
|
+
resolveGate();
|
|
2817
|
+
if (this.disposed) return;
|
|
2818
|
+
this.closing = false;
|
|
2819
|
+
void this.#drainCronQueue();
|
|
2820
|
+
void this.#drainNotificationQueue();
|
|
2821
|
+
};
|
|
2822
|
+
}
|
|
2823
|
+
beginCloseIfAvailable() {
|
|
2824
|
+
if (this.disposed) {
|
|
2825
|
+
throw RequestError.invalidParams(void 0, "Session has been disposed");
|
|
2826
|
+
}
|
|
2827
|
+
return this.closing ? null : this.beginClose();
|
|
2828
|
+
}
|
|
2829
|
+
waitForCloseGateToRelease() {
|
|
2830
|
+
return this.closeGateCompletion ?? Promise.resolve();
|
|
2831
|
+
}
|
|
2832
|
+
async waitForActiveTurnsToSettle() {
|
|
2833
|
+
const pending = [
|
|
2834
|
+
this.pendingPromptCompletion,
|
|
2835
|
+
this.cronCompletion,
|
|
2836
|
+
this.notificationCompletion
|
|
2837
|
+
].filter((completion) => completion !== null);
|
|
2838
|
+
await Promise.allSettled(pending);
|
|
2839
|
+
}
|
|
2840
|
+
#deferAutomaticQueueDrainUntilTurnsSettle() {
|
|
2841
|
+
const completions = [
|
|
2842
|
+
this.pendingPromptCompletion,
|
|
2843
|
+
this.cronCompletion,
|
|
2844
|
+
this.notificationCompletion
|
|
2845
|
+
].filter((completion) => completion !== null);
|
|
2846
|
+
if (completions.length === 0) return false;
|
|
2847
|
+
if (this.automaticDrainRetry) return true;
|
|
2848
|
+
const retry = Promise.allSettled(completions).then(() => {
|
|
2849
|
+
if (this.automaticDrainRetry !== retry) return;
|
|
2850
|
+
this.automaticDrainRetry = null;
|
|
2851
|
+
if (this.disposed) return;
|
|
2852
|
+
void this.#drainCronQueue();
|
|
2853
|
+
void this.#drainNotificationQueue();
|
|
2854
|
+
});
|
|
2855
|
+
this.automaticDrainRetry = retry;
|
|
2856
|
+
return true;
|
|
2651
2857
|
}
|
|
2652
2858
|
getTurnCount() {
|
|
2653
2859
|
return this.turn;
|
|
@@ -2657,6 +2863,10 @@ var Session = class {
|
|
|
2657
2863
|
}
|
|
2658
2864
|
dispose() {
|
|
2659
2865
|
this.disposed = true;
|
|
2866
|
+
this.closing = true;
|
|
2867
|
+
this.resolveCloseGate?.();
|
|
2868
|
+
this.resolveCloseGate = null;
|
|
2869
|
+
this.closeGateCompletion = null;
|
|
2660
2870
|
this.todoStopGuardQueuedPromptPriority = false;
|
|
2661
2871
|
this.todoStopGuardDrainAutomaticQueuesWhenIdle = false;
|
|
2662
2872
|
this.todoStopGuard.clearTrust();
|
|
@@ -2673,7 +2883,7 @@ var Session = class {
|
|
|
2673
2883
|
this.cronProcessing = false;
|
|
2674
2884
|
this.cronCompletion = null;
|
|
2675
2885
|
if (this.config.isCronEnabled()) {
|
|
2676
|
-
this
|
|
2886
|
+
this.#stopCronSchedulerInRuntime();
|
|
2677
2887
|
}
|
|
2678
2888
|
this.config.getBackgroundTaskRegistry().setNotificationCallback(void 0);
|
|
2679
2889
|
this.config.getMonitorRegistry().setNotificationCallback(void 0);
|
|
@@ -2757,7 +2967,7 @@ var Session = class {
|
|
|
2757
2967
|
"targetTurnIndex must be a non-negative integer"
|
|
2758
2968
|
);
|
|
2759
2969
|
}
|
|
2760
|
-
if (this.
|
|
2970
|
+
if (this.closing || this.#hasActiveTurn()) {
|
|
2761
2971
|
throw RequestError.invalidParams(
|
|
2762
2972
|
void 0,
|
|
2763
2973
|
"Cannot rewind while a prompt is running"
|
|
@@ -2814,7 +3024,7 @@ var Session = class {
|
|
|
2814
3024
|
return count;
|
|
2815
3025
|
}
|
|
2816
3026
|
restoreHistory(history) {
|
|
2817
|
-
if (this.
|
|
3027
|
+
if (this.closing || this.#hasActiveTurn()) {
|
|
2818
3028
|
throw RequestError.invalidParams(
|
|
2819
3029
|
void 0,
|
|
2820
3030
|
"Cannot restore history while a prompt is running"
|
|
@@ -2888,13 +3098,17 @@ var Session = class {
|
|
|
2888
3098
|
const scheduler = this.config.isCronEnabled() ? this.config.getCronScheduler() : null;
|
|
2889
3099
|
if (scheduler) {
|
|
2890
3100
|
const summary = scheduler.getExitSummary();
|
|
2891
|
-
|
|
3101
|
+
this.#stopCronSchedulerInRuntime();
|
|
2892
3102
|
if (summary) {
|
|
2893
3103
|
await this.messageEmitter.emitAgentMessage(summary);
|
|
2894
3104
|
}
|
|
2895
3105
|
}
|
|
2896
3106
|
}
|
|
2897
3107
|
async prompt(params) {
|
|
3108
|
+
if (this.closing) {
|
|
3109
|
+
throw RequestError.invalidParams(void 0, "Session is closing");
|
|
3110
|
+
}
|
|
3111
|
+
await this.assertCanStartTurn();
|
|
2898
3112
|
const todoStopGuardPreparation = this.#prepareTodoStopGuardForPrompt(params);
|
|
2899
3113
|
this.pendingPrompt?.abort();
|
|
2900
3114
|
const pendingSend = new AbortController();
|
|
@@ -2954,6 +3168,13 @@ var Session = class {
|
|
|
2954
3168
|
void this.#drainNotificationQueue();
|
|
2955
3169
|
this.#maybeEmitFollowupSuggestion(result);
|
|
2956
3170
|
return result;
|
|
3171
|
+
} catch (error) {
|
|
3172
|
+
if (error instanceof SessionWriterError) {
|
|
3173
|
+
throw new RequestError(error.rpcCode, error.message, {
|
|
3174
|
+
errorKind: error.errorKind
|
|
3175
|
+
});
|
|
3176
|
+
}
|
|
3177
|
+
throw error;
|
|
2957
3178
|
} finally {
|
|
2958
3179
|
this.pendingPrompt = null;
|
|
2959
3180
|
const shouldDrainAutomaticQueues = todoStopGuardPreparation.drainSupersededAutomaticQueues || this.todoStopGuardDrainAutomaticQueuesWhenIdle || this.todoStopGuard.blocksUnrelatedAutomaticTurns || this.todoStopGuard.hasCommittedContinuation || this.todoStopGuardQueuedPromptPriority;
|
|
@@ -2962,7 +3183,7 @@ var Session = class {
|
|
|
2962
3183
|
void this.#drainCronQueue();
|
|
2963
3184
|
void this.#drainNotificationQueue();
|
|
2964
3185
|
}
|
|
2965
|
-
void this.#
|
|
3186
|
+
void this.#startCronSchedulerInRuntime();
|
|
2966
3187
|
resolveCompletion();
|
|
2967
3188
|
this.pendingPromptCompletion = null;
|
|
2968
3189
|
}
|
|
@@ -3096,6 +3317,10 @@ var Session = class {
|
|
|
3096
3317
|
this.runtimeBaseDir,
|
|
3097
3318
|
this.config.getWorkingDir(),
|
|
3098
3319
|
async () => {
|
|
3320
|
+
await this.assertCanStartTurn();
|
|
3321
|
+
if (pendingSend.signal.aborted) {
|
|
3322
|
+
return { stopReason: "cancelled" };
|
|
3323
|
+
}
|
|
3099
3324
|
this.turn += 1;
|
|
3100
3325
|
const promptId = this.config.getSessionId() + "########" + this.turn;
|
|
3101
3326
|
const parentContext = extractDaemonTraceContext(params);
|
|
@@ -3162,6 +3387,9 @@ var Session = class {
|
|
|
3162
3387
|
let parts;
|
|
3163
3388
|
let fullTurnModelOverride;
|
|
3164
3389
|
const onFullTurnModel = /* @__PURE__ */ __name((model) => {
|
|
3390
|
+
if (fullTurnModelOverride === model) {
|
|
3391
|
+
return true;
|
|
3392
|
+
}
|
|
3165
3393
|
if (fullTurnModelOverride) {
|
|
3166
3394
|
return false;
|
|
3167
3395
|
}
|
|
@@ -3397,7 +3625,8 @@ ${this.pendingWorktreeNotice}
|
|
|
3397
3625
|
pendingSend.signal,
|
|
3398
3626
|
promptId,
|
|
3399
3627
|
functionCalls,
|
|
3400
|
-
toolLoopState
|
|
3628
|
+
toolLoopState,
|
|
3629
|
+
onFullTurnModel
|
|
3401
3630
|
)
|
|
3402
3631
|
);
|
|
3403
3632
|
if (toolRun.stopAfterPermissionCancel) {
|
|
@@ -3406,7 +3635,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3406
3635
|
toolRun,
|
|
3407
3636
|
pendingSend.signal
|
|
3408
3637
|
);
|
|
3409
|
-
return {
|
|
3638
|
+
return {
|
|
3639
|
+
stopReason: getAbortAwareEndTurnStopReason(
|
|
3640
|
+
pendingSend.signal
|
|
3641
|
+
)
|
|
3642
|
+
};
|
|
3410
3643
|
}
|
|
3411
3644
|
const nextAfterTools = await this.#buildNextMessageAfterToolRun(
|
|
3412
3645
|
toolRun,
|
|
@@ -3420,7 +3653,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3420
3653
|
toolRun,
|
|
3421
3654
|
pendingSend.signal
|
|
3422
3655
|
);
|
|
3423
|
-
return {
|
|
3656
|
+
return {
|
|
3657
|
+
stopReason: getAbortAwareEndTurnStopReason(
|
|
3658
|
+
pendingSend.signal
|
|
3659
|
+
)
|
|
3660
|
+
};
|
|
3424
3661
|
}
|
|
3425
3662
|
}
|
|
3426
3663
|
}
|
|
@@ -3455,6 +3692,9 @@ ${this.pendingWorktreeNotice}
|
|
|
3455
3692
|
let stopHookIterationCount = 0;
|
|
3456
3693
|
let stopHookReasons = [];
|
|
3457
3694
|
const onFullTurnModel = /* @__PURE__ */ __name((model) => {
|
|
3695
|
+
if (modelOverride === model) {
|
|
3696
|
+
return true;
|
|
3697
|
+
}
|
|
3458
3698
|
if (modelOverride) {
|
|
3459
3699
|
return false;
|
|
3460
3700
|
}
|
|
@@ -3465,7 +3705,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3465
3705
|
while (true) {
|
|
3466
3706
|
if (pendingSend.signal.aborted) {
|
|
3467
3707
|
this.todoStopGuard.suspend();
|
|
3468
|
-
return { stopReason: "
|
|
3708
|
+
return { stopReason: "cancelled" };
|
|
3469
3709
|
}
|
|
3470
3710
|
if (this.config.getApprovalMode() === "plan" /* PLAN */) {
|
|
3471
3711
|
this.#clearTodoStopGuardTrustAndDrainAutomaticQueues();
|
|
@@ -3568,7 +3808,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3568
3808
|
await this.messageEmitter.emitAgentMessage(stopOutput.systemMessage);
|
|
3569
3809
|
}
|
|
3570
3810
|
if (stopOutput?.isBlockingDecision() || stopOutput?.shouldStopExecution()) {
|
|
3571
|
-
externalReason = stopOutput
|
|
3811
|
+
externalReason = getStopHookContinuationReason(stopOutput);
|
|
3572
3812
|
stopHookIterationCount++;
|
|
3573
3813
|
stopHookReasons = [...stopHookReasons, externalReason];
|
|
3574
3814
|
stopHookCount = response.stopHookCount ?? 1;
|
|
@@ -3907,7 +4147,8 @@ ${this.pendingWorktreeNotice}
|
|
|
3907
4147
|
pendingSend.signal,
|
|
3908
4148
|
toolPromptId,
|
|
3909
4149
|
functionCalls,
|
|
3910
|
-
toolLoopState
|
|
4150
|
+
toolLoopState,
|
|
4151
|
+
options.onFullTurnModel
|
|
3911
4152
|
)
|
|
3912
4153
|
);
|
|
3913
4154
|
if (toolRun.stopAfterPermissionCancel || toolRun.loopDetected) {
|
|
@@ -3915,7 +4156,7 @@ ${this.pendingWorktreeNotice}
|
|
|
3915
4156
|
await this.#preserveStoppedToolRun(toolRun, pendingSend.signal);
|
|
3916
4157
|
return {
|
|
3917
4158
|
kind: "terminal",
|
|
3918
|
-
stopReason:
|
|
4159
|
+
stopReason: getAbortAwareEndTurnStopReason(pendingSend.signal),
|
|
3919
4160
|
...supersededAutomaticContinuation ? { supersededAutomaticContinuation: true } : {}
|
|
3920
4161
|
};
|
|
3921
4162
|
}
|
|
@@ -4164,13 +4405,18 @@ ${this.pendingWorktreeNotice}
|
|
|
4164
4405
|
}
|
|
4165
4406
|
}
|
|
4166
4407
|
async #preserveStoppedToolRun(toolRun, abortSignal) {
|
|
4408
|
+
const midTurnParts = abortSignal.aborted ? await this.#buildMidTurnParts(
|
|
4409
|
+
this.#takeRecoveredMidTurnMessages(),
|
|
4410
|
+
abortSignal,
|
|
4411
|
+
{ preserveFallbackOnAbort: true }
|
|
4412
|
+
) : await this.#drainMidTurnUserMessages(abortSignal);
|
|
4167
4413
|
this.#preserveUnsentMessageHistory(
|
|
4168
4414
|
{
|
|
4169
4415
|
role: "user",
|
|
4170
4416
|
parts: [
|
|
4171
4417
|
...toolRun.parts,
|
|
4172
4418
|
...toolRun.loopDetected ? [{ text: LOOP_DETECTED_CONTEXT_MESSAGE }] : [],
|
|
4173
|
-
...
|
|
4419
|
+
...midTurnParts
|
|
4174
4420
|
]
|
|
4175
4421
|
},
|
|
4176
4422
|
true
|
|
@@ -4285,11 +4531,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4285
4531
|
const recovered = this.#takeRecoveredMidTurnMessages();
|
|
4286
4532
|
if (this.midTurnDrainUnavailable) {
|
|
4287
4533
|
return {
|
|
4288
|
-
parts: await this.#buildMidTurnParts(
|
|
4289
|
-
recovered,
|
|
4290
|
-
abortSignal,
|
|
4291
|
-
options.onFullTurnModel
|
|
4292
|
-
),
|
|
4534
|
+
parts: await this.#buildMidTurnParts(recovered, abortSignal, options),
|
|
4293
4535
|
hasQueuedPrompt: false
|
|
4294
4536
|
};
|
|
4295
4537
|
}
|
|
@@ -4317,7 +4559,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4317
4559
|
parts: await this.#buildMidTurnParts(
|
|
4318
4560
|
[...recovered, ...parseMidTurnDrainResponse(response)],
|
|
4319
4561
|
abortSignal,
|
|
4320
|
-
options
|
|
4562
|
+
options
|
|
4321
4563
|
),
|
|
4322
4564
|
hasQueuedPrompt: isRecord2(response) && response["hasQueuedPrompt"] === true
|
|
4323
4565
|
};
|
|
@@ -4337,11 +4579,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4337
4579
|
`Mid-turn queue drain ${isPermanentError ? "permanently " : ""}unavailable [session ${this.sessionId}]: ${errorMessage}`
|
|
4338
4580
|
);
|
|
4339
4581
|
return {
|
|
4340
|
-
parts: await this.#buildMidTurnParts(
|
|
4341
|
-
recovered,
|
|
4342
|
-
abortSignal,
|
|
4343
|
-
options.onFullTurnModel
|
|
4344
|
-
),
|
|
4582
|
+
parts: await this.#buildMidTurnParts(recovered, abortSignal, options),
|
|
4345
4583
|
hasQueuedPrompt: false
|
|
4346
4584
|
};
|
|
4347
4585
|
}
|
|
@@ -4401,7 +4639,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4401
4639
|
* happens on injection (here), so a message recovered from an earlier
|
|
4402
4640
|
* timed-out drain is still recorded exactly once.
|
|
4403
4641
|
*/
|
|
4404
|
-
async #buildMidTurnParts(messages, abortSignal,
|
|
4642
|
+
async #buildMidTurnParts(messages, abortSignal, options = {}) {
|
|
4405
4643
|
const parts = [];
|
|
4406
4644
|
for (const message of messages) {
|
|
4407
4645
|
const displayText = message.kind === "text" ? message.message : message.displayText;
|
|
@@ -4411,13 +4649,19 @@ ${this.pendingWorktreeNotice}
|
|
|
4411
4649
|
abortSignal,
|
|
4412
4650
|
MID_TURN_QUEUE_RESOLVE_TIMEOUT_MS,
|
|
4413
4651
|
(signal) => this.#resolvePrompt(message.content, signal, {
|
|
4414
|
-
onFullTurnModel
|
|
4652
|
+
onFullTurnModel: options.onFullTurnModel
|
|
4415
4653
|
})
|
|
4416
4654
|
);
|
|
4417
4655
|
} catch (messageError) {
|
|
4418
|
-
if (abortSignal.aborted)
|
|
4419
|
-
|
|
4420
|
-
|
|
4656
|
+
if (abortSignal.aborted && !options.preserveFallbackOnAbort) {
|
|
4657
|
+
return parts;
|
|
4658
|
+
}
|
|
4659
|
+
if (!abortSignal.aborted) {
|
|
4660
|
+
const errorMessage = this.#formatError(messageError);
|
|
4661
|
+
debugLogger6.warn(
|
|
4662
|
+
`Failed to resolve mid-turn message: ${errorMessage}`
|
|
4663
|
+
);
|
|
4664
|
+
}
|
|
4421
4665
|
rawParts = [{ text: displayText }];
|
|
4422
4666
|
if (message.kind === "structured" && hasInlineMediaContentBlock(message.content)) {
|
|
4423
4667
|
rawParts.push({ text: MID_TURN_ATTACHMENT_PROCESSING_FAILURE_TEXT });
|
|
@@ -4459,6 +4703,20 @@ ${this.pendingWorktreeNotice}
|
|
|
4459
4703
|
void this.#drainCronQueue();
|
|
4460
4704
|
});
|
|
4461
4705
|
}
|
|
4706
|
+
#startCronSchedulerInRuntime() {
|
|
4707
|
+
return Storage.runWithRuntimeBaseDir(
|
|
4708
|
+
this.runtimeBaseDir,
|
|
4709
|
+
this.config.getWorkingDir(),
|
|
4710
|
+
() => this.#startCronSchedulerIfNeeded()
|
|
4711
|
+
);
|
|
4712
|
+
}
|
|
4713
|
+
#stopCronSchedulerInRuntime() {
|
|
4714
|
+
Storage.runWithRuntimeBaseDir(
|
|
4715
|
+
this.runtimeBaseDir,
|
|
4716
|
+
this.config.getWorkingDir(),
|
|
4717
|
+
() => this.config.getCronScheduler().stop()
|
|
4718
|
+
);
|
|
4719
|
+
}
|
|
4462
4720
|
#enqueueCronPrompt(item) {
|
|
4463
4721
|
if ((this.todoStopGuard.blocksUnrelatedAutomaticTurns || this.todoStopGuardQueuedPromptPriority) && !this.#cronContinuesTodoStopGuardWorkChain(item)) {
|
|
4464
4722
|
if (item.taskId) {
|
|
@@ -4489,10 +4747,24 @@ ${this.pendingWorktreeNotice}
|
|
|
4489
4747
|
*/
|
|
4490
4748
|
async #drainCronQueue() {
|
|
4491
4749
|
if (this.disposed) return;
|
|
4750
|
+
if (this.closing) return;
|
|
4492
4751
|
if (this.cronProcessing) return;
|
|
4493
4752
|
if (this.pendingPrompt) return;
|
|
4494
4753
|
if (this.notificationProcessing) return;
|
|
4754
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4495
4755
|
if (this.#nextCronQueueIndex() < 0) return;
|
|
4756
|
+
try {
|
|
4757
|
+
await this.assertCanStartTurn();
|
|
4758
|
+
} catch (error) {
|
|
4759
|
+
debugLogger6.warn(
|
|
4760
|
+
`Cron turn rejected [session ${this.sessionId}]: ${error instanceof Error ? error.message : String(error)}`
|
|
4761
|
+
);
|
|
4762
|
+
return;
|
|
4763
|
+
}
|
|
4764
|
+
if (this.disposed || this.closing || this.cronProcessing || this.pendingPrompt || this.notificationProcessing || this.#nextCronQueueIndex() < 0) {
|
|
4765
|
+
return;
|
|
4766
|
+
}
|
|
4767
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4496
4768
|
this.cronProcessing = true;
|
|
4497
4769
|
let resolveCompletion;
|
|
4498
4770
|
this.cronCompletion = new Promise((resolve5) => {
|
|
@@ -4514,7 +4786,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4514
4786
|
if (this.config.isCronEnabled()) {
|
|
4515
4787
|
const scheduler = this.config.getCronScheduler();
|
|
4516
4788
|
if (!scheduler.hasPendingWork) {
|
|
4517
|
-
|
|
4789
|
+
this.#stopCronSchedulerInRuntime();
|
|
4518
4790
|
}
|
|
4519
4791
|
}
|
|
4520
4792
|
}
|
|
@@ -4581,6 +4853,8 @@ ${this.pendingWorktreeNotice}
|
|
|
4581
4853
|
async () => {
|
|
4582
4854
|
let turnCount = 0;
|
|
4583
4855
|
try {
|
|
4856
|
+
await this.assertCanStartTurn();
|
|
4857
|
+
if (ac.signal.aborted) return;
|
|
4584
4858
|
const loopMode = detectLoopSentinel(prompt);
|
|
4585
4859
|
const autonomousMode = loopMode ? null : detectAutonomousSentinel(prompt);
|
|
4586
4860
|
let loopTick = null;
|
|
@@ -4910,12 +5184,26 @@ ${this.pendingWorktreeNotice}
|
|
|
4910
5184
|
}
|
|
4911
5185
|
async #drainNotificationQueue() {
|
|
4912
5186
|
if (this.disposed) return;
|
|
5187
|
+
if (this.closing) return;
|
|
4913
5188
|
if (this.notificationProcessing) return;
|
|
4914
5189
|
if (this.pendingPrompt || this.cronProcessing || this.cronAbortController) {
|
|
4915
5190
|
return;
|
|
4916
5191
|
}
|
|
5192
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4917
5193
|
if (this.notificationQueue.length === 0) return;
|
|
4918
5194
|
if (this.#nextNotificationQueueIndex() < 0) return;
|
|
5195
|
+
try {
|
|
5196
|
+
await this.assertCanStartTurn();
|
|
5197
|
+
} catch (error) {
|
|
5198
|
+
debugLogger6.warn(
|
|
5199
|
+
`Notification turn rejected [session ${this.sessionId}]: ${error instanceof Error ? error.message : String(error)}`
|
|
5200
|
+
);
|
|
5201
|
+
return;
|
|
5202
|
+
}
|
|
5203
|
+
if (this.disposed || this.closing || this.notificationProcessing || this.pendingPrompt || this.cronProcessing || this.cronAbortController || this.#nextNotificationQueueIndex() < 0) {
|
|
5204
|
+
return;
|
|
5205
|
+
}
|
|
5206
|
+
if (this.#deferAutomaticQueueDrainUntilTurnsSettle()) return;
|
|
4919
5207
|
this.notificationProcessing = true;
|
|
4920
5208
|
let resolveCompletion;
|
|
4921
5209
|
this.notificationCompletion = new Promise((resolve5) => {
|
|
@@ -4965,6 +5253,8 @@ ${this.pendingWorktreeNotice}
|
|
|
4965
5253
|
);
|
|
4966
5254
|
const promptId = this.config.getSessionId() + "########notification" + Date.now();
|
|
4967
5255
|
try {
|
|
5256
|
+
await this.assertCanStartTurn();
|
|
5257
|
+
if (ac.signal.aborted) return;
|
|
4968
5258
|
await this.#emitBackgroundNotificationDisplay(item);
|
|
4969
5259
|
const notificationParts = [{ text: item.modelText }];
|
|
4970
5260
|
this.config.getChatRecordingService()?.recordNotification(notificationParts, item.displayText);
|
|
@@ -5094,7 +5384,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5094
5384
|
if (toolRun.stopAfterPermissionCancel) {
|
|
5095
5385
|
this.todoStopGuard.suspend();
|
|
5096
5386
|
await this.#preserveStoppedToolRun(toolRun, ac.signal);
|
|
5097
|
-
await this.#emitBackgroundNotificationEndTurn(
|
|
5387
|
+
await this.#emitBackgroundNotificationEndTurn(
|
|
5388
|
+
getAbortAwareEndTurnStopReason(ac.signal)
|
|
5389
|
+
);
|
|
5098
5390
|
return;
|
|
5099
5391
|
}
|
|
5100
5392
|
const nextAfterTools = await this.#buildNextMessageAfterToolRun(
|
|
@@ -5105,7 +5397,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5105
5397
|
if (toolRun.loopDetected) {
|
|
5106
5398
|
this.todoStopGuard.suspend();
|
|
5107
5399
|
await this.#preserveStoppedToolRun(toolRun, ac.signal);
|
|
5108
|
-
await this.#emitBackgroundNotificationEndTurn(
|
|
5400
|
+
await this.#emitBackgroundNotificationEndTurn(
|
|
5401
|
+
getAbortAwareEndTurnStopReason(ac.signal)
|
|
5402
|
+
);
|
|
5109
5403
|
return;
|
|
5110
5404
|
}
|
|
5111
5405
|
}
|
|
@@ -5123,7 +5417,9 @@ ${this.pendingWorktreeNotice}
|
|
|
5123
5417
|
false
|
|
5124
5418
|
)).stopReason;
|
|
5125
5419
|
}
|
|
5126
|
-
await this.#emitBackgroundNotificationEndTurn(
|
|
5420
|
+
await this.#emitBackgroundNotificationEndTurn(
|
|
5421
|
+
ac.signal.aborted ? "cancelled" : stopReason
|
|
5422
|
+
);
|
|
5127
5423
|
} catch (error) {
|
|
5128
5424
|
if (ac.signal.aborted) {
|
|
5129
5425
|
this.todoStopGuard.suspend();
|
|
@@ -5414,10 +5710,48 @@ ${this.pendingWorktreeNotice}
|
|
|
5414
5710
|
* sequential batch to preserve the implicit ordering the model may rely
|
|
5415
5711
|
* on. Response-part ordering matches the original `functionCalls` order.
|
|
5416
5712
|
*/
|
|
5417
|
-
async runToolCalls(abortSignal, promptId, functionCalls, toolLoopState) {
|
|
5713
|
+
async runToolCalls(abortSignal, promptId, functionCalls, toolLoopState, onFullTurnModel) {
|
|
5418
5714
|
const dedupedFunctionCalls = dedupeToolCallsById(functionCalls);
|
|
5715
|
+
const generatedCallIdBase = randomUUID();
|
|
5716
|
+
const executionCallIds = new Map(
|
|
5717
|
+
dedupedFunctionCalls.map((functionCall, index) => [
|
|
5718
|
+
functionCall,
|
|
5719
|
+
functionCall.id ?? `${functionCall.name ?? "tool"}-${generatedCallIdBase}-${index}`
|
|
5720
|
+
])
|
|
5721
|
+
);
|
|
5722
|
+
const pendingToolResultRecords = [];
|
|
5723
|
+
let toolResultRecordSequence = 0;
|
|
5724
|
+
const queueToolResultRecord = /* @__PURE__ */ __name((fc, record) => {
|
|
5725
|
+
pendingToolResultRecords.push({
|
|
5726
|
+
...record,
|
|
5727
|
+
ordinal: dedupedFunctionCalls.indexOf(fc),
|
|
5728
|
+
sequence: toolResultRecordSequence++
|
|
5729
|
+
});
|
|
5730
|
+
}, "queueToolResultRecord");
|
|
5731
|
+
const finalizeRunToolResult = /* @__PURE__ */ __name(async (result) => {
|
|
5732
|
+
if (pendingToolResultRecords.length === 0) return result;
|
|
5733
|
+
const orderedRecords = [...pendingToolResultRecords].sort(
|
|
5734
|
+
(left, right) => left.ordinal - right.ordinal || left.sequence - right.sequence
|
|
5735
|
+
);
|
|
5736
|
+
const finalized = await finalizeToolResponses(
|
|
5737
|
+
this.config,
|
|
5738
|
+
orderedRecords.map((record) => ({
|
|
5739
|
+
callId: record.callId,
|
|
5740
|
+
toolName: record.toolName,
|
|
5741
|
+
responseParts: record.responseParts,
|
|
5742
|
+
persistedOutputFiles: record.persistedOutputFiles
|
|
5743
|
+
}))
|
|
5744
|
+
);
|
|
5745
|
+
orderedRecords.forEach((record, index) => {
|
|
5746
|
+
this.config.getChatRecordingService()?.recordToolResult(finalized[index].responseParts, record.metadata);
|
|
5747
|
+
});
|
|
5748
|
+
return {
|
|
5749
|
+
...result,
|
|
5750
|
+
parts: finalized.flatMap((entry) => entry.responseParts)
|
|
5751
|
+
};
|
|
5752
|
+
}, "finalizeRunToolResult");
|
|
5419
5753
|
let skippedToolCallCounter = 0;
|
|
5420
|
-
const recordSkippedToolCall = /* @__PURE__ */ __name(async (fc, message = PERMISSION_CANCEL_SKIP_MESSAGE, emitStart = true) => {
|
|
5754
|
+
const recordSkippedToolCall = /* @__PURE__ */ __name(async (fc, message = PERMISSION_CANCEL_SKIP_MESSAGE, emitStart = true, errorType) => {
|
|
5421
5755
|
const toolName = fc.name ?? "unknown_tool";
|
|
5422
5756
|
const callId = fc.id ?? `${toolName}-skip-${++skippedToolCallCounter}`;
|
|
5423
5757
|
const part = {
|
|
@@ -5429,12 +5763,17 @@ ${this.pendingWorktreeNotice}
|
|
|
5429
5763
|
};
|
|
5430
5764
|
const error = new Error(message);
|
|
5431
5765
|
try {
|
|
5432
|
-
|
|
5766
|
+
queueToolResultRecord(fc, {
|
|
5433
5767
|
callId,
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5768
|
+
toolName,
|
|
5769
|
+
responseParts: [part],
|
|
5770
|
+
metadata: {
|
|
5771
|
+
callId,
|
|
5772
|
+
status: "error",
|
|
5773
|
+
resultDisplay: void 0,
|
|
5774
|
+
error,
|
|
5775
|
+
errorType
|
|
5776
|
+
}
|
|
5438
5777
|
});
|
|
5439
5778
|
if (emitStart) {
|
|
5440
5779
|
await this.toolCallEmitter.emitStart({
|
|
@@ -5456,7 +5795,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5456
5795
|
toolLoopState,
|
|
5457
5796
|
dedupedFunctionCalls.length
|
|
5458
5797
|
)) {
|
|
5459
|
-
return {
|
|
5798
|
+
return await finalizeRunToolResult({
|
|
5460
5799
|
parts: await Promise.all(
|
|
5461
5800
|
dedupedFunctionCalls.map(
|
|
5462
5801
|
(fc) => recordSkippedToolCall(fc, LOOP_DETECTED_SKIP_MESSAGE, false)
|
|
@@ -5464,7 +5803,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5464
5803
|
),
|
|
5465
5804
|
stopAfterPermissionCancel: false,
|
|
5466
5805
|
loopDetected: true
|
|
5467
|
-
};
|
|
5806
|
+
});
|
|
5468
5807
|
}
|
|
5469
5808
|
const batches = [];
|
|
5470
5809
|
const handledProviderToolCallIds = new Set(
|
|
@@ -5481,13 +5820,13 @@ ${this.pendingWorktreeNotice}
|
|
|
5481
5820
|
debugLogger6.debug(
|
|
5482
5821
|
`[Session.runToolCalls] Dropping batch after repeated duplicate provider tool-call id: ${providerCallId} (tool: ${repeatedDuplicateCall.name ?? "unknown_tool"})`
|
|
5483
5822
|
);
|
|
5484
|
-
return {
|
|
5823
|
+
return await finalizeRunToolResult({
|
|
5485
5824
|
parts: [],
|
|
5486
5825
|
stopAfterPermissionCancel: false,
|
|
5487
5826
|
repeatedDuplicateProviderToolCall: true
|
|
5488
|
-
};
|
|
5827
|
+
});
|
|
5489
5828
|
}
|
|
5490
|
-
const pushDuplicateBatch = /* @__PURE__ */ __name((request) => {
|
|
5829
|
+
const pushDuplicateBatch = /* @__PURE__ */ __name((fc, request) => {
|
|
5491
5830
|
const providerCallId = request.providerCallId ?? request.callId;
|
|
5492
5831
|
markDuplicateProviderToolCallResponseSent(
|
|
5493
5832
|
providerCallId,
|
|
@@ -5497,7 +5836,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5497
5836
|
debugLogger6.debug(
|
|
5498
5837
|
`[Session.runToolCalls] Suppressing duplicate provider tool-call id: ${providerCallId} (tool: ${request.name})`
|
|
5499
5838
|
);
|
|
5500
|
-
batches.push({ kind: "duplicate", request, response });
|
|
5839
|
+
batches.push({ kind: "duplicate", fc, request, response });
|
|
5501
5840
|
}, "pushDuplicateBatch");
|
|
5502
5841
|
const emitDuplicateBatch = /* @__PURE__ */ __name(async (batch) => {
|
|
5503
5842
|
const { request, response } = batch;
|
|
@@ -5534,20 +5873,26 @@ ${this.pendingWorktreeNotice}
|
|
|
5534
5873
|
success: false
|
|
5535
5874
|
});
|
|
5536
5875
|
}
|
|
5537
|
-
|
|
5876
|
+
queueToolResultRecord(batch.fc, {
|
|
5538
5877
|
callId: response.callId,
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5878
|
+
toolName: request.name,
|
|
5879
|
+
responseParts: response.responseParts,
|
|
5880
|
+
persistedOutputFiles: response.persistedOutputFiles,
|
|
5881
|
+
metadata: {
|
|
5882
|
+
callId: response.callId,
|
|
5883
|
+
status: "error",
|
|
5884
|
+
resultDisplay: response.resultDisplay,
|
|
5885
|
+
error: response.error,
|
|
5886
|
+
errorType: response.errorType
|
|
5887
|
+
}
|
|
5543
5888
|
});
|
|
5544
5889
|
}, "emitDuplicateBatch");
|
|
5545
5890
|
for (const fc of dedupedFunctionCalls) {
|
|
5546
5891
|
const providerCallId = getProviderToolCallId(fc) ?? fc.id;
|
|
5547
5892
|
if (providerCallId) {
|
|
5548
5893
|
if (handledProviderToolCallIds.has(providerCallId)) {
|
|
5549
|
-
const callId =
|
|
5550
|
-
pushDuplicateBatch({
|
|
5894
|
+
const callId = executionCallIds.get(fc);
|
|
5895
|
+
pushDuplicateBatch(fc, {
|
|
5551
5896
|
callId,
|
|
5552
5897
|
providerCallId,
|
|
5553
5898
|
name: fc.name ?? "unknown_tool",
|
|
@@ -5567,6 +5912,13 @@ ${this.pendingWorktreeNotice}
|
|
|
5567
5912
|
batches.push({ kind: "execute", concurrent: isAgent, calls: [fc] });
|
|
5568
5913
|
}
|
|
5569
5914
|
}
|
|
5915
|
+
const executableCalls = batches.flatMap(
|
|
5916
|
+
(batch) => batch.kind === "execute" ? batch.calls : []
|
|
5917
|
+
);
|
|
5918
|
+
const planModeEntryBoundaryIndex = findPlanModeEntryBatchBoundaryIndex(
|
|
5919
|
+
executableCalls.map((call) => call.name)
|
|
5920
|
+
);
|
|
5921
|
+
const planModeEntryBoundary = planModeEntryBoundaryIndex === void 0 ? void 0 : executableCalls[planModeEntryBoundaryIndex];
|
|
5570
5922
|
const appendSkippedAfter = /* @__PURE__ */ __name(async (parts2, fc, message = PERMISSION_CANCEL_SKIP_MESSAGE) => {
|
|
5571
5923
|
const startIndex = dedupedFunctionCalls.indexOf(fc) + 1;
|
|
5572
5924
|
for (const remainingCall of dedupedFunctionCalls.slice(startIndex)) {
|
|
@@ -5633,7 +5985,10 @@ ${this.pendingWorktreeNotice}
|
|
|
5633
5985
|
calls[i],
|
|
5634
5986
|
onStopAfterPermissionCancel,
|
|
5635
5987
|
toolLoopState,
|
|
5636
|
-
recordSkippedToolCall
|
|
5988
|
+
recordSkippedToolCall,
|
|
5989
|
+
queueToolResultRecord,
|
|
5990
|
+
executionCallIds.get(calls[i]),
|
|
5991
|
+
onFullTurnModel
|
|
5637
5992
|
);
|
|
5638
5993
|
results[i] = r;
|
|
5639
5994
|
if (r.loopDetected) {
|
|
@@ -5665,7 +6020,10 @@ ${this.pendingWorktreeNotice}
|
|
|
5665
6020
|
calls[idx],
|
|
5666
6021
|
onStopAfterPermissionCancel,
|
|
5667
6022
|
toolLoopState,
|
|
5668
|
-
recordSkippedToolCall
|
|
6023
|
+
recordSkippedToolCall,
|
|
6024
|
+
queueToolResultRecord,
|
|
6025
|
+
executionCallIds.get(calls[idx]),
|
|
6026
|
+
onFullTurnModel
|
|
5669
6027
|
).then((r) => {
|
|
5670
6028
|
results[idx] = r;
|
|
5671
6029
|
}).finally(() => {
|
|
@@ -5704,6 +6062,19 @@ ${this.pendingWorktreeNotice}
|
|
|
5704
6062
|
parts.push(...batch.response.responseParts);
|
|
5705
6063
|
continue;
|
|
5706
6064
|
}
|
|
6065
|
+
if (planModeEntryBoundary && !batch.calls.includes(planModeEntryBoundary)) {
|
|
6066
|
+
for (const fc of batch.calls) {
|
|
6067
|
+
parts.push(
|
|
6068
|
+
await recordSkippedToolCall(
|
|
6069
|
+
fc,
|
|
6070
|
+
PLAN_MODE_ENTRY_SIBLING_SKIP_MESSAGE,
|
|
6071
|
+
true,
|
|
6072
|
+
"execution_denied" /* EXECUTION_DENIED */
|
|
6073
|
+
)
|
|
6074
|
+
);
|
|
6075
|
+
}
|
|
6076
|
+
continue;
|
|
6077
|
+
}
|
|
5707
6078
|
if (batch.concurrent && batch.calls.length > 1) {
|
|
5708
6079
|
const batchAbortController = new AbortController();
|
|
5709
6080
|
let batchStopAfterPermissionCancel = false;
|
|
@@ -5747,24 +6118,24 @@ ${this.pendingWorktreeNotice}
|
|
|
5747
6118
|
batch.calls[batch.calls.length - 1],
|
|
5748
6119
|
LOOP_DETECTED_SKIP_MESSAGE
|
|
5749
6120
|
);
|
|
5750
|
-
return {
|
|
6121
|
+
return await finalizeRunToolResult({
|
|
5751
6122
|
parts,
|
|
5752
6123
|
stopAfterPermissionCancel: false,
|
|
5753
6124
|
loopDetected: true,
|
|
5754
6125
|
memoryWriteCandidates
|
|
5755
|
-
};
|
|
6126
|
+
});
|
|
5756
6127
|
}
|
|
5757
6128
|
if (shouldStop) {
|
|
5758
6129
|
await appendSkippedAfter(
|
|
5759
6130
|
parts,
|
|
5760
6131
|
batch.calls[batch.calls.length - 1]
|
|
5761
6132
|
);
|
|
5762
|
-
return {
|
|
6133
|
+
return await finalizeRunToolResult({
|
|
5763
6134
|
parts,
|
|
5764
6135
|
stopAfterPermissionCancel: true,
|
|
5765
6136
|
repeatedDuplicateProviderToolCall: false,
|
|
5766
6137
|
memoryWriteCandidates
|
|
5767
|
-
};
|
|
6138
|
+
});
|
|
5768
6139
|
}
|
|
5769
6140
|
} else {
|
|
5770
6141
|
for (const fc of batch.calls) {
|
|
@@ -5774,37 +6145,40 @@ ${this.pendingWorktreeNotice}
|
|
|
5774
6145
|
fc,
|
|
5775
6146
|
void 0,
|
|
5776
6147
|
toolLoopState,
|
|
5777
|
-
recordSkippedToolCall
|
|
6148
|
+
recordSkippedToolCall,
|
|
6149
|
+
queueToolResultRecord,
|
|
6150
|
+
executionCallIds.get(fc),
|
|
6151
|
+
onFullTurnModel
|
|
5778
6152
|
);
|
|
5779
6153
|
parts.push(...r.parts);
|
|
5780
6154
|
collectMemoryWriteCandidates(r);
|
|
5781
6155
|
if (r.loopDetected) {
|
|
5782
6156
|
await appendSkippedAfter(parts, fc, LOOP_DETECTED_SKIP_MESSAGE);
|
|
5783
|
-
return {
|
|
6157
|
+
return await finalizeRunToolResult({
|
|
5784
6158
|
parts,
|
|
5785
6159
|
stopAfterPermissionCancel: false,
|
|
5786
6160
|
loopDetected: true,
|
|
5787
6161
|
memoryWriteCandidates
|
|
5788
|
-
};
|
|
6162
|
+
});
|
|
5789
6163
|
}
|
|
5790
6164
|
if (r.stopAfterPermissionCancel) {
|
|
5791
6165
|
await appendSkippedAfter(parts, fc);
|
|
5792
|
-
return {
|
|
6166
|
+
return await finalizeRunToolResult({
|
|
5793
6167
|
parts,
|
|
5794
6168
|
stopAfterPermissionCancel: true,
|
|
5795
6169
|
repeatedDuplicateProviderToolCall: false,
|
|
5796
6170
|
memoryWriteCandidates
|
|
5797
|
-
};
|
|
6171
|
+
});
|
|
5798
6172
|
}
|
|
5799
6173
|
}
|
|
5800
6174
|
}
|
|
5801
6175
|
}
|
|
5802
|
-
return {
|
|
6176
|
+
return await finalizeRunToolResult({
|
|
5803
6177
|
parts,
|
|
5804
6178
|
stopAfterPermissionCancel: false,
|
|
5805
6179
|
repeatedDuplicateProviderToolCall: false,
|
|
5806
6180
|
memoryWriteCandidates
|
|
5807
|
-
};
|
|
6181
|
+
});
|
|
5808
6182
|
} finally {
|
|
5809
6183
|
await refreshMemoryIfNeeded();
|
|
5810
6184
|
}
|
|
@@ -5839,8 +6213,8 @@ ${this.pendingWorktreeNotice}
|
|
|
5839
6213
|
}
|
|
5840
6214
|
return reminders;
|
|
5841
6215
|
}
|
|
5842
|
-
async runTool(abortSignal, promptId, fc, onStopAfterPermissionCancel, toolLoopState, recordSkippedToolCall) {
|
|
5843
|
-
const callId = fc.id ?? `${fc.name}-${Date.now()}`;
|
|
6216
|
+
async runTool(abortSignal, promptId, fc, onStopAfterPermissionCancel, toolLoopState, recordSkippedToolCall, queueToolResultRecord, generatedCallId, onFullTurnModel) {
|
|
6217
|
+
const callId = fc.id ?? generatedCallId ?? `${fc.name}-${Date.now()}`;
|
|
5844
6218
|
let args = fc.args ?? {};
|
|
5845
6219
|
if (toolLoopState?.loopDetected) {
|
|
5846
6220
|
return {
|
|
@@ -5902,12 +6276,17 @@ ${this.pendingWorktreeNotice}
|
|
|
5902
6276
|
await this.toolCallEmitter.emitError(callId, toolName2, error);
|
|
5903
6277
|
}
|
|
5904
6278
|
const errorParts = errorResponse(error);
|
|
5905
|
-
|
|
6279
|
+
queueToolResultRecord?.(fc, {
|
|
5906
6280
|
callId,
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
6281
|
+
toolName: toolName2,
|
|
6282
|
+
responseParts: errorParts,
|
|
6283
|
+
metadata: {
|
|
6284
|
+
callId,
|
|
6285
|
+
status: "error",
|
|
6286
|
+
resultDisplay: void 0,
|
|
6287
|
+
error,
|
|
6288
|
+
errorType: void 0
|
|
6289
|
+
}
|
|
5911
6290
|
});
|
|
5912
6291
|
const loopDetected = opts?.recordInvalidToolParams === true && !activeToolAbortSignal.aborted && !opts?.stopAfterPermissionCancel && recordDaemonInvalidToolParams(
|
|
5913
6292
|
this.config,
|
|
@@ -5937,19 +6316,21 @@ ${this.pendingWorktreeNotice}
|
|
|
5937
6316
|
{ recordInvalidToolParams: true }
|
|
5938
6317
|
);
|
|
5939
6318
|
}
|
|
5940
|
-
const
|
|
6319
|
+
const policyToolName = tool.name;
|
|
6320
|
+
const originalPolicyRequestArgs = policyToolName === ToolNames.SHELL || policyToolName === ToolNames.MONITOR ? structuredClone(args) : args;
|
|
6321
|
+
const toolSpan = startToolSpan(policyToolName, {
|
|
5941
6322
|
"tool.call_id": callId,
|
|
5942
6323
|
// Dual-emit the legacy call_id/tool_name aliases like CoreToolScheduler
|
|
5943
6324
|
// (coreToolScheduler.ts) so pre-Phase-2 dashboards keyed off call_id keep
|
|
5944
6325
|
// matching daemon/ACP tool spans during the migration window.
|
|
5945
6326
|
call_id: callId,
|
|
5946
|
-
tool_name:
|
|
6327
|
+
tool_name: policyToolName
|
|
5947
6328
|
});
|
|
5948
6329
|
let spanSuccess = false;
|
|
5949
6330
|
try {
|
|
5950
6331
|
return await runInToolSpanContext(toolSpan, async () => {
|
|
5951
6332
|
const pm = this.config.getPermissionManager?.();
|
|
5952
|
-
if (pm && !await pm.isToolEnabled(
|
|
6333
|
+
if (pm && !await pm.isToolEnabled(policyToolName)) {
|
|
5953
6334
|
return earlyErrorResponse(
|
|
5954
6335
|
new Error(`Tool "${toolName}" is disabled.`),
|
|
5955
6336
|
toolName
|
|
@@ -5978,7 +6359,7 @@ ${this.pendingWorktreeNotice}
|
|
|
5978
6359
|
}
|
|
5979
6360
|
}
|
|
5980
6361
|
const toolUseId = generateToolUseId();
|
|
5981
|
-
|
|
6362
|
+
let approvalMode = this.config.getApprovalMode();
|
|
5982
6363
|
let toolBuildSucceeded = false;
|
|
5983
6364
|
try {
|
|
5984
6365
|
const invocation = tool.build(args);
|
|
@@ -6003,12 +6384,12 @@ ${this.pendingWorktreeNotice}
|
|
|
6003
6384
|
activeToolAbortSignal
|
|
6004
6385
|
);
|
|
6005
6386
|
}
|
|
6006
|
-
const isAskUserQuestionTool =
|
|
6007
|
-
|
|
6387
|
+
const isAskUserQuestionTool = policyToolName === ToolNames.ASK_USER_QUESTION;
|
|
6388
|
+
let toolParams = invocation.params;
|
|
6008
6389
|
const flowResult = await evaluatePermissionFlow(
|
|
6009
6390
|
this.config,
|
|
6010
6391
|
invocation,
|
|
6011
|
-
|
|
6392
|
+
policyToolName,
|
|
6012
6393
|
toolParams
|
|
6013
6394
|
);
|
|
6014
6395
|
const {
|
|
@@ -6018,31 +6399,75 @@ ${this.pendingWorktreeNotice}
|
|
|
6018
6399
|
denyMessage,
|
|
6019
6400
|
requiresUserInteraction
|
|
6020
6401
|
} = flowResult;
|
|
6402
|
+
approvalMode = this.config.getApprovalMode();
|
|
6021
6403
|
const isPlanMode = approvalMode === "plan" /* PLAN */;
|
|
6404
|
+
const isPlanShellCall = isPlanMode && (policyToolName === ToolNames.SHELL || policyToolName === ToolNames.MONITOR);
|
|
6022
6405
|
if (finalPermission === "deny") {
|
|
6023
6406
|
return earlyErrorResponse(
|
|
6024
6407
|
new Error(denyMessage ?? `Tool "${toolName}" is denied.`),
|
|
6025
6408
|
toolName
|
|
6026
6409
|
);
|
|
6027
6410
|
}
|
|
6028
|
-
|
|
6411
|
+
let planShellAmbientWorkingDirectory;
|
|
6412
|
+
if (isPlanShellCall) {
|
|
6413
|
+
const directory = toolParams["directory"];
|
|
6414
|
+
planShellAmbientWorkingDirectory = typeof directory === "string" && directory.length > 0 ? void 0 : this.config.getTargetDir();
|
|
6415
|
+
invocation.params = {
|
|
6416
|
+
...structuredClone(invocation.params),
|
|
6417
|
+
directory: typeof directory === "string" && directory.length > 0 ? directory : planShellAmbientWorkingDirectory
|
|
6418
|
+
};
|
|
6419
|
+
toolParams = invocation.params;
|
|
6420
|
+
}
|
|
6421
|
+
const planShellDecision = isPlanShellCall ? await evaluatePlanModeShellPolicy({
|
|
6422
|
+
config: this.config,
|
|
6423
|
+
toolName: policyToolName,
|
|
6424
|
+
requestArgs: originalPolicyRequestArgs,
|
|
6425
|
+
invocationParams: toolParams,
|
|
6426
|
+
permissionContext: pmCtx,
|
|
6427
|
+
ambientWorkingDirectory: planShellAmbientWorkingDirectory,
|
|
6428
|
+
signal: activeToolAbortSignal
|
|
6429
|
+
}) : { classification: "not-applicable" };
|
|
6430
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6431
|
+
const initialPlanShellError = await validatePlanModeShellContext({
|
|
6432
|
+
config: this.config,
|
|
6433
|
+
decision: planShellDecision,
|
|
6434
|
+
requestArgs: args,
|
|
6435
|
+
invocationParams: invocation.params,
|
|
6436
|
+
signal: activeToolAbortSignal
|
|
6437
|
+
});
|
|
6438
|
+
if (initialPlanShellError) {
|
|
6439
|
+
return earlyErrorResponse(
|
|
6440
|
+
new Error(initialPlanShellError),
|
|
6441
|
+
toolName
|
|
6442
|
+
);
|
|
6443
|
+
}
|
|
6444
|
+
}
|
|
6445
|
+
if (planShellDecision.classification === "write") {
|
|
6446
|
+
return earlyErrorResponse(
|
|
6447
|
+
new Error(planShellDecision.writeBlockMessage),
|
|
6448
|
+
toolName
|
|
6449
|
+
);
|
|
6450
|
+
}
|
|
6451
|
+
const planShellRequiresConfirmation = planShellDecision.classification === "unknown";
|
|
6452
|
+
const forceAutoReviewForAllow = approvalMode === "auto" /* AUTO */ && (shouldForceAutoModeReviewForAllow(pmCtx, this.config.getCwd()) || shouldClassifyAllShellForAutoMode(policyToolName, this.config));
|
|
6029
6453
|
const confirmationPermission = getEffectivePermissionForConfirmation(
|
|
6030
6454
|
finalPermission,
|
|
6031
6455
|
forceAutoReviewForAllow
|
|
6032
6456
|
);
|
|
6033
6457
|
if (finalPermission === "allow" && forceAutoReviewForAllow) {
|
|
6034
6458
|
debugLogger6.info(
|
|
6035
|
-
`Auto mode: L4 allow overridden by protected-write guard for ${
|
|
6459
|
+
`Auto mode: L4 allow overridden by protected-write guard for ${policyToolName}`
|
|
6036
6460
|
);
|
|
6037
6461
|
}
|
|
6038
|
-
let autoModeAllowed = finalPermission === "allow" && !forceAutoReviewForAllow;
|
|
6462
|
+
let autoModeAllowed = finalPermission === "allow" && !forceAutoReviewForAllow && !planShellRequiresConfirmation;
|
|
6039
6463
|
if (autoModeAllowed && approvalMode === "auto" /* AUTO */) {
|
|
6040
6464
|
this.config.setAutoModeDenialState(
|
|
6041
6465
|
recordAllow(this.config.getAutoModeDenialState())
|
|
6042
6466
|
);
|
|
6043
6467
|
}
|
|
6044
|
-
let
|
|
6045
|
-
|
|
6468
|
+
let wasAutoModeManualFallback = false;
|
|
6469
|
+
let autoModeFallbackMessage;
|
|
6470
|
+
if (!autoModeAllowed && !requiresUserInteraction && shouldRunAutoModeForCall(approvalMode, policyToolName)) {
|
|
6046
6471
|
const denialState = this.config.getAutoModeDenialState();
|
|
6047
6472
|
const fallback = shouldFallback(denialState);
|
|
6048
6473
|
const messages = this.config.getGeminiClient?.()?.getHistoryTail(MAX_TRANSCRIPT_MESSAGES, false) ?? [];
|
|
@@ -6064,7 +6489,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6064
6489
|
this.config,
|
|
6065
6490
|
decision,
|
|
6066
6491
|
outcome,
|
|
6067
|
-
|
|
6492
|
+
policyToolName,
|
|
6068
6493
|
toolParams,
|
|
6069
6494
|
callId,
|
|
6070
6495
|
abortSignal
|
|
@@ -6075,17 +6500,16 @@ ${this.pendingWorktreeNotice}
|
|
|
6075
6500
|
break;
|
|
6076
6501
|
case "blocked":
|
|
6077
6502
|
debugLogger6.warn(
|
|
6078
|
-
`Auto mode blocked (${outcome.reason}): tool=${
|
|
6503
|
+
`Auto mode blocked (${outcome.reason}): tool=${policyToolName}, ` + formatDenialStateLog(denialState)
|
|
6079
6504
|
);
|
|
6080
6505
|
return earlyErrorResponse(
|
|
6081
6506
|
new Error(outcome.errorMessage),
|
|
6082
6507
|
toolName
|
|
6083
6508
|
);
|
|
6084
6509
|
case "fallback":
|
|
6085
|
-
|
|
6086
|
-
|
|
6087
|
-
)
|
|
6088
|
-
if (wasAutoModeDenialFallback) {
|
|
6510
|
+
wasAutoModeManualFallback = isDenialFallbackReason(outcome.reason) || outcome.reason === "classifier_unavailable";
|
|
6511
|
+
autoModeFallbackMessage = outcome.message;
|
|
6512
|
+
if (wasAutoModeManualFallback) {
|
|
6089
6513
|
debugLogger6.warn(
|
|
6090
6514
|
`Auto mode fallback to manual approval (${outcome.reason}): ` + formatDenialStateLog(denialState)
|
|
6091
6515
|
);
|
|
@@ -6100,7 +6524,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6100
6524
|
let didRequestPermission = false;
|
|
6101
6525
|
let confirmationDetails;
|
|
6102
6526
|
const recordAutoModeFallbackResolution = /* @__PURE__ */ __name((outcome) => {
|
|
6103
|
-
if (approvalMode === "auto" /* AUTO */ &&
|
|
6527
|
+
if (approvalMode === "auto" /* AUTO */ && wasAutoModeManualFallback && isApproveOutcome(outcome)) {
|
|
6104
6528
|
const before = this.config.getAutoModeDenialState();
|
|
6105
6529
|
const after = recordFallbackApprove(before);
|
|
6106
6530
|
if (after === before) {
|
|
@@ -6116,14 +6540,51 @@ ${this.pendingWorktreeNotice}
|
|
|
6116
6540
|
}
|
|
6117
6541
|
}, "recordAutoModeFallbackResolution");
|
|
6118
6542
|
if (!autoModeAllowed && needsConfirmation(
|
|
6119
|
-
confirmationPermission,
|
|
6543
|
+
planShellRequiresConfirmation ? "ask" : confirmationPermission,
|
|
6120
6544
|
approvalMode,
|
|
6121
|
-
|
|
6545
|
+
policyToolName,
|
|
6122
6546
|
requiresUserInteraction
|
|
6123
6547
|
)) {
|
|
6124
|
-
confirmationDetails = await invocation.getConfirmationDetails(
|
|
6548
|
+
confirmationDetails = await invocation.getConfirmationDetails(
|
|
6549
|
+
activeToolAbortSignal
|
|
6550
|
+
);
|
|
6551
|
+
if (autoModeFallbackMessage) {
|
|
6552
|
+
confirmationDetails = decorateClassifierUnavailableConfirmation(
|
|
6553
|
+
confirmationDetails,
|
|
6554
|
+
autoModeFallbackMessage
|
|
6555
|
+
);
|
|
6556
|
+
}
|
|
6557
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6558
|
+
const preDisplayPlanShellError = await validatePlanModeShellContext({
|
|
6559
|
+
config: this.config,
|
|
6560
|
+
decision: planShellDecision,
|
|
6561
|
+
requestArgs: args,
|
|
6562
|
+
invocationParams: invocation.params,
|
|
6563
|
+
signal: activeToolAbortSignal
|
|
6564
|
+
});
|
|
6565
|
+
if (preDisplayPlanShellError) {
|
|
6566
|
+
return earlyErrorResponse(
|
|
6567
|
+
new Error(preDisplayPlanShellError),
|
|
6568
|
+
toolName
|
|
6569
|
+
);
|
|
6570
|
+
}
|
|
6571
|
+
}
|
|
6572
|
+
try {
|
|
6573
|
+
confirmationDetails = decoratePlanModeShellConfirmation(
|
|
6574
|
+
planShellDecision,
|
|
6575
|
+
confirmationDetails
|
|
6576
|
+
);
|
|
6577
|
+
} catch {
|
|
6578
|
+
if (planShellDecision.classification === "unknown") {
|
|
6579
|
+
return earlyErrorResponse(
|
|
6580
|
+
new Error(planShellDecision.noApprovalMessage),
|
|
6581
|
+
toolName
|
|
6582
|
+
);
|
|
6583
|
+
}
|
|
6584
|
+
throw new Error("Unable to prepare shell confirmation.");
|
|
6585
|
+
}
|
|
6125
6586
|
injectPermissionRulesIfMissing(confirmationDetails, pmCtx);
|
|
6126
|
-
if (isPlanModeBlocked(
|
|
6587
|
+
if (planShellDecision.classification === "not-applicable" && isPlanModeBlocked(
|
|
6127
6588
|
isPlanMode,
|
|
6128
6589
|
isExitPlanModeTool,
|
|
6129
6590
|
isAskUserQuestionTool,
|
|
@@ -6143,23 +6604,50 @@ ${this.pendingWorktreeNotice}
|
|
|
6143
6604
|
if (hooksEnabled && messageBus) {
|
|
6144
6605
|
const hookResult = await firePermissionRequestHook(
|
|
6145
6606
|
messageBus,
|
|
6146
|
-
|
|
6607
|
+
policyToolName,
|
|
6147
6608
|
args,
|
|
6148
|
-
String(approvalMode)
|
|
6609
|
+
String(approvalMode),
|
|
6610
|
+
void 0,
|
|
6611
|
+
activeToolAbortSignal
|
|
6149
6612
|
);
|
|
6150
6613
|
if (hookResult.hasDecision && (!hookResult.shouldAllow || !requiresUserInteraction)) {
|
|
6151
6614
|
hookHandled = true;
|
|
6152
6615
|
if (hookResult.shouldAllow) {
|
|
6153
|
-
if (
|
|
6154
|
-
|
|
6155
|
-
|
|
6616
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6617
|
+
const approval = await validatePlanModeShellApproval({
|
|
6618
|
+
config: this.config,
|
|
6619
|
+
decision: planShellDecision,
|
|
6620
|
+
requestArgs: args,
|
|
6621
|
+
invocationParams: invocation.params,
|
|
6622
|
+
signal: activeToolAbortSignal,
|
|
6623
|
+
outcome: "proceed_once" /* ProceedOnce */,
|
|
6624
|
+
payload: hookResult.updatedInput ? { updatedInput: hookResult.updatedInput } : void 0
|
|
6625
|
+
});
|
|
6626
|
+
await confirmationDetails.onConfirm(
|
|
6627
|
+
approval.outcome,
|
|
6628
|
+
approval.payload
|
|
6629
|
+
);
|
|
6630
|
+
if (approval.outcome === "cancel" /* Cancel */) {
|
|
6631
|
+
return earlyErrorResponse(
|
|
6632
|
+
new Error(
|
|
6633
|
+
approval.payload?.cancelMessage ?? planShellDecision.noApprovalMessage
|
|
6634
|
+
),
|
|
6635
|
+
toolName
|
|
6636
|
+
);
|
|
6637
|
+
}
|
|
6638
|
+
recordAutoModeFallbackResolution(approval.outcome);
|
|
6639
|
+
} else {
|
|
6640
|
+
if (hookResult.updatedInput) {
|
|
6641
|
+
args = hookResult.updatedInput;
|
|
6642
|
+
invocation.params = hookResult.updatedInput;
|
|
6643
|
+
}
|
|
6644
|
+
await confirmationDetails.onConfirm(
|
|
6645
|
+
"proceed_once" /* ProceedOnce */
|
|
6646
|
+
);
|
|
6647
|
+
recordAutoModeFallbackResolution(
|
|
6648
|
+
"proceed_once" /* ProceedOnce */
|
|
6649
|
+
);
|
|
6156
6650
|
}
|
|
6157
|
-
await confirmationDetails.onConfirm(
|
|
6158
|
-
"proceed_once" /* ProceedOnce */
|
|
6159
|
-
);
|
|
6160
|
-
recordAutoModeFallbackResolution(
|
|
6161
|
-
"proceed_once" /* ProceedOnce */
|
|
6162
|
-
);
|
|
6163
6651
|
} else {
|
|
6164
6652
|
return earlyErrorResponse(
|
|
6165
6653
|
new Error(
|
|
@@ -6172,11 +6660,26 @@ ${this.pendingWorktreeNotice}
|
|
|
6172
6660
|
}
|
|
6173
6661
|
if (!requiresUserInteraction && approvalMode === "auto-edit" /* AUTO_EDIT */ && (confirmationDetails.type === "edit" || confirmationDetails.type === "info")) {
|
|
6174
6662
|
} else if (!hookHandled) {
|
|
6663
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6664
|
+
const finalPreDisplayPlanShellError = await validatePlanModeShellContext({
|
|
6665
|
+
config: this.config,
|
|
6666
|
+
decision: planShellDecision,
|
|
6667
|
+
requestArgs: args,
|
|
6668
|
+
invocationParams: invocation.params,
|
|
6669
|
+
signal: activeToolAbortSignal
|
|
6670
|
+
});
|
|
6671
|
+
if (finalPreDisplayPlanShellError) {
|
|
6672
|
+
return earlyErrorResponse(
|
|
6673
|
+
new Error(finalPreDisplayPlanShellError),
|
|
6674
|
+
toolName
|
|
6675
|
+
);
|
|
6676
|
+
}
|
|
6677
|
+
}
|
|
6175
6678
|
didRequestPermission = true;
|
|
6176
6679
|
const content = buildPermissionRequestContent(confirmationDetails);
|
|
6177
6680
|
const mappedKind = this.toolCallEmitter.mapToolKind(
|
|
6178
6681
|
tool.kind,
|
|
6179
|
-
|
|
6682
|
+
policyToolName
|
|
6180
6683
|
);
|
|
6181
6684
|
if (hooksEnabled && messageBus) {
|
|
6182
6685
|
this.fireNotificationHookWithTerminalSequence(
|
|
@@ -6186,9 +6689,16 @@ ${this.pendingWorktreeNotice}
|
|
|
6186
6689
|
"Permission needed"
|
|
6187
6690
|
);
|
|
6188
6691
|
}
|
|
6692
|
+
const permissionOptions = toPermissionOptions(
|
|
6693
|
+
confirmationDetails,
|
|
6694
|
+
pmForcedAsk
|
|
6695
|
+
);
|
|
6696
|
+
const offeredPermissionOptions = permissionOptions.map(
|
|
6697
|
+
(option) => ({ ...option })
|
|
6698
|
+
);
|
|
6189
6699
|
const params = {
|
|
6190
6700
|
sessionId: this.sessionId,
|
|
6191
|
-
options:
|
|
6701
|
+
options: permissionOptions,
|
|
6192
6702
|
toolCall: {
|
|
6193
6703
|
toolCallId: callId,
|
|
6194
6704
|
status: "pending",
|
|
@@ -6207,10 +6717,12 @@ ${this.pendingWorktreeNotice}
|
|
|
6207
6717
|
}
|
|
6208
6718
|
}
|
|
6209
6719
|
};
|
|
6210
|
-
const stopAfterPermissionCancel = /* @__PURE__ */ __name(() => {
|
|
6720
|
+
const stopAfterPermissionCancel = /* @__PURE__ */ __name((message) => {
|
|
6211
6721
|
onStopAfterPermissionCancel?.();
|
|
6212
6722
|
return earlyErrorResponse(
|
|
6213
|
-
new Error(
|
|
6723
|
+
new Error(
|
|
6724
|
+
message ?? `Tool "${toolName}" was canceled by the user.`
|
|
6725
|
+
),
|
|
6214
6726
|
toolName,
|
|
6215
6727
|
{ stopAfterPermissionCancel: true }
|
|
6216
6728
|
);
|
|
@@ -6218,10 +6730,15 @@ ${this.pendingWorktreeNotice}
|
|
|
6218
6730
|
let output;
|
|
6219
6731
|
let outcome;
|
|
6220
6732
|
try {
|
|
6221
|
-
output = await
|
|
6222
|
-
|
|
6733
|
+
output = await requestPermissionWithAbort(
|
|
6734
|
+
this.client,
|
|
6735
|
+
params,
|
|
6736
|
+
activeToolAbortSignal
|
|
6737
|
+
);
|
|
6738
|
+
outcome = resolvePermissionOutcome(
|
|
6739
|
+
output,
|
|
6740
|
+
offeredPermissionOptions
|
|
6223
6741
|
);
|
|
6224
|
-
outcome = output.outcome.outcome === "cancelled" ? "cancel" /* Cancel */ : external_exports.nativeEnum(ToolConfirmationOutcome).parse(output.outcome.optionId);
|
|
6225
6742
|
} catch (error) {
|
|
6226
6743
|
debugLogger6.error(
|
|
6227
6744
|
`Permission request failed for tool ${toolName}:`,
|
|
@@ -6238,7 +6755,9 @@ ${this.pendingWorktreeNotice}
|
|
|
6238
6755
|
);
|
|
6239
6756
|
}
|
|
6240
6757
|
onStopAfterPermissionCancel?.();
|
|
6241
|
-
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." : `
|
|
6758
|
+
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(
|
|
6759
|
+
error
|
|
6760
|
+
)}. The command was not run; Plan mode remains active.` : `Permission request failed for "${toolName}": ${this.#formatError(
|
|
6242
6761
|
error
|
|
6243
6762
|
)}`;
|
|
6244
6763
|
return earlyErrorResponse(
|
|
@@ -6247,11 +6766,32 @@ ${this.pendingWorktreeNotice}
|
|
|
6247
6766
|
{ stopAfterPermissionCancel: true }
|
|
6248
6767
|
);
|
|
6249
6768
|
}
|
|
6769
|
+
let confirmationPayload = {
|
|
6770
|
+
answers: output.answers
|
|
6771
|
+
};
|
|
6772
|
+
if (planShellDecision.classification !== "not-applicable") {
|
|
6773
|
+
const approval = await validatePlanModeShellApproval({
|
|
6774
|
+
config: this.config,
|
|
6775
|
+
decision: planShellDecision,
|
|
6776
|
+
requestArgs: args,
|
|
6777
|
+
invocationParams: invocation.params,
|
|
6778
|
+
signal: activeToolAbortSignal,
|
|
6779
|
+
outcome,
|
|
6780
|
+
payload: confirmationPayload
|
|
6781
|
+
});
|
|
6782
|
+
outcome = approval.outcome;
|
|
6783
|
+
confirmationPayload = approval.payload;
|
|
6784
|
+
}
|
|
6785
|
+
const shouldSwitchToDefault = outcome === "proceed_once_and_switch_to_default" /* ProceedOnceAndSwitchToDefault */;
|
|
6786
|
+
if (shouldSwitchToDefault) {
|
|
6787
|
+
outcome = "proceed_once" /* ProceedOnce */;
|
|
6788
|
+
}
|
|
6250
6789
|
recordAutoModeFallbackResolution(outcome);
|
|
6251
6790
|
try {
|
|
6252
|
-
await confirmationDetails.onConfirm(
|
|
6253
|
-
|
|
6254
|
-
|
|
6791
|
+
await confirmationDetails.onConfirm(
|
|
6792
|
+
outcome,
|
|
6793
|
+
confirmationPayload
|
|
6794
|
+
);
|
|
6255
6795
|
} catch (error) {
|
|
6256
6796
|
if (outcome !== "cancel" /* Cancel */) {
|
|
6257
6797
|
throw error;
|
|
@@ -6262,21 +6802,31 @@ ${this.pendingWorktreeNotice}
|
|
|
6262
6802
|
);
|
|
6263
6803
|
return stopAfterPermissionCancel();
|
|
6264
6804
|
}
|
|
6805
|
+
if (shouldSwitchToDefault) {
|
|
6806
|
+
this.config.setApprovalMode("default" /* DEFAULT */);
|
|
6807
|
+
await this.sendCurrentModeUpdateNotification();
|
|
6808
|
+
}
|
|
6265
6809
|
if (outcome === "proceed_always" /* ProceedAlways */ || outcome === "proceed_always_project" /* ProceedAlwaysProject */ || outcome === "proceed_always_user" /* ProceedAlwaysUser */) {
|
|
6266
6810
|
await persistPermissionOutcome(
|
|
6267
6811
|
outcome,
|
|
6268
6812
|
confirmationDetails,
|
|
6269
6813
|
this.config.getOnPersistPermissionRule?.(),
|
|
6270
6814
|
this.config.getPermissionManager?.(),
|
|
6271
|
-
|
|
6815
|
+
confirmationPayload
|
|
6272
6816
|
);
|
|
6273
6817
|
}
|
|
6274
6818
|
if (confirmationDetails.type === "edit" && outcome === "proceed_always" /* ProceedAlways */) {
|
|
6275
6819
|
await this.sendCurrentModeUpdateNotification();
|
|
6276
6820
|
}
|
|
6277
6821
|
switch (outcome) {
|
|
6822
|
+
case "proceed_once_and_switch_to_default" /* ProceedOnceAndSwitchToDefault */:
|
|
6823
|
+
throw new Error(
|
|
6824
|
+
"Switch-to-Default outcome must be normalized before execution."
|
|
6825
|
+
);
|
|
6278
6826
|
case "cancel" /* Cancel */:
|
|
6279
|
-
return stopAfterPermissionCancel(
|
|
6827
|
+
return stopAfterPermissionCancel(
|
|
6828
|
+
confirmationPayload?.cancelMessage
|
|
6829
|
+
);
|
|
6280
6830
|
case "proceed_once" /* ProceedOnce */:
|
|
6281
6831
|
case "proceed_always" /* ProceedAlways */:
|
|
6282
6832
|
case "proceed_always_project" /* ProceedAlwaysProject */:
|
|
@@ -6308,7 +6858,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6308
6858
|
if (hooksEnabledForTool && messageBusForTool) {
|
|
6309
6859
|
const preHookResult = await firePreToolUseHook(
|
|
6310
6860
|
messageBusForTool,
|
|
6311
|
-
|
|
6861
|
+
policyToolName,
|
|
6312
6862
|
args,
|
|
6313
6863
|
toolUseId,
|
|
6314
6864
|
permissionMode,
|
|
@@ -6398,7 +6948,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6398
6948
|
this.#clearTodoStopGuardTrustAndDrainAutomaticQueues();
|
|
6399
6949
|
}
|
|
6400
6950
|
}
|
|
6401
|
-
|
|
6951
|
+
let responseParts = toolResult.error ? convertToFunctionErrorResponse(
|
|
6402
6952
|
toolName,
|
|
6403
6953
|
callId,
|
|
6404
6954
|
toolResult.llmContent,
|
|
@@ -6425,7 +6975,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6425
6975
|
};
|
|
6426
6976
|
const postHookResult = await firePostToolUseHook(
|
|
6427
6977
|
messageBusForTool,
|
|
6428
|
-
|
|
6978
|
+
policyToolName,
|
|
6429
6979
|
args,
|
|
6430
6980
|
toolResponse,
|
|
6431
6981
|
toolUseId,
|
|
@@ -6456,7 +7006,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6456
7006
|
const failureHookResult = await firePostToolUseFailureHook(
|
|
6457
7007
|
messageBusForTool,
|
|
6458
7008
|
toolUseId,
|
|
6459
|
-
|
|
7009
|
+
policyToolName,
|
|
6460
7010
|
args,
|
|
6461
7011
|
toolResult.error?.message ?? "Tool execution was cancelled",
|
|
6462
7012
|
isInterrupt,
|
|
@@ -6476,6 +7026,12 @@ ${this.pendingWorktreeNotice}
|
|
|
6476
7026
|
artifacts: failureHookResult.artifacts
|
|
6477
7027
|
});
|
|
6478
7028
|
}
|
|
7029
|
+
responseParts = await bridgeToolResultImages({
|
|
7030
|
+
config: this.config,
|
|
7031
|
+
responseParts,
|
|
7032
|
+
signal: activeToolAbortSignal,
|
|
7033
|
+
onFullTurnModel
|
|
7034
|
+
});
|
|
6479
7035
|
if (isTodoWriteTool) {
|
|
6480
7036
|
const todos = this.planEmitter.extractTodos(
|
|
6481
7037
|
toolResult.returnDisplay,
|
|
@@ -6510,12 +7066,18 @@ ${this.pendingWorktreeNotice}
|
|
|
6510
7066
|
prompt_id: promptId,
|
|
6511
7067
|
tool_type: typeof tool !== "undefined" && tool instanceof DiscoveredMCPTool ? "mcp" : "native"
|
|
6512
7068
|
});
|
|
6513
|
-
|
|
7069
|
+
queueToolResultRecord?.(fc, {
|
|
6514
7070
|
callId,
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
7071
|
+
toolName,
|
|
7072
|
+
responseParts,
|
|
7073
|
+
persistedOutputFiles: toolResult.persistedOutputFiles,
|
|
7074
|
+
metadata: {
|
|
7075
|
+
callId,
|
|
7076
|
+
status,
|
|
7077
|
+
resultDisplay: toolResult.returnDisplay,
|
|
7078
|
+
error: toolResult.error ? new Error(toolResult.error.message) : void 0,
|
|
7079
|
+
errorType: toolResult.error?.type
|
|
7080
|
+
}
|
|
6519
7081
|
});
|
|
6520
7082
|
spanSuccess = succeeded;
|
|
6521
7083
|
if (toolResult.error) {
|
|
@@ -6545,7 +7107,7 @@ ${this.pendingWorktreeNotice}
|
|
|
6545
7107
|
const failureHookResult = await firePostToolUseFailureHook(
|
|
6546
7108
|
messageBusForError,
|
|
6547
7109
|
toolUseId,
|
|
6548
|
-
|
|
7110
|
+
policyToolName,
|
|
6549
7111
|
args,
|
|
6550
7112
|
error.message,
|
|
6551
7113
|
isInterrupt,
|
|
@@ -6566,24 +7128,6 @@ ${this.pendingWorktreeNotice}
|
|
|
6566
7128
|
});
|
|
6567
7129
|
}
|
|
6568
7130
|
await this.toolCallEmitter.emitError(callId, toolName, error);
|
|
6569
|
-
const errorParts = [
|
|
6570
|
-
{
|
|
6571
|
-
functionResponse: {
|
|
6572
|
-
id: callId,
|
|
6573
|
-
name: toolName,
|
|
6574
|
-
response: { error: error.message }
|
|
6575
|
-
}
|
|
6576
|
-
}
|
|
6577
|
-
];
|
|
6578
|
-
this.config.getChatRecordingService()?.recordToolResult(errorParts, {
|
|
6579
|
-
callId,
|
|
6580
|
-
// A throw caused by abort (e.g. AbortError) is a cancellation, not
|
|
6581
|
-
// a genuine tool error — keep it consistent with the success path.
|
|
6582
|
-
status: activeToolAbortSignal.aborted ? "cancelled" : "error",
|
|
6583
|
-
resultDisplay: void 0,
|
|
6584
|
-
error,
|
|
6585
|
-
errorType: void 0
|
|
6586
|
-
});
|
|
6587
7131
|
const loopDetected = !activeToolAbortSignal.aborted && !toolBuildSucceeded && recordDaemonInvalidToolParams(
|
|
6588
7132
|
this.config,
|
|
6589
7133
|
promptId,
|
|
@@ -6592,6 +7136,18 @@ ${this.pendingWorktreeNotice}
|
|
|
6592
7136
|
error
|
|
6593
7137
|
);
|
|
6594
7138
|
const responseParts = errorResponse(error);
|
|
7139
|
+
queueToolResultRecord?.(fc, {
|
|
7140
|
+
callId,
|
|
7141
|
+
toolName,
|
|
7142
|
+
responseParts,
|
|
7143
|
+
metadata: {
|
|
7144
|
+
callId,
|
|
7145
|
+
status: activeToolAbortSignal.aborted ? "cancelled" : "error",
|
|
7146
|
+
resultDisplay: void 0,
|
|
7147
|
+
error,
|
|
7148
|
+
errorType: void 0
|
|
7149
|
+
}
|
|
7150
|
+
});
|
|
6595
7151
|
return {
|
|
6596
7152
|
parts: responseParts,
|
|
6597
7153
|
stopAfterPermissionCancel: nestedPermissionCancelled,
|
|
@@ -7152,7 +7708,8 @@ function serializeAgentTask(entry, now) {
|
|
|
7152
7708
|
at: a.at
|
|
7153
7709
|
}))
|
|
7154
7710
|
} : {},
|
|
7155
|
-
...optionalField("prompt", entry.prompt)
|
|
7711
|
+
...optionalField("prompt", entry.prompt),
|
|
7712
|
+
...optionalField("toolUseId", entry.toolUseId)
|
|
7156
7713
|
};
|
|
7157
7714
|
}
|
|
7158
7715
|
__name(serializeAgentTask, "serializeAgentTask");
|
|
@@ -7228,6 +7785,7 @@ var QWEN_ACP_LOCAL_READ_ROOTS_ENV = "QWEN_ACP_LOCAL_READ_ROOTS";
|
|
|
7228
7785
|
var POSIX_TMP_LOCAL_READ_ROOT = "/tmp";
|
|
7229
7786
|
var BTW_CHILD_TIMEOUT_MS = 55e3;
|
|
7230
7787
|
var MCP_OAUTH_START_TIMEOUT_MS = 3e4;
|
|
7788
|
+
var SESSION_DRAIN_TIMEOUT_MS = 3e4;
|
|
7231
7789
|
var WORKSPACE_MEMORY_REMEMBER_CHILD_TIMEOUT_MS = 295e3;
|
|
7232
7790
|
function createAcpSessionStartProfiler(span) {
|
|
7233
7791
|
let failedStage;
|
|
@@ -7286,6 +7844,77 @@ function workspaceMemoryErrorData(code, diagnostics) {
|
|
|
7286
7844
|
};
|
|
7287
7845
|
}
|
|
7288
7846
|
__name(workspaceMemoryErrorData, "workspaceMemoryErrorData");
|
|
7847
|
+
var SESSION_WRITER_MESSAGES = {
|
|
7848
|
+
session_writer_conflict: "This session is already open in another Qwen process.",
|
|
7849
|
+
session_writer_lost: "Write ownership for this session was lost.",
|
|
7850
|
+
session_transcript_changed: "The session transcript changed outside its active writer.",
|
|
7851
|
+
session_writer_unavailable: "Session write ownership could not be verified."
|
|
7852
|
+
};
|
|
7853
|
+
function getSessionWriterError(error) {
|
|
7854
|
+
if (!error || typeof error !== "object") return void 0;
|
|
7855
|
+
const candidate = error;
|
|
7856
|
+
const errorKind = candidate["errorKind"];
|
|
7857
|
+
if (typeof errorKind !== "string" || !(errorKind in SESSION_WRITER_RPC_CODES)) {
|
|
7858
|
+
return void 0;
|
|
7859
|
+
}
|
|
7860
|
+
const typedKind = errorKind;
|
|
7861
|
+
if (candidate["rpcCode"] !== SESSION_WRITER_RPC_CODES[typedKind]) {
|
|
7862
|
+
return void 0;
|
|
7863
|
+
}
|
|
7864
|
+
return {
|
|
7865
|
+
rpcCode: SESSION_WRITER_RPC_CODES[typedKind],
|
|
7866
|
+
errorKind: typedKind,
|
|
7867
|
+
message: SESSION_WRITER_MESSAGES[typedKind]
|
|
7868
|
+
};
|
|
7869
|
+
}
|
|
7870
|
+
__name(getSessionWriterError, "getSessionWriterError");
|
|
7871
|
+
function mapSessionWriterRequestError(error) {
|
|
7872
|
+
const writerError = getSessionWriterError(error);
|
|
7873
|
+
return writerError ? new RequestError(writerError.rpcCode, writerError.message, {
|
|
7874
|
+
errorKind: writerError.errorKind
|
|
7875
|
+
}) : error;
|
|
7876
|
+
}
|
|
7877
|
+
__name(mapSessionWriterRequestError, "mapSessionWriterRequestError");
|
|
7878
|
+
async function shutdownSessionConfig(config) {
|
|
7879
|
+
await config.shutdown({ shutdownTelemetry: false });
|
|
7880
|
+
if (config.hasSessionWriteOwnership()) {
|
|
7881
|
+
throw new SessionWriterUnavailableError();
|
|
7882
|
+
}
|
|
7883
|
+
}
|
|
7884
|
+
__name(shutdownSessionConfig, "shutdownSessionConfig");
|
|
7885
|
+
async function waitForSessionDrain(operation, timeoutMs, kind) {
|
|
7886
|
+
let timer;
|
|
7887
|
+
const timeout = new Promise((_, reject) => {
|
|
7888
|
+
timer = setTimeout(
|
|
7889
|
+
() => reject(new Error(`Session ${kind} timed out after ${timeoutMs}ms`)),
|
|
7890
|
+
timeoutMs
|
|
7891
|
+
);
|
|
7892
|
+
timer.unref();
|
|
7893
|
+
});
|
|
7894
|
+
try {
|
|
7895
|
+
await Promise.race([operation, timeout]);
|
|
7896
|
+
} finally {
|
|
7897
|
+
if (timer) clearTimeout(timer);
|
|
7898
|
+
}
|
|
7899
|
+
}
|
|
7900
|
+
__name(waitForSessionDrain, "waitForSessionDrain");
|
|
7901
|
+
async function beginSessionCloseAfterCurrentGate(session, timeoutMs) {
|
|
7902
|
+
const deadline = Date.now() + timeoutMs;
|
|
7903
|
+
while (true) {
|
|
7904
|
+
const releaseGate = session.beginCloseIfAvailable();
|
|
7905
|
+
if (releaseGate) return releaseGate;
|
|
7906
|
+
const remainingMs = deadline - Date.now();
|
|
7907
|
+
if (remainingMs <= 0) {
|
|
7908
|
+
throw new Error(`Session close timed out after ${timeoutMs}ms`);
|
|
7909
|
+
}
|
|
7910
|
+
await waitForSessionDrain(
|
|
7911
|
+
session.waitForCloseGateToRelease(),
|
|
7912
|
+
remainingMs,
|
|
7913
|
+
"close"
|
|
7914
|
+
);
|
|
7915
|
+
}
|
|
7916
|
+
}
|
|
7917
|
+
__name(beginSessionCloseAfterCurrentGate, "beginSessionCloseAfterCurrentGate");
|
|
7289
7918
|
var logWorkspaceMemoryExtractionError = createWorkspaceMemoryExtractionErrorLogger(debugLogger7);
|
|
7290
7919
|
function parseAcpLocalReadRootsEnv(raw = process.env[QWEN_ACP_LOCAL_READ_ROOTS_ENV]) {
|
|
7291
7920
|
if (!raw) return [];
|
|
@@ -7303,7 +7932,7 @@ function buildAcpLocalReadRoots(config) {
|
|
|
7303
7932
|
// local read fallback, not read_file's default permission.
|
|
7304
7933
|
config.storage.getProjectTempDir(),
|
|
7305
7934
|
path4.join(config.storage.getProjectDir(), "subagents"),
|
|
7306
|
-
|
|
7935
|
+
path4.join(config.getSessionRuntimeBaseDir(), "tmp"),
|
|
7307
7936
|
getAutoMemoryRoot(config.getTargetDir()),
|
|
7308
7937
|
getUserAutoMemoryRoot(),
|
|
7309
7938
|
...config.storage.getUserSkillsDirs(),
|
|
@@ -8881,7 +9510,7 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
8881
9510
|
debugLogger7.debug("[ACP] Shutdown signal received, closing streams");
|
|
8882
9511
|
try {
|
|
8883
9512
|
await fireSessionEndOnce("other" /* Other */);
|
|
8884
|
-
agentInstance?.disposeSessions();
|
|
9513
|
+
await agentInstance?.disposeSessions();
|
|
8885
9514
|
try {
|
|
8886
9515
|
process.stdin.destroy();
|
|
8887
9516
|
} catch {
|
|
@@ -8908,7 +9537,7 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
8908
9537
|
await connection.closed;
|
|
8909
9538
|
await fireSessionEndOnce("prompt_input_exit" /* PromptInputExit */);
|
|
8910
9539
|
await drainPoolBeforeExit("ide_close");
|
|
8911
|
-
agentInstance?.disposeSessions();
|
|
9540
|
+
await agentInstance?.disposeSessions();
|
|
8912
9541
|
} finally {
|
|
8913
9542
|
process.off("SIGTERM", shutdownHandler);
|
|
8914
9543
|
process.off("SIGINT", shutdownHandler);
|
|
@@ -9067,6 +9696,7 @@ var QwenAgent = class {
|
|
|
9067
9696
|
mcpAuthenticationResults = /* @__PURE__ */ new Map();
|
|
9068
9697
|
generationControllers = /* @__PURE__ */ new Map();
|
|
9069
9698
|
transcriptReplayConfigCache = /* @__PURE__ */ new Map();
|
|
9699
|
+
pendingConfigCleanup = /* @__PURE__ */ new Map();
|
|
9070
9700
|
clientCapabilities;
|
|
9071
9701
|
// CPU-usage delta baseline for the daemon's `workspaceResource` extMethod
|
|
9072
9702
|
// (Daemon Status child-resource chart). The daemon polls this at a fixed
|
|
@@ -9169,21 +9799,26 @@ var QwenAgent = class {
|
|
|
9169
9799
|
async createWorkspaceMcpDiscoveryConfig(settings) {
|
|
9170
9800
|
if (this.workspaceMcpDiscoveryConfig) return;
|
|
9171
9801
|
const cwd = this.config.getTargetDir();
|
|
9172
|
-
const config = await
|
|
9173
|
-
settings
|
|
9174
|
-
{
|
|
9175
|
-
...this.argv,
|
|
9176
|
-
sessionId: "workspace-mcp-discovery",
|
|
9177
|
-
resume: void 0,
|
|
9178
|
-
continue: false
|
|
9179
|
-
},
|
|
9802
|
+
const config = await this.runWithPinnedRuntimeBaseDir(
|
|
9803
|
+
settings,
|
|
9180
9804
|
cwd,
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9805
|
+
() => loadCliConfig(
|
|
9806
|
+
settings.merged,
|
|
9807
|
+
{
|
|
9808
|
+
...this.argv,
|
|
9809
|
+
sessionId: "workspace-mcp-discovery",
|
|
9810
|
+
resume: void 0,
|
|
9811
|
+
continue: false,
|
|
9812
|
+
chatRecording: false
|
|
9813
|
+
},
|
|
9814
|
+
cwd,
|
|
9815
|
+
void 0,
|
|
9816
|
+
{
|
|
9817
|
+
userHooks: settings.getUserHooks(),
|
|
9818
|
+
projectHooks: settings.getProjectHooks()
|
|
9819
|
+
},
|
|
9820
|
+
buildDisabledSkillNamesProvider(settings)
|
|
9821
|
+
)
|
|
9187
9822
|
);
|
|
9188
9823
|
config.setMcpTransportPool(this.mcpPool);
|
|
9189
9824
|
try {
|
|
@@ -9291,100 +9926,225 @@ var QwenAgent = class {
|
|
|
9291
9926
|
);
|
|
9292
9927
|
}
|
|
9293
9928
|
}
|
|
9294
|
-
async
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
const session = this.sessions.get(sessionId);
|
|
9301
|
-
if (!session) {
|
|
9302
|
-
this.mcpPool?.releaseSession(sessionId);
|
|
9303
|
-
return;
|
|
9929
|
+
async removeStoredSessionEntry(sessionId, session, cleanupErrors = [], options = {}) {
|
|
9930
|
+
if (this.sessions.get(sessionId) !== session) return;
|
|
9931
|
+
try {
|
|
9932
|
+
session.dispose();
|
|
9933
|
+
} catch (error) {
|
|
9934
|
+
cleanupErrors.push(error);
|
|
9304
9935
|
}
|
|
9305
|
-
|
|
9306
|
-
const flushRecording = /* @__PURE__ */ __name(async () => {
|
|
9936
|
+
if (options.shutdownConfig !== false) {
|
|
9307
9937
|
try {
|
|
9308
|
-
await session.getConfig().
|
|
9309
|
-
|
|
9310
|
-
|
|
9311
|
-
debugLogger7.debug(
|
|
9312
|
-
`Session ${sessionId} chat recording flush during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
9313
|
-
);
|
|
9314
|
-
return err;
|
|
9315
|
-
}
|
|
9316
|
-
}, "flushRecording");
|
|
9317
|
-
if (requireFlush) {
|
|
9318
|
-
const preCancelFlushError = await flushRecording();
|
|
9319
|
-
if (preCancelFlushError !== void 0) {
|
|
9320
|
-
throw preCancelFlushError;
|
|
9938
|
+
await session.getConfig().shutdown({ shutdownTelemetry: false });
|
|
9939
|
+
} catch (error) {
|
|
9940
|
+
cleanupErrors.push(error);
|
|
9321
9941
|
}
|
|
9322
9942
|
}
|
|
9323
9943
|
try {
|
|
9324
|
-
|
|
9325
|
-
} catch (
|
|
9326
|
-
|
|
9327
|
-
`Session ${sessionId} cancel during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
9328
|
-
);
|
|
9944
|
+
unregisterGoalHook(session.getConfig(), sessionId);
|
|
9945
|
+
} catch (error) {
|
|
9946
|
+
cleanupErrors.push(error);
|
|
9329
9947
|
}
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9948
|
+
try {
|
|
9949
|
+
this.mcpPool?.releaseSession(sessionId);
|
|
9950
|
+
} catch (error) {
|
|
9951
|
+
cleanupErrors.push(error);
|
|
9333
9952
|
}
|
|
9334
9953
|
try {
|
|
9335
|
-
|
|
9336
|
-
} catch (
|
|
9337
|
-
|
|
9338
|
-
`Session ${sessionId} tool registry stop during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
9339
|
-
);
|
|
9954
|
+
uiTelemetryService.removeSession(sessionId);
|
|
9955
|
+
} catch (error) {
|
|
9956
|
+
cleanupErrors.push(error);
|
|
9340
9957
|
}
|
|
9341
|
-
unregisterGoalHook(session.getConfig(), sessionId);
|
|
9342
|
-
this.mcpPool?.releaseSession(sessionId);
|
|
9343
|
-
uiTelemetryService.removeSession(sessionId);
|
|
9344
9958
|
this.sessions.delete(sessionId);
|
|
9345
|
-
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
const logCleanupFailure = /* @__PURE__ */ __name((action, err) => {
|
|
9351
|
-
debugLogger7.debug(
|
|
9352
|
-
`Session ${sessionId} ${action} during failed restore cleanup failed: ${err instanceof Error ? err.message : String(err)}`
|
|
9959
|
+
if (cleanupErrors.length > 0) {
|
|
9960
|
+
debugLogger7.warn(
|
|
9961
|
+
`Session ${sessionId} closed after ${cleanupErrors.length} cleanup failure(s): ${cleanupErrors.map(
|
|
9962
|
+
(error) => error instanceof Error ? error.message : String(error)
|
|
9963
|
+
).join("; ")}`
|
|
9353
9964
|
);
|
|
9354
|
-
}
|
|
9965
|
+
}
|
|
9966
|
+
}
|
|
9967
|
+
async withLiveSessionRestore(sessionId, session, operation) {
|
|
9968
|
+
await session.assertCanStartTurn();
|
|
9969
|
+
const config = session.getConfig();
|
|
9970
|
+
const releaseGate = session.beginClose();
|
|
9355
9971
|
try {
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9972
|
+
await waitForSessionDrain(
|
|
9973
|
+
session.waitForActiveTurnsToSettle(),
|
|
9974
|
+
SESSION_DRAIN_TIMEOUT_MS,
|
|
9975
|
+
"restore"
|
|
9976
|
+
);
|
|
9977
|
+
const recorder = config.getChatRecordingService();
|
|
9978
|
+
const loadAuthoritative = /* @__PURE__ */ __name(() => config.getSessionService().loadSession(sessionId), "loadAuthoritative");
|
|
9979
|
+
const data = recorder ? await recorder.runWithWriteBarrier(loadAuthoritative) : await loadAuthoritative();
|
|
9980
|
+
if (!data) throw new SessionWriterUnavailableError();
|
|
9981
|
+
return await operation(config, data);
|
|
9982
|
+
} catch (error) {
|
|
9983
|
+
throw mapSessionWriterRequestError(error);
|
|
9984
|
+
} finally {
|
|
9985
|
+
releaseGate();
|
|
9359
9986
|
}
|
|
9987
|
+
}
|
|
9988
|
+
async cleanupUnstoredConfig(config) {
|
|
9989
|
+
const sessionId = config.getSessionId();
|
|
9990
|
+
const cleanupKey = this.pendingConfigCleanupKey(
|
|
9991
|
+
config.getSessionRuntimeBaseDir(),
|
|
9992
|
+
sessionId
|
|
9993
|
+
);
|
|
9360
9994
|
try {
|
|
9361
|
-
|
|
9362
|
-
} catch (
|
|
9363
|
-
|
|
9995
|
+
await shutdownSessionConfig(config);
|
|
9996
|
+
} catch (error) {
|
|
9997
|
+
const pending2 = this.pendingConfigCleanup.get(cleanupKey) ?? /* @__PURE__ */ new Set();
|
|
9998
|
+
pending2.add(config);
|
|
9999
|
+
this.pendingConfigCleanup.set(cleanupKey, pending2);
|
|
10000
|
+
throw mapSessionWriterRequestError(error);
|
|
10001
|
+
}
|
|
10002
|
+
const pending = this.pendingConfigCleanup.get(cleanupKey);
|
|
10003
|
+
pending?.delete(config);
|
|
10004
|
+
if (pending?.size === 0) {
|
|
10005
|
+
this.pendingConfigCleanup.delete(cleanupKey);
|
|
9364
10006
|
}
|
|
10007
|
+
}
|
|
10008
|
+
async cleanupAfterRequestFailure(error, cleanup) {
|
|
9365
10009
|
try {
|
|
10010
|
+
await cleanup();
|
|
10011
|
+
} catch (cleanupError) {
|
|
10012
|
+
debugLogger7.warn(
|
|
10013
|
+
`Session cleanup failed while preserving the original request error: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`
|
|
10014
|
+
);
|
|
10015
|
+
}
|
|
10016
|
+
throw error;
|
|
10017
|
+
}
|
|
10018
|
+
pendingConfigCleanupKey(runtimeBaseDir, sessionId) {
|
|
10019
|
+
return `${path4.resolve(runtimeBaseDir)}\0${sessionId}`;
|
|
10020
|
+
}
|
|
10021
|
+
async retryPendingConfigCleanup(runtimeBaseDir, requiredSessionId) {
|
|
10022
|
+
const resolvedRuntimeBaseDir = path4.resolve(runtimeBaseDir);
|
|
10023
|
+
const configs = /* @__PURE__ */ new Set();
|
|
10024
|
+
for (const pending of this.pendingConfigCleanup.values()) {
|
|
10025
|
+
for (const config of pending) {
|
|
10026
|
+
if (path4.resolve(config.getSessionRuntimeBaseDir()) === resolvedRuntimeBaseDir) {
|
|
10027
|
+
configs.add(config);
|
|
10028
|
+
}
|
|
10029
|
+
}
|
|
10030
|
+
}
|
|
10031
|
+
for (const config of configs) {
|
|
10032
|
+
try {
|
|
10033
|
+
await this.cleanupUnstoredConfig(config);
|
|
10034
|
+
} catch (error) {
|
|
10035
|
+
if (config.getSessionId() === requiredSessionId) throw error;
|
|
10036
|
+
debugLogger7.warn(
|
|
10037
|
+
`Deferred Config cleanup retry failed for session ${config.getSessionId()}: ${error instanceof Error ? error.message : String(error)}`
|
|
10038
|
+
);
|
|
10039
|
+
}
|
|
10040
|
+
}
|
|
10041
|
+
}
|
|
10042
|
+
async closeStoredSession(sessionId, opts) {
|
|
10043
|
+
const session = this.sessions.get(sessionId);
|
|
10044
|
+
if (!session) {
|
|
9366
10045
|
this.mcpPool?.releaseSession(sessionId);
|
|
9367
|
-
|
|
9368
|
-
|
|
10046
|
+
return;
|
|
10047
|
+
}
|
|
10048
|
+
const recorder = session.getConfig().getChatRecordingService();
|
|
10049
|
+
const requireFlush = opts?.requireFlush === true;
|
|
10050
|
+
if (requireFlush) {
|
|
10051
|
+
await recorder?.flush();
|
|
10052
|
+
}
|
|
10053
|
+
const drainTimeoutMs = opts?.drainTimeoutMs ?? SESSION_DRAIN_TIMEOUT_MS;
|
|
10054
|
+
const cancelClose = opts?.waitForCloseGate ? await beginSessionCloseAfterCurrentGate(session, drainTimeoutMs) : session.beginClose();
|
|
10055
|
+
for (const [requestId, generation] of this.generationControllers) {
|
|
10056
|
+
if (generation.sessionId !== sessionId) continue;
|
|
10057
|
+
generation.controller.abort();
|
|
10058
|
+
this.generationControllers.delete(requestId);
|
|
9369
10059
|
}
|
|
10060
|
+
let removedFromStore = false;
|
|
9370
10061
|
try {
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
10062
|
+
await waitForSessionDrain(
|
|
10063
|
+
(async () => {
|
|
10064
|
+
try {
|
|
10065
|
+
await session.cancelPendingPrompt();
|
|
10066
|
+
} catch (err) {
|
|
10067
|
+
debugLogger7.debug(
|
|
10068
|
+
`Session ${sessionId} cancel during close failed: ${err instanceof Error ? err.message : String(err)}`
|
|
10069
|
+
);
|
|
10070
|
+
}
|
|
10071
|
+
await session.waitForActiveTurnsToSettle();
|
|
10072
|
+
})(),
|
|
10073
|
+
drainTimeoutMs,
|
|
10074
|
+
"close"
|
|
10075
|
+
);
|
|
10076
|
+
recorder?.finalize();
|
|
10077
|
+
let flushError;
|
|
10078
|
+
try {
|
|
10079
|
+
await recorder?.flush();
|
|
10080
|
+
} catch (error) {
|
|
10081
|
+
flushError = error;
|
|
10082
|
+
}
|
|
10083
|
+
if (flushError !== void 0 && requireFlush) {
|
|
10084
|
+
throw flushError;
|
|
10085
|
+
}
|
|
10086
|
+
let closeError;
|
|
10087
|
+
try {
|
|
10088
|
+
await recorder?.close();
|
|
10089
|
+
} catch (error) {
|
|
10090
|
+
closeError = error;
|
|
10091
|
+
}
|
|
10092
|
+
if (recorder?.hasWriteOwnership()) {
|
|
10093
|
+
throw closeError ?? new SessionWriterUnavailableError();
|
|
10094
|
+
}
|
|
10095
|
+
const cleanupErrors = [];
|
|
10096
|
+
if (flushError !== void 0) cleanupErrors.push(flushError);
|
|
10097
|
+
if (closeError !== void 0) cleanupErrors.push(closeError);
|
|
10098
|
+
await this.removeStoredSessionEntry(sessionId, session, cleanupErrors, {
|
|
10099
|
+
shutdownConfig: opts?.shutdownConfig
|
|
10100
|
+
});
|
|
10101
|
+
removedFromStore = true;
|
|
10102
|
+
} finally {
|
|
10103
|
+
if (!removedFromStore) cancelClose();
|
|
9374
10104
|
}
|
|
9375
|
-
this.sessions.delete(sessionId);
|
|
9376
10105
|
}
|
|
9377
|
-
|
|
10106
|
+
async discardStoredSessionIfCurrent(sessionId, session, opts) {
|
|
10107
|
+
if (this.sessions.get(sessionId) !== session) {
|
|
10108
|
+
return;
|
|
10109
|
+
}
|
|
10110
|
+
await this.closeStoredSession(sessionId, opts);
|
|
10111
|
+
}
|
|
10112
|
+
async disposeSessions() {
|
|
9378
10113
|
for (const generation of this.generationControllers.values()) {
|
|
9379
10114
|
generation.controller.abort();
|
|
9380
10115
|
}
|
|
9381
10116
|
this.generationControllers.clear();
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
10117
|
+
await Promise.allSettled(
|
|
10118
|
+
[...this.sessions.entries()].map(
|
|
10119
|
+
([sessionId, session]) => this.discardStoredSessionIfCurrent(sessionId, session, {
|
|
10120
|
+
waitForCloseGate: true
|
|
10121
|
+
})
|
|
10122
|
+
)
|
|
10123
|
+
);
|
|
10124
|
+
await Promise.allSettled(
|
|
10125
|
+
[...this.pendingConfigCleanup.values()].flatMap((configs) => [...configs]).map((config) => this.cleanupUnstoredConfig(config))
|
|
10126
|
+
);
|
|
9386
10127
|
this.disposeTranscriptReplayConfigs();
|
|
9387
10128
|
}
|
|
10129
|
+
runWithPinnedRuntimeBaseDir(settings, cwd, operation) {
|
|
10130
|
+
return runWithAcpRuntimeOutputDir(settings, cwd, operation);
|
|
10131
|
+
}
|
|
10132
|
+
async assertLiveSessionScope(config, settings, cwd) {
|
|
10133
|
+
if (path4.resolve(config.storage.getProjectRoot()) !== path4.resolve(cwd)) {
|
|
10134
|
+
throw RequestError.invalidParams(
|
|
10135
|
+
void 0,
|
|
10136
|
+
"The live session belongs to another workspace."
|
|
10137
|
+
);
|
|
10138
|
+
}
|
|
10139
|
+
const requestedRuntimeBaseDir = await this.runWithPinnedRuntimeBaseDir(
|
|
10140
|
+
settings,
|
|
10141
|
+
cwd,
|
|
10142
|
+
() => Storage.getRuntimeBaseDir()
|
|
10143
|
+
);
|
|
10144
|
+
if (path4.resolve(config.getSessionRuntimeBaseDir()) !== path4.resolve(requestedRuntimeBaseDir)) {
|
|
10145
|
+
throw mapSessionWriterRequestError(new SessionWriterUnavailableError());
|
|
10146
|
+
}
|
|
10147
|
+
}
|
|
9388
10148
|
/** Expose the pool's workspace-scoped budget controller for snapshot builders. */
|
|
9389
10149
|
getWorkspaceMcpBudget() {
|
|
9390
10150
|
return this.workspaceMcpBudget;
|
|
@@ -9414,7 +10174,7 @@ var QwenAgent = class {
|
|
|
9414
10174
|
markAcpStartup("initializeHandlerStart");
|
|
9415
10175
|
this.clientCapabilities = args.clientCapabilities;
|
|
9416
10176
|
const authMethods = buildAuthMethods();
|
|
9417
|
-
const version = "0.20.
|
|
10177
|
+
const version = "0.20.2-gdpval-vl-agent.0";
|
|
9418
10178
|
const response = {
|
|
9419
10179
|
protocolVersion: PROTOCOL_VERSION,
|
|
9420
10180
|
agentInfo: {
|
|
@@ -9503,15 +10263,24 @@ var QwenAgent = class {
|
|
|
9503
10263
|
"config_setup",
|
|
9504
10264
|
() => this.newSessionConfig(cwd, mcpServers, settings)
|
|
9505
10265
|
);
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
"
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
10266
|
+
let session;
|
|
10267
|
+
try {
|
|
10268
|
+
await profiler.time("auth", () => this.ensureAuthenticated(config));
|
|
10269
|
+
profiler.timeSync(
|
|
10270
|
+
"file_system_setup",
|
|
10271
|
+
() => this.setupFileSystem(config)
|
|
10272
|
+
);
|
|
10273
|
+
session = await profiler.time(
|
|
10274
|
+
"session_register",
|
|
10275
|
+
() => this.createAndStoreSession(config, settings)
|
|
10276
|
+
);
|
|
10277
|
+
} catch (error) {
|
|
10278
|
+
return this.cleanupAfterRequestFailure(error, async () => {
|
|
10279
|
+
if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
|
|
10280
|
+
await this.cleanupUnstoredConfig(config);
|
|
10281
|
+
}
|
|
10282
|
+
});
|
|
10283
|
+
}
|
|
9515
10284
|
profiler.setSessionId(session.getId());
|
|
9516
10285
|
return profiler.timeSync("response_build", () => ({
|
|
9517
10286
|
sessionId: session.getId(),
|
|
@@ -9525,7 +10294,56 @@ var QwenAgent = class {
|
|
|
9525
10294
|
}
|
|
9526
10295
|
async loadSession(params) {
|
|
9527
10296
|
const settings = loadSettingsCached(params.cwd);
|
|
9528
|
-
const
|
|
10297
|
+
const liveSession = this.sessions.get(params.sessionId);
|
|
10298
|
+
if (liveSession) {
|
|
10299
|
+
const liveConfig = liveSession.getConfig();
|
|
10300
|
+
await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
|
|
10301
|
+
return this.withLiveSessionRestore(
|
|
10302
|
+
params.sessionId,
|
|
10303
|
+
liveSession,
|
|
10304
|
+
async (config2, sessionData2) => {
|
|
10305
|
+
const response2 = {
|
|
10306
|
+
modes: this.buildModesData(config2),
|
|
10307
|
+
models: this.buildAvailableModels(config2),
|
|
10308
|
+
configOptions: this.buildConfigOptions(config2),
|
|
10309
|
+
...sessionData2.artifactSnapshot ? { artifactSnapshot: sessionData2.artifactSnapshot } : {}
|
|
10310
|
+
};
|
|
10311
|
+
const records = sessionData2.conversation.messages;
|
|
10312
|
+
if (records.length === 0) return response2;
|
|
10313
|
+
const bulkReplay2 = isBulkLoadReplayRequest(params);
|
|
10314
|
+
const replayPage = bulkReplay2 ? selectRecentHistoryRecords(records, getLoadReplayPageSize(params)) : { records, hasMore: false };
|
|
10315
|
+
const replay = await collectHistoryReplayUpdates({
|
|
10316
|
+
sessionId: params.sessionId,
|
|
10317
|
+
config: config2,
|
|
10318
|
+
records: replayPage.records,
|
|
10319
|
+
gaps: sessionData2.historyGaps,
|
|
10320
|
+
cumulativeUsage: createReplayCumulativeUsage(),
|
|
10321
|
+
logger: debugLogger7
|
|
10322
|
+
});
|
|
10323
|
+
if (!bulkReplay2) {
|
|
10324
|
+
for (const update of replay.updates) {
|
|
10325
|
+
await liveSession.sendUpdate(update);
|
|
10326
|
+
}
|
|
10327
|
+
if (replay.replayError !== void 0) {
|
|
10328
|
+
throw RequestError.internalError(void 0, replay.replayError);
|
|
10329
|
+
}
|
|
10330
|
+
return response2;
|
|
10331
|
+
}
|
|
10332
|
+
return {
|
|
10333
|
+
...response2,
|
|
10334
|
+
_meta: {
|
|
10335
|
+
[LOAD_REPLAY_META_KEY]: {
|
|
10336
|
+
v: LOAD_REPLAY_VERSION,
|
|
10337
|
+
updates: replay.updates,
|
|
10338
|
+
...replay.replayError !== void 0 ? { partial: true, replayError: replay.replayError } : {},
|
|
10339
|
+
...replayPage.hasMore ? { hasMore: true } : {}
|
|
10340
|
+
}
|
|
10341
|
+
}
|
|
10342
|
+
};
|
|
10343
|
+
}
|
|
10344
|
+
);
|
|
10345
|
+
}
|
|
10346
|
+
const exists = await this.runWithPinnedRuntimeBaseDir(
|
|
9529
10347
|
settings,
|
|
9530
10348
|
params.cwd,
|
|
9531
10349
|
async () => {
|
|
@@ -9548,17 +10366,26 @@ var QwenAgent = class {
|
|
|
9548
10366
|
params.sessionId,
|
|
9549
10367
|
true
|
|
9550
10368
|
);
|
|
9551
|
-
await this.ensureAuthenticated(config);
|
|
9552
|
-
this.setupFileSystem(config);
|
|
9553
10369
|
const sessionData = config.getResumedSessionData();
|
|
9554
10370
|
const bulkReplay = isBulkLoadReplayRequest(params);
|
|
9555
10371
|
const replayPageSize = bulkReplay ? getLoadReplayPageSize(params) : void 0;
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
|
|
10372
|
+
let session;
|
|
10373
|
+
try {
|
|
10374
|
+
await this.ensureAuthenticated(config);
|
|
10375
|
+
this.setupFileSystem(config);
|
|
10376
|
+
session = await this.createAndStoreSession(
|
|
10377
|
+
config,
|
|
10378
|
+
settings,
|
|
10379
|
+
sessionData,
|
|
10380
|
+
bulkReplay ? { replayHistory: false, startPostReplayServices: false } : {}
|
|
10381
|
+
);
|
|
10382
|
+
} catch (error) {
|
|
10383
|
+
return this.cleanupAfterRequestFailure(error, async () => {
|
|
10384
|
+
if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
|
|
10385
|
+
await this.cleanupUnstoredConfig(config);
|
|
10386
|
+
}
|
|
10387
|
+
});
|
|
10388
|
+
}
|
|
9562
10389
|
let replayEnvelope;
|
|
9563
10390
|
if (bulkReplay) {
|
|
9564
10391
|
try {
|
|
@@ -9605,8 +10432,21 @@ var QwenAgent = class {
|
|
|
9605
10432
|
session.installRewriter();
|
|
9606
10433
|
session.startCronScheduler();
|
|
9607
10434
|
} catch (err) {
|
|
9608
|
-
this.
|
|
9609
|
-
|
|
10435
|
+
return this.cleanupAfterRequestFailure(err, async () => {
|
|
10436
|
+
try {
|
|
10437
|
+
await this.discardStoredSessionIfCurrent(params.sessionId, session);
|
|
10438
|
+
} catch (cleanupError) {
|
|
10439
|
+
await this.removeStoredSessionEntry(
|
|
10440
|
+
params.sessionId,
|
|
10441
|
+
session,
|
|
10442
|
+
[cleanupError],
|
|
10443
|
+
{
|
|
10444
|
+
shutdownConfig: false
|
|
10445
|
+
}
|
|
10446
|
+
);
|
|
10447
|
+
await this.cleanupUnstoredConfig(config);
|
|
10448
|
+
}
|
|
10449
|
+
});
|
|
9610
10450
|
}
|
|
9611
10451
|
}
|
|
9612
10452
|
await this.#restoreWorktreeOnResume(config, session);
|
|
@@ -9632,7 +10472,22 @@ var QwenAgent = class {
|
|
|
9632
10472
|
}
|
|
9633
10473
|
async unstable_resumeSession(params) {
|
|
9634
10474
|
const settings = loadSettingsCached(params.cwd);
|
|
9635
|
-
const
|
|
10475
|
+
const liveSession = this.sessions.get(params.sessionId);
|
|
10476
|
+
if (liveSession) {
|
|
10477
|
+
const liveConfig = liveSession.getConfig();
|
|
10478
|
+
await this.assertLiveSessionScope(liveConfig, settings, params.cwd);
|
|
10479
|
+
return this.withLiveSessionRestore(
|
|
10480
|
+
params.sessionId,
|
|
10481
|
+
liveSession,
|
|
10482
|
+
async (config2, sessionData2) => ({
|
|
10483
|
+
modes: this.buildModesData(config2),
|
|
10484
|
+
models: this.buildAvailableModels(config2),
|
|
10485
|
+
configOptions: this.buildConfigOptions(config2),
|
|
10486
|
+
...sessionData2.artifactSnapshot ? { artifactSnapshot: sessionData2.artifactSnapshot } : {}
|
|
10487
|
+
})
|
|
10488
|
+
);
|
|
10489
|
+
}
|
|
10490
|
+
const exists = await this.runWithPinnedRuntimeBaseDir(
|
|
9636
10491
|
settings,
|
|
9637
10492
|
params.cwd,
|
|
9638
10493
|
async () => {
|
|
@@ -9651,14 +10506,23 @@ var QwenAgent = class {
|
|
|
9651
10506
|
params.sessionId,
|
|
9652
10507
|
true
|
|
9653
10508
|
);
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
config
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
10509
|
+
let session;
|
|
10510
|
+
try {
|
|
10511
|
+
await this.ensureAuthenticated(config);
|
|
10512
|
+
this.setupFileSystem(config);
|
|
10513
|
+
session = await this.createAndStoreSession(
|
|
10514
|
+
config,
|
|
10515
|
+
settings,
|
|
10516
|
+
config.getResumedSessionData(),
|
|
10517
|
+
{ replayHistory: false }
|
|
10518
|
+
);
|
|
10519
|
+
} catch (error) {
|
|
10520
|
+
return this.cleanupAfterRequestFailure(error, async () => {
|
|
10521
|
+
if (this.sessions.get(config.getSessionId())?.getConfig() !== config) {
|
|
10522
|
+
await this.cleanupUnstoredConfig(config);
|
|
10523
|
+
}
|
|
10524
|
+
});
|
|
10525
|
+
}
|
|
9662
10526
|
await this.#restoreWorktreeOnResume(config, session);
|
|
9663
10527
|
this.#restoreGoalOnResume(config, session);
|
|
9664
10528
|
const modesData = this.buildModesData(config);
|
|
@@ -11572,6 +12436,19 @@ var QwenAgent = class {
|
|
|
11572
12436
|
};
|
|
11573
12437
|
}
|
|
11574
12438
|
async extMethod(method, params) {
|
|
12439
|
+
try {
|
|
12440
|
+
return await this.extMethodInternal(method, params);
|
|
12441
|
+
} catch (error) {
|
|
12442
|
+
const writerError = getSessionWriterError(error);
|
|
12443
|
+
if (writerError) {
|
|
12444
|
+
throw new RequestError(writerError.rpcCode, writerError.message, {
|
|
12445
|
+
errorKind: writerError.errorKind
|
|
12446
|
+
});
|
|
12447
|
+
}
|
|
12448
|
+
throw error;
|
|
12449
|
+
}
|
|
12450
|
+
}
|
|
12451
|
+
async extMethodInternal(method, params) {
|
|
11575
12452
|
const requestedCwd = typeof params["cwd"] === "string" ? params["cwd"] : void 0;
|
|
11576
12453
|
const cwd = requestedCwd || process.cwd();
|
|
11577
12454
|
const SESSION_ID_RE = /^[0-9a-fA-F-]{32,36}$/;
|
|
@@ -11845,6 +12722,25 @@ var QwenAgent = class {
|
|
|
11845
12722
|
"Transcript cursor and record boundary are mutually exclusive"
|
|
11846
12723
|
);
|
|
11847
12724
|
}
|
|
12725
|
+
const rawDirection = params["direction"];
|
|
12726
|
+
if (rawDirection !== void 0 && rawDirection !== "backward") {
|
|
12727
|
+
throw RequestError.invalidParams(
|
|
12728
|
+
void 0,
|
|
12729
|
+
"Invalid transcript direction"
|
|
12730
|
+
);
|
|
12731
|
+
}
|
|
12732
|
+
if (rawCursor !== void 0 && rawDirection !== void 0) {
|
|
12733
|
+
throw RequestError.invalidParams(
|
|
12734
|
+
void 0,
|
|
12735
|
+
"Transcript cursor and direction are mutually exclusive"
|
|
12736
|
+
);
|
|
12737
|
+
}
|
|
12738
|
+
if (rawBeforeRecordId !== void 0 && rawDirection !== void 0) {
|
|
12739
|
+
throw RequestError.invalidParams(
|
|
12740
|
+
void 0,
|
|
12741
|
+
"Transcript record boundary and direction are mutually exclusive"
|
|
12742
|
+
);
|
|
12743
|
+
}
|
|
11848
12744
|
const rawLimit = params["limit"];
|
|
11849
12745
|
if (rawLimit !== void 0 && (!Number.isSafeInteger(rawLimit) || rawLimit < 1 || rawLimit > SESSION_TRANSCRIPT_MAX_LIMIT)) {
|
|
11850
12746
|
throw RequestError.invalidParams(
|
|
@@ -11855,10 +12751,14 @@ var QwenAgent = class {
|
|
|
11855
12751
|
try {
|
|
11856
12752
|
const settings = loadSettingsCached(cwd);
|
|
11857
12753
|
return await runWithAcpRuntimeOutputDir(settings, cwd, async () => {
|
|
12754
|
+
if (rawDirection === "backward") {
|
|
12755
|
+
await this.sessions.get(sessionId)?.getConfig().getChatRecordingService()?.flush();
|
|
12756
|
+
}
|
|
11858
12757
|
const reader = new SessionTranscriptReader(cwd);
|
|
11859
12758
|
const page = await reader.readPage(sessionId, {
|
|
11860
12759
|
...typeof rawCursor === "string" ? { cursor: rawCursor } : {},
|
|
11861
12760
|
...typeof rawBeforeRecordId === "string" ? { beforeRecordId: rawBeforeRecordId } : {},
|
|
12761
|
+
...rawDirection === "backward" ? { direction: rawDirection } : {},
|
|
11862
12762
|
...typeof rawLimit === "number" ? { limit: rawLimit } : {},
|
|
11863
12763
|
maxBytes: SESSION_TRANSCRIPT_MAX_PAGE_BYTES
|
|
11864
12764
|
});
|
|
@@ -12712,6 +13612,34 @@ var QwenAgent = class {
|
|
|
12712
13612
|
}
|
|
12713
13613
|
return { sessionId, persisted: true, kind };
|
|
12714
13614
|
}
|
|
13615
|
+
case "qwen/session/recordTextElements": {
|
|
13616
|
+
const sessionId = params["sessionId"];
|
|
13617
|
+
const content = params["content"];
|
|
13618
|
+
const textElements = params["textElements"];
|
|
13619
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
13620
|
+
throw RequestError.invalidParams(
|
|
13621
|
+
void 0,
|
|
13622
|
+
"Invalid or missing sessionId"
|
|
13623
|
+
);
|
|
13624
|
+
}
|
|
13625
|
+
if (typeof content !== "string" || !Array.isArray(textElements)) {
|
|
13626
|
+
throw RequestError.invalidParams(
|
|
13627
|
+
void 0,
|
|
13628
|
+
"Invalid user text elements payload"
|
|
13629
|
+
);
|
|
13630
|
+
}
|
|
13631
|
+
const session = this.sessionOrThrow(sessionId);
|
|
13632
|
+
await session.assertCanStartTurn();
|
|
13633
|
+
const recording = session.getConfig().getChatRecordingService();
|
|
13634
|
+
if (!recording) {
|
|
13635
|
+
throw RequestError.internalError(
|
|
13636
|
+
void 0,
|
|
13637
|
+
"Chat recording service unavailable"
|
|
13638
|
+
);
|
|
13639
|
+
}
|
|
13640
|
+
await recording.recordUserTextElements({ content, textElements });
|
|
13641
|
+
return { sessionId, persisted: true };
|
|
13642
|
+
}
|
|
12715
13643
|
case SERVE_CONTROL_EXT_METHODS.sessionTitle: {
|
|
12716
13644
|
const sessionId = params["sessionId"];
|
|
12717
13645
|
const displayName = params["displayName"];
|
|
@@ -12807,8 +13735,16 @@ var QwenAgent = class {
|
|
|
12807
13735
|
"Invalid or missing sessionId"
|
|
12808
13736
|
);
|
|
12809
13737
|
}
|
|
13738
|
+
const rawDrainTimeoutMs = params["drainTimeoutMs"];
|
|
13739
|
+
if (rawDrainTimeoutMs !== void 0 && (typeof rawDrainTimeoutMs !== "number" || !Number.isSafeInteger(rawDrainTimeoutMs) || rawDrainTimeoutMs < 1 || rawDrainTimeoutMs > 2147483647)) {
|
|
13740
|
+
throw RequestError.invalidParams(
|
|
13741
|
+
void 0,
|
|
13742
|
+
"Invalid session close drain timeout"
|
|
13743
|
+
);
|
|
13744
|
+
}
|
|
12810
13745
|
await this.closeStoredSession(sessionId, {
|
|
12811
|
-
requireFlush: params["requireFlush"] === true
|
|
13746
|
+
requireFlush: params["requireFlush"] === true,
|
|
13747
|
+
...typeof rawDrainTimeoutMs === "number" ? { drainTimeoutMs: rawDrainTimeoutMs } : {}
|
|
12812
13748
|
});
|
|
12813
13749
|
return { sessionId, closed: true };
|
|
12814
13750
|
}
|
|
@@ -12850,6 +13786,21 @@ var QwenAgent = class {
|
|
|
12850
13786
|
});
|
|
12851
13787
|
}
|
|
12852
13788
|
const canonicalPath = await fs2.realpath(targetPath);
|
|
13789
|
+
const allowedRoots = params["allowedRoots"];
|
|
13790
|
+
if (Array.isArray(allowedRoots) && allowedRoots.length > 0) {
|
|
13791
|
+
const contained = allowedRoots.some((root) => {
|
|
13792
|
+
if (typeof root !== "string") return false;
|
|
13793
|
+
const rel = path4.relative(root, canonicalPath);
|
|
13794
|
+
return !rel.startsWith("..") && !path4.isAbsolute(rel);
|
|
13795
|
+
});
|
|
13796
|
+
if (!contained) {
|
|
13797
|
+
throw new RequestError(
|
|
13798
|
+
-32004,
|
|
13799
|
+
`Path outside allowed roots: ${canonicalPath}`,
|
|
13800
|
+
{ errorKind: "containment_violation", path: canonicalPath }
|
|
13801
|
+
);
|
|
13802
|
+
}
|
|
13803
|
+
}
|
|
12853
13804
|
const previousCwd = config.getTargetDir();
|
|
12854
13805
|
if (canonicalPath === previousCwd) {
|
|
12855
13806
|
return { previousCwd, newCwd: canonicalPath, warnings: [] };
|
|
@@ -13731,16 +14682,11 @@ ${outputText}
|
|
|
13731
14682
|
let artifactSnapshot;
|
|
13732
14683
|
let artifactSnapshotUnavailable;
|
|
13733
14684
|
try {
|
|
13734
|
-
|
|
13735
|
-
const
|
|
13736
|
-
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
async () => {
|
|
13740
|
-
const sessionService = new SessionService(cwd2);
|
|
13741
|
-
return sessionService.loadSession(sessionId);
|
|
13742
|
-
}
|
|
13743
|
-
);
|
|
14685
|
+
const config = session.getConfig();
|
|
14686
|
+
const recording = config.getChatRecordingService();
|
|
14687
|
+
await recording?.flush();
|
|
14688
|
+
const loadAuthoritative = /* @__PURE__ */ __name(() => config.getSessionService().loadSession(sessionId), "loadAuthoritative");
|
|
14689
|
+
const sessionData = recording ? await recording.runWithWriteBarrier(loadAuthoritative) : await loadAuthoritative();
|
|
13744
14690
|
if (sessionData === void 0) {
|
|
13745
14691
|
artifactSnapshotUnavailable = "session data unavailable after rewind";
|
|
13746
14692
|
} else if (sessionData.artifactSnapshot) {
|
|
@@ -13781,20 +14727,37 @@ ${outputText}
|
|
|
13781
14727
|
"Invalid or missing sessionId"
|
|
13782
14728
|
);
|
|
13783
14729
|
}
|
|
13784
|
-
const
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
|
|
14730
|
+
const liveSession = this.sessions.get(sessionId);
|
|
14731
|
+
let replayConfig = this.config;
|
|
14732
|
+
let sessionData;
|
|
14733
|
+
if (liveSession) {
|
|
14734
|
+
const config = liveSession.getConfig();
|
|
14735
|
+
await this.assertLiveSessionScope(
|
|
14736
|
+
config,
|
|
14737
|
+
loadSettingsCached(cwd),
|
|
14738
|
+
cwd
|
|
14739
|
+
);
|
|
14740
|
+
const recording = config.getChatRecordingService();
|
|
14741
|
+
const loadAuthoritative = /* @__PURE__ */ __name(() => config.getSessionService().loadSession(sessionId), "loadAuthoritative");
|
|
14742
|
+
sessionData = recording ? await recording.runWithWriteBarrier(loadAuthoritative) : await loadAuthoritative();
|
|
14743
|
+
replayConfig = config;
|
|
14744
|
+
} else {
|
|
14745
|
+
const settings = loadSettingsCached(cwd);
|
|
14746
|
+
sessionData = await this.runWithPinnedRuntimeBaseDir(
|
|
14747
|
+
settings,
|
|
14748
|
+
cwd,
|
|
14749
|
+
async () => {
|
|
14750
|
+
const sessionService = new SessionService(cwd);
|
|
14751
|
+
return sessionService.loadSession(sessionId);
|
|
14752
|
+
}
|
|
14753
|
+
);
|
|
14754
|
+
}
|
|
13792
14755
|
if (!sessionData?.conversation) {
|
|
13793
14756
|
return { updates: [] };
|
|
13794
14757
|
}
|
|
13795
14758
|
const replay = await collectHistoryReplayUpdates({
|
|
13796
14759
|
sessionId,
|
|
13797
|
-
config:
|
|
14760
|
+
config: replayConfig,
|
|
13798
14761
|
records: sessionData.conversation.messages,
|
|
13799
14762
|
gaps: sessionData.historyGaps,
|
|
13800
14763
|
cumulativeUsage: createReplayCumulativeUsage(),
|
|
@@ -13862,56 +14825,51 @@ ${outputText}
|
|
|
13862
14825
|
sessionId
|
|
13863
14826
|
});
|
|
13864
14827
|
}
|
|
13865
|
-
const
|
|
14828
|
+
const sourceConfig = sourceSession.getConfig();
|
|
14829
|
+
const recording = sourceConfig.getChatRecordingService();
|
|
13866
14830
|
if (recording) {
|
|
13867
14831
|
await recording.flush();
|
|
13868
14832
|
}
|
|
13869
|
-
const newSessionId =
|
|
13870
|
-
|
|
13871
|
-
|
|
13872
|
-
|
|
13873
|
-
|
|
13874
|
-
|
|
13875
|
-
|
|
13876
|
-
|
|
13877
|
-
|
|
13878
|
-
|
|
13879
|
-
|
|
13880
|
-
|
|
13881
|
-
|
|
13882
|
-
|
|
13883
|
-
|
|
13884
|
-
if (stripped && stripped.length > 0) {
|
|
13885
|
-
baseName = stripped;
|
|
13886
|
-
} else {
|
|
13887
|
-
baseName = sessionId.slice(0, 8);
|
|
13888
|
-
}
|
|
13889
|
-
}
|
|
13890
|
-
title = await computeUniqueBranchTitle(baseName, sessionService);
|
|
13891
|
-
const renamed = await sessionService.renameSession(
|
|
13892
|
-
newSessionId,
|
|
13893
|
-
title,
|
|
13894
|
-
"manual"
|
|
13895
|
-
);
|
|
13896
|
-
if (!renamed) {
|
|
13897
|
-
throw new RequestError(
|
|
13898
|
-
-32603,
|
|
13899
|
-
`Failed to set title on forked session ${newSessionId}`,
|
|
13900
|
-
{ errorKind: "internal", sessionId: newSessionId }
|
|
13901
|
-
);
|
|
13902
|
-
}
|
|
13903
|
-
} catch (err) {
|
|
13904
|
-
sessionService.removeSession(newSessionId).catch((rmErr) => {
|
|
13905
|
-
process.stderr.write(
|
|
13906
|
-
`qwen serve: failed to clean up orphan session ${newSessionId}: ${rmErr instanceof Error ? rmErr.message : rmErr}
|
|
13907
|
-
`
|
|
13908
|
-
);
|
|
13909
|
-
});
|
|
13910
|
-
throw err;
|
|
14833
|
+
const newSessionId = randomUUID2();
|
|
14834
|
+
const sessionService = sourceConfig.getSessionService();
|
|
14835
|
+
await sessionService.forkSession(sessionId, newSessionId);
|
|
14836
|
+
let title;
|
|
14837
|
+
try {
|
|
14838
|
+
let baseName;
|
|
14839
|
+
if (typeof name === "string" && name.trim().length > 0) {
|
|
14840
|
+
baseName = name.trim();
|
|
14841
|
+
} else {
|
|
14842
|
+
const existingTitle = recording?.getCurrentCustomTitle();
|
|
14843
|
+
const stripped = existingTitle?.replace(/\s*\(Branch(?:\s+\d+)?\)\s*$/, "").trim();
|
|
14844
|
+
if (stripped && stripped.length > 0) {
|
|
14845
|
+
baseName = stripped;
|
|
14846
|
+
} else {
|
|
14847
|
+
baseName = sessionId.slice(0, 8);
|
|
13911
14848
|
}
|
|
13912
|
-
return { newSessionId, title, displayName: title };
|
|
13913
14849
|
}
|
|
13914
|
-
|
|
14850
|
+
title = await computeUniqueBranchTitle(baseName, sessionService);
|
|
14851
|
+
const renamed = await sessionService.renameSession(
|
|
14852
|
+
newSessionId,
|
|
14853
|
+
title,
|
|
14854
|
+
"manual"
|
|
14855
|
+
);
|
|
14856
|
+
if (!renamed) {
|
|
14857
|
+
throw new RequestError(
|
|
14858
|
+
-32603,
|
|
14859
|
+
`Failed to set title on forked session ${newSessionId}`,
|
|
14860
|
+
{ errorKind: "internal", sessionId: newSessionId }
|
|
14861
|
+
);
|
|
14862
|
+
}
|
|
14863
|
+
} catch (err) {
|
|
14864
|
+
sessionService.removeSession(newSessionId).catch((rmErr) => {
|
|
14865
|
+
process.stderr.write(
|
|
14866
|
+
`qwen serve: failed to clean up orphan session ${newSessionId}: ${rmErr instanceof Error ? rmErr.message : rmErr}
|
|
14867
|
+
`
|
|
14868
|
+
);
|
|
14869
|
+
});
|
|
14870
|
+
throw err;
|
|
14871
|
+
}
|
|
14872
|
+
return { newSessionId, title, displayName: title };
|
|
13915
14873
|
}
|
|
13916
14874
|
case "qwen/settings/getCore": {
|
|
13917
14875
|
const settings = loadSettings(cwd);
|
|
@@ -14300,17 +15258,25 @@ ${outputText}
|
|
|
14300
15258
|
this.disposeTranscriptReplayConfig(cached.config);
|
|
14301
15259
|
}
|
|
14302
15260
|
const entry = { settings };
|
|
14303
|
-
const pending = this.newSessionConfig(
|
|
14304
|
-
|
|
14305
|
-
|
|
14306
|
-
|
|
14307
|
-
|
|
14308
|
-
|
|
14309
|
-
|
|
14310
|
-
|
|
14311
|
-
|
|
14312
|
-
|
|
14313
|
-
|
|
15261
|
+
const pending = this.newSessionConfig(
|
|
15262
|
+
cwd,
|
|
15263
|
+
[],
|
|
15264
|
+
settings,
|
|
15265
|
+
void 0,
|
|
15266
|
+
false,
|
|
15267
|
+
{
|
|
15268
|
+
skipMcpDiscovery: true,
|
|
15269
|
+
skipHooks: true,
|
|
15270
|
+
skipSkillManager: true,
|
|
15271
|
+
skipFileCheckpointing: true,
|
|
15272
|
+
// Read-only replay: tolerate tools that cannot construct without the
|
|
15273
|
+
// subsystems skipped above (e.g. SkillTool needs the SkillManager). The
|
|
15274
|
+
// registry is only consulted for optional tool_call metadata during
|
|
15275
|
+
// replay, and ToolCallEmitter falls back to the recorded tool name.
|
|
15276
|
+
lenientToolWarmup: true
|
|
15277
|
+
},
|
|
15278
|
+
false
|
|
15279
|
+
);
|
|
14314
15280
|
entry.pending = pending;
|
|
14315
15281
|
this.transcriptReplayConfigCache.set(key, entry);
|
|
14316
15282
|
try {
|
|
@@ -14338,7 +15304,34 @@ ${outputText}
|
|
|
14338
15304
|
throw error;
|
|
14339
15305
|
}
|
|
14340
15306
|
}
|
|
14341
|
-
async newSessionConfig(cwd, mcpServers, settings, sessionId, resume, initializeOptions = {}) {
|
|
15307
|
+
async newSessionConfig(cwd, mcpServers, settings, sessionId, resume, initializeOptions = {}, chatRecording) {
|
|
15308
|
+
try {
|
|
15309
|
+
return await this.runWithPinnedRuntimeBaseDir(settings, cwd, async () => {
|
|
15310
|
+
await this.retryPendingConfigCleanup(
|
|
15311
|
+
Storage.getRuntimeBaseDir(),
|
|
15312
|
+
sessionId
|
|
15313
|
+
);
|
|
15314
|
+
return this.newSessionConfigInRuntimeContext(
|
|
15315
|
+
cwd,
|
|
15316
|
+
mcpServers,
|
|
15317
|
+
settings,
|
|
15318
|
+
sessionId,
|
|
15319
|
+
resume,
|
|
15320
|
+
initializeOptions,
|
|
15321
|
+
chatRecording
|
|
15322
|
+
);
|
|
15323
|
+
});
|
|
15324
|
+
} catch (error) {
|
|
15325
|
+
const writerError = getSessionWriterError(error);
|
|
15326
|
+
if (writerError) {
|
|
15327
|
+
throw new RequestError(writerError.rpcCode, writerError.message, {
|
|
15328
|
+
errorKind: writerError.errorKind
|
|
15329
|
+
});
|
|
15330
|
+
}
|
|
15331
|
+
throw error;
|
|
15332
|
+
}
|
|
15333
|
+
}
|
|
15334
|
+
async newSessionConfigInRuntimeContext(cwd, mcpServers, settings, sessionId, resume, initializeOptions = {}, chatRecording) {
|
|
14342
15335
|
const sessionMcpServers = {};
|
|
14343
15336
|
for (const server of mcpServers) {
|
|
14344
15337
|
const stdioServer = toStdioServer(server);
|
|
@@ -14394,8 +15387,14 @@ ${outputText}
|
|
|
14394
15387
|
const sessionArg = resume === true ? { resume: sessionId, sessionId: void 0 } : { sessionId, resume: void 0 };
|
|
14395
15388
|
const argvForSession = {
|
|
14396
15389
|
...this.argv,
|
|
15390
|
+
// Docker sandbox relaunch injects a fixed --sandbox-session-id into
|
|
15391
|
+
// the ACP process argv. Without clearing it, every newSession()
|
|
15392
|
+
// inherits the same ID and the second session collides with the
|
|
15393
|
+
// first's writer lease (#7435).
|
|
15394
|
+
sandboxSessionId: void 0,
|
|
14397
15395
|
...sessionArg,
|
|
14398
|
-
continue: false
|
|
15396
|
+
continue: false,
|
|
15397
|
+
...chatRecording !== void 0 ? { chatRecording } : {}
|
|
14399
15398
|
};
|
|
14400
15399
|
const config = await loadCliConfig(
|
|
14401
15400
|
mergedSettings,
|
|
@@ -14449,15 +15448,22 @@ ${outputText}
|
|
|
14449
15448
|
});
|
|
14450
15449
|
});
|
|
14451
15450
|
}
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
|
|
14457
|
-
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
15451
|
+
try {
|
|
15452
|
+
await config.initialize({
|
|
15453
|
+
...initializeOptions,
|
|
15454
|
+
// Reverse tool channel (issue #5626, Phase 2): bind the session
|
|
15455
|
+
// manager's SDK MCP callback to the `client_mcp/message` ext-method so a
|
|
15456
|
+
// client-hosted (extension) MCP server added at runtime reaches the
|
|
15457
|
+
// daemon WS. Servers that aren't client-hosted never use this callback
|
|
15458
|
+
// (the daemon only adds SDK-type runtime servers for client MCP).
|
|
15459
|
+
sendSdkMcpMessage: this.buildClientMcpSender(wiredSessionId)
|
|
15460
|
+
});
|
|
15461
|
+
} catch (error) {
|
|
15462
|
+
return this.cleanupAfterRequestFailure(
|
|
15463
|
+
error,
|
|
15464
|
+
() => this.cleanupUnstoredConfig(config)
|
|
15465
|
+
);
|
|
15466
|
+
}
|
|
14461
15467
|
void this.surfaceMcpFailuresWhenReady(config);
|
|
14462
15468
|
return config;
|
|
14463
15469
|
}
|
|
@@ -14518,29 +15524,47 @@ ${outputText}
|
|
|
14518
15524
|
if (needsInitialize) {
|
|
14519
15525
|
await geminiClient.initialize();
|
|
14520
15526
|
}
|
|
14521
|
-
this.sessions.
|
|
15527
|
+
if (this.sessions.has(sessionId)) {
|
|
15528
|
+
throw new Error(`Session ${sessionId} is already active.`);
|
|
15529
|
+
}
|
|
14522
15530
|
const session = new Session(sessionId, config, this.connection, settings);
|
|
14523
15531
|
this.sessions.set(sessionId, session);
|
|
14524
|
-
|
|
14525
|
-
|
|
14526
|
-
|
|
14527
|
-
|
|
14528
|
-
|
|
14529
|
-
|
|
14530
|
-
|
|
14531
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
14535
|
-
|
|
14536
|
-
|
|
14537
|
-
)
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
15532
|
+
try {
|
|
15533
|
+
if (sessionData?.fileHistorySnapshots?.length) {
|
|
15534
|
+
config.getFileHistoryService().restoreFromSnapshots(sessionData.fileHistorySnapshots);
|
|
15535
|
+
}
|
|
15536
|
+
if (sessionData?.conversation.messages) {
|
|
15537
|
+
config.getChatRecordingService()?.rebuildTurnBoundaries(sessionData.conversation.messages);
|
|
15538
|
+
}
|
|
15539
|
+
if (options.replayHistory !== false && sessionData?.conversation.messages) {
|
|
15540
|
+
await session.replayHistory(
|
|
15541
|
+
sessionData.conversation.messages,
|
|
15542
|
+
sessionData.historyGaps
|
|
15543
|
+
);
|
|
15544
|
+
}
|
|
15545
|
+
if (options.startPostReplayServices !== false) {
|
|
15546
|
+
session.installRewriter();
|
|
15547
|
+
session.startCronScheduler();
|
|
15548
|
+
}
|
|
15549
|
+
setTimeout(() => {
|
|
15550
|
+
void session.sendAvailableCommandsUpdate();
|
|
15551
|
+
}, 0);
|
|
15552
|
+
return session;
|
|
15553
|
+
} catch (error) {
|
|
15554
|
+
try {
|
|
15555
|
+
await this.discardStoredSessionIfCurrent(sessionId, session, {
|
|
15556
|
+
shutdownConfig: false
|
|
15557
|
+
});
|
|
15558
|
+
} catch (cleanupError) {
|
|
15559
|
+
await this.removeStoredSessionEntry(
|
|
15560
|
+
sessionId,
|
|
15561
|
+
session,
|
|
15562
|
+
[cleanupError],
|
|
15563
|
+
{ shutdownConfig: false }
|
|
15564
|
+
);
|
|
15565
|
+
}
|
|
15566
|
+
throw error;
|
|
14542
15567
|
}
|
|
14543
|
-
return session;
|
|
14544
15568
|
}
|
|
14545
15569
|
buildAvailableModels(config) {
|
|
14546
15570
|
const rawCurrentModelId = (config.getModel() || this.config.getModel() || "").trim();
|