@xopcai/xopc 0.0.109 → 0.0.111

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 (346) hide show
  1. package/README.md +46 -4
  2. package/README.zh-CN.md +46 -4
  3. package/dist/browser-ext/manifest.json +1 -1
  4. package/dist/extensions/feishu/src/pairing-config-resolver.d.ts +1 -0
  5. package/dist/extensions/feishu/src/pairing-config-resolver.js +30 -0
  6. package/dist/extensions/feishu/src/pairing-config-resolver.js.map +1 -0
  7. package/dist/extensions/feishu/src/plugin.d.ts +1 -0
  8. package/dist/extensions/feishu/src/plugin.js +1 -0
  9. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  10. package/dist/extensions/telegram/src/access-control.d.ts +2 -1
  11. package/dist/extensions/telegram/src/access-control.js.map +1 -1
  12. package/dist/extensions/telegram/src/account-manager.d.ts +2 -1
  13. package/dist/extensions/telegram/src/account-manager.js.map +1 -1
  14. package/dist/extensions/telegram/src/adapters/gateway-setup.js +26 -26
  15. package/dist/extensions/telegram/src/adapters/gateway-setup.js.map +1 -1
  16. package/dist/extensions/telegram/src/adapters/onboard-cli.js +8 -4
  17. package/dist/extensions/telegram/src/adapters/onboard-cli.js.map +1 -1
  18. package/dist/extensions/telegram/src/config-schema.d.ts +88 -50
  19. package/dist/extensions/telegram/src/config-schema.js +40 -32
  20. package/dist/extensions/telegram/src/config-schema.js.map +1 -1
  21. package/dist/extensions/telegram/src/config-types.d.ts +54 -0
  22. package/dist/extensions/telegram/src/config-types.js +1 -0
  23. package/dist/extensions/telegram/src/doctor.js +17 -16
  24. package/dist/extensions/telegram/src/doctor.js.map +1 -1
  25. package/dist/extensions/telegram/src/exec-approvals.js +2 -3
  26. package/dist/extensions/telegram/src/exec-approvals.js.map +1 -1
  27. package/dist/extensions/telegram/src/group-config-resolver.d.ts +1 -1
  28. package/dist/extensions/telegram/src/group-config-resolver.js.map +1 -1
  29. package/dist/extensions/telegram/src/pairing-config-resolver.d.ts +1 -0
  30. package/dist/extensions/telegram/src/pairing-config-resolver.js +56 -0
  31. package/dist/extensions/telegram/src/pairing-config-resolver.js.map +1 -0
  32. package/dist/extensions/telegram/src/plugin.d.ts +1 -0
  33. package/dist/extensions/telegram/src/plugin.js +8 -9
  34. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  35. package/dist/extensions/telegram/xopc.extension.json +156 -122
  36. package/dist/extensions/weixin/src/pairing-config-resolver.d.ts +1 -0
  37. package/dist/extensions/weixin/src/pairing-config-resolver.js +54 -0
  38. package/dist/extensions/weixin/src/pairing-config-resolver.js.map +1 -0
  39. package/dist/extensions/weixin/src/plugin.d.ts +1 -0
  40. package/dist/extensions/weixin/src/plugin.js +1 -0
  41. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  42. package/dist/gateway/static/root/assets/Combination-BzaXOLd9.js +41 -0
  43. package/dist/gateway/static/root/assets/agent-avatar-dicebear-zlx9l5Yp.js +1 -0
  44. package/dist/gateway/static/root/assets/agent-browser-settings-page-B-0zGjt8.js +6 -0
  45. package/dist/gateway/static/root/assets/agent-defaults-tabbed-page-Bz7JWjRM.js +1 -0
  46. package/dist/gateway/static/root/assets/agents-DwDnJlXT.js +71 -0
  47. package/dist/gateway/static/root/assets/app-management-settings-panel-DaQwdeCq.js +1 -0
  48. package/dist/gateway/static/root/assets/appearance-settings-D2zv6r3P.js +1 -0
  49. package/dist/gateway/static/root/assets/apps-page-BIppe_jj.js +1 -0
  50. package/dist/gateway/static/root/assets/archive-plugin-DEmu8eH7.js +1 -0
  51. package/dist/gateway/static/root/assets/attachment-load-B98lJoN5.js +2 -0
  52. package/dist/gateway/static/root/assets/{attachment-preview-renderer-CybMSIoS.js → attachment-preview-renderer-DonnL2dL.js} +1 -1
  53. package/dist/gateway/static/root/assets/binary-plugins-CL9QKmyo.js +2 -0
  54. package/dist/gateway/static/root/assets/block-editor-BOAhMAhT.js +180 -0
  55. package/dist/gateway/static/root/assets/channels-settings-Br8iRnXp.js +1 -0
  56. package/dist/gateway/static/root/assets/cn-JdwAhgNB.js +1 -0
  57. package/dist/gateway/static/root/assets/code-editor-dZTY2dRW.js +1 -0
  58. package/dist/gateway/static/root/assets/config-api-0o1WYdz2.js +3 -0
  59. package/dist/gateway/static/root/assets/connectors-settings-DDvHo9in.js +2 -0
  60. package/dist/gateway/static/root/assets/cron-api-Dj_UZKST.js +1 -0
  61. package/dist/gateway/static/root/assets/cron-dreaming-jobs-nCMWCf0p.js +1 -0
  62. package/dist/gateway/static/root/assets/cron-page-Dv7GII9G.js +1 -0
  63. package/dist/gateway/static/root/assets/cron-schedule-picker-DH10KgD6.js +1 -0
  64. package/dist/gateway/static/root/assets/dist-By6Rh2ee.js +1 -0
  65. package/dist/gateway/static/root/assets/dist-CkobR7mk.js +1 -0
  66. package/dist/gateway/static/root/assets/dist-DokQNVMQ.js +1 -0
  67. package/dist/gateway/static/root/assets/dreaming-scene-BHMRVEUS.js +4585 -0
  68. package/dist/gateway/static/root/assets/dreaming-settings-L2rgZDQl.js +1 -0
  69. package/dist/gateway/static/root/assets/extension-debug-page-Cjx6pZVz.js +1 -0
  70. package/dist/gateway/static/root/assets/{extension-page-DNcTendk.js → extension-page-BSPNL90V.js} +1 -1
  71. package/dist/gateway/static/root/assets/extension-settings-page-m_UQYkVc.js +1 -0
  72. package/dist/gateway/static/root/assets/fetch-Bs7in_4F.js +1 -0
  73. package/dist/gateway/static/root/assets/format-interval-label-CftJ5uXu.js +1 -0
  74. package/dist/gateway/static/root/assets/gateway-config-api-Clfck-hW.js +1 -0
  75. package/dist/gateway/static/root/assets/gateway-settings-CS177xni.js +1 -0
  76. package/dist/gateway/static/root/assets/gateway-startup-retry-BkjVJc38.js +1 -0
  77. package/dist/gateway/static/root/assets/goal-detail-page-kqJue0sE.js +1 -0
  78. package/dist/gateway/static/root/assets/goals-page-C0FujUB5.js +2 -0
  79. package/dist/gateway/static/root/assets/goals-settings-CJnzNSDo.js +1 -0
  80. package/dist/gateway/static/root/assets/heartbeat-config-api-Cp7CPuIn.js +1 -0
  81. package/dist/gateway/static/root/assets/heartbeat-settings-ifSI1Wbh.js +1 -0
  82. package/dist/gateway/static/root/assets/html-workspace-editor-CQLWDiwE.js +1 -0
  83. package/dist/gateway/static/root/assets/index-COkF54xv.js +121 -0
  84. package/dist/gateway/static/root/assets/index-DIaSNGEO.css +1 -0
  85. package/dist/gateway/static/root/assets/interval-presets-B29Ss_2y.js +2 -0
  86. package/dist/gateway/static/root/assets/keyboard-shortcuts-settings--MI1rYl7.js +1 -0
  87. package/dist/gateway/static/root/assets/locale-store-DjbfSsfA.js +1 -0
  88. package/dist/gateway/static/root/assets/logs-page-BwrVNlyW.js +2 -0
  89. package/dist/gateway/static/root/assets/markdown-editor-AssmZFx4.js +2 -0
  90. package/dist/gateway/static/root/assets/markdown-split-B_oc9lJe.js +1 -0
  91. package/dist/gateway/static/root/assets/media-plugins-DLPvB5H3.js +1 -0
  92. package/dist/gateway/static/root/assets/mermaid-render-BbqDc_LQ.js +134 -0
  93. package/dist/gateway/static/root/assets/messages-Csef1aW7.js +3 -0
  94. package/dist/gateway/static/root/assets/middleware-Pd0e8Igk.js +1 -0
  95. package/dist/gateway/static/root/assets/models-hub-panel-DHGiTIvf.js +2 -0
  96. package/dist/gateway/static/root/assets/note-detail-page-BM7zlDiT.js +2 -0
  97. package/dist/gateway/static/root/assets/note-image-lightbox-rSqAgOi9.js +1 -0
  98. package/dist/gateway/static/root/assets/note-time-hm6JO_Wi.js +1 -0
  99. package/dist/gateway/static/root/assets/notes-page-C9ACGEty.js +1 -0
  100. package/dist/gateway/static/root/assets/preview-open-alternatives-Bw_N2oZi.js +1 -0
  101. package/dist/gateway/static/root/assets/remote-access-hub-BhcWIKuM.js +1 -0
  102. package/dist/gateway/static/root/assets/save-bar-controls-CNP2jmw0.js +1 -0
  103. package/dist/gateway/static/root/assets/schedule-field-BPAWui3P.js +1 -0
  104. package/dist/gateway/static/root/assets/schedule-summary-B-hdSRdR.js +1 -0
  105. package/dist/gateway/static/root/assets/schema-form-CDPzua9q.js +1 -0
  106. package/dist/gateway/static/root/assets/sessions-page-DzkpSDZr.js +1 -0
  107. package/dist/gateway/static/root/assets/settings-advanced-gate-BYS-rpzn.js +1 -0
  108. package/dist/gateway/static/root/assets/settings-collapsible-section-C9bff85B.js +1 -0
  109. package/dist/gateway/static/root/assets/settings-form-section-BsrK7TBF.js +1 -0
  110. package/dist/gateway/static/root/assets/settings-page-DWK4Zo7s.js +1 -0
  111. package/dist/gateway/static/root/assets/setup-status-panel-DJiksNu4.js +1 -0
  112. package/dist/gateway/static/root/assets/share-preview-page-DnutoY_S.js +2 -0
  113. package/dist/gateway/static/root/assets/shares-settings-6oRgJMpn.js +1 -0
  114. package/dist/gateway/static/root/assets/skill-reload-api-CU9i0nJV.js +1 -0
  115. package/dist/gateway/static/root/assets/skills-page-ERbdWENm.js +2 -0
  116. package/dist/gateway/static/root/assets/system-settings-panel-qP1JDtDd.js +1 -0
  117. package/dist/gateway/static/root/assets/theme-store-CD2wtgZV.js +1 -0
  118. package/dist/gateway/static/root/assets/use-agent-defaults-form-D3FGVLZb.js +1 -0
  119. package/dist/gateway/static/root/assets/use-blob-object-url-D4BFuzZB.js +1 -0
  120. package/dist/gateway/static/root/assets/use-channel-catalog-C4mg1hjD.js +1 -0
  121. package/dist/gateway/static/root/assets/use-settings-tab-guard-F6C0mpJt.js +1 -0
  122. package/dist/gateway/static/root/assets/vendor-codemirror-CNP1wPe7.js +45 -0
  123. package/dist/gateway/static/root/assets/voice-api-key-field-BnDDb6qO.js +1 -0
  124. package/dist/gateway/static/root/assets/voice-player-store-B2EwIhtY.js +1 -0
  125. package/dist/gateway/static/root/assets/{workflow-page.utils-BcZQmKBX.js → workflow-page.utils-CRB7WX9l.js} +1 -1
  126. package/dist/gateway/static/root/assets/workflows-page-2Fptr0je.js +18 -0
  127. package/dist/gateway/static/root/index.html +12 -10
  128. package/dist/package.js +1 -1
  129. package/dist/src/agent/goals/checklist-judge.d.ts +5 -0
  130. package/dist/src/agent/goals/checklist-judge.js +26 -2
  131. package/dist/src/agent/goals/checklist-judge.js.map +1 -1
  132. package/dist/src/agent/goals/evaluate-turn.d.ts +5 -1
  133. package/dist/src/agent/goals/evaluate-turn.js +29 -3
  134. package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
  135. package/dist/src/agent/goals/goal-locale.d.ts +0 -2
  136. package/dist/src/agent/goals/goal-locale.js +2 -15
  137. package/dist/src/agent/goals/goal-locale.js.map +1 -1
  138. package/dist/src/agent/goals/persistent-goal-service.d.ts +9 -0
  139. package/dist/src/agent/goals/persistent-goal-service.js +2 -1
  140. package/dist/src/agent/goals/persistent-goal-service.js.map +1 -1
  141. package/dist/src/agent/goals/post-turn.d.ts +7 -0
  142. package/dist/src/agent/goals/post-turn.js +68 -23
  143. package/dist/src/agent/goals/post-turn.js.map +1 -1
  144. package/dist/src/agent/goals/state.d.ts +0 -5
  145. package/dist/src/agent/goals/state.js +1 -96
  146. package/dist/src/agent/goals/state.js.map +1 -1
  147. package/dist/src/agent/messaging/command-handler.d.ts +4 -0
  148. package/dist/src/agent/messaging/command-handler.js +6 -2
  149. package/dist/src/agent/messaging/command-handler.js.map +1 -1
  150. package/dist/src/agent/service/direct-turn-helpers.d.ts +2 -0
  151. package/dist/src/agent/service/direct-turn-helpers.js +3 -2
  152. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  153. package/dist/src/agent/service/process-direct-streaming.js +10 -1
  154. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  155. package/dist/src/agent/service.js +20 -1
  156. package/dist/src/agent/service.js.map +1 -1
  157. package/dist/src/agent/service.types.d.ts +8 -0
  158. package/dist/src/agent/tools/cronjob-tool.d.ts +2 -0
  159. package/dist/src/agent/tools/cronjob-tool.js +27 -4
  160. package/dist/src/agent/tools/cronjob-tool.js.map +1 -1
  161. package/dist/src/agent/tools/edit.d.ts +2 -0
  162. package/dist/src/agent/tools/edit.js +10 -0
  163. package/dist/src/agent/tools/edit.js.map +1 -1
  164. package/dist/src/agent/tools/factory.js +16 -3
  165. package/dist/src/agent/tools/factory.js.map +1 -1
  166. package/dist/src/agent/tools/goal-evidence-recorder.d.ts +6 -0
  167. package/dist/src/agent/tools/goal-evidence-recorder.js +34 -0
  168. package/dist/src/agent/tools/goal-evidence-recorder.js.map +1 -0
  169. package/dist/src/agent/tools/goal-tool.d.ts +19 -0
  170. package/dist/src/agent/tools/goal-tool.js +101 -0
  171. package/dist/src/agent/tools/goal-tool.js.map +1 -0
  172. package/dist/src/agent/tools/index.d.ts +1 -0
  173. package/dist/src/agent/tools/index.js +2 -1
  174. package/dist/src/agent/tools/shell.d.ts +2 -0
  175. package/dist/src/agent/tools/shell.js +17 -2
  176. package/dist/src/agent/tools/shell.js.map +1 -1
  177. package/dist/src/agent/tools/workflow-tool.d.ts +1 -0
  178. package/dist/src/agent/tools/workflow-tool.js +10 -2
  179. package/dist/src/agent/tools/workflow-tool.js.map +1 -1
  180. package/dist/src/agent/tools/write.d.ts +2 -0
  181. package/dist/src/agent/tools/write.js +11 -0
  182. package/dist/src/agent/tools/write.js.map +1 -1
  183. package/dist/src/channels/attachments/inbound-persist.d.ts +7 -0
  184. package/dist/src/channels/attachments/inbound-persist.js +20 -2
  185. package/dist/src/channels/attachments/inbound-persist.js.map +1 -1
  186. package/dist/src/channels/channel-domain.d.ts +1 -81
  187. package/dist/src/channels/pairing/index.d.ts +2 -2
  188. package/dist/src/channels/pairing/index.js +2 -2
  189. package/dist/src/channels/pairing/pairing-service.d.ts +13 -0
  190. package/dist/src/channels/pairing/pairing-service.js +78 -63
  191. package/dist/src/channels/pairing/pairing-service.js.map +1 -1
  192. package/dist/src/chat-commands/builtins/config.js +4 -11
  193. package/dist/src/chat-commands/builtins/config.js.map +1 -1
  194. package/dist/src/chat-commands/builtins/goal.d.ts +1 -1
  195. package/dist/src/chat-commands/builtins/goal.js +55 -97
  196. package/dist/src/chat-commands/builtins/goal.js.map +1 -1
  197. package/dist/src/chat-commands/builtins/subgoal.d.ts +1 -1
  198. package/dist/src/chat-commands/builtins/subgoal.js +49 -108
  199. package/dist/src/chat-commands/builtins/subgoal.js.map +1 -1
  200. package/dist/src/chat-commands/builtins/workflow.js +132 -8
  201. package/dist/src/chat-commands/builtins/workflow.js.map +1 -1
  202. package/dist/src/chat-commands/context.d.ts +3 -0
  203. package/dist/src/chat-commands/context.js +5 -0
  204. package/dist/src/chat-commands/context.js.map +1 -1
  205. package/dist/src/chat-commands/types.d.ts +5 -0
  206. package/dist/src/cli/command-catalog.js +43 -0
  207. package/dist/src/cli/command-catalog.js.map +1 -1
  208. package/dist/src/cli/command-loaders.js +1 -0
  209. package/dist/src/cli/command-loaders.js.map +1 -1
  210. package/dist/src/cli/command-manifest.js +4 -0
  211. package/dist/src/cli/command-manifest.js.map +1 -1
  212. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  213. package/dist/src/cli/commands/goal.d.ts +4 -0
  214. package/dist/src/cli/commands/goal.js +213 -0
  215. package/dist/src/cli/commands/goal.js.map +1 -0
  216. package/dist/src/cli/commands/onboard.js +11 -5
  217. package/dist/src/cli/commands/onboard.js.map +1 -1
  218. package/dist/src/config/index.js +2 -2
  219. package/dist/src/config/schema.d.ts +115 -0
  220. package/dist/src/config/schema.js +72 -18
  221. package/dist/src/config/schema.js.map +1 -1
  222. package/dist/src/config/web-patch.d.ts +14 -0
  223. package/dist/src/config/web-patch.js +45 -6
  224. package/dist/src/config/web-patch.js.map +1 -1
  225. package/dist/src/cron/executor.d.ts +2 -0
  226. package/dist/src/cron/executor.js +25 -0
  227. package/dist/src/cron/executor.js.map +1 -1
  228. package/dist/src/cron/job-content.js +1 -0
  229. package/dist/src/cron/job-content.js.map +1 -1
  230. package/dist/src/cron/types.d.ts +19 -1
  231. package/dist/src/cron/validation.d.ts +20 -0
  232. package/dist/src/cron/validation.js +7 -0
  233. package/dist/src/cron/validation.js.map +1 -1
  234. package/dist/src/gateway/hono/lib/config-payload.d.ts +14 -0
  235. package/dist/src/gateway/hono/routes/goals.d.ts +1 -1
  236. package/dist/src/gateway/hono/routes/goals.js +670 -173
  237. package/dist/src/gateway/hono/routes/goals.js.map +1 -1
  238. package/dist/src/gateway/hono/routes/home.d.ts +5 -0
  239. package/dist/src/gateway/hono/routes/home.js +88 -3
  240. package/dist/src/gateway/hono/routes/home.js.map +1 -1
  241. package/dist/src/gateway/hono/routes/notes.js +20 -14
  242. package/dist/src/gateway/hono/routes/notes.js.map +1 -1
  243. package/dist/src/gateway/hono/routes/workflows.js +6 -2
  244. package/dist/src/gateway/hono/routes/workflows.js.map +1 -1
  245. package/dist/src/gateway/hono/sse.js.map +1 -1
  246. package/dist/src/gateway/service/agent-runner.d.ts +2 -0
  247. package/dist/src/gateway/service/agent-runner.js +6 -2
  248. package/dist/src/gateway/service/agent-runner.js.map +1 -1
  249. package/dist/src/gateway/service/run-gateway-agent.d.ts +3 -0
  250. package/dist/src/gateway/service/run-gateway-agent.js.map +1 -1
  251. package/dist/src/gateway/service.d.ts +8 -0
  252. package/dist/src/gateway/service.js +70 -3
  253. package/dist/src/gateway/service.js.map +1 -1
  254. package/dist/src/goals/goal-notifications.d.ts +29 -0
  255. package/dist/src/goals/goal-notifications.js +154 -0
  256. package/dist/src/goals/goal-notifications.js.map +1 -0
  257. package/dist/src/goals/goal-queue-store.d.ts +16 -0
  258. package/dist/src/goals/goal-queue-store.js +131 -0
  259. package/dist/src/goals/goal-queue-store.js.map +1 -0
  260. package/dist/src/goals/goal-queue-types.d.ts +31 -0
  261. package/dist/src/goals/goal-queue-types.js +1 -0
  262. package/dist/src/goals/goal-runner.d.ts +17 -0
  263. package/dist/src/goals/goal-runner.js +127 -0
  264. package/dist/src/goals/goal-runner.js.map +1 -0
  265. package/dist/src/goals/goal-service.d.ts +77 -0
  266. package/dist/src/goals/goal-service.js +261 -0
  267. package/dist/src/goals/goal-service.js.map +1 -0
  268. package/dist/src/goals/goal-store.d.ts +38 -0
  269. package/dist/src/goals/goal-store.js +404 -0
  270. package/dist/src/goals/goal-store.js.map +1 -0
  271. package/dist/src/goals/goal-workflow-judge.d.ts +13 -0
  272. package/dist/src/goals/goal-workflow-judge.js +147 -0
  273. package/dist/src/goals/goal-workflow-judge.js.map +1 -0
  274. package/dist/src/goals/index.d.ts +10 -0
  275. package/dist/src/goals/index.js +7 -0
  276. package/dist/src/goals/types.d.ts +119 -0
  277. package/dist/src/goals/types.js +1 -0
  278. package/dist/src/storage/sqlite/migrations/006_add_goals.sql +108 -0
  279. package/dist/src/storage/sqlite/migrations/007_goal_run_judge_schema.sql +4 -0
  280. package/dist/src/storage/sqlite/migrations/008_goal_queue_workflow_runs.sql +53 -0
  281. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  282. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  283. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -1
  284. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  285. package/dist/src/storage/sqlite/schema.js +1 -1
  286. package/dist/src/storage/sqlite/schema.sql +163 -0
  287. package/dist/src/utils/logger/stats.d.ts +1 -1
  288. package/dist/src/workflows/domain/run.d.ts +1 -0
  289. package/dist/src/workflows/domain/run.js.map +1 -1
  290. package/dist/src/workflows/service/workflow-run-service.d.ts +1 -0
  291. package/dist/src/workflows/service/workflow-run-service.js +5 -1
  292. package/dist/src/workflows/service/workflow-run-service.js.map +1 -1
  293. package/dist/src/workflows/service/workflow-run-service.types.d.ts +1 -0
  294. package/dist/src/workflows/service/workflow-session-bridge.js +7 -0
  295. package/dist/src/workflows/service/workflow-session-bridge.js.map +1 -1
  296. package/dist/src/workflows/store/run-index-store.d.ts +8 -0
  297. package/dist/src/workflows/store/run-index-store.js +58 -0
  298. package/dist/src/workflows/store/run-index-store.js.map +1 -0
  299. package/dist/src/workflows/store/run-store.d.ts +2 -0
  300. package/dist/src/workflows/store/run-store.js +14 -21
  301. package/dist/src/workflows/store/run-store.js.map +1 -1
  302. package/package.json +9 -3
  303. package/dist/gateway/static/root/assets/Combination-HAlzriaz.js +0 -41
  304. package/dist/gateway/static/root/assets/agents-D2VtykeA.js +0 -78
  305. package/dist/gateway/static/root/assets/apps-page-BPQ6ueG-.js +0 -1
  306. package/dist/gateway/static/root/assets/channels-settings-DgZc25cS.js +0 -1
  307. package/dist/gateway/static/root/assets/circle-check-C23XjkUj.js +0 -1
  308. package/dist/gateway/static/root/assets/copy-Dv6d4Dvw.js +0 -1
  309. package/dist/gateway/static/root/assets/cron-page-BQFw5O-8.js +0 -1
  310. package/dist/gateway/static/root/assets/dist-BLMShn4_.js +0 -1
  311. package/dist/gateway/static/root/assets/extension-debug-page-BbQ8uZY_.js +0 -1
  312. package/dist/gateway/static/root/assets/extension-settings-page-ClWJvwHK.js +0 -1
  313. package/dist/gateway/static/root/assets/fetch-CFdKBnE6.js +0 -1
  314. package/dist/gateway/static/root/assets/gateway-startup-retry-DdngdObI.js +0 -1
  315. package/dist/gateway/static/root/assets/heartbeat-config-api-4O1U_Oki.js +0 -1
  316. package/dist/gateway/static/root/assets/index-DI5_GsZt.css +0 -1
  317. package/dist/gateway/static/root/assets/index-S23p3aa0.js +0 -4845
  318. package/dist/gateway/static/root/assets/logs-page-BAIdbvSC.js +0 -2
  319. package/dist/gateway/static/root/assets/note-detail-page-BVDoLwec.js +0 -180
  320. package/dist/gateway/static/root/assets/note-time-COWUfBZO.js +0 -1
  321. package/dist/gateway/static/root/assets/notes-page-CI3aD7Tm.js +0 -1
  322. package/dist/gateway/static/root/assets/schema-form-CDpBshDP.js +0 -1
  323. package/dist/gateway/static/root/assets/sessions-page-DM1S4eso.js +0 -1
  324. package/dist/gateway/static/root/assets/settings-advanced-gate-Bz_nYzvB.js +0 -2
  325. package/dist/gateway/static/root/assets/settings-form-section-BxhPoWWH.js +0 -1
  326. package/dist/gateway/static/root/assets/settings-page-Ch_Sd28M.js +0 -3
  327. package/dist/gateway/static/root/assets/share-preview-page-D6u4llqD.js +0 -2
  328. package/dist/gateway/static/root/assets/skills-page-XMi76Nps.js +0 -2
  329. package/dist/gateway/static/root/assets/theme-store-BZozwAeK.js +0 -1
  330. package/dist/gateway/static/root/assets/url-DQRqHuL-.js +0 -3
  331. package/dist/gateway/static/root/assets/vendor-codemirror-DYoKfS8f.js +0 -45
  332. package/dist/gateway/static/root/assets/voice-api-key-field-CMt5Xc7_.js +0 -1
  333. package/dist/gateway/static/root/assets/workflows-page-CxFbPBed.js +0 -18
  334. package/dist/src/agent/goals/checklist-user.d.ts +0 -24
  335. package/dist/src/agent/goals/checklist-user.js +0 -92
  336. package/dist/src/agent/goals/checklist-user.js.map +0 -1
  337. package/dist/src/agent/goals/goal-run-store.d.ts +0 -19
  338. package/dist/src/agent/goals/goal-run-store.js +0 -138
  339. package/dist/src/agent/goals/goal-run-store.js.map +0 -1
  340. package/dist/src/agent/goals/goal-run-types.d.ts +0 -28
  341. package/dist/src/agent/goals/goal-run-types.js +0 -6
  342. package/dist/src/agent/goals/goal-run-types.js.map +0 -1
  343. package/dist/src/agent/goals/patch-from-user-action.d.ts +0 -20
  344. package/dist/src/agent/goals/patch-from-user-action.js +0 -103
  345. package/dist/src/agent/goals/patch-from-user-action.js.map +0 -1
  346. /package/dist/gateway/static/root/assets/{note-detail-page-D4ZIVQbk.css → block-editor-D4ZIVQbk.css} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","names":[],"sources":["../../../../extensions/telegram/src/doctor.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type { ChannelDoctorCheckResult } from '@xopcai/xopc/channels/plugin-types.js';\nimport { hasTelegramBotEndpointApiRoot, normalizeTelegramApiRoot } from './api-root.js';\nimport { createProxyFetch } from './proxy-fetch.js';\nimport { isTelegramUnauthorizedTokenError } from './startup-errors.js';\nimport { resolveTelegramBotToken } from './token-resolver.js';\n\nconst TELEGRAM_DOCTOR_GETME_TIMEOUT_MS = 10_000;\n\ntype TelegramCfg = {\n enabled?: boolean;\n dmPolicy?: string;\n allowFrom?: Array<string | number>;\n apiRoot?: string;\n proxy?: string;\n accounts?: Record<\n string,\n {\n enabled?: boolean;\n botToken?: string;\n tokenFile?: string;\n apiRoot?: string;\n proxy?: string;\n dmPolicy?: string;\n allowFrom?: Array<string | number>;\n }\n >;\n};\n\nfunction collectTokens(cfg: TelegramCfg): Map<string, string[]> {\n const map = new Map<string, string[]>();\n const accounts = cfg.accounts ?? {};\n for (const [id, acc] of Object.entries(accounts)) {\n const { token } = resolveTelegramBotToken({\n botToken: acc.botToken,\n tokenFile: acc.tokenFile,\n });\n if (!token) continue;\n const list = map.get(token) ?? [];\n list.push(id);\n map.set(token, list);\n }\n return map;\n}\n\nfunction formatGetMeError(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nfunction createTimeoutSignal(timeoutMs: number): { signal: AbortSignal; dispose: () => void } {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(new Error(`Timed out after ${timeoutMs}ms`)), timeoutMs);\n timer.unref?.();\n return {\n signal: controller.signal,\n dispose: () => clearTimeout(timer),\n };\n}\n\nasync function checkGetMe(params: {\n accountId: string;\n token: string;\n apiRoot?: string;\n proxy?: string;\n fetchImpl?: typeof fetch;\n}): Promise<ChannelDoctorCheckResult> {\n const apiRoot = normalizeTelegramApiRoot(params.apiRoot);\n const url = `${apiRoot}/bot${params.token}/getMe`;\n const timeout = createTimeoutSignal(TELEGRAM_DOCTOR_GETME_TIMEOUT_MS);\n const fetchImpl = params.proxy ? createProxyFetch(params.proxy) : (params.fetchImpl ?? fetch);\n\n try {\n const startedAt = Date.now();\n const response = await fetchImpl(url, { signal: timeout.signal });\n const elapsedMs = Date.now() - startedAt;\n const body = (await response.json().catch(() => undefined)) as\n | { ok?: boolean; result?: { username?: string }; description?: string }\n | undefined;\n\n if (response.ok && body?.ok === true) {\n const username = body.result?.username ? ` @${body.result.username}` : '';\n return {\n id: `telegram-account-getme-${params.accountId}`,\n label: `Telegram getMe (${params.accountId})`,\n status: 'pass',\n message: `getMe succeeded${username} in ${elapsedMs}ms.`,\n hints: params.proxy ? [`Using proxy: ${params.proxy}`] : [],\n };\n }\n\n const description = body?.description || `HTTP ${response.status}`;\n return {\n id: `telegram-account-getme-${params.accountId}`,\n label: `Telegram getMe (${params.accountId})`,\n status: isTelegramUnauthorizedTokenError(description) ? 'fail' : 'warn',\n message: `getMe failed: ${description}`,\n hints: isTelegramUnauthorizedTokenError(description)\n ? ['Verify the bot token from @BotFather.']\n : ['Check channels.telegram.apiRoot / account apiRoot and network access.'],\n };\n } catch (err) {\n const message = formatGetMeError(err);\n return {\n id: `telegram-account-getme-${params.accountId}`,\n label: `Telegram getMe (${params.accountId})`,\n status: 'fail',\n message: `getMe network check failed: ${message}`,\n hints: [\n 'Verify this host can reach the Telegram Bot API.',\n 'If your shell uses HTTP(S)_PROXY, also set channels.telegram.proxy because Node fetch does not use env proxy automatically.',\n `Effective apiRoot: ${apiRoot}`,\n ],\n };\n } finally {\n timeout.dispose();\n }\n}\n\nexport async function runTelegramDoctorChecks(params: {\n cfg: Config;\n fetchImpl?: typeof fetch;\n}): Promise<ChannelDoctorCheckResult[]> {\n const results: ChannelDoctorCheckResult[] = [];\n const tg = params.cfg.channels?.telegram as TelegramCfg | undefined;\n if (!tg) {\n return results;\n }\n\n if (tg.enabled && tg.dmPolicy === 'open') {\n const allow = tg.allowFrom ?? [];\n const hasWildcard = allow.some((e) => String(e).trim() === '*');\n results.push({\n id: 'telegram-dm-open-wildcard',\n label: 'Telegram DM open policy',\n status: hasWildcard ? 'pass' : 'warn',\n message: hasWildcard\n ? 'DM policy is open with allowFrom wildcard.'\n : 'dmPolicy \"open\" should include allowFrom: [\"*\"] for explicit opt-in.',\n hints: hasWildcard ? [] : ['Add `\"allowFrom\": [\"*\"]` or switch to pairing/allowlist.'],\n });\n }\n\n if (hasTelegramBotEndpointApiRoot(tg.apiRoot)) {\n results.push({\n id: 'telegram-api-root-bot-endpoint',\n label: 'Telegram apiRoot',\n status: 'warn',\n message: 'apiRoot includes a bot token path segment; it will be normalized to the API root.',\n hints: [`Use \"${normalizeTelegramApiRoot(tg.apiRoot)}\" instead.`],\n });\n }\n\n const tokenMap = collectTokens(tg);\n for (const [token, accountIds] of tokenMap) {\n if (accountIds.length > 1) {\n results.push({\n id: `telegram-duplicate-token-${accountIds.join('-')}`,\n label: 'Telegram duplicate bot token',\n status: 'fail',\n message: `Bot token is shared by accounts: ${accountIds.join(', ')}.`,\n hints: ['Use one token per account or disable duplicate accounts.'],\n });\n }\n void token;\n }\n\n for (const [id, acc] of Object.entries(tg.accounts ?? {})) {\n if (hasTelegramBotEndpointApiRoot(acc.apiRoot)) {\n results.push({\n id: `telegram-account-api-root-${id}`,\n label: `Telegram apiRoot (${id})`,\n status: 'warn',\n message: `Account \"${id}\" apiRoot includes bot endpoint; will be normalized.`,\n hints: [`Use \"${normalizeTelegramApiRoot(acc.apiRoot)}\"`],\n });\n }\n const { token, source } = resolveTelegramBotToken({\n botToken: acc.botToken,\n tokenFile: acc.tokenFile,\n });\n if (tg.enabled && acc && source === 'none' && (acc as { enabled?: boolean }).enabled !== false) {\n results.push({\n id: `telegram-account-token-${id}`,\n label: `Telegram token (${id})`,\n status: 'fail',\n message: `Account \"${id}\" has no bot token or readable tokenFile.`,\n hints: ['Set botToken or tokenFile in channels.telegram.accounts.' + id],\n });\n }\n if (token && token.length < 20) {\n results.push({\n id: `telegram-account-token-short-${id}`,\n label: `Telegram token (${id})`,\n status: 'warn',\n message: `Account \"${id}\" bot token looks too short.`,\n hints: ['Verify the token from @BotFather.'],\n });\n }\n\n if (tg.enabled && token && acc.enabled !== false) {\n results.push(\n await checkGetMe({\n accountId: id,\n token,\n apiRoot: acc.apiRoot || tg.apiRoot,\n proxy: acc.proxy || tg.proxy,\n fetchImpl: params.fetchImpl,\n }),\n );\n }\n }\n\n return results;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"doctor.js","names":[],"sources":["../../../../extensions/telegram/src/doctor.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type { ChannelDoctorCheckResult } from '@xopcai/xopc/channels/plugin-types.js';\nimport { hasTelegramBotEndpointApiRoot, normalizeTelegramApiRoot } from './api-root.js';\nimport { createProxyFetch } from './proxy-fetch.js';\nimport { isTelegramUnauthorizedTokenError } from './startup-errors.js';\nimport { resolveTelegramBotToken } from './token-resolver.js';\n\nconst TELEGRAM_DOCTOR_GETME_TIMEOUT_MS = 10_000;\n\ntype TelegramCfg = {\n enabled?: boolean;\n defaults?: {\n dmPolicy?: string;\n apiRoot?: string;\n proxy?: string;\n };\n accounts?: Record<\n string,\n {\n enabled?: boolean;\n botToken?: string;\n tokenFile?: string;\n apiRoot?: string;\n proxy?: string;\n dmPolicy?: string;\n allowFrom?: Array<string | number>;\n }\n >;\n};\n\nfunction collectTokens(cfg: TelegramCfg): Map<string, string[]> {\n const map = new Map<string, string[]>();\n const accounts = cfg.accounts ?? {};\n for (const [id, acc] of Object.entries(accounts)) {\n const { token } = resolveTelegramBotToken({\n botToken: acc.botToken,\n tokenFile: acc.tokenFile,\n });\n if (!token) continue;\n const list = map.get(token) ?? [];\n list.push(id);\n map.set(token, list);\n }\n return map;\n}\n\nfunction formatGetMeError(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n\nfunction createTimeoutSignal(timeoutMs: number): { signal: AbortSignal; dispose: () => void } {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(new Error(`Timed out after ${timeoutMs}ms`)), timeoutMs);\n timer.unref?.();\n return {\n signal: controller.signal,\n dispose: () => clearTimeout(timer),\n };\n}\n\nasync function checkGetMe(params: {\n accountId: string;\n token: string;\n apiRoot?: string;\n proxy?: string;\n fetchImpl?: typeof fetch;\n}): Promise<ChannelDoctorCheckResult> {\n const apiRoot = normalizeTelegramApiRoot(params.apiRoot);\n const url = `${apiRoot}/bot${params.token}/getMe`;\n const timeout = createTimeoutSignal(TELEGRAM_DOCTOR_GETME_TIMEOUT_MS);\n const fetchImpl = params.proxy ? createProxyFetch(params.proxy) : (params.fetchImpl ?? fetch);\n\n try {\n const startedAt = Date.now();\n const response = await fetchImpl(url, { signal: timeout.signal });\n const elapsedMs = Date.now() - startedAt;\n const body = (await response.json().catch(() => undefined)) as\n | { ok?: boolean; result?: { username?: string }; description?: string }\n | undefined;\n\n if (response.ok && body?.ok === true) {\n const username = body.result?.username ? ` @${body.result.username}` : '';\n return {\n id: `telegram-account-getme-${params.accountId}`,\n label: `Telegram getMe (${params.accountId})`,\n status: 'pass',\n message: `getMe succeeded${username} in ${elapsedMs}ms.`,\n hints: params.proxy ? [`Using proxy: ${params.proxy}`] : [],\n };\n }\n\n const description = body?.description || `HTTP ${response.status}`;\n return {\n id: `telegram-account-getme-${params.accountId}`,\n label: `Telegram getMe (${params.accountId})`,\n status: isTelegramUnauthorizedTokenError(description) ? 'fail' : 'warn',\n message: `getMe failed: ${description}`,\n hints: isTelegramUnauthorizedTokenError(description)\n ? ['Verify the bot token from @BotFather.']\n : ['Check channels.telegram.defaults.apiRoot / account apiRoot and network access.'],\n };\n } catch (err) {\n const message = formatGetMeError(err);\n return {\n id: `telegram-account-getme-${params.accountId}`,\n label: `Telegram getMe (${params.accountId})`,\n status: 'fail',\n message: `getMe network check failed: ${message}`,\n hints: [\n 'Verify this host can reach the Telegram Bot API.',\n 'If your shell uses HTTP(S)_PROXY, also set channels.telegram.defaults.proxy because Node fetch does not use env proxy automatically.',\n `Effective apiRoot: ${apiRoot}`,\n ],\n };\n } finally {\n timeout.dispose();\n }\n}\n\nexport async function runTelegramDoctorChecks(params: {\n cfg: Config;\n fetchImpl?: typeof fetch;\n}): Promise<ChannelDoctorCheckResult[]> {\n const results: ChannelDoctorCheckResult[] = [];\n const tg = params.cfg.channels?.telegram as TelegramCfg | undefined;\n if (!tg) {\n return results;\n }\n\n if (hasTelegramBotEndpointApiRoot(tg.defaults?.apiRoot)) {\n results.push({\n id: 'telegram-api-root-bot-endpoint',\n label: 'Telegram apiRoot',\n status: 'warn',\n message: 'apiRoot includes a bot token path segment; it will be normalized to the API root.',\n hints: [`Use \"${normalizeTelegramApiRoot(tg.defaults?.apiRoot)}\" instead.`],\n });\n }\n\n const tokenMap = collectTokens(tg);\n for (const [token, accountIds] of tokenMap) {\n if (accountIds.length > 1) {\n results.push({\n id: `telegram-duplicate-token-${accountIds.join('-')}`,\n label: 'Telegram duplicate bot token',\n status: 'fail',\n message: `Bot token is shared by accounts: ${accountIds.join(', ')}.`,\n hints: ['Use one token per account or disable duplicate accounts.'],\n });\n }\n void token;\n }\n\n for (const [id, acc] of Object.entries(tg.accounts ?? {})) {\n const effectiveDmPolicy = acc.dmPolicy ?? tg.defaults?.dmPolicy ?? 'pairing';\n if (tg.enabled && effectiveDmPolicy === 'open') {\n const allow = acc.allowFrom ?? [];\n const hasWildcard = allow.some((e) => String(e).trim() === '*');\n results.push({\n id: `telegram-dm-open-wildcard-${id}`,\n label: `Telegram DM open policy (${id})`,\n status: hasWildcard ? 'pass' : 'warn',\n message: hasWildcard\n ? `Account \"${id}\" DM policy is open with allowFrom wildcard.`\n : `Account \"${id}\" dmPolicy \"open\" should include allowFrom: [\"*\"] for explicit opt-in.`,\n hints: hasWildcard ? [] : [`Add \"allowFrom\": [\"*\"] to channels.telegram.accounts.${id} or switch to pairing/allowlist.`],\n });\n }\n if (hasTelegramBotEndpointApiRoot(acc.apiRoot)) {\n results.push({\n id: `telegram-account-api-root-${id}`,\n label: `Telegram apiRoot (${id})`,\n status: 'warn',\n message: `Account \"${id}\" apiRoot includes bot endpoint; will be normalized.`,\n hints: [`Use \"${normalizeTelegramApiRoot(acc.apiRoot)}\"`],\n });\n }\n const { token, source } = resolveTelegramBotToken({\n botToken: acc.botToken,\n tokenFile: acc.tokenFile,\n });\n if (tg.enabled && acc && source === 'none' && (acc as { enabled?: boolean }).enabled !== false) {\n results.push({\n id: `telegram-account-token-${id}`,\n label: `Telegram token (${id})`,\n status: 'fail',\n message: `Account \"${id}\" has no bot token or readable tokenFile.`,\n hints: ['Set botToken or tokenFile in channels.telegram.accounts.' + id],\n });\n }\n if (token && token.length < 20) {\n results.push({\n id: `telegram-account-token-short-${id}`,\n label: `Telegram token (${id})`,\n status: 'warn',\n message: `Account \"${id}\" bot token looks too short.`,\n hints: ['Verify the token from @BotFather.'],\n });\n }\n\n if (tg.enabled && token && acc.enabled !== false) {\n results.push(\n await checkGetMe({\n accountId: id,\n token,\n apiRoot: acc.apiRoot || tg.defaults?.apiRoot,\n proxy: acc.proxy || tg.defaults?.proxy,\n fetchImpl: params.fetchImpl,\n }),\n );\n }\n }\n\n return results;\n}\n"],"mappings":"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"}
