@qwen-code/qwen-code 0.23.0 → 0.23.1-preview.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/new-app/SKILL.md +1 -1
- package/bundled/qc-helper/docs/configuration/auth.md +84 -12
- package/bundled/qc-helper/docs/configuration/settings.md +76 -74
- package/bundled/qc-helper/docs/features/arena.md +15 -20
- package/bundled/qc-helper/docs/features/channels/overview.md +7 -2
- package/bundled/qc-helper/docs/features/code-review.md +22 -19
- package/bundled/qc-helper/docs/features/commands.md +51 -10
- package/bundled/qc-helper/docs/features/followup-suggestions.md +1 -1
- package/bundled/qc-helper/docs/features/goals.md +8 -0
- package/bundled/qc-helper/docs/features/headless.md +2 -2
- package/bundled/qc-helper/docs/features/hooks.md +19 -19
- package/bundled/qc-helper/docs/features/output-styles.md +35 -2
- package/bundled/qc-helper/docs/qwen-serve.md +67 -52
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +3 -1
- package/bundled/qc-helper/docs/support/troubleshooting.md +3 -3
- package/bundled/review/SKILL.md +45 -41
- package/bundled/review/references/aone.md +1 -1
- package/bundled/review/references/posting.md +1 -1
- package/bundled/workflow-creator/SKILL.md +48 -0
- package/bundled/zvec-grep-install/SKILL.md +57 -0
- package/chunks/MaxSizedBox-5ARLO5PR.js +116 -0
- package/chunks/{StandaloneSessionPicker-QUMO4LLQ.js → StandaloneSessionPicker-T6B322CB.js} +87 -82
- package/chunks/{acp-startup-profiler-M4X5F3VK.js → acp-startup-profiler-6ULXXQMS.js} +2 -2
- package/chunks/{acpAgent-2GTFCIEP.js → acpAgent-WTDEY5KD.js} +1041 -364
- package/chunks/{agent-XKF5SZWU.js → agent-NXPUXEVZ.js} +46 -43
- package/chunks/agent-headless-QQZTWOKO.js +88 -0
- package/chunks/{anthropicContentGenerator-L76MR5OR.js → anthropicContentGenerator-6XDHXIII.js} +16 -9
- package/chunks/{artifact-tool-MYCL2QCS.js → artifact-tool-DFVVJXL2.js} +3 -3
- package/chunks/askUserQuestion-GF7VQ44M.js +14 -0
- package/chunks/bridge-OHY5OGOZ.js +123 -0
- package/chunks/{ca-BNU7YNDE.js → ca-KC2AISNS.js} +1 -0
- package/chunks/{channel-management-service-4MTCEGJB.js → channel-management-service-ZDDG3G5S.js} +4 -4
- package/chunks/channel-settings-store-7BJAS2SU.js +126 -0
- package/chunks/{channel-worker-group-47F4ISUZ.js → channel-worker-group-2ISMRENV.js} +6 -6
- package/chunks/{channel-worker-manager-I5Y44GYR.js → channel-worker-manager-VSRPVPRH.js} +6 -6
- package/chunks/{channel-worker-supervisor-6VCLUXFE.js → channel-worker-supervisor-SRJBK72Z.js} +4 -4
- package/chunks/{chunk-5RTTI4GE.js → chunk-2RYWGYB3.js} +4 -3
- package/chunks/{chunk-FUO5V5KI.js → chunk-2UWQX4FP.js} +2 -2
- package/chunks/{chunk-L26ONV2Y.js → chunk-2WGJG2KW.js} +9 -8
- package/chunks/{chunk-JHN7UIDW.js → chunk-2XRE4KE4.js} +1 -1
- package/chunks/chunk-32CM56LO.js +20 -0
- package/chunks/{chunk-SI7WDR3U.js → chunk-32YDNYXP.js} +129 -14
- package/chunks/{chunk-ZHO2CW6D.js → chunk-3CZ2BQV6.js} +1 -1
- package/chunks/{chunk-FD5SJOWT.js → chunk-3K456UJF.js} +9 -4
- package/chunks/{chunk-5M6IDOMF.js → chunk-3K65MUKD.js} +105 -0
- package/chunks/chunk-3UMWOKJC.js +78 -0
- package/chunks/{chunk-UM2FFKXN.js → chunk-43JNQAHO.js} +3 -3
- package/chunks/{chunk-KM3XVTMO.js → chunk-43NOB5NM.js} +112 -12
- package/chunks/{chunk-G5PBOQWI.js → chunk-47BZVBTE.js} +3 -3
- package/chunks/{chunk-32LU3APX.js → chunk-4F2QRVW6.js} +1 -1
- package/chunks/{chunk-KMU3ZHH4.js → chunk-4HC4DYKN.js} +2 -2
- package/chunks/{chunk-22UH7VTP.js → chunk-4HOEU2OR.js} +1 -1
- package/chunks/{chunk-NXKOVOM5.js → chunk-4IQKBLTQ.js} +15 -9
- package/chunks/{chunk-M4KFODIP.js → chunk-4JAGXZR3.js} +1 -1
- package/chunks/{chunk-PDAKFU7M.js → chunk-4LIPOIXS.js} +1 -1
- package/chunks/{chunk-LEPCWS5A.js → chunk-4MCY33Y2.js} +3 -3
- package/chunks/{chunk-U6D2PPMN.js → chunk-4VUVBN3Y.js} +1 -1
- package/chunks/{chunk-37JFWFCD.js → chunk-4VZCORNT.js} +1 -1
- package/chunks/{daemon-RKDGBFLK.js → chunk-537SQ2AI.js} +2216 -1721
- package/chunks/{chunk-VNAYZAFX.js → chunk-54TF2ZIQ.js} +4 -4
- package/chunks/{chunk-OKTNXDVO.js → chunk-565U2ANU.js} +1 -1
- package/chunks/chunk-5ETULJLP.js +74 -0
- package/chunks/{chunk-ADYN7P2Y.js → chunk-5JLQWQK6.js} +8 -6
- package/chunks/{chunk-BFY33IB4.js → chunk-5MTARK4Y.js} +7 -7
- package/chunks/{chunk-BJXCYUGM.js → chunk-5YY5MZT6.js} +1 -1
- package/chunks/{chunk-4PSDSCW3.js → chunk-64MQTIX7.js} +3 -3
- package/chunks/{chunk-54C6PIGT.js → chunk-6UIACMGH.js} +3 -3
- package/chunks/{chunk-ALUYNJPM.js → chunk-7BZS4ZDV.js} +1362 -1140
- package/chunks/{chunk-LB3WQQJK.js → chunk-7OCIQNKX.js} +2 -2
- package/chunks/{chunk-QKDNS6FU.js → chunk-7VEYUF3N.js} +13 -2
- package/chunks/{chunk-AZJLY2XZ.js → chunk-AHBLRVD5.js} +5 -5
- package/chunks/{chunk-VWTSRH6C.js → chunk-AQ5NAGWI.js} +89 -17
- package/chunks/{chunk-MOF6VZN2.js → chunk-AXPOOQAW.js} +2 -2
- package/chunks/{chunk-CVX63TFJ.js → chunk-B44JBZBB.js} +3 -3
- package/chunks/{chunk-AI35S34R.js → chunk-B54PFQS5.js} +3 -3
- package/chunks/{chunk-373DQUVA.js → chunk-BF3RUIVP.js} +5 -4
- package/chunks/{chunk-RJUVTJEZ.js → chunk-BKNY7PDI.js} +1 -1
- package/chunks/{chunk-UKYXYWI2.js → chunk-BUQN5LTI.js} +2 -2
- package/chunks/{chunk-O5CD7T4T.js → chunk-BW4333PP.js} +0 -95
- package/chunks/{chunk-UPFRILIL.js → chunk-CWNC7M73.js} +2 -2
- package/chunks/{chunk-3L724BJ5.js → chunk-CZACBHAW.js} +6 -6
- package/chunks/{chunk-EBDGRBZX.js → chunk-D4CU6DKR.js} +6 -6
- package/chunks/{chunk-G7HBEEX7.js → chunk-D6PIMKY3.js} +9 -9
- package/chunks/{chunk-ENYUKMFK.js → chunk-DJXSOEFB.js} +1 -1
- package/chunks/{chunk-C2VWOXHS.js → chunk-DNPHKA72.js} +8 -8
- package/chunks/{chunk-UUASLXHW.js → chunk-E4L5BM2B.js} +5 -5
- package/chunks/{chunk-HT5S5TRQ.js → chunk-EDIDYZBT.js} +4 -11
- package/chunks/{chunk-5H5S4UY5.js → chunk-EFT7OMDN.js} +1 -1
- package/chunks/{chunk-GB4UKWY5.js → chunk-EJNYBDYC.js} +2 -2
- package/chunks/{chunk-NQ4L2CMD.js → chunk-ER273QE6.js} +53 -9
- package/chunks/{chunk-RKW36UWC.js → chunk-EWNKP4V4.js} +1 -1
- package/chunks/{chunk-UJ4DUYIH.js → chunk-F53KKZUD.js} +2 -2
- package/chunks/{chunk-EFTPIZIC.js → chunk-FDOGGKAA.js} +21 -0
- package/chunks/{chunk-AQ37AY7B.js → chunk-FKJM6JKY.js} +5 -0
- package/chunks/{chunk-KEVYJSI4.js → chunk-G34YLYCS.js} +13 -13
- package/chunks/{chunk-P6UIF2OW.js → chunk-GCFZ2LAX.js} +195 -10
- package/chunks/{chunk-VGHZT6JR.js → chunk-GELRJXE2.js} +1 -1
- package/chunks/{chunk-ZDFQGHZH.js → chunk-GMNLYQOS.js} +1 -1
- package/chunks/{chunk-KOGW3YWJ.js → chunk-GVVCLL2P.js} +12 -12
- package/chunks/{chunk-OSSTATJF.js → chunk-GXZHYPHZ.js} +428 -30
- package/chunks/{chunk-IPATA3T2.js → chunk-GZWW2QWR.js} +2 -2
- package/chunks/{chunk-C4TIXFDZ.js → chunk-H3UDNQLO.js} +6 -4
- package/chunks/chunk-HD7O6WLV.js +18 -0
- package/chunks/{chunk-4UANMABT.js → chunk-HFTB354P.js} +259 -49
- package/chunks/{chunk-LOBDDFYK.js → chunk-HJ34U5J4.js} +5 -5
- package/chunks/{chunk-M4LBBSVP.js → chunk-HY3DXYZK.js} +2 -2
- package/chunks/{chunk-4F7GQGXB.js → chunk-I72PHOKL.js} +1451 -415
- package/chunks/{chunk-YPWZTR7F.js → chunk-IFD3BTEA.js} +3 -3
- package/chunks/{chunk-EWRW2WQC.js → chunk-IKLFS6SC.js} +5 -5
- package/chunks/{chunk-VPSIC437.js → chunk-IQN2CCIE.js} +66 -6
- package/chunks/{chunk-F7NF2IOE.js → chunk-IXSGOSEG.js} +7 -7
- package/chunks/{chunk-ODZF64DM.js → chunk-IZ2U57NY.js} +1 -1
- package/chunks/{chunk-4BGDFKQE.js → chunk-J3O5I5ZD.js} +24 -7
- package/chunks/{chunk-DYTW3QVG.js → chunk-J6MB5ZHZ.js} +1 -1
- package/chunks/{chunk-HJBHMANB.js → chunk-JBTZUFR4.js} +11 -8
- package/chunks/{chunk-SRF4KTAG.js → chunk-JLWFGYXU.js} +4 -4
- package/chunks/{chunk-SX2QIMJV.js → chunk-JOPC3FND.js} +5 -5
- package/chunks/chunk-JPEAQJNS.js +2142 -0
- package/chunks/{chunk-ZTPGUFQV.js → chunk-JRYL3T2O.js} +24 -5
- package/chunks/{chunk-GXUTFQXK.js → chunk-KE3Q4JMY.js} +4 -4
- package/chunks/{chunk-LKODFJRD.js → chunk-KFFCDLKV.js} +1 -1
- package/chunks/{chunk-4M24B5J5.js → chunk-KJJPJYHI.js} +79 -30
- package/chunks/chunk-KK2GZGBK.js +21080 -0
- package/chunks/{chunk-64QH2UC6.js → chunk-KPXRFTT7.js} +12 -1
- package/chunks/{chunk-JZWOCUZ3.js → chunk-L4R7BCVV.js} +1 -1
- package/chunks/{chunk-IG4W5SJR.js → chunk-LDS57224.js} +3 -3
- package/chunks/{chunk-UAKRDON5.js → chunk-LK7S2D6V.js} +4 -4
- package/chunks/{chunk-4HVH57J3.js → chunk-LMJQSPWB.js} +21 -6
- package/chunks/{chunk-ANVG3BVV.js → chunk-LNYV4GXX.js} +13 -3
- package/chunks/{chunk-RM4WT2XB.js → chunk-LPBQODMR.js} +4 -4
- package/chunks/{chunk-XEAAO654.js → chunk-M3JGHRMQ.js} +1 -1
- package/chunks/{chunk-AMDSOFFV.js → chunk-MATEIJZF.js} +1 -0
- package/chunks/{chunk-LHBNR6EU.js → chunk-MNEYUNOE.js} +2 -2
- package/chunks/{chunk-I4NRYS6A.js → chunk-MUZCSTOO.js} +11 -11
- package/chunks/{chunk-I5N4EAS6.js → chunk-MWHY26G3.js} +1 -1
- package/chunks/{chunk-7XL4WRXM.js → chunk-N6VQ37ZZ.js} +2 -2
- package/chunks/{chunk-AHYTURFB.js → chunk-N7EYO2E7.js} +1 -1
- package/chunks/{chunk-LU77UT4D.js → chunk-N7VURC4O.js} +24 -26
- package/chunks/{chunk-DSX7KQPM.js → chunk-NAKALAL4.js} +227 -29
- package/chunks/{chunk-QQD2GART.js → chunk-NGX4NUNP.js} +3 -3
- package/chunks/{chunk-2M3EWQNG.js → chunk-NUQFUXOG.js} +17 -1
- package/chunks/{chunk-E4JNFXNI.js → chunk-NXWYCSPL.js} +3 -3
- package/chunks/{chunk-6A2D4QSO.js → chunk-O2GG7H4C.js} +4 -4
- package/chunks/{chunk-ZKFTS3OV.js → chunk-O45WBTNS.js} +6 -6
- package/chunks/{chunk-KGV55H53.js → chunk-OECNP26L.js} +1 -1
- package/chunks/{chunk-S6H3ELPG.js → chunk-P4RUUG64.js} +1 -1
- package/chunks/{chunk-GH2S4GD5.js → chunk-P5LDR7FI.js} +21 -68
- package/chunks/{chunk-RN3YGDCA.js → chunk-P6LATTDG.js} +4 -4
- package/chunks/{chunk-WP4AX3XD.js → chunk-PTFFWTTO.js} +3 -3
- package/chunks/{chunk-DTVQSSNM.js → chunk-PZUOHCWI.js} +3 -3
- package/chunks/{chunk-VYIUNFEA.js → chunk-PZV2FASB.js} +3 -3
- package/chunks/{chunk-XLXAZLDR.js → chunk-Q2SAQTEJ.js} +1 -1
- package/chunks/{chunk-47RYEQW5.js → chunk-QMFOYPGV.js} +2 -2
- package/chunks/{chunk-SULZPKTA.js → chunk-QSC5YOEC.js} +3 -3
- package/chunks/{chunk-F33GFWPR.js → chunk-QWZOOIR3.js} +58 -18
- package/chunks/{chunk-H43PSPYS.js → chunk-R355CUNQ.js} +4 -4
- package/chunks/{chunk-DQCKVAF5.js → chunk-RDKXZ2LS.js} +3 -3
- package/chunks/{chunk-7JMGTOH7.js → chunk-RPBMP6BN.js} +21 -1
- package/chunks/{chunk-5Q5RC2WE.js → chunk-RVNS7NWN.js} +2 -2
- package/chunks/{chunk-7RB56BRJ.js → chunk-SAZS4IWW.js} +6 -4
- package/chunks/{chunk-5EIOJGCR.js → chunk-SFMCYMVF.js} +4 -4
- package/chunks/{chunk-TMKTOTMQ.js → chunk-SN5FV4FY.js} +5 -5
- package/chunks/{chunk-QJGYU5PG.js → chunk-TDP7UULF.js} +1 -1
- package/chunks/{chunk-EIJT2PQ6.js → chunk-TIGXX4PA.js} +2 -2
- package/chunks/{chunk-PCRBLMIN.js → chunk-TMWB67LS.js} +21 -3
- package/chunks/{chunk-JUARRUMA.js → chunk-UEZOXZNI.js} +1358 -646
- package/chunks/{chunk-KFN2IZYR.js → chunk-UKADFFL2.js} +3 -3
- package/chunks/{chunk-TJYRTS4S.js → chunk-UKKYOIVT.js} +2 -2
- package/chunks/{chunk-EVFDRBUM.js → chunk-URSCX7S7.js} +12 -7
- package/chunks/{chunk-U4DJ5XB3.js → chunk-VDXYYVCD.js} +269 -70
- package/chunks/{chunk-4LIFGNI4.js → chunk-VEFRT7NX.js} +1 -1
- package/chunks/chunk-VFFQAOPR.js +18 -0
- package/chunks/{chunk-3AKCBZVW.js → chunk-VU7O7CGQ.js} +3 -3
- package/chunks/{chunk-RAFQIHN2.js → chunk-VUSSAGKI.js} +76 -5
- package/chunks/{chunk-TQHPVKO6.js → chunk-VY6UVU7G.js} +6 -6
- package/chunks/{chunk-S2T7H5MI.js → chunk-W4LL5RZO.js} +1 -1
- package/chunks/{chunk-ZGCKTAL5.js → chunk-WEXA2DNG.js} +2 -0
- package/chunks/{chunk-NVVJTUSL.js → chunk-WR3SH3EY.js} +136 -85
- package/chunks/{chunk-JR42V4UY.js → chunk-WTW36TJ3.js} +1 -1
- package/chunks/{chunk-TSZSGQ3N.js → chunk-WXC6OAWD.js} +1 -1
- package/chunks/{chunk-ZVP4PWBU.js → chunk-X35VIWWJ.js} +1 -1
- package/chunks/{chunk-KHP66DFN.js → chunk-XFFRI3WM.js} +1 -1
- package/chunks/{chunk-EIY7SUPZ.js → chunk-XHGGYCTA.js} +1 -1
- package/chunks/{chunk-BA4WJC4L.js → chunk-XOVVCGZX.js} +1 -1
- package/chunks/{chunk-VBWD6C27.js → chunk-XUSOYE2I.js} +1 -1
- package/chunks/{chunk-NUHOLAQ6.js → chunk-XWJFDJZK.js} +1 -1
- package/chunks/{chunk-65HWLGA7.js → chunk-XY3USGFE.js} +3 -3
- package/chunks/{chunk-STCVJXQB.js → chunk-Y3ZKI4RQ.js} +56 -26
- package/chunks/{chunk-QAK5475D.js → chunk-Y53DG2HA.js} +1 -1
- package/chunks/{chunk-3JQZVCBI.js → chunk-YCDL2SAS.js} +2 -2
- package/chunks/{chunk-NSUKQ4DN.js → chunk-YHDGABDC.js} +3 -3
- package/chunks/{chunk-FRICLXCZ.js → chunk-Z6WZPXQH.js} +3 -3
- package/chunks/{chunk-EAHOJF6V.js → chunk-ZAFYHRVY.js} +12 -0
- package/chunks/{chunk-MP6YZ4RK.js → chunk-ZAZ3NFL6.js} +852 -309
- package/chunks/{chunk-7TBU7PU2.js → chunk-ZSTCM3MX.js} +1 -1
- package/chunks/{chunk-NRL5CUZT.js → chunk-ZTAVGFKA.js} +1 -1
- package/chunks/config-utils-QXDOTXEQ.js +119 -0
- package/chunks/contextCommand-RN4KARWC.js +112 -0
- package/chunks/{core-runtime-B4UKKIAQ.js → core-runtime-NAZCOKHB.js} +63 -58
- package/chunks/{create-sub-session-NJ24B4US.js → create-sub-session-BCSM4WKB.js} +61 -56
- package/chunks/{create-sub-session-LUPWEUHR.js → create-sub-session-BQ3SE4TX.js} +3 -3
- package/chunks/{cron-create-CRSPET3H.js → cron-create-D6HQ7I7I.js} +4 -4
- package/chunks/{cron-delete-DB77SZTU.js → cron-delete-KK3D2SQV.js} +4 -4
- package/chunks/{cron-list-U2JNYWV6.js → cron-list-VBF3IZMF.js} +4 -4
- package/chunks/daemon-LCUELM6E.js +191 -0
- package/chunks/{daemon-git-worktree-guard-O2HPOBAB.js → daemon-git-worktree-guard-3K5CAU36.js} +62 -57
- package/chunks/daemon-status-provider-4X3ZZQTZ.js +122 -0
- package/chunks/daemon-trust-policy-R45CFUJA.js +118 -0
- package/chunks/{daemon-trust-policy-monitor-JL7F4Y4Q.js → daemon-trust-policy-monitor-DSSFCO3K.js} +69 -64
- package/chunks/{de-T4BLOKEC.js → de-UU2YTO37.js} +1 -0
- package/chunks/deferred-core-runtime-UO2M6WYI.js +120 -0
- package/chunks/{display-image-73C7XNRK.js → display-image-EVVTBVYE.js} +6 -6
- package/chunks/{dist-EDHQIBYD.js → dist-3T5MDUHP.js} +62 -20
- package/chunks/{dist-ZCJLKQSP.js → dist-AFH3BMZZ.js} +18 -10
- package/chunks/{dist-LXFYIJNG.js → dist-MK5PPBRF.js} +40 -9
- package/chunks/{dist-GT64AAUR.js → dist-PH5RSTEA.js} +56 -20
- package/chunks/{dist-62OZ7QXB.js → dist-QUU7TVE3.js} +35 -12
- package/chunks/{dist-JVXT4VUJ.js → dist-R5Y34V6T.js} +11 -2
- package/chunks/{dist-L6URO6CK.js → dist-SB2XRXZA.js} +5 -1
- package/chunks/{dist-QAF5DO3Y.js → dist-SIHF5MU2.js} +326 -131
- package/chunks/{dist-PDGNRVPY.js → dist-UVHW2U56.js} +20 -1
- package/chunks/earlyInputCapture-BXP7V2P3.js +22 -0
- package/chunks/{edit-SUGXY63Y.js → edit-VNBCTRWP.js} +48 -44
- package/chunks/{en-2RATMNX7.js → en-JMR535HP.js} +3 -1
- package/chunks/{enter-worktree-B6USKSIK.js → enter-worktree-CEVK7MQ2.js} +7 -7
- package/chunks/{enterPlanMode-MDX4RVVL.js → enterPlanMode-4KMZMUIA.js} +48 -45
- package/chunks/environment-S2HYQDON.js +135 -0
- package/chunks/errors-DAAN5TL7.js +119 -0
- package/chunks/{exit-worktree-DLQ73SJH.js → exit-worktree-D3YE6MUN.js} +7 -7
- package/chunks/exitPlanMode-HR36HG3D.js +86 -0
- package/chunks/{fast-path-Y73R42LV.js → fast-path-4IWSW3UV.js} +3 -3
- package/chunks/{fast-path-settings-MFUR3IWK.js → fast-path-settings-ISEJPRYE.js} +6 -4
- package/chunks/{fr-BGHGYX6A.js → fr-HKNWVXRJ.js} +1 -0
- package/chunks/{glob-DMGH7EZN.js → glob-IZYB2XH2.js} +46 -43
- package/chunks/{goal-tools-3RF3PXCL.js → goal-tools-VGUPKQDJ.js} +46 -43
- package/chunks/{grep-AJVLCVXC.js → grep-OUVLNXG7.js} +9 -8
- package/chunks/handleAutoUpdate-D56FMDTW.js +115 -0
- package/chunks/i18n-BKE5WO6T.js +130 -0
- package/chunks/{image-gen-VOIDOHOB.js → image-gen-SHVQ3XID.js} +8 -8
- package/chunks/initializer-MS4SGEHF.js +119 -0
- package/chunks/installationInfo-542MGC4S.js +113 -0
- package/chunks/{ja-G3FTD5XE.js → ja-GJS5RZGU.js} +1 -0
- package/chunks/{keychain-token-storage-REZVMJA6.js → keychain-token-storage-NQ5XWIPX.js} +2 -2
- package/chunks/list-H6XTKUWL.js +122 -0
- package/chunks/{list-agents-SBMONIUK.js → list-agents-ULYBGJXC.js} +6 -6
- package/chunks/{llm-K26SUDVK.js → llm-3NUC4EJY.js} +132 -113
- package/chunks/{llm-content-generator-TT6EAUD4.js → llm-content-generator-R4NL3OQN.js} +40 -13
- package/chunks/loadedSettingsAdapter-3XLKYDVT.js +116 -0
- package/chunks/{loggingContentGenerator-EYQBA4M4.js → loggingContentGenerator-ZYSWVNEO.js} +55 -52
- package/chunks/{loop-wakeup-QA6SHCZT.js → loop-wakeup-B27BEYRL.js} +5 -5
- package/chunks/{lowlight-J2OZNPCA.js → lowlight-BTE423KL.js} +3 -6
- package/chunks/{ls-HEJNCEYO.js → ls-3IIMMVKF.js} +5 -4
- package/chunks/{lsp-WOQKNZP6.js → lsp-VJAT7XKS.js} +2 -2
- package/chunks/{managed-npm-update-HIJTODQT.js → managed-npm-update-L2I53ZAI.js} +62 -57
- package/chunks/mcp-4PIXQASW.js +116 -0
- package/chunks/{monitor-DKNZQAB2.js → monitor-O2YQTOZZ.js} +50 -46
- package/chunks/{node-UETAYMMO.js → node-ISQAFKIS.js} +2 -2
- package/chunks/nonInteractiveCli-LV7CDBA2.js +198 -0
- package/chunks/{notebook-edit-MGHTRL2D.js → notebook-edit-4RE2ALH4.js} +48 -44
- package/chunks/{openaiContentGenerator-ZJIEQ3ZJ.js → openaiContentGenerator-7ND7K5CP.js} +30 -25
- package/chunks/pidfile-UFTLQ7NP.js +117 -0
- package/chunks/{processUtils-UY3SAJJZ.js → processUtils-3XBB4FYV.js} +2 -2
- package/chunks/prompt-terminal-ledger-2QASOGMM.js +111 -0
- package/chunks/{pt-D73IFYT7.js → pt-FXMYXEUV.js} +1 -0
- package/chunks/{qwenContentGenerator-VI4KATRY.js → qwenContentGenerator-AELTUTH6.js} +52 -49
- package/chunks/{qwenOAuth2-7AOCKSOQ.js → qwenOAuth2-BS5D2LYV.js} +7 -7
- package/chunks/{read-file-P7F4P7LV.js → read-file-PDWHZPHX.js} +13 -11
- package/chunks/{read-mcp-resource-GLAGB6R7.js → read-mcp-resource-YXJZ75UB.js} +2 -2
- package/chunks/{record-artifact-SWVR7NSU.js → record-artifact-WJDOV6XU.js} +4 -4
- package/chunks/{report-findings-AL5YW3KI.js → report-findings-Q4UACKWR.js} +5 -5
- package/chunks/{request-shutdown-5YK4IZ54.js → request-shutdown-2YZ3E3GH.js} +8 -8
- package/chunks/resumeHistoryUtils-QRXZEEBA.js +124 -0
- package/chunks/ripGrep-KSOOLE6H.js +39 -0
- package/chunks/{ru-QMISLKRH.js → ru-RMHURE5U.js} +1 -0
- package/chunks/{run-qwen-serve-OGTEEUR2.js → run-qwen-serve-RTAREPT6.js} +84 -70
- package/chunks/runtime-ESFSCJRZ.js +154 -0
- package/chunks/scheduled-tasks-6ZHRNBH6.js +133 -0
- package/chunks/{scheduler-73YXGUGW.js → scheduler-DQI6KV7T.js} +63 -58
- package/chunks/{sdk-exporters-http-3JO5TJNU.js → sdk-exporters-http-7R2ARBPV.js} +2 -2
- package/chunks/{sdk-impl-HZAUUTHJ.js → sdk-impl-YOLO7LV4.js} +4 -4
- package/chunks/{send-message-JC7NJTY6.js → send-message-PQCVSVMN.js} +24 -24
- package/chunks/serve-FY7ZEW52.js +124 -0
- package/chunks/{server-AOYZVVOM.js → server-KNDY6K5F.js} +1594 -273
- package/chunks/{session-UAWFNFGI.js → session-MCEPXAZP.js} +113 -105
- package/chunks/session-attachments-root-OLNAE6GF.js +109 -0
- package/chunks/{session-pr-refresh-CT2INROL.js → session-pr-refresh-HKJHQQQK.js} +67 -62
- package/chunks/{settings-BHRGDASJ.js → settings-VXO4WBMK.js} +68 -63
- package/chunks/shell-U263OTES.js +96 -0
- package/chunks/{skill-ZGBKNCHQ.js → skill-SDODGBKL.js} +19 -17
- package/chunks/skill-settings-YEIA22QJ.js +124 -0
- package/chunks/spawnChannel-4WJZVFPP.js +117 -0
- package/chunks/standalone-update-ZWVQUO64.js +124 -0
- package/chunks/{start-opentui-ui-FZ4USOU7.js → start-opentui-ui-BFYCJQRZ.js} +1199 -190
- package/chunks/{startInteractiveUI-E2WQJUOA.js → startInteractiveUI-JYAFCMHL.js} +2977 -2319
- package/chunks/{syntheticOutput-HJNZSEHN.js → syntheticOutput-AUAJBNXR.js} +3 -3
- package/chunks/{task-create-6RSD54S5.js → task-create-LD5ISM3E.js} +12 -12
- package/chunks/{task-list-IQSACPOM.js → task-list-YISJ4RJA.js} +5 -5
- package/chunks/{task-stop-HE2LRQNW.js → task-stop-65ZOVATJ.js} +2 -2
- package/chunks/{task-update-XAJ2NYOA.js → task-update-AAN4ZVEY.js} +15 -15
- package/chunks/{team-create-SOKMYSQU.js → team-create-KU7MABNO.js} +47 -44
- package/chunks/{team-delete-NGNNKGMG.js → team-delete-XFRRTJTT.js} +5 -5
- package/chunks/{team-plan-approval-U7ZWXYAY.js → team-plan-approval-DPB377A3.js} +46 -43
- package/chunks/terminal-image-renderer-WGWRENOF.js +124 -0
- package/chunks/theme-manager-GBUFULSO.js +108 -0
- package/chunks/{todoWrite-5UTVUXHA.js → todoWrite-G7NT4IFP.js} +5 -5
- package/chunks/{tool-search-IAI2RVWT.js → tool-search-6YUXHBPT.js} +19 -17
- package/chunks/total-session-admission-54R2JQ5L.js +118 -0
- package/chunks/trustedFolders-KAJIDJTH.js +128 -0
- package/chunks/{update-relaunch-5RWKZAL3.js → update-relaunch-XM4IWBFD.js} +5 -5
- package/chunks/updateCheck-W6UZFURI.js +124 -0
- package/chunks/useAutoAcceptIndicator-LAWYHY3U.js +126 -0
- package/chunks/{validateNonInterActiveAuth-QPFEKATS.js → validateNonInterActiveAuth-7WCKHRN2.js} +109 -101
- package/chunks/{version-JKNG7YDH.js → version-3ZU43RJ6.js} +1 -1
- package/chunks/{web-fetch-X3AHIIHW.js → web-fetch-QHI2SQL4.js} +16 -14
- package/chunks/{web-search-K2FMOGS5.js → web-search-3KZZKWNY.js} +9 -8
- package/chunks/{workflow-TOLPAK5G.js → workflow-HRW7Y2X4.js} +330 -1667
- package/chunks/workspace-providers-status-KTGCWCPC.js +120 -0
- package/chunks/{workspace-registration-store-KQWVVW4Y.js → workspace-registration-store-LHLPPWNE.js} +1 -1
- package/chunks/workspace-registry-X34MLN52.js +127 -0
- package/chunks/workspace-runtime-coordinator-U4PW4P7K.js +128 -0
- package/chunks/workspace-service-KD7BCGYL.js +132 -0
- package/chunks/workspace-skills-status-YJGO6Y3T.js +119 -0
- package/chunks/{workspace-trust-reconciler-IBDFQBQS.js → workspace-trust-reconciler-EUYHISCH.js} +74 -69
- package/chunks/write-file-EBSB34NJ.js +91 -0
- package/chunks/{zh-25DF7OGK.js → zh-DVFYHRK5.js} +3 -1
- package/chunks/{zh-TW-5EDMZVGK.js → zh-TW-W2GNP2IU.js} +3 -1
- package/chunks/{zoom-image-IFXSN74N.js → zoom-image-UJ5VKWKP.js} +13 -11
- package/cli.js +13 -13
- package/export-transcript-document.js +617 -0
- package/locales/ca.js +1 -0
- package/locales/de.js +1 -0
- package/locales/en.js +5 -2
- package/locales/fr.js +1 -0
- package/locales/ja.js +1 -0
- package/locales/pt.js +1 -0
- package/locales/ru.js +1 -0
- package/locales/zh-TW.js +5 -2
- package/locales/zh.js +5 -2
- package/package.json +5 -4
- package/web-shell/assets/{abnfDiagram-VCTEODGH-Cxf7xE_Z.js → abnfDiagram-VCTEODGH-Dur--luQ.js} +1 -1
- package/web-shell/assets/{arc-ESi1eNkE.js → arc-tYLobxFi.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-D9l7-bDo.js → architectureDiagram-5GKGNRK7-IG6aXD03.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-Bc8DEasw.js → blockDiagram-NRAW4CY4-C6eBSkfA.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-Dimb2Hmh.js → c4Diagram-UCG6FXSJ-BrX3HJqB.js} +1 -1
- package/web-shell/assets/channel-uEkvKckd.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-jVDmOpAQ.js → chunk-2Q5K7J3B-B3fcJ8ee.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-DbG_SwdB.js → chunk-5VM5RSS4-CeC90yKM.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-QEc4cY1v.js → chunk-F27PBJKO-CW44RVki.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-iJ36lQ3X.js → chunk-G27WJ6UU-D1PAMukD.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-DuArnVtF.js → chunk-JWPE2WC7-Dt3Y2Fvx.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-DxOf1zwL.js → chunk-LCL6LL3I-CZHw2lLI.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-lVLu9Ild.js → chunk-POPQ4Y6H-ysNAdTGx.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-C6XYlIer.js → chunk-SVP7TREG-BdNXW6YQ.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-CiG2j2Ji.js → chunk-XXDRQBXY-DgqQ9UA8.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DuPsnhWS.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DuPsnhWS.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-DGVHMMVm.js → cose-bilkent-JH36ORCC-BILImXzJ.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-D6cgpCnH.js → cynefin-OW5HDTMX-DR88Pund.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BKv4Z-UX.js → cynefinDiagram-5FMLGOSQ-BYFbfkA6.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-B4ABMIG-.js → dagre-3AP2YEHR-rfpyc6sX.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-DgCkp_Lm.js → diagram-S7CK7UJ4-BJxLmEwH.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-FG0FNokz.js → diagram-UQ7AKVKN-H34xm7k3.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-JgkP9qg-.js → diagram-VSXAHHWV-HYxhwNLx.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-ADh2x83l.js → diagram-VX7I27RA-BJazso8F.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-yXqoYF1J.js → diagram-Z3DM3KII-Clje1aNy.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-Duk83Ek_.js → ebnfDiagram-PWID7BFC-M93YBkFh.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-DMdvxySG.js → erDiagram-SSCWMZ5O-DY8XzSHU.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-DHjVgSji.js → flowDiagram-A5DVABFB-CE6Aylcq.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DMM9DkCE.js → ganttDiagram-EL5Y4UJY-DI-5LL22.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-t_ug9vO8.js → gitGraphDiagram-WWUBYQGX-C7BZWElk.js} +1 -1
- package/web-shell/assets/index-CVyqwW7y.js +2142 -0
- package/web-shell/assets/{index-zqvnpGHv.js → index-DclFHns9.js} +1 -1
- package/web-shell/assets/index-FO7JXPnH.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-eT1fANNm.js → infoDiagram-RXCK75RN-CGUSy4Pc.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-k3evzZNn.js → ishikawaDiagram-5VMMS53U-B5BVks9q.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-CGim3EAi.js → journeyDiagram-EYS64GPL-CFh6Tf7h.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-WHfJo-22.js → kanban-definition-3QL26DDD-B7TlxP7c.js} +1 -1
- package/web-shell/assets/{layout-DkqIaFlJ.js → layout-Br_pZq2Q.js} +1 -1
- package/web-shell/assets/{linear-Bdkd3mCz.js → linear-BVlP6fte.js} +1 -1
- package/web-shell/assets/{mermaid.core-CGw0LkT_.js → mermaid.core-TrcYWoiF.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-C9V4rBvo.js → mindmap-definition-FBJOCRG2-BJ4LzqjZ.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-CwoI2T5G.js → pegDiagram-XKGWAZYB-1b_MxlOl.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-DaTmBmPG.js → pieDiagram-E7YTZNPT-B8zl0YhY.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-plh6MyGI.js → quadrantDiagram-AXDQQJYC-CIZO8ukl.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-D_b-S0iK.js → railroadDiagram-O6MQD6OU-CepHSbCj.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-zUzTN7VE.js → requirementDiagram-EFPCY7ZU-BCgxkcSW.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-m6AhoD0l.js → sankeyDiagram-P5KCCOFB-CE5CcoMM.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-Cwhzsine.js → sequenceDiagram-WJ2MYXX4-DvgHi-d5.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-CcZuKIae.js → sizeCapture-X5ZJPWSS-T-fAsCPX.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-CFoiJwD_.js → stateDiagram-HBIQ2CUA-DYHaul-5.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-BcYho9a4.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-CgS9hcaV.js → swimlanes-XN3QIQJK-Dbz3Qiej.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-D6HsOIgX.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-Dzzc05t9.js → timeline-definition-24CTP7MA-9NVRts3N.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-DemK0f7Y.js → vennDiagram-4TSXK5OY-C7cb7vnH.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CquLxtMr.js → wardleyDiagram-VM6X3IG4-CG-8Ddjm.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-BTBKTM5g.js → xychartDiagram-S5SC5T6Z-iGeYAcP4.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/MaxSizedBox-B3D7545A.js +0 -111
- package/chunks/agent-headless-OC2IB55D.js +0 -85
- package/chunks/askUserQuestion-THQZMG44.js +0 -322
- package/chunks/bridge-IHSBI2YJ.js +0 -118
- package/chunks/channel-settings-store-BVKWAI2T.js +0 -121
- package/chunks/chunk-I2TMJPCV.js +0 -448
- package/chunks/chunk-QI27MKNQ.js +0 -4008
- package/chunks/config-utils-LVSYDLHZ.js +0 -114
- package/chunks/contextCommand-TZD7UAJK.js +0 -107
- package/chunks/daemon-status-provider-GRRVCJFW.js +0 -117
- package/chunks/daemon-trust-policy-YJL442BK.js +0 -113
- package/chunks/deferred-core-runtime-S32AYVZI.js +0 -115
- package/chunks/earlyInputCapture-BBPCIVZG.js +0 -108
- package/chunks/environment-VN6RXDVN.js +0 -130
- package/chunks/errors-UEY36PIT.js +0 -114
- package/chunks/exitPlanMode-EPHIEDAA.js +0 -83
- package/chunks/handleAutoUpdate-HVWQT2AU.js +0 -110
- package/chunks/i18n-5OR7NTRZ.js +0 -125
- package/chunks/initializer-JE5RQSOE.js +0 -114
- package/chunks/installationInfo-KO3CCSCK.js +0 -108
- package/chunks/list-3IORSFIY.js +0 -117
- package/chunks/loadedSettingsAdapter-KLLFZF3M.js +0 -111
- package/chunks/mcp-A2UEHETW.js +0 -111
- package/chunks/nonInteractiveCli-YA47F2F4.js +0 -190
- package/chunks/pidfile-ETHAZNMY.js +0 -112
- package/chunks/prompt-terminal-ledger-GZ747VYE.js +0 -106
- package/chunks/resumeHistoryUtils-DPZKFW24.js +0 -119
- package/chunks/ripGrep-C7LJKUPZ.js +0 -37
- package/chunks/runtime-LNBLEMZS.js +0 -149
- package/chunks/scheduled-tasks-FLDYZQOF.js +0 -128
- package/chunks/serve-3UR2H4CV.js +0 -119
- package/chunks/session-attachments-root-ZCGXQQTR.js +0 -104
- package/chunks/shell-YHOGC7TO.js +0 -93
- package/chunks/skill-settings-AKSP665O.js +0 -119
- package/chunks/spawnChannel-N25MBB6F.js +0 -112
- package/chunks/standalone-update-XGPWJDRN.js +0 -119
- package/chunks/terminal-image-renderer-KKM4OBLO.js +0 -117
- package/chunks/theme-manager-GQHF3A7T.js +0 -103
- package/chunks/total-session-admission-G4CGCSTG.js +0 -113
- package/chunks/trustedFolders-D2I3FDPB.js +0 -123
- package/chunks/updateCheck-ZXOQDFEI.js +0 -119
- package/chunks/useAutoAcceptIndicator-6EK4QGAH.js +0 -121
- package/chunks/workspace-providers-status-PCJK3RC7.js +0 -115
- package/chunks/workspace-registry-YNIOB6HJ.js +0 -122
- package/chunks/workspace-runtime-coordinator-WG2RNEN7.js +0 -123
- package/chunks/workspace-service-G4ZNBOFH.js +0 -127
- package/chunks/workspace-skills-status-FMTPPMWC.js +0 -114
- package/chunks/write-file-YTLFY2S5.js +0 -88
- package/web-shell/assets/channel-B7ohGDil.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DdFpqpfD.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DdFpqpfD.js +0 -1
- package/web-shell/assets/index-BGZRqbRo.css +0 -36
- package/web-shell/assets/index-DRri_6_x.js +0 -2067
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V--H8HdEmk.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ShE9OIgf.js +0 -8
|
@@ -1,75 +1,86 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
3
|
import {
|
|
4
|
+
compileWorkflowScript,
|
|
5
|
+
createWorkflowSandbox,
|
|
6
|
+
debugLogger,
|
|
7
|
+
deleteInlineWorkflowScript,
|
|
8
|
+
describeWorkflowCompileError,
|
|
9
|
+
extractAndStripMeta,
|
|
4
10
|
isSymlinkedRoot,
|
|
11
|
+
persistInlineWorkflowScript,
|
|
5
12
|
resolveSavedWorkflowScript,
|
|
6
13
|
writeWorkflowSnapshot
|
|
7
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-JPEAQJNS.js";
|
|
8
15
|
import {
|
|
9
16
|
AgentEventEmitter,
|
|
17
|
+
RESUME_ARGS_TOO_LARGE_NOTE,
|
|
10
18
|
attachJsonlTranscriptWriter,
|
|
11
19
|
buildAgentTranscriptAttach,
|
|
20
|
+
buildResumeCall,
|
|
12
21
|
deriveApprovalModeConfig,
|
|
13
22
|
deriveConfig,
|
|
14
23
|
deriveWorktreeConfig,
|
|
15
24
|
getRuleDisplayName,
|
|
16
25
|
getWorkflowTaskMutationKey,
|
|
26
|
+
hasUninlinableResumeArgs,
|
|
17
27
|
installSessionWorkflowRevisionWriteThrough,
|
|
18
28
|
isTerminalWorkflowStatus,
|
|
29
|
+
markWorkflowRunPersistenceActive,
|
|
19
30
|
rebuildToolRegistryOnOverride,
|
|
20
31
|
resolveExternalWorktreeDir,
|
|
21
32
|
resolveToolName,
|
|
22
33
|
toModelVisibleSubagentResult,
|
|
23
34
|
tryWithWorkflowTaskMutation
|
|
24
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-I72PHOKL.js";
|
|
25
36
|
import "./chunk-GOFAQQZA.js";
|
|
26
|
-
import "./chunk-
|
|
37
|
+
import "./chunk-3K65MUKD.js";
|
|
27
38
|
import "./chunk-6HUXPLB5.js";
|
|
28
39
|
import "./chunk-TWPJO254.js";
|
|
29
40
|
import "./chunk-CQ35AJ4Z.js";
|
|
30
|
-
import "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
41
|
+
import "./chunk-YHDGABDC.js";
|
|
42
|
+
import "./chunk-RDKXZ2LS.js";
|
|
43
|
+
import "./chunk-B54PFQS5.js";
|
|
33
44
|
import {
|
|
34
45
|
GitWorktreeService,
|
|
35
46
|
generateAgentWorktreeSlug,
|
|
36
47
|
writeWorktreeSessionMarker
|
|
37
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-43NOB5NM.js";
|
|
38
49
|
import {
|
|
39
50
|
parsePositiveIntegerEnv
|
|
40
51
|
} from "./chunk-6PVPNMXU.js";
|
|
41
|
-
import "./chunk-
|
|
42
|
-
import "./chunk-
|
|
52
|
+
import "./chunk-565U2ANU.js";
|
|
53
|
+
import "./chunk-FDOGGKAA.js";
|
|
43
54
|
import "./chunk-IRH27ZC2.js";
|
|
44
55
|
import "./chunk-QHWCP53L.js";
|
|
45
|
-
import "./chunk-
|
|
56
|
+
import "./chunk-F53KKZUD.js";
|
|
57
|
+
import "./chunk-PZV2FASB.js";
|
|
46
58
|
import "./chunk-QJNDUTOL.js";
|
|
59
|
+
import "./chunk-OECNP26L.js";
|
|
47
60
|
import "./chunk-O6GEWCJA.js";
|
|
48
|
-
import "./chunk-OSSTATJF.js";
|
|
49
|
-
import "./chunk-ZHO2CW6D.js";
|
|
50
|
-
import "./chunk-CVX63TFJ.js";
|
|
51
|
-
import "./chunk-373DQUVA.js";
|
|
52
|
-
import "./chunk-H43PSPYS.js";
|
|
53
|
-
import "./chunk-U6D2PPMN.js";
|
|
54
|
-
import "./chunk-VYIUNFEA.js";
|
|
55
|
-
import "./chunk-KGV55H53.js";
|
|
56
|
-
import "./chunk-7TBU7PU2.js";
|
|
57
|
-
import "./chunk-E4JNFXNI.js";
|
|
58
61
|
import "./chunk-CHEIIBT3.js";
|
|
59
62
|
import {
|
|
60
63
|
SUBAGENT_PLAN_LIFECYCLE_TOOLS
|
|
61
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-UKKYOIVT.js";
|
|
65
|
+
import "./chunk-B44JBZBB.js";
|
|
66
|
+
import "./chunk-BF3RUIVP.js";
|
|
62
67
|
import "./chunk-JX6XHPTX.js";
|
|
68
|
+
import "./chunk-R355CUNQ.js";
|
|
69
|
+
import "./chunk-4VUVBN3Y.js";
|
|
70
|
+
import "./chunk-ZSTCM3MX.js";
|
|
71
|
+
import "./chunk-NXWYCSPL.js";
|
|
63
72
|
import "./chunk-MLXTMF7H.js";
|
|
73
|
+
import "./chunk-GXZHYPHZ.js";
|
|
74
|
+
import "./chunk-3CZ2BQV6.js";
|
|
64
75
|
import "./chunk-PQEISIKS.js";
|
|
65
|
-
import "./chunk-
|
|
76
|
+
import "./chunk-3K456UJF.js";
|
|
66
77
|
import {
|
|
67
78
|
runWithAgentContext
|
|
68
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-VEFRT7NX.js";
|
|
69
80
|
import "./chunk-S6LOFUVP.js";
|
|
70
81
|
import "./chunk-NAVJD2PQ.js";
|
|
71
|
-
import "./chunk-
|
|
72
|
-
import "./chunk-
|
|
82
|
+
import "./chunk-UKADFFL2.js";
|
|
83
|
+
import "./chunk-EJNYBDYC.js";
|
|
73
84
|
import "./chunk-QHMLYMMS.js";
|
|
74
85
|
import "./chunk-CFKIH3D3.js";
|
|
75
86
|
import "./chunk-2LD5U7Q3.js";
|
|
@@ -77,52 +88,55 @@ import {
|
|
|
77
88
|
createAbortController,
|
|
78
89
|
createChildAbortController
|
|
79
90
|
} from "./chunk-DJ2GSRLV.js";
|
|
80
|
-
import "./chunk-
|
|
81
|
-
import "./chunk-
|
|
82
|
-
import "./chunk-
|
|
91
|
+
import "./chunk-W4LL5RZO.js";
|
|
92
|
+
import "./chunk-3UMWOKJC.js";
|
|
93
|
+
import "./chunk-KFFCDLKV.js";
|
|
94
|
+
import "./chunk-7OCIQNKX.js";
|
|
83
95
|
import {
|
|
84
96
|
WorkflowRunEvent,
|
|
85
97
|
logWorkflowRun,
|
|
86
98
|
read,
|
|
87
99
|
writeLine
|
|
88
|
-
} from "./chunk-
|
|
100
|
+
} from "./chunk-P5LDR7FI.js";
|
|
101
|
+
import "./chunk-5ETULJLP.js";
|
|
89
102
|
import "./chunk-XBVNNDPK.js";
|
|
90
103
|
import "./chunk-VGC4I5JJ.js";
|
|
91
104
|
import {
|
|
92
105
|
isWithinRoot
|
|
93
|
-
} from "./chunk-
|
|
94
|
-
import "./chunk-
|
|
106
|
+
} from "./chunk-J6MB5ZHZ.js";
|
|
107
|
+
import "./chunk-EDIDYZBT.js";
|
|
108
|
+
import "./chunk-HD7O6WLV.js";
|
|
95
109
|
import "./chunk-WZAD4ZNJ.js";
|
|
96
110
|
import "./chunk-FPGTNKCP.js";
|
|
97
|
-
import "./chunk-
|
|
98
|
-
import "./chunk-
|
|
99
|
-
import "./chunk-
|
|
100
|
-
import "./chunk-
|
|
111
|
+
import "./chunk-TIGXX4PA.js";
|
|
112
|
+
import "./chunk-5MTARK4Y.js";
|
|
113
|
+
import "./chunk-XFFRI3WM.js";
|
|
114
|
+
import "./chunk-4HOEU2OR.js";
|
|
101
115
|
import "./chunk-HHJLM3WQ.js";
|
|
102
116
|
import {
|
|
103
117
|
stripAnsiAndControl
|
|
104
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-7VEYUF3N.js";
|
|
105
119
|
import "./chunk-74TONY4F.js";
|
|
106
120
|
import {
|
|
107
121
|
SyntheticOutputTool
|
|
108
|
-
} from "./chunk-
|
|
109
|
-
import "./chunk-
|
|
110
|
-
import "./chunk-
|
|
111
|
-
import "./chunk-
|
|
112
|
-
import "./chunk-
|
|
122
|
+
} from "./chunk-GMNLYQOS.js";
|
|
123
|
+
import "./chunk-D6PIMKY3.js";
|
|
124
|
+
import "./chunk-NGX4NUNP.js";
|
|
125
|
+
import "./chunk-FKJM6JKY.js";
|
|
126
|
+
import "./chunk-IZ2U57NY.js";
|
|
113
127
|
import {
|
|
114
128
|
BaseDeclarativeTool,
|
|
115
129
|
BaseToolInvocation,
|
|
116
130
|
ToolDisplayNames,
|
|
117
131
|
ToolNames
|
|
118
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-RPBMP6BN.js";
|
|
119
133
|
import {
|
|
120
134
|
createDebugLogger
|
|
121
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-ZAFYHRVY.js";
|
|
122
136
|
import "./chunk-75DOP5OR.js";
|
|
123
137
|
import "./chunk-DMTGGOSA.js";
|
|
124
138
|
import "./chunk-YQ3U5MUC.js";
|
|
125
|
-
import "./chunk-
|
|
139
|
+
import "./chunk-MATEIJZF.js";
|
|
126
140
|
import "./chunk-TBWQLLFO.js";
|
|
127
141
|
import {
|
|
128
142
|
init_esbuild_shims
|
|
@@ -134,1585 +148,6 @@ import {
|
|
|
134
148
|
// packages/core/src/tools/workflow/workflow.ts
|
|
135
149
|
init_esbuild_shims();
|
|
136
150
|
|
|
137
|
-
// packages/core/src/agents/runtime/workflow-sandbox.ts
|
|
138
|
-
init_esbuild_shims();
|
|
139
|
-
import * as vm from "node:vm";
|
|
140
|
-
|
|
141
|
-
// packages/core/src/agents/runtime/workflow-meta-literal.ts
|
|
142
|
-
init_esbuild_shims();
|
|
143
|
-
var WorkflowMetaSyntaxError = class extends Error {
|
|
144
|
-
static {
|
|
145
|
-
__name(this, "WorkflowMetaSyntaxError");
|
|
146
|
-
}
|
|
147
|
-
index;
|
|
148
|
-
constructor(message, index) {
|
|
149
|
-
super(message);
|
|
150
|
-
this.name = "WorkflowMetaSyntaxError";
|
|
151
|
-
this.index = index;
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
function parseWorkflowMetaLiteral(source) {
|
|
155
|
-
const parser = new MetaLiteralParser(source);
|
|
156
|
-
parser.skipTrivia();
|
|
157
|
-
const value = parser.parseValue(0);
|
|
158
|
-
parser.skipTrivia();
|
|
159
|
-
if (parser.index < source.length) {
|
|
160
|
-
throw parser.fail("unexpected trailing content");
|
|
161
|
-
}
|
|
162
|
-
return value;
|
|
163
|
-
}
|
|
164
|
-
__name(parseWorkflowMetaLiteral, "parseWorkflowMetaLiteral");
|
|
165
|
-
var MAX_DEPTH = 32;
|
|
166
|
-
var WHITESPACE = /* @__PURE__ */ new Set([" ", " ", "\n", "\r", "\f", "\v", "\xA0", "\uFEFF"]);
|
|
167
|
-
var ID_START = /[A-Za-z_$]/;
|
|
168
|
-
var ID_PART = /[A-Za-z0-9_$]/;
|
|
169
|
-
var MetaLiteralParser = class {
|
|
170
|
-
constructor(src) {
|
|
171
|
-
this.src = src;
|
|
172
|
-
}
|
|
173
|
-
static {
|
|
174
|
-
__name(this, "MetaLiteralParser");
|
|
175
|
-
}
|
|
176
|
-
index = 0;
|
|
177
|
-
fail(message) {
|
|
178
|
-
const from = Math.max(0, this.index - 24);
|
|
179
|
-
const snippet = this.src.slice(from, this.index + 24).replace(/\s+/g, " ").trim();
|
|
180
|
-
return new WorkflowMetaSyntaxError(
|
|
181
|
-
`${message} at position ${this.index} (near "${snippet}"). meta must be a plain object literal \u2014 strings, numbers, booleans, null, arrays and objects only, with no variables, function calls, spreads, accessors or template substitutions.`,
|
|
182
|
-
this.index
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
skipTrivia() {
|
|
186
|
-
for (; ; ) {
|
|
187
|
-
while (this.index < this.src.length && WHITESPACE.has(this.src[this.index])) {
|
|
188
|
-
this.index++;
|
|
189
|
-
}
|
|
190
|
-
if (this.src.startsWith("//", this.index)) {
|
|
191
|
-
let end = this.index + 2;
|
|
192
|
-
while (end < this.src.length && !"\n\r\u2028\u2029".includes(this.src[end])) {
|
|
193
|
-
end++;
|
|
194
|
-
}
|
|
195
|
-
if (this.src[end] === "\r" && this.src[end + 1] === "\n") end++;
|
|
196
|
-
this.index = end < this.src.length ? end + 1 : this.src.length;
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
if (this.src.startsWith("/*", this.index)) {
|
|
200
|
-
const end = this.src.indexOf("*/", this.index + 2);
|
|
201
|
-
if (end === -1) throw this.fail("unterminated comment");
|
|
202
|
-
this.index = end + 2;
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
parseValue(depth) {
|
|
209
|
-
if (depth > MAX_DEPTH) throw this.fail("meta literal is nested too deeply");
|
|
210
|
-
this.skipTrivia();
|
|
211
|
-
const c = this.src[this.index];
|
|
212
|
-
if (c === void 0) throw this.fail("unexpected end of meta literal");
|
|
213
|
-
if (c === "{") return this.parseObject(depth);
|
|
214
|
-
if (c === "[") return this.parseArray(depth);
|
|
215
|
-
if (c === '"' || c === "'" || c === "`") return this.parseString();
|
|
216
|
-
if (c === "-" || c >= "0" && c <= "9") return this.parseNumber();
|
|
217
|
-
if (this.src.startsWith("true", this.index)) return this.word("true", true);
|
|
218
|
-
if (this.src.startsWith("false", this.index)) {
|
|
219
|
-
return this.word("false", false);
|
|
220
|
-
}
|
|
221
|
-
if (this.src.startsWith("null", this.index)) return this.word("null", null);
|
|
222
|
-
if (c === "/")
|
|
223
|
-
throw this.fail("regular expressions are not allowed in meta");
|
|
224
|
-
throw this.fail("unsupported value");
|
|
225
|
-
}
|
|
226
|
-
word(literal, value) {
|
|
227
|
-
const after = this.src[this.index + literal.length];
|
|
228
|
-
if (after !== void 0 && ID_PART.test(after)) {
|
|
229
|
-
throw this.fail("unsupported value");
|
|
230
|
-
}
|
|
231
|
-
this.index += literal.length;
|
|
232
|
-
return value;
|
|
233
|
-
}
|
|
234
|
-
parseObject(depth) {
|
|
235
|
-
this.index++;
|
|
236
|
-
const out = /* @__PURE__ */ Object.create(null);
|
|
237
|
-
for (; ; ) {
|
|
238
|
-
this.skipTrivia();
|
|
239
|
-
const c = this.src[this.index];
|
|
240
|
-
if (c === "}") {
|
|
241
|
-
this.index++;
|
|
242
|
-
return out;
|
|
243
|
-
}
|
|
244
|
-
if (c === void 0) throw this.fail("unterminated object");
|
|
245
|
-
if (this.src.startsWith("...", this.index)) {
|
|
246
|
-
throw this.fail("spread is not allowed in meta");
|
|
247
|
-
}
|
|
248
|
-
if (c === "[") throw this.fail("computed keys are not allowed in meta");
|
|
249
|
-
const key = this.parseKey();
|
|
250
|
-
this.skipTrivia();
|
|
251
|
-
if (this.src[this.index] === "(") {
|
|
252
|
-
throw this.fail("methods are not allowed in meta");
|
|
253
|
-
}
|
|
254
|
-
if (this.src[this.index] !== ":")
|
|
255
|
-
throw this.fail('expected ":" after key');
|
|
256
|
-
this.index++;
|
|
257
|
-
out[key] = this.parseValue(depth + 1);
|
|
258
|
-
this.skipTrivia();
|
|
259
|
-
if (this.src[this.index] === ",") {
|
|
260
|
-
this.index++;
|
|
261
|
-
continue;
|
|
262
|
-
}
|
|
263
|
-
if (this.src[this.index] === "}") {
|
|
264
|
-
this.index++;
|
|
265
|
-
return out;
|
|
266
|
-
}
|
|
267
|
-
throw this.fail('expected "," or "}"');
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
parseKey() {
|
|
271
|
-
const c = this.src[this.index];
|
|
272
|
-
if (c === '"' || c === "'" || c === "`") return this.parseString();
|
|
273
|
-
if (c !== void 0 && ID_START.test(c)) {
|
|
274
|
-
const start = this.index;
|
|
275
|
-
while (this.index < this.src.length && ID_PART.test(this.src[this.index])) {
|
|
276
|
-
this.index++;
|
|
277
|
-
}
|
|
278
|
-
const word = this.src.slice(start, this.index);
|
|
279
|
-
if (word === "get" || word === "set" || word === "async") {
|
|
280
|
-
const save = this.index;
|
|
281
|
-
this.skipTrivia();
|
|
282
|
-
const next = this.src[this.index];
|
|
283
|
-
const startsPropertyName = next !== void 0 && (ID_START.test(next) || next === '"' || next === "'" || next === "[");
|
|
284
|
-
this.index = save;
|
|
285
|
-
if (startsPropertyName) {
|
|
286
|
-
throw this.fail(
|
|
287
|
-
word === "async" ? "async members are not allowed in meta" : `${word}ters are not allowed in meta`
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
return word;
|
|
292
|
-
}
|
|
293
|
-
throw this.fail("expected a property name");
|
|
294
|
-
}
|
|
295
|
-
parseArray(depth) {
|
|
296
|
-
this.index++;
|
|
297
|
-
const out = [];
|
|
298
|
-
for (; ; ) {
|
|
299
|
-
this.skipTrivia();
|
|
300
|
-
const c = this.src[this.index];
|
|
301
|
-
if (c === "]") {
|
|
302
|
-
this.index++;
|
|
303
|
-
return out;
|
|
304
|
-
}
|
|
305
|
-
if (c === void 0) throw this.fail("unterminated array");
|
|
306
|
-
if (this.src.startsWith("...", this.index)) {
|
|
307
|
-
throw this.fail("spread is not allowed in meta");
|
|
308
|
-
}
|
|
309
|
-
if (c === ",") throw this.fail("missing array element");
|
|
310
|
-
out.push(this.parseValue(depth + 1));
|
|
311
|
-
this.skipTrivia();
|
|
312
|
-
if (this.src[this.index] === ",") {
|
|
313
|
-
this.index++;
|
|
314
|
-
continue;
|
|
315
|
-
}
|
|
316
|
-
if (this.src[this.index] === "]") {
|
|
317
|
-
this.index++;
|
|
318
|
-
return out;
|
|
319
|
-
}
|
|
320
|
-
throw this.fail('expected "," or "]"');
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
parseString() {
|
|
324
|
-
const quote = this.src[this.index++];
|
|
325
|
-
let out = "";
|
|
326
|
-
for (; ; ) {
|
|
327
|
-
const c = this.src[this.index];
|
|
328
|
-
if (c === void 0) throw this.fail("unterminated string");
|
|
329
|
-
if (c === quote) {
|
|
330
|
-
this.index++;
|
|
331
|
-
return out;
|
|
332
|
-
}
|
|
333
|
-
if (c === "\n" || c === "\r") {
|
|
334
|
-
if (quote !== "`") throw this.fail("unterminated string");
|
|
335
|
-
if (c === "\r") {
|
|
336
|
-
this.index++;
|
|
337
|
-
if (this.src[this.index] === "\n") this.index++;
|
|
338
|
-
out += "\n";
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
if (quote === "`" && c === "$" && this.src[this.index + 1] === "{") {
|
|
343
|
-
throw this.fail("template substitutions are not allowed in meta");
|
|
344
|
-
}
|
|
345
|
-
if (c === "\\") {
|
|
346
|
-
out += this.parseEscape();
|
|
347
|
-
continue;
|
|
348
|
-
}
|
|
349
|
-
out += c;
|
|
350
|
-
this.index++;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
parseEscape() {
|
|
354
|
-
this.index++;
|
|
355
|
-
const c = this.src[this.index++];
|
|
356
|
-
switch (c) {
|
|
357
|
-
case "n":
|
|
358
|
-
return "\n";
|
|
359
|
-
case "t":
|
|
360
|
-
return " ";
|
|
361
|
-
case "r":
|
|
362
|
-
return "\r";
|
|
363
|
-
case "b":
|
|
364
|
-
return "\b";
|
|
365
|
-
case "f":
|
|
366
|
-
return "\f";
|
|
367
|
-
case "v":
|
|
368
|
-
return "\v";
|
|
369
|
-
case "0":
|
|
370
|
-
if (/[0-9]/.test(this.src[this.index] ?? "")) {
|
|
371
|
-
throw this.fail("octal escapes are not allowed in meta");
|
|
372
|
-
}
|
|
373
|
-
return "\0";
|
|
374
|
-
case "x": {
|
|
375
|
-
const hex = this.src.slice(this.index, this.index + 2);
|
|
376
|
-
if (!/^[0-9a-fA-F]{2}$/.test(hex)) {
|
|
377
|
-
throw this.fail("invalid \\x escape");
|
|
378
|
-
}
|
|
379
|
-
this.index += 2;
|
|
380
|
-
return String.fromCharCode(parseInt(hex, 16));
|
|
381
|
-
}
|
|
382
|
-
case "u": {
|
|
383
|
-
if (this.src[this.index] === "{") {
|
|
384
|
-
const end = this.src.indexOf("}", this.index);
|
|
385
|
-
const hex2 = end === -1 ? "" : this.src.slice(this.index + 1, end);
|
|
386
|
-
if (!/^[0-9a-fA-F]{1,6}$/.test(hex2)) {
|
|
387
|
-
throw this.fail("invalid \\u{...} escape");
|
|
388
|
-
}
|
|
389
|
-
const code = parseInt(hex2, 16);
|
|
390
|
-
if (code > 1114111) throw this.fail("invalid \\u{...} escape");
|
|
391
|
-
this.index = end + 1;
|
|
392
|
-
return String.fromCodePoint(code);
|
|
393
|
-
}
|
|
394
|
-
const hex = this.src.slice(this.index, this.index + 4);
|
|
395
|
-
if (!/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
396
|
-
throw this.fail("invalid \\u escape");
|
|
397
|
-
}
|
|
398
|
-
this.index += 4;
|
|
399
|
-
return String.fromCharCode(parseInt(hex, 16));
|
|
400
|
-
}
|
|
401
|
-
case "\n":
|
|
402
|
-
return "";
|
|
403
|
-
// line continuation
|
|
404
|
-
case "\r":
|
|
405
|
-
if (this.src[this.index] === "\n") this.index++;
|
|
406
|
-
return "";
|
|
407
|
-
case "\u2028":
|
|
408
|
-
case "\u2029":
|
|
409
|
-
return "";
|
|
410
|
-
case void 0:
|
|
411
|
-
throw this.fail("unterminated escape sequence");
|
|
412
|
-
default:
|
|
413
|
-
return c;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
parseNumber() {
|
|
417
|
-
const start = this.index;
|
|
418
|
-
if (this.src[this.index] === "-") this.index++;
|
|
419
|
-
while (this.index < this.src.length && /[0-9]/.test(this.src[this.index])) {
|
|
420
|
-
this.index++;
|
|
421
|
-
}
|
|
422
|
-
if (this.src[this.index] === ".") {
|
|
423
|
-
this.index++;
|
|
424
|
-
while (this.index < this.src.length && /[0-9]/.test(this.src[this.index])) {
|
|
425
|
-
this.index++;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
if (this.src[this.index] === "e" || this.src[this.index] === "E") {
|
|
429
|
-
this.index++;
|
|
430
|
-
if (this.src[this.index] === "+" || this.src[this.index] === "-") {
|
|
431
|
-
this.index++;
|
|
432
|
-
}
|
|
433
|
-
while (this.index < this.src.length && /[0-9]/.test(this.src[this.index])) {
|
|
434
|
-
this.index++;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
const after = this.src[this.index];
|
|
438
|
-
if (after !== void 0 && ID_PART.test(after)) {
|
|
439
|
-
throw this.fail("unsupported numeric literal");
|
|
440
|
-
}
|
|
441
|
-
const text = this.src.slice(start, this.index);
|
|
442
|
-
const value = Number(text);
|
|
443
|
-
if (text.length === 0 || !Number.isFinite(value)) {
|
|
444
|
-
throw this.fail("unsupported numeric literal");
|
|
445
|
-
}
|
|
446
|
-
return value;
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
// packages/core/src/agents/runtime/workflow-sandbox.ts
|
|
451
|
-
function findMetaBlockBounds(source) {
|
|
452
|
-
const re = /^\s*export\s+const\s+meta\s*=\s*\{/;
|
|
453
|
-
const match = re.exec(source);
|
|
454
|
-
if (!match) return null;
|
|
455
|
-
const exportIdx = match.index;
|
|
456
|
-
const startBrace = source.indexOf("{", exportIdx);
|
|
457
|
-
let depth = 1;
|
|
458
|
-
let i = startBrace + 1;
|
|
459
|
-
while (i < source.length && depth > 0) {
|
|
460
|
-
const ch = source[i];
|
|
461
|
-
const next = source[i + 1];
|
|
462
|
-
if (ch === "/" && next === "/") {
|
|
463
|
-
i += 2;
|
|
464
|
-
while (i < source.length && source[i] !== "\n") i++;
|
|
465
|
-
continue;
|
|
466
|
-
}
|
|
467
|
-
if (ch === "/" && next === "*") {
|
|
468
|
-
i += 2;
|
|
469
|
-
while (i < source.length && !(source[i] === "*" && source[i + 1] === "/"))
|
|
470
|
-
i++;
|
|
471
|
-
i += 2;
|
|
472
|
-
continue;
|
|
473
|
-
}
|
|
474
|
-
if (ch === "/" && isRegexContext(source, i)) {
|
|
475
|
-
i++;
|
|
476
|
-
let inClass = false;
|
|
477
|
-
while (i < source.length && (inClass || source[i] !== "/") && source[i] !== "\n") {
|
|
478
|
-
if (source[i] === "\\") i += 2;
|
|
479
|
-
else if (source[i] === "[") {
|
|
480
|
-
inClass = true;
|
|
481
|
-
i++;
|
|
482
|
-
} else if (source[i] === "]") {
|
|
483
|
-
inClass = false;
|
|
484
|
-
i++;
|
|
485
|
-
} else {
|
|
486
|
-
i++;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
i++;
|
|
490
|
-
while (i < source.length && /[gimsuy]/.test(source[i])) i++;
|
|
491
|
-
continue;
|
|
492
|
-
}
|
|
493
|
-
if (ch === '"' || ch === "'" || ch === "`") {
|
|
494
|
-
const q = ch;
|
|
495
|
-
i++;
|
|
496
|
-
while (i < source.length && source[i] !== q) {
|
|
497
|
-
if (source[i] === "\\") i++;
|
|
498
|
-
i++;
|
|
499
|
-
}
|
|
500
|
-
i++;
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
if (ch === "{") depth++;
|
|
504
|
-
else if (ch === "}") depth--;
|
|
505
|
-
i++;
|
|
506
|
-
}
|
|
507
|
-
if (depth !== 0) {
|
|
508
|
-
throw new Error(
|
|
509
|
-
"unbalanced braces in export const meta declaration \u2014 the workflow script cannot be safely stripped. Check the meta block syntax."
|
|
510
|
-
);
|
|
511
|
-
}
|
|
512
|
-
const endBraceIncl = i - 1;
|
|
513
|
-
while (i < source.length && /[\s;]/.test(source[i])) i++;
|
|
514
|
-
return { exportIdx, startBrace, endBraceIncl, afterMeta: i };
|
|
515
|
-
}
|
|
516
|
-
__name(findMetaBlockBounds, "findMetaBlockBounds");
|
|
517
|
-
function extractAndStripMeta(source) {
|
|
518
|
-
const bounds = findMetaBlockBounds(source);
|
|
519
|
-
if (!bounds) return { stripped: source, meta: null };
|
|
520
|
-
const metaSource = source.slice(bounds.startBrace, bounds.endBraceIncl + 1);
|
|
521
|
-
const stripped = source.slice(0, bounds.exportIdx) + source.slice(bounds.afterMeta);
|
|
522
|
-
let raw;
|
|
523
|
-
try {
|
|
524
|
-
raw = parseWorkflowMetaLiteral(metaSource);
|
|
525
|
-
} catch (e) {
|
|
526
|
-
const msg = e instanceof Error ? e.message : String(e);
|
|
527
|
-
throw new Error(`invalid meta object literal: ${msg}`);
|
|
528
|
-
}
|
|
529
|
-
const meta = validateMeta(raw);
|
|
530
|
-
return { stripped, meta };
|
|
531
|
-
}
|
|
532
|
-
__name(extractAndStripMeta, "extractAndStripMeta");
|
|
533
|
-
var WORKFLOW_SCRIPT_FILENAME = "workflow.js";
|
|
534
|
-
function wrapWorkflowBody(strippedSource) {
|
|
535
|
-
return `(async () => {'use strict';
|
|
536
|
-
${strippedSource}
|
|
537
|
-
})()`;
|
|
538
|
-
}
|
|
539
|
-
__name(wrapWorkflowBody, "wrapWorkflowBody");
|
|
540
|
-
function compileWorkflowScript(scriptSource) {
|
|
541
|
-
const { stripped, meta } = extractAndStripMeta(scriptSource);
|
|
542
|
-
const bounds = findMetaBlockBounds(scriptSource);
|
|
543
|
-
const compilable = bounds ? scriptSource.slice(0, bounds.exportIdx) + scriptSource.slice(bounds.exportIdx, bounds.afterMeta).replace(/[^\r\n\u2028\u2029]/g, " ") + scriptSource.slice(bounds.afterMeta) : stripped;
|
|
544
|
-
const script = new vm.Script(wrapWorkflowBody(compilable), {
|
|
545
|
-
filename: WORKFLOW_SCRIPT_FILENAME
|
|
546
|
-
});
|
|
547
|
-
return { script, meta };
|
|
548
|
-
}
|
|
549
|
-
__name(compileWorkflowScript, "compileWorkflowScript");
|
|
550
|
-
function workflowCancelledError() {
|
|
551
|
-
const error = new Error("Workflow run was aborted (cancelled).");
|
|
552
|
-
error.name = "AbortError";
|
|
553
|
-
return error;
|
|
554
|
-
}
|
|
555
|
-
__name(workflowCancelledError, "workflowCancelledError");
|
|
556
|
-
var COMPILE_ERROR_LINE_WIDTH = 80;
|
|
557
|
-
function describeWorkflowCompileError(error, authorLineCount) {
|
|
558
|
-
const err = error instanceof Error ? error : new Error(String(error));
|
|
559
|
-
const stack = typeof err.stack === "string" ? err.stack : "";
|
|
560
|
-
const frame = [];
|
|
561
|
-
for (const line of stack.split("\n")) {
|
|
562
|
-
if (frame.length >= 3 && /^\s+at\s/.test(line)) break;
|
|
563
|
-
frame.push(line);
|
|
564
|
-
}
|
|
565
|
-
const header = frame[0] ?? "";
|
|
566
|
-
const match = /^.*?:(\d+)$/.exec(header);
|
|
567
|
-
if (frame.length < 3 || !match) {
|
|
568
|
-
return err.message;
|
|
569
|
-
}
|
|
570
|
-
const bodyLine = Number(match[1]) - 1;
|
|
571
|
-
if (bodyLine < 1) return err.message;
|
|
572
|
-
if (bodyLine > authorLineCount) {
|
|
573
|
-
return "The script ends with unmatched or incomplete syntax. Check parentheses, brackets, braces, quotes, and template literals near the end.";
|
|
574
|
-
}
|
|
575
|
-
const rendered = clampSourceFrame(frame[1] ?? "", frame[2] ?? "");
|
|
576
|
-
const tail = frame.slice(3).filter((l) => l.trim().length > 0).join("\n");
|
|
577
|
-
return [`line ${bodyLine}`, rendered, tail].filter(Boolean).join("\n");
|
|
578
|
-
}
|
|
579
|
-
__name(describeWorkflowCompileError, "describeWorkflowCompileError");
|
|
580
|
-
function clampSourceFrame(sourceLine, caretLine) {
|
|
581
|
-
if (sourceLine.length <= COMPILE_ERROR_LINE_WIDTH) {
|
|
582
|
-
return `${sourceLine}
|
|
583
|
-
${caretLine}`;
|
|
584
|
-
}
|
|
585
|
-
const caret = /\^+/.exec(caretLine);
|
|
586
|
-
if (!caret) return "";
|
|
587
|
-
const caretCol = caret.index;
|
|
588
|
-
const start = Math.max(
|
|
589
|
-
0,
|
|
590
|
-
Math.min(
|
|
591
|
-
caretCol - Math.floor(COMPILE_ERROR_LINE_WIDTH / 2),
|
|
592
|
-
sourceLine.length - COMPILE_ERROR_LINE_WIDTH
|
|
593
|
-
)
|
|
594
|
-
);
|
|
595
|
-
const prefix = start > 0 ? "\u2026" : "";
|
|
596
|
-
const window = sourceLine.slice(start, start + COMPILE_ERROR_LINE_WIDTH);
|
|
597
|
-
const suffix = start + COMPILE_ERROR_LINE_WIDTH < sourceLine.length ? "\u2026" : "";
|
|
598
|
-
const visibleCaretStart = Math.max(caretCol, start);
|
|
599
|
-
const visibleCaretEnd = Math.min(
|
|
600
|
-
caretCol + caret[0].length,
|
|
601
|
-
start + COMPILE_ERROR_LINE_WIDTH
|
|
602
|
-
);
|
|
603
|
-
const shiftedCaret = " ".repeat(prefix.length + visibleCaretStart - start) + "^".repeat(visibleCaretEnd - visibleCaretStart);
|
|
604
|
-
return `${prefix}${window}${suffix}
|
|
605
|
-
${shiftedCaret}`;
|
|
606
|
-
}
|
|
607
|
-
__name(clampSourceFrame, "clampSourceFrame");
|
|
608
|
-
function validateMeta(value) {
|
|
609
|
-
if (value === null || typeof value !== "object") {
|
|
610
|
-
throw new Error("meta must be an object");
|
|
611
|
-
}
|
|
612
|
-
const obj = value;
|
|
613
|
-
if (typeof obj["name"] !== "string" || obj["name"].length === 0) {
|
|
614
|
-
throw new Error("meta.name must be a non-empty string");
|
|
615
|
-
}
|
|
616
|
-
if (typeof obj["description"] !== "string" || obj["description"].length === 0) {
|
|
617
|
-
throw new Error("meta.description must be a non-empty string");
|
|
618
|
-
}
|
|
619
|
-
if (obj["whenToUse"] !== void 0 && typeof obj["whenToUse"] !== "string") {
|
|
620
|
-
throw new Error("meta.whenToUse must be a string");
|
|
621
|
-
}
|
|
622
|
-
let phases;
|
|
623
|
-
if (obj["phases"] !== void 0) {
|
|
624
|
-
if (!Array.isArray(obj["phases"])) {
|
|
625
|
-
throw new Error("meta.phases must be an array");
|
|
626
|
-
}
|
|
627
|
-
phases = [];
|
|
628
|
-
for (const p of obj["phases"]) {
|
|
629
|
-
if (p === null || typeof p !== "object") {
|
|
630
|
-
throw new Error("meta.phases entries must be objects");
|
|
631
|
-
}
|
|
632
|
-
const ph = p;
|
|
633
|
-
if (typeof ph["title"] !== "string" || ph["title"].length === 0) {
|
|
634
|
-
throw new Error("meta.phases[].title must be a non-empty string");
|
|
635
|
-
}
|
|
636
|
-
const phase = {
|
|
637
|
-
title: ph["title"]
|
|
638
|
-
};
|
|
639
|
-
if (ph["detail"] !== void 0) {
|
|
640
|
-
if (typeof ph["detail"] !== "string") {
|
|
641
|
-
throw new Error("meta.phases[].detail must be a string");
|
|
642
|
-
}
|
|
643
|
-
phase.detail = ph["detail"];
|
|
644
|
-
}
|
|
645
|
-
if (ph["model"] !== void 0) {
|
|
646
|
-
if (typeof ph["model"] !== "string") {
|
|
647
|
-
throw new Error("meta.phases[].model must be a string");
|
|
648
|
-
}
|
|
649
|
-
phase.model = ph["model"];
|
|
650
|
-
}
|
|
651
|
-
phases.push(phase);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
const out = {
|
|
655
|
-
name: obj["name"],
|
|
656
|
-
description: obj["description"]
|
|
657
|
-
};
|
|
658
|
-
if (obj["whenToUse"] !== void 0) {
|
|
659
|
-
out.whenToUse = obj["whenToUse"];
|
|
660
|
-
}
|
|
661
|
-
if (phases !== void 0) {
|
|
662
|
-
out.phases = phases;
|
|
663
|
-
}
|
|
664
|
-
return out;
|
|
665
|
-
}
|
|
666
|
-
__name(validateMeta, "validateMeta");
|
|
667
|
-
function isRegexContext(source, i) {
|
|
668
|
-
let j = i - 1;
|
|
669
|
-
while (j >= 0 && /\s/.test(source[j])) j--;
|
|
670
|
-
if (j < 0) return true;
|
|
671
|
-
const prev = source[j];
|
|
672
|
-
return /[{[(,;:=!&|?+\-*/%^~<>]/.test(prev);
|
|
673
|
-
}
|
|
674
|
-
__name(isRegexContext, "isRegexContext");
|
|
675
|
-
var debugLogger = createDebugLogger("WORKFLOW");
|
|
676
|
-
var MAX_LOG_LINES = 1e4;
|
|
677
|
-
var MAX_PHASE_ENTRIES = 1e4;
|
|
678
|
-
var ARGS_MAX_DEPTH = 64;
|
|
679
|
-
var DEFAULT_MAX_WALL_CLOCK_MS = 30 * 60 * 1e3;
|
|
680
|
-
function resolveMaxWallClockMs(opts) {
|
|
681
|
-
if (typeof opts.maxWallClockMs === "number" && opts.maxWallClockMs > 0) {
|
|
682
|
-
return opts.maxWallClockMs;
|
|
683
|
-
}
|
|
684
|
-
const envSec = Number(process.env["QWEN_CODE_MAX_WORKFLOW_SECONDS"]);
|
|
685
|
-
if (Number.isFinite(envSec) && envSec > 0) return envSec * 1e3;
|
|
686
|
-
return DEFAULT_MAX_WALL_CLOCK_MS;
|
|
687
|
-
}
|
|
688
|
-
__name(resolveMaxWallClockMs, "resolveMaxWallClockMs");
|
|
689
|
-
var WallClockWatchdog = class {
|
|
690
|
-
constructor(budgetMs, onFire) {
|
|
691
|
-
this.onFire = onFire;
|
|
692
|
-
this.remainingMs = budgetMs;
|
|
693
|
-
this.arm();
|
|
694
|
-
}
|
|
695
|
-
static {
|
|
696
|
-
__name(this, "WallClockWatchdog");
|
|
697
|
-
}
|
|
698
|
-
timer;
|
|
699
|
-
remainingMs;
|
|
700
|
-
armedAt = 0;
|
|
701
|
-
paused = false;
|
|
702
|
-
stopped = false;
|
|
703
|
-
pause() {
|
|
704
|
-
if (this.stopped || this.paused || this.timer === void 0) return;
|
|
705
|
-
this.paused = true;
|
|
706
|
-
clearTimeout(this.timer);
|
|
707
|
-
this.timer = void 0;
|
|
708
|
-
this.remainingMs = Math.max(
|
|
709
|
-
0,
|
|
710
|
-
this.remainingMs - (performance.now() - this.armedAt)
|
|
711
|
-
);
|
|
712
|
-
}
|
|
713
|
-
resume() {
|
|
714
|
-
if (this.stopped || !this.paused) return;
|
|
715
|
-
this.paused = false;
|
|
716
|
-
this.arm();
|
|
717
|
-
}
|
|
718
|
-
stop() {
|
|
719
|
-
this.stopped = true;
|
|
720
|
-
if (this.timer !== void 0) clearTimeout(this.timer);
|
|
721
|
-
this.timer = void 0;
|
|
722
|
-
}
|
|
723
|
-
arm() {
|
|
724
|
-
this.armedAt = performance.now();
|
|
725
|
-
this.timer = setTimeout(() => {
|
|
726
|
-
this.stopped = true;
|
|
727
|
-
this.timer = void 0;
|
|
728
|
-
this.onFire();
|
|
729
|
-
}, this.remainingMs);
|
|
730
|
-
this.timer.unref?.();
|
|
731
|
-
}
|
|
732
|
-
};
|
|
733
|
-
function validateArgs(val, depth = 0, seen = /* @__PURE__ */ new WeakSet()) {
|
|
734
|
-
if (depth > ARGS_MAX_DEPTH) {
|
|
735
|
-
throw new Error(
|
|
736
|
-
`WorkflowSandbox: args exceeded max nesting depth of ${ARGS_MAX_DEPTH}`
|
|
737
|
-
);
|
|
738
|
-
}
|
|
739
|
-
if (val === null) return;
|
|
740
|
-
const t = typeof val;
|
|
741
|
-
if (t === "function") {
|
|
742
|
-
throw new Error(
|
|
743
|
-
"WorkflowSandbox: args must be JSON-serializable (functions are not allowed)."
|
|
744
|
-
);
|
|
745
|
-
}
|
|
746
|
-
if (t === "bigint") {
|
|
747
|
-
throw new Error(
|
|
748
|
-
"WorkflowSandbox: args must be JSON-serializable (BigInt is not allowed \u2014 pass as string)."
|
|
749
|
-
);
|
|
750
|
-
}
|
|
751
|
-
if (t !== "object") return;
|
|
752
|
-
const obj = val;
|
|
753
|
-
if (seen.has(obj)) {
|
|
754
|
-
throw new Error(
|
|
755
|
-
"WorkflowSandbox: args must be JSON-serializable (circular reference detected)."
|
|
756
|
-
);
|
|
757
|
-
}
|
|
758
|
-
seen.add(obj);
|
|
759
|
-
if (Array.isArray(val)) {
|
|
760
|
-
for (const item of val) validateArgs(item, depth + 1, seen);
|
|
761
|
-
} else {
|
|
762
|
-
for (const v of Object.values(val)) {
|
|
763
|
-
validateArgs(v, depth + 1, seen);
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
__name(validateArgs, "validateArgs");
|
|
768
|
-
function createWorkflowSandbox(opts) {
|
|
769
|
-
const phases = [];
|
|
770
|
-
const logs = [];
|
|
771
|
-
const emitLog = /* @__PURE__ */ __name((line) => {
|
|
772
|
-
try {
|
|
773
|
-
opts.emitter?.logAppended?.(line);
|
|
774
|
-
} catch (e) {
|
|
775
|
-
debugLogger.warn("emitter.logAppended threw:", e);
|
|
776
|
-
}
|
|
777
|
-
}, "emitLog");
|
|
778
|
-
const safeLog = /* @__PURE__ */ __name((msg, notify = true) => {
|
|
779
|
-
if (logs.length < MAX_LOG_LINES) {
|
|
780
|
-
const line = String(msg);
|
|
781
|
-
logs.push(line);
|
|
782
|
-
if (notify) emitLog(line);
|
|
783
|
-
} else if (logs.length === MAX_LOG_LINES) {
|
|
784
|
-
const line = `[workflow log truncated at ${MAX_LOG_LINES} lines]`;
|
|
785
|
-
logs.push(line);
|
|
786
|
-
if (notify) emitLog(line);
|
|
787
|
-
}
|
|
788
|
-
}, "safeLog");
|
|
789
|
-
const safePhase = /* @__PURE__ */ __name((title) => {
|
|
790
|
-
if (phases.length < MAX_PHASE_ENTRIES) {
|
|
791
|
-
const t = stripAnsiAndControl(String(title)).slice(0, 200) || "phase";
|
|
792
|
-
if (phases[phases.length - 1] === t) return;
|
|
793
|
-
phases.push(t);
|
|
794
|
-
try {
|
|
795
|
-
opts.emitter?.phaseStarted?.(t);
|
|
796
|
-
} catch (e) {
|
|
797
|
-
debugLogger.warn("emitter.phaseStarted threw:", e);
|
|
798
|
-
}
|
|
799
|
-
} else if (phases.length === MAX_PHASE_ENTRIES) {
|
|
800
|
-
phases.push(
|
|
801
|
-
`[workflow phases truncated at ${MAX_PHASE_ENTRIES} entries]`
|
|
802
|
-
);
|
|
803
|
-
}
|
|
804
|
-
}, "safePhase");
|
|
805
|
-
if (opts.args !== void 0) validateArgs(opts.args);
|
|
806
|
-
const argsJson = opts.args === void 0 ? null : JSON.stringify(opts.args);
|
|
807
|
-
const unconsumedRoots = /* @__PURE__ */ new Map();
|
|
808
|
-
const unconsumedRejections = /* @__PURE__ */ new Map();
|
|
809
|
-
let nextUnconsumedId = 1;
|
|
810
|
-
let unconsumedSettled = false;
|
|
811
|
-
let mirroredEscapeKeys = /* @__PURE__ */ new Set();
|
|
812
|
-
const unconsumedRejectionLine = /* @__PURE__ */ __name((rec) => {
|
|
813
|
-
if (rec.dispatchFailed) {
|
|
814
|
-
return rec.isRoot ? "dispatch failed (result not consumed): " + rec.msg : "dispatch failed (rejection not handled): " + rec.msg;
|
|
815
|
-
}
|
|
816
|
-
return "script handler failed (rejection not handled): " + rec.msg;
|
|
817
|
-
}, "unconsumedRejectionLine");
|
|
818
|
-
const bridge = {
|
|
819
|
-
argsJson,
|
|
820
|
-
pushPhase: safePhase,
|
|
821
|
-
pushLog: safeLog,
|
|
822
|
-
lastPhase: /* @__PURE__ */ __name(() => phases[phases.length - 1], "lastPhase"),
|
|
823
|
-
hostAgent: opts.dispatch,
|
|
824
|
-
// PR #4947 R2 T7 (qwen-code-ci-bot): host-side log hook for reviveInRealm's
|
|
825
|
-
// catch path. Mirrors the rejection-logging in settleToNullArray so an
|
|
826
|
-
// operator running with debug logging can distinguish "thunk rejected"
|
|
827
|
-
// (settleToNullArray.warn) from "thunk resolved to a non-JSON-serializable
|
|
828
|
-
// value" (this warn). Receives only primitive strings/numbers — the bridge
|
|
829
|
-
// contract forbids host objects crossing back to the script.
|
|
830
|
-
logRevivalFailure: /* @__PURE__ */ __name((idx, reason) => {
|
|
831
|
-
debugLogger.warn(
|
|
832
|
-
`Workflow result revival failed at index ${idx}: ${reason}; slot set to null (non-JSON-serializable thunk return).`
|
|
833
|
-
);
|
|
834
|
-
}, "logRevivalFailure"),
|
|
835
|
-
// --- Unconsumed-rejection mirror bookkeeping ---
|
|
836
|
-
wfRegisterRoot: /* @__PURE__ */ __name(() => {
|
|
837
|
-
const id = nextUnconsumedId++;
|
|
838
|
-
unconsumedRoots.set(id, { rejectionHandled: false, adoptedOut: false });
|
|
839
|
-
return id;
|
|
840
|
-
}, "wfRegisterRoot"),
|
|
841
|
-
wfMarkRejectionHandled: /* @__PURE__ */ __name((rootId) => {
|
|
842
|
-
const root = unconsumedRoots.get(rootId);
|
|
843
|
-
if (root) root.rejectionHandled = true;
|
|
844
|
-
}, "wfMarkRejectionHandled"),
|
|
845
|
-
wfIsRootHandled: /* @__PURE__ */ __name((rootId) => unconsumedRoots.get(rootId)?.rejectionHandled === true, "wfIsRootHandled"),
|
|
846
|
-
wfMarkAdopted: /* @__PURE__ */ __name((rootId) => {
|
|
847
|
-
const root = unconsumedRoots.get(rootId);
|
|
848
|
-
if (root) root.adoptedOut = true;
|
|
849
|
-
}, "wfMarkAdopted"),
|
|
850
|
-
runId: opts.runId ?? "",
|
|
851
|
-
wfReportUnconsumed: /* @__PURE__ */ __name((rootId, isRoot, dispatchFailed, msg) => {
|
|
852
|
-
if (unconsumedSettled) {
|
|
853
|
-
const rec = {
|
|
854
|
-
rootId,
|
|
855
|
-
isRoot,
|
|
856
|
-
dispatchFailed,
|
|
857
|
-
msg
|
|
858
|
-
};
|
|
859
|
-
const rootState = unconsumedRoots.get(rootId);
|
|
860
|
-
if (!rootState?.rejectionHandled && !(dispatchFailed && rootState?.adoptedOut)) {
|
|
861
|
-
safeLog(unconsumedRejectionLine(rec));
|
|
862
|
-
}
|
|
863
|
-
return 0;
|
|
864
|
-
}
|
|
865
|
-
const id = nextUnconsumedId++;
|
|
866
|
-
unconsumedRejections.set(id, { rootId, isRoot, dispatchFailed, msg });
|
|
867
|
-
return id;
|
|
868
|
-
}, "wfReportUnconsumed"),
|
|
869
|
-
wfClearUnconsumed: /* @__PURE__ */ __name((id) => {
|
|
870
|
-
unconsumedRejections.delete(id);
|
|
871
|
-
}, "wfClearUnconsumed"),
|
|
872
|
-
// R10-1: teardown discrimination cannot key on the error name alone.
|
|
873
|
-
// The dominant in-flight cancellation path (controller.abort() →
|
|
874
|
-
// subagent returns terminateMode=CANCELLED → runSingleDispatch throws
|
|
875
|
-
// a PLAIN Error) never produces an 'AbortError', so the mirror would
|
|
876
|
-
// log a spurious dispatch failure for a correctly-cancelled run. Once
|
|
877
|
-
// the run's abort signal has fired, the run is already settling as
|
|
878
|
-
// cancelled / timed-out — every rejection still crossing the boundary
|
|
879
|
-
// is teardown noise regardless of its shape.
|
|
880
|
-
isRunAborted: /* @__PURE__ */ __name(() => opts.abortOnTimeout?.signal.aborted === true, "isRunAborted"),
|
|
881
|
-
// The truthy flags distinguish "injected" from "default stub" inside the
|
|
882
|
-
// init script without leaking the host function itself when not used.
|
|
883
|
-
hasParallel: !!opts.parallel,
|
|
884
|
-
hasPipeline: !!opts.pipeline,
|
|
885
|
-
hasWorkflow: !!opts.workflow,
|
|
886
|
-
hasBudget: !!opts.budget,
|
|
887
|
-
hostParallel: opts.parallel,
|
|
888
|
-
hostPipeline: opts.pipeline,
|
|
889
|
-
hostWorkflow: opts.workflow,
|
|
890
|
-
budgetTotal: opts.budget ? opts.budget.total : null,
|
|
891
|
-
hostBudgetSpent: opts.budget ? opts.budget.spent.bind(opts.budget) : null,
|
|
892
|
-
hostBudgetRemaining: opts.budget ? opts.budget.remaining.bind(opts.budget) : null
|
|
893
|
-
};
|
|
894
|
-
Object.setPrototypeOf(bridge, null);
|
|
895
|
-
const sandboxGlobals = Object.assign(
|
|
896
|
-
/* @__PURE__ */ Object.create(null),
|
|
897
|
-
{ __workflowBridge: bridge }
|
|
898
|
-
);
|
|
899
|
-
const ctx = vm.createContext(sandboxGlobals);
|
|
900
|
-
vm.runInContext(
|
|
901
|
-
`(() => {
|
|
902
|
-
const __b = globalThis.__workflowBridge;
|
|
903
|
-
delete globalThis.__workflowBridge;
|
|
904
|
-
|
|
905
|
-
// --- Math (vm-realm, random throws) ---
|
|
906
|
-
const realMath = Math;
|
|
907
|
-
const safeMath = Object.create(null);
|
|
908
|
-
for (const k of Object.getOwnPropertyNames(realMath)) {
|
|
909
|
-
if (k === 'random' || k === 'constructor') continue;
|
|
910
|
-
safeMath[k] = realMath[k];
|
|
911
|
-
}
|
|
912
|
-
safeMath.random = () => {
|
|
913
|
-
throw new Error(
|
|
914
|
-
'Math.random() is unavailable in workflow scripts (breaks resume). ' +
|
|
915
|
-
'For N independent samples, include the index in the agent label or prompt.'
|
|
916
|
-
);
|
|
917
|
-
};
|
|
918
|
-
globalThis.Math = safeMath;
|
|
919
|
-
|
|
920
|
-
// --- Date (vm-realm function that throws on any access) ---
|
|
921
|
-
const dateMsg = 'Date.now() / new Date() are unavailable in workflow ' +
|
|
922
|
-
'scripts (breaks resume). Stamp results after the workflow returns, ' +
|
|
923
|
-
'or pass timestamps via args.';
|
|
924
|
-
const safeDate = function Date() { throw new Error(dateMsg); };
|
|
925
|
-
safeDate.now = () => { throw new Error(dateMsg); };
|
|
926
|
-
safeDate.UTC = () => { throw new Error(dateMsg); };
|
|
927
|
-
safeDate.parse = () => { throw new Error(dateMsg); };
|
|
928
|
-
Object.setPrototypeOf(safeDate, null);
|
|
929
|
-
Object.defineProperty(safeDate, 'constructor', {
|
|
930
|
-
value: undefined, writable: false, configurable: false,
|
|
931
|
-
});
|
|
932
|
-
globalThis.Date = safeDate;
|
|
933
|
-
|
|
934
|
-
// --- args (parsed via vm-realm JSON \u2192 vm-realm objects/arrays) ---
|
|
935
|
-
// FIX-Round1-T2: vm-realm arrays keep their vm-realm Array.prototype,
|
|
936
|
-
// so for...of, .map, .forEach, spread, destructuring all work \u2014 and
|
|
937
|
-
// their inherited methods' constructors are vm-realm Function, which
|
|
938
|
-
// cannot reach host process.
|
|
939
|
-
globalThis.args = __b.argsJson === null ? undefined : JSON.parse(__b.argsJson);
|
|
940
|
-
|
|
941
|
-
// --- Wrap a host async function so it returns a vm-realm Promise ---
|
|
942
|
-
// FIX-Round1-T1/T8/T14: success and failure both cross the boundary
|
|
943
|
-
// as vm-realm values: resolve with the host's value (a primitive
|
|
944
|
-
// string for dispatch; vm-realm arrays for parallel/pipeline because
|
|
945
|
-
// those wrappers will produce vm-realm results); reject with a
|
|
946
|
-
// freshly-constructed vm-realm Error so e.constructor.constructor
|
|
947
|
-
// stays in the vm realm.
|
|
948
|
-
// Dispatch promises are ObservedPromise instances (a vm-realm
|
|
949
|
-
// Promise subclass). Its then override marks the result consumed
|
|
950
|
-
// and re-attaches the teardown observer to the derived promise, so
|
|
951
|
-
// script-derived chains (agent(...).then(...), await, and the
|
|
952
|
-
// ELEMENTS of static-combinator aggregates \u2014 everything that
|
|
953
|
-
// funnels through then) stay observed at every depth. The
|
|
954
|
-
// AGGREGATES of Promise.all/race/any are built by the native
|
|
955
|
-
// statics and never pass through the observed then, so those
|
|
956
|
-
// statics are wrapped explicitly below (observeAggregate).
|
|
957
|
-
// Without this, a correctly-cancelled run holding a pending derived
|
|
958
|
-
// chain fired a process-level unhandledRejection even though the
|
|
959
|
-
// bare dispatch promise was observed.
|
|
960
|
-
//
|
|
961
|
-
// Unconsumed rejections of an observed node are recorded through
|
|
962
|
-
// the bridge and mirrored into the run log at run settlement (a
|
|
963
|
-
// later consumption clears the record first) \u2014 a dispatch refused
|
|
964
|
-
// at the entry gate (budget / agent cap) or failing mid-run reaches
|
|
965
|
-
// no other surface, so without the mirror the failure leaves no
|
|
966
|
-
// log, alarm, or telemetry.
|
|
967
|
-
function mapDispatchError(hostErr) {
|
|
968
|
-
var msg;
|
|
969
|
-
try {
|
|
970
|
-
msg = (hostErr && hostErr.message != null)
|
|
971
|
-
? String(hostErr.message)
|
|
972
|
-
: String(hostErr);
|
|
973
|
-
} catch (e) {
|
|
974
|
-
msg = '[unserializable rejection value]';
|
|
975
|
-
}
|
|
976
|
-
const vmErr = new Error(msg);
|
|
977
|
-
// Teardown discrimination at the host boundary \u2014 before the error
|
|
978
|
-
// is flattened into a vm-realm Error. Two shapes count as
|
|
979
|
-
// teardown: an error NAMED 'AbortError' (the scheduler's
|
|
980
|
-
// abortError() DOMException), and ANY rejection that crosses
|
|
981
|
-
// after the run's abort signal has fired \u2014 the dominant
|
|
982
|
-
// cancellation path rejects with a plain Error ('did not complete
|
|
983
|
-
// (terminate mode: CANCELLED).'), which a name-only match would
|
|
984
|
-
// mirror as a spurious dispatch failure on a correctly-cancelled
|
|
985
|
-
// run. Matching the name here (rather than the message text)
|
|
986
|
-
// still suppresses teardown noise without swallowing genuine
|
|
987
|
-
// failures whose message merely contains 'aborted' (e.g. a
|
|
988
|
-
// network-layer 'connection aborted by peer').
|
|
989
|
-
var isAbort = false;
|
|
990
|
-
try {
|
|
991
|
-
isAbort = !!(hostErr && hostErr.name === 'AbortError');
|
|
992
|
-
} catch (e) {
|
|
993
|
-
isAbort = false;
|
|
994
|
-
}
|
|
995
|
-
if (isAbort || __b.isRunAborted()) vmErr.__wfAbort = true;
|
|
996
|
-
vmErr.__wfDispatchFailed = true;
|
|
997
|
-
return vmErr;
|
|
998
|
-
}
|
|
999
|
-
function readFlag(value, name) {
|
|
1000
|
-
try {
|
|
1001
|
-
return !!(value && value[name]);
|
|
1002
|
-
} catch (e) {
|
|
1003
|
-
return false;
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
function observeDispatch(promise) {
|
|
1007
|
-
// Direct native-then call: routing through ObservedPromise.then
|
|
1008
|
-
// would mark the promise consumed and recurse the observer. The
|
|
1009
|
-
// observer body must be exception-safe on ANY rejection value:
|
|
1010
|
-
// a script handler can throw an exotic value (a message getter
|
|
1011
|
-
// that throws, a Proxy with throwing traps), and an observer
|
|
1012
|
-
// killed mid-body would turn the very rejection it watches into
|
|
1013
|
-
// a process-level unhandledRejection \u2014 the exact failure class
|
|
1014
|
-
// the observer exists to remove.
|
|
1015
|
-
Promise.prototype.then.call(promise, undefined, function (err) {
|
|
1016
|
-
if (promise.__wfConsumed) return;
|
|
1017
|
-
// R11-30: also suppress on the run-level abort state, not just
|
|
1018
|
-
// the rejection's own marker \u2014 a wrapped Promise.any aggregate
|
|
1019
|
-
// rejects with a natively built AggregateError that carries
|
|
1020
|
-
// neither marker, so teardown rejections of a correctly-
|
|
1021
|
-
// cancelled run would still be mirrored when it is unconsumed.
|
|
1022
|
-
if (readFlag(err, '__wfAbort') || __b.isRunAborted()) return;
|
|
1023
|
-
var dispatchFailed = readFlag(err, '__wfDispatchFailed');
|
|
1024
|
-
var errors = null;
|
|
1025
|
-
try {
|
|
1026
|
-
if (err && Array.isArray(err.errors)) errors = err.errors;
|
|
1027
|
-
} catch (e) {
|
|
1028
|
-
errors = null;
|
|
1029
|
-
}
|
|
1030
|
-
if (!dispatchFailed && errors) {
|
|
1031
|
-
// R11-4: Promise.any rejects with a fresh vm-realm
|
|
1032
|
-
// AggregateError carrying no flags; the element errors are
|
|
1033
|
-
// reachable on .errors with their markers preserved. Derive
|
|
1034
|
-
// the attribution from the causes instead of blaming the
|
|
1035
|
-
// script for a dispatch failure.
|
|
1036
|
-
for (var i = 0; i < errors.length; i++) {
|
|
1037
|
-
if (readFlag(errors[i], '__wfDispatchFailed')) {
|
|
1038
|
-
dispatchFailed = true;
|
|
1039
|
-
break;
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
}
|
|
1043
|
-
// R11-15: cross-root suppression \u2014 aggregate roots track
|
|
1044
|
-
// rejectionHandled independently of their elements' roots, so
|
|
1045
|
-
// a forwarded dispatch failure whose originating element root
|
|
1046
|
-
// the script already handled must not mirror from the
|
|
1047
|
-
// aggregate. The element rootId is stamped in vmAsync;
|
|
1048
|
-
// Promise.all/race forward the element's own reason,
|
|
1049
|
-
// Promise.any surfaces them on .errors.
|
|
1050
|
-
try {
|
|
1051
|
-
var sourceIds = [];
|
|
1052
|
-
if (err && err.__wfRootId) {
|
|
1053
|
-
sourceIds.push(err.__wfRootId);
|
|
1054
|
-
} else if (errors) {
|
|
1055
|
-
for (var j = 0; j < errors.length; j++) {
|
|
1056
|
-
if (errors[j] && errors[j].__wfRootId) {
|
|
1057
|
-
sourceIds.push(errors[j].__wfRootId);
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
for (var k = 0; k < sourceIds.length; k++) {
|
|
1062
|
-
if (
|
|
1063
|
-
sourceIds[k] !== promise.__wfRootId &&
|
|
1064
|
-
__b.wfIsRootHandled(sourceIds[k])
|
|
1065
|
-
) {
|
|
1066
|
-
return;
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
} catch (e) {
|
|
1070
|
-
// A throwing exotic value must not kill the observer; fall
|
|
1071
|
-
// through and mirror conservatively.
|
|
1072
|
-
}
|
|
1073
|
-
var msg;
|
|
1074
|
-
try {
|
|
1075
|
-
msg = String(err && err.message != null ? err.message : err);
|
|
1076
|
-
} catch (e) {
|
|
1077
|
-
msg = '[unserializable rejection value]';
|
|
1078
|
-
}
|
|
1079
|
-
promise.__wfUnconsumedId = __b.wfReportUnconsumed(
|
|
1080
|
-
promise.__wfRootId,
|
|
1081
|
-
promise.__wfIsRoot === true,
|
|
1082
|
-
dispatchFailed,
|
|
1083
|
-
msg,
|
|
1084
|
-
);
|
|
1085
|
-
});
|
|
1086
|
-
}
|
|
1087
|
-
// R11-3: await / Promise.resolve / returning a thenable from a
|
|
1088
|
-
// handler adopts an ObservedPromise through this then with the
|
|
1089
|
-
// adopting promise's capability (resolve, reject) pair \u2014 native
|
|
1090
|
-
// functions, indistinguishable from real handlers by arity. They
|
|
1091
|
-
// are detected by the native toString signature. Adoption
|
|
1092
|
-
// CONSUMES the result (a delayed adoption clears a recorded
|
|
1093
|
-
// verdict exactly like a delayed await) but is NOT a rejection
|
|
1094
|
-
// handler: the rejection transfers into the adopting promise \u2014
|
|
1095
|
-
// typically an async wrapper's implicit promise, which is a plain
|
|
1096
|
-
// vm-realm Promise the mirror cannot observe. Marking adoption as
|
|
1097
|
-
// handling would silently disarm the mirror for the forgotten-
|
|
1098
|
-
// await failure class; the run-level escape hook in the host
|
|
1099
|
-
// surfaces those escapes instead. Bound script functions also
|
|
1100
|
-
// stringify as native code; misreading one as adoption only
|
|
1101
|
-
// forgoes the rejectionHandled marking, never native semantics.
|
|
1102
|
-
function isAdoptionAttach(handler) {
|
|
1103
|
-
try {
|
|
1104
|
-
return (
|
|
1105
|
-
typeof handler === 'function' &&
|
|
1106
|
-
Function.prototype.toString
|
|
1107
|
-
.call(handler)
|
|
1108
|
-
.indexOf('[native code]') !== -1
|
|
1109
|
-
);
|
|
1110
|
-
} catch (e) {
|
|
1111
|
-
return false;
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
class ObservedPromise extends Promise {
|
|
1115
|
-
then(onFulfilled, onRejected) {
|
|
1116
|
-
// R11-26: introspect the handler BEFORE any state mutation.
|
|
1117
|
-
// The read is guarded because a script-supplied handler can
|
|
1118
|
-
// be exotic (a revoked Proxy wrapping a function, a throwing
|
|
1119
|
-
// accessor) \u2014 an unguarded read made .then() throw
|
|
1120
|
-
// synchronously, something native then never does, leaving
|
|
1121
|
-
// the promise marked consumed with no handler attached.
|
|
1122
|
-
var rethrows = false;
|
|
1123
|
-
try {
|
|
1124
|
-
rethrows = !!(onRejected && onRejected.__wfRethrows);
|
|
1125
|
-
} catch (e) {
|
|
1126
|
-
rethrows = false;
|
|
1127
|
-
}
|
|
1128
|
-
this.__wfConsumed = true;
|
|
1129
|
-
// An attached rejection handler means the script can surface the
|
|
1130
|
-
// root rejection itself; the mirror stays silent for it. The
|
|
1131
|
-
// finally override below routes through this then with marked
|
|
1132
|
-
// rethrow combinators \u2014 those re-raise the rejection instead of
|
|
1133
|
-
// handling it, so they must NOT set the flag (marking them
|
|
1134
|
-
// handled would silently drop a fire-and-forget
|
|
1135
|
-
// agent(...).finally(...) failure). Adoption attaches count
|
|
1136
|
-
// as consumption only, never handling (see isAdoptionAttach):
|
|
1137
|
-
// they mark adoptedOut so forwarded sibling entries defer to
|
|
1138
|
-
// the adopting chain / escape hook instead of mirroring.
|
|
1139
|
-
if (isAdoptionAttach(onRejected)) {
|
|
1140
|
-
__b.wfMarkAdopted(this.__wfRootId);
|
|
1141
|
-
} else if (typeof onRejected === 'function' && !rethrows) {
|
|
1142
|
-
__b.wfMarkRejectionHandled(this.__wfRootId);
|
|
1143
|
-
}
|
|
1144
|
-
// A delayed consumption clears a verdict recorded at
|
|
1145
|
-
// rejection-settlement time, so a late-but-real await is not
|
|
1146
|
-
// misreported as unconsumed.
|
|
1147
|
-
if (this.__wfUnconsumedId !== undefined) {
|
|
1148
|
-
__b.wfClearUnconsumed(this.__wfUnconsumedId);
|
|
1149
|
-
this.__wfUnconsumedId = undefined;
|
|
1150
|
-
}
|
|
1151
|
-
const derived = super.then(onFulfilled, onRejected);
|
|
1152
|
-
derived.__wfRootId = this.__wfRootId;
|
|
1153
|
-
observeDispatch(derived);
|
|
1154
|
-
return derived;
|
|
1155
|
-
}
|
|
1156
|
-
finally(onFinally) {
|
|
1157
|
-
// Native Promise.prototype.finally calls the observed then with
|
|
1158
|
-
// two function combinators, indistinguishable there from a real
|
|
1159
|
-
// then(f, g) \u2014 which would mark the root rejection handled even
|
|
1160
|
-
// though finally rethrows it. Implement finally through the
|
|
1161
|
-
// observed then with an explicitly-marked rethrow combinator so
|
|
1162
|
-
// the mirror stays armed for finally-only chains.
|
|
1163
|
-
if (typeof onFinally !== 'function') {
|
|
1164
|
-
return this.then(undefined, undefined);
|
|
1165
|
-
}
|
|
1166
|
-
const onRethrow = function (err) {
|
|
1167
|
-
return Promise.resolve(onFinally()).then(function () {
|
|
1168
|
-
throw err;
|
|
1169
|
-
});
|
|
1170
|
-
};
|
|
1171
|
-
onRethrow.__wfRethrows = true;
|
|
1172
|
-
return this.then(
|
|
1173
|
-
function (value) {
|
|
1174
|
-
return Promise.resolve(onFinally()).then(function () {
|
|
1175
|
-
return value;
|
|
1176
|
-
});
|
|
1177
|
-
},
|
|
1178
|
-
onRethrow,
|
|
1179
|
-
);
|
|
1180
|
-
}
|
|
1181
|
-
}
|
|
1182
|
-
// --- Static combinators: observe the aggregate promise ---
|
|
1183
|
-
// Promise.all/race/any build their aggregate via the native static;
|
|
1184
|
-
// it never passes through the observed then, so a fire-and-forget
|
|
1185
|
-
// aggregate holding a failed dispatch would escape the run-log
|
|
1186
|
-
// mirror. While the run is live the host's adoption-escape hook
|
|
1187
|
-
// (R11-3) still catches and mirrors the process-level
|
|
1188
|
-
// unhandledRejection \u2014 a round-14 A/B confirmed that hook, not
|
|
1189
|
-
// this wrap, is the live-run backstop \u2014 but only with the coarse
|
|
1190
|
-
// '(rejection not handled)' wording, and once the run's hook is
|
|
1191
|
-
// detached nothing in the sandbox catches the escape. R14-A:
|
|
1192
|
-
// wrapping the statics gives each aggregate its own observer, so
|
|
1193
|
-
// consumption tracking works through the aggregate's own observed
|
|
1194
|
-
// then (await / .catch / .then marks it handled) and the mirror
|
|
1195
|
-
// itself classifies the rejection; the elements still funnel
|
|
1196
|
-
// through the then override via the native static's internal
|
|
1197
|
-
// attach, so they stay marked consumed.
|
|
1198
|
-
function observeAggregate(nativeAggregate) {
|
|
1199
|
-
const rootId = __b.wfRegisterRoot();
|
|
1200
|
-
const observed = new ObservedPromise(function (resolve, reject) {
|
|
1201
|
-
Promise.prototype.then.call(nativeAggregate, resolve, reject);
|
|
1202
|
-
});
|
|
1203
|
-
observed.__wfRootId = rootId;
|
|
1204
|
-
observed.__wfIsRoot = true;
|
|
1205
|
-
observeDispatch(observed);
|
|
1206
|
-
return observed;
|
|
1207
|
-
}
|
|
1208
|
-
const nativePromiseAll = Promise.all;
|
|
1209
|
-
const nativePromiseRace = Promise.race;
|
|
1210
|
-
const nativePromiseAny = Promise.any;
|
|
1211
|
-
// R11-16: a static called on a script-defined Promise subclass
|
|
1212
|
-
// must honor the species contract and return a subclass instance,
|
|
1213
|
-
// so non-default receivers bypass observation (their elements
|
|
1214
|
-
// still funnel through the observed then, and a fire-and-forget
|
|
1215
|
-
// dispatch failure escaping such an aggregate is still caught by
|
|
1216
|
-
// the host's adoption-escape hook via its stamped markers).
|
|
1217
|
-
Promise.all = function (items) {
|
|
1218
|
-
if (this !== Promise) return nativePromiseAll.call(this, items);
|
|
1219
|
-
return observeAggregate(nativePromiseAll.call(this, items));
|
|
1220
|
-
};
|
|
1221
|
-
Promise.race = function (items) {
|
|
1222
|
-
if (this !== Promise) return nativePromiseRace.call(this, items);
|
|
1223
|
-
return observeAggregate(nativePromiseRace.call(this, items));
|
|
1224
|
-
};
|
|
1225
|
-
Promise.any = function (items) {
|
|
1226
|
-
if (this !== Promise) return nativePromiseAny.call(this, items);
|
|
1227
|
-
return observeAggregate(nativePromiseAny.call(this, items));
|
|
1228
|
-
};
|
|
1229
|
-
function vmAsync(hostFn) {
|
|
1230
|
-
return function (...vmArgs) {
|
|
1231
|
-
const rootId = __b.wfRegisterRoot();
|
|
1232
|
-
const p = new ObservedPromise(function (resolve, reject) {
|
|
1233
|
-
function rejectMapped(hostErr) {
|
|
1234
|
-
const vmErr = mapDispatchError(hostErr);
|
|
1235
|
-
// Stamp the originating root and run BEFORE the error can
|
|
1236
|
-
// be forwarded into aggregate promises: the observer's
|
|
1237
|
-
// cross-root suppression (R11-15) reads __wfRootId and
|
|
1238
|
-
// the host's adoption-escape hook (R11-3) attributes by
|
|
1239
|
-
// __wfRunId.
|
|
1240
|
-
try {
|
|
1241
|
-
vmErr.__wfRootId = rootId;
|
|
1242
|
-
vmErr.__wfRunId = __b.runId;
|
|
1243
|
-
} catch (e) {}
|
|
1244
|
-
reject(vmErr);
|
|
1245
|
-
}
|
|
1246
|
-
try {
|
|
1247
|
-
const hostPromise = hostFn.apply(null, vmArgs);
|
|
1248
|
-
hostPromise.then(
|
|
1249
|
-
function (value) { resolve(value); },
|
|
1250
|
-
rejectMapped
|
|
1251
|
-
);
|
|
1252
|
-
} catch (hostErr) {
|
|
1253
|
-
rejectMapped(hostErr);
|
|
1254
|
-
}
|
|
1255
|
-
});
|
|
1256
|
-
p.__wfRootId = rootId;
|
|
1257
|
-
p.__wfIsRoot = true;
|
|
1258
|
-
observeDispatch(p);
|
|
1259
|
-
return p;
|
|
1260
|
-
};
|
|
1261
|
-
}
|
|
1262
|
-
|
|
1263
|
-
// --- phase / log ---
|
|
1264
|
-
globalThis.phase = function phase(title) {
|
|
1265
|
-
__b.pushPhase(String(title));
|
|
1266
|
-
};
|
|
1267
|
-
globalThis.log = function log(msg) {
|
|
1268
|
-
__b.pushLog(msg);
|
|
1269
|
-
};
|
|
1270
|
-
|
|
1271
|
-
// --- console (object with hardened methods, all in vm-realm) ---
|
|
1272
|
-
const safeConsole = Object.create(null);
|
|
1273
|
-
safeConsole.log = function () {
|
|
1274
|
-
const parts = [];
|
|
1275
|
-
for (let i = 0; i < arguments.length; i++) parts.push(String(arguments[i]));
|
|
1276
|
-
__b.pushLog(parts.join(' '));
|
|
1277
|
-
};
|
|
1278
|
-
safeConsole.warn = safeConsole.log;
|
|
1279
|
-
safeConsole.error = safeConsole.log;
|
|
1280
|
-
globalThis.console = safeConsole;
|
|
1281
|
-
|
|
1282
|
-
// --- agent (with runtime allowlist + named throws, all vm-realm) ---
|
|
1283
|
-
// FIX-Round1-T13: throw on any opts key not in the allowlist \u2014 catches
|
|
1284
|
-
// typos like { scema: ... } that previously slipped through the
|
|
1285
|
-
// [key:string]: unknown index signature.
|
|
1286
|
-
const KNOWN_AGENT_OPTS = ['label', 'phase', 'schema', 'model', 'isolation', 'agentType', 'stallMs', 'workingDir'];
|
|
1287
|
-
globalThis.agent = vmAsync(function (prompt, agentOpts) {
|
|
1288
|
-
agentOpts = agentOpts || {};
|
|
1289
|
-
const keys = Object.keys(agentOpts);
|
|
1290
|
-
for (let i = 0; i < keys.length; i++) {
|
|
1291
|
-
const k = keys[i];
|
|
1292
|
-
if (KNOWN_AGENT_OPTS.indexOf(k) === -1) {
|
|
1293
|
-
throw new Error(
|
|
1294
|
-
"agent({" + k + "}): unknown option. " +
|
|
1295
|
-
"Known options are: " + KNOWN_AGENT_OPTS.join(', ') + "."
|
|
1296
|
-
);
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
// P3: schema + model + agentType + isolation are all wired through
|
|
1300
|
-
// createProductionDispatch \u2192 SubagentManager.createAgentHeadless.
|
|
1301
|
-
// The dispatch surfaces descriptive errors for "agent type not found",
|
|
1302
|
-
// "isolation:'remote' is not available in this build", parent-dirty
|
|
1303
|
-
// refuse, worktree creation failures, and StructuredOutput contract
|
|
1304
|
-
// violations ("completed without calling StructuredOutput after 2
|
|
1305
|
-
// in-conversation nudges").
|
|
1306
|
-
if (
|
|
1307
|
-
agentOpts.isolation !== undefined &&
|
|
1308
|
-
agentOpts.isolation !== 'worktree' &&
|
|
1309
|
-
agentOpts.isolation !== 'remote'
|
|
1310
|
-
) {
|
|
1311
|
-
throw new Error(
|
|
1312
|
-
"agent({isolation: '" + agentOpts.isolation + "'}): unknown isolation mode. " +
|
|
1313
|
-
"Known modes are: 'worktree', 'remote'."
|
|
1314
|
-
);
|
|
1315
|
-
}
|
|
1316
|
-
// NOTE: this init script is a host-side template literal \u2014 no
|
|
1317
|
-
// backticks anywhere below, in code or comments.
|
|
1318
|
-
//
|
|
1319
|
-
// A non-number stallMs is silently dropped downstream and the
|
|
1320
|
-
// default watchdog applies, contradicting "0 disables the watchdog"
|
|
1321
|
-
// \u2014 refuse it loudly like the other option gates.
|
|
1322
|
-
if (agentOpts.stallMs !== undefined && (typeof agentOpts.stallMs !== 'number' || !Number.isFinite(agentOpts.stallMs))) {
|
|
1323
|
-
throw new Error("agent({stallMs}): must be a finite number of milliseconds (0 disables the watchdog).");
|
|
1324
|
-
}
|
|
1325
|
-
// workingDir pins the agent to a worktree the CALLER already owns;
|
|
1326
|
-
// isolation creates and reaps one. Asking for both is a contradiction
|
|
1327
|
-
// about who owns the directory's lifetime, so name it here rather than
|
|
1328
|
-
// silently letting one win.
|
|
1329
|
-
if (agentOpts.workingDir !== undefined) {
|
|
1330
|
-
if (typeof agentOpts.workingDir !== 'string' || agentOpts.workingDir.trim().length === 0) {
|
|
1331
|
-
throw new Error(
|
|
1332
|
-
"agent({workingDir}): must be a non-empty string naming an existing " +
|
|
1333
|
-
"git worktree of this repository."
|
|
1334
|
-
);
|
|
1335
|
-
}
|
|
1336
|
-
if (agentOpts.isolation !== undefined) {
|
|
1337
|
-
throw new Error(
|
|
1338
|
-
"agent({workingDir, isolation}): incompatible options. workingDir " +
|
|
1339
|
-
"pins the agent to a worktree you already own; isolation creates " +
|
|
1340
|
-
"a fresh one and removes it afterwards. Pass one."
|
|
1341
|
-
);
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
if (typeof agentOpts.phase === 'string' && agentOpts.phase.length > 0) {
|
|
1345
|
-
if (__b.lastPhase() !== agentOpts.phase) {
|
|
1346
|
-
__b.pushPhase(agentOpts.phase);
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
// SECURITY (P3 R2 self-review): user-script-controlled agentOpts
|
|
1350
|
-
// cross the vm/host boundary verbatim via vmAsync's hostFn.apply.
|
|
1351
|
-
// A Proxy / inherited-getter / non-plain object in agentOpts.schema
|
|
1352
|
-
// would let host-side code (SyntheticOutputTool constructor + AJV
|
|
1353
|
-
// compile) trigger user-controlled trap handlers that execute with
|
|
1354
|
-
// the host realm's full surface. Revive agentOpts through JSON
|
|
1355
|
-
// round-trip BEFORE crossing so the host only ever sees vm-realm
|
|
1356
|
-
// plain objects with vm-realm prototypes. Same mechanism that
|
|
1357
|
-
// makes args + parallel/pipeline results safe.
|
|
1358
|
-
var safeOpts;
|
|
1359
|
-
try {
|
|
1360
|
-
safeOpts = JSON.parse(JSON.stringify(agentOpts));
|
|
1361
|
-
} catch (e) {
|
|
1362
|
-
throw new Error(
|
|
1363
|
-
"agent() opts contain a non-JSON-serializable value: " +
|
|
1364
|
-
String(e && e.message != null ? e.message : e)
|
|
1365
|
-
);
|
|
1366
|
-
}
|
|
1367
|
-
// SECURITY (PR #4947 R1 wenshao, extended for P3): vmAsync's resolve
|
|
1368
|
-
// path is verbatim (no re-wrap of resolved values). Host-realm
|
|
1369
|
-
// strings cross the boundary harmlessly because primitives have no
|
|
1370
|
-
// prototype identity. But P3's schema-mode dispatch returns the
|
|
1371
|
-
// validated structured_output args as a host-realm OBJECT --
|
|
1372
|
-
// handing that to the script reopens the T1/T8/T14 escape:
|
|
1373
|
-
// result.constructor.constructor("return process")() would walk
|
|
1374
|
-
// the host Object.prototype chain to the host Function
|
|
1375
|
-
// constructor. Per-call JSON revival inside this vm runInContext
|
|
1376
|
-
// block makes the returned object carry vm-realm prototypes (same
|
|
1377
|
-
// mechanism as parallel/pipeline reviveInRealm and the args
|
|
1378
|
-
// global revival). The fallback to null on a non-serializable
|
|
1379
|
-
// resolve mirrors the errors-as-data convention parallel/pipeline
|
|
1380
|
-
// already use for individual slot failures.
|
|
1381
|
-
// R3 review (wenshao T3 [Suggestion]): the null fallback below is
|
|
1382
|
-
// a SECURITY backstop, not a contract path. In schema mode the
|
|
1383
|
-
// host return is the validated args of a structured_output tool
|
|
1384
|
-
// call -- LLM tool_call payloads are always JSON-serializable
|
|
1385
|
-
// (the model sends them through the OpenAI tool-call protocol
|
|
1386
|
-
// which serializes through JSON itself) and SyntheticOutputTool's
|
|
1387
|
-
// AJV validation runs over the parsed JSON, so a non-serializable
|
|
1388
|
-
// host return is unreachable in production schema mode. The
|
|
1389
|
-
// sentinel preserves the errors-as-data convention parallel /
|
|
1390
|
-
// pipeline already use for individual slot failures, and stays as
|
|
1391
|
-
// residual defense for any future dispatch path whose return
|
|
1392
|
-
// value isn't a tool_call payload. logRevivalFailure surfaces
|
|
1393
|
-
// the actionable detail (slot 0 + the error string) to operators
|
|
1394
|
-
// so a real trigger in production isn't silent.
|
|
1395
|
-
return __b.hostAgent(prompt, safeOpts).then(function (value) {
|
|
1396
|
-
if (value === null || typeof value !== 'object') {
|
|
1397
|
-
return value;
|
|
1398
|
-
}
|
|
1399
|
-
try {
|
|
1400
|
-
return JSON.parse(JSON.stringify(value));
|
|
1401
|
-
} catch (e) {
|
|
1402
|
-
__b.logRevivalFailure(0, String(e && e.message != null ? e.message : e));
|
|
1403
|
-
return null;
|
|
1404
|
-
}
|
|
1405
|
-
});
|
|
1406
|
-
});
|
|
1407
|
-
|
|
1408
|
-
// --- parallel / pipeline ---
|
|
1409
|
-
// SECURITY (PR #4732 P2): the host impl resolves with a HOST-realm array.
|
|
1410
|
-
// vmAsync's resolve path is verbatim (it does NOT re-wrap resolved
|
|
1411
|
-
// values), so handing that host array to the script would reopen the
|
|
1412
|
-
// T1/T8/T14 escape: result.constructor.constructor('return process')()
|
|
1413
|
-
// walks the host Array.prototype chain to the host Function constructor.
|
|
1414
|
-
// We revive the array INSIDE the vm realm with JSON.parse(JSON.stringify)
|
|
1415
|
-
// -- the same mechanism that makes the args global safe (see the args
|
|
1416
|
-
// revival above) -- so the value the script sees has vm-realm prototypes
|
|
1417
|
-
// whose constructors can't reach host process. Agent results are JSON
|
|
1418
|
-
// strings (and null slots), so the round-trip is lossless for P2.
|
|
1419
|
-
//
|
|
1420
|
-
// EAD-1 (P2 self-review): revive PER-ELEMENT, not the whole array in one
|
|
1421
|
-
// JSON.stringify. A single slot whose VALUE is non-serializable (a thunk
|
|
1422
|
-
// that returns a BigInt or a circular object) must become null at its
|
|
1423
|
-
// index -- it must NOT throw on the whole array and destroy every sibling
|
|
1424
|
-
// result, which would defeat errors-as-data for return values. The outer
|
|
1425
|
-
// [] is built in-realm here, so the result keeps vm-realm prototypes.
|
|
1426
|
-
//
|
|
1427
|
-
// SECURITY (PR #4947 R1 wenshao): reviveInRealm MUST remain inside this
|
|
1428
|
-
// vm init runInContext block. JSON, Array, Object here are vm-realm
|
|
1429
|
-
// globals; extracting this function to a host-side utility (e.g. a
|
|
1430
|
-
// shared utils/jsonRevive.ts) would resolve those references against
|
|
1431
|
-
// the HOST realm, silently reopening the T1/T8/T14 escape that the
|
|
1432
|
-
// revival is designed to prevent. The textual identity to a host-side
|
|
1433
|
-
// util is exactly the trap.
|
|
1434
|
-
function reviveInRealm(hostArr) {
|
|
1435
|
-
const out = [];
|
|
1436
|
-
for (let i = 0; i < hostArr.length; i++) {
|
|
1437
|
-
try {
|
|
1438
|
-
out[i] = JSON.parse(JSON.stringify(hostArr[i]));
|
|
1439
|
-
} catch (e) {
|
|
1440
|
-
// Cross to host realm for debug logging. The bridge function
|
|
1441
|
-
// accepts only primitive strings/numbers; the error message is
|
|
1442
|
-
// coerced to a String here so no vm-realm Error object crosses.
|
|
1443
|
-
__b.logRevivalFailure(i, String(e?.message ?? e));
|
|
1444
|
-
out[i] = null;
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
return out;
|
|
1448
|
-
}
|
|
1449
|
-
if (__b.hasParallel) {
|
|
1450
|
-
const callParallel = vmAsync(function (thunks) {
|
|
1451
|
-
return __b.hostParallel(thunks);
|
|
1452
|
-
});
|
|
1453
|
-
globalThis.parallel = function parallel(thunks) {
|
|
1454
|
-
return callParallel(thunks).then(reviveInRealm);
|
|
1455
|
-
};
|
|
1456
|
-
} else {
|
|
1457
|
-
globalThis.parallel = function parallel() {
|
|
1458
|
-
return new Promise(function (_, reject) {
|
|
1459
|
-
reject(new Error(
|
|
1460
|
-
'parallel() is unavailable: this sandbox was created without a ' +
|
|
1461
|
-
'parallel implementation. The orchestrator injects one; a bare ' +
|
|
1462
|
-
'sandbox has no concurrent-dispatch capability.'
|
|
1463
|
-
));
|
|
1464
|
-
});
|
|
1465
|
-
};
|
|
1466
|
-
}
|
|
1467
|
-
if (__b.hasPipeline) {
|
|
1468
|
-
const callPipeline = vmAsync(function (items) {
|
|
1469
|
-
const stages = [];
|
|
1470
|
-
for (let i = 1; i < arguments.length; i++) stages.push(arguments[i]);
|
|
1471
|
-
return __b.hostPipeline.apply(null, [items].concat(stages));
|
|
1472
|
-
});
|
|
1473
|
-
globalThis.pipeline = function pipeline() {
|
|
1474
|
-
return callPipeline.apply(null, arguments).then(reviveInRealm);
|
|
1475
|
-
};
|
|
1476
|
-
} else {
|
|
1477
|
-
globalThis.pipeline = function pipeline() {
|
|
1478
|
-
return new Promise(function (_, reject) {
|
|
1479
|
-
reject(new Error(
|
|
1480
|
-
'pipeline() is unavailable: this sandbox was created without a ' +
|
|
1481
|
-
'pipeline implementation. The orchestrator injects one; a bare ' +
|
|
1482
|
-
'sandbox has no staggered multi-stage capability.'
|
|
1483
|
-
));
|
|
1484
|
-
});
|
|
1485
|
-
};
|
|
1486
|
-
}
|
|
1487
|
-
// --- workflow (nested, single-level) ---
|
|
1488
|
-
// Mirrors agent(): args cross vm\u2192host verbatim (safe direction), the
|
|
1489
|
-
// single result is revived back into the vm realm via JSON round-trip
|
|
1490
|
-
// (same T1/T8/T14 escape defense as agent / parallel / pipeline). The
|
|
1491
|
-
// host impl resolves a saved workflow and runs it sharing this run's
|
|
1492
|
-
// agent-count cap + token budget. When __b.hasWorkflow is false, the
|
|
1493
|
-
// sandbox is either bare (no resolver wired) OR is itself a nested
|
|
1494
|
-
// workflow \u2014 in both cases workflow() must throw, which is how the
|
|
1495
|
-
// single-level nesting limit is enforced (a nested sandbox is created
|
|
1496
|
-
// without a workflow impl, so its workflow() lands in the else branch).
|
|
1497
|
-
if (__b.hasWorkflow) {
|
|
1498
|
-
const callWorkflow = vmAsync(function (nameOrRef, wfArgs) {
|
|
1499
|
-
// Sanitize args through a JSON round-trip BEFORE crossing so the
|
|
1500
|
-
// host only ever sees vm-realm plain objects (same defense as
|
|
1501
|
-
// agent()'s safeOpts). nameOrRef may be a string or {scriptPath}.
|
|
1502
|
-
var safeRef;
|
|
1503
|
-
var safeArgs;
|
|
1504
|
-
try {
|
|
1505
|
-
safeRef = nameOrRef === undefined
|
|
1506
|
-
? undefined
|
|
1507
|
-
: JSON.parse(JSON.stringify(nameOrRef));
|
|
1508
|
-
safeArgs = wfArgs === undefined
|
|
1509
|
-
? undefined
|
|
1510
|
-
: JSON.parse(JSON.stringify(wfArgs));
|
|
1511
|
-
} catch (e) {
|
|
1512
|
-
throw new Error(
|
|
1513
|
-
'workflow() received a non-JSON-serializable argument: ' +
|
|
1514
|
-
String(e && e.message != null ? e.message : e)
|
|
1515
|
-
);
|
|
1516
|
-
}
|
|
1517
|
-
return __b.hostWorkflow(safeRef, safeArgs).then(function (value) {
|
|
1518
|
-
if (value === null || typeof value !== 'object') {
|
|
1519
|
-
return value;
|
|
1520
|
-
}
|
|
1521
|
-
try {
|
|
1522
|
-
return JSON.parse(JSON.stringify(value));
|
|
1523
|
-
} catch (e) {
|
|
1524
|
-
__b.logRevivalFailure(0, String(e && e.message != null ? e.message : e));
|
|
1525
|
-
return null;
|
|
1526
|
-
}
|
|
1527
|
-
});
|
|
1528
|
-
});
|
|
1529
|
-
globalThis.workflow = function workflow(nameOrRef, wfArgs) {
|
|
1530
|
-
return callWorkflow(nameOrRef, wfArgs);
|
|
1531
|
-
};
|
|
1532
|
-
} else {
|
|
1533
|
-
globalThis.workflow = function workflow() {
|
|
1534
|
-
return new Promise(function (_, reject) {
|
|
1535
|
-
reject(new Error(
|
|
1536
|
-
"workflow() is unavailable here. Either this sandbox was created " +
|
|
1537
|
-
"without a saved-workflow resolver, or this script is already " +
|
|
1538
|
-
"running as a nested workflow \u2014 workflow() nesting is limited to " +
|
|
1539
|
-
"a single level (a workflow cannot call another workflow that " +
|
|
1540
|
-
"itself calls workflow())."
|
|
1541
|
-
));
|
|
1542
|
-
});
|
|
1543
|
-
};
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
// --- budget ---
|
|
1547
|
-
const safeBudget = Object.create(null);
|
|
1548
|
-
Object.defineProperty(safeBudget, 'total', {
|
|
1549
|
-
value: __b.budgetTotal,
|
|
1550
|
-
writable: false, configurable: false,
|
|
1551
|
-
});
|
|
1552
|
-
if (__b.hasBudget) {
|
|
1553
|
-
Object.defineProperty(safeBudget, 'spent', {
|
|
1554
|
-
value: function spent() { return __b.hostBudgetSpent(); },
|
|
1555
|
-
writable: false, configurable: false,
|
|
1556
|
-
});
|
|
1557
|
-
Object.defineProperty(safeBudget, 'remaining', {
|
|
1558
|
-
value: function remaining() { return __b.hostBudgetRemaining(); },
|
|
1559
|
-
writable: false, configurable: false,
|
|
1560
|
-
});
|
|
1561
|
-
} else {
|
|
1562
|
-
Object.defineProperty(safeBudget, 'spent', {
|
|
1563
|
-
value: function spent() {
|
|
1564
|
-
throw new Error(
|
|
1565
|
-
'budget.spent() is not supported in P1. Token tracking is scheduled for P5.'
|
|
1566
|
-
);
|
|
1567
|
-
},
|
|
1568
|
-
writable: false, configurable: false,
|
|
1569
|
-
});
|
|
1570
|
-
Object.defineProperty(safeBudget, 'remaining', {
|
|
1571
|
-
value: function remaining() {
|
|
1572
|
-
throw new Error(
|
|
1573
|
-
'budget.remaining() is not supported in P1. Token tracking is scheduled for P5.'
|
|
1574
|
-
);
|
|
1575
|
-
},
|
|
1576
|
-
writable: false, configurable: false,
|
|
1577
|
-
});
|
|
1578
|
-
}
|
|
1579
|
-
globalThis.budget = safeBudget;
|
|
1580
|
-
})();`,
|
|
1581
|
-
ctx,
|
|
1582
|
-
{ filename: "workflow-sandbox-init.js" }
|
|
1583
|
-
);
|
|
1584
|
-
const maxWallClockMs = resolveMaxWallClockMs(opts);
|
|
1585
|
-
const flushUnconsumedRejections = /* @__PURE__ */ __name(async () => {
|
|
1586
|
-
unconsumedSettled = true;
|
|
1587
|
-
if (nextUnconsumedId === 1) return;
|
|
1588
|
-
await new Promise((resolve2) => {
|
|
1589
|
-
setImmediate(resolve2);
|
|
1590
|
-
});
|
|
1591
|
-
for (const rec of unconsumedRejections.values()) {
|
|
1592
|
-
const rootState = unconsumedRoots.get(rec.rootId);
|
|
1593
|
-
if (rootState?.rejectionHandled) {
|
|
1594
|
-
continue;
|
|
1595
|
-
}
|
|
1596
|
-
if (rec.dispatchFailed && rootState?.adoptedOut) {
|
|
1597
|
-
continue;
|
|
1598
|
-
}
|
|
1599
|
-
const key = rec.rootId + "\0" + rec.msg;
|
|
1600
|
-
if (mirroredEscapeKeys.has(key)) continue;
|
|
1601
|
-
mirroredEscapeKeys.add(key);
|
|
1602
|
-
safeLog(unconsumedRejectionLine(rec));
|
|
1603
|
-
}
|
|
1604
|
-
unconsumedRejections.clear();
|
|
1605
|
-
}, "flushUnconsumedRejections");
|
|
1606
|
-
const hookRunId = opts.runId ?? "";
|
|
1607
|
-
const adoptionEscapeHook = /* @__PURE__ */ __name((reason, _promise) => {
|
|
1608
|
-
try {
|
|
1609
|
-
if (!reason || typeof reason !== "object") return;
|
|
1610
|
-
const marked = reason;
|
|
1611
|
-
if (marked.__wfDispatchFailed !== true) return;
|
|
1612
|
-
if (String(marked.__wfRunId ?? "") !== hookRunId) return;
|
|
1613
|
-
const rootId = typeof marked.__wfRootId === "number" ? marked.__wfRootId : void 0;
|
|
1614
|
-
if (rootId !== void 0 && unconsumedRoots.get(rootId)?.rejectionHandled) {
|
|
1615
|
-
return;
|
|
1616
|
-
}
|
|
1617
|
-
let msg;
|
|
1618
|
-
try {
|
|
1619
|
-
msg = marked.message != null ? String(marked.message) : String(reason);
|
|
1620
|
-
} catch {
|
|
1621
|
-
msg = "[unserializable rejection value]";
|
|
1622
|
-
}
|
|
1623
|
-
const key = String(rootId ?? "") + "\0" + msg;
|
|
1624
|
-
if (mirroredEscapeKeys.has(key)) return;
|
|
1625
|
-
mirroredEscapeKeys.add(key);
|
|
1626
|
-
safeLog("dispatch failed (rejection not handled): " + msg);
|
|
1627
|
-
} catch (e) {
|
|
1628
|
-
debugLogger.warn("adoptionEscapeHook failed:", e);
|
|
1629
|
-
}
|
|
1630
|
-
}, "adoptionEscapeHook");
|
|
1631
|
-
let extractedMeta = null;
|
|
1632
|
-
return {
|
|
1633
|
-
async run(scriptSource) {
|
|
1634
|
-
unconsumedSettled = false;
|
|
1635
|
-
unconsumedRoots.clear();
|
|
1636
|
-
unconsumedRejections.clear();
|
|
1637
|
-
nextUnconsumedId = 1;
|
|
1638
|
-
mirroredEscapeKeys = /* @__PURE__ */ new Set();
|
|
1639
|
-
let watchdog;
|
|
1640
|
-
let stopWatchingState;
|
|
1641
|
-
let rearmWatchdogOnAbort;
|
|
1642
|
-
let settleOnAbort;
|
|
1643
|
-
let wallClockFired = false;
|
|
1644
|
-
process.on("unhandledRejection", adoptionEscapeHook);
|
|
1645
|
-
try {
|
|
1646
|
-
const { script, meta } = compileWorkflowScript(scriptSource);
|
|
1647
|
-
extractedMeta = meta;
|
|
1648
|
-
if (opts.abortOnTimeout?.signal.aborted) {
|
|
1649
|
-
throw workflowCancelledError();
|
|
1650
|
-
}
|
|
1651
|
-
const runOpts = {
|
|
1652
|
-
timeout: 3e4
|
|
1653
|
-
};
|
|
1654
|
-
const result = script.runInContext(ctx, runOpts);
|
|
1655
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
1656
|
-
watchdog = new WallClockWatchdog(maxWallClockMs, () => {
|
|
1657
|
-
wallClockFired = true;
|
|
1658
|
-
opts.abortOnTimeout?.abort();
|
|
1659
|
-
reject(
|
|
1660
|
-
new Error(
|
|
1661
|
-
`Workflow execution exceeded ${maxWallClockMs} ms of active time (paused time is not counted). Override via SandboxOptions.maxWallClockMs or QWEN_CODE_MAX_WORKFLOW_SECONDS env var.`
|
|
1662
|
-
)
|
|
1663
|
-
);
|
|
1664
|
-
});
|
|
1665
|
-
});
|
|
1666
|
-
const aborted = /* @__PURE__ */ __name(() => opts.abortOnTimeout?.signal.aborted === true, "aborted");
|
|
1667
|
-
stopWatchingState = opts.scheduler?.onStateChange(({ state }) => {
|
|
1668
|
-
if (state === "paused" && !aborted()) watchdog?.pause();
|
|
1669
|
-
else watchdog?.resume();
|
|
1670
|
-
});
|
|
1671
|
-
if (opts.scheduler?.snapshot().state === "paused" && !aborted()) {
|
|
1672
|
-
watchdog?.pause();
|
|
1673
|
-
}
|
|
1674
|
-
rearmWatchdogOnAbort = /* @__PURE__ */ __name(() => watchdog?.resume(), "rearmWatchdogOnAbort");
|
|
1675
|
-
opts.abortOnTimeout?.signal.addEventListener(
|
|
1676
|
-
"abort",
|
|
1677
|
-
rearmWatchdogOnAbort,
|
|
1678
|
-
{ once: true }
|
|
1679
|
-
);
|
|
1680
|
-
const abortPromise = new Promise((_, reject) => {
|
|
1681
|
-
const signal = opts.abortOnTimeout?.signal;
|
|
1682
|
-
if (!signal) return;
|
|
1683
|
-
settleOnAbort = /* @__PURE__ */ __name(() => {
|
|
1684
|
-
if (!wallClockFired) reject(workflowCancelledError());
|
|
1685
|
-
}, "settleOnAbort");
|
|
1686
|
-
signal.addEventListener("abort", settleOnAbort, { once: true });
|
|
1687
|
-
});
|
|
1688
|
-
return await Promise.race([result, timeoutPromise, abortPromise]);
|
|
1689
|
-
} finally {
|
|
1690
|
-
if (rearmWatchdogOnAbort) {
|
|
1691
|
-
opts.abortOnTimeout?.signal.removeEventListener(
|
|
1692
|
-
"abort",
|
|
1693
|
-
rearmWatchdogOnAbort
|
|
1694
|
-
);
|
|
1695
|
-
}
|
|
1696
|
-
if (settleOnAbort) {
|
|
1697
|
-
opts.abortOnTimeout?.signal.removeEventListener(
|
|
1698
|
-
"abort",
|
|
1699
|
-
settleOnAbort
|
|
1700
|
-
);
|
|
1701
|
-
}
|
|
1702
|
-
stopWatchingState?.();
|
|
1703
|
-
watchdog?.stop();
|
|
1704
|
-
await flushUnconsumedRejections();
|
|
1705
|
-
process.off("unhandledRejection", adoptionEscapeHook);
|
|
1706
|
-
}
|
|
1707
|
-
},
|
|
1708
|
-
getPhases: /* @__PURE__ */ __name(() => [...phases], "getPhases"),
|
|
1709
|
-
getLogs: /* @__PURE__ */ __name(() => [...logs], "getLogs"),
|
|
1710
|
-
appendLog: /* @__PURE__ */ __name((line) => safeLog(line, false), "appendLog"),
|
|
1711
|
-
getMeta: /* @__PURE__ */ __name(() => extractedMeta, "getMeta")
|
|
1712
|
-
};
|
|
1713
|
-
}
|
|
1714
|
-
__name(createWorkflowSandbox, "createWorkflowSandbox");
|
|
1715
|
-
|
|
1716
151
|
// packages/core/src/agents/runtime/workflow-orchestrator.ts
|
|
1717
152
|
init_esbuild_shims();
|
|
1718
153
|
import { randomBytes } from "node:crypto";
|
|
@@ -1941,6 +376,8 @@ __name(runStallResilient, "runStallResilient");
|
|
|
1941
376
|
// packages/core/src/agents/runtime/workflow-journal.ts
|
|
1942
377
|
init_esbuild_shims();
|
|
1943
378
|
import { createHash } from "node:crypto";
|
|
379
|
+
import { constants, promises as fs } from "node:fs";
|
|
380
|
+
import path from "node:path";
|
|
1944
381
|
var debugLogger4 = createDebugLogger("WORKFLOW_JOURNAL");
|
|
1945
382
|
var JOURNAL_KEY_VERSION = "v2";
|
|
1946
383
|
function canonicalizeAgentOpts(opts) {
|
|
@@ -2014,13 +451,61 @@ function buildReplay(entries) {
|
|
|
2014
451
|
}
|
|
2015
452
|
__name(buildReplay, "buildReplay");
|
|
2016
453
|
var WorkflowJournal = class {
|
|
2017
|
-
constructor(
|
|
2018
|
-
this.
|
|
454
|
+
constructor(journalPath, root = path.dirname(path.dirname(journalPath))) {
|
|
455
|
+
this.root = root;
|
|
456
|
+
this.path = journalPath;
|
|
2019
457
|
}
|
|
2020
458
|
static {
|
|
2021
459
|
__name(this, "WorkflowJournal");
|
|
2022
460
|
}
|
|
2023
461
|
pending = Promise.resolve();
|
|
462
|
+
path;
|
|
463
|
+
async hasSymlinkedPath() {
|
|
464
|
+
if (await isSymlinkedRoot(this.root) || await isSymlinkedRoot(path.dirname(this.path))) {
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
return fs.lstat(this.path).then((stat) => stat.isSymbolicLink()).catch(() => false);
|
|
468
|
+
}
|
|
469
|
+
/** Ensure the advertised journal path exists without affecting the run. */
|
|
470
|
+
async ensureExists() {
|
|
471
|
+
try {
|
|
472
|
+
if (await this.hasSymlinkedPath()) return false;
|
|
473
|
+
await fs.mkdir(path.dirname(this.path), { recursive: true });
|
|
474
|
+
if (await this.hasSymlinkedPath()) return false;
|
|
475
|
+
const noFollow = process.platform === "win32" ? 0 : constants.O_NOFOLLOW;
|
|
476
|
+
const file = await fs.open(
|
|
477
|
+
this.path,
|
|
478
|
+
constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY | noFollow,
|
|
479
|
+
384
|
|
480
|
+
);
|
|
481
|
+
try {
|
|
482
|
+
await file.chmod(384);
|
|
483
|
+
} finally {
|
|
484
|
+
await file.close();
|
|
485
|
+
}
|
|
486
|
+
return true;
|
|
487
|
+
} catch (error) {
|
|
488
|
+
debugLogger4.warn(
|
|
489
|
+
`WorkflowJournal.ensureExists failed for ${this.path}: ${error}`
|
|
490
|
+
);
|
|
491
|
+
return false;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
/** Remove a never-registered run's journal file, best-effort. */
|
|
495
|
+
async remove() {
|
|
496
|
+
try {
|
|
497
|
+
if (await this.hasSymlinkedPath()) return;
|
|
498
|
+
await fs.rm(this.path, { force: true });
|
|
499
|
+
await fs.rmdir(path.dirname(this.path)).catch((error) => {
|
|
500
|
+
const code = error.code;
|
|
501
|
+
if (code !== "ENOENT" && code !== "ENOTEMPTY") throw error;
|
|
502
|
+
});
|
|
503
|
+
} catch (error) {
|
|
504
|
+
debugLogger4.warn(
|
|
505
|
+
`WorkflowJournal.remove failed for ${this.path}: ${error}`
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
2024
509
|
/** Load + parse all entries into replay maps. Empty maps if no file. */
|
|
2025
510
|
async load() {
|
|
2026
511
|
try {
|
|
@@ -2380,7 +865,7 @@ function attachDispatchTranscript(config, agentId, prompt, agentName, emitter, a
|
|
|
2380
865
|
}
|
|
2381
866
|
__name(attachDispatchTranscript, "attachDispatchTranscript");
|
|
2382
867
|
async function runSingleDispatch(config, prompt, opts, attemptSignal, emitter, workflowAgentId, agentIdentity, onTokens) {
|
|
2383
|
-
const { AgentHeadless, ContextState } = await import("./agent-headless-
|
|
868
|
+
const { AgentHeadless, ContextState } = await import("./agent-headless-QQZTWOKO.js");
|
|
2384
869
|
const ctx = new ContextState();
|
|
2385
870
|
ctx.set("task_prompt", prompt);
|
|
2386
871
|
debugLogger.debug(`[workflow] Dispatch ${workflowAgentId}`);
|
|
@@ -3253,18 +1738,30 @@ __name(extractErrorMessage, "extractErrorMessage");
|
|
|
3253
1738
|
init_esbuild_shims();
|
|
3254
1739
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
3255
1740
|
var WorkflowRunHandle = class {
|
|
3256
|
-
constructor(runId, budget, registry, controller, scheduler, start) {
|
|
1741
|
+
constructor(runId, budget, registry, controller, scheduler, start, locations = {}) {
|
|
3257
1742
|
this.runId = runId;
|
|
3258
1743
|
this.budget = budget;
|
|
3259
1744
|
this.registry = registry;
|
|
3260
1745
|
this.controller = controller;
|
|
3261
1746
|
this.scheduler = scheduler;
|
|
1747
|
+
this.scriptPath = locations.scriptPath;
|
|
1748
|
+
this.journalPath = locations.journalPath;
|
|
3262
1749
|
this.completion = Promise.resolve().then(start);
|
|
3263
1750
|
}
|
|
3264
1751
|
static {
|
|
3265
1752
|
__name(this, "WorkflowRunHandle");
|
|
3266
1753
|
}
|
|
3267
1754
|
completion;
|
|
1755
|
+
/**
|
|
1756
|
+
* Where this run's script lives on disk: the file a `{scriptPath}` launch
|
|
1757
|
+
* loaded, or the persisted copy of an inline `{script}`. `undefined` when
|
|
1758
|
+
* an inline script could not be persisted (no `storage`, symlinked root,
|
|
1759
|
+
* write failure) — callers report the run without it rather than naming a
|
|
1760
|
+
* path that does not exist.
|
|
1761
|
+
*/
|
|
1762
|
+
scriptPath;
|
|
1763
|
+
/** This run's resume journal, when the config has a `storage` to hold one. */
|
|
1764
|
+
journalPath;
|
|
3268
1765
|
abort() {
|
|
3269
1766
|
this.controller.abort();
|
|
3270
1767
|
}
|
|
@@ -3328,11 +1825,26 @@ var WorkflowRunner = class {
|
|
|
3328
1825
|
const isCurrentEntry = /* @__PURE__ */ __name(() => registry === void 0 || entry !== void 0 && registry.get(runId) === entry, "isCurrentEntry");
|
|
3329
1826
|
const createController = /* @__PURE__ */ __name(() => runInBackground ? createAbortController() : createChildAbortController(options.signal), "createController");
|
|
3330
1827
|
const controller = registry ? registry.reserveStart(runId, createController) : createController();
|
|
1828
|
+
const releasePersistenceActivity = markWorkflowRunPersistenceActive(
|
|
1829
|
+
config,
|
|
1830
|
+
runId
|
|
1831
|
+
);
|
|
1832
|
+
const assertStartNotCancelled = /* @__PURE__ */ __name(() => {
|
|
1833
|
+
if (controller.signal.aborted && !options.signal.aborted) {
|
|
1834
|
+
throw new WorkflowStartCancelledError();
|
|
1835
|
+
}
|
|
1836
|
+
if (runInBackground && options.signal.aborted) {
|
|
1837
|
+
throw new WorkflowStartCancelledError();
|
|
1838
|
+
}
|
|
1839
|
+
}, "assertStartNotCancelled");
|
|
3331
1840
|
const storage = config.storage;
|
|
3332
|
-
const
|
|
1841
|
+
const previousEntry = registry?.get(runId);
|
|
1842
|
+
let journalPath = storage ? storage.getWorkflowRunJournalPath(runId) : void 0;
|
|
1843
|
+
const journal = journalPath ? new WorkflowJournal(journalPath, storage.getWorkflowRunsDir()) : void 0;
|
|
3333
1844
|
let script;
|
|
3334
1845
|
let scriptPath;
|
|
3335
1846
|
let resumeReplay;
|
|
1847
|
+
let persistedInlineScript = false;
|
|
3336
1848
|
let callerWasAbortedBeforeStart;
|
|
3337
1849
|
let orchestrator;
|
|
3338
1850
|
try {
|
|
@@ -3342,6 +1854,7 @@ var WorkflowRunner = class {
|
|
|
3342
1854
|
) : void 0;
|
|
3343
1855
|
script = loaded?.script ?? options.script ?? "";
|
|
3344
1856
|
scriptPath = loaded?.scriptPath ?? options.scriptPath;
|
|
1857
|
+
const workflowName = options.workflowName ?? loaded?.savedWorkflowName ?? registry?.get(runId)?.workflowName;
|
|
3345
1858
|
try {
|
|
3346
1859
|
compileWorkflowScript(script);
|
|
3347
1860
|
} catch (error) {
|
|
@@ -3353,13 +1866,21 @@ var WorkflowRunner = class {
|
|
|
3353
1866
|
);
|
|
3354
1867
|
}
|
|
3355
1868
|
resumeReplay = options.resumeFromRunId ? await journal?.load() : void 0;
|
|
3356
|
-
|
|
3357
|
-
|
|
1869
|
+
assertStartNotCancelled();
|
|
1870
|
+
callerWasAbortedBeforeStart = options.signal.aborted;
|
|
1871
|
+
if (options.script !== void 0 && scriptPath === void 0) {
|
|
1872
|
+
const persisted = await persistInlineWorkflowScript(
|
|
1873
|
+
config,
|
|
1874
|
+
runId,
|
|
1875
|
+
script
|
|
1876
|
+
);
|
|
1877
|
+
scriptPath = persisted ?? void 0;
|
|
1878
|
+
persistedInlineScript = persisted !== null;
|
|
3358
1879
|
}
|
|
3359
|
-
if (
|
|
3360
|
-
|
|
1880
|
+
if (journal && !await journal.ensureExists()) {
|
|
1881
|
+
journalPath = void 0;
|
|
3361
1882
|
}
|
|
3362
|
-
|
|
1883
|
+
assertStartNotCancelled();
|
|
3363
1884
|
const dispatch = options.dispatch ?? createProductionDispatch(
|
|
3364
1885
|
config,
|
|
3365
1886
|
controller.signal,
|
|
@@ -3376,6 +1897,7 @@ var WorkflowRunner = class {
|
|
|
3376
1897
|
{
|
|
3377
1898
|
runId,
|
|
3378
1899
|
toolUseId: options.toolUseId,
|
|
1900
|
+
...workflowName ? { workflowName } : {},
|
|
3379
1901
|
meta: null,
|
|
3380
1902
|
status: "running",
|
|
3381
1903
|
startTime: Date.now(),
|
|
@@ -3384,18 +1906,30 @@ var WorkflowRunner = class {
|
|
|
3384
1906
|
tokenBudgetTotal: budget.total,
|
|
3385
1907
|
script,
|
|
3386
1908
|
scriptPath,
|
|
1909
|
+
...journalPath ? { journalPath } : {},
|
|
3387
1910
|
args: options.args,
|
|
3388
1911
|
...options.resumeFromRunId ? {
|
|
3389
1912
|
sourceRunId: options.resumeFromRunId,
|
|
3390
1913
|
startMode: "retry"
|
|
3391
1914
|
} : {},
|
|
3392
|
-
isBackgrounded: runInBackground
|
|
1915
|
+
isBackgrounded: runInBackground,
|
|
1916
|
+
resumeInBackground: runInBackground && config.isInteractive?.() === true && config.getExperimentalZedIntegration?.() !== true
|
|
3393
1917
|
},
|
|
3394
1918
|
controller
|
|
3395
1919
|
);
|
|
3396
1920
|
} catch (error) {
|
|
3397
1921
|
registry?.releaseStart(runId, controller);
|
|
3398
1922
|
controller.abort();
|
|
1923
|
+
if (persistedInlineScript && options.resumeFromRunId === void 0) {
|
|
1924
|
+
await deleteInlineWorkflowScript(config, runId);
|
|
1925
|
+
}
|
|
1926
|
+
if (persistedInlineScript && options.resumeFromRunId && previousEntry) {
|
|
1927
|
+
await persistInlineWorkflowScript(config, runId, previousEntry.script);
|
|
1928
|
+
}
|
|
1929
|
+
if (options.resumeFromRunId === void 0) {
|
|
1930
|
+
await journal?.remove();
|
|
1931
|
+
}
|
|
1932
|
+
releasePersistenceActivity();
|
|
3399
1933
|
throw error;
|
|
3400
1934
|
}
|
|
3401
1935
|
const emitUpdate = /* @__PURE__ */ __name(() => {
|
|
@@ -3538,8 +2072,13 @@ var WorkflowRunner = class {
|
|
|
3538
2072
|
} catch {
|
|
3539
2073
|
}
|
|
3540
2074
|
}
|
|
2075
|
+
releasePersistenceActivity();
|
|
3541
2076
|
registry?.releaseHandle(runId, handle);
|
|
3542
2077
|
}
|
|
2078
|
+
},
|
|
2079
|
+
{
|
|
2080
|
+
...scriptPath ? { scriptPath } : {},
|
|
2081
|
+
...journalPath ? { journalPath } : {}
|
|
3543
2082
|
}
|
|
3544
2083
|
);
|
|
3545
2084
|
registry?.attachHandle(handle);
|
|
@@ -3557,8 +2096,8 @@ function extractErrorMessage2(error) {
|
|
|
3557
2096
|
__name(extractErrorMessage2, "extractErrorMessage");
|
|
3558
2097
|
|
|
3559
2098
|
// packages/core/src/tools/workflow/workflow.ts
|
|
3560
|
-
import { promises as
|
|
3561
|
-
import * as
|
|
2099
|
+
import { promises as fs2 } from "node:fs";
|
|
2100
|
+
import * as path2 from "node:path";
|
|
3562
2101
|
var WORKFLOW_PARAM_SCHEMA = {
|
|
3563
2102
|
type: "object",
|
|
3564
2103
|
properties: {
|
|
@@ -3568,14 +2107,14 @@ var WORKFLOW_PARAM_SCHEMA = {
|
|
|
3568
2107
|
},
|
|
3569
2108
|
scriptPath: {
|
|
3570
2109
|
type: "string",
|
|
3571
|
-
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."
|
|
2110
|
+
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."
|
|
3572
2111
|
},
|
|
3573
2112
|
args: {
|
|
3574
2113
|
description: "Optional structured value bound to the `args` global. Pass actual JSON, not a stringified value."
|
|
3575
2114
|
},
|
|
3576
2115
|
resumeFromRunId: {
|
|
3577
2116
|
type: "string",
|
|
3578
|
-
description: "Optional. Resume a prior workflow run by id (e.g. wf_abc123\u2026). Re-runs the
|
|
2117
|
+
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."
|
|
3579
2118
|
},
|
|
3580
2119
|
run_in_background: {
|
|
3581
2120
|
type: "boolean",
|
|
@@ -3589,10 +2128,11 @@ var WORKFLOW_PARAM_SCHEMA = {
|
|
|
3589
2128
|
// pass `script`; the `scriptPath` property description states the XOR.
|
|
3590
2129
|
};
|
|
3591
2130
|
var WorkflowToolInvocation = class extends BaseToolInvocation {
|
|
3592
|
-
constructor(config, toolOptions, params) {
|
|
2131
|
+
constructor(config, toolOptions, params, workflowName) {
|
|
3593
2132
|
super(params);
|
|
3594
2133
|
this.config = config;
|
|
3595
2134
|
this.toolOptions = toolOptions;
|
|
2135
|
+
this.workflowName = workflowName;
|
|
3596
2136
|
}
|
|
3597
2137
|
static {
|
|
3598
2138
|
__name(this, "WorkflowToolInvocation");
|
|
@@ -3623,7 +2163,7 @@ var WorkflowToolInvocation = class extends BaseToolInvocation {
|
|
|
3623
2163
|
this.config,
|
|
3624
2164
|
this.params.scriptPath
|
|
3625
2165
|
) ? "generated workflow script" : "saved workflow";
|
|
3626
|
-
return `Run ${kind} (${
|
|
2166
|
+
return `Run ${kind} (${path2.basename(this.params.scriptPath)})`;
|
|
3627
2167
|
}
|
|
3628
2168
|
return `Run a workflow script (${this.params.script?.length ?? 0} chars)`;
|
|
3629
2169
|
}
|
|
@@ -3662,6 +2202,10 @@ var WorkflowToolInvocation = class extends BaseToolInvocation {
|
|
|
3662
2202
|
this.config,
|
|
3663
2203
|
this.params.scriptPath
|
|
3664
2204
|
);
|
|
2205
|
+
const isGeneratedInlineScriptPath = this.params.scriptPath !== void 0 && await isWorkflowScriptPathWithinCanonicalRoot(
|
|
2206
|
+
this.params.scriptPath,
|
|
2207
|
+
path2.dirname(this.config.storage.getInlineWorkflowScriptPath("wf_0"))
|
|
2208
|
+
);
|
|
3665
2209
|
const body = buildConfirmationPrompt(
|
|
3666
2210
|
this.params,
|
|
3667
2211
|
meta,
|
|
@@ -3672,7 +2216,7 @@ var WorkflowToolInvocation = class extends BaseToolInvocation {
|
|
|
3672
2216
|
this.config.getWorkflowRunRegistry?.(),
|
|
3673
2217
|
resolveMaxTokensPerWorkflow()
|
|
3674
2218
|
);
|
|
3675
|
-
const isInlineScript = this.params.script !== void 0;
|
|
2219
|
+
const isInlineScript = this.params.script !== void 0 || isGeneratedInlineScriptPath;
|
|
3676
2220
|
const details = {
|
|
3677
2221
|
type: "info",
|
|
3678
2222
|
title: "Run a dynamic workflow?",
|
|
@@ -3700,6 +2244,7 @@ var WorkflowToolInvocation = class extends BaseToolInvocation {
|
|
|
3700
2244
|
config: this.config,
|
|
3701
2245
|
signal,
|
|
3702
2246
|
toolUseId: this.callId,
|
|
2247
|
+
...this.workflowName ? { workflowName: this.workflowName } : {},
|
|
3703
2248
|
script: this.params.script,
|
|
3704
2249
|
scriptPath: this.params.scriptPath,
|
|
3705
2250
|
args: this.params.args,
|
|
@@ -3733,11 +2278,11 @@ var WorkflowToolInvocation = class extends BaseToolInvocation {
|
|
|
3733
2278
|
);
|
|
3734
2279
|
return {
|
|
3735
2280
|
workflowRunId: handle.runId,
|
|
2281
|
+
...handle.scriptPath ? { scriptPath: handle.scriptPath } : {},
|
|
2282
|
+
...handle.journalPath ? { journalPath: handle.journalPath } : {},
|
|
3736
2283
|
llmContent: [
|
|
3737
2284
|
{
|
|
3738
|
-
text:
|
|
3739
|
-
Run ID: ${handle.runId}
|
|
3740
|
-
Status: ${status}`
|
|
2285
|
+
text: buildBackgroundStartText(handle, status)
|
|
3741
2286
|
}
|
|
3742
2287
|
],
|
|
3743
2288
|
returnDisplay: usageBanner + `Workflow ${handle.runId} started in the background (status: ${status}). Use Background Tasks to observe, cooperatively pause/resume, or stop it.`
|
|
@@ -3772,30 +2317,142 @@ Status: ${status}`
|
|
|
3772
2317
|
} : {}
|
|
3773
2318
|
});
|
|
3774
2319
|
return {
|
|
3775
|
-
|
|
2320
|
+
...handle.scriptPath ? { scriptPath: handle.scriptPath } : {},
|
|
2321
|
+
...handle.journalPath ? { journalPath: handle.journalPath } : {},
|
|
2322
|
+
// Two parts: the script's return value is left exactly as it was,
|
|
2323
|
+
// and the run handle follows as a separate part. Note what this does
|
|
2324
|
+
// NOT mean — `convertToFunctionResponse` joins the text parts with a
|
|
2325
|
+
// newline, so the model reads `<return value>\n--- workflow run ---…`
|
|
2326
|
+
// as one string. Keeping them apart is still what makes the return
|
|
2327
|
+
// value untouched at the tool boundary, keeps `returnDisplay` clean,
|
|
2328
|
+
// and gives the per-tool head/tail truncator a distinct trailer part.
|
|
2329
|
+
// The scheduler-wide persistence gate may still fold both parts into
|
|
2330
|
+
// one head-only preview when their combined text crosses its limit.
|
|
2331
|
+
llmContent: [
|
|
2332
|
+
{ text: llmText },
|
|
2333
|
+
{ text: buildRunTrailer(this.config, handle, this.params.args) }
|
|
2334
|
+
],
|
|
3776
2335
|
returnDisplay: usageBanner + "```json\n" + displayJson + "\n```"
|
|
3777
2336
|
};
|
|
3778
2337
|
} else {
|
|
3779
2338
|
const { message, details } = settlement;
|
|
3780
2339
|
const { phases, logs, meta } = details ?? {};
|
|
3781
|
-
const
|
|
2340
|
+
const cancelled = handle.registry?.get(handle.runId)?.status === "cancelled";
|
|
2341
|
+
const failureText = cancelled ? "Workflow cancelled." : `Workflow failed: ${clampForDisplay(
|
|
2342
|
+
sanitizeBlock(message),
|
|
2343
|
+
TRAILER_ERROR_CHARS
|
|
2344
|
+
)}`;
|
|
2345
|
+
const trailer = buildRunTrailer(
|
|
2346
|
+
this.config,
|
|
2347
|
+
handle,
|
|
2348
|
+
this.params.args,
|
|
2349
|
+
logs,
|
|
2350
|
+
!cancelled
|
|
2351
|
+
);
|
|
2352
|
+
const display = `${cancelled ? "Workflow cancelled." : `Workflow failed: ${message}`}
|
|
3782
2353
|
|
|
3783
|
-
${safeStringifyDisplayPayload(
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
2354
|
+
${safeStringifyDisplayPayload(
|
|
2355
|
+
{
|
|
2356
|
+
runId: handle.runId,
|
|
2357
|
+
...meta ? { meta } : {},
|
|
2358
|
+
phases: phases ?? [],
|
|
2359
|
+
logs: logs ?? []
|
|
2360
|
+
}
|
|
2361
|
+
)}`;
|
|
3788
2362
|
return {
|
|
3789
|
-
|
|
2363
|
+
...handle.scriptPath ? { scriptPath: handle.scriptPath } : {},
|
|
2364
|
+
...handle.journalPath ? { journalPath: handle.journalPath } : {},
|
|
2365
|
+
// The failure message alone names what threw but not where to look:
|
|
2366
|
+
// the logs the runtime already mirrored (`dispatch failed (result not
|
|
2367
|
+
// consumed)` and friends) only reached `returnDisplay`, which the
|
|
2368
|
+
// scheduler overwrites with `error.message` — so the model never saw
|
|
2369
|
+
// them. Mirror the two content parts into the error message because
|
|
2370
|
+
// that is the only text the non-timeout scheduler branch delivers.
|
|
2371
|
+
llmContent: [{ text: failureText }, { text: trailer }],
|
|
3790
2372
|
returnDisplay: display,
|
|
3791
2373
|
// FIX-10 (REUSE-I1): use the standard ToolErrorType.EXECUTION_FAILED
|
|
3792
2374
|
// code so error routing / dashboards can classify workflow failures
|
|
3793
2375
|
// the same way as other execution-time tool errors.
|
|
3794
|
-
error: {
|
|
2376
|
+
error: {
|
|
2377
|
+
message: `${failureText}
|
|
2378
|
+
${trailer}`,
|
|
2379
|
+
type: "execution_failed" /* EXECUTION_FAILED */
|
|
2380
|
+
}
|
|
3795
2381
|
};
|
|
3796
2382
|
}
|
|
3797
2383
|
}
|
|
3798
2384
|
};
|
|
2385
|
+
var TRAILER_LOG_LINES = 20;
|
|
2386
|
+
var TRAILER_LOG_LINE_CHARS = 400;
|
|
2387
|
+
var TRAILER_ERROR_CHARS = 4e3;
|
|
2388
|
+
function buildRunTrailer(config, handle, args, logs, includeResume = true) {
|
|
2389
|
+
const lines = [
|
|
2390
|
+
"--- workflow run ---",
|
|
2391
|
+
`runId: ${sanitizeLine(handle.runId)}`
|
|
2392
|
+
];
|
|
2393
|
+
if (handle.scriptPath) {
|
|
2394
|
+
lines.push(`script: ${sanitizeLine(handle.scriptPath)}`);
|
|
2395
|
+
}
|
|
2396
|
+
if (handle.journalPath) {
|
|
2397
|
+
lines.push(`journal: ${sanitizeLine(handle.journalPath)}`);
|
|
2398
|
+
}
|
|
2399
|
+
const entry = handle.registry?.get(handle.runId);
|
|
2400
|
+
if (entry) {
|
|
2401
|
+
const countByStatus = /* @__PURE__ */ __name((status) => entry.dispatches.reduce(
|
|
2402
|
+
(n, dispatch) => dispatch.status === status ? n + 1 : n,
|
|
2403
|
+
0
|
|
2404
|
+
), "countByStatus");
|
|
2405
|
+
lines.push(
|
|
2406
|
+
`agents: ${entry.dispatches.length} dispatched \xB7 ${countByStatus("completed")} completed \xB7 ${countByStatus("cached")} cached \xB7 ${countByStatus("failed")} failed \xB7 ${countByStatus("cancelled")} cancelled`
|
|
2407
|
+
);
|
|
2408
|
+
}
|
|
2409
|
+
const spent = handle.budget.spent();
|
|
2410
|
+
lines.push(
|
|
2411
|
+
handle.budget.total === null ? `tokens: ${spent} spent (no cap)` : `tokens: ${spent} / ${handle.budget.total} spent`
|
|
2412
|
+
);
|
|
2413
|
+
const resume = buildResumeCall({
|
|
2414
|
+
runId: handle.runId,
|
|
2415
|
+
scriptPath: handle.scriptPath,
|
|
2416
|
+
args
|
|
2417
|
+
});
|
|
2418
|
+
if (resume && includeResume) {
|
|
2419
|
+
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";
|
|
2420
|
+
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";
|
|
2421
|
+
lines.push(`resume: ${resume} \u2014 ${pathAdvice}; ${journalAdvice}.`);
|
|
2422
|
+
if (hasUninlinableResumeArgs({ runId: handle.runId, args })) {
|
|
2423
|
+
lines.push(RESUME_ARGS_TOO_LARGE_NOTE);
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
const tail = (logs ?? []).slice(-TRAILER_LOG_LINES);
|
|
2427
|
+
if (tail.length > 0) {
|
|
2428
|
+
lines.push(
|
|
2429
|
+
`logs (last ${tail.length}):`,
|
|
2430
|
+
...tail.map(
|
|
2431
|
+
(line) => clampForDisplay(sanitizeLine(line), TRAILER_LOG_LINE_CHARS)
|
|
2432
|
+
)
|
|
2433
|
+
);
|
|
2434
|
+
}
|
|
2435
|
+
return lines.join("\n");
|
|
2436
|
+
}
|
|
2437
|
+
__name(buildRunTrailer, "buildRunTrailer");
|
|
2438
|
+
function buildBackgroundStartText(handle, status) {
|
|
2439
|
+
const lines = [
|
|
2440
|
+
"Workflow started in background.",
|
|
2441
|
+
`Run ID: ${sanitizeLine(handle.runId)}`,
|
|
2442
|
+
`Status: ${sanitizeLine(status)}`
|
|
2443
|
+
];
|
|
2444
|
+
if (handle.scriptPath) {
|
|
2445
|
+
lines.push(`Script file: ${sanitizeLine(handle.scriptPath)}`);
|
|
2446
|
+
}
|
|
2447
|
+
if (handle.journalPath) {
|
|
2448
|
+
lines.push(`Journal: ${sanitizeLine(handle.journalPath)}`);
|
|
2449
|
+
}
|
|
2450
|
+
lines.push(
|
|
2451
|
+
`You will be notified when it settles. Use /workflows ${sanitizeLine(handle.runId)} for the live phase tree.`
|
|
2452
|
+
);
|
|
2453
|
+
return lines.join("\n");
|
|
2454
|
+
}
|
|
2455
|
+
__name(buildBackgroundStartText, "buildBackgroundStartText");
|
|
3799
2456
|
function startCancelledResult() {
|
|
3800
2457
|
return {
|
|
3801
2458
|
llmContent: "Workflow was cancelled before it could start.",
|
|
@@ -3863,23 +2520,29 @@ function isGeneratedWorkflowScriptPath(config, scriptPath) {
|
|
|
3863
2520
|
}
|
|
3864
2521
|
__name(isGeneratedWorkflowScriptPath, "isGeneratedWorkflowScriptPath");
|
|
3865
2522
|
async function isGeneratedWorkflowScriptPathCanonical(config, scriptPath) {
|
|
3866
|
-
|
|
2523
|
+
return isWorkflowScriptPathWithinCanonicalRoot(
|
|
2524
|
+
scriptPath,
|
|
2525
|
+
config.storage.getGeneratedWorkflowsDir()
|
|
2526
|
+
);
|
|
2527
|
+
}
|
|
2528
|
+
__name(isGeneratedWorkflowScriptPathCanonical, "isGeneratedWorkflowScriptPathCanonical");
|
|
2529
|
+
async function isWorkflowScriptPathWithinCanonicalRoot(scriptPath, root) {
|
|
3867
2530
|
if (await isSymlinkedRoot(root)) return false;
|
|
3868
2531
|
let realScriptPath;
|
|
3869
2532
|
try {
|
|
3870
|
-
realScriptPath = await
|
|
2533
|
+
realScriptPath = await fs2.realpath(scriptPath);
|
|
3871
2534
|
} catch {
|
|
3872
2535
|
return isWithinRoot(scriptPath, root);
|
|
3873
2536
|
}
|
|
3874
2537
|
let realRoot;
|
|
3875
2538
|
try {
|
|
3876
|
-
realRoot = await
|
|
2539
|
+
realRoot = await fs2.realpath(root);
|
|
3877
2540
|
} catch {
|
|
3878
|
-
realRoot =
|
|
2541
|
+
realRoot = path2.resolve(root);
|
|
3879
2542
|
}
|
|
3880
2543
|
return isWithinRoot(realScriptPath, realRoot);
|
|
3881
2544
|
}
|
|
3882
|
-
__name(
|
|
2545
|
+
__name(isWorkflowScriptPathWithinCanonicalRoot, "isWorkflowScriptPathWithinCanonicalRoot");
|
|
3883
2546
|
function buildConfirmationPrompt(params, meta, isGeneratedScriptPath) {
|
|
3884
2547
|
const lines = [];
|
|
3885
2548
|
if (meta) {
|
|
@@ -4005,7 +2668,7 @@ Reach for one to be comprehensive (decompose the work and cover every part in pa
|
|
|
4005
2668
|
|
|
4006
2669
|
**Runtime** \u2014 see the \`script\` parameter for the detailed authoring contract.
|
|
4007
2670
|
|
|
4008
|
-
\`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 an attempt that hits either becomes \`null\` in \`parallel()\`/\`pipeline()\`, indistinguishable from a missing agent, so raise them for legitimately long work. 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 \u2014 a bare sequential \`await agent()\` sees the rejection, while inside \`parallel()\`/\`pipeline()\` the refused slot becomes \`null\` and the script keeps running on partial results. 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. 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.
|
|
2671
|
+
\`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 an attempt that hits either becomes \`null\` in \`parallel()\`/\`pipeline()\`, indistinguishable from a missing agent, so raise them for legitimately long work. 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 \u2014 a bare sequential \`await agent()\` sees the rejection, while inside \`parallel()\`/\`pipeline()\` the refused slot becomes \`null\` and the script keeps running on partial results. 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.
|
|
4009
2672
|
|
|
4010
2673
|
**Scout first, then orchestrate**
|
|
4011
2674
|
|
|
@@ -4051,7 +2714,7 @@ var WorkflowTool = class extends BaseDeclarativeTool {
|
|
|
4051
2714
|
static {
|
|
4052
2715
|
__name(this, "WorkflowTool");
|
|
4053
2716
|
}
|
|
4054
|
-
buildSessionOwnedBackground(params) {
|
|
2717
|
+
buildSessionOwnedBackground(params, workflowName) {
|
|
4055
2718
|
const validationError = this.validateToolParams(params);
|
|
4056
2719
|
if (validationError) {
|
|
4057
2720
|
throw new Error(validationError);
|
|
@@ -4061,7 +2724,12 @@ var WorkflowTool = class extends BaseDeclarativeTool {
|
|
|
4061
2724
|
"WorkflowTool: session-owned background runs require an active workflow completion channel."
|
|
4062
2725
|
);
|
|
4063
2726
|
}
|
|
4064
|
-
return
|
|
2727
|
+
return new WorkflowToolInvocation(
|
|
2728
|
+
this.config,
|
|
2729
|
+
this.toolOptions,
|
|
2730
|
+
{ ...params, run_in_background: true },
|
|
2731
|
+
workflowName
|
|
2732
|
+
);
|
|
4065
2733
|
}
|
|
4066
2734
|
validateToolParamValues(params) {
|
|
4067
2735
|
const hasScript = typeof params.script === "string" && params.script.length > 0;
|
|
@@ -4094,7 +2762,7 @@ export {
|
|
|
4094
2762
|
};
|
|
4095
2763
|
/**
|
|
4096
2764
|
* @license
|
|
4097
|
-
* Copyright
|
|
2765
|
+
* Copyright 2026 Qwen Team
|
|
4098
2766
|
* SPDX-License-Identifier: Apache-2.0
|
|
4099
2767
|
*/
|
|
4100
2768
|
/**
|
|
@@ -4102,8 +2770,3 @@ export {
|
|
|
4102
2770
|
* Copyright 2025 Qwen
|
|
4103
2771
|
* SPDX-License-Identifier: Apache-2.0
|
|
4104
2772
|
*/
|
|
4105
|
-
/**
|
|
4106
|
-
* @license
|
|
4107
|
-
* Copyright 2026 Qwen Team
|
|
4108
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4109
|
-
*/
|