@qwen-code/qwen-code 0.22.3 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/bundled/computer-use/SKILL.md +116 -180
- package/bundled/goal-draft/SKILL.md +5 -1
- package/bundled/qc-helper/docs/common-workflow.md +32 -0
- package/bundled/qc-helper/docs/configuration/auth.md +6 -6
- package/bundled/qc-helper/docs/configuration/model-providers.md +8 -2
- package/bundled/qc-helper/docs/configuration/settings.md +63 -58
- package/bundled/qc-helper/docs/extension/introduction.md +1 -1
- package/bundled/qc-helper/docs/features/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/approval-mode.md +3 -0
- package/bundled/qc-helper/docs/features/auto-mode.md +34 -17
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +4 -2
- package/bundled/qc-helper/docs/features/channels/dws.md +6 -2
- package/bundled/qc-helper/docs/features/channels/overview.md +5 -2
- package/bundled/qc-helper/docs/features/code-review.md +2 -2
- package/bundled/qc-helper/docs/features/commands.md +79 -1
- package/bundled/qc-helper/docs/features/computer-use.md +2 -2
- package/bundled/qc-helper/docs/features/goals.md +9 -3
- package/bundled/qc-helper/docs/features/headless.md +16 -1
- package/bundled/qc-helper/docs/features/hooks.md +8 -3
- package/bundled/qc-helper/docs/features/memory.md +1 -0
- package/bundled/qc-helper/docs/features/output-styles.md +38 -0
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +17 -7
- package/bundled/qc-helper/docs/qwen-serve.md +74 -55
- package/bundled/review/SKILL.md +16 -7
- package/bundled/review/references/posting.md +3 -3
- package/chunks/MaxSizedBox-B3D7545A.js +111 -0
- package/chunks/{StandaloneSessionPicker-2FJAOLGG.js → StandaloneSessionPicker-QUMO4LLQ.js} +88 -86
- package/chunks/{acp-startup-profiler-GNYAL6LI.js → acp-startup-profiler-M4X5F3VK.js} +2 -2
- package/chunks/{acpAgent-2ZMIJAFV.js → acpAgent-2GTFCIEP.js} +2041 -444
- package/chunks/{agent-X5WX3L2I.js → agent-XKF5SZWU.js} +46 -46
- package/chunks/agent-headless-OC2IB55D.js +85 -0
- package/chunks/{anthropicContentGenerator-YVTB6QX7.js → anthropicContentGenerator-L76MR5OR.js} +53 -20
- package/chunks/{artifact-tool-XSMPHZBT.js → artifact-tool-MYCL2QCS.js} +3 -4
- package/chunks/{askUserQuestion-4SWJY65V.js → askUserQuestion-THQZMG44.js} +45 -7
- package/chunks/bridge-IHSBI2YJ.js +118 -0
- package/chunks/{build-INBK7IXX.js → build-63BIOYWK.js} +1 -1
- package/chunks/{ca-7HPYOYSZ.js → ca-BNU7YNDE.js} +3 -0
- package/chunks/{channel-management-service-HQ6KDS7C.js → channel-management-service-4MTCEGJB.js} +4 -4
- package/chunks/channel-settings-store-BVKWAI2T.js +121 -0
- package/chunks/{channel-worker-group-6NA6BBZV.js → channel-worker-group-47F4ISUZ.js} +7 -7
- package/chunks/{channel-worker-manager-NEZ2J6RK.js → channel-worker-manager-I5Y44GYR.js} +51 -10
- package/chunks/{channel-worker-supervisor-FKU7DIHJ.js → channel-worker-supervisor-6VCLUXFE.js} +4 -4
- package/chunks/{chunk-PPKZ7JOE.js → chunk-22UH7VTP.js} +1 -1
- package/chunks/chunk-24FVUD5P.js +49 -0
- package/chunks/{chunk-MZCJWS5Y.js → chunk-2M3EWQNG.js} +20 -0
- package/chunks/{chunk-7T52W4SW.js → chunk-32LU3APX.js} +1 -1
- package/chunks/{chunk-42IDLQWS.js → chunk-373DQUVA.js} +48 -13
- package/chunks/{chunk-MSBO7X2W.js → chunk-37JFWFCD.js} +1 -1
- package/chunks/{chunk-3JXM2CVW.js → chunk-3AKCBZVW.js} +3 -3
- package/chunks/{chunk-TVC6HQ2U.js → chunk-3JQZVCBI.js} +2 -2
- package/chunks/{chunk-2LNNVAUV.js → chunk-3L724BJ5.js} +246 -15
- package/chunks/{chunk-E7REAOTN.js → chunk-47ECGEJC.js} +4 -0
- package/chunks/{chunk-WNPDGUJO.js → chunk-47RYEQW5.js} +2 -3
- package/chunks/{chunk-TZBSGJ6C.js → chunk-4BGDFKQE.js} +7 -7
- package/chunks/{chunk-PZ66FRIC.js → chunk-4F7GQGXB.js} +11772 -4773
- package/chunks/{chunk-DMLVSW7L.js → chunk-4HVH57J3.js} +713 -9
- package/chunks/{chunk-CMHFCLBU.js → chunk-4LIFGNI4.js} +1 -1
- package/chunks/{chunk-3SZC4VP4.js → chunk-4M24B5J5.js} +88 -49
- package/chunks/{chunk-BOWFGCEU.js → chunk-4PSDSCW3.js} +3 -3
- package/chunks/chunk-4UANMABT.js +1026 -0
- package/chunks/{chunk-M3QRM3DE.js → chunk-54C6PIGT.js} +5 -5
- package/chunks/{chunk-HP5LR5HL.js → chunk-5EIOJGCR.js} +4 -4
- package/chunks/{chunk-64REQJJ2.js → chunk-5H5S4UY5.js} +3 -3
- package/chunks/chunk-5IENVM7Z.js +35 -0
- package/chunks/{chunk-I6LYRJPB.js → chunk-5Q5RC2WE.js} +2 -2
- package/chunks/{chunk-WGY3AVGM.js → chunk-5RTTI4GE.js} +79 -5
- package/chunks/{chunk-KID24ZFN.js → chunk-64QH2UC6.js} +13 -1
- package/chunks/{chunk-MF7HCQWZ.js → chunk-65HWLGA7.js} +3 -3
- package/chunks/{chunk-OU5APVWO.js → chunk-6A2D4QSO.js} +13 -7
- package/chunks/chunk-6HUXPLB5.js +110 -0
- package/chunks/{chunk-VQUGEVGR.js → chunk-7IKXTGZT.js} +1 -1
- package/chunks/{chunk-UTLCH2FK.js → chunk-7JMGTOH7.js} +437 -136
- package/chunks/{chunk-7LOELM2I.js → chunk-7RB56BRJ.js} +3 -3
- package/chunks/{chunk-NIFYWDYN.js → chunk-7TBU7PU2.js} +1 -1
- package/chunks/{chunk-V2NDP3I4.js → chunk-7XL4WRXM.js} +2 -2
- package/chunks/chunk-ADJD4LZF.js +210 -0
- package/chunks/{chunk-T7KMERIX.js → chunk-ADYN7P2Y.js} +2 -2
- package/chunks/{chunk-TPI7O7HR.js → chunk-AHYTURFB.js} +1 -1
- package/chunks/{chunk-LUEHOUHM.js → chunk-AI35S34R.js} +3 -3
- package/chunks/{chunk-CIZCL2MW.js → chunk-ALUYNJPM.js} +1486 -2172
- package/chunks/{chunk-ABS25QER.js → chunk-ANVG3BVV.js} +1 -1
- package/chunks/{chunk-6ZPDLGHN.js → chunk-AZJLY2XZ.js} +5 -5
- package/chunks/{chunk-A3LWD5MK.js → chunk-BA4WJC4L.js} +1 -1
- package/chunks/{chunk-W3JH33JE.js → chunk-BFY33IB4.js} +18 -10
- package/chunks/{chunk-N4X7G4J2.js → chunk-BHTYRHJF.js} +1 -1
- package/chunks/{chunk-TEBDFQBZ.js → chunk-BJXCYUGM.js} +11 -6
- package/chunks/{chunk-7VMIMAVB.js → chunk-C2VWOXHS.js} +8 -8
- package/chunks/{chunk-XHF7WQ6B.js → chunk-C4TIXFDZ.js} +16 -5
- package/chunks/chunk-CHEIIBT3.js +40 -0
- package/chunks/chunk-CVX63TFJ.js +348 -0
- package/chunks/{chunk-RXFQM6FQ.js → chunk-DMEUXLSS.js} +16 -1
- package/chunks/{chunk-EKSCLBBF.js → chunk-DQCKVAF5.js} +23 -5
- package/chunks/{chunk-734C6JGI.js → chunk-DSX7KQPM.js} +5195 -666
- package/chunks/{chunk-4CMJKUND.js → chunk-DTVQSSNM.js} +67 -2
- package/chunks/{chunk-BKWNKLZB.js → chunk-DYTW3QVG.js} +24 -9
- package/chunks/{chunk-C2X7KY45.js → chunk-E4JNFXNI.js} +3 -3
- package/chunks/{chunk-UHQFIS7N.js → chunk-EAHOJF6V.js} +28 -4
- package/chunks/{chunk-YLSQLSH7.js → chunk-EBDGRBZX.js} +24 -16
- package/chunks/{chunk-DJBQCO2E.js → chunk-EFTPIZIC.js} +412 -3
- package/chunks/{chunk-6DIGWMGT.js → chunk-EIJT2PQ6.js} +2 -2
- package/chunks/{chunk-4TT3IVGA.js → chunk-EIY7SUPZ.js} +1 -1
- package/chunks/{chunk-XQFT3QUF.js → chunk-ENYUKMFK.js} +1 -1
- package/chunks/{chunk-ZWJDJ6RU.js → chunk-EVFDRBUM.js} +157 -153
- package/chunks/{chunk-4VPCTGH6.js → chunk-EWRW2WQC.js} +15 -9
- package/chunks/{chunk-VBCPNIQD.js → chunk-F33GFWPR.js} +47 -184
- package/chunks/{chunk-ERFDKH32.js → chunk-F47DITLZ.js} +19 -8
- package/chunks/{chunk-73RM4POK.js → chunk-F7NF2IOE.js} +7 -7
- package/chunks/{chunk-EB6QRGHM.js → chunk-FD5SJOWT.js} +10 -7
- package/chunks/{chunk-SS5SDCD3.js → chunk-FRICLXCZ.js} +7 -7
- package/chunks/{chunk-NU7RKEZR.js → chunk-FUO5V5KI.js} +14 -7
- package/chunks/{chunk-G6FECKTJ.js → chunk-G5PBOQWI.js} +9 -6
- package/chunks/{chunk-CAJTKR6W.js → chunk-G7HBEEX7.js} +15 -9
- package/chunks/{chunk-4QHPPXK2.js → chunk-GB4UKWY5.js} +2 -2
- package/chunks/{chunk-QYMAKPY5.js → chunk-GH2S4GD5.js} +350 -12
- package/chunks/{chunk-LHBUKJG2.js → chunk-GXUTFQXK.js} +28 -25
- package/chunks/{chunk-KJO2LBUK.js → chunk-H43PSPYS.js} +5 -5
- package/chunks/{chunk-XSG6G3G6.js → chunk-HJBHMANB.js} +12 -14
- package/chunks/chunk-HRPFBHW7.js +336 -0
- package/chunks/{chunk-6PJOTWAN.js → chunk-HT5S5TRQ.js} +1 -1
- package/chunks/{chunk-HCOBAG2L.js → chunk-HWVUSYSN.js} +3 -8
- package/chunks/{chunk-2OUD5T67.js → chunk-I2TMJPCV.js} +213 -185
- package/chunks/{chunk-CLWO3B77.js → chunk-I4NRYS6A.js} +11 -11
- package/chunks/{chunk-V7EESTJV.js → chunk-I5N4EAS6.js} +1 -1
- package/chunks/{chunk-K5KXUXWC.js → chunk-IG4W5SJR.js} +3 -3
- package/chunks/{chunk-FROAFEFB.js → chunk-IPATA3T2.js} +3 -3
- package/chunks/{chunk-NKLP3DCK.js → chunk-IQAFKVXS.js} +1 -1
- package/chunks/{chunk-AYHQZBJ4.js → chunk-IRKQ4YYX.js} +3 -3
- package/chunks/{chunk-J3NNHTV6.js → chunk-J5TTWBZK.js} +6 -0
- package/chunks/{chunk-QFCDF5PL.js → chunk-JHN7UIDW.js} +1 -1
- package/chunks/{chunk-AVNATYLY.js → chunk-JJKNYRFY.js} +1 -1
- package/chunks/{chunk-CQH5KTKC.js → chunk-JR42V4UY.js} +1 -1
- package/chunks/chunk-JS73NNWF.js +30 -0
- package/chunks/{chunk-NV55WWD6.js → chunk-JUARRUMA.js} +802 -2011
- package/chunks/chunk-JX6XHPTX.js +26 -0
- package/chunks/{chunk-5JTIYALA.js → chunk-JZWOCUZ3.js} +1 -1
- package/chunks/{chunk-P2G476QN.js → chunk-KEVYJSI4.js} +13 -13
- package/chunks/{chunk-B466ZSHZ.js → chunk-KFN2IZYR.js} +3 -3
- package/chunks/{chunk-JWALNCLT.js → chunk-KGV55H53.js} +1 -1
- package/chunks/{chunk-23RFD54N.js → chunk-KHP66DFN.js} +1 -1
- package/chunks/{chunk-2SXSLSQE.js → chunk-KM3XVTMO.js} +12 -6
- package/chunks/{chunk-GPGU4S2N.js → chunk-KMU3ZHH4.js} +3 -3
- package/chunks/chunk-KOGW3YWJ.js +2054 -0
- package/chunks/{chunk-NMOD2FXQ.js → chunk-L26ONV2Y.js} +8 -8
- package/chunks/chunk-L34XSHIZ.js +28 -0
- package/chunks/{chunk-SEONHUS3.js → chunk-LAUEEBDL.js} +2 -0
- package/chunks/{chunk-3WK3QDNV.js → chunk-LB3WQQJK.js} +2 -2
- package/chunks/{chunk-URE3QBBB.js → chunk-LEPCWS5A.js} +3 -3
- package/chunks/{chunk-36GSQ3MM.js → chunk-LHBNR6EU.js} +2 -2
- package/chunks/{chunk-V4264FEG.js → chunk-LKODFJRD.js} +1 -1
- package/chunks/{chunk-PADPMMYM.js → chunk-LOBDDFYK.js} +5 -29
- package/chunks/{chunk-BXDAPVQU.js → chunk-LU77UT4D.js} +28 -4
- package/chunks/{chunk-RFIDDFAL.js → chunk-M4KFODIP.js} +1 -1
- package/chunks/{chunk-CFJY4DGX.js → chunk-M4LBBSVP.js} +4 -2
- package/chunks/{chunk-KYWTPLBJ.js → chunk-MOF6VZN2.js} +2 -2
- package/chunks/{chunk-DJPASAUV.js → chunk-MP6YZ4RK.js} +4829 -3638
- package/chunks/{chunk-T26EAKDL.js → chunk-N2TNM3QB.js} +2 -6
- package/chunks/{chunk-2TNL5KPM.js → chunk-N4QWUPDM.js} +7 -0
- package/chunks/{chunk-7S226YTK.js → chunk-NFIDVZND.js} +11 -1
- package/chunks/{chunk-ZEYFMJQA.js → chunk-NQ4L2CMD.js} +83 -18
- package/chunks/{chunk-ZZUKP7HV.js → chunk-NRL5CUZT.js} +1 -1
- package/chunks/{chunk-WXEA74YB.js → chunk-NSUKQ4DN.js} +9 -3
- package/chunks/chunk-NUHOLAQ6.js +59 -0
- package/chunks/{chunk-DJEZ55D4.js → chunk-NVVJTUSL.js} +336 -140
- package/chunks/{chunk-3XKLXHGK.js → chunk-NXKOVOM5.js} +9 -9
- package/chunks/{chunk-5Q372OFJ.js → chunk-O4KNCAX4.js} +57 -10
- package/chunks/{chunk-GOXKNSDZ.js → chunk-O5CD7T4T.js} +40 -9
- package/chunks/{chunk-XIQ5HQ2F.js → chunk-OBTWL6ZW.js} +1 -1
- package/chunks/{chunk-PDQGMSZK.js → chunk-ODZF64DM.js} +1 -1
- package/chunks/{chunk-5MK45KZ3.js → chunk-OHOO527W.js} +1 -1
- package/chunks/{chunk-36LGBEM6.js → chunk-OHU2H5CS.js} +1 -1
- package/chunks/{chunk-JB4JIVTJ.js → chunk-OKTNXDVO.js} +1 -1
- package/chunks/{chunk-CETB5XY4.js → chunk-ORFIYTI2.js} +1 -1
- package/chunks/{chunk-7E7UCJHS.js → chunk-OSHQMOBS.js} +18 -17
- package/chunks/chunk-OSSTATJF.js +1310 -0
- package/chunks/chunk-P6UIF2OW.js +400 -0
- package/chunks/{chunk-U54AYGEC.js → chunk-PB7JBAHF.js} +15 -49
- package/chunks/{chunk-Y5S7LBOZ.js → chunk-PCRBLMIN.js} +17 -3
- package/chunks/{chunk-WAOIHTJS.js → chunk-PDAKFU7M.js} +1 -1
- package/chunks/{chunk-YTDVNSUQ.js → chunk-QAK5475D.js} +1 -1
- package/chunks/{chunk-ST5MDGH3.js → chunk-QI27MKNQ.js} +27 -19
- package/chunks/{chunk-MK2GIB46.js → chunk-QJGYU5PG.js} +1 -1
- package/chunks/{chunk-SMPR7SPO.js → chunk-QJNDUTOL.js} +45 -239
- package/chunks/{chunk-MQM5PJML.js → chunk-QJVZLILI.js} +1 -1
- package/chunks/{chunk-B5PHIJGI.js → chunk-QKDNS6FU.js} +2 -2
- package/chunks/{chunk-ZU4UDIWX.js → chunk-QQD2GART.js} +15 -9
- package/chunks/{chunk-62GQFYID.js → chunk-RAFQIHN2.js} +3 -3
- package/chunks/{chunk-MO3FC2WT.js → chunk-RJUVTJEZ.js} +1 -1
- package/chunks/{chunk-M6FOJXW3.js → chunk-RKW36UWC.js} +1 -1
- package/chunks/{chunk-GBJBJ4HX.js → chunk-RM4WT2XB.js} +4 -26
- package/chunks/{chunk-VGIFXISB.js → chunk-RN3YGDCA.js} +7 -5
- package/chunks/{chunk-DYXFD5RO.js → chunk-S2T7H5MI.js} +1 -1
- package/chunks/{chunk-FTF2YIZ5.js → chunk-S6H3ELPG.js} +1 -1
- package/chunks/{chunk-4NDLQAY2.js → chunk-SI7WDR3U.js} +524 -16
- package/chunks/{chunk-2YOHKHYR.js → chunk-SRF4KTAG.js} +6 -6
- package/chunks/{chunk-ZZMSC3RG.js → chunk-STCVJXQB.js} +24 -24
- package/chunks/{chunk-ST5V3ZOC.js → chunk-SULZPKTA.js} +3 -3
- package/chunks/{chunk-6X7EU5TI.js → chunk-SX2QIMJV.js} +9 -7
- package/chunks/{chunk-V5J4J5TP.js → chunk-TJYRTS4S.js} +2 -20
- package/chunks/{chunk-C3PEFRKD.js → chunk-TMKTOTMQ.js} +5 -5
- package/chunks/{chunk-ISKH4QX3.js → chunk-TQHPVKO6.js} +4 -4
- package/chunks/{chunk-HVC3PNVC.js → chunk-TSZSGQ3N.js} +1 -1
- package/chunks/{chunk-ICURCKIU.js → chunk-U4DJ5XB3.js} +594 -91
- package/chunks/{chunk-TTX2JUE6.js → chunk-U6D2PPMN.js} +1 -1
- package/chunks/{chunk-GVIVASYK.js → chunk-UAKRDON5.js} +4 -4
- package/chunks/{chunk-D5LUXLUH.js → chunk-UJ4DUYIH.js} +18 -4
- package/chunks/{chunk-VTHREBQM.js → chunk-UKYXYWI2.js} +2 -2
- package/chunks/{chunk-ZYMLPEZQ.js → chunk-UM2FFKXN.js} +3 -3
- package/chunks/{chunk-2OBKDPZZ.js → chunk-UPFRILIL.js} +2 -2
- package/chunks/{chunk-2HYKTO7V.js → chunk-UUASLXHW.js} +55 -6
- package/chunks/chunk-V5U2NZNJ.js +29 -0
- package/chunks/{chunk-P5Y23G2L.js → chunk-V7RNNPGC.js} +1 -18
- package/chunks/{chunk-Q2MSPKIJ.js → chunk-VBWD6C27.js} +1 -1
- package/chunks/chunk-VGHZT6JR.js +51 -0
- package/chunks/{chunk-MPNBVAEU.js → chunk-VNAYZAFX.js} +4 -4
- package/chunks/chunk-VPSIC437.js +780 -0
- package/chunks/{chunk-AIAOIFY4.js → chunk-VWTSRH6C.js} +92 -17
- package/chunks/{chunk-4K7KNVWH.js → chunk-VYIUNFEA.js} +3 -3
- package/chunks/{chunk-EQSBPBZ3.js → chunk-WP4AX3XD.js} +5 -7
- package/chunks/{chunk-BFPESSTR.js → chunk-XEAAO654.js} +1 -1
- package/chunks/{chunk-RU7BK6B3.js → chunk-XLXAZLDR.js} +3 -3
- package/chunks/{chunk-EFWRMA2I.js → chunk-YPWZTR7F.js} +3 -3
- package/chunks/{chunk-XF63PKEN.js → chunk-ZDFQGHZH.js} +1 -1
- package/chunks/{chunk-OZ6KS6KW.js → chunk-ZGCKTAL5.js} +6 -1
- package/chunks/chunk-ZHO2CW6D.js +205 -0
- package/chunks/chunk-ZJ2LM2SI.js +198 -0
- package/chunks/{chunk-AYFA7MZV.js → chunk-ZKFTS3OV.js} +6 -6
- package/chunks/{chunk-HMJ2P3SV.js → chunk-ZL4HFSL6.js} +91 -29
- package/chunks/{chunk-DJECZIJX.js → chunk-ZTPGUFQV.js} +30 -8
- package/chunks/{chunk-7EQQR46F.js → chunk-ZVP4PWBU.js} +1 -1
- package/chunks/chunk-bdqvmfwv-ZTSOWAFE.js +17446 -0
- package/chunks/config-utils-LVSYDLHZ.js +114 -0
- package/chunks/contextCommand-TZD7UAJK.js +107 -0
- package/chunks/{core-runtime-AXB6SK5D.js → core-runtime-B4UKKIAQ.js} +63 -62
- package/chunks/{create-sub-session-23ITIELI.js → create-sub-session-LUPWEUHR.js} +3 -3
- package/chunks/{create-sub-session-4QNE64MR.js → create-sub-session-NJ24B4US.js} +94 -66
- package/chunks/{cron-create-KJ4IY6PP.js → cron-create-CRSPET3H.js} +4 -4
- package/chunks/{cron-delete-MBLQCAYY.js → cron-delete-DB77SZTU.js} +4 -4
- package/chunks/{cron-list-DWH2PQ47.js → cron-list-U2JNYWV6.js} +4 -4
- package/chunks/{daemon-3GNHB3M2.js → daemon-RKDGBFLK.js} +613 -102
- package/chunks/{daemon-git-worktree-guard-IVAJJWYK.js → daemon-git-worktree-guard-O2HPOBAB.js} +62 -61
- package/chunks/daemon-status-provider-GRRVCJFW.js +117 -0
- package/chunks/daemon-trust-policy-YJL442BK.js +113 -0
- package/chunks/{daemon-trust-policy-monitor-KGGROSIV.js → daemon-trust-policy-monitor-JL7F4Y4Q.js} +68 -67
- package/chunks/{de-X6HLSIFE.js → de-T4BLOKEC.js} +3 -0
- package/chunks/deferred-core-runtime-S32AYVZI.js +115 -0
- package/chunks/{devtools-JCG4K2NZ.js → devtools-VDRJYPZF.js} +1 -1
- package/chunks/{discovery-X2NV535U.js → discovery-TUM3ZQ6U.js} +2 -2
- package/chunks/{display-image-BE7I6ZB6.js → display-image-73C7XNRK.js} +5 -5
- package/chunks/{dist-LVZCXVPF.js → dist-62OZ7QXB.js} +44 -26
- package/chunks/{dist-GFN5DCBX.js → dist-EDHQIBYD.js} +152 -63
- package/chunks/{dist-N6W6E753.js → dist-GT64AAUR.js} +135 -26
- package/chunks/{dist-6BPYWHVD.js → dist-JVXT4VUJ.js} +14 -7
- package/chunks/{dist-4WXLCBDR.js → dist-L6URO6CK.js} +12 -5
- package/chunks/{dist-5VXFRTWU.js → dist-LXFYIJNG.js} +866 -172
- package/chunks/{dist-SWQMYP2Q.js → dist-PDGNRVPY.js} +27 -8
- package/chunks/{dist-NSV4NBPK.js → dist-QAF5DO3Y.js} +380 -83
- package/chunks/{dist-HZNT6GQS.js → dist-ZCJLKQSP.js} +28 -14
- package/chunks/earlyInputCapture-BBPCIVZG.js +108 -0
- package/chunks/{edit-LEQLAGPZ.js → edit-SUGXY63Y.js} +47 -47
- package/chunks/{en-YLXBXM4Z.js → en-2RATMNX7.js} +5 -0
- package/chunks/{enter-worktree-35QCAAFP.js → enter-worktree-B6USKSIK.js} +7 -7
- package/chunks/{enterPlanMode-ONQN3WHE.js → enterPlanMode-MDX4RVVL.js} +48 -48
- package/chunks/{environment-UANTR7A4.js → environment-VN6RXDVN.js} +63 -62
- package/chunks/errors-UEY36PIT.js +114 -0
- package/chunks/{exit-worktree-XQD6D543.js → exit-worktree-DLQ73SJH.js} +10 -8
- package/chunks/exitPlanMode-EPHIEDAA.js +83 -0
- package/chunks/{fast-path-WUL7UZ6H.js → fast-path-Y73R42LV.js} +8 -7
- package/chunks/{fast-path-settings-XH426LUU.js → fast-path-settings-MFUR3IWK.js} +3 -3
- package/chunks/{fr-FTZWF462.js → fr-BGHGYX6A.js} +3 -0
- package/chunks/{glob-Y54QUWDY.js → glob-DMGH7EZN.js} +47 -47
- package/chunks/goal-tools-3RF3PXCL.js +99 -0
- package/chunks/{grep-5GPICQBU.js → grep-AJVLCVXC.js} +9 -7
- package/chunks/handleAutoUpdate-HVWQT2AU.js +110 -0
- package/chunks/i18n-5OR7NTRZ.js +125 -0
- package/chunks/{image-gen-J6FDGUZP.js → image-gen-VOIDOHOB.js} +8 -8
- package/chunks/initializer-JE5RQSOE.js +114 -0
- package/chunks/installationInfo-KO3CCSCK.js +108 -0
- package/chunks/{ja-2GL5FKYJ.js → ja-G3FTD5XE.js} +3 -0
- package/chunks/{keychain-token-storage-37XPR34V.js → keychain-token-storage-REZVMJA6.js} +2 -2
- package/chunks/list-3IORSFIY.js +117 -0
- package/chunks/list-agents-SBMONIUK.js +128 -0
- package/chunks/{llm-NSAVK5V3.js → llm-K26SUDVK.js} +223 -140
- package/chunks/{llm-content-generator-AY2QKXHE.js → llm-content-generator-TT6EAUD4.js} +11 -12
- package/chunks/loadedSettingsAdapter-KLLFZF3M.js +111 -0
- package/chunks/{loggingContentGenerator-DSFQHXIF.js → loggingContentGenerator-EYQBA4M4.js} +66 -65
- package/chunks/{loop-wakeup-XJFONSQ7.js → loop-wakeup-QA6SHCZT.js} +5 -5
- package/chunks/{ls-3VAT2J7A.js → ls-HEJNCEYO.js} +4 -4
- package/chunks/{lsp-5W7IRUBH.js → lsp-WOQKNZP6.js} +2 -2
- package/chunks/{managed-npm-update-TSWENTK5.js → managed-npm-update-HIJTODQT.js} +61 -60
- package/chunks/mcp-A2UEHETW.js +111 -0
- package/chunks/{monitor-RW4GWJHB.js → monitor-DKNZQAB2.js} +46 -46
- package/chunks/{node-QKLNSZMX.js → node-UETAYMMO.js} +3 -3
- package/chunks/nonInteractiveCli-YA47F2F4.js +190 -0
- package/chunks/{notebook-edit-CQNYS5OR.js → notebook-edit-MGHTRL2D.js} +47 -47
- package/chunks/{open-with-auth-YN3QZHVM.js → open-with-auth-D6JD6LDS.js} +3 -3
- package/chunks/{openaiContentGenerator-J6QIF7EX.js → openaiContentGenerator-ZJIEQ3ZJ.js} +26 -28
- package/chunks/pidfile-ETHAZNMY.js +112 -0
- package/chunks/{processUtils-GPHNANKZ.js → processUtils-UY3SAJJZ.js} +2 -2
- package/chunks/prompt-terminal-ledger-GZ747VYE.js +106 -0
- package/chunks/{pt-XN2YWJVM.js → pt-D73IFYT7.js} +3 -0
- package/chunks/{qwenContentGenerator-WWDXPYQI.js → qwenContentGenerator-VI4KATRY.js} +58 -58
- package/chunks/{qwenOAuth2-OF5WRBQT.js → qwenOAuth2-7AOCKSOQ.js} +7 -7
- package/chunks/{read-file-FQUQHC6N.js → read-file-P7F4P7LV.js} +11 -13
- package/chunks/{read-mcp-resource-XD257PGJ.js → read-mcp-resource-GLAGB6R7.js} +2 -2
- package/chunks/{record-artifact-VW23GS4F.js → record-artifact-SWVR7NSU.js} +4 -4
- package/chunks/renderer-selection-M4UN63VJ.js +99 -0
- package/chunks/{report-findings-AO5VYFLR.js → report-findings-AL5YW3KI.js} +5 -5
- package/chunks/{request-shutdown-BCLA3JV2.js → request-shutdown-5YK4IZ54.js} +8 -7
- package/chunks/resumeHistoryUtils-DPZKFW24.js +119 -0
- package/chunks/ripGrep-C7LJKUPZ.js +37 -0
- package/chunks/{ru-OLTMFJEW.js → ru-QMISLKRH.js} +3 -0
- package/chunks/{run-qwen-serve-5X6IDZER.js → run-qwen-serve-OGTEEUR2.js} +589 -251
- package/chunks/{runtime-HK27GMPF.js → runtime-LNBLEMZS.js} +73 -72
- package/chunks/scheduled-tasks-FLDYZQOF.js +128 -0
- package/chunks/{scheduler-WD4MHMO5.js → scheduler-73YXGUGW.js} +62 -61
- package/chunks/{sdk-exporters-grpc-G5IT4XS4.js → sdk-exporters-grpc-MXTVSE3C.js} +2 -2
- package/chunks/{sdk-exporters-http-TTU2CHBU.js → sdk-exporters-http-3JO5TJNU.js} +4 -4
- package/chunks/{sdk-impl-UUMVYMAL.js → sdk-impl-HZAUUTHJ.js} +6 -6
- package/chunks/{send-message-AJ4OCUBV.js → send-message-JC7NJTY6.js} +166 -35
- package/chunks/serve-3UR2H4CV.js +119 -0
- package/chunks/{server-GO2N5DH7.js → server-AOYZVVOM.js} +2904 -860
- package/chunks/{session-IFNHTUBT.js → session-UAWFNFGI.js} +119 -114
- package/chunks/session-attachments-root-ZCGXQQTR.js +104 -0
- package/chunks/{session-pr-refresh-I3UBWMVP.js → session-pr-refresh-CT2INROL.js} +157 -88
- package/chunks/{settings-L6N54CU6.js → settings-BHRGDASJ.js} +67 -66
- package/chunks/{shell-4Y5LLW6N.js → shell-YHOGC7TO.js} +46 -46
- package/chunks/{skill-YOWTRAKQ.js → skill-ZGBKNCHQ.js} +131 -97
- package/chunks/skill-settings-AKSP665O.js +119 -0
- package/chunks/spawnChannel-N25MBB6F.js +112 -0
- package/chunks/standalone-update-XGPWJDRN.js +119 -0
- package/chunks/start-opentui-ui-FZ4USOU7.js +55342 -0
- package/chunks/{startInteractiveUI-XDFSHBZD.js → startInteractiveUI-E2WQJUOA.js} +3509 -4706
- package/chunks/{syntheticOutput-ML43GEFN.js → syntheticOutput-HJNZSEHN.js} +3 -3
- package/chunks/{task-create-QN4LYRSE.js → task-create-6RSD54S5.js} +12 -12
- package/chunks/{task-list-JPLGK45U.js → task-list-IQSACPOM.js} +34 -11
- package/chunks/{task-stop-CXEH5L2D.js → task-stop-HE2LRQNW.js} +2 -2
- package/chunks/{task-update-IWEOJFV2.js → task-update-XAJ2NYOA.js} +13 -14
- package/chunks/{team-create-OOPXCDBA.js → team-create-SOKMYSQU.js} +54 -55
- package/chunks/{team-delete-RZVVSGCY.js → team-delete-NGNNKGMG.js} +25 -8
- package/chunks/{team-plan-approval-DSX5EWAT.js → team-plan-approval-U7ZWXYAY.js} +46 -46
- package/chunks/terminal-image-renderer-KKM4OBLO.js +117 -0
- package/chunks/theme-manager-GQHF3A7T.js +103 -0
- package/chunks/{todoWrite-WDJNQEMW.js → todoWrite-5UTVUXHA.js} +39 -9
- package/chunks/{tool-search-J5Q6U7DN.js → tool-search-IAI2RVWT.js} +21 -19
- package/chunks/total-session-admission-G4CGCSTG.js +113 -0
- package/chunks/trustedFolders-D2I3FDPB.js +123 -0
- package/chunks/{update-relaunch-SIKHLHVR.js → update-relaunch-5RWKZAL3.js} +5 -5
- package/chunks/updateCheck-ZXOQDFEI.js +119 -0
- package/chunks/useAutoAcceptIndicator-6EK4QGAH.js +121 -0
- package/chunks/{validateNonInterActiveAuth-JUDQP6V4.js → validateNonInterActiveAuth-QPFEKATS.js} +113 -109
- package/chunks/{version-C63GDDWN.js → version-JKNG7YDH.js} +1 -1
- package/chunks/{web-fetch-FOQZMNSC.js → web-fetch-X3AHIIHW.js} +16 -19
- package/chunks/{web-search-PUJTBFUC.js → web-search-K2FMOGS5.js} +10 -11
- package/chunks/{web-shell-static-HNB4FDOE.js → web-shell-static-POZHGGXE.js} +5 -4
- package/chunks/{workflow-Y5IPINVH.js → workflow-TOLPAK5G.js} +213 -119
- package/chunks/workspace-providers-status-PCJK3RC7.js +115 -0
- package/chunks/{workspace-registration-store-SMJWI2AI.js → workspace-registration-store-KQWVVW4Y.js} +2 -1
- package/chunks/workspace-registry-YNIOB6HJ.js +122 -0
- package/chunks/workspace-runtime-coordinator-WG2RNEN7.js +123 -0
- package/chunks/workspace-service-G4ZNBOFH.js +127 -0
- package/chunks/workspace-skills-status-FMTPPMWC.js +114 -0
- package/chunks/{workspace-trust-reconciler-PLIDLJZX.js → workspace-trust-reconciler-IBDFQBQS.js} +76 -77
- package/chunks/wrapper-JH3IFHT2.js +35 -0
- package/chunks/write-file-YTLFY2S5.js +88 -0
- package/chunks/{zh-UNY63FR3.js → zh-25DF7OGK.js} +5 -0
- package/chunks/{zh-TW-RPTMRTHG.js → zh-TW-5EDMZVGK.js} +5 -0
- package/chunks/{zoom-image-LYQD7BQA.js → zoom-image-IFXSN74N.js} +11 -13
- package/cli.js +131 -90
- package/locales/ca.js +6 -0
- package/locales/de.js +6 -0
- package/locales/en.js +9 -0
- package/locales/fr.js +6 -0
- package/locales/ja.js +6 -0
- package/locales/pt.js +6 -0
- package/locales/ru.js +6 -0
- package/locales/zh-TW.js +9 -0
- package/locales/zh.js +9 -0
- package/package.json +3 -3
- package/web-shell/assets/{abnfDiagram-VCTEODGH-TRCMSA_6.js → abnfDiagram-VCTEODGH-Cxf7xE_Z.js} +1 -1
- package/web-shell/assets/{arc-D9Uls5b3.js → arc-ESi1eNkE.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-Bwb8jPXg.js → architectureDiagram-5GKGNRK7-D9l7-bDo.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-DHj71TSX.js → blockDiagram-NRAW4CY4-Bc8DEasw.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-uKBBdbyr.js → c4Diagram-UCG6FXSJ-Dimb2Hmh.js} +1 -1
- package/web-shell/assets/channel-B7ohGDil.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-BZd0Phrl.js → chunk-2Q5K7J3B-jVDmOpAQ.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-7KNeNBqN.js → chunk-5VM5RSS4-DbG_SwdB.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-BeboS7Fi.js → chunk-F27PBJKO-QEc4cY1v.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-RV3JONoj.js → chunk-G27WJ6UU-iJ36lQ3X.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-Yw9FCFsP.js → chunk-JWPE2WC7-DuArnVtF.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-GIMnydDe.js → chunk-LCL6LL3I-DxOf1zwL.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-Cfrux7bL.js → chunk-POPQ4Y6H-lVLu9Ild.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-BlvIN0CO.js → chunk-SVP7TREG-C6XYlIer.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-DMs7Rr4t.js → chunk-XXDRQBXY-CiG2j2Ji.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DdFpqpfD.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DdFpqpfD.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-DNGqTNwI.js → cose-bilkent-JH36ORCC-DGVHMMVm.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-CojMpaoH.js → cynefin-OW5HDTMX-D6cgpCnH.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-DF07YXGo.js → cynefinDiagram-5FMLGOSQ-BKv4Z-UX.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-17-4WtCH.js → dagre-3AP2YEHR-B4ABMIG-.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-G3Wuyz9m.js → diagram-S7CK7UJ4-DgCkp_Lm.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-nyWIKZ8P.js → diagram-UQ7AKVKN-FG0FNokz.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-tKHhmYSC.js → diagram-VSXAHHWV-JgkP9qg-.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-CpDf1hYk.js → diagram-VX7I27RA-ADh2x83l.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-Cah2IFXG.js → diagram-Z3DM3KII-yXqoYF1J.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-DNaCkgxy.js → ebnfDiagram-PWID7BFC-Duk83Ek_.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-CAdRgcf1.js → erDiagram-SSCWMZ5O-DMdvxySG.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-CMUJAShL.js → flowDiagram-A5DVABFB-DHjVgSji.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-o-_MUNey.js → ganttDiagram-EL5Y4UJY-DMM9DkCE.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-_aG-2Z7O.js → gitGraphDiagram-WWUBYQGX-t_ug9vO8.js} +1 -1
- package/web-shell/assets/index-BGZRqbRo.css +36 -0
- package/web-shell/assets/index-DRri_6_x.js +2067 -0
- package/web-shell/assets/{index-BK_NKxiJ.js → index-zqvnpGHv.js} +1 -1
- package/web-shell/assets/{infoDiagram-RXCK75RN-qJPeZbGP.js → infoDiagram-RXCK75RN-eT1fANNm.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-7Om4vNo1.js → ishikawaDiagram-5VMMS53U-k3evzZNn.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-BNtXqmBW.js → journeyDiagram-EYS64GPL-CGim3EAi.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-COgFec8P.js → kanban-definition-3QL26DDD-WHfJo-22.js} +1 -1
- package/web-shell/assets/{layout-B9n81PC9.js → layout-DkqIaFlJ.js} +1 -1
- package/web-shell/assets/{linear-Bb6nXZQq.js → linear-Bdkd3mCz.js} +1 -1
- package/web-shell/assets/{mermaid.core-Cgrm3JVT.js → mermaid.core-CGw0LkT_.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-TKwLTjnG.js → mindmap-definition-FBJOCRG2-C9V4rBvo.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-BJPuvlpi.js → pegDiagram-XKGWAZYB-CwoI2T5G.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-D01VkNsW.js → pieDiagram-E7YTZNPT-DaTmBmPG.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-C4hHsiv-.js → quadrantDiagram-AXDQQJYC-plh6MyGI.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-CuEO4xK2.js → railroadDiagram-O6MQD6OU-D_b-S0iK.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-D5J_vIo5.js → requirementDiagram-EFPCY7ZU-zUzTN7VE.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-DQKY223V.js → sankeyDiagram-P5KCCOFB-m6AhoD0l.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-D27YV_cm.js → sequenceDiagram-WJ2MYXX4-Cwhzsine.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-TJg8UcwV.js → sizeCapture-X5ZJPWSS-CcZuKIae.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-CmnPzUIx.js → stateDiagram-HBIQ2CUA-CFoiJwD_.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V--H8HdEmk.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-ByeP3_Nu.js → swimlanes-XN3QIQJK-CgS9hcaV.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ShE9OIgf.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-BsFA5juR.js → timeline-definition-24CTP7MA-Dzzc05t9.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-DREP2ECo.js → vennDiagram-4TSXK5OY-DemK0f7Y.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-iyd9lKi2.js → wardleyDiagram-VM6X3IG4-CquLxtMr.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-CVr1_j9q.js → xychartDiagram-S5SC5T6Z-BTBKTM5g.js} +1 -1
- package/web-shell/index.html +196 -2
- package/chunks/MaxSizedBox-X42SXBJH.js +0 -110
- package/chunks/agent-headless-IZM25LJA.js +0 -85
- package/chunks/bridge-ME6QXZNA.js +0 -119
- package/chunks/channel-settings-store-PEOI7XCG.js +0 -120
- package/chunks/chunk-7J6OTNGO.js +0 -424
- package/chunks/chunk-BWORX6FA.js +0 -135
- package/chunks/chunk-CPBF7KYF.js +0 -51
- package/chunks/chunk-H72BQNM3.js +0 -645
- package/chunks/chunk-JHYH6PYQ.js +0 -3096
- package/chunks/chunk-SS4MRMKE.js +0 -3525
- package/chunks/chunk-T4EFG2P5.js +0 -113
- package/chunks/chunk-XZA32HII.js +0 -19
- package/chunks/chunk-ZYNTSXWK.js +0 -32
- package/chunks/config-utils-R6M3TA34.js +0 -113
- package/chunks/contextCommand-ZCAP23J6.js +0 -106
- package/chunks/daemon-status-provider-K3SJ5C2U.js +0 -117
- package/chunks/daemon-trust-policy-DOR3YG62.js +0 -112
- package/chunks/deferred-core-runtime-WOYLUQQ7.js +0 -114
- package/chunks/earlyInputCapture-OHBEVO4K.js +0 -107
- package/chunks/errors-WAK6KFBC.js +0 -113
- package/chunks/exitPlanMode-UEYBG6P5.js +0 -83
- package/chunks/goal-tools-PTD3MBA7.js +0 -411
- package/chunks/handleAutoUpdate-FP3NWNSG.js +0 -109
- package/chunks/i18n-INIU5X7A.js +0 -124
- package/chunks/initializer-TYODV6GE.js +0 -113
- package/chunks/installationInfo-AAPKYDSZ.js +0 -107
- package/chunks/list-TUODDN6J.js +0 -116
- package/chunks/list-agents-DI3YFTDT.js +0 -80
- package/chunks/loadedSettingsAdapter-KJCLZ3C4.js +0 -110
- package/chunks/mcp-MWSAPFOL.js +0 -110
- package/chunks/nonInteractiveCli-JXKL343Q.js +0 -185
- package/chunks/pidfile-QOIQZFT2.js +0 -111
- package/chunks/prompt-terminal-ledger-FOMFTYOM.js +0 -105
- package/chunks/resumeHistoryUtils-NSGF3UCB.js +0 -118
- package/chunks/ripGrep-4CAT6SKV.js +0 -39
- package/chunks/scheduled-tasks-MN2ZZ5P6.js +0 -127
- package/chunks/serve-2XCHPPGG.js +0 -118
- package/chunks/skill-settings-ZL4JY5UE.js +0 -118
- package/chunks/spawnChannel-ZST6XJVJ.js +0 -112
- package/chunks/standalone-update-THVU3OKY.js +0 -118
- package/chunks/terminal-image-renderer-KS25G33E.js +0 -114
- package/chunks/theme-manager-YMZNG45F.js +0 -102
- package/chunks/total-session-admission-PVN64JVV.js +0 -114
- package/chunks/trustedFolders-FATSC4YI.js +0 -122
- package/chunks/updateCheck-D3YG2WCD.js +0 -118
- package/chunks/useAutoAcceptIndicator-ILINOSAS.js +0 -120
- package/chunks/workspace-providers-status-IJ4VHFMB.js +0 -114
- package/chunks/workspace-registry-BTGZIMPK.js +0 -123
- package/chunks/workspace-service-SIN67ITC.js +0 -126
- package/chunks/workspace-skills-status-F3RKCUIX.js +0 -113
- package/chunks/write-file-PAIGB33C.js +0 -88
- package/web-shell/assets/channel-CXjVLaBa.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DANEijO3.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DANEijO3.js +0 -1
- package/web-shell/assets/index-Ci-z4zWY.js +0 -1913
- package/web-shell/assets/index-LDlXZRHA.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DNKPyrDc.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ZL1HPC6w.js +0 -8
- /package/chunks/{chunk-FOGQO4FG.js → chunk-JA5CBKRP.js} +0 -0
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
require_dist,
|
|
5
5
|
require_follow_redirects,
|
|
6
6
|
require_form_data
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-OBTWL6ZW.js";
|
|
8
8
|
import "./chunk-K6KS3LTN.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-OSHQMOBS.js";
|
|
10
10
|
import {
|
|
11
11
|
ChannelBase,
|
|
12
12
|
isTerminalTaskLifecycleType,
|
|
@@ -14,14 +14,14 @@ import {
|
|
|
14
14
|
sanitizePromptText,
|
|
15
15
|
sanitizeSenderName,
|
|
16
16
|
truncateUtf16Units
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-U4DJ5XB3.js";
|
|
18
18
|
import "./chunk-IW6RQPQB.js";
|
|
19
19
|
import "./chunk-CQ35AJ4Z.js";
|
|
20
20
|
import "./chunk-DMTGGOSA.js";
|
|
21
21
|
import "./chunk-YQ3U5MUC.js";
|
|
22
22
|
import {
|
|
23
23
|
wrapper_default
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-J5TTWBZK.js";
|
|
25
25
|
import "./chunk-RVIGZBIT.js";
|
|
26
26
|
import {
|
|
27
27
|
init_esbuild_shims
|
|
@@ -39,8 +39,8 @@ init_esbuild_shims();
|
|
|
39
39
|
init_esbuild_shims();
|
|
40
40
|
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
41
41
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
42
|
-
import { basename as
|
|
43
|
-
import { tmpdir as
|
|
42
|
+
import { basename as basename3, join } from "node:path";
|
|
43
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
44
44
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
45
45
|
|
|
46
46
|
// node_modules/dingtalk-stream-sdk-nodejs/dist/index.mjs
|
|
@@ -5792,9 +5792,21 @@ var DWClient = class extends EventEmitter2 {
|
|
|
5792
5792
|
|
|
5793
5793
|
// packages/channels/dingtalk/dist/markdown.js
|
|
5794
5794
|
init_esbuild_shims();
|
|
5795
|
-
var
|
|
5796
|
-
function
|
|
5797
|
-
|
|
5795
|
+
var DINGTALK_CHUNK_LIMIT = 3800;
|
|
5796
|
+
function escapeDingTalkMarkdown(value) {
|
|
5797
|
+
return value.replace(/([\\`*_[\]{}()#+.!|>~:-])/gu, "\\$1");
|
|
5798
|
+
}
|
|
5799
|
+
__name(escapeDingTalkMarkdown, "escapeDingTalkMarkdown");
|
|
5800
|
+
function safeUtf16SliceEnd(value, end) {
|
|
5801
|
+
if (end <= 0 || end >= value.length)
|
|
5802
|
+
return end;
|
|
5803
|
+
const previous = value.charCodeAt(end - 1);
|
|
5804
|
+
const next = value.charCodeAt(end);
|
|
5805
|
+
return previous >= 55296 && previous <= 56319 && next >= 56320 && next <= 57343 ? end - 1 : end;
|
|
5806
|
+
}
|
|
5807
|
+
__name(safeUtf16SliceEnd, "safeUtf16SliceEnd");
|
|
5808
|
+
function splitChunks(text, chunkLimit = DINGTALK_CHUNK_LIMIT) {
|
|
5809
|
+
if (!text || text.length <= chunkLimit) {
|
|
5798
5810
|
return [text];
|
|
5799
5811
|
}
|
|
5800
5812
|
const chunks = [];
|
|
@@ -5814,11 +5826,15 @@ function splitChunks(text) {
|
|
|
5814
5826
|
let lineOpenedFenceInBuffer = false;
|
|
5815
5827
|
while (remaining.length > 0 || prefixPending) {
|
|
5816
5828
|
const prefix = prefixPending ? "\n" : "";
|
|
5817
|
-
const fitsAsFinalPiece = remaining.length <=
|
|
5829
|
+
const fitsAsFinalPiece = remaining.length <= chunkLimit - buf.length - prefix.length;
|
|
5818
5830
|
const closeFenceOverhead = inCode && !(closesCodeFence && fitsAsFinalPiece) || !inCode && leavesCodeFenceOpen ? "\n```".length : 0;
|
|
5819
|
-
const available =
|
|
5831
|
+
const available = chunkLimit - closeFenceOverhead - buf.length - prefix.length;
|
|
5820
5832
|
if (available <= 0) {
|
|
5821
|
-
|
|
5833
|
+
const keepCodeOpen = inCode || lineOpenedFenceInBuffer;
|
|
5834
|
+
if (buf === (keepCodeOpen ? "```" : "")) {
|
|
5835
|
+
throw new RangeError("chunk limit cannot contain one Unicode character");
|
|
5836
|
+
}
|
|
5837
|
+
flush(keepCodeOpen);
|
|
5822
5838
|
continue;
|
|
5823
5839
|
}
|
|
5824
5840
|
let pieceLength = Math.min(available, remaining.length);
|
|
@@ -5830,8 +5846,13 @@ function splitChunks(text) {
|
|
|
5830
5846
|
}
|
|
5831
5847
|
}
|
|
5832
5848
|
}
|
|
5849
|
+
pieceLength = safeUtf16SliceEnd(remaining, pieceLength);
|
|
5833
5850
|
if (pieceLength === 0 && remaining.length > 0) {
|
|
5834
|
-
|
|
5851
|
+
const keepCodeOpen = inCode || lineOpenedFenceInBuffer;
|
|
5852
|
+
if (!buf || keepCodeOpen && buf === "```") {
|
|
5853
|
+
throw new RangeError("chunk limit cannot contain one Unicode character");
|
|
5854
|
+
}
|
|
5855
|
+
flush(keepCodeOpen);
|
|
5835
5856
|
continue;
|
|
5836
5857
|
}
|
|
5837
5858
|
const piece = remaining.slice(0, pieceLength);
|
|
@@ -5868,8 +5889,8 @@ function extractTitle(text) {
|
|
|
5868
5889
|
return cleaned || "Reply";
|
|
5869
5890
|
}
|
|
5870
5891
|
__name(extractTitle, "extractTitle");
|
|
5871
|
-
function normalizeDingTalkMarkdown(text) {
|
|
5872
|
-
return splitChunks(text);
|
|
5892
|
+
function normalizeDingTalkMarkdown(text, chunkLimit = DINGTALK_CHUNK_LIMIT) {
|
|
5893
|
+
return splitChunks(text, chunkLimit);
|
|
5873
5894
|
}
|
|
5874
5895
|
__name(normalizeDingTalkMarkdown, "normalizeDingTalkMarkdown");
|
|
5875
5896
|
|
|
@@ -6156,8 +6177,15 @@ __name(uploadDingTalkImage, "uploadDingTalkImage");
|
|
|
6156
6177
|
|
|
6157
6178
|
// packages/channels/dingtalk/dist/outbound-file.js
|
|
6158
6179
|
init_esbuild_shims();
|
|
6180
|
+
import { closeSync as closeSync2, constants, fstatSync as fstatSync2, openSync as openSync2, readSync as readSync2, realpathSync as realpathSync2, statSync } from "node:fs";
|
|
6181
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
6182
|
+
import { basename as basename2, extname as extname2, isAbsolute as isAbsolute2, relative as relative2, sep } from "node:path";
|
|
6159
6183
|
var FILE_OPENING = "[FILE:";
|
|
6184
|
+
var MEDIA_UPLOAD_API2 = "https://oapi.dingtalk.com/media/upload";
|
|
6185
|
+
var MEDIA_UPLOAD_TIMEOUT_MS2 = 3e4;
|
|
6160
6186
|
var MAX_FILE_PATH_CHARS = 4096;
|
|
6187
|
+
var MAX_FILE_BYTES = 20 * 1024 * 1024;
|
|
6188
|
+
var AUTH_ERROR_CODES2 = /* @__PURE__ */ new Set([40014, 42001]);
|
|
6161
6189
|
var MAX_FILES_PER_RESPONSE = 5;
|
|
6162
6190
|
var FILE_UNAVAILABLE_NOTICE = "[File delivery unavailable]";
|
|
6163
6191
|
var OutboundFileProjector = class {
|
|
@@ -6256,6 +6284,104 @@ function withFileUnavailableNotice(text) {
|
|
|
6256
6284
|
return `${safe}${safe ? "\n" : ""}${FILE_UNAVAILABLE_NOTICE}`;
|
|
6257
6285
|
}
|
|
6258
6286
|
__name(withFileUnavailableNotice, "withFileUnavailableNotice");
|
|
6287
|
+
function safeFileName(filePath) {
|
|
6288
|
+
return basename2(filePath).replace(/[\p{Cc}\p{Cf}[\]]+/gu, "_").slice(0, 200) || "file";
|
|
6289
|
+
}
|
|
6290
|
+
__name(safeFileName, "safeFileName");
|
|
6291
|
+
function isInside2(filePath, directory) {
|
|
6292
|
+
const child = relative2(directory, filePath);
|
|
6293
|
+
return child === "" || !isAbsolute2(child) && child !== ".." && !child.startsWith(`..${sep}`);
|
|
6294
|
+
}
|
|
6295
|
+
__name(isInside2, "isInside");
|
|
6296
|
+
function readValidatedFile(filePath, workspaceDir) {
|
|
6297
|
+
if (!isAbsolute2(filePath))
|
|
6298
|
+
throw new Error("File path must be absolute");
|
|
6299
|
+
let realPath;
|
|
6300
|
+
try {
|
|
6301
|
+
realPath = realpathSync2(filePath);
|
|
6302
|
+
} catch {
|
|
6303
|
+
throw new Error("File not found");
|
|
6304
|
+
}
|
|
6305
|
+
const roots = [
|
|
6306
|
+
workspaceDir,
|
|
6307
|
+
tmpdir2(),
|
|
6308
|
+
...process.platform === "win32" ? [] : ["/tmp"]
|
|
6309
|
+
].map((root) => realpathSync2(root));
|
|
6310
|
+
if (!roots.some((root) => isInside2(realPath, root))) {
|
|
6311
|
+
throw new Error("File path outside allowed directories");
|
|
6312
|
+
}
|
|
6313
|
+
if (!statSync(realPath).isFile())
|
|
6314
|
+
throw new Error("Not a regular file");
|
|
6315
|
+
const descriptor = openSync2(realPath, constants.O_RDONLY | constants.O_NONBLOCK | (constants.O_NOFOLLOW ?? 0));
|
|
6316
|
+
try {
|
|
6317
|
+
const stats = fstatSync2(descriptor);
|
|
6318
|
+
if (!stats.isFile())
|
|
6319
|
+
throw new Error("Not a regular file");
|
|
6320
|
+
if (stats.size === 0)
|
|
6321
|
+
throw new Error("File is empty");
|
|
6322
|
+
if (stats.size > MAX_FILE_BYTES)
|
|
6323
|
+
throw new Error("File is too large");
|
|
6324
|
+
const data = Buffer.allocUnsafe(stats.size + 1);
|
|
6325
|
+
let bytesRead = 0;
|
|
6326
|
+
while (bytesRead < data.length) {
|
|
6327
|
+
const count = readSync2(descriptor, data, bytesRead, data.length - bytesRead, bytesRead);
|
|
6328
|
+
if (count === 0)
|
|
6329
|
+
break;
|
|
6330
|
+
bytesRead += count;
|
|
6331
|
+
}
|
|
6332
|
+
if (bytesRead !== stats.size)
|
|
6333
|
+
throw new Error("File changed while read");
|
|
6334
|
+
const fileName = safeFileName(realPath);
|
|
6335
|
+
return {
|
|
6336
|
+
data: data.subarray(0, bytesRead),
|
|
6337
|
+
fileName,
|
|
6338
|
+
fileType: extname2(fileName).slice(1).toLowerCase() || "file"
|
|
6339
|
+
};
|
|
6340
|
+
} finally {
|
|
6341
|
+
closeSync2(descriptor);
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
__name(readValidatedFile, "readValidatedFile");
|
|
6345
|
+
function sanitizeApiMessage2(message, accessToken) {
|
|
6346
|
+
const value = String(message ?? "");
|
|
6347
|
+
return (accessToken ? value.replaceAll(accessToken, "[redacted]") : value).replace(/[\r\n\t]+/g, " ").slice(0, 200);
|
|
6348
|
+
}
|
|
6349
|
+
__name(sanitizeApiMessage2, "sanitizeApiMessage");
|
|
6350
|
+
async function uploadDingTalkFile(file, accessToken) {
|
|
6351
|
+
const form = new FormData();
|
|
6352
|
+
form.append("media", new Blob([file.data], { type: "application/octet-stream" }), file.fileName);
|
|
6353
|
+
let response;
|
|
6354
|
+
try {
|
|
6355
|
+
const url2 = new URL(MEDIA_UPLOAD_API2);
|
|
6356
|
+
url2.searchParams.set("access_token", accessToken);
|
|
6357
|
+
url2.searchParams.set("type", "file");
|
|
6358
|
+
response = await fetch(url2, {
|
|
6359
|
+
method: "POST",
|
|
6360
|
+
body: form,
|
|
6361
|
+
signal: AbortSignal.timeout(MEDIA_UPLOAD_TIMEOUT_MS2)
|
|
6362
|
+
});
|
|
6363
|
+
} catch {
|
|
6364
|
+
throw new DingTalkMediaUploadError("DingTalk file upload failed: network request failed", false);
|
|
6365
|
+
}
|
|
6366
|
+
let payload;
|
|
6367
|
+
try {
|
|
6368
|
+
const parsed = await response.json();
|
|
6369
|
+
payload = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
6370
|
+
} catch {
|
|
6371
|
+
throw new DingTalkMediaUploadError(`DingTalk file upload failed: HTTP ${response.status} invalid JSON response`, response.status === 401);
|
|
6372
|
+
}
|
|
6373
|
+
const errcode = typeof payload["errcode"] === "number" ? payload["errcode"] : void 0;
|
|
6374
|
+
if (!response.ok || errcode !== void 0 && errcode !== 0) {
|
|
6375
|
+
const detail = sanitizeApiMessage2(payload["errmsg"], accessToken);
|
|
6376
|
+
throw new DingTalkMediaUploadError(`DingTalk file upload failed: HTTP ${response.status}${errcode === void 0 ? "" : ` errcode=${errcode}`}${detail ? ` ${detail}` : ""}`, response.status === 401 || errcode !== void 0 && AUTH_ERROR_CODES2.has(errcode));
|
|
6377
|
+
}
|
|
6378
|
+
const mediaId = typeof payload["media_id"] === "string" ? payload["media_id"] : typeof payload["mediaId"] === "string" ? payload["mediaId"] : void 0;
|
|
6379
|
+
if (!mediaId) {
|
|
6380
|
+
throw new DingTalkMediaUploadError("DingTalk file upload failed: response did not include a MediaID", false);
|
|
6381
|
+
}
|
|
6382
|
+
return mediaId;
|
|
6383
|
+
}
|
|
6384
|
+
__name(uploadDingTalkFile, "uploadDingTalkFile");
|
|
6259
6385
|
|
|
6260
6386
|
// packages/channels/dingtalk/dist/DingtalkConnectionManager.js
|
|
6261
6387
|
init_esbuild_shims();
|
|
@@ -6569,6 +6695,25 @@ var STATUS_CARD_TEMPLATE_ID = "675cde2f-f526-40cb-b828-f5b2b57b8b77.schema";
|
|
|
6569
6695
|
var QUESTION_CARD_TEMPLATE_ID = "c2a6355b-9724-4f7e-9653-d33fcb3311bb.schema";
|
|
6570
6696
|
var DINGTALK_API = "https://api.dingtalk.com";
|
|
6571
6697
|
var CARD_FETCH_TIMEOUT_MS = 1e4;
|
|
6698
|
+
function isRetryableStatus(status) {
|
|
6699
|
+
return status === 408 || status === 425 || status === 429 || status >= 500 && status <= 599;
|
|
6700
|
+
}
|
|
6701
|
+
__name(isRetryableStatus, "isRetryableStatus");
|
|
6702
|
+
var DingtalkCardRequestError = class extends Error {
|
|
6703
|
+
static {
|
|
6704
|
+
__name(this, "DingtalkCardRequestError");
|
|
6705
|
+
}
|
|
6706
|
+
retryable;
|
|
6707
|
+
constructor(message, retryable) {
|
|
6708
|
+
super(message);
|
|
6709
|
+
this.retryable = retryable;
|
|
6710
|
+
this.name = "DingtalkCardRequestError";
|
|
6711
|
+
}
|
|
6712
|
+
};
|
|
6713
|
+
function isRetryableDingtalkCardError(error) {
|
|
6714
|
+
return !(error instanceof DingtalkCardRequestError) || error.retryable;
|
|
6715
|
+
}
|
|
6716
|
+
__name(isRetryableDingtalkCardError, "isRetryableDingtalkCardError");
|
|
6572
6717
|
function stringifyCardParamMap(cardParamMap) {
|
|
6573
6718
|
return Object.fromEntries(Object.entries(cardParamMap).map(([key, value]) => [
|
|
6574
6719
|
key,
|
|
@@ -6617,7 +6762,7 @@ var DingtalkInteractiveCardClient = class {
|
|
|
6617
6762
|
if (Array.isArray(deliveries)) {
|
|
6618
6763
|
const failure = deliveries.find((entry) => entry !== null && typeof entry === "object" && entry.success === false);
|
|
6619
6764
|
if (failure) {
|
|
6620
|
-
throw new
|
|
6765
|
+
throw new DingtalkCardRequestError(`${input.templateId}: ${typeof failure.errorMsg === "string" && failure.errorMsg.trim() ? failure.errorMsg.trim() : "DingTalk card delivery failed"}`, false);
|
|
6621
6766
|
}
|
|
6622
6767
|
}
|
|
6623
6768
|
}
|
|
@@ -6642,21 +6787,28 @@ var DingtalkInteractiveCardClient = class {
|
|
|
6642
6787
|
});
|
|
6643
6788
|
}
|
|
6644
6789
|
async request(path, method, body, templateId) {
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
6649
|
-
|
|
6650
|
-
|
|
6651
|
-
|
|
6652
|
-
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6790
|
+
for (let attempt = 0; ; attempt++) {
|
|
6791
|
+
const token = await this.options.getAccessToken();
|
|
6792
|
+
const response = await this.fetch(`${DINGTALK_API}${path}`, {
|
|
6793
|
+
method,
|
|
6794
|
+
headers: {
|
|
6795
|
+
"Content-Type": "application/json",
|
|
6796
|
+
"x-acs-dingtalk-access-token": token
|
|
6797
|
+
},
|
|
6798
|
+
body: JSON.stringify(body),
|
|
6799
|
+
signal: AbortSignal.timeout(CARD_FETCH_TIMEOUT_MS)
|
|
6800
|
+
});
|
|
6801
|
+
if (response.status === 401 && attempt === 0) {
|
|
6802
|
+
this.options.invalidateAccessToken(token);
|
|
6803
|
+
await response.body?.cancel();
|
|
6804
|
+
continue;
|
|
6805
|
+
}
|
|
6806
|
+
if (!response.ok) {
|
|
6807
|
+
const detail = (await response.text().catch(() => "")).slice(0, 300);
|
|
6808
|
+
throw new DingtalkCardRequestError(`DingTalk Card OpenAPI ${method} ${path} failed${templateId ? ` for ${templateId}` : ""}: HTTP ${response.status}${detail ? ` ${detail}` : ""}`, isRetryableStatus(response.status));
|
|
6809
|
+
}
|
|
6810
|
+
return response.json().catch(() => void 0);
|
|
6658
6811
|
}
|
|
6659
|
-
return response.json().catch(() => void 0);
|
|
6660
6812
|
}
|
|
6661
6813
|
};
|
|
6662
6814
|
|
|
@@ -6783,8 +6935,11 @@ init_esbuild_shims();
|
|
|
6783
6935
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
6784
6936
|
var FLUSH_INTERVAL_MS = 500;
|
|
6785
6937
|
var STATUS_REFRESH_INTERVAL_MS = 1e3;
|
|
6938
|
+
var CONTENT_SYNC_INTERVAL_SECONDS = 5;
|
|
6786
6939
|
var BREAKER_PROBE_INTERVAL_MS = 3e4;
|
|
6787
6940
|
var MAX_CONSECUTIVE_STATUS_FAILURES = 3;
|
|
6941
|
+
var INITIAL_RETRY_INTERVAL_MS = 1e3;
|
|
6942
|
+
var MAX_RETRY_INTERVAL_MS = 3e4;
|
|
6788
6943
|
var CONTENT_LIMIT = 2e4;
|
|
6789
6944
|
var TRUNCATION_MARKER = "[Earlier output truncated]\n";
|
|
6790
6945
|
function boundContent(content) {
|
|
@@ -6802,10 +6957,13 @@ var StatusCardController = class {
|
|
|
6802
6957
|
recordsByOutTrack = /* @__PURE__ */ new Map();
|
|
6803
6958
|
segmentIdsByRun = /* @__PURE__ */ new Map();
|
|
6804
6959
|
terminalSegmentIds = /* @__PURE__ */ new Set();
|
|
6960
|
+
disposed = false;
|
|
6805
6961
|
constructor(options) {
|
|
6806
6962
|
this.options = options;
|
|
6807
6963
|
}
|
|
6808
6964
|
ensure(segment, target) {
|
|
6965
|
+
if (this.disposed)
|
|
6966
|
+
return;
|
|
6809
6967
|
if (this.terminalSegmentIds.has(segment.segmentId))
|
|
6810
6968
|
return;
|
|
6811
6969
|
if (!this.recordsBySegment.has(segment.segmentId)) {
|
|
@@ -6813,6 +6971,8 @@ var StatusCardController = class {
|
|
|
6813
6971
|
}
|
|
6814
6972
|
}
|
|
6815
6973
|
replace(segment, target, content) {
|
|
6974
|
+
if (this.disposed)
|
|
6975
|
+
return;
|
|
6816
6976
|
if (this.terminalSegmentIds.has(segment.segmentId))
|
|
6817
6977
|
return;
|
|
6818
6978
|
const record = this.recordsBySegment.get(segment.segmentId);
|
|
@@ -6823,22 +6983,27 @@ var StatusCardController = class {
|
|
|
6823
6983
|
if (record.terminal)
|
|
6824
6984
|
return;
|
|
6825
6985
|
record.content = boundContent(content);
|
|
6986
|
+
record.contentVersion++;
|
|
6826
6987
|
if (record.streamFailed)
|
|
6827
6988
|
return;
|
|
6828
|
-
record.
|
|
6989
|
+
record.hasPendingWrite = true;
|
|
6829
6990
|
this.scheduleFlush(record);
|
|
6830
6991
|
}
|
|
6831
6992
|
/**
|
|
6832
6993
|
* Whether a created, still-running status card is displaying content for
|
|
6833
6994
|
* this segment. Awaits the in-flight creation so a boundary decision made
|
|
6834
6995
|
* while creation is pending does not race it. A latched stream failure
|
|
6835
|
-
* means the card can never show further content, so it is not live.
|
|
6996
|
+
* means the card can never show further content, so it is not live. A
|
|
6997
|
+
* creation that is backing off for a retry is not awaited either (see
|
|
6998
|
+
* `awaitDelivery`).
|
|
6836
6999
|
*/
|
|
6837
7000
|
async isCardLive(segmentId) {
|
|
7001
|
+
if (this.disposed)
|
|
7002
|
+
return false;
|
|
6838
7003
|
const record = this.recordsBySegment.get(segmentId);
|
|
6839
7004
|
if (!record || record.terminal || record.streamFailed)
|
|
6840
7005
|
return false;
|
|
6841
|
-
return record
|
|
7006
|
+
return this.awaitDelivery(record);
|
|
6842
7007
|
}
|
|
6843
7008
|
/**
|
|
6844
7009
|
* Drain any pending snapshot so callers can treat the card's current
|
|
@@ -6847,23 +7012,64 @@ var StatusCardController = class {
|
|
|
6847
7012
|
* caller can fall back instead of claiming delivery.
|
|
6848
7013
|
*/
|
|
6849
7014
|
async flushPending(segmentId) {
|
|
7015
|
+
if (this.disposed)
|
|
7016
|
+
return false;
|
|
6850
7017
|
const record = this.recordsBySegment.get(segmentId);
|
|
6851
7018
|
if (!record || record.terminal)
|
|
6852
7019
|
return false;
|
|
6853
|
-
if (!await record
|
|
7020
|
+
if (!await this.awaitDelivery(record))
|
|
6854
7021
|
return false;
|
|
6855
7022
|
while (!record.terminal && !record.streamFailed) {
|
|
6856
7023
|
if (record.flushTimer) {
|
|
6857
7024
|
clearTimeout(record.flushTimer);
|
|
6858
7025
|
record.flushTimer = void 0;
|
|
6859
7026
|
}
|
|
7027
|
+
if (record.streamRetryTimer) {
|
|
7028
|
+
clearTimeout(record.streamRetryTimer);
|
|
7029
|
+
record.streamRetryTimer = void 0;
|
|
7030
|
+
}
|
|
7031
|
+
const failureVersion = record.streamFailureVersion;
|
|
6860
7032
|
this.flush(record);
|
|
6861
7033
|
await record.writeChain;
|
|
6862
|
-
if (record.
|
|
7034
|
+
if (record.streamFailureVersion !== failureVersion)
|
|
7035
|
+
return false;
|
|
7036
|
+
if (!record.hasPendingWrite)
|
|
6863
7037
|
break;
|
|
6864
7038
|
}
|
|
6865
7039
|
return !record.terminal && !record.streamFailed;
|
|
6866
7040
|
}
|
|
7041
|
+
abandon(segmentId) {
|
|
7042
|
+
const record = this.recordsBySegment.get(segmentId);
|
|
7043
|
+
if (!record || record.terminal)
|
|
7044
|
+
return;
|
|
7045
|
+
record.terminal = true;
|
|
7046
|
+
record.hasPendingWrite = false;
|
|
7047
|
+
void record.ready.then((ready) => {
|
|
7048
|
+
if (!ready)
|
|
7049
|
+
return;
|
|
7050
|
+
void this.options.client.updateInstance({
|
|
7051
|
+
outTrackId: record.outTrackId,
|
|
7052
|
+
cardParamMap: {
|
|
7053
|
+
flowStatus: 3,
|
|
7054
|
+
hasAction: "false",
|
|
7055
|
+
stop_action: "false"
|
|
7056
|
+
}
|
|
7057
|
+
}).catch(() => {
|
|
7058
|
+
});
|
|
7059
|
+
});
|
|
7060
|
+
this.removeRecord(record);
|
|
7061
|
+
}
|
|
7062
|
+
/**
|
|
7063
|
+
* Resolves once the card is known to be delivered (or not) without waiting
|
|
7064
|
+
* through a creation backoff: `creationAttempt` is the failed attempt until
|
|
7065
|
+
* the retry actually starts, so a boundary reached mid-backoff falls back
|
|
7066
|
+
* to text while the retry keeps running for later output.
|
|
7067
|
+
*/
|
|
7068
|
+
async awaitDelivery(record) {
|
|
7069
|
+
if (!await record.creationAttempt)
|
|
7070
|
+
return false;
|
|
7071
|
+
return record.ready;
|
|
7072
|
+
}
|
|
6867
7073
|
createRecord(segment, target, initialContent = "") {
|
|
6868
7074
|
const outTrackId = `qwen-status-${randomUUID2()}`;
|
|
6869
7075
|
const record = {
|
|
@@ -6876,13 +7082,21 @@ var StatusCardController = class {
|
|
|
6876
7082
|
content: boundContent(initialContent),
|
|
6877
7083
|
startedAt: Date.now(),
|
|
6878
7084
|
lastStatusSecond: 0,
|
|
7085
|
+
lastContentSyncSecond: 0,
|
|
6879
7086
|
ready: Promise.resolve(false),
|
|
7087
|
+
creationAttempt: Promise.resolve(false),
|
|
6880
7088
|
terminal: false,
|
|
6881
7089
|
streamFailed: false,
|
|
7090
|
+
streamFailureVersion: 0,
|
|
7091
|
+
createRetryAttempt: 0,
|
|
7092
|
+
streamRetryAttempt: 0,
|
|
7093
|
+
terminalRetryAttempt: 0,
|
|
6882
7094
|
consecutiveStatusFailures: 0,
|
|
6883
7095
|
stopClaimed: false,
|
|
6884
7096
|
forbiddenActors: /* @__PURE__ */ new Set(),
|
|
6885
7097
|
lastWriteAt: Date.now(),
|
|
7098
|
+
contentVersion: 0,
|
|
7099
|
+
hasPendingWrite: false,
|
|
6886
7100
|
writeChain: Promise.resolve()
|
|
6887
7101
|
};
|
|
6888
7102
|
this.recordsBySegment.set(record.segmentId, record);
|
|
@@ -6904,6 +7118,8 @@ var StatusCardController = class {
|
|
|
6904
7118
|
void this.finalize(segmentId, boundContent(error), "Failed", true);
|
|
6905
7119
|
}
|
|
6906
7120
|
cancelRun(runId, reason) {
|
|
7121
|
+
if (this.disposed)
|
|
7122
|
+
return;
|
|
6907
7123
|
for (const segmentId of [...this.segmentIdsByRun.get(runId) ?? []]) {
|
|
6908
7124
|
const record = this.recordsBySegment.get(segmentId);
|
|
6909
7125
|
if (!record)
|
|
@@ -6912,6 +7128,8 @@ var StatusCardController = class {
|
|
|
6912
7128
|
}
|
|
6913
7129
|
}
|
|
6914
7130
|
claimStop(outTrackId, actorId) {
|
|
7131
|
+
if (this.disposed)
|
|
7132
|
+
return { kind: "ignored", actorId };
|
|
6915
7133
|
const record = this.recordsByOutTrack.get(outTrackId);
|
|
6916
7134
|
if (!record || record.terminal || record.stopClaimed) {
|
|
6917
7135
|
return { kind: "ignored", actorId };
|
|
@@ -6940,44 +7158,72 @@ var StatusCardController = class {
|
|
|
6940
7158
|
};
|
|
6941
7159
|
}
|
|
6942
7160
|
async create(record, target) {
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
outTrackId: record.outTrackId,
|
|
6948
|
-
target,
|
|
6949
|
-
cardParamMap: {
|
|
6950
|
-
content: initialContent,
|
|
6951
|
-
flowStatus: 2,
|
|
6952
|
-
statusLine: this.statusLine(record, "Running").text,
|
|
6953
|
-
hasAction: "true",
|
|
6954
|
-
stop_action: "true"
|
|
6955
|
-
}
|
|
7161
|
+
for (; ; ) {
|
|
7162
|
+
let settleAttempt;
|
|
7163
|
+
record.creationAttempt = new Promise((resolve) => {
|
|
7164
|
+
settleAttempt = resolve;
|
|
6956
7165
|
});
|
|
7166
|
+
try {
|
|
7167
|
+
await this.options.client.createAndDeliver({
|
|
7168
|
+
templateId: STATUS_CARD_TEMPLATE_ID,
|
|
7169
|
+
outTrackId: record.outTrackId,
|
|
7170
|
+
target,
|
|
7171
|
+
cardParamMap: {
|
|
7172
|
+
content: sanitizeStreamingImageMarkers(record.content),
|
|
7173
|
+
flowStatus: 2,
|
|
7174
|
+
statusLine: this.statusLine(record, "Running").text,
|
|
7175
|
+
hasAction: "true",
|
|
7176
|
+
stop_action: "true"
|
|
7177
|
+
}
|
|
7178
|
+
});
|
|
7179
|
+
settleAttempt(true);
|
|
7180
|
+
break;
|
|
7181
|
+
} catch (error) {
|
|
7182
|
+
settleAttempt(false);
|
|
7183
|
+
this.options.onError?.("status card creation", error);
|
|
7184
|
+
if (this.disposed || record.terminal || !isRetryableDingtalkCardError(error)) {
|
|
7185
|
+
return false;
|
|
7186
|
+
}
|
|
7187
|
+
if (!await this.waitForCreationRetry(record))
|
|
7188
|
+
return false;
|
|
7189
|
+
}
|
|
7190
|
+
}
|
|
7191
|
+
if (this.disposed)
|
|
7192
|
+
return false;
|
|
7193
|
+
if (this.recordsBySegment.get(record.segmentId) !== record)
|
|
7194
|
+
return true;
|
|
7195
|
+
try {
|
|
6957
7196
|
await this.options.client.openOrUpdateStream({
|
|
6958
7197
|
outTrackId: record.outTrackId,
|
|
6959
7198
|
key: "content",
|
|
6960
|
-
content:
|
|
7199
|
+
content: sanitizeStreamingImageMarkers(record.content),
|
|
6961
7200
|
finalize: false
|
|
6962
7201
|
});
|
|
6963
|
-
return true;
|
|
6964
7202
|
} catch (error) {
|
|
6965
|
-
this.
|
|
6966
|
-
await this.options.client.updateInstance({
|
|
6967
|
-
outTrackId: record.outTrackId,
|
|
6968
|
-
cardParamMap: {
|
|
6969
|
-
flowStatus: 3,
|
|
6970
|
-
statusLine: "Unavailable",
|
|
6971
|
-
hasAction: "false",
|
|
6972
|
-
stop_action: "false"
|
|
6973
|
-
}
|
|
6974
|
-
}).catch(() => {
|
|
6975
|
-
});
|
|
6976
|
-
return false;
|
|
7203
|
+
this.handleStreamFailure(record, error);
|
|
6977
7204
|
}
|
|
7205
|
+
return true;
|
|
7206
|
+
}
|
|
7207
|
+
/**
|
|
7208
|
+
* Sleeps for the next creation backoff. Resolves false when finalization or
|
|
7209
|
+
* disposal abandons the creation so `ready` settles without waiting.
|
|
7210
|
+
*/
|
|
7211
|
+
waitForCreationRetry(record) {
|
|
7212
|
+
const delay = this.retryDelay(record.createRetryAttempt++);
|
|
7213
|
+
return new Promise((resolve) => {
|
|
7214
|
+
const settle2 = /* @__PURE__ */ __name((resumed) => {
|
|
7215
|
+
if (record.createRetryTimer)
|
|
7216
|
+
clearTimeout(record.createRetryTimer);
|
|
7217
|
+
record.createRetryTimer = void 0;
|
|
7218
|
+
record.abandonCreation = void 0;
|
|
7219
|
+
resolve(resumed);
|
|
7220
|
+
}, "settle");
|
|
7221
|
+
record.abandonCreation = () => settle2(false);
|
|
7222
|
+
record.createRetryTimer = setTimeout(() => settle2(true), delay);
|
|
7223
|
+
});
|
|
6978
7224
|
}
|
|
6979
7225
|
scheduleFlush(record) {
|
|
6980
|
-
if (record.flushTimer || record.inFlight || record.terminal)
|
|
7226
|
+
if (record.flushTimer || record.streamRetryTimer || record.inFlight || record.terminal)
|
|
6981
7227
|
return;
|
|
6982
7228
|
const delay = Math.max(0, FLUSH_INTERVAL_MS - (Date.now() - record.lastWriteAt));
|
|
6983
7229
|
record.flushTimer = setTimeout(() => {
|
|
@@ -6986,42 +7232,44 @@ var StatusCardController = class {
|
|
|
6986
7232
|
}, delay);
|
|
6987
7233
|
}
|
|
6988
7234
|
flush(record) {
|
|
6989
|
-
if (record.terminal || record.
|
|
7235
|
+
if (this.disposed || record.terminal || record.streamFailed || record.inFlight || !record.hasPendingWrite)
|
|
6990
7236
|
return;
|
|
6991
|
-
|
|
6992
|
-
|
|
7237
|
+
record.hasPendingWrite = false;
|
|
7238
|
+
let sentVersion;
|
|
7239
|
+
let contentWritten = false;
|
|
6993
7240
|
const write = record.writeChain.then(async () => {
|
|
6994
7241
|
const ready = await record.ready;
|
|
6995
|
-
if (!ready || record.terminal)
|
|
7242
|
+
if (!ready || record.terminal || record.streamFailed)
|
|
6996
7243
|
return;
|
|
7244
|
+
sentVersion = record.contentVersion;
|
|
6997
7245
|
await this.options.client.openOrUpdateStream({
|
|
6998
7246
|
outTrackId: record.outTrackId,
|
|
6999
7247
|
key: "content",
|
|
7000
|
-
content,
|
|
7248
|
+
content: sanitizeStreamingImageMarkers(record.content),
|
|
7001
7249
|
finalize: false
|
|
7002
7250
|
});
|
|
7251
|
+
contentWritten = true;
|
|
7252
|
+
record.streamRetryAttempt = 0;
|
|
7003
7253
|
await this.updateRunningStatus(record);
|
|
7004
|
-
}).catch((error) =>
|
|
7005
|
-
record.streamFailed = true;
|
|
7006
|
-
record.pendingSnapshot = void 0;
|
|
7007
|
-
if (record.statusTimer) {
|
|
7008
|
-
clearTimeout(record.statusTimer);
|
|
7009
|
-
record.statusTimer = void 0;
|
|
7010
|
-
}
|
|
7011
|
-
this.options.onError?.("status card streaming", error);
|
|
7012
|
-
});
|
|
7254
|
+
}).catch((error) => this.handleStreamFailure(record, error));
|
|
7013
7255
|
const tracked = write.finally(() => {
|
|
7014
7256
|
if (record.inFlight === tracked) {
|
|
7015
7257
|
record.inFlight = void 0;
|
|
7016
7258
|
}
|
|
7017
7259
|
record.lastWriteAt = Date.now();
|
|
7018
|
-
if (record.
|
|
7260
|
+
if (contentWritten && record.contentVersion === sentVersion) {
|
|
7261
|
+
record.hasPendingWrite = false;
|
|
7262
|
+
}
|
|
7263
|
+
if (record.hasPendingWrite && record.contentVersion !== sentVersion) {
|
|
7019
7264
|
this.scheduleFlush(record);
|
|
7265
|
+
}
|
|
7020
7266
|
});
|
|
7021
7267
|
record.inFlight = tracked;
|
|
7022
7268
|
record.writeChain = tracked;
|
|
7023
7269
|
}
|
|
7024
7270
|
async finalize(segmentId, content, state, isError, retainedContent) {
|
|
7271
|
+
if (this.disposed)
|
|
7272
|
+
return false;
|
|
7025
7273
|
const record = this.recordsBySegment.get(segmentId);
|
|
7026
7274
|
if (!record || record.terminal)
|
|
7027
7275
|
return false;
|
|
@@ -7036,58 +7284,165 @@ var StatusCardController = class {
|
|
|
7036
7284
|
if (record.flushTimer)
|
|
7037
7285
|
clearTimeout(record.flushTimer);
|
|
7038
7286
|
record.flushTimer = void 0;
|
|
7287
|
+
if (record.streamRetryTimer)
|
|
7288
|
+
clearTimeout(record.streamRetryTimer);
|
|
7289
|
+
record.streamRetryTimer = void 0;
|
|
7039
7290
|
if (record.statusTimer)
|
|
7040
7291
|
clearTimeout(record.statusTimer);
|
|
7041
7292
|
record.statusTimer = void 0;
|
|
7042
|
-
record.
|
|
7293
|
+
record.hasPendingWrite = false;
|
|
7294
|
+
record.abandonCreation?.();
|
|
7295
|
+
if (!await record.ready) {
|
|
7296
|
+
this.removeRecord(record);
|
|
7297
|
+
return false;
|
|
7298
|
+
}
|
|
7299
|
+
await record.writeChain;
|
|
7300
|
+
const retained = content || (retainedContent ? retainedContent(record.content) : record.content);
|
|
7301
|
+
record.terminalIntent = {
|
|
7302
|
+
content: boundContent(sanitizeStreamingImageMarkers(retained)),
|
|
7303
|
+
isError,
|
|
7304
|
+
statusLine: this.statusLine(record, state).text,
|
|
7305
|
+
streamFinalizeSettled: false
|
|
7306
|
+
};
|
|
7307
|
+
return this.attemptFinalization(record);
|
|
7308
|
+
}
|
|
7309
|
+
async attemptFinalization(record) {
|
|
7310
|
+
if (this.disposed)
|
|
7311
|
+
return false;
|
|
7312
|
+
if (this.recordsBySegment.get(record.segmentId) !== record)
|
|
7313
|
+
return false;
|
|
7314
|
+
const intent = record.terminalIntent;
|
|
7315
|
+
if (!intent)
|
|
7316
|
+
return false;
|
|
7317
|
+
if (!intent.streamFinalizeSettled) {
|
|
7318
|
+
try {
|
|
7319
|
+
await this.options.client.openOrUpdateStream({
|
|
7320
|
+
outTrackId: record.outTrackId,
|
|
7321
|
+
key: "content",
|
|
7322
|
+
content: "",
|
|
7323
|
+
finalize: true,
|
|
7324
|
+
isError: intent.isError
|
|
7325
|
+
});
|
|
7326
|
+
intent.streamFinalizeSettled = true;
|
|
7327
|
+
} catch (error) {
|
|
7328
|
+
if (!isRetryableDingtalkCardError(error)) {
|
|
7329
|
+
intent.streamFinalizeSettled = true;
|
|
7330
|
+
}
|
|
7331
|
+
this.options.onError?.("status card finalization", error);
|
|
7332
|
+
}
|
|
7333
|
+
}
|
|
7334
|
+
if (this.disposed)
|
|
7335
|
+
return false;
|
|
7043
7336
|
try {
|
|
7044
|
-
if (!await record.ready)
|
|
7045
|
-
return false;
|
|
7046
|
-
await record.writeChain;
|
|
7047
|
-
const retained = content || (retainedContent ? retainedContent(record.content) : record.content);
|
|
7048
|
-
const finalContent = boundContent(sanitizeStreamingImageMarkers(retained));
|
|
7049
|
-
await this.options.client.openOrUpdateStream({
|
|
7050
|
-
outTrackId: record.outTrackId,
|
|
7051
|
-
key: "content",
|
|
7052
|
-
content: "",
|
|
7053
|
-
finalize: true,
|
|
7054
|
-
isError
|
|
7055
|
-
});
|
|
7056
7337
|
await this.options.client.updateInstance({
|
|
7057
7338
|
outTrackId: record.outTrackId,
|
|
7058
7339
|
cardParamMap: {
|
|
7059
7340
|
blockList: JSON.stringify([
|
|
7060
7341
|
{
|
|
7061
7342
|
type: 0,
|
|
7062
|
-
markdown:
|
|
7343
|
+
markdown: intent.content
|
|
7063
7344
|
}
|
|
7064
7345
|
]),
|
|
7065
|
-
content:
|
|
7066
|
-
copy_content:
|
|
7346
|
+
content: intent.content,
|
|
7347
|
+
copy_content: intent.content,
|
|
7067
7348
|
flowStatus: 3,
|
|
7068
|
-
statusLine:
|
|
7349
|
+
statusLine: intent.statusLine,
|
|
7069
7350
|
hasAction: "false",
|
|
7070
7351
|
stop_action: "false"
|
|
7071
7352
|
}
|
|
7072
7353
|
});
|
|
7073
7354
|
record.content = "";
|
|
7355
|
+
this.removeRecord(record);
|
|
7074
7356
|
return true;
|
|
7075
7357
|
} catch (error) {
|
|
7076
7358
|
this.options.onError?.("status card finalization", error);
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
if (this.recordsByOutTrack.get(record.outTrackId) === record) {
|
|
7083
|
-
this.recordsByOutTrack.delete(record.outTrackId);
|
|
7359
|
+
if (isRetryableDingtalkCardError(error)) {
|
|
7360
|
+
this.scheduleTerminalRetry(record);
|
|
7361
|
+
return true;
|
|
7362
|
+
} else {
|
|
7363
|
+
this.removeRecord(record);
|
|
7084
7364
|
}
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7365
|
+
return false;
|
|
7366
|
+
}
|
|
7367
|
+
}
|
|
7368
|
+
scheduleStreamRetry(record) {
|
|
7369
|
+
if (this.disposed || record.terminal || record.streamFailed || record.streamRetryTimer) {
|
|
7370
|
+
return;
|
|
7371
|
+
}
|
|
7372
|
+
const delay = this.retryDelay(record.streamRetryAttempt++);
|
|
7373
|
+
record.streamRetryTimer = setTimeout(() => {
|
|
7374
|
+
record.streamRetryTimer = void 0;
|
|
7375
|
+
if (this.disposed || record.terminal || record.streamFailed)
|
|
7376
|
+
return;
|
|
7377
|
+
this.flush(record);
|
|
7378
|
+
}, delay);
|
|
7379
|
+
}
|
|
7380
|
+
scheduleTerminalRetry(record) {
|
|
7381
|
+
if (this.disposed || !record.terminalIntent || record.terminalRetryTimer) {
|
|
7382
|
+
return;
|
|
7383
|
+
}
|
|
7384
|
+
const delay = this.retryDelay(record.terminalRetryAttempt++);
|
|
7385
|
+
record.terminalRetryTimer = setTimeout(() => {
|
|
7386
|
+
record.terminalRetryTimer = void 0;
|
|
7387
|
+
if (this.disposed)
|
|
7388
|
+
return;
|
|
7389
|
+
void this.attemptFinalization(record);
|
|
7390
|
+
}, delay);
|
|
7391
|
+
}
|
|
7392
|
+
handleStreamFailure(record, error) {
|
|
7393
|
+
record.streamFailureVersion++;
|
|
7394
|
+
if (!this.disposed && !record.terminal && isRetryableDingtalkCardError(error)) {
|
|
7395
|
+
record.hasPendingWrite = true;
|
|
7396
|
+
this.scheduleStreamRetry(record);
|
|
7397
|
+
} else if (!record.terminal) {
|
|
7398
|
+
record.streamFailed = true;
|
|
7399
|
+
record.hasPendingWrite = false;
|
|
7400
|
+
if (record.statusTimer) {
|
|
7401
|
+
clearTimeout(record.statusTimer);
|
|
7402
|
+
record.statusTimer = void 0;
|
|
7089
7403
|
}
|
|
7090
7404
|
}
|
|
7405
|
+
this.options.onError?.("status card streaming", error);
|
|
7406
|
+
}
|
|
7407
|
+
retryDelay(attempt) {
|
|
7408
|
+
return Math.min(INITIAL_RETRY_INTERVAL_MS * 2 ** Math.min(attempt, 10), MAX_RETRY_INTERVAL_MS);
|
|
7409
|
+
}
|
|
7410
|
+
removeRecord(record) {
|
|
7411
|
+
record.abandonCreation?.();
|
|
7412
|
+
if (record.flushTimer)
|
|
7413
|
+
clearTimeout(record.flushTimer);
|
|
7414
|
+
if (record.streamRetryTimer)
|
|
7415
|
+
clearTimeout(record.streamRetryTimer);
|
|
7416
|
+
if (record.terminalRetryTimer)
|
|
7417
|
+
clearTimeout(record.terminalRetryTimer);
|
|
7418
|
+
if (record.statusTimer)
|
|
7419
|
+
clearTimeout(record.statusTimer);
|
|
7420
|
+
record.flushTimer = void 0;
|
|
7421
|
+
record.streamRetryTimer = void 0;
|
|
7422
|
+
record.terminalRetryTimer = void 0;
|
|
7423
|
+
record.statusTimer = void 0;
|
|
7424
|
+
if (this.recordsBySegment.get(record.segmentId) === record) {
|
|
7425
|
+
this.recordsBySegment.delete(record.segmentId);
|
|
7426
|
+
}
|
|
7427
|
+
if (this.recordsByOutTrack.get(record.outTrackId) === record) {
|
|
7428
|
+
this.recordsByOutTrack.delete(record.outTrackId);
|
|
7429
|
+
}
|
|
7430
|
+
const segmentIds = this.segmentIdsByRun.get(record.runId);
|
|
7431
|
+
segmentIds?.delete(record.segmentId);
|
|
7432
|
+
if (segmentIds?.size === 0) {
|
|
7433
|
+
this.segmentIdsByRun.delete(record.runId);
|
|
7434
|
+
}
|
|
7435
|
+
}
|
|
7436
|
+
dispose() {
|
|
7437
|
+
if (this.disposed)
|
|
7438
|
+
return;
|
|
7439
|
+
this.disposed = true;
|
|
7440
|
+
for (const record of [...this.recordsBySegment.values()]) {
|
|
7441
|
+
record.terminal = true;
|
|
7442
|
+
record.hasPendingWrite = false;
|
|
7443
|
+
this.removeRecord(record);
|
|
7444
|
+
}
|
|
7445
|
+
this.terminalSegmentIds.clear();
|
|
7091
7446
|
}
|
|
7092
7447
|
statusLine(record, state) {
|
|
7093
7448
|
const second = Math.max(0, Math.floor((Date.now() - record.startedAt) / 1e3));
|
|
@@ -7098,17 +7453,23 @@ var StatusCardController = class {
|
|
|
7098
7453
|
};
|
|
7099
7454
|
}
|
|
7100
7455
|
async updateRunningStatus(record) {
|
|
7101
|
-
if (record.terminal || record.streamFailed)
|
|
7456
|
+
if (this.disposed || record.terminal || record.streamFailed)
|
|
7102
7457
|
return;
|
|
7103
7458
|
const status = this.statusLine(record, "Running");
|
|
7104
7459
|
if (status.second === record.lastStatusSecond)
|
|
7105
7460
|
return;
|
|
7461
|
+
const syncContent = status.second - record.lastContentSyncSecond >= CONTENT_SYNC_INTERVAL_SECONDS;
|
|
7106
7462
|
try {
|
|
7107
7463
|
await this.options.client.updateInstance({
|
|
7108
7464
|
outTrackId: record.outTrackId,
|
|
7109
|
-
cardParamMap: {
|
|
7465
|
+
cardParamMap: {
|
|
7466
|
+
...syncContent ? { content: sanitizeStreamingImageMarkers(record.content) } : {},
|
|
7467
|
+
statusLine: status.text
|
|
7468
|
+
}
|
|
7110
7469
|
});
|
|
7111
7470
|
record.lastStatusSecond = status.second;
|
|
7471
|
+
if (syncContent)
|
|
7472
|
+
record.lastContentSyncSecond = status.second;
|
|
7112
7473
|
record.consecutiveStatusFailures = 0;
|
|
7113
7474
|
if (record.statusTimer) {
|
|
7114
7475
|
clearTimeout(record.statusTimer);
|
|
@@ -7121,13 +7482,13 @@ var StatusCardController = class {
|
|
|
7121
7482
|
}
|
|
7122
7483
|
}
|
|
7123
7484
|
scheduleStatusRefresh(record, intervalMs = STATUS_REFRESH_INTERVAL_MS) {
|
|
7124
|
-
if (record.terminal || record.streamFailed || record.statusTimer)
|
|
7485
|
+
if (this.disposed || record.terminal || record.streamFailed || record.statusTimer)
|
|
7125
7486
|
return;
|
|
7126
7487
|
const elapsed = Math.max(0, Date.now() - record.startedAt);
|
|
7127
7488
|
const delay = Math.max(50, intervalMs - elapsed % intervalMs);
|
|
7128
7489
|
record.statusTimer = setTimeout(() => {
|
|
7129
7490
|
record.statusTimer = void 0;
|
|
7130
|
-
if (record.terminal || record.streamFailed)
|
|
7491
|
+
if (this.disposed || record.terminal || record.streamFailed)
|
|
7131
7492
|
return;
|
|
7132
7493
|
const refresh = record.writeChain.then(() => this.updateRunningStatus(record));
|
|
7133
7494
|
record.writeChain = refresh;
|
|
@@ -7208,7 +7569,7 @@ var QuestionCardController = class {
|
|
|
7208
7569
|
}
|
|
7209
7570
|
await this.finalize(record, "cancelled");
|
|
7210
7571
|
try {
|
|
7211
|
-
await this.options.sendFallback(context.target.chatId, this.fallbackText(context));
|
|
7572
|
+
await this.options.sendFallback(context.target.chatId, this.fallbackText(context), ...context.sourceLabel ? [context.sourceLabel] : []);
|
|
7212
7573
|
} catch (fallbackError) {
|
|
7213
7574
|
this.options.onError?.("question fallback delivery", fallbackError);
|
|
7214
7575
|
}
|
|
@@ -7350,22 +7711,22 @@ var QuestionCardController = class {
|
|
|
7350
7711
|
const cardParamMap = {
|
|
7351
7712
|
submitted: {
|
|
7352
7713
|
card_status: "submitted",
|
|
7353
|
-
question_desc: "Submitted.",
|
|
7714
|
+
question_desc: this.withSourceLabel(record.context, "Submitted."),
|
|
7354
7715
|
form_btn_text: "Submitted"
|
|
7355
7716
|
},
|
|
7356
7717
|
expired: {
|
|
7357
7718
|
card_status: "expired",
|
|
7358
|
-
question_desc: "This question expired. Please retry.",
|
|
7719
|
+
question_desc: this.withSourceLabel(record.context, "This question expired. Please retry."),
|
|
7359
7720
|
form_btn_text: "Expired"
|
|
7360
7721
|
},
|
|
7361
7722
|
resolved_outside_presenter: {
|
|
7362
7723
|
card_status: "expired",
|
|
7363
|
-
question_desc: "Resolved outside this card.",
|
|
7724
|
+
question_desc: this.withSourceLabel(record.context, "Resolved outside this card."),
|
|
7364
7725
|
form_btn_text: "Expired"
|
|
7365
7726
|
},
|
|
7366
7727
|
cancelled: {
|
|
7367
7728
|
card_status: "cancelled",
|
|
7368
|
-
question_desc: "Cancelled.",
|
|
7729
|
+
question_desc: this.withSourceLabel(record.context, "Cancelled."),
|
|
7369
7730
|
form_btn_text: "Cancelled"
|
|
7370
7731
|
}
|
|
7371
7732
|
};
|
|
@@ -7374,7 +7735,9 @@ var QuestionCardController = class {
|
|
|
7374
7735
|
outTrackId: record.outTrackId,
|
|
7375
7736
|
cardParamMap: {
|
|
7376
7737
|
...cardParamMap[record.terminalState],
|
|
7377
|
-
...record.terminalDescription ? {
|
|
7738
|
+
...record.terminalDescription ? {
|
|
7739
|
+
question_desc: this.withSourceLabel(record.context, record.terminalDescription)
|
|
7740
|
+
} : {}
|
|
7378
7741
|
}
|
|
7379
7742
|
});
|
|
7380
7743
|
} catch (error) {
|
|
@@ -7434,7 +7797,7 @@ var QuestionCardController = class {
|
|
|
7434
7797
|
return {
|
|
7435
7798
|
question_id: context.requestId,
|
|
7436
7799
|
question_title: first.header,
|
|
7437
|
-
question_desc: first.question,
|
|
7800
|
+
question_desc: this.withSourceLabel(context, first.question),
|
|
7438
7801
|
card_status: "pending",
|
|
7439
7802
|
form_btn_text: "Submit",
|
|
7440
7803
|
selected_text: "",
|
|
@@ -7470,19 +7833,27 @@ var QuestionCardController = class {
|
|
|
7470
7833
|
return `The interactive question could not be delivered, so this request was cancelled. Please retry.
|
|
7471
7834
|
${questions}`;
|
|
7472
7835
|
}
|
|
7836
|
+
withSourceLabel(context, text) {
|
|
7837
|
+
if (!context.sourceLabel)
|
|
7838
|
+
return text;
|
|
7839
|
+
const label = escapeDingTalkMarkdown(context.sourceLabel);
|
|
7840
|
+
return `${label}
|
|
7841
|
+
|
|
7842
|
+
${text}`;
|
|
7843
|
+
}
|
|
7473
7844
|
};
|
|
7474
7845
|
|
|
7475
7846
|
// packages/channels/dingtalk/dist/interaction-presenter.js
|
|
7476
7847
|
init_esbuild_shims();
|
|
7477
7848
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
7478
|
-
function
|
|
7849
|
+
function escapeSenderMarkdownText(text) {
|
|
7479
7850
|
return text.replace(/([\\`*_[\]{}()#+.!|>~-])/gu, "\\$1");
|
|
7480
7851
|
}
|
|
7481
|
-
__name(
|
|
7852
|
+
__name(escapeSenderMarkdownText, "escapeSenderMarkdownText");
|
|
7482
7853
|
function formatSenderPrefixes(sender) {
|
|
7483
7854
|
const senderName = sanitizeSenderName(sender.senderName);
|
|
7484
7855
|
return {
|
|
7485
|
-
senderPrefix: `@${
|
|
7856
|
+
senderPrefix: `@${escapeSenderMarkdownText(senderName)}`,
|
|
7486
7857
|
senderRawPrefix: `@${senderName}`
|
|
7487
7858
|
};
|
|
7488
7859
|
}
|
|
@@ -7498,7 +7869,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7498
7869
|
constructor(options) {
|
|
7499
7870
|
this.options = options;
|
|
7500
7871
|
}
|
|
7501
|
-
registerRun(runId, ownerId, target, sessionId = "", sender) {
|
|
7872
|
+
registerRun(runId, ownerId, target, sessionId = "", sender, sourceLabel) {
|
|
7502
7873
|
this.runs.set(runId, {
|
|
7503
7874
|
runId,
|
|
7504
7875
|
ownerId,
|
|
@@ -7514,10 +7885,12 @@ var DingtalkInteractionPresenter = class {
|
|
|
7514
7885
|
chatId: target.chatId,
|
|
7515
7886
|
senderId: ownerId,
|
|
7516
7887
|
isGroup: target.isGroup
|
|
7517
|
-
}
|
|
7888
|
+
},
|
|
7889
|
+
sourceLabel
|
|
7518
7890
|
},
|
|
7519
7891
|
projectionChain: Promise.resolve(),
|
|
7520
7892
|
...target.isGroup && sender ? formatSenderPrefixes(sender) : {},
|
|
7893
|
+
...sourceLabel ? { sourceLabel } : {},
|
|
7521
7894
|
terminal: false
|
|
7522
7895
|
});
|
|
7523
7896
|
}
|
|
@@ -7529,7 +7902,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7529
7902
|
void this.enqueue(run, () => {
|
|
7530
7903
|
const statusCards = this.options.statusCards;
|
|
7531
7904
|
const target = this.cardTarget(statusContext.target);
|
|
7532
|
-
statusCards?.
|
|
7905
|
+
statusCards?.replace(statusContext, target, this.withSourcePrefix(run, ""));
|
|
7533
7906
|
});
|
|
7534
7907
|
}
|
|
7535
7908
|
appendOutput(segment, chunk) {
|
|
@@ -7550,7 +7923,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7550
7923
|
run.activeSegmentId = segment.segmentId;
|
|
7551
7924
|
const statusContext = this.ensureStatusContext(run, segment);
|
|
7552
7925
|
void this.enqueue(run, () => {
|
|
7553
|
-
this.options.statusCards?.replace(statusContext, this.cardTarget(statusContext.target), presentation.content);
|
|
7926
|
+
this.options.statusCards?.replace(statusContext, this.cardTarget(statusContext.target), this.withSourcePrefix(run, presentation.content));
|
|
7554
7927
|
});
|
|
7555
7928
|
}
|
|
7556
7929
|
closeOutput(segmentId, text, reason, segment) {
|
|
@@ -7594,7 +7967,8 @@ var DingtalkInteractionPresenter = class {
|
|
|
7594
7967
|
const fallbackText2 = stripPartialImageMarker(text || presentation.content);
|
|
7595
7968
|
if (!fallbackText2 || !this.options.sendFallback)
|
|
7596
7969
|
return false;
|
|
7597
|
-
await this.
|
|
7970
|
+
await this.sendFallback(run, presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
|
|
7971
|
+
statusCards?.abandon(statusContext.segmentId);
|
|
7598
7972
|
return true;
|
|
7599
7973
|
}
|
|
7600
7974
|
if (reason === "input_requested") {
|
|
@@ -7605,7 +7979,8 @@ var DingtalkInteractionPresenter = class {
|
|
|
7605
7979
|
const fallbackText2 = stripPartialImageMarker(text || presentation.content);
|
|
7606
7980
|
if (!fallbackText2 || !this.options.sendFallback)
|
|
7607
7981
|
return false;
|
|
7608
|
-
await this.
|
|
7982
|
+
await this.sendFallback(run, presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
|
|
7983
|
+
statusCards?.abandon(statusContext.segmentId);
|
|
7609
7984
|
return true;
|
|
7610
7985
|
}
|
|
7611
7986
|
statusCards?.ensure(statusContext, this.cardTarget(statusContext.target));
|
|
@@ -7615,7 +7990,8 @@ var DingtalkInteractionPresenter = class {
|
|
|
7615
7990
|
const fallbackText = stripPartialImageMarker(text || presentation.content);
|
|
7616
7991
|
if (!fallbackText || !this.options.sendFallback)
|
|
7617
7992
|
return false;
|
|
7618
|
-
await this.
|
|
7993
|
+
await this.sendFallback(run, presentation.context.target.chatId, fallbackText, presentation.context.sessionId);
|
|
7994
|
+
statusCards?.abandon(statusContext.segmentId);
|
|
7619
7995
|
return true;
|
|
7620
7996
|
});
|
|
7621
7997
|
}
|
|
@@ -7657,7 +8033,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7657
8033
|
} else {
|
|
7658
8034
|
const statusContext = run.statusContext;
|
|
7659
8035
|
if (statusContext) {
|
|
7660
|
-
await this.options.statusCards?.complete(statusContext.segmentId, "", (retained) => retained ? this.withSenderPrefix(run, retained) : retained);
|
|
8036
|
+
await this.options.statusCards?.complete(statusContext.segmentId, "", (retained) => retained ? this.withSenderPrefix(run, this.withoutRenderedSourcePrefix(run, retained)) : retained);
|
|
7661
8037
|
}
|
|
7662
8038
|
}
|
|
7663
8039
|
});
|
|
@@ -7700,7 +8076,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7700
8076
|
if (!delivered || !this.options.sendFallback)
|
|
7701
8077
|
return;
|
|
7702
8078
|
run.cardDelivered = void 0;
|
|
7703
|
-
await this.
|
|
8079
|
+
await this.sendFallback(run, delivered.chatId, delivered.text, delivered.sessionId);
|
|
7704
8080
|
}
|
|
7705
8081
|
enqueue(run, operation) {
|
|
7706
8082
|
const result = run.projectionChain.then(operation);
|
|
@@ -7717,14 +8093,38 @@ var DingtalkInteractionPresenter = class {
|
|
|
7717
8093
|
return `${TRUNCATION_MARKER}${content.slice(content.length - (limit - TRUNCATION_MARKER.length))}`;
|
|
7718
8094
|
}
|
|
7719
8095
|
withSenderPrefix(run, content) {
|
|
7720
|
-
|
|
8096
|
+
const prefixes = [
|
|
8097
|
+
run.senderPrefix,
|
|
8098
|
+
run.sourceLabel ? escapeDingTalkMarkdown(run.sourceLabel) : void 0
|
|
8099
|
+
].filter((value) => Boolean(value));
|
|
8100
|
+
if (prefixes.length === 0)
|
|
7721
8101
|
return this.boundContent(content);
|
|
7722
8102
|
const body = this.withoutExistingSenderPrefix(run, content);
|
|
8103
|
+
const prefix = prefixes.join("\n\n");
|
|
7723
8104
|
if (!body)
|
|
7724
|
-
return
|
|
8105
|
+
return prefix;
|
|
7725
8106
|
const separator = "\n\n";
|
|
7726
|
-
const bodyLimit = Math.max(0, CONTENT_LIMIT -
|
|
7727
|
-
return `${
|
|
8107
|
+
const bodyLimit = Math.max(0, CONTENT_LIMIT - prefix.length - separator.length);
|
|
8108
|
+
return `${prefix}${separator}${this.boundContent(body, bodyLimit)}`;
|
|
8109
|
+
}
|
|
8110
|
+
withSourcePrefix(run, content) {
|
|
8111
|
+
if (!run.sourceLabel)
|
|
8112
|
+
return this.boundContent(content);
|
|
8113
|
+
const sourceLabel = escapeDingTalkMarkdown(run.sourceLabel);
|
|
8114
|
+
if (!content)
|
|
8115
|
+
return sourceLabel;
|
|
8116
|
+
return `${sourceLabel}
|
|
8117
|
+
|
|
8118
|
+
${this.boundContent(content, Math.max(0, CONTENT_LIMIT - sourceLabel.length - 2))}`;
|
|
8119
|
+
}
|
|
8120
|
+
async sendFallback(run, chatId, text, sessionId) {
|
|
8121
|
+
if (!this.options.sendFallback)
|
|
8122
|
+
return;
|
|
8123
|
+
if (run.sourceLabel) {
|
|
8124
|
+
await this.options.sendFallback(chatId, text, sessionId, run.sourceLabel);
|
|
8125
|
+
return;
|
|
8126
|
+
}
|
|
8127
|
+
await this.options.sendFallback(chatId, text, sessionId);
|
|
7728
8128
|
}
|
|
7729
8129
|
withoutExistingSenderPrefix(run, content) {
|
|
7730
8130
|
const prefixes = /* @__PURE__ */ new Set([run.senderPrefix, run.senderRawPrefix]);
|
|
@@ -7750,6 +8150,17 @@ var DingtalkInteractionPresenter = class {
|
|
|
7750
8150
|
}
|
|
7751
8151
|
return body;
|
|
7752
8152
|
}
|
|
8153
|
+
withoutRenderedSourcePrefix(run, content) {
|
|
8154
|
+
if (!run.sourceLabel)
|
|
8155
|
+
return content;
|
|
8156
|
+
const rendered = escapeDingTalkMarkdown(run.sourceLabel);
|
|
8157
|
+
if (content === rendered)
|
|
8158
|
+
return "";
|
|
8159
|
+
const prefix = `${rendered}
|
|
8160
|
+
|
|
8161
|
+
`;
|
|
8162
|
+
return content.startsWith(prefix) ? content.slice(prefix.length) : content;
|
|
8163
|
+
}
|
|
7753
8164
|
ensureStatusContext(run, segment) {
|
|
7754
8165
|
if (run.statusContext)
|
|
7755
8166
|
return run.statusContext;
|
|
@@ -7980,9 +8391,102 @@ var EMOTION_RETRY_BASE_DELAY_MS = 250;
|
|
|
7980
8391
|
var GROUP_MSG_API = "https://api.dingtalk.com/v1.0/robot/groupMessages/send";
|
|
7981
8392
|
var DIRECT_MSG_API = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend";
|
|
7982
8393
|
var PROACTIVE_MSG_KEY = "sampleMarkdown";
|
|
8394
|
+
var PROACTIVE_FILE_MSG_KEY = "sampleFile";
|
|
7983
8395
|
var TOKEN_API = "https://oapi.dingtalk.com/gettoken";
|
|
7984
8396
|
var PROACTIVE_FETCH_TIMEOUT_MS = 15e3;
|
|
8397
|
+
var ROBOT_MESSAGE_HOSTS = /* @__PURE__ */ new Set(["api.dingtalk.com", "oapi.dingtalk.com"]);
|
|
8398
|
+
var PERMANENT_TOKEN_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
8399
|
+
40001,
|
|
8400
|
+
40013,
|
|
8401
|
+
40089,
|
|
8402
|
+
40096,
|
|
8403
|
+
90002,
|
|
8404
|
+
90003
|
|
8405
|
+
]);
|
|
7985
8406
|
var REPLY_FETCH_TIMEOUT_MS = 15e3;
|
|
8407
|
+
function presentInboundError(error) {
|
|
8408
|
+
const parts = [];
|
|
8409
|
+
let status;
|
|
8410
|
+
try {
|
|
8411
|
+
if (error instanceof Error) {
|
|
8412
|
+
if (typeof error.name === "string")
|
|
8413
|
+
parts.push(error.name);
|
|
8414
|
+
if (typeof error.message === "string")
|
|
8415
|
+
parts.push(error.message);
|
|
8416
|
+
} else if (typeof error === "string") {
|
|
8417
|
+
parts.push(error);
|
|
8418
|
+
}
|
|
8419
|
+
if (typeof error === "object" && error !== null) {
|
|
8420
|
+
const record = error;
|
|
8421
|
+
if (typeof record["code"] === "string")
|
|
8422
|
+
parts.push(record["code"]);
|
|
8423
|
+
if (typeof record["status"] === "number")
|
|
8424
|
+
status = record["status"];
|
|
8425
|
+
const body = record["body"];
|
|
8426
|
+
if (typeof body === "string") {
|
|
8427
|
+
parts.push(body);
|
|
8428
|
+
} else if (typeof body === "object" && body !== null) {
|
|
8429
|
+
const bodyRecord = body;
|
|
8430
|
+
for (const key of ["code", "errorKind", "message"]) {
|
|
8431
|
+
if (typeof bodyRecord[key] === "string")
|
|
8432
|
+
parts.push(bodyRecord[key]);
|
|
8433
|
+
}
|
|
8434
|
+
}
|
|
8435
|
+
}
|
|
8436
|
+
} catch {
|
|
8437
|
+
return {
|
|
8438
|
+
status: "Processing failed",
|
|
8439
|
+
nextStep: "Try again. If it keeps failing, contact the bot administrator."
|
|
8440
|
+
};
|
|
8441
|
+
}
|
|
8442
|
+
const diagnostic = parts.join(" ").slice(0, 2e3).toLowerCase();
|
|
8443
|
+
if (status === 401 || status === 403 || /unauthor|forbidden|authentication|credential|invalid.?token/.test(diagnostic)) {
|
|
8444
|
+
return {
|
|
8445
|
+
status: "Bot configuration error",
|
|
8446
|
+
nextStep: "Contact the bot administrator."
|
|
8447
|
+
};
|
|
8448
|
+
}
|
|
8449
|
+
if (status === 408 || status === 504 || /timeout|timed?\s+out|deadline/.test(diagnostic)) {
|
|
8450
|
+
return {
|
|
8451
|
+
status: "Request timed out",
|
|
8452
|
+
nextStep: "Try again. For a large request, split it into smaller parts."
|
|
8453
|
+
};
|
|
8454
|
+
}
|
|
8455
|
+
if (/cancel|abort/.test(diagnostic)) {
|
|
8456
|
+
return {
|
|
8457
|
+
status: "Request was cancelled",
|
|
8458
|
+
nextStep: "Send the request again if you still need it."
|
|
8459
|
+
};
|
|
8460
|
+
}
|
|
8461
|
+
if (status === 429 || /overload|rate.?limit|queue.?full|too many|busy|pending prompts full/.test(diagnostic)) {
|
|
8462
|
+
return {
|
|
8463
|
+
status: "Service is busy",
|
|
8464
|
+
nextStep: "Try again in a moment."
|
|
8465
|
+
};
|
|
8466
|
+
}
|
|
8467
|
+
if (status === 502 || status === 503 || /unavailable|econn|enotfound|etimedout|network|socket|fetch failed|connection|session[_ ](?:not[ _]found|closing)|workspace[_ ]draining|transport closed/.test(diagnostic)) {
|
|
8468
|
+
return {
|
|
8469
|
+
status: "Service is temporarily unavailable",
|
|
8470
|
+
nextStep: "Try again in a moment. If it keeps failing, contact the bot administrator."
|
|
8471
|
+
};
|
|
8472
|
+
}
|
|
8473
|
+
return {
|
|
8474
|
+
status: "Processing failed",
|
|
8475
|
+
nextStep: "Try again. If it keeps failing, contact the bot administrator."
|
|
8476
|
+
};
|
|
8477
|
+
}
|
|
8478
|
+
__name(presentInboundError, "presentInboundError");
|
|
8479
|
+
function formatInboundErrorMessage(error, reference) {
|
|
8480
|
+
const presentation = presentInboundError(error);
|
|
8481
|
+
return [
|
|
8482
|
+
"**Unable to process this message**",
|
|
8483
|
+
"",
|
|
8484
|
+
`**Status:** ${presentation.status}`,
|
|
8485
|
+
`**Next step:** ${presentation.nextStep}`,
|
|
8486
|
+
`**Reference:** \`${reference}\``
|
|
8487
|
+
].join("\n");
|
|
8488
|
+
}
|
|
8489
|
+
__name(formatInboundErrorMessage, "formatInboundErrorMessage");
|
|
7986
8490
|
var GENERATED_MEDIA_EXT = {
|
|
7987
8491
|
"image/jpeg": "jpg",
|
|
7988
8492
|
"image/png": "png",
|
|
@@ -8002,6 +8506,15 @@ var IMAGE_INSTRUCTIONS = [
|
|
|
8002
8506
|
"",
|
|
8003
8507
|
"Only use a real image file inside the workspace or system temporary directory."
|
|
8004
8508
|
].join("\n");
|
|
8509
|
+
var FILE_INSTRUCTIONS = [
|
|
8510
|
+
"",
|
|
8511
|
+
"When the user explicitly asks for a completed local file, send it by writing this on its own line:",
|
|
8512
|
+
"`[FILE: /absolute/path/to/file]` (without the backticks)",
|
|
8513
|
+
"",
|
|
8514
|
+
"Use at most five non-empty files inside the workspace or system temporary directory.",
|
|
8515
|
+
"File paths containing ] are not supported.",
|
|
8516
|
+
"Do not claim delivery succeeded; DingTalk shows successful files separately and reports failures in the final text."
|
|
8517
|
+
].join("\n");
|
|
8005
8518
|
function collectNonBotMentionIds(data) {
|
|
8006
8519
|
if (!Array.isArray(data.atUsers) || typeof data.chatbotUserId !== "string") {
|
|
8007
8520
|
return [];
|
|
@@ -8083,6 +8596,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8083
8596
|
} else if (!this.config.instructions.includes("[IMAGE:")) {
|
|
8084
8597
|
this.config.instructions += IMAGE_INSTRUCTIONS;
|
|
8085
8598
|
}
|
|
8599
|
+
if (config.blockStreaming !== "on" && !this.config.instructions.includes("[FILE:")) {
|
|
8600
|
+
this.config.instructions += FILE_INSTRUCTIONS;
|
|
8601
|
+
}
|
|
8086
8602
|
this.interactiveCardConfig = parseDingtalkInteractiveCardConfig(config.interactiveCards);
|
|
8087
8603
|
if (!config.clientId || !config.clientSecret) {
|
|
8088
8604
|
throw new Error(`Channel "${name}" requires clientId and clientSecret for DingTalk.`);
|
|
@@ -8096,7 +8612,12 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8096
8612
|
if (this.interactiveCardConfig.enabled) {
|
|
8097
8613
|
this.interactiveCardClient = new DingtalkInteractiveCardClient({
|
|
8098
8614
|
robotCode: config.clientId,
|
|
8099
|
-
getAccessToken: /* @__PURE__ */ __name(() => this.getProactiveToken(), "getAccessToken")
|
|
8615
|
+
getAccessToken: /* @__PURE__ */ __name(() => this.getProactiveToken(), "getAccessToken"),
|
|
8616
|
+
invalidateAccessToken: /* @__PURE__ */ __name((token) => {
|
|
8617
|
+
if (this.proactiveToken?.token === token) {
|
|
8618
|
+
this.proactiveToken = void 0;
|
|
8619
|
+
}
|
|
8620
|
+
}, "invalidateAccessToken")
|
|
8100
8621
|
});
|
|
8101
8622
|
if (this.interactiveCardConfig.statusCard.enabled && config.blockStreaming !== "on") {
|
|
8102
8623
|
this.statusCardController = new StatusCardController({
|
|
@@ -8113,7 +8634,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8113
8634
|
this.questionCardController = new QuestionCardController({
|
|
8114
8635
|
client: this.interactiveCardClient,
|
|
8115
8636
|
timeoutMs: this.interactiveCardConfig.questionCard.timeoutMs,
|
|
8116
|
-
sendFallback: /* @__PURE__ */ __name((chatId, text) => this.
|
|
8637
|
+
sendFallback: /* @__PURE__ */ __name((chatId, text, sourceLabel) => this.sendReply(chatId, text, void 0, sourceLabel), "sendFallback"),
|
|
8117
8638
|
reserveRunProjection: /* @__PURE__ */ __name((runId) => this.interactionPresenter?.reserveProjection(runId), "reserveRunProjection"),
|
|
8118
8639
|
onError: /* @__PURE__ */ __name((operation, error) => {
|
|
8119
8640
|
process.stderr.write(`[DingTalk:${this.name}] ${operation} failed: ${sanitizeLogText(String(error), 300)}
|
|
@@ -8126,7 +8647,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8126
8647
|
statusCards: this.statusCardController,
|
|
8127
8648
|
questionCards: this.questionCardController,
|
|
8128
8649
|
...config.blockStreaming !== "on" ? {
|
|
8129
|
-
sendFallback: /* @__PURE__ */ __name((chatId, text, sessionId) => this.sendFallbackReply(chatId, text, sessionId), "sendFallback")
|
|
8650
|
+
sendFallback: /* @__PURE__ */ __name((chatId, text, sessionId, sourceLabel) => this.sendFallbackReply(chatId, text, sessionId, sourceLabel), "sendFallback")
|
|
8130
8651
|
} : {}
|
|
8131
8652
|
});
|
|
8132
8653
|
}
|
|
@@ -8315,24 +8836,135 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8315
8836
|
static isUnroutableGroupMessage(isGroup, conversationId) {
|
|
8316
8837
|
return isGroup && !conversationId;
|
|
8317
8838
|
}
|
|
8318
|
-
|
|
8839
|
+
resolveSessionWebhook(chatId) {
|
|
8840
|
+
const value = this.webhooks.get(chatId);
|
|
8841
|
+
if (!value)
|
|
8842
|
+
return void 0;
|
|
8843
|
+
try {
|
|
8844
|
+
const url2 = new URL(value);
|
|
8845
|
+
return url2.protocol === "https:" && url2.port === "" && ROBOT_MESSAGE_HOSTS.has(url2.hostname) ? url2.toString() : void 0;
|
|
8846
|
+
} catch {
|
|
8847
|
+
return void 0;
|
|
8848
|
+
}
|
|
8849
|
+
}
|
|
8850
|
+
async uploadOutboundFile(filePath) {
|
|
8851
|
+
const file = readValidatedFile(filePath, this.config.cwd);
|
|
8852
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
8853
|
+
const token = await this.getProactiveToken();
|
|
8854
|
+
try {
|
|
8855
|
+
return { file, mediaId: await uploadDingTalkFile(file, token) };
|
|
8856
|
+
} catch (error) {
|
|
8857
|
+
if (error instanceof DingTalkMediaUploadError && error.authFailure && attempt === 0) {
|
|
8858
|
+
this.proactiveToken = void 0;
|
|
8859
|
+
continue;
|
|
8860
|
+
}
|
|
8861
|
+
throw error;
|
|
8862
|
+
}
|
|
8863
|
+
}
|
|
8864
|
+
throw new Error("DingTalk file upload returned no MediaID");
|
|
8865
|
+
}
|
|
8866
|
+
async deliverFiles(paths, send, preflight) {
|
|
8867
|
+
const notices = [];
|
|
8868
|
+
for (const filePath of paths) {
|
|
8869
|
+
const displayName = safeFileName(filePath);
|
|
8870
|
+
try {
|
|
8871
|
+
preflight?.();
|
|
8872
|
+
const { file, mediaId } = await this.uploadOutboundFile(filePath);
|
|
8873
|
+
await send(file, mediaId);
|
|
8874
|
+
} catch (error) {
|
|
8875
|
+
process.stderr.write(`[DingTalk:${this.name}] outbound file delivery failed (${sanitizeLogText(displayName, 200)}): ${sanitizeLogText(error instanceof Error ? error.message : String(error), 300)}
|
|
8876
|
+
`);
|
|
8877
|
+
notices.push(`[File delivery failed: ${displayName}]`);
|
|
8878
|
+
}
|
|
8879
|
+
}
|
|
8880
|
+
return notices;
|
|
8881
|
+
}
|
|
8882
|
+
async sendSessionFile(chatId, file, mediaId) {
|
|
8883
|
+
const webhook = this.resolveSessionWebhook(chatId);
|
|
8884
|
+
if (!webhook)
|
|
8885
|
+
throw new Error("DingTalk session webhook unavailable");
|
|
8886
|
+
let response;
|
|
8887
|
+
try {
|
|
8888
|
+
response = await fetch(webhook, {
|
|
8889
|
+
method: "POST",
|
|
8890
|
+
redirect: "error",
|
|
8891
|
+
headers: { "Content-Type": "application/json" },
|
|
8892
|
+
body: JSON.stringify({
|
|
8893
|
+
msgtype: "file",
|
|
8894
|
+
file: {
|
|
8895
|
+
mediaId,
|
|
8896
|
+
fileName: file.fileName,
|
|
8897
|
+
fileType: file.fileType
|
|
8898
|
+
}
|
|
8899
|
+
}),
|
|
8900
|
+
signal: AbortSignal.timeout(REPLY_FETCH_TIMEOUT_MS)
|
|
8901
|
+
});
|
|
8902
|
+
} catch {
|
|
8903
|
+
throw new Error("DingTalk file delivery failed: network request failed");
|
|
8904
|
+
}
|
|
8905
|
+
const body = await response.text().catch(() => "");
|
|
8906
|
+
if (!response.ok) {
|
|
8907
|
+
throw new Error(`DingTalk file delivery failed: HTTP ${response.status}`);
|
|
8908
|
+
}
|
|
8909
|
+
if (!body.trim())
|
|
8910
|
+
return;
|
|
8911
|
+
let data;
|
|
8912
|
+
try {
|
|
8913
|
+
const parsed = JSON.parse(body);
|
|
8914
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
8915
|
+
return;
|
|
8916
|
+
data = parsed;
|
|
8917
|
+
} catch {
|
|
8918
|
+
return;
|
|
8919
|
+
}
|
|
8920
|
+
const code = data["errcode"] ?? data["code"];
|
|
8921
|
+
if (code !== void 0 && String(code) !== "0") {
|
|
8922
|
+
throw new Error(`DingTalk file delivery failed: API code ${code}`);
|
|
8923
|
+
}
|
|
8924
|
+
}
|
|
8925
|
+
appendFileNotices(text, notices) {
|
|
8926
|
+
if (notices.length === 0)
|
|
8927
|
+
return text;
|
|
8928
|
+
const prefix = text.trimEnd();
|
|
8929
|
+
return `${prefix}${prefix ? "\n" : ""}${notices.join("\n")}`;
|
|
8930
|
+
}
|
|
8931
|
+
async prepareReplyOutput(chatId, text, streamed) {
|
|
8932
|
+
return this.prepareFileOutput(text, (file, mediaId) => this.sendSessionFile(chatId, file, mediaId), streamed, () => {
|
|
8933
|
+
if (!this.resolveSessionWebhook(chatId)) {
|
|
8934
|
+
throw new Error("DingTalk session webhook unavailable");
|
|
8935
|
+
}
|
|
8936
|
+
});
|
|
8937
|
+
}
|
|
8938
|
+
async prepareFileOutput(text, send, streamed, preflight) {
|
|
8319
8939
|
const projection = projectFileText(text);
|
|
8320
8940
|
const streamedMarkers = streamed ? streamed.result("").markerCount : 0;
|
|
8321
|
-
if (projection.markerCount
|
|
8322
|
-
|
|
8323
|
-
}
|
|
8324
|
-
process.stderr.write(`[DingTalk:${this.name}] file markers redacted (final=${projection.markerCount}, streamed=${streamedMarkers})
|
|
8941
|
+
if (projection.markerCount > 0 || streamedMarkers > 0) {
|
|
8942
|
+
process.stderr.write(`[DingTalk:${this.name}] file markers projected (final=${projection.markerCount}, streamed=${streamedMarkers})
|
|
8325
8943
|
`);
|
|
8326
|
-
|
|
8944
|
+
}
|
|
8945
|
+
if (this.config.blockStreaming === "on" && (projection.markerCount > 0 || streamedMarkers > 0)) {
|
|
8946
|
+
return this.prepareOutgoingText(withFileUnavailableNotice(projection.text));
|
|
8947
|
+
}
|
|
8948
|
+
const notices = [];
|
|
8949
|
+
if (projection.invalidMarkers > 0) {
|
|
8950
|
+
notices.push("[File delivery failed: invalid marker]");
|
|
8951
|
+
}
|
|
8952
|
+
if (projection.excessMarkers > 0) {
|
|
8953
|
+
notices.push("[File delivery failed: response file limit exceeded]");
|
|
8954
|
+
}
|
|
8955
|
+
if (streamedMarkers > projection.markerCount) {
|
|
8956
|
+
notices.push(FILE_UNAVAILABLE_NOTICE);
|
|
8957
|
+
}
|
|
8958
|
+
notices.push(...await this.deliverFiles(projection.paths, send, preflight));
|
|
8959
|
+
return this.prepareOutgoingText(this.appendFileNotices(projection.text, notices));
|
|
8327
8960
|
}
|
|
8328
|
-
async prepareOutgoingText(text
|
|
8329
|
-
const
|
|
8330
|
-
const markers = findImageMarkers(fileSafeText);
|
|
8961
|
+
async prepareOutgoingText(text) {
|
|
8962
|
+
const markers = findImageMarkers(text);
|
|
8331
8963
|
if (markers.length === 0)
|
|
8332
|
-
return
|
|
8964
|
+
return text;
|
|
8333
8965
|
const replacements = [];
|
|
8334
8966
|
for (const marker of markers) {
|
|
8335
|
-
const fileName =
|
|
8967
|
+
const fileName = basename3(marker.path).replace(/[\r\n[\]]+/g, "_").slice(0, 100) || "image";
|
|
8336
8968
|
try {
|
|
8337
8969
|
const image = readValidatedImage(marker.path, {
|
|
8338
8970
|
workspaceDir: this.config.cwd
|
|
@@ -8361,20 +8993,29 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8361
8993
|
replacements.push(`[Image delivery failed: ${fileName}]`);
|
|
8362
8994
|
}
|
|
8363
8995
|
}
|
|
8364
|
-
return replaceImageMarkers(
|
|
8996
|
+
return replaceImageMarkers(text, markers, replacements);
|
|
8365
8997
|
}
|
|
8366
|
-
async sendReply(chatId, text, atUserId) {
|
|
8998
|
+
async sendReply(chatId, text, atUserId, sourceLabel, prepared = false) {
|
|
8367
8999
|
const webhook = this.webhooks.get(chatId);
|
|
8368
9000
|
if (!webhook) {
|
|
8369
9001
|
process.stderr.write(`[DingTalk:${this.name}] No webhook for chatId ${chatId}, cannot send.
|
|
8370
9002
|
`);
|
|
8371
9003
|
return;
|
|
8372
9004
|
}
|
|
8373
|
-
const outgoingText = await this.
|
|
9005
|
+
const outgoingText = prepared ? text : await this.prepareReplyOutput(chatId, text);
|
|
9006
|
+
if (!outgoingText.trim())
|
|
9007
|
+
return;
|
|
8374
9008
|
const mentionPrefix = atUserId ? `@${atUserId}
|
|
8375
9009
|
|
|
8376
9010
|
` : "";
|
|
8377
|
-
const
|
|
9011
|
+
const sourcePrefix = sourceLabel && outgoingText.trim().length > 0 ? `${escapeDingTalkMarkdown(sourceLabel)}
|
|
9012
|
+
|
|
9013
|
+
` : "";
|
|
9014
|
+
const contentLimit = DINGTALK_CHUNK_LIMIT - mentionPrefix.length - sourcePrefix.length;
|
|
9015
|
+
if (contentLimit <= 0) {
|
|
9016
|
+
throw new Error("DingTalk source label exceeds the message limit.");
|
|
9017
|
+
}
|
|
9018
|
+
const chunks = normalizeDingTalkMarkdown(outgoingText, contentLimit).map((chunk, index) => `${index === 0 ? mentionPrefix : ""}${sourcePrefix}${chunk}`);
|
|
8378
9019
|
const title = extractTitle(outgoingText);
|
|
8379
9020
|
for (let i = 0; i < chunks.length; i++) {
|
|
8380
9021
|
const chunk = chunks[i];
|
|
@@ -8418,6 +9059,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8418
9059
|
async sendMessage(chatId, text) {
|
|
8419
9060
|
await this.sendReply(chatId, text);
|
|
8420
9061
|
}
|
|
9062
|
+
async sendThreadMessage(chatId, _threadId, text, sourceLabel) {
|
|
9063
|
+
await this.sendReply(chatId, text, void 0, sourceLabel);
|
|
9064
|
+
}
|
|
8421
9065
|
supportsProactiveSend() {
|
|
8422
9066
|
return true;
|
|
8423
9067
|
}
|
|
@@ -8436,11 +9080,20 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8436
9080
|
* Single-shot cold send: a failed chunk aborts the remainder (already-sent
|
|
8437
9081
|
* chunks are not recalled) and the error surfaces in the loop's lastError.
|
|
8438
9082
|
*/
|
|
8439
|
-
async pushProactive(target, text) {
|
|
9083
|
+
async pushProactive(target, text, sourceLabel) {
|
|
8440
9084
|
if (!text.trim())
|
|
8441
9085
|
return;
|
|
8442
|
-
const outgoingText = await this.
|
|
8443
|
-
|
|
9086
|
+
const outgoingText = await this.prepareFileOutput(text, (file, mediaId) => this.sendProactiveFile(target, file, mediaId));
|
|
9087
|
+
if (!outgoingText.trim())
|
|
9088
|
+
return;
|
|
9089
|
+
const sourcePrefix = sourceLabel ? `${escapeDingTalkMarkdown(sourceLabel)}
|
|
9090
|
+
|
|
9091
|
+
` : "";
|
|
9092
|
+
const contentLimit = DINGTALK_CHUNK_LIMIT - sourcePrefix.length;
|
|
9093
|
+
if (contentLimit <= 0) {
|
|
9094
|
+
throw new Error("DingTalk source label exceeds the message limit.");
|
|
9095
|
+
}
|
|
9096
|
+
const chunks = normalizeDingTalkMarkdown(outgoingText, contentLimit).map((chunk) => `${sourcePrefix}${chunk}`);
|
|
8444
9097
|
const title = extractTitle(outgoingText);
|
|
8445
9098
|
for (let i = 0; i < chunks.length; i++) {
|
|
8446
9099
|
await this.sendProactiveChunk(target, i === 0 ? title : `${title} (cont.)`, chunks[i], `chunk ${i + 1}/${chunks.length}`);
|
|
@@ -8466,7 +9119,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8466
9119
|
const errmsg = sanitizeLogText(String(data.errmsg ?? ""), 200);
|
|
8467
9120
|
process.stderr.write(`[DingTalk:${this.name}] access token request failed: gettoken errcode=${data.errcode} ${errmsg}
|
|
8468
9121
|
`);
|
|
8469
|
-
throw new
|
|
9122
|
+
throw new DingtalkCardRequestError(`DingTalk access token request failed: gettoken errcode=${data.errcode}${errmsg ? ` ${errmsg}` : ""}`, !PERMANENT_TOKEN_ERROR_CODES.has(Number(data.errcode)));
|
|
8470
9123
|
}
|
|
8471
9124
|
this.proactiveToken = {
|
|
8472
9125
|
token: data.access_token,
|
|
@@ -8492,6 +9145,12 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8492
9145
|
}, "\u5361\u7247\u64CD\u4F5C", "\u4F60\u65E0\u6743\u64CD\u4F5C\u8FD9\u5F20\u5361\u7247\uFF0C\u4EC5\u4EFB\u52A1\u53D1\u8D77\u4EBA\u53EF\u4EE5\u63D0\u4EA4\u6216\u505C\u6B62\u3002", "card interaction feedback");
|
|
8493
9146
|
}
|
|
8494
9147
|
async sendProactiveChunk(target, title, text, chunkLabel) {
|
|
9148
|
+
return this.sendProactivePayload(target, PROACTIVE_MSG_KEY, { title, text }, chunkLabel);
|
|
9149
|
+
}
|
|
9150
|
+
async sendProactiveFile(target, file, mediaId) {
|
|
9151
|
+
return this.sendProactivePayload(target, PROACTIVE_FILE_MSG_KEY, { mediaId, fileName: file.fileName, fileType: file.fileType }, `file ${file.fileName}`);
|
|
9152
|
+
}
|
|
9153
|
+
async sendProactivePayload(target, msgKey, msgParam, chunkLabel) {
|
|
8495
9154
|
const targetKind = target.isGroup === true ? "group" : "dm";
|
|
8496
9155
|
for (let attempt = 0; ; attempt++) {
|
|
8497
9156
|
const token = await this.getProactiveToken();
|
|
@@ -8507,8 +9166,8 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8507
9166
|
body: JSON.stringify({
|
|
8508
9167
|
robotCode: this.config.clientId,
|
|
8509
9168
|
...targetBody,
|
|
8510
|
-
msgKey
|
|
8511
|
-
msgParam: JSON.stringify(
|
|
9169
|
+
msgKey,
|
|
9170
|
+
msgParam: JSON.stringify(msgParam)
|
|
8512
9171
|
}),
|
|
8513
9172
|
signal: AbortSignal.timeout(PROACTIVE_FETCH_TIMEOUT_MS)
|
|
8514
9173
|
});
|
|
@@ -8529,6 +9188,27 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8529
9188
|
`);
|
|
8530
9189
|
throw new Error(`DingTalk proactive send failed: HTTP ${resp.status}${detail ? ` ${detail}` : ""}`);
|
|
8531
9190
|
}
|
|
9191
|
+
if (target.isGroup === true) {
|
|
9192
|
+
if (msgKey !== PROACTIVE_FILE_MSG_KEY) {
|
|
9193
|
+
await resp.body?.cancel();
|
|
9194
|
+
return;
|
|
9195
|
+
}
|
|
9196
|
+
let data;
|
|
9197
|
+
try {
|
|
9198
|
+
const parsed = await resp.json();
|
|
9199
|
+
data = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
9200
|
+
} catch {
|
|
9201
|
+
throw new Error("DingTalk file delivery failed: invalid JSON response");
|
|
9202
|
+
}
|
|
9203
|
+
const code = data["errcode"] ?? data["code"];
|
|
9204
|
+
if (code !== void 0 && String(code) !== "0") {
|
|
9205
|
+
throw new Error(`DingTalk file delivery failed: API code ${code}`);
|
|
9206
|
+
}
|
|
9207
|
+
if (typeof data["processQueryKey"] !== "string" || !data["processQueryKey"].trim()) {
|
|
9208
|
+
throw new Error("DingTalk file delivery failed: missing processQueryKey");
|
|
9209
|
+
}
|
|
9210
|
+
return;
|
|
9211
|
+
}
|
|
8532
9212
|
if (target.isGroup === false) {
|
|
8533
9213
|
let data;
|
|
8534
9214
|
try {
|
|
@@ -8548,6 +9228,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8548
9228
|
`);
|
|
8549
9229
|
throw new Error("DingTalk proactive send failed: direct recipient rate limited");
|
|
8550
9230
|
}
|
|
9231
|
+
if (msgKey === PROACTIVE_FILE_MSG_KEY && !data.processQueryKey?.trim()) {
|
|
9232
|
+
throw new Error("DingTalk file delivery failed: missing processQueryKey");
|
|
9233
|
+
}
|
|
8551
9234
|
return;
|
|
8552
9235
|
}
|
|
8553
9236
|
await resp.body?.cancel();
|
|
@@ -8612,6 +9295,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8612
9295
|
if (this.dedupTimer) {
|
|
8613
9296
|
clearInterval(this.dedupTimer);
|
|
8614
9297
|
}
|
|
9298
|
+
this.statusCardController?.dispose();
|
|
8615
9299
|
this.activeReactionKeys.clear();
|
|
8616
9300
|
this.sessionReactionKeys.clear();
|
|
8617
9301
|
if (this.connectionManager) {
|
|
@@ -8733,7 +9417,8 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8733
9417
|
if (event.runId && event.owner && inboundOwner?.ownerId === event.owner.id) {
|
|
8734
9418
|
this.cardRuns.set(event.runId, inboundOwner);
|
|
8735
9419
|
this.cardRunBySession.set(event.sessionId, event.runId);
|
|
8736
|
-
this.
|
|
9420
|
+
const sourceLabel = this.getResponseSourceLabel(event.sessionId);
|
|
9421
|
+
this.interactionPresenter?.registerRun(event.runId, event.owner.id, inboundOwner.target, event.sessionId, inboundOwner.sender, ...sourceLabel ? [sourceLabel] : []);
|
|
8737
9422
|
this.interactionPresenter?.startStatusCard(event.runId);
|
|
8738
9423
|
}
|
|
8739
9424
|
return;
|
|
@@ -8873,7 +9558,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8873
9558
|
const tail = state.projector.complete();
|
|
8874
9559
|
if (!tail.trim())
|
|
8875
9560
|
return;
|
|
8876
|
-
void this.sendReply(chatId, tail).catch((err) => {
|
|
9561
|
+
void this.sendReply(chatId, tail, void 0, this.getResponseSourceLabel(sessionId)).catch((err) => {
|
|
8877
9562
|
process.stderr.write(`[DingTalk:${this.name}] projector tail delivery failed for session ${sessionId}: ${err instanceof Error ? err.message : String(err)}
|
|
8878
9563
|
`);
|
|
8879
9564
|
});
|
|
@@ -8883,13 +9568,13 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8883
9568
|
* the session's block-streaming projector: a second sender interleaving with
|
|
8884
9569
|
* mid-projection state can swallow the send or split a held marker.
|
|
8885
9570
|
*/
|
|
8886
|
-
async deliverBackgroundReply(chatId, text, sessionId) {
|
|
9571
|
+
async deliverBackgroundReply(chatId, text, sessionId, sourceLabel) {
|
|
8887
9572
|
if (this.config.blockStreaming !== "on") {
|
|
8888
|
-
return super.deliverBackgroundReply(chatId, text, sessionId);
|
|
9573
|
+
return super.deliverBackgroundReply(chatId, text, sessionId, sourceLabel);
|
|
8889
9574
|
}
|
|
8890
|
-
await this.sendReply(chatId, text);
|
|
9575
|
+
await this.sendReply(chatId, text, void 0, sourceLabel);
|
|
8891
9576
|
}
|
|
8892
|
-
async sendResponseMessage(chatId, text, sessionId) {
|
|
9577
|
+
async sendResponseMessage(chatId, text, sessionId, sourceLabel, prepared = false) {
|
|
8893
9578
|
let outgoingText = text;
|
|
8894
9579
|
let consumesMention = true;
|
|
8895
9580
|
if (this.config.blockStreaming === "on") {
|
|
@@ -8902,7 +9587,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8902
9587
|
const atUserId = consumesMention && this.atSender ? this.sessionMentionTargets.get(sessionId) : void 0;
|
|
8903
9588
|
if (atUserId)
|
|
8904
9589
|
this.sessionMentionTargets.delete(sessionId);
|
|
8905
|
-
await this.sendReply(chatId, outgoingText, atUserId);
|
|
9590
|
+
await this.sendReply(chatId, outgoingText, atUserId, sourceLabel ?? this.getResponseSourceLabel(sessionId), prepared);
|
|
8906
9591
|
}
|
|
8907
9592
|
projectBlockStreamChunk(text, sessionId) {
|
|
8908
9593
|
let state = this.blockFileProjectors.get(sessionId);
|
|
@@ -8925,21 +9610,21 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8925
9610
|
}
|
|
8926
9611
|
return { text: outgoingText, hasContent };
|
|
8927
9612
|
}
|
|
8928
|
-
async sendFallbackReply(chatId, text, sessionId) {
|
|
9613
|
+
async sendFallbackReply(chatId, text, sessionId, sourceLabel) {
|
|
8929
9614
|
const atUserId = this.atSender ? this.sessionMentionTargets.get(sessionId) : void 0;
|
|
8930
|
-
await this.sendReply(chatId, text, atUserId);
|
|
9615
|
+
await this.sendReply(chatId, text, atUserId, sourceLabel);
|
|
8931
9616
|
}
|
|
8932
9617
|
async onResponseComplete(chatId, text, sessionId, segment) {
|
|
8933
9618
|
const streamed = segment ? this.fileProjectors.get(segment.runId)?.projector : void 0;
|
|
8934
9619
|
if (segment)
|
|
8935
9620
|
this.fileProjectors.delete(segment.runId);
|
|
8936
|
-
const outgoingText = await this.
|
|
9621
|
+
const outgoingText = await this.prepareReplyOutput(chatId, text, streamed);
|
|
8937
9622
|
if (segment && this.interactionPresenter) {
|
|
8938
9623
|
if (await this.interactionPresenter.closeOutput(segment.segmentId, outgoingText, "completed", segment)) {
|
|
8939
9624
|
return;
|
|
8940
9625
|
}
|
|
8941
9626
|
}
|
|
8942
|
-
await this.sendResponseMessage(chatId, outgoingText, sessionId);
|
|
9627
|
+
await this.sendResponseMessage(chatId, outgoingText, sessionId, segment?.sourceLabel, true);
|
|
8943
9628
|
}
|
|
8944
9629
|
onOutputSegmentEnd(_chatId, _sessionId, segment, reason) {
|
|
8945
9630
|
if (reason === "completed" || reason === "failed" || reason === "cancelled") {
|
|
@@ -9205,9 +9890,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9205
9890
|
let filePath;
|
|
9206
9891
|
let safeName;
|
|
9207
9892
|
try {
|
|
9208
|
-
dir = join(
|
|
9893
|
+
dir = join(tmpdir3(), "channel-files", randomUUID5());
|
|
9209
9894
|
mkdirSync(dir, { recursive: true });
|
|
9210
|
-
safeName =
|
|
9895
|
+
safeName = basename3(typeof fileName === "string" ? fileName : "") || `dingtalk_${mediaType}_${Date.now()}.${GENERATED_MEDIA_EXT[media.mimeType] ?? "bin"}`;
|
|
9211
9896
|
filePath = join(dir, safeName);
|
|
9212
9897
|
writeFileSync(filePath, media.buffer);
|
|
9213
9898
|
} catch (error) {
|
|
@@ -9311,9 +9996,18 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9311
9996
|
}
|
|
9312
9997
|
}) : this.handleInbound(envelope);
|
|
9313
9998
|
processMessage.catch((err) => {
|
|
9314
|
-
|
|
9999
|
+
const reference = randomUUID5().slice(0, 8);
|
|
10000
|
+
let errorSummary = "Unknown error";
|
|
10001
|
+
try {
|
|
10002
|
+
errorSummary = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
|
|
10003
|
+
} catch {
|
|
10004
|
+
}
|
|
10005
|
+
process.stderr.write(`[DingTalk:${this.name}] Error handling message ref=${reference}: ${sanitizeLogText(errorSummary, 300)}
|
|
9315
10006
|
`);
|
|
9316
|
-
|
|
10007
|
+
const fallbackMessage = formatInboundErrorMessage(err, reference);
|
|
10008
|
+
const sourceLabel = this.getInboundErrorSourceLabel(envelope);
|
|
10009
|
+
const delivery = sourceLabel ? this.sendThreadMessage(chatId, envelope.threadId, fallbackMessage, sourceLabel) : this.sendMessage(chatId, fallbackMessage);
|
|
10010
|
+
delivery.catch(() => {
|
|
9317
10011
|
});
|
|
9318
10012
|
});
|
|
9319
10013
|
} catch (err) {
|