@@ -3,10 +3,9 @@ function isTelegramExecApprovalEnabled(cfg, accountId = "default") {
3
3
  return ((cfg.channels?.telegram)?.accounts?.[accountId])?.execApprovals?.enabled === true;
4
4
  }
5
5
  function resolveTelegramExecApprovers(cfg, accountId = "default") {
6
- const tg = cfg.channels?.telegram;
7
- const acc = tg?.accounts?.[accountId];
6
+ const acc = (cfg.channels?.telegram)?.accounts?.[accountId];
8
7
  const explicit = acc?.execApprovals?.approvers ?? [];
9
- const fallback = acc?.allowFrom ?? tg?.allowFrom ?? [];
8
+ const fallback = acc?.allowFrom ?? [];
10
9
  return (explicit.length > 0 ? explicit : fallback).map((v) => String(v).trim()).filter((v) => v && v !== "*" && /^\d+$/.test(v.replace(/^(telegram|tg):/i, ""))).map((v) => v.replace(/^(telegram|tg):/i, ""));
11
10
  }
12
11
  function isTelegramExecApprovalApprover(params) {
@@ -1 +1 @@
1
- {"version":3,"file":"exec-approvals.js","names":[],"sources":["../../../../extensions/telegram/src/exec-approvals.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\n\nexport function isTelegramExecApprovalEnabled(cfg: Config, accountId = 'default'): boolean {\n const tg = cfg.channels?.telegram as\n | { accounts?: Record<string, { execApprovals?: { enabled?: boolean } }> }\n | undefined;\n const acc = tg?.accounts?.[accountId];\n return acc?.execApprovals?.enabled === true;\n}\n\nexport function resolveTelegramExecApprovers(\n cfg: Config,\n accountId = 'default',\n): string[] {\n const tg = cfg.channels?.telegram as\n | {\n allowFrom?: Array<string | number>;\n accounts?: Record<\n string,\n {\n execApprovals?: { approvers?: Array<string | number> };\n allowFrom?: Array<string | number>;\n }\n >;\n }\n | undefined;\n const acc = tg?.accounts?.[accountId];\n const explicit = acc?.execApprovals?.approvers ?? [];\n const fallback = acc?.allowFrom ?? tg?.allowFrom ?? [];\n const merged = explicit.length > 0 ? explicit : fallback;\n return merged\n .map((v) => String(v).trim())\n .filter((v) => v && v !== '*' && /^\\d+$/.test(v.replace(/^(telegram|tg):/i, '')))\n .map((v) => v.replace(/^(telegram|tg):/i, ''));\n}\n\nexport function isTelegramExecApprovalApprover(params: {\n cfg: Config;\n accountId: string;\n senderId: string;\n}): boolean {\n const approvers = resolveTelegramExecApprovers(params.cfg, params.accountId);\n const sid = params.senderId.replace(/^(telegram|tg):/i, '');\n return approvers.includes(sid);\n}\n"],"mappings":";AAEA,SAAgB,8BAA8B,KAAa,YAAY,WAAoB;AAKzF,UAJW,IAAI,UAAU,WAGT,WAAW,aACf,eAAe,YAAY;;AAGzC,SAAgB,6BACd,KACA,YAAY,WACF;CACV,MAAM,KAAK,IAAI,UAAU;CAYzB,MAAM,MAAM,IAAI,WAAW;CAC3B,MAAM,WAAW,KAAK,eAAe,aAAa,EAAE;CACpD,MAAM,WAAW,KAAK,aAAa,IAAI,aAAa,EAAE;AAEtD,SADe,SAAS,SAAS,IAAI,WAAW,UAE7C,KAAK,MAAM,OAAO,EAAE,CAAC,MAAM,CAAC,CAC5B,QAAQ,MAAM,KAAK,MAAM,OAAO,QAAQ,KAAK,EAAE,QAAQ,oBAAoB,GAAG,CAAC,CAAC,CAChF,KAAK,MAAM,EAAE,QAAQ,oBAAoB,GAAG,CAAC;;AAGlD,SAAgB,+BAA+B,QAInC;CACV,MAAM,YAAY,6BAA6B,OAAO,KAAK,OAAO,UAAU;CAC5E,MAAM,MAAM,OAAO,SAAS,QAAQ,oBAAoB,GAAG;AAC3D,QAAO,UAAU,SAAS,IAAI"}
1
+ {"version":3,"file":"exec-approvals.js","names":[],"sources":["../../../../extensions/telegram/src/exec-approvals.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\n\nexport function isTelegramExecApprovalEnabled(cfg: Config, accountId = 'default'): boolean {\n const tg = cfg.channels?.telegram as\n | { accounts?: Record<string, { execApprovals?: { enabled?: boolean } }> }\n | undefined;\n const acc = tg?.accounts?.[accountId];\n return acc?.execApprovals?.enabled === true;\n}\n\nexport function resolveTelegramExecApprovers(\n cfg: Config,\n accountId = 'default',\n): string[] {\n const tg = cfg.channels?.telegram as\n | {\n accounts?: Record<\n string,\n {\n execApprovals?: { approvers?: Array<string | number> };\n allowFrom?: Array<string | number>;\n }\n >;\n }\n | undefined;\n const acc = tg?.accounts?.[accountId];\n const explicit = acc?.execApprovals?.approvers ?? [];\n const fallback = acc?.allowFrom ?? [];\n const merged = explicit.length > 0 ? explicit : fallback;\n return merged\n .map((v) => String(v).trim())\n .filter((v) => v && v !== '*' && /^\\d+$/.test(v.replace(/^(telegram|tg):/i, '')))\n .map((v) => v.replace(/^(telegram|tg):/i, ''));\n}\n\nexport function isTelegramExecApprovalApprover(params: {\n cfg: Config;\n accountId: string;\n senderId: string;\n}): boolean {\n const approvers = resolveTelegramExecApprovers(params.cfg, params.accountId);\n const sid = params.senderId.replace(/^(telegram|tg):/i, '');\n return approvers.includes(sid);\n}\n"],"mappings":";AAEA,SAAgB,8BAA8B,KAAa,YAAY,WAAoB;AAKzF,UAJW,IAAI,UAAU,WAGT,WAAW,aACf,eAAe,YAAY;;AAGzC,SAAgB,6BACd,KACA,YAAY,WACF;CAYV,MAAM,OAXK,IAAI,UAAU,WAWT,WAAW;CAC3B,MAAM,WAAW,KAAK,eAAe,aAAa,EAAE;CACpD,MAAM,WAAW,KAAK,aAAa,EAAE;AAErC,SADe,SAAS,SAAS,IAAI,WAAW,UAE7C,KAAK,MAAM,OAAO,EAAE,CAAC,MAAM,CAAC,CAC5B,QAAQ,MAAM,KAAK,MAAM,OAAO,QAAQ,KAAK,EAAE,QAAQ,oBAAoB,GAAG,CAAC,CAAC,CAChF,KAAK,MAAM,EAAE,QAAQ,oBAAoB,GAAG,CAAC;;AAGlD,SAAgB,+BAA+B,QAInC;CACV,MAAM,YAAY,6BAA6B,OAAO,KAAK,OAAO,UAAU;CAC5E,MAAM,MAAM,OAAO,SAAS,QAAQ,oBAAoB,GAAG;AAC3D,QAAO,UAAU,SAAS,IAAI"}
@@ -1,4 +1,4 @@
1
- import type { TelegramAccountConfig, TelegramGroupConfig, TelegramTopicConfig } from '@xopcai/xopc/channels/channel-domain.js';
1
+ import type { TelegramAccountConfig, TelegramGroupConfig, TelegramTopicConfig } from './config-types.js';
2
2
  export interface ResolvedTelegramGroupContext {
3
3
  groupConfig?: TelegramGroupConfig;
4
4
  topicConfig?: TelegramTopicConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"group-config-resolver.js","names":[],"sources":["../../../../extensions/telegram/src/group-config-resolver.ts"],"sourcesContent":["import type { TelegramAccountConfig, TelegramGroupConfig, TelegramTopicConfig } from '@xopcai/xopc/channels/channel-domain.js';\n\nexport interface ResolvedTelegramGroupContext {\n groupConfig?: TelegramGroupConfig;\n topicConfig?: TelegramTopicConfig;\n systemPrompt?: string;\n agentId?: string;\n}\n\nexport function resolveTelegramGroupContext(params: {\n account: TelegramAccountConfig;\n chatId: string;\n threadId?: string | number;\n}): ResolvedTelegramGroupContext {\n const chatKey = params.chatId;\n const threadKey = params.threadId != null ? String(params.threadId) : undefined;\n const groupConfig = params.account.groups?.[chatKey];\n const topicConfig = threadKey ? groupConfig?.topics?.[threadKey] : undefined;\n\n const systemPrompt = topicConfig?.systemPrompt?.trim() || groupConfig?.systemPrompt?.trim() || undefined;\n const agentId = topicConfig?.agentId?.trim() || groupConfig?.agentId?.trim() || undefined;\n\n return { groupConfig, topicConfig, systemPrompt, agentId };\n}\n"],"mappings":";AASA,SAAgB,4BAA4B,QAIX;CAC/B,MAAM,UAAU,OAAO;CACvB,MAAM,YAAY,OAAO,YAAY,OAAO,OAAO,OAAO,SAAS,GAAG,KAAA;CACtE,MAAM,cAAc,OAAO,QAAQ,SAAS;CAC5C,MAAM,cAAc,YAAY,aAAa,SAAS,aAAa,KAAA;AAKnE,QAAO;EAAE;EAAa;EAAa,cAHd,aAAa,cAAc,MAAM,IAAI,aAAa,cAAc,MAAM,IAAI,KAAA;EAG9C,SAFjC,aAAa,SAAS,MAAM,IAAI,aAAa,SAAS,MAAM,IAAI,KAAA;EAEtB"}
1
+ {"version":3,"file":"group-config-resolver.js","names":[],"sources":["../../../../extensions/telegram/src/group-config-resolver.ts"],"sourcesContent":["import type { TelegramAccountConfig, TelegramGroupConfig, TelegramTopicConfig } from './config-types.js';\n\nexport interface ResolvedTelegramGroupContext {\n groupConfig?: TelegramGroupConfig;\n topicConfig?: TelegramTopicConfig;\n systemPrompt?: string;\n agentId?: string;\n}\n\nexport function resolveTelegramGroupContext(params: {\n account: TelegramAccountConfig;\n chatId: string;\n threadId?: string | number;\n}): ResolvedTelegramGroupContext {\n const chatKey = params.chatId;\n const threadKey = params.threadId != null ? String(params.threadId) : undefined;\n const groupConfig = params.account.groups?.[chatKey];\n const topicConfig = threadKey ? groupConfig?.topics?.[threadKey] : undefined;\n\n const systemPrompt = topicConfig?.systemPrompt?.trim() || groupConfig?.systemPrompt?.trim() || undefined;\n const agentId = topicConfig?.agentId?.trim() || groupConfig?.agentId?.trim() || undefined;\n\n return { groupConfig, topicConfig, systemPrompt, agentId };\n}\n"],"mappings":";AASA,SAAgB,4BAA4B,QAIX;CAC/B,MAAM,UAAU,OAAO;CACvB,MAAM,YAAY,OAAO,YAAY,OAAO,OAAO,OAAO,SAAS,GAAG,KAAA;CACtE,MAAM,cAAc,OAAO,QAAQ,SAAS;CAC5C,MAAM,cAAc,YAAY,aAAa,SAAS,aAAa,KAAA;AAKnE,QAAO;EAAE;EAAa;EAAa,cAHd,aAAa,cAAc,MAAM,IAAI,aAAa,cAAc,MAAM,IAAI,KAAA;EAG9C,SAFjC,aAAa,SAAS,MAAM,IAAI,aAAa,SAAS,MAAM,IAAI,KAAA;EAEtB"}
@@ -0,0 +1 @@
1
+ export declare function registerTelegramPairingResolver(): void;
@@ -0,0 +1,56 @@
1
+ import { resolveDmPolicy } from "../../../src/channels/security.js";
2
+ import { resolveStandardAllowFromPath, resolveStandardPairingPath } from "../../../src/channels/pairing/paths.js";
3
+ import { registerPairingChannelResolver } from "../../../src/channels/pairing/pairing-service.js";
4
+ //#region extensions/telegram/src/pairing-config-resolver.ts
5
+ function telegramBlock(config) {
6
+ const ch = config?.channels?.telegram;
7
+ return ch && typeof ch === "object" && !Array.isArray(ch) ? ch : null;
8
+ }
9
+ function account(block, accountId) {
10
+ const accounts = block?.accounts;
11
+ if (!accounts || typeof accounts !== "object" || Array.isArray(accounts)) return null;
12
+ const acc = accounts[accountId];
13
+ return acc && typeof acc === "object" && !Array.isArray(acc) ? acc : null;
14
+ }
15
+ function registerTelegramPairingResolver() {
16
+ registerPairingChannelResolver("telegram", {
17
+ resolvePaths(accountId) {
18
+ return {
19
+ pairingPath: resolveStandardPairingPath("telegram", accountId),
20
+ allowPath: resolveStandardAllowFromPath("telegram", accountId)
21
+ };
22
+ },
23
+ resolveAllowFromConfig(config, _channel, accountId) {
24
+ const allow = account(telegramBlock(config), accountId)?.allowFrom;
25
+ return Array.isArray(allow) ? [...new Set(allow.map(String).filter(Boolean))] : [];
26
+ },
27
+ resolveChannelEnabled(config) {
28
+ return telegramBlock(config)?.enabled === true;
29
+ },
30
+ resolveAccountEnabled(config, _channel, accountId) {
31
+ const block = telegramBlock(config);
32
+ if (block?.enabled !== true) return false;
33
+ return account(block, accountId)?.enabled !== false;
34
+ },
35
+ resolveDmPolicy(config, _channel, accountId) {
36
+ const block = telegramBlock(config);
37
+ const accPolicy = account(block, accountId)?.dmPolicy;
38
+ if (accPolicy) return resolveDmPolicy(accPolicy, "pairing");
39
+ const defaults = block?.defaults;
40
+ return resolveDmPolicy(defaults && typeof defaults === "object" && !Array.isArray(defaults) ? defaults.dmPolicy : void 0, "pairing");
41
+ },
42
+ resolveAccountIds(config) {
43
+ const accounts = telegramBlock(config)?.accounts;
44
+ if (accounts && typeof accounts === "object" && !Array.isArray(accounts)) {
45
+ const keys = Object.keys(accounts).sort();
46
+ if (keys.length > 0) return keys;
47
+ }
48
+ return ["default"];
49
+ }
50
+ });
51
+ }
52
+ registerTelegramPairingResolver();
53
+ //#endregion
54
+ export { registerTelegramPairingResolver };
55
+
56
+ //# sourceMappingURL=pairing-config-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pairing-config-resolver.js","names":[],"sources":["../../../../extensions/telegram/src/pairing-config-resolver.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/schema.js';\nimport type { DmPolicy } from '@xopcai/xopc/channels/channel-domain.js';\nimport {\n registerPairingChannelResolver,\n resolveStandardAllowFromPath,\n resolveStandardPairingPath,\n} from '@xopcai/xopc/channels/pairing/index.js';\nimport { resolveDmPolicy } from '@xopcai/xopc/channels/security.js';\n\nfunction telegramBlock(config: Config | undefined): Record<string, unknown> | null {\n const ch = config?.channels?.telegram;\n return ch && typeof ch === 'object' && !Array.isArray(ch) ? (ch as Record<string, unknown>) : null;\n}\n\nfunction account(block: Record<string, unknown> | null, accountId: string): Record<string, unknown> | null {\n const accounts = block?.accounts;\n if (!accounts || typeof accounts !== 'object' || Array.isArray(accounts)) return null;\n const acc = (accounts as Record<string, unknown>)[accountId];\n return acc && typeof acc === 'object' && !Array.isArray(acc) ? (acc as Record<string, unknown>) : null;\n}\n\nexport function registerTelegramPairingResolver(): void {\n registerPairingChannelResolver('telegram', {\n resolvePaths(accountId) {\n return {\n pairingPath: resolveStandardPairingPath('telegram', accountId),\n allowPath: resolveStandardAllowFromPath('telegram', accountId),\n };\n },\n resolveAllowFromConfig(config, _channel, accountId) {\n const allow = account(telegramBlock(config), accountId)?.allowFrom;\n return Array.isArray(allow) ? [...new Set(allow.map(String).filter(Boolean))] : [];\n },\n resolveChannelEnabled(config) {\n return telegramBlock(config)?.enabled === true;\n },\n resolveAccountEnabled(config, _channel, accountId) {\n const block = telegramBlock(config);\n if (block?.enabled !== true) return false;\n return account(block, accountId)?.enabled !== false;\n },\n resolveDmPolicy(config, _channel, accountId) {\n const block = telegramBlock(config);\n const accPolicy = account(block, accountId)?.dmPolicy as DmPolicy | undefined;\n if (accPolicy) return resolveDmPolicy(accPolicy, 'pairing');\n const defaults = block?.defaults;\n const defaultPolicy =\n defaults && typeof defaults === 'object' && !Array.isArray(defaults)\n ? (defaults as { dmPolicy?: DmPolicy }).dmPolicy\n : undefined;\n return resolveDmPolicy(defaultPolicy, 'pairing');\n },\n resolveAccountIds(config) {\n const accounts = telegramBlock(config)?.accounts;\n if (accounts && typeof accounts === 'object' && !Array.isArray(accounts)) {\n const keys = Object.keys(accounts as Record<string, unknown>).sort();\n if (keys.length > 0) return keys;\n }\n return ['default'];\n },\n });\n}\n\nregisterTelegramPairingResolver();\n"],"mappings":";;;;AASA,SAAS,cAAc,QAA4D;CACjF,MAAM,KAAK,QAAQ,UAAU;AAC7B,QAAO,MAAM,OAAO,OAAO,YAAY,CAAC,MAAM,QAAQ,GAAG,GAAI,KAAiC;;AAGhG,SAAS,QAAQ,OAAuC,WAAmD;CACzG,MAAM,WAAW,OAAO;AACxB,KAAI,CAAC,YAAY,OAAO,aAAa,YAAY,MAAM,QAAQ,SAAS,CAAE,QAAO;CACjF,MAAM,MAAO,SAAqC;AAClD,QAAO,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAI,MAAkC;;AAGpG,SAAgB,kCAAwC;AACtD,gCAA+B,YAAY;EACzC,aAAa,WAAW;AACtB,UAAO;IACL,aAAa,2BAA2B,YAAY,UAAU;IAC9D,WAAW,6BAA6B,YAAY,UAAU;IAC/D;;EAEH,uBAAuB,QAAQ,UAAU,WAAW;GAClD,MAAM,QAAQ,QAAQ,cAAc,OAAO,EAAE,UAAU,EAAE;AACzD,UAAO,MAAM,QAAQ,MAAM,GAAG,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,OAAO,CAAC,OAAO,QAAQ,CAAC,CAAC,GAAG,EAAE;;EAEpF,sBAAsB,QAAQ;AAC5B,UAAO,cAAc,OAAO,EAAE,YAAY;;EAE5C,sBAAsB,QAAQ,UAAU,WAAW;GACjD,MAAM,QAAQ,cAAc,OAAO;AACnC,OAAI,OAAO,YAAY,KAAM,QAAO;AACpC,UAAO,QAAQ,OAAO,UAAU,EAAE,YAAY;;EAEhD,gBAAgB,QAAQ,UAAU,WAAW;GAC3C,MAAM,QAAQ,cAAc,OAAO;GACnC,MAAM,YAAY,QAAQ,OAAO,UAAU,EAAE;AAC7C,OAAI,UAAW,QAAO,gBAAgB,WAAW,UAAU;GAC3D,MAAM,WAAW,OAAO;AAKxB,UAAO,gBAHL,YAAY,OAAO,aAAa,YAAY,CAAC,MAAM,QAAQ,SAAS,GAC/D,SAAqC,WACtC,KAAA,GACgC,UAAU;;EAElD,kBAAkB,QAAQ;GACxB,MAAM,WAAW,cAAc,OAAO,EAAE;AACxC,OAAI,YAAY,OAAO,aAAa,YAAY,CAAC,MAAM,QAAQ,SAAS,EAAE;IACxE,MAAM,OAAO,OAAO,KAAK,SAAoC,CAAC,MAAM;AACpE,QAAI,KAAK,SAAS,EAAG,QAAO;;AAE9B,UAAO,CAAC,UAAU;;EAErB,CAAC;;AAGJ,iCAAiC"}
@@ -4,6 +4,7 @@
4
4
  * This plugin integrates Telegram with the ChannelPlugin architecture.
5
5
  * It reuses components from this package's src tree where possible.
6
6
  */
7
+ import './pairing-config-resolver.js';
7
8
  import type { Config } from '@xopcai/xopc/config/index.js';
8
9
  import type { ChannelPlugin, ChannelPluginDefaults, ChannelPluginInitOptions, ChannelPluginReloadMeta, ChannelPluginStartOptions, ChannelOutboundAdapter, ChannelGatewayAdapter, ChannelStreamingAdapter, ChannelCommandAdapter } from '@xopcai/xopc/channels/plugin-types.js';
9
10
  import type { TelegramResolvedAccount } from './adapters/index.js';
@@ -4,10 +4,11 @@ import { init_logger } from "../../../src/utils/logger.js";
4
4
  import { registerChannelExecApprovalHandler } from "../../../src/channels/exec-approval-runtime.js";
5
5
  import { isSTTAvailable } from "../../../src/voice/stt/availability.js";
6
6
  import { generateSessionKey } from "../../../src/chat-commands/session-key.js";
7
- import { submitClarifyChoiceFromChannel } from "../../../src/gateway/clarify-runtime.js";
8
7
  import { resolveStandardPairingPath } from "../../../src/channels/pairing/paths.js";
9
8
  import { issuePairingChallenge } from "../../../src/channels/pairing/pairing-challenge.js";
10
9
  import { createStandardPairingAdapter } from "../../../src/channels/pairing/pairing-store-adapter.js";
10
+ import "./pairing-config-resolver.js";
11
+ import { submitClarifyChoiceFromChannel } from "../../../src/gateway/clarify-runtime.js";
11
12
  import { createTimeoutAbortSignal } from "./timeout-abort.js";
12
13
  import { createInboundDebouncer } from "../../../src/infra/debounce.js";
13
14
  import { getMimeType } from "../../../src/channels/media.js";
@@ -268,10 +269,9 @@ var TelegramChannelPlugin = class {
268
269
  if (telegramCfg.enabled !== true) return;
269
270
  const accounts = telegramCfg.accounts;
270
271
  if (!accounts || Object.keys(accounts).length === 0) return;
271
- const channelApiRoot = typeof telegramCfg.apiRoot === "string" ? normalizeTelegramApiRoot(telegramCfg.apiRoot) : void 0;
272
- const channelProxy = typeof telegramCfg.proxy === "string" && telegramCfg.proxy.trim() ? telegramCfg.proxy.trim() : void 0;
273
- const channelReplyToMode = telegramCfg.replyToMode;
274
- const channelStreaming = telegramCfg.streaming;
272
+ const defaults = telegramCfg.defaults && typeof telegramCfg.defaults === "object" && !Array.isArray(telegramCfg.defaults) ? telegramCfg.defaults : {};
273
+ const defaultApiRoot = typeof defaults.apiRoot === "string" ? normalizeTelegramApiRoot(defaults.apiRoot) : void 0;
274
+ const defaultProxy = typeof defaults.proxy === "string" && defaults.proxy.trim() ? defaults.proxy.trim() : void 0;
275
275
  const tokenOwners = /* @__PURE__ */ new Map();
276
276
  for (const [id, account] of Object.entries(accounts)) {
277
277
  const { token, source } = resolveTelegramBotToken({
@@ -286,15 +286,14 @@ var TelegramChannelPlugin = class {
286
286
  const accApiRoot = typeof account.apiRoot === "string" ? normalizeTelegramApiRoot(account.apiRoot) : void 0;
287
287
  const accProxy = typeof account.proxy === "string" && account.proxy.trim() ? account.proxy.trim() : void 0;
288
288
  this.accountManager.registerAccount({
289
+ ...defaults,
289
290
  ...account,
290
291
  accountId: id,
291
292
  botToken: token,
292
293
  tokenFile: typeof account.tokenFile === "string" ? account.tokenFile : void 0,
293
294
  tokenSource: source,
294
- ...accApiRoot || channelApiRoot ? { apiRoot: accApiRoot || channelApiRoot } : {},
295
- ...accProxy || channelProxy ? { proxy: accProxy || channelProxy } : {},
296
- replyToMode: account.replyToMode ?? channelReplyToMode,
297
- streaming: account.streaming ?? channelStreaming
295
+ ...accApiRoot || defaultApiRoot ? { apiRoot: accApiRoot || defaultApiRoot } : {},
296
+ ...accProxy || defaultProxy ? { proxy: accProxy || defaultProxy } : {}
298
297
  });
299
298
  }
300
299
  for (const [token, owners] of tokenOwners) if (owners.length > 1) log.error({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../../../../extensions/telegram/src/plugin.ts"],"sourcesContent":["/**\n * Telegram Channel Plugin - Implementation based on ChannelPlugin interface\n *\n * This plugin integrates Telegram with the ChannelPlugin architecture.\n * It reuses components from this package's src tree where possible.\n */\n\nimport { isDeepStrictEqual } from 'node:util';\n\nimport { Bot, type Context } from 'grammy';\n\nimport type { Config } from '@xopcai/xopc/config/index.js';\nimport type {\n ChannelPlugin,\n ChannelPluginDefaults,\n ChannelPluginInitOptions,\n ChannelPluginReloadMeta,\n ChannelPluginSessionModelHooks,\n ChannelPluginStartOptions,\n ChannelOutboundAdapter,\n ChannelSecurityContext,\n ChannelGatewayAdapter,\n ChannelStreamingAdapter,\n ChannelCommandAdapter,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport { generateSessionKey } from '@xopcai/xopc/chat-commands/session-key.js';\nimport { submitClarifyChoiceFromChannel } from '@xopcai/xopc/gateway/clarify-runtime.js';\n\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport { issuePairingChallenge, resolveStandardPairingPath } from '@xopcai/xopc/channels/pairing/index.js';\nimport { createStandardPairingAdapter } from '@xopcai/xopc/channels/pairing/pairing-store-adapter.js';\nimport { createTimeoutAbortSignal } from './timeout-abort.js';\nimport { createInboundDebouncer } from '@xopcai/xopc/infra/debounce.js';\nimport { getMimeType } from '@xopcai/xopc/channels/media.js';\nimport { isSTTAvailable } from '@xopcai/xopc/voice/stt/availability.js';\nimport type { STTConfig } from '@xopcai/xopc/voice/stt/types.js';\n\nimport { TelegramAccountManager } from './account-manager.js';\nimport { createOutboundSender } from './outbound-sender.js';\n\nimport { createTelegramCommandHandler } from './command-handler.js';\nimport { createInboundProcessor } from './inbound-processor.js';\nimport { TELEGRAM_CHANNEL_DEFAULTS } from './plugin-defaults.js';\nimport {\n createTelegramPluginAdapters,\n createTelegramSetupWizard,\n createTelegramOutboundSendMethods,\n telegramTextChunker,\n TELEGRAM_OUTBOUND_DEFAULTS,\n createTelegramInboundAccessControl,\n telegramDebouncerKeyPolicy,\n type TelegramMessageEvent,\n} from './adapters/index.js';\nimport {\n createTelegramGatewayAdapter,\n createTelegramStreamingAdapter,\n createTelegramCommandAdapter,\n} from './channel.js';\nimport type { TelegramResolvedAccount } from './adapters/index.js';\nimport type { ChannelCronDeliveryAdapter } from '@xopcai/xopc/channels/plugins/types.adapters.js';\nimport { normalizeTelegramDeliveryChatId } from './delivery-chat-id.js';\nimport { telegramOnboardAdapter } from './adapters/onboard-cli.js';\nimport { telegramGatewaySetupActions } from './adapters/gateway-setup.js';\nimport { TelegramConfigSchema } from './config-schema.js';\nimport { normalizeTelegramApiRoot } from './api-root.js';\nimport { resolveTelegramBotToken } from './token-resolver.js';\nimport { formatTelegramStartupError, isTelegramUnauthorizedTokenError } from './startup-errors.js';\nimport { startTelegramPollingSession } from './polling-session.js';\nimport { createProxyFetch } from './proxy-fetch.js';\nimport { runTelegramDoctorChecks } from './doctor.js';\nimport { telegramReplyTracker } from './reply-params.js';\nimport { createTelegramInboundCoalescer } from './inbound-coalescer.js';\nimport { sendTelegramAckReaction, handleTelegramMessageReaction } from './reactions.js';\nimport { handleTelegramChannelAction, bindTelegramMessageActionAccountManager } from './actions/message-actions.js';\nimport { registerChannelExecApprovalHandler } from '@xopcai/xopc/channels/exec-approval-runtime.js';\nimport { createTelegramExecApprovalHandler } from './exec-approval-handler.js';\nimport { handleTelegramFocusCommand } from './focus-handler.js';\nimport { resolveTelegramApproval } from './approval-store.js';\nimport { isTelegramExecApprovalApprover } from './exec-approvals.js';\n\n/** Bound initial `getMe` so a bad `apiRoot` or unreachable API cannot block gateway startup for minutes. */\nconst TELEGRAM_GETME_TIMEOUT_MS = 20_000;\n/** grammY per-request ceiling; must exceed long-poll `getUpdates` (~30s) but avoid multi-minute hangs on bad hosts. */\nconst TELEGRAM_CLIENT_TIMEOUT_SECONDS = 75;\n\nconst log = createLogger('TelegramPlugin');\n\nfunction contextWithMessage(ctx: Context, message: import('@grammyjs/types').Message): Context {\n if (ctx.message === message) return ctx;\n\n const clone = Object.create(Object.getPrototypeOf(ctx)) as Context;\n Object.defineProperties(clone, Object.getOwnPropertyDescriptors(ctx));\n Object.defineProperty(clone, 'message', {\n configurable: true,\n enumerable: true,\n value: message,\n writable: true,\n });\n return clone;\n}\n\nexport type { TelegramResolvedAccount as TelegramAccount } from './channel.js';\n\nexport class TelegramChannelPlugin implements ChannelPlugin<TelegramResolvedAccount> {\n readonly id = 'telegram' as const;\n\n readonly reload: ChannelPluginReloadMeta = {\n configPrefixes: ['channels.telegram'],\n };\n\n readonly meta = {\n id: 'telegram',\n label: 'Telegram',\n selectionLabel: 'Telegram Bot',\n docsPath: '/channels/telegram',\n blurb: 'Telegram Bot API channel',\n order: 0,\n deferConnectUntilAfterListen: true,\n } as const;\n\n readonly capabilities = {\n chatTypes: ['direct', 'group', 'channel', 'thread'] as Array<'direct' | 'group' | 'channel' | 'thread'>,\n reactions: true,\n threads: true,\n media: true,\n polls: false,\n nativeCommands: true,\n blockStreaming: true,\n } as const;\n\n readonly defaults: ChannelPluginDefaults = {\n queue: { debounceMs: TELEGRAM_CHANNEL_DEFAULTS.queue.debounceMs },\n outbound: { textChunkLimit: TELEGRAM_CHANNEL_DEFAULTS.outbound.textChunkLimit },\n };\n\n readonly setupWizard = createTelegramSetupWizard();\n\n readonly configSchema = {\n schema: {},\n validate: (raw: unknown) => {\n const r = TelegramConfigSchema.safeParse(raw);\n return r.success ? { ok: true as const } : { ok: false as const, errors: [r.error.message] };\n },\n };\n\n readonly cronDelivery: ChannelCronDeliveryAdapter = {\n async normalizeDeliveryTarget(to) {\n return { chatId: normalizeTelegramDeliveryChatId(to) };\n },\n };\n\n readonly onboard = telegramOnboardAdapter;\n\n readonly runtimeActions = telegramGatewaySetupActions;\n\n readonly doctor = {\n check: (params: { cfg: Config }) => runTelegramDoctorChecks(params),\n };\n\n readonly pairing = createStandardPairingAdapter('telegram');\n\n private bus!: NonNullable<ChannelPluginInitOptions['bus']>;\n private cfg!: NonNullable<ChannelPluginInitOptions['config']>;\n private debouncer!: ReturnType<typeof createInboundDebouncer<TelegramMessageEvent>>;\n\n private accountManager!: TelegramAccountManager;\n private outboundSender!: ReturnType<typeof createOutboundSender>;\n private commandHandler!: ReturnType<typeof createTelegramCommandHandler>;\n private inboundProcessor!: ReturnType<typeof createInboundProcessor>;\n private sessionModelHooks?: ChannelPluginSessionModelHooks;\n /** Unregister fn for the workflow-progress capability registered against the global broker. */\n private workflowProgressUnregister: (() => void) | null = null;\n private inboundCoalescer = createTelegramInboundCoalescer();\n private execApprovalUnregister: (() => void) | null = null;\n\n readonly actions = {\n handleAction: handleTelegramChannelAction,\n };\n\n config!: import('@xopcai/xopc/channels/plugin-types.js').ChannelConfigAdapter<TelegramResolvedAccount>;\n security!: import('@xopcai/xopc/channels/plugin-types.js').ChannelSecurityAdapter<TelegramResolvedAccount>;\n status!: import('@xopcai/xopc/channels/plugin-types.js').ChannelStatusAdapter<TelegramResolvedAccount>;\n\n outbound!: ChannelOutboundAdapter;\n\n gateway!: ChannelGatewayAdapter<TelegramResolvedAccount>;\n\n streaming!: ChannelStreamingAdapter;\n\n commands!: ChannelCommandAdapter;\n\n async init(options: ChannelPluginInitOptions): Promise<void> {\n this.bus = options.bus;\n this.cfg = options.config;\n this.sessionModelHooks = options.sessionModel;\n\n this.accountManager = new TelegramAccountManager();\n this.loadAccounts();\n this.bindOutboundComponents();\n bindTelegramMessageActionAccountManager(this.accountManager);\n this.execApprovalUnregister?.();\n this.execApprovalUnregister = registerChannelExecApprovalHandler(\n 'telegram',\n createTelegramExecApprovalHandler({\n accountManager: this.accountManager,\n getConfig: () => this.cfg,\n }),\n );\n\n await this.registerWorkflowProgressCapability();\n\n const debounceMs =\n this.defaults.queue?.debounceMs ?? TELEGRAM_CHANNEL_DEFAULTS.queue.debounceMs;\n const keyPolicy = telegramDebouncerKeyPolicy();\n this.debouncer = createInboundDebouncer<TelegramMessageEvent>({\n debounceMs,\n ...keyPolicy,\n onFlush: async (items) => {\n await this.processMessages(items);\n },\n onError: (err, items) => {\n log.error({ err, count: items.length }, 'Debounced message processing failed');\n },\n });\n\n log.debug('Telegram plugin initialized');\n }\n\n private async registerWorkflowProgressCapability(): Promise<void> {\n // Lazy-load workflow progress so channel runtime startup does not pull the\n // whole workflow/agent/provider graph into Electron's dynamic extension path.\n const [{ getWorkflowProgressBroker }, { createTelegramWorkflowProgressCapability }] = await Promise.all([\n import('@xopcai/xopc/agent/workflow/progress-broker.js'),\n import('./workflow-progress.js'),\n ]);\n this.workflowProgressUnregister = getWorkflowProgressBroker().registerChannel(\n createTelegramWorkflowProgressCapability(this.accountManager),\n );\n }\n\n private bindOutboundComponents(): void {\n this.outboundSender = createOutboundSender({\n accountManager: this.accountManager,\n config: this.cfg,\n });\n const sm = this.sessionModelHooks;\n this.commandHandler = createTelegramCommandHandler({\n bus: this.bus,\n config: this.cfg,\n accountManager: this.accountManager,\n getSessionModel: (sessionKey) => sm?.getModelForSession(sessionKey),\n setSessionModel: (sessionKey, modelId) => {\n if (!sm) return;\n void sm.switchModelForSession(sessionKey, modelId);\n },\n });\n const adapters = createTelegramPluginAdapters({\n accountManager: this.accountManager,\n });\n this.config = adapters.config;\n this.security = adapters.security;\n this.status = adapters.status;\n\n const accessControl = createTelegramInboundAccessControl();\n\n this.inboundProcessor = createInboundProcessor({\n bus: this.bus,\n config: this.cfg,\n accountManager: this.accountManager,\n accessControl,\n sessionKeyService: {\n generateSessionKey: (opts) =>\n generateSessionKey({\n source: 'telegram',\n chatId: opts.chatId,\n senderId: opts.senderId,\n isGroup: opts.isGroup,\n threadId: opts.threadId,\n accountId: opts.accountId,\n }),\n },\n sttService: {\n transcribe: async (buffer, config, options) => {\n // Lazy-load STT providers only when voice transcription is actually used.\n const { transcribe } = await import('@xopcai/xopc/voice/stt/transcribe-core.js');\n const result = await transcribe(buffer, config as STTConfig, options);\n return { text: result.text };\n },\n isSTTAvailable: (config) => isSTTAvailable(config as STTConfig | undefined),\n },\n mediaUtils: { getMimeType },\n });\n\n const sends = createTelegramOutboundSendMethods(\n (opts) => this.outboundSender.send(opts),\n this.accountManager,\n );\n this.outbound = {\n deliveryMode: 'direct',\n chunker: telegramTextChunker,\n chunkerMode: 'text',\n textChunkLimit: TELEGRAM_OUTBOUND_DEFAULTS.textChunkLimit,\n ...sends,\n };\n\n this.gateway = createTelegramGatewayAdapter({\n startAccount: (account) => this.startAccount(account),\n stopAccount: (accountId) => this.accountManager.stopRunner(accountId),\n });\n this.streaming = createTelegramStreamingAdapter({ accountManager: this.accountManager });\n this.commands = createTelegramCommandAdapter();\n }\n\n async onConfigUpdated(cfg: Config): Promise<void> {\n const prevTg = this.cfg.channels?.telegram as unknown;\n const nextTg = cfg.channels?.telegram as { enabled?: boolean } | undefined;\n // Match Weixin: only `enabled === true` keeps inbound (polling). Stops immediately on disable / missing section.\n const channelOff = !nextTg || nextTg.enabled !== true;\n if (channelOff) {\n this.cfg = cfg;\n await this.stop();\n this.accountManager.reset();\n this.bindOutboundComponents();\n return;\n }\n\n if (isDeepStrictEqual(prevTg, nextTg)) {\n this.cfg = cfg;\n this.bindOutboundComponents();\n // Config unchanged but runners may be stopped (e.g. disable → enable with identical JSON shape after normalize).\n if (!this.channelIsRunning(cfg)) {\n await this.reapplyFromConfig(cfg);\n }\n return;\n }\n await this.reapplyFromConfig(cfg);\n }\n\n private async reapplyFromConfig(cfg: Config): Promise<void> {\n this.cfg = cfg;\n await this.stop();\n this.accountManager.reset();\n const telegramCfg = cfg.channels?.telegram as Record<string, unknown> | undefined;\n const channelOn = telegramCfg != null && telegramCfg.enabled === true;\n if (!channelOn) {\n this.bindOutboundComponents();\n return;\n }\n this.loadAccounts();\n this.bindOutboundComponents();\n await this.start();\n }\n\n private loadAccounts(): void {\n const telegramCfg = this.cfg.channels?.telegram as Record<string, unknown> | undefined;\n if (!telegramCfg) return;\n if (telegramCfg.enabled !== true) {\n return;\n }\n\n const accounts = telegramCfg.accounts as Record<string, Record<string, unknown>> | undefined;\n if (!accounts || Object.keys(accounts).length === 0) return;\n\n const channelApiRoot =\n typeof telegramCfg.apiRoot === 'string'\n ? normalizeTelegramApiRoot(telegramCfg.apiRoot)\n : undefined;\n const channelProxy =\n typeof telegramCfg.proxy === 'string' && telegramCfg.proxy.trim()\n ? telegramCfg.proxy.trim()\n : undefined;\n const channelReplyToMode = telegramCfg.replyToMode as TelegramResolvedAccount['replyToMode'];\n const channelStreaming = telegramCfg.streaming as TelegramResolvedAccount['streaming'];\n\n const tokenOwners = new Map<string, string[]>();\n\n for (const [id, account] of Object.entries(accounts)) {\n const { token, source } = resolveTelegramBotToken({\n botToken: typeof account.botToken === 'string' ? account.botToken : undefined,\n tokenFile: typeof account.tokenFile === 'string' ? account.tokenFile : undefined,\n });\n if (token) {\n const owners = tokenOwners.get(token) ?? [];\n owners.push(id);\n tokenOwners.set(token, owners);\n }\n\n const accApiRoot =\n typeof account.apiRoot === 'string'\n ? normalizeTelegramApiRoot(account.apiRoot)\n : undefined;\n const accProxy =\n typeof account.proxy === 'string' && account.proxy.trim() ? account.proxy.trim() : undefined;\n\n this.accountManager.registerAccount({\n ...account,\n accountId: id,\n botToken: token,\n tokenFile: typeof account.tokenFile === 'string' ? account.tokenFile : undefined,\n tokenSource: source,\n ...(accApiRoot || channelApiRoot ? { apiRoot: accApiRoot || channelApiRoot } : {}),\n ...(accProxy || channelProxy ? { proxy: accProxy || channelProxy } : {}),\n replyToMode:\n (account.replyToMode as TelegramResolvedAccount['replyToMode']) ?? channelReplyToMode,\n streaming:\n (account.streaming as TelegramResolvedAccount['streaming']) ?? channelStreaming,\n } as import('@xopcai/xopc/channels/channel-domain.js').TelegramAccountConfig);\n }\n\n for (const [token, owners] of tokenOwners) {\n if (owners.length > 1) {\n log.error(\n { accountIds: owners, tokenPreview: `${token.slice(0, 8)}…` },\n `Duplicate Telegram bot token across accounts: ${owners.join(', ')}`,\n );\n }\n }\n }\n\n channelIsRunning(cfg: Config): boolean {\n return this.accountManager.getAllAccounts().some(\n (a) => a.enabled !== false && !!a.botToken && this.accountManager.isRunning(a.accountId),\n );\n }\n\n async start(options?: ChannelPluginStartOptions): Promise<void> {\n const section = this.cfg.channels?.telegram as { enabled?: boolean } | undefined;\n if (!section || section.enabled !== true) {\n return;\n }\n\n const accountIds = options?.accountId\n ? [options.accountId]\n : this.config.listAccountIds(this.cfg);\n\n for (const accountId of accountIds) {\n const account = this.config.resolveAccount(this.cfg, accountId);\n if (!account.enabled || !account.botToken) continue;\n await this.startAccount(account);\n }\n }\n\n async stop(accountId?: string): Promise<void> {\n if (!this.config) return;\n const ids = accountId ? [accountId] : this.config.listAccountIds(this.cfg);\n for (const id of ids) {\n await this.accountManager.stopRunner(id);\n log.info({ accountId: id }, 'Telegram account stopped');\n }\n // Only unregister the broker capability on a full stop (no specific\n // account). A per-account stop still leaves other accounts capable of\n // sending progress through the same registered cap.\n if (!accountId) {\n this.workflowProgressUnregister?.();\n this.workflowProgressUnregister = null;\n this.execApprovalUnregister?.();\n this.execApprovalUnregister = null;\n }\n }\n\n private async startAccount(account: TelegramResolvedAccount): Promise<void> {\n if (this.accountManager.isRunning(account.accountId)) return;\n\n const resolved = resolveTelegramBotToken({\n botToken: account.botToken,\n tokenFile: account.tokenFile,\n });\n if (!resolved.token) return;\n\n const duplicateAccounts = this.accountManager\n .getAllAccounts()\n .filter((a) => {\n const t = resolveTelegramBotToken({\n botToken: a.botToken,\n tokenFile: a.tokenFile,\n }).token;\n return t === resolved.token && a.accountId !== account.accountId;\n })\n .map((a) => a.accountId);\n if (duplicateAccounts.length > 0) {\n const em = `Duplicate bot token shared with account(s): ${duplicateAccounts.join(', ')}`;\n log.error({ accountId: account.accountId, duplicateAccounts }, em);\n this.accountManager.updateStatus({\n accountId: account.accountId,\n running: false,\n mode: 'stopped',\n lastError: em,\n });\n return;\n }\n\n this.accountManager.markStarting(account.accountId);\n\n try {\n const client: {\n timeoutSeconds: number;\n apiRoot?: string;\n fetch?: typeof fetch;\n } = {\n timeoutSeconds: TELEGRAM_CLIENT_TIMEOUT_SECONDS,\n ...(account.apiRoot ? { apiRoot: account.apiRoot } : {}),\n ...(account.proxy ? { fetch: createProxyFetch(account.proxy) } : {}),\n };\n const bot = new Bot(resolved.token, { client });\n const getMeSignal = createTimeoutAbortSignal(TELEGRAM_GETME_TIMEOUT_MS);\n let me;\n try {\n me = await bot.api.getMe(getMeSignal.signal);\n } finally {\n getMeSignal.dispose();\n }\n\n this.accountManager.registerBot(account.accountId, bot);\n this.accountManager.setBotUsername(account.accountId, me.username);\n this.setupMessageHandler(account.accountId, bot);\n\n const session = startTelegramPollingSession({\n accountId: account.accountId,\n botToken: resolved.token,\n bot,\n stallThresholdMs: account.pollingStallThresholdMs,\n onExit: () => {\n void this.accountManager.stopRunner(account.accountId);\n },\n });\n this.accountManager.registerPollingSession(account.accountId, session);\n this.accountManager.updateStatus({\n accountId: account.accountId,\n running: true,\n mode: 'polling',\n });\n\n log.info({ accountId: account.accountId, username: me.username }, 'Telegram account started');\n } catch (err) {\n const em = formatTelegramStartupError(err);\n const level = isTelegramUnauthorizedTokenError(err) ? 'error' : 'warn';\n log[level](\n {\n accountId: account.accountId,\n apiRootConfigured: !!account.apiRoot,\n unauthorized: isTelegramUnauthorizedTokenError(err),\n errorMessage: em,\n },\n `Telegram account not started: ${em}`,\n );\n this.accountManager.updateStatus({\n accountId: account.accountId,\n running: false,\n mode: 'stopped',\n lastError: em.slice(0, 400),\n });\n } finally {\n this.accountManager.markStartComplete(account.accountId);\n }\n }\n\n private attachRunnerExitHandler(_accountId: string, _runner: unknown): void {\n // Polling exit is handled by startTelegramPollingSession.onExit.\n }\n\n private setupMessageHandler(accountId: string, bot: Bot): void {\n const account = this.config.resolveAccount(this.cfg, accountId);\n\n const handleInboundMessage = async (ctx: Context) => {\n const text = ctx.message?.text ?? ctx.message?.caption ?? ctx.channelPost?.text ?? ctx.channelPost?.caption ?? '';\n const command = text.trim().split(' ')[0].split('@')[0].toLowerCase();\n\n if (command === '/models') {\n await this.commandHandler.handleModels(ctx);\n return;\n }\n if (command === '/start') {\n await this.commandHandler.handleStart(ctx);\n return;\n }\n if (command === '/cleanup') {\n await this.commandHandler.handleCleanup(ctx);\n return;\n }\n if (command === '/focus') {\n await handleTelegramFocusCommand({ ctx, accountId, config: this.cfg });\n return;\n }\n\n const message = ctx.message ?? ctx.channelPost;\n if (!message) return;\n\n await this.inboundCoalescer.enqueue({\n ctx,\n accountId,\n message,\n onReady: async (batch) => {\n for (const msg of batch.messages) {\n const batchCtx = batch.ctx;\n await this.debouncer.enqueue({\n ctx: contextWithMessage(batchCtx, msg),\n accountId: batch.accountId,\n message: msg,\n });\n }\n },\n });\n };\n\n bot.on('message', async (ctx) => {\n try {\n await handleInboundMessage(ctx);\n } catch (err) {\n log.error({ accountId, err }, 'Message handler error');\n }\n });\n\n bot.on('channel_post', async (ctx) => {\n try {\n await handleInboundMessage(ctx);\n } catch (err) {\n log.error({ accountId, err }, 'Channel post handler error');\n }\n });\n\n bot.on('message_reaction', async (ctx) => {\n try {\n await handleTelegramMessageReaction({\n ctx,\n accountId,\n bus: this.bus,\n mode: account.reactionNotifications as 'off' | 'own' | 'all' | undefined,\n });\n } catch (err) {\n log.error({ accountId, err }, 'Message reaction handler error');\n }\n });\n\n bot.on('callback_query:data', async (ctx) => {\n try {\n await this.handleCallbackQuery(ctx, accountId);\n } catch (err) {\n log.error({ accountId, err }, 'Callback query handler error');\n await ctx.answerCallbackQuery('An error occurred').catch(() => {});\n }\n });\n }\n\n private async handleCallbackQuery(ctx: Context, _accountId: string): Promise<void> {\n const data = ctx.callbackQuery?.data;\n if (!data) return;\n\n if (data.startsWith('provider:')) {\n const providerId = data.substring('provider:'.length);\n await this.commandHandler.handleProviderSelect(ctx, providerId);\n return;\n }\n\n if (data.startsWith('model:')) {\n const modelId = data.substring('model:'.length);\n await this.commandHandler.handleModelSelect(ctx, modelId);\n return;\n }\n\n if (data === 'cancel') {\n await this.commandHandler.handleCancel(ctx);\n return;\n }\n\n if (data === 'providers') {\n await this.commandHandler.handleShowProviders(ctx);\n return;\n }\n\n if (data === 'cleanup:confirm') {\n await this.commandHandler.handleCleanupConfirm(ctx);\n return;\n }\n\n if (data.startsWith('clarify:')) {\n const rest = data.slice('clarify:'.length);\n const lastColon = rest.lastIndexOf(':');\n if (lastColon > 0) {\n const requestId = rest.slice(0, lastColon);\n const idx = Number.parseInt(rest.slice(lastColon + 1), 10);\n if (requestId && Number.isFinite(idx) && submitClarifyChoiceFromChannel(requestId, idx)) {\n await ctx.answerCallbackQuery();\n return;\n }\n }\n await ctx.answerCallbackQuery('No pending question');\n return;\n }\n\n if (data.startsWith('approval:approve:') || data.startsWith('approval:deny:')) {\n const approved = data.startsWith('approval:approve:');\n const approvalId = data.slice(approved ? 'approval:approve:'.length : 'approval:deny:'.length);\n const senderId = String(ctx.from?.id ?? '');\n if (\n !isTelegramExecApprovalApprover({\n cfg: this.cfg,\n accountId: _accountId,\n senderId,\n })\n ) {\n await ctx.answerCallbackQuery('Not authorized');\n return;\n }\n if (resolveTelegramApproval(approvalId, approved)) {\n await ctx.answerCallbackQuery(approved ? 'Approved' : 'Denied');\n } else {\n await ctx.answerCallbackQuery('Approval expired or already resolved');\n }\n return;\n }\n\n await ctx.answerCallbackQuery('Unknown action');\n }\n\n private async processMessages(items: TelegramMessageEvent[]): Promise<void> {\n if (items.length === 0) return;\n\n const tgSection = this.cfg.channels?.telegram as { enabled?: boolean } | undefined;\n if (!tgSection || tgSection.enabled !== true) {\n return;\n }\n\n const last = items[items.length - 1];\n const ctx = last.ctx;\n const accountId = last.accountId;\n if (!this.accountManager.getAccount(accountId)) {\n log.warn({ accountId }, 'Unknown account');\n return;\n }\n\n const account = this.config.resolveAccount(this.cfg, accountId);\n\n const isGroup = ctx.chat?.type === 'group' || ctx.chat?.type === 'supergroup';\n const senderId = ctx.from?.id?.toString() ?? '';\n const senderUsername = ctx.from?.username;\n const chatId = ctx.chat?.id?.toString() ?? '';\n telegramReplyTracker.reset(accountId, chatId);\n\n const securityCtx: ChannelSecurityContext = {\n accountId,\n chatId,\n senderId,\n senderName: senderUsername,\n isGroup,\n };\n\n const accessResult = this.security.checkAccess?.(securityCtx, account, this.cfg);\n\n if (!accessResult?.allowed) {\n if (!isGroup && accessResult?.reason === 'pairing-required') {\n const cid = ctx.chat?.id;\n const bot = cid != null ? this.accountManager.getBot(accountId) : undefined;\n if (bot && cid != null && senderId) {\n void issuePairingChallenge({\n channel: 'telegram',\n pairingFilePath: resolveStandardPairingPath('telegram', accountId),\n accountId,\n senderId,\n senderIdLine: `Your Telegram user id: ${senderId}`,\n sendPairingReply: async (text) => {\n await bot.api.sendMessage(cid, text);\n },\n onCreated: ({ code }) => {\n log.info({ accountId, senderId, code }, 'Telegram DM pairing code issued');\n },\n onReplyError: (err) => {\n log.warn({ err, accountId, chatId: String(cid) }, 'Telegram pairing reply failed');\n },\n });\n }\n return;\n }\n log.warn(\n {\n accountId,\n chatId,\n senderId,\n isGroup,\n reason: accessResult?.reason,\n dmPolicy: account.dmPolicy,\n groupPolicy: account.groupPolicy,\n },\n 'Telegram: message dropped by channel security (check dmPolicy/groupPolicy and allowFrom)',\n );\n return;\n }\n\n const bot = this.accountManager.getBot(accountId);\n const messageId = ctx.message?.message_id;\n const reactionLevel = (account as { reactionLevel?: string }).reactionLevel ?? 'ack';\n const ackEmoji = (account as { ackReaction?: string }).ackReaction ?? '👀';\n if (\n bot &&\n messageId &&\n reactionLevel !== 'off' &&\n ctx.chat?.id != null &&\n !ctx.channelPost\n ) {\n void sendTelegramAckReaction({\n bot,\n chatId: ctx.chat.id,\n messageId,\n emoji: ackEmoji,\n });\n }\n\n await this.inboundProcessor(ctx, accountId);\n }\n}\n\nexport const telegramPlugin = new TelegramChannelPlugin();\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../../../../extensions/telegram/src/plugin.ts"],"sourcesContent":["/**\n * Telegram Channel Plugin - Implementation based on ChannelPlugin interface\n *\n * This plugin integrates Telegram with the ChannelPlugin architecture.\n * It reuses components from this package's src tree where possible.\n */\n\nimport { isDeepStrictEqual } from 'node:util';\n\nimport { Bot, type Context } from 'grammy';\n\nimport './pairing-config-resolver.js';\n\nimport type { Config } from '@xopcai/xopc/config/index.js';\nimport type {\n ChannelPlugin,\n ChannelPluginDefaults,\n ChannelPluginInitOptions,\n ChannelPluginReloadMeta,\n ChannelPluginSessionModelHooks,\n ChannelPluginStartOptions,\n ChannelOutboundAdapter,\n ChannelSecurityContext,\n ChannelGatewayAdapter,\n ChannelStreamingAdapter,\n ChannelCommandAdapter,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport { generateSessionKey } from '@xopcai/xopc/chat-commands/session-key.js';\nimport { submitClarifyChoiceFromChannel } from '@xopcai/xopc/gateway/clarify-runtime.js';\n\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport { issuePairingChallenge, resolveStandardPairingPath } from '@xopcai/xopc/channels/pairing/index.js';\nimport { createStandardPairingAdapter } from '@xopcai/xopc/channels/pairing/pairing-store-adapter.js';\nimport { createTimeoutAbortSignal } from './timeout-abort.js';\nimport { createInboundDebouncer } from '@xopcai/xopc/infra/debounce.js';\nimport { getMimeType } from '@xopcai/xopc/channels/media.js';\nimport { isSTTAvailable } from '@xopcai/xopc/voice/stt/availability.js';\nimport type { STTConfig } from '@xopcai/xopc/voice/stt/types.js';\n\nimport { TelegramAccountManager } from './account-manager.js';\nimport { createOutboundSender } from './outbound-sender.js';\n\nimport { createTelegramCommandHandler } from './command-handler.js';\nimport { createInboundProcessor } from './inbound-processor.js';\nimport { TELEGRAM_CHANNEL_DEFAULTS } from './plugin-defaults.js';\nimport {\n createTelegramPluginAdapters,\n createTelegramSetupWizard,\n createTelegramOutboundSendMethods,\n telegramTextChunker,\n TELEGRAM_OUTBOUND_DEFAULTS,\n createTelegramInboundAccessControl,\n telegramDebouncerKeyPolicy,\n type TelegramMessageEvent,\n} from './adapters/index.js';\nimport {\n createTelegramGatewayAdapter,\n createTelegramStreamingAdapter,\n createTelegramCommandAdapter,\n} from './channel.js';\nimport type { TelegramResolvedAccount } from './adapters/index.js';\nimport type { ChannelCronDeliveryAdapter } from '@xopcai/xopc/channels/plugins/types.adapters.js';\nimport { normalizeTelegramDeliveryChatId } from './delivery-chat-id.js';\nimport { telegramOnboardAdapter } from './adapters/onboard-cli.js';\nimport { telegramGatewaySetupActions } from './adapters/gateway-setup.js';\nimport { TelegramConfigSchema } from './config-schema.js';\nimport { normalizeTelegramApiRoot } from './api-root.js';\nimport { resolveTelegramBotToken } from './token-resolver.js';\nimport { formatTelegramStartupError, isTelegramUnauthorizedTokenError } from './startup-errors.js';\nimport { startTelegramPollingSession } from './polling-session.js';\nimport { createProxyFetch } from './proxy-fetch.js';\nimport { runTelegramDoctorChecks } from './doctor.js';\nimport { telegramReplyTracker } from './reply-params.js';\nimport { createTelegramInboundCoalescer } from './inbound-coalescer.js';\nimport { sendTelegramAckReaction, handleTelegramMessageReaction } from './reactions.js';\nimport { handleTelegramChannelAction, bindTelegramMessageActionAccountManager } from './actions/message-actions.js';\nimport { registerChannelExecApprovalHandler } from '@xopcai/xopc/channels/exec-approval-runtime.js';\nimport { createTelegramExecApprovalHandler } from './exec-approval-handler.js';\nimport { handleTelegramFocusCommand } from './focus-handler.js';\nimport { resolveTelegramApproval } from './approval-store.js';\nimport { isTelegramExecApprovalApprover } from './exec-approvals.js';\n\n/** Bound initial `getMe` so a bad `apiRoot` or unreachable API cannot block gateway startup for minutes. */\nconst TELEGRAM_GETME_TIMEOUT_MS = 20_000;\n/** grammY per-request ceiling; must exceed long-poll `getUpdates` (~30s) but avoid multi-minute hangs on bad hosts. */\nconst TELEGRAM_CLIENT_TIMEOUT_SECONDS = 75;\n\nconst log = createLogger('TelegramPlugin');\n\nfunction contextWithMessage(ctx: Context, message: import('@grammyjs/types').Message): Context {\n if (ctx.message === message) return ctx;\n\n const clone = Object.create(Object.getPrototypeOf(ctx)) as Context;\n Object.defineProperties(clone, Object.getOwnPropertyDescriptors(ctx));\n Object.defineProperty(clone, 'message', {\n configurable: true,\n enumerable: true,\n value: message,\n writable: true,\n });\n return clone;\n}\n\nexport type { TelegramResolvedAccount as TelegramAccount } from './channel.js';\n\nexport class TelegramChannelPlugin implements ChannelPlugin<TelegramResolvedAccount> {\n readonly id = 'telegram' as const;\n\n readonly reload: ChannelPluginReloadMeta = {\n configPrefixes: ['channels.telegram'],\n };\n\n readonly meta = {\n id: 'telegram',\n label: 'Telegram',\n selectionLabel: 'Telegram Bot',\n docsPath: '/channels/telegram',\n blurb: 'Telegram Bot API channel',\n order: 0,\n deferConnectUntilAfterListen: true,\n } as const;\n\n readonly capabilities = {\n chatTypes: ['direct', 'group', 'channel', 'thread'] as Array<'direct' | 'group' | 'channel' | 'thread'>,\n reactions: true,\n threads: true,\n media: true,\n polls: false,\n nativeCommands: true,\n blockStreaming: true,\n } as const;\n\n readonly defaults: ChannelPluginDefaults = {\n queue: { debounceMs: TELEGRAM_CHANNEL_DEFAULTS.queue.debounceMs },\n outbound: { textChunkLimit: TELEGRAM_CHANNEL_DEFAULTS.outbound.textChunkLimit },\n };\n\n readonly setupWizard = createTelegramSetupWizard();\n\n readonly configSchema = {\n schema: {},\n validate: (raw: unknown) => {\n const r = TelegramConfigSchema.safeParse(raw);\n return r.success ? { ok: true as const } : { ok: false as const, errors: [r.error.message] };\n },\n };\n\n readonly cronDelivery: ChannelCronDeliveryAdapter = {\n async normalizeDeliveryTarget(to) {\n return { chatId: normalizeTelegramDeliveryChatId(to) };\n },\n };\n\n readonly onboard = telegramOnboardAdapter;\n\n readonly runtimeActions = telegramGatewaySetupActions;\n\n readonly doctor = {\n check: (params: { cfg: Config }) => runTelegramDoctorChecks(params),\n };\n\n readonly pairing = createStandardPairingAdapter('telegram');\n\n private bus!: NonNullable<ChannelPluginInitOptions['bus']>;\n private cfg!: NonNullable<ChannelPluginInitOptions['config']>;\n private debouncer!: ReturnType<typeof createInboundDebouncer<TelegramMessageEvent>>;\n\n private accountManager!: TelegramAccountManager;\n private outboundSender!: ReturnType<typeof createOutboundSender>;\n private commandHandler!: ReturnType<typeof createTelegramCommandHandler>;\n private inboundProcessor!: ReturnType<typeof createInboundProcessor>;\n private sessionModelHooks?: ChannelPluginSessionModelHooks;\n /** Unregister fn for the workflow-progress capability registered against the global broker. */\n private workflowProgressUnregister: (() => void) | null = null;\n private inboundCoalescer = createTelegramInboundCoalescer();\n private execApprovalUnregister: (() => void) | null = null;\n\n readonly actions = {\n handleAction: handleTelegramChannelAction,\n };\n\n config!: import('@xopcai/xopc/channels/plugin-types.js').ChannelConfigAdapter<TelegramResolvedAccount>;\n security!: import('@xopcai/xopc/channels/plugin-types.js').ChannelSecurityAdapter<TelegramResolvedAccount>;\n status!: import('@xopcai/xopc/channels/plugin-types.js').ChannelStatusAdapter<TelegramResolvedAccount>;\n\n outbound!: ChannelOutboundAdapter;\n\n gateway!: ChannelGatewayAdapter<TelegramResolvedAccount>;\n\n streaming!: ChannelStreamingAdapter;\n\n commands!: ChannelCommandAdapter;\n\n async init(options: ChannelPluginInitOptions): Promise<void> {\n this.bus = options.bus;\n this.cfg = options.config;\n this.sessionModelHooks = options.sessionModel;\n\n this.accountManager = new TelegramAccountManager();\n this.loadAccounts();\n this.bindOutboundComponents();\n bindTelegramMessageActionAccountManager(this.accountManager);\n this.execApprovalUnregister?.();\n this.execApprovalUnregister = registerChannelExecApprovalHandler(\n 'telegram',\n createTelegramExecApprovalHandler({\n accountManager: this.accountManager,\n getConfig: () => this.cfg,\n }),\n );\n\n await this.registerWorkflowProgressCapability();\n\n const debounceMs =\n this.defaults.queue?.debounceMs ?? TELEGRAM_CHANNEL_DEFAULTS.queue.debounceMs;\n const keyPolicy = telegramDebouncerKeyPolicy();\n this.debouncer = createInboundDebouncer<TelegramMessageEvent>({\n debounceMs,\n ...keyPolicy,\n onFlush: async (items) => {\n await this.processMessages(items);\n },\n onError: (err, items) => {\n log.error({ err, count: items.length }, 'Debounced message processing failed');\n },\n });\n\n log.debug('Telegram plugin initialized');\n }\n\n private async registerWorkflowProgressCapability(): Promise<void> {\n // Lazy-load workflow progress so channel runtime startup does not pull the\n // whole workflow/agent/provider graph into Electron's dynamic extension path.\n const [{ getWorkflowProgressBroker }, { createTelegramWorkflowProgressCapability }] = await Promise.all([\n import('@xopcai/xopc/agent/workflow/progress-broker.js'),\n import('./workflow-progress.js'),\n ]);\n this.workflowProgressUnregister = getWorkflowProgressBroker().registerChannel(\n createTelegramWorkflowProgressCapability(this.accountManager),\n );\n }\n\n private bindOutboundComponents(): void {\n this.outboundSender = createOutboundSender({\n accountManager: this.accountManager,\n config: this.cfg,\n });\n const sm = this.sessionModelHooks;\n this.commandHandler = createTelegramCommandHandler({\n bus: this.bus,\n config: this.cfg,\n accountManager: this.accountManager,\n getSessionModel: (sessionKey) => sm?.getModelForSession(sessionKey),\n setSessionModel: (sessionKey, modelId) => {\n if (!sm) return;\n void sm.switchModelForSession(sessionKey, modelId);\n },\n });\n const adapters = createTelegramPluginAdapters({\n accountManager: this.accountManager,\n });\n this.config = adapters.config;\n this.security = adapters.security;\n this.status = adapters.status;\n\n const accessControl = createTelegramInboundAccessControl();\n\n this.inboundProcessor = createInboundProcessor({\n bus: this.bus,\n config: this.cfg,\n accountManager: this.accountManager,\n accessControl,\n sessionKeyService: {\n generateSessionKey: (opts) =>\n generateSessionKey({\n source: 'telegram',\n chatId: opts.chatId,\n senderId: opts.senderId,\n isGroup: opts.isGroup,\n threadId: opts.threadId,\n accountId: opts.accountId,\n }),\n },\n sttService: {\n transcribe: async (buffer, config, options) => {\n // Lazy-load STT providers only when voice transcription is actually used.\n const { transcribe } = await import('@xopcai/xopc/voice/stt/transcribe-core.js');\n const result = await transcribe(buffer, config as STTConfig, options);\n return { text: result.text };\n },\n isSTTAvailable: (config) => isSTTAvailable(config as STTConfig | undefined),\n },\n mediaUtils: { getMimeType },\n });\n\n const sends = createTelegramOutboundSendMethods(\n (opts) => this.outboundSender.send(opts),\n this.accountManager,\n );\n this.outbound = {\n deliveryMode: 'direct',\n chunker: telegramTextChunker,\n chunkerMode: 'text',\n textChunkLimit: TELEGRAM_OUTBOUND_DEFAULTS.textChunkLimit,\n ...sends,\n };\n\n this.gateway = createTelegramGatewayAdapter({\n startAccount: (account) => this.startAccount(account),\n stopAccount: (accountId) => this.accountManager.stopRunner(accountId),\n });\n this.streaming = createTelegramStreamingAdapter({ accountManager: this.accountManager });\n this.commands = createTelegramCommandAdapter();\n }\n\n async onConfigUpdated(cfg: Config): Promise<void> {\n const prevTg = this.cfg.channels?.telegram as unknown;\n const nextTg = cfg.channels?.telegram as { enabled?: boolean } | undefined;\n // Match Weixin: only `enabled === true` keeps inbound (polling). Stops immediately on disable / missing section.\n const channelOff = !nextTg || nextTg.enabled !== true;\n if (channelOff) {\n this.cfg = cfg;\n await this.stop();\n this.accountManager.reset();\n this.bindOutboundComponents();\n return;\n }\n\n if (isDeepStrictEqual(prevTg, nextTg)) {\n this.cfg = cfg;\n this.bindOutboundComponents();\n // Config unchanged but runners may be stopped (e.g. disable → enable with identical JSON shape after normalize).\n if (!this.channelIsRunning(cfg)) {\n await this.reapplyFromConfig(cfg);\n }\n return;\n }\n await this.reapplyFromConfig(cfg);\n }\n\n private async reapplyFromConfig(cfg: Config): Promise<void> {\n this.cfg = cfg;\n await this.stop();\n this.accountManager.reset();\n const telegramCfg = cfg.channels?.telegram as Record<string, unknown> | undefined;\n const channelOn = telegramCfg != null && telegramCfg.enabled === true;\n if (!channelOn) {\n this.bindOutboundComponents();\n return;\n }\n this.loadAccounts();\n this.bindOutboundComponents();\n await this.start();\n }\n\n private loadAccounts(): void {\n const telegramCfg = this.cfg.channels?.telegram as Record<string, unknown> | undefined;\n if (!telegramCfg) return;\n if (telegramCfg.enabled !== true) {\n return;\n }\n\n const accounts = telegramCfg.accounts as Record<string, Record<string, unknown>> | undefined;\n if (!accounts || Object.keys(accounts).length === 0) return;\n\n const defaults =\n telegramCfg.defaults && typeof telegramCfg.defaults === 'object' && !Array.isArray(telegramCfg.defaults)\n ? telegramCfg.defaults as Record<string, unknown>\n : {};\n const defaultApiRoot =\n typeof defaults.apiRoot === 'string'\n ? normalizeTelegramApiRoot(defaults.apiRoot)\n : undefined;\n const defaultProxy =\n typeof defaults.proxy === 'string' && defaults.proxy.trim()\n ? defaults.proxy.trim()\n : undefined;\n\n const tokenOwners = new Map<string, string[]>();\n\n for (const [id, account] of Object.entries(accounts)) {\n const { token, source } = resolveTelegramBotToken({\n botToken: typeof account.botToken === 'string' ? account.botToken : undefined,\n tokenFile: typeof account.tokenFile === 'string' ? account.tokenFile : undefined,\n });\n if (token) {\n const owners = tokenOwners.get(token) ?? [];\n owners.push(id);\n tokenOwners.set(token, owners);\n }\n\n const accApiRoot =\n typeof account.apiRoot === 'string'\n ? normalizeTelegramApiRoot(account.apiRoot)\n : undefined;\n const accProxy =\n typeof account.proxy === 'string' && account.proxy.trim() ? account.proxy.trim() : undefined;\n\n this.accountManager.registerAccount({\n ...defaults,\n ...account,\n accountId: id,\n botToken: token,\n tokenFile: typeof account.tokenFile === 'string' ? account.tokenFile : undefined,\n tokenSource: source,\n ...(accApiRoot || defaultApiRoot ? { apiRoot: accApiRoot || defaultApiRoot } : {}),\n ...(accProxy || defaultProxy ? { proxy: accProxy || defaultProxy } : {}),\n } as import('./config-types.js').TelegramAccountConfig);\n }\n\n for (const [token, owners] of tokenOwners) {\n if (owners.length > 1) {\n log.error(\n { accountIds: owners, tokenPreview: `${token.slice(0, 8)}…` },\n `Duplicate Telegram bot token across accounts: ${owners.join(', ')}`,\n );\n }\n }\n }\n\n channelIsRunning(cfg: Config): boolean {\n return this.accountManager.getAllAccounts().some(\n (a) => a.enabled !== false && !!a.botToken && this.accountManager.isRunning(a.accountId),\n );\n }\n\n async start(options?: ChannelPluginStartOptions): Promise<void> {\n const section = this.cfg.channels?.telegram as { enabled?: boolean } | undefined;\n if (!section || section.enabled !== true) {\n return;\n }\n\n const accountIds = options?.accountId\n ? [options.accountId]\n : this.config.listAccountIds(this.cfg);\n\n for (const accountId of accountIds) {\n const account = this.config.resolveAccount(this.cfg, accountId);\n if (!account.enabled || !account.botToken) continue;\n await this.startAccount(account);\n }\n }\n\n async stop(accountId?: string): Promise<void> {\n if (!this.config) return;\n const ids = accountId ? [accountId] : this.config.listAccountIds(this.cfg);\n for (const id of ids) {\n await this.accountManager.stopRunner(id);\n log.info({ accountId: id }, 'Telegram account stopped');\n }\n // Only unregister the broker capability on a full stop (no specific\n // account). A per-account stop still leaves other accounts capable of\n // sending progress through the same registered cap.\n if (!accountId) {\n this.workflowProgressUnregister?.();\n this.workflowProgressUnregister = null;\n this.execApprovalUnregister?.();\n this.execApprovalUnregister = null;\n }\n }\n\n private async startAccount(account: TelegramResolvedAccount): Promise<void> {\n if (this.accountManager.isRunning(account.accountId)) return;\n\n const resolved = resolveTelegramBotToken({\n botToken: account.botToken,\n tokenFile: account.tokenFile,\n });\n if (!resolved.token) return;\n\n const duplicateAccounts = this.accountManager\n .getAllAccounts()\n .filter((a) => {\n const t = resolveTelegramBotToken({\n botToken: a.botToken,\n tokenFile: a.tokenFile,\n }).token;\n return t === resolved.token && a.accountId !== account.accountId;\n })\n .map((a) => a.accountId);\n if (duplicateAccounts.length > 0) {\n const em = `Duplicate bot token shared with account(s): ${duplicateAccounts.join(', ')}`;\n log.error({ accountId: account.accountId, duplicateAccounts }, em);\n this.accountManager.updateStatus({\n accountId: account.accountId,\n running: false,\n mode: 'stopped',\n lastError: em,\n });\n return;\n }\n\n this.accountManager.markStarting(account.accountId);\n\n try {\n const client: {\n timeoutSeconds: number;\n apiRoot?: string;\n fetch?: typeof fetch;\n } = {\n timeoutSeconds: TELEGRAM_CLIENT_TIMEOUT_SECONDS,\n ...(account.apiRoot ? { apiRoot: account.apiRoot } : {}),\n ...(account.proxy ? { fetch: createProxyFetch(account.proxy) } : {}),\n };\n const bot = new Bot(resolved.token, { client });\n const getMeSignal = createTimeoutAbortSignal(TELEGRAM_GETME_TIMEOUT_MS);\n let me;\n try {\n me = await bot.api.getMe(getMeSignal.signal);\n } finally {\n getMeSignal.dispose();\n }\n\n this.accountManager.registerBot(account.accountId, bot);\n this.accountManager.setBotUsername(account.accountId, me.username);\n this.setupMessageHandler(account.accountId, bot);\n\n const session = startTelegramPollingSession({\n accountId: account.accountId,\n botToken: resolved.token,\n bot,\n stallThresholdMs: account.pollingStallThresholdMs,\n onExit: () => {\n void this.accountManager.stopRunner(account.accountId);\n },\n });\n this.accountManager.registerPollingSession(account.accountId, session);\n this.accountManager.updateStatus({\n accountId: account.accountId,\n running: true,\n mode: 'polling',\n });\n\n log.info({ accountId: account.accountId, username: me.username }, 'Telegram account started');\n } catch (err) {\n const em = formatTelegramStartupError(err);\n const level = isTelegramUnauthorizedTokenError(err) ? 'error' : 'warn';\n log[level](\n {\n accountId: account.accountId,\n apiRootConfigured: !!account.apiRoot,\n unauthorized: isTelegramUnauthorizedTokenError(err),\n errorMessage: em,\n },\n `Telegram account not started: ${em}`,\n );\n this.accountManager.updateStatus({\n accountId: account.accountId,\n running: false,\n mode: 'stopped',\n lastError: em.slice(0, 400),\n });\n } finally {\n this.accountManager.markStartComplete(account.accountId);\n }\n }\n\n private attachRunnerExitHandler(_accountId: string, _runner: unknown): void {\n // Polling exit is handled by startTelegramPollingSession.onExit.\n }\n\n private setupMessageHandler(accountId: string, bot: Bot): void {\n const account = this.config.resolveAccount(this.cfg, accountId);\n\n const handleInboundMessage = async (ctx: Context) => {\n const text = ctx.message?.text ?? ctx.message?.caption ?? ctx.channelPost?.text ?? ctx.channelPost?.caption ?? '';\n const command = text.trim().split(' ')[0].split('@')[0].toLowerCase();\n\n if (command === '/models') {\n await this.commandHandler.handleModels(ctx);\n return;\n }\n if (command === '/start') {\n await this.commandHandler.handleStart(ctx);\n return;\n }\n if (command === '/cleanup') {\n await this.commandHandler.handleCleanup(ctx);\n return;\n }\n if (command === '/focus') {\n await handleTelegramFocusCommand({ ctx, accountId, config: this.cfg });\n return;\n }\n\n const message = ctx.message ?? ctx.channelPost;\n if (!message) return;\n\n await this.inboundCoalescer.enqueue({\n ctx,\n accountId,\n message,\n onReady: async (batch) => {\n for (const msg of batch.messages) {\n const batchCtx = batch.ctx;\n await this.debouncer.enqueue({\n ctx: contextWithMessage(batchCtx, msg),\n accountId: batch.accountId,\n message: msg,\n });\n }\n },\n });\n };\n\n bot.on('message', async (ctx) => {\n try {\n await handleInboundMessage(ctx);\n } catch (err) {\n log.error({ accountId, err }, 'Message handler error');\n }\n });\n\n bot.on('channel_post', async (ctx) => {\n try {\n await handleInboundMessage(ctx);\n } catch (err) {\n log.error({ accountId, err }, 'Channel post handler error');\n }\n });\n\n bot.on('message_reaction', async (ctx) => {\n try {\n await handleTelegramMessageReaction({\n ctx,\n accountId,\n bus: this.bus,\n mode: account.reactionNotifications as 'off' | 'own' | 'all' | undefined,\n });\n } catch (err) {\n log.error({ accountId, err }, 'Message reaction handler error');\n }\n });\n\n bot.on('callback_query:data', async (ctx) => {\n try {\n await this.handleCallbackQuery(ctx, accountId);\n } catch (err) {\n log.error({ accountId, err }, 'Callback query handler error');\n await ctx.answerCallbackQuery('An error occurred').catch(() => {});\n }\n });\n }\n\n private async handleCallbackQuery(ctx: Context, _accountId: string): Promise<void> {\n const data = ctx.callbackQuery?.data;\n if (!data) return;\n\n if (data.startsWith('provider:')) {\n const providerId = data.substring('provider:'.length);\n await this.commandHandler.handleProviderSelect(ctx, providerId);\n return;\n }\n\n if (data.startsWith('model:')) {\n const modelId = data.substring('model:'.length);\n await this.commandHandler.handleModelSelect(ctx, modelId);\n return;\n }\n\n if (data === 'cancel') {\n await this.commandHandler.handleCancel(ctx);\n return;\n }\n\n if (data === 'providers') {\n await this.commandHandler.handleShowProviders(ctx);\n return;\n }\n\n if (data === 'cleanup:confirm') {\n await this.commandHandler.handleCleanupConfirm(ctx);\n return;\n }\n\n if (data.startsWith('clarify:')) {\n const rest = data.slice('clarify:'.length);\n const lastColon = rest.lastIndexOf(':');\n if (lastColon > 0) {\n const requestId = rest.slice(0, lastColon);\n const idx = Number.parseInt(rest.slice(lastColon + 1), 10);\n if (requestId && Number.isFinite(idx) && submitClarifyChoiceFromChannel(requestId, idx)) {\n await ctx.answerCallbackQuery();\n return;\n }\n }\n await ctx.answerCallbackQuery('No pending question');\n return;\n }\n\n if (data.startsWith('approval:approve:') || data.startsWith('approval:deny:')) {\n const approved = data.startsWith('approval:approve:');\n const approvalId = data.slice(approved ? 'approval:approve:'.length : 'approval:deny:'.length);\n const senderId = String(ctx.from?.id ?? '');\n if (\n !isTelegramExecApprovalApprover({\n cfg: this.cfg,\n accountId: _accountId,\n senderId,\n })\n ) {\n await ctx.answerCallbackQuery('Not authorized');\n return;\n }\n if (resolveTelegramApproval(approvalId, approved)) {\n await ctx.answerCallbackQuery(approved ? 'Approved' : 'Denied');\n } else {\n await ctx.answerCallbackQuery('Approval expired or already resolved');\n }\n return;\n }\n\n await ctx.answerCallbackQuery('Unknown action');\n }\n\n private async processMessages(items: TelegramMessageEvent[]): Promise<void> {\n if (items.length === 0) return;\n\n const tgSection = this.cfg.channels?.telegram as { enabled?: boolean } | undefined;\n if (!tgSection || tgSection.enabled !== true) {\n return;\n }\n\n const last = items[items.length - 1];\n const ctx = last.ctx;\n const accountId = last.accountId;\n if (!this.accountManager.getAccount(accountId)) {\n log.warn({ accountId }, 'Unknown account');\n return;\n }\n\n const account = this.config.resolveAccount(this.cfg, accountId);\n\n const isGroup = ctx.chat?.type === 'group' || ctx.chat?.type === 'supergroup';\n const senderId = ctx.from?.id?.toString() ?? '';\n const senderUsername = ctx.from?.username;\n const chatId = ctx.chat?.id?.toString() ?? '';\n telegramReplyTracker.reset(accountId, chatId);\n\n const securityCtx: ChannelSecurityContext = {\n accountId,\n chatId,\n senderId,\n senderName: senderUsername,\n isGroup,\n };\n\n const accessResult = this.security.checkAccess?.(securityCtx, account, this.cfg);\n\n if (!accessResult?.allowed) {\n if (!isGroup && accessResult?.reason === 'pairing-required') {\n const cid = ctx.chat?.id;\n const bot = cid != null ? this.accountManager.getBot(accountId) : undefined;\n if (bot && cid != null && senderId) {\n void issuePairingChallenge({\n channel: 'telegram',\n pairingFilePath: resolveStandardPairingPath('telegram', accountId),\n accountId,\n senderId,\n senderIdLine: `Your Telegram user id: ${senderId}`,\n sendPairingReply: async (text) => {\n await bot.api.sendMessage(cid, text);\n },\n onCreated: ({ code }) => {\n log.info({ accountId, senderId, code }, 'Telegram DM pairing code issued');\n },\n onReplyError: (err) => {\n log.warn({ err, accountId, chatId: String(cid) }, 'Telegram pairing reply failed');\n },\n });\n }\n return;\n }\n log.warn(\n {\n accountId,\n chatId,\n senderId,\n isGroup,\n reason: accessResult?.reason,\n dmPolicy: account.dmPolicy,\n groupPolicy: account.groupPolicy,\n },\n 'Telegram: message dropped by channel security (check dmPolicy/groupPolicy and allowFrom)',\n );\n return;\n }\n\n const bot = this.accountManager.getBot(accountId);\n const messageId = ctx.message?.message_id;\n const reactionLevel = (account as { reactionLevel?: string }).reactionLevel ?? 'ack';\n const ackEmoji = (account as { ackReaction?: string }).ackReaction ?? '👀';\n if (\n bot &&\n messageId &&\n reactionLevel !== 'off' &&\n ctx.chat?.id != null &&\n !ctx.channelPost\n ) {\n void sendTelegramAckReaction({\n bot,\n chatId: ctx.chat.id,\n messageId,\n emoji: ackEmoji,\n });\n }\n\n await this.inboundProcessor(ctx, accountId);\n }\n}\n\nexport const telegramPlugin = new TelegramChannelPlugin();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA8B4D;oBAmCF;;AAkB1D,MAAM,4BAA4B;;AAElC,MAAM,kCAAkC;AAExC,MAAM,MAAM,aAAa,iBAAiB;AAE1C,SAAS,mBAAmB,KAAc,SAAqD;AAC7F,KAAI,IAAI,YAAY,QAAS,QAAO;CAEpC,MAAM,QAAQ,OAAO,OAAO,OAAO,eAAe,IAAI,CAAC;AACvD,QAAO,iBAAiB,OAAO,OAAO,0BAA0B,IAAI,CAAC;AACrE,QAAO,eAAe,OAAO,WAAW;EACtC,cAAc;EACd,YAAY;EACZ,OAAO;EACP,UAAU;EACX,CAAC;AACF,QAAO;;AAKT,IAAa,wBAAb,MAAqF;CACnF,KAAc;CAEd,SAA2C,EACzC,gBAAgB,CAAC,oBAAoB,EACtC;CAED,OAAgB;EACd,IAAI;EACJ,OAAO;EACP,gBAAgB;EAChB,UAAU;EACV,OAAO;EACP,OAAO;EACP,8BAA8B;EAC/B;CAED,eAAwB;EACtB,WAAW;GAAC;GAAU;GAAS;GAAW;GAAS;EACnD,WAAW;EACX,SAAS;EACT,OAAO;EACP,OAAO;EACP,gBAAgB;EAChB,gBAAgB;EACjB;CAED,WAA2C;EACzC,OAAO,EAAE,YAAY,0BAA0B,MAAM,YAAY;EACjE,UAAU,EAAE,gBAAgB,0BAA0B,SAAS,gBAAgB;EAChF;CAED,cAAuB,2BAA2B;CAElD,eAAwB;EACtB,QAAQ,EAAE;EACV,WAAW,QAAiB;GAC1B,MAAM,IAAI,qBAAqB,UAAU,IAAI;AAC7C,UAAO,EAAE,UAAU,EAAE,IAAI,MAAe,GAAG;IAAE,IAAI;IAAgB,QAAQ,CAAC,EAAE,MAAM,QAAQ;IAAE;;EAE/F;CAED,eAAoD,EAClD,MAAM,wBAAwB,IAAI;AAChC,SAAO,EAAE,QAAQ,gCAAgC,GAAG,EAAE;IAEzD;CAED,UAAmB;CAEnB,iBAA0B;CAE1B,SAAkB,EAChB,QAAQ,WAA4B,wBAAwB,OAAO,EACpE;CAED,UAAmB,6BAA6B,WAAW;CAE3D;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;;CAEA,6BAA0D;CAC1D,mBAA2B,gCAAgC;CAC3D,yBAAsD;CAEtD,UAAmB,EACjB,cAAc,6BACf;CAED;CACA;CACA;CAEA;CAEA;CAEA;CAEA;CAEA,MAAM,KAAK,SAAkD;AAC3D,OAAK,MAAM,QAAQ;AACnB,OAAK,MAAM,QAAQ;AACnB,OAAK,oBAAoB,QAAQ;AAEjC,OAAK,iBAAiB,IAAI,wBAAwB;AAClD,OAAK,cAAc;AACnB,OAAK,wBAAwB;AAC7B,0CAAwC,KAAK,eAAe;AAC5D,OAAK,0BAA0B;AAC/B,OAAK,yBAAyB,mCAC5B,YACA,kCAAkC;GAChC,gBAAgB,KAAK;GACrB,iBAAiB,KAAK;GACvB,CAAC,CACH;AAED,QAAM,KAAK,oCAAoC;EAE/C,MAAM,aACJ,KAAK,SAAS,OAAO,cAAc,0BAA0B,MAAM;EACrE,MAAM,YAAY,4BAA4B;AAC9C,OAAK,YAAY,uBAA6C;GAC5D;GACA,GAAG;GACH,SAAS,OAAO,UAAU;AACxB,UAAM,KAAK,gBAAgB,MAAM;;GAEnC,UAAU,KAAK,UAAU;AACvB,QAAI,MAAM;KAAE;KAAK,OAAO,MAAM;KAAQ,EAAE,sCAAsC;;GAEjF,CAAC;AAEF,MAAI,MAAM,8BAA8B;;CAG1C,MAAc,qCAAoD;EAGhE,MAAM,CAAC,EAAE,6BAA6B,EAAE,8CAA8C,MAAM,QAAQ,IAAI,CACtG,OAAO,mDACP,OAAO,0BACR,CAAC;AACF,OAAK,6BAA6B,2BAA2B,CAAC,gBAC5D,yCAAyC,KAAK,eAAe,CAC9D;;CAGH,yBAAuC;AACrC,OAAK,iBAAiB,qBAAqB;GACzC,gBAAgB,KAAK;GACrB,QAAQ,KAAK;GACd,CAAC;EACF,MAAM,KAAK,KAAK;AAChB,OAAK,iBAAiB,6BAA6B;GACjD,KAAK,KAAK;GACV,QAAQ,KAAK;GACb,gBAAgB,KAAK;GACrB,kBAAkB,eAAe,IAAI,mBAAmB,WAAW;GACnE,kBAAkB,YAAY,YAAY;AACxC,QAAI,CAAC,GAAI;AACJ,OAAG,sBAAsB,YAAY,QAAQ;;GAErD,CAAC;EACF,MAAM,WAAW,6BAA6B,EAC5C,gBAAgB,KAAK,gBACtB,CAAC;AACF,OAAK,SAAS,SAAS;AACvB,OAAK,WAAW,SAAS;AACzB,OAAK,SAAS,SAAS;EAEvB,MAAM,gBAAgB,oCAAoC;AAE1D,OAAK,mBAAmB,uBAAuB;GAC7C,KAAK,KAAK;GACV,QAAQ,KAAK;GACb,gBAAgB,KAAK;GACrB;GACA,mBAAmB,EACjB,qBAAqB,SACnB,mBAAmB;IACjB,QAAQ;IACR,QAAQ,KAAK;IACb,UAAU,KAAK;IACf,SAAS,KAAK;IACd,UAAU,KAAK;IACf,WAAW,KAAK;IACjB,CAAC,EACL;GACD,YAAY;IACV,YAAY,OAAO,QAAQ,QAAQ,YAAY;KAE7C,MAAM,EAAE,eAAe,MAAM,OAAO;AAEpC,YAAO,EAAE,OAAM,MADM,WAAW,QAAQ,QAAqB,QAAQ,EAC/C,MAAM;;IAE9B,iBAAiB,WAAW,eAAe,OAAgC;IAC5E;GACD,YAAY,EAAE,aAAa;GAC5B,CAAC;EAEF,MAAM,QAAQ,mCACX,SAAS,KAAK,eAAe,KAAK,KAAK,EACxC,KAAK,eACN;AACD,OAAK,WAAW;GACd,cAAc;GACd,SAAS;GACT,aAAa;GACb,gBAAgB,2BAA2B;GAC3C,GAAG;GACJ;AAED,OAAK,UAAU,6BAA6B;GAC1C,eAAe,YAAY,KAAK,aAAa,QAAQ;GACrD,cAAc,cAAc,KAAK,eAAe,WAAW,UAAU;GACtE,CAAC;AACF,OAAK,YAAY,+BAA+B,EAAE,gBAAgB,KAAK,gBAAgB,CAAC;AACxF,OAAK,WAAW,8BAA8B;;CAGhD,MAAM,gBAAgB,KAA4B;EAChD,MAAM,SAAS,KAAK,IAAI,UAAU;EAClC,MAAM,SAAS,IAAI,UAAU;AAG7B,MADmB,CAAC,UAAU,OAAO,YAAY,MACjC;AACd,QAAK,MAAM;AACX,SAAM,KAAK,MAAM;AACjB,QAAK,eAAe,OAAO;AAC3B,QAAK,wBAAwB;AAC7B;;AAGF,MAAI,kBAAkB,QAAQ,OAAO,EAAE;AACrC,QAAK,MAAM;AACX,QAAK,wBAAwB;AAE7B,OAAI,CAAC,KAAK,iBAAiB,IAAI,CAC7B,OAAM,KAAK,kBAAkB,IAAI;AAEnC;;AAEF,QAAM,KAAK,kBAAkB,IAAI;;CAGnC,MAAc,kBAAkB,KAA4B;AAC1D,OAAK,MAAM;AACX,QAAM,KAAK,MAAM;AACjB,OAAK,eAAe,OAAO;EAC3B,MAAM,cAAc,IAAI,UAAU;AAElC,MAAI,EADc,eAAe,QAAQ,YAAY,YAAY,OACjD;AACd,QAAK,wBAAwB;AAC7B;;AAEF,OAAK,cAAc;AACnB,OAAK,wBAAwB;AAC7B,QAAM,KAAK,OAAO;;CAGpB,eAA6B;EAC3B,MAAM,cAAc,KAAK,IAAI,UAAU;AACvC,MAAI,CAAC,YAAa;AAClB,MAAI,YAAY,YAAY,KAC1B;EAGF,MAAM,WAAW,YAAY;AAC7B,MAAI,CAAC,YAAY,OAAO,KAAK,SAAS,CAAC,WAAW,EAAG;EAErD,MAAM,WACJ,YAAY,YAAY,OAAO,YAAY,aAAa,YAAY,CAAC,MAAM,QAAQ,YAAY,SAAS,GACpG,YAAY,WACZ,EAAE;EACR,MAAM,iBACJ,OAAO,SAAS,YAAY,WACxB,yBAAyB,SAAS,QAAQ,GAC1C,KAAA;EACN,MAAM,eACJ,OAAO,SAAS,UAAU,YAAY,SAAS,MAAM,MAAM,GACvD,SAAS,MAAM,MAAM,GACrB,KAAA;EAEN,MAAM,8BAAc,IAAI,KAAuB;AAE/C,OAAK,MAAM,CAAC,IAAI,YAAY,OAAO,QAAQ,SAAS,EAAE;GACpD,MAAM,EAAE,OAAO,WAAW,wBAAwB;IAChD,UAAU,OAAO,QAAQ,aAAa,WAAW,QAAQ,WAAW,KAAA;IACpE,WAAW,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY,KAAA;IACxE,CAAC;AACF,OAAI,OAAO;IACT,MAAM,SAAS,YAAY,IAAI,MAAM,IAAI,EAAE;AAC3C,WAAO,KAAK,GAAG;AACf,gBAAY,IAAI,OAAO,OAAO;;GAGhC,MAAM,aACJ,OAAO,QAAQ,YAAY,WACvB,yBAAyB,QAAQ,QAAQ,GACzC,KAAA;GACN,MAAM,WACJ,OAAO,QAAQ,UAAU,YAAY,QAAQ,MAAM,MAAM,GAAG,QAAQ,MAAM,MAAM,GAAG,KAAA;AAErF,QAAK,eAAe,gBAAgB;IAClC,GAAG;IACH,GAAG;IACH,WAAW;IACX,UAAU;IACV,WAAW,OAAO,QAAQ,cAAc,WAAW,QAAQ,YAAY,KAAA;IACvE,aAAa;IACb,GAAI,cAAc,iBAAiB,EAAE,SAAS,cAAc,gBAAgB,GAAG,EAAE;IACjF,GAAI,YAAY,eAAe,EAAE,OAAO,YAAY,cAAc,GAAG,EAAE;IACxE,CAAsD;;AAGzD,OAAK,MAAM,CAAC,OAAO,WAAW,YAC5B,KAAI,OAAO,SAAS,EAClB,KAAI,MACF;GAAE,YAAY;GAAQ,cAAc,GAAG,MAAM,MAAM,GAAG,EAAE,CAAC;GAAI,EAC7D,iDAAiD,OAAO,KAAK,KAAK,GACnE;;CAKP,iBAAiB,KAAsB;AACrC,SAAO,KAAK,eAAe,gBAAgB,CAAC,MACzC,MAAM,EAAE,YAAY,SAAS,CAAC,CAAC,EAAE,YAAY,KAAK,eAAe,UAAU,EAAE,UAAU,CACzF;;CAGH,MAAM,MAAM,SAAoD;EAC9D,MAAM,UAAU,KAAK,IAAI,UAAU;AACnC,MAAI,CAAC,WAAW,QAAQ,YAAY,KAClC;EAGF,MAAM,aAAa,SAAS,YACxB,CAAC,QAAQ,UAAU,GACnB,KAAK,OAAO,eAAe,KAAK,IAAI;AAExC,OAAK,MAAM,aAAa,YAAY;GAClC,MAAM,UAAU,KAAK,OAAO,eAAe,KAAK,KAAK,UAAU;AAC/D,OAAI,CAAC,QAAQ,WAAW,CAAC,QAAQ,SAAU;AAC3C,SAAM,KAAK,aAAa,QAAQ;;;CAIpC,MAAM,KAAK,WAAmC;AAC5C,MAAI,CAAC,KAAK,OAAQ;EAClB,MAAM,MAAM,YAAY,CAAC,UAAU,GAAG,KAAK,OAAO,eAAe,KAAK,IAAI;AAC1E,OAAK,MAAM,MAAM,KAAK;AACpB,SAAM,KAAK,eAAe,WAAW,GAAG;AACxC,OAAI,KAAK,EAAE,WAAW,IAAI,EAAE,2BAA2B;;AAKzD,MAAI,CAAC,WAAW;AACd,QAAK,8BAA8B;AACnC,QAAK,6BAA6B;AAClC,QAAK,0BAA0B;AAC/B,QAAK,yBAAyB;;;CAIlC,MAAc,aAAa,SAAiD;AAC1E,MAAI,KAAK,eAAe,UAAU,QAAQ,UAAU,CAAE;EAEtD,MAAM,WAAW,wBAAwB;GACvC,UAAU,QAAQ;GAClB,WAAW,QAAQ;GACpB,CAAC;AACF,MAAI,CAAC,SAAS,MAAO;EAErB,MAAM,oBAAoB,KAAK,eAC5B,gBAAgB,CAChB,QAAQ,MAAM;AAKb,UAJU,wBAAwB;IAChC,UAAU,EAAE;IACZ,WAAW,EAAE;IACd,CAAC,CAAC,UACU,SAAS,SAAS,EAAE,cAAc,QAAQ;IACvD,CACD,KAAK,MAAM,EAAE,UAAU;AAC1B,MAAI,kBAAkB,SAAS,GAAG;GAChC,MAAM,KAAK,+CAA+C,kBAAkB,KAAK,KAAK;AACtF,OAAI,MAAM;IAAE,WAAW,QAAQ;IAAW;IAAmB,EAAE,GAAG;AAClE,QAAK,eAAe,aAAa;IAC/B,WAAW,QAAQ;IACnB,SAAS;IACT,MAAM;IACN,WAAW;IACZ,CAAC;AACF;;AAGF,OAAK,eAAe,aAAa,QAAQ,UAAU;AAEnD,MAAI;GACF,MAAM,SAIF;IACF,gBAAgB;IAChB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;IACvD,GAAI,QAAQ,QAAQ,EAAE,OAAO,iBAAiB,QAAQ,MAAM,EAAE,GAAG,EAAE;IACpE;GACD,MAAM,MAAM,IAAI,IAAI,SAAS,OAAO,EAAE,QAAQ,CAAC;GAC/C,MAAM,cAAc,yBAAyB,0BAA0B;GACvE,IAAI;AACJ,OAAI;AACF,SAAK,MAAM,IAAI,IAAI,MAAM,YAAY,OAAO;aACpC;AACR,gBAAY,SAAS;;AAGvB,QAAK,eAAe,YAAY,QAAQ,WAAW,IAAI;AACvD,QAAK,eAAe,eAAe,QAAQ,WAAW,GAAG,SAAS;AAClE,QAAK,oBAAoB,QAAQ,WAAW,IAAI;GAEhD,MAAM,UAAU,4BAA4B;IAC1C,WAAW,QAAQ;IACnB,UAAU,SAAS;IACnB;IACA,kBAAkB,QAAQ;IAC1B,cAAc;AACP,UAAK,eAAe,WAAW,QAAQ,UAAU;;IAEzD,CAAC;AACF,QAAK,eAAe,uBAAuB,QAAQ,WAAW,QAAQ;AACtE,QAAK,eAAe,aAAa;IAC/B,WAAW,QAAQ;IACnB,SAAS;IACT,MAAM;IACP,CAAC;AAEF,OAAI,KAAK;IAAE,WAAW,QAAQ;IAAW,UAAU,GAAG;IAAU,EAAE,2BAA2B;WACtF,KAAK;GACZ,MAAM,KAAK,2BAA2B,IAAI;AAE1C,OADc,iCAAiC,IAAI,GAAG,UAAU,QAE9D;IACE,WAAW,QAAQ;IACnB,mBAAmB,CAAC,CAAC,QAAQ;IAC7B,cAAc,iCAAiC,IAAI;IACnD,cAAc;IACf,EACD,iCAAiC,KAClC;AACD,QAAK,eAAe,aAAa;IAC/B,WAAW,QAAQ;IACnB,SAAS;IACT,MAAM;IACN,WAAW,GAAG,MAAM,GAAG,IAAI;IAC5B,CAAC;YACM;AACR,QAAK,eAAe,kBAAkB,QAAQ,UAAU;;;CAI5D,wBAAgC,YAAoB,SAAwB;CAI5E,oBAA4B,WAAmB,KAAgB;EAC7D,MAAM,UAAU,KAAK,OAAO,eAAe,KAAK,KAAK,UAAU;EAE/D,MAAM,uBAAuB,OAAO,QAAiB;GAEnD,MAAM,WADO,IAAI,SAAS,QAAQ,IAAI,SAAS,WAAW,IAAI,aAAa,QAAQ,IAAI,aAAa,WAAW,IAC1F,MAAM,CAAC,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,aAAa;AAErE,OAAI,YAAY,WAAW;AACzB,UAAM,KAAK,eAAe,aAAa,IAAI;AAC3C;;AAEF,OAAI,YAAY,UAAU;AACxB,UAAM,KAAK,eAAe,YAAY,IAAI;AAC1C;;AAEF,OAAI,YAAY,YAAY;AAC1B,UAAM,KAAK,eAAe,cAAc,IAAI;AAC5C;;AAEF,OAAI,YAAY,UAAU;AACxB,UAAM,2BAA2B;KAAE;KAAK;KAAW,QAAQ,KAAK;KAAK,CAAC;AACtE;;GAGF,MAAM,UAAU,IAAI,WAAW,IAAI;AACnC,OAAI,CAAC,QAAS;AAEd,SAAM,KAAK,iBAAiB,QAAQ;IAClC;IACA;IACA;IACA,SAAS,OAAO,UAAU;AACxB,UAAK,MAAM,OAAO,MAAM,UAAU;MAChC,MAAM,WAAW,MAAM;AACvB,YAAM,KAAK,UAAU,QAAQ;OAC3B,KAAK,mBAAmB,UAAU,IAAI;OACtC,WAAW,MAAM;OACjB,SAAS;OACV,CAAC;;;IAGP,CAAC;;AAGJ,MAAI,GAAG,WAAW,OAAO,QAAQ;AAC/B,OAAI;AACF,UAAM,qBAAqB,IAAI;YACxB,KAAK;AACZ,QAAI,MAAM;KAAE;KAAW;KAAK,EAAE,wBAAwB;;IAExD;AAEF,MAAI,GAAG,gBAAgB,OAAO,QAAQ;AACpC,OAAI;AACF,UAAM,qBAAqB,IAAI;YACxB,KAAK;AACZ,QAAI,MAAM;KAAE;KAAW;KAAK,EAAE,6BAA6B;;IAE7D;AAEF,MAAI,GAAG,oBAAoB,OAAO,QAAQ;AACxC,OAAI;AACF,UAAM,8BAA8B;KAClC;KACA;KACA,KAAK,KAAK;KACV,MAAM,QAAQ;KACf,CAAC;YACK,KAAK;AACZ,QAAI,MAAM;KAAE;KAAW;KAAK,EAAE,iCAAiC;;IAEjE;AAEF,MAAI,GAAG,uBAAuB,OAAO,QAAQ;AAC3C,OAAI;AACF,UAAM,KAAK,oBAAoB,KAAK,UAAU;YACvC,KAAK;AACZ,QAAI,MAAM;KAAE;KAAW;KAAK,EAAE,+BAA+B;AAC7D,UAAM,IAAI,oBAAoB,oBAAoB,CAAC,YAAY,GAAG;;IAEpE;;CAGJ,MAAc,oBAAoB,KAAc,YAAmC;EACjF,MAAM,OAAO,IAAI,eAAe;AAChC,MAAI,CAAC,KAAM;AAEX,MAAI,KAAK,WAAW,YAAY,EAAE;GAChC,MAAM,aAAa,KAAK,UAAU,EAAmB;AACrD,SAAM,KAAK,eAAe,qBAAqB,KAAK,WAAW;AAC/D;;AAGF,MAAI,KAAK,WAAW,SAAS,EAAE;GAC7B,MAAM,UAAU,KAAK,UAAU,EAAgB;AAC/C,SAAM,KAAK,eAAe,kBAAkB,KAAK,QAAQ;AACzD;;AAGF,MAAI,SAAS,UAAU;AACrB,SAAM,KAAK,eAAe,aAAa,IAAI;AAC3C;;AAGF,MAAI,SAAS,aAAa;AACxB,SAAM,KAAK,eAAe,oBAAoB,IAAI;AAClD;;AAGF,MAAI,SAAS,mBAAmB;AAC9B,SAAM,KAAK,eAAe,qBAAqB,IAAI;AACnD;;AAGF,MAAI,KAAK,WAAW,WAAW,EAAE;GAC/B,MAAM,OAAO,KAAK,MAAM,EAAkB;GAC1C,MAAM,YAAY,KAAK,YAAY,IAAI;AACvC,OAAI,YAAY,GAAG;IACjB,MAAM,YAAY,KAAK,MAAM,GAAG,UAAU;IAC1C,MAAM,MAAM,OAAO,SAAS,KAAK,MAAM,YAAY,EAAE,EAAE,GAAG;AAC1D,QAAI,aAAa,OAAO,SAAS,IAAI,IAAI,+BAA+B,WAAW,IAAI,EAAE;AACvF,WAAM,IAAI,qBAAqB;AAC/B;;;AAGJ,SAAM,IAAI,oBAAoB,sBAAsB;AACpD;;AAGF,MAAI,KAAK,WAAW,oBAAoB,IAAI,KAAK,WAAW,iBAAiB,EAAE;GAC7E,MAAM,WAAW,KAAK,WAAW,oBAAoB;GACrD,MAAM,aAAa,KAAK,MAAM,WAAW,KAA6B,GAAwB;GAC9F,MAAM,WAAW,OAAO,IAAI,MAAM,MAAM,GAAG;AAC3C,OACE,CAAC,+BAA+B;IAC9B,KAAK,KAAK;IACV,WAAW;IACX;IACD,CAAC,EACF;AACA,UAAM,IAAI,oBAAoB,iBAAiB;AAC/C;;AAEF,OAAI,wBAAwB,YAAY,SAAS,CAC/C,OAAM,IAAI,oBAAoB,WAAW,aAAa,SAAS;OAE/D,OAAM,IAAI,oBAAoB,uCAAuC;AAEvE;;AAGF,QAAM,IAAI,oBAAoB,iBAAiB;;CAGjD,MAAc,gBAAgB,OAA8C;AAC1E,MAAI,MAAM,WAAW,EAAG;EAExB,MAAM,YAAY,KAAK,IAAI,UAAU;AACrC,MAAI,CAAC,aAAa,UAAU,YAAY,KACtC;EAGF,MAAM,OAAO,MAAM,MAAM,SAAS;EAClC,MAAM,MAAM,KAAK;EACjB,MAAM,YAAY,KAAK;AACvB,MAAI,CAAC,KAAK,eAAe,WAAW,UAAU,EAAE;AAC9C,OAAI,KAAK,EAAE,WAAW,EAAE,kBAAkB;AAC1C;;EAGF,MAAM,UAAU,KAAK,OAAO,eAAe,KAAK,KAAK,UAAU;EAE/D,MAAM,UAAU,IAAI,MAAM,SAAS,WAAW,IAAI,MAAM,SAAS;EACjE,MAAM,WAAW,IAAI,MAAM,IAAI,UAAU,IAAI;EAC7C,MAAM,iBAAiB,IAAI,MAAM;EACjC,MAAM,SAAS,IAAI,MAAM,IAAI,UAAU,IAAI;AAC3C,uBAAqB,MAAM,WAAW,OAAO;EAE7C,MAAM,cAAsC;GAC1C;GACA;GACA;GACA,YAAY;GACZ;GACD;EAED,MAAM,eAAe,KAAK,SAAS,cAAc,aAAa,SAAS,KAAK,IAAI;AAEhF,MAAI,CAAC,cAAc,SAAS;AAC1B,OAAI,CAAC,WAAW,cAAc,WAAW,oBAAoB;IAC3D,MAAM,MAAM,IAAI,MAAM;IACtB,MAAM,MAAM,OAAO,OAAO,KAAK,eAAe,OAAO,UAAU,GAAG,KAAA;AAClE,QAAI,OAAO,OAAO,QAAQ,SACnB,uBAAsB;KACzB,SAAS;KACT,iBAAiB,2BAA2B,YAAY,UAAU;KAClE;KACA;KACA,cAAc,0BAA0B;KACxC,kBAAkB,OAAO,SAAS;AAChC,YAAM,IAAI,IAAI,YAAY,KAAK,KAAK;;KAEtC,YAAY,EAAE,WAAW;AACvB,UAAI,KAAK;OAAE;OAAW;OAAU;OAAM,EAAE,kCAAkC;;KAE5E,eAAe,QAAQ;AACrB,UAAI,KAAK;OAAE;OAAK;OAAW,QAAQ,OAAO,IAAI;OAAE,EAAE,gCAAgC;;KAErF,CAAC;AAEJ;;AAEF,OAAI,KACF;IACE;IACA;IACA;IACA;IACA,QAAQ,cAAc;IACtB,UAAU,QAAQ;IAClB,aAAa,QAAQ;IACtB,EACD,2FACD;AACD;;EAGF,MAAM,MAAM,KAAK,eAAe,OAAO,UAAU;EACjD,MAAM,YAAY,IAAI,SAAS;EAC/B,MAAM,gBAAiB,QAAuC,iBAAiB;EAC/E,MAAM,WAAY,QAAqC,eAAe;AACtE,MACE,OACA,aACA,kBAAkB,SAClB,IAAI,MAAM,MAAM,QAChB,CAAC,IAAI,YAEA,yBAAwB;GAC3B;GACA,QAAQ,IAAI,KAAK;GACjB;GACA,OAAO;GACR,CAAC;AAGJ,QAAM,KAAK,iBAAiB,KAAK,UAAU;;;AAI/C,MAAa,iBAAiB,IAAI,uBAAuB"}