gerege-cli 0.26.6 → 0.26.8
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/gerege-video/SKILL.md +22 -0
- package/bundled/gerege-video/scripts/video.js +137 -0
- package/chunks/{MaxSizedBox-QCIXIS4P.js → MaxSizedBox-LUINLOQW.js} +1 -1
- package/chunks/{StandaloneSessionPicker-BAFAIRT7.js → StandaloneSessionPicker-B7N4QO5D.js} +1 -1
- package/chunks/{acp-subagent-executor-TPVXURLW.js → acp-subagent-executor-J6H6FKUT.js} +1 -1
- package/chunks/{acpAgent-67UN66PB.js → acpAgent-XG6SM2VU.js} +3 -3
- package/chunks/{advisor-SAXMI4QZ.js → advisor-SZVPQNPA.js} +1 -1
- package/chunks/{agent-KV7BXY6C.js → agent-N7QF7BJS.js} +1 -1
- package/chunks/{agent-headless-FQX3JGG6.js → agent-headless-GLP5GUEX.js} +1 -1
- package/chunks/{agent-host-client-L5EHC4AC.js → agent-host-client-H4VOB3M6.js} +1 -1
- package/chunks/{agent-host-connections-EDBMCVQF.js → agent-host-connections-E4C3OC4M.js} +1 -1
- package/chunks/{anthropicContentGenerator-V7TX2NXP.js → anthropicContentGenerator-5VTWQLT5.js} +1 -1
- package/chunks/{autofix-pr-WP34NYHL.js → autofix-pr-HDYQDJS4.js} +1 -1
- package/chunks/{batch-XFVQ4BLM.js → batch-3CRVN5VJ.js} +1 -1
- package/chunks/{bridge-AE7AFEXB.js → bridge-NZ6WVBLQ.js} +1 -1
- package/chunks/{channel-settings-store-X63P5OVT.js → channel-settings-store-Z7I2JI6M.js} +1 -1
- package/chunks/{chunk-BCI62WSL.js → chunk-236DHGNH.js} +1 -1
- package/chunks/{chunk-JRTOPEM3.js → chunk-2M3ND5WN.js} +1 -1
- package/chunks/{chunk-LBLLWAKK.js → chunk-36A6EXHB.js} +1 -1
- package/chunks/{chunk-H3IR3GIE.js → chunk-3ANIQTDT.js} +1 -1
- package/chunks/{chunk-GSPGIGO5.js → chunk-3QTR2HAE.js} +3 -3
- package/chunks/{chunk-32XHDDIA.js → chunk-3TTHYXT3.js} +1 -1
- package/chunks/{chunk-MTDBCIDA.js → chunk-4CE4GMDL.js} +1 -1
- package/chunks/{chunk-T2YTHAJW.js → chunk-4FVT657Y.js} +1 -1
- package/chunks/{chunk-CGDFZEER.js → chunk-4HSISRRA.js} +1 -1
- package/chunks/{chunk-7453BHJO.js → chunk-4SZUJ5RT.js} +1 -1
- package/chunks/{chunk-B37YY4XU.js → chunk-57D2OB3I.js} +1 -1
- package/chunks/{chunk-WGFX3EL3.js → chunk-5FGBLIXB.js} +1 -1
- package/chunks/{chunk-I6PUY2T3.js → chunk-5HX2QGVR.js} +1 -1
- package/chunks/{chunk-BPFFRPWE.js → chunk-5ZNXAWOG.js} +6 -6
- package/chunks/{chunk-BHIDG6VZ.js → chunk-6CKX56LJ.js} +1 -1
- package/chunks/{chunk-GRAECADD.js → chunk-6NIQFWXP.js} +1 -1
- package/chunks/{chunk-ELDZ4MNL.js → chunk-6PC6MZHL.js} +1 -1
- package/chunks/{chunk-FEP6W4NJ.js → chunk-6VQKGKMJ.js} +1 -1
- package/chunks/{chunk-GBSRWT7J.js → chunk-6ZEMLEK2.js} +1 -1
- package/chunks/{chunk-4NDJKNN6.js → chunk-72VY2PJA.js} +1 -1
- package/chunks/{chunk-BAUMVH4Q.js → chunk-75I3NYBD.js} +1 -1
- package/chunks/{chunk-YH2XRWRF.js → chunk-76L7ZDEK.js} +1 -1
- package/chunks/{chunk-2JGTWRZJ.js → chunk-7XQ5D34E.js} +6 -6
- package/chunks/{chunk-DA6LOBSB.js → chunk-AYX75VXG.js} +1 -1
- package/chunks/{chunk-G6DALGGS.js → chunk-BBDFEMCF.js} +1 -1
- package/chunks/{chunk-VD2GSW64.js → chunk-BOTX7S66.js} +1 -1
- package/chunks/{chunk-M6KB5RVD.js → chunk-CY2QKKZA.js} +1 -1
- package/chunks/{chunk-HTAUIJB4.js → chunk-D5JWQUID.js} +1 -1
- package/chunks/{chunk-P3JEEDQZ.js → chunk-DMIPB7RZ.js} +1 -1
- package/chunks/{chunk-CF6SZJNP.js → chunk-DSKA3P2C.js} +1 -1
- package/chunks/{chunk-LTE4N6L3.js → chunk-DVC65H4X.js} +1 -1
- package/chunks/{chunk-W5Z4BWWA.js → chunk-DVJSDCMX.js} +1 -1
- package/chunks/{chunk-65ME4BOH.js → chunk-E6CPFQX2.js} +1 -1
- package/chunks/{chunk-JEDL4IKF.js → chunk-EIFBGEXJ.js} +1 -1
- package/chunks/{chunk-AYVCT5FF.js → chunk-EQOHDAYU.js} +1 -1
- package/chunks/{chunk-2TAJ5STJ.js → chunk-EZPM4DLR.js} +1 -1
- package/chunks/{chunk-JWNKPINR.js → chunk-F6U6T7QD.js} +1 -1
- package/chunks/{chunk-ET5M5WFN.js → chunk-FCGFBUHS.js} +1 -1
- package/chunks/{chunk-OU7CEG7Q.js → chunk-G2LTZU67.js} +1 -1
- package/chunks/{chunk-2N3NBTYJ.js → chunk-GMJSEK4V.js} +1 -1
- package/chunks/{chunk-NA4ZF2FE.js → chunk-HJMUBVXZ.js} +2 -2
- package/chunks/{chunk-AFO5ER23.js → chunk-HQZTAA2U.js} +1 -1
- package/chunks/{chunk-OK7LBM5G.js → chunk-I63TIQOI.js} +1 -1
- package/chunks/{chunk-OJ4K62S2.js → chunk-I65LBJN7.js} +1 -1
- package/chunks/{chunk-GHIFIXNX.js → chunk-IBDOC27R.js} +1 -1
- package/chunks/{chunk-2LWJGXTW.js → chunk-IKF2HWEV.js} +1 -1
- package/chunks/{chunk-AEZYXPFS.js → chunk-K6NS2HXT.js} +1 -1
- package/chunks/{chunk-T5DKF33F.js → chunk-KTRNYPQP.js} +1 -1
- package/chunks/{chunk-SKGJ26HQ.js → chunk-L3ANU5JZ.js} +1 -1
- package/chunks/{chunk-U3Q72OGV.js → chunk-LKPMADUO.js} +1 -1
- package/chunks/{chunk-MYV7GY3H.js → chunk-M56Y2B6N.js} +1 -1
- package/chunks/{chunk-34HC2AXI.js → chunk-N5KRBAK5.js} +2 -2
- package/chunks/{chunk-EXIFPXMB.js → chunk-NA2WJPOU.js} +1 -1
- package/chunks/{chunk-7RNOS7R4.js → chunk-NGOWLXYK.js} +1 -1
- package/chunks/{chunk-IZ5MWA6E.js → chunk-NL7P73ZP.js} +1 -1
- package/chunks/{chunk-FYBJGRX7.js → chunk-NS3QR7D3.js} +1 -1
- package/chunks/{chunk-XISR37DQ.js → chunk-O5JCCBMQ.js} +1 -1
- package/chunks/{chunk-FKL3V5BO.js → chunk-OOKFFZHF.js} +1 -1
- package/chunks/{chunk-VRKYBH5G.js → chunk-OTYPLLMT.js} +5 -5
- package/chunks/{chunk-W66WWTOP.js → chunk-P7NHWX27.js} +1 -1
- package/chunks/{chunk-AEKEZRIU.js → chunk-PC5QZUKR.js} +1 -1
- package/chunks/{chunk-NEKPQLFY.js → chunk-PS7MQL57.js} +2 -2
- package/chunks/{chunk-TB4AUC2L.js → chunk-PXWHOFAA.js} +1 -1
- package/chunks/{chunk-OOJ2AQT3.js → chunk-Q65LVCDR.js} +1 -1
- package/chunks/{chunk-EFIRES46.js → chunk-QDUDLELH.js} +1 -1
- package/chunks/{chunk-KZNYALFU.js → chunk-QF22ILPV.js} +1 -1
- package/chunks/{chunk-MGATL4OA.js → chunk-QW7MAG2E.js} +1 -1
- package/chunks/{chunk-KJGRCIVY.js → chunk-RXK6XD6F.js} +1 -1
- package/chunks/{chunk-W2RQIZ6B.js → chunk-SVDFCWS7.js} +1 -1
- package/chunks/{chunk-P62S5JGM.js → chunk-TKP3GAUI.js} +1 -1
- package/chunks/{chunk-BQZF3UKI.js → chunk-TUS74LFI.js} +1 -1
- package/chunks/{chunk-JH3V5SPA.js → chunk-U7YGHPSL.js} +1 -1
- package/chunks/{chunk-NONBHCXP.js → chunk-UB37RBSK.js} +1 -1
- package/chunks/{chunk-T53VMDXH.js → chunk-UK5SIRH4.js} +1 -1
- package/chunks/{chunk-3W32X2DH.js → chunk-UTTSBCFR.js} +1 -1
- package/chunks/{chunk-RSLTOIG5.js → chunk-UYV4ZVXY.js} +2 -2
- package/chunks/{chunk-FKZ46GKL.js → chunk-VC3JJL7E.js} +1 -1
- package/chunks/{chunk-SP6CQ3MO.js → chunk-VKWVIWLK.js} +1 -1
- package/chunks/{chunk-N7PWZBXV.js → chunk-VUI6STKU.js} +1 -1
- package/chunks/{chunk-5EXL4TKQ.js → chunk-W3YXE55M.js} +1 -1
- package/chunks/{chunk-NVOI6UDQ.js → chunk-WAIPC47V.js} +1 -1
- package/chunks/{chunk-QDCUR3JB.js → chunk-WMJ6UHDP.js} +1 -1
- package/chunks/{chunk-CBE6ZIHU.js → chunk-WZU2ECUD.js} +1 -1
- package/chunks/{chunk-ZENMAISJ.js → chunk-XAGIZY2Y.js} +1 -1
- package/chunks/{chunk-RXN7DUMP.js → chunk-XGZYVULJ.js} +2 -2
- package/chunks/{chunk-HOG66S6K.js → chunk-XJIHDVPX.js} +1 -1
- package/chunks/{chunk-UKLXKJKL.js → chunk-XVDIHFRH.js} +1 -1
- package/chunks/{chunk-76FSYQTG.js → chunk-YMEW4TTT.js} +1 -1
- package/chunks/{chunk-EYPLBTMI.js → chunk-Z32URWBG.js} +1 -1
- package/chunks/{chunk-CUP2TNJK.js → chunk-Z6HRXHJP.js} +1 -1
- package/chunks/{chunk-MPVQDYPH.js → chunk-ZO4F6ZWR.js} +1 -1
- package/chunks/{codex-subagent-executor-OLMGVPVS.js → codex-subagent-executor-DDKYNU42.js} +1 -1
- package/chunks/{config-utils-OWY5G5Y2.js → config-utils-S7Z2ZZ2E.js} +1 -1
- package/chunks/{contextCommand-IXFUZH65.js → contextCommand-7F4PGV2A.js} +1 -1
- package/chunks/{core-runtime-O4LC4NY3.js → core-runtime-LBH3U7ZF.js} +1 -1
- package/chunks/{create-sub-session-6F7C3TMT.js → create-sub-session-56DS2T6L.js} +1 -1
- package/chunks/{cron-create-2422NBSJ.js → cron-create-PBP3C46Q.js} +1 -1
- package/chunks/{daemon-git-worktree-guard-EWPQA6NO.js → daemon-git-worktree-guard-WJS6FBDA.js} +1 -1
- package/chunks/{daemon-status-provider-FAHOXNFW.js → daemon-status-provider-UPPAEHJ6.js} +1 -1
- package/chunks/{daemon-trust-policy-L3DM6AI5.js → daemon-trust-policy-4Z5HSNUX.js} +1 -1
- package/chunks/{daemon-trust-policy-monitor-HNPY5KJ4.js → daemon-trust-policy-monitor-WFWDOYX3.js} +1 -1
- package/chunks/{deferred-core-runtime-JF42NQJK.js → deferred-core-runtime-MJYNEA4N.js} +1 -1
- package/chunks/{edit-E5LEI2LL.js → edit-U7TGKKK3.js} +1 -1
- package/chunks/{enterPlanMode-3COTUV5V.js → enterPlanMode-27HC5AXN.js} +1 -1
- package/chunks/{environment-XBBIB3VA.js → environment-PHWY6C4P.js} +1 -1
- package/chunks/{errors-LNMQ7TUK.js → errors-F2EYYFI3.js} +1 -1
- package/chunks/{execution-tool-QDDKJD2K.js → execution-tool-O4KJ5SMM.js} +1 -1
- package/chunks/{execution-worker-TXGZRZXE.js → execution-worker-AMFXZ7JD.js} +1 -1
- package/chunks/{exitPlanMode-Z7QEMWPE.js → exitPlanMode-LDYL43PB.js} +1 -1
- package/chunks/{fast-path-M6K2RACY.js → fast-path-HTODEVOR.js} +1 -1
- package/chunks/{glob-N2QT4U7U.js → glob-NKQJJZND.js} +1 -1
- package/chunks/{goal-tools-CUSQD3DG.js → goal-tools-47I455VV.js} +1 -1
- package/chunks/{handleAutoUpdate-QF2YQHF6.js → handleAutoUpdate-MJKTDJUO.js} +1 -1
- package/chunks/{i18n-AGOA6MUI.js → i18n-TCOB4TC5.js} +1 -1
- package/chunks/{initializer-FRKYDUSX.js → initializer-NLYOGZZS.js} +1 -1
- package/chunks/{installationInfo-OKA4WXAS.js → installationInfo-TF2RSJOG.js} +1 -1
- package/chunks/{interactive-mod-session-MWYN5IFK.js → interactive-mod-session-5F7R3KSA.js} +1 -1
- package/chunks/{list-DE7VUIR2.js → list-U2AEVLFP.js} +1 -1
- package/chunks/{llm-N3JGJHYC.js → llm-EV2QTQBU.js} +4 -4
- package/chunks/{llm-content-generator-VMUBA7OJ.js → llm-content-generator-ZXUSPPG2.js} +1 -1
- package/chunks/{loadedSettingsAdapter-5C36OZ7N.js → loadedSettingsAdapter-TLRI22X7.js} +1 -1
- package/chunks/{local-BE624O3A.js → local-ZTSBSKWV.js} +1 -1
- package/chunks/{local-execution-environment-OPGM7Y6L.js → local-execution-environment-F263PSIM.js} +1 -1
- package/chunks/{loggingContentGenerator-2MHAI6JR.js → loggingContentGenerator-2XHSIJQD.js} +1 -1
- package/chunks/{loop-wakeup-BDLATBXH.js → loop-wakeup-5ET3JHUT.js} +1 -1
- package/chunks/{manage-memory-BBCEIIWB.js → manage-memory-MJEQ47H2.js} +1 -1
- package/chunks/{managed-execution-engine-SRFALTCX.js → managed-execution-engine-ODPR5OEH.js} +1 -1
- package/chunks/{managed-local-serve-ICNAS3E6.js → managed-local-serve-S5R4Z5OL.js} +1 -1
- package/chunks/managed-npm-update-BUI5APGY.js +8 -0
- package/chunks/{managed-runtime-attestation-worker-ZRDWKXCI.js → managed-runtime-attestation-worker-BQP4E7LQ.js} +1 -1
- package/chunks/{managed-runtime-bootstrap-6NTGZXQL.js → managed-runtime-bootstrap-SRBDFSKK.js} +1 -1
- package/chunks/{managed-runtime-session-worker-RKQBBFR6.js → managed-runtime-session-worker-UI23BTYJ.js} +1 -1
- package/chunks/{managed-runtime-ssh-worker-FCGV6FSW.js → managed-runtime-ssh-worker-HU4CIJRK.js} +1 -1
- package/chunks/{managed-session-authority-C7IW6TJX.js → managed-session-authority-XSSTLAEY.js} +1 -1
- package/chunks/{mcp-VC4CJPE5.js → mcp-WLHDOKP7.js} +1 -1
- package/chunks/{memory-S6OJA3ZD.js → memory-OUUHPSDD.js} +1 -1
- package/chunks/{model-call-collection-MJZWRQSU.js → model-call-collection-4A2EB76B.js} +1 -1
- package/chunks/{model-configuration-SKU6L3QI.js → model-configuration-4CGUFKEP.js} +1 -1
- package/chunks/{modelConfigUtils-TJCB6NXT.js → modelConfigUtils-HUEERWBA.js} +1 -1
- package/chunks/{monitor-M3PNLCYP.js → monitor-FXL5UNMP.js} +1 -1
- package/chunks/{nonInteractiveCli-MR7JLAWU.js → nonInteractiveCli-W7M2O43W.js} +1 -1
- package/chunks/{nonInteractiveToolExecutor-YKA6JMTY.js → nonInteractiveToolExecutor-EMLI363Q.js} +1 -1
- package/chunks/{notebook-edit-ENTFB5D7.js → notebook-edit-R5RSLSSH.js} +1 -1
- package/chunks/{omni-6YBX4R6K.js → omni-DNZGITTE.js} +1 -1
- package/chunks/{openaiContentGenerator-XRXX33FY.js → openaiContentGenerator-PKOPYMHR.js} +1 -1
- package/chunks/{openaiResponsesContentGenerator-L6ONEHMR.js → openaiResponsesContentGenerator-MHH2MF3V.js} +1 -1
- package/chunks/{pidfile-XR4JF2Z6.js → pidfile-5ZNJWMKG.js} +1 -1
- package/chunks/{processUtils-GQYNJRBJ.js → processUtils-JIHQDASW.js} +1 -1
- package/chunks/{prompt-terminal-ledger-7BM7YDLG.js → prompt-terminal-ledger-L3LZ5SLR.js} +1 -1
- package/chunks/{qwenContentGenerator-QSA32XEL.js → qwenContentGenerator-QCZL7HJJ.js} +1 -1
- package/chunks/{reactive-degrade-TFNBAAPZ.js → reactive-degrade-YUXOUQG4.js} +1 -1
- package/chunks/{read-file-VD7OFO2E.js → read-file-FBNU3AVX.js} +1 -1
- package/chunks/{resumeHistoryUtils-2B4KPI7G.js → resumeHistoryUtils-5FPRTI4A.js} +1 -1
- package/chunks/{review-C365WGCW.js → review-NLFYSNM3.js} +1 -1
- package/chunks/{ripGrep-D7WPMBXR.js → ripGrep-JUAPC5LD.js} +1 -1
- package/chunks/{run-qwen-serve-NZWQHWQA.js → run-qwen-serve-JP64UQ3Y.js} +1 -1
- package/chunks/{runtime-J6SPBSCS.js → runtime-D2QUYM6U.js} +1 -1
- package/chunks/{sandboxConfig-QS2XBPZG.js → sandboxConfig-7VZJQV6H.js} +1 -1
- package/chunks/{scheduled-tasks-YNNIOOPM.js → scheduled-tasks-PC6EH75E.js} +1 -1
- package/chunks/{scheduler-KCMSPHON.js → scheduler-RUV2FNDR.js} +1 -1
- package/chunks/{search-memory-EUBJ7IAV.js → search-memory-YJTJ7BRU.js} +1 -1
- package/chunks/{send-message-CWWZUPSK.js → send-message-EEEFFTHX.js} +1 -1
- package/chunks/{serve-4CB4BWJ5.js → serve-KMIZDYON.js} +1 -1
- package/chunks/{server-JNANUIGC.js → server-DUPK3V7B.js} +3 -3
- package/chunks/{session-3LQLXPUA.js → session-CW5YMFMP.js} +1 -1
- package/chunks/{session-attachments-root-BWIVWFHJ.js → session-attachments-root-5H5GFHLI.js} +1 -1
- package/chunks/{session-execution-engine-selector-5OLRX57L.js → session-execution-engine-selector-MVXM2HZW.js} +1 -1
- package/chunks/{session-pr-refresh-RLF3EXS3.js → session-pr-refresh-4UPONX4L.js} +1 -1
- package/chunks/{sessionService-U7ACD2HP.js → sessionService-GGCYISSL.js} +1 -1
- package/chunks/{settings-FTGWYTUH.js → settings-AASJCESS.js} +1 -1
- package/chunks/{shell-E4RENYQC.js → shell-V4WWLW3Q.js} +1 -1
- package/chunks/{skill-OLNPHRWB.js → skill-NDEBB7VX.js} +1 -1
- package/chunks/{skill-settings-R2BV2GEK.js → skill-settings-YAI3GYU5.js} +1 -1
- package/chunks/{spawnChannel-LOPAR5T2.js → spawnChannel-6JKVJAXZ.js} +1 -1
- package/chunks/{standalone-update-IGDX2RGN.js → standalone-update-NJP5OCKJ.js} +1 -1
- package/chunks/{start-opentui-ui-33QLBNRC.js → start-opentui-ui-M4B4SXRM.js} +1 -1
- package/chunks/{startInteractiveUI-RQKHD7MM.js → startInteractiveUI-O4JUDEAU.js} +1 -1
- package/chunks/{team-create-HAVKHNU5.js → team-create-NLJ7QBLD.js} +1 -1
- package/chunks/{team-plan-approval-7MCQX67C.js → team-plan-approval-XKYPVWNG.js} +1 -1
- package/chunks/{terminal-image-renderer-XT5JVEO6.js → terminal-image-renderer-47TD747D.js} +1 -1
- package/chunks/{theme-manager-DR5EYGLT.js → theme-manager-AANEBPLJ.js} +1 -1
- package/chunks/{tool-call-LZHZ5RVH.js → tool-call-ETH3LS7Y.js} +1 -1
- package/chunks/{tool-result-media-XCXCF4YC.js → tool-result-media-EFOEPAF2.js} +1 -1
- package/chunks/{tool-search-K6S3ON7M.js → tool-search-J3CF5PRN.js} +1 -1
- package/chunks/{total-session-admission-LGSS2VWS.js → total-session-admission-3DC52PLQ.js} +1 -1
- package/chunks/{trustedFolders-IIR2UZRL.js → trustedFolders-4KPWZZKB.js} +1 -1
- package/chunks/{update-relaunch-WVIFX5CN.js → update-relaunch-A67BS7QS.js} +1 -1
- package/chunks/{updateCheck-CMEWLLZJ.js → updateCheck-X623JRSY.js} +1 -1
- package/chunks/{upload-config-TCCFCNCD.js → upload-config-X2CR3F26.js} +1 -1
- package/chunks/{useAutoAcceptIndicator-5RTTH3OW.js → useAutoAcceptIndicator-INIOQGJH.js} +1 -1
- package/chunks/{validateNonInterActiveAuth-AO336KDX.js → validateNonInterActiveAuth-XJ2U5CLB.js} +1 -1
- package/chunks/{version-JYWKKMNP.js → version-MFHRMM7W.js} +1 -1
- package/chunks/{web-fetch-HWTAWXFM.js → web-fetch-3GEJ62DH.js} +1 -1
- package/chunks/{web-search-HAI5LW3G.js → web-search-WJZO3Q3A.js} +1 -1
- package/chunks/{workflow-BZ2YFGF6.js → workflow-ML7ITCMH.js} +1 -1
- package/chunks/{workflow-ancestor-trust-26TFXFPO.js → workflow-ancestor-trust-M3VFMS73.js} +1 -1
- package/chunks/{workspace-agents-DLI4JQJZ.js → workspace-agents-YFZMV7EF.js} +1 -1
- package/chunks/{workspace-providers-status-64C7DJZU.js → workspace-providers-status-3COKLBCI.js} +1 -1
- package/chunks/{workspace-recovery-worker-IFRT3KKP.js → workspace-recovery-worker-QURA3WFZ.js} +1 -1
- package/chunks/{workspace-registration-store-MYKJM2SK.js → workspace-registration-store-F3AGIOBW.js} +1 -1
- package/chunks/{workspace-registry-GZJRONAY.js → workspace-registry-QUBL3RW6.js} +1 -1
- package/chunks/{workspace-runtime-coordinator-44KW6HSN.js → workspace-runtime-coordinator-22TSDHXX.js} +1 -1
- package/chunks/{workspace-service-YHTSZYYD.js → workspace-service-UUENTHNO.js} +1 -1
- package/chunks/{workspace-skills-status-NEB62X24.js → workspace-skills-status-NNQQBBCJ.js} +1 -1
- package/chunks/{workspace-trust-reconciler-HZLOOZWM.js → workspace-trust-reconciler-3CMMNCGG.js} +1 -1
- package/chunks/{write-file-HD5LHXGL.js → write-file-DEAFIK4C.js} +1 -1
- package/chunks/{zoom-image-W4BMRC5T.js → zoom-image-YYO22PQG.js} +1 -1
- package/cli-entry.js +2 -3
- package/cli.js +2 -2
- package/execution-worker.js +1 -1
- package/export-transcript-document.js +1 -1
- package/gerege.mjs +11 -0
- package/package.json +2 -12
- package/chunks/managed-npm-update-CTL6LH5Z.js +0 -8
- package/opentui-assets/@opentui/core/assets/javascript/highlights.scm +0 -205
- package/opentui-assets/@opentui/core/assets/javascript/tree-sitter-javascript.wasm +0 -0
- package/opentui-assets/@opentui/core/assets/markdown/highlights.scm +0 -150
- package/opentui-assets/@opentui/core/assets/markdown/injections.scm +0 -27
- package/opentui-assets/@opentui/core/assets/markdown/tree-sitter-markdown.wasm +0 -0
- package/opentui-assets/@opentui/core/assets/markdown_inline/highlights.scm +0 -115
- package/opentui-assets/@opentui/core/assets/markdown_inline/tree-sitter-markdown_inline.wasm +0 -0
- package/opentui-assets/@opentui/core/assets/typescript/highlights.scm +0 -604
- package/opentui-assets/@opentui/core/assets/typescript/tree-sitter-typescript.wasm +0 -0
- package/opentui-assets/@opentui/core/assets/zig/highlights.scm +0 -284
- package/opentui-assets/@opentui/core/assets/zig/tree-sitter-zig.wasm +0 -0
- package/opentui-assets/@opentui/core/parser.worker.js +0 -4566
- package/opentui-assets/@opentui/core-darwin-arm64/libopentui.dylib +0 -0
- package/opentui-assets/@opentui/core-darwin-x64/libopentui.dylib +0 -0
- package/opentui-assets/@opentui/core-linux-arm64/libopentui.so +0 -0
- package/opentui-assets/@opentui/core-linux-x64/libopentui.so +0 -0
- package/opentui-assets/web-tree-sitter/tree-sitter.wasm +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{buildScheduledTaskRunPrompt,parseChannelDelivery,scheduledTaskRunSessionName,scheduledTaskRunSourceId}from"./chunk-EXIFPXMB.js";import{createSessionOrganizationService}from"./chunk-5EXL4TKQ.js";import{requireTrustedWorkspaceRuntime,resolveWorkspaceRuntimeWithLiveCompatibilityFromParam,sendConversationRuntimeUnavailable,sendGenerationClosedError}from"./chunk-TB4AUC2L.js";import{parseCallerSuppliedSessionId}from"./chunk-LGFF5PJA.js";import{SCHEDULED_TASK_RUN_SOURCE_TYPE}from"./chunk-BCI62WSL.js";import{SessionNotFoundError}from"./chunk-VTZZXEWA.js";import{isChannelDeliveryError}from"./chunk-O6ZQAVRG.js";import{MAX_JOBS,SessionService,gateCommandError,nextDurableFireMs,nextFireTime,parseCron}from"./chunk-2JGTWRZJ.js";import{stripTerminalControlSequences}from"./chunk-R2EHHA2C.js";import{MAX_CRON_TASK_ROUTING_ID_LENGTH,annotateCronRunSession,appendCronRun,cronTaskSessionDeletionId,generateCronTaskId,getCronFilePath,isValidCronTaskRoutingId,readCronTasks,taskHasLegacyCondition,updateCronTasks,withTaskGate}from"./chunk-T6W33SET.js";import{writeStderrLine}from"./chunk-M4ECEHLX.js";import{Storage}from"./chunk-EPODBRBP.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import{isDeepStrictEqual}from"node:util";import{access}from"node:fs/promises";var MAX_SCHEDULED_TASKS=MAX_JOBS;var MAX_PROMPT_LENGTH=1e5;var MAX_NAME_LENGTH=200;var MAX_CRON_LENGTH=200;var MAX_ROUTING_ID_LENGTH=MAX_CRON_TASK_ROUTING_ID_LENGTH;var MAX_SESSION_NAME_LENGTH=60;function scheduledTaskSessionName(label){const cleaned=stripTerminalControlSequences(label).replace(/[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g,"").trim().replace(/\s+/g," ");let short=cleaned;if(cleaned.length>MAX_SESSION_NAME_LENGTH){let cut=MAX_SESSION_NAME_LENGTH-1;const boundary=cleaned.charCodeAt(cut-1);if(boundary>=55296&&boundary<=56319)cut-=1;short=`${cleaned.slice(0,cut)}\u2026`}return short}__name(scheduledTaskSessionName,"scheduledTaskSessionName");var ExistingSessionScheduledTaskCreateError=class extends Error{constructor(status,code,message){super(message);this.status=status;this.code=code;this.name="ExistingSessionScheduledTaskCreateError"}static{__name(this,"ExistingSessionScheduledTaskCreateError")}};function assertReusableScheduledTaskSession(target,sessionId,allowActivePrompt,assertCallerPromptActive){const{bridge,workspaceCwd}=target;if(!bridge){throw new ExistingSessionScheduledTaskCreateError(409,"session_binding_unavailable","Session management is not available for this workspace")}assertCallerPromptActive?.();let owner;try{owner=target.resolveLiveSessionOwner?.(sessionId)}catch(error){writeStderrLine(`qwen serve: failed to resolve scheduled-task session owner '${sessionId}': ${error instanceof Error?error.message:String(error)}`);throw new ExistingSessionScheduledTaskCreateError(500,"scheduled_tasks_session_failed","Failed to look up the requested session")}if(owner?.kind==="unavailable"){throw new ExistingSessionScheduledTaskCreateError(503,"workspace_runtime_unavailable","The workspace runtime is unavailable")}if(owner?.kind==="ambiguous"){throw new ExistingSessionScheduledTaskCreateError(500,"ambiguous_session_owner",`Session owner is ambiguous for "${sessionId}"`)}if(owner?.kind==="found"&&owner.runtime.workspaceCwd!==workspaceCwd){throw new ExistingSessionScheduledTaskCreateError(400,"session_workspace_mismatch","The requested session belongs to a different workspace; use that workspace's scheduled-task endpoint")}let summary;try{summary=bridge.getSessionSummary(sessionId)}catch(error){if(error instanceof SessionNotFoundError){throw new ExistingSessionScheduledTaskCreateError(404,"session_not_found",`Session '${sessionId}' was not found`)}writeStderrLine(`qwen serve: failed to look up scheduled-task session '${sessionId}': ${error instanceof Error?error.message:String(error)}`);throw new ExistingSessionScheduledTaskCreateError(500,"scheduled_tasks_session_failed","Failed to look up the requested session")}if(summary.workspaceCwd!==workspaceCwd){throw new ExistingSessionScheduledTaskCreateError(400,"session_workspace_mismatch","The requested session belongs to a different workspace; use that workspace's scheduled-task endpoint")}if(!allowActivePrompt&&summary.hasActivePrompt||(summary.pendingInteractionCount??0)>0){throw new ExistingSessionScheduledTaskCreateError(409,"session_busy",allowActivePrompt?"The caller session has a pending interaction; resolve it before binding the session to a task":"The requested session is busy; wait for its active prompt or pending interaction to finish before binding it to a task")}if(summary.sourceType==="scheduled_task"){throw new ExistingSessionScheduledTaskCreateError(409,"session_already_bound","The requested session is already reserved for a scheduled task")}if(summary.parentSessionId!==void 0||summary.sourceId!==void 0||summary.sourceType!==void 0&&summary.sourceType!=="default"){throw new ExistingSessionScheduledTaskCreateError(409,"session_source_ineligible","The requested session source cannot own a scheduled task")}}__name(assertReusableScheduledTaskSession,"assertReusableScheduledTaskSession");async function createScheduledTaskWithExistingSession(target,input,options){if(input.cron.length===0||input.cron.length>MAX_CRON_LENGTH||validateCron(input.cron)!==null){throw new ExistingSessionScheduledTaskCreateError(400,"invalid_cron","The scheduled-task cron expression is invalid")}const prompt=input.prompt.trim();if(prompt.length===0||prompt.length>MAX_PROMPT_LENGTH){throw new ExistingSessionScheduledTaskCreateError(400,"invalid_prompt","The scheduled-task prompt is invalid")}const gate=input.gate?.trim();if(gate!==void 0){const gateError=gateCommandError(gate);if(gateError){throw new ExistingSessionScheduledTaskCreateError(400,"invalid_gate",`The scheduled-task gate ${gateError}`)}if(!input.recurring){throw new ExistingSessionScheduledTaskCreateError(400,"gate_requires_recurring",GATE_REQUIRES_RECURRING_MESSAGE)}}const allowActivePrompt=options.source==="cron-tool";const assertCallerPromptActive=options.source==="cron-tool"?options.assertCallerPromptActive:void 0;assertReusableScheduledTaskSession(target,input.sessionId,allowActivePrompt,assertCallerPromptActive);target.assertGenerationOpen?.();if(options.source==="rest"){const ensurePersisted=target.bridge?.ensureDefaultSessionPersisted;if(!ensurePersisted){throw new ExistingSessionScheduledTaskCreateError(409,"session_binding_unavailable","Session persistence is not available for this workspace")}try{await ensurePersisted.call(target.bridge,input.sessionId)}catch(error){target.assertGenerationOpen?.();if(error instanceof SessionNotFoundError){throw new ExistingSessionScheduledTaskCreateError(404,"session_not_found",`Session '${input.sessionId}' was not found`)}writeStderrLine(`qwen serve: failed to persist scheduled-task session '${input.sessionId}': ${error instanceof Error?error.message:String(error)}`);throw new ExistingSessionScheduledTaskCreateError(500,"session_persistence_failed","Failed to persist the requested session")}target.assertGenerationOpen?.()}const now=Date.now();const task=withTaskGate({id:generateCronTaskId(),cron:input.cron,prompt,recurring:input.recurring,createdAt:now,lastFiredAt:now-now%6e4,enabled:input.enabled!==false,sessionId:input.sessionId,sessionOwnedByTask:false,sessionMode:input.sessionMode==="per_run"?"per_run":"persistent",...input.sessionMode==="per_run"&&input.modelServiceId!==void 0?{modelServiceId:input.modelServiceId}:{},...input.sessionMode==="per_run"&&input.groupId!==void 0?{groupId:input.groupId}:{},...input.delivery!==void 0?{delivery:input.delivery}:{},...input.name!==void 0?{name:input.name}:{}},gate);let before;let after;await runWithScheduledTaskTarget(target,()=>updateCronTasks(target.workspaceCwd,tasks=>{assertReusableScheduledTaskSession(target,input.sessionId,allowActivePrompt,assertCallerPromptActive);if(tasks.some(candidate=>candidate.sessionId===input.sessionId)){throw new ExistingSessionScheduledTaskCreateError(409,"session_already_bound","The requested session is already bound to another scheduled task")}if(tasks.length>=MAX_SCHEDULED_TASKS){throw new ExistingSessionScheduledTaskCreateError(409,"max_tasks_reached",`Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`)}before=tasks;after=[...tasks,task];return after},{assertCanCommit:target.assertGenerationOpen}));try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,before,after,"scheduled-task create");throw error}return task}__name(createScheduledTaskWithExistingSession,"createScheduledTaskWithExistingSession");function requireOpenGeneration(target,res){try{target.assertGenerationOpen?.();return true}catch(error){if(sendGenerationClosedError(res,error))return false;throw error}}__name(requireOpenGeneration,"requireOpenGeneration");async function rollbackCronMutation(target,before,after,route){if(!before||!after)return;await runWithScheduledTaskTarget(target,()=>updateCronTasks(target.workspaceCwd,tasks=>isDeepStrictEqual(tasks,after)?before:tasks)).catch(error=>{writeStderrLine(`qwen serve: ${route} failed to roll back a stale task mutation: ${error instanceof Error?error.message:String(error)}`)})}__name(rollbackCronMutation,"rollbackCronMutation");async function restoreConsumedOneShot(target,before,failedTask,removalGenerations,route){const id=failedTask.id;const index=before?.findIndex(t=>t.id===id)??-1;const original=index===-1?void 0:before[index];if(!original||!removalGenerations)return;let restoreGenerations;await runWithScheduledTaskTarget(target,()=>updateCronTasks(target.workspaceCwd,tasks=>{if([...removalGenerations].some(([key,generation])=>restoreGenerations?.get(key)!==generation))return tasks;if(tasks.some(t=>t.id===id))return tasks;const restored=[...tasks];restored.splice(Math.min(index,restored.length),0,{...failedTask,enabled:false});return restored},{observeDeletionIds:[...removalGenerations.keys()],onDeletionGenerations:__name(generations=>{restoreGenerations=generations},"onDeletionGenerations")})).catch(error=>{writeStderrLine(`qwen serve: ${route} failed to restore the consumed one-shot task: ${error instanceof Error?error.message:String(error)}`)})}__name(restoreConsumedOneShot,"restoreConsumedOneShot");async function teardownBoundSession(target,sessionId){if(target.cleanupSession){await target.cleanupSession(sessionId).catch(()=>{})}else if(target.bridge){await target.bridge.closeSession(sessionId).catch(()=>{});const removed=await new SessionService(target.workspaceCwd,{runtimeBaseDir:target.runtimeBaseDir}).removeSession(sessionId).catch(()=>false);if(removed)target.bridge.markSessionCatalogChanged?.()}}__name(teardownBoundSession,"teardownBoundSession");async function dispatchTaskToFreshSession(target,task){const{bridge}=target;const sendPrompt=bridge?.sendPrompt?.bind(bridge);if(!bridge||!sendPrompt||!task.sessionId){throw new Error("Fresh-session dispatch is unavailable for this task")}const triggeredAt=task.lastFiredAt??Date.now();const child=await runWithScheduledTaskTarget(target,()=>bridge.spawnOrAttach({workspaceCwd:target.workspaceCwd,...task.modelServiceId?{modelServiceId:task.modelServiceId}:{},sessionScope:"thread",parentSessionId:task.sessionId,sourceType:SCHEDULED_TASK_RUN_SOURCE_TYPE,sourceId:scheduledTaskRunSourceId(task.id)}));try{if(task.modelServiceId&&child.modelApplied===false){throw new Error(`Scheduled task model selection failed: ${task.modelServiceId}`)}try{bridge.updateSessionMetadata(child.sessionId,{displayName:scheduledTaskRunSessionName(task.name??task.prompt,triggeredAt),titleSource:"auto"})}catch{}let markPromptAdmitted;const promptAdmitted=new Promise(resolve=>{markPromptAdmitted=resolve});const turn=sendPrompt(child.sessionId,{sessionId:child.sessionId,prompt:[{type:"text",text:buildScheduledTaskRunPrompt({id:task.id,name:task.name,cron:task.cron,prompt:task.prompt,triggeredAt,trigger:"manual",...task.gate?{gate:task.gate}:{}})}]},void 0,{onPromptAdmitted:markPromptAdmitted});void turn.catch(error=>{writeStderrLine(`qwen serve: scheduled-task session ${child.sessionId} prompt failed: ${error instanceof Error?error.message:String(error)}`)});await Promise.race([promptAdmitted,turn.then(()=>void 0,error=>Promise.reject(error))]);if(task.groupId){try{await runWithScheduledTaskTarget(target,()=>createSessionOrganizationService(target.workspaceCwd).updateSessionOrganization(child.sessionId,{groupId:task.groupId,color:null}));bridge.markSessionCatalogChanged?.()}catch(error){writeStderrLine(`qwen serve: scheduled-task session ${child.sessionId} could not be assigned to group ${task.groupId}: ${error instanceof Error?error.message:String(error)}`)}}}catch(error){await teardownBoundSession(target,child.sessionId);throw error}return child.sessionId}__name(dispatchTaskToFreshSession,"dispatchTaskToFreshSession");async function runWithScheduledTaskTarget(target,fn){const result=target.runtimeBaseDir===void 0?fn():Storage.runWithResolvedRuntimeBaseDir(target.runtimeBaseDir,fn);return await result}__name(runWithScheduledTaskTarget,"runWithScheduledTaskTarget");function sendActivityGateError(res,error){if(!error||typeof error!=="object"||error.code!=="daemon_draining"){return false}res.status(503).json({error:"The daemon is draining and no longer accepts work.",code:"daemon_draining"});return true}__name(sendActivityGateError,"sendActivityGateError");var GATE_REQUIRES_RECURRING_MESSAGE="A gate needs a recurring task: a one-shot whose gate prints nothing would be consumed with nothing delivered";function computeNextRunAt(task){if(task.enabled===false)return null;return nextDurableFireMs(task)}__name(computeNextRunAt,"computeNextRunAt");function toView(task){return{id:task.id,name:typeof task.name==="string"&&task.name.length>0?task.name:null,cron:task.cron,prompt:task.prompt,recurring:task.recurring,enabled:task.enabled!==false&&!taskHasLegacyCondition(task),createdAt:task.createdAt,lastFiredAt:task.lastFiredAt,nextRunAt:taskHasLegacyCondition(task)?null:computeNextRunAt(task),sessionId:typeof task.sessionId==="string"&&task.sessionId.length>0?task.sessionId:null,sessionMode:task.sessionMode==="per_run"?"per_run":"persistent",modelServiceId:task.modelServiceId??null,groupId:task.groupId??null,runs:Array.isArray(task.runs)?task.runs:[],...task.delivery!==void 0?{delivery:task.delivery}:{},gate:typeof task.gate==="string"&&task.gate.length>0?task.gate:null,gateStatus:task.gateStatus??null}}__name(toView,"toView");function validateCron(cron){try{parseCron(cron);nextFireTime(cron,new Date);return null}catch(err){return err instanceof Error?err.message:String(err)}}__name(validateCron,"validateCron");function canonicalCron(cron){try{const f=parseCron(cron);const s=__name(set=>[...set].sort((a,b)=>a-b).join(","),"s");return[s(f.minute),s(f.hour),s(f.dayOfMonth),s(f.month),s(f.dayOfWeek),f.domIsWild?"W":"",f.dowIsWild?"W":""].join("|")}catch{return null}}__name(canonicalCron,"canonicalCron");function registerScheduledTaskCrudRoutes(app,deps){const{prefix,resolveTarget,mutate,safeBody,channelDeliveryAuthorizations}=deps;const base=`${prefix}/scheduled-tasks`;const withTarget=__name(handler=>async(req,res)=>{const target=resolveTarget(req,res);if(!target)return;const operation=__name(async()=>{if(!requireOpenGeneration(target,res))return;await handler(req,res,target)},"operation");try{if(target.activity){await target.activity.run(operation)}else{await operation()}}catch(error){if(sendActivityGateError(res,error))return;throw error}},"withTarget");app.get(base,withTarget(async(_req,res,target)=>{try{const tasks=await runWithScheduledTaskTarget(target,()=>readCronTasks(target.workspaceCwd));if(!requireOpenGeneration(target,res))return;res.status(200).json({v:1,tasks:tasks.map(toView)})}catch(err){if(sendActivityGateError(res,err))return;writeStderrLine(`qwen serve: GET ${base} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to read scheduled tasks (the tasks file may be corrupt)",code:"scheduled_tasks_read_failed"})}}));app.post(base,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd,bridge}=target;const body=safeBody(req);const cron=typeof body["cron"]==="string"?body["cron"].trim():"";if(cron.length===0){res.status(400).json({error:"`cron` is required and must be a non-empty string",code:"invalid_cron"});return}if(cron.length>MAX_CRON_LENGTH){res.status(400).json({error:`\`cron\` exceeds ${MAX_CRON_LENGTH}-character limit`,code:"invalid_cron"});return}const cronError=validateCron(cron);if(cronError){res.status(400).json({error:cronError,code:"invalid_cron"});return}const prompt=typeof body["prompt"]==="string"?body["prompt"].trim():"";if(prompt.length===0){res.status(400).json({error:"`prompt` is required and must be a non-empty string",code:"invalid_prompt"});return}if(prompt.length>MAX_PROMPT_LENGTH){res.status(400).json({error:`\`prompt\` exceeds ${MAX_PROMPT_LENGTH}-character limit`,code:"invalid_prompt"});return}const nameResult=parseNameField(body["name"]);if(nameResult.error){res.status(400).json({error:nameResult.error,code:"invalid_name"});return}if(body["recurring"]!==void 0&&typeof body["recurring"]!=="boolean"){res.status(400).json({error:"`recurring` must be a boolean",code:"invalid_recurring"});return}if(body["enabled"]!==void 0&&typeof body["enabled"]!=="boolean"){res.status(400).json({error:"`enabled` must be a boolean",code:"invalid_enabled"});return}const sessionMode=body["sessionMode"]===void 0?"persistent":body["sessionMode"];if(sessionMode!=="persistent"&&sessionMode!=="per_run"){res.status(400).json({error:'`sessionMode` must be "persistent" or "per_run"',code:"invalid_session_mode"});return}const modelServiceId=body["modelServiceId"];if(modelServiceId!==void 0&&!isValidCronTaskRoutingId(modelServiceId)){res.status(400).json({error:`\`modelServiceId\` must be a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_model_service_id"});return}const groupId=body["groupId"];if(groupId!==void 0&&!isValidCronTaskRoutingId(groupId)){res.status(400).json({error:`\`groupId\` must be a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_group_id"});return}if(sessionMode!=="per_run"&&(modelServiceId!==void 0||groupId!==void 0)){res.status(400).json({error:'`modelServiceId` and `groupId` are only supported when `sessionMode` is "per_run"',code:"session_routing_requires_per_run"});return}if(typeof groupId==="string"){const groups=await runWithScheduledTaskTarget(target,()=>createSessionOrganizationService(workspaceCwd).listGroups());if(!groups.groups.some(group=>group.id===groupId)){res.status(400).json({error:`Group not found: ${groupId}`,code:"group_not_found"});return}}const parsedSessionId=parseCallerSuppliedSessionId(body["sessionId"]);if(parsedSessionId.kind==="invalid"){res.status(400).json({error:'`sessionId` must be an RFC UUID v1-v5 (e.g. "550e8400-e29b-41d4-a716-446655440000")',code:"invalid_session_id"});return}const providedSessionId=parsedSessionId.kind==="valid"?parsedSessionId.sessionId:void 0;let delivery;if(body["delivery"]!==void 0){try{delivery=parseChannelDelivery(body["delivery"])}catch(err){if(!isChannelDeliveryError(err))throw err;res.status(400).json({error:err.message,code:err.code});return}}if(sessionMode==="per_run"&&delivery!==void 0){res.status(400).json({error:"Per-run sessions do not support channel delivery",code:"session_mode_delivery_unsupported"});return}const removedField=findRemovedTaskField(body);if(removedField){res.status(400).json(removedFieldError(removedField));return}const recurring=body["recurring"]!==false;const enabled=body["enabled"]!==false;let gate;if(body["gate"]!==void 0&&body["gate"]!==null){const gateError=gateCommandError(body["gate"]);if(gateError){res.status(400).json({error:`\`gate\` ${gateError}`,code:"invalid_gate"});return}gate=body["gate"].trim();if(!recurring){res.status(400).json({error:GATE_REQUIRES_RECURRING_MESSAGE,code:"gate_requires_recurring"});return}}const taskId=generateCronTaskId();if(sessionMode==="per_run"&&(!bridge||!bridge.sendPrompt)){res.status(409).json({error:"Fresh-session dispatch is not available for this workspace",code:"session_mode_unavailable"});return}if(providedSessionId!==void 0){try{const task2=await createScheduledTaskWithExistingSession(target,{sessionId:providedSessionId,cron,prompt,recurring,enabled,sessionMode,...typeof modelServiceId==="string"?{modelServiceId}:{},...typeof groupId==="string"?{groupId}:{},...delivery!==void 0?{delivery}:{},...nameResult.value!==void 0?{name:nameResult.value}:{},...gate!==void 0?{gate}:{}},{source:"rest"});if(task2.delivery&&task2.sessionId){channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd,{sessionId:task2.sessionId,taskId:task2.id,target:task2.delivery.target,recurring:task2.recurring,lastFiredAt:task2.lastFiredAt??void 0})}res.status(201).json(toView(task2))}catch(error){if(error instanceof ExistingSessionScheduledTaskCreateError){if(error.code==="workspace_runtime_unavailable"){res.set("Retry-After","1")}res.status(error.status).json({error:error.message,code:error.code});return}if(sendActivityGateError(res,error))return;if(sendGenerationClosedError(res,error))return;writeStderrLine(`qwen serve: POST ${base} failed to create a task for session '${providedSessionId}': ${error instanceof Error?error.message:String(error)}`);res.status(500).json({error:"Failed to create scheduled task",code:"scheduled_tasks_write_failed"})}return}let boundSessionId;let sessionMintedHere=false;if(bridge){try{const tasks=await runWithScheduledTaskTarget(target,()=>readCronTasks(workspaceCwd));if(tasks.length>=MAX_SCHEDULED_TASKS){res.status(409).json({error:`Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,code:"max_tasks_reached"});return}}catch{}if(!requireOpenGeneration(target,res))return;try{const session=await runWithScheduledTaskTarget(target,()=>bridge.spawnOrAttach({workspaceCwd,sessionScope:"thread",sourceType:"scheduled_task",sourceId:taskId}));boundSessionId=session.sessionId;sessionMintedHere=true;if(!requireOpenGeneration(target,res)){await teardownBoundSession(target,boundSessionId);return}try{await runWithScheduledTaskTarget(target,async()=>bridge.updateSessionMetadata(boundSessionId,{displayName:scheduledTaskSessionName(nameResult.value??prompt),titleSource:"auto"}))}catch{}}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST ${base} failed to create the task's session: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to create the task's session",code:"scheduled_tasks_session_failed"});return}}const now=Date.now();const task=withTaskGate({id:taskId,cron,prompt,recurring,createdAt:now,lastFiredAt:now-now%6e4,enabled,sessionMode,...typeof modelServiceId==="string"?{modelServiceId}:{},...typeof groupId==="string"?{groupId}:{},...delivery!==void 0?{delivery}:{},...boundSessionId!==void 0?{sessionId:boundSessionId}:{},...nameResult.value!==void 0?{name:nameResult.value}:{}},gate);const rollbackSession=__name(async()=>{if(boundSessionId!==void 0&&sessionMintedHere){await teardownBoundSession(target,boundSessionId)}},"rollbackSession");let overCap=false;let rollbackBefore;let rollbackAfter;try{await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>{if(tasks.length>=MAX_SCHEDULED_TASKS){overCap=true;return tasks}rollbackBefore=tasks;rollbackAfter=[...tasks,task];return rollbackAfter},{assertCanCommit:target.assertGenerationOpen}))}catch(err){await rollbackSession();if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST ${base} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to create scheduled task",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`POST ${base}`);await rollbackSession();if(sendGenerationClosedError(res,error))return;throw error}}if(overCap){await rollbackSession();res.status(409).json({error:`Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,code:"max_tasks_reached"});return}if(task.delivery&&task.sessionId){channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd,{sessionId:task.sessionId,taskId:task.id,target:task.delivery.target,recurring:task.recurring,lastFiredAt:task.lastFiredAt??void 0})}res.status(201).json(toView(task))}));app.patch(`${base}/:id`,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd,bridge}=target;const id=typeof req.params["id"]==="string"?req.params["id"]:"";if(id.length===0){res.status(400).json({error:"Task id is required",code:"invalid_id"});return}const body=safeBody(req);const patch={};let clearName=false;let clearDelivery=false;let clearModelServiceId=false;let clearGroupId=false;let clearGate=false;let missingGroupId;const removedPatchField=findRemovedTaskField(body);if(removedPatchField){res.status(400).json(removedFieldError(removedPatchField));return}if("cron"in body){const cron=typeof body["cron"]==="string"?body["cron"].trim():"";if(cron.length===0||cron.length>MAX_CRON_LENGTH){res.status(400).json({error:"`cron` must be a non-empty string within the length limit",code:"invalid_cron"});return}const cronError=validateCron(cron);if(cronError){res.status(400).json({error:cronError,code:"invalid_cron"});return}patch.cron=cron}if("prompt"in body){const prompt=typeof body["prompt"]==="string"?body["prompt"].trim():"";if(prompt.length===0||prompt.length>MAX_PROMPT_LENGTH){res.status(400).json({error:"`prompt` must be a non-empty string within the length limit",code:"invalid_prompt"});return}patch.prompt=prompt}if("name"in body){const nameResult=parseNameField(body["name"]);if(nameResult.error){res.status(400).json({error:nameResult.error,code:"invalid_name"});return}if(nameResult.value===void 0){clearName=true}else{patch.name=nameResult.value}}if("recurring"in body){if(typeof body["recurring"]!=="boolean"){res.status(400).json({error:"`recurring` must be a boolean",code:"invalid_recurring"});return}patch.recurring=body["recurring"]}if("enabled"in body){if(typeof body["enabled"]!=="boolean"){res.status(400).json({error:"`enabled` must be a boolean",code:"invalid_enabled"});return}patch.enabled=body["enabled"]}if("sessionMode"in body){if(body["sessionMode"]!=="persistent"&&body["sessionMode"]!=="per_run"){res.status(400).json({error:'`sessionMode` must be "persistent" or "per_run"',code:"invalid_session_mode"});return}patch.sessionMode=body["sessionMode"]}if("modelServiceId"in body){const value=body["modelServiceId"];if(value===null||value===""){clearModelServiceId=true}else if(!isValidCronTaskRoutingId(value)){res.status(400).json({error:`\`modelServiceId\` must be null or a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_model_service_id"});return}else{patch.modelServiceId=value}}if("groupId"in body){const value=body["groupId"];if(value===null||value===""){clearGroupId=true}else if(!isValidCronTaskRoutingId(value)){res.status(400).json({error:`\`groupId\` must be null or a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_group_id"});return}else{const groups=await runWithScheduledTaskTarget(target,()=>createSessionOrganizationService(workspaceCwd).listGroups());if(!groups.groups.some(group=>group.id===value)){missingGroupId=value}patch.groupId=value}}if("delivery"in body){if(body["delivery"]===null){clearDelivery=true}else{try{patch.delivery=parseChannelDelivery(body["delivery"])}catch(err){if(!isChannelDeliveryError(err))throw err;res.status(400).json({error:err.message,code:err.code});return}}}if("gate"in body){if(body["gate"]===null||body["gate"]===""){clearGate=true}else{const gateError=gateCommandError(body["gate"]);if(gateError){res.status(400).json({error:`\`gate\` must be null or a shell command; it ${gateError}`,code:"invalid_gate"});return}patch.gate=body["gate"].trim()}}if(Object.keys(patch).length===0&&!clearName&&!clearDelivery&&!clearModelServiceId&&!clearGroupId&&!clearGate){res.status(400).json({error:"No updatable fields provided",code:"empty_patch"});return}let found=false;let updated;let blockedByArchive=false;let blockedLegacy=false;let blockedGateOneShot=false;let blockedSessionModeDelivery=false;let blockedSessionModeUnavailable=false;let blockedSessionModeUnbound=false;let blockedGroupNotFound=false;let rollbackBefore;let rollbackAfter;try{await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>{const idx=tasks.findIndex(t=>t.id===id);if(idx===-1)return tasks;found=true;const current=tasks[idx];if(missingGroupId!==void 0&¤t.groupId!==missingGroupId){blockedGroupNotFound=true;return tasks}const convertingToPerRun=patch.sessionMode==="per_run"&¤t.sessionMode!=="per_run";if(convertingToPerRun&&(!bridge||!bridge.sendPrompt)){blockedSessionModeUnavailable=true;return tasks}if(convertingToPerRun&&!current.sessionId){blockedSessionModeUnbound=true;return tasks}if(patch.enabled===true&&taskHasLegacyCondition(current)){blockedLegacy=true;return tasks}if((patch.gate!==void 0||clearGate)&&taskHasLegacyCondition(current)){blockedLegacy=true;return tasks}if(patch.enabled===true&¤t.disabledByArchive===true){blockedByArchive=true;return tasks}let next={...current,...patch};if(clearName)delete next.name;if(clearDelivery)delete next.delivery;if(clearModelServiceId)delete next.modelServiceId;if(clearGroupId)delete next.groupId;if(next.sessionMode!=="per_run"){delete next.modelServiceId;delete next.groupId}if(next.sessionMode==="per_run"&&next.delivery){blockedSessionModeDelivery=true;return tasks}if(clearGate||patch.gate!==void 0){next=withTaskGate(next,clearGate?void 0:patch.gate);if(clearGate||patch.gate!==current.gate){delete next.gateStatus}}if(next.gate!==void 0&&!next.recurring&&(patch.gate!==void 0&&patch.gate!==current.gate||patch.recurring===false&¤t.recurring!==false)){blockedGateOneShot=true;return tasks}const justReEnabled=current.enabled===false&&patch.enabled===true;const cronChanged=patch.cron!==void 0&&canonicalCron(patch.cron)!==canonicalCron(current.cron);const becameRecurring=patch.recurring===true&¤t.recurring!==true;const becameOneShot=patch.recurring===false&¤t.recurring!==false;const retryFailedOneShot=!next.recurring&&justReEnabled&&!cronChanged&&!becameOneShot&¤t.runs?.at(-1)?.sessionDispatchFailed===true;{const now=Date.now();const minute=now-now%6e4;if(next.recurring&&(justReEnabled||cronChanged||becameRecurring)){next.lastFiredAt=minute}else if(!next.recurring&&!retryFailedOneShot&&(justReEnabled||cronChanged||becameOneShot)){next.createdAt=now;next.lastFiredAt=minute}}updated=next;rollbackBefore=tasks;rollbackAfter=tasks.map((t,i)=>i===idx?next:t);return rollbackAfter},{assertCanCommit:target.assertGenerationOpen}))}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: PATCH ${base}/${id} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to update scheduled task",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`PATCH ${base}/${id}`);if(sendGenerationClosedError(res,error))return;throw error}}if(!found){res.status(404).json({error:"Task not found",code:"task_not_found"});return}if(missingGroupId!==void 0&&blockedGroupNotFound){res.status(400).json({error:`Group not found: ${missingGroupId}`,code:"group_not_found"});return}if(blockedLegacy){res.status(409).json({error:"This task uses the removed isolated run mode with a precondition and can no longer be enabled or run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",code:"task_legacy_unsupported"});return}if(blockedByArchive){res.status(409).json({error:"This task was disabled by archiving its session; unarchive the session to re-enable it.",code:"task_session_archived"});return}if(blockedSessionModeUnavailable){res.status(409).json({error:"Fresh-session dispatch is not available for this workspace",code:"session_mode_unavailable"});return}if(blockedSessionModeUnbound){res.status(409).json({error:"This task is not bound to a session yet, so it cannot run in a new session every run. Try again once it has run or been opened at least once.",code:"session_mode_requires_bound_session"});return}if(blockedSessionModeDelivery){res.status(409).json({error:"Per-run sessions do not support channel delivery",code:"session_mode_delivery_unsupported"});return}if(blockedGateOneShot){res.status(400).json({error:GATE_REQUIRES_RECURRING_MESSAGE,code:"gate_requires_recurring"});return}if(!updated){res.status(404).json({error:"Task not found",code:"task_not_found"});return}const effectiveLabelChanged=patch.name!==void 0||clearName||patch.prompt!==void 0&&updated.name===void 0;if(bridge&&updated.sessionId&&updated.sessionOwnedByTask!==false&&effectiveLabelChanged){try{bridge.updateSessionMetadata(updated.sessionId,{displayName:scheduledTaskSessionName(updated.name??updated.prompt),titleSource:"auto"})}catch{}}if(updated.delivery&&updated.sessionId){channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd,{sessionId:updated.sessionId,taskId:updated.id,target:updated.delivery.target,recurring:updated.recurring,lastFiredAt:updated.lastFiredAt??void 0})}if(clearDelivery&&updated.sessionId){channelDeliveryAuthorizations?.revokeScheduledTask(workspaceCwd,updated.sessionId,updated.id)}res.status(200).json(toView(updated))}));app.delete(`${base}/:id`,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd,bridge}=target;const id=typeof req.params["id"]==="string"?req.params["id"]:"";if(id.length===0){res.status(400).json({error:"Task id is required",code:"invalid_id"});return}let boundSessionId;let sessionOwnedByTask=true;let removed=false;let rollbackBefore;let rollbackAfter;try{await runWithScheduledTaskTarget(target,async()=>{try{await access(getCronFilePath(workspaceCwd))}catch(error){if(error.code==="ENOENT")return;throw error}await updateCronTasks(workspaceCwd,tasks=>{const idx=tasks.findIndex(t=>t.id===id);if(idx===-1)return tasks;const match=tasks[idx].sessionId;if(typeof match==="string"&&match.length>0){boundSessionId=match;sessionOwnedByTask=tasks[idx].sessionOwnedByTask!==false}removed=true;rollbackBefore=tasks;rollbackAfter=tasks.filter((_,i)=>i!==idx);return rollbackAfter},{assertCanCommit:target.assertGenerationOpen,deletionIds:[id]})})}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: DELETE ${base}/${id} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to delete scheduled task",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`DELETE ${base}/${id}`);if(sendGenerationClosedError(res,error))return;throw error}}if(!removed){res.status(404).json({error:"Task not found",code:"task_not_found"});return}if(boundSessionId&&sessionOwnedByTask&&bridge){try{await runWithScheduledTaskTarget(target,()=>bridge.closeSession(boundSessionId,void 0,{closeIfUnheld:true,reason:"scheduled_task_deleted"}))}catch(error){if(sendActivityGateError(res,error))return}}if(boundSessionId){channelDeliveryAuthorizations?.revokeScheduledTask(workspaceCwd,boundSessionId,id)}res.status(200).json({deleted:true,id})}));app.post(`${base}/:id/run`,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd}=target;const id=typeof req.params["id"]==="string"?req.params["id"]:"";if(id.length===0){res.status(400).json({error:"Task id is required",code:"invalid_id"});return}const now=Date.now();let found=false;let blockedDisabled=false;let blockedLegacy=false;let updated;let rollbackBefore;let rollbackAfter;let removalGenerations;try{await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>{const idx=tasks.findIndex(t=>t.id===id);if(idx===-1)return tasks;found=true;const current=tasks[idx];if(taskHasLegacyCondition(current)){blockedLegacy=true;return tasks}if(current.enabled===false){blockedDisabled=true;return tasks}const next={...current,lastFiredAt:now,runs:appendCronRun(current.runs,{at:now,kind:"manual",...current.sessionMode!=="per_run"&¤t.sessionId?{sessionId:current.sessionId}:{}})};updated=next;rollbackBefore=tasks;const nextTasks=!current.recurring?tasks.filter((_,i)=>i!==idx):tasks.map((t,i)=>i===idx?next:t);rollbackAfter=nextTasks;return nextTasks},{assertCanCommit:target.assertGenerationOpen,observeDeletionIds:__name(tasks=>{const task=tasks.find(task2=>task2.id===id);return task?.sessionId?[id,cronTaskSessionDeletionId(task.sessionId)]:[id]},"observeDeletionIds"),onDeletionGenerations:__name(generations=>{removalGenerations=generations},"onDeletionGenerations")}))}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST ${base}/${id}/run failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to record scheduled task run",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`POST ${base}/${id}/run`);if(sendGenerationClosedError(res,error))return;throw error}}if(blockedLegacy){res.status(409).json({error:"This task uses the removed isolated run mode with a precondition and can no longer run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",code:"task_legacy_unsupported"});return}if(blockedDisabled){res.status(409).json({error:"Cannot run a disabled task; enable it first (unarchive its session if it was archived).",code:"task_disabled"});return}if(!found||!updated){res.status(404).json({error:"Task not found",code:"task_not_found"});return}if(updated.sessionMode==="per_run"){const persistOutcome=__name(async outcome=>{if(!updated.recurring)return;await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>tasks.map(task=>task.id===id?annotateCronRunSession(task,now,outcome):task),{assertCanCommit:target.assertGenerationOpen}))},"persistOutcome");let childSessionId;try{childSessionId=await dispatchTaskToFreshSession(target,updated)}catch(error){updated=annotateCronRunSession(updated,now,{dispatchFailed:true});if(updated.recurring){await persistOutcome({dispatchFailed:true}).catch(persistError=>{writeStderrLine(`qwen serve: POST ${base}/${id}/run could not record the failed dispatch: ${persistError instanceof Error?persistError.message:String(persistError)}`)})}else{await restoreConsumedOneShot(target,rollbackBefore,updated,removalGenerations,`POST ${base}/${id}/run fresh-session dispatch`)}writeStderrLine(`qwen serve: POST ${base}/${id}/run could not create a fresh session: ${error instanceof Error?error.message:String(error)}`);res.status(500).json({error:"Failed to create a fresh session for the scheduled task",code:"scheduled_task_session_dispatch_failed"});return}updated=annotateCronRunSession(updated,now,{sessionId:childSessionId});await persistOutcome({sessionId:childSessionId}).catch(error=>{writeStderrLine(`qwen serve: POST ${base}/${id}/run could not attribute fresh session ${childSessionId}: ${error instanceof Error?error.message:String(error)}`)})}if(!updated.recurring&&updated.sessionId){channelDeliveryAuthorizations?.revokeScheduledTask(workspaceCwd,updated.sessionId,updated.id)}const view=toView(updated);if(!updated.recurring)view.nextRunAt=null;res.status(200).json(view)}))}__name(registerScheduledTaskCrudRoutes,"registerScheduledTaskCrudRoutes");function registerScheduledTasksRoutes(app,deps){const{boundWorkspace,mutate,safeBody,bridge,channelDeliveryAuthorizations}=deps;registerScheduledTaskCrudRoutes(app,{prefix:"",resolveTarget:__name((_req,res)=>{const runtime=deps.getRuntime?.();if(deps.getRuntime&&!runtime){res.set("Retry-After","1");res.status(503).json({error:"Workspace runtime is not active",code:"workspace_runtime_unavailable"});return null}if(runtime&&!requireTrustedWorkspaceRuntime(runtime,res))return null;return{workspaceCwd:boundWorkspace,...runtime?{runtimeBaseDir:runtime.sessionRuntimeBaseDir,...deps.cleanupSession?{cleanupSession:__name(sessionId=>deps.cleanupSession(runtime,sessionId),"cleanupSession")}:{}}:{},bridge:bridge===void 0?void 0:runtime?.bridge??bridge,...runtime?.generationGuard?{assertGenerationOpen:__name(()=>runtime.generationGuard?.assertOpen(),"assertGenerationOpen")}:{},...deps.workspaceRegistry?{resolveLiveSessionOwner:__name(sessionId=>deps.workspaceRegistry.resolveLiveSessionOwner(sessionId),"resolveLiveSessionOwner")}:{}}},"resolveTarget"),mutate,safeBody,channelDeliveryAuthorizations})}__name(registerScheduledTasksRoutes,"registerScheduledTasksRoutes");function registerWorkspaceQualifiedScheduledTasksRoutes(app,deps){const{workspaceRegistry,mutate,safeBody,manageScheduledTaskSessions,channelDeliveryAuthorizations,cleanupSession}=deps;registerScheduledTaskCrudRoutes(app,{prefix:"/workspaces/:workspace",resolveTarget:__name((req,res)=>{const runtime=resolveWorkspaceRuntimeWithLiveCompatibilityFromParam(workspaceRegistry,req,res);if(!runtime)return null;if(!requireTrustedWorkspaceRuntime(runtime,res))return null;if(runtime.provenance==="live-conversation"&&!deps.conversationRuntimeActivity){sendConversationRuntimeUnavailable(res);return null}if(runtime.provenance==="live-conversation"&&req.method==="POST"&&req.params["id"]===void 0&&parseCallerSuppliedSessionId(safeBody(req)["sessionId"]).kind==="absent"){res.status(400).json({error:"Generic scheduled tasks cannot create sessions in the Conversations workspace.",code:"live_session_creation_reserved"});return null}return{workspaceCwd:runtime.workspaceCwd,runtimeBaseDir:runtime.sessionRuntimeBaseDir,...runtime.provenance==="live-conversation"&&deps.conversationRuntimeActivity?{activity:deps.conversationRuntimeActivity}:{},...cleanupSession?{cleanupSession:__name(sessionId=>cleanupSession(runtime,sessionId),"cleanupSession")}:{},bridge:manageScheduledTaskSessions?runtime.bridge:void 0,...runtime.generationGuard?{assertGenerationOpen:__name(()=>runtime.generationGuard?.assertOpen(),"assertGenerationOpen")}:{},resolveLiveSessionOwner:__name(sessionId=>workspaceRegistry.resolveLiveSessionOwner(sessionId),"resolveLiveSessionOwner")}},"resolveTarget"),mutate,safeBody,channelDeliveryAuthorizations})}__name(registerWorkspaceQualifiedScheduledTasksRoutes,"registerWorkspaceQualifiedScheduledTasksRoutes");var REMOVED_TASK_FIELDS=["runMode","condition"];function findRemovedTaskField(body){return REMOVED_TASK_FIELDS.find(field=>field in body)}__name(findRemovedTaskField,"findRemovedTaskField");function removedFieldError(field){return{error:`\`${field}\` is no longer supported: the isolated scheduled-task run mode was removed. Every task now runs in its bound session; call the \`create_sub_session\` tool from the task prompt for per-run isolation.`,code:"unsupported_field"}}__name(removedFieldError,"removedFieldError");function parseNameField(raw){if(raw===void 0||raw===null)return{value:void 0};if(typeof raw!=="string"){return{error:"`name` must be a string"}}const trimmed=raw.trim();if(trimmed.length===0)return{value:void 0};if(trimmed.length>MAX_NAME_LENGTH){return{error:`\`name\` exceeds ${MAX_NAME_LENGTH}-character limit`}}return{value:trimmed}}__name(parseNameField,"parseNameField");export{scheduledTaskSessionName,ExistingSessionScheduledTaskCreateError,createScheduledTaskWithExistingSession,registerScheduledTasksRoutes,registerWorkspaceQualifiedScheduledTasksRoutes};
|
|
3
|
+
import{buildScheduledTaskRunPrompt,parseChannelDelivery,scheduledTaskRunSessionName,scheduledTaskRunSourceId}from"./chunk-NA2WJPOU.js";import{createSessionOrganizationService}from"./chunk-W3YXE55M.js";import{requireTrustedWorkspaceRuntime,resolveWorkspaceRuntimeWithLiveCompatibilityFromParam,sendConversationRuntimeUnavailable,sendGenerationClosedError}from"./chunk-PXWHOFAA.js";import{parseCallerSuppliedSessionId}from"./chunk-LGFF5PJA.js";import{SCHEDULED_TASK_RUN_SOURCE_TYPE}from"./chunk-236DHGNH.js";import{SessionNotFoundError}from"./chunk-VTZZXEWA.js";import{isChannelDeliveryError}from"./chunk-O6ZQAVRG.js";import{MAX_JOBS,SessionService,gateCommandError,nextDurableFireMs,nextFireTime,parseCron}from"./chunk-7XQ5D34E.js";import{stripTerminalControlSequences}from"./chunk-R2EHHA2C.js";import{MAX_CRON_TASK_ROUTING_ID_LENGTH,annotateCronRunSession,appendCronRun,cronTaskSessionDeletionId,generateCronTaskId,getCronFilePath,isValidCronTaskRoutingId,readCronTasks,taskHasLegacyCondition,updateCronTasks,withTaskGate}from"./chunk-T6W33SET.js";import{writeStderrLine}from"./chunk-M4ECEHLX.js";import{Storage}from"./chunk-EPODBRBP.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import{isDeepStrictEqual}from"node:util";import{access}from"node:fs/promises";var MAX_SCHEDULED_TASKS=MAX_JOBS;var MAX_PROMPT_LENGTH=1e5;var MAX_NAME_LENGTH=200;var MAX_CRON_LENGTH=200;var MAX_ROUTING_ID_LENGTH=MAX_CRON_TASK_ROUTING_ID_LENGTH;var MAX_SESSION_NAME_LENGTH=60;function scheduledTaskSessionName(label){const cleaned=stripTerminalControlSequences(label).replace(/[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g,"").trim().replace(/\s+/g," ");let short=cleaned;if(cleaned.length>MAX_SESSION_NAME_LENGTH){let cut=MAX_SESSION_NAME_LENGTH-1;const boundary=cleaned.charCodeAt(cut-1);if(boundary>=55296&&boundary<=56319)cut-=1;short=`${cleaned.slice(0,cut)}\u2026`}return short}__name(scheduledTaskSessionName,"scheduledTaskSessionName");var ExistingSessionScheduledTaskCreateError=class extends Error{constructor(status,code,message){super(message);this.status=status;this.code=code;this.name="ExistingSessionScheduledTaskCreateError"}static{__name(this,"ExistingSessionScheduledTaskCreateError")}};function assertReusableScheduledTaskSession(target,sessionId,allowActivePrompt,assertCallerPromptActive){const{bridge,workspaceCwd}=target;if(!bridge){throw new ExistingSessionScheduledTaskCreateError(409,"session_binding_unavailable","Session management is not available for this workspace")}assertCallerPromptActive?.();let owner;try{owner=target.resolveLiveSessionOwner?.(sessionId)}catch(error){writeStderrLine(`qwen serve: failed to resolve scheduled-task session owner '${sessionId}': ${error instanceof Error?error.message:String(error)}`);throw new ExistingSessionScheduledTaskCreateError(500,"scheduled_tasks_session_failed","Failed to look up the requested session")}if(owner?.kind==="unavailable"){throw new ExistingSessionScheduledTaskCreateError(503,"workspace_runtime_unavailable","The workspace runtime is unavailable")}if(owner?.kind==="ambiguous"){throw new ExistingSessionScheduledTaskCreateError(500,"ambiguous_session_owner",`Session owner is ambiguous for "${sessionId}"`)}if(owner?.kind==="found"&&owner.runtime.workspaceCwd!==workspaceCwd){throw new ExistingSessionScheduledTaskCreateError(400,"session_workspace_mismatch","The requested session belongs to a different workspace; use that workspace's scheduled-task endpoint")}let summary;try{summary=bridge.getSessionSummary(sessionId)}catch(error){if(error instanceof SessionNotFoundError){throw new ExistingSessionScheduledTaskCreateError(404,"session_not_found",`Session '${sessionId}' was not found`)}writeStderrLine(`qwen serve: failed to look up scheduled-task session '${sessionId}': ${error instanceof Error?error.message:String(error)}`);throw new ExistingSessionScheduledTaskCreateError(500,"scheduled_tasks_session_failed","Failed to look up the requested session")}if(summary.workspaceCwd!==workspaceCwd){throw new ExistingSessionScheduledTaskCreateError(400,"session_workspace_mismatch","The requested session belongs to a different workspace; use that workspace's scheduled-task endpoint")}if(!allowActivePrompt&&summary.hasActivePrompt||(summary.pendingInteractionCount??0)>0){throw new ExistingSessionScheduledTaskCreateError(409,"session_busy",allowActivePrompt?"The caller session has a pending interaction; resolve it before binding the session to a task":"The requested session is busy; wait for its active prompt or pending interaction to finish before binding it to a task")}if(summary.sourceType==="scheduled_task"){throw new ExistingSessionScheduledTaskCreateError(409,"session_already_bound","The requested session is already reserved for a scheduled task")}if(summary.parentSessionId!==void 0||summary.sourceId!==void 0||summary.sourceType!==void 0&&summary.sourceType!=="default"){throw new ExistingSessionScheduledTaskCreateError(409,"session_source_ineligible","The requested session source cannot own a scheduled task")}}__name(assertReusableScheduledTaskSession,"assertReusableScheduledTaskSession");async function createScheduledTaskWithExistingSession(target,input,options){if(input.cron.length===0||input.cron.length>MAX_CRON_LENGTH||validateCron(input.cron)!==null){throw new ExistingSessionScheduledTaskCreateError(400,"invalid_cron","The scheduled-task cron expression is invalid")}const prompt=input.prompt.trim();if(prompt.length===0||prompt.length>MAX_PROMPT_LENGTH){throw new ExistingSessionScheduledTaskCreateError(400,"invalid_prompt","The scheduled-task prompt is invalid")}const gate=input.gate?.trim();if(gate!==void 0){const gateError=gateCommandError(gate);if(gateError){throw new ExistingSessionScheduledTaskCreateError(400,"invalid_gate",`The scheduled-task gate ${gateError}`)}if(!input.recurring){throw new ExistingSessionScheduledTaskCreateError(400,"gate_requires_recurring",GATE_REQUIRES_RECURRING_MESSAGE)}}const allowActivePrompt=options.source==="cron-tool";const assertCallerPromptActive=options.source==="cron-tool"?options.assertCallerPromptActive:void 0;assertReusableScheduledTaskSession(target,input.sessionId,allowActivePrompt,assertCallerPromptActive);target.assertGenerationOpen?.();if(options.source==="rest"){const ensurePersisted=target.bridge?.ensureDefaultSessionPersisted;if(!ensurePersisted){throw new ExistingSessionScheduledTaskCreateError(409,"session_binding_unavailable","Session persistence is not available for this workspace")}try{await ensurePersisted.call(target.bridge,input.sessionId)}catch(error){target.assertGenerationOpen?.();if(error instanceof SessionNotFoundError){throw new ExistingSessionScheduledTaskCreateError(404,"session_not_found",`Session '${input.sessionId}' was not found`)}writeStderrLine(`qwen serve: failed to persist scheduled-task session '${input.sessionId}': ${error instanceof Error?error.message:String(error)}`);throw new ExistingSessionScheduledTaskCreateError(500,"session_persistence_failed","Failed to persist the requested session")}target.assertGenerationOpen?.()}const now=Date.now();const task=withTaskGate({id:generateCronTaskId(),cron:input.cron,prompt,recurring:input.recurring,createdAt:now,lastFiredAt:now-now%6e4,enabled:input.enabled!==false,sessionId:input.sessionId,sessionOwnedByTask:false,sessionMode:input.sessionMode==="per_run"?"per_run":"persistent",...input.sessionMode==="per_run"&&input.modelServiceId!==void 0?{modelServiceId:input.modelServiceId}:{},...input.sessionMode==="per_run"&&input.groupId!==void 0?{groupId:input.groupId}:{},...input.delivery!==void 0?{delivery:input.delivery}:{},...input.name!==void 0?{name:input.name}:{}},gate);let before;let after;await runWithScheduledTaskTarget(target,()=>updateCronTasks(target.workspaceCwd,tasks=>{assertReusableScheduledTaskSession(target,input.sessionId,allowActivePrompt,assertCallerPromptActive);if(tasks.some(candidate=>candidate.sessionId===input.sessionId)){throw new ExistingSessionScheduledTaskCreateError(409,"session_already_bound","The requested session is already bound to another scheduled task")}if(tasks.length>=MAX_SCHEDULED_TASKS){throw new ExistingSessionScheduledTaskCreateError(409,"max_tasks_reached",`Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`)}before=tasks;after=[...tasks,task];return after},{assertCanCommit:target.assertGenerationOpen}));try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,before,after,"scheduled-task create");throw error}return task}__name(createScheduledTaskWithExistingSession,"createScheduledTaskWithExistingSession");function requireOpenGeneration(target,res){try{target.assertGenerationOpen?.();return true}catch(error){if(sendGenerationClosedError(res,error))return false;throw error}}__name(requireOpenGeneration,"requireOpenGeneration");async function rollbackCronMutation(target,before,after,route){if(!before||!after)return;await runWithScheduledTaskTarget(target,()=>updateCronTasks(target.workspaceCwd,tasks=>isDeepStrictEqual(tasks,after)?before:tasks)).catch(error=>{writeStderrLine(`qwen serve: ${route} failed to roll back a stale task mutation: ${error instanceof Error?error.message:String(error)}`)})}__name(rollbackCronMutation,"rollbackCronMutation");async function restoreConsumedOneShot(target,before,failedTask,removalGenerations,route){const id=failedTask.id;const index=before?.findIndex(t=>t.id===id)??-1;const original=index===-1?void 0:before[index];if(!original||!removalGenerations)return;let restoreGenerations;await runWithScheduledTaskTarget(target,()=>updateCronTasks(target.workspaceCwd,tasks=>{if([...removalGenerations].some(([key,generation])=>restoreGenerations?.get(key)!==generation))return tasks;if(tasks.some(t=>t.id===id))return tasks;const restored=[...tasks];restored.splice(Math.min(index,restored.length),0,{...failedTask,enabled:false});return restored},{observeDeletionIds:[...removalGenerations.keys()],onDeletionGenerations:__name(generations=>{restoreGenerations=generations},"onDeletionGenerations")})).catch(error=>{writeStderrLine(`qwen serve: ${route} failed to restore the consumed one-shot task: ${error instanceof Error?error.message:String(error)}`)})}__name(restoreConsumedOneShot,"restoreConsumedOneShot");async function teardownBoundSession(target,sessionId){if(target.cleanupSession){await target.cleanupSession(sessionId).catch(()=>{})}else if(target.bridge){await target.bridge.closeSession(sessionId).catch(()=>{});const removed=await new SessionService(target.workspaceCwd,{runtimeBaseDir:target.runtimeBaseDir}).removeSession(sessionId).catch(()=>false);if(removed)target.bridge.markSessionCatalogChanged?.()}}__name(teardownBoundSession,"teardownBoundSession");async function dispatchTaskToFreshSession(target,task){const{bridge}=target;const sendPrompt=bridge?.sendPrompt?.bind(bridge);if(!bridge||!sendPrompt||!task.sessionId){throw new Error("Fresh-session dispatch is unavailable for this task")}const triggeredAt=task.lastFiredAt??Date.now();const child=await runWithScheduledTaskTarget(target,()=>bridge.spawnOrAttach({workspaceCwd:target.workspaceCwd,...task.modelServiceId?{modelServiceId:task.modelServiceId}:{},sessionScope:"thread",parentSessionId:task.sessionId,sourceType:SCHEDULED_TASK_RUN_SOURCE_TYPE,sourceId:scheduledTaskRunSourceId(task.id)}));try{if(task.modelServiceId&&child.modelApplied===false){throw new Error(`Scheduled task model selection failed: ${task.modelServiceId}`)}try{bridge.updateSessionMetadata(child.sessionId,{displayName:scheduledTaskRunSessionName(task.name??task.prompt,triggeredAt),titleSource:"auto"})}catch{}let markPromptAdmitted;const promptAdmitted=new Promise(resolve=>{markPromptAdmitted=resolve});const turn=sendPrompt(child.sessionId,{sessionId:child.sessionId,prompt:[{type:"text",text:buildScheduledTaskRunPrompt({id:task.id,name:task.name,cron:task.cron,prompt:task.prompt,triggeredAt,trigger:"manual",...task.gate?{gate:task.gate}:{}})}]},void 0,{onPromptAdmitted:markPromptAdmitted});void turn.catch(error=>{writeStderrLine(`qwen serve: scheduled-task session ${child.sessionId} prompt failed: ${error instanceof Error?error.message:String(error)}`)});await Promise.race([promptAdmitted,turn.then(()=>void 0,error=>Promise.reject(error))]);if(task.groupId){try{await runWithScheduledTaskTarget(target,()=>createSessionOrganizationService(target.workspaceCwd).updateSessionOrganization(child.sessionId,{groupId:task.groupId,color:null}));bridge.markSessionCatalogChanged?.()}catch(error){writeStderrLine(`qwen serve: scheduled-task session ${child.sessionId} could not be assigned to group ${task.groupId}: ${error instanceof Error?error.message:String(error)}`)}}}catch(error){await teardownBoundSession(target,child.sessionId);throw error}return child.sessionId}__name(dispatchTaskToFreshSession,"dispatchTaskToFreshSession");async function runWithScheduledTaskTarget(target,fn){const result=target.runtimeBaseDir===void 0?fn():Storage.runWithResolvedRuntimeBaseDir(target.runtimeBaseDir,fn);return await result}__name(runWithScheduledTaskTarget,"runWithScheduledTaskTarget");function sendActivityGateError(res,error){if(!error||typeof error!=="object"||error.code!=="daemon_draining"){return false}res.status(503).json({error:"The daemon is draining and no longer accepts work.",code:"daemon_draining"});return true}__name(sendActivityGateError,"sendActivityGateError");var GATE_REQUIRES_RECURRING_MESSAGE="A gate needs a recurring task: a one-shot whose gate prints nothing would be consumed with nothing delivered";function computeNextRunAt(task){if(task.enabled===false)return null;return nextDurableFireMs(task)}__name(computeNextRunAt,"computeNextRunAt");function toView(task){return{id:task.id,name:typeof task.name==="string"&&task.name.length>0?task.name:null,cron:task.cron,prompt:task.prompt,recurring:task.recurring,enabled:task.enabled!==false&&!taskHasLegacyCondition(task),createdAt:task.createdAt,lastFiredAt:task.lastFiredAt,nextRunAt:taskHasLegacyCondition(task)?null:computeNextRunAt(task),sessionId:typeof task.sessionId==="string"&&task.sessionId.length>0?task.sessionId:null,sessionMode:task.sessionMode==="per_run"?"per_run":"persistent",modelServiceId:task.modelServiceId??null,groupId:task.groupId??null,runs:Array.isArray(task.runs)?task.runs:[],...task.delivery!==void 0?{delivery:task.delivery}:{},gate:typeof task.gate==="string"&&task.gate.length>0?task.gate:null,gateStatus:task.gateStatus??null}}__name(toView,"toView");function validateCron(cron){try{parseCron(cron);nextFireTime(cron,new Date);return null}catch(err){return err instanceof Error?err.message:String(err)}}__name(validateCron,"validateCron");function canonicalCron(cron){try{const f=parseCron(cron);const s=__name(set=>[...set].sort((a,b)=>a-b).join(","),"s");return[s(f.minute),s(f.hour),s(f.dayOfMonth),s(f.month),s(f.dayOfWeek),f.domIsWild?"W":"",f.dowIsWild?"W":""].join("|")}catch{return null}}__name(canonicalCron,"canonicalCron");function registerScheduledTaskCrudRoutes(app,deps){const{prefix,resolveTarget,mutate,safeBody,channelDeliveryAuthorizations}=deps;const base=`${prefix}/scheduled-tasks`;const withTarget=__name(handler=>async(req,res)=>{const target=resolveTarget(req,res);if(!target)return;const operation=__name(async()=>{if(!requireOpenGeneration(target,res))return;await handler(req,res,target)},"operation");try{if(target.activity){await target.activity.run(operation)}else{await operation()}}catch(error){if(sendActivityGateError(res,error))return;throw error}},"withTarget");app.get(base,withTarget(async(_req,res,target)=>{try{const tasks=await runWithScheduledTaskTarget(target,()=>readCronTasks(target.workspaceCwd));if(!requireOpenGeneration(target,res))return;res.status(200).json({v:1,tasks:tasks.map(toView)})}catch(err){if(sendActivityGateError(res,err))return;writeStderrLine(`qwen serve: GET ${base} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to read scheduled tasks (the tasks file may be corrupt)",code:"scheduled_tasks_read_failed"})}}));app.post(base,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd,bridge}=target;const body=safeBody(req);const cron=typeof body["cron"]==="string"?body["cron"].trim():"";if(cron.length===0){res.status(400).json({error:"`cron` is required and must be a non-empty string",code:"invalid_cron"});return}if(cron.length>MAX_CRON_LENGTH){res.status(400).json({error:`\`cron\` exceeds ${MAX_CRON_LENGTH}-character limit`,code:"invalid_cron"});return}const cronError=validateCron(cron);if(cronError){res.status(400).json({error:cronError,code:"invalid_cron"});return}const prompt=typeof body["prompt"]==="string"?body["prompt"].trim():"";if(prompt.length===0){res.status(400).json({error:"`prompt` is required and must be a non-empty string",code:"invalid_prompt"});return}if(prompt.length>MAX_PROMPT_LENGTH){res.status(400).json({error:`\`prompt\` exceeds ${MAX_PROMPT_LENGTH}-character limit`,code:"invalid_prompt"});return}const nameResult=parseNameField(body["name"]);if(nameResult.error){res.status(400).json({error:nameResult.error,code:"invalid_name"});return}if(body["recurring"]!==void 0&&typeof body["recurring"]!=="boolean"){res.status(400).json({error:"`recurring` must be a boolean",code:"invalid_recurring"});return}if(body["enabled"]!==void 0&&typeof body["enabled"]!=="boolean"){res.status(400).json({error:"`enabled` must be a boolean",code:"invalid_enabled"});return}const sessionMode=body["sessionMode"]===void 0?"persistent":body["sessionMode"];if(sessionMode!=="persistent"&&sessionMode!=="per_run"){res.status(400).json({error:'`sessionMode` must be "persistent" or "per_run"',code:"invalid_session_mode"});return}const modelServiceId=body["modelServiceId"];if(modelServiceId!==void 0&&!isValidCronTaskRoutingId(modelServiceId)){res.status(400).json({error:`\`modelServiceId\` must be a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_model_service_id"});return}const groupId=body["groupId"];if(groupId!==void 0&&!isValidCronTaskRoutingId(groupId)){res.status(400).json({error:`\`groupId\` must be a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_group_id"});return}if(sessionMode!=="per_run"&&(modelServiceId!==void 0||groupId!==void 0)){res.status(400).json({error:'`modelServiceId` and `groupId` are only supported when `sessionMode` is "per_run"',code:"session_routing_requires_per_run"});return}if(typeof groupId==="string"){const groups=await runWithScheduledTaskTarget(target,()=>createSessionOrganizationService(workspaceCwd).listGroups());if(!groups.groups.some(group=>group.id===groupId)){res.status(400).json({error:`Group not found: ${groupId}`,code:"group_not_found"});return}}const parsedSessionId=parseCallerSuppliedSessionId(body["sessionId"]);if(parsedSessionId.kind==="invalid"){res.status(400).json({error:'`sessionId` must be an RFC UUID v1-v5 (e.g. "550e8400-e29b-41d4-a716-446655440000")',code:"invalid_session_id"});return}const providedSessionId=parsedSessionId.kind==="valid"?parsedSessionId.sessionId:void 0;let delivery;if(body["delivery"]!==void 0){try{delivery=parseChannelDelivery(body["delivery"])}catch(err){if(!isChannelDeliveryError(err))throw err;res.status(400).json({error:err.message,code:err.code});return}}if(sessionMode==="per_run"&&delivery!==void 0){res.status(400).json({error:"Per-run sessions do not support channel delivery",code:"session_mode_delivery_unsupported"});return}const removedField=findRemovedTaskField(body);if(removedField){res.status(400).json(removedFieldError(removedField));return}const recurring=body["recurring"]!==false;const enabled=body["enabled"]!==false;let gate;if(body["gate"]!==void 0&&body["gate"]!==null){const gateError=gateCommandError(body["gate"]);if(gateError){res.status(400).json({error:`\`gate\` ${gateError}`,code:"invalid_gate"});return}gate=body["gate"].trim();if(!recurring){res.status(400).json({error:GATE_REQUIRES_RECURRING_MESSAGE,code:"gate_requires_recurring"});return}}const taskId=generateCronTaskId();if(sessionMode==="per_run"&&(!bridge||!bridge.sendPrompt)){res.status(409).json({error:"Fresh-session dispatch is not available for this workspace",code:"session_mode_unavailable"});return}if(providedSessionId!==void 0){try{const task2=await createScheduledTaskWithExistingSession(target,{sessionId:providedSessionId,cron,prompt,recurring,enabled,sessionMode,...typeof modelServiceId==="string"?{modelServiceId}:{},...typeof groupId==="string"?{groupId}:{},...delivery!==void 0?{delivery}:{},...nameResult.value!==void 0?{name:nameResult.value}:{},...gate!==void 0?{gate}:{}},{source:"rest"});if(task2.delivery&&task2.sessionId){channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd,{sessionId:task2.sessionId,taskId:task2.id,target:task2.delivery.target,recurring:task2.recurring,lastFiredAt:task2.lastFiredAt??void 0})}res.status(201).json(toView(task2))}catch(error){if(error instanceof ExistingSessionScheduledTaskCreateError){if(error.code==="workspace_runtime_unavailable"){res.set("Retry-After","1")}res.status(error.status).json({error:error.message,code:error.code});return}if(sendActivityGateError(res,error))return;if(sendGenerationClosedError(res,error))return;writeStderrLine(`qwen serve: POST ${base} failed to create a task for session '${providedSessionId}': ${error instanceof Error?error.message:String(error)}`);res.status(500).json({error:"Failed to create scheduled task",code:"scheduled_tasks_write_failed"})}return}let boundSessionId;let sessionMintedHere=false;if(bridge){try{const tasks=await runWithScheduledTaskTarget(target,()=>readCronTasks(workspaceCwd));if(tasks.length>=MAX_SCHEDULED_TASKS){res.status(409).json({error:`Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,code:"max_tasks_reached"});return}}catch{}if(!requireOpenGeneration(target,res))return;try{const session=await runWithScheduledTaskTarget(target,()=>bridge.spawnOrAttach({workspaceCwd,sessionScope:"thread",sourceType:"scheduled_task",sourceId:taskId}));boundSessionId=session.sessionId;sessionMintedHere=true;if(!requireOpenGeneration(target,res)){await teardownBoundSession(target,boundSessionId);return}try{await runWithScheduledTaskTarget(target,async()=>bridge.updateSessionMetadata(boundSessionId,{displayName:scheduledTaskSessionName(nameResult.value??prompt),titleSource:"auto"}))}catch{}}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST ${base} failed to create the task's session: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to create the task's session",code:"scheduled_tasks_session_failed"});return}}const now=Date.now();const task=withTaskGate({id:taskId,cron,prompt,recurring,createdAt:now,lastFiredAt:now-now%6e4,enabled,sessionMode,...typeof modelServiceId==="string"?{modelServiceId}:{},...typeof groupId==="string"?{groupId}:{},...delivery!==void 0?{delivery}:{},...boundSessionId!==void 0?{sessionId:boundSessionId}:{},...nameResult.value!==void 0?{name:nameResult.value}:{}},gate);const rollbackSession=__name(async()=>{if(boundSessionId!==void 0&&sessionMintedHere){await teardownBoundSession(target,boundSessionId)}},"rollbackSession");let overCap=false;let rollbackBefore;let rollbackAfter;try{await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>{if(tasks.length>=MAX_SCHEDULED_TASKS){overCap=true;return tasks}rollbackBefore=tasks;rollbackAfter=[...tasks,task];return rollbackAfter},{assertCanCommit:target.assertGenerationOpen}))}catch(err){await rollbackSession();if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST ${base} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to create scheduled task",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`POST ${base}`);await rollbackSession();if(sendGenerationClosedError(res,error))return;throw error}}if(overCap){await rollbackSession();res.status(409).json({error:`Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,code:"max_tasks_reached"});return}if(task.delivery&&task.sessionId){channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd,{sessionId:task.sessionId,taskId:task.id,target:task.delivery.target,recurring:task.recurring,lastFiredAt:task.lastFiredAt??void 0})}res.status(201).json(toView(task))}));app.patch(`${base}/:id`,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd,bridge}=target;const id=typeof req.params["id"]==="string"?req.params["id"]:"";if(id.length===0){res.status(400).json({error:"Task id is required",code:"invalid_id"});return}const body=safeBody(req);const patch={};let clearName=false;let clearDelivery=false;let clearModelServiceId=false;let clearGroupId=false;let clearGate=false;let missingGroupId;const removedPatchField=findRemovedTaskField(body);if(removedPatchField){res.status(400).json(removedFieldError(removedPatchField));return}if("cron"in body){const cron=typeof body["cron"]==="string"?body["cron"].trim():"";if(cron.length===0||cron.length>MAX_CRON_LENGTH){res.status(400).json({error:"`cron` must be a non-empty string within the length limit",code:"invalid_cron"});return}const cronError=validateCron(cron);if(cronError){res.status(400).json({error:cronError,code:"invalid_cron"});return}patch.cron=cron}if("prompt"in body){const prompt=typeof body["prompt"]==="string"?body["prompt"].trim():"";if(prompt.length===0||prompt.length>MAX_PROMPT_LENGTH){res.status(400).json({error:"`prompt` must be a non-empty string within the length limit",code:"invalid_prompt"});return}patch.prompt=prompt}if("name"in body){const nameResult=parseNameField(body["name"]);if(nameResult.error){res.status(400).json({error:nameResult.error,code:"invalid_name"});return}if(nameResult.value===void 0){clearName=true}else{patch.name=nameResult.value}}if("recurring"in body){if(typeof body["recurring"]!=="boolean"){res.status(400).json({error:"`recurring` must be a boolean",code:"invalid_recurring"});return}patch.recurring=body["recurring"]}if("enabled"in body){if(typeof body["enabled"]!=="boolean"){res.status(400).json({error:"`enabled` must be a boolean",code:"invalid_enabled"});return}patch.enabled=body["enabled"]}if("sessionMode"in body){if(body["sessionMode"]!=="persistent"&&body["sessionMode"]!=="per_run"){res.status(400).json({error:'`sessionMode` must be "persistent" or "per_run"',code:"invalid_session_mode"});return}patch.sessionMode=body["sessionMode"]}if("modelServiceId"in body){const value=body["modelServiceId"];if(value===null||value===""){clearModelServiceId=true}else if(!isValidCronTaskRoutingId(value)){res.status(400).json({error:`\`modelServiceId\` must be null or a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_model_service_id"});return}else{patch.modelServiceId=value}}if("groupId"in body){const value=body["groupId"];if(value===null||value===""){clearGroupId=true}else if(!isValidCronTaskRoutingId(value)){res.status(400).json({error:`\`groupId\` must be null or a non-empty string of at most ${MAX_ROUTING_ID_LENGTH} characters without control characters`,code:"invalid_group_id"});return}else{const groups=await runWithScheduledTaskTarget(target,()=>createSessionOrganizationService(workspaceCwd).listGroups());if(!groups.groups.some(group=>group.id===value)){missingGroupId=value}patch.groupId=value}}if("delivery"in body){if(body["delivery"]===null){clearDelivery=true}else{try{patch.delivery=parseChannelDelivery(body["delivery"])}catch(err){if(!isChannelDeliveryError(err))throw err;res.status(400).json({error:err.message,code:err.code});return}}}if("gate"in body){if(body["gate"]===null||body["gate"]===""){clearGate=true}else{const gateError=gateCommandError(body["gate"]);if(gateError){res.status(400).json({error:`\`gate\` must be null or a shell command; it ${gateError}`,code:"invalid_gate"});return}patch.gate=body["gate"].trim()}}if(Object.keys(patch).length===0&&!clearName&&!clearDelivery&&!clearModelServiceId&&!clearGroupId&&!clearGate){res.status(400).json({error:"No updatable fields provided",code:"empty_patch"});return}let found=false;let updated;let blockedByArchive=false;let blockedLegacy=false;let blockedGateOneShot=false;let blockedSessionModeDelivery=false;let blockedSessionModeUnavailable=false;let blockedSessionModeUnbound=false;let blockedGroupNotFound=false;let rollbackBefore;let rollbackAfter;try{await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>{const idx=tasks.findIndex(t=>t.id===id);if(idx===-1)return tasks;found=true;const current=tasks[idx];if(missingGroupId!==void 0&¤t.groupId!==missingGroupId){blockedGroupNotFound=true;return tasks}const convertingToPerRun=patch.sessionMode==="per_run"&¤t.sessionMode!=="per_run";if(convertingToPerRun&&(!bridge||!bridge.sendPrompt)){blockedSessionModeUnavailable=true;return tasks}if(convertingToPerRun&&!current.sessionId){blockedSessionModeUnbound=true;return tasks}if(patch.enabled===true&&taskHasLegacyCondition(current)){blockedLegacy=true;return tasks}if((patch.gate!==void 0||clearGate)&&taskHasLegacyCondition(current)){blockedLegacy=true;return tasks}if(patch.enabled===true&¤t.disabledByArchive===true){blockedByArchive=true;return tasks}let next={...current,...patch};if(clearName)delete next.name;if(clearDelivery)delete next.delivery;if(clearModelServiceId)delete next.modelServiceId;if(clearGroupId)delete next.groupId;if(next.sessionMode!=="per_run"){delete next.modelServiceId;delete next.groupId}if(next.sessionMode==="per_run"&&next.delivery){blockedSessionModeDelivery=true;return tasks}if(clearGate||patch.gate!==void 0){next=withTaskGate(next,clearGate?void 0:patch.gate);if(clearGate||patch.gate!==current.gate){delete next.gateStatus}}if(next.gate!==void 0&&!next.recurring&&(patch.gate!==void 0&&patch.gate!==current.gate||patch.recurring===false&¤t.recurring!==false)){blockedGateOneShot=true;return tasks}const justReEnabled=current.enabled===false&&patch.enabled===true;const cronChanged=patch.cron!==void 0&&canonicalCron(patch.cron)!==canonicalCron(current.cron);const becameRecurring=patch.recurring===true&¤t.recurring!==true;const becameOneShot=patch.recurring===false&¤t.recurring!==false;const retryFailedOneShot=!next.recurring&&justReEnabled&&!cronChanged&&!becameOneShot&¤t.runs?.at(-1)?.sessionDispatchFailed===true;{const now=Date.now();const minute=now-now%6e4;if(next.recurring&&(justReEnabled||cronChanged||becameRecurring)){next.lastFiredAt=minute}else if(!next.recurring&&!retryFailedOneShot&&(justReEnabled||cronChanged||becameOneShot)){next.createdAt=now;next.lastFiredAt=minute}}updated=next;rollbackBefore=tasks;rollbackAfter=tasks.map((t,i)=>i===idx?next:t);return rollbackAfter},{assertCanCommit:target.assertGenerationOpen}))}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: PATCH ${base}/${id} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to update scheduled task",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`PATCH ${base}/${id}`);if(sendGenerationClosedError(res,error))return;throw error}}if(!found){res.status(404).json({error:"Task not found",code:"task_not_found"});return}if(missingGroupId!==void 0&&blockedGroupNotFound){res.status(400).json({error:`Group not found: ${missingGroupId}`,code:"group_not_found"});return}if(blockedLegacy){res.status(409).json({error:"This task uses the removed isolated run mode with a precondition and can no longer be enabled or run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",code:"task_legacy_unsupported"});return}if(blockedByArchive){res.status(409).json({error:"This task was disabled by archiving its session; unarchive the session to re-enable it.",code:"task_session_archived"});return}if(blockedSessionModeUnavailable){res.status(409).json({error:"Fresh-session dispatch is not available for this workspace",code:"session_mode_unavailable"});return}if(blockedSessionModeUnbound){res.status(409).json({error:"This task is not bound to a session yet, so it cannot run in a new session every run. Try again once it has run or been opened at least once.",code:"session_mode_requires_bound_session"});return}if(blockedSessionModeDelivery){res.status(409).json({error:"Per-run sessions do not support channel delivery",code:"session_mode_delivery_unsupported"});return}if(blockedGateOneShot){res.status(400).json({error:GATE_REQUIRES_RECURRING_MESSAGE,code:"gate_requires_recurring"});return}if(!updated){res.status(404).json({error:"Task not found",code:"task_not_found"});return}const effectiveLabelChanged=patch.name!==void 0||clearName||patch.prompt!==void 0&&updated.name===void 0;if(bridge&&updated.sessionId&&updated.sessionOwnedByTask!==false&&effectiveLabelChanged){try{bridge.updateSessionMetadata(updated.sessionId,{displayName:scheduledTaskSessionName(updated.name??updated.prompt),titleSource:"auto"})}catch{}}if(updated.delivery&&updated.sessionId){channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd,{sessionId:updated.sessionId,taskId:updated.id,target:updated.delivery.target,recurring:updated.recurring,lastFiredAt:updated.lastFiredAt??void 0})}if(clearDelivery&&updated.sessionId){channelDeliveryAuthorizations?.revokeScheduledTask(workspaceCwd,updated.sessionId,updated.id)}res.status(200).json(toView(updated))}));app.delete(`${base}/:id`,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd,bridge}=target;const id=typeof req.params["id"]==="string"?req.params["id"]:"";if(id.length===0){res.status(400).json({error:"Task id is required",code:"invalid_id"});return}let boundSessionId;let sessionOwnedByTask=true;let removed=false;let rollbackBefore;let rollbackAfter;try{await runWithScheduledTaskTarget(target,async()=>{try{await access(getCronFilePath(workspaceCwd))}catch(error){if(error.code==="ENOENT")return;throw error}await updateCronTasks(workspaceCwd,tasks=>{const idx=tasks.findIndex(t=>t.id===id);if(idx===-1)return tasks;const match=tasks[idx].sessionId;if(typeof match==="string"&&match.length>0){boundSessionId=match;sessionOwnedByTask=tasks[idx].sessionOwnedByTask!==false}removed=true;rollbackBefore=tasks;rollbackAfter=tasks.filter((_,i)=>i!==idx);return rollbackAfter},{assertCanCommit:target.assertGenerationOpen,deletionIds:[id]})})}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: DELETE ${base}/${id} failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to delete scheduled task",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`DELETE ${base}/${id}`);if(sendGenerationClosedError(res,error))return;throw error}}if(!removed){res.status(404).json({error:"Task not found",code:"task_not_found"});return}if(boundSessionId&&sessionOwnedByTask&&bridge){try{await runWithScheduledTaskTarget(target,()=>bridge.closeSession(boundSessionId,void 0,{closeIfUnheld:true,reason:"scheduled_task_deleted"}))}catch(error){if(sendActivityGateError(res,error))return}}if(boundSessionId){channelDeliveryAuthorizations?.revokeScheduledTask(workspaceCwd,boundSessionId,id)}res.status(200).json({deleted:true,id})}));app.post(`${base}/:id/run`,mutate(),withTarget(async(req,res,target)=>{const{workspaceCwd}=target;const id=typeof req.params["id"]==="string"?req.params["id"]:"";if(id.length===0){res.status(400).json({error:"Task id is required",code:"invalid_id"});return}const now=Date.now();let found=false;let blockedDisabled=false;let blockedLegacy=false;let updated;let rollbackBefore;let rollbackAfter;let removalGenerations;try{await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>{const idx=tasks.findIndex(t=>t.id===id);if(idx===-1)return tasks;found=true;const current=tasks[idx];if(taskHasLegacyCondition(current)){blockedLegacy=true;return tasks}if(current.enabled===false){blockedDisabled=true;return tasks}const next={...current,lastFiredAt:now,runs:appendCronRun(current.runs,{at:now,kind:"manual",...current.sessionMode!=="per_run"&¤t.sessionId?{sessionId:current.sessionId}:{}})};updated=next;rollbackBefore=tasks;const nextTasks=!current.recurring?tasks.filter((_,i)=>i!==idx):tasks.map((t,i)=>i===idx?next:t);rollbackAfter=nextTasks;return nextTasks},{assertCanCommit:target.assertGenerationOpen,observeDeletionIds:__name(tasks=>{const task=tasks.find(task2=>task2.id===id);return task?.sessionId?[id,cronTaskSessionDeletionId(task.sessionId)]:[id]},"observeDeletionIds"),onDeletionGenerations:__name(generations=>{removalGenerations=generations},"onDeletionGenerations")}))}catch(err){if(sendActivityGateError(res,err))return;if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST ${base}/${id}/run failed: ${err instanceof Error?err.message:String(err)}`);res.status(500).json({error:"Failed to record scheduled task run",code:"scheduled_tasks_write_failed"});return}if(rollbackBefore&&rollbackAfter){try{target.assertGenerationOpen?.()}catch(error){await rollbackCronMutation(target,rollbackBefore,rollbackAfter,`POST ${base}/${id}/run`);if(sendGenerationClosedError(res,error))return;throw error}}if(blockedLegacy){res.status(409).json({error:"This task uses the removed isolated run mode with a precondition and can no longer run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",code:"task_legacy_unsupported"});return}if(blockedDisabled){res.status(409).json({error:"Cannot run a disabled task; enable it first (unarchive its session if it was archived).",code:"task_disabled"});return}if(!found||!updated){res.status(404).json({error:"Task not found",code:"task_not_found"});return}if(updated.sessionMode==="per_run"){const persistOutcome=__name(async outcome=>{if(!updated.recurring)return;await runWithScheduledTaskTarget(target,()=>updateCronTasks(workspaceCwd,tasks=>tasks.map(task=>task.id===id?annotateCronRunSession(task,now,outcome):task),{assertCanCommit:target.assertGenerationOpen}))},"persistOutcome");let childSessionId;try{childSessionId=await dispatchTaskToFreshSession(target,updated)}catch(error){updated=annotateCronRunSession(updated,now,{dispatchFailed:true});if(updated.recurring){await persistOutcome({dispatchFailed:true}).catch(persistError=>{writeStderrLine(`qwen serve: POST ${base}/${id}/run could not record the failed dispatch: ${persistError instanceof Error?persistError.message:String(persistError)}`)})}else{await restoreConsumedOneShot(target,rollbackBefore,updated,removalGenerations,`POST ${base}/${id}/run fresh-session dispatch`)}writeStderrLine(`qwen serve: POST ${base}/${id}/run could not create a fresh session: ${error instanceof Error?error.message:String(error)}`);res.status(500).json({error:"Failed to create a fresh session for the scheduled task",code:"scheduled_task_session_dispatch_failed"});return}updated=annotateCronRunSession(updated,now,{sessionId:childSessionId});await persistOutcome({sessionId:childSessionId}).catch(error=>{writeStderrLine(`qwen serve: POST ${base}/${id}/run could not attribute fresh session ${childSessionId}: ${error instanceof Error?error.message:String(error)}`)})}if(!updated.recurring&&updated.sessionId){channelDeliveryAuthorizations?.revokeScheduledTask(workspaceCwd,updated.sessionId,updated.id)}const view=toView(updated);if(!updated.recurring)view.nextRunAt=null;res.status(200).json(view)}))}__name(registerScheduledTaskCrudRoutes,"registerScheduledTaskCrudRoutes");function registerScheduledTasksRoutes(app,deps){const{boundWorkspace,mutate,safeBody,bridge,channelDeliveryAuthorizations}=deps;registerScheduledTaskCrudRoutes(app,{prefix:"",resolveTarget:__name((_req,res)=>{const runtime=deps.getRuntime?.();if(deps.getRuntime&&!runtime){res.set("Retry-After","1");res.status(503).json({error:"Workspace runtime is not active",code:"workspace_runtime_unavailable"});return null}if(runtime&&!requireTrustedWorkspaceRuntime(runtime,res))return null;return{workspaceCwd:boundWorkspace,...runtime?{runtimeBaseDir:runtime.sessionRuntimeBaseDir,...deps.cleanupSession?{cleanupSession:__name(sessionId=>deps.cleanupSession(runtime,sessionId),"cleanupSession")}:{}}:{},bridge:bridge===void 0?void 0:runtime?.bridge??bridge,...runtime?.generationGuard?{assertGenerationOpen:__name(()=>runtime.generationGuard?.assertOpen(),"assertGenerationOpen")}:{},...deps.workspaceRegistry?{resolveLiveSessionOwner:__name(sessionId=>deps.workspaceRegistry.resolveLiveSessionOwner(sessionId),"resolveLiveSessionOwner")}:{}}},"resolveTarget"),mutate,safeBody,channelDeliveryAuthorizations})}__name(registerScheduledTasksRoutes,"registerScheduledTasksRoutes");function registerWorkspaceQualifiedScheduledTasksRoutes(app,deps){const{workspaceRegistry,mutate,safeBody,manageScheduledTaskSessions,channelDeliveryAuthorizations,cleanupSession}=deps;registerScheduledTaskCrudRoutes(app,{prefix:"/workspaces/:workspace",resolveTarget:__name((req,res)=>{const runtime=resolveWorkspaceRuntimeWithLiveCompatibilityFromParam(workspaceRegistry,req,res);if(!runtime)return null;if(!requireTrustedWorkspaceRuntime(runtime,res))return null;if(runtime.provenance==="live-conversation"&&!deps.conversationRuntimeActivity){sendConversationRuntimeUnavailable(res);return null}if(runtime.provenance==="live-conversation"&&req.method==="POST"&&req.params["id"]===void 0&&parseCallerSuppliedSessionId(safeBody(req)["sessionId"]).kind==="absent"){res.status(400).json({error:"Generic scheduled tasks cannot create sessions in the Conversations workspace.",code:"live_session_creation_reserved"});return null}return{workspaceCwd:runtime.workspaceCwd,runtimeBaseDir:runtime.sessionRuntimeBaseDir,...runtime.provenance==="live-conversation"&&deps.conversationRuntimeActivity?{activity:deps.conversationRuntimeActivity}:{},...cleanupSession?{cleanupSession:__name(sessionId=>cleanupSession(runtime,sessionId),"cleanupSession")}:{},bridge:manageScheduledTaskSessions?runtime.bridge:void 0,...runtime.generationGuard?{assertGenerationOpen:__name(()=>runtime.generationGuard?.assertOpen(),"assertGenerationOpen")}:{},resolveLiveSessionOwner:__name(sessionId=>workspaceRegistry.resolveLiveSessionOwner(sessionId),"resolveLiveSessionOwner")}},"resolveTarget"),mutate,safeBody,channelDeliveryAuthorizations})}__name(registerWorkspaceQualifiedScheduledTasksRoutes,"registerWorkspaceQualifiedScheduledTasksRoutes");var REMOVED_TASK_FIELDS=["runMode","condition"];function findRemovedTaskField(body){return REMOVED_TASK_FIELDS.find(field=>field in body)}__name(findRemovedTaskField,"findRemovedTaskField");function removedFieldError(field){return{error:`\`${field}\` is no longer supported: the isolated scheduled-task run mode was removed. Every task now runs in its bound session; call the \`create_sub_session\` tool from the task prompt for per-run isolation.`,code:"unsupported_field"}}__name(removedFieldError,"removedFieldError");function parseNameField(raw){if(raw===void 0||raw===null)return{value:void 0};if(typeof raw!=="string"){return{error:"`name` must be a string"}}const trimmed=raw.trim();if(trimmed.length===0)return{value:void 0};if(trimmed.length>MAX_NAME_LENGTH){return{error:`\`name\` exceeds ${MAX_NAME_LENGTH}-character limit`}}return{value:trimmed}}__name(parseNameField,"parseNameField");export{scheduledTaskSessionName,ExistingSessionScheduledTaskCreateError,createScheduledTaskWithExistingSession,registerScheduledTasksRoutes,registerWorkspaceQualifiedScheduledTasksRoutes};
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright 2025 Qwen Team
|