@qwen-code/qwen-code 0.20.0 → 0.20.1-nightly.20260724.7d17c44a3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/qc-helper/docs/configuration/settings.md +1 -1
- package/bundled/qc-helper/docs/features/auto-mode.md +19 -16
- package/bundled/qc-helper/docs/features/commands.md +54 -0
- package/bundled/qc-helper/docs/features/sub-agents.md +16 -7
- package/bundled/qc-helper/docs/integration-github-action.md +1 -1
- package/bundled/qc-helper/docs/qwen-serve.md +2 -1
- package/bundled/review/DESIGN.md +2 -2
- package/bundled/review/SKILL.md +7 -5
- package/chunks/MaxSizedBox-LGRTXB47.js +84 -0
- package/chunks/{StandaloneSessionPicker-CEGO2AZX.js → StandaloneSessionPicker-H3TBU3C3.js} +68 -56
- package/chunks/{acp-startup-profiler-N3RHHXJ3.js → acp-startup-profiler-RV3IV562.js} +2 -2
- package/chunks/{acpAgent-YUR43TLG.js → acpAgent-5D7P4BB5.js} +2061 -556
- package/chunks/agent-W7UAHCCI.js +80 -0
- package/chunks/agent-headless-KTBMPRSC.js +74 -0
- package/chunks/{anthropicContentGenerator-HVKLXOOU.js → anthropicContentGenerator-ZLQ3X2HI.js} +112 -45
- package/chunks/{artifact-tool-WBCAMD3O.js → artifact-tool-OKMWONT6.js} +3 -3
- package/chunks/{askUserQuestion-6DZC4UV5.js → askUserQuestion-V6FUS23G.js} +3 -3
- package/chunks/bridge-FFC4C6VD.js +89 -0
- package/chunks/{build-SSCNEHZZ.js → build-RV63TIRH.js} +2 -3
- package/chunks/{ca-2SL2BXTK.js → ca-GKRQZ7AM.js} +612 -201
- package/chunks/{channel-worker-group-53CMOPFT.js → channel-worker-group-MA3WXWYX.js} +7 -6
- package/chunks/{channel-worker-manager-UTXILKC2.js → channel-worker-manager-TIYYYBCT.js} +189 -29
- package/chunks/{channel-worker-supervisor-ZGO2W2MD.js → channel-worker-supervisor-CXRCDA4Y.js} +6 -5
- package/chunks/{chunk-TYQMGACW.js → chunk-22C7BQ6D.js} +508 -10967
- package/chunks/{chunk-4EP2PYYL.js → chunk-2G6QIHYL.js} +5 -5
- package/chunks/{chunk-H2XVO6NE.js → chunk-2MIN6GRR.js} +1 -1
- package/chunks/chunk-2RFKHEXL.js +74 -0
- package/chunks/{chunk-7SXZC7ID.js → chunk-2WTVWAKT.js} +7 -6
- package/chunks/{chunk-TIH2ZTOC.js → chunk-32A4PI3E.js} +2 -2
- package/chunks/chunk-36HSVBBU.js +469 -0
- package/chunks/{chunk-IR46U7RB.js → chunk-3FB2Y2OE.js} +3 -3
- package/chunks/{chunk-QR6U5QPP.js → chunk-3SJ43L4W.js} +4 -0
- package/chunks/chunk-3Z43GZUQ.js +32 -0
- package/chunks/chunk-43T5WDQ7.js +127 -0
- package/chunks/chunk-46UV252V.js +128 -0
- package/chunks/{chunk-JD3MKVKL.js → chunk-4K56OJFJ.js} +1 -1
- package/chunks/{chunk-KTUQMDEP.js → chunk-4K7VDKAD.js} +1 -1
- package/chunks/{chunk-QKYTTBYW.js → chunk-4LVZNIDO.js} +1 -1
- package/chunks/{chunk-OWCALFEG.js → chunk-54R2CV2G.js} +1 -1
- package/chunks/{chunk-ZEOZL37W.js → chunk-57FIIFJN.js} +1 -1
- package/chunks/chunk-5BS3KLRP.js +6194 -0
- package/chunks/{chunk-NEEB7UEN.js → chunk-6GMVPFB2.js} +153 -72
- package/chunks/{chunk-GMGDLUC7.js → chunk-6IL7KRLE.js} +1 -1
- package/chunks/chunk-6PVPNMXU.js +29 -0
- package/chunks/chunk-6QHAUJUE.js +293 -0
- package/chunks/chunk-6VK3IRTX.js +10017 -0
- package/chunks/{chunk-BDBMYST4.js → chunk-6X4GWOPW.js} +1 -1
- package/chunks/{chunk-AYCDXHZB.js → chunk-7Z6JQEL6.js} +1 -1
- package/chunks/{chunk-FSL5W5TI.js → chunk-AFFGGOF6.js} +4 -4
- package/chunks/chunk-AMDSOFFV.js +10860 -0
- package/chunks/chunk-AXUW635Q.js +934 -0
- package/chunks/{chunk-A5LYNIW7.js → chunk-BJBUDCM3.js} +8 -8
- package/chunks/chunk-BK2UNYWD.js +29 -0
- package/chunks/{chunk-6RLROE6G.js → chunk-BLFVGB7D.js} +30 -4
- package/chunks/chunk-BPJSQIJX.js +100 -0
- package/chunks/{chunk-FLSVD6BS.js → chunk-BRTR7S7O.js} +3 -3
- package/chunks/{chunk-KG3XV6FH.js → chunk-BSNWBC33.js} +32 -2
- package/chunks/chunk-BULDBTYC.js +153 -0
- package/chunks/{chunk-PBWEWI4N.js → chunk-BW5Z5NOG.js} +83 -74
- package/chunks/{chunk-EIAK6Q2B.js → chunk-C3VHAXP2.js} +20 -3
- package/chunks/{chunk-6AFUCL3D.js → chunk-CEZB3XFD.js} +1 -1
- package/chunks/chunk-CHMENNJV.js +1832 -0
- package/chunks/{chunk-TMQ6XQCX.js → chunk-CK3IEEHR.js} +416 -291
- package/chunks/{chunk-OYZWQNWG.js → chunk-CK6UABV2.js} +2 -2
- package/chunks/{chunk-VZQUV7VK.js → chunk-CKTMY3EP.js} +1 -1
- package/chunks/{chunk-VDWBQ5AW.js → chunk-CUPAVLRY.js} +5 -2
- package/chunks/{chunk-I2PYAYFM.js → chunk-CXUFILV3.js} +3 -3
- package/chunks/chunk-DP3IHZGG.js +1498 -0
- package/chunks/{chunk-BMWMT5Y2.js → chunk-DP5GT2MW.js} +7 -375
- package/chunks/{chunk-D22SX43D.js → chunk-DWNZ6PVQ.js} +1 -1
- package/chunks/{chunk-5SCI6E3E.js → chunk-E4IMU4Y5.js} +1 -1
- package/chunks/{chunk-DP5GXXNZ.js → chunk-EL2IQ2S5.js} +5 -1
- package/chunks/{chunk-EZVDJFZ7.js → chunk-ERLGR7GI.js} +1 -1
- package/chunks/{chunk-IVPSS6EL.js → chunk-F5MBYZSU.js} +4 -4
- package/chunks/{chunk-AQIEINAY.js → chunk-F6IYL66A.js} +28 -1766
- package/chunks/{chunk-FEOZBUMT.js → chunk-FODK6UMO.js} +0 -27
- package/chunks/{chunk-PGEPSDJI.js → chunk-FWNZ7CVN.js} +24 -20
- package/chunks/{chunk-5JBR5XIK.js → chunk-G7EFBBVF.js} +220 -141
- package/chunks/chunk-GLNBDYUX.js +38 -0
- package/chunks/{chunk-ANPINBOF.js → chunk-H4YKEV2X.js} +5 -5
- package/chunks/{chunk-TDKQP3M6.js → chunk-HIJQF5B5.js} +1 -1
- package/chunks/{chunk-FQD7GFSV.js → chunk-HJJDKFL5.js} +3 -3
- package/chunks/{chunk-4N3KMAIL.js → chunk-HPWHDJID.js} +152 -35
- package/chunks/{chunk-KQNM4EO7.js → chunk-HQCSRJ3P.js} +138 -6
- package/chunks/chunk-HTR4WV6U.js +327 -0
- package/chunks/{chunk-YWEW33JY.js → chunk-HVO55LUD.js} +7 -7
- package/chunks/{chunk-MJ6S23WZ.js → chunk-HZEWYOVI.js} +5 -5
- package/chunks/chunk-IFG6TYJ2.js +16577 -0
- package/chunks/{chunk-B3KGZCQN.js → chunk-IJTOWOD7.js} +322 -202
- package/chunks/{chunk-RS7MT2QG.js → chunk-IPUUTYMV.js} +2 -4
- package/chunks/{chunk-4ILMYHEI.js → chunk-IRDZJSCL.js} +3 -3
- package/chunks/{chunk-XU457J4V.js → chunk-IRH27ZC2.js} +2 -2
- package/chunks/{chunk-33XUAINQ.js → chunk-J5UKQEFG.js} +69 -9
- package/chunks/{chunk-G45X5TRN.js → chunk-JCW2R7WC.js} +1 -72
- package/chunks/{chunk-S2XVRHDN.js → chunk-JDFBBGRD.js} +1 -1
- package/chunks/{chunk-4XNLIGVA.js → chunk-JKCALGYN.js} +1023 -383
- package/chunks/{chunk-TJTKSVIV.js → chunk-JLU636DO.js} +5 -1
- package/chunks/{chunk-VEXFOTEO.js → chunk-JYUSL2V4.js} +3 -3
- package/chunks/{chunk-S2PD3EZD.js → chunk-KJEMJWNH.js} +1 -1
- package/chunks/{chunk-E2UVIFI2.js → chunk-KRXPRVGL.js} +0 -1
- package/chunks/{chunk-CZF3E5GF.js → chunk-LA5H3LM5.js} +1 -1
- package/chunks/{chunk-NDMQLV4Y.js → chunk-LBAO2XRA.js} +4 -4
- package/chunks/{chunk-7RMOXZTC.js → chunk-LDPP5VTZ.js} +4 -4
- package/chunks/{chunk-KDC6GNQR.js → chunk-LEEWLFHW.js} +4 -4
- package/chunks/{chunk-KX6UK4VJ.js → chunk-LI4I37W4.js} +22152 -18007
- package/chunks/{chunk-OOCI5VVU.js → chunk-LIZRAKPB.js} +1 -1
- package/chunks/{chunk-AJSJ5TTU.js → chunk-LP2E4MQG.js} +1 -1
- package/chunks/chunk-LS77BEZP.js +405 -0
- package/chunks/{chunk-BRRF37CO.js → chunk-LYTBLSSW.js} +5 -5
- package/chunks/{chunk-DBE4QFZS.js → chunk-MB7ENXPR.js} +39 -37
- package/chunks/{chunk-GKY2OJ7R.js → chunk-MOHAWVLH.js} +4 -4
- package/chunks/chunk-NABLFI57.js +82 -0
- package/chunks/chunk-NBQDBANR.js +411 -0
- package/chunks/{chunk-EAUYY7SS.js → chunk-NOAAFNTJ.js} +43 -10
- package/chunks/chunk-NXS53EA7.js +1462 -0
- package/chunks/{chunk-C27BYUX6.js → chunk-OQB4EXO4.js} +14 -11
- package/chunks/{chunk-NHDKSOEY.js → chunk-P3QQPMQA.js} +5 -5
- package/chunks/{chunk-OP4MOGXF.js → chunk-P5RRUHL7.js} +23 -1
- package/chunks/{chunk-KOR3XKCA.js → chunk-PBII2NFX.js} +12 -6
- package/chunks/{chunk-O3OCNYY5.js → chunk-PDYB7HG2.js} +2 -2
- package/chunks/{chunk-2HOVDT7W.js → chunk-PFSUKTZH.js} +1 -1
- package/chunks/chunk-PKL3HGNZ.js +2299 -0
- package/chunks/{chunk-5DTTYNB7.js → chunk-PQNHRFJC.js} +16 -3
- package/chunks/{chunk-OLMETXLX.js → chunk-PXHK5ONM.js} +41 -9
- package/chunks/{chunk-PF4CHQOJ.js → chunk-Q6GU6TKM.js} +11 -10
- package/chunks/{chunk-4ODB7WIB.js → chunk-QAFKR7WR.js} +1 -1
- package/chunks/{chunk-PBATSWUQ.js → chunk-QBUDF33N.js} +1 -1
- package/chunks/{chunk-BVLROR2T.js → chunk-QLJUC7TG.js} +1 -1
- package/chunks/{chunk-UEY4AYUL.js → chunk-QNLNLENL.js} +2 -2
- package/chunks/{chunk-333CXMNJ.js → chunk-QXZTZJLX.js} +5 -5
- package/chunks/chunk-R6D2CTQR.js +289 -0
- package/chunks/{chunk-7PZ2ATFZ.js → chunk-R6SKHK3T.js} +54 -29
- package/chunks/{chunk-OONJNQ42.js → chunk-RGG6M2WF.js} +4 -4
- package/chunks/{chunk-RFIAR4YL.js → chunk-RV4C2ZFG.js} +1 -1
- package/chunks/{chunk-O3Z73NBP.js → chunk-RW2NEXYJ.js} +15 -11
- package/chunks/{chunk-HZPN55E5.js → chunk-SJEDL7DI.js} +1 -1
- package/chunks/{chunk-AKX4WPPP.js → chunk-SWBJRDYC.js} +866 -183
- package/chunks/{chunk-NBMIC7DR.js → chunk-SX4PK3FC.js} +145 -5
- package/chunks/chunk-T3452DP5.js +246 -0
- package/chunks/{chunk-TB6UDU4T.js → chunk-THJNPLI4.js} +16 -16
- package/chunks/{chunk-T4TZQJ7W.js → chunk-TWPJO254.js} +5 -16
- package/chunks/chunk-U7ZFW55U.js +2098 -0
- package/chunks/{chunk-JNWZQ27S.js → chunk-UCOJC6EB.js} +72 -23
- package/chunks/{chunk-W7H223ZZ.js → chunk-UGYMA4EI.js} +1 -1
- package/chunks/{chunk-X6YQWCIJ.js → chunk-UH3WSE5L.js} +13 -1
- package/chunks/{chunk-2LL7TXB4.js → chunk-UH7242DI.js} +3 -3
- package/chunks/{chunk-CB2HFGRV.js → chunk-UJV643E2.js} +31 -6
- package/chunks/chunk-UO7DCGEV.js +121 -0
- package/chunks/{chunk-Y2ENGUD6.js → chunk-UPF7PTBI.js} +79 -2
- package/chunks/chunk-UW5EOVUN.js +249 -0
- package/chunks/{chunk-SJMV7ZBK.js → chunk-VLVO52KC.js} +8 -8
- package/chunks/{chunk-R3VWUU2E.js → chunk-VYPFXUCB.js} +1 -1
- package/chunks/{chunk-S2W2LVDU.js → chunk-WHFK6G6U.js} +8 -9
- package/chunks/chunk-WI3KCKZ5.js +391 -0
- package/chunks/{chunk-NGFEPAE6.js → chunk-WLEFWSSC.js} +8 -6
- package/chunks/{chunk-XVVH63JG.js → chunk-WUJXJ34P.js} +3 -3
- package/chunks/{chunk-MAQQGNQ5.js → chunk-WYLPWQHJ.js} +56 -717
- package/chunks/{chunk-D2VIDMVM.js → chunk-X6N25LXS.js} +2 -2
- package/chunks/chunk-XAWJ2526.js +1049 -0
- package/chunks/{chunk-CV63PP6U.js → chunk-YCIM6O3I.js} +1 -1
- package/chunks/{chunk-OEO2ERWK.js → chunk-Z44CVEUF.js} +54 -33
- package/chunks/{chunk-TKLLK6XQ.js → chunk-ZT4POVWC.js} +11 -11
- package/chunks/{chunk-NIJEXGV6.js → chunk-ZXYUQXY5.js} +148 -10
- package/chunks/{computer-use-NIWQNUZF.js → computer-use-UJ5T34TE.js} +50 -37
- package/chunks/{config-utils-AHQ6YZ66.js → config-utils-XQRXHAN3.js} +3 -3
- package/chunks/contextCommand-CSCB4E5M.js +79 -0
- package/chunks/{create-sub-session-MGNX52P3.js → create-sub-session-55F3GOLK.js} +46 -33
- package/chunks/{create-sub-session-P26FE5GG.js → create-sub-session-JPCSYZAJ.js} +3 -3
- package/chunks/{cron-create-JWFHBDRQ.js → cron-create-CUMELMPL.js} +6 -6
- package/chunks/{cron-delete-GDX4E26G.js → cron-delete-QZFV6U3P.js} +5 -5
- package/chunks/{cron-list-USMAIWPT.js → cron-list-IDKO7ZO2.js} +5 -5
- package/chunks/{daemon-RG2MAI6T.js → daemon-7LP7R6IU.js} +500 -133
- package/chunks/daemon-status-provider-6YNZ3UAE.js +88 -0
- package/chunks/{de-I7ZIYXZC.js → de-4IBXM7CN.js} +5 -1
- package/chunks/{dist-WGTQO7F2.js → dist-376652EZ.js} +114 -28
- package/chunks/{dist-53PZYC5B.js → dist-3YCTE6HD.js} +2 -2
- package/chunks/{dist-2BHAYBKP.js → dist-D7Z3HOO7.js} +14 -2
- package/chunks/{dist-FUTEXY6A.js → dist-MEGJFGAI.js} +40 -9
- package/chunks/{dist-2MIU4UUH.js → dist-NQ436QEX.js} +1 -1
- package/chunks/{dist-AU7NQQRP.js → dist-NQNTOIEN.js} +26 -2
- package/chunks/earlyInputCapture-HPUVJ2KH.js +81 -0
- package/chunks/{edit-3QV3JZJL.js → edit-7CMAN3F4.js} +50 -39
- package/chunks/{en-XE34GKAA.js → en-SALLIJS7.js} +6 -1
- package/chunks/{enter-worktree-4GMMF7EG.js → enter-worktree-3PH4YTY2.js} +49 -36
- package/chunks/{enterPlanMode-L5UWBAUC.js → enterPlanMode-MSXLSWLI.js} +55 -37
- package/chunks/{environment-3OV7UQOT.js → environment-KS36ZHBE.js} +48 -35
- package/chunks/errors-LCPFS62A.js +87 -0
- package/chunks/{exit-worktree-DDP57JLV.js → exit-worktree-ARA4C3CK.js} +49 -36
- package/chunks/{exitPlanMode-CJBLGPIP.js → exitPlanMode-GCDIQPB7.js} +49 -36
- package/chunks/{fast-path-M6RP2ING.js → fast-path-IDHBVIT6.js} +3 -2
- package/chunks/{fr-X7KDVZIY.js → fr-WVHEBDDB.js} +5 -1
- package/chunks/{gemini-H4PHBJTL.js → gemini-2AFQJMX5.js} +141 -105
- package/chunks/{geminiContentGenerator-VURJYPWP.js → geminiContentGenerator-UDIH3YI6.js} +9 -8
- package/chunks/{getMachineId-bsd-EXV7SWPA.js → getMachineId-bsd-QFVLPUPT.js} +1 -1
- package/chunks/{getMachineId-darwin-IUOMFXU3.js → getMachineId-darwin-DGMQQE2E.js} +1 -1
- package/chunks/{getMachineId-linux-K7XJYFHL.js → getMachineId-linux-R4Z6CSWC.js} +1 -1
- package/chunks/{getMachineId-unsupported-EA5FDRJ6.js → getMachineId-unsupported-Z3SBVBUV.js} +1 -1
- package/chunks/{getMachineId-win-KBA6RAI5.js → getMachineId-win-SCK5UFDT.js} +1 -1
- package/chunks/{glob-2KUSRAVQ.js → glob-HCL7HZ67.js} +49 -36
- package/chunks/{grep-B5RXVESV.js → grep-CJLBSCTV.js} +49 -36
- package/chunks/handleAutoUpdate-Q572P3FL.js +80 -0
- package/chunks/i18n-OBB4R7SR.js +96 -0
- package/chunks/initializer-LXEY6V3C.js +85 -0
- package/chunks/installationInfo-XUAOVMEE.js +79 -0
- package/chunks/{ja-2ICT3KXF.js → ja-KY4ROZTE.js} +5 -1
- package/chunks/{keychain-token-storage-DWRJMNH3.js → keychain-token-storage-6ACJDYIB.js} +3 -3
- package/chunks/{kittyProtocolDetector-HCNNKJTI.js → kittyProtocolDetector-MBRTDRBK.js} +5 -3
- package/chunks/list-WAXY7QOU.js +88 -0
- package/chunks/list-agents-AH3P5NB7.js +80 -0
- package/chunks/loadedSettingsAdapter-OZFNBRHE.js +82 -0
- package/chunks/loggingContentGenerator-7WDTTE6G.js +1068 -0
- package/chunks/{loop-wakeup-5GLTUBHA.js → loop-wakeup-IHRW6TNB.js} +7 -7
- package/chunks/{ls-FHBY3Y7I.js → ls-ZAXZ2G2W.js} +5 -5
- package/chunks/{lsp-B6VMEW6Y.js → lsp-R4ZG3UGQ.js} +3 -3
- package/chunks/managed-npm-update-N42DO5QW.js +339 -0
- package/chunks/mcp-6SOORKTY.js +82 -0
- package/chunks/{monitor-GLJZDNPS.js → monitor-4PSVNVU4.js} +51 -37
- package/chunks/node-UUDY34IG.js +305 -0
- package/chunks/nonInteractiveCli-FBR5S7IZ.js +140 -0
- package/chunks/{notebook-edit-AVCIWS4F.js → notebook-edit-QK26632S.js} +50 -39
- package/chunks/{openaiContentGenerator-B7W24G3D.js → openaiContentGenerator-IXJS6C2U.js} +33 -20
- package/chunks/pidfile-UCFCJOAP.js +85 -0
- package/chunks/{processUtils-XZPY2PBB.js → processUtils-YL2LXON2.js} +2 -2
- package/chunks/{pt-JJ4XPIBP.js → pt-OK455PLH.js} +5 -1
- package/chunks/{qwenContentGenerator-6GUTWJIC.js → qwenContentGenerator-H6WZPJKC.js} +56 -36
- package/chunks/{qwenOAuth2-GASEEWGU.js → qwenOAuth2-HTROHKXO.js} +10 -23
- package/chunks/read-file-FOYTMUNL.js +31 -0
- package/chunks/{read-mcp-resource-AKCL7I43.js → read-mcp-resource-65BWNF3F.js} +3 -3
- package/chunks/{record-artifact-PEUB7727.js → record-artifact-2RLSOP6U.js} +3 -3
- package/chunks/resumeHistoryUtils-ZNHTWBXS.js +90 -0
- package/chunks/ripGrep-K4K4QLNJ.js +72 -0
- package/chunks/{ru-STR4KTW7.js → ru-7SPDGMGD.js} +5 -1
- package/chunks/{run-qwen-serve-OZGR3FQA.js → run-qwen-serve-XI4MCAFV.js} +343 -88
- package/chunks/runtime-4CTBU5WX.js +115 -0
- package/chunks/{scheduler-Z7QLMUWA.js → scheduler-TTEITHBF.js} +46 -33
- package/chunks/sdk-exporters-grpc-N3OLDF63.js +23214 -0
- package/chunks/sdk-exporters-http-AOHAEOMC.js +563 -0
- package/chunks/sdk-impl-TLQOC7P4.js +9193 -0
- package/chunks/{send-message-3RHE7HSM.js → send-message-GEY4CNPS.js} +47 -8
- package/chunks/serve-W7UKJTQT.js +88 -0
- package/chunks/{server-SO64U3X5.js → server-JD5PIE7A.js} +3069 -517
- package/chunks/{session-2KL2WQAH.js → session-R4BDHLYR.js} +112 -177
- package/chunks/{settings-KITVOUSV.js → settings-BXZHA6TZ.js} +50 -37
- package/chunks/shell-XYMFCGN5.js +82 -0
- package/chunks/{skill-SOQHY455.js → skill-YKXYEPOF.js} +25 -20
- package/chunks/spawnChannel-IO4HQLFS.js +81 -0
- package/chunks/{src-43LM7JLB.js → src-LKKTJ4NG.js} +382 -235
- package/chunks/standalone-update-76JG7DVN.js +91 -0
- package/chunks/{startInteractiveUI-3RGTGEX5.js → startInteractiveUI-BXWQUXAS.js} +1314 -958
- package/chunks/{syntheticOutput-FG5PQKIR.js → syntheticOutput-2WNMXEU5.js} +4 -4
- package/chunks/task-create-R5H74Y76.js +25 -0
- package/chunks/{task-list-QWSY4ZIU.js → task-list-WXAFDSRY.js} +7 -7
- package/chunks/{task-stop-GWC6UWAL.js → task-stop-CHFZP23W.js} +4 -4
- package/chunks/{task-update-NCTAB73Q.js → task-update-Z44A4GAR.js} +11 -9
- package/chunks/{team-create-FXN3PEBP.js → team-create-5Y3MCAIM.js} +49 -36
- package/chunks/{team-delete-KK37HTOG.js → team-delete-YDCMRSI4.js} +7 -7
- package/chunks/{team-plan-approval-GEIZ356Q.js → team-plan-approval-HYJJZ76T.js} +49 -36
- package/chunks/theme-manager-3YF2SUZL.js +76 -0
- package/chunks/{todoWrite-ERCAMLFS.js → todoWrite-ED2IVZJL.js} +5 -5
- package/chunks/{tool-search-XKK7DNOK.js → tool-search-3ZO2XMEP.js} +21 -17
- package/chunks/total-session-admission-NDF7EVG7.js +83 -0
- package/chunks/trustedFolders-Q7RALK4T.js +92 -0
- package/chunks/{chunk-6EFTQYW7.js → undici-3FJYTMOF.js} +24 -399
- package/chunks/{chunk-L573Z2QZ.js → undici-PYHBDDPN.js} +1 -5
- package/chunks/{update-relaunch-FMVZK6XF.js → update-relaunch-BTW5XGVT.js} +17 -17
- package/chunks/updateCheck-MXIU6DWQ.js +91 -0
- package/chunks/useAutoAcceptIndicator-BJXHJW77.js +92 -0
- package/chunks/{validateNonInterActiveAuth-PRVEB6GG.js → validateNonInterActiveAuth-FLEPF3QQ.js} +90 -76
- package/chunks/{version-AZMG6KWL.js → version-75VRONIL.js} +1 -1
- package/chunks/{web-fetch-EPGJ5OQQ.js → web-fetch-5X27LYHB.js} +101 -41
- package/chunks/web-search-IDMTBJUP.js +718 -0
- package/chunks/{workflow-UTNVPW22.js → workflow-JOD2OPFQ.js} +54 -40
- package/chunks/workspace-providers-status-WDLBDLPG.js +85 -0
- package/chunks/{workspace-registration-store-F3ZX3YHT.js → workspace-registration-store-26Z6J6P5.js} +9 -3
- package/chunks/workspace-registry-IABDATX3.js +87 -0
- package/chunks/workspace-service-BI4KDYPD.js +97 -0
- package/chunks/workspace-skills-status-OVB4LPHA.js +84 -0
- package/chunks/write-file-276AJ7KE.js +72 -0
- package/chunks/{zh-6ANG2HTL.js → zh-Q54GA5SV.js} +6 -1
- package/chunks/{zh-TW-4RR3YHNN.js → zh-TW-VOBNFOPU.js} +6 -1
- package/cli-entry.js +164 -12
- package/cli.js +19 -12
- package/locales/ca.js +773 -203
- package/locales/de.js +8 -2
- package/locales/en.js +9 -2
- package/locales/fr.js +8 -2
- package/locales/ja.js +8 -2
- package/locales/pt.js +8 -2
- package/locales/ru.js +8 -2
- package/locales/zh-TW.js +9 -2
- package/locales/zh.js +9 -2
- package/package.json +3 -3
- package/web-shell/assets/{arc-Buk1besA.js → arc-CMb7lr2P.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-B1aUKYDC.js → architectureDiagram-3BPJPVTR-D6KQ5Kwm.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-CRTdg3Zx.js → blockDiagram-GPEHLZMM-Ce7YYSf8.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-DFdRMp5g.js → c4Diagram-AAUBKEIU-DaStHfor.js} +1 -1
- package/web-shell/assets/channel-Dg4f-Kry.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-4rYQdkEI.js → chunk-2J33WTMH-CPaqadg9.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-Coi-pQJy.js → chunk-4BX2VUAB-Veh9ZGKg.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-BtBjz02t.js → chunk-55IACEB6-BPTX5n4q.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-CGYOWorl.js → chunk-727SXJPM-CtXsE_ca.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-CH5AKhqx.js → chunk-AQP2D5EJ-D8DDCJ8h.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-Cd50-w85.js → chunk-FMBD7UC4-cjMDGzHz.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-C2wF3KCK.js → chunk-ND2GUHAM-BaZ1hNhV.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-pCeRTaWi.js → chunk-QZHKN3VN-C7w-9w5-.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CT7Fo2aW.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CT7Fo2aW.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-B-_fAB6D.js → cose-bilkent-S5V4N54A-DqvBEEIe.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-ChSPNHpL.js → dagre-BM42HDAG-RkPyoMAk.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-BX7cFOF3.js → diagram-2AECGRRQ-D9b6nNyg.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BQUTW92n.js → diagram-5GNKFQAL-CiiNKUIy.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-BkYPh3e4.js → diagram-KO2AKTUF-CP1qizXd.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-Cl6jsNyx.js → diagram-LMA3HP47-BGe30TWx.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-DRWoHz8n.js → diagram-OG6HWLK6-CvoEPARH.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-CGvFcZco.js → erDiagram-TEJ5UH35-DWfLzVkV.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-vms6oVdv.js → flowDiagram-I6XJVG4X-D-dTQmo6.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-ukT_sfmi.js → ganttDiagram-6RSMTGT7-CYPHKaGY.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Bn2ZE2Ut.js → gitGraphDiagram-PVQCEYII-DA7_aQYD.js} +1 -1
- package/web-shell/assets/index-B0i-TOYM.css +5 -0
- package/web-shell/assets/index-CgCHD46L.js +1225 -0
- package/web-shell/assets/{index-wFXp7W68.js → index-DqHNAB8C.js} +1 -1
- package/web-shell/assets/{infoDiagram-5YYISTIA-DHJdSi7x.js → infoDiagram-5YYISTIA-B87ljDPa.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-DOvd2Wph.js → ishikawaDiagram-YF4QCWOH-CYSpyjaN.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CH_urMCT.js → journeyDiagram-JHISSGLW-DAL6Js6f.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-FKiBdgbH.js → kanban-definition-UN3LZRKU-_zufKGJv.js} +1 -1
- package/web-shell/assets/{linear-0ZVQFVKf.js → linear-DidhMgku.js} +1 -1
- package/web-shell/assets/{mermaid.core-DJ05ZZIK.js → mermaid.core-DAkX3h3a.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-BPuUhkUm.js → mindmap-definition-RKZ34NQL-DbZxUBEH.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-yLFKcXyG.js → pieDiagram-4H26LBE5-Du9uoqrf.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-irWqc1pE.js → quadrantDiagram-W4KKPZXB-DwjELuKm.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-B_4uMoIV.js → requirementDiagram-4Y6WPE33-BAqfVtBL.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-ciA4GPwk.js → sankeyDiagram-5OEKKPKP--hm2VpmK.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CRdZvy0U.js → sequenceDiagram-3UESZ5HK-R5MUQaIt.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-DaYIkCCn.js → stateDiagram-AJRCARHV-VsX032xQ.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-uPWLcSfy.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-oBUKv6iH.js → timeline-definition-PNZ67QCA-BqjVRXzg.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-CGW9Sdmb.js → vennDiagram-CIIHVFJN-i2tkvlkg.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-CvwKJOCm.js → wardley-L42UT6IY-Ch8G49EM.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Ipc260sN.js → wardleyDiagram-YWT4CUSO-bYpWeQNy.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-D6-CM7pK.js → xychartDiagram-2RQKCTM6-C9NhuBqB.js} +1 -1
- package/web-shell/index.html +17 -13
- package/chunks/MaxSizedBox-B5YGZSYE.js +0 -72
- package/chunks/agent-H4JIDL7S.js +0 -67
- package/chunks/agent-headless-TTBEREQV.js +0 -61
- package/chunks/bridge-VL7ITBU5.js +0 -75
- package/chunks/chunk-542SK7KV.js +0 -8293
- package/chunks/chunk-CPCVCKKF.js +0 -358
- package/chunks/chunk-SEKHYHMS.js +0 -45
- package/chunks/chunk-W7FJ3N32.js +0 -49
- package/chunks/chunk-ZFKNWQGQ.js +0 -74639
- package/chunks/contextCommand-L2COEUHS.js +0 -66
- package/chunks/daemon-status-provider-NL4IAG7B.js +0 -74
- package/chunks/earlyInputCapture-L6I2A22T.js +0 -68
- package/chunks/errors-LEOF5QG4.js +0 -74
- package/chunks/handleAutoUpdate-QQVIWXKT.js +0 -67
- package/chunks/i18n-N6OBDORT.js +0 -83
- package/chunks/initializer-6WCFNDLL.js +0 -72
- package/chunks/installationInfo-6J3WPXNS.js +0 -64
- package/chunks/list-HOWQSWP6.js +0 -75
- package/chunks/loadedSettingsAdapter-AO4YBRXZ.js +0 -69
- package/chunks/mcp-QH7QNXOH.js +0 -69
- package/chunks/nonInteractiveCli-TI7EMPXD.js +0 -126
- package/chunks/pidfile-UEHAT6DH.js +0 -72
- package/chunks/read-file-SQJONF6A.js +0 -29
- package/chunks/resumeHistoryUtils-PFQ2A23X.js +0 -78
- package/chunks/ripGrep-QCK22GDU.js +0 -59
- package/chunks/runtime-SNVAP6EH.js +0 -100
- package/chunks/serve-BT7KS6SC.js +0 -75
- package/chunks/shell-BITUVH2R.js +0 -69
- package/chunks/spawnChannel-2BU3AULL.js +0 -68
- package/chunks/standalone-update-YG5JUYCM.js +0 -78
- package/chunks/task-create-HX32YXO7.js +0 -23
- package/chunks/theme-manager-IAETOI25.js +0 -63
- package/chunks/total-session-admission-BJLDHKJN.js +0 -69
- package/chunks/trustedFolders-5XCVNEUU.js +0 -79
- package/chunks/updateCheck-YZZB7YBU.js +0 -70
- package/chunks/useAutoAcceptIndicator-ZSQX4I2H.js +0 -80
- package/chunks/workspace-providers-status-EADV364W.js +0 -72
- package/chunks/workspace-registry-W6VMFYZU.js +0 -73
- package/chunks/workspace-service-F3KIN2UN.js +0 -84
- package/chunks/workspace-skills-status-YVICUR5Y.js +0 -71
- package/chunks/write-file-CVGF2OKV.js +0 -596
- package/web-shell/assets/channel-04R0vLbG.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-Bw9SOwAV.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Bw9SOwAV.js +0 -1
- package/web-shell/assets/index-DgkKrjw3.js +0 -1187
- package/web-shell/assets/index-Rv6mOAN9.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DWBoO4UY.js +0 -1
|
@@ -1,28 +1,5 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import {
|
|
4
|
-
DEFAULT_RING_SIZE,
|
|
5
|
-
EVENT_SCHEMA_VERSION,
|
|
6
|
-
EventBus,
|
|
7
|
-
serializedBridgeEventByteLength
|
|
8
|
-
} from "./chunk-6RLROE6G.js";
|
|
9
|
-
import {
|
|
10
|
-
normalizeCompactedReplayMaxBytes
|
|
11
|
-
} from "./chunk-COH43MRJ.js";
|
|
12
|
-
import {
|
|
13
|
-
CHANNEL_STARTUP_PROFILE_META_KEY,
|
|
14
|
-
CHANNEL_STARTUP_PROFILE_VERSION,
|
|
15
|
-
LOAD_REPLAY_BULK_MODE,
|
|
16
|
-
LOAD_REPLAY_META_KEY,
|
|
17
|
-
LOAD_REPLAY_MODE_META_KEY,
|
|
18
|
-
LOAD_REPLAY_PAGE_SIZE_META_KEY,
|
|
19
|
-
LOAD_REPLAY_VERSION,
|
|
20
|
-
MID_TURN_QUEUE_DRAIN_METHOD,
|
|
21
|
-
TODO_STOP_GUARD_QUEUE_RELEASE_METHOD
|
|
22
|
-
} from "./chunk-QR6U5QPP.js";
|
|
23
|
-
import {
|
|
24
|
-
defaultSpawnChannelFactory
|
|
25
|
-
} from "./chunk-CV63PP6U.js";
|
|
26
3
|
import {
|
|
27
4
|
BranchWhilePromptActiveError,
|
|
28
5
|
CancelSentinelCollisionError,
|
|
@@ -34,6 +11,7 @@ import {
|
|
|
34
11
|
InvalidSessionScopeError,
|
|
35
12
|
MCP_RESTART_SERVER_DEADLINE_MS,
|
|
36
13
|
PermissionForbiddenError,
|
|
14
|
+
PromptDeadlineExceededError,
|
|
37
15
|
PromptQueueFullError,
|
|
38
16
|
RestoreInProgressError,
|
|
39
17
|
SessionBusyError,
|
|
@@ -43,7 +21,32 @@ import {
|
|
|
43
21
|
SessionShellDisabledError,
|
|
44
22
|
WorkspaceMismatchError,
|
|
45
23
|
isNotCurrentlyGeneratingCancelError
|
|
46
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-UH3WSE5L.js";
|
|
25
|
+
import {
|
|
26
|
+
CHANNEL_STARTUP_PROFILE_META_KEY,
|
|
27
|
+
CHANNEL_STARTUP_PROFILE_VERSION,
|
|
28
|
+
DAEMON_CHANNEL_DELIVERY_META_KEY,
|
|
29
|
+
LOAD_REPLAY_BULK_MODE,
|
|
30
|
+
LOAD_REPLAY_META_KEY,
|
|
31
|
+
LOAD_REPLAY_MODE_META_KEY,
|
|
32
|
+
LOAD_REPLAY_PAGE_SIZE_META_KEY,
|
|
33
|
+
LOAD_REPLAY_VERSION,
|
|
34
|
+
MID_TURN_QUEUE_DRAIN_METHOD,
|
|
35
|
+
PROMPT_CANCEL_METHOD,
|
|
36
|
+
TODO_STOP_GUARD_QUEUE_RELEASE_METHOD
|
|
37
|
+
} from "./chunk-3SJ43L4W.js";
|
|
38
|
+
import {
|
|
39
|
+
DEFAULT_RING_SIZE,
|
|
40
|
+
EVENT_SCHEMA_VERSION,
|
|
41
|
+
EventBus,
|
|
42
|
+
serializedBridgeEventByteLength
|
|
43
|
+
} from "./chunk-BLFVGB7D.js";
|
|
44
|
+
import {
|
|
45
|
+
normalizeCompactedReplayMaxBytes
|
|
46
|
+
} from "./chunk-COH43MRJ.js";
|
|
47
|
+
import {
|
|
48
|
+
defaultSpawnChannelFactory
|
|
49
|
+
} from "./chunk-YCIM6O3I.js";
|
|
47
50
|
import {
|
|
48
51
|
BridgeChannelClosedError,
|
|
49
52
|
BridgeTimeoutError,
|
|
@@ -52,10 +55,16 @@ import {
|
|
|
52
55
|
STATUS_SCHEMA_VERSION,
|
|
53
56
|
createIdleWorkspaceExtensionsStatus,
|
|
54
57
|
createIdleWorkspaceHooksStatus
|
|
55
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-CUPAVLRY.js";
|
|
56
59
|
import {
|
|
57
|
-
canonicalizeWorkspace
|
|
58
|
-
|
|
60
|
+
canonicalizeWorkspace,
|
|
61
|
+
translateAndCheckAbsoluteWorkspacePath
|
|
62
|
+
} from "./chunk-2RFKHEXL.js";
|
|
63
|
+
import {
|
|
64
|
+
CHANNEL_DELIVERY_ERROR_CODES,
|
|
65
|
+
MAX_SUB_SESSION_NAME_CHARS,
|
|
66
|
+
MAX_SUB_SESSION_PROMPT_CHARS
|
|
67
|
+
} from "./chunk-BK2UNYWD.js";
|
|
59
68
|
import {
|
|
60
69
|
ClientSideConnection,
|
|
61
70
|
PROTOCOL_VERSION,
|
|
@@ -72,11 +81,16 @@ import {
|
|
|
72
81
|
metadataBudgetBytes,
|
|
73
82
|
normalizeSnapshotPayload,
|
|
74
83
|
stableSessionArtifactId
|
|
75
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-LI4I37W4.js";
|
|
76
85
|
import {
|
|
77
86
|
DAEMON_TRACEPARENT_META_KEY,
|
|
78
87
|
DAEMON_TRACESTATE_META_KEY
|
|
79
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-AXUW635Q.js";
|
|
89
|
+
import {
|
|
90
|
+
INVOCATION_CONTEXT_META_KEY,
|
|
91
|
+
PRIVATE_ACP_CAPABILITY_ENV,
|
|
92
|
+
PRIVATE_PARENT_CAPABILITY_META_KEY
|
|
93
|
+
} from "./chunk-IFG6TYJ2.js";
|
|
80
94
|
import {
|
|
81
95
|
init_esbuild_shims
|
|
82
96
|
} from "./chunk-5O2XNYP6.js";
|
|
@@ -86,7 +100,7 @@ import {
|
|
|
86
100
|
|
|
87
101
|
// packages/acp-bridge/src/bridge.ts
|
|
88
102
|
init_esbuild_shims();
|
|
89
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
103
|
+
import { randomBytes, randomUUID as randomUUID2 } from "node:crypto";
|
|
90
104
|
import * as path3 from "node:path";
|
|
91
105
|
|
|
92
106
|
// packages/acp-bridge/src/compactionEngine.ts
|
|
@@ -310,6 +324,8 @@ var TurnBoundaryCompactionEngine = class {
|
|
|
310
324
|
if (event.id !== void 0) slot.lastEventId = event.id;
|
|
311
325
|
slot.lastMeta = meta ?? slot.lastMeta;
|
|
312
326
|
slot.lastEnvelopeMeta = event._meta ?? slot.lastEnvelopeMeta;
|
|
327
|
+
slot.lastTurn = captureTurnFields(event, slot.lastTurn);
|
|
328
|
+
slot.lastSessionId = captureSessionId(event) ?? slot.lastSessionId;
|
|
313
329
|
} else {
|
|
314
330
|
entries.push({ sourceRecordIds, index: this.slots.length });
|
|
315
331
|
this.textSlotIndex[kind].set(parentToolCallId, entries);
|
|
@@ -320,7 +336,9 @@ var TurnBoundaryCompactionEngine = class {
|
|
|
320
336
|
sourceRecordIds,
|
|
321
337
|
lastEventId: event.id ?? 0,
|
|
322
338
|
lastMeta: meta,
|
|
323
|
-
lastEnvelopeMeta: event._meta
|
|
339
|
+
lastEnvelopeMeta: event._meta,
|
|
340
|
+
lastTurn: captureTurnFields(event),
|
|
341
|
+
lastSessionId: captureSessionId(event)
|
|
324
342
|
});
|
|
325
343
|
}
|
|
326
344
|
} else {
|
|
@@ -330,6 +348,8 @@ var TurnBoundaryCompactionEngine = class {
|
|
|
330
348
|
if (event.id !== void 0) lastSlot.lastEventId = event.id;
|
|
331
349
|
lastSlot.lastMeta = meta ?? lastSlot.lastMeta;
|
|
332
350
|
lastSlot.lastEnvelopeMeta = event._meta ?? lastSlot.lastEnvelopeMeta;
|
|
351
|
+
lastSlot.lastTurn = captureTurnFields(event, lastSlot.lastTurn);
|
|
352
|
+
lastSlot.lastSessionId = captureSessionId(event) ?? lastSlot.lastSessionId;
|
|
333
353
|
} else {
|
|
334
354
|
this.slots.push({
|
|
335
355
|
kind,
|
|
@@ -338,7 +358,9 @@ var TurnBoundaryCompactionEngine = class {
|
|
|
338
358
|
sourceRecordIds,
|
|
339
359
|
lastEventId: event.id ?? 0,
|
|
340
360
|
lastMeta: meta,
|
|
341
|
-
lastEnvelopeMeta: event._meta
|
|
361
|
+
lastEnvelopeMeta: event._meta,
|
|
362
|
+
lastTurn: captureTurnFields(event),
|
|
363
|
+
lastSessionId: captureSessionId(event)
|
|
342
364
|
});
|
|
343
365
|
}
|
|
344
366
|
}
|
|
@@ -355,7 +377,9 @@ var TurnBoundaryCompactionEngine = class {
|
|
|
355
377
|
slot.chunks.join(""),
|
|
356
378
|
slot.lastEventId,
|
|
357
379
|
slot.lastMeta,
|
|
358
|
-
slot.lastEnvelopeMeta
|
|
380
|
+
slot.lastEnvelopeMeta,
|
|
381
|
+
slot.lastTurn,
|
|
382
|
+
slot.lastSessionId
|
|
359
383
|
)
|
|
360
384
|
);
|
|
361
385
|
break;
|
|
@@ -462,13 +486,20 @@ var TurnBoundaryCompactionEngine = class {
|
|
|
462
486
|
this.textSlotIndex.thought.clear();
|
|
463
487
|
}
|
|
464
488
|
};
|
|
465
|
-
function makeMergedSessionUpdateEvent(sessionUpdate, text, eventId, meta, envelopeMeta) {
|
|
489
|
+
function makeMergedSessionUpdateEvent(sessionUpdate, text, eventId, meta, envelopeMeta, turn, sessionId) {
|
|
466
490
|
return {
|
|
467
491
|
id: eventId || void 0,
|
|
468
492
|
v: EVENT_SCHEMA_VERSION,
|
|
469
493
|
type: "session_update",
|
|
494
|
+
// Re-stamp prompt/originator attribution captured from the source
|
|
495
|
+
// chunks — clients rebuilding state from a compacted snapshot need
|
|
496
|
+
// them for prompt correlation and originator filtering. Present only
|
|
497
|
+
// when the source events carried them ("present only if set" style).
|
|
498
|
+
...turn?.promptId !== void 0 ? { promptId: turn.promptId } : {},
|
|
499
|
+
...turn?.originatorClientId !== void 0 ? { originatorClientId: turn.originatorClientId } : {},
|
|
470
500
|
...envelopeMeta !== void 0 ? { _meta: envelopeMeta } : {},
|
|
471
501
|
data: {
|
|
502
|
+
...sessionId !== void 0 ? { sessionId } : {},
|
|
472
503
|
update: {
|
|
473
504
|
sessionUpdate,
|
|
474
505
|
content: { type: "text", text },
|
|
@@ -478,6 +509,23 @@ function makeMergedSessionUpdateEvent(sessionUpdate, text, eventId, meta, envelo
|
|
|
478
509
|
};
|
|
479
510
|
}
|
|
480
511
|
__name(makeMergedSessionUpdateEvent, "makeMergedSessionUpdateEvent");
|
|
512
|
+
function captureTurnFields(event, previous) {
|
|
513
|
+
const promptId = event.promptId ?? previous?.promptId;
|
|
514
|
+
const originatorClientId = event.originatorClientId ?? previous?.originatorClientId;
|
|
515
|
+
if (promptId === void 0 && originatorClientId === void 0) {
|
|
516
|
+
return void 0;
|
|
517
|
+
}
|
|
518
|
+
return {
|
|
519
|
+
...promptId !== void 0 ? { promptId } : {},
|
|
520
|
+
...originatorClientId !== void 0 ? { originatorClientId } : {}
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
__name(captureTurnFields, "captureTurnFields");
|
|
524
|
+
function captureSessionId(event) {
|
|
525
|
+
const sessionId = event.data?.sessionId;
|
|
526
|
+
return typeof sessionId === "string" ? sessionId : void 0;
|
|
527
|
+
}
|
|
528
|
+
__name(captureSessionId, "captureSessionId");
|
|
481
529
|
function normalizeToolCallType(event) {
|
|
482
530
|
const data = event.data;
|
|
483
531
|
if (data?.update?.sessionUpdate === "tool_call_update") {
|
|
@@ -540,10 +588,14 @@ function mergeToolCallEvent(existing, incoming) {
|
|
|
540
588
|
if (updateMeta !== void 0) merged["_meta"] = updateMeta;
|
|
541
589
|
merged["sessionUpdate"] = "tool_call";
|
|
542
590
|
const mergedMeta = existing._meta || incoming._meta ? { ...existing._meta ?? {}, ...incoming._meta ?? {} } : void 0;
|
|
591
|
+
const promptId = incoming.promptId ?? existing.promptId;
|
|
592
|
+
const originatorClientId = incoming.originatorClientId ?? existing.originatorClientId;
|
|
543
593
|
return {
|
|
544
594
|
id: incoming.id ?? existing.id,
|
|
545
595
|
v: EVENT_SCHEMA_VERSION,
|
|
546
596
|
type: "session_update",
|
|
597
|
+
...promptId !== void 0 ? { promptId } : {},
|
|
598
|
+
...originatorClientId !== void 0 ? { originatorClientId } : {},
|
|
547
599
|
...mergedMeta ? { _meta: mergedMeta } : {},
|
|
548
600
|
data: {
|
|
549
601
|
...existingData,
|
|
@@ -715,11 +767,6 @@ import * as path from "node:path";
|
|
|
715
767
|
init_esbuild_shims();
|
|
716
768
|
var MID_TURN_MESSAGE_INJECTED_EVENT = "mid_turn_message_injected";
|
|
717
769
|
|
|
718
|
-
// packages/acp-bridge/src/bridgeOptions.ts
|
|
719
|
-
init_esbuild_shims();
|
|
720
|
-
var MAX_SUB_SESSION_PROMPT_CHARS = 1e5;
|
|
721
|
-
var MAX_SUB_SESSION_NAME_CHARS = 200;
|
|
722
|
-
|
|
723
770
|
// packages/acp-bridge/src/permissionMediator.ts
|
|
724
771
|
init_esbuild_shims();
|
|
725
772
|
|
|
@@ -1405,6 +1452,9 @@ var MultiClientPermissionMediator = class {
|
|
|
1405
1452
|
|
|
1406
1453
|
// packages/acp-bridge/src/bridgeClient.ts
|
|
1407
1454
|
var PUBLISH_ARTIFACT_TOOL_NAME = "artifact";
|
|
1455
|
+
var MAX_CHANNEL_DELIVERY_TEXT_CHARS = 1e5;
|
|
1456
|
+
var MAX_CHANNEL_DELIVERY_FIELD_CHARS = 2048;
|
|
1457
|
+
var MAX_CHANNEL_DELIVERY_ERROR_CHARS = 500;
|
|
1408
1458
|
function isFsErrorShape(err) {
|
|
1409
1459
|
return err instanceof Error && err.name === "FsError" && typeof err.kind === "string";
|
|
1410
1460
|
}
|
|
@@ -1413,6 +1463,25 @@ function isRecord2(value) {
|
|
|
1413
1463
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1414
1464
|
}
|
|
1415
1465
|
__name(isRecord2, "isRecord");
|
|
1466
|
+
function isBoundedChannelDeliveryString(value) {
|
|
1467
|
+
return typeof value === "string" && value.trim().length > 0 && value.length <= MAX_CHANNEL_DELIVERY_FIELD_CHARS;
|
|
1468
|
+
}
|
|
1469
|
+
__name(isBoundedChannelDeliveryString, "isBoundedChannelDeliveryString");
|
|
1470
|
+
function isChannelDeliveryTarget(value) {
|
|
1471
|
+
if (!isRecord2(value)) return false;
|
|
1472
|
+
return isBoundedChannelDeliveryString(value["channelName"]) && (value["type"] === "user" || value["type"] === "chat") && isBoundedChannelDeliveryString(value["id"]) && Object.keys(value).every(
|
|
1473
|
+
(key) => key === "channelName" || key === "type" || key === "id"
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1476
|
+
__name(isChannelDeliveryTarget, "isChannelDeliveryTarget");
|
|
1477
|
+
function normalizeChannelDeliveryHostResult(value) {
|
|
1478
|
+
if (value.status === "delivered") return { status: "delivered" };
|
|
1479
|
+
if (value.status === "skipped") return { status: "skipped" };
|
|
1480
|
+
const code = CHANNEL_DELIVERY_ERROR_CODES.has(value.code) ? value.code : "channel_delivery_failed";
|
|
1481
|
+
const error = typeof value.error === "string" && value.error.length > 0 ? value.error.slice(0, MAX_CHANNEL_DELIVERY_ERROR_CHARS) : "Channel delivery failed.";
|
|
1482
|
+
return { status: "failed", code, error };
|
|
1483
|
+
}
|
|
1484
|
+
__name(normalizeChannelDeliveryHostResult, "normalizeChannelDeliveryHostResult");
|
|
1416
1485
|
function pendingInteractionOptions(options) {
|
|
1417
1486
|
return options.map((option) => ({
|
|
1418
1487
|
optionId: String(option.optionId ?? ""),
|
|
@@ -1623,7 +1692,7 @@ function sliceLineRange(content, startLine, endLine) {
|
|
|
1623
1692
|
}
|
|
1624
1693
|
__name(sliceLineRange, "sliceLineRange");
|
|
1625
1694
|
var BridgeClient = class {
|
|
1626
|
-
constructor(resolveEntry, resolvePendingRestoreEvents, mediator, permissionTimeoutMs, maxPendingPerSession, fileSystem, onModelPromoted, onModePromoted, clientMcpSender, ownsSession = () => true, onTokenUsage, onCreateSubSession, onGenerationEvent) {
|
|
1695
|
+
constructor(resolveEntry, resolvePendingRestoreEvents, mediator, permissionTimeoutMs, maxPendingPerSession, fileSystem, onModelPromoted, onModePromoted, clientMcpSender, ownsSession = () => true, onTokenUsage, onCreateSubSession, onGenerationEvent, onWorkspaceGenerationEvent, onChannelDelivery) {
|
|
1627
1696
|
this.resolveEntry = resolveEntry;
|
|
1628
1697
|
this.resolvePendingRestoreEvents = resolvePendingRestoreEvents;
|
|
1629
1698
|
this.mediator = mediator;
|
|
@@ -1637,6 +1706,8 @@ var BridgeClient = class {
|
|
|
1637
1706
|
this.onTokenUsage = onTokenUsage;
|
|
1638
1707
|
this.onCreateSubSession = onCreateSubSession;
|
|
1639
1708
|
this.onGenerationEvent = onGenerationEvent;
|
|
1709
|
+
this.onWorkspaceGenerationEvent = onWorkspaceGenerationEvent;
|
|
1710
|
+
this.onChannelDelivery = onChannelDelivery;
|
|
1640
1711
|
}
|
|
1641
1712
|
static {
|
|
1642
1713
|
__name(this, "BridgeClient");
|
|
@@ -1914,6 +1985,9 @@ var BridgeClient = class {
|
|
|
1914
1985
|
if (method === SERVE_CONTROL_EXT_METHODS.createSubSession) {
|
|
1915
1986
|
return this.handleCreateSubSession(params);
|
|
1916
1987
|
}
|
|
1988
|
+
if (method === SERVE_CONTROL_EXT_METHODS.channelDelivery) {
|
|
1989
|
+
return this.handleChannelDelivery(params);
|
|
1990
|
+
}
|
|
1917
1991
|
if (method !== MID_TURN_QUEUE_DRAIN_METHOD) {
|
|
1918
1992
|
throw RequestError.methodNotFound(method);
|
|
1919
1993
|
}
|
|
@@ -1950,6 +2024,98 @@ var BridgeClient = class {
|
|
|
1950
2024
|
}
|
|
1951
2025
|
return { messages, hasQueuedPrompt };
|
|
1952
2026
|
}
|
|
2027
|
+
async handleChannelDelivery(params) {
|
|
2028
|
+
if (!this.onChannelDelivery) {
|
|
2029
|
+
throw RequestError.methodNotFound(
|
|
2030
|
+
SERVE_CONTROL_EXT_METHODS.channelDelivery
|
|
2031
|
+
);
|
|
2032
|
+
}
|
|
2033
|
+
const sessionId = params["sessionId"];
|
|
2034
|
+
if (typeof sessionId !== "string" || sessionId.length === 0 || !this.ownsSession(sessionId)) {
|
|
2035
|
+
throw RequestError.invalidParams(
|
|
2036
|
+
void 0,
|
|
2037
|
+
"`sessionId` must name a session owned by this connection"
|
|
2038
|
+
);
|
|
2039
|
+
}
|
|
2040
|
+
const entry = this.resolveEntry(sessionId);
|
|
2041
|
+
if (!entry) {
|
|
2042
|
+
throw RequestError.invalidParams(void 0, "Unknown `sessionId`");
|
|
2043
|
+
}
|
|
2044
|
+
const deliveryId = params["deliveryId"];
|
|
2045
|
+
const source = params["source"];
|
|
2046
|
+
const text = params["text"];
|
|
2047
|
+
const rawTarget = params["target"];
|
|
2048
|
+
if (!isBoundedChannelDeliveryString(deliveryId) || source !== "prompt" && source !== "scheduled" || typeof text !== "string" || text.length > MAX_CHANNEL_DELIVERY_TEXT_CHARS || !isChannelDeliveryTarget(rawTarget)) {
|
|
2049
|
+
throw RequestError.invalidParams(
|
|
2050
|
+
void 0,
|
|
2051
|
+
"Invalid channel delivery request"
|
|
2052
|
+
);
|
|
2053
|
+
}
|
|
2054
|
+
const promptId = params["promptId"];
|
|
2055
|
+
const taskId = params["taskId"];
|
|
2056
|
+
const firedAt = params["firedAt"];
|
|
2057
|
+
const allowedKeys = source === "prompt" ? /* @__PURE__ */ new Set([
|
|
2058
|
+
"sessionId",
|
|
2059
|
+
"deliveryId",
|
|
2060
|
+
"source",
|
|
2061
|
+
"target",
|
|
2062
|
+
"text",
|
|
2063
|
+
"promptId"
|
|
2064
|
+
]) : /* @__PURE__ */ new Set([
|
|
2065
|
+
"sessionId",
|
|
2066
|
+
"deliveryId",
|
|
2067
|
+
"source",
|
|
2068
|
+
"target",
|
|
2069
|
+
"text",
|
|
2070
|
+
"taskId",
|
|
2071
|
+
"firedAt"
|
|
2072
|
+
]);
|
|
2073
|
+
const correlationValid = source === "prompt" ? isBoundedChannelDeliveryString(promptId) && promptId === deliveryId : isBoundedChannelDeliveryString(taskId) && typeof firedAt === "number" && Number.isFinite(firedAt) && deliveryId === `${taskId}:${firedAt}`;
|
|
2074
|
+
if (!correlationValid || !Object.keys(params).every((key) => allowedKeys.has(key))) {
|
|
2075
|
+
throw RequestError.invalidParams(
|
|
2076
|
+
void 0,
|
|
2077
|
+
"Invalid channel delivery correlation"
|
|
2078
|
+
);
|
|
2079
|
+
}
|
|
2080
|
+
const info = {
|
|
2081
|
+
sessionId,
|
|
2082
|
+
deliveryId,
|
|
2083
|
+
source,
|
|
2084
|
+
target: rawTarget,
|
|
2085
|
+
text,
|
|
2086
|
+
...source === "prompt" ? { promptId } : {},
|
|
2087
|
+
...source === "scheduled" ? { taskId, firedAt } : {}
|
|
2088
|
+
};
|
|
2089
|
+
let result;
|
|
2090
|
+
try {
|
|
2091
|
+
result = normalizeChannelDeliveryHostResult(
|
|
2092
|
+
await this.onChannelDelivery(info)
|
|
2093
|
+
);
|
|
2094
|
+
} catch {
|
|
2095
|
+
result = {
|
|
2096
|
+
status: "failed",
|
|
2097
|
+
code: "channel_delivery_failed",
|
|
2098
|
+
error: "Channel delivery failed."
|
|
2099
|
+
};
|
|
2100
|
+
}
|
|
2101
|
+
try {
|
|
2102
|
+
entry.events.publish({
|
|
2103
|
+
type: "channel_delivery_result",
|
|
2104
|
+
...source === "prompt" ? { promptId } : {},
|
|
2105
|
+
data: {
|
|
2106
|
+
sessionId,
|
|
2107
|
+
deliveryId,
|
|
2108
|
+
source,
|
|
2109
|
+
status: result.status,
|
|
2110
|
+
...source === "prompt" ? { promptId } : {},
|
|
2111
|
+
...source === "scheduled" ? { taskId, firedAt } : {},
|
|
2112
|
+
...result.status === "failed" ? { code: result.code, error: result.error } : {}
|
|
2113
|
+
}
|
|
2114
|
+
});
|
|
2115
|
+
} catch {
|
|
2116
|
+
}
|
|
2117
|
+
return result;
|
|
2118
|
+
}
|
|
1953
2119
|
/**
|
|
1954
2120
|
* Reverse tool channel (issue #5626, Phase 2) — answer the child's
|
|
1955
2121
|
* `qwen/control/client_mcp/message` ext-method. The child's session
|
|
@@ -2117,6 +2283,47 @@ var BridgeClient = class {
|
|
|
2117
2283
|
}
|
|
2118
2284
|
return;
|
|
2119
2285
|
}
|
|
2286
|
+
if (method === "qwen/notify/workspace/generation/event") {
|
|
2287
|
+
const requestId = params["requestId"];
|
|
2288
|
+
const event = params["event"];
|
|
2289
|
+
if (params["v"] !== 1 || typeof requestId !== "string" || !event || typeof event !== "object" || Array.isArray(event)) {
|
|
2290
|
+
return;
|
|
2291
|
+
}
|
|
2292
|
+
const record = event;
|
|
2293
|
+
if (record["type"] === "started") {
|
|
2294
|
+
const model = record["model"];
|
|
2295
|
+
const modelSource = record["modelSource"];
|
|
2296
|
+
if (typeof model !== "string" || modelSource !== "fast" && modelSource !== "main") {
|
|
2297
|
+
return;
|
|
2298
|
+
}
|
|
2299
|
+
this.onWorkspaceGenerationEvent?.({
|
|
2300
|
+
type: "started",
|
|
2301
|
+
requestId,
|
|
2302
|
+
model,
|
|
2303
|
+
modelSource
|
|
2304
|
+
});
|
|
2305
|
+
return;
|
|
2306
|
+
}
|
|
2307
|
+
if (record["type"] === "thinking") {
|
|
2308
|
+
this.onWorkspaceGenerationEvent?.({ type: "thinking", requestId });
|
|
2309
|
+
return;
|
|
2310
|
+
}
|
|
2311
|
+
if (record["type"] === "delta") {
|
|
2312
|
+
const seq = record["seq"];
|
|
2313
|
+
const text = record["text"];
|
|
2314
|
+
if (typeof seq !== "number" || !Number.isSafeInteger(seq) || seq < 0 || typeof text !== "string" || text.length === 0) {
|
|
2315
|
+
return;
|
|
2316
|
+
}
|
|
2317
|
+
this.onWorkspaceGenerationEvent?.({
|
|
2318
|
+
type: "delta",
|
|
2319
|
+
requestId,
|
|
2320
|
+
seq,
|
|
2321
|
+
text
|
|
2322
|
+
});
|
|
2323
|
+
return;
|
|
2324
|
+
}
|
|
2325
|
+
return;
|
|
2326
|
+
}
|
|
2120
2327
|
if (method === "qwen/notify/session/model-update") {
|
|
2121
2328
|
this.handleInSessionModelUpdate(params);
|
|
2122
2329
|
return;
|
|
@@ -5040,6 +5247,12 @@ function isRecord3(value) {
|
|
|
5040
5247
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5041
5248
|
}
|
|
5042
5249
|
__name(isRecord3, "isRecord");
|
|
5250
|
+
function isDefinitiveAcpRequestError(error) {
|
|
5251
|
+
if (error instanceof RequestError) return true;
|
|
5252
|
+
if (!isRecord3(error)) return false;
|
|
5253
|
+
return typeof error["code"] === "number" && Number.isInteger(error["code"]) && typeof error["message"] === "string";
|
|
5254
|
+
}
|
|
5255
|
+
__name(isDefinitiveAcpRequestError, "isDefinitiveAcpRequestError");
|
|
5043
5256
|
function getCanonicalModelId(response, fallback) {
|
|
5044
5257
|
if (!isRecord3(response) || !isRecord3(response["_meta"])) return fallback;
|
|
5045
5258
|
const modelSwitch = response["_meta"]["qwenModelSwitch"];
|
|
@@ -5295,13 +5508,15 @@ function broadcastPromptCancelled(entry, sessionId, promptId, originatorClientId
|
|
|
5295
5508
|
}
|
|
5296
5509
|
__name(broadcastPromptCancelled, "broadcastPromptCancelled");
|
|
5297
5510
|
function broadcastPromptCancelledOnce(entry, sessionId, promptId, originatorClientId, reason) {
|
|
5298
|
-
if (entry.
|
|
5511
|
+
if (promptId !== void 0 && entry.cancelBroadcastPromptId === promptId) {
|
|
5299
5512
|
writeStderrLine(
|
|
5300
|
-
`broadcastPromptCancelledOnce: suppressed duplicate cancel for session ${sessionId}
|
|
5513
|
+
`broadcastPromptCancelledOnce: suppressed duplicate cancel for session ${sessionId} prompt=${promptId}`
|
|
5301
5514
|
);
|
|
5302
5515
|
return;
|
|
5303
5516
|
}
|
|
5304
|
-
|
|
5517
|
+
if (promptId !== void 0) {
|
|
5518
|
+
entry.cancelBroadcastPromptId = promptId;
|
|
5519
|
+
}
|
|
5305
5520
|
broadcastPromptCancelled(
|
|
5306
5521
|
entry,
|
|
5307
5522
|
sessionId,
|
|
@@ -5367,7 +5582,7 @@ function classifyTurnErrorKind(message) {
|
|
|
5367
5582
|
return message.trim().toLowerCase() === "terminated" ? "model_stream_interrupted" : void 0;
|
|
5368
5583
|
}
|
|
5369
5584
|
__name(classifyTurnErrorKind, "classifyTurnErrorKind");
|
|
5370
|
-
function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId) {
|
|
5585
|
+
function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId, mutateTurnState) {
|
|
5371
5586
|
const message = extractErrorMessage(err);
|
|
5372
5587
|
const code = extractErrorCode(err);
|
|
5373
5588
|
const errorKind = classifyTurnErrorKind(message);
|
|
@@ -5376,12 +5591,14 @@ function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId)
|
|
|
5376
5591
|
`turn_error classified session=${JSON.stringify(sessionId)} message=${JSON.stringify(message)} errorKind=${JSON.stringify(errorKind)}` + (code ? ` code=${JSON.stringify(code)}` : "") + (promptId ? ` promptId=${JSON.stringify(promptId)}` : "")
|
|
5377
5592
|
);
|
|
5378
5593
|
}
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5594
|
+
if (mutateTurnState) {
|
|
5595
|
+
entry.retryAllowed = true;
|
|
5596
|
+
entry.turnError = {
|
|
5597
|
+
message,
|
|
5598
|
+
...code ? { code } : {},
|
|
5599
|
+
...errorKind ? { errorKind } : {}
|
|
5600
|
+
};
|
|
5601
|
+
}
|
|
5385
5602
|
try {
|
|
5386
5603
|
entry.events.publish({
|
|
5387
5604
|
type: "turn_error",
|
|
@@ -5399,6 +5616,64 @@ function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId)
|
|
|
5399
5616
|
}
|
|
5400
5617
|
}
|
|
5401
5618
|
__name(broadcastTurnError, "broadcastTurnError");
|
|
5619
|
+
function publishPromptTerminal(entry, pendingEntry, terminal) {
|
|
5620
|
+
if (pendingEntry.terminalPublished) {
|
|
5621
|
+
writeServeDebugLine(
|
|
5622
|
+
`publishPromptTerminal: suppressed duplicate ${terminal.kind} terminal for prompt ${pendingEntry.promptId} (session ${entry.sessionId})`
|
|
5623
|
+
);
|
|
5624
|
+
return;
|
|
5625
|
+
}
|
|
5626
|
+
pendingEntry.terminalPublished = true;
|
|
5627
|
+
const originatorClientId = pendingEntry.originatorClientId;
|
|
5628
|
+
if (terminal.kind === "complete") {
|
|
5629
|
+
broadcastTurnComplete(
|
|
5630
|
+
entry,
|
|
5631
|
+
entry.sessionId,
|
|
5632
|
+
terminal.result,
|
|
5633
|
+
pendingEntry.promptId,
|
|
5634
|
+
originatorClientId
|
|
5635
|
+
);
|
|
5636
|
+
} else if (terminal.kind === "cancelled") {
|
|
5637
|
+
broadcastTurnComplete(
|
|
5638
|
+
entry,
|
|
5639
|
+
entry.sessionId,
|
|
5640
|
+
{ stopReason: "cancelled" },
|
|
5641
|
+
pendingEntry.promptId,
|
|
5642
|
+
originatorClientId
|
|
5643
|
+
);
|
|
5644
|
+
} else {
|
|
5645
|
+
broadcastTurnError(
|
|
5646
|
+
entry,
|
|
5647
|
+
entry.sessionId,
|
|
5648
|
+
terminal.err,
|
|
5649
|
+
pendingEntry.promptId,
|
|
5650
|
+
originatorClientId,
|
|
5651
|
+
// Only a running prompt's failure is the active turn's failure. The
|
|
5652
|
+
// `state === 'running'` gate (not `activePromptId`) is deliberate:
|
|
5653
|
+
// on the normal settle path `settleActivePromptState` runs in
|
|
5654
|
+
// `promptPromise.finally` BEFORE the terminal is published, so
|
|
5655
|
+
// `activePromptId` is already cleared when a genuine active failure
|
|
5656
|
+
// lands here.
|
|
5657
|
+
pendingEntry.state === "running"
|
|
5658
|
+
);
|
|
5659
|
+
}
|
|
5660
|
+
}
|
|
5661
|
+
__name(publishPromptTerminal, "publishPromptTerminal");
|
|
5662
|
+
function flushPromptTerminals(entry, code, message) {
|
|
5663
|
+
for (const pending of [...entry.pendingPromptList]) {
|
|
5664
|
+
publishPromptTerminal(entry, pending, {
|
|
5665
|
+
kind: "error",
|
|
5666
|
+
err: { code, message }
|
|
5667
|
+
});
|
|
5668
|
+
try {
|
|
5669
|
+
pending.abortController.abort(
|
|
5670
|
+
new DOMException("Prompt aborted", "AbortError")
|
|
5671
|
+
);
|
|
5672
|
+
} catch {
|
|
5673
|
+
}
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5676
|
+
__name(flushPromptTerminals, "flushPromptTerminals");
|
|
5402
5677
|
function hasControlCharacter2(value) {
|
|
5403
5678
|
for (let i = 0; i < value.length; i += 1) {
|
|
5404
5679
|
const code = value.charCodeAt(i);
|
|
@@ -5558,6 +5833,18 @@ function createAcpSessionBridge(opts) {
|
|
|
5558
5833
|
lastActivityTimestamp = Date.now();
|
|
5559
5834
|
}
|
|
5560
5835
|
__name(touchActivity, "touchActivity");
|
|
5836
|
+
function settleActivePromptState(entry, promptId) {
|
|
5837
|
+
if (entry.activePromptId !== promptId) return;
|
|
5838
|
+
delete entry.activePromptId;
|
|
5839
|
+
delete entry.activePromptOriginatorClientId;
|
|
5840
|
+
if (entry.promptActive) {
|
|
5841
|
+
entry.promptActive = false;
|
|
5842
|
+
activePromptCounter--;
|
|
5843
|
+
entry.sessionLastSeenAt = Date.now();
|
|
5844
|
+
touchActivity();
|
|
5845
|
+
}
|
|
5846
|
+
}
|
|
5847
|
+
__name(settleActivePromptState, "settleActivePromptState");
|
|
5561
5848
|
function resolvePositiveFiniteMs(raw, fallback) {
|
|
5562
5849
|
if (raw === void 0) return fallback;
|
|
5563
5850
|
return raw > 0 && Number.isFinite(raw) ? Math.min(raw, 2147483647) : 0;
|
|
@@ -5674,7 +5961,7 @@ function createAcpSessionBridge(opts) {
|
|
|
5674
5961
|
if (shuttingDown) return;
|
|
5675
5962
|
const now = Date.now();
|
|
5676
5963
|
for (const [id, entry] of byId) {
|
|
5677
|
-
if (entry.
|
|
5964
|
+
if (entry.pendingPromptCount > 0) continue;
|
|
5678
5965
|
if (entry.events.subscriberCount > 0) continue;
|
|
5679
5966
|
const lastActive = entry.sessionLastSeenAt ?? Date.parse(entry.createdAt);
|
|
5680
5967
|
const idle = now - lastActive;
|
|
@@ -5704,7 +5991,54 @@ function createAcpSessionBridge(opts) {
|
|
|
5704
5991
|
const aliveChannels = /* @__PURE__ */ new Set();
|
|
5705
5992
|
let inFlightChannelSpawn;
|
|
5706
5993
|
const byId = /* @__PURE__ */ new Map();
|
|
5994
|
+
const forwardRunningPromptCancel = /* @__PURE__ */ __name(async (entry, pending, notification) => {
|
|
5995
|
+
if (pending.cancelForwardInitial) {
|
|
5996
|
+
return pending.cancelForwardInitial;
|
|
5997
|
+
}
|
|
5998
|
+
const initial = (async () => {
|
|
5999
|
+
try {
|
|
6000
|
+
const extension = entry.connection.extMethod(PROMPT_CANCEL_METHOD, notification).then((result2) => ({ kind: "result", result: result2 }));
|
|
6001
|
+
const outcome = await Promise.race([
|
|
6002
|
+
extension,
|
|
6003
|
+
getTransportClosedReject(entry),
|
|
6004
|
+
...pending.cancelForwardDeadline ? [
|
|
6005
|
+
pending.cancelForwardDeadline.then(() => ({
|
|
6006
|
+
kind: "deadline"
|
|
6007
|
+
}))
|
|
6008
|
+
] : []
|
|
6009
|
+
]);
|
|
6010
|
+
if (outcome.kind === "deadline") return;
|
|
6011
|
+
const { result } = outcome;
|
|
6012
|
+
if (typeof result["cancelled"] !== "boolean") {
|
|
6013
|
+
throw new Error(
|
|
6014
|
+
`${PROMPT_CANCEL_METHOD} returned an invalid acknowledgement`
|
|
6015
|
+
);
|
|
6016
|
+
}
|
|
6017
|
+
} catch (error) {
|
|
6018
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === -32601 || isNotCurrentlyGeneratingCancelError(error)) {
|
|
6019
|
+
await Promise.race([
|
|
6020
|
+
entry.connection.cancel(notification),
|
|
6021
|
+
getTransportClosedReject(entry),
|
|
6022
|
+
...pending.cancelForwardDeadline ? [pending.cancelForwardDeadline] : []
|
|
6023
|
+
]);
|
|
6024
|
+
return;
|
|
6025
|
+
}
|
|
6026
|
+
throw error;
|
|
6027
|
+
}
|
|
6028
|
+
})().catch((error) => {
|
|
6029
|
+
if (pending.cancelForwardInitial === initial) {
|
|
6030
|
+
delete pending.cancelForwardInitial;
|
|
6031
|
+
}
|
|
6032
|
+
throw error;
|
|
6033
|
+
});
|
|
6034
|
+
pending.cancelForwardInitial = initial;
|
|
6035
|
+
pending.cancelForwardDrain = initial;
|
|
6036
|
+
void initial.catch(() => {
|
|
6037
|
+
});
|
|
6038
|
+
return initial;
|
|
6039
|
+
}, "forwardRunningPromptCancel");
|
|
5707
6040
|
const generationRequests = /* @__PURE__ */ new Map();
|
|
6041
|
+
const workspaceGenerationRequests = /* @__PURE__ */ new Map();
|
|
5708
6042
|
const inFlightExtensionRefreshes = /* @__PURE__ */ new Map();
|
|
5709
6043
|
const toSessionSummary = /* @__PURE__ */ __name((entry) => {
|
|
5710
6044
|
let isWaitingForPermission = false;
|
|
@@ -5731,7 +6065,8 @@ function createAcpSessionBridge(opts) {
|
|
|
5731
6065
|
pendingInteractionCount: entry.pendingInteractions.size,
|
|
5732
6066
|
hasTurnError: entry.turnError !== void 0,
|
|
5733
6067
|
...entry.turnError !== void 0 ? { turnError: entry.turnError } : {},
|
|
5734
|
-
pendingInteractions: [...entry.pendingInteractions.values()]
|
|
6068
|
+
pendingInteractions: [...entry.pendingInteractions.values()],
|
|
6069
|
+
...entry.worktree ? { worktree: entry.worktree } : {}
|
|
5735
6070
|
};
|
|
5736
6071
|
}, "toSessionSummary");
|
|
5737
6072
|
const permissionConsensusQuorum = opts.permissionConsensusQuorum;
|
|
@@ -5793,13 +6128,30 @@ function createAcpSessionBridge(opts) {
|
|
|
5793
6128
|
entry.clientIds.set(clientId, count - 1);
|
|
5794
6129
|
}
|
|
5795
6130
|
}, "unregisterClient");
|
|
6131
|
+
const recordAttachRef = /* @__PURE__ */ __name((entry, clientId) => {
|
|
6132
|
+
entry.attachRefs.set(clientId, (entry.attachRefs.get(clientId) ?? 0) + 1);
|
|
6133
|
+
}, "recordAttachRef");
|
|
6134
|
+
const releaseAttachRef = /* @__PURE__ */ __name((entry, clientId) => {
|
|
6135
|
+
const refs = entry.attachRefs.get(clientId);
|
|
6136
|
+
if (refs === void 0 || refs <= 0) return false;
|
|
6137
|
+
if (refs === 1) {
|
|
6138
|
+
entry.attachRefs.delete(clientId);
|
|
6139
|
+
} else {
|
|
6140
|
+
entry.attachRefs.set(clientId, refs - 1);
|
|
6141
|
+
}
|
|
6142
|
+
return true;
|
|
6143
|
+
}, "releaseAttachRef");
|
|
5796
6144
|
const rollbackAttachRegistration = /* @__PURE__ */ __name(async (entry, clientId, attachCountDelta = 1) => {
|
|
5797
|
-
|
|
6145
|
+
const released = releaseAttachRef(entry, clientId) ? 1 : 0;
|
|
6146
|
+
entry.attachCount = Math.max(
|
|
6147
|
+
0,
|
|
6148
|
+
entry.attachCount - (released + (attachCountDelta - 1))
|
|
6149
|
+
);
|
|
5798
6150
|
unregisterClient(entry, clientId);
|
|
5799
6151
|
if (entry.spawnOwnerWantedKill && entry.attachCount === 0 && entry.events.subscriberCount === 0) {
|
|
5800
6152
|
await bridgeApi.killSession(entry.sessionId).catch(() => {
|
|
5801
6153
|
});
|
|
5802
|
-
} else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 &&
|
|
6154
|
+
} else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && entry.pendingPromptCount === 0) {
|
|
5803
6155
|
await closeSessionImpl(entry.sessionId, void 0, {
|
|
5804
6156
|
reason: "last_client_detached"
|
|
5805
6157
|
}).catch((err) => {
|
|
@@ -5821,6 +6173,7 @@ function createAcpSessionBridge(opts) {
|
|
|
5821
6173
|
if (channelInfo && !channelInfo.isDying) return channelInfo;
|
|
5822
6174
|
if (inFlightChannelSpawn) return await inFlightChannelSpawn;
|
|
5823
6175
|
const promise = (async () => {
|
|
6176
|
+
const privateParentCapability = randomBytes(32).toString("base64url");
|
|
5824
6177
|
const acpChannelId = randomUUID2();
|
|
5825
6178
|
const channel = await telemetry.withSpan(
|
|
5826
6179
|
"channel.spawn",
|
|
@@ -5829,7 +6182,10 @@ function createAcpSessionBridge(opts) {
|
|
|
5829
6182
|
"qwen-code.daemon.channel.reused": false,
|
|
5830
6183
|
"qwen-code.daemon.acp_channel.id": acpChannelId
|
|
5831
6184
|
},
|
|
5832
|
-
async () => await channelFactory(boundWorkspace,
|
|
6185
|
+
async () => await channelFactory(boundWorkspace, {
|
|
6186
|
+
...childEnvOverrides,
|
|
6187
|
+
[PRIVATE_ACP_CAPABILITY_ENV]: privateParentCapability
|
|
6188
|
+
})
|
|
5833
6189
|
);
|
|
5834
6190
|
const sessionIds = /* @__PURE__ */ new Set();
|
|
5835
6191
|
const client = new BridgeClient(
|
|
@@ -5909,7 +6265,19 @@ function createAcpSessionBridge(opts) {
|
|
|
5909
6265
|
sessionId,
|
|
5910
6266
|
requestId: event.requestId
|
|
5911
6267
|
}).catch(() => void 0);
|
|
5912
|
-
}
|
|
6268
|
+
},
|
|
6269
|
+
(event) => {
|
|
6270
|
+
const request = workspaceGenerationRequests.get(event.requestId);
|
|
6271
|
+
if (!request) return;
|
|
6272
|
+
if (request.queue.push(event)) return;
|
|
6273
|
+
request.settled = true;
|
|
6274
|
+
workspaceGenerationRequests.delete(event.requestId);
|
|
6275
|
+
request.queue.fail(new Error("Generation stream consumer too slow"));
|
|
6276
|
+
void request.connection?.extMethod(SERVE_CONTROL_EXT_METHODS.workspaceGenerationCancel, {
|
|
6277
|
+
requestId: event.requestId
|
|
6278
|
+
}).catch(() => void 0);
|
|
6279
|
+
},
|
|
6280
|
+
opts.onChannelDelivery
|
|
5913
6281
|
);
|
|
5914
6282
|
const connection = new ClientSideConnection(() => client, channel.stream);
|
|
5915
6283
|
const info = {
|
|
@@ -5968,6 +6336,11 @@ function createAcpSessionBridge(opts) {
|
|
|
5968
6336
|
const sessEntry = byId.get(sid);
|
|
5969
6337
|
if (!sessEntry) continue;
|
|
5970
6338
|
cancelPendingForSession(sid);
|
|
6339
|
+
flushPromptTerminals(
|
|
6340
|
+
sessEntry,
|
|
6341
|
+
"channel_closed",
|
|
6342
|
+
"agent channel exited before the prompt completed"
|
|
6343
|
+
);
|
|
5971
6344
|
try {
|
|
5972
6345
|
sessEntry.events.publish({
|
|
5973
6346
|
type: "session_died",
|
|
@@ -6013,7 +6386,8 @@ function createAcpSessionBridge(opts) {
|
|
|
6013
6386
|
_meta: {
|
|
6014
6387
|
[CHANNEL_STARTUP_PROFILE_META_KEY]: {
|
|
6015
6388
|
v: CHANNEL_STARTUP_PROFILE_VERSION
|
|
6016
|
-
}
|
|
6389
|
+
},
|
|
6390
|
+
[PRIVATE_PARENT_CAPABILITY_META_KEY]: privateParentCapability
|
|
6017
6391
|
},
|
|
6018
6392
|
clientCapabilities: {
|
|
6019
6393
|
fs: { readTextFile: true, writeTextFile: true }
|
|
@@ -6062,7 +6436,7 @@ function createAcpSessionBridge(opts) {
|
|
|
6062
6436
|
}
|
|
6063
6437
|
}
|
|
6064
6438
|
__name(ensureChannel, "ensureChannel");
|
|
6065
|
-
async function doSpawn(modelServiceId, effectiveScope, approvalMode, requestedClientId, onSessionRegistered, parentSessionId, sourceType, sourceId) {
|
|
6439
|
+
async function doSpawn(modelServiceId, effectiveScope, approvalMode, requestedClientId, onSessionRegistered, parentSessionId, sourceType, sourceId, worktree) {
|
|
6066
6440
|
const channelPath = channelInfo && !channelInfo.isDying ? "reused" : inFlightChannelSpawn ? "joined" : "spawned_on_request";
|
|
6067
6441
|
const ci = await telemetry.withSpan(
|
|
6068
6442
|
"channel.wait",
|
|
@@ -6123,7 +6497,7 @@ function createAcpSessionBridge(opts) {
|
|
|
6123
6497
|
newSessionResp.sessionId,
|
|
6124
6498
|
boundWorkspace,
|
|
6125
6499
|
void 0,
|
|
6126
|
-
{ parentSessionId, sourceType, sourceId }
|
|
6500
|
+
{ parentSessionId, sourceType, sourceId, worktree }
|
|
6127
6501
|
);
|
|
6128
6502
|
initializedSessionId = entry.sessionId;
|
|
6129
6503
|
sessionRegistered = true;
|
|
@@ -6237,7 +6611,8 @@ function createAcpSessionBridge(opts) {
|
|
|
6237
6611
|
...entry.sourceType ? { sourceType: entry.sourceType } : {},
|
|
6238
6612
|
...entry.sourceId !== void 0 ? { sourceId: entry.sourceId } : {},
|
|
6239
6613
|
...entry.sourceType ? { sourcePersisted: sourcePersisted === true } : {},
|
|
6240
|
-
...entry.parentSessionId ? { parentSessionPersisted: parentSessionPersisted === true } : {}
|
|
6614
|
+
...entry.parentSessionId ? { parentSessionPersisted: parentSessionPersisted === true } : {},
|
|
6615
|
+
...entry.worktree ? { worktree: entry.worktree } : {}
|
|
6241
6616
|
};
|
|
6242
6617
|
} finally {
|
|
6243
6618
|
ci.sessionSpawnsInFlight = Math.max(0, ci.sessionSpawnsInFlight - 1);
|
|
@@ -6447,10 +6822,11 @@ function createAcpSessionBridge(opts) {
|
|
|
6447
6822
|
}
|
|
6448
6823
|
return entry.transportClosedReject;
|
|
6449
6824
|
}, "getTransportClosedReject");
|
|
6450
|
-
const resolveWorkspaceKey = /* @__PURE__ */ __name((
|
|
6451
|
-
|
|
6825
|
+
const resolveWorkspaceKey = /* @__PURE__ */ __name((rawWorkspaceCwd) => {
|
|
6826
|
+
const workspaceCwd = translateAndCheckAbsoluteWorkspacePath(rawWorkspaceCwd);
|
|
6827
|
+
if (workspaceCwd === null) {
|
|
6452
6828
|
throw new Error(
|
|
6453
|
-
`workspaceCwd must be an absolute path; got "${
|
|
6829
|
+
`workspaceCwd must be an absolute path; got "${rawWorkspaceCwd}"`
|
|
6454
6830
|
);
|
|
6455
6831
|
}
|
|
6456
6832
|
const workspaceKey = workspaceCwd === boundWorkspace ? boundWorkspace : canonicalizeWorkspace(workspaceCwd);
|
|
@@ -6689,12 +7065,18 @@ function createAcpSessionBridge(opts) {
|
|
|
6689
7065
|
return;
|
|
6690
7066
|
}
|
|
6691
7067
|
try {
|
|
7068
|
+
const closeRequest = entry.connection.extMethod(
|
|
7069
|
+
SERVE_CONTROL_EXT_METHODS.sessionClose,
|
|
7070
|
+
{
|
|
7071
|
+
sessionId: entry.sessionId,
|
|
7072
|
+
drainTimeoutMs: Math.max(1, Math.floor(initTimeoutMs * 0.8)),
|
|
7073
|
+
...opts2?.requireFlush === true ? { requireFlush: true } : {}
|
|
7074
|
+
}
|
|
7075
|
+
);
|
|
7076
|
+
const observedCloseRequest = opts2?.timeoutMs ? withTimeout(closeRequest, opts2.timeoutMs, label) : closeRequest;
|
|
6692
7077
|
await Promise.race([
|
|
6693
|
-
withTimeout(
|
|
6694
|
-
|
|
6695
|
-
sessionId: entry.sessionId,
|
|
6696
|
-
...opts2?.requireFlush === true ? { requireFlush: true } : {}
|
|
6697
|
-
}),
|
|
7078
|
+
opts2?.throwOnFailure === true ? observedCloseRequest : withTimeout(
|
|
7079
|
+
observedCloseRequest,
|
|
6698
7080
|
initTimeoutMs,
|
|
6699
7081
|
SERVE_CONTROL_EXT_METHODS.sessionClose
|
|
6700
7082
|
),
|
|
@@ -6748,7 +7130,7 @@ function createAcpSessionBridge(opts) {
|
|
|
6748
7130
|
);
|
|
6749
7131
|
}
|
|
6750
7132
|
}, "broadcastWorkspaceEvent");
|
|
6751
|
-
const createSessionEventBus = /* @__PURE__ */ __name(() => new EventBus(
|
|
7133
|
+
const createSessionEventBus = /* @__PURE__ */ __name((sessionId) => new EventBus(
|
|
6752
7134
|
eventRingSize,
|
|
6753
7135
|
void 0,
|
|
6754
7136
|
new TurnBoundaryCompactionEngine({
|
|
@@ -6758,7 +7140,17 @@ function createAcpSessionBridge(opts) {
|
|
|
6758
7140
|
`replay window evicted ${JSON.stringify(eviction)}`
|
|
6759
7141
|
);
|
|
6760
7142
|
}, "onReplayWindowEviction")
|
|
6761
|
-
})
|
|
7143
|
+
}),
|
|
7144
|
+
{
|
|
7145
|
+
// Fired once, on the FIRST ingest/seed failure (the bus keeps the
|
|
7146
|
+
// degraded flag set silently afterwards). The bus doesn't know its
|
|
7147
|
+
// session, so the sessionId context is injected here.
|
|
7148
|
+
onCompactionError: /* @__PURE__ */ __name((err) => {
|
|
7149
|
+
writeStderrLine(
|
|
7150
|
+
`qwen serve: compaction degraded for session=${sessionId}; replay snapshot may lag behind live events: ${err instanceof Error ? err.message : String(err)}`
|
|
7151
|
+
);
|
|
7152
|
+
}, "onCompactionError")
|
|
7153
|
+
}
|
|
6762
7154
|
), "createSessionEventBus");
|
|
6763
7155
|
const publishModelSwitched = /* @__PURE__ */ __name((entry, modelId, originatorClientId) => {
|
|
6764
7156
|
entry.currentModelId = modelId;
|
|
@@ -6842,7 +7234,7 @@ function createAcpSessionBridge(opts) {
|
|
|
6842
7234
|
if (rerun) void reconcileAfterRoundtrip(entry, target);
|
|
6843
7235
|
}
|
|
6844
7236
|
}, "reconcileAfterRoundtrip");
|
|
6845
|
-
const createSessionEntry = /* @__PURE__ */ __name((ci, sessionId, workspaceCwd, events = createSessionEventBus(), options = {}) => {
|
|
7237
|
+
const createSessionEntry = /* @__PURE__ */ __name((ci, sessionId, workspaceCwd, events = createSessionEventBus(sessionId), options = {}) => {
|
|
6846
7238
|
const entry = {
|
|
6847
7239
|
sessionId,
|
|
6848
7240
|
workspaceCwd,
|
|
@@ -6850,6 +7242,7 @@ function createAcpSessionBridge(opts) {
|
|
|
6850
7242
|
...options.parentSessionId ? { parentSessionId: options.parentSessionId } : {},
|
|
6851
7243
|
...options.sourceType ? { sourceType: options.sourceType } : {},
|
|
6852
7244
|
...options.sourceId !== void 0 ? { sourceId: options.sourceId } : {},
|
|
7245
|
+
...options.worktree ? { worktree: options.worktree } : {},
|
|
6853
7246
|
channel: ci.channel,
|
|
6854
7247
|
connection: ci.connection,
|
|
6855
7248
|
events,
|
|
@@ -6859,6 +7252,7 @@ function createAcpSessionBridge(opts) {
|
|
|
6859
7252
|
persistence: createSessionArtifactPersistence(ci.connection, sessionId)
|
|
6860
7253
|
}),
|
|
6861
7254
|
recordingDegraded: false,
|
|
7255
|
+
closing: false,
|
|
6862
7256
|
promptQueue: Promise.resolve(),
|
|
6863
7257
|
pendingPromptCount: 0,
|
|
6864
7258
|
pendingPromptList: [],
|
|
@@ -6872,6 +7266,7 @@ function createAcpSessionBridge(opts) {
|
|
|
6872
7266
|
clientIds: /* @__PURE__ */ new Map(),
|
|
6873
7267
|
clientLastSeenAt: /* @__PURE__ */ new Map(),
|
|
6874
7268
|
attachCount: 0,
|
|
7269
|
+
attachRefs: /* @__PURE__ */ new Map(),
|
|
6875
7270
|
spawnOwnerWantedKill: false,
|
|
6876
7271
|
promptActive: false,
|
|
6877
7272
|
retryAllowed: false
|
|
@@ -7015,20 +7410,27 @@ function createAcpSessionBridge(opts) {
|
|
|
7015
7410
|
partial: true,
|
|
7016
7411
|
...typeof entry.restoreReplayError === "string" ? { replayError: entry.restoreReplayError } : {}
|
|
7017
7412
|
} : {};
|
|
7413
|
+
const eventEpoch = entry.events.epoch;
|
|
7018
7414
|
const snapshot = entry.events.snapshotReplay();
|
|
7019
7415
|
if (!snapshot) {
|
|
7020
|
-
return {
|
|
7416
|
+
return {
|
|
7417
|
+
lastEventId: entry.events.lastEventId,
|
|
7418
|
+
eventEpoch,
|
|
7419
|
+
...replayStatus
|
|
7420
|
+
};
|
|
7021
7421
|
}
|
|
7022
7422
|
if (action === "load") {
|
|
7023
7423
|
return {
|
|
7024
7424
|
compactedReplay: snapshot.compactedTurns,
|
|
7025
7425
|
liveJournal: snapshot.liveJournal,
|
|
7026
7426
|
lastEventId: snapshot.lastEventId,
|
|
7427
|
+
eventEpoch,
|
|
7027
7428
|
...replayStatus,
|
|
7429
|
+
...snapshot.degraded ? { replayDegraded: true } : {},
|
|
7028
7430
|
...entry.restoreHistoryHasMore === true ? { historyHasMore: true } : {}
|
|
7029
7431
|
};
|
|
7030
7432
|
}
|
|
7031
|
-
return { lastEventId: snapshot.lastEventId, ...replayStatus };
|
|
7433
|
+
return { lastEventId: snapshot.lastEventId, eventEpoch, ...replayStatus };
|
|
7032
7434
|
}, "replayFieldsFor");
|
|
7033
7435
|
const restoredArtifactSnapshotFromState = /* @__PURE__ */ __name((state) => {
|
|
7034
7436
|
const candidate = state.artifactSnapshot;
|
|
@@ -7061,6 +7463,62 @@ function createAcpSessionBridge(opts) {
|
|
|
7061
7463
|
} = state;
|
|
7062
7464
|
return publicState;
|
|
7063
7465
|
}, "publicRestoreState");
|
|
7466
|
+
async function requestSessionTranscriptPage(req) {
|
|
7467
|
+
const info = await ensureChannel();
|
|
7468
|
+
try {
|
|
7469
|
+
const response = await withWorkspaceControl(
|
|
7470
|
+
info,
|
|
7471
|
+
() => withTimeout(
|
|
7472
|
+
Promise.race([
|
|
7473
|
+
info.connection.extMethod(
|
|
7474
|
+
SERVE_STATUS_EXT_METHODS.sessionTranscript,
|
|
7475
|
+
{ ...req, cwd: boundWorkspace }
|
|
7476
|
+
),
|
|
7477
|
+
getChannelClosedReject(info)
|
|
7478
|
+
]),
|
|
7479
|
+
Math.max(initTimeoutMs, SESSION_TRANSCRIPT_TIMEOUT_MS),
|
|
7480
|
+
SERVE_STATUS_EXT_METHODS.sessionTranscript
|
|
7481
|
+
)
|
|
7482
|
+
);
|
|
7483
|
+
return response;
|
|
7484
|
+
} catch (err) {
|
|
7485
|
+
if (isAcpSessionResourceNotFound(err, req.sessionId)) {
|
|
7486
|
+
throw new SessionNotFoundError(req.sessionId);
|
|
7487
|
+
}
|
|
7488
|
+
throw err;
|
|
7489
|
+
} finally {
|
|
7490
|
+
if (hasNoChannelWork(info)) {
|
|
7491
|
+
await startIdleTimer(info, "session transcript");
|
|
7492
|
+
}
|
|
7493
|
+
}
|
|
7494
|
+
}
|
|
7495
|
+
__name(requestSessionTranscriptPage, "requestSessionTranscriptPage");
|
|
7496
|
+
async function refreshedReplayFieldsFor(entry, historyPageSize) {
|
|
7497
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
7498
|
+
try {
|
|
7499
|
+
const lastEventId = entry.events.lastEventId;
|
|
7500
|
+
const page = await requestSessionTranscriptPage({
|
|
7501
|
+
sessionId: entry.sessionId,
|
|
7502
|
+
direction: "backward",
|
|
7503
|
+
limit: historyPageSize
|
|
7504
|
+
});
|
|
7505
|
+
if (byId.get(entry.sessionId) === entry && !entry.promptActive && entry.events.lastEventId === lastEventId) {
|
|
7506
|
+
return {
|
|
7507
|
+
compactedReplay: page.events,
|
|
7508
|
+
liveJournal: [],
|
|
7509
|
+
lastEventId,
|
|
7510
|
+
...page.partial === true ? { partial: true } : {},
|
|
7511
|
+
...page.replayError !== void 0 ? { replayError: page.replayError } : {},
|
|
7512
|
+
...page.hasMore ? { historyHasMore: true } : {}
|
|
7513
|
+
};
|
|
7514
|
+
}
|
|
7515
|
+
} catch {
|
|
7516
|
+
break;
|
|
7517
|
+
}
|
|
7518
|
+
}
|
|
7519
|
+
return replayFieldsFor(entry, "load");
|
|
7520
|
+
}
|
|
7521
|
+
__name(refreshedReplayFieldsFor, "refreshedReplayFieldsFor");
|
|
7064
7522
|
async function restoreSession(action, req, options = {}) {
|
|
7065
7523
|
if (shuttingDown) {
|
|
7066
7524
|
throw new Error("AcpSessionBridge is shutting down");
|
|
@@ -7074,8 +7532,19 @@ function createAcpSessionBridge(opts) {
|
|
|
7074
7532
|
const historyReplay = action === "load" ? req.historyReplay ?? "stream" : "stream";
|
|
7075
7533
|
const existing = byId.get(req.sessionId);
|
|
7076
7534
|
if (existing) {
|
|
7535
|
+
if (existing.closing) {
|
|
7536
|
+
throw new SessionNotFoundError(
|
|
7537
|
+
req.sessionId,
|
|
7538
|
+
"The session is closing; retry after close completes"
|
|
7539
|
+
);
|
|
7540
|
+
}
|
|
7541
|
+
const replayFields = action === "load" && req.historyPageSize !== void 0 ? await refreshedReplayFieldsFor(existing, req.historyPageSize) : replayFieldsFor(existing, action);
|
|
7542
|
+
if (byId.get(req.sessionId) !== existing || existing.closing) {
|
|
7543
|
+
throw new SessionNotFoundError(req.sessionId);
|
|
7544
|
+
}
|
|
7077
7545
|
existing.attachCount++;
|
|
7078
7546
|
const clientId = registerClient(existing, req.clientId);
|
|
7547
|
+
recordAttachRef(existing, clientId);
|
|
7079
7548
|
if (req.approvalMode) {
|
|
7080
7549
|
await applyApprovalModeForAttach(existing, req.approvalMode, clientId);
|
|
7081
7550
|
}
|
|
@@ -7091,7 +7560,7 @@ function createAcpSessionBridge(opts) {
|
|
|
7091
7560
|
// caller saw; spawn-only sessions don't carry a state payload.
|
|
7092
7561
|
state: existing.restoreState ?? {},
|
|
7093
7562
|
hasActivePrompt: existing.promptActive,
|
|
7094
|
-
...
|
|
7563
|
+
...replayFields
|
|
7095
7564
|
};
|
|
7096
7565
|
}
|
|
7097
7566
|
const inFlight = inFlightRestores.get(req.sessionId);
|
|
@@ -7120,6 +7589,7 @@ function createAcpSessionBridge(opts) {
|
|
|
7120
7589
|
);
|
|
7121
7590
|
}
|
|
7122
7591
|
const clientId = registerClient(entry, req.clientId);
|
|
7592
|
+
recordAttachRef(entry, clientId);
|
|
7123
7593
|
if (req.approvalMode) {
|
|
7124
7594
|
await applyApprovalModeForAttach(entry, req.approvalMode, clientId);
|
|
7125
7595
|
}
|
|
@@ -7134,7 +7604,7 @@ function createAcpSessionBridge(opts) {
|
|
|
7134
7604
|
if (byId.size + inFlightSpawns.size + inFlightRestores.size >= maxSessions) {
|
|
7135
7605
|
throw new SessionLimitExceededError(maxSessions);
|
|
7136
7606
|
}
|
|
7137
|
-
const restoreEvents = createSessionEventBus();
|
|
7607
|
+
const restoreEvents = createSessionEventBus(req.sessionId);
|
|
7138
7608
|
let registeredEntry;
|
|
7139
7609
|
let ci;
|
|
7140
7610
|
const coalesceState = { count: 0 };
|
|
@@ -7241,6 +7711,7 @@ function createAcpSessionBridge(opts) {
|
|
|
7241
7711
|
restoreEvents.close();
|
|
7242
7712
|
racedEntry.attachCount += 1 + coalesceState.count;
|
|
7243
7713
|
const clientId2 = registerClient(racedEntry, req.clientId);
|
|
7714
|
+
recordAttachRef(racedEntry, clientId2);
|
|
7244
7715
|
if (req.approvalMode) {
|
|
7245
7716
|
try {
|
|
7246
7717
|
await applyApprovalMode(
|
|
@@ -7387,10 +7858,17 @@ function createAcpSessionBridge(opts) {
|
|
|
7387
7858
|
async function closeSessionImpl(sessionId, context, closeOpts) {
|
|
7388
7859
|
const entry = byId.get(sessionId);
|
|
7389
7860
|
if (!entry) throw new SessionNotFoundError(sessionId);
|
|
7861
|
+
if (entry.closing) {
|
|
7862
|
+
throw new SessionNotFoundError(
|
|
7863
|
+
sessionId,
|
|
7864
|
+
"The session is already closing"
|
|
7865
|
+
);
|
|
7866
|
+
}
|
|
7390
7867
|
let originatorClientId;
|
|
7391
7868
|
if (context?.clientId !== void 0) {
|
|
7392
7869
|
originatorClientId = resolveTrustedClientId(entry, context.clientId);
|
|
7393
7870
|
}
|
|
7871
|
+
entry.closing = true;
|
|
7394
7872
|
const reason = closeOpts?.reason ?? "client_close";
|
|
7395
7873
|
writeStderrLine(
|
|
7396
7874
|
`qwen serve: closing session ${JSON.stringify(sessionId)} (reason: ${reason})` + (originatorClientId ? ` by client ${JSON.stringify(originatorClientId)}` : "")
|
|
@@ -7400,26 +7878,37 @@ function createAcpSessionBridge(opts) {
|
|
|
7400
7878
|
"session.id": sessionId,
|
|
7401
7879
|
"session.close.reason": reason
|
|
7402
7880
|
});
|
|
7403
|
-
if (defaultEntry === entry) defaultEntry = void 0;
|
|
7404
7881
|
const ci = channelInfoForEntry(entry);
|
|
7405
7882
|
if (!ci) {
|
|
7406
7883
|
writeStderrLine(
|
|
7407
7884
|
`qwen serve: closeSession channelInfoForEntry returned undefined for session ${JSON.stringify(sessionId)} \u2014 channel cleanup skipped (entry's channel already torn down)`
|
|
7408
7885
|
);
|
|
7409
7886
|
}
|
|
7410
|
-
|
|
7411
|
-
|
|
7887
|
+
try {
|
|
7888
|
+
permissionMediator.forgetSession(sessionId);
|
|
7889
|
+
entry.pendingPermissionIds.clear();
|
|
7890
|
+
entry.pendingInteractions.clear();
|
|
7412
7891
|
await notifyAgentSessionClose(entry, ci, "closeSession", {
|
|
7413
7892
|
throwOnFailure: true,
|
|
7414
|
-
requireFlush: true
|
|
7893
|
+
requireFlush: closeOpts?.requireAgentClose === true
|
|
7415
7894
|
});
|
|
7895
|
+
} catch (error) {
|
|
7896
|
+
if (isDefinitiveAcpRequestError(error)) {
|
|
7897
|
+
entry.closing = false;
|
|
7898
|
+
} else if (ci) {
|
|
7899
|
+
await killChannelWithLog(
|
|
7900
|
+
ci,
|
|
7901
|
+
`recover unknown close outcome for session ${JSON.stringify(sessionId)}`
|
|
7902
|
+
);
|
|
7903
|
+
} else {
|
|
7904
|
+
entry.closing = false;
|
|
7905
|
+
}
|
|
7906
|
+
throw error;
|
|
7416
7907
|
}
|
|
7908
|
+
if (defaultEntry === entry) defaultEntry = void 0;
|
|
7417
7909
|
if (ci && ci.channel === entry.channel) {
|
|
7418
7910
|
ci.sessionIds.delete(sessionId);
|
|
7419
7911
|
}
|
|
7420
|
-
permissionMediator.forgetSession(sessionId);
|
|
7421
|
-
entry.pendingPermissionIds.clear();
|
|
7422
|
-
entry.pendingInteractions.clear();
|
|
7423
7912
|
if (entry.promptActive) {
|
|
7424
7913
|
entry.promptActive = false;
|
|
7425
7914
|
activePromptCounter--;
|
|
@@ -7434,6 +7923,11 @@ function createAcpSessionBridge(opts) {
|
|
|
7434
7923
|
reason
|
|
7435
7924
|
});
|
|
7436
7925
|
ci?.client.markSessionClosed(sessionId);
|
|
7926
|
+
flushPromptTerminals(
|
|
7927
|
+
entry,
|
|
7928
|
+
"session_closed",
|
|
7929
|
+
"session closed before the prompt completed"
|
|
7930
|
+
);
|
|
7437
7931
|
try {
|
|
7438
7932
|
entry.events.publish({
|
|
7439
7933
|
type: "session_closed",
|
|
@@ -7451,9 +7945,6 @@ function createAcpSessionBridge(opts) {
|
|
|
7451
7945
|
} catch {
|
|
7452
7946
|
}
|
|
7453
7947
|
entry.events.close();
|
|
7454
|
-
if (!requireAgentClose) {
|
|
7455
|
-
await notifyAgentSessionClose(entry, ci, "closeSession");
|
|
7456
|
-
}
|
|
7457
7948
|
try {
|
|
7458
7949
|
await telemetry.withSpan(
|
|
7459
7950
|
"session.close.cancel_active_prompt",
|
|
@@ -7568,8 +8059,15 @@ function createAcpSessionBridge(opts) {
|
|
|
7568
8059
|
if (effectiveScope === "single") {
|
|
7569
8060
|
const existing = defaultEntry;
|
|
7570
8061
|
if (existing) {
|
|
8062
|
+
if (existing.closing) {
|
|
8063
|
+
throw new SessionNotFoundError(
|
|
8064
|
+
existing.sessionId,
|
|
8065
|
+
"The session is closing; retry after close completes"
|
|
8066
|
+
);
|
|
8067
|
+
}
|
|
7571
8068
|
existing.attachCount++;
|
|
7572
8069
|
const clientId = registerClient(existing, req.clientId);
|
|
8070
|
+
recordAttachRef(existing, clientId);
|
|
7573
8071
|
if (req.modelServiceId) {
|
|
7574
8072
|
await applyModelServiceId(
|
|
7575
8073
|
existing,
|
|
@@ -7609,6 +8107,7 @@ function createAcpSessionBridge(opts) {
|
|
|
7609
8107
|
);
|
|
7610
8108
|
}
|
|
7611
8109
|
const clientId = registerClient(attachedEntry, req.clientId);
|
|
8110
|
+
recordAttachRef(attachedEntry, clientId);
|
|
7612
8111
|
if (req.modelServiceId) {
|
|
7613
8112
|
await applyModelServiceId(
|
|
7614
8113
|
attachedEntry,
|
|
@@ -7654,7 +8153,8 @@ function createAcpSessionBridge(opts) {
|
|
|
7654
8153
|
releaseAdmissionOnce,
|
|
7655
8154
|
req.parentSessionId,
|
|
7656
8155
|
source.sourceType,
|
|
7657
|
-
source.sourceId
|
|
8156
|
+
source.sourceId,
|
|
8157
|
+
req.worktree
|
|
7658
8158
|
);
|
|
7659
8159
|
const tracker = effectiveScope === "single" ? workspaceKey : `${workspaceKey}#${randomUUID2()}`;
|
|
7660
8160
|
inFlightSpawns.set(tracker, promise);
|
|
@@ -7676,6 +8176,14 @@ function createAcpSessionBridge(opts) {
|
|
|
7676
8176
|
const queuedAt = Date.now();
|
|
7677
8177
|
const entry = byId.get(sessionId);
|
|
7678
8178
|
if (!entry) return Promise.reject(new SessionNotFoundError(sessionId));
|
|
8179
|
+
if (entry.closing) {
|
|
8180
|
+
return Promise.reject(
|
|
8181
|
+
new SessionNotFoundError(
|
|
8182
|
+
sessionId,
|
|
8183
|
+
"The session is closing; retry after close completes"
|
|
8184
|
+
)
|
|
8185
|
+
);
|
|
8186
|
+
}
|
|
7679
8187
|
const originatorClientId = resolveTrustedClientId(
|
|
7680
8188
|
entry,
|
|
7681
8189
|
context?.clientId
|
|
@@ -7698,6 +8206,12 @@ function createAcpSessionBridge(opts) {
|
|
|
7698
8206
|
entry.pendingPromptCount = Math.max(0, entry.pendingPromptCount - 1);
|
|
7699
8207
|
}, "releasePromptSlot");
|
|
7700
8208
|
const promptId = context?.promptId ?? randomUUID2();
|
|
8209
|
+
const invocationContext = Object.freeze({
|
|
8210
|
+
version: 1,
|
|
8211
|
+
sessionId,
|
|
8212
|
+
promptId,
|
|
8213
|
+
...originatorClientId ? { originatorClientId } : {}
|
|
8214
|
+
});
|
|
7701
8215
|
const isQueued = entry.pendingPromptCount > 1;
|
|
7702
8216
|
const pendingAbort = new AbortController();
|
|
7703
8217
|
if (signal) {
|
|
@@ -7720,6 +8234,41 @@ function createAcpSessionBridge(opts) {
|
|
|
7720
8234
|
state: isQueued ? "queued" : "running"
|
|
7721
8235
|
};
|
|
7722
8236
|
entry.pendingPromptList.push(pendingEntry);
|
|
8237
|
+
const deadlineMs = context?.deadlineMs;
|
|
8238
|
+
const hasDeadline = typeof deadlineMs === "number" && Number.isFinite(deadlineMs) && deadlineMs > 0;
|
|
8239
|
+
let deadlineReject;
|
|
8240
|
+
let deadlinePromise;
|
|
8241
|
+
let deadlineTimer;
|
|
8242
|
+
if (hasDeadline) {
|
|
8243
|
+
deadlinePromise = new Promise((_resolve, reject) => {
|
|
8244
|
+
deadlineReject = reject;
|
|
8245
|
+
});
|
|
8246
|
+
deadlinePromise.catch(() => {
|
|
8247
|
+
});
|
|
8248
|
+
pendingEntry.cancelForwardDeadline = deadlinePromise.then(
|
|
8249
|
+
() => void 0,
|
|
8250
|
+
() => void 0
|
|
8251
|
+
);
|
|
8252
|
+
const onDeadline = /* @__PURE__ */ __name(() => {
|
|
8253
|
+
if (pendingEntry.terminalPublished) return;
|
|
8254
|
+
const deadlineErr = new PromptDeadlineExceededError(deadlineMs);
|
|
8255
|
+
writeStderrLine(
|
|
8256
|
+
`sendPrompt: prompt ${promptId} exceeded ${deadlineMs}ms deadline for session ${sessionId}; agent may still be executing`
|
|
8257
|
+
);
|
|
8258
|
+
publishPromptTerminal(entry, pendingEntry, {
|
|
8259
|
+
kind: "error",
|
|
8260
|
+
err: {
|
|
8261
|
+
code: "prompt_deadline_exceeded",
|
|
8262
|
+
message: deadlineErr.message
|
|
8263
|
+
}
|
|
8264
|
+
});
|
|
8265
|
+
settleActivePromptState(entry, pendingEntry.promptId);
|
|
8266
|
+
deadlineReject?.(deadlineErr);
|
|
8267
|
+
pendingAbort.abort(deadlineErr);
|
|
8268
|
+
}, "onDeadline");
|
|
8269
|
+
deadlineTimer = setTimeout(onDeadline, deadlineMs);
|
|
8270
|
+
deadlineTimer.unref();
|
|
8271
|
+
}
|
|
7723
8272
|
if (isQueued) {
|
|
7724
8273
|
pendingAbort.signal.addEventListener(
|
|
7725
8274
|
"abort",
|
|
@@ -7756,6 +8305,9 @@ function createAcpSessionBridge(opts) {
|
|
|
7756
8305
|
const queueWaitMs = Date.now() - queuedAt;
|
|
7757
8306
|
telemetry.metrics?.promptQueueWait(queueWaitMs);
|
|
7758
8307
|
if (pendingAbort.signal.aborted) {
|
|
8308
|
+
if (pendingAbort.signal.reason instanceof PromptDeadlineExceededError) {
|
|
8309
|
+
throw pendingAbort.signal.reason;
|
|
8310
|
+
}
|
|
7759
8311
|
throw new DOMException("Prompt aborted", "AbortError");
|
|
7760
8312
|
}
|
|
7761
8313
|
if (pendingEntry.state === "queued") {
|
|
@@ -7799,15 +8351,23 @@ function createAcpSessionBridge(opts) {
|
|
|
7799
8351
|
...normalized
|
|
7800
8352
|
};
|
|
7801
8353
|
delete copy.retry;
|
|
8354
|
+
delete copy.delivery;
|
|
7802
8355
|
const meta = copy._meta && typeof copy._meta === "object" ? { ...copy._meta } : {};
|
|
7803
8356
|
delete meta[DAEMON_RETRY_META_KEY];
|
|
8357
|
+
delete meta[INVOCATION_CONTEXT_META_KEY];
|
|
8358
|
+
delete meta[PRIVATE_PARENT_CAPABILITY_META_KEY];
|
|
7804
8359
|
delete meta[DAEMON_CONTINUE_META_KEY];
|
|
8360
|
+
delete meta[DAEMON_CHANNEL_DELIVERY_META_KEY];
|
|
7805
8361
|
if (isRetry) {
|
|
7806
8362
|
meta[DAEMON_RETRY_META_KEY] = true;
|
|
7807
8363
|
}
|
|
7808
8364
|
if (isContinue) {
|
|
7809
8365
|
meta[DAEMON_CONTINUE_META_KEY] = true;
|
|
7810
8366
|
}
|
|
8367
|
+
if (context?.channelDelivery) {
|
|
8368
|
+
meta[DAEMON_CHANNEL_DELIVERY_META_KEY] = context.channelDelivery;
|
|
8369
|
+
}
|
|
8370
|
+
meta[INVOCATION_CONTEXT_META_KEY] = invocationContext;
|
|
7811
8371
|
if (Object.keys(meta).length > 0) {
|
|
7812
8372
|
copy._meta = meta;
|
|
7813
8373
|
} else {
|
|
@@ -7827,7 +8387,6 @@ function createAcpSessionBridge(opts) {
|
|
|
7827
8387
|
entry.activePromptOriginatorClientId = originatorClientId;
|
|
7828
8388
|
}
|
|
7829
8389
|
try {
|
|
7830
|
-
entry.cancelBroadcast = false;
|
|
7831
8390
|
if (!isRetry && !isContinue) {
|
|
7832
8391
|
echoPromptToSessionBus(
|
|
7833
8392
|
entry,
|
|
@@ -7837,35 +8396,18 @@ function createAcpSessionBridge(opts) {
|
|
|
7837
8396
|
);
|
|
7838
8397
|
}
|
|
7839
8398
|
} catch (echoErr) {
|
|
7840
|
-
|
|
7841
|
-
delete entry.activePromptOriginatorClientId;
|
|
7842
|
-
if (entry.promptActive) {
|
|
7843
|
-
entry.promptActive = false;
|
|
7844
|
-
activePromptCounter--;
|
|
7845
|
-
touchActivity();
|
|
7846
|
-
}
|
|
8399
|
+
settleActivePromptState(entry, pendingEntry.promptId);
|
|
7847
8400
|
throw echoErr;
|
|
7848
8401
|
}
|
|
8402
|
+
pendingEntry.dispatched = true;
|
|
7849
8403
|
const promptPromise = entry.connection.prompt(promptRequest).finally(() => {
|
|
7850
|
-
|
|
7851
|
-
entry.promptActive = false;
|
|
7852
|
-
activePromptCounter--;
|
|
7853
|
-
entry.sessionLastSeenAt = Date.now();
|
|
7854
|
-
touchActivity();
|
|
7855
|
-
}
|
|
7856
|
-
delete entry.activePromptId;
|
|
7857
|
-
delete entry.activePromptOriginatorClientId;
|
|
7858
|
-
if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && byId.has(sessionId)) {
|
|
7859
|
-
void closeSessionImpl(sessionId, void 0, {
|
|
7860
|
-
reason: "last_client_detached"
|
|
7861
|
-
}).catch((err) => {
|
|
7862
|
-
writeStderrLine(
|
|
7863
|
-
`qwen serve: deferred close-on-prompt-complete failed for ${JSON.stringify(sessionId)}: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
|
|
7864
|
-
);
|
|
7865
|
-
});
|
|
7866
|
-
}
|
|
8404
|
+
settleActivePromptState(entry, pendingEntry.promptId);
|
|
7867
8405
|
});
|
|
7868
|
-
const racedPromise = Promise.race([
|
|
8406
|
+
const racedPromise = deadlinePromise ? Promise.race([
|
|
8407
|
+
promptPromise,
|
|
8408
|
+
getTransportClosedReject(entry),
|
|
8409
|
+
deadlinePromise
|
|
8410
|
+
]) : Promise.race([
|
|
7869
8411
|
promptPromise,
|
|
7870
8412
|
getTransportClosedReject(entry)
|
|
7871
8413
|
]);
|
|
@@ -7873,6 +8415,9 @@ function createAcpSessionBridge(opts) {
|
|
|
7873
8415
|
() => {
|
|
7874
8416
|
},
|
|
7875
8417
|
(err) => {
|
|
8418
|
+
if (err instanceof PromptDeadlineExceededError) {
|
|
8419
|
+
return;
|
|
8420
|
+
}
|
|
7876
8421
|
if (err instanceof DOMException && err.name === "AbortError" && pendingEntry.state === "queued") {
|
|
7877
8422
|
writeStderrLine(
|
|
7878
8423
|
`sendPrompt: queued prompt removed before agent forward for session ${sessionId}`
|
|
@@ -7890,11 +8435,6 @@ function createAcpSessionBridge(opts) {
|
|
|
7890
8435
|
"forward_failed"
|
|
7891
8436
|
);
|
|
7892
8437
|
cancelPendingForSession(sessionId);
|
|
7893
|
-
entry.connection.cancel({ sessionId }).catch((err2) => {
|
|
7894
|
-
writeStderrLine(
|
|
7895
|
-
`[pending-prompt] cancel forward failed after prompt abort session=${sessionId}: ${extractErrorMessage(err2)}`
|
|
7896
|
-
);
|
|
7897
|
-
});
|
|
7898
8438
|
}
|
|
7899
8439
|
).catch(() => {
|
|
7900
8440
|
});
|
|
@@ -7907,11 +8447,15 @@ function createAcpSessionBridge(opts) {
|
|
|
7907
8447
|
originatorClientId
|
|
7908
8448
|
);
|
|
7909
8449
|
cancelPendingForSession(sessionId);
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
)
|
|
7914
|
-
|
|
8450
|
+
if (byId.get(sessionId) === entry) {
|
|
8451
|
+
void forwardRunningPromptCancel(entry, pendingEntry, {
|
|
8452
|
+
sessionId
|
|
8453
|
+
}).catch((err) => {
|
|
8454
|
+
writeStderrLine(
|
|
8455
|
+
`[pending-prompt] cancel forward failed after removePendingPrompt session=${sessionId}: ${extractErrorMessage(err)}`
|
|
8456
|
+
);
|
|
8457
|
+
});
|
|
8458
|
+
}
|
|
7915
8459
|
}, "onAbort");
|
|
7916
8460
|
if (abortSignal.aborted) {
|
|
7917
8461
|
onAbort();
|
|
@@ -7935,34 +8479,35 @@ function createAcpSessionBridge(opts) {
|
|
|
7935
8479
|
);
|
|
7936
8480
|
result.then(
|
|
7937
8481
|
(promptResult) => {
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
7942
|
-
pendingEntry.promptId,
|
|
7943
|
-
originatorClientId
|
|
7944
|
-
);
|
|
8482
|
+
publishPromptTerminal(entry, pendingEntry, {
|
|
8483
|
+
kind: "complete",
|
|
8484
|
+
result: promptResult
|
|
8485
|
+
});
|
|
7945
8486
|
},
|
|
7946
8487
|
(err) => {
|
|
7947
|
-
if (err instanceof DOMException && err.name === "AbortError")
|
|
7948
|
-
|
|
7949
|
-
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
pendingEntry.promptId,
|
|
7953
|
-
originatorClientId
|
|
7954
|
-
);
|
|
8488
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
8489
|
+
publishPromptTerminal(entry, pendingEntry, { kind: "cancelled" });
|
|
8490
|
+
return;
|
|
8491
|
+
}
|
|
8492
|
+
publishPromptTerminal(entry, pendingEntry, { kind: "error", err });
|
|
7955
8493
|
}
|
|
7956
8494
|
);
|
|
8495
|
+
const drainCancelForwarding = /* @__PURE__ */ __name(async () => {
|
|
8496
|
+
try {
|
|
8497
|
+
await pendingEntry.cancelForwardDrain;
|
|
8498
|
+
} catch {
|
|
8499
|
+
}
|
|
8500
|
+
}, "drainCancelForwarding");
|
|
7957
8501
|
entry.promptQueue = result.then(
|
|
7958
|
-
|
|
7959
|
-
|
|
8502
|
+
drainCancelForwarding,
|
|
8503
|
+
drainCancelForwarding
|
|
7960
8504
|
);
|
|
7961
8505
|
result.finally(() => {
|
|
8506
|
+
if (deadlineTimer !== void 0) clearTimeout(deadlineTimer);
|
|
7962
8507
|
const listIdx = entry.pendingPromptList.indexOf(pendingEntry);
|
|
7963
8508
|
if (listIdx !== -1) {
|
|
7964
8509
|
entry.pendingPromptList.splice(listIdx, 1);
|
|
7965
|
-
if (isQueued) {
|
|
8510
|
+
if (isQueued && !pendingEntry.removed) {
|
|
7966
8511
|
try {
|
|
7967
8512
|
entry.events.publish({
|
|
7968
8513
|
type: "pending_prompt_completed",
|
|
@@ -7985,6 +8530,15 @@ function createAcpSessionBridge(opts) {
|
|
|
7985
8530
|
);
|
|
7986
8531
|
entry.midTurnMessageQueue.length = 0;
|
|
7987
8532
|
}
|
|
8533
|
+
if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && entry.pendingPromptCount === 0 && byId.get(sessionId) === entry) {
|
|
8534
|
+
void closeSessionImpl(sessionId, void 0, {
|
|
8535
|
+
reason: "last_client_detached"
|
|
8536
|
+
}).catch((err) => {
|
|
8537
|
+
writeStderrLine(
|
|
8538
|
+
`qwen serve: deferred close-on-prompt-complete failed for ${JSON.stringify(sessionId)}: ${err instanceof Error ? err.stack ?? err.message : String(err)}`
|
|
8539
|
+
);
|
|
8540
|
+
});
|
|
8541
|
+
}
|
|
7988
8542
|
}).catch(() => {
|
|
7989
8543
|
});
|
|
7990
8544
|
return result;
|
|
@@ -8000,10 +8554,13 @@ function createAcpSessionBridge(opts) {
|
|
|
8000
8554
|
entry,
|
|
8001
8555
|
context?.clientId
|
|
8002
8556
|
);
|
|
8557
|
+
const runningPrompt = entry.pendingPromptList.find(
|
|
8558
|
+
(pending) => pending.state === "running" && !pending.terminalPublished
|
|
8559
|
+
);
|
|
8003
8560
|
broadcastPromptCancelledOnce(
|
|
8004
8561
|
entry,
|
|
8005
8562
|
sessionId,
|
|
8006
|
-
entry.activePromptId,
|
|
8563
|
+
entry.activePromptId ?? runningPrompt?.promptId,
|
|
8007
8564
|
cancelOriginatorClientId
|
|
8008
8565
|
);
|
|
8009
8566
|
cancelPendingForSession(sessionId);
|
|
@@ -8016,6 +8573,17 @@ function createAcpSessionBridge(opts) {
|
|
|
8016
8573
|
"session.id": sessionId
|
|
8017
8574
|
},
|
|
8018
8575
|
async () => {
|
|
8576
|
+
if (runningPrompt) {
|
|
8577
|
+
const forwarding = runningPrompt.dispatched === true && entry.activePromptId === runningPrompt.promptId ? forwardRunningPromptCancel(entry, runningPrompt, notif) : Promise.resolve();
|
|
8578
|
+
runningPrompt.abortController.abort(
|
|
8579
|
+
new DOMException(
|
|
8580
|
+
"Prompt cancelled before dispatch",
|
|
8581
|
+
"AbortError"
|
|
8582
|
+
)
|
|
8583
|
+
);
|
|
8584
|
+
await forwarding;
|
|
8585
|
+
return;
|
|
8586
|
+
}
|
|
8019
8587
|
try {
|
|
8020
8588
|
await entry.connection.cancel(notif);
|
|
8021
8589
|
} catch (err) {
|
|
@@ -8062,6 +8630,11 @@ function createAcpSessionBridge(opts) {
|
|
|
8062
8630
|
if (!entry) throw new SessionNotFoundError(sessionId);
|
|
8063
8631
|
return entry.events.lastEventId;
|
|
8064
8632
|
},
|
|
8633
|
+
getSessionEventEpoch(sessionId) {
|
|
8634
|
+
const entry = byId.get(sessionId);
|
|
8635
|
+
if (!entry) throw new SessionNotFoundError(sessionId);
|
|
8636
|
+
return entry.events.epoch;
|
|
8637
|
+
},
|
|
8065
8638
|
getSessionReplaySnapshot(sessionId) {
|
|
8066
8639
|
const entry = byId.get(sessionId);
|
|
8067
8640
|
if (!entry) throw new SessionNotFoundError(sessionId);
|
|
@@ -8260,7 +8833,8 @@ function createAcpSessionBridge(opts) {
|
|
|
8260
8833
|
SERVE_CONTROL_EXT_METHODS.sessionCd,
|
|
8261
8834
|
{
|
|
8262
8835
|
sessionId,
|
|
8263
|
-
path: req.path
|
|
8836
|
+
path: req.path,
|
|
8837
|
+
...req.allowedRoots ? { allowedRoots: req.allowedRoots } : {}
|
|
8264
8838
|
}
|
|
8265
8839
|
);
|
|
8266
8840
|
const extResult = raw;
|
|
@@ -8296,6 +8870,12 @@ function createAcpSessionBridge(opts) {
|
|
|
8296
8870
|
);
|
|
8297
8871
|
return { sessionId, ...result };
|
|
8298
8872
|
},
|
|
8873
|
+
setSessionWorktree(sessionId, worktree) {
|
|
8874
|
+
const entry = byId.get(sessionId);
|
|
8875
|
+
if (entry) {
|
|
8876
|
+
entry.worktree = worktree;
|
|
8877
|
+
}
|
|
8878
|
+
},
|
|
8299
8879
|
async closeSession(sessionId, context, closeOpts) {
|
|
8300
8880
|
return closeSessionImpl(sessionId, context, closeOpts);
|
|
8301
8881
|
},
|
|
@@ -8699,33 +9279,7 @@ function createAcpSessionBridge(opts) {
|
|
|
8699
9279
|
);
|
|
8700
9280
|
},
|
|
8701
9281
|
async getSessionTranscriptPage(req) {
|
|
8702
|
-
|
|
8703
|
-
try {
|
|
8704
|
-
const response = await withWorkspaceControl(
|
|
8705
|
-
info,
|
|
8706
|
-
() => withTimeout(
|
|
8707
|
-
Promise.race([
|
|
8708
|
-
info.connection.extMethod(
|
|
8709
|
-
SERVE_STATUS_EXT_METHODS.sessionTranscript,
|
|
8710
|
-
{ ...req, cwd: boundWorkspace }
|
|
8711
|
-
),
|
|
8712
|
-
getChannelClosedReject(info)
|
|
8713
|
-
]),
|
|
8714
|
-
Math.max(initTimeoutMs, SESSION_TRANSCRIPT_TIMEOUT_MS),
|
|
8715
|
-
SERVE_STATUS_EXT_METHODS.sessionTranscript
|
|
8716
|
-
)
|
|
8717
|
-
);
|
|
8718
|
-
return response;
|
|
8719
|
-
} catch (err) {
|
|
8720
|
-
if (isAcpSessionResourceNotFound(err, req.sessionId)) {
|
|
8721
|
-
throw new SessionNotFoundError(req.sessionId);
|
|
8722
|
-
}
|
|
8723
|
-
throw err;
|
|
8724
|
-
} finally {
|
|
8725
|
-
if (hasNoChannelWork(info)) {
|
|
8726
|
-
await startIdleTimer(info, "session transcript");
|
|
8727
|
-
}
|
|
8728
|
-
}
|
|
9282
|
+
return requestSessionTranscriptPage(req);
|
|
8729
9283
|
},
|
|
8730
9284
|
async cancelSessionTask(sessionId, taskId, taskKind) {
|
|
8731
9285
|
return requestSessionStatus(
|
|
@@ -8757,6 +9311,7 @@ function createAcpSessionBridge(opts) {
|
|
|
8757
9311
|
const liveEntry = byId.get(sessionId);
|
|
8758
9312
|
if (!liveEntry) throw new SessionNotFoundError(sessionId);
|
|
8759
9313
|
const lastEventId = liveEntry.events.lastEventId;
|
|
9314
|
+
const eventEpoch = liveEntry.events.epoch;
|
|
8760
9315
|
const promptId = context?.promptId;
|
|
8761
9316
|
const promptPromise = bridgeApi.sendPrompt(
|
|
8762
9317
|
sessionId,
|
|
@@ -8776,7 +9331,8 @@ function createAcpSessionBridge(opts) {
|
|
|
8776
9331
|
return {
|
|
8777
9332
|
...decision,
|
|
8778
9333
|
...promptId !== void 0 ? { promptId } : {},
|
|
8779
|
-
lastEventId
|
|
9334
|
+
lastEventId,
|
|
9335
|
+
eventEpoch
|
|
8780
9336
|
};
|
|
8781
9337
|
},
|
|
8782
9338
|
async getSessionStatsStatus(sessionId) {
|
|
@@ -9093,7 +9649,7 @@ function createAcpSessionBridge(opts) {
|
|
|
9093
9649
|
const entry = byId.get(sessionId);
|
|
9094
9650
|
if (!entry) throw new SessionNotFoundError(sessionId);
|
|
9095
9651
|
resolveTrustedClientId(entry, context?.clientId);
|
|
9096
|
-
return entry.pendingPromptList.map((p) => ({
|
|
9652
|
+
return entry.pendingPromptList.filter((p) => !p.removed).map((p) => ({
|
|
9097
9653
|
promptId: p.promptId,
|
|
9098
9654
|
text: p.text,
|
|
9099
9655
|
queuedAt: p.queuedAt,
|
|
@@ -9110,13 +9666,18 @@ function createAcpSessionBridge(opts) {
|
|
|
9110
9666
|
);
|
|
9111
9667
|
if (idx === -1) return { removed: false };
|
|
9112
9668
|
const target = entry.pendingPromptList[idx];
|
|
9669
|
+
if (target.removed) return { removed: false };
|
|
9113
9670
|
writeStderrLine(
|
|
9114
9671
|
`[pending-prompt] session=${sessionId} removing promptId=${promptId} state=${target.state}`
|
|
9115
9672
|
);
|
|
9116
9673
|
target.abortController.abort(
|
|
9117
9674
|
new DOMException("Prompt removed by user", "AbortError")
|
|
9118
9675
|
);
|
|
9119
|
-
|
|
9676
|
+
if (target.state === "queued") {
|
|
9677
|
+
entry.pendingPromptList.splice(idx, 1);
|
|
9678
|
+
} else {
|
|
9679
|
+
target.removed = true;
|
|
9680
|
+
}
|
|
9120
9681
|
try {
|
|
9121
9682
|
entry.events.publish({
|
|
9122
9683
|
type: "pending_prompt_completed",
|
|
@@ -9126,6 +9687,9 @@ function createAcpSessionBridge(opts) {
|
|
|
9126
9687
|
});
|
|
9127
9688
|
} catch {
|
|
9128
9689
|
}
|
|
9690
|
+
if (target.state === "queued") {
|
|
9691
|
+
publishPromptTerminal(entry, target, { kind: "cancelled" });
|
|
9692
|
+
}
|
|
9129
9693
|
return { removed: true };
|
|
9130
9694
|
},
|
|
9131
9695
|
enqueueMidTurnMessage(sessionId, message, context) {
|
|
@@ -9373,6 +9937,9 @@ function createAcpSessionBridge(opts) {
|
|
|
9373
9937
|
async rewindSession(sessionId, req, context) {
|
|
9374
9938
|
const entry = byId.get(sessionId);
|
|
9375
9939
|
if (!entry) throw new SessionNotFoundError(sessionId);
|
|
9940
|
+
if (entry.closing) {
|
|
9941
|
+
throw new SessionNotFoundError(sessionId, "The session is closing");
|
|
9942
|
+
}
|
|
9376
9943
|
const info = channelInfoForEntry(entry);
|
|
9377
9944
|
if (!info || info.isDying) throw new SessionNotFoundError(sessionId);
|
|
9378
9945
|
const originatorClientId = resolveTrustedClientId(
|
|
@@ -9564,7 +10131,7 @@ function createAcpSessionBridge(opts) {
|
|
|
9564
10131
|
}
|
|
9565
10132
|
}
|
|
9566
10133
|
},
|
|
9567
|
-
async reloadWorkspaceMcp() {
|
|
10134
|
+
async reloadWorkspaceMcp(options) {
|
|
9568
10135
|
const info = await ensureChannel();
|
|
9569
10136
|
info.workspaceMcpDiscoveryRequested = true;
|
|
9570
10137
|
try {
|
|
@@ -9572,7 +10139,7 @@ function createAcpSessionBridge(opts) {
|
|
|
9572
10139
|
withTimeout(
|
|
9573
10140
|
info.connection.extMethod(
|
|
9574
10141
|
SERVE_CONTROL_EXT_METHODS.workspaceMcpReload,
|
|
9575
|
-
{ cwd: boundWorkspace }
|
|
10142
|
+
{ cwd: boundWorkspace, ...options }
|
|
9576
10143
|
),
|
|
9577
10144
|
initTimeoutMs,
|
|
9578
10145
|
SERVE_CONTROL_EXT_METHODS.workspaceMcpReload
|
|
@@ -9606,6 +10173,85 @@ function createAcpSessionBridge(opts) {
|
|
|
9606
10173
|
getChannelClosedReject(info)
|
|
9607
10174
|
]);
|
|
9608
10175
|
},
|
|
10176
|
+
generateWorkspaceContent(prompt, signal, _originatorClientId) {
|
|
10177
|
+
const requestId = randomUUID2();
|
|
10178
|
+
const queue = new GenerationStreamQueue(
|
|
10179
|
+
GENERATION_STREAM_QUEUE_CAPACITY
|
|
10180
|
+
);
|
|
10181
|
+
const request = {
|
|
10182
|
+
connection: void 0,
|
|
10183
|
+
queue,
|
|
10184
|
+
settled: false
|
|
10185
|
+
};
|
|
10186
|
+
const cancel = /* @__PURE__ */ __name(() => {
|
|
10187
|
+
if (request.settled) return;
|
|
10188
|
+
request.settled = true;
|
|
10189
|
+
workspaceGenerationRequests.delete(requestId);
|
|
10190
|
+
queue.close();
|
|
10191
|
+
void request.connection?.extMethod(SERVE_CONTROL_EXT_METHODS.workspaceGenerationCancel, {
|
|
10192
|
+
requestId
|
|
10193
|
+
}).catch(() => void 0);
|
|
10194
|
+
}, "cancel");
|
|
10195
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
10196
|
+
if (signal.aborted) {
|
|
10197
|
+
cancel();
|
|
10198
|
+
return queue;
|
|
10199
|
+
}
|
|
10200
|
+
void (async () => {
|
|
10201
|
+
let info;
|
|
10202
|
+
try {
|
|
10203
|
+
const channelInfo2 = await ensureChannel();
|
|
10204
|
+
info = channelInfo2;
|
|
10205
|
+
request.connection = channelInfo2.connection;
|
|
10206
|
+
await withWorkspaceControl(channelInfo2, async () => {
|
|
10207
|
+
if (request.settled) return;
|
|
10208
|
+
workspaceGenerationRequests.set(requestId, request);
|
|
10209
|
+
const raw = await Promise.race([
|
|
10210
|
+
withTimeout(
|
|
10211
|
+
channelInfo2.connection.extMethod(
|
|
10212
|
+
SERVE_CONTROL_EXT_METHODS.workspaceGenerationStart,
|
|
10213
|
+
{
|
|
10214
|
+
requestId,
|
|
10215
|
+
prompt,
|
|
10216
|
+
purpose: "text"
|
|
10217
|
+
}
|
|
10218
|
+
),
|
|
10219
|
+
SESSION_GENERATION_TIMEOUT_MS,
|
|
10220
|
+
SERVE_CONTROL_EXT_METHODS.workspaceGenerationStart
|
|
10221
|
+
),
|
|
10222
|
+
getChannelClosedReject(channelInfo2)
|
|
10223
|
+
]);
|
|
10224
|
+
if (request.settled) return;
|
|
10225
|
+
const response = raw;
|
|
10226
|
+
const model = response["model"];
|
|
10227
|
+
const modelSource = response["modelSource"];
|
|
10228
|
+
if (typeof model !== "string" || modelSource !== "fast" && modelSource !== "main") {
|
|
10229
|
+
throw new Error("Malformed workspace generation completion");
|
|
10230
|
+
}
|
|
10231
|
+
const accepted = queue.push({
|
|
10232
|
+
type: "done",
|
|
10233
|
+
requestId,
|
|
10234
|
+
model,
|
|
10235
|
+
modelSource,
|
|
10236
|
+
...typeof response["inputTokens"] === "number" ? { inputTokens: response["inputTokens"] } : {},
|
|
10237
|
+
...typeof response["outputTokens"] === "number" ? { outputTokens: response["outputTokens"] } : {}
|
|
10238
|
+
});
|
|
10239
|
+
if (accepted) queue.close();
|
|
10240
|
+
else queue.fail(new Error("Generation stream consumer too slow"));
|
|
10241
|
+
});
|
|
10242
|
+
} catch (error) {
|
|
10243
|
+
if (!request.settled) queue.fail(error);
|
|
10244
|
+
} finally {
|
|
10245
|
+
request.settled = true;
|
|
10246
|
+
signal.removeEventListener("abort", cancel);
|
|
10247
|
+
workspaceGenerationRequests.delete(requestId);
|
|
10248
|
+
if (info && hasNoChannelWork(info) && !info.isDying) {
|
|
10249
|
+
await startIdleTimer(info, "workspace generation");
|
|
10250
|
+
}
|
|
10251
|
+
}
|
|
10252
|
+
})().catch(() => void 0);
|
|
10253
|
+
return queue;
|
|
10254
|
+
},
|
|
9609
10255
|
async addRuntimeMcpServer(name, config, originatorClientId) {
|
|
9610
10256
|
const info = liveChannelInfo();
|
|
9611
10257
|
if (!info) {
|
|
@@ -9684,9 +10330,41 @@ function createAcpSessionBridge(opts) {
|
|
|
9684
10330
|
entry.spawnOwnerWantedKill = true;
|
|
9685
10331
|
return false;
|
|
9686
10332
|
}
|
|
10333
|
+
if (entry.closing) {
|
|
10334
|
+
const closingChannel = channelInfoForEntry(entry);
|
|
10335
|
+
if (!closingChannel) return false;
|
|
10336
|
+
await killChannelWithLog(
|
|
10337
|
+
closingChannel,
|
|
10338
|
+
`force kill closing session ${JSON.stringify(sessionId)}`
|
|
10339
|
+
);
|
|
10340
|
+
return true;
|
|
10341
|
+
}
|
|
10342
|
+
entry.closing = true;
|
|
10343
|
+
const ci = channelInfoForEntry(entry);
|
|
10344
|
+
if (!ci) {
|
|
10345
|
+
writeStderrLine(
|
|
10346
|
+
`qwen serve: killSession channelInfoForEntry returned undefined for session ${JSON.stringify(sessionId)} \u2014 channel cleanup skipped (entry's channel already torn down)`
|
|
10347
|
+
);
|
|
10348
|
+
}
|
|
9687
10349
|
permissionMediator.forgetSession(sessionId);
|
|
9688
10350
|
entry.pendingPermissionIds.clear();
|
|
9689
10351
|
entry.pendingInteractions.clear();
|
|
10352
|
+
try {
|
|
10353
|
+
await notifyAgentSessionClose(entry, ci, "killSession", {
|
|
10354
|
+
throwOnFailure: true,
|
|
10355
|
+
timeoutMs: initTimeoutMs
|
|
10356
|
+
});
|
|
10357
|
+
} catch (error) {
|
|
10358
|
+
if (ci) {
|
|
10359
|
+
await killChannelWithLog(
|
|
10360
|
+
ci,
|
|
10361
|
+
`force kill session ${JSON.stringify(sessionId)}`
|
|
10362
|
+
);
|
|
10363
|
+
return true;
|
|
10364
|
+
}
|
|
10365
|
+
entry.closing = false;
|
|
10366
|
+
throw error;
|
|
10367
|
+
}
|
|
9690
10368
|
if (entry.promptActive) {
|
|
9691
10369
|
entry.promptActive = false;
|
|
9692
10370
|
activePromptCounter--;
|
|
@@ -9701,17 +10379,15 @@ function createAcpSessionBridge(opts) {
|
|
|
9701
10379
|
workspaceCwd: entry.workspaceCwd,
|
|
9702
10380
|
reason: "killed"
|
|
9703
10381
|
});
|
|
9704
|
-
const ci = channelInfoForEntry(entry);
|
|
9705
|
-
if (!ci) {
|
|
9706
|
-
writeStderrLine(
|
|
9707
|
-
`qwen serve: killSession channelInfoForEntry returned undefined for session ${JSON.stringify(sessionId)} \u2014 channel cleanup skipped (entry's channel already torn down)`
|
|
9708
|
-
);
|
|
9709
|
-
}
|
|
9710
10382
|
if (ci && ci.channel === entry.channel) {
|
|
9711
10383
|
ci.sessionIds.delete(sessionId);
|
|
9712
10384
|
}
|
|
9713
|
-
await notifyAgentSessionClose(entry, ci, "killSession");
|
|
9714
10385
|
ci?.client.markSessionClosed(sessionId);
|
|
10386
|
+
flushPromptTerminals(
|
|
10387
|
+
entry,
|
|
10388
|
+
"session_killed",
|
|
10389
|
+
"session killed before the prompt completed"
|
|
10390
|
+
);
|
|
9715
10391
|
try {
|
|
9716
10392
|
entry.events.publish({
|
|
9717
10393
|
type: "session_died",
|
|
@@ -9731,12 +10407,14 @@ function createAcpSessionBridge(opts) {
|
|
|
9731
10407
|
async detachClient(sessionId, clientId) {
|
|
9732
10408
|
const entry = byId.get(sessionId);
|
|
9733
10409
|
if (!entry) return;
|
|
9734
|
-
if (
|
|
10410
|
+
if (clientId !== void 0 && releaseAttachRef(entry, clientId)) {
|
|
10411
|
+
if (entry.attachCount > 0) entry.attachCount--;
|
|
10412
|
+
}
|
|
9735
10413
|
unregisterClient(entry, clientId);
|
|
9736
10414
|
if (entry.spawnOwnerWantedKill && entry.attachCount === 0 && entry.events.subscriberCount === 0) {
|
|
9737
10415
|
await this.killSession(sessionId).catch(() => {
|
|
9738
10416
|
});
|
|
9739
|
-
} else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 &&
|
|
10417
|
+
} else if (entry.clientIds.size === 0 && entry.events.subscriberCount === 0 && entry.pendingPromptCount === 0) {
|
|
9740
10418
|
await closeSessionImpl(sessionId, void 0, {
|
|
9741
10419
|
reason: "last_client_detached"
|
|
9742
10420
|
}).catch((err) => {
|
|
@@ -9800,6 +10478,11 @@ function createAcpSessionBridge(opts) {
|
|
|
9800
10478
|
workspaceCwd: e.workspaceCwd,
|
|
9801
10479
|
reason: shutdownReason
|
|
9802
10480
|
});
|
|
10481
|
+
flushPromptTerminals(
|
|
10482
|
+
e,
|
|
10483
|
+
"daemon_shutdown",
|
|
10484
|
+
"daemon shut down before the prompt completed"
|
|
10485
|
+
);
|
|
9803
10486
|
try {
|
|
9804
10487
|
e.events.publish({
|
|
9805
10488
|
type: "session_died",
|