@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.
Files changed (351) hide show
  1. package/bundled/computer-use/SKILL.md +189 -116
  2. package/bundled/goal-draft/SKILL.md +23 -13
  3. package/bundled/qc-helper/docs/_meta.ts +1 -0
  4. package/bundled/qc-helper/docs/configuration/model-providers.md +47 -1
  5. package/bundled/qc-helper/docs/configuration/settings.md +57 -7
  6. package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
  7. package/bundled/qc-helper/docs/features/channels/dingtalk.md +26 -0
  8. package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
  9. package/bundled/qc-helper/docs/features/commands.md +71 -6
  10. package/bundled/qc-helper/docs/features/computer-use.md +9 -7
  11. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  12. package/bundled/qc-helper/docs/features/goals.md +15 -3
  13. package/bundled/qc-helper/docs/features/skills.md +40 -0
  14. package/bundled/qc-helper/docs/qwen-serve.md +19 -1
  15. package/chunks/{MaxSizedBox-5ARLO5PR.js → MaxSizedBox-UDO6Y7RB.js} +35 -36
  16. package/chunks/{StandaloneSessionPicker-T6B322CB.js → StandaloneSessionPicker-D4CUOO4H.js} +55 -56
  17. package/chunks/{acp-startup-profiler-6ULXXQMS.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
  18. package/chunks/{acpAgent-WTDEY5KD.js → acpAgent-KWLJFADK.js} +210 -131
  19. package/chunks/{agent-NXPUXEVZ.js → agent-GSUPGEOL.js} +24 -25
  20. package/chunks/{agent-headless-QQZTWOKO.js → agent-headless-HNYCQUJB.js} +24 -25
  21. package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-I7LQZH26.js} +30 -7
  22. package/chunks/{artifact-tool-DFVVJXL2.js → artifact-tool-P52OKKEF.js} +1 -1
  23. package/chunks/{askUserQuestion-GF7VQ44M.js → askUserQuestion-I5W5S3D6.js} +2 -2
  24. package/chunks/{bridge-OHY5OGOZ.js → bridge-B7CV6RVI.js} +40 -41
  25. package/chunks/{channel-management-service-ZDDG3G5S.js → channel-management-service-TRTLQTSV.js} +4 -4
  26. package/chunks/{channel-settings-store-7BJAS2SU.js → channel-settings-store-FW45IRUP.js} +46 -47
  27. package/chunks/{channel-worker-group-2ISMRENV.js → channel-worker-group-PIYPVCTF.js} +6 -6
  28. package/chunks/{channel-worker-manager-VSRPVPRH.js → channel-worker-manager-FQHEDTD2.js} +6 -6
  29. package/chunks/{channel-worker-supervisor-SRJBK72Z.js → channel-worker-supervisor-XJPZZ3VK.js} +3 -3
  30. package/chunks/{chunk-2WGJG2KW.js → chunk-25CBAK3H.js} +4 -4
  31. package/chunks/{chunk-XUSOYE2I.js → chunk-27LTEY6D.js} +1 -1
  32. package/chunks/{chunk-WTW36TJ3.js → chunk-2EKVPSIJ.js} +1 -1
  33. package/chunks/{chunk-NAKALAL4.js → chunk-2TMJRF46.js} +116 -15
  34. package/chunks/{chunk-E4L5BM2B.js → chunk-2YS3NU4A.js} +4 -4
  35. package/chunks/chunk-2Z3T52OC.js +82 -0
  36. package/chunks/{chunk-ER273QE6.js → chunk-2ZFO5JD7.js} +21 -4
  37. package/chunks/{chunk-WXC6OAWD.js → chunk-3BTHHXXE.js} +1 -1
  38. package/chunks/{chunk-GXZHYPHZ.js → chunk-3LPJ776W.js} +5 -2
  39. package/chunks/{chunk-XY3USGFE.js → chunk-3VDLQUR2.js} +1 -1
  40. package/chunks/{chunk-LK7S2D6V.js → chunk-3VWPPK5Q.js} +58 -4
  41. package/chunks/{chunk-IKLFS6SC.js → chunk-3YQMUBTS.js} +3 -3
  42. package/chunks/{chunk-P4RUUG64.js → chunk-45ROPFQY.js} +1 -1
  43. package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
  44. package/chunks/{chunk-D6PIMKY3.js → chunk-4VY3ITHR.js} +4 -4
  45. package/chunks/{chunk-H3UDNQLO.js → chunk-5CVY5Q2P.js} +3 -3
  46. package/chunks/{chunk-6UIACMGH.js → chunk-5DQ4YTIZ.js} +1 -1
  47. package/chunks/{chunk-P6LATTDG.js → chunk-5IL2BZHW.js} +3 -3
  48. package/chunks/{chunk-537SQ2AI.js → chunk-5WC2ECUK.js} +104 -16
  49. package/chunks/{chunk-HFTB354P.js → chunk-5Z4FCEPY.js} +60 -6
  50. package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
  51. package/chunks/{chunk-AQ5NAGWI.js → chunk-66JBCTJF.js} +8 -7
  52. package/chunks/{chunk-54TF2ZIQ.js → chunk-6JXHO7LG.js} +3 -3
  53. package/chunks/{chunk-YCDL2SAS.js → chunk-6QILGINT.js} +2 -2
  54. package/chunks/{chunk-P5LDR7FI.js → chunk-6QV7Z74P.js} +3 -3
  55. package/chunks/{chunk-4HC4DYKN.js → chunk-6RZX2HIH.js} +1 -1
  56. package/chunks/{chunk-O45WBTNS.js → chunk-6SADVYQQ.js} +3 -3
  57. package/chunks/{chunk-KE3Q4JMY.js → chunk-6TPVIESH.js} +5 -7
  58. package/chunks/{chunk-2LD5U7Q3.js → chunk-6YEOCHSE.js} +29 -1
  59. package/chunks/{chunk-QWZOOIR3.js → chunk-75LBC7SV.js} +69 -12
  60. package/chunks/{chunk-7BZS4ZDV.js → chunk-7SL55L5H.js} +25 -18
  61. package/chunks/{chunk-O2GG7H4C.js → chunk-ARYNBBBM.js} +3 -3
  62. package/chunks/{chunk-CZACBHAW.js → chunk-B3EL44K3.js} +5 -5
  63. package/chunks/{chunk-VY6UVU7G.js → chunk-CABDNUJ4.js} +2 -2
  64. package/chunks/{chunk-RVNS7NWN.js → chunk-CALNF3Z3.js} +1 -1
  65. package/chunks/{chunk-MWHY26G3.js → chunk-CHVU543W.js} +1 -1
  66. package/chunks/{chunk-GZWW2QWR.js → chunk-CIKL2DQP.js} +2 -2
  67. package/chunks/{chunk-R355CUNQ.js → chunk-CLKE4IY3.js} +1 -77
  68. package/chunks/{chunk-MUZCSTOO.js → chunk-CRZBDVP2.js} +5 -4
  69. package/chunks/{chunk-SFMCYMVF.js → chunk-D6AQNMUA.js} +4 -4
  70. package/chunks/{chunk-D4CU6DKR.js → chunk-DO5SMV52.js} +10 -8
  71. package/chunks/{chunk-ZAZ3NFL6.js → chunk-DXQ6Z7AH.js} +315 -63
  72. package/chunks/{chunk-IXSGOSEG.js → chunk-DZ6D4B3K.js} +28 -25
  73. package/chunks/{chunk-GMNLYQOS.js → chunk-E6TI726I.js} +1 -1
  74. package/chunks/{chunk-JBTZUFR4.js → chunk-E7XSUYCZ.js} +6 -6
  75. package/chunks/{chunk-AHBLRVD5.js → chunk-EEKU6COG.js} +4 -4
  76. package/chunks/{chunk-47BZVBTE.js → chunk-EHTKOO6W.js} +4 -4
  77. package/chunks/{chunk-HJ34U5J4.js → chunk-ENZDGHGJ.js} +4 -4
  78. package/chunks/{chunk-IFD3BTEA.js → chunk-EOET4H7C.js} +3 -3
  79. package/chunks/{chunk-ZTAVGFKA.js → chunk-ERXNTINK.js} +1 -1
  80. package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
  81. package/chunks/{chunk-KPXRFTT7.js → chunk-FETY36NQ.js} +1 -1
  82. package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
  83. package/chunks/{chunk-4F2QRVW6.js → chunk-FW4E4QPG.js} +1 -1
  84. package/chunks/{chunk-KJJPJYHI.js → chunk-FWRRUITH.js} +8 -8
  85. package/chunks/{chunk-4VUVBN3Y.js → chunk-G6UUOCUT.js} +87 -0
  86. package/chunks/{chunk-4JAGXZR3.js → chunk-GM44O6F7.js} +1 -1
  87. package/chunks/{chunk-4MCY33Y2.js → chunk-GNY7B3CA.js} +1 -1
  88. package/chunks/{chunk-VEFRT7NX.js → chunk-H3Q3RSKZ.js} +1 -1
  89. package/chunks/{chunk-43NOB5NM.js → chunk-HIXUUCGY.js} +188 -13
  90. package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
  91. package/chunks/{chunk-JOPC3FND.js → chunk-HUX2DOTF.js} +5 -5
  92. package/chunks/{chunk-GCFZ2LAX.js → chunk-HZ2HUXX7.js} +2 -2
  93. package/chunks/{chunk-CWNC7M73.js → chunk-IKG2YVRZ.js} +2 -2
  94. package/chunks/{chunk-L4R7BCVV.js → chunk-J3TJH52D.js} +1 -1
  95. package/chunks/{chunk-QMFOYPGV.js → chunk-J3VZF2AL.js} +2 -2
  96. package/chunks/{chunk-ZJ2LM2SI.js → chunk-JGDRB4FP.js} +104 -33
  97. package/chunks/{chunk-LMJQSPWB.js → chunk-KA5HR3G2.js} +1 -1
  98. package/chunks/{chunk-G34YLYCS.js → chunk-L7V52QEZ.js} +10 -10
  99. package/chunks/{chunk-GVVCLL2P.js → chunk-LNCNUMJ5.js} +451 -396
  100. package/chunks/{chunk-RDKXZ2LS.js → chunk-LYT2OU7D.js} +1 -1
  101. package/chunks/{chunk-SAZS4IWW.js → chunk-LZGFVUWZ.js} +3 -3
  102. package/chunks/{chunk-32YDNYXP.js → chunk-M73KHGNR.js} +13 -66
  103. package/chunks/{chunk-ADJD4LZF.js → chunk-MA5OUNN6.js} +1 -1
  104. package/chunks/{chunk-2RYWGYB3.js → chunk-MFYH2VXV.js} +3 -3
  105. package/chunks/{chunk-RPBMP6BN.js → chunk-MWIO7MF6.js} +3 -0
  106. package/chunks/{chunk-OECNP26L.js → chunk-N6S3NUYJ.js} +1 -1
  107. package/chunks/{chunk-5MTARK4Y.js → chunk-N7YQEKGX.js} +6 -6
  108. package/chunks/{chunk-XOVVCGZX.js → chunk-NB3NDQQK.js} +1 -1
  109. package/chunks/chunk-NOO4QFXM.js +171 -0
  110. package/chunks/{chunk-NGX4NUNP.js → chunk-O2FEO2CB.js} +131 -6
  111. package/chunks/{chunk-XHGGYCTA.js → chunk-O2JBJQCF.js} +1 -1
  112. package/chunks/{chunk-LPBQODMR.js → chunk-OESZTXTG.js} +4 -4
  113. package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
  114. package/chunks/{chunk-TDP7UULF.js → chunk-OPMKGOLD.js} +1 -1
  115. package/chunks/{chunk-LDS57224.js → chunk-OWCFKIFQ.js} +1 -1
  116. package/chunks/{chunk-I72PHOKL.js → chunk-PDUMGZ2P.js} +1524 -1382
  117. package/chunks/{chunk-JRYL3T2O.js → chunk-PQSCGZT2.js} +1 -1
  118. package/chunks/{chunk-WEXA2DNG.js → chunk-PSPAM24S.js} +14 -0
  119. package/chunks/{chunk-UKKYOIVT.js → chunk-QAZ2MGYT.js} +2 -2
  120. package/chunks/{chunk-J3O5I5ZD.js → chunk-QK4K76T6.js} +3 -3
  121. package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
  122. package/chunks/{chunk-5YY5MZT6.js → chunk-QZOXVQPK.js} +1 -1
  123. package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
  124. package/chunks/{chunk-IQN2CCIE.js → chunk-RNYENHN5.js} +398 -55
  125. package/chunks/{chunk-64MQTIX7.js → chunk-RPFJJ33Z.js} +2 -2
  126. package/chunks/{chunk-4VZCORNT.js → chunk-RXT4QBDX.js} +1 -1
  127. package/chunks/{chunk-SN5FV4FY.js → chunk-S6QVI3MV.js} +3 -3
  128. package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
  129. package/chunks/{chunk-JLWFGYXU.js → chunk-T2IHCZLS.js} +2 -2
  130. package/chunks/{chunk-DNPHKA72.js → chunk-TGC4264Q.js} +6 -6
  131. package/chunks/{chunk-PZV2FASB.js → chunk-TRWQQBVH.js} +1 -1
  132. package/chunks/{chunk-Y3ZKI4RQ.js → chunk-TWAMIEQ2.js} +85 -22
  133. package/chunks/{chunk-KK2GZGBK.js → chunk-TWWS7XUW.js} +14 -11
  134. package/chunks/{chunk-4IQKBLTQ.js → chunk-UHUT4IDM.js} +18 -9
  135. package/chunks/{chunk-BKNY7PDI.js → chunk-USN6VNTO.js} +1 -1
  136. package/chunks/{chunk-TMWB67LS.js → chunk-UXDVUFKU.js} +3 -3
  137. package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
  138. package/chunks/{chunk-3K456UJF.js → chunk-VF6D6EGV.js} +12 -4
  139. package/chunks/{chunk-PZUOHCWI.js → chunk-WAASYFPK.js} +2 -2
  140. package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
  141. package/chunks/{chunk-JPEAQJNS.js → chunk-WJDXKQIO.js} +1 -1
  142. package/chunks/{chunk-MNEYUNOE.js → chunk-WNISCNTA.js} +40 -2
  143. package/chunks/{chunk-Z6WZPXQH.js → chunk-WQMUGQ6G.js} +2 -2
  144. package/chunks/{chunk-N7VURC4O.js → chunk-WXFCI3O5.js} +2 -2
  145. package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
  146. package/chunks/{chunk-N7EYO2E7.js → chunk-XQ4RDO5B.js} +1 -1
  147. package/chunks/{chunk-VDXYYVCD.js → chunk-XVTCSVBK.js} +579 -57
  148. package/chunks/{chunk-PTFFWTTO.js → chunk-XZ3Z43XL.js} +3 -3
  149. package/chunks/{chunk-QSC5YOEC.js → chunk-YAC7H4K3.js} +2 -2
  150. package/chunks/{chunk-43JNQAHO.js → chunk-YCEKI7QX.js} +51 -10
  151. package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
  152. package/chunks/{chunk-VUSSAGKI.js → chunk-YZTGGCEE.js} +10 -2
  153. package/chunks/{chunk-WR3SH3EY.js → chunk-ZNO5BUAD.js} +149 -66
  154. package/chunks/{chunk-URSCX7S7.js → chunk-ZPL2TZNA.js} +353 -11
  155. package/chunks/{chunk-UEZOXZNI.js → chunk-ZU2T5JIS.js} +804 -371
  156. package/chunks/{config-utils-QXDOTXEQ.js → config-utils-KTDSQ4MU.js} +39 -40
  157. package/chunks/{contextCommand-RN4KARWC.js → contextCommand-UQ3KRYGK.js} +37 -38
  158. package/chunks/{core-runtime-NAZCOKHB.js → core-runtime-JR34JAFH.js} +35 -36
  159. package/chunks/{create-sub-session-BCSM4WKB.js → create-sub-session-RGPJOI4S.js} +45 -40
  160. package/chunks/{create-sub-session-BQ3SE4TX.js → create-sub-session-TGIX63YU.js} +2 -2
  161. package/chunks/{cron-create-D6HQ7I7I.js → cron-create-GTPVMJCF.js} +1 -1
  162. package/chunks/{cron-delete-KK3D2SQV.js → cron-delete-ZBK27Z4K.js} +1 -1
  163. package/chunks/{cron-list-VBF3IZMF.js → cron-list-KTFKFDKC.js} +1 -1
  164. package/chunks/{daemon-LCUELM6E.js → daemon-UI6SQSBV.js} +1 -1
  165. package/chunks/{daemon-git-worktree-guard-3K5CAU36.js → daemon-git-worktree-guard-H3OA26KQ.js} +35 -36
  166. package/chunks/{daemon-status-provider-4X3ZZQTZ.js → daemon-status-provider-6WZLKSZU.js} +45 -46
  167. package/chunks/{daemon-trust-policy-R45CFUJA.js → daemon-trust-policy-3EDP2BYD.js} +42 -43
  168. package/chunks/{daemon-trust-policy-monitor-DSSFCO3K.js → daemon-trust-policy-monitor-CRHZPK52.js} +42 -43
  169. package/chunks/{deferred-core-runtime-UO2M6WYI.js → deferred-core-runtime-LO5NTQQ4.js} +35 -36
  170. package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
  171. package/chunks/{display-image-EVVTBVYE.js → display-image-CTNHJRZC.js} +4 -4
  172. package/chunks/{dist-SIHF5MU2.js → dist-24TCWK5H.js} +1 -1
  173. package/chunks/{dist-AFH3BMZZ.js → dist-5I4HLUTO.js} +1 -1
  174. package/chunks/{dist-3T5MDUHP.js → dist-FDISN4AK.js} +1 -1
  175. package/chunks/{dist-SB2XRXZA.js → dist-M4CBX53H.js} +1 -1
  176. package/chunks/{dist-UVHW2U56.js → dist-NQ2636VT.js} +1 -1
  177. package/chunks/{dist-PH5RSTEA.js → dist-OR2ZQTXZ.js} +1 -1
  178. package/chunks/{dist-MK5PPBRF.js → dist-STAGIFNB.js} +1099 -67
  179. package/chunks/{dist-R5Y34V6T.js → dist-WZTUKIDR.js} +2 -2
  180. package/chunks/{dist-QUU7TVE3.js → dist-XJ25G6OH.js} +1 -1
  181. package/chunks/{edit-VNBCTRWP.js → edit-LB7Z7XK5.js} +24 -25
  182. package/chunks/{en-JMR535HP.js → en-YJNRUQG4.js} +1 -1
  183. package/chunks/{enter-worktree-CEVK7MQ2.js → enter-worktree-YFTKHXHZ.js} +4 -4
  184. package/chunks/{enterPlanMode-4KMZMUIA.js → enterPlanMode-P6TVUFIY.js} +24 -25
  185. package/chunks/{environment-S2HYQDON.js → environment-QATJNNKI.js} +38 -39
  186. package/chunks/{errors-DAAN5TL7.js → errors-3XJ37PS2.js} +37 -38
  187. package/chunks/{exit-worktree-D3YE6MUN.js → exit-worktree-NF2XEMES.js} +5 -5
  188. package/chunks/{exitPlanMode-HR36HG3D.js → exitPlanMode-A3OKL5UO.js} +24 -25
  189. package/chunks/{fast-path-4IWSW3UV.js → fast-path-DBIT5YQQ.js} +3 -3
  190. package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
  191. package/chunks/{glob-IZYB2XH2.js → glob-73EDTXUE.js} +24 -25
  192. package/chunks/{goal-tools-VGUPKQDJ.js → goal-tools-DFI6YMSD.js} +24 -25
  193. package/chunks/{grep-OUVLNXG7.js → grep-BLHF2S5D.js} +2 -2
  194. package/chunks/{handleAutoUpdate-D56FMDTW.js → handleAutoUpdate-2FUNJO3B.js} +38 -39
  195. package/chunks/{i18n-BKE5WO6T.js → i18n-FDIA6KFI.js} +38 -37
  196. package/chunks/{image-gen-SHVQ3XID.js → image-gen-XP4NNIYG.js} +5 -5
  197. package/chunks/{initializer-MS4SGEHF.js → initializer-4MJTJOTW.js} +42 -43
  198. package/chunks/{installationInfo-542MGC4S.js → installationInfo-232RA2OK.js} +35 -36
  199. package/chunks/{list-H6XTKUWL.js → list-WN6WSGEB.js} +45 -46
  200. package/chunks/{list-agents-ULYBGJXC.js → list-agents-I5TRH3J7.js} +2 -2
  201. package/chunks/{llm-3NUC4EJY.js → llm-UDFWQWZA.js} +77 -78
  202. package/chunks/{llm-content-generator-R4NL3OQN.js → llm-content-generator-VLMZ2A7A.js} +23 -8
  203. package/chunks/{loadedSettingsAdapter-3XLKYDVT.js → loadedSettingsAdapter-OBQEIXM7.js} +42 -43
  204. package/chunks/{loggingContentGenerator-ZYSWVNEO.js → loggingContentGenerator-RGVUMUVX.js} +26 -27
  205. package/chunks/{loop-wakeup-B27BEYRL.js → loop-wakeup-HL6XOWI4.js} +2 -2
  206. package/chunks/{ls-3IIMMVKF.js → ls-YV7RKLKY.js} +1 -1
  207. package/chunks/{lsp-VJAT7XKS.js → lsp-NO3AMRZT.js} +1 -1
  208. package/chunks/{managed-npm-update-L2I53ZAI.js → managed-npm-update-QBAJYCFU.js} +35 -36
  209. package/chunks/{mcp-4PIXQASW.js → mcp-OTIZZCPY.js} +42 -43
  210. package/chunks/{monitor-O2YQTOZZ.js → monitor-BV5XF6LL.js} +24 -25
  211. package/chunks/{nonInteractiveCli-LV7CDBA2.js → nonInteractiveCli-W6MUKDVJ.js} +79 -77
  212. package/chunks/{notebook-edit-4RE2ALH4.js → notebook-edit-HGBEKGTE.js} +24 -25
  213. package/chunks/{openaiContentGenerator-7ND7K5CP.js → openaiContentGenerator-NSU3ERBH.js} +15 -15
  214. package/chunks/{pidfile-UFTLQ7NP.js → pidfile-LE3TU4GE.js} +35 -36
  215. package/chunks/{processUtils-3XBB4FYV.js → processUtils-YFBGJK67.js} +2 -2
  216. package/chunks/{prompt-terminal-ledger-2QASOGMM.js → prompt-terminal-ledger-4W4W7DSO.js} +36 -37
  217. package/chunks/{qwenContentGenerator-AELTUTH6.js → qwenContentGenerator-HTA57WFC.js} +28 -29
  218. package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
  219. package/chunks/{read-file-PDWHZPHX.js → read-file-KHPQ2MB6.js} +4 -4
  220. package/chunks/{read-mcp-resource-YXJZ75UB.js → read-mcp-resource-D3N75DGF.js} +1 -1
  221. package/chunks/{record-artifact-WJDOV6XU.js → record-artifact-Q5CRGJTP.js} +2 -2
  222. package/chunks/{report-findings-Q4UACKWR.js → report-findings-TJ34R7QK.js} +3 -3
  223. package/chunks/{request-shutdown-2YZ3E3GH.js → request-shutdown-LRKMTBAD.js} +6 -6
  224. package/chunks/{resumeHistoryUtils-QRXZEEBA.js → resumeHistoryUtils-K7RV3QBN.js} +39 -40
  225. package/chunks/{ripGrep-KSOOLE6H.js → ripGrep-NBBVCMG4.js} +7 -7
  226. package/chunks/{run-qwen-serve-RTAREPT6.js → run-qwen-serve-A3JBOZCM.js} +58 -60
  227. package/chunks/{runtime-ESFSCJRZ.js → runtime-7YOU2KJ3.js} +47 -48
  228. package/chunks/{scheduled-tasks-6ZHRNBH6.js → scheduled-tasks-52LXK7LN.js} +42 -43
  229. package/chunks/{scheduler-DQI6KV7T.js → scheduler-J44M72VM.js} +37 -38
  230. package/chunks/{send-message-PQCVSVMN.js → send-message-AWKUDJBH.js} +8 -8
  231. package/chunks/{serve-FY7ZEW52.js → serve-TRC6XJUB.js} +42 -43
  232. package/chunks/{server-KNDY6K5F.js → server-YPNTJLX2.js} +1314 -841
  233. package/chunks/{session-MCEPXAZP.js → session-FMMIBFYX.js} +98 -84
  234. package/chunks/{session-attachments-root-OLNAE6GF.js → session-attachments-root-LDJMNK7K.js} +35 -36
  235. package/chunks/{session-pr-refresh-HKJHQQQK.js → session-pr-refresh-NLR4EK2J.js} +41 -42
  236. package/chunks/{settings-VXO4WBMK.js → settings-A46L577J.js} +41 -42
  237. package/chunks/{shell-U263OTES.js → shell-Q5LSQPPY.js} +24 -25
  238. package/chunks/{skill-SDODGBKL.js → skill-75KPJRCM.js} +10 -57
  239. package/chunks/{skill-settings-YEIA22QJ.js → skill-settings-775YT4YR.js} +41 -42
  240. package/chunks/{spawnChannel-4WJZVFPP.js → spawnChannel-XY73I5CU.js} +37 -38
  241. package/chunks/{standalone-update-ZWVQUO64.js → standalone-update-L46XXNQ2.js} +37 -38
  242. package/chunks/{start-opentui-ui-BFYCJQRZ.js → start-opentui-ui-WLV43247.js} +2007 -1003
  243. package/chunks/{startInteractiveUI-JYAFCMHL.js → startInteractiveUI-F5DKMLOV.js} +1231 -1528
  244. package/chunks/{syntheticOutput-AUAJBNXR.js → syntheticOutput-D2P5V6RG.js} +2 -2
  245. package/chunks/{task-create-LD5ISM3E.js → task-create-PMAFST2T.js} +7 -7
  246. package/chunks/{task-list-YISJ4RJA.js → task-list-R2HSY2NC.js} +1 -1
  247. package/chunks/{task-stop-65ZOVATJ.js → task-stop-BFSKRTGV.js} +1 -1
  248. package/chunks/{task-update-AAN4ZVEY.js → task-update-JYC57USF.js} +7 -7
  249. package/chunks/{team-create-KU7MABNO.js → team-create-2PATB77U.js} +24 -25
  250. package/chunks/{team-delete-XFRRTJTT.js → team-delete-CBHVBTPB.js} +1 -1
  251. package/chunks/{team-plan-approval-DPB377A3.js → team-plan-approval-QTANEWOS.js} +24 -25
  252. package/chunks/{terminal-image-renderer-WGWRENOF.js → terminal-image-renderer-OGULCFNF.js} +37 -38
  253. package/chunks/{theme-manager-GBUFULSO.js → theme-manager-CNO3QERP.js} +35 -36
  254. package/chunks/{todoWrite-G7NT4IFP.js → todoWrite-5ERKFWAK.js} +3 -5
  255. package/chunks/{tool-search-6YUXHBPT.js → tool-search-VXWEOZE7.js} +9 -9
  256. package/chunks/{total-session-admission-54R2JQ5L.js → total-session-admission-4KAADZPB.js} +41 -42
  257. package/chunks/{trustedFolders-KAJIDJTH.js → trustedFolders-PPJSOPOT.js} +36 -37
  258. package/chunks/{update-relaunch-XM4IWBFD.js → update-relaunch-4PT4MW7B.js} +5 -5
  259. package/chunks/{updateCheck-W6UZFURI.js → updateCheck-WAVFLWNG.js} +37 -38
  260. package/chunks/{useAutoAcceptIndicator-LAWYHY3U.js → useAutoAcceptIndicator-XNED4NRB.js} +44 -45
  261. package/chunks/{validateNonInterActiveAuth-7WCKHRN2.js → validateNonInterActiveAuth-J676DUQ2.js} +74 -74
  262. package/chunks/{version-3ZU43RJ6.js → version-J6SRRQB2.js} +1 -1
  263. package/chunks/{web-fetch-QHI2SQL4.js → web-fetch-FMZZYX44.js} +7 -7
  264. package/chunks/{web-search-3KZZKWNY.js → web-search-3G2KXCX5.js} +19 -8
  265. package/chunks/{workflow-HRW7Y2X4.js → workflow-PPZZICQ7.js} +26 -27
  266. package/chunks/{workspace-providers-status-KTGCWCPC.js → workspace-providers-status-IIYTAQST.js} +46 -47
  267. package/chunks/{workspace-registration-store-LHLPPWNE.js → workspace-registration-store-VHCDXAV7.js} +1 -1
  268. package/chunks/{workspace-registry-X34MLN52.js → workspace-registry-I7VQIPS2.js} +41 -42
  269. package/chunks/{workspace-runtime-coordinator-U4PW4P7K.js → workspace-runtime-coordinator-DBGNY32G.js} +41 -42
  270. package/chunks/{workspace-service-KD7BCGYL.js → workspace-service-QSKB2T54.js} +47 -48
  271. package/chunks/{workspace-skills-status-YJGO6Y3T.js → workspace-skills-status-T7GPT65J.js} +43 -44
  272. package/chunks/{workspace-trust-reconciler-EUYHISCH.js → workspace-trust-reconciler-2PKRDAU4.js} +48 -49
  273. package/chunks/{write-file-EBSB34NJ.js → write-file-L76CGFTQ.js} +26 -27
  274. package/chunks/{zh-TW-W2GNP2IU.js → zh-TW-N2TBF2F2.js} +1 -1
  275. package/chunks/{zh-DVFYHRK5.js → zh-VBFCRQBL.js} +1 -1
  276. package/chunks/{zoom-image-UJ5VKWKP.js → zoom-image-TDJJY2VZ.js} +4 -4
  277. package/cli.js +13 -13
  278. package/export-transcript-document.js +126 -122
  279. package/locales/en.js +2 -2
  280. package/locales/zh-TW.js +2 -2
  281. package/locales/zh.js +2 -2
  282. package/package.json +3 -3
  283. package/web-shell/assets/{abnfDiagram-VCTEODGH-Dur--luQ.js → abnfDiagram-VCTEODGH-DHc6plZn.js} +1 -1
  284. package/web-shell/assets/{arc-tYLobxFi.js → arc-BQ9m8TDV.js} +1 -1
  285. package/web-shell/assets/{architectureDiagram-5GKGNRK7-IG6aXD03.js → architectureDiagram-5GKGNRK7-D5ap3oVB.js} +1 -1
  286. package/web-shell/assets/{blockDiagram-NRAW4CY4-C6eBSkfA.js → blockDiagram-NRAW4CY4-BIbnyNph.js} +1 -1
  287. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BrX3HJqB.js → c4Diagram-UCG6FXSJ-BRsdx_iG.js} +1 -1
  288. package/web-shell/assets/channel-uMMdTrYk.js +1 -0
  289. package/web-shell/assets/{chunk-2Q5K7J3B-B3fcJ8ee.js → chunk-2Q5K7J3B-3lf1fNlx.js} +1 -1
  290. package/web-shell/assets/{chunk-5VM5RSS4-CeC90yKM.js → chunk-5VM5RSS4-DP8VNRc4.js} +1 -1
  291. package/web-shell/assets/{chunk-F27PBJKO-CW44RVki.js → chunk-F27PBJKO-DrohDmZ6.js} +1 -1
  292. package/web-shell/assets/{chunk-G27WJ6UU-D1PAMukD.js → chunk-G27WJ6UU-UZ2QhSx6.js} +1 -1
  293. package/web-shell/assets/{chunk-JWPE2WC7-Dt3Y2Fvx.js → chunk-JWPE2WC7-BIMHVcZK.js} +1 -1
  294. package/web-shell/assets/{chunk-LCL6LL3I-CZHw2lLI.js → chunk-LCL6LL3I-izRxdSDd.js} +1 -1
  295. package/web-shell/assets/{chunk-POPQ4Y6H-ysNAdTGx.js → chunk-POPQ4Y6H-CXADD4PP.js} +1 -1
  296. package/web-shell/assets/{chunk-SVP7TREG-BdNXW6YQ.js → chunk-SVP7TREG-B96d8Y_1.js} +1 -1
  297. package/web-shell/assets/{chunk-XXDRQBXY-DgqQ9UA8.js → chunk-XXDRQBXY-CF2sVQpv.js} +1 -1
  298. package/web-shell/assets/classDiagram-DTDB5LWJ-DcY-26Ig.js +1 -0
  299. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DcY-26Ig.js +1 -0
  300. package/web-shell/assets/{cose-bilkent-JH36ORCC-BILImXzJ.js → cose-bilkent-JH36ORCC-CT6tXVAS.js} +1 -1
  301. package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
  302. package/web-shell/assets/{cynefin-OW5HDTMX-DR88Pund.js → cynefin-OW5HDTMX-X1NS4vtV.js} +1 -1
  303. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BYFbfkA6.js → cynefinDiagram-5FMLGOSQ-DNsKNOT4.js} +1 -1
  304. package/web-shell/assets/{dagre-3AP2YEHR-rfpyc6sX.js → dagre-3AP2YEHR-9-AHKqsb.js} +1 -1
  305. package/web-shell/assets/{diagram-S7CK7UJ4-BJxLmEwH.js → diagram-S7CK7UJ4-Bjgms7j6.js} +1 -1
  306. package/web-shell/assets/{diagram-UQ7AKVKN-H34xm7k3.js → diagram-UQ7AKVKN-h6bCprbE.js} +1 -1
  307. package/web-shell/assets/{diagram-VSXAHHWV-HYxhwNLx.js → diagram-VSXAHHWV-4SbQXVLt.js} +1 -1
  308. package/web-shell/assets/{diagram-VX7I27RA-BJazso8F.js → diagram-VX7I27RA-B5gPCzzB.js} +1 -1
  309. package/web-shell/assets/{diagram-Z3DM3KII-Clje1aNy.js → diagram-Z3DM3KII-DFJXIA3A.js} +1 -1
  310. package/web-shell/assets/{ebnfDiagram-PWID7BFC-M93YBkFh.js → ebnfDiagram-PWID7BFC-FwyaU7VY.js} +1 -1
  311. package/web-shell/assets/{erDiagram-SSCWMZ5O-DY8XzSHU.js → erDiagram-SSCWMZ5O-8vJQh2te.js} +1 -1
  312. package/web-shell/assets/{flowDiagram-A5DVABFB-CE6Aylcq.js → flowDiagram-A5DVABFB-BzA_1gMN.js} +1 -1
  313. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DI-5LL22.js → ganttDiagram-EL5Y4UJY-Co-ABbVX.js} +1 -1
  314. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-C7BZWElk.js → gitGraphDiagram-WWUBYQGX-DW_FcyrX.js} +1 -1
  315. package/web-shell/assets/{index-DclFHns9.js → index-BbMXfhNG.js} +1 -1
  316. package/web-shell/assets/{index-CVyqwW7y.js → index-Bu-rZoJ-.js} +483 -475
  317. package/web-shell/assets/index-CsPwZ1ut.css +36 -0
  318. package/web-shell/assets/{infoDiagram-RXCK75RN-CGUSy4Pc.js → infoDiagram-RXCK75RN-BEgfhUFN.js} +1 -1
  319. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-B5BVks9q.js → ishikawaDiagram-5VMMS53U-DCsMxQmc.js} +1 -1
  320. package/web-shell/assets/{journeyDiagram-EYS64GPL-CFh6Tf7h.js → journeyDiagram-EYS64GPL-DyIEYoHz.js} +1 -1
  321. package/web-shell/assets/{kanban-definition-3QL26DDD-B7TlxP7c.js → kanban-definition-3QL26DDD-CkxjqCNr.js} +1 -1
  322. package/web-shell/assets/{layout-Br_pZq2Q.js → layout-BEWc0Al9.js} +1 -1
  323. package/web-shell/assets/{linear-BVlP6fte.js → linear-CNuNxirL.js} +1 -1
  324. package/web-shell/assets/{mermaid.core-TrcYWoiF.js → mermaid.core-DZBre674.js} +6 -6
  325. package/web-shell/assets/{mindmap-definition-FBJOCRG2-BJ4LzqjZ.js → mindmap-definition-FBJOCRG2-CpafFz_F.js} +1 -1
  326. package/web-shell/assets/{pegDiagram-XKGWAZYB-1b_MxlOl.js → pegDiagram-XKGWAZYB-DfZqk_dq.js} +1 -1
  327. package/web-shell/assets/{pieDiagram-E7YTZNPT-B8zl0YhY.js → pieDiagram-E7YTZNPT-S0UWXlgC.js} +1 -1
  328. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-CIZO8ukl.js → quadrantDiagram-AXDQQJYC-dd37_Ohj.js} +1 -1
  329. package/web-shell/assets/{railroadDiagram-O6MQD6OU-CepHSbCj.js → railroadDiagram-O6MQD6OU-CH8NJZ7u.js} +1 -1
  330. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-BCgxkcSW.js → requirementDiagram-EFPCY7ZU-CFdqWYih.js} +1 -1
  331. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-CE5CcoMM.js → sankeyDiagram-P5KCCOFB-CsddcEGD.js} +1 -1
  332. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DvgHi-d5.js → sequenceDiagram-WJ2MYXX4-BZ270mGw.js} +1 -1
  333. package/web-shell/assets/{sizeCapture-X5ZJPWSS-T-fAsCPX.js → sizeCapture-X5ZJPWSS-CGaS4DBV.js} +1 -1
  334. package/web-shell/assets/{stateDiagram-HBIQ2CUA-DYHaul-5.js → stateDiagram-HBIQ2CUA-COpIzMu6.js} +1 -1
  335. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-D6qEVAji.js +1 -0
  336. package/web-shell/assets/{swimlanes-XN3QIQJK-Dbz3Qiej.js → swimlanes-XN3QIQJK-CMF889m3.js} +1 -1
  337. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-mem5Jj4m.js +8 -0
  338. package/web-shell/assets/{timeline-definition-24CTP7MA-9NVRts3N.js → timeline-definition-24CTP7MA-BelnxYz5.js} +1 -1
  339. package/web-shell/assets/{vennDiagram-4TSXK5OY-C7cb7vnH.js → vennDiagram-4TSXK5OY-CU-NRqIB.js} +1 -1
  340. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CG-8Ddjm.js → wardleyDiagram-VM6X3IG4-CDNKqWh-.js} +1 -1
  341. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-iGeYAcP4.js → xychartDiagram-S5SC5T6Z-CLqguL5D.js} +1 -1
  342. package/web-shell/index.html +6 -3
  343. package/chunks/chunk-3UMWOKJC.js +0 -78
  344. package/chunks/chunk-FKJM6JKY.js +0 -98
  345. package/chunks/chunk-IQAFKVXS.js +0 -22
  346. package/web-shell/assets/channel-uEkvKckd.js +0 -1
  347. package/web-shell/assets/classDiagram-DTDB5LWJ-DuPsnhWS.js +0 -1
  348. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DuPsnhWS.js +0 -1
  349. package/web-shell/assets/index-FO7JXPnH.css +0 -36
  350. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-BcYho9a4.js +0 -1
  351. 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-VDXYYVCD.js";
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: sanitizeStreamingImageMarkers(record.content),
7294
+ content: activeContent(record.phase, record.content, this.options.language, record.sourcePrefix),
7173
7295
  flowStatus: 2,
7174
- statusLine: this.statusLine(record, "Running").text,
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: sanitizeStreamingImageMarkers(record.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: sanitizeStreamingImageMarkers(record.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: [state, model, `${second}s`].filter(Boolean).join(" \xB7 "),
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, "Running");
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 ? { content: sanitizeStreamingImageMarkers(record.content) } : {},
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, "\u672C\u6B21\u5904\u7406\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002"));
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" ? "\u4EFB\u52A1\u5DF2\u505C\u6B62" : "\u4EFB\u52A1\u5DF2\u53D6\u6D88"));
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
- const title = extractTitle(outgoingText);
9040
- for (let i = 0; i < chunks.length; i++) {
9041
- const chunk = chunks[i];
9042
- const isMention = i === 0 && atUserId !== void 0;
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: i === 0 ? title : `${title} (cont.)`,
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
- const title = extractTitle(outgoingText);
9118
- for (let i = 0; i < chunks.length; i++) {
9119
- await this.sendProactiveChunk(target, i === 0 ? title : `${title} (cont.)`, chunks[i], `chunk ${i + 1}/${chunks.length}`);
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: ACK_REACTION_NAME,
9566
+ emotionName: tag.name,
9284
9567
  textEmotion: {
9285
- emotionId: ACK_EMOTION_ID,
9286
- emotionName: ACK_REACTION_NAME,
9287
- text: ACK_REACTION_NAME,
9288
- backgroundId: ACK_EMOTION_BG_ID
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
- await this.emotionApi("reply", msgId, conversationId);
9593
+ async attachReaction(msgId, conversationId, tag = EYE_TAG) {
9594
+ return this.emotionApi("reply", msgId, conversationId, tag);
9310
9595
  }
9311
- async recallReaction(msgId, conversationId) {
9312
- await this.emotionApi("recall", msgId, conversationId);
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.attachReaction(messageId, chatId).then(() => {
9367
- if (!this.activeReactionKeys.has(key)) {
9368
- void this.recallReaction(messageId, chatId).catch((err) => {
9369
- this.logReactionFailure("late reaction recall", err);
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
- stopReaction(chatId, messageId, sessionId) {
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
- if (sessionId) {
9382
- const keys = this.sessionReactionKeys.get(sessionId);
9383
- if (keys) {
9384
- keys.delete(key);
9385
- if (keys.size === 0)
9386
- this.sessionReactionKeys.delete(sessionId);
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
- this.recallReaction(messageId, chatId).catch((err) => {
9392
- this.logReactionFailure("reaction recall", err);
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 [key, { messageId, chatId }] of keys) {
9422
- if (this.activeReactionKeys.delete(key)) {
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.stopReaction(event.chatId, event.messageId, event.sessionId);
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 super.deliverBackgroundReply(chatId, text, sessionId, sourceLabel);
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",