@qwen-code/qwen-code 0.23.1-preview.1 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled/computer-use/SKILL.md +189 -116
- package/bundled/goal-draft/SKILL.md +23 -13
- package/bundled/qc-helper/docs/_meta.ts +1 -0
- package/bundled/qc-helper/docs/configuration/model-providers.md +47 -1
- package/bundled/qc-helper/docs/configuration/settings.md +57 -7
- package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +26 -0
- package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
- package/bundled/qc-helper/docs/features/commands.md +71 -6
- package/bundled/qc-helper/docs/features/computer-use.md +9 -7
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/goals.md +15 -3
- package/bundled/qc-helper/docs/features/skills.md +40 -0
- package/bundled/qc-helper/docs/qwen-serve.md +19 -1
- package/chunks/{MaxSizedBox-5ARLO5PR.js → MaxSizedBox-UDO6Y7RB.js} +35 -36
- package/chunks/{StandaloneSessionPicker-T6B322CB.js → StandaloneSessionPicker-D4CUOO4H.js} +55 -56
- package/chunks/{acp-startup-profiler-6ULXXQMS.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
- package/chunks/{acpAgent-WTDEY5KD.js → acpAgent-KWLJFADK.js} +210 -131
- package/chunks/{agent-NXPUXEVZ.js → agent-GSUPGEOL.js} +24 -25
- package/chunks/{agent-headless-QQZTWOKO.js → agent-headless-HNYCQUJB.js} +24 -25
- package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-I7LQZH26.js} +30 -7
- package/chunks/{artifact-tool-DFVVJXL2.js → artifact-tool-P52OKKEF.js} +1 -1
- package/chunks/{askUserQuestion-GF7VQ44M.js → askUserQuestion-I5W5S3D6.js} +2 -2
- package/chunks/{bridge-OHY5OGOZ.js → bridge-B7CV6RVI.js} +40 -41
- package/chunks/{channel-management-service-ZDDG3G5S.js → channel-management-service-TRTLQTSV.js} +4 -4
- package/chunks/{channel-settings-store-7BJAS2SU.js → channel-settings-store-FW45IRUP.js} +46 -47
- package/chunks/{channel-worker-group-2ISMRENV.js → channel-worker-group-PIYPVCTF.js} +6 -6
- package/chunks/{channel-worker-manager-VSRPVPRH.js → channel-worker-manager-FQHEDTD2.js} +6 -6
- package/chunks/{channel-worker-supervisor-SRJBK72Z.js → channel-worker-supervisor-XJPZZ3VK.js} +3 -3
- package/chunks/{chunk-2WGJG2KW.js → chunk-25CBAK3H.js} +4 -4
- package/chunks/{chunk-XUSOYE2I.js → chunk-27LTEY6D.js} +1 -1
- package/chunks/{chunk-WTW36TJ3.js → chunk-2EKVPSIJ.js} +1 -1
- package/chunks/{chunk-NAKALAL4.js → chunk-2TMJRF46.js} +116 -15
- package/chunks/{chunk-E4L5BM2B.js → chunk-2YS3NU4A.js} +4 -4
- package/chunks/chunk-2Z3T52OC.js +82 -0
- package/chunks/{chunk-ER273QE6.js → chunk-2ZFO5JD7.js} +21 -4
- package/chunks/{chunk-WXC6OAWD.js → chunk-3BTHHXXE.js} +1 -1
- package/chunks/{chunk-GXZHYPHZ.js → chunk-3LPJ776W.js} +5 -2
- package/chunks/{chunk-XY3USGFE.js → chunk-3VDLQUR2.js} +1 -1
- package/chunks/{chunk-LK7S2D6V.js → chunk-3VWPPK5Q.js} +58 -4
- package/chunks/{chunk-IKLFS6SC.js → chunk-3YQMUBTS.js} +3 -3
- package/chunks/{chunk-P4RUUG64.js → chunk-45ROPFQY.js} +1 -1
- package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
- package/chunks/{chunk-D6PIMKY3.js → chunk-4VY3ITHR.js} +4 -4
- package/chunks/{chunk-H3UDNQLO.js → chunk-5CVY5Q2P.js} +3 -3
- package/chunks/{chunk-6UIACMGH.js → chunk-5DQ4YTIZ.js} +1 -1
- package/chunks/{chunk-P6LATTDG.js → chunk-5IL2BZHW.js} +3 -3
- package/chunks/{chunk-537SQ2AI.js → chunk-5WC2ECUK.js} +104 -16
- package/chunks/{chunk-HFTB354P.js → chunk-5Z4FCEPY.js} +60 -6
- package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
- package/chunks/{chunk-AQ5NAGWI.js → chunk-66JBCTJF.js} +8 -7
- package/chunks/{chunk-54TF2ZIQ.js → chunk-6JXHO7LG.js} +3 -3
- package/chunks/{chunk-YCDL2SAS.js → chunk-6QILGINT.js} +2 -2
- package/chunks/{chunk-P5LDR7FI.js → chunk-6QV7Z74P.js} +3 -3
- package/chunks/{chunk-4HC4DYKN.js → chunk-6RZX2HIH.js} +1 -1
- package/chunks/{chunk-O45WBTNS.js → chunk-6SADVYQQ.js} +3 -3
- package/chunks/{chunk-KE3Q4JMY.js → chunk-6TPVIESH.js} +5 -7
- package/chunks/{chunk-2LD5U7Q3.js → chunk-6YEOCHSE.js} +29 -1
- package/chunks/{chunk-QWZOOIR3.js → chunk-75LBC7SV.js} +69 -12
- package/chunks/{chunk-7BZS4ZDV.js → chunk-7SL55L5H.js} +25 -18
- package/chunks/{chunk-O2GG7H4C.js → chunk-ARYNBBBM.js} +3 -3
- package/chunks/{chunk-CZACBHAW.js → chunk-B3EL44K3.js} +5 -5
- package/chunks/{chunk-VY6UVU7G.js → chunk-CABDNUJ4.js} +2 -2
- package/chunks/{chunk-RVNS7NWN.js → chunk-CALNF3Z3.js} +1 -1
- package/chunks/{chunk-MWHY26G3.js → chunk-CHVU543W.js} +1 -1
- package/chunks/{chunk-GZWW2QWR.js → chunk-CIKL2DQP.js} +2 -2
- package/chunks/{chunk-R355CUNQ.js → chunk-CLKE4IY3.js} +1 -77
- package/chunks/{chunk-MUZCSTOO.js → chunk-CRZBDVP2.js} +5 -4
- package/chunks/{chunk-SFMCYMVF.js → chunk-D6AQNMUA.js} +4 -4
- package/chunks/{chunk-D4CU6DKR.js → chunk-DO5SMV52.js} +10 -8
- package/chunks/{chunk-ZAZ3NFL6.js → chunk-DXQ6Z7AH.js} +315 -63
- package/chunks/{chunk-IXSGOSEG.js → chunk-DZ6D4B3K.js} +28 -25
- package/chunks/{chunk-GMNLYQOS.js → chunk-E6TI726I.js} +1 -1
- package/chunks/{chunk-JBTZUFR4.js → chunk-E7XSUYCZ.js} +6 -6
- package/chunks/{chunk-AHBLRVD5.js → chunk-EEKU6COG.js} +4 -4
- package/chunks/{chunk-47BZVBTE.js → chunk-EHTKOO6W.js} +4 -4
- package/chunks/{chunk-HJ34U5J4.js → chunk-ENZDGHGJ.js} +4 -4
- package/chunks/{chunk-IFD3BTEA.js → chunk-EOET4H7C.js} +3 -3
- package/chunks/{chunk-ZTAVGFKA.js → chunk-ERXNTINK.js} +1 -1
- package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
- package/chunks/{chunk-KPXRFTT7.js → chunk-FETY36NQ.js} +1 -1
- package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
- package/chunks/{chunk-4F2QRVW6.js → chunk-FW4E4QPG.js} +1 -1
- package/chunks/{chunk-KJJPJYHI.js → chunk-FWRRUITH.js} +8 -8
- package/chunks/{chunk-4VUVBN3Y.js → chunk-G6UUOCUT.js} +87 -0
- package/chunks/{chunk-4JAGXZR3.js → chunk-GM44O6F7.js} +1 -1
- package/chunks/{chunk-4MCY33Y2.js → chunk-GNY7B3CA.js} +1 -1
- package/chunks/{chunk-VEFRT7NX.js → chunk-H3Q3RSKZ.js} +1 -1
- package/chunks/{chunk-43NOB5NM.js → chunk-HIXUUCGY.js} +188 -13
- package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
- package/chunks/{chunk-JOPC3FND.js → chunk-HUX2DOTF.js} +5 -5
- package/chunks/{chunk-GCFZ2LAX.js → chunk-HZ2HUXX7.js} +2 -2
- package/chunks/{chunk-CWNC7M73.js → chunk-IKG2YVRZ.js} +2 -2
- package/chunks/{chunk-L4R7BCVV.js → chunk-J3TJH52D.js} +1 -1
- package/chunks/{chunk-QMFOYPGV.js → chunk-J3VZF2AL.js} +2 -2
- package/chunks/{chunk-ZJ2LM2SI.js → chunk-JGDRB4FP.js} +104 -33
- package/chunks/{chunk-LMJQSPWB.js → chunk-KA5HR3G2.js} +1 -1
- package/chunks/{chunk-G34YLYCS.js → chunk-L7V52QEZ.js} +10 -10
- package/chunks/{chunk-GVVCLL2P.js → chunk-LNCNUMJ5.js} +451 -396
- package/chunks/{chunk-RDKXZ2LS.js → chunk-LYT2OU7D.js} +1 -1
- package/chunks/{chunk-SAZS4IWW.js → chunk-LZGFVUWZ.js} +3 -3
- package/chunks/{chunk-32YDNYXP.js → chunk-M73KHGNR.js} +13 -66
- package/chunks/{chunk-ADJD4LZF.js → chunk-MA5OUNN6.js} +1 -1
- package/chunks/{chunk-2RYWGYB3.js → chunk-MFYH2VXV.js} +3 -3
- package/chunks/{chunk-RPBMP6BN.js → chunk-MWIO7MF6.js} +3 -0
- package/chunks/{chunk-OECNP26L.js → chunk-N6S3NUYJ.js} +1 -1
- package/chunks/{chunk-5MTARK4Y.js → chunk-N7YQEKGX.js} +6 -6
- package/chunks/{chunk-XOVVCGZX.js → chunk-NB3NDQQK.js} +1 -1
- package/chunks/chunk-NOO4QFXM.js +171 -0
- package/chunks/{chunk-NGX4NUNP.js → chunk-O2FEO2CB.js} +131 -6
- package/chunks/{chunk-XHGGYCTA.js → chunk-O2JBJQCF.js} +1 -1
- package/chunks/{chunk-LPBQODMR.js → chunk-OESZTXTG.js} +4 -4
- package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
- package/chunks/{chunk-TDP7UULF.js → chunk-OPMKGOLD.js} +1 -1
- package/chunks/{chunk-LDS57224.js → chunk-OWCFKIFQ.js} +1 -1
- package/chunks/{chunk-I72PHOKL.js → chunk-PDUMGZ2P.js} +1524 -1382
- package/chunks/{chunk-JRYL3T2O.js → chunk-PQSCGZT2.js} +1 -1
- package/chunks/{chunk-WEXA2DNG.js → chunk-PSPAM24S.js} +14 -0
- package/chunks/{chunk-UKKYOIVT.js → chunk-QAZ2MGYT.js} +2 -2
- package/chunks/{chunk-J3O5I5ZD.js → chunk-QK4K76T6.js} +3 -3
- package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
- package/chunks/{chunk-5YY5MZT6.js → chunk-QZOXVQPK.js} +1 -1
- package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
- package/chunks/{chunk-IQN2CCIE.js → chunk-RNYENHN5.js} +398 -55
- package/chunks/{chunk-64MQTIX7.js → chunk-RPFJJ33Z.js} +2 -2
- package/chunks/{chunk-4VZCORNT.js → chunk-RXT4QBDX.js} +1 -1
- package/chunks/{chunk-SN5FV4FY.js → chunk-S6QVI3MV.js} +3 -3
- package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
- package/chunks/{chunk-JLWFGYXU.js → chunk-T2IHCZLS.js} +2 -2
- package/chunks/{chunk-DNPHKA72.js → chunk-TGC4264Q.js} +6 -6
- package/chunks/{chunk-PZV2FASB.js → chunk-TRWQQBVH.js} +1 -1
- package/chunks/{chunk-Y3ZKI4RQ.js → chunk-TWAMIEQ2.js} +85 -22
- package/chunks/{chunk-KK2GZGBK.js → chunk-TWWS7XUW.js} +14 -11
- package/chunks/{chunk-4IQKBLTQ.js → chunk-UHUT4IDM.js} +18 -9
- package/chunks/{chunk-BKNY7PDI.js → chunk-USN6VNTO.js} +1 -1
- package/chunks/{chunk-TMWB67LS.js → chunk-UXDVUFKU.js} +3 -3
- package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
- package/chunks/{chunk-3K456UJF.js → chunk-VF6D6EGV.js} +12 -4
- package/chunks/{chunk-PZUOHCWI.js → chunk-WAASYFPK.js} +2 -2
- package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
- package/chunks/{chunk-JPEAQJNS.js → chunk-WJDXKQIO.js} +1 -1
- package/chunks/{chunk-MNEYUNOE.js → chunk-WNISCNTA.js} +40 -2
- package/chunks/{chunk-Z6WZPXQH.js → chunk-WQMUGQ6G.js} +2 -2
- package/chunks/{chunk-N7VURC4O.js → chunk-WXFCI3O5.js} +2 -2
- package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
- package/chunks/{chunk-N7EYO2E7.js → chunk-XQ4RDO5B.js} +1 -1
- package/chunks/{chunk-VDXYYVCD.js → chunk-XVTCSVBK.js} +579 -57
- package/chunks/{chunk-PTFFWTTO.js → chunk-XZ3Z43XL.js} +3 -3
- package/chunks/{chunk-QSC5YOEC.js → chunk-YAC7H4K3.js} +2 -2
- package/chunks/{chunk-43JNQAHO.js → chunk-YCEKI7QX.js} +51 -10
- package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
- package/chunks/{chunk-VUSSAGKI.js → chunk-YZTGGCEE.js} +10 -2
- package/chunks/{chunk-WR3SH3EY.js → chunk-ZNO5BUAD.js} +149 -66
- package/chunks/{chunk-URSCX7S7.js → chunk-ZPL2TZNA.js} +353 -11
- package/chunks/{chunk-UEZOXZNI.js → chunk-ZU2T5JIS.js} +804 -371
- package/chunks/{config-utils-QXDOTXEQ.js → config-utils-KTDSQ4MU.js} +39 -40
- package/chunks/{contextCommand-RN4KARWC.js → contextCommand-UQ3KRYGK.js} +37 -38
- package/chunks/{core-runtime-NAZCOKHB.js → core-runtime-JR34JAFH.js} +35 -36
- package/chunks/{create-sub-session-BCSM4WKB.js → create-sub-session-RGPJOI4S.js} +45 -40
- package/chunks/{create-sub-session-BQ3SE4TX.js → create-sub-session-TGIX63YU.js} +2 -2
- package/chunks/{cron-create-D6HQ7I7I.js → cron-create-GTPVMJCF.js} +1 -1
- package/chunks/{cron-delete-KK3D2SQV.js → cron-delete-ZBK27Z4K.js} +1 -1
- package/chunks/{cron-list-VBF3IZMF.js → cron-list-KTFKFDKC.js} +1 -1
- package/chunks/{daemon-LCUELM6E.js → daemon-UI6SQSBV.js} +1 -1
- package/chunks/{daemon-git-worktree-guard-3K5CAU36.js → daemon-git-worktree-guard-H3OA26KQ.js} +35 -36
- package/chunks/{daemon-status-provider-4X3ZZQTZ.js → daemon-status-provider-6WZLKSZU.js} +45 -46
- package/chunks/{daemon-trust-policy-R45CFUJA.js → daemon-trust-policy-3EDP2BYD.js} +42 -43
- package/chunks/{daemon-trust-policy-monitor-DSSFCO3K.js → daemon-trust-policy-monitor-CRHZPK52.js} +42 -43
- package/chunks/{deferred-core-runtime-UO2M6WYI.js → deferred-core-runtime-LO5NTQQ4.js} +35 -36
- package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
- package/chunks/{display-image-EVVTBVYE.js → display-image-CTNHJRZC.js} +4 -4
- package/chunks/{dist-SIHF5MU2.js → dist-24TCWK5H.js} +1 -1
- package/chunks/{dist-AFH3BMZZ.js → dist-5I4HLUTO.js} +1 -1
- package/chunks/{dist-3T5MDUHP.js → dist-FDISN4AK.js} +1 -1
- package/chunks/{dist-SB2XRXZA.js → dist-M4CBX53H.js} +1 -1
- package/chunks/{dist-UVHW2U56.js → dist-NQ2636VT.js} +1 -1
- package/chunks/{dist-PH5RSTEA.js → dist-OR2ZQTXZ.js} +1 -1
- package/chunks/{dist-MK5PPBRF.js → dist-STAGIFNB.js} +1099 -67
- package/chunks/{dist-R5Y34V6T.js → dist-WZTUKIDR.js} +2 -2
- package/chunks/{dist-QUU7TVE3.js → dist-XJ25G6OH.js} +1 -1
- package/chunks/{edit-VNBCTRWP.js → edit-LB7Z7XK5.js} +24 -25
- package/chunks/{en-JMR535HP.js → en-YJNRUQG4.js} +1 -1
- package/chunks/{enter-worktree-CEVK7MQ2.js → enter-worktree-YFTKHXHZ.js} +4 -4
- package/chunks/{enterPlanMode-4KMZMUIA.js → enterPlanMode-P6TVUFIY.js} +24 -25
- package/chunks/{environment-S2HYQDON.js → environment-QATJNNKI.js} +38 -39
- package/chunks/{errors-DAAN5TL7.js → errors-3XJ37PS2.js} +37 -38
- package/chunks/{exit-worktree-D3YE6MUN.js → exit-worktree-NF2XEMES.js} +5 -5
- package/chunks/{exitPlanMode-HR36HG3D.js → exitPlanMode-A3OKL5UO.js} +24 -25
- package/chunks/{fast-path-4IWSW3UV.js → fast-path-DBIT5YQQ.js} +3 -3
- package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
- package/chunks/{glob-IZYB2XH2.js → glob-73EDTXUE.js} +24 -25
- package/chunks/{goal-tools-VGUPKQDJ.js → goal-tools-DFI6YMSD.js} +24 -25
- package/chunks/{grep-OUVLNXG7.js → grep-BLHF2S5D.js} +2 -2
- package/chunks/{handleAutoUpdate-D56FMDTW.js → handleAutoUpdate-2FUNJO3B.js} +38 -39
- package/chunks/{i18n-BKE5WO6T.js → i18n-FDIA6KFI.js} +38 -37
- package/chunks/{image-gen-SHVQ3XID.js → image-gen-XP4NNIYG.js} +5 -5
- package/chunks/{initializer-MS4SGEHF.js → initializer-4MJTJOTW.js} +42 -43
- package/chunks/{installationInfo-542MGC4S.js → installationInfo-232RA2OK.js} +35 -36
- package/chunks/{list-H6XTKUWL.js → list-WN6WSGEB.js} +45 -46
- package/chunks/{list-agents-ULYBGJXC.js → list-agents-I5TRH3J7.js} +2 -2
- package/chunks/{llm-3NUC4EJY.js → llm-UDFWQWZA.js} +77 -78
- package/chunks/{llm-content-generator-R4NL3OQN.js → llm-content-generator-VLMZ2A7A.js} +23 -8
- package/chunks/{loadedSettingsAdapter-3XLKYDVT.js → loadedSettingsAdapter-OBQEIXM7.js} +42 -43
- package/chunks/{loggingContentGenerator-ZYSWVNEO.js → loggingContentGenerator-RGVUMUVX.js} +26 -27
- package/chunks/{loop-wakeup-B27BEYRL.js → loop-wakeup-HL6XOWI4.js} +2 -2
- package/chunks/{ls-3IIMMVKF.js → ls-YV7RKLKY.js} +1 -1
- package/chunks/{lsp-VJAT7XKS.js → lsp-NO3AMRZT.js} +1 -1
- package/chunks/{managed-npm-update-L2I53ZAI.js → managed-npm-update-QBAJYCFU.js} +35 -36
- package/chunks/{mcp-4PIXQASW.js → mcp-OTIZZCPY.js} +42 -43
- package/chunks/{monitor-O2YQTOZZ.js → monitor-BV5XF6LL.js} +24 -25
- package/chunks/{nonInteractiveCli-LV7CDBA2.js → nonInteractiveCli-W6MUKDVJ.js} +79 -77
- package/chunks/{notebook-edit-4RE2ALH4.js → notebook-edit-HGBEKGTE.js} +24 -25
- package/chunks/{openaiContentGenerator-7ND7K5CP.js → openaiContentGenerator-NSU3ERBH.js} +15 -15
- package/chunks/{pidfile-UFTLQ7NP.js → pidfile-LE3TU4GE.js} +35 -36
- package/chunks/{processUtils-3XBB4FYV.js → processUtils-YFBGJK67.js} +2 -2
- package/chunks/{prompt-terminal-ledger-2QASOGMM.js → prompt-terminal-ledger-4W4W7DSO.js} +36 -37
- package/chunks/{qwenContentGenerator-AELTUTH6.js → qwenContentGenerator-HTA57WFC.js} +28 -29
- package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
- package/chunks/{read-file-PDWHZPHX.js → read-file-KHPQ2MB6.js} +4 -4
- package/chunks/{read-mcp-resource-YXJZ75UB.js → read-mcp-resource-D3N75DGF.js} +1 -1
- package/chunks/{record-artifact-WJDOV6XU.js → record-artifact-Q5CRGJTP.js} +2 -2
- package/chunks/{report-findings-Q4UACKWR.js → report-findings-TJ34R7QK.js} +3 -3
- package/chunks/{request-shutdown-2YZ3E3GH.js → request-shutdown-LRKMTBAD.js} +6 -6
- package/chunks/{resumeHistoryUtils-QRXZEEBA.js → resumeHistoryUtils-K7RV3QBN.js} +39 -40
- package/chunks/{ripGrep-KSOOLE6H.js → ripGrep-NBBVCMG4.js} +7 -7
- package/chunks/{run-qwen-serve-RTAREPT6.js → run-qwen-serve-A3JBOZCM.js} +58 -60
- package/chunks/{runtime-ESFSCJRZ.js → runtime-7YOU2KJ3.js} +47 -48
- package/chunks/{scheduled-tasks-6ZHRNBH6.js → scheduled-tasks-52LXK7LN.js} +42 -43
- package/chunks/{scheduler-DQI6KV7T.js → scheduler-J44M72VM.js} +37 -38
- package/chunks/{send-message-PQCVSVMN.js → send-message-AWKUDJBH.js} +8 -8
- package/chunks/{serve-FY7ZEW52.js → serve-TRC6XJUB.js} +42 -43
- package/chunks/{server-KNDY6K5F.js → server-YPNTJLX2.js} +1314 -841
- package/chunks/{session-MCEPXAZP.js → session-FMMIBFYX.js} +98 -84
- package/chunks/{session-attachments-root-OLNAE6GF.js → session-attachments-root-LDJMNK7K.js} +35 -36
- package/chunks/{session-pr-refresh-HKJHQQQK.js → session-pr-refresh-NLR4EK2J.js} +41 -42
- package/chunks/{settings-VXO4WBMK.js → settings-A46L577J.js} +41 -42
- package/chunks/{shell-U263OTES.js → shell-Q5LSQPPY.js} +24 -25
- package/chunks/{skill-SDODGBKL.js → skill-75KPJRCM.js} +10 -57
- package/chunks/{skill-settings-YEIA22QJ.js → skill-settings-775YT4YR.js} +41 -42
- package/chunks/{spawnChannel-4WJZVFPP.js → spawnChannel-XY73I5CU.js} +37 -38
- package/chunks/{standalone-update-ZWVQUO64.js → standalone-update-L46XXNQ2.js} +37 -38
- package/chunks/{start-opentui-ui-BFYCJQRZ.js → start-opentui-ui-WLV43247.js} +2007 -1003
- package/chunks/{startInteractiveUI-JYAFCMHL.js → startInteractiveUI-F5DKMLOV.js} +1231 -1528
- package/chunks/{syntheticOutput-AUAJBNXR.js → syntheticOutput-D2P5V6RG.js} +2 -2
- package/chunks/{task-create-LD5ISM3E.js → task-create-PMAFST2T.js} +7 -7
- package/chunks/{task-list-YISJ4RJA.js → task-list-R2HSY2NC.js} +1 -1
- package/chunks/{task-stop-65ZOVATJ.js → task-stop-BFSKRTGV.js} +1 -1
- package/chunks/{task-update-AAN4ZVEY.js → task-update-JYC57USF.js} +7 -7
- package/chunks/{team-create-KU7MABNO.js → team-create-2PATB77U.js} +24 -25
- package/chunks/{team-delete-XFRRTJTT.js → team-delete-CBHVBTPB.js} +1 -1
- package/chunks/{team-plan-approval-DPB377A3.js → team-plan-approval-QTANEWOS.js} +24 -25
- package/chunks/{terminal-image-renderer-WGWRENOF.js → terminal-image-renderer-OGULCFNF.js} +37 -38
- package/chunks/{theme-manager-GBUFULSO.js → theme-manager-CNO3QERP.js} +35 -36
- package/chunks/{todoWrite-G7NT4IFP.js → todoWrite-5ERKFWAK.js} +3 -5
- package/chunks/{tool-search-6YUXHBPT.js → tool-search-VXWEOZE7.js} +9 -9
- package/chunks/{total-session-admission-54R2JQ5L.js → total-session-admission-4KAADZPB.js} +41 -42
- package/chunks/{trustedFolders-KAJIDJTH.js → trustedFolders-PPJSOPOT.js} +36 -37
- package/chunks/{update-relaunch-XM4IWBFD.js → update-relaunch-4PT4MW7B.js} +5 -5
- package/chunks/{updateCheck-W6UZFURI.js → updateCheck-WAVFLWNG.js} +37 -38
- package/chunks/{useAutoAcceptIndicator-LAWYHY3U.js → useAutoAcceptIndicator-XNED4NRB.js} +44 -45
- package/chunks/{validateNonInterActiveAuth-7WCKHRN2.js → validateNonInterActiveAuth-J676DUQ2.js} +74 -74
- package/chunks/{version-3ZU43RJ6.js → version-J6SRRQB2.js} +1 -1
- package/chunks/{web-fetch-QHI2SQL4.js → web-fetch-FMZZYX44.js} +7 -7
- package/chunks/{web-search-3KZZKWNY.js → web-search-3G2KXCX5.js} +19 -8
- package/chunks/{workflow-HRW7Y2X4.js → workflow-PPZZICQ7.js} +26 -27
- package/chunks/{workspace-providers-status-KTGCWCPC.js → workspace-providers-status-IIYTAQST.js} +46 -47
- package/chunks/{workspace-registration-store-LHLPPWNE.js → workspace-registration-store-VHCDXAV7.js} +1 -1
- package/chunks/{workspace-registry-X34MLN52.js → workspace-registry-I7VQIPS2.js} +41 -42
- package/chunks/{workspace-runtime-coordinator-U4PW4P7K.js → workspace-runtime-coordinator-DBGNY32G.js} +41 -42
- package/chunks/{workspace-service-KD7BCGYL.js → workspace-service-QSKB2T54.js} +47 -48
- package/chunks/{workspace-skills-status-YJGO6Y3T.js → workspace-skills-status-T7GPT65J.js} +43 -44
- package/chunks/{workspace-trust-reconciler-EUYHISCH.js → workspace-trust-reconciler-2PKRDAU4.js} +48 -49
- package/chunks/{write-file-EBSB34NJ.js → write-file-L76CGFTQ.js} +26 -27
- package/chunks/{zh-TW-W2GNP2IU.js → zh-TW-N2TBF2F2.js} +1 -1
- package/chunks/{zh-DVFYHRK5.js → zh-VBFCRQBL.js} +1 -1
- package/chunks/{zoom-image-UJ5VKWKP.js → zoom-image-TDJJY2VZ.js} +4 -4
- package/cli.js +13 -13
- package/export-transcript-document.js +126 -122
- package/locales/en.js +2 -2
- package/locales/zh-TW.js +2 -2
- package/locales/zh.js +2 -2
- package/package.json +3 -3
- package/web-shell/assets/{abnfDiagram-VCTEODGH-Dur--luQ.js → abnfDiagram-VCTEODGH-DHc6plZn.js} +1 -1
- package/web-shell/assets/{arc-tYLobxFi.js → arc-BQ9m8TDV.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-IG6aXD03.js → architectureDiagram-5GKGNRK7-D5ap3oVB.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-C6eBSkfA.js → blockDiagram-NRAW4CY4-BIbnyNph.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-BrX3HJqB.js → c4Diagram-UCG6FXSJ-BRsdx_iG.js} +1 -1
- package/web-shell/assets/channel-uMMdTrYk.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-B3fcJ8ee.js → chunk-2Q5K7J3B-3lf1fNlx.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-CeC90yKM.js → chunk-5VM5RSS4-DP8VNRc4.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-CW44RVki.js → chunk-F27PBJKO-DrohDmZ6.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-D1PAMukD.js → chunk-G27WJ6UU-UZ2QhSx6.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-Dt3Y2Fvx.js → chunk-JWPE2WC7-BIMHVcZK.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-CZHw2lLI.js → chunk-LCL6LL3I-izRxdSDd.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-ysNAdTGx.js → chunk-POPQ4Y6H-CXADD4PP.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-BdNXW6YQ.js → chunk-SVP7TREG-B96d8Y_1.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-DgqQ9UA8.js → chunk-XXDRQBXY-CF2sVQpv.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DcY-26Ig.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DcY-26Ig.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-BILImXzJ.js → cose-bilkent-JH36ORCC-CT6tXVAS.js} +1 -1
- package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
- package/web-shell/assets/{cynefin-OW5HDTMX-DR88Pund.js → cynefin-OW5HDTMX-X1NS4vtV.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BYFbfkA6.js → cynefinDiagram-5FMLGOSQ-DNsKNOT4.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-rfpyc6sX.js → dagre-3AP2YEHR-9-AHKqsb.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-BJxLmEwH.js → diagram-S7CK7UJ4-Bjgms7j6.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-H34xm7k3.js → diagram-UQ7AKVKN-h6bCprbE.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-HYxhwNLx.js → diagram-VSXAHHWV-4SbQXVLt.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-BJazso8F.js → diagram-VX7I27RA-B5gPCzzB.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-Clje1aNy.js → diagram-Z3DM3KII-DFJXIA3A.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-M93YBkFh.js → ebnfDiagram-PWID7BFC-FwyaU7VY.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-DY8XzSHU.js → erDiagram-SSCWMZ5O-8vJQh2te.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-CE6Aylcq.js → flowDiagram-A5DVABFB-BzA_1gMN.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DI-5LL22.js → ganttDiagram-EL5Y4UJY-Co-ABbVX.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-C7BZWElk.js → gitGraphDiagram-WWUBYQGX-DW_FcyrX.js} +1 -1
- package/web-shell/assets/{index-DclFHns9.js → index-BbMXfhNG.js} +1 -1
- package/web-shell/assets/{index-CVyqwW7y.js → index-Bu-rZoJ-.js} +483 -475
- package/web-shell/assets/index-CsPwZ1ut.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-CGUSy4Pc.js → infoDiagram-RXCK75RN-BEgfhUFN.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-B5BVks9q.js → ishikawaDiagram-5VMMS53U-DCsMxQmc.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-CFh6Tf7h.js → journeyDiagram-EYS64GPL-DyIEYoHz.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-B7TlxP7c.js → kanban-definition-3QL26DDD-CkxjqCNr.js} +1 -1
- package/web-shell/assets/{layout-Br_pZq2Q.js → layout-BEWc0Al9.js} +1 -1
- package/web-shell/assets/{linear-BVlP6fte.js → linear-CNuNxirL.js} +1 -1
- package/web-shell/assets/{mermaid.core-TrcYWoiF.js → mermaid.core-DZBre674.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-BJ4LzqjZ.js → mindmap-definition-FBJOCRG2-CpafFz_F.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-1b_MxlOl.js → pegDiagram-XKGWAZYB-DfZqk_dq.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-B8zl0YhY.js → pieDiagram-E7YTZNPT-S0UWXlgC.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-CIZO8ukl.js → quadrantDiagram-AXDQQJYC-dd37_Ohj.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-CepHSbCj.js → railroadDiagram-O6MQD6OU-CH8NJZ7u.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-BCgxkcSW.js → requirementDiagram-EFPCY7ZU-CFdqWYih.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-CE5CcoMM.js → sankeyDiagram-P5KCCOFB-CsddcEGD.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DvgHi-d5.js → sequenceDiagram-WJ2MYXX4-BZ270mGw.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-T-fAsCPX.js → sizeCapture-X5ZJPWSS-CGaS4DBV.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-DYHaul-5.js → stateDiagram-HBIQ2CUA-COpIzMu6.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-D6qEVAji.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-Dbz3Qiej.js → swimlanes-XN3QIQJK-CMF889m3.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-mem5Jj4m.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-9NVRts3N.js → timeline-definition-24CTP7MA-BelnxYz5.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-C7cb7vnH.js → vennDiagram-4TSXK5OY-CU-NRqIB.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CG-8Ddjm.js → wardleyDiagram-VM6X3IG4-CDNKqWh-.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-iGeYAcP4.js → xychartDiagram-S5SC5T6Z-CLqguL5D.js} +1 -1
- package/web-shell/index.html +6 -3
- package/chunks/chunk-3UMWOKJC.js +0 -78
- package/chunks/chunk-FKJM6JKY.js +0 -98
- package/chunks/chunk-IQAFKVXS.js +0 -22
- package/web-shell/assets/channel-uEkvKckd.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DuPsnhWS.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DuPsnhWS.js +0 -1
- package/web-shell/assets/index-FO7JXPnH.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-BcYho9a4.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-D6HsOIgX.js +0 -8
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
sanitizePromptText,
|
|
15
15
|
sanitizeSenderName,
|
|
16
16
|
truncateUtf16Units
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-XVTCSVBK.js";
|
|
18
18
|
import "./chunk-IW6RQPQB.js";
|
|
19
19
|
import "./chunk-CQ35AJ4Z.js";
|
|
20
20
|
import "./chunk-DMTGGOSA.js";
|
|
@@ -6933,6 +6933,95 @@ __name(parseDingtalkCardActorId, "parseDingtalkCardActorId");
|
|
|
6933
6933
|
// packages/channels/dingtalk/dist/status-card-controller.js
|
|
6934
6934
|
init_esbuild_shims();
|
|
6935
6935
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
6936
|
+
|
|
6937
|
+
// packages/channels/dingtalk/dist/presentation-phase.js
|
|
6938
|
+
init_esbuild_shims();
|
|
6939
|
+
var DINGTALK_PRESENTATION_PHASE_LABELS = {
|
|
6940
|
+
thinking: "\u{1F914} Thinking",
|
|
6941
|
+
reading: "\u{1F4D6} Reading",
|
|
6942
|
+
searching: "\u{1F50E} Searching",
|
|
6943
|
+
running: "\u{1F5A5}\uFE0F Running",
|
|
6944
|
+
editing: "\u{1F6E0}\uFE0F Editing",
|
|
6945
|
+
deleting: "\u{1F5D1}\uFE0F Deleting",
|
|
6946
|
+
moving: "\u{1F4E6} Moving",
|
|
6947
|
+
fetching: "\u{1F310} Fetching",
|
|
6948
|
+
switching: "\u{1F504} Switching mode",
|
|
6949
|
+
working: "\u{1F6E0}\uFE0F Working",
|
|
6950
|
+
failed: "\u26A0\uFE0F Tool failed",
|
|
6951
|
+
replying: "\u270D\uFE0F Replying"
|
|
6952
|
+
};
|
|
6953
|
+
var DINGTALK_ZH_PRESENTATION_PHASE_LABELS = {
|
|
6954
|
+
thinking: "\u{1F914} \u601D\u8003\u4E2D",
|
|
6955
|
+
reading: "\u{1F4D6} \u8BFB\u53D6\u4E2D",
|
|
6956
|
+
searching: "\u{1F50E} \u641C\u7D22\u4E2D",
|
|
6957
|
+
running: "\u{1F5A5}\uFE0F \u6267\u884C\u4E2D",
|
|
6958
|
+
editing: "\u{1F6E0}\uFE0F \u7F16\u8F91\u4E2D",
|
|
6959
|
+
deleting: "\u{1F5D1}\uFE0F \u5220\u9664\u4E2D",
|
|
6960
|
+
moving: "\u{1F4E6} \u79FB\u52A8\u4E2D",
|
|
6961
|
+
fetching: "\u{1F310} \u83B7\u53D6\u4E2D",
|
|
6962
|
+
switching: "\u{1F504} \u5207\u6362\u6A21\u5F0F\u4E2D",
|
|
6963
|
+
working: "\u{1F6E0}\uFE0F \u5904\u7406\u4E2D",
|
|
6964
|
+
failed: "\u26A0\uFE0F \u5DE5\u5177\u5931\u8D25",
|
|
6965
|
+
replying: "\u270D\uFE0F \u56DE\u590D\u4E2D"
|
|
6966
|
+
};
|
|
6967
|
+
function isChinesePresentationLanguage(language) {
|
|
6968
|
+
const normalized = language?.trim().toLowerCase().replaceAll("_", "-");
|
|
6969
|
+
return normalized === "zh" || normalized === "zh-cn";
|
|
6970
|
+
}
|
|
6971
|
+
__name(isChinesePresentationLanguage, "isChinesePresentationLanguage");
|
|
6972
|
+
function presentationPhaseLabel(phase, language) {
|
|
6973
|
+
return (isChinesePresentationLanguage(language) ? DINGTALK_ZH_PRESENTATION_PHASE_LABELS : DINGTALK_PRESENTATION_PHASE_LABELS)[phase];
|
|
6974
|
+
}
|
|
6975
|
+
__name(presentationPhaseLabel, "presentationPhaseLabel");
|
|
6976
|
+
function toolPresentationPhase(kind) {
|
|
6977
|
+
switch (kind.trim().toLowerCase()) {
|
|
6978
|
+
case "read":
|
|
6979
|
+
return "reading";
|
|
6980
|
+
case "edit":
|
|
6981
|
+
return "editing";
|
|
6982
|
+
case "delete":
|
|
6983
|
+
return "deleting";
|
|
6984
|
+
case "move":
|
|
6985
|
+
return "moving";
|
|
6986
|
+
case "search":
|
|
6987
|
+
return "searching";
|
|
6988
|
+
case "execute":
|
|
6989
|
+
return "running";
|
|
6990
|
+
case "think":
|
|
6991
|
+
return "thinking";
|
|
6992
|
+
case "fetch":
|
|
6993
|
+
return "fetching";
|
|
6994
|
+
case "switch_mode":
|
|
6995
|
+
return "switching";
|
|
6996
|
+
case "other":
|
|
6997
|
+
return "working";
|
|
6998
|
+
default:
|
|
6999
|
+
if (/read/iu.test(kind))
|
|
7000
|
+
return "reading";
|
|
7001
|
+
if (/search|browser|web/iu.test(kind))
|
|
7002
|
+
return "searching";
|
|
7003
|
+
if (/shell|exec|command|run/iu.test(kind))
|
|
7004
|
+
return "running";
|
|
7005
|
+
if (/edit|write|patch/iu.test(kind))
|
|
7006
|
+
return "editing";
|
|
7007
|
+
return "working";
|
|
7008
|
+
}
|
|
7009
|
+
}
|
|
7010
|
+
__name(toolPresentationPhase, "toolPresentationPhase");
|
|
7011
|
+
function lifecyclePresentationPhase(event) {
|
|
7012
|
+
if (event.type === "text_chunk")
|
|
7013
|
+
return "replying";
|
|
7014
|
+
if (event.type !== "tool_call")
|
|
7015
|
+
return void 0;
|
|
7016
|
+
if (/fail|error/iu.test(event.toolCall.status))
|
|
7017
|
+
return "failed";
|
|
7018
|
+
if (/complete|success/iu.test(event.toolCall.status))
|
|
7019
|
+
return "thinking";
|
|
7020
|
+
return toolPresentationPhase(event.toolCall.kind);
|
|
7021
|
+
}
|
|
7022
|
+
__name(lifecyclePresentationPhase, "lifecyclePresentationPhase");
|
|
7023
|
+
|
|
7024
|
+
// packages/channels/dingtalk/dist/status-card-controller.js
|
|
6936
7025
|
var FLUSH_INTERVAL_MS = 500;
|
|
6937
7026
|
var STATUS_REFRESH_INTERVAL_MS = 1e3;
|
|
6938
7027
|
var CONTENT_SYNC_INTERVAL_SECONDS = 5;
|
|
@@ -6948,6 +7037,23 @@ function boundContent(content) {
|
|
|
6948
7037
|
return `${TRUNCATION_MARKER}${content.slice(content.length - (CONTENT_LIMIT - TRUNCATION_MARKER.length))}`;
|
|
6949
7038
|
}
|
|
6950
7039
|
__name(boundContent, "boundContent");
|
|
7040
|
+
function activeContent(phase, content, language, sourcePrefix) {
|
|
7041
|
+
const label = presentationPhaseLabel(phase, language);
|
|
7042
|
+
const sanitized = sanitizeStreamingImageMarkers(content);
|
|
7043
|
+
const renderedSourcePrefix = sourcePrefix && (sanitized === sourcePrefix || sanitized.startsWith(`${sourcePrefix}
|
|
7044
|
+
|
|
7045
|
+
`)) ? sourcePrefix : void 0;
|
|
7046
|
+
const body = renderedSourcePrefix ? sanitized.slice(renderedSourcePrefix.length + (sanitized.length === renderedSourcePrefix.length ? 0 : 2)) : sanitized;
|
|
7047
|
+
const prefix = [label, renderedSourcePrefix].filter(Boolean).join("\n\n");
|
|
7048
|
+
if (!body)
|
|
7049
|
+
return prefix;
|
|
7050
|
+
const separator = "\n\n";
|
|
7051
|
+
const available = CONTENT_LIMIT - prefix.length - separator.length;
|
|
7052
|
+
if (body.length <= available)
|
|
7053
|
+
return `${prefix}${separator}${body}`;
|
|
7054
|
+
return `${prefix}${separator}${TRUNCATION_MARKER}${body.slice(body.length - (available - TRUNCATION_MARKER.length))}`;
|
|
7055
|
+
}
|
|
7056
|
+
__name(activeContent, "activeContent");
|
|
6951
7057
|
var StatusCardController = class {
|
|
6952
7058
|
static {
|
|
6953
7059
|
__name(this, "StatusCardController");
|
|
@@ -7080,6 +7186,8 @@ var StatusCardController = class {
|
|
|
7080
7186
|
target,
|
|
7081
7187
|
outTrackId,
|
|
7082
7188
|
content: boundContent(initialContent),
|
|
7189
|
+
...segment.sourceLabel ? { sourcePrefix: escapeDingTalkMarkdown(segment.sourceLabel) } : {},
|
|
7190
|
+
phase: "thinking",
|
|
7083
7191
|
startedAt: Date.now(),
|
|
7084
7192
|
lastStatusSecond: 0,
|
|
7085
7193
|
lastContentSyncSecond: 0,
|
|
@@ -7114,6 +7222,20 @@ var StatusCardController = class {
|
|
|
7114
7222
|
complete(segmentId, text, retainedContent) {
|
|
7115
7223
|
return this.finalize(segmentId, boundContent(text), "Completed", false, retainedContent);
|
|
7116
7224
|
}
|
|
7225
|
+
updateRunPhase(runId, phase) {
|
|
7226
|
+
if (this.disposed)
|
|
7227
|
+
return;
|
|
7228
|
+
for (const segmentId of this.segmentIdsByRun.get(runId) ?? []) {
|
|
7229
|
+
const record = this.recordsBySegment.get(segmentId);
|
|
7230
|
+
if (!record || record.terminal || record.streamFailed || record.phase === phase) {
|
|
7231
|
+
continue;
|
|
7232
|
+
}
|
|
7233
|
+
record.phase = phase;
|
|
7234
|
+
record.contentVersion++;
|
|
7235
|
+
record.hasPendingWrite = true;
|
|
7236
|
+
this.scheduleFlush(record);
|
|
7237
|
+
}
|
|
7238
|
+
}
|
|
7117
7239
|
fail(segmentId, error) {
|
|
7118
7240
|
void this.finalize(segmentId, boundContent(error), "Failed", true);
|
|
7119
7241
|
}
|
|
@@ -7169,9 +7291,9 @@ var StatusCardController = class {
|
|
|
7169
7291
|
outTrackId: record.outTrackId,
|
|
7170
7292
|
target,
|
|
7171
7293
|
cardParamMap: {
|
|
7172
|
-
content:
|
|
7294
|
+
content: activeContent(record.phase, record.content, this.options.language, record.sourcePrefix),
|
|
7173
7295
|
flowStatus: 2,
|
|
7174
|
-
statusLine: this.statusLine(record
|
|
7296
|
+
statusLine: this.statusLine(record).text,
|
|
7175
7297
|
hasAction: "true",
|
|
7176
7298
|
stop_action: "true"
|
|
7177
7299
|
}
|
|
@@ -7196,7 +7318,7 @@ var StatusCardController = class {
|
|
|
7196
7318
|
await this.options.client.openOrUpdateStream({
|
|
7197
7319
|
outTrackId: record.outTrackId,
|
|
7198
7320
|
key: "content",
|
|
7199
|
-
content:
|
|
7321
|
+
content: activeContent(record.phase, record.content, this.options.language, record.sourcePrefix),
|
|
7200
7322
|
finalize: false
|
|
7201
7323
|
});
|
|
7202
7324
|
} catch (error) {
|
|
@@ -7245,7 +7367,7 @@ var StatusCardController = class {
|
|
|
7245
7367
|
await this.options.client.openOrUpdateStream({
|
|
7246
7368
|
outTrackId: record.outTrackId,
|
|
7247
7369
|
key: "content",
|
|
7248
|
-
content:
|
|
7370
|
+
content: activeContent(record.phase, record.content, this.options.language, record.sourcePrefix),
|
|
7249
7371
|
finalize: false
|
|
7250
7372
|
});
|
|
7251
7373
|
contentWritten = true;
|
|
@@ -7448,14 +7570,28 @@ var StatusCardController = class {
|
|
|
7448
7570
|
const second = Math.max(0, Math.floor((Date.now() - record.startedAt) / 1e3));
|
|
7449
7571
|
const model = this.options.model?.trim();
|
|
7450
7572
|
return {
|
|
7451
|
-
text: [
|
|
7573
|
+
text: [
|
|
7574
|
+
state ? this.statusStateLabel(state) : void 0,
|
|
7575
|
+
model,
|
|
7576
|
+
`${second}s`
|
|
7577
|
+
].filter(Boolean).join(" \xB7 "),
|
|
7452
7578
|
second
|
|
7453
7579
|
};
|
|
7454
7580
|
}
|
|
7581
|
+
statusStateLabel(state) {
|
|
7582
|
+
if (!isChinesePresentationLanguage(this.options.language))
|
|
7583
|
+
return state;
|
|
7584
|
+
return {
|
|
7585
|
+
Completed: "\u5DF2\u5B8C\u6210",
|
|
7586
|
+
Failed: "\u5DF2\u5931\u8D25",
|
|
7587
|
+
Stopped: "\u5DF2\u7EC8\u6B62",
|
|
7588
|
+
Cancelled: "\u5DF2\u53D6\u6D88"
|
|
7589
|
+
}[state] ?? state;
|
|
7590
|
+
}
|
|
7455
7591
|
async updateRunningStatus(record) {
|
|
7456
7592
|
if (this.disposed || record.terminal || record.streamFailed)
|
|
7457
7593
|
return;
|
|
7458
|
-
const status = this.statusLine(record
|
|
7594
|
+
const status = this.statusLine(record);
|
|
7459
7595
|
if (status.second === record.lastStatusSecond)
|
|
7460
7596
|
return;
|
|
7461
7597
|
const syncContent = status.second - record.lastContentSyncSecond >= CONTENT_SYNC_INTERVAL_SECONDS;
|
|
@@ -7463,7 +7599,9 @@ var StatusCardController = class {
|
|
|
7463
7599
|
await this.options.client.updateInstance({
|
|
7464
7600
|
outTrackId: record.outTrackId,
|
|
7465
7601
|
cardParamMap: {
|
|
7466
|
-
...syncContent ? {
|
|
7602
|
+
...syncContent ? {
|
|
7603
|
+
content: activeContent(record.phase, record.content, this.options.language, record.sourcePrefix)
|
|
7604
|
+
} : {},
|
|
7467
7605
|
statusLine: status.text
|
|
7468
7606
|
}
|
|
7469
7607
|
});
|
|
@@ -7905,6 +8043,12 @@ var DingtalkInteractionPresenter = class {
|
|
|
7905
8043
|
statusCards?.replace(statusContext, target, this.withSourcePrefix(run, ""));
|
|
7906
8044
|
});
|
|
7907
8045
|
}
|
|
8046
|
+
updateStatusCardPhase(runId, phase) {
|
|
8047
|
+
const run = this.runs.get(runId);
|
|
8048
|
+
if (!run || run.terminal)
|
|
8049
|
+
return;
|
|
8050
|
+
void this.enqueue(run, () => this.options.statusCards?.updateRunPhase(runId, phase));
|
|
8051
|
+
}
|
|
7908
8052
|
appendOutput(segment, chunk) {
|
|
7909
8053
|
const run = this.runs.get(segment.runId);
|
|
7910
8054
|
if (!run || run.terminal || run.ownerId !== segment.owner.id || run.target.chatId !== segment.target.chatId || run.target.isGroup !== segment.target.isGroup || !chunk || this.terminalSegmentIds.has(segment.segmentId)) {
|
|
@@ -8005,6 +8149,20 @@ var DingtalkInteractionPresenter = class {
|
|
|
8005
8149
|
return Promise.resolve({ kind: "unsupported" });
|
|
8006
8150
|
return questionCards.present(context, this.cardTarget(context.target));
|
|
8007
8151
|
}
|
|
8152
|
+
terminalCopy() {
|
|
8153
|
+
if (this.options.language !== void 0 && !isChinesePresentationLanguage(this.options.language)) {
|
|
8154
|
+
return {
|
|
8155
|
+
failed: "Processing failed, please try again later.",
|
|
8156
|
+
stopped: "Task stopped",
|
|
8157
|
+
cancelled: "Task cancelled"
|
|
8158
|
+
};
|
|
8159
|
+
}
|
|
8160
|
+
return {
|
|
8161
|
+
failed: "\u672C\u6B21\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002",
|
|
8162
|
+
stopped: "\u4EFB\u52A1\u5DF2\u505C\u6B62",
|
|
8163
|
+
cancelled: "\u4EFB\u52A1\u5DF2\u53D6\u6D88"
|
|
8164
|
+
};
|
|
8165
|
+
}
|
|
8008
8166
|
terminalizeRun(runId, terminal, detail = "") {
|
|
8009
8167
|
const run = this.runs.get(runId);
|
|
8010
8168
|
if (!run || run.terminal)
|
|
@@ -8017,16 +8175,17 @@ var DingtalkInteractionPresenter = class {
|
|
|
8017
8175
|
this.segments.delete(activeSegmentId);
|
|
8018
8176
|
this.addTerminalSegment(activeSegmentId);
|
|
8019
8177
|
}
|
|
8178
|
+
const copy = this.terminalCopy();
|
|
8020
8179
|
const finalization = this.enqueue(run, async () => {
|
|
8021
8180
|
if (terminal === "failed") {
|
|
8022
8181
|
const statusContext = this.ensureStatusContext(run);
|
|
8023
8182
|
this.options.statusCards?.ensure(statusContext, this.cardTarget(statusContext.target));
|
|
8024
|
-
this.options.statusCards?.fail(statusContext.segmentId, this.withSenderPrefix(run,
|
|
8183
|
+
this.options.statusCards?.fail(statusContext.segmentId, this.withSenderPrefix(run, copy.failed));
|
|
8025
8184
|
await this.redeliverCardDeliveredContent(run);
|
|
8026
8185
|
} else if (terminal === "cancelled") {
|
|
8027
8186
|
const statusContext = run.statusContext;
|
|
8028
8187
|
if (statusContext) {
|
|
8029
|
-
this.options.statusCards?.replace(statusContext, this.cardTarget(statusContext.target), this.withSenderPrefix(run, detail === "cancel_command" ?
|
|
8188
|
+
this.options.statusCards?.replace(statusContext, this.cardTarget(statusContext.target), this.withSenderPrefix(run, detail === "cancel_command" ? copy.stopped : copy.cancelled));
|
|
8030
8189
|
}
|
|
8031
8190
|
this.options.statusCards?.cancelRun(runId, detail === "cancel_command" ? "cancel_command" : "dropped");
|
|
8032
8191
|
await this.redeliverCardDeliveredContent(run);
|
|
@@ -8382,12 +8541,21 @@ ${boundedLines.join("\n")}`);
|
|
|
8382
8541
|
}
|
|
8383
8542
|
__name(formatChatRecord, "formatChatRecord");
|
|
8384
8543
|
var DEDUP_TTL_MS = 5 * 60 * 1e3;
|
|
8544
|
+
var BACKGROUND_RESPONSE_AGGREGATION_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
8545
|
+
var BACKGROUND_RESPONSE_AGGREGATION_RETRY_MS = 30 * 1e3;
|
|
8546
|
+
var BACKGROUND_RESPONSE_AGGREGATION_MAX_RETRIES = 3;
|
|
8385
8547
|
var ACK_REACTION_NAME = "\u{1F440}";
|
|
8386
8548
|
var ACK_EMOTION_ID = "2659900";
|
|
8387
8549
|
var ACK_EMOTION_BG_ID = "im_bg_1";
|
|
8550
|
+
var STATUS_EMOTION_ID = "34019";
|
|
8551
|
+
var STATUS_EMOTION_BG_ID = "im_bg_6";
|
|
8552
|
+
var DONE_EMOTION_ID = "54054";
|
|
8553
|
+
var DONE_EMOTION_BG_ID = "im_bg_5";
|
|
8388
8554
|
var EMOTION_API = "https://api.dingtalk.com/v1.0/robot/emotion";
|
|
8389
8555
|
var EMOTION_MAX_ATTEMPTS = 3;
|
|
8390
8556
|
var EMOTION_RETRY_BASE_DELAY_MS = 250;
|
|
8557
|
+
var EMOTION_FETCH_TIMEOUT_MS = 15e3;
|
|
8558
|
+
var EMOTION_FINISH_MAX_ATTEMPTS = 3;
|
|
8391
8559
|
var GROUP_MSG_API = "https://api.dingtalk.com/v1.0/robot/groupMessages/send";
|
|
8392
8560
|
var DIRECT_MSG_API = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend";
|
|
8393
8561
|
var PROACTIVE_MSG_KEY = "sampleMarkdown";
|
|
@@ -8515,6 +8683,26 @@ var FILE_INSTRUCTIONS = [
|
|
|
8515
8683
|
"File paths containing ] are not supported.",
|
|
8516
8684
|
"Do not claim delivery succeeded; DingTalk shows successful files separately and reports failures in the final text."
|
|
8517
8685
|
].join("\n");
|
|
8686
|
+
function statusEmotionTag(name) {
|
|
8687
|
+
return {
|
|
8688
|
+
name,
|
|
8689
|
+
emotionId: STATUS_EMOTION_ID,
|
|
8690
|
+
backgroundId: STATUS_EMOTION_BG_ID
|
|
8691
|
+
};
|
|
8692
|
+
}
|
|
8693
|
+
__name(statusEmotionTag, "statusEmotionTag");
|
|
8694
|
+
var EYE_TAG = {
|
|
8695
|
+
name: ACK_REACTION_NAME,
|
|
8696
|
+
emotionId: ACK_EMOTION_ID,
|
|
8697
|
+
backgroundId: ACK_EMOTION_BG_ID
|
|
8698
|
+
};
|
|
8699
|
+
var DONE_TAG = {
|
|
8700
|
+
name: "\u2705 Done",
|
|
8701
|
+
emotionId: DONE_EMOTION_ID,
|
|
8702
|
+
backgroundId: DONE_EMOTION_BG_ID
|
|
8703
|
+
};
|
|
8704
|
+
var FAILED_TAG = statusEmotionTag("\u274C Failed");
|
|
8705
|
+
var STOPPED_TAG = statusEmotionTag("\u23F9\uFE0F Stopped");
|
|
8518
8706
|
function collectNonBotMentionIds(data) {
|
|
8519
8707
|
if (!Array.isArray(data.atUsers) || typeof data.chatbotUserId !== "string") {
|
|
8520
8708
|
return [];
|
|
@@ -8552,12 +8740,37 @@ async function withConnectLoggingSuppressed(connect) {
|
|
|
8552
8740
|
}
|
|
8553
8741
|
}
|
|
8554
8742
|
__name(withConnectLoggingSuppressed, "withConnectLoggingSuppressed");
|
|
8743
|
+
var ProactiveTextDeliveryError = class extends Error {
|
|
8744
|
+
static {
|
|
8745
|
+
__name(this, "ProactiveTextDeliveryError");
|
|
8746
|
+
}
|
|
8747
|
+
plan;
|
|
8748
|
+
retryable;
|
|
8749
|
+
constructor(plan, cause) {
|
|
8750
|
+
super(cause instanceof Error ? cause.message : String(cause), { cause });
|
|
8751
|
+
this.plan = plan;
|
|
8752
|
+
if (cause instanceof DingtalkCardRequestError) {
|
|
8753
|
+
this.retryable = cause.retryable;
|
|
8754
|
+
}
|
|
8755
|
+
}
|
|
8756
|
+
};
|
|
8757
|
+
var ReplyTextDeliveryError = class extends Error {
|
|
8758
|
+
static {
|
|
8759
|
+
__name(this, "ReplyTextDeliveryError");
|
|
8760
|
+
}
|
|
8761
|
+
plan;
|
|
8762
|
+
constructor(plan, cause) {
|
|
8763
|
+
super(cause instanceof Error ? cause.message : String(cause), { cause });
|
|
8764
|
+
this.plan = plan;
|
|
8765
|
+
}
|
|
8766
|
+
};
|
|
8555
8767
|
var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
8556
8768
|
static {
|
|
8557
8769
|
__name(this, "DingtalkChannel");
|
|
8558
8770
|
}
|
|
8559
8771
|
client;
|
|
8560
8772
|
atSender;
|
|
8773
|
+
displayLanguage;
|
|
8561
8774
|
connectionManager;
|
|
8562
8775
|
seenMessages = /* @__PURE__ */ new Map();
|
|
8563
8776
|
mentionTargets = /* @__PURE__ */ new Map();
|
|
@@ -8568,8 +8781,11 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8568
8781
|
/** Map conversationId → latest sessionWebhook URL for sending replies. */
|
|
8569
8782
|
webhooks = /* @__PURE__ */ new Map();
|
|
8570
8783
|
activeReactionKeys = /* @__PURE__ */ new Set();
|
|
8784
|
+
reactionStates = /* @__PURE__ */ new Map();
|
|
8571
8785
|
/** sessionId → reaction keys, so a dead session's reactions can be recalled. */
|
|
8572
8786
|
sessionReactionKeys = /* @__PURE__ */ new Map();
|
|
8787
|
+
/** Settles when the reaction cleanup queued by disconnect() has run. */
|
|
8788
|
+
disconnectDrain;
|
|
8573
8789
|
/**
|
|
8574
8790
|
* Real inbound message ids (insertion-ordered, size-capped). Unlike the
|
|
8575
8791
|
* TTL-swept seenMessages dedup map, entries survive long queue waits, so a
|
|
@@ -8582,6 +8798,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8582
8798
|
*/
|
|
8583
8799
|
proactiveToken;
|
|
8584
8800
|
interactiveCardConfig;
|
|
8801
|
+
aggregateBackgroundAgentResponses;
|
|
8585
8802
|
interactiveCardClient;
|
|
8586
8803
|
statusCardController;
|
|
8587
8804
|
questionCardController;
|
|
@@ -8601,9 +8818,14 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8601
8818
|
// must be dropped, because recreating state would post the tail of a
|
|
8602
8819
|
// force-split [FILE: ...] marker verbatim.
|
|
8603
8820
|
blockProjectionArmed = /* @__PURE__ */ new Set();
|
|
8821
|
+
backgroundResponseAggregations = /* @__PURE__ */ new Map();
|
|
8822
|
+
detachedBackgroundResponseAggregations = /* @__PURE__ */ new Set();
|
|
8823
|
+
pendingBackgroundResponseTerminals = /* @__PURE__ */ new Map();
|
|
8824
|
+
detachedPendingBackgroundResponseTerminals = /* @__PURE__ */ new Set();
|
|
8604
8825
|
constructor(name, config, bridge, options) {
|
|
8605
8826
|
super(name, config, bridge, options);
|
|
8606
8827
|
this.atSender = config["atSender"] === true;
|
|
8828
|
+
this.displayLanguage = options?.displayLanguage;
|
|
8607
8829
|
if (!this.config.instructions) {
|
|
8608
8830
|
this.config.instructions = [
|
|
8609
8831
|
"## DingTalk Channel",
|
|
@@ -8618,6 +8840,11 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8618
8840
|
this.config.instructions += FILE_INSTRUCTIONS;
|
|
8619
8841
|
}
|
|
8620
8842
|
this.interactiveCardConfig = parseDingtalkInteractiveCardConfig(config.interactiveCards);
|
|
8843
|
+
const rawAggregateBackgroundAgentResponses = config.aggregateBackgroundAgentResponses;
|
|
8844
|
+
if (rawAggregateBackgroundAgentResponses !== void 0 && typeof rawAggregateBackgroundAgentResponses !== "boolean") {
|
|
8845
|
+
throw new Error(`Channel "${name}" aggregateBackgroundAgentResponses must be a boolean.`);
|
|
8846
|
+
}
|
|
8847
|
+
this.aggregateBackgroundAgentResponses = rawAggregateBackgroundAgentResponses === true;
|
|
8621
8848
|
if (!config.clientId || !config.clientSecret) {
|
|
8622
8849
|
throw new Error(`Channel "${name}" requires clientId and clientSecret for DingTalk.`);
|
|
8623
8850
|
}
|
|
@@ -8642,6 +8869,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8642
8869
|
client: this.interactiveCardClient,
|
|
8643
8870
|
cancelRun: /* @__PURE__ */ __name((sessionId, runId) => this.requestPromptRunCancellation(sessionId, runId), "cancelRun"),
|
|
8644
8871
|
...config.model ? { model: config.model } : {},
|
|
8872
|
+
...options?.displayLanguage ? { language: options.displayLanguage } : {},
|
|
8645
8873
|
onError: /* @__PURE__ */ __name((operation, error) => {
|
|
8646
8874
|
process.stderr.write(`[DingTalk:${this.name}] ${operation} failed: ${sanitizeLogText(String(error), 300)}
|
|
8647
8875
|
`);
|
|
@@ -8664,6 +8892,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
8664
8892
|
this.interactionPresenter = new DingtalkInteractionPresenter({
|
|
8665
8893
|
statusCards: this.statusCardController,
|
|
8666
8894
|
questionCards: this.questionCardController,
|
|
8895
|
+
...options?.displayLanguage ? { language: options.displayLanguage } : {},
|
|
8667
8896
|
...config.blockStreaming !== "on" ? {
|
|
8668
8897
|
sendFallback: /* @__PURE__ */ __name((chatId, text, sessionId, sourceLabel) => this.sendFallbackReply(chatId, text, sessionId, sourceLabel), "sendFallback")
|
|
8669
8898
|
} : {}
|
|
@@ -9015,16 +9244,27 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9015
9244
|
}
|
|
9016
9245
|
return replaceImageMarkers(text, markers, replacements);
|
|
9017
9246
|
}
|
|
9018
|
-
async sendReply(chatId, text, atUserId, sourceLabel, prepared = false) {
|
|
9247
|
+
async sendReply(chatId, text, atUserId, sourceLabel, prepared = false, failOnHttpError = false) {
|
|
9019
9248
|
const webhook = this.webhooks.get(chatId);
|
|
9020
9249
|
if (!webhook) {
|
|
9021
9250
|
process.stderr.write(`[DingTalk:${this.name}] No webhook for chatId ${chatId}, cannot send.
|
|
9022
9251
|
`);
|
|
9252
|
+
if (failOnHttpError) {
|
|
9253
|
+
throw new Error("DingTalk session webhook unavailable");
|
|
9254
|
+
}
|
|
9023
9255
|
return;
|
|
9024
9256
|
}
|
|
9025
9257
|
const outgoingText = prepared ? text : await this.prepareReplyOutput(chatId, text);
|
|
9026
9258
|
if (!outgoingText.trim())
|
|
9027
9259
|
return;
|
|
9260
|
+
const plan = this.createReplyTextDelivery(outgoingText, atUserId, sourceLabel);
|
|
9261
|
+
try {
|
|
9262
|
+
await this.deliverReplyText(chatId, plan, failOnHttpError);
|
|
9263
|
+
} catch (error) {
|
|
9264
|
+
throw new ReplyTextDeliveryError(plan, error);
|
|
9265
|
+
}
|
|
9266
|
+
}
|
|
9267
|
+
createReplyTextDelivery(outgoingText, atUserId, sourceLabel) {
|
|
9028
9268
|
const mentionPrefix = atUserId ? `@${atUserId}
|
|
9029
9269
|
|
|
9030
9270
|
` : "";
|
|
@@ -9036,17 +9276,32 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9036
9276
|
throw new Error("DingTalk source label exceeds the message limit.");
|
|
9037
9277
|
}
|
|
9038
9278
|
const chunks = normalizeDingTalkMarkdown(outgoingText, contentLimit).map((chunk, index) => `${index === 0 ? mentionPrefix : ""}${sourcePrefix}${chunk}`);
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9279
|
+
return {
|
|
9280
|
+
title: extractTitle(outgoingText),
|
|
9281
|
+
chunks,
|
|
9282
|
+
nextChunk: 0,
|
|
9283
|
+
...atUserId ? { atUserId } : {}
|
|
9284
|
+
};
|
|
9285
|
+
}
|
|
9286
|
+
async deliverReplyText(chatId, plan, failOnHttpError = false) {
|
|
9287
|
+
const webhook = this.webhooks.get(chatId);
|
|
9288
|
+
if (!webhook) {
|
|
9289
|
+
if (failOnHttpError) {
|
|
9290
|
+
throw new Error("DingTalk session webhook unavailable");
|
|
9291
|
+
}
|
|
9292
|
+
return;
|
|
9293
|
+
}
|
|
9294
|
+
while (plan.nextChunk < plan.chunks.length) {
|
|
9295
|
+
const index = plan.nextChunk;
|
|
9296
|
+
const chunk = plan.chunks[index];
|
|
9297
|
+
const isMention = index === 0 && plan.atUserId !== void 0;
|
|
9043
9298
|
const body = {
|
|
9044
9299
|
msgtype: "markdown",
|
|
9045
9300
|
markdown: {
|
|
9046
|
-
title:
|
|
9301
|
+
title: index === 0 ? plan.title : `${plan.title} (cont.)`,
|
|
9047
9302
|
text: chunk
|
|
9048
9303
|
},
|
|
9049
|
-
...isMention ? { at: { atUserIds: [atUserId] } } : {}
|
|
9304
|
+
...isMention ? { at: { atUserIds: [plan.atUserId] } } : {}
|
|
9050
9305
|
};
|
|
9051
9306
|
let resp;
|
|
9052
9307
|
try {
|
|
@@ -9073,7 +9328,21 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9073
9328
|
const detail = await resp.text().catch(() => "");
|
|
9074
9329
|
process.stderr.write(`[DingTalk:${this.name}] sendMessage failed: HTTP ${resp.status} ${detail}
|
|
9075
9330
|
`);
|
|
9331
|
+
if (failOnHttpError) {
|
|
9332
|
+
throw new Error(`DingTalk reply send failed: HTTP ${resp.status} ${detail}`);
|
|
9333
|
+
}
|
|
9334
|
+
} else if (failOnHttpError) {
|
|
9335
|
+
const payload = await resp.clone().json().catch(() => void 0);
|
|
9336
|
+
const response = payload && typeof payload === "object" ? payload : void 0;
|
|
9337
|
+
const value = response?.["errcode"] ?? response?.["code"];
|
|
9338
|
+
if (value !== void 0 && String(value) !== "0") {
|
|
9339
|
+
const detail = sanitizeLogText(String(response?.["errmsg"] ?? response?.["message"] ?? value), 300);
|
|
9340
|
+
process.stderr.write(`[DingTalk:${this.name}] sendMessage failed: ${detail}
|
|
9341
|
+
`);
|
|
9342
|
+
throw new Error(`DingTalk reply send failed: ${detail}`);
|
|
9343
|
+
}
|
|
9076
9344
|
}
|
|
9345
|
+
plan.nextChunk++;
|
|
9077
9346
|
}
|
|
9078
9347
|
}
|
|
9079
9348
|
async sendMessage(chatId, text) {
|
|
@@ -9103,9 +9372,19 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9103
9372
|
async pushProactive(target, text, sourceLabel) {
|
|
9104
9373
|
if (!text.trim())
|
|
9105
9374
|
return;
|
|
9375
|
+
const plan = await this.createProactiveTextDelivery(target, text, sourceLabel);
|
|
9376
|
+
if (!plan)
|
|
9377
|
+
return;
|
|
9378
|
+
try {
|
|
9379
|
+
await this.deliverProactiveText(target, plan);
|
|
9380
|
+
} catch (error) {
|
|
9381
|
+
throw new ProactiveTextDeliveryError(plan, error);
|
|
9382
|
+
}
|
|
9383
|
+
}
|
|
9384
|
+
async createProactiveTextDelivery(target, text, sourceLabel) {
|
|
9106
9385
|
const outgoingText = await this.prepareFileOutput(text, (file, mediaId) => this.sendProactiveFile(target, file, mediaId));
|
|
9107
9386
|
if (!outgoingText.trim())
|
|
9108
|
-
return;
|
|
9387
|
+
return void 0;
|
|
9109
9388
|
const sourcePrefix = sourceLabel ? `${escapeDingTalkMarkdown(sourceLabel)}
|
|
9110
9389
|
|
|
9111
9390
|
` : "";
|
|
@@ -9114,9 +9393,13 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9114
9393
|
throw new Error("DingTalk source label exceeds the message limit.");
|
|
9115
9394
|
}
|
|
9116
9395
|
const chunks = normalizeDingTalkMarkdown(outgoingText, contentLimit).map((chunk) => `${sourcePrefix}${chunk}`);
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9396
|
+
return { title: extractTitle(outgoingText), chunks, nextChunk: 0 };
|
|
9397
|
+
}
|
|
9398
|
+
async deliverProactiveText(target, plan) {
|
|
9399
|
+
while (plan.nextChunk < plan.chunks.length) {
|
|
9400
|
+
const index = plan.nextChunk;
|
|
9401
|
+
await this.sendProactiveChunk(target, index === 0 ? plan.title : `${plan.title} (cont.)`, plan.chunks[index], `chunk ${index + 1}/${plan.chunks.length}`);
|
|
9402
|
+
plan.nextChunk++;
|
|
9120
9403
|
}
|
|
9121
9404
|
}
|
|
9122
9405
|
async getProactiveToken() {
|
|
@@ -9260,14 +9543,14 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9260
9543
|
getAccessToken() {
|
|
9261
9544
|
return this.client.getConfig().access_token;
|
|
9262
9545
|
}
|
|
9263
|
-
async emotionApi(endpoint, msgId, conversationId) {
|
|
9546
|
+
async emotionApi(endpoint, msgId, conversationId, tag) {
|
|
9264
9547
|
const robotCode = this.config.clientId;
|
|
9265
9548
|
if (!robotCode || !msgId || !conversationId)
|
|
9266
|
-
return;
|
|
9549
|
+
return false;
|
|
9267
9550
|
try {
|
|
9268
9551
|
const token = this.config.clientSecret ? await this.getProactiveToken() : this.getAccessToken();
|
|
9269
9552
|
if (!token)
|
|
9270
|
-
return;
|
|
9553
|
+
return false;
|
|
9271
9554
|
for (let attempt = 0; attempt < EMOTION_MAX_ATTEMPTS; attempt++) {
|
|
9272
9555
|
const resp = await fetch(`${EMOTION_API}/${endpoint}`, {
|
|
9273
9556
|
method: "POST",
|
|
@@ -9280,17 +9563,18 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9280
9563
|
openMsgId: msgId,
|
|
9281
9564
|
openConversationId: conversationId,
|
|
9282
9565
|
emotionType: 2,
|
|
9283
|
-
emotionName:
|
|
9566
|
+
emotionName: tag.name,
|
|
9284
9567
|
textEmotion: {
|
|
9285
|
-
emotionId:
|
|
9286
|
-
emotionName:
|
|
9287
|
-
text:
|
|
9288
|
-
backgroundId:
|
|
9568
|
+
emotionId: tag.emotionId,
|
|
9569
|
+
emotionName: tag.name,
|
|
9570
|
+
text: tag.name,
|
|
9571
|
+
backgroundId: tag.backgroundId
|
|
9289
9572
|
}
|
|
9290
|
-
})
|
|
9573
|
+
}),
|
|
9574
|
+
signal: AbortSignal.timeout(EMOTION_FETCH_TIMEOUT_MS)
|
|
9291
9575
|
});
|
|
9292
9576
|
if (resp.ok)
|
|
9293
|
-
return;
|
|
9577
|
+
return true;
|
|
9294
9578
|
const isTransient = resp.status === 429 || resp.status >= 500;
|
|
9295
9579
|
if (isTransient && attempt < EMOTION_MAX_ATTEMPTS - 1) {
|
|
9296
9580
|
await resp.body?.cancel();
|
|
@@ -9300,24 +9584,31 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9300
9584
|
const detail = sanitizeLogText(await resp.text().catch(() => ""), 500);
|
|
9301
9585
|
process.stderr.write(`[DingTalk:${this.name}] emotion/${endpoint} failed after ${attempt + 1}/${EMOTION_MAX_ATTEMPTS} attempts: ${resp.status} ${detail}
|
|
9302
9586
|
`);
|
|
9303
|
-
return;
|
|
9587
|
+
return false;
|
|
9304
9588
|
}
|
|
9305
9589
|
} catch {
|
|
9306
9590
|
}
|
|
9591
|
+
return false;
|
|
9307
9592
|
}
|
|
9308
|
-
async attachReaction(msgId, conversationId) {
|
|
9309
|
-
|
|
9593
|
+
async attachReaction(msgId, conversationId, tag = EYE_TAG) {
|
|
9594
|
+
return this.emotionApi("reply", msgId, conversationId, tag);
|
|
9310
9595
|
}
|
|
9311
|
-
async recallReaction(msgId, conversationId) {
|
|
9312
|
-
|
|
9596
|
+
async recallReaction(msgId, conversationId, tag = EYE_TAG) {
|
|
9597
|
+
return this.emotionApi("recall", msgId, conversationId, tag);
|
|
9313
9598
|
}
|
|
9314
9599
|
disconnect() {
|
|
9315
9600
|
if (this.dedupTimer) {
|
|
9316
9601
|
clearInterval(this.dedupTimer);
|
|
9317
9602
|
}
|
|
9603
|
+
const reactionStates = [...this.reactionStates.values()];
|
|
9604
|
+
for (const state of reactionStates) {
|
|
9605
|
+
this.finishReaction(state.chatId, state.messageId, state.sessionId);
|
|
9606
|
+
}
|
|
9318
9607
|
this.statusCardController?.dispose();
|
|
9608
|
+
this.drainBackgroundResponseAggregations();
|
|
9319
9609
|
this.activeReactionKeys.clear();
|
|
9320
9610
|
this.sessionReactionKeys.clear();
|
|
9611
|
+
this.reactionStates.clear();
|
|
9321
9612
|
if (this.connectionManager) {
|
|
9322
9613
|
this.connectionManager.stop();
|
|
9323
9614
|
} else {
|
|
@@ -9325,6 +9616,10 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9325
9616
|
}
|
|
9326
9617
|
process.stderr.write(`[DingTalk:${this.name}] Disconnected.
|
|
9327
9618
|
`);
|
|
9619
|
+
this.disconnectDrain = Promise.allSettled(reactionStates.map((state) => state.tail)).then(() => void 0);
|
|
9620
|
+
}
|
|
9621
|
+
waitForDisconnect() {
|
|
9622
|
+
return this.disconnectDrain ?? Promise.resolve();
|
|
9328
9623
|
}
|
|
9329
9624
|
/** Stable API targets are conversation or user IDs, never webhook URLs. */
|
|
9330
9625
|
isStableTargetId(chatId) {
|
|
@@ -9333,6 +9628,111 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9333
9628
|
reactionKey(messageId, conversationId) {
|
|
9334
9629
|
return `${conversationId}:${messageId}`;
|
|
9335
9630
|
}
|
|
9631
|
+
forgetReactionState(state) {
|
|
9632
|
+
this.activeReactionKeys.delete(state.key);
|
|
9633
|
+
if (this.reactionStates.get(state.key) === state) {
|
|
9634
|
+
this.reactionStates.delete(state.key);
|
|
9635
|
+
}
|
|
9636
|
+
if (!state.sessionId)
|
|
9637
|
+
return;
|
|
9638
|
+
const keys = this.sessionReactionKeys.get(state.sessionId);
|
|
9639
|
+
keys?.delete(state.key);
|
|
9640
|
+
if (keys?.size === 0)
|
|
9641
|
+
this.sessionReactionKeys.delete(state.sessionId);
|
|
9642
|
+
}
|
|
9643
|
+
enqueueReaction(state, operation) {
|
|
9644
|
+
state.tail = state.tail.then(operation).catch((err) => {
|
|
9645
|
+
this.logReactionFailure("lifecycle tag update", err);
|
|
9646
|
+
});
|
|
9647
|
+
}
|
|
9648
|
+
scheduleReactionDrain(state) {
|
|
9649
|
+
if (state.drainScheduled)
|
|
9650
|
+
return;
|
|
9651
|
+
state.drainScheduled = true;
|
|
9652
|
+
this.enqueueReaction(state, async () => {
|
|
9653
|
+
try {
|
|
9654
|
+
await this.drainReactionState(state);
|
|
9655
|
+
} finally {
|
|
9656
|
+
state.drainScheduled = false;
|
|
9657
|
+
if (this.reactionStates.get(state.key) === state && (state.finishing ? !state.finishBlocked : this.activeReactionKeys.has(state.key) && state.desiredStatusTag && state.desiredStatusTag.name !== state.statusTag?.name)) {
|
|
9658
|
+
this.scheduleReactionDrain(state);
|
|
9659
|
+
}
|
|
9660
|
+
}
|
|
9661
|
+
});
|
|
9662
|
+
}
|
|
9663
|
+
async drainReactionState(state) {
|
|
9664
|
+
while (true) {
|
|
9665
|
+
if (state.finishing) {
|
|
9666
|
+
await this.finishReactionState(state);
|
|
9667
|
+
return;
|
|
9668
|
+
}
|
|
9669
|
+
if (this.reactionStates.get(state.key) !== state || !this.activeReactionKeys.has(state.key)) {
|
|
9670
|
+
return;
|
|
9671
|
+
}
|
|
9672
|
+
const desired = state.desiredStatusTag;
|
|
9673
|
+
if (!desired || desired.name === state.statusTag?.name)
|
|
9674
|
+
return;
|
|
9675
|
+
const latched = state.failedTransition;
|
|
9676
|
+
if (state.statusTag) {
|
|
9677
|
+
const from = state.statusTag.name;
|
|
9678
|
+
if (latched && latched.from === from && latched.to === desired.name) {
|
|
9679
|
+
state.desiredStatusTag = state.statusTag;
|
|
9680
|
+
return;
|
|
9681
|
+
}
|
|
9682
|
+
const revision2 = state.revision;
|
|
9683
|
+
if (await this.recallReaction(state.messageId, state.chatId, state.statusTag) === false) {
|
|
9684
|
+
state.failedTransition = { from, to: desired.name };
|
|
9685
|
+
if (state.revision !== revision2)
|
|
9686
|
+
continue;
|
|
9687
|
+
state.desiredStatusTag = state.statusTag;
|
|
9688
|
+
return;
|
|
9689
|
+
}
|
|
9690
|
+
state.failedTransition = void 0;
|
|
9691
|
+
state.statusTag = void 0;
|
|
9692
|
+
continue;
|
|
9693
|
+
}
|
|
9694
|
+
if (latched && latched.from === void 0 && latched.to === desired.name) {
|
|
9695
|
+
state.desiredStatusTag = void 0;
|
|
9696
|
+
return;
|
|
9697
|
+
}
|
|
9698
|
+
const revision = state.revision;
|
|
9699
|
+
if (await this.attachReaction(state.messageId, state.chatId, desired) === false) {
|
|
9700
|
+
state.failedTransition = { from: void 0, to: desired.name };
|
|
9701
|
+
if (state.revision !== revision)
|
|
9702
|
+
continue;
|
|
9703
|
+
state.desiredStatusTag = void 0;
|
|
9704
|
+
return;
|
|
9705
|
+
}
|
|
9706
|
+
state.failedTransition = void 0;
|
|
9707
|
+
state.statusTag = desired;
|
|
9708
|
+
}
|
|
9709
|
+
}
|
|
9710
|
+
async finishReactionState(state) {
|
|
9711
|
+
let statusCleared = true;
|
|
9712
|
+
if (state.statusTag) {
|
|
9713
|
+
statusCleared = await this.recallReaction(state.messageId, state.chatId, state.statusTag) !== false;
|
|
9714
|
+
if (statusCleared)
|
|
9715
|
+
state.statusTag = void 0;
|
|
9716
|
+
}
|
|
9717
|
+
const eyeCleared = !state.eyeAttached || await this.recallReaction(state.messageId, state.chatId, EYE_TAG) !== false;
|
|
9718
|
+
if (eyeCleared)
|
|
9719
|
+
state.eyeAttached = false;
|
|
9720
|
+
let terminalAttached = true;
|
|
9721
|
+
if (state.terminalTag && statusCleared && eyeCleared) {
|
|
9722
|
+
terminalAttached = await this.attachReaction(state.messageId, state.chatId, state.terminalTag) !== false;
|
|
9723
|
+
}
|
|
9724
|
+
if (!statusCleared || !eyeCleared || !terminalAttached) {
|
|
9725
|
+
state.finishAttempts = (state.finishAttempts ?? 0) + 1;
|
|
9726
|
+
if (state.finishAttempts >= EMOTION_FINISH_MAX_ATTEMPTS) {
|
|
9727
|
+
this.logReactionFailure("reaction cleanup", `abandoned after ${state.finishAttempts} attempts`);
|
|
9728
|
+
this.forgetReactionState(state);
|
|
9729
|
+
return;
|
|
9730
|
+
}
|
|
9731
|
+
state.finishBlocked = true;
|
|
9732
|
+
return;
|
|
9733
|
+
}
|
|
9734
|
+
this.forgetReactionState(state);
|
|
9735
|
+
}
|
|
9336
9736
|
rememberInboundMessageId(msgId) {
|
|
9337
9737
|
this.inboundMessageIds.delete(msgId);
|
|
9338
9738
|
this.inboundMessageIds.add(msgId);
|
|
@@ -9355,6 +9755,19 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9355
9755
|
if (this.activeReactionKeys.has(key))
|
|
9356
9756
|
return;
|
|
9357
9757
|
this.activeReactionKeys.add(key);
|
|
9758
|
+
const state = {
|
|
9759
|
+
key,
|
|
9760
|
+
messageId,
|
|
9761
|
+
chatId,
|
|
9762
|
+
...sessionId ? { sessionId } : {},
|
|
9763
|
+
desiredStatusTag: this.phaseReactionTag("thinking"),
|
|
9764
|
+
finishing: false,
|
|
9765
|
+
drainScheduled: false,
|
|
9766
|
+
eyeAttached: false,
|
|
9767
|
+
revision: 0,
|
|
9768
|
+
tail: Promise.resolve()
|
|
9769
|
+
};
|
|
9770
|
+
this.reactionStates.set(key, state);
|
|
9358
9771
|
if (sessionId) {
|
|
9359
9772
|
let keys = this.sessionReactionKeys.get(sessionId);
|
|
9360
9773
|
if (!keys) {
|
|
@@ -9363,34 +9776,68 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9363
9776
|
}
|
|
9364
9777
|
keys.set(key, { messageId, chatId });
|
|
9365
9778
|
}
|
|
9366
|
-
this.
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
this.
|
|
9370
|
-
|
|
9779
|
+
this.enqueueReaction(state, async () => {
|
|
9780
|
+
try {
|
|
9781
|
+
if (await this.attachReaction(messageId, chatId, EYE_TAG) === false) {
|
|
9782
|
+
this.forgetReactionState(state);
|
|
9783
|
+
return;
|
|
9784
|
+
}
|
|
9785
|
+
state.eyeAttached = true;
|
|
9786
|
+
this.scheduleReactionDrain(state);
|
|
9787
|
+
} catch (err) {
|
|
9788
|
+
this.forgetReactionState(state);
|
|
9789
|
+
this.logReactionFailure("reaction attach", err);
|
|
9371
9790
|
}
|
|
9372
|
-
}).catch((err) => {
|
|
9373
|
-
this.activeReactionKeys.delete(key);
|
|
9374
|
-
this.logReactionFailure("reaction attach", err);
|
|
9375
9791
|
});
|
|
9376
9792
|
}
|
|
9377
|
-
|
|
9793
|
+
replaceStatusReaction(chatId, messageId, tag) {
|
|
9794
|
+
if (!messageId)
|
|
9795
|
+
return;
|
|
9796
|
+
const state = this.reactionStates.get(this.reactionKey(messageId, chatId));
|
|
9797
|
+
if (!state || !this.activeReactionKeys.has(state.key))
|
|
9798
|
+
return;
|
|
9799
|
+
state.desiredStatusTag = tag;
|
|
9800
|
+
state.revision++;
|
|
9801
|
+
this.scheduleReactionDrain(state);
|
|
9802
|
+
}
|
|
9803
|
+
phaseReactionTag(phase) {
|
|
9804
|
+
return statusEmotionTag(presentationPhaseLabel(phase, this.displayLanguage));
|
|
9805
|
+
}
|
|
9806
|
+
terminalReactionTag(type) {
|
|
9807
|
+
if (!isChinesePresentationLanguage(this.displayLanguage)) {
|
|
9808
|
+
return type === "completed" ? DONE_TAG : type === "failed" ? FAILED_TAG : STOPPED_TAG;
|
|
9809
|
+
}
|
|
9810
|
+
if (type === "completed") {
|
|
9811
|
+
return { ...DONE_TAG, name: "\u2705 \u5DF2\u5B8C\u6210" };
|
|
9812
|
+
}
|
|
9813
|
+
return statusEmotionTag(type === "failed" ? "\u274C \u5931\u8D25" : "\u23F9\uFE0F \u5DF2\u505C\u6B62");
|
|
9814
|
+
}
|
|
9815
|
+
finishReaction(chatId, messageId, sessionId, terminalTag) {
|
|
9378
9816
|
if (!messageId || !this.isStableTargetId(chatId))
|
|
9379
9817
|
return;
|
|
9380
9818
|
const key = this.reactionKey(messageId, chatId);
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9385
|
-
|
|
9386
|
-
|
|
9387
|
-
|
|
9819
|
+
const state = this.reactionStates.get(key);
|
|
9820
|
+
if (!state)
|
|
9821
|
+
return;
|
|
9822
|
+
if (state.finishing) {
|
|
9823
|
+
if (!state.finishBlocked)
|
|
9824
|
+
return;
|
|
9825
|
+
state.finishBlocked = false;
|
|
9826
|
+
if (terminalTag)
|
|
9827
|
+
state.terminalTag = terminalTag;
|
|
9828
|
+
this.scheduleReactionDrain(state);
|
|
9829
|
+
return;
|
|
9388
9830
|
}
|
|
9389
9831
|
if (!this.activeReactionKeys.delete(key))
|
|
9390
9832
|
return;
|
|
9391
|
-
|
|
9392
|
-
|
|
9393
|
-
|
|
9833
|
+
state.finishing = true;
|
|
9834
|
+
state.desiredStatusTag = void 0;
|
|
9835
|
+
state.terminalTag = terminalTag;
|
|
9836
|
+
state.revision++;
|
|
9837
|
+
this.scheduleReactionDrain(state);
|
|
9838
|
+
}
|
|
9839
|
+
stopReaction(chatId, messageId, sessionId) {
|
|
9840
|
+
this.finishReaction(chatId, messageId, sessionId);
|
|
9394
9841
|
}
|
|
9395
9842
|
/** Recall reactions left behind when a session dies without terminal lifecycle events. */
|
|
9396
9843
|
onSessionDied(sessionId) {
|
|
@@ -9409,6 +9856,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9409
9856
|
}
|
|
9410
9857
|
}
|
|
9411
9858
|
this.sessionMentionTargets.delete(sessionId);
|
|
9859
|
+
this.drainBackgroundResponseAggregations(sessionId);
|
|
9412
9860
|
const cardRunId = this.cardRunBySession.get(sessionId);
|
|
9413
9861
|
if (cardRunId) {
|
|
9414
9862
|
this.cardRunBySession.delete(sessionId);
|
|
@@ -9418,16 +9866,35 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9418
9866
|
const keys = this.sessionReactionKeys.get(sessionId);
|
|
9419
9867
|
if (keys) {
|
|
9420
9868
|
this.sessionReactionKeys.delete(sessionId);
|
|
9421
|
-
for (const
|
|
9422
|
-
|
|
9423
|
-
void this.recallReaction(messageId, chatId).catch((err) => {
|
|
9424
|
-
this.logReactionFailure("session-death reaction recall", err);
|
|
9425
|
-
});
|
|
9426
|
-
}
|
|
9869
|
+
for (const { messageId, chatId } of keys.values()) {
|
|
9870
|
+
this.finishReaction(chatId, messageId, sessionId);
|
|
9427
9871
|
}
|
|
9428
9872
|
}
|
|
9429
9873
|
super.onSessionDied(sessionId);
|
|
9430
9874
|
}
|
|
9875
|
+
/**
|
|
9876
|
+
* A crashed standalone bridge never settles its in-flight turns, so their
|
|
9877
|
+
* transient tags and ticking status cards would otherwise assert a live
|
|
9878
|
+
* turn forever. Finish the tags without a terminal result and terminalize
|
|
9879
|
+
* the cards as interrupted. Session state stays: crash recovery restores
|
|
9880
|
+
* the sessions on a fresh bridge.
|
|
9881
|
+
*/
|
|
9882
|
+
onBridgeDisconnected() {
|
|
9883
|
+
for (const [sessionId, keys] of this.sessionReactionKeys) {
|
|
9884
|
+
this.sessionReactionKeys.delete(sessionId);
|
|
9885
|
+
for (const { messageId, chatId } of keys.values()) {
|
|
9886
|
+
this.finishReaction(chatId, messageId, sessionId);
|
|
9887
|
+
}
|
|
9888
|
+
}
|
|
9889
|
+
for (const [sessionId, runId] of this.cardRunBySession) {
|
|
9890
|
+
this.cardRunBySession.delete(sessionId);
|
|
9891
|
+
this.interactionPresenter?.terminalizeRun(runId, "cancelled");
|
|
9892
|
+
this.cardRuns.delete(runId);
|
|
9893
|
+
}
|
|
9894
|
+
}
|
|
9895
|
+
onSessionRetiring(sessionId) {
|
|
9896
|
+
this.drainBackgroundResponseAggregations(sessionId);
|
|
9897
|
+
}
|
|
9431
9898
|
onTaskLifecycle(event) {
|
|
9432
9899
|
if (event.type === "started") {
|
|
9433
9900
|
this.startReaction(event.chatId, event.messageId, event.sessionId);
|
|
@@ -9443,10 +9910,18 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9443
9910
|
}
|
|
9444
9911
|
return;
|
|
9445
9912
|
}
|
|
9913
|
+
const presentationPhase = lifecyclePresentationPhase(event);
|
|
9914
|
+
if (event.runId && presentationPhase) {
|
|
9915
|
+
this.interactionPresenter?.updateStatusCardPhase(event.runId, presentationPhase);
|
|
9916
|
+
}
|
|
9917
|
+
if (presentationPhase) {
|
|
9918
|
+
this.replaceStatusReaction(event.chatId, event.messageId, this.phaseReactionTag(presentationPhase));
|
|
9919
|
+
return;
|
|
9920
|
+
}
|
|
9446
9921
|
if (isTerminalTaskLifecycleType(event.type)) {
|
|
9447
9922
|
if (event.messageId)
|
|
9448
9923
|
this.mentionTargets.delete(event.messageId);
|
|
9449
|
-
this.
|
|
9924
|
+
this.finishReaction(event.chatId, event.messageId, event.sessionId, this.terminalReactionTag(event.type));
|
|
9450
9925
|
if (event.runId) {
|
|
9451
9926
|
this.deleteFileProjectorsForRun(event.runId);
|
|
9452
9927
|
if (event.type === "failed") {
|
|
@@ -9583,18 +10058,569 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9583
10058
|
`);
|
|
9584
10059
|
});
|
|
9585
10060
|
}
|
|
10061
|
+
/** Deliver every Agent segment immediately unless aggregation is enabled. */
|
|
10062
|
+
async dispatchBackgroundResponse(sessionId, text, context) {
|
|
10063
|
+
const target = this.router.getTarget(sessionId);
|
|
10064
|
+
if (!target || target.channelName !== this.name || context !== void 0 && context.kind !== "agent") {
|
|
10065
|
+
return super.dispatchBackgroundResponse(sessionId, text, context);
|
|
10066
|
+
}
|
|
10067
|
+
const canAggregate = this.aggregateBackgroundAgentResponses && context?.kind === "agent" && typeof context.turnComplete === "boolean";
|
|
10068
|
+
if (!canAggregate) {
|
|
10069
|
+
if (text.trim().length === 0) {
|
|
10070
|
+
return super.dispatchBackgroundResponse(sessionId, text, context);
|
|
10071
|
+
}
|
|
10072
|
+
return super.dispatchBackgroundResponse(sessionId, this.formatBackgroundAgentResponse(text, context?.label), context);
|
|
10073
|
+
}
|
|
10074
|
+
const key = JSON.stringify([sessionId, context.taskId, context.turnId]);
|
|
10075
|
+
let current = this.backgroundResponseAggregations.get(key);
|
|
10076
|
+
let parked = this.pendingBackgroundResponseTerminals.get(key);
|
|
10077
|
+
if (current?.turnComplete === true) {
|
|
10078
|
+
this.detachedBackgroundResponseAggregations.add(current);
|
|
10079
|
+
this.backgroundResponseAggregations.delete(key);
|
|
10080
|
+
current = void 0;
|
|
10081
|
+
}
|
|
10082
|
+
if (!current && (parked?.turnEnded === true || parked?.turnComplete === true && (parked.retryTimer || parked.retryInFlight || parked.resolvers > 0))) {
|
|
10083
|
+
if (!parked.turnEnded) {
|
|
10084
|
+
this.detachedPendingBackgroundResponseTerminals.add(parked);
|
|
10085
|
+
}
|
|
10086
|
+
parked = { sessionId, target, resolvers: 0, held: [] };
|
|
10087
|
+
this.pendingBackgroundResponseTerminals.set(key, parked);
|
|
10088
|
+
}
|
|
10089
|
+
if (!current && text.trim().length === 0) {
|
|
10090
|
+
if (!parked || parked.resolvers === 0 && !parked.retryTimer && !parked.retryInFlight && !parked.resolutionDropped && !parked.turnComplete) {
|
|
10091
|
+
if (parked)
|
|
10092
|
+
this.pendingBackgroundResponseTerminals.delete(key);
|
|
10093
|
+
return super.dispatchBackgroundResponse(sessionId, text, context);
|
|
10094
|
+
}
|
|
10095
|
+
if (context.turnComplete) {
|
|
10096
|
+
parked.turnComplete = true;
|
|
10097
|
+
parked.status = context.status;
|
|
10098
|
+
parked.label = context.label ?? parked.label;
|
|
10099
|
+
parked.completionPartial = context.partial === true;
|
|
10100
|
+
if (parked.resolvers === 0 && !parked.retryTimer && !parked.retryInFlight && (parked.retryAttempts ?? 0) >= BACKGROUND_RESPONSE_AGGREGATION_MAX_RETRIES) {
|
|
10101
|
+
parked.turnEnded = true;
|
|
10102
|
+
this.pendingBackgroundResponseTerminals.delete(key);
|
|
10103
|
+
}
|
|
10104
|
+
}
|
|
10105
|
+
return;
|
|
10106
|
+
}
|
|
10107
|
+
if (!current) {
|
|
10108
|
+
parked ??= { sessionId, target, resolvers: 0, held: [] };
|
|
10109
|
+
this.pendingBackgroundResponseTerminals.set(key, parked);
|
|
10110
|
+
this.holdPendingBackgroundResponse(parked, text, context);
|
|
10111
|
+
parked.resolvers++;
|
|
10112
|
+
try {
|
|
10113
|
+
let delivery;
|
|
10114
|
+
try {
|
|
10115
|
+
delivery = await this.resolveBackgroundResponseDelivery(sessionId);
|
|
10116
|
+
} catch (error) {
|
|
10117
|
+
if (parked.resolvers === 1 && !this.backgroundResponseAggregations.has(key)) {
|
|
10118
|
+
this.scheduleBackgroundResponseResolutionRetry(key, sessionId, parked);
|
|
10119
|
+
} else {
|
|
10120
|
+
const existing = this.backgroundResponseAggregations.get(key);
|
|
10121
|
+
if (existing) {
|
|
10122
|
+
if (parked.held.length > 0) {
|
|
10123
|
+
this.applyHeldBackgroundResponses(existing, parked);
|
|
10124
|
+
}
|
|
10125
|
+
this.applyPendingBackgroundResponseTerminal(existing, parked);
|
|
10126
|
+
if (parked.resolvers === 1) {
|
|
10127
|
+
if (existing.turnComplete) {
|
|
10128
|
+
await this.completeBackgroundResponseAggregation(key, existing);
|
|
10129
|
+
} else {
|
|
10130
|
+
this.scheduleBackgroundResponseAggregationFlush(key, existing);
|
|
10131
|
+
}
|
|
10132
|
+
}
|
|
10133
|
+
}
|
|
10134
|
+
}
|
|
10135
|
+
throw error;
|
|
10136
|
+
}
|
|
10137
|
+
if (!delivery || this.router.getTarget(sessionId) !== delivery.target) {
|
|
10138
|
+
if (parked.resolvers === 1 && !this.backgroundResponseAggregations.has(key)) {
|
|
10139
|
+
this.scheduleBackgroundResponseResolutionRetry(key, sessionId, parked);
|
|
10140
|
+
} else {
|
|
10141
|
+
const existing = this.backgroundResponseAggregations.get(key);
|
|
10142
|
+
if (existing) {
|
|
10143
|
+
if (parked.held.length > 0) {
|
|
10144
|
+
this.applyHeldBackgroundResponses(existing, parked);
|
|
10145
|
+
}
|
|
10146
|
+
this.applyPendingBackgroundResponseTerminal(existing, parked);
|
|
10147
|
+
if (parked.resolvers === 1) {
|
|
10148
|
+
if (existing.turnComplete) {
|
|
10149
|
+
await this.completeBackgroundResponseAggregation(key, existing);
|
|
10150
|
+
} else {
|
|
10151
|
+
this.scheduleBackgroundResponseAggregationFlush(key, existing);
|
|
10152
|
+
}
|
|
10153
|
+
}
|
|
10154
|
+
}
|
|
10155
|
+
}
|
|
10156
|
+
return;
|
|
10157
|
+
}
|
|
10158
|
+
if (parked.retiring || this.pendingBackgroundResponseTerminals.get(key) !== parked) {
|
|
10159
|
+
await this.flushDetachedBackgroundResponse(key, sessionId, parked, delivery);
|
|
10160
|
+
return;
|
|
10161
|
+
}
|
|
10162
|
+
if (parked.retryTimer) {
|
|
10163
|
+
clearTimeout(parked.retryTimer);
|
|
10164
|
+
parked.retryTimer = void 0;
|
|
10165
|
+
}
|
|
10166
|
+
current = this.backgroundResponseAggregations.get(key) ?? this.createBackgroundResponseAggregation(key, sessionId, parked.held[0]?.context ?? context, delivery.target, delivery.sourceLabel);
|
|
10167
|
+
this.applyHeldBackgroundResponses(current, parked);
|
|
10168
|
+
this.applyPendingBackgroundResponseTerminal(current, parked);
|
|
10169
|
+
if (parked.resolutionDropped) {
|
|
10170
|
+
current.resolutionDropped = true;
|
|
10171
|
+
parked.resolutionDropped = void 0;
|
|
10172
|
+
}
|
|
10173
|
+
} finally {
|
|
10174
|
+
parked.resolvers--;
|
|
10175
|
+
if (this.pendingBackgroundResponseTerminals.get(key) === parked && parked.resolvers === 0 && !parked.retryTimer && parked.held.length === 0 && (!parked.resolutionDropped || parked.turnEnded)) {
|
|
10176
|
+
this.pendingBackgroundResponseTerminals.delete(key);
|
|
10177
|
+
}
|
|
10178
|
+
}
|
|
10179
|
+
if (!current)
|
|
10180
|
+
return;
|
|
10181
|
+
if (current.turnComplete && parked.resolvers > 0)
|
|
10182
|
+
return;
|
|
10183
|
+
if (!current.turnComplete) {
|
|
10184
|
+
this.scheduleBackgroundResponseAggregationFlush(key, current);
|
|
10185
|
+
} else {
|
|
10186
|
+
await this.completeBackgroundResponseAggregation(key, current);
|
|
10187
|
+
}
|
|
10188
|
+
return;
|
|
10189
|
+
}
|
|
10190
|
+
current.status = context.status;
|
|
10191
|
+
current.label = context.label ?? current.label;
|
|
10192
|
+
if (text.trim().length > 0)
|
|
10193
|
+
current.parts.push(text);
|
|
10194
|
+
if (context.turnComplete && parked && parked.resolvers > 0) {
|
|
10195
|
+
parked.turnComplete = true;
|
|
10196
|
+
parked.status = context.status;
|
|
10197
|
+
parked.label = context.label ?? parked.label;
|
|
10198
|
+
parked.completionPartial = context.partial === true;
|
|
10199
|
+
} else if (context.turnComplete) {
|
|
10200
|
+
current.turnComplete = true;
|
|
10201
|
+
current.completionPartial = context.partial === true;
|
|
10202
|
+
} else if (parked?.turnComplete && parked.resolvers === 0) {
|
|
10203
|
+
current.turnComplete = true;
|
|
10204
|
+
current.status = parked.status ?? current.status;
|
|
10205
|
+
current.label = parked.label ?? current.label;
|
|
10206
|
+
current.completionPartial = parked.completionPartial === true;
|
|
10207
|
+
}
|
|
10208
|
+
current.resolutionDropped ||= parked?.resolutionDropped;
|
|
10209
|
+
if (!current.turnComplete) {
|
|
10210
|
+
this.scheduleBackgroundResponseAggregationFlush(key, current);
|
|
10211
|
+
return;
|
|
10212
|
+
}
|
|
10213
|
+
await this.completeBackgroundResponseAggregation(key, current);
|
|
10214
|
+
}
|
|
10215
|
+
async flushBackgroundResponseAggregation(key, aggregation) {
|
|
10216
|
+
if (this.backgroundResponseAggregations.get(key) !== aggregation && !this.detachedBackgroundResponseAggregations.has(aggregation) || aggregation.flushing) {
|
|
10217
|
+
return;
|
|
10218
|
+
}
|
|
10219
|
+
this.refreshBackgroundResponseDelivery(aggregation);
|
|
10220
|
+
if (aggregation.retryTimer)
|
|
10221
|
+
clearTimeout(aggregation.retryTimer);
|
|
10222
|
+
aggregation.retryTimer = void 0;
|
|
10223
|
+
let delivery = aggregation.delivery;
|
|
10224
|
+
if (!delivery) {
|
|
10225
|
+
if (aggregation.parts.length === 0) {
|
|
10226
|
+
if (!this.owesTerminalBackgroundResponseCard(aggregation)) {
|
|
10227
|
+
if (aggregation.retiring || aggregation.turnComplete) {
|
|
10228
|
+
this.removeBackgroundResponseAggregation(key, aggregation);
|
|
10229
|
+
} else {
|
|
10230
|
+
this.scheduleBackgroundResponseAggregationFlush(key, aggregation);
|
|
10231
|
+
}
|
|
10232
|
+
return;
|
|
10233
|
+
}
|
|
10234
|
+
}
|
|
10235
|
+
if (aggregation.timeoutTimer)
|
|
10236
|
+
clearTimeout(aggregation.timeoutTimer);
|
|
10237
|
+
aggregation.timeoutTimer = void 0;
|
|
10238
|
+
const parts = aggregation.parts.splice(0);
|
|
10239
|
+
delivery = {
|
|
10240
|
+
status: aggregation.status,
|
|
10241
|
+
label: aggregation.label,
|
|
10242
|
+
parts,
|
|
10243
|
+
partial: this.isPartialBackgroundResponseDelivery(aggregation, parts.length),
|
|
10244
|
+
attempts: 0,
|
|
10245
|
+
composedTurnComplete: aggregation.turnComplete === true
|
|
10246
|
+
};
|
|
10247
|
+
aggregation.delivery = delivery;
|
|
10248
|
+
}
|
|
10249
|
+
const body = this.formatBackgroundResponseAggregation(delivery);
|
|
10250
|
+
aggregation.flushing = true;
|
|
10251
|
+
let error;
|
|
10252
|
+
try {
|
|
10253
|
+
if (delivery.proactivePlan) {
|
|
10254
|
+
await this.deliverProactiveText(aggregation.target, delivery.proactivePlan);
|
|
10255
|
+
} else if (delivery.replyPlan) {
|
|
10256
|
+
await this.deliverReplyText(aggregation.target.chatId, delivery.replyPlan, true);
|
|
10257
|
+
} else if (this.supportsProactiveSend() && this.supportsProactiveTarget(aggregation.target)) {
|
|
10258
|
+
await this.deliverBackgroundResponseToTarget(aggregation.sessionId, body, {
|
|
10259
|
+
target: aggregation.target,
|
|
10260
|
+
sourceLabel: aggregation.sourceLabel
|
|
10261
|
+
});
|
|
10262
|
+
} else {
|
|
10263
|
+
delivery.preparedReplyBody ??= await this.prepareReplyOutput(aggregation.target.chatId, body);
|
|
10264
|
+
await this.deliverBackgroundReply(aggregation.target.chatId, delivery.preparedReplyBody, aggregation.sessionId, aggregation.sourceLabel, true, true);
|
|
10265
|
+
}
|
|
10266
|
+
} catch (caught) {
|
|
10267
|
+
error = caught;
|
|
10268
|
+
if (caught instanceof ProactiveTextDeliveryError) {
|
|
10269
|
+
delivery.proactivePlan = caught.plan;
|
|
10270
|
+
} else if (caught instanceof ReplyTextDeliveryError) {
|
|
10271
|
+
delivery.replyPlan = caught.plan;
|
|
10272
|
+
}
|
|
10273
|
+
} finally {
|
|
10274
|
+
aggregation.flushing = false;
|
|
10275
|
+
}
|
|
10276
|
+
if (error === void 0) {
|
|
10277
|
+
aggregation.delivery = void 0;
|
|
10278
|
+
aggregation.delivered = true;
|
|
10279
|
+
if (delivery.composedTurnComplete === true && aggregation.turnComplete && delivery.partial !== true && !aggregation.retiring) {
|
|
10280
|
+
aggregation.completionDelivered = true;
|
|
10281
|
+
}
|
|
10282
|
+
if (aggregation.retiring || aggregation.turnComplete) {
|
|
10283
|
+
await this.flushBackgroundResponseAggregation(key, aggregation);
|
|
10284
|
+
} else {
|
|
10285
|
+
this.scheduleBackgroundResponseAggregationFlush(key, aggregation);
|
|
10286
|
+
}
|
|
10287
|
+
return;
|
|
10288
|
+
}
|
|
10289
|
+
delivery.attempts++;
|
|
10290
|
+
process.stderr.write(`[DingTalk:${this.name}] background response delivery failed (attempt ${delivery.attempts}): ${sanitizeLogText(error instanceof Error ? error.message : String(error), 300)}
|
|
10291
|
+
`);
|
|
10292
|
+
if (delivery.attempts >= BACKGROUND_RESPONSE_AGGREGATION_MAX_RETRIES || // A permanently rejected send (an invalid appkey, a missing app) cannot
|
|
10293
|
+
// succeed later; retrying it only spends the chat's send quota.
|
|
10294
|
+
error instanceof ProactiveTextDeliveryError && error.retryable === false) {
|
|
10295
|
+
aggregation.delivery = void 0;
|
|
10296
|
+
aggregation.dropped = true;
|
|
10297
|
+
if (aggregation.parts.length === 0) {
|
|
10298
|
+
if (aggregation.retiring || aggregation.turnComplete) {
|
|
10299
|
+
this.removeBackgroundResponseAggregation(key, aggregation);
|
|
10300
|
+
} else {
|
|
10301
|
+
this.scheduleBackgroundResponseAggregationFlush(key, aggregation);
|
|
10302
|
+
}
|
|
10303
|
+
} else if (aggregation.retiring || aggregation.turnComplete) {
|
|
10304
|
+
await this.flushBackgroundResponseAggregation(key, aggregation);
|
|
10305
|
+
} else {
|
|
10306
|
+
this.scheduleBackgroundResponseAggregationFlush(key, aggregation);
|
|
10307
|
+
}
|
|
10308
|
+
return;
|
|
10309
|
+
}
|
|
10310
|
+
aggregation.retryTimer = setTimeout(() => {
|
|
10311
|
+
aggregation.retryTimer = void 0;
|
|
10312
|
+
void this.flushBackgroundResponseAggregation(key, aggregation);
|
|
10313
|
+
}, BACKGROUND_RESPONSE_AGGREGATION_RETRY_MS);
|
|
10314
|
+
aggregation.retryTimer.unref?.();
|
|
10315
|
+
}
|
|
10316
|
+
/**
|
|
10317
|
+
* A card carries `(部分)` whenever it is not the turn's whole output: the
|
|
10318
|
+
* turn is still open, earlier text already went out (or was given up on),
|
|
10319
|
+
* or the turn itself ended early.
|
|
10320
|
+
*/
|
|
10321
|
+
isPartialBackgroundResponseDelivery(aggregation, partCount) {
|
|
10322
|
+
return partCount > 0 && (aggregation.delivered === true || aggregation.dropped === true || aggregation.resolutionDropped === true || aggregation.retiring === true || aggregation.completionPartial === true || aggregation.turnComplete !== true);
|
|
10323
|
+
}
|
|
10324
|
+
/**
|
|
10325
|
+
* A turn that outran the bounded wait had its text delivered under the
|
|
10326
|
+
* `(部分)` label. When it then completes normally with nothing buffered,
|
|
10327
|
+
* a header-only card is the only way the chat ever learns it finished.
|
|
10328
|
+
*/
|
|
10329
|
+
owesTerminalBackgroundResponseCard(aggregation) {
|
|
10330
|
+
return aggregation.turnComplete === true && aggregation.delivered === true && aggregation.completionDelivered !== true && aggregation.retiring !== true && aggregation.completionPartial !== true && aggregation.dropped !== true && aggregation.resolutionDropped !== true;
|
|
10331
|
+
}
|
|
10332
|
+
refreshBackgroundResponseDelivery(aggregation) {
|
|
10333
|
+
const delivery = aggregation.delivery;
|
|
10334
|
+
if (!delivery || aggregation.flushing)
|
|
10335
|
+
return;
|
|
10336
|
+
const plan = delivery.proactivePlan ?? delivery.replyPlan;
|
|
10337
|
+
if (plan && plan.nextChunk > 0)
|
|
10338
|
+
return;
|
|
10339
|
+
const body = this.formatBackgroundResponseAggregation(delivery);
|
|
10340
|
+
const header = body.split("\n", 1)[0];
|
|
10341
|
+
const replaceHeader = /* @__PURE__ */ __name((text) => text.replace(/## (?:✅|❌|⏹️) Agent · [^\n]+/, () => header), "replaceHeader");
|
|
10342
|
+
if (plan) {
|
|
10343
|
+
plan.title = extractTitle(body);
|
|
10344
|
+
plan.chunks[0] = replaceHeader(plan.chunks[0]);
|
|
10345
|
+
}
|
|
10346
|
+
if (delivery.preparedReplyBody) {
|
|
10347
|
+
delivery.preparedReplyBody = replaceHeader(delivery.preparedReplyBody);
|
|
10348
|
+
}
|
|
10349
|
+
delivery.composedTurnComplete = aggregation.turnComplete === true;
|
|
10350
|
+
}
|
|
10351
|
+
removeBackgroundResponseAggregation(key, aggregation) {
|
|
10352
|
+
if (this.backgroundResponseAggregations.get(key) === aggregation) {
|
|
10353
|
+
this.backgroundResponseAggregations.delete(key);
|
|
10354
|
+
}
|
|
10355
|
+
this.detachedBackgroundResponseAggregations.delete(aggregation);
|
|
10356
|
+
}
|
|
10357
|
+
drainBackgroundResponseAggregations(sessionId) {
|
|
10358
|
+
for (const [key, pending] of this.pendingBackgroundResponseTerminals) {
|
|
10359
|
+
if (sessionId !== void 0 && pending.sessionId !== sessionId)
|
|
10360
|
+
continue;
|
|
10361
|
+
if (pending.retryTimer)
|
|
10362
|
+
clearTimeout(pending.retryTimer);
|
|
10363
|
+
pending.retryTimer = void 0;
|
|
10364
|
+
pending.retiring = true;
|
|
10365
|
+
pending.turnComplete = true;
|
|
10366
|
+
pending.completionPartial = true;
|
|
10367
|
+
this.pendingBackgroundResponseTerminals.delete(key);
|
|
10368
|
+
this.detachedPendingBackgroundResponseTerminals.add(pending);
|
|
10369
|
+
}
|
|
10370
|
+
for (const pending of this.detachedPendingBackgroundResponseTerminals) {
|
|
10371
|
+
if (sessionId !== void 0 && pending.sessionId !== sessionId)
|
|
10372
|
+
continue;
|
|
10373
|
+
if (pending.retryTimer)
|
|
10374
|
+
clearTimeout(pending.retryTimer);
|
|
10375
|
+
pending.retryTimer = void 0;
|
|
10376
|
+
pending.retiring = true;
|
|
10377
|
+
pending.turnComplete = true;
|
|
10378
|
+
pending.completionPartial = true;
|
|
10379
|
+
if (pending.held.length > 0 && this.router.getTarget(pending.sessionId) === pending.target) {
|
|
10380
|
+
void this.flushDetachedBackgroundResponse("", pending.sessionId, pending, { target: pending.target }).catch((error) => {
|
|
10381
|
+
process.stderr.write(`[DingTalk:${this.name}] background response delivery failed during drain: ${sanitizeLogText(error instanceof Error ? error.message : String(error), 300)}
|
|
10382
|
+
`);
|
|
10383
|
+
});
|
|
10384
|
+
} else if (pending.held.length > 0) {
|
|
10385
|
+
process.stderr.write(`[DingTalk:${this.name}] background response target unavailable during drain; ${pending.held.length} buffered segment(s) discarded
|
|
10386
|
+
`);
|
|
10387
|
+
pending.held.length = 0;
|
|
10388
|
+
this.detachedPendingBackgroundResponseTerminals.delete(pending);
|
|
10389
|
+
} else if (pending.held.length === 0) {
|
|
10390
|
+
this.detachedPendingBackgroundResponseTerminals.delete(pending);
|
|
10391
|
+
}
|
|
10392
|
+
}
|
|
10393
|
+
const aggregations = /* @__PURE__ */ new Set([
|
|
10394
|
+
...this.backgroundResponseAggregations.values(),
|
|
10395
|
+
...this.detachedBackgroundResponseAggregations
|
|
10396
|
+
]);
|
|
10397
|
+
for (const aggregation of aggregations) {
|
|
10398
|
+
if (sessionId !== void 0 && aggregation.sessionId !== sessionId) {
|
|
10399
|
+
continue;
|
|
10400
|
+
}
|
|
10401
|
+
if (aggregation.timeoutTimer)
|
|
10402
|
+
clearTimeout(aggregation.timeoutTimer);
|
|
10403
|
+
if (aggregation.retryTimer)
|
|
10404
|
+
clearTimeout(aggregation.retryTimer);
|
|
10405
|
+
aggregation.timeoutTimer = void 0;
|
|
10406
|
+
aggregation.retryTimer = void 0;
|
|
10407
|
+
aggregation.retiring = true;
|
|
10408
|
+
aggregation.turnComplete = true;
|
|
10409
|
+
aggregation.completionPartial = true;
|
|
10410
|
+
if (!aggregation.flushing) {
|
|
10411
|
+
void this.flushBackgroundResponseAggregation(aggregation.key, aggregation);
|
|
10412
|
+
}
|
|
10413
|
+
}
|
|
10414
|
+
}
|
|
10415
|
+
createBackgroundResponseAggregation(key, sessionId, context, target, sourceLabel) {
|
|
10416
|
+
const aggregation = {
|
|
10417
|
+
key,
|
|
10418
|
+
sessionId,
|
|
10419
|
+
target,
|
|
10420
|
+
sourceLabel,
|
|
10421
|
+
status: context.status,
|
|
10422
|
+
label: context.label,
|
|
10423
|
+
parts: []
|
|
10424
|
+
};
|
|
10425
|
+
this.backgroundResponseAggregations.set(key, aggregation);
|
|
10426
|
+
return aggregation;
|
|
10427
|
+
}
|
|
10428
|
+
scheduleBackgroundResponseResolutionRetry(key, sessionId, pending) {
|
|
10429
|
+
if (pending.retiring)
|
|
10430
|
+
return;
|
|
10431
|
+
if (pending.retryTimer)
|
|
10432
|
+
return;
|
|
10433
|
+
pending.retryAttempts = (pending.retryAttempts ?? 0) + 1;
|
|
10434
|
+
if (pending.retryAttempts >= BACKGROUND_RESPONSE_AGGREGATION_MAX_RETRIES) {
|
|
10435
|
+
pending.resolutionDropped = true;
|
|
10436
|
+
pending.turnEnded = pending.turnComplete === true;
|
|
10437
|
+
pending.held.length = 0;
|
|
10438
|
+
pending.turnComplete = void 0;
|
|
10439
|
+
pending.status = void 0;
|
|
10440
|
+
pending.label = void 0;
|
|
10441
|
+
pending.completionPartial = void 0;
|
|
10442
|
+
if (pending.turnEnded) {
|
|
10443
|
+
this.detachedPendingBackgroundResponseTerminals.delete(pending);
|
|
10444
|
+
}
|
|
10445
|
+
return;
|
|
10446
|
+
}
|
|
10447
|
+
pending.retryTimer = setTimeout(() => {
|
|
10448
|
+
pending.retryTimer = void 0;
|
|
10449
|
+
pending.retryInFlight = true;
|
|
10450
|
+
void this.retryBackgroundResponseResolution(key, sessionId, pending).catch((error) => {
|
|
10451
|
+
process.stderr.write(`[DingTalk:${this.name}] background response target resolution failed: ${sanitizeLogText(error instanceof Error ? error.message : String(error), 300)}
|
|
10452
|
+
`);
|
|
10453
|
+
}).finally(() => {
|
|
10454
|
+
pending.retryInFlight = false;
|
|
10455
|
+
if (pending.retiring || !pending.retryTimer && !pending.resolutionDropped) {
|
|
10456
|
+
this.detachedPendingBackgroundResponseTerminals.delete(pending);
|
|
10457
|
+
}
|
|
10458
|
+
if (this.pendingBackgroundResponseTerminals.get(key) === pending && pending.resolvers === 0 && !pending.retryTimer && pending.held.length === 0 && (!pending.resolutionDropped || pending.turnEnded)) {
|
|
10459
|
+
this.pendingBackgroundResponseTerminals.delete(key);
|
|
10460
|
+
}
|
|
10461
|
+
});
|
|
10462
|
+
}, BACKGROUND_RESPONSE_AGGREGATION_RETRY_MS);
|
|
10463
|
+
pending.retryTimer.unref?.();
|
|
10464
|
+
const active = this.pendingBackgroundResponseTerminals.get(key);
|
|
10465
|
+
if (!active || active === pending) {
|
|
10466
|
+
this.pendingBackgroundResponseTerminals.set(key, pending);
|
|
10467
|
+
}
|
|
10468
|
+
}
|
|
10469
|
+
async retryBackgroundResponseResolution(key, sessionId, pending) {
|
|
10470
|
+
let delivery;
|
|
10471
|
+
try {
|
|
10472
|
+
delivery = await this.resolveBackgroundResponseDelivery(sessionId);
|
|
10473
|
+
} catch (error) {
|
|
10474
|
+
if (this.pendingBackgroundResponseTerminals.get(key) === pending && !this.backgroundResponseAggregations.has(key) || this.detachedPendingBackgroundResponseTerminals.has(pending)) {
|
|
10475
|
+
this.scheduleBackgroundResponseResolutionRetry(key, sessionId, pending);
|
|
10476
|
+
}
|
|
10477
|
+
throw error;
|
|
10478
|
+
}
|
|
10479
|
+
if (!delivery || this.router.getTarget(sessionId) !== delivery.target) {
|
|
10480
|
+
if (pending.retiring) {
|
|
10481
|
+
if (pending.held.length > 0) {
|
|
10482
|
+
process.stderr.write(`[DingTalk:${this.name}] background response target unavailable during drain; ${pending.held.length} buffered segment(s) discarded
|
|
10483
|
+
`);
|
|
10484
|
+
}
|
|
10485
|
+
pending.held.length = 0;
|
|
10486
|
+
this.detachedPendingBackgroundResponseTerminals.delete(pending);
|
|
10487
|
+
return;
|
|
10488
|
+
}
|
|
10489
|
+
if (this.pendingBackgroundResponseTerminals.get(key) === pending && !this.backgroundResponseAggregations.has(key) || this.detachedPendingBackgroundResponseTerminals.has(pending)) {
|
|
10490
|
+
this.scheduleBackgroundResponseResolutionRetry(key, sessionId, pending);
|
|
10491
|
+
}
|
|
10492
|
+
return;
|
|
10493
|
+
}
|
|
10494
|
+
if (pending.retiring || this.pendingBackgroundResponseTerminals.get(key) !== pending || pending.turnComplete) {
|
|
10495
|
+
await this.flushDetachedBackgroundResponse(key, sessionId, pending, delivery);
|
|
10496
|
+
return;
|
|
10497
|
+
}
|
|
10498
|
+
const first = pending.held[0];
|
|
10499
|
+
if (!first)
|
|
10500
|
+
return;
|
|
10501
|
+
const aggregation = this.createBackgroundResponseAggregation(key, sessionId, first.context, delivery.target, delivery.sourceLabel);
|
|
10502
|
+
this.applyHeldBackgroundResponses(aggregation, pending);
|
|
10503
|
+
if (pending.resolutionDropped) {
|
|
10504
|
+
aggregation.resolutionDropped = true;
|
|
10505
|
+
pending.resolutionDropped = void 0;
|
|
10506
|
+
}
|
|
10507
|
+
if (this.pendingBackgroundResponseTerminals.get(key) === pending) {
|
|
10508
|
+
this.pendingBackgroundResponseTerminals.delete(key);
|
|
10509
|
+
}
|
|
10510
|
+
this.scheduleBackgroundResponseAggregationFlush(key, aggregation);
|
|
10511
|
+
}
|
|
10512
|
+
holdPendingBackgroundResponse(pending, text, context) {
|
|
10513
|
+
if (text.trim().length > 0)
|
|
10514
|
+
pending.held.push({ text, context });
|
|
10515
|
+
if (context.turnComplete) {
|
|
10516
|
+
pending.turnComplete = true;
|
|
10517
|
+
pending.status = context.status;
|
|
10518
|
+
pending.label = context.label ?? pending.label;
|
|
10519
|
+
pending.completionPartial = context.partial === true;
|
|
10520
|
+
}
|
|
10521
|
+
}
|
|
10522
|
+
applyHeldBackgroundResponses(aggregation, pending) {
|
|
10523
|
+
for (const { text, context } of pending.held.splice(0)) {
|
|
10524
|
+
aggregation.status = context.status;
|
|
10525
|
+
aggregation.label = context.label ?? aggregation.label;
|
|
10526
|
+
aggregation.parts.push(text);
|
|
10527
|
+
if (context.turnComplete) {
|
|
10528
|
+
aggregation.turnComplete = true;
|
|
10529
|
+
aggregation.completionPartial = context.partial === true;
|
|
10530
|
+
}
|
|
10531
|
+
}
|
|
10532
|
+
}
|
|
10533
|
+
applyPendingBackgroundResponseTerminal(aggregation, pending) {
|
|
10534
|
+
if (!pending.turnComplete)
|
|
10535
|
+
return;
|
|
10536
|
+
aggregation.turnComplete = true;
|
|
10537
|
+
aggregation.status = pending.status ?? aggregation.status;
|
|
10538
|
+
aggregation.label = pending.label ?? aggregation.label;
|
|
10539
|
+
aggregation.completionPartial = pending.completionPartial === true;
|
|
10540
|
+
pending.turnComplete = void 0;
|
|
10541
|
+
pending.status = void 0;
|
|
10542
|
+
pending.label = void 0;
|
|
10543
|
+
pending.completionPartial = void 0;
|
|
10544
|
+
}
|
|
10545
|
+
async completeBackgroundResponseAggregation(key, aggregation) {
|
|
10546
|
+
if (aggregation.delivery) {
|
|
10547
|
+
aggregation.delivery.status = aggregation.status;
|
|
10548
|
+
aggregation.delivery.label = aggregation.label ?? aggregation.delivery.label;
|
|
10549
|
+
aggregation.delivery.partial = this.isPartialBackgroundResponseDelivery(aggregation, aggregation.delivery.parts.length) || aggregation.parts.length > 0;
|
|
10550
|
+
}
|
|
10551
|
+
if (aggregation.timeoutTimer)
|
|
10552
|
+
clearTimeout(aggregation.timeoutTimer);
|
|
10553
|
+
aggregation.timeoutTimer = void 0;
|
|
10554
|
+
await this.flushBackgroundResponseAggregation(key, aggregation);
|
|
10555
|
+
}
|
|
10556
|
+
async flushDetachedBackgroundResponse(key, sessionId, pending, delivery) {
|
|
10557
|
+
const first = pending.held[0];
|
|
10558
|
+
if (!first) {
|
|
10559
|
+
this.detachedPendingBackgroundResponseTerminals.delete(pending);
|
|
10560
|
+
return;
|
|
10561
|
+
}
|
|
10562
|
+
const aggregation = {
|
|
10563
|
+
key,
|
|
10564
|
+
sessionId,
|
|
10565
|
+
target: delivery.target,
|
|
10566
|
+
sourceLabel: delivery.sourceLabel,
|
|
10567
|
+
status: first.context.status,
|
|
10568
|
+
label: first.context.label,
|
|
10569
|
+
parts: [],
|
|
10570
|
+
turnComplete: pending.turnComplete,
|
|
10571
|
+
completionPartial: pending.completionPartial,
|
|
10572
|
+
resolutionDropped: pending.resolutionDropped
|
|
10573
|
+
};
|
|
10574
|
+
this.applyHeldBackgroundResponses(aggregation, pending);
|
|
10575
|
+
aggregation.status = pending.status ?? aggregation.status;
|
|
10576
|
+
aggregation.label = pending.label ?? aggregation.label;
|
|
10577
|
+
if (this.pendingBackgroundResponseTerminals.get(key) === pending) {
|
|
10578
|
+
this.pendingBackgroundResponseTerminals.delete(key);
|
|
10579
|
+
}
|
|
10580
|
+
this.detachedPendingBackgroundResponseTerminals.delete(pending);
|
|
10581
|
+
this.detachedBackgroundResponseAggregations.add(aggregation);
|
|
10582
|
+
await this.flushBackgroundResponseAggregation(key, aggregation);
|
|
10583
|
+
}
|
|
10584
|
+
scheduleBackgroundResponseAggregationFlush(key, aggregation) {
|
|
10585
|
+
if (aggregation.timeoutTimer || aggregation.delivery)
|
|
10586
|
+
return;
|
|
10587
|
+
aggregation.timeoutTimer = setTimeout(() => {
|
|
10588
|
+
aggregation.timeoutTimer = void 0;
|
|
10589
|
+
void this.flushBackgroundResponseAggregation(key, aggregation);
|
|
10590
|
+
}, BACKGROUND_RESPONSE_AGGREGATION_TIMEOUT_MS);
|
|
10591
|
+
aggregation.timeoutTimer.unref?.();
|
|
10592
|
+
}
|
|
10593
|
+
formatBackgroundResponseAggregation(delivery) {
|
|
10594
|
+
const icon = delivery.status === "completed" ? "\u2705" : delivery.status === "failed" ? "\u274C" : "\u23F9\uFE0F";
|
|
10595
|
+
const label = this.formatBackgroundAgentLabel(delivery.label);
|
|
10596
|
+
const header = `## ${icon} Agent \xB7 ${label}${delivery.partial ? "\uFF08\u90E8\u5206\uFF09" : ""}`;
|
|
10597
|
+
if (delivery.parts.length === 0)
|
|
10598
|
+
return header;
|
|
10599
|
+
return `${header}
|
|
10600
|
+
|
|
10601
|
+
${delivery.parts.join("\n\n")}`;
|
|
10602
|
+
}
|
|
10603
|
+
formatBackgroundAgentResponse(text, label) {
|
|
10604
|
+
return `## \u{1F916} Agent \xB7 ${this.formatBackgroundAgentLabel(label)}
|
|
10605
|
+
|
|
10606
|
+
${text}`;
|
|
10607
|
+
}
|
|
10608
|
+
formatBackgroundAgentLabel(label) {
|
|
10609
|
+
const normalized = label?.replace(new RegExp("\\p{Cc}+", "gu"), " ").replace(/\s+/g, " ").trim();
|
|
10610
|
+
return escapeDingTalkMarkdown(normalized || "\u540E\u53F0\u4EFB\u52A1");
|
|
10611
|
+
}
|
|
9586
10612
|
/**
|
|
9587
10613
|
* Out-of-turn one-shot sends (background responses) must not flow through
|
|
9588
10614
|
* the session's block-streaming projector: a second sender interleaving with
|
|
9589
10615
|
* mid-projection state can swallow the send or split a held marker.
|
|
9590
10616
|
*/
|
|
9591
|
-
async deliverBackgroundReply(chatId, text, sessionId, sourceLabel) {
|
|
10617
|
+
async deliverBackgroundReply(chatId, text, sessionId, sourceLabel, prepared = false, failOnHttpError = false) {
|
|
9592
10618
|
if (this.config.blockStreaming !== "on") {
|
|
9593
|
-
return
|
|
10619
|
+
return this.sendResponseMessage(chatId, text, sessionId, sourceLabel, prepared, failOnHttpError);
|
|
9594
10620
|
}
|
|
9595
|
-
await this.sendReply(chatId, text, void 0, sourceLabel);
|
|
10621
|
+
await this.sendReply(chatId, text, void 0, sourceLabel, prepared, failOnHttpError);
|
|
9596
10622
|
}
|
|
9597
|
-
async sendResponseMessage(chatId, text, sessionId, sourceLabel, prepared = false) {
|
|
10623
|
+
async sendResponseMessage(chatId, text, sessionId, sourceLabel, prepared = false, failOnHttpError = false) {
|
|
9598
10624
|
let outgoingText = text;
|
|
9599
10625
|
let consumesMention = true;
|
|
9600
10626
|
if (this.config.blockStreaming === "on") {
|
|
@@ -9607,7 +10633,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
|
|
|
9607
10633
|
const atUserId = consumesMention && this.atSender ? this.sessionMentionTargets.get(sessionId) : void 0;
|
|
9608
10634
|
if (atUserId)
|
|
9609
10635
|
this.sessionMentionTargets.delete(sessionId);
|
|
9610
|
-
await this.sendReply(chatId, outgoingText, atUserId, sourceLabel ?? this.getResponseSourceLabel(sessionId), prepared);
|
|
10636
|
+
await this.sendReply(chatId, outgoingText, atUserId, sourceLabel ?? this.getResponseSourceLabel(sessionId), prepared, failOnHttpError);
|
|
9611
10637
|
}
|
|
9612
10638
|
projectBlockStreamChunk(text, sessionId) {
|
|
9613
10639
|
let state = this.blockFileProjectors.get(sessionId);
|
|
@@ -10069,6 +11095,12 @@ var plugin = {
|
|
|
10069
11095
|
required: true,
|
|
10070
11096
|
envResolvable: true
|
|
10071
11097
|
},
|
|
11098
|
+
{
|
|
11099
|
+
key: "aggregateBackgroundAgentResponses",
|
|
11100
|
+
label: "Aggregate Background Agent Responses",
|
|
11101
|
+
kind: "boolean",
|
|
11102
|
+
description: "Buffer each background Agent turn and send one labeled result instead of labeled segments"
|
|
11103
|
+
},
|
|
10072
11104
|
{
|
|
10073
11105
|
key: "interactiveCards",
|
|
10074
11106
|
label: "Interactive Cards",
|