@qwen-code/qwen-code 0.23.2 → 0.23.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -15
- package/bundled/computer-use/SKILL.md +1 -1
- package/bundled/qc-helper/docs/configuration/model-providers.md +66 -28
- package/bundled/qc-helper/docs/configuration/settings.md +5 -3
- package/bundled/qc-helper/docs/features/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/channels/dws.md +7 -1
- package/bundled/qc-helper/docs/features/commands.md +57 -9
- package/bundled/qc-helper/docs/features/computer-use.md +1 -1
- package/bundled/qc-helper/docs/features/cross-session-protocol.md +320 -0
- package/bundled/qc-helper/docs/features/goals.md +1 -1
- package/bundled/qc-helper/docs/qwen-serve.md +16 -3
- package/bundled/review/SKILL.md +82 -79
- package/bundled/review/references/posting.md +31 -14
- package/chunks/{MaxSizedBox-4C3BKKKY.js → MaxSizedBox-D4LW7RZZ.js} +58 -51
- package/chunks/{StandaloneSessionPicker-TXVF65YW.js → StandaloneSessionPicker-ALTTRWUP.js} +80 -73
- package/chunks/acp-subagent-executor-LEUN3N7N.js +919 -0
- package/chunks/{acpAgent-H5XBKGB4.js → acpAgent-BBSW7XZG.js} +509 -201
- package/chunks/{agent-T5LEFJIU.js → agent-SQ6OY3QD.js} +42 -36
- package/chunks/{agent-headless-VZKSRH36.js → agent-headless-RI2THRQ7.js} +42 -36
- package/chunks/{anthropicContentGenerator-PRJWWVYJ.js → anthropicContentGenerator-JSKMKS6V.js} +66 -34
- package/chunks/{artifact-tool-G5LHNECG.js → artifact-tool-PMYZCYNH.js} +2 -2
- package/chunks/{askUserQuestion-I5W5S3D6.js → askUserQuestion-4M4YYIB4.js} +2 -2
- package/chunks/{bridge-AOX5IY44.js → bridge-DAFMI72L.js} +62 -55
- package/chunks/{channel-management-service-MWQGHPAS.js → channel-management-service-OWDXVL7R.js} +8 -8
- package/chunks/{channel-settings-store-XZCGDGHW.js → channel-settings-store-4I6JONT7.js} +69 -62
- package/chunks/{channel-worker-group-SQ5FRWOH.js → channel-worker-group-F2ZZMLNS.js} +8 -8
- package/chunks/{channel-worker-manager-TU4ZNWOE.js → channel-worker-manager-2SZLJJSJ.js} +18 -9
- package/chunks/{channel-worker-supervisor-EMITFMCP.js → channel-worker-supervisor-ZFNWMG6D.js} +6 -6
- package/chunks/{chunk-GNY7B3CA.js → chunk-2ALXPGB4.js} +1 -1
- package/chunks/{chunk-LUNC5KCL.js → chunk-2PJRI3EH.js} +7 -7
- package/chunks/{chunk-CLKE4IY3.js → chunk-2SZH22YO.js} +1 -1
- package/chunks/{chunk-RNAJVXUG.js → chunk-2ZN3O5FT.js} +6 -6
- package/chunks/{chunk-HIXUUCGY.js → chunk-36HCNKDS.js} +1 -1
- package/chunks/{chunk-FGHPZGOP.js → chunk-3BTSSIJO.js} +38 -54
- package/chunks/{chunk-VBLAI2HA.js → chunk-3FPYT6QC.js} +0 -31
- package/chunks/{chunk-QB3KS3N3.js → chunk-3I7W2POO.js} +1 -1
- package/chunks/{chunk-QTB4VP4K.js → chunk-3KQBQ6FM.js} +136 -11
- package/chunks/{chunk-JO77FGNZ.js → chunk-3UXUOFO6.js} +19 -7
- package/chunks/{chunk-WDN64MVT.js → chunk-3XLK2QMY.js} +82 -16
- package/chunks/chunk-532WHF4F.js +127 -0
- package/chunks/{chunk-NX7ZTXFF.js → chunk-53GWJOLP.js} +1 -1
- package/chunks/{chunk-QQK4L3UU.js → chunk-5GLDOLNQ.js} +131 -26
- package/chunks/{chunk-WK7P62DV.js → chunk-5KI7ZDTB.js} +6 -6
- package/chunks/{chunk-ERXNTINK.js → chunk-6JACAGYH.js} +1 -1
- package/chunks/{chunk-CMWU6P4D.js → chunk-6W4HBUA2.js} +1 -1
- package/chunks/{chunk-AUTUFD5X.js → chunk-76RGWKLS.js} +1 -1
- package/chunks/{chunk-PDN7FJZV.js → chunk-7APZIRH3.js} +2 -2
- package/chunks/{chunk-WBU2PIZ5.js → chunk-7BXXIQG4.js} +16 -16
- package/chunks/{chunk-APXIW2TF.js → chunk-7ICHPMBQ.js} +4 -4
- package/chunks/{chunk-CWVZBIZJ.js → chunk-7Q2AXRDJ.js} +1 -1
- package/chunks/{chunk-WDVV3LRM.js → chunk-7QYWGTHB.js} +1 -1
- package/chunks/{chunk-RM244SCQ.js → chunk-AC6KDLH3.js} +1 -1
- package/chunks/{chunk-2WC3Y7YY.js → chunk-AEY27Z35.js} +401 -23
- package/chunks/{chunk-XDNFODER.js → chunk-AXTFYDXT.js} +1 -1
- package/chunks/chunk-AYEJOTIU.js +43 -0
- package/chunks/{chunk-ZN5TKAVR.js → chunk-BV6Q5HMY.js} +3 -3
- package/chunks/{chunk-TOOOLHVS.js → chunk-BWAMMKIS.js} +3 -3
- package/chunks/{chunk-IRGDIDGJ.js → chunk-BWQLXU37.js} +26 -19
- package/chunks/{process-registry-OAEG6WGC.js → chunk-BYUAT5OC.js} +1 -0
- package/chunks/{chunk-GOEVQADN.js → chunk-BZM5U74J.js} +287 -169
- package/chunks/chunk-CF5KXZZX.js +150 -0
- package/chunks/{chunk-TGNNLRC3.js → chunk-CJ3DHN5I.js} +1 -0
- package/chunks/{chunk-PFKGV6PO.js → chunk-CUEXOHQH.js} +9 -9
- package/chunks/chunk-CXTPVBFA.js +937 -0
- package/chunks/{chunk-LEAOJ43M.js → chunk-DAWWT2ID.js} +62 -59
- package/chunks/{chunk-CALTQWTZ.js → chunk-DLH7YIX6.js} +2 -2
- package/chunks/chunk-DT75RKNH.js +691 -0
- package/chunks/{chunk-TRWQQBVH.js → chunk-DTNV6UZY.js} +1 -1
- package/chunks/{chunk-3OAXF3UK.js → chunk-DYFOSJHU.js} +3080 -933
- package/chunks/{chunk-GSFV5RQW.js → chunk-E4UEO3XM.js} +3 -2
- package/chunks/{chunk-A7EFXK7P.js → chunk-E7LB57MB.js} +5 -5
- package/chunks/{chunk-KEPC5BOL.js → chunk-EDMXGXAK.js} +9 -9
- package/chunks/chunk-ELRMZTPF.js +374 -0
- package/chunks/chunk-ERU3SDXT.js +27 -0
- package/chunks/{chunk-O2FEO2CB.js → chunk-EUURTIV6.js} +18 -2
- package/chunks/{chunk-QFJZAY7W.js → chunk-EVTNACMT.js} +3 -3
- package/chunks/{chunk-4HOEU2OR.js → chunk-EWJTAP3Y.js} +1 -19
- package/chunks/{chunk-YQGW3M6Z.js → chunk-F42YYSCK.js} +8 -8
- package/chunks/{chunk-7PD7ZMX5.js → chunk-FCQJLMA2.js} +98 -5
- package/chunks/{chunk-4VY3ITHR.js → chunk-FN3JNDRU.js} +3 -3
- package/chunks/{chunk-R457KFV7.js → chunk-GCDXVPFK.js} +3 -3
- package/chunks/{chunk-IR6JKBAP.js → chunk-GOXQL4YH.js} +2 -2
- package/chunks/{chunk-YLOHCA6I.js → chunk-GSILBZLN.js} +2 -2
- package/chunks/{chunk-LNYV4GXX.js → chunk-GSKX53AN.js} +0 -139
- package/chunks/{chunk-4WMGYG3F.js → chunk-HBQ2NXOU.js} +2 -2
- package/chunks/{chunk-F2NYVASI.js → chunk-HBU7EKY4.js} +14 -12
- package/chunks/{chunk-6G4V7SE4.js → chunk-HG46TTAG.js} +1 -1
- package/chunks/{chunk-G5VOXCRX.js → chunk-HGAELO7B.js} +2 -2
- package/chunks/{chunk-FETY36NQ.js → chunk-HGEUHUEV.js} +1 -1
- package/chunks/{chunk-E6TI726I.js → chunk-HUXPEUFL.js} +1 -1
- package/chunks/{chunk-LYT2OU7D.js → chunk-IAEXTMED.js} +1 -1
- package/chunks/{chunk-IW6RQPQB.js → chunk-IJOS26LH.js} +1 -3
- package/chunks/{chunk-ORFIYTI2.js → chunk-IK2MWJP5.js} +1 -1
- package/chunks/{chunk-WXD7INFV.js → chunk-IL5M5NYD.js} +8 -8
- package/chunks/{chunk-KA5HR3G2.js → chunk-IUVIBDKU.js} +2 -2
- package/chunks/{chunk-5DQ4YTIZ.js → chunk-IV7GDNKC.js} +1 -1
- package/chunks/chunk-JL6APGBX.js +43 -0
- package/chunks/{chunk-N6S3NUYJ.js → chunk-JXNIF2O5.js} +1 -1
- package/chunks/{chunk-DAI65CMX.js → chunk-JYKWOREU.js} +1 -1
- package/chunks/chunk-K2OJUPOE.js +78 -0
- package/chunks/{chunk-KFECPHLV.js → chunk-KFZYGSJN.js} +3 -3
- package/chunks/{chunk-BK7D2JR6.js → chunk-KOKPXIAN.js} +3 -3
- package/chunks/{chunk-4I3WFI3U.js → chunk-LDVNJZGH.js} +12 -12
- package/chunks/{chunk-WXFCI3O5.js → chunk-LG5Y4OWO.js} +2 -2
- package/chunks/{chunk-3LPJ776W.js → chunk-LILGKQ4B.js} +10 -7
- package/chunks/{chunk-X7LFJF5D.js → chunk-LK2WUCDQ.js} +36 -84
- package/chunks/{chunk-7LTCFO6T.js → chunk-MF6E7FSA.js} +6 -5
- package/chunks/{chunk-ELD3OBPU.js → chunk-MHAADZOZ.js} +3 -3
- package/chunks/{chunk-4JNHNVAZ.js → chunk-MLQNSPRZ.js} +4 -4
- package/chunks/{chunk-NPKCVSXX.js → chunk-MOS5OAOG.js} +10 -8
- package/chunks/{chunk-IWABUX6T.js → chunk-MSNHNAQZ.js} +6 -6
- package/chunks/{chunk-HJ5UJQQL.js → chunk-N7VWZDWW.js} +1699 -1312
- package/chunks/{chunk-NB3NDQQK.js → chunk-NE624IVP.js} +1 -1
- package/chunks/{chunk-SOA4HKRJ.js → chunk-NFYEQRLG.js} +2 -2
- package/chunks/{chunk-G3ZUMSFS.js → chunk-NHCZJQE4.js} +6 -6
- package/chunks/{chunk-B25JYXZE.js → chunk-NHJKAR6E.js} +4 -4
- package/chunks/{chunk-ZP5XDLSA.js → chunk-NJQTG2G3.js} +12 -12
- package/chunks/{chunk-DARWOZY6.js → chunk-NLNQNBZ2.js} +1 -1
- package/chunks/{chunk-CCBTNJB4.js → chunk-NMCDMLHL.js} +27 -27
- package/chunks/{chunk-AO2VMS72.js → chunk-NMRCXKQ5.js} +3 -3
- package/chunks/{chunk-5BH2AIEY.js → chunk-NOAG7N22.js} +2 -2
- package/chunks/{chunk-VJJXG73H.js → chunk-NRXWJXJ4.js} +15 -0
- package/chunks/chunk-NUQ4GK5I.js +315 -0
- package/chunks/{chunk-J3VZF2AL.js → chunk-NUQVB25K.js} +2 -2
- package/chunks/{chunk-U6REWGVR.js → chunk-OLTN767L.js} +2 -2
- package/chunks/{chunk-R3JIDRUL.js → chunk-OX7IZ2G5.js} +4 -4
- package/chunks/{chunk-QAZ2MGYT.js → chunk-PLLIWEM3.js} +2 -2
- package/chunks/{chunk-KCF2436G.js → chunk-POC3YMHG.js} +4 -4
- package/chunks/{chunk-HZ2HUXX7.js → chunk-Q2LVVIKF.js} +1 -1
- package/chunks/{chunk-7NDZKE2M.js → chunk-Q5BD56BW.js} +3 -3
- package/chunks/{chunk-22GORRNY.js → chunk-QMUYLYT5.js} +1 -1
- package/chunks/{chunk-MV5DTLJV.js → chunk-R4Q2PEFV.js} +1 -1
- package/chunks/{chunk-GOKAOSCN.js → chunk-RLLRJJDR.js} +1 -1
- package/chunks/{chunk-5OZUKLL7.js → chunk-RWVD5RRY.js} +4 -4
- package/chunks/{chunk-ULZECEIP.js → chunk-RZHU3K6M.js} +2 -2
- package/chunks/{chunk-UYDQYDW2.js → chunk-S6Q6Q4P2.js} +1 -1
- package/chunks/{chunk-PQEISIKS.js → chunk-SAH4BD2J.js} +0 -67
- package/chunks/{chunk-LWX4WDFF.js → chunk-SBRX4BDI.js} +43 -15
- package/chunks/{chunk-TODNHE76.js → chunk-SODMFNAR.js} +5 -5
- package/chunks/{chunk-FAJPLSYF.js → chunk-SSGAAWLY.js} +89 -85
- package/chunks/{chunk-46MMBZHI.js → chunk-SYLECP23.js} +4 -4
- package/chunks/{chunk-6RZX2HIH.js → chunk-TBEXLLAO.js} +2 -2
- package/chunks/{chunk-MWIO7MF6.js → chunk-TP6FYVQT.js} +2 -0
- package/chunks/{chunk-HRPFBHW7.js → chunk-TPKQIA7G.js} +1 -0
- package/chunks/{chunk-QHLHE2OT.js → chunk-TWUKBNWM.js} +1 -1
- package/chunks/{chunk-H3Q3RSKZ.js → chunk-U7O65WKL.js} +1 -1
- package/chunks/{chunk-S5QR6CB5.js → chunk-UKMWZ5NS.js} +108 -887
- package/chunks/{chunk-OXR34GCD.js → chunk-UKZ45TJL.js} +1851 -34
- package/chunks/{chunk-CALNF3Z3.js → chunk-V2P3DOQR.js} +1 -1
- package/chunks/{chunk-FV4DM2M4.js → chunk-VG3Q2NC4.js} +7 -7
- package/chunks/{chunk-QTNCGZHQ.js → chunk-VX63RJXE.js} +9 -0
- package/chunks/{chunk-CRZBDVP2.js → chunk-VZUCTJ2P.js} +4 -4
- package/chunks/{chunk-2BMXHB6N.js → chunk-W5FIP7FC.js} +7 -7
- package/chunks/{chunk-7VEYUF3N.js → chunk-W5ZQMAEM.js} +1 -1
- package/chunks/{chunk-XQ4RDO5B.js → chunk-WBCPROWX.js} +1 -1
- package/chunks/{chunk-JYGIJA4W.js → chunk-X6K77VHC.js} +1 -1
- package/chunks/{chunk-7SVM3RP2.js → chunk-X7UJKOHZ.js} +3 -3
- package/chunks/{chunk-WXPPUPHM.js → chunk-XBZTAGB7.js} +1 -1
- package/chunks/{chunk-TRQNRP2H.js → chunk-XGYHNWL3.js} +45 -2
- package/chunks/{chunk-2EKVPSIJ.js → chunk-Y2MYW47X.js} +1 -1
- package/chunks/{chunk-OFVAS4AR.js → chunk-YBUMTY7B.js} +1 -1
- package/chunks/{chunk-67XTVRVB.js → chunk-YQHLFCPU.js} +7 -7
- package/chunks/{chunk-G37O7YO6.js → chunk-Z3GF56ME.js} +2 -2
- package/chunks/{chunk-XBVNNDPK.js → chunk-ZHKTKHMO.js} +8 -1
- package/chunks/{chunk-OWCFKIFQ.js → chunk-ZKYR7QS4.js} +1 -1
- package/chunks/{chunk-YZTGGCEE.js → chunk-ZKZHSB5W.js} +1 -1
- package/chunks/{chunk-565U2ANU.js → chunk-ZTTC7T4X.js} +1 -1
- package/chunks/{chunk-XSOXPG2L.js → chunk-ZU47FBOC.js} +36 -7
- package/chunks/{chunk-7OCIQNKX.js → chunk-ZW2EUO2A.js} +1 -1
- package/chunks/{config-utils-GPLIABL2.js → config-utils-L6KLDYIV.js} +62 -55
- package/chunks/{contextCommand-NCUQUDBY.js → contextCommand-UYEH7NIU.js} +59 -52
- package/chunks/{core-runtime-WKYKWVYU.js → core-runtime-NVHT3Z3V.js} +61 -54
- package/chunks/{create-sub-session-TGIX63YU.js → create-sub-session-TIGCFGCS.js} +2 -2
- package/chunks/{create-sub-session-PPLXB3JJ.js → create-sub-session-YWASE5VH.js} +59 -52
- package/chunks/{cron-create-GTPVMJCF.js → cron-create-AKWX67FO.js} +1 -1
- package/chunks/{cron-delete-ZBK27Z4K.js → cron-delete-XPB6IYZJ.js} +1 -1
- package/chunks/{cron-list-KTFKFDKC.js → cron-list-XBKO4WU5.js} +1 -1
- package/chunks/{daemon-2CKIAO3I.js → daemon-G5TYKZD6.js} +2 -2
- package/chunks/{daemon-git-worktree-guard-73ZWOLKL.js → daemon-git-worktree-guard-FOW4RQSK.js} +60 -53
- package/chunks/{daemon-status-provider-OK7VONJG.js → daemon-status-provider-O5KQZYMP.js} +67 -60
- package/chunks/{daemon-trust-policy-CAUCREG2.js → daemon-trust-policy-3ATXEON7.js} +64 -57
- package/chunks/{daemon-trust-policy-monitor-3Y36OOEQ.js → daemon-trust-policy-monitor-7MCNDNEC.js} +64 -57
- package/chunks/{deferred-core-runtime-Q7WFWYD3.js → deferred-core-runtime-JK5IXL5K.js} +57 -50
- package/chunks/{display-image-CTNHJRZC.js → display-image-NAH3AZ63.js} +3 -3
- package/chunks/{dist-NP7QKLVG.js → dist-AHJYPSJL.js} +3 -3
- package/chunks/{dist-6YDUH3BB.js → dist-AIKC5E5P.js} +2 -2
- package/chunks/{dist-Y5KC3IHW.js → dist-F2DVGTL3.js} +225 -6
- package/chunks/{dist-BNQVF565.js → dist-GWNQVPZT.js} +5 -5
- package/chunks/{dist-F6JLAJLE.js → dist-H6G3K26N.js} +3 -3
- package/chunks/{dist-ZDNJK74R.js → dist-KJGRVIGJ.js} +2 -2
- package/chunks/{dist-F34J4FZX.js → dist-KLZ7XGEQ.js} +2 -2
- package/chunks/{dist-UFTFGI6I.js → dist-ZA52JXAS.js} +2 -2
- package/chunks/{dist-XLV33CLY.js → dist-ZXTZTE54.js} +2 -2
- package/chunks/{edit-YJD6IETK.js → edit-SY35KYIE.js} +45 -39
- package/chunks/{en-YJNRUQG4.js → en-CAJHTIQT.js} +1 -0
- package/chunks/{enter-worktree-YFTKHXHZ.js → enter-worktree-54L5QJ3N.js} +4 -4
- package/chunks/{enterPlanMode-EFPVTWIH.js → enterPlanMode-HXX6KQJR.js} +42 -36
- package/chunks/{environment-HP3AXFTB.js → environment-DKXHG4HB.js} +60 -53
- package/chunks/{errors-22ON46G7.js → errors-ADY7LQJJ.js} +59 -52
- package/chunks/{exit-worktree-NF2XEMES.js → exit-worktree-EORJDKDS.js} +4 -4
- package/chunks/{exitPlanMode-MOQUNCBH.js → exitPlanMode-HSK2CQI6.js} +42 -36
- package/chunks/{fast-path-2X7BPMXX.js → fast-path-U636VWN2.js} +6 -6
- package/chunks/{fast-path-settings-SATXY3PD.js → fast-path-settings-V7MI7EZJ.js} +2 -2
- package/chunks/{glob-Y7ACIB3P.js → glob-GUGGTH5L.js} +45 -39
- package/chunks/{goal-tools-DABMICUC.js → goal-tools-PXYRSQGX.js} +42 -36
- package/chunks/{grep-BLHF2S5D.js → grep-3PKFKLCA.js} +2 -2
- package/chunks/{handleAutoUpdate-MCAMHYDI.js → handleAutoUpdate-5KHS4HIN.js} +60 -53
- package/chunks/{i18n-C3GDCALP.js → i18n-KSGKMUPT.js} +58 -51
- package/chunks/{image-gen-XP4NNIYG.js → image-gen-OCCR2WWU.js} +5 -4
- package/chunks/{initializer-4URDQL2G.js → initializer-YYT5XEZF.js} +64 -57
- package/chunks/{installationInfo-LBOL6SBV.js → installationInfo-UNSBPYW2.js} +57 -50
- package/chunks/{list-JOGBAC2R.js → list-YL6LDQKQ.js} +67 -60
- package/chunks/{list-agents-2CXPGJUE.js → list-agents-QLDXS5OD.js} +17 -7
- package/chunks/{llm-2KPNSAVY.js → llm-XGGLBGPH.js} +126 -119
- package/chunks/{llm-content-generator-GR3FOHLB.js → llm-content-generator-ZHQQT5W7.js} +5 -4
- package/chunks/{loadedSettingsAdapter-DVKROEJD.js → loadedSettingsAdapter-3DXLASK7.js} +64 -57
- package/chunks/{loggingContentGenerator-P4K6K5W4.js → loggingContentGenerator-V72OCCJO.js} +64 -57
- package/chunks/{loop-wakeup-HL6XOWI4.js → loop-wakeup-HHMYIC7Z.js} +2 -2
- package/chunks/{ls-YV7RKLKY.js → ls-N7ABR6HI.js} +4 -4
- package/chunks/{lsp-NO3AMRZT.js → lsp-LTOFWG5P.js} +1 -1
- package/chunks/{managed-npm-update-VWBKHNIN.js → managed-npm-update-HV5LPZH2.js} +57 -50
- package/chunks/{mcp-6YYNSYLK.js → mcp-IYVSIW6O.js} +64 -57
- package/chunks/{monitor-A255TNZR.js → monitor-TLBNM4MV.js} +44 -38
- package/chunks/{nonInteractiveCli-LXGIKQAT.js → nonInteractiveCli-LSJSQ2W4.js} +110 -103
- package/chunks/{notebook-edit-5UYHS2DM.js → notebook-edit-OSPOLZP6.js} +43 -37
- package/chunks/openai-WX26N5OJ.js +47 -0
- package/chunks/{openaiContentGenerator-A6MAMEO5.js → openaiContentGenerator-BE4S5TRD.js} +29 -23
- package/chunks/openaiResponsesContentGenerator-RTCAJ5V5.js +1658 -0
- package/chunks/{pidfile-B7DZC4TP.js → pidfile-H32FEPWA.js} +57 -50
- package/chunks/process-registry-X6ZCASEN.js +10 -0
- package/chunks/{processUtils-BPZ2MCZS.js → processUtils-SSLIPDEA.js} +2 -2
- package/chunks/{prompt-terminal-ledger-FYYTAOXS.js → prompt-terminal-ledger-I5SLL6UF.js} +58 -51
- package/chunks/{qwenContentGenerator-4IOJFD4S.js → qwenContentGenerator-TMQC623Z.js} +55 -47
- package/chunks/{qwenOAuth2-KX6LVYQ3.js → qwenOAuth2-3ZRQHHTC.js} +4 -3
- package/chunks/{read-file-A4H4O3VQ.js → read-file-T2QAIZE2.js} +11 -9
- package/chunks/{read-mcp-resource-D3N75DGF.js → read-mcp-resource-B37WANAQ.js} +1 -1
- package/chunks/{record-artifact-Q5CRGJTP.js → record-artifact-OAXWXZ5D.js} +2 -2
- package/chunks/record-source-D7R7X3GT.js +22 -0
- package/chunks/{report-findings-TJ34R7QK.js → report-findings-AR3VC6EQ.js} +3 -3
- package/chunks/{request-shutdown-LRKMTBAD.js → request-shutdown-IKNWTX5M.js} +5 -5
- package/chunks/{resumeHistoryUtils-YQQ43E4N.js → resumeHistoryUtils-QLKDH5GY.js} +63 -56
- package/chunks/{ripGrep-W32NWFTA.js → ripGrep-YGWL7KCV.js} +15 -13
- package/chunks/{run-qwen-serve-WBSWWIRV.js → run-qwen-serve-26KZDECC.js} +127 -102
- package/chunks/{runtime-VRVBX2E5.js → runtime-BMEIVDDG.js} +70 -63
- package/chunks/{scheduled-tasks-D65KJDA3.js → scheduled-tasks-NCFPP6VQ.js} +64 -57
- package/chunks/{scheduler-M2YPN7Z7.js → scheduler-47TVMUVN.js} +59 -52
- package/chunks/{sdk-exporters-grpc-MXTVSE3C.js → sdk-exporters-grpc-Y2ZUQDUQ.js} +2 -2
- package/chunks/{sdk-exporters-http-7R2ARBPV.js → sdk-exporters-http-VWTF4W6K.js} +3 -3
- package/chunks/{sdk-impl-YOLO7LV4.js → sdk-impl-G6FVTBQZ.js} +9 -9
- package/chunks/{send-message-76BKWKFZ.js → send-message-TWOGWCBG.js} +12 -9
- package/chunks/{serve-BE3H2P6P.js → serve-KL3G6LQQ.js} +64 -57
- package/chunks/{server-FLY5JERG.js → server-LBPYXZ5G.js} +2931 -518
- package/chunks/{session-JVN62R5K.js → session-YG6742LO.js} +118 -111
- package/chunks/{session-attachments-root-7ACGLHXA.js → session-attachments-root-OUBQDYC4.js} +57 -50
- package/chunks/{session-pr-refresh-TQS57SDK.js → session-pr-refresh-EKGMYNAW.js} +64 -57
- package/chunks/{settings-D44YMZFT.js → settings-DDNHJX2L.js} +69 -62
- package/chunks/{shell-3VE6I4V5.js → shell-KUCXWITU.js} +42 -36
- package/chunks/{skill-FHEGRRZU.js → skill-JQLKPNWZ.js} +33 -23
- package/chunks/{skill-settings-VHEJMBFL.js → skill-settings-XERQCUXZ.js} +63 -56
- package/chunks/{spawnChannel-T6MX2ZDN.js → spawnChannel-GQ45QFGB.js} +60 -53
- package/chunks/{standalone-update-QUGHFMCS.js → standalone-update-PRF3ILGZ.js} +59 -52
- package/chunks/{start-opentui-ui-IHIIZ2LE.js → start-opentui-ui-JDSOZE3N.js} +174 -157
- package/chunks/{startInteractiveUI-LR7K2ARZ.js → startInteractiveUI-RRW3JVHN.js} +533 -1119
- package/chunks/{syntheticOutput-D2P5V6RG.js → syntheticOutput-F6F27JMK.js} +2 -2
- package/chunks/{task-create-MWXJFRRM.js → task-create-Y623TBHB.js} +8 -8
- package/chunks/{task-list-EYO3FE57.js → task-list-FCPEEGWL.js} +1 -1
- package/chunks/{task-stop-BFSKRTGV.js → task-stop-QTKZXLPH.js} +1 -1
- package/chunks/{task-update-2JJJRHMT.js → task-update-YLSXF25N.js} +8 -8
- package/chunks/{team-create-GY3VFY47.js → team-create-5DRLOLOE.js} +44 -38
- package/chunks/{team-delete-IQZ6XGFI.js → team-delete-S7TLHZCF.js} +1 -1
- package/chunks/{team-plan-approval-BQPGZOT5.js → team-plan-approval-MWSGAL5T.js} +42 -36
- package/chunks/{terminal-image-renderer-YNYW5CQG.js → terminal-image-renderer-H7PD4FQW.js} +59 -52
- package/chunks/{theme-manager-U6CIK3GM.js → theme-manager-7AV73D6R.js} +57 -50
- package/chunks/{todoWrite-5ERKFWAK.js → todoWrite-5QI2H2FW.js} +4 -4
- package/chunks/{tool-search-XI3QWD5I.js → tool-search-UGYTBLUV.js} +17 -15
- package/chunks/{total-session-admission-3SNSJJ32.js → total-session-admission-JIHSTJ5S.js} +62 -55
- package/chunks/{trustedFolders-OVAQKNV5.js → trustedFolders-5VCBXFOP.js} +58 -51
- package/chunks/{update-relaunch-XV5O74E3.js → update-relaunch-4LF3APCV.js} +5 -5
- package/chunks/{updateCheck-CHUYWD6L.js → updateCheck-4T3WUE5F.js} +59 -52
- package/chunks/{useAutoAcceptIndicator-VKSVIXZC.js → useAutoAcceptIndicator-UMGB64Z6.js} +67 -60
- package/chunks/{validateNonInterActiveAuth-ZNUTD3E5.js → validateNonInterActiveAuth-GFJ72U2C.js} +107 -100
- package/chunks/{version-EK7VAGSI.js → version-EAAZN4T2.js} +1 -1
- package/chunks/{web-fetch-24KZO763.js → web-fetch-VRU3A2NI.js} +13 -11
- package/chunks/{web-search-CRNXKZ2X.js → web-search-NEGYQNDJ.js} +14 -10
- package/chunks/{web-shell-static-BFDESDD4.js → web-shell-static-CCN4JZEE.js} +1 -1
- package/chunks/workflow-UHPFALVZ.js +1224 -0
- package/chunks/{workspace-providers-status-MAM42IZS.js → workspace-providers-status-AEYISSU2.js} +68 -61
- package/chunks/{workspace-registration-store-HKLJEDQX.js → workspace-registration-store-A7RGKW62.js} +3 -1
- package/chunks/{workspace-registry-7RDDOBLN.js → workspace-registry-C2NGE6SD.js} +62 -55
- package/chunks/{workspace-runtime-coordinator-LEPDPXJO.js → workspace-runtime-coordinator-QKMZ24YF.js} +63 -56
- package/chunks/{workspace-service-5IFDCNN3.js → workspace-service-RQTTAGGC.js} +70 -63
- package/chunks/{workspace-skills-status-FJ3HNH4H.js → workspace-skills-status-5HWZU3HX.js} +65 -58
- package/chunks/{workspace-trust-reconciler-PQFHIWLR.js → workspace-trust-reconciler-KFWATZUU.js} +69 -62
- package/chunks/{write-file-ERG67ZFX.js → write-file-DPVB2SBQ.js} +44 -38
- package/chunks/{zh-VBFCRQBL.js → zh-S5V3Z5CR.js} +1 -0
- package/chunks/{zh-TW-N2TBF2F2.js → zh-TW-2K2WRFPY.js} +1 -0
- package/chunks/{zoom-image-WQYEC3SR.js → zoom-image-S7AWLAPC.js} +12 -10
- package/cli.js +13 -13
- package/export-transcript-document.css +1 -0
- package/export-transcript-document.js +164 -165
- package/locales/en.js +1 -0
- package/locales/zh-TW.js +1 -0
- package/locales/zh.js +1 -0
- package/package.json +5 -4
- package/web-shell/assets/{abnfDiagram-VCTEODGH-BRLgQbnT.js → abnfDiagram-VCTEODGH-nU24rpIE.js} +1 -1
- package/web-shell/assets/{arc-qAF9_XsR.js → arc-D1hTu8QI.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-BorUttEz.js → architectureDiagram-5GKGNRK7-B_fgkKe7.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-Bj0qZVxu.js → blockDiagram-NRAW4CY4-C3pddUNg.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-BTqJis32.js → c4Diagram-UCG6FXSJ-kEFoC1ei.js} +1 -1
- package/web-shell/assets/channel-Blod4z1X.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-RrQ5X8m-.js → chunk-2Q5K7J3B-DbT9wS7j.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-uUjDl8wO.js → chunk-5VM5RSS4-CNbULt6O.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-C3JhpyzI.js → chunk-F27PBJKO-CbQRy4Tb.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-C8ZNFs7F.js → chunk-G27WJ6UU-CVbXTxYk.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-DNpXtEOs.js → chunk-JWPE2WC7-D89c_BXy.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-DagA2ZLw.js → chunk-LCL6LL3I-B7-I_9KB.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-R23uH7Xm.js → chunk-POPQ4Y6H-DcLQFzS4.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-Qz9RN_BR.js → chunk-SVP7TREG-DyBb2Axj.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-jYb1_hni.js → chunk-XXDRQBXY-BIA0eb5B.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-D6hFDMqb.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-D6hFDMqb.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-Cv2OunpE.js → cose-bilkent-JH36ORCC-Db2FYN85.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-LH42KFJx.js → cynefin-OW5HDTMX-i4GwmBVy.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-Dha4_OoR.js → cynefinDiagram-5FMLGOSQ-LENf_IUy.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-Br5lnUKD.js → dagre-3AP2YEHR-CF9XVrD9.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-dpKq2bBX.js → diagram-S7CK7UJ4-DD5PJfSm.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-BAgHWpXr.js → diagram-UQ7AKVKN-CjD_sBMj.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-GRRzpyE2.js → diagram-VSXAHHWV-U5WwMqyA.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-BNFiaYpG.js → diagram-VX7I27RA-BujpHJJf.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-BisZzB_h.js → diagram-Z3DM3KII-3ZLtKEXo.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-B1xbwycf.js → ebnfDiagram-PWID7BFC-BGpiquRm.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-CQMzbGE5.js → erDiagram-SSCWMZ5O-D0besu_U.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-CZ_Zondl.js → flowDiagram-A5DVABFB-9DwDuIyr.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-BTh2ShxS.js → ganttDiagram-EL5Y4UJY-CNlsAeNr.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-oHOB-Uxt.js → gitGraphDiagram-WWUBYQGX-C_pPFiTR.js} +1 -1
- package/web-shell/assets/{index-DWoFMu5x.js → index-BYWs4JWq.js} +1 -1
- package/web-shell/assets/index-D3YS6KuJ.js +2173 -0
- package/web-shell/assets/index-eBxK3rs2.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-C0QpudbG.js → infoDiagram-RXCK75RN-Bpai64Ll.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-a6B741uT.js → ishikawaDiagram-5VMMS53U-ktpJFq4r.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-Dbht9ICp.js → journeyDiagram-EYS64GPL-iz_DKgFX.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-D4OFR8-h.js → kanban-definition-3QL26DDD-m_gG00Yt.js} +1 -1
- package/web-shell/assets/{layout-Dvdh5jRH.js → layout-qEvKgnvU.js} +1 -1
- package/web-shell/assets/{linear-Dvc6KIW2.js → linear-C6lklGdq.js} +1 -1
- package/web-shell/assets/{mermaid.core-CB36RfIb.js → mermaid.core-DSCYB_2P.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-Fmqo1CjP.js → mindmap-definition-FBJOCRG2-DRQbT8w-.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-CCxYBoA4.js → pegDiagram-XKGWAZYB-BhD0q0i6.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-BVHKQFzt.js → pieDiagram-E7YTZNPT-BvIGQCSd.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-l95IznwR.js → quadrantDiagram-AXDQQJYC-BDQtfpU-.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-BlLdRdXp.js → railroadDiagram-O6MQD6OU-E1g2KIFK.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-BkDLBR5w.js → requirementDiagram-EFPCY7ZU-CuerYJOe.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-jAIqRp65.js → sankeyDiagram-P5KCCOFB-CqWyCZGA.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-f-soZYPr.js → sequenceDiagram-WJ2MYXX4-B-YWb8x4.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-BzOuAfB2.js → sizeCapture-X5ZJPWSS-BB7YY4Tl.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-BPLSs12r.js → stateDiagram-HBIQ2CUA-C8LDpNHS.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-C4CbdvGa.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-D-9E_RIR.js → swimlanes-XN3QIQJK-D94vOoxZ.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN--QNSIOC8.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-CT56K-gV.js → timeline-definition-24CTP7MA-C9C8uEYm.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-B-vi4IyO.js → vennDiagram-4TSXK5OY-CYzMHbVW.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-C9O7Ju98.js → wardleyDiagram-VM6X3IG4-G9nhtLES.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-6d8w3jg2.js → xychartDiagram-S5SC5T6Z-ruD2Wjhg.js} +1 -1
- package/web-shell/index.html +29 -5
- package/chunks/chunk-V7RNNPGC.js +0 -44
- package/chunks/workflow-HD5NYMW5.js +0 -2907
- package/web-shell/assets/channel-COIuCrVH.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DoX6OYqu.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DoX6OYqu.js +0 -1
- package/web-shell/assets/index-CI1ysIEv.js +0 -2154
- package/web-shell/assets/index-CpxXGH-8.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-IRul-LaT.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-D6lgKepA.js +0 -8
- /package/chunks/{chunk-JA5CBKRP.js → chunk-7NXSVSFB.js} +0 -0
|
@@ -0,0 +1,1224 @@
|
|
|
1
|
+
// Force strict mode and setup for ESM
|
|
2
|
+
"use strict";
|
|
3
|
+
import {
|
|
4
|
+
DEFAULT_MAX_AGENTS_PER_RUN,
|
|
5
|
+
DEFAULT_STALL_MS,
|
|
6
|
+
DEFAULT_WORKFLOW_SUBAGENT_MAX_TIME_MINUTES,
|
|
7
|
+
DEFAULT_WORKFLOW_SUBAGENT_MAX_TURNS,
|
|
8
|
+
MAX_STALL_ATTEMPTS,
|
|
9
|
+
MAX_TOKENS_PER_WORKFLOW_ENV,
|
|
10
|
+
MAX_WORKFLOW_AGENTS_ENV,
|
|
11
|
+
MAX_WORKFLOW_CONCURRENCY_ENV,
|
|
12
|
+
MAX_WORKFLOW_STALL_MS_ENV,
|
|
13
|
+
WORKFLOW_SUBAGENT_MAX_MINUTES_ENV,
|
|
14
|
+
WORKFLOW_SUBAGENT_MAX_TURNS_ENV,
|
|
15
|
+
WorkflowBudgetImpl,
|
|
16
|
+
WorkflowDispatchScheduler,
|
|
17
|
+
WorkflowExecutionError,
|
|
18
|
+
WorkflowJournal,
|
|
19
|
+
WorkflowOrchestrator,
|
|
20
|
+
compileWorkflowScript,
|
|
21
|
+
createProductionDispatch,
|
|
22
|
+
deleteInlineWorkflowScript,
|
|
23
|
+
describeWorkflowCompileError,
|
|
24
|
+
extractAndStripMeta,
|
|
25
|
+
isSymlinkedRoot,
|
|
26
|
+
persistInlineWorkflowScript,
|
|
27
|
+
resolveConcurrencyLimit,
|
|
28
|
+
resolveMaxTokensPerWorkflow,
|
|
29
|
+
resolveReviewWorkflowLimits,
|
|
30
|
+
resolveSavedWorkflowScript,
|
|
31
|
+
writeWorkflowSnapshot
|
|
32
|
+
} from "./chunk-UKZ45TJL.js";
|
|
33
|
+
import {
|
|
34
|
+
RESUME_ARGS_TOO_LARGE_NOTE,
|
|
35
|
+
buildFailureLines,
|
|
36
|
+
buildResumeCall,
|
|
37
|
+
getRuleDisplayName,
|
|
38
|
+
getWorkflowTaskMutationKey,
|
|
39
|
+
hasUninlinableResumeArgs,
|
|
40
|
+
isTerminalWorkflowStatus,
|
|
41
|
+
markWorkflowRunPersistenceActive,
|
|
42
|
+
resolveToolName,
|
|
43
|
+
tryWithWorkflowTaskMutation
|
|
44
|
+
} from "./chunk-N7VWZDWW.js";
|
|
45
|
+
import "./chunk-GOFAQQZA.js";
|
|
46
|
+
import "./chunk-TWPJO254.js";
|
|
47
|
+
import "./chunk-CQ35AJ4Z.js";
|
|
48
|
+
import "./chunk-65I7S4Z3.js";
|
|
49
|
+
import "./chunk-6HUXPLB5.js";
|
|
50
|
+
import "./chunk-7CLLH5TI.js";
|
|
51
|
+
import "./chunk-XKBFYTCD.js";
|
|
52
|
+
import "./chunk-ZTTC7T4X.js";
|
|
53
|
+
import "./chunk-E4UEO3XM.js";
|
|
54
|
+
import "./chunk-IAEXTMED.js";
|
|
55
|
+
import "./chunk-IRH27ZC2.js";
|
|
56
|
+
import "./chunk-QHWCP53L.js";
|
|
57
|
+
import "./chunk-F53KKZUD.js";
|
|
58
|
+
import "./chunk-O6GEWCJA.js";
|
|
59
|
+
import "./chunk-36HCNKDS.js";
|
|
60
|
+
import "./chunk-6PVPNMXU.js";
|
|
61
|
+
import "./chunk-2SZH22YO.js";
|
|
62
|
+
import "./chunk-DTNV6UZY.js";
|
|
63
|
+
import "./chunk-QJNDUTOL.js";
|
|
64
|
+
import "./chunk-JXNIF2O5.js";
|
|
65
|
+
import "./chunk-NFYEQRLG.js";
|
|
66
|
+
import "./chunk-ELRMZTPF.js";
|
|
67
|
+
import "./chunk-CHEIIBT3.js";
|
|
68
|
+
import "./chunk-PLLIWEM3.js";
|
|
69
|
+
import "./chunk-5GLDOLNQ.js";
|
|
70
|
+
import "./chunk-CH2YDT6X.js";
|
|
71
|
+
import "./chunk-JX6XHPTX.js";
|
|
72
|
+
import "./chunk-ZSTCM3MX.js";
|
|
73
|
+
import "./chunk-MLXTMF7H.js";
|
|
74
|
+
import "./chunk-LILGKQ4B.js";
|
|
75
|
+
import "./chunk-3CZ2BQV6.js";
|
|
76
|
+
import "./chunk-SAH4BD2J.js";
|
|
77
|
+
import "./chunk-CXTPVBFA.js";
|
|
78
|
+
import "./chunk-U7O65WKL.js";
|
|
79
|
+
import "./chunk-S6LOFUVP.js";
|
|
80
|
+
import "./chunk-FN3JNDRU.js";
|
|
81
|
+
import "./chunk-EUURTIV6.js";
|
|
82
|
+
import "./chunk-G6UUOCUT.js";
|
|
83
|
+
import "./chunk-IZ2U57NY.js";
|
|
84
|
+
import "./chunk-NUQ4GK5I.js";
|
|
85
|
+
import "./chunk-K2OJUPOE.js";
|
|
86
|
+
import "./chunk-NAVJD2PQ.js";
|
|
87
|
+
import "./chunk-YBUMTY7B.js";
|
|
88
|
+
import "./chunk-HNLMYDQE.js";
|
|
89
|
+
import "./chunk-QHMLYMMS.js";
|
|
90
|
+
import "./chunk-CFKIH3D3.js";
|
|
91
|
+
import "./chunk-JL6APGBX.js";
|
|
92
|
+
import {
|
|
93
|
+
createAbortController,
|
|
94
|
+
createChildAbortController
|
|
95
|
+
} from "./chunk-DJ2GSRLV.js";
|
|
96
|
+
import "./chunk-4ALNJDHL.js";
|
|
97
|
+
import "./chunk-NOO4QFXM.js";
|
|
98
|
+
import "./chunk-KFFCDLKV.js";
|
|
99
|
+
import "./chunk-ZW2EUO2A.js";
|
|
100
|
+
import {
|
|
101
|
+
WorkflowRunEvent,
|
|
102
|
+
logWorkflowRun
|
|
103
|
+
} from "./chunk-HBU7EKY4.js";
|
|
104
|
+
import "./chunk-5ETULJLP.js";
|
|
105
|
+
import "./chunk-ZHKTKHMO.js";
|
|
106
|
+
import "./chunk-VGC4I5JJ.js";
|
|
107
|
+
import "./chunk-EDIDYZBT.js";
|
|
108
|
+
import "./chunk-HD7O6WLV.js";
|
|
109
|
+
import {
|
|
110
|
+
isWithinRoot
|
|
111
|
+
} from "./chunk-J6MB5ZHZ.js";
|
|
112
|
+
import "./chunk-WZAD4ZNJ.js";
|
|
113
|
+
import "./chunk-3FPYT6QC.js";
|
|
114
|
+
import "./chunk-FPGTNKCP.js";
|
|
115
|
+
import "./chunk-TIGXX4PA.js";
|
|
116
|
+
import "./chunk-3UXUOFO6.js";
|
|
117
|
+
import "./chunk-XFFRI3WM.js";
|
|
118
|
+
import "./chunk-ERU3SDXT.js";
|
|
119
|
+
import "./chunk-EWJTAP3Y.js";
|
|
120
|
+
import "./chunk-HHJLM3WQ.js";
|
|
121
|
+
import {
|
|
122
|
+
stripAnsiAndControl
|
|
123
|
+
} from "./chunk-W5ZQMAEM.js";
|
|
124
|
+
import "./chunk-74TONY4F.js";
|
|
125
|
+
import "./chunk-HUXPEUFL.js";
|
|
126
|
+
import {
|
|
127
|
+
BaseDeclarativeTool,
|
|
128
|
+
BaseToolInvocation,
|
|
129
|
+
ToolDisplayNames,
|
|
130
|
+
ToolNames
|
|
131
|
+
} from "./chunk-TP6FYVQT.js";
|
|
132
|
+
import "./chunk-ZAFYHRVY.js";
|
|
133
|
+
import "./chunk-TBWQLLFO.js";
|
|
134
|
+
import "./chunk-UKMWZ5NS.js";
|
|
135
|
+
import "./chunk-75DOP5OR.js";
|
|
136
|
+
import "./chunk-DMTGGOSA.js";
|
|
137
|
+
import "./chunk-YQ3U5MUC.js";
|
|
138
|
+
import "./chunk-MATEIJZF.js";
|
|
139
|
+
import {
|
|
140
|
+
init_esbuild_shims
|
|
141
|
+
} from "./chunk-5O2XNYP6.js";
|
|
142
|
+
import {
|
|
143
|
+
__name
|
|
144
|
+
} from "./chunk-J2S4EL5Y.js";
|
|
145
|
+
|
|
146
|
+
// packages/core/src/tools/workflow/workflow.ts
|
|
147
|
+
init_esbuild_shims();
|
|
148
|
+
|
|
149
|
+
// packages/core/src/agents/runtime/workflow-runner.ts
|
|
150
|
+
init_esbuild_shims();
|
|
151
|
+
import { randomBytes } from "node:crypto";
|
|
152
|
+
var WorkflowRunHandle = class {
|
|
153
|
+
constructor(runId, budget, registry, controller, scheduler, start, locations = {}) {
|
|
154
|
+
this.runId = runId;
|
|
155
|
+
this.budget = budget;
|
|
156
|
+
this.registry = registry;
|
|
157
|
+
this.controller = controller;
|
|
158
|
+
this.scheduler = scheduler;
|
|
159
|
+
this.scriptPath = locations.scriptPath;
|
|
160
|
+
this.journalPath = locations.journalPath;
|
|
161
|
+
this.completion = Promise.resolve().then(start);
|
|
162
|
+
}
|
|
163
|
+
static {
|
|
164
|
+
__name(this, "WorkflowRunHandle");
|
|
165
|
+
}
|
|
166
|
+
completion;
|
|
167
|
+
/**
|
|
168
|
+
* Where this run's script lives on disk: the file a `{scriptPath}` launch
|
|
169
|
+
* loaded, or the persisted copy of an inline `{script}`. `undefined` when
|
|
170
|
+
* an inline script could not be persisted (no `storage`, symlinked root,
|
|
171
|
+
* write failure) — callers report the run without it rather than naming a
|
|
172
|
+
* path that does not exist.
|
|
173
|
+
*/
|
|
174
|
+
scriptPath;
|
|
175
|
+
/** This run's resume journal, when the config has a `storage` to hold one. */
|
|
176
|
+
journalPath;
|
|
177
|
+
abort() {
|
|
178
|
+
this.controller.abort();
|
|
179
|
+
}
|
|
180
|
+
pause() {
|
|
181
|
+
return this.scheduler.pause();
|
|
182
|
+
}
|
|
183
|
+
resume() {
|
|
184
|
+
return this.scheduler.resume();
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
var WorkflowScriptNotLaunchedError = class extends Error {
|
|
188
|
+
constructor(detail) {
|
|
189
|
+
super(
|
|
190
|
+
`Workflow script is invalid and was not launched:
|
|
191
|
+
${detail}
|
|
192
|
+
|
|
193
|
+
Workflow scripts must be plain JavaScript \u2014 the usual causes are TypeScript syntax (type annotations, interfaces, generics) and broken string quoting or escaping. Metadata must use literal values.`
|
|
194
|
+
);
|
|
195
|
+
this.detail = detail;
|
|
196
|
+
this.name = "WorkflowScriptNotLaunchedError";
|
|
197
|
+
}
|
|
198
|
+
static {
|
|
199
|
+
__name(this, "WorkflowScriptNotLaunchedError");
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
var WorkflowStartCancelledError = class extends Error {
|
|
203
|
+
static {
|
|
204
|
+
__name(this, "WorkflowStartCancelledError");
|
|
205
|
+
}
|
|
206
|
+
constructor() {
|
|
207
|
+
super("Workflow start was cancelled.");
|
|
208
|
+
this.name = "WorkflowStartCancelledError";
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
var WorkflowRunner = class {
|
|
212
|
+
static {
|
|
213
|
+
__name(this, "WorkflowRunner");
|
|
214
|
+
}
|
|
215
|
+
static async start(options) {
|
|
216
|
+
if (options.resumeFromRunId) {
|
|
217
|
+
const attempt = await tryWithWorkflowTaskMutation(
|
|
218
|
+
getWorkflowTaskMutationKey(options.config, options.resumeFromRunId),
|
|
219
|
+
() => this.startClaimed(options)
|
|
220
|
+
);
|
|
221
|
+
if (!attempt.acquired) {
|
|
222
|
+
throw new Error(
|
|
223
|
+
`Workflow run ${options.resumeFromRunId} is already being modified.`
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
return attempt.value;
|
|
227
|
+
}
|
|
228
|
+
return this.startClaimed(options);
|
|
229
|
+
}
|
|
230
|
+
static async startClaimed(options) {
|
|
231
|
+
const config = options.config;
|
|
232
|
+
const runInBackground = options.runInBackground === true;
|
|
233
|
+
const budget = WorkflowBudgetImpl.fromEnv();
|
|
234
|
+
const runId = options.resumeFromRunId ?? `wf_${randomBytes(8).toString("hex")}`;
|
|
235
|
+
const registry = config.getWorkflowRunRegistry?.();
|
|
236
|
+
let entry;
|
|
237
|
+
const isCurrentEntry = /* @__PURE__ */ __name(() => registry === void 0 || entry !== void 0 && registry.get(runId) === entry, "isCurrentEntry");
|
|
238
|
+
const createController = /* @__PURE__ */ __name(() => runInBackground ? createAbortController() : createChildAbortController(options.signal), "createController");
|
|
239
|
+
const controller = registry ? registry.reserveStart(runId, createController) : createController();
|
|
240
|
+
const releasePersistenceActivity = markWorkflowRunPersistenceActive(
|
|
241
|
+
config,
|
|
242
|
+
runId
|
|
243
|
+
);
|
|
244
|
+
const assertStartNotCancelled = /* @__PURE__ */ __name(() => {
|
|
245
|
+
if (controller.signal.aborted && !options.signal.aborted) {
|
|
246
|
+
throw new WorkflowStartCancelledError();
|
|
247
|
+
}
|
|
248
|
+
if (runInBackground && options.signal.aborted) {
|
|
249
|
+
throw new WorkflowStartCancelledError();
|
|
250
|
+
}
|
|
251
|
+
}, "assertStartNotCancelled");
|
|
252
|
+
const storage = config.storage;
|
|
253
|
+
const previousEntry = registry?.get(runId);
|
|
254
|
+
let journalPath = storage ? storage.getWorkflowRunJournalPath(runId) : void 0;
|
|
255
|
+
const journal = journalPath ? new WorkflowJournal(journalPath, storage.getWorkflowRunsDir()) : void 0;
|
|
256
|
+
let script;
|
|
257
|
+
let scriptPath;
|
|
258
|
+
let resumeReplay;
|
|
259
|
+
let persistedInlineScript = false;
|
|
260
|
+
let callerWasAbortedBeforeStart;
|
|
261
|
+
let orchestrator;
|
|
262
|
+
let reviewLimits;
|
|
263
|
+
try {
|
|
264
|
+
const loaded = options.scriptPath && options.script === void 0 ? await resolveSavedWorkflowScript(
|
|
265
|
+
{ scriptPath: options.scriptPath },
|
|
266
|
+
config
|
|
267
|
+
) : void 0;
|
|
268
|
+
script = loaded?.script ?? options.script ?? "";
|
|
269
|
+
scriptPath = loaded?.scriptPath ?? options.scriptPath;
|
|
270
|
+
if (loaded && scriptPath && storage) {
|
|
271
|
+
reviewLimits = await resolveReviewWorkflowLimits(
|
|
272
|
+
scriptPath,
|
|
273
|
+
storage.getGeneratedWorkflowsDir(),
|
|
274
|
+
script
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
const workflowName = options.workflowName ?? loaded?.savedWorkflowName ?? registry?.get(runId)?.workflowName;
|
|
278
|
+
try {
|
|
279
|
+
compileWorkflowScript(script);
|
|
280
|
+
} catch (error) {
|
|
281
|
+
throw new WorkflowScriptNotLaunchedError(
|
|
282
|
+
describeWorkflowCompileError(
|
|
283
|
+
error,
|
|
284
|
+
script.split(/\r\n|[\n\r\u2028\u2029]/).length
|
|
285
|
+
)
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
resumeReplay = options.resumeFromRunId ? await journal?.load() : void 0;
|
|
289
|
+
assertStartNotCancelled();
|
|
290
|
+
callerWasAbortedBeforeStart = options.signal.aborted;
|
|
291
|
+
if (options.script !== void 0 && scriptPath === void 0) {
|
|
292
|
+
const persisted = await persistInlineWorkflowScript(
|
|
293
|
+
config,
|
|
294
|
+
runId,
|
|
295
|
+
script
|
|
296
|
+
);
|
|
297
|
+
scriptPath = persisted ?? void 0;
|
|
298
|
+
persistedInlineScript = persisted !== null;
|
|
299
|
+
}
|
|
300
|
+
if (journal && !await journal.ensureExists()) {
|
|
301
|
+
journalPath = void 0;
|
|
302
|
+
}
|
|
303
|
+
assertStartNotCancelled();
|
|
304
|
+
const dispatch = options.dispatch ?? createProductionDispatch(
|
|
305
|
+
config,
|
|
306
|
+
controller.signal,
|
|
307
|
+
(outputTokens) => budget.recordSpent(outputTokens),
|
|
308
|
+
registry ? (emitter2, dispatchId) => isCurrentEntry() ? registry.bridgeApprovalEvents(
|
|
309
|
+
runId,
|
|
310
|
+
emitter2,
|
|
311
|
+
dispatchId,
|
|
312
|
+
entry
|
|
313
|
+
) : () => void 0 : void 0,
|
|
314
|
+
reviewLimits?.subagent
|
|
315
|
+
);
|
|
316
|
+
orchestrator = new WorkflowOrchestrator(dispatch);
|
|
317
|
+
entry = registry?.register(
|
|
318
|
+
{
|
|
319
|
+
runId,
|
|
320
|
+
toolUseId: options.toolUseId,
|
|
321
|
+
...workflowName ? { workflowName } : {},
|
|
322
|
+
meta: null,
|
|
323
|
+
status: "running",
|
|
324
|
+
startTime: Date.now(),
|
|
325
|
+
outputFile: "",
|
|
326
|
+
abortController: controller,
|
|
327
|
+
tokenBudgetTotal: budget.total,
|
|
328
|
+
script,
|
|
329
|
+
scriptPath,
|
|
330
|
+
...journalPath ? { journalPath } : {},
|
|
331
|
+
args: options.args,
|
|
332
|
+
...options.resumeFromRunId ? {
|
|
333
|
+
sourceRunId: options.resumeFromRunId,
|
|
334
|
+
startMode: "retry"
|
|
335
|
+
} : {},
|
|
336
|
+
isBackgrounded: runInBackground,
|
|
337
|
+
resumeInBackground: runInBackground && config.isInteractive?.() === true && config.getExperimentalZedIntegration?.() !== true
|
|
338
|
+
},
|
|
339
|
+
controller
|
|
340
|
+
);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
registry?.releaseStart(runId, controller);
|
|
343
|
+
controller.abort();
|
|
344
|
+
if (persistedInlineScript && options.resumeFromRunId === void 0) {
|
|
345
|
+
await deleteInlineWorkflowScript(config, runId);
|
|
346
|
+
}
|
|
347
|
+
if (persistedInlineScript && options.resumeFromRunId && previousEntry) {
|
|
348
|
+
await persistInlineWorkflowScript(config, runId, previousEntry.script);
|
|
349
|
+
}
|
|
350
|
+
if (options.resumeFromRunId === void 0) {
|
|
351
|
+
await journal?.remove();
|
|
352
|
+
}
|
|
353
|
+
releasePersistenceActivity();
|
|
354
|
+
throw error;
|
|
355
|
+
}
|
|
356
|
+
const emitUpdate = /* @__PURE__ */ __name(() => {
|
|
357
|
+
if (!entry || !options.onUpdate || !isCurrentEntry()) return;
|
|
358
|
+
try {
|
|
359
|
+
options.onUpdate(entry);
|
|
360
|
+
} catch {
|
|
361
|
+
}
|
|
362
|
+
}, "emitUpdate");
|
|
363
|
+
const emitter = {
|
|
364
|
+
phaseStarted: /* @__PURE__ */ __name((title) => {
|
|
365
|
+
if (!isCurrentEntry()) return;
|
|
366
|
+
registry?.onPhaseStarted(runId, title);
|
|
367
|
+
emitUpdate();
|
|
368
|
+
}, "phaseStarted"),
|
|
369
|
+
agentDispatched: /* @__PURE__ */ __name(() => {
|
|
370
|
+
if (!isCurrentEntry()) return;
|
|
371
|
+
registry?.onAgentDispatched(runId);
|
|
372
|
+
emitUpdate();
|
|
373
|
+
}, "agentDispatched"),
|
|
374
|
+
agentCompleted: /* @__PURE__ */ __name(() => {
|
|
375
|
+
if (!isCurrentEntry()) return;
|
|
376
|
+
registry?.onAgentCompleted(runId);
|
|
377
|
+
}, "agentCompleted"),
|
|
378
|
+
dispatchQueued: /* @__PURE__ */ __name((event) => {
|
|
379
|
+
if (!isCurrentEntry()) return;
|
|
380
|
+
registry?.onDispatchQueued(runId, event);
|
|
381
|
+
emitUpdate();
|
|
382
|
+
}, "dispatchQueued"),
|
|
383
|
+
dispatchStarted: /* @__PURE__ */ __name((dispatchId, startedAt) => {
|
|
384
|
+
if (!isCurrentEntry()) return;
|
|
385
|
+
registry?.onDispatchStarted(runId, dispatchId, startedAt);
|
|
386
|
+
emitUpdate();
|
|
387
|
+
}, "dispatchStarted"),
|
|
388
|
+
dispatchSettled: /* @__PURE__ */ __name((dispatchId, error, endedAt) => {
|
|
389
|
+
if (!isCurrentEntry()) return;
|
|
390
|
+
registry?.onDispatchSettled(
|
|
391
|
+
runId,
|
|
392
|
+
dispatchId,
|
|
393
|
+
error,
|
|
394
|
+
endedAt,
|
|
395
|
+
!runInBackground && options.signal.aborted
|
|
396
|
+
);
|
|
397
|
+
emitUpdate();
|
|
398
|
+
}, "dispatchSettled"),
|
|
399
|
+
// The registry records this without firing a status update, avoiding a
|
|
400
|
+
// TUI redraw per line while retaining the real replay timestamp.
|
|
401
|
+
logAppended: /* @__PURE__ */ __name((line) => {
|
|
402
|
+
if (!isCurrentEntry()) return;
|
|
403
|
+
registry?.onLogAppended(runId, line);
|
|
404
|
+
}, "logAppended"),
|
|
405
|
+
budgetUpdated: /* @__PURE__ */ __name((spent, total) => {
|
|
406
|
+
if (!isCurrentEntry()) return;
|
|
407
|
+
registry?.onBudgetUpdated(runId, spent, total);
|
|
408
|
+
emitUpdate();
|
|
409
|
+
}, "budgetUpdated"),
|
|
410
|
+
resumeRespawn: /* @__PURE__ */ __name((line) => {
|
|
411
|
+
if (!isCurrentEntry()) return;
|
|
412
|
+
registry?.onResumeRespawn(runId, line);
|
|
413
|
+
emitUpdate();
|
|
414
|
+
}, "resumeRespawn")
|
|
415
|
+
};
|
|
416
|
+
const scheduler = new WorkflowDispatchScheduler(
|
|
417
|
+
reviewLimits?.concurrency ?? resolveConcurrencyLimit(),
|
|
418
|
+
controller.signal,
|
|
419
|
+
({ state }) => {
|
|
420
|
+
if (!isCurrentEntry()) return;
|
|
421
|
+
registry?.onDispatchStateChange(runId, state);
|
|
422
|
+
}
|
|
423
|
+
);
|
|
424
|
+
const handle = new WorkflowRunHandle(
|
|
425
|
+
runId,
|
|
426
|
+
budget,
|
|
427
|
+
registry,
|
|
428
|
+
controller,
|
|
429
|
+
scheduler,
|
|
430
|
+
async () => {
|
|
431
|
+
try {
|
|
432
|
+
const outcome = await orchestrator.run({
|
|
433
|
+
script,
|
|
434
|
+
args: options.args,
|
|
435
|
+
maxWallClockMs: reviewLimits?.maxWallClockMs,
|
|
436
|
+
abortOnTimeout: controller,
|
|
437
|
+
runId,
|
|
438
|
+
emitter,
|
|
439
|
+
budget,
|
|
440
|
+
resolveSavedWorkflow: /* @__PURE__ */ __name((ref) => resolveSavedWorkflowScript(ref, config), "resolveSavedWorkflow"),
|
|
441
|
+
journal,
|
|
442
|
+
resumeReplay,
|
|
443
|
+
scheduler
|
|
444
|
+
});
|
|
445
|
+
if (entry) {
|
|
446
|
+
entry.meta = outcome.meta;
|
|
447
|
+
if (outcome.meta?.name && entry.description === runId) {
|
|
448
|
+
entry.description = outcome.meta.name;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
registry?.setRecentLogs(runId, outcome.logs);
|
|
452
|
+
if (entry && isTerminalWorkflowStatus(entry.status)) {
|
|
453
|
+
return {
|
|
454
|
+
ok: false,
|
|
455
|
+
message: entry.status === "cancelled" ? "Workflow run cancelled." : entry.error ?? "Workflow run failed."
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
registry?.complete(runId, outcome.result, Date.now());
|
|
459
|
+
return { ok: true, outcome };
|
|
460
|
+
} catch (error) {
|
|
461
|
+
const details = error instanceof WorkflowExecutionError ? error : void 0;
|
|
462
|
+
const message = extractErrorMessage(error);
|
|
463
|
+
if (entry && details?.meta && !entry.meta) entry.meta = details.meta;
|
|
464
|
+
if (details?.logs) registry?.setRecentLogs(runId, details.logs);
|
|
465
|
+
if (entry && isTerminalWorkflowStatus(entry.status)) {
|
|
466
|
+
return {
|
|
467
|
+
ok: false,
|
|
468
|
+
message: entry.status === "cancelled" ? "Workflow run cancelled." : entry.error ?? message,
|
|
469
|
+
details
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
if (callerWasAbortedBeforeStart || !runInBackground && options.signal.aborted) {
|
|
473
|
+
registry?.cancel(runId, Date.now());
|
|
474
|
+
} else {
|
|
475
|
+
registry?.fail(runId, message, Date.now());
|
|
476
|
+
}
|
|
477
|
+
return { ok: false, message, details };
|
|
478
|
+
} finally {
|
|
479
|
+
controller.abort();
|
|
480
|
+
if (entry && isTerminalWorkflowStatus(entry.status)) {
|
|
481
|
+
const telemetryEvent = new WorkflowRunEvent({
|
|
482
|
+
status: entry.status,
|
|
483
|
+
agents_dispatched: entry.agentsDispatched,
|
|
484
|
+
agents_completed: entry.agentsCompleted,
|
|
485
|
+
// Read off the dispatch traces rather than the counters: a
|
|
486
|
+
// dispatch that failed or replayed from cache still counts as
|
|
487
|
+
// completed, so without these three a run that lost half its
|
|
488
|
+
// fan-out and one that lost none report identically.
|
|
489
|
+
agents_failed: entry.dispatches.reduce(
|
|
490
|
+
(n, dispatch) => dispatch.status === "failed" ? n + 1 : n,
|
|
491
|
+
0
|
|
492
|
+
),
|
|
493
|
+
agents_cached: entry.dispatches.reduce(
|
|
494
|
+
(n, dispatch) => dispatch.status === "cached" ? n + 1 : n,
|
|
495
|
+
0
|
|
496
|
+
),
|
|
497
|
+
agents_respawned: entry.agentsRespawned ?? 0,
|
|
498
|
+
phase_count: entry.phases.length,
|
|
499
|
+
tokens_spent: entry.tokensSpent,
|
|
500
|
+
duration_ms: (entry.endTime ?? entry.startTime) - entry.startTime
|
|
501
|
+
});
|
|
502
|
+
const snapshotPersisted = await writeWorkflowSnapshot(
|
|
503
|
+
config,
|
|
504
|
+
entry
|
|
505
|
+
);
|
|
506
|
+
if (snapshotPersisted) {
|
|
507
|
+
registry?.notifySnapshotPersisted(entry.runId);
|
|
508
|
+
}
|
|
509
|
+
await journal?.drain();
|
|
510
|
+
try {
|
|
511
|
+
logWorkflowRun(config, telemetryEvent);
|
|
512
|
+
} catch {
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
releasePersistenceActivity();
|
|
516
|
+
registry?.releaseHandle(runId, handle);
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
...scriptPath ? { scriptPath } : {},
|
|
521
|
+
...journalPath ? { journalPath } : {}
|
|
522
|
+
}
|
|
523
|
+
);
|
|
524
|
+
registry?.attachHandle(handle);
|
|
525
|
+
return handle;
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
function extractErrorMessage(error) {
|
|
529
|
+
if (error && typeof error === "object" && "message" in error) {
|
|
530
|
+
const message = error.message;
|
|
531
|
+
if (typeof message === "string") return message;
|
|
532
|
+
return String(message);
|
|
533
|
+
}
|
|
534
|
+
return String(error);
|
|
535
|
+
}
|
|
536
|
+
__name(extractErrorMessage, "extractErrorMessage");
|
|
537
|
+
|
|
538
|
+
// packages/core/src/tools/workflow/workflow.ts
|
|
539
|
+
import { promises as fs } from "node:fs";
|
|
540
|
+
import * as path from "node:path";
|
|
541
|
+
var WORKFLOW_PARAM_SCHEMA = {
|
|
542
|
+
type: "object",
|
|
543
|
+
properties: {
|
|
544
|
+
script: {
|
|
545
|
+
type: "string",
|
|
546
|
+
description: `JavaScript source of the workflow. Wrapped as an async IIFE. May call the injected globals \`phase(title)\`, \`log(msg)\`, \`agent(prompt, opts?)\`, and read \`args\`. agent() opts: \`{ label?, phase?, schema?, model?, agentType?, isolation?, workingDir?, stallMs? }\`. \`schema\` (JSON Schema object): the subagent must deliver its result by calling \`structured_output\` with arguments matching the schema; agent() resolves to the validated object. After two in-conversation nudges without a valid result, it resolves to null and the failure is recorded as "subagent completed without calling StructuredOutput (after 2 in-conversation nudges)"; check for null. \`agentType\` (string): resolves against the declarative-agents registry (\`.qwen/agents/<name>.md\`, project then user then built-in). Unresolved names make the admitted agent() resolve to null and record "agent({agentType}): agent type 'X' not found"; check for null. \`model\` (string): per-call model override; routes provider correctly via the subagent runtime view. \`isolation\`: \`'worktree'\` provisions a fresh git worktree under \`<projectRoot>/.qwen/worktrees/agent-<7hex>\`; the worktree is auto-removed if no changes, otherwise the path and branch are returned alongside the result. \`'remote'\` makes the admitted agent() resolve to null and records "agent({isolation:'remote'}) is not available in this build" (parity with upstream). isolation=worktree also resolves to null and records a refusal when the parent working tree has uncommitted changes (the subagent would see a stale HEAD). \`workingDir\` (string): pin the subagent to an EXISTING git worktree of this repository that the caller owns \u2014 nothing is created and nothing is removed. Use it when the directory the agent must work in already exists and its uncommitted state is the point (a review worktree, a checkout a previous step provisioned) \u2014 exactly the case isolation cannot serve. Mutually exclusive with \`isolation\`. The path must be a linked worktree of this repository registered via \`git worktree add\` (it may live anywhere on disk) \u2014 the main checkout is not eligible. \`stallMs\` (number, ms): a no-progress watchdog, not a wall-clock cap. The dispatch is aborted and retried (up to ${MAX_STALL_ATTEMPTS} attempts total) after this many milliseconds with no observable subagent progress \u2014 including before the first response arrives; the timer is suspended while a tool is in flight, so a legitimately slow tool is not a stall. Default ${DEFAULT_STALL_MS} (override via \`${MAX_WORKFLOW_STALL_MS_ENV}\`, whole seconds); \`0\` disables the watchdog. Wall time per attempt is bounded separately. Workflow subagents always have SendMessage / Monitor / EnterPlanMode / ExitPlanMode in their disallowed-tool floor regardless of agentType. Concurrency: \`parallel([() => agent(...), ...])\` runs thunks through a shared per-run window (default \`max(2, min(16, cpus-2))\` agents in flight; override via \`${MAX_WORKFLOW_CONCURRENCY_ENV}\`) and resolves to a position-aligned array \u2014 a thunk that throws, or resolves to a non-JSON-serializable value, becomes \`null\` at its index (errors-as-data); parallel() itself rejects on invalid arguments, abort, or a run-level token/agent-cap refusal. \`pipeline(items, ...stages)\` runs each item through the stages (staggered, no inter-stage barrier); an ordinary stage error, \`null\`, or non-JSON-serializable value drops that item to \`null\`, while a run-level refusal rejects the batch. A bare sequential \`await agent()\` follows the same rule: an agent that fails on its own terms resolves to \`null\` there too, so the fan-out and the sequential form never disagree about what a broken agent means. Pass THUNKS to parallel, not eager calls: \`parallel([() => agent(...)])\`, not \`parallel([agent(...)])\`. At most ${DEFAULT_MAX_AGENTS_PER_RUN} agent() calls per run (override via \`${MAX_WORKFLOW_AGENTS_ENV}\`). \`Date.now()\` and \`Math.random()\` both throw \u2014 workflow scripts must be deterministic for resume. \`export const meta = {...}\` declarations are stripped before execution.`
|
|
547
|
+
},
|
|
548
|
+
scriptPath: {
|
|
549
|
+
type: "string",
|
|
550
|
+
description: "Optional. Absolute path to a workflow `.js` file to load and run instead of inline `script`. Primarily set by the `/<name>` saved-workflow slash command; a tool that generated a script for this run hands you its path the same way. The file must resolve inside a saved-workflow directory (`.qwen/workflows`, `~/.qwen/workflows`) or the generated-scripts root (`$QWEN_CODE_PROJECT_DIR/workflows/generated` \u2014 the per-project runtime dir, not the project tree) \u2014 any other path is refused. Provide exactly ONE of `script` or `scriptPath`. The file is read at execution time, so edits to a saved workflow take effect on the next run. An inline `script` is persisted to `<generated root>/inline/<runId>.js` and that path comes back in the result, so a resume passes the path instead of the source."
|
|
551
|
+
},
|
|
552
|
+
args: {
|
|
553
|
+
description: "Optional structured value bound to the `args` global. Pass actual JSON, not a stringified value."
|
|
554
|
+
},
|
|
555
|
+
resumeFromRunId: {
|
|
556
|
+
type: "string",
|
|
557
|
+
description: "Optional. Resume a prior workflow run by id (e.g. wf_abc123\u2026). Re-runs the supplied script or returned script path; agent() calls whose rolling prefix-hash (prompt + opts, chained in call order) matches a journaled result are served from cache for the longest unchanged prefix, and the first changed/missing call onward runs live. Pass the `scriptPath` the original run returned and the same `args`. Editing a saved workflow changes future runs too, so copy it for run-specific edits. Replay requires a journal; without one, every agent() call runs live. The journal keys hash each agent() call's prompt and opts, not the script text, so post-processing can change without losing the cache."
|
|
558
|
+
},
|
|
559
|
+
run_in_background: {
|
|
560
|
+
type: "boolean",
|
|
561
|
+
default: false,
|
|
562
|
+
description: "Optional. When true, start the workflow under the interactive session and return a run handle immediately. The Background Tasks view can observe, cooperatively pause/resume, or stop it, and completion is delivered to the conversation when the run settles. Interactive TUI only. Defaults to false."
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
// `script` is required UNLESS `scriptPath` is supplied; this XOR can't be
|
|
566
|
+
// expressed as a plain `required` list, so it's enforced in
|
|
567
|
+
// `validateToolParamValues`. Inline authoring (the LLM path) should always
|
|
568
|
+
// pass `script`; the `scriptPath` property description states the XOR.
|
|
569
|
+
};
|
|
570
|
+
var WorkflowToolInvocation = class extends BaseToolInvocation {
|
|
571
|
+
constructor(config, toolOptions, params, workflowName) {
|
|
572
|
+
super(params);
|
|
573
|
+
this.config = config;
|
|
574
|
+
this.toolOptions = toolOptions;
|
|
575
|
+
this.workflowName = workflowName;
|
|
576
|
+
}
|
|
577
|
+
static {
|
|
578
|
+
__name(this, "WorkflowToolInvocation");
|
|
579
|
+
}
|
|
580
|
+
callId;
|
|
581
|
+
setCallId(callId) {
|
|
582
|
+
this.callId = callId;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Cache so the transcript header and the approval dialog cannot disagree,
|
|
586
|
+
* and so an oversized script is scanned once per invocation rather than
|
|
587
|
+
* once per surface that asks.
|
|
588
|
+
*/
|
|
589
|
+
metaCache;
|
|
590
|
+
resolveMeta() {
|
|
591
|
+
if (this.metaCache === void 0) {
|
|
592
|
+
this.metaCache = this.params.script ? readMetaForConfirmation(this.params.script) : null;
|
|
593
|
+
}
|
|
594
|
+
return this.metaCache;
|
|
595
|
+
}
|
|
596
|
+
getDescription() {
|
|
597
|
+
const meta = this.resolveMeta();
|
|
598
|
+
if (meta) {
|
|
599
|
+
return `Run workflow: ${sanitizeLine(meta.name)}`;
|
|
600
|
+
}
|
|
601
|
+
if (this.params.scriptPath && this.params.script === void 0) {
|
|
602
|
+
const kind = isGeneratedWorkflowScriptPath(
|
|
603
|
+
this.config,
|
|
604
|
+
this.params.scriptPath
|
|
605
|
+
) ? "generated workflow script" : "saved workflow";
|
|
606
|
+
return `Run ${kind} (${path.basename(this.params.scriptPath)})`;
|
|
607
|
+
}
|
|
608
|
+
return `Run a workflow script (${this.params.script?.length ?? 0} chars)`;
|
|
609
|
+
}
|
|
610
|
+
toolLocations() {
|
|
611
|
+
return [];
|
|
612
|
+
}
|
|
613
|
+
getDefaultPermission() {
|
|
614
|
+
return Promise.resolve("ask");
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Show what is about to run, and scope the grant that approves it.
|
|
618
|
+
*
|
|
619
|
+
* Without this override the base class renders `Confirm WorkflowTool` over
|
|
620
|
+
* `Run a workflow script (4127 chars)` — a character count standing in for
|
|
621
|
+
* arbitrary model-authored JavaScript that may fan out to
|
|
622
|
+
* `DEFAULT_MAX_AGENTS_PER_RUN` subagents, provision git worktrees and spend
|
|
623
|
+
* an uncapped token budget. The asymmetry is visible within one run: the
|
|
624
|
+
* subagent approvals this workflow bubbles up each get a full dialog.
|
|
625
|
+
*
|
|
626
|
+
* Two properties of the grant matter as much as the disclosure:
|
|
627
|
+
*
|
|
628
|
+
* - An inline `script` can never be pre-approved. It is fresh
|
|
629
|
+
* model-authored source every time, so a blanket "always allow" would
|
|
630
|
+
* transfer consent from the script the user read to every script the
|
|
631
|
+
* model writes afterwards. `hideAlwaysAllow` removes the option and the
|
|
632
|
+
* empty `permissionRules` stops `injectPermissionRulesIfMissing` from
|
|
633
|
+
* supplying the bare-tool-name rule, which `buildPermissionRules`
|
|
634
|
+
* documents as matching *all* invocations.
|
|
635
|
+
* - A `scriptPath` names a file on disk that the user chose, so it can be
|
|
636
|
+
* pre-approved — but scoped to that path. The rule is built with the
|
|
637
|
+
* same helpers the matcher uses so a tool rename moves both sides.
|
|
638
|
+
*/
|
|
639
|
+
async getConfirmationDetails(_abortSignal) {
|
|
640
|
+
const meta = this.resolveMeta();
|
|
641
|
+
const isGeneratedScriptPath = this.params.scriptPath !== void 0 && await isGeneratedWorkflowScriptPathCanonical(
|
|
642
|
+
this.config,
|
|
643
|
+
this.params.scriptPath
|
|
644
|
+
);
|
|
645
|
+
const isGeneratedInlineScriptPath = this.params.scriptPath !== void 0 && await isWorkflowScriptPathWithinCanonicalRoot(
|
|
646
|
+
this.params.scriptPath,
|
|
647
|
+
path.dirname(this.config.storage.getInlineWorkflowScriptPath("wf_0"))
|
|
648
|
+
);
|
|
649
|
+
const body = buildConfirmationPrompt(
|
|
650
|
+
this.params,
|
|
651
|
+
meta,
|
|
652
|
+
isGeneratedScriptPath
|
|
653
|
+
);
|
|
654
|
+
const banner = resolveUsageBanner(
|
|
655
|
+
this.config,
|
|
656
|
+
this.config.getWorkflowRunRegistry?.(),
|
|
657
|
+
resolveMaxTokensPerWorkflow()
|
|
658
|
+
);
|
|
659
|
+
const isInlineScript = this.params.script !== void 0 || isGeneratedInlineScriptPath;
|
|
660
|
+
const details = {
|
|
661
|
+
type: "info",
|
|
662
|
+
title: "Run a dynamic workflow?",
|
|
663
|
+
prompt: banner ? `${banner}${body}` : body,
|
|
664
|
+
// The body is a script excerpt and a phase list: rendering it as
|
|
665
|
+
// Markdown would swallow the very characters the reader needs to see.
|
|
666
|
+
renderPromptAsPlainText: true,
|
|
667
|
+
hideAlwaysAllow: isInlineScript,
|
|
668
|
+
permissionRules: isInlineScript ? [] : [
|
|
669
|
+
`${getRuleDisplayName(resolveToolName(ToolNames.WORKFLOW))}(scriptPath:${this.params.scriptPath})`
|
|
670
|
+
],
|
|
671
|
+
onConfirm: /* @__PURE__ */ __name(async (_outcome, _payload) => {
|
|
672
|
+
}, "onConfirm")
|
|
673
|
+
};
|
|
674
|
+
return details;
|
|
675
|
+
}
|
|
676
|
+
async execute(signal, updateOutput, _shellExecutionConfig) {
|
|
677
|
+
const runInBackground = this.params.run_in_background === true;
|
|
678
|
+
if (runInBackground && signal.aborted) {
|
|
679
|
+
return startCancelledResult();
|
|
680
|
+
}
|
|
681
|
+
let handle;
|
|
682
|
+
try {
|
|
683
|
+
handle = await WorkflowRunner.start({
|
|
684
|
+
config: this.config,
|
|
685
|
+
signal,
|
|
686
|
+
toolUseId: this.callId,
|
|
687
|
+
...this.workflowName ? { workflowName: this.workflowName } : {},
|
|
688
|
+
script: this.params.script,
|
|
689
|
+
scriptPath: this.params.scriptPath,
|
|
690
|
+
args: this.params.args,
|
|
691
|
+
resumeFromRunId: this.params.resumeFromRunId,
|
|
692
|
+
dispatch: this.toolOptions.dispatch,
|
|
693
|
+
runInBackground,
|
|
694
|
+
onUpdate: !runInBackground && updateOutput ? (entry) => safeEmitUpdate(updateOutput, entry) : void 0
|
|
695
|
+
});
|
|
696
|
+
} catch (error) {
|
|
697
|
+
if (error instanceof WorkflowStartCancelledError || runInBackground && signal.aborted) {
|
|
698
|
+
return startCancelledResult();
|
|
699
|
+
}
|
|
700
|
+
if (error instanceof WorkflowScriptNotLaunchedError) {
|
|
701
|
+
return {
|
|
702
|
+
llmContent: [{ text: error.message }],
|
|
703
|
+
returnDisplay: error.message,
|
|
704
|
+
error: {
|
|
705
|
+
message: error.message,
|
|
706
|
+
type: "invalid_tool_params" /* INVALID_TOOL_PARAMS */
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
throw error;
|
|
711
|
+
}
|
|
712
|
+
if (runInBackground) {
|
|
713
|
+
const status = handle.registry?.get(handle.runId)?.status ?? "running";
|
|
714
|
+
const usageBanner = resolveUsageBanner(
|
|
715
|
+
this.config,
|
|
716
|
+
handle.registry,
|
|
717
|
+
handle.budget.total
|
|
718
|
+
);
|
|
719
|
+
return {
|
|
720
|
+
workflowRunId: handle.runId,
|
|
721
|
+
...handle.scriptPath ? { scriptPath: handle.scriptPath } : {},
|
|
722
|
+
...handle.journalPath ? { journalPath: handle.journalPath } : {},
|
|
723
|
+
llmContent: [
|
|
724
|
+
{
|
|
725
|
+
text: buildBackgroundStartText(handle, status)
|
|
726
|
+
}
|
|
727
|
+
],
|
|
728
|
+
returnDisplay: usageBanner + `Workflow ${handle.runId} started in the background (status: ${status}). Use Background Tasks to observe, cooperatively pause/resume, or stop it.`
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
const settlement = await handle.completion;
|
|
732
|
+
if (settlement.ok) {
|
|
733
|
+
const { outcome } = settlement;
|
|
734
|
+
const usageBanner = resolveUsageBanner(
|
|
735
|
+
this.config,
|
|
736
|
+
handle.registry,
|
|
737
|
+
handle.budget.total
|
|
738
|
+
);
|
|
739
|
+
const llmText = safeStringifyResult(outcome.result);
|
|
740
|
+
const displayJson = safeStringifyDisplayPayload({
|
|
741
|
+
runId: outcome.runId,
|
|
742
|
+
...outcome.meta ? { meta: outcome.meta } : {},
|
|
743
|
+
phases: outcome.phases,
|
|
744
|
+
logs: outcome.logs,
|
|
745
|
+
result: outcome.result,
|
|
746
|
+
// P5: surface the per-run token total in the terminal display so
|
|
747
|
+
// the user sees actual usage even without opening the dialog.
|
|
748
|
+
// P5 R1 (#11): align with `buildLivePhaseTreeDisplay` — include
|
|
749
|
+
// tokens whenever ANY usage is reported OR a cap is set, not
|
|
750
|
+
// only when spend > 0. A capped-but-zero-spend run still wants
|
|
751
|
+
// the cap visible so the user sees the gate engaged.
|
|
752
|
+
...handle.budget.spent() > 0 || handle.budget.total !== null ? {
|
|
753
|
+
tokens: {
|
|
754
|
+
spent: handle.budget.spent(),
|
|
755
|
+
total: handle.budget.total
|
|
756
|
+
}
|
|
757
|
+
} : {}
|
|
758
|
+
});
|
|
759
|
+
return {
|
|
760
|
+
...handle.scriptPath ? { scriptPath: handle.scriptPath } : {},
|
|
761
|
+
...handle.journalPath ? { journalPath: handle.journalPath } : {},
|
|
762
|
+
// Two parts: the script's return value is left exactly as it was,
|
|
763
|
+
// and the run handle follows as a separate part. Note what this does
|
|
764
|
+
// NOT mean — `convertToFunctionResponse` joins the text parts with a
|
|
765
|
+
// newline, so the model reads `<return value>\n--- workflow run ---…`
|
|
766
|
+
// as one string. Keeping them apart is still what makes the return
|
|
767
|
+
// value untouched at the tool boundary, keeps `returnDisplay` clean,
|
|
768
|
+
// and gives the per-tool head/tail truncator a distinct trailer part.
|
|
769
|
+
// The scheduler-wide persistence gate may still fold both parts into
|
|
770
|
+
// one head-only preview when their combined text crosses its limit.
|
|
771
|
+
llmContent: [
|
|
772
|
+
{ text: llmText },
|
|
773
|
+
{ text: buildRunTrailer(this.config, handle, this.params.args) }
|
|
774
|
+
],
|
|
775
|
+
returnDisplay: usageBanner + "```json\n" + displayJson + "\n```"
|
|
776
|
+
};
|
|
777
|
+
} else {
|
|
778
|
+
const { message, details } = settlement;
|
|
779
|
+
const { phases, logs, meta } = details ?? {};
|
|
780
|
+
const cancelled = handle.registry?.get(handle.runId)?.status === "cancelled";
|
|
781
|
+
const failureText = cancelled ? "Workflow cancelled." : `Workflow failed: ${clampForDisplay(
|
|
782
|
+
sanitizeBlock(message),
|
|
783
|
+
TRAILER_ERROR_CHARS
|
|
784
|
+
)}`;
|
|
785
|
+
const trailer = buildRunTrailer(
|
|
786
|
+
this.config,
|
|
787
|
+
handle,
|
|
788
|
+
this.params.args,
|
|
789
|
+
logs,
|
|
790
|
+
!cancelled
|
|
791
|
+
);
|
|
792
|
+
const display = `${cancelled ? "Workflow cancelled." : `Workflow failed: ${message}`}
|
|
793
|
+
|
|
794
|
+
${safeStringifyDisplayPayload(
|
|
795
|
+
{
|
|
796
|
+
runId: handle.runId,
|
|
797
|
+
...meta ? { meta } : {},
|
|
798
|
+
phases: phases ?? [],
|
|
799
|
+
logs: logs ?? []
|
|
800
|
+
}
|
|
801
|
+
)}`;
|
|
802
|
+
return {
|
|
803
|
+
...handle.scriptPath ? { scriptPath: handle.scriptPath } : {},
|
|
804
|
+
...handle.journalPath ? { journalPath: handle.journalPath } : {},
|
|
805
|
+
// The failure message alone names what threw but not where to look:
|
|
806
|
+
// the logs the runtime already mirrored (`dispatch failed (result not
|
|
807
|
+
// consumed)` and friends) only reached `returnDisplay`, which the
|
|
808
|
+
// scheduler overwrites with `error.message` — so the model never saw
|
|
809
|
+
// them. Mirror the two content parts into the error message because
|
|
810
|
+
// that is the only text the non-timeout scheduler branch delivers.
|
|
811
|
+
llmContent: [{ text: failureText }, { text: trailer }],
|
|
812
|
+
returnDisplay: display,
|
|
813
|
+
// FIX-10 (REUSE-I1): use the standard ToolErrorType.EXECUTION_FAILED
|
|
814
|
+
// code so error routing / dashboards can classify workflow failures
|
|
815
|
+
// the same way as other execution-time tool errors.
|
|
816
|
+
error: {
|
|
817
|
+
message: `${failureText}
|
|
818
|
+
${trailer}`,
|
|
819
|
+
type: "execution_failed" /* EXECUTION_FAILED */
|
|
820
|
+
}
|
|
821
|
+
};
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
var TRAILER_LOG_LINES = 20;
|
|
826
|
+
var TRAILER_LOG_LINE_CHARS = 400;
|
|
827
|
+
var TRAILER_ERROR_CHARS = 4e3;
|
|
828
|
+
function buildRunTrailer(config, handle, args, logs, includeResume = true) {
|
|
829
|
+
const lines = [
|
|
830
|
+
"--- workflow run ---",
|
|
831
|
+
`runId: ${sanitizeLine(handle.runId)}`
|
|
832
|
+
];
|
|
833
|
+
if (handle.scriptPath) {
|
|
834
|
+
lines.push(`script: ${sanitizeLine(handle.scriptPath)}`);
|
|
835
|
+
}
|
|
836
|
+
if (handle.journalPath) {
|
|
837
|
+
lines.push(`journal: ${sanitizeLine(handle.journalPath)}`);
|
|
838
|
+
}
|
|
839
|
+
const entry = handle.registry?.get(handle.runId);
|
|
840
|
+
let failedCount = 0;
|
|
841
|
+
if (entry) {
|
|
842
|
+
const countByStatus = /* @__PURE__ */ __name((status) => entry.dispatches.reduce(
|
|
843
|
+
(n, dispatch) => dispatch.status === status ? n + 1 : n,
|
|
844
|
+
0
|
|
845
|
+
), "countByStatus");
|
|
846
|
+
const respawned = entry.agentsRespawned ?? 0;
|
|
847
|
+
failedCount = countByStatus("failed");
|
|
848
|
+
lines.push(
|
|
849
|
+
`agents: ${entry.dispatches.length} dispatched` + (respawned > 0 ? ` (${respawned} re-ran from a prior run)` : "") + ` \xB7 ${countByStatus("completed")} completed \xB7 ${countByStatus("cached")} cached \xB7 ${failedCount} failed \xB7 ${countByStatus("cancelled")} cancelled`
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
const spent = handle.budget.spent();
|
|
853
|
+
lines.push(
|
|
854
|
+
handle.budget.total === null ? `tokens: ${spent} spent (no cap)` : `tokens: ${spent} / ${handle.budget.total} spent`
|
|
855
|
+
);
|
|
856
|
+
const failures = entry ? buildFailureLines(entry) : [];
|
|
857
|
+
if (failures.length > 0 && entry) {
|
|
858
|
+
lines.push(
|
|
859
|
+
`failures (${failedCount}):`,
|
|
860
|
+
...failures.map(
|
|
861
|
+
(line) => clampForDisplay(sanitizeLine(line), TRAILER_LOG_LINE_CHARS)
|
|
862
|
+
)
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
const resume = buildResumeCall({
|
|
866
|
+
runId: handle.runId,
|
|
867
|
+
scriptPath: handle.scriptPath,
|
|
868
|
+
args
|
|
869
|
+
});
|
|
870
|
+
if (resume && includeResume) {
|
|
871
|
+
const pathAdvice = entry?.workflowName || !isGeneratedWorkflowScriptPath(config, handle.scriptPath) ? "this reads the saved workflow; copy it before making a run-specific change" : "edit that generated copy first if the script needs to change";
|
|
872
|
+
const journalAdvice = handle.journalPath ? "the journal replays the longest unchanged prefix of agent() calls, and the first changed call onward runs live" : "no journal was written for this run, so every agent() call runs live";
|
|
873
|
+
lines.push(`resume: ${resume} \u2014 ${pathAdvice}; ${journalAdvice}.`);
|
|
874
|
+
if (hasUninlinableResumeArgs({ runId: handle.runId, args })) {
|
|
875
|
+
lines.push(RESUME_ARGS_TOO_LARGE_NOTE);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
const tail = (logs ?? []).slice(-TRAILER_LOG_LINES);
|
|
879
|
+
if (tail.length > 0) {
|
|
880
|
+
lines.push(
|
|
881
|
+
`logs (last ${tail.length}):`,
|
|
882
|
+
...tail.map(
|
|
883
|
+
(line) => clampForDisplay(sanitizeLine(line), TRAILER_LOG_LINE_CHARS)
|
|
884
|
+
)
|
|
885
|
+
);
|
|
886
|
+
}
|
|
887
|
+
return lines.join("\n");
|
|
888
|
+
}
|
|
889
|
+
__name(buildRunTrailer, "buildRunTrailer");
|
|
890
|
+
function buildBackgroundStartText(handle, status) {
|
|
891
|
+
const lines = [
|
|
892
|
+
"Workflow started in background.",
|
|
893
|
+
`Run ID: ${sanitizeLine(handle.runId)}`,
|
|
894
|
+
`Status: ${sanitizeLine(status)}`
|
|
895
|
+
];
|
|
896
|
+
if (handle.scriptPath) {
|
|
897
|
+
lines.push(`Script file: ${sanitizeLine(handle.scriptPath)}`);
|
|
898
|
+
}
|
|
899
|
+
if (handle.journalPath) {
|
|
900
|
+
lines.push(`Journal: ${sanitizeLine(handle.journalPath)}`);
|
|
901
|
+
}
|
|
902
|
+
lines.push(
|
|
903
|
+
`You will be notified when it settles. Use /workflows ${sanitizeLine(handle.runId)} for the live phase tree.`
|
|
904
|
+
);
|
|
905
|
+
return lines.join("\n");
|
|
906
|
+
}
|
|
907
|
+
__name(buildBackgroundStartText, "buildBackgroundStartText");
|
|
908
|
+
function startCancelledResult() {
|
|
909
|
+
return {
|
|
910
|
+
llmContent: "Workflow was cancelled before it could start.",
|
|
911
|
+
returnDisplay: "Workflow cancelled."
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
__name(startCancelledResult, "startCancelledResult");
|
|
915
|
+
function buildLivePhaseTreeDisplay(entry) {
|
|
916
|
+
const payload = {
|
|
917
|
+
runId: entry.runId,
|
|
918
|
+
...entry.meta ? { meta: entry.meta } : {},
|
|
919
|
+
status: entry.status,
|
|
920
|
+
currentPhase: entry.currentPhase,
|
|
921
|
+
phases: entry.phases,
|
|
922
|
+
agentsDispatched: entry.agentsDispatched,
|
|
923
|
+
agentsCompleted: entry.agentsCompleted
|
|
924
|
+
};
|
|
925
|
+
if (entry.tokensSpent > 0 || entry.tokenBudgetTotal !== null) {
|
|
926
|
+
payload["tokens"] = {
|
|
927
|
+
spent: entry.tokensSpent,
|
|
928
|
+
total: entry.tokenBudgetTotal
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
try {
|
|
932
|
+
return "```json\n" + JSON.stringify(payload, null, 2) + "\n```";
|
|
933
|
+
} catch {
|
|
934
|
+
return `Workflow ${entry.runId} \u2014 ${entry.status} \u2014 ${entry.phases.length} phase(s)`;
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
__name(buildLivePhaseTreeDisplay, "buildLivePhaseTreeDisplay");
|
|
938
|
+
function resolveUsageBanner(config, registry, budgetTotal) {
|
|
939
|
+
if (!registry) return "";
|
|
940
|
+
if (config.getSkipWorkflowUsageWarning?.()) return "";
|
|
941
|
+
if (!registry.shouldShowUsageWarning()) return "";
|
|
942
|
+
return buildUsageBanner(budgetTotal);
|
|
943
|
+
}
|
|
944
|
+
__name(resolveUsageBanner, "resolveUsageBanner");
|
|
945
|
+
var CONFIRM_SCRIPT_EXCERPT_CHARS = 1200;
|
|
946
|
+
var CONFIRM_ARGS_CHARS = 300;
|
|
947
|
+
var CONFIRM_MAX_PHASES = 12;
|
|
948
|
+
function sanitizeLine(text) {
|
|
949
|
+
return stripAnsiAndControl(text);
|
|
950
|
+
}
|
|
951
|
+
__name(sanitizeLine, "sanitizeLine");
|
|
952
|
+
function sanitizeBlock(text) {
|
|
953
|
+
return text.replace(/\t/g, " ").split("\n").map((line) => stripAnsiAndControl(line)).join("\n");
|
|
954
|
+
}
|
|
955
|
+
__name(sanitizeBlock, "sanitizeBlock");
|
|
956
|
+
function clampForDisplay(text, max) {
|
|
957
|
+
if (text.length <= max) return text;
|
|
958
|
+
return `${text.slice(0, max)}
|
|
959
|
+
\u2026 (${text.length - max} more characters)`;
|
|
960
|
+
}
|
|
961
|
+
__name(clampForDisplay, "clampForDisplay");
|
|
962
|
+
function readMetaForConfirmation(script) {
|
|
963
|
+
try {
|
|
964
|
+
return extractAndStripMeta(script).meta;
|
|
965
|
+
} catch {
|
|
966
|
+
return null;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
__name(readMetaForConfirmation, "readMetaForConfirmation");
|
|
970
|
+
function isGeneratedWorkflowScriptPath(config, scriptPath) {
|
|
971
|
+
return isWithinRoot(scriptPath, config.storage.getGeneratedWorkflowsDir());
|
|
972
|
+
}
|
|
973
|
+
__name(isGeneratedWorkflowScriptPath, "isGeneratedWorkflowScriptPath");
|
|
974
|
+
async function isGeneratedWorkflowScriptPathCanonical(config, scriptPath) {
|
|
975
|
+
return isWorkflowScriptPathWithinCanonicalRoot(
|
|
976
|
+
scriptPath,
|
|
977
|
+
config.storage.getGeneratedWorkflowsDir()
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
__name(isGeneratedWorkflowScriptPathCanonical, "isGeneratedWorkflowScriptPathCanonical");
|
|
981
|
+
async function isWorkflowScriptPathWithinCanonicalRoot(scriptPath, root) {
|
|
982
|
+
if (await isSymlinkedRoot(root)) return false;
|
|
983
|
+
let realScriptPath;
|
|
984
|
+
try {
|
|
985
|
+
realScriptPath = await fs.realpath(scriptPath);
|
|
986
|
+
} catch {
|
|
987
|
+
return isWithinRoot(scriptPath, root);
|
|
988
|
+
}
|
|
989
|
+
let realRoot;
|
|
990
|
+
try {
|
|
991
|
+
realRoot = await fs.realpath(root);
|
|
992
|
+
} catch {
|
|
993
|
+
realRoot = path.resolve(root);
|
|
994
|
+
}
|
|
995
|
+
return isWithinRoot(realScriptPath, realRoot);
|
|
996
|
+
}
|
|
997
|
+
__name(isWorkflowScriptPathWithinCanonicalRoot, "isWorkflowScriptPathWithinCanonicalRoot");
|
|
998
|
+
function buildConfirmationPrompt(params, meta, isGeneratedScriptPath) {
|
|
999
|
+
const lines = [];
|
|
1000
|
+
if (meta) {
|
|
1001
|
+
lines.push(`Workflow: ${sanitizeLine(meta.name)}`);
|
|
1002
|
+
lines.push(sanitizeLine(meta.description));
|
|
1003
|
+
} else if (params.scriptPath) {
|
|
1004
|
+
const label = isGeneratedScriptPath ? "Generated workflow script" : "Saved workflow";
|
|
1005
|
+
lines.push(`${label}: ${sanitizeLine(params.scriptPath)}`);
|
|
1006
|
+
} else {
|
|
1007
|
+
lines.push("Workflow: (the script declares no meta block)");
|
|
1008
|
+
}
|
|
1009
|
+
if (meta?.phases?.length) {
|
|
1010
|
+
const shown = meta.phases.slice(0, CONFIRM_MAX_PHASES);
|
|
1011
|
+
lines.push("", `Phases (${meta.phases.length}):`);
|
|
1012
|
+
shown.forEach((phase, i) => {
|
|
1013
|
+
const detail = phase.detail ? ` \u2014 ${sanitizeLine(phase.detail)}` : "";
|
|
1014
|
+
lines.push(` ${i + 1}. ${sanitizeLine(phase.title)}${detail}`);
|
|
1015
|
+
});
|
|
1016
|
+
if (meta.phases.length > shown.length) {
|
|
1017
|
+
lines.push(` \u2026 and ${meta.phases.length - shown.length} more`);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
if (params.scriptPath && meta) {
|
|
1021
|
+
lines.push("", `Loaded from: ${sanitizeLine(params.scriptPath)}`);
|
|
1022
|
+
}
|
|
1023
|
+
if (params.resumeFromRunId) {
|
|
1024
|
+
lines.push("", `Resuming run: ${sanitizeLine(params.resumeFromRunId)}`);
|
|
1025
|
+
}
|
|
1026
|
+
if (params.args !== void 0) {
|
|
1027
|
+
let rendered;
|
|
1028
|
+
try {
|
|
1029
|
+
rendered = JSON.stringify(params.args) ?? String(params.args);
|
|
1030
|
+
} catch {
|
|
1031
|
+
rendered = "(args are not JSON-serializable)";
|
|
1032
|
+
}
|
|
1033
|
+
lines.push(
|
|
1034
|
+
"",
|
|
1035
|
+
`Args: ${clampForDisplay(sanitizeLine(rendered), CONFIRM_ARGS_CHARS)}`
|
|
1036
|
+
);
|
|
1037
|
+
}
|
|
1038
|
+
if (params.script) {
|
|
1039
|
+
lines.push(
|
|
1040
|
+
"",
|
|
1041
|
+
"Script:",
|
|
1042
|
+
clampForDisplay(
|
|
1043
|
+
sanitizeBlock(params.script),
|
|
1044
|
+
CONFIRM_SCRIPT_EXCERPT_CHARS
|
|
1045
|
+
)
|
|
1046
|
+
);
|
|
1047
|
+
}
|
|
1048
|
+
return lines.join("\n");
|
|
1049
|
+
}
|
|
1050
|
+
__name(buildConfirmationPrompt, "buildConfirmationPrompt");
|
|
1051
|
+
function buildUsageBanner(total) {
|
|
1052
|
+
if (total === null) {
|
|
1053
|
+
return `> Workflows have no per-run token cap. Set \`${MAX_TOKENS_PER_WORKFLOW_ENV}=<n>\` (env) for a soft cap. Suppress this notice with \`skipWorkflowUsageWarning: true\` in settings.
|
|
1054
|
+
|
|
1055
|
+
`;
|
|
1056
|
+
}
|
|
1057
|
+
return `> Workflow token cap is ${total} (per \`${MAX_TOKENS_PER_WORKFLOW_ENV}\`). Suppress this notice with \`skipWorkflowUsageWarning: true\` in settings.
|
|
1058
|
+
|
|
1059
|
+
`;
|
|
1060
|
+
}
|
|
1061
|
+
__name(buildUsageBanner, "buildUsageBanner");
|
|
1062
|
+
function safeEmitUpdate(updateOutput, entry) {
|
|
1063
|
+
if (!updateOutput || !entry) return;
|
|
1064
|
+
try {
|
|
1065
|
+
updateOutput(buildLivePhaseTreeDisplay(entry));
|
|
1066
|
+
} catch {
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
__name(safeEmitUpdate, "safeEmitUpdate");
|
|
1070
|
+
function safeStringifyResult(result) {
|
|
1071
|
+
if (result === void 0) return "(workflow returned no value)";
|
|
1072
|
+
if (typeof result === "string") return result;
|
|
1073
|
+
try {
|
|
1074
|
+
return JSON.stringify(result, null, 2);
|
|
1075
|
+
} catch {
|
|
1076
|
+
return `(workflow returned a non-JSON-serializable value of type ${typeof result})`;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
__name(safeStringifyResult, "safeStringifyResult");
|
|
1080
|
+
function safeStringifyDisplayPayload(payload) {
|
|
1081
|
+
try {
|
|
1082
|
+
return JSON.stringify(payload, null, 2);
|
|
1083
|
+
} catch {
|
|
1084
|
+
if (payload && typeof payload === "object") {
|
|
1085
|
+
const sanitized = {};
|
|
1086
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
1087
|
+
try {
|
|
1088
|
+
JSON.stringify(value);
|
|
1089
|
+
sanitized[key] = value;
|
|
1090
|
+
} catch {
|
|
1091
|
+
sanitized[key] = `(non-JSON-serializable value of type ${typeof value})`;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
try {
|
|
1095
|
+
return JSON.stringify(sanitized, null, 2);
|
|
1096
|
+
} catch {
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
return "(display payload not JSON-serializable)";
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
__name(safeStringifyDisplayPayload, "safeStringifyDisplayPayload");
|
|
1103
|
+
var WORKFLOW_TOOL_DESCRIPTION = `Execute a workflow script that orchestrates subagents deterministically.
|
|
1104
|
+
|
|
1105
|
+
**Only on an explicit request**
|
|
1106
|
+
|
|
1107
|
+
Do not call this tool unless the user has asked for multi-agent orchestration. A run can dispatch up to ${DEFAULT_MAX_AGENTS_PER_RUN} subagents and spend tokens accordingly, so that scale has to be requested rather than inferred. It counts as requested when any of these holds:
|
|
1108
|
+
|
|
1109
|
+
- The user's message contains the word \`workflow\`; a system reminder confirms it when it does.
|
|
1110
|
+
- The user asked for orchestration in their own words \u2014 run a workflow, fan out agents, orchestrate this with subagents.
|
|
1111
|
+
- A skill or slash command the user invoked instructs you to use this tool.
|
|
1112
|
+
- The user named a saved workflow to run, reached through \`workflow('<name>')\` or \`scriptPath\`.
|
|
1113
|
+
- The user asked to resume or continue an earlier run, which is \`resumeFromRunId\`.
|
|
1114
|
+
|
|
1115
|
+
Otherwise do not call it, however well the task would parallelize. Do the work in the main loop, or spawn a single subagent for one self-contained piece. When a workflow would genuinely be the better tool, say in one sentence what it would fan out over and roughly how many agents that is, then let the user decide \u2014 and mention that including the word \`workflow\` next time skips the ask.
|
|
1116
|
+
|
|
1117
|
+
**What a workflow is for**
|
|
1118
|
+
|
|
1119
|
+
Reach for one to be comprehensive (decompose the work and cover every part in parallel), to be confident (independent perspectives and adversarial checks before an answer is committed to), or to take on scale a single context cannot hold \u2014 migrations, audits, broad sweeps. The script is where that structure is encoded: what fans out, what verifies, what synthesizes. Parallelism on its own is not a reason; work that is already one short sequence of edits belongs in the main loop.
|
|
1120
|
+
|
|
1121
|
+
**Runtime** \u2014 see the \`script\` parameter for the detailed authoring contract.
|
|
1122
|
+
|
|
1123
|
+
\`phase(title)\`, \`log(msg)\`, \`agent(prompt, opts?)\`, \`parallel(thunks)\`, \`pipeline(items, ...stages)\`, \`workflow(nameOrRef, args?)\`, plus the \`args\` and \`budget\` globals. \`workflow()\` runs a saved workflow inline under this run's caps and nests one level only \u2014 a workflow reached through \`workflow()\` cannot call \`workflow()\` itself, and doing so throws. Saved workflows are \`<name>.js\` files under \`<projectRoot>/.qwen/workflows\` (project scope, also surfaced as \`/<name>\` slash commands) or \`~/.qwen/workflows\` (user scope, lower precedence when both define the same name); \`workflow('<name>')\` resolves against those two directories, while \`scriptPath\` takes an absolute path to a script inside either of them or inside the generated-scripts root (\`$QWEN_CODE_PROJECT_DIR/workflows/generated\` \u2014 the per-project runtime dir, not the project tree \u2014 where a tool emitting a one-run script writes it; never a slash command, never resolvable by name); a path outside those roots is refused. Default \`max(2, min(16, cpus-2))\` agents in flight per run (\`${MAX_WORKFLOW_CONCURRENCY_ENV}\`), up to ${DEFAULT_MAX_AGENTS_PER_RUN} agents total (\`${MAX_WORKFLOW_AGENTS_ENV}\`), under a 30-minute wall-clock cap per run (\`QWEN_CODE_MAX_WORKFLOW_SECONDS\`) \u2014 a fan-out near the agent cap will not fit inside the default cap. Each subagent attempt is separately capped at ${DEFAULT_WORKFLOW_SUBAGENT_MAX_TURNS} turns (\`${WORKFLOW_SUBAGENT_MAX_TURNS_ENV}\`) and ${DEFAULT_WORKFLOW_SUBAGENT_MAX_TIME_MINUTES} minutes (\`${WORKFLOW_SUBAGENT_MAX_MINUTES_ENV}\`) \u2014 raise them for legitimately long work. \`agent()\` resolves to \`null\` when that admitted agent fails on its own \u2014 including turn/time caps, model or setup errors, missing structured output, and exhausted stall retries \u2014 and it does so for a bare \`await agent()\` exactly as it does inside \`parallel()\`/\`pipeline()\`, so check for \`null\` wherever you read a result. Call-shape validation failures \u2014 such as an empty prompt, an unsupported option combination, or an invalid option value \u2014 reject a bare call; inside \`parallel()\`/\`pipeline()\`, the surrounding ordinary thunk or stage rejection becomes a position-aligned \`null\`. Run-level rejections no later call could survive \u2014 the token budget, the ${DEFAULT_MAX_AGENTS_PER_RUN}-agent cap, and cancellation \u2014 throw and end a \`parallel()\`/\`pipeline()\` batch. An admitted agent that fails and settles to \`null\` still counts as dispatched and is named, with its error, in the run's failures list; a \`null\` returned by an ordinary thunk or stage is not an agent dispatch. A per-run output-token cap may also be in effect: read \`budget.total\` (\`null\` = uncapped) before committing to a large fan-out, because once the cap is reached every further \`agent()\` call is refused. Per-call \`agent({ schema, agentType, model, isolation: 'worktree', workingDir, stallMs })\` covers structured-output contracts, declarative-agent selection, model override, git-worktree-isolated subagents, pinning an agent to a caller-owned worktree, and the no-progress stall watchdog (\`stallMs: 0\` disables it). \`resumeFromRunId\` resumes a prior run \u2014 agent() calls whose rolling prefix-hash matches the journal are served from cache for the longest unchanged prefix. Every run hands back its runId, the script's path on disk (an inline script is persisted, so a resume edits that file rather than re-sending the source) and its journal path; the journal holds one result line per completed agent, so read it before diagnosing an empty or surprising result. Runs appear in the background-tasks view and the \`/workflows\` dialog (live phase tree, token usage, cooperative pause/resume, cancel); \`run_in_background: true\` returns a run handle immediately in the interactive TUI and delivers completion through the conversation. Scripts run in a node:vm sandbox with no filesystem or shell access \u2014 all I/O happens through the spawned agents.
|
|
1124
|
+
|
|
1125
|
+
**Scout first, then orchestrate**
|
|
1126
|
+
|
|
1127
|
+
The strongest pattern is hybrid: discover the work list in the main loop (list the files, scope the diff, read the failing test), then hand that list to a workflow. You do not need to know the shape of the work before the task \u2014 only before the orchestration step. When the work has distinct phases, run several small workflows across turns and read each result before choosing the next, rather than authoring one large script that runs unattended.
|
|
1128
|
+
|
|
1129
|
+
Common single-phase shapes: understand (parallel readers over subsystems, merged into one map), design (independent approaches, judged, then synthesized), review (dimensions, find, verify each finding), research (broad sweep, deep read, synthesis), migrate (discover sites, transform each under \`isolation: 'worktree'\`, verify).
|
|
1130
|
+
|
|
1131
|
+
**Default to \`pipeline()\`**
|
|
1132
|
+
|
|
1133
|
+
\`pipeline()\` runs each item through every stage independently \u2014 item A can be in stage 3 while item B is still in stage 1 \u2014 so wall-clock is the slowest single chain. \`parallel()\` is a barrier: it waits for every thunk before anything moves on, so it costs the slowest item of every stage.
|
|
1134
|
+
|
|
1135
|
+
A barrier is right only when a stage genuinely needs cross-item context: deduplicating or merging across the full result set before expensive downstream work, exiting early when the total count is zero, or a prompt that compares one finding against all the others. It is not justified by needing to flatten, map, or filter between stages (do that inside a pipeline stage), by two stages being conceptually separate, or by the code reading more tidily. Smell test: \`parallel()\` \u2192 a pure transform \u2192 \`parallel()\` is a pipeline someone wrote with an unnecessary barrier. When in doubt, \`pipeline()\`.
|
|
1136
|
+
|
|
1137
|
+
**Verify before believing**
|
|
1138
|
+
|
|
1139
|
+
A subagent's answer is a claim, not a result. For findings that matter, spawn independent verifiers prompted to *refute*, and drop what a majority refutes. When a claim can be wrong in several different ways, give each verifier a distinct lens (correctness, security, performance, does it actually reproduce) \u2014 diversity catches what repetition cannot. For a wide solution space, generate several independent attempts, judge them in parallel, and synthesize from the winner while grafting the best ideas from the rest.
|
|
1140
|
+
|
|
1141
|
+
**Converge deliberately**
|
|
1142
|
+
|
|
1143
|
+
For discovery of unknown size, keep running finders until some number of consecutive rounds turn up nothing new; a fixed round count stops partway into the tail. Deduplicate each round against everything already seen, never against only what survived judging \u2014 otherwise rejected findings reappear every round and the loop never terminates. A closing pass that asks what is still missing (a search angle never run, a claim never verified, a file never read) usually produces the next round of real work.
|
|
1144
|
+
|
|
1145
|
+
**Report honestly**
|
|
1146
|
+
|
|
1147
|
+
Scale the fleet to what was actually asked: a quick check gets a few agents and one verification pass; an explicit request to be thorough or exhaustive earns a larger pool and a multi-vote adversarial round. Whenever a run bounds its own coverage \u2014 top-N, sampling, no retry \u2014 \`log()\` what was dropped. Silent truncation reads as full coverage, which is worse than a smaller honest result.
|
|
1148
|
+
|
|
1149
|
+
These shapes are a starting point, not a menu; compose the harness the task actually needs.`;
|
|
1150
|
+
var WorkflowTool = class extends BaseDeclarativeTool {
|
|
1151
|
+
constructor(config, toolOptions = {}) {
|
|
1152
|
+
super(
|
|
1153
|
+
ToolNames.WORKFLOW,
|
|
1154
|
+
ToolDisplayNames.WORKFLOW,
|
|
1155
|
+
WORKFLOW_TOOL_DESCRIPTION,
|
|
1156
|
+
"other" /* Other */,
|
|
1157
|
+
WORKFLOW_PARAM_SCHEMA,
|
|
1158
|
+
/* isOutputMarkdown */
|
|
1159
|
+
true,
|
|
1160
|
+
/* canUpdateOutput */
|
|
1161
|
+
true
|
|
1162
|
+
);
|
|
1163
|
+
this.config = config;
|
|
1164
|
+
this.toolOptions = toolOptions;
|
|
1165
|
+
}
|
|
1166
|
+
static {
|
|
1167
|
+
__name(this, "WorkflowTool");
|
|
1168
|
+
}
|
|
1169
|
+
buildSessionOwnedBackground(params, workflowName) {
|
|
1170
|
+
const validationError = this.validateToolParams(params);
|
|
1171
|
+
if (validationError) {
|
|
1172
|
+
throw new Error(validationError);
|
|
1173
|
+
}
|
|
1174
|
+
if (!this.config.getWorkflowRunRegistry().hasCompletionCallback()) {
|
|
1175
|
+
throw new Error(
|
|
1176
|
+
"WorkflowTool: session-owned background runs require an active workflow completion channel."
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
return new WorkflowToolInvocation(
|
|
1180
|
+
this.config,
|
|
1181
|
+
this.toolOptions,
|
|
1182
|
+
{ ...params, run_in_background: true },
|
|
1183
|
+
workflowName
|
|
1184
|
+
);
|
|
1185
|
+
}
|
|
1186
|
+
validateToolParamValues(params) {
|
|
1187
|
+
const hasScript = typeof params.script === "string" && params.script.length > 0;
|
|
1188
|
+
const hasPath = typeof params.scriptPath === "string" && params.scriptPath.length > 0;
|
|
1189
|
+
if (!hasScript && !hasPath) {
|
|
1190
|
+
return "WorkflowTool: provide `script` (inline source) or `scriptPath` (a workflow script file).";
|
|
1191
|
+
}
|
|
1192
|
+
if (hasScript && hasPath) {
|
|
1193
|
+
return "WorkflowTool: provide exactly one of `script` or `scriptPath`, not both.";
|
|
1194
|
+
}
|
|
1195
|
+
if (params.resumeFromRunId !== void 0 && !/^wf_[0-9a-f]+$/.test(params.resumeFromRunId)) {
|
|
1196
|
+
return "WorkflowTool: `resumeFromRunId` must match the generated id format `wf_<hex>`.";
|
|
1197
|
+
}
|
|
1198
|
+
if (params.run_in_background === true) {
|
|
1199
|
+
if (!this.config.isInteractive() || this.config.getExperimentalZedIntegration?.() === true) {
|
|
1200
|
+
return "WorkflowTool: `run_in_background` is available only in the interactive TUI.";
|
|
1201
|
+
}
|
|
1202
|
+
if (!this.config.getWorkflowRunRegistry().hasCompletionCallback()) {
|
|
1203
|
+
return "WorkflowTool: `run_in_background` requires an active workflow completion channel.";
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
return null;
|
|
1207
|
+
}
|
|
1208
|
+
createInvocation(params) {
|
|
1209
|
+
return new WorkflowToolInvocation(this.config, this.toolOptions, params);
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
export {
|
|
1213
|
+
WorkflowTool
|
|
1214
|
+
};
|
|
1215
|
+
/**
|
|
1216
|
+
* @license
|
|
1217
|
+
* Copyright 2026 Qwen Team
|
|
1218
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
1219
|
+
*/
|
|
1220
|
+
/**
|
|
1221
|
+
* @license
|
|
1222
|
+
* Copyright 2025 Qwen
|
|
1223
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
1224
|
+
*/
|