@qwen-code/qwen-code 0.22.3-nightly.20260831.3a0c4c6108 → 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/configuration/model-providers.md +4 -0
- package/bundled/qc-helper/docs/configuration/settings.md +53 -50
- package/bundled/qc-helper/docs/features/_meta.ts +1 -0
- 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 +1 -0
- package/bundled/qc-helper/docs/features/commands.md +38 -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 +2 -1
- package/bundled/qc-helper/docs/features/output-styles.md +38 -0
- package/bundled/qc-helper/docs/qwen-serve.md +15 -0
- package/bundled/review/SKILL.md +5 -5
- package/bundled/review/references/posting.md +2 -2
- package/chunks/{MaxSizedBox-IHRTWGSY.js → MaxSizedBox-B3D7545A.js} +41 -45
- package/chunks/{StandaloneSessionPicker-TLVWVTJ7.js → StandaloneSessionPicker-QUMO4LLQ.js} +64 -67
- package/chunks/{acpAgent-7I5LLPP3.js → acpAgent-2GTFCIEP.js} +771 -248
- package/chunks/{agent-4Z4NTJXD.js → agent-XKF5SZWU.js} +26 -30
- package/chunks/{agent-headless-TVUJXQWU.js → agent-headless-OC2IB55D.js} +26 -30
- package/chunks/{anthropicContentGenerator-VSSPG7XV.js → anthropicContentGenerator-L76MR5OR.js} +14 -14
- package/chunks/{artifact-tool-TEYW6I4A.js → artifact-tool-MYCL2QCS.js} +2 -3
- package/chunks/{askUserQuestion-PYNBWV63.js → askUserQuestion-THQZMG44.js} +2 -2
- package/chunks/{bridge-EVURP4NO.js → bridge-IHSBI2YJ.js} +42 -46
- package/chunks/{build-INBK7IXX.js → build-63BIOYWK.js} +1 -1
- package/chunks/{channel-management-service-IDBNYSFW.js → channel-management-service-4MTCEGJB.js} +4 -4
- package/chunks/{channel-settings-store-MZNXRKVI.js → channel-settings-store-BVKWAI2T.js} +50 -54
- package/chunks/{channel-worker-group-ZLP5SJHT.js → channel-worker-group-47F4ISUZ.js} +6 -6
- package/chunks/{channel-worker-manager-FG5377T2.js → channel-worker-manager-I5Y44GYR.js} +50 -9
- package/chunks/{channel-worker-supervisor-HDVE4ADS.js → channel-worker-supervisor-6VCLUXFE.js} +4 -4
- package/chunks/{chunk-3452WXOK.js → chunk-2M3EWQNG.js} +17 -0
- package/chunks/{chunk-HDMKCJHI.js → chunk-32LU3APX.js} +1 -1
- package/chunks/{chunk-BSJOBW4U.js → chunk-37JFWFCD.js} +1 -1
- package/chunks/{chunk-AN3KFCNH.js → chunk-3JQZVCBI.js} +2 -2
- package/chunks/{chunk-RGEV5AUD.js → chunk-3L724BJ5.js} +11 -8
- package/chunks/{chunk-GCUR24KK.js → chunk-47RYEQW5.js} +2 -2
- package/chunks/{chunk-CM4F4JBB.js → chunk-4BGDFKQE.js} +5 -5
- package/chunks/{chunk-ZBDYI7VM.js → chunk-4F7GQGXB.js} +10961 -4033
- package/chunks/{chunk-JMRE4WJQ.js → chunk-4HVH57J3.js} +81 -17
- package/chunks/{chunk-26SIKQIC.js → chunk-4LIFGNI4.js} +1 -1
- package/chunks/{chunk-U5RTYI7D.js → chunk-4M24B5J5.js} +13 -13
- package/chunks/{chunk-7XICSE62.js → chunk-4PSDSCW3.js} +3 -3
- package/chunks/{chunk-AYYKUUKP.js → chunk-4UANMABT.js} +73 -19
- package/chunks/{chunk-GS7XT345.js → chunk-54C6PIGT.js} +3 -3
- package/chunks/{chunk-UKB2TZAO.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-JOWQD4LO.js → chunk-5Q5RC2WE.js} +1 -1
- package/chunks/{chunk-3NQCZMUB.js → chunk-5RTTI4GE.js} +73 -73
- package/chunks/{chunk-J4Y3QJHF.js → chunk-64QH2UC6.js} +11 -1
- package/chunks/{chunk-I75VKFCJ.js → chunk-65HWLGA7.js} +1 -1
- package/chunks/{chunk-W7KWB6AH.js → chunk-6A2D4QSO.js} +8 -5
- package/chunks/{chunk-OTTNXUT5.js → chunk-7IKXTGZT.js} +1 -1
- package/chunks/{chunk-LYSZVCCD.js → chunk-7JMGTOH7.js} +427 -129
- package/chunks/{chunk-YOFULAHO.js → chunk-7RB56BRJ.js} +3 -3
- package/chunks/{chunk-6VHIWUJP.js → chunk-ADYN7P2Y.js} +2 -2
- package/chunks/{chunk-7DDTI7Q3.js → chunk-AHYTURFB.js} +1 -1
- package/chunks/{chunk-TNMOFNT4.js → chunk-ALUYNJPM.js} +1395 -2079
- package/chunks/{chunk-H2A2GJGL.js → chunk-AZJLY2XZ.js} +5 -5
- package/chunks/{chunk-BE5FGT5Z.js → chunk-BA4WJC4L.js} +1 -1
- package/chunks/{chunk-H5GPPDGY.js → chunk-BFY33IB4.js} +16 -8
- package/chunks/{chunk-RY7DL5IF.js → chunk-BJXCYUGM.js} +1 -1
- package/chunks/{chunk-ND7TQQPE.js → chunk-C2VWOXHS.js} +6 -6
- package/chunks/{chunk-T4RMUTTT.js → chunk-C4TIXFDZ.js} +2 -2
- package/chunks/{chunk-B2RIIK3K.js → chunk-CVX63TFJ.js} +3 -1
- package/chunks/{chunk-SMJYTKTB.js → chunk-DQCKVAF5.js} +1 -1
- package/chunks/{chunk-RLSPPTWH.js → chunk-DSX7KQPM.js} +438 -181
- package/chunks/{chunk-PNIGAVY6.js → chunk-DTVQSSNM.js} +2 -2
- package/chunks/{chunk-67AY5D3M.js → chunk-DYTW3QVG.js} +23 -8
- package/chunks/{chunk-3CZGSTZX.js → chunk-EBDGRBZX.js} +22 -14
- package/chunks/{chunk-DJBQCO2E.js → chunk-EFTPIZIC.js} +412 -3
- package/chunks/{chunk-QE7DTCLX.js → chunk-EIY7SUPZ.js} +1 -1
- package/chunks/{chunk-6OO7QEWV.js → chunk-EVFDRBUM.js} +97 -77
- package/chunks/{chunk-QTMPM6RC.js → chunk-EWRW2WQC.js} +3 -3
- package/chunks/{chunk-IIFL7QDN.js → chunk-F33GFWPR.js} +34 -11
- package/chunks/{chunk-YPISTYEI.js → chunk-F47DITLZ.js} +11 -1
- package/chunks/{chunk-OE5AQVNB.js → chunk-F7NF2IOE.js} +6 -6
- package/chunks/{chunk-RT4QNQ5P.js → chunk-FD5SJOWT.js} +8 -5
- package/chunks/{chunk-ACZ4YRYK.js → chunk-FRICLXCZ.js} +3 -3
- package/chunks/{chunk-IBMUI5EV.js → chunk-FUO5V5KI.js} +11 -4
- package/chunks/{chunk-T3TL6S3B.js → chunk-G5PBOQWI.js} +8 -5
- package/chunks/{chunk-D7D3HSYQ.js → chunk-G7HBEEX7.js} +12 -7
- package/chunks/{chunk-FXUSWLBF.js → chunk-GH2S4GD5.js} +133 -8
- package/chunks/{chunk-XPDKSOVW.js → chunk-GXUTFQXK.js} +42 -44
- package/chunks/{chunk-OSTQZIOY.js → chunk-H43PSPYS.js} +2 -2
- package/chunks/{chunk-UVYKCRJZ.js → chunk-HJBHMANB.js} +11 -13
- package/chunks/{chunk-WLEYH7CD.js → chunk-HRPFBHW7.js} +4 -0
- package/chunks/{chunk-DBTMP3P4.js → chunk-I2TMJPCV.js} +1 -1
- package/chunks/{chunk-EU2B4P3D.js → chunk-I4NRYS6A.js} +4 -4
- package/chunks/{chunk-JPKTAQS3.js → chunk-I5N4EAS6.js} +1 -1
- package/chunks/{chunk-W4BDHLRT.js → chunk-IG4W5SJR.js} +2 -2
- package/chunks/{chunk-BXNKREX7.js → chunk-IPATA3T2.js} +2 -2
- 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-AVNATYLY.js → chunk-JJKNYRFY.js} +1 -1
- package/chunks/{chunk-ERHAMGAA.js → chunk-JR42V4UY.js} +1 -1
- package/chunks/{chunk-NT7LXVV5.js → chunk-JUARRUMA.js} +362 -1084
- package/chunks/{chunk-OKMDOATP.js → chunk-KEVYJSI4.js} +11 -11
- package/chunks/{chunk-AF3QB6OL.js → chunk-KGV55H53.js} +1 -1
- package/chunks/{chunk-SDCHI64N.js → chunk-KM3XVTMO.js} +10 -4
- package/chunks/{chunk-ERRJA23L.js → chunk-KMU3ZHH4.js} +1 -1
- package/chunks/chunk-KOGW3YWJ.js +2054 -0
- package/chunks/{chunk-6NWPR2EB.js → chunk-L26ONV2Y.js} +5 -5
- package/chunks/chunk-L34XSHIZ.js +28 -0
- package/chunks/{chunk-UXEW7TQS.js → chunk-LB3WQQJK.js} +1 -1
- package/chunks/{chunk-YNG7XAJU.js → chunk-LEPCWS5A.js} +1 -1
- package/chunks/{chunk-XLENZQXH.js → chunk-LHBNR6EU.js} +2 -2
- package/chunks/{chunk-AKNQMSL2.js → chunk-LOBDDFYK.js} +4 -28
- package/chunks/{chunk-L6CUJZDG.js → chunk-LU77UT4D.js} +2 -2
- package/chunks/{chunk-3EGEBDTW.js → chunk-M4KFODIP.js} +1 -1
- package/chunks/{chunk-JLSZT354.js → chunk-M4LBBSVP.js} +2 -0
- package/chunks/{chunk-YOMKOM7E.js → chunk-MP6YZ4RK.js} +6580 -5992
- package/chunks/chunk-N2TNM3QB.js +9 -0
- package/chunks/{chunk-GDXSXL3H.js → chunk-NFIDVZND.js} +1 -1
- package/chunks/{chunk-NT5XIL5H.js → chunk-NQ4L2CMD.js} +51 -6
- package/chunks/{chunk-OQYXJK2V.js → chunk-NRL5CUZT.js} +1 -1
- package/chunks/{chunk-FIWZOMBF.js → chunk-NSUKQ4DN.js} +6 -0
- package/chunks/chunk-NUHOLAQ6.js +59 -0
- package/chunks/{chunk-BBYTY46C.js → chunk-NVVJTUSL.js} +266 -105
- package/chunks/{chunk-CAZADEU7.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-5MK45KZ3.js → chunk-OHOO527W.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-YDQ4OCDK.js → chunk-OSSTATJF.js} +89 -1
- package/chunks/chunk-P6UIF2OW.js +400 -0
- package/chunks/{chunk-V4HN35IF.js → chunk-PCRBLMIN.js} +16 -2
- package/chunks/{chunk-L2OKAIUK.js → chunk-QI27MKNQ.js} +23 -15
- package/chunks/{chunk-FHPYRXRH.js → chunk-QJGYU5PG.js} +1 -1
- package/chunks/{chunk-IVUWTA2D.js → chunk-QJVZLILI.js} +1 -1
- package/chunks/{chunk-TBJ3SNS3.js → chunk-QKDNS6FU.js} +1 -1
- package/chunks/{chunk-YKADANK6.js → chunk-QQD2GART.js} +10 -3
- package/chunks/{chunk-ED7DD7MV.js → chunk-RAFQIHN2.js} +1 -1
- package/chunks/{chunk-TV7BJ7TX.js → chunk-RJUVTJEZ.js} +1 -1
- package/chunks/{chunk-RVCGAHC7.js → chunk-RM4WT2XB.js} +4 -4
- package/chunks/{chunk-6YXNJXQW.js → chunk-RN3YGDCA.js} +3 -3
- package/chunks/{chunk-SMRDCANI.js → chunk-S6H3ELPG.js} +1 -1
- package/chunks/{chunk-MBZ5ORJB.js → chunk-SI7WDR3U.js} +281 -2
- package/chunks/{chunk-5FGWVPCM.js → chunk-SRF4KTAG.js} +4 -4
- package/chunks/{chunk-LFAR7CPW.js → chunk-STCVJXQB.js} +23 -23
- package/chunks/{chunk-JDIO45X7.js → chunk-SULZPKTA.js} +1 -1
- package/chunks/{chunk-KUDI54QQ.js → chunk-SX2QIMJV.js} +5 -5
- package/chunks/{chunk-VYSZUQGU.js → chunk-TJYRTS4S.js} +2 -2
- package/chunks/{chunk-JOTYTYYW.js → chunk-TMKTOTMQ.js} +3 -3
- package/chunks/{chunk-FPMQT2YY.js → chunk-TQHPVKO6.js} +4 -4
- package/chunks/{chunk-GN422P4J.js → chunk-TSZSGQ3N.js} +1 -1
- package/chunks/{chunk-IXEZHTDR.js → chunk-U4DJ5XB3.js} +292 -38
- package/chunks/{chunk-MZ5A5PQW.js → chunk-UAKRDON5.js} +4 -4
- package/chunks/{chunk-NGKLMNWN.js → chunk-UM2FFKXN.js} +2 -2
- package/chunks/{chunk-5ICKESC3.js → chunk-UPFRILIL.js} +2 -2
- package/chunks/{chunk-RAEEQEC5.js → chunk-UUASLXHW.js} +54 -5
- package/chunks/chunk-V5U2NZNJ.js +29 -0
- package/chunks/{chunk-P5Y23G2L.js → chunk-V7RNNPGC.js} +1 -18
- package/chunks/{chunk-ZYPJ7HVZ.js → chunk-VBWD6C27.js} +1 -1
- package/chunks/{chunk-MJBHSZEJ.js → chunk-VNAYZAFX.js} +3 -3
- package/chunks/chunk-VPSIC437.js +780 -0
- package/chunks/{chunk-AAX236AR.js → chunk-VWTSRH6C.js} +52 -11
- package/chunks/{chunk-PDXYZBBQ.js → chunk-VYIUNFEA.js} +2 -2
- package/chunks/{chunk-BY24DZ4J.js → chunk-WP4AX3XD.js} +5 -7
- package/chunks/{chunk-X7C7KFWA.js → chunk-XLXAZLDR.js} +1 -1
- package/chunks/{chunk-ZQ3FKEWA.js → chunk-YPWZTR7F.js} +3 -3
- package/chunks/{chunk-IXHV5MIC.js → chunk-ZDFQGHZH.js} +1 -1
- package/chunks/chunk-ZJ2LM2SI.js +198 -0
- package/chunks/{chunk-PWR2NQBS.js → chunk-ZKFTS3OV.js} +3 -3
- package/chunks/{chunk-HMJ2P3SV.js → chunk-ZL4HFSL6.js} +91 -29
- package/chunks/{chunk-ID33ZRWH.js → chunk-ZTPGUFQV.js} +28 -6
- package/chunks/chunk-bdqvmfwv-ZTSOWAFE.js +17446 -0
- package/chunks/{config-utils-NNUPVGEC.js → config-utils-LVSYDLHZ.js} +42 -46
- package/chunks/{contextCommand-S3TPCDM5.js → contextCommand-TZD7UAJK.js} +40 -44
- package/chunks/{core-runtime-NASPCSQX.js → core-runtime-B4UKKIAQ.js} +42 -46
- package/chunks/{create-sub-session-36TNCHCP.js → create-sub-session-LUPWEUHR.js} +2 -2
- package/chunks/{create-sub-session-DS4BJLYZ.js → create-sub-session-NJ24B4US.js} +41 -44
- package/chunks/{cron-create-QXHTYUTO.js → cron-create-CRSPET3H.js} +1 -1
- package/chunks/{cron-delete-WV2BM42M.js → cron-delete-DB77SZTU.js} +1 -1
- package/chunks/{cron-list-7KVNBLZ7.js → cron-list-U2JNYWV6.js} +1 -1
- package/chunks/{daemon-UCVUHPJD.js → daemon-RKDGBFLK.js} +385 -19
- package/chunks/{daemon-git-worktree-guard-ATXVQPS3.js → daemon-git-worktree-guard-O2HPOBAB.js} +40 -44
- package/chunks/{daemon-status-provider-UI3GBTMO.js → daemon-status-provider-GRRVCJFW.js} +47 -51
- package/chunks/{daemon-trust-policy-SUCBJ2CA.js → daemon-trust-policy-YJL442BK.js} +46 -50
- package/chunks/{daemon-trust-policy-monitor-3LM5RQNS.js → daemon-trust-policy-monitor-JL7F4Y4Q.js} +46 -50
- package/chunks/{deferred-core-runtime-SCOJLVYG.js → deferred-core-runtime-S32AYVZI.js} +39 -43
- package/chunks/{devtools-JCG4K2NZ.js → devtools-VDRJYPZF.js} +1 -1
- package/chunks/{discovery-X2NV535U.js → discovery-TUM3ZQ6U.js} +2 -2
- package/chunks/{display-image-Z4VBQDEJ.js → display-image-73C7XNRK.js} +3 -3
- package/chunks/{dist-7WDZYMWV.js → dist-62OZ7QXB.js} +2 -2
- package/chunks/{dist-FLJLHASF.js → dist-EDHQIBYD.js} +7 -7
- package/chunks/{dist-S3BKCTWF.js → dist-GT64AAUR.js} +1 -1
- package/chunks/{dist-GPSRNVVP.js → dist-JVXT4VUJ.js} +2 -2
- package/chunks/{dist-LY66XNUL.js → dist-L6URO6CK.js} +3 -3
- package/chunks/{dist-5423MG3D.js → dist-LXFYIJNG.js} +734 -128
- package/chunks/{dist-SDKHGH5O.js → dist-PDGNRVPY.js} +4 -4
- package/chunks/{dist-WAUO5OMN.js → dist-QAF5DO3Y.js} +363 -73
- package/chunks/{dist-WIVVPE7M.js → dist-ZCJLKQSP.js} +1 -1
- package/chunks/{earlyInputCapture-INWJ2STR.js → earlyInputCapture-BBPCIVZG.js} +38 -42
- package/chunks/{edit-B7ZRRGAE.js → edit-SUGXY63Y.js} +26 -30
- package/chunks/{en-E4AYTX6H.js → en-2RATMNX7.js} +2 -0
- package/chunks/{enter-worktree-SPZHEETQ.js → enter-worktree-B6USKSIK.js} +5 -5
- package/chunks/{enterPlanMode-S554IKJ2.js → enterPlanMode-MDX4RVVL.js} +26 -30
- package/chunks/{environment-25ADH4Y6.js → environment-VN6RXDVN.js} +41 -45
- package/chunks/{errors-G2I6LFTW.js → errors-UEY36PIT.js} +40 -44
- package/chunks/{exit-worktree-AWUXAMAM.js → exit-worktree-DLQ73SJH.js} +8 -6
- package/chunks/{exitPlanMode-ZFH4OYPM.js → exitPlanMode-EPHIEDAA.js} +26 -30
- package/chunks/{fast-path-WZHVZ2ER.js → fast-path-Y73R42LV.js} +3 -3
- package/chunks/{fast-path-settings-NILM6QZL.js → fast-path-settings-MFUR3IWK.js} +3 -3
- package/chunks/{glob-UOVDMBUP.js → glob-DMGH7EZN.js} +27 -31
- package/chunks/goal-tools-3RF3PXCL.js +99 -0
- package/chunks/{grep-LHYJ5V2N.js → grep-AJVLCVXC.js} +2 -2
- package/chunks/{handleAutoUpdate-4MZ45DZY.js → handleAutoUpdate-HVWQT2AU.js} +42 -46
- package/chunks/{i18n-KWUEI4DS.js → i18n-5OR7NTRZ.js} +39 -43
- package/chunks/{image-gen-YZDVO5YS.js → image-gen-VOIDOHOB.js} +1 -1
- package/chunks/{initializer-2NBROGMG.js → initializer-JE5RQSOE.js} +46 -50
- package/chunks/{installationInfo-YKUSY3ZB.js → installationInfo-KO3CCSCK.js} +38 -42
- package/chunks/{list-W2WV3COM.js → list-3IORSFIY.js} +49 -53
- package/chunks/{list-agents-PMVMHNY7.js → list-agents-SBMONIUK.js} +3 -3
- package/chunks/{llm-NPPHLIJI.js → llm-K26SUDVK.js} +155 -99
- package/chunks/{llm-content-generator-YK3WN6XW.js → llm-content-generator-TT6EAUD4.js} +5 -6
- package/chunks/{loadedSettingsAdapter-2P7DFWUR.js → loadedSettingsAdapter-KLLFZF3M.js} +46 -50
- package/chunks/{loggingContentGenerator-QYYYGU6V.js → loggingContentGenerator-EYQBA4M4.js} +43 -47
- package/chunks/{loop-wakeup-EBM4F5MZ.js → loop-wakeup-QA6SHCZT.js} +2 -2
- package/chunks/{ls-F6TRX3DD.js → ls-HEJNCEYO.js} +1 -1
- package/chunks/{lsp-QYTOS2FI.js → lsp-WOQKNZP6.js} +1 -1
- package/chunks/{managed-npm-update-UMC4NBWW.js → managed-npm-update-HIJTODQT.js} +38 -42
- package/chunks/{mcp-OFI6XDP2.js → mcp-A2UEHETW.js} +46 -50
- package/chunks/{monitor-QX3BM3JY.js → monitor-DKNZQAB2.js} +28 -32
- package/chunks/{node-QKLNSZMX.js → node-UETAYMMO.js} +3 -3
- package/chunks/{nonInteractiveCli-NVRMD5MN.js → nonInteractiveCli-YA47F2F4.js} +86 -89
- package/chunks/{notebook-edit-AAILDPSV.js → notebook-edit-MGHTRL2D.js} +26 -30
- package/chunks/{openaiContentGenerator-53PB3CMN.js → openaiContentGenerator-ZJIEQ3ZJ.js} +15 -17
- package/chunks/{pidfile-5ACKG2LI.js → pidfile-ETHAZNMY.js} +38 -42
- package/chunks/{processUtils-2BCDO3DZ.js → processUtils-UY3SAJJZ.js} +2 -2
- package/chunks/{prompt-terminal-ledger-3RKW73A2.js → prompt-terminal-ledger-GZ747VYE.js} +39 -43
- package/chunks/{qwenContentGenerator-N4LLWDPH.js → qwenContentGenerator-VI4KATRY.js} +39 -43
- package/chunks/{read-file-DPAKXHYE.js → read-file-P7F4P7LV.js} +6 -8
- package/chunks/{read-mcp-resource-R4NO75DW.js → read-mcp-resource-GLAGB6R7.js} +1 -1
- package/chunks/{record-artifact-2EAYLAL5.js → record-artifact-SWVR7NSU.js} +3 -3
- package/chunks/renderer-selection-M4UN63VJ.js +99 -0
- package/chunks/{report-findings-Y4MSHDS3.js → report-findings-AL5YW3KI.js} +4 -4
- package/chunks/{request-shutdown-DWRMGTMB.js → request-shutdown-5YK4IZ54.js} +5 -5
- package/chunks/{resumeHistoryUtils-3JQORXAK.js → resumeHistoryUtils-DPZKFW24.js} +44 -48
- package/chunks/{ripGrep-AHF5QCI7.js → ripGrep-C7LJKUPZ.js} +9 -11
- package/chunks/{run-qwen-serve-3LKV7KDC.js → run-qwen-serve-OGTEEUR2.js} +132 -81
- package/chunks/{runtime-66F4W3IA.js → runtime-LNBLEMZS.js} +51 -55
- package/chunks/{scheduled-tasks-2NVKS5Q2.js → scheduled-tasks-FLDYZQOF.js} +44 -48
- package/chunks/{scheduler-JNV7T3ZO.js → scheduler-73YXGUGW.js} +40 -44
- package/chunks/{sdk-exporters-grpc-G5IT4XS4.js → sdk-exporters-grpc-MXTVSE3C.js} +2 -2
- package/chunks/{sdk-exporters-http-MFIWD23D.js → sdk-exporters-http-3JO5TJNU.js} +3 -3
- package/chunks/{sdk-impl-2RXJ4Q6X.js → sdk-impl-HZAUUTHJ.js} +5 -5
- package/chunks/{send-message-WPZRCJOB.js → send-message-JC7NJTY6.js} +7 -7
- package/chunks/{serve-GP2UNRP7.js → serve-3UR2H4CV.js} +46 -50
- package/chunks/{server-7W6C3SOW.js → server-AOYZVVOM.js} +1736 -502
- package/chunks/{session-PZLBAQGG.js → session-UAWFNFGI.js} +90 -93
- package/chunks/session-attachments-root-ZCGXQQTR.js +104 -0
- package/chunks/{session-pr-refresh-OIVL3U3Z.js → session-pr-refresh-CT2INROL.js} +131 -65
- package/chunks/{settings-ZOHIQWYK.js → settings-BHRGDASJ.js} +45 -49
- package/chunks/{shell-FWZT6IUR.js → shell-YHOGC7TO.js} +26 -30
- package/chunks/{skill-RTQC2YGA.js → skill-ZGBKNCHQ.js} +71 -49
- package/chunks/{skill-settings-AKMIXFSJ.js → skill-settings-AKSP665O.js} +45 -49
- package/chunks/{spawnChannel-ZP23JL6O.js → spawnChannel-N25MBB6F.js} +40 -44
- package/chunks/{standalone-update-P2Q5H4ZU.js → standalone-update-XGPWJDRN.js} +40 -44
- package/chunks/start-opentui-ui-FZ4USOU7.js +55342 -0
- package/chunks/{startInteractiveUI-NSA6QPQZ.js → startInteractiveUI-E2WQJUOA.js} +2920 -4542
- package/chunks/{syntheticOutput-5URSQLIS.js → syntheticOutput-HJNZSEHN.js} +2 -2
- package/chunks/{task-create-3EXVDG3G.js → task-create-6RSD54S5.js} +7 -7
- package/chunks/{task-list-PIBYNSE7.js → task-list-IQSACPOM.js} +31 -7
- package/chunks/{task-stop-IV3BYWJC.js → task-stop-HE2LRQNW.js} +1 -1
- package/chunks/{task-update-H5BPDS5Y.js → task-update-XAJ2NYOA.js} +7 -7
- package/chunks/{team-create-53T42W37.js → team-create-SOKMYSQU.js} +28 -32
- package/chunks/{team-delete-X3WPELS6.js → team-delete-NGNNKGMG.js} +1 -1
- package/chunks/{team-plan-approval-D45ZC5OE.js → team-plan-approval-U7ZWXYAY.js} +26 -30
- package/chunks/{terminal-image-renderer-FCRUWT6C.js → terminal-image-renderer-KKM4OBLO.js} +40 -44
- package/chunks/{theme-manager-MHNPEDP7.js → theme-manager-GQHF3A7T.js} +38 -42
- package/chunks/{todoWrite-A5IOZZ3P.js → todoWrite-5UTVUXHA.js} +36 -6
- package/chunks/{tool-search-6RPBGGUX.js → tool-search-IAI2RVWT.js} +10 -12
- package/chunks/{total-session-admission-MGV56XDK.js → total-session-admission-G4CGCSTG.js} +43 -47
- package/chunks/{trustedFolders-QJYEFMTU.js → trustedFolders-D2I3FDPB.js} +39 -43
- package/chunks/{update-relaunch-ZDMQX63C.js → update-relaunch-5RWKZAL3.js} +5 -5
- package/chunks/{updateCheck-4QZWCGP6.js → updateCheck-ZXOQDFEI.js} +42 -46
- package/chunks/{useAutoAcceptIndicator-DLIQN256.js → useAutoAcceptIndicator-6EK4QGAH.js} +49 -53
- package/chunks/{validateNonInterActiveAuth-HGTG7AEK.js → validateNonInterActiveAuth-QPFEKATS.js} +82 -86
- package/chunks/{version-CPAZMC4B.js → version-JKNG7YDH.js} +1 -1
- package/chunks/{web-fetch-N4K5M3M4.js → web-fetch-X3AHIIHW.js} +8 -11
- package/chunks/{web-search-4VZKM5SF.js → web-search-K2FMOGS5.js} +6 -7
- package/chunks/{web-shell-static-PW7OEDQO.js → web-shell-static-POZHGGXE.js} +4 -4
- package/chunks/{workflow-2ALQKTHG.js → workflow-TOLPAK5G.js} +38 -38
- package/chunks/{workspace-providers-status-5JM4CB6R.js → workspace-providers-status-PCJK3RC7.js} +50 -54
- package/chunks/{workspace-registration-store-RNMFVCH7.js → workspace-registration-store-KQWVVW4Y.js} +1 -1
- package/chunks/{workspace-registry-6EULAPZC.js → workspace-registry-YNIOB6HJ.js} +43 -47
- package/chunks/{workspace-runtime-coordinator-IRI2DRCJ.js → workspace-runtime-coordinator-WG2RNEN7.js} +43 -47
- package/chunks/{workspace-service-SETHN4WE.js → workspace-service-G4ZNBOFH.js} +51 -55
- package/chunks/{workspace-skills-status-4D4EUEQU.js → workspace-skills-status-FMTPPMWC.js} +47 -51
- package/chunks/{workspace-trust-reconciler-4LR3CDL4.js → workspace-trust-reconciler-IBDFQBQS.js} +53 -57
- package/chunks/wrapper-JH3IFHT2.js +35 -0
- package/chunks/{write-file-45GWPSOI.js → write-file-YTLFY2S5.js} +28 -32
- package/chunks/{zh-2BQ7P6OD.js → zh-25DF7OGK.js} +2 -0
- package/chunks/{zh-TW-UFXRZTXX.js → zh-TW-5EDMZVGK.js} +2 -0
- package/chunks/{zoom-image-K6IQUKRC.js → zoom-image-IFXSN74N.js} +6 -8
- package/cli.js +17 -13
- package/locales/en.js +3 -0
- package/locales/zh-TW.js +3 -0
- package/locales/zh.js +3 -0
- package/package.json +3 -3
- package/web-shell/assets/{abnfDiagram-VCTEODGH-C80OZcPP.js → abnfDiagram-VCTEODGH-Cxf7xE_Z.js} +1 -1
- package/web-shell/assets/{arc-AUqStYgf.js → arc-ESi1eNkE.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-CQYOdYla.js → architectureDiagram-5GKGNRK7-D9l7-bDo.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-lYKlFysy.js → blockDiagram-NRAW4CY4-Bc8DEasw.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-BoS23iIp.js → c4Diagram-UCG6FXSJ-Dimb2Hmh.js} +1 -1
- package/web-shell/assets/channel-B7ohGDil.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-DLLooL1E.js → chunk-2Q5K7J3B-jVDmOpAQ.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-kPfJxScY.js → chunk-5VM5RSS4-DbG_SwdB.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-CVGFBqkD.js → chunk-F27PBJKO-QEc4cY1v.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-CnM_kOVV.js → chunk-G27WJ6UU-iJ36lQ3X.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-Cj-ajOkT.js → chunk-JWPE2WC7-DuArnVtF.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-8L5c-wFo.js → chunk-LCL6LL3I-DxOf1zwL.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-DsXTxpvL.js → chunk-POPQ4Y6H-lVLu9Ild.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-DU5GE1_z.js → chunk-SVP7TREG-C6XYlIer.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-D2IIWZKt.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-CF_txUJr.js → cose-bilkent-JH36ORCC-DGVHMMVm.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-DEZ-My-Z.js → cynefin-OW5HDTMX-D6cgpCnH.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BV7EKUS6.js → cynefinDiagram-5FMLGOSQ-BKv4Z-UX.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-JGIX0G4H.js → dagre-3AP2YEHR-B4ABMIG-.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-DdUY7q6A.js → diagram-S7CK7UJ4-DgCkp_Lm.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-fhzRZ19v.js → diagram-UQ7AKVKN-FG0FNokz.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-BOgOex6q.js → diagram-VSXAHHWV-JgkP9qg-.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-C0NknIz6.js → diagram-VX7I27RA-ADh2x83l.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-C__3mUBX.js → diagram-Z3DM3KII-yXqoYF1J.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-BvPhqycH.js → ebnfDiagram-PWID7BFC-Duk83Ek_.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-BqzoNoL9.js → erDiagram-SSCWMZ5O-DMdvxySG.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-CJKOre47.js → flowDiagram-A5DVABFB-DHjVgSji.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-C5xZjrp0.js → ganttDiagram-EL5Y4UJY-DMM9DkCE.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-C0EjwuPK.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-C5M93syE.js → index-zqvnpGHv.js} +1 -1
- package/web-shell/assets/{infoDiagram-RXCK75RN-BUwzsYOs.js → infoDiagram-RXCK75RN-eT1fANNm.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-EDJ_DH3V.js → ishikawaDiagram-5VMMS53U-k3evzZNn.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-BnfcOsS0.js → journeyDiagram-EYS64GPL-CGim3EAi.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-D_ofTVGu.js → kanban-definition-3QL26DDD-WHfJo-22.js} +1 -1
- package/web-shell/assets/{layout-CBuQFdfZ.js → layout-DkqIaFlJ.js} +1 -1
- package/web-shell/assets/{linear-DRIHtmGv.js → linear-Bdkd3mCz.js} +1 -1
- package/web-shell/assets/{mermaid.core-CmR5wZH6.js → mermaid.core-CGw0LkT_.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-BV374olC.js → mindmap-definition-FBJOCRG2-C9V4rBvo.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-Bpy1SplK.js → pegDiagram-XKGWAZYB-CwoI2T5G.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-CeZx4hR2.js → pieDiagram-E7YTZNPT-DaTmBmPG.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-COYKs14h.js → quadrantDiagram-AXDQQJYC-plh6MyGI.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-5g2pOeTs.js → railroadDiagram-O6MQD6OU-D_b-S0iK.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-Yn8uPGtF.js → requirementDiagram-EFPCY7ZU-zUzTN7VE.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-CTayAGq6.js → sankeyDiagram-P5KCCOFB-m6AhoD0l.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-BFWDKzUU.js → sequenceDiagram-WJ2MYXX4-Cwhzsine.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-CtErUbj4.js → sizeCapture-X5ZJPWSS-CcZuKIae.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-Co3HFzOd.js → stateDiagram-HBIQ2CUA-CFoiJwD_.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V--H8HdEmk.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-CDZuxzOj.js → swimlanes-XN3QIQJK-CgS9hcaV.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ShE9OIgf.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-UcNHj8At.js → timeline-definition-24CTP7MA-Dzzc05t9.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-JKR9pVFG.js → vennDiagram-4TSXK5OY-DemK0f7Y.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-C4SU-yIW.js → wardleyDiagram-VM6X3IG4-CquLxtMr.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-D_yoWGZ4.js → xychartDiagram-S5SC5T6Z-BTBKTM5g.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-4P7PPAHN.js +0 -3097
- package/chunks/chunk-7J6OTNGO.js +0 -424
- package/chunks/chunk-LMMHS3RS.js +0 -135
- package/chunks/chunk-MZYWNU66.js +0 -149
- package/chunks/chunk-T4EFG2P5.js +0 -113
- package/chunks/chunk-XZA32HII.js +0 -19
- package/chunks/goal-tools-7TNK5ZHC.js +0 -411
- package/web-shell/assets/channel-B0ovOJeK.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DMll2-6_.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DMll2-6_.js +0 -1
- package/web-shell/assets/index-B_IPzA0h.js +0 -2020
- package/web-shell/assets/index-D1OKGQlM.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-C3gdRjPm.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-C34TGCPZ.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
|
|
@@ -6177,8 +6177,15 @@ __name(uploadDingTalkImage, "uploadDingTalkImage");
|
|
|
6177
6177
|
|
|
6178
6178
|
// packages/channels/dingtalk/dist/outbound-file.js
|
|
6179
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";
|
|
6180
6183
|
var FILE_OPENING = "[FILE:";
|
|
6184
|
+
var MEDIA_UPLOAD_API2 = "https://oapi.dingtalk.com/media/upload";
|
|
6185
|
+
var MEDIA_UPLOAD_TIMEOUT_MS2 = 3e4;
|
|
6181
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]);
|
|
6182
6189
|
var MAX_FILES_PER_RESPONSE = 5;
|
|
6183
6190
|
var FILE_UNAVAILABLE_NOTICE = "[File delivery unavailable]";
|
|
6184
6191
|
var OutboundFileProjector = class {
|
|
@@ -6277,6 +6284,104 @@ function withFileUnavailableNotice(text) {
|
|
|
6277
6284
|
return `${safe}${safe ? "\n" : ""}${FILE_UNAVAILABLE_NOTICE}`;
|
|
6278
6285
|
}
|
|
6279
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");
|
|
6280
6385
|
|
|
6281
6386
|
// packages/channels/dingtalk/dist/DingtalkConnectionManager.js
|
|
6282
6387
|
init_esbuild_shims();
|
|
@@ -6590,6 +6695,25 @@ var STATUS_CARD_TEMPLATE_ID = "675cde2f-f526-40cb-b828-f5b2b57b8b77.schema";
|
|
|
6590
6695
|
var QUESTION_CARD_TEMPLATE_ID = "c2a6355b-9724-4f7e-9653-d33fcb3311bb.schema";
|
|
6591
6696
|
var DINGTALK_API = "https://api.dingtalk.com";
|
|
6592
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");
|
|
6593
6717
|
function stringifyCardParamMap(cardParamMap) {
|
|
6594
6718
|
return Object.fromEntries(Object.entries(cardParamMap).map(([key, value]) => [
|
|
6595
6719
|
key,
|
|
@@ -6638,7 +6762,7 @@ var DingtalkInteractiveCardClient = class {
|
|
|
6638
6762
|
if (Array.isArray(deliveries)) {
|
|
6639
6763
|
const failure = deliveries.find((entry) => entry !== null && typeof entry === "object" && entry.success === false);
|
|
6640
6764
|
if (failure) {
|
|
6641
|
-
throw new
|
|
6765
|
+
throw new DingtalkCardRequestError(`${input.templateId}: ${typeof failure.errorMsg === "string" && failure.errorMsg.trim() ? failure.errorMsg.trim() : "DingTalk card delivery failed"}`, false);
|
|
6642
6766
|
}
|
|
6643
6767
|
}
|
|
6644
6768
|
}
|
|
@@ -6663,21 +6787,28 @@ var DingtalkInteractiveCardClient = class {
|
|
|
6663
6787
|
});
|
|
6664
6788
|
}
|
|
6665
6789
|
async request(path, method, body, templateId) {
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
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);
|
|
6679
6811
|
}
|
|
6680
|
-
return response.json().catch(() => void 0);
|
|
6681
6812
|
}
|
|
6682
6813
|
};
|
|
6683
6814
|
|
|
@@ -6804,8 +6935,11 @@ init_esbuild_shims();
|
|
|
6804
6935
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
6805
6936
|
var FLUSH_INTERVAL_MS = 500;
|
|
6806
6937
|
var STATUS_REFRESH_INTERVAL_MS = 1e3;
|
|
6938
|
+
var CONTENT_SYNC_INTERVAL_SECONDS = 5;
|
|
6807
6939
|
var BREAKER_PROBE_INTERVAL_MS = 3e4;
|
|
6808
6940
|
var MAX_CONSECUTIVE_STATUS_FAILURES = 3;
|
|
6941
|
+
var INITIAL_RETRY_INTERVAL_MS = 1e3;
|
|
6942
|
+
var MAX_RETRY_INTERVAL_MS = 3e4;
|
|
6809
6943
|
var CONTENT_LIMIT = 2e4;
|
|
6810
6944
|
var TRUNCATION_MARKER = "[Earlier output truncated]\n";
|
|
6811
6945
|
function boundContent(content) {
|
|
@@ -6823,10 +6957,13 @@ var StatusCardController = class {
|
|
|
6823
6957
|
recordsByOutTrack = /* @__PURE__ */ new Map();
|
|
6824
6958
|
segmentIdsByRun = /* @__PURE__ */ new Map();
|
|
6825
6959
|
terminalSegmentIds = /* @__PURE__ */ new Set();
|
|
6960
|
+
disposed = false;
|
|
6826
6961
|
constructor(options) {
|
|
6827
6962
|
this.options = options;
|
|
6828
6963
|
}
|
|
6829
6964
|
ensure(segment, target) {
|
|
6965
|
+
if (this.disposed)
|
|
6966
|
+
return;
|
|
6830
6967
|
if (this.terminalSegmentIds.has(segment.segmentId))
|
|
6831
6968
|
return;
|
|
6832
6969
|
if (!this.recordsBySegment.has(segment.segmentId)) {
|
|
@@ -6834,6 +6971,8 @@ var StatusCardController = class {
|
|
|
6834
6971
|
}
|
|
6835
6972
|
}
|
|
6836
6973
|
replace(segment, target, content) {
|
|
6974
|
+
if (this.disposed)
|
|
6975
|
+
return;
|
|
6837
6976
|
if (this.terminalSegmentIds.has(segment.segmentId))
|
|
6838
6977
|
return;
|
|
6839
6978
|
const record = this.recordsBySegment.get(segment.segmentId);
|
|
@@ -6844,22 +6983,27 @@ var StatusCardController = class {
|
|
|
6844
6983
|
if (record.terminal)
|
|
6845
6984
|
return;
|
|
6846
6985
|
record.content = boundContent(content);
|
|
6986
|
+
record.contentVersion++;
|
|
6847
6987
|
if (record.streamFailed)
|
|
6848
6988
|
return;
|
|
6849
|
-
record.
|
|
6989
|
+
record.hasPendingWrite = true;
|
|
6850
6990
|
this.scheduleFlush(record);
|
|
6851
6991
|
}
|
|
6852
6992
|
/**
|
|
6853
6993
|
* Whether a created, still-running status card is displaying content for
|
|
6854
6994
|
* this segment. Awaits the in-flight creation so a boundary decision made
|
|
6855
6995
|
* while creation is pending does not race it. A latched stream failure
|
|
6856
|
-
* 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`).
|
|
6857
6999
|
*/
|
|
6858
7000
|
async isCardLive(segmentId) {
|
|
7001
|
+
if (this.disposed)
|
|
7002
|
+
return false;
|
|
6859
7003
|
const record = this.recordsBySegment.get(segmentId);
|
|
6860
7004
|
if (!record || record.terminal || record.streamFailed)
|
|
6861
7005
|
return false;
|
|
6862
|
-
return record
|
|
7006
|
+
return this.awaitDelivery(record);
|
|
6863
7007
|
}
|
|
6864
7008
|
/**
|
|
6865
7009
|
* Drain any pending snapshot so callers can treat the card's current
|
|
@@ -6868,23 +7012,64 @@ var StatusCardController = class {
|
|
|
6868
7012
|
* caller can fall back instead of claiming delivery.
|
|
6869
7013
|
*/
|
|
6870
7014
|
async flushPending(segmentId) {
|
|
7015
|
+
if (this.disposed)
|
|
7016
|
+
return false;
|
|
6871
7017
|
const record = this.recordsBySegment.get(segmentId);
|
|
6872
7018
|
if (!record || record.terminal)
|
|
6873
7019
|
return false;
|
|
6874
|
-
if (!await record
|
|
7020
|
+
if (!await this.awaitDelivery(record))
|
|
6875
7021
|
return false;
|
|
6876
7022
|
while (!record.terminal && !record.streamFailed) {
|
|
6877
7023
|
if (record.flushTimer) {
|
|
6878
7024
|
clearTimeout(record.flushTimer);
|
|
6879
7025
|
record.flushTimer = void 0;
|
|
6880
7026
|
}
|
|
7027
|
+
if (record.streamRetryTimer) {
|
|
7028
|
+
clearTimeout(record.streamRetryTimer);
|
|
7029
|
+
record.streamRetryTimer = void 0;
|
|
7030
|
+
}
|
|
7031
|
+
const failureVersion = record.streamFailureVersion;
|
|
6881
7032
|
this.flush(record);
|
|
6882
7033
|
await record.writeChain;
|
|
6883
|
-
if (record.
|
|
7034
|
+
if (record.streamFailureVersion !== failureVersion)
|
|
7035
|
+
return false;
|
|
7036
|
+
if (!record.hasPendingWrite)
|
|
6884
7037
|
break;
|
|
6885
7038
|
}
|
|
6886
7039
|
return !record.terminal && !record.streamFailed;
|
|
6887
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
|
+
}
|
|
6888
7073
|
createRecord(segment, target, initialContent = "") {
|
|
6889
7074
|
const outTrackId = `qwen-status-${randomUUID2()}`;
|
|
6890
7075
|
const record = {
|
|
@@ -6897,13 +7082,21 @@ var StatusCardController = class {
|
|
|
6897
7082
|
content: boundContent(initialContent),
|
|
6898
7083
|
startedAt: Date.now(),
|
|
6899
7084
|
lastStatusSecond: 0,
|
|
7085
|
+
lastContentSyncSecond: 0,
|
|
6900
7086
|
ready: Promise.resolve(false),
|
|
7087
|
+
creationAttempt: Promise.resolve(false),
|
|
6901
7088
|
terminal: false,
|
|
6902
7089
|
streamFailed: false,
|
|
7090
|
+
streamFailureVersion: 0,
|
|
7091
|
+
createRetryAttempt: 0,
|
|
7092
|
+
streamRetryAttempt: 0,
|
|
7093
|
+
terminalRetryAttempt: 0,
|
|
6903
7094
|
consecutiveStatusFailures: 0,
|
|
6904
7095
|
stopClaimed: false,
|
|
6905
7096
|
forbiddenActors: /* @__PURE__ */ new Set(),
|
|
6906
7097
|
lastWriteAt: Date.now(),
|
|
7098
|
+
contentVersion: 0,
|
|
7099
|
+
hasPendingWrite: false,
|
|
6907
7100
|
writeChain: Promise.resolve()
|
|
6908
7101
|
};
|
|
6909
7102
|
this.recordsBySegment.set(record.segmentId, record);
|
|
@@ -6925,6 +7118,8 @@ var StatusCardController = class {
|
|
|
6925
7118
|
void this.finalize(segmentId, boundContent(error), "Failed", true);
|
|
6926
7119
|
}
|
|
6927
7120
|
cancelRun(runId, reason) {
|
|
7121
|
+
if (this.disposed)
|
|
7122
|
+
return;
|
|
6928
7123
|
for (const segmentId of [...this.segmentIdsByRun.get(runId) ?? []]) {
|
|
6929
7124
|
const record = this.recordsBySegment.get(segmentId);
|
|
6930
7125
|
if (!record)
|
|
@@ -6933,6 +7128,8 @@ var StatusCardController = class {
|
|
|
6933
7128
|
}
|
|
6934
7129
|
}
|
|
6935
7130
|
claimStop(outTrackId, actorId) {
|
|
7131
|
+
if (this.disposed)
|
|
7132
|
+
return { kind: "ignored", actorId };
|
|
6936
7133
|
const record = this.recordsByOutTrack.get(outTrackId);
|
|
6937
7134
|
if (!record || record.terminal || record.stopClaimed) {
|
|
6938
7135
|
return { kind: "ignored", actorId };
|
|
@@ -6961,44 +7158,72 @@ var StatusCardController = class {
|
|
|
6961
7158
|
};
|
|
6962
7159
|
}
|
|
6963
7160
|
async create(record, target) {
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
outTrackId: record.outTrackId,
|
|
6969
|
-
target,
|
|
6970
|
-
cardParamMap: {
|
|
6971
|
-
content: initialContent,
|
|
6972
|
-
flowStatus: 2,
|
|
6973
|
-
statusLine: this.statusLine(record, "Running").text,
|
|
6974
|
-
hasAction: "true",
|
|
6975
|
-
stop_action: "true"
|
|
6976
|
-
}
|
|
7161
|
+
for (; ; ) {
|
|
7162
|
+
let settleAttempt;
|
|
7163
|
+
record.creationAttempt = new Promise((resolve) => {
|
|
7164
|
+
settleAttempt = resolve;
|
|
6977
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 {
|
|
6978
7196
|
await this.options.client.openOrUpdateStream({
|
|
6979
7197
|
outTrackId: record.outTrackId,
|
|
6980
7198
|
key: "content",
|
|
6981
|
-
content:
|
|
7199
|
+
content: sanitizeStreamingImageMarkers(record.content),
|
|
6982
7200
|
finalize: false
|
|
6983
7201
|
});
|
|
6984
|
-
return true;
|
|
6985
7202
|
} catch (error) {
|
|
6986
|
-
this.
|
|
6987
|
-
await this.options.client.updateInstance({
|
|
6988
|
-
outTrackId: record.outTrackId,
|
|
6989
|
-
cardParamMap: {
|
|
6990
|
-
flowStatus: 3,
|
|
6991
|
-
statusLine: "Unavailable",
|
|
6992
|
-
hasAction: "false",
|
|
6993
|
-
stop_action: "false"
|
|
6994
|
-
}
|
|
6995
|
-
}).catch(() => {
|
|
6996
|
-
});
|
|
6997
|
-
return false;
|
|
7203
|
+
this.handleStreamFailure(record, error);
|
|
6998
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
|
+
});
|
|
6999
7224
|
}
|
|
7000
7225
|
scheduleFlush(record) {
|
|
7001
|
-
if (record.flushTimer || record.inFlight || record.terminal)
|
|
7226
|
+
if (record.flushTimer || record.streamRetryTimer || record.inFlight || record.terminal)
|
|
7002
7227
|
return;
|
|
7003
7228
|
const delay = Math.max(0, FLUSH_INTERVAL_MS - (Date.now() - record.lastWriteAt));
|
|
7004
7229
|
record.flushTimer = setTimeout(() => {
|
|
@@ -7007,42 +7232,44 @@ var StatusCardController = class {
|
|
|
7007
7232
|
}, delay);
|
|
7008
7233
|
}
|
|
7009
7234
|
flush(record) {
|
|
7010
|
-
if (record.terminal || record.
|
|
7235
|
+
if (this.disposed || record.terminal || record.streamFailed || record.inFlight || !record.hasPendingWrite)
|
|
7011
7236
|
return;
|
|
7012
|
-
|
|
7013
|
-
|
|
7237
|
+
record.hasPendingWrite = false;
|
|
7238
|
+
let sentVersion;
|
|
7239
|
+
let contentWritten = false;
|
|
7014
7240
|
const write = record.writeChain.then(async () => {
|
|
7015
7241
|
const ready = await record.ready;
|
|
7016
|
-
if (!ready || record.terminal)
|
|
7242
|
+
if (!ready || record.terminal || record.streamFailed)
|
|
7017
7243
|
return;
|
|
7244
|
+
sentVersion = record.contentVersion;
|
|
7018
7245
|
await this.options.client.openOrUpdateStream({
|
|
7019
7246
|
outTrackId: record.outTrackId,
|
|
7020
7247
|
key: "content",
|
|
7021
|
-
content,
|
|
7248
|
+
content: sanitizeStreamingImageMarkers(record.content),
|
|
7022
7249
|
finalize: false
|
|
7023
7250
|
});
|
|
7251
|
+
contentWritten = true;
|
|
7252
|
+
record.streamRetryAttempt = 0;
|
|
7024
7253
|
await this.updateRunningStatus(record);
|
|
7025
|
-
}).catch((error) =>
|
|
7026
|
-
record.streamFailed = true;
|
|
7027
|
-
record.pendingSnapshot = void 0;
|
|
7028
|
-
if (record.statusTimer) {
|
|
7029
|
-
clearTimeout(record.statusTimer);
|
|
7030
|
-
record.statusTimer = void 0;
|
|
7031
|
-
}
|
|
7032
|
-
this.options.onError?.("status card streaming", error);
|
|
7033
|
-
});
|
|
7254
|
+
}).catch((error) => this.handleStreamFailure(record, error));
|
|
7034
7255
|
const tracked = write.finally(() => {
|
|
7035
7256
|
if (record.inFlight === tracked) {
|
|
7036
7257
|
record.inFlight = void 0;
|
|
7037
7258
|
}
|
|
7038
7259
|
record.lastWriteAt = Date.now();
|
|
7039
|
-
if (record.
|
|
7260
|
+
if (contentWritten && record.contentVersion === sentVersion) {
|
|
7261
|
+
record.hasPendingWrite = false;
|
|
7262
|
+
}
|
|
7263
|
+
if (record.hasPendingWrite && record.contentVersion !== sentVersion) {
|
|
7040
7264
|
this.scheduleFlush(record);
|
|
7265
|
+
}
|
|
7041
7266
|
});
|
|
7042
7267
|
record.inFlight = tracked;
|
|
7043
7268
|
record.writeChain = tracked;
|
|
7044
7269
|
}
|
|
7045
7270
|
async finalize(segmentId, content, state, isError, retainedContent) {
|
|
7271
|
+
if (this.disposed)
|
|
7272
|
+
return false;
|
|
7046
7273
|
const record = this.recordsBySegment.get(segmentId);
|
|
7047
7274
|
if (!record || record.terminal)
|
|
7048
7275
|
return false;
|
|
@@ -7057,58 +7284,165 @@ var StatusCardController = class {
|
|
|
7057
7284
|
if (record.flushTimer)
|
|
7058
7285
|
clearTimeout(record.flushTimer);
|
|
7059
7286
|
record.flushTimer = void 0;
|
|
7287
|
+
if (record.streamRetryTimer)
|
|
7288
|
+
clearTimeout(record.streamRetryTimer);
|
|
7289
|
+
record.streamRetryTimer = void 0;
|
|
7060
7290
|
if (record.statusTimer)
|
|
7061
7291
|
clearTimeout(record.statusTimer);
|
|
7062
7292
|
record.statusTimer = void 0;
|
|
7063
|
-
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;
|
|
7064
7336
|
try {
|
|
7065
|
-
if (!await record.ready)
|
|
7066
|
-
return false;
|
|
7067
|
-
await record.writeChain;
|
|
7068
|
-
const retained = content || (retainedContent ? retainedContent(record.content) : record.content);
|
|
7069
|
-
const finalContent = boundContent(sanitizeStreamingImageMarkers(retained));
|
|
7070
|
-
await this.options.client.openOrUpdateStream({
|
|
7071
|
-
outTrackId: record.outTrackId,
|
|
7072
|
-
key: "content",
|
|
7073
|
-
content: "",
|
|
7074
|
-
finalize: true,
|
|
7075
|
-
isError
|
|
7076
|
-
});
|
|
7077
7337
|
await this.options.client.updateInstance({
|
|
7078
7338
|
outTrackId: record.outTrackId,
|
|
7079
7339
|
cardParamMap: {
|
|
7080
7340
|
blockList: JSON.stringify([
|
|
7081
7341
|
{
|
|
7082
7342
|
type: 0,
|
|
7083
|
-
markdown:
|
|
7343
|
+
markdown: intent.content
|
|
7084
7344
|
}
|
|
7085
7345
|
]),
|
|
7086
|
-
content:
|
|
7087
|
-
copy_content:
|
|
7346
|
+
content: intent.content,
|
|
7347
|
+
copy_content: intent.content,
|
|
7088
7348
|
flowStatus: 3,
|
|
7089
|
-
statusLine:
|
|
7349
|
+
statusLine: intent.statusLine,
|
|
7090
7350
|
hasAction: "false",
|
|
7091
7351
|
stop_action: "false"
|
|
7092
7352
|
}
|
|
7093
7353
|
});
|
|
7094
7354
|
record.content = "";
|
|
7355
|
+
this.removeRecord(record);
|
|
7095
7356
|
return true;
|
|
7096
7357
|
} catch (error) {
|
|
7097
7358
|
this.options.onError?.("status card finalization", error);
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
|
|
7102
|
-
|
|
7103
|
-
if (this.recordsByOutTrack.get(record.outTrackId) === record) {
|
|
7104
|
-
this.recordsByOutTrack.delete(record.outTrackId);
|
|
7359
|
+
if (isRetryableDingtalkCardError(error)) {
|
|
7360
|
+
this.scheduleTerminalRetry(record);
|
|
7361
|
+
return true;
|
|
7362
|
+
} else {
|
|
7363
|
+
this.removeRecord(record);
|
|
7105
7364
|
}
|
|
7106
|
-
|
|
7107
|
-
|
|
7108
|
-
|
|
7109
|
-
|
|
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;
|
|
7110
7403
|
}
|
|
7111
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();
|
|
7112
7446
|
}
|
|
7113
7447
|
statusLine(record, state) {
|
|
7114
7448
|
const second = Math.max(0, Math.floor((Date.now() - record.startedAt) / 1e3));
|
|
@@ -7119,17 +7453,23 @@ var StatusCardController = class {
|
|
|
7119
7453
|
};
|
|
7120
7454
|
}
|
|
7121
7455
|
async updateRunningStatus(record) {
|
|
7122
|
-
if (record.terminal || record.streamFailed)
|
|
7456
|
+
if (this.disposed || record.terminal || record.streamFailed)
|
|
7123
7457
|
return;
|
|
7124
7458
|
const status = this.statusLine(record, "Running");
|
|
7125
7459
|
if (status.second === record.lastStatusSecond)
|
|
7126
7460
|
return;
|
|
7461
|
+
const syncContent = status.second - record.lastContentSyncSecond >= CONTENT_SYNC_INTERVAL_SECONDS;
|
|
7127
7462
|
try {
|
|
7128
7463
|
await this.options.client.updateInstance({
|
|
7129
7464
|
outTrackId: record.outTrackId,
|
|
7130
|
-
cardParamMap: {
|
|
7465
|
+
cardParamMap: {
|
|
7466
|
+
...syncContent ? { content: sanitizeStreamingImageMarkers(record.content) } : {},
|
|
7467
|
+
statusLine: status.text
|
|
7468
|
+
}
|
|
7131
7469
|
});
|
|
7132
7470
|
record.lastStatusSecond = status.second;
|
|
7471
|
+
if (syncContent)
|
|
7472
|
+
record.lastContentSyncSecond = status.second;
|
|
7133
7473
|
record.consecutiveStatusFailures = 0;
|
|
7134
7474
|
if (record.statusTimer) {
|
|
7135
7475
|
clearTimeout(record.statusTimer);
|
|
@@ -7142,13 +7482,13 @@ var StatusCardController = class {
|
|
|
7142
7482
|
}
|
|
7143
7483
|
}
|
|
7144
7484
|
scheduleStatusRefresh(record, intervalMs = STATUS_REFRESH_INTERVAL_MS) {
|
|
7145
|
-
if (record.terminal || record.streamFailed || record.statusTimer)
|
|
7485
|
+
if (this.disposed || record.terminal || record.streamFailed || record.statusTimer)
|
|
7146
7486
|
return;
|
|
7147
7487
|
const elapsed = Math.max(0, Date.now() - record.startedAt);
|
|
7148
7488
|
const delay = Math.max(50, intervalMs - elapsed % intervalMs);
|
|
7149
7489
|
record.statusTimer = setTimeout(() => {
|
|
7150
7490
|
record.statusTimer = void 0;
|
|
7151
|
-
if (record.terminal || record.streamFailed)
|
|
7491
|
+
if (this.disposed || record.terminal || record.streamFailed)
|
|
7152
7492
|
return;
|
|
7153
7493
|
const refresh = record.writeChain.then(() => this.updateRunningStatus(record));
|
|
7154
7494
|
record.writeChain = refresh;
|
|
@@ -7628,6 +7968,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7628
7968
|
if (!fallbackText2 || !this.options.sendFallback)
|
|
7629
7969
|
return false;
|
|
7630
7970
|
await this.sendFallback(run, presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
|
|
7971
|
+
statusCards?.abandon(statusContext.segmentId);
|
|
7631
7972
|
return true;
|
|
7632
7973
|
}
|
|
7633
7974
|
if (reason === "input_requested") {
|
|
@@ -7639,6 +7980,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7639
7980
|
if (!fallbackText2 || !this.options.sendFallback)
|
|
7640
7981
|
return false;
|
|
7641
7982
|
await this.sendFallback(run, presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
|
|
7983
|
+
statusCards?.abandon(statusContext.segmentId);
|
|
7642
7984
|
return true;
|
|
7643
7985
|
}
|
|
7644
7986
|
statusCards?.ensure(statusContext, this.cardTarget(statusContext.target));
|
|
@@ -7649,6 +7991,7 @@ var DingtalkInteractionPresenter = class {
|
|
|
7649
7991
|
if (!fallbackText || !this.options.sendFallback)
|
|
7650
7992
|
return false;
|
|
7651
7993
|
await this.sendFallback(run, presentation.context.target.chatId, fallbackText, presentation.context.sessionId);
|
|
7994
|
+
statusCards?.abandon(statusContext.segmentId);
|
|
7652
7995
|
return true;
|
|
7653
7996
|
});
|
|
7654
7997
|
}
|
|
@@ -8048,9 +8391,102 @@ var EMOTION_RETRY_BASE_DELAY_MS = 250;
|
|
|
8048
8391
|
var GROUP_MSG_API = "https://api.dingtalk.com/v1.0/robot/groupMessages/send";
|
|
8049
8392
|
var DIRECT_MSG_API = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend";
|
|
8050
8393
|
var PROACTIVE_MSG_KEY = "sampleMarkdown";
|
|
8394
|
+
var PROACTIVE_FILE_MSG_KEY = "sampleFile";
|
|
8051
8395
|
var TOKEN_API = "https://oapi.dingtalk.com/gettoken";
|
|
8052
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
|
+
]);
|
|
8053
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");
|
|
8054
8490
|
var GENERATED_MEDIA_EXT = {
|
|
8055
8491
|
"image/jpeg": "jpg",
|
|
8056
8492
|
"image/png": "png",
|
|
@@ -8070,6 +8506,15 @@ var IMAGE_INSTRUCTIONS = [
|
|
|
8070
8506
|
"",
|
|
8071
8507
|
"Only use a real image file inside the workspace or system temporary directory."
|
|
8072
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");
|
|
8073
8518
|
function collectNonBotMentionIds(data) {
|
|
8074
8519
|
if (!Array.isArray(data.atUsers) || typeof data.chatbotUserId !== "string") {
|
|
8075
8520
|
return [];
|
|
@@ -8151,6 +8596,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8151
8596
|
} else if (!this.config.instructions.includes("[IMAGE:")) {
|
|
8152
8597
|
this.config.instructions += IMAGE_INSTRUCTIONS;
|
|
8153
8598
|
}
|
|
8599
|
+
if (config.blockStreaming !== "on" && !this.config.instructions.includes("[FILE:")) {
|
|
8600
|
+
this.config.instructions += FILE_INSTRUCTIONS;
|
|
8601
|
+
}
|
|
8154
8602
|
this.interactiveCardConfig = parseDingtalkInteractiveCardConfig(config.interactiveCards);
|
|
8155
8603
|
if (!config.clientId || !config.clientSecret) {
|
|
8156
8604
|
throw new Error(`Channel "${name}" requires clientId and clientSecret for DingTalk.`);
|
|
@@ -8164,7 +8612,12 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8164
8612
|
if (this.interactiveCardConfig.enabled) {
|
|
8165
8613
|
this.interactiveCardClient = new DingtalkInteractiveCardClient({
|
|
8166
8614
|
robotCode: config.clientId,
|
|
8167
|
-
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")
|
|
8168
8621
|
});
|
|
8169
8622
|
if (this.interactiveCardConfig.statusCard.enabled && config.blockStreaming !== "on") {
|
|
8170
8623
|
this.statusCardController = new StatusCardController({
|
|
@@ -8383,24 +8836,135 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8383
8836
|
static isUnroutableGroupMessage(isGroup, conversationId) {
|
|
8384
8837
|
return isGroup && !conversationId;
|
|
8385
8838
|
}
|
|
8386
|
-
|
|
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) {
|
|
8387
8939
|
const projection = projectFileText(text);
|
|
8388
8940
|
const streamedMarkers = streamed ? streamed.result("").markerCount : 0;
|
|
8389
|
-
if (projection.markerCount
|
|
8390
|
-
|
|
8391
|
-
}
|
|
8392
|
-
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})
|
|
8393
8943
|
`);
|
|
8394
|
-
|
|
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));
|
|
8395
8960
|
}
|
|
8396
|
-
async prepareOutgoingText(text
|
|
8397
|
-
const
|
|
8398
|
-
const markers = findImageMarkers(fileSafeText);
|
|
8961
|
+
async prepareOutgoingText(text) {
|
|
8962
|
+
const markers = findImageMarkers(text);
|
|
8399
8963
|
if (markers.length === 0)
|
|
8400
|
-
return
|
|
8964
|
+
return text;
|
|
8401
8965
|
const replacements = [];
|
|
8402
8966
|
for (const marker of markers) {
|
|
8403
|
-
const fileName =
|
|
8967
|
+
const fileName = basename3(marker.path).replace(/[\r\n[\]]+/g, "_").slice(0, 100) || "image";
|
|
8404
8968
|
try {
|
|
8405
8969
|
const image = readValidatedImage(marker.path, {
|
|
8406
8970
|
workspaceDir: this.config.cwd
|
|
@@ -8429,16 +8993,18 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8429
8993
|
replacements.push(`[Image delivery failed: ${fileName}]`);
|
|
8430
8994
|
}
|
|
8431
8995
|
}
|
|
8432
|
-
return replaceImageMarkers(
|
|
8996
|
+
return replaceImageMarkers(text, markers, replacements);
|
|
8433
8997
|
}
|
|
8434
|
-
async sendReply(chatId, text, atUserId, sourceLabel) {
|
|
8998
|
+
async sendReply(chatId, text, atUserId, sourceLabel, prepared = false) {
|
|
8435
8999
|
const webhook = this.webhooks.get(chatId);
|
|
8436
9000
|
if (!webhook) {
|
|
8437
9001
|
process.stderr.write(`[DingTalk:${this.name}] No webhook for chatId ${chatId}, cannot send.
|
|
8438
9002
|
`);
|
|
8439
9003
|
return;
|
|
8440
9004
|
}
|
|
8441
|
-
const outgoingText = await this.
|
|
9005
|
+
const outgoingText = prepared ? text : await this.prepareReplyOutput(chatId, text);
|
|
9006
|
+
if (!outgoingText.trim())
|
|
9007
|
+
return;
|
|
8442
9008
|
const mentionPrefix = atUserId ? `@${atUserId}
|
|
8443
9009
|
|
|
8444
9010
|
` : "";
|
|
@@ -8517,7 +9083,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8517
9083
|
async pushProactive(target, text, sourceLabel) {
|
|
8518
9084
|
if (!text.trim())
|
|
8519
9085
|
return;
|
|
8520
|
-
const outgoingText = await this.
|
|
9086
|
+
const outgoingText = await this.prepareFileOutput(text, (file, mediaId) => this.sendProactiveFile(target, file, mediaId));
|
|
9087
|
+
if (!outgoingText.trim())
|
|
9088
|
+
return;
|
|
8521
9089
|
const sourcePrefix = sourceLabel ? `${escapeDingTalkMarkdown(sourceLabel)}
|
|
8522
9090
|
|
|
8523
9091
|
` : "";
|
|
@@ -8551,7 +9119,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8551
9119
|
const errmsg = sanitizeLogText(String(data.errmsg ?? ""), 200);
|
|
8552
9120
|
process.stderr.write(`[DingTalk:${this.name}] access token request failed: gettoken errcode=${data.errcode} ${errmsg}
|
|
8553
9121
|
`);
|
|
8554
|
-
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)));
|
|
8555
9123
|
}
|
|
8556
9124
|
this.proactiveToken = {
|
|
8557
9125
|
token: data.access_token,
|
|
@@ -8577,6 +9145,12 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8577
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");
|
|
8578
9146
|
}
|
|
8579
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) {
|
|
8580
9154
|
const targetKind = target.isGroup === true ? "group" : "dm";
|
|
8581
9155
|
for (let attempt = 0; ; attempt++) {
|
|
8582
9156
|
const token = await this.getProactiveToken();
|
|
@@ -8592,8 +9166,8 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8592
9166
|
body: JSON.stringify({
|
|
8593
9167
|
robotCode: this.config.clientId,
|
|
8594
9168
|
...targetBody,
|
|
8595
|
-
msgKey
|
|
8596
|
-
msgParam: JSON.stringify(
|
|
9169
|
+
msgKey,
|
|
9170
|
+
msgParam: JSON.stringify(msgParam)
|
|
8597
9171
|
}),
|
|
8598
9172
|
signal: AbortSignal.timeout(PROACTIVE_FETCH_TIMEOUT_MS)
|
|
8599
9173
|
});
|
|
@@ -8614,6 +9188,27 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8614
9188
|
`);
|
|
8615
9189
|
throw new Error(`DingTalk proactive send failed: HTTP ${resp.status}${detail ? ` ${detail}` : ""}`);
|
|
8616
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
|
+
}
|
|
8617
9212
|
if (target.isGroup === false) {
|
|
8618
9213
|
let data;
|
|
8619
9214
|
try {
|
|
@@ -8633,6 +9228,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8633
9228
|
`);
|
|
8634
9229
|
throw new Error("DingTalk proactive send failed: direct recipient rate limited");
|
|
8635
9230
|
}
|
|
9231
|
+
if (msgKey === PROACTIVE_FILE_MSG_KEY && !data.processQueryKey?.trim()) {
|
|
9232
|
+
throw new Error("DingTalk file delivery failed: missing processQueryKey");
|
|
9233
|
+
}
|
|
8636
9234
|
return;
|
|
8637
9235
|
}
|
|
8638
9236
|
await resp.body?.cancel();
|
|
@@ -8697,6 +9295,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8697
9295
|
if (this.dedupTimer) {
|
|
8698
9296
|
clearInterval(this.dedupTimer);
|
|
8699
9297
|
}
|
|
9298
|
+
this.statusCardController?.dispose();
|
|
8700
9299
|
this.activeReactionKeys.clear();
|
|
8701
9300
|
this.sessionReactionKeys.clear();
|
|
8702
9301
|
if (this.connectionManager) {
|
|
@@ -8975,7 +9574,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8975
9574
|
}
|
|
8976
9575
|
await this.sendReply(chatId, text, void 0, sourceLabel);
|
|
8977
9576
|
}
|
|
8978
|
-
async sendResponseMessage(chatId, text, sessionId, sourceLabel) {
|
|
9577
|
+
async sendResponseMessage(chatId, text, sessionId, sourceLabel, prepared = false) {
|
|
8979
9578
|
let outgoingText = text;
|
|
8980
9579
|
let consumesMention = true;
|
|
8981
9580
|
if (this.config.blockStreaming === "on") {
|
|
@@ -8988,7 +9587,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8988
9587
|
const atUserId = consumesMention && this.atSender ? this.sessionMentionTargets.get(sessionId) : void 0;
|
|
8989
9588
|
if (atUserId)
|
|
8990
9589
|
this.sessionMentionTargets.delete(sessionId);
|
|
8991
|
-
await this.sendReply(chatId, outgoingText, atUserId, sourceLabel ?? this.getResponseSourceLabel(sessionId));
|
|
9590
|
+
await this.sendReply(chatId, outgoingText, atUserId, sourceLabel ?? this.getResponseSourceLabel(sessionId), prepared);
|
|
8992
9591
|
}
|
|
8993
9592
|
projectBlockStreamChunk(text, sessionId) {
|
|
8994
9593
|
let state = this.blockFileProjectors.get(sessionId);
|
|
@@ -9019,13 +9618,13 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9019
9618
|
const streamed = segment ? this.fileProjectors.get(segment.runId)?.projector : void 0;
|
|
9020
9619
|
if (segment)
|
|
9021
9620
|
this.fileProjectors.delete(segment.runId);
|
|
9022
|
-
const outgoingText = await this.
|
|
9621
|
+
const outgoingText = await this.prepareReplyOutput(chatId, text, streamed);
|
|
9023
9622
|
if (segment && this.interactionPresenter) {
|
|
9024
9623
|
if (await this.interactionPresenter.closeOutput(segment.segmentId, outgoingText, "completed", segment)) {
|
|
9025
9624
|
return;
|
|
9026
9625
|
}
|
|
9027
9626
|
}
|
|
9028
|
-
await this.sendResponseMessage(chatId, outgoingText, sessionId, segment?.sourceLabel);
|
|
9627
|
+
await this.sendResponseMessage(chatId, outgoingText, sessionId, segment?.sourceLabel, true);
|
|
9029
9628
|
}
|
|
9030
9629
|
onOutputSegmentEnd(_chatId, _sessionId, segment, reason) {
|
|
9031
9630
|
if (reason === "completed" || reason === "failed" || reason === "cancelled") {
|
|
@@ -9291,9 +9890,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9291
9890
|
let filePath;
|
|
9292
9891
|
let safeName;
|
|
9293
9892
|
try {
|
|
9294
|
-
dir = join(
|
|
9893
|
+
dir = join(tmpdir3(), "channel-files", randomUUID5());
|
|
9295
9894
|
mkdirSync(dir, { recursive: true });
|
|
9296
|
-
safeName =
|
|
9895
|
+
safeName = basename3(typeof fileName === "string" ? fileName : "") || `dingtalk_${mediaType}_${Date.now()}.${GENERATED_MEDIA_EXT[media.mimeType] ?? "bin"}`;
|
|
9297
9896
|
filePath = join(dir, safeName);
|
|
9298
9897
|
writeFileSync(filePath, media.buffer);
|
|
9299
9898
|
} catch (error) {
|
|
@@ -9397,10 +9996,17 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9397
9996
|
}
|
|
9398
9997
|
}) : this.handleInbound(envelope);
|
|
9399
9998
|
processMessage.catch((err) => {
|
|
9400
|
-
|
|
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)}
|
|
9401
10006
|
`);
|
|
10007
|
+
const fallbackMessage = formatInboundErrorMessage(err, reference);
|
|
9402
10008
|
const sourceLabel = this.getInboundErrorSourceLabel(envelope);
|
|
9403
|
-
const delivery = sourceLabel ? this.sendThreadMessage(chatId, envelope.threadId,
|
|
10009
|
+
const delivery = sourceLabel ? this.sendThreadMessage(chatId, envelope.threadId, fallbackMessage, sourceLabel) : this.sendMessage(chatId, fallbackMessage);
|
|
9404
10010
|
delivery.catch(() => {
|
|
9405
10011
|
});
|
|
9406
10012
|
});
|