@qwen-code/qwen-code 0.19.2 → 0.19.3-nightly.20260630.e00fe6a27
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/extension-creator/SKILL.md +357 -0
- package/bundled/loop/SKILL.md +21 -7
- package/bundled/loop/SKILL.test.ts +41 -0
- package/bundled/loop/loop-task-file.test.ts +1064 -0
- package/bundled/loop/loop-task-file.ts +404 -0
- package/bundled/loop/loop-tick-resolver.test.ts +665 -0
- package/bundled/loop/loop-tick-resolver.ts +347 -0
- package/bundled/qc-helper/SKILL.md +26 -19
- package/bundled/qc-helper/docs/configuration/auth.md +11 -11
- package/bundled/qc-helper/docs/configuration/model-providers.md +13 -13
- package/bundled/qc-helper/docs/configuration/settings.md +76 -75
- package/bundled/qc-helper/docs/features/channels/plugins.md +1 -1
- package/bundled/qc-helper/docs/features/commands.md +108 -77
- package/bundled/qc-helper/docs/features/hooks.md +6 -1
- package/bundled/qc-helper/docs/features/memory.md +52 -0
- package/bundled/qc-helper/docs/qwen-serve.md +24 -2
- package/bundled/qc-helper/docs/support/tos-privacy.md +16 -3
- package/bundled/qc-helper/docs/support/troubleshooting.md +6 -0
- package/chunks/{MaxSizedBox-7RERNLFK.js → MaxSizedBox-T5X5MN5Q.js} +29 -27
- package/chunks/{StandaloneSessionPicker-S22XBSN6.js → StandaloneSessionPicker-P3E3WTOQ.js} +42 -37
- package/chunks/{acpAgent-4MCETHF2.js → acpAgent-QEP6DXFW.js} +864 -175
- package/chunks/{agent-K3ENVYSB.js → agent-UDANDUF7.js} +24 -23
- package/chunks/{agent-headless-HO3V3A3A.js → agent-headless-KYVSZHSO.js} +24 -23
- package/chunks/{anthropicContentGenerator-E3TQ5XJJ.js → anthropicContentGenerator-KWSJAQ7B.js} +33 -12
- package/chunks/{artifact-tool-QA4KRO3B.js → artifact-tool-D2X7G3C3.js} +2 -2
- package/chunks/{askUserQuestion-HMWXW6VN.js → askUserQuestion-UGETICJQ.js} +2 -2
- package/chunks/{bridge-4LV2HBH2.js → bridge-X42LXPTA.js} +31 -30
- package/chunks/{ca-7WC7ELX6.js → ca-IUFWESZL.js} +1 -0
- package/chunks/{chunk-JXQ23SNT.js → chunk-2JKEQWDZ.js} +623 -78
- package/chunks/{chunk-2TJ3YN6Q.js → chunk-2RJA6J57.js} +416 -401
- package/chunks/{chunk-3UALQ56H.js → chunk-3227DZO4.js} +1 -1
- package/chunks/{chunk-BGUDAULQ.js → chunk-3CPCDXFR.js} +5 -5
- package/chunks/{chunk-5RVSM6NW.js → chunk-3HUHAQF3.js} +1 -1
- package/chunks/{chunk-D5E5TMYH.js → chunk-3M4W4U5G.js} +16 -2
- package/chunks/{chunk-DBZUXSSV.js → chunk-4X7NIEQJ.js} +3 -3
- package/chunks/chunk-5GOVVXEV.js +73 -0
- package/chunks/{chunk-2BAQ3ACS.js → chunk-5SM4VT6V.js} +405 -5
- package/chunks/{chunk-NYOHZYHM.js → chunk-5XQ4A26L.js} +45 -3
- package/chunks/{chunk-CI5O6SQL.js → chunk-6FKEVYCD.js} +4 -4
- package/chunks/{chunk-ZD3NW5KL.js → chunk-7LM4XHPE.js} +63 -9
- package/chunks/chunk-7UNP2XM7.js +840 -0
- package/chunks/{chunk-OQHQHJRK.js → chunk-ARYCHZ4B.js} +151 -4775
- package/chunks/chunk-BC3C4F3Q.js +40 -0
- package/chunks/{chunk-CGEGHF2C.js → chunk-BKXBARJZ.js} +1 -1
- package/chunks/chunk-BMFMJINR.js +45 -0
- package/chunks/chunk-BOJWHRMX.js +11273 -0
- package/chunks/{chunk-CGOMICBE.js → chunk-BSZEQNUA.js} +34 -1
- package/chunks/{chunk-OIC6S73E.js → chunk-BUUQ5HPX.js} +1 -1
- package/chunks/{chunk-2BIF2NVV.js → chunk-BVSVIN45.js} +2 -2
- package/chunks/{chunk-TOEGRAVX.js → chunk-BX5YO7UW.js} +17 -5
- package/chunks/{chunk-4W4T77MO.js → chunk-BXVWV4GI.js} +109 -6
- package/chunks/{chunk-VQRYPFCV.js → chunk-CYHVPQYT.js} +10 -460
- package/chunks/{chunk-PRYMDRBV.js → chunk-DDMOU62Q.js} +1 -1
- package/chunks/{chunk-S566HKUS.js → chunk-DHXWNSJA.js} +15 -1
- package/chunks/{chunk-F6XNTYNE.js → chunk-E6XQPQXW.js} +30 -307
- package/chunks/{chunk-QBZ22PQX.js → chunk-EWALXUAD.js} +3 -1
- package/chunks/{chunk-EL5IHQON.js → chunk-EWYQFWYF.js} +6 -27
- package/chunks/{chunk-HG6YKEBI.js → chunk-F2DOT6UZ.js} +161 -30
- package/chunks/{chunk-JTYRZODB.js → chunk-FOOIZCWL.js} +16 -7
- package/chunks/{chunk-EX4W6ZYG.js → chunk-G5G4TFZ7.js} +1 -1
- package/chunks/{chunk-EW6C27XX.js → chunk-GEHVIWAT.js} +9 -3
- package/chunks/chunk-HEVBZSXG.js +4923 -0
- package/chunks/chunk-HFQ2XSE7.js +690 -0
- package/chunks/{chunk-PF523XJX.js → chunk-HPGTGMP3.js} +1 -1
- package/chunks/{chunk-OTBK43JR.js → chunk-HYCC3XM3.js} +1 -1
- package/chunks/{chunk-TMBPDHXD.js → chunk-I4H7PRWQ.js} +1 -1
- package/chunks/{chunk-EEEZIVFJ.js → chunk-JOLIREYR.js} +1 -1
- package/chunks/{chunk-TZM5JIAX.js → chunk-JYPQTRA3.js} +10 -7
- package/chunks/chunk-K5XU6E4T.js +167 -0
- package/chunks/{chunk-BS64PXY3.js → chunk-KFVU7ODN.js} +1 -1
- package/chunks/{chunk-3RJ3ZPPR.js → chunk-KKQWC6WS.js} +7 -7
- package/chunks/{chunk-3QFE4OTE.js → chunk-LBW7NW7X.js} +4 -4
- package/chunks/{chunk-Z7XXFPGP.js → chunk-LDWTYE33.js} +1 -1
- package/chunks/{chunk-EXMX5YHG.js → chunk-LP5E4YIH.js} +1 -1
- package/chunks/{chunk-ZUAXI2OA.js → chunk-M2U5NM24.js} +188 -11366
- package/chunks/{chunk-I5T6PIBQ.js → chunk-MBV2CTRL.js} +1010 -925
- package/chunks/{chunk-5JZLXFPD.js → chunk-MTHMXSNT.js} +11 -11
- package/chunks/{chunk-FPACXT7T.js → chunk-MTJVHQDP.js} +534 -164
- package/chunks/chunk-NDOC6M5S.js +481 -0
- package/chunks/{chunk-HGNSRCRB.js → chunk-NL4C3H6C.js} +1 -1
- package/chunks/{chunk-GZCJS5WH.js → chunk-O2VBQ3Y2.js} +2 -2
- package/chunks/{chunk-UN3C6GOR.js → chunk-PPFWEV7G.js} +10 -108
- package/chunks/{chunk-RS4HRC75.js → chunk-QI2CFVRF.js} +85 -8
- package/chunks/{chunk-XU5P23GN.js → chunk-QLDPRILK.js} +3 -3
- package/chunks/chunk-QYUE6W3T.js +123 -0
- package/chunks/{chunk-USGMPVOY.js → chunk-R3LHDWF2.js} +21 -12
- package/chunks/{chunk-BNXANYLH.js → chunk-RD6YJJJ6.js} +81 -1
- package/chunks/{chunk-PXFFKNCO.js → chunk-RIP623NO.js} +4877 -2469
- package/chunks/{chunk-XKBP7M7A.js → chunk-RYBSUGOR.js} +142 -30
- package/chunks/{chunk-BG4BIP7F.js → chunk-SBBN4BWR.js} +4 -2
- package/chunks/{chunk-T2VDEFUU.js → chunk-SKQZZVAV.js} +2 -2
- package/chunks/{chunk-5R4SBCX6.js → chunk-SL5MOGQH.js} +3 -3
- package/chunks/chunk-SMXULRAN.js +37 -0
- package/chunks/{chunk-WA5OJGFL.js → chunk-SS6WJMQK.js} +363 -76
- package/chunks/{chunk-UAARVVBI.js → chunk-TNWFHGN6.js} +1 -1
- package/chunks/{chunk-I2RFAW6Q.js → chunk-TT6Q3EN4.js} +7 -5
- package/chunks/chunk-UAKXW3DN.js +30 -0
- package/chunks/{chunk-C4K3FEQ2.js → chunk-UX4SGCGN.js} +32 -3
- package/chunks/{chunk-J6AW7O5D.js → chunk-WHDQZHRU.js} +2 -2
- package/chunks/{chunk-WGAEWQTF.js → chunk-WN6K47NR.js} +1 -2
- package/chunks/{chunk-UAARJR2G.js → chunk-WQT5SOI6.js} +2 -2
- package/chunks/{chunk-VYFMN7C6.js → chunk-WUMVIRTN.js} +225 -37
- package/chunks/{chunk-R36VMVEP.js → chunk-XJMKOTVV.js} +5 -5
- package/chunks/{chunk-TXVGVZYR.js → chunk-XJYUPHRC.js} +3 -3
- package/chunks/{chunk-2JD55C6G.js → chunk-Y6YMRS3U.js} +2 -2
- package/chunks/{chunk-LLFFKXZZ.js → chunk-YALKC62D.js} +56 -29
- package/chunks/{chunk-GYZQA2FO.js → chunk-YLZJCUH6.js} +1 -1
- package/chunks/chunk-YTFBURQD.js +313 -0
- package/chunks/{chunk-KBXLIVWQ.js → chunk-ZFPRYHWR.js} +2 -2
- package/chunks/{chunk-X6EDWN44.js → chunk-ZP6UKOPB.js} +1 -1
- package/chunks/{computer-use-6BBRNT6S.js → computer-use-LF2S6LUZ.js} +103 -49
- package/chunks/{contextCommand-UJAJ6N57.js → contextCommand-VPX5UG55.js} +26 -25
- package/chunks/{cron-create-4KQE6YLH.js → cron-create-SKEY55RG.js} +4 -4
- package/chunks/{cron-delete-THME66UP.js → cron-delete-I3NAT32Z.js} +6 -6
- package/chunks/{cron-list-7A54SJ5N.js → cron-list-6XRRL6TH.js} +5 -5
- package/chunks/{daemon-status-provider-CSL3BUOY.js → daemon-status-provider-5JAWZS4V.js} +34 -34
- package/chunks/{de-ACHALDED.js → de-EOW5PVHF.js} +1 -0
- package/chunks/{dist-BD27IA3L.js → dist-4FCNM6KJ.js} +2 -2
- package/chunks/{dist-OD2FY543.js → dist-O3H4PABL.js} +2 -2
- package/chunks/{dist-BOOH5JWN.js → dist-SCAAUWPS.js} +18 -4
- package/chunks/{dist-QHJRBCMP.js → dist-UKPWQJCL.js} +44 -2
- package/chunks/{dist-QFFZWACU.js → dist-VD7HXTML.js} +20 -9
- package/chunks/{earlyInputCapture-X6KMCSHD.js → earlyInputCapture-7FRQMU4P.js} +25 -24
- package/chunks/{edit-7J6WXARF.js → edit-REKJDIRL.js} +68 -27
- package/chunks/{en-NCUBOJOY.js → en-HPWEJBTR.js} +8 -0
- package/chunks/{enter-worktree-KULCKJPJ.js → enter-worktree-GBKUDCD3.js} +24 -23
- package/chunks/{enterPlanMode-H2CIOLMH.js → enterPlanMode-WB3Y4FGT.js} +24 -23
- package/chunks/{errors-6G2JYR54.js → errors-2XJDYO3M.js} +26 -25
- package/chunks/{exit-worktree-ECBWBVC5.js → exit-worktree-KKC7O2ZV.js} +24 -23
- package/chunks/{exitPlanMode-DQV56GTW.js → exitPlanMode-7HMS3TF7.js} +24 -23
- package/chunks/{fast-path-35JJFS3C.js → fast-path-XVNIYWGG.js} +4 -4
- package/chunks/{fast-path-settings-TSVI53EB.js → fast-path-settings-UQLRFDQP.js} +3 -2
- package/chunks/{fr-GVKZ27MF.js → fr-BN5NKSAC.js} +1 -0
- package/chunks/{gemini-NDTG7WAX.js → gemini-U5TPU3IQ.js} +210 -104
- package/chunks/{geminiContentGenerator-XTG6SFLA.js → geminiContentGenerator-ZVWRHXOO.js} +4 -4
- package/chunks/{glob-SJ2JBZK4.js → glob-FEJWIH2W.js} +24 -23
- package/chunks/{grep-BRMWFEWR.js → grep-KMP25IIA.js} +24 -23
- package/chunks/{headlessSafetyWarnings-LJ6FJX77.js → headlessSafetyWarnings-5DEDET4M.js} +24 -23
- package/chunks/{initializer-P5AXF7PV.js → initializer-FJTACLOH.js} +31 -28
- package/chunks/{ja-FKZ2WZ4D.js → ja-7DEUB2TS.js} +1 -0
- package/chunks/{keychain-token-storage-CSYMNRPP.js → keychain-token-storage-YLMDLKXT.js} +2 -2
- package/chunks/{list-6COK34BP.js → list-SCQXYJUW.js} +32 -29
- package/chunks/{loadedSettingsAdapter-XIUTN245.js → loadedSettingsAdapter-P6KPNAG7.js} +30 -27
- package/chunks/{loop-wakeup-33GPXJLA.js → loop-wakeup-FYEQEJUA.js} +7 -7
- package/chunks/{ls-BYQY7RVV.js → ls-R5WP4BGZ.js} +4 -4
- package/chunks/{lsp-X54RO4IV.js → lsp-GSICJMMW.js} +2 -2
- package/chunks/{monitor-DH7KFSJV.js → monitor-JU3HHHVY.js} +24 -23
- package/chunks/nonInteractiveCli-IZEKUHU3.js +100 -0
- package/chunks/{notebook-edit-D4R4ZLMA.js → notebook-edit-YHY3Z2QQ.js} +52 -23
- package/chunks/{openaiContentGenerator-F74IPQ6E.js → openaiContentGenerator-4WUVA3Q2.js} +13 -12
- package/chunks/{pt-SY5NCFGR.js → pt-TNZRNLQB.js} +1 -0
- package/chunks/{qwenContentGenerator-ATTK5P4D.js → qwenContentGenerator-MVYYR44B.js} +26 -25
- package/chunks/{qwenOAuth2-K4AASPCV.js → qwenOAuth2-6HNGHALT.js} +5 -4
- package/chunks/{read-file-767G23OY.js → read-file-NABEO2X4.js} +8 -8
- package/chunks/{read-mcp-resource-I5HCZJ6X.js → read-mcp-resource-DQQW7H7T.js} +2 -2
- package/chunks/{ripGrep-4OMMGSWX.js → ripGrep-YXLK6UTX.js} +24 -23
- package/chunks/{ru-FWNXJG4F.js → ru-NIAUBKCN.js} +1 -0
- package/chunks/{run-qwen-serve-REKSTYRA.js → run-qwen-serve-4B5QBMLQ.js} +144 -41
- package/chunks/{scheduler-UNTFDQLG.js → scheduler-XAKIYBDL.js} +24 -23
- package/chunks/{send-message-2DAFXEYP.js → send-message-EE4TWKVU.js} +2 -2
- package/chunks/{serve-KZ56QB5S.js → serve-4RXVLUKD.js} +30 -28
- package/chunks/{server-BV5TZUMU.js → server-7PA5QGIA.js} +11037 -8747
- package/chunks/{session-OIBXFSGD.js → session-WNVWRYAH.js} +194 -57
- package/chunks/{settings-WJTCBIRA.js → settings-YJH32TFF.js} +30 -27
- package/chunks/{shell-WC52IBHW.js → shell-YFLABOS5.js} +24 -23
- package/chunks/{skill-U7F7JR4M.js → skill-N3J7FUAY.js} +38 -11
- package/chunks/{spawnChannel-EI2E5BCW.js → spawnChannel-D6WVMFZJ.js} +26 -25
- package/chunks/{src-4F6FBZFI.js → src-IU5GDBEH.js} +88 -28
- package/chunks/{startInteractiveUI-SFRVB3CE.js → startInteractiveUI-QIPQTRT4.js} +2784 -2474
- package/chunks/{syntheticOutput-PPS3HDVA.js → syntheticOutput-T5YHQ6S2.js} +3 -3
- package/chunks/{task-create-OUYCA553.js → task-create-BLY7RHXX.js} +6 -6
- package/chunks/{task-list-WAX7I2IA.js → task-list-3QUYNVYR.js} +5 -5
- package/chunks/{task-stop-CAIL6FNH.js → task-stop-U4RATK2V.js} +2 -2
- package/chunks/{task-update-AHEO5OUT.js → task-update-U54O7KJX.js} +6 -6
- package/chunks/{team-create-3WC7CIIW.js → team-create-TP4CLLM3.js} +24 -23
- package/chunks/{team-delete-HGHFG23B.js → team-delete-LKBYPASD.js} +5 -5
- package/chunks/{theme-manager-DICFCT3P.js → theme-manager-N2TBIBZT.js} +25 -24
- package/chunks/{todoWrite-IFBMN3FH.js → todoWrite-OYXKTVYN.js} +4 -4
- package/chunks/{tool-search-L5K7HLER.js → tool-search-GBBSICYB.js} +101 -16
- package/chunks/trustedFolders-F7TBU5CD.js +76 -0
- package/chunks/types-QX5C3CHJ.js +12 -0
- package/chunks/{validateNonInterActiveAuth-GCH4Z6KI.js → validateNonInterActiveAuth-EQDQPSMI.js} +55 -50
- package/chunks/{web-fetch-B5IIQ5TT.js → web-fetch-PCVCML2X.js} +29 -15
- package/chunks/{workflow-OB3AND7I.js → workflow-ANJ4FYBK.js} +32 -30
- package/chunks/{workspace-providers-status-ZIR5EPOO.js → workspace-providers-status-462QQKQM.js} +32 -29
- package/chunks/workspace-service-VTG4G6CW.js +75 -0
- package/chunks/{write-file-SEXBNDZM.js → write-file-3P3WMQQW.js} +63 -27
- package/chunks/{zh-RBEGQVQT.js → zh-5EUYXASN.js} +8 -0
- package/chunks/{zh-TW-QGAVRXT3.js → zh-TW-TR3XYGE5.js} +8 -0
- package/cli-entry.js +20 -9
- package/cli.js +6 -6
- package/locales/ca.js +2 -0
- package/locales/de.js +2 -0
- package/locales/en.js +14 -0
- package/locales/fr.js +2 -0
- package/locales/ja.js +1 -0
- package/locales/pt.js +2 -0
- package/locales/ru.js +2 -0
- package/locales/zh-TW.js +12 -0
- package/locales/zh.js +12 -0
- package/node_modules/@qwen-code/audio-capture/dist/index.d.ts +35 -0
- package/node_modules/@qwen-code/audio-capture/dist/index.js +48 -0
- package/node_modules/@qwen-code/audio-capture/dist/index.js.map +1 -0
- package/node_modules/@qwen-code/audio-capture/dist/platform.d.ts +7 -0
- package/node_modules/@qwen-code/audio-capture/dist/platform.js +18 -0
- package/node_modules/@qwen-code/audio-capture/dist/platform.js.map +1 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/LICENSE +21 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/README.md +58 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/SECURITY.md +5 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/bin.js +84 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/build-test.js +19 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/index.js +6 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/node-gyp-build.js +207 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/optional.js +7 -0
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/package.json +43 -0
- package/node_modules/@qwen-code/audio-capture/package.json +30 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/linux-arm64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/linux-x64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
- package/package.json +18 -6
- package/patches/chrome-devtools-mcp+1.4.0.patch +31 -0
- package/postinstall.js +50 -0
- package/web-shell/assets/{arc-D_ae_Y9k.js → arc-DIemsO_F.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-BMLRjppa.js → architectureDiagram-3BPJPVTR-CTlUvIQv.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-qVDQC8KL.js → blockDiagram-GPEHLZMM-DG0jmIZK.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-CxWS6MBd.js → c4Diagram-AAUBKEIU-WljDBi55.js} +1 -1
- package/web-shell/assets/channel-CbzRbdpA.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-BtNuY5Yp.js → chunk-2J33WTMH-8nc6onr2.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-BU-x368d.js → chunk-4BX2VUAB-EopXix8Z.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-DRgTLvBu.js → chunk-55IACEB6-BE4Jz3N3.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-D2aElv7q.js → chunk-727SXJPM-C_eErgDN.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-BwHCMRQ0.js → chunk-AQP2D5EJ-DFtVW-Is.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-BMyPH-ku.js → chunk-FMBD7UC4-CJPyxIg9.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-BNKTstUf.js → chunk-ND2GUHAM-Bk-xgj6M.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-gD3vsFId.js → chunk-QZHKN3VN-p3Y4yaFB.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-BFdyQ52h.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BFdyQ52h.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-BG9FAsXE.js → cose-bilkent-S5V4N54A-BCMO6Js3.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-Cy1sR7om.js → dagre-BM42HDAG-DUMrwASf.js} +1 -1
- package/web-shell/assets/default-aEtf0G7-.svg +1 -0
- package/web-shell/assets/{diagram-2AECGRRQ-Bxi1I_Vu.js → diagram-2AECGRRQ-C5d7qJbL.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BGCJjO6y.js → diagram-5GNKFQAL-CjLzMhbT.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-CMTeLXp7.js → diagram-KO2AKTUF-RCoNWeAm.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-BN1wyAGh.js → diagram-LMA3HP47-KThXjaNV.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-UYSG_zcp.js → diagram-OG6HWLK6-DKsC2BWz.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-DqXL08lw.js → erDiagram-TEJ5UH35-DJ2ukmq0.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-BPJ9SFji.js → flowDiagram-I6XJVG4X-zzqaARRX.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-BEd9Pnms.js → ganttDiagram-6RSMTGT7-kFUg-gqT.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-DrNRH3oi.js → gitGraphDiagram-PVQCEYII-C6JnMVzD.js} +1 -1
- package/web-shell/assets/index-B3XUm7dw.js +713 -0
- package/web-shell/assets/index-CHmzAWys.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-CFYBrkVI.js → infoDiagram-5YYISTIA-XqPVhp89.js} +1 -1
- package/web-shell/assets/insert-DmRbh9Rv.svg +1 -0
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-Dxsddth7.js → ishikawaDiagram-YF4QCWOH-D2k8sGpf.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-DxaDK80t.js → journeyDiagram-JHISSGLW-CQEST1GE.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-Q0jQCOct.js → kanban-definition-UN3LZRKU-DZ7kqVBC.js} +1 -1
- package/web-shell/assets/{linear-DGGM2kcP.js → linear-B6C_6q_E.js} +1 -1
- package/web-shell/assets/{mermaid.core-ByoxnWut.js → mermaid.core-CsyNP1qt.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-C0ZseHsi.js → mindmap-definition-RKZ34NQL-B1VDIzJq.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-MQXNhl5A.js → pieDiagram-4H26LBE5-DN0E7Jwu.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-DIR4ee2A.js → quadrantDiagram-W4KKPZXB-UKTQdHKm.js} +1 -1
- package/web-shell/assets/queue-DWpnpFgW.svg +1 -0
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-BTR0UdYQ.js → requirementDiagram-4Y6WPE33-BRGceQvN.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-sfnhMELN.js → sankeyDiagram-5OEKKPKP-2DDyu41v.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DXczHOHH.js → sequenceDiagram-3UESZ5HK-CT5iE8ZU.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-DdE_KQFH.js → stateDiagram-AJRCARHV-CqMQ_s4G.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CamhV5pM.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-DIc61uE8.js → timeline-definition-PNZ67QCA-Di37QSZU.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-BF7ODmxB.js → vennDiagram-CIIHVFJN-DCXvpz5S.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-3pc1MEaw.js → wardley-L42UT6IY-CpUCk6OX.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-9jnPcZuP.js → wardleyDiagram-YWT4CUSO-D01pVEBg.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-DcthaZK6.js → xychartDiagram-2RQKCTM6-DOu5JDoz.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-B6HQGTYR.js +0 -410
- package/chunks/chunk-R2BXK7SX.js +0 -13
- package/chunks/chunk-RKIZXJMB.js +0 -13
- package/chunks/nonInteractiveCli-7575LBXP.js +0 -91
- package/chunks/workspace-service-OM5D4OI2.js +0 -60
- package/web-shell/assets/channel-DYPNiTww.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-p_g25Tni.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-p_g25Tni.js +0 -1
- package/web-shell/assets/index-CpOXWDPh.js +0 -714
- package/web-shell/assets/index-oVK7qhre.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BHUSEndU.js +0 -1
|
@@ -3,8 +3,13 @@
|
|
|
3
3
|
import {
|
|
4
4
|
classifyApiError,
|
|
5
5
|
prefixMidTurnUserMessageParts
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import
|
|
6
|
+
} from "./chunk-YALKC62D.js";
|
|
7
|
+
import {
|
|
8
|
+
EXTENSION_CONTEXT_BUDGET,
|
|
9
|
+
buildExtensionMentionContext,
|
|
10
|
+
matchExtensionByRef,
|
|
11
|
+
parseExtensionRef
|
|
12
|
+
} from "./chunk-7UNP2XM7.js";
|
|
8
13
|
import {
|
|
9
14
|
HistoryReplayer,
|
|
10
15
|
MessageEmitter,
|
|
@@ -12,105 +17,118 @@ import {
|
|
|
12
17
|
ToolCallEmitter,
|
|
13
18
|
getAvailableCommands,
|
|
14
19
|
handleSlashCommand,
|
|
20
|
+
insertAfterFunctionResponses,
|
|
15
21
|
isSlashCommand,
|
|
16
22
|
normalizePartList
|
|
17
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-2RJA6J57.js";
|
|
18
24
|
import {
|
|
19
25
|
appEvents,
|
|
20
26
|
buildDisabledSkillNamesProvider,
|
|
21
27
|
loadCliConfig,
|
|
22
28
|
normalizeDisabledToolList
|
|
23
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-BOJWHRMX.js";
|
|
30
|
+
import {
|
|
31
|
+
collectContextData,
|
|
32
|
+
formatContextUsageText
|
|
33
|
+
} from "./chunk-JYPQTRA3.js";
|
|
24
34
|
import {
|
|
25
35
|
getCommandSubcommandNames
|
|
26
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-BXVWV4GI.js";
|
|
37
|
+
import "./chunk-5GOVVXEV.js";
|
|
27
38
|
import {
|
|
28
39
|
getEffectiveSupportedModes
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-MRO43B25.js";
|
|
31
|
-
import "./chunk-UAARJR2G.js";
|
|
32
|
-
import "./chunk-JZSY4WP3.js";
|
|
33
|
-
import {
|
|
34
|
-
collectContextData,
|
|
35
|
-
formatContextUsageText
|
|
36
|
-
} from "./chunk-TZM5JIAX.js";
|
|
40
|
+
} from "./chunk-FOOIZCWL.js";
|
|
37
41
|
import {
|
|
38
42
|
isTerminalGoalStatusKind
|
|
39
43
|
} from "./chunk-KSPVDFE4.js";
|
|
44
|
+
import "./chunk-MRO43B25.js";
|
|
45
|
+
import "./chunk-SMXULRAN.js";
|
|
46
|
+
import "./chunk-WQT5SOI6.js";
|
|
40
47
|
import "./chunk-KYMBIKIW.js";
|
|
41
|
-
import "./chunk-
|
|
48
|
+
import "./chunk-I4H7PRWQ.js";
|
|
49
|
+
import "./chunk-JZSY4WP3.js";
|
|
50
|
+
import "./chunk-4X7NIEQJ.js";
|
|
51
|
+
import "./chunk-TT6Q3EN4.js";
|
|
42
52
|
import "./chunk-3GONHQOA.js";
|
|
43
|
-
import "./chunk-
|
|
44
|
-
import "./chunk-
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-TMBPDHXD.js";
|
|
53
|
+
import "./chunk-SL5MOGQH.js";
|
|
54
|
+
import "./chunk-LDWTYE33.js";
|
|
55
|
+
import "./chunk-2JKEQWDZ.js";
|
|
47
56
|
import {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
import "./chunk-NYOHZYHM.js";
|
|
55
|
-
import "./chunk-CGOMICBE.js";
|
|
56
|
-
import "./chunk-RKIZXJMB.js";
|
|
57
|
-
import "./chunk-CI5O6SQL.js";
|
|
57
|
+
isValidServerName
|
|
58
|
+
} from "./chunk-UAKXW3DN.js";
|
|
59
|
+
import "./chunk-NDOC6M5S.js";
|
|
60
|
+
import "./chunk-M2U5NM24.js";
|
|
61
|
+
import "./chunk-BSZEQNUA.js";
|
|
62
|
+
import "./chunk-6FKEVYCD.js";
|
|
58
63
|
import "./chunk-KHDZHZMH.js";
|
|
64
|
+
import "./chunk-ALX6BUYW.js";
|
|
59
65
|
import {
|
|
60
|
-
|
|
61
|
-
|
|
66
|
+
AgentSideConnection,
|
|
67
|
+
PROTOCOL_VERSION,
|
|
68
|
+
RequestError,
|
|
69
|
+
ndJsonStream
|
|
70
|
+
} from "./chunk-UFC57OYT.js";
|
|
62
71
|
import {
|
|
63
72
|
formatAcpModelId,
|
|
64
73
|
parseAcpBaseModelId,
|
|
65
74
|
parseAcpModelOption,
|
|
66
75
|
sanitizeProviderBaseUrl
|
|
67
|
-
} from "./chunk-
|
|
76
|
+
} from "./chunk-QI2CFVRF.js";
|
|
77
|
+
import {
|
|
78
|
+
PERMISSION_RULE_TYPES,
|
|
79
|
+
PermissionRulesValidationError,
|
|
80
|
+
buildPermissionSettings,
|
|
81
|
+
normalizePermissionRules,
|
|
82
|
+
readPermissionRuleSet
|
|
83
|
+
} from "./chunk-WN6K47NR.js";
|
|
84
|
+
import "./chunk-5XQ4A26L.js";
|
|
85
|
+
import "./chunk-BC3C4F3Q.js";
|
|
68
86
|
import {
|
|
69
87
|
NOT_CURRENTLY_GENERATING_CANCEL_MESSAGE
|
|
70
|
-
} from "./chunk-
|
|
71
|
-
import
|
|
88
|
+
} from "./chunk-DHXWNSJA.js";
|
|
89
|
+
import {
|
|
90
|
+
ACP_PREFLIGHT_KINDS,
|
|
91
|
+
IDLE_HOOK_EVENTS,
|
|
92
|
+
SERVE_CONTROL_EXT_METHODS,
|
|
93
|
+
SERVE_STATUS_EXT_METHODS,
|
|
94
|
+
STATUS_SCHEMA_VERSION,
|
|
95
|
+
mapDomainErrorToErrorKind
|
|
96
|
+
} from "./chunk-3M4W4U5G.js";
|
|
97
|
+
import "./chunk-KFVU7ODN.js";
|
|
98
|
+
import {
|
|
99
|
+
CLIENT_MCP_OVER_WS_CONFIG_FLAG,
|
|
100
|
+
MID_TURN_QUEUE_DRAIN_METHOD
|
|
101
|
+
} from "./chunk-EWALXUAD.js";
|
|
72
102
|
import "./chunk-SEZC2725.js";
|
|
73
|
-
import "./chunk-DBZUXSSV.js";
|
|
74
|
-
import "./chunk-R2BXK7SX.js";
|
|
75
|
-
import "./chunk-ALX6BUYW.js";
|
|
76
103
|
import "./chunk-5DWXLGOM.js";
|
|
77
104
|
import {
|
|
78
105
|
createLoadedSettingsAdapter
|
|
79
|
-
} from "./chunk-
|
|
106
|
+
} from "./chunk-3HUHAQF3.js";
|
|
80
107
|
import {
|
|
81
108
|
OUTPUT_LANGUAGE_AUTO,
|
|
82
109
|
getOutputLanguageFilePath,
|
|
83
110
|
getPersistScopeForModelSelection,
|
|
84
111
|
isAutoLanguage,
|
|
85
|
-
isWorkspaceTrusted,
|
|
86
112
|
loadSettings,
|
|
87
113
|
reloadEnvironment,
|
|
88
114
|
resolveOutputLanguage,
|
|
89
115
|
updateOutputLanguageFile,
|
|
90
116
|
writeOutputLanguageAndRegisterPath
|
|
91
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-HEVBZSXG.js";
|
|
92
118
|
import {
|
|
93
119
|
SUPPORTED_LANGUAGES,
|
|
94
120
|
getCurrentLanguage,
|
|
95
121
|
setLanguageAsync
|
|
96
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-MTHMXSNT.js";
|
|
97
123
|
import "./chunk-TLRYABYP.js";
|
|
98
|
-
import "./chunk-
|
|
99
|
-
import {
|
|
100
|
-
AgentSideConnection,
|
|
101
|
-
PROTOCOL_VERSION,
|
|
102
|
-
RequestError,
|
|
103
|
-
ndJsonStream
|
|
104
|
-
} from "./chunk-UFC57OYT.js";
|
|
124
|
+
import "./chunk-PPFWEV7G.js";
|
|
105
125
|
import {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
} from "./chunk-D5E5TMYH.js";
|
|
113
|
-
import "./chunk-UN3C6GOR.js";
|
|
126
|
+
isFolderTrustEnabled,
|
|
127
|
+
isWorkspaceTrusted,
|
|
128
|
+
loadTrustedFolders
|
|
129
|
+
} from "./chunk-ARYCHZ4B.js";
|
|
130
|
+
import "./chunk-Y6Z2O3WR.js";
|
|
131
|
+
import "./chunk-QYUE6W3T.js";
|
|
114
132
|
import {
|
|
115
133
|
ALL_PROVIDERS,
|
|
116
134
|
APPROVAL_MODES,
|
|
@@ -119,6 +137,7 @@ import {
|
|
|
119
137
|
ExtensionManager,
|
|
120
138
|
FORK_SUBAGENT_TYPE,
|
|
121
139
|
InvalidMcpConfigError,
|
|
140
|
+
LoopTickResolver,
|
|
122
141
|
MAX_TRANSCRIPT_MESSAGES,
|
|
123
142
|
MCPOAuthProvider,
|
|
124
143
|
MCPOAuthTokenStorage,
|
|
@@ -127,9 +146,11 @@ import {
|
|
|
127
146
|
McpBudgetWouldExceedError,
|
|
128
147
|
McpServerSpawnFailedError,
|
|
129
148
|
McpTransportPool,
|
|
149
|
+
ORPHAN_TOOL_USE_REPAIR_REASON,
|
|
130
150
|
POOLED_TRANSPORTS_DEFAULT,
|
|
131
151
|
SESSION_TITLE_MAX_LENGTH,
|
|
132
152
|
SessionService,
|
|
153
|
+
TURN_INTERRUPTION_HISTORY_TAIL_COUNT,
|
|
133
154
|
WorkspaceMcpBudget,
|
|
134
155
|
abortGoalForStopHookCap,
|
|
135
156
|
acquireSleepInhibitor,
|
|
@@ -138,17 +159,22 @@ import {
|
|
|
138
159
|
buildBackgroundEntryLabel,
|
|
139
160
|
buildBtwCacheSafeParams,
|
|
140
161
|
buildBtwPrompt,
|
|
162
|
+
buildContextUsage,
|
|
141
163
|
buildInstallPlan,
|
|
164
|
+
buildSyntheticToolResponseParts,
|
|
142
165
|
clampInlineMediaPart,
|
|
143
166
|
clearGoalTerminalObserver,
|
|
144
167
|
computeUniqueBranchTitle,
|
|
145
168
|
convertToFunctionResponse,
|
|
146
169
|
createDuplicateProviderToolCallResponse,
|
|
147
170
|
dedupeToolCallsById,
|
|
171
|
+
detectLoopSentinel,
|
|
172
|
+
detectTurnInterruption,
|
|
148
173
|
evaluateAutoMode,
|
|
149
174
|
evaluatePermissionFlow,
|
|
150
175
|
findExistingProviderModels,
|
|
151
176
|
findProviderById,
|
|
177
|
+
findRepeatedDuplicateProviderToolCall,
|
|
152
178
|
fireNotificationHook,
|
|
153
179
|
firePermissionRequestHook,
|
|
154
180
|
firePostToolUseFailureHook,
|
|
@@ -174,6 +200,7 @@ import {
|
|
|
174
200
|
isDenialFallbackReason,
|
|
175
201
|
isPlanModeBlocked,
|
|
176
202
|
isSystemReminderContent,
|
|
203
|
+
markDuplicateProviderToolCallResponseSent,
|
|
177
204
|
needsConfirmation,
|
|
178
205
|
parsePositiveIntegerEnv,
|
|
179
206
|
persistPermissionOutcome,
|
|
@@ -193,32 +220,32 @@ import {
|
|
|
193
220
|
subagentGenerator,
|
|
194
221
|
unregisterGoalHook,
|
|
195
222
|
updateSetting
|
|
196
|
-
} from "./chunk-
|
|
223
|
+
} from "./chunk-RIP623NO.js";
|
|
197
224
|
import {
|
|
198
225
|
external_exports
|
|
199
226
|
} from "./chunk-K5PGHDBN.js";
|
|
200
227
|
import "./chunk-5P5XGNYH.js";
|
|
201
228
|
import "./chunk-SKAZWEV5.js";
|
|
202
|
-
import "./chunk-
|
|
203
|
-
import "./chunk-
|
|
204
|
-
import "./chunk-
|
|
229
|
+
import "./chunk-XJYUPHRC.js";
|
|
230
|
+
import "./chunk-QLDPRILK.js";
|
|
231
|
+
import "./chunk-BVSVIN45.js";
|
|
205
232
|
import {
|
|
206
233
|
runSideQuery
|
|
207
|
-
} from "./chunk-
|
|
208
|
-
import "./chunk-
|
|
234
|
+
} from "./chunk-SBBN4BWR.js";
|
|
235
|
+
import "./chunk-7LM4XHPE.js";
|
|
209
236
|
import "./chunk-2MPVVENX.js";
|
|
210
237
|
import "./chunk-ZTQ26VBE.js";
|
|
211
|
-
import "./chunk-
|
|
238
|
+
import "./chunk-O2VBQ3Y2.js";
|
|
212
239
|
import "./chunk-MLZQVCF3.js";
|
|
213
240
|
import "./chunk-LQ7TMOCE.js";
|
|
214
241
|
import "./chunk-LD2XBG6Z.js";
|
|
215
|
-
import "./chunk-
|
|
242
|
+
import "./chunk-HYCC3XM3.js";
|
|
216
243
|
import {
|
|
217
244
|
HookEventName,
|
|
218
245
|
createHookOutput
|
|
219
|
-
} from "./chunk-
|
|
220
|
-
import "./chunk-
|
|
221
|
-
import "./chunk-
|
|
246
|
+
} from "./chunk-NL4C3H6C.js";
|
|
247
|
+
import "./chunk-JOLIREYR.js";
|
|
248
|
+
import "./chunk-DDMOU62Q.js";
|
|
222
249
|
import {
|
|
223
250
|
AuthType,
|
|
224
251
|
ConversationFinishedEvent,
|
|
@@ -239,46 +266,48 @@ import {
|
|
|
239
266
|
startToolSpan,
|
|
240
267
|
uiTelemetryService,
|
|
241
268
|
withInteractionSpan
|
|
242
|
-
} from "./chunk-
|
|
269
|
+
} from "./chunk-SS6WJMQK.js";
|
|
243
270
|
import "./chunk-3PJXIDKI.js";
|
|
244
271
|
import "./chunk-UWCTAVOD.js";
|
|
245
272
|
import "./chunk-OFEVLU4C.js";
|
|
246
273
|
import "./chunk-OMX7CUOE.js";
|
|
247
274
|
import {
|
|
248
275
|
getAutoMemoryRoot
|
|
249
|
-
} from "./chunk-
|
|
250
|
-
import "./chunk-
|
|
251
|
-
import "./chunk-
|
|
276
|
+
} from "./chunk-RD6YJJJ6.js";
|
|
277
|
+
import "./chunk-SKQZZVAV.js";
|
|
278
|
+
import "./chunk-BUUQ5HPX.js";
|
|
252
279
|
import {
|
|
253
280
|
ToolConfirmationOutcome,
|
|
254
281
|
ToolNames
|
|
255
|
-
} from "./chunk-
|
|
282
|
+
} from "./chunk-BX5YO7UW.js";
|
|
256
283
|
import {
|
|
257
284
|
clearCachedCredentialFile,
|
|
258
285
|
qwenOAuth2Events
|
|
259
|
-
} from "./chunk-
|
|
260
|
-
import "./chunk-
|
|
286
|
+
} from "./chunk-3CPCDXFR.js";
|
|
287
|
+
import "./chunk-GEHVIWAT.js";
|
|
261
288
|
import "./chunk-22IFUCVR.js";
|
|
262
|
-
import "./chunk-
|
|
263
|
-
import "./chunk-3UALQ56H.js";
|
|
289
|
+
import "./chunk-3227DZO4.js";
|
|
264
290
|
import {
|
|
291
|
+
DEFAULT_TOKEN_LIMIT,
|
|
265
292
|
tokenLimit
|
|
266
|
-
} from "./chunk-
|
|
267
|
-
import "./chunk-
|
|
293
|
+
} from "./chunk-YTFBURQD.js";
|
|
294
|
+
import "./chunk-BKXBARJZ.js";
|
|
268
295
|
import "./chunk-IRJWHZWU.js";
|
|
269
296
|
import "./chunk-SYCJMSIJ.js";
|
|
270
297
|
import "./chunk-55ZMG67I.js";
|
|
271
298
|
import "./chunk-H6BD2ELD.js";
|
|
272
299
|
import "./chunk-5IFG2VC4.js";
|
|
300
|
+
import "./chunk-64WXLC72.js";
|
|
301
|
+
import "./chunk-E6XQPQXW.js";
|
|
273
302
|
import {
|
|
274
303
|
Storage,
|
|
275
304
|
createDebugLogger,
|
|
276
305
|
getErrorStatus
|
|
277
|
-
} from "./chunk-
|
|
278
|
-
import "./chunk-
|
|
306
|
+
} from "./chunk-UX4SGCGN.js";
|
|
307
|
+
import "./chunk-HPGTGMP3.js";
|
|
279
308
|
import {
|
|
280
309
|
runExitCleanup
|
|
281
|
-
} from "./chunk-
|
|
310
|
+
} from "./chunk-YLZJCUH6.js";
|
|
282
311
|
import "./chunk-ZERZSAZL.js";
|
|
283
312
|
import "./chunk-QN5NZ3UQ.js";
|
|
284
313
|
import "./chunk-BR4QREVK.js";
|
|
@@ -391,11 +420,14 @@ var AcpFileSystemService = class {
|
|
|
391
420
|
import { Readable, Writable } from "node:stream";
|
|
392
421
|
import { pipeline } from "node:stream/promises";
|
|
393
422
|
import * as fs from "node:fs/promises";
|
|
394
|
-
import
|
|
423
|
+
import { createRequire } from "node:module";
|
|
424
|
+
import * as path2 from "node:path";
|
|
395
425
|
import { createGunzip } from "node:zlib";
|
|
396
426
|
|
|
397
427
|
// packages/cli/src/acp-integration/session/Session.ts
|
|
398
428
|
init_esbuild_shims();
|
|
429
|
+
import * as os from "node:os";
|
|
430
|
+
import * as path from "node:path";
|
|
399
431
|
|
|
400
432
|
// packages/cli/src/acp-integration/session/SubAgentTracker.ts
|
|
401
433
|
init_esbuild_shims();
|
|
@@ -1087,6 +1119,7 @@ __name(loadRewriteConfig, "loadRewriteConfig");
|
|
|
1087
1119
|
var debugLogger4 = createDebugLogger("SESSION");
|
|
1088
1120
|
var USER_CANCEL_ABORT_REASON = "qwen:user-cancel";
|
|
1089
1121
|
var DAEMON_RETRY_META_KEY = "qwen.daemon.retry";
|
|
1122
|
+
var DAEMON_CONTINUE_META_KEY = "qwen.daemon.continueLastTurn";
|
|
1090
1123
|
function maskApiKeyForDisplay(apiKey) {
|
|
1091
1124
|
const trimmed = apiKey?.trim() ?? "";
|
|
1092
1125
|
if (trimmed.length === 0) return "(not set)";
|
|
@@ -1102,6 +1135,14 @@ var MAX_MID_TURN_DRAIN_ITEMS = 10;
|
|
|
1102
1135
|
var MID_TURN_ATTACHMENT_PROCESSING_FAILURE_TEXT = "[Attachment could not be processed]";
|
|
1103
1136
|
var MAX_MID_TURN_RESOURCE_TEXT_LENGTH = 1e5;
|
|
1104
1137
|
var MID_TURN_QUEUE_DRAIN_MAX_TIMEOUT_STRIKES = 3;
|
|
1138
|
+
var TRANSIENT_FS_CODES = [
|
|
1139
|
+
"EACCES",
|
|
1140
|
+
"EIO",
|
|
1141
|
+
"EBUSY",
|
|
1142
|
+
"EPERM",
|
|
1143
|
+
"EISDIR",
|
|
1144
|
+
"ENOTDIR"
|
|
1145
|
+
];
|
|
1105
1146
|
function isRecord(value) {
|
|
1106
1147
|
return value !== null && typeof value === "object";
|
|
1107
1148
|
}
|
|
@@ -1328,6 +1369,18 @@ function isUserPromptRecord(record) {
|
|
|
1328
1369
|
) ?? false;
|
|
1329
1370
|
}
|
|
1330
1371
|
__name(isUserPromptRecord, "isUserPromptRecord");
|
|
1372
|
+
var AT_TOKEN_RE = /@([^\s,;!?()[\]{}]+)/g;
|
|
1373
|
+
function collectExtensionMentionRefs(text, mentions) {
|
|
1374
|
+
for (const match of text.matchAll(AT_TOKEN_RE)) {
|
|
1375
|
+
const pathName = match[1];
|
|
1376
|
+
if (!pathName) continue;
|
|
1377
|
+
const ref = parseExtensionRef(pathName);
|
|
1378
|
+
if (ref) {
|
|
1379
|
+
mentions.set(ref.name.toLowerCase(), ref.name);
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
}
|
|
1383
|
+
__name(collectExtensionMentionRefs, "collectExtensionMentionRefs");
|
|
1331
1384
|
async function buildAvailableCommandsSnapshot(config, abortSignal = AbortSignal.timeout(1e4), settings) {
|
|
1332
1385
|
const slashCommands = await getAvailableCommands(
|
|
1333
1386
|
config,
|
|
@@ -1347,7 +1400,12 @@ async function buildAvailableCommandsSnapshot(config, abortSignal = AbortSignal.
|
|
|
1347
1400
|
sourceLabel: cmd.sourceLabel,
|
|
1348
1401
|
supportedModes: getEffectiveSupportedModes(cmd),
|
|
1349
1402
|
subcommands: getCommandSubcommandNames(cmd),
|
|
1350
|
-
modelInvocable: cmd.modelInvocable === true
|
|
1403
|
+
modelInvocable: cmd.modelInvocable === true,
|
|
1404
|
+
// Carry aliases so a channel consumer (which only sees the wire snapshot,
|
|
1405
|
+
// not the command registry) can recognize an aliased command and avoid
|
|
1406
|
+
// tagging it. _meta is ACP's extension point; omitted when there are none
|
|
1407
|
+
// so command entries without aliases stay byte-identical on the wire.
|
|
1408
|
+
...cmd.altNames && cmd.altNames.length > 0 ? { altNames: cmd.altNames } : {}
|
|
1351
1409
|
}
|
|
1352
1410
|
};
|
|
1353
1411
|
});
|
|
@@ -1442,12 +1500,23 @@ var Session = class {
|
|
|
1442
1500
|
cronQueue = [];
|
|
1443
1501
|
cronProcessing = false;
|
|
1444
1502
|
cronAbortController = null;
|
|
1503
|
+
// Resolves the `<<loop.md>>` / `<<loop.md-dynamic>>` sentinels at fire time.
|
|
1504
|
+
// Lazily created on the first loop tick; its content cache is reset on
|
|
1505
|
+
// compaction (see #sendMessageStreamWithAutoCompression) and it is rebuilt if
|
|
1506
|
+
// the working dir changes (e.g. /cd) so it always reads the current project's
|
|
1507
|
+
// loop.md.
|
|
1508
|
+
loopTickResolver = null;
|
|
1509
|
+
loopTickResolverRoot = null;
|
|
1445
1510
|
cronCompletion = null;
|
|
1446
1511
|
cronDisabledByTokenLimit = false;
|
|
1447
1512
|
lastPromptTokenCount = 0;
|
|
1448
1513
|
lastPromptTokenCountChat = null;
|
|
1449
1514
|
midTurnDrainUnavailable = false;
|
|
1450
1515
|
midTurnDrainTimeoutStrikes = 0;
|
|
1516
|
+
// ACP can continue one logical conversation through prompt, cron, and
|
|
1517
|
+
// background loops, so keep this with the session instead of a single
|
|
1518
|
+
// runToolCalls invocation.
|
|
1519
|
+
duplicateProviderToolCallResponseIds = /* @__PURE__ */ new Set();
|
|
1451
1520
|
// Messages from a drain that the daemon answered but we timed out waiting for
|
|
1452
1521
|
// (the daemon already spliced + SSE-published them). Re-injected on the next
|
|
1453
1522
|
// batch so a transient stall can't silently lose them. See
|
|
@@ -1751,6 +1820,7 @@ var Session = class {
|
|
|
1751
1820
|
if (pendingSend.signal.aborted) {
|
|
1752
1821
|
return { stopReason: "cancelled" };
|
|
1753
1822
|
}
|
|
1823
|
+
this.duplicateProviderToolCallResponseIds.clear();
|
|
1754
1824
|
let resolveCompletion;
|
|
1755
1825
|
this.pendingPromptCompletion = new Promise((resolve3) => {
|
|
1756
1826
|
resolveCompletion = resolve3;
|
|
@@ -1769,6 +1839,36 @@ var Session = class {
|
|
|
1769
1839
|
this.pendingPromptCompletion = null;
|
|
1770
1840
|
}
|
|
1771
1841
|
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Classify whether an unfinished previous turn can be resumed — an
|
|
1844
|
+
* interrupted prompt (the model never answered) or a turn left with dangling
|
|
1845
|
+
* tool calls — without injecting a synthetic "continue" user message.
|
|
1846
|
+
* Classifies from persisted history. Idempotent no-op (accepted:false) when
|
|
1847
|
+
* the last turn ended cleanly or a prompt is already in flight.
|
|
1848
|
+
*
|
|
1849
|
+
* This is the accept/reject pre-check only — it does NOT fire the turn. When
|
|
1850
|
+
* accepted, the daemon bridge drives the continuation through the normal
|
|
1851
|
+
* prompt-admission path (`sendPrompt` with the trusted continue meta) so it is
|
|
1852
|
+
* tracked like any other prompt; `prompt()` then re-detects/strips
|
|
1853
|
+
* authoritatively. Powers `qwen/control/session/continue`.
|
|
1854
|
+
*/
|
|
1855
|
+
async continueLastTurn() {
|
|
1856
|
+
const geminiClient = this.config.getGeminiClient();
|
|
1857
|
+
if (!geminiClient || !geminiClient.isInitialized()) {
|
|
1858
|
+
return { accepted: false, interruption: "none" };
|
|
1859
|
+
}
|
|
1860
|
+
const chat = this.#getCurrentChat();
|
|
1861
|
+
const detection = detectTurnInterruption(
|
|
1862
|
+
chat.getHistoryTailShallow?.(TURN_INTERRUPTION_HISTORY_TAIL_COUNT) ?? chat.getHistoryTail(TURN_INTERRUPTION_HISTORY_TAIL_COUNT)
|
|
1863
|
+
);
|
|
1864
|
+
if (detection.kind === "none") {
|
|
1865
|
+
return { accepted: false, interruption: "none" };
|
|
1866
|
+
}
|
|
1867
|
+
if (this.pendingPrompt && !this.pendingPrompt.signal.aborted) {
|
|
1868
|
+
return { accepted: false, interruption: detection.kind };
|
|
1869
|
+
}
|
|
1870
|
+
return { accepted: true, interruption: detection.kind };
|
|
1871
|
+
}
|
|
1772
1872
|
/**
|
|
1773
1873
|
* Generate a server-side follow-up suggestion for the just-completed
|
|
1774
1874
|
* turn and push it to attached clients via the daemon's
|
|
@@ -1886,7 +1986,40 @@ var Session = class {
|
|
|
1886
1986
|
)
|
|
1887
1987
|
);
|
|
1888
1988
|
const isRetry = params.retry === true || params._meta?.[DAEMON_RETRY_META_KEY] === true;
|
|
1889
|
-
|
|
1989
|
+
const isContinue = params._meta?.[DAEMON_CONTINUE_META_KEY] === true;
|
|
1990
|
+
let continuationParts = null;
|
|
1991
|
+
let strippedOrphanEntries = null;
|
|
1992
|
+
let orphanPushCountSnapshot = 0;
|
|
1993
|
+
if (isContinue) {
|
|
1994
|
+
const detection = detectTurnInterruption(
|
|
1995
|
+
this.#getCurrentChat().getHistory()
|
|
1996
|
+
);
|
|
1997
|
+
if (detection.kind === "none") {
|
|
1998
|
+
debugLogger4.warn(
|
|
1999
|
+
`[Session] continue ${promptId}: no interrupted turn on re-detection, nothing to continue`
|
|
2000
|
+
);
|
|
2001
|
+
logConversationFinishedEvent(
|
|
2002
|
+
this.config,
|
|
2003
|
+
new ConversationFinishedEvent(
|
|
2004
|
+
this.config.getApprovalMode(),
|
|
2005
|
+
0
|
|
2006
|
+
)
|
|
2007
|
+
);
|
|
2008
|
+
return { stopReason: "end_turn" };
|
|
2009
|
+
}
|
|
2010
|
+
if (detection.kind === "interrupted_prompt") {
|
|
2011
|
+
strippedOrphanEntries = this.#getCurrentChat().stripOrphanedUserEntriesFromHistory() ?? null;
|
|
2012
|
+
orphanPushCountSnapshot = this.#getCurrentChat().getUserContentPushCount?.() ?? 0;
|
|
2013
|
+
continuationParts = detection.parts;
|
|
2014
|
+
} else {
|
|
2015
|
+
continuationParts = buildSyntheticToolResponseParts(
|
|
2016
|
+
detection.danglingCalls,
|
|
2017
|
+
ORPHAN_TOOL_USE_REPAIR_REASON
|
|
2018
|
+
);
|
|
2019
|
+
}
|
|
2020
|
+
}
|
|
2021
|
+
if (isContinue) {
|
|
2022
|
+
} else if (isRetry) {
|
|
1890
2023
|
this.#getCurrentChat().stripOrphanedUserEntriesFromHistory();
|
|
1891
2024
|
} else {
|
|
1892
2025
|
this.config.getChatRecordingService()?.recordUserMessage(promptText);
|
|
@@ -1896,7 +2029,9 @@ var Session = class {
|
|
|
1896
2029
|
);
|
|
1897
2030
|
const inputText = firstTextBlock?.text || "";
|
|
1898
2031
|
let parts;
|
|
1899
|
-
if (
|
|
2032
|
+
if (isContinue) {
|
|
2033
|
+
parts = continuationParts;
|
|
2034
|
+
} else if (isSlashCommand(inputText)) {
|
|
1900
2035
|
const slashCommandResult = await handleSlashCommand(
|
|
1901
2036
|
inputText,
|
|
1902
2037
|
pendingSend,
|
|
@@ -1918,7 +2053,7 @@ var Session = class {
|
|
|
1918
2053
|
}
|
|
1919
2054
|
const hooksEnabled = !this.config.getDisableAllHooks?.();
|
|
1920
2055
|
const messageBus = this.config.getMessageBus?.();
|
|
1921
|
-
if (hooksEnabled && messageBus && this.config.hasHooksForEvent?.("UserPromptSubmit")) {
|
|
2056
|
+
if (!isContinue && hooksEnabled && messageBus && this.config.hasHooksForEvent?.("UserPromptSubmit")) {
|
|
1922
2057
|
const response = await messageBus.request(
|
|
1923
2058
|
{
|
|
1924
2059
|
type: "hook-execution-request" /* HOOK_EXECUTION_REQUEST */,
|
|
@@ -1959,19 +2094,22 @@ var Session = class {
|
|
|
1959
2094
|
}
|
|
1960
2095
|
const systemReminders = await this.#buildInitialSystemReminders();
|
|
1961
2096
|
if (systemReminders.length > 0) {
|
|
1962
|
-
|
|
2097
|
+
const alreadyHasReminder = isContinue && parts.some(
|
|
2098
|
+
(part) => isSystemReminderContent({ role: "user", parts: [part] })
|
|
2099
|
+
);
|
|
2100
|
+
if (!alreadyHasReminder) {
|
|
2101
|
+
parts = insertAfterFunctionResponses(parts, systemReminders);
|
|
2102
|
+
}
|
|
1963
2103
|
}
|
|
1964
2104
|
if (this.pendingWorktreeNotice) {
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
text: `<system-reminder>
|
|
2105
|
+
const noticePart = {
|
|
2106
|
+
text: `<system-reminder>
|
|
1968
2107
|
${this.pendingWorktreeNotice}
|
|
1969
2108
|
</system-reminder>
|
|
1970
2109
|
|
|
1971
2110
|
`
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
];
|
|
2111
|
+
};
|
|
2112
|
+
parts = insertAfterFunctionResponses(parts, [noticePart]);
|
|
1975
2113
|
this.pendingWorktreeNotice = null;
|
|
1976
2114
|
}
|
|
1977
2115
|
let nextMessage = { role: "user", parts };
|
|
@@ -1995,7 +2133,7 @@ ${this.pendingWorktreeNotice}
|
|
|
1995
2133
|
if (!sendResult.responseStream) {
|
|
1996
2134
|
this.#preserveUnsentMessageHistory(
|
|
1997
2135
|
nextMessage,
|
|
1998
|
-
sendResult.stopReason === "cancelled"
|
|
2136
|
+
isContinue || sendResult.stopReason === "cancelled"
|
|
1999
2137
|
);
|
|
2000
2138
|
return { stopReason: sendResult.stopReason };
|
|
2001
2139
|
}
|
|
@@ -2026,6 +2164,12 @@ ${this.pendingWorktreeNotice}
|
|
|
2026
2164
|
}
|
|
2027
2165
|
}
|
|
2028
2166
|
} catch (error) {
|
|
2167
|
+
if (strippedOrphanEntries && (this.#getCurrentChat().getUserContentPushCount?.() ?? 0) <= orphanPushCountSnapshot) {
|
|
2168
|
+
for (const entry of strippedOrphanEntries) {
|
|
2169
|
+
this.#getCurrentChat().addHistory(entry);
|
|
2170
|
+
}
|
|
2171
|
+
strippedOrphanEntries = null;
|
|
2172
|
+
}
|
|
2029
2173
|
if (pendingSend.signal.aborted && pendingSend.signal.reason === USER_CANCEL_ABORT_REASON && this.#isAbortError(error)) {
|
|
2030
2174
|
return { stopReason: "cancelled" };
|
|
2031
2175
|
}
|
|
@@ -2075,15 +2219,10 @@ ${this.pendingWorktreeNotice}
|
|
|
2075
2219
|
);
|
|
2076
2220
|
return { stopReason: "end_turn" };
|
|
2077
2221
|
}
|
|
2078
|
-
nextMessage =
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
...await this.#drainMidTurnUserMessages(
|
|
2083
|
-
pendingSend.signal
|
|
2084
|
-
)
|
|
2085
|
-
]
|
|
2086
|
-
};
|
|
2222
|
+
nextMessage = await this.#buildNextMessageAfterToolRun(
|
|
2223
|
+
toolRun,
|
|
2224
|
+
pendingSend.signal
|
|
2225
|
+
);
|
|
2087
2226
|
}
|
|
2088
2227
|
}
|
|
2089
2228
|
if (this.messageRewriter) {
|
|
@@ -2131,13 +2270,18 @@ ${this.pendingWorktreeNotice}
|
|
|
2131
2270
|
return { stopReason: "end_turn" };
|
|
2132
2271
|
}
|
|
2133
2272
|
const responseText = this.#getCurrentChat().getLastModelMessageText?.() || "[no response text]";
|
|
2273
|
+
const contextUsage = buildContextUsage(
|
|
2274
|
+
this.config.getContentGeneratorConfig()?.contextWindowSize ?? DEFAULT_TOKEN_LIMIT,
|
|
2275
|
+
this.lastPromptTokenCount
|
|
2276
|
+
);
|
|
2134
2277
|
const response = await messageBus.request(
|
|
2135
2278
|
{
|
|
2136
2279
|
type: "hook-execution-request" /* HOOK_EXECUTION_REQUEST */,
|
|
2137
2280
|
eventName: "Stop",
|
|
2138
2281
|
input: {
|
|
2139
2282
|
stop_hook_active: true,
|
|
2140
|
-
last_assistant_message: responseText
|
|
2283
|
+
last_assistant_message: responseText,
|
|
2284
|
+
...contextUsage
|
|
2141
2285
|
},
|
|
2142
2286
|
signal: pendingSend.signal
|
|
2143
2287
|
},
|
|
@@ -2270,13 +2414,10 @@ ${this.pendingWorktreeNotice}
|
|
|
2270
2414
|
);
|
|
2271
2415
|
return { stopReason: "end_turn" };
|
|
2272
2416
|
}
|
|
2273
|
-
nextMessage =
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
...await this.#drainMidTurnUserMessages(pendingSend.signal)
|
|
2278
|
-
]
|
|
2279
|
-
};
|
|
2417
|
+
nextMessage = await this.#buildNextMessageAfterToolRun(
|
|
2418
|
+
toolRun,
|
|
2419
|
+
pendingSend.signal
|
|
2420
|
+
);
|
|
2280
2421
|
}
|
|
2281
2422
|
}
|
|
2282
2423
|
continue;
|
|
@@ -2317,6 +2458,7 @@ ${this.pendingWorktreeNotice}
|
|
|
2317
2458
|
compressionInfo = compressed;
|
|
2318
2459
|
this.#recordCompressionTokenCount(compressed);
|
|
2319
2460
|
if (compressed.compressionStatus === 1 /* COMPRESSED */) {
|
|
2461
|
+
this.loopTickResolver?.resetCache();
|
|
2320
2462
|
const reasonClause = compressed.triggerReason === "image_overflow" ? `accumulated enough tool screenshots to trigger compaction for ${this.config.getModel()}` : `approached the input token limit for ${this.config.getModel()}`;
|
|
2321
2463
|
compressionDiagnostic = `IMPORTANT: This conversation ${reasonClause}. A compressed context will be sent for future messages (compressed from: ${compressed.originalTokenCount ?? "unknown"} to ${compressed.newTokenCount ?? "unknown"} tokens).`;
|
|
2322
2464
|
}
|
|
@@ -2410,6 +2552,19 @@ ${this.pendingWorktreeNotice}
|
|
|
2410
2552
|
);
|
|
2411
2553
|
await this.messageRewriter?.waitForPendingRewrites();
|
|
2412
2554
|
}
|
|
2555
|
+
async #buildNextMessageAfterToolRun(toolRun, abortSignal) {
|
|
2556
|
+
if (toolRun.repeatedDuplicateProviderToolCall) {
|
|
2557
|
+
debugLogger4.debug(
|
|
2558
|
+
"Stopping ACP turn after dropping repeated duplicate provider tool-call response."
|
|
2559
|
+
);
|
|
2560
|
+
return null;
|
|
2561
|
+
}
|
|
2562
|
+
const parts = [
|
|
2563
|
+
...toolRun.parts,
|
|
2564
|
+
...await this.#drainMidTurnUserMessages(abortSignal)
|
|
2565
|
+
];
|
|
2566
|
+
return { role: "user", parts };
|
|
2567
|
+
}
|
|
2413
2568
|
#recordCompressionTokenCount(info) {
|
|
2414
2569
|
this.#syncPromptTokenCountWithCurrentChat();
|
|
2415
2570
|
const tokenCount = this.#extractCompressionTokenCount(info);
|
|
@@ -2673,6 +2828,28 @@ ${this.pendingWorktreeNotice}
|
|
|
2673
2828
|
}
|
|
2674
2829
|
}
|
|
2675
2830
|
}
|
|
2831
|
+
#getLoopTickResolver() {
|
|
2832
|
+
const root = this.config.getWorkingDir();
|
|
2833
|
+
if (!this.loopTickResolver || this.loopTickResolverRoot !== root) {
|
|
2834
|
+
const homeQwenDir = Storage.getGlobalQwenDir();
|
|
2835
|
+
const homeConfineRoot = (process.env["QWEN_HOME"] ? homeQwenDir : os.homedir()) || path.dirname(homeQwenDir);
|
|
2836
|
+
this.loopTickResolver = new LoopTickResolver({
|
|
2837
|
+
projectRoot: root,
|
|
2838
|
+
homeDir: homeConfineRoot,
|
|
2839
|
+
homeQwenDir,
|
|
2840
|
+
// The project `.qwen/loop.md` is repo-controlled, so an untrusted folder
|
|
2841
|
+
// must not read it and feed it to the model (mirrors getProjectHooks()'s
|
|
2842
|
+
// trust gate). The home/global `~/.qwen/loop.md` is user-owned and stays
|
|
2843
|
+
// allowed. Pass a getter, not a snapshot: isTrustedFolder() can flip
|
|
2844
|
+
// mid-session on an IDE workspace-trust update, and the resolver outlives
|
|
2845
|
+
// a single tick — re-read it on every resolve() so a trusted→untrusted
|
|
2846
|
+
// flip stops reading the project file immediately.
|
|
2847
|
+
allowProjectFile: /* @__PURE__ */ __name(() => this.config.isTrustedFolder(), "allowProjectFile")
|
|
2848
|
+
});
|
|
2849
|
+
this.loopTickResolverRoot = root;
|
|
2850
|
+
}
|
|
2851
|
+
return this.loopTickResolver;
|
|
2852
|
+
}
|
|
2676
2853
|
/**
|
|
2677
2854
|
* Executes a single cron-fired prompt: echoes it as a user message with
|
|
2678
2855
|
* `_meta.source='cron'`, streams the model response, and handles tool calls.
|
|
@@ -2703,15 +2880,56 @@ ${this.pendingWorktreeNotice}
|
|
|
2703
2880
|
async () => {
|
|
2704
2881
|
let turnCount = 0;
|
|
2705
2882
|
try {
|
|
2883
|
+
const loopMode = detectLoopSentinel(prompt);
|
|
2884
|
+
let loopTick = null;
|
|
2885
|
+
if (loopMode) {
|
|
2886
|
+
const resolver = this.#getLoopTickResolver();
|
|
2887
|
+
const trustedAtResolve = this.config.isTrustedFolder();
|
|
2888
|
+
try {
|
|
2889
|
+
loopTick = await resolver.resolve(loopMode, trustedAtResolve);
|
|
2890
|
+
} catch (resolveErr) {
|
|
2891
|
+
const code = resolveErr.code ?? "unknown";
|
|
2892
|
+
debugLogger4.warn(
|
|
2893
|
+
`loop.md sentinel resolution failed (mode=${loopMode}, code=${code}) \u2014 check .qwen/loop.md permissions/IO`,
|
|
2894
|
+
resolveErr
|
|
2895
|
+
);
|
|
2896
|
+
if (loopMode === "dynamic" && TRANSIENT_FS_CODES.includes(code)) {
|
|
2897
|
+
loopTick = resolver.buildTransientErrorTick(
|
|
2898
|
+
loopMode,
|
|
2899
|
+
trustedAtResolve,
|
|
2900
|
+
code
|
|
2901
|
+
);
|
|
2902
|
+
} else {
|
|
2903
|
+
throw new Error(
|
|
2904
|
+
`loop.md resolution failed (${code}) for ${resolver.absentLocations(
|
|
2905
|
+
trustedAtResolve
|
|
2906
|
+
)}`
|
|
2907
|
+
);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
const modelText = loopTick ? loopTick.modelText : prompt;
|
|
2912
|
+
if (loopTick) {
|
|
2913
|
+
debugLogger4.debug(
|
|
2914
|
+
`loop tick: mode=${loopMode} delivery=${loopTick.full ? "full" : loopTick.sourceLabel ? "reminder" : "absent"} source=${loopTick.sourceLabel ?? "none"} transient=${loopTick.transientError ?? false}`
|
|
2915
|
+
);
|
|
2916
|
+
}
|
|
2917
|
+
const echoText = loopTick ? loopTick.sourceLabel ? `Loop tick \u2014 tasks from ${loopTick.sourceLabel}` : (
|
|
2918
|
+
// A transient-error tick (buildTransientErrorTick) resolved a
|
|
2919
|
+
// file but couldn't read it this tick; it deliberately omits
|
|
2920
|
+
// sourceLabel, so don't conflate it with a genuinely-absent
|
|
2921
|
+
// loop.md. No errno/path here — those stay in the model text.
|
|
2922
|
+
loopTick.transientError ? "Loop tick \u2014 loop.md temporarily unavailable" : "Loop tick \u2014 loop.md not present"
|
|
2923
|
+
) : prompt;
|
|
2706
2924
|
await this.sendUpdate({
|
|
2707
2925
|
sessionUpdate: "user_message_chunk",
|
|
2708
|
-
content: { type: "text", text:
|
|
2926
|
+
content: { type: "text", text: echoText },
|
|
2709
2927
|
_meta: { source: item.source }
|
|
2710
2928
|
});
|
|
2711
2929
|
const cronReminders = await this.#buildInitialSystemReminders();
|
|
2712
2930
|
let nextMessage = {
|
|
2713
2931
|
role: "user",
|
|
2714
|
-
parts: [...cronReminders, { text:
|
|
2932
|
+
parts: [...cronReminders, { text: modelText }]
|
|
2715
2933
|
};
|
|
2716
2934
|
while (nextMessage !== null) {
|
|
2717
2935
|
turnCount++;
|
|
@@ -2735,6 +2953,9 @@ ${this.pendingWorktreeNotice}
|
|
|
2735
2953
|
return;
|
|
2736
2954
|
}
|
|
2737
2955
|
const responseStream = sendResult.responseStream;
|
|
2956
|
+
if (loopTick && turnCount === 1) {
|
|
2957
|
+
this.loopTickResolver?.markDelivered();
|
|
2958
|
+
}
|
|
2738
2959
|
nextMessage = null;
|
|
2739
2960
|
for await (const resp of responseStream) {
|
|
2740
2961
|
if (ac.signal.aborted) return;
|
|
@@ -2781,13 +3002,10 @@ ${this.pendingWorktreeNotice}
|
|
|
2781
3002
|
);
|
|
2782
3003
|
return;
|
|
2783
3004
|
}
|
|
2784
|
-
nextMessage =
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
...await this.#drainMidTurnUserMessages(ac.signal)
|
|
2789
|
-
]
|
|
2790
|
-
};
|
|
3005
|
+
nextMessage = await this.#buildNextMessageAfterToolRun(
|
|
3006
|
+
toolRun,
|
|
3007
|
+
ac.signal
|
|
3008
|
+
);
|
|
2791
3009
|
}
|
|
2792
3010
|
}
|
|
2793
3011
|
} catch (error) {
|
|
@@ -3020,13 +3238,10 @@ ${this.pendingWorktreeNotice}
|
|
|
3020
3238
|
await this.#emitBackgroundNotificationEndTurn("end_turn");
|
|
3021
3239
|
return;
|
|
3022
3240
|
}
|
|
3023
|
-
nextMessage =
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
...await this.#drainMidTurnUserMessages(ac.signal)
|
|
3028
|
-
]
|
|
3029
|
-
};
|
|
3241
|
+
nextMessage = await this.#buildNextMessageAfterToolRun(
|
|
3242
|
+
toolRun,
|
|
3243
|
+
ac.signal
|
|
3244
|
+
);
|
|
3030
3245
|
}
|
|
3031
3246
|
}
|
|
3032
3247
|
if (this.messageRewriter) {
|
|
@@ -3270,10 +3485,32 @@ ${this.pendingWorktreeNotice}
|
|
|
3270
3485
|
const handledProviderToolCallIds = new Set(
|
|
3271
3486
|
this.#getCurrentChat().getHistoryFunctionResponseIds()
|
|
3272
3487
|
);
|
|
3488
|
+
const repeatedDuplicateCall = findRepeatedDuplicateProviderToolCall(
|
|
3489
|
+
dedupedFunctionCalls,
|
|
3490
|
+
(fc) => getProviderToolCallId(fc) ?? fc.id,
|
|
3491
|
+
handledProviderToolCallIds,
|
|
3492
|
+
this.duplicateProviderToolCallResponseIds
|
|
3493
|
+
);
|
|
3494
|
+
if (repeatedDuplicateCall) {
|
|
3495
|
+
const providerCallId = getProviderToolCallId(repeatedDuplicateCall) ?? repeatedDuplicateCall.id;
|
|
3496
|
+
debugLogger4.debug(
|
|
3497
|
+
`[Session.runToolCalls] Dropping batch after repeated duplicate provider tool-call id: ${providerCallId} (tool: ${repeatedDuplicateCall.name ?? "unknown_tool"})`
|
|
3498
|
+
);
|
|
3499
|
+
return {
|
|
3500
|
+
parts: [],
|
|
3501
|
+
stopAfterPermissionCancel: false,
|
|
3502
|
+
repeatedDuplicateProviderToolCall: true
|
|
3503
|
+
};
|
|
3504
|
+
}
|
|
3273
3505
|
const pushDuplicateBatch = /* @__PURE__ */ __name((request) => {
|
|
3506
|
+
const providerCallId = request.providerCallId ?? request.callId;
|
|
3507
|
+
markDuplicateProviderToolCallResponseSent(
|
|
3508
|
+
providerCallId,
|
|
3509
|
+
this.duplicateProviderToolCallResponseIds
|
|
3510
|
+
);
|
|
3274
3511
|
const response = createDuplicateProviderToolCallResponse(request);
|
|
3275
3512
|
debugLogger4.debug(
|
|
3276
|
-
`[Session.runToolCalls] Suppressing duplicate provider tool-call id: ${
|
|
3513
|
+
`[Session.runToolCalls] Suppressing duplicate provider tool-call id: ${providerCallId} (tool: ${request.name})`
|
|
3277
3514
|
);
|
|
3278
3515
|
batches.push({ kind: "duplicate", request, response });
|
|
3279
3516
|
}, "pushDuplicateBatch");
|
|
@@ -3459,7 +3696,11 @@ ${this.pendingWorktreeNotice}
|
|
|
3459
3696
|
}
|
|
3460
3697
|
if (shouldStop) {
|
|
3461
3698
|
await appendSkippedAfter(parts, batch.calls[batch.calls.length - 1]);
|
|
3462
|
-
return {
|
|
3699
|
+
return {
|
|
3700
|
+
parts,
|
|
3701
|
+
stopAfterPermissionCancel: true,
|
|
3702
|
+
repeatedDuplicateProviderToolCall: false
|
|
3703
|
+
};
|
|
3463
3704
|
}
|
|
3464
3705
|
} else {
|
|
3465
3706
|
for (const fc of batch.calls) {
|
|
@@ -3467,12 +3708,20 @@ ${this.pendingWorktreeNotice}
|
|
|
3467
3708
|
parts.push(...r.parts);
|
|
3468
3709
|
if (r.stopAfterPermissionCancel) {
|
|
3469
3710
|
await appendSkippedAfter(parts, fc);
|
|
3470
|
-
return {
|
|
3711
|
+
return {
|
|
3712
|
+
parts,
|
|
3713
|
+
stopAfterPermissionCancel: true,
|
|
3714
|
+
repeatedDuplicateProviderToolCall: false
|
|
3715
|
+
};
|
|
3471
3716
|
}
|
|
3472
3717
|
}
|
|
3473
3718
|
}
|
|
3474
3719
|
}
|
|
3475
|
-
return {
|
|
3720
|
+
return {
|
|
3721
|
+
parts,
|
|
3722
|
+
stopAfterPermissionCancel: false,
|
|
3723
|
+
repeatedDuplicateProviderToolCall: false
|
|
3724
|
+
};
|
|
3476
3725
|
}
|
|
3477
3726
|
/**
|
|
3478
3727
|
* Assemble the per-turn system reminders the model needs to see at the
|
|
@@ -4245,9 +4494,11 @@ ${this.pendingWorktreeNotice}
|
|
|
4245
4494
|
async #resolvePrompt(message, abortSignal) {
|
|
4246
4495
|
const FILE_URI_SCHEME = "file://";
|
|
4247
4496
|
const embeddedContext = [];
|
|
4497
|
+
const extensionMentions = /* @__PURE__ */ new Map();
|
|
4248
4498
|
const parts = message.map((part) => {
|
|
4249
4499
|
switch (part.type) {
|
|
4250
4500
|
case "text":
|
|
4501
|
+
collectExtensionMentionRefs(part.text, extensionMentions);
|
|
4251
4502
|
return { text: part.text };
|
|
4252
4503
|
case "image":
|
|
4253
4504
|
case "audio":
|
|
@@ -4281,9 +4532,16 @@ ${this.pendingWorktreeNotice}
|
|
|
4281
4532
|
}
|
|
4282
4533
|
});
|
|
4283
4534
|
const atPathCommandParts = parts.filter((part) => "fileData" in part);
|
|
4284
|
-
|
|
4535
|
+
const extensionParts = await this.#resolveExtensionMentionParts(
|
|
4536
|
+
extensionMentions,
|
|
4537
|
+
abortSignal
|
|
4538
|
+
);
|
|
4539
|
+
if (atPathCommandParts.length === 0 && embeddedContext.length === 0 && extensionParts.length === 0) {
|
|
4285
4540
|
return parts;
|
|
4286
4541
|
}
|
|
4542
|
+
if (atPathCommandParts.length === 0 && embeddedContext.length === 0) {
|
|
4543
|
+
return [...parts, ...extensionParts];
|
|
4544
|
+
}
|
|
4287
4545
|
const pathSpecsToRead = atPathCommandParts.map(
|
|
4288
4546
|
(part) => part.fileData.fileUri
|
|
4289
4547
|
);
|
|
@@ -4308,6 +4566,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4308
4566
|
});
|
|
4309
4567
|
const contentParts = Array.isArray(readResult.contentParts) ? readResult.contentParts : [readResult.contentParts];
|
|
4310
4568
|
processedQueryParts.push({ text: initialQueryText });
|
|
4569
|
+
processedQueryParts.push(...extensionParts);
|
|
4311
4570
|
for (const part of contentParts) {
|
|
4312
4571
|
if (typeof part === "string") {
|
|
4313
4572
|
processedQueryParts.push({ text: part });
|
|
@@ -4317,6 +4576,7 @@ ${this.pendingWorktreeNotice}
|
|
|
4317
4576
|
}
|
|
4318
4577
|
} else {
|
|
4319
4578
|
processedQueryParts.push({ text: initialQueryText.trim() });
|
|
4579
|
+
processedQueryParts.push(...extensionParts);
|
|
4320
4580
|
}
|
|
4321
4581
|
for (const contextPart of embeddedContext) {
|
|
4322
4582
|
if ("text" in contextPart && contextPart.text) {
|
|
@@ -4338,6 +4598,33 @@ ${contextPart.text}`
|
|
|
4338
4598
|
}
|
|
4339
4599
|
return processedQueryParts;
|
|
4340
4600
|
}
|
|
4601
|
+
async #resolveExtensionMentionParts(extensionMentions, abortSignal) {
|
|
4602
|
+
if (extensionMentions.size === 0) return [];
|
|
4603
|
+
const activeExtensions = this.config.getActiveExtensions?.() ?? [];
|
|
4604
|
+
if (activeExtensions.length === 0) return [];
|
|
4605
|
+
const extensionParts = [];
|
|
4606
|
+
const resolvedExtensionNames = /* @__PURE__ */ new Set();
|
|
4607
|
+
let remainingBudget = EXTENSION_CONTEXT_BUDGET;
|
|
4608
|
+
for (const name of extensionMentions.values()) {
|
|
4609
|
+
const extension = matchExtensionByRef(name, activeExtensions);
|
|
4610
|
+
if (!extension) {
|
|
4611
|
+
this.debug(
|
|
4612
|
+
`Extension "${name}" not found among active extensions. Available: ${activeExtensions.map((e) => e.name).join(", ") || "(none)"}`
|
|
4613
|
+
);
|
|
4614
|
+
continue;
|
|
4615
|
+
}
|
|
4616
|
+
if (resolvedExtensionNames.has(extension.name)) continue;
|
|
4617
|
+
resolvedExtensionNames.add(extension.name);
|
|
4618
|
+
const context = await buildExtensionMentionContext(extension, {
|
|
4619
|
+
remainingBudget,
|
|
4620
|
+
signal: abortSignal,
|
|
4621
|
+
onDebugMessage: /* @__PURE__ */ __name((message) => this.debug(message), "onDebugMessage")
|
|
4622
|
+
});
|
|
4623
|
+
remainingBudget = context.remainingBudget;
|
|
4624
|
+
extensionParts.push({ text: context.text });
|
|
4625
|
+
}
|
|
4626
|
+
return extensionParts;
|
|
4627
|
+
}
|
|
4341
4628
|
debug(msg) {
|
|
4342
4629
|
if (this.config.getDebugMode()) {
|
|
4343
4630
|
debugLogger4.warn(msg);
|
|
@@ -4527,6 +4814,9 @@ var QWEN_CORE_SETTING_DEFINITIONS = {
|
|
|
4527
4814
|
"memory.enableManagedAutoMemory": { type: "boolean" },
|
|
4528
4815
|
"memory.enableManagedAutoDream": { type: "boolean" },
|
|
4529
4816
|
"memory.enableAutoSkill": { type: "boolean" },
|
|
4817
|
+
"memory.autoSkillConfirm": { type: "boolean" },
|
|
4818
|
+
"memory.enableTeamMemory": { type: "boolean" },
|
|
4819
|
+
"memory.enableTeamMemorySync": { type: "boolean" },
|
|
4530
4820
|
disableAllHooks: { type: "boolean" }
|
|
4531
4821
|
};
|
|
4532
4822
|
var QWEN_CORE_SETTING_KEYS = Object.keys(
|
|
@@ -4536,12 +4826,18 @@ var QWEN_HOOK_EVENTS = Object.values(HookEventName);
|
|
|
4536
4826
|
var DEFAULT_QWEN_MEMORY_SETTINGS = {
|
|
4537
4827
|
enableManagedAutoMemory: true,
|
|
4538
4828
|
enableManagedAutoDream: true,
|
|
4539
|
-
enableAutoSkill: true
|
|
4829
|
+
enableAutoSkill: true,
|
|
4830
|
+
autoSkillConfirm: true,
|
|
4831
|
+
enableTeamMemory: false,
|
|
4832
|
+
enableTeamMemorySync: false
|
|
4540
4833
|
};
|
|
4541
4834
|
var QWEN_MEMORY_SETTING_KEYS = [
|
|
4542
4835
|
"enableManagedAutoMemory",
|
|
4543
4836
|
"enableManagedAutoDream",
|
|
4544
|
-
"enableAutoSkill"
|
|
4837
|
+
"enableAutoSkill",
|
|
4838
|
+
"autoSkillConfirm",
|
|
4839
|
+
"enableTeamMemory",
|
|
4840
|
+
"enableTeamMemorySync"
|
|
4545
4841
|
];
|
|
4546
4842
|
function normalizeQwenMemorySettings(value) {
|
|
4547
4843
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -4551,7 +4847,10 @@ function normalizeQwenMemorySettings(value) {
|
|
|
4551
4847
|
return {
|
|
4552
4848
|
enableManagedAutoMemory: typeof record["enableManagedAutoMemory"] === "boolean" ? record["enableManagedAutoMemory"] : DEFAULT_QWEN_MEMORY_SETTINGS.enableManagedAutoMemory,
|
|
4553
4849
|
enableManagedAutoDream: typeof record["enableManagedAutoDream"] === "boolean" ? record["enableManagedAutoDream"] : DEFAULT_QWEN_MEMORY_SETTINGS.enableManagedAutoDream,
|
|
4554
|
-
enableAutoSkill: typeof record["enableAutoSkill"] === "boolean" ? record["enableAutoSkill"] : DEFAULT_QWEN_MEMORY_SETTINGS.enableAutoSkill
|
|
4850
|
+
enableAutoSkill: typeof record["enableAutoSkill"] === "boolean" ? record["enableAutoSkill"] : DEFAULT_QWEN_MEMORY_SETTINGS.enableAutoSkill,
|
|
4851
|
+
autoSkillConfirm: typeof record["autoSkillConfirm"] === "boolean" ? record["autoSkillConfirm"] : DEFAULT_QWEN_MEMORY_SETTINGS.autoSkillConfirm,
|
|
4852
|
+
enableTeamMemory: typeof record["enableTeamMemory"] === "boolean" ? record["enableTeamMemory"] : DEFAULT_QWEN_MEMORY_SETTINGS.enableTeamMemory,
|
|
4853
|
+
enableTeamMemorySync: typeof record["enableTeamMemorySync"] === "boolean" ? record["enableTeamMemorySync"] : DEFAULT_QWEN_MEMORY_SETTINGS.enableTeamMemorySync
|
|
4555
4854
|
};
|
|
4556
4855
|
}
|
|
4557
4856
|
__name(normalizeQwenMemorySettings, "normalizeQwenMemorySettings");
|
|
@@ -4583,7 +4882,7 @@ function readRequiredString(value, fieldName) {
|
|
|
4583
4882
|
}
|
|
4584
4883
|
__name(readRequiredString, "readRequiredString");
|
|
4585
4884
|
function validateSkillSlug(slug) {
|
|
4586
|
-
if (!slug || slug === "." || slug === ".." || slug.includes("/") || slug.includes(
|
|
4885
|
+
if (!slug || slug === "." || slug === ".." || slug.includes("/") || slug.includes(path2.sep) || !/^[a-zA-Z0-9._-]+$/.test(slug)) {
|
|
4587
4886
|
throw RequestError.invalidParams(void 0, "Invalid skill.slug");
|
|
4588
4887
|
}
|
|
4589
4888
|
}
|
|
@@ -5052,7 +5351,7 @@ async function downloadGitHubSkillDirectoryFromApi(githubUrl, directoryPath, rel
|
|
|
5052
5351
|
const name = readRequiredString(record["name"], "github.name");
|
|
5053
5352
|
const itemPath = readRequiredString(record["path"], "github.path");
|
|
5054
5353
|
const type = readRequiredString(record["type"], "github.type");
|
|
5055
|
-
const relativePath = relativeRoot ?
|
|
5354
|
+
const relativePath = relativeRoot ? path2.posix.join(relativeRoot, name) : name;
|
|
5056
5355
|
if (type === "dir") {
|
|
5057
5356
|
files.push(
|
|
5058
5357
|
...await downloadGitHubSkillDirectoryFromApi(
|
|
@@ -5112,10 +5411,10 @@ __name(downloadGitHubSkillDirectory, "downloadGitHubSkillDirectory");
|
|
|
5112
5411
|
async function downloadSkill(sourceUrl) {
|
|
5113
5412
|
assertAllowedSkillSourceUrl(sourceUrl);
|
|
5114
5413
|
const githubUrl = parseGitHubBlobSkillUrl(sourceUrl);
|
|
5115
|
-
if (!githubUrl ||
|
|
5414
|
+
if (!githubUrl || path2.posix.basename(githubUrl.filePath) !== "SKILL.md") {
|
|
5116
5415
|
return downloadSingleSkillFile(sourceUrl);
|
|
5117
5416
|
}
|
|
5118
|
-
const skillDirectory =
|
|
5417
|
+
const skillDirectory = path2.posix.dirname(githubUrl.filePath);
|
|
5119
5418
|
const files = await downloadGitHubSkillDirectory(githubUrl, skillDirectory);
|
|
5120
5419
|
const skillFile = files.find((file) => file.relativePath === "SKILL.md");
|
|
5121
5420
|
if (!skillFile) {
|
|
@@ -5131,9 +5430,9 @@ async function downloadSkill(sourceUrl) {
|
|
|
5131
5430
|
}
|
|
5132
5431
|
__name(downloadSkill, "downloadSkill");
|
|
5133
5432
|
function resolveSkillInstallPath(skillDir, relativePath) {
|
|
5134
|
-
const root =
|
|
5135
|
-
const target =
|
|
5136
|
-
if (target !== root && !target.startsWith(root +
|
|
5433
|
+
const root = path2.resolve(skillDir);
|
|
5434
|
+
const target = path2.resolve(skillDir, relativePath);
|
|
5435
|
+
if (target !== root && !target.startsWith(root + path2.sep)) {
|
|
5137
5436
|
throw RequestError.invalidParams(
|
|
5138
5437
|
void 0,
|
|
5139
5438
|
`Invalid skill file path: ${relativePath}`
|
|
@@ -5143,9 +5442,9 @@ function resolveSkillInstallPath(skillDir, relativePath) {
|
|
|
5143
5442
|
}
|
|
5144
5443
|
__name(resolveSkillInstallPath, "resolveSkillInstallPath");
|
|
5145
5444
|
function resolveManagedSkillDir(skillsBaseDir, slug) {
|
|
5146
|
-
const root =
|
|
5147
|
-
const skillDir =
|
|
5148
|
-
if (!skillDir.startsWith(root +
|
|
5445
|
+
const root = path2.resolve(skillsBaseDir);
|
|
5446
|
+
const skillDir = path2.resolve(skillsBaseDir, slug);
|
|
5447
|
+
if (!skillDir.startsWith(root + path2.sep)) {
|
|
5149
5448
|
throw RequestError.invalidParams(void 0, "Invalid skill.slug");
|
|
5150
5449
|
}
|
|
5151
5450
|
return skillDir;
|
|
@@ -5822,14 +6121,14 @@ function readScopeSettings(settings, scope) {
|
|
|
5822
6121
|
__name(readScopeSettings, "readScopeSettings");
|
|
5823
6122
|
async function resolvePreferredMemoryFile(dir, fallbackFilename) {
|
|
5824
6123
|
for (const filename of getAllGeminiMdFilenames()) {
|
|
5825
|
-
const filePath =
|
|
6124
|
+
const filePath = path2.join(dir, filename);
|
|
5826
6125
|
try {
|
|
5827
6126
|
await fs.access(filePath);
|
|
5828
6127
|
return filePath;
|
|
5829
6128
|
} catch {
|
|
5830
6129
|
}
|
|
5831
6130
|
}
|
|
5832
|
-
return
|
|
6131
|
+
return path2.join(dir, fallbackFilename);
|
|
5833
6132
|
}
|
|
5834
6133
|
__name(resolvePreferredMemoryFile, "resolvePreferredMemoryFile");
|
|
5835
6134
|
async function resolveQwenMemoryPaths(params) {
|
|
@@ -5850,13 +6149,37 @@ async function resolveQwenMemoryPaths(params) {
|
|
|
5850
6149
|
};
|
|
5851
6150
|
}
|
|
5852
6151
|
__name(resolveQwenMemoryPaths, "resolveQwenMemoryPaths");
|
|
6152
|
+
async function deliverClientMcpMessage(connection, serverName, message) {
|
|
6153
|
+
if (!connection) {
|
|
6154
|
+
throw new Error(
|
|
6155
|
+
`client MCP server '${serverName}' has no ACP connection yet`
|
|
6156
|
+
);
|
|
6157
|
+
}
|
|
6158
|
+
const response = await connection.extMethod(
|
|
6159
|
+
SERVE_CONTROL_EXT_METHODS.clientMcpMessage,
|
|
6160
|
+
{ server: serverName, payload: message }
|
|
6161
|
+
);
|
|
6162
|
+
const payload = response["payload"];
|
|
6163
|
+
if (payload === void 0 || payload === null) {
|
|
6164
|
+
throw new Error(
|
|
6165
|
+
`client_mcp/message returned no payload for server '${serverName}'`
|
|
6166
|
+
);
|
|
6167
|
+
}
|
|
6168
|
+
return payload;
|
|
6169
|
+
}
|
|
6170
|
+
__name(deliverClientMcpMessage, "deliverClientMcpMessage");
|
|
5853
6171
|
async function runAcpAgent(config, settings, argv) {
|
|
6172
|
+
let acpConnection;
|
|
6173
|
+
const bootstrapClientMcpSender = /* @__PURE__ */ __name((serverName, message) => deliverClientMcpMessage(acpConnection, serverName, message), "bootstrapClientMcpSender");
|
|
5854
6174
|
await config.initialize({
|
|
5855
6175
|
skipGeminiInitialization: true,
|
|
5856
6176
|
// Bootstrap skips MCP discovery — each session runs its own
|
|
5857
6177
|
// pool-routed discovery, so bootstrap-level spawns would be
|
|
5858
6178
|
// redundant subprocess leaks (W119).
|
|
5859
|
-
skipMcpDiscovery: true
|
|
6179
|
+
skipMcpDiscovery: true,
|
|
6180
|
+
// Bind the workspace-level manager's SDK callback so a runtime-added
|
|
6181
|
+
// client-hosted MCP server (#5626) round-trips over the parent WS.
|
|
6182
|
+
sendSdkMcpMessage: bootstrapClientMcpSender
|
|
5860
6183
|
});
|
|
5861
6184
|
const stdout = Writable.toWeb(process.stdout);
|
|
5862
6185
|
const stdin = Readable.toWeb(process.stdin);
|
|
@@ -5866,6 +6189,7 @@ async function runAcpAgent(config, settings, argv) {
|
|
|
5866
6189
|
const stream = ndJsonStream(stdout, stdin);
|
|
5867
6190
|
let agentInstance;
|
|
5868
6191
|
const connection = new AgentSideConnection((conn) => {
|
|
6192
|
+
acpConnection = conn;
|
|
5869
6193
|
agentInstance = new QwenAgent(config, settings, argv, conn);
|
|
5870
6194
|
return agentInstance;
|
|
5871
6195
|
}, stream);
|
|
@@ -6179,7 +6503,7 @@ var QwenAgent = class {
|
|
|
6179
6503
|
async initialize(args) {
|
|
6180
6504
|
this.clientCapabilities = args.clientCapabilities;
|
|
6181
6505
|
const authMethods = buildAuthMethods();
|
|
6182
|
-
const version = "0.19.
|
|
6506
|
+
const version = "0.19.3-nightly.20260630.e00fe6a27";
|
|
6183
6507
|
return {
|
|
6184
6508
|
protocolVersion: PROTOCOL_VERSION,
|
|
6185
6509
|
agentInfo: {
|
|
@@ -6774,6 +7098,16 @@ var QwenAgent = class {
|
|
|
6774
7098
|
status: this.mcpStatus(e.status)
|
|
6775
7099
|
}));
|
|
6776
7100
|
}
|
|
7101
|
+
if (!disabled) {
|
|
7102
|
+
out.resourceCount = this.resolveServerMcpResources(
|
|
7103
|
+
config,
|
|
7104
|
+
name
|
|
7105
|
+
).length;
|
|
7106
|
+
out.promptCount = this.resolveServerMcpPrompts(
|
|
7107
|
+
config,
|
|
7108
|
+
name
|
|
7109
|
+
).length;
|
|
7110
|
+
}
|
|
6777
7111
|
return out;
|
|
6778
7112
|
})
|
|
6779
7113
|
),
|
|
@@ -6880,6 +7214,102 @@ var QwenAgent = class {
|
|
|
6880
7214
|
};
|
|
6881
7215
|
}
|
|
6882
7216
|
}
|
|
7217
|
+
/**
|
|
7218
|
+
* Resolve the resources discovered for one server, with the same
|
|
7219
|
+
* pool-mode fallback `buildWorkspaceMcpToolsStatus` uses for tools: the
|
|
7220
|
+
* workspace `Config`'s `ResourceRegistry` is authoritative in
|
|
7221
|
+
* single-session mode, but in pool mode resources are registered into
|
|
7222
|
+
* per-session registries (`SessionMcpView.applyResources`), leaving the
|
|
7223
|
+
* workspace registry empty. Fall back to the first active session that
|
|
7224
|
+
* has this server's resources.
|
|
7225
|
+
*/
|
|
7226
|
+
resolveServerMcpResources(config, serverName) {
|
|
7227
|
+
const resources = config.getResourceRegistry?.()?.getResourcesByServer(serverName) ?? [];
|
|
7228
|
+
if (resources.length > 0) {
|
|
7229
|
+
return resources;
|
|
7230
|
+
}
|
|
7231
|
+
for (const session of this.getActiveSessions()) {
|
|
7232
|
+
try {
|
|
7233
|
+
const sessionResources = session.getConfig().getResourceRegistry?.()?.getResourcesByServer(serverName) ?? [];
|
|
7234
|
+
if (sessionResources.length > 0) {
|
|
7235
|
+
return sessionResources;
|
|
7236
|
+
}
|
|
7237
|
+
} catch {
|
|
7238
|
+
}
|
|
7239
|
+
}
|
|
7240
|
+
return resources;
|
|
7241
|
+
}
|
|
7242
|
+
/**
|
|
7243
|
+
* Resolve the prompts discovered for one server, mirroring
|
|
7244
|
+
* {@link resolveServerMcpResources}. Used only for the per-server
|
|
7245
|
+
* `promptCount` on the base status — prompts have no drill-down
|
|
7246
|
+
* endpoint (they surface as slash commands).
|
|
7247
|
+
*/
|
|
7248
|
+
resolveServerMcpPrompts(config, serverName) {
|
|
7249
|
+
const prompts = config.getPromptRegistry?.()?.getPromptsByServer(serverName) ?? [];
|
|
7250
|
+
if (prompts.length > 0) {
|
|
7251
|
+
return prompts;
|
|
7252
|
+
}
|
|
7253
|
+
for (const session of this.getActiveSessions()) {
|
|
7254
|
+
try {
|
|
7255
|
+
const sessionPrompts = session.getConfig().getPromptRegistry?.()?.getPromptsByServer(serverName) ?? [];
|
|
7256
|
+
if (sessionPrompts.length > 0) {
|
|
7257
|
+
return sessionPrompts;
|
|
7258
|
+
}
|
|
7259
|
+
} catch {
|
|
7260
|
+
}
|
|
7261
|
+
}
|
|
7262
|
+
return prompts;
|
|
7263
|
+
}
|
|
7264
|
+
buildWorkspaceMcpResourcesStatus(config, serverName) {
|
|
7265
|
+
const workspaceCwd = this.safeWorkspaceCwd(config);
|
|
7266
|
+
try {
|
|
7267
|
+
const servers = config.getMcpServers() ?? {};
|
|
7268
|
+
if (!Object.prototype.hasOwnProperty.call(servers, serverName)) {
|
|
7269
|
+
return {
|
|
7270
|
+
v: STATUS_SCHEMA_VERSION,
|
|
7271
|
+
workspaceCwd,
|
|
7272
|
+
serverName,
|
|
7273
|
+
initialized: true,
|
|
7274
|
+
acpChannelLive: true,
|
|
7275
|
+
resources: [],
|
|
7276
|
+
errors: [
|
|
7277
|
+
{
|
|
7278
|
+
kind: "mcp_resources",
|
|
7279
|
+
status: "error",
|
|
7280
|
+
error: `MCP server not configured: ${serverName}`
|
|
7281
|
+
}
|
|
7282
|
+
]
|
|
7283
|
+
};
|
|
7284
|
+
}
|
|
7285
|
+
const resources = this.resolveServerMcpResources(config, serverName).map((resource) => ({
|
|
7286
|
+
uri: resource.uri,
|
|
7287
|
+
...typeof resource.name === "string" ? { name: resource.name } : {},
|
|
7288
|
+
...typeof resource.title === "string" ? { title: resource.title } : {},
|
|
7289
|
+
...typeof resource.description === "string" ? { description: resource.description } : {},
|
|
7290
|
+
...typeof resource.mimeType === "string" ? { mimeType: resource.mimeType } : {},
|
|
7291
|
+
...typeof resource.size === "number" ? { size: resource.size } : {}
|
|
7292
|
+
}));
|
|
7293
|
+
return {
|
|
7294
|
+
v: STATUS_SCHEMA_VERSION,
|
|
7295
|
+
workspaceCwd,
|
|
7296
|
+
serverName,
|
|
7297
|
+
initialized: true,
|
|
7298
|
+
acpChannelLive: true,
|
|
7299
|
+
resources
|
|
7300
|
+
};
|
|
7301
|
+
} catch (error) {
|
|
7302
|
+
return {
|
|
7303
|
+
v: STATUS_SCHEMA_VERSION,
|
|
7304
|
+
workspaceCwd,
|
|
7305
|
+
serverName,
|
|
7306
|
+
initialized: true,
|
|
7307
|
+
acpChannelLive: true,
|
|
7308
|
+
resources: [],
|
|
7309
|
+
errors: [this.errorCell("mcp_resources", error)]
|
|
7310
|
+
};
|
|
7311
|
+
}
|
|
7312
|
+
}
|
|
6883
7313
|
/**
|
|
6884
7314
|
* Build the MCP budget status cells exposed on `GET /workspace/mcp`.
|
|
6885
7315
|
*
|
|
@@ -6986,7 +7416,7 @@ var QwenAgent = class {
|
|
|
6986
7416
|
const currentAuth = activeRuntimeSnapshot?.authType ?? currentAuthType;
|
|
6987
7417
|
const currentAcpModelId = hasCurrentModel && currentAuth ? formatAcpModelId(currentModelId, currentAuth) : currentModelId || void 0;
|
|
6988
7418
|
const providers = /* @__PURE__ */ new Map();
|
|
6989
|
-
for (const model of config.getAllConfiguredModels()) {
|
|
7419
|
+
for (const model of config.getAllConfiguredModels().filter(isMainSelectableModel)) {
|
|
6990
7420
|
const authType = String(model.authType);
|
|
6991
7421
|
let provider = providers.get(authType);
|
|
6992
7422
|
if (!provider) {
|
|
@@ -7480,6 +7910,25 @@ var QwenAgent = class {
|
|
|
7480
7910
|
}
|
|
7481
7911
|
};
|
|
7482
7912
|
}
|
|
7913
|
+
const skillMetrics = metrics.skills ?? {
|
|
7914
|
+
totalCalls: 0,
|
|
7915
|
+
totalSuccess: 0,
|
|
7916
|
+
totalFail: 0,
|
|
7917
|
+
byName: {}
|
|
7918
|
+
};
|
|
7919
|
+
const skillsByName = {};
|
|
7920
|
+
for (const [name, skill] of Object.entries(skillMetrics.byName)) {
|
|
7921
|
+
Object.defineProperty(skillsByName, name, {
|
|
7922
|
+
value: {
|
|
7923
|
+
count: skill.count,
|
|
7924
|
+
success: skill.success,
|
|
7925
|
+
fail: skill.fail
|
|
7926
|
+
},
|
|
7927
|
+
enumerable: true,
|
|
7928
|
+
configurable: true,
|
|
7929
|
+
writable: true
|
|
7930
|
+
});
|
|
7931
|
+
}
|
|
7483
7932
|
return {
|
|
7484
7933
|
v: STATUS_SCHEMA_VERSION,
|
|
7485
7934
|
sessionId,
|
|
@@ -7498,6 +7947,12 @@ var QwenAgent = class {
|
|
|
7498
7947
|
files: {
|
|
7499
7948
|
totalLinesAdded: metrics.files.totalLinesAdded,
|
|
7500
7949
|
totalLinesRemoved: metrics.files.totalLinesRemoved
|
|
7950
|
+
},
|
|
7951
|
+
skills: {
|
|
7952
|
+
totalCalls: skillMetrics.totalCalls,
|
|
7953
|
+
totalSuccess: skillMetrics.totalSuccess,
|
|
7954
|
+
totalFail: skillMetrics.totalFail,
|
|
7955
|
+
byName: skillsByName
|
|
7501
7956
|
}
|
|
7502
7957
|
};
|
|
7503
7958
|
}
|
|
@@ -7681,6 +8136,7 @@ var QwenAgent = class {
|
|
|
7681
8136
|
id: ext.id,
|
|
7682
8137
|
name: ext.name,
|
|
7683
8138
|
displayName: ext.displayName,
|
|
8139
|
+
...ext.config.description ? { description: ext.config.description } : {},
|
|
7684
8140
|
version: ext.version,
|
|
7685
8141
|
isActive: ext.isActive,
|
|
7686
8142
|
path: ext.path,
|
|
@@ -7727,9 +8183,9 @@ var QwenAgent = class {
|
|
|
7727
8183
|
);
|
|
7728
8184
|
}
|
|
7729
8185
|
const download = await downloadSkill(request.sourceUrl);
|
|
7730
|
-
const skillsBaseDir =
|
|
8186
|
+
const skillsBaseDir = path2.join(Storage.getGlobalQwenDir(), "skills");
|
|
7731
8187
|
const skillDir = resolveManagedSkillDir(skillsBaseDir, request.slug);
|
|
7732
|
-
const skillFile =
|
|
8188
|
+
const skillFile = path2.join(skillDir, "SKILL.md");
|
|
7733
8189
|
const parsed = skillManager.parseSkillContent(
|
|
7734
8190
|
download.skillContent,
|
|
7735
8191
|
skillFile,
|
|
@@ -7749,7 +8205,7 @@ var QwenAgent = class {
|
|
|
7749
8205
|
stagingDir,
|
|
7750
8206
|
file.relativePath
|
|
7751
8207
|
);
|
|
7752
|
-
await fs.mkdir(
|
|
8208
|
+
await fs.mkdir(path2.dirname(targetPath), { recursive: true });
|
|
7753
8209
|
await fs.writeFile(targetPath, file.content);
|
|
7754
8210
|
}
|
|
7755
8211
|
await fs.rm(skillDir, { recursive: true, force: true });
|
|
@@ -7788,11 +8244,11 @@ var QwenAgent = class {
|
|
|
7788
8244
|
`Skill name "${parsed.name}" does not match requested slug "${request.slug}"`
|
|
7789
8245
|
);
|
|
7790
8246
|
}
|
|
7791
|
-
const resolvedSkillDir =
|
|
7792
|
-
const resolvedSkillFile =
|
|
7793
|
-
const globalDir =
|
|
7794
|
-
const isDedicatedSkillDir = resolvedSkillFile ===
|
|
7795
|
-
if (!isDedicatedSkillDir || resolvedSkillDir ===
|
|
8247
|
+
const resolvedSkillDir = path2.resolve(skillDir);
|
|
8248
|
+
const resolvedSkillFile = path2.resolve(skillFile);
|
|
8249
|
+
const globalDir = path2.resolve(Storage.getGlobalQwenDir());
|
|
8250
|
+
const isDedicatedSkillDir = resolvedSkillFile === path2.join(resolvedSkillDir, "SKILL.md");
|
|
8251
|
+
if (!isDedicatedSkillDir || resolvedSkillDir === path2.parse(resolvedSkillDir).root || resolvedSkillDir === globalDir) {
|
|
7796
8252
|
throw RequestError.invalidParams(
|
|
7797
8253
|
void 0,
|
|
7798
8254
|
`Refusing to delete unexpected skill directory: ${skillDir}`
|
|
@@ -7808,10 +8264,10 @@ var QwenAgent = class {
|
|
|
7808
8264
|
async readManagedSkillFile(slug, scope, skillManager, cwd) {
|
|
7809
8265
|
if (scope === "global") {
|
|
7810
8266
|
const qwenSkillDir = resolveManagedSkillDir(
|
|
7811
|
-
|
|
8267
|
+
path2.join(Storage.getGlobalQwenDir(), "skills"),
|
|
7812
8268
|
slug
|
|
7813
8269
|
);
|
|
7814
|
-
const qwenSkillFile =
|
|
8270
|
+
const qwenSkillFile = path2.join(qwenSkillDir, "SKILL.md");
|
|
7815
8271
|
const qwenContent = await fs.readFile(qwenSkillFile, "utf8").catch(() => void 0);
|
|
7816
8272
|
if (qwenContent !== void 0) {
|
|
7817
8273
|
return {
|
|
@@ -7847,15 +8303,15 @@ var QwenAgent = class {
|
|
|
7847
8303
|
);
|
|
7848
8304
|
});
|
|
7849
8305
|
return {
|
|
7850
|
-
skillDir:
|
|
8306
|
+
skillDir: path2.dirname(skillFile),
|
|
7851
8307
|
skillFile,
|
|
7852
8308
|
content
|
|
7853
8309
|
};
|
|
7854
8310
|
}
|
|
7855
8311
|
async findProjectSkillFileFromCwd(slug, cwd, skillManager) {
|
|
7856
|
-
const projectRoot =
|
|
8312
|
+
const projectRoot = path2.resolve(cwd);
|
|
7857
8313
|
for (const configDir of PROJECT_SKILL_DIRS) {
|
|
7858
|
-
const baseDir =
|
|
8314
|
+
const baseDir = path2.join(projectRoot, configDir, SKILLS_DIR);
|
|
7859
8315
|
const skills = await skillManager.loadSkillsFromDir(baseDir, "project");
|
|
7860
8316
|
const skill = skills.find((candidate) => candidate.name === slug);
|
|
7861
8317
|
const skillFile = skill?.filePath;
|
|
@@ -7867,7 +8323,7 @@ var QwenAgent = class {
|
|
|
7867
8323
|
);
|
|
7868
8324
|
});
|
|
7869
8325
|
return {
|
|
7870
|
-
skillDir:
|
|
8326
|
+
skillDir: path2.dirname(skillFile),
|
|
7871
8327
|
skillFile,
|
|
7872
8328
|
content
|
|
7873
8329
|
};
|
|
@@ -7898,7 +8354,7 @@ var QwenAgent = class {
|
|
|
7898
8354
|
}
|
|
7899
8355
|
const nextContent = setSkillFrontmatterEnabled(content, request.enabled);
|
|
7900
8356
|
skillManager.parseSkillContent(nextContent, skillFile, level);
|
|
7901
|
-
if (
|
|
8357
|
+
if (path2.basename(skillFile) !== "SKILL.md") {
|
|
7902
8358
|
throw RequestError.invalidParams(
|
|
7903
8359
|
void 0,
|
|
7904
8360
|
`Refusing to write to unexpected skill file: ${skillFile}`
|
|
@@ -7948,19 +8404,25 @@ var QwenAgent = class {
|
|
|
7948
8404
|
);
|
|
7949
8405
|
const persistScope = readProviderConnectScope(params["scope"]);
|
|
7950
8406
|
const plan = buildInstallPlan(providerConfig, inputs);
|
|
8407
|
+
const adapter = createLoadedSettingsAdapter(
|
|
8408
|
+
this.settings,
|
|
8409
|
+
persistScope
|
|
8410
|
+
);
|
|
7951
8411
|
await applyProviderInstallPlan(plan, {
|
|
7952
|
-
settings:
|
|
8412
|
+
settings: adapter,
|
|
7953
8413
|
reloadModelProviders: /* @__PURE__ */ __name((modelProviders) => this.config.reloadModelProvidersConfig(modelProviders), "reloadModelProviders"),
|
|
7954
8414
|
syncAuthState: /* @__PURE__ */ __name((authType, modelId, baseUrl) => this.config.getModelsConfig().syncAfterAuthRefresh(authType, modelId, baseUrl), "syncAuthState"),
|
|
7955
8415
|
refreshAuth: /* @__PURE__ */ __name((authType) => this.config.refreshAuth(authType), "refreshAuth")
|
|
7956
8416
|
});
|
|
8417
|
+
const effectiveModelId = adapter.getValue("model.name") ?? plan.modelSelection?.modelId;
|
|
8418
|
+
const effectiveBaseUrl = adapter.getValue("model.baseUrl") ?? plan.modelSelection?.baseUrl;
|
|
7957
8419
|
return {
|
|
7958
8420
|
success: true,
|
|
7959
8421
|
providerId: providerConfig.id,
|
|
7960
8422
|
providerLabel: providerConfig.label,
|
|
7961
8423
|
authType: plan.authType,
|
|
7962
|
-
modelId:
|
|
7963
|
-
...
|
|
8424
|
+
...effectiveModelId ? { modelId: effectiveModelId } : {},
|
|
8425
|
+
...effectiveBaseUrl ? { baseUrl: effectiveBaseUrl } : {}
|
|
7964
8426
|
};
|
|
7965
8427
|
}
|
|
7966
8428
|
case "qwen/skills/install": {
|
|
@@ -8026,6 +8488,19 @@ var QwenAgent = class {
|
|
|
8026
8488
|
serverName
|
|
8027
8489
|
);
|
|
8028
8490
|
}
|
|
8491
|
+
case SERVE_STATUS_EXT_METHODS.workspaceMcpResources: {
|
|
8492
|
+
const serverName = params["serverName"];
|
|
8493
|
+
if (typeof serverName !== "string" || serverName.length === 0) {
|
|
8494
|
+
throw RequestError.invalidParams(
|
|
8495
|
+
void 0,
|
|
8496
|
+
"Invalid or missing serverName"
|
|
8497
|
+
);
|
|
8498
|
+
}
|
|
8499
|
+
return this.buildWorkspaceMcpResourcesStatus(
|
|
8500
|
+
this.config,
|
|
8501
|
+
serverName
|
|
8502
|
+
);
|
|
8503
|
+
}
|
|
8029
8504
|
case SERVE_STATUS_EXT_METHODS.workspaceSkills:
|
|
8030
8505
|
return await this.buildWorkspaceSkillsStatus(
|
|
8031
8506
|
this.config
|
|
@@ -8481,6 +8956,78 @@ var QwenAgent = class {
|
|
|
8481
8956
|
await this.closeStoredSession(sessionId);
|
|
8482
8957
|
return { sessionId, closed: true };
|
|
8483
8958
|
}
|
|
8959
|
+
case SERVE_CONTROL_EXT_METHODS.sessionCd: {
|
|
8960
|
+
const sessionId = params["sessionId"];
|
|
8961
|
+
const targetPath = params["path"];
|
|
8962
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
8963
|
+
throw RequestError.invalidParams(
|
|
8964
|
+
void 0,
|
|
8965
|
+
"Invalid or missing sessionId"
|
|
8966
|
+
);
|
|
8967
|
+
}
|
|
8968
|
+
if (typeof targetPath !== "string" || targetPath.length === 0 || !path2.isAbsolute(targetPath) || targetPath.includes("\0")) {
|
|
8969
|
+
throw RequestError.invalidParams(
|
|
8970
|
+
void 0,
|
|
8971
|
+
"Invalid or missing path (must be an absolute path)"
|
|
8972
|
+
);
|
|
8973
|
+
}
|
|
8974
|
+
const session = this.sessionOrThrow(sessionId);
|
|
8975
|
+
const config = session.getConfig();
|
|
8976
|
+
if (config.isRestrictiveSandbox()) {
|
|
8977
|
+
throw new RequestError(-32003, "Restrictive sandbox mode active", {
|
|
8978
|
+
errorKind: "restrictive_sandbox"
|
|
8979
|
+
});
|
|
8980
|
+
}
|
|
8981
|
+
let stats;
|
|
8982
|
+
try {
|
|
8983
|
+
stats = await fs.stat(targetPath);
|
|
8984
|
+
} catch {
|
|
8985
|
+
throw new RequestError(-32002, `Directory not found: ${targetPath}`, {
|
|
8986
|
+
errorKind: "directory_not_found",
|
|
8987
|
+
path: targetPath
|
|
8988
|
+
});
|
|
8989
|
+
}
|
|
8990
|
+
if (!stats.isDirectory()) {
|
|
8991
|
+
throw new RequestError(-32002, `Not a directory: ${targetPath}`, {
|
|
8992
|
+
errorKind: "directory_not_found",
|
|
8993
|
+
path: targetPath
|
|
8994
|
+
});
|
|
8995
|
+
}
|
|
8996
|
+
const canonicalPath = await fs.realpath(targetPath);
|
|
8997
|
+
const previousCwd = config.getTargetDir();
|
|
8998
|
+
if (canonicalPath === previousCwd) {
|
|
8999
|
+
return { previousCwd, newCwd: canonicalPath, warnings: [] };
|
|
9000
|
+
}
|
|
9001
|
+
if (isFolderTrustEnabled(this.settings.merged)) {
|
|
9002
|
+
const trustedFolders = loadTrustedFolders();
|
|
9003
|
+
if (trustedFolders.isPathTrusted(canonicalPath) !== true) {
|
|
9004
|
+
throw new RequestError(
|
|
9005
|
+
-32001,
|
|
9006
|
+
`Directory not trusted: ${canonicalPath}`,
|
|
9007
|
+
{ errorKind: "directory_not_trusted", path: canonicalPath }
|
|
9008
|
+
);
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
const warnings = [];
|
|
9012
|
+
const relocation = await config.relocateWorkingDirectory(
|
|
9013
|
+
canonicalPath,
|
|
9014
|
+
canonicalPath,
|
|
9015
|
+
{ skipProcessChdir: true, skipArtifactMigration: true }
|
|
9016
|
+
);
|
|
9017
|
+
if (relocation.memoryRefreshError) {
|
|
9018
|
+
warnings.push(
|
|
9019
|
+
`Memory refresh failed: ${relocation.memoryRefreshError instanceof Error ? relocation.memoryRefreshError.message : String(relocation.memoryRefreshError)}`
|
|
9020
|
+
);
|
|
9021
|
+
}
|
|
9022
|
+
try {
|
|
9023
|
+
await config.getGeminiClient()?.addWorkingDirectoryChangedContext(previousCwd, canonicalPath);
|
|
9024
|
+
} catch (error) {
|
|
9025
|
+
warnings.push(
|
|
9026
|
+
`Model context refresh failed: ${error instanceof Error ? error.message : String(error)}`
|
|
9027
|
+
);
|
|
9028
|
+
}
|
|
9029
|
+
return { previousCwd, newCwd: canonicalPath, warnings };
|
|
9030
|
+
}
|
|
8484
9031
|
case SERVE_CONTROL_EXT_METHODS.sessionApprovalMode: {
|
|
8485
9032
|
const sessionId = params["sessionId"];
|
|
8486
9033
|
const mode = params["mode"];
|
|
@@ -8898,6 +9445,21 @@ ${outputText}
|
|
|
8898
9445
|
condition: cleared?.condition
|
|
8899
9446
|
};
|
|
8900
9447
|
}
|
|
9448
|
+
case SERVE_CONTROL_EXT_METHODS.sessionContinue: {
|
|
9449
|
+
const sessionId = params["sessionId"];
|
|
9450
|
+
if (typeof sessionId !== "string" || sessionId.length === 0) {
|
|
9451
|
+
throw RequestError.invalidParams(
|
|
9452
|
+
void 0,
|
|
9453
|
+
"Invalid or missing sessionId"
|
|
9454
|
+
);
|
|
9455
|
+
}
|
|
9456
|
+
const session = this.sessionOrThrow(sessionId);
|
|
9457
|
+
const result = await session.continueLastTurn();
|
|
9458
|
+
debugLogger5.info(
|
|
9459
|
+
`sessionContinue sessionId=${sessionId} accepted=${result.accepted} interruption=${result.interruption}`
|
|
9460
|
+
);
|
|
9461
|
+
return result;
|
|
9462
|
+
}
|
|
8901
9463
|
case SERVE_CONTROL_EXT_METHODS.workspaceMcpRuntimeAdd: {
|
|
8902
9464
|
const name = params["name"];
|
|
8903
9465
|
const config = params["config"];
|
|
@@ -8908,7 +9470,7 @@ ${outputText}
|
|
|
8908
9470
|
"Invalid or missing name"
|
|
8909
9471
|
);
|
|
8910
9472
|
}
|
|
8911
|
-
if (
|
|
9473
|
+
if (!isValidServerName(name)) {
|
|
8912
9474
|
throw RequestError.invalidParams(
|
|
8913
9475
|
void 0,
|
|
8914
9476
|
"Server name must be \u2264256 chars, alphanumeric + underscore/hyphen, and not a reserved JS property name"
|
|
@@ -8944,13 +9506,37 @@ ${outputText}
|
|
|
8944
9506
|
oauth: _oauth,
|
|
8945
9507
|
headers: _headers,
|
|
8946
9508
|
type: _type,
|
|
9509
|
+
// Reverse tool channel marker (issue #5626, Phase 2). The parent
|
|
9510
|
+
// serve process stamps this on a client-hosted (extension) MCP
|
|
9511
|
+
// server's runtime config; it never reaches the transport itself.
|
|
9512
|
+
[CLIENT_MCP_OVER_WS_CONFIG_FLAG]: clientMcpOverWs,
|
|
8947
9513
|
...safeConfig
|
|
8948
9514
|
} = config;
|
|
9515
|
+
if (clientMcpOverWs === true) {
|
|
9516
|
+
safeConfig["type"] = "sdk";
|
|
9517
|
+
}
|
|
8949
9518
|
const result = await manager.addRuntimeMcpServer(
|
|
8950
9519
|
name,
|
|
8951
9520
|
safeConfig,
|
|
8952
9521
|
originatorClientId
|
|
8953
9522
|
);
|
|
9523
|
+
await Promise.all(
|
|
9524
|
+
this.getActiveSessions().map(async (session) => {
|
|
9525
|
+
const sessionManager = session.getConfig().getToolRegistry()?.getMcpClientManager();
|
|
9526
|
+
if (!sessionManager) return;
|
|
9527
|
+
try {
|
|
9528
|
+
await sessionManager.addRuntimeMcpServer(
|
|
9529
|
+
name,
|
|
9530
|
+
safeConfig,
|
|
9531
|
+
originatorClientId
|
|
9532
|
+
);
|
|
9533
|
+
} catch (sessionErr) {
|
|
9534
|
+
debugLogger5.warn(
|
|
9535
|
+
`workspaceMcpRuntimeAdd: failed to add runtime MCP server '${name}' to active session ${session.getConfig().getSessionId()}: ${sessionErr instanceof Error ? sessionErr.message : String(sessionErr)}`
|
|
9536
|
+
);
|
|
9537
|
+
}
|
|
9538
|
+
})
|
|
9539
|
+
);
|
|
8954
9540
|
return result;
|
|
8955
9541
|
} catch (err) {
|
|
8956
9542
|
if (err instanceof McpBudgetWouldExceedError) {
|
|
@@ -8985,7 +9571,7 @@ ${outputText}
|
|
|
8985
9571
|
"Invalid or missing name"
|
|
8986
9572
|
);
|
|
8987
9573
|
}
|
|
8988
|
-
if (
|
|
9574
|
+
if (!isValidServerName(name)) {
|
|
8989
9575
|
throw RequestError.invalidParams(
|
|
8990
9576
|
void 0,
|
|
8991
9577
|
"Server name must be \u2264256 chars, alphanumeric + underscore/hyphen, and not a reserved JS property name"
|
|
@@ -9008,6 +9594,22 @@ ${outputText}
|
|
|
9008
9594
|
name,
|
|
9009
9595
|
originatorClientId
|
|
9010
9596
|
);
|
|
9597
|
+
await Promise.all(
|
|
9598
|
+
this.getActiveSessions().map(async (session) => {
|
|
9599
|
+
const sessionManager = session.getConfig().getToolRegistry()?.getMcpClientManager();
|
|
9600
|
+
if (!sessionManager) return;
|
|
9601
|
+
try {
|
|
9602
|
+
await sessionManager.removeRuntimeMcpServer(
|
|
9603
|
+
name,
|
|
9604
|
+
originatorClientId
|
|
9605
|
+
);
|
|
9606
|
+
} catch (sessionErr) {
|
|
9607
|
+
debugLogger5.warn(
|
|
9608
|
+
`workspaceMcpRuntimeRemove: failed to remove runtime MCP server '${name}' from active session ${session.getConfig().getSessionId()}: ${sessionErr instanceof Error ? sessionErr.message : String(sessionErr)}`
|
|
9609
|
+
);
|
|
9610
|
+
}
|
|
9611
|
+
})
|
|
9612
|
+
);
|
|
9011
9613
|
return result;
|
|
9012
9614
|
}
|
|
9013
9615
|
case SERVE_CONTROL_EXT_METHODS.workspaceExtensionsRefresh: {
|
|
@@ -9576,9 +10178,13 @@ ${outputText}
|
|
|
9576
10178
|
}
|
|
9577
10179
|
const config = session.getConfig();
|
|
9578
10180
|
const authType = config.getAuthType();
|
|
9579
|
-
|
|
10181
|
+
const providersChanged = changed.has("modelProviders") || changed.has("providerProtocol");
|
|
10182
|
+
if (providersChanged) {
|
|
9580
10183
|
try {
|
|
9581
|
-
config.reloadModelProvidersConfig(
|
|
10184
|
+
config.reloadModelProvidersConfig(
|
|
10185
|
+
newMerged.modelProviders,
|
|
10186
|
+
newMerged.providerProtocol ?? {}
|
|
10187
|
+
);
|
|
9582
10188
|
} catch (err) {
|
|
9583
10189
|
debugLogger5.warn(
|
|
9584
10190
|
`reload: reloadModelProvidersConfig failed for session ${id}: ${err}`
|
|
@@ -9594,7 +10200,7 @@ ${outputText}
|
|
|
9594
10200
|
`reload: switchModel failed for session ${id}: ${err}`
|
|
9595
10201
|
);
|
|
9596
10202
|
}
|
|
9597
|
-
} else if ((
|
|
10203
|
+
} else if ((providersChanged || envChanged) && authType) {
|
|
9598
10204
|
try {
|
|
9599
10205
|
await config.refreshAuth(authType);
|
|
9600
10206
|
} catch (err) {
|
|
@@ -9657,6 +10263,21 @@ ${outputText}
|
|
|
9657
10263
|
}
|
|
9658
10264
|
}
|
|
9659
10265
|
// --- private helpers ---
|
|
10266
|
+
/**
|
|
10267
|
+
* Reverse tool channel (issue #5626, Phase 2). Build the session
|
|
10268
|
+
* `McpClientManager`'s `sendSdkMcpMessage` callback. Client-hosted
|
|
10269
|
+
* (extension) MCP servers are registered SDK-type, so the manager routes
|
|
10270
|
+
* their JSON-RPC through this callback. We forward each frame UP to the
|
|
10271
|
+
* parent serve process via the `qwen/control/client_mcp/message` ext-method;
|
|
10272
|
+
* the parent's `BridgeClient.extMethod` hands it to the per-WS-connection
|
|
10273
|
+
* `ClientMcpRegistrar`, which carries it down the daemon WS to the extension
|
|
10274
|
+
* and returns the correlated response (the `payload` field). All SDK-type
|
|
10275
|
+
* servers in this session share one callback — the `serverName` argument
|
|
10276
|
+
* routes to the right client-hosted server in the parent.
|
|
10277
|
+
*/
|
|
10278
|
+
buildClientMcpSender() {
|
|
10279
|
+
return (serverName, message) => deliverClientMcpMessage(this.connection, serverName, message);
|
|
10280
|
+
}
|
|
9660
10281
|
async newSessionConfig(cwd, mcpServers, sessionId, resume) {
|
|
9661
10282
|
this.settings = loadSettings(cwd);
|
|
9662
10283
|
const sessionMcpServers = {};
|
|
@@ -9710,6 +10331,10 @@ ${outputText}
|
|
|
9710
10331
|
continue;
|
|
9711
10332
|
}
|
|
9712
10333
|
}
|
|
10334
|
+
const cdpTunnelMcp = buildCdpTunnelMcpServer();
|
|
10335
|
+
if (cdpTunnelMcp && !sessionMcpServers["chrome-devtools"]) {
|
|
10336
|
+
sessionMcpServers["chrome-devtools"] = cdpTunnelMcp;
|
|
10337
|
+
}
|
|
9713
10338
|
const settings = this.settings.merged;
|
|
9714
10339
|
const argvForSession = {
|
|
9715
10340
|
...this.argv,
|
|
@@ -9741,6 +10366,14 @@ ${outputText}
|
|
|
9741
10366
|
if (typeof config.enableFileCheckpointing === "function") {
|
|
9742
10367
|
config.enableFileCheckpointing();
|
|
9743
10368
|
}
|
|
10369
|
+
if (typeof this.config.getRuntimeMcpServers === "function" && typeof config.addRuntimeMcpServer === "function") {
|
|
10370
|
+
const bootstrapRuntimeMcpServers = this.config.getRuntimeMcpServers();
|
|
10371
|
+
for (const [runtimeServerName, runtimeServerConfig] of Object.entries(
|
|
10372
|
+
bootstrapRuntimeMcpServers
|
|
10373
|
+
)) {
|
|
10374
|
+
config.addRuntimeMcpServer(runtimeServerName, runtimeServerConfig);
|
|
10375
|
+
}
|
|
10376
|
+
}
|
|
9744
10377
|
if (this.mcpPool !== void 0 && typeof config.setMcpTransportPool === "function") {
|
|
9745
10378
|
config.setMcpTransportPool(this.mcpPool);
|
|
9746
10379
|
}
|
|
@@ -9760,7 +10393,14 @@ ${outputText}
|
|
|
9760
10393
|
});
|
|
9761
10394
|
});
|
|
9762
10395
|
}
|
|
9763
|
-
await config.initialize(
|
|
10396
|
+
await config.initialize({
|
|
10397
|
+
// Reverse tool channel (issue #5626, Phase 2): bind the session
|
|
10398
|
+
// manager's SDK MCP callback to the `client_mcp/message` ext-method so a
|
|
10399
|
+
// client-hosted (extension) MCP server added at runtime reaches the
|
|
10400
|
+
// daemon WS. Servers that aren't client-hosted never use this callback
|
|
10401
|
+
// (the daemon only adds SDK-type runtime servers for client MCP).
|
|
10402
|
+
sendSdkMcpMessage: this.buildClientMcpSender()
|
|
10403
|
+
});
|
|
9764
10404
|
await config.waitForMcpReady();
|
|
9765
10405
|
const failedMcpServers = typeof config.getFailedMcpServerNames === "function" ? config.getFailedMcpServerNames() : [];
|
|
9766
10406
|
if (failedMcpServers.length > 0) {
|
|
@@ -9822,6 +10462,9 @@ ${outputText}
|
|
|
9822
10462
|
if (sessionData?.fileHistorySnapshots?.length) {
|
|
9823
10463
|
config.getFileHistoryService().restoreFromSnapshots(sessionData.fileHistorySnapshots);
|
|
9824
10464
|
}
|
|
10465
|
+
if (sessionData?.conversation.messages) {
|
|
10466
|
+
config.getChatRecordingService()?.rebuildTurnBoundaries(sessionData.conversation.messages);
|
|
10467
|
+
}
|
|
9825
10468
|
if (options.replayHistory !== false && sessionData?.conversation.messages) {
|
|
9826
10469
|
await session.replayHistory(sessionData.conversation.messages);
|
|
9827
10470
|
}
|
|
@@ -9832,7 +10475,7 @@ ${outputText}
|
|
|
9832
10475
|
buildAvailableModels(config) {
|
|
9833
10476
|
const rawCurrentModelId = (config.getModel() || this.config.getModel() || "").trim();
|
|
9834
10477
|
const currentAuthType = config.getAuthType();
|
|
9835
|
-
const allConfiguredModels = config.getAllConfiguredModels();
|
|
10478
|
+
const allConfiguredModels = config.getAllConfiguredModels().filter(isMainSelectableModel);
|
|
9836
10479
|
const activeRuntimeSnapshot = config.getActiveRuntimeModelSnapshot?.();
|
|
9837
10480
|
const currentModelId = activeRuntimeSnapshot ? formatAcpModelId(
|
|
9838
10481
|
activeRuntimeSnapshot.id,
|
|
@@ -9868,7 +10511,7 @@ ${outputText}
|
|
|
9868
10511
|
}
|
|
9869
10512
|
buildConfigOptions(config) {
|
|
9870
10513
|
const currentApprovalMode = config.getApprovalMode();
|
|
9871
|
-
const allConfiguredModels = config.getAllConfiguredModels();
|
|
10514
|
+
const allConfiguredModels = config.getAllConfiguredModels().filter(isMainSelectableModel);
|
|
9872
10515
|
const rawCurrentModelId = (config.getModel() || "").trim();
|
|
9873
10516
|
const currentAuthType = config.getAuthType?.();
|
|
9874
10517
|
const activeRuntimeSnapshot = config.getActiveRuntimeModelSnapshot?.();
|
|
@@ -9914,6 +10557,10 @@ ${outputText}
|
|
|
9914
10557
|
return authType ? formatAcpModelId(baseModelId, authType) : baseModelId;
|
|
9915
10558
|
}
|
|
9916
10559
|
};
|
|
10560
|
+
function isMainSelectableModel(model) {
|
|
10561
|
+
return model.fastOnly !== true && model.voiceOnly !== true;
|
|
10562
|
+
}
|
|
10563
|
+
__name(isMainSelectableModel, "isMainSelectableModel");
|
|
9917
10564
|
function diffSettingsKeys(oldMerged, newMerged) {
|
|
9918
10565
|
const changed = /* @__PURE__ */ new Set();
|
|
9919
10566
|
const allKeys = /* @__PURE__ */ new Set([
|
|
@@ -9928,10 +10575,52 @@ function diffSettingsKeys(oldMerged, newMerged) {
|
|
|
9928
10575
|
return changed;
|
|
9929
10576
|
}
|
|
9930
10577
|
__name(diffSettingsKeys, "diffSettingsKeys");
|
|
10578
|
+
function buildCdpTunnelMcpServer() {
|
|
10579
|
+
if (process.env["QWEN_SERVE_CDP_TUNNEL_OVER_WS"] !== "1") return void 0;
|
|
10580
|
+
if (process.env["QWEN_SERVE_CDP_TUNNEL_AUTH_REQUIRED"] === "1") {
|
|
10581
|
+
process.stderr.write(
|
|
10582
|
+
"qwen serve: browser tools (chrome-devtools-mcp) disabled \u2014 the /cdp tunnel requires bearer auth, which is not yet supported for the auto-registered browser MCP server.\n"
|
|
10583
|
+
);
|
|
10584
|
+
return void 0;
|
|
10585
|
+
}
|
|
10586
|
+
const port = Number(process.env["QWEN_SERVE_CDP_TUNNEL_PORT"]);
|
|
10587
|
+
if (!Number.isInteger(port) || port <= 0) {
|
|
10588
|
+
process.stderr.write(
|
|
10589
|
+
`qwen serve: browser tools (chrome-devtools-mcp) disabled \u2014 no valid /cdp tunnel port (QWEN_SERVE_CDP_TUNNEL_PORT=${process.env["QWEN_SERVE_CDP_TUNNEL_PORT"] ?? "<unset>"}). Start the daemon with a fixed --port (ephemeral --port 0 is not supported for the CDP tunnel).
|
|
10590
|
+
`
|
|
10591
|
+
);
|
|
10592
|
+
return void 0;
|
|
10593
|
+
}
|
|
10594
|
+
try {
|
|
10595
|
+
const requireFromHere = createRequire(import.meta.url);
|
|
10596
|
+
const pkgJsonPath = requireFromHere.resolve(
|
|
10597
|
+
"chrome-devtools-mcp/package.json"
|
|
10598
|
+
);
|
|
10599
|
+
const pkg = requireFromHere("chrome-devtools-mcp/package.json");
|
|
10600
|
+
const binRel = typeof pkg.bin === "string" ? pkg.bin : Object.values(pkg.bin ?? {})[0];
|
|
10601
|
+
if (!binRel) return void 0;
|
|
10602
|
+
const pkgDir = path2.dirname(pkgJsonPath);
|
|
10603
|
+
const binPath = path2.resolve(pkgDir, binRel);
|
|
10604
|
+
const binRelToPkg = path2.relative(pkgDir, binPath);
|
|
10605
|
+
if (binRelToPkg.startsWith("..") || path2.isAbsolute(binRelToPkg)) {
|
|
10606
|
+
return void 0;
|
|
10607
|
+
}
|
|
10608
|
+
return new MCPServerConfig(process.execPath, [
|
|
10609
|
+
binPath,
|
|
10610
|
+
"--wsEndpoint",
|
|
10611
|
+
`ws://127.0.0.1:${port}/cdp`
|
|
10612
|
+
]);
|
|
10613
|
+
} catch {
|
|
10614
|
+
return void 0;
|
|
10615
|
+
}
|
|
10616
|
+
}
|
|
10617
|
+
__name(buildCdpTunnelMcpServer, "buildCdpTunnelMcpServer");
|
|
9931
10618
|
export {
|
|
9932
10619
|
AUTH_PREFLIGHT_ENV_KEYS,
|
|
9933
10620
|
AUTH_PREFLIGHT_WAIVED_AUTH_TYPES,
|
|
10621
|
+
buildCdpTunnelMcpServer,
|
|
9934
10622
|
createWorkspaceMcpBudget,
|
|
10623
|
+
deliverClientMcpMessage,
|
|
9935
10624
|
extractFilesFromTarGz,
|
|
9936
10625
|
fetchAllowedGitHub,
|
|
9937
10626
|
normalizeCoreSettingValue,
|