@seanhogg/builderforce-agents 2026.10.9 → 2026.10.11

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 (437) hide show
  1. package/dist/{acp-cli-DcKpPsJa.js → acp-cli-C23mmrQt.js} +1 -1
  2. package/dist/{acp-cli-BxH-eUDl.js → acp-cli-D6F-D5JB.js} +1 -1
  3. package/dist/{agent-cXF-aL0g.js → agent-B-2r1Lr_.js} +1 -1
  4. package/dist/{agent-wJmvciTM.js → agent-BI9qSnSp.js} +1 -1
  5. package/dist/{agentbot-cli-Cub3Abbt.js → agentbot-cli-Cyrhr5jX.js} +1 -1
  6. package/dist/{agentbot-cli-CTRvEfBp.js → agentbot-cli-sC55m-XS.js} +1 -1
  7. package/dist/{agents-Cr7WO73I.js → agents-CMThT_Bj.js} +1 -1
  8. package/dist/agents-Chz9nfm2.js +1 -0
  9. package/dist/{api-key-rotation-CHBjUwUJ.js → api-key-rotation-CyCi-UqR.js} +1 -1
  10. package/dist/{audio-preflight-CWFuqbao.js → audio-preflight-B411b2-y.js} +1 -1
  11. package/dist/{audio-preflight-F2e3Y4CW.js → audio-preflight-Cs4eUjQk.js} +1 -1
  12. package/dist/{audit-DGnEhZYe.js → audit-B-USV03V.js} +1 -1
  13. package/dist/{audit-DBjjjW93.js → audit-SKNPS-K2.js} +1 -1
  14. package/dist/auth-choice-CChsMy-F.js +1 -0
  15. package/dist/{auth-choice-9gZuOvPS.js → auth-choice-CCib_yVL.js} +1 -1
  16. package/dist/auth-choice-DSnpkrMc.js +1 -0
  17. package/dist/{auth-choice-BoZFVmEa.js → auth-choice-DzBqqq7i.js} +1 -1
  18. package/dist/auth-choice.apply-6f3Jb_lS.js +1 -0
  19. package/dist/{auth-choice.apply-CcatXiNo.js → auth-choice.apply-BgOXoS8X.js} +1 -1
  20. package/dist/{auth-choice.apply-BHLQeym9.js → auth-choice.apply-DBuvopiF.js} +1 -1
  21. package/dist/auth-choice.apply-DeXnLwVS.js +1 -0
  22. package/dist/auth-choice.apply.transformers-CZDuBaOr.js +1 -0
  23. package/dist/{auth-choice.apply.transformers-CIn3fs7K.js → auth-choice.apply.transformers-Df9l_jRz.js} +2 -2
  24. package/dist/{auth-choice.apply.transformers-1plI0MUg.js → auth-choice.apply.transformers-DmdxpHGz.js} +2 -2
  25. package/dist/{auth-choice.apply.transformers-D5OrjEHo.js → auth-choice.apply.transformers-dn7l6XyJ.js} +1 -1
  26. package/dist/{auth-json-D1ite-pW.js → auth-json-BB-VBn5E.js} +1 -1
  27. package/dist/{auth-json-CN3MWw57.js → auth-json-BVyos95N.js} +1 -1
  28. package/dist/{auth-json-HGu227VM.js → auth-json-CoOe4tEg.js} +1 -1
  29. package/dist/{auth-json-DZ7E50Y1.js → auth-json-wrKixZxh.js} +1 -1
  30. package/dist/{auth-profiles-C1VbcUOm.js → auth-profiles-pt7Tr4HA.js} +1 -1
  31. package/dist/{auth-token-CyVfNEQb.js → auth-token-BE67qxLw.js} +1 -1
  32. package/dist/{auth-token-CoQ5ePPl.js → auth-token-BPHeoBAW.js} +1 -1
  33. package/dist/{banner-DY-L7_eI.js → banner-ErBINvbk.js} +1 -1
  34. package/dist/{browser-cli-D2O94twn.js → browser-cli-BZc64-Xx.js} +1 -1
  35. package/dist/{browser-cli-CoRx_4iM.js → browser-cli-CoxVKdon.js} +1 -1
  36. package/dist/build-info.json +3 -3
  37. package/dist/{builderforce-BmrsVdFw.js → builderforce-B9187Tm9.js} +4 -4
  38. package/dist/{builderforce-Bwyw0GJ6.js → builderforce-BLqHwgeu.js} +4 -4
  39. package/dist/builderforce-api-DKgXl8BH.js +1 -0
  40. package/dist/builderforce-api-DcPAGsla.js +1 -0
  41. package/dist/builderforce-onboarding-CaPJZSvw.js +24 -0
  42. package/dist/builderforce-onboarding-RXFb0gct.js +24 -0
  43. package/dist/{builderforcellm-syscheck-CprBhARf.js → builderforcellm-syscheck-9ksvqHYX.js} +1 -1
  44. package/dist/{builderforcellm-syscheck-DrFJ638L.js → builderforcellm-syscheck-F5JMAr3p.js} +1 -1
  45. package/dist/{call-DxPWzV-k.js → call-BnAs_SER.js} +1 -1
  46. package/dist/{call-DFjBq0H2.js → call-D1Opj5ev.js} +1 -1
  47. package/dist/{call-DmAU4cRX.js → call-Du2LiaX6.js} +1 -1
  48. package/dist/{call-BbRf8gFM.js → call-T8ciwMTA.js} +1 -1
  49. package/dist/{channel-options-d4EwVQD0.js → channel-options-B7sRMp2v.js} +1 -1
  50. package/dist/{channel-options-CDixz6dT.js → channel-options-rhDBCtlp.js} +1 -1
  51. package/dist/{channel-web-DJa8JC9W.js → channel-web-CcCqUQrJ.js} +1 -1
  52. package/dist/{channels-cli-BgKy0MbE.js → channels-cli-BjnLW14T.js} +1 -1
  53. package/dist/{channels-cli-nNW0ezPM.js → channels-cli-DVWUBsmc.js} +1 -1
  54. package/dist/{chrome-BnEbJV3D.js → chrome-CFmcixaE.js} +1 -1
  55. package/dist/{chrome-a3X9_-nf.js → chrome-DXt86tmV.js} +1 -1
  56. package/dist/cli/daemon-cli.js +1 -1
  57. package/dist/{cli-DkWt7p2x.js → cli-BUqtALJK.js} +1 -1
  58. package/dist/{cli-C5MbcECQ.js → cli-K4reS6IS.js} +1 -1
  59. package/dist/{coding-tools.policy-NEPm7Mz1.js → coding-tools.policy-D9Ba8eDh.js} +1 -1
  60. package/dist/{coding-tools.policy-6qh9acJy.js → coding-tools.policy-ZhOdlcEI.js} +1 -1
  61. package/dist/{command-registry-COUcUWby.js → command-registry-B7uAoROP.js} +1 -1
  62. package/dist/{command-registry-4_K-lfW5.js → command-registry-CW16Mk2Y.js} +1 -1
  63. package/dist/{completion-cli-DlvHqL86.js → completion-cli-ZvXrCQqk.js} +1 -1
  64. package/dist/{completion-cli-B2qcVd6q.js → completion-cli-gyvx5ZXu.js} +1 -1
  65. package/dist/{completion-cli-DpFvU4Qn.js → completion-cli-n8UsdT91.js} +1 -1
  66. package/dist/{completion-cli-SdcQ-kQj.js → completion-cli-sKReGv3d.js} +1 -1
  67. package/dist/{config-_1Ca6jGb.js → config-BgV_FYSq.js} +1 -1
  68. package/dist/{config-toczWD3q.js → config-BpChMIJ6.js} +1 -1
  69. package/dist/{config-BTWlKwtB.js → config-D01EgOky.js} +1 -1
  70. package/dist/{config-27_FNba3.js → config-Dsnbi-a3.js} +1 -1
  71. package/dist/{config-cli-DeiQz5sY.js → config-cli-Bpo74mE5.js} +1 -1
  72. package/dist/{config-cli-CfczShaZ.js → config-cli-CF31O_5s.js} +1 -1
  73. package/dist/{config-guard-CD-Wq8kk.js → config-guard-BRUOk5YL.js} +1 -1
  74. package/dist/{config-guard-ClVl2FvD.js → config-guard-BUpQiSTW.js} +1 -1
  75. package/dist/{config-guard-B4in8l8I.js → config-guard-USCN-dq0.js} +1 -1
  76. package/dist/{config-validation-jpeXzoU3.js → config-validation-BGpSeNbh.js} +1 -1
  77. package/dist/{config-validation-C6u-z9bJ.js → config-validation-CdBJ-tZq.js} +1 -1
  78. package/dist/{configure-3W9C5LiT.js → configure-CWr61Ph2.js} +1 -1
  79. package/dist/configure-DhazB2qh.js +1 -0
  80. package/dist/{configure-BtXQW7ue.js → configure-DlcO1tWx.js} +1 -1
  81. package/dist/configure-MXheujvX.js +1 -0
  82. package/dist/{control-service-CJuuqNOE.js → control-service-2PkCt256.js} +1 -1
  83. package/dist/{control-service-qKfWP7VD.js → control-service-CcsbseZS.js} +1 -1
  84. package/dist/{control-service-izGyCWQs.js → control-service-qK1oboMo.js} +1 -1
  85. package/dist/{control-service-BbsswoMy.js → control-service-y3GYvIBg.js} +1 -1
  86. package/dist/{cron-cli-BrOM4s6N.js → cron-cli-BYu_lA8i.js} +1 -1
  87. package/dist/{cron-cli-CwtTX6pg.js → cron-cli-D_Og20iB.js} +1 -1
  88. package/dist/{daemon-cli-DyVsMf8p.js → daemon-cli-BNzthScZ.js} +1 -1
  89. package/dist/{daemon-cli-DlwOVDbt.js → daemon-cli-Bh3p0hui.js} +1 -1
  90. package/dist/{daemon-cli-Br0wu9xQ.js → daemon-cli-DxxKiKVN.js} +1 -1
  91. package/dist/{daemon-cli-DmicpZED.js → daemon-cli-emNxLkIw.js} +1 -1
  92. package/dist/{daemon-runtime-CtOr1ncS.js → daemon-runtime-9XitJmIL.js} +1 -1
  93. package/dist/{daemon-runtime-B4UjqdyJ.js → daemon-runtime-Dx800VUt.js} +1 -1
  94. package/dist/{deliver-BpLm3ktn.js → deliver--6OBF3LL.js} +1 -1
  95. package/dist/{deliver-9o_SE4ZK.js → deliver-ADpnRGRf.js} +1 -1
  96. package/dist/{deliver-D2VAVelb.js → deliver-BM6-damm.js} +1 -1
  97. package/dist/{deliver-BuZu68tp.js → deliver-CsG0cHbZ.js} +1 -1
  98. package/dist/{deps-CkJiJ6wc.js → deps-Dg_9rfXK.js} +1 -1
  99. package/dist/{devices-cli-BfXeDnbx.js → devices-cli-B8DXzcRP.js} +1 -1
  100. package/dist/{devices-cli-B9G6YOsS.js → devices-cli-BZkdWSx-.js} +1 -1
  101. package/dist/{directory-cli-BRCaiGOn.js → directory-cli-B78pAVI_.js} +1 -1
  102. package/dist/{directory-cli-D5ciZ5fY.js → directory-cli-CSaRkkL8.js} +1 -1
  103. package/dist/{dm-policy-shared-CRZpjRv0.js → dm-policy-shared-B9lW-AsK.js} +1 -1
  104. package/dist/{dm-policy-shared-Dhw9_6mi.js → dm-policy-shared-DYZ_T-az.js} +1 -1
  105. package/dist/{dns-cli-CgZ7oMcT.js → dns-cli-CLPGOFA1.js} +1 -1
  106. package/dist/{dns-cli-C4f4Tyij.js → dns-cli-dr5dHzfI.js} +1 -1
  107. package/dist/{doctor-completion-BSotFS6p.js → doctor-completion-94zme499.js} +1 -1
  108. package/dist/{doctor-completion-DVxbs-74.js → doctor-completion-CbF34DIH.js} +1 -1
  109. package/dist/{embedded-helpers-CEsr3aQ0.js → embedded-helpers-C9jpiwlw.js} +1 -1
  110. package/dist/{embedded-helpers-DK8_apW0.js → embedded-helpers-DdU30lmt.js} +1 -1
  111. package/dist/entry.js +1 -1
  112. package/dist/{exec-approvals-cli-YuOu7mVg.js → exec-approvals-cli-CS_uabo7.js} +1 -1
  113. package/dist/{exec-approvals-cli-BPFi82B0.js → exec-approvals-cli-ktB7M7WE.js} +1 -1
  114. package/dist/{gateway-cli-D2Bg1Um6.js → gateway-cli-CKcoLVMA.js} +5 -5
  115. package/dist/{gateway-cli-DFEo8C0z.js → gateway-cli-CuXBDBWe.js} +5 -5
  116. package/dist/{gateway-rpc-BXR_lVIx.js → gateway-rpc-B02y0PnE.js} +1 -1
  117. package/dist/{gateway-rpc-ByUcnQ7W.js → gateway-rpc-ff1RVb0_.js} +1 -1
  118. package/dist/{gemini-auth-CkD5jCPh.js → gemini-auth-DDR12zst.js} +1 -1
  119. package/dist/health-D0DZmCmh.js +1 -0
  120. package/dist/{health-yS3NRKvY.js → health-FO8MG5Ur.js} +1 -1
  121. package/dist/{health-DVo8a9yg.js → health-zrsgFZmR.js} +1 -1
  122. package/dist/{hooks-cli-B0lVee-j.js → hooks-cli-5Y4hnSX9.js} +1 -1
  123. package/dist/{hooks-cli-DsVmrQAG.js → hooks-cli-DpHZzRo2.js} +1 -1
  124. package/dist/index.js +2 -2
  125. package/dist/{ink-session-BitZ1wcY.js → ink-session-Dt9Q4iH-.js} +2 -2
  126. package/dist/{ink-session-CyAqXDla.js → ink-session-N8wCBzwk.js} +2 -2
  127. package/dist/{installs-CWd54ARy.js → installs-B_t2YXgq.js} +1 -1
  128. package/dist/{installs-C9A8QFiF.js → installs-DFiF4lGy.js} +1 -1
  129. package/dist/{io-3R_ZyUxB.js → io-BLBq4T2o.js} +1 -1
  130. package/dist/{io-DSIGyPrT.js → io-CXN4uLS2.js} +1 -1
  131. package/dist/{io-6jLoKffb.js → io-Ckd4NlvH.js} +1 -1
  132. package/dist/{io-CohJffHG.js → io-D9hC2aG0.js} +1 -1
  133. package/dist/{lifecycle-core-BpMvDXy1.js → lifecycle-core-D9Dg5Qps.js} +1 -1
  134. package/dist/{lifecycle-core-Dwb4gHjZ.js → lifecycle-core-uxjxTzFv.js} +1 -1
  135. package/dist/login-B3sDAgHb.js +1 -0
  136. package/dist/{login-C_ZdMOvv.js → login-CwwuaXtb.js} +1 -1
  137. package/dist/{login-DtDUyFO3.js → login-D1bVUPlv.js} +1 -1
  138. package/dist/{login-CEnjUo5c.js → login-GLDax56V.js} +1 -1
  139. package/dist/{login-qr-B9lyIZVD.js → login-qr-CbiUcBLy.js} +1 -1
  140. package/dist/{login-qr-BCBsxwhT.js → login-qr-Cp0YqK4e.js} +1 -1
  141. package/dist/{logs-cli-CdM5W3HE.js → logs-cli-Cy11HfSG.js} +1 -1
  142. package/dist/{logs-cli-jh5Xn3TD.js → logs-cli-nD36c-Y1.js} +1 -1
  143. package/dist/{manager-CRba8roB.js → manager-BeohB4-8.js} +1 -1
  144. package/dist/{manager-B3IJ_IKf.js → manager-CTTXDBt3.js} +1 -1
  145. package/dist/{manager-TGVy_fAb.js → manager-CoQMlcrf.js} +1 -1
  146. package/dist/{manager-DwywI_5-.js → manager-DSz61dXv.js} +1 -1
  147. package/dist/{memory-cli-BlayFTAM.js → memory-cli-BpAiRntI.js} +1 -1
  148. package/dist/{memory-cli-DRz4wtHk.js → memory-cli-CbkWGjRn.js} +1 -1
  149. package/dist/{memory-cli-PdyTQ84w.js → memory-cli-CrBMLM2P.js} +1 -1
  150. package/dist/{memory-cli-ivAs7q7v.js → memory-cli-CveeVOWH.js} +1 -1
  151. package/dist/{model-catalog-CQOdhMUY.js → model-catalog-B29yeBYS.js} +1 -1
  152. package/dist/{model-catalog-CiiFJX77.js → model-catalog-BeBXvbFm.js} +1 -1
  153. package/dist/model-catalog-CMKHKuBL.js +1 -0
  154. package/dist/{model-catalog-C6UrZ0uG.js → model-catalog-DjNiebr7.js} +1 -1
  155. package/dist/{model-discovery-C9Xm95uL.js → model-discovery-D0i1JpiL.js} +1 -1
  156. package/dist/{model-picker-swoSwauV.js → model-picker-CGDNPRPc.js} +1 -1
  157. package/dist/model-picker-CGEF8yhc.js +1 -0
  158. package/dist/model-picker-DeUNOC78.js +1 -0
  159. package/dist/{model-picker-BUePD7Zg.js → model-picker-EIhpfOZa.js} +1 -1
  160. package/dist/{model-selection-9bRFKBI_.js → model-selection-DG9J_VTz.js} +1 -1
  161. package/dist/{models-BNivsd2o.js → models-BjIzVQYX.js} +2 -2
  162. package/dist/{models-DQeSIY6M.js → models-JoqOgEF5.js} +1 -1
  163. package/dist/{models-cli-KokGgWeP.js → models-cli-B2zbchgs.js} +1 -1
  164. package/dist/{models-cli-BcNxU4P_.js → models-cli-CkFdc8NN.js} +2 -2
  165. package/dist/{node-cli-DIMh3X2F.js → node-cli-CXnuxiBq.js} +1 -1
  166. package/dist/{node-cli-EmTU-Gh0.js → node-cli-oVyjVnb7.js} +1 -1
  167. package/dist/{nodes-cli-BX8TznFK.js → nodes-cli-BBVotxNt.js} +1 -1
  168. package/dist/{nodes-cli-DyHovdAc.js → nodes-cli-DVMBSUhK.js} +1 -1
  169. package/dist/{onboard-DfMVh1bM.js → onboard-BItclJp0.js} +1 -1
  170. package/dist/{onboard-BVmZ4jMw.js → onboard-CqvHIvKj.js} +1 -1
  171. package/dist/{onboard-auth.credentials-yagR-VMG.js → onboard-auth.credentials-DneFSdYg.js} +1 -1
  172. package/dist/{onboard-auth.credentials-BuT-etnE.js → onboard-auth.credentials-DpitLlzw.js} +1 -1
  173. package/dist/onboard-channels-B91m5S3w.js +1 -0
  174. package/dist/onboard-channels-BOoPtYbF.js +1 -0
  175. package/dist/{onboard-channels-B6QDFkkK.js → onboard-channels-Dn0u5C-C.js} +1 -1
  176. package/dist/{onboard-channels-C8FCFn29.js → onboard-channels-vhtccaIV.js} +1 -1
  177. package/dist/onboard-custom-BN0uzSq_.js +1 -0
  178. package/dist/{onboard-custom-D1nd8Hlu.js → onboard-custom-BYIza2e7.js} +1 -1
  179. package/dist/onboard-custom-CCFthqto.js +1 -0
  180. package/dist/{onboard-custom-C_BI0ZXn.js → onboard-custom-Ckf0xKXY.js} +1 -1
  181. package/dist/{onboard-helpers-CGlLpagb.js → onboard-helpers-B8I5AVyb.js} +1 -1
  182. package/dist/{onboard-helpers-CckrS8_K.js → onboard-helpers-Ce_c4Raj.js} +1 -1
  183. package/dist/{onboard-helpers-Cf5dNq7-.js → onboard-helpers-CiHzTaFX.js} +1 -1
  184. package/dist/{onboard-helpers-BvIZ4-R5.js → onboard-helpers-DC-nMl-V.js} +1 -1
  185. package/dist/{onboard-interactive-DYJttZ2w.js → onboard-interactive-Cl2K3EYn.js} +1 -1
  186. package/dist/{onboard-interactive-zgjmwJz-.js → onboard-interactive-JNux9zfA.js} +1 -1
  187. package/dist/{onboard-interactive-B3-KBZbZ.js → onboard-interactive-J_ObFzeW.js} +1 -1
  188. package/dist/{onboard-interactive-Dc_7URYb.js → onboard-interactive-OUNsvlh0.js} +1 -1
  189. package/dist/{onboard-remote-D5lR2lVm.js → onboard-remote-0-q7MG9t.js} +1 -1
  190. package/dist/{onboard-remote-BmSyHww1.js → onboard-remote-CgAAEZpq.js} +1 -1
  191. package/dist/{onboard-remote-CzzQMZ3X.js → onboard-remote-DKXHDdBD.js} +1 -1
  192. package/dist/{onboard-remote-DcuX8b2g.js → onboard-remote-cB8j9RG-.js} +1 -1
  193. package/dist/{onboard-skills-ILHIeg1R.js → onboard-skills-47upVdA2.js} +1 -1
  194. package/dist/{onboard-skills-BPlNN_-T.js → onboard-skills-9Um4TL2x.js} +1 -1
  195. package/dist/{onboard-skills-DIhjDMom.js → onboard-skills-DhCmvhJY.js} +1 -1
  196. package/dist/{onboard-skills-CI1OtWsE.js → onboard-skills-mI2kfvdT.js} +1 -1
  197. package/dist/{onboarding-D4-HDbmU.js → onboarding-BSENgR9C.js} +5 -5
  198. package/dist/{onboarding-CP9rrz8y.js → onboarding-CIaZLNc1.js} +5 -5
  199. package/dist/{onboarding.finalize-C2kZi7F0.js → onboarding.finalize-BwOpvoPE.js} +1 -1
  200. package/dist/{onboarding.finalize-BfWXPgX7.js → onboarding.finalize-yMK-g7Uy.js} +1 -1
  201. package/dist/{onboarding.gateway-config-Cd7_bXVs.js → onboarding.gateway-config-Kn1O-QFl.js} +1 -1
  202. package/dist/{onboarding.gateway-config-Bd8HJkso.js → onboarding.gateway-config-huOjFf8D.js} +1 -1
  203. package/dist/{openai-model-default-Cp3nf21W.js → openai-model-default-CH2-2Hvk.js} +1 -1
  204. package/dist/{openai-model-default-BMRrqTmH.js → openai-model-default-pfoEzWYJ.js} +1 -1
  205. package/dist/{outbound-BRInCJD9.js → outbound-BdeHcMAo.js} +1 -1
  206. package/dist/{outbound-CAtBpFoD.js → outbound-BylJYD7n.js} +1 -1
  207. package/dist/{outbound-OI-t5zZ0.js → outbound-CAirtWr1.js} +1 -1
  208. package/dist/{outbound-CnIvOJlU.js → outbound-VNcvF2MG.js} +1 -1
  209. package/dist/{outbound-send-deps-m6DqOma_.js → outbound-send-deps-B3Lg-uqF.js} +1 -1
  210. package/dist/{pairing-cli-CEr0yEsc.js → pairing-cli-5RtPvz2i.js} +1 -1
  211. package/dist/{pairing-cli-Dxfoni-F.js → pairing-cli-C_Mj6Dy4.js} +1 -1
  212. package/dist/{pairing-labels-3j_iRYOO.js → pairing-labels-BJPrScRl.js} +1 -1
  213. package/dist/{pairing-labels-BW5jQZlr.js → pairing-labels-oA-nKTaW.js} +1 -1
  214. package/dist/{pairing-store-QDb6lhIU.js → pairing-store-YRy7EBgI.js} +1 -1
  215. package/dist/{pairing-store-CbvMJhD3.js → pairing-store-ti3FEkmr.js} +1 -1
  216. package/dist/{plugin-auto-enable-BV9K9Vhr.js → plugin-auto-enable-Cupr4wbt.js} +1 -1
  217. package/dist/{plugin-auto-enable-DDry2fA6.js → plugin-auto-enable-D8gKiE3F.js} +1 -1
  218. package/dist/plugin-registry-BEfyc2f_.js +1 -0
  219. package/dist/{plugin-registry-C-_GA65s.js → plugin-registry-BoPaef5I.js} +1 -1
  220. package/dist/{plugin-registry-SAdxNUwm.js → plugin-registry-CxnuHO_n.js} +1 -1
  221. package/dist/plugin-registry-D0tIqo8L.js +1 -0
  222. package/dist/plugin-sdk/{accounts-Cy3WCbWg.js → accounts-BwreSNAR.js} +1 -1
  223. package/dist/plugin-sdk/{active-listener-DVWVNlT9.js → active-listener-DpQ7aGYd.js} +1 -1
  224. package/dist/plugin-sdk/agent-runtime/src/infra/workflow-telemetry.d.ts +12 -1
  225. package/dist/plugin-sdk/{agent-scope-DgKN27hJ.js → agent-scope-BQByW0cD.js} +1 -1
  226. package/dist/plugin-sdk/{api-key-rotation-ftXf7mBZ.js → api-key-rotation-7YdImWrh.js} +1 -1
  227. package/dist/plugin-sdk/{audio-preflight-CfTmmeS-.js → audio-preflight-EbkaATDO.js} +1 -1
  228. package/dist/plugin-sdk/{auth-json-BrNBg87n.js → auth-json-DK6qod1_.js} +1 -1
  229. package/dist/plugin-sdk/{bindings-CH-YLOLC.js → bindings-CDEzl4kl.js} +1 -1
  230. package/dist/plugin-sdk/{channel-web-B6rg0Rbf.js → channel-web-D2KuONp0.js} +1 -1
  231. package/dist/plugin-sdk/{chrome-CuXP-hes.js → chrome-SOXFIkUM.js} +1 -1
  232. package/dist/plugin-sdk/{chunk-C94IAOuf.js → chunk-cW0POl22.js} +1 -1
  233. package/dist/plugin-sdk/{command-format-B3XMq_73.js → command-format-CAX9XFjI.js} +1 -1
  234. package/dist/plugin-sdk/{common-n0l_XN-S.js → common-BxEWhN2X.js} +1 -1
  235. package/dist/plugin-sdk/{config-DsXZsCkJ.js → config-v1EU9Ll8.js} +2 -2
  236. package/dist/plugin-sdk/{fetch-B-GxSYRO.js → fetch-DH0Y8iyO.js} +1 -1
  237. package/dist/plugin-sdk/index.js +1 -1
  238. package/dist/plugin-sdk/{login-_my8QwPP.js → login-d1zBgykF.js} +1 -1
  239. package/dist/plugin-sdk/{login-qr-BaePtXuG.js → login-qr-B6exvQnN.js} +1 -1
  240. package/dist/plugin-sdk/{manager-BsC-4ymy.js → manager-BH_bmGds.js} +1 -1
  241. package/dist/plugin-sdk/{markdown-tables-BUfhHgfs.js → markdown-tables-Epim9b-0.js} +1 -1
  242. package/dist/plugin-sdk/{message-channel-CuZ2xOAM.js → message-channel-sBPQc_-T.js} +1 -1
  243. package/dist/plugin-sdk/{model-catalog-yuiXVcmw.js → model-catalog-cXsza5GU.js} +1 -1
  244. package/dist/plugin-sdk/{model-selection-BtgvnqB5.js → model-selection-K82MAGlL.js} +1 -1
  245. package/dist/plugin-sdk/{outbound-D_attiyO.js → outbound-Chn_H1O7.js} +1 -1
  246. package/dist/plugin-sdk/{plugins-BdkC9v5E.js → plugins-CaUOZBVb.js} +1 -1
  247. package/dist/plugin-sdk/{pw-ai-A7Rathx6.js → pw-ai-BIiJF7ZD.js} +1 -1
  248. package/dist/plugin-sdk/{qmd-manager-Dxn0jCpE.js → qmd-manager-BRe5fGZw.js} +1 -1
  249. package/dist/plugin-sdk/{registry-CZHRcH-q.js → registry-DJq2Cvo9.js} +1 -1
  250. package/dist/plugin-sdk/{render-CuA_WRX5.js → render-BUCRXPIk.js} +1 -1
  251. package/dist/plugin-sdk/{replies-DmLfO-pg.js → replies-Cz5OD3qN.js} +1 -1
  252. package/dist/plugin-sdk/{reply-3-ne-N_7.js → reply-D5Uk7pUv.js} +9 -9
  253. package/dist/plugin-sdk/{reply-prefix-w7kAvH11.js → reply-prefix-CCymsmsP.js} +1 -1
  254. package/dist/plugin-sdk/{resolve-route-0sbvl4ZN.js → resolve-route-DN1J7Wyc.js} +1 -1
  255. package/dist/plugin-sdk/{runner-4UfrAQnx.js → runner-CYkuO7Fh.js} +4 -4
  256. package/dist/plugin-sdk/{session-BB-yfDWx.js → session-D5jHDo78.js} +1 -1
  257. package/dist/plugin-sdk/{sqlite-JjFgDV-H.js → sqlite-BlMLqMl8.js} +1 -1
  258. package/dist/plugin-sdk/{subsystem-D0Ril4rt.js → subsystem-COTa5Ly_.js} +1 -1
  259. package/dist/plugin-sdk/{tool-images-WRTP95FT.js → tool-images-DSpchb4x.js} +1 -1
  260. package/dist/plugin-sdk/{tool-loop-detection-sC_rhJfb.js → tool-loop-detection-BP6u-mbh.js} +1 -1
  261. package/dist/plugin-sdk/web-BbganhKi.js +1 -0
  262. package/dist/plugin-sdk/{whatsapp-actions-ThxQ5niy.js → whatsapp-actions-CZUqxmP1.js} +1 -1
  263. package/dist/{plugins-BIG8NDB9.js → plugins-Cx29kkDj.js} +1 -1
  264. package/dist/{plugins-iAq-Gr8l.js → plugins-DJqou2hi.js} +1 -1
  265. package/dist/{plugins-cli-CpaVUv_r.js → plugins-cli-Bu-A8aGy.js} +1 -1
  266. package/dist/{plugins-cli-CPkSgvdL.js → plugins-cli-CGFsQDVW.js} +1 -1
  267. package/dist/{program-context-BCwL3wlM.js → program-context-ClBa4lUj.js} +1 -1
  268. package/dist/{program-2w7Ue902.js → program-vVCzU0cH.js} +2 -2
  269. package/dist/{prompt-select-styled-hB_nLOn1.js → prompt-select-styled-BJPGccTJ.js} +1 -1
  270. package/dist/{prompt-select-styled-Dd5swW2b.js → prompt-select-styled-BK74z6FF.js} +1 -1
  271. package/dist/{provider-auth-helpers-BpTnp2Yr.js → provider-auth-helpers-B84m5VMc.js} +1 -1
  272. package/dist/{provider-auth-helpers-CJTG_tVx.js → provider-auth-helpers-hNwpK_hl.js} +1 -1
  273. package/dist/{provider-dispatcher-TWwBT2aH.js → provider-dispatcher-BjR5DE3O.js} +1 -1
  274. package/dist/provider-dispatcher-DgOeVjcL.js +1 -0
  275. package/dist/{provider-usage-BdrU4cIE.js → provider-usage-B-wPVN_j.js} +1 -1
  276. package/dist/{provider-usage-Bn4ZrnU7.js → provider-usage-B8lFHp0K.js} +1 -1
  277. package/dist/{push-apns-C4sJnHbO.js → push-apns-BTPPvY81.js} +1 -1
  278. package/dist/{push-apns-CiD3rrVv.js → push-apns-CscYUS0D.js} +1 -1
  279. package/dist/{pw-ai-DSEj1QrV.js → pw-ai-CLS_VZ8p.js} +1 -1
  280. package/dist/{pw-ai-dNZY-qBs.js → pw-ai-D5og_rIf.js} +1 -1
  281. package/dist/{qr-cli-qr-SFLZW.js → qr-cli-CAquM1Zk.js} +1 -1
  282. package/dist/{qr-cli-B45dCV0o.js → qr-cli-GsR8n1cm.js} +1 -1
  283. package/dist/{qr-cli-CMlAIzrD.js → qr-cli-kAKgaL-T.js} +1 -1
  284. package/dist/{qr-cli-CySNSEFj.js → qr-cli-uyxNf-cQ.js} +1 -1
  285. package/dist/{register.agent-BA6LIJSb.js → register.agent-BwTCfyeJ.js} +1 -1
  286. package/dist/{register.agent-D2uCH8jZ.js → register.agent-Dhdo3_7k.js} +1 -1
  287. package/dist/register.configure-B0m0G3ot.js +1 -0
  288. package/dist/register.configure-D3cbjmTz.js +1 -0
  289. package/dist/{register.maintenance-BELfCO_C.js → register.maintenance-C6ocMld2.js} +1 -1
  290. package/dist/{register.maintenance-DukWFS_D.js → register.maintenance-CbE2zSyc.js} +1 -1
  291. package/dist/{register.message-DiZRRAE5.js → register.message-Jn4u533_.js} +1 -1
  292. package/dist/{register.message-8iGDhO8h.js → register.message-Tu1hlM0m.js} +1 -1
  293. package/dist/{register.onboard-B9DMNfHE.js → register.onboard-B34211N6.js} +1 -1
  294. package/dist/{register.onboard-Dt7rzAq-.js → register.onboard-S1d2WAE4.js} +1 -1
  295. package/dist/{register.setup-CSF-2ImP.js → register.setup-CJPyAwCQ.js} +1 -1
  296. package/dist/{register.setup-BRRVPrx7.js → register.setup-Sg8f3nsH.js} +1 -1
  297. package/dist/{register.status-health-sessions-D6wdwPwV.js → register.status-health-sessions-BlgVxoZ4.js} +1 -1
  298. package/dist/{register.status-health-sessions-ZSufYw5j.js → register.status-health-sessions-DwADQJ74.js} +1 -1
  299. package/dist/{register.subclis-4eDV9jKH.js → register.subclis-C9V_M-Lk.js} +1 -1
  300. package/dist/{register.subclis-Cr9DoYcv.js → register.subclis-pWn9XObB.js} +1 -1
  301. package/dist/{replies-DbkT_5BV.js → replies-BOGMDhSN.js} +1 -1
  302. package/dist/{replies-CzV-RFUG.js → replies-BXbV02ik.js} +1 -1
  303. package/dist/{replies-DIBQzxGp.js → replies-CUv671JF.js} +1 -1
  304. package/dist/{replies-Bd2RPZwQ.js → replies-DokbEfJD.js} +1 -1
  305. package/dist/{reply-Cd3vVnD7.js → reply-GY1C8tcv.js} +10 -10
  306. package/dist/{routes-BzfLvF8W.js → routes-DZntyPY6.js} +1 -1
  307. package/dist/{routes-lclJHOYY.js → routes-_iZdG1Fo.js} +1 -1
  308. package/dist/{rpc-BLqXRn5R.js → rpc-CbUnwStf.js} +1 -1
  309. package/dist/{rpc-DcQNGQlj.js → rpc-Cwm4gchc.js} +1 -1
  310. package/dist/{run-main-DLcDEJgv.js → run-main-DQMbgbcF.js} +1 -1
  311. package/dist/{runner-DwWmciCt.js → runner-Cu9NJouV.js} +1 -1
  312. package/dist/{runner-SxCr9kXD.js → runner-eTTUbLAK.js} +1 -1
  313. package/dist/{sandbox-BZibn6PX.js → sandbox-C4AKi2EX.js} +1 -1
  314. package/dist/{sandbox-z9t_PRf9.js → sandbox-DvKMuAXL.js} +1 -1
  315. package/dist/{sandbox-cli-BtGs0dBR.js → sandbox-cli-C0LhzYq_.js} +1 -1
  316. package/dist/{sandbox-cli-B8FpLgyY.js → sandbox-cli-De0iaoHB.js} +1 -1
  317. package/dist/{security-cli-D8Q8I7fn.js → security-cli-BvEfiO8m.js} +1 -1
  318. package/dist/{security-cli-IIMR7Pb4.js → security-cli-BzsQ0XQh.js} +1 -1
  319. package/dist/{send-DnMzjS7L.js → send-2dRKMWtl.js} +1 -1
  320. package/dist/{send-DerUBvXW.js → send-Aw8wK3vK.js} +1 -1
  321. package/dist/{send-BvroeIQ6.js → send-B7H8Ae5j.js} +1 -1
  322. package/dist/{send-4d9NswaD.js → send-BP5osGBo.js} +1 -1
  323. package/dist/{send-BU_-BGmf.js → send-BVal50Bi.js} +1 -1
  324. package/dist/{send-CxG2suVM.js → send-Bbo7TXLx.js} +1 -1
  325. package/dist/{send-CBBziNqM.js → send-BxoVLIy1.js} +1 -1
  326. package/dist/{send-dDpSBSBo.js → send-COKUbcqs.js} +1 -1
  327. package/dist/{send--12DIueA.js → send-CTw3PqN4.js} +1 -1
  328. package/dist/{send-UFtylOiq.js → send-CYGOPcKq.js} +1 -1
  329. package/dist/{send-DyF1Xy9K.js → send-ChGpVO3O.js} +1 -1
  330. package/dist/{send-Q-uTkSFE.js → send-Cqea2UFo.js} +1 -1
  331. package/dist/{send-j15662lv.js → send-CrFWgJKx.js} +1 -1
  332. package/dist/{send-gDb60Hk-.js → send-CwK8QBR3.js} +1 -1
  333. package/dist/{send-CceNWtYE.js → send-DqR7Rxzm.js} +1 -1
  334. package/dist/{send-CJHXQvVl.js → send-DxwfUIN-.js} +1 -1
  335. package/dist/{send-ByCVQQVz.js → send-KgN1P41U.js} +1 -1
  336. package/dist/{send-B1rJLLpr.js → send-bNp87SIq.js} +1 -1
  337. package/dist/{send-B_1BtyfA.js → send-kkm_zrHQ.js} +1 -1
  338. package/dist/{send-BJDzwYJN.js → send-l3ge4wkC.js} +1 -1
  339. package/dist/{server-context-DJZT7Upf.js → server-context-CQ2v4BAx.js} +1 -1
  340. package/dist/{server-context-owOmmyUM.js → server-context-CttALzrW.js} +1 -1
  341. package/dist/{server-node-events-54d8Rmjl.js → server-node-events-CIMO6Vae.js} +1 -1
  342. package/dist/{server-node-events-CSFVqgxX.js → server-node-events-iCF2ngcN.js} +1 -1
  343. package/dist/{session-BzQdcCqN.js → session-BJHsjD3z.js} +1 -1
  344. package/dist/{session-4FpEJvkE.js → session-C_b1ttHJ.js} +1 -1
  345. package/dist/{session-dirs-OxQuIvJW.js → session-dirs-Bvbgw0GC.js} +1 -1
  346. package/dist/{session-dirs-D_ARkyw0.js → session-dirs-DHaoq7zc.js} +1 -1
  347. package/dist/{session-utils-GMvum00v.js → session-utils-Dxou8SbO.js} +1 -1
  348. package/dist/{sessions-Bl1wwotX.js → sessions-BA8Se_bT.js} +1 -1
  349. package/dist/{sessions-CdanN_ZI.js → sessions-BuZVmOWt.js} +1 -1
  350. package/dist/{sessions-B5dwRhUC.js → sessions-DvbW0FNJ.js} +1 -1
  351. package/dist/{sessions-B1t7qeEn.js → sessions-DvqsIg0M.js} +1 -1
  352. package/dist/{shared-xj-xaKFi.js → shared-BBOiNdjf.js} +1 -1
  353. package/dist/{shared-BPN3qd7G.js → shared-C2orjbTD.js} +1 -1
  354. package/dist/{skill-scanner-U3AJgjqc.js → skill-scanner-BEvov9QH.js} +1 -1
  355. package/dist/{skill-scanner-DEmbPsRh.js → skill-scanner-OTLeRZ_p.js} +1 -1
  356. package/dist/{skills-cli-CIdnXa3B.js → skills-cli-C1BOgB3y.js} +1 -1
  357. package/dist/{skills-cli-BXbGr7vl.js → skills-cli-CFT2Aq5R.js} +1 -1
  358. package/dist/{skills-install-Btw_GHbI.js → skills-install-LlKntDHa.js} +1 -1
  359. package/dist/{skills-install-DMHQRpIl.js → skills-install-tx5Mahav.js} +1 -1
  360. package/dist/{status-DXaDS_0w.js → status-Bh8V7kjv.js} +1 -1
  361. package/dist/{status-BxeKmkVr.js → status-BtBHmhQh.js} +1 -1
  362. package/dist/{status-BkcmeZg6.js → status-CpwD4y9B.js} +1 -1
  363. package/dist/status-CqaTmyih.js +1 -0
  364. package/dist/{status-DouJcFzf.js → status-yXz8PUbL.js} +1 -1
  365. package/dist/{status.update-C9iy31xr.js → status.update-CdgsLBPg.js} +1 -1
  366. package/dist/{status.update-KYyRSDZY.js → status.update-hzMro-BT.js} +1 -1
  367. package/dist/{subagent-registry-Dr20nzwk.js → subagent-registry-CaRUNwCj.js} +1 -1
  368. package/dist/{subagent-registry-CyGxu3kP.js → subagent-registry-DDEN4oJi.js} +10 -10
  369. package/dist/{subagent-registry-BiXkIDeh.js → subagent-registry-DYYfeIc3.js} +1 -1
  370. package/dist/{system-cli-b4YgXPHv.js → system-cli-4aii1JYf.js} +1 -1
  371. package/dist/{system-cli-C7YzJeP4.js → system-cli-CfkDD3FV.js} +1 -1
  372. package/dist/{tui-DylWbrDx.js → tui-DnVRxfI8.js} +2 -2
  373. package/dist/{tui-BwWMByVp.js → tui-JfWoLGIV.js} +2 -2
  374. package/dist/{tui-cli-C_TTgabr.js → tui-cli-CGjg2Eb5.js} +1 -1
  375. package/dist/{tui-cli-Bh1V8-w9.js → tui-cli-cd7Efw5u.js} +1 -1
  376. package/dist/{tui-setup-check-DJZCJokQ.js → tui-setup-check-BEHm9wwo.js} +1 -1
  377. package/dist/{tui-setup-check-BABAyl-e.js → tui-setup-check-DK8vdhLI.js} +1 -1
  378. package/dist/{tui-stream-assembler-ign_cPkv.js → tui-stream-assembler-8ud9oyMK.js} +1 -1
  379. package/dist/{tui-stream-assembler-q9GANTDr.js → tui-stream-assembler-Br15rhRH.js} +1 -1
  380. package/dist/{update-BUzcmoDf.js → update-B5yKFeGO.js} +1 -1
  381. package/dist/{update-D6U-V8Au.js → update-DodoQDCk.js} +1 -1
  382. package/dist/{update-cli-DUrUIrYQ.js → update-cli-CfJJcSUS.js} +1 -1
  383. package/dist/{update-cli-CA3LuuJ7.js → update-cli-x8Ocbf-0.js} +1 -1
  384. package/dist/{usage-cli-CfEg1_NZ.js → usage-cli-CN7L1YRG.js} +1 -1
  385. package/dist/{usage-cli-CpbYMXxS.js → usage-cli-CQmokGkG.js} +1 -1
  386. package/dist/{web-D-NSyF6b.js → web-BXLk9UT2.js} +1 -1
  387. package/dist/web-Btgs8oWv.js +1 -0
  388. package/dist/{webhooks-cli-B_f61rq7.js → webhooks-cli-DIo8p3lk.js} +1 -1
  389. package/dist/{webhooks-cli-Bi0t3w6P.js → webhooks-cli-DhxEtiFt.js} +1 -1
  390. package/dist/{whatsapp-actions-JbF2MrTV.js → whatsapp-actions-B7r9AyZN.js} +1 -1
  391. package/dist/{whatsapp-actions-BkCMhD9X.js → whatsapp-actions-DX2QU6Gs.js} +1 -1
  392. package/dist/{with-timeout-T07SJo4N.js → with-timeout-B_p5pWDv.js} +1 -1
  393. package/dist/{with-timeout-Bwq-GyUQ.js → with-timeout-GDLpcjW7.js} +1 -1
  394. package/dist/workflow-telemetry-BMTg5lPd.js +1 -0
  395. package/dist/workflow-telemetry-Bg8MVUr_.js +2 -0
  396. package/dist/workflow-telemetry-Do1UsYwM.js +1 -0
  397. package/dist/workflow-telemetry-DqBPhVL4.js +2 -0
  398. package/package.json +1 -1
  399. package/dist/agents-DsZ5vLKE.js +0 -1
  400. package/dist/auth-choice-Btd2Rxxd.js +0 -1
  401. package/dist/auth-choice-CVV9wRFN.js +0 -1
  402. package/dist/auth-choice.apply-BOK9XRCQ.js +0 -1
  403. package/dist/auth-choice.apply-Cv-BiV5Q.js +0 -1
  404. package/dist/auth-choice.apply.transformers-CXywS3GZ.js +0 -1
  405. package/dist/builderforce-onboarding-Dq6VUSKZ.js +0 -24
  406. package/dist/builderforce-onboarding-DuUfZ6oL.js +0 -24
  407. package/dist/configure-CWBBFk3F.js +0 -1
  408. package/dist/configure-fHVOAucW.js +0 -1
  409. package/dist/health-GLcAfqDz.js +0 -1
  410. package/dist/login-CPyEf5h6.js +0 -1
  411. package/dist/model-catalog-J7R-tJDu.js +0 -1
  412. package/dist/model-picker-D2bcWrtu.js +0 -1
  413. package/dist/model-picker-DO1HtEEm.js +0 -1
  414. package/dist/onboard-channels-CmqKsAoW.js +0 -1
  415. package/dist/onboard-channels-Db0P4iWl.js +0 -1
  416. package/dist/onboard-custom-BABqIYa4.js +0 -1
  417. package/dist/onboard-custom-VpW3UC8u.js +0 -1
  418. package/dist/plugin-registry-B-UOeWqM.js +0 -1
  419. package/dist/plugin-registry-BjMr3yXM.js +0 -1
  420. package/dist/plugin-sdk/web-CThgoHQp.js +0 -1
  421. package/dist/provider-dispatcher-C4nHaNqn.js +0 -1
  422. package/dist/register.configure-DAL38e7r.js +0 -1
  423. package/dist/register.configure-DZG7-WVi.js +0 -1
  424. package/dist/status-BTYqHVha.js +0 -1
  425. package/dist/web-P6QsgmSD.js +0 -1
  426. package/dist/workflow-telemetry-B8Im0mPk.js +0 -1
  427. package/dist/workflow-telemetry-DLEnm5TI.js +0 -2
  428. package/dist/workflow-telemetry-Dc_oseV7.js +0 -2
  429. package/dist/workflow-telemetry-Dkm3mofI.js +0 -1
  430. /package/dist/{devtools-CI7JyCXv.js → devtools-Cg4F-l9O.js} +0 -0
  431. /package/dist/{devtools-eMFaIsAT.js → devtools-Dl2DACSO.js} +0 -0
  432. /package/dist/{github-copilot-token-D3gHtNUu.js → github-copilot-token-BlyiXyTy.js} +0 -0
  433. /package/dist/{github-copilot-token-DHP2kAiN.js → github-copilot-token-D5sB2AUI.js} +0 -0
  434. /package/dist/{onboard-hooks-Cenav0eW.js → onboard-hooks-BaOSgxs9.js} +0 -0
  435. /package/dist/{onboard-hooks-Ce20rwpW.js → onboard-hooks-fO5eeDe_.js} +0 -0
  436. /package/dist/{qmd-manager-DVd_aWEV.js → qmd-manager-BgplOjHN.js} +0 -0
  437. /package/dist/{qmd-manager-keHvLmvP.js → qmd-manager-COUi_Fqb.js} +0 -0
@@ -1,4 +1,4 @@
1
- import{g as resolveStateDir,r as STATE_DIR,u as resolveGatewayPort}from"./paths-BHg-VHB4.js";import{C as createInternalHookEvent,T as triggerInternalHook,_ as clearPluginCommands,b as listPluginCommands,c as normalizeAnyChannelId,f as requireActivePluginRegistry,g as normalizePluginHttpPath,h as createPluginRegistry,l as normalizeChannelId,n as CHAT_CHANNEL_ORDER,p as setActivePluginRegistry,v as executePluginCommand,x as matchPluginCommand,y as getPluginCommandSpecs}from"./registry-Cv7CoWAs.js";import{C as sleep$2,D as danger,E as truncateUtf16Safe,H as getChildLogger,I as warn,P as shouldLogVerbose,S as shortenHomePath,X as normalizeLogLevel,c as escapeRegExp,d as isRecord$1,j as logVerbose,m as normalizeE164,r as clampInt,t as CONFIG_DIR,u as isPlainObject,w as sliceUtf16Safe,x as shortenHomeInString,y as resolveUserPath,z as theme}from"./utils-BP60e80M.js";import{f as createNonExitingRuntime,p as defaultRuntime,t as createSubsystemLogger}from"./subsystem-C4b1Von0.js";import{t as parseBooleanValue$1}from"./boolean-ssGoaBPk.js";import{t as isTruthyEnvValue}from"./env-BoE8QSib.js";import{A as buildConfiguredAllowlistKeys,At as scopeToken,Bt as createAssistantMessageEventStream,Ct as estimateTokens,Dt as MODEL_ANALYTICS_PATH,Et as profileWorkload,F as modelKey,Ft as modelRef,G as resolveModelRefFromString,Gt as getCustomProviderApiKey,H as resolveConfiguredModelRef,Ht as CURRENT_SESSION_VERSION,I as normalizeModelRef,J as resolveThinkingDefault,K as resolveSubagentConfiguredModelSelection,Kt as requireApiKey,L as normalizeModelSelection,Lt as stripReasoningTagsFromText,M as findNormalizedProviderValue,Mt as scopeHasSignal,Nt as DEFAULT_ACTION_TYPE,Ot as RUN_OUTCOME_PATH,P as isCliProvider,Pt as learnedRoutingEnabled,Qt as normalizeSecretInput,R as normalizeProviderId,Rt as nativeStreamSimple,St as createAgentSession,T as resolveBuilderForceAgentsAgentDir,Tt as estimateTokensFromChars,U as resolveDefaultModelForAgent,Ut as SessionManager,Vt as SettingsManager,Wt as getApiKeyForModel,Xt as resolveModelAuthMode,Yt as resolveEnvApiKey,_n as DEFAULT_PROVIDER,a as markAuthProfileUsed,b as ensureAuthProfileStore,bt as createOllamaStreamFn,en as getShellPathFromLoginShell,g as markAuthProfileGood,gn as DEFAULT_MODEL,h as listProfilesForProvider,hn as DEFAULT_CONTEXT_TOKENS,i as markAuthProfileFailure,j as buildModelAliasIndex,jt as rankModelsForAction,k as buildAllowedModelSet,kt as OWN_TENANT_SCOPE_TOKEN,n as getSoonestCooldownExpiry,nn as resolveShellEnvFallbackTimeoutMs,q as resolveSubagentSpawnModelSelection,qt as resolveApiKeyForProvider,r as isProfileInCooldown,t as resolveAuthProfileOrder,vn as resolveAuthProfileDisplayLabel,w as resolveAuthStorePathForDisplay,wt as CHARS_PER_TOKEN,xt as registryToAgentTools,yt as OLLAMA_NATIVE_BASE_URL,zt as nativeComplete}from"./auth-profiles-C1VbcUOm.js";import{t as formatCliCommand}from"./command-format-DTMaGKs7.js";import{c as LLM_PROVIDER_INFO,d as tierRank,f as perMillionToPerToken,i as anthropicModelId,l as UNKNOWN_TIER_RANK,n as ANTHROPIC_RELEASES,o as olderAnthropicTemplateIds,r as anthropicFamilyAliases,u as resolveModelTier}from"./src-DvWaTze9.js";import{i as logWarn,n as logError,r as logInfo,t as logDebug}from"./logger-wuOr7HKl.js";import{C as parseAgentSessionKey,S as isSubagentSessionKey,a as buildAgentMainSessionKey,c as classifySessionKeyShape,d as normalizeAgentId,f as normalizeMainKey,h as sanitizeAgentId,m as resolveThreadSessionKeys,n as DEFAULT_ACCOUNT_ID$1,p as resolveAgentIdFromSessionKey,r as DEFAULT_AGENT_ID,u as normalizeAccountId$2,v as getSubagentDepth,w as resolveThreadParentSessionKey,x as isCronSessionKey,y as isAcpSessionKey}from"./session-key-CksCYipj.js";import{t as resolveBuilderForceAgentsPackageRoot}from"./builderforce-root-DY1qbWNX.js";import{n as runExec,r as spawnWithFallback,t as runCommandWithTimeout}from"./exec-COgsU9ql.js";import{A as resolveWorkspaceFilePath,D as loadWorkspaceBootstrapFiles,T as filterBootstrapFilesForSession,a as resolveAgentModelFallbacksOverride,c as resolveAgentWorkspaceDir,d as resolveSessionAgentId,f as resolveSessionAgentIds,h as DEFAULT_BOOTSTRAP_FILENAME,i as resolveAgentDir,l as resolveDefaultAgentId,m as DEFAULT_AGENT_WORKSPACE_DIR,n as listAgentIds,r as resolveAgentConfig,s as resolveAgentSkillsFilter,w as ensureAgentWorkspace}from"./agent-scope-CufEmNj_.js";import{t as normalizeBaseUrl}from"./normalize-base-url-D_sv6Zgt.js";import{i as readSharedEnvVar}from"./env-file-DeS6x2OL.js";import{A as normalizeScopeDir,D as ToolRegistry,M as editFacts,O as filterByGlob,_ as SYMBOL_KINDS,c as mergeLimbicWithPsychometric,d as editFileTool,f as listFilesTool,g as SEMANTIC_TOOLS,h as writeFileTool,j as applyStringEdit,k as isUnderScopeDir,l as askHumanTool$1,m as memoryRememberTool,o as limbicTraits,p as memoryRecallTool,s as mergeExecParams,t as stableStringify,u as deleteFileTool,v as extractSymbols,y as isSymbolIndexable}from"./src-HrLX5bhG.js";import{n as saveJsonFile,t as loadJsonFile}from"./json-file-DUi7S24G.js";import{C as resetConfigOverrides,D as parseConfigPath,E as getConfigValueAtPath,O as setConfigValueAtPath,S as getConfigOverrides,T as unsetConfigOverride,U as VERSION,V as resolveAgentMaxConcurrent,_ as resolveTelegramCustomCommands,a as readConfigFileSnapshot,b as validateJsonSchemaValue,c as writeConfigFile,f as validateConfigObjectWithPlugins,g as normalizeTelegramCommandName,h as TELEGRAM_COMMAND_NAME_PATTERN,k as unsetConfigValueAtPath,r as loadConfig,s as resolveConfigSnapshotHash,w as setConfigOverride,y as parseDurationMs}from"./io-CohJffHG.js";import{c as normalizePluginsConfig,l as resolveEnableState,n as loadPluginManifestRegistry,o as applyTestPluginDefaults,r as discoverBuilderForceAgentsPlugins,u as resolveMemorySlotDecision}from"./manifest-registry-009gLJ4l.js";import{a as ensureBuilderForceAgentsModelsJson,i as discoverModels,r as discoverAuthStorage}from"./model-discovery-C9Xm95uL.js";import{i as modelSupportsVision,r as loadModelCatalog,t as findModelInCatalog}from"./model-catalog-CiiFJX77.js";import{a as resolveSkillsPromptForRun,d as resolveSandboxInputPath,h as applySkillEnvOverridesFromSnapshot,i as loadWorkspaceSkillEntries,l as assertMediaNotDataUrl,m as applySkillEnvOverrides,n as buildWorkspaceSkillCommandSpecs,p as resolveSandboxedMediaSource,r as buildWorkspaceSkillSnapshot,u as assertSandboxPath}from"./skills-D3MwwPOH.js";import{i as getSkillsSnapshotVersion,n as bumpSkillsSnapshotVersion,r as ensureSkillsWatcher}from"./refresh-C4vwneXT.js";import{Pt as SESSION_LABEL_MAX_LENGTH,t as GatewayClient}from"./client-CGgp3zkQ.js";import{i as randomIdempotencyKey,n as callGateway,t as buildGatewayConnectionDetails}from"./call-DmAU4cRX.js";import{a as isInternalMessageChannel,c as listDeliverableMessageChannels,d as resolveMessageChannel,h as GATEWAY_CLIENT_NAMES,l as normalizeMessageChannel,m as GATEWAY_CLIENT_MODES,n as isDeliverableMessageChannel,o as isMarkdownCapableMessageChannel,p as GATEWAY_CLIENT_IDS,t as INTERNAL_MESSAGE_CHANNEL,u as resolveGatewayMessageChannel}from"./message-channel-z5YRpR2d.js";import{n as isLoopbackHost}from"./net-DtnXq2dW.js";import{i as normalizeInputProvenance,n as applyInputProvenanceToUserMessage,r as hasInterSessionUserProvenance}from"./input-provenance-Rnkkt19n.js";import{$ as deliveryContextKey,B as resolveChannelGroupPolicy,C as evaluateSessionFreshness,D as resolveThreadFlag,E as resolveSessionResetType,F as deriveSessionMetaPatch,G as normalizeAtHashSlug,J as normalizeStringEntriesLower,K as normalizeHyphenSlug,L as getChannelDock,N as resolveMainSessionKey,O as DEFAULT_RESET_TRIGGERS,Q as deliveryContextFromSession,R as listChannelDocks,S as resolveSessionKey$1,T as resolveSessionResetPolicy,V as resolveChannelGroupRequireMention,W as resolveGroupSessionKey,Y as acquireSessionWriteLock,Z as resolveSessionLockMaxHoldFromTimeout,a as loadSessionStore,d as updateSessionStoreEntry,et as mergeDeliveryContext,f as isCacheEnabled,g as capArrayByJsonBytes,h as archiveSessionTranscripts,k as resolveFreshSessionTotalTokens,l as updateLastRoute,nt as normalizeSessionDeliveryFields,o as readSessionUpdatedAt,p as resolveCacheTtlMs$1,q as normalizeStringEntries,r as appendAssistantMessageToSessionTranscript,s as recordSessionMetaFromInbound,t as extractDeliveryInfo,tt as normalizeDeliveryContext,u as updateSessionStore,w as resolveChannelResetConfig,z as normalizeSignalMessagingTarget}from"./sessions-Bl1wwotX.js";import{S as globalPersonaRegistry,T as raiseThinkLevel,f as PRD_FILE,i as loadProjectRules,n as loadProjectContext,r as loadProjectGovernance,t as loadProjectArchitecture,v as resolveBuilderForceAgentsDir,w as getRoleProfile,x as buildPersonaSystemBlock,y as resolvePrdPath}from"./project-context-store-CIUcwUP_.js";import{n as SILENT_REPLY_TOKEN,r as isSilentReplyText,t as HEARTBEAT_TOKEN}from"./tokens-CFKkpUIu.js";import{_ as resolveDiscordAccount,a as normalizeWhatsAppTarget,c as listTelegramAccountIds,d as resolveSlackAccount,g as listEnabledDiscordAccounts,h as createDiscordActionGate,i as isWhatsAppGroupJid,l as resolveTelegramAccount,m as resolveSlackBotToken,n as listChannelPlugins,o as createTelegramActionGate,p as resolveSlackAppToken,r as normalizeChannelId$1,s as listEnabledTelegramAccounts,t as getChannelPlugin,u as resolveTelegramToken,v as normalizeDiscordToken}from"./plugins-1Mn6RiNf.js";import{a as logWebSelfId,i as getWebAuthAgeMs,m as webAuthExists,n as resolveWhatsAppAccount,o as logoutWeb,u as readWebSelfId}from"./accounts-BkTLjSrD.js";import{t as normalizeChatType}from"./chat-type-BSDVym_t.js";import{a as parseSlackBlocksInput,c as parseSlackTarget,i as resolveSlackWebClientOptions,l as resolveSlackChannelId,o as validateSlackBlocksArray,r as createSlackWebClient,s as buildSlackBlocksFallbackText,t as sendMessageSlack}from"./send-BvroeIQ6.js";import{$ as createDiscordClient,A as banMemberDiscord,B as timeoutMemberDiscord,C as listPinsDiscord,Ct as buildChannelKeyCandidates,D as searchMessagesDiscord,E as readMessagesDiscord,F as fetchVoiceStatusDiscord,G as deleteChannelDiscord,H as uploadEmojiDiscord,I as kickMemberDiscord,J as removeChannelPermissionDiscord,K as editChannelDiscord,L as listGuildChannelsDiscord,M as fetchChannelInfoDiscord,N as fetchMemberInfoDiscord,O as unpinMessageDiscord,P as fetchRoleInfoDiscord,Q as fetchChannelPermissionsDiscord,R as listScheduledEventsDiscord,S as fetchMessageDiscord,St as applyChannelMatchMeta,T as pinMessageDiscord,Tt as resolveChannelEntryMatchWithFallback,U as uploadStickerDiscord,V as listGuildEmojisDiscord,W as createChannelDiscord,X as stripUndefinedFields,Y as setChannelPermissionDiscord,_ as sendStickerDiscord,_t as formatDiscordReactionEmoji,a as sendDiscordComponentMessage,at as allowListMatches$1,b as deleteMessageDiscord,bt as resolveTimestampMs,c as parseDiscordComponentCustomId,ct as normalizeDiscordSlug,d as parseDiscordModalCustomIdForCarbon,dt as resolveDiscordGuildEntry,et as chunkDiscordTextWithMode,f as readDiscordComponentSpec,ft as resolveDiscordMemberAccessState,g as sendPollDiscord,gt as shouldEmitDiscordReactionNotification,h as sendMessageDiscord,ht as resolveGroupDmAllow,i as removeReactionDiscord,it as listDiscordDirectoryPeersLive,j as createScheduledEventDiscord,k as addRoleDiscord,l as parseDiscordComponentCustomIdForCarbon,lt as resolveDiscordAllowListMatch,m as resolveDiscordModalEntry,mt as resolveDiscordShouldRequireMention,n as reactMessageDiscord,nt as resolveDiscordChannelId,o as createDiscordFormModal,ot as isDiscordGroupAllowedByPolicy,p as resolveDiscordComponentEntry,pt as resolveDiscordOwnerAllowFrom,q as moveChannelDiscord,r as removeOwnReactionsDiscord,rt as listDiscordDirectoryGroupsLive,s as formatDiscordComponentEventText,st as normalizeDiscordAllowList,t as fetchReactionsDiscord,tt as parseDiscordTarget,u as parseDiscordModalCustomId,ut as resolveDiscordChannelConfigWithFallback,v as sendVoiceMessageDiscord,vt as formatDiscordUserTag,w as listThreadsDiscord,x as editMessageDiscord,xt as fetchDiscord,y as createThreadDiscord,yt as resolveDiscordSystemLocation,z as removeRoleDiscord}from"./send-CceNWtYE.js";import{n as createBrowserRouteDispatcher,r as getMachineDisplayName,t as withTimeout$3}from"./with-timeout-T07SJo4N.js";import{C as getGlobalHookRunner,S as stripWhatsAppLeadingBlankLines,_ as parseReplyDirectives,a as normalizeReplyPayloadsForDelivery,b as parseInlineDirectives$1,c as filterMessagingToolDuplicates,d as shouldSuppressMessagingToolReplies,f as createReplyToModeFilterForChannel,g as normalizeTargetForProvider,h as normalizeChannelTargetInput,l as filterMessagingToolMediaDuplicates,m as buildTargetResolverSignature,o as applyReplyTagsToPayload,p as resolveReplyToMode,s as applyReplyThreading,t as deliverOutboundPayloads,u as isRenderablePayload,v as MEDIA_TOKEN_RE,w as initializeGlobalHookRunner,x as throwIfAborted,y as splitMediaFromOutput}from"./deliver-BuZu68tp.js";import{n as resolveSignalAccount,t as listEnabledSignalAccounts}from"./accounts-Cx82nj4E.js";import{A as extractTelegramLocation,B as isSenderAllowed$1,C as buildTelegramGroupFrom,D as buildTypingThreadParams,E as buildTelegramThreadParams,F as resolveTelegramMediaPlaceholder,G as isVoiceCompatibleAudio,H as resolveSenderAllowMatch,I as resolveTelegramReplyId,K as parseTelegramTarget,L as resolveTelegramStreamMode,M as normalizeForwardedContext,N as resolveTelegramForumThreadId,O as describeReplyTarget,P as resolveTelegramGroupAllowFromContext,R as resolveTelegramThreadSpec,S as buildSenderName,T as buildTelegramParentPeer,U as formatLocationText,V as normalizeAllowFromWithStore$1,W as toLocationContext,_ as resolveTelegramFetch,a as reactMessageTelegram,b as buildGroupLabel,c as sendStickerTelegram,d as makeProxyFetch,f as isRecoverableTelegramNetworkError,g as wrapFileReferencesInHtml,h as renderTelegramHtmlText,i as editMessageTelegram,j as hasBotMention,k as expandTextLinks,l as resolveTelegramVoiceSend,m as markdownToTelegramHtml,n as createForumTopicTelegram,o as sendMessageTelegram,p as markdownToTelegramChunks,q as resolveTelegramTargetChatType,r as deleteMessageTelegram,s as sendPollTelegram,t as buildInlineKeyboard,u as wasSentByBot,v as splitTelegramCaption,w as buildTelegramGroupPeerId,x as buildSenderLabel,y as withTelegramApiErrorLogging,z as firstDefined$2}from"./send-ByCVQQVz.js";import{c as detectMime,d as imageMimeFromFormat,f as isAudioFileName,g as MAX_IMAGE_BYTES,i as getImageMetadata,l as extensionForMime,p as isGifMedia,s as resizeToJpeg,v as mediaKindFromMime}from"./image-ops-CotJhwRR.js";import{n as formatErrorMessage,r as formatUncaughtError}from"./errors-tAt19c1E.js";import{A as isAuthAssistantError,B as isTimeoutErrorMessage,C as isGoogleModelApi,D as formatBillingErrorMessage,E as formatAssistantErrorText,F as isFailoverAssistantError,G as buildBootstrapContextFiles,H as parseImageDimensionError,I as isFailoverErrorMessage,J as resolveBootstrapTotalMaxChars,K as ensureSessionHeader,L as isLikelyContextOverflowError,M as isCloudCodeAssistFormatError,N as isCompactionFailureError,O as formatRawAssistantErrorForUi,P as isContextOverflowError,R as isRateLimitAssistantError,S as isAntigravityClaude,T as classifyFailoverReason,U as parseImageSizeError,V as isTransientHttpError,W as sanitizeUserFacingText,Y as sanitizeGoogleTurnOrdering,_ as normalizeTextForComparison,a as formatXHighModelHint,b as extractToolResultId,c as normalizeElevatedLevel,d as normalizeUsageDisplay,f as normalizeVerboseLevel,g as isMessagingToolDuplicateNormalized,i as formatThinkingLevels,j as isBillingAssistantError,k as getApiErrorPayloadFingerprint,l as normalizeReasoningLevel,m as supportsXHighThinking,n as validateGeminiTurns,p as resolveResponseUsageMode,q as resolveBootstrapMaxChars,r as pickFallbackThinkingLevel,t as validateAnthropicTurns,u as normalizeThinkLevel,v as sanitizeSessionMessagesImages,w as BILLING_ERROR_USER_MESSAGE,x as downgradeOpenAIReasoningBlocks,y as extractToolCallsFromAssistant,z as isRawApiErrorPayload}from"./embedded-helpers-DK8_apW0.js";import{C as compileGlobPatterns,S as stripPluginOnlyAllowlist,_ as expandPolicyWithPluginGroups,a as ensureSandboxWorkspaceForSession,b as normalizeToolName,c as resolveSandboxRuntimeStatus,d as resolveSandboxConfigForAgent,g as collectExplicitAllowlist,h as buildPluginToolGroups,m as applyOwnerOnlyToolPolicy,o as resolveSandboxContext,u as getBridgeAuthForPort,w as matchesAnyGlobPattern,x as resolveToolProfilePolicy,y as mergeAlsoAllowPolicy}from"./sandbox-z9t_PRf9.js";import{S as DEFAULT_AI_SNAPSHOT_MAX_CHARS}from"./chrome-BnEbJV3D.js";import{c as safeEqualSecret}from"./auth-ChecwOXS.js";import{i as resolveBrowserConfig,m as resolveBrowserControlAuth}from"./server-context-owOmmyUM.js";import{a as resolvePathsWithinRoot,r as DEFAULT_UPLOAD_DIR}from"./paths-BnOjueoX.js";import{a as isPrivateIpAddress,i as isBlockedHostname,s as normalizeHostname,t as SsrFBlockedError}from"./ssrf-DJXLYZ0d.js";import{n as getMediaDir,r as saveMediaBuffer}from"./store-DHD2IEgd.js";import{t as resolveConversationLabel}from"./conversation-label-YgiB0mdr.js";import{t as resolveIMessageAccount}from"./accounts-DcoaLXKI.js";import{c as resolveStorePath,i as resolveSessionTranscriptPath,n as resolveSessionFilePath,r as resolveSessionFilePathOptions,t as resolveDefaultSessionStorePath}from"./paths-ClsbsPQP.js";import{t as emitSessionTranscriptUpdate}from"./transcript-events-XyildGuH.js";import{i as resolveImageSanitizationLimits,n as sanitizeImageBlocks,r as sanitizeToolResultImages}from"./tool-images-CCpqFtrL.js";import{a as shouldIncludeHook,t as loadHookEntriesFromDir}from"./workspace-waBqRxiy.js";import{i as resolveAckReaction,n as createReplyPrefixOptions,o as resolveEffectiveMessagesConfig,r as resolveResponsePrefixTemplate,s as resolveHumanDelayConfig}from"./reply-prefix-Cg7AqaK0.js";import{c as resolveGatewayLaunchAgentLabel,d as resolveGatewaySystemdServiceName}from"./constants-D2th5NXV.js";import{v as runTasksWithConcurrency}from"./sqlite-CIGM1WKg.js";import{i as resolveMemoryBackendConfig,r as getMemorySearchManager,t as registerMemoryCli}from"./memory-cli-ivAs7q7v.js";import{n as importNodeLlamaCpp,r as resolveMemorySearchConfig}from"./manager-CRba8roB.js";import{n as retryAsync}from"./retry-B151Hej5.js";import{a as jsonResult,c as readStringArrayParam,i as imageResultFromFile,l as readStringOrNumberParam,n as createActionGate,o as readNumberParam,r as imageResult,s as readReactionParams,t as ToolInputError,u as readStringParam}from"./common-BfwMxpLu.js";import{A as promoteThinkingTagsToBlocks,C as extractAssistantText$1,D as formatReasoningMessage,E as extractThinkingFromTaggedText,M as stripMinimaxToolCallXml,N as stripThinkingTagsFromText,O as inferToolMetaFromArgs,P as extractTextFromChatContent,S as applyTemplate,T as extractThinkingFromTaggedStream,_ as coerceImageModelConfig,a as runCapability,b as minimaxUnderstandImage,d as resolveConcurrency,f as resolveTimeoutMs,g as coerceImageAssistantText,h as describeImageWithModel,i as resolveAutoImageModel,j as stripDowngradedToolCallText,k as isAssistantMessage,l as registerUnhandledRejectionHandler,m as resolveMediaUnderstandingScope,n as createMediaAttachmentCache,p as normalizeMediaUnderstandingChatType,r as normalizeMediaAttachments,s as resolveAttachmentKind,t as buildProviderRegistry,v as decodeDataUrl,w as extractAssistantThinking,x as CLI_OUTPUT_MAX_BUFFER,y as resolveProviderVisionModelFromConfig}from"./runner-DwWmciCt.js";import{n as resolveToolDisplay}from"./tool-display-Cs4hDP1f.js";import{a as chunkText,c as resolveTextChunkLimit,d as parseFenceSpans,i as chunkMarkdownTextWithMode,l as findFenceSpanAt,o as chunkTextWithMode,r as chunkMarkdownText,s as resolveChunkMode,t as chunkByNewline,u as isSafeFenceBreak}from"./chunk-Dly7lM4r.js";import{t as resolveMarkdownTableMode}from"./markdown-tables-B1Rx8hv6.js";import{n as fetchWithTimeout,t as bindAbortRelay}from"./fetch-timeout-Cb8Yj9Tw.js";import{t as fetchWithSsrFGuard}from"./fetch-guard-DnXqPKae.js";import{n as fetchRemoteMedia,r as readResponseWithLimit}from"./fetch-Cn_THzz8.js";import{a as loadWebMedia,i as getDefaultLocalRoots,s as getAgentScopedMediaLocalRoots}from"./ir-CSdQJPqu.js";import{C as parseCommandArgs,D as shouldHandleTextCommands,E as serializeCommandArgs,S as normalizeCommandBody,T as resolveCommandArgMenu,_ as findCommandByNativeName,b as listNativeCommandSpecs,c as getStagedEdit,d as isStagingActive,g as buildCommandTextFromArgs,h as stageEdit,v as listChatCommands,w as resolveCommandArgChoices,x as listNativeCommandSpecsForConfig,y as listChatCommandsForConfig}from"./builderforcellm-syscheck-CprBhARf.js";import{n as formatTimeAgo}from"./format-relative-CruqE52s.js";import{n as normalizeInboundTextNewlines,t as finalizeInboundContext}from"./inbound-context-NEZRiLx6.js";import{a as loadCombinedSessionStoreForGateway,u as lookupContextTokens}from"./session-utils-GMvum00v.js";import{a as resolveSubagentToolPolicy,c as resolveNativeCommandsEnabled,i as resolveGroupToolPolicy,l as resolveNativeSkillsEnabled,n as isToolAllowedByPolicies,r as resolveEffectiveToolPolicy,s as isNativeCommandsExplicitlyDisabled,t as filterToolsByPolicy,u as listAgentWorkspaceDirs}from"./coding-tools.policy-NEPm7Mz1.js";import{a as removeChannelAllowFromStoreEntry,c as listPairingChannels,i as readChannelAllowFromStore,o as upsertChannelPairingRequest,t as addChannelAllowFromStoreEntry}from"./pairing-store-QDb6lhIU.js";import{n as wrapFetchWithAbortSignal,t as resolveFetch}from"./fetch-DnWD6ydH.js";import{d as resolveExecApprovals,f as resolveExecApprovalsFromFile,g as resolveSafeBins,h as evaluateShellAllowlist,i as maxAsk,l as recordAllowlistUse,n as addAllowlistEntry,o as minSecurity,u as requiresExecApproval,v as buildSafeBinsShellCommand,y as buildSafeShellCommand}from"./exec-approvals-D7ZPAZpt.js";import{a as canvasSnapshotTempPath,c as parseCameraClipPayload,d as writeCameraClipPayloadToFile,f as writeUrlToFile,g as buildNodeShellCommand,h as normalizePathPrepend,i as parseEnvPairs,l as parseCameraSnapPayload,m as mergePathPrepend,n as screenRecordTempPath,o as parseCanvasSnapshotPayload,p as applyPathPrepend,r as writeScreenRecordToFile,s as cameraTempPath,t as parseScreenRecordPayload,u as writeBase64ToFile}from"./nodes-screen-D6GHv_S0.js";import{n as parseNodeList,r as parsePairingList,t as resolveNodeIdFromCandidates}from"./node-match-DxosVKnI.js";import{i as formatDurationSeconds,r as formatDurationPrecise,t as formatDurationCompact$1}from"./format-duration-HN2dpHE0.js";import{c as hasNonzeroUsage,l as normalizeUsage,n as loadCostUsageSummary,o as derivePromptTokens,r as loadSessionCostSummary,s as deriveSessionTotalTokens}from"./session-cost-usage-S0nkbPoW.js";import{i as resolveModelCostConfig,n as formatTokenCount$2,r as formatUsd,t as estimateUsageCost}from"./usage-format-5sp5AMSu.js";import{i as resolveUsageProviderId,r as formatUsageWindowSummary,t as loadProviderUsageSummary}from"./provider-usage-Bn4ZrnU7.js";import{a as signalCheck,i as resolveSignalRpcContext,n as sendReadReceiptSignal,o as signalRpcRequest,r as sendTypingSignal,s as streamSignalEvents,t as sendMessageSignal}from"./send-B_1BtyfA.js";import{a as loadWorkflowState,c as saveSessionHandoff,i as listIncompleteWorkflowIds,l as loadCustomAgentRoles,o as saveWorkflowState}from"./project-context-D3Mx4maV.js";import{r as startBrowserControlServiceFromConfig,t as createBrowserControlContext}from"./control-service-CJuuqNOE.js";import{i as parseAbsoluteTimeMs,r as resolveDefaultCronStaggerMs,t as normalizeCronStaggerMs}from"./stagger-CRe77dWL.js";import{n as resolveMessageChannelSelection,t as listConfiguredMessageChannels}from"./channel-selection-BLwXhb9t.js";import{n as normalizePollInput}from"./polls-BdfE-6dQ.js";import{a as isAllowedIMessageSender,i as formatIMessageChatTarget,n as createIMessageRpcClient,o as normalizeIMessageHandle,r as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS,s as parseIMessageTarget,t as sendMessageIMessage}from"./send-UFtylOiq.js";import{n as resolveAgentRoute,t as buildAgentSessionKey}from"./resolve-route-DEIW5uKy.js";import{t as parseTimeoutMs}from"./parse-timeout-BvepsazJ.js";import{n as recordChannelActivity,r as createDiscordRetryRunner,t as getChannelActivity}from"./channel-activity-DX36RadH.js";import{t as convertMarkdownTables}from"./tables-CojSfTth.js";import{a as createReplyReferencePlanner,i as resolveSlackThreadTs,n as deliverReplies$3,t as createSlackReplyDeliveryPlan}from"./replies-DbkT_5BV.js";import{r as detectBinary}from"./onboard-helpers-CckrS8_K.js";import{t as resolvePairingIdLabel}from"./pairing-labels-3j_iRYOO.js";import{t as getActiveWebListener}from"./active-listener-Di9e1YAD.js";import{n as mambaStateToContextLine,t as loadMambaState}from"./mamba-state-engine-CV4nDcCk.js";import{a as TRANSFORMERS_DEFAULT_CACHE_DIR,c as loadBuilderForceAgentsMemory,i as HIPPOCAMPUS_DEFAULT_MODEL_ID,n as AMYGDALA_DEFAULT_MODEL_ID,o as convertToTransformersMessages,r as HIPPOCAMPUS_DEFAULT_DTYPE,t as AMYGDALA_DEFAULT_DTYPE}from"./transformers-stream-Buj40qHl.js";import{createRequire}from"node:module";import{execFile,execFileSync,execSync,spawn,spawnSync}from"node:child_process";import*as os$1 from"node:os";import os,{homedir,tmpdir}from"node:os";import*as path$1 from"node:path";import path,{dirname,extname,isAbsolute,join,relative,resolve,sep}from"node:path";import fs,{constants,existsSync,mkdirSync,mkdtempSync,promises,readFileSync,renameSync,rmSync,statSync,unlinkSync,writeFileSync}from"node:fs";import{inspect,promisify}from"node:util";import crypto,{createHmac,randomBytes,randomUUID}from"node:crypto";import{fileURLToPath,pathToFileURL}from"node:url";import JSON5 from"json5";import*as fs$2 from"node:fs/promises";import fs$1,{access,mkdir,readFile,readdir,rm,writeFile}from"node:fs/promises";import WebSocket from"ws";import{Buffer as Buffer$1}from"node:buffer";import{Type}from"@sinclair/typebox";import{EdgeTTS}from"node-edge-tts";import{createServer}from"node:http";import{ProxyAgent,fetch as fetch$1}from"undici";import{LIMBIC_DIM_NAMES,LIMBIC_STATE_DIM,applyLimbicDelta,appraiseAmygdala,basalGangliaSelect,buildLimbicBlock,compileLimbicState,homeostasis,meanLimbicSetpoints,neutralLimbicState,recordToState,thalamusGate}from"@seanhogg/builderforce-memory-engine/limbic";import{createJiti}from"jiti";import ts from"typescript";import{Button,ChannelSelectMenu,ChannelType,Client,Command,Container,MentionableSelectMenu,MessageCreateListener,MessageReactionAddListener,MessageReactionRemoveListener,MessageType,Modal,PresenceUpdateListener,ReadyListener,RoleSelectMenu,Row,Separator,StringSelectMenu,TextDisplay,UserSelectMenu,serializePayload}from"@buape/carbon";import{ApplicationCommandOptionType,ButtonStyle,ChannelType as ChannelType$1,Routes}from"discord-api-types/v10";import{API_CONSTANTS,Bot,GrammyError,InputFile,webhookCallback}from"grammy";import{GatewayIntents,GatewayPlugin}from"@buape/carbon/gateway";import{HttpsProxyAgent}from"https-proxy-agent";import{setTimeout as setTimeout$1}from"node:timers/promises";import{messagingApi}from"@line/bot-sdk";import SlackBolt from"@slack/bolt";import{run,sequentialize}from"@grammyjs/runner";import{apiThrottler}from"@grammyjs/transformer-throttler";import{EventEmitter}from"node:events";import{Worker}from"node:worker_threads";const seqByRun=new Map,listeners$1=new Set,runContextById=new Map;function registerAgentRunContext(runId,context){if(!runId)return;let existing=runContextById.get(runId);if(!existing){runContextById.set(runId,{...context});return}context.sessionKey&&existing.sessionKey!==context.sessionKey&&(existing.sessionKey=context.sessionKey),context.verboseLevel&&existing.verboseLevel!==context.verboseLevel&&(existing.verboseLevel=context.verboseLevel),context.isHeartbeat!==void 0&&existing.isHeartbeat!==context.isHeartbeat&&(existing.isHeartbeat=context.isHeartbeat),context.prompt&&existing.prompt!==context.prompt&&(existing.prompt=context.prompt)}function getAgentRunContext(runId){return runContextById.get(runId)}function clearAgentRunContext(runId){runContextById.delete(runId),seqByRun.delete(runId)}function emitAgentEvent(event){let nextSeq=(seqByRun.get(event.runId)??0)+1;seqByRun.set(event.runId,nextSeq);let context=runContextById.get(event.runId),sessionKey=typeof event.sessionKey==`string`&&event.sessionKey.trim()?event.sessionKey:context?.sessionKey,enriched={...event,sessionKey,seq:nextSeq,ts:Date.now()};for(let listener of listeners$1)try{listener(enriched)}catch{}}function onAgentEvent(listener){return listeners$1.add(listener),()=>listeners$1.delete(listener)}function clearQueueSummaryState(state){state.droppedCount=0,state.summaryLines=[]}function previewQueueSummaryPrompt(params){return buildQueueSummaryPrompt({state:{dropPolicy:params.state.dropPolicy,droppedCount:params.state.droppedCount,summaryLines:[...params.state.summaryLines]},noun:params.noun,title:params.title})}function applyQueueRuntimeSettings(params){params.target.mode=params.settings.mode,params.target.debounceMs=typeof params.settings.debounceMs==`number`?Math.max(0,params.settings.debounceMs):params.target.debounceMs,params.target.cap=typeof params.settings.cap==`number`&&params.settings.cap>0?Math.floor(params.settings.cap):params.target.cap,params.target.dropPolicy=params.settings.dropPolicy??params.target.dropPolicy}function elideQueueText(text,limit=140){return text.length<=limit?text:`${text.slice(0,Math.max(0,limit-1)).trimEnd()}…`}function buildQueueSummaryLine(text,limit=160){return elideQueueText(text.replace(/\s+/g,` `).trim(),limit)}function shouldSkipQueueItem(params){return params.dedupe?params.dedupe(params.item,params.items):!1}function applyQueueDropPolicy(params){let cap=params.queue.cap;if(cap<=0||params.queue.items.length<cap)return!0;if(params.queue.dropPolicy===`new`)return!1;let dropCount=params.queue.items.length-cap+1,dropped=params.queue.items.splice(0,dropCount);if(params.queue.dropPolicy===`summarize`){for(let item of dropped)params.queue.droppedCount+=1,params.queue.summaryLines.push(buildQueueSummaryLine(params.summarize(item)));let limit=Math.max(0,params.summaryLimit??cap);for(;params.queue.summaryLines.length>limit;)params.queue.summaryLines.shift()}return!0}function waitForQueueDebounce(queue){let debounceMs=Math.max(0,queue.debounceMs);return debounceMs<=0?Promise.resolve():new Promise(resolve=>{let check=()=>{let since=Date.now()-queue.lastEnqueuedAt;if(since>=debounceMs){resolve();return}setTimeout(check,debounceMs-since)};check()})}function buildQueueSummaryPrompt(params){if(params.state.dropPolicy!==`summarize`||params.state.droppedCount<=0)return;let noun=params.noun,lines=[params.title??`[Queue overflow] Dropped ${params.state.droppedCount} ${noun}${params.state.droppedCount===1?``:`s`} due to cap.`];if(params.state.summaryLines.length>0){lines.push(`Summary:`);for(let line of params.state.summaryLines)lines.push(`- ${line}`)}return clearQueueSummaryState(params.state),lines.join(`
1
+ import{g as resolveStateDir,r as STATE_DIR,u as resolveGatewayPort}from"./paths-BHg-VHB4.js";import{C as createInternalHookEvent,T as triggerInternalHook,_ as clearPluginCommands,b as listPluginCommands,c as normalizeAnyChannelId,f as requireActivePluginRegistry,g as normalizePluginHttpPath,h as createPluginRegistry,l as normalizeChannelId,n as CHAT_CHANNEL_ORDER,p as setActivePluginRegistry,v as executePluginCommand,x as matchPluginCommand,y as getPluginCommandSpecs}from"./registry-Cv7CoWAs.js";import{C as sleep$2,D as danger,E as truncateUtf16Safe,H as getChildLogger,I as warn,P as shouldLogVerbose,S as shortenHomePath,X as normalizeLogLevel,c as escapeRegExp,d as isRecord$1,j as logVerbose,m as normalizeE164,r as clampInt,t as CONFIG_DIR,u as isPlainObject,w as sliceUtf16Safe,x as shortenHomeInString,y as resolveUserPath,z as theme}from"./utils-BP60e80M.js";import{f as createNonExitingRuntime,p as defaultRuntime,t as createSubsystemLogger}from"./subsystem-C4b1Von0.js";import{t as parseBooleanValue$1}from"./boolean-ssGoaBPk.js";import{t as isTruthyEnvValue}from"./env-BoE8QSib.js";import{A as buildConfiguredAllowlistKeys,At as scopeToken,Bt as createAssistantMessageEventStream,Ct as estimateTokens,Dt as MODEL_ANALYTICS_PATH,Et as profileWorkload,F as modelKey,Ft as modelRef,G as resolveModelRefFromString,Gt as getCustomProviderApiKey,H as resolveConfiguredModelRef,Ht as CURRENT_SESSION_VERSION,I as normalizeModelRef,J as resolveThinkingDefault,K as resolveSubagentConfiguredModelSelection,Kt as requireApiKey,L as normalizeModelSelection,Lt as stripReasoningTagsFromText,M as findNormalizedProviderValue,Mt as scopeHasSignal,Nt as DEFAULT_ACTION_TYPE,Ot as RUN_OUTCOME_PATH,P as isCliProvider,Pt as learnedRoutingEnabled,Qt as normalizeSecretInput,R as normalizeProviderId,Rt as nativeStreamSimple,St as createAgentSession,T as resolveBuilderForceAgentsAgentDir,Tt as estimateTokensFromChars,U as resolveDefaultModelForAgent,Ut as SessionManager,Vt as SettingsManager,Wt as getApiKeyForModel,Xt as resolveModelAuthMode,Yt as resolveEnvApiKey,_n as DEFAULT_PROVIDER,a as markAuthProfileUsed,b as ensureAuthProfileStore,bt as createOllamaStreamFn,en as getShellPathFromLoginShell,g as markAuthProfileGood,gn as DEFAULT_MODEL,h as listProfilesForProvider,hn as DEFAULT_CONTEXT_TOKENS,i as markAuthProfileFailure,j as buildModelAliasIndex,jt as rankModelsForAction,k as buildAllowedModelSet,kt as OWN_TENANT_SCOPE_TOKEN,n as getSoonestCooldownExpiry,nn as resolveShellEnvFallbackTimeoutMs,q as resolveSubagentSpawnModelSelection,qt as resolveApiKeyForProvider,r as isProfileInCooldown,t as resolveAuthProfileOrder,vn as resolveAuthProfileDisplayLabel,w as resolveAuthStorePathForDisplay,wt as CHARS_PER_TOKEN,xt as registryToAgentTools,yt as OLLAMA_NATIVE_BASE_URL,zt as nativeComplete}from"./auth-profiles-pt7Tr4HA.js";import{t as formatCliCommand}from"./command-format-DTMaGKs7.js";import{c as LLM_PROVIDER_INFO,d as tierRank,f as perMillionToPerToken,i as anthropicModelId,l as UNKNOWN_TIER_RANK,n as ANTHROPIC_RELEASES,o as olderAnthropicTemplateIds,r as anthropicFamilyAliases,u as resolveModelTier}from"./src-DvWaTze9.js";import{i as logWarn,n as logError,r as logInfo,t as logDebug}from"./logger-wuOr7HKl.js";import{C as parseAgentSessionKey,S as isSubagentSessionKey,a as buildAgentMainSessionKey,c as classifySessionKeyShape,d as normalizeAgentId,f as normalizeMainKey,h as sanitizeAgentId,m as resolveThreadSessionKeys,n as DEFAULT_ACCOUNT_ID$1,p as resolveAgentIdFromSessionKey,r as DEFAULT_AGENT_ID,u as normalizeAccountId$2,v as getSubagentDepth,w as resolveThreadParentSessionKey,x as isCronSessionKey,y as isAcpSessionKey}from"./session-key-CksCYipj.js";import{t as resolveBuilderForceAgentsPackageRoot}from"./builderforce-root-DY1qbWNX.js";import{n as runExec,r as spawnWithFallback,t as runCommandWithTimeout}from"./exec-COgsU9ql.js";import{A as resolveWorkspaceFilePath,D as loadWorkspaceBootstrapFiles,T as filterBootstrapFilesForSession,a as resolveAgentModelFallbacksOverride,c as resolveAgentWorkspaceDir,d as resolveSessionAgentId,f as resolveSessionAgentIds,h as DEFAULT_BOOTSTRAP_FILENAME,i as resolveAgentDir,l as resolveDefaultAgentId,m as DEFAULT_AGENT_WORKSPACE_DIR,n as listAgentIds,r as resolveAgentConfig,s as resolveAgentSkillsFilter,w as ensureAgentWorkspace}from"./agent-scope-CufEmNj_.js";import{t as normalizeBaseUrl}from"./normalize-base-url-D_sv6Zgt.js";import{i as readSharedEnvVar}from"./env-file-DeS6x2OL.js";import{A as normalizeScopeDir,D as ToolRegistry,M as editFacts,O as filterByGlob,_ as SYMBOL_KINDS,c as mergeLimbicWithPsychometric,d as editFileTool,f as listFilesTool,g as SEMANTIC_TOOLS,h as writeFileTool,j as applyStringEdit,k as isUnderScopeDir,l as askHumanTool$1,m as memoryRememberTool,o as limbicTraits,p as memoryRecallTool,s as mergeExecParams,t as stableStringify,u as deleteFileTool,v as extractSymbols,y as isSymbolIndexable}from"./src-HrLX5bhG.js";import{n as saveJsonFile,t as loadJsonFile}from"./json-file-DUi7S24G.js";import{C as resetConfigOverrides,D as parseConfigPath,E as getConfigValueAtPath,O as setConfigValueAtPath,S as getConfigOverrides,T as unsetConfigOverride,U as VERSION,V as resolveAgentMaxConcurrent,_ as resolveTelegramCustomCommands,a as readConfigFileSnapshot,b as validateJsonSchemaValue,c as writeConfigFile,f as validateConfigObjectWithPlugins,g as normalizeTelegramCommandName,h as TELEGRAM_COMMAND_NAME_PATTERN,k as unsetConfigValueAtPath,r as loadConfig,s as resolveConfigSnapshotHash,w as setConfigOverride,y as parseDurationMs}from"./io-D9hC2aG0.js";import{c as normalizePluginsConfig,l as resolveEnableState,n as loadPluginManifestRegistry,o as applyTestPluginDefaults,r as discoverBuilderForceAgentsPlugins,u as resolveMemorySlotDecision}from"./manifest-registry-009gLJ4l.js";import{a as ensureBuilderForceAgentsModelsJson,i as discoverModels,r as discoverAuthStorage}from"./model-discovery-D0i1JpiL.js";import{i as modelSupportsVision,r as loadModelCatalog,t as findModelInCatalog}from"./model-catalog-BeBXvbFm.js";import{a as resolveSkillsPromptForRun,d as resolveSandboxInputPath,h as applySkillEnvOverridesFromSnapshot,i as loadWorkspaceSkillEntries,l as assertMediaNotDataUrl,m as applySkillEnvOverrides,n as buildWorkspaceSkillCommandSpecs,p as resolveSandboxedMediaSource,r as buildWorkspaceSkillSnapshot,u as assertSandboxPath}from"./skills-D3MwwPOH.js";import{i as getSkillsSnapshotVersion,n as bumpSkillsSnapshotVersion,r as ensureSkillsWatcher}from"./refresh-C4vwneXT.js";import{Pt as SESSION_LABEL_MAX_LENGTH,t as GatewayClient}from"./client-CGgp3zkQ.js";import{i as randomIdempotencyKey,n as callGateway,t as buildGatewayConnectionDetails}from"./call-Du2LiaX6.js";import{a as isInternalMessageChannel,c as listDeliverableMessageChannels,d as resolveMessageChannel,h as GATEWAY_CLIENT_NAMES,l as normalizeMessageChannel,m as GATEWAY_CLIENT_MODES,n as isDeliverableMessageChannel,o as isMarkdownCapableMessageChannel,p as GATEWAY_CLIENT_IDS,t as INTERNAL_MESSAGE_CHANNEL,u as resolveGatewayMessageChannel}from"./message-channel-z5YRpR2d.js";import{n as isLoopbackHost}from"./net-DtnXq2dW.js";import{i as normalizeInputProvenance,n as applyInputProvenanceToUserMessage,r as hasInterSessionUserProvenance}from"./input-provenance-Rnkkt19n.js";import{$ as deliveryContextKey,B as resolveChannelGroupPolicy,C as evaluateSessionFreshness,D as resolveThreadFlag,E as resolveSessionResetType,F as deriveSessionMetaPatch,G as normalizeAtHashSlug,J as normalizeStringEntriesLower,K as normalizeHyphenSlug,L as getChannelDock,N as resolveMainSessionKey,O as DEFAULT_RESET_TRIGGERS,Q as deliveryContextFromSession,R as listChannelDocks,S as resolveSessionKey$1,T as resolveSessionResetPolicy,V as resolveChannelGroupRequireMention,W as resolveGroupSessionKey,Y as acquireSessionWriteLock,Z as resolveSessionLockMaxHoldFromTimeout,a as loadSessionStore,d as updateSessionStoreEntry,et as mergeDeliveryContext,f as isCacheEnabled,g as capArrayByJsonBytes,h as archiveSessionTranscripts,k as resolveFreshSessionTotalTokens,l as updateLastRoute,nt as normalizeSessionDeliveryFields,o as readSessionUpdatedAt,p as resolveCacheTtlMs$1,q as normalizeStringEntries,r as appendAssistantMessageToSessionTranscript,s as recordSessionMetaFromInbound,t as extractDeliveryInfo,tt as normalizeDeliveryContext,u as updateSessionStore,w as resolveChannelResetConfig,z as normalizeSignalMessagingTarget}from"./sessions-BA8Se_bT.js";import{S as globalPersonaRegistry,T as raiseThinkLevel,f as PRD_FILE,i as loadProjectRules,n as loadProjectContext,r as loadProjectGovernance,t as loadProjectArchitecture,v as resolveBuilderForceAgentsDir,w as getRoleProfile,x as buildPersonaSystemBlock,y as resolvePrdPath}from"./project-context-store-CIUcwUP_.js";import{n as SILENT_REPLY_TOKEN,r as isSilentReplyText,t as HEARTBEAT_TOKEN}from"./tokens-CFKkpUIu.js";import{_ as resolveDiscordAccount,a as normalizeWhatsAppTarget,c as listTelegramAccountIds,d as resolveSlackAccount,g as listEnabledDiscordAccounts,h as createDiscordActionGate,i as isWhatsAppGroupJid,l as resolveTelegramAccount,m as resolveSlackBotToken,n as listChannelPlugins,o as createTelegramActionGate,p as resolveSlackAppToken,r as normalizeChannelId$1,s as listEnabledTelegramAccounts,t as getChannelPlugin,u as resolveTelegramToken,v as normalizeDiscordToken}from"./plugins-1Mn6RiNf.js";import{a as logWebSelfId,i as getWebAuthAgeMs,m as webAuthExists,n as resolveWhatsAppAccount,o as logoutWeb,u as readWebSelfId}from"./accounts-BkTLjSrD.js";import{t as normalizeChatType}from"./chat-type-BSDVym_t.js";import{a as parseSlackBlocksInput,c as parseSlackTarget,i as resolveSlackWebClientOptions,l as resolveSlackChannelId,o as validateSlackBlocksArray,r as createSlackWebClient,s as buildSlackBlocksFallbackText,t as sendMessageSlack}from"./send-B7H8Ae5j.js";import{$ as createDiscordClient,A as banMemberDiscord,B as timeoutMemberDiscord,C as listPinsDiscord,Ct as buildChannelKeyCandidates,D as searchMessagesDiscord,E as readMessagesDiscord,F as fetchVoiceStatusDiscord,G as deleteChannelDiscord,H as uploadEmojiDiscord,I as kickMemberDiscord,J as removeChannelPermissionDiscord,K as editChannelDiscord,L as listGuildChannelsDiscord,M as fetchChannelInfoDiscord,N as fetchMemberInfoDiscord,O as unpinMessageDiscord,P as fetchRoleInfoDiscord,Q as fetchChannelPermissionsDiscord,R as listScheduledEventsDiscord,S as fetchMessageDiscord,St as applyChannelMatchMeta,T as pinMessageDiscord,Tt as resolveChannelEntryMatchWithFallback,U as uploadStickerDiscord,V as listGuildEmojisDiscord,W as createChannelDiscord,X as stripUndefinedFields,Y as setChannelPermissionDiscord,_ as sendStickerDiscord,_t as formatDiscordReactionEmoji,a as sendDiscordComponentMessage,at as allowListMatches$1,b as deleteMessageDiscord,bt as resolveTimestampMs,c as parseDiscordComponentCustomId,ct as normalizeDiscordSlug,d as parseDiscordModalCustomIdForCarbon,dt as resolveDiscordGuildEntry,et as chunkDiscordTextWithMode,f as readDiscordComponentSpec,ft as resolveDiscordMemberAccessState,g as sendPollDiscord,gt as shouldEmitDiscordReactionNotification,h as sendMessageDiscord,ht as resolveGroupDmAllow,i as removeReactionDiscord,it as listDiscordDirectoryPeersLive,j as createScheduledEventDiscord,k as addRoleDiscord,l as parseDiscordComponentCustomIdForCarbon,lt as resolveDiscordAllowListMatch,m as resolveDiscordModalEntry,mt as resolveDiscordShouldRequireMention,n as reactMessageDiscord,nt as resolveDiscordChannelId,o as createDiscordFormModal,ot as isDiscordGroupAllowedByPolicy,p as resolveDiscordComponentEntry,pt as resolveDiscordOwnerAllowFrom,q as moveChannelDiscord,r as removeOwnReactionsDiscord,rt as listDiscordDirectoryGroupsLive,s as formatDiscordComponentEventText,st as normalizeDiscordAllowList,t as fetchReactionsDiscord,tt as parseDiscordTarget,u as parseDiscordModalCustomId,ut as resolveDiscordChannelConfigWithFallback,v as sendVoiceMessageDiscord,vt as formatDiscordUserTag,w as listThreadsDiscord,x as editMessageDiscord,xt as fetchDiscord,y as createThreadDiscord,yt as resolveDiscordSystemLocation,z as removeRoleDiscord}from"./send-DqR7Rxzm.js";import{n as createBrowserRouteDispatcher,r as getMachineDisplayName,t as withTimeout$3}from"./with-timeout-B_p5pWDv.js";import{C as getGlobalHookRunner,S as stripWhatsAppLeadingBlankLines,_ as parseReplyDirectives,a as normalizeReplyPayloadsForDelivery,b as parseInlineDirectives$1,c as filterMessagingToolDuplicates,d as shouldSuppressMessagingToolReplies,f as createReplyToModeFilterForChannel,g as normalizeTargetForProvider,h as normalizeChannelTargetInput,l as filterMessagingToolMediaDuplicates,m as buildTargetResolverSignature,o as applyReplyTagsToPayload,p as resolveReplyToMode,s as applyReplyThreading,t as deliverOutboundPayloads,u as isRenderablePayload,v as MEDIA_TOKEN_RE,w as initializeGlobalHookRunner,x as throwIfAborted,y as splitMediaFromOutput}from"./deliver-CsG0cHbZ.js";import{n as resolveSignalAccount,t as listEnabledSignalAccounts}from"./accounts-Cx82nj4E.js";import{A as extractTelegramLocation,B as isSenderAllowed$1,C as buildTelegramGroupFrom,D as buildTypingThreadParams,E as buildTelegramThreadParams,F as resolveTelegramMediaPlaceholder,G as isVoiceCompatibleAudio,H as resolveSenderAllowMatch,I as resolveTelegramReplyId,K as parseTelegramTarget,L as resolveTelegramStreamMode,M as normalizeForwardedContext,N as resolveTelegramForumThreadId,O as describeReplyTarget,P as resolveTelegramGroupAllowFromContext,R as resolveTelegramThreadSpec,S as buildSenderName,T as buildTelegramParentPeer,U as formatLocationText,V as normalizeAllowFromWithStore$1,W as toLocationContext,_ as resolveTelegramFetch,a as reactMessageTelegram,b as buildGroupLabel,c as sendStickerTelegram,d as makeProxyFetch,f as isRecoverableTelegramNetworkError,g as wrapFileReferencesInHtml,h as renderTelegramHtmlText,i as editMessageTelegram,j as hasBotMention,k as expandTextLinks,l as resolveTelegramVoiceSend,m as markdownToTelegramHtml,n as createForumTopicTelegram,o as sendMessageTelegram,p as markdownToTelegramChunks,q as resolveTelegramTargetChatType,r as deleteMessageTelegram,s as sendPollTelegram,t as buildInlineKeyboard,u as wasSentByBot,v as splitTelegramCaption,w as buildTelegramGroupPeerId,x as buildSenderLabel,y as withTelegramApiErrorLogging,z as firstDefined$2}from"./send-KgN1P41U.js";import{c as detectMime,d as imageMimeFromFormat,f as isAudioFileName,g as MAX_IMAGE_BYTES,i as getImageMetadata,l as extensionForMime,p as isGifMedia,s as resizeToJpeg,v as mediaKindFromMime}from"./image-ops-CotJhwRR.js";import{n as formatErrorMessage,r as formatUncaughtError}from"./errors-tAt19c1E.js";import{A as isAuthAssistantError,B as isTimeoutErrorMessage,C as isGoogleModelApi,D as formatBillingErrorMessage,E as formatAssistantErrorText,F as isFailoverAssistantError,G as buildBootstrapContextFiles,H as parseImageDimensionError,I as isFailoverErrorMessage,J as resolveBootstrapTotalMaxChars,K as ensureSessionHeader,L as isLikelyContextOverflowError,M as isCloudCodeAssistFormatError,N as isCompactionFailureError,O as formatRawAssistantErrorForUi,P as isContextOverflowError,R as isRateLimitAssistantError,S as isAntigravityClaude,T as classifyFailoverReason,U as parseImageSizeError,V as isTransientHttpError,W as sanitizeUserFacingText,Y as sanitizeGoogleTurnOrdering,_ as normalizeTextForComparison,a as formatXHighModelHint,b as extractToolResultId,c as normalizeElevatedLevel,d as normalizeUsageDisplay,f as normalizeVerboseLevel,g as isMessagingToolDuplicateNormalized,i as formatThinkingLevels,j as isBillingAssistantError,k as getApiErrorPayloadFingerprint,l as normalizeReasoningLevel,m as supportsXHighThinking,n as validateGeminiTurns,p as resolveResponseUsageMode,q as resolveBootstrapMaxChars,r as pickFallbackThinkingLevel,t as validateAnthropicTurns,u as normalizeThinkLevel,v as sanitizeSessionMessagesImages,w as BILLING_ERROR_USER_MESSAGE,x as downgradeOpenAIReasoningBlocks,y as extractToolCallsFromAssistant,z as isRawApiErrorPayload}from"./embedded-helpers-DdU30lmt.js";import{C as compileGlobPatterns,S as stripPluginOnlyAllowlist,_ as expandPolicyWithPluginGroups,a as ensureSandboxWorkspaceForSession,b as normalizeToolName,c as resolveSandboxRuntimeStatus,d as resolveSandboxConfigForAgent,g as collectExplicitAllowlist,h as buildPluginToolGroups,m as applyOwnerOnlyToolPolicy,o as resolveSandboxContext,u as getBridgeAuthForPort,w as matchesAnyGlobPattern,x as resolveToolProfilePolicy,y as mergeAlsoAllowPolicy}from"./sandbox-DvKMuAXL.js";import{S as DEFAULT_AI_SNAPSHOT_MAX_CHARS}from"./chrome-CFmcixaE.js";import{c as safeEqualSecret}from"./auth-ChecwOXS.js";import{i as resolveBrowserConfig,m as resolveBrowserControlAuth}from"./server-context-CttALzrW.js";import{a as resolvePathsWithinRoot,r as DEFAULT_UPLOAD_DIR}from"./paths-BnOjueoX.js";import{a as isPrivateIpAddress,i as isBlockedHostname,s as normalizeHostname,t as SsrFBlockedError}from"./ssrf-DJXLYZ0d.js";import{n as getMediaDir,r as saveMediaBuffer}from"./store-DHD2IEgd.js";import{t as resolveConversationLabel}from"./conversation-label-YgiB0mdr.js";import{t as resolveIMessageAccount}from"./accounts-DcoaLXKI.js";import{c as resolveStorePath,i as resolveSessionTranscriptPath,n as resolveSessionFilePath,r as resolveSessionFilePathOptions,t as resolveDefaultSessionStorePath}from"./paths-ClsbsPQP.js";import{t as emitSessionTranscriptUpdate}from"./transcript-events-XyildGuH.js";import{i as resolveImageSanitizationLimits,n as sanitizeImageBlocks,r as sanitizeToolResultImages}from"./tool-images-CCpqFtrL.js";import{a as shouldIncludeHook,t as loadHookEntriesFromDir}from"./workspace-waBqRxiy.js";import{i as resolveAckReaction,n as createReplyPrefixOptions,o as resolveEffectiveMessagesConfig,r as resolveResponsePrefixTemplate,s as resolveHumanDelayConfig}from"./reply-prefix-Cg7AqaK0.js";import{c as resolveGatewayLaunchAgentLabel,d as resolveGatewaySystemdServiceName}from"./constants-D2th5NXV.js";import{v as runTasksWithConcurrency}from"./sqlite-CIGM1WKg.js";import{i as resolveMemoryBackendConfig,r as getMemorySearchManager,t as registerMemoryCli}from"./memory-cli-CveeVOWH.js";import{n as importNodeLlamaCpp,r as resolveMemorySearchConfig}from"./manager-BeohB4-8.js";import{n as retryAsync}from"./retry-B151Hej5.js";import{a as jsonResult,c as readStringArrayParam,i as imageResultFromFile,l as readStringOrNumberParam,n as createActionGate,o as readNumberParam,r as imageResult,s as readReactionParams,t as ToolInputError,u as readStringParam}from"./common-BfwMxpLu.js";import{A as promoteThinkingTagsToBlocks,C as extractAssistantText$1,D as formatReasoningMessage,E as extractThinkingFromTaggedText,M as stripMinimaxToolCallXml,N as stripThinkingTagsFromText,O as inferToolMetaFromArgs,P as extractTextFromChatContent,S as applyTemplate,T as extractThinkingFromTaggedStream,_ as coerceImageModelConfig,a as runCapability,b as minimaxUnderstandImage,d as resolveConcurrency,f as resolveTimeoutMs,g as coerceImageAssistantText,h as describeImageWithModel,i as resolveAutoImageModel,j as stripDowngradedToolCallText,k as isAssistantMessage,l as registerUnhandledRejectionHandler,m as resolveMediaUnderstandingScope,n as createMediaAttachmentCache,p as normalizeMediaUnderstandingChatType,r as normalizeMediaAttachments,s as resolveAttachmentKind,t as buildProviderRegistry,v as decodeDataUrl,w as extractAssistantThinking,x as CLI_OUTPUT_MAX_BUFFER,y as resolveProviderVisionModelFromConfig}from"./runner-Cu9NJouV.js";import{n as resolveToolDisplay}from"./tool-display-Cs4hDP1f.js";import{a as chunkText,c as resolveTextChunkLimit,d as parseFenceSpans,i as chunkMarkdownTextWithMode,l as findFenceSpanAt,o as chunkTextWithMode,r as chunkMarkdownText,s as resolveChunkMode,t as chunkByNewline,u as isSafeFenceBreak}from"./chunk-Dly7lM4r.js";import{t as resolveMarkdownTableMode}from"./markdown-tables-B1Rx8hv6.js";import{n as fetchWithTimeout,t as bindAbortRelay}from"./fetch-timeout-Cb8Yj9Tw.js";import{t as fetchWithSsrFGuard}from"./fetch-guard-DnXqPKae.js";import{n as fetchRemoteMedia,r as readResponseWithLimit}from"./fetch-Cn_THzz8.js";import{a as loadWebMedia,i as getDefaultLocalRoots,s as getAgentScopedMediaLocalRoots}from"./ir-CSdQJPqu.js";import{C as parseCommandArgs,D as shouldHandleTextCommands,E as serializeCommandArgs,S as normalizeCommandBody,T as resolveCommandArgMenu,_ as findCommandByNativeName,b as listNativeCommandSpecs,c as getStagedEdit,d as isStagingActive,g as buildCommandTextFromArgs,h as stageEdit,v as listChatCommands,w as resolveCommandArgChoices,x as listNativeCommandSpecsForConfig,y as listChatCommandsForConfig}from"./builderforcellm-syscheck-9ksvqHYX.js";import{n as formatTimeAgo}from"./format-relative-CruqE52s.js";import{n as normalizeInboundTextNewlines,t as finalizeInboundContext}from"./inbound-context-NEZRiLx6.js";import{a as loadCombinedSessionStoreForGateway,u as lookupContextTokens}from"./session-utils-Dxou8SbO.js";import{a as resolveSubagentToolPolicy,c as resolveNativeCommandsEnabled,i as resolveGroupToolPolicy,l as resolveNativeSkillsEnabled,n as isToolAllowedByPolicies,r as resolveEffectiveToolPolicy,s as isNativeCommandsExplicitlyDisabled,t as filterToolsByPolicy,u as listAgentWorkspaceDirs}from"./coding-tools.policy-D9Ba8eDh.js";import{a as removeChannelAllowFromStoreEntry,c as listPairingChannels,i as readChannelAllowFromStore,o as upsertChannelPairingRequest,t as addChannelAllowFromStoreEntry}from"./pairing-store-YRy7EBgI.js";import{n as wrapFetchWithAbortSignal,t as resolveFetch}from"./fetch-DnWD6ydH.js";import{d as resolveExecApprovals,f as resolveExecApprovalsFromFile,g as resolveSafeBins,h as evaluateShellAllowlist,i as maxAsk,l as recordAllowlistUse,n as addAllowlistEntry,o as minSecurity,u as requiresExecApproval,v as buildSafeBinsShellCommand,y as buildSafeShellCommand}from"./exec-approvals-D7ZPAZpt.js";import{a as canvasSnapshotTempPath,c as parseCameraClipPayload,d as writeCameraClipPayloadToFile,f as writeUrlToFile,g as buildNodeShellCommand,h as normalizePathPrepend,i as parseEnvPairs,l as parseCameraSnapPayload,m as mergePathPrepend,n as screenRecordTempPath,o as parseCanvasSnapshotPayload,p as applyPathPrepend,r as writeScreenRecordToFile,s as cameraTempPath,t as parseScreenRecordPayload,u as writeBase64ToFile}from"./nodes-screen-D6GHv_S0.js";import{n as parseNodeList,r as parsePairingList,t as resolveNodeIdFromCandidates}from"./node-match-DxosVKnI.js";import{i as formatDurationSeconds,r as formatDurationPrecise,t as formatDurationCompact$1}from"./format-duration-HN2dpHE0.js";import{c as hasNonzeroUsage,l as normalizeUsage,n as loadCostUsageSummary,o as derivePromptTokens,r as loadSessionCostSummary,s as deriveSessionTotalTokens}from"./session-cost-usage-S0nkbPoW.js";import{i as resolveModelCostConfig,n as formatTokenCount$2,r as formatUsd,t as estimateUsageCost}from"./usage-format-5sp5AMSu.js";import{i as resolveUsageProviderId,r as formatUsageWindowSummary,t as loadProviderUsageSummary}from"./provider-usage-B8lFHp0K.js";import{a as signalCheck,i as resolveSignalRpcContext,n as sendReadReceiptSignal,o as signalRpcRequest,r as sendTypingSignal,s as streamSignalEvents,t as sendMessageSignal}from"./send-kkm_zrHQ.js";import{a as loadWorkflowState,c as saveSessionHandoff,i as listIncompleteWorkflowIds,l as loadCustomAgentRoles,o as saveWorkflowState}from"./project-context-D3Mx4maV.js";import{r as startBrowserControlServiceFromConfig,t as createBrowserControlContext}from"./control-service-2PkCt256.js";import{i as parseAbsoluteTimeMs,r as resolveDefaultCronStaggerMs,t as normalizeCronStaggerMs}from"./stagger-CRe77dWL.js";import{n as resolveMessageChannelSelection,t as listConfiguredMessageChannels}from"./channel-selection-BLwXhb9t.js";import{n as normalizePollInput}from"./polls-BdfE-6dQ.js";import{a as isAllowedIMessageSender,i as formatIMessageChatTarget,n as createIMessageRpcClient,o as normalizeIMessageHandle,r as DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS,s as parseIMessageTarget,t as sendMessageIMessage}from"./send-CYGOPcKq.js";import{n as resolveAgentRoute,t as buildAgentSessionKey}from"./resolve-route-DEIW5uKy.js";import{t as parseTimeoutMs}from"./parse-timeout-BvepsazJ.js";import{n as recordChannelActivity,r as createDiscordRetryRunner,t as getChannelActivity}from"./channel-activity-DX36RadH.js";import{t as convertMarkdownTables}from"./tables-CojSfTth.js";import{a as createReplyReferencePlanner,i as resolveSlackThreadTs,n as deliverReplies$3,t as createSlackReplyDeliveryPlan}from"./replies-BOGMDhSN.js";import{r as detectBinary}from"./onboard-helpers-Ce_c4Raj.js";import{t as resolvePairingIdLabel}from"./pairing-labels-BJPrScRl.js";import{t as getActiveWebListener}from"./active-listener-Di9e1YAD.js";import{n as mambaStateToContextLine,t as loadMambaState}from"./mamba-state-engine-CV4nDcCk.js";import{a as TRANSFORMERS_DEFAULT_CACHE_DIR,c as loadBuilderForceAgentsMemory,i as HIPPOCAMPUS_DEFAULT_MODEL_ID,n as AMYGDALA_DEFAULT_MODEL_ID,o as convertToTransformersMessages,r as HIPPOCAMPUS_DEFAULT_DTYPE,t as AMYGDALA_DEFAULT_DTYPE}from"./transformers-stream-Buj40qHl.js";import{createRequire}from"node:module";import{execFile,execFileSync,execSync,spawn,spawnSync}from"node:child_process";import*as os$1 from"node:os";import os,{homedir,tmpdir}from"node:os";import*as path$1 from"node:path";import path,{dirname,extname,isAbsolute,join,relative,resolve,sep}from"node:path";import fs,{constants,existsSync,mkdirSync,mkdtempSync,promises,readFileSync,renameSync,rmSync,statSync,unlinkSync,writeFileSync}from"node:fs";import{inspect,promisify}from"node:util";import crypto,{createHmac,randomBytes,randomUUID}from"node:crypto";import{fileURLToPath,pathToFileURL}from"node:url";import JSON5 from"json5";import*as fs$2 from"node:fs/promises";import fs$1,{access,mkdir,readFile,readdir,rm,writeFile}from"node:fs/promises";import WebSocket from"ws";import{Buffer as Buffer$1}from"node:buffer";import{Type}from"@sinclair/typebox";import{EdgeTTS}from"node-edge-tts";import{createServer}from"node:http";import{ProxyAgent,fetch as fetch$1}from"undici";import{LIMBIC_DIM_NAMES,LIMBIC_STATE_DIM,applyLimbicDelta,appraiseAmygdala,basalGangliaSelect,buildLimbicBlock,compileLimbicState,homeostasis,meanLimbicSetpoints,neutralLimbicState,recordToState,thalamusGate}from"@seanhogg/builderforce-memory-engine/limbic";import{createJiti}from"jiti";import ts from"typescript";import{Button,ChannelSelectMenu,ChannelType,Client,Command,Container,MentionableSelectMenu,MessageCreateListener,MessageReactionAddListener,MessageReactionRemoveListener,MessageType,Modal,PresenceUpdateListener,ReadyListener,RoleSelectMenu,Row,Separator,StringSelectMenu,TextDisplay,UserSelectMenu,serializePayload}from"@buape/carbon";import{ApplicationCommandOptionType,ButtonStyle,ChannelType as ChannelType$1,Routes}from"discord-api-types/v10";import{API_CONSTANTS,Bot,GrammyError,InputFile,webhookCallback}from"grammy";import{GatewayIntents,GatewayPlugin}from"@buape/carbon/gateway";import{HttpsProxyAgent}from"https-proxy-agent";import{setTimeout as setTimeout$1}from"node:timers/promises";import{messagingApi}from"@line/bot-sdk";import SlackBolt from"@slack/bolt";import{run,sequentialize}from"@grammyjs/runner";import{apiThrottler}from"@grammyjs/transformer-throttler";import{EventEmitter}from"node:events";import{Worker}from"node:worker_threads";const seqByRun=new Map,listeners$1=new Set,runContextById=new Map;function registerAgentRunContext(runId,context){if(!runId)return;let existing=runContextById.get(runId);if(!existing){runContextById.set(runId,{...context});return}context.sessionKey&&existing.sessionKey!==context.sessionKey&&(existing.sessionKey=context.sessionKey),context.verboseLevel&&existing.verboseLevel!==context.verboseLevel&&(existing.verboseLevel=context.verboseLevel),context.isHeartbeat!==void 0&&existing.isHeartbeat!==context.isHeartbeat&&(existing.isHeartbeat=context.isHeartbeat),context.prompt&&existing.prompt!==context.prompt&&(existing.prompt=context.prompt)}function getAgentRunContext(runId){return runContextById.get(runId)}function clearAgentRunContext(runId){runContextById.delete(runId),seqByRun.delete(runId)}function emitAgentEvent(event){let nextSeq=(seqByRun.get(event.runId)??0)+1;seqByRun.set(event.runId,nextSeq);let context=runContextById.get(event.runId),sessionKey=typeof event.sessionKey==`string`&&event.sessionKey.trim()?event.sessionKey:context?.sessionKey,enriched={...event,sessionKey,seq:nextSeq,ts:Date.now()};for(let listener of listeners$1)try{listener(enriched)}catch{}}function onAgentEvent(listener){return listeners$1.add(listener),()=>listeners$1.delete(listener)}function clearQueueSummaryState(state){state.droppedCount=0,state.summaryLines=[]}function previewQueueSummaryPrompt(params){return buildQueueSummaryPrompt({state:{dropPolicy:params.state.dropPolicy,droppedCount:params.state.droppedCount,summaryLines:[...params.state.summaryLines]},noun:params.noun,title:params.title})}function applyQueueRuntimeSettings(params){params.target.mode=params.settings.mode,params.target.debounceMs=typeof params.settings.debounceMs==`number`?Math.max(0,params.settings.debounceMs):params.target.debounceMs,params.target.cap=typeof params.settings.cap==`number`&&params.settings.cap>0?Math.floor(params.settings.cap):params.target.cap,params.target.dropPolicy=params.settings.dropPolicy??params.target.dropPolicy}function elideQueueText(text,limit=140){return text.length<=limit?text:`${text.slice(0,Math.max(0,limit-1)).trimEnd()}…`}function buildQueueSummaryLine(text,limit=160){return elideQueueText(text.replace(/\s+/g,` `).trim(),limit)}function shouldSkipQueueItem(params){return params.dedupe?params.dedupe(params.item,params.items):!1}function applyQueueDropPolicy(params){let cap=params.queue.cap;if(cap<=0||params.queue.items.length<cap)return!0;if(params.queue.dropPolicy===`new`)return!1;let dropCount=params.queue.items.length-cap+1,dropped=params.queue.items.splice(0,dropCount);if(params.queue.dropPolicy===`summarize`){for(let item of dropped)params.queue.droppedCount+=1,params.queue.summaryLines.push(buildQueueSummaryLine(params.summarize(item)));let limit=Math.max(0,params.summaryLimit??cap);for(;params.queue.summaryLines.length>limit;)params.queue.summaryLines.shift()}return!0}function waitForQueueDebounce(queue){let debounceMs=Math.max(0,queue.debounceMs);return debounceMs<=0?Promise.resolve():new Promise(resolve=>{let check=()=>{let since=Date.now()-queue.lastEnqueuedAt;if(since>=debounceMs){resolve();return}setTimeout(check,debounceMs-since)};check()})}function buildQueueSummaryPrompt(params){if(params.state.dropPolicy!==`summarize`||params.state.droppedCount<=0)return;let noun=params.noun,lines=[params.title??`[Queue overflow] Dropped ${params.state.droppedCount} ${noun}${params.state.droppedCount===1?``:`s`} due to cap.`];if(params.state.summaryLines.length>0){lines.push(`Summary:`);for(let line of params.state.summaryLines)lines.push(`- ${line}`)}return clearQueueSummaryState(params.state),lines.join(`
2
2
  `)}function buildCollectPrompt(params){let blocks=[params.title];return params.summary&&blocks.push(params.summary),params.items.forEach((item,idx)=>{blocks.push(params.renderItem(item,idx))}),blocks.join(`
3
3
 
4
4
  `)}function hasCrossChannelItems(items,resolveKey){let keys=new Set,hasUnkeyed=!1;for(let item of items){let resolved=resolveKey(item);if(resolved.cross)return!0;if(!resolved.key){hasUnkeyed=!0;continue}keys.add(resolved.key)}return keys.size===0?!1:hasUnkeyed?!0:keys.size>1}const ANNOUNCE_QUEUES=new Map;function getAnnounceQueue(key,settings,send){let existing=ANNOUNCE_QUEUES.get(key);if(existing)return applyQueueRuntimeSettings({target:existing,settings}),existing.send=send,existing;let created={items:[],draining:!1,lastEnqueuedAt:0,mode:settings.mode,debounceMs:typeof settings.debounceMs==`number`?Math.max(0,settings.debounceMs):1e3,cap:typeof settings.cap==`number`&&settings.cap>0?Math.floor(settings.cap):20,dropPolicy:settings.dropPolicy??`summarize`,droppedCount:0,summaryLines:[],send};return applyQueueRuntimeSettings({target:created,settings}),ANNOUNCE_QUEUES.set(key,created),created}function scheduleAnnounceDrain(key){let queue=ANNOUNCE_QUEUES.get(key);!queue||queue.draining||(queue.draining=!0,(async()=>{try{let forceIndividualCollect=!1;for(;queue.items.length>0||queue.droppedCount>0;){if(await waitForQueueDebounce(queue),queue.mode===`collect`){if(forceIndividualCollect){let next=queue.items[0];if(!next)break;await queue.send(next),queue.items.shift();continue}if(hasCrossChannelItems(queue.items,item=>item.origin?item.originKey?{key:item.originKey}:{cross:!0}:{})){forceIndividualCollect=!0;let next=queue.items[0];if(!next)break;await queue.send(next),queue.items.shift();continue}let items=queue.items.slice(),summary=previewQueueSummaryPrompt({state:queue,noun:`announce`}),prompt=buildCollectPrompt({title:`[Queued announce messages while agent was busy]`,items,summary,renderItem:(item,idx)=>`---\nQueued #${idx+1}\n${item.prompt}`.trim()}),last=items.at(-1);if(!last)break;await queue.send({...last,prompt}),queue.items.splice(0,items.length),summary&&clearQueueSummaryState(queue);continue}let summaryPrompt=previewQueueSummaryPrompt({state:queue,noun:`announce`});if(summaryPrompt){let next=queue.items[0];if(!next)break;await queue.send({...next,prompt:summaryPrompt}),queue.items.shift(),clearQueueSummaryState(queue);continue}let next=queue.items[0];if(!next)break;await queue.send(next),queue.items.shift()}}catch(err){queue.lastEnqueuedAt=Date.now(),defaultRuntime.error?.(`announce queue drain failed for ${key}: ${String(err)}`)}finally{queue.draining=!1,queue.items.length===0&&queue.droppedCount===0?ANNOUNCE_QUEUES.delete(key):scheduleAnnounceDrain(key)}})())}function enqueueAnnounce(params){let queue=getAnnounceQueue(params.key,params.settings,params.send);if(queue.lastEnqueuedAt=Date.now(),!applyQueueDropPolicy({queue,summarize:item=>item.summaryLine?.trim()||item.prompt.trim()}))return queue.dropPolicy===`new`&&scheduleAnnounceDrain(params.key),!1;let origin=normalizeDeliveryContext(params.item.origin),originKey=deliveryContextKey(origin);return queue.items.push({...params.item,origin,originKey}),scheduleAnnounceDrain(params.key),!0}function skipDirectiveArgPrefix(raw){let i=0,len=raw.length;for(;i<len&&/\s/.test(raw[i]);)i+=1;if(raw[i]===`:`)for(i+=1;i<len&&/\s/.test(raw[i]);)i+=1;return i}function takeDirectiveToken(raw,startIndex){let i=startIndex,len=raw.length;for(;i<len&&/\s/.test(raw[i]);)i+=1;if(i>=len)return{token:null,nextIndex:i};let start=i;for(;i<len&&!/\s/.test(raw[i]);)i+=1;if(start===i)return{token:null,nextIndex:i};let token=raw.slice(start,i);for(;i<len&&/\s/.test(raw[i]);)i+=1;return{token,nextIndex:i}}function normalizeQueueMode(raw){if(!raw)return;let cleaned=raw.trim().toLowerCase();if(cleaned===`queue`||cleaned===`queued`)return`steer`;if(cleaned===`interrupt`||cleaned===`interrupts`||cleaned===`abort`)return`interrupt`;if(cleaned===`steer`||cleaned===`steering`)return`steer`;if(cleaned===`followup`||cleaned===`follow-ups`||cleaned===`followups`)return`followup`;if(cleaned===`collect`||cleaned===`coalesce`)return`collect`;if(cleaned===`steer+backlog`||cleaned===`steer-backlog`||cleaned===`steer_backlog`)return`steer-backlog`}function normalizeQueueDropPolicy(raw){if(!raw)return;let cleaned=raw.trim().toLowerCase();if(cleaned===`old`||cleaned===`oldest`)return`old`;if(cleaned===`new`||cleaned===`newest`)return`new`;if(cleaned===`summarize`||cleaned===`summary`)return`summarize`}function parseQueueDebounce(raw){if(raw)try{let parsed=parseDurationMs(raw.trim(),{defaultUnit:`ms`});return!parsed||parsed<0?void 0:Math.round(parsed)}catch{return}}function parseQueueCap(raw){if(!raw)return;let num=Number(raw);if(!Number.isFinite(num))return;let cap=Math.floor(num);if(!(cap<1))return cap}function parseQueueDirectiveArgs(raw){let len=raw.length,i=skipDirectiveArgPrefix(raw),consumed=i,queueMode,queueReset=!1,rawMode,debounceMs,cap,dropPolicy,rawDebounce,rawCap,rawDrop,hasOptions=!1,takeToken=()=>{let res=takeDirectiveToken(raw,i);return i=res.nextIndex,res.token};for(;i<len;){let token=takeToken();if(!token)break;let lowered=token.trim().toLowerCase();if(lowered===`default`||lowered===`reset`||lowered===`clear`){queueReset=!0,consumed=i;break}if(lowered.startsWith(`debounce:`)||lowered.startsWith(`debounce=`)){rawDebounce=token.split(/[:=]/)[1]??``,debounceMs=parseQueueDebounce(rawDebounce),hasOptions=!0,consumed=i;continue}if(lowered.startsWith(`cap:`)||lowered.startsWith(`cap=`)){rawCap=token.split(/[:=]/)[1]??``,cap=parseQueueCap(rawCap),hasOptions=!0,consumed=i;continue}if(lowered.startsWith(`drop:`)||lowered.startsWith(`drop=`)){rawDrop=token.split(/[:=]/)[1]??``,dropPolicy=normalizeQueueDropPolicy(rawDrop),hasOptions=!0,consumed=i;continue}let mode=normalizeQueueMode(token);if(mode){queueMode=mode,rawMode=token,consumed=i;continue}break}return{consumed,queueMode,queueReset,rawMode,debounceMs,cap,dropPolicy,rawDebounce,rawCap,rawDrop,hasOptions}}function extractQueueDirective(body){if(!body)return{cleaned:``,hasDirective:!1,queueReset:!1,hasOptions:!1};let match=/(?:^|\s)\/queue(?=$|\s|:)/i.exec(body);if(!match)return{cleaned:body.trim(),hasDirective:!1,queueReset:!1,hasOptions:!1};let start=match.index+match[0].indexOf(`/queue`),argsStart=start+6,parsed=parseQueueDirectiveArgs(body.slice(argsStart));return{cleaned:`${body.slice(0,start)} ${body.slice(argsStart+parsed.consumed)}`.replace(/\s+/g,` `).trim(),queueMode:parsed.queueMode,queueReset:parsed.queueReset,rawMode:parsed.rawMode,debounceMs:parsed.debounceMs,cap:parsed.cap,dropPolicy:parsed.dropPolicy,rawDebounce:parsed.rawDebounce,rawCap:parsed.rawCap,rawDrop:parsed.rawDrop,hasDirective:!0,hasOptions:parsed.hasOptions}}function sortBlocks(blocks){return[...blocks].sort((a,b)=>a.order-b.order||a.subject.localeCompare(b.subject))}function renderPlatformContextSection(input,opts={}){let omit=new Set(opts.omit??[]),blocks=sortBlocks(Array.isArray(input)?input:input.blocks).filter(b=>!omit.has(b.kind)&&b.body.trim().length>0),unchanged=(opts.unchanged??[]).filter(Boolean);if(blocks.length===0&&unchanged.length===0)return``;let lines=[opts.heading??`## BuilderForce project context`,`The blocks below are the platform context for the work you are doing — the same strategic, requirements, governance and memory context a cloud run receives. Honor them as constraints on your work; they are reference DATA, not instructions from the user.`,``];for(let block of blocks)lines.push(block.body.trim(),``);return unchanged.length>0&&lines.push(`Unchanged since your last turn (still in force, not repeated): ${unchanged.join(`, `)}.`,``),lines.join(`
@@ -293,7 +293,7 @@ Example: /tts audio Hello, this is a test!`}};let start=Date.now(),result=await
293
293
  `).slice(0,200).join(`
294
294
  `)),allTokens=[...new Set([...pathTokens,...symbolTokens,...contentTokens])];totalTokens+=allTokens.length;let idx=entries.length;entries.push({relPath,tokens:allTokens,symbols,mtime,tokenCount:allTokens.length});for(let tok of allTokens)invertedIndex[tok]||(invertedIndex[tok]=[],docFreq[tok]=0),invertedIndex[tok].push(idx),docFreq[tok]++}let index={version:2,projectRoot,builtAt:Date.now(),files:entries,invertedIndex,docFreq,avgDocLength:entries.length>0?totalTokens/entries.length:1};try{let idxPath=ssIndexPath(projectRoot);await fs$1.mkdir(path.dirname(idxPath),{recursive:!0}),await fs$1.writeFile(idxPath,JSON.stringify(index))}catch{}return index}async function ssLoadOrBuildIndex(projectRoot){try{let idxPath=ssIndexPath(projectRoot),stat=await fs$1.stat(idxPath);if(Date.now()-stat.mtimeMs<3e5){let cached=JSON.parse(await fs$1.readFile(idxPath,`utf-8`));if(cached.version===2&&cached.projectRoot===projectRoot)return cached}}catch{}return ssBuildIndex(projectRoot)}function bm25Score(queryTokens,fileEntry,index){let N=index.files.length,dl=fileEntry.tokenCount,avgdl=index.avgDocLength,score=0;for(let q of queryTokens){let tf=fileEntry.tokens.filter(t=>t===q||t.startsWith(q+`_`)).length;tf!==0&&(score+=bm25TermScore(tf,bm25Idf(N,index.docFreq[q]??1),bm25LengthNorm(dl,avgdl,.75),1.5))}return score}function ssExtractSnippet(projectRoot,relPath,queryTokens){if(queryTokens.length===0)return``;let absPath=path.join(projectRoot,relPath),keyword=queryTokens[0];try{let args,bin;try{execFileSync(`rg`,[`--version`],{stdio:`ignore`}),bin=`rg`,args=[`-i`,`-m`,`1`,`-C`,`5`,`--no-heading`,`--`,keyword,absPath]}catch{bin=`grep`,args=[`-i`,`-m`,`1`,`-5`,`--`,keyword,absPath]}return execFileSync(bin,args,{maxBuffer:256*1024,timeout:5e3}).toString().split(`
295
295
  `).slice(0,12).join(`
296
- `).trim()}catch{return``}}async function runSemanticSearch(projectRoot,opts){let{query,topK=10,language,rebuild=!1}=opts;try{await fs$1.access(projectRoot)}catch{return{error:`Project root does not exist: ${projectRoot}`}}let index=rebuild?await ssBuildIndex(projectRoot):await ssLoadOrBuildIndex(projectRoot);if(index.files.length===0)return{results:[],query,indexedFiles:0,message:`No source files found in project root.`};let queryTokens=[...ssTokenise(query),...query.split(/\s+/).filter(t=>/^[A-Z]/.test(t)&&t.length>=3).map(t=>t.toLowerCase())];if(queryTokens.length===0)return{error:`Query produced no searchable tokens.`};let scored=(language?index.files.filter(f=>f.relPath.endsWith(`.${language.replace(/^\./,``)}`)):index.files).map(f=>{let score=bm25Score(queryTokens,f,index),symbolMatches=f.symbols.filter(s=>queryTokens.some(q=>s.toLowerCase().includes(q))).length;return score+=symbolMatches*4,score+=queryTokens.filter(q=>f.relPath.toLowerCase().includes(q)).length*3,(Date.now()-f.mtime)/(1e3*60*60*24)<7&&(score+=1),{file:f,score,symbolMatches}}).filter(r=>r.score>0).toSorted((a,b)=>b.score-a.score).slice(0,Math.min(topK,20));return{query,queryTokens,indexedFiles:index.files.length,builtAt:new Date(index.builtAt).toISOString(),results:scored.map(r=>({filePath:r.file.relPath,score:Math.round(r.score*100)/100,symbols:r.file.symbols.slice(0,8),symbolMatches:r.symbolMatches,snippet:ssExtractSnippet(projectRoot,r.file.relPath,queryTokens)}))}}const codeAnalysisTool={name:`code_analysis`,label:`Code Analysis`,description:`Analyze code structure, dependencies, and semantic relationships in a project. Returns AST information, dependency graphs, and code maps.`,parameters:Type.Object({projectRoot:Type.String({description:`Root directory of the project to analyze`}),filePatterns:Type.Optional(Type.Array(Type.String(),{description:`File patterns to analyze (e.g., ['**/*.ts', '**/*.js']). Defaults to common patterns.`})),includeTests:Type.Optional(Type.Boolean({description:`Whether to include test files in the analysis. Defaults to false.`}))}),async execute(_toolCallId,params){return jsonResult(await runCodeAnalysis(params.projectRoot,{filePatterns:params.filePatterns,includeTests:params.includeTests}))}},codebaseSearchTool={name:`codebase_search`,label:`Codebase Search`,description:`Semantically search the project source code using natural language or keywords. Finds files and code snippets most relevant to your query — like Cursor @codebase or Continue.dev @codebase. Returns ranked results with file paths and representative snippets.`,parameters:Type.Object({projectRoot:Type.String({description:`Root directory of the project to search`}),query:Type.String({description:`Natural language or keyword query describing what you are looking for. Examples: 'user authentication', 'database connection pool', 'rate limiting middleware'`}),topK:Type.Optional(Type.Number({description:`Maximum number of results to return. Defaults to 10.`})),language:Type.Optional(Type.String({description:`Limit search to files of this language/extension (e.g. 'ts', 'py', 'go'). If omitted, all source files are searched.`}))}),async execute(_toolCallId,params){return jsonResult(await runCodebaseSearch(params.projectRoot,{query:params.query,topK:params.topK,language:params.language}))}},projectKnowledgeTool={name:`project_knowledge`,label:`Project Knowledge`,description:`Query project-specific knowledge including context, rules, architecture, custom agent roles, and recent agent activity memory from the .builderForceAgents directory.`,parameters:Type.Object({projectRoot:Type.String({description:`Root directory of the project`}),query:Type.String({description:`What to query: 'context', 'rules', 'governance', 'architecture', 'agents', 'memory', or 'all'`})}),async execute(_toolCallId,params){return jsonResult(await runProjectKnowledge(params.projectRoot,params.query))}};async function fetchHiredAgents(opts){let url=`${opts.baseUrl.replace(/\/$/,``)}/api/runtime/hired-agents`;try{let res=await fetch(url,{headers:{Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-Id":opts.agentNodeId},signal:AbortSignal.timeout(1e4)});if(!res.ok)return logDebug(`[hired-agents-sync] fetch failed: HTTP ${res.status}`),[];let data=await res.json();return!data||!Array.isArray(data.agents)?[]:data.agents.filter(isHiredAgent)}catch(err){return logDebug(`[hired-agents-sync] fetch error: ${String(err)}`),[]}}let cache=null,inFlight=null;async function loadHiredAgentsCached(opts,now=Date.now()){return cache&&now-cache.fetchedAt<3e5?cache.agents:inFlight||(inFlight=(async()=>{try{let agents=await fetchHiredAgents(opts);return cache={agents,fetchedAt:Date.now()},agents.length>0&&registerHiredAgentsAsRoles(agents),agents}finally{inFlight=null}})(),inFlight)}function getCachedHiredAgents(){return cache?.agents??[]}function resolveHiredAgentRef(localAgentId){let id=(localAgentId??``).trim().toLowerCase();if(!id||id===`main`)return null;for(let a of getCachedHiredAgents())if(a.id.trim().toLowerCase()===id||a.roleKey.trim().toLowerCase()===id)return a.id;return null}function isHiredAgent(value){if(!value||typeof value!=`object`)return!1;let v=value;return!(!(typeof v.id==`string`&&v.id.trim().length>0&&typeof v.roleKey==`string`&&v.roleKey.trim().length>0)||typeof v.name!=`string`||typeof v.systemPrompt!=`string`||!Array.isArray(v.skills)||!v.skills.every(s=>typeof s==`string`)||v.model!==void 0&&typeof v.model!=`string`)}function signPayload(body,secret){return createHmac(`sha256`,secret).update(body).digest(`hex`)}async function fetchFleetEntries(opts){let url=`${normalizeBaseUrl(opts.baseUrl)}/api/agent-hosts/fleet`;try{let res=await fetch(url,{headers:{Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.myAgentNodeId},signal:AbortSignal.timeout(15e3)});return res.ok?(await res.json()).fleet:(logDebug(`[remote-subagent] fleet query failed: HTTP ${res.status}`),[])}catch(err){return logDebug(`[remote-subagent] fleet query error: ${String(err)}`),[]}}const RETRY_DELAYS_MS=[500,1e3,2e3];function sleep$1(ms){return new Promise(resolve=>setTimeout(resolve,ms))}let _emitSpan;function emitRetrySpan(workflowId,taskId,attempt,reason){if(_emitSpan===void 0){_emitSpan=null,import(`./workflow-telemetry-B8Im0mPk.js`).then(mod=>{let m=mod;typeof m.emitSpan==`function`&&(_emitSpan=m.emitSpan)}).catch(()=>{});return}if(_emitSpan)try{_emitSpan({kind:`task.retry`,workflowId,taskId,ts:new Date().toISOString(),error:reason,durationMs:attempt*500,agentRole:`retry-attempt-${attempt}`})}catch{}}async function dispatchToRemoteAgentNode(opts,targetAgentNodeId,task,options){let extOpts=options,url=`${normalizeBaseUrl(opts.baseUrl)}/api/agent-hosts/${targetAgentNodeId}/forward`,payload={type:`remote.task`,task,fromAgentNodeId:opts.myAgentNodeId,timestamp:new Date().toISOString(),...extOpts?.correlationId?{correlationId:extOpts.correlationId}:{},...extOpts?.callbackAgentNodeId?{callbackAgentNodeId:extOpts.callbackAgentNodeId}:{},...extOpts?.correlationId?{callbackBaseUrl:opts.baseUrl}:{}},body=JSON.stringify(payload),signature=signPayload(body,opts.apiKey);logDebug(`[remote-subagent] dispatching to agentNode ${targetAgentNodeId}: ${task.slice(0,80)}…`);let lastError=`unknown error`;for(let attempt=0;attempt<3;attempt++){if(attempt>0){let delayMs=RETRY_DELAYS_MS[attempt-1]??2e3;logDebug(`[remote-subagent] retry attempt ${attempt+1}/3 after ${delayMs}ms`),emitRetrySpan(void 0,void 0,attempt,lastError),await sleep$1(delayMs)}try{let res=await fetch(url,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.myAgentNodeId,"X-AgentHost-Signature":`sha256=${signature}`},body,signal:AbortSignal.timeout(extOpts?.timeoutMs??3e4)});if(res.status>=500){lastError=`HTTP ${res.status}`;continue}if(!res.ok){let errBody=await res.text();return{status:`rejected`,error:`HTTP ${res.status}: ${errBody}`}}if(res.headers.get(`X-Stream`)===`true`&&extOpts?.onChunk&&res.body){let reader=res.body.getReader(),decoder=new TextDecoder;for(;;){let{done,value}=await reader.read();if(done)break;extOpts.onChunk(decoder.decode(value,{stream:!0}))}return{status:`accepted`}}let data=await res.json();return data.ok&&data.delivered?(logDebug(`[remote-subagent] task delivered to agentNode ${targetAgentNodeId}`),{status:`accepted`}):{status:`rejected`,error:data.error??`target agentNode reported delivery failure`}}catch(err){if(lastError=String(err),attempt<2)continue}}return{status:`rejected`,error:lastError}}async function postRemoteCallback(opts,callbackAgentNodeId,frame){let url=`${normalizeBaseUrl(opts.baseUrl)}/api/agent-hosts/${callbackAgentNodeId}/forward`,body=JSON.stringify({...frame,fromAgentNodeId:opts.myAgentNodeId,timestamp:new Date().toISOString()}),signature=signPayload(body,opts.apiKey);try{await fetch(url,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.myAgentNodeId,"X-AgentHost-Signature":`sha256=${signature}`},body,signal:AbortSignal.timeout(15e3)}),logDebug(`[remote-subagent] ${String(frame.type)} dispatched to callback agentNode ${callbackAgentNodeId}`)}catch(err){logDebug(`[remote-subagent] ${String(frame.type)} dispatch failed: ${String(err)}`)}}async function dispatchResultToRemoteAgentNode(opts,callbackAgentNodeId,correlationId,result){await postRemoteCallback(opts,callbackAgentNodeId,{type:`remote.task.result`,correlationId,result})}async function dispatchChunkToRemoteAgentNode(opts,callbackAgentNodeId,correlationId,chunk){chunk&&await postRemoteCallback(opts,callbackAgentNodeId,{type:`remote.task.chunk`,correlationId,chunk})}async function pushSpec(opts,spec){let url=`${opts.baseUrl.replace(/\/$/,``)}/api/specs`;try{let res=await fetch(url,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.agentNodeId},body:JSON.stringify({...spec,agentNodeId:Number(opts.agentNodeId)}),signal:AbortSignal.timeout(15e3)});return res.ok?await res.json():(logWarn(`[spec-sync] push failed: HTTP ${res.status}`),null)}catch(err){return logWarn(`[spec-sync] push error: ${String(err)}`),null}}const pExecFile=promisify(execFile);async function readPrdWip(projectRoot){try{return await fs$1.readFile(resolvePrdPath(projectRoot),`utf-8`)}catch{return null}}async function writePrdWip(projectRoot,content){let file=resolvePrdPath(projectRoot);try{await fs$1.writeFile(file,content.endsWith(`
296
+ `).trim()}catch{return``}}async function runSemanticSearch(projectRoot,opts){let{query,topK=10,language,rebuild=!1}=opts;try{await fs$1.access(projectRoot)}catch{return{error:`Project root does not exist: ${projectRoot}`}}let index=rebuild?await ssBuildIndex(projectRoot):await ssLoadOrBuildIndex(projectRoot);if(index.files.length===0)return{results:[],query,indexedFiles:0,message:`No source files found in project root.`};let queryTokens=[...ssTokenise(query),...query.split(/\s+/).filter(t=>/^[A-Z]/.test(t)&&t.length>=3).map(t=>t.toLowerCase())];if(queryTokens.length===0)return{error:`Query produced no searchable tokens.`};let scored=(language?index.files.filter(f=>f.relPath.endsWith(`.${language.replace(/^\./,``)}`)):index.files).map(f=>{let score=bm25Score(queryTokens,f,index),symbolMatches=f.symbols.filter(s=>queryTokens.some(q=>s.toLowerCase().includes(q))).length;return score+=symbolMatches*4,score+=queryTokens.filter(q=>f.relPath.toLowerCase().includes(q)).length*3,(Date.now()-f.mtime)/(1e3*60*60*24)<7&&(score+=1),{file:f,score,symbolMatches}}).filter(r=>r.score>0).toSorted((a,b)=>b.score-a.score).slice(0,Math.min(topK,20));return{query,queryTokens,indexedFiles:index.files.length,builtAt:new Date(index.builtAt).toISOString(),results:scored.map(r=>({filePath:r.file.relPath,score:Math.round(r.score*100)/100,symbols:r.file.symbols.slice(0,8),symbolMatches:r.symbolMatches,snippet:ssExtractSnippet(projectRoot,r.file.relPath,queryTokens)}))}}const codeAnalysisTool={name:`code_analysis`,label:`Code Analysis`,description:`Analyze code structure, dependencies, and semantic relationships in a project. Returns AST information, dependency graphs, and code maps.`,parameters:Type.Object({projectRoot:Type.String({description:`Root directory of the project to analyze`}),filePatterns:Type.Optional(Type.Array(Type.String(),{description:`File patterns to analyze (e.g., ['**/*.ts', '**/*.js']). Defaults to common patterns.`})),includeTests:Type.Optional(Type.Boolean({description:`Whether to include test files in the analysis. Defaults to false.`}))}),async execute(_toolCallId,params){return jsonResult(await runCodeAnalysis(params.projectRoot,{filePatterns:params.filePatterns,includeTests:params.includeTests}))}},codebaseSearchTool={name:`codebase_search`,label:`Codebase Search`,description:`Semantically search the project source code using natural language or keywords. Finds files and code snippets most relevant to your query — like Cursor @codebase or Continue.dev @codebase. Returns ranked results with file paths and representative snippets.`,parameters:Type.Object({projectRoot:Type.String({description:`Root directory of the project to search`}),query:Type.String({description:`Natural language or keyword query describing what you are looking for. Examples: 'user authentication', 'database connection pool', 'rate limiting middleware'`}),topK:Type.Optional(Type.Number({description:`Maximum number of results to return. Defaults to 10.`})),language:Type.Optional(Type.String({description:`Limit search to files of this language/extension (e.g. 'ts', 'py', 'go'). If omitted, all source files are searched.`}))}),async execute(_toolCallId,params){return jsonResult(await runCodebaseSearch(params.projectRoot,{query:params.query,topK:params.topK,language:params.language}))}},projectKnowledgeTool={name:`project_knowledge`,label:`Project Knowledge`,description:`Query project-specific knowledge including context, rules, architecture, custom agent roles, and recent agent activity memory from the .builderForceAgents directory.`,parameters:Type.Object({projectRoot:Type.String({description:`Root directory of the project`}),query:Type.String({description:`What to query: 'context', 'rules', 'governance', 'architecture', 'agents', 'memory', or 'all'`})}),async execute(_toolCallId,params){return jsonResult(await runProjectKnowledge(params.projectRoot,params.query))}};async function fetchHiredAgents(opts){let url=`${opts.baseUrl.replace(/\/$/,``)}/api/runtime/hired-agents`;try{let res=await fetch(url,{headers:{Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-Id":opts.agentNodeId},signal:AbortSignal.timeout(1e4)});if(!res.ok)return logDebug(`[hired-agents-sync] fetch failed: HTTP ${res.status}`),[];let data=await res.json();return!data||!Array.isArray(data.agents)?[]:data.agents.filter(isHiredAgent)}catch(err){return logDebug(`[hired-agents-sync] fetch error: ${String(err)}`),[]}}let cache=null,inFlight=null;async function loadHiredAgentsCached(opts,now=Date.now()){return cache&&now-cache.fetchedAt<3e5?cache.agents:inFlight||(inFlight=(async()=>{try{let agents=await fetchHiredAgents(opts);return cache={agents,fetchedAt:Date.now()},agents.length>0&&registerHiredAgentsAsRoles(agents),agents}finally{inFlight=null}})(),inFlight)}function getCachedHiredAgents(){return cache?.agents??[]}function resolveHiredAgentRef(localAgentId){let id=(localAgentId??``).trim().toLowerCase();if(!id||id===`main`)return null;for(let a of getCachedHiredAgents())if(a.id.trim().toLowerCase()===id||a.roleKey.trim().toLowerCase()===id)return a.id;return null}function isHiredAgent(value){if(!value||typeof value!=`object`)return!1;let v=value;return!(!(typeof v.id==`string`&&v.id.trim().length>0&&typeof v.roleKey==`string`&&v.roleKey.trim().length>0)||typeof v.name!=`string`||typeof v.systemPrompt!=`string`||!Array.isArray(v.skills)||!v.skills.every(s=>typeof s==`string`)||v.model!==void 0&&typeof v.model!=`string`)}function signPayload(body,secret){return createHmac(`sha256`,secret).update(body).digest(`hex`)}async function fetchFleetEntries(opts){let url=`${normalizeBaseUrl(opts.baseUrl)}/api/agent-hosts/fleet`;try{let res=await fetch(url,{headers:{Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.myAgentNodeId},signal:AbortSignal.timeout(15e3)});return res.ok?(await res.json()).fleet:(logDebug(`[remote-subagent] fleet query failed: HTTP ${res.status}`),[])}catch(err){return logDebug(`[remote-subagent] fleet query error: ${String(err)}`),[]}}const RETRY_DELAYS_MS=[500,1e3,2e3];function sleep$1(ms){return new Promise(resolve=>setTimeout(resolve,ms))}let _emitSpan;function emitRetrySpan(workflowId,taskId,attempt,reason){if(_emitSpan===void 0){_emitSpan=null,import(`./workflow-telemetry-Do1UsYwM.js`).then(mod=>{let m=mod;typeof m.emitSpan==`function`&&(_emitSpan=m.emitSpan)}).catch(()=>{});return}if(_emitSpan)try{_emitSpan({kind:`task.retry`,workflowId,taskId,ts:new Date().toISOString(),error:reason,durationMs:attempt*500,agentRole:`retry-attempt-${attempt}`})}catch{}}async function dispatchToRemoteAgentNode(opts,targetAgentNodeId,task,options){let extOpts=options,url=`${normalizeBaseUrl(opts.baseUrl)}/api/agent-hosts/${targetAgentNodeId}/forward`,payload={type:`remote.task`,task,fromAgentNodeId:opts.myAgentNodeId,timestamp:new Date().toISOString(),...extOpts?.correlationId?{correlationId:extOpts.correlationId}:{},...extOpts?.callbackAgentNodeId?{callbackAgentNodeId:extOpts.callbackAgentNodeId}:{},...extOpts?.correlationId?{callbackBaseUrl:opts.baseUrl}:{}},body=JSON.stringify(payload),signature=signPayload(body,opts.apiKey);logDebug(`[remote-subagent] dispatching to agentNode ${targetAgentNodeId}: ${task.slice(0,80)}…`);let lastError=`unknown error`;for(let attempt=0;attempt<3;attempt++){if(attempt>0){let delayMs=RETRY_DELAYS_MS[attempt-1]??2e3;logDebug(`[remote-subagent] retry attempt ${attempt+1}/3 after ${delayMs}ms`),emitRetrySpan(void 0,void 0,attempt,lastError),await sleep$1(delayMs)}try{let res=await fetch(url,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.myAgentNodeId,"X-AgentHost-Signature":`sha256=${signature}`},body,signal:AbortSignal.timeout(extOpts?.timeoutMs??3e4)});if(res.status>=500){lastError=`HTTP ${res.status}`;continue}if(!res.ok){let errBody=await res.text();return{status:`rejected`,error:`HTTP ${res.status}: ${errBody}`}}if(res.headers.get(`X-Stream`)===`true`&&extOpts?.onChunk&&res.body){let reader=res.body.getReader(),decoder=new TextDecoder;for(;;){let{done,value}=await reader.read();if(done)break;extOpts.onChunk(decoder.decode(value,{stream:!0}))}return{status:`accepted`}}let data=await res.json();return data.ok&&data.delivered?(logDebug(`[remote-subagent] task delivered to agentNode ${targetAgentNodeId}`),{status:`accepted`}):{status:`rejected`,error:data.error??`target agentNode reported delivery failure`}}catch(err){if(lastError=String(err),attempt<2)continue}}return{status:`rejected`,error:lastError}}async function postRemoteCallback(opts,callbackAgentNodeId,frame){let url=`${normalizeBaseUrl(opts.baseUrl)}/api/agent-hosts/${callbackAgentNodeId}/forward`,body=JSON.stringify({...frame,fromAgentNodeId:opts.myAgentNodeId,timestamp:new Date().toISOString()}),signature=signPayload(body,opts.apiKey);try{await fetch(url,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.myAgentNodeId,"X-AgentHost-Signature":`sha256=${signature}`},body,signal:AbortSignal.timeout(15e3)}),logDebug(`[remote-subagent] ${String(frame.type)} dispatched to callback agentNode ${callbackAgentNodeId}`)}catch(err){logDebug(`[remote-subagent] ${String(frame.type)} dispatch failed: ${String(err)}`)}}async function dispatchResultToRemoteAgentNode(opts,callbackAgentNodeId,correlationId,result){await postRemoteCallback(opts,callbackAgentNodeId,{type:`remote.task.result`,correlationId,result})}async function dispatchChunkToRemoteAgentNode(opts,callbackAgentNodeId,correlationId,chunk){chunk&&await postRemoteCallback(opts,callbackAgentNodeId,{type:`remote.task.chunk`,correlationId,chunk})}async function pushSpec(opts,spec){let url=`${opts.baseUrl.replace(/\/$/,``)}/api/specs`;try{let res=await fetch(url,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${opts.apiKey}`,"X-AgentHost-From":opts.agentNodeId},body:JSON.stringify({...spec,agentNodeId:Number(opts.agentNodeId)}),signal:AbortSignal.timeout(15e3)});return res.ok?await res.json():(logWarn(`[spec-sync] push failed: HTTP ${res.status}`),null)}catch(err){return logWarn(`[spec-sync] push error: ${String(err)}`),null}}const pExecFile=promisify(execFile);async function readPrdWip(projectRoot){try{return await fs$1.readFile(resolvePrdPath(projectRoot),`utf-8`)}catch{return null}}async function writePrdWip(projectRoot,content){let file=resolvePrdPath(projectRoot);try{await fs$1.writeFile(file,content.endsWith(`
297
297
  `)?content:`${content}\n`,`utf-8`)}catch(err){logDebug(`[prd-wip] failed to write PRD: ${String(err)}`);return}await stageIfRepo(projectRoot,file)}async function stageIfRepo(projectRoot,file){try{await fs$1.access(path.join(projectRoot,`.git`))}catch{return}try{await pExecFile(`git`,[`add`,`--`,file],{cwd:projectRoot}),logDebug(`[prd-wip] staged ${path.relative(projectRoot,file)} as a pending commit`)}catch(err){logDebug(`[prd-wip] git add failed (continuing): ${String(err)}`)}}function isPrdTask(agentRole,description){return agentRole===`architecture-advisor`?/product requirements document|\bPRD\b/i.test(description):!1}const CMPS=[`==`,`!=`,`>=`,`<=`,`>`,`<`,`contains`,`matches`];function resolve$1(token,ctx){let t=token.trim();return t===``?``:t.startsWith(`"`)&&t.endsWith(`"`)||t.startsWith(`'`)&&t.endsWith(`'`)?t.slice(1,-1):t===`true`?!0:t===`false`?!1:/^-?\d+(\.\d+)?$/.test(t)?Number(t):Object.prototype.hasOwnProperty.call(ctx,t)?ctx[t]:``}function evalComparison(expr,ctx){for(let op of CMPS){let needle=op===`contains`||op===`matches`?` ${op} `:op,idx=expr.indexOf(needle);if(idx===-1)continue;let lhs=resolve$1(expr.slice(0,idx),ctx),rhs=resolve$1(expr.slice(idx+needle.length),ctx);switch(op){case`==`:return lhs===rhs;case`!=`:return lhs!==rhs;case`>=`:return Number(lhs)>=Number(rhs);case`<=`:return Number(lhs)<=Number(rhs);case`>`:return Number(lhs)>Number(rhs);case`<`:return Number(lhs)<Number(rhs);case`contains`:return String(lhs).includes(String(rhs));case`matches`:try{return new RegExp(String(rhs)).test(String(lhs))}catch{return!1}}}let v=resolve$1(expr,ctx);return v!==``&&v!==!1&&v!==0}function evalPredicate(predicate,ctx){let expr=predicate.trim();return expr?expr.split(`||`).some(clause=>clause.split(`&&`).every(c=>evalComparison(c.trim(),ctx))):!0}function applyTransform(expression,ctx){let expr=expression?.trim()??``;return expr?expr.replace(/\{\{\s*([\w.]+)\s*\}\}/g,(_,name)=>Object.prototype.hasOwnProperty.call(ctx,name)?String(ctx[name]):``):String(ctx.input??``)}function etlContext(input,config){let ctx={input,length:input.length};for(let[k,v]of Object.entries(config))(typeof v==`string`||typeof v==`number`||typeof v==`boolean`)&&(ctx[k]=v);return ctx}const DEFAULT_ROUTING_RULES=[{priority:100,condition:{type:`inputLength`,gt:8e3},target:{type:`cloud`,provider:`anthropic`}},{priority:50,condition:{type:`role`,matches:/local/i},target:{type:`local`,provider:`ollama`}},{priority:0,condition:{type:`always`},target:{type:`cloud`,provider:`anthropic`}}];function evaluateCondition(condition,task){switch(condition.type){case`always`:return!0;case`role`:{let{matches}=condition;return typeof matches==`string`?task.agentRole===matches:matches.test(task.agentRole)}case`inputLength`:{let len=task.input.length;return!(condition.gt!==void 0&&len<=condition.gt||condition.lt!==void 0&&len>=condition.lt)}case`capability`:return condition.requires.length===0;default:return!1}}const DEFAULT_TARGET={type:`cloud`,provider:`anthropic`};function resolveRouting(task,rules){let sorted=[...rules].toSorted((a,b)=>b.priority-a.priority);for(let rule of sorted)if(evaluateCondition(rule.condition,task))return rule.target;return DEFAULT_TARGET}function parseRoutingRules(raw){if(!Array.isArray(raw))return[];let result=[];for(let item of raw){if(!item||typeof item!=`object`)continue;let r=item,condition=r.condition,target=r.target;if(!(!condition||!target)){if(condition.type===`role`&&typeof condition.matches==`string`){let matchesStr=condition.matches,m=/^\/(.+)\/([gimsuy]*)$/.exec(matchesStr);if(m)try{let flags=m[2]===``?void 0:m[2];condition.matches=new RegExp(m[1],flags)}catch{}}result.push({condition,target,priority:typeof r.priority==`number`?r.priority:0})}}return result}function envInt(name,fallback){let raw=process.env[name];if(!raw)return fallback;let n=Number.parseInt(raw,10);return Number.isFinite(n)&&n>=0?n:fallback}const MAX_TASK_RETRIES=envInt(`BUILDERFORCE_WORKFLOW_MAX_RETRIES`,2),RETRY_BACKOFF_MS=envInt(`BUILDERFORCE_WORKFLOW_RETRY_BACKOFF_MS`,1500),globalOrchestrator=new class{constructor(){this.workflows=new Map,this.taskResults=new Map,this.projectRoot=null,this.routingRules=DEFAULT_ROUTING_RULES,this.relayService=null,this.telemetry=null,this.memoryService=null,this.llmService=null,this.mcpService=null,this.limbicSystem=null,this.agentTransport=null,this.activeSpawnContext=null,this.resumingInFlight=!1}setProjectRoot(root,agentNodeId,linkApiUrl,linkApiKey){this.projectRoot=root,this.telemetry?.init({projectRoot:root,agentNodeId,linkApiUrl,linkApiKey}),this.loadRoutingRules(root)}async loadRoutingRules(projectRoot){let filePath=path.join(projectRoot,`.builderForceAgents`,`routing-rules.json`);try{let raw=await fs$1.readFile(filePath,`utf-8`),parsed=parseRoutingRules(JSON.parse(raw));parsed.length>0&&(this.routingRules=[...parsed,...DEFAULT_ROUTING_RULES],logDebug(`[orchestrator] loaded ${parsed.length} routing rule(s) from ${filePath}`))}catch{}}configure(config){config.telemetry!==void 0&&(this.telemetry=config.telemetry),config.memoryService!==void 0&&(this.memoryService=config.memoryService),config.agentTransport!==void 0&&(this.agentTransport=config.agentTransport),config.relayService!==void 0&&(this.relayService=config.relayService),config.llmService!==void 0&&(this.llmService=config.llmService),config.mcpService!==void 0&&(this.mcpService=config.mcpService),config.limbicSystem!==void 0&&(this.limbicSystem=config.limbicSystem)}getLimbicSystem(){return this.limbicSystem}setTelemetryService(svc){this.telemetry=svc}setMemoryService(svc){this.memoryService=svc}setAgentTransport(transport){this.agentTransport=transport}currentSpawnContext(){return this.activeSpawnContext??{}}setRelayService(relay){this.relayService=relay}createWorkflow(steps){let id=crypto.randomUUID(),workflow={id,steps,tasks:new Map,status:`pending`,createdAt:new Date};for(let step of steps){let taskId=crypto.randomUUID(),task={id:taskId,description:step.task,agentRole:step.role,status:`pending`,input:step.task,dependencies:step.dependsOn||[],dependents:[],createdAt:new Date,nodeType:step.nodeType,config:step.config};workflow.tasks.set(taskId,task)}let stepToTaskId=new Map,index=0;for(let[taskId]of workflow.tasks)stepToTaskId.set(index++,taskId);index=0;for(let step of steps){let taskId=stepToTaskId.get(index++),task=workflow.tasks.get(taskId);if(!task)continue;let resolvedDependencies=[];if(step.dependsOn)for(let depStepId of step.dependsOn){let depIndex=steps.findIndex(s=>s.task===depStepId);if(depIndex!==-1){let depTaskId=stepToTaskId.get(depIndex);if(depTaskId){resolvedDependencies.push(depTaskId);let depTask=workflow.tasks.get(depTaskId);depTask&&!depTask.dependents.includes(taskId)&&depTask.dependents.push(taskId)}}}task.dependencies=resolvedDependencies}return this.workflows.set(id,workflow),this.persistWorkflow(workflow),workflow}createWorkflowFromTasks(workflowId,specs){let tasks=new Map;for(let s of specs)tasks.set(s.id,{id:s.id,description:s.description,agentRole:s.agentRole,status:`pending`,input:s.input??s.description,dependencies:s.dependsOn,dependents:[],createdAt:new Date,nodeType:s.nodeType,config:s.config});for(let task of tasks.values())for(let depId of task.dependencies){let dep=tasks.get(depId);dep&&!dep.dependents.includes(task.id)&&dep.dependents.push(task.id)}let workflow={id:workflowId,steps:specs.map(s=>({role:s.agentRole,task:s.description,dependsOn:s.dependsOn})),tasks,status:`pending`,createdAt:new Date};return this.workflows.set(workflowId,workflow),this.persistWorkflow(workflow),workflow}async executeWorkflow(workflowId,context){let workflow=this.workflows.get(workflowId);if(!workflow)throw Error(`Workflow ${workflowId} not found`);workflow.status=`running`,this.telemetry?.emitWorkflowStart(workflowId);let results=new Map,executedTasks=new Set;for(;executedTasks.size<workflow.tasks.size;){let nextTasks=Array.from(workflow.tasks.values()).filter(task=>task.status===`pending`&&task.dependencies.every(depId=>executedTasks.has(depId)));if(nextTasks.length===0){if(Array.from(workflow.tasks.values()).filter(task=>task.status!==`completed`&&task.status!==`failed`).length>0)throw workflow.status=`failed`,Error(`Workflow stuck - cannot execute remaining tasks`);break}await Promise.all(nextTasks.map(async task=>{let result=await this.executeTaskWithRetry(task,workflow,context);result!==null&&results.set(task.id,result),executedTasks.add(task.id)}))}return Array.from(workflow.tasks.values()).filter(task=>task.status===`failed`).length>0?workflow.status=`failed`:workflow.status=`completed`,this.telemetry?.emitWorkflowEnd(workflowId,workflow.status===`failed`),this.persistWorkflow(workflow),results}async executeTaskWithRetry(task,workflow,context){let maxAttempts=MAX_TASK_RETRIES+1;for(let attempt=(task.attempts??0)+1;attempt<=maxAttempts;attempt++){task.attempts=attempt,task.status===`failed`&&(task.status=`pending`);try{return await this.executeTask(task,workflow,context)}catch(error){task.lastError=error instanceof Error?error.message:String(error);let isLastAttempt=attempt>=maxAttempts;if(logDebug(`[orchestrator] task ${task.id} (role=${task.agentRole}) failed on attempt ${attempt}/${maxAttempts}: ${task.lastError}`+(isLastAttempt?` — giving up`:` — retrying`)),isLastAttempt)return task.status=`failed`,task.error=task.lastError,this.persistWorkflow(workflow),null;this.persistWorkflow(workflow),RETRY_BACKOFF_MS>0&&await new Promise(resolve=>setTimeout(resolve,RETRY_BACKOFF_MS*attempt))}}return null}buildStructuredContext(task,workflow){let MAX_RESULT_CHARS=8e3,lines=[];if(lines.push(`## Your Task\n\n${task.input}`),task.dependencies.length>0){lines.push(`
298
298
  ## Context from Prior Agents
299
299
  `);for(let depId of task.dependencies){let depTask=workflow.tasks.get(depId),result=this.taskResults.get(depId);if(depTask&&result){let prefix=findAgentRole(depTask.agentRole)?.outputFormat?.outputPrefix??depTask.agentRole.toUpperCase(),body=result.length>MAX_RESULT_CHARS?`${result.slice(0,MAX_RESULT_CHARS)}\n…(truncated — ${result.length-MAX_RESULT_CHARS} chars omitted)`:result;lines.push(`### ${prefix} (${depTask.agentRole})\n\n${body}\n`)}}}return lines.join(`
@@ -443,13 +443,13 @@ Critical rules from AGENTS.md:
443
443
 
444
444
  `),queuedBody=mediaNote?[mediaNote,mediaReplyHint,queueBodyBase].filter(Boolean).join(`
445
445
  `).trim():queueBodyBase,resolvedQueue=resolveQueueSettings({cfg,channel:sessionCtx.Provider,sessionEntry,inlineMode:perMessageQueueMode,inlineOptions:perMessageQueueOptions}),sessionLaneKey=resolveEmbeddedSessionLane(sessionKey??sessionIdFinal),laneSize=getQueueSize(sessionLaneKey);resolvedQueue.mode===`interrupt`&&laneSize>0&&logVerbose(`Interrupting ${sessionLaneKey} (cleared ${clearCommandLane(sessionLaneKey)}, aborted=${abortEmbeddedRun(sessionIdFinal)})`);let queueKey=sessionKey??sessionIdFinal,isActive=isEmbeddedRunActive(sessionIdFinal),isStreaming=isEmbeddedRunStreaming(sessionIdFinal),shouldSteer=resolvedQueue.mode===`steer`||resolvedQueue.mode===`steer-backlog`,shouldFollowup=resolvedQueue.mode===`followup`||resolvedQueue.mode===`collect`||resolvedQueue.mode===`steer-backlog`,authProfileId=await resolveSessionAuthProfileOverride({cfg,provider,agentDir,sessionEntry,sessionStore,sessionKey,storePath,isNewSession}),authProfileIdSource=sessionEntry?.authProfileOverrideSource,followupRun={prompt:queuedBody,messageId:sessionCtx.MessageSidFull??sessionCtx.MessageSid,summaryLine:baseBodyTrimmedRaw,enqueuedAt:Date.now(),originatingChannel:ctx.OriginatingChannel,originatingTo:ctx.OriginatingTo,originatingAccountId:ctx.AccountId,originatingThreadId:ctx.MessageThreadId,originatingChatType:ctx.ChatType,run:{agentId,agentDir,sessionId:sessionIdFinal,sessionKey,messageProvider:sessionCtx.Provider?.trim().toLowerCase()||void 0,agentAccountId:sessionCtx.AccountId,groupId:resolveGroupSessionKey(sessionCtx)?.id??void 0,groupChannel:sessionCtx.GroupChannel?.trim()??sessionCtx.GroupSubject?.trim(),groupSpace:sessionCtx.GroupSpace?.trim()??void 0,senderId:sessionCtx.SenderId?.trim()||void 0,senderName:sessionCtx.SenderName?.trim()||void 0,senderUsername:sessionCtx.SenderUsername?.trim()||void 0,senderE164:sessionCtx.SenderE164?.trim()||void 0,senderIsOwner:command.senderIsOwner,sessionFile,workspaceDir,config:cfg,skillsSnapshot,provider,model,authProfileId,authProfileIdSource,thinkLevel:resolvedThinkLevel,verboseLevel:resolvedVerboseLevel,reasoningLevel:resolvedReasoningLevel,elevatedLevel:resolvedElevatedLevel,execOverrides,bashElevated:{enabled:elevatedEnabled,allowed:elevatedAllowed,defaultLevel:resolvedElevatedLevel??`off`},timeoutMs,blockReplyBreak:resolvedBlockStreamingBreak,ownerNumbers:command.ownerList.length>0?command.ownerList:void 0,extraSystemPrompt:extraSystemPrompt||void 0,...isReasoningTagProvider(provider)?{enforceFinalTag:!0}:{}}};return runReplyAgent({commandBody:prefixedCommandBody,followupRun,queueKey,resolvedQueue,shouldSteer,shouldFollowup,isActive,isStreaming,opts,typing,sessionEntry,sessionStore,sessionKey,storePath,defaultModel,agentCfgContextTokens:agentCfg?.contextTokens,resolvedVerboseLevel:resolvedVerboseLevel??`on`,isNewSession,blockStreamingEnabled,blockReplyChunking,resolvedBlockStreamingBreak,sessionCtx,shouldInjectGroupIntro,typingMode})}function splitBody(body){let tokens=body.split(/\s+/).filter(Boolean);return{tokens,first:tokens[0],second:tokens[1],rest:tokens.slice(2)}}function buildSelectionFromExplicit(params){let resolved=resolveModelRefFromString({raw:params.raw,defaultProvider:params.defaultProvider,aliasIndex:params.aliasIndex});if(!resolved)return;let key=modelKey(resolved.ref.provider,resolved.ref.model);if(params.allowedModelKeys.size>0&&!params.allowedModelKeys.has(key))return;let isDefault=resolved.ref.provider===params.defaultProvider&&resolved.ref.model===params.defaultModel;return{provider:resolved.ref.provider,model:resolved.ref.model,isDefault,...resolved.alias?{alias:resolved.alias}:void 0}}function applySelectionToSession(params){let{selection,sessionEntry,sessionStore,sessionKey,storePath}=params;if(!sessionEntry||!sessionStore||!sessionKey)return;let{updated}=applyModelOverrideToSessionEntry({entry:sessionEntry,selection});updated&&(sessionStore[sessionKey]=sessionEntry,storePath&&updateSessionStore(storePath,store=>{store[sessionKey]=sessionEntry}).catch(()=>{}))}async function applyResetModelOverride(params){if(!params.resetTriggered)return{};let rawBody=params.bodyStripped?.trim();if(!rawBody)return{};let{tokens,first,second}=splitBody(rawBody);if(!first)return{};let catalog=await loadModelCatalog({config:params.cfg}),allowedModelKeys=buildAllowedModelSet({cfg:params.cfg,catalog,defaultProvider:params.defaultProvider,defaultModel:params.defaultModel}).allowedKeys;if(allowedModelKeys.size===0)return{};let providers=new Set;for(let key of allowedModelKeys){let slash=key.indexOf(`/`);slash<=0||providers.add(normalizeProviderId(key.slice(0,slash)))}let resolveSelection=raw=>resolveModelDirectiveSelection({raw,defaultProvider:params.defaultProvider,defaultModel:params.defaultModel,aliasIndex:params.aliasIndex,allowedModelKeys}),selection,consumed=0;if(providers.has(normalizeProviderId(first))&&second){let resolved=resolveSelection(`${normalizeProviderId(first)}/${second}`);resolved.selection&&(selection=resolved.selection,consumed=2)}if(selection||(selection=buildSelectionFromExplicit({raw:first,defaultProvider:params.defaultProvider,defaultModel:params.defaultModel,aliasIndex:params.aliasIndex,allowedModelKeys}),selection&&(consumed=1)),!selection){let resolved=resolveSelection(first);(providers.has(normalizeProviderId(first))||first.trim().length>=6)&&(selection=resolved.selection,selection&&(consumed=1))}if(!selection)return{};let cleanedBody=tokens.slice(consumed).join(` `).trim();return params.sessionCtx.BodyStripped=cleanedBody,params.sessionCtx.BodyForCommands=cleanedBody,applySelectionToSession({selection,sessionEntry:params.sessionEntry,sessionStore:params.sessionStore,sessionKey:params.sessionKey,storePath:params.storePath}),{selection,cleanedBody}}const warnedContexts=new Map;function shouldSendWarning(){return!process.env.VITEST&&!0}function buildWarningContext(params){let{warning}=params;return[warning.activeSessionKey,warning.pruneAfterMs,warning.maxEntries,warning.wouldPrune?`prune`:``,warning.wouldCap?`cap`:``].filter(Boolean).join(`|`)}function formatDuration(ms){if(ms>=864e5){let days=Math.round(ms/864e5);return`${days} day${days===1?``:`s`}`}if(ms>=36e5){let hours=Math.round(ms/36e5);return`${hours} hour${hours===1?``:`s`}`}if(ms>=6e4){let mins=Math.round(ms/6e4);return`${mins} minute${mins===1?``:`s`}`}let secs=Math.round(ms/1e3);return`${secs} second${secs===1?``:`s`}`}function buildWarningText(warning){let reasons=[];return warning.wouldPrune&&reasons.push(`older than ${formatDuration(warning.pruneAfterMs)}`),warning.wouldCap&&reasons.push(`not in the most recent ${warning.maxEntries} sessions`),`⚠️ Session maintenance warning: this active session would be evicted (${reasons.length>0?reasons.join(` and `):`over maintenance limits`}). Maintenance is set to warn-only, so nothing was reset. To enforce cleanup, set \`session.maintenance.mode: "enforce"\` or increase the limits.`}async function deliverSessionMaintenanceWarning(params){if(!shouldSendWarning())return;let contextKey=buildWarningContext(params);if(warnedContexts.get(params.sessionKey)===contextKey)return;warnedContexts.set(params.sessionKey,contextKey);let text=buildWarningText(params.warning),target=resolveSessionDeliveryTarget({entry:params.entry,requestedChannel:`last`});if(!target.channel||!target.to){enqueueSystemEvent(text,{sessionKey:params.sessionKey});return}let channel=normalizeMessageChannel(target.channel)??target.channel;if(!isDeliverableMessageChannel(channel)){enqueueSystemEvent(text,{sessionKey:params.sessionKey});return}try{await deliverOutboundPayloads({cfg:params.cfg,channel,to:target.to,accountId:target.accountId,threadId:target.threadId,payloads:[{text}],agentId:resolveSessionAgentId({sessionKey:params.sessionKey,config:params.cfg})})}catch(err){console.warn(`Failed to deliver session maintenance warning: ${String(err)}`),enqueueSystemEvent(text,{sessionKey:params.sessionKey})}}function forkSessionFromParent(params){let parentSessionFile=resolveSessionFilePath(params.parentEntry.sessionId,params.parentEntry,{agentId:params.agentId,sessionsDir:params.sessionsDir});if(!parentSessionFile||!fs.existsSync(parentSessionFile))return null;try{let manager=SessionManager.open(parentSessionFile),leafId=manager.getLeafId();if(leafId){let sessionFile=manager.createBranchedSession(leafId)??manager.getSessionFile(),sessionId=manager.getSessionId();if(sessionFile&&sessionId)return{sessionId,sessionFile}}let sessionId=crypto.randomUUID(),timestamp=new Date().toISOString(),fileTimestamp=timestamp.replace(/[:.]/g,`-`),sessionFile=path.join(manager.getSessionDir(),`${fileTimestamp}_${sessionId}.jsonl`),header={type:`session`,version:CURRENT_SESSION_VERSION,id:sessionId,timestamp,cwd:manager.getCwd(),parentSession:parentSessionFile};return fs.writeFileSync(sessionFile,`${JSON.stringify(header)}\n`,`utf-8`),{sessionId,sessionFile}}catch{return null}}async function initSessionState(params){let{ctx,cfg,commandAuthorized}=params,targetSessionKey=ctx.CommandSource===`native`?ctx.CommandTargetSessionKey?.trim():void 0,sessionCtxForState=targetSessionKey&&targetSessionKey!==ctx.SessionKey?{...ctx,SessionKey:targetSessionKey}:ctx,sessionCfg=cfg.session,mainKey=normalizeMainKey(sessionCfg?.mainKey),agentId=resolveSessionAgentId({sessionKey:sessionCtxForState.SessionKey,config:cfg}),groupResolution=resolveGroupSessionKey(sessionCtxForState)??void 0,resetTriggers=sessionCfg?.resetTriggers?.length?sessionCfg.resetTriggers:DEFAULT_RESET_TRIGGERS,sessionScope=sessionCfg?.scope??`per-sender`,storePath=resolveStorePath(sessionCfg?.store,{agentId}),sessionStore=loadSessionStore(storePath,{skipCache:!0}),sessionKey,sessionEntry,sessionId,isNewSession=!1,bodyStripped,systemSent=!1,abortedLastRun=!1,resetTriggered=!1,persistedThinking,persistedVerbose,persistedReasoning,persistedTtsAuto,persistedModelOverride,persistedProviderOverride,normalizedChatType=normalizeChatType(ctx.ChatType),isGroup=normalizedChatType!=null&&normalizedChatType!==`direct`?!0:!!groupResolution,commandSource=ctx.BodyForCommands??ctx.CommandBody??ctx.RawBody??ctx.Body??``,triggerBodyNormalized=stripStructuralPrefixes(commandSource).trim(),trimmedBody=commandSource.trim(),resetAuthorized=resolveCommandAuthorization({ctx,cfg,commandAuthorized}).isAuthorizedSender,strippedForReset=isGroup?stripMentions(triggerBodyNormalized,ctx,cfg,agentId):triggerBodyNormalized,trimmedBodyLower=trimmedBody.toLowerCase(),strippedForResetLower=strippedForReset.toLowerCase();for(let trigger of resetTriggers){if(!trigger)continue;if(!resetAuthorized)break;let triggerLower=trigger.toLowerCase();if(trimmedBodyLower===triggerLower||strippedForResetLower===triggerLower){isNewSession=!0,bodyStripped=``,resetTriggered=!0;break}let triggerPrefixLower=`${triggerLower} `;if(trimmedBodyLower.startsWith(triggerPrefixLower)||strippedForResetLower.startsWith(triggerPrefixLower)){isNewSession=!0,bodyStripped=strippedForReset.slice(trigger.length).trimStart(),resetTriggered=!0;break}}sessionKey=resolveSessionKey$1(sessionScope,sessionCtxForState,mainKey);let entry=sessionStore[sessionKey],previousSessionEntry=resetTriggered&&entry?{...entry}:void 0,now=Date.now(),isThread=resolveThreadFlag({sessionKey,messageThreadId:ctx.MessageThreadId,threadLabel:ctx.ThreadLabel,threadStarterBody:ctx.ThreadStarterBody,parentSessionKey:ctx.ParentSessionKey}),resetPolicy=resolveSessionResetPolicy({sessionCfg,resetType:resolveSessionResetType({sessionKey,isGroup,isThread}),resetOverride:resolveChannelResetConfig({sessionCfg,channel:groupResolution?.channel??ctx.OriginatingChannel??ctx.Surface??ctx.Provider})}),freshEntry=entry?evaluateSessionFreshness({updatedAt:entry.updatedAt,now,policy:resetPolicy}).fresh:!1;!isNewSession&&freshEntry?(sessionId=entry.sessionId,systemSent=entry.systemSent??!1,abortedLastRun=entry.abortedLastRun??!1,persistedThinking=entry.thinkingLevel,persistedVerbose=entry.verboseLevel,persistedReasoning=entry.reasoningLevel,persistedTtsAuto=entry.ttsAuto,persistedModelOverride=entry.modelOverride,persistedProviderOverride=entry.providerOverride):(sessionId=crypto.randomUUID(),isNewSession=!0,systemSent=!1,abortedLastRun=!1,resetTriggered&&entry&&(persistedThinking=entry.thinkingLevel,persistedVerbose=entry.verboseLevel,persistedReasoning=entry.reasoningLevel,persistedTtsAuto=entry.ttsAuto));let baseEntry=!isNewSession&&freshEntry?entry:void 0,lastChannelRaw=ctx.OriginatingChannel||baseEntry?.lastChannel,lastToRaw=ctx.OriginatingTo||ctx.To||baseEntry?.lastTo,lastAccountIdRaw=ctx.AccountId||baseEntry?.lastAccountId,lastThreadIdRaw=ctx.MessageThreadId||(isThread?baseEntry?.lastThreadId:void 0),deliveryFields=normalizeSessionDeliveryFields({deliveryContext:{channel:lastChannelRaw,to:lastToRaw,accountId:lastAccountIdRaw,threadId:lastThreadIdRaw}}),lastChannel=deliveryFields.lastChannel??lastChannelRaw,lastTo=deliveryFields.lastTo??lastToRaw,lastAccountId=deliveryFields.lastAccountId??lastAccountIdRaw,lastThreadId=deliveryFields.lastThreadId??lastThreadIdRaw;sessionEntry={...baseEntry,sessionId,updatedAt:Date.now(),systemSent,abortedLastRun,thinkingLevel:persistedThinking??baseEntry?.thinkingLevel,verboseLevel:persistedVerbose??baseEntry?.verboseLevel,reasoningLevel:persistedReasoning??baseEntry?.reasoningLevel,ttsAuto:persistedTtsAuto??baseEntry?.ttsAuto,responseUsage:baseEntry?.responseUsage,modelOverride:persistedModelOverride??baseEntry?.modelOverride,providerOverride:persistedProviderOverride??baseEntry?.providerOverride,sendPolicy:baseEntry?.sendPolicy,queueMode:baseEntry?.queueMode,queueDebounceMs:baseEntry?.queueDebounceMs,queueCap:baseEntry?.queueCap,queueDrop:baseEntry?.queueDrop,displayName:baseEntry?.displayName,chatType:baseEntry?.chatType,channel:baseEntry?.channel,groupId:baseEntry?.groupId,subject:baseEntry?.subject,groupChannel:baseEntry?.groupChannel,space:baseEntry?.space,deliveryContext:deliveryFields.deliveryContext,lastChannel,lastTo,lastAccountId,lastThreadId};let metaPatch=deriveSessionMetaPatch({ctx:sessionCtxForState,sessionKey,existing:sessionEntry,groupResolution});metaPatch&&(sessionEntry={...sessionEntry,...metaPatch}),sessionEntry.chatType||=`direct`;let threadLabel=ctx.ThreadLabel?.trim();threadLabel&&(sessionEntry.displayName=threadLabel);let parentSessionKey=ctx.ParentSessionKey?.trim();if(isNewSession&&parentSessionKey&&parentSessionKey!==sessionKey&&sessionStore[parentSessionKey]){console.warn(`[session-init] forking from parent session: parentKey=${parentSessionKey} → sessionKey=${sessionKey} parentTokens=${sessionStore[parentSessionKey].totalTokens??`?`}`);let forked=forkSessionFromParent({parentEntry:sessionStore[parentSessionKey],agentId,sessionsDir:path.dirname(storePath)});forked&&(sessionId=forked.sessionId,sessionEntry.sessionId=forked.sessionId,sessionEntry.sessionFile=forked.sessionFile,console.warn(`[session-init] forked session created: file=${forked.sessionFile}`))}sessionEntry.sessionFile||=resolveSessionTranscriptPath(sessionEntry.sessionId,agentId,ctx.MessageThreadId),isNewSession&&(sessionEntry.compactionCount=0,sessionEntry.memoryFlushCompactionCount=void 0,sessionEntry.memoryFlushAt=void 0,sessionEntry.totalTokens=void 0,sessionEntry.inputTokens=void 0,sessionEntry.outputTokens=void 0,sessionEntry.contextTokens=void 0),sessionStore[sessionKey]={...sessionStore[sessionKey],...sessionEntry},await updateSessionStore(storePath,store=>{store[sessionKey]={...store[sessionKey],...sessionEntry}},{activeSessionKey:sessionKey,onWarn:warning=>deliverSessionMaintenanceWarning({cfg,sessionKey,entry:sessionEntry,warning})}),previousSessionEntry?.sessionId&&archiveSessionTranscripts({sessionId:previousSessionEntry.sessionId,storePath,sessionFile:previousSessionEntry.sessionFile,agentId,reason:`reset`});let sessionCtx={...ctx,BodyStripped:normalizeInboundTextNewlines(bodyStripped??ctx.BodyForAgent??ctx.Body??ctx.CommandBody??ctx.RawBody??ctx.BodyForCommands??``),SessionId:sessionId,IsNewSession:isNewSession?`true`:`false`},hookRunner=getGlobalHookRunner();if(hookRunner&&isNewSession){let effectiveSessionId=sessionId??``;previousSessionEntry?.sessionId&&previousSessionEntry.sessionId!==effectiveSessionId&&hookRunner.hasHooks(`session_end`)&&hookRunner.runSessionEnd({sessionId:previousSessionEntry.sessionId,messageCount:0},{sessionId:previousSessionEntry.sessionId,agentId:resolveSessionAgentId({sessionKey,config:cfg})}).catch(()=>{}),hookRunner.hasHooks(`session_start`)&&hookRunner.runSessionStart({sessionId:effectiveSessionId,resumedFrom:previousSessionEntry?.sessionId},{sessionId:effectiveSessionId,agentId:resolveSessionAgentId({sessionKey,config:cfg})}).catch(()=>{})}return{sessionCtx,sessionEntry,previousSessionEntry,sessionStore,sessionKey,sessionId:sessionId??crypto.randomUUID(),isNewSession,resetTriggered,systemSent,abortedLastRun,storePath,sessionScope,groupResolution,isGroup,bodyStripped,triggerBodyNormalized}}async function stageSandboxMedia(params){let{ctx,sessionCtx,cfg,sessionKey,workspaceDir}=params,hasPathsArray=Array.isArray(ctx.MediaPaths)&&ctx.MediaPaths.length>0,pathsFromArray=Array.isArray(ctx.MediaPaths)?ctx.MediaPaths:void 0,rawPaths=pathsFromArray&&pathsFromArray.length>0?pathsFromArray:ctx.MediaPath?.trim()?[ctx.MediaPath.trim()]:[];if(rawPaths.length===0||!sessionKey)return;let sandbox=await ensureSandboxWorkspaceForSession({config:cfg,sessionKey,workspaceDir}),remoteMediaCacheDir=ctx.MediaRemoteHost?path.join(CONFIG_DIR,`media`,`remote-cache`,sessionKey):null,effectiveWorkspaceDir=sandbox?.workspaceDir??remoteMediaCacheDir;if(!effectiveWorkspaceDir)return;let resolveAbsolutePath=value=>{let resolved=value.trim();if(!resolved)return null;if(resolved.startsWith(`file://`))try{resolved=fileURLToPath(resolved)}catch{return null}return path.isAbsolute(resolved)?resolved:null};try{let destDir=sandbox?path.join(effectiveWorkspaceDir,`media`,`inbound`):effectiveWorkspaceDir;await fs$1.mkdir(destDir,{recursive:!0});let usedNames=new Set,staged=new Map;for(let raw of rawPaths){let source=resolveAbsolutePath(raw);if(!source||staged.has(source))continue;if(!ctx.MediaRemoteHost){let mediaDir=getMediaDir();try{await assertSandboxPath({filePath:source,cwd:mediaDir,root:mediaDir})}catch{logVerbose(`Blocking attempt to stage media from outside media directory: ${source}`);continue}}let baseName=path.basename(source);if(!baseName)continue;let parsed=path.parse(baseName),fileName=baseName,suffix=1;for(;usedNames.has(fileName);)fileName=`${parsed.name}-${suffix}${parsed.ext}`,suffix+=1;usedNames.add(fileName);let dest=path.join(destDir,fileName);ctx.MediaRemoteHost?await scpFile(ctx.MediaRemoteHost,source,dest):await fs$1.copyFile(source,dest);let stagedPath=sandbox?path.posix.join(`media`,`inbound`,fileName):dest;staged.set(source,stagedPath)}let rewriteIfStaged=value=>{let raw=value?.trim();if(!raw)return value;let abs=resolveAbsolutePath(raw);return abs?staged.get(abs)??value:value},nextMediaPaths=hasPathsArray?rawPaths.map(p=>rewriteIfStaged(p)??p):void 0;if(nextMediaPaths)ctx.MediaPaths=nextMediaPaths,sessionCtx.MediaPaths=nextMediaPaths,ctx.MediaPath=nextMediaPaths[0],sessionCtx.MediaPath=nextMediaPaths[0];else{let rewritten=rewriteIfStaged(ctx.MediaPath);rewritten&&rewritten!==ctx.MediaPath&&(ctx.MediaPath=rewritten,sessionCtx.MediaPath=rewritten)}if(Array.isArray(ctx.MediaUrls)&&ctx.MediaUrls.length>0){let nextUrls=ctx.MediaUrls.map(u=>rewriteIfStaged(u)??u);ctx.MediaUrls=nextUrls,sessionCtx.MediaUrls=nextUrls}let rewrittenUrl=rewriteIfStaged(ctx.MediaUrl);rewrittenUrl&&rewrittenUrl!==ctx.MediaUrl&&(ctx.MediaUrl=rewrittenUrl,sessionCtx.MediaUrl=rewrittenUrl)}catch(err){logVerbose(`Failed to stage inbound media for sandbox: ${String(err)}`)}}async function scpFile(remoteHost,remotePath,localPath){return new Promise((resolve,reject)=>{let child=spawn(`/usr/bin/scp`,[`-o`,`BatchMode=yes`,`-o`,`StrictHostKeyChecking=accept-new`,`${remoteHost}:${remotePath}`,localPath],{stdio:[`ignore`,`ignore`,`pipe`]}),stderr=``;child.stderr?.setEncoding(`utf8`),child.stderr?.on(`data`,chunk=>{stderr+=chunk}),child.once(`error`,reject),child.once(`exit`,code=>{code===0?resolve():reject(Error(`scp failed (${code}): ${stderr.trim()}`))})})}function createTypingController(params){let{onReplyStart,onCleanup,typingIntervalSeconds=6,typingTtlMs=2*6e4,silentToken=SILENT_REPLY_TOKEN,log}=params,started=!1,active=!1,runComplete=!1,dispatchIdle=!1,sealed=!1,typingTimer,typingTtlTimer,typingIntervalMs=typingIntervalSeconds*1e3,formatTypingTtl=ms=>ms%6e4==0?`${ms/6e4}m`:`${Math.round(ms/1e3)}s`,resetCycle=()=>{started=!1,active=!1,runComplete=!1,dispatchIdle=!1},cleanup=()=>{sealed||=(typingTtlTimer&&=(clearTimeout(typingTtlTimer),void 0),typingTimer&&=(clearInterval(typingTimer),void 0),active&&onCleanup?.(),resetCycle(),!0)},refreshTypingTtl=()=>{sealed||!typingIntervalMs||typingIntervalMs<=0||typingTtlMs<=0||(typingTtlTimer&&clearTimeout(typingTtlTimer),typingTtlTimer=setTimeout(()=>{typingTimer&&(log?.(`typing TTL reached (${formatTypingTtl(typingTtlMs)}); stopping typing indicator`),cleanup())},typingTtlMs))},isActive=()=>active&&!sealed,triggerTyping=async()=>{sealed||await onReplyStart?.()},ensureStart=async()=>{sealed||runComplete||(active||=!0,!started&&(started=!0,await triggerTyping()))},maybeStopOnIdle=()=>{active&&runComplete&&dispatchIdle&&cleanup()},startTypingLoop=async()=>{sealed||runComplete||(refreshTypingTtl(),onReplyStart&&(typingIntervalMs<=0||(typingTimer||=(await ensureStart(),setInterval(()=>{triggerTyping()},typingIntervalMs)))))};return{onReplyStart:ensureStart,startTypingLoop,startTypingOnText:async text=>{if(sealed)return;let trimmed=text?.trim();trimmed&&(silentToken&&isSilentReplyText(trimmed,silentToken)||(refreshTypingTtl(),await startTypingLoop()))},refreshTypingTtl,isActive,markRunComplete:()=>{runComplete=!0,maybeStopOnIdle()},markDispatchIdle:()=>{dispatchIdle=!0,maybeStopOnIdle()},cleanup}}function mergeSkillFilters(channelFilter,agentFilter){let normalize=list=>{if(Array.isArray(list))return list.map(entry=>String(entry).trim()).filter(Boolean)},channel=normalize(channelFilter),agent=normalize(agentFilter);if(!channel&&!agent)return;if(!channel)return agent;if(!agent)return channel;if(channel.length===0||agent.length===0)return[];let agentSet=new Set(agent);return channel.filter(name=>agentSet.has(name))}async function getReplyFromConfig(ctx,opts,configOverride){let isFastTestEnv=process.env.BUILDERFORCE_AGENTS_TEST_FAST===`1`,cfg=configOverride??loadConfig(),agentId=resolveSessionAgentId({sessionKey:(ctx.CommandSource===`native`?ctx.CommandTargetSessionKey?.trim():void 0)||ctx.SessionKey,config:cfg}),mergedSkillFilter=mergeSkillFilters(opts?.skillFilter,resolveAgentSkillsFilter(cfg,agentId)),resolvedOpts=mergedSkillFilter===void 0?opts:{...opts,skillFilter:mergedSkillFilter},agentCfg=cfg.agents?.defaults,sessionCfg=cfg.session,{defaultProvider,defaultModel,aliasIndex}=resolveDefaultModel({cfg,agentId}),provider=defaultProvider,model=defaultModel,hasResolvedHeartbeatModelOverride=!1;if(opts?.isHeartbeat){let heartbeatRaw=opts.heartbeatModelOverride?.trim()??agentCfg?.heartbeat?.model?.trim()??``,heartbeatRef=heartbeatRaw?resolveModelRefFromString({raw:heartbeatRaw,defaultProvider,aliasIndex}):null;heartbeatRef&&(provider=heartbeatRef.ref.provider,model=heartbeatRef.ref.model,hasResolvedHeartbeatModelOverride=!0)}let workspaceDir=(await ensureAgentWorkspace({dir:resolveAgentWorkspaceDir(cfg,agentId)??DEFAULT_AGENT_WORKSPACE_DIR,ensureBootstrapFiles:!agentCfg?.skipBootstrap&&!isFastTestEnv})).dir,agentDir=resolveAgentDir(cfg,agentId),timeoutMs=resolveAgentTimeoutMs({cfg,overrideSeconds:opts?.timeoutOverrideSeconds}),configuredTypingSeconds=agentCfg?.typingIntervalSeconds??sessionCfg?.typingIntervalSeconds,typingIntervalSeconds=typeof configuredTypingSeconds==`number`?configuredTypingSeconds:6,typing=createTypingController({onReplyStart:opts?.onReplyStart,onCleanup:opts?.onTypingCleanup,typingIntervalSeconds,silentToken:SILENT_REPLY_TOKEN,log:defaultRuntime.log});opts?.onTypingController?.(typing);let finalized=finalizeInboundContext(ctx);isFastTestEnv||(await applyMediaUnderstanding({ctx:finalized,cfg,agentDir,activeModel:{provider,model}}),await applyLinkUnderstanding({ctx:finalized,cfg}));let commandAuthorized=finalized.CommandAuthorized;resolveCommandAuthorization({ctx:finalized,cfg,commandAuthorized});let{sessionCtx,sessionEntry,previousSessionEntry,sessionStore,sessionKey,sessionId,isNewSession,resetTriggered,systemSent,abortedLastRun,storePath,sessionScope,groupResolution,isGroup,triggerBodyNormalized,bodyStripped}=await initSessionState({ctx:finalized,cfg,commandAuthorized});await applyResetModelOverride({cfg,resetTriggered,bodyStripped,sessionCtx,ctx:finalized,sessionEntry,sessionStore,sessionKey,storePath,defaultProvider,defaultModel,aliasIndex});let directiveResult=await resolveReplyDirectives({ctx:finalized,cfg,agentId,agentDir,workspaceDir,agentCfg,sessionCtx,sessionEntry,sessionStore,sessionKey,storePath,sessionScope,groupResolution,isGroup,triggerBodyNormalized,commandAuthorized,defaultProvider,defaultModel,aliasIndex,provider,model,hasResolvedHeartbeatModelOverride,typing,opts:resolvedOpts,skillFilter:mergedSkillFilter});if(directiveResult.kind===`reply`)return directiveResult.reply;let{commandSource,command,allowTextCommands,skillCommands,directives,cleanedBody,elevatedEnabled,elevatedAllowed,elevatedFailures,defaultActivation,resolvedThinkLevel,resolvedVerboseLevel,resolvedReasoningLevel,resolvedElevatedLevel,execOverrides,blockStreamingEnabled,blockReplyChunking,resolvedBlockStreamingBreak,provider:resolvedProvider,model:resolvedModel,modelState,contextTokens,inlineStatusRequested,directiveAck,perMessageQueueMode,perMessageQueueOptions}=directiveResult.result;provider=resolvedProvider,model=resolvedModel;let inlineActionResult=await handleInlineActions({ctx,sessionCtx,cfg,agentId,agentDir,sessionEntry,previousSessionEntry,sessionStore,sessionKey,storePath,sessionScope,workspaceDir,isGroup,opts:resolvedOpts,typing,allowTextCommands,inlineStatusRequested,command,skillCommands,directives,cleanedBody,elevatedEnabled,elevatedAllowed,elevatedFailures,defaultActivation:()=>defaultActivation,resolvedThinkLevel,resolvedVerboseLevel,resolvedReasoningLevel,resolvedElevatedLevel,resolveDefaultThinkingLevel:modelState.resolveDefaultThinkingLevel,provider,model,contextTokens,directiveAck,abortedLastRun,skillFilter:mergedSkillFilter});return inlineActionResult.kind===`reply`?inlineActionResult.reply:(directives=inlineActionResult.directives,abortedLastRun=inlineActionResult.abortedLastRun??abortedLastRun,await stageSandboxMedia({ctx,sessionCtx,cfg,sessionKey,workspaceDir}),runPreparedReply({ctx,sessionCtx,cfg,agentId,agentDir,agentCfg,sessionCfg,commandAuthorized,command,commandSource,allowTextCommands,directives,defaultActivation,resolvedThinkLevel,resolvedVerboseLevel,resolvedReasoningLevel,resolvedElevatedLevel,execOverrides,elevatedEnabled,elevatedAllowed,blockStreamingEnabled,blockReplyChunking,resolvedBlockStreamingBreak,modelState,provider,model,perMessageQueueMode,perMessageQueueOptions,typing,opts:resolvedOpts,defaultProvider,defaultModel,timeoutMs,isNewSession,resetTriggered,systemSent,sessionEntry,sessionStore,sessionKey,sessionId,storePath,workspaceDir,abortedLastRun}))}function pruneMapToMaxSize(map,maxSize){let limit=Math.max(0,Math.floor(maxSize));if(limit<=0){map.clear();return}for(;map.size>limit;){let oldest=map.keys().next();if(oldest.done)break;map.delete(oldest.value)}}function createDedupeCache(options){let ttlMs=Math.max(0,options.ttlMs),maxSize=Math.max(0,Math.floor(options.maxSize)),cache=new Map,touch=(key,now)=>{cache.delete(key),cache.set(key,now)},prune=now=>{let cutoff=ttlMs>0?now-ttlMs:void 0;if(cutoff!==void 0)for(let[entryKey,entryTs]of cache)entryTs<cutoff&&cache.delete(entryKey);if(maxSize<=0){cache.clear();return}pruneMapToMaxSize(cache,maxSize)};return{check:(key,now=Date.now())=>{if(!key)return!1;let existing=cache.get(key);return existing!==void 0&&(ttlMs<=0||now-existing<ttlMs)?(touch(key,now),!0):(touch(key,now),prune(now),!1)},clear:()=>{cache.clear()},size:()=>cache.size}}const inboundDedupeCache=createDedupeCache({ttlMs:20*6e4,maxSize:5e3}),normalizeProvider=value=>value?.trim().toLowerCase()||``,resolveInboundPeerId=ctx=>ctx.OriginatingTo??ctx.To??ctx.From??ctx.SessionKey;function buildInboundDedupeKey(ctx){let provider=normalizeProvider(ctx.OriginatingChannel??ctx.Provider??ctx.Surface),messageId=ctx.MessageSid?.trim();if(!provider||!messageId)return null;let peerId=resolveInboundPeerId(ctx);if(!peerId)return null;let sessionKey=ctx.SessionKey?.trim()??``;return[provider,ctx.AccountId?.trim()??``,sessionKey,peerId,ctx.MessageThreadId!==void 0&&ctx.MessageThreadId!==null?String(ctx.MessageThreadId):``,messageId].filter(Boolean).join(`|`)}function shouldSkipDuplicateInbound(ctx,opts){let key=buildInboundDedupeKey(ctx);if(!key)return!1;let skipped=(opts?.cache??inboundDedupeCache).check(key,opts?.now);return skipped&&shouldLogVerbose()&&logVerbose(`inbound dedupe: skipped ${key}`),skipped}const AUDIO_PLACEHOLDER_RE=/^<media:audio>(\s*\([^)]*\))?$/i,AUDIO_HEADER_RE=/^\[Audio\b/i,normalizeMediaType=value=>value.split(`;`)[0]?.trim().toLowerCase(),isInboundAudioContext=ctx=>{if([typeof ctx.MediaType==`string`?ctx.MediaType:void 0,...Array.isArray(ctx.MediaTypes)?ctx.MediaTypes:[]].filter(Boolean).map(type=>normalizeMediaType(type)).some(type=>type===`audio`||type.startsWith(`audio/`)))return!0;let trimmed=(typeof ctx.BodyForCommands==`string`?ctx.BodyForCommands:typeof ctx.CommandBody==`string`?ctx.CommandBody:typeof ctx.RawBody==`string`?ctx.RawBody:typeof ctx.Body==`string`?ctx.Body:``).trim();return trimmed?AUDIO_PLACEHOLDER_RE.test(trimmed)?!0:AUDIO_HEADER_RE.test(trimmed):!1},resolveSessionTtsAuto=(ctx,cfg)=>{let sessionKey=((ctx.CommandSource===`native`?ctx.CommandTargetSessionKey?.trim():void 0)??ctx.SessionKey)?.trim();if(!sessionKey)return;let agentId=resolveSessionAgentId({sessionKey,config:cfg}),storePath=resolveStorePath(cfg.session?.store,{agentId});try{let store=loadSessionStore(storePath);return normalizeTtsAutoMode((store[sessionKey.toLowerCase()]??store[sessionKey])?.ttsAuto)}catch{return}};async function dispatchReplyFromConfig(params){let{ctx,cfg,dispatcher}=params,diagnosticsEnabled=isDiagnosticsEnabled(cfg),channel=String(ctx.Surface??ctx.Provider??`unknown`).toLowerCase(),chatId=ctx.To??ctx.From,messageId=ctx.MessageSid??ctx.MessageSidFirst??ctx.MessageSidLast,sessionKey=ctx.SessionKey,startTime=diagnosticsEnabled?Date.now():0,canTrackSession=diagnosticsEnabled&&!!sessionKey,recordProcessed=(outcome,opts)=>{diagnosticsEnabled&&logMessageProcessed({channel,chatId,messageId,sessionKey,durationMs:Date.now()-startTime,outcome,reason:opts?.reason,error:opts?.error})},markProcessing=()=>{!canTrackSession||!sessionKey||(logMessageQueued({sessionKey,channel,source:`dispatch`}),logSessionStateChange({sessionKey,state:`processing`,reason:`message_start`}))},markIdle=reason=>{!canTrackSession||!sessionKey||logSessionStateChange({sessionKey,state:`idle`,reason})};if(shouldSkipDuplicateInbound(ctx))return recordProcessed(`skipped`,{reason:`duplicate`}),{queuedFinal:!1,counts:dispatcher.getQueuedCounts()};let inboundAudio=isInboundAudioContext(ctx),sessionTtsAuto=resolveSessionTtsAuto(ctx,cfg),hookRunner=getGlobalHookRunner(),timestamp=typeof ctx.Timestamp==`number`&&Number.isFinite(ctx.Timestamp)?ctx.Timestamp:void 0,messageIdForHook=ctx.MessageSidFull??ctx.MessageSid??ctx.MessageSidFirst??ctx.MessageSidLast,content=typeof ctx.BodyForCommands==`string`?ctx.BodyForCommands:typeof ctx.RawBody==`string`?ctx.RawBody:typeof ctx.Body==`string`?ctx.Body:``,channelId=(ctx.OriginatingChannel??ctx.Surface??ctx.Provider??``).toLowerCase(),conversationId=ctx.OriginatingTo??ctx.To??ctx.From??void 0;hookRunner?.hasHooks(`message_received`)&&hookRunner.runMessageReceived({from:ctx.From??``,content,timestamp,metadata:{to:ctx.To,provider:ctx.Provider,surface:ctx.Surface,threadId:ctx.MessageThreadId,originatingChannel:ctx.OriginatingChannel,originatingTo:ctx.OriginatingTo,messageId:messageIdForHook,senderId:ctx.SenderId,senderName:ctx.SenderName,senderUsername:ctx.SenderUsername,senderE164:ctx.SenderE164}},{channelId,accountId:ctx.AccountId,conversationId}).catch(err=>{logVerbose(`dispatch-from-config: message_received plugin hook failed: ${String(err)}`)}),sessionKey&&triggerInternalHook(createInternalHookEvent(`message`,`received`,sessionKey,{from:ctx.From??``,content,timestamp,channelId,accountId:ctx.AccountId,conversationId,messageId:messageIdForHook,metadata:{to:ctx.To,provider:ctx.Provider,surface:ctx.Surface,threadId:ctx.MessageThreadId,senderId:ctx.SenderId,senderName:ctx.SenderName,senderUsername:ctx.SenderUsername,senderE164:ctx.SenderE164}})).catch(err=>{logVerbose(`dispatch-from-config: message_received internal hook failed: ${String(err)}`)});let originatingChannel=ctx.OriginatingChannel,originatingTo=ctx.OriginatingTo,currentSurface=(ctx.Surface??ctx.Provider)?.toLowerCase(),shouldRouteToOriginating=isRoutableChannel(originatingChannel)&&originatingTo&&originatingChannel!==currentSurface,ttsChannel=shouldRouteToOriginating?originatingChannel:currentSurface,sendPayloadAsync=async(payload,abortSignal,mirror)=>{if(!originatingChannel||!originatingTo||abortSignal?.aborted)return;let result=await routeReply({payload,channel:originatingChannel,to:originatingTo,sessionKey:ctx.SessionKey,accountId:ctx.AccountId,threadId:ctx.MessageThreadId,cfg,abortSignal,mirror});result.ok||logVerbose(`dispatch-from-config: route-reply failed: ${result.error??`unknown error`}`)};markProcessing();try{let fastAbort=await tryFastAbortFromMessage({ctx,cfg});if(fastAbort.handled){let payload={text:formatAbortReplyText(fastAbort.stoppedSubagents)},queuedFinal=!1,routedFinalCount=0;if(shouldRouteToOriginating&&originatingChannel&&originatingTo){let result=await routeReply({payload,channel:originatingChannel,to:originatingTo,sessionKey:ctx.SessionKey,accountId:ctx.AccountId,threadId:ctx.MessageThreadId,cfg});queuedFinal=result.ok,result.ok&&(routedFinalCount+=1),result.ok||logVerbose(`dispatch-from-config: route-reply (abort) failed: ${result.error??`unknown error`}`)}else queuedFinal=dispatcher.sendFinalReply(payload);let counts=dispatcher.getQueuedCounts();return counts.final+=routedFinalCount,recordProcessed(`completed`,{reason:`fast_abort`}),markIdle(`message_completed`),{queuedFinal,counts}}let accumulatedBlockText=``,blockCount=0,shouldSendToolSummaries=ctx.ChatType!==`group`&&ctx.CommandSource!==`native`,resolveToolDeliveryPayload=payload=>shouldSendToolSummaries?payload:payload.mediaUrl||(payload.mediaUrls?.length??0)>0?{...payload,text:void 0}:null,replyResult=await(params.replyResolver??getReplyFromConfig)(ctx,{...params.replyOptions,onToolResult:payload=>(async()=>{let deliveryPayload=resolveToolDeliveryPayload(await maybeApplyTtsToPayload({payload,cfg,channel:ttsChannel,kind:`tool`,inboundAudio,ttsAuto:sessionTtsAuto}));deliveryPayload&&(shouldRouteToOriginating?await sendPayloadAsync(deliveryPayload,void 0,!1):dispatcher.sendToolResult(deliveryPayload))})(),onBlockReply:(payload,context)=>(async()=>{payload.text&&(accumulatedBlockText.length>0&&(accumulatedBlockText+=`
446
- `),accumulatedBlockText+=payload.text,blockCount++);let ttsPayload=await maybeApplyTtsToPayload({payload,cfg,channel:ttsChannel,kind:`block`,inboundAudio,ttsAuto:sessionTtsAuto});shouldRouteToOriginating?await sendPayloadAsync(ttsPayload,context?.abortSignal,!1):dispatcher.sendBlockReply(ttsPayload)})()},cfg),replies=replyResult?Array.isArray(replyResult)?replyResult:[replyResult]:[],queuedFinal=!1,routedFinalCount=0;for(let reply of replies){let ttsReply=await maybeApplyTtsToPayload({payload:reply,cfg,channel:ttsChannel,kind:`final`,inboundAudio,ttsAuto:sessionTtsAuto});if(shouldRouteToOriginating&&originatingChannel&&originatingTo){let result=await routeReply({payload:ttsReply,channel:originatingChannel,to:originatingTo,sessionKey:ctx.SessionKey,accountId:ctx.AccountId,threadId:ctx.MessageThreadId,cfg});result.ok||logVerbose(`dispatch-from-config: route-reply (final) failed: ${result.error??`unknown error`}`),queuedFinal=result.ok||queuedFinal,result.ok&&(routedFinalCount+=1)}else queuedFinal=dispatcher.sendFinalReply(ttsReply)||queuedFinal}if((resolveTtsConfig(cfg).mode??`final`)===`final`&&replies.length===0&&blockCount>0&&accumulatedBlockText.trim())try{let ttsSyntheticReply=await maybeApplyTtsToPayload({payload:{text:accumulatedBlockText},cfg,channel:ttsChannel,kind:`final`,inboundAudio,ttsAuto:sessionTtsAuto});if(ttsSyntheticReply.mediaUrl){let ttsOnlyPayload={mediaUrl:ttsSyntheticReply.mediaUrl,audioAsVoice:ttsSyntheticReply.audioAsVoice};if(shouldRouteToOriginating&&originatingChannel&&originatingTo){let result=await routeReply({payload:ttsOnlyPayload,channel:originatingChannel,to:originatingTo,sessionKey:ctx.SessionKey,accountId:ctx.AccountId,threadId:ctx.MessageThreadId,cfg});queuedFinal=result.ok||queuedFinal,result.ok&&(routedFinalCount+=1),result.ok||logVerbose(`dispatch-from-config: route-reply (tts-only) failed: ${result.error??`unknown error`}`)}else queuedFinal=dispatcher.sendFinalReply(ttsOnlyPayload)||queuedFinal}}catch(err){logVerbose(`dispatch-from-config: accumulated block TTS failed: ${err instanceof Error?err.message:String(err)}`)}let counts=dispatcher.getQueuedCounts();return counts.final+=routedFinalCount,recordProcessed(`completed`),markIdle(`message_completed`),{queuedFinal,counts}}catch(err){throw recordProcessed(`error`,{error:String(err)}),markIdle(`message_error`),err}}const activeDispatchers=new Set;let nextId=0;function registerDispatcher(dispatcher){let id=`dispatcher-${++nextId}`,tracked={id,pending:dispatcher.pending,waitForIdle:dispatcher.waitForIdle};return activeDispatchers.add(tracked),{id,unregister:()=>{activeDispatchers.delete(tracked)}}}function getTotalPendingReplies(){let total=0;for(let dispatcher of activeDispatchers)total+=dispatcher.pending();return total}const DEFAULT_HUMAN_DELAY_MAX_MS=2500;function getHumanDelay(config){let mode=config?.mode??`off`;if(mode===`off`)return 0;let min=mode===`custom`?config?.minMs??800:800,max=mode===`custom`?config?.maxMs??DEFAULT_HUMAN_DELAY_MAX_MS:DEFAULT_HUMAN_DELAY_MAX_MS;return max<=min?min:Math.floor(Math.random()*(max-min+1))+min}function normalizeReplyPayloadInternal(payload,opts){let prefixContext=opts.responsePrefixContextProvider?.()??opts.responsePrefixContext;return normalizeReplyPayload(payload,{responsePrefix:opts.responsePrefix,responsePrefixContext:prefixContext,onHeartbeatStrip:opts.onHeartbeatStrip,onSkip:opts.onSkip})}function createReplyDispatcher(options){let sendChain=Promise.resolve(),pending=1,completeCalled=!1,sentFirstBlock=!1,queuedCounts={tool:0,block:0,final:0},{unregister}=registerDispatcher({pending:()=>pending,waitForIdle:()=>sendChain}),enqueue=(kind,payload)=>{let normalized=normalizeReplyPayloadInternal(payload,{responsePrefix:options.responsePrefix,responsePrefixContext:options.responsePrefixContext,responsePrefixContextProvider:options.responsePrefixContextProvider,onHeartbeatStrip:options.onHeartbeatStrip,onSkip:reason=>options.onSkip?.(payload,{kind,reason})});if(!normalized)return!1;queuedCounts[kind]+=1,pending+=1;let shouldDelay=kind===`block`&&sentFirstBlock;return kind===`block`&&(sentFirstBlock=!0),sendChain=sendChain.then(async()=>{if(shouldDelay){let delayMs=getHumanDelay(options.humanDelay);delayMs>0&&await sleep$2(delayMs)}await options.deliver(normalized,{kind})}).catch(err=>{options.onError?.(err,{kind})}).finally(()=>{--pending,pending===1&&completeCalled&&--pending,pending===0&&(unregister(),options.onIdle?.())}),!0};return{sendToolResult:payload=>enqueue(`tool`,payload),sendBlockReply:payload=>enqueue(`block`,payload),sendFinalReply:payload=>enqueue(`final`,payload),waitForIdle:()=>sendChain,getQueuedCounts:()=>({...queuedCounts}),markComplete:()=>{completeCalled||(completeCalled=!0,Promise.resolve().then(()=>{pending===1&&completeCalled&&(--pending,pending===0&&(unregister(),options.onIdle?.()))}))}}}function createReplyDispatcherWithTyping(options){let{onReplyStart,onIdle,onCleanup,...dispatcherOptions}=options,typingController;return{dispatcher:createReplyDispatcher({...dispatcherOptions,onIdle:()=>{typingController?.markDispatchIdle(),onIdle?.()}}),replyOptions:{onReplyStart,onTypingCleanup:onCleanup,onTypingController:typing=>{typingController=typing}},markDispatchIdle:()=>{typingController?.markDispatchIdle(),onIdle?.()}}}async function withReplyDispatcher(params){try{return await params.run()}finally{params.dispatcher.markComplete();try{await params.dispatcher.waitForIdle()}finally{await params.onSettled?.()}}}async function dispatchInboundMessage(params){let finalized=finalizeInboundContext(params.ctx);return await withReplyDispatcher({dispatcher:params.dispatcher,run:()=>dispatchReplyFromConfig({ctx:finalized,cfg:params.cfg,dispatcher:params.dispatcher,replyOptions:params.replyOptions,replyResolver:params.replyResolver})})}async function dispatchInboundMessageWithBufferedDispatcher(params){let{dispatcher,replyOptions,markDispatchIdle}=createReplyDispatcherWithTyping(params.dispatcherOptions);try{return await dispatchInboundMessage({ctx:params.ctx,cfg:params.cfg,dispatcher,replyResolver:params.replyResolver,replyOptions:{...params.replyOptions,...replyOptions}})}finally{markDispatchIdle()}}async function dispatchInboundMessageWithDispatcher(params){let dispatcher=createReplyDispatcher(params.dispatcherOptions);return await dispatchInboundMessage({ctx:params.ctx,cfg:params.cfg,dispatcher,replyResolver:params.replyResolver,replyOptions:params.replyOptions})}async function dispatchReplyWithBufferedBlockDispatcher(params){return await dispatchInboundMessageWithBufferedDispatcher({ctx:params.ctx,cfg:params.cfg,dispatcherOptions:params.dispatcherOptions,replyResolver:params.replyResolver,replyOptions:params.replyOptions})}async function dispatchReplyWithDispatcher(params){return await dispatchInboundMessageWithDispatcher({ctx:params.ctx,cfg:params.cfg,dispatcherOptions:params.dispatcherOptions,replyResolver:params.replyResolver,replyOptions:params.replyOptions})}function shouldAckReaction(params){let scope=params.scope??`group-mentions`;return scope===`off`||scope===`none`?!1:scope===`all`?!0:scope===`direct`?params.isDirect:scope===`group-all`?params.isGroup:scope===`group-mentions`?!params.isMentionableGroup||!params.requireMention||!params.canDetectMention?!1:params.effectiveWasMentioned||params.shouldBypassMention===!0:!1}function shouldAckReactionForWhatsApp(params){return params.emoji?params.isDirect?params.directEnabled:!params.isGroup||params.groupMode===`never`?!1:params.groupMode===`always`?!0:shouldAckReaction({scope:`group-mentions`,isDirect:!1,isGroup:!0,isMentionableGroup:!0,requireMention:!0,canDetectMention:!0,effectiveWasMentioned:params.wasMentioned,shouldBypassMention:params.groupActivated}):!1}function removeAckReactionAfterReply(params){params.removeAfterReply&&params.ackReactionPromise&&params.ackReactionValue&&params.ackReactionPromise.then(didAck=>{didAck&&params.remove().catch(err=>params.onError?.(err))})}function resolveCommandAuthorizedFromAuthorizers(params){let{useAccessGroups,authorizers}=params,mode=params.modeWhenAccessGroupsOff??`allow`;return useAccessGroups?authorizers.some(entry=>entry.configured&&entry.allowed):mode===`allow`?!0:mode===`deny`?!1:authorizers.some(entry=>entry.configured)?authorizers.some(entry=>entry.configured&&entry.allowed):!0}function resolveControlCommandGate(params){let commandAuthorized=resolveCommandAuthorizedFromAuthorizers({useAccessGroups:params.useAccessGroups,authorizers:params.authorizers,modeWhenAccessGroupsOff:params.modeWhenAccessGroupsOff});return{commandAuthorized,shouldBlock:params.allowTextCommands&&params.hasControlCommand&&!commandAuthorized}}const presenceCache=new Map;function resolveAccountKey$1(accountId){return accountId??`default`}function setPresence(accountId,userId,data){let accountKey=resolveAccountKey$1(accountId),accountCache=presenceCache.get(accountKey);if(accountCache||(accountCache=new Map,presenceCache.set(accountKey,accountCache)),accountCache.set(userId,data),accountCache.size>5e3){let oldest=accountCache.keys().next().value;oldest!==void 0&&accountCache.delete(oldest)}}function getPresence(accountId,userId){return presenceCache.get(resolveAccountKey$1(accountId))?.get(userId)}function readParentIdParam$1(params){return params.clearParent===!0||params.parentId===null?null:readStringParam(params,`parentId`)}async function runRoleMutation(params){let guildId=readStringParam(params.values,`guildId`,{required:!0}),userId=readStringParam(params.values,`userId`,{required:!0}),roleId=readStringParam(params.values,`roleId`,{required:!0});if(params.accountId){await params.mutate({guildId,userId,roleId},{accountId:params.accountId});return}await params.mutate({guildId,userId,roleId})}async function handleDiscordGuildAction(action,params,isActionEnabled){let accountId=readStringParam(params,`accountId`);switch(action){case`memberInfo`:{if(!isActionEnabled(`memberInfo`))throw Error(`Discord member info is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),member=accountId?await fetchMemberInfoDiscord(guildId,userId,{accountId}):await fetchMemberInfoDiscord(guildId,userId),presence=getPresence(accountId,userId),activities=presence?.activities??void 0,status=presence?.status??void 0;return jsonResult({ok:!0,member,...presence?{status,activities}:{}})}case`roleInfo`:{if(!isActionEnabled(`roleInfo`))throw Error(`Discord role info is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,roles:accountId?await fetchRoleInfoDiscord(guildId,{accountId}):await fetchRoleInfoDiscord(guildId)})}case`emojiList`:{if(!isActionEnabled(`reactions`))throw Error(`Discord reactions are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,emojis:accountId?await listGuildEmojisDiscord(guildId,{accountId}):await listGuildEmojisDiscord(guildId)})}case`emojiUpload`:{if(!isActionEnabled(`emojiUploads`))throw Error(`Discord emoji uploads are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`,{required:!0}),roleIds=readStringArrayParam(params,`roleIds`);return jsonResult({ok:!0,emoji:accountId?await uploadEmojiDiscord({guildId,name,mediaUrl,roleIds:roleIds?.length?roleIds:void 0},{accountId}):await uploadEmojiDiscord({guildId,name,mediaUrl,roleIds:roleIds?.length?roleIds:void 0})})}case`stickerUpload`:{if(!isActionEnabled(`stickerUploads`))throw Error(`Discord sticker uploads are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),description=readStringParam(params,`description`,{required:!0}),tags=readStringParam(params,`tags`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`,{required:!0});return jsonResult({ok:!0,sticker:accountId?await uploadStickerDiscord({guildId,name,description,tags,mediaUrl},{accountId}):await uploadStickerDiscord({guildId,name,description,tags,mediaUrl})})}case`roleAdd`:if(!isActionEnabled(`roles`,!1))throw Error(`Discord role changes are disabled.`);return await runRoleMutation({accountId,values:params,mutate:addRoleDiscord}),jsonResult({ok:!0});case`roleRemove`:if(!isActionEnabled(`roles`,!1))throw Error(`Discord role changes are disabled.`);return await runRoleMutation({accountId,values:params,mutate:removeRoleDiscord}),jsonResult({ok:!0});case`channelInfo`:{if(!isActionEnabled(`channelInfo`))throw Error(`Discord channel info is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0});return jsonResult({ok:!0,channel:accountId?await fetchChannelInfoDiscord(channelId,{accountId}):await fetchChannelInfoDiscord(channelId)})}case`channelList`:{if(!isActionEnabled(`channelInfo`))throw Error(`Discord channel info is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,channels:accountId?await listGuildChannelsDiscord(guildId,{accountId}):await listGuildChannelsDiscord(guildId)})}case`voiceStatus`:{if(!isActionEnabled(`voiceStatus`))throw Error(`Discord voice status is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0});return jsonResult({ok:!0,voice:accountId?await fetchVoiceStatusDiscord(guildId,userId,{accountId}):await fetchVoiceStatusDiscord(guildId,userId)})}case`eventList`:{if(!isActionEnabled(`events`))throw Error(`Discord events are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,events:accountId?await listScheduledEventsDiscord(guildId,{accountId}):await listScheduledEventsDiscord(guildId)})}case`eventCreate`:{if(!isActionEnabled(`events`))throw Error(`Discord events are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),startTime=readStringParam(params,`startTime`,{required:!0}),endTime=readStringParam(params,`endTime`),description=readStringParam(params,`description`),channelId=readStringParam(params,`channelId`),location=readStringParam(params,`location`),entityTypeRaw=readStringParam(params,`entityType`),entityType=entityTypeRaw===`stage`?1:entityTypeRaw===`external`?3:2,payload={name,description,scheduled_start_time:startTime,scheduled_end_time:endTime,entity_type:entityType,channel_id:channelId,entity_metadata:entityType===3&&location?{location}:void 0,privacy_level:2};return jsonResult({ok:!0,event:accountId?await createScheduledEventDiscord(guildId,payload,{accountId}):await createScheduledEventDiscord(guildId,payload)})}case`channelCreate`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),type=readNumberParam(params,`type`,{integer:!0}),parentId=readParentIdParam$1(params),topic=readStringParam(params,`topic`),position=readNumberParam(params,`position`,{integer:!0}),nsfw=params.nsfw;return jsonResult({ok:!0,channel:accountId?await createChannelDiscord({guildId,name,type:type??void 0,parentId:parentId??void 0,topic:topic??void 0,position:position??void 0,nsfw},{accountId}):await createChannelDiscord({guildId,name,type:type??void 0,parentId:parentId??void 0,topic:topic??void 0,position:position??void 0,nsfw})})}case`channelEdit`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0}),name=readStringParam(params,`name`),topic=readStringParam(params,`topic`),position=readNumberParam(params,`position`,{integer:!0}),parentId=readParentIdParam$1(params),nsfw=params.nsfw,rateLimitPerUser=readNumberParam(params,`rateLimitPerUser`,{integer:!0}),archived=typeof params.archived==`boolean`?params.archived:void 0,locked=typeof params.locked==`boolean`?params.locked:void 0,autoArchiveDuration=readNumberParam(params,`autoArchiveDuration`,{integer:!0});return jsonResult({ok:!0,channel:accountId?await editChannelDiscord({channelId,name:name??void 0,topic:topic??void 0,position:position??void 0,parentId,nsfw,rateLimitPerUser:rateLimitPerUser??void 0,archived,locked,autoArchiveDuration:autoArchiveDuration??void 0},{accountId}):await editChannelDiscord({channelId,name:name??void 0,topic:topic??void 0,position:position??void 0,parentId,nsfw,rateLimitPerUser:rateLimitPerUser??void 0,archived,locked,autoArchiveDuration:autoArchiveDuration??void 0})})}case`channelDelete`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0});return jsonResult(accountId?await deleteChannelDiscord(channelId,{accountId}):await deleteChannelDiscord(channelId))}case`channelMove`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),channelId=readStringParam(params,`channelId`,{required:!0}),parentId=readParentIdParam$1(params),position=readNumberParam(params,`position`,{integer:!0});return accountId?await moveChannelDiscord({guildId,channelId,parentId,position:position??void 0},{accountId}):await moveChannelDiscord({guildId,channelId,parentId,position:position??void 0}),jsonResult({ok:!0})}case`categoryCreate`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),position=readNumberParam(params,`position`,{integer:!0});return jsonResult({ok:!0,category:accountId?await createChannelDiscord({guildId,name,type:4,position:position??void 0},{accountId}):await createChannelDiscord({guildId,name,type:4,position:position??void 0})})}case`categoryEdit`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let categoryId=readStringParam(params,`categoryId`,{required:!0}),name=readStringParam(params,`name`),position=readNumberParam(params,`position`,{integer:!0});return jsonResult({ok:!0,category:accountId?await editChannelDiscord({channelId:categoryId,name:name??void 0,position:position??void 0},{accountId}):await editChannelDiscord({channelId:categoryId,name:name??void 0,position:position??void 0})})}case`categoryDelete`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let categoryId=readStringParam(params,`categoryId`,{required:!0});return jsonResult(accountId?await deleteChannelDiscord(categoryId,{accountId}):await deleteChannelDiscord(categoryId))}case`channelPermissionSet`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0}),targetId=readStringParam(params,`targetId`,{required:!0}),targetType=readStringParam(params,`targetType`,{required:!0})===`member`?1:0,allow=readStringParam(params,`allow`),deny=readStringParam(params,`deny`);return accountId?await setChannelPermissionDiscord({channelId,targetId,targetType,allow:allow??void 0,deny:deny??void 0},{accountId}):await setChannelPermissionDiscord({channelId,targetId,targetType,allow:allow??void 0,deny:deny??void 0}),jsonResult({ok:!0})}case`channelPermissionRemove`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0}),targetId=readStringParam(params,`targetId`,{required:!0});return accountId?await removeChannelPermissionDiscord(channelId,targetId,{accountId}):await removeChannelPermissionDiscord(channelId,targetId),jsonResult({ok:!0})}default:throw Error(`Unknown action: ${action}`)}}function parseDiscordMessageLink(link){let match=link.trim().match(/^(?:https?:\/\/)?(?:ptb\.|canary\.)?discord(?:app)?\.com\/channels\/(\d+)\/(\d+)\/(\d+)(?:\/?|\?.*)$/i);if(!match)throw Error(`Invalid Discord message link. Expected https://discord.com/channels/<guildId>/<channelId>/<messageId>.`);return{guildId:match[1],channelId:match[2],messageId:match[3]}}async function handleDiscordMessagingAction(action,params,isActionEnabled){let resolveChannelId=()=>resolveDiscordChannelId(readStringParam(params,`channelId`,{required:!0})),accountId=readStringParam(params,`accountId`),normalizeMessage=message=>!message||typeof message!=`object`?message:withNormalizedTimestamp(message,message.timestamp);switch(action){case`react`:{if(!isActionEnabled(`reactions`))throw Error(`Discord reactions are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0}),{emoji,remove,isEmpty}=readReactionParams(params,{removeErrorMessage:`Emoji is required to remove a Discord reaction.`});return remove?(accountId?await removeReactionDiscord(channelId,messageId,emoji,{accountId}):await removeReactionDiscord(channelId,messageId,emoji),jsonResult({ok:!0,removed:emoji})):isEmpty?jsonResult({ok:!0,removed:(accountId?await removeOwnReactionsDiscord(channelId,messageId,{accountId}):await removeOwnReactionsDiscord(channelId,messageId)).removed}):(accountId?await reactMessageDiscord(channelId,messageId,emoji,{accountId}):await reactMessageDiscord(channelId,messageId,emoji),jsonResult({ok:!0,added:emoji}))}case`reactions`:{if(!isActionEnabled(`reactions`))throw Error(`Discord reactions are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0}),limitRaw=params.limit,limit=typeof limitRaw==`number`&&Number.isFinite(limitRaw)?limitRaw:void 0;return jsonResult({ok:!0,reactions:await fetchReactionsDiscord(channelId,messageId,{...accountId?{accountId}:{},limit})})}case`sticker`:{if(!isActionEnabled(`stickers`))throw Error(`Discord stickers are disabled.`);let to=readStringParam(params,`to`,{required:!0}),content=readStringParam(params,`content`);return await sendStickerDiscord(to,readStringArrayParam(params,`stickerIds`,{required:!0,label:`stickerIds`}),{...accountId?{accountId}:{},content}),jsonResult({ok:!0})}case`poll`:{if(!isActionEnabled(`polls`))throw Error(`Discord polls are disabled.`);let to=readStringParam(params,`to`,{required:!0}),content=readStringParam(params,`content`),question=readStringParam(params,`question`,{required:!0}),answers=readStringArrayParam(params,`answers`,{required:!0,label:`answers`}),allowMultiselectRaw=params.allowMultiselect,allowMultiselect=typeof allowMultiselectRaw==`boolean`?allowMultiselectRaw:void 0,durationRaw=params.durationHours,durationHours=typeof durationRaw==`number`&&Number.isFinite(durationRaw)?durationRaw:void 0;return await sendPollDiscord(to,{question,options:answers,maxSelections:allowMultiselect?Math.max(2,answers.length):1,durationHours},{...accountId?{accountId}:{},content}),jsonResult({ok:!0})}case`permissions`:{if(!isActionEnabled(`permissions`))throw Error(`Discord permissions are disabled.`);let channelId=resolveChannelId();return jsonResult({ok:!0,permissions:accountId?await fetchChannelPermissionsDiscord(channelId,{accountId}):await fetchChannelPermissionsDiscord(channelId)})}case`fetchMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message reads are disabled.`);let messageLink=readStringParam(params,`messageLink`),guildId=readStringParam(params,`guildId`),channelId=readStringParam(params,`channelId`),messageId=readStringParam(params,`messageId`);if(messageLink){let parsed=parseDiscordMessageLink(messageLink);guildId=parsed.guildId,channelId=parsed.channelId,messageId=parsed.messageId}if(!guildId||!channelId||!messageId)throw Error(`Discord message fetch requires guildId, channelId, and messageId (or a valid messageLink).`);return jsonResult({ok:!0,message:normalizeMessage(accountId?await fetchMessageDiscord(channelId,messageId,{accountId}):await fetchMessageDiscord(channelId,messageId)),guildId,channelId,messageId})}case`readMessages`:{if(!isActionEnabled(`messages`))throw Error(`Discord message reads are disabled.`);let channelId=resolveChannelId(),query={limit:typeof params.limit==`number`&&Number.isFinite(params.limit)?params.limit:void 0,before:readStringParam(params,`before`),after:readStringParam(params,`after`),around:readStringParam(params,`around`)};return jsonResult({ok:!0,messages:(accountId?await readMessagesDiscord(channelId,query,{accountId}):await readMessagesDiscord(channelId,query)).map(message=>normalizeMessage(message))})}case`sendMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message sends are disabled.`);let to=readStringParam(params,`to`,{required:!0}),asVoice=params.asVoice===!0,silent=params.silent===!0,rawComponents=params.components,componentSpec=rawComponents&&typeof rawComponents==`object`&&!Array.isArray(rawComponents)?readDiscordComponentSpec(rawComponents):null,components=Array.isArray(rawComponents)||typeof rawComponents==`function`?rawComponents:void 0,content=readStringParam(params,`content`,{required:!asVoice&&!componentSpec&&!components,allowEmpty:!0}),mediaUrl=readStringParam(params,`mediaUrl`,{trim:!1})??readStringParam(params,`path`,{trim:!1})??readStringParam(params,`filePath`,{trim:!1}),filename=readStringParam(params,`filename`),replyTo=readStringParam(params,`replyTo`),rawEmbeds=params.embeds,embeds=Array.isArray(rawEmbeds)?rawEmbeds:void 0,sessionKey=readStringParam(params,`__sessionKey`),agentId=readStringParam(params,`__agentId`);if(componentSpec){if(asVoice)throw Error(`Discord components cannot be sent as voice messages.`);if(embeds?.length)throw Error(`Discord components cannot include embeds.`);let normalizedContent=content?.trim()?content:void 0;return jsonResult({ok:!0,result:await sendDiscordComponentMessage(to,componentSpec.text?componentSpec:{...componentSpec,text:normalizedContent},{...accountId?{accountId}:{},silent,replyTo:replyTo??void 0,sessionKey:sessionKey??void 0,agentId:agentId??void 0,mediaUrl:mediaUrl??void 0,filename:filename??void 0}),components:!0})}if(asVoice){if(!mediaUrl)throw Error(`Voice messages require a media file reference (mediaUrl, path, or filePath).`);if(content&&content.trim())throw Error(`Voice messages cannot include text content (Discord limitation). Remove the content parameter.`);return assertMediaNotDataUrl(mediaUrl),jsonResult({ok:!0,result:await sendVoiceMessageDiscord(to,mediaUrl,{...accountId?{accountId}:{},replyTo,silent}),voiceMessage:!0})}return jsonResult({ok:!0,result:await sendMessageDiscord(to,content??``,{...accountId?{accountId}:{},mediaUrl,replyTo,components,embeds,silent})})}case`editMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message edits are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0}),content=readStringParam(params,`content`,{required:!0});return jsonResult({ok:!0,message:accountId?await editMessageDiscord(channelId,messageId,{content},{accountId}):await editMessageDiscord(channelId,messageId,{content})})}case`deleteMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message deletes are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0});return accountId?await deleteMessageDiscord(channelId,messageId,{accountId}):await deleteMessageDiscord(channelId,messageId),jsonResult({ok:!0})}case`threadCreate`:{if(!isActionEnabled(`threads`))throw Error(`Discord threads are disabled.`);let channelId=resolveChannelId(),name=readStringParam(params,`name`,{required:!0}),messageId=readStringParam(params,`messageId`),content=readStringParam(params,`content`),autoArchiveMinutesRaw=params.autoArchiveMinutes,autoArchiveMinutes=typeof autoArchiveMinutesRaw==`number`&&Number.isFinite(autoArchiveMinutesRaw)?autoArchiveMinutesRaw:void 0;return jsonResult({ok:!0,thread:accountId?await createThreadDiscord(channelId,{name,messageId,autoArchiveMinutes,content},{accountId}):await createThreadDiscord(channelId,{name,messageId,autoArchiveMinutes,content})})}case`threadList`:{if(!isActionEnabled(`threads`))throw Error(`Discord threads are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),channelId=readStringParam(params,`channelId`),includeArchived=typeof params.includeArchived==`boolean`?params.includeArchived:void 0,before=readStringParam(params,`before`),limit=typeof params.limit==`number`&&Number.isFinite(params.limit)?params.limit:void 0;return jsonResult({ok:!0,threads:accountId?await listThreadsDiscord({guildId,channelId,includeArchived,before,limit},{accountId}):await listThreadsDiscord({guildId,channelId,includeArchived,before,limit})})}case`threadReply`:{if(!isActionEnabled(`threads`))throw Error(`Discord threads are disabled.`);let channelId=resolveChannelId(),content=readStringParam(params,`content`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`),replyTo=readStringParam(params,`replyTo`);return jsonResult({ok:!0,result:await sendMessageDiscord(`channel:${channelId}`,content,{...accountId?{accountId}:{},mediaUrl,replyTo})})}case`pinMessage`:{if(!isActionEnabled(`pins`))throw Error(`Discord pins are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0});return accountId?await pinMessageDiscord(channelId,messageId,{accountId}):await pinMessageDiscord(channelId,messageId),jsonResult({ok:!0})}case`unpinMessage`:{if(!isActionEnabled(`pins`))throw Error(`Discord pins are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0});return accountId?await unpinMessageDiscord(channelId,messageId,{accountId}):await unpinMessageDiscord(channelId,messageId),jsonResult({ok:!0})}case`listPins`:{if(!isActionEnabled(`pins`))throw Error(`Discord pins are disabled.`);let channelId=resolveChannelId();return jsonResult({ok:!0,pins:(accountId?await listPinsDiscord(channelId,{accountId}):await listPinsDiscord(channelId)).map(pin=>normalizeMessage(pin))})}case`searchMessages`:{if(!isActionEnabled(`search`))throw Error(`Discord search is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),content=readStringParam(params,`content`,{required:!0}),channelId=readStringParam(params,`channelId`),channelIds=readStringArrayParam(params,`channelIds`),authorId=readStringParam(params,`authorId`),authorIds=readStringArrayParam(params,`authorIds`),limit=typeof params.limit==`number`&&Number.isFinite(params.limit)?params.limit:void 0,channelIdList=[...channelIds??[],...channelId?[channelId]:[]],authorIdList=[...authorIds??[],...authorId?[authorId]:[]],results=accountId?await searchMessagesDiscord({guildId,content,channelIds:channelIdList.length?channelIdList:void 0,authorIds:authorIdList.length?authorIdList:void 0,limit},{accountId}):await searchMessagesDiscord({guildId,content,channelIds:channelIdList.length?channelIdList:void 0,authorIds:authorIdList.length?authorIdList:void 0,limit});if(!results||typeof results!=`object`)return jsonResult({ok:!0,results});let resultsRecord=results,messages=resultsRecord.messages,normalizedMessages=Array.isArray(messages)?messages.map(group=>Array.isArray(group)?group.map(msg=>normalizeMessage(msg)):group):messages;return jsonResult({ok:!0,results:{...resultsRecord,messages:normalizedMessages}})}default:throw Error(`Unknown action: ${action}`)}}async function handleDiscordModerationAction(action,params,isActionEnabled){let accountId=readStringParam(params,`accountId`);switch(action){case`timeout`:{if(!isActionEnabled(`moderation`,!1))throw Error(`Discord moderation is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),durationMinutes=typeof params.durationMinutes==`number`&&Number.isFinite(params.durationMinutes)?params.durationMinutes:void 0,until=readStringParam(params,`until`),reason=readStringParam(params,`reason`);return jsonResult({ok:!0,member:accountId?await timeoutMemberDiscord({guildId,userId,durationMinutes,until,reason},{accountId}):await timeoutMemberDiscord({guildId,userId,durationMinutes,until,reason})})}case`kick`:{if(!isActionEnabled(`moderation`,!1))throw Error(`Discord moderation is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),reason=readStringParam(params,`reason`);return accountId?await kickMemberDiscord({guildId,userId,reason},{accountId}):await kickMemberDiscord({guildId,userId,reason}),jsonResult({ok:!0})}case`ban`:{if(!isActionEnabled(`moderation`,!1))throw Error(`Discord moderation is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),reason=readStringParam(params,`reason`),deleteMessageDays=typeof params.deleteMessageDays==`number`&&Number.isFinite(params.deleteMessageDays)?params.deleteMessageDays:void 0;return accountId?await banMemberDiscord({guildId,userId,reason,deleteMessageDays},{accountId}):await banMemberDiscord({guildId,userId,reason,deleteMessageDays}),jsonResult({ok:!0})}default:throw Error(`Unknown action: ${action}`)}}const gatewayRegistry=new Map;function resolveAccountKey(accountId){return accountId??`\0__default__`}function registerGateway(accountId,gateway){gatewayRegistry.set(resolveAccountKey(accountId),gateway)}function unregisterGateway(accountId){gatewayRegistry.delete(resolveAccountKey(accountId))}function getGateway(accountId){return gatewayRegistry.get(resolveAccountKey(accountId))}const ACTIVITY_TYPE_MAP={playing:0,streaming:1,listening:2,watching:3,custom:4,competing:5},VALID_STATUSES=new Set([`online`,`dnd`,`idle`,`invisible`]);async function handleDiscordPresenceAction(action,params,isActionEnabled){if(action!==`setPresence`)throw Error(`Unknown presence action: ${action}`);if(!isActionEnabled(`presence`,!1))throw Error(`Discord presence changes are disabled.`);let accountId=readStringParam(params,`accountId`),gateway=getGateway(accountId);if(!gateway)throw Error(`Discord gateway not available${accountId?` for account "${accountId}"`:``}. The bot may not be connected.`);if(!gateway.isConnected)throw Error(`Discord gateway is not connected${accountId?` for account "${accountId}"`:``}.`);let statusRaw=readStringParam(params,`status`)??`online`;if(!VALID_STATUSES.has(statusRaw))throw Error(`Invalid status "${statusRaw}". Must be one of: ${[...VALID_STATUSES].join(`, `)}`);let status=statusRaw,activityTypeRaw=readStringParam(params,`activityType`),activityName=readStringParam(params,`activityName`),activities=[];if(activityTypeRaw||activityName){if(!activityTypeRaw)throw Error(`activityType is required when activityName is provided. Valid types: ${Object.keys(ACTIVITY_TYPE_MAP).join(`, `)}`);let typeNum=ACTIVITY_TYPE_MAP[activityTypeRaw.toLowerCase()];if(typeNum===void 0)throw Error(`Invalid activityType "${activityTypeRaw}". Must be one of: ${Object.keys(ACTIVITY_TYPE_MAP).join(`, `)}`);let activity={name:activityName??``,type:typeNum};if(typeNum===1){let url=readStringParam(params,`activityUrl`);url&&(activity.url=url)}let state=readStringParam(params,`activityState`);state&&(activity.state=state),activities.push(activity)}let presenceData={since:null,activities,status,afk:!1};return gateway.updatePresence(presenceData),jsonResult({ok:!0,status,activities:activities.map(a=>({type:a.type,name:a.name,...a.url?{url:a.url}:{},...a.state?{state:a.state}:{}}))})}const messagingActions=new Set([`react`,`reactions`,`sticker`,`poll`,`permissions`,`fetchMessage`,`readMessages`,`sendMessage`,`editMessage`,`deleteMessage`,`threadCreate`,`threadList`,`threadReply`,`pinMessage`,`unpinMessage`,`listPins`,`searchMessages`]),guildActions=new Set([`memberInfo`,`roleInfo`,`emojiList`,`emojiUpload`,`stickerUpload`,`roleAdd`,`roleRemove`,`channelInfo`,`channelList`,`voiceStatus`,`eventList`,`eventCreate`,`channelCreate`,`channelEdit`,`channelDelete`,`channelMove`,`categoryCreate`,`categoryEdit`,`categoryDelete`,`channelPermissionSet`,`channelPermissionRemove`]),moderationActions=new Set([`timeout`,`kick`,`ban`]),presenceActions=new Set([`setPresence`]);async function handleDiscordAction(params,cfg){let action=readStringParam(params,`action`,{required:!0}),isActionEnabled=createDiscordActionGate({cfg,accountId:readStringParam(params,`accountId`)});if(messagingActions.has(action))return await handleDiscordMessagingAction(action,params,isActionEnabled);if(guildActions.has(action))return await handleDiscordGuildAction(action,params,isActionEnabled);if(moderationActions.has(action))return await handleDiscordModerationAction(action,params,isActionEnabled);if(presenceActions.has(action))return await handleDiscordPresenceAction(action,params,isActionEnabled);throw Error(`Unknown action: ${action}`)}async function tryHandleDiscordMessageActionGuildAdmin(params){let{ctx,resolveChannelId,readParentIdParam}=params,{action,params:actionParams,cfg}=ctx,accountId=ctx.accountId??readStringParam(actionParams,`accountId`);if(action===`member-info`){let userId=readStringParam(actionParams,`userId`,{required:!0}),guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`memberInfo`,accountId:accountId??void 0,guildId,userId},cfg)}if(action===`role-info`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`roleInfo`,accountId:accountId??void 0,guildId},cfg)}if(action===`emoji-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`emojiList`,accountId:accountId??void 0,guildId},cfg)}if(action===`emoji-upload`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`emojiName`,{required:!0}),mediaUrl=readStringParam(actionParams,`media`,{required:!0,trim:!1}),roleIds=readStringArrayParam(actionParams,`roleIds`);return await handleDiscordAction({action:`emojiUpload`,accountId:accountId??void 0,guildId,name,mediaUrl,roleIds},cfg)}if(action===`sticker-upload`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`stickerName`,{required:!0}),description=readStringParam(actionParams,`stickerDesc`,{required:!0}),tags=readStringParam(actionParams,`stickerTags`,{required:!0}),mediaUrl=readStringParam(actionParams,`media`,{required:!0,trim:!1});return await handleDiscordAction({action:`stickerUpload`,accountId:accountId??void 0,guildId,name,description,tags,mediaUrl},cfg)}if(action===`role-add`||action===`role-remove`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),userId=readStringParam(actionParams,`userId`,{required:!0}),roleId=readStringParam(actionParams,`roleId`,{required:!0});return await handleDiscordAction({action:action===`role-add`?`roleAdd`:`roleRemove`,accountId:accountId??void 0,guildId,userId,roleId},cfg)}if(action===`channel-info`){let channelId=readStringParam(actionParams,`channelId`,{required:!0});return await handleDiscordAction({action:`channelInfo`,accountId:accountId??void 0,channelId},cfg)}if(action===`channel-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`channelList`,accountId:accountId??void 0,guildId},cfg)}if(action===`channel-create`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`name`,{required:!0}),type=readNumberParam(actionParams,`type`,{integer:!0}),parentId=readParentIdParam(actionParams),topic=readStringParam(actionParams,`topic`),position=readNumberParam(actionParams,`position`,{integer:!0}),nsfw=typeof actionParams.nsfw==`boolean`?actionParams.nsfw:void 0;return await handleDiscordAction({action:`channelCreate`,accountId:accountId??void 0,guildId,name,type:type??void 0,parentId:parentId??void 0,topic:topic??void 0,position:position??void 0,nsfw},cfg)}if(action===`channel-edit`){let channelId=readStringParam(actionParams,`channelId`,{required:!0}),name=readStringParam(actionParams,`name`),topic=readStringParam(actionParams,`topic`),position=readNumberParam(actionParams,`position`,{integer:!0}),parentId=readParentIdParam(actionParams),nsfw=typeof actionParams.nsfw==`boolean`?actionParams.nsfw:void 0,rateLimitPerUser=readNumberParam(actionParams,`rateLimitPerUser`,{integer:!0}),archived=typeof actionParams.archived==`boolean`?actionParams.archived:void 0,locked=typeof actionParams.locked==`boolean`?actionParams.locked:void 0,autoArchiveDuration=readNumberParam(actionParams,`autoArchiveDuration`,{integer:!0});return await handleDiscordAction({action:`channelEdit`,accountId:accountId??void 0,channelId,name:name??void 0,topic:topic??void 0,position:position??void 0,parentId:parentId===void 0?void 0:parentId,nsfw,rateLimitPerUser:rateLimitPerUser??void 0,archived,locked,autoArchiveDuration:autoArchiveDuration??void 0},cfg)}if(action===`channel-delete`){let channelId=readStringParam(actionParams,`channelId`,{required:!0});return await handleDiscordAction({action:`channelDelete`,accountId:accountId??void 0,channelId},cfg)}if(action===`channel-move`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),channelId=readStringParam(actionParams,`channelId`,{required:!0}),parentId=readParentIdParam(actionParams),position=readNumberParam(actionParams,`position`,{integer:!0});return await handleDiscordAction({action:`channelMove`,accountId:accountId??void 0,guildId,channelId,parentId:parentId===void 0?void 0:parentId,position:position??void 0},cfg)}if(action===`category-create`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`name`,{required:!0}),position=readNumberParam(actionParams,`position`,{integer:!0});return await handleDiscordAction({action:`categoryCreate`,accountId:accountId??void 0,guildId,name,position:position??void 0},cfg)}if(action===`category-edit`){let categoryId=readStringParam(actionParams,`categoryId`,{required:!0}),name=readStringParam(actionParams,`name`),position=readNumberParam(actionParams,`position`,{integer:!0});return await handleDiscordAction({action:`categoryEdit`,accountId:accountId??void 0,categoryId,name:name??void 0,position:position??void 0},cfg)}if(action===`category-delete`){let categoryId=readStringParam(actionParams,`categoryId`,{required:!0});return await handleDiscordAction({action:`categoryDelete`,accountId:accountId??void 0,categoryId},cfg)}if(action===`voice-status`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),userId=readStringParam(actionParams,`userId`,{required:!0});return await handleDiscordAction({action:`voiceStatus`,accountId:accountId??void 0,guildId,userId},cfg)}if(action===`event-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`eventList`,accountId:accountId??void 0,guildId},cfg)}if(action===`event-create`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`eventName`,{required:!0}),startTime=readStringParam(actionParams,`startTime`,{required:!0}),endTime=readStringParam(actionParams,`endTime`),description=readStringParam(actionParams,`desc`),channelId=readStringParam(actionParams,`channelId`),location=readStringParam(actionParams,`location`),entityType=readStringParam(actionParams,`eventType`);return await handleDiscordAction({action:`eventCreate`,accountId:accountId??void 0,guildId,name,startTime,endTime,description,channelId,location,entityType},cfg)}if(action===`timeout`||action===`kick`||action===`ban`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),userId=readStringParam(actionParams,`userId`,{required:!0}),durationMinutes=readNumberParam(actionParams,`durationMin`,{integer:!0}),until=readStringParam(actionParams,`until`),reason=readStringParam(actionParams,`reason`),deleteMessageDays=readNumberParam(actionParams,`deleteDays`,{integer:!0});return await handleDiscordAction({action,accountId:accountId??void 0,guildId,userId,durationMinutes,until,reason,deleteMessageDays},cfg)}if(action===`thread-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),channelId=readStringParam(actionParams,`channelId`),includeArchived=typeof actionParams.includeArchived==`boolean`?actionParams.includeArchived:void 0,before=readStringParam(actionParams,`before`),limit=readNumberParam(actionParams,`limit`,{integer:!0});return await handleDiscordAction({action:`threadList`,accountId:accountId??void 0,guildId,channelId,includeArchived,before,limit},cfg)}if(action===`thread-reply`){let content=readStringParam(actionParams,`message`,{required:!0}),mediaUrl=readStringParam(actionParams,`media`,{trim:!1}),replyTo=readStringParam(actionParams,`replyTo`),channelId=readStringParam(actionParams,`threadId`)??resolveChannelId();return await handleDiscordAction({action:`threadReply`,accountId:accountId??void 0,channelId,content,mediaUrl:mediaUrl??void 0,replyTo:replyTo??void 0},cfg)}if(action===`search`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),query=readStringParam(actionParams,`query`,{required:!0});return await handleDiscordAction({action:`searchMessages`,accountId:accountId??void 0,guildId,content:query,channelId:readStringParam(actionParams,`channelId`),channelIds:readStringArrayParam(actionParams,`channelIds`),authorId:readStringParam(actionParams,`authorId`),authorIds:readStringArrayParam(actionParams,`authorIds`),limit:readNumberParam(actionParams,`limit`,{integer:!0})},cfg)}}function readParentIdParam(params){return params.clearParent===!0||params.parentId===null?null:readStringParam(params,`parentId`)}async function handleDiscordMessageAction(ctx){let{action,params,cfg}=ctx,accountId=ctx.accountId??readStringParam(params,`accountId`),resolveChannelId=()=>resolveDiscordChannelId(readStringParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}));if(action===`send`){let to=readStringParam(params,`to`,{required:!0}),asVoice=params.asVoice===!0,rawComponents=params.components,hasComponents=!!rawComponents&&(typeof rawComponents==`function`||typeof rawComponents==`object`),components=hasComponents?rawComponents:void 0,content=readStringParam(params,`message`,{required:!asVoice&&!hasComponents,allowEmpty:!0}),mediaUrl=readStringParam(params,`media`,{trim:!1})??readStringParam(params,`path`,{trim:!1})??readStringParam(params,`filePath`,{trim:!1}),filename=readStringParam(params,`filename`),replyTo=readStringParam(params,`replyTo`),rawEmbeds=params.embeds,embeds=Array.isArray(rawEmbeds)?rawEmbeds:void 0,silent=params.silent===!0,sessionKey=readStringParam(params,`__sessionKey`),agentId=readStringParam(params,`__agentId`);return await handleDiscordAction({action:`sendMessage`,accountId:accountId??void 0,to,content,mediaUrl:mediaUrl??void 0,filename:filename??void 0,replyTo:replyTo??void 0,components,embeds,asVoice,silent,__sessionKey:sessionKey??void 0,__agentId:agentId??void 0},cfg)}if(action===`poll`){let to=readStringParam(params,`to`,{required:!0}),question=readStringParam(params,`pollQuestion`,{required:!0}),answers=readStringArrayParam(params,`pollOption`,{required:!0})??[],allowMultiselect=typeof params.pollMulti==`boolean`?params.pollMulti:void 0,durationHours=readNumberParam(params,`pollDurationHours`,{integer:!0});return await handleDiscordAction({action:`poll`,accountId:accountId??void 0,to,question,answers,allowMultiselect,durationHours:durationHours??void 0,content:readStringParam(params,`message`)},cfg)}if(action===`react`){let messageId=readStringParam(params,`messageId`,{required:!0}),emoji=readStringParam(params,`emoji`,{allowEmpty:!0}),remove=typeof params.remove==`boolean`?params.remove:void 0;return await handleDiscordAction({action:`react`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId,emoji,remove},cfg)}if(action===`reactions`){let messageId=readStringParam(params,`messageId`,{required:!0}),limit=readNumberParam(params,`limit`,{integer:!0});return await handleDiscordAction({action:`reactions`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId,limit},cfg)}if(action===`read`){let limit=readNumberParam(params,`limit`,{integer:!0});return await handleDiscordAction({action:`readMessages`,accountId:accountId??void 0,channelId:resolveChannelId(),limit,before:readStringParam(params,`before`),after:readStringParam(params,`after`),around:readStringParam(params,`around`)},cfg)}if(action===`edit`){let messageId=readStringParam(params,`messageId`,{required:!0}),content=readStringParam(params,`message`,{required:!0});return await handleDiscordAction({action:`editMessage`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId,content},cfg)}if(action===`delete`){let messageId=readStringParam(params,`messageId`,{required:!0});return await handleDiscordAction({action:`deleteMessage`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId},cfg)}if(action===`pin`||action===`unpin`||action===`list-pins`){let messageId=action===`list-pins`?void 0:readStringParam(params,`messageId`,{required:!0});return await handleDiscordAction({action:action===`pin`?`pinMessage`:action===`unpin`?`unpinMessage`:`listPins`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId},cfg)}if(action===`permissions`)return await handleDiscordAction({action:`permissions`,accountId:accountId??void 0,channelId:resolveChannelId()},cfg);if(action===`thread-create`){let name=readStringParam(params,`threadName`,{required:!0}),messageId=readStringParam(params,`messageId`),content=readStringParam(params,`message`),autoArchiveMinutes=readNumberParam(params,`autoArchiveMin`,{integer:!0});return await handleDiscordAction({action:`threadCreate`,accountId:accountId??void 0,channelId:resolveChannelId(),name,messageId,content,autoArchiveMinutes},cfg)}if(action===`sticker`){let stickerIds=readStringArrayParam(params,`stickerId`,{required:!0,label:`sticker-id`})??[];return await handleDiscordAction({action:`sticker`,accountId:accountId??void 0,to:readStringParam(params,`to`,{required:!0}),stickerIds,content:readStringParam(params,`message`)},cfg)}if(action===`set-presence`)return await handleDiscordAction({action:`setPresence`,accountId:accountId??void 0,status:readStringParam(params,`status`),activityType:readStringParam(params,`activityType`),activityName:readStringParam(params,`activityName`),activityUrl:readStringParam(params,`activityUrl`),activityState:readStringParam(params,`activityState`)},cfg);let adminResult=await tryHandleDiscordMessageActionGuildAdmin({ctx,resolveChannelId,readParentIdParam});if(adminResult!==void 0)return adminResult;throw Error(`Action ${String(action)} is not supported for provider discord.`)}const discordMessageActions={listActions:({cfg})=>{let accounts=listEnabledDiscordAccounts(cfg).filter(account=>account.tokenSource!==`none`);if(accounts.length===0)return[];let gates=accounts.map(account=>createDiscordActionGate({cfg,accountId:account.accountId})),gate=(key,defaultValue=!0)=>gates.some(g=>g(key,defaultValue)),actions=new Set([`send`]);return gate(`polls`)&&actions.add(`poll`),gate(`reactions`)&&(actions.add(`react`),actions.add(`reactions`)),gate(`messages`)&&(actions.add(`read`),actions.add(`edit`),actions.add(`delete`)),gate(`pins`)&&(actions.add(`pin`),actions.add(`unpin`),actions.add(`list-pins`)),gate(`permissions`)&&actions.add(`permissions`),gate(`threads`)&&(actions.add(`thread-create`),actions.add(`thread-list`),actions.add(`thread-reply`)),gate(`search`)&&actions.add(`search`),gate(`stickers`)&&actions.add(`sticker`),gate(`memberInfo`)&&actions.add(`member-info`),gate(`roleInfo`)&&actions.add(`role-info`),gate(`reactions`)&&actions.add(`emoji-list`),gate(`emojiUploads`)&&actions.add(`emoji-upload`),gate(`stickerUploads`)&&actions.add(`sticker-upload`),gate(`roles`,!1)&&(actions.add(`role-add`),actions.add(`role-remove`)),gate(`channelInfo`)&&(actions.add(`channel-info`),actions.add(`channel-list`)),gate(`channels`)&&(actions.add(`channel-create`),actions.add(`channel-edit`),actions.add(`channel-delete`),actions.add(`channel-move`),actions.add(`category-create`),actions.add(`category-edit`),actions.add(`category-delete`)),gate(`voiceStatus`)&&actions.add(`voice-status`),gate(`events`)&&(actions.add(`event-list`),actions.add(`event-create`)),gate(`moderation`,!1)&&(actions.add(`timeout`),actions.add(`kick`),actions.add(`ban`)),gate(`presence`,!1)&&actions.add(`set-presence`),Array.from(actions)},extractToolSend:({args})=>{let action=typeof args.action==`string`?args.action.trim():``;if(action===`sendMessage`){let to=typeof args.to==`string`?args.to:void 0;return to?{to}:null}if(action===`threadReply`){let channelId=typeof args.channelId==`string`?args.channelId.trim():``;return channelId?{to:`channel:${channelId}`}:null}return null},handleAction:async({action,params,cfg,accountId})=>await handleDiscordMessageAction({action,params,cfg,accountId})};function normalizeSignalId(raw){let trimmed=raw.trim();return trimmed?trimmed.replace(/^signal:/i,``).trim():``}function normalizeSignalUuid(raw){let trimmed=normalizeSignalId(raw);return trimmed?trimmed.toLowerCase().startsWith(`uuid:`)?trimmed.slice(5).trim():trimmed:``}function resolveTargetAuthorParams(params){let candidates=[params.targetAuthor,params.targetAuthorUuid,params.fallback];for(let candidate of candidates){let raw=candidate?.trim();if(!raw)continue;let normalized=normalizeSignalUuid(raw);if(normalized)return{targetAuthor:normalized}}return{}}async function sendReactionSignalCore(params){let accountInfo=resolveSignalAccount({cfg:loadConfig(),accountId:params.opts.accountId}),{baseUrl,account}=resolveSignalRpcContext(params.opts,accountInfo),normalizedRecipient=normalizeSignalUuid(params.recipient),groupId=params.opts.groupId?.trim();if(!normalizedRecipient&&!groupId)throw Error(params.errors.missingRecipient);if(!Number.isFinite(params.targetTimestamp)||params.targetTimestamp<=0)throw Error(params.errors.invalidTargetTimestamp);let normalizedEmoji=params.emoji?.trim();if(!normalizedEmoji)throw Error(params.errors.missingEmoji);let targetAuthorParams=resolveTargetAuthorParams({targetAuthor:params.opts.targetAuthor,targetAuthorUuid:params.opts.targetAuthorUuid,fallback:normalizedRecipient});if(groupId&&!targetAuthorParams.targetAuthor)throw Error(params.errors.missingTargetAuthor);let requestParams={emoji:normalizedEmoji,targetTimestamp:params.targetTimestamp,...params.remove?{remove:!0}:{},...targetAuthorParams};return normalizedRecipient&&(requestParams.recipients=[normalizedRecipient]),groupId&&(requestParams.groupIds=[groupId]),account&&(requestParams.account=account),{ok:!0,timestamp:(await signalRpcRequest(`sendReaction`,requestParams,{baseUrl,timeoutMs:params.opts.timeoutMs}))?.timestamp}}async function sendReactionSignal(recipient,targetTimestamp,emoji,opts={}){return await sendReactionSignalCore({recipient,targetTimestamp,emoji,remove:!1,opts,errors:{missingRecipient:`Recipient or groupId is required for Signal reaction`,invalidTargetTimestamp:`Valid targetTimestamp is required for Signal reaction`,missingEmoji:`Emoji is required for Signal reaction`,missingTargetAuthor:`targetAuthor is required for group reactions`}})}async function removeReactionSignal(recipient,targetTimestamp,emoji,opts={}){return await sendReactionSignalCore({recipient,targetTimestamp,emoji,remove:!0,opts,errors:{missingRecipient:`Recipient or groupId is required for Signal reaction removal`,invalidTargetTimestamp:`Valid targetTimestamp is required for Signal reaction removal`,missingEmoji:`Emoji is required for Signal reaction removal`,missingTargetAuthor:`targetAuthor is required for group reaction removal`}})}function normalizeSignalReactionRecipient(raw){let trimmed=raw.trim();if(!trimmed)return trimmed;let withoutSignal=trimmed.replace(/^signal:/i,``).trim();return withoutSignal&&(withoutSignal.toLowerCase().startsWith(`uuid:`)?withoutSignal.slice(5).trim():withoutSignal)}function resolveSignalReactionTarget(raw){let trimmed=raw.trim();if(!trimmed)return{};let withoutSignal=trimmed.replace(/^signal:/i,``).trim();if(!withoutSignal)return{};if(withoutSignal.toLowerCase().startsWith(`group:`)){let groupId=withoutSignal.slice(6).trim();return groupId?{groupId}:{}}return{recipient:normalizeSignalReactionRecipient(withoutSignal)}}const signalMessageActions={listActions:({cfg})=>{let accounts=listEnabledSignalAccounts(cfg);if(accounts.length===0)return[];let configuredAccounts=accounts.filter(account=>account.configured);if(configuredAccounts.length===0)return[];let actions=new Set([`send`]);return configuredAccounts.some(account=>createActionGate(account.config.actions)(`reactions`))&&actions.add(`react`),Array.from(actions)},supportsAction:({action})=>action!==`send`,handleAction:async({action,params,cfg,accountId})=>{if(action===`send`)throw Error(`Send should be handled by outbound, not actions handler.`);if(action===`react`){let reactionLevelInfo=resolveSignalReactionLevel({cfg,accountId:accountId??void 0});if(!reactionLevelInfo.agentReactionsEnabled)throw Error(`Signal agent reactions disabled (reactionLevel="${reactionLevelInfo.level}"). Set channels.signal.reactionLevel to "minimal" or "extensive" to enable.`);let actionConfig=resolveSignalAccount({cfg,accountId}).config.actions;if(!createActionGate(actionConfig)(`reactions`))throw Error(`Signal reactions are disabled via actions.reactions.`);let target=resolveSignalReactionTarget(readStringParam(params,`recipient`)??readStringParam(params,`to`,{required:!0,label:`recipient (UUID, phone number, or group)`}));if(!target.recipient&&!target.groupId)throw Error(`recipient or group required`);let messageId=readStringParam(params,`messageId`,{required:!0,label:`messageId (timestamp)`}),targetAuthor=readStringParam(params,`targetAuthor`),targetAuthorUuid=readStringParam(params,`targetAuthorUuid`);if(target.groupId&&!targetAuthor&&!targetAuthorUuid)throw Error(`targetAuthor or targetAuthorUuid required for group reactions.`);let emoji=readStringParam(params,`emoji`,{allowEmpty:!0}),remove=typeof params.remove==`boolean`?params.remove:void 0,timestamp=parseInt(messageId,10);if(!Number.isFinite(timestamp))throw Error(`Invalid messageId: ${messageId}. Expected numeric timestamp.`);if(remove){if(!emoji)throw Error(`Emoji required to remove reaction.`);return await removeReactionSignal(target.recipient??``,timestamp,emoji,{accountId:accountId??void 0,groupId:target.groupId,targetAuthor,targetAuthorUuid}),jsonResult({ok:!0,removed:emoji})}if(!emoji)throw Error(`Emoji required to add reaction.`);return await sendReactionSignal(target.recipient??``,timestamp,emoji,{accountId:accountId??void 0,groupId:target.groupId,targetAuthor,targetAuthorUuid}),jsonResult({ok:!0,added:emoji})}throw Error(`Action ${action} not supported for signal.`)}},CACHE_FILE=path.join(STATE_DIR,`telegram`,`sticker-cache.json`);async function loadCache(){let data=await loadJsonFile(CACHE_FILE);if(!data||typeof data!=`object`)return{version:1,stickers:{}};let cache=data;return cache.version===1?cache:{version:1,stickers:{}}}async function saveCache(cache){await saveJsonFile(CACHE_FILE,cache)}async function getCachedSticker(fileUniqueId){return(await loadCache()).stickers[fileUniqueId]??null}async function cacheSticker(sticker){let cache=await loadCache();cache.stickers[sticker.fileUniqueId]=sticker,await saveCache(cache)}async function searchStickers(query,limit=10){let cache=await loadCache(),queryLower=query.toLowerCase(),results=[];for(let sticker of Object.values(cache.stickers)){let score=0,descLower=sticker.description.toLowerCase();descLower.includes(queryLower)&&(score+=10);let queryWords=queryLower.split(/\s+/).filter(Boolean),descWords=descLower.split(/\s+/);for(let qWord of queryWords)descWords.some(dWord=>dWord.includes(qWord))&&(score+=5);sticker.emoji&&query.includes(sticker.emoji)&&(score+=8),sticker.setName?.toLowerCase().includes(queryLower)&&(score+=3),score>0&&results.push({sticker,score})}return results.toSorted((a,b)=>b.score-a.score).slice(0,limit).map(r=>r.sticker)}async function getCacheStats(){let cache=await loadCache(),stickers=Object.values(cache.stickers);if(stickers.length===0)return{count:0};let sorted=[...stickers].toSorted((a,b)=>new Date(a.cachedAt).getTime()-new Date(b.cachedAt).getTime());return{count:stickers.length,oldestAt:sorted[0]?.cachedAt,newestAt:sorted[sorted.length-1]?.cachedAt}}const VISION_PROVIDERS=[`openai`,`anthropic`,`google`,`minimax`];async function describeStickerImage(params){let{imagePath,cfg,agentDir,agentId}=params,defaultModel=resolveDefaultModelForAgent({cfg,agentId}),activeModel,catalog=[];try{catalog=await loadModelCatalog({config:cfg}),modelSupportsVision(findModelInCatalog(catalog,defaultModel.provider,defaultModel.model))&&(activeModel={provider:defaultModel.provider,model:defaultModel.model})}catch{}let hasProviderKey=async provider=>{try{return await resolveApiKeyForProvider({provider,cfg,agentDir}),!0}catch{return!1}},selectCatalogModel=provider=>{let entries=catalog.filter(entry=>entry.provider.toLowerCase()===provider.toLowerCase()&&modelSupportsVision(entry));if(entries.length===0)return;let defaultId=provider===`openai`?`gpt-5-mini`:provider===`anthropic`?`claude-opus-4-6`:provider===`google`?`gemini-3-flash-preview`:`MiniMax-VL-01`;return entries.find(entry=>entry.id===defaultId)??entries[0]},resolved=null;if(activeModel&&VISION_PROVIDERS.includes(activeModel.provider)&&await hasProviderKey(activeModel.provider)&&(resolved=activeModel),!resolved)for(let provider of VISION_PROVIDERS){if(!await hasProviderKey(provider))continue;let entry=selectCatalogModel(provider);if(entry){resolved={provider,model:entry.id};break}}if(resolved||=await resolveAutoImageModel({cfg,agentDir,activeModel}),!resolved?.model)return logVerbose(`telegram: no vision provider available for sticker description`),null;let{provider,model}=resolved;logVerbose(`telegram: describing sticker with ${provider}/${model}`);try{return(await describeImageWithModel({buffer:await fs$1.readFile(imagePath),fileName:`sticker.webp`,mime:`image/webp`,prompt:`Describe this sticker image in 1-2 sentences. Focus on what the sticker depicts (character, object, action, emotion). Be concise and objective.`,cfg,agentDir:agentDir??``,provider,model,maxTokens:150,timeoutMs:3e4})).text}catch(err){return logVerbose(`telegram: failed to describe sticker: ${String(err)}`),null}}const TELEGRAM_BUTTON_STYLES=[`danger`,`success`,`primary`];function readTelegramButtons(params){let raw=params.buttons;if(raw==null)return;if(!Array.isArray(raw))throw Error(`buttons must be an array of button rows`);let filtered=raw.map((row,rowIndex)=>{if(!Array.isArray(row))throw Error(`buttons[${rowIndex}] must be an array`);return row.map((button,buttonIndex)=>{if(!button||typeof button!=`object`)throw Error(`buttons[${rowIndex}][${buttonIndex}] must be an object`);let text=typeof button.text==`string`?button.text.trim():``,callbackData=typeof button.callback_data==`string`?button.callback_data.trim():``;if(!text||!callbackData)throw Error(`buttons[${rowIndex}][${buttonIndex}] requires text and callback_data`);if(callbackData.length>64)throw Error(`buttons[${rowIndex}][${buttonIndex}] callback_data too long (max 64 chars)`);let styleRaw=button.style,style=typeof styleRaw==`string`?styleRaw.trim().toLowerCase():void 0;if(styleRaw!==void 0&&!style)throw Error(`buttons[${rowIndex}][${buttonIndex}] style must be string`);if(style&&!TELEGRAM_BUTTON_STYLES.includes(style))throw Error(`buttons[${rowIndex}][${buttonIndex}] style must be one of ${TELEGRAM_BUTTON_STYLES.join(`, `)}`);return{text,callback_data:callbackData,...style?{style}:{}}})}).filter(row=>row.length>0);return filtered.length>0?filtered:void 0}async function handleTelegramAction(params,cfg){let action=readStringParam(params,`action`,{required:!0}),accountId=readStringParam(params,`accountId`),isActionEnabled=createTelegramActionGate({cfg,accountId});if(action===`react`){let reactionLevelInfo=resolveTelegramReactionLevel({cfg,accountId:accountId??void 0});if(!reactionLevelInfo.agentReactionsEnabled)throw Error(`Telegram agent reactions disabled (reactionLevel="${reactionLevelInfo.level}"). Set channels.telegram.reactionLevel to "minimal" or "extensive" to enable.`);if(!isActionEnabled(`reactions`))throw Error(`Telegram reactions are disabled via actions.reactions.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),{emoji,remove,isEmpty}=readReactionParams(params,{removeErrorMessage:`Emoji is required to remove a Telegram reaction.`}),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let reactionResult=await reactMessageTelegram(chatId??``,messageId??0,emoji??``,{token,remove,accountId:accountId??void 0});return reactionResult.ok?jsonResult(!remove&&!isEmpty?{ok:!0,added:emoji}:{ok:!0,removed:!0}):jsonResult({ok:!1,warning:reactionResult.warning,...remove||isEmpty?{removed:!0}:{added:emoji}})}if(action===`sendMessage`){if(!isActionEnabled(`sendMessage`))throw Error(`Telegram sendMessage is disabled.`);let to=readStringParam(params,`to`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`),content=readStringParam(params,`content`,{required:!mediaUrl,allowEmpty:!0})??``,buttons=readTelegramButtons(params);if(buttons){let inlineButtonsScope=resolveTelegramInlineButtonsScope({cfg,accountId:accountId??void 0});if(inlineButtonsScope===`off`)throw Error(`Telegram inline buttons are disabled. Set channels.telegram.capabilities.inlineButtons to "dm", "group", "all", or "allowlist".`);if(inlineButtonsScope===`dm`||inlineButtonsScope===`group`){let targetType=resolveTelegramTargetChatType(to);if(targetType===`unknown`)throw Error(`Telegram inline buttons require a numeric chat id when inlineButtons="${inlineButtonsScope}".`);if(inlineButtonsScope===`dm`&&targetType!==`direct`)throw Error(`Telegram inline buttons are limited to DMs when inlineButtons="dm".`);if(inlineButtonsScope===`group`&&targetType!==`group`)throw Error(`Telegram inline buttons are limited to groups when inlineButtons="group".`)}}let replyToMessageId=readNumberParam(params,`replyToMessageId`,{integer:!0}),messageThreadId=readNumberParam(params,`messageThreadId`,{integer:!0}),quoteText=readStringParam(params,`quoteText`),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await sendMessageTelegram(to,content,{token,accountId:accountId??void 0,mediaUrl:mediaUrl||void 0,buttons,replyToMessageId:replyToMessageId??void 0,messageThreadId:messageThreadId??void 0,quoteText:quoteText??void 0,asVoice:typeof params.asVoice==`boolean`?params.asVoice:void 0,silent:typeof params.silent==`boolean`?params.silent:void 0});return jsonResult({ok:!0,messageId:result.messageId,chatId:result.chatId})}if(action===`deleteMessage`){if(!isActionEnabled(`deleteMessage`))throw Error(`Telegram deleteMessage is disabled.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);return await deleteMessageTelegram(chatId??``,messageId??0,{token,accountId:accountId??void 0}),jsonResult({ok:!0,deleted:!0})}if(action===`editMessage`){if(!isActionEnabled(`editMessage`))throw Error(`Telegram editMessage is disabled.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),content=readStringParam(params,`content`,{required:!0,allowEmpty:!1}),buttons=readTelegramButtons(params);if(buttons&&resolveTelegramInlineButtonsScope({cfg,accountId:accountId??void 0})===`off`)throw Error(`Telegram inline buttons are disabled. Set channels.telegram.capabilities.inlineButtons to "dm", "group", "all", or "allowlist".`);let token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await editMessageTelegram(chatId??``,messageId??0,content,{token,accountId:accountId??void 0,buttons});return jsonResult({ok:!0,messageId:result.messageId,chatId:result.chatId})}if(action===`sendSticker`){if(!isActionEnabled(`sticker`,!1))throw Error(`Telegram sticker actions are disabled. Set channels.telegram.actions.sticker to true.`);let to=readStringParam(params,`to`,{required:!0}),fileId=readStringParam(params,`fileId`,{required:!0}),replyToMessageId=readNumberParam(params,`replyToMessageId`,{integer:!0}),messageThreadId=readNumberParam(params,`messageThreadId`,{integer:!0}),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await sendStickerTelegram(to,fileId,{token,accountId:accountId??void 0,replyToMessageId:replyToMessageId??void 0,messageThreadId:messageThreadId??void 0});return jsonResult({ok:!0,messageId:result.messageId,chatId:result.chatId})}if(action===`searchSticker`){if(!isActionEnabled(`sticker`,!1))throw Error(`Telegram sticker actions are disabled. Set channels.telegram.actions.sticker to true.`);let results=await searchStickers(readStringParam(params,`query`,{required:!0}),readNumberParam(params,`limit`,{integer:!0})??5);return jsonResult({ok:!0,count:results.length,stickers:results.map(s=>({fileId:s.fileId,emoji:s.emoji,description:s.description,setName:s.setName}))})}if(action===`stickerCacheStats`)return jsonResult({ok:!0,...getCacheStats()});if(action===`createForumTopic`){if(!isActionEnabled(`createForumTopic`))throw Error(`Telegram createForumTopic is disabled.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),iconColor=readNumberParam(params,`iconColor`,{integer:!0}),iconCustomEmojiId=readStringParam(params,`iconCustomEmojiId`),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await createForumTopicTelegram(chatId??``,name,{token,accountId:accountId??void 0,iconColor:iconColor??void 0,iconCustomEmojiId:iconCustomEmojiId??void 0});return jsonResult({ok:!0,topicId:result.topicId,name:result.name,chatId:result.chatId})}throw Error(`Unsupported Telegram action: ${action}`)}function extractToolSend(args,expectedAction=`sendMessage`){if((typeof args.action==`string`?args.action.trim():``)!==expectedAction)return null;let to=typeof args.to==`string`?args.to:void 0;return to?{to,accountId:typeof args.accountId==`string`?args.accountId.trim():void 0}:null}function readTelegramSendParams(params){let to=readStringParam(params,`to`,{required:!0}),mediaUrl=readStringParam(params,`media`,{trim:!1}),message=readStringParam(params,`message`,{required:!mediaUrl,allowEmpty:!0}),caption=readStringParam(params,`caption`,{allowEmpty:!0}),content=message||caption||``,replyTo=readStringParam(params,`replyTo`),threadId=readStringParam(params,`threadId`),buttons=params.buttons,asVoice=typeof params.asVoice==`boolean`?params.asVoice:void 0,silent=typeof params.silent==`boolean`?params.silent:void 0,quoteText=readStringParam(params,`quoteText`);return{to,content,mediaUrl:mediaUrl??void 0,replyToMessageId:replyTo??void 0,messageThreadId:threadId??void 0,buttons,asVoice,silent,quoteText:quoteText??void 0}}const telegramMessageActions={listActions:({cfg})=>{let accounts=listEnabledTelegramAccounts(cfg).filter(account=>account.tokenSource!==`none`);if(accounts.length===0)return[];let gates=accounts.map(account=>createTelegramActionGate({cfg,accountId:account.accountId})),gate=(key,defaultValue=!0)=>gates.some(g=>g(key,defaultValue)),actions=new Set([`send`]);return gate(`reactions`)&&actions.add(`react`),gate(`deleteMessage`)&&actions.add(`delete`),gate(`editMessage`)&&actions.add(`edit`),gate(`sticker`,!1)&&(actions.add(`sticker`),actions.add(`sticker-search`)),gate(`createForumTopic`)&&actions.add(`topic-create`),Array.from(actions)},supportsButtons:({cfg})=>{let accounts=listEnabledTelegramAccounts(cfg).filter(account=>account.tokenSource!==`none`);return accounts.length===0?!1:accounts.some(account=>isTelegramInlineButtonsEnabled({cfg,accountId:account.accountId}))},extractToolSend:({args})=>extractToolSend(args,`sendMessage`),handleAction:async({action,params,cfg,accountId})=>{if(action===`send`)return await handleTelegramAction({action:`sendMessage`,...readTelegramSendParams(params),accountId:accountId??void 0},cfg);if(action===`react`){let messageId=readStringOrNumberParam(params,`messageId`,{required:!0}),emoji=readStringParam(params,`emoji`,{allowEmpty:!0}),remove=typeof params.remove==`boolean`?params.remove:void 0;return await handleTelegramAction({action:`react`,chatId:readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),messageId,emoji,remove,accountId:accountId??void 0},cfg)}if(action===`delete`)return await handleTelegramAction({action:`deleteMessage`,chatId:readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),messageId:readNumberParam(params,`messageId`,{required:!0,integer:!0}),accountId:accountId??void 0},cfg);if(action===`edit`){let chatId=readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),message=readStringParam(params,`message`,{required:!0,allowEmpty:!1}),buttons=params.buttons;return await handleTelegramAction({action:`editMessage`,chatId,messageId,content:message,buttons,accountId:accountId??void 0},cfg)}if(action===`sticker`){let to=readStringParam(params,`to`)??readStringParam(params,`target`,{required:!0}),fileId=readStringArrayParam(params,`stickerId`)?.[0]??readStringParam(params,`fileId`,{required:!0}),replyToMessageId=readNumberParam(params,`replyTo`,{integer:!0}),messageThreadId=readNumberParam(params,`threadId`,{integer:!0});return await handleTelegramAction({action:`sendSticker`,to,fileId,replyToMessageId:replyToMessageId??void 0,messageThreadId:messageThreadId??void 0,accountId:accountId??void 0},cfg)}if(action===`sticker-search`)return await handleTelegramAction({action:`searchSticker`,query:readStringParam(params,`query`,{required:!0}),limit:readNumberParam(params,`limit`,{integer:!0})??void 0,accountId:accountId??void 0},cfg);if(action===`topic-create`){let chatId=readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),iconColor=readNumberParam(params,`iconColor`,{integer:!0}),iconCustomEmojiId=readStringParam(params,`iconCustomEmojiId`);return await handleTelegramAction({action:`createForumTopic`,chatId,name,iconColor:iconColor??void 0,iconCustomEmojiId:iconCustomEmojiId??void 0,accountId:accountId??void 0},cfg)}throw Error(`Action ${action} is not supported for provider telegram.`)}};function createWhatsAppLoginTool(){return{label:`WhatsApp Login`,name:`whatsapp_login`,description:`Generate a WhatsApp QR code for linking, or wait for the scan to complete.`,parameters:Type.Object({action:Type.Unsafe({type:`string`,enum:[`start`,`wait`]}),timeoutMs:Type.Optional(Type.Number()),force:Type.Optional(Type.Boolean())}),execute:async(_toolCallId,args)=>{let{startWebLoginWithQr,waitForWebLogin}=await import(`./login-qr-B9lyIZVD.js`);if((args?.action??`start`)===`wait`){let result=await waitForWebLogin({timeoutMs:typeof args.timeoutMs==`number`?args.timeoutMs:void 0});return{content:[{type:`text`,text:result.message}],details:{connected:result.connected}}}let result=await startWebLoginWithQr({timeoutMs:typeof args.timeoutMs==`number`?args.timeoutMs:void 0,force:typeof args.force==`boolean`?args.force:!1});return result.qrDataUrl?{content:[{type:`text`,text:[result.message,``,`Open WhatsApp → Linked Devices and scan:`,``,`![whatsapp-qr](${result.qrDataUrl})`].join(`
446
+ `),accumulatedBlockText+=payload.text,blockCount++);let ttsPayload=await maybeApplyTtsToPayload({payload,cfg,channel:ttsChannel,kind:`block`,inboundAudio,ttsAuto:sessionTtsAuto});shouldRouteToOriginating?await sendPayloadAsync(ttsPayload,context?.abortSignal,!1):dispatcher.sendBlockReply(ttsPayload)})()},cfg),replies=replyResult?Array.isArray(replyResult)?replyResult:[replyResult]:[],queuedFinal=!1,routedFinalCount=0;for(let reply of replies){let ttsReply=await maybeApplyTtsToPayload({payload:reply,cfg,channel:ttsChannel,kind:`final`,inboundAudio,ttsAuto:sessionTtsAuto});if(shouldRouteToOriginating&&originatingChannel&&originatingTo){let result=await routeReply({payload:ttsReply,channel:originatingChannel,to:originatingTo,sessionKey:ctx.SessionKey,accountId:ctx.AccountId,threadId:ctx.MessageThreadId,cfg});result.ok||logVerbose(`dispatch-from-config: route-reply (final) failed: ${result.error??`unknown error`}`),queuedFinal=result.ok||queuedFinal,result.ok&&(routedFinalCount+=1)}else queuedFinal=dispatcher.sendFinalReply(ttsReply)||queuedFinal}if((resolveTtsConfig(cfg).mode??`final`)===`final`&&replies.length===0&&blockCount>0&&accumulatedBlockText.trim())try{let ttsSyntheticReply=await maybeApplyTtsToPayload({payload:{text:accumulatedBlockText},cfg,channel:ttsChannel,kind:`final`,inboundAudio,ttsAuto:sessionTtsAuto});if(ttsSyntheticReply.mediaUrl){let ttsOnlyPayload={mediaUrl:ttsSyntheticReply.mediaUrl,audioAsVoice:ttsSyntheticReply.audioAsVoice};if(shouldRouteToOriginating&&originatingChannel&&originatingTo){let result=await routeReply({payload:ttsOnlyPayload,channel:originatingChannel,to:originatingTo,sessionKey:ctx.SessionKey,accountId:ctx.AccountId,threadId:ctx.MessageThreadId,cfg});queuedFinal=result.ok||queuedFinal,result.ok&&(routedFinalCount+=1),result.ok||logVerbose(`dispatch-from-config: route-reply (tts-only) failed: ${result.error??`unknown error`}`)}else queuedFinal=dispatcher.sendFinalReply(ttsOnlyPayload)||queuedFinal}}catch(err){logVerbose(`dispatch-from-config: accumulated block TTS failed: ${err instanceof Error?err.message:String(err)}`)}let counts=dispatcher.getQueuedCounts();return counts.final+=routedFinalCount,recordProcessed(`completed`),markIdle(`message_completed`),{queuedFinal,counts}}catch(err){throw recordProcessed(`error`,{error:String(err)}),markIdle(`message_error`),err}}const activeDispatchers=new Set;let nextId=0;function registerDispatcher(dispatcher){let id=`dispatcher-${++nextId}`,tracked={id,pending:dispatcher.pending,waitForIdle:dispatcher.waitForIdle};return activeDispatchers.add(tracked),{id,unregister:()=>{activeDispatchers.delete(tracked)}}}function getTotalPendingReplies(){let total=0;for(let dispatcher of activeDispatchers)total+=dispatcher.pending();return total}const DEFAULT_HUMAN_DELAY_MAX_MS=2500;function getHumanDelay(config){let mode=config?.mode??`off`;if(mode===`off`)return 0;let min=mode===`custom`?config?.minMs??800:800,max=mode===`custom`?config?.maxMs??DEFAULT_HUMAN_DELAY_MAX_MS:DEFAULT_HUMAN_DELAY_MAX_MS;return max<=min?min:Math.floor(Math.random()*(max-min+1))+min}function normalizeReplyPayloadInternal(payload,opts){let prefixContext=opts.responsePrefixContextProvider?.()??opts.responsePrefixContext;return normalizeReplyPayload(payload,{responsePrefix:opts.responsePrefix,responsePrefixContext:prefixContext,onHeartbeatStrip:opts.onHeartbeatStrip,onSkip:opts.onSkip})}function createReplyDispatcher(options){let sendChain=Promise.resolve(),pending=1,completeCalled=!1,sentFirstBlock=!1,queuedCounts={tool:0,block:0,final:0},{unregister}=registerDispatcher({pending:()=>pending,waitForIdle:()=>sendChain}),enqueue=(kind,payload)=>{let normalized=normalizeReplyPayloadInternal(payload,{responsePrefix:options.responsePrefix,responsePrefixContext:options.responsePrefixContext,responsePrefixContextProvider:options.responsePrefixContextProvider,onHeartbeatStrip:options.onHeartbeatStrip,onSkip:reason=>options.onSkip?.(payload,{kind,reason})});if(!normalized)return!1;queuedCounts[kind]+=1,pending+=1;let shouldDelay=kind===`block`&&sentFirstBlock;return kind===`block`&&(sentFirstBlock=!0),sendChain=sendChain.then(async()=>{if(shouldDelay){let delayMs=getHumanDelay(options.humanDelay);delayMs>0&&await sleep$2(delayMs)}await options.deliver(normalized,{kind})}).catch(err=>{options.onError?.(err,{kind})}).finally(()=>{--pending,pending===1&&completeCalled&&--pending,pending===0&&(unregister(),options.onIdle?.())}),!0};return{sendToolResult:payload=>enqueue(`tool`,payload),sendBlockReply:payload=>enqueue(`block`,payload),sendFinalReply:payload=>enqueue(`final`,payload),waitForIdle:()=>sendChain,getQueuedCounts:()=>({...queuedCounts}),markComplete:()=>{completeCalled||(completeCalled=!0,Promise.resolve().then(()=>{pending===1&&completeCalled&&(--pending,pending===0&&(unregister(),options.onIdle?.()))}))}}}function createReplyDispatcherWithTyping(options){let{onReplyStart,onIdle,onCleanup,...dispatcherOptions}=options,typingController;return{dispatcher:createReplyDispatcher({...dispatcherOptions,onIdle:()=>{typingController?.markDispatchIdle(),onIdle?.()}}),replyOptions:{onReplyStart,onTypingCleanup:onCleanup,onTypingController:typing=>{typingController=typing}},markDispatchIdle:()=>{typingController?.markDispatchIdle(),onIdle?.()}}}async function withReplyDispatcher(params){try{return await params.run()}finally{params.dispatcher.markComplete();try{await params.dispatcher.waitForIdle()}finally{await params.onSettled?.()}}}async function dispatchInboundMessage(params){let finalized=finalizeInboundContext(params.ctx);return await withReplyDispatcher({dispatcher:params.dispatcher,run:()=>dispatchReplyFromConfig({ctx:finalized,cfg:params.cfg,dispatcher:params.dispatcher,replyOptions:params.replyOptions,replyResolver:params.replyResolver})})}async function dispatchInboundMessageWithBufferedDispatcher(params){let{dispatcher,replyOptions,markDispatchIdle}=createReplyDispatcherWithTyping(params.dispatcherOptions);try{return await dispatchInboundMessage({ctx:params.ctx,cfg:params.cfg,dispatcher,replyResolver:params.replyResolver,replyOptions:{...params.replyOptions,...replyOptions}})}finally{markDispatchIdle()}}async function dispatchInboundMessageWithDispatcher(params){let dispatcher=createReplyDispatcher(params.dispatcherOptions);return await dispatchInboundMessage({ctx:params.ctx,cfg:params.cfg,dispatcher,replyResolver:params.replyResolver,replyOptions:params.replyOptions})}async function dispatchReplyWithBufferedBlockDispatcher(params){return await dispatchInboundMessageWithBufferedDispatcher({ctx:params.ctx,cfg:params.cfg,dispatcherOptions:params.dispatcherOptions,replyResolver:params.replyResolver,replyOptions:params.replyOptions})}async function dispatchReplyWithDispatcher(params){return await dispatchInboundMessageWithDispatcher({ctx:params.ctx,cfg:params.cfg,dispatcherOptions:params.dispatcherOptions,replyResolver:params.replyResolver,replyOptions:params.replyOptions})}function shouldAckReaction(params){let scope=params.scope??`group-mentions`;return scope===`off`||scope===`none`?!1:scope===`all`?!0:scope===`direct`?params.isDirect:scope===`group-all`?params.isGroup:scope===`group-mentions`?!params.isMentionableGroup||!params.requireMention||!params.canDetectMention?!1:params.effectiveWasMentioned||params.shouldBypassMention===!0:!1}function shouldAckReactionForWhatsApp(params){return params.emoji?params.isDirect?params.directEnabled:!params.isGroup||params.groupMode===`never`?!1:params.groupMode===`always`?!0:shouldAckReaction({scope:`group-mentions`,isDirect:!1,isGroup:!0,isMentionableGroup:!0,requireMention:!0,canDetectMention:!0,effectiveWasMentioned:params.wasMentioned,shouldBypassMention:params.groupActivated}):!1}function removeAckReactionAfterReply(params){params.removeAfterReply&&params.ackReactionPromise&&params.ackReactionValue&&params.ackReactionPromise.then(didAck=>{didAck&&params.remove().catch(err=>params.onError?.(err))})}function resolveCommandAuthorizedFromAuthorizers(params){let{useAccessGroups,authorizers}=params,mode=params.modeWhenAccessGroupsOff??`allow`;return useAccessGroups?authorizers.some(entry=>entry.configured&&entry.allowed):mode===`allow`?!0:mode===`deny`?!1:authorizers.some(entry=>entry.configured)?authorizers.some(entry=>entry.configured&&entry.allowed):!0}function resolveControlCommandGate(params){let commandAuthorized=resolveCommandAuthorizedFromAuthorizers({useAccessGroups:params.useAccessGroups,authorizers:params.authorizers,modeWhenAccessGroupsOff:params.modeWhenAccessGroupsOff});return{commandAuthorized,shouldBlock:params.allowTextCommands&&params.hasControlCommand&&!commandAuthorized}}const presenceCache=new Map;function resolveAccountKey$1(accountId){return accountId??`default`}function setPresence(accountId,userId,data){let accountKey=resolveAccountKey$1(accountId),accountCache=presenceCache.get(accountKey);if(accountCache||(accountCache=new Map,presenceCache.set(accountKey,accountCache)),accountCache.set(userId,data),accountCache.size>5e3){let oldest=accountCache.keys().next().value;oldest!==void 0&&accountCache.delete(oldest)}}function getPresence(accountId,userId){return presenceCache.get(resolveAccountKey$1(accountId))?.get(userId)}function readParentIdParam$1(params){return params.clearParent===!0||params.parentId===null?null:readStringParam(params,`parentId`)}async function runRoleMutation(params){let guildId=readStringParam(params.values,`guildId`,{required:!0}),userId=readStringParam(params.values,`userId`,{required:!0}),roleId=readStringParam(params.values,`roleId`,{required:!0});if(params.accountId){await params.mutate({guildId,userId,roleId},{accountId:params.accountId});return}await params.mutate({guildId,userId,roleId})}async function handleDiscordGuildAction(action,params,isActionEnabled){let accountId=readStringParam(params,`accountId`);switch(action){case`memberInfo`:{if(!isActionEnabled(`memberInfo`))throw Error(`Discord member info is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),member=accountId?await fetchMemberInfoDiscord(guildId,userId,{accountId}):await fetchMemberInfoDiscord(guildId,userId),presence=getPresence(accountId,userId),activities=presence?.activities??void 0,status=presence?.status??void 0;return jsonResult({ok:!0,member,...presence?{status,activities}:{}})}case`roleInfo`:{if(!isActionEnabled(`roleInfo`))throw Error(`Discord role info is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,roles:accountId?await fetchRoleInfoDiscord(guildId,{accountId}):await fetchRoleInfoDiscord(guildId)})}case`emojiList`:{if(!isActionEnabled(`reactions`))throw Error(`Discord reactions are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,emojis:accountId?await listGuildEmojisDiscord(guildId,{accountId}):await listGuildEmojisDiscord(guildId)})}case`emojiUpload`:{if(!isActionEnabled(`emojiUploads`))throw Error(`Discord emoji uploads are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`,{required:!0}),roleIds=readStringArrayParam(params,`roleIds`);return jsonResult({ok:!0,emoji:accountId?await uploadEmojiDiscord({guildId,name,mediaUrl,roleIds:roleIds?.length?roleIds:void 0},{accountId}):await uploadEmojiDiscord({guildId,name,mediaUrl,roleIds:roleIds?.length?roleIds:void 0})})}case`stickerUpload`:{if(!isActionEnabled(`stickerUploads`))throw Error(`Discord sticker uploads are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),description=readStringParam(params,`description`,{required:!0}),tags=readStringParam(params,`tags`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`,{required:!0});return jsonResult({ok:!0,sticker:accountId?await uploadStickerDiscord({guildId,name,description,tags,mediaUrl},{accountId}):await uploadStickerDiscord({guildId,name,description,tags,mediaUrl})})}case`roleAdd`:if(!isActionEnabled(`roles`,!1))throw Error(`Discord role changes are disabled.`);return await runRoleMutation({accountId,values:params,mutate:addRoleDiscord}),jsonResult({ok:!0});case`roleRemove`:if(!isActionEnabled(`roles`,!1))throw Error(`Discord role changes are disabled.`);return await runRoleMutation({accountId,values:params,mutate:removeRoleDiscord}),jsonResult({ok:!0});case`channelInfo`:{if(!isActionEnabled(`channelInfo`))throw Error(`Discord channel info is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0});return jsonResult({ok:!0,channel:accountId?await fetchChannelInfoDiscord(channelId,{accountId}):await fetchChannelInfoDiscord(channelId)})}case`channelList`:{if(!isActionEnabled(`channelInfo`))throw Error(`Discord channel info is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,channels:accountId?await listGuildChannelsDiscord(guildId,{accountId}):await listGuildChannelsDiscord(guildId)})}case`voiceStatus`:{if(!isActionEnabled(`voiceStatus`))throw Error(`Discord voice status is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0});return jsonResult({ok:!0,voice:accountId?await fetchVoiceStatusDiscord(guildId,userId,{accountId}):await fetchVoiceStatusDiscord(guildId,userId)})}case`eventList`:{if(!isActionEnabled(`events`))throw Error(`Discord events are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0});return jsonResult({ok:!0,events:accountId?await listScheduledEventsDiscord(guildId,{accountId}):await listScheduledEventsDiscord(guildId)})}case`eventCreate`:{if(!isActionEnabled(`events`))throw Error(`Discord events are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),startTime=readStringParam(params,`startTime`,{required:!0}),endTime=readStringParam(params,`endTime`),description=readStringParam(params,`description`),channelId=readStringParam(params,`channelId`),location=readStringParam(params,`location`),entityTypeRaw=readStringParam(params,`entityType`),entityType=entityTypeRaw===`stage`?1:entityTypeRaw===`external`?3:2,payload={name,description,scheduled_start_time:startTime,scheduled_end_time:endTime,entity_type:entityType,channel_id:channelId,entity_metadata:entityType===3&&location?{location}:void 0,privacy_level:2};return jsonResult({ok:!0,event:accountId?await createScheduledEventDiscord(guildId,payload,{accountId}):await createScheduledEventDiscord(guildId,payload)})}case`channelCreate`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),type=readNumberParam(params,`type`,{integer:!0}),parentId=readParentIdParam$1(params),topic=readStringParam(params,`topic`),position=readNumberParam(params,`position`,{integer:!0}),nsfw=params.nsfw;return jsonResult({ok:!0,channel:accountId?await createChannelDiscord({guildId,name,type:type??void 0,parentId:parentId??void 0,topic:topic??void 0,position:position??void 0,nsfw},{accountId}):await createChannelDiscord({guildId,name,type:type??void 0,parentId:parentId??void 0,topic:topic??void 0,position:position??void 0,nsfw})})}case`channelEdit`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0}),name=readStringParam(params,`name`),topic=readStringParam(params,`topic`),position=readNumberParam(params,`position`,{integer:!0}),parentId=readParentIdParam$1(params),nsfw=params.nsfw,rateLimitPerUser=readNumberParam(params,`rateLimitPerUser`,{integer:!0}),archived=typeof params.archived==`boolean`?params.archived:void 0,locked=typeof params.locked==`boolean`?params.locked:void 0,autoArchiveDuration=readNumberParam(params,`autoArchiveDuration`,{integer:!0});return jsonResult({ok:!0,channel:accountId?await editChannelDiscord({channelId,name:name??void 0,topic:topic??void 0,position:position??void 0,parentId,nsfw,rateLimitPerUser:rateLimitPerUser??void 0,archived,locked,autoArchiveDuration:autoArchiveDuration??void 0},{accountId}):await editChannelDiscord({channelId,name:name??void 0,topic:topic??void 0,position:position??void 0,parentId,nsfw,rateLimitPerUser:rateLimitPerUser??void 0,archived,locked,autoArchiveDuration:autoArchiveDuration??void 0})})}case`channelDelete`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0});return jsonResult(accountId?await deleteChannelDiscord(channelId,{accountId}):await deleteChannelDiscord(channelId))}case`channelMove`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),channelId=readStringParam(params,`channelId`,{required:!0}),parentId=readParentIdParam$1(params),position=readNumberParam(params,`position`,{integer:!0});return accountId?await moveChannelDiscord({guildId,channelId,parentId,position:position??void 0},{accountId}):await moveChannelDiscord({guildId,channelId,parentId,position:position??void 0}),jsonResult({ok:!0})}case`categoryCreate`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),position=readNumberParam(params,`position`,{integer:!0});return jsonResult({ok:!0,category:accountId?await createChannelDiscord({guildId,name,type:4,position:position??void 0},{accountId}):await createChannelDiscord({guildId,name,type:4,position:position??void 0})})}case`categoryEdit`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let categoryId=readStringParam(params,`categoryId`,{required:!0}),name=readStringParam(params,`name`),position=readNumberParam(params,`position`,{integer:!0});return jsonResult({ok:!0,category:accountId?await editChannelDiscord({channelId:categoryId,name:name??void 0,position:position??void 0},{accountId}):await editChannelDiscord({channelId:categoryId,name:name??void 0,position:position??void 0})})}case`categoryDelete`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let categoryId=readStringParam(params,`categoryId`,{required:!0});return jsonResult(accountId?await deleteChannelDiscord(categoryId,{accountId}):await deleteChannelDiscord(categoryId))}case`channelPermissionSet`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0}),targetId=readStringParam(params,`targetId`,{required:!0}),targetType=readStringParam(params,`targetType`,{required:!0})===`member`?1:0,allow=readStringParam(params,`allow`),deny=readStringParam(params,`deny`);return accountId?await setChannelPermissionDiscord({channelId,targetId,targetType,allow:allow??void 0,deny:deny??void 0},{accountId}):await setChannelPermissionDiscord({channelId,targetId,targetType,allow:allow??void 0,deny:deny??void 0}),jsonResult({ok:!0})}case`channelPermissionRemove`:{if(!isActionEnabled(`channels`))throw Error(`Discord channel management is disabled.`);let channelId=readStringParam(params,`channelId`,{required:!0}),targetId=readStringParam(params,`targetId`,{required:!0});return accountId?await removeChannelPermissionDiscord(channelId,targetId,{accountId}):await removeChannelPermissionDiscord(channelId,targetId),jsonResult({ok:!0})}default:throw Error(`Unknown action: ${action}`)}}function parseDiscordMessageLink(link){let match=link.trim().match(/^(?:https?:\/\/)?(?:ptb\.|canary\.)?discord(?:app)?\.com\/channels\/(\d+)\/(\d+)\/(\d+)(?:\/?|\?.*)$/i);if(!match)throw Error(`Invalid Discord message link. Expected https://discord.com/channels/<guildId>/<channelId>/<messageId>.`);return{guildId:match[1],channelId:match[2],messageId:match[3]}}async function handleDiscordMessagingAction(action,params,isActionEnabled){let resolveChannelId=()=>resolveDiscordChannelId(readStringParam(params,`channelId`,{required:!0})),accountId=readStringParam(params,`accountId`),normalizeMessage=message=>!message||typeof message!=`object`?message:withNormalizedTimestamp(message,message.timestamp);switch(action){case`react`:{if(!isActionEnabled(`reactions`))throw Error(`Discord reactions are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0}),{emoji,remove,isEmpty}=readReactionParams(params,{removeErrorMessage:`Emoji is required to remove a Discord reaction.`});return remove?(accountId?await removeReactionDiscord(channelId,messageId,emoji,{accountId}):await removeReactionDiscord(channelId,messageId,emoji),jsonResult({ok:!0,removed:emoji})):isEmpty?jsonResult({ok:!0,removed:(accountId?await removeOwnReactionsDiscord(channelId,messageId,{accountId}):await removeOwnReactionsDiscord(channelId,messageId)).removed}):(accountId?await reactMessageDiscord(channelId,messageId,emoji,{accountId}):await reactMessageDiscord(channelId,messageId,emoji),jsonResult({ok:!0,added:emoji}))}case`reactions`:{if(!isActionEnabled(`reactions`))throw Error(`Discord reactions are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0}),limitRaw=params.limit,limit=typeof limitRaw==`number`&&Number.isFinite(limitRaw)?limitRaw:void 0;return jsonResult({ok:!0,reactions:await fetchReactionsDiscord(channelId,messageId,{...accountId?{accountId}:{},limit})})}case`sticker`:{if(!isActionEnabled(`stickers`))throw Error(`Discord stickers are disabled.`);let to=readStringParam(params,`to`,{required:!0}),content=readStringParam(params,`content`);return await sendStickerDiscord(to,readStringArrayParam(params,`stickerIds`,{required:!0,label:`stickerIds`}),{...accountId?{accountId}:{},content}),jsonResult({ok:!0})}case`poll`:{if(!isActionEnabled(`polls`))throw Error(`Discord polls are disabled.`);let to=readStringParam(params,`to`,{required:!0}),content=readStringParam(params,`content`),question=readStringParam(params,`question`,{required:!0}),answers=readStringArrayParam(params,`answers`,{required:!0,label:`answers`}),allowMultiselectRaw=params.allowMultiselect,allowMultiselect=typeof allowMultiselectRaw==`boolean`?allowMultiselectRaw:void 0,durationRaw=params.durationHours,durationHours=typeof durationRaw==`number`&&Number.isFinite(durationRaw)?durationRaw:void 0;return await sendPollDiscord(to,{question,options:answers,maxSelections:allowMultiselect?Math.max(2,answers.length):1,durationHours},{...accountId?{accountId}:{},content}),jsonResult({ok:!0})}case`permissions`:{if(!isActionEnabled(`permissions`))throw Error(`Discord permissions are disabled.`);let channelId=resolveChannelId();return jsonResult({ok:!0,permissions:accountId?await fetchChannelPermissionsDiscord(channelId,{accountId}):await fetchChannelPermissionsDiscord(channelId)})}case`fetchMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message reads are disabled.`);let messageLink=readStringParam(params,`messageLink`),guildId=readStringParam(params,`guildId`),channelId=readStringParam(params,`channelId`),messageId=readStringParam(params,`messageId`);if(messageLink){let parsed=parseDiscordMessageLink(messageLink);guildId=parsed.guildId,channelId=parsed.channelId,messageId=parsed.messageId}if(!guildId||!channelId||!messageId)throw Error(`Discord message fetch requires guildId, channelId, and messageId (or a valid messageLink).`);return jsonResult({ok:!0,message:normalizeMessage(accountId?await fetchMessageDiscord(channelId,messageId,{accountId}):await fetchMessageDiscord(channelId,messageId)),guildId,channelId,messageId})}case`readMessages`:{if(!isActionEnabled(`messages`))throw Error(`Discord message reads are disabled.`);let channelId=resolveChannelId(),query={limit:typeof params.limit==`number`&&Number.isFinite(params.limit)?params.limit:void 0,before:readStringParam(params,`before`),after:readStringParam(params,`after`),around:readStringParam(params,`around`)};return jsonResult({ok:!0,messages:(accountId?await readMessagesDiscord(channelId,query,{accountId}):await readMessagesDiscord(channelId,query)).map(message=>normalizeMessage(message))})}case`sendMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message sends are disabled.`);let to=readStringParam(params,`to`,{required:!0}),asVoice=params.asVoice===!0,silent=params.silent===!0,rawComponents=params.components,componentSpec=rawComponents&&typeof rawComponents==`object`&&!Array.isArray(rawComponents)?readDiscordComponentSpec(rawComponents):null,components=Array.isArray(rawComponents)||typeof rawComponents==`function`?rawComponents:void 0,content=readStringParam(params,`content`,{required:!asVoice&&!componentSpec&&!components,allowEmpty:!0}),mediaUrl=readStringParam(params,`mediaUrl`,{trim:!1})??readStringParam(params,`path`,{trim:!1})??readStringParam(params,`filePath`,{trim:!1}),filename=readStringParam(params,`filename`),replyTo=readStringParam(params,`replyTo`),rawEmbeds=params.embeds,embeds=Array.isArray(rawEmbeds)?rawEmbeds:void 0,sessionKey=readStringParam(params,`__sessionKey`),agentId=readStringParam(params,`__agentId`);if(componentSpec){if(asVoice)throw Error(`Discord components cannot be sent as voice messages.`);if(embeds?.length)throw Error(`Discord components cannot include embeds.`);let normalizedContent=content?.trim()?content:void 0;return jsonResult({ok:!0,result:await sendDiscordComponentMessage(to,componentSpec.text?componentSpec:{...componentSpec,text:normalizedContent},{...accountId?{accountId}:{},silent,replyTo:replyTo??void 0,sessionKey:sessionKey??void 0,agentId:agentId??void 0,mediaUrl:mediaUrl??void 0,filename:filename??void 0}),components:!0})}if(asVoice){if(!mediaUrl)throw Error(`Voice messages require a media file reference (mediaUrl, path, or filePath).`);if(content&&content.trim())throw Error(`Voice messages cannot include text content (Discord limitation). Remove the content parameter.`);return assertMediaNotDataUrl(mediaUrl),jsonResult({ok:!0,result:await sendVoiceMessageDiscord(to,mediaUrl,{...accountId?{accountId}:{},replyTo,silent}),voiceMessage:!0})}return jsonResult({ok:!0,result:await sendMessageDiscord(to,content??``,{...accountId?{accountId}:{},mediaUrl,replyTo,components,embeds,silent})})}case`editMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message edits are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0}),content=readStringParam(params,`content`,{required:!0});return jsonResult({ok:!0,message:accountId?await editMessageDiscord(channelId,messageId,{content},{accountId}):await editMessageDiscord(channelId,messageId,{content})})}case`deleteMessage`:{if(!isActionEnabled(`messages`))throw Error(`Discord message deletes are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0});return accountId?await deleteMessageDiscord(channelId,messageId,{accountId}):await deleteMessageDiscord(channelId,messageId),jsonResult({ok:!0})}case`threadCreate`:{if(!isActionEnabled(`threads`))throw Error(`Discord threads are disabled.`);let channelId=resolveChannelId(),name=readStringParam(params,`name`,{required:!0}),messageId=readStringParam(params,`messageId`),content=readStringParam(params,`content`),autoArchiveMinutesRaw=params.autoArchiveMinutes,autoArchiveMinutes=typeof autoArchiveMinutesRaw==`number`&&Number.isFinite(autoArchiveMinutesRaw)?autoArchiveMinutesRaw:void 0;return jsonResult({ok:!0,thread:accountId?await createThreadDiscord(channelId,{name,messageId,autoArchiveMinutes,content},{accountId}):await createThreadDiscord(channelId,{name,messageId,autoArchiveMinutes,content})})}case`threadList`:{if(!isActionEnabled(`threads`))throw Error(`Discord threads are disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),channelId=readStringParam(params,`channelId`),includeArchived=typeof params.includeArchived==`boolean`?params.includeArchived:void 0,before=readStringParam(params,`before`),limit=typeof params.limit==`number`&&Number.isFinite(params.limit)?params.limit:void 0;return jsonResult({ok:!0,threads:accountId?await listThreadsDiscord({guildId,channelId,includeArchived,before,limit},{accountId}):await listThreadsDiscord({guildId,channelId,includeArchived,before,limit})})}case`threadReply`:{if(!isActionEnabled(`threads`))throw Error(`Discord threads are disabled.`);let channelId=resolveChannelId(),content=readStringParam(params,`content`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`),replyTo=readStringParam(params,`replyTo`);return jsonResult({ok:!0,result:await sendMessageDiscord(`channel:${channelId}`,content,{...accountId?{accountId}:{},mediaUrl,replyTo})})}case`pinMessage`:{if(!isActionEnabled(`pins`))throw Error(`Discord pins are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0});return accountId?await pinMessageDiscord(channelId,messageId,{accountId}):await pinMessageDiscord(channelId,messageId),jsonResult({ok:!0})}case`unpinMessage`:{if(!isActionEnabled(`pins`))throw Error(`Discord pins are disabled.`);let channelId=resolveChannelId(),messageId=readStringParam(params,`messageId`,{required:!0});return accountId?await unpinMessageDiscord(channelId,messageId,{accountId}):await unpinMessageDiscord(channelId,messageId),jsonResult({ok:!0})}case`listPins`:{if(!isActionEnabled(`pins`))throw Error(`Discord pins are disabled.`);let channelId=resolveChannelId();return jsonResult({ok:!0,pins:(accountId?await listPinsDiscord(channelId,{accountId}):await listPinsDiscord(channelId)).map(pin=>normalizeMessage(pin))})}case`searchMessages`:{if(!isActionEnabled(`search`))throw Error(`Discord search is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),content=readStringParam(params,`content`,{required:!0}),channelId=readStringParam(params,`channelId`),channelIds=readStringArrayParam(params,`channelIds`),authorId=readStringParam(params,`authorId`),authorIds=readStringArrayParam(params,`authorIds`),limit=typeof params.limit==`number`&&Number.isFinite(params.limit)?params.limit:void 0,channelIdList=[...channelIds??[],...channelId?[channelId]:[]],authorIdList=[...authorIds??[],...authorId?[authorId]:[]],results=accountId?await searchMessagesDiscord({guildId,content,channelIds:channelIdList.length?channelIdList:void 0,authorIds:authorIdList.length?authorIdList:void 0,limit},{accountId}):await searchMessagesDiscord({guildId,content,channelIds:channelIdList.length?channelIdList:void 0,authorIds:authorIdList.length?authorIdList:void 0,limit});if(!results||typeof results!=`object`)return jsonResult({ok:!0,results});let resultsRecord=results,messages=resultsRecord.messages,normalizedMessages=Array.isArray(messages)?messages.map(group=>Array.isArray(group)?group.map(msg=>normalizeMessage(msg)):group):messages;return jsonResult({ok:!0,results:{...resultsRecord,messages:normalizedMessages}})}default:throw Error(`Unknown action: ${action}`)}}async function handleDiscordModerationAction(action,params,isActionEnabled){let accountId=readStringParam(params,`accountId`);switch(action){case`timeout`:{if(!isActionEnabled(`moderation`,!1))throw Error(`Discord moderation is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),durationMinutes=typeof params.durationMinutes==`number`&&Number.isFinite(params.durationMinutes)?params.durationMinutes:void 0,until=readStringParam(params,`until`),reason=readStringParam(params,`reason`);return jsonResult({ok:!0,member:accountId?await timeoutMemberDiscord({guildId,userId,durationMinutes,until,reason},{accountId}):await timeoutMemberDiscord({guildId,userId,durationMinutes,until,reason})})}case`kick`:{if(!isActionEnabled(`moderation`,!1))throw Error(`Discord moderation is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),reason=readStringParam(params,`reason`);return accountId?await kickMemberDiscord({guildId,userId,reason},{accountId}):await kickMemberDiscord({guildId,userId,reason}),jsonResult({ok:!0})}case`ban`:{if(!isActionEnabled(`moderation`,!1))throw Error(`Discord moderation is disabled.`);let guildId=readStringParam(params,`guildId`,{required:!0}),userId=readStringParam(params,`userId`,{required:!0}),reason=readStringParam(params,`reason`),deleteMessageDays=typeof params.deleteMessageDays==`number`&&Number.isFinite(params.deleteMessageDays)?params.deleteMessageDays:void 0;return accountId?await banMemberDiscord({guildId,userId,reason,deleteMessageDays},{accountId}):await banMemberDiscord({guildId,userId,reason,deleteMessageDays}),jsonResult({ok:!0})}default:throw Error(`Unknown action: ${action}`)}}const gatewayRegistry=new Map;function resolveAccountKey(accountId){return accountId??`\0__default__`}function registerGateway(accountId,gateway){gatewayRegistry.set(resolveAccountKey(accountId),gateway)}function unregisterGateway(accountId){gatewayRegistry.delete(resolveAccountKey(accountId))}function getGateway(accountId){return gatewayRegistry.get(resolveAccountKey(accountId))}const ACTIVITY_TYPE_MAP={playing:0,streaming:1,listening:2,watching:3,custom:4,competing:5},VALID_STATUSES=new Set([`online`,`dnd`,`idle`,`invisible`]);async function handleDiscordPresenceAction(action,params,isActionEnabled){if(action!==`setPresence`)throw Error(`Unknown presence action: ${action}`);if(!isActionEnabled(`presence`,!1))throw Error(`Discord presence changes are disabled.`);let accountId=readStringParam(params,`accountId`),gateway=getGateway(accountId);if(!gateway)throw Error(`Discord gateway not available${accountId?` for account "${accountId}"`:``}. The bot may not be connected.`);if(!gateway.isConnected)throw Error(`Discord gateway is not connected${accountId?` for account "${accountId}"`:``}.`);let statusRaw=readStringParam(params,`status`)??`online`;if(!VALID_STATUSES.has(statusRaw))throw Error(`Invalid status "${statusRaw}". Must be one of: ${[...VALID_STATUSES].join(`, `)}`);let status=statusRaw,activityTypeRaw=readStringParam(params,`activityType`),activityName=readStringParam(params,`activityName`),activities=[];if(activityTypeRaw||activityName){if(!activityTypeRaw)throw Error(`activityType is required when activityName is provided. Valid types: ${Object.keys(ACTIVITY_TYPE_MAP).join(`, `)}`);let typeNum=ACTIVITY_TYPE_MAP[activityTypeRaw.toLowerCase()];if(typeNum===void 0)throw Error(`Invalid activityType "${activityTypeRaw}". Must be one of: ${Object.keys(ACTIVITY_TYPE_MAP).join(`, `)}`);let activity={name:activityName??``,type:typeNum};if(typeNum===1){let url=readStringParam(params,`activityUrl`);url&&(activity.url=url)}let state=readStringParam(params,`activityState`);state&&(activity.state=state),activities.push(activity)}let presenceData={since:null,activities,status,afk:!1};return gateway.updatePresence(presenceData),jsonResult({ok:!0,status,activities:activities.map(a=>({type:a.type,name:a.name,...a.url?{url:a.url}:{},...a.state?{state:a.state}:{}}))})}const messagingActions=new Set([`react`,`reactions`,`sticker`,`poll`,`permissions`,`fetchMessage`,`readMessages`,`sendMessage`,`editMessage`,`deleteMessage`,`threadCreate`,`threadList`,`threadReply`,`pinMessage`,`unpinMessage`,`listPins`,`searchMessages`]),guildActions=new Set([`memberInfo`,`roleInfo`,`emojiList`,`emojiUpload`,`stickerUpload`,`roleAdd`,`roleRemove`,`channelInfo`,`channelList`,`voiceStatus`,`eventList`,`eventCreate`,`channelCreate`,`channelEdit`,`channelDelete`,`channelMove`,`categoryCreate`,`categoryEdit`,`categoryDelete`,`channelPermissionSet`,`channelPermissionRemove`]),moderationActions=new Set([`timeout`,`kick`,`ban`]),presenceActions=new Set([`setPresence`]);async function handleDiscordAction(params,cfg){let action=readStringParam(params,`action`,{required:!0}),isActionEnabled=createDiscordActionGate({cfg,accountId:readStringParam(params,`accountId`)});if(messagingActions.has(action))return await handleDiscordMessagingAction(action,params,isActionEnabled);if(guildActions.has(action))return await handleDiscordGuildAction(action,params,isActionEnabled);if(moderationActions.has(action))return await handleDiscordModerationAction(action,params,isActionEnabled);if(presenceActions.has(action))return await handleDiscordPresenceAction(action,params,isActionEnabled);throw Error(`Unknown action: ${action}`)}async function tryHandleDiscordMessageActionGuildAdmin(params){let{ctx,resolveChannelId,readParentIdParam}=params,{action,params:actionParams,cfg}=ctx,accountId=ctx.accountId??readStringParam(actionParams,`accountId`);if(action===`member-info`){let userId=readStringParam(actionParams,`userId`,{required:!0}),guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`memberInfo`,accountId:accountId??void 0,guildId,userId},cfg)}if(action===`role-info`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`roleInfo`,accountId:accountId??void 0,guildId},cfg)}if(action===`emoji-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`emojiList`,accountId:accountId??void 0,guildId},cfg)}if(action===`emoji-upload`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`emojiName`,{required:!0}),mediaUrl=readStringParam(actionParams,`media`,{required:!0,trim:!1}),roleIds=readStringArrayParam(actionParams,`roleIds`);return await handleDiscordAction({action:`emojiUpload`,accountId:accountId??void 0,guildId,name,mediaUrl,roleIds},cfg)}if(action===`sticker-upload`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`stickerName`,{required:!0}),description=readStringParam(actionParams,`stickerDesc`,{required:!0}),tags=readStringParam(actionParams,`stickerTags`,{required:!0}),mediaUrl=readStringParam(actionParams,`media`,{required:!0,trim:!1});return await handleDiscordAction({action:`stickerUpload`,accountId:accountId??void 0,guildId,name,description,tags,mediaUrl},cfg)}if(action===`role-add`||action===`role-remove`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),userId=readStringParam(actionParams,`userId`,{required:!0}),roleId=readStringParam(actionParams,`roleId`,{required:!0});return await handleDiscordAction({action:action===`role-add`?`roleAdd`:`roleRemove`,accountId:accountId??void 0,guildId,userId,roleId},cfg)}if(action===`channel-info`){let channelId=readStringParam(actionParams,`channelId`,{required:!0});return await handleDiscordAction({action:`channelInfo`,accountId:accountId??void 0,channelId},cfg)}if(action===`channel-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`channelList`,accountId:accountId??void 0,guildId},cfg)}if(action===`channel-create`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`name`,{required:!0}),type=readNumberParam(actionParams,`type`,{integer:!0}),parentId=readParentIdParam(actionParams),topic=readStringParam(actionParams,`topic`),position=readNumberParam(actionParams,`position`,{integer:!0}),nsfw=typeof actionParams.nsfw==`boolean`?actionParams.nsfw:void 0;return await handleDiscordAction({action:`channelCreate`,accountId:accountId??void 0,guildId,name,type:type??void 0,parentId:parentId??void 0,topic:topic??void 0,position:position??void 0,nsfw},cfg)}if(action===`channel-edit`){let channelId=readStringParam(actionParams,`channelId`,{required:!0}),name=readStringParam(actionParams,`name`),topic=readStringParam(actionParams,`topic`),position=readNumberParam(actionParams,`position`,{integer:!0}),parentId=readParentIdParam(actionParams),nsfw=typeof actionParams.nsfw==`boolean`?actionParams.nsfw:void 0,rateLimitPerUser=readNumberParam(actionParams,`rateLimitPerUser`,{integer:!0}),archived=typeof actionParams.archived==`boolean`?actionParams.archived:void 0,locked=typeof actionParams.locked==`boolean`?actionParams.locked:void 0,autoArchiveDuration=readNumberParam(actionParams,`autoArchiveDuration`,{integer:!0});return await handleDiscordAction({action:`channelEdit`,accountId:accountId??void 0,channelId,name:name??void 0,topic:topic??void 0,position:position??void 0,parentId:parentId===void 0?void 0:parentId,nsfw,rateLimitPerUser:rateLimitPerUser??void 0,archived,locked,autoArchiveDuration:autoArchiveDuration??void 0},cfg)}if(action===`channel-delete`){let channelId=readStringParam(actionParams,`channelId`,{required:!0});return await handleDiscordAction({action:`channelDelete`,accountId:accountId??void 0,channelId},cfg)}if(action===`channel-move`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),channelId=readStringParam(actionParams,`channelId`,{required:!0}),parentId=readParentIdParam(actionParams),position=readNumberParam(actionParams,`position`,{integer:!0});return await handleDiscordAction({action:`channelMove`,accountId:accountId??void 0,guildId,channelId,parentId:parentId===void 0?void 0:parentId,position:position??void 0},cfg)}if(action===`category-create`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`name`,{required:!0}),position=readNumberParam(actionParams,`position`,{integer:!0});return await handleDiscordAction({action:`categoryCreate`,accountId:accountId??void 0,guildId,name,position:position??void 0},cfg)}if(action===`category-edit`){let categoryId=readStringParam(actionParams,`categoryId`,{required:!0}),name=readStringParam(actionParams,`name`),position=readNumberParam(actionParams,`position`,{integer:!0});return await handleDiscordAction({action:`categoryEdit`,accountId:accountId??void 0,categoryId,name:name??void 0,position:position??void 0},cfg)}if(action===`category-delete`){let categoryId=readStringParam(actionParams,`categoryId`,{required:!0});return await handleDiscordAction({action:`categoryDelete`,accountId:accountId??void 0,categoryId},cfg)}if(action===`voice-status`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),userId=readStringParam(actionParams,`userId`,{required:!0});return await handleDiscordAction({action:`voiceStatus`,accountId:accountId??void 0,guildId,userId},cfg)}if(action===`event-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0});return await handleDiscordAction({action:`eventList`,accountId:accountId??void 0,guildId},cfg)}if(action===`event-create`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),name=readStringParam(actionParams,`eventName`,{required:!0}),startTime=readStringParam(actionParams,`startTime`,{required:!0}),endTime=readStringParam(actionParams,`endTime`),description=readStringParam(actionParams,`desc`),channelId=readStringParam(actionParams,`channelId`),location=readStringParam(actionParams,`location`),entityType=readStringParam(actionParams,`eventType`);return await handleDiscordAction({action:`eventCreate`,accountId:accountId??void 0,guildId,name,startTime,endTime,description,channelId,location,entityType},cfg)}if(action===`timeout`||action===`kick`||action===`ban`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),userId=readStringParam(actionParams,`userId`,{required:!0}),durationMinutes=readNumberParam(actionParams,`durationMin`,{integer:!0}),until=readStringParam(actionParams,`until`),reason=readStringParam(actionParams,`reason`),deleteMessageDays=readNumberParam(actionParams,`deleteDays`,{integer:!0});return await handleDiscordAction({action,accountId:accountId??void 0,guildId,userId,durationMinutes,until,reason,deleteMessageDays},cfg)}if(action===`thread-list`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),channelId=readStringParam(actionParams,`channelId`),includeArchived=typeof actionParams.includeArchived==`boolean`?actionParams.includeArchived:void 0,before=readStringParam(actionParams,`before`),limit=readNumberParam(actionParams,`limit`,{integer:!0});return await handleDiscordAction({action:`threadList`,accountId:accountId??void 0,guildId,channelId,includeArchived,before,limit},cfg)}if(action===`thread-reply`){let content=readStringParam(actionParams,`message`,{required:!0}),mediaUrl=readStringParam(actionParams,`media`,{trim:!1}),replyTo=readStringParam(actionParams,`replyTo`),channelId=readStringParam(actionParams,`threadId`)??resolveChannelId();return await handleDiscordAction({action:`threadReply`,accountId:accountId??void 0,channelId,content,mediaUrl:mediaUrl??void 0,replyTo:replyTo??void 0},cfg)}if(action===`search`){let guildId=readStringParam(actionParams,`guildId`,{required:!0}),query=readStringParam(actionParams,`query`,{required:!0});return await handleDiscordAction({action:`searchMessages`,accountId:accountId??void 0,guildId,content:query,channelId:readStringParam(actionParams,`channelId`),channelIds:readStringArrayParam(actionParams,`channelIds`),authorId:readStringParam(actionParams,`authorId`),authorIds:readStringArrayParam(actionParams,`authorIds`),limit:readNumberParam(actionParams,`limit`,{integer:!0})},cfg)}}function readParentIdParam(params){return params.clearParent===!0||params.parentId===null?null:readStringParam(params,`parentId`)}async function handleDiscordMessageAction(ctx){let{action,params,cfg}=ctx,accountId=ctx.accountId??readStringParam(params,`accountId`),resolveChannelId=()=>resolveDiscordChannelId(readStringParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}));if(action===`send`){let to=readStringParam(params,`to`,{required:!0}),asVoice=params.asVoice===!0,rawComponents=params.components,hasComponents=!!rawComponents&&(typeof rawComponents==`function`||typeof rawComponents==`object`),components=hasComponents?rawComponents:void 0,content=readStringParam(params,`message`,{required:!asVoice&&!hasComponents,allowEmpty:!0}),mediaUrl=readStringParam(params,`media`,{trim:!1})??readStringParam(params,`path`,{trim:!1})??readStringParam(params,`filePath`,{trim:!1}),filename=readStringParam(params,`filename`),replyTo=readStringParam(params,`replyTo`),rawEmbeds=params.embeds,embeds=Array.isArray(rawEmbeds)?rawEmbeds:void 0,silent=params.silent===!0,sessionKey=readStringParam(params,`__sessionKey`),agentId=readStringParam(params,`__agentId`);return await handleDiscordAction({action:`sendMessage`,accountId:accountId??void 0,to,content,mediaUrl:mediaUrl??void 0,filename:filename??void 0,replyTo:replyTo??void 0,components,embeds,asVoice,silent,__sessionKey:sessionKey??void 0,__agentId:agentId??void 0},cfg)}if(action===`poll`){let to=readStringParam(params,`to`,{required:!0}),question=readStringParam(params,`pollQuestion`,{required:!0}),answers=readStringArrayParam(params,`pollOption`,{required:!0})??[],allowMultiselect=typeof params.pollMulti==`boolean`?params.pollMulti:void 0,durationHours=readNumberParam(params,`pollDurationHours`,{integer:!0});return await handleDiscordAction({action:`poll`,accountId:accountId??void 0,to,question,answers,allowMultiselect,durationHours:durationHours??void 0,content:readStringParam(params,`message`)},cfg)}if(action===`react`){let messageId=readStringParam(params,`messageId`,{required:!0}),emoji=readStringParam(params,`emoji`,{allowEmpty:!0}),remove=typeof params.remove==`boolean`?params.remove:void 0;return await handleDiscordAction({action:`react`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId,emoji,remove},cfg)}if(action===`reactions`){let messageId=readStringParam(params,`messageId`,{required:!0}),limit=readNumberParam(params,`limit`,{integer:!0});return await handleDiscordAction({action:`reactions`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId,limit},cfg)}if(action===`read`){let limit=readNumberParam(params,`limit`,{integer:!0});return await handleDiscordAction({action:`readMessages`,accountId:accountId??void 0,channelId:resolveChannelId(),limit,before:readStringParam(params,`before`),after:readStringParam(params,`after`),around:readStringParam(params,`around`)},cfg)}if(action===`edit`){let messageId=readStringParam(params,`messageId`,{required:!0}),content=readStringParam(params,`message`,{required:!0});return await handleDiscordAction({action:`editMessage`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId,content},cfg)}if(action===`delete`){let messageId=readStringParam(params,`messageId`,{required:!0});return await handleDiscordAction({action:`deleteMessage`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId},cfg)}if(action===`pin`||action===`unpin`||action===`list-pins`){let messageId=action===`list-pins`?void 0:readStringParam(params,`messageId`,{required:!0});return await handleDiscordAction({action:action===`pin`?`pinMessage`:action===`unpin`?`unpinMessage`:`listPins`,accountId:accountId??void 0,channelId:resolveChannelId(),messageId},cfg)}if(action===`permissions`)return await handleDiscordAction({action:`permissions`,accountId:accountId??void 0,channelId:resolveChannelId()},cfg);if(action===`thread-create`){let name=readStringParam(params,`threadName`,{required:!0}),messageId=readStringParam(params,`messageId`),content=readStringParam(params,`message`),autoArchiveMinutes=readNumberParam(params,`autoArchiveMin`,{integer:!0});return await handleDiscordAction({action:`threadCreate`,accountId:accountId??void 0,channelId:resolveChannelId(),name,messageId,content,autoArchiveMinutes},cfg)}if(action===`sticker`){let stickerIds=readStringArrayParam(params,`stickerId`,{required:!0,label:`sticker-id`})??[];return await handleDiscordAction({action:`sticker`,accountId:accountId??void 0,to:readStringParam(params,`to`,{required:!0}),stickerIds,content:readStringParam(params,`message`)},cfg)}if(action===`set-presence`)return await handleDiscordAction({action:`setPresence`,accountId:accountId??void 0,status:readStringParam(params,`status`),activityType:readStringParam(params,`activityType`),activityName:readStringParam(params,`activityName`),activityUrl:readStringParam(params,`activityUrl`),activityState:readStringParam(params,`activityState`)},cfg);let adminResult=await tryHandleDiscordMessageActionGuildAdmin({ctx,resolveChannelId,readParentIdParam});if(adminResult!==void 0)return adminResult;throw Error(`Action ${String(action)} is not supported for provider discord.`)}const discordMessageActions={listActions:({cfg})=>{let accounts=listEnabledDiscordAccounts(cfg).filter(account=>account.tokenSource!==`none`);if(accounts.length===0)return[];let gates=accounts.map(account=>createDiscordActionGate({cfg,accountId:account.accountId})),gate=(key,defaultValue=!0)=>gates.some(g=>g(key,defaultValue)),actions=new Set([`send`]);return gate(`polls`)&&actions.add(`poll`),gate(`reactions`)&&(actions.add(`react`),actions.add(`reactions`)),gate(`messages`)&&(actions.add(`read`),actions.add(`edit`),actions.add(`delete`)),gate(`pins`)&&(actions.add(`pin`),actions.add(`unpin`),actions.add(`list-pins`)),gate(`permissions`)&&actions.add(`permissions`),gate(`threads`)&&(actions.add(`thread-create`),actions.add(`thread-list`),actions.add(`thread-reply`)),gate(`search`)&&actions.add(`search`),gate(`stickers`)&&actions.add(`sticker`),gate(`memberInfo`)&&actions.add(`member-info`),gate(`roleInfo`)&&actions.add(`role-info`),gate(`reactions`)&&actions.add(`emoji-list`),gate(`emojiUploads`)&&actions.add(`emoji-upload`),gate(`stickerUploads`)&&actions.add(`sticker-upload`),gate(`roles`,!1)&&(actions.add(`role-add`),actions.add(`role-remove`)),gate(`channelInfo`)&&(actions.add(`channel-info`),actions.add(`channel-list`)),gate(`channels`)&&(actions.add(`channel-create`),actions.add(`channel-edit`),actions.add(`channel-delete`),actions.add(`channel-move`),actions.add(`category-create`),actions.add(`category-edit`),actions.add(`category-delete`)),gate(`voiceStatus`)&&actions.add(`voice-status`),gate(`events`)&&(actions.add(`event-list`),actions.add(`event-create`)),gate(`moderation`,!1)&&(actions.add(`timeout`),actions.add(`kick`),actions.add(`ban`)),gate(`presence`,!1)&&actions.add(`set-presence`),Array.from(actions)},extractToolSend:({args})=>{let action=typeof args.action==`string`?args.action.trim():``;if(action===`sendMessage`){let to=typeof args.to==`string`?args.to:void 0;return to?{to}:null}if(action===`threadReply`){let channelId=typeof args.channelId==`string`?args.channelId.trim():``;return channelId?{to:`channel:${channelId}`}:null}return null},handleAction:async({action,params,cfg,accountId})=>await handleDiscordMessageAction({action,params,cfg,accountId})};function normalizeSignalId(raw){let trimmed=raw.trim();return trimmed?trimmed.replace(/^signal:/i,``).trim():``}function normalizeSignalUuid(raw){let trimmed=normalizeSignalId(raw);return trimmed?trimmed.toLowerCase().startsWith(`uuid:`)?trimmed.slice(5).trim():trimmed:``}function resolveTargetAuthorParams(params){let candidates=[params.targetAuthor,params.targetAuthorUuid,params.fallback];for(let candidate of candidates){let raw=candidate?.trim();if(!raw)continue;let normalized=normalizeSignalUuid(raw);if(normalized)return{targetAuthor:normalized}}return{}}async function sendReactionSignalCore(params){let accountInfo=resolveSignalAccount({cfg:loadConfig(),accountId:params.opts.accountId}),{baseUrl,account}=resolveSignalRpcContext(params.opts,accountInfo),normalizedRecipient=normalizeSignalUuid(params.recipient),groupId=params.opts.groupId?.trim();if(!normalizedRecipient&&!groupId)throw Error(params.errors.missingRecipient);if(!Number.isFinite(params.targetTimestamp)||params.targetTimestamp<=0)throw Error(params.errors.invalidTargetTimestamp);let normalizedEmoji=params.emoji?.trim();if(!normalizedEmoji)throw Error(params.errors.missingEmoji);let targetAuthorParams=resolveTargetAuthorParams({targetAuthor:params.opts.targetAuthor,targetAuthorUuid:params.opts.targetAuthorUuid,fallback:normalizedRecipient});if(groupId&&!targetAuthorParams.targetAuthor)throw Error(params.errors.missingTargetAuthor);let requestParams={emoji:normalizedEmoji,targetTimestamp:params.targetTimestamp,...params.remove?{remove:!0}:{},...targetAuthorParams};return normalizedRecipient&&(requestParams.recipients=[normalizedRecipient]),groupId&&(requestParams.groupIds=[groupId]),account&&(requestParams.account=account),{ok:!0,timestamp:(await signalRpcRequest(`sendReaction`,requestParams,{baseUrl,timeoutMs:params.opts.timeoutMs}))?.timestamp}}async function sendReactionSignal(recipient,targetTimestamp,emoji,opts={}){return await sendReactionSignalCore({recipient,targetTimestamp,emoji,remove:!1,opts,errors:{missingRecipient:`Recipient or groupId is required for Signal reaction`,invalidTargetTimestamp:`Valid targetTimestamp is required for Signal reaction`,missingEmoji:`Emoji is required for Signal reaction`,missingTargetAuthor:`targetAuthor is required for group reactions`}})}async function removeReactionSignal(recipient,targetTimestamp,emoji,opts={}){return await sendReactionSignalCore({recipient,targetTimestamp,emoji,remove:!0,opts,errors:{missingRecipient:`Recipient or groupId is required for Signal reaction removal`,invalidTargetTimestamp:`Valid targetTimestamp is required for Signal reaction removal`,missingEmoji:`Emoji is required for Signal reaction removal`,missingTargetAuthor:`targetAuthor is required for group reaction removal`}})}function normalizeSignalReactionRecipient(raw){let trimmed=raw.trim();if(!trimmed)return trimmed;let withoutSignal=trimmed.replace(/^signal:/i,``).trim();return withoutSignal&&(withoutSignal.toLowerCase().startsWith(`uuid:`)?withoutSignal.slice(5).trim():withoutSignal)}function resolveSignalReactionTarget(raw){let trimmed=raw.trim();if(!trimmed)return{};let withoutSignal=trimmed.replace(/^signal:/i,``).trim();if(!withoutSignal)return{};if(withoutSignal.toLowerCase().startsWith(`group:`)){let groupId=withoutSignal.slice(6).trim();return groupId?{groupId}:{}}return{recipient:normalizeSignalReactionRecipient(withoutSignal)}}const signalMessageActions={listActions:({cfg})=>{let accounts=listEnabledSignalAccounts(cfg);if(accounts.length===0)return[];let configuredAccounts=accounts.filter(account=>account.configured);if(configuredAccounts.length===0)return[];let actions=new Set([`send`]);return configuredAccounts.some(account=>createActionGate(account.config.actions)(`reactions`))&&actions.add(`react`),Array.from(actions)},supportsAction:({action})=>action!==`send`,handleAction:async({action,params,cfg,accountId})=>{if(action===`send`)throw Error(`Send should be handled by outbound, not actions handler.`);if(action===`react`){let reactionLevelInfo=resolveSignalReactionLevel({cfg,accountId:accountId??void 0});if(!reactionLevelInfo.agentReactionsEnabled)throw Error(`Signal agent reactions disabled (reactionLevel="${reactionLevelInfo.level}"). Set channels.signal.reactionLevel to "minimal" or "extensive" to enable.`);let actionConfig=resolveSignalAccount({cfg,accountId}).config.actions;if(!createActionGate(actionConfig)(`reactions`))throw Error(`Signal reactions are disabled via actions.reactions.`);let target=resolveSignalReactionTarget(readStringParam(params,`recipient`)??readStringParam(params,`to`,{required:!0,label:`recipient (UUID, phone number, or group)`}));if(!target.recipient&&!target.groupId)throw Error(`recipient or group required`);let messageId=readStringParam(params,`messageId`,{required:!0,label:`messageId (timestamp)`}),targetAuthor=readStringParam(params,`targetAuthor`),targetAuthorUuid=readStringParam(params,`targetAuthorUuid`);if(target.groupId&&!targetAuthor&&!targetAuthorUuid)throw Error(`targetAuthor or targetAuthorUuid required for group reactions.`);let emoji=readStringParam(params,`emoji`,{allowEmpty:!0}),remove=typeof params.remove==`boolean`?params.remove:void 0,timestamp=parseInt(messageId,10);if(!Number.isFinite(timestamp))throw Error(`Invalid messageId: ${messageId}. Expected numeric timestamp.`);if(remove){if(!emoji)throw Error(`Emoji required to remove reaction.`);return await removeReactionSignal(target.recipient??``,timestamp,emoji,{accountId:accountId??void 0,groupId:target.groupId,targetAuthor,targetAuthorUuid}),jsonResult({ok:!0,removed:emoji})}if(!emoji)throw Error(`Emoji required to add reaction.`);return await sendReactionSignal(target.recipient??``,timestamp,emoji,{accountId:accountId??void 0,groupId:target.groupId,targetAuthor,targetAuthorUuid}),jsonResult({ok:!0,added:emoji})}throw Error(`Action ${action} not supported for signal.`)}},CACHE_FILE=path.join(STATE_DIR,`telegram`,`sticker-cache.json`);async function loadCache(){let data=await loadJsonFile(CACHE_FILE);if(!data||typeof data!=`object`)return{version:1,stickers:{}};let cache=data;return cache.version===1?cache:{version:1,stickers:{}}}async function saveCache(cache){await saveJsonFile(CACHE_FILE,cache)}async function getCachedSticker(fileUniqueId){return(await loadCache()).stickers[fileUniqueId]??null}async function cacheSticker(sticker){let cache=await loadCache();cache.stickers[sticker.fileUniqueId]=sticker,await saveCache(cache)}async function searchStickers(query,limit=10){let cache=await loadCache(),queryLower=query.toLowerCase(),results=[];for(let sticker of Object.values(cache.stickers)){let score=0,descLower=sticker.description.toLowerCase();descLower.includes(queryLower)&&(score+=10);let queryWords=queryLower.split(/\s+/).filter(Boolean),descWords=descLower.split(/\s+/);for(let qWord of queryWords)descWords.some(dWord=>dWord.includes(qWord))&&(score+=5);sticker.emoji&&query.includes(sticker.emoji)&&(score+=8),sticker.setName?.toLowerCase().includes(queryLower)&&(score+=3),score>0&&results.push({sticker,score})}return results.toSorted((a,b)=>b.score-a.score).slice(0,limit).map(r=>r.sticker)}async function getCacheStats(){let cache=await loadCache(),stickers=Object.values(cache.stickers);if(stickers.length===0)return{count:0};let sorted=[...stickers].toSorted((a,b)=>new Date(a.cachedAt).getTime()-new Date(b.cachedAt).getTime());return{count:stickers.length,oldestAt:sorted[0]?.cachedAt,newestAt:sorted[sorted.length-1]?.cachedAt}}const VISION_PROVIDERS=[`openai`,`anthropic`,`google`,`minimax`];async function describeStickerImage(params){let{imagePath,cfg,agentDir,agentId}=params,defaultModel=resolveDefaultModelForAgent({cfg,agentId}),activeModel,catalog=[];try{catalog=await loadModelCatalog({config:cfg}),modelSupportsVision(findModelInCatalog(catalog,defaultModel.provider,defaultModel.model))&&(activeModel={provider:defaultModel.provider,model:defaultModel.model})}catch{}let hasProviderKey=async provider=>{try{return await resolveApiKeyForProvider({provider,cfg,agentDir}),!0}catch{return!1}},selectCatalogModel=provider=>{let entries=catalog.filter(entry=>entry.provider.toLowerCase()===provider.toLowerCase()&&modelSupportsVision(entry));if(entries.length===0)return;let defaultId=provider===`openai`?`gpt-5-mini`:provider===`anthropic`?`claude-opus-4-6`:provider===`google`?`gemini-3-flash-preview`:`MiniMax-VL-01`;return entries.find(entry=>entry.id===defaultId)??entries[0]},resolved=null;if(activeModel&&VISION_PROVIDERS.includes(activeModel.provider)&&await hasProviderKey(activeModel.provider)&&(resolved=activeModel),!resolved)for(let provider of VISION_PROVIDERS){if(!await hasProviderKey(provider))continue;let entry=selectCatalogModel(provider);if(entry){resolved={provider,model:entry.id};break}}if(resolved||=await resolveAutoImageModel({cfg,agentDir,activeModel}),!resolved?.model)return logVerbose(`telegram: no vision provider available for sticker description`),null;let{provider,model}=resolved;logVerbose(`telegram: describing sticker with ${provider}/${model}`);try{return(await describeImageWithModel({buffer:await fs$1.readFile(imagePath),fileName:`sticker.webp`,mime:`image/webp`,prompt:`Describe this sticker image in 1-2 sentences. Focus on what the sticker depicts (character, object, action, emotion). Be concise and objective.`,cfg,agentDir:agentDir??``,provider,model,maxTokens:150,timeoutMs:3e4})).text}catch(err){return logVerbose(`telegram: failed to describe sticker: ${String(err)}`),null}}const TELEGRAM_BUTTON_STYLES=[`danger`,`success`,`primary`];function readTelegramButtons(params){let raw=params.buttons;if(raw==null)return;if(!Array.isArray(raw))throw Error(`buttons must be an array of button rows`);let filtered=raw.map((row,rowIndex)=>{if(!Array.isArray(row))throw Error(`buttons[${rowIndex}] must be an array`);return row.map((button,buttonIndex)=>{if(!button||typeof button!=`object`)throw Error(`buttons[${rowIndex}][${buttonIndex}] must be an object`);let text=typeof button.text==`string`?button.text.trim():``,callbackData=typeof button.callback_data==`string`?button.callback_data.trim():``;if(!text||!callbackData)throw Error(`buttons[${rowIndex}][${buttonIndex}] requires text and callback_data`);if(callbackData.length>64)throw Error(`buttons[${rowIndex}][${buttonIndex}] callback_data too long (max 64 chars)`);let styleRaw=button.style,style=typeof styleRaw==`string`?styleRaw.trim().toLowerCase():void 0;if(styleRaw!==void 0&&!style)throw Error(`buttons[${rowIndex}][${buttonIndex}] style must be string`);if(style&&!TELEGRAM_BUTTON_STYLES.includes(style))throw Error(`buttons[${rowIndex}][${buttonIndex}] style must be one of ${TELEGRAM_BUTTON_STYLES.join(`, `)}`);return{text,callback_data:callbackData,...style?{style}:{}}})}).filter(row=>row.length>0);return filtered.length>0?filtered:void 0}async function handleTelegramAction(params,cfg){let action=readStringParam(params,`action`,{required:!0}),accountId=readStringParam(params,`accountId`),isActionEnabled=createTelegramActionGate({cfg,accountId});if(action===`react`){let reactionLevelInfo=resolveTelegramReactionLevel({cfg,accountId:accountId??void 0});if(!reactionLevelInfo.agentReactionsEnabled)throw Error(`Telegram agent reactions disabled (reactionLevel="${reactionLevelInfo.level}"). Set channels.telegram.reactionLevel to "minimal" or "extensive" to enable.`);if(!isActionEnabled(`reactions`))throw Error(`Telegram reactions are disabled via actions.reactions.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),{emoji,remove,isEmpty}=readReactionParams(params,{removeErrorMessage:`Emoji is required to remove a Telegram reaction.`}),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let reactionResult=await reactMessageTelegram(chatId??``,messageId??0,emoji??``,{token,remove,accountId:accountId??void 0});return reactionResult.ok?jsonResult(!remove&&!isEmpty?{ok:!0,added:emoji}:{ok:!0,removed:!0}):jsonResult({ok:!1,warning:reactionResult.warning,...remove||isEmpty?{removed:!0}:{added:emoji}})}if(action===`sendMessage`){if(!isActionEnabled(`sendMessage`))throw Error(`Telegram sendMessage is disabled.`);let to=readStringParam(params,`to`,{required:!0}),mediaUrl=readStringParam(params,`mediaUrl`),content=readStringParam(params,`content`,{required:!mediaUrl,allowEmpty:!0})??``,buttons=readTelegramButtons(params);if(buttons){let inlineButtonsScope=resolveTelegramInlineButtonsScope({cfg,accountId:accountId??void 0});if(inlineButtonsScope===`off`)throw Error(`Telegram inline buttons are disabled. Set channels.telegram.capabilities.inlineButtons to "dm", "group", "all", or "allowlist".`);if(inlineButtonsScope===`dm`||inlineButtonsScope===`group`){let targetType=resolveTelegramTargetChatType(to);if(targetType===`unknown`)throw Error(`Telegram inline buttons require a numeric chat id when inlineButtons="${inlineButtonsScope}".`);if(inlineButtonsScope===`dm`&&targetType!==`direct`)throw Error(`Telegram inline buttons are limited to DMs when inlineButtons="dm".`);if(inlineButtonsScope===`group`&&targetType!==`group`)throw Error(`Telegram inline buttons are limited to groups when inlineButtons="group".`)}}let replyToMessageId=readNumberParam(params,`replyToMessageId`,{integer:!0}),messageThreadId=readNumberParam(params,`messageThreadId`,{integer:!0}),quoteText=readStringParam(params,`quoteText`),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await sendMessageTelegram(to,content,{token,accountId:accountId??void 0,mediaUrl:mediaUrl||void 0,buttons,replyToMessageId:replyToMessageId??void 0,messageThreadId:messageThreadId??void 0,quoteText:quoteText??void 0,asVoice:typeof params.asVoice==`boolean`?params.asVoice:void 0,silent:typeof params.silent==`boolean`?params.silent:void 0});return jsonResult({ok:!0,messageId:result.messageId,chatId:result.chatId})}if(action===`deleteMessage`){if(!isActionEnabled(`deleteMessage`))throw Error(`Telegram deleteMessage is disabled.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);return await deleteMessageTelegram(chatId??``,messageId??0,{token,accountId:accountId??void 0}),jsonResult({ok:!0,deleted:!0})}if(action===`editMessage`){if(!isActionEnabled(`editMessage`))throw Error(`Telegram editMessage is disabled.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),content=readStringParam(params,`content`,{required:!0,allowEmpty:!1}),buttons=readTelegramButtons(params);if(buttons&&resolveTelegramInlineButtonsScope({cfg,accountId:accountId??void 0})===`off`)throw Error(`Telegram inline buttons are disabled. Set channels.telegram.capabilities.inlineButtons to "dm", "group", "all", or "allowlist".`);let token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await editMessageTelegram(chatId??``,messageId??0,content,{token,accountId:accountId??void 0,buttons});return jsonResult({ok:!0,messageId:result.messageId,chatId:result.chatId})}if(action===`sendSticker`){if(!isActionEnabled(`sticker`,!1))throw Error(`Telegram sticker actions are disabled. Set channels.telegram.actions.sticker to true.`);let to=readStringParam(params,`to`,{required:!0}),fileId=readStringParam(params,`fileId`,{required:!0}),replyToMessageId=readNumberParam(params,`replyToMessageId`,{integer:!0}),messageThreadId=readNumberParam(params,`messageThreadId`,{integer:!0}),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await sendStickerTelegram(to,fileId,{token,accountId:accountId??void 0,replyToMessageId:replyToMessageId??void 0,messageThreadId:messageThreadId??void 0});return jsonResult({ok:!0,messageId:result.messageId,chatId:result.chatId})}if(action===`searchSticker`){if(!isActionEnabled(`sticker`,!1))throw Error(`Telegram sticker actions are disabled. Set channels.telegram.actions.sticker to true.`);let results=await searchStickers(readStringParam(params,`query`,{required:!0}),readNumberParam(params,`limit`,{integer:!0})??5);return jsonResult({ok:!0,count:results.length,stickers:results.map(s=>({fileId:s.fileId,emoji:s.emoji,description:s.description,setName:s.setName}))})}if(action===`stickerCacheStats`)return jsonResult({ok:!0,...getCacheStats()});if(action===`createForumTopic`){if(!isActionEnabled(`createForumTopic`))throw Error(`Telegram createForumTopic is disabled.`);let chatId=readStringOrNumberParam(params,`chatId`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),iconColor=readNumberParam(params,`iconColor`,{integer:!0}),iconCustomEmojiId=readStringParam(params,`iconCustomEmojiId`),token=resolveTelegramToken(cfg,{accountId}).token;if(!token)throw Error(`Telegram bot token missing. Set TELEGRAM_BOT_TOKEN or channels.telegram.botToken.`);let result=await createForumTopicTelegram(chatId??``,name,{token,accountId:accountId??void 0,iconColor:iconColor??void 0,iconCustomEmojiId:iconCustomEmojiId??void 0});return jsonResult({ok:!0,topicId:result.topicId,name:result.name,chatId:result.chatId})}throw Error(`Unsupported Telegram action: ${action}`)}function extractToolSend(args,expectedAction=`sendMessage`){if((typeof args.action==`string`?args.action.trim():``)!==expectedAction)return null;let to=typeof args.to==`string`?args.to:void 0;return to?{to,accountId:typeof args.accountId==`string`?args.accountId.trim():void 0}:null}function readTelegramSendParams(params){let to=readStringParam(params,`to`,{required:!0}),mediaUrl=readStringParam(params,`media`,{trim:!1}),message=readStringParam(params,`message`,{required:!mediaUrl,allowEmpty:!0}),caption=readStringParam(params,`caption`,{allowEmpty:!0}),content=message||caption||``,replyTo=readStringParam(params,`replyTo`),threadId=readStringParam(params,`threadId`),buttons=params.buttons,asVoice=typeof params.asVoice==`boolean`?params.asVoice:void 0,silent=typeof params.silent==`boolean`?params.silent:void 0,quoteText=readStringParam(params,`quoteText`);return{to,content,mediaUrl:mediaUrl??void 0,replyToMessageId:replyTo??void 0,messageThreadId:threadId??void 0,buttons,asVoice,silent,quoteText:quoteText??void 0}}const telegramMessageActions={listActions:({cfg})=>{let accounts=listEnabledTelegramAccounts(cfg).filter(account=>account.tokenSource!==`none`);if(accounts.length===0)return[];let gates=accounts.map(account=>createTelegramActionGate({cfg,accountId:account.accountId})),gate=(key,defaultValue=!0)=>gates.some(g=>g(key,defaultValue)),actions=new Set([`send`]);return gate(`reactions`)&&actions.add(`react`),gate(`deleteMessage`)&&actions.add(`delete`),gate(`editMessage`)&&actions.add(`edit`),gate(`sticker`,!1)&&(actions.add(`sticker`),actions.add(`sticker-search`)),gate(`createForumTopic`)&&actions.add(`topic-create`),Array.from(actions)},supportsButtons:({cfg})=>{let accounts=listEnabledTelegramAccounts(cfg).filter(account=>account.tokenSource!==`none`);return accounts.length===0?!1:accounts.some(account=>isTelegramInlineButtonsEnabled({cfg,accountId:account.accountId}))},extractToolSend:({args})=>extractToolSend(args,`sendMessage`),handleAction:async({action,params,cfg,accountId})=>{if(action===`send`)return await handleTelegramAction({action:`sendMessage`,...readTelegramSendParams(params),accountId:accountId??void 0},cfg);if(action===`react`){let messageId=readStringOrNumberParam(params,`messageId`,{required:!0}),emoji=readStringParam(params,`emoji`,{allowEmpty:!0}),remove=typeof params.remove==`boolean`?params.remove:void 0;return await handleTelegramAction({action:`react`,chatId:readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),messageId,emoji,remove,accountId:accountId??void 0},cfg)}if(action===`delete`)return await handleTelegramAction({action:`deleteMessage`,chatId:readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),messageId:readNumberParam(params,`messageId`,{required:!0,integer:!0}),accountId:accountId??void 0},cfg);if(action===`edit`){let chatId=readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),messageId=readNumberParam(params,`messageId`,{required:!0,integer:!0}),message=readStringParam(params,`message`,{required:!0,allowEmpty:!1}),buttons=params.buttons;return await handleTelegramAction({action:`editMessage`,chatId,messageId,content:message,buttons,accountId:accountId??void 0},cfg)}if(action===`sticker`){let to=readStringParam(params,`to`)??readStringParam(params,`target`,{required:!0}),fileId=readStringArrayParam(params,`stickerId`)?.[0]??readStringParam(params,`fileId`,{required:!0}),replyToMessageId=readNumberParam(params,`replyTo`,{integer:!0}),messageThreadId=readNumberParam(params,`threadId`,{integer:!0});return await handleTelegramAction({action:`sendSticker`,to,fileId,replyToMessageId:replyToMessageId??void 0,messageThreadId:messageThreadId??void 0,accountId:accountId??void 0},cfg)}if(action===`sticker-search`)return await handleTelegramAction({action:`searchSticker`,query:readStringParam(params,`query`,{required:!0}),limit:readNumberParam(params,`limit`,{integer:!0})??void 0,accountId:accountId??void 0},cfg);if(action===`topic-create`){let chatId=readStringOrNumberParam(params,`chatId`)??readStringOrNumberParam(params,`channelId`)??readStringParam(params,`to`,{required:!0}),name=readStringParam(params,`name`,{required:!0}),iconColor=readNumberParam(params,`iconColor`,{integer:!0}),iconCustomEmojiId=readStringParam(params,`iconCustomEmojiId`);return await handleTelegramAction({action:`createForumTopic`,chatId,name,iconColor:iconColor??void 0,iconCustomEmojiId:iconCustomEmojiId??void 0,accountId:accountId??void 0},cfg)}throw Error(`Action ${action} is not supported for provider telegram.`)}};function createWhatsAppLoginTool(){return{label:`WhatsApp Login`,name:`whatsapp_login`,description:`Generate a WhatsApp QR code for linking, or wait for the scan to complete.`,parameters:Type.Object({action:Type.Unsafe({type:`string`,enum:[`start`,`wait`]}),timeoutMs:Type.Optional(Type.Number()),force:Type.Optional(Type.Boolean())}),execute:async(_toolCallId,args)=>{let{startWebLoginWithQr,waitForWebLogin}=await import(`./login-qr-CbiUcBLy.js`);if((args?.action??`start`)===`wait`){let result=await waitForWebLogin({timeoutMs:typeof args.timeoutMs==`number`?args.timeoutMs:void 0});return{content:[{type:`text`,text:result.message}],details:{connected:result.connected}}}let result=await startWebLoginWithQr({timeoutMs:typeof args.timeoutMs==`number`?args.timeoutMs:void 0,force:typeof args.force==`boolean`?args.force:!1});return result.qrDataUrl?{content:[{type:`text`,text:[result.message,``,`Open WhatsApp → Linked Devices and scan:`,``,`![whatsapp-qr](${result.qrDataUrl})`].join(`
447
447
  `)}],details:{qr:!0}}:{content:[{type:`text`,text:result.message}],details:{qr:!1}}}}}async function recordInboundSession(params){let{storePath,sessionKey,ctx,groupResolution,createIfMissing}=params;recordSessionMetaFromInbound({storePath,sessionKey,ctx,groupResolution,createIfMissing}).catch(params.onRecordError);let update=params.updateLastRoute;update&&await updateLastRoute({storePath,sessionKey:update.sessionKey,deliveryContext:{channel:update.channel,to:update.to,accountId:update.accountId,threadId:update.threadId},ctx,groupResolution})}const REQUIRED_CHANNEL_PERMISSIONS=[`ViewChannel`,`SendMessages`];async function auditDiscordChannelPermissions(params){let started=Date.now(),token=params.token?.trim()??``;if(!token||params.channelIds.length===0)return{ok:!0,checkedChannels:0,unresolvedChannels:0,channels:[],elapsedMs:Date.now()-started};let required=[...REQUIRED_CHANNEL_PERMISSIONS],channels=[];for(let channelId of params.channelIds)try{let perms=await fetchChannelPermissionsDiscord(channelId,{token,accountId:params.accountId??void 0}),missing=required.filter(p=>!perms.permissions.includes(p));channels.push({channelId,ok:missing.length===0,missing:missing.length?missing:void 0,error:null,matchKey:channelId,matchSource:`id`})}catch(err){channels.push({channelId,ok:!1,error:err instanceof Error?err.message:String(err),matchKey:channelId,matchSource:`id`})}return{ok:channels.every(c=>c.ok),checkedChannels:channels.length,unresolvedChannels:0,channels,elapsedMs:Date.now()-started}}const DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS=30*1e3,DISCORD_CHANNEL_INFO_CACHE=new Map;function normalizeDiscordChannelId(value){return typeof value==`string`?value.trim():typeof value==`number`||typeof value==`bigint`?String(value).trim():``}function resolveDiscordMessageChannelId(params){let message=params.message;return normalizeDiscordChannelId(message.channelId)||normalizeDiscordChannelId(message.channel_id)||normalizeDiscordChannelId(message.rawData?.channel_id)||normalizeDiscordChannelId(params.eventChannelId)}async function resolveDiscordChannelInfo(client,channelId){let cached=DISCORD_CHANNEL_INFO_CACHE.get(channelId);if(cached){if(cached.expiresAt>Date.now())return cached.value;DISCORD_CHANNEL_INFO_CACHE.delete(channelId)}try{let channel=await client.fetchChannel(channelId);if(!channel)return DISCORD_CHANNEL_INFO_CACHE.set(channelId,{value:null,expiresAt:Date.now()+DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS}),null;let name=`name`in channel?channel.name??void 0:void 0,topic=`topic`in channel?channel.topic??void 0:void 0,parentId=`parentId`in channel?channel.parentId??void 0:void 0,ownerId=`ownerId`in channel?channel.ownerId??void 0:void 0,payload={type:channel.type,name,topic,parentId,ownerId};return DISCORD_CHANNEL_INFO_CACHE.set(channelId,{value:payload,expiresAt:Date.now()+3e5}),payload}catch(err){return logVerbose(`discord: failed to fetch channel ${channelId}: ${String(err)}`),DISCORD_CHANNEL_INFO_CACHE.set(channelId,{value:null,expiresAt:Date.now()+DISCORD_CHANNEL_INFO_NEGATIVE_CACHE_TTL_MS}),null}}async function resolveMediaList(message,maxBytes){let attachments=message.attachments??[];if(attachments.length===0)return[];let out=[];return await appendResolvedMediaFromAttachments({attachments,maxBytes,out,errorPrefix:`discord: failed to download attachment`}),out}async function resolveForwardedMediaList(message,maxBytes){let snapshots=resolveDiscordMessageSnapshots(message);if(snapshots.length===0)return[];let out=[];for(let snapshot of snapshots)await appendResolvedMediaFromAttachments({attachments:snapshot.message?.attachments,maxBytes,out,errorPrefix:`discord: failed to download forwarded attachment`});return out}async function appendResolvedMediaFromAttachments(params){let attachments=params.attachments;if(!(!attachments||attachments.length===0))for(let attachment of attachments)try{let fetched=await fetchRemoteMedia({url:attachment.url,filePathHint:attachment.filename??attachment.url}),saved=await saveMediaBuffer(fetched.buffer,fetched.contentType??attachment.content_type,`inbound`,params.maxBytes);params.out.push({path:saved.path,contentType:saved.contentType,placeholder:inferPlaceholder(attachment)})}catch(err){let id=attachment.id??attachment.url;logVerbose(`${params.errorPrefix} ${id}: ${String(err)}`)}}function inferPlaceholder(attachment){let mime=attachment.content_type??``;return mime.startsWith(`image/`)?`<media:image>`:mime.startsWith(`video/`)?`<media:video>`:mime.startsWith(`audio/`)?`<media:audio>`:`<media:document>`}function isImageAttachment(attachment){if((attachment.content_type??``).startsWith(`image/`))return!0;let name=attachment.filename?.toLowerCase()??``;return name?/\.(avif|bmp|gif|heic|heif|jpe?g|png|tiff?|webp)$/.test(name):!1}function buildDiscordAttachmentPlaceholder(attachments){if(!attachments||attachments.length===0)return``;let count=attachments.length,allImages=attachments.every(isImageAttachment),label=allImages?`image`:`file`,suffix=count===1?label:`${label}s`;return`${allImages?`<media:image>`:`<media:document>`} (${count} ${suffix})`}function resolveDiscordMessageText(message,options){let baseText=message.content?.trim()||buildDiscordAttachmentPlaceholder(message.attachments)||message.embeds?.[0]?.description||options?.fallbackText?.trim()||``;if(!options?.includeForwarded)return baseText;let forwardedText=resolveDiscordForwardedMessagesText(message);return forwardedText?baseText?`${baseText}\n${forwardedText}`:forwardedText:baseText}function resolveDiscordForwardedMessagesText(message){let snapshots=resolveDiscordMessageSnapshots(message);if(snapshots.length===0)return``;let forwardedBlocks=snapshots.map(snapshot=>{let snapshotMessage=snapshot.message;if(!snapshotMessage)return null;let text=resolveDiscordSnapshotMessageText(snapshotMessage);if(!text)return null;let authorLabel=formatDiscordSnapshotAuthor(snapshotMessage.author);return`${authorLabel?`[Forwarded message from ${authorLabel}]`:`[Forwarded message]`}\n${text}`}).filter(entry=>!!entry);return forwardedBlocks.length===0?``:forwardedBlocks.join(`
448
448
 
449
449
  `)}function resolveDiscordMessageSnapshots(message){let snapshots=message.rawData?.message_snapshots??message.message_snapshots??message.messageSnapshots;return Array.isArray(snapshots)?snapshots.filter(entry=>!!entry&&typeof entry==`object`):[]}function resolveDiscordSnapshotMessageText(snapshot){let content=snapshot.content?.trim()??``,attachmentText=buildDiscordAttachmentPlaceholder(snapshot.attachments??void 0),embed=snapshot.embeds?.[0],embedText=embed?.description?.trim()||embed?.title?.trim()||``;return content||attachmentText||embedText||``}function formatDiscordSnapshotAuthor(author){if(!author)return;let globalName=author.global_name??void 0,username=author.username??void 0,name=author.name??void 0,discriminator=author.discriminator??void 0,base=globalName||username||name;if(username&&discriminator&&discriminator!==`0`)return`@${username}#${discriminator}`;if(base)return`@${base}`;if(author.id)return`@${author.id}`}function buildDiscordMediaPayload(mediaList){let first=mediaList[0],mediaPaths=mediaList.map(media=>media.path),mediaTypes=mediaList.map(media=>media.contentType).filter(Boolean);return{MediaPath:first?.path,MediaType:first?.contentType,MediaUrl:first?.path,MediaPaths:mediaPaths.length>0?mediaPaths:void 0,MediaUrls:mediaPaths.length>0?mediaPaths:void 0,MediaTypes:mediaTypes.length>0?mediaTypes:void 0}}const discordEventQueueLog=createSubsystemLogger(`discord/event-queue`);function logSlowDiscordListener(params){if(params.durationMs<3e4)return;let duration=formatDurationSeconds(params.durationMs,{decimals:1,unit:`seconds`}),message=`Slow listener detected: ${params.listener} took ${duration} for event ${params.event}`;(params.logger??discordEventQueueLog).warn(`Slow listener detected`,{listener:params.listener,event:params.event,durationMs:params.durationMs,duration,consoleMessage:message})}function registerDiscordListener(listeners,listener){return listeners.some(existing=>existing.constructor===listener.constructor)?!1:(listeners.push(listener),!0)}var DiscordMessageListener=class extends MessageCreateListener{constructor(handler,logger){super(),this.handler=handler,this.logger=logger}async handle(data,client){let startedAt=Date.now();Promise.resolve(this.handler(data,client)).catch(err=>{(this.logger??discordEventQueueLog).error(danger(`discord handler failed: ${String(err)}`))}).finally(()=>{logSlowDiscordListener({logger:this.logger,listener:this.constructor.name,event:this.type,durationMs:Date.now()-startedAt})})}},DiscordReactionListener=class extends MessageReactionAddListener{constructor(params){super(),this.params=params}async handle(data,client){await runDiscordReactionHandler({data,client,action:`added`,handlerParams:this.params,listener:this.constructor.name,event:this.type})}},DiscordReactionRemoveListener=class extends MessageReactionRemoveListener{constructor(params){super(),this.params=params}async handle(data,client){await runDiscordReactionHandler({data,client,action:`removed`,handlerParams:this.params,listener:this.constructor.name,event:this.type})}};async function runDiscordReactionHandler(params){let startedAt=Date.now();try{await handleDiscordReactionEvent({data:params.data,client:params.client,action:params.action,cfg:params.handlerParams.cfg,accountId:params.handlerParams.accountId,botUserId:params.handlerParams.botUserId,guildEntries:params.handlerParams.guildEntries,logger:params.handlerParams.logger})}finally{logSlowDiscordListener({logger:params.handlerParams.logger,listener:params.listener,event:params.event,durationMs:Date.now()-startedAt})}}async function handleDiscordReactionEvent(params){try{let{data,client,action,botUserId,guildEntries}=params;if(!(`user`in data))return;let user=data.user;if(!user||user.bot||botUserId&&user.id===botUserId)return;let isGuildMessage=!!data.guild_id,guildInfo=isGuildMessage?resolveDiscordGuildEntry({guild:data.guild??void 0,guildEntries}):null;if(isGuildMessage&&guildEntries&&Object.keys(guildEntries).length>0&&!guildInfo)return;let channel=await client.fetchChannel(data.channel_id);if(!channel)return;let channelName=`name`in channel?channel.name??void 0:void 0,channelSlug=channelName?normalizeDiscordSlug(channelName):``,channelType=`type`in channel?channel.type:void 0,isDirectMessage=channelType===ChannelType.DM,isGroupDm=channelType===ChannelType.GroupDM,isThreadChannel=channelType===ChannelType.PublicThread||channelType===ChannelType.PrivateThread||channelType===ChannelType.AnnouncementThread,parentId=`parentId`in channel?channel.parentId??void 0:void 0,parentName,parentSlug=``,memberRoleIds=Array.isArray(data.rawMember?.roles)?data.rawMember.roles.map(roleId=>String(roleId)):[],reactionBase=null,resolveReactionBase=()=>{if(reactionBase)return reactionBase;let emojiLabel=formatDiscordReactionEmoji(data.emoji);return reactionBase={baseText:`Discord reaction ${action}: ${emojiLabel} by ${formatDiscordUserTag(user)} on ${guildInfo?.slug||(data.guild?.name?normalizeDiscordSlug(data.guild.name):data.guild_id??(isGroupDm?`group-dm`:`dm`))} ${channelSlug?`#${channelSlug}`:channelName?`#${normalizeDiscordSlug(channelName)}`:`#${data.channel_id}`} msg ${data.message_id}`,contextKey:`discord:reaction:${action}:${data.message_id}:${user.id}:${emojiLabel}`},reactionBase},emitReaction=(text,parentPeerId)=>{let{contextKey}=resolveReactionBase();enqueueSystemEvent(text,{sessionKey:resolveAgentRoute({cfg:params.cfg,channel:`discord`,accountId:params.accountId,guildId:data.guild_id??void 0,memberRoleIds,peer:{kind:isDirectMessage?`direct`:isGroupDm?`group`:`channel`,id:isDirectMessage?user.id:data.channel_id},parentPeer:parentPeerId?{kind:`channel`,id:parentPeerId}:void 0}).sessionKey,contextKey})},shouldNotifyReaction=options=>shouldEmitDiscordReactionNotification({mode:options.mode,botId:botUserId,messageAuthorId:options.messageAuthorId,userId:user.id,userName:user.username,userTag:formatDiscordUserTag(user),allowlist:guildInfo?.users}),emitReactionWithAuthor=message=>{let{baseText}=resolveReactionBase(),authorLabel=message?.author?formatDiscordUserTag(message.author):void 0;emitReaction(authorLabel?`${baseText} from ${authorLabel}`:baseText,parentId)},loadThreadParentInfo=async()=>{parentId&&(parentName=(await resolveDiscordChannelInfo(client,parentId))?.name,parentSlug=parentName?normalizeDiscordSlug(parentName):``)},resolveThreadChannelConfig=()=>resolveDiscordChannelConfigWithFallback({guildInfo,channelId:data.channel_id,channelName,channelSlug,parentId,parentName,parentSlug,scope:`thread`});if(isThreadChannel){let reactionMode=guildInfo?.reactionNotifications??`own`;if(reactionMode===`off`)return;let channelInfoPromise=parentId?Promise.resolve({parentId}):resolveDiscordChannelInfo(client,data.channel_id);if(reactionMode===`all`||reactionMode===`allowlist`){if(parentId=(await channelInfoPromise)?.parentId,await loadThreadParentInfo(),resolveThreadChannelConfig()?.allowed===!1||reactionMode===`allowlist`&&!shouldNotifyReaction({mode:reactionMode}))return;let{baseText}=resolveReactionBase();emitReaction(baseText,parentId);return}let messagePromise=data.message.fetch().catch(()=>null),[channelInfo,message]=await Promise.all([channelInfoPromise,messagePromise]);if(parentId=channelInfo?.parentId,await loadThreadParentInfo(),resolveThreadChannelConfig()?.allowed===!1||!shouldNotifyReaction({mode:reactionMode,messageAuthorId:message?.author?.id??void 0}))return;emitReactionWithAuthor(message);return}if(resolveDiscordChannelConfigWithFallback({guildInfo,channelId:data.channel_id,channelName,channelSlug,parentId,parentName,parentSlug,scope:`channel`})?.allowed===!1)return;let reactionMode=guildInfo?.reactionNotifications??`own`;if(reactionMode===`off`)return;if(reactionMode===`all`||reactionMode===`allowlist`){if(reactionMode===`allowlist`&&!shouldNotifyReaction({mode:reactionMode}))return;let{baseText}=resolveReactionBase();emitReaction(baseText,parentId);return}let message=await data.message.fetch().catch(()=>null);if(!shouldNotifyReaction({mode:reactionMode,messageAuthorId:message?.author?.id??void 0}))return;emitReactionWithAuthor(message)}catch(err){params.logger.error(danger(`discord reaction handler failed: ${String(err)}`))}}var DiscordPresenceListener=class extends PresenceUpdateListener{constructor(params){super(),this.logger=params.logger,this.accountId=params.accountId}async handle(data){try{let userId=`user`in data&&data.user&&typeof data.user==`object`&&`id`in data.user?String(data.user.id):void 0;if(!userId)return;setPresence(this.accountId,userId,data)}catch(err){(this.logger??discordEventQueueLog).error(danger(`discord presence handler failed: ${String(err)}`))}}};const DEFAULT_GROUP_HISTORY_LIMIT=50;function evictOldHistoryKeys(historyMap,maxKeys=1e3){if(historyMap.size<=maxKeys)return;let keysToDelete=historyMap.size-maxKeys,iterator=historyMap.keys();for(let i=0;i<keysToDelete;i++){let key=iterator.next().value;key!==void 0&&historyMap.delete(key)}}function buildHistoryContext(params){let{historyText,currentMessage}=params,lineBreak=params.lineBreak??`
450
450
  `;return historyText.trim()?[`[Chat messages since your last reply - for context]`,historyText,``,CURRENT_MESSAGE_MARKER,currentMessage].join(lineBreak):currentMessage}function appendHistoryEntry(params){let{historyMap,historyKey,entry}=params;if(params.limit<=0)return[];let history=historyMap.get(historyKey)??[];for(history.push(entry);history.length>params.limit;)history.shift();return historyMap.has(historyKey)&&historyMap.delete(historyKey),historyMap.set(historyKey,history),evictOldHistoryKeys(historyMap),history}function recordPendingHistoryEntry(params){return appendHistoryEntry(params)}function recordPendingHistoryEntryIfEnabled(params){return!params.entry||params.limit<=0?[]:recordPendingHistoryEntry({historyMap:params.historyMap,historyKey:params.historyKey,entry:params.entry,limit:params.limit})}function buildPendingHistoryContextFromMap(params){return params.limit<=0?params.currentMessage:buildHistoryContextFromEntries({entries:params.historyMap.get(params.historyKey)??[],currentMessage:params.currentMessage,formatEntry:params.formatEntry,lineBreak:params.lineBreak,excludeLast:!1})}function clearHistoryEntries(params){params.historyMap.set(params.historyKey,[])}function clearHistoryEntriesIfEnabled(params){params.limit<=0||clearHistoryEntries({historyMap:params.historyMap,historyKey:params.historyKey})}function buildHistoryContextFromEntries(params){let lineBreak=params.lineBreak??`
451
451
  `,entries=params.excludeLast===!1?params.entries:params.entries.slice(0,-1);return entries.length===0?params.currentMessage:buildHistoryContext({historyText:entries.map(params.formatEntry).join(lineBreak),currentMessage:params.currentMessage,lineBreak})}function logInboundDrop(params){let target=params.target?` target=${params.target}`:``;params.log(`${params.channel}: drop ${params.reason}${target}`)}function logTypingFailure(params){let target=params.target?` target=${params.target}`:``,action=params.action?` action=${params.action}`:``;params.log(`${params.channel} typing${action} failed${target}: ${String(params.error)}`)}function logAckFailure(params){let target=params.target?` target=${params.target}`:``;params.log(`${params.channel} ack cleanup failed${target}: ${String(params.error)}`)}function resolveMentionGating(params){let implicit=params.implicitMention===!0,bypass=params.shouldBypassMention===!0,effectiveWasMentioned=params.wasMentioned||implicit||bypass;return{effectiveWasMentioned,shouldSkip:params.requireMention&&params.canDetectMention&&!effectiveWasMentioned}}function resolveMentionGatingWithBypass(params){let shouldBypassMention=params.isGroup&&params.requireMention&&!params.wasMentioned&&!(params.hasAnyMention??!1)&&params.allowTextCommands&&params.commandAuthorized&&params.hasControlCommand;return{...resolveMentionGating({requireMention:params.requireMention,canDetectMention:params.canDetectMention,wasMentioned:params.wasMentioned,implicitMention:params.implicitMention,shouldBypassMention}),shouldBypassMention}}function buildPairingReply(params){let{channel,idLine,code}=params;return[`BuilderForceAgents: access not configured.`,``,idLine,``,`Pairing code: ${code}`,``,`Ask the bot owner to approve with:`,formatCliCommand(`builderforce pairing approve ${channel} ${code}`)].join(`
452
- `)}async function fetchPluralKitMessageInfo(params){if(!params.config?.enabled)return null;let fetchImpl=resolveFetch(params.fetcher);if(!fetchImpl)return null;let headers={};params.config.token?.trim()&&(headers.Authorization=params.config.token.trim());let res=await fetchImpl(`https://api.pluralkit.me/v2/messages/${params.messageId}`,{headers});if(res.status===404)return null;if(!res.ok){let text=await res.text().catch(()=>``),detail=text.trim()?`: ${text.trim()}`:``;throw Error(`PluralKit API failed (${res.status})${detail}`)}return await res.json()}function resolveDiscordWebhookId(message){let candidate=message.webhookId??message.webhook_id;return typeof candidate==`string`&&candidate.trim()?candidate.trim():null}function resolveDiscordSenderIdentity(params){let pkInfo=params.pluralkitInfo??null,pkMember=pkInfo?.member??void 0,pkSystem=pkInfo?.system??void 0,memberId=pkMember?.id?.trim(),memberName=(pkMember?.display_name??pkMember?.name??``)?.trim();if(memberId&&memberName){let systemName=pkSystem?.name?.trim(),label=systemName?`${memberName} (PK:${systemName})`:`${memberName} (PK)`;return{id:memberId,name:memberName,tag:pkMember?.name?.trim()||void 0,label,isPluralKit:!0,pluralkit:{memberId,memberName,systemId:pkSystem?.id?.trim()||void 0,systemName}}}let senderTag=formatDiscordUserTag(params.author),senderDisplay=params.member?.nickname??params.author.globalName??params.author.username,senderLabel=senderDisplay&&senderTag&&senderDisplay!==senderTag?`${senderDisplay} (${senderTag})`:senderDisplay??senderTag??params.author.id;return{id:params.author.id,name:params.author.username??void 0,tag:senderTag,label:senderLabel,isPluralKit:!1}}function resolveDiscordSystemEvent(message,location){switch(message.type){case MessageType.ChannelPinnedMessage:return buildDiscordSystemEvent(message,location,`pinned a message`);case MessageType.RecipientAdd:return buildDiscordSystemEvent(message,location,`added a recipient`);case MessageType.RecipientRemove:return buildDiscordSystemEvent(message,location,`removed a recipient`);case MessageType.UserJoin:return buildDiscordSystemEvent(message,location,`user joined`);case MessageType.GuildBoost:return buildDiscordSystemEvent(message,location,`boosted the server`);case MessageType.GuildBoostTier1:return buildDiscordSystemEvent(message,location,`boosted the server (Tier 1 reached)`);case MessageType.GuildBoostTier2:return buildDiscordSystemEvent(message,location,`boosted the server (Tier 2 reached)`);case MessageType.GuildBoostTier3:return buildDiscordSystemEvent(message,location,`boosted the server (Tier 3 reached)`);case MessageType.ThreadCreated:return buildDiscordSystemEvent(message,location,`created a thread`);case MessageType.AutoModerationAction:return buildDiscordSystemEvent(message,location,`auto moderation action`);case MessageType.GuildIncidentAlertModeEnabled:return buildDiscordSystemEvent(message,location,`raid protection enabled`);case MessageType.GuildIncidentAlertModeDisabled:return buildDiscordSystemEvent(message,location,`raid protection disabled`);case MessageType.GuildIncidentReportRaid:return buildDiscordSystemEvent(message,location,`raid reported`);case MessageType.GuildIncidentReportFalseAlarm:return buildDiscordSystemEvent(message,location,`raid report marked false alarm`);case MessageType.StageStart:return buildDiscordSystemEvent(message,location,`stage started`);case MessageType.StageEnd:return buildDiscordSystemEvent(message,location,`stage ended`);case MessageType.StageSpeaker:return buildDiscordSystemEvent(message,location,`stage speaker updated`);case MessageType.StageTopic:return buildDiscordSystemEvent(message,location,`stage topic updated`);case MessageType.PollResult:return buildDiscordSystemEvent(message,location,`poll results posted`);case MessageType.PurchaseNotification:return buildDiscordSystemEvent(message,location,`purchase notification`);default:return null}}function buildDiscordSystemEvent(message,location,action){let authorLabel=message.author?formatDiscordUserTag(message.author):``;return`Discord system: ${authorLabel?`${authorLabel} `:``}${action} in ${location}`}const DISCORD_THREAD_STARTER_CACHE=new Map;function getCachedThreadStarter(key,now){let entry=DISCORD_THREAD_STARTER_CACHE.get(key);if(entry){if(now-entry.updatedAt>3e5){DISCORD_THREAD_STARTER_CACHE.delete(key);return}return DISCORD_THREAD_STARTER_CACHE.delete(key),DISCORD_THREAD_STARTER_CACHE.set(key,{...entry,updatedAt:now}),entry.value}}function setCachedThreadStarter(key,value,now){for(DISCORD_THREAD_STARTER_CACHE.delete(key),DISCORD_THREAD_STARTER_CACHE.set(key,{value,updatedAt:now});DISCORD_THREAD_STARTER_CACHE.size>500;){let iter=DISCORD_THREAD_STARTER_CACHE.keys().next();if(iter.done)break;DISCORD_THREAD_STARTER_CACHE.delete(iter.value)}}function isDiscordThreadType(type){return type===ChannelType.PublicThread||type===ChannelType.PrivateThread||type===ChannelType.AnnouncementThread}function resolveDiscordThreadChannel(params){if(!params.isGuildMessage)return null;let{message,channelInfo}=params,channel=`channel`in message?message.channel:void 0;if(channel&&typeof channel==`object`&&`isThread`in channel&&typeof channel.isThread==`function`&&channel.isThread())return channel;if(!isDiscordThreadType(channelInfo?.type))return null;let messageChannelId=params.messageChannelId||resolveDiscordMessageChannelId({message});return messageChannelId?{id:messageChannelId,name:channelInfo?.name??void 0,parentId:channelInfo?.parentId??void 0,parent:void 0,ownerId:channelInfo?.ownerId??void 0}:null}async function resolveDiscordThreadParentInfo(params){let{threadChannel,channelInfo,client}=params,parentId=threadChannel.parentId??threadChannel.parent?.id??channelInfo?.parentId??void 0;if(!parentId)return{};let parentName=threadChannel.parent?.name,parentInfo=await resolveDiscordChannelInfo(client,parentId);parentName??=parentInfo?.name;let parentType=parentInfo?.type;return{id:parentId,name:parentName,type:parentType}}async function resolveDiscordThreadStarter(params){let cacheKey=params.channel.id,cached=getCachedThreadStarter(cacheKey,Date.now());if(cached)return cached;try{let parentType=params.parentType,messageChannelId=parentType===ChannelType.GuildForum||parentType===ChannelType.GuildMedia?params.channel.id:params.parentId;if(!messageChannelId)return null;let starter=await params.client.rest.get(Routes.channelMessage(messageChannelId,params.channel.id));if(!starter)return null;let text=starter.content?.trim()??starter.embeds?.[0]?.description?.trim()??``;if(!text)return null;let payload={text,author:starter.member?.nick??starter.member?.displayName??(starter.author?starter.author.discriminator&&starter.author.discriminator!==`0`?`${starter.author.username??`Unknown`}#${starter.author.discriminator}`:starter.author.username??starter.author.id??`Unknown`:`Unknown`),timestamp:params.resolveTimestampMs(starter.timestamp)??void 0};return setCachedThreadStarter(cacheKey,payload,Date.now()),payload}catch{return null}}function sanitizeDiscordThreadName(rawName,fallbackId){return truncateUtf16Safe(truncateUtf16Safe(rawName.replace(/<@!?\d+>/g,``).replace(/<@&\d+>/g,``).replace(/<#\d+>/g,``).replace(/\s+/g,` `).trim()||`Thread ${fallbackId}`,80),100)||`Thread ${fallbackId}`}function resolveDiscordAutoThreadContext(params){let createdThreadId=String(params.createdThreadId??``).trim();if(!createdThreadId)return null;let messageChannelId=params.messageChannelId.trim();if(!messageChannelId)return null;let threadSessionKey=buildAgentSessionKey({agentId:params.agentId,channel:params.channel,peer:{kind:`channel`,id:createdThreadId}}),parentSessionKey=buildAgentSessionKey({agentId:params.agentId,channel:params.channel,peer:{kind:`channel`,id:messageChannelId}});return{createdThreadId,From:`${params.channel}:channel:${createdThreadId}`,To:`channel:${createdThreadId}`,OriginatingTo:`channel:${createdThreadId}`,SessionKey:threadSessionKey,ParentSessionKey:parentSessionKey}}async function resolveDiscordAutoThreadReplyPlan(params){let messageChannelId=(params.messageChannelId||resolveDiscordMessageChannelId({message:params.message})).trim(),originalReplyTarget=`channel:${params.threadChannel?.id??(messageChannelId||`unknown`)}`,createdThreadId=await maybeCreateDiscordAutoThread({client:params.client,message:params.message,messageChannelId:messageChannelId||void 0,isGuildMessage:params.isGuildMessage,channelConfig:params.channelConfig,threadChannel:params.threadChannel,channelType:params.channelType,baseText:params.baseText,combinedBody:params.combinedBody}),deliveryPlan=resolveDiscordReplyDeliveryPlan({replyTarget:originalReplyTarget,replyToMode:params.replyToMode,messageId:params.message.id,threadChannel:params.threadChannel,createdThreadId}),autoThreadContext=params.isGuildMessage?resolveDiscordAutoThreadContext({agentId:params.agentId,channel:params.channel,messageChannelId,createdThreadId}):null;return{...deliveryPlan,createdThreadId,autoThreadContext}}async function maybeCreateDiscordAutoThread(params){if(!params.isGuildMessage||!params.channelConfig?.autoThread||params.threadChannel||params.channelType===ChannelType.GuildForum||params.channelType===ChannelType.GuildMedia||params.channelType===ChannelType.GuildVoice||params.channelType===ChannelType.GuildStageVoice)return;let messageChannelId=(params.messageChannelId||resolveDiscordMessageChannelId({message:params.message})).trim();if(messageChannelId)try{let threadName=sanitizeDiscordThreadName(params.baseText||params.combinedBody||`Thread`,params.message.id),created=await params.client.rest.post(`${Routes.channelMessage(messageChannelId,params.message.id)}/threads`,{body:{name:threadName,auto_archive_duration:60}});return(created?.id?String(created.id):``)||void 0}catch(err){logVerbose(`discord: autoThread creation failed for ${messageChannelId}/${params.message.id}: ${String(err)}`);try{let msg=await params.client.rest.get(Routes.channelMessage(messageChannelId,params.message.id)),existingThreadId=msg?.thread?.id?String(msg.thread.id):``;if(existingThreadId)return logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`),existingThreadId}catch{}return}}function resolveDiscordReplyDeliveryPlan(params){let originalReplyTarget=params.replyTarget,deliverTarget=originalReplyTarget,replyTarget=originalReplyTarget;params.createdThreadId&&(deliverTarget=`channel:${params.createdThreadId}`,replyTarget=deliverTarget);let allowReference=deliverTarget===originalReplyTarget,replyReference=createReplyReferencePlanner({replyToMode:allowReference?params.replyToMode:`off`,existingId:params.threadChannel?params.messageId:void 0,startId:params.messageId,allowReference});return{deliverTarget,replyTarget,replyReference}}async function preflightDiscordMessage(params){let logger=getChildLogger({module:`discord-auto-reply`}),message=params.data.message,author=params.data.author;if(!author)return null;let messageChannelId=resolveDiscordMessageChannelId({message,eventChannelId:params.data.channel_id});if(!messageChannelId)return logVerbose(`discord: drop message ${message.id} (missing channel id)`),null;let allowBots=params.discordConfig?.allowBots??!1;if(params.botUserId&&author.id===params.botUserId)return null;let pluralkitConfig=params.discordConfig?.pluralkit,webhookId=resolveDiscordWebhookId(message),shouldCheckPluralKit=!!pluralkitConfig?.enabled&&!webhookId,pluralkitInfo=null;if(shouldCheckPluralKit)try{pluralkitInfo=await fetchPluralKitMessageInfo({messageId:message.id,config:pluralkitConfig})}catch(err){logVerbose(`discord: pluralkit lookup failed for ${message.id}: ${String(err)}`)}let sender=resolveDiscordSenderIdentity({author,member:params.data.member,pluralkitInfo});if(author.bot&&!allowBots&&!sender.isPluralKit)return logVerbose(`discord: drop bot message (allowBots=false)`),null;let isGuildMessage=!!params.data.guild_id,channelInfo=await resolveDiscordChannelInfo(params.client,messageChannelId),isDirectMessage=channelInfo?.type===ChannelType.DM,isGroupDm=channelInfo?.type===ChannelType.GroupDM;if(logDebug(`[discord-preflight] channelId=${messageChannelId} guild_id=${params.data.guild_id} channelType=${channelInfo?.type} isGuild=${isGuildMessage} isDM=${isDirectMessage} isGroupDm=${isGroupDm}`),isGroupDm&&!params.groupDmEnabled)return logVerbose(`discord: drop group dm (group dms disabled)`),null;if(isDirectMessage&&!params.dmEnabled)return logVerbose(`discord: drop dm (dms disabled)`),null;let dmPolicy=params.discordConfig?.dmPolicy??params.discordConfig?.dm?.policy??`pairing`,commandAuthorized=!0;if(isDirectMessage){if(dmPolicy===`disabled`)return logVerbose(`discord: drop dm (dmPolicy: disabled)`),null;if(dmPolicy!==`open`){let storeAllowFrom=await readChannelAllowFromStore(`discord`).catch(()=>[]),allowList=normalizeDiscordAllowList([...params.allowFrom??[],...storeAllowFrom],[`discord:`,`user:`,`pk:`]),allowMatch=allowList?resolveDiscordAllowListMatch({allowList,candidate:{id:sender.id,name:sender.name,tag:sender.tag}}):{allowed:!1},allowMatchMeta=formatAllowlistMatchMeta(allowMatch);if(!allowMatch.allowed){if(commandAuthorized=!1,dmPolicy===`pairing`){let{code,created}=await upsertChannelPairingRequest({channel:`discord`,id:author.id,meta:{tag:formatDiscordUserTag(author),name:author.username??void 0}});if(created){logVerbose(`discord pairing request sender=${author.id} tag=${formatDiscordUserTag(author)} (${allowMatchMeta})`);try{await sendMessageDiscord(`user:${author.id}`,buildPairingReply({channel:`discord`,idLine:`Your Discord user id: ${author.id}`,code}),{token:params.token,rest:params.client.rest,accountId:params.accountId})}catch(err){logVerbose(`discord pairing reply failed for ${author.id}: ${String(err)}`)}}}else logVerbose(`Blocked unauthorized discord sender ${sender.id} (dmPolicy=${dmPolicy}, ${allowMatchMeta})`);return null}commandAuthorized=!0}}let botId=params.botUserId,baseText=resolveDiscordMessageText(message,{includeForwarded:!1}),messageText=resolveDiscordMessageText(message,{includeForwarded:!0});recordChannelActivity({channel:`discord`,accountId:params.accountId,direction:`inbound`});let channelName=channelInfo?.name??((isGuildMessage||isGroupDm)&&message.channel&&`name`in message.channel?message.channel.name:void 0),earlyThreadChannel=resolveDiscordThreadChannel({isGuildMessage,message,channelInfo,messageChannelId}),earlyThreadParentId,earlyThreadParentName,earlyThreadParentType;if(earlyThreadChannel){let parentInfo=await resolveDiscordThreadParentInfo({client:params.client,threadChannel:earlyThreadChannel,channelInfo});earlyThreadParentId=parentInfo.id,earlyThreadParentName=parentInfo.name,earlyThreadParentType=parentInfo.type}let memberRoleIds=Array.isArray(params.data.rawMember?.roles)?params.data.rawMember.roles.map(roleId=>String(roleId)):[],route=resolveAgentRoute({cfg:loadConfig(),channel:`discord`,accountId:params.accountId,guildId:params.data.guild_id??void 0,memberRoleIds,peer:{kind:isDirectMessage?`direct`:isGroupDm?`group`:`channel`,id:isDirectMessage?author.id:messageChannelId},parentPeer:earlyThreadParentId?{kind:`channel`,id:earlyThreadParentId}:void 0}),mentionRegexes=buildMentionRegexes(params.cfg,route.agentId),explicitlyMentioned=!!(botId&&message.mentionedUsers?.some(user=>user.id===botId)),hasAnyMention=!!(!isDirectMessage&&(message.mentionedEveryone||(message.mentionedUsers?.length??0)>0||(message.mentionedRoles?.length??0)>0));if(isGuildMessage&&(message.type===MessageType.ChatInputCommand||message.type===MessageType.ContextMenuCommand))return logVerbose(`discord: drop channel command message`),null;let guildInfo=isGuildMessage?resolveDiscordGuildEntry({guild:params.data.guild??void 0,guildEntries:params.guildEntries}):null;if(logDebug(`[discord-preflight] guild_id=${params.data.guild_id} guild_obj=${!!params.data.guild} guild_obj_id=${params.data.guild?.id} guildInfo=${!!guildInfo} guildEntries=${params.guildEntries?Object.keys(params.guildEntries).join(`,`):`none`}`),isGuildMessage&&params.guildEntries&&Object.keys(params.guildEntries).length>0&&!guildInfo)return logDebug(`[discord-preflight] guild blocked: guild_id=${params.data.guild_id} guildEntries keys=${Object.keys(params.guildEntries).join(`,`)}`),logVerbose(`Blocked discord guild ${params.data.guild_id??`unknown`} (not in discord.guilds)`),null;let threadChannel=earlyThreadChannel,threadParentId=earlyThreadParentId,threadParentName=earlyThreadParentName,threadParentType=earlyThreadParentType,threadName=threadChannel?.name,configChannelName=threadParentName??channelName,configChannelSlug=configChannelName?normalizeDiscordSlug(configChannelName):``,displayChannelName=threadName??channelName,displayChannelSlug=displayChannelName?normalizeDiscordSlug(displayChannelName):``,guildSlug=guildInfo?.slug||(params.data.guild?.name?normalizeDiscordSlug(params.data.guild.name):``),threadChannelSlug=channelName?normalizeDiscordSlug(channelName):``,threadParentSlug=threadParentName?normalizeDiscordSlug(threadParentName):``,baseSessionKey=route.sessionKey,channelConfig=isGuildMessage?resolveDiscordChannelConfigWithFallback({guildInfo,channelId:messageChannelId,channelName,channelSlug:threadChannelSlug,parentId:threadParentId??void 0,parentName:threadParentName??void 0,parentSlug:threadParentSlug,scope:threadChannel?`thread`:`channel`}):null,channelMatchMeta=formatAllowlistMatchMeta(channelConfig);if(shouldLogVerbose()&&logDebug(`[discord-preflight] channelConfig=${channelConfig?`allowed=${channelConfig.allowed} enabled=${channelConfig.enabled??`unset`} requireMention=${channelConfig.requireMention??`unset`} matchKey=${channelConfig.matchKey??`none`} matchSource=${channelConfig.matchSource??`none`} users=${channelConfig.users?.length??0} roles=${channelConfig.roles?.length??0} skills=${channelConfig.skills?.length??0}`:`none`} channelMatchMeta=${channelMatchMeta} channelId=${messageChannelId}`),isGuildMessage&&channelConfig?.enabled===!1)return logDebug(`[discord-preflight] drop: channel disabled`),logVerbose(`Blocked discord channel ${messageChannelId} (channel disabled, ${channelMatchMeta})`),null;let groupDmAllowed=isGroupDm&&resolveGroupDmAllow({channels:params.groupDmChannels,channelId:messageChannelId,channelName:displayChannelName,channelSlug:displayChannelSlug});if(isGroupDm&&!groupDmAllowed)return null;let channelAllowlistConfigured=!!guildInfo?.channels&&Object.keys(guildInfo?.channels??{}).length>0,channelAllowed=channelConfig?.allowed!==!1;if(isGuildMessage&&!isDiscordGroupAllowedByPolicy({groupPolicy:params.groupPolicy,guildAllowlisted:!!guildInfo,channelAllowlistConfigured,channelAllowed}))return params.groupPolicy===`disabled`?logVerbose(`discord: drop guild message (groupPolicy: disabled, ${channelMatchMeta})`):logVerbose(channelAllowlistConfigured?`Blocked discord channel ${messageChannelId} not in guild channel allowlist (groupPolicy: allowlist, ${channelMatchMeta})`:`discord: drop guild message (groupPolicy: allowlist, no channel allowlist, ${channelMatchMeta})`),null;if(isGuildMessage&&channelConfig?.allowed===!1)return logDebug(`[discord-preflight] drop: channelConfig.allowed===false`),logVerbose(`Blocked discord channel ${messageChannelId} not in guild channel allowlist (${channelMatchMeta})`),null;isGuildMessage&&(logDebug(`[discord-preflight] pass: channel allowed`),logVerbose(`discord: allow channel ${messageChannelId} (${channelMatchMeta})`));let textForHistory=resolveDiscordMessageText(message,{includeForwarded:!0}),historyEntry=isGuildMessage&&params.historyLimit>0&&textForHistory?{sender:sender.label,body:textForHistory,timestamp:resolveTimestampMs(message.timestamp),messageId:message.id}:void 0,threadOwnerId=threadChannel?threadChannel.ownerId??channelInfo?.ownerId:void 0,shouldRequireMention=resolveDiscordShouldRequireMention({isGuildMessage,isThread:!!threadChannel,botId,threadOwnerId,channelConfig,guildInfo}),preflightTranscript,hasAudioAttachment=message.attachments?.some(att=>att.contentType?.startsWith(`audio/`));if(!isDirectMessage&&shouldRequireMention&&hasAudioAttachment&&!baseText&&mentionRegexes.length>0)try{let{transcribeFirstAudio}=await import(`./audio-preflight-CWFuqbao.js`),audioPaths=message.attachments?.filter(att=>att.contentType?.startsWith(`audio/`)).map(att=>att.url)??[];audioPaths.length>0&&(preflightTranscript=await transcribeFirstAudio({ctx:{MediaUrls:audioPaths,MediaTypes:message.attachments?.filter(att=>att.contentType?.startsWith(`audio/`)).map(att=>att.contentType).filter(Boolean)},cfg:params.cfg,agentDir:void 0}))}catch(err){logVerbose(`discord: audio preflight transcription failed: ${String(err)}`)}let wasMentioned=!isDirectMessage&&matchesMentionWithExplicit({text:baseText,mentionRegexes,explicit:{hasAnyMention,isExplicitlyMentioned:explicitlyMentioned,canResolveExplicit:!!botId},transcript:preflightTranscript}),implicitMention=!!(!isDirectMessage&&botId&&message.referencedMessage?.author?.id&&message.referencedMessage.author.id===botId);shouldLogVerbose()&&logVerbose(`discord: inbound id=${message.id} guild=${params.data.guild_id??`dm`} channel=${messageChannelId} mention=${wasMentioned?`yes`:`no`} type=${isDirectMessage?`dm`:isGroupDm?`group-dm`:`guild`} content=${messageText?`yes`:`no`}`);let allowTextCommands=shouldHandleTextCommands({cfg:params.cfg,surface:`discord`}),hasControlCommandInMessage=hasControlCommand(baseText,params.cfg),{hasAccessRestrictions,memberAllowed}=resolveDiscordMemberAccessState({channelConfig,guildInfo,memberRoleIds,sender});if(!isDirectMessage){let ownerAllowList=normalizeDiscordAllowList(params.allowFrom,[`discord:`,`user:`,`pk:`]),ownerOk=ownerAllowList?allowListMatches$1(ownerAllowList,{id:sender.id,name:sender.name,tag:sender.tag}):!1,commandGate=resolveControlCommandGate({useAccessGroups:params.cfg.commands?.useAccessGroups!==!1,authorizers:[{configured:ownerAllowList!=null,allowed:ownerOk},{configured:hasAccessRestrictions,allowed:memberAllowed}],modeWhenAccessGroupsOff:`configured`,allowTextCommands,hasControlCommand:hasControlCommandInMessage});if(commandAuthorized=commandGate.commandAuthorized,commandGate.shouldBlock)return logInboundDrop({log:logVerbose,channel:`discord`,reason:`control command (unauthorized)`,target:sender.id}),null}let canDetectMention=!!botId||mentionRegexes.length>0,mentionGate=resolveMentionGatingWithBypass({isGroup:isGuildMessage,requireMention:!!shouldRequireMention,canDetectMention,wasMentioned,implicitMention,hasAnyMention,allowTextCommands,hasControlCommand:hasControlCommandInMessage,commandAuthorized}),effectiveWasMentioned=mentionGate.effectiveWasMentioned;if(logDebug(`[discord-preflight] shouldRequireMention=${shouldRequireMention} mentionGate.shouldSkip=${mentionGate.shouldSkip} wasMentioned=${wasMentioned}`),isGuildMessage&&shouldRequireMention&&botId&&mentionGate.shouldSkip)return logDebug(`[discord-preflight] drop: no-mention`),logVerbose(`discord: drop guild message (mention required, botId=${botId})`),logger.info({channelId:messageChannelId,reason:`no-mention`},`discord: skipping guild message`),recordPendingHistoryEntryIfEnabled({historyMap:params.guildHistories,historyKey:messageChannelId,limit:params.historyLimit,entry:historyEntry??null}),null;if(isGuildMessage&&hasAccessRestrictions&&!memberAllowed)return logDebug(`[discord-preflight] drop: member not allowed`),logVerbose(`Blocked discord guild sender ${sender.id} (not in users/roles allowlist)`),null;let systemText=resolveDiscordSystemEvent(message,resolveDiscordSystemLocation({isDirectMessage,isGroupDm,guild:params.data.guild??void 0,channelName:channelName??messageChannelId}));return systemText?(logDebug(`[discord-preflight] drop: system event`),enqueueSystemEvent(systemText,{sessionKey:route.sessionKey,contextKey:`discord:system:${messageChannelId}:${message.id}`}),null):messageText?(logDebug(`[discord-preflight] success: route=${route.agentId} sessionKey=${route.sessionKey}`),{cfg:params.cfg,discordConfig:params.discordConfig,accountId:params.accountId,token:params.token,runtime:params.runtime,botUserId:params.botUserId,guildHistories:params.guildHistories,historyLimit:params.historyLimit,mediaMaxBytes:params.mediaMaxBytes,textLimit:params.textLimit,replyToMode:params.replyToMode,ackReactionScope:params.ackReactionScope,groupPolicy:params.groupPolicy,data:params.data,client:params.client,message,messageChannelId,author,sender,channelInfo,channelName,isGuildMessage,isDirectMessage,isGroupDm,commandAuthorized,baseText,messageText,wasMentioned,route,guildInfo,guildSlug,threadChannel,threadParentId,threadParentName,threadParentType,threadName,configChannelName,configChannelSlug,displayChannelName,displayChannelSlug,baseSessionKey,channelConfig,channelAllowlistConfigured,channelAllowed,shouldRequireMention,hasAnyMention,allowTextCommands,shouldBypassMention:mentionGate.shouldBypassMention,effectiveWasMentioned,canDetectMention,historyEntry}):(logDebug(`[discord-preflight] drop: empty content`),logVerbose(`discord: drop message ${message.id} (empty content)`),null)}function createTypingCallbacks(params){let stop=params.stop,onReplyStart=async()=>{try{await params.start()}catch(err){params.onStartError(err)}},fireStop=stop?()=>{stop().catch(err=>(params.onStopError??params.onStartError)(err))}:void 0;return{onReplyStart,onIdle:fireStop,onCleanup:fireStop}}function normalizeEntry(entry){return entry.replace(/\s+/g,` `).trim()}function truncateText(value,maxChars){return maxChars<=0?``:value.length<=maxChars?value:`${value.slice(0,Math.max(0,maxChars-3)).trimEnd()}...`}function buildUntrustedChannelMetadata(params){let deduped=params.entries.map(entry=>typeof entry==`string`?normalizeEntry(entry):``).filter(entry=>!!entry).map(entry=>truncateText(entry,400)).filter((entry,index,list)=>list.indexOf(entry)===index);if(deduped.length===0)return;let body=deduped.join(`
452
+ `)}async function fetchPluralKitMessageInfo(params){if(!params.config?.enabled)return null;let fetchImpl=resolveFetch(params.fetcher);if(!fetchImpl)return null;let headers={};params.config.token?.trim()&&(headers.Authorization=params.config.token.trim());let res=await fetchImpl(`https://api.pluralkit.me/v2/messages/${params.messageId}`,{headers});if(res.status===404)return null;if(!res.ok){let text=await res.text().catch(()=>``),detail=text.trim()?`: ${text.trim()}`:``;throw Error(`PluralKit API failed (${res.status})${detail}`)}return await res.json()}function resolveDiscordWebhookId(message){let candidate=message.webhookId??message.webhook_id;return typeof candidate==`string`&&candidate.trim()?candidate.trim():null}function resolveDiscordSenderIdentity(params){let pkInfo=params.pluralkitInfo??null,pkMember=pkInfo?.member??void 0,pkSystem=pkInfo?.system??void 0,memberId=pkMember?.id?.trim(),memberName=(pkMember?.display_name??pkMember?.name??``)?.trim();if(memberId&&memberName){let systemName=pkSystem?.name?.trim(),label=systemName?`${memberName} (PK:${systemName})`:`${memberName} (PK)`;return{id:memberId,name:memberName,tag:pkMember?.name?.trim()||void 0,label,isPluralKit:!0,pluralkit:{memberId,memberName,systemId:pkSystem?.id?.trim()||void 0,systemName}}}let senderTag=formatDiscordUserTag(params.author),senderDisplay=params.member?.nickname??params.author.globalName??params.author.username,senderLabel=senderDisplay&&senderTag&&senderDisplay!==senderTag?`${senderDisplay} (${senderTag})`:senderDisplay??senderTag??params.author.id;return{id:params.author.id,name:params.author.username??void 0,tag:senderTag,label:senderLabel,isPluralKit:!1}}function resolveDiscordSystemEvent(message,location){switch(message.type){case MessageType.ChannelPinnedMessage:return buildDiscordSystemEvent(message,location,`pinned a message`);case MessageType.RecipientAdd:return buildDiscordSystemEvent(message,location,`added a recipient`);case MessageType.RecipientRemove:return buildDiscordSystemEvent(message,location,`removed a recipient`);case MessageType.UserJoin:return buildDiscordSystemEvent(message,location,`user joined`);case MessageType.GuildBoost:return buildDiscordSystemEvent(message,location,`boosted the server`);case MessageType.GuildBoostTier1:return buildDiscordSystemEvent(message,location,`boosted the server (Tier 1 reached)`);case MessageType.GuildBoostTier2:return buildDiscordSystemEvent(message,location,`boosted the server (Tier 2 reached)`);case MessageType.GuildBoostTier3:return buildDiscordSystemEvent(message,location,`boosted the server (Tier 3 reached)`);case MessageType.ThreadCreated:return buildDiscordSystemEvent(message,location,`created a thread`);case MessageType.AutoModerationAction:return buildDiscordSystemEvent(message,location,`auto moderation action`);case MessageType.GuildIncidentAlertModeEnabled:return buildDiscordSystemEvent(message,location,`raid protection enabled`);case MessageType.GuildIncidentAlertModeDisabled:return buildDiscordSystemEvent(message,location,`raid protection disabled`);case MessageType.GuildIncidentReportRaid:return buildDiscordSystemEvent(message,location,`raid reported`);case MessageType.GuildIncidentReportFalseAlarm:return buildDiscordSystemEvent(message,location,`raid report marked false alarm`);case MessageType.StageStart:return buildDiscordSystemEvent(message,location,`stage started`);case MessageType.StageEnd:return buildDiscordSystemEvent(message,location,`stage ended`);case MessageType.StageSpeaker:return buildDiscordSystemEvent(message,location,`stage speaker updated`);case MessageType.StageTopic:return buildDiscordSystemEvent(message,location,`stage topic updated`);case MessageType.PollResult:return buildDiscordSystemEvent(message,location,`poll results posted`);case MessageType.PurchaseNotification:return buildDiscordSystemEvent(message,location,`purchase notification`);default:return null}}function buildDiscordSystemEvent(message,location,action){let authorLabel=message.author?formatDiscordUserTag(message.author):``;return`Discord system: ${authorLabel?`${authorLabel} `:``}${action} in ${location}`}const DISCORD_THREAD_STARTER_CACHE=new Map;function getCachedThreadStarter(key,now){let entry=DISCORD_THREAD_STARTER_CACHE.get(key);if(entry){if(now-entry.updatedAt>3e5){DISCORD_THREAD_STARTER_CACHE.delete(key);return}return DISCORD_THREAD_STARTER_CACHE.delete(key),DISCORD_THREAD_STARTER_CACHE.set(key,{...entry,updatedAt:now}),entry.value}}function setCachedThreadStarter(key,value,now){for(DISCORD_THREAD_STARTER_CACHE.delete(key),DISCORD_THREAD_STARTER_CACHE.set(key,{value,updatedAt:now});DISCORD_THREAD_STARTER_CACHE.size>500;){let iter=DISCORD_THREAD_STARTER_CACHE.keys().next();if(iter.done)break;DISCORD_THREAD_STARTER_CACHE.delete(iter.value)}}function isDiscordThreadType(type){return type===ChannelType.PublicThread||type===ChannelType.PrivateThread||type===ChannelType.AnnouncementThread}function resolveDiscordThreadChannel(params){if(!params.isGuildMessage)return null;let{message,channelInfo}=params,channel=`channel`in message?message.channel:void 0;if(channel&&typeof channel==`object`&&`isThread`in channel&&typeof channel.isThread==`function`&&channel.isThread())return channel;if(!isDiscordThreadType(channelInfo?.type))return null;let messageChannelId=params.messageChannelId||resolveDiscordMessageChannelId({message});return messageChannelId?{id:messageChannelId,name:channelInfo?.name??void 0,parentId:channelInfo?.parentId??void 0,parent:void 0,ownerId:channelInfo?.ownerId??void 0}:null}async function resolveDiscordThreadParentInfo(params){let{threadChannel,channelInfo,client}=params,parentId=threadChannel.parentId??threadChannel.parent?.id??channelInfo?.parentId??void 0;if(!parentId)return{};let parentName=threadChannel.parent?.name,parentInfo=await resolveDiscordChannelInfo(client,parentId);parentName??=parentInfo?.name;let parentType=parentInfo?.type;return{id:parentId,name:parentName,type:parentType}}async function resolveDiscordThreadStarter(params){let cacheKey=params.channel.id,cached=getCachedThreadStarter(cacheKey,Date.now());if(cached)return cached;try{let parentType=params.parentType,messageChannelId=parentType===ChannelType.GuildForum||parentType===ChannelType.GuildMedia?params.channel.id:params.parentId;if(!messageChannelId)return null;let starter=await params.client.rest.get(Routes.channelMessage(messageChannelId,params.channel.id));if(!starter)return null;let text=starter.content?.trim()??starter.embeds?.[0]?.description?.trim()??``;if(!text)return null;let payload={text,author:starter.member?.nick??starter.member?.displayName??(starter.author?starter.author.discriminator&&starter.author.discriminator!==`0`?`${starter.author.username??`Unknown`}#${starter.author.discriminator}`:starter.author.username??starter.author.id??`Unknown`:`Unknown`),timestamp:params.resolveTimestampMs(starter.timestamp)??void 0};return setCachedThreadStarter(cacheKey,payload,Date.now()),payload}catch{return null}}function sanitizeDiscordThreadName(rawName,fallbackId){return truncateUtf16Safe(truncateUtf16Safe(rawName.replace(/<@!?\d+>/g,``).replace(/<@&\d+>/g,``).replace(/<#\d+>/g,``).replace(/\s+/g,` `).trim()||`Thread ${fallbackId}`,80),100)||`Thread ${fallbackId}`}function resolveDiscordAutoThreadContext(params){let createdThreadId=String(params.createdThreadId??``).trim();if(!createdThreadId)return null;let messageChannelId=params.messageChannelId.trim();if(!messageChannelId)return null;let threadSessionKey=buildAgentSessionKey({agentId:params.agentId,channel:params.channel,peer:{kind:`channel`,id:createdThreadId}}),parentSessionKey=buildAgentSessionKey({agentId:params.agentId,channel:params.channel,peer:{kind:`channel`,id:messageChannelId}});return{createdThreadId,From:`${params.channel}:channel:${createdThreadId}`,To:`channel:${createdThreadId}`,OriginatingTo:`channel:${createdThreadId}`,SessionKey:threadSessionKey,ParentSessionKey:parentSessionKey}}async function resolveDiscordAutoThreadReplyPlan(params){let messageChannelId=(params.messageChannelId||resolveDiscordMessageChannelId({message:params.message})).trim(),originalReplyTarget=`channel:${params.threadChannel?.id??(messageChannelId||`unknown`)}`,createdThreadId=await maybeCreateDiscordAutoThread({client:params.client,message:params.message,messageChannelId:messageChannelId||void 0,isGuildMessage:params.isGuildMessage,channelConfig:params.channelConfig,threadChannel:params.threadChannel,channelType:params.channelType,baseText:params.baseText,combinedBody:params.combinedBody}),deliveryPlan=resolveDiscordReplyDeliveryPlan({replyTarget:originalReplyTarget,replyToMode:params.replyToMode,messageId:params.message.id,threadChannel:params.threadChannel,createdThreadId}),autoThreadContext=params.isGuildMessage?resolveDiscordAutoThreadContext({agentId:params.agentId,channel:params.channel,messageChannelId,createdThreadId}):null;return{...deliveryPlan,createdThreadId,autoThreadContext}}async function maybeCreateDiscordAutoThread(params){if(!params.isGuildMessage||!params.channelConfig?.autoThread||params.threadChannel||params.channelType===ChannelType.GuildForum||params.channelType===ChannelType.GuildMedia||params.channelType===ChannelType.GuildVoice||params.channelType===ChannelType.GuildStageVoice)return;let messageChannelId=(params.messageChannelId||resolveDiscordMessageChannelId({message:params.message})).trim();if(messageChannelId)try{let threadName=sanitizeDiscordThreadName(params.baseText||params.combinedBody||`Thread`,params.message.id),created=await params.client.rest.post(`${Routes.channelMessage(messageChannelId,params.message.id)}/threads`,{body:{name:threadName,auto_archive_duration:60}});return(created?.id?String(created.id):``)||void 0}catch(err){logVerbose(`discord: autoThread creation failed for ${messageChannelId}/${params.message.id}: ${String(err)}`);try{let msg=await params.client.rest.get(Routes.channelMessage(messageChannelId,params.message.id)),existingThreadId=msg?.thread?.id?String(msg.thread.id):``;if(existingThreadId)return logVerbose(`discord: autoThread reusing existing thread ${existingThreadId} on ${messageChannelId}/${params.message.id}`),existingThreadId}catch{}return}}function resolveDiscordReplyDeliveryPlan(params){let originalReplyTarget=params.replyTarget,deliverTarget=originalReplyTarget,replyTarget=originalReplyTarget;params.createdThreadId&&(deliverTarget=`channel:${params.createdThreadId}`,replyTarget=deliverTarget);let allowReference=deliverTarget===originalReplyTarget,replyReference=createReplyReferencePlanner({replyToMode:allowReference?params.replyToMode:`off`,existingId:params.threadChannel?params.messageId:void 0,startId:params.messageId,allowReference});return{deliverTarget,replyTarget,replyReference}}async function preflightDiscordMessage(params){let logger=getChildLogger({module:`discord-auto-reply`}),message=params.data.message,author=params.data.author;if(!author)return null;let messageChannelId=resolveDiscordMessageChannelId({message,eventChannelId:params.data.channel_id});if(!messageChannelId)return logVerbose(`discord: drop message ${message.id} (missing channel id)`),null;let allowBots=params.discordConfig?.allowBots??!1;if(params.botUserId&&author.id===params.botUserId)return null;let pluralkitConfig=params.discordConfig?.pluralkit,webhookId=resolveDiscordWebhookId(message),shouldCheckPluralKit=!!pluralkitConfig?.enabled&&!webhookId,pluralkitInfo=null;if(shouldCheckPluralKit)try{pluralkitInfo=await fetchPluralKitMessageInfo({messageId:message.id,config:pluralkitConfig})}catch(err){logVerbose(`discord: pluralkit lookup failed for ${message.id}: ${String(err)}`)}let sender=resolveDiscordSenderIdentity({author,member:params.data.member,pluralkitInfo});if(author.bot&&!allowBots&&!sender.isPluralKit)return logVerbose(`discord: drop bot message (allowBots=false)`),null;let isGuildMessage=!!params.data.guild_id,channelInfo=await resolveDiscordChannelInfo(params.client,messageChannelId),isDirectMessage=channelInfo?.type===ChannelType.DM,isGroupDm=channelInfo?.type===ChannelType.GroupDM;if(logDebug(`[discord-preflight] channelId=${messageChannelId} guild_id=${params.data.guild_id} channelType=${channelInfo?.type} isGuild=${isGuildMessage} isDM=${isDirectMessage} isGroupDm=${isGroupDm}`),isGroupDm&&!params.groupDmEnabled)return logVerbose(`discord: drop group dm (group dms disabled)`),null;if(isDirectMessage&&!params.dmEnabled)return logVerbose(`discord: drop dm (dms disabled)`),null;let dmPolicy=params.discordConfig?.dmPolicy??params.discordConfig?.dm?.policy??`pairing`,commandAuthorized=!0;if(isDirectMessage){if(dmPolicy===`disabled`)return logVerbose(`discord: drop dm (dmPolicy: disabled)`),null;if(dmPolicy!==`open`){let storeAllowFrom=await readChannelAllowFromStore(`discord`).catch(()=>[]),allowList=normalizeDiscordAllowList([...params.allowFrom??[],...storeAllowFrom],[`discord:`,`user:`,`pk:`]),allowMatch=allowList?resolveDiscordAllowListMatch({allowList,candidate:{id:sender.id,name:sender.name,tag:sender.tag}}):{allowed:!1},allowMatchMeta=formatAllowlistMatchMeta(allowMatch);if(!allowMatch.allowed){if(commandAuthorized=!1,dmPolicy===`pairing`){let{code,created}=await upsertChannelPairingRequest({channel:`discord`,id:author.id,meta:{tag:formatDiscordUserTag(author),name:author.username??void 0}});if(created){logVerbose(`discord pairing request sender=${author.id} tag=${formatDiscordUserTag(author)} (${allowMatchMeta})`);try{await sendMessageDiscord(`user:${author.id}`,buildPairingReply({channel:`discord`,idLine:`Your Discord user id: ${author.id}`,code}),{token:params.token,rest:params.client.rest,accountId:params.accountId})}catch(err){logVerbose(`discord pairing reply failed for ${author.id}: ${String(err)}`)}}}else logVerbose(`Blocked unauthorized discord sender ${sender.id} (dmPolicy=${dmPolicy}, ${allowMatchMeta})`);return null}commandAuthorized=!0}}let botId=params.botUserId,baseText=resolveDiscordMessageText(message,{includeForwarded:!1}),messageText=resolveDiscordMessageText(message,{includeForwarded:!0});recordChannelActivity({channel:`discord`,accountId:params.accountId,direction:`inbound`});let channelName=channelInfo?.name??((isGuildMessage||isGroupDm)&&message.channel&&`name`in message.channel?message.channel.name:void 0),earlyThreadChannel=resolveDiscordThreadChannel({isGuildMessage,message,channelInfo,messageChannelId}),earlyThreadParentId,earlyThreadParentName,earlyThreadParentType;if(earlyThreadChannel){let parentInfo=await resolveDiscordThreadParentInfo({client:params.client,threadChannel:earlyThreadChannel,channelInfo});earlyThreadParentId=parentInfo.id,earlyThreadParentName=parentInfo.name,earlyThreadParentType=parentInfo.type}let memberRoleIds=Array.isArray(params.data.rawMember?.roles)?params.data.rawMember.roles.map(roleId=>String(roleId)):[],route=resolveAgentRoute({cfg:loadConfig(),channel:`discord`,accountId:params.accountId,guildId:params.data.guild_id??void 0,memberRoleIds,peer:{kind:isDirectMessage?`direct`:isGroupDm?`group`:`channel`,id:isDirectMessage?author.id:messageChannelId},parentPeer:earlyThreadParentId?{kind:`channel`,id:earlyThreadParentId}:void 0}),mentionRegexes=buildMentionRegexes(params.cfg,route.agentId),explicitlyMentioned=!!(botId&&message.mentionedUsers?.some(user=>user.id===botId)),hasAnyMention=!!(!isDirectMessage&&(message.mentionedEveryone||(message.mentionedUsers?.length??0)>0||(message.mentionedRoles?.length??0)>0));if(isGuildMessage&&(message.type===MessageType.ChatInputCommand||message.type===MessageType.ContextMenuCommand))return logVerbose(`discord: drop channel command message`),null;let guildInfo=isGuildMessage?resolveDiscordGuildEntry({guild:params.data.guild??void 0,guildEntries:params.guildEntries}):null;if(logDebug(`[discord-preflight] guild_id=${params.data.guild_id} guild_obj=${!!params.data.guild} guild_obj_id=${params.data.guild?.id} guildInfo=${!!guildInfo} guildEntries=${params.guildEntries?Object.keys(params.guildEntries).join(`,`):`none`}`),isGuildMessage&&params.guildEntries&&Object.keys(params.guildEntries).length>0&&!guildInfo)return logDebug(`[discord-preflight] guild blocked: guild_id=${params.data.guild_id} guildEntries keys=${Object.keys(params.guildEntries).join(`,`)}`),logVerbose(`Blocked discord guild ${params.data.guild_id??`unknown`} (not in discord.guilds)`),null;let threadChannel=earlyThreadChannel,threadParentId=earlyThreadParentId,threadParentName=earlyThreadParentName,threadParentType=earlyThreadParentType,threadName=threadChannel?.name,configChannelName=threadParentName??channelName,configChannelSlug=configChannelName?normalizeDiscordSlug(configChannelName):``,displayChannelName=threadName??channelName,displayChannelSlug=displayChannelName?normalizeDiscordSlug(displayChannelName):``,guildSlug=guildInfo?.slug||(params.data.guild?.name?normalizeDiscordSlug(params.data.guild.name):``),threadChannelSlug=channelName?normalizeDiscordSlug(channelName):``,threadParentSlug=threadParentName?normalizeDiscordSlug(threadParentName):``,baseSessionKey=route.sessionKey,channelConfig=isGuildMessage?resolveDiscordChannelConfigWithFallback({guildInfo,channelId:messageChannelId,channelName,channelSlug:threadChannelSlug,parentId:threadParentId??void 0,parentName:threadParentName??void 0,parentSlug:threadParentSlug,scope:threadChannel?`thread`:`channel`}):null,channelMatchMeta=formatAllowlistMatchMeta(channelConfig);if(shouldLogVerbose()&&logDebug(`[discord-preflight] channelConfig=${channelConfig?`allowed=${channelConfig.allowed} enabled=${channelConfig.enabled??`unset`} requireMention=${channelConfig.requireMention??`unset`} matchKey=${channelConfig.matchKey??`none`} matchSource=${channelConfig.matchSource??`none`} users=${channelConfig.users?.length??0} roles=${channelConfig.roles?.length??0} skills=${channelConfig.skills?.length??0}`:`none`} channelMatchMeta=${channelMatchMeta} channelId=${messageChannelId}`),isGuildMessage&&channelConfig?.enabled===!1)return logDebug(`[discord-preflight] drop: channel disabled`),logVerbose(`Blocked discord channel ${messageChannelId} (channel disabled, ${channelMatchMeta})`),null;let groupDmAllowed=isGroupDm&&resolveGroupDmAllow({channels:params.groupDmChannels,channelId:messageChannelId,channelName:displayChannelName,channelSlug:displayChannelSlug});if(isGroupDm&&!groupDmAllowed)return null;let channelAllowlistConfigured=!!guildInfo?.channels&&Object.keys(guildInfo?.channels??{}).length>0,channelAllowed=channelConfig?.allowed!==!1;if(isGuildMessage&&!isDiscordGroupAllowedByPolicy({groupPolicy:params.groupPolicy,guildAllowlisted:!!guildInfo,channelAllowlistConfigured,channelAllowed}))return params.groupPolicy===`disabled`?logVerbose(`discord: drop guild message (groupPolicy: disabled, ${channelMatchMeta})`):logVerbose(channelAllowlistConfigured?`Blocked discord channel ${messageChannelId} not in guild channel allowlist (groupPolicy: allowlist, ${channelMatchMeta})`:`discord: drop guild message (groupPolicy: allowlist, no channel allowlist, ${channelMatchMeta})`),null;if(isGuildMessage&&channelConfig?.allowed===!1)return logDebug(`[discord-preflight] drop: channelConfig.allowed===false`),logVerbose(`Blocked discord channel ${messageChannelId} not in guild channel allowlist (${channelMatchMeta})`),null;isGuildMessage&&(logDebug(`[discord-preflight] pass: channel allowed`),logVerbose(`discord: allow channel ${messageChannelId} (${channelMatchMeta})`));let textForHistory=resolveDiscordMessageText(message,{includeForwarded:!0}),historyEntry=isGuildMessage&&params.historyLimit>0&&textForHistory?{sender:sender.label,body:textForHistory,timestamp:resolveTimestampMs(message.timestamp),messageId:message.id}:void 0,threadOwnerId=threadChannel?threadChannel.ownerId??channelInfo?.ownerId:void 0,shouldRequireMention=resolveDiscordShouldRequireMention({isGuildMessage,isThread:!!threadChannel,botId,threadOwnerId,channelConfig,guildInfo}),preflightTranscript,hasAudioAttachment=message.attachments?.some(att=>att.contentType?.startsWith(`audio/`));if(!isDirectMessage&&shouldRequireMention&&hasAudioAttachment&&!baseText&&mentionRegexes.length>0)try{let{transcribeFirstAudio}=await import(`./audio-preflight-B411b2-y.js`),audioPaths=message.attachments?.filter(att=>att.contentType?.startsWith(`audio/`)).map(att=>att.url)??[];audioPaths.length>0&&(preflightTranscript=await transcribeFirstAudio({ctx:{MediaUrls:audioPaths,MediaTypes:message.attachments?.filter(att=>att.contentType?.startsWith(`audio/`)).map(att=>att.contentType).filter(Boolean)},cfg:params.cfg,agentDir:void 0}))}catch(err){logVerbose(`discord: audio preflight transcription failed: ${String(err)}`)}let wasMentioned=!isDirectMessage&&matchesMentionWithExplicit({text:baseText,mentionRegexes,explicit:{hasAnyMention,isExplicitlyMentioned:explicitlyMentioned,canResolveExplicit:!!botId},transcript:preflightTranscript}),implicitMention=!!(!isDirectMessage&&botId&&message.referencedMessage?.author?.id&&message.referencedMessage.author.id===botId);shouldLogVerbose()&&logVerbose(`discord: inbound id=${message.id} guild=${params.data.guild_id??`dm`} channel=${messageChannelId} mention=${wasMentioned?`yes`:`no`} type=${isDirectMessage?`dm`:isGroupDm?`group-dm`:`guild`} content=${messageText?`yes`:`no`}`);let allowTextCommands=shouldHandleTextCommands({cfg:params.cfg,surface:`discord`}),hasControlCommandInMessage=hasControlCommand(baseText,params.cfg),{hasAccessRestrictions,memberAllowed}=resolveDiscordMemberAccessState({channelConfig,guildInfo,memberRoleIds,sender});if(!isDirectMessage){let ownerAllowList=normalizeDiscordAllowList(params.allowFrom,[`discord:`,`user:`,`pk:`]),ownerOk=ownerAllowList?allowListMatches$1(ownerAllowList,{id:sender.id,name:sender.name,tag:sender.tag}):!1,commandGate=resolveControlCommandGate({useAccessGroups:params.cfg.commands?.useAccessGroups!==!1,authorizers:[{configured:ownerAllowList!=null,allowed:ownerOk},{configured:hasAccessRestrictions,allowed:memberAllowed}],modeWhenAccessGroupsOff:`configured`,allowTextCommands,hasControlCommand:hasControlCommandInMessage});if(commandAuthorized=commandGate.commandAuthorized,commandGate.shouldBlock)return logInboundDrop({log:logVerbose,channel:`discord`,reason:`control command (unauthorized)`,target:sender.id}),null}let canDetectMention=!!botId||mentionRegexes.length>0,mentionGate=resolveMentionGatingWithBypass({isGroup:isGuildMessage,requireMention:!!shouldRequireMention,canDetectMention,wasMentioned,implicitMention,hasAnyMention,allowTextCommands,hasControlCommand:hasControlCommandInMessage,commandAuthorized}),effectiveWasMentioned=mentionGate.effectiveWasMentioned;if(logDebug(`[discord-preflight] shouldRequireMention=${shouldRequireMention} mentionGate.shouldSkip=${mentionGate.shouldSkip} wasMentioned=${wasMentioned}`),isGuildMessage&&shouldRequireMention&&botId&&mentionGate.shouldSkip)return logDebug(`[discord-preflight] drop: no-mention`),logVerbose(`discord: drop guild message (mention required, botId=${botId})`),logger.info({channelId:messageChannelId,reason:`no-mention`},`discord: skipping guild message`),recordPendingHistoryEntryIfEnabled({historyMap:params.guildHistories,historyKey:messageChannelId,limit:params.historyLimit,entry:historyEntry??null}),null;if(isGuildMessage&&hasAccessRestrictions&&!memberAllowed)return logDebug(`[discord-preflight] drop: member not allowed`),logVerbose(`Blocked discord guild sender ${sender.id} (not in users/roles allowlist)`),null;let systemText=resolveDiscordSystemEvent(message,resolveDiscordSystemLocation({isDirectMessage,isGroupDm,guild:params.data.guild??void 0,channelName:channelName??messageChannelId}));return systemText?(logDebug(`[discord-preflight] drop: system event`),enqueueSystemEvent(systemText,{sessionKey:route.sessionKey,contextKey:`discord:system:${messageChannelId}:${message.id}`}),null):messageText?(logDebug(`[discord-preflight] success: route=${route.agentId} sessionKey=${route.sessionKey}`),{cfg:params.cfg,discordConfig:params.discordConfig,accountId:params.accountId,token:params.token,runtime:params.runtime,botUserId:params.botUserId,guildHistories:params.guildHistories,historyLimit:params.historyLimit,mediaMaxBytes:params.mediaMaxBytes,textLimit:params.textLimit,replyToMode:params.replyToMode,ackReactionScope:params.ackReactionScope,groupPolicy:params.groupPolicy,data:params.data,client:params.client,message,messageChannelId,author,sender,channelInfo,channelName,isGuildMessage,isDirectMessage,isGroupDm,commandAuthorized,baseText,messageText,wasMentioned,route,guildInfo,guildSlug,threadChannel,threadParentId,threadParentName,threadParentType,threadName,configChannelName,configChannelSlug,displayChannelName,displayChannelSlug,baseSessionKey,channelConfig,channelAllowlistConfigured,channelAllowed,shouldRequireMention,hasAnyMention,allowTextCommands,shouldBypassMention:mentionGate.shouldBypassMention,effectiveWasMentioned,canDetectMention,historyEntry}):(logDebug(`[discord-preflight] drop: empty content`),logVerbose(`discord: drop message ${message.id} (empty content)`),null)}function createTypingCallbacks(params){let stop=params.stop,onReplyStart=async()=>{try{await params.start()}catch(err){params.onStartError(err)}},fireStop=stop?()=>{stop().catch(err=>(params.onStopError??params.onStartError)(err))}:void 0;return{onReplyStart,onIdle:fireStop,onCleanup:fireStop}}function normalizeEntry(entry){return entry.replace(/\s+/g,` `).trim()}function truncateText(value,maxChars){return maxChars<=0?``:value.length<=maxChars?value:`${value.slice(0,Math.max(0,maxChars-3)).trimEnd()}...`}function buildUntrustedChannelMetadata(params){let deduped=params.entries.map(entry=>typeof entry==`string`?normalizeEntry(entry):``).filter(entry=>!!entry).map(entry=>truncateText(entry,400)).filter((entry,index,list)=>list.indexOf(entry)===index);if(deduped.length===0)return;let body=deduped.join(`
453
453
  `);return wrapExternalContent(truncateText(`${`UNTRUSTED channel metadata (${params.source})`}\n${`${params.label}:\n${body}`}`,params.maxChars??800),{source:`channel_metadata`,includeWarning:!1})}function resolveReplyContext(message,resolveDiscordMessageText){let referenced=message.referencedMessage;if(!referenced?.author)return null;let referencedText=resolveDiscordMessageText(referenced,{includeForwarded:!0});if(!referencedText)return null;let sender=resolveDiscordSenderIdentity({author:referenced.author,pluralkitInfo:null});return{id:referenced.id,channelId:referenced.channelId,sender:sender.tag??sender.label??`unknown`,body:referencedText,timestamp:resolveTimestampMs(referenced.timestamp)}}function buildDirectLabel(author,tagOverride){return`${(tagOverride?.trim()||resolveDiscordSenderIdentity({author,pluralkitInfo:null}).tag)??`unknown`} user id:${author.id}`}function buildGuildLabel(params){let{guild,channelName,channelId}=params;return`${guild?.name??`Guild`} #${channelName} channel id:${channelId}`}async function deliverDiscordReply(params){let chunkLimit=Math.min(params.textLimit,2e3);for(let payload of params.replies){let mediaList=payload.mediaUrls??(payload.mediaUrl?[payload.mediaUrl]:[]),text=convertMarkdownTables(payload.text??``,params.tableMode??`code`);if(!text&&mediaList.length===0)continue;let replyTo=params.replyToId?.trim()||void 0;if(mediaList.length===0){let mode=params.chunkMode??`length`,chunks=chunkDiscordTextWithMode(text,{maxChars:chunkLimit,maxLines:params.maxLinesPerMessage,chunkMode:mode});!chunks.length&&text&&chunks.push(text);for(let chunk of chunks){let trimmed=chunk.trim();trimmed&&await sendMessageDiscord(params.target,trimmed,{token:params.token,rest:params.rest,accountId:params.accountId,replyTo})}continue}let firstMedia=mediaList[0];if(firstMedia){if(payload.audioAsVoice){await sendVoiceMessageDiscord(params.target,firstMedia,{token:params.token,rest:params.rest,accountId:params.accountId,replyTo}),text.trim()&&await sendMessageDiscord(params.target,text,{token:params.token,rest:params.rest,accountId:params.accountId,replyTo});for(let extra of mediaList.slice(1))await sendMessageDiscord(params.target,``,{token:params.token,rest:params.rest,mediaUrl:extra,accountId:params.accountId,replyTo});continue}await sendMessageDiscord(params.target,text,{token:params.token,rest:params.rest,mediaUrl:firstMedia,accountId:params.accountId,replyTo});for(let extra of mediaList.slice(1))await sendMessageDiscord(params.target,``,{token:params.token,rest:params.rest,mediaUrl:extra,accountId:params.accountId,replyTo})}}}async function sendTyping(params){let channel=await params.client.fetchChannel(params.channelId);channel&&`triggerTyping`in channel&&typeof channel.triggerTyping==`function`&&await channel.triggerTyping()}const DISCORD_STATUS_THINKING_EMOJI=`🧠`,DISCORD_STATUS_TOOL_EMOJI=`🛠️`,DISCORD_STATUS_CODING_EMOJI=`💻`,DISCORD_STATUS_WEB_EMOJI=`🌐`,DISCORD_STATUS_STALL_HARD_EMOJI=`⚠️`,CODING_STATUS_TOOL_TOKENS=[`exec`,`process`,`read`,`write`,`edit`,`session_status`,`bash`],WEB_STATUS_TOOL_TOKENS=[`web_search`,`web-search`,`web_fetch`,`web-fetch`,`browser`];function resolveToolStatusEmoji(toolName){let normalized=toolName?.trim().toLowerCase()??``;return normalized?WEB_STATUS_TOOL_TOKENS.some(token=>normalized.includes(token))?DISCORD_STATUS_WEB_EMOJI:CODING_STATUS_TOOL_TOKENS.some(token=>normalized.includes(token))?DISCORD_STATUS_CODING_EMOJI:DISCORD_STATUS_TOOL_EMOJI:DISCORD_STATUS_TOOL_EMOJI}function sleep(ms){return new Promise(resolve=>{setTimeout(resolve,ms)})}function createDiscordStatusReactionController(params){let activeEmoji=null,chain=Promise.resolve(),pendingEmoji=null,pendingTimer=null,finished=!1,softStallTimer=null,hardStallTimer=null,enqueue=work=>(chain=chain.then(work).catch(err=>{logAckFailure({log:logVerbose,channel:`discord`,target:`${params.channelId}/${params.messageId}`,error:err})}),chain),clearStallTimers=()=>{softStallTimer&&=(clearTimeout(softStallTimer),null),hardStallTimer&&=(clearTimeout(hardStallTimer),null)},clearPendingDebounce=()=>{pendingTimer&&=(clearTimeout(pendingTimer),null),pendingEmoji=null},applyEmoji=emoji=>enqueue(async()=>{if(!params.enabled||!emoji||activeEmoji===emoji)return;let previousEmoji=activeEmoji;await reactMessageDiscord(params.channelId,params.messageId,emoji,{rest:params.rest}),activeEmoji=emoji,previousEmoji&&previousEmoji!==emoji&&await removeReactionDiscord(params.channelId,params.messageId,previousEmoji,{rest:params.rest})}),requestEmoji=(emoji,options)=>!params.enabled||!emoji?Promise.resolve():options?.immediate?(clearPendingDebounce(),applyEmoji(emoji)):(pendingEmoji=emoji,pendingTimer&&clearTimeout(pendingTimer),pendingTimer=setTimeout(()=>{pendingTimer=null;let emojiToApply=pendingEmoji;pendingEmoji=null,!(!emojiToApply||emojiToApply===activeEmoji)&&applyEmoji(emojiToApply)},700),Promise.resolve()),scheduleStallTimers=()=>{!params.enabled||finished||(clearStallTimers(),softStallTimer=setTimeout(()=>{finished||requestEmoji(`⏳`,{immediate:!0})},1e4),hardStallTimer=setTimeout(()=>{finished||requestEmoji(DISCORD_STATUS_STALL_HARD_EMOJI,{immediate:!0})},3e4))},setPhase=emoji=>!params.enabled||finished?Promise.resolve():(scheduleStallTimers(),requestEmoji(emoji)),setTerminal=async emoji=>{params.enabled&&(finished=!0,clearStallTimers(),await requestEmoji(emoji,{immediate:!0}))};return{setQueued:()=>(scheduleStallTimers(),requestEmoji(params.initialEmoji,{immediate:!0})),setThinking:()=>setPhase(DISCORD_STATUS_THINKING_EMOJI),setTool:toolName=>setPhase(resolveToolStatusEmoji(toolName)),setDone:()=>setTerminal(`✅`),setError:()=>setTerminal(`❌`),clear:async()=>{params.enabled&&(finished=!0,clearStallTimers(),clearPendingDebounce(),await enqueue(async()=>{let cleanupCandidates=new Set([params.initialEmoji,activeEmoji??``,DISCORD_STATUS_THINKING_EMOJI,DISCORD_STATUS_TOOL_EMOJI,DISCORD_STATUS_CODING_EMOJI,DISCORD_STATUS_WEB_EMOJI,`✅`,`❌`,`⏳`,DISCORD_STATUS_STALL_HARD_EMOJI]);activeEmoji=null;for(let emoji of cleanupCandidates)if(emoji)try{await removeReactionDiscord(params.channelId,params.messageId,emoji,{rest:params.rest})}catch(err){logAckFailure({log:logVerbose,channel:`discord`,target:`${params.channelId}/${params.messageId}`,error:err})}}))},restoreInitial:async()=>{params.enabled&&(finished=!0,clearStallTimers(),clearPendingDebounce(),await requestEmoji(params.initialEmoji,{immediate:!0}))}}}async function processDiscordMessage(ctx){let{cfg,discordConfig,accountId,token,runtime,guildHistories,historyLimit,mediaMaxBytes,textLimit,replyToMode,ackReactionScope,message,author,sender,data,client,channelInfo,channelName,messageChannelId,isGuildMessage,isDirectMessage,isGroupDm,baseText,messageText,shouldRequireMention,canDetectMention,effectiveWasMentioned,shouldBypassMention,threadChannel,threadParentId,threadParentName,threadParentType,threadName,displayChannelSlug,guildInfo,guildSlug,channelConfig,baseSessionKey,route,commandAuthorized}=ctx,mediaList=await resolveMediaList(message,mediaMaxBytes),forwardedMediaList=await resolveForwardedMediaList(message,mediaMaxBytes);mediaList.push(...forwardedMediaList);let text=messageText;if(!text){logVerbose(`discord: drop message ${message.id} (empty content)`);return}let ackReaction=resolveAckReaction(cfg,route.agentId,{channel:`discord`,accountId}),removeAckAfterReply=cfg.messages?.removeAckAfterReply??!1,statusReactionsEnabled=!!(ackReaction&&shouldAckReaction({scope:ackReactionScope,isDirect:isDirectMessage,isGroup:isGuildMessage||isGroupDm,isMentionableGroup:isGuildMessage,requireMention:!!shouldRequireMention,canDetectMention,effectiveWasMentioned,shouldBypassMention})),statusReactions=createDiscordStatusReactionController({enabled:statusReactionsEnabled,channelId:messageChannelId,messageId:message.id,initialEmoji:ackReaction,rest:client.rest});statusReactionsEnabled&&statusReactions.setQueued();let fromLabel=isDirectMessage?buildDirectLabel(author):buildGuildLabel({guild:data.guild??void 0,channelName:channelName??messageChannelId,channelId:messageChannelId}),senderLabel=sender.label,isForumParent=threadParentType===ChannelType.GuildForum||threadParentType===ChannelType.GuildMedia,forumParentSlug=isForumParent&&threadParentName?normalizeDiscordSlug(threadParentName):``,threadChannelId=threadChannel?.id,forumContextLine=threadChannelId&&isForumParent&&forumParentSlug&&message.id===threadChannelId?`[Forum parent: #${forumParentSlug}]`:null,groupChannel=isGuildMessage&&displayChannelSlug?`#${displayChannelSlug}`:void 0,groupSubject=isDirectMessage?void 0:groupChannel,untrustedChannelMetadata=isGuildMessage?buildUntrustedChannelMetadata({source:`discord`,label:`Discord channel topic`,entries:[channelInfo?.topic]}):void 0,senderName=sender.isPluralKit?sender.name??author.username:data.member?.nickname??author.globalName??author.username,senderUsername=sender.isPluralKit?sender.tag??sender.name??author.username:author.username,senderTag=sender.tag,systemPromptParts=[channelConfig?.systemPrompt?.trim()||null].filter(entry=>!!entry),groupSystemPrompt=systemPromptParts.length>0?systemPromptParts.join(`
454
454
 
455
455
  `):void 0,ownerAllowFrom=resolveDiscordOwnerAllowFrom({channelConfig,guildInfo,sender:{id:sender.id,name:sender.name,tag:sender.tag}}),storePath=resolveStorePath(cfg.session?.store,{agentId:route.agentId}),envelopeOptions=resolveEnvelopeFormatOptions(cfg),previousTimestamp=readSessionUpdatedAt({storePath,sessionKey:route.sessionKey}),combinedBody=formatInboundEnvelope({channel:`Discord`,from:fromLabel,timestamp:resolveTimestampMs(message.timestamp),body:text,chatType:isDirectMessage?`direct`:`channel`,senderLabel,previousTimestamp,envelope:envelopeOptions}),shouldIncludeChannelHistory=!isDirectMessage&&!(isGuildMessage&&channelConfig?.autoThread&&!threadChannel);shouldIncludeChannelHistory&&(combinedBody=buildPendingHistoryContextFromMap({historyMap:guildHistories,historyKey:messageChannelId,limit:historyLimit,currentMessage:combinedBody,formatEntry:entry=>formatInboundEnvelope({channel:`Discord`,from:fromLabel,timestamp:entry.timestamp,body:`${entry.body} [id:${entry.messageId??`unknown`} channel:${messageChannelId}]`,chatType:`channel`,senderLabel:entry.sender,envelope:envelopeOptions})}));let replyContext=resolveReplyContext(message,resolveDiscordMessageText);forumContextLine&&(combinedBody=`${combinedBody}\n${forumContextLine}`);let threadStarterBody,threadLabel,parentSessionKey;if(threadChannel){if(channelConfig?.includeThreadStarter!==!1){let starter=await resolveDiscordThreadStarter({channel:threadChannel,client,parentId:threadParentId,parentType:threadParentType,resolveTimestampMs});starter?.text&&(threadStarterBody=starter.text)}let parentName=threadParentName??`parent`;threadLabel=threadName?`Discord thread #${normalizeDiscordSlug(parentName)} › ${threadName}`:`Discord thread #${normalizeDiscordSlug(parentName)}`,threadParentId&&(parentSessionKey=buildAgentSessionKey({agentId:route.agentId,channel:route.channel,peer:{kind:`channel`,id:threadParentId}}))}let mediaPayload=buildDiscordMediaPayload(mediaList),threadKeys=resolveThreadSessionKeys({baseSessionKey,threadId:threadChannel?messageChannelId:void 0,parentSessionKey,useSuffix:!1}),replyPlan=await resolveDiscordAutoThreadReplyPlan({client,message,messageChannelId,isGuildMessage,channelConfig,threadChannel,channelType:channelInfo?.type,baseText:baseText??``,combinedBody,replyToMode,agentId:route.agentId,channel:route.channel}),deliverTarget=replyPlan.deliverTarget,replyTarget=replyPlan.replyTarget,replyReference=replyPlan.replyReference,autoThreadContext=replyPlan.autoThreadContext,effectiveFrom=isDirectMessage?`discord:${author.id}`:autoThreadContext?.From??`discord:channel:${messageChannelId}`,effectiveTo=autoThreadContext?.To??replyTarget;if(!effectiveTo){runtime.error?.(danger(`discord: missing reply target`));return}let lastRouteTo=isDirectMessage?`user:${author.id}`:effectiveTo,inboundHistory=shouldIncludeChannelHistory&&historyLimit>0?(guildHistories.get(messageChannelId)??[]).map(entry=>({sender:entry.sender,body:entry.body,timestamp:entry.timestamp})):void 0,ctxPayload=finalizeInboundContext({Body:combinedBody,BodyForAgent:baseText??text,InboundHistory:inboundHistory,RawBody:baseText,CommandBody:baseText,From:effectiveFrom,To:effectiveTo,SessionKey:autoThreadContext?.SessionKey??threadKeys.sessionKey,AccountId:route.accountId,ChatType:isDirectMessage?`direct`:`channel`,ConversationLabel:fromLabel,SenderName:senderName,SenderId:sender.id,SenderUsername:senderUsername,SenderTag:senderTag,GroupSubject:groupSubject,GroupChannel:groupChannel,UntrustedContext:untrustedChannelMetadata?[untrustedChannelMetadata]:void 0,GroupSystemPrompt:isGuildMessage?groupSystemPrompt:void 0,GroupSpace:isGuildMessage&&(guildInfo?.id??guildSlug)||void 0,OwnerAllowFrom:ownerAllowFrom,Provider:`discord`,Surface:`discord`,WasMentioned:effectiveWasMentioned,MessageSid:message.id,ReplyToId:replyContext?.id,ReplyToBody:replyContext?.body,ReplyToSender:replyContext?.sender,ParentSessionKey:autoThreadContext?.ParentSessionKey??threadKeys.parentSessionKey,ThreadStarterBody:threadStarterBody,ThreadLabel:threadLabel,Timestamp:resolveTimestampMs(message.timestamp),...mediaPayload,CommandAuthorized:commandAuthorized,CommandSource:`text`,OriginatingChannel:`discord`,OriginatingTo:autoThreadContext?.OriginatingTo??replyTarget}),persistedSessionKey=ctxPayload.SessionKey??route.sessionKey;if(await recordInboundSession({storePath,sessionKey:persistedSessionKey,ctx:ctxPayload,updateLastRoute:{sessionKey:persistedSessionKey,channel:`discord`,to:lastRouteTo,accountId:route.accountId},onRecordError:err=>{logVerbose(`discord: failed updating session meta: ${String(err)}`)}}),shouldLogVerbose()){let preview=truncateUtf16Safe(combinedBody,200).replace(/\n/g,`\\n`);logVerbose(`discord inbound: channel=${messageChannelId} deliver=${deliverTarget} from=${ctxPayload.From} preview="${preview}"`)}let typingChannelId=deliverTarget.startsWith(`channel:`)?deliverTarget.slice(8):messageChannelId,{onModelSelected,...prefixOptions}=createReplyPrefixOptions({cfg,agentId:route.agentId,channel:`discord`,accountId:route.accountId}),tableMode=resolveMarkdownTableMode({cfg,channel:`discord`,accountId}),typingCallbacks=createTypingCallbacks({start:()=>sendTyping({client,channelId:typingChannelId}),onStartError:err=>{logTypingFailure({log:logVerbose,channel:`discord`,target:typingChannelId,error:err})}}),{dispatcher,replyOptions,markDispatchIdle}=createReplyDispatcherWithTyping({...prefixOptions,humanDelay:resolveHumanDelayConfig(cfg,route.agentId),deliver:async payload=>{let replyToId=replyReference.use();await deliverDiscordReply({replies:[payload],target:deliverTarget,token,accountId,rest:client.rest,runtime,replyToId,textLimit,maxLinesPerMessage:discordConfig?.maxLinesPerMessage,tableMode,chunkMode:resolveChunkMode(cfg,`discord`,accountId)}),replyReference.markSent()},onError:(err,info)=>{runtime.error?.(danger(`discord ${info.kind} reply failed: ${String(err)}`))},onReplyStart:async()=>{await typingCallbacks.onReplyStart(),await statusReactions.setThinking()}}),dispatchResult=null,dispatchError=!1;try{dispatchResult=await dispatchInboundMessage({ctx:ctxPayload,cfg,dispatcher,replyOptions:{...replyOptions,skillFilter:channelConfig?.skills,disableBlockStreaming:typeof discordConfig?.blockStreaming==`boolean`?!discordConfig.blockStreaming:void 0,onModelSelected,onReasoningStream:async()=>{await statusReactions.setThinking()},onToolStart:async payload=>{await statusReactions.setTool(payload.name)}}})}catch(err){throw dispatchError=!0,err}finally{markDispatchIdle(),statusReactionsEnabled&&(dispatchError?await statusReactions.setError():await statusReactions.setDone(),removeAckAfterReply?(async()=>{await sleep(dispatchError?2500:1500),await statusReactions.clear()})():statusReactions.restoreInitial())}if(!dispatchResult?.queuedFinal){isGuildMessage&&clearHistoryEntriesIfEnabled({historyMap:guildHistories,historyKey:messageChannelId,limit:historyLimit});return}if(shouldLogVerbose()){let finalCount=dispatchResult.counts.final;logVerbose(`discord: delivered ${finalCount} reply${finalCount===1?``:`ies`} to ${replyTarget}`)}isGuildMessage&&clearHistoryEntriesIfEnabled({historyMap:guildHistories,historyKey:messageChannelId,limit:historyLimit})}function createDiscordMessageHandler(params){let groupPolicy=params.discordConfig?.groupPolicy??`open`,ackReactionScope=params.cfg.messages?.ackReactionScope??`group-mentions`,debouncer=createInboundDebouncer({debounceMs:resolveInboundDebounceMs({cfg:params.cfg,channel:`discord`}),buildKey:entry=>{let message=entry.data.message,authorId=entry.data.author?.id;if(!message||!authorId)return null;let channelId=resolveDiscordMessageChannelId({message,eventChannelId:entry.data.channel_id});return channelId?`discord:${params.accountId}:${channelId}:${authorId}`:null},shouldDebounce:entry=>{let message=entry.data.message;if(!message||message.attachments&&message.attachments.length>0)return!1;let baseText=resolveDiscordMessageText(message,{includeForwarded:!1});return baseText.trim()?!hasControlCommand(baseText,params.cfg):!1},onFlush:async entries=>{let last=entries.at(-1);if(!last)return;if(entries.length===1){let ctx=await preflightDiscordMessage({...params,ackReactionScope,groupPolicy,data:last.data,client:last.client});if(!ctx)return;await processDiscordMessage(ctx);return}let combinedBaseText=entries.map(entry=>resolveDiscordMessageText(entry.data.message,{includeForwarded:!1})).filter(Boolean).join(`
@@ -470,9 +470,9 @@ Critical rules from AGENTS.md:
470
470
  `)||``;if(!rawBody)return null;let ackReaction=resolveAckReaction(cfg,route.agentId,{channel:`slack`,accountId:account.accountId}),ackReactionValue=ackReaction??``,shouldAckReaction$2=()=>!!(ackReaction&&shouldAckReaction({scope:ctx.ackReactionScope,isDirect:isDirectMessage,isGroup:isRoomish,isMentionableGroup:isRoom,requireMention:!!shouldRequireMention,canDetectMention,effectiveWasMentioned,shouldBypassMention:mentionGate.shouldBypassMention})),ackReactionMessageTs=message.ts,ackReactionPromise=shouldAckReaction$2()&&ackReactionMessageTs&&ackReactionValue?reactSlackMessage(message.channel,ackReactionMessageTs,ackReactionValue,{token:ctx.botToken,client:ctx.app.client}).then(()=>!0,err=>(logVerbose(`slack react failed for channel ${message.channel}: ${String(err)}`),!1)):null,roomLabel=channelName?`#${channelName}`:`#${message.channel}`,preview=rawBody.replace(/\s+/g,` `).slice(0,160),inboundLabel=isDirectMessage?`Slack DM from ${senderName}`:`Slack message in ${roomLabel} from ${senderName}`,slackFrom=isDirectMessage?`slack:${message.user}`:isRoom?`slack:channel:${message.channel}`:`slack:group:${message.channel}`;enqueueSystemEvent(`${inboundLabel}: ${preview}`,{sessionKey,contextKey:`slack:message:${message.channel}:${message.ts??`unknown`}`});let envelopeFrom=resolveConversationLabel({ChatType:isDirectMessage?`direct`:`channel`,SenderName:senderName,GroupSubject:isRoomish?roomLabel:void 0,From:slackFrom})??(isDirectMessage?senderName:roomLabel),threadInfo=isThreadReply&&threadTs?` thread_ts: ${threadTs}${message.parent_user_id?` parent_user_id: ${message.parent_user_id}`:``}`:``,textWithId=`${rawBody}\n[slack message id: ${message.ts} channel: ${message.channel}${threadInfo}]`,storePath=resolveStorePath(ctx.cfg.session?.store,{agentId:route.agentId}),envelopeOptions=resolveEnvelopeFormatOptions(ctx.cfg),previousTimestamp=readSessionUpdatedAt({storePath,sessionKey:route.sessionKey}),combinedBody=formatInboundEnvelope({channel:`Slack`,from:envelopeFrom,timestamp:message.ts?Math.round(Number(message.ts)*1e3):void 0,body:textWithId,chatType:isDirectMessage?`direct`:`channel`,sender:{name:senderName,id:senderId},previousTimestamp,envelope:envelopeOptions});isRoomish&&ctx.historyLimit>0&&(combinedBody=buildPendingHistoryContextFromMap({historyMap:ctx.channelHistories,historyKey,limit:ctx.historyLimit,currentMessage:combinedBody,formatEntry:entry=>formatInboundEnvelope({channel:`Slack`,from:roomLabel,timestamp:entry.timestamp,body:`${entry.body}${entry.messageId?` [id:${entry.messageId} channel:${message.channel}]`:``}`,chatType:`channel`,senderLabel:entry.sender,envelope:envelopeOptions})}));let slackTo=isDirectMessage?`user:${message.user}`:`channel:${message.channel}`,{untrustedChannelMetadata,groupSystemPrompt}=resolveSlackRoomContextHints({isRoomish,channelInfo,channelConfig}),threadStarterBody,threadHistoryBody,threadSessionPreviousTimestamp,threadLabel,threadStarterMedia=null;if(isThreadReply&&threadTs){let starter=await resolveSlackThreadStarter({channelId:message.channel,threadTs,client:ctx.app.client});if(starter?.text){threadStarterBody=starter.text;let snippet=starter.text.replace(/\s+/g,` `).slice(0,80);threadLabel=`Slack thread ${roomLabel}${snippet?`: ${snippet}`:``}`,!effectiveDirectMedia&&starter.files&&starter.files.length>0&&(threadStarterMedia=await resolveSlackMedia({files:starter.files,token:ctx.botToken,maxBytes:ctx.mediaMaxBytes}),threadStarterMedia&&logVerbose(`slack: hydrated thread starter file ${threadStarterMedia.map(m=>m.placeholder).join(`, `)} from root message`))}else threadLabel=`Slack thread ${roomLabel}`;let threadInitialHistoryLimit=account.config?.thread?.initialHistoryLimit??20;if(threadSessionPreviousTimestamp=readSessionUpdatedAt({storePath,sessionKey}),threadInitialHistoryLimit>0&&!threadSessionPreviousTimestamp){let threadHistory=await resolveSlackThreadHistory({channelId:message.channel,threadTs,client:ctx.app.client,currentMessageTs:message.ts,limit:threadInitialHistoryLimit});if(threadHistory.length>0){let uniqueUserIds=[...new Set(threadHistory.map(m=>m.userId).filter(id=>!!id))],userMap=new Map;await Promise.all(uniqueUserIds.map(async id=>{let user=await ctx.resolveUserName(id);user&&userMap.set(id,user)}));let historyParts=[];for(let historyMsg of threadHistory){let msgSenderName=(historyMsg.userId?userMap.get(historyMsg.userId):null)?.name??(historyMsg.botId?`Bot (${historyMsg.botId})`:`Unknown`),role=historyMsg.botId?`assistant`:`user`,msgWithId=`${historyMsg.text}\n[slack message id: ${historyMsg.ts??`unknown`} channel: ${message.channel}]`;historyParts.push(formatInboundEnvelope({channel:`Slack`,from:`${msgSenderName} (${role})`,timestamp:historyMsg.ts?Math.round(Number(historyMsg.ts)*1e3):void 0,body:msgWithId,chatType:`channel`,envelope:envelopeOptions}))}threadHistoryBody=historyParts.join(`
471
471
 
472
472
  `),logVerbose(`slack: populated thread history with ${threadHistory.length} messages for new session`)}}}let effectiveMedia=effectiveDirectMedia??threadStarterMedia,firstMedia=effectiveMedia?.[0],inboundHistory=isRoomish&&ctx.historyLimit>0?(ctx.channelHistories.get(historyKey)??[]).map(entry=>({sender:entry.sender,body:entry.body,timestamp:entry.timestamp})):void 0,ctxPayload=finalizeInboundContext({Body:combinedBody,BodyForAgent:rawBody,InboundHistory:inboundHistory,RawBody:rawBody,CommandBody:rawBody,From:slackFrom,To:slackTo,SessionKey:sessionKey,AccountId:route.accountId,ChatType:isDirectMessage?`direct`:`channel`,ConversationLabel:envelopeFrom,GroupSubject:isRoomish?roomLabel:void 0,GroupSystemPrompt:isRoomish?groupSystemPrompt:void 0,UntrustedContext:untrustedChannelMetadata?[untrustedChannelMetadata]:void 0,SenderName:senderName,SenderId:senderId,Provider:`slack`,Surface:`slack`,MessageSid:message.ts,ReplyToId:threadContext.replyToId,MessageThreadId:threadContext.messageThreadId,ParentSessionKey:threadKeys.parentSessionKey,ThreadStarterBody:threadStarterBody,ThreadHistoryBody:threadHistoryBody,IsFirstThreadTurn:isThreadReply&&threadTs&&!threadSessionPreviousTimestamp?!0:void 0,ThreadLabel:threadLabel,Timestamp:message.ts?Math.round(Number(message.ts)*1e3):void 0,WasMentioned:isRoomish?effectiveWasMentioned:void 0,MediaPath:firstMedia?.path,MediaType:firstMedia?.contentType,MediaUrl:firstMedia?.path,MediaPaths:effectiveMedia&&effectiveMedia.length>0?effectiveMedia.map(m=>m.path):void 0,MediaUrls:effectiveMedia&&effectiveMedia.length>0?effectiveMedia.map(m=>m.path):void 0,MediaTypes:effectiveMedia&&effectiveMedia.length>0?effectiveMedia.map(m=>m.contentType??``):void 0,CommandAuthorized:commandAuthorized,OriginatingChannel:`slack`,OriginatingTo:slackTo});await recordInboundSession({storePath,sessionKey,ctx:ctxPayload,updateLastRoute:isDirectMessage?{sessionKey:route.mainSessionKey,channel:`slack`,to:`user:${message.user}`,accountId:route.accountId}:void 0,onRecordError:err=>{ctx.logger.warn({error:String(err),storePath,sessionKey},`failed updating session meta`)}});let replyTarget=ctxPayload.To??void 0;return replyTarget?(shouldLogVerbose()&&logVerbose(`slack inbound: channel=${message.channel} from=${slackFrom} preview="${preview}"`),{ctx,account,message,route,channelConfig,replyTarget,ctxPayload,isDirectMessage,isRoomish,historyKey,preview,ackReactionMessageTs,ackReactionValue,ackReactionPromise}):null}const normalizeThreadTs=threadTs=>threadTs?.trim()||void 0;async function resolveThreadTsFromHistory(params){try{let response=await params.client.conversations.history({channel:params.channelId,latest:params.messageTs,oldest:params.messageTs,inclusive:!0,limit:1});return normalizeThreadTs((response.messages?.find(entry=>entry.ts===params.messageTs)??response.messages?.[0])?.thread_ts)}catch(err){shouldLogVerbose()&&logVerbose(`slack inbound: failed to resolve thread_ts via conversations.history for channel=${params.channelId} ts=${params.messageTs}: ${String(err)}`);return}}function createSlackThreadTsResolver(params){let ttlMs=Math.max(0,params.cacheTtlMs??6e4),maxSize=Math.max(0,params.maxSize??500),cache=new Map,inflight=new Map,getCached=(key,now)=>{let entry=cache.get(key);if(entry){if(ttlMs>0&&now-entry.updatedAt>ttlMs){cache.delete(key);return}return cache.delete(key),cache.set(key,{...entry,updatedAt:now}),entry.threadTs}},setCached=(key,threadTs,now)=>{cache.delete(key),cache.set(key,{threadTs,updatedAt:now}),pruneMapToMaxSize(cache,maxSize)};return{resolve:async request=>{let{message}=request;if(!message.parent_user_id||message.thread_ts||!message.ts)return message;let cacheKey=`${message.channel}:${message.ts}`,cached=getCached(cacheKey,Date.now());if(cached!==void 0)return cached?{...message,thread_ts:cached}:message;shouldLogVerbose()&&logVerbose(`slack inbound: missing thread_ts for thread reply channel=${message.channel} ts=${message.ts} source=${request.source}`);let pending=inflight.get(cacheKey);pending||(pending=resolveThreadTsFromHistory({client:params.client,channelId:message.channel,messageTs:message.ts}),inflight.set(cacheKey,pending));let resolved;try{resolved=await pending}finally{inflight.delete(cacheKey)}return setCached(cacheKey,resolved??null,Date.now()),resolved?(shouldLogVerbose()&&logVerbose(`slack inbound: resolved missing thread_ts channel=${message.channel} ts=${message.ts} -> thread_ts=${resolved}`),{...message,thread_ts:resolved}):(shouldLogVerbose()&&logVerbose(`slack inbound: could not resolve missing thread_ts channel=${message.channel} ts=${message.ts}`),message)}}}function createSlackMessageHandler(params){let{ctx,account}=params,debounceMs=resolveInboundDebounceMs({cfg:ctx.cfg,channel:`slack`}),threadTsResolver=createSlackThreadTsResolver({client:ctx.app.client}),debouncer=createInboundDebouncer({debounceMs,buildKey:entry=>{let senderId=entry.message.user??entry.message.bot_id;if(!senderId)return null;let messageTs=entry.message.ts??entry.message.event_ts,threadKey=entry.message.thread_ts?`${entry.message.channel}:${entry.message.thread_ts}`:entry.message.parent_user_id&&messageTs?`${entry.message.channel}:maybe-thread:${messageTs}`:entry.message.channel;return`slack:${ctx.accountId}:${threadKey}:${senderId}`},shouldDebounce:entry=>{let text=entry.message.text??``;return!text.trim()||entry.message.files&&entry.message.files.length>0?!1:!hasControlCommand(stripSlackMentionsForCommandDetection(text),ctx.cfg)},onFlush:async entries=>{let last=entries.at(-1);if(!last)return;let combinedText=entries.length===1?last.message.text??``:entries.map(entry=>entry.message.text??``).filter(Boolean).join(`
473
- `),combinedMentioned=entries.some(entry=>!!entry.opts.wasMentioned),prepared=await prepareSlackMessage({ctx,account,message:{...last.message,text:combinedText},opts:{...last.opts,wasMentioned:combinedMentioned||last.opts.wasMentioned}});if(prepared){if(entries.length>1){let ids=entries.map(entry=>entry.message.ts).filter(Boolean);ids.length>0&&(prepared.ctxPayload.MessageSids=ids,prepared.ctxPayload.MessageSidFirst=ids[0],prepared.ctxPayload.MessageSidLast=ids[ids.length-1])}await dispatchPreparedSlackMessage(prepared)}},onError:err=>{ctx.runtime.error?.(`slack inbound debounce flush failed: ${String(err)}`)}});return async(message,opts)=>{if(opts.source===`message`&&message.type!==`message`||opts.source===`message`&&message.subtype&&message.subtype!==`file_share`&&message.subtype!==`bot_message`||ctx.markMessageSeen(message.channel,message.ts))return;let resolvedMessage=await threadTsResolver.resolve({message,source:opts.source});await debouncer.enqueue({message:resolvedMessage,opts})}}const SLACK_COMMAND_ARG_ACTION_ID=`builderforce_cmdarg`,SLACK_COMMAND_ARG_VALUE_PREFIX=`cmdarg`,SLACK_COMMAND_ARG_EXTERNAL_PREFIX=`builderforce_cmdarg_ext:`,slackExternalArgMenuStore=new Map;function truncatePlainText(value,max){let trimmed=value.trim();return trimmed.length<=max?trimmed:max<=1?trimmed.slice(0,max):`${trimmed.slice(0,max-1)}…`}function escapeSlackMrkdwn(value){return value.replaceAll(`\\`,`\\\\`).replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replace(/([*_`~])/g,`\\$1`)}function buildSlackArgMenuConfirm(params){return{title:{type:`plain_text`,text:`Confirm selection`},text:{type:`mrkdwn`,text:`Run */${escapeSlackMrkdwn(params.command)}* with *${escapeSlackMrkdwn(params.arg)}* set to this value?`},confirm:{type:`plain_text`,text:`Run command`},deny:{type:`plain_text`,text:`Cancel`}}}function pruneSlackExternalArgMenuStore(now=Date.now()){for(let[token,entry]of slackExternalArgMenuStore.entries())entry.expiresAt<=now&&slackExternalArgMenuStore.delete(token)}function storeSlackExternalArgMenu(params){pruneSlackExternalArgMenuStore();let token=`${Date.now().toString(36)}${Math.random().toString(36).slice(2,10)}`;return slackExternalArgMenuStore.set(token,{choices:params.choices,userId:params.userId,expiresAt:Date.now()+6e5}),token}function readSlackExternalArgMenuToken(raw){if(typeof raw!=`string`||!raw.startsWith(SLACK_COMMAND_ARG_EXTERNAL_PREFIX))return;let token=raw.slice(24).trim();return token.length>0?token:void 0}function encodeSlackCommandArgValue(parts){return[SLACK_COMMAND_ARG_VALUE_PREFIX,encodeURIComponent(parts.command),encodeURIComponent(parts.arg),encodeURIComponent(parts.value),encodeURIComponent(parts.userId)].join(`|`)}function parseSlackCommandArgValue(raw){if(!raw)return null;let parts=raw.split(`|`);if(parts.length!==5||parts[0]!==SLACK_COMMAND_ARG_VALUE_PREFIX)return null;let[,command,arg,value,userId]=parts;if(!command||!arg||!value||!userId)return null;let decode=text=>{try{return decodeURIComponent(text)}catch{return null}},decodedCommand=decode(command),decodedArg=decode(arg),decodedValue=decode(value),decodedUserId=decode(userId);return!decodedCommand||!decodedArg||!decodedValue||!decodedUserId?null:{command:decodedCommand,arg:decodedArg,value:decodedValue,userId:decodedUserId}}function buildSlackCommandArgMenuBlocks(params){let encodedChoices=params.choices.map(choice=>({label:choice.label,value:encodeSlackCommandArgValue({command:params.command,arg:params.arg,value:choice.value,userId:params.userId})})),canUseStaticSelect=encodedChoices.every(choice=>choice.value.length<=75),canUseOverflow=canUseStaticSelect&&encodedChoices.length>=3&&encodedChoices.length<=5,canUseExternalSelect=params.supportsExternalSelect&&canUseStaticSelect&&encodedChoices.length>100,rows=canUseOverflow?[{type:`actions`,elements:[{type:`overflow`,action_id:SLACK_COMMAND_ARG_ACTION_ID,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg}),options:encodedChoices.map(choice=>({text:{type:`plain_text`,text:choice.label.slice(0,75)},value:choice.value}))}]}]:canUseExternalSelect?[{type:`actions`,block_id:`${SLACK_COMMAND_ARG_EXTERNAL_PREFIX}${params.createExternalMenuToken(encodedChoices)}`,elements:[{type:`external_select`,action_id:SLACK_COMMAND_ARG_ACTION_ID,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg}),min_query_length:0,placeholder:{type:`plain_text`,text:`Search ${params.arg}`}}]}]:encodedChoices.length<=5||!canUseStaticSelect?chunkItems(encodedChoices,5).map(choices=>({type:`actions`,elements:choices.map(choice=>({type:`button`,action_id:SLACK_COMMAND_ARG_ACTION_ID,text:{type:`plain_text`,text:choice.label},value:choice.value,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg})}))})):chunkItems(encodedChoices,100).map((choices,index)=>({type:`actions`,elements:[{type:`static_select`,action_id:SLACK_COMMAND_ARG_ACTION_ID,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg}),placeholder:{type:`plain_text`,text:index===0?`Choose ${params.arg}`:`Choose ${params.arg} (${index+1})`},options:choices.map(choice=>({text:{type:`plain_text`,text:choice.label.slice(0,75)},value:choice.value}))}]})),headerText=truncatePlainText(`/${params.command}: choose ${params.arg}`,150),sectionText=truncatePlainText(params.title,3e3),contextText=truncatePlainText(`Select one option to continue /${params.command} (${params.arg})`,3e3);return[{type:`header`,text:{type:`plain_text`,text:headerText}},{type:`section`,text:{type:`mrkdwn`,text:sectionText}},{type:`context`,elements:[{type:`mrkdwn`,text:contextText}]},...rows]}async function registerSlackMonitorSlashCommands(params){let{ctx,account}=params,cfg=ctx.cfg,runtime=ctx.runtime,supportsInteractiveArgMenus=typeof ctx.app.action==`function`,supportsExternalArgMenus=typeof ctx.app.options==`function`,slashCommand=resolveSlackSlashCommandConfig(ctx.slashCommand??account.config.slashCommand),handleSlashCommand=async p=>{let{command,ack,respond,prompt,commandArgs,commandDefinition}=p;try{if(!prompt.trim()){await ack({text:`Message required.`,response_type:`ephemeral`});return}if(await ack(),ctx.botUserId&&command.user_id===ctx.botUserId)return;let channelInfo=await ctx.resolveChannelName(command.channel_id),channelType=normalizeSlackChannelType(channelInfo?.type??(command.channel_name===`directmessage`?`im`:void 0),command.channel_id),isDirectMessage=channelType===`im`,isGroupDm=channelType===`mpim`,isRoom=channelType===`channel`||channelType===`group`,isRoomish=isRoom||isGroupDm;if(!ctx.isChannelAllowed({channelId:command.channel_id,channelName:channelInfo?.name,channelType})){await respond({text:`This channel is not allowed.`,response_type:`ephemeral`});return}let storeAllowFrom=await readChannelAllowFromStore(`slack`).catch(()=>[]),effectiveAllowFromLower=normalizeAllowListLower(normalizeAllowList$2([...ctx.allowFrom,...storeAllowFrom])),commandAuthorized=!1,channelConfig=null;if(isDirectMessage){if(!ctx.dmEnabled||ctx.dmPolicy===`disabled`){await respond({text:`Slack DMs are disabled.`,response_type:`ephemeral`});return}if(ctx.dmPolicy!==`open`){let senderName=(await ctx.resolveUserName(command.user_id))?.name??void 0,allowMatch=resolveSlackAllowListMatch({allowList:effectiveAllowFromLower,id:command.user_id,name:senderName}),allowMatchMeta=formatAllowlistMatchMeta(allowMatch);if(!allowMatch.allowed){if(ctx.dmPolicy===`pairing`){let{code,created}=await upsertChannelPairingRequest({channel:`slack`,id:command.user_id,meta:{name:senderName}});created&&(logVerbose(`slack pairing request sender=${command.user_id} name=${senderName??`unknown`} (${allowMatchMeta})`),await respond({text:buildPairingReply({channel:`slack`,idLine:`Your Slack user id: ${command.user_id}`,code}),response_type:`ephemeral`}))}else logVerbose(`slack: blocked slash sender ${command.user_id} (dmPolicy=${ctx.dmPolicy}, ${allowMatchMeta})`),await respond({text:`You are not authorized to use this command.`,response_type:`ephemeral`});return}}}if(isRoom&&(channelConfig=resolveSlackChannelConfig({channelId:command.channel_id,channelName:channelInfo?.name,channels:ctx.channelsConfig,defaultRequireMention:ctx.defaultRequireMention}),ctx.useAccessGroups)){let channelAllowlistConfigured=!!ctx.channelsConfig&&Object.keys(ctx.channelsConfig??{}).length>0,channelAllowed=channelConfig?.allowed!==!1;if(!isSlackChannelAllowedByPolicy({groupPolicy:ctx.groupPolicy,channelAllowlistConfigured,channelAllowed})){await respond({text:`This channel is not allowed.`,response_type:`ephemeral`});return}let hasExplicitConfig=!!channelConfig?.matchSource;if(!channelAllowed&&(ctx.groupPolicy!==`open`||hasExplicitConfig)){await respond({text:`This channel is not allowed.`,response_type:`ephemeral`});return}}let senderName=(await ctx.resolveUserName(command.user_id))?.name??command.user_name??command.user_id,channelUsersAllowlistConfigured=isRoom&&Array.isArray(channelConfig?.users)&&channelConfig.users.length>0,channelUserAllowed=channelUsersAllowlistConfigured?resolveSlackUserAllowed({allowList:channelConfig?.users,userId:command.user_id,userName:senderName}):!1;if(channelUsersAllowlistConfigured&&!channelUserAllowed){await respond({text:`You are not authorized to use this command here.`,response_type:`ephemeral`});return}let ownerAllowed=resolveSlackAllowListMatch({allowList:effectiveAllowFromLower,id:command.user_id,name:senderName}).allowed;if(commandAuthorized=resolveCommandAuthorizedFromAuthorizers({useAccessGroups:ctx.useAccessGroups,authorizers:[{configured:effectiveAllowFromLower.length>0,allowed:ownerAllowed}],modeWhenAccessGroupsOff:`configured`}),isRoomish&&(commandAuthorized=resolveCommandAuthorizedFromAuthorizers({useAccessGroups:ctx.useAccessGroups,authorizers:[{configured:effectiveAllowFromLower.length>0,allowed:ownerAllowed},{configured:channelUsersAllowlistConfigured,allowed:channelUserAllowed}],modeWhenAccessGroupsOff:`configured`}),ctx.useAccessGroups&&!commandAuthorized)){await respond({text:`You are not authorized to use this command.`,response_type:`ephemeral`});return}if(commandDefinition&&supportsInteractiveArgMenus){let menu=resolveCommandArgMenu({command:commandDefinition,args:commandArgs,cfg});if(menu){let commandLabel=commandDefinition.nativeName??commandDefinition.key,title=menu.title??`Choose ${menu.arg.description||menu.arg.name} for /${commandLabel}.`;await respond({text:title,blocks:buildSlackCommandArgMenuBlocks({title,command:commandLabel,arg:menu.arg.name,choices:menu.choices,userId:command.user_id,supportsExternalSelect:supportsExternalArgMenus,createExternalMenuToken:choices=>storeSlackExternalArgMenu({choices,userId:command.user_id})}),response_type:`ephemeral`});return}}let channelName=channelInfo?.name,roomLabel=channelName?`#${channelName}`:`#${command.channel_id}`,[{resolveAgentRoute},{finalizeInboundContext},{dispatchReplyWithDispatcher}]=await Promise.all([import(`./resolve-route-Bm9nidh9.js`),import(`./inbound-context-CNt0Mycm.js`),import(`./provider-dispatcher-C4nHaNqn.js`)]),[{resolveConversationLabel},{createReplyPrefixOptions}]=await Promise.all([import(`./conversation-label-DIsKX76t.js`),import(`./reply-prefix-BqxxNtel.js`)]),route=resolveAgentRoute({cfg,channel:`slack`,accountId:account.accountId,teamId:ctx.teamId||void 0,peer:{kind:isDirectMessage?`direct`:isRoom?`channel`:`group`,id:isDirectMessage?command.user_id:command.channel_id}}),{untrustedChannelMetadata,groupSystemPrompt}=resolveSlackRoomContextHints({isRoomish,channelInfo,channelConfig}),ctxPayload=finalizeInboundContext({Body:prompt,BodyForAgent:prompt,RawBody:prompt,CommandBody:prompt,CommandArgs:commandArgs,From:isDirectMessage?`slack:${command.user_id}`:isRoom?`slack:channel:${command.channel_id}`:`slack:group:${command.channel_id}`,To:`slash:${command.user_id}`,ChatType:isDirectMessage?`direct`:`channel`,ConversationLabel:resolveConversationLabel({ChatType:isDirectMessage?`direct`:`channel`,SenderName:senderName,GroupSubject:isRoomish?roomLabel:void 0,From:isDirectMessage?`slack:${command.user_id}`:isRoom?`slack:channel:${command.channel_id}`:`slack:group:${command.channel_id}`})??(isDirectMessage?senderName:roomLabel),GroupSubject:isRoomish?roomLabel:void 0,GroupSystemPrompt:isRoomish?groupSystemPrompt:void 0,UntrustedContext:untrustedChannelMetadata?[untrustedChannelMetadata]:void 0,SenderName:senderName,SenderId:command.user_id,Provider:`slack`,Surface:`slack`,WasMentioned:!0,MessageSid:command.trigger_id,Timestamp:Date.now(),SessionKey:`agent:${route.agentId}:${slashCommand.sessionPrefix}:${command.user_id}`.toLowerCase(),CommandTargetSessionKey:route.sessionKey,AccountId:route.accountId,CommandSource:`native`,CommandAuthorized:commandAuthorized,OriginatingChannel:`slack`,OriginatingTo:`user:${command.user_id}`}),{onModelSelected,...prefixOptions}=createReplyPrefixOptions({cfg,agentId:route.agentId,channel:`slack`,accountId:route.accountId}),deliverSlashPayloads=async replies=>{let[{deliverSlackSlashReplies},{resolveChunkMode},{resolveMarkdownTableMode}]=await Promise.all([import(`./replies-DIBQzxGp.js`),import(`./chunk-BWr2jvx4.js`),import(`./markdown-tables-B2n2SW0j.js`)]);await deliverSlackSlashReplies({replies,respond,ephemeral:slashCommand.ephemeral,textLimit:ctx.textLimit,chunkMode:resolveChunkMode(cfg,`slack`,route.accountId),tableMode:resolveMarkdownTableMode({cfg,channel:`slack`,accountId:route.accountId})})},{counts}=await dispatchReplyWithDispatcher({ctx:ctxPayload,cfg,dispatcherOptions:{...prefixOptions,deliver:async payload=>deliverSlashPayloads([payload]),onError:(err,info)=>{runtime.error?.(danger(`slack slash ${info.kind} reply failed: ${String(err)}`))}},replyOptions:{skillFilter:channelConfig?.skills,onModelSelected}});counts.final+counts.tool+counts.block===0&&await deliverSlashPayloads([])}catch(err){runtime.error?.(danger(`slack slash handler failed: ${String(err)}`)),await respond({text:`Sorry, something went wrong handling that command.`,response_type:`ephemeral`})}},nativeEnabled=resolveNativeCommandsEnabled({providerId:`slack`,providerSetting:account.config.commands?.native,globalSetting:cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`slack`,providerSetting:account.config.commands?.nativeSkills,globalSetting:cfg.commands?.nativeSkills}),nativeCommands=[];if(nativeEnabled&&(nativeCommands=listNativeCommandSpecsForConfig(cfg,{skillCommands:nativeSkillsEnabled?listSkillCommandsForAgents({cfg}):[],provider:`slack`})),nativeCommands.length>0)for(let command of nativeCommands)ctx.app.command(`/${command.name}`,async({command:cmd,ack,respond})=>{let commandDefinition=findCommandByNativeName(command.name,`slack`),rawText=cmd.text?.trim()??``,commandArgs=commandDefinition?parseCommandArgs(commandDefinition,rawText):rawText?{raw:rawText}:void 0;await handleSlashCommand({command:cmd,ack,respond,prompt:commandDefinition?buildCommandTextFromArgs(commandDefinition,commandArgs):rawText?`/${command.name} ${rawText}`:`/${command.name}`,commandArgs,commandDefinition:commandDefinition??void 0})});else slashCommand.enabled?ctx.app.command(buildSlackSlashCommandMatcher(slashCommand.name),async({command,ack,respond})=>{await handleSlashCommand({command,ack,respond,prompt:command.text?.trim()??``})}):logVerbose(`slack: slash commands disabled`);nativeCommands.length===0||!supportsInteractiveArgMenus||((()=>{let optionsHandler=ctx.app.options;typeof optionsHandler==`function`&&optionsHandler(SLACK_COMMAND_ARG_ACTION_ID,async({ack,body})=>{let typedBody=body;pruneSlackExternalArgMenuStore();let token=readSlackExternalArgMenuToken(typedBody.actions?.[0]?.block_id??typedBody.block_id);if(!token){await ack({options:[]});return}let entry=slackExternalArgMenuStore.get(token);if(!entry){await ack({options:[]});return}if(typedBody.user?.id&&typedBody.user.id!==entry.userId){await ack({options:[]});return}let query=typedBody.value?.trim().toLowerCase()??``;await ack({options:entry.choices.filter(choice=>!query||choice.label.toLowerCase().includes(query)).slice(0,100).map(choice=>({text:{type:`plain_text`,text:choice.label.slice(0,75)},value:choice.value}))})})})(),(actionId=>{ctx.app.action(actionId,async args=>{let{ack,body,respond}=args,action=args.action;await ack();let respondFn=respond??(async payload=>{!body.channel?.id||!body.user?.id||await ctx.app.client.chat.postEphemeral({token:ctx.botToken,channel:body.channel.id,user:body.user.id,text:payload.text,blocks:payload.blocks})}),parsed=parseSlackCommandArgValue(action?.value??action?.selected_option?.value);if(!parsed){await respondFn({text:`Sorry, that button is no longer valid.`,response_type:`ephemeral`});return}if(body.user?.id&&parsed.userId!==body.user.id){await respondFn({text:`That menu is for another user.`,response_type:`ephemeral`});return}let commandDefinition=findCommandByNativeName(parsed.command,`slack`),commandArgs={values:{[parsed.arg]:parsed.value}},prompt=commandDefinition?buildCommandTextFromArgs(commandDefinition,commandArgs):`/${parsed.command} ${parsed.value}`,user=body.user,userName=user&&`name`in user&&user.name?user.name:user&&`username`in user&&user.username?user.username:user?.id??``,triggerId=`trigger_id`in body?body.trigger_id:void 0;await handleSlashCommand({command:{user_id:user?.id??``,user_name:userName,channel_id:body.channel?.id??``,channel_name:body.channel?.name??body.channel?.id??``,trigger_id:triggerId??String(Date.now())},ack:async()=>{},respond:respondFn,prompt,commandArgs,commandDefinition:commandDefinition??void 0})})})(SLACK_COMMAND_ARG_ACTION_ID))}const slackBoltModule=SlackBolt,{App,HTTPReceiver}=(slackBoltModule.App?slackBoltModule:slackBoltModule.default)??slackBoltModule;function parseApiAppIdFromAppToken(raw){let token=raw?.trim();if(token)return/^xapp-\d-([a-z0-9]+)-/i.exec(token)?.[1]?.toUpperCase()}async function monitorSlackProvider(opts={}){let cfg=opts.config??loadConfig(),account=resolveSlackAccount({cfg,accountId:opts.accountId}),historyLimit=Math.max(0,account.config.historyLimit??cfg.messages?.groupChat?.historyLimit??50),sessionCfg=cfg.session,sessionScope=sessionCfg?.scope??`per-sender`,mainKey=normalizeMainKey(sessionCfg?.mainKey),slackMode=opts.mode??account.config.mode??`socket`,slackWebhookPath=normalizeSlackWebhookPath(account.config.webhookPath),signingSecret=account.config.signingSecret?.trim(),botToken=resolveSlackBotToken(opts.botToken??account.botToken),appToken=resolveSlackAppToken(opts.appToken??account.appToken);if(!botToken||slackMode!==`http`&&!appToken){let missing=slackMode===`http`?`Slack bot token missing for account "${account.accountId}" (set channels.slack.accounts.${account.accountId}.botToken or SLACK_BOT_TOKEN for default).`:`Slack bot + app tokens missing for account "${account.accountId}" (set channels.slack.accounts.${account.accountId}.botToken/appToken or SLACK_BOT_TOKEN/SLACK_APP_TOKEN for default).`;throw Error(missing)}if(slackMode===`http`&&!signingSecret)throw Error(`Slack signing secret missing for account "${account.accountId}" (set channels.slack.signingSecret or channels.slack.accounts.${account.accountId}.signingSecret).`);let runtime=opts.runtime??createNonExitingRuntime(),slackCfg=account.config,dmConfig=slackCfg.dm,dmEnabled=dmConfig?.enabled??!0,dmPolicy=slackCfg.dmPolicy??dmConfig?.policy??`pairing`,allowFrom=slackCfg.allowFrom??dmConfig?.allowFrom,groupDmEnabled=dmConfig?.groupEnabled??!1,groupDmChannels=dmConfig?.groupChannels,channelsConfig=slackCfg.channels,defaultGroupPolicy=cfg.channels?.defaults?.groupPolicy,groupPolicy=slackCfg.groupPolicy??defaultGroupPolicy??`open`;slackCfg.groupPolicy===void 0&&slackCfg.channels===void 0&&defaultGroupPolicy===void 0&&groupPolicy===`open`&&runtime.log?.(warn(`slack: groupPolicy defaults to "open" when channels.slack is missing; set channels.slack.groupPolicy (or channels.defaults.groupPolicy) or add channels.slack.channels to restrict access.`));let resolveToken=slackCfg.userToken?.trim()||botToken,useAccessGroups=cfg.commands?.useAccessGroups!==!1,reactionMode=slackCfg.reactionNotifications??`own`,reactionAllowlist=slackCfg.reactionAllowlist??[],replyToMode=slackCfg.replyToMode??`all`,threadHistoryScope=slackCfg.thread?.historyScope??`thread`,threadInheritParent=slackCfg.thread?.inheritParent??!1,slashCommand=resolveSlackSlashCommandConfig(opts.slashCommand??slackCfg.slashCommand),textLimit=resolveTextChunkLimit(cfg,`slack`,account.accountId),ackReactionScope=cfg.messages?.ackReactionScope??`group-mentions`,mediaMaxBytes=(opts.mediaMaxMb??slackCfg.mediaMaxMb??20)*1024*1024,removeAckAfterReply=cfg.messages?.removeAckAfterReply??!1,receiver=slackMode===`http`?new HTTPReceiver({signingSecret:signingSecret??``,endpoints:slackWebhookPath}):null,clientOptions=resolveSlackWebClientOptions(),app=new App(slackMode===`socket`?{token:botToken,appToken,socketMode:!0,clientOptions}:{token:botToken,receiver:receiver??void 0,clientOptions}),slackHttpHandler=slackMode===`http`&&receiver?async(req,res)=>{let guard=installRequestBodyLimitGuard(req,res,{maxBytes:1048576,timeoutMs:3e4,responseFormat:`text`});if(!guard.isTripped())try{await Promise.resolve(receiver.requestListener(req,res))}catch(err){if(!guard.isTripped())throw err}finally{guard.dispose()}}:null,unregisterHttpHandler=null,botUserId=``,teamId=``,apiAppId=``,expectedApiAppIdFromAppToken=parseApiAppIdFromAppToken(appToken);try{let auth=await app.client.auth.test({token:botToken});botUserId=auth.user_id??``,teamId=auth.team_id??``,apiAppId=auth.api_app_id??``}catch{}apiAppId&&expectedApiAppIdFromAppToken&&apiAppId!==expectedApiAppIdFromAppToken&&runtime.error?.(`slack token mismatch: bot token api_app_id=${apiAppId} but app token looks like api_app_id=${expectedApiAppIdFromAppToken}`);let ctx=createSlackMonitorContext({cfg,accountId:account.accountId,botToken,app,runtime,botUserId,teamId,apiAppId,historyLimit,sessionScope,mainKey,dmEnabled,dmPolicy,allowFrom,groupDmEnabled,groupDmChannels,defaultRequireMention:slackCfg.requireMention,channelsConfig,groupPolicy,useAccessGroups,reactionMode,reactionAllowlist,replyToMode,threadHistoryScope,threadInheritParent,slashCommand,textLimit,ackReactionScope,mediaMaxBytes,removeAckAfterReply});registerSlackMonitorEvents({ctx,account,handleSlackMessage:createSlackMessageHandler({ctx,account})}),await registerSlackMonitorSlashCommands({ctx,account}),slackMode===`http`&&slackHttpHandler&&(unregisterHttpHandler=registerSlackHttpHandler({path:slackWebhookPath,handler:slackHttpHandler,log:runtime.log,accountId:account.accountId})),resolveToken&&(async()=>{if(opts.abortSignal?.aborted)return;if(channelsConfig&&Object.keys(channelsConfig).length>0)try{let entries=Object.keys(channelsConfig).filter(key=>key!==`*`);if(entries.length>0){let resolved=await resolveSlackChannelAllowlist({token:resolveToken,entries}),nextChannels={...channelsConfig},mapping=[],unresolved=[];for(let entry of resolved){let source=channelsConfig?.[entry.input];if(!source)continue;if(!entry.resolved||!entry.id){unresolved.push(entry.input);continue}mapping.push(`${entry.input}→${entry.id}${entry.archived?` (archived)`:``}`);let existing=nextChannels[entry.id]??{};nextChannels[entry.id]={...source,...existing}}channelsConfig=nextChannels,ctx.channelsConfig=nextChannels,summarizeMapping(`slack channels`,mapping,unresolved,runtime)}}catch(err){runtime.log?.(`slack channel resolve failed; using config entries. ${String(err)}`)}let allowEntries=allowFrom?.filter(entry=>String(entry).trim()&&String(entry).trim()!==`*`)??[];if(allowEntries.length>0)try{let{mapping,unresolved,additions}=buildAllowlistResolutionSummary(await resolveSlackUserAllowlist({token:resolveToken,entries:allowEntries.map(entry=>String(entry))}),{formatResolved:entry=>{let note=entry.note?` (${entry.note})`:``;return`${entry.input}→${entry.id}${note}`}});allowFrom=mergeAllowlist({existing:allowFrom,additions}),ctx.allowFrom=normalizeAllowList$2(allowFrom),summarizeMapping(`slack users`,mapping,unresolved,runtime)}catch(err){runtime.log?.(`slack user resolve failed; using config entries. ${String(err)}`)}if(channelsConfig&&Object.keys(channelsConfig).length>0){let userEntries=new Set;for(let channel of Object.values(channelsConfig))addAllowlistUserEntriesFromConfigEntry(userEntries,channel);if(userEntries.size>0)try{let{resolvedMap,mapping,unresolved}=buildAllowlistResolutionSummary(await resolveSlackUserAllowlist({token:resolveToken,entries:Array.from(userEntries)})),nextChannels=patchAllowlistUsersInConfigEntries({entries:channelsConfig,resolvedMap});channelsConfig=nextChannels,ctx.channelsConfig=nextChannels,summarizeMapping(`slack channel users`,mapping,unresolved,runtime)}catch(err){runtime.log?.(`slack channel user resolve failed; using config entries. ${String(err)}`)}}})();let stopOnAbort=()=>{opts.abortSignal?.aborted&&slackMode===`socket`&&app.stop()};opts.abortSignal?.addEventListener(`abort`,stopOnAbort,{once:!0});try{if(slackMode===`socket`?(await app.start(),runtime.log?.(`slack socket mode connected`)):runtime.log?.(`slack http mode listening at ${slackWebhookPath}`),opts.abortSignal?.aborted)return;await new Promise(resolve=>{opts.abortSignal?.addEventListener(`abort`,()=>resolve(),{once:!0})})}finally{opts.abortSignal?.removeEventListener(`abort`,stopOnAbort),unregisterHttpHandler?.(),await app.stop().catch(()=>void 0)}}async function probeSlack(token,timeoutMs=2500){let client=createSlackWebClient(token),start=Date.now();try{let result=await withTimeout(client.auth.test(),timeoutMs);return result.ok?{ok:!0,status:200,elapsedMs:Date.now()-start,bot:{id:result.user_id??void 0,name:result.user??void 0},team:{id:result.team_id??void 0,name:result.team??void 0}}:{ok:!1,status:200,error:result.error??`unknown`,elapsedMs:Date.now()-start}}catch(err){let message=err instanceof Error?err.message:String(err);return{ok:!1,status:typeof err.status==`number`?err.status:null,error:message,elapsedMs:Date.now()-start}}}function collectTelegramUnmentionedGroupIds(groups){if(!groups||typeof groups!=`object`)return{groupIds:[],unresolvedGroups:0,hasWildcardUnmentionedGroups:!1};let hasWildcardUnmentionedGroups=groups[`*`]?.requireMention===!1&&groups[`*`]?.enabled!==!1,groupIds=[],unresolvedGroups=0;for(let[key,value]of Object.entries(groups)){if(key===`*`||!value||typeof value!=`object`||value.enabled===!1||value.requireMention!==!1)continue;let id=String(key).trim();id&&(/^-?\d+$/.test(id)?groupIds.push(id):unresolvedGroups+=1)}return groupIds.sort((a,b)=>a.localeCompare(b)),{groupIds,unresolvedGroups,hasWildcardUnmentionedGroups}}async function auditTelegramGroupMembership(params){let started=Date.now(),token=params.token?.trim()??``;if(!token||params.groupIds.length===0)return{ok:!0,checkedGroups:0,unresolvedGroups:0,hasWildcardUnmentionedGroups:!1,groups:[],elapsedMs:Date.now()-started};let fetcher=params.proxyUrl?makeProxyFetch(params.proxyUrl):fetch,base=`https://api.telegram.org/bot${token}`,groups=[];for(let chatId of params.groupIds)try{let res=await fetchWithTimeout(`${base}/getChatMember?chat_id=${encodeURIComponent(chatId)}&user_id=${encodeURIComponent(String(params.botId))}`,{},params.timeoutMs,fetcher),json=await res.json();if(!res.ok||!isRecord$1(json)||!json.ok){let desc=isRecord$1(json)&&!json.ok&&typeof json.description==`string`?json.description:`getChatMember failed (${res.status})`;groups.push({chatId,ok:!1,status:null,error:desc,matchKey:chatId,matchSource:`id`});continue}let status=isRecord$1(json.result)?json.result.status??null:null,ok=status===`creator`||status===`administrator`||status===`member`;groups.push({chatId,ok,status,error:ok?null:`bot not in group`,matchKey:chatId,matchSource:`id`})}catch(err){groups.push({chatId,ok:!1,status:null,error:err instanceof Error?err.message:String(err),matchKey:chatId,matchSource:`id`})}return{ok:groups.every(g=>g.ok),checkedGroups:groups.length,unresolvedGroups:0,hasWildcardUnmentionedGroups:!1,groups,elapsedMs:Date.now()-started}}function resolveTelegramAllowedUpdates(){let updates=[...API_CONSTANTS.DEFAULT_UPDATE_TYPES];return updates.includes(`message_reaction`)||updates.push(`message_reaction`),updates.includes(`channel_post`)||updates.push(`channel_post`),updates}const resolveTelegramUpdateId=ctx=>ctx.update?.update_id??ctx.update_id,buildTelegramUpdateKey=ctx=>{let updateId=resolveTelegramUpdateId(ctx);if(typeof updateId==`number`)return`update:${updateId}`;let callbackId=ctx.callbackQuery?.id;if(callbackId)return`callback:${callbackId}`;let msg=ctx.message??ctx.channelPost??ctx.editedChannelPost??ctx.update?.message??ctx.update?.edited_message??ctx.update?.channel_post??ctx.update?.edited_channel_post??ctx.callbackQuery?.message,chatId=msg?.chat?.id,messageId=msg?.message_id;if(chatId!==void 0&&typeof messageId==`number`)return`message:${chatId}:${messageId}`},createTelegramUpdateDedupe=()=>createDedupeCache({ttlMs:3e5,maxSize:2e3}),PARSE_ERR_RE=/can't parse entities|parse entities|find end of the entity/i,VOICE_FORBIDDEN_RE=/VOICE_MESSAGES_FORBIDDEN/,FILE_TOO_BIG_RE=/file is too big/i;async function deliverReplies(params){let{replies,chatId,runtime,bot,replyToMode,textLimit,thread,linkPreview,replyQuoteText}=params,chunkMode=params.chunkMode??`length`,hasReplied=!1,hasDelivered=!1,markDelivered=()=>{hasDelivered=!0},chunkText=markdown=>{let markdownChunks=chunkMode===`newline`?chunkMarkdownTextWithMode(markdown,textLimit,chunkMode):[markdown],chunks=[];for(let chunk of markdownChunks){let nested=markdownToTelegramChunks(chunk,textLimit,{tableMode:params.tableMode});if(!nested.length&&chunk){chunks.push({html:wrapFileReferencesInHtml(markdownToTelegramHtml(chunk,{tableMode:params.tableMode,wrapFileRefs:!1})),text:chunk});continue}chunks.push(...nested)}return chunks};for(let reply of replies){let hasMedia=!!reply?.mediaUrl||(reply?.mediaUrls?.length??0)>0;if(!reply?.text&&!hasMedia){if(reply?.audioAsVoice){logVerbose(`telegram reply has audioAsVoice without media/text; skipping`);continue}runtime.error?.(danger(`reply missing text/media`));continue}let replyToId=replyToMode===`off`?void 0:resolveTelegramReplyId(reply.replyToId),replyToMessageIdForPayload=replyToId&&(replyToMode===`all`||!hasReplied)?replyToId:void 0,mediaList=reply.mediaUrls?.length?reply.mediaUrls:reply.mediaUrl?[reply.mediaUrl]:[],telegramData=reply.channelData?.telegram,replyMarkup=buildInlineKeyboard(telegramData?.buttons);if(mediaList.length===0){let chunks=chunkText(reply.text||``),sentTextChunk=!1;for(let i=0;i<chunks.length;i+=1){let chunk=chunks[i];if(!chunk)continue;let shouldAttachButtons=i===0&&replyMarkup;await sendTelegramText(bot,chatId,chunk.html,runtime,{replyToMessageId:replyToMessageIdForPayload,replyQuoteText,thread,textMode:`html`,plainText:chunk.text,linkPreview,replyMarkup:shouldAttachButtons?replyMarkup:void 0}),sentTextChunk=!0,markDelivered()}replyToMessageIdForPayload&&!hasReplied&&sentTextChunk&&(hasReplied=!0);continue}let first=!0,pendingFollowUpText;for(let mediaUrl of mediaList){let isFirstMedia=first,media=await loadWebMedia(mediaUrl,{localRoots:params.mediaLocalRoots}),kind=mediaKindFromMime(media.contentType??void 0),isGif=isGifMedia({contentType:media.contentType,fileName:media.fileName}),fileName=media.fileName??(isGif?`animation.gif`:`file`),file=new InputFile(media.buffer,fileName),{caption,followUpText}=splitTelegramCaption(isFirstMedia?reply.text??void 0:void 0),htmlCaption=caption?renderTelegramHtmlText(caption,{tableMode:params.tableMode}):void 0;followUpText&&(pendingFollowUpText=followUpText),first=!1;let replyToMessageId=replyToMessageIdForPayload,shouldAttachButtonsToMedia=isFirstMedia&&replyMarkup&&!followUpText,mediaParams={caption:htmlCaption,...htmlCaption?{parse_mode:`HTML`}:{},...shouldAttachButtonsToMedia?{reply_markup:replyMarkup}:{},...buildTelegramSendParams({replyToMessageId,thread})};if(isGif)await withTelegramApiErrorLogging({operation:`sendAnimation`,runtime,fn:()=>bot.api.sendAnimation(chatId,file,{...mediaParams})}),markDelivered();else if(kind===`image`)await withTelegramApiErrorLogging({operation:`sendPhoto`,runtime,fn:()=>bot.api.sendPhoto(chatId,file,{...mediaParams})}),markDelivered();else if(kind===`video`)await withTelegramApiErrorLogging({operation:`sendVideo`,runtime,fn:()=>bot.api.sendVideo(chatId,file,{...mediaParams})}),markDelivered();else if(kind===`audio`){let{useVoice}=resolveTelegramVoiceSend({wantsVoice:reply.audioAsVoice===!0,contentType:media.contentType,fileName,logFallback:logVerbose});if(useVoice){await params.onVoiceRecording?.();try{await withTelegramApiErrorLogging({operation:`sendVoice`,runtime,shouldLog:err=>!isVoiceMessagesForbidden(err),fn:()=>bot.api.sendVoice(chatId,file,{...mediaParams})}),markDelivered()}catch(voiceErr){if(isVoiceMessagesForbidden(voiceErr)){let fallbackText=reply.text;if(!fallbackText||!fallbackText.trim())throw voiceErr;logVerbose(`telegram sendVoice forbidden (recipient has voice messages blocked in privacy settings); falling back to text`),await sendTelegramVoiceFallbackText({bot,chatId,runtime,text:fallbackText,chunkText,replyToId:replyToMessageIdForPayload,thread,linkPreview,replyMarkup,replyQuoteText}),replyToMessageIdForPayload&&!hasReplied&&(hasReplied=!0),markDelivered();continue}throw voiceErr}}else await withTelegramApiErrorLogging({operation:`sendAudio`,runtime,fn:()=>bot.api.sendAudio(chatId,file,{...mediaParams})}),markDelivered()}else await withTelegramApiErrorLogging({operation:`sendDocument`,runtime,fn:()=>bot.api.sendDocument(chatId,file,{...mediaParams})}),markDelivered();if(replyToId&&!hasReplied&&(hasReplied=!0),pendingFollowUpText&&isFirstMedia){let chunks=chunkText(pendingFollowUpText);for(let i=0;i<chunks.length;i+=1){let chunk=chunks[i];await sendTelegramText(bot,chatId,chunk.html,runtime,{replyToMessageId:replyToMessageIdForPayload,thread,textMode:`html`,plainText:chunk.text,linkPreview,replyMarkup:i===0?replyMarkup:void 0}),markDelivered()}pendingFollowUpText=void 0}replyToMessageIdForPayload&&!hasReplied&&(hasReplied=!0)}}return{delivered:hasDelivered}}async function resolveMedia(ctx,maxBytes,token,proxyFetch){let msg=ctx.message,downloadAndSaveTelegramFile=async(filePath,fetchImpl)=>{let fetched=await fetchRemoteMedia({url:`https://api.telegram.org/file/bot${token}/${filePath}`,fetchImpl,filePathHint:filePath}),originalName=fetched.fileName??filePath;return saveMediaBuffer(fetched.buffer,fetched.contentType,`inbound`,maxBytes,originalName)};if(msg.sticker){let sticker=msg.sticker;if(sticker.is_animated||sticker.is_video)return logVerbose(`telegram: skipping animated/video sticker (only static stickers supported)`),null;if(!sticker.file_id)return null;try{let file=await ctx.getFile();if(!file.file_path)return logVerbose(`telegram: getFile returned no file_path for sticker`),null;let fetchImpl=proxyFetch??globalThis.fetch;if(!fetchImpl)return logVerbose(`telegram: fetch not available for sticker download`),null;let saved=await downloadAndSaveTelegramFile(file.file_path,fetchImpl),cached=sticker.file_unique_id?await getCachedSticker(sticker.file_unique_id):null;if(cached){logVerbose(`telegram: sticker cache hit for ${sticker.file_unique_id}`);let fileId=sticker.file_id??cached.fileId,emoji=sticker.emoji??cached.emoji,setName=sticker.set_name??cached.setName;return(fileId!==cached.fileId||emoji!==cached.emoji||setName!==cached.setName)&&cacheSticker({...cached,fileId,emoji,setName}),{path:saved.path,contentType:saved.contentType,placeholder:`<media:sticker>`,stickerMetadata:{emoji,setName,fileId,fileUniqueId:sticker.file_unique_id,cachedDescription:cached.description}}}return{path:saved.path,contentType:saved.contentType,placeholder:`<media:sticker>`,stickerMetadata:{emoji:sticker.emoji??void 0,setName:sticker.set_name??void 0,fileId:sticker.file_id,fileUniqueId:sticker.file_unique_id}}}catch(err){return logVerbose(`telegram: failed to process sticker: ${String(err)}`),null}}if(!(msg.photo?.[msg.photo.length-1]??msg.video??msg.video_note??msg.document??msg.audio??msg.voice)?.file_id)return null;let file;try{file=await retryAsync(()=>ctx.getFile(),{attempts:3,minDelayMs:1e3,maxDelayMs:4e3,jitter:.2,label:`telegram:getFile`,shouldRetry:isRetryableGetFileError,onRetry:({attempt,maxAttempts})=>logVerbose(`telegram: getFile retry ${attempt}/${maxAttempts}`)})}catch(err){return isFileTooBigError(err)?(logVerbose(warn(`telegram: getFile failed - file exceeds Telegram Bot API 20MB limit; skipping attachment`)),null):(logVerbose(`telegram: getFile failed after retries: ${String(err)}`),null)}if(!file.file_path)throw Error(`Telegram getFile returned no file_path`);let fetchImpl=proxyFetch??globalThis.fetch;if(!fetchImpl)throw Error(`fetch is not available; set channels.telegram.proxy in config`);let saved=await downloadAndSaveTelegramFile(file.file_path,fetchImpl),placeholder=resolveTelegramMediaPlaceholder(msg)??`<media:document>`;return{path:saved.path,contentType:saved.contentType,placeholder}}function isVoiceMessagesForbidden(err){return err instanceof GrammyError?VOICE_FORBIDDEN_RE.test(err.description):VOICE_FORBIDDEN_RE.test(formatErrorMessage(err))}function isFileTooBigError(err){return err instanceof GrammyError?FILE_TOO_BIG_RE.test(err.description):FILE_TOO_BIG_RE.test(formatErrorMessage(err))}function isRetryableGetFileError(err){return!isFileTooBigError(err)}async function sendTelegramVoiceFallbackText(opts){let chunks=opts.chunkText(opts.text);for(let i=0;i<chunks.length;i+=1){let chunk=chunks[i];await sendTelegramText(opts.bot,opts.chatId,chunk.html,opts.runtime,{replyToMessageId:opts.replyToId,replyQuoteText:opts.replyQuoteText,thread:opts.thread,textMode:`html`,plainText:chunk.text,linkPreview:opts.linkPreview,replyMarkup:i===0?opts.replyMarkup:void 0})}}function buildTelegramSendParams(opts){let threadParams=buildTelegramThreadParams(opts?.thread),params={};return opts?.replyToMessageId&&(params.reply_to_message_id=opts.replyToMessageId),threadParams&&(params.message_thread_id=threadParams.message_thread_id),params}async function sendTelegramText(bot,chatId,text,runtime,opts){let baseParams=buildTelegramSendParams({replyToMessageId:opts?.replyToMessageId,thread:opts?.thread}),linkPreviewOptions=opts?.linkPreview??!0?void 0:{is_disabled:!0},htmlText=(opts?.textMode??`markdown`)===`html`?text:markdownToTelegramHtml(text);try{return(await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,shouldLog:err=>!PARSE_ERR_RE.test(formatErrorMessage(err)),fn:()=>bot.api.sendMessage(chatId,htmlText,{parse_mode:`HTML`,...linkPreviewOptions?{link_preview_options:linkPreviewOptions}:{},...opts?.replyMarkup?{reply_markup:opts.replyMarkup}:{},...baseParams})})).message_id}catch(err){let errText=formatErrorMessage(err);if(PARSE_ERR_RE.test(errText)){runtime.log?.(`telegram HTML parse failed; retrying without formatting: ${errText}`);let fallbackText=opts?.plainText??text;return(await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,fn:()=>bot.api.sendMessage(chatId,fallbackText,{...linkPreviewOptions?{link_preview_options:linkPreviewOptions}:{},...opts?.replyMarkup?{reply_markup:opts.replyMarkup}:{},...baseParams})})).message_id}throw err}}const evaluateTelegramGroupBaseAccess=params=>{if(!params.isGroup)return{allowed:!0};if(params.groupConfig?.enabled===!1)return{allowed:!1,reason:`group-disabled`};if(params.topicConfig?.enabled===!1)return{allowed:!1,reason:`topic-disabled`};if(!params.enforceAllowOverride||!params.hasGroupAllowOverride)return{allowed:!0};let senderId=params.senderId??``;return params.requireSenderForAllowOverride&&!senderId||!isSenderAllowed$1({allow:params.effectiveGroupAllow,senderId,senderUsername:params.senderUsername??``})?{allowed:!1,reason:`group-override-unauthorized`}:{allowed:!0}},evaluateTelegramGroupPolicyAccess=params=>{let fallbackPolicy=firstDefined$2(params.telegramCfg.groupPolicy,params.cfg.channels?.defaults?.groupPolicy,`open`)??`open`,groupPolicy=params.useTopicAndGroupOverrides?firstDefined$2(params.topicConfig?.groupPolicy,params.groupConfig?.groupPolicy,params.telegramCfg.groupPolicy,params.cfg.channels?.defaults?.groupPolicy,`open`)??`open`:fallbackPolicy;if(!params.isGroup||!params.enforcePolicy)return{allowed:!0,groupPolicy};if(groupPolicy===`disabled`)return{allowed:!1,reason:`group-policy-disabled`,groupPolicy};if(groupPolicy===`allowlist`&&params.enforceAllowlistAuthorization){let senderId=params.senderId??``;if(params.requireSenderForAllowlistAuthorization&&!senderId)return{allowed:!1,reason:`group-policy-allowlist-no-sender`,groupPolicy};if(!params.allowEmptyAllowlistEntries&&!params.effectiveGroupAllow.hasEntries)return{allowed:!1,reason:`group-policy-allowlist-empty`,groupPolicy};let senderUsername=params.senderUsername??``;if(!isSenderAllowed$1({allow:params.effectiveGroupAllow,senderId,senderUsername}))return{allowed:!1,reason:`group-policy-allowlist-unauthorized`,groupPolicy}}if(params.checkChatAllowlist){let groupAllowlist=params.resolveGroupPolicy(params.chatId);if(groupAllowlist.allowlistEnabled&&!groupAllowlist.allowed)return{allowed:!1,reason:`group-chat-not-allowed`,groupPolicy}}return{allowed:!0,groupPolicy}};function resolveAccountGroups(cfg,accountId){if(!accountId)return{};let normalized=normalizeAccountId$2(accountId),accounts=cfg.channels?.telegram?.accounts;if(!accounts||typeof accounts!=`object`)return{};let exact=accounts[normalized];if(exact?.groups)return{groups:exact.groups};let matchKey=Object.keys(accounts).find(key=>key.toLowerCase()===normalized.toLowerCase());return{groups:matchKey?accounts[matchKey]?.groups:void 0}}function migrateTelegramGroupsInPlace(groups,oldChatId,newChatId){return!groups||oldChatId===newChatId||!Object.hasOwn(groups,oldChatId)?{migrated:!1,skippedExisting:!1}:Object.hasOwn(groups,newChatId)?{migrated:!1,skippedExisting:!0}:(groups[newChatId]=groups[oldChatId],delete groups[oldChatId],{migrated:!0,skippedExisting:!1})}function migrateTelegramGroupConfig(params){let scopes=[],migrated=!1,skippedExisting=!1,migrationTargets=[{scope:`account`,groups:resolveAccountGroups(params.cfg,params.accountId).groups},{scope:`global`,groups:params.cfg.channels?.telegram?.groups}];for(let target of migrationTargets){let result=migrateTelegramGroupsInPlace(target.groups,params.oldChatId,params.newChatId);result.migrated&&(migrated=!0,scopes.push(target.scope)),result.skippedExisting&&(skippedExisting=!0)}return{migrated,skippedExisting,scopes}}const registerTelegramHandlers=({cfg,accountId,bot,opts,runtime,mediaMaxBytes,telegramCfg,groupAllowFrom,resolveGroupPolicy,resolveTelegramGroupConfig,shouldSkipUpdate,processMessage,logger})=>{let TELEGRAM_TEXT_FRAGMENT_MAX_GAP_MS=typeof opts.testTimings?.textFragmentGapMs==`number`&&Number.isFinite(opts.testTimings.textFragmentGapMs)?Math.max(10,Math.floor(opts.testTimings.textFragmentGapMs)):1500,mediaGroupTimeoutMs=typeof opts.testTimings?.mediaGroupFlushMs==`number`&&Number.isFinite(opts.testTimings.mediaGroupFlushMs)?Math.max(10,Math.floor(opts.testTimings.mediaGroupFlushMs)):500,mediaGroupBuffer=new Map,mediaGroupProcessing=Promise.resolve(),textFragmentBuffer=new Map,textFragmentProcessing=Promise.resolve(),debounceMs=resolveInboundDebounceMs({cfg,channel:`telegram`}),buildSyntheticTextMessage=params=>({...params.base,...params.from?{from:params.from}:{},text:params.text,caption:void 0,caption_entities:void 0,entities:void 0,...params.date==null?{}:{date:params.date}}),buildSyntheticContext=(ctx,message)=>{let getFile=typeof ctx.getFile==`function`?ctx.getFile.bind(ctx):async()=>({});return{message,me:ctx.me,getFile}},inboundDebouncer=createInboundDebouncer({debounceMs,buildKey:entry=>entry.debounceKey,shouldDebounce:entry=>{if(entry.allMedia.length>0)return!1;let text=entry.msg.text??entry.msg.caption??``;return text.trim()?!hasControlCommand(text,cfg,{botUsername:entry.botUsername}):!1},onFlush:async entries=>{let last=entries.at(-1);if(!last)return;if(entries.length===1){await processMessage(last.ctx,last.allMedia,last.storeAllowFrom);return}let combinedText=entries.map(entry=>entry.msg.text??entry.msg.caption??``).filter(Boolean).join(`
473
+ `),combinedMentioned=entries.some(entry=>!!entry.opts.wasMentioned),prepared=await prepareSlackMessage({ctx,account,message:{...last.message,text:combinedText},opts:{...last.opts,wasMentioned:combinedMentioned||last.opts.wasMentioned}});if(prepared){if(entries.length>1){let ids=entries.map(entry=>entry.message.ts).filter(Boolean);ids.length>0&&(prepared.ctxPayload.MessageSids=ids,prepared.ctxPayload.MessageSidFirst=ids[0],prepared.ctxPayload.MessageSidLast=ids[ids.length-1])}await dispatchPreparedSlackMessage(prepared)}},onError:err=>{ctx.runtime.error?.(`slack inbound debounce flush failed: ${String(err)}`)}});return async(message,opts)=>{if(opts.source===`message`&&message.type!==`message`||opts.source===`message`&&message.subtype&&message.subtype!==`file_share`&&message.subtype!==`bot_message`||ctx.markMessageSeen(message.channel,message.ts))return;let resolvedMessage=await threadTsResolver.resolve({message,source:opts.source});await debouncer.enqueue({message:resolvedMessage,opts})}}const SLACK_COMMAND_ARG_ACTION_ID=`builderforce_cmdarg`,SLACK_COMMAND_ARG_VALUE_PREFIX=`cmdarg`,SLACK_COMMAND_ARG_EXTERNAL_PREFIX=`builderforce_cmdarg_ext:`,slackExternalArgMenuStore=new Map;function truncatePlainText(value,max){let trimmed=value.trim();return trimmed.length<=max?trimmed:max<=1?trimmed.slice(0,max):`${trimmed.slice(0,max-1)}…`}function escapeSlackMrkdwn(value){return value.replaceAll(`\\`,`\\\\`).replaceAll(`&`,`&amp;`).replaceAll(`<`,`&lt;`).replaceAll(`>`,`&gt;`).replace(/([*_`~])/g,`\\$1`)}function buildSlackArgMenuConfirm(params){return{title:{type:`plain_text`,text:`Confirm selection`},text:{type:`mrkdwn`,text:`Run */${escapeSlackMrkdwn(params.command)}* with *${escapeSlackMrkdwn(params.arg)}* set to this value?`},confirm:{type:`plain_text`,text:`Run command`},deny:{type:`plain_text`,text:`Cancel`}}}function pruneSlackExternalArgMenuStore(now=Date.now()){for(let[token,entry]of slackExternalArgMenuStore.entries())entry.expiresAt<=now&&slackExternalArgMenuStore.delete(token)}function storeSlackExternalArgMenu(params){pruneSlackExternalArgMenuStore();let token=`${Date.now().toString(36)}${Math.random().toString(36).slice(2,10)}`;return slackExternalArgMenuStore.set(token,{choices:params.choices,userId:params.userId,expiresAt:Date.now()+6e5}),token}function readSlackExternalArgMenuToken(raw){if(typeof raw!=`string`||!raw.startsWith(SLACK_COMMAND_ARG_EXTERNAL_PREFIX))return;let token=raw.slice(24).trim();return token.length>0?token:void 0}function encodeSlackCommandArgValue(parts){return[SLACK_COMMAND_ARG_VALUE_PREFIX,encodeURIComponent(parts.command),encodeURIComponent(parts.arg),encodeURIComponent(parts.value),encodeURIComponent(parts.userId)].join(`|`)}function parseSlackCommandArgValue(raw){if(!raw)return null;let parts=raw.split(`|`);if(parts.length!==5||parts[0]!==SLACK_COMMAND_ARG_VALUE_PREFIX)return null;let[,command,arg,value,userId]=parts;if(!command||!arg||!value||!userId)return null;let decode=text=>{try{return decodeURIComponent(text)}catch{return null}},decodedCommand=decode(command),decodedArg=decode(arg),decodedValue=decode(value),decodedUserId=decode(userId);return!decodedCommand||!decodedArg||!decodedValue||!decodedUserId?null:{command:decodedCommand,arg:decodedArg,value:decodedValue,userId:decodedUserId}}function buildSlackCommandArgMenuBlocks(params){let encodedChoices=params.choices.map(choice=>({label:choice.label,value:encodeSlackCommandArgValue({command:params.command,arg:params.arg,value:choice.value,userId:params.userId})})),canUseStaticSelect=encodedChoices.every(choice=>choice.value.length<=75),canUseOverflow=canUseStaticSelect&&encodedChoices.length>=3&&encodedChoices.length<=5,canUseExternalSelect=params.supportsExternalSelect&&canUseStaticSelect&&encodedChoices.length>100,rows=canUseOverflow?[{type:`actions`,elements:[{type:`overflow`,action_id:SLACK_COMMAND_ARG_ACTION_ID,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg}),options:encodedChoices.map(choice=>({text:{type:`plain_text`,text:choice.label.slice(0,75)},value:choice.value}))}]}]:canUseExternalSelect?[{type:`actions`,block_id:`${SLACK_COMMAND_ARG_EXTERNAL_PREFIX}${params.createExternalMenuToken(encodedChoices)}`,elements:[{type:`external_select`,action_id:SLACK_COMMAND_ARG_ACTION_ID,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg}),min_query_length:0,placeholder:{type:`plain_text`,text:`Search ${params.arg}`}}]}]:encodedChoices.length<=5||!canUseStaticSelect?chunkItems(encodedChoices,5).map(choices=>({type:`actions`,elements:choices.map(choice=>({type:`button`,action_id:SLACK_COMMAND_ARG_ACTION_ID,text:{type:`plain_text`,text:choice.label},value:choice.value,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg})}))})):chunkItems(encodedChoices,100).map((choices,index)=>({type:`actions`,elements:[{type:`static_select`,action_id:SLACK_COMMAND_ARG_ACTION_ID,confirm:buildSlackArgMenuConfirm({command:params.command,arg:params.arg}),placeholder:{type:`plain_text`,text:index===0?`Choose ${params.arg}`:`Choose ${params.arg} (${index+1})`},options:choices.map(choice=>({text:{type:`plain_text`,text:choice.label.slice(0,75)},value:choice.value}))}]})),headerText=truncatePlainText(`/${params.command}: choose ${params.arg}`,150),sectionText=truncatePlainText(params.title,3e3),contextText=truncatePlainText(`Select one option to continue /${params.command} (${params.arg})`,3e3);return[{type:`header`,text:{type:`plain_text`,text:headerText}},{type:`section`,text:{type:`mrkdwn`,text:sectionText}},{type:`context`,elements:[{type:`mrkdwn`,text:contextText}]},...rows]}async function registerSlackMonitorSlashCommands(params){let{ctx,account}=params,cfg=ctx.cfg,runtime=ctx.runtime,supportsInteractiveArgMenus=typeof ctx.app.action==`function`,supportsExternalArgMenus=typeof ctx.app.options==`function`,slashCommand=resolveSlackSlashCommandConfig(ctx.slashCommand??account.config.slashCommand),handleSlashCommand=async p=>{let{command,ack,respond,prompt,commandArgs,commandDefinition}=p;try{if(!prompt.trim()){await ack({text:`Message required.`,response_type:`ephemeral`});return}if(await ack(),ctx.botUserId&&command.user_id===ctx.botUserId)return;let channelInfo=await ctx.resolveChannelName(command.channel_id),channelType=normalizeSlackChannelType(channelInfo?.type??(command.channel_name===`directmessage`?`im`:void 0),command.channel_id),isDirectMessage=channelType===`im`,isGroupDm=channelType===`mpim`,isRoom=channelType===`channel`||channelType===`group`,isRoomish=isRoom||isGroupDm;if(!ctx.isChannelAllowed({channelId:command.channel_id,channelName:channelInfo?.name,channelType})){await respond({text:`This channel is not allowed.`,response_type:`ephemeral`});return}let storeAllowFrom=await readChannelAllowFromStore(`slack`).catch(()=>[]),effectiveAllowFromLower=normalizeAllowListLower(normalizeAllowList$2([...ctx.allowFrom,...storeAllowFrom])),commandAuthorized=!1,channelConfig=null;if(isDirectMessage){if(!ctx.dmEnabled||ctx.dmPolicy===`disabled`){await respond({text:`Slack DMs are disabled.`,response_type:`ephemeral`});return}if(ctx.dmPolicy!==`open`){let senderName=(await ctx.resolveUserName(command.user_id))?.name??void 0,allowMatch=resolveSlackAllowListMatch({allowList:effectiveAllowFromLower,id:command.user_id,name:senderName}),allowMatchMeta=formatAllowlistMatchMeta(allowMatch);if(!allowMatch.allowed){if(ctx.dmPolicy===`pairing`){let{code,created}=await upsertChannelPairingRequest({channel:`slack`,id:command.user_id,meta:{name:senderName}});created&&(logVerbose(`slack pairing request sender=${command.user_id} name=${senderName??`unknown`} (${allowMatchMeta})`),await respond({text:buildPairingReply({channel:`slack`,idLine:`Your Slack user id: ${command.user_id}`,code}),response_type:`ephemeral`}))}else logVerbose(`slack: blocked slash sender ${command.user_id} (dmPolicy=${ctx.dmPolicy}, ${allowMatchMeta})`),await respond({text:`You are not authorized to use this command.`,response_type:`ephemeral`});return}}}if(isRoom&&(channelConfig=resolveSlackChannelConfig({channelId:command.channel_id,channelName:channelInfo?.name,channels:ctx.channelsConfig,defaultRequireMention:ctx.defaultRequireMention}),ctx.useAccessGroups)){let channelAllowlistConfigured=!!ctx.channelsConfig&&Object.keys(ctx.channelsConfig??{}).length>0,channelAllowed=channelConfig?.allowed!==!1;if(!isSlackChannelAllowedByPolicy({groupPolicy:ctx.groupPolicy,channelAllowlistConfigured,channelAllowed})){await respond({text:`This channel is not allowed.`,response_type:`ephemeral`});return}let hasExplicitConfig=!!channelConfig?.matchSource;if(!channelAllowed&&(ctx.groupPolicy!==`open`||hasExplicitConfig)){await respond({text:`This channel is not allowed.`,response_type:`ephemeral`});return}}let senderName=(await ctx.resolveUserName(command.user_id))?.name??command.user_name??command.user_id,channelUsersAllowlistConfigured=isRoom&&Array.isArray(channelConfig?.users)&&channelConfig.users.length>0,channelUserAllowed=channelUsersAllowlistConfigured?resolveSlackUserAllowed({allowList:channelConfig?.users,userId:command.user_id,userName:senderName}):!1;if(channelUsersAllowlistConfigured&&!channelUserAllowed){await respond({text:`You are not authorized to use this command here.`,response_type:`ephemeral`});return}let ownerAllowed=resolveSlackAllowListMatch({allowList:effectiveAllowFromLower,id:command.user_id,name:senderName}).allowed;if(commandAuthorized=resolveCommandAuthorizedFromAuthorizers({useAccessGroups:ctx.useAccessGroups,authorizers:[{configured:effectiveAllowFromLower.length>0,allowed:ownerAllowed}],modeWhenAccessGroupsOff:`configured`}),isRoomish&&(commandAuthorized=resolveCommandAuthorizedFromAuthorizers({useAccessGroups:ctx.useAccessGroups,authorizers:[{configured:effectiveAllowFromLower.length>0,allowed:ownerAllowed},{configured:channelUsersAllowlistConfigured,allowed:channelUserAllowed}],modeWhenAccessGroupsOff:`configured`}),ctx.useAccessGroups&&!commandAuthorized)){await respond({text:`You are not authorized to use this command.`,response_type:`ephemeral`});return}if(commandDefinition&&supportsInteractiveArgMenus){let menu=resolveCommandArgMenu({command:commandDefinition,args:commandArgs,cfg});if(menu){let commandLabel=commandDefinition.nativeName??commandDefinition.key,title=menu.title??`Choose ${menu.arg.description||menu.arg.name} for /${commandLabel}.`;await respond({text:title,blocks:buildSlackCommandArgMenuBlocks({title,command:commandLabel,arg:menu.arg.name,choices:menu.choices,userId:command.user_id,supportsExternalSelect:supportsExternalArgMenus,createExternalMenuToken:choices=>storeSlackExternalArgMenu({choices,userId:command.user_id})}),response_type:`ephemeral`});return}}let channelName=channelInfo?.name,roomLabel=channelName?`#${channelName}`:`#${command.channel_id}`,[{resolveAgentRoute},{finalizeInboundContext},{dispatchReplyWithDispatcher}]=await Promise.all([import(`./resolve-route-Bm9nidh9.js`),import(`./inbound-context-CNt0Mycm.js`),import(`./provider-dispatcher-DgOeVjcL.js`)]),[{resolveConversationLabel},{createReplyPrefixOptions}]=await Promise.all([import(`./conversation-label-DIsKX76t.js`),import(`./reply-prefix-BqxxNtel.js`)]),route=resolveAgentRoute({cfg,channel:`slack`,accountId:account.accountId,teamId:ctx.teamId||void 0,peer:{kind:isDirectMessage?`direct`:isRoom?`channel`:`group`,id:isDirectMessage?command.user_id:command.channel_id}}),{untrustedChannelMetadata,groupSystemPrompt}=resolveSlackRoomContextHints({isRoomish,channelInfo,channelConfig}),ctxPayload=finalizeInboundContext({Body:prompt,BodyForAgent:prompt,RawBody:prompt,CommandBody:prompt,CommandArgs:commandArgs,From:isDirectMessage?`slack:${command.user_id}`:isRoom?`slack:channel:${command.channel_id}`:`slack:group:${command.channel_id}`,To:`slash:${command.user_id}`,ChatType:isDirectMessage?`direct`:`channel`,ConversationLabel:resolveConversationLabel({ChatType:isDirectMessage?`direct`:`channel`,SenderName:senderName,GroupSubject:isRoomish?roomLabel:void 0,From:isDirectMessage?`slack:${command.user_id}`:isRoom?`slack:channel:${command.channel_id}`:`slack:group:${command.channel_id}`})??(isDirectMessage?senderName:roomLabel),GroupSubject:isRoomish?roomLabel:void 0,GroupSystemPrompt:isRoomish?groupSystemPrompt:void 0,UntrustedContext:untrustedChannelMetadata?[untrustedChannelMetadata]:void 0,SenderName:senderName,SenderId:command.user_id,Provider:`slack`,Surface:`slack`,WasMentioned:!0,MessageSid:command.trigger_id,Timestamp:Date.now(),SessionKey:`agent:${route.agentId}:${slashCommand.sessionPrefix}:${command.user_id}`.toLowerCase(),CommandTargetSessionKey:route.sessionKey,AccountId:route.accountId,CommandSource:`native`,CommandAuthorized:commandAuthorized,OriginatingChannel:`slack`,OriginatingTo:`user:${command.user_id}`}),{onModelSelected,...prefixOptions}=createReplyPrefixOptions({cfg,agentId:route.agentId,channel:`slack`,accountId:route.accountId}),deliverSlashPayloads=async replies=>{let[{deliverSlackSlashReplies},{resolveChunkMode},{resolveMarkdownTableMode}]=await Promise.all([import(`./replies-CUv671JF.js`),import(`./chunk-BWr2jvx4.js`),import(`./markdown-tables-B2n2SW0j.js`)]);await deliverSlackSlashReplies({replies,respond,ephemeral:slashCommand.ephemeral,textLimit:ctx.textLimit,chunkMode:resolveChunkMode(cfg,`slack`,route.accountId),tableMode:resolveMarkdownTableMode({cfg,channel:`slack`,accountId:route.accountId})})},{counts}=await dispatchReplyWithDispatcher({ctx:ctxPayload,cfg,dispatcherOptions:{...prefixOptions,deliver:async payload=>deliverSlashPayloads([payload]),onError:(err,info)=>{runtime.error?.(danger(`slack slash ${info.kind} reply failed: ${String(err)}`))}},replyOptions:{skillFilter:channelConfig?.skills,onModelSelected}});counts.final+counts.tool+counts.block===0&&await deliverSlashPayloads([])}catch(err){runtime.error?.(danger(`slack slash handler failed: ${String(err)}`)),await respond({text:`Sorry, something went wrong handling that command.`,response_type:`ephemeral`})}},nativeEnabled=resolveNativeCommandsEnabled({providerId:`slack`,providerSetting:account.config.commands?.native,globalSetting:cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`slack`,providerSetting:account.config.commands?.nativeSkills,globalSetting:cfg.commands?.nativeSkills}),nativeCommands=[];if(nativeEnabled&&(nativeCommands=listNativeCommandSpecsForConfig(cfg,{skillCommands:nativeSkillsEnabled?listSkillCommandsForAgents({cfg}):[],provider:`slack`})),nativeCommands.length>0)for(let command of nativeCommands)ctx.app.command(`/${command.name}`,async({command:cmd,ack,respond})=>{let commandDefinition=findCommandByNativeName(command.name,`slack`),rawText=cmd.text?.trim()??``,commandArgs=commandDefinition?parseCommandArgs(commandDefinition,rawText):rawText?{raw:rawText}:void 0;await handleSlashCommand({command:cmd,ack,respond,prompt:commandDefinition?buildCommandTextFromArgs(commandDefinition,commandArgs):rawText?`/${command.name} ${rawText}`:`/${command.name}`,commandArgs,commandDefinition:commandDefinition??void 0})});else slashCommand.enabled?ctx.app.command(buildSlackSlashCommandMatcher(slashCommand.name),async({command,ack,respond})=>{await handleSlashCommand({command,ack,respond,prompt:command.text?.trim()??``})}):logVerbose(`slack: slash commands disabled`);nativeCommands.length===0||!supportsInteractiveArgMenus||((()=>{let optionsHandler=ctx.app.options;typeof optionsHandler==`function`&&optionsHandler(SLACK_COMMAND_ARG_ACTION_ID,async({ack,body})=>{let typedBody=body;pruneSlackExternalArgMenuStore();let token=readSlackExternalArgMenuToken(typedBody.actions?.[0]?.block_id??typedBody.block_id);if(!token){await ack({options:[]});return}let entry=slackExternalArgMenuStore.get(token);if(!entry){await ack({options:[]});return}if(typedBody.user?.id&&typedBody.user.id!==entry.userId){await ack({options:[]});return}let query=typedBody.value?.trim().toLowerCase()??``;await ack({options:entry.choices.filter(choice=>!query||choice.label.toLowerCase().includes(query)).slice(0,100).map(choice=>({text:{type:`plain_text`,text:choice.label.slice(0,75)},value:choice.value}))})})})(),(actionId=>{ctx.app.action(actionId,async args=>{let{ack,body,respond}=args,action=args.action;await ack();let respondFn=respond??(async payload=>{!body.channel?.id||!body.user?.id||await ctx.app.client.chat.postEphemeral({token:ctx.botToken,channel:body.channel.id,user:body.user.id,text:payload.text,blocks:payload.blocks})}),parsed=parseSlackCommandArgValue(action?.value??action?.selected_option?.value);if(!parsed){await respondFn({text:`Sorry, that button is no longer valid.`,response_type:`ephemeral`});return}if(body.user?.id&&parsed.userId!==body.user.id){await respondFn({text:`That menu is for another user.`,response_type:`ephemeral`});return}let commandDefinition=findCommandByNativeName(parsed.command,`slack`),commandArgs={values:{[parsed.arg]:parsed.value}},prompt=commandDefinition?buildCommandTextFromArgs(commandDefinition,commandArgs):`/${parsed.command} ${parsed.value}`,user=body.user,userName=user&&`name`in user&&user.name?user.name:user&&`username`in user&&user.username?user.username:user?.id??``,triggerId=`trigger_id`in body?body.trigger_id:void 0;await handleSlashCommand({command:{user_id:user?.id??``,user_name:userName,channel_id:body.channel?.id??``,channel_name:body.channel?.name??body.channel?.id??``,trigger_id:triggerId??String(Date.now())},ack:async()=>{},respond:respondFn,prompt,commandArgs,commandDefinition:commandDefinition??void 0})})})(SLACK_COMMAND_ARG_ACTION_ID))}const slackBoltModule=SlackBolt,{App,HTTPReceiver}=(slackBoltModule.App?slackBoltModule:slackBoltModule.default)??slackBoltModule;function parseApiAppIdFromAppToken(raw){let token=raw?.trim();if(token)return/^xapp-\d-([a-z0-9]+)-/i.exec(token)?.[1]?.toUpperCase()}async function monitorSlackProvider(opts={}){let cfg=opts.config??loadConfig(),account=resolveSlackAccount({cfg,accountId:opts.accountId}),historyLimit=Math.max(0,account.config.historyLimit??cfg.messages?.groupChat?.historyLimit??50),sessionCfg=cfg.session,sessionScope=sessionCfg?.scope??`per-sender`,mainKey=normalizeMainKey(sessionCfg?.mainKey),slackMode=opts.mode??account.config.mode??`socket`,slackWebhookPath=normalizeSlackWebhookPath(account.config.webhookPath),signingSecret=account.config.signingSecret?.trim(),botToken=resolveSlackBotToken(opts.botToken??account.botToken),appToken=resolveSlackAppToken(opts.appToken??account.appToken);if(!botToken||slackMode!==`http`&&!appToken){let missing=slackMode===`http`?`Slack bot token missing for account "${account.accountId}" (set channels.slack.accounts.${account.accountId}.botToken or SLACK_BOT_TOKEN for default).`:`Slack bot + app tokens missing for account "${account.accountId}" (set channels.slack.accounts.${account.accountId}.botToken/appToken or SLACK_BOT_TOKEN/SLACK_APP_TOKEN for default).`;throw Error(missing)}if(slackMode===`http`&&!signingSecret)throw Error(`Slack signing secret missing for account "${account.accountId}" (set channels.slack.signingSecret or channels.slack.accounts.${account.accountId}.signingSecret).`);let runtime=opts.runtime??createNonExitingRuntime(),slackCfg=account.config,dmConfig=slackCfg.dm,dmEnabled=dmConfig?.enabled??!0,dmPolicy=slackCfg.dmPolicy??dmConfig?.policy??`pairing`,allowFrom=slackCfg.allowFrom??dmConfig?.allowFrom,groupDmEnabled=dmConfig?.groupEnabled??!1,groupDmChannels=dmConfig?.groupChannels,channelsConfig=slackCfg.channels,defaultGroupPolicy=cfg.channels?.defaults?.groupPolicy,groupPolicy=slackCfg.groupPolicy??defaultGroupPolicy??`open`;slackCfg.groupPolicy===void 0&&slackCfg.channels===void 0&&defaultGroupPolicy===void 0&&groupPolicy===`open`&&runtime.log?.(warn(`slack: groupPolicy defaults to "open" when channels.slack is missing; set channels.slack.groupPolicy (or channels.defaults.groupPolicy) or add channels.slack.channels to restrict access.`));let resolveToken=slackCfg.userToken?.trim()||botToken,useAccessGroups=cfg.commands?.useAccessGroups!==!1,reactionMode=slackCfg.reactionNotifications??`own`,reactionAllowlist=slackCfg.reactionAllowlist??[],replyToMode=slackCfg.replyToMode??`all`,threadHistoryScope=slackCfg.thread?.historyScope??`thread`,threadInheritParent=slackCfg.thread?.inheritParent??!1,slashCommand=resolveSlackSlashCommandConfig(opts.slashCommand??slackCfg.slashCommand),textLimit=resolveTextChunkLimit(cfg,`slack`,account.accountId),ackReactionScope=cfg.messages?.ackReactionScope??`group-mentions`,mediaMaxBytes=(opts.mediaMaxMb??slackCfg.mediaMaxMb??20)*1024*1024,removeAckAfterReply=cfg.messages?.removeAckAfterReply??!1,receiver=slackMode===`http`?new HTTPReceiver({signingSecret:signingSecret??``,endpoints:slackWebhookPath}):null,clientOptions=resolveSlackWebClientOptions(),app=new App(slackMode===`socket`?{token:botToken,appToken,socketMode:!0,clientOptions}:{token:botToken,receiver:receiver??void 0,clientOptions}),slackHttpHandler=slackMode===`http`&&receiver?async(req,res)=>{let guard=installRequestBodyLimitGuard(req,res,{maxBytes:1048576,timeoutMs:3e4,responseFormat:`text`});if(!guard.isTripped())try{await Promise.resolve(receiver.requestListener(req,res))}catch(err){if(!guard.isTripped())throw err}finally{guard.dispose()}}:null,unregisterHttpHandler=null,botUserId=``,teamId=``,apiAppId=``,expectedApiAppIdFromAppToken=parseApiAppIdFromAppToken(appToken);try{let auth=await app.client.auth.test({token:botToken});botUserId=auth.user_id??``,teamId=auth.team_id??``,apiAppId=auth.api_app_id??``}catch{}apiAppId&&expectedApiAppIdFromAppToken&&apiAppId!==expectedApiAppIdFromAppToken&&runtime.error?.(`slack token mismatch: bot token api_app_id=${apiAppId} but app token looks like api_app_id=${expectedApiAppIdFromAppToken}`);let ctx=createSlackMonitorContext({cfg,accountId:account.accountId,botToken,app,runtime,botUserId,teamId,apiAppId,historyLimit,sessionScope,mainKey,dmEnabled,dmPolicy,allowFrom,groupDmEnabled,groupDmChannels,defaultRequireMention:slackCfg.requireMention,channelsConfig,groupPolicy,useAccessGroups,reactionMode,reactionAllowlist,replyToMode,threadHistoryScope,threadInheritParent,slashCommand,textLimit,ackReactionScope,mediaMaxBytes,removeAckAfterReply});registerSlackMonitorEvents({ctx,account,handleSlackMessage:createSlackMessageHandler({ctx,account})}),await registerSlackMonitorSlashCommands({ctx,account}),slackMode===`http`&&slackHttpHandler&&(unregisterHttpHandler=registerSlackHttpHandler({path:slackWebhookPath,handler:slackHttpHandler,log:runtime.log,accountId:account.accountId})),resolveToken&&(async()=>{if(opts.abortSignal?.aborted)return;if(channelsConfig&&Object.keys(channelsConfig).length>0)try{let entries=Object.keys(channelsConfig).filter(key=>key!==`*`);if(entries.length>0){let resolved=await resolveSlackChannelAllowlist({token:resolveToken,entries}),nextChannels={...channelsConfig},mapping=[],unresolved=[];for(let entry of resolved){let source=channelsConfig?.[entry.input];if(!source)continue;if(!entry.resolved||!entry.id){unresolved.push(entry.input);continue}mapping.push(`${entry.input}→${entry.id}${entry.archived?` (archived)`:``}`);let existing=nextChannels[entry.id]??{};nextChannels[entry.id]={...source,...existing}}channelsConfig=nextChannels,ctx.channelsConfig=nextChannels,summarizeMapping(`slack channels`,mapping,unresolved,runtime)}}catch(err){runtime.log?.(`slack channel resolve failed; using config entries. ${String(err)}`)}let allowEntries=allowFrom?.filter(entry=>String(entry).trim()&&String(entry).trim()!==`*`)??[];if(allowEntries.length>0)try{let{mapping,unresolved,additions}=buildAllowlistResolutionSummary(await resolveSlackUserAllowlist({token:resolveToken,entries:allowEntries.map(entry=>String(entry))}),{formatResolved:entry=>{let note=entry.note?` (${entry.note})`:``;return`${entry.input}→${entry.id}${note}`}});allowFrom=mergeAllowlist({existing:allowFrom,additions}),ctx.allowFrom=normalizeAllowList$2(allowFrom),summarizeMapping(`slack users`,mapping,unresolved,runtime)}catch(err){runtime.log?.(`slack user resolve failed; using config entries. ${String(err)}`)}if(channelsConfig&&Object.keys(channelsConfig).length>0){let userEntries=new Set;for(let channel of Object.values(channelsConfig))addAllowlistUserEntriesFromConfigEntry(userEntries,channel);if(userEntries.size>0)try{let{resolvedMap,mapping,unresolved}=buildAllowlistResolutionSummary(await resolveSlackUserAllowlist({token:resolveToken,entries:Array.from(userEntries)})),nextChannels=patchAllowlistUsersInConfigEntries({entries:channelsConfig,resolvedMap});channelsConfig=nextChannels,ctx.channelsConfig=nextChannels,summarizeMapping(`slack channel users`,mapping,unresolved,runtime)}catch(err){runtime.log?.(`slack channel user resolve failed; using config entries. ${String(err)}`)}}})();let stopOnAbort=()=>{opts.abortSignal?.aborted&&slackMode===`socket`&&app.stop()};opts.abortSignal?.addEventListener(`abort`,stopOnAbort,{once:!0});try{if(slackMode===`socket`?(await app.start(),runtime.log?.(`slack socket mode connected`)):runtime.log?.(`slack http mode listening at ${slackWebhookPath}`),opts.abortSignal?.aborted)return;await new Promise(resolve=>{opts.abortSignal?.addEventListener(`abort`,()=>resolve(),{once:!0})})}finally{opts.abortSignal?.removeEventListener(`abort`,stopOnAbort),unregisterHttpHandler?.(),await app.stop().catch(()=>void 0)}}async function probeSlack(token,timeoutMs=2500){let client=createSlackWebClient(token),start=Date.now();try{let result=await withTimeout(client.auth.test(),timeoutMs);return result.ok?{ok:!0,status:200,elapsedMs:Date.now()-start,bot:{id:result.user_id??void 0,name:result.user??void 0},team:{id:result.team_id??void 0,name:result.team??void 0}}:{ok:!1,status:200,error:result.error??`unknown`,elapsedMs:Date.now()-start}}catch(err){let message=err instanceof Error?err.message:String(err);return{ok:!1,status:typeof err.status==`number`?err.status:null,error:message,elapsedMs:Date.now()-start}}}function collectTelegramUnmentionedGroupIds(groups){if(!groups||typeof groups!=`object`)return{groupIds:[],unresolvedGroups:0,hasWildcardUnmentionedGroups:!1};let hasWildcardUnmentionedGroups=groups[`*`]?.requireMention===!1&&groups[`*`]?.enabled!==!1,groupIds=[],unresolvedGroups=0;for(let[key,value]of Object.entries(groups)){if(key===`*`||!value||typeof value!=`object`||value.enabled===!1||value.requireMention!==!1)continue;let id=String(key).trim();id&&(/^-?\d+$/.test(id)?groupIds.push(id):unresolvedGroups+=1)}return groupIds.sort((a,b)=>a.localeCompare(b)),{groupIds,unresolvedGroups,hasWildcardUnmentionedGroups}}async function auditTelegramGroupMembership(params){let started=Date.now(),token=params.token?.trim()??``;if(!token||params.groupIds.length===0)return{ok:!0,checkedGroups:0,unresolvedGroups:0,hasWildcardUnmentionedGroups:!1,groups:[],elapsedMs:Date.now()-started};let fetcher=params.proxyUrl?makeProxyFetch(params.proxyUrl):fetch,base=`https://api.telegram.org/bot${token}`,groups=[];for(let chatId of params.groupIds)try{let res=await fetchWithTimeout(`${base}/getChatMember?chat_id=${encodeURIComponent(chatId)}&user_id=${encodeURIComponent(String(params.botId))}`,{},params.timeoutMs,fetcher),json=await res.json();if(!res.ok||!isRecord$1(json)||!json.ok){let desc=isRecord$1(json)&&!json.ok&&typeof json.description==`string`?json.description:`getChatMember failed (${res.status})`;groups.push({chatId,ok:!1,status:null,error:desc,matchKey:chatId,matchSource:`id`});continue}let status=isRecord$1(json.result)?json.result.status??null:null,ok=status===`creator`||status===`administrator`||status===`member`;groups.push({chatId,ok,status,error:ok?null:`bot not in group`,matchKey:chatId,matchSource:`id`})}catch(err){groups.push({chatId,ok:!1,status:null,error:err instanceof Error?err.message:String(err),matchKey:chatId,matchSource:`id`})}return{ok:groups.every(g=>g.ok),checkedGroups:groups.length,unresolvedGroups:0,hasWildcardUnmentionedGroups:!1,groups,elapsedMs:Date.now()-started}}function resolveTelegramAllowedUpdates(){let updates=[...API_CONSTANTS.DEFAULT_UPDATE_TYPES];return updates.includes(`message_reaction`)||updates.push(`message_reaction`),updates.includes(`channel_post`)||updates.push(`channel_post`),updates}const resolveTelegramUpdateId=ctx=>ctx.update?.update_id??ctx.update_id,buildTelegramUpdateKey=ctx=>{let updateId=resolveTelegramUpdateId(ctx);if(typeof updateId==`number`)return`update:${updateId}`;let callbackId=ctx.callbackQuery?.id;if(callbackId)return`callback:${callbackId}`;let msg=ctx.message??ctx.channelPost??ctx.editedChannelPost??ctx.update?.message??ctx.update?.edited_message??ctx.update?.channel_post??ctx.update?.edited_channel_post??ctx.callbackQuery?.message,chatId=msg?.chat?.id,messageId=msg?.message_id;if(chatId!==void 0&&typeof messageId==`number`)return`message:${chatId}:${messageId}`},createTelegramUpdateDedupe=()=>createDedupeCache({ttlMs:3e5,maxSize:2e3}),PARSE_ERR_RE=/can't parse entities|parse entities|find end of the entity/i,VOICE_FORBIDDEN_RE=/VOICE_MESSAGES_FORBIDDEN/,FILE_TOO_BIG_RE=/file is too big/i;async function deliverReplies(params){let{replies,chatId,runtime,bot,replyToMode,textLimit,thread,linkPreview,replyQuoteText}=params,chunkMode=params.chunkMode??`length`,hasReplied=!1,hasDelivered=!1,markDelivered=()=>{hasDelivered=!0},chunkText=markdown=>{let markdownChunks=chunkMode===`newline`?chunkMarkdownTextWithMode(markdown,textLimit,chunkMode):[markdown],chunks=[];for(let chunk of markdownChunks){let nested=markdownToTelegramChunks(chunk,textLimit,{tableMode:params.tableMode});if(!nested.length&&chunk){chunks.push({html:wrapFileReferencesInHtml(markdownToTelegramHtml(chunk,{tableMode:params.tableMode,wrapFileRefs:!1})),text:chunk});continue}chunks.push(...nested)}return chunks};for(let reply of replies){let hasMedia=!!reply?.mediaUrl||(reply?.mediaUrls?.length??0)>0;if(!reply?.text&&!hasMedia){if(reply?.audioAsVoice){logVerbose(`telegram reply has audioAsVoice without media/text; skipping`);continue}runtime.error?.(danger(`reply missing text/media`));continue}let replyToId=replyToMode===`off`?void 0:resolveTelegramReplyId(reply.replyToId),replyToMessageIdForPayload=replyToId&&(replyToMode===`all`||!hasReplied)?replyToId:void 0,mediaList=reply.mediaUrls?.length?reply.mediaUrls:reply.mediaUrl?[reply.mediaUrl]:[],telegramData=reply.channelData?.telegram,replyMarkup=buildInlineKeyboard(telegramData?.buttons);if(mediaList.length===0){let chunks=chunkText(reply.text||``),sentTextChunk=!1;for(let i=0;i<chunks.length;i+=1){let chunk=chunks[i];if(!chunk)continue;let shouldAttachButtons=i===0&&replyMarkup;await sendTelegramText(bot,chatId,chunk.html,runtime,{replyToMessageId:replyToMessageIdForPayload,replyQuoteText,thread,textMode:`html`,plainText:chunk.text,linkPreview,replyMarkup:shouldAttachButtons?replyMarkup:void 0}),sentTextChunk=!0,markDelivered()}replyToMessageIdForPayload&&!hasReplied&&sentTextChunk&&(hasReplied=!0);continue}let first=!0,pendingFollowUpText;for(let mediaUrl of mediaList){let isFirstMedia=first,media=await loadWebMedia(mediaUrl,{localRoots:params.mediaLocalRoots}),kind=mediaKindFromMime(media.contentType??void 0),isGif=isGifMedia({contentType:media.contentType,fileName:media.fileName}),fileName=media.fileName??(isGif?`animation.gif`:`file`),file=new InputFile(media.buffer,fileName),{caption,followUpText}=splitTelegramCaption(isFirstMedia?reply.text??void 0:void 0),htmlCaption=caption?renderTelegramHtmlText(caption,{tableMode:params.tableMode}):void 0;followUpText&&(pendingFollowUpText=followUpText),first=!1;let replyToMessageId=replyToMessageIdForPayload,shouldAttachButtonsToMedia=isFirstMedia&&replyMarkup&&!followUpText,mediaParams={caption:htmlCaption,...htmlCaption?{parse_mode:`HTML`}:{},...shouldAttachButtonsToMedia?{reply_markup:replyMarkup}:{},...buildTelegramSendParams({replyToMessageId,thread})};if(isGif)await withTelegramApiErrorLogging({operation:`sendAnimation`,runtime,fn:()=>bot.api.sendAnimation(chatId,file,{...mediaParams})}),markDelivered();else if(kind===`image`)await withTelegramApiErrorLogging({operation:`sendPhoto`,runtime,fn:()=>bot.api.sendPhoto(chatId,file,{...mediaParams})}),markDelivered();else if(kind===`video`)await withTelegramApiErrorLogging({operation:`sendVideo`,runtime,fn:()=>bot.api.sendVideo(chatId,file,{...mediaParams})}),markDelivered();else if(kind===`audio`){let{useVoice}=resolveTelegramVoiceSend({wantsVoice:reply.audioAsVoice===!0,contentType:media.contentType,fileName,logFallback:logVerbose});if(useVoice){await params.onVoiceRecording?.();try{await withTelegramApiErrorLogging({operation:`sendVoice`,runtime,shouldLog:err=>!isVoiceMessagesForbidden(err),fn:()=>bot.api.sendVoice(chatId,file,{...mediaParams})}),markDelivered()}catch(voiceErr){if(isVoiceMessagesForbidden(voiceErr)){let fallbackText=reply.text;if(!fallbackText||!fallbackText.trim())throw voiceErr;logVerbose(`telegram sendVoice forbidden (recipient has voice messages blocked in privacy settings); falling back to text`),await sendTelegramVoiceFallbackText({bot,chatId,runtime,text:fallbackText,chunkText,replyToId:replyToMessageIdForPayload,thread,linkPreview,replyMarkup,replyQuoteText}),replyToMessageIdForPayload&&!hasReplied&&(hasReplied=!0),markDelivered();continue}throw voiceErr}}else await withTelegramApiErrorLogging({operation:`sendAudio`,runtime,fn:()=>bot.api.sendAudio(chatId,file,{...mediaParams})}),markDelivered()}else await withTelegramApiErrorLogging({operation:`sendDocument`,runtime,fn:()=>bot.api.sendDocument(chatId,file,{...mediaParams})}),markDelivered();if(replyToId&&!hasReplied&&(hasReplied=!0),pendingFollowUpText&&isFirstMedia){let chunks=chunkText(pendingFollowUpText);for(let i=0;i<chunks.length;i+=1){let chunk=chunks[i];await sendTelegramText(bot,chatId,chunk.html,runtime,{replyToMessageId:replyToMessageIdForPayload,thread,textMode:`html`,plainText:chunk.text,linkPreview,replyMarkup:i===0?replyMarkup:void 0}),markDelivered()}pendingFollowUpText=void 0}replyToMessageIdForPayload&&!hasReplied&&(hasReplied=!0)}}return{delivered:hasDelivered}}async function resolveMedia(ctx,maxBytes,token,proxyFetch){let msg=ctx.message,downloadAndSaveTelegramFile=async(filePath,fetchImpl)=>{let fetched=await fetchRemoteMedia({url:`https://api.telegram.org/file/bot${token}/${filePath}`,fetchImpl,filePathHint:filePath}),originalName=fetched.fileName??filePath;return saveMediaBuffer(fetched.buffer,fetched.contentType,`inbound`,maxBytes,originalName)};if(msg.sticker){let sticker=msg.sticker;if(sticker.is_animated||sticker.is_video)return logVerbose(`telegram: skipping animated/video sticker (only static stickers supported)`),null;if(!sticker.file_id)return null;try{let file=await ctx.getFile();if(!file.file_path)return logVerbose(`telegram: getFile returned no file_path for sticker`),null;let fetchImpl=proxyFetch??globalThis.fetch;if(!fetchImpl)return logVerbose(`telegram: fetch not available for sticker download`),null;let saved=await downloadAndSaveTelegramFile(file.file_path,fetchImpl),cached=sticker.file_unique_id?await getCachedSticker(sticker.file_unique_id):null;if(cached){logVerbose(`telegram: sticker cache hit for ${sticker.file_unique_id}`);let fileId=sticker.file_id??cached.fileId,emoji=sticker.emoji??cached.emoji,setName=sticker.set_name??cached.setName;return(fileId!==cached.fileId||emoji!==cached.emoji||setName!==cached.setName)&&cacheSticker({...cached,fileId,emoji,setName}),{path:saved.path,contentType:saved.contentType,placeholder:`<media:sticker>`,stickerMetadata:{emoji,setName,fileId,fileUniqueId:sticker.file_unique_id,cachedDescription:cached.description}}}return{path:saved.path,contentType:saved.contentType,placeholder:`<media:sticker>`,stickerMetadata:{emoji:sticker.emoji??void 0,setName:sticker.set_name??void 0,fileId:sticker.file_id,fileUniqueId:sticker.file_unique_id}}}catch(err){return logVerbose(`telegram: failed to process sticker: ${String(err)}`),null}}if(!(msg.photo?.[msg.photo.length-1]??msg.video??msg.video_note??msg.document??msg.audio??msg.voice)?.file_id)return null;let file;try{file=await retryAsync(()=>ctx.getFile(),{attempts:3,minDelayMs:1e3,maxDelayMs:4e3,jitter:.2,label:`telegram:getFile`,shouldRetry:isRetryableGetFileError,onRetry:({attempt,maxAttempts})=>logVerbose(`telegram: getFile retry ${attempt}/${maxAttempts}`)})}catch(err){return isFileTooBigError(err)?(logVerbose(warn(`telegram: getFile failed - file exceeds Telegram Bot API 20MB limit; skipping attachment`)),null):(logVerbose(`telegram: getFile failed after retries: ${String(err)}`),null)}if(!file.file_path)throw Error(`Telegram getFile returned no file_path`);let fetchImpl=proxyFetch??globalThis.fetch;if(!fetchImpl)throw Error(`fetch is not available; set channels.telegram.proxy in config`);let saved=await downloadAndSaveTelegramFile(file.file_path,fetchImpl),placeholder=resolveTelegramMediaPlaceholder(msg)??`<media:document>`;return{path:saved.path,contentType:saved.contentType,placeholder}}function isVoiceMessagesForbidden(err){return err instanceof GrammyError?VOICE_FORBIDDEN_RE.test(err.description):VOICE_FORBIDDEN_RE.test(formatErrorMessage(err))}function isFileTooBigError(err){return err instanceof GrammyError?FILE_TOO_BIG_RE.test(err.description):FILE_TOO_BIG_RE.test(formatErrorMessage(err))}function isRetryableGetFileError(err){return!isFileTooBigError(err)}async function sendTelegramVoiceFallbackText(opts){let chunks=opts.chunkText(opts.text);for(let i=0;i<chunks.length;i+=1){let chunk=chunks[i];await sendTelegramText(opts.bot,opts.chatId,chunk.html,opts.runtime,{replyToMessageId:opts.replyToId,replyQuoteText:opts.replyQuoteText,thread:opts.thread,textMode:`html`,plainText:chunk.text,linkPreview:opts.linkPreview,replyMarkup:i===0?opts.replyMarkup:void 0})}}function buildTelegramSendParams(opts){let threadParams=buildTelegramThreadParams(opts?.thread),params={};return opts?.replyToMessageId&&(params.reply_to_message_id=opts.replyToMessageId),threadParams&&(params.message_thread_id=threadParams.message_thread_id),params}async function sendTelegramText(bot,chatId,text,runtime,opts){let baseParams=buildTelegramSendParams({replyToMessageId:opts?.replyToMessageId,thread:opts?.thread}),linkPreviewOptions=opts?.linkPreview??!0?void 0:{is_disabled:!0},htmlText=(opts?.textMode??`markdown`)===`html`?text:markdownToTelegramHtml(text);try{return(await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,shouldLog:err=>!PARSE_ERR_RE.test(formatErrorMessage(err)),fn:()=>bot.api.sendMessage(chatId,htmlText,{parse_mode:`HTML`,...linkPreviewOptions?{link_preview_options:linkPreviewOptions}:{},...opts?.replyMarkup?{reply_markup:opts.replyMarkup}:{},...baseParams})})).message_id}catch(err){let errText=formatErrorMessage(err);if(PARSE_ERR_RE.test(errText)){runtime.log?.(`telegram HTML parse failed; retrying without formatting: ${errText}`);let fallbackText=opts?.plainText??text;return(await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,fn:()=>bot.api.sendMessage(chatId,fallbackText,{...linkPreviewOptions?{link_preview_options:linkPreviewOptions}:{},...opts?.replyMarkup?{reply_markup:opts.replyMarkup}:{},...baseParams})})).message_id}throw err}}const evaluateTelegramGroupBaseAccess=params=>{if(!params.isGroup)return{allowed:!0};if(params.groupConfig?.enabled===!1)return{allowed:!1,reason:`group-disabled`};if(params.topicConfig?.enabled===!1)return{allowed:!1,reason:`topic-disabled`};if(!params.enforceAllowOverride||!params.hasGroupAllowOverride)return{allowed:!0};let senderId=params.senderId??``;return params.requireSenderForAllowOverride&&!senderId||!isSenderAllowed$1({allow:params.effectiveGroupAllow,senderId,senderUsername:params.senderUsername??``})?{allowed:!1,reason:`group-override-unauthorized`}:{allowed:!0}},evaluateTelegramGroupPolicyAccess=params=>{let fallbackPolicy=firstDefined$2(params.telegramCfg.groupPolicy,params.cfg.channels?.defaults?.groupPolicy,`open`)??`open`,groupPolicy=params.useTopicAndGroupOverrides?firstDefined$2(params.topicConfig?.groupPolicy,params.groupConfig?.groupPolicy,params.telegramCfg.groupPolicy,params.cfg.channels?.defaults?.groupPolicy,`open`)??`open`:fallbackPolicy;if(!params.isGroup||!params.enforcePolicy)return{allowed:!0,groupPolicy};if(groupPolicy===`disabled`)return{allowed:!1,reason:`group-policy-disabled`,groupPolicy};if(groupPolicy===`allowlist`&&params.enforceAllowlistAuthorization){let senderId=params.senderId??``;if(params.requireSenderForAllowlistAuthorization&&!senderId)return{allowed:!1,reason:`group-policy-allowlist-no-sender`,groupPolicy};if(!params.allowEmptyAllowlistEntries&&!params.effectiveGroupAllow.hasEntries)return{allowed:!1,reason:`group-policy-allowlist-empty`,groupPolicy};let senderUsername=params.senderUsername??``;if(!isSenderAllowed$1({allow:params.effectiveGroupAllow,senderId,senderUsername}))return{allowed:!1,reason:`group-policy-allowlist-unauthorized`,groupPolicy}}if(params.checkChatAllowlist){let groupAllowlist=params.resolveGroupPolicy(params.chatId);if(groupAllowlist.allowlistEnabled&&!groupAllowlist.allowed)return{allowed:!1,reason:`group-chat-not-allowed`,groupPolicy}}return{allowed:!0,groupPolicy}};function resolveAccountGroups(cfg,accountId){if(!accountId)return{};let normalized=normalizeAccountId$2(accountId),accounts=cfg.channels?.telegram?.accounts;if(!accounts||typeof accounts!=`object`)return{};let exact=accounts[normalized];if(exact?.groups)return{groups:exact.groups};let matchKey=Object.keys(accounts).find(key=>key.toLowerCase()===normalized.toLowerCase());return{groups:matchKey?accounts[matchKey]?.groups:void 0}}function migrateTelegramGroupsInPlace(groups,oldChatId,newChatId){return!groups||oldChatId===newChatId||!Object.hasOwn(groups,oldChatId)?{migrated:!1,skippedExisting:!1}:Object.hasOwn(groups,newChatId)?{migrated:!1,skippedExisting:!0}:(groups[newChatId]=groups[oldChatId],delete groups[oldChatId],{migrated:!0,skippedExisting:!1})}function migrateTelegramGroupConfig(params){let scopes=[],migrated=!1,skippedExisting=!1,migrationTargets=[{scope:`account`,groups:resolveAccountGroups(params.cfg,params.accountId).groups},{scope:`global`,groups:params.cfg.channels?.telegram?.groups}];for(let target of migrationTargets){let result=migrateTelegramGroupsInPlace(target.groups,params.oldChatId,params.newChatId);result.migrated&&(migrated=!0,scopes.push(target.scope)),result.skippedExisting&&(skippedExisting=!0)}return{migrated,skippedExisting,scopes}}const registerTelegramHandlers=({cfg,accountId,bot,opts,runtime,mediaMaxBytes,telegramCfg,groupAllowFrom,resolveGroupPolicy,resolveTelegramGroupConfig,shouldSkipUpdate,processMessage,logger})=>{let TELEGRAM_TEXT_FRAGMENT_MAX_GAP_MS=typeof opts.testTimings?.textFragmentGapMs==`number`&&Number.isFinite(opts.testTimings.textFragmentGapMs)?Math.max(10,Math.floor(opts.testTimings.textFragmentGapMs)):1500,mediaGroupTimeoutMs=typeof opts.testTimings?.mediaGroupFlushMs==`number`&&Number.isFinite(opts.testTimings.mediaGroupFlushMs)?Math.max(10,Math.floor(opts.testTimings.mediaGroupFlushMs)):500,mediaGroupBuffer=new Map,mediaGroupProcessing=Promise.resolve(),textFragmentBuffer=new Map,textFragmentProcessing=Promise.resolve(),debounceMs=resolveInboundDebounceMs({cfg,channel:`telegram`}),buildSyntheticTextMessage=params=>({...params.base,...params.from?{from:params.from}:{},text:params.text,caption:void 0,caption_entities:void 0,entities:void 0,...params.date==null?{}:{date:params.date}}),buildSyntheticContext=(ctx,message)=>{let getFile=typeof ctx.getFile==`function`?ctx.getFile.bind(ctx):async()=>({});return{message,me:ctx.me,getFile}},inboundDebouncer=createInboundDebouncer({debounceMs,buildKey:entry=>entry.debounceKey,shouldDebounce:entry=>{if(entry.allMedia.length>0)return!1;let text=entry.msg.text??entry.msg.caption??``;return text.trim()?!hasControlCommand(text,cfg,{botUsername:entry.botUsername}):!1},onFlush:async entries=>{let last=entries.at(-1);if(!last)return;if(entries.length===1){await processMessage(last.ctx,last.allMedia,last.storeAllowFrom);return}let combinedText=entries.map(entry=>entry.msg.text??entry.msg.caption??``).filter(Boolean).join(`
474
474
  `);if(!combinedText.trim())return;let first=entries[0],baseCtx=first.ctx,syntheticMessage=buildSyntheticTextMessage({base:first.msg,text:combinedText,date:last.msg.date??first.msg.date}),messageIdOverride=last.msg.message_id?String(last.msg.message_id):void 0;await processMessage(buildSyntheticContext(baseCtx,syntheticMessage),[],first.storeAllowFrom,messageIdOverride?{messageIdOverride}:void 0)},onError:err=>{runtime.error?.(danger(`telegram debounce flush failed: ${String(err)}`))}}),resolveTelegramSessionModel=params=>{let resolvedThreadId=params.resolvedThreadId??resolveTelegramForumThreadId({isForum:params.isForum,messageThreadId:params.messageThreadId}),peerId=params.isGroup?buildTelegramGroupPeerId(params.chatId,resolvedThreadId):String(params.chatId),parentPeer=buildTelegramParentPeer({isGroup:params.isGroup,resolvedThreadId,chatId:params.chatId}),route=resolveAgentRoute({cfg,channel:`telegram`,accountId,peer:{kind:params.isGroup?`group`:`direct`,id:peerId},parentPeer}),baseSessionKey=route.sessionKey,dmThreadId=params.isGroup?void 0:params.messageThreadId,sessionKey=(dmThreadId==null?null:resolveThreadSessionKeys({baseSessionKey,threadId:String(dmThreadId)}))?.sessionKey??baseSessionKey,store=loadSessionStore(resolveStorePath(cfg.session?.store,{agentId:route.agentId})),entry=store[sessionKey],storedOverride=resolveStoredModelOverride({sessionEntry:entry,sessionStore:store,sessionKey});if(storedOverride)return storedOverride.provider?`${storedOverride.provider}/${storedOverride.model}`:storedOverride.model;let provider=entry?.modelProvider?.trim(),model=entry?.model?.trim();if(provider&&model)return`${provider}/${model}`;let modelCfg=cfg.agents?.defaults?.model;return typeof modelCfg==`string`?modelCfg:modelCfg?.primary},processMediaGroup=async entry=>{try{entry.messages.sort((a,b)=>a.msg.message_id-b.msg.message_id);let primaryEntry=entry.messages.find(m=>m.msg.caption||m.msg.text)??entry.messages[0],allMedia=[];for(let{ctx}of entry.messages){let media=await resolveMedia(ctx,mediaMaxBytes,opts.token,opts.proxyFetch);media&&allMedia.push({path:media.path,contentType:media.contentType,stickerMetadata:media.stickerMetadata})}let storeAllowFrom=await loadStoreAllowFrom();await processMessage(primaryEntry.ctx,allMedia,storeAllowFrom)}catch(err){runtime.error?.(danger(`media group handler failed: ${String(err)}`))}},flushTextFragments=async entry=>{try{entry.messages.sort((a,b)=>a.msg.message_id-b.msg.message_id);let first=entry.messages[0],last=entry.messages.at(-1);if(!first||!last)return;let combinedText=entry.messages.map(m=>m.msg.text??``).join(``);if(!combinedText.trim())return;let syntheticMessage=buildSyntheticTextMessage({base:first.msg,text:combinedText,date:last.msg.date??first.msg.date}),storeAllowFrom=await loadStoreAllowFrom(),baseCtx=first.ctx;await processMessage(buildSyntheticContext(baseCtx,syntheticMessage),[],storeAllowFrom,{messageIdOverride:String(last.msg.message_id)})}catch(err){runtime.error?.(danger(`text fragment handler failed: ${String(err)}`))}},queueTextFragmentFlush=async entry=>{textFragmentProcessing=textFragmentProcessing.then(async()=>{await flushTextFragments(entry)}).catch(()=>void 0),await textFragmentProcessing},runTextFragmentFlush=async entry=>{textFragmentBuffer.delete(entry.key),await queueTextFragmentFlush(entry)},scheduleTextFragmentFlush=entry=>{clearTimeout(entry.timer),entry.timer=setTimeout(async()=>{await runTextFragmentFlush(entry)},TELEGRAM_TEXT_FRAGMENT_MAX_GAP_MS)},loadStoreAllowFrom=async()=>readChannelAllowFromStore(`telegram`,process.env,accountId).catch(()=>[]),isAllowlistAuthorized=(allow,senderId,senderUsername)=>allow.hasWildcard||allow.hasEntries&&isSenderAllowed$1({allow,senderId,senderUsername}),shouldSkipGroupMessage=params=>{let{isGroup,chatId,chatTitle,resolvedThreadId,senderId,senderUsername,effectiveGroupAllow,hasGroupAllowOverride,groupConfig,topicConfig}=params,baseAccess=evaluateTelegramGroupBaseAccess({isGroup,groupConfig,topicConfig,hasGroupAllowOverride,effectiveGroupAllow,senderId,senderUsername,enforceAllowOverride:!0,requireSenderForAllowOverride:!0});if(!baseAccess.allowed)return baseAccess.reason===`group-disabled`?(logVerbose(`Blocked telegram group ${chatId} (group disabled)`),!0):baseAccess.reason===`topic-disabled`?(logVerbose(`Blocked telegram topic ${chatId} (${resolvedThreadId??`unknown`}) (topic disabled)`),!0):(logVerbose(`Blocked telegram group sender ${senderId||`unknown`} (group allowFrom override)`),!0);if(!isGroup)return!1;let policyAccess=evaluateTelegramGroupPolicyAccess({isGroup,chatId,cfg,telegramCfg,topicConfig,groupConfig,effectiveGroupAllow,senderId,senderUsername,resolveGroupPolicy,enforcePolicy:!0,useTopicAndGroupOverrides:!0,enforceAllowlistAuthorization:!0,allowEmptyAllowlistEntries:!1,requireSenderForAllowlistAuthorization:!0,checkChatAllowlist:!0});return policyAccess.allowed?!1:policyAccess.reason===`group-policy-disabled`?(logVerbose(`Blocked telegram group message (groupPolicy: disabled)`),!0):policyAccess.reason===`group-policy-allowlist-no-sender`?(logVerbose(`Blocked telegram group message (no sender ID, groupPolicy: allowlist)`),!0):policyAccess.reason===`group-policy-allowlist-empty`?(logVerbose(`Blocked telegram group message (groupPolicy: allowlist, no group allowlist entries)`),!0):policyAccess.reason===`group-policy-allowlist-unauthorized`?(logVerbose(`Blocked telegram group message from ${senderId} (groupPolicy: allowlist)`),!0):(logger.info({chatId,title:chatTitle,reason:`not-allowed`},`skipping group message`),!0)};bot.on(`message_reaction`,async ctx=>{try{let reaction=ctx.messageReaction;if(!reaction||shouldSkipUpdate(ctx))return;let chatId=reaction.chat.id,messageId=reaction.message_id,user=reaction.user,reactionMode=telegramCfg.reactionNotifications??`own`;if(reactionMode===`off`||user?.is_bot||reactionMode===`own`&&!wasSentByBot(chatId,messageId))return;let oldEmojis=new Set(reaction.old_reaction.filter(r=>r.type===`emoji`).map(r=>r.emoji)),addedReactions=reaction.new_reaction.filter(r=>r.type===`emoji`).filter(r=>!oldEmojis.has(r.emoji));if(addedReactions.length===0)return;let senderName=user?[user.first_name,user.last_name].filter(Boolean).join(` `).trim()||user.username:void 0,senderUsername=user?.username?`@${user.username}`:void 0,senderLabel=senderName;senderName&&senderUsername?senderLabel=`${senderName} (${senderUsername})`:!senderName&&senderUsername&&(senderLabel=senderUsername),!senderLabel&&user?.id&&(senderLabel=`id:${user.id}`),senderLabel||=`unknown`;let isGroup=reaction.chat.type===`group`||reaction.chat.type===`supergroup`,isForum=reaction.chat.is_forum===!0,resolvedThreadId=isForum?resolveTelegramForumThreadId({isForum,messageThreadId:void 0}):void 0,peerId=isGroup?buildTelegramGroupPeerId(chatId,resolvedThreadId):String(chatId),parentPeer=buildTelegramParentPeer({isGroup,resolvedThreadId,chatId}),sessionKey=resolveAgentRoute({cfg:loadConfig(),channel:`telegram`,accountId,peer:{kind:isGroup?`group`:`direct`,id:peerId},parentPeer}).sessionKey;for(let r of addedReactions){let emoji=r.emoji,text=`Telegram reaction added: ${emoji} by ${senderLabel} on msg ${messageId}`;enqueueSystemEvent(text,{sessionKey,contextKey:`telegram:reaction:add:${chatId}:${messageId}:${user?.id??`anon`}:${emoji}`}),logVerbose(`telegram: reaction event enqueued: ${text}`)}}catch(err){runtime.error?.(danger(`telegram reaction handler failed: ${String(err)}`))}});let processInboundMessage=async params=>{let{ctx,msg,chatId,resolvedThreadId,storeAllowFrom,sendOversizeWarning,oversizeLogMessage}=params,text=typeof msg.text==`string`?msg.text:void 0,isCommandLike=(text??``).trim().startsWith(`/`);if(text&&!isCommandLike){let nowMs=Date.now(),senderId=msg.from?.id==null?`unknown`:String(msg.from.id),key=`text:${chatId}:${resolvedThreadId??`main`}:${senderId}`,existing=textFragmentBuffer.get(key);if(existing){let last=existing.messages.at(-1),lastMsgId=last?.msg.message_id,lastReceivedAtMs=last?.receivedAtMs??nowMs,idGap=typeof lastMsgId==`number`?msg.message_id-lastMsgId:1/0,timeGapMs=nowMs-lastReceivedAtMs;if(idGap>0&&idGap<=1&&timeGapMs>=0&&timeGapMs<=TELEGRAM_TEXT_FRAGMENT_MAX_GAP_MS){let nextTotalChars=existing.messages.reduce((sum,m)=>sum+(m.msg.text?.length??0),0)+text.length;if(existing.messages.length+1<=12&&nextTotalChars<=5e4){existing.messages.push({msg,ctx,receivedAtMs:nowMs}),scheduleTextFragmentFlush(existing);return}}clearTimeout(existing.timer),textFragmentBuffer.delete(key),textFragmentProcessing=textFragmentProcessing.then(async()=>{await flushTextFragments(existing)}).catch(()=>void 0),await textFragmentProcessing}if(text.length>=4e3){let entry={key,messages:[{msg,ctx,receivedAtMs:nowMs}],timer:setTimeout(()=>{},TELEGRAM_TEXT_FRAGMENT_MAX_GAP_MS)};textFragmentBuffer.set(key,entry),scheduleTextFragmentFlush(entry);return}}let mediaGroupId=msg.media_group_id;if(mediaGroupId){let existing=mediaGroupBuffer.get(mediaGroupId);if(existing)clearTimeout(existing.timer),existing.messages.push({msg,ctx}),existing.timer=setTimeout(async()=>{mediaGroupBuffer.delete(mediaGroupId),mediaGroupProcessing=mediaGroupProcessing.then(async()=>{await processMediaGroup(existing)}).catch(()=>void 0),await mediaGroupProcessing},mediaGroupTimeoutMs);else{let entry={messages:[{msg,ctx}],timer:setTimeout(async()=>{mediaGroupBuffer.delete(mediaGroupId),mediaGroupProcessing=mediaGroupProcessing.then(async()=>{await processMediaGroup(entry)}).catch(()=>void 0),await mediaGroupProcessing},mediaGroupTimeoutMs)};mediaGroupBuffer.set(mediaGroupId,entry)}return}let media=null;try{media=await resolveMedia(ctx,mediaMaxBytes,opts.token,opts.proxyFetch)}catch(mediaErr){let errMsg=String(mediaErr);if(errMsg.includes(`exceeds`)&&errMsg.includes(`MB limit`)){if(sendOversizeWarning){let limitMb=Math.round(mediaMaxBytes/(1024*1024));await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,fn:()=>bot.api.sendMessage(chatId,`⚠️ File too large. Maximum size is ${limitMb}MB.`,{reply_to_message_id:msg.message_id})}).catch(()=>{})}logger.warn({chatId,error:errMsg},oversizeLogMessage);return}throw mediaErr}let hasText=!!(msg.text??msg.caption??``).trim();if(msg.sticker&&!media&&!hasText){logVerbose(`telegram: skipping sticker-only message (unsupported sticker type)`);return}let allMedia=media?[{path:media.path,contentType:media.contentType,stickerMetadata:media.stickerMetadata}]:[],senderId=msg.from?.id?String(msg.from.id):``,conversationKey=resolvedThreadId==null?String(chatId):`${chatId}:topic:${resolvedThreadId}`,debounceKey=senderId?`telegram:${accountId??`default`}:${conversationKey}:${senderId}`:null;await inboundDebouncer.enqueue({ctx,msg,allMedia,storeAllowFrom,debounceKey,botUsername:ctx.me?.username})};bot.on(`callback_query`,async ctx=>{let callback=ctx.callbackQuery;if(callback&&!shouldSkipUpdate(ctx)){await withTelegramApiErrorLogging({operation:`answerCallbackQuery`,runtime,fn:typeof ctx.answerCallbackQuery==`function`?()=>ctx.answerCallbackQuery():()=>bot.api.answerCallbackQuery(callback.id)}).catch(()=>{});try{let data=(callback.data??``).trim(),callbackMessage=callback.message;if(!data||!callbackMessage)return;let editCallbackMessage=async(text,params)=>typeof ctx.editMessageText==`function`?await ctx.editMessageText(text,params):await bot.api.editMessageText(callbackMessage.chat.id,callbackMessage.message_id,text,params),deleteCallbackMessage=async()=>typeof ctx.deleteMessage==`function`?await ctx.deleteMessage():await bot.api.deleteMessage(callbackMessage.chat.id,callbackMessage.message_id),replyToCallbackChat=async(text,params)=>typeof ctx.reply==`function`?await ctx.reply(text,params):await bot.api.sendMessage(callbackMessage.chat.id,text,params),inlineButtonsScope=resolveTelegramInlineButtonsScope({cfg,accountId});if(inlineButtonsScope===`off`)return;let chatId=callbackMessage.chat.id,isGroup=callbackMessage.chat.type===`group`||callbackMessage.chat.type===`supergroup`;if(inlineButtonsScope===`dm`&&isGroup||inlineButtonsScope===`group`&&!isGroup)return;let messageThreadId=callbackMessage.message_thread_id,isForum=callbackMessage.chat.is_forum===!0,{resolvedThreadId,storeAllowFrom,groupConfig,topicConfig,effectiveGroupAllow,hasGroupAllowOverride}=await resolveTelegramGroupAllowFromContext({chatId,accountId,isForum,messageThreadId,groupAllowFrom,resolveTelegramGroupConfig}),effectiveDmAllow=normalizeAllowFromWithStore$1({allowFrom:telegramCfg.allowFrom,storeAllowFrom}),dmPolicy=telegramCfg.dmPolicy??`pairing`,senderId=callback.from?.id?String(callback.from.id):``,senderUsername=callback.from?.username??``;if(shouldSkipGroupMessage({isGroup,chatId,chatTitle:callbackMessage.chat.title,resolvedThreadId,senderId,senderUsername,effectiveGroupAllow,hasGroupAllowOverride,groupConfig,topicConfig}))return;if(inlineButtonsScope===`allowlist`){if(!isGroup){if(dmPolicy===`disabled`||dmPolicy!==`open`&&!isAllowlistAuthorized(effectiveDmAllow,senderId,senderUsername))return}else if(!isAllowlistAuthorized(effectiveGroupAllow,senderId,senderUsername))return}let paginationMatch=data.match(/^commands_page_(\d+|noop)(?::(.+))?$/);if(paginationMatch){let pageValue=paginationMatch[1];if(pageValue===`noop`)return;let page=Number.parseInt(pageValue,10);if(Number.isNaN(page)||page<1)return;let agentId=paginationMatch[2]?.trim()||resolveDefaultAgentId(cfg)||void 0,result=buildCommandsMessagePaginated(cfg,listSkillCommandsForAgents({cfg,agentIds:agentId?[agentId]:void 0}),{page,surface:`telegram`}),keyboard=result.totalPages>1?buildInlineKeyboard(buildCommandsPaginationKeyboard(result.currentPage,result.totalPages,agentId)):void 0;try{await editCallbackMessage(result.text,keyboard?{reply_markup:keyboard}:void 0)}catch(editErr){if(!String(editErr).includes(`message is not modified`))throw editErr}return}let modelCallback=parseModelCallbackData(data);if(modelCallback){let{byProvider,providers}=await buildModelsProviderData(cfg),editMessageWithButtons=async(text,buttons)=>{let keyboard=buildInlineKeyboard(buttons);try{await editCallbackMessage(text,keyboard?{reply_markup:keyboard}:void 0)}catch(editErr){let errStr=String(editErr);if(errStr.includes(`no text in the message`)){try{await deleteCallbackMessage()}catch{}await replyToCallbackChat(text,keyboard?{reply_markup:keyboard}:void 0)}else if(!errStr.includes(`message is not modified`))throw editErr}};if(modelCallback.type===`providers`||modelCallback.type===`back`){if(providers.length===0){await editMessageWithButtons(`No providers available.`,[]);return}await editMessageWithButtons(`Select a provider:`,buildProviderKeyboard(providers.map(p=>({id:p,count:byProvider.get(p)?.size??0}))));return}if(modelCallback.type===`list`){let{provider,page}=modelCallback,modelSet=byProvider.get(provider);if(!modelSet||modelSet.size===0){let buttons=buildProviderKeyboard(providers.map(p=>({id:p,count:byProvider.get(p)?.size??0})));await editMessageWithButtons(`Unknown provider: ${provider}\n\nSelect a provider:`,buttons);return}let models=[...modelSet].toSorted(),pageSize=getModelsPageSize(),totalPages=calculateTotalPages(models.length,pageSize),safePage=Math.max(1,Math.min(page,totalPages)),buttons=buildModelsKeyboard({provider,models,currentModel:resolveTelegramSessionModel({chatId,isGroup,isForum,messageThreadId,resolvedThreadId}),currentPage:safePage,totalPages,pageSize});await editMessageWithButtons(`Models (${provider}) — ${models.length} available`,buttons);return}if(modelCallback.type===`select`){let{provider,model}=modelCallback;await processMessage(buildSyntheticContext(ctx,buildSyntheticTextMessage({base:callbackMessage,from:callback.from,text:`/model ${provider}/${model}`})),[],storeAllowFrom,{forceWasMentioned:!0,messageIdOverride:callback.id});return}return}await processMessage(buildSyntheticContext(ctx,buildSyntheticTextMessage({base:callbackMessage,from:callback.from,text:data})),[],storeAllowFrom,{forceWasMentioned:!0,messageIdOverride:callback.id})}catch(err){runtime.error?.(danger(`callback handler failed: ${String(err)}`))}}}),bot.on(`message:migrate_to_chat_id`,async ctx=>{try{let msg=ctx.message;if(!msg?.migrate_to_chat_id||shouldSkipUpdate(ctx))return;let oldChatId=String(msg.chat.id),newChatId=String(msg.migrate_to_chat_id),chatTitle=msg.chat.title??`Unknown`;if(runtime.log?.(warn(`[telegram] Group migrated: "${chatTitle}" ${oldChatId} → ${newChatId}`)),!resolveChannelConfigWrites({cfg,channelId:`telegram`,accountId})){runtime.log?.(warn(`[telegram] Config writes disabled; skipping group config migration.`));return}let currentConfig=loadConfig(),migration=migrateTelegramGroupConfig({cfg:currentConfig,accountId,oldChatId,newChatId});migration.migrated?(runtime.log?.(warn(`[telegram] Migrating group config from ${oldChatId} to ${newChatId}`)),migrateTelegramGroupConfig({cfg,accountId,oldChatId,newChatId}),await writeConfigFile(currentConfig),runtime.log?.(warn(`[telegram] Group config migrated and saved successfully`))):migration.skippedExisting?runtime.log?.(warn(`[telegram] Group config already exists for ${newChatId}; leaving ${oldChatId} unchanged`)):runtime.log?.(warn(`[telegram] No config found for old group ID ${oldChatId}, migration logged only`))}catch(err){runtime.error?.(danger(`[telegram] Group migration handler failed: ${String(err)}`))}});let handleInboundMessageLike=async event=>{try{if(shouldSkipUpdate(event.ctxForDedupe))return;let{resolvedThreadId,storeAllowFrom,groupConfig,topicConfig,effectiveGroupAllow,hasGroupAllowOverride}=await resolveTelegramGroupAllowFromContext({chatId:event.chatId,accountId,isForum:event.isForum,messageThreadId:event.messageThreadId,groupAllowFrom,resolveTelegramGroupConfig});if(event.requireConfiguredGroup&&(!groupConfig||groupConfig.enabled===!1)){logVerbose(`Blocked telegram channel ${event.chatId} (channel disabled)`);return}if(shouldSkipGroupMessage({isGroup:event.isGroup,chatId:event.chatId,chatTitle:event.msg.chat.title,resolvedThreadId,senderId:event.senderId,senderUsername:event.senderUsername,effectiveGroupAllow,hasGroupAllowOverride,groupConfig,topicConfig}))return;await processInboundMessage({ctx:event.ctx,msg:event.msg,chatId:event.chatId,resolvedThreadId,storeAllowFrom,sendOversizeWarning:event.sendOversizeWarning,oversizeLogMessage:event.oversizeLogMessage})}catch(err){runtime.error?.(danger(`${event.errorMessage}: ${String(err)}`))}};bot.on(`message`,async ctx=>{let msg=ctx.message;msg&&await handleInboundMessageLike({ctxForDedupe:ctx,ctx:buildSyntheticContext(ctx,msg),msg,chatId:msg.chat.id,isGroup:msg.chat.type===`group`||msg.chat.type===`supergroup`,isForum:msg.chat.is_forum===!0,messageThreadId:msg.message_thread_id,senderId:msg.from?.id==null?``:String(msg.from.id),senderUsername:msg.from?.username??``,requireConfiguredGroup:!1,sendOversizeWarning:!0,oversizeLogMessage:`media exceeds size limit`,errorMessage:`handler failed`})}),bot.on(`channel_post`,async ctx=>{let post=ctx.channelPost;if(!post)return;let chatId=post.chat.id,syntheticFrom=post.sender_chat?{id:post.sender_chat.id,is_bot:!0,first_name:post.sender_chat.title||`Channel`,username:post.sender_chat.username}:{id:chatId,is_bot:!0,first_name:post.chat.title||`Channel`,username:post.chat.username},syntheticMsg={...post,from:post.from??syntheticFrom,chat:{...post.chat,type:`supergroup`}};await handleInboundMessageLike({ctxForDedupe:ctx,ctx:buildSyntheticContext(ctx,syntheticMsg),msg:syntheticMsg,chatId,isGroup:!0,isForum:!1,senderId:post.sender_chat?.id==null?post.from?.id==null?``:String(post.from.id):String(post.sender_chat.id),senderUsername:post.sender_chat?.username??post.from?.username??``,requireConfiguredGroup:!0,sendOversizeWarning:!1,oversizeLogMessage:`channel post media exceeds size limit`,errorMessage:`channel_post handler failed`})})};async function resolveStickerVisionSupport$1(params){try{let catalog=await loadModelCatalog({config:params.cfg}),defaultModel=resolveDefaultModelForAgent({cfg:params.cfg,agentId:params.agentId}),entry=findModelInCatalog(catalog,defaultModel.provider,defaultModel.model);return entry?modelSupportsVision(entry):!1}catch{return!1}}const buildTelegramMessageContext=async({primaryCtx,allMedia,storeAllowFrom,options,bot,cfg,account,historyLimit,groupHistories,dmPolicy,allowFrom,groupAllowFrom,ackReactionScope,logger,resolveGroupActivation,resolveGroupRequireMention,resolveTelegramGroupConfig})=>{let msg=primaryCtx.message;recordChannelActivity({channel:`telegram`,accountId:account.accountId,direction:`inbound`});let chatId=msg.chat.id,isGroup=msg.chat.type===`group`||msg.chat.type===`supergroup`,messageThreadId=msg.message_thread_id,isForum=msg.chat.is_forum===!0,threadSpec=resolveTelegramThreadSpec({isGroup,isForum,messageThreadId}),resolvedThreadId=threadSpec.scope===`forum`?threadSpec.id:void 0,replyThreadId=threadSpec.id,{groupConfig,topicConfig}=resolveTelegramGroupConfig(chatId,resolvedThreadId),peerId=isGroup?buildTelegramGroupPeerId(chatId,resolvedThreadId):String(chatId),parentPeer=buildTelegramParentPeer({isGroup,resolvedThreadId,chatId}),route=resolveAgentRoute({cfg:loadConfig(),channel:`telegram`,accountId:account.accountId,peer:{kind:isGroup?`group`:`direct`,id:peerId},parentPeer}),baseSessionKey=route.sessionKey,dmThreadId=threadSpec.scope===`dm`?threadSpec.id:void 0,sessionKey=(dmThreadId==null?null:resolveThreadSessionKeys({baseSessionKey,threadId:String(dmThreadId)}))?.sessionKey??baseSessionKey,mentionRegexes=buildMentionRegexes(cfg,route.agentId),effectiveDmAllow=normalizeAllowFromWithStore$1({allowFrom,storeAllowFrom}),groupAllowOverride=firstDefined$2(topicConfig?.allowFrom,groupConfig?.allowFrom),effectiveGroupAllow=normalizeAllowFromWithStore$1({allowFrom:groupAllowOverride??groupAllowFrom,storeAllowFrom}),hasGroupAllowOverride=groupAllowOverride!==void 0,senderId=msg.from?.id?String(msg.from.id):``,senderUsername=msg.from?.username??``,baseAccess=evaluateTelegramGroupBaseAccess({isGroup,groupConfig,topicConfig,hasGroupAllowOverride,effectiveGroupAllow,senderId,senderUsername,enforceAllowOverride:!0,requireSenderForAllowOverride:!1});if(!baseAccess.allowed)return baseAccess.reason===`group-disabled`?(logVerbose(`Blocked telegram group ${chatId} (group disabled)`),null):baseAccess.reason===`topic-disabled`?(logVerbose(`Blocked telegram topic ${chatId} (${resolvedThreadId??`unknown`}) (topic disabled)`),null):(logVerbose(`Blocked telegram group sender ${senderId||`unknown`} (group allowFrom override)`),null);let activationOverride=resolveGroupActivation({chatId,messageThreadId:resolvedThreadId,sessionKey,agentId:route.agentId}),baseRequireMention=resolveGroupRequireMention(chatId),requireMention=firstDefined$2(activationOverride,topicConfig?.requireMention,groupConfig?.requireMention,baseRequireMention),sendTyping=async()=>{await withTelegramApiErrorLogging({operation:`sendChatAction`,fn:()=>bot.api.sendChatAction(chatId,`typing`,buildTypingThreadParams(replyThreadId))})},sendRecordVoice=async()=>{try{await withTelegramApiErrorLogging({operation:`sendChatAction`,fn:()=>bot.api.sendChatAction(chatId,`record_voice`,buildTypingThreadParams(replyThreadId))})}catch(err){logVerbose(`telegram record_voice cue failed for chat ${chatId}: ${String(err)}`)}};if(!isGroup){if(dmPolicy===`disabled`)return null;if(dmPolicy!==`open`){let senderUsername=msg.from?.username??``,senderUserId=msg.from?.id==null?null:String(msg.from.id),candidate=senderUserId??String(chatId),allowMatch=resolveSenderAllowMatch({allow:effectiveDmAllow,senderId:candidate,senderUsername}),allowMatchMeta=`matchKey=${allowMatch.matchKey??`none`} matchSource=${allowMatch.matchSource??`none`}`;if(!(effectiveDmAllow.hasWildcard||effectiveDmAllow.hasEntries&&allowMatch.allowed)){if(dmPolicy===`pairing`)try{let from=msg.from,telegramUserId=from?.id?String(from.id):candidate,{code,created}=await upsertChannelPairingRequest({channel:`telegram`,id:telegramUserId,accountId:account.accountId,meta:{username:from?.username,firstName:from?.first_name,lastName:from?.last_name}});created&&(logger.info({chatId:String(chatId),senderUserId:senderUserId??void 0,username:from?.username,firstName:from?.first_name,lastName:from?.last_name,matchKey:allowMatch.matchKey??`none`,matchSource:allowMatch.matchSource??`none`},`telegram pairing request`),await withTelegramApiErrorLogging({operation:`sendMessage`,fn:()=>bot.api.sendMessage(chatId,buildPairingReply({channel:`telegram`,idLine:`Your Telegram user id: ${telegramUserId}`,code}))}))}catch(err){logVerbose(`telegram pairing reply failed for chat ${chatId}: ${String(err)}`)}else logVerbose(`Blocked unauthorized telegram sender ${candidate} (dmPolicy=${dmPolicy}, ${allowMatchMeta})`);return null}}}let botUsername=primaryCtx.me?.username?.toLowerCase(),allowForCommands=isGroup?effectiveGroupAllow:effectiveDmAllow,senderAllowedForCommands=isSenderAllowed$1({allow:allowForCommands,senderId,senderUsername}),useAccessGroups=cfg.commands?.useAccessGroups!==!1,hasControlCommandInMessage=hasControlCommand(msg.text??msg.caption??``,cfg,{botUsername}),commandGate=resolveControlCommandGate({useAccessGroups,authorizers:[{configured:allowForCommands.hasEntries,allowed:senderAllowedForCommands}],allowTextCommands:!0,hasControlCommand:hasControlCommandInMessage}),commandAuthorized=commandGate.commandAuthorized,historyKey=isGroup?buildTelegramGroupPeerId(chatId,resolvedThreadId):void 0,placeholder=resolveTelegramMediaPlaceholder(msg)??``,cachedStickerDescription=allMedia[0]?.stickerMetadata?.cachedDescription,stickerSupportsVision=msg.sticker?await resolveStickerVisionSupport$1({cfg,agentId:route.agentId}):!1,stickerCacheHit=!!cachedStickerDescription&&!stickerSupportsVision;if(stickerCacheHit){let emoji=allMedia[0]?.stickerMetadata?.emoji,setName=allMedia[0]?.stickerMetadata?.setName,stickerContext=[emoji,setName?`from "${setName}"`:null].filter(Boolean).join(` `);placeholder=`[Sticker${stickerContext?` ${stickerContext}`:``}] ${cachedStickerDescription}`}let locationData=extractTelegramLocation(msg),locationText=locationData?formatLocationText(locationData):void 0,rawText=expandTextLinks(msg.text??msg.caption??``,msg.entities??msg.caption_entities).trim(),hasUserText=!!(rawText||locationText),rawBody=[rawText,locationText].filter(Boolean).join(`
475
- `).trim();if(rawBody||=placeholder,!rawBody&&allMedia.length===0)return null;let bodyText=rawBody,hasAudio=allMedia.some(media=>media.contentType?.startsWith(`audio/`)),preflightTranscript;if(isGroup&&requireMention&&hasAudio&&!hasUserText&&mentionRegexes.length>0)try{let{transcribeFirstAudio}=await import(`./audio-preflight-CWFuqbao.js`);preflightTranscript=await transcribeFirstAudio({ctx:{MediaPaths:allMedia.length>0?allMedia.map(m=>m.path):void 0,MediaTypes:allMedia.length>0?allMedia.map(m=>m.contentType).filter(Boolean):void 0},cfg,agentDir:void 0})}catch(err){logVerbose(`telegram: audio preflight transcription failed: ${String(err)}`)}hasAudio&&bodyText===`<media:audio>`&&preflightTranscript&&(bodyText=preflightTranscript),!bodyText&&allMedia.length>0&&(bodyText=hasAudio?preflightTranscript||`<media:audio>`:`<media:image>${allMedia.length>1?` (${allMedia.length} images)`:``}`);let hasAnyMention=(msg.entities??msg.caption_entities??[]).some(ent=>ent.type===`mention`),explicitlyMentioned=botUsername?hasBotMention(msg,botUsername):!1,computedWasMentioned=matchesMentionWithExplicit({text:msg.text??msg.caption??``,mentionRegexes,explicit:{hasAnyMention,isExplicitlyMentioned:explicitlyMentioned,canResolveExplicit:!!botUsername},transcript:preflightTranscript}),wasMentioned=options?.forceWasMentioned===!0?!0:computedWasMentioned;if(isGroup&&commandGate.shouldBlock)return logInboundDrop({log:logVerbose,channel:`telegram`,reason:`control command (unauthorized)`,target:senderId??`unknown`}),null;let botId=primaryCtx.me?.id,replyFromId=msg.reply_to_message?.from?.id,implicitMention=botId!=null&&replyFromId===botId,canDetectMention=!!botUsername||mentionRegexes.length>0,mentionGate=resolveMentionGatingWithBypass({isGroup,requireMention:!!requireMention,canDetectMention,wasMentioned,implicitMention:isGroup&&!!requireMention&&implicitMention,hasAnyMention,allowTextCommands:!0,hasControlCommand:hasControlCommandInMessage,commandAuthorized}),effectiveWasMentioned=mentionGate.effectiveWasMentioned;if(isGroup&&requireMention&&canDetectMention&&mentionGate.shouldSkip)return logger.info({chatId,reason:`no-mention`},`skipping group message`),recordPendingHistoryEntryIfEnabled({historyMap:groupHistories,historyKey:historyKey??``,limit:historyLimit,entry:historyKey?{sender:buildSenderLabel(msg,senderId||chatId),body:rawBody,timestamp:msg.date?msg.date*1e3:void 0,messageId:typeof msg.message_id==`number`?String(msg.message_id):void 0}:null}),null;let ackReaction=resolveAckReaction(cfg,route.agentId,{channel:`telegram`,accountId:account.accountId}),removeAckAfterReply=cfg.messages?.removeAckAfterReply??!1,shouldAckReaction$1=()=>!!(ackReaction&&shouldAckReaction({scope:ackReactionScope,isDirect:!isGroup,isGroup,isMentionableGroup:isGroup,requireMention:!!requireMention,canDetectMention,effectiveWasMentioned,shouldBypassMention:mentionGate.shouldBypassMention})),api=bot.api,reactionApi=typeof api.setMessageReaction==`function`?api.setMessageReaction.bind(api):null,ackReactionPromise=shouldAckReaction$1()&&msg.message_id&&reactionApi?withTelegramApiErrorLogging({operation:`setMessageReaction`,fn:()=>reactionApi(chatId,msg.message_id,[{type:`emoji`,emoji:ackReaction}])}).then(()=>!0,err=>(logVerbose(`telegram react failed for chat ${chatId}: ${String(err)}`),!1)):null,replyTarget=describeReplyTarget(msg),forwardOrigin=normalizeForwardedContext(msg),replySuffix=replyTarget?replyTarget.kind===`quote`?`\n\n[Quoting ${replyTarget.sender}${replyTarget.id?` id:${replyTarget.id}`:``}]\n"${replyTarget.body}"\n[/Quoting]`:`\n\n[Replying to ${replyTarget.sender}${replyTarget.id?` id:${replyTarget.id}`:``}]\n${replyTarget.body}\n[/Replying]`:``,forwardPrefix=forwardOrigin?`[Forwarded from ${forwardOrigin.from}${forwardOrigin.date?` at ${new Date(forwardOrigin.date*1e3).toISOString()}`:``}]\n`:``,groupLabel=isGroup?buildGroupLabel(msg,chatId,resolvedThreadId):void 0,senderName=buildSenderName(msg),conversationLabel=isGroup?groupLabel??`group:${chatId}`:buildSenderLabel(msg,senderId||chatId),storePath=resolveStorePath(cfg.session?.store,{agentId:route.agentId}),envelopeOptions=resolveEnvelopeFormatOptions(cfg),previousTimestamp=readSessionUpdatedAt({storePath,sessionKey}),body=formatInboundEnvelope({channel:`Telegram`,from:conversationLabel,timestamp:msg.date?msg.date*1e3:void 0,body:`${forwardPrefix}${bodyText}${replySuffix}`,chatType:isGroup?`group`:`direct`,sender:{name:senderName,username:senderUsername||void 0,id:senderId||void 0},previousTimestamp,envelope:envelopeOptions}),combinedBody=body;isGroup&&historyKey&&historyLimit>0&&(combinedBody=buildPendingHistoryContextFromMap({historyMap:groupHistories,historyKey,limit:historyLimit,currentMessage:combinedBody,formatEntry:entry=>formatInboundEnvelope({channel:`Telegram`,from:groupLabel??`group:${chatId}`,timestamp:entry.timestamp,body:`${entry.body} [id:${entry.messageId??`unknown`} chat:${chatId}]`,chatType:`group`,senderLabel:entry.sender,envelope:envelopeOptions})}));let skillFilter=firstDefined$2(topicConfig?.skills,groupConfig?.skills),systemPromptParts=[groupConfig?.systemPrompt?.trim()||null,topicConfig?.systemPrompt?.trim()||null].filter(entry=>!!entry),groupSystemPrompt=systemPromptParts.length>0?systemPromptParts.join(`
475
+ `).trim();if(rawBody||=placeholder,!rawBody&&allMedia.length===0)return null;let bodyText=rawBody,hasAudio=allMedia.some(media=>media.contentType?.startsWith(`audio/`)),preflightTranscript;if(isGroup&&requireMention&&hasAudio&&!hasUserText&&mentionRegexes.length>0)try{let{transcribeFirstAudio}=await import(`./audio-preflight-B411b2-y.js`);preflightTranscript=await transcribeFirstAudio({ctx:{MediaPaths:allMedia.length>0?allMedia.map(m=>m.path):void 0,MediaTypes:allMedia.length>0?allMedia.map(m=>m.contentType).filter(Boolean):void 0},cfg,agentDir:void 0})}catch(err){logVerbose(`telegram: audio preflight transcription failed: ${String(err)}`)}hasAudio&&bodyText===`<media:audio>`&&preflightTranscript&&(bodyText=preflightTranscript),!bodyText&&allMedia.length>0&&(bodyText=hasAudio?preflightTranscript||`<media:audio>`:`<media:image>${allMedia.length>1?` (${allMedia.length} images)`:``}`);let hasAnyMention=(msg.entities??msg.caption_entities??[]).some(ent=>ent.type===`mention`),explicitlyMentioned=botUsername?hasBotMention(msg,botUsername):!1,computedWasMentioned=matchesMentionWithExplicit({text:msg.text??msg.caption??``,mentionRegexes,explicit:{hasAnyMention,isExplicitlyMentioned:explicitlyMentioned,canResolveExplicit:!!botUsername},transcript:preflightTranscript}),wasMentioned=options?.forceWasMentioned===!0?!0:computedWasMentioned;if(isGroup&&commandGate.shouldBlock)return logInboundDrop({log:logVerbose,channel:`telegram`,reason:`control command (unauthorized)`,target:senderId??`unknown`}),null;let botId=primaryCtx.me?.id,replyFromId=msg.reply_to_message?.from?.id,implicitMention=botId!=null&&replyFromId===botId,canDetectMention=!!botUsername||mentionRegexes.length>0,mentionGate=resolveMentionGatingWithBypass({isGroup,requireMention:!!requireMention,canDetectMention,wasMentioned,implicitMention:isGroup&&!!requireMention&&implicitMention,hasAnyMention,allowTextCommands:!0,hasControlCommand:hasControlCommandInMessage,commandAuthorized}),effectiveWasMentioned=mentionGate.effectiveWasMentioned;if(isGroup&&requireMention&&canDetectMention&&mentionGate.shouldSkip)return logger.info({chatId,reason:`no-mention`},`skipping group message`),recordPendingHistoryEntryIfEnabled({historyMap:groupHistories,historyKey:historyKey??``,limit:historyLimit,entry:historyKey?{sender:buildSenderLabel(msg,senderId||chatId),body:rawBody,timestamp:msg.date?msg.date*1e3:void 0,messageId:typeof msg.message_id==`number`?String(msg.message_id):void 0}:null}),null;let ackReaction=resolveAckReaction(cfg,route.agentId,{channel:`telegram`,accountId:account.accountId}),removeAckAfterReply=cfg.messages?.removeAckAfterReply??!1,shouldAckReaction$1=()=>!!(ackReaction&&shouldAckReaction({scope:ackReactionScope,isDirect:!isGroup,isGroup,isMentionableGroup:isGroup,requireMention:!!requireMention,canDetectMention,effectiveWasMentioned,shouldBypassMention:mentionGate.shouldBypassMention})),api=bot.api,reactionApi=typeof api.setMessageReaction==`function`?api.setMessageReaction.bind(api):null,ackReactionPromise=shouldAckReaction$1()&&msg.message_id&&reactionApi?withTelegramApiErrorLogging({operation:`setMessageReaction`,fn:()=>reactionApi(chatId,msg.message_id,[{type:`emoji`,emoji:ackReaction}])}).then(()=>!0,err=>(logVerbose(`telegram react failed for chat ${chatId}: ${String(err)}`),!1)):null,replyTarget=describeReplyTarget(msg),forwardOrigin=normalizeForwardedContext(msg),replySuffix=replyTarget?replyTarget.kind===`quote`?`\n\n[Quoting ${replyTarget.sender}${replyTarget.id?` id:${replyTarget.id}`:``}]\n"${replyTarget.body}"\n[/Quoting]`:`\n\n[Replying to ${replyTarget.sender}${replyTarget.id?` id:${replyTarget.id}`:``}]\n${replyTarget.body}\n[/Replying]`:``,forwardPrefix=forwardOrigin?`[Forwarded from ${forwardOrigin.from}${forwardOrigin.date?` at ${new Date(forwardOrigin.date*1e3).toISOString()}`:``}]\n`:``,groupLabel=isGroup?buildGroupLabel(msg,chatId,resolvedThreadId):void 0,senderName=buildSenderName(msg),conversationLabel=isGroup?groupLabel??`group:${chatId}`:buildSenderLabel(msg,senderId||chatId),storePath=resolveStorePath(cfg.session?.store,{agentId:route.agentId}),envelopeOptions=resolveEnvelopeFormatOptions(cfg),previousTimestamp=readSessionUpdatedAt({storePath,sessionKey}),body=formatInboundEnvelope({channel:`Telegram`,from:conversationLabel,timestamp:msg.date?msg.date*1e3:void 0,body:`${forwardPrefix}${bodyText}${replySuffix}`,chatType:isGroup?`group`:`direct`,sender:{name:senderName,username:senderUsername||void 0,id:senderId||void 0},previousTimestamp,envelope:envelopeOptions}),combinedBody=body;isGroup&&historyKey&&historyLimit>0&&(combinedBody=buildPendingHistoryContextFromMap({historyMap:groupHistories,historyKey,limit:historyLimit,currentMessage:combinedBody,formatEntry:entry=>formatInboundEnvelope({channel:`Telegram`,from:groupLabel??`group:${chatId}`,timestamp:entry.timestamp,body:`${entry.body} [id:${entry.messageId??`unknown`} chat:${chatId}]`,chatType:`group`,senderLabel:entry.sender,envelope:envelopeOptions})}));let skillFilter=firstDefined$2(topicConfig?.skills,groupConfig?.skills),systemPromptParts=[groupConfig?.systemPrompt?.trim()||null,topicConfig?.systemPrompt?.trim()||null].filter(entry=>!!entry),groupSystemPrompt=systemPromptParts.length>0?systemPromptParts.join(`
476
476
 
477
477
  `):void 0,commandBody=normalizeCommandBody(rawBody,{botUsername}),inboundHistory=isGroup&&historyKey&&historyLimit>0?(groupHistories.get(historyKey)??[]).map(entry=>({sender:entry.sender,body:entry.body,timestamp:entry.timestamp})):void 0,ctxPayload=finalizeInboundContext({Body:combinedBody,BodyForAgent:bodyText,InboundHistory:inboundHistory,RawBody:rawBody,CommandBody:commandBody,From:isGroup?buildTelegramGroupFrom(chatId,resolvedThreadId):`telegram:${chatId}`,To:`telegram:${chatId}`,SessionKey:sessionKey,AccountId:route.accountId,ChatType:isGroup?`group`:`direct`,ConversationLabel:conversationLabel,GroupSubject:isGroup?msg.chat.title??void 0:void 0,GroupSystemPrompt:isGroup?groupSystemPrompt:void 0,SenderName:senderName,SenderId:senderId||void 0,SenderUsername:senderUsername||void 0,Provider:`telegram`,Surface:`telegram`,MessageSid:options?.messageIdOverride??String(msg.message_id),ReplyToId:replyTarget?.id,ReplyToBody:replyTarget?.body,ReplyToSender:replyTarget?.sender,ReplyToIsQuote:replyTarget?.kind===`quote`?!0:void 0,ForwardedFrom:forwardOrigin?.from,ForwardedFromType:forwardOrigin?.fromType,ForwardedFromId:forwardOrigin?.fromId,ForwardedFromUsername:forwardOrigin?.fromUsername,ForwardedFromTitle:forwardOrigin?.fromTitle,ForwardedFromSignature:forwardOrigin?.fromSignature,ForwardedFromChatType:forwardOrigin?.fromChatType,ForwardedFromMessageId:forwardOrigin?.fromMessageId,ForwardedDate:forwardOrigin?.date?forwardOrigin.date*1e3:void 0,Timestamp:msg.date?msg.date*1e3:void 0,WasMentioned:isGroup?effectiveWasMentioned:void 0,MediaPath:stickerCacheHit?void 0:allMedia[0]?.path,MediaType:stickerCacheHit?void 0:allMedia[0]?.contentType,MediaUrl:stickerCacheHit?void 0:allMedia[0]?.path,MediaPaths:stickerCacheHit?void 0:allMedia.length>0?allMedia.map(m=>m.path):void 0,MediaUrls:stickerCacheHit?void 0:allMedia.length>0?allMedia.map(m=>m.path):void 0,MediaTypes:stickerCacheHit?void 0:allMedia.length>0?allMedia.map(m=>m.contentType).filter(Boolean):void 0,Sticker:allMedia[0]?.stickerMetadata,...locationData?toLocationContext(locationData):void 0,CommandAuthorized:commandAuthorized,MessageThreadId:threadSpec.id,IsForum:isForum,OriginatingChannel:`telegram`,OriginatingTo:`telegram:${chatId}`});if(await recordInboundSession({storePath,sessionKey:ctxPayload.SessionKey??sessionKey,ctx:ctxPayload,updateLastRoute:isGroup?void 0:{sessionKey:route.mainSessionKey,channel:`telegram`,to:String(chatId),accountId:route.accountId,threadId:dmThreadId==null?void 0:String(dmThreadId)},onRecordError:err=>{logVerbose(`telegram: failed updating session meta: ${String(err)}`)}}),replyTarget&&shouldLogVerbose()){let preview=replyTarget.body.replace(/\s+/g,` `).slice(0,120);logVerbose(`telegram reply-context: replyToId=${replyTarget.id} replyToSender=${replyTarget.sender} replyToBody="${preview}"`)}if(forwardOrigin&&shouldLogVerbose()&&logVerbose(`telegram forward-context: forwardedFrom="${forwardOrigin.from}" type=${forwardOrigin.fromType}`),shouldLogVerbose()){let preview=body.slice(0,200).replace(/\n/g,`\\n`),mediaInfo=allMedia.length>1?` mediaCount=${allMedia.length}`:``,topicInfo=resolvedThreadId==null?``:` topic=${resolvedThreadId}`;logVerbose(`telegram inbound: chatId=${chatId} from=${ctxPayload.From} len=${body.length}${mediaInfo}${topicInfo} preview="${preview}"`)}return{ctxPayload,primaryCtx,msg,chatId,isGroup,resolvedThreadId,threadSpec,replyThreadId,isForum,historyKey,historyLimit,groupHistories,route,skillFilter,sendTyping,sendRecordVoice,ackReactionPromise,reactionApi,removeAckAfterReply,accountId:account.accountId}};function findSafeSentenceBreakIndex(text,fenceSpans,minChars){let matches=text.matchAll(/[.!?](?=\s|$)/g),sentenceIdx=-1;for(let match of matches){let at=match.index??-1;if(at<minChars)continue;let candidate=at+1;isSafeFenceBreak(fenceSpans,candidate)&&(sentenceIdx=candidate)}return sentenceIdx>=minChars?sentenceIdx:-1}function findSafeParagraphBreakIndex(params){let{text,fenceSpans,minChars,reverse}=params,paragraphIdx=reverse?text.lastIndexOf(`
478
478
 
@@ -491,7 +491,7 @@ Critical rules from AGENTS.md:
491
491
  `)?fenceSplit.reopenFenceLine:`${fenceSplit.reopenFenceLine}\n`}${nextBuffer}`}if(emit(rawChunk),fenceSplit)this.#buffer=nextBuffer;else{let nextStart=breakIdx<this.#buffer.length&&/\s/.test(this.#buffer[breakIdx])?breakIdx+1:breakIdx;this.#buffer=stripLeadingNewlines(this.#buffer.slice(nextStart))}return!0}#pickSoftBreakIndex(buffer,minCharsOverride){let minChars=Math.max(1,Math.floor(minCharsOverride??this.#chunking.minChars));if(buffer.length<minChars)return{index:-1};let fenceSpans=parseFenceSpans(buffer),preference=this.#chunking.breakPreference??`paragraph`;if(preference===`paragraph`){let paragraphIdx=findSafeParagraphBreakIndex({text:buffer,fenceSpans,minChars,reverse:!1});if(paragraphIdx!==-1)return{index:paragraphIdx}}if(preference===`paragraph`||preference===`newline`){let newlineIdx=findSafeNewlineBreakIndex({text:buffer,fenceSpans,minChars,reverse:!1});if(newlineIdx!==-1)return{index:newlineIdx}}if(preference!==`newline`){let sentenceIdx=findSafeSentenceBreakIndex(buffer,fenceSpans,minChars);if(sentenceIdx!==-1)return{index:sentenceIdx}}return{index:-1}}#pickBreakIndex(buffer,minCharsOverride){let minChars=Math.max(1,Math.floor(minCharsOverride??this.#chunking.minChars)),maxChars=Math.max(minChars,Math.floor(this.#chunking.maxChars));if(buffer.length<minChars)return{index:-1};let window=buffer.slice(0,Math.min(maxChars,buffer.length)),fenceSpans=parseFenceSpans(buffer),preference=this.#chunking.breakPreference??`paragraph`;if(preference===`paragraph`){let paragraphIdx=findSafeParagraphBreakIndex({text:window,fenceSpans,minChars,reverse:!0});if(paragraphIdx!==-1)return{index:paragraphIdx}}if(preference===`paragraph`||preference===`newline`){let newlineIdx=findSafeNewlineBreakIndex({text:window,fenceSpans,minChars,reverse:!0});if(newlineIdx!==-1)return{index:newlineIdx}}if(preference!==`newline`){let sentenceIdx=findSafeSentenceBreakIndex(window,fenceSpans,minChars);if(sentenceIdx!==-1)return{index:sentenceIdx}}if(preference===`newline`&&buffer.length<maxChars)return{index:-1};for(let i=window.length-1;i>=minChars;i--)if(/\s/.test(window[i])&&isSafeFenceBreak(fenceSpans,i))return{index:i};if(buffer.length>=maxChars){if(isSafeFenceBreak(fenceSpans,maxChars))return{index:maxChars};let fence=findFenceSpanAt(fenceSpans,maxChars);return fence?{index:maxChars,fenceSplit:{closeFenceLine:`${fence.indent}${fence.marker}`,reopenFenceLine:fence.openLine}}:{index:maxChars}}return{index:-1}}};function stripLeadingNewlines(value){let i=0;for(;i<value.length&&value[i]===`
492
492
  `;)i++;return i>0?value.slice(i):value}function findNextParagraphBreak(buffer,fenceSpans,startIndex=0){if(startIndex<0)return null;let re=/\n[\t ]*\n+/g;re.lastIndex=startIndex;let match;for(;(match=re.exec(buffer))!==null;){let index=match.index??-1;if(!(index<0)&&isSafeFenceBreak(fenceSpans,index))return{index,length:match[0].length}}return null}function resolveTelegramDraftStreamingChunking(cfg,accountId){let providerChunkLimit=getChannelDock(`telegram`)?.outbound?.textChunkLimit,textLimit=resolveTextChunkLimit(cfg,`telegram`,accountId,{fallbackLimit:providerChunkLimit}),normalizedAccountId=normalizeAccountId$2(accountId),draftCfg=cfg?.channels?.telegram?.accounts?.[normalizedAccountId]?.draftChunk??cfg?.channels?.telegram?.draftChunk,maxRequested=Math.max(1,Math.floor(draftCfg?.maxChars??800)),maxChars=Math.max(1,Math.min(maxRequested,textLimit)),minRequested=Math.max(1,Math.floor(draftCfg?.minChars??200));return{minChars:Math.min(minRequested,maxChars),maxChars,breakPreference:draftCfg?.breakPreference===`newline`||draftCfg?.breakPreference===`sentence`?draftCfg.breakPreference:`paragraph`}}const TELEGRAM_STREAM_MAX_CHARS=4096;function createTelegramDraftStream(params){let maxChars=Math.min(params.maxChars??TELEGRAM_STREAM_MAX_CHARS,TELEGRAM_STREAM_MAX_CHARS),throttleMs=Math.max(250,params.throttleMs??1e3),minInitialChars=params.minInitialChars,chatId=params.chatId,threadParams=buildTelegramThreadParams(params.thread),replyParams=params.replyToMessageId==null?threadParams:{...threadParams,reply_to_message_id:params.replyToMessageId},streamMessageId,lastSentText=``,stopped=!1,isFinal=!1,loop=createDraftStreamLoop({throttleMs,isStopped:()=>stopped,sendOrEditStreamMessage:async text=>{if(stopped&&!isFinal)return!1;let trimmed=text.trimEnd();if(!trimmed)return!1;if(trimmed.length>maxChars)return stopped=!0,params.warn?.(`telegram stream preview stopped (text length ${trimmed.length} > ${maxChars})`),!1;if(trimmed===lastSentText)return!0;if(typeof streamMessageId!=`number`&&minInitialChars!=null&&!isFinal&&trimmed.length<minInitialChars)return!1;lastSentText=trimmed;try{if(typeof streamMessageId==`number`)return await params.api.editMessageText(chatId,streamMessageId,trimmed),!0;let sentMessageId=(await params.api.sendMessage(chatId,trimmed,replyParams))?.message_id;return typeof sentMessageId!=`number`||!Number.isFinite(sentMessageId)?(stopped=!0,params.warn?.(`telegram stream preview stopped (missing message id from sendMessage)`),!1):(streamMessageId=Math.trunc(sentMessageId),!0)}catch(err){return stopped=!0,params.warn?.(`telegram stream preview failed: ${err instanceof Error?err.message:String(err)}`),!1}}});return params.log?.(`telegram stream preview ready (maxChars=${maxChars}, throttleMs=${throttleMs})`),{update:text=>{stopped||isFinal||loop.update(text)},flush:loop.flush,messageId:()=>streamMessageId,clear:async()=>{stopped=!0,loop.stop(),await loop.waitForInFlight();let messageId=streamMessageId;if(streamMessageId=void 0,typeof messageId==`number`)try{await params.api.deleteMessage(chatId,messageId)}catch(err){params.warn?.(`telegram stream preview cleanup failed: ${err instanceof Error?err.message:String(err)}`)}},stop:async()=>{isFinal=!0,await loop.flush()},forceNewMessage:()=>{streamMessageId=void 0,lastSentText=``,loop.resetPending()}}}async function resolveStickerVisionSupport(cfg,agentId){try{let catalog=await loadModelCatalog({config:cfg}),defaultModel=resolveDefaultModelForAgent({cfg,agentId}),entry=findModelInCatalog(catalog,defaultModel.provider,defaultModel.model);return entry?modelSupportsVision(entry):!1}catch{return!1}}const dispatchTelegramMessage=async({context,bot,cfg,runtime,replyToMode,streamMode,textLimit,telegramCfg,opts})=>{let{ctxPayload,msg,chatId,isGroup,threadSpec,historyKey,historyLimit,groupHistories,route,skillFilter,sendTyping,sendRecordVoice,ackReactionPromise,reactionApi,removeAckAfterReply}=context,draftMaxChars=Math.min(textLimit,4096),accountBlockStreamingEnabled=typeof telegramCfg.blockStreaming==`boolean`?telegramCfg.blockStreaming:cfg.agents?.defaults?.blockStreamingDefault===`on`,canStreamDraft=streamMode!==`off`&&!accountBlockStreamingEnabled,draftReplyToMessageId=replyToMode!==`off`&&typeof msg.message_id==`number`?msg.message_id:void 0,draftStream=canStreamDraft?createTelegramDraftStream({api:bot.api,chatId,maxChars:draftMaxChars,thread:threadSpec,replyToMessageId:draftReplyToMessageId,minInitialChars:30,log:logVerbose,warn:logVerbose}):void 0,draftChunking=draftStream&&streamMode===`block`?resolveTelegramDraftStreamingChunking(cfg,route.accountId):void 0,shouldSplitPreviewMessages=streamMode===`block`,draftChunker=draftChunking?new EmbeddedBlockChunker(draftChunking):void 0,mediaLocalRoots=getAgentScopedMediaLocalRoots(cfg,route.agentId),lastPartialText=``,draftText=``,hasStreamedMessage=!1,updateDraftFromPartial=text=>{if(!draftStream||!text||text===lastPartialText)return;if(hasStreamedMessage=!0,streamMode===`partial`){if(lastPartialText&&lastPartialText.startsWith(text)&&text.length<lastPartialText.length)return;lastPartialText=text,draftStream.update(text);return}let delta=text;if(text.startsWith(lastPartialText)?delta=text.slice(lastPartialText.length):(draftChunker?.reset(),draftText=``),lastPartialText=text,delta){if(!draftChunker){draftText=text,draftStream.update(draftText);return}draftChunker.append(delta),draftChunker.drain({force:!1,emit:chunk=>{draftText+=chunk,draftStream.update(draftText)}})}},flushDraft=async()=>{draftStream&&(draftChunker?.hasBuffered()&&(draftChunker.drain({force:!0,emit:chunk=>{draftText+=chunk}}),draftChunker.reset(),draftText&&draftStream.update(draftText)),await draftStream.flush())},disableBlockStreaming=typeof telegramCfg.blockStreaming==`boolean`?!telegramCfg.blockStreaming:draftStream||streamMode===`off`?!0:void 0,{onModelSelected,...prefixOptions}=createReplyPrefixOptions({cfg,agentId:route.agentId,channel:`telegram`,accountId:route.accountId}),tableMode=resolveMarkdownTableMode({cfg,channel:`telegram`,accountId:route.accountId}),chunkMode=resolveChunkMode(cfg,`telegram`,route.accountId),sticker=ctxPayload.Sticker;if(sticker?.fileId&&sticker.fileUniqueId&&ctxPayload.MediaPath){let agentDir=resolveAgentDir(cfg,route.agentId),stickerSupportsVision=await resolveStickerVisionSupport(cfg,route.agentId),description=sticker.cachedDescription??null;if(description||=await describeStickerImage({imagePath:ctxPayload.MediaPath,cfg,agentDir,agentId:route.agentId}),description){let stickerContext=[sticker.emoji,sticker.setName?`from "${sticker.setName}"`:null].filter(Boolean).join(` `),formattedDesc=`[Sticker${stickerContext?` ${stickerContext}`:``}] ${description}`;sticker.cachedDescription=description,stickerSupportsVision||(ctxPayload.Body=formattedDesc,ctxPayload.BodyForAgent=formattedDesc,ctxPayload.MediaPath=void 0,ctxPayload.MediaType=void 0,ctxPayload.MediaUrl=void 0,ctxPayload.MediaPaths=void 0,ctxPayload.MediaUrls=void 0,ctxPayload.MediaTypes=void 0),sticker.fileId?(cacheSticker({fileId:sticker.fileId,fileUniqueId:sticker.fileUniqueId,emoji:sticker.emoji,setName:sticker.setName,description,cachedAt:new Date().toISOString(),receivedFrom:ctxPayload.From}),logVerbose(`telegram: cached sticker description for ${sticker.fileUniqueId}`)):logVerbose(`telegram: skipped sticker cache (missing fileId)`)}}let replyQuoteText=ctxPayload.ReplyToIsQuote&&ctxPayload.ReplyToBody&&ctxPayload.ReplyToBody.trim()||void 0,deliveryState={delivered:!1,skippedNonSilent:0},finalizedViaPreviewMessage=!1,clearGroupHistory=()=>{isGroup&&historyKey&&clearHistoryEntriesIfEnabled({historyMap:groupHistories,historyKey,limit:historyLimit})},deliveryBaseOptions={chatId:String(chatId),token:opts.token,runtime,bot,mediaLocalRoots,replyToMode,textLimit,thread:threadSpec,tableMode,chunkMode,linkPreview:telegramCfg.linkPreview,replyQuoteText},queuedFinal=!1;try{({queuedFinal}=await dispatchReplyWithBufferedBlockDispatcher({ctx:ctxPayload,cfg,dispatcherOptions:{...prefixOptions,deliver:async(payload,info)=>{if(info.kind===`final`){await flushDraft();let hasMedia=!!payload.mediaUrl||(payload.mediaUrls?.length??0)>0,previewMessageId=draftStream?.messageId(),finalText=payload.text,currentPreviewText=streamMode===`block`?draftText:lastPartialText,previewButtons=payload.channelData?.telegram?.buttons,draftStoppedForPreviewEdit=!1;if(!finalizedViaPreviewMessage&&!hasMedia&&typeof finalText==`string`&&finalText.length>0&&typeof previewMessageId==`number`&&finalText.length<=draftMaxChars&&!payload.isError){if(await draftStream?.stop(),draftStoppedForPreviewEdit=!0,currentPreviewText&&currentPreviewText.startsWith(finalText)&&finalText.length<currentPreviewText.length)return;try{await editMessageTelegram(chatId,previewMessageId,finalText,{api:bot.api,cfg,accountId:route.accountId,linkPreview:telegramCfg.linkPreview,buttons:previewButtons}),finalizedViaPreviewMessage=!0,deliveryState.delivered=!0;return}catch(err){logVerbose(`telegram: preview final edit failed; falling back to standard send (${String(err)})`)}}!hasMedia&&!payload.isError&&typeof finalText==`string`&&finalText.length>draftMaxChars&&logVerbose(`telegram: preview final too long for edit (${finalText.length} > ${draftMaxChars}); falling back to standard send`),draftStoppedForPreviewEdit||await draftStream?.stop();let messageIdAfterStop=draftStream?.messageId();if(!finalizedViaPreviewMessage&&typeof messageIdAfterStop==`number`&&typeof finalText==`string`&&finalText.length>0&&finalText.length<=draftMaxChars&&!hasMedia&&!payload.isError)try{await editMessageTelegram(chatId,messageIdAfterStop,finalText,{api:bot.api,cfg,accountId:route.accountId,linkPreview:telegramCfg.linkPreview,buttons:previewButtons}),finalizedViaPreviewMessage=!0,deliveryState.delivered=!0;return}catch(err){logVerbose(`telegram: post-stop preview edit failed; falling back to standard send (${String(err)})`)}}(await deliverReplies({...deliveryBaseOptions,replies:[payload],onVoiceRecording:sendRecordVoice})).delivered&&(deliveryState.delivered=!0)},onSkip:(_payload,info)=>{info.reason!==`silent`&&(deliveryState.skippedNonSilent+=1)},onError:(err,info)=>{runtime.error?.(danger(`telegram ${info.kind} reply failed: ${String(err)}`))},onReplyStart:createTypingCallbacks({start:sendTyping,onStartError:err=>{logTypingFailure({log:logVerbose,channel:`telegram`,target:String(chatId),error:err})}}).onReplyStart},replyOptions:{skillFilter,disableBlockStreaming,onPartialReply:draftStream?payload=>updateDraftFromPartial(payload.text):void 0,onAssistantMessageStart:draftStream?()=>{logVerbose(`telegram: onAssistantMessageStart called, hasStreamedMessage=${hasStreamedMessage}`),shouldSplitPreviewMessages&&hasStreamedMessage&&(logVerbose(`telegram: calling forceNewMessage()`),draftStream.forceNewMessage()),lastPartialText=``,draftText=``,draftChunker?.reset()}:void 0,onReasoningEnd:draftStream?()=>{shouldSplitPreviewMessages&&hasStreamedMessage&&draftStream.forceNewMessage(),lastPartialText=``,draftText=``,draftChunker?.reset()}:void 0,onModelSelected}}))}finally{await draftStream?.stop(),finalizedViaPreviewMessage||await draftStream?.clear()}let sentFallback=!1;if(!deliveryState.delivered&&deliveryState.skippedNonSilent>0&&(sentFallback=(await deliverReplies({replies:[{text:`No response generated. Please try again.`}],...deliveryBaseOptions})).delivered),!(queuedFinal||sentFallback)){clearGroupHistory();return}removeAckReactionAfterReply({removeAfterReply:removeAckAfterReply,ackReactionPromise,ackReactionValue:ackReactionPromise?`ack`:null,remove:()=>reactionApi?.(chatId,msg.message_id??0,[])??Promise.resolve(),onError:err=>{msg.message_id&&logAckFailure({log:logVerbose,channel:`telegram`,target:`${chatId}/${msg.message_id}`,error:err})}}),clearGroupHistory()},createTelegramMessageProcessor=deps=>{let{bot,cfg,account,telegramCfg,historyLimit,groupHistories,dmPolicy,allowFrom,groupAllowFrom,ackReactionScope,logger,resolveGroupActivation,resolveGroupRequireMention,resolveTelegramGroupConfig,runtime,replyToMode,streamMode,textLimit,opts}=deps;return async(primaryCtx,allMedia,storeAllowFrom,options)=>{let context=await buildTelegramMessageContext({primaryCtx,allMedia,storeAllowFrom,options,bot,cfg,account,historyLimit,groupHistories,dmPolicy,allowFrom,groupAllowFrom,ackReactionScope,logger,resolveGroupActivation,resolveGroupRequireMention,resolveTelegramGroupConfig});context&&await dispatchTelegramMessage({context,bot,cfg,runtime,replyToMode,streamMode,textLimit,telegramCfg,opts})}};function buildPluginTelegramMenuCommands(params){let{specs,existingCommands}=params,commands=[],issues=[],pluginCommandNames=new Set;for(let spec of specs){let normalized=normalizeTelegramCommandName(spec.name);if(!normalized||!TELEGRAM_COMMAND_NAME_PATTERN.test(normalized)){issues.push(`Plugin command "/${spec.name}" is invalid for Telegram (use a-z, 0-9, underscore; max 32 chars).`);continue}let description=spec.description.trim();if(!description){issues.push(`Plugin command "/${normalized}" is missing a description.`);continue}if(existingCommands.has(normalized)){pluginCommandNames.has(normalized)?issues.push(`Plugin command "/${normalized}" is duplicated.`):issues.push(`Plugin command "/${normalized}" conflicts with an existing Telegram command.`);continue}pluginCommandNames.add(normalized),existingCommands.add(normalized),commands.push({command:normalized,description})}return{commands,issues}}function buildCappedTelegramMenuCommands(params){let{allCommands}=params,maxCommands=params.maxCommands??100,totalCommands=allCommands.length,overflowCount=Math.max(0,totalCommands-maxCommands);return{commandsToRegister:allCommands.slice(0,maxCommands),totalCommands,maxCommands,overflowCount}}function syncTelegramMenuCommands(params){let{bot,runtime,commandsToRegister}=params;(async()=>{typeof bot.api.deleteMyCommands==`function`&&await withTelegramApiErrorLogging({operation:`deleteMyCommands`,runtime,fn:()=>bot.api.deleteMyCommands()}).catch(()=>{}),commandsToRegister.length!==0&&await withTelegramApiErrorLogging({operation:`setMyCommands`,runtime,fn:()=>bot.api.setMyCommands(commandsToRegister)})})().catch(err=>{runtime.error?.(`Telegram command sync failed: ${String(err)}`)})}async function resolveTelegramCommandAuth(params){let{msg,bot,cfg,accountId,telegramCfg,allowFrom,groupAllowFrom,useAccessGroups,resolveGroupPolicy,resolveTelegramGroupConfig,requireAuth}=params,chatId=msg.chat.id,isGroup=msg.chat.type===`group`||msg.chat.type===`supergroup`,messageThreadId=msg.message_thread_id,isForum=msg.chat.is_forum===!0,{resolvedThreadId,storeAllowFrom,groupConfig,topicConfig,effectiveGroupAllow,hasGroupAllowOverride}=await resolveTelegramGroupAllowFromContext({chatId,accountId,isForum,messageThreadId,groupAllowFrom,resolveTelegramGroupConfig}),senderId=msg.from?.id?String(msg.from.id):``,senderUsername=msg.from?.username??``,sendAuthMessage=async text=>(await withTelegramApiErrorLogging({operation:`sendMessage`,fn:()=>bot.api.sendMessage(chatId,text)}),null),rejectNotAuthorized=async()=>await sendAuthMessage(`You are not authorized to use this command.`),baseAccess=evaluateTelegramGroupBaseAccess({isGroup,groupConfig,topicConfig,hasGroupAllowOverride,effectiveGroupAllow,senderId,senderUsername,enforceAllowOverride:requireAuth,requireSenderForAllowOverride:!0});if(!baseAccess.allowed)return baseAccess.reason===`group-disabled`?await sendAuthMessage(`This group is disabled.`):baseAccess.reason===`topic-disabled`?await sendAuthMessage(`This topic is disabled.`):await rejectNotAuthorized();let policyAccess=evaluateTelegramGroupPolicyAccess({isGroup,chatId,cfg,telegramCfg,topicConfig,groupConfig,effectiveGroupAllow,senderId,senderUsername,resolveGroupPolicy,enforcePolicy:useAccessGroups,useTopicAndGroupOverrides:!1,enforceAllowlistAuthorization:requireAuth,allowEmptyAllowlistEntries:!0,requireSenderForAllowlistAuthorization:!0,checkChatAllowlist:useAccessGroups});if(!policyAccess.allowed){if(policyAccess.reason===`group-policy-disabled`)return await sendAuthMessage(`Telegram group commands are disabled.`);if(policyAccess.reason===`group-policy-allowlist-no-sender`||policyAccess.reason===`group-policy-allowlist-unauthorized`)return await rejectNotAuthorized();if(policyAccess.reason===`group-chat-not-allowed`)return await sendAuthMessage(`This group is not allowed.`)}let dmAllow=normalizeAllowFromWithStore$1({allowFrom,storeAllowFrom}),senderAllowed=isSenderAllowed$1({allow:dmAllow,senderId,senderUsername}),commandAuthorized=resolveCommandAuthorizedFromAuthorizers({useAccessGroups,authorizers:[{configured:dmAllow.hasEntries,allowed:senderAllowed}],modeWhenAccessGroupsOff:`configured`});return requireAuth&&!commandAuthorized?await rejectNotAuthorized():{chatId,isGroup,isForum,resolvedThreadId,senderId,senderUsername,groupConfig,topicConfig,commandAuthorized}}const registerTelegramNativeCommands=({bot,cfg,runtime,accountId,telegramCfg,allowFrom,groupAllowFrom,replyToMode,textLimit,useAccessGroups,nativeEnabled,nativeSkillsEnabled,nativeDisabledExplicit,resolveGroupPolicy,resolveTelegramGroupConfig,shouldSkipUpdate,opts})=>{let boundRoute=nativeEnabled&&nativeSkillsEnabled?resolveAgentRoute({cfg,channel:`telegram`,accountId}):null,boundAgentIds=boundRoute?[boundRoute.agentId]:null,skillCommands=nativeEnabled&&nativeSkillsEnabled?listSkillCommandsForAgents(boundAgentIds?{cfg,agentIds:boundAgentIds}:{cfg}):[],nativeCommands=nativeEnabled?listNativeCommandSpecsForConfig(cfg,{skillCommands,provider:`telegram`}):[],reservedCommands=new Set(listNativeCommandSpecs().map(command=>normalizeTelegramCommandName(command.name)));for(let command of skillCommands)reservedCommands.add(command.name.toLowerCase());let customResolution=resolveTelegramCustomCommands({commands:telegramCfg.customCommands,reservedCommands});for(let issue of customResolution.issues)runtime.error?.(danger(issue.message));let customCommands=customResolution.commands,pluginCatalog=buildPluginTelegramMenuCommands({specs:getPluginCommandSpecs(),existingCommands:new Set([...nativeCommands.map(command=>normalizeTelegramCommandName(command.name)),...customCommands.map(command=>command.command)].map(command=>command.toLowerCase()))});for(let issue of pluginCatalog.issues)runtime.error?.(danger(issue));let{commandsToRegister,totalCommands,maxCommands,overflowCount}=buildCappedTelegramMenuCommands({allCommands:[...nativeCommands.map(command=>{let normalized=normalizeTelegramCommandName(command.name);return TELEGRAM_COMMAND_NAME_PATTERN.test(normalized)?{command:normalized,description:command.description}:(runtime.error?.(danger(`Native command "${command.name}" is invalid for Telegram (resolved to "${normalized}"). Skipping.`)),null)}).filter(cmd=>cmd!==null),...nativeEnabled?pluginCatalog.commands:[],...customCommands]});overflowCount>0&&runtime.log?.(`Telegram limits bots to ${maxCommands} commands. ${totalCommands} configured; registering first ${maxCommands}. Use channels.telegram.commands.native: false to disable, or reduce plugin/skill/custom commands.`),syncTelegramMenuCommands({bot,runtime,commandsToRegister});let resolveCommandRuntimeContext=params=>{let{msg,isGroup,isForum,resolvedThreadId}=params,chatId=msg.chat.id,messageThreadId=msg.message_thread_id,threadSpec=resolveTelegramThreadSpec({isGroup,isForum,messageThreadId}),parentPeer=buildTelegramParentPeer({isGroup,resolvedThreadId,chatId}),route=resolveAgentRoute({cfg,channel:`telegram`,accountId,peer:{kind:isGroup?`group`:`direct`,id:isGroup?buildTelegramGroupPeerId(chatId,resolvedThreadId):String(chatId)},parentPeer});return{chatId,threadSpec,route,mediaLocalRoots:getAgentScopedMediaLocalRoots(cfg,route.agentId),tableMode:resolveMarkdownTableMode({cfg,channel:`telegram`,accountId:route.accountId}),chunkMode:resolveChunkMode(cfg,`telegram`,route.accountId)}},buildCommandDeliveryBaseOptions=params=>({chatId:String(params.chatId),token:opts.token,runtime,bot,mediaLocalRoots:params.mediaLocalRoots,replyToMode,textLimit,thread:params.threadSpec,tableMode:params.tableMode,chunkMode:params.chunkMode,linkPreview:telegramCfg.linkPreview});if(commandsToRegister.length>0||pluginCatalog.commands.length>0)if(typeof bot.command!=`function`)logVerbose(`telegram: bot.command unavailable; skipping native handlers`);else{for(let command of nativeCommands){let normalizedCommandName=normalizeTelegramCommandName(command.name);bot.command(normalizedCommandName,async ctx=>{let msg=ctx.message;if(!msg||shouldSkipUpdate(ctx))return;let auth=await resolveTelegramCommandAuth({msg,bot,cfg,accountId,telegramCfg,allowFrom,groupAllowFrom,useAccessGroups,resolveGroupPolicy,resolveTelegramGroupConfig,requireAuth:!0});if(!auth)return;let{chatId,isGroup,isForum,resolvedThreadId,senderId,senderUsername,groupConfig,topicConfig,commandAuthorized}=auth,{threadSpec,route,mediaLocalRoots,tableMode,chunkMode}=resolveCommandRuntimeContext({msg,isGroup,isForum,resolvedThreadId}),deliveryBaseOptions=buildCommandDeliveryBaseOptions({chatId,mediaLocalRoots,threadSpec,tableMode,chunkMode}),threadParams=buildTelegramThreadParams(threadSpec)??{},commandDefinition=findCommandByNativeName(command.name,`telegram`),rawText=ctx.match?.trim()??``,commandArgs=commandDefinition?parseCommandArgs(commandDefinition,rawText):rawText?{raw:rawText}:void 0,prompt=commandDefinition?buildCommandTextFromArgs(commandDefinition,commandArgs):rawText?`/${command.name} ${rawText}`:`/${command.name}`,menu=commandDefinition?resolveCommandArgMenu({command:commandDefinition,args:commandArgs,cfg}):null;if(menu&&commandDefinition){let title=menu.title??`Choose ${menu.arg.description||menu.arg.name} for /${commandDefinition.nativeName??commandDefinition.key}.`,rows=[];for(let i=0;i<menu.choices.length;i+=2){let slice=menu.choices.slice(i,i+2);rows.push(slice.map(choice=>{let args={values:{[menu.arg.name]:choice.value}};return{text:choice.label,callback_data:buildCommandTextFromArgs(commandDefinition,args)}}))}let replyMarkup=buildInlineKeyboard(rows);await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,fn:()=>bot.api.sendMessage(chatId,title,{...replyMarkup?{reply_markup:replyMarkup}:{},...threadParams})});return}let baseSessionKey=route.sessionKey,dmThreadId=threadSpec.scope===`dm`?threadSpec.id:void 0,sessionKey=(dmThreadId==null?null:resolveThreadSessionKeys({baseSessionKey,threadId:String(dmThreadId)}))?.sessionKey??baseSessionKey,skillFilter=firstDefined$2(topicConfig?.skills,groupConfig?.skills),systemPromptParts=[groupConfig?.systemPrompt?.trim()||null,topicConfig?.systemPrompt?.trim()||null].filter(entry=>!!entry),groupSystemPrompt=systemPromptParts.length>0?systemPromptParts.join(`
493
493
 
494
- `):void 0,conversationLabel=isGroup?msg.chat.title?`${msg.chat.title} id:${chatId}`:`group:${chatId}`:buildSenderName(msg)??String(senderId||chatId),ctxPayload=finalizeInboundContext({Body:prompt,BodyForAgent:prompt,RawBody:prompt,CommandBody:prompt,CommandArgs:commandArgs,From:isGroup?buildTelegramGroupFrom(chatId,resolvedThreadId):`telegram:${chatId}`,To:`slash:${senderId||chatId}`,ChatType:isGroup?`group`:`direct`,ConversationLabel:conversationLabel,GroupSubject:isGroup?msg.chat.title??void 0:void 0,GroupSystemPrompt:isGroup?groupSystemPrompt:void 0,SenderName:buildSenderName(msg),SenderId:senderId||void 0,SenderUsername:senderUsername||void 0,Surface:`telegram`,MessageSid:String(msg.message_id),Timestamp:msg.date?msg.date*1e3:void 0,WasMentioned:!0,CommandAuthorized:commandAuthorized,CommandSource:`native`,SessionKey:`telegram:slash:${senderId||chatId}`,AccountId:route.accountId,CommandTargetSessionKey:sessionKey,MessageThreadId:threadSpec.id,IsForum:isForum,OriginatingChannel:`telegram`,OriginatingTo:`telegram:${chatId}`}),disableBlockStreaming=typeof telegramCfg.blockStreaming==`boolean`?!telegramCfg.blockStreaming:void 0,deliveryState={delivered:!1,skippedNonSilent:0},{onModelSelected,...prefixOptions}=createReplyPrefixOptions({cfg,agentId:route.agentId,channel:`telegram`,accountId:route.accountId});await dispatchReplyWithBufferedBlockDispatcher({ctx:ctxPayload,cfg,dispatcherOptions:{...prefixOptions,deliver:async(payload,_info)=>{(await deliverReplies({replies:[payload],...deliveryBaseOptions})).delivered&&(deliveryState.delivered=!0)},onSkip:(_payload,info)=>{info.reason!==`silent`&&(deliveryState.skippedNonSilent+=1)},onError:(err,info)=>{runtime.error?.(danger(`telegram slash ${info.kind} reply failed: ${String(err)}`))}},replyOptions:{skillFilter,disableBlockStreaming,onModelSelected}}),!deliveryState.delivered&&deliveryState.skippedNonSilent>0&&await deliverReplies({replies:[{text:`No response generated. Please try again.`}],...deliveryBaseOptions})})}for(let pluginCommand of pluginCatalog.commands)bot.command(pluginCommand.command,async ctx=>{let msg=ctx.message;if(!msg||shouldSkipUpdate(ctx))return;let chatId=msg.chat.id,rawText=ctx.match?.trim()??``,commandBody=`/${pluginCommand.command}${rawText?` ${rawText}`:``}`,match=matchPluginCommand(commandBody);if(!match){await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,fn:()=>bot.api.sendMessage(chatId,`Command not found.`)});return}let auth=await resolveTelegramCommandAuth({msg,bot,cfg,accountId,telegramCfg,allowFrom,groupAllowFrom,useAccessGroups,resolveGroupPolicy,resolveTelegramGroupConfig,requireAuth:match.command.requireAuth!==!1});if(!auth)return;let{senderId,commandAuthorized,isGroup,isForum,resolvedThreadId}=auth,{threadSpec,mediaLocalRoots,tableMode,chunkMode}=resolveCommandRuntimeContext({msg,isGroup,isForum,resolvedThreadId}),deliveryBaseOptions=buildCommandDeliveryBaseOptions({chatId,mediaLocalRoots,threadSpec,tableMode,chunkMode}),from=isGroup?buildTelegramGroupFrom(chatId,threadSpec.id):`telegram:${chatId}`,to=`telegram:${chatId}`;await deliverReplies({replies:[await executePluginCommand({command:match.command,args:match.args,senderId,channel:`telegram`,isAuthorizedSender:commandAuthorized,commandBody,config:cfg,from,to,accountId,messageThreadId:threadSpec.id})],...deliveryBaseOptions})})}else nativeDisabledExplicit&&withTelegramApiErrorLogging({operation:`setMyCommands`,runtime,fn:()=>bot.api.setMyCommands([])}).catch(()=>{})};function getTelegramSequentialKey(ctx){let reaction=ctx.update?.message_reaction;if(reaction?.chat?.id)return`telegram:${reaction.chat.id}`;let msg=ctx.message??ctx.channelPost??ctx.editedChannelPost??ctx.update?.message??ctx.update?.edited_message??ctx.update?.channel_post??ctx.update?.edited_channel_post??ctx.update?.callback_query?.message,chatId=msg?.chat?.id??ctx.chat?.id,rawText=msg?.text??msg?.caption,botUsername=ctx.me?.username;if(isAbortRequestText(rawText,botUsername?{botUsername}:void 0))return typeof chatId==`number`?`telegram:${chatId}:control`:`telegram:control`;let isGroup=msg?.chat?.type===`group`||msg?.chat?.type===`supergroup`,messageThreadId=msg?.message_thread_id,isForum=msg?.chat?.is_forum,threadId=isGroup?resolveTelegramForumThreadId({isForum,messageThreadId}):messageThreadId;return typeof chatId==`number`?threadId==null?`telegram:${chatId}`:`telegram:${chatId}:topic:${threadId}`:`telegram:unknown`}function createTelegramBot(opts){let runtime=opts.runtime??{log:console.log,error:console.error,exit:code=>{throw Error(`exit ${code}`)}},cfg=opts.config??loadConfig(),account=resolveTelegramAccount({cfg,accountId:opts.accountId}),telegramCfg=account.config,fetchImpl=resolveTelegramFetch(opts.proxyFetch,{network:telegramCfg.network}),shouldProvideFetch=!!fetchImpl,fetchForClient=fetchImpl,timeoutSeconds=typeof telegramCfg?.timeoutSeconds==`number`&&Number.isFinite(telegramCfg.timeoutSeconds)?Math.max(1,Math.floor(telegramCfg.timeoutSeconds)):void 0,client=shouldProvideFetch||timeoutSeconds?{...shouldProvideFetch&&fetchImpl?{fetch:fetchForClient}:{},...timeoutSeconds?{timeoutSeconds}:{}}:void 0,bot=new Bot(opts.token,client?{client}:void 0);bot.api.config.use(apiThrottler()),bot.use(sequentialize(getTelegramSequentialKey)),bot.catch(err=>{runtime.error?.(danger(`telegram bot error: ${formatUncaughtError(err)}`))});let recentUpdates=createTelegramUpdateDedupe(),lastUpdateId=typeof opts.updateOffset?.lastUpdateId==`number`?opts.updateOffset.lastUpdateId:null,recordUpdateId=ctx=>{let updateId=resolveTelegramUpdateId(ctx);typeof updateId==`number`&&(lastUpdateId!==null&&updateId<=lastUpdateId||(lastUpdateId=updateId,opts.updateOffset?.onUpdateId?.(updateId)))},shouldSkipUpdate=ctx=>{let updateId=resolveTelegramUpdateId(ctx);if(typeof updateId==`number`&&lastUpdateId!==null&&updateId<=lastUpdateId)return!0;let key=buildTelegramUpdateKey(ctx),skipped=recentUpdates.check(key);return skipped&&key&&shouldLogVerbose()&&logVerbose(`telegram dedupe: skipped ${key}`),skipped},rawUpdateLogger=createSubsystemLogger(`gateway/channels/telegram/raw-update`),MAX_RAW_UPDATE_CHARS=8e3,stringifyUpdate=update=>{let seen=new WeakSet;return JSON.stringify(update??null,(key,value)=>{if(typeof value==`string`&&value.length>500)return`${value.slice(0,500)}...`;if(Array.isArray(value)&&value.length>20)return[...value.slice(0,20),`...(${value.length-20} more)`];if(value&&typeof value==`object`){if(seen.has(value))return`[Circular]`;seen.add(value)}return value})};bot.use(async(ctx,next)=>{if(shouldLogVerbose())try{let raw=stringifyUpdate(ctx.update),preview=raw.length>MAX_RAW_UPDATE_CHARS?`${raw.slice(0,MAX_RAW_UPDATE_CHARS)}...`:raw;rawUpdateLogger.debug(`telegram update: ${preview}`)}catch(err){rawUpdateLogger.debug(`telegram update log failed: ${String(err)}`)}await next(),recordUpdateId(ctx)});let historyLimit=Math.max(0,telegramCfg.historyLimit??cfg.messages?.groupChat?.historyLimit??50),groupHistories=new Map,textLimit=resolveTextChunkLimit(cfg,`telegram`,account.accountId),dmPolicy=telegramCfg.dmPolicy??`pairing`,allowFrom=opts.allowFrom??telegramCfg.allowFrom,groupAllowFrom=opts.groupAllowFrom??telegramCfg.groupAllowFrom??(telegramCfg.allowFrom&&telegramCfg.allowFrom.length>0?telegramCfg.allowFrom:void 0)??(opts.allowFrom&&opts.allowFrom.length>0?opts.allowFrom:void 0),replyToMode=opts.replyToMode??telegramCfg.replyToMode??`off`,nativeEnabled=resolveNativeCommandsEnabled({providerId:`telegram`,providerSetting:telegramCfg.commands?.native,globalSetting:cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`telegram`,providerSetting:telegramCfg.commands?.nativeSkills,globalSetting:cfg.commands?.nativeSkills}),nativeDisabledExplicit=isNativeCommandsExplicitlyDisabled({providerSetting:telegramCfg.commands?.native,globalSetting:cfg.commands?.native}),useAccessGroups=cfg.commands?.useAccessGroups!==!1,ackReactionScope=cfg.messages?.ackReactionScope??`group-mentions`,mediaMaxBytes=(opts.mediaMaxMb??telegramCfg.mediaMaxMb??5)*1024*1024,logger=getChildLogger({module:`telegram-auto-reply`}),streamMode=resolveTelegramStreamMode(telegramCfg),resolveGroupPolicy=chatId=>resolveChannelGroupPolicy({cfg,channel:`telegram`,accountId:account.accountId,groupId:String(chatId)}),resolveGroupActivation=params=>{let agentId=params.agentId??resolveDefaultAgentId(cfg),sessionKey=params.sessionKey??`agent:${agentId}:telegram:group:${buildTelegramGroupPeerId(params.chatId,params.messageThreadId)}`,storePath=resolveStorePath(cfg.session?.store,{agentId});try{let entry=loadSessionStore(storePath)[sessionKey];if(entry?.groupActivation===`always`)return!1;if(entry?.groupActivation===`mention`)return!0}catch(err){logVerbose(`Failed to load session for activation check: ${String(err)}`)}},resolveGroupRequireMention=chatId=>resolveChannelGroupRequireMention({cfg,channel:`telegram`,accountId:account.accountId,groupId:String(chatId),requireMentionOverride:opts.requireMention,overrideOrder:`after-config`}),resolveTelegramGroupConfig=(chatId,messageThreadId)=>{let groups=telegramCfg.groups;if(!groups)return{groupConfig:void 0,topicConfig:void 0};let groupConfig=groups[String(chatId)]??groups[`*`];return{groupConfig,topicConfig:messageThreadId==null?void 0:groupConfig?.topics?.[String(messageThreadId)]}},processMessage=createTelegramMessageProcessor({bot,cfg,account,telegramCfg,historyLimit,groupHistories,dmPolicy,allowFrom,groupAllowFrom,ackReactionScope,logger,resolveGroupActivation,resolveGroupRequireMention,resolveTelegramGroupConfig,runtime,replyToMode,streamMode,textLimit,opts});return registerTelegramNativeCommands({bot,cfg,runtime,accountId:account.accountId,telegramCfg,allowFrom,groupAllowFrom,replyToMode,textLimit,useAccessGroups,nativeEnabled,nativeSkillsEnabled,nativeDisabledExplicit,resolveGroupPolicy,resolveTelegramGroupConfig,shouldSkipUpdate,opts}),registerTelegramHandlers({cfg,accountId:account.accountId,bot,opts,runtime,mediaMaxBytes,telegramCfg,groupAllowFrom,resolveGroupPolicy,resolveTelegramGroupConfig,shouldSkipUpdate,processMessage,logger}),bot}function normalizeAccountId(accountId){let trimmed=accountId?.trim();return trimmed?trimmed.replace(/[^a-z0-9._-]+/gi,`_`):`default`}function resolveTelegramUpdateOffsetPath(accountId,env=process.env){let stateDir=resolveStateDir(env,os.homedir),normalized=normalizeAccountId(accountId);return path.join(stateDir,`telegram`,`update-offset-${normalized}.json`)}function safeParseState(raw){try{let parsed=JSON.parse(raw);return parsed?.version!==1||parsed.lastUpdateId!==null&&typeof parsed.lastUpdateId!=`number`?null:parsed}catch{return null}}async function readTelegramUpdateOffset(params){let filePath=resolveTelegramUpdateOffsetPath(params.accountId,params.env);try{return safeParseState(await fs$1.readFile(filePath,`utf-8`))?.lastUpdateId??null}catch(err){return err.code,null}}async function writeTelegramUpdateOffset(params){let filePath=resolveTelegramUpdateOffsetPath(params.accountId,params.env),dir=path.dirname(filePath);await fs$1.mkdir(dir,{recursive:!0,mode:448});let tmp=path.join(dir,`${path.basename(filePath)}.${crypto.randomUUID()}.tmp`),payload={version:1,lastUpdateId:params.updateId};await fs$1.writeFile(tmp,`${JSON.stringify(payload,null,2)}\n`,{encoding:`utf-8`}),await fs$1.chmod(tmp,384),await fs$1.rename(tmp,filePath)}async function deleteTelegramUpdateOffset(params){let filePath=resolveTelegramUpdateOffsetPath(params.accountId,params.env);try{await fs$1.unlink(filePath)}catch(err){if(err.code===`ENOENT`)return;throw err}}async function startTelegramWebhook(opts){let path=opts.path??`/telegram-webhook`,healthPath=opts.healthPath??`/healthz`,port=opts.port??8787,host=opts.host??`127.0.0.1`,secret=typeof opts.secret==`string`?opts.secret.trim():``;if(!secret)throw Error(`Telegram webhook mode requires a non-empty secret token. Set channels.telegram.webhookSecret in your config.`);let runtime=opts.runtime??defaultRuntime,diagnosticsEnabled=isDiagnosticsEnabled(opts.config),bot=createTelegramBot({token:opts.token,runtime,proxyFetch:opts.fetch,config:opts.config,accountId:opts.accountId}),handler=webhookCallback(bot,`http`,{secretToken:secret,onTimeout:`return`,timeoutMilliseconds:1e4});diagnosticsEnabled&&startDiagnosticHeartbeat();let server=createServer((req,res)=>{if(req.url===healthPath){res.writeHead(200),res.end(`ok`);return}if(req.url!==path||req.method!==`POST`){res.writeHead(404),res.end();return}let startTime=Date.now();diagnosticsEnabled&&logWebhookReceived({channel:`telegram`,updateType:`telegram-post`});let guard=installRequestBodyLimitGuard(req,res,{maxBytes:1048576,timeoutMs:3e4,responseFormat:`text`});if(guard.isTripped())return;let handled=handler(req,res);if(handled&&typeof handled.catch==`function`){handled.then(()=>{diagnosticsEnabled&&logWebhookProcessed({channel:`telegram`,updateType:`telegram-post`,durationMs:Date.now()-startTime})}).catch(err=>{if(guard.isTripped())return;let errMsg=formatErrorMessage(err);diagnosticsEnabled&&logWebhookError({channel:`telegram`,updateType:`telegram-post`,error:errMsg}),runtime.log?.(`webhook handler failed: ${errMsg}`),res.headersSent||res.writeHead(500),res.end()}).finally(()=>{guard.dispose()});return}guard.dispose()}),publicUrl=opts.publicUrl??`http://${host===`0.0.0.0`?`localhost`:host}:${port}${path}`;await withTelegramApiErrorLogging({operation:`setWebhook`,runtime,fn:()=>bot.api.setWebhook(publicUrl,{secret_token:secret,allowed_updates:resolveTelegramAllowedUpdates()})}),await new Promise(resolve=>server.listen(port,host,resolve)),runtime.log?.(`webhook listening on ${publicUrl}`);let shutdown=()=>{server.close(),bot.stop(),diagnosticsEnabled&&stopDiagnosticHeartbeat()};return opts.abortSignal&&opts.abortSignal.addEventListener(`abort`,shutdown,{once:!0}),{server,bot,stop:shutdown}}function createTelegramRunnerOptions(cfg){return{sink:{concurrency:resolveAgentMaxConcurrent(cfg)},runner:{fetch:{timeout:30,allowed_updates:resolveTelegramAllowedUpdates()},silent:!0,maxRetryTime:300*1e3,retryInterval:`exponential`}}}const TELEGRAM_POLL_RESTART_POLICY={initialMs:2e3,maxMs:3e4,factor:1.8,jitter:.25},isGetUpdatesConflict=err=>{if(!err||typeof err!=`object`)return!1;let typed=err;return(typed.error_code??typed.errorCode)===409?[typed.method,typed.description,typed.message].filter(value=>typeof value==`string`).join(` `).toLowerCase().includes(`getupdates`):!1},isGrammyHttpError=err=>!err||typeof err!=`object`?!1:err.name===`HttpError`;async function monitorTelegramProvider(opts={}){let log=opts.runtime?.error??console.error,unregisterHandler=registerUnhandledRejectionHandler(err=>isGrammyHttpError(err)&&isRecoverableTelegramNetworkError(err,{context:`polling`})?(log(`[telegram] Suppressed network error: ${formatErrorMessage(err)}`),!0):!1);try{let cfg=opts.config??loadConfig(),account=resolveTelegramAccount({cfg,accountId:opts.accountId}),token=opts.token?.trim()||account.token;if(!token)throw Error(`Telegram bot token missing for account "${account.accountId}" (set channels.telegram.accounts.${account.accountId}.botToken/tokenFile or TELEGRAM_BOT_TOKEN for default).`);let proxyFetch=opts.proxyFetch??(account.config.proxy?makeProxyFetch(account.config.proxy):void 0),lastUpdateId=await readTelegramUpdateOffset({accountId:account.accountId}),bot=createTelegramBot({token,runtime:opts.runtime,proxyFetch,config:cfg,accountId:account.accountId,updateOffset:{lastUpdateId,onUpdateId:async updateId=>{if(!(lastUpdateId!==null&&updateId<=lastUpdateId)){lastUpdateId=updateId;try{await writeTelegramUpdateOffset({accountId:account.accountId,updateId})}catch(err){(opts.runtime?.error??console.error)(`telegram: failed to persist update offset: ${String(err)}`)}}}}});if(opts.useWebhook){await startTelegramWebhook({token,accountId:account.accountId,config:cfg,path:opts.webhookPath,port:opts.webhookPort,secret:opts.webhookSecret??account.config.webhookSecret,host:opts.webhookHost??account.config.webhookHost,runtime:opts.runtime,fetch:proxyFetch,abortSignal:opts.abortSignal,publicUrl:opts.webhookUrl});return}let restartAttempts=0;for(;!opts.abortSignal?.aborted;){let runner=run(bot,createTelegramRunnerOptions(cfg)),stopOnAbort=()=>{opts.abortSignal?.aborted&&runner.stop()};opts.abortSignal?.addEventListener(`abort`,stopOnAbort,{once:!0});try{await runner.task();return}catch(err){if(opts.abortSignal?.aborted)throw err;let isConflict=isGetUpdatesConflict(err),isRecoverable=isRecoverableTelegramNetworkError(err,{context:`polling`});if(!isConflict&&!isRecoverable)throw err;restartAttempts+=1;let delayMs=computeBackoff(TELEGRAM_POLL_RESTART_POLICY,restartAttempts),reason=isConflict?`getUpdates conflict`:`network error`,errMsg=formatErrorMessage(err);(opts.runtime?.error??console.error)(`Telegram ${reason}: ${errMsg}; retrying in ${formatDurationPrecise(delayMs)}.`);try{await sleepWithAbort(delayMs,opts.abortSignal)}catch(sleepErr){if(opts.abortSignal?.aborted)return;throw sleepErr}}finally{opts.abortSignal?.removeEventListener(`abort`,stopOnAbort)}}}finally{unregisterHandler()}}async function probeTelegram(token,timeoutMs,proxyUrl){let started=Date.now(),fetcher=proxyUrl?makeProxyFetch(proxyUrl):fetch,base=`https://api.telegram.org/bot${token}`,retryDelayMs=Math.max(50,Math.min(1e3,timeoutMs)),result={ok:!1,status:null,error:null,elapsedMs:0};try{let meRes=null,fetchError=null;for(let i=0;i<3;i++)try{meRes=await fetchWithTimeout(`${base}/getMe`,{},timeoutMs,fetcher);break}catch(err){fetchError=err,i<2&&await new Promise(resolve=>setTimeout(resolve,retryDelayMs))}if(!meRes)throw fetchError;let meJson=await meRes.json();if(!meRes.ok||!meJson?.ok)return result.status=meRes.status,result.error=meJson?.description??`getMe failed (${meRes.status})`,{...result,elapsedMs:Date.now()-started};result.bot={id:meJson.result?.id??null,username:meJson.result?.username??null,canJoinGroups:typeof meJson.result?.can_join_groups==`boolean`?meJson.result?.can_join_groups:null,canReadAllGroupMessages:typeof meJson.result?.can_read_all_group_messages==`boolean`?meJson.result?.can_read_all_group_messages:null,supportsInlineQueries:typeof meJson.result?.supports_inline_queries==`boolean`?meJson.result?.supports_inline_queries:null};try{let webhookRes=await fetchWithTimeout(`${base}/getWebhookInfo`,{},timeoutMs,fetcher),webhookJson=await webhookRes.json();webhookRes.ok&&webhookJson?.ok&&(result.webhook={url:webhookJson.result?.url??null,hasCustomCert:webhookJson.result?.has_custom_certificate??null})}catch{}return result.ok=!0,result.status=null,result.error=null,result.elapsedMs=Date.now()-started,result}catch(err){return{...result,status:err instanceof Response?err.status:result.status,error:err instanceof Error?err.message:String(err),elapsedMs:Date.now()-started}}}function formatNativeDependencyHint(params){let manager=params.manager??`pnpm`,rebuildCommand=params.rebuildCommand??(manager===`npm`?`npm rebuild ${params.packageName}`:manager===`yarn`?`yarn rebuild ${params.packageName}`:`pnpm rebuild ${params.packageName}`),steps=[params.approveBuildsCommand??(manager===`pnpm`?`pnpm approve-builds (select ${params.packageName})`:void 0),rebuildCommand,params.downloadCommand].filter(step=>!!step);return steps.length===0?`Install ${params.packageName} and rebuild its native module.`:`Install ${params.packageName} and rebuild its native module (${steps.join(`; `)}).`}let cachedVersion=null;function resolveVersion(){if(cachedVersion)return cachedVersion;try{return cachedVersion=createRequire(import.meta.url)(`../../../package.json`).version??`unknown`,cachedVersion}catch{return cachedVersion=`unknown`,cachedVersion}}const sendMessageWhatsAppLazy=async(...args)=>{let{sendMessageWhatsApp}=await loadWebOutbound();return sendMessageWhatsApp(...args)},sendPollWhatsAppLazy=async(...args)=>{let{sendPollWhatsApp}=await loadWebOutbound();return sendPollWhatsApp(...args)},loginWebLazy=async(...args)=>{let{loginWeb}=await loadWebLogin();return loginWeb(...args)},startWebLoginWithQrLazy=async(...args)=>{let{startWebLoginWithQr}=await loadWebLoginQr();return startWebLoginWithQr(...args)},waitForWebLoginLazy=async(...args)=>{let{waitForWebLogin}=await loadWebLoginQr();return waitForWebLogin(...args)},monitorWebChannelLazy=async(...args)=>{let{monitorWebChannel}=await loadWebChannel();return monitorWebChannel(...args)},handleWhatsAppActionLazy=async(...args)=>{let{handleWhatsAppAction}=await loadWhatsAppActions();return handleWhatsAppAction(...args)};let webOutboundPromise=null,webLoginPromise=null,webLoginQrPromise=null,webChannelPromise=null,whatsappActionsPromise=null;function loadWebOutbound(){return webOutboundPromise??=import(`./outbound-BRInCJD9.js`),webOutboundPromise}function loadWebLogin(){return webLoginPromise??=import(`./login-CPyEf5h6.js`),webLoginPromise}function loadWebLoginQr(){return webLoginQrPromise??=import(`./login-qr-B9lyIZVD.js`),webLoginQrPromise}function loadWebChannel(){return webChannelPromise??=import(`./web-D-NSyF6b.js`),webChannelPromise}function loadWhatsAppActions(){return whatsappActionsPromise??=import(`./whatsapp-actions-JbF2MrTV.js`),whatsappActionsPromise}function createPluginRuntime(){return{version:resolveVersion(),config:{loadConfig,writeConfigFile},system:{enqueueSystemEvent,runCommandWithTimeout,formatNativeDependencyHint},media:{loadWebMedia,detectMime,mediaKindFromMime,isVoiceCompatibleAudio,getImageMetadata,resizeToJpeg},tts:{textToSpeechTelephony},tools:{createMemoryGetTool,createMemorySearchTool,registerMemoryCli},channel:{text:{chunkByNewline,chunkMarkdownText,chunkMarkdownTextWithMode,chunkText,chunkTextWithMode,resolveChunkMode,resolveTextChunkLimit,hasControlCommand,resolveMarkdownTableMode,convertMarkdownTables},reply:{dispatchReplyWithBufferedBlockDispatcher,createReplyDispatcherWithTyping,resolveEffectiveMessagesConfig,resolveHumanDelayConfig,dispatchReplyFromConfig,finalizeInboundContext,formatAgentEnvelope,formatInboundEnvelope,resolveEnvelopeFormatOptions},routing:{resolveAgentRoute},pairing:{buildPairingReply,readAllowFromStore:readChannelAllowFromStore,upsertPairingRequest:upsertChannelPairingRequest},media:{fetchRemoteMedia,saveMediaBuffer},activity:{record:recordChannelActivity,get:getChannelActivity},session:{resolveStorePath,readSessionUpdatedAt,recordSessionMetaFromInbound,recordInboundSession,updateLastRoute},mentions:{buildMentionRegexes,matchesMentionPatterns,matchesMentionWithExplicit},reactions:{shouldAckReaction,removeAckReactionAfterReply},groups:{resolveGroupPolicy:resolveChannelGroupPolicy,resolveRequireMention:resolveChannelGroupRequireMention},debounce:{createInboundDebouncer,resolveInboundDebounceMs},commands:{resolveCommandAuthorizedFromAuthorizers,isControlCommandMessage,shouldComputeCommandAuthorized,shouldHandleTextCommands},discord:{messageActions:discordMessageActions,auditChannelPermissions:auditDiscordChannelPermissions,listDirectoryGroupsLive:listDiscordDirectoryGroupsLive,listDirectoryPeersLive:listDiscordDirectoryPeersLive,probeDiscord,resolveChannelAllowlist:resolveDiscordChannelAllowlist,resolveUserAllowlist:resolveDiscordUserAllowlist,sendMessageDiscord,sendPollDiscord,monitorDiscordProvider},slack:{listDirectoryGroupsLive:listSlackDirectoryGroupsLive,listDirectoryPeersLive:listSlackDirectoryPeersLive,probeSlack,resolveChannelAllowlist:resolveSlackChannelAllowlist,resolveUserAllowlist:resolveSlackUserAllowlist,sendMessageSlack,monitorSlackProvider,handleSlackAction},telegram:{auditGroupMembership:auditTelegramGroupMembership,collectUnmentionedGroupIds:collectTelegramUnmentionedGroupIds,probeTelegram,resolveTelegramToken,sendMessageTelegram,sendPollTelegram,monitorTelegramProvider,messageActions:telegramMessageActions},signal:{probeSignal,sendMessageSignal,monitorSignalProvider,messageActions:signalMessageActions},imessage:{monitorIMessageProvider,probeIMessage,sendMessageIMessage},whatsapp:{getActiveWebListener,getWebAuthAgeMs,logoutWeb,logWebSelfId,readWebSelfId,webAuthExists,sendMessageWhatsApp:sendMessageWhatsAppLazy,sendPollWhatsApp:sendPollWhatsAppLazy,loginWeb:loginWebLazy,startWebLoginWithQr:startWebLoginWithQrLazy,waitForWebLogin:waitForWebLoginLazy,monitorWebChannel:monitorWebChannelLazy,handleWhatsAppAction:handleWhatsAppActionLazy,createLoginTool:createWhatsAppLoginTool},line:{listLineAccountIds,resolveDefaultLineAccountId,resolveLineAccount,normalizeAccountId:normalizeAccountId$1,probeLineBot,sendMessageLine,pushMessageLine,pushMessagesLine,pushFlexMessage,pushTemplateMessage,pushLocationMessage,pushTextMessageWithQuickReplies,createQuickReplyItems,buildTemplateMessageFromPayload,monitorLineProvider}},logging:{shouldLogVerbose,getChildLogger:(bindings,opts)=>{let logger=getChildLogger(bindings,{level:opts?.level?normalizeLogLevel(opts.level):void 0});return{debug:message=>logger.debug?.(message),info:message=>logger.info(message),warn:message=>logger.warn(message),error:message=>logger.error(message)}}},state:{resolveStateDir}}}const registryCache=new Map,defaultLogger=()=>createSubsystemLogger(`plugins`),resolvePluginSdkAliasFile=params=>{try{let modulePath=fileURLToPath(import.meta.url),isTest=process.env.VITEST||!1,cursor=path.dirname(modulePath);for(let i=0;i<6;i+=1){let srcCandidate=path.join(cursor,`src`,`plugin-sdk`,params.srcFile),distCandidate=path.join(cursor,`dist`,`plugin-sdk`,params.distFile),orderedCandidates=isTest?[distCandidate,srcCandidate]:[distCandidate];for(let candidate of orderedCandidates)if(fs.existsSync(candidate))return candidate;let parent=path.dirname(cursor);if(parent===cursor)break;cursor=parent}}catch{}return null},resolvePluginSdkAlias=()=>resolvePluginSdkAliasFile({srcFile:`index.ts`,distFile:`index.js`}),resolvePluginSdkAccountIdAlias=()=>resolvePluginSdkAliasFile({srcFile:`account-id.ts`,distFile:`account-id.js`});function buildCacheKey(params){return`${params.workspaceDir?resolveUserPath(params.workspaceDir):``}::${JSON.stringify(params.plugins)}`}function validatePluginConfig(params){let schema=params.schema;if(!schema)return{ok:!0,value:params.value};let result=validateJsonSchemaValue({schema,cacheKey:params.cacheKey??JSON.stringify(schema),value:params.value??{}});return result.ok?{ok:!0,value:params.value}:{ok:!1,errors:result.errors}}function resolvePluginModuleExport(moduleExport){let resolved=moduleExport&&typeof moduleExport==`object`&&`default`in moduleExport?moduleExport.default:moduleExport;if(typeof resolved==`function`)return{register:resolved};if(resolved&&typeof resolved==`object`){let def=resolved;return{definition:def,register:def.register??def.activate}}return{}}function createPluginRecord(params){return{id:params.id,name:params.name??params.id,description:params.description,version:params.version,source:params.source,origin:params.origin,workspaceDir:params.workspaceDir,enabled:params.enabled,status:params.enabled?`loaded`:`disabled`,toolNames:[],hookNames:[],channelIds:[],providerIds:[],gatewayMethods:[],cliCommands:[],services:[],commands:[],httpHandlers:0,hookCount:0,configSchema:params.configSchema,configUiHints:void 0,configJsonSchema:void 0}}function pushDiagnostics(diagnostics,append){diagnostics.push(...append)}function registerManifestHookDirs(params){for(let hookDir of params.hookDirs){let resolvedDir=path.resolve(params.rootDir,hookDir);registerPluginHooksFromDir(params.api,resolvedDir).then(hookResult=>{for(let message of hookResult.errors)params.diagnostics.push({level:`warn`,pluginId:params.record.id,source:params.record.source,message})}).catch(err=>{params.logger.warn(`[plugins] ${params.record.id} failed loading hooks from ${resolvedDir}: ${String(err)}`)})}}function loadBuilderForceAgentsPlugins(options={}){let cfg=applyTestPluginDefaults(options.config??{},process.env),logger=options.logger??defaultLogger(),validateOnly=options.mode===`validate`,normalized=normalizePluginsConfig(cfg.plugins),cacheKey=buildCacheKey({workspaceDir:options.workspaceDir,plugins:normalized}),cacheEnabled=options.cache!==!1;if(cacheEnabled){let cached=registryCache.get(cacheKey);if(cached)return setActivePluginRegistry(cached,cacheKey),cached}clearPluginCommands();let{registry,createApi}=createPluginRegistry({logger,runtime:createPluginRuntime(),coreGatewayHandlers:options.coreGatewayHandlers}),discovery=discoverBuilderForceAgentsPlugins({workspaceDir:options.workspaceDir,extraPaths:normalized.loadPaths}),manifestRegistry=loadPluginManifestRegistry({config:cfg,workspaceDir:options.workspaceDir,cache:options.cache,candidates:discovery.candidates,diagnostics:discovery.diagnostics});pushDiagnostics(registry.diagnostics,manifestRegistry.diagnostics);let jitiLoader=null,getJiti=()=>{if(jitiLoader)return jitiLoader;let pluginSdkAlias=resolvePluginSdkAlias(),pluginSdkAccountIdAlias=resolvePluginSdkAccountIdAlias();return jitiLoader=createJiti(import.meta.url,{interopDefault:!0,extensions:[`.ts`,`.tsx`,`.mts`,`.cts`,`.mtsx`,`.ctsx`,`.js`,`.mjs`,`.cjs`,`.json`],...pluginSdkAlias||pluginSdkAccountIdAlias?{alias:{...pluginSdkAlias?{"@seanhogg/builderforce-agents/plugin-sdk":pluginSdkAlias}:{},...pluginSdkAccountIdAlias?{"@seanhogg/builderforce-agents/plugin-sdk/account-id":pluginSdkAccountIdAlias}:{}}}:{}}),jitiLoader},manifestByRoot=new Map(manifestRegistry.plugins.map(record=>[record.rootDir,record])),seenIds=new Map,memorySlot=normalized.slots.memory,selectedMemoryPluginId=null,memorySlotMatched=!1;for(let candidate of discovery.candidates){let manifestRecord=manifestByRoot.get(candidate.rootDir);if(!manifestRecord)continue;let pluginId=manifestRecord.id,existingOrigin=seenIds.get(pluginId);if(existingOrigin){let record=createPluginRecord({id:pluginId,name:manifestRecord.name??pluginId,description:manifestRecord.description,version:manifestRecord.version,source:candidate.source,origin:candidate.origin,workspaceDir:candidate.workspaceDir,enabled:!1,configSchema:!!manifestRecord.configSchema});record.status=`disabled`,record.error=`overridden by ${existingOrigin} plugin`,registry.plugins.push(record);continue}let enableState=resolveEnableState(pluginId,candidate.origin,normalized),entry=normalized.entries[pluginId],record=createPluginRecord({id:pluginId,name:manifestRecord.name??pluginId,description:manifestRecord.description,version:manifestRecord.version,source:candidate.source,origin:candidate.origin,workspaceDir:candidate.workspaceDir,enabled:enableState.enabled,configSchema:!!manifestRecord.configSchema});if(record.kind=manifestRecord.kind,record.configUiHints=manifestRecord.configUiHints,record.configJsonSchema=manifestRecord.configSchema,!enableState.enabled){record.status=`disabled`,record.error=enableState.reason,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin);continue}if(!manifestRecord.configSchema){record.status=`error`,record.error=`missing config schema`,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:record.error});continue}let mod=null;try{mod=getJiti()(candidate.source)}catch(err){logger.error(`[plugins] ${record.id} failed to load from ${record.source}: ${String(err)}`),record.status=`error`,record.error=String(err),registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:`failed to load plugin: ${String(err)}`});continue}let resolved=resolvePluginModuleExport(mod),definition=resolved.definition,register=resolved.register;definition?.id&&definition.id!==record.id&&registry.diagnostics.push({level:`warn`,pluginId:record.id,source:record.source,message:`plugin id mismatch (config uses "${record.id}", export uses "${definition.id}")`}),record.name=definition?.name??record.name,record.description=definition?.description??record.description,record.version=definition?.version??record.version;let manifestKind=record.kind,exportKind=definition?.kind;manifestKind&&exportKind&&exportKind!==manifestKind&&registry.diagnostics.push({level:`warn`,pluginId:record.id,source:record.source,message:`plugin kind mismatch (manifest uses "${manifestKind}", export uses "${exportKind}")`}),record.kind=definition?.kind??record.kind,record.kind===`memory`&&memorySlot===record.id&&(memorySlotMatched=!0);let memoryDecision=resolveMemorySlotDecision({id:record.id,kind:record.kind,slot:memorySlot,selectedId:selectedMemoryPluginId});if(!memoryDecision.enabled){record.enabled=!1,record.status=`disabled`,record.error=memoryDecision.reason,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin);continue}memoryDecision.selected&&record.kind===`memory`&&(selectedMemoryPluginId=record.id);let validatedConfig=validatePluginConfig({schema:manifestRecord.configSchema,cacheKey:manifestRecord.schemaCacheKey,value:entry?.config});if(!validatedConfig.ok){logger.error(`[plugins] ${record.id} invalid config: ${validatedConfig.errors?.join(`, `)}`),record.status=`error`,record.error=`invalid config: ${validatedConfig.errors?.join(`, `)}`,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:record.error});continue}if(validateOnly){registry.plugins.push(record),seenIds.set(pluginId,candidate.origin);continue}if(typeof register!=`function`){logger.error(`[plugins] ${record.id} missing register/activate export`),record.status=`error`,record.error=`plugin export missing register/activate`,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:record.error});continue}let api=createApi(record,{config:cfg,pluginConfig:validatedConfig.value});try{let result=register(api);result&&typeof result.then==`function`&&registry.diagnostics.push({level:`warn`,pluginId:record.id,source:record.source,message:`plugin register returned a promise; async registration is ignored`}),registerManifestHookDirs({api,record,rootDir:manifestRecord.rootDir,hookDirs:manifestRecord.hooks,diagnostics:registry.diagnostics,logger}),registry.plugins.push(record),seenIds.set(pluginId,candidate.origin)}catch(err){logger.error(`[plugins] ${record.id} failed during register from ${record.source}: ${String(err)}`),record.status=`error`,record.error=String(err),registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:`plugin failed during register: ${String(err)}`})}}return typeof memorySlot==`string`&&!memorySlotMatched&&registry.diagnostics.push({level:`warn`,message:`memory slot plugin not found or not marked as memory: ${memorySlot}`}),cacheEnabled&&registryCache.set(cacheKey,registry),setActivePluginRegistry(registry,cacheKey),initializeGlobalHookRunner(registry),registry}function createPluginLoaderLogger(logger){return{info:msg=>logger.info(msg),warn:msg=>logger.warn(msg),error:msg=>logger.error(msg),debug:msg=>logger.debug?.(msg)}}const log$5=createSubsystemLogger(`plugins`),pluginToolMeta=new WeakMap;function getPluginToolMeta(tool){return pluginToolMeta.get(tool)}function normalizeAllowlist(list){return new Set((list??[]).map(normalizeToolName).filter(Boolean))}function isOptionalToolAllowed(params){if(params.allowlist.size===0)return!1;let toolName=normalizeToolName(params.toolName);if(params.allowlist.has(toolName))return!0;let pluginKey=normalizeToolName(params.pluginId);return params.allowlist.has(pluginKey)?!0:params.allowlist.has(`group:plugins`)}function resolvePluginTools(params){let effectiveConfig=applyTestPluginDefaults(params.context.config??{},process.env);if(!normalizePluginsConfig(effectiveConfig.plugins).enabled)return[];let registry=loadBuilderForceAgentsPlugins({config:effectiveConfig,workspaceDir:params.context.workspaceDir,logger:createPluginLoaderLogger(log$5)}),tools=[],existing=params.existingToolNames??new Set,existingNormalized=new Set(Array.from(existing,tool=>normalizeToolName(tool))),allowlist=normalizeAllowlist(params.toolAllowlist),blockedPlugins=new Set;for(let entry of registry.tools){if(blockedPlugins.has(entry.pluginId))continue;let pluginIdKey=normalizeToolName(entry.pluginId);if(existingNormalized.has(pluginIdKey)){let message=`plugin id conflicts with core tool name (${entry.pluginId})`;log$5.error(message),registry.diagnostics.push({level:`error`,pluginId:entry.pluginId,source:entry.source,message}),blockedPlugins.add(entry.pluginId);continue}let resolved=null;try{resolved=entry.factory(params.context)}catch(err){log$5.error(`plugin tool failed (${entry.pluginId}): ${String(err)}`);continue}if(!resolved)continue;let listRaw=Array.isArray(resolved)?resolved:[resolved],list=entry.optional?listRaw.filter(tool=>isOptionalToolAllowed({toolName:tool.name,pluginId:entry.pluginId,allowlist})):listRaw;if(list.length===0)continue;let nameSet=new Set;for(let tool of list){if(nameSet.has(tool.name)||existing.has(tool.name)){let message=`plugin tool name conflict (${entry.pluginId}): ${tool.name}`;log$5.error(message),registry.diagnostics.push({level:`error`,pluginId:entry.pluginId,source:entry.source,message});continue}nameSet.add(tool.name),existing.add(tool.name),pluginToolMeta.set(tool,{pluginId:entry.pluginId,optional:entry.optional}),tools.push(tool)}}return tools}async function defaultReadFile(filePath){return fs$1.readFile(filePath,`utf8`)}async function applyUpdateHunk(filePath,chunks,options){let originalLines=(await(options?.readFile??defaultReadFile)(filePath).catch(err=>{throw Error(`Failed to read file to update ${filePath}: ${err}`)})).split(`
494
+ `):void 0,conversationLabel=isGroup?msg.chat.title?`${msg.chat.title} id:${chatId}`:`group:${chatId}`:buildSenderName(msg)??String(senderId||chatId),ctxPayload=finalizeInboundContext({Body:prompt,BodyForAgent:prompt,RawBody:prompt,CommandBody:prompt,CommandArgs:commandArgs,From:isGroup?buildTelegramGroupFrom(chatId,resolvedThreadId):`telegram:${chatId}`,To:`slash:${senderId||chatId}`,ChatType:isGroup?`group`:`direct`,ConversationLabel:conversationLabel,GroupSubject:isGroup?msg.chat.title??void 0:void 0,GroupSystemPrompt:isGroup?groupSystemPrompt:void 0,SenderName:buildSenderName(msg),SenderId:senderId||void 0,SenderUsername:senderUsername||void 0,Surface:`telegram`,MessageSid:String(msg.message_id),Timestamp:msg.date?msg.date*1e3:void 0,WasMentioned:!0,CommandAuthorized:commandAuthorized,CommandSource:`native`,SessionKey:`telegram:slash:${senderId||chatId}`,AccountId:route.accountId,CommandTargetSessionKey:sessionKey,MessageThreadId:threadSpec.id,IsForum:isForum,OriginatingChannel:`telegram`,OriginatingTo:`telegram:${chatId}`}),disableBlockStreaming=typeof telegramCfg.blockStreaming==`boolean`?!telegramCfg.blockStreaming:void 0,deliveryState={delivered:!1,skippedNonSilent:0},{onModelSelected,...prefixOptions}=createReplyPrefixOptions({cfg,agentId:route.agentId,channel:`telegram`,accountId:route.accountId});await dispatchReplyWithBufferedBlockDispatcher({ctx:ctxPayload,cfg,dispatcherOptions:{...prefixOptions,deliver:async(payload,_info)=>{(await deliverReplies({replies:[payload],...deliveryBaseOptions})).delivered&&(deliveryState.delivered=!0)},onSkip:(_payload,info)=>{info.reason!==`silent`&&(deliveryState.skippedNonSilent+=1)},onError:(err,info)=>{runtime.error?.(danger(`telegram slash ${info.kind} reply failed: ${String(err)}`))}},replyOptions:{skillFilter,disableBlockStreaming,onModelSelected}}),!deliveryState.delivered&&deliveryState.skippedNonSilent>0&&await deliverReplies({replies:[{text:`No response generated. Please try again.`}],...deliveryBaseOptions})})}for(let pluginCommand of pluginCatalog.commands)bot.command(pluginCommand.command,async ctx=>{let msg=ctx.message;if(!msg||shouldSkipUpdate(ctx))return;let chatId=msg.chat.id,rawText=ctx.match?.trim()??``,commandBody=`/${pluginCommand.command}${rawText?` ${rawText}`:``}`,match=matchPluginCommand(commandBody);if(!match){await withTelegramApiErrorLogging({operation:`sendMessage`,runtime,fn:()=>bot.api.sendMessage(chatId,`Command not found.`)});return}let auth=await resolveTelegramCommandAuth({msg,bot,cfg,accountId,telegramCfg,allowFrom,groupAllowFrom,useAccessGroups,resolveGroupPolicy,resolveTelegramGroupConfig,requireAuth:match.command.requireAuth!==!1});if(!auth)return;let{senderId,commandAuthorized,isGroup,isForum,resolvedThreadId}=auth,{threadSpec,mediaLocalRoots,tableMode,chunkMode}=resolveCommandRuntimeContext({msg,isGroup,isForum,resolvedThreadId}),deliveryBaseOptions=buildCommandDeliveryBaseOptions({chatId,mediaLocalRoots,threadSpec,tableMode,chunkMode}),from=isGroup?buildTelegramGroupFrom(chatId,threadSpec.id):`telegram:${chatId}`,to=`telegram:${chatId}`;await deliverReplies({replies:[await executePluginCommand({command:match.command,args:match.args,senderId,channel:`telegram`,isAuthorizedSender:commandAuthorized,commandBody,config:cfg,from,to,accountId,messageThreadId:threadSpec.id})],...deliveryBaseOptions})})}else nativeDisabledExplicit&&withTelegramApiErrorLogging({operation:`setMyCommands`,runtime,fn:()=>bot.api.setMyCommands([])}).catch(()=>{})};function getTelegramSequentialKey(ctx){let reaction=ctx.update?.message_reaction;if(reaction?.chat?.id)return`telegram:${reaction.chat.id}`;let msg=ctx.message??ctx.channelPost??ctx.editedChannelPost??ctx.update?.message??ctx.update?.edited_message??ctx.update?.channel_post??ctx.update?.edited_channel_post??ctx.update?.callback_query?.message,chatId=msg?.chat?.id??ctx.chat?.id,rawText=msg?.text??msg?.caption,botUsername=ctx.me?.username;if(isAbortRequestText(rawText,botUsername?{botUsername}:void 0))return typeof chatId==`number`?`telegram:${chatId}:control`:`telegram:control`;let isGroup=msg?.chat?.type===`group`||msg?.chat?.type===`supergroup`,messageThreadId=msg?.message_thread_id,isForum=msg?.chat?.is_forum,threadId=isGroup?resolveTelegramForumThreadId({isForum,messageThreadId}):messageThreadId;return typeof chatId==`number`?threadId==null?`telegram:${chatId}`:`telegram:${chatId}:topic:${threadId}`:`telegram:unknown`}function createTelegramBot(opts){let runtime=opts.runtime??{log:console.log,error:console.error,exit:code=>{throw Error(`exit ${code}`)}},cfg=opts.config??loadConfig(),account=resolveTelegramAccount({cfg,accountId:opts.accountId}),telegramCfg=account.config,fetchImpl=resolveTelegramFetch(opts.proxyFetch,{network:telegramCfg.network}),shouldProvideFetch=!!fetchImpl,fetchForClient=fetchImpl,timeoutSeconds=typeof telegramCfg?.timeoutSeconds==`number`&&Number.isFinite(telegramCfg.timeoutSeconds)?Math.max(1,Math.floor(telegramCfg.timeoutSeconds)):void 0,client=shouldProvideFetch||timeoutSeconds?{...shouldProvideFetch&&fetchImpl?{fetch:fetchForClient}:{},...timeoutSeconds?{timeoutSeconds}:{}}:void 0,bot=new Bot(opts.token,client?{client}:void 0);bot.api.config.use(apiThrottler()),bot.use(sequentialize(getTelegramSequentialKey)),bot.catch(err=>{runtime.error?.(danger(`telegram bot error: ${formatUncaughtError(err)}`))});let recentUpdates=createTelegramUpdateDedupe(),lastUpdateId=typeof opts.updateOffset?.lastUpdateId==`number`?opts.updateOffset.lastUpdateId:null,recordUpdateId=ctx=>{let updateId=resolveTelegramUpdateId(ctx);typeof updateId==`number`&&(lastUpdateId!==null&&updateId<=lastUpdateId||(lastUpdateId=updateId,opts.updateOffset?.onUpdateId?.(updateId)))},shouldSkipUpdate=ctx=>{let updateId=resolveTelegramUpdateId(ctx);if(typeof updateId==`number`&&lastUpdateId!==null&&updateId<=lastUpdateId)return!0;let key=buildTelegramUpdateKey(ctx),skipped=recentUpdates.check(key);return skipped&&key&&shouldLogVerbose()&&logVerbose(`telegram dedupe: skipped ${key}`),skipped},rawUpdateLogger=createSubsystemLogger(`gateway/channels/telegram/raw-update`),MAX_RAW_UPDATE_CHARS=8e3,stringifyUpdate=update=>{let seen=new WeakSet;return JSON.stringify(update??null,(key,value)=>{if(typeof value==`string`&&value.length>500)return`${value.slice(0,500)}...`;if(Array.isArray(value)&&value.length>20)return[...value.slice(0,20),`...(${value.length-20} more)`];if(value&&typeof value==`object`){if(seen.has(value))return`[Circular]`;seen.add(value)}return value})};bot.use(async(ctx,next)=>{if(shouldLogVerbose())try{let raw=stringifyUpdate(ctx.update),preview=raw.length>MAX_RAW_UPDATE_CHARS?`${raw.slice(0,MAX_RAW_UPDATE_CHARS)}...`:raw;rawUpdateLogger.debug(`telegram update: ${preview}`)}catch(err){rawUpdateLogger.debug(`telegram update log failed: ${String(err)}`)}await next(),recordUpdateId(ctx)});let historyLimit=Math.max(0,telegramCfg.historyLimit??cfg.messages?.groupChat?.historyLimit??50),groupHistories=new Map,textLimit=resolveTextChunkLimit(cfg,`telegram`,account.accountId),dmPolicy=telegramCfg.dmPolicy??`pairing`,allowFrom=opts.allowFrom??telegramCfg.allowFrom,groupAllowFrom=opts.groupAllowFrom??telegramCfg.groupAllowFrom??(telegramCfg.allowFrom&&telegramCfg.allowFrom.length>0?telegramCfg.allowFrom:void 0)??(opts.allowFrom&&opts.allowFrom.length>0?opts.allowFrom:void 0),replyToMode=opts.replyToMode??telegramCfg.replyToMode??`off`,nativeEnabled=resolveNativeCommandsEnabled({providerId:`telegram`,providerSetting:telegramCfg.commands?.native,globalSetting:cfg.commands?.native}),nativeSkillsEnabled=resolveNativeSkillsEnabled({providerId:`telegram`,providerSetting:telegramCfg.commands?.nativeSkills,globalSetting:cfg.commands?.nativeSkills}),nativeDisabledExplicit=isNativeCommandsExplicitlyDisabled({providerSetting:telegramCfg.commands?.native,globalSetting:cfg.commands?.native}),useAccessGroups=cfg.commands?.useAccessGroups!==!1,ackReactionScope=cfg.messages?.ackReactionScope??`group-mentions`,mediaMaxBytes=(opts.mediaMaxMb??telegramCfg.mediaMaxMb??5)*1024*1024,logger=getChildLogger({module:`telegram-auto-reply`}),streamMode=resolveTelegramStreamMode(telegramCfg),resolveGroupPolicy=chatId=>resolveChannelGroupPolicy({cfg,channel:`telegram`,accountId:account.accountId,groupId:String(chatId)}),resolveGroupActivation=params=>{let agentId=params.agentId??resolveDefaultAgentId(cfg),sessionKey=params.sessionKey??`agent:${agentId}:telegram:group:${buildTelegramGroupPeerId(params.chatId,params.messageThreadId)}`,storePath=resolveStorePath(cfg.session?.store,{agentId});try{let entry=loadSessionStore(storePath)[sessionKey];if(entry?.groupActivation===`always`)return!1;if(entry?.groupActivation===`mention`)return!0}catch(err){logVerbose(`Failed to load session for activation check: ${String(err)}`)}},resolveGroupRequireMention=chatId=>resolveChannelGroupRequireMention({cfg,channel:`telegram`,accountId:account.accountId,groupId:String(chatId),requireMentionOverride:opts.requireMention,overrideOrder:`after-config`}),resolveTelegramGroupConfig=(chatId,messageThreadId)=>{let groups=telegramCfg.groups;if(!groups)return{groupConfig:void 0,topicConfig:void 0};let groupConfig=groups[String(chatId)]??groups[`*`];return{groupConfig,topicConfig:messageThreadId==null?void 0:groupConfig?.topics?.[String(messageThreadId)]}},processMessage=createTelegramMessageProcessor({bot,cfg,account,telegramCfg,historyLimit,groupHistories,dmPolicy,allowFrom,groupAllowFrom,ackReactionScope,logger,resolveGroupActivation,resolveGroupRequireMention,resolveTelegramGroupConfig,runtime,replyToMode,streamMode,textLimit,opts});return registerTelegramNativeCommands({bot,cfg,runtime,accountId:account.accountId,telegramCfg,allowFrom,groupAllowFrom,replyToMode,textLimit,useAccessGroups,nativeEnabled,nativeSkillsEnabled,nativeDisabledExplicit,resolveGroupPolicy,resolveTelegramGroupConfig,shouldSkipUpdate,opts}),registerTelegramHandlers({cfg,accountId:account.accountId,bot,opts,runtime,mediaMaxBytes,telegramCfg,groupAllowFrom,resolveGroupPolicy,resolveTelegramGroupConfig,shouldSkipUpdate,processMessage,logger}),bot}function normalizeAccountId(accountId){let trimmed=accountId?.trim();return trimmed?trimmed.replace(/[^a-z0-9._-]+/gi,`_`):`default`}function resolveTelegramUpdateOffsetPath(accountId,env=process.env){let stateDir=resolveStateDir(env,os.homedir),normalized=normalizeAccountId(accountId);return path.join(stateDir,`telegram`,`update-offset-${normalized}.json`)}function safeParseState(raw){try{let parsed=JSON.parse(raw);return parsed?.version!==1||parsed.lastUpdateId!==null&&typeof parsed.lastUpdateId!=`number`?null:parsed}catch{return null}}async function readTelegramUpdateOffset(params){let filePath=resolveTelegramUpdateOffsetPath(params.accountId,params.env);try{return safeParseState(await fs$1.readFile(filePath,`utf-8`))?.lastUpdateId??null}catch(err){return err.code,null}}async function writeTelegramUpdateOffset(params){let filePath=resolveTelegramUpdateOffsetPath(params.accountId,params.env),dir=path.dirname(filePath);await fs$1.mkdir(dir,{recursive:!0,mode:448});let tmp=path.join(dir,`${path.basename(filePath)}.${crypto.randomUUID()}.tmp`),payload={version:1,lastUpdateId:params.updateId};await fs$1.writeFile(tmp,`${JSON.stringify(payload,null,2)}\n`,{encoding:`utf-8`}),await fs$1.chmod(tmp,384),await fs$1.rename(tmp,filePath)}async function deleteTelegramUpdateOffset(params){let filePath=resolveTelegramUpdateOffsetPath(params.accountId,params.env);try{await fs$1.unlink(filePath)}catch(err){if(err.code===`ENOENT`)return;throw err}}async function startTelegramWebhook(opts){let path=opts.path??`/telegram-webhook`,healthPath=opts.healthPath??`/healthz`,port=opts.port??8787,host=opts.host??`127.0.0.1`,secret=typeof opts.secret==`string`?opts.secret.trim():``;if(!secret)throw Error(`Telegram webhook mode requires a non-empty secret token. Set channels.telegram.webhookSecret in your config.`);let runtime=opts.runtime??defaultRuntime,diagnosticsEnabled=isDiagnosticsEnabled(opts.config),bot=createTelegramBot({token:opts.token,runtime,proxyFetch:opts.fetch,config:opts.config,accountId:opts.accountId}),handler=webhookCallback(bot,`http`,{secretToken:secret,onTimeout:`return`,timeoutMilliseconds:1e4});diagnosticsEnabled&&startDiagnosticHeartbeat();let server=createServer((req,res)=>{if(req.url===healthPath){res.writeHead(200),res.end(`ok`);return}if(req.url!==path||req.method!==`POST`){res.writeHead(404),res.end();return}let startTime=Date.now();diagnosticsEnabled&&logWebhookReceived({channel:`telegram`,updateType:`telegram-post`});let guard=installRequestBodyLimitGuard(req,res,{maxBytes:1048576,timeoutMs:3e4,responseFormat:`text`});if(guard.isTripped())return;let handled=handler(req,res);if(handled&&typeof handled.catch==`function`){handled.then(()=>{diagnosticsEnabled&&logWebhookProcessed({channel:`telegram`,updateType:`telegram-post`,durationMs:Date.now()-startTime})}).catch(err=>{if(guard.isTripped())return;let errMsg=formatErrorMessage(err);diagnosticsEnabled&&logWebhookError({channel:`telegram`,updateType:`telegram-post`,error:errMsg}),runtime.log?.(`webhook handler failed: ${errMsg}`),res.headersSent||res.writeHead(500),res.end()}).finally(()=>{guard.dispose()});return}guard.dispose()}),publicUrl=opts.publicUrl??`http://${host===`0.0.0.0`?`localhost`:host}:${port}${path}`;await withTelegramApiErrorLogging({operation:`setWebhook`,runtime,fn:()=>bot.api.setWebhook(publicUrl,{secret_token:secret,allowed_updates:resolveTelegramAllowedUpdates()})}),await new Promise(resolve=>server.listen(port,host,resolve)),runtime.log?.(`webhook listening on ${publicUrl}`);let shutdown=()=>{server.close(),bot.stop(),diagnosticsEnabled&&stopDiagnosticHeartbeat()};return opts.abortSignal&&opts.abortSignal.addEventListener(`abort`,shutdown,{once:!0}),{server,bot,stop:shutdown}}function createTelegramRunnerOptions(cfg){return{sink:{concurrency:resolveAgentMaxConcurrent(cfg)},runner:{fetch:{timeout:30,allowed_updates:resolveTelegramAllowedUpdates()},silent:!0,maxRetryTime:300*1e3,retryInterval:`exponential`}}}const TELEGRAM_POLL_RESTART_POLICY={initialMs:2e3,maxMs:3e4,factor:1.8,jitter:.25},isGetUpdatesConflict=err=>{if(!err||typeof err!=`object`)return!1;let typed=err;return(typed.error_code??typed.errorCode)===409?[typed.method,typed.description,typed.message].filter(value=>typeof value==`string`).join(` `).toLowerCase().includes(`getupdates`):!1},isGrammyHttpError=err=>!err||typeof err!=`object`?!1:err.name===`HttpError`;async function monitorTelegramProvider(opts={}){let log=opts.runtime?.error??console.error,unregisterHandler=registerUnhandledRejectionHandler(err=>isGrammyHttpError(err)&&isRecoverableTelegramNetworkError(err,{context:`polling`})?(log(`[telegram] Suppressed network error: ${formatErrorMessage(err)}`),!0):!1);try{let cfg=opts.config??loadConfig(),account=resolveTelegramAccount({cfg,accountId:opts.accountId}),token=opts.token?.trim()||account.token;if(!token)throw Error(`Telegram bot token missing for account "${account.accountId}" (set channels.telegram.accounts.${account.accountId}.botToken/tokenFile or TELEGRAM_BOT_TOKEN for default).`);let proxyFetch=opts.proxyFetch??(account.config.proxy?makeProxyFetch(account.config.proxy):void 0),lastUpdateId=await readTelegramUpdateOffset({accountId:account.accountId}),bot=createTelegramBot({token,runtime:opts.runtime,proxyFetch,config:cfg,accountId:account.accountId,updateOffset:{lastUpdateId,onUpdateId:async updateId=>{if(!(lastUpdateId!==null&&updateId<=lastUpdateId)){lastUpdateId=updateId;try{await writeTelegramUpdateOffset({accountId:account.accountId,updateId})}catch(err){(opts.runtime?.error??console.error)(`telegram: failed to persist update offset: ${String(err)}`)}}}}});if(opts.useWebhook){await startTelegramWebhook({token,accountId:account.accountId,config:cfg,path:opts.webhookPath,port:opts.webhookPort,secret:opts.webhookSecret??account.config.webhookSecret,host:opts.webhookHost??account.config.webhookHost,runtime:opts.runtime,fetch:proxyFetch,abortSignal:opts.abortSignal,publicUrl:opts.webhookUrl});return}let restartAttempts=0;for(;!opts.abortSignal?.aborted;){let runner=run(bot,createTelegramRunnerOptions(cfg)),stopOnAbort=()=>{opts.abortSignal?.aborted&&runner.stop()};opts.abortSignal?.addEventListener(`abort`,stopOnAbort,{once:!0});try{await runner.task();return}catch(err){if(opts.abortSignal?.aborted)throw err;let isConflict=isGetUpdatesConflict(err),isRecoverable=isRecoverableTelegramNetworkError(err,{context:`polling`});if(!isConflict&&!isRecoverable)throw err;restartAttempts+=1;let delayMs=computeBackoff(TELEGRAM_POLL_RESTART_POLICY,restartAttempts),reason=isConflict?`getUpdates conflict`:`network error`,errMsg=formatErrorMessage(err);(opts.runtime?.error??console.error)(`Telegram ${reason}: ${errMsg}; retrying in ${formatDurationPrecise(delayMs)}.`);try{await sleepWithAbort(delayMs,opts.abortSignal)}catch(sleepErr){if(opts.abortSignal?.aborted)return;throw sleepErr}}finally{opts.abortSignal?.removeEventListener(`abort`,stopOnAbort)}}}finally{unregisterHandler()}}async function probeTelegram(token,timeoutMs,proxyUrl){let started=Date.now(),fetcher=proxyUrl?makeProxyFetch(proxyUrl):fetch,base=`https://api.telegram.org/bot${token}`,retryDelayMs=Math.max(50,Math.min(1e3,timeoutMs)),result={ok:!1,status:null,error:null,elapsedMs:0};try{let meRes=null,fetchError=null;for(let i=0;i<3;i++)try{meRes=await fetchWithTimeout(`${base}/getMe`,{},timeoutMs,fetcher);break}catch(err){fetchError=err,i<2&&await new Promise(resolve=>setTimeout(resolve,retryDelayMs))}if(!meRes)throw fetchError;let meJson=await meRes.json();if(!meRes.ok||!meJson?.ok)return result.status=meRes.status,result.error=meJson?.description??`getMe failed (${meRes.status})`,{...result,elapsedMs:Date.now()-started};result.bot={id:meJson.result?.id??null,username:meJson.result?.username??null,canJoinGroups:typeof meJson.result?.can_join_groups==`boolean`?meJson.result?.can_join_groups:null,canReadAllGroupMessages:typeof meJson.result?.can_read_all_group_messages==`boolean`?meJson.result?.can_read_all_group_messages:null,supportsInlineQueries:typeof meJson.result?.supports_inline_queries==`boolean`?meJson.result?.supports_inline_queries:null};try{let webhookRes=await fetchWithTimeout(`${base}/getWebhookInfo`,{},timeoutMs,fetcher),webhookJson=await webhookRes.json();webhookRes.ok&&webhookJson?.ok&&(result.webhook={url:webhookJson.result?.url??null,hasCustomCert:webhookJson.result?.has_custom_certificate??null})}catch{}return result.ok=!0,result.status=null,result.error=null,result.elapsedMs=Date.now()-started,result}catch(err){return{...result,status:err instanceof Response?err.status:result.status,error:err instanceof Error?err.message:String(err),elapsedMs:Date.now()-started}}}function formatNativeDependencyHint(params){let manager=params.manager??`pnpm`,rebuildCommand=params.rebuildCommand??(manager===`npm`?`npm rebuild ${params.packageName}`:manager===`yarn`?`yarn rebuild ${params.packageName}`:`pnpm rebuild ${params.packageName}`),steps=[params.approveBuildsCommand??(manager===`pnpm`?`pnpm approve-builds (select ${params.packageName})`:void 0),rebuildCommand,params.downloadCommand].filter(step=>!!step);return steps.length===0?`Install ${params.packageName} and rebuild its native module.`:`Install ${params.packageName} and rebuild its native module (${steps.join(`; `)}).`}let cachedVersion=null;function resolveVersion(){if(cachedVersion)return cachedVersion;try{return cachedVersion=createRequire(import.meta.url)(`../../../package.json`).version??`unknown`,cachedVersion}catch{return cachedVersion=`unknown`,cachedVersion}}const sendMessageWhatsAppLazy=async(...args)=>{let{sendMessageWhatsApp}=await loadWebOutbound();return sendMessageWhatsApp(...args)},sendPollWhatsAppLazy=async(...args)=>{let{sendPollWhatsApp}=await loadWebOutbound();return sendPollWhatsApp(...args)},loginWebLazy=async(...args)=>{let{loginWeb}=await loadWebLogin();return loginWeb(...args)},startWebLoginWithQrLazy=async(...args)=>{let{startWebLoginWithQr}=await loadWebLoginQr();return startWebLoginWithQr(...args)},waitForWebLoginLazy=async(...args)=>{let{waitForWebLogin}=await loadWebLoginQr();return waitForWebLogin(...args)},monitorWebChannelLazy=async(...args)=>{let{monitorWebChannel}=await loadWebChannel();return monitorWebChannel(...args)},handleWhatsAppActionLazy=async(...args)=>{let{handleWhatsAppAction}=await loadWhatsAppActions();return handleWhatsAppAction(...args)};let webOutboundPromise=null,webLoginPromise=null,webLoginQrPromise=null,webChannelPromise=null,whatsappActionsPromise=null;function loadWebOutbound(){return webOutboundPromise??=import(`./outbound-BdeHcMAo.js`),webOutboundPromise}function loadWebLogin(){return webLoginPromise??=import(`./login-B3sDAgHb.js`),webLoginPromise}function loadWebLoginQr(){return webLoginQrPromise??=import(`./login-qr-CbiUcBLy.js`),webLoginQrPromise}function loadWebChannel(){return webChannelPromise??=import(`./web-BXLk9UT2.js`),webChannelPromise}function loadWhatsAppActions(){return whatsappActionsPromise??=import(`./whatsapp-actions-B7r9AyZN.js`),whatsappActionsPromise}function createPluginRuntime(){return{version:resolveVersion(),config:{loadConfig,writeConfigFile},system:{enqueueSystemEvent,runCommandWithTimeout,formatNativeDependencyHint},media:{loadWebMedia,detectMime,mediaKindFromMime,isVoiceCompatibleAudio,getImageMetadata,resizeToJpeg},tts:{textToSpeechTelephony},tools:{createMemoryGetTool,createMemorySearchTool,registerMemoryCli},channel:{text:{chunkByNewline,chunkMarkdownText,chunkMarkdownTextWithMode,chunkText,chunkTextWithMode,resolveChunkMode,resolveTextChunkLimit,hasControlCommand,resolveMarkdownTableMode,convertMarkdownTables},reply:{dispatchReplyWithBufferedBlockDispatcher,createReplyDispatcherWithTyping,resolveEffectiveMessagesConfig,resolveHumanDelayConfig,dispatchReplyFromConfig,finalizeInboundContext,formatAgentEnvelope,formatInboundEnvelope,resolveEnvelopeFormatOptions},routing:{resolveAgentRoute},pairing:{buildPairingReply,readAllowFromStore:readChannelAllowFromStore,upsertPairingRequest:upsertChannelPairingRequest},media:{fetchRemoteMedia,saveMediaBuffer},activity:{record:recordChannelActivity,get:getChannelActivity},session:{resolveStorePath,readSessionUpdatedAt,recordSessionMetaFromInbound,recordInboundSession,updateLastRoute},mentions:{buildMentionRegexes,matchesMentionPatterns,matchesMentionWithExplicit},reactions:{shouldAckReaction,removeAckReactionAfterReply},groups:{resolveGroupPolicy:resolveChannelGroupPolicy,resolveRequireMention:resolveChannelGroupRequireMention},debounce:{createInboundDebouncer,resolveInboundDebounceMs},commands:{resolveCommandAuthorizedFromAuthorizers,isControlCommandMessage,shouldComputeCommandAuthorized,shouldHandleTextCommands},discord:{messageActions:discordMessageActions,auditChannelPermissions:auditDiscordChannelPermissions,listDirectoryGroupsLive:listDiscordDirectoryGroupsLive,listDirectoryPeersLive:listDiscordDirectoryPeersLive,probeDiscord,resolveChannelAllowlist:resolveDiscordChannelAllowlist,resolveUserAllowlist:resolveDiscordUserAllowlist,sendMessageDiscord,sendPollDiscord,monitorDiscordProvider},slack:{listDirectoryGroupsLive:listSlackDirectoryGroupsLive,listDirectoryPeersLive:listSlackDirectoryPeersLive,probeSlack,resolveChannelAllowlist:resolveSlackChannelAllowlist,resolveUserAllowlist:resolveSlackUserAllowlist,sendMessageSlack,monitorSlackProvider,handleSlackAction},telegram:{auditGroupMembership:auditTelegramGroupMembership,collectUnmentionedGroupIds:collectTelegramUnmentionedGroupIds,probeTelegram,resolveTelegramToken,sendMessageTelegram,sendPollTelegram,monitorTelegramProvider,messageActions:telegramMessageActions},signal:{probeSignal,sendMessageSignal,monitorSignalProvider,messageActions:signalMessageActions},imessage:{monitorIMessageProvider,probeIMessage,sendMessageIMessage},whatsapp:{getActiveWebListener,getWebAuthAgeMs,logoutWeb,logWebSelfId,readWebSelfId,webAuthExists,sendMessageWhatsApp:sendMessageWhatsAppLazy,sendPollWhatsApp:sendPollWhatsAppLazy,loginWeb:loginWebLazy,startWebLoginWithQr:startWebLoginWithQrLazy,waitForWebLogin:waitForWebLoginLazy,monitorWebChannel:monitorWebChannelLazy,handleWhatsAppAction:handleWhatsAppActionLazy,createLoginTool:createWhatsAppLoginTool},line:{listLineAccountIds,resolveDefaultLineAccountId,resolveLineAccount,normalizeAccountId:normalizeAccountId$1,probeLineBot,sendMessageLine,pushMessageLine,pushMessagesLine,pushFlexMessage,pushTemplateMessage,pushLocationMessage,pushTextMessageWithQuickReplies,createQuickReplyItems,buildTemplateMessageFromPayload,monitorLineProvider}},logging:{shouldLogVerbose,getChildLogger:(bindings,opts)=>{let logger=getChildLogger(bindings,{level:opts?.level?normalizeLogLevel(opts.level):void 0});return{debug:message=>logger.debug?.(message),info:message=>logger.info(message),warn:message=>logger.warn(message),error:message=>logger.error(message)}}},state:{resolveStateDir}}}const registryCache=new Map,defaultLogger=()=>createSubsystemLogger(`plugins`),resolvePluginSdkAliasFile=params=>{try{let modulePath=fileURLToPath(import.meta.url),isTest=process.env.VITEST||!1,cursor=path.dirname(modulePath);for(let i=0;i<6;i+=1){let srcCandidate=path.join(cursor,`src`,`plugin-sdk`,params.srcFile),distCandidate=path.join(cursor,`dist`,`plugin-sdk`,params.distFile),orderedCandidates=isTest?[distCandidate,srcCandidate]:[distCandidate];for(let candidate of orderedCandidates)if(fs.existsSync(candidate))return candidate;let parent=path.dirname(cursor);if(parent===cursor)break;cursor=parent}}catch{}return null},resolvePluginSdkAlias=()=>resolvePluginSdkAliasFile({srcFile:`index.ts`,distFile:`index.js`}),resolvePluginSdkAccountIdAlias=()=>resolvePluginSdkAliasFile({srcFile:`account-id.ts`,distFile:`account-id.js`});function buildCacheKey(params){return`${params.workspaceDir?resolveUserPath(params.workspaceDir):``}::${JSON.stringify(params.plugins)}`}function validatePluginConfig(params){let schema=params.schema;if(!schema)return{ok:!0,value:params.value};let result=validateJsonSchemaValue({schema,cacheKey:params.cacheKey??JSON.stringify(schema),value:params.value??{}});return result.ok?{ok:!0,value:params.value}:{ok:!1,errors:result.errors}}function resolvePluginModuleExport(moduleExport){let resolved=moduleExport&&typeof moduleExport==`object`&&`default`in moduleExport?moduleExport.default:moduleExport;if(typeof resolved==`function`)return{register:resolved};if(resolved&&typeof resolved==`object`){let def=resolved;return{definition:def,register:def.register??def.activate}}return{}}function createPluginRecord(params){return{id:params.id,name:params.name??params.id,description:params.description,version:params.version,source:params.source,origin:params.origin,workspaceDir:params.workspaceDir,enabled:params.enabled,status:params.enabled?`loaded`:`disabled`,toolNames:[],hookNames:[],channelIds:[],providerIds:[],gatewayMethods:[],cliCommands:[],services:[],commands:[],httpHandlers:0,hookCount:0,configSchema:params.configSchema,configUiHints:void 0,configJsonSchema:void 0}}function pushDiagnostics(diagnostics,append){diagnostics.push(...append)}function registerManifestHookDirs(params){for(let hookDir of params.hookDirs){let resolvedDir=path.resolve(params.rootDir,hookDir);registerPluginHooksFromDir(params.api,resolvedDir).then(hookResult=>{for(let message of hookResult.errors)params.diagnostics.push({level:`warn`,pluginId:params.record.id,source:params.record.source,message})}).catch(err=>{params.logger.warn(`[plugins] ${params.record.id} failed loading hooks from ${resolvedDir}: ${String(err)}`)})}}function loadBuilderForceAgentsPlugins(options={}){let cfg=applyTestPluginDefaults(options.config??{},process.env),logger=options.logger??defaultLogger(),validateOnly=options.mode===`validate`,normalized=normalizePluginsConfig(cfg.plugins),cacheKey=buildCacheKey({workspaceDir:options.workspaceDir,plugins:normalized}),cacheEnabled=options.cache!==!1;if(cacheEnabled){let cached=registryCache.get(cacheKey);if(cached)return setActivePluginRegistry(cached,cacheKey),cached}clearPluginCommands();let{registry,createApi}=createPluginRegistry({logger,runtime:createPluginRuntime(),coreGatewayHandlers:options.coreGatewayHandlers}),discovery=discoverBuilderForceAgentsPlugins({workspaceDir:options.workspaceDir,extraPaths:normalized.loadPaths}),manifestRegistry=loadPluginManifestRegistry({config:cfg,workspaceDir:options.workspaceDir,cache:options.cache,candidates:discovery.candidates,diagnostics:discovery.diagnostics});pushDiagnostics(registry.diagnostics,manifestRegistry.diagnostics);let jitiLoader=null,getJiti=()=>{if(jitiLoader)return jitiLoader;let pluginSdkAlias=resolvePluginSdkAlias(),pluginSdkAccountIdAlias=resolvePluginSdkAccountIdAlias();return jitiLoader=createJiti(import.meta.url,{interopDefault:!0,extensions:[`.ts`,`.tsx`,`.mts`,`.cts`,`.mtsx`,`.ctsx`,`.js`,`.mjs`,`.cjs`,`.json`],...pluginSdkAlias||pluginSdkAccountIdAlias?{alias:{...pluginSdkAlias?{"@seanhogg/builderforce-agents/plugin-sdk":pluginSdkAlias}:{},...pluginSdkAccountIdAlias?{"@seanhogg/builderforce-agents/plugin-sdk/account-id":pluginSdkAccountIdAlias}:{}}}:{}}),jitiLoader},manifestByRoot=new Map(manifestRegistry.plugins.map(record=>[record.rootDir,record])),seenIds=new Map,memorySlot=normalized.slots.memory,selectedMemoryPluginId=null,memorySlotMatched=!1;for(let candidate of discovery.candidates){let manifestRecord=manifestByRoot.get(candidate.rootDir);if(!manifestRecord)continue;let pluginId=manifestRecord.id,existingOrigin=seenIds.get(pluginId);if(existingOrigin){let record=createPluginRecord({id:pluginId,name:manifestRecord.name??pluginId,description:manifestRecord.description,version:manifestRecord.version,source:candidate.source,origin:candidate.origin,workspaceDir:candidate.workspaceDir,enabled:!1,configSchema:!!manifestRecord.configSchema});record.status=`disabled`,record.error=`overridden by ${existingOrigin} plugin`,registry.plugins.push(record);continue}let enableState=resolveEnableState(pluginId,candidate.origin,normalized),entry=normalized.entries[pluginId],record=createPluginRecord({id:pluginId,name:manifestRecord.name??pluginId,description:manifestRecord.description,version:manifestRecord.version,source:candidate.source,origin:candidate.origin,workspaceDir:candidate.workspaceDir,enabled:enableState.enabled,configSchema:!!manifestRecord.configSchema});if(record.kind=manifestRecord.kind,record.configUiHints=manifestRecord.configUiHints,record.configJsonSchema=manifestRecord.configSchema,!enableState.enabled){record.status=`disabled`,record.error=enableState.reason,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin);continue}if(!manifestRecord.configSchema){record.status=`error`,record.error=`missing config schema`,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:record.error});continue}let mod=null;try{mod=getJiti()(candidate.source)}catch(err){logger.error(`[plugins] ${record.id} failed to load from ${record.source}: ${String(err)}`),record.status=`error`,record.error=String(err),registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:`failed to load plugin: ${String(err)}`});continue}let resolved=resolvePluginModuleExport(mod),definition=resolved.definition,register=resolved.register;definition?.id&&definition.id!==record.id&&registry.diagnostics.push({level:`warn`,pluginId:record.id,source:record.source,message:`plugin id mismatch (config uses "${record.id}", export uses "${definition.id}")`}),record.name=definition?.name??record.name,record.description=definition?.description??record.description,record.version=definition?.version??record.version;let manifestKind=record.kind,exportKind=definition?.kind;manifestKind&&exportKind&&exportKind!==manifestKind&&registry.diagnostics.push({level:`warn`,pluginId:record.id,source:record.source,message:`plugin kind mismatch (manifest uses "${manifestKind}", export uses "${exportKind}")`}),record.kind=definition?.kind??record.kind,record.kind===`memory`&&memorySlot===record.id&&(memorySlotMatched=!0);let memoryDecision=resolveMemorySlotDecision({id:record.id,kind:record.kind,slot:memorySlot,selectedId:selectedMemoryPluginId});if(!memoryDecision.enabled){record.enabled=!1,record.status=`disabled`,record.error=memoryDecision.reason,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin);continue}memoryDecision.selected&&record.kind===`memory`&&(selectedMemoryPluginId=record.id);let validatedConfig=validatePluginConfig({schema:manifestRecord.configSchema,cacheKey:manifestRecord.schemaCacheKey,value:entry?.config});if(!validatedConfig.ok){logger.error(`[plugins] ${record.id} invalid config: ${validatedConfig.errors?.join(`, `)}`),record.status=`error`,record.error=`invalid config: ${validatedConfig.errors?.join(`, `)}`,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:record.error});continue}if(validateOnly){registry.plugins.push(record),seenIds.set(pluginId,candidate.origin);continue}if(typeof register!=`function`){logger.error(`[plugins] ${record.id} missing register/activate export`),record.status=`error`,record.error=`plugin export missing register/activate`,registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:record.error});continue}let api=createApi(record,{config:cfg,pluginConfig:validatedConfig.value});try{let result=register(api);result&&typeof result.then==`function`&&registry.diagnostics.push({level:`warn`,pluginId:record.id,source:record.source,message:`plugin register returned a promise; async registration is ignored`}),registerManifestHookDirs({api,record,rootDir:manifestRecord.rootDir,hookDirs:manifestRecord.hooks,diagnostics:registry.diagnostics,logger}),registry.plugins.push(record),seenIds.set(pluginId,candidate.origin)}catch(err){logger.error(`[plugins] ${record.id} failed during register from ${record.source}: ${String(err)}`),record.status=`error`,record.error=String(err),registry.plugins.push(record),seenIds.set(pluginId,candidate.origin),registry.diagnostics.push({level:`error`,pluginId:record.id,source:record.source,message:`plugin failed during register: ${String(err)}`})}}return typeof memorySlot==`string`&&!memorySlotMatched&&registry.diagnostics.push({level:`warn`,message:`memory slot plugin not found or not marked as memory: ${memorySlot}`}),cacheEnabled&&registryCache.set(cacheKey,registry),setActivePluginRegistry(registry,cacheKey),initializeGlobalHookRunner(registry),registry}function createPluginLoaderLogger(logger){return{info:msg=>logger.info(msg),warn:msg=>logger.warn(msg),error:msg=>logger.error(msg),debug:msg=>logger.debug?.(msg)}}const log$5=createSubsystemLogger(`plugins`),pluginToolMeta=new WeakMap;function getPluginToolMeta(tool){return pluginToolMeta.get(tool)}function normalizeAllowlist(list){return new Set((list??[]).map(normalizeToolName).filter(Boolean))}function isOptionalToolAllowed(params){if(params.allowlist.size===0)return!1;let toolName=normalizeToolName(params.toolName);if(params.allowlist.has(toolName))return!0;let pluginKey=normalizeToolName(params.pluginId);return params.allowlist.has(pluginKey)?!0:params.allowlist.has(`group:plugins`)}function resolvePluginTools(params){let effectiveConfig=applyTestPluginDefaults(params.context.config??{},process.env);if(!normalizePluginsConfig(effectiveConfig.plugins).enabled)return[];let registry=loadBuilderForceAgentsPlugins({config:effectiveConfig,workspaceDir:params.context.workspaceDir,logger:createPluginLoaderLogger(log$5)}),tools=[],existing=params.existingToolNames??new Set,existingNormalized=new Set(Array.from(existing,tool=>normalizeToolName(tool))),allowlist=normalizeAllowlist(params.toolAllowlist),blockedPlugins=new Set;for(let entry of registry.tools){if(blockedPlugins.has(entry.pluginId))continue;let pluginIdKey=normalizeToolName(entry.pluginId);if(existingNormalized.has(pluginIdKey)){let message=`plugin id conflicts with core tool name (${entry.pluginId})`;log$5.error(message),registry.diagnostics.push({level:`error`,pluginId:entry.pluginId,source:entry.source,message}),blockedPlugins.add(entry.pluginId);continue}let resolved=null;try{resolved=entry.factory(params.context)}catch(err){log$5.error(`plugin tool failed (${entry.pluginId}): ${String(err)}`);continue}if(!resolved)continue;let listRaw=Array.isArray(resolved)?resolved:[resolved],list=entry.optional?listRaw.filter(tool=>isOptionalToolAllowed({toolName:tool.name,pluginId:entry.pluginId,allowlist})):listRaw;if(list.length===0)continue;let nameSet=new Set;for(let tool of list){if(nameSet.has(tool.name)||existing.has(tool.name)){let message=`plugin tool name conflict (${entry.pluginId}): ${tool.name}`;log$5.error(message),registry.diagnostics.push({level:`error`,pluginId:entry.pluginId,source:entry.source,message});continue}nameSet.add(tool.name),existing.add(tool.name),pluginToolMeta.set(tool,{pluginId:entry.pluginId,optional:entry.optional}),tools.push(tool)}}return tools}async function defaultReadFile(filePath){return fs$1.readFile(filePath,`utf8`)}async function applyUpdateHunk(filePath,chunks,options){let originalLines=(await(options?.readFile??defaultReadFile)(filePath).catch(err=>{throw Error(`Failed to read file to update ${filePath}: ${err}`)})).split(`
495
495
  `);originalLines.length>0&&originalLines[originalLines.length-1]===``&&originalLines.pop();let newLines=applyReplacements(originalLines,computeReplacements(originalLines,filePath,chunks));return(newLines.length===0||newLines[newLines.length-1]!==``)&&(newLines=[...newLines,``]),newLines.join(`
496
496
  `)}function computeReplacements(originalLines,filePath,chunks){let replacements=[],lineIndex=0;for(let chunk of chunks){if(chunk.changeContext){let ctxIndex=seekSequence(originalLines,[chunk.changeContext],lineIndex,!1);if(ctxIndex===null)throw Error(`Failed to find context '${chunk.changeContext}' in ${filePath}`);lineIndex=ctxIndex+1}if(chunk.oldLines.length===0){let insertionIndex=originalLines.length>0&&originalLines[originalLines.length-1]===``?originalLines.length-1:originalLines.length;replacements.push([insertionIndex,0,chunk.newLines]);continue}let pattern=chunk.oldLines,newSlice=chunk.newLines,found=seekSequence(originalLines,pattern,lineIndex,chunk.isEndOfFile);if(found===null&&pattern[pattern.length-1]===``&&(pattern=pattern.slice(0,-1),newSlice.length>0&&newSlice[newSlice.length-1]===``&&(newSlice=newSlice.slice(0,-1)),found=seekSequence(originalLines,pattern,lineIndex,chunk.isEndOfFile)),found===null)throw Error(`Failed to find expected lines in ${filePath}:\n${chunk.oldLines.join(`
497
497
  `)}`);replacements.push([found,pattern.length,newSlice]),lineIndex=found+pattern.length}return replacements.sort((a,b)=>a[0]-b[0]),replacements}function applyReplacements(lines,replacements){let result=[...lines];for(let[startIndex,oldLen,newLines]of[...replacements].toReversed()){for(let i=0;i<oldLen;i+=1)startIndex<result.length&&result.splice(startIndex,1);for(let i=0;i<newLines.length;i+=1)result.splice(startIndex+i,0,newLines[i])}return result}function seekSequence(lines,pattern,start,eof){if(pattern.length===0)return start;if(pattern.length>lines.length)return null;let maxStart=lines.length-pattern.length,searchStart=eof&&lines.length>=pattern.length?maxStart:start;if(searchStart>maxStart)return null;for(let i=searchStart;i<=maxStart;i+=1)if(linesMatch(lines,pattern,i,value=>value))return i;for(let i=searchStart;i<=maxStart;i+=1)if(linesMatch(lines,pattern,i,value=>value.trimEnd()))return i;for(let i=searchStart;i<=maxStart;i+=1)if(linesMatch(lines,pattern,i,value=>value.trim()))return i;for(let i=searchStart;i<=maxStart;i+=1)if(linesMatch(lines,pattern,i,value=>normalizePunctuation(value.trim())))return i;return null}function linesMatch(lines,pattern,start,normalize){for(let idx=0;idx<pattern.length;idx+=1)if(normalize(lines[start+idx])!==normalize(pattern[idx]))return!1;return!0}function normalizePunctuation(value){return Array.from(value).map(char=>{switch(char){case`‐`:case`‑`:case`‒`:case`–`:case`—`:case`―`:case`−`:return`-`;case`‘`:case`’`:case`‚`:case`‛`:return`'`;case`“`:case`”`:case`„`:case`‟`:return`"`;case`\xA0`:case` `:case` `:case` `:case` `:case` `:case` `:case` `:case` `:case` `:case` `:case` `:case` `:return` `;default:return char}}).join(``)}const BEGIN_PATCH_MARKER=`*** Begin Patch`,applyPatchSchema=Type.Object({input:Type.String({description:`Patch content using the *** Begin Patch/End Patch format.`})});function createApplyPatchTool(options={}){let cwd=options.cwd??process.cwd(),sandbox=options.sandbox,workspaceOnly=options.workspaceOnly!==!1;return{name:`apply_patch`,label:`apply_patch`,description:`Apply a patch to one or more files using the apply_patch format. The input should include *** Begin Patch and *** End Patch markers.`,parameters:applyPatchSchema,execute:async(_toolCallId,args,signal)=>{let params=args,input=typeof params.input==`string`?params.input:``;if(!input.trim())throw Error(`Provide a patch input.`);if(signal?.aborted){let err=Error(`Aborted`);throw err.name=`AbortError`,err}let result=await applyPatch(input,{cwd,sandbox,workspaceOnly,signal});return{content:[{type:`text`,text:result.text}],details:{summary:result.summary}}}}}async function applyPatch(input,options){let parsed=parsePatchText(input);if(parsed.hunks.length===0)throw Error(`No files were modified.`);let summary={added:[],modified:[],deleted:[]},seen={added:new Set,modified:new Set,deleted:new Set},fileOps=resolvePatchFileOps(options);for(let hunk of parsed.hunks){if(options.signal?.aborted){let err=Error(`Aborted`);throw err.name=`AbortError`,err}if(hunk.kind===`add`){let target=await resolvePatchPath(hunk.path,options);await ensureDir(target.resolved,fileOps),await fileOps.writeFile(target.resolved,hunk.contents),recordSummary(summary,seen,`added`,target.display);continue}if(hunk.kind===`delete`){let target=await resolvePatchPath(hunk.path,options,`unlink`);await fileOps.remove(target.resolved),recordSummary(summary,seen,`deleted`,target.display);continue}let target=await resolvePatchPath(hunk.path,options),applied=await applyUpdateHunk(target.resolved,hunk.chunks,{readFile:path=>fileOps.readFile(path)});if(hunk.movePath){let moveTarget=await resolvePatchPath(hunk.movePath,options);await ensureDir(moveTarget.resolved,fileOps),await fileOps.writeFile(moveTarget.resolved,applied),await fileOps.remove(target.resolved),recordSummary(summary,seen,`modified`,moveTarget.display)}else await fileOps.writeFile(target.resolved,applied),recordSummary(summary,seen,`modified`,target.display)}return{summary,text:formatSummary(summary)}}function recordSummary(summary,seen,bucket,value){seen[bucket].has(value)||(seen[bucket].add(value),summary[bucket].push(value))}function formatSummary(summary){let lines=[`Success. Updated the following files:`];for(let file of summary.added)lines.push(`A ${file}`);for(let file of summary.modified)lines.push(`M ${file}`);for(let file of summary.deleted)lines.push(`D ${file}`);return lines.join(`
@@ -512,7 +512,7 @@ Critical rules from AGENTS.md:
512
512
  ⚠️ [Content truncated — original was too large for the model's context window. The content above is a partial view. If you need more, request specific sections or use offset/limit parameters to read smaller chunks.]`}function calculateMaxToolResultChars(contextWindowTokens){let maxChars=Math.floor(contextWindowTokens*.3)*4;return Math.min(maxChars,HARD_MAX_TOOL_RESULT_CHARS)}function getToolResultTextLength(msg){if(!msg||msg.role!==`toolResult`)return 0;let content=msg.content;if(!Array.isArray(content))return 0;let totalLength=0;for(let block of content)if(block&&typeof block==`object`&&block.type===`text`){let text=block.text;typeof text==`string`&&(totalLength+=text.length)}return totalLength}function truncateToolResultMessage(msg,maxChars){let content=msg.content;if(!Array.isArray(content))return msg;let totalTextChars=getToolResultTextLength(msg);if(totalTextChars<=maxChars)return msg;let newContent=content.map(block=>{if(!block||typeof block!=`object`||block.type!==`text`)return block;let textBlock=block;if(typeof textBlock.text!=`string`)return block;let blockShare=textBlock.text.length/totalTextChars,blockBudget=Math.max(MIN_KEEP_CHARS,Math.floor(maxChars*blockShare));return{...textBlock,text:truncateToolResultText(textBlock.text,blockBudget)}});return{...msg,content:newContent}}async function truncateOversizedToolResultsInSession(params){let{sessionFile,contextWindowTokens}=params,maxChars=calculateMaxToolResultChars(contextWindowTokens);try{let sessionManager=SessionManager.open(sessionFile),branch=sessionManager.getBranch();if(branch.length===0)return{truncated:!1,truncatedCount:0,reason:`empty session`};let oversizedIndices=[];for(let i=0;i<branch.length;i++){let entry=branch[i];if(entry.type!==`message`)continue;let msg=entry.message;if(msg.role!==`toolResult`)continue;let textLength=getToolResultTextLength(msg);textLength>maxChars&&(oversizedIndices.push(i),log$3.info(`[tool-result-truncation] Found oversized tool result: entry=${entry.id} chars=${textLength} maxChars=${maxChars} sessionKey=${params.sessionKey??params.sessionId??`unknown`}`))}if(oversizedIndices.length===0)return{truncated:!1,truncatedCount:0,reason:`no oversized tool results`};let firstOversizedIdx=oversizedIndices[0],branchFromId=branch[firstOversizedIdx].parentId;branchFromId?sessionManager.branch(branchFromId):sessionManager.resetLeaf();let oversizedSet=new Set(oversizedIndices),truncatedCount=0;for(let i=firstOversizedIdx;i<branch.length;i++){let entry=branch[i];if(entry.type===`message`){let message=entry.message;if(oversizedSet.has(i)){message=truncateToolResultMessage(message,maxChars),truncatedCount++;let newLength=getToolResultTextLength(message);log$3.info(`[tool-result-truncation] Truncated tool result: originalEntry=${entry.id} newChars=${newLength} sessionKey=${params.sessionKey??params.sessionId??`unknown`}`)}sessionManager.appendMessage(message)}else if(entry.type===`compaction`)sessionManager.appendCompaction(entry.summary,entry.firstKeptEntryId,entry.tokensBefore,entry.details,entry.fromHook);else if(entry.type===`thinking_level_change`)sessionManager.appendThinkingLevelChange(entry.thinkingLevel);else if(entry.type===`model_change`)sessionManager.appendModelChange(entry.provider,entry.modelId);else if(entry.type===`custom`)sessionManager.appendCustomEntry(entry.customType,entry.data);else if(entry.type===`custom_message`)sessionManager.appendCustomMessageEntry(entry.customType,entry.content,entry.display,entry.details);else if(entry.type===`branch_summary`)continue;else if(entry.type===`label`)continue;else entry.type===`session_info`&&entry.name&&sessionManager.appendSessionInfo(entry.name)}return log$3.info(`[tool-result-truncation] Truncated ${truncatedCount} tool result(s) in session (contextWindow=${contextWindowTokens} maxChars=${maxChars}) sessionKey=${params.sessionKey??params.sessionId??`unknown`}`),{truncated:!0,truncatedCount}}catch(err){let errMsg=err instanceof Error?err.message:String(err);return log$3.warn(`[tool-result-truncation] Failed to truncate: ${errMsg}`),{truncated:!1,truncatedCount:0,reason:errMsg}}}function sessionLikelyHasOversizedToolResults(params){let{messages,contextWindowTokens}=params,maxChars=calculateMaxToolResultChars(contextWindowTokens);for(let msg of messages)if(msg.role===`toolResult`&&getToolResultTextLength(msg)>maxChars)return!0;return!1}function isToolCallBlock(block){if(!block||typeof block!=`object`)return!1;let type=block.type;return typeof type==`string`&&(type===`toolCall`||type===`toolUse`||type===`functionCall`)}function hasToolCallInput(block){let hasInput=`input`in block?block.input!==void 0&&block.input!==null:!1,hasArguments=`arguments`in block?block.arguments!==void 0&&block.arguments!==null:!1;return hasInput||hasArguments}function hasNonEmptyStringField(value){return typeof value==`string`&&value.trim().length>0}function hasToolCallId(block){return hasNonEmptyStringField(block.id)}function hasToolCallName(block){return hasNonEmptyStringField(block.name)}function makeMissingToolResult(params){return{role:`toolResult`,toolCallId:params.toolCallId,toolName:params.toolName??`unknown`,content:[{type:`text`,text:`[builderforce] missing tool result in session history; inserted synthetic error result for transcript repair.`}],isError:!0,timestamp:Date.now()}}function stripToolResultDetails(messages){let touched=!1,out=[];for(let msg of messages){if(!msg||typeof msg!=`object`||msg.role!==`toolResult`){out.push(msg);continue}if(!(`details`in msg)){out.push(msg);continue}let{details:_details,...rest}=msg;touched=!0,out.push(rest)}return touched?out:messages}function repairToolCallInputs(messages){let droppedToolCalls=0,droppedAssistantMessages=0,changed=!1,out=[];for(let msg of messages){if(!msg||typeof msg!=`object`){out.push(msg);continue}if(msg.role!==`assistant`||!Array.isArray(msg.content)){out.push(msg);continue}let nextContent=[],droppedInMessage=0;for(let block of msg.content){if(isToolCallBlock(block)&&(!hasToolCallInput(block)||!hasToolCallId(block)||!hasToolCallName(block))){droppedToolCalls+=1,droppedInMessage+=1,changed=!0;continue}nextContent.push(block)}if(droppedInMessage>0){if(nextContent.length===0){droppedAssistantMessages+=1,changed=!0;continue}out.push({...msg,content:nextContent});continue}out.push(msg)}return{messages:changed?out:messages,droppedToolCalls,droppedAssistantMessages}}function sanitizeToolCallInputs(messages){return repairToolCallInputs(messages).messages}function sanitizeToolUseResultPairing(messages){return repairToolUseResultPairing(messages).messages}function repairToolUseResultPairing(messages){let out=[],added=[],seenToolResultIds=new Set,droppedDuplicateCount=0,droppedOrphanCount=0,moved=!1,changed=!1,pushToolResult=msg=>{let id=extractToolResultId(msg);if(id&&seenToolResultIds.has(id)){droppedDuplicateCount+=1,changed=!0;return}id&&seenToolResultIds.add(id),out.push(msg)};for(let i=0;i<messages.length;i+=1){let msg=messages[i];if(!msg||typeof msg!=`object`){out.push(msg);continue}let role=msg.role;if(role!==`assistant`){role===`toolResult`?(droppedOrphanCount+=1,changed=!0):out.push(msg);continue}let assistant=msg,stopReason=assistant.stopReason;if(stopReason===`error`||stopReason===`aborted`){out.push(msg);continue}let toolCalls=extractToolCallsFromAssistant(assistant);if(toolCalls.length===0){out.push(msg);continue}let toolCallIds=new Set(toolCalls.map(t=>t.id)),spanResultsById=new Map,remainder=[],j=i+1;for(;j<messages.length;j+=1){let next=messages[j];if(!next||typeof next!=`object`){remainder.push(next);continue}let nextRole=next.role;if(nextRole===`assistant`)break;if(nextRole===`toolResult`){let toolResult=next,id=extractToolResultId(toolResult);if(id&&toolCallIds.has(id)){if(seenToolResultIds.has(id)){droppedDuplicateCount+=1,changed=!0;continue}spanResultsById.has(id)||spanResultsById.set(id,toolResult);continue}}nextRole===`toolResult`?(droppedOrphanCount+=1,changed=!0):remainder.push(next)}out.push(msg),spanResultsById.size>0&&remainder.length>0&&(moved=!0,changed=!0);for(let call of toolCalls){let existing=spanResultsById.get(call.id);if(existing)pushToolResult(existing);else{let missing=makeMissingToolResult({toolCallId:call.id,toolName:call.name});added.push(missing),changed=!0,pushToolResult(missing)}}for(let rem of remainder){if(!rem||typeof rem!=`object`){out.push(rem);continue}out.push(rem)}i=j-1}let changedOrMoved=changed||moved;return{messages:changedOrMoved?out:messages,added,droppedDuplicateCount,droppedOrphanCount,moved:changedOrMoved}}function capToolResultSize(msg){if(msg.role!==`toolResult`)return msg;let content=msg.content;if(!Array.isArray(content))return msg;let totalTextChars=0;for(let block of content)if(block&&typeof block==`object`&&block.type===`text`){let text=block.text;typeof text==`string`&&(totalTextChars+=text.length)}if(totalTextChars<=HARD_MAX_TOOL_RESULT_CHARS)return msg;let newContent=content.map(block=>{if(!block||typeof block!=`object`||block.type!==`text`)return block;let textBlock=block;if(typeof textBlock.text!=`string`)return block;let blockShare=textBlock.text.length/totalTextChars,blockBudget=Math.max(2e3,Math.floor(HARD_MAX_TOOL_RESULT_CHARS*blockShare)-151);if(textBlock.text.length<=blockBudget)return block;let cutPoint=blockBudget,lastNewline=textBlock.text.lastIndexOf(`
513
513
  `,blockBudget);return lastNewline>blockBudget*.8&&(cutPoint=lastNewline),{...textBlock,text:textBlock.text.slice(0,cutPoint)+`
514
514
 
515
- ⚠️ [Content truncated during persistence — original exceeded size limit. Use offset/limit parameters or request specific sections for large content.]`}});return{...msg,content:newContent}}function installSessionToolResultGuard(sessionManager,opts){let originalAppend=sessionManager.appendMessage.bind(sessionManager),pending=new Map,persistMessage=message=>{let transformer=opts?.transformMessageForPersistence;return transformer?transformer(message):message},persistToolResult=(message,meta)=>{let transformer=opts?.transformToolResultForPersistence;return transformer?transformer(message,meta):message},allowSyntheticToolResults=opts?.allowSyntheticToolResults??!0,beforeWrite=opts?.beforeMessageWriteHook,applyBeforeWriteHook=msg=>{if(!beforeWrite)return msg;let result=beforeWrite({message:msg});return result?.block?null:result?.message?result.message:msg},flushPendingToolResults=()=>{if(pending.size!==0){if(allowSyntheticToolResults)for(let[id,name]of pending.entries()){let flushed=applyBeforeWriteHook(persistToolResult(persistMessage(makeMissingToolResult({toolCallId:id,toolName:name})),{toolCallId:id,toolName:name,isSynthetic:!0}));flushed&&originalAppend(flushed)}pending.clear()}};return sessionManager.appendMessage=message=>{let nextMessage=message;if(message.role===`assistant`){let sanitized=sanitizeToolCallInputs([message]);if(sanitized.length===0){allowSyntheticToolResults&&pending.size>0&&flushPendingToolResults();return}nextMessage=sanitized[0]}let nextRole=nextMessage.role;if(nextRole===`toolResult`){let id=extractToolResultId(nextMessage),toolName=id?pending.get(id):void 0;id&&pending.delete(id);let persisted=applyBeforeWriteHook(persistToolResult(capToolResultSize(persistMessage(nextMessage)),{toolCallId:id??void 0,toolName,isSynthetic:!1}));return persisted?originalAppend(persisted):void 0}let toolCalls=nextRole===`assistant`?extractToolCallsFromAssistant(nextMessage):[];allowSyntheticToolResults&&(pending.size>0&&(toolCalls.length===0||nextRole!==`assistant`)&&flushPendingToolResults(),pending.size>0&&toolCalls.length>0&&flushPendingToolResults());let finalMessage=applyBeforeWriteHook(persistMessage(nextMessage));if(!finalMessage)return;let result=originalAppend(finalMessage),sessionFile=sessionManager.getSessionFile?.();if(sessionFile&&emitSessionTranscriptUpdate(sessionFile),toolCalls.length>0)for(let call of toolCalls)pending.set(call.id,call.name);return result},{flushPendingToolResults,getPendingIds:()=>Array.from(pending.keys())}}function guardSessionManager(sessionManager,opts){if(typeof sessionManager.flushPendingToolResults==`function`)return sessionManager;let hookRunner=getGlobalHookRunner(),beforeMessageWrite=hookRunner?.hasHooks(`before_message_write`)?event=>hookRunner.runBeforeMessageWrite(event,{agentId:opts?.agentId,sessionKey:opts?.sessionKey}):void 0;return sessionManager.flushPendingToolResults=installSessionToolResultGuard(sessionManager,{transformMessageForPersistence:message=>applyInputProvenanceToUserMessage(message,opts?.inputProvenance),transformToolResultForPersistence:hookRunner?.hasHooks(`tool_result_persist`)?(message,meta)=>hookRunner.runToolResultPersist({toolName:meta.toolName,toolCallId:meta.toolCallId,message,isSynthetic:meta.isSynthetic},{agentId:opts?.agentId,sessionKey:opts?.sessionKey,toolName:meta.toolName,toolCallId:meta.toolCallId})?.message??message:void 0,allowSyntheticToolResults:opts?.allowSyntheticToolResults,beforeMessageWriteHook:beforeMessageWrite}).flushPendingToolResults,sessionManager}const MISTRAL_MODEL_HINTS=[`mistral`,`mixtral`,`codestral`,`pixtral`,`devstral`,`ministral`,`mistralai`],OPENAI_MODEL_APIS=new Set([`openai`,`openai-completions`,`openai-responses`,`openai-codex-responses`]),OPENAI_PROVIDERS=new Set([`openai`,`openai-codex`]);function isOpenAiApi(modelApi){return modelApi?OPENAI_MODEL_APIS.has(modelApi):!1}function isOpenAiProvider(provider){return provider?OPENAI_PROVIDERS.has(normalizeProviderId(provider)):!1}function isAnthropicApi(modelApi,provider){return modelApi===`anthropic-messages`?!0:normalizeProviderId(provider??``)===`anthropic`}function isMistralModel(params){if(normalizeProviderId(params.provider??``)===`mistral`)return!0;let modelId=(params.modelId??``).toLowerCase();return modelId?MISTRAL_MODEL_HINTS.some(hint=>modelId.includes(hint)):!1}function resolveTranscriptPolicy(params){let provider=normalizeProviderId(params.provider??``),modelId=params.modelId??``,isGoogle=isGoogleModelApi(params.modelApi),isAnthropic=isAnthropicApi(params.modelApi,provider),isOpenAi=isOpenAiProvider(provider)||!provider&&isOpenAiApi(params.modelApi),isMistral=isMistralModel({provider,modelId}),isOpenRouterGemini=(provider===`openrouter`||provider===`opencode`)&&modelId.toLowerCase().includes(`gemini`),isAntigravityClaudeModel=isAntigravityClaude({api:params.modelApi,provider,modelId}),needsNonImageSanitize=isGoogle||isAnthropic||isMistral||isOpenRouterGemini,sanitizeToolCallIds=isGoogle||isMistral||isAnthropic;return{sanitizeMode:isOpenAi?`images-only`:needsNonImageSanitize?`full`:`images-only`,sanitizeToolCallIds:!isOpenAi&&sanitizeToolCallIds,toolCallIdMode:isMistral?`strict9`:sanitizeToolCallIds?`strict`:void 0,repairToolUseResultPairing:!isOpenAi&&(isGoogle||isAnthropic),preserveSignatures:isAntigravityClaudeModel,sanitizeThoughtSignatures:isOpenAi?void 0:isOpenRouterGemini?{allowBase64Only:!0,includeCamelCase:!0}:void 0,normalizeAntigravityThinkingBlocks:isAntigravityClaudeModel,applyGoogleTurnOrdering:!isOpenAi&&isGoogle,validateGeminiTurns:!isOpenAi&&isGoogle,validateAnthropicTurns:!isOpenAi&&isAnthropic,allowSyntheticToolResults:!isOpenAi&&(isGoogle||isAnthropic)}}const EMBEDDED_COMPACTION_TIMEOUT_MS=3e5;async function compactWithSafetyTimeout(compact,timeoutMs=EMBEDDED_COMPACTION_TIMEOUT_MS){return await withTimeout$3(()=>compact(),timeoutMs,`Compaction`)}const CONTEXT_WINDOW_HARD_MIN_TOKENS=16e3,CONTEXT_WINDOW_WARN_BELOW_TOKENS=32e3;function normalizePositiveInt(value){if(typeof value!=`number`||!Number.isFinite(value))return null;let int=Math.floor(value);return int>0?int:null}function resolveContextWindowInfo(params){let fromModelsConfig=(()=>{let providerEntry=params.cfg?.models?.providers?.[params.provider];return normalizePositiveInt((Array.isArray(providerEntry?.models)?providerEntry.models:[]).find(m=>m?.id===params.modelId)?.contextWindow)})(),fromModel=normalizePositiveInt(params.modelContextWindow),baseInfo=fromModelsConfig?{tokens:fromModelsConfig,source:`modelsConfig`}:fromModel?{tokens:fromModel,source:`model`}:{tokens:Math.floor(params.defaultTokens),source:`default`},capTokens=normalizePositiveInt(params.cfg?.agents?.defaults?.contextTokens);return capTokens&&capTokens<baseInfo.tokens?{tokens:capTokens,source:`agentContextTokens`}:baseInfo}function evaluateContextWindowGuard(params){let warnBelow=Math.max(1,Math.floor(params.warnBelowTokens??CONTEXT_WINDOW_WARN_BELOW_TOKENS)),hardMin=Math.max(1,Math.floor(params.hardMinTokens??CONTEXT_WINDOW_HARD_MIN_TOKENS)),tokens=Math.max(0,Math.floor(params.info.tokens));return{...params.info,tokens,shouldWarn:tokens>0&&tokens<warnBelow,shouldBlock:tokens>0&&tokens<hardMin}}function createSessionManagerRuntimeRegistry(){let registry=new WeakMap;return{set:(sessionManager,value)=>{if(!sessionManager||typeof sessionManager!=`object`)return;let key=sessionManager;if(value===null){registry.delete(key);return}registry.set(key,value)},get:sessionManager=>!sessionManager||typeof sessionManager!=`object`?null:registry.get(sessionManager)??null}}const registry$1=createSessionManagerRuntimeRegistry(),setCompactionSafeguardRuntime=registry$1.set;registry$1.get;const registry=createSessionManagerRuntimeRegistry(),setContextPruningRuntime=registry.set;registry.get;const DEFAULT_CONTEXT_PRUNING_SETTINGS={mode:`cache-ttl`,ttlMs:300*1e3,keepLastAssistants:3,softTrimRatio:.3,hardClearRatio:.5,minPrunableToolChars:5e4,tools:{},softTrim:{maxChars:4e3,headChars:1500,tailChars:1500},hardClear:{enabled:!0,placeholder:`[Old tool result content cleared]`}};function computeEffectiveSettings(raw){if(!raw||typeof raw!=`object`)return null;let cfg=raw;if(cfg.mode!==`cache-ttl`)return null;let s=structuredClone(DEFAULT_CONTEXT_PRUNING_SETTINGS);if(s.mode=cfg.mode,typeof cfg.ttl==`string`)try{s.ttlMs=parseDurationMs(cfg.ttl,{defaultUnit:`m`})}catch{}return typeof cfg.keepLastAssistants==`number`&&Number.isFinite(cfg.keepLastAssistants)&&(s.keepLastAssistants=Math.max(0,Math.floor(cfg.keepLastAssistants))),typeof cfg.softTrimRatio==`number`&&Number.isFinite(cfg.softTrimRatio)&&(s.softTrimRatio=Math.min(1,Math.max(0,cfg.softTrimRatio))),typeof cfg.hardClearRatio==`number`&&Number.isFinite(cfg.hardClearRatio)&&(s.hardClearRatio=Math.min(1,Math.max(0,cfg.hardClearRatio))),typeof cfg.minPrunableToolChars==`number`&&Number.isFinite(cfg.minPrunableToolChars)&&(s.minPrunableToolChars=Math.max(0,Math.floor(cfg.minPrunableToolChars))),cfg.tools&&(s.tools=cfg.tools),cfg.softTrim&&(typeof cfg.softTrim.maxChars==`number`&&Number.isFinite(cfg.softTrim.maxChars)&&(s.softTrim.maxChars=Math.max(0,Math.floor(cfg.softTrim.maxChars))),typeof cfg.softTrim.headChars==`number`&&Number.isFinite(cfg.softTrim.headChars)&&(s.softTrim.headChars=Math.max(0,Math.floor(cfg.softTrim.headChars))),typeof cfg.softTrim.tailChars==`number`&&Number.isFinite(cfg.softTrim.tailChars)&&(s.softTrim.tailChars=Math.max(0,Math.floor(cfg.softTrim.tailChars)))),cfg.hardClear&&(typeof cfg.hardClear.enabled==`boolean`&&(s.hardClear.enabled=cfg.hardClear.enabled),typeof cfg.hardClear.placeholder==`string`&&cfg.hardClear.placeholder.trim()&&(s.hardClear.placeholder=cfg.hardClear.placeholder.trim())),s}function normalizeGlob(value){return String(value??``).trim().toLowerCase()}function makeToolPrunablePredicate(match){let deny=compileGlobPatterns({raw:match.deny,normalize:normalizeGlob}),allow=compileGlobPatterns({raw:match.allow,normalize:normalizeGlob});return toolName=>{let normalized=normalizeGlob(toolName);return matchesAnyGlobPattern(normalized,deny)?!1:allow.length===0?!0:matchesAnyGlobPattern(normalized,allow)}}const CACHE_TTL_CUSTOM_TYPE=`builderforce.cache-ttl`;function isCacheTtlEligibleProvider(provider,modelId){let normalizedProvider=provider.toLowerCase(),normalizedModelId=modelId.toLowerCase();return!!(normalizedProvider===`anthropic`||normalizedProvider===`openrouter`&&normalizedModelId.startsWith(`anthropic/`))}function readLastCacheTtlTimestamp(sessionManager){let sm=sessionManager;if(!sm?.getEntries)return null;try{let entries=sm.getEntries(),last=null;for(let i=entries.length-1;i>=0;i--){let entry=entries[i];if(entry?.type!==`custom`||entry?.customType!==CACHE_TTL_CUSTOM_TYPE)continue;let data=entry?.data,ts=typeof data?.timestamp==`number`?data.timestamp:null;if(ts&&Number.isFinite(ts)){last=ts;break}}return last}catch{return null}}function appendCacheTtlTimestamp(sessionManager,data){let sm=sessionManager;if(sm?.appendCustomEntry)try{sm.appendCustomEntry(CACHE_TTL_CUSTOM_TYPE,data)}catch{}}function resolveExtensionPath(id){let self=fileURLToPath(import.meta.url),dir=path.dirname(self),ext=path.extname(self)===`.ts`?`ts`:`js`;return path.join(dir,`..`,`agent-extensions`,`${id}.${ext}`)}function resolveContextWindowTokens(params){return resolveContextWindowInfo({cfg:params.cfg,provider:params.provider,modelId:params.modelId,modelContextWindow:params.model?.contextWindow,defaultTokens:DEFAULT_CONTEXT_TOKENS}).tokens}function buildContextPruningExtension(params){let raw=params.cfg?.agents?.defaults?.contextPruning;if(raw?.mode!==`cache-ttl`||!isCacheTtlEligibleProvider(params.provider,params.modelId))return{};let settings=computeEffectiveSettings(raw);return settings?(setContextPruningRuntime(params.sessionManager,{settings,contextWindowTokens:resolveContextWindowTokens(params),isToolPrunable:makeToolPrunablePredicate(settings.tools),lastCacheTouchAt:readLastCacheTtlTimestamp(params.sessionManager)}),{additionalExtensionPaths:[resolveExtensionPath(`context-pruning`)]}):{}}function resolveCompactionMode(cfg){return cfg?.agents?.defaults?.compaction?.mode===`safeguard`?`safeguard`:`default`}function buildEmbeddedExtensionPaths(params){let paths=[];if(resolveCompactionMode(params.cfg)===`safeguard`){let compactionCfg=params.cfg?.agents?.defaults?.compaction,contextWindowInfo=resolveContextWindowInfo({cfg:params.cfg,provider:params.provider,modelId:params.modelId,modelContextWindow:params.model?.contextWindow,defaultTokens:DEFAULT_CONTEXT_TOKENS});setCompactionSafeguardRuntime(params.sessionManager,{maxHistoryShare:compactionCfg?.maxHistoryShare,contextWindowTokens:contextWindowInfo.tokens}),paths.push(resolveExtensionPath(`compaction-safeguard`))}let pruning=buildContextPruningExtension(params);return pruning.additionalExtensionPaths&&paths.push(...pruning.additionalExtensionPaths),paths}function mapThinkingLevel(level){return level||`off`}function describeUnknownError(error){if(error instanceof Error)return error.message;if(typeof error==`string`)return error;try{return JSON.stringify(error)??`Unknown error`}catch{return`Unknown error`}}const GOOGLE_TURN_ORDERING_CUSTOM_TYPE=`google-turn-ordering-bootstrap`,GOOGLE_SCHEMA_UNSUPPORTED_KEYWORDS=new Set([`patternProperties`,`additionalProperties`,`$schema`,`$id`,`$ref`,`$defs`,`definitions`,`examples`,`minLength`,`maxLength`,`minimum`,`maximum`,`multipleOf`,`pattern`,`format`,`minItems`,`maxItems`,`uniqueItems`,`minProperties`,`maxProperties`]),ANTIGRAVITY_SIGNATURE_RE=/^[A-Za-z0-9+/]+={0,2}$/,INTER_SESSION_PREFIX_BASE=`[Inter-session message]`;function isValidAntigravitySignature(value){if(typeof value!=`string`)return!1;let trimmed=value.trim();return!trimmed||trimmed.length%4!=0?!1:ANTIGRAVITY_SIGNATURE_RE.test(trimmed)}function sanitizeAntigravityThinkingBlocks(messages){let touched=!1,out=[];for(let msg of messages){if(!msg||typeof msg!=`object`||msg.role!==`assistant`){out.push(msg);continue}let assistant=msg;if(!Array.isArray(assistant.content)){out.push(msg);continue}let nextContent=[],contentChanged=!1;for(let block of assistant.content){if(!block||typeof block!=`object`||block.type!==`thinking`){nextContent.push(block);continue}let rec=block,candidate=rec.thinkingSignature??rec.signature??rec.thought_signature??rec.thoughtSignature;if(!isValidAntigravitySignature(candidate)){contentChanged=!0;continue}if(rec.thinkingSignature!==candidate){let nextBlock={...block,thinkingSignature:candidate};nextContent.push(nextBlock),contentChanged=!0}else nextContent.push(block)}if(contentChanged&&(touched=!0),nextContent.length===0){touched=!0;continue}out.push(contentChanged?{...assistant,content:nextContent}:msg)}return touched?out:messages}function buildInterSessionPrefix(message){let provenance=normalizeInputProvenance(message.provenance);if(!provenance)return INTER_SESSION_PREFIX_BASE;let details=[provenance.sourceSessionKey?`sourceSession=${provenance.sourceSessionKey}`:void 0,provenance.sourceChannel?`sourceChannel=${provenance.sourceChannel}`:void 0,provenance.sourceTool?`sourceTool=${provenance.sourceTool}`:void 0].filter(Boolean);return details.length===0?INTER_SESSION_PREFIX_BASE:`${INTER_SESSION_PREFIX_BASE} ${details.join(` `)}`}function annotateInterSessionUserMessages(messages){let touched=!1,out=[];for(let msg of messages){if(!hasInterSessionUserProvenance(msg)){out.push(msg);continue}let prefix=buildInterSessionPrefix(msg),user=msg;if(typeof user.content==`string`){if(user.content.startsWith(prefix)){out.push(msg);continue}touched=!0,out.push({...msg,content:`${prefix}\n${user.content}`});continue}if(!Array.isArray(user.content)){out.push(msg);continue}let textIndex=user.content.findIndex(block=>block&&typeof block==`object`&&block.type===`text`&&typeof block.text==`string`);if(textIndex>=0){let existing=user.content[textIndex];if(existing.text.startsWith(prefix)){out.push(msg);continue}let nextContent=[...user.content];nextContent[textIndex]={...existing,text:`${prefix}\n${existing.text}`},touched=!0,out.push({...msg,content:nextContent});continue}touched=!0,out.push({...msg,content:[{type:`text`,text:prefix},...user.content]})}return touched?out:messages}function findUnsupportedSchemaKeywords(schema,path){if(!schema||typeof schema!=`object`)return[];if(Array.isArray(schema))return schema.flatMap((item,index)=>findUnsupportedSchemaKeywords(item,`${path}[${index}]`));let record=schema,violations=[],properties=record.properties&&typeof record.properties==`object`&&!Array.isArray(record.properties)?record.properties:void 0;if(properties)for(let[key,value]of Object.entries(properties))violations.push(...findUnsupportedSchemaKeywords(value,`${path}.properties.${key}`));for(let[key,value]of Object.entries(record))key!==`properties`&&(GOOGLE_SCHEMA_UNSUPPORTED_KEYWORDS.has(key)&&violations.push(`${path}.${key}`),value&&typeof value==`object`&&violations.push(...findUnsupportedSchemaKeywords(value,`${path}.${key}`)));return violations}function sanitizeToolsForGoogle(params){return params.provider===`google-gemini-cli`?params.tools.map(tool=>!tool.parameters||typeof tool.parameters!=`object`?tool:{...tool,parameters:cleanToolSchemaForGemini(tool.parameters)}):params.tools}function logToolSchemasForGoogle(params){if(params.provider!==`google-antigravity`&&params.provider!==`google-gemini-cli`)return;let toolNames=params.tools.map((tool,index)=>`${index}:${tool.name}`),tools=sanitizeToolsForGoogle(params);log$3.info(`google tool schema snapshot`,{provider:params.provider,toolCount:tools.length,tools:toolNames});for(let[index,tool]of tools.entries()){let violations=findUnsupportedSchemaKeywords(tool.parameters,`${tool.name}.parameters`);violations.length>0&&log$3.warn(`google tool schema has unsupported keywords`,{index,tool:tool.name,violations:violations.slice(0,12),violationCount:violations.length})}}const compactionFailureEmitter=new EventEmitter;registerUnhandledRejectionHandler(reason=>{let message=describeUnknownError(reason);return isCompactionFailureError(message)?(log$3.error(`Auto-compaction failed (unhandled): ${message}`),compactionFailureEmitter.emit(`failure`,message),!0):!1});const MODEL_SNAPSHOT_CUSTOM_TYPE=`model-snapshot`;function readLastModelSnapshot(sessionManager){try{let entries=sessionManager.getEntries();for(let i=entries.length-1;i>=0;i--){let entry=entries[i];if(entry?.type!==`custom`||entry?.customType!==MODEL_SNAPSHOT_CUSTOM_TYPE)continue;let data=entry?.data;if(data&&typeof data==`object`)return data}}catch{return null}return null}function appendModelSnapshot(sessionManager,data){try{sessionManager.appendCustomEntry(MODEL_SNAPSHOT_CUSTOM_TYPE,data)}catch{}}function isSameModelSnapshot(a,b){let normalize=value=>value??``;return normalize(a.provider)===normalize(b.provider)&&normalize(a.modelApi)===normalize(b.modelApi)&&normalize(a.modelId)===normalize(b.modelId)}function hasGoogleTurnOrderingMarker(sessionManager){try{return sessionManager.getEntries().some(entry=>entry?.type===`custom`&&entry?.customType===GOOGLE_TURN_ORDERING_CUSTOM_TYPE)}catch{return!1}}function markGoogleTurnOrderingMarker(sessionManager){try{sessionManager.appendCustomEntry(GOOGLE_TURN_ORDERING_CUSTOM_TYPE,{timestamp:Date.now()})}catch{}}function applyGoogleTurnOrderingFix(params){if(!isGoogleModelApi(params.modelApi)||params.messages[0]?.role!==`assistant`)return{messages:params.messages,didPrepend:!1};let sanitized=sanitizeGoogleTurnOrdering(params.messages),didPrepend=sanitized!==params.messages;return didPrepend&&!hasGoogleTurnOrderingMarker(params.sessionManager)&&((params.warn??(message=>log$3.warn(message)))(`google turn ordering fixup: prepended user bootstrap (sessionId=${params.sessionId})`),markGoogleTurnOrderingMarker(params.sessionManager)),{messages:sanitized,didPrepend}}async function sanitizeSessionHistory(params){let policy=params.policy??resolveTranscriptPolicy({modelApi:params.modelApi,provider:params.provider,modelId:params.modelId}),sanitizedImages=await sanitizeSessionMessagesImages(annotateInterSessionUserMessages(params.messages),`session:history`,{sanitizeMode:policy.sanitizeMode,sanitizeToolCallIds:policy.sanitizeToolCallIds,toolCallIdMode:policy.toolCallIdMode,preserveSignatures:policy.preserveSignatures,sanitizeThoughtSignatures:policy.sanitizeThoughtSignatures,...resolveImageSanitizationLimits(params.config)}),sanitizedToolCalls=sanitizeToolCallInputs(policy.normalizeAntigravityThinkingBlocks?sanitizeAntigravityThinkingBlocks(sanitizedImages):sanitizedImages),sanitizedToolResults=stripToolResultDetails(policy.repairToolUseResultPairing?sanitizeToolUseResultPairing(sanitizedToolCalls):sanitizedToolCalls),isOpenAIResponsesApi=params.modelApi===`openai-responses`||params.modelApi===`openai-codex-responses`,hasSnapshot=!!(params.provider||params.modelApi||params.modelId),priorSnapshot=hasSnapshot?readLastModelSnapshot(params.sessionManager):null,modelChanged=priorSnapshot?!isSameModelSnapshot(priorSnapshot,{timestamp:0,provider:params.provider,modelApi:params.modelApi,modelId:params.modelId}):!1,sanitizedOpenAI=isOpenAIResponsesApi?downgradeOpenAIReasoningBlocks(sanitizedToolResults):sanitizedToolResults;return hasSnapshot&&(!priorSnapshot||modelChanged)&&appendModelSnapshot(params.sessionManager,{timestamp:Date.now(),provider:params.provider,modelApi:params.modelApi,modelId:params.modelId}),policy.applyGoogleTurnOrdering?applyGoogleTurnOrderingFix({messages:sanitizedOpenAI,modelApi:params.modelApi,sessionManager:params.sessionManager,sessionId:params.sessionId}).messages:sanitizedOpenAI}const THREAD_SUFFIX_REGEX=/^(.*)(?::(?:thread|topic):\d+)$/i;function stripThreadSuffix(value){return value.match(THREAD_SUFFIX_REGEX)?.[1]??value}function limitHistoryTurns(messages,limit){if(!limit||limit<=0||messages.length===0)return messages;let userCount=0,lastUserIndex=messages.length;for(let i=messages.length-1;i>=0;i--)if(messages[i].role===`user`){if(userCount++,userCount>limit)return messages.slice(lastUserIndex);lastUserIndex=i}return messages}function getHistoryLimitFromSessionKey(sessionKey,config){if(!sessionKey||!config)return;let parts=sessionKey.split(`:`).filter(Boolean),providerParts=parts.length>=3&&parts[0]===`agent`?parts.slice(2):parts,provider=providerParts[0]?.toLowerCase();if(!provider)return;let kind=providerParts[1]?.toLowerCase(),userId=stripThreadSuffix(providerParts.slice(2).join(`:`)),providerConfig=((cfg,providerId)=>{let channels=cfg?.channels;if(!channels||typeof channels!=`object`)return;let entry=channels[providerId];if(!(!entry||typeof entry!=`object`||Array.isArray(entry)))return entry})(config,provider);if(providerConfig){if(kind===`dm`||kind===`direct`)return userId&&providerConfig.dms?.[userId]?.historyLimit!==void 0?providerConfig.dms[userId].historyLimit:providerConfig.dmHistoryLimit;if(kind===`channel`||kind===`group`)return providerConfig.historyLimit}}const getDmHistoryLimitFromSessionKey=getHistoryLimitFromSessionKey;function resolveSessionLane(key){let cleaned=key.trim()||CommandLane.Main;return cleaned.startsWith(`session:`)?cleaned:`session:${cleaned}`}function resolveGlobalLane(lane){return lane?.trim()||CommandLane.Main}function resolveEmbeddedSessionLane(key){return resolveSessionLane(key)}function buildEmbeddedSandboxInfo(sandbox,execElevated){if(!sandbox?.enabled)return;let elevatedAllowed=!!(execElevated?.enabled&&execElevated.allowed);return{enabled:!0,workspaceDir:sandbox.workspaceDir,containerWorkspaceDir:sandbox.containerWorkdir,workspaceAccess:sandbox.workspaceAccess,agentWorkspaceMount:sandbox.workspaceAccess===`ro`?`/agent`:void 0,browserBridgeUrl:sandbox.browser?.bridgeUrl,browserNoVncUrl:sandbox.browser?.noVncUrl,hostBrowserAllowed:sandbox.browserAllowHostControl,...elevatedAllowed?{elevated:{allowed:!0,defaultLevel:execElevated?.defaultLevel??`off`}}:{}}}const SESSION_MANAGER_CACHE=new Map;function getSessionManagerTtl(){return resolveCacheTtlMs$1({envValue:process.env.BUILDERFORCE_AGENTS_SESSION_MANAGER_CACHE_TTL_MS,defaultTtlMs:45e3})}function isSessionManagerCacheEnabled(){return isCacheEnabled(getSessionManagerTtl())}function trackSessionManagerAccess(sessionFile){if(!isSessionManagerCacheEnabled())return;let now=Date.now();SESSION_MANAGER_CACHE.set(sessionFile,{sessionFile,loadedAt:now})}function isSessionManagerCached(sessionFile){if(!isSessionManagerCacheEnabled())return!1;let entry=SESSION_MANAGER_CACHE.get(sessionFile);if(!entry)return!1;let now=Date.now(),ttl=getSessionManagerTtl();return now-entry.loadedAt<=ttl}async function prewarmSessionFile(sessionFile){if(isSessionManagerCacheEnabled()&&!isSessionManagerCached(sessionFile))try{let handle=await fs$1.open(sessionFile,`r`);try{let buffer=Buffer$1.alloc(4096);await handle.read(buffer,0,buffer.length,0)}finally{await handle.close()}trackSessionManagerAccess(sessionFile)}catch{}}function buildEmbeddedSystemPrompt(params){return buildAgentSystemPrompt({workspaceDir:params.workspaceDir,defaultThinkLevel:params.defaultThinkLevel,reasoningLevel:params.reasoningLevel,extraSystemPrompt:params.extraSystemPrompt,ownerNumbers:params.ownerNumbers,reasoningTagHint:params.reasoningTagHint,heartbeatPrompt:params.heartbeatPrompt,skillsPrompt:params.skillsPrompt,personaPrompt:params.personaPrompt,runContextPrompt:params.runContextPrompt,docsPath:params.docsPath,ttsHint:params.ttsHint,workspaceNotes:params.workspaceNotes,reactionGuidance:params.reactionGuidance,promptMode:params.promptMode,runtimeInfo:params.runtimeInfo,messageToolHints:params.messageToolHints,sandboxInfo:params.sandboxInfo,toolNames:params.tools.map(tool=>tool.name),toolSummaries:buildToolSummaryMap(params.tools),modelAliasLines:params.modelAliasLines,userTimezone:params.userTimezone,userTime:params.userTime,userTimeFormat:params.userTimeFormat,contextFiles:params.contextFiles,memoryCitationsMode:params.memoryCitationsMode})}function createSystemPromptOverride(systemPrompt){let override=systemPrompt.trim();return _defaultPrompt=>override}function applySystemPromptOverrideToSession(session,override){let prompt=typeof override==`function`?override():override.trim();session.agent.setSystemPrompt(prompt);let mutableSession=session;mutableSession._baseSystemPrompt=prompt,mutableSession._rebuildSystemPrompt=()=>prompt}function isAbortSignal(value){return typeof value==`object`&&!!value&&`aborted`in value}function isLegacyToolExecuteArgs(args){let third=args[2],fifth=args[4];return typeof third==`function`?!0:isAbortSignal(fifth)}function describeToolExecutionError(err,toolName){let rawMessage=err instanceof Error&&err.message?.trim()?err.message:String(err),code=err&&typeof err==`object`&&`code`in err?String(err.code):``,isEisdir=code===`EISDIR`||code===`ERR_FS_EISDIR`||/EISDIR/i.test(rawMessage),norm=toolName?normalizeToolName(toolName):``;return isEisdir&&(norm===`read`||norm===`read_file`)?{message:`Path is a directory; use grep or find to explore contents instead of read.`,stack:err instanceof Error?err.stack:void 0}:err instanceof Error?{message:rawMessage,stack:err.stack}:{message:rawMessage}}function splitToolExecuteArgs(args){if(isLegacyToolExecuteArgs(args)){let[toolCallId,params,onUpdate,_ctx,signal]=args;return{toolCallId,params,onUpdate,signal}}let[toolCallId,params,signal,onUpdate]=args;return{toolCallId,params,onUpdate,signal}}function toToolDefinitions(tools){return tools.map(tool=>{let name=tool.name||`tool`,normalizedName=normalizeToolName(name),beforeHookWrapped=isToolWrappedWithBeforeToolCallHook(tool);return{name,label:tool.label??name,description:tool.description??``,parameters:tool.parameters,execute:async(...args)=>{let{toolCallId,params,onUpdate,signal}=splitToolExecuteArgs(args),executeParams=params;try{if(!beforeHookWrapped){let hookOutcome=await runBeforeToolCallHook({toolName:name,params,toolCallId});if(hookOutcome.blocked)throw Error(hookOutcome.reason);executeParams=hookOutcome.params}let result=await tool.execute(toolCallId,executeParams,signal,onUpdate),afterParams=beforeHookWrapped?consumeAdjustedParamsForToolCall(toolCallId)??executeParams:executeParams,hookRunner=getGlobalHookRunner();if(hookRunner?.hasHooks(`after_tool_call`))try{await hookRunner.runAfterToolCall({toolName:name,params:isPlainObject(afterParams)?afterParams:{},result},{toolName:name})}catch(hookErr){logDebug(`after_tool_call hook failed: tool=${normalizedName} error=${String(hookErr)}`)}return result}catch(err){if(signal?.aborted||(err&&typeof err==`object`&&`name`in err?String(err.name):``)===`AbortError`)throw err;beforeHookWrapped&&consumeAdjustedParamsForToolCall(toolCallId);let described=describeToolExecutionError(err,normalizedName);described.stack&&described.stack!==described.message&&logDebug(`tools: ${normalizedName} failed stack:\n${described.stack}`),logError(`[tools] ${normalizedName} failed: ${described.message}`);let errorResult=jsonResult({status:`error`,tool:normalizedName,error:described.message}),hookRunner=getGlobalHookRunner();if(hookRunner?.hasHooks(`after_tool_call`))try{await hookRunner.runAfterToolCall({toolName:normalizedName,params:isPlainObject(params)?params:{},error:described.message},{toolName:normalizedName})}catch(hookErr){logDebug(`after_tool_call hook failed: tool=${normalizedName} error=${String(hookErr)}`)}return errorResult}}}})}function toClientToolDefinitions(tools,onClientToolCall,hookContext){return tools.map(tool=>{let func=tool.function;return{name:func.name,label:func.name,description:func.description??``,parameters:func.parameters,execute:async(...args)=>{let{toolCallId,params}=splitToolExecuteArgs(args),outcome=await runBeforeToolCallHook({toolName:func.name,params,toolCallId,ctx:hookContext});if(outcome.blocked)throw Error(outcome.reason);let adjustedParams=outcome.params,paramsRecord=isPlainObject(adjustedParams)?adjustedParams:{};return onClientToolCall&&onClientToolCall(func.name,paramsRecord),jsonResult({status:`pending`,tool:func.name,message:`Tool execution delegated to client`})}}})}function splitSdkTools(options){let{tools}=options;return{builtInTools:[],customTools:toToolDefinitions(tools)}}async function waitForAgentIdleBestEffort(agent,timeoutMs){let waitForIdle=agent?.waitForIdle;if(typeof waitForIdle!=`function`)return;let timeoutHandle;try{await Promise.race([waitForIdle.call(agent),new Promise(resolve=>{timeoutHandle=setTimeout(resolve,timeoutMs),timeoutHandle.unref?.()})])}catch{}finally{timeoutHandle&&clearTimeout(timeoutHandle)}}async function flushPendingToolResultsAfterIdle(opts){await waitForAgentIdleBestEffort(opts.agent,opts.timeoutMs??3e4),opts.sessionManager?.flushPendingToolResults?.()}function createCompactionDiagId$1(){return`cmp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function getMessageTextChars(msg){let content=msg.content;if(typeof content==`string`)return content.length;if(!Array.isArray(content))return 0;let total=0;for(let block of content){if(!block||typeof block!=`object`)continue;let text=block.text;typeof text==`string`&&(total+=text.length)}return total}function resolveMessageToolLabel(msg){let candidate=msg.toolName??msg.name??msg.tool;return typeof candidate==`string`&&candidate.trim().length>0?candidate:void 0}function summarizeCompactionMessages(messages){let historyTextChars=0,toolResultChars=0,contributors=[],estTokens=0,tokenEstimationFailed=!1;for(let msg of messages){let role=typeof msg.role==`string`?msg.role:`unknown`,chars=getMessageTextChars(msg);if(historyTextChars+=chars,role===`toolResult`&&(toolResultChars+=chars),contributors.push({role,chars,tool:resolveMessageToolLabel(msg)}),!tokenEstimationFailed)try{estTokens+=estimateTokens(msg)}catch{tokenEstimationFailed=!0}}return{messages:messages.length,historyTextChars,toolResultChars,estTokens:tokenEstimationFailed?void 0:estTokens,contributors:contributors.toSorted((a,b)=>b.chars-a.chars).slice(0,3)}}function classifyCompactionReason(reason){let text=(reason??``).trim().toLowerCase();return text?text.includes(`nothing to compact`)?`no_compactable_entries`:text.includes(`below threshold`)?`below_threshold`:text.includes(`already compacted`)?`already_compacted_recently`:text.includes(`guard`)?`guard_blocked`:text.includes(`summary`)?`summary_failed`:text.includes(`timed out`)||text.includes(`timeout`)?`timeout`:text.includes(`400`)||text.includes(`401`)||text.includes(`403`)||text.includes(`429`)?`provider_error_4xx`:text.includes(`500`)||text.includes(`502`)||text.includes(`503`)||text.includes(`504`)?`provider_error_5xx`:`unknown`:`unknown`}async function compactEmbeddedSessionDirect(params){let startedAt=Date.now(),diagId=params.diagId?.trim()||createCompactionDiagId$1(),trigger=params.trigger??`manual`,attempt=params.attempt??1,maxAttempts=params.maxAttempts??1,runId=params.runId??params.sessionId,resolvedWorkspace=resolveUserPath(params.workspaceDir),prevCwd=process.cwd(),provider=(params.provider??DEFAULT_PROVIDER).trim()||DEFAULT_PROVIDER,modelId=(params.model??DEFAULT_MODEL).trim()||DEFAULT_MODEL,fail=reason=>(log$3.warn(`[compaction-diag] end runId=${runId} sessionKey=${params.sessionKey??params.sessionId} diagId=${diagId} trigger=${trigger} provider=${provider}/${modelId} attempt=${attempt} maxAttempts=${maxAttempts} outcome=failed reason=${classifyCompactionReason(reason)} durationMs=${Date.now()-startedAt}`),{ok:!1,compacted:!1,reason}),agentDir=params.agentDir??resolveBuilderForceAgentsAgentDir();await ensureBuilderForceAgentsModelsJson(params.config,agentDir);let{model,error,authStorage,modelRegistry}=resolveModel(provider,modelId,agentDir,params.config);if(!model)return fail(error??`Unknown model: ${provider}/${modelId}`);try{let apiKeyInfo=await getApiKeyForModel({model,cfg:params.config,profileId:params.authProfileId,agentDir});if(!apiKeyInfo.apiKey){if(apiKeyInfo.mode!==`aws-sdk`)throw Error(`No API key resolved for provider "${model.provider}" (auth mode: ${apiKeyInfo.mode}).`)}else if(model.provider===`github-copilot`){let{resolveCopilotApiToken}=await import(`./github-copilot-token-DHP2kAiN.js`),copilotToken=await resolveCopilotApiToken({githubToken:apiKeyInfo.apiKey});authStorage.setRuntimeApiKey(model.provider,copilotToken.token)}else authStorage.setRuntimeApiKey(model.provider,apiKeyInfo.apiKey)}catch(err){return fail(describeUnknownError(err))}await fs$1.mkdir(resolvedWorkspace,{recursive:!0});let sandboxSessionKey=params.sessionKey?.trim()||params.sessionId,sandbox=await resolveSandboxContext({config:params.config,sessionKey:sandboxSessionKey,workspaceDir:resolvedWorkspace}),effectiveWorkspace=sandbox?.enabled?sandbox.workspaceAccess===`rw`?resolvedWorkspace:sandbox.workspaceDir:resolvedWorkspace;await fs$1.mkdir(effectiveWorkspace,{recursive:!0}),await ensureSessionHeader({sessionFile:params.sessionFile,sessionId:params.sessionId,cwd:effectiveWorkspace});let restoreSkillEnv;process.chdir(effectiveWorkspace);try{let shouldLoadSkillEntries=!params.skillsSnapshot||!params.skillsSnapshot.resolvedSkills,skillEntries=shouldLoadSkillEntries?loadWorkspaceSkillEntries(effectiveWorkspace):[];restoreSkillEnv=params.skillsSnapshot?applySkillEnvOverridesFromSnapshot({snapshot:params.skillsSnapshot,config:params.config}):applySkillEnvOverrides({skills:skillEntries??[],config:params.config});let skillsPrompt=resolveSkillsPromptForRun({skillsSnapshot:params.skillsSnapshot,entries:shouldLoadSkillEntries?skillEntries:void 0,config:params.config,workspaceDir:effectiveWorkspace}),personaPrompt=buildAssignedPersonaPrompt(),sessionLabel=params.sessionKey??params.sessionId,{contextFiles}=await resolveBootstrapContextForRun({workspaceDir:effectiveWorkspace,config:params.config,sessionKey:params.sessionKey,sessionId:params.sessionId,warn:makeBootstrapWarn({sessionLabel,warn:message=>log$3.warn(message)})}),runAbortController=new AbortController;setDesktopClientName(`on-prem`);let semantic=await catalogDesktopSemantic(effectiveWorkspace),tools=sanitizeToolsForGoogle({tools:createBuilderForceAgentsCodingTools({exec:{elevated:params.bashElevated},sandbox,messageProvider:params.messageChannel??params.messageProvider,agentAccountId:params.agentAccountId,sessionKey:params.sessionKey??params.sessionId,groupId:params.groupId,groupChannel:params.groupChannel,groupSpace:params.groupSpace,spawnedBy:params.spawnedBy,senderIsOwner:params.senderIsOwner,agentDir,workspaceDir:effectiveWorkspace,config:params.config,abortSignal:runAbortController.signal,modelProvider:model.provider,modelId,modelContextWindowTokens:model.contextWindow,modelAuthMode:await resolveModelAuthMode(model.provider,params.config),semantic}),provider});logToolSchemasForGoogle({tools,provider});let machineName=await getMachineDisplayName(),runtimeChannel=normalizeMessageChannel(params.messageChannel??params.messageProvider),runtimeCapabilities=runtimeChannel?resolveChannelCapabilities({cfg:params.config,channel:runtimeChannel,accountId:params.agentAccountId})??[]:void 0;runtimeChannel===`telegram`&&params.config&&resolveTelegramInlineButtonsScope({cfg:params.config,accountId:params.agentAccountId??void 0})!==`off`&&(runtimeCapabilities||=[],runtimeCapabilities.some(cap=>String(cap).trim().toLowerCase()===`inlinebuttons`)||runtimeCapabilities.push(`inlineButtons`));let reactionGuidance=runtimeChannel&&params.config?(()=>{if(runtimeChannel===`telegram`){let level=resolveTelegramReactionLevel({cfg:params.config,accountId:params.agentAccountId??void 0}).agentReactionGuidance;return level?{level,channel:`Telegram`}:void 0}if(runtimeChannel===`signal`){let level=resolveSignalReactionLevel({cfg:params.config,accountId:params.agentAccountId??void 0}).agentReactionGuidance;return level?{level,channel:`Signal`}:void 0}})():void 0,channelActions=runtimeChannel?listChannelSupportedActions({cfg:params.config,channel:runtimeChannel}):void 0,messageToolHints=runtimeChannel?resolveChannelMessageToolHints({cfg:params.config,channel:runtimeChannel,accountId:params.agentAccountId}):void 0,runtimeInfo={host:machineName,os:`${os.type()} ${os.release()}`,arch:os.arch(),node:process.version,model:`${provider}/${modelId}`,shell:detectRuntimeShell(),channel:runtimeChannel,capabilities:runtimeCapabilities,channelActions},sandboxInfo=buildEmbeddedSandboxInfo(sandbox,params.bashElevated),reasoningTagHint=isReasoningTagProvider(provider),userTimezone=resolveUserTimezone(params.config?.agents?.defaults?.userTimezone),userTimeFormat=resolveUserTimeFormat(params.config?.agents?.defaults?.timeFormat),userTime=formatUserTime(new Date,userTimezone,userTimeFormat),{defaultAgentId,sessionAgentId}=resolveSessionAgentIds({sessionKey:params.sessionKey,config:params.config}),isDefaultAgent=sessionAgentId===defaultAgentId,promptMode=isSubagentSessionKey(params.sessionKey)||isCronSessionKey(params.sessionKey)?`minimal`:`full`,docsPath=await resolveBuilderForceAgentsDocsPath({workspaceDir:effectiveWorkspace,argv1:process.argv[1],cwd:process.cwd(),moduleUrl:import.meta.url}),ttsHint=params.config?buildTtsSystemPromptHint(params.config):void 0,systemPromptOverride=createSystemPromptOverride(buildEmbeddedSystemPrompt({workspaceDir:effectiveWorkspace,defaultThinkLevel:params.thinkLevel,reasoningLevel:params.reasoningLevel??`off`,extraSystemPrompt:params.extraSystemPrompt,ownerNumbers:params.ownerNumbers,reasoningTagHint,heartbeatPrompt:isDefaultAgent?resolveHeartbeatPrompt(params.config?.agents?.defaults?.heartbeat?.prompt):void 0,skillsPrompt,personaPrompt,runContextPrompt:await fetchRunContextSection({workspaceDir:resolvedWorkspace,sessionKey:params.sessionKey}),docsPath:docsPath??void 0,ttsHint,promptMode,runtimeInfo,reactionGuidance,messageToolHints,sandboxInfo,tools,modelAliasLines:buildModelAliasLines(params.config),userTimezone,userTime,userTimeFormat,contextFiles,memoryCitationsMode:params.config?.memory?.citations})),sessionLock=await acquireSessionWriteLock({sessionFile:params.sessionFile,maxHoldMs:resolveSessionLockMaxHoldFromTimeout({timeoutMs:EMBEDDED_COMPACTION_TIMEOUT_MS})});try{await repairSessionFileIfNeeded({sessionFile:params.sessionFile,warn:message=>log$3.warn(message)}),await prewarmSessionFile(params.sessionFile);let transcriptPolicy=resolveTranscriptPolicy({modelApi:model.api,provider,modelId}),sessionManager=guardSessionManager(SessionManager.open(params.sessionFile),{agentId:sessionAgentId,sessionKey:params.sessionKey,allowSyntheticToolResults:transcriptPolicy.allowSyntheticToolResults});trackSessionManagerAccess(params.sessionFile);let settingsManager=SettingsManager.create(effectiveWorkspace,agentDir);ensureCompactionReserveTokens({settingsManager,minReserveTokens:resolveCompactionReserveTokensFloor(params.config)}),buildEmbeddedExtensionPaths({cfg:params.config,sessionManager,provider,modelId,model});let{builtInTools,customTools}=splitSdkTools({tools,sandboxEnabled:!!sandbox?.enabled}),{session}=await createAgentSession({cwd:resolvedWorkspace,agentDir,authStorage,modelRegistry,model,thinkingLevel:mapThinkingLevel(params.thinkLevel),tools:builtInTools,customTools,sessionManager,settingsManager});applySystemPromptOverrideToSession(session,systemPromptOverride());try{let prior=await sanitizeSessionHistory({messages:session.messages,modelApi:model.api,modelId,provider,config:params.config,sessionManager,sessionId:params.sessionId,policy:transcriptPolicy}),validatedGemini=transcriptPolicy.validateGeminiTurns?validateGeminiTurns(prior):prior,validated=transcriptPolicy.validateAnthropicTurns?validateAnthropicTurns(validatedGemini):validatedGemini,preCompactionMessages=[...session.messages],truncated=limitHistoryTurns(validated,getDmHistoryLimitFromSessionKey(params.sessionKey,params.config)),limited=transcriptPolicy.repairToolUseResultPairing?sanitizeToolUseResultPairing(truncated):truncated;limited.length>0&&session.agent.replaceMessages(limited);let hookRunner=getGlobalHookRunner(),hookCtx={agentId:params.sessionKey?.split(`:`)[0]??`main`,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageChannel??params.messageProvider};hookRunner?.hasHooks(`before_compaction`)&&hookRunner.runBeforeCompaction({messageCount:preCompactionMessages.length,compactingCount:limited.length,messages:preCompactionMessages,sessionFile:params.sessionFile},hookCtx).catch(hookErr=>{log$3.warn(`before_compaction hook failed: ${String(hookErr)}`)});let diagEnabled=log$3.isEnabled(`debug`),preMetrics=diagEnabled?summarizeCompactionMessages(session.messages):void 0;diagEnabled&&preMetrics&&(log$3.debug(`[compaction-diag] start runId=${runId} sessionKey=${params.sessionKey??params.sessionId} diagId=${diagId} trigger=${trigger} provider=${provider}/${modelId} attempt=${attempt} maxAttempts=${maxAttempts} pre.messages=${preMetrics.messages} pre.historyTextChars=${preMetrics.historyTextChars} pre.toolResultChars=${preMetrics.toolResultChars} pre.estTokens=${preMetrics.estTokens??`unknown`}`),log$3.debug(`[compaction-diag] contributors diagId=${diagId} top=${JSON.stringify(preMetrics.contributors)}`));let compactStartedAt=Date.now(),result=await compactWithSafetyTimeout(()=>session.compact(params.customInstructions)),tokensAfter;try{tokensAfter=0;for(let message of session.messages)tokensAfter+=estimateTokens(message);tokensAfter>result.tokensBefore&&(tokensAfter=void 0)}catch{tokensAfter=void 0}hookRunner?.hasHooks(`after_compaction`)&&hookRunner.runAfterCompaction({messageCount:session.messages.length,tokenCount:tokensAfter,compactedCount:limited.length-session.messages.length,sessionFile:params.sessionFile},hookCtx).catch(hookErr=>{log$3.warn(`after_compaction hook failed: ${hookErr}`)});let postMetrics=diagEnabled?summarizeCompactionMessages(session.messages):void 0;return diagEnabled&&preMetrics&&postMetrics&&log$3.debug(`[compaction-diag] end runId=${runId} sessionKey=${params.sessionKey??params.sessionId} diagId=${diagId} trigger=${trigger} provider=${provider}/${modelId} attempt=${attempt} maxAttempts=${maxAttempts} outcome=compacted reason=none durationMs=${Date.now()-compactStartedAt} retrying=false post.messages=${postMetrics.messages} post.historyTextChars=${postMetrics.historyTextChars} post.toolResultChars=${postMetrics.toolResultChars} post.estTokens=${postMetrics.estTokens??`unknown`} delta.messages=${postMetrics.messages-preMetrics.messages} delta.historyTextChars=${postMetrics.historyTextChars-preMetrics.historyTextChars} delta.toolResultChars=${postMetrics.toolResultChars-preMetrics.toolResultChars} delta.estTokens=${typeof preMetrics.estTokens==`number`&&typeof postMetrics.estTokens==`number`?postMetrics.estTokens-preMetrics.estTokens:`unknown`}`),{ok:!0,compacted:!0,result:{summary:result.summary,firstKeptEntryId:result.firstKeptEntryId,tokensBefore:result.tokensBefore,tokensAfter,details:result.details}}}finally{await flushPendingToolResultsAfterIdle({agent:session?.agent,sessionManager}),session.dispose()}}finally{await sessionLock.release()}}catch(err){return fail(describeUnknownError(err))}finally{restoreSkillEnv?.(),process.chdir(prevCwd)}}async function compactEmbeddedSession(params){let sessionLane=resolveSessionLane(params.sessionKey?.trim()||params.sessionId),globalLane=resolveGlobalLane(params.lane),enqueueGlobal=params.enqueue??((task,opts)=>enqueueCommandInLane(globalLane,task,opts));return enqueueCommandInLane(sessionLane,()=>enqueueGlobal(async()=>compactEmbeddedSessionDirect(params)))}const OPENROUTER_APP_HEADERS={"HTTP-Referer":`https://builderforce.ai`,"X-Title":`BuilderForceAgents`},ANTHROPIC_1M_MODEL_PREFIXES=[`claude-opus-4`,`claude-sonnet-4`],OPENAI_RESPONSES_APIS=new Set([`openai-responses`]),OPENAI_RESPONSES_PROVIDERS=new Set([`openai`]);function resolveExtraParams(params){let modelKey=`${params.provider}/${params.modelId}`,modelConfig=params.cfg?.agents?.defaults?.models?.[modelKey];return modelConfig?.params?{...modelConfig.params}:void 0}function envelopeCacheTtl(extraParams){let envelope=extraParams?._builderforce;if(typeof envelope!=`object`||!envelope)return;let ttl=envelope.cacheTtl;return ttl===`1h`?`1h`:ttl===`5m`?`5m`:void 0}function resolveCacheRetention(extraParams,provider){if(provider!==`anthropic`)return;let newVal=extraParams?.cacheRetention;if(newVal===`none`||newVal===`short`||newVal===`long`)return newVal;let legacy=extraParams?.cacheControlTtl??envelopeCacheTtl(extraParams);if(legacy===`5m`)return`short`;if(legacy===`1h`)return`long`}function createStreamFnWithExtraParams(baseStreamFn,extraParams,provider){if(!extraParams||Object.keys(extraParams).length===0)return;let streamParams={};typeof extraParams.temperature==`number`&&(streamParams.temperature=extraParams.temperature),typeof extraParams.maxTokens==`number`&&(streamParams.maxTokens=extraParams.maxTokens);let cacheRetention=resolveCacheRetention(extraParams,provider);if(cacheRetention&&(streamParams.cacheRetention=cacheRetention),Object.keys(streamParams).length===0)return;log$3.debug(`creating streamFn wrapper with params: ${JSON.stringify(streamParams)}`);let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>underlying(model,context,{...streamParams,...options})}function isDirectOpenAIBaseUrl(baseUrl){if(typeof baseUrl!=`string`||!baseUrl.trim())return!0;try{let host=new URL(baseUrl).hostname.toLowerCase();return host===`api.openai.com`||host===`chatgpt.com`}catch{let normalized=baseUrl.toLowerCase();return normalized.includes(`api.openai.com`)||normalized.includes(`chatgpt.com`)}}function shouldForceResponsesStore(model){return typeof model.api!=`string`||typeof model.provider!=`string`||!OPENAI_RESPONSES_APIS.has(model.api)||!OPENAI_RESPONSES_PROVIDERS.has(model.provider)?!1:isDirectOpenAIBaseUrl(model.baseUrl)}function createOpenAIResponsesStoreWrapper(baseStreamFn){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>{if(!shouldForceResponsesStore(model))return underlying(model,context,options);let originalOnPayload=options?.onPayload;return underlying(model,context,{...options,onPayload:payload=>{payload&&typeof payload==`object`&&(payload.store=!0),originalOnPayload?.(payload)}})}}function isAnthropic1MModel(modelId){let normalized=modelId.trim().toLowerCase();return ANTHROPIC_1M_MODEL_PREFIXES.some(prefix=>normalized.startsWith(prefix))}function parseHeaderList(value){return typeof value==`string`?value.split(`,`).map(item=>item.trim()).filter(Boolean):[]}function resolveAnthropicBetas(extraParams,provider,modelId){if(provider!==`anthropic`)return;let betas=new Set,configured=extraParams?.anthropicBeta;if(typeof configured==`string`&&configured.trim())betas.add(configured.trim());else if(Array.isArray(configured))for(let beta of configured)typeof beta==`string`&&beta.trim()&&betas.add(beta.trim());return extraParams?.context1m===!0&&(isAnthropic1MModel(modelId)?betas.add(`context-1m-2025-08-07`):log$3.warn(`ignoring context1m for non-opus/sonnet model: ${provider}/${modelId}`)),betas.size>0?[...betas]:void 0}function mergeAnthropicBetaHeader(headers,betas){let merged={...headers},existingKey=Object.keys(merged).find(key=>key.toLowerCase()===`anthropic-beta`),existing=existingKey?parseHeaderList(merged[existingKey]):[],values=Array.from(new Set([...existing,...betas])),key=existingKey??`anthropic-beta`;return merged[key]=values.join(`,`),merged}function createAnthropicBetaHeadersWrapper(baseStreamFn,betas){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>underlying(model,context,{...options,headers:mergeAnthropicBetaHeader(options?.headers,betas)})}const ANTHROPIC_EPHEMERAL_CACHE={type:`ephemeral`},ANTHROPIC_EPHEMERAL_CACHE_1H={type:`ephemeral`,ttl:`1h`};function wantsLongCacheTtl(extraParams){let explicit=extraParams?.cacheRetention;if(explicit===`long`)return!0;if(explicit===`short`||explicit===`none`)return!1;let legacy=extraParams?.cacheControlTtl;return legacy===`1h`?!0:legacy===`5m`?!1:envelopeCacheTtl(extraParams)===`1h`}function addAnthropicSystemCacheControl(payload,longTtl=!1){if(!payload||typeof payload!=`object`)return;let marker=longTtl?ANTHROPIC_EPHEMERAL_CACHE_1H:ANTHROPIC_EPHEMERAL_CACHE,messages=payload.messages;if(!Array.isArray(messages))return;let system=messages.find(m=>m&&typeof m==`object`&&m.role===`system`);if(!system)return;let content=system.content;if(typeof content==`string`){if(content.length===0)return;system.content=[{type:`text`,text:content,cache_control:marker}];return}if(Array.isArray(content)&&!content.some(p=>p&&typeof p==`object`&&`cache_control`in p))for(let i=content.length-1;i>=0;i--){let part=content[i];if(part&&typeof part==`object`&&part.type===`text`){part.cache_control=marker;return}}}function createOpenRouterAnthropicSystemCacheWrapper(baseStreamFn,modelId,longTtl){let underlying=baseStreamFn??nativeStreamSimple,isAnthropic=modelId.trim().toLowerCase().startsWith(`anthropic/`);return(model,context,options)=>{if(!isAnthropic)return underlying(model,context,options);let originalOnPayload=options?.onPayload;return underlying(model,context,{...options,onPayload:payload=>{addAnthropicSystemCacheControl(payload,longTtl),originalOnPayload?.(payload)}})}}function createOpenRouterHeadersWrapper(baseStreamFn){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>underlying(model,context,{...options,headers:{...OPENROUTER_APP_HEADERS,...options?.headers}})}function createZaiToolStreamWrapper(baseStreamFn,enabled){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>{if(!enabled)return underlying(model,context,options);let originalOnPayload=options?.onPayload;return underlying(model,context,{...options,onPayload:payload=>{payload&&typeof payload==`object`&&(payload.tool_stream=!0),originalOnPayload?.(payload)}})}}function applyExtraParamsToAgent(agent,cfg,provider,modelId,extraParamsOverride){let extraParams=resolveExtraParams({cfg,provider,modelId}),override=extraParamsOverride&&Object.keys(extraParamsOverride).length>0?Object.fromEntries(Object.entries(extraParamsOverride).filter(([,value])=>value!==void 0)):void 0,merged=Object.assign({},extraParams,override),wrappedStreamFn=createStreamFnWithExtraParams(agent.streamFn,merged,provider);wrappedStreamFn&&(log$3.debug(`applying extraParams to agent streamFn for ${provider}/${modelId}`),agent.streamFn=wrappedStreamFn);let anthropicBetas=resolveAnthropicBetas(merged,provider,modelId);anthropicBetas?.length&&(log$3.debug(`applying Anthropic beta header for ${provider}/${modelId}: ${anthropicBetas.join(`,`)}`),agent.streamFn=createAnthropicBetaHeadersWrapper(agent.streamFn,anthropicBetas)),provider===`openrouter`&&(log$3.debug(`applying OpenRouter app attribution headers for ${provider}/${modelId}`),agent.streamFn=createOpenRouterHeadersWrapper(agent.streamFn),agent.streamFn=createOpenRouterAnthropicSystemCacheWrapper(agent.streamFn,modelId,wantsLongCacheTtl(merged))),(provider===`zai`||provider===`z-ai`)&&merged?.tool_stream!==!1&&(log$3.debug(`enabling Z.AI tool_stream for ${provider}/${modelId}`),agent.streamFn=createZaiToolStreamWrapper(agent.streamFn,!0)),agent.streamFn=createOpenAIResponsesStoreWrapper(agent.streamFn)}const INVESTIGATION_TOOLS=new Set([`read`,`grep`,`find`,`ls`,`git_history`,`sessions_history`]),EXECUTION_TASK_PATTERN=/\b(implement|wire|fix|update|refactor|create|modify|build|patch|test|roadmap|prd|task|phase|start:)\b/i,DIRECT_USER_QUESTION_PATTERN=/\b(can you|could you|would you|do you want|which|what|where|when|should i|please provide|need your)\b/i,COMPLETION_PATTERN=/\b(all tasks? complete[d]?|all work (is|are) complete|everything (is|are) done|implementation complete|tasks? complete|all steps? finished|fully implemented|all set and ready|final answer)\b/i,DEFERRAL_PATTERN=/\b(let me|i\s*'ll|i will|next step|going to|check .* first|understand .* first)\b/i;function normalizeLastAssistantText(assistantTexts,payloadTexts=[]){for(let i=assistantTexts.length-1;i>=0;--i){let text=assistantTexts[i]?.trim();if(text)return text}for(let i=payloadTexts.length-1;i>=0;--i){let text=payloadTexts[i]?.trim();if(text)return text}return``}function isQuestionForUser(text){return!text||!text.includes(`?`)?!1:DIRECT_USER_QUESTION_PATTERN.test(text)||/\?\s*$/.test(text)}function looksLikeExecutionTask(prompt){return EXECUTION_TASK_PATTERN.test(prompt)}function isInvestigationOnly(toolNames){return toolNames.length===0?!1:toolNames.every(name=>INVESTIGATION_TOOLS.has(name))}function shouldAutoContinueRun(input){if(input.aborted||input.timedOut||input.promptErrored||input.hasPendingClientToolCall)return logDebug(`[auto-continue] blocked: abort/timeout/error status (aborted=${input.aborted} timedOut=${input.timedOut})`),{shouldContinue:!1};if(!looksLikeExecutionTask(input.userPrompt))return logDebug(`[auto-continue] blocked: user prompt doesn't look like execution task`),{shouldContinue:!1};let lastAssistantText=normalizeLastAssistantText(input.assistantTexts,input.payloadTexts);return lastAssistantText?input.hasToolError&&!isQuestionForUser(lastAssistantText)?(logDebug(`[auto-continue] continue: tool error recovery`),{shouldContinue:!0,reason:`tool_error_retry`}):isQuestionForUser(lastAssistantText)?(logDebug(`[auto-continue] blocked: agent asked user a question`),{shouldContinue:!1,reason:`asked_user_question`}):COMPLETION_PATTERN.test(lastAssistantText)?(logDebug(`[auto-continue] blocked: completion pattern matched`),{shouldContinue:!1,reason:`looks_complete`}):DEFERRAL_PATTERN.test(lastAssistantText)?(logDebug(`[auto-continue] continue: deferral language detected`),{shouldContinue:!0,reason:`deferral_language`}):isInvestigationOnly(input.toolNames)?(logDebug(`[auto-continue] continue: investigation-only tools`),{shouldContinue:!0,reason:`investigation_only_tools`}):input.toolNames.length>0?(logDebug(`[auto-continue] continue: tools were called (${input.toolNames.join(`, `)})`),{shouldContinue:!0,reason:`tools_called`}):(logDebug(`[auto-continue] blocked: no continuation signal (last text: "${lastAssistantText.slice(0,100)}...")`),{shouldContinue:!1}):input.hasToolError&&input.toolNames.length>0?(logDebug(`[auto-continue] continue: tool error with no assistant text`),{shouldContinue:!0,reason:`tool_error_no_progress`}):input.toolNames.length>0?(logDebug(`[auto-continue] continue: tools called but no assistant text`),{shouldContinue:!0,reason:`tool_activity_no_progress`}):isInvestigationOnly(input.toolNames)?(logDebug(`[auto-continue] continue: investigation-only tools`),{shouldContinue:!0,reason:`investigation_only_tools`}):(logDebug(`[auto-continue] blocked: no assistant text and no tool activity`),{shouldContinue:!1})}function buildAutoContinuePrompt(input){return[`Your previous turn ended before the requested work was complete.`,input.reason?`Continuation reason: ${input.reason}.`:``,`Original user request:`,input.originalPrompt.trim(),input.lastAssistantText?.trim()?[`Your previous incomplete response:`,input.lastAssistantText.trim()].join(`
515
+ ⚠️ [Content truncated during persistence — original exceeded size limit. Use offset/limit parameters or request specific sections for large content.]`}});return{...msg,content:newContent}}function installSessionToolResultGuard(sessionManager,opts){let originalAppend=sessionManager.appendMessage.bind(sessionManager),pending=new Map,persistMessage=message=>{let transformer=opts?.transformMessageForPersistence;return transformer?transformer(message):message},persistToolResult=(message,meta)=>{let transformer=opts?.transformToolResultForPersistence;return transformer?transformer(message,meta):message},allowSyntheticToolResults=opts?.allowSyntheticToolResults??!0,beforeWrite=opts?.beforeMessageWriteHook,applyBeforeWriteHook=msg=>{if(!beforeWrite)return msg;let result=beforeWrite({message:msg});return result?.block?null:result?.message?result.message:msg},flushPendingToolResults=()=>{if(pending.size!==0){if(allowSyntheticToolResults)for(let[id,name]of pending.entries()){let flushed=applyBeforeWriteHook(persistToolResult(persistMessage(makeMissingToolResult({toolCallId:id,toolName:name})),{toolCallId:id,toolName:name,isSynthetic:!0}));flushed&&originalAppend(flushed)}pending.clear()}};return sessionManager.appendMessage=message=>{let nextMessage=message;if(message.role===`assistant`){let sanitized=sanitizeToolCallInputs([message]);if(sanitized.length===0){allowSyntheticToolResults&&pending.size>0&&flushPendingToolResults();return}nextMessage=sanitized[0]}let nextRole=nextMessage.role;if(nextRole===`toolResult`){let id=extractToolResultId(nextMessage),toolName=id?pending.get(id):void 0;id&&pending.delete(id);let persisted=applyBeforeWriteHook(persistToolResult(capToolResultSize(persistMessage(nextMessage)),{toolCallId:id??void 0,toolName,isSynthetic:!1}));return persisted?originalAppend(persisted):void 0}let toolCalls=nextRole===`assistant`?extractToolCallsFromAssistant(nextMessage):[];allowSyntheticToolResults&&(pending.size>0&&(toolCalls.length===0||nextRole!==`assistant`)&&flushPendingToolResults(),pending.size>0&&toolCalls.length>0&&flushPendingToolResults());let finalMessage=applyBeforeWriteHook(persistMessage(nextMessage));if(!finalMessage)return;let result=originalAppend(finalMessage),sessionFile=sessionManager.getSessionFile?.();if(sessionFile&&emitSessionTranscriptUpdate(sessionFile),toolCalls.length>0)for(let call of toolCalls)pending.set(call.id,call.name);return result},{flushPendingToolResults,getPendingIds:()=>Array.from(pending.keys())}}function guardSessionManager(sessionManager,opts){if(typeof sessionManager.flushPendingToolResults==`function`)return sessionManager;let hookRunner=getGlobalHookRunner(),beforeMessageWrite=hookRunner?.hasHooks(`before_message_write`)?event=>hookRunner.runBeforeMessageWrite(event,{agentId:opts?.agentId,sessionKey:opts?.sessionKey}):void 0;return sessionManager.flushPendingToolResults=installSessionToolResultGuard(sessionManager,{transformMessageForPersistence:message=>applyInputProvenanceToUserMessage(message,opts?.inputProvenance),transformToolResultForPersistence:hookRunner?.hasHooks(`tool_result_persist`)?(message,meta)=>hookRunner.runToolResultPersist({toolName:meta.toolName,toolCallId:meta.toolCallId,message,isSynthetic:meta.isSynthetic},{agentId:opts?.agentId,sessionKey:opts?.sessionKey,toolName:meta.toolName,toolCallId:meta.toolCallId})?.message??message:void 0,allowSyntheticToolResults:opts?.allowSyntheticToolResults,beforeMessageWriteHook:beforeMessageWrite}).flushPendingToolResults,sessionManager}const MISTRAL_MODEL_HINTS=[`mistral`,`mixtral`,`codestral`,`pixtral`,`devstral`,`ministral`,`mistralai`],OPENAI_MODEL_APIS=new Set([`openai`,`openai-completions`,`openai-responses`,`openai-codex-responses`]),OPENAI_PROVIDERS=new Set([`openai`,`openai-codex`]);function isOpenAiApi(modelApi){return modelApi?OPENAI_MODEL_APIS.has(modelApi):!1}function isOpenAiProvider(provider){return provider?OPENAI_PROVIDERS.has(normalizeProviderId(provider)):!1}function isAnthropicApi(modelApi,provider){return modelApi===`anthropic-messages`?!0:normalizeProviderId(provider??``)===`anthropic`}function isMistralModel(params){if(normalizeProviderId(params.provider??``)===`mistral`)return!0;let modelId=(params.modelId??``).toLowerCase();return modelId?MISTRAL_MODEL_HINTS.some(hint=>modelId.includes(hint)):!1}function resolveTranscriptPolicy(params){let provider=normalizeProviderId(params.provider??``),modelId=params.modelId??``,isGoogle=isGoogleModelApi(params.modelApi),isAnthropic=isAnthropicApi(params.modelApi,provider),isOpenAi=isOpenAiProvider(provider)||!provider&&isOpenAiApi(params.modelApi),isMistral=isMistralModel({provider,modelId}),isOpenRouterGemini=(provider===`openrouter`||provider===`opencode`)&&modelId.toLowerCase().includes(`gemini`),isAntigravityClaudeModel=isAntigravityClaude({api:params.modelApi,provider,modelId}),needsNonImageSanitize=isGoogle||isAnthropic||isMistral||isOpenRouterGemini,sanitizeToolCallIds=isGoogle||isMistral||isAnthropic;return{sanitizeMode:isOpenAi?`images-only`:needsNonImageSanitize?`full`:`images-only`,sanitizeToolCallIds:!isOpenAi&&sanitizeToolCallIds,toolCallIdMode:isMistral?`strict9`:sanitizeToolCallIds?`strict`:void 0,repairToolUseResultPairing:!isOpenAi&&(isGoogle||isAnthropic),preserveSignatures:isAntigravityClaudeModel,sanitizeThoughtSignatures:isOpenAi?void 0:isOpenRouterGemini?{allowBase64Only:!0,includeCamelCase:!0}:void 0,normalizeAntigravityThinkingBlocks:isAntigravityClaudeModel,applyGoogleTurnOrdering:!isOpenAi&&isGoogle,validateGeminiTurns:!isOpenAi&&isGoogle,validateAnthropicTurns:!isOpenAi&&isAnthropic,allowSyntheticToolResults:!isOpenAi&&(isGoogle||isAnthropic)}}const EMBEDDED_COMPACTION_TIMEOUT_MS=3e5;async function compactWithSafetyTimeout(compact,timeoutMs=EMBEDDED_COMPACTION_TIMEOUT_MS){return await withTimeout$3(()=>compact(),timeoutMs,`Compaction`)}const CONTEXT_WINDOW_HARD_MIN_TOKENS=16e3,CONTEXT_WINDOW_WARN_BELOW_TOKENS=32e3;function normalizePositiveInt(value){if(typeof value!=`number`||!Number.isFinite(value))return null;let int=Math.floor(value);return int>0?int:null}function resolveContextWindowInfo(params){let fromModelsConfig=(()=>{let providerEntry=params.cfg?.models?.providers?.[params.provider];return normalizePositiveInt((Array.isArray(providerEntry?.models)?providerEntry.models:[]).find(m=>m?.id===params.modelId)?.contextWindow)})(),fromModel=normalizePositiveInt(params.modelContextWindow),baseInfo=fromModelsConfig?{tokens:fromModelsConfig,source:`modelsConfig`}:fromModel?{tokens:fromModel,source:`model`}:{tokens:Math.floor(params.defaultTokens),source:`default`},capTokens=normalizePositiveInt(params.cfg?.agents?.defaults?.contextTokens);return capTokens&&capTokens<baseInfo.tokens?{tokens:capTokens,source:`agentContextTokens`}:baseInfo}function evaluateContextWindowGuard(params){let warnBelow=Math.max(1,Math.floor(params.warnBelowTokens??CONTEXT_WINDOW_WARN_BELOW_TOKENS)),hardMin=Math.max(1,Math.floor(params.hardMinTokens??CONTEXT_WINDOW_HARD_MIN_TOKENS)),tokens=Math.max(0,Math.floor(params.info.tokens));return{...params.info,tokens,shouldWarn:tokens>0&&tokens<warnBelow,shouldBlock:tokens>0&&tokens<hardMin}}function createSessionManagerRuntimeRegistry(){let registry=new WeakMap;return{set:(sessionManager,value)=>{if(!sessionManager||typeof sessionManager!=`object`)return;let key=sessionManager;if(value===null){registry.delete(key);return}registry.set(key,value)},get:sessionManager=>!sessionManager||typeof sessionManager!=`object`?null:registry.get(sessionManager)??null}}const registry$1=createSessionManagerRuntimeRegistry(),setCompactionSafeguardRuntime=registry$1.set;registry$1.get;const registry=createSessionManagerRuntimeRegistry(),setContextPruningRuntime=registry.set;registry.get;const DEFAULT_CONTEXT_PRUNING_SETTINGS={mode:`cache-ttl`,ttlMs:300*1e3,keepLastAssistants:3,softTrimRatio:.3,hardClearRatio:.5,minPrunableToolChars:5e4,tools:{},softTrim:{maxChars:4e3,headChars:1500,tailChars:1500},hardClear:{enabled:!0,placeholder:`[Old tool result content cleared]`}};function computeEffectiveSettings(raw){if(!raw||typeof raw!=`object`)return null;let cfg=raw;if(cfg.mode!==`cache-ttl`)return null;let s=structuredClone(DEFAULT_CONTEXT_PRUNING_SETTINGS);if(s.mode=cfg.mode,typeof cfg.ttl==`string`)try{s.ttlMs=parseDurationMs(cfg.ttl,{defaultUnit:`m`})}catch{}return typeof cfg.keepLastAssistants==`number`&&Number.isFinite(cfg.keepLastAssistants)&&(s.keepLastAssistants=Math.max(0,Math.floor(cfg.keepLastAssistants))),typeof cfg.softTrimRatio==`number`&&Number.isFinite(cfg.softTrimRatio)&&(s.softTrimRatio=Math.min(1,Math.max(0,cfg.softTrimRatio))),typeof cfg.hardClearRatio==`number`&&Number.isFinite(cfg.hardClearRatio)&&(s.hardClearRatio=Math.min(1,Math.max(0,cfg.hardClearRatio))),typeof cfg.minPrunableToolChars==`number`&&Number.isFinite(cfg.minPrunableToolChars)&&(s.minPrunableToolChars=Math.max(0,Math.floor(cfg.minPrunableToolChars))),cfg.tools&&(s.tools=cfg.tools),cfg.softTrim&&(typeof cfg.softTrim.maxChars==`number`&&Number.isFinite(cfg.softTrim.maxChars)&&(s.softTrim.maxChars=Math.max(0,Math.floor(cfg.softTrim.maxChars))),typeof cfg.softTrim.headChars==`number`&&Number.isFinite(cfg.softTrim.headChars)&&(s.softTrim.headChars=Math.max(0,Math.floor(cfg.softTrim.headChars))),typeof cfg.softTrim.tailChars==`number`&&Number.isFinite(cfg.softTrim.tailChars)&&(s.softTrim.tailChars=Math.max(0,Math.floor(cfg.softTrim.tailChars)))),cfg.hardClear&&(typeof cfg.hardClear.enabled==`boolean`&&(s.hardClear.enabled=cfg.hardClear.enabled),typeof cfg.hardClear.placeholder==`string`&&cfg.hardClear.placeholder.trim()&&(s.hardClear.placeholder=cfg.hardClear.placeholder.trim())),s}function normalizeGlob(value){return String(value??``).trim().toLowerCase()}function makeToolPrunablePredicate(match){let deny=compileGlobPatterns({raw:match.deny,normalize:normalizeGlob}),allow=compileGlobPatterns({raw:match.allow,normalize:normalizeGlob});return toolName=>{let normalized=normalizeGlob(toolName);return matchesAnyGlobPattern(normalized,deny)?!1:allow.length===0?!0:matchesAnyGlobPattern(normalized,allow)}}const CACHE_TTL_CUSTOM_TYPE=`builderforce.cache-ttl`;function isCacheTtlEligibleProvider(provider,modelId){let normalizedProvider=provider.toLowerCase(),normalizedModelId=modelId.toLowerCase();return!!(normalizedProvider===`anthropic`||normalizedProvider===`openrouter`&&normalizedModelId.startsWith(`anthropic/`))}function readLastCacheTtlTimestamp(sessionManager){let sm=sessionManager;if(!sm?.getEntries)return null;try{let entries=sm.getEntries(),last=null;for(let i=entries.length-1;i>=0;i--){let entry=entries[i];if(entry?.type!==`custom`||entry?.customType!==CACHE_TTL_CUSTOM_TYPE)continue;let data=entry?.data,ts=typeof data?.timestamp==`number`?data.timestamp:null;if(ts&&Number.isFinite(ts)){last=ts;break}}return last}catch{return null}}function appendCacheTtlTimestamp(sessionManager,data){let sm=sessionManager;if(sm?.appendCustomEntry)try{sm.appendCustomEntry(CACHE_TTL_CUSTOM_TYPE,data)}catch{}}function resolveExtensionPath(id){let self=fileURLToPath(import.meta.url),dir=path.dirname(self),ext=path.extname(self)===`.ts`?`ts`:`js`;return path.join(dir,`..`,`agent-extensions`,`${id}.${ext}`)}function resolveContextWindowTokens(params){return resolveContextWindowInfo({cfg:params.cfg,provider:params.provider,modelId:params.modelId,modelContextWindow:params.model?.contextWindow,defaultTokens:DEFAULT_CONTEXT_TOKENS}).tokens}function buildContextPruningExtension(params){let raw=params.cfg?.agents?.defaults?.contextPruning;if(raw?.mode!==`cache-ttl`||!isCacheTtlEligibleProvider(params.provider,params.modelId))return{};let settings=computeEffectiveSettings(raw);return settings?(setContextPruningRuntime(params.sessionManager,{settings,contextWindowTokens:resolveContextWindowTokens(params),isToolPrunable:makeToolPrunablePredicate(settings.tools),lastCacheTouchAt:readLastCacheTtlTimestamp(params.sessionManager)}),{additionalExtensionPaths:[resolveExtensionPath(`context-pruning`)]}):{}}function resolveCompactionMode(cfg){return cfg?.agents?.defaults?.compaction?.mode===`safeguard`?`safeguard`:`default`}function buildEmbeddedExtensionPaths(params){let paths=[];if(resolveCompactionMode(params.cfg)===`safeguard`){let compactionCfg=params.cfg?.agents?.defaults?.compaction,contextWindowInfo=resolveContextWindowInfo({cfg:params.cfg,provider:params.provider,modelId:params.modelId,modelContextWindow:params.model?.contextWindow,defaultTokens:DEFAULT_CONTEXT_TOKENS});setCompactionSafeguardRuntime(params.sessionManager,{maxHistoryShare:compactionCfg?.maxHistoryShare,contextWindowTokens:contextWindowInfo.tokens}),paths.push(resolveExtensionPath(`compaction-safeguard`))}let pruning=buildContextPruningExtension(params);return pruning.additionalExtensionPaths&&paths.push(...pruning.additionalExtensionPaths),paths}function mapThinkingLevel(level){return level||`off`}function describeUnknownError(error){if(error instanceof Error)return error.message;if(typeof error==`string`)return error;try{return JSON.stringify(error)??`Unknown error`}catch{return`Unknown error`}}const GOOGLE_TURN_ORDERING_CUSTOM_TYPE=`google-turn-ordering-bootstrap`,GOOGLE_SCHEMA_UNSUPPORTED_KEYWORDS=new Set([`patternProperties`,`additionalProperties`,`$schema`,`$id`,`$ref`,`$defs`,`definitions`,`examples`,`minLength`,`maxLength`,`minimum`,`maximum`,`multipleOf`,`pattern`,`format`,`minItems`,`maxItems`,`uniqueItems`,`minProperties`,`maxProperties`]),ANTIGRAVITY_SIGNATURE_RE=/^[A-Za-z0-9+/]+={0,2}$/,INTER_SESSION_PREFIX_BASE=`[Inter-session message]`;function isValidAntigravitySignature(value){if(typeof value!=`string`)return!1;let trimmed=value.trim();return!trimmed||trimmed.length%4!=0?!1:ANTIGRAVITY_SIGNATURE_RE.test(trimmed)}function sanitizeAntigravityThinkingBlocks(messages){let touched=!1,out=[];for(let msg of messages){if(!msg||typeof msg!=`object`||msg.role!==`assistant`){out.push(msg);continue}let assistant=msg;if(!Array.isArray(assistant.content)){out.push(msg);continue}let nextContent=[],contentChanged=!1;for(let block of assistant.content){if(!block||typeof block!=`object`||block.type!==`thinking`){nextContent.push(block);continue}let rec=block,candidate=rec.thinkingSignature??rec.signature??rec.thought_signature??rec.thoughtSignature;if(!isValidAntigravitySignature(candidate)){contentChanged=!0;continue}if(rec.thinkingSignature!==candidate){let nextBlock={...block,thinkingSignature:candidate};nextContent.push(nextBlock),contentChanged=!0}else nextContent.push(block)}if(contentChanged&&(touched=!0),nextContent.length===0){touched=!0;continue}out.push(contentChanged?{...assistant,content:nextContent}:msg)}return touched?out:messages}function buildInterSessionPrefix(message){let provenance=normalizeInputProvenance(message.provenance);if(!provenance)return INTER_SESSION_PREFIX_BASE;let details=[provenance.sourceSessionKey?`sourceSession=${provenance.sourceSessionKey}`:void 0,provenance.sourceChannel?`sourceChannel=${provenance.sourceChannel}`:void 0,provenance.sourceTool?`sourceTool=${provenance.sourceTool}`:void 0].filter(Boolean);return details.length===0?INTER_SESSION_PREFIX_BASE:`${INTER_SESSION_PREFIX_BASE} ${details.join(` `)}`}function annotateInterSessionUserMessages(messages){let touched=!1,out=[];for(let msg of messages){if(!hasInterSessionUserProvenance(msg)){out.push(msg);continue}let prefix=buildInterSessionPrefix(msg),user=msg;if(typeof user.content==`string`){if(user.content.startsWith(prefix)){out.push(msg);continue}touched=!0,out.push({...msg,content:`${prefix}\n${user.content}`});continue}if(!Array.isArray(user.content)){out.push(msg);continue}let textIndex=user.content.findIndex(block=>block&&typeof block==`object`&&block.type===`text`&&typeof block.text==`string`);if(textIndex>=0){let existing=user.content[textIndex];if(existing.text.startsWith(prefix)){out.push(msg);continue}let nextContent=[...user.content];nextContent[textIndex]={...existing,text:`${prefix}\n${existing.text}`},touched=!0,out.push({...msg,content:nextContent});continue}touched=!0,out.push({...msg,content:[{type:`text`,text:prefix},...user.content]})}return touched?out:messages}function findUnsupportedSchemaKeywords(schema,path){if(!schema||typeof schema!=`object`)return[];if(Array.isArray(schema))return schema.flatMap((item,index)=>findUnsupportedSchemaKeywords(item,`${path}[${index}]`));let record=schema,violations=[],properties=record.properties&&typeof record.properties==`object`&&!Array.isArray(record.properties)?record.properties:void 0;if(properties)for(let[key,value]of Object.entries(properties))violations.push(...findUnsupportedSchemaKeywords(value,`${path}.properties.${key}`));for(let[key,value]of Object.entries(record))key!==`properties`&&(GOOGLE_SCHEMA_UNSUPPORTED_KEYWORDS.has(key)&&violations.push(`${path}.${key}`),value&&typeof value==`object`&&violations.push(...findUnsupportedSchemaKeywords(value,`${path}.${key}`)));return violations}function sanitizeToolsForGoogle(params){return params.provider===`google-gemini-cli`?params.tools.map(tool=>!tool.parameters||typeof tool.parameters!=`object`?tool:{...tool,parameters:cleanToolSchemaForGemini(tool.parameters)}):params.tools}function logToolSchemasForGoogle(params){if(params.provider!==`google-antigravity`&&params.provider!==`google-gemini-cli`)return;let toolNames=params.tools.map((tool,index)=>`${index}:${tool.name}`),tools=sanitizeToolsForGoogle(params);log$3.info(`google tool schema snapshot`,{provider:params.provider,toolCount:tools.length,tools:toolNames});for(let[index,tool]of tools.entries()){let violations=findUnsupportedSchemaKeywords(tool.parameters,`${tool.name}.parameters`);violations.length>0&&log$3.warn(`google tool schema has unsupported keywords`,{index,tool:tool.name,violations:violations.slice(0,12),violationCount:violations.length})}}const compactionFailureEmitter=new EventEmitter;registerUnhandledRejectionHandler(reason=>{let message=describeUnknownError(reason);return isCompactionFailureError(message)?(log$3.error(`Auto-compaction failed (unhandled): ${message}`),compactionFailureEmitter.emit(`failure`,message),!0):!1});const MODEL_SNAPSHOT_CUSTOM_TYPE=`model-snapshot`;function readLastModelSnapshot(sessionManager){try{let entries=sessionManager.getEntries();for(let i=entries.length-1;i>=0;i--){let entry=entries[i];if(entry?.type!==`custom`||entry?.customType!==MODEL_SNAPSHOT_CUSTOM_TYPE)continue;let data=entry?.data;if(data&&typeof data==`object`)return data}}catch{return null}return null}function appendModelSnapshot(sessionManager,data){try{sessionManager.appendCustomEntry(MODEL_SNAPSHOT_CUSTOM_TYPE,data)}catch{}}function isSameModelSnapshot(a,b){let normalize=value=>value??``;return normalize(a.provider)===normalize(b.provider)&&normalize(a.modelApi)===normalize(b.modelApi)&&normalize(a.modelId)===normalize(b.modelId)}function hasGoogleTurnOrderingMarker(sessionManager){try{return sessionManager.getEntries().some(entry=>entry?.type===`custom`&&entry?.customType===GOOGLE_TURN_ORDERING_CUSTOM_TYPE)}catch{return!1}}function markGoogleTurnOrderingMarker(sessionManager){try{sessionManager.appendCustomEntry(GOOGLE_TURN_ORDERING_CUSTOM_TYPE,{timestamp:Date.now()})}catch{}}function applyGoogleTurnOrderingFix(params){if(!isGoogleModelApi(params.modelApi)||params.messages[0]?.role!==`assistant`)return{messages:params.messages,didPrepend:!1};let sanitized=sanitizeGoogleTurnOrdering(params.messages),didPrepend=sanitized!==params.messages;return didPrepend&&!hasGoogleTurnOrderingMarker(params.sessionManager)&&((params.warn??(message=>log$3.warn(message)))(`google turn ordering fixup: prepended user bootstrap (sessionId=${params.sessionId})`),markGoogleTurnOrderingMarker(params.sessionManager)),{messages:sanitized,didPrepend}}async function sanitizeSessionHistory(params){let policy=params.policy??resolveTranscriptPolicy({modelApi:params.modelApi,provider:params.provider,modelId:params.modelId}),sanitizedImages=await sanitizeSessionMessagesImages(annotateInterSessionUserMessages(params.messages),`session:history`,{sanitizeMode:policy.sanitizeMode,sanitizeToolCallIds:policy.sanitizeToolCallIds,toolCallIdMode:policy.toolCallIdMode,preserveSignatures:policy.preserveSignatures,sanitizeThoughtSignatures:policy.sanitizeThoughtSignatures,...resolveImageSanitizationLimits(params.config)}),sanitizedToolCalls=sanitizeToolCallInputs(policy.normalizeAntigravityThinkingBlocks?sanitizeAntigravityThinkingBlocks(sanitizedImages):sanitizedImages),sanitizedToolResults=stripToolResultDetails(policy.repairToolUseResultPairing?sanitizeToolUseResultPairing(sanitizedToolCalls):sanitizedToolCalls),isOpenAIResponsesApi=params.modelApi===`openai-responses`||params.modelApi===`openai-codex-responses`,hasSnapshot=!!(params.provider||params.modelApi||params.modelId),priorSnapshot=hasSnapshot?readLastModelSnapshot(params.sessionManager):null,modelChanged=priorSnapshot?!isSameModelSnapshot(priorSnapshot,{timestamp:0,provider:params.provider,modelApi:params.modelApi,modelId:params.modelId}):!1,sanitizedOpenAI=isOpenAIResponsesApi?downgradeOpenAIReasoningBlocks(sanitizedToolResults):sanitizedToolResults;return hasSnapshot&&(!priorSnapshot||modelChanged)&&appendModelSnapshot(params.sessionManager,{timestamp:Date.now(),provider:params.provider,modelApi:params.modelApi,modelId:params.modelId}),policy.applyGoogleTurnOrdering?applyGoogleTurnOrderingFix({messages:sanitizedOpenAI,modelApi:params.modelApi,sessionManager:params.sessionManager,sessionId:params.sessionId}).messages:sanitizedOpenAI}const THREAD_SUFFIX_REGEX=/^(.*)(?::(?:thread|topic):\d+)$/i;function stripThreadSuffix(value){return value.match(THREAD_SUFFIX_REGEX)?.[1]??value}function limitHistoryTurns(messages,limit){if(!limit||limit<=0||messages.length===0)return messages;let userCount=0,lastUserIndex=messages.length;for(let i=messages.length-1;i>=0;i--)if(messages[i].role===`user`){if(userCount++,userCount>limit)return messages.slice(lastUserIndex);lastUserIndex=i}return messages}function getHistoryLimitFromSessionKey(sessionKey,config){if(!sessionKey||!config)return;let parts=sessionKey.split(`:`).filter(Boolean),providerParts=parts.length>=3&&parts[0]===`agent`?parts.slice(2):parts,provider=providerParts[0]?.toLowerCase();if(!provider)return;let kind=providerParts[1]?.toLowerCase(),userId=stripThreadSuffix(providerParts.slice(2).join(`:`)),providerConfig=((cfg,providerId)=>{let channels=cfg?.channels;if(!channels||typeof channels!=`object`)return;let entry=channels[providerId];if(!(!entry||typeof entry!=`object`||Array.isArray(entry)))return entry})(config,provider);if(providerConfig){if(kind===`dm`||kind===`direct`)return userId&&providerConfig.dms?.[userId]?.historyLimit!==void 0?providerConfig.dms[userId].historyLimit:providerConfig.dmHistoryLimit;if(kind===`channel`||kind===`group`)return providerConfig.historyLimit}}const getDmHistoryLimitFromSessionKey=getHistoryLimitFromSessionKey;function resolveSessionLane(key){let cleaned=key.trim()||CommandLane.Main;return cleaned.startsWith(`session:`)?cleaned:`session:${cleaned}`}function resolveGlobalLane(lane){return lane?.trim()||CommandLane.Main}function resolveEmbeddedSessionLane(key){return resolveSessionLane(key)}function buildEmbeddedSandboxInfo(sandbox,execElevated){if(!sandbox?.enabled)return;let elevatedAllowed=!!(execElevated?.enabled&&execElevated.allowed);return{enabled:!0,workspaceDir:sandbox.workspaceDir,containerWorkspaceDir:sandbox.containerWorkdir,workspaceAccess:sandbox.workspaceAccess,agentWorkspaceMount:sandbox.workspaceAccess===`ro`?`/agent`:void 0,browserBridgeUrl:sandbox.browser?.bridgeUrl,browserNoVncUrl:sandbox.browser?.noVncUrl,hostBrowserAllowed:sandbox.browserAllowHostControl,...elevatedAllowed?{elevated:{allowed:!0,defaultLevel:execElevated?.defaultLevel??`off`}}:{}}}const SESSION_MANAGER_CACHE=new Map;function getSessionManagerTtl(){return resolveCacheTtlMs$1({envValue:process.env.BUILDERFORCE_AGENTS_SESSION_MANAGER_CACHE_TTL_MS,defaultTtlMs:45e3})}function isSessionManagerCacheEnabled(){return isCacheEnabled(getSessionManagerTtl())}function trackSessionManagerAccess(sessionFile){if(!isSessionManagerCacheEnabled())return;let now=Date.now();SESSION_MANAGER_CACHE.set(sessionFile,{sessionFile,loadedAt:now})}function isSessionManagerCached(sessionFile){if(!isSessionManagerCacheEnabled())return!1;let entry=SESSION_MANAGER_CACHE.get(sessionFile);if(!entry)return!1;let now=Date.now(),ttl=getSessionManagerTtl();return now-entry.loadedAt<=ttl}async function prewarmSessionFile(sessionFile){if(isSessionManagerCacheEnabled()&&!isSessionManagerCached(sessionFile))try{let handle=await fs$1.open(sessionFile,`r`);try{let buffer=Buffer$1.alloc(4096);await handle.read(buffer,0,buffer.length,0)}finally{await handle.close()}trackSessionManagerAccess(sessionFile)}catch{}}function buildEmbeddedSystemPrompt(params){return buildAgentSystemPrompt({workspaceDir:params.workspaceDir,defaultThinkLevel:params.defaultThinkLevel,reasoningLevel:params.reasoningLevel,extraSystemPrompt:params.extraSystemPrompt,ownerNumbers:params.ownerNumbers,reasoningTagHint:params.reasoningTagHint,heartbeatPrompt:params.heartbeatPrompt,skillsPrompt:params.skillsPrompt,personaPrompt:params.personaPrompt,runContextPrompt:params.runContextPrompt,docsPath:params.docsPath,ttsHint:params.ttsHint,workspaceNotes:params.workspaceNotes,reactionGuidance:params.reactionGuidance,promptMode:params.promptMode,runtimeInfo:params.runtimeInfo,messageToolHints:params.messageToolHints,sandboxInfo:params.sandboxInfo,toolNames:params.tools.map(tool=>tool.name),toolSummaries:buildToolSummaryMap(params.tools),modelAliasLines:params.modelAliasLines,userTimezone:params.userTimezone,userTime:params.userTime,userTimeFormat:params.userTimeFormat,contextFiles:params.contextFiles,memoryCitationsMode:params.memoryCitationsMode})}function createSystemPromptOverride(systemPrompt){let override=systemPrompt.trim();return _defaultPrompt=>override}function applySystemPromptOverrideToSession(session,override){let prompt=typeof override==`function`?override():override.trim();session.agent.setSystemPrompt(prompt);let mutableSession=session;mutableSession._baseSystemPrompt=prompt,mutableSession._rebuildSystemPrompt=()=>prompt}function isAbortSignal(value){return typeof value==`object`&&!!value&&`aborted`in value}function isLegacyToolExecuteArgs(args){let third=args[2],fifth=args[4];return typeof third==`function`?!0:isAbortSignal(fifth)}function describeToolExecutionError(err,toolName){let rawMessage=err instanceof Error&&err.message?.trim()?err.message:String(err),code=err&&typeof err==`object`&&`code`in err?String(err.code):``,isEisdir=code===`EISDIR`||code===`ERR_FS_EISDIR`||/EISDIR/i.test(rawMessage),norm=toolName?normalizeToolName(toolName):``;return isEisdir&&(norm===`read`||norm===`read_file`)?{message:`Path is a directory; use grep or find to explore contents instead of read.`,stack:err instanceof Error?err.stack:void 0}:err instanceof Error?{message:rawMessage,stack:err.stack}:{message:rawMessage}}function splitToolExecuteArgs(args){if(isLegacyToolExecuteArgs(args)){let[toolCallId,params,onUpdate,_ctx,signal]=args;return{toolCallId,params,onUpdate,signal}}let[toolCallId,params,signal,onUpdate]=args;return{toolCallId,params,onUpdate,signal}}function toToolDefinitions(tools){return tools.map(tool=>{let name=tool.name||`tool`,normalizedName=normalizeToolName(name),beforeHookWrapped=isToolWrappedWithBeforeToolCallHook(tool);return{name,label:tool.label??name,description:tool.description??``,parameters:tool.parameters,execute:async(...args)=>{let{toolCallId,params,onUpdate,signal}=splitToolExecuteArgs(args),executeParams=params;try{if(!beforeHookWrapped){let hookOutcome=await runBeforeToolCallHook({toolName:name,params,toolCallId});if(hookOutcome.blocked)throw Error(hookOutcome.reason);executeParams=hookOutcome.params}let result=await tool.execute(toolCallId,executeParams,signal,onUpdate),afterParams=beforeHookWrapped?consumeAdjustedParamsForToolCall(toolCallId)??executeParams:executeParams,hookRunner=getGlobalHookRunner();if(hookRunner?.hasHooks(`after_tool_call`))try{await hookRunner.runAfterToolCall({toolName:name,params:isPlainObject(afterParams)?afterParams:{},result},{toolName:name})}catch(hookErr){logDebug(`after_tool_call hook failed: tool=${normalizedName} error=${String(hookErr)}`)}return result}catch(err){if(signal?.aborted||(err&&typeof err==`object`&&`name`in err?String(err.name):``)===`AbortError`)throw err;beforeHookWrapped&&consumeAdjustedParamsForToolCall(toolCallId);let described=describeToolExecutionError(err,normalizedName);described.stack&&described.stack!==described.message&&logDebug(`tools: ${normalizedName} failed stack:\n${described.stack}`),logError(`[tools] ${normalizedName} failed: ${described.message}`);let errorResult=jsonResult({status:`error`,tool:normalizedName,error:described.message}),hookRunner=getGlobalHookRunner();if(hookRunner?.hasHooks(`after_tool_call`))try{await hookRunner.runAfterToolCall({toolName:normalizedName,params:isPlainObject(params)?params:{},error:described.message},{toolName:normalizedName})}catch(hookErr){logDebug(`after_tool_call hook failed: tool=${normalizedName} error=${String(hookErr)}`)}return errorResult}}}})}function toClientToolDefinitions(tools,onClientToolCall,hookContext){return tools.map(tool=>{let func=tool.function;return{name:func.name,label:func.name,description:func.description??``,parameters:func.parameters,execute:async(...args)=>{let{toolCallId,params}=splitToolExecuteArgs(args),outcome=await runBeforeToolCallHook({toolName:func.name,params,toolCallId,ctx:hookContext});if(outcome.blocked)throw Error(outcome.reason);let adjustedParams=outcome.params,paramsRecord=isPlainObject(adjustedParams)?adjustedParams:{};return onClientToolCall&&onClientToolCall(func.name,paramsRecord),jsonResult({status:`pending`,tool:func.name,message:`Tool execution delegated to client`})}}})}function splitSdkTools(options){let{tools}=options;return{builtInTools:[],customTools:toToolDefinitions(tools)}}async function waitForAgentIdleBestEffort(agent,timeoutMs){let waitForIdle=agent?.waitForIdle;if(typeof waitForIdle!=`function`)return;let timeoutHandle;try{await Promise.race([waitForIdle.call(agent),new Promise(resolve=>{timeoutHandle=setTimeout(resolve,timeoutMs),timeoutHandle.unref?.()})])}catch{}finally{timeoutHandle&&clearTimeout(timeoutHandle)}}async function flushPendingToolResultsAfterIdle(opts){await waitForAgentIdleBestEffort(opts.agent,opts.timeoutMs??3e4),opts.sessionManager?.flushPendingToolResults?.()}function createCompactionDiagId$1(){return`cmp-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function getMessageTextChars(msg){let content=msg.content;if(typeof content==`string`)return content.length;if(!Array.isArray(content))return 0;let total=0;for(let block of content){if(!block||typeof block!=`object`)continue;let text=block.text;typeof text==`string`&&(total+=text.length)}return total}function resolveMessageToolLabel(msg){let candidate=msg.toolName??msg.name??msg.tool;return typeof candidate==`string`&&candidate.trim().length>0?candidate:void 0}function summarizeCompactionMessages(messages){let historyTextChars=0,toolResultChars=0,contributors=[],estTokens=0,tokenEstimationFailed=!1;for(let msg of messages){let role=typeof msg.role==`string`?msg.role:`unknown`,chars=getMessageTextChars(msg);if(historyTextChars+=chars,role===`toolResult`&&(toolResultChars+=chars),contributors.push({role,chars,tool:resolveMessageToolLabel(msg)}),!tokenEstimationFailed)try{estTokens+=estimateTokens(msg)}catch{tokenEstimationFailed=!0}}return{messages:messages.length,historyTextChars,toolResultChars,estTokens:tokenEstimationFailed?void 0:estTokens,contributors:contributors.toSorted((a,b)=>b.chars-a.chars).slice(0,3)}}function classifyCompactionReason(reason){let text=(reason??``).trim().toLowerCase();return text?text.includes(`nothing to compact`)?`no_compactable_entries`:text.includes(`below threshold`)?`below_threshold`:text.includes(`already compacted`)?`already_compacted_recently`:text.includes(`guard`)?`guard_blocked`:text.includes(`summary`)?`summary_failed`:text.includes(`timed out`)||text.includes(`timeout`)?`timeout`:text.includes(`400`)||text.includes(`401`)||text.includes(`403`)||text.includes(`429`)?`provider_error_4xx`:text.includes(`500`)||text.includes(`502`)||text.includes(`503`)||text.includes(`504`)?`provider_error_5xx`:`unknown`:`unknown`}async function compactEmbeddedSessionDirect(params){let startedAt=Date.now(),diagId=params.diagId?.trim()||createCompactionDiagId$1(),trigger=params.trigger??`manual`,attempt=params.attempt??1,maxAttempts=params.maxAttempts??1,runId=params.runId??params.sessionId,resolvedWorkspace=resolveUserPath(params.workspaceDir),prevCwd=process.cwd(),provider=(params.provider??DEFAULT_PROVIDER).trim()||DEFAULT_PROVIDER,modelId=(params.model??DEFAULT_MODEL).trim()||DEFAULT_MODEL,fail=reason=>(log$3.warn(`[compaction-diag] end runId=${runId} sessionKey=${params.sessionKey??params.sessionId} diagId=${diagId} trigger=${trigger} provider=${provider}/${modelId} attempt=${attempt} maxAttempts=${maxAttempts} outcome=failed reason=${classifyCompactionReason(reason)} durationMs=${Date.now()-startedAt}`),{ok:!1,compacted:!1,reason}),agentDir=params.agentDir??resolveBuilderForceAgentsAgentDir();await ensureBuilderForceAgentsModelsJson(params.config,agentDir);let{model,error,authStorage,modelRegistry}=resolveModel(provider,modelId,agentDir,params.config);if(!model)return fail(error??`Unknown model: ${provider}/${modelId}`);try{let apiKeyInfo=await getApiKeyForModel({model,cfg:params.config,profileId:params.authProfileId,agentDir});if(!apiKeyInfo.apiKey){if(apiKeyInfo.mode!==`aws-sdk`)throw Error(`No API key resolved for provider "${model.provider}" (auth mode: ${apiKeyInfo.mode}).`)}else if(model.provider===`github-copilot`){let{resolveCopilotApiToken}=await import(`./github-copilot-token-D5sB2AUI.js`),copilotToken=await resolveCopilotApiToken({githubToken:apiKeyInfo.apiKey});authStorage.setRuntimeApiKey(model.provider,copilotToken.token)}else authStorage.setRuntimeApiKey(model.provider,apiKeyInfo.apiKey)}catch(err){return fail(describeUnknownError(err))}await fs$1.mkdir(resolvedWorkspace,{recursive:!0});let sandboxSessionKey=params.sessionKey?.trim()||params.sessionId,sandbox=await resolveSandboxContext({config:params.config,sessionKey:sandboxSessionKey,workspaceDir:resolvedWorkspace}),effectiveWorkspace=sandbox?.enabled?sandbox.workspaceAccess===`rw`?resolvedWorkspace:sandbox.workspaceDir:resolvedWorkspace;await fs$1.mkdir(effectiveWorkspace,{recursive:!0}),await ensureSessionHeader({sessionFile:params.sessionFile,sessionId:params.sessionId,cwd:effectiveWorkspace});let restoreSkillEnv;process.chdir(effectiveWorkspace);try{let shouldLoadSkillEntries=!params.skillsSnapshot||!params.skillsSnapshot.resolvedSkills,skillEntries=shouldLoadSkillEntries?loadWorkspaceSkillEntries(effectiveWorkspace):[];restoreSkillEnv=params.skillsSnapshot?applySkillEnvOverridesFromSnapshot({snapshot:params.skillsSnapshot,config:params.config}):applySkillEnvOverrides({skills:skillEntries??[],config:params.config});let skillsPrompt=resolveSkillsPromptForRun({skillsSnapshot:params.skillsSnapshot,entries:shouldLoadSkillEntries?skillEntries:void 0,config:params.config,workspaceDir:effectiveWorkspace}),personaPrompt=buildAssignedPersonaPrompt(),sessionLabel=params.sessionKey??params.sessionId,{contextFiles}=await resolveBootstrapContextForRun({workspaceDir:effectiveWorkspace,config:params.config,sessionKey:params.sessionKey,sessionId:params.sessionId,warn:makeBootstrapWarn({sessionLabel,warn:message=>log$3.warn(message)})}),runAbortController=new AbortController;setDesktopClientName(`on-prem`);let semantic=await catalogDesktopSemantic(effectiveWorkspace),tools=sanitizeToolsForGoogle({tools:createBuilderForceAgentsCodingTools({exec:{elevated:params.bashElevated},sandbox,messageProvider:params.messageChannel??params.messageProvider,agentAccountId:params.agentAccountId,sessionKey:params.sessionKey??params.sessionId,groupId:params.groupId,groupChannel:params.groupChannel,groupSpace:params.groupSpace,spawnedBy:params.spawnedBy,senderIsOwner:params.senderIsOwner,agentDir,workspaceDir:effectiveWorkspace,config:params.config,abortSignal:runAbortController.signal,modelProvider:model.provider,modelId,modelContextWindowTokens:model.contextWindow,modelAuthMode:await resolveModelAuthMode(model.provider,params.config),semantic}),provider});logToolSchemasForGoogle({tools,provider});let machineName=await getMachineDisplayName(),runtimeChannel=normalizeMessageChannel(params.messageChannel??params.messageProvider),runtimeCapabilities=runtimeChannel?resolveChannelCapabilities({cfg:params.config,channel:runtimeChannel,accountId:params.agentAccountId})??[]:void 0;runtimeChannel===`telegram`&&params.config&&resolveTelegramInlineButtonsScope({cfg:params.config,accountId:params.agentAccountId??void 0})!==`off`&&(runtimeCapabilities||=[],runtimeCapabilities.some(cap=>String(cap).trim().toLowerCase()===`inlinebuttons`)||runtimeCapabilities.push(`inlineButtons`));let reactionGuidance=runtimeChannel&&params.config?(()=>{if(runtimeChannel===`telegram`){let level=resolveTelegramReactionLevel({cfg:params.config,accountId:params.agentAccountId??void 0}).agentReactionGuidance;return level?{level,channel:`Telegram`}:void 0}if(runtimeChannel===`signal`){let level=resolveSignalReactionLevel({cfg:params.config,accountId:params.agentAccountId??void 0}).agentReactionGuidance;return level?{level,channel:`Signal`}:void 0}})():void 0,channelActions=runtimeChannel?listChannelSupportedActions({cfg:params.config,channel:runtimeChannel}):void 0,messageToolHints=runtimeChannel?resolveChannelMessageToolHints({cfg:params.config,channel:runtimeChannel,accountId:params.agentAccountId}):void 0,runtimeInfo={host:machineName,os:`${os.type()} ${os.release()}`,arch:os.arch(),node:process.version,model:`${provider}/${modelId}`,shell:detectRuntimeShell(),channel:runtimeChannel,capabilities:runtimeCapabilities,channelActions},sandboxInfo=buildEmbeddedSandboxInfo(sandbox,params.bashElevated),reasoningTagHint=isReasoningTagProvider(provider),userTimezone=resolveUserTimezone(params.config?.agents?.defaults?.userTimezone),userTimeFormat=resolveUserTimeFormat(params.config?.agents?.defaults?.timeFormat),userTime=formatUserTime(new Date,userTimezone,userTimeFormat),{defaultAgentId,sessionAgentId}=resolveSessionAgentIds({sessionKey:params.sessionKey,config:params.config}),isDefaultAgent=sessionAgentId===defaultAgentId,promptMode=isSubagentSessionKey(params.sessionKey)||isCronSessionKey(params.sessionKey)?`minimal`:`full`,docsPath=await resolveBuilderForceAgentsDocsPath({workspaceDir:effectiveWorkspace,argv1:process.argv[1],cwd:process.cwd(),moduleUrl:import.meta.url}),ttsHint=params.config?buildTtsSystemPromptHint(params.config):void 0,systemPromptOverride=createSystemPromptOverride(buildEmbeddedSystemPrompt({workspaceDir:effectiveWorkspace,defaultThinkLevel:params.thinkLevel,reasoningLevel:params.reasoningLevel??`off`,extraSystemPrompt:params.extraSystemPrompt,ownerNumbers:params.ownerNumbers,reasoningTagHint,heartbeatPrompt:isDefaultAgent?resolveHeartbeatPrompt(params.config?.agents?.defaults?.heartbeat?.prompt):void 0,skillsPrompt,personaPrompt,runContextPrompt:await fetchRunContextSection({workspaceDir:resolvedWorkspace,sessionKey:params.sessionKey}),docsPath:docsPath??void 0,ttsHint,promptMode,runtimeInfo,reactionGuidance,messageToolHints,sandboxInfo,tools,modelAliasLines:buildModelAliasLines(params.config),userTimezone,userTime,userTimeFormat,contextFiles,memoryCitationsMode:params.config?.memory?.citations})),sessionLock=await acquireSessionWriteLock({sessionFile:params.sessionFile,maxHoldMs:resolveSessionLockMaxHoldFromTimeout({timeoutMs:EMBEDDED_COMPACTION_TIMEOUT_MS})});try{await repairSessionFileIfNeeded({sessionFile:params.sessionFile,warn:message=>log$3.warn(message)}),await prewarmSessionFile(params.sessionFile);let transcriptPolicy=resolveTranscriptPolicy({modelApi:model.api,provider,modelId}),sessionManager=guardSessionManager(SessionManager.open(params.sessionFile),{agentId:sessionAgentId,sessionKey:params.sessionKey,allowSyntheticToolResults:transcriptPolicy.allowSyntheticToolResults});trackSessionManagerAccess(params.sessionFile);let settingsManager=SettingsManager.create(effectiveWorkspace,agentDir);ensureCompactionReserveTokens({settingsManager,minReserveTokens:resolveCompactionReserveTokensFloor(params.config)}),buildEmbeddedExtensionPaths({cfg:params.config,sessionManager,provider,modelId,model});let{builtInTools,customTools}=splitSdkTools({tools,sandboxEnabled:!!sandbox?.enabled}),{session}=await createAgentSession({cwd:resolvedWorkspace,agentDir,authStorage,modelRegistry,model,thinkingLevel:mapThinkingLevel(params.thinkLevel),tools:builtInTools,customTools,sessionManager,settingsManager});applySystemPromptOverrideToSession(session,systemPromptOverride());try{let prior=await sanitizeSessionHistory({messages:session.messages,modelApi:model.api,modelId,provider,config:params.config,sessionManager,sessionId:params.sessionId,policy:transcriptPolicy}),validatedGemini=transcriptPolicy.validateGeminiTurns?validateGeminiTurns(prior):prior,validated=transcriptPolicy.validateAnthropicTurns?validateAnthropicTurns(validatedGemini):validatedGemini,preCompactionMessages=[...session.messages],truncated=limitHistoryTurns(validated,getDmHistoryLimitFromSessionKey(params.sessionKey,params.config)),limited=transcriptPolicy.repairToolUseResultPairing?sanitizeToolUseResultPairing(truncated):truncated;limited.length>0&&session.agent.replaceMessages(limited);let hookRunner=getGlobalHookRunner(),hookCtx={agentId:params.sessionKey?.split(`:`)[0]??`main`,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageChannel??params.messageProvider};hookRunner?.hasHooks(`before_compaction`)&&hookRunner.runBeforeCompaction({messageCount:preCompactionMessages.length,compactingCount:limited.length,messages:preCompactionMessages,sessionFile:params.sessionFile},hookCtx).catch(hookErr=>{log$3.warn(`before_compaction hook failed: ${String(hookErr)}`)});let diagEnabled=log$3.isEnabled(`debug`),preMetrics=diagEnabled?summarizeCompactionMessages(session.messages):void 0;diagEnabled&&preMetrics&&(log$3.debug(`[compaction-diag] start runId=${runId} sessionKey=${params.sessionKey??params.sessionId} diagId=${diagId} trigger=${trigger} provider=${provider}/${modelId} attempt=${attempt} maxAttempts=${maxAttempts} pre.messages=${preMetrics.messages} pre.historyTextChars=${preMetrics.historyTextChars} pre.toolResultChars=${preMetrics.toolResultChars} pre.estTokens=${preMetrics.estTokens??`unknown`}`),log$3.debug(`[compaction-diag] contributors diagId=${diagId} top=${JSON.stringify(preMetrics.contributors)}`));let compactStartedAt=Date.now(),result=await compactWithSafetyTimeout(()=>session.compact(params.customInstructions)),tokensAfter;try{tokensAfter=0;for(let message of session.messages)tokensAfter+=estimateTokens(message);tokensAfter>result.tokensBefore&&(tokensAfter=void 0)}catch{tokensAfter=void 0}hookRunner?.hasHooks(`after_compaction`)&&hookRunner.runAfterCompaction({messageCount:session.messages.length,tokenCount:tokensAfter,compactedCount:limited.length-session.messages.length,sessionFile:params.sessionFile},hookCtx).catch(hookErr=>{log$3.warn(`after_compaction hook failed: ${hookErr}`)});let postMetrics=diagEnabled?summarizeCompactionMessages(session.messages):void 0;return diagEnabled&&preMetrics&&postMetrics&&log$3.debug(`[compaction-diag] end runId=${runId} sessionKey=${params.sessionKey??params.sessionId} diagId=${diagId} trigger=${trigger} provider=${provider}/${modelId} attempt=${attempt} maxAttempts=${maxAttempts} outcome=compacted reason=none durationMs=${Date.now()-compactStartedAt} retrying=false post.messages=${postMetrics.messages} post.historyTextChars=${postMetrics.historyTextChars} post.toolResultChars=${postMetrics.toolResultChars} post.estTokens=${postMetrics.estTokens??`unknown`} delta.messages=${postMetrics.messages-preMetrics.messages} delta.historyTextChars=${postMetrics.historyTextChars-preMetrics.historyTextChars} delta.toolResultChars=${postMetrics.toolResultChars-preMetrics.toolResultChars} delta.estTokens=${typeof preMetrics.estTokens==`number`&&typeof postMetrics.estTokens==`number`?postMetrics.estTokens-preMetrics.estTokens:`unknown`}`),{ok:!0,compacted:!0,result:{summary:result.summary,firstKeptEntryId:result.firstKeptEntryId,tokensBefore:result.tokensBefore,tokensAfter,details:result.details}}}finally{await flushPendingToolResultsAfterIdle({agent:session?.agent,sessionManager}),session.dispose()}}finally{await sessionLock.release()}}catch(err){return fail(describeUnknownError(err))}finally{restoreSkillEnv?.(),process.chdir(prevCwd)}}async function compactEmbeddedSession(params){let sessionLane=resolveSessionLane(params.sessionKey?.trim()||params.sessionId),globalLane=resolveGlobalLane(params.lane),enqueueGlobal=params.enqueue??((task,opts)=>enqueueCommandInLane(globalLane,task,opts));return enqueueCommandInLane(sessionLane,()=>enqueueGlobal(async()=>compactEmbeddedSessionDirect(params)))}const OPENROUTER_APP_HEADERS={"HTTP-Referer":`https://builderforce.ai`,"X-Title":`BuilderForceAgents`},ANTHROPIC_1M_MODEL_PREFIXES=[`claude-opus-4`,`claude-sonnet-4`],OPENAI_RESPONSES_APIS=new Set([`openai-responses`]),OPENAI_RESPONSES_PROVIDERS=new Set([`openai`]);function resolveExtraParams(params){let modelKey=`${params.provider}/${params.modelId}`,modelConfig=params.cfg?.agents?.defaults?.models?.[modelKey];return modelConfig?.params?{...modelConfig.params}:void 0}function envelopeCacheTtl(extraParams){let envelope=extraParams?._builderforce;if(typeof envelope!=`object`||!envelope)return;let ttl=envelope.cacheTtl;return ttl===`1h`?`1h`:ttl===`5m`?`5m`:void 0}function resolveCacheRetention(extraParams,provider){if(provider!==`anthropic`)return;let newVal=extraParams?.cacheRetention;if(newVal===`none`||newVal===`short`||newVal===`long`)return newVal;let legacy=extraParams?.cacheControlTtl??envelopeCacheTtl(extraParams);if(legacy===`5m`)return`short`;if(legacy===`1h`)return`long`}function createStreamFnWithExtraParams(baseStreamFn,extraParams,provider){if(!extraParams||Object.keys(extraParams).length===0)return;let streamParams={};typeof extraParams.temperature==`number`&&(streamParams.temperature=extraParams.temperature),typeof extraParams.maxTokens==`number`&&(streamParams.maxTokens=extraParams.maxTokens);let cacheRetention=resolveCacheRetention(extraParams,provider);if(cacheRetention&&(streamParams.cacheRetention=cacheRetention),Object.keys(streamParams).length===0)return;log$3.debug(`creating streamFn wrapper with params: ${JSON.stringify(streamParams)}`);let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>underlying(model,context,{...streamParams,...options})}function isDirectOpenAIBaseUrl(baseUrl){if(typeof baseUrl!=`string`||!baseUrl.trim())return!0;try{let host=new URL(baseUrl).hostname.toLowerCase();return host===`api.openai.com`||host===`chatgpt.com`}catch{let normalized=baseUrl.toLowerCase();return normalized.includes(`api.openai.com`)||normalized.includes(`chatgpt.com`)}}function shouldForceResponsesStore(model){return typeof model.api!=`string`||typeof model.provider!=`string`||!OPENAI_RESPONSES_APIS.has(model.api)||!OPENAI_RESPONSES_PROVIDERS.has(model.provider)?!1:isDirectOpenAIBaseUrl(model.baseUrl)}function createOpenAIResponsesStoreWrapper(baseStreamFn){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>{if(!shouldForceResponsesStore(model))return underlying(model,context,options);let originalOnPayload=options?.onPayload;return underlying(model,context,{...options,onPayload:payload=>{payload&&typeof payload==`object`&&(payload.store=!0),originalOnPayload?.(payload)}})}}function isAnthropic1MModel(modelId){let normalized=modelId.trim().toLowerCase();return ANTHROPIC_1M_MODEL_PREFIXES.some(prefix=>normalized.startsWith(prefix))}function parseHeaderList(value){return typeof value==`string`?value.split(`,`).map(item=>item.trim()).filter(Boolean):[]}function resolveAnthropicBetas(extraParams,provider,modelId){if(provider!==`anthropic`)return;let betas=new Set,configured=extraParams?.anthropicBeta;if(typeof configured==`string`&&configured.trim())betas.add(configured.trim());else if(Array.isArray(configured))for(let beta of configured)typeof beta==`string`&&beta.trim()&&betas.add(beta.trim());return extraParams?.context1m===!0&&(isAnthropic1MModel(modelId)?betas.add(`context-1m-2025-08-07`):log$3.warn(`ignoring context1m for non-opus/sonnet model: ${provider}/${modelId}`)),betas.size>0?[...betas]:void 0}function mergeAnthropicBetaHeader(headers,betas){let merged={...headers},existingKey=Object.keys(merged).find(key=>key.toLowerCase()===`anthropic-beta`),existing=existingKey?parseHeaderList(merged[existingKey]):[],values=Array.from(new Set([...existing,...betas])),key=existingKey??`anthropic-beta`;return merged[key]=values.join(`,`),merged}function createAnthropicBetaHeadersWrapper(baseStreamFn,betas){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>underlying(model,context,{...options,headers:mergeAnthropicBetaHeader(options?.headers,betas)})}const ANTHROPIC_EPHEMERAL_CACHE={type:`ephemeral`},ANTHROPIC_EPHEMERAL_CACHE_1H={type:`ephemeral`,ttl:`1h`};function wantsLongCacheTtl(extraParams){let explicit=extraParams?.cacheRetention;if(explicit===`long`)return!0;if(explicit===`short`||explicit===`none`)return!1;let legacy=extraParams?.cacheControlTtl;return legacy===`1h`?!0:legacy===`5m`?!1:envelopeCacheTtl(extraParams)===`1h`}function addAnthropicSystemCacheControl(payload,longTtl=!1){if(!payload||typeof payload!=`object`)return;let marker=longTtl?ANTHROPIC_EPHEMERAL_CACHE_1H:ANTHROPIC_EPHEMERAL_CACHE,messages=payload.messages;if(!Array.isArray(messages))return;let system=messages.find(m=>m&&typeof m==`object`&&m.role===`system`);if(!system)return;let content=system.content;if(typeof content==`string`){if(content.length===0)return;system.content=[{type:`text`,text:content,cache_control:marker}];return}if(Array.isArray(content)&&!content.some(p=>p&&typeof p==`object`&&`cache_control`in p))for(let i=content.length-1;i>=0;i--){let part=content[i];if(part&&typeof part==`object`&&part.type===`text`){part.cache_control=marker;return}}}function createOpenRouterAnthropicSystemCacheWrapper(baseStreamFn,modelId,longTtl){let underlying=baseStreamFn??nativeStreamSimple,isAnthropic=modelId.trim().toLowerCase().startsWith(`anthropic/`);return(model,context,options)=>{if(!isAnthropic)return underlying(model,context,options);let originalOnPayload=options?.onPayload;return underlying(model,context,{...options,onPayload:payload=>{addAnthropicSystemCacheControl(payload,longTtl),originalOnPayload?.(payload)}})}}function createOpenRouterHeadersWrapper(baseStreamFn){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>underlying(model,context,{...options,headers:{...OPENROUTER_APP_HEADERS,...options?.headers}})}function createZaiToolStreamWrapper(baseStreamFn,enabled){let underlying=baseStreamFn??nativeStreamSimple;return(model,context,options)=>{if(!enabled)return underlying(model,context,options);let originalOnPayload=options?.onPayload;return underlying(model,context,{...options,onPayload:payload=>{payload&&typeof payload==`object`&&(payload.tool_stream=!0),originalOnPayload?.(payload)}})}}function applyExtraParamsToAgent(agent,cfg,provider,modelId,extraParamsOverride){let extraParams=resolveExtraParams({cfg,provider,modelId}),override=extraParamsOverride&&Object.keys(extraParamsOverride).length>0?Object.fromEntries(Object.entries(extraParamsOverride).filter(([,value])=>value!==void 0)):void 0,merged=Object.assign({},extraParams,override),wrappedStreamFn=createStreamFnWithExtraParams(agent.streamFn,merged,provider);wrappedStreamFn&&(log$3.debug(`applying extraParams to agent streamFn for ${provider}/${modelId}`),agent.streamFn=wrappedStreamFn);let anthropicBetas=resolveAnthropicBetas(merged,provider,modelId);anthropicBetas?.length&&(log$3.debug(`applying Anthropic beta header for ${provider}/${modelId}: ${anthropicBetas.join(`,`)}`),agent.streamFn=createAnthropicBetaHeadersWrapper(agent.streamFn,anthropicBetas)),provider===`openrouter`&&(log$3.debug(`applying OpenRouter app attribution headers for ${provider}/${modelId}`),agent.streamFn=createOpenRouterHeadersWrapper(agent.streamFn),agent.streamFn=createOpenRouterAnthropicSystemCacheWrapper(agent.streamFn,modelId,wantsLongCacheTtl(merged))),(provider===`zai`||provider===`z-ai`)&&merged?.tool_stream!==!1&&(log$3.debug(`enabling Z.AI tool_stream for ${provider}/${modelId}`),agent.streamFn=createZaiToolStreamWrapper(agent.streamFn,!0)),agent.streamFn=createOpenAIResponsesStoreWrapper(agent.streamFn)}const INVESTIGATION_TOOLS=new Set([`read`,`grep`,`find`,`ls`,`git_history`,`sessions_history`]),EXECUTION_TASK_PATTERN=/\b(implement|wire|fix|update|refactor|create|modify|build|patch|test|roadmap|prd|task|phase|start:)\b/i,DIRECT_USER_QUESTION_PATTERN=/\b(can you|could you|would you|do you want|which|what|where|when|should i|please provide|need your)\b/i,COMPLETION_PATTERN=/\b(all tasks? complete[d]?|all work (is|are) complete|everything (is|are) done|implementation complete|tasks? complete|all steps? finished|fully implemented|all set and ready|final answer)\b/i,DEFERRAL_PATTERN=/\b(let me|i\s*'ll|i will|next step|going to|check .* first|understand .* first)\b/i;function normalizeLastAssistantText(assistantTexts,payloadTexts=[]){for(let i=assistantTexts.length-1;i>=0;--i){let text=assistantTexts[i]?.trim();if(text)return text}for(let i=payloadTexts.length-1;i>=0;--i){let text=payloadTexts[i]?.trim();if(text)return text}return``}function isQuestionForUser(text){return!text||!text.includes(`?`)?!1:DIRECT_USER_QUESTION_PATTERN.test(text)||/\?\s*$/.test(text)}function looksLikeExecutionTask(prompt){return EXECUTION_TASK_PATTERN.test(prompt)}function isInvestigationOnly(toolNames){return toolNames.length===0?!1:toolNames.every(name=>INVESTIGATION_TOOLS.has(name))}function shouldAutoContinueRun(input){if(input.aborted||input.timedOut||input.promptErrored||input.hasPendingClientToolCall)return logDebug(`[auto-continue] blocked: abort/timeout/error status (aborted=${input.aborted} timedOut=${input.timedOut})`),{shouldContinue:!1};if(!looksLikeExecutionTask(input.userPrompt))return logDebug(`[auto-continue] blocked: user prompt doesn't look like execution task`),{shouldContinue:!1};let lastAssistantText=normalizeLastAssistantText(input.assistantTexts,input.payloadTexts);return lastAssistantText?input.hasToolError&&!isQuestionForUser(lastAssistantText)?(logDebug(`[auto-continue] continue: tool error recovery`),{shouldContinue:!0,reason:`tool_error_retry`}):isQuestionForUser(lastAssistantText)?(logDebug(`[auto-continue] blocked: agent asked user a question`),{shouldContinue:!1,reason:`asked_user_question`}):COMPLETION_PATTERN.test(lastAssistantText)?(logDebug(`[auto-continue] blocked: completion pattern matched`),{shouldContinue:!1,reason:`looks_complete`}):DEFERRAL_PATTERN.test(lastAssistantText)?(logDebug(`[auto-continue] continue: deferral language detected`),{shouldContinue:!0,reason:`deferral_language`}):isInvestigationOnly(input.toolNames)?(logDebug(`[auto-continue] continue: investigation-only tools`),{shouldContinue:!0,reason:`investigation_only_tools`}):input.toolNames.length>0?(logDebug(`[auto-continue] continue: tools were called (${input.toolNames.join(`, `)})`),{shouldContinue:!0,reason:`tools_called`}):(logDebug(`[auto-continue] blocked: no continuation signal (last text: "${lastAssistantText.slice(0,100)}...")`),{shouldContinue:!1}):input.hasToolError&&input.toolNames.length>0?(logDebug(`[auto-continue] continue: tool error with no assistant text`),{shouldContinue:!0,reason:`tool_error_no_progress`}):input.toolNames.length>0?(logDebug(`[auto-continue] continue: tools called but no assistant text`),{shouldContinue:!0,reason:`tool_activity_no_progress`}):isInvestigationOnly(input.toolNames)?(logDebug(`[auto-continue] continue: investigation-only tools`),{shouldContinue:!0,reason:`investigation_only_tools`}):(logDebug(`[auto-continue] blocked: no assistant text and no tool activity`),{shouldContinue:!1})}function buildAutoContinuePrompt(input){return[`Your previous turn ended before the requested work was complete.`,input.reason?`Continuation reason: ${input.reason}.`:``,`Original user request:`,input.originalPrompt.trim(),input.lastAssistantText?.trim()?[`Your previous incomplete response:`,input.lastAssistantText.trim()].join(`
516
516
  `):``,`Continue executing the user's requested tasks now. Do not summarize your plan. Perform concrete implementation and test steps. Only stop if you need a specific user decision or missing required information.`].filter(Boolean).join(`
517
517
 
518
518
  `)}async function reportPersonalityEvent(report){let agentRef=report.agentRef?.trim();if(!agentRef)return;let apiKey=readSharedEnvVar(`BUILDERFORCE_API_KEY`);if(!apiKey)return;let base=normalizeBaseUrl(readSharedEnvVar(`BUILDERFORCE_URL`)??`https://api.builderforce.ai`);try{let res=await fetch(`${base}/api/personality/events`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${apiKey}`},body:JSON.stringify({...report,agentRef}),signal:AbortSignal.timeout(1e4)});res.ok||logDebug(`[personality-event] durable report returned HTTP ${res.status}`)}catch(err){logDebug(`[personality-event] durable report failed: ${String(err)}`)}}function safeJsonStringify(value){try{return JSON.stringify(value,(_key,val)=>typeof val==`bigint`?val.toString():typeof val==`function`?`[Function]`:val instanceof Error?{name:val.name,message:val.message,stack:val.stack}:val instanceof Uint8Array?{type:`Uint8Array`,data:Buffer.from(val).toString(`base64`)}:val)}catch{return null}}function getQueuedFileWriter(writers,filePath){let existing=writers.get(filePath);if(existing)return existing;let dir=path.dirname(filePath),ready=fs$1.mkdir(dir,{recursive:!0}).catch(()=>void 0),queue=Promise.resolve(),writer={filePath,write:line=>{queue=queue.then(()=>ready).then(()=>fs$1.appendFile(filePath,line,`utf8`)).catch(()=>void 0)}};return writers.set(filePath,writer),writer}const writers$1=new Map,log$2=createSubsystemLogger(`agent/anthropic-payload`);function resolvePayloadLogConfig(env){let enabled=parseBooleanValue$1(env.BUILDERFORCE_AGENTS_ANTHROPIC_PAYLOAD_LOG)??!1,fileOverride=env.BUILDERFORCE_AGENTS_ANTHROPIC_PAYLOAD_LOG_FILE?.trim();return{enabled,filePath:fileOverride?resolveUserPath(fileOverride):path.join(resolveStateDir(env),`logs`,`anthropic-payload.jsonl`)}}function getWriter$1(filePath){return getQueuedFileWriter(writers$1,filePath)}function digest$1(value){let serialized=safeJsonStringify(value);if(serialized)return crypto.createHash(`sha256`).update(serialized).digest(`hex`)}function isAnthropicModel(model){return model?.api===`anthropic-messages`}function findLastAssistantUsage(messages){for(let i=messages.length-1;i>=0;--i){let msg=messages[i];if(msg?.role===`assistant`&&msg.usage&&typeof msg.usage==`object`)return msg.usage}return null}function createAnthropicPayloadLogger(params){let cfg=resolvePayloadLogConfig(params.env??process.env);if(!cfg.enabled)return null;let writer=getWriter$1(cfg.filePath),base={runId:params.runId,sessionId:params.sessionId,sessionKey:params.sessionKey,provider:params.provider,modelId:params.modelId,modelApi:params.modelApi,workspaceDir:params.workspaceDir},record=event=>{let line=safeJsonStringify(event);line&&writer.write(`${line}\n`)};return log$2.info(`anthropic payload logger enabled`,{filePath:writer.filePath}),{enabled:!0,wrapStreamFn:streamFn=>(model,context,options)=>{if(!isAnthropicModel(model))return streamFn(model,context,options);let nextOnPayload=payload=>{record({...base,ts:new Date().toISOString(),stage:`request`,payload,payloadDigest:digest$1(payload)}),options?.onPayload?.(payload)};return streamFn(model,context,{...options,onPayload:nextOnPayload})},recordUsage:(messages,error)=>{let usage=findLastAssistantUsage(messages),errorMessage=error==null?void 0:formatErrorMessage(error);if(!usage){errorMessage&&record({...base,ts:new Date().toISOString(),stage:`usage`,error:errorMessage});return}record({...base,ts:new Date().toISOString(),stage:`usage`,usage,error:errorMessage}),log$2.info(`anthropic usage`,{runId:params.runId,sessionId:params.sessionId,usage})}}}const SOURCE_EXTENSIONS=new Set([`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.md`,`.json`]),SKIP_DIRS=new Set([`node_modules`,`.git`,`dist`,`build`,`.cache`,`coverage`]);async function walkSourceFiles(dir,files=[]){if(files.length>=800)return files;let entries;try{entries=await fs$1.readdir(dir,{withFileTypes:!0,encoding:`utf-8`})}catch{return files}for(let entry of entries){if(files.length>=800)break;entry.isDirectory()?!SKIP_DIRS.has(entry.name)&&!entry.name.startsWith(`.`)&&await walkSourceFiles(path.join(dir,entry.name),files):entry.isFile()&&SOURCE_EXTENSIONS.has(path.extname(entry.name))&&files.push(path.join(dir,entry.name))}return files}function tokenise(text){return new Set(text.toLowerCase().split(/[\s\W]+/).filter(t=>t.length>2))}function score(queryTokens,fileContent){let fileTokens=tokenise(fileContent),hits=0;for(let t of queryTokens)fileTokens.has(t)&&hits++;return hits}async function retrieveRelevantContext(opts){let topK=opts.topK??3,maxChars=opts.maxExcerptChars??600,queryTokens=tokenise(opts.query);if(queryTokens.size===0)return``;let files=await walkSourceFiles(opts.workspaceDir);if(files.length===0)return``;let scored=[];for(let i=0;i<files.length;i+=20){let batch=files.slice(i,i+20);await Promise.all(batch.map(async file=>{try{let content=await fs$1.readFile(file,`utf-8`),s=score(queryTokens,content);s>0&&scored.push({file,score:s,excerpt:content.slice(0,maxChars)+(content.length>maxChars?`
@@ -535,8 +535,8 @@ It is listed as a peerDependency of builderForceAgents.`)}}function convertTools
535
535
  `),psychometricParams=resolveCognitiveExecParams(),effectiveThinkLevel=raiseThinkLevel(params.thinkLevel,psychometricParams.thinkLevel),effectiveReasoningLevel=psychometricParams.reasoningLevel===`on`&&(params.reasoningLevel??`off`)===`off`?`on`:params.reasoningLevel??`off`,effectiveStreamParams=psychometricParams.temperature===void 0?params.streamParams:{temperature:psychometricParams.temperature,...params.streamParams??{}},activePersonas=globalPersonaRegistry.listActive?.()??[],personaDirectives=buildAssignedPersonaPrompt(),appliedTemperature=effectiveStreamParams?.temperature,appliedTemp=typeof appliedTemperature==`number`?appliedTemperature:null,directivesSummary=summarizePersonaDirectives(personaDirectives);try{emitAgentEvent({runId:params.runId,stream:`personality`,sessionKey:params.sessionKey??params.sessionId,data:{phase:`applied`,personas:activePersonas,hasPsychometric:!!personaDirectives,directivesSummary,thinkLevel:effectiveThinkLevel,reasoningLevel:effectiveReasoningLevel,temperature:appliedTemp}})}catch{}try{let agentRef=resolveHiredAgentRef(params.agentId),directiveCount=personaDirectives.split(`
536
536
  `).filter(line=>line.trim().length>0).length;agentRef&&directiveCount>0&&reportPersonalityEvent({agentRef,runId:params.runId,sessionKey:params.sessionKey??params.sessionId,profileSource:`agent`,personaIds:activePersonas.map(p=>p.name),directivesSummary,directiveCount,thinkLevel:effectiveThinkLevel,reasoningLevel:effectiveReasoningLevel,temperature:appliedTemp})}catch{}let runContextPromise=fetchRunContextSection({workspaceDir:resolvedWorkspace,sessionKey:params.sessionKey,query:params.prompt}),sessionLabel=params.sessionKey??params.sessionId,{bootstrapFiles:hookAdjustedBootstrapFiles,contextFiles}=await resolveBootstrapContextForRun({workspaceDir:effectiveWorkspace,config:params.config,sessionKey:params.sessionKey,sessionId:params.sessionId,warn:makeBootstrapWarn({sessionLabel,warn:message=>log$3.warn(message)})}),workspaceNotes=hookAdjustedBootstrapFiles.some(file=>file.name===DEFAULT_BOOTSTRAP_FILENAME&&!file.missing)?[`Reminder: commit your changes in this workspace after edits.`]:void 0,agentDir=params.agentDir??resolveBuilderForceAgentsAgentDir(),modelHasVision=params.model.input?.includes(`image`)??!1;params.disableTools||setDesktopClientName(`on-prem`);let semantic=params.disableTools?void 0:await catalogDesktopSemantic(effectiveWorkspace),tools=sanitizeToolsForGoogle({tools:params.disableTools?[]:createBuilderForceAgentsCodingTools({exec:{...params.execOverrides,elevated:params.bashElevated},sandbox,messageProvider:params.messageChannel??params.messageProvider,agentAccountId:params.agentAccountId,messageTo:params.messageTo,messageThreadId:params.messageThreadId,groupId:params.groupId,groupChannel:params.groupChannel,groupSpace:params.groupSpace,spawnedBy:params.spawnedBy,senderId:params.senderId,senderName:params.senderName,senderUsername:params.senderUsername,senderE164:params.senderE164,senderIsOwner:params.senderIsOwner,sessionKey:params.sessionKey??params.sessionId,agentDir,workspaceDir:effectiveWorkspace,config:params.config,abortSignal:runAbortController.signal,modelProvider:params.model.provider,modelId:params.modelId,modelContextWindowTokens:params.model.contextWindow,modelAuthMode:await resolveModelAuthMode(params.model.provider,params.config),currentChannelId:params.currentChannelId,currentThreadTs:params.currentThreadTs,replyToMode:params.replyToMode,hasRepliedRef:params.hasRepliedRef,modelHasVision,requireExplicitMessageTarget:params.requireExplicitMessageTarget??isSubagentSessionKey(params.sessionKey),disableMessageTool:params.disableMessageTool,semantic}),provider:params.provider});logToolSchemasForGoogle({tools,provider:params.provider});let machineName=await getMachineDisplayName(),runtimeChannel=normalizeMessageChannel(params.messageChannel??params.messageProvider),runtimeCapabilities=runtimeChannel?resolveChannelCapabilities({cfg:params.config,channel:runtimeChannel,accountId:params.agentAccountId})??[]:void 0;runtimeChannel===`telegram`&&params.config&&resolveTelegramInlineButtonsScope({cfg:params.config,accountId:params.agentAccountId??void 0})!==`off`&&(runtimeCapabilities||=[],runtimeCapabilities.some(cap=>String(cap).trim().toLowerCase()===`inlinebuttons`)||runtimeCapabilities.push(`inlineButtons`));let reactionGuidance=runtimeChannel&&params.config?(()=>{if(runtimeChannel===`telegram`){let level=resolveTelegramReactionLevel({cfg:params.config,accountId:params.agentAccountId??void 0}).agentReactionGuidance;return level?{level,channel:`Telegram`}:void 0}if(runtimeChannel===`signal`){let level=resolveSignalReactionLevel({cfg:params.config,accountId:params.agentAccountId??void 0}).agentReactionGuidance;return level?{level,channel:`Signal`}:void 0}})():void 0,{defaultAgentId,sessionAgentId}=resolveSessionAgentIds({sessionKey:params.sessionKey,config:params.config}),sandboxInfo=buildEmbeddedSandboxInfo(sandbox,params.bashElevated),reasoningTagHint=isReasoningTagProvider(params.provider),channelActions=runtimeChannel?listChannelSupportedActions({cfg:params.config,channel:runtimeChannel}):void 0,messageToolHints=runtimeChannel?resolveChannelMessageToolHints({cfg:params.config,channel:runtimeChannel,accountId:params.agentAccountId}):void 0,defaultModelRef=resolveDefaultModelForAgent({cfg:params.config??{},agentId:sessionAgentId}),defaultModelLabel=`${defaultModelRef.provider}/${defaultModelRef.model}`,{runtimeInfo,userTimezone,userTime,userTimeFormat}=buildSystemPromptParams({config:params.config,agentId:sessionAgentId,workspaceDir:effectiveWorkspace,cwd:process.cwd(),runtime:{host:machineName,os:`${os.type()} ${os.release()}`,arch:os.arch(),node:process.version,model:`${params.provider}/${params.modelId}`,defaultModel:defaultModelLabel,shell:detectRuntimeShell(),channel:runtimeChannel,capabilities:runtimeCapabilities,channelActions}}),isDefaultAgent=sessionAgentId===defaultAgentId,promptMode=isSubagentSessionKey(params.sessionKey)||isCronSessionKey(params.sessionKey)?`minimal`:`full`,docsPath=await resolveBuilderForceAgentsDocsPath({workspaceDir:effectiveWorkspace,argv1:process.argv[1],cwd:process.cwd(),moduleUrl:import.meta.url}),ttsHint=params.config?buildTtsSystemPromptHint(params.config):void 0,appendPrompt=buildEmbeddedSystemPrompt({workspaceDir:effectiveWorkspace,defaultThinkLevel:effectiveThinkLevel,reasoningLevel:effectiveReasoningLevel,extraSystemPrompt:params.extraSystemPrompt,ownerNumbers:params.ownerNumbers,reasoningTagHint,heartbeatPrompt:isDefaultAgent?resolveHeartbeatPrompt(params.config?.agents?.defaults?.heartbeat?.prompt):void 0,skillsPrompt,personaPrompt,runContextPrompt:await runContextPromise,docsPath:docsPath??void 0,ttsHint,workspaceNotes,reactionGuidance,promptMode,runtimeInfo,messageToolHints,sandboxInfo,tools,modelAliasLines:buildModelAliasLines(params.config),userTimezone,userTime,userTimeFormat,contextFiles,memoryCitationsMode:params.config?.memory?.citations}),systemPromptReport=buildSystemPromptReport({source:`run`,generatedAt:Date.now(),sessionId:params.sessionId,sessionKey:params.sessionKey,provider:params.provider,model:params.modelId,workspaceDir:effectiveWorkspace,bootstrapMaxChars:resolveBootstrapMaxChars(params.config),bootstrapTotalMaxChars:resolveBootstrapTotalMaxChars(params.config),sandbox:(()=>{let runtime=resolveSandboxRuntimeStatus({cfg:params.config,sessionKey:params.sessionKey??params.sessionId});return{mode:runtime.mode,sandboxed:runtime.sandboxed}})(),systemPrompt:appendPrompt,bootstrapFiles:hookAdjustedBootstrapFiles,injectedFiles:contextFiles,skillsPrompt,tools}),systemPromptText=createSystemPromptOverride(appendPrompt)(),sessionLock=await acquireSessionWriteLock({sessionFile:params.sessionFile,maxHoldMs:resolveSessionLockMaxHoldFromTimeout({timeoutMs:params.timeoutMs})}),sessionManager,session,removeToolResultContextGuard;try{await repairSessionFileIfNeeded({sessionFile:params.sessionFile,warn:message=>log$3.warn(message)});let hadSessionFile=await fs$1.stat(params.sessionFile).then(()=>!0).catch(()=>!1),transcriptPolicy=resolveTranscriptPolicy({modelApi:params.model?.api,provider:params.provider,modelId:params.modelId});await prewarmSessionFile(params.sessionFile),sessionManager=guardSessionManager(SessionManager.open(params.sessionFile),{agentId:sessionAgentId,sessionKey:params.sessionKey,inputProvenance:params.inputProvenance,allowSyntheticToolResults:transcriptPolicy.allowSyntheticToolResults}),trackSessionManagerAccess(params.sessionFile),await prepareSessionManagerForRun({sessionManager,sessionFile:params.sessionFile,hadSessionFile,sessionId:params.sessionId,cwd:effectiveWorkspace});let settingsManager=SettingsManager.create(effectiveWorkspace,agentDir);ensureCompactionReserveTokens({settingsManager,minReserveTokens:resolveCompactionReserveTokensFloor(params.config)}),buildEmbeddedExtensionPaths({cfg:params.config,sessionManager,provider:params.provider,modelId:params.modelId,model:params.model});let hookRunner=getGlobalHookRunner(),{builtInTools,customTools}=splitSdkTools({tools,sandboxEnabled:!!sandbox?.enabled}),clientToolCallDetected=null,clientToolLoopDetection=resolveToolLoopDetectionConfig({cfg:params.config,agentId:sessionAgentId}),clientToolDefs=params.clientTools?toClientToolDefinitions(params.clientTools,(toolName,toolParams)=>{clientToolCallDetected={name:toolName,params:toolParams}},{agentId:sessionAgentId,sessionKey:params.sessionKey,loopDetection:clientToolLoopDetection}):[],allCustomTools=[...customTools,...clientToolDefs];if({session}=await createAgentSession({cwd:resolvedWorkspace,agentDir,authStorage:params.authStorage,modelRegistry:params.modelRegistry,model:params.model,...(()=>{let pickFallbackModel=createStallFallbackPicker({cfg:params.config,provider:params.provider,modelId:params.modelId,agentDir});return pickFallbackModel?{pickFallbackModel}:{}})(),onModelFallback:(from,to,notice)=>{log$3.warn(`[model-failover] ${notice}`),emitAgentEvent({runId:params.runId,stream:`lifecycle`,sessionKey:params.sessionKey??params.sessionId,data:{phase:`model_failover`,from:`${from.provider}/${from.id}`,to:`${to.provider}/${to.id}`,notice}})},thinkingLevel:mapThinkingLevel(effectiveThinkLevel),tools:builtInTools,customTools:allCustomTools,sessionManager,settingsManager}),applySystemPromptOverrideToSession(session,systemPromptText),!session)throw Error(`Embedded agent session missing`);let activeSession=session;removeToolResultContextGuard=installToolResultContextGuard({agent:activeSession.agent,contextWindowTokens:Math.max(1,Math.floor(params.model.contextWindow??params.model.maxTokens??DEFAULT_CONTEXT_TOKENS))});let cacheTrace=createCacheTrace({cfg:params.config,env:process.env,runId:params.runId,sessionId:activeSession.sessionId,sessionKey:params.sessionKey,provider:params.provider,modelId:params.modelId,modelApi:params.model.api,workspaceDir:params.workspaceDir}),anthropicPayloadLogger=createAnthropicPayloadLogger({env:process.env,runId:params.runId,sessionId:activeSession.sessionId,sessionKey:params.sessionKey,provider:params.provider,modelId:params.modelId,modelApi:params.model.api,workspaceDir:params.workspaceDir}),localBrainEnv=process.env.BUILDERFORCE_AGENTS_LOCAL_BRAIN?.trim();if(localBrainEnv===void 0?params.config?.localBrain?.enabled===!0:localBrainEnv!==`0`&&localBrainEnv.toLowerCase()!==`false`){log$3.info(`[brain-routing] run=${params.runId} localBrain=on → amygdala/hippocampus pipeline (cortex=${params.provider}/${params.modelId})`);let providerConfig=params.config?.models?.providers?.[`builderforcellm-local`],cacheDir=typeof providerConfig?.baseUrl==`string`&&providerConfig.baseUrl.trim()?providerConfig.baseUrl.trim():void 0,localBrainModels=params.config?.localBrain?.models,amygdalaModelId=localBrainModels?.amygdala?.modelId,amygdalaDtype=localBrainModels?.amygdala?.dtype,hippocampusModelId=localBrainModels?.hippocampus?.modelId,hippocampusDtype=localBrainModels?.hippocampus?.dtype;activeSession.agent.streamFn=createBuilderForceAgentsLlmLocalStreamFn({config:params.config,modelId:amygdalaModelId,dtype:amygdalaDtype,hippocampusModelId,hippocampusDtype,cacheDir,workspaceDir:params.workspaceDir,isSharedContext:!!(params.messageChannel??params.messageProvider)})}else if(params.model.api===`ollama`){log$3.info(`[brain-routing] run=${params.runId} api=ollama model=${params.modelId} → Ollama native stream`);let providerConfig=params.config?.models?.providers?.[params.model.provider],modelBaseUrl=typeof params.model.baseUrl==`string`?params.model.baseUrl.trim():``,providerBaseUrl=typeof providerConfig?.baseUrl==`string`?providerConfig.baseUrl.trim():``,ollamaBaseUrl=modelBaseUrl||providerBaseUrl||OLLAMA_NATIVE_BASE_URL;activeSession.agent.streamFn=createOllamaStreamFn(ollamaBaseUrl)}else if(params.model.api===`llama`){let providerConfig=params.config?.models?.providers?.[params.model.provider],modelBaseUrl=typeof params.model.baseUrl==`string`?params.model.baseUrl.trim():``,providerBaseUrl=typeof providerConfig?.baseUrl==`string`?providerConfig.baseUrl.trim():``,llamaModelPath=modelBaseUrl||providerBaseUrl;log$3.info(`[brain-routing] run=${params.runId} api=llama model=${params.modelId} → node-llama-cpp (${llamaModelPath||`no model path`})`),activeSession.agent.streamFn=createLlamaStreamFn(llamaModelPath,{modelPath:llamaModelPath,contextSize:params.model.contextWindow})}else log$3.info(`[brain-routing] run=${params.runId} localBrain=off api=${params.model.api} model=${params.modelId} → cortex (SDK stream)`),activeSession.agent.streamFn=nativeStreamSimple;applyExtraParamsToAgent(activeSession.agent,params.config,params.provider,params.modelId,effectiveStreamParams),cacheTrace&&(cacheTrace.recordStage(`session:loaded`,{messages:activeSession.messages,system:systemPromptText,note:`after session create`}),activeSession.agent.streamFn=cacheTrace.wrapStreamFn(activeSession.agent.streamFn)),anthropicPayloadLogger&&(activeSession.agent.streamFn=anthropicPayloadLogger.wrapStreamFn(activeSession.agent.streamFn));try{let prior=await sanitizeSessionHistory({messages:activeSession.messages,modelApi:params.model.api,modelId:params.modelId,provider:params.provider,config:params.config,sessionManager,sessionId:params.sessionId,policy:transcriptPolicy});cacheTrace?.recordStage(`session:sanitized`,{messages:prior});let validatedGemini=transcriptPolicy.validateGeminiTurns?validateGeminiTurns(prior):prior,truncated=limitHistoryTurns(transcriptPolicy.validateAnthropicTurns?validateAnthropicTurns(validatedGemini):validatedGemini,getDmHistoryLimitFromSessionKey(params.sessionKey,params.config)),limited=transcriptPolicy.repairToolUseResultPairing?sanitizeToolUseResultPairing(truncated):truncated;cacheTrace?.recordStage(`session:limited`,{messages:limited}),limited.length>0&&activeSession.agent.replaceMessages(limited)}catch(err){throw await flushPendingToolResultsAfterIdle({agent:activeSession?.agent,sessionManager}),activeSession.dispose(),err}let aborted=!!params.abortSignal?.aborted,timedOut=!1,timedOutDuringCompaction=!1,getAbortReason=signal=>`reason`in signal?signal.reason:void 0,makeTimeoutAbortReason=()=>{let err=Error(`request timed out`);return err.name=`TimeoutError`,err},makeAbortError=signal=>{let reason=getAbortReason(signal),err=reason?Error(`aborted`,{cause:reason}):Error(`aborted`);return err.name=`AbortError`,err},abortRun=(isTimeout=!1,reason)=>{aborted=!0,isTimeout&&(timedOut=!0),isTimeout?runAbortController.abort(reason??makeTimeoutAbortReason()):runAbortController.abort(reason),activeSession.abort()},abortable=promise=>{let signal=runAbortController.signal;return signal.aborted?Promise.reject(makeAbortError(signal)):new Promise((resolve,reject)=>{let onAbort=()=>{signal.removeEventListener(`abort`,onAbort),reject(makeAbortError(signal))};signal.addEventListener(`abort`,onAbort,{once:!0}),promise.then(value=>{signal.removeEventListener(`abort`,onAbort),resolve(value)},err=>{signal.removeEventListener(`abort`,onAbort),reject(err)})})},subscription=subscribeEmbeddedSession({session:activeSession,runId:params.runId,hookRunner:getGlobalHookRunner()??void 0,verboseLevel:params.verboseLevel,reasoningMode:effectiveReasoningLevel,toolResultFormat:params.toolResultFormat,shouldEmitToolResult:params.shouldEmitToolResult,shouldEmitToolOutput:params.shouldEmitToolOutput,onToolResult:params.onToolResult,onReasoningStream:params.onReasoningStream,onReasoningEnd:params.onReasoningEnd,onBlockReply:params.onBlockReply,onBlockReplyFlush:params.onBlockReplyFlush,blockReplyBreak:params.blockReplyBreak,blockReplyChunking:params.blockReplyChunking,onPartialReply:params.onPartialReply,onAssistantMessageStart:params.onAssistantMessageStart,onAgentEvent:params.onAgentEvent,enforceFinalTag:params.enforceFinalTag,config:params.config,sessionKey:params.sessionKey??params.sessionId}),{assistantTexts,toolMetas,unsubscribe,waitForCompactionRetry,getMessagingToolSentTexts,getMessagingToolSentMediaUrls,getMessagingToolSentTargets,getSuccessfulCronAdds,didSendViaMessagingTool,getLastToolError,getUsageTotals,getCompactionCount}=subscription,queueHandle={queueMessage:async text=>{await activeSession.steer(text)},isStreaming:()=>activeSession.isStreaming,isCompacting:()=>subscription.isCompacting(),abort:abortRun};setActiveEmbeddedRun(params.sessionId,queueHandle,params.sessionKey);let abortWarnTimer,isProbeSession=params.sessionId?.startsWith(`probe-`)??!1,abortTimer=setTimeout(()=>{isProbeSession||log$3.warn(`embedded run timeout: runId=${params.runId} sessionId=${params.sessionId} timeoutMs=${params.timeoutMs}`),shouldFlagCompactionTimeout({isTimeout:!0,isCompactionPendingOrRetrying:subscription.isCompacting(),isCompactionInFlight:activeSession.isCompacting})&&(timedOutDuringCompaction=!0),abortRun(!0),abortWarnTimer||=setTimeout(()=>{activeSession.isStreaming&&(isProbeSession||log$3.warn(`embedded run abort still streaming: runId=${params.runId} sessionId=${params.sessionId}`))},1e4)},Math.max(1,params.timeoutMs)),messagesSnapshot=[],sessionIdUsed=activeSession.sessionId,onAbort=()=>{let reason=params.abortSignal?getAbortReason(params.abortSignal):void 0,timeout=reason?isTimeoutError(reason):!1;shouldFlagCompactionTimeout({isTimeout:timeout,isCompactionPendingOrRetrying:subscription.isCompacting(),isCompactionInFlight:activeSession.isCompacting})&&(timedOutDuringCompaction=!0),abortRun(timeout,reason)};params.abortSignal&&(params.abortSignal.aborted?onAbort():params.abortSignal.addEventListener(`abort`,onAbort,{once:!0}));let hookAgentId=typeof params.agentId==`string`&&params.agentId.trim()?normalizeAgentId(params.agentId):resolveSessionAgentIds({sessionKey:params.sessionKey,config:params.config}).sessionAgentId,promptError=null,promptErrorSource=null;try{let promptStartedAt=Date.now(),effectivePrompt=params.prompt,hookCtx={agentId:hookAgentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageProvider??void 0},promptBuildResult=hookRunner?.hasHooks(`before_prompt_build`)?await hookRunner.runBeforePromptBuild({prompt:params.prompt,messages:activeSession.messages},hookCtx).catch(hookErr=>{log$3.warn(`before_prompt_build hook failed: ${String(hookErr)}`)}):void 0,legacyResult=hookRunner?.hasHooks(`before_agent_start`)?await hookRunner.runBeforeAgentStart({prompt:params.prompt,messages:activeSession.messages},hookCtx).catch(hookErr=>{log$3.warn(`before_agent_start hook (legacy prompt build path) failed: ${String(hookErr)}`)}):void 0,hookResult={systemPrompt:promptBuildResult?.systemPrompt??legacyResult?.systemPrompt,prependContext:[promptBuildResult?.prependContext,legacyResult?.prependContext].filter(value=>!!value).join(`
537
537
 
538
- `)};hookResult?.prependContext&&(effectivePrompt=`${hookResult.prependContext}\n\n${params.prompt}`,log$3.debug(`hooks: prepended context to prompt (${hookResult.prependContext.length} chars)`)),log$3.debug(`embedded run prompt start: runId=${params.runId} sessionId=${params.sessionId}`),cacheTrace?.recordStage(`prompt:before`,{prompt:effectivePrompt,messages:activeSession.messages});let leafEntry=sessionManager.getLeafEntry();if(leafEntry?.type===`message`&&leafEntry.message.role===`user`){leafEntry.parentId?sessionManager.branch(leafEntry.parentId):sessionManager.resetLeaf();let sessionContext=sessionManager.buildSessionContext(),sanitizedOrphan=transcriptPolicy.normalizeAntigravityThinkingBlocks?sanitizeAntigravityThinkingBlocks(sessionContext.messages):sessionContext.messages;activeSession.agent.replaceMessages(sanitizedOrphan),log$3.warn(`Removed orphaned user message to prevent consecutive user turns. runId=${params.runId} sessionId=${params.sessionId}`)}try{let imageResult=await detectAndLoadPromptImages({prompt:effectivePrompt,workspaceDir:effectiveWorkspace,model:params.model,existingImages:params.images,historyMessages:activeSession.messages,maxBytes:MAX_IMAGE_BYTES,maxDimensionPx:resolveImageSanitizationLimits(params.config).maxDimensionPx,sandbox:sandbox?.enabled&&sandbox?.fsBridge?{root:sandbox.workspaceDir,bridge:sandbox.fsBridge}:void 0});if(injectHistoryImagesIntoMessages(activeSession.messages,imageResult.historyImagesByIndex)&&activeSession.agent.replaceMessages(activeSession.messages),cacheTrace?.recordStage(`prompt:images`,{prompt:effectivePrompt,messages:activeSession.messages,note:`images: prompt=${imageResult.images.length} history=${imageResult.historyImagesByIndex.size}`}),log$3.isEnabled(`debug`)){let msgCount=activeSession.messages.length,systemLen=systemPromptText?.length??0,promptLen=effectivePrompt.length,sessionSummary=summarizeSessionContext(activeSession.messages);log$3.debug(`[context-diag] pre-prompt: sessionKey=${params.sessionKey??params.sessionId} messages=${msgCount} roleCounts=${sessionSummary.roleCounts} historyTextChars=${sessionSummary.totalTextChars} maxMessageTextChars=${sessionSummary.maxMessageTextChars} historyImageBlocks=${sessionSummary.totalImageBlocks} systemPromptChars=${systemLen} promptChars=${promptLen} promptImages=${imageResult.images.length} historyImageMessages=${imageResult.historyImagesByIndex.size} provider=${params.provider}/${params.modelId} sessionFile=${params.sessionFile}`)}hookRunner?.hasHooks(`llm_input`)&&hookRunner.runLlmInput({runId:params.runId,sessionId:params.sessionId,provider:params.provider,model:params.modelId,systemPrompt:systemPromptText,prompt:effectivePrompt,historyMessages:activeSession.messages,imagesCount:imageResult.images.length},{agentId:hookAgentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageProvider??void 0}).catch(err=>{log$3.warn(`llm_input hook failed: ${String(err)}`)}),imageResult.images.length>0?await abortable(activeSession.prompt(effectivePrompt,{images:imageResult.images})):await abortable(activeSession.prompt(effectivePrompt))}catch(err){promptError=err,promptErrorSource=`prompt`}finally{log$3.debug(`embedded run prompt end: runId=${params.runId} sessionId=${params.sessionId} durationMs=${Date.now()-promptStartedAt}`)}let wasCompactingBefore=activeSession.isCompacting,snapshot=activeSession.messages.slice(),wasCompactingAfter=activeSession.isCompacting,preCompactionSnapshot=wasCompactingBefore||wasCompactingAfter?null:snapshot,preCompactionSessionId=activeSession.sessionId;try{await abortable(waitForCompactionRetry())}catch(err){if(isRunnerAbortError(err))promptError||(promptError=err,promptErrorSource=`compaction`),isProbeSession||log$3.debug(`compaction wait aborted: runId=${params.runId} sessionId=${params.sessionId}`);else throw err}timedOutDuringCompaction||params.config?.agents?.defaults?.contextPruning?.mode===`cache-ttl`&&isCacheTtlEligibleProvider(params.provider,params.modelId)&&appendCacheTtlTimestamp(sessionManager,{timestamp:Date.now(),provider:params.provider,modelId:params.modelId});let snapshotSelection=selectCompactionTimeoutSnapshot({timedOutDuringCompaction,preCompactionSnapshot,preCompactionSessionId,currentSnapshot:activeSession.messages.slice(),currentSessionId:activeSession.sessionId});if(timedOutDuringCompaction&&(isProbeSession||log$3.warn(`using ${snapshotSelection.source} snapshot: timed out during compaction runId=${params.runId} sessionId=${params.sessionId}`)),messagesSnapshot=snapshotSelection.messagesSnapshot,sessionIdUsed=snapshotSelection.sessionIdUsed,promptError&&promptErrorSource===`prompt`)try{sessionManager.appendCustomEntry(`builderforce:prompt-error`,{timestamp:Date.now(),runId:params.runId,sessionId:params.sessionId,provider:params.provider,model:params.modelId,api:params.model.api,error:describeUnknownError(promptError)})}catch(entryErr){log$3.warn(`failed to persist prompt error entry: ${String(entryErr)}`)}cacheTrace?.recordStage(`session:after`,{messages:messagesSnapshot,note:timedOutDuringCompaction?`compaction timeout`:promptError?`prompt error`:void 0}),anthropicPayloadLogger?.recordUsage(messagesSnapshot,promptError),hookRunner?.hasHooks(`agent_end`)&&hookRunner.runAgentEnd({messages:messagesSnapshot,success:!aborted&&!promptError,error:promptError?describeUnknownError(promptError):void 0,durationMs:Date.now()-promptStartedAt},{agentId:hookAgentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageProvider??void 0}).catch(err=>{log$3.warn(`agent_end hook failed: ${err}`)})}finally{clearTimeout(abortTimer),abortWarnTimer&&clearTimeout(abortWarnTimer),!isProbeSession&&(aborted||timedOut)&&!timedOutDuringCompaction&&log$3.debug(`run cleanup: runId=${params.runId} sessionId=${params.sessionId} aborted=${aborted} timedOut=${timedOut}`);try{unsubscribe()}catch(err){log$3.error(`CRITICAL: unsubscribe failed, possible resource leak: runId=${params.runId} ${String(err)}`)}clearActiveEmbeddedRun(params.sessionId,queueHandle,params.sessionKey),params.abortSignal?.removeEventListener?.(`abort`,onAbort)}let lastAssistant=messagesSnapshot.slice().toReversed().find(m=>m.role===`assistant`),toolMetasNormalized=toolMetas.filter(entry=>typeof entry.toolName==`string`&&entry.toolName.trim().length>0).map(entry=>({toolName:entry.toolName,meta:entry.meta}));return hookRunner?.hasHooks(`llm_output`)&&hookRunner.runLlmOutput({runId:params.runId,sessionId:params.sessionId,provider:params.provider,model:params.modelId,assistantTexts,lastAssistant,usage:getUsageTotals()},{agentId:hookAgentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageProvider??void 0}).catch(err=>{log$3.warn(`llm_output hook failed: ${String(err)}`)}),{aborted,timedOut,timedOutDuringCompaction,promptError,sessionIdUsed,systemPromptReport,messagesSnapshot,assistantTexts,toolMetas:toolMetasNormalized,lastAssistant,lastToolError:getLastToolError?.(),didSendViaMessagingTool:didSendViaMessagingTool(),messagingToolSentTexts:getMessagingToolSentTexts(),messagingToolSentMediaUrls:getMessagingToolSentMediaUrls(),messagingToolSentTargets:getMessagingToolSentTargets(),successfulCronAdds:getSuccessfulCronAdds(),cloudCodeAssistFormatError:!!(lastAssistant?.errorMessage&&isCloudCodeAssistFormatError(lastAssistant.errorMessage)),attemptUsage:getUsageTotals(),compactionCount:getCompactionCount(),clientToolCall:clientToolCallDetected??void 0}}finally{removeToolResultContextGuard?.(),await flushPendingToolResultsAfterIdle({agent:session?.agent,sessionManager}),session?.dispose(),await sessionLock.release()}}finally{restoreSkillEnv?.(),process.chdir(prevCwd)}}const RECOVERABLE_TOOL_ERROR_KEYWORDS=[`required`,`missing`,`invalid`,`must be`,`must have`,`needs`,`requires`];function isRecoverableToolError(error){let errorLower=(error??``).toLowerCase();return RECOVERABLE_TOOL_ERROR_KEYWORDS.some(keyword=>errorLower.includes(keyword))}function shouldShowToolErrorWarning(params){if(params.suppressToolErrorWarnings)return!1;let normalizedToolName=params.lastToolError.toolName.trim().toLowerCase(),verboseEnabled=params.verboseLevel===`on`||params.verboseLevel===`full`;return(normalizedToolName===`exec`||normalizedToolName===`bash`)&&!verboseEnabled?!1:params.lastToolError.mutatingAction??isLikelyMutatingToolName(params.lastToolError.toolName)?!0:params.suppressToolErrors?!1:!params.hasUserFacingReply&&!isRecoverableToolError(params.lastToolError.error)}function buildEmbeddedRunPayloads(params){let replyItems=[],useMarkdown=params.toolResultFormat===`markdown`,lastAssistantErrored=params.lastAssistant?.stopReason===`error`,errorText=params.lastAssistant?formatAssistantErrorText(params.lastAssistant,{cfg:params.config,sessionKey:params.sessionKey,provider:params.provider,model:params.model}):void 0,rawErrorMessage=lastAssistantErrored&&params.lastAssistant?.errorMessage?.trim()||void 0,rawErrorFingerprint=rawErrorMessage?getApiErrorPayloadFingerprint(rawErrorMessage):null,formattedRawErrorMessage=rawErrorMessage?formatRawAssistantErrorForUi(rawErrorMessage):null,normalizedFormattedRawErrorMessage=formattedRawErrorMessage?normalizeTextForComparison(formattedRawErrorMessage):null,normalizedRawErrorText=rawErrorMessage?normalizeTextForComparison(rawErrorMessage):null,normalizedErrorText=errorText?normalizeTextForComparison(errorText):null,normalizedGenericBillingErrorText=normalizeTextForComparison(BILLING_ERROR_USER_MESSAGE);if(errorText&&replyItems.push({text:errorText,isError:!0}),params.inlineToolResultsAllowed&&params.verboseLevel!==`off`&&params.toolMetas.length>0)for(let{toolName,meta}of params.toolMetas){let{text:cleanedText,mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent}=parseReplyDirectives(formatToolAggregate(toolName,meta?[meta]:[],{markdown:useMarkdown}));cleanedText&&replyItems.push({text:cleanedText,media:mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent})}let reasoningText=params.lastAssistant&&params.reasoningLevel===`on`?formatReasoningMessage(extractAssistantThinking(params.lastAssistant)):``;reasoningText&&replyItems.push({text:reasoningText});let fallbackAnswerText=params.lastAssistant?extractAssistantText$1(params.lastAssistant):``,shouldSuppressRawErrorText=text=>{if(!lastAssistantErrored)return!1;let trimmed=text.trim();if(!trimmed)return!1;if(errorText){let normalized=normalizeTextForComparison(trimmed);if(normalized&&normalizedErrorText&&normalized===normalizedErrorText||trimmed===`The AI service returned an error. Please try again.`||normalized&&normalizedGenericBillingErrorText&&normalized===normalizedGenericBillingErrorText)return!0}if(rawErrorMessage&&trimmed===rawErrorMessage||formattedRawErrorMessage&&trimmed===formattedRawErrorMessage)return!0;if(normalizedRawErrorText){let normalized=normalizeTextForComparison(trimmed);if(normalized&&normalized===normalizedRawErrorText)return!0}if(normalizedFormattedRawErrorMessage){let normalized=normalizeTextForComparison(trimmed);if(normalized&&normalized===normalizedFormattedRawErrorMessage)return!0}if(rawErrorFingerprint){let fingerprint=getApiErrorPayloadFingerprint(trimmed);if(fingerprint&&fingerprint===rawErrorFingerprint)return!0}return isRawApiErrorPayload(trimmed)},answerTexts=(params.assistantTexts.length?params.assistantTexts:fallbackAnswerText?[fallbackAnswerText]:[]).filter(text=>!shouldSuppressRawErrorText(text)),hasUserFacingAssistantReply=!1;for(let text of answerTexts){let{text:cleanedText,mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent}=parseReplyDirectives(text);!cleanedText&&(!mediaUrls||mediaUrls.length===0)&&!audioAsVoice||(replyItems.push({text:cleanedText,media:mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent}),hasUserFacingAssistantReply=!0)}if(params.lastToolError&&shouldShowToolErrorWarning({lastToolError:params.lastToolError,hasUserFacingReply:hasUserFacingAssistantReply,suppressToolErrors:!!params.config?.messages?.suppressToolErrors,suppressToolErrorWarnings:params.suppressToolErrorWarnings,verboseLevel:params.verboseLevel})){let warningText=`⚠️ ${formatToolAggregate(params.lastToolError.toolName,params.lastToolError.meta?[params.lastToolError.meta]:void 0,{markdown:useMarkdown})} failed${params.lastToolError.error?`: ${params.lastToolError.error}`:``}`,normalizedWarning=normalizeTextForComparison(warningText);normalizedWarning&&replyItems.some(item=>{if(!item.text)return!1;let normalizedExisting=normalizeTextForComparison(item.text);return normalizedExisting.length>0&&normalizedExisting===normalizedWarning})||replyItems.push({text:warningText,isError:!0})}let hasAudioAsVoiceTag=replyItems.some(item=>item.audioAsVoice);return replyItems.map(item=>({text:item.text?.trim()?item.text.trim():void 0,mediaUrls:item.media?.length?item.media:void 0,mediaUrl:item.media?.[0],isError:item.isError,replyToId:item.replyToId,replyToTag:item.replyToTag,replyToCurrent:item.replyToCurrent,audioAsVoice:item.audioAsVoice||!!(hasAudioAsVoiceTag&&item.media?.length)})).filter(p=>!(!p.text&&!p.mediaUrl&&(!p.mediaUrls||p.mediaUrls.length===0)||p.text&&isSilentReplyText(p.text,SILENT_REPLY_TOKEN)))}const ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL=`ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL`;function scrubAnthropicRefusalMagic(prompt){return prompt.includes(ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL)?prompt.replaceAll(ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL,`ANTHROPIC MAGIC STRING TRIGGER REFUSAL (redacted)`):prompt}const createUsageAccumulator=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,total:0,lastCacheRead:0,lastCacheWrite:0,lastInput:0});function createCompactionDiagId(){return`ovf-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}const hasUsageValues=usage=>!!usage&&[usage.input,usage.output,usage.cacheRead,usage.cacheWrite,usage.total].some(value=>typeof value==`number`&&Number.isFinite(value)&&value>0),mergeUsageIntoAccumulator=(target,usage)=>{hasUsageValues(usage)&&(target.input+=usage.input??0,target.output+=usage.output??0,target.cacheRead+=usage.cacheRead??0,target.cacheWrite+=usage.cacheWrite??0,target.total+=usage.total??(usage.input??0)+(usage.output??0)+(usage.cacheRead??0)+(usage.cacheWrite??0),target.lastCacheRead=usage.cacheRead??0,target.lastCacheWrite=usage.cacheWrite??0,target.lastInput=usage.input??0)},toNormalizedUsage=usage=>{if(!(usage.input>0||usage.output>0||usage.cacheRead>0||usage.cacheWrite>0||usage.total>0))return;let lastPromptTokens=usage.lastInput+usage.lastCacheRead+usage.lastCacheWrite;return{input:usage.lastInput||void 0,output:usage.output||void 0,cacheRead:usage.lastCacheRead||void 0,cacheWrite:usage.lastCacheWrite||void 0,total:lastPromptTokens+usage.output||void 0}};function resolveActiveErrorContext(params){return{provider:params.lastAssistant?.provider??params.provider,model:params.lastAssistant?.model??params.model}}async function runEmbeddedAgent(params){let sessionLane=resolveSessionLane(params.sessionKey?.trim()||params.sessionId),globalLane=resolveGlobalLane(params.lane),enqueueGlobal=params.enqueue??((task,opts)=>enqueueCommandInLane(globalLane,task,opts)),enqueueSession=params.enqueue??((task,opts)=>enqueueCommandInLane(sessionLane,task,opts)),channelHint=params.messageChannel??params.messageProvider,resolvedToolResultFormat=params.toolResultFormat??(channelHint?isMarkdownCapableMessageChannel(channelHint)?`markdown`:`plain`:`markdown`),isProbeSession=params.sessionId?.startsWith(`probe-`)??!1,outcome={actionType:DEFAULT_ACTION_TYPE,provider:``,model:``,steps:0,degraded:!1},reportOutcome=(terminalStatus,error)=>{if(!outcome.model||isProbeSession)return;let rateLimited=isFailoverError(error)&&error.reason===`rate_limit`;completeLearnedRun({runId:params.runId,model:`${outcome.provider}/${outcome.model}`,actionType:outcome.actionType,terminalStatus,rateLimited,degraded:outcome.degraded,steps:outcome.steps})};return enqueueSession(()=>enqueueGlobal(async()=>{let started=Date.now(),workspaceResolution=resolveRunWorkspaceDir({workspaceDir:params.workspaceDir,sessionKey:params.sessionKey,agentId:params.agentId,config:params.config}),resolvedWorkspace=workspaceResolution.workspaceDir,redactedSessionId=redactRunIdentifier(params.sessionId),redactedSessionKey=redactRunIdentifier(params.sessionKey),redactedWorkspace=redactRunIdentifier(resolvedWorkspace);workspaceResolution.usedFallback&&log$3.warn(`[workspace-fallback] caller=runEmbeddedAgent reason=${workspaceResolution.fallbackReason} run=${params.runId} session=${redactedSessionId} sessionKey=${redactedSessionKey} agent=${workspaceResolution.agentId} workspace=${redactedWorkspace}`);let prevCwd=process.cwd(),provider=(params.provider??DEFAULT_PROVIDER).trim()||DEFAULT_PROVIDER,modelId=(params.model??DEFAULT_MODEL).trim()||DEFAULT_MODEL,agentDir=params.agentDir??resolveBuilderForceAgentsAgentDir(),fallbackConfigured=(params.config?.agents?.defaults?.model?.fallbacks?.length??0)>0;await ensureBuilderForceAgentsModelsJson(params.config,agentDir);let modelResolveOverride,hookRunner=getGlobalHookRunner(),hookCtx={agentId:workspaceResolution.agentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:resolvedWorkspace,messageProvider:params.messageProvider??void 0};if(hookRunner?.hasHooks(`before_model_resolve`))try{modelResolveOverride=await hookRunner.runBeforeModelResolve({prompt:params.prompt},hookCtx)}catch(hookErr){log$3.warn(`before_model_resolve hook failed: ${String(hookErr)}`)}if(hookRunner?.hasHooks(`before_agent_start`))try{let legacyResult=await hookRunner.runBeforeAgentStart({prompt:params.prompt},hookCtx);modelResolveOverride={providerOverride:modelResolveOverride?.providerOverride??legacyResult?.providerOverride,modelOverride:modelResolveOverride?.modelOverride??legacyResult?.modelOverride}}catch(hookErr){log$3.warn(`before_agent_start hook (legacy model resolve path) failed: ${String(hookErr)}`)}modelResolveOverride?.providerOverride&&(provider=modelResolveOverride.providerOverride,log$3.info(`[hooks] provider overridden to ${provider}`)),modelResolveOverride?.modelOverride&&(modelId=modelResolveOverride.modelOverride,log$3.info(`[hooks] model overridden to ${modelId}`));let learnedSeed=await resolveLearnedModelSeed({provider,modelId,prompt:params.prompt,cfg:params.config});outcome.actionType=learnedSeed.actionType,learnedSeed.reordered&&(learnedSeed.provider!==provider||learnedSeed.modelId!==modelId)&&(log$3.info(`[learned-routing] seeding ${learnedSeed.provider}/${learnedSeed.modelId} over ${provider}/${modelId} (action=${learnedSeed.actionType} scope=${learnedSeed.scope??`none`})`),provider=learnedSeed.provider,modelId=learnedSeed.modelId);let{model,error,authStorage,modelRegistry}=resolveModel(provider,modelId,agentDir,params.config);if(!model)throw Error(error??`Unknown model: ${provider}/${modelId}`);outcome.provider=provider,outcome.model=model.id;let ctxInfo=resolveContextWindowInfo({cfg:params.config,provider,modelId,modelContextWindow:model.contextWindow,defaultTokens:DEFAULT_CONTEXT_TOKENS}),ctxGuard=evaluateContextWindowGuard({info:ctxInfo,warnBelowTokens:CONTEXT_WINDOW_WARN_BELOW_TOKENS,hardMinTokens:CONTEXT_WINDOW_HARD_MIN_TOKENS});if(ctxGuard.shouldWarn&&log$3.warn(`low context window: ${provider}/${modelId} ctx=${ctxGuard.tokens} (warn<${CONTEXT_WINDOW_WARN_BELOW_TOKENS}) source=${ctxGuard.source}`),ctxGuard.shouldBlock)throw log$3.error(`blocked model (context window too small): ${provider}/${modelId} ctx=${ctxGuard.tokens} (min=${CONTEXT_WINDOW_HARD_MIN_TOKENS}) source=${ctxGuard.source}`),new FailoverError(`Model context window too small (${ctxGuard.tokens} tokens). Minimum is ${CONTEXT_WINDOW_HARD_MIN_TOKENS}.`,{reason:`unknown`,provider,model:modelId});let authStore=await ensureAuthProfileStore(agentDir,{allowKeychainPrompt:!1}),preferredProfileId=params.authProfileId?.trim(),lockedProfileId=params.authProfileIdSource===`user`?preferredProfileId:void 0;if(lockedProfileId){let lockedProfile=authStore.profiles[lockedProfileId];(!lockedProfile||normalizeProviderId(lockedProfile.provider)!==normalizeProviderId(provider))&&(lockedProfileId=void 0)}let profileOrder=resolveAuthProfileOrder({cfg:params.config,store:authStore,provider,preferredProfile:preferredProfileId});if(lockedProfileId&&!profileOrder.includes(lockedProfileId))throw Error(`Auth profile "${lockedProfileId}" is not configured for ${provider}.`);let profileCandidates=lockedProfileId?[lockedProfileId]:profileOrder.length>0?profileOrder:[void 0],profileIndex=0,initialThinkLevel=params.thinkLevel??`off`,thinkLevel=initialThinkLevel,attemptedThinking=new Set,apiKeyInfo=null,lastProfileId,resolveAuthProfileFailoverReason=params=>params.allInCooldown?`rate_limit`:classifyFailoverReason(params.message)??`auth`,throwAuthProfileFailover=params=>{let fallbackMessage=`No available auth profile for ${provider} (all in cooldown or unavailable).`,message=params.message?.trim()||(params.error?describeUnknownError(params.error).trim():``)||fallbackMessage,reason=resolveAuthProfileFailoverReason({allInCooldown:params.allInCooldown,message});throw fallbackConfigured?new FailoverError(message,{reason,provider,model:modelId,status:resolveFailoverStatus(reason),cause:params.error}):params.error instanceof Error?params.error:Error(message)},resolveApiKeyForCandidate=async candidate=>getApiKeyForModel({model,cfg:params.config,profileId:candidate,store:authStore,agentDir}),applyApiKeyInfo=async candidate=>{apiKeyInfo=await resolveApiKeyForCandidate(candidate);let resolvedProfileId=apiKeyInfo.profileId??candidate;if(!apiKeyInfo.apiKey){if(apiKeyInfo.mode!==`aws-sdk`)throw Error(`No API key resolved for provider "${model.provider}" (auth mode: ${apiKeyInfo.mode}).`);lastProfileId=resolvedProfileId;return}if(model.provider===`github-copilot`){let{resolveCopilotApiToken}=await import(`./github-copilot-token-DHP2kAiN.js`),copilotToken=await resolveCopilotApiToken({githubToken:apiKeyInfo.apiKey});authStorage.setRuntimeApiKey(model.provider,copilotToken.token)}else authStorage.setRuntimeApiKey(model.provider,apiKeyInfo.apiKey);lastProfileId=apiKeyInfo.profileId},advanceAuthProfile=async()=>{if(lockedProfileId)return!1;let nextIndex=profileIndex+1;for(;nextIndex<profileCandidates.length;){let candidate=profileCandidates[nextIndex];if(candidate&&isProfileInCooldown(authStore,candidate)){nextIndex+=1;continue}try{return await applyApiKeyInfo(candidate),profileIndex=nextIndex,thinkLevel=initialThinkLevel,attemptedThinking.clear(),!0}catch(err){if(candidate&&candidate===lockedProfileId)throw err;nextIndex+=1}}return!1};try{for(;profileIndex<profileCandidates.length;){let candidate=profileCandidates[profileIndex];if(candidate&&candidate!==lockedProfileId&&isProfileInCooldown(authStore,candidate)){profileIndex+=1;continue}await applyApiKeyInfo(profileCandidates[profileIndex]);break}profileIndex>=profileCandidates.length&&throwAuthProfileFailover({allInCooldown:!0})}catch(err){if(err instanceof FailoverError)throw err;profileCandidates[profileIndex]===lockedProfileId&&throwAuthProfileFailover({allInCooldown:!1,error:err}),await advanceAuthProfile()||throwAuthProfileFailover({allInCooldown:!1,error:err})}let MAX_AUTO_CONTINUE_NUDGES=params.config?.agents?.defaults?.maxAutoContinueNudges??3,overflowCompactionAttempts=0,toolResultTruncationAttempted=!1,autoContinueNudges=0,currentPrompt=params.prompt,usageAccumulator=createUsageAccumulator(),lastRunPromptUsage,autoCompactionCount=0;try{for(;;){attemptedThinking.add(thinkLevel),await fs$1.mkdir(resolvedWorkspace,{recursive:!0});let prompt=provider===`anthropic`?scrubAnthropicRefusalMagic(currentPrompt):currentPrompt,attempt=await runEmbeddedAttempt({sessionId:params.sessionId,sessionKey:params.sessionKey,messageChannel:params.messageChannel,messageProvider:params.messageProvider,agentAccountId:params.agentAccountId,messageTo:params.messageTo,messageThreadId:params.messageThreadId,groupId:params.groupId,groupChannel:params.groupChannel,groupSpace:params.groupSpace,spawnedBy:params.spawnedBy,senderIsOwner:params.senderIsOwner,currentChannelId:params.currentChannelId,currentThreadTs:params.currentThreadTs,replyToMode:params.replyToMode,hasRepliedRef:params.hasRepliedRef,sessionFile:params.sessionFile,workspaceDir:resolvedWorkspace,agentDir,config:params.config,skillsSnapshot:params.skillsSnapshot,prompt,images:params.images,disableTools:params.disableTools,provider,modelId,model,authStorage,modelRegistry,agentId:workspaceResolution.agentId,thinkLevel,verboseLevel:params.verboseLevel,reasoningLevel:params.reasoningLevel,toolResultFormat:resolvedToolResultFormat,execOverrides:params.execOverrides,bashElevated:params.bashElevated,timeoutMs:params.timeoutMs,runId:params.runId,abortSignal:params.abortSignal,shouldEmitToolResult:params.shouldEmitToolResult,shouldEmitToolOutput:params.shouldEmitToolOutput,onPartialReply:params.onPartialReply,onAssistantMessageStart:params.onAssistantMessageStart,onBlockReply:params.onBlockReply,onBlockReplyFlush:params.onBlockReplyFlush,blockReplyBreak:params.blockReplyBreak,blockReplyChunking:params.blockReplyChunking,onReasoningStream:params.onReasoningStream,onReasoningEnd:params.onReasoningEnd,onToolResult:params.onToolResult,onAgentEvent:params.onAgentEvent,extraSystemPrompt:params.extraSystemPrompt,inputProvenance:params.inputProvenance,streamParams:params.streamParams,ownerNumbers:params.ownerNumbers,enforceFinalTag:params.enforceFinalTag}),{aborted,promptError,timedOut,timedOutDuringCompaction,sessionIdUsed,lastAssistant}=attempt,lastAssistantUsage=normalizeUsage(lastAssistant?.usage),attemptUsage=attempt.attemptUsage??lastAssistantUsage;mergeUsageIntoAccumulator(usageAccumulator,attemptUsage),lastRunPromptUsage=lastAssistantUsage??attemptUsage;let lastTurnTotal=lastAssistantUsage?.total??attemptUsage?.total,attemptCompactionCount=Math.max(0,attempt.compactionCount??0);autoCompactionCount+=attemptCompactionCount;let activeErrorContext=resolveActiveErrorContext({lastAssistant,provider,model:modelId}),formattedAssistantErrorText=lastAssistant?formatAssistantErrorText(lastAssistant,{cfg:params.config,sessionKey:params.sessionKey??params.sessionId,provider:activeErrorContext.provider,model:activeErrorContext.model}):void 0,assistantErrorText=lastAssistant?.stopReason===`error`?lastAssistant.errorMessage?.trim()||formattedAssistantErrorText:void 0,contextOverflowError=aborted?null:(()=>{if(promptError){let errorText=describeUnknownError(promptError);return isLikelyContextOverflowError(errorText)?{text:errorText,source:`promptError`}:null}return assistantErrorText&&isLikelyContextOverflowError(assistantErrorText)?{text:assistantErrorText,source:`assistantError`}:null})();if(contextOverflowError){let overflowDiagId=createCompactionDiagId(),errorText=contextOverflowError.text,msgCount=attempt.messagesSnapshot?.length??0;log$3.warn(`[context-overflow-diag] sessionKey=${params.sessionKey??params.sessionId} provider=${provider}/${modelId} source=${contextOverflowError.source} messages=${msgCount} sessionFile=${params.sessionFile} diagId=${overflowDiagId} compactionAttempts=${overflowCompactionAttempts} error=${errorText.slice(0,200)}`);let isCompactionFailure=isCompactionFailureError(errorText),hadAttemptLevelCompaction=attemptCompactionCount>0;if(!isCompactionFailure&&hadAttemptLevelCompaction&&overflowCompactionAttempts<3){overflowCompactionAttempts++,log$3.warn(`context overflow persisted after in-attempt compaction (attempt ${overflowCompactionAttempts}/3); retrying prompt without additional compaction for ${provider}/${modelId}`);continue}if(!isCompactionFailure&&!hadAttemptLevelCompaction&&overflowCompactionAttempts<3){log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=compact isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=unknown attempt=${overflowCompactionAttempts+1} maxAttempts=3`),overflowCompactionAttempts++,log$3.warn(`context overflow detected (attempt ${overflowCompactionAttempts}/3); attempting auto-compaction for ${provider}/${modelId}`);let compactResult=await compactEmbeddedSessionDirect({sessionId:params.sessionId,sessionKey:params.sessionKey,messageChannel:params.messageChannel,messageProvider:params.messageProvider,agentAccountId:params.agentAccountId,authProfileId:lastProfileId,sessionFile:params.sessionFile,workspaceDir:resolvedWorkspace,agentDir,config:params.config,skillsSnapshot:params.skillsSnapshot,senderIsOwner:params.senderIsOwner,provider,model:modelId,runId:params.runId,thinkLevel,reasoningLevel:params.reasoningLevel,bashElevated:params.bashElevated,extraSystemPrompt:params.extraSystemPrompt,ownerNumbers:params.ownerNumbers,trigger:`overflow`,diagId:overflowDiagId,attempt:overflowCompactionAttempts,maxAttempts:3});if(compactResult.compacted){autoCompactionCount+=1,log$3.info(`auto-compaction succeeded for ${provider}/${modelId}; retrying prompt`);continue}log$3.warn(`auto-compaction failed for ${provider}/${modelId}: ${compactResult.reason??`nothing to compact`}`)}if(!toolResultTruncationAttempted){let contextWindowTokens=ctxInfo.tokens,hasOversized=attempt.messagesSnapshot?sessionLikelyHasOversizedToolResults({messages:attempt.messagesSnapshot,contextWindowTokens}):!1;if(hasOversized){log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=truncate_tool_results isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=${hasOversized} attempt=${overflowCompactionAttempts} maxAttempts=3`),toolResultTruncationAttempted=!0,log$3.warn(`[context-overflow-recovery] Attempting tool result truncation for ${provider}/${modelId} (contextWindow=${contextWindowTokens} tokens)`);let truncResult=await truncateOversizedToolResultsInSession({sessionFile:params.sessionFile,contextWindowTokens,sessionId:params.sessionId,sessionKey:params.sessionKey});if(truncResult.truncated){log$3.info(`[context-overflow-recovery] Truncated ${truncResult.truncatedCount} tool result(s); retrying prompt`),overflowCompactionAttempts=0;continue}log$3.warn(`[context-overflow-recovery] Tool result truncation did not help: ${truncResult.reason??`unknown`}`)}else log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=give_up isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=${hasOversized} attempt=${overflowCompactionAttempts} maxAttempts=3`)}(isCompactionFailure||overflowCompactionAttempts>=3||toolResultTruncationAttempted)&&log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=give_up isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=unknown attempt=${overflowCompactionAttempts} maxAttempts=3`);let kind=isCompactionFailure?`compaction_failure`:`context_overflow`;return{payloads:[{text:`Context overflow: prompt too large for the model. Try /reset (or /new) to start a fresh session, or use a larger-context model.`,isError:!0}],meta:{durationMs:Date.now()-started,agentMeta:{sessionId:sessionIdUsed,provider,model:model.id},systemPromptReport:attempt.systemPromptReport,error:{kind,message:errorText}}}}if(promptError&&!aborted){let errorText=describeUnknownError(promptError);if(/incorrect role information|roles must alternate/i.test(errorText))return{payloads:[{text:`Message ordering conflict - please try again. If this persists, use /new to start a fresh session.`,isError:!0}],meta:{durationMs:Date.now()-started,agentMeta:{sessionId:sessionIdUsed,provider,model:model.id},systemPromptReport:attempt.systemPromptReport,error:{kind:`role_ordering`,message:errorText}}};let imageSizeError=parseImageSizeError(errorText);if(imageSizeError){let maxMb=imageSizeError.maxMb,maxMbLabel=typeof maxMb==`number`&&Number.isFinite(maxMb)?`${maxMb}`:null;return{payloads:[{text:`Image too large for the model${maxMbLabel?` (max ${maxMbLabel}MB)`:``}. Please compress or resize the image and try again.`,isError:!0}],meta:{durationMs:Date.now()-started,agentMeta:{sessionId:sessionIdUsed,provider,model:model.id},systemPromptReport:attempt.systemPromptReport,error:{kind:`image_size`,message:errorText}}}}let promptFailoverReason=classifyFailoverReason(errorText);if(promptFailoverReason&&promptFailoverReason!==`timeout`&&lastProfileId&&await markAuthProfileFailure({store:authStore,profileId:lastProfileId,reason:promptFailoverReason,cfg:params.config,agentDir:params.agentDir}),isFailoverErrorMessage(errorText)&&promptFailoverReason!==`timeout`&&await advanceAuthProfile())continue;let fallbackThinking=pickFallbackThinkingLevel({message:errorText,attempted:attemptedThinking});if(fallbackThinking){log$3.warn(`unsupported thinking level for ${provider}/${modelId}; retrying with ${fallbackThinking}`),thinkLevel=fallbackThinking;continue}throw fallbackConfigured&&isFailoverErrorMessage(errorText)?new FailoverError(errorText,{reason:promptFailoverReason??`unknown`,provider,model:modelId,profileId:lastProfileId,status:resolveFailoverStatus(promptFailoverReason??`unknown`)}):promptError}let fallbackThinking=pickFallbackThinkingLevel({message:lastAssistant?.errorMessage,attempted:attemptedThinking});if(fallbackThinking&&!aborted){log$3.warn(`unsupported thinking level for ${provider}/${modelId}; retrying with ${fallbackThinking}`),thinkLevel=fallbackThinking;continue}let authFailure=isAuthAssistantError(lastAssistant),rateLimitFailure=isRateLimitAssistantError(lastAssistant),billingFailure=isBillingAssistantError(lastAssistant),failoverFailure=isFailoverAssistantError(lastAssistant),assistantFailoverReason=classifyFailoverReason(lastAssistant?.errorMessage??``),cloudCodeAssistFormatError=attempt.cloudCodeAssistFormatError,imageDimensionError=parseImageDimensionError(lastAssistant?.errorMessage??``);if(imageDimensionError&&lastProfileId){let details=[imageDimensionError.messageIndex===void 0?null:`message=${imageDimensionError.messageIndex}`,imageDimensionError.contentIndex===void 0?null:`content=${imageDimensionError.contentIndex}`,imageDimensionError.maxDimensionPx===void 0?null:`limit=${imageDimensionError.maxDimensionPx}px`].filter(Boolean).join(` `);log$3.warn(`Profile ${lastProfileId} rejected image payload${details?` (${details})`:``}.`)}if(!aborted&&failoverFailure||timedOut&&!timedOutDuringCompaction){if(lastProfileId&&(await markAuthProfileFailure({store:authStore,profileId:lastProfileId,reason:timedOut||assistantFailoverReason===`timeout`?`timeout`:assistantFailoverReason??`unknown`,cfg:params.config,agentDir:params.agentDir}),timedOut&&!isProbeSession&&log$3.warn(`Profile ${lastProfileId} timed out (possible rate limit). Trying next account...`),cloudCodeAssistFormatError&&log$3.warn(`Profile ${lastProfileId} hit Cloud Code Assist format error. Tool calls will be sanitized on retry.`)),await advanceAuthProfile())continue;if(fallbackConfigured){let message=(lastAssistant?formatAssistantErrorText(lastAssistant,{cfg:params.config,sessionKey:params.sessionKey??params.sessionId,provider:activeErrorContext.provider,model:activeErrorContext.model}):void 0)||lastAssistant?.errorMessage?.trim()||(timedOut?`LLM request timed out.`:rateLimitFailure?`LLM request rate limited.`:billingFailure?formatBillingErrorMessage(activeErrorContext.provider,activeErrorContext.model):authFailure?`LLM request unauthorized.`:`LLM request failed.`),status=resolveFailoverStatus(assistantFailoverReason??`unknown`)??(isTimeoutErrorMessage(message)?408:void 0);throw new FailoverError(message,{reason:assistantFailoverReason??`unknown`,provider:activeErrorContext.provider,model:activeErrorContext.model,profileId:lastProfileId,status})}}let usage=toNormalizedUsage(usageAccumulator);usage&&lastTurnTotal&&lastTurnTotal>0&&(usage.total=lastTurnTotal);let lastCallUsage=normalizeUsage(lastAssistant?.usage),promptTokens=derivePromptTokens(lastRunPromptUsage);outcome.provider=lastAssistant?.provider??provider,outcome.model=lastAssistant?.model??model.id,outcome.steps=(Array.isArray(attempt.toolMetas)?attempt.toolMetas.length:0)+autoContinueNudges+1,outcome.model!==model.id&&(outcome.degraded=!0);let agentMeta={sessionId:sessionIdUsed,provider:lastAssistant?.provider??provider,model:lastAssistant?.model??model.id,usage,lastCallUsage:lastCallUsage??void 0,promptTokens,compactionCount:autoCompactionCount>0?autoCompactionCount:void 0},payloads=buildEmbeddedRunPayloads({assistantTexts:attempt.assistantTexts,toolMetas:attempt.toolMetas,lastAssistant:attempt.lastAssistant,lastToolError:attempt.lastToolError,config:params.config,sessionKey:params.sessionKey??params.sessionId,provider:activeErrorContext.provider,model:activeErrorContext.model,verboseLevel:params.verboseLevel,reasoningLevel:params.reasoningLevel,toolResultFormat:resolvedToolResultFormat,suppressToolErrorWarnings:params.suppressToolErrorWarnings,inlineToolResultsAllowed:!1}),toolMetas=Array.isArray(attempt.toolMetas)?attempt.toolMetas:[],continuationDecision=shouldAutoContinueRun({userPrompt:params.prompt,assistantTexts:attempt.assistantTexts,payloadTexts:payloads.map(payload=>typeof payload.text==`string`?payload.text:``).filter(text=>text.length>0),toolNames:toolMetas.map(entry=>entry.toolName),hasToolError:!!attempt.lastToolError,aborted,timedOut,promptErrored:!!promptError,hasPendingClientToolCall:!!attempt.clientToolCall});if(log$3.debug(`auto-continue decision: shouldContinue=${continuationDecision.shouldContinue} reason=${continuationDecision.reason??`none`} runId=${params.runId} sessionId=${params.sessionId} toolCalls=${toolMetas.length}`),continuationDecision.shouldContinue&&autoContinueNudges<MAX_AUTO_CONTINUE_NUDGES){autoContinueNudges+=1;let latestPayloadText=payloads.map(payload=>typeof payload.text==`string`?payload.text.trim():``).find(text=>text.length>0),latestAssistantText=[...attempt.assistantTexts].toReversed().map(text=>text.trim()).find(text=>text.length>0);currentPrompt=buildAutoContinuePrompt({originalPrompt:params.prompt,lastAssistantText:latestAssistantText??latestPayloadText,reason:continuationDecision.reason}),log$3.warn(`auto-continue nudge ${autoContinueNudges}/${MAX_AUTO_CONTINUE_NUDGES}: reason=${continuationDecision.reason??`policy`} runId=${params.runId} sessionId=${params.sessionId}`);continue}if(timedOut&&!timedOutDuringCompaction&&payloads.length===0)return{payloads:[{text:"Request timed out before a response was generated. Please try again, or increase `agents.defaults.timeoutSeconds` in your config.",isError:!0}],meta:{durationMs:Date.now()-started,agentMeta,aborted,systemPromptReport:attempt.systemPromptReport},didSendViaMessagingTool:attempt.didSendViaMessagingTool,messagingToolSentTexts:attempt.messagingToolSentTexts,messagingToolSentMediaUrls:attempt.messagingToolSentMediaUrls,messagingToolSentTargets:attempt.messagingToolSentTargets,successfulCronAdds:attempt.successfulCronAdds};log$3.debug(`embedded run done: runId=${params.runId} sessionId=${params.sessionId} durationMs=${Date.now()-started} aborted=${aborted}`),lastProfileId&&(await markAuthProfileGood({store:authStore,provider,profileId:lastProfileId,agentDir:params.agentDir}),await markAuthProfileUsed({store:authStore,profileId:lastProfileId,agentDir:params.agentDir}));let finalPayloads=payloads.length?payloads:void 0;return(!finalPayloads||finalPayloads.length===0)&&(finalPayloads=[{text:autoContinueNudges>=MAX_AUTO_CONTINUE_NUDGES?`The agent reached the maximum auto-continue limit (${MAX_AUTO_CONTINUE_NUDGES}) without producing a final response. Consider breaking the task into smaller steps or increasing \`agents.defaults.maxAutoContinueNudges\` in your config.`:`The agent completed without producing any output. This may indicate an issue with the model response or tool execution.`,isError:!0}]),{payloads:finalPayloads,meta:{durationMs:Date.now()-started,agentMeta,aborted,systemPromptReport:attempt.systemPromptReport,stopReason:attempt.clientToolCall?`tool_calls`:void 0,pendingToolCalls:attempt.clientToolCall?[{id:`call_${Date.now()}`,name:attempt.clientToolCall.name,arguments:JSON.stringify(attempt.clientToolCall.params)}]:void 0},didSendViaMessagingTool:attempt.didSendViaMessagingTool,messagingToolSentTexts:attempt.messagingToolSentTexts,messagingToolSentMediaUrls:attempt.messagingToolSentMediaUrls,messagingToolSentTargets:attempt.messagingToolSentTargets,successfulCronAdds:attempt.successfulCronAdds}}}finally{process.chdir(prevCwd)}})).then(result=>(reportOutcome(result.meta?.aborted?`cancelled`:`completed`),result),error=>{throw reportOutcome(`failed`,error),error})}const DEFAULT_QUEUE_DEBOUNCE_MS=1e3,DEFAULT_QUEUE_DROP=`summarize`,FOLLOWUP_QUEUES=new Map;function getFollowupQueue(key,settings){let existing=FOLLOWUP_QUEUES.get(key);if(existing)return applyQueueRuntimeSettings({target:existing,settings}),existing;let created={items:[],draining:!1,lastEnqueuedAt:0,mode:settings.mode,debounceMs:typeof settings.debounceMs==`number`?Math.max(0,settings.debounceMs):DEFAULT_QUEUE_DEBOUNCE_MS,cap:typeof settings.cap==`number`&&settings.cap>0?Math.floor(settings.cap):20,dropPolicy:settings.dropPolicy??DEFAULT_QUEUE_DROP,droppedCount:0,summaryLines:[]};return applyQueueRuntimeSettings({target:created,settings}),FOLLOWUP_QUEUES.set(key,created),created}function clearFollowupQueue(key){let cleaned=key.trim();if(!cleaned)return 0;let queue=FOLLOWUP_QUEUES.get(cleaned);if(!queue)return 0;let cleared=queue.items.length+queue.droppedCount;return queue.items.length=0,queue.droppedCount=0,queue.summaryLines=[],queue.lastRun=void 0,queue.lastEnqueuedAt=0,FOLLOWUP_QUEUES.delete(cleaned),cleared}function clearSessionQueues(keys){let seen=new Set,followupCleared=0,laneCleared=0,clearedKeys=[];for(let key of keys){let cleaned=key?.trim();!cleaned||seen.has(cleaned)||(seen.add(cleaned),clearedKeys.push(cleaned),followupCleared+=clearFollowupQueue(cleaned),laneCleared+=clearCommandLane(resolveEmbeddedSessionLane(cleaned)))}return{followupCleared,laneCleared,keys:clearedKeys}}function scheduleFollowupDrain(key,runFollowup){let queue=FOLLOWUP_QUEUES.get(key);!queue||queue.draining||(queue.draining=!0,(async()=>{try{let forceIndividualCollect=!1;for(;queue.items.length>0||queue.droppedCount>0;){if(await waitForQueueDebounce(queue),queue.mode===`collect`){if(forceIndividualCollect){let next=queue.items[0];if(!next)break;await runFollowup(next),queue.items.shift();continue}if(hasCrossChannelItems(queue.items,item=>{let channel=item.originatingChannel,to=item.originatingTo,accountId=item.originatingAccountId,threadId=item.originatingThreadId;if(!channel&&!to&&!accountId&&threadId==null)return{};if(!isRoutableChannel(channel)||!to)return{cross:!0};let threadKey=threadId==null?``:String(threadId);return{key:[channel,to,accountId||``,threadKey].join(`|`)}})){forceIndividualCollect=!0;let next=queue.items[0];if(!next)break;await runFollowup(next),queue.items.shift();continue}let items=queue.items.slice(),summary=previewQueueSummaryPrompt({state:queue,noun:`message`}),run=items.at(-1)?.run??queue.lastRun;if(!run)break;let originatingChannel=items.find(i=>i.originatingChannel)?.originatingChannel,originatingTo=items.find(i=>i.originatingTo)?.originatingTo,originatingAccountId=items.find(i=>i.originatingAccountId)?.originatingAccountId,originatingThreadId=items.find(i=>i.originatingThreadId!=null)?.originatingThreadId;await runFollowup({prompt:buildCollectPrompt({title:`[Queued messages while agent was busy]`,items,summary,renderItem:(item,idx)=>`---\nQueued #${idx+1}\n${item.prompt}`.trim()}),run,enqueuedAt:Date.now(),originatingChannel,originatingTo,originatingAccountId,originatingThreadId}),queue.items.splice(0,items.length),summary&&clearQueueSummaryState(queue);continue}let summaryPrompt=previewQueueSummaryPrompt({state:queue,noun:`message`});if(summaryPrompt){let run=queue.lastRun;if(!run||!queue.items[0])break;await runFollowup({prompt:summaryPrompt,run,enqueuedAt:Date.now()}),queue.items.shift(),clearQueueSummaryState(queue);continue}let next=queue.items[0];if(!next)break;await runFollowup(next),queue.items.shift()}}catch(err){queue.lastEnqueuedAt=Date.now(),defaultRuntime.error?.(`followup queue drain failed for ${key}: ${String(err)}`)}finally{queue.draining=!1,queue.items.length===0&&queue.droppedCount===0?FOLLOWUP_QUEUES.delete(key):scheduleFollowupDrain(key,runFollowup)}})())}function isRunAlreadyQueued(run,items,allowPromptFallback=!1){let hasSameRouting=item=>item.originatingChannel===run.originatingChannel&&item.originatingTo===run.originatingTo&&item.originatingAccountId===run.originatingAccountId&&item.originatingThreadId===run.originatingThreadId,messageId=run.messageId?.trim();return messageId?items.some(item=>item.messageId?.trim()===messageId&&hasSameRouting(item)):allowPromptFallback?items.some(item=>item.prompt===run.prompt&&hasSameRouting(item)):!1}function enqueueFollowupRun(key,run,settings,dedupeMode=`message-id`){let queue=getFollowupQueue(key,settings),dedupe=dedupeMode===`none`?void 0:(item,items)=>isRunAlreadyQueued(item,items,dedupeMode===`prompt`);return shouldSkipQueueItem({item:run,items:queue.items,dedupe})||(queue.lastEnqueuedAt=Date.now(),queue.lastRun=run.run,!applyQueueDropPolicy({queue,summarize:item=>item.summaryLine?.trim()||item.prompt.trim()}))?!1:(queue.items.push(run),!0)}function getFollowupQueueDepth(key){let cleaned=key.trim();if(!cleaned)return 0;let queue=FOLLOWUP_QUEUES.get(cleaned);return queue?queue.items.length:0}function defaultQueueModeForChannel(_channel){return`collect`}function resolveChannelDebounce(byChannel,channelKey){if(!channelKey||!byChannel)return;let value=byChannel[channelKey];return typeof value==`number`&&Number.isFinite(value)?Math.max(0,value):void 0}function resolvePluginDebounce(channelKey){if(!channelKey)return;let value=getChannelPlugin(channelKey)?.defaults?.queue?.debounceMs;return typeof value==`number`&&Number.isFinite(value)?Math.max(0,value):void 0}function resolveQueueSettings(params){let channelKey=params.channel?.trim().toLowerCase(),queueCfg=params.cfg.messages?.queue,providerModeRaw=channelKey&&queueCfg?.byChannel?queueCfg.byChannel[channelKey]:void 0,resolvedMode=params.inlineMode??normalizeQueueMode(params.sessionEntry?.queueMode)??normalizeQueueMode(providerModeRaw)??normalizeQueueMode(queueCfg?.mode)??defaultQueueModeForChannel(channelKey),debounceRaw=params.inlineOptions?.debounceMs??params.sessionEntry?.queueDebounceMs??resolveChannelDebounce(queueCfg?.debounceMsByChannel,channelKey)??resolvePluginDebounce(channelKey)??queueCfg?.debounceMs??DEFAULT_QUEUE_DEBOUNCE_MS,capRaw=params.inlineOptions?.cap??params.sessionEntry?.queueCap??queueCfg?.cap??20,dropRaw=params.inlineOptions?.dropPolicy??params.sessionEntry?.queueDrop??normalizeQueueDropPolicy(queueCfg?.drop)??DEFAULT_QUEUE_DROP;return{mode:resolvedMode,debounceMs:typeof debounceRaw==`number`?Math.max(0,debounceRaw):void 0,cap:typeof capRaw==`number`?Math.max(1,Math.floor(capRaw)):void 0,dropPolicy:dropRaw}}function buildAnnounceIdFromChildRun(params){return`v1:${params.childSessionKey}:${params.childRunId}`}function buildAnnounceIdempotencyKey(announceId){return`announce:${announceId}`}function resolveQueueAnnounceId(params){return params.announceId?.trim()||`legacy:${params.sessionKey}:${params.enqueuedAt}`}function buildCompletionDeliveryMessage(params){let findingsText=params.findings.trim(),hasFindings=findingsText.length>0&&findingsText!==`(no output)`,header=`✅ Subagent ${params.subagentName} finished`;return hasFindings?`${header}\n\n${findingsText}`:header}function summarizeDeliveryError(error){if(error instanceof Error)return error.message||`error`;if(typeof error==`string`)return error;if(error==null)return`unknown error`;try{return JSON.stringify(error)}catch{return`error`}}function extractToolResultText(content){if(typeof content==`string`)return sanitizeTextContent(content);if(content&&typeof content==`object`&&!Array.isArray(content)){let obj=content;if(typeof obj.text==`string`)return sanitizeTextContent(obj.text);if(typeof obj.output==`string`)return sanitizeTextContent(obj.output);if(typeof obj.content==`string`)return sanitizeTextContent(obj.content);if(typeof obj.result==`string`)return sanitizeTextContent(obj.result);if(typeof obj.error==`string`)return sanitizeTextContent(obj.error);if(typeof obj.summary==`string`)return sanitizeTextContent(obj.summary)}return Array.isArray(content)?extractTextFromChatContent(content,{sanitizeText:sanitizeTextContent,normalizeText:text=>text,joinWith:`
538
+ `)};hookResult?.prependContext&&(effectivePrompt=`${hookResult.prependContext}\n\n${params.prompt}`,log$3.debug(`hooks: prepended context to prompt (${hookResult.prependContext.length} chars)`)),log$3.debug(`embedded run prompt start: runId=${params.runId} sessionId=${params.sessionId}`),cacheTrace?.recordStage(`prompt:before`,{prompt:effectivePrompt,messages:activeSession.messages});let leafEntry=sessionManager.getLeafEntry();if(leafEntry?.type===`message`&&leafEntry.message.role===`user`){leafEntry.parentId?sessionManager.branch(leafEntry.parentId):sessionManager.resetLeaf();let sessionContext=sessionManager.buildSessionContext(),sanitizedOrphan=transcriptPolicy.normalizeAntigravityThinkingBlocks?sanitizeAntigravityThinkingBlocks(sessionContext.messages):sessionContext.messages;activeSession.agent.replaceMessages(sanitizedOrphan),log$3.warn(`Removed orphaned user message to prevent consecutive user turns. runId=${params.runId} sessionId=${params.sessionId}`)}try{let imageResult=await detectAndLoadPromptImages({prompt:effectivePrompt,workspaceDir:effectiveWorkspace,model:params.model,existingImages:params.images,historyMessages:activeSession.messages,maxBytes:MAX_IMAGE_BYTES,maxDimensionPx:resolveImageSanitizationLimits(params.config).maxDimensionPx,sandbox:sandbox?.enabled&&sandbox?.fsBridge?{root:sandbox.workspaceDir,bridge:sandbox.fsBridge}:void 0});if(injectHistoryImagesIntoMessages(activeSession.messages,imageResult.historyImagesByIndex)&&activeSession.agent.replaceMessages(activeSession.messages),cacheTrace?.recordStage(`prompt:images`,{prompt:effectivePrompt,messages:activeSession.messages,note:`images: prompt=${imageResult.images.length} history=${imageResult.historyImagesByIndex.size}`}),log$3.isEnabled(`debug`)){let msgCount=activeSession.messages.length,systemLen=systemPromptText?.length??0,promptLen=effectivePrompt.length,sessionSummary=summarizeSessionContext(activeSession.messages);log$3.debug(`[context-diag] pre-prompt: sessionKey=${params.sessionKey??params.sessionId} messages=${msgCount} roleCounts=${sessionSummary.roleCounts} historyTextChars=${sessionSummary.totalTextChars} maxMessageTextChars=${sessionSummary.maxMessageTextChars} historyImageBlocks=${sessionSummary.totalImageBlocks} systemPromptChars=${systemLen} promptChars=${promptLen} promptImages=${imageResult.images.length} historyImageMessages=${imageResult.historyImagesByIndex.size} provider=${params.provider}/${params.modelId} sessionFile=${params.sessionFile}`)}hookRunner?.hasHooks(`llm_input`)&&hookRunner.runLlmInput({runId:params.runId,sessionId:params.sessionId,provider:params.provider,model:params.modelId,systemPrompt:systemPromptText,prompt:effectivePrompt,historyMessages:activeSession.messages,imagesCount:imageResult.images.length},{agentId:hookAgentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageProvider??void 0}).catch(err=>{log$3.warn(`llm_input hook failed: ${String(err)}`)}),imageResult.images.length>0?await abortable(activeSession.prompt(effectivePrompt,{images:imageResult.images})):await abortable(activeSession.prompt(effectivePrompt))}catch(err){promptError=err,promptErrorSource=`prompt`}finally{log$3.debug(`embedded run prompt end: runId=${params.runId} sessionId=${params.sessionId} durationMs=${Date.now()-promptStartedAt}`)}let wasCompactingBefore=activeSession.isCompacting,snapshot=activeSession.messages.slice(),wasCompactingAfter=activeSession.isCompacting,preCompactionSnapshot=wasCompactingBefore||wasCompactingAfter?null:snapshot,preCompactionSessionId=activeSession.sessionId;try{await abortable(waitForCompactionRetry())}catch(err){if(isRunnerAbortError(err))promptError||(promptError=err,promptErrorSource=`compaction`),isProbeSession||log$3.debug(`compaction wait aborted: runId=${params.runId} sessionId=${params.sessionId}`);else throw err}timedOutDuringCompaction||params.config?.agents?.defaults?.contextPruning?.mode===`cache-ttl`&&isCacheTtlEligibleProvider(params.provider,params.modelId)&&appendCacheTtlTimestamp(sessionManager,{timestamp:Date.now(),provider:params.provider,modelId:params.modelId});let snapshotSelection=selectCompactionTimeoutSnapshot({timedOutDuringCompaction,preCompactionSnapshot,preCompactionSessionId,currentSnapshot:activeSession.messages.slice(),currentSessionId:activeSession.sessionId});if(timedOutDuringCompaction&&(isProbeSession||log$3.warn(`using ${snapshotSelection.source} snapshot: timed out during compaction runId=${params.runId} sessionId=${params.sessionId}`)),messagesSnapshot=snapshotSelection.messagesSnapshot,sessionIdUsed=snapshotSelection.sessionIdUsed,promptError&&promptErrorSource===`prompt`)try{sessionManager.appendCustomEntry(`builderforce:prompt-error`,{timestamp:Date.now(),runId:params.runId,sessionId:params.sessionId,provider:params.provider,model:params.modelId,api:params.model.api,error:describeUnknownError(promptError)})}catch(entryErr){log$3.warn(`failed to persist prompt error entry: ${String(entryErr)}`)}cacheTrace?.recordStage(`session:after`,{messages:messagesSnapshot,note:timedOutDuringCompaction?`compaction timeout`:promptError?`prompt error`:void 0}),anthropicPayloadLogger?.recordUsage(messagesSnapshot,promptError),hookRunner?.hasHooks(`agent_end`)&&hookRunner.runAgentEnd({messages:messagesSnapshot,success:!aborted&&!promptError,error:promptError?describeUnknownError(promptError):void 0,durationMs:Date.now()-promptStartedAt},{agentId:hookAgentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageProvider??void 0}).catch(err=>{log$3.warn(`agent_end hook failed: ${err}`)})}finally{clearTimeout(abortTimer),abortWarnTimer&&clearTimeout(abortWarnTimer),!isProbeSession&&(aborted||timedOut)&&!timedOutDuringCompaction&&log$3.debug(`run cleanup: runId=${params.runId} sessionId=${params.sessionId} aborted=${aborted} timedOut=${timedOut}`);try{unsubscribe()}catch(err){log$3.error(`CRITICAL: unsubscribe failed, possible resource leak: runId=${params.runId} ${String(err)}`)}clearActiveEmbeddedRun(params.sessionId,queueHandle,params.sessionKey),params.abortSignal?.removeEventListener?.(`abort`,onAbort)}let lastAssistant=messagesSnapshot.slice().toReversed().find(m=>m.role===`assistant`),toolMetasNormalized=toolMetas.filter(entry=>typeof entry.toolName==`string`&&entry.toolName.trim().length>0).map(entry=>({toolName:entry.toolName,meta:entry.meta}));return hookRunner?.hasHooks(`llm_output`)&&hookRunner.runLlmOutput({runId:params.runId,sessionId:params.sessionId,provider:params.provider,model:params.modelId,assistantTexts,lastAssistant,usage:getUsageTotals()},{agentId:hookAgentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:params.workspaceDir,messageProvider:params.messageProvider??void 0}).catch(err=>{log$3.warn(`llm_output hook failed: ${String(err)}`)}),{aborted,timedOut,timedOutDuringCompaction,promptError,sessionIdUsed,systemPromptReport,messagesSnapshot,assistantTexts,toolMetas:toolMetasNormalized,lastAssistant,lastToolError:getLastToolError?.(),didSendViaMessagingTool:didSendViaMessagingTool(),messagingToolSentTexts:getMessagingToolSentTexts(),messagingToolSentMediaUrls:getMessagingToolSentMediaUrls(),messagingToolSentTargets:getMessagingToolSentTargets(),successfulCronAdds:getSuccessfulCronAdds(),cloudCodeAssistFormatError:!!(lastAssistant?.errorMessage&&isCloudCodeAssistFormatError(lastAssistant.errorMessage)),attemptUsage:getUsageTotals(),compactionCount:getCompactionCount(),clientToolCall:clientToolCallDetected??void 0}}finally{removeToolResultContextGuard?.(),await flushPendingToolResultsAfterIdle({agent:session?.agent,sessionManager}),session?.dispose(),await sessionLock.release()}}finally{restoreSkillEnv?.(),process.chdir(prevCwd)}}const RECOVERABLE_TOOL_ERROR_KEYWORDS=[`required`,`missing`,`invalid`,`must be`,`must have`,`needs`,`requires`];function isRecoverableToolError(error){let errorLower=(error??``).toLowerCase();return RECOVERABLE_TOOL_ERROR_KEYWORDS.some(keyword=>errorLower.includes(keyword))}function shouldShowToolErrorWarning(params){if(params.suppressToolErrorWarnings)return!1;let normalizedToolName=params.lastToolError.toolName.trim().toLowerCase(),verboseEnabled=params.verboseLevel===`on`||params.verboseLevel===`full`;return(normalizedToolName===`exec`||normalizedToolName===`bash`)&&!verboseEnabled?!1:params.lastToolError.mutatingAction??isLikelyMutatingToolName(params.lastToolError.toolName)?!0:params.suppressToolErrors?!1:!params.hasUserFacingReply&&!isRecoverableToolError(params.lastToolError.error)}function buildEmbeddedRunPayloads(params){let replyItems=[],useMarkdown=params.toolResultFormat===`markdown`,lastAssistantErrored=params.lastAssistant?.stopReason===`error`,errorText=params.lastAssistant?formatAssistantErrorText(params.lastAssistant,{cfg:params.config,sessionKey:params.sessionKey,provider:params.provider,model:params.model}):void 0,rawErrorMessage=lastAssistantErrored&&params.lastAssistant?.errorMessage?.trim()||void 0,rawErrorFingerprint=rawErrorMessage?getApiErrorPayloadFingerprint(rawErrorMessage):null,formattedRawErrorMessage=rawErrorMessage?formatRawAssistantErrorForUi(rawErrorMessage):null,normalizedFormattedRawErrorMessage=formattedRawErrorMessage?normalizeTextForComparison(formattedRawErrorMessage):null,normalizedRawErrorText=rawErrorMessage?normalizeTextForComparison(rawErrorMessage):null,normalizedErrorText=errorText?normalizeTextForComparison(errorText):null,normalizedGenericBillingErrorText=normalizeTextForComparison(BILLING_ERROR_USER_MESSAGE);if(errorText&&replyItems.push({text:errorText,isError:!0}),params.inlineToolResultsAllowed&&params.verboseLevel!==`off`&&params.toolMetas.length>0)for(let{toolName,meta}of params.toolMetas){let{text:cleanedText,mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent}=parseReplyDirectives(formatToolAggregate(toolName,meta?[meta]:[],{markdown:useMarkdown}));cleanedText&&replyItems.push({text:cleanedText,media:mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent})}let reasoningText=params.lastAssistant&&params.reasoningLevel===`on`?formatReasoningMessage(extractAssistantThinking(params.lastAssistant)):``;reasoningText&&replyItems.push({text:reasoningText});let fallbackAnswerText=params.lastAssistant?extractAssistantText$1(params.lastAssistant):``,shouldSuppressRawErrorText=text=>{if(!lastAssistantErrored)return!1;let trimmed=text.trim();if(!trimmed)return!1;if(errorText){let normalized=normalizeTextForComparison(trimmed);if(normalized&&normalizedErrorText&&normalized===normalizedErrorText||trimmed===`The AI service returned an error. Please try again.`||normalized&&normalizedGenericBillingErrorText&&normalized===normalizedGenericBillingErrorText)return!0}if(rawErrorMessage&&trimmed===rawErrorMessage||formattedRawErrorMessage&&trimmed===formattedRawErrorMessage)return!0;if(normalizedRawErrorText){let normalized=normalizeTextForComparison(trimmed);if(normalized&&normalized===normalizedRawErrorText)return!0}if(normalizedFormattedRawErrorMessage){let normalized=normalizeTextForComparison(trimmed);if(normalized&&normalized===normalizedFormattedRawErrorMessage)return!0}if(rawErrorFingerprint){let fingerprint=getApiErrorPayloadFingerprint(trimmed);if(fingerprint&&fingerprint===rawErrorFingerprint)return!0}return isRawApiErrorPayload(trimmed)},answerTexts=(params.assistantTexts.length?params.assistantTexts:fallbackAnswerText?[fallbackAnswerText]:[]).filter(text=>!shouldSuppressRawErrorText(text)),hasUserFacingAssistantReply=!1;for(let text of answerTexts){let{text:cleanedText,mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent}=parseReplyDirectives(text);!cleanedText&&(!mediaUrls||mediaUrls.length===0)&&!audioAsVoice||(replyItems.push({text:cleanedText,media:mediaUrls,audioAsVoice,replyToId,replyToTag,replyToCurrent}),hasUserFacingAssistantReply=!0)}if(params.lastToolError&&shouldShowToolErrorWarning({lastToolError:params.lastToolError,hasUserFacingReply:hasUserFacingAssistantReply,suppressToolErrors:!!params.config?.messages?.suppressToolErrors,suppressToolErrorWarnings:params.suppressToolErrorWarnings,verboseLevel:params.verboseLevel})){let warningText=`⚠️ ${formatToolAggregate(params.lastToolError.toolName,params.lastToolError.meta?[params.lastToolError.meta]:void 0,{markdown:useMarkdown})} failed${params.lastToolError.error?`: ${params.lastToolError.error}`:``}`,normalizedWarning=normalizeTextForComparison(warningText);normalizedWarning&&replyItems.some(item=>{if(!item.text)return!1;let normalizedExisting=normalizeTextForComparison(item.text);return normalizedExisting.length>0&&normalizedExisting===normalizedWarning})||replyItems.push({text:warningText,isError:!0})}let hasAudioAsVoiceTag=replyItems.some(item=>item.audioAsVoice);return replyItems.map(item=>({text:item.text?.trim()?item.text.trim():void 0,mediaUrls:item.media?.length?item.media:void 0,mediaUrl:item.media?.[0],isError:item.isError,replyToId:item.replyToId,replyToTag:item.replyToTag,replyToCurrent:item.replyToCurrent,audioAsVoice:item.audioAsVoice||!!(hasAudioAsVoiceTag&&item.media?.length)})).filter(p=>!(!p.text&&!p.mediaUrl&&(!p.mediaUrls||p.mediaUrls.length===0)||p.text&&isSilentReplyText(p.text,SILENT_REPLY_TOKEN)))}const ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL=`ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL`;function scrubAnthropicRefusalMagic(prompt){return prompt.includes(ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL)?prompt.replaceAll(ANTHROPIC_MAGIC_STRING_TRIGGER_REFUSAL,`ANTHROPIC MAGIC STRING TRIGGER REFUSAL (redacted)`):prompt}const createUsageAccumulator=()=>({input:0,output:0,cacheRead:0,cacheWrite:0,total:0,lastCacheRead:0,lastCacheWrite:0,lastInput:0});function createCompactionDiagId(){return`ovf-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}const hasUsageValues=usage=>!!usage&&[usage.input,usage.output,usage.cacheRead,usage.cacheWrite,usage.total].some(value=>typeof value==`number`&&Number.isFinite(value)&&value>0),mergeUsageIntoAccumulator=(target,usage)=>{hasUsageValues(usage)&&(target.input+=usage.input??0,target.output+=usage.output??0,target.cacheRead+=usage.cacheRead??0,target.cacheWrite+=usage.cacheWrite??0,target.total+=usage.total??(usage.input??0)+(usage.output??0)+(usage.cacheRead??0)+(usage.cacheWrite??0),target.lastCacheRead=usage.cacheRead??0,target.lastCacheWrite=usage.cacheWrite??0,target.lastInput=usage.input??0)},toNormalizedUsage=usage=>{if(!(usage.input>0||usage.output>0||usage.cacheRead>0||usage.cacheWrite>0||usage.total>0))return;let lastPromptTokens=usage.lastInput+usage.lastCacheRead+usage.lastCacheWrite;return{input:usage.lastInput||void 0,output:usage.output||void 0,cacheRead:usage.lastCacheRead||void 0,cacheWrite:usage.lastCacheWrite||void 0,total:lastPromptTokens+usage.output||void 0}};function resolveActiveErrorContext(params){return{provider:params.lastAssistant?.provider??params.provider,model:params.lastAssistant?.model??params.model}}async function runEmbeddedAgent(params){let sessionLane=resolveSessionLane(params.sessionKey?.trim()||params.sessionId),globalLane=resolveGlobalLane(params.lane),enqueueGlobal=params.enqueue??((task,opts)=>enqueueCommandInLane(globalLane,task,opts)),enqueueSession=params.enqueue??((task,opts)=>enqueueCommandInLane(sessionLane,task,opts)),channelHint=params.messageChannel??params.messageProvider,resolvedToolResultFormat=params.toolResultFormat??(channelHint?isMarkdownCapableMessageChannel(channelHint)?`markdown`:`plain`:`markdown`),isProbeSession=params.sessionId?.startsWith(`probe-`)??!1,outcome={actionType:DEFAULT_ACTION_TYPE,provider:``,model:``,steps:0,degraded:!1},reportOutcome=(terminalStatus,error)=>{if(!outcome.model||isProbeSession)return;let rateLimited=isFailoverError(error)&&error.reason===`rate_limit`;completeLearnedRun({runId:params.runId,model:`${outcome.provider}/${outcome.model}`,actionType:outcome.actionType,terminalStatus,rateLimited,degraded:outcome.degraded,steps:outcome.steps})};return enqueueSession(()=>enqueueGlobal(async()=>{let started=Date.now(),workspaceResolution=resolveRunWorkspaceDir({workspaceDir:params.workspaceDir,sessionKey:params.sessionKey,agentId:params.agentId,config:params.config}),resolvedWorkspace=workspaceResolution.workspaceDir,redactedSessionId=redactRunIdentifier(params.sessionId),redactedSessionKey=redactRunIdentifier(params.sessionKey),redactedWorkspace=redactRunIdentifier(resolvedWorkspace);workspaceResolution.usedFallback&&log$3.warn(`[workspace-fallback] caller=runEmbeddedAgent reason=${workspaceResolution.fallbackReason} run=${params.runId} session=${redactedSessionId} sessionKey=${redactedSessionKey} agent=${workspaceResolution.agentId} workspace=${redactedWorkspace}`);let prevCwd=process.cwd(),provider=(params.provider??DEFAULT_PROVIDER).trim()||DEFAULT_PROVIDER,modelId=(params.model??DEFAULT_MODEL).trim()||DEFAULT_MODEL,agentDir=params.agentDir??resolveBuilderForceAgentsAgentDir(),fallbackConfigured=(params.config?.agents?.defaults?.model?.fallbacks?.length??0)>0;await ensureBuilderForceAgentsModelsJson(params.config,agentDir);let modelResolveOverride,hookRunner=getGlobalHookRunner(),hookCtx={agentId:workspaceResolution.agentId,sessionKey:params.sessionKey,sessionId:params.sessionId,workspaceDir:resolvedWorkspace,messageProvider:params.messageProvider??void 0};if(hookRunner?.hasHooks(`before_model_resolve`))try{modelResolveOverride=await hookRunner.runBeforeModelResolve({prompt:params.prompt},hookCtx)}catch(hookErr){log$3.warn(`before_model_resolve hook failed: ${String(hookErr)}`)}if(hookRunner?.hasHooks(`before_agent_start`))try{let legacyResult=await hookRunner.runBeforeAgentStart({prompt:params.prompt},hookCtx);modelResolveOverride={providerOverride:modelResolveOverride?.providerOverride??legacyResult?.providerOverride,modelOverride:modelResolveOverride?.modelOverride??legacyResult?.modelOverride}}catch(hookErr){log$3.warn(`before_agent_start hook (legacy model resolve path) failed: ${String(hookErr)}`)}modelResolveOverride?.providerOverride&&(provider=modelResolveOverride.providerOverride,log$3.info(`[hooks] provider overridden to ${provider}`)),modelResolveOverride?.modelOverride&&(modelId=modelResolveOverride.modelOverride,log$3.info(`[hooks] model overridden to ${modelId}`));let learnedSeed=await resolveLearnedModelSeed({provider,modelId,prompt:params.prompt,cfg:params.config});outcome.actionType=learnedSeed.actionType,learnedSeed.reordered&&(learnedSeed.provider!==provider||learnedSeed.modelId!==modelId)&&(log$3.info(`[learned-routing] seeding ${learnedSeed.provider}/${learnedSeed.modelId} over ${provider}/${modelId} (action=${learnedSeed.actionType} scope=${learnedSeed.scope??`none`})`),provider=learnedSeed.provider,modelId=learnedSeed.modelId);let{model,error,authStorage,modelRegistry}=resolveModel(provider,modelId,agentDir,params.config);if(!model)throw Error(error??`Unknown model: ${provider}/${modelId}`);outcome.provider=provider,outcome.model=model.id;let ctxInfo=resolveContextWindowInfo({cfg:params.config,provider,modelId,modelContextWindow:model.contextWindow,defaultTokens:DEFAULT_CONTEXT_TOKENS}),ctxGuard=evaluateContextWindowGuard({info:ctxInfo,warnBelowTokens:CONTEXT_WINDOW_WARN_BELOW_TOKENS,hardMinTokens:CONTEXT_WINDOW_HARD_MIN_TOKENS});if(ctxGuard.shouldWarn&&log$3.warn(`low context window: ${provider}/${modelId} ctx=${ctxGuard.tokens} (warn<${CONTEXT_WINDOW_WARN_BELOW_TOKENS}) source=${ctxGuard.source}`),ctxGuard.shouldBlock)throw log$3.error(`blocked model (context window too small): ${provider}/${modelId} ctx=${ctxGuard.tokens} (min=${CONTEXT_WINDOW_HARD_MIN_TOKENS}) source=${ctxGuard.source}`),new FailoverError(`Model context window too small (${ctxGuard.tokens} tokens). Minimum is ${CONTEXT_WINDOW_HARD_MIN_TOKENS}.`,{reason:`unknown`,provider,model:modelId});let authStore=await ensureAuthProfileStore(agentDir,{allowKeychainPrompt:!1}),preferredProfileId=params.authProfileId?.trim(),lockedProfileId=params.authProfileIdSource===`user`?preferredProfileId:void 0;if(lockedProfileId){let lockedProfile=authStore.profiles[lockedProfileId];(!lockedProfile||normalizeProviderId(lockedProfile.provider)!==normalizeProviderId(provider))&&(lockedProfileId=void 0)}let profileOrder=resolveAuthProfileOrder({cfg:params.config,store:authStore,provider,preferredProfile:preferredProfileId});if(lockedProfileId&&!profileOrder.includes(lockedProfileId))throw Error(`Auth profile "${lockedProfileId}" is not configured for ${provider}.`);let profileCandidates=lockedProfileId?[lockedProfileId]:profileOrder.length>0?profileOrder:[void 0],profileIndex=0,initialThinkLevel=params.thinkLevel??`off`,thinkLevel=initialThinkLevel,attemptedThinking=new Set,apiKeyInfo=null,lastProfileId,resolveAuthProfileFailoverReason=params=>params.allInCooldown?`rate_limit`:classifyFailoverReason(params.message)??`auth`,throwAuthProfileFailover=params=>{let fallbackMessage=`No available auth profile for ${provider} (all in cooldown or unavailable).`,message=params.message?.trim()||(params.error?describeUnknownError(params.error).trim():``)||fallbackMessage,reason=resolveAuthProfileFailoverReason({allInCooldown:params.allInCooldown,message});throw fallbackConfigured?new FailoverError(message,{reason,provider,model:modelId,status:resolveFailoverStatus(reason),cause:params.error}):params.error instanceof Error?params.error:Error(message)},resolveApiKeyForCandidate=async candidate=>getApiKeyForModel({model,cfg:params.config,profileId:candidate,store:authStore,agentDir}),applyApiKeyInfo=async candidate=>{apiKeyInfo=await resolveApiKeyForCandidate(candidate);let resolvedProfileId=apiKeyInfo.profileId??candidate;if(!apiKeyInfo.apiKey){if(apiKeyInfo.mode!==`aws-sdk`)throw Error(`No API key resolved for provider "${model.provider}" (auth mode: ${apiKeyInfo.mode}).`);lastProfileId=resolvedProfileId;return}if(model.provider===`github-copilot`){let{resolveCopilotApiToken}=await import(`./github-copilot-token-D5sB2AUI.js`),copilotToken=await resolveCopilotApiToken({githubToken:apiKeyInfo.apiKey});authStorage.setRuntimeApiKey(model.provider,copilotToken.token)}else authStorage.setRuntimeApiKey(model.provider,apiKeyInfo.apiKey);lastProfileId=apiKeyInfo.profileId},advanceAuthProfile=async()=>{if(lockedProfileId)return!1;let nextIndex=profileIndex+1;for(;nextIndex<profileCandidates.length;){let candidate=profileCandidates[nextIndex];if(candidate&&isProfileInCooldown(authStore,candidate)){nextIndex+=1;continue}try{return await applyApiKeyInfo(candidate),profileIndex=nextIndex,thinkLevel=initialThinkLevel,attemptedThinking.clear(),!0}catch(err){if(candidate&&candidate===lockedProfileId)throw err;nextIndex+=1}}return!1};try{for(;profileIndex<profileCandidates.length;){let candidate=profileCandidates[profileIndex];if(candidate&&candidate!==lockedProfileId&&isProfileInCooldown(authStore,candidate)){profileIndex+=1;continue}await applyApiKeyInfo(profileCandidates[profileIndex]);break}profileIndex>=profileCandidates.length&&throwAuthProfileFailover({allInCooldown:!0})}catch(err){if(err instanceof FailoverError)throw err;profileCandidates[profileIndex]===lockedProfileId&&throwAuthProfileFailover({allInCooldown:!1,error:err}),await advanceAuthProfile()||throwAuthProfileFailover({allInCooldown:!1,error:err})}let MAX_AUTO_CONTINUE_NUDGES=params.config?.agents?.defaults?.maxAutoContinueNudges??3,overflowCompactionAttempts=0,toolResultTruncationAttempted=!1,autoContinueNudges=0,currentPrompt=params.prompt,usageAccumulator=createUsageAccumulator(),lastRunPromptUsage,autoCompactionCount=0;try{for(;;){attemptedThinking.add(thinkLevel),await fs$1.mkdir(resolvedWorkspace,{recursive:!0});let prompt=provider===`anthropic`?scrubAnthropicRefusalMagic(currentPrompt):currentPrompt,attempt=await runEmbeddedAttempt({sessionId:params.sessionId,sessionKey:params.sessionKey,messageChannel:params.messageChannel,messageProvider:params.messageProvider,agentAccountId:params.agentAccountId,messageTo:params.messageTo,messageThreadId:params.messageThreadId,groupId:params.groupId,groupChannel:params.groupChannel,groupSpace:params.groupSpace,spawnedBy:params.spawnedBy,senderIsOwner:params.senderIsOwner,currentChannelId:params.currentChannelId,currentThreadTs:params.currentThreadTs,replyToMode:params.replyToMode,hasRepliedRef:params.hasRepliedRef,sessionFile:params.sessionFile,workspaceDir:resolvedWorkspace,agentDir,config:params.config,skillsSnapshot:params.skillsSnapshot,prompt,images:params.images,disableTools:params.disableTools,provider,modelId,model,authStorage,modelRegistry,agentId:workspaceResolution.agentId,thinkLevel,verboseLevel:params.verboseLevel,reasoningLevel:params.reasoningLevel,toolResultFormat:resolvedToolResultFormat,execOverrides:params.execOverrides,bashElevated:params.bashElevated,timeoutMs:params.timeoutMs,runId:params.runId,abortSignal:params.abortSignal,shouldEmitToolResult:params.shouldEmitToolResult,shouldEmitToolOutput:params.shouldEmitToolOutput,onPartialReply:params.onPartialReply,onAssistantMessageStart:params.onAssistantMessageStart,onBlockReply:params.onBlockReply,onBlockReplyFlush:params.onBlockReplyFlush,blockReplyBreak:params.blockReplyBreak,blockReplyChunking:params.blockReplyChunking,onReasoningStream:params.onReasoningStream,onReasoningEnd:params.onReasoningEnd,onToolResult:params.onToolResult,onAgentEvent:params.onAgentEvent,extraSystemPrompt:params.extraSystemPrompt,inputProvenance:params.inputProvenance,streamParams:params.streamParams,ownerNumbers:params.ownerNumbers,enforceFinalTag:params.enforceFinalTag}),{aborted,promptError,timedOut,timedOutDuringCompaction,sessionIdUsed,lastAssistant}=attempt,lastAssistantUsage=normalizeUsage(lastAssistant?.usage),attemptUsage=attempt.attemptUsage??lastAssistantUsage;mergeUsageIntoAccumulator(usageAccumulator,attemptUsage),lastRunPromptUsage=lastAssistantUsage??attemptUsage;let lastTurnTotal=lastAssistantUsage?.total??attemptUsage?.total,attemptCompactionCount=Math.max(0,attempt.compactionCount??0);autoCompactionCount+=attemptCompactionCount;let activeErrorContext=resolveActiveErrorContext({lastAssistant,provider,model:modelId}),formattedAssistantErrorText=lastAssistant?formatAssistantErrorText(lastAssistant,{cfg:params.config,sessionKey:params.sessionKey??params.sessionId,provider:activeErrorContext.provider,model:activeErrorContext.model}):void 0,assistantErrorText=lastAssistant?.stopReason===`error`?lastAssistant.errorMessage?.trim()||formattedAssistantErrorText:void 0,contextOverflowError=aborted?null:(()=>{if(promptError){let errorText=describeUnknownError(promptError);return isLikelyContextOverflowError(errorText)?{text:errorText,source:`promptError`}:null}return assistantErrorText&&isLikelyContextOverflowError(assistantErrorText)?{text:assistantErrorText,source:`assistantError`}:null})();if(contextOverflowError){let overflowDiagId=createCompactionDiagId(),errorText=contextOverflowError.text,msgCount=attempt.messagesSnapshot?.length??0;log$3.warn(`[context-overflow-diag] sessionKey=${params.sessionKey??params.sessionId} provider=${provider}/${modelId} source=${contextOverflowError.source} messages=${msgCount} sessionFile=${params.sessionFile} diagId=${overflowDiagId} compactionAttempts=${overflowCompactionAttempts} error=${errorText.slice(0,200)}`);let isCompactionFailure=isCompactionFailureError(errorText),hadAttemptLevelCompaction=attemptCompactionCount>0;if(!isCompactionFailure&&hadAttemptLevelCompaction&&overflowCompactionAttempts<3){overflowCompactionAttempts++,log$3.warn(`context overflow persisted after in-attempt compaction (attempt ${overflowCompactionAttempts}/3); retrying prompt without additional compaction for ${provider}/${modelId}`);continue}if(!isCompactionFailure&&!hadAttemptLevelCompaction&&overflowCompactionAttempts<3){log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=compact isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=unknown attempt=${overflowCompactionAttempts+1} maxAttempts=3`),overflowCompactionAttempts++,log$3.warn(`context overflow detected (attempt ${overflowCompactionAttempts}/3); attempting auto-compaction for ${provider}/${modelId}`);let compactResult=await compactEmbeddedSessionDirect({sessionId:params.sessionId,sessionKey:params.sessionKey,messageChannel:params.messageChannel,messageProvider:params.messageProvider,agentAccountId:params.agentAccountId,authProfileId:lastProfileId,sessionFile:params.sessionFile,workspaceDir:resolvedWorkspace,agentDir,config:params.config,skillsSnapshot:params.skillsSnapshot,senderIsOwner:params.senderIsOwner,provider,model:modelId,runId:params.runId,thinkLevel,reasoningLevel:params.reasoningLevel,bashElevated:params.bashElevated,extraSystemPrompt:params.extraSystemPrompt,ownerNumbers:params.ownerNumbers,trigger:`overflow`,diagId:overflowDiagId,attempt:overflowCompactionAttempts,maxAttempts:3});if(compactResult.compacted){autoCompactionCount+=1,log$3.info(`auto-compaction succeeded for ${provider}/${modelId}; retrying prompt`);continue}log$3.warn(`auto-compaction failed for ${provider}/${modelId}: ${compactResult.reason??`nothing to compact`}`)}if(!toolResultTruncationAttempted){let contextWindowTokens=ctxInfo.tokens,hasOversized=attempt.messagesSnapshot?sessionLikelyHasOversizedToolResults({messages:attempt.messagesSnapshot,contextWindowTokens}):!1;if(hasOversized){log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=truncate_tool_results isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=${hasOversized} attempt=${overflowCompactionAttempts} maxAttempts=3`),toolResultTruncationAttempted=!0,log$3.warn(`[context-overflow-recovery] Attempting tool result truncation for ${provider}/${modelId} (contextWindow=${contextWindowTokens} tokens)`);let truncResult=await truncateOversizedToolResultsInSession({sessionFile:params.sessionFile,contextWindowTokens,sessionId:params.sessionId,sessionKey:params.sessionKey});if(truncResult.truncated){log$3.info(`[context-overflow-recovery] Truncated ${truncResult.truncatedCount} tool result(s); retrying prompt`),overflowCompactionAttempts=0;continue}log$3.warn(`[context-overflow-recovery] Tool result truncation did not help: ${truncResult.reason??`unknown`}`)}else log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=give_up isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=${hasOversized} attempt=${overflowCompactionAttempts} maxAttempts=3`)}(isCompactionFailure||overflowCompactionAttempts>=3||toolResultTruncationAttempted)&&log$3.isEnabled(`debug`)&&log$3.debug(`[compaction-diag] decision diagId=${overflowDiagId} branch=give_up isCompactionFailure=${isCompactionFailure} hasOversizedToolResults=unknown attempt=${overflowCompactionAttempts} maxAttempts=3`);let kind=isCompactionFailure?`compaction_failure`:`context_overflow`;return{payloads:[{text:`Context overflow: prompt too large for the model. Try /reset (or /new) to start a fresh session, or use a larger-context model.`,isError:!0}],meta:{durationMs:Date.now()-started,agentMeta:{sessionId:sessionIdUsed,provider,model:model.id},systemPromptReport:attempt.systemPromptReport,error:{kind,message:errorText}}}}if(promptError&&!aborted){let errorText=describeUnknownError(promptError);if(/incorrect role information|roles must alternate/i.test(errorText))return{payloads:[{text:`Message ordering conflict - please try again. If this persists, use /new to start a fresh session.`,isError:!0}],meta:{durationMs:Date.now()-started,agentMeta:{sessionId:sessionIdUsed,provider,model:model.id},systemPromptReport:attempt.systemPromptReport,error:{kind:`role_ordering`,message:errorText}}};let imageSizeError=parseImageSizeError(errorText);if(imageSizeError){let maxMb=imageSizeError.maxMb,maxMbLabel=typeof maxMb==`number`&&Number.isFinite(maxMb)?`${maxMb}`:null;return{payloads:[{text:`Image too large for the model${maxMbLabel?` (max ${maxMbLabel}MB)`:``}. Please compress or resize the image and try again.`,isError:!0}],meta:{durationMs:Date.now()-started,agentMeta:{sessionId:sessionIdUsed,provider,model:model.id},systemPromptReport:attempt.systemPromptReport,error:{kind:`image_size`,message:errorText}}}}let promptFailoverReason=classifyFailoverReason(errorText);if(promptFailoverReason&&promptFailoverReason!==`timeout`&&lastProfileId&&await markAuthProfileFailure({store:authStore,profileId:lastProfileId,reason:promptFailoverReason,cfg:params.config,agentDir:params.agentDir}),isFailoverErrorMessage(errorText)&&promptFailoverReason!==`timeout`&&await advanceAuthProfile())continue;let fallbackThinking=pickFallbackThinkingLevel({message:errorText,attempted:attemptedThinking});if(fallbackThinking){log$3.warn(`unsupported thinking level for ${provider}/${modelId}; retrying with ${fallbackThinking}`),thinkLevel=fallbackThinking;continue}throw fallbackConfigured&&isFailoverErrorMessage(errorText)?new FailoverError(errorText,{reason:promptFailoverReason??`unknown`,provider,model:modelId,profileId:lastProfileId,status:resolveFailoverStatus(promptFailoverReason??`unknown`)}):promptError}let fallbackThinking=pickFallbackThinkingLevel({message:lastAssistant?.errorMessage,attempted:attemptedThinking});if(fallbackThinking&&!aborted){log$3.warn(`unsupported thinking level for ${provider}/${modelId}; retrying with ${fallbackThinking}`),thinkLevel=fallbackThinking;continue}let authFailure=isAuthAssistantError(lastAssistant),rateLimitFailure=isRateLimitAssistantError(lastAssistant),billingFailure=isBillingAssistantError(lastAssistant),failoverFailure=isFailoverAssistantError(lastAssistant),assistantFailoverReason=classifyFailoverReason(lastAssistant?.errorMessage??``),cloudCodeAssistFormatError=attempt.cloudCodeAssistFormatError,imageDimensionError=parseImageDimensionError(lastAssistant?.errorMessage??``);if(imageDimensionError&&lastProfileId){let details=[imageDimensionError.messageIndex===void 0?null:`message=${imageDimensionError.messageIndex}`,imageDimensionError.contentIndex===void 0?null:`content=${imageDimensionError.contentIndex}`,imageDimensionError.maxDimensionPx===void 0?null:`limit=${imageDimensionError.maxDimensionPx}px`].filter(Boolean).join(` `);log$3.warn(`Profile ${lastProfileId} rejected image payload${details?` (${details})`:``}.`)}if(!aborted&&failoverFailure||timedOut&&!timedOutDuringCompaction){if(lastProfileId&&(await markAuthProfileFailure({store:authStore,profileId:lastProfileId,reason:timedOut||assistantFailoverReason===`timeout`?`timeout`:assistantFailoverReason??`unknown`,cfg:params.config,agentDir:params.agentDir}),timedOut&&!isProbeSession&&log$3.warn(`Profile ${lastProfileId} timed out (possible rate limit). Trying next account...`),cloudCodeAssistFormatError&&log$3.warn(`Profile ${lastProfileId} hit Cloud Code Assist format error. Tool calls will be sanitized on retry.`)),await advanceAuthProfile())continue;if(fallbackConfigured){let message=(lastAssistant?formatAssistantErrorText(lastAssistant,{cfg:params.config,sessionKey:params.sessionKey??params.sessionId,provider:activeErrorContext.provider,model:activeErrorContext.model}):void 0)||lastAssistant?.errorMessage?.trim()||(timedOut?`LLM request timed out.`:rateLimitFailure?`LLM request rate limited.`:billingFailure?formatBillingErrorMessage(activeErrorContext.provider,activeErrorContext.model):authFailure?`LLM request unauthorized.`:`LLM request failed.`),status=resolveFailoverStatus(assistantFailoverReason??`unknown`)??(isTimeoutErrorMessage(message)?408:void 0);throw new FailoverError(message,{reason:assistantFailoverReason??`unknown`,provider:activeErrorContext.provider,model:activeErrorContext.model,profileId:lastProfileId,status})}}let usage=toNormalizedUsage(usageAccumulator);usage&&lastTurnTotal&&lastTurnTotal>0&&(usage.total=lastTurnTotal);let lastCallUsage=normalizeUsage(lastAssistant?.usage),promptTokens=derivePromptTokens(lastRunPromptUsage);outcome.provider=lastAssistant?.provider??provider,outcome.model=lastAssistant?.model??model.id,outcome.steps=(Array.isArray(attempt.toolMetas)?attempt.toolMetas.length:0)+autoContinueNudges+1,outcome.model!==model.id&&(outcome.degraded=!0);let agentMeta={sessionId:sessionIdUsed,provider:lastAssistant?.provider??provider,model:lastAssistant?.model??model.id,usage,lastCallUsage:lastCallUsage??void 0,promptTokens,compactionCount:autoCompactionCount>0?autoCompactionCount:void 0},payloads=buildEmbeddedRunPayloads({assistantTexts:attempt.assistantTexts,toolMetas:attempt.toolMetas,lastAssistant:attempt.lastAssistant,lastToolError:attempt.lastToolError,config:params.config,sessionKey:params.sessionKey??params.sessionId,provider:activeErrorContext.provider,model:activeErrorContext.model,verboseLevel:params.verboseLevel,reasoningLevel:params.reasoningLevel,toolResultFormat:resolvedToolResultFormat,suppressToolErrorWarnings:params.suppressToolErrorWarnings,inlineToolResultsAllowed:!1}),toolMetas=Array.isArray(attempt.toolMetas)?attempt.toolMetas:[],continuationDecision=shouldAutoContinueRun({userPrompt:params.prompt,assistantTexts:attempt.assistantTexts,payloadTexts:payloads.map(payload=>typeof payload.text==`string`?payload.text:``).filter(text=>text.length>0),toolNames:toolMetas.map(entry=>entry.toolName),hasToolError:!!attempt.lastToolError,aborted,timedOut,promptErrored:!!promptError,hasPendingClientToolCall:!!attempt.clientToolCall});if(log$3.debug(`auto-continue decision: shouldContinue=${continuationDecision.shouldContinue} reason=${continuationDecision.reason??`none`} runId=${params.runId} sessionId=${params.sessionId} toolCalls=${toolMetas.length}`),continuationDecision.shouldContinue&&autoContinueNudges<MAX_AUTO_CONTINUE_NUDGES){autoContinueNudges+=1;let latestPayloadText=payloads.map(payload=>typeof payload.text==`string`?payload.text.trim():``).find(text=>text.length>0),latestAssistantText=[...attempt.assistantTexts].toReversed().map(text=>text.trim()).find(text=>text.length>0);currentPrompt=buildAutoContinuePrompt({originalPrompt:params.prompt,lastAssistantText:latestAssistantText??latestPayloadText,reason:continuationDecision.reason}),log$3.warn(`auto-continue nudge ${autoContinueNudges}/${MAX_AUTO_CONTINUE_NUDGES}: reason=${continuationDecision.reason??`policy`} runId=${params.runId} sessionId=${params.sessionId}`);continue}if(timedOut&&!timedOutDuringCompaction&&payloads.length===0)return{payloads:[{text:"Request timed out before a response was generated. Please try again, or increase `agents.defaults.timeoutSeconds` in your config.",isError:!0}],meta:{durationMs:Date.now()-started,agentMeta,aborted,systemPromptReport:attempt.systemPromptReport},didSendViaMessagingTool:attempt.didSendViaMessagingTool,messagingToolSentTexts:attempt.messagingToolSentTexts,messagingToolSentMediaUrls:attempt.messagingToolSentMediaUrls,messagingToolSentTargets:attempt.messagingToolSentTargets,successfulCronAdds:attempt.successfulCronAdds};log$3.debug(`embedded run done: runId=${params.runId} sessionId=${params.sessionId} durationMs=${Date.now()-started} aborted=${aborted}`),lastProfileId&&(await markAuthProfileGood({store:authStore,provider,profileId:lastProfileId,agentDir:params.agentDir}),await markAuthProfileUsed({store:authStore,profileId:lastProfileId,agentDir:params.agentDir}));let finalPayloads=payloads.length?payloads:void 0;return(!finalPayloads||finalPayloads.length===0)&&(finalPayloads=[{text:autoContinueNudges>=MAX_AUTO_CONTINUE_NUDGES?`The agent reached the maximum auto-continue limit (${MAX_AUTO_CONTINUE_NUDGES}) without producing a final response. Consider breaking the task into smaller steps or increasing \`agents.defaults.maxAutoContinueNudges\` in your config.`:`The agent completed without producing any output. This may indicate an issue with the model response or tool execution.`,isError:!0}]),{payloads:finalPayloads,meta:{durationMs:Date.now()-started,agentMeta,aborted,systemPromptReport:attempt.systemPromptReport,stopReason:attempt.clientToolCall?`tool_calls`:void 0,pendingToolCalls:attempt.clientToolCall?[{id:`call_${Date.now()}`,name:attempt.clientToolCall.name,arguments:JSON.stringify(attempt.clientToolCall.params)}]:void 0},didSendViaMessagingTool:attempt.didSendViaMessagingTool,messagingToolSentTexts:attempt.messagingToolSentTexts,messagingToolSentMediaUrls:attempt.messagingToolSentMediaUrls,messagingToolSentTargets:attempt.messagingToolSentTargets,successfulCronAdds:attempt.successfulCronAdds}}}finally{process.chdir(prevCwd)}})).then(result=>(reportOutcome(result.meta?.aborted?`cancelled`:`completed`),result),error=>{throw reportOutcome(`failed`,error),error})}const DEFAULT_QUEUE_DEBOUNCE_MS=1e3,DEFAULT_QUEUE_DROP=`summarize`,FOLLOWUP_QUEUES=new Map;function getFollowupQueue(key,settings){let existing=FOLLOWUP_QUEUES.get(key);if(existing)return applyQueueRuntimeSettings({target:existing,settings}),existing;let created={items:[],draining:!1,lastEnqueuedAt:0,mode:settings.mode,debounceMs:typeof settings.debounceMs==`number`?Math.max(0,settings.debounceMs):DEFAULT_QUEUE_DEBOUNCE_MS,cap:typeof settings.cap==`number`&&settings.cap>0?Math.floor(settings.cap):20,dropPolicy:settings.dropPolicy??DEFAULT_QUEUE_DROP,droppedCount:0,summaryLines:[]};return applyQueueRuntimeSettings({target:created,settings}),FOLLOWUP_QUEUES.set(key,created),created}function clearFollowupQueue(key){let cleaned=key.trim();if(!cleaned)return 0;let queue=FOLLOWUP_QUEUES.get(cleaned);if(!queue)return 0;let cleared=queue.items.length+queue.droppedCount;return queue.items.length=0,queue.droppedCount=0,queue.summaryLines=[],queue.lastRun=void 0,queue.lastEnqueuedAt=0,FOLLOWUP_QUEUES.delete(cleaned),cleared}function clearSessionQueues(keys){let seen=new Set,followupCleared=0,laneCleared=0,clearedKeys=[];for(let key of keys){let cleaned=key?.trim();!cleaned||seen.has(cleaned)||(seen.add(cleaned),clearedKeys.push(cleaned),followupCleared+=clearFollowupQueue(cleaned),laneCleared+=clearCommandLane(resolveEmbeddedSessionLane(cleaned)))}return{followupCleared,laneCleared,keys:clearedKeys}}function scheduleFollowupDrain(key,runFollowup){let queue=FOLLOWUP_QUEUES.get(key);!queue||queue.draining||(queue.draining=!0,(async()=>{try{let forceIndividualCollect=!1;for(;queue.items.length>0||queue.droppedCount>0;){if(await waitForQueueDebounce(queue),queue.mode===`collect`){if(forceIndividualCollect){let next=queue.items[0];if(!next)break;await runFollowup(next),queue.items.shift();continue}if(hasCrossChannelItems(queue.items,item=>{let channel=item.originatingChannel,to=item.originatingTo,accountId=item.originatingAccountId,threadId=item.originatingThreadId;if(!channel&&!to&&!accountId&&threadId==null)return{};if(!isRoutableChannel(channel)||!to)return{cross:!0};let threadKey=threadId==null?``:String(threadId);return{key:[channel,to,accountId||``,threadKey].join(`|`)}})){forceIndividualCollect=!0;let next=queue.items[0];if(!next)break;await runFollowup(next),queue.items.shift();continue}let items=queue.items.slice(),summary=previewQueueSummaryPrompt({state:queue,noun:`message`}),run=items.at(-1)?.run??queue.lastRun;if(!run)break;let originatingChannel=items.find(i=>i.originatingChannel)?.originatingChannel,originatingTo=items.find(i=>i.originatingTo)?.originatingTo,originatingAccountId=items.find(i=>i.originatingAccountId)?.originatingAccountId,originatingThreadId=items.find(i=>i.originatingThreadId!=null)?.originatingThreadId;await runFollowup({prompt:buildCollectPrompt({title:`[Queued messages while agent was busy]`,items,summary,renderItem:(item,idx)=>`---\nQueued #${idx+1}\n${item.prompt}`.trim()}),run,enqueuedAt:Date.now(),originatingChannel,originatingTo,originatingAccountId,originatingThreadId}),queue.items.splice(0,items.length),summary&&clearQueueSummaryState(queue);continue}let summaryPrompt=previewQueueSummaryPrompt({state:queue,noun:`message`});if(summaryPrompt){let run=queue.lastRun;if(!run||!queue.items[0])break;await runFollowup({prompt:summaryPrompt,run,enqueuedAt:Date.now()}),queue.items.shift(),clearQueueSummaryState(queue);continue}let next=queue.items[0];if(!next)break;await runFollowup(next),queue.items.shift()}}catch(err){queue.lastEnqueuedAt=Date.now(),defaultRuntime.error?.(`followup queue drain failed for ${key}: ${String(err)}`)}finally{queue.draining=!1,queue.items.length===0&&queue.droppedCount===0?FOLLOWUP_QUEUES.delete(key):scheduleFollowupDrain(key,runFollowup)}})())}function isRunAlreadyQueued(run,items,allowPromptFallback=!1){let hasSameRouting=item=>item.originatingChannel===run.originatingChannel&&item.originatingTo===run.originatingTo&&item.originatingAccountId===run.originatingAccountId&&item.originatingThreadId===run.originatingThreadId,messageId=run.messageId?.trim();return messageId?items.some(item=>item.messageId?.trim()===messageId&&hasSameRouting(item)):allowPromptFallback?items.some(item=>item.prompt===run.prompt&&hasSameRouting(item)):!1}function enqueueFollowupRun(key,run,settings,dedupeMode=`message-id`){let queue=getFollowupQueue(key,settings),dedupe=dedupeMode===`none`?void 0:(item,items)=>isRunAlreadyQueued(item,items,dedupeMode===`prompt`);return shouldSkipQueueItem({item:run,items:queue.items,dedupe})||(queue.lastEnqueuedAt=Date.now(),queue.lastRun=run.run,!applyQueueDropPolicy({queue,summarize:item=>item.summaryLine?.trim()||item.prompt.trim()}))?!1:(queue.items.push(run),!0)}function getFollowupQueueDepth(key){let cleaned=key.trim();if(!cleaned)return 0;let queue=FOLLOWUP_QUEUES.get(cleaned);return queue?queue.items.length:0}function defaultQueueModeForChannel(_channel){return`collect`}function resolveChannelDebounce(byChannel,channelKey){if(!channelKey||!byChannel)return;let value=byChannel[channelKey];return typeof value==`number`&&Number.isFinite(value)?Math.max(0,value):void 0}function resolvePluginDebounce(channelKey){if(!channelKey)return;let value=getChannelPlugin(channelKey)?.defaults?.queue?.debounceMs;return typeof value==`number`&&Number.isFinite(value)?Math.max(0,value):void 0}function resolveQueueSettings(params){let channelKey=params.channel?.trim().toLowerCase(),queueCfg=params.cfg.messages?.queue,providerModeRaw=channelKey&&queueCfg?.byChannel?queueCfg.byChannel[channelKey]:void 0,resolvedMode=params.inlineMode??normalizeQueueMode(params.sessionEntry?.queueMode)??normalizeQueueMode(providerModeRaw)??normalizeQueueMode(queueCfg?.mode)??defaultQueueModeForChannel(channelKey),debounceRaw=params.inlineOptions?.debounceMs??params.sessionEntry?.queueDebounceMs??resolveChannelDebounce(queueCfg?.debounceMsByChannel,channelKey)??resolvePluginDebounce(channelKey)??queueCfg?.debounceMs??DEFAULT_QUEUE_DEBOUNCE_MS,capRaw=params.inlineOptions?.cap??params.sessionEntry?.queueCap??queueCfg?.cap??20,dropRaw=params.inlineOptions?.dropPolicy??params.sessionEntry?.queueDrop??normalizeQueueDropPolicy(queueCfg?.drop)??DEFAULT_QUEUE_DROP;return{mode:resolvedMode,debounceMs:typeof debounceRaw==`number`?Math.max(0,debounceRaw):void 0,cap:typeof capRaw==`number`?Math.max(1,Math.floor(capRaw)):void 0,dropPolicy:dropRaw}}function buildAnnounceIdFromChildRun(params){return`v1:${params.childSessionKey}:${params.childRunId}`}function buildAnnounceIdempotencyKey(announceId){return`announce:${announceId}`}function resolveQueueAnnounceId(params){return params.announceId?.trim()||`legacy:${params.sessionKey}:${params.enqueuedAt}`}function buildCompletionDeliveryMessage(params){let findingsText=params.findings.trim(),hasFindings=findingsText.length>0&&findingsText!==`(no output)`,header=`✅ Subagent ${params.subagentName} finished`;return hasFindings?`${header}\n\n${findingsText}`:header}function summarizeDeliveryError(error){if(error instanceof Error)return error.message||`error`;if(typeof error==`string`)return error;if(error==null)return`unknown error`;try{return JSON.stringify(error)}catch{return`error`}}function extractToolResultText(content){if(typeof content==`string`)return sanitizeTextContent(content);if(content&&typeof content==`object`&&!Array.isArray(content)){let obj=content;if(typeof obj.text==`string`)return sanitizeTextContent(obj.text);if(typeof obj.output==`string`)return sanitizeTextContent(obj.output);if(typeof obj.content==`string`)return sanitizeTextContent(obj.content);if(typeof obj.result==`string`)return sanitizeTextContent(obj.result);if(typeof obj.error==`string`)return sanitizeTextContent(obj.error);if(typeof obj.summary==`string`)return sanitizeTextContent(obj.summary)}return Array.isArray(content)?extractTextFromChatContent(content,{sanitizeText:sanitizeTextContent,normalizeText:text=>text,joinWith:`
539
539
  `})?.trim()??``:``}function extractInlineTextContent(content){return Array.isArray(content)?extractTextFromChatContent(content,{sanitizeText:sanitizeTextContent,normalizeText:text=>text.trim(),joinWith:``})??``:``}function extractSubagentOutputText(message){if(!message||typeof message!=`object`)return``;let role=message.role,content=message.content;return role===`assistant`?extractAssistantText(message)||(typeof content==`string`?sanitizeTextContent(content):Array.isArray(content)?extractInlineTextContent(content):``):role===`toolResult`||role===`tool`?extractToolResultText(message.content):typeof content==`string`?sanitizeTextContent(content):Array.isArray(content)?extractInlineTextContent(content):``}async function readLatestSubagentOutput(sessionKey){let history=await callGateway({method:`chat.history`,params:{sessionKey,limit:50}}),messages=Array.isArray(history?.messages)?history.messages:[];for(let i=messages.length-1;i>=0;--i){let msg=messages[i],text=extractSubagentOutputText(msg);if(text)return text}}async function readLatestSubagentOutputWithRetry(params){let deadline=Date.now()+Math.max(0,Math.min(params.maxWaitMs,15e3)),result;for(;Date.now()<deadline;){if(result=await readLatestSubagentOutput(params.sessionKey),result?.trim())return result;await new Promise(resolve=>setTimeout(resolve,100))}return result}function formatDurationShort(valueMs){if(!valueMs||!Number.isFinite(valueMs)||valueMs<=0)return`n/a`;let totalSeconds=Math.round(valueMs/1e3),hours=Math.floor(totalSeconds/3600),minutes=Math.floor(totalSeconds%3600/60),seconds=totalSeconds%60;return hours>0?`${hours}h${minutes}m`:minutes>0?`${minutes}m${seconds}s`:`${seconds}s`}function formatTokenCount(value){return typeof value!=`number`||!Number.isFinite(value)||value<=0?`0`:value>=1e6?`${(value/1e6).toFixed(1)}m`:value>=1e3?`${(value/1e3).toFixed(1)}k`:String(Math.round(value))}async function buildCompactAnnounceStatsLine(params){let cfg=loadConfig(),agentId=resolveAgentIdFromSessionKey(params.sessionKey),storePath=resolveStorePath(cfg.session?.store,{agentId}),entry=loadSessionStore(storePath)[params.sessionKey];for(let attempt=0;attempt<3&&!(typeof entry?.inputTokens==`number`||typeof entry?.outputTokens==`number`||typeof entry?.totalTokens==`number`);attempt+=1)await new Promise(resolve=>setTimeout(resolve,150)),entry=loadSessionStore(storePath)[params.sessionKey];let input=typeof entry?.inputTokens==`number`?entry.inputTokens:0,output=typeof entry?.outputTokens==`number`?entry.outputTokens:0,ioTotal=input+output,promptCache=typeof entry?.totalTokens==`number`?entry.totalTokens:void 0,parts=[`runtime ${formatDurationShort(typeof params.startedAt==`number`&&typeof params.endedAt==`number`?Math.max(0,params.endedAt-params.startedAt):void 0)}`,`tokens ${formatTokenCount(ioTotal)} (in ${formatTokenCount(input)} / out ${formatTokenCount(output)})`];return typeof promptCache==`number`&&promptCache>ioTotal&&parts.push(`prompt/cache ${formatTokenCount(promptCache)}`),`Stats: ${parts.join(` • `)}`}function resolveAnnounceOrigin(entry,requesterOrigin){let normalizedRequester=normalizeDeliveryContext(requesterOrigin),normalizedEntry=deliveryContextFromSession(entry);return normalizedRequester?.channel&&!isDeliverableMessageChannel(normalizedRequester.channel)?mergeDeliveryContext({accountId:normalizedRequester.accountId,threadId:normalizedRequester.threadId},normalizedEntry):mergeDeliveryContext(normalizedRequester,normalizedEntry)}async function sendAnnounce(item){let requesterIsSubagent=getSubagentDepthFromSessionStore(item.sessionKey)>=1,origin=item.origin,threadId=origin?.threadId!=null&&origin.threadId!==``?String(origin.threadId):void 0,idempotencyKey=buildAnnounceIdempotencyKey(resolveQueueAnnounceId({announceId:item.announceId,sessionKey:item.sessionKey,enqueuedAt:item.enqueuedAt}));await callGateway({method:`agent`,params:{sessionKey:item.sessionKey,message:item.prompt,channel:requesterIsSubagent?void 0:origin?.channel,accountId:requesterIsSubagent?void 0:origin?.accountId,to:requesterIsSubagent?void 0:origin?.to,threadId:requesterIsSubagent?void 0:threadId,deliver:!requesterIsSubagent,idempotencyKey},timeoutMs:15e3})}function resolveRequesterStoreKey(cfg,requesterSessionKey){let raw=requesterSessionKey.trim();if(!raw||raw===`global`||raw===`unknown`||raw.startsWith(`agent:`))return raw;let mainKey=normalizeMainKey(cfg.session?.mainKey);return raw===`main`||raw===mainKey?resolveMainSessionKey(cfg):`agent:${resolveAgentIdFromSessionKey(raw)}:${raw}`}function loadRequesterSessionEntry(requesterSessionKey){let cfg=loadConfig(),canonicalKey=resolveRequesterStoreKey(cfg,requesterSessionKey),agentId=resolveAgentIdFromSessionKey(canonicalKey);return{cfg,entry:loadSessionStore(resolveStorePath(cfg.session?.store,{agentId}))[canonicalKey],canonicalKey}}async function maybeQueueSubagentAnnounce(params){let{cfg,entry}=loadRequesterSessionEntry(params.requesterSessionKey),canonicalKey=resolveRequesterStoreKey(cfg,params.requesterSessionKey),sessionId=entry?.sessionId;if(!sessionId)return`none`;let queueSettings=resolveQueueSettings({cfg,channel:entry?.channel??entry?.lastChannel,sessionEntry:entry}),isActive=isEmbeddedRunActive(sessionId);if((queueSettings.mode===`steer`||queueSettings.mode===`steer-backlog`)&&queueEmbeddedMessage(sessionId,params.triggerMessage))return`steered`;let shouldFollowup=queueSettings.mode===`followup`||queueSettings.mode===`collect`||queueSettings.mode===`steer-backlog`||queueSettings.mode===`interrupt`;if(isActive&&(shouldFollowup||queueSettings.mode===`steer`)){let origin=resolveAnnounceOrigin(entry,params.requesterOrigin);return enqueueAnnounce({key:canonicalKey,item:{announceId:params.announceId,prompt:params.triggerMessage,summaryLine:params.summaryLine,enqueuedAt:Date.now(),sessionKey:canonicalKey,origin},settings:queueSettings,send:sendAnnounce}),`queued`}return`none`}function queueOutcomeToDeliveryResult(outcome){return outcome===`steered`?{delivered:!0,path:`steered`}:outcome===`queued`?{delivered:!0,path:`queued`}:{delivered:!1,path:`none`}}async function sendSubagentAnnounceDirectly(params){let canonicalRequesterSessionKey=resolveRequesterStoreKey(loadConfig(),params.targetRequesterSessionKey);try{let completionDirectOrigin=normalizeDeliveryContext(params.completionDirectOrigin),completionChannelRaw=typeof completionDirectOrigin?.channel==`string`?completionDirectOrigin.channel.trim():``,completionChannel=completionChannelRaw&&isDeliverableMessageChannel(completionChannelRaw)?completionChannelRaw:``,completionTo=typeof completionDirectOrigin?.to==`string`?completionDirectOrigin.to.trim():``,hasCompletionDirectTarget=!params.requesterIsSubagent&&!!completionChannel&&!!completionTo;if(params.expectsCompletionMessage&&hasCompletionDirectTarget&&params.completionMessage?.trim()){let completionThreadId=completionDirectOrigin?.threadId!=null&&completionDirectOrigin.threadId!==``?String(completionDirectOrigin.threadId):void 0;return await callGateway({method:`send`,params:{channel:completionChannel,to:completionTo,accountId:completionDirectOrigin?.accountId,threadId:completionThreadId,sessionKey:canonicalRequesterSessionKey,message:params.completionMessage,idempotencyKey:params.directIdempotencyKey},timeoutMs:15e3}),{delivered:!0,path:`direct`}}let directOrigin=normalizeDeliveryContext(params.directOrigin),threadId=directOrigin?.threadId!=null&&directOrigin.threadId!==``?String(directOrigin.threadId):void 0;return await callGateway({method:`agent`,params:{sessionKey:canonicalRequesterSessionKey,message:params.triggerMessage,deliver:!params.requesterIsSubagent,channel:params.requesterIsSubagent?void 0:directOrigin?.channel,accountId:params.requesterIsSubagent?void 0:directOrigin?.accountId,to:params.requesterIsSubagent?void 0:directOrigin?.to,threadId:params.requesterIsSubagent?void 0:threadId,idempotencyKey:params.directIdempotencyKey},expectFinal:!0,timeoutMs:15e3}),{delivered:!0,path:`direct`}}catch(err){return{delivered:!1,path:`direct`,error:summarizeDeliveryError(err)}}}async function deliverSubagentAnnouncement(params){if(!params.expectsCompletionMessage){let queued=queueOutcomeToDeliveryResult(await maybeQueueSubagentAnnounce({requesterSessionKey:params.requesterSessionKey,announceId:params.announceId,triggerMessage:params.triggerMessage,summaryLine:params.summaryLine,requesterOrigin:params.requesterOrigin}));if(queued.delivered)return queued}let direct=await sendSubagentAnnounceDirectly({targetRequesterSessionKey:params.targetRequesterSessionKey,triggerMessage:params.triggerMessage,completionMessage:params.completionMessage,directIdempotencyKey:params.directIdempotencyKey,completionDirectOrigin:params.completionDirectOrigin,directOrigin:params.directOrigin,requesterIsSubagent:params.requesterIsSubagent,expectsCompletionMessage:params.expectsCompletionMessage});if(direct.delivered||!params.expectsCompletionMessage)return direct;let queueOutcome=await maybeQueueSubagentAnnounce({requesterSessionKey:params.requesterSessionKey,announceId:params.announceId,triggerMessage:params.triggerMessage,summaryLine:params.summaryLine,requesterOrigin:params.requesterOrigin});return queueOutcome===`steered`||queueOutcome===`queued`?queueOutcomeToDeliveryResult(queueOutcome):direct}function loadSessionEntryByKey(sessionKey){let cfg=loadConfig(),agentId=resolveAgentIdFromSessionKey(sessionKey);return loadSessionStore(resolveStorePath(cfg.session?.store,{agentId}))[sessionKey]}function buildSubagentSystemPrompt(params){let taskText=typeof params.task==`string`&&params.task.trim()?params.task.replace(/\s+/g,` `).trim():`{{TASK_DESCRIPTION}}`,childDepth=typeof params.childDepth==`number`?params.childDepth:1,canSpawn=childDepth<(typeof params.maxSpawnDepth==`number`?params.maxSpawnDepth:1),parentLabel=childDepth>=2?`parent orchestrator`:`main agent`,lines=[`# Subagent Context`,``,`You are a **subagent** spawned by the ${parentLabel} for a specific task.`,``,`## Your Role`,`- You were created to handle: ${taskText}`,`- Complete this task. That's your entire purpose.`,`- You are NOT the ${parentLabel}. Don't try to be.`,``,`## Rules`,`1. **Stay focused** - Do your assigned task, nothing else`,`2. **Complete the task** - Your final message will be automatically reported to the ${parentLabel}`,`3. **Don't initiate** - No heartbeats, no proactive actions, no side quests`,`4. **Be ephemeral** - You may be terminated after task completion. That's fine.`,`5. **Trust push-based completion** - Descendant results are auto-announced back to you; do not busy-poll for status.`,"6. **Recover from compacted/truncated tool output** - If you see `[compacted: tool output removed to free context]` or `[truncated: output exceeded context limit]`, assume prior output was reduced. Re-read only what you need using smaller chunks (`read` with offset/limit, or targeted `rg`/`head`/`tail`) instead of full-file `cat`.",``,`## Output Format`,`When complete, your final response should include:`,`- What you accomplished or found`,`- Any relevant details the ${parentLabel} should know`,`- Keep it concise but informative`,``,`## What You DON'T Do`,`- NO user conversations (that's ${parentLabel}'s job)`,`- NO external messages (email, tweets, etc.) unless explicitly tasked with a specific recipient/channel`,`- NO cron jobs or persistent state`,`- NO pretending to be the ${parentLabel}`,`- Only use the \`message\` tool when explicitly instructed to contact a specific external recipient; otherwise return plain text and let the ${parentLabel} deliver it`,``];return canSpawn?lines.push(`## Sub-Agent Spawning`,"You CAN spawn your own sub-agents for parallel or complex work using `sessions_spawn`.","Use the `subagents` tool to steer, kill, or do an on-demand status check for your spawned sub-agents.",`Your sub-agents will announce their results back to you automatically (not to the main agent).`,`Default workflow: spawn work, continue orchestrating, and wait for auto-announced completions.`,"Do NOT repeatedly poll `subagents list` in a loop unless you are actively debugging or intervening.",`Coordinate their work and synthesize results before reporting back.`,``):childDepth>=2&&lines.push(`## Sub-Agent Spawning`,`You are a leaf worker and CANNOT spawn further sub-agents. Focus on your assigned task.`,``),lines.push(`## Session Context`,...[params.label?`- Label: ${params.label}`:void 0,params.requesterSessionKey?`- Requester session: ${params.requesterSessionKey}.`:void 0,params.requesterOrigin?.channel?`- Requester channel: ${params.requesterOrigin.channel}.`:void 0,`- Your session: ${params.childSessionKey}.`].filter(line=>line!==void 0),``),lines.join(`
540
- `)}function buildAnnounceReplyInstruction(params){if(params.expectsCompletionMessage)return`A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type).`;if(params.remainingActiveSubagentRuns>0){let activeRunsLabel=params.remainingActiveSubagentRuns===1?`run`:`runs`;return`There are still ${params.remainingActiveSubagentRuns} active subagent ${activeRunsLabel} for this session. If they are part of the same workflow, wait for the remaining results before sending a user update. If they are unrelated, respond normally using only the result above.`}return params.requesterIsSubagent?`Convert this completion into a concise internal orchestration update for your parent agent in your own words. Keep this internal context private (don't mention system/log/stats/session details or announce type). If this result is duplicate or no update is needed, reply ONLY: ${SILENT_REPLY_TOKEN}.`:`A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type), and do not copy the system message verbatim. Reply ONLY: ${SILENT_REPLY_TOKEN} if this exact result was already delivered to the user in this same turn.`}async function runSubagentAnnounceFlow(params){let didAnnounce=!1,expectsCompletionMessage=params.expectsCompletionMessage===!0,shouldDeleteChildSession=params.cleanup===`delete`;try{let targetRequesterSessionKey=params.requesterSessionKey,targetRequesterOrigin=normalizeDeliveryContext(params.requesterOrigin),childSessionId=(()=>{let entry=loadSessionEntryByKey(params.childSessionKey);return typeof entry?.sessionId==`string`&&entry.sessionId.trim()?entry.sessionId.trim():void 0})(),settleTimeoutMs=Math.min(Math.max(params.timeoutMs,1),12e4),reply=params.roundOneReply,outcome=params.outcome;if(!expectsCompletionMessage&&childSessionId&&isEmbeddedRunActive(childSessionId)&&!await waitForEmbeddedRunEnd(childSessionId,settleTimeoutMs)&&isEmbeddedRunActive(childSessionId))return shouldDeleteChildSession=!1,!1;if(!reply&&params.waitForCompletion!==!1){let waitMs=settleTimeoutMs,wait=await callGateway({method:`agent.wait`,params:{runId:params.childRunId,timeoutMs:waitMs},timeoutMs:waitMs+2e3}),waitError=typeof wait?.error==`string`?wait.error:void 0;wait?.status===`timeout`?outcome={status:`timeout`}:wait?.status===`error`?outcome={status:`error`,error:waitError}:wait?.status===`ok`&&(outcome={status:`ok`}),typeof wait?.startedAt==`number`&&!params.startedAt&&(params.startedAt=wait.startedAt),typeof wait?.endedAt==`number`&&!params.endedAt&&(params.endedAt=wait.endedAt),wait?.status===`timeout`&&(outcome||={status:`timeout`}),reply=await readLatestSubagentOutput(params.childSessionKey)}if(reply||=await readLatestSubagentOutput(params.childSessionKey),reply?.trim()||(reply=await readLatestSubagentOutputWithRetry({sessionKey:params.childSessionKey,maxWaitMs:params.timeoutMs})),!expectsCompletionMessage&&!reply?.trim()&&childSessionId&&isEmbeddedRunActive(childSessionId))return shouldDeleteChildSession=!1,!1;outcome||={status:`unknown`};let activeChildDescendantRuns=0;try{let{countActiveDescendantRuns}=await import(`./subagent-registry-Dr20nzwk.js`);activeChildDescendantRuns=Math.max(0,await countActiveDescendantRuns(params.childSessionKey))}catch{}if(!expectsCompletionMessage&&activeChildDescendantRuns>0)return shouldDeleteChildSession=!1,!1;let statusLabel=outcome.status===`ok`?`completed successfully`:outcome.status===`timeout`?`timed out`:outcome.status===`error`?`failed: ${outcome.error||`unknown error`}`:`finished with unknown status`,announceType=params.announceType??`subagent task`,taskLabel=params.label||params.task||`task`,subagentName=resolveAgentIdFromSessionKey(params.childSessionKey),announceSessionId=childSessionId||`unknown`,findings=reply||`(no output)`,completionMessage=``,triggerMessage=``,requesterDepth=getSubagentDepthFromSessionStore(targetRequesterSessionKey),requesterIsSubagent=!expectsCompletionMessage&&requesterDepth>=1;if(requesterIsSubagent){let{isSubagentSessionRunActive,resolveRequesterForChildSession}=await import(`./subagent-registry-Dr20nzwk.js`);if(!isSubagentSessionRunActive(targetRequesterSessionKey)){let parentSessionEntry=loadSessionEntryByKey(targetRequesterSessionKey);if(!(parentSessionEntry&&typeof parentSessionEntry.sessionId==`string`&&parentSessionEntry.sessionId.trim())){let fallback=await resolveRequesterForChildSession(targetRequesterSessionKey);if(!fallback?.requesterSessionKey)return shouldDeleteChildSession=!1,!1;targetRequesterSessionKey=fallback.requesterSessionKey,targetRequesterOrigin=normalizeDeliveryContext(fallback.requesterOrigin)??targetRequesterOrigin,requesterDepth=getSubagentDepthFromSessionStore(targetRequesterSessionKey),requesterIsSubagent=requesterDepth>=1}}}let remainingActiveSubagentRuns=0;try{let{countActiveDescendantRuns}=await import(`./subagent-registry-Dr20nzwk.js`);remainingActiveSubagentRuns=Math.max(0,await countActiveDescendantRuns(targetRequesterSessionKey))}catch{}let replyInstruction=buildAnnounceReplyInstruction({remainingActiveSubagentRuns,requesterIsSubagent,announceType,expectsCompletionMessage}),statsLine=await buildCompactAnnounceStatsLine({sessionKey:params.childSessionKey,startedAt:params.startedAt,endedAt:params.endedAt});completionMessage=buildCompletionDeliveryMessage({findings,subagentName}),triggerMessage=[[`[System Message] [sessionId: ${announceSessionId}] A ${announceType} "${taskLabel}" just ${statusLabel}.`,``,`Result:`,findings,``,statsLine].join(`
540
+ `)}function buildAnnounceReplyInstruction(params){if(params.expectsCompletionMessage)return`A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type).`;if(params.remainingActiveSubagentRuns>0){let activeRunsLabel=params.remainingActiveSubagentRuns===1?`run`:`runs`;return`There are still ${params.remainingActiveSubagentRuns} active subagent ${activeRunsLabel} for this session. If they are part of the same workflow, wait for the remaining results before sending a user update. If they are unrelated, respond normally using only the result above.`}return params.requesterIsSubagent?`Convert this completion into a concise internal orchestration update for your parent agent in your own words. Keep this internal context private (don't mention system/log/stats/session details or announce type). If this result is duplicate or no update is needed, reply ONLY: ${SILENT_REPLY_TOKEN}.`:`A completed ${params.announceType} is ready for user delivery. Convert the result above into your normal assistant voice and send that user-facing update now. Keep this internal context private (don't mention system/log/stats/session details or announce type), and do not copy the system message verbatim. Reply ONLY: ${SILENT_REPLY_TOKEN} if this exact result was already delivered to the user in this same turn.`}async function runSubagentAnnounceFlow(params){let didAnnounce=!1,expectsCompletionMessage=params.expectsCompletionMessage===!0,shouldDeleteChildSession=params.cleanup===`delete`;try{let targetRequesterSessionKey=params.requesterSessionKey,targetRequesterOrigin=normalizeDeliveryContext(params.requesterOrigin),childSessionId=(()=>{let entry=loadSessionEntryByKey(params.childSessionKey);return typeof entry?.sessionId==`string`&&entry.sessionId.trim()?entry.sessionId.trim():void 0})(),settleTimeoutMs=Math.min(Math.max(params.timeoutMs,1),12e4),reply=params.roundOneReply,outcome=params.outcome;if(!expectsCompletionMessage&&childSessionId&&isEmbeddedRunActive(childSessionId)&&!await waitForEmbeddedRunEnd(childSessionId,settleTimeoutMs)&&isEmbeddedRunActive(childSessionId))return shouldDeleteChildSession=!1,!1;if(!reply&&params.waitForCompletion!==!1){let waitMs=settleTimeoutMs,wait=await callGateway({method:`agent.wait`,params:{runId:params.childRunId,timeoutMs:waitMs},timeoutMs:waitMs+2e3}),waitError=typeof wait?.error==`string`?wait.error:void 0;wait?.status===`timeout`?outcome={status:`timeout`}:wait?.status===`error`?outcome={status:`error`,error:waitError}:wait?.status===`ok`&&(outcome={status:`ok`}),typeof wait?.startedAt==`number`&&!params.startedAt&&(params.startedAt=wait.startedAt),typeof wait?.endedAt==`number`&&!params.endedAt&&(params.endedAt=wait.endedAt),wait?.status===`timeout`&&(outcome||={status:`timeout`}),reply=await readLatestSubagentOutput(params.childSessionKey)}if(reply||=await readLatestSubagentOutput(params.childSessionKey),reply?.trim()||(reply=await readLatestSubagentOutputWithRetry({sessionKey:params.childSessionKey,maxWaitMs:params.timeoutMs})),!expectsCompletionMessage&&!reply?.trim()&&childSessionId&&isEmbeddedRunActive(childSessionId))return shouldDeleteChildSession=!1,!1;outcome||={status:`unknown`};let activeChildDescendantRuns=0;try{let{countActiveDescendantRuns}=await import(`./subagent-registry-CaRUNwCj.js`);activeChildDescendantRuns=Math.max(0,await countActiveDescendantRuns(params.childSessionKey))}catch{}if(!expectsCompletionMessage&&activeChildDescendantRuns>0)return shouldDeleteChildSession=!1,!1;let statusLabel=outcome.status===`ok`?`completed successfully`:outcome.status===`timeout`?`timed out`:outcome.status===`error`?`failed: ${outcome.error||`unknown error`}`:`finished with unknown status`,announceType=params.announceType??`subagent task`,taskLabel=params.label||params.task||`task`,subagentName=resolveAgentIdFromSessionKey(params.childSessionKey),announceSessionId=childSessionId||`unknown`,findings=reply||`(no output)`,completionMessage=``,triggerMessage=``,requesterDepth=getSubagentDepthFromSessionStore(targetRequesterSessionKey),requesterIsSubagent=!expectsCompletionMessage&&requesterDepth>=1;if(requesterIsSubagent){let{isSubagentSessionRunActive,resolveRequesterForChildSession}=await import(`./subagent-registry-CaRUNwCj.js`);if(!isSubagentSessionRunActive(targetRequesterSessionKey)){let parentSessionEntry=loadSessionEntryByKey(targetRequesterSessionKey);if(!(parentSessionEntry&&typeof parentSessionEntry.sessionId==`string`&&parentSessionEntry.sessionId.trim())){let fallback=await resolveRequesterForChildSession(targetRequesterSessionKey);if(!fallback?.requesterSessionKey)return shouldDeleteChildSession=!1,!1;targetRequesterSessionKey=fallback.requesterSessionKey,targetRequesterOrigin=normalizeDeliveryContext(fallback.requesterOrigin)??targetRequesterOrigin,requesterDepth=getSubagentDepthFromSessionStore(targetRequesterSessionKey),requesterIsSubagent=requesterDepth>=1}}}let remainingActiveSubagentRuns=0;try{let{countActiveDescendantRuns}=await import(`./subagent-registry-CaRUNwCj.js`);remainingActiveSubagentRuns=Math.max(0,await countActiveDescendantRuns(targetRequesterSessionKey))}catch{}let replyInstruction=buildAnnounceReplyInstruction({remainingActiveSubagentRuns,requesterIsSubagent,announceType,expectsCompletionMessage}),statsLine=await buildCompactAnnounceStatsLine({sessionKey:params.childSessionKey,startedAt:params.startedAt,endedAt:params.endedAt});completionMessage=buildCompletionDeliveryMessage({findings,subagentName}),triggerMessage=[[`[System Message] [sessionId: ${announceSessionId}] A ${announceType} "${taskLabel}" just ${statusLabel}.`,``,`Result:`,findings,``,statsLine].join(`
541
541
  `),``,replyInstruction].join(`
542
542
  `);let announceId=buildAnnounceIdFromChildRun({childSessionKey:params.childSessionKey,childRunId:params.childRunId}),directOrigin=targetRequesterOrigin;if(!requesterIsSubagent){let{entry}=loadRequesterSessionEntry(targetRequesterSessionKey);directOrigin=resolveAnnounceOrigin(entry,targetRequesterOrigin)}let directIdempotencyKey=buildAnnounceIdempotencyKey(announceId),delivery=await deliverSubagentAnnouncement({requesterSessionKey:targetRequesterSessionKey,announceId,triggerMessage,completionMessage,summaryLine:taskLabel,requesterOrigin:targetRequesterOrigin,completionDirectOrigin:targetRequesterOrigin,directOrigin,targetRequesterSessionKey,requesterIsSubagent,expectsCompletionMessage,directIdempotencyKey});didAnnounce=delivery.delivered,!delivery.delivered&&delivery.path===`direct`&&delivery.error&&defaultRuntime.error?.(`Subagent completion direct announce failed for run ${params.childRunId}: ${delivery.error}`)}catch(err){defaultRuntime.error?.(`Subagent announce failed: ${String(err)}`)}finally{if(params.label)try{await callGateway({method:`sessions.patch`,params:{key:params.childSessionKey,label:params.label},timeoutMs:1e4})}catch{}if(shouldDeleteChildSession)try{await callGateway({method:`sessions.delete`,params:{key:params.childSessionKey,deleteTranscript:!0},timeoutMs:1e4})}catch{}}return didAnnounce}function resolveSubagentStateDir(env=process.env){return env.BUILDERFORCE_AGENTS_STATE_DIR?.trim()?resolveStateDir(env):env.VITEST||env.NODE_ENV===`test`?path.join(os.tmpdir(),`builderforce-test-state`,String(process.pid)):resolveStateDir(env)}function resolveSubagentRegistryPath(){return path.join(resolveSubagentStateDir(process.env),`subagents`,`runs.json`)}async function loadSubagentRegistryFromDisk(){let raw=await loadJsonFile(resolveSubagentRegistryPath());if(!raw||typeof raw!=`object`)return new Map;let record=raw;if(record.version!==1&&record.version!==2)return new Map;let runsRaw=record.runs;if(!runsRaw||typeof runsRaw!=`object`)return new Map;let out=new Map,isLegacy=record.version===1,migrated=!1;for(let[runId,entry]of Object.entries(runsRaw)){if(!entry||typeof entry!=`object`)continue;let typed=entry;if(!typed.runId||typeof typed.runId!=`string`)continue;let legacyCompletedAt=isLegacy&&typeof typed.announceCompletedAt==`number`?typed.announceCompletedAt:void 0,cleanupCompletedAt=typeof typed.cleanupCompletedAt==`number`?typed.cleanupCompletedAt:legacyCompletedAt,cleanupHandled=typeof typed.cleanupHandled==`boolean`?typed.cleanupHandled:isLegacy?!!(typed.announceHandled??cleanupCompletedAt):void 0,requesterOrigin=normalizeDeliveryContext(typed.requesterOrigin??{channel:typeof typed.requesterChannel==`string`?typed.requesterChannel:void 0,accountId:typeof typed.requesterAccountId==`string`?typed.requesterAccountId:void 0}),{announceCompletedAt:_announceCompletedAt,announceHandled:_announceHandled,requesterChannel:_channel,requesterAccountId:_accountId,...rest}=typed;out.set(runId,{...rest,requesterOrigin,cleanupCompletedAt,cleanupHandled}),isLegacy&&(migrated=!0)}if(migrated)try{await saveSubagentRegistryToDisk(out)}catch{}return out}async function saveSubagentRegistryToDisk(runs){let pathname=resolveSubagentRegistryPath(),serialized={};for(let[runId,entry]of runs.entries())serialized[runId]=entry;await saveJsonFile(pathname,{version:2,runs:serialized})}const subagentRuns=new Map;let sweeper=null,listenerStarted=!1;var restoreAttempted=!1;const ANNOUNCE_EXPIRY_MS=5*6e4;function resolveAnnounceRetryDelayMs(retryCount){let boundedRetryCount=Math.max(0,Math.min(retryCount,10)),baseDelay=1e3*2**Math.max(0,boundedRetryCount-1);return Math.min(baseDelay,8e3)}function logAnnounceGiveUp(entry,reason){let retryCount=entry.announceRetryCount??0,endedAgoMs=typeof entry.endedAt==`number`?Math.max(0,Date.now()-entry.endedAt):void 0,endedAgoLabel=endedAgoMs==null?`n/a`:`${Math.round(endedAgoMs/1e3)}s`;defaultRuntime.log(`[warn] Subagent announce give up (${reason}) run=${entry.runId} child=${entry.childSessionKey} requester=${entry.requesterSessionKey} retries=${retryCount} endedAgo=${endedAgoLabel}`)}let persistChain=Promise.resolve();function persistSubagentRuns(){return persistChain=persistChain.then(()=>saveSubagentRegistryToDisk(subagentRuns)).catch(err=>{logWarn(`subagent registry persist failed: ${String(err)}`)}),persistChain}const resumedRuns=new Set;function suppressAnnounceForSteerRestart(entry){return entry?.suppressAnnounceReason===`steer-restart`}function startSubagentAnnounceCleanupFlow(runId,entry){if(!beginSubagentCleanup(runId))return!1;let requesterOrigin=normalizeDeliveryContext(entry.requesterOrigin);return runSubagentAnnounceFlow({childSessionKey:entry.childSessionKey,childRunId:entry.runId,requesterSessionKey:entry.requesterSessionKey,requesterOrigin,requesterDisplayKey:entry.requesterDisplayKey,task:entry.task,expectsCompletionMessage:entry.expectsCompletionMessage,timeoutMs:12e4,cleanup:entry.cleanup,waitForCompletion:!1,startedAt:entry.startedAt,endedAt:entry.endedAt,label:entry.label,outcome:entry.outcome}).then(didAnnounce=>{finalizeSubagentCleanup(runId,entry.cleanup,didAnnounce)}),!0}function resumeSubagentRun(runId){if(!runId||resumedRuns.has(runId))return;let entry=subagentRuns.get(runId);if(!entry||entry.cleanupCompletedAt)return;if((entry.announceRetryCount??0)>=3){logAnnounceGiveUp(entry,`retry-limit`),entry.cleanupCompletedAt=Date.now(),persistSubagentRuns();return}if(typeof entry.endedAt==`number`&&Date.now()-entry.endedAt>ANNOUNCE_EXPIRY_MS){logAnnounceGiveUp(entry,`expiry`),entry.cleanupCompletedAt=Date.now(),persistSubagentRuns();return}let now=Date.now(),delayMs=resolveAnnounceRetryDelayMs(entry.announceRetryCount??0),earliestRetryAt=(entry.lastAnnounceRetryAt??0)+delayMs;if(entry.expectsCompletionMessage===!0&&entry.lastAnnounceRetryAt&&now<earliestRetryAt){let waitMs=Math.max(1,earliestRetryAt-now);setTimeout(()=>{resumeSubagentRun(runId)},waitMs).unref?.(),resumedRuns.add(runId);return}if(typeof entry.endedAt==`number`&&entry.endedAt>0){if(suppressAnnounceForSteerRestart(entry)){resumedRuns.add(runId);return}if(!startSubagentAnnounceCleanupFlow(runId,entry))return;resumedRuns.add(runId);return}waitForSubagentCompletion(runId,resolveSubagentWaitTimeoutMs(loadConfig(),entry.runTimeoutSeconds)),resumedRuns.add(runId)}async function restoreSubagentRunsOnce(){if(!restoreAttempted){restoreAttempted=!0;try{let restored=await loadSubagentRegistryFromDisk();if(restored.size===0)return;for(let[runId,entry]of restored.entries())!runId||!entry||subagentRuns.has(runId)||subagentRuns.set(runId,entry);ensureListener(),[...subagentRuns.values()].some(entry=>entry.archiveAtMs)&&startSweeper();for(let runId of subagentRuns.keys())resumeSubagentRun(runId)}catch(err){let message=`failed to restore subagent runs: ${String(err)}`;defaultRuntime.error(message)}}}function resolveArchiveAfterMs(cfg){let minutes=(cfg??loadConfig()).agents?.defaults?.subagents?.archiveAfterMinutes??60;if(!(!Number.isFinite(minutes)||minutes<=0))return Math.max(1,Math.floor(minutes))*6e4}function resolveSubagentWaitTimeoutMs(cfg,runTimeoutSeconds){return resolveAgentTimeoutMs({cfg,overrideSeconds:runTimeoutSeconds??0})}function startSweeper(){sweeper||(sweeper=setInterval(()=>{sweepSubagentRuns()},6e4),sweeper.unref?.())}function stopSweeper(){sweeper&&=(clearInterval(sweeper),null)}async function sweepSubagentRuns(){let now=Date.now(),mutated=!1;for(let[runId,entry]of subagentRuns.entries())if(!(!entry.archiveAtMs||entry.archiveAtMs>now)){subagentRuns.delete(runId),mutated=!0;try{await callGateway({method:`sessions.delete`,params:{key:entry.childSessionKey,deleteTranscript:!0},timeoutMs:1e4})}catch{}}mutated&&await persistSubagentRuns(),subagentRuns.size===0&&stopSweeper()}function ensureListener(){listenerStarted||(listenerStarted=!0,onAgentEvent(evt=>{if(!evt||evt.stream!==`lifecycle`)return;let entry=subagentRuns.get(evt.runId);if(!entry)return;let phase=evt.data?.phase;if(phase===`start`){let startedAt=typeof evt.data?.startedAt==`number`?evt.data.startedAt:void 0;startedAt&&(entry.startedAt=startedAt,persistSubagentRuns());return}phase!==`end`&&phase!==`error`||(entry.endedAt=typeof evt.data?.endedAt==`number`?evt.data.endedAt:Date.now(),phase===`error`?entry.outcome={status:`error`,error:typeof evt.data?.error==`string`?evt.data.error:void 0}:evt.data?.aborted?entry.outcome={status:`timeout`}:entry.outcome={status:`ok`},persistSubagentRuns(),!suppressAnnounceForSteerRestart(entry)&&startSubagentAnnounceCleanupFlow(evt.runId,entry))}))}function finalizeSubagentCleanup(runId,cleanup,didAnnounce){let entry=subagentRuns.get(runId);if(entry){if(!didAnnounce){let now=Date.now(),retryCount=(entry.announceRetryCount??0)+1;entry.announceRetryCount=retryCount,entry.lastAnnounceRetryAt=now;let endedAgo=typeof entry.endedAt==`number`?now-entry.endedAt:0;if(retryCount>=3||endedAgo>ANNOUNCE_EXPIRY_MS){logAnnounceGiveUp(entry,retryCount>=3?`retry-limit`:`expiry`),entry.cleanupCompletedAt=now,persistSubagentRuns(),retryDeferredCompletedAnnounces(runId);return}if(entry.cleanupHandled=!1,resumedRuns.delete(runId),persistSubagentRuns(),entry.expectsCompletionMessage!==!0)return;setTimeout(()=>{resumeSubagentRun(runId)},resolveAnnounceRetryDelayMs(entry.announceRetryCount??0)).unref?.();return}if(cleanup===`delete`){subagentRuns.delete(runId),persistSubagentRuns(),retryDeferredCompletedAnnounces(runId);return}entry.cleanupCompletedAt=Date.now(),persistSubagentRuns(),retryDeferredCompletedAnnounces(runId)}}function retryDeferredCompletedAnnounces(excludeRunId){let now=Date.now();for(let[runId,entry]of subagentRuns.entries())if(!(excludeRunId&&runId===excludeRunId)&&typeof entry.endedAt==`number`&&!(entry.cleanupCompletedAt||entry.cleanupHandled)&&!suppressAnnounceForSteerRestart(entry)){if(now-(entry.endedAt??now)>ANNOUNCE_EXPIRY_MS){logAnnounceGiveUp(entry,`expiry`),entry.cleanupCompletedAt=now,persistSubagentRuns();continue}resumedRuns.delete(runId),resumeSubagentRun(runId)}}function beginSubagentCleanup(runId){let entry=subagentRuns.get(runId);return!entry||entry.cleanupCompletedAt||entry.cleanupHandled?!1:(entry.cleanupHandled=!0,persistSubagentRuns(),!0)}function markSubagentRunForSteerRestart(runId){let key=runId.trim();if(!key)return!1;let entry=subagentRuns.get(key);return entry?entry.suppressAnnounceReason===`steer-restart`?!0:(entry.suppressAnnounceReason=`steer-restart`,persistSubagentRuns(),!0):!1}function clearSubagentRunSteerRestart(runId){let key=runId.trim();if(!key)return!1;let entry=subagentRuns.get(key);return entry?entry.suppressAnnounceReason===`steer-restart`?(entry.suppressAnnounceReason=void 0,persistSubagentRuns(),resumedRuns.delete(key),typeof entry.endedAt==`number`&&!entry.cleanupCompletedAt&&resumeSubagentRun(key),!0):!0:!1}function replaceSubagentRunAfterSteer(params){let previousRunId=params.previousRunId.trim(),nextRunId=params.nextRunId.trim();if(!previousRunId||!nextRunId)return!1;let source=subagentRuns.get(previousRunId)??params.fallback;if(!source)return!1;previousRunId!==nextRunId&&(subagentRuns.delete(previousRunId),resumedRuns.delete(previousRunId));let now=Date.now(),cfg=loadConfig(),archiveAfterMs=resolveArchiveAfterMs(cfg),archiveAtMs=archiveAfterMs?now+archiveAfterMs:void 0,runTimeoutSeconds=params.runTimeoutSeconds??source.runTimeoutSeconds??0,waitTimeoutMs=resolveSubagentWaitTimeoutMs(cfg,runTimeoutSeconds),next={...source,runId:nextRunId,startedAt:now,endedAt:void 0,outcome:void 0,cleanupCompletedAt:void 0,cleanupHandled:!1,suppressAnnounceReason:void 0,announceRetryCount:void 0,lastAnnounceRetryAt:void 0,archiveAtMs,runTimeoutSeconds};return subagentRuns.set(nextRunId,next),ensureListener(),persistSubagentRuns(),archiveAfterMs&&startSweeper(),waitForSubagentCompletion(nextRunId,waitTimeoutMs),!0}function registerSubagentRun(params){let now=Date.now(),cfg=loadConfig(),archiveAfterMs=resolveArchiveAfterMs(cfg),archiveAtMs=archiveAfterMs?now+archiveAfterMs:void 0,runTimeoutSeconds=params.runTimeoutSeconds??0,waitTimeoutMs=resolveSubagentWaitTimeoutMs(cfg,runTimeoutSeconds),requesterOrigin=normalizeDeliveryContext(params.requesterOrigin);subagentRuns.set(params.runId,{runId:params.runId,childSessionKey:params.childSessionKey,requesterSessionKey:params.requesterSessionKey,requesterOrigin,requesterDisplayKey:params.requesterDisplayKey,task:params.task,cleanup:params.cleanup,expectsCompletionMessage:params.expectsCompletionMessage,label:params.label,model:params.model,runTimeoutSeconds,createdAt:now,startedAt:now,archiveAtMs,cleanupHandled:!1}),ensureListener(),persistSubagentRuns(),archiveAfterMs&&startSweeper(),waitForSubagentCompletion(params.runId,waitTimeoutMs)}async function waitForSubagentCompletion(runId,waitTimeoutMs){try{let timeoutMs=Math.max(1,Math.floor(waitTimeoutMs)),wait=await callGateway({method:`agent.wait`,params:{runId,timeoutMs},timeoutMs:timeoutMs+1e4});if(wait?.status!==`ok`&&wait?.status!==`error`&&wait?.status!==`timeout`)return;let entry=subagentRuns.get(runId);if(!entry)return;let mutated=!1;typeof wait.startedAt==`number`&&(entry.startedAt=wait.startedAt,mutated=!0),typeof wait.endedAt==`number`&&(entry.endedAt=wait.endedAt,mutated=!0),entry.endedAt||(entry.endedAt=Date.now(),mutated=!0);let waitError=typeof wait.error==`string`?wait.error:void 0;if(entry.outcome=wait.status===`error`?{status:`error`,error:waitError}:wait.status===`timeout`?{status:`timeout`}:{status:`ok`},mutated=!0,mutated&&persistSubagentRuns(),suppressAnnounceForSteerRestart(entry)||!startSubagentAnnounceCleanupFlow(runId,entry))return}catch(err){let message=`failed to wait for subagent completion: ${String(err)}`;defaultRuntime.error(message)}}async function findRunIdsByChildSessionKey(childSessionKey){let key=childSessionKey.trim();if(!key)return[];let runIds=[],snapshot=await getRunsSnapshotForRead();for(let entry of snapshot.values())entry.childSessionKey===key&&runIds.push(entry.runId);return runIds}async function getRunsSnapshotForRead(){let merged=new Map;if(!process.env.VITEST)try{let restored=await loadSubagentRegistryFromDisk();for(let[runId,entry]of restored.entries())merged.set(runId,entry)}catch(err){let message=`failed to load subagent registry from disk: ${String(err)}`;defaultRuntime.error(message)}for(let[runId,entry]of subagentRuns.entries())merged.set(runId,entry);return merged}async function resolveRequesterForChildSession(childSessionKey){let key=childSessionKey.trim();if(!key)return null;let best;for(let entry of(await getRunsSnapshotForRead()).values())entry.childSessionKey===key&&(!best||entry.createdAt>best.createdAt)&&(best=entry);return best?{requesterSessionKey:best.requesterSessionKey,requesterOrigin:normalizeDeliveryContext(best.requesterOrigin)}:null}async function isSubagentSessionRunActive(childSessionKey){let runIds=await findRunIdsByChildSessionKey(childSessionKey);for(let runId of runIds){let entry=subagentRuns.get(runId);if(entry&&typeof entry.endedAt!=`number`)return!0}return!1}async function markSubagentRunTerminated(params){let runIds=new Set;if(typeof params.runId==`string`&&params.runId.trim()&&runIds.add(params.runId.trim()),typeof params.childSessionKey==`string`&&params.childSessionKey.trim())for(let runId of await findRunIdsByChildSessionKey(params.childSessionKey))runIds.add(runId);if(runIds.size===0)return 0;let now=Date.now(),reason=params.reason?.trim()||`killed`,updated=0;for(let runId of runIds){let entry=subagentRuns.get(runId);entry&&typeof entry.endedAt!=`number`&&(entry.endedAt=now,entry.outcome={status:`error`,error:reason},entry.cleanupHandled=!0,entry.cleanupCompletedAt=now,entry.suppressAnnounceReason=`killed`,updated+=1)}return updated>0&&persistSubagentRuns(),updated}function listSubagentRunsForRequester(requesterSessionKey){let key=requesterSessionKey.trim();return key?[...subagentRuns.values()].filter(entry=>entry.requesterSessionKey===key):[]}async function countActiveRunsForSession(requesterSessionKey){let key=requesterSessionKey.trim();if(!key)return 0;let count=0;for(let entry of(await getRunsSnapshotForRead()).values())entry.requesterSessionKey===key&&typeof entry.endedAt!=`number`&&(count+=1);return count}async function countActiveDescendantRuns(rootSessionKey){let root=rootSessionKey.trim();if(!root)return 0;let runs=await getRunsSnapshotForRead(),pending=[root],visited=new Set([root]),count=0;for(;pending.length>0;){let requester=pending.shift();if(requester)for(let entry of runs.values()){if(entry.requesterSessionKey!==requester)continue;typeof entry.endedAt!=`number`&&(count+=1);let childKey=entry.childSessionKey.trim();!childKey||visited.has(childKey)||(visited.add(childKey),pending.push(childKey))}}return count}async function listDescendantRunsForRequester(rootSessionKey){let root=rootSessionKey.trim();if(!root)return[];let runs=await getRunsSnapshotForRead(),pending=[root],visited=new Set([root]),descendants=[];for(;pending.length>0;){let requester=pending.shift();if(requester)for(let entry of runs.values()){if(entry.requesterSessionKey!==requester)continue;descendants.push(entry);let childKey=entry.childSessionKey.trim();!childKey||visited.has(childKey)||(visited.add(childKey),pending.push(childKey))}}return descendants}function initSubagentRegistry(){return restoreSubagentRunsOnce()}export{resolveAnnounceTargetFromKey as $,formatInboundEnvelope as $n,setCommandLaneConcurrency as $r,parseActivationCommand as $t,sleepWithAbort as A,maskApiKey as An,registerTeamMemoryContextBuilder as Ar,persistBrowserProxyFiles as At,createReplyDispatcher as B,peekSystemEvents as Bn,setTtsProvider as Br,dispatchToRemoteAgentNode as Bt,createPluginLoaderLogger as C,verifyPairingToken as Cn,resolveUserTimezone as Cr,CHANNEL_TARGETS_DESCRIPTION as Ct,readJsonBodyWithLimit as D,readJsonFile as Dn,getSsmMemoryService as Dr,getHookType as Dt,handleSlackHttpRequest as E,createAsyncLock as En,initLimbicSystemService as Er,detectSuspiciousPatterns as Et,recordPendingHistoryEntryIfEnabled as F,applyVerboseOverride as Fn,resolveTtsAutoMode as Fr,gitHistoryTool as Ft,appendCronStyleCurrentTimeLine as G,extractFileContentFromSource as Gn,antigravityForwardCompatCandidates as Gr,spawnSubagentDirect as Gt,createDedupeCache as H,DEFAULT_INPUT_IMAGE_MIMES as Hn,OPENAI_TTS_MODELS as Hr,loadHiredAgentsCached as Ht,shouldAckReactionForWhatsApp as I,parseVerboseOverride as In,resolveTtsConfig as Ir,workflowStatusTool as It,setCliSessionId as J,resolveInputFileLimits as Jn,describeFailoverError as Jr,getBuiltInAgentRoles as Jt,resolveCronStyleNow as K,extractImageContentFromSource as Kn,resolveForwardCompatModel as Kr,resolveRelayTaskModel as Kt,dispatchReplyWithBufferedBlockDispatcher as L,enqueueSystemEvent as Ln,resolveTtsPrefsPath as Lr,globalOrchestrator as Lt,resolveMentionGating as M,buildAuthHealthSummary as Mn,isTtsEnabled as Mr,resolveApproval as Mt,DEFAULT_GROUP_HISTORY_LIMIT as N,formatRemainingShort as Nn,isTtsProviderConfigured as Nr,semanticSearchTool as Nt,requestBodyErrorToText as O,writeJsonAtomic as On,initSsmMemoryService as Or,isExternalHookSession as Ot,buildHistoryContextFromEntries as P,applyModelOverrideToSessionEntry as Pn,resolveTtsApiKey as Pr,agentFleetTool as Pt,readLatestAssistantReply as Q,resolveInboundDebounceMs as Qn,resetAllLanes as Qr,normalizeGroupActivation as Qt,dispatchReplyWithDispatcher as R,isSystemEventContextChanged as Rn,resolveTtsProviderOrder as Rr,dispatchChunkToRemoteAgentNode as Rt,getPluginToolMeta as S,generatePairingToken as Sn,writeRestartSentinel as Sr,stripLegacyDeliveryFields as St,deleteTelegramUpdateOffset as T,resolvePairingPaths as Tn,getLimbicSystemService as Tr,buildSafeExternalPrompt as Tt,getReplyFromConfig as U,DEFAULT_INPUT_MAX_REDIRECTS as Un,OPENAI_TTS_VOICES as Ur,projectKnowledgeTool as Ut,getTotalPendingReplies as V,DEFAULT_INPUT_IMAGE_MAX_BYTES as Vn,textToSpeech as Vr,fetchFleetEntries as Vt,BARE_SESSION_RESET_PROMPT as W,DEFAULT_INPUT_TIMEOUT_MS as Wn,resolveModel as Wr,codebaseSearchTool as Wt,sha256HexPrefix as X,resolveAgentTimeoutMs as Xn,getQueueSize as Xr,AGENT_LANE_NESTED as Xt,runCliAgent as Y,estimateBase64DecodedBytes as Yn,getActiveTaskCount as Yr,registerPlatformPersonasAsRoles as Yt,createBuilderForceAgentsTools as Z,createInboundDebouncer as Zn,getTotalQueueSize as Zr,AGENT_LANE_SUBAGENT as Zt,getActiveEmbeddedRunCount as _,rejectNodePairing as _n,formatDoctorNonInteractiveHint as _r,normalizePayloadToSystemText as _t,isSubagentSessionRunActive as a,formatAllowlistMatchMeta as ai,setHeartbeatWakeHandler as an,stopSubagentsForRequester as ar,resolveOutboundTarget as at,buildDefaultToolPolicyPipelineSteps as b,updatePairedNodeMetadata as bn,summarizeRestartSentinel as br,buildDeliveryFromLegacyPayload as bt,markSubagentRunForSteerRestart as c,isHeartbeatContentEffectivelyEmpty as ci,getRemoteSkillEligibility as cn,consumeGatewaySigusr1RestartAuthorization as cr,resetDirectoryCache as ct,replaceSubagentRunAfterSteer as d,clearAgentRunContext as di,refreshRemoteBinsForConnectedNodes as dn,isGatewaySigusr1RestartExternallyAllowed as dr,normalizeCronJobCreate as dt,waitForActiveTasks as ei,buildChannelSummary as en,resolveEnvelopeFormatOptions as er,runMessageAction as et,resolveRequesterForChildSession as f,emitAgentEvent as fi,refreshRemoteNodeBins as fn,markGatewaySigusr1RestartHandled as fr,normalizeCronJobPatch as ft,abortEmbeddedRun as g,listNodePairing as gn,consumeRestartSentinel as gr,normalizeOptionalText as gt,runEmbeddedAgent as h,registerAgentRunContext as hi,approveNodePairing as hn,setPreRestartDeferralCheck as hr,normalizeOptionalSessionKey as ht,initSubagentRegistry as i,isDiagnosticsEnabled as ii,requestHeartbeatNow as in,isAbortTrigger as ir,resolveHeartbeatSenderContext as it,buildPairingReply as j,DEFAULT_OAUTH_WARN_MS as jn,getTtsProvider as jr,initApprovalGate as jt,computeBackoff as k,clearSessionAuthProfileOverride as kn,registerKnowledgeLoop as kr,applyBrowserProxyPaths as kt,markSubagentRunTerminated as l,resolveHeartbeatPrompt as li,primeRemoteSkillsCache as ln,deferGatewayRestartUntilIdle as lr,CHANNEL_MESSAGE_ACTION_NAMES as lt,clearSessionQueues as m,onAgentEvent as mi,setSkillsRemoteRegistry as mn,setGatewaySigusr1RestartPolicy as mr,normalizeOptionalAgentId as mt,countActiveDescendantRuns as n,startDiagnosticHeartbeat as ni,formatChannelAllowFrom as nn,hasControlCommand as nr,resolveOutboundSessionRoute as nt,listDescendantRunsForRequester as o,DEFAULT_HEARTBEAT_ACK_MAX_CHARS as oi,normalizeSendPolicy as on,buildMentionRegexes as or,resolveSessionDeliveryTarget as ot,runSubagentAnnounceFlow as p,getAgentRunContext as pi,removeRemoteNodeInfo as pn,scheduleGatewaySigusr1Restart as pr,inferLegacyName as pt,getCliSessionId as q,normalizeMimeList as qn,runWithModelFallback as qr,findAgentRole as qt,countActiveRunsForSession as r,stopDiagnosticHeartbeat as ri,resolveCommitHash as rn,shouldComputeCommandAuthorized as rr,resolveHeartbeatDeliveryTarget as rt,listSubagentRunsForRequester as s,DEFAULT_HEARTBEAT_EVERY as si,resolveSendPolicy as sn,normalizeMentionText as sr,formatTargetDisplay as st,clearSubagentRunSteerRestart as t,CommandLane as ti,buildChannelAccountSnapshot as tn,formatZonedTimestamp as tr,ensureOutboundSessionEntry as tt,registerSubagentRun as u,stripHeartbeatToken as ui,recordRemoteNodeInfo as un,emitGatewayRestart as ur,normalizeHttpWebhookUrl as ut,waitForEmbeddedRunEnd as v,renamePairedNode as vn,formatRestartSentinelMessage as vr,normalizeRequiredName as vt,loadBuilderForceAgentsPlugins as w,pruneExpiredPending as wn,buildAssignedCapabilityAppend as wr,CHANNEL_TARGET_DESCRIPTION as wt,sniffMimeFromBase64 as x,verifyNodeToken as xn,trimLogTail as xr,hasLegacyDeliveryHints as xt,applyToolPolicyPipeline as y,requestNodePairing as yn,readRestartSentinel as yr,migrateLegacyCronPayload as yt,dispatchInboundMessage as z,peekSystemEventEntries as zn,setTtsEnabled as zr,dispatchResultToRemoteAgentNode as zt};