@xopcai/xopc 0.0.99 → 0.0.100

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 (349) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/src/account-manager.d.ts +3 -3
  3. package/dist/extensions/telegram/src/account-manager.js +8 -8
  4. package/dist/extensions/telegram/src/account-manager.js.map +1 -1
  5. package/dist/extensions/telegram/src/actions/message-actions.d.ts +4 -0
  6. package/dist/extensions/telegram/src/actions/message-actions.js +71 -0
  7. package/dist/extensions/telegram/src/actions/message-actions.js.map +1 -0
  8. package/dist/extensions/telegram/src/adapters/config-adapter.js +9 -1
  9. package/dist/extensions/telegram/src/adapters/config-adapter.js.map +1 -1
  10. package/dist/extensions/telegram/src/adapters/config-surface.js +1 -1
  11. package/dist/extensions/telegram/src/adapters/config-surface.js.map +1 -1
  12. package/dist/extensions/telegram/src/adapters/outbound-adapter.d.ts +2 -1
  13. package/dist/extensions/telegram/src/adapters/outbound-adapter.js +18 -4
  14. package/dist/extensions/telegram/src/adapters/outbound-adapter.js.map +1 -1
  15. package/dist/extensions/telegram/src/adapters/security-adapter.js +2 -1
  16. package/dist/extensions/telegram/src/adapters/security-adapter.js.map +1 -1
  17. package/dist/extensions/telegram/src/adapters/streaming-adapter.js +90 -6
  18. package/dist/extensions/telegram/src/adapters/streaming-adapter.js.map +1 -1
  19. package/dist/extensions/telegram/src/adapters/types.d.ts +9 -1
  20. package/dist/extensions/telegram/src/api-root.d.ts +4 -0
  21. package/dist/extensions/telegram/src/api-root.js +42 -0
  22. package/dist/extensions/telegram/src/api-root.js.map +1 -0
  23. package/dist/extensions/telegram/src/approval-delivery.d.ts +9 -0
  24. package/dist/extensions/telegram/src/approval-delivery.js +36 -0
  25. package/dist/extensions/telegram/src/approval-delivery.js.map +1 -0
  26. package/dist/extensions/telegram/src/approval-store.d.ts +25 -0
  27. package/dist/extensions/telegram/src/approval-store.js +61 -0
  28. package/dist/extensions/telegram/src/approval-store.js.map +1 -0
  29. package/dist/extensions/telegram/src/config-schema.d.ts +185 -35
  30. package/dist/extensions/telegram/src/config-schema.js +67 -45
  31. package/dist/extensions/telegram/src/config-schema.js.map +1 -1
  32. package/dist/extensions/telegram/src/conversation-id.d.ts +6 -0
  33. package/dist/extensions/telegram/src/conversation-id.js +18 -0
  34. package/dist/extensions/telegram/src/conversation-id.js.map +1 -0
  35. package/dist/extensions/telegram/src/doctor.d.ts +5 -0
  36. package/dist/extensions/telegram/src/doctor.js +80 -0
  37. package/dist/extensions/telegram/src/doctor.js.map +1 -0
  38. package/dist/extensions/telegram/src/exec-approval-handler.d.ts +7 -0
  39. package/dist/extensions/telegram/src/exec-approval-handler.js +36 -0
  40. package/dist/extensions/telegram/src/exec-approval-handler.js.map +1 -0
  41. package/dist/extensions/telegram/src/exec-approvals.d.ts +8 -0
  42. package/dist/extensions/telegram/src/exec-approvals.js +20 -0
  43. package/dist/extensions/telegram/src/exec-approvals.js.map +1 -0
  44. package/dist/extensions/telegram/src/focus-handler.d.ts +12 -0
  45. package/dist/extensions/telegram/src/focus-handler.js +55 -0
  46. package/dist/extensions/telegram/src/focus-handler.js.map +1 -0
  47. package/dist/extensions/telegram/src/group-config-resolver.d.ts +12 -0
  48. package/dist/extensions/telegram/src/group-config-resolver.js +17 -0
  49. package/dist/extensions/telegram/src/group-config-resolver.js.map +1 -0
  50. package/dist/extensions/telegram/src/inbound-coalescer.d.ts +15 -0
  51. package/dist/extensions/telegram/src/inbound-coalescer.js +107 -0
  52. package/dist/extensions/telegram/src/inbound-coalescer.js.map +1 -0
  53. package/dist/extensions/telegram/src/inbound-processor.d.ts +1 -0
  54. package/dist/extensions/telegram/src/inbound-processor.js +41 -4
  55. package/dist/extensions/telegram/src/inbound-processor.js.map +1 -1
  56. package/dist/extensions/telegram/src/network-errors.d.ts +2 -0
  57. package/dist/extensions/telegram/src/network-errors.js +23 -0
  58. package/dist/extensions/telegram/src/network-errors.js.map +1 -0
  59. package/dist/extensions/telegram/src/plugin.d.ts +11 -0
  60. package/dist/extensions/telegram/src/plugin.js +191 -57
  61. package/dist/extensions/telegram/src/plugin.js.map +1 -1
  62. package/dist/extensions/telegram/src/polling-session.d.ts +17 -0
  63. package/dist/extensions/telegram/src/polling-session.js +112 -0
  64. package/dist/extensions/telegram/src/polling-session.js.map +1 -0
  65. package/dist/extensions/telegram/src/proxy-fetch.d.ts +2 -0
  66. package/dist/extensions/telegram/src/proxy-fetch.js +14 -0
  67. package/dist/extensions/telegram/src/proxy-fetch.js.map +1 -0
  68. package/dist/extensions/telegram/src/reactions.d.ts +14 -0
  69. package/dist/extensions/telegram/src/reactions.js +48 -0
  70. package/dist/extensions/telegram/src/reactions.js.map +1 -0
  71. package/dist/extensions/telegram/src/reply-params.d.ts +15 -0
  72. package/dist/extensions/telegram/src/reply-params.js +28 -0
  73. package/dist/extensions/telegram/src/reply-params.js.map +1 -0
  74. package/dist/extensions/telegram/src/startup-errors.d.ts +3 -0
  75. package/dist/extensions/telegram/src/startup-errors.js +27 -0
  76. package/dist/extensions/telegram/src/startup-errors.js.map +1 -0
  77. package/dist/extensions/telegram/src/telegram-actions.d.ts +25 -0
  78. package/dist/extensions/telegram/src/telegram-actions.js +65 -0
  79. package/dist/extensions/telegram/src/telegram-actions.js.map +1 -0
  80. package/dist/extensions/telegram/src/thread-bindings.d.ts +15 -0
  81. package/dist/extensions/telegram/src/thread-bindings.js +22 -0
  82. package/dist/extensions/telegram/src/thread-bindings.js.map +1 -0
  83. package/dist/extensions/telegram/src/token-resolver.d.ts +8 -0
  84. package/dist/extensions/telegram/src/token-resolver.js +34 -0
  85. package/dist/extensions/telegram/src/token-resolver.js.map +1 -0
  86. package/dist/extensions/telegram/src/update-offset-store.d.ts +9 -0
  87. package/dist/extensions/telegram/src/update-offset-store.js +66 -0
  88. package/dist/extensions/telegram/src/update-offset-store.js.map +1 -0
  89. package/dist/extensions/telegram/xopc.extension.json +1 -1
  90. package/dist/gateway/static/root/assets/{agents-4KTK-Ku7.js → agents-C5jtBK-H.js} +1 -1
  91. package/dist/gateway/static/root/assets/{apps-page-DkgInY2w.js → apps-page-smJl-qf_.js} +1 -1
  92. package/dist/gateway/static/root/assets/channels-settings-CH6KgFK6.js +1 -0
  93. package/dist/gateway/static/root/assets/channels-status-swr-CV70xvY7.js +8 -0
  94. package/dist/gateway/static/root/assets/{cron-api-BRDli2Mm.js → cron-api-CgBO8B7I.js} +1 -1
  95. package/dist/gateway/static/root/assets/{cron-page-BzEr5Za8.js → cron-page-Be0cW1cR.js} +1 -1
  96. package/dist/gateway/static/root/assets/{dist-BsHh1vX0.js → dist-P8HRGUuh.js} +1 -1
  97. package/dist/gateway/static/root/assets/{extension-debug-page-TWt5q_ef.js → extension-debug-page-BowuycYu.js} +1 -1
  98. package/dist/gateway/static/root/assets/{extension-page-C3kV8ZvZ.js → extension-page-27-Zpv8O.js} +1 -1
  99. package/dist/gateway/static/root/assets/{extension-settings-page-Csy9LNC6.js → extension-settings-page-DDFa_rIq.js} +1 -1
  100. package/dist/gateway/static/root/assets/{fetch-BLLOP2CM.js → fetch-drJUxxKP.js} +1 -1
  101. package/dist/gateway/static/root/assets/{field-primitives-MXbM8HvY.js → field-primitives-BWLssxEb.js} +1 -1
  102. package/dist/gateway/static/root/assets/{heartbeat-config-api-CkoyqfRx.js → heartbeat-config-api-BVuYNYT_.js} +1 -1
  103. package/dist/gateway/static/root/assets/index-CRDAmr3W.js +4840 -0
  104. package/dist/gateway/static/root/assets/index-DjNDHzwG.css +1 -0
  105. package/dist/gateway/static/root/assets/{logs-page-B2vY41ph.js → logs-page-BDX8IrDQ.js} +1 -1
  106. package/dist/gateway/static/root/assets/{note-detail-page-B7qE5pkO.js → note-detail-page-BmQ9KeiA.js} +1 -1
  107. package/dist/gateway/static/root/assets/{note-time-NBBReVR4.js → note-time-14I9Sgqh.js} +1 -1
  108. package/dist/gateway/static/root/assets/{notes-page-CsWYaqYM.js → notes-page-BMfP0FFf.js} +1 -1
  109. package/dist/gateway/static/root/assets/{sessions-page-BPGY3SCT.js → sessions-page-C3scyChq.js} +1 -1
  110. package/dist/gateway/static/root/assets/{settings-advanced-gate-DtA451RM.js → settings-advanced-gate-2ODuCjHP.js} +1 -1
  111. package/dist/gateway/static/root/assets/{settings-form-section-DYR_SPlX.js → settings-form-section-DUoGKAiW.js} +1 -1
  112. package/dist/gateway/static/root/assets/{settings-page-BJUgZQzN.js → settings-page-CttAfOWV.js} +1 -1
  113. package/dist/gateway/static/root/assets/{share-preview-page-3u8VFmdo.js → share-preview-page-B77xqiiI.js} +1 -1
  114. package/dist/gateway/static/root/assets/{skills-page-DuyhcH4U.js → skills-page-B_bAZGzB.js} +1 -1
  115. package/dist/gateway/static/root/assets/{theme-store-e2q2yjs4.js → theme-store-BgCPrmxU.js} +1 -1
  116. package/dist/gateway/static/root/assets/url-q28QhI7l.js +3 -0
  117. package/dist/gateway/static/root/assets/{utils-B4Vw3fnc.js → utils-CCGejlcX.js} +1 -1
  118. package/dist/gateway/static/root/assets/{voice-api-key-field-BFY67Hhp.js → voice-api-key-field-DZzzihcY.js} +1 -1
  119. package/dist/gateway/static/root/assets/{workflow-page.utils-yUJ5jexd.js → workflow-page.utils-D5RMAmT4.js} +1 -1
  120. package/dist/gateway/static/root/assets/{workflows-page-DIMHCpNt.js → workflows-page-DEYpC6Bv.js} +1 -1
  121. package/dist/gateway/static/root/index.html +5 -5
  122. package/dist/package.js +1 -1
  123. package/dist/src/agent/agent-manager.d.ts +4 -0
  124. package/dist/src/agent/agent-manager.js +68 -4
  125. package/dist/src/agent/agent-manager.js.map +1 -1
  126. package/dist/src/agent/child-agent-factory.d.ts +1 -0
  127. package/dist/src/agent/child-agent-factory.js +13 -10
  128. package/dist/src/agent/child-agent-factory.js.map +1 -1
  129. package/dist/src/agent/embedded/run-for-session.d.ts +1 -0
  130. package/dist/src/agent/embedded/run-for-session.js +1 -0
  131. package/dist/src/agent/embedded/run-for-session.js.map +1 -1
  132. package/dist/src/agent/embedded/run-turn.js +1 -17
  133. package/dist/src/agent/embedded/run-turn.js.map +1 -1
  134. package/dist/src/agent/embedded/session-runner.js +3 -1
  135. package/dist/src/agent/embedded/session-runner.js.map +1 -1
  136. package/dist/src/agent/embedded/session-tool-result-guard.d.ts +1 -0
  137. package/dist/src/agent/embedded/session-tool-result-guard.js +1 -0
  138. package/dist/src/agent/embedded/session-tool-result-guard.js.map +1 -1
  139. package/dist/src/agent/inbound/attachment-pipeline.d.ts +37 -0
  140. package/dist/src/agent/inbound/attachment-pipeline.js +169 -0
  141. package/dist/src/agent/inbound/attachment-pipeline.js.map +1 -0
  142. package/dist/src/agent/inbound/turn-dispatcher.d.ts +3 -5
  143. package/dist/src/agent/inbound/turn-dispatcher.js +1 -2
  144. package/dist/src/agent/inbound/turn-dispatcher.js.map +1 -1
  145. package/dist/src/agent/memory/index.d.ts +2 -0
  146. package/dist/src/agent/memory/index.js +2 -1
  147. package/dist/src/agent/memory/memory-flush.d.ts +27 -0
  148. package/dist/src/agent/memory/memory-flush.js +124 -0
  149. package/dist/src/agent/memory/memory-flush.js.map +1 -0
  150. package/dist/src/agent/messaging/outbound-coordinator.js +2 -1
  151. package/dist/src/agent/messaging/outbound-coordinator.js.map +1 -1
  152. package/dist/src/agent/messaging/stream-manager.d.ts +2 -0
  153. package/dist/src/agent/messaging/stream-manager.js +3 -0
  154. package/dist/src/agent/messaging/stream-manager.js.map +1 -1
  155. package/dist/src/agent/orchestration/agent-orchestrator.d.ts +0 -4
  156. package/dist/src/agent/orchestration/agent-orchestrator.js +40 -107
  157. package/dist/src/agent/orchestration/agent-orchestrator.js.map +1 -1
  158. package/dist/src/agent/prompt/contribution.d.ts +9 -0
  159. package/dist/src/agent/prompt/contribution.js +1 -0
  160. package/dist/src/agent/prompt/safety.js +0 -10
  161. package/dist/src/agent/prompt/safety.js.map +1 -1
  162. package/dist/src/agent/prompt/sanitize-for-prompt.d.ts +6 -0
  163. package/dist/src/agent/prompt/sanitize-for-prompt.js +13 -0
  164. package/dist/src/agent/prompt/sanitize-for-prompt.js.map +1 -0
  165. package/dist/src/agent/prompt/sections/behavior.d.ts +5 -0
  166. package/dist/src/agent/prompt/sections/behavior.js +50 -0
  167. package/dist/src/agent/prompt/sections/behavior.js.map +1 -0
  168. package/dist/src/agent/prompt/sections/memory-skills.d.ts +9 -0
  169. package/dist/src/agent/prompt/sections/memory-skills.js +59 -0
  170. package/dist/src/agent/prompt/sections/memory-skills.js.map +1 -0
  171. package/dist/src/agent/prompt/sections/messaging-runtime.d.ts +16 -0
  172. package/dist/src/agent/prompt/sections/messaging-runtime.js +69 -0
  173. package/dist/src/agent/prompt/sections/messaging-runtime.js.map +1 -0
  174. package/dist/src/agent/prompt/sections/project-context.d.ts +16 -0
  175. package/dist/src/agent/prompt/sections/project-context.js +58 -0
  176. package/dist/src/agent/prompt/sections/project-context.js.map +1 -0
  177. package/dist/src/agent/prompt/sections/tooling.d.ts +5 -0
  178. package/dist/src/agent/prompt/sections/tooling.js +119 -0
  179. package/dist/src/agent/prompt/sections/tooling.js.map +1 -0
  180. package/dist/src/agent/prompt/sections/workspace-runtime.d.ts +11 -0
  181. package/dist/src/agent/prompt/sections/workspace-runtime.js +32 -0
  182. package/dist/src/agent/prompt/sections/workspace-runtime.js.map +1 -0
  183. package/dist/src/agent/prompt/service-prompt-builder.d.ts +13 -0
  184. package/dist/src/agent/prompt/service-prompt-builder.js +54 -13
  185. package/dist/src/agent/prompt/service-prompt-builder.js.map +1 -1
  186. package/dist/src/agent/prompt/subagent-context.d.ts +15 -0
  187. package/dist/src/agent/prompt/subagent-context.js +68 -0
  188. package/dist/src/agent/prompt/subagent-context.js.map +1 -0
  189. package/dist/src/agent/prompt/system-prompt-params.d.ts +53 -0
  190. package/dist/src/agent/prompt/system-prompt-params.js +74 -0
  191. package/dist/src/agent/prompt/system-prompt-params.js.map +1 -0
  192. package/dist/src/agent/prompt/system-prompt.d.ts +22 -11
  193. package/dist/src/agent/prompt/system-prompt.js +79 -193
  194. package/dist/src/agent/prompt/system-prompt.js.map +1 -1
  195. package/dist/src/agent/prompt/types.d.ts +3 -0
  196. package/dist/src/agent/service/build-direct-message-content.d.ts +5 -21
  197. package/dist/src/agent/service/build-direct-message-content.js +11 -64
  198. package/dist/src/agent/service/build-direct-message-content.js.map +1 -1
  199. package/dist/src/agent/service/direct-turn-helpers.d.ts +1 -1
  200. package/dist/src/agent/service/direct-turn-helpers.js +7 -0
  201. package/dist/src/agent/service/direct-turn-helpers.js.map +1 -1
  202. package/dist/src/agent/service/process-direct-one-shot.d.ts +3 -3
  203. package/dist/src/agent/service/process-direct-one-shot.js +22 -17
  204. package/dist/src/agent/service/process-direct-one-shot.js.map +1 -1
  205. package/dist/src/agent/service/process-direct-streaming.d.ts +6 -20
  206. package/dist/src/agent/service/process-direct-streaming.js +39 -40
  207. package/dist/src/agent/service/process-direct-streaming.js.map +1 -1
  208. package/dist/src/agent/service/webchat-tts.d.ts +4 -9
  209. package/dist/src/agent/service/webchat-tts.js +9 -20
  210. package/dist/src/agent/service/webchat-tts.js.map +1 -1
  211. package/dist/src/agent/service.d.ts +8 -19
  212. package/dist/src/agent/service.js +53 -11
  213. package/dist/src/agent/service.js.map +1 -1
  214. package/dist/src/agent/tools/factory.js +2 -0
  215. package/dist/src/agent/tools/factory.js.map +1 -1
  216. package/dist/src/agent/tools/index.d.ts +1 -0
  217. package/dist/src/agent/tools/index.js +2 -1
  218. package/dist/src/agent/tools/media-read-tool.d.ts +2 -0
  219. package/dist/src/agent/tools/media-read-tool.js +89 -0
  220. package/dist/src/agent/tools/media-read-tool.js.map +1 -0
  221. package/dist/src/channels/attachments/attachment-classifiers.d.ts +8 -0
  222. package/dist/src/channels/attachments/attachment-classifiers.js +11 -0
  223. package/dist/src/channels/attachments/attachment-classifiers.js.map +1 -0
  224. package/dist/src/channels/attachments/inbound-persist.d.ts +13 -34
  225. package/dist/src/channels/attachments/inbound-persist.js +34 -102
  226. package/dist/src/channels/attachments/inbound-persist.js.map +1 -1
  227. package/dist/src/channels/attachments/inbound-types.d.ts +13 -0
  228. package/dist/src/channels/attachments/inbound-types.js +30 -0
  229. package/dist/src/channels/attachments/inbound-types.js.map +1 -0
  230. package/dist/src/channels/attachments/outbound-tts-persist.d.ts +3 -12
  231. package/dist/src/channels/attachments/outbound-tts-persist.js +28 -48
  232. package/dist/src/channels/attachments/outbound-tts-persist.js.map +1 -1
  233. package/dist/src/channels/attachments/voice-stt-webchat.d.ts +3 -3
  234. package/dist/src/channels/attachments/voice-stt-webchat.js +8 -14
  235. package/dist/src/channels/attachments/voice-stt-webchat.js.map +1 -1
  236. package/dist/src/channels/channel-domain.d.ts +30 -2
  237. package/dist/src/channels/exec-approval-runtime.d.ts +29 -0
  238. package/dist/src/channels/exec-approval-runtime.js +30 -0
  239. package/dist/src/channels/exec-approval-runtime.js.map +1 -0
  240. package/dist/src/channels/index.js +1 -1
  241. package/dist/src/channels/plugin-types.d.ts +1 -0
  242. package/dist/src/channels/transport-types.d.ts +2 -2
  243. package/dist/src/cli/commands/channels.js +1 -1
  244. package/dist/src/cli/commands/doctor/checks/database-schema.d.ts +2 -0
  245. package/dist/src/cli/commands/doctor/checks/database-schema.js +62 -0
  246. package/dist/src/cli/commands/doctor/checks/database-schema.js.map +1 -0
  247. package/dist/src/cli/commands/doctor/flow.js +2 -0
  248. package/dist/src/cli/commands/doctor/flow.js.map +1 -1
  249. package/dist/src/cli/commands/init.js +2 -57
  250. package/dist/src/cli/commands/init.js.map +1 -1
  251. package/dist/src/cli/commands/onboard/channels/registry.js +1 -1
  252. package/dist/src/cli/commands/setup.js +6 -5
  253. package/dist/src/cli/commands/setup.js.map +1 -1
  254. package/dist/src/cli/utils/init-workspace-core.js +1 -2
  255. package/dist/src/cli/utils/init-workspace-core.js.map +1 -1
  256. package/dist/src/config/index.js +2 -2
  257. package/dist/src/config/paths.d.ts +0 -13
  258. package/dist/src/config/paths.js +1 -20
  259. package/dist/src/config/paths.js.map +1 -1
  260. package/dist/src/config/rules.js +1 -1
  261. package/dist/src/config/schema.d.ts +24 -0
  262. package/dist/src/config/schema.js +33 -2
  263. package/dist/src/config/schema.js.map +1 -1
  264. package/dist/src/cron/executor.js +2 -2
  265. package/dist/src/gateway/heartbeat/service.js +1 -1
  266. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  267. package/dist/src/gateway/hono/routes/config-patch/channels.js +3 -3
  268. package/dist/src/gateway/hono/routes/config-patch/channels.js.map +1 -1
  269. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  270. package/dist/src/gateway/hono/routes/lazy-bundles.js.map +1 -1
  271. package/dist/src/gateway/hono/routes/media.d.ts +3 -0
  272. package/dist/src/gateway/hono/routes/media.js +50 -0
  273. package/dist/src/gateway/hono/routes/media.js.map +1 -0
  274. package/dist/src/gateway/hono/routes/sessions.js +6 -0
  275. package/dist/src/gateway/hono/routes/sessions.js.map +1 -1
  276. package/dist/src/gateway/hono/routes/workspace.js +1 -87
  277. package/dist/src/gateway/hono/routes/workspace.js.map +1 -1
  278. package/dist/src/gateway/service/sessions-api.js +3 -0
  279. package/dist/src/gateway/service/sessions-api.js.map +1 -1
  280. package/dist/src/heartbeat/index.js +1 -1
  281. package/dist/src/media/index.d.ts +5 -0
  282. package/dist/src/media/index.js +5 -0
  283. package/dist/src/media/media-reference.d.ts +23 -0
  284. package/dist/src/media/media-reference.js +34 -0
  285. package/dist/src/media/media-reference.js.map +1 -0
  286. package/dist/src/media/paths.d.ts +5 -0
  287. package/dist/src/media/paths.js +20 -0
  288. package/dist/src/media/paths.js.map +1 -0
  289. package/dist/src/media/session-references.d.ts +8 -0
  290. package/dist/src/media/session-references.js +45 -0
  291. package/dist/src/media/session-references.js.map +1 -0
  292. package/dist/src/media/store.d.ts +19 -0
  293. package/dist/src/media/store.js +131 -0
  294. package/dist/src/media/store.js.map +1 -0
  295. package/dist/src/media/types.d.ts +34 -0
  296. package/dist/src/media/types.js +1 -0
  297. package/dist/src/media/uri.d.ts +15 -0
  298. package/dist/src/media/uri.js +51 -0
  299. package/dist/src/media/uri.js.map +1 -0
  300. package/dist/src/session/session-title.js +6 -3
  301. package/dist/src/session/session-title.js.map +1 -1
  302. package/dist/src/session/store.js +1 -1
  303. package/dist/src/session/store.js.map +1 -1
  304. package/dist/src/session/types.d.ts +12 -7
  305. package/dist/src/session/types.js.map +1 -1
  306. package/dist/src/storage/sqlite/index.d.ts +4 -1
  307. package/dist/src/storage/sqlite/index.js +6 -2
  308. package/dist/src/storage/sqlite/migrations/002_add_flush_columns.sql +3 -0
  309. package/dist/src/storage/sqlite/migrations/discover.d.ts +4 -0
  310. package/dist/src/storage/sqlite/migrations/discover.js +38 -0
  311. package/dist/src/storage/sqlite/migrations/discover.js.map +1 -0
  312. package/dist/src/storage/sqlite/migrations/discover.ts +52 -0
  313. package/dist/src/storage/sqlite/migrations/errors.d.ts +11 -0
  314. package/dist/src/storage/sqlite/migrations/errors.js +27 -0
  315. package/dist/src/storage/sqlite/migrations/errors.js.map +1 -0
  316. package/dist/src/storage/sqlite/migrations/errors.ts +32 -0
  317. package/dist/src/storage/sqlite/migrations/runner.d.ts +22 -0
  318. package/dist/src/storage/sqlite/migrations/runner.js +97 -0
  319. package/dist/src/storage/sqlite/migrations/runner.js.map +1 -0
  320. package/dist/src/storage/sqlite/migrations/runner.ts +153 -0
  321. package/dist/src/storage/sqlite/migrations/types.d.ts +12 -0
  322. package/dist/src/storage/sqlite/migrations/types.js +1 -0
  323. package/dist/src/storage/sqlite/migrations/types.ts +13 -0
  324. package/dist/src/storage/sqlite/row-mappers.d.ts +4 -0
  325. package/dist/src/storage/sqlite/row-mappers.js +4 -0
  326. package/dist/src/storage/sqlite/row-mappers.js.map +1 -1
  327. package/dist/src/storage/sqlite/schema-version.d.ts +6 -0
  328. package/dist/src/storage/sqlite/schema-version.js +29 -0
  329. package/dist/src/storage/sqlite/schema-version.js.map +1 -0
  330. package/dist/src/storage/sqlite/schema.d.ts +5 -3
  331. package/dist/src/storage/sqlite/schema.js +24 -28
  332. package/dist/src/storage/sqlite/schema.js.map +1 -1
  333. package/dist/src/storage/sqlite/schema.sql +2 -0
  334. package/dist/src/storage/sqlite/session-metadata.js +1 -0
  335. package/dist/src/storage/sqlite/session-metadata.js.map +1 -1
  336. package/dist/src/storage/sqlite/session-repository.js +7 -3
  337. package/dist/src/storage/sqlite/session-repository.js.map +1 -1
  338. package/package.json +1 -1
  339. package/dist/gateway/static/root/assets/channels-settings-BxW1Xio4.js +0 -1
  340. package/dist/gateway/static/root/assets/channels-status-swr-Cxm6AvQO.js +0 -8
  341. package/dist/gateway/static/root/assets/index-BJDmBCSl.css +0 -1
  342. package/dist/gateway/static/root/assets/index-Cbg5TS5m.js +0 -4707
  343. package/dist/gateway/static/root/assets/url-DpFBIyN9.js +0 -3
  344. package/dist/src/cli/commands/onboard/workspace.d.ts +0 -14
  345. package/dist/src/cli/commands/onboard/workspace.js +0 -33
  346. package/dist/src/cli/commands/onboard/workspace.js.map +0 -1
  347. package/dist/src/cli/utils/workspace.d.ts +0 -35
  348. package/dist/src/cli/utils/workspace.js +0 -72
  349. package/dist/src/cli/utils/workspace.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "manifest_version": 3,
3
3
  "name": "xopc Browser Bridge",
4
- "version": "0.0.99",
4
+ "version": "0.0.100",
5
5
  "description": "Browser automation bridge for xopc — executes commands in Chrome via the local xopc daemon.",
6
6
  "permissions": [
7
7
  "debugger",
@@ -9,12 +9,12 @@
9
9
  * - Bot username mapping
10
10
  */
11
11
  import type { Bot, Context } from 'grammy';
12
- import { run } from '@grammyjs/runner';
13
12
  import type { TelegramAccountConfig, ChannelStatus } from '@xopcai/xopc/channels/channel-domain.js';
13
+ import type { TelegramPollingSession } from './polling-session.js';
14
14
  export declare class TelegramAccountManager {
15
15
  private accounts;
16
16
  private bots;
17
- private runners;
17
+ private pollingSessions;
18
18
  private statuses;
19
19
  private botUsernames;
20
20
  private startingAccounts;
@@ -25,7 +25,7 @@ export declare class TelegramAccountManager {
25
25
  reset(): void;
26
26
  registerBot(accountId: string, bot: Bot): void;
27
27
  getBot(accountId: string): Bot | undefined;
28
- registerRunner(accountId: string, runner: ReturnType<typeof run>): void;
28
+ registerPollingSession(accountId: string, session: TelegramPollingSession): void;
29
29
  stopRunner(accountId: string): Promise<void>;
30
30
  isStarting(accountId: string): boolean;
31
31
  markStarting(accountId: string): void;
@@ -2,7 +2,7 @@
2
2
  var TelegramAccountManager = class {
3
3
  accounts = /* @__PURE__ */ new Map();
4
4
  bots = /* @__PURE__ */ new Map();
5
- runners = /* @__PURE__ */ new Map();
5
+ pollingSessions = /* @__PURE__ */ new Map();
6
6
  statuses = /* @__PURE__ */ new Map();
7
7
  botUsernames = /* @__PURE__ */ new Map();
8
8
  startingAccounts = /* @__PURE__ */ new Set();
@@ -24,7 +24,7 @@ var TelegramAccountManager = class {
24
24
  reset() {
25
25
  this.accounts.clear();
26
26
  this.bots.clear();
27
- this.runners.clear();
27
+ this.pollingSessions.clear();
28
28
  this.statuses.clear();
29
29
  this.botUsernames.clear();
30
30
  this.startingAccounts.clear();
@@ -35,15 +35,15 @@ var TelegramAccountManager = class {
35
35
  getBot(accountId) {
36
36
  return this.bots.get(accountId);
37
37
  }
38
- registerRunner(accountId, runner) {
39
- this.runners.set(accountId, runner);
38
+ registerPollingSession(accountId, session) {
39
+ this.pollingSessions.set(accountId, session);
40
40
  }
41
41
  async stopRunner(accountId) {
42
- const runner = this.runners.get(accountId);
42
+ const session = this.pollingSessions.get(accountId);
43
43
  const bot = this.bots.get(accountId);
44
- if (runner) {
45
- await runner.stop();
46
- this.runners.delete(accountId);
44
+ if (session) {
45
+ await session.stop();
46
+ this.pollingSessions.delete(accountId);
47
47
  }
48
48
  if (bot) {
49
49
  bot.stop();
@@ -1 +1 @@
1
- {"version":3,"file":"account-manager.js","names":[],"sources":["../../../../extensions/telegram/src/account-manager.ts"],"sourcesContent":["/**\n * Telegram Account Manager\n *\n * Manages multiple Telegram bot accounts, including:\n * - Account configuration storage\n * - Bot instance management\n * - Runner lifecycle\n * - Status tracking\n * - Bot username mapping\n */\n\nimport type { Bot, Context } from 'grammy';\nimport { run } from '@grammyjs/runner';\nimport type { TelegramAccountConfig, ChannelStatus } from '@xopcai/xopc/channels/channel-domain.js';\n\nexport class TelegramAccountManager {\n private accounts = new Map<string, TelegramAccountConfig>();\n private bots = new Map<string, Bot>();\n private runners = new Map<string, ReturnType<typeof run>>();\n private statuses = new Map<string, ChannelStatus>();\n private botUsernames = new Map<string, string>();\n private startingAccounts = new Set<string>();\n\n registerAccount(account: TelegramAccountConfig): void {\n this.accounts.set(account.accountId, account);\n this.statuses.set(account.accountId, {\n accountId: account.accountId,\n running: false,\n mode: 'stopped',\n });\n }\n\n getAccount(accountId: string): TelegramAccountConfig | undefined {\n return this.accounts.get(accountId);\n }\n\n getAllAccounts(): TelegramAccountConfig[] {\n return Array.from(this.accounts.values());\n }\n\n /** Clear all accounts and runtime state (used when reloading channel config). */\n reset(): void {\n this.accounts.clear();\n this.bots.clear();\n this.runners.clear();\n this.statuses.clear();\n this.botUsernames.clear();\n this.startingAccounts.clear();\n }\n\n registerBot(accountId: string, bot: Bot): void {\n this.bots.set(accountId, bot);\n }\n\n getBot(accountId: string): Bot | undefined {\n return this.bots.get(accountId);\n }\n\n registerRunner(accountId: string, runner: ReturnType<typeof run>): void {\n this.runners.set(accountId, runner);\n }\n\n async stopRunner(accountId: string): Promise<void> {\n const runner = this.runners.get(accountId);\n const bot = this.bots.get(accountId);\n \n if (runner) {\n await runner.stop();\n this.runners.delete(accountId);\n }\n \n if (bot) {\n bot.stop();\n this.bots.delete(accountId);\n }\n \n this.startingAccounts.delete(accountId);\n \n // Update status to stopped\n this.updateStatus({\n accountId,\n running: false,\n mode: 'stopped',\n });\n }\n\n isStarting(accountId: string): boolean {\n return this.startingAccounts.has(accountId);\n }\n\n markStarting(accountId: string): void {\n this.startingAccounts.add(accountId);\n }\n\n markStartComplete(accountId: string): void {\n this.startingAccounts.delete(accountId);\n }\n\n isRunning(accountId: string): boolean {\n const status = this.statuses.get(accountId);\n return status?.running ?? false;\n }\n\n updateStatus(status: ChannelStatus): void {\n this.statuses.set(status.accountId, status);\n }\n\n getStatus(accountId: string): ChannelStatus | undefined {\n return this.statuses.get(accountId);\n }\n\n setBotUsername(accountId: string, username: string): void {\n this.botUsernames.set(accountId, username);\n }\n\n getBotUsername(accountId: string): string | undefined {\n return this.botUsernames.get(accountId);\n }\n\n /** Map the bot handling this update to a configured account id (session keys must match inbound). */\n resolveAccountIdFromContext(ctx: Context): string {\n const botId = ctx.me?.id;\n if (botId == null) {\n const accounts = this.getAllAccounts();\n return accounts[0]?.accountId ?? 'default';\n }\n for (const [accountId, bot] of this.bots) {\n if (bot.botInfo?.id === botId) return accountId;\n }\n const accounts = this.getAllAccounts();\n if (accounts.length === 1) return accounts[0]!.accountId;\n return 'default';\n }\n}\n"],"mappings":";AAeA,IAAa,yBAAb,MAAoC;CAClC,2BAAmB,IAAI,KAAoC;CAC3D,uBAAe,IAAI,KAAkB;CACrC,0BAAkB,IAAI,KAAqC;CAC3D,2BAAmB,IAAI,KAA4B;CACnD,+BAAuB,IAAI,KAAqB;CAChD,mCAA2B,IAAI,KAAa;CAE5C,gBAAgB,SAAsC;AACpD,OAAK,SAAS,IAAI,QAAQ,WAAW,QAAQ;AAC7C,OAAK,SAAS,IAAI,QAAQ,WAAW;GACnC,WAAW,QAAQ;GACnB,SAAS;GACT,MAAM;GACP,CAAC;;CAGJ,WAAW,WAAsD;AAC/D,SAAO,KAAK,SAAS,IAAI,UAAU;;CAGrC,iBAA0C;AACxC,SAAO,MAAM,KAAK,KAAK,SAAS,QAAQ,CAAC;;;CAI3C,QAAc;AACZ,OAAK,SAAS,OAAO;AACrB,OAAK,KAAK,OAAO;AACjB,OAAK,QAAQ,OAAO;AACpB,OAAK,SAAS,OAAO;AACrB,OAAK,aAAa,OAAO;AACzB,OAAK,iBAAiB,OAAO;;CAG/B,YAAY,WAAmB,KAAgB;AAC7C,OAAK,KAAK,IAAI,WAAW,IAAI;;CAG/B,OAAO,WAAoC;AACzC,SAAO,KAAK,KAAK,IAAI,UAAU;;CAGjC,eAAe,WAAmB,QAAsC;AACtE,OAAK,QAAQ,IAAI,WAAW,OAAO;;CAGrC,MAAM,WAAW,WAAkC;EACjD,MAAM,SAAS,KAAK,QAAQ,IAAI,UAAU;EAC1C,MAAM,MAAM,KAAK,KAAK,IAAI,UAAU;AAEpC,MAAI,QAAQ;AACV,SAAM,OAAO,MAAM;AACnB,QAAK,QAAQ,OAAO,UAAU;;AAGhC,MAAI,KAAK;AACP,OAAI,MAAM;AACV,QAAK,KAAK,OAAO,UAAU;;AAG7B,OAAK,iBAAiB,OAAO,UAAU;AAGvC,OAAK,aAAa;GAChB;GACA,SAAS;GACT,MAAM;GACP,CAAC;;CAGJ,WAAW,WAA4B;AACrC,SAAO,KAAK,iBAAiB,IAAI,UAAU;;CAG7C,aAAa,WAAyB;AACpC,OAAK,iBAAiB,IAAI,UAAU;;CAGtC,kBAAkB,WAAyB;AACzC,OAAK,iBAAiB,OAAO,UAAU;;CAGzC,UAAU,WAA4B;AAEpC,SADe,KAAK,SAAS,IAAI,UACpB,EAAE,WAAW;;CAG5B,aAAa,QAA6B;AACxC,OAAK,SAAS,IAAI,OAAO,WAAW,OAAO;;CAG7C,UAAU,WAA8C;AACtD,SAAO,KAAK,SAAS,IAAI,UAAU;;CAGrC,eAAe,WAAmB,UAAwB;AACxD,OAAK,aAAa,IAAI,WAAW,SAAS;;CAG5C,eAAe,WAAuC;AACpD,SAAO,KAAK,aAAa,IAAI,UAAU;;;CAIzC,4BAA4B,KAAsB;EAChD,MAAM,QAAQ,IAAI,IAAI;AACtB,MAAI,SAAS,KAEX,QADiB,KAAK,gBACP,CAAC,IAAI,aAAa;AAEnC,OAAK,MAAM,CAAC,WAAW,QAAQ,KAAK,KAClC,KAAI,IAAI,SAAS,OAAO,MAAO,QAAO;EAExC,MAAM,WAAW,KAAK,gBAAgB;AACtC,MAAI,SAAS,WAAW,EAAG,QAAO,SAAS,GAAI;AAC/C,SAAO"}
1
+ {"version":3,"file":"account-manager.js","names":[],"sources":["../../../../extensions/telegram/src/account-manager.ts"],"sourcesContent":["/**\n * Telegram Account Manager\n *\n * Manages multiple Telegram bot accounts, including:\n * - Account configuration storage\n * - Bot instance management\n * - Runner lifecycle\n * - Status tracking\n * - Bot username mapping\n */\n\nimport type { Bot, Context } from 'grammy';\nimport type { TelegramAccountConfig, ChannelStatus } from '@xopcai/xopc/channels/channel-domain.js';\nimport type { TelegramPollingSession } from './polling-session.js';\n\nexport class TelegramAccountManager {\n private accounts = new Map<string, TelegramAccountConfig>();\n private bots = new Map<string, Bot>();\n private pollingSessions = new Map<string, TelegramPollingSession>();\n private statuses = new Map<string, ChannelStatus>();\n private botUsernames = new Map<string, string>();\n private startingAccounts = new Set<string>();\n\n registerAccount(account: TelegramAccountConfig): void {\n this.accounts.set(account.accountId, account);\n this.statuses.set(account.accountId, {\n accountId: account.accountId,\n running: false,\n mode: 'stopped',\n });\n }\n\n getAccount(accountId: string): TelegramAccountConfig | undefined {\n return this.accounts.get(accountId);\n }\n\n getAllAccounts(): TelegramAccountConfig[] {\n return Array.from(this.accounts.values());\n }\n\n /** Clear all accounts and runtime state (used when reloading channel config). */\n reset(): void {\n this.accounts.clear();\n this.bots.clear();\n this.pollingSessions.clear();\n this.statuses.clear();\n this.botUsernames.clear();\n this.startingAccounts.clear();\n }\n\n registerBot(accountId: string, bot: Bot): void {\n this.bots.set(accountId, bot);\n }\n\n getBot(accountId: string): Bot | undefined {\n return this.bots.get(accountId);\n }\n\n registerPollingSession(accountId: string, session: TelegramPollingSession): void {\n this.pollingSessions.set(accountId, session);\n }\n\n async stopRunner(accountId: string): Promise<void> {\n const session = this.pollingSessions.get(accountId);\n const bot = this.bots.get(accountId);\n\n if (session) {\n await session.stop();\n this.pollingSessions.delete(accountId);\n }\n\n if (bot) {\n bot.stop();\n this.bots.delete(accountId);\n }\n \n this.startingAccounts.delete(accountId);\n \n // Update status to stopped\n this.updateStatus({\n accountId,\n running: false,\n mode: 'stopped',\n });\n }\n\n isStarting(accountId: string): boolean {\n return this.startingAccounts.has(accountId);\n }\n\n markStarting(accountId: string): void {\n this.startingAccounts.add(accountId);\n }\n\n markStartComplete(accountId: string): void {\n this.startingAccounts.delete(accountId);\n }\n\n isRunning(accountId: string): boolean {\n const status = this.statuses.get(accountId);\n return status?.running ?? false;\n }\n\n updateStatus(status: ChannelStatus): void {\n this.statuses.set(status.accountId, status);\n }\n\n getStatus(accountId: string): ChannelStatus | undefined {\n return this.statuses.get(accountId);\n }\n\n setBotUsername(accountId: string, username: string): void {\n this.botUsernames.set(accountId, username);\n }\n\n getBotUsername(accountId: string): string | undefined {\n return this.botUsernames.get(accountId);\n }\n\n /** Map the bot handling this update to a configured account id (session keys must match inbound). */\n resolveAccountIdFromContext(ctx: Context): string {\n const botId = ctx.me?.id;\n if (botId == null) {\n const accounts = this.getAllAccounts();\n return accounts[0]?.accountId ?? 'default';\n }\n for (const [accountId, bot] of this.bots) {\n if (bot.botInfo?.id === botId) return accountId;\n }\n const accounts = this.getAllAccounts();\n if (accounts.length === 1) return accounts[0]!.accountId;\n return 'default';\n }\n}\n"],"mappings":";AAeA,IAAa,yBAAb,MAAoC;CAClC,2BAAmB,IAAI,KAAoC;CAC3D,uBAAe,IAAI,KAAkB;CACrC,kCAA0B,IAAI,KAAqC;CACnE,2BAAmB,IAAI,KAA4B;CACnD,+BAAuB,IAAI,KAAqB;CAChD,mCAA2B,IAAI,KAAa;CAE5C,gBAAgB,SAAsC;AACpD,OAAK,SAAS,IAAI,QAAQ,WAAW,QAAQ;AAC7C,OAAK,SAAS,IAAI,QAAQ,WAAW;GACnC,WAAW,QAAQ;GACnB,SAAS;GACT,MAAM;GACP,CAAC;;CAGJ,WAAW,WAAsD;AAC/D,SAAO,KAAK,SAAS,IAAI,UAAU;;CAGrC,iBAA0C;AACxC,SAAO,MAAM,KAAK,KAAK,SAAS,QAAQ,CAAC;;;CAI3C,QAAc;AACZ,OAAK,SAAS,OAAO;AACrB,OAAK,KAAK,OAAO;AACjB,OAAK,gBAAgB,OAAO;AAC5B,OAAK,SAAS,OAAO;AACrB,OAAK,aAAa,OAAO;AACzB,OAAK,iBAAiB,OAAO;;CAG/B,YAAY,WAAmB,KAAgB;AAC7C,OAAK,KAAK,IAAI,WAAW,IAAI;;CAG/B,OAAO,WAAoC;AACzC,SAAO,KAAK,KAAK,IAAI,UAAU;;CAGjC,uBAAuB,WAAmB,SAAuC;AAC/E,OAAK,gBAAgB,IAAI,WAAW,QAAQ;;CAG9C,MAAM,WAAW,WAAkC;EACjD,MAAM,UAAU,KAAK,gBAAgB,IAAI,UAAU;EACnD,MAAM,MAAM,KAAK,KAAK,IAAI,UAAU;AAEpC,MAAI,SAAS;AACX,SAAM,QAAQ,MAAM;AACpB,QAAK,gBAAgB,OAAO,UAAU;;AAGxC,MAAI,KAAK;AACP,OAAI,MAAM;AACV,QAAK,KAAK,OAAO,UAAU;;AAG7B,OAAK,iBAAiB,OAAO,UAAU;AAGvC,OAAK,aAAa;GAChB;GACA,SAAS;GACT,MAAM;GACP,CAAC;;CAGJ,WAAW,WAA4B;AACrC,SAAO,KAAK,iBAAiB,IAAI,UAAU;;CAG7C,aAAa,WAAyB;AACpC,OAAK,iBAAiB,IAAI,UAAU;;CAGtC,kBAAkB,WAAyB;AACzC,OAAK,iBAAiB,OAAO,UAAU;;CAGzC,UAAU,WAA4B;AAEpC,SADe,KAAK,SAAS,IAAI,UACpB,EAAE,WAAW;;CAG5B,aAAa,QAA6B;AACxC,OAAK,SAAS,IAAI,OAAO,WAAW,OAAO;;CAG7C,UAAU,WAA8C;AACtD,SAAO,KAAK,SAAS,IAAI,UAAU;;CAGrC,eAAe,WAAmB,UAAwB;AACxD,OAAK,aAAa,IAAI,WAAW,SAAS;;CAG5C,eAAe,WAAuC;AACpD,SAAO,KAAK,aAAa,IAAI,UAAU;;;CAIzC,4BAA4B,KAAsB;EAChD,MAAM,QAAQ,IAAI,IAAI;AACtB,MAAI,SAAS,KAEX,QADiB,KAAK,gBACP,CAAC,IAAI,aAAa;AAEnC,OAAK,MAAM,CAAC,WAAW,QAAQ,KAAK,KAClC,KAAI,IAAI,SAAS,OAAO,MAAO,QAAO;EAExC,MAAM,WAAW,KAAK,gBAAgB;AACtC,MAAI,SAAS,WAAW,EAAG,QAAO,SAAS,GAAI;AAC/C,SAAO"}
@@ -0,0 +1,4 @@
1
+ import type { ChannelMessageActionContext } from '@xopcai/xopc/channels/plugin-types.js';
2
+ import type { TelegramAccountManager } from '../account-manager.js';
3
+ export declare function bindTelegramMessageActionAccountManager(manager: TelegramAccountManager): void;
4
+ export declare function handleTelegramChannelAction(ctx: ChannelMessageActionContext): Promise<void>;
@@ -0,0 +1,71 @@
1
+ import { createLogger } from "../../../../src/utils/logger/index.js";
2
+ import { init_logger } from "../../../../src/utils/logger.js";
3
+ import { telegramDeleteMessage, telegramEditMessage, telegramSendPoll, telegramSetReaction } from "../telegram-actions.js";
4
+ //#region extensions/telegram/src/actions/message-actions.ts
5
+ init_logger();
6
+ const log = createLogger("TelegramMessageActions");
7
+ let accountManagerRef = null;
8
+ function bindTelegramMessageActionAccountManager(manager) {
9
+ accountManagerRef = manager;
10
+ }
11
+ async function handleTelegramChannelAction(ctx) {
12
+ const manager = accountManagerRef;
13
+ if (!manager) {
14
+ log.warn("Telegram message actions: account manager not bound");
15
+ return;
16
+ }
17
+ const bot = manager.getBot(ctx.accountId);
18
+ if (!bot) {
19
+ log.warn({ accountId: ctx.accountId }, "Telegram message actions: bot unavailable");
20
+ return;
21
+ }
22
+ const messageId = Number.parseInt(ctx.messageId, 10);
23
+ if (!Number.isFinite(messageId)) return;
24
+ switch (ctx.action) {
25
+ case "react": {
26
+ const emoji = ctx.data?.trim() || "👍";
27
+ await telegramSetReaction({
28
+ bot,
29
+ chatId: ctx.chatId,
30
+ messageId,
31
+ emoji
32
+ });
33
+ break;
34
+ }
35
+ case "edit": {
36
+ const text = ctx.data?.trim();
37
+ if (text) await telegramEditMessage({
38
+ bot,
39
+ chatId: ctx.chatId,
40
+ messageId,
41
+ text
42
+ });
43
+ break;
44
+ }
45
+ case "delete":
46
+ await telegramDeleteMessage({
47
+ bot,
48
+ chatId: ctx.chatId,
49
+ messageId
50
+ });
51
+ break;
52
+ case "poll":
53
+ try {
54
+ const parsed = JSON.parse(ctx.data);
55
+ if (parsed.question && Array.isArray(parsed.options) && parsed.options.length >= 2) await telegramSendPoll({
56
+ bot,
57
+ chatId: ctx.chatId,
58
+ question: parsed.question,
59
+ options: parsed.options.slice(0, 10)
60
+ });
61
+ } catch {
62
+ log.warn({ dataPreview: ctx.data.slice(0, 80) }, "Invalid poll action payload");
63
+ }
64
+ break;
65
+ default: log.debug({ action: ctx.action }, "Unhandled Telegram message action");
66
+ }
67
+ }
68
+ //#endregion
69
+ export { bindTelegramMessageActionAccountManager, handleTelegramChannelAction };
70
+
71
+ //# sourceMappingURL=message-actions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-actions.js","names":[],"sources":["../../../../../extensions/telegram/src/actions/message-actions.ts"],"sourcesContent":["import type { ChannelMessageActionContext } from '@xopcai/xopc/channels/plugin-types.js';\nimport type { TelegramAccountManager } from '../account-manager.js';\nimport {\n telegramDeleteMessage,\n telegramEditMessage,\n telegramSendPoll,\n telegramSetReaction,\n} from '../telegram-actions.js';\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\n\nconst log = createLogger('TelegramMessageActions');\n\nlet accountManagerRef: TelegramAccountManager | null = null;\n\nexport function bindTelegramMessageActionAccountManager(manager: TelegramAccountManager): void {\n accountManagerRef = manager;\n}\n\nexport async function handleTelegramChannelAction(ctx: ChannelMessageActionContext): Promise<void> {\n const manager = accountManagerRef;\n if (!manager) {\n log.warn('Telegram message actions: account manager not bound');\n return;\n }\n\n const bot = manager.getBot(ctx.accountId);\n if (!bot) {\n log.warn({ accountId: ctx.accountId }, 'Telegram message actions: bot unavailable');\n return;\n }\n\n const messageId = Number.parseInt(ctx.messageId, 10);\n if (!Number.isFinite(messageId)) {\n return;\n }\n\n switch (ctx.action) {\n case 'react': {\n const emoji = ctx.data?.trim() || '👍';\n await telegramSetReaction({ bot, chatId: ctx.chatId, messageId, emoji });\n break;\n }\n case 'edit': {\n const text = ctx.data?.trim();\n if (text) {\n await telegramEditMessage({ bot, chatId: ctx.chatId, messageId, text });\n }\n break;\n }\n case 'delete':\n await telegramDeleteMessage({ bot, chatId: ctx.chatId, messageId });\n break;\n case 'poll': {\n try {\n const parsed = JSON.parse(ctx.data) as { question?: string; options?: string[] };\n if (parsed.question && Array.isArray(parsed.options) && parsed.options.length >= 2) {\n await telegramSendPoll({\n bot,\n chatId: ctx.chatId,\n question: parsed.question,\n options: parsed.options.slice(0, 10),\n });\n }\n } catch {\n log.warn({ dataPreview: ctx.data.slice(0, 80) }, 'Invalid poll action payload');\n }\n break;\n }\n default:\n log.debug({ action: ctx.action }, 'Unhandled Telegram message action');\n }\n}\n"],"mappings":";;;;aAQ4D;AAE5D,MAAM,MAAM,aAAa,yBAAyB;AAElD,IAAI,oBAAmD;AAEvD,SAAgB,wCAAwC,SAAuC;AAC7F,qBAAoB;;AAGtB,eAAsB,4BAA4B,KAAiD;CACjG,MAAM,UAAU;AAChB,KAAI,CAAC,SAAS;AACZ,MAAI,KAAK,sDAAsD;AAC/D;;CAGF,MAAM,MAAM,QAAQ,OAAO,IAAI,UAAU;AACzC,KAAI,CAAC,KAAK;AACR,MAAI,KAAK,EAAE,WAAW,IAAI,WAAW,EAAE,4CAA4C;AACnF;;CAGF,MAAM,YAAY,OAAO,SAAS,IAAI,WAAW,GAAG;AACpD,KAAI,CAAC,OAAO,SAAS,UAAU,CAC7B;AAGF,SAAQ,IAAI,QAAZ;EACE,KAAK,SAAS;GACZ,MAAM,QAAQ,IAAI,MAAM,MAAM,IAAI;AAClC,SAAM,oBAAoB;IAAE;IAAK,QAAQ,IAAI;IAAQ;IAAW;IAAO,CAAC;AACxE;;EAEF,KAAK,QAAQ;GACX,MAAM,OAAO,IAAI,MAAM,MAAM;AAC7B,OAAI,KACF,OAAM,oBAAoB;IAAE;IAAK,QAAQ,IAAI;IAAQ;IAAW;IAAM,CAAC;AAEzE;;EAEF,KAAK;AACH,SAAM,sBAAsB;IAAE;IAAK,QAAQ,IAAI;IAAQ;IAAW,CAAC;AACnE;EACF,KAAK;AACH,OAAI;IACF,MAAM,SAAS,KAAK,MAAM,IAAI,KAAK;AACnC,QAAI,OAAO,YAAY,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,QAAQ,UAAU,EAC/E,OAAM,iBAAiB;KACrB;KACA,QAAQ,IAAI;KACZ,UAAU,OAAO;KACjB,SAAS,OAAO,QAAQ,MAAM,GAAG,GAAG;KACrC,CAAC;WAEE;AACN,QAAI,KAAK,EAAE,aAAa,IAAI,KAAK,MAAM,GAAG,GAAG,EAAE,EAAE,8BAA8B;;AAEjF;EAEF,QACE,KAAI,MAAM,EAAE,QAAQ,IAAI,QAAQ,EAAE,oCAAoC"}
@@ -15,13 +15,21 @@ function createTelegramConfigAdapter(options) {
15
15
  name: account.name,
16
16
  enabled: account.enabled !== false,
17
17
  botToken: account.botToken || "",
18
+ tokenFile: account.tokenFile,
18
19
  apiRoot: account.apiRoot,
20
+ proxy: account.proxy,
19
21
  dmPolicy: account.dmPolicy,
20
22
  groupPolicy: account.groupPolicy,
21
23
  allowFrom: account.allowFrom,
22
24
  groupAllowFrom: account.groupAllowFrom,
23
25
  requireMention: account.requireMention,
24
- streamMode: account.streamMode
26
+ replyToMode: account.replyToMode,
27
+ streaming: account.streaming,
28
+ pollingStallThresholdMs: account.pollingStallThresholdMs,
29
+ reactionLevel: account.reactionLevel,
30
+ reactionNotifications: account.reactionNotifications,
31
+ ackReaction: account.ackReaction,
32
+ groups: account.groups
25
33
  };
26
34
  },
27
35
  isEnabled: (account) => account.enabled !== false,
@@ -1 +1 @@
1
- {"version":3,"file":"config-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/config-adapter.ts"],"sourcesContent":["import type { ChannelAccountSnapshot, ChannelConfigAdapter } from '@xopcai/xopc/channels/plugin-types.js';\nimport type { TelegramAccountManager } from '../account-manager.js';\nimport type { TelegramResolvedAccount } from './types.js';\n\nexport function createTelegramConfigAdapter(options: {\n accountManager: TelegramAccountManager;\n}): ChannelConfigAdapter<TelegramResolvedAccount> {\n const { accountManager } = options;\n\n return {\n listAccountIds: (_cfg) => accountManager.getAllAccounts().map((a) => a.accountId),\n resolveAccount: (_cfg, accountId = 'default') => {\n const account = accountManager.getAccount(accountId);\n if (!account) return { accountId, enabled: false, botToken: '' };\n return {\n accountId: account.accountId,\n name: account.name,\n enabled: account.enabled !== false,\n botToken: account.botToken || '',\n apiRoot: account.apiRoot,\n dmPolicy: account.dmPolicy as TelegramResolvedAccount['dmPolicy'],\n groupPolicy: account.groupPolicy as TelegramResolvedAccount['groupPolicy'],\n allowFrom: account.allowFrom,\n groupAllowFrom: account.groupAllowFrom,\n requireMention: (account as { requireMention?: boolean }).requireMention,\n streamMode: account.streamMode as TelegramResolvedAccount['streamMode'],\n };\n },\n isEnabled: (account) => account.enabled !== false,\n disabledReason: (account) => {\n if (account.enabled === false) return 'Account disabled';\n if (!account.botToken) return 'No token configured';\n return '';\n },\n isConfigured: async (account) => !!account.botToken,\n describeAccount: (account) => {\n const status = accountManager.getStatus(account.accountId);\n return {\n accountId: account.accountId,\n channelId: 'telegram',\n enabled: account.enabled !== false,\n configured: !!account.botToken,\n status: status?.running ? 'running' : 'stopped',\n } as ChannelAccountSnapshot;\n },\n };\n}\n"],"mappings":";AAIA,SAAgB,4BAA4B,SAEM;CAChD,MAAM,EAAE,mBAAmB;AAE3B,QAAO;EACL,iBAAiB,SAAS,eAAe,gBAAgB,CAAC,KAAK,MAAM,EAAE,UAAU;EACjF,iBAAiB,MAAM,YAAY,cAAc;GAC/C,MAAM,UAAU,eAAe,WAAW,UAAU;AACpD,OAAI,CAAC,QAAS,QAAO;IAAE;IAAW,SAAS;IAAO,UAAU;IAAI;AAChE,UAAO;IACL,WAAW,QAAQ;IACnB,MAAM,QAAQ;IACd,SAAS,QAAQ,YAAY;IAC7B,UAAU,QAAQ,YAAY;IAC9B,SAAS,QAAQ;IACjB,UAAU,QAAQ;IAClB,aAAa,QAAQ;IACrB,WAAW,QAAQ;IACnB,gBAAgB,QAAQ;IACxB,gBAAiB,QAAyC;IAC1D,YAAY,QAAQ;IACrB;;EAEH,YAAY,YAAY,QAAQ,YAAY;EAC5C,iBAAiB,YAAY;AAC3B,OAAI,QAAQ,YAAY,MAAO,QAAO;AACtC,OAAI,CAAC,QAAQ,SAAU,QAAO;AAC9B,UAAO;;EAET,cAAc,OAAO,YAAY,CAAC,CAAC,QAAQ;EAC3C,kBAAkB,YAAY;GAC5B,MAAM,SAAS,eAAe,UAAU,QAAQ,UAAU;AAC1D,UAAO;IACL,WAAW,QAAQ;IACnB,WAAW;IACX,SAAS,QAAQ,YAAY;IAC7B,YAAY,CAAC,CAAC,QAAQ;IACtB,QAAQ,QAAQ,UAAU,YAAY;IACvC;;EAEJ"}
1
+ {"version":3,"file":"config-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/config-adapter.ts"],"sourcesContent":["import type { ChannelAccountSnapshot, ChannelConfigAdapter } from '@xopcai/xopc/channels/plugin-types.js';\nimport type { TelegramAccountManager } from '../account-manager.js';\nimport type { TelegramResolvedAccount } from './types.js';\n\nexport function createTelegramConfigAdapter(options: {\n accountManager: TelegramAccountManager;\n}): ChannelConfigAdapter<TelegramResolvedAccount> {\n const { accountManager } = options;\n\n return {\n listAccountIds: (_cfg) => accountManager.getAllAccounts().map((a) => a.accountId),\n resolveAccount: (_cfg, accountId = 'default') => {\n const account = accountManager.getAccount(accountId);\n if (!account) return { accountId, enabled: false, botToken: '' };\n return {\n accountId: account.accountId,\n name: account.name,\n enabled: account.enabled !== false,\n botToken: account.botToken || '',\n tokenFile: account.tokenFile,\n apiRoot: account.apiRoot,\n proxy: account.proxy,\n dmPolicy: account.dmPolicy as TelegramResolvedAccount['dmPolicy'],\n groupPolicy: account.groupPolicy as TelegramResolvedAccount['groupPolicy'],\n allowFrom: account.allowFrom,\n groupAllowFrom: account.groupAllowFrom,\n requireMention: (account as { requireMention?: boolean }).requireMention,\n replyToMode: account.replyToMode as TelegramResolvedAccount['replyToMode'],\n streaming: account.streaming as TelegramResolvedAccount['streaming'],\n pollingStallThresholdMs: account.pollingStallThresholdMs,\n reactionLevel: account.reactionLevel as TelegramResolvedAccount['reactionLevel'],\n reactionNotifications: account.reactionNotifications as TelegramResolvedAccount['reactionNotifications'],\n ackReaction: account.ackReaction,\n groups: account.groups,\n };\n },\n isEnabled: (account) => account.enabled !== false,\n disabledReason: (account) => {\n if (account.enabled === false) return 'Account disabled';\n if (!account.botToken) return 'No token configured';\n return '';\n },\n isConfigured: async (account) => !!account.botToken,\n describeAccount: (account) => {\n const status = accountManager.getStatus(account.accountId);\n return {\n accountId: account.accountId,\n channelId: 'telegram',\n enabled: account.enabled !== false,\n configured: !!account.botToken,\n status: status?.running ? 'running' : 'stopped',\n } as ChannelAccountSnapshot;\n },\n };\n}\n"],"mappings":";AAIA,SAAgB,4BAA4B,SAEM;CAChD,MAAM,EAAE,mBAAmB;AAE3B,QAAO;EACL,iBAAiB,SAAS,eAAe,gBAAgB,CAAC,KAAK,MAAM,EAAE,UAAU;EACjF,iBAAiB,MAAM,YAAY,cAAc;GAC/C,MAAM,UAAU,eAAe,WAAW,UAAU;AACpD,OAAI,CAAC,QAAS,QAAO;IAAE;IAAW,SAAS;IAAO,UAAU;IAAI;AAChE,UAAO;IACL,WAAW,QAAQ;IACnB,MAAM,QAAQ;IACd,SAAS,QAAQ,YAAY;IAC7B,UAAU,QAAQ,YAAY;IAC9B,WAAW,QAAQ;IACnB,SAAS,QAAQ;IACjB,OAAO,QAAQ;IACf,UAAU,QAAQ;IAClB,aAAa,QAAQ;IACrB,WAAW,QAAQ;IACnB,gBAAgB,QAAQ;IACxB,gBAAiB,QAAyC;IAC1D,aAAa,QAAQ;IACrB,WAAW,QAAQ;IACnB,yBAAyB,QAAQ;IACjC,eAAe,QAAQ;IACvB,uBAAuB,QAAQ;IAC/B,aAAa,QAAQ;IACrB,QAAQ,QAAQ;IACjB;;EAEH,YAAY,YAAY,QAAQ,YAAY;EAC5C,iBAAiB,YAAY;AAC3B,OAAI,QAAQ,YAAY,MAAO,QAAO;AACtC,OAAI,CAAC,QAAQ,SAAU,QAAO;AAC9B,UAAO;;EAET,cAAc,OAAO,YAAY,CAAC,CAAC,QAAQ;EAC3C,kBAAkB,YAAY;GAC5B,MAAM,SAAS,eAAe,UAAU,QAAQ,UAAU;AAC1D,UAAO;IACL,WAAW,QAAQ;IACnB,WAAW;IACX,SAAS,QAAQ,YAAY;IAC7B,YAAY,CAAC,CAAC,QAAQ;IACtB,QAAQ,QAAQ,UAAU,YAAY;IACvC;;EAEJ"}
@@ -13,7 +13,7 @@ const telegramConfigSurface = { buildConfigSurface(cfg) {
13
13
  dmPolicy: telegram?.dmPolicy || "pairing",
14
14
  groupPolicy: telegram?.groupPolicy || "open",
15
15
  replyToMode: telegram?.replyToMode || "off",
16
- streamMode: telegram?.streamMode || "partial",
16
+ streamMode: (accounts?.default?.streaming)?.mode || (telegram?.streaming)?.mode || "partial",
17
17
  historyLimit: telegram?.historyLimit || 50,
18
18
  textChunkLimit: telegram?.textChunkLimit || 4e3,
19
19
  proxy: telegram?.proxy || "",
@@ -1 +1 @@
1
- {"version":3,"file":"config-surface.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/config-surface.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type { ChannelConfigSurfaceAdapter } from '@xopcai/xopc/channels/plugins/types.adapters.js';\n\nexport const telegramConfigSurface: ChannelConfigSurfaceAdapter = {\n buildConfigSurface(cfg: Config): Record<string, unknown> {\n const telegram = cfg.channels?.telegram as Record<string, unknown> | undefined;\n const accounts = telegram?.accounts as Record<string, { botToken?: string }> | undefined;\n const defTok =\n accounts?.default && typeof accounts.default === 'object'\n ? accounts.default.botToken\n : undefined;\n return {\n enabled: telegram?.enabled,\n // Send the real token to the authenticated settings UI.\n // The web UI is responsible for masking it by default.\n botToken: typeof defTok === 'string' ? defTok : '',\n allowFrom: telegram?.allowFrom || [],\n groupAllowFrom: telegram?.groupAllowFrom || [],\n apiRoot: telegram?.apiRoot || '',\n debug: telegram?.debug || false,\n dmPolicy: telegram?.dmPolicy || 'pairing',\n groupPolicy: telegram?.groupPolicy || 'open',\n replyToMode: telegram?.replyToMode || 'off',\n streamMode: telegram?.streamMode || 'partial',\n historyLimit: telegram?.historyLimit || 50,\n textChunkLimit: telegram?.textChunkLimit || 4000,\n proxy: telegram?.proxy || '',\n accounts: telegram?.accounts || {},\n };\n },\n};\n"],"mappings":";AAGA,MAAa,wBAAqD,EAChE,mBAAmB,KAAsC;CACvD,MAAM,WAAW,IAAI,UAAU;CAC/B,MAAM,WAAW,UAAU;CAC3B,MAAM,SACJ,UAAU,WAAW,OAAO,SAAS,YAAY,WAC7C,SAAS,QAAQ,WACjB,KAAA;AACN,QAAO;EACL,SAAS,UAAU;EAGnB,UAAU,OAAO,WAAW,WAAW,SAAS;EAChD,WAAW,UAAU,aAAa,EAAE;EACpC,gBAAgB,UAAU,kBAAkB,EAAE;EAC9C,SAAS,UAAU,WAAW;EAC9B,OAAO,UAAU,SAAS;EAC1B,UAAU,UAAU,YAAY;EAChC,aAAa,UAAU,eAAe;EACtC,aAAa,UAAU,eAAe;EACtC,YAAY,UAAU,cAAc;EACpC,cAAc,UAAU,gBAAgB;EACxC,gBAAgB,UAAU,kBAAkB;EAC5C,OAAO,UAAU,SAAS;EAC1B,UAAU,UAAU,YAAY,EAAE;EACnC;GAEJ"}
1
+ {"version":3,"file":"config-surface.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/config-surface.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type { ChannelConfigSurfaceAdapter } from '@xopcai/xopc/channels/plugins/types.adapters.js';\n\nexport const telegramConfigSurface: ChannelConfigSurfaceAdapter = {\n buildConfigSurface(cfg: Config): Record<string, unknown> {\n const telegram = cfg.channels?.telegram as Record<string, unknown> | undefined;\n const accounts = telegram?.accounts as\n | Record<string, { botToken?: string; streaming?: { mode?: string } }>\n | undefined;\n const defTok =\n accounts?.default && typeof accounts.default === 'object'\n ? accounts.default.botToken\n : undefined;\n return {\n enabled: telegram?.enabled,\n // Send the real token to the authenticated settings UI.\n // The web UI is responsible for masking it by default.\n botToken: typeof defTok === 'string' ? defTok : '',\n allowFrom: telegram?.allowFrom || [],\n groupAllowFrom: telegram?.groupAllowFrom || [],\n apiRoot: telegram?.apiRoot || '',\n debug: telegram?.debug || false,\n dmPolicy: telegram?.dmPolicy || 'pairing',\n groupPolicy: telegram?.groupPolicy || 'open',\n replyToMode: telegram?.replyToMode || 'off',\n streamMode:\n (accounts?.default?.streaming as { mode?: string } | undefined)?.mode ||\n (telegram?.streaming as { mode?: string } | undefined)?.mode || 'partial',\n historyLimit: telegram?.historyLimit || 50,\n textChunkLimit: telegram?.textChunkLimit || 4000,\n proxy: telegram?.proxy || '',\n accounts: telegram?.accounts || {},\n };\n },\n};\n"],"mappings":";AAGA,MAAa,wBAAqD,EAChE,mBAAmB,KAAsC;CACvD,MAAM,WAAW,IAAI,UAAU;CAC/B,MAAM,WAAW,UAAU;CAG3B,MAAM,SACJ,UAAU,WAAW,OAAO,SAAS,YAAY,WAC7C,SAAS,QAAQ,WACjB,KAAA;AACN,QAAO;EACL,SAAS,UAAU;EAGnB,UAAU,OAAO,WAAW,WAAW,SAAS;EAChD,WAAW,UAAU,aAAa,EAAE;EACpC,gBAAgB,UAAU,kBAAkB,EAAE;EAC9C,SAAS,UAAU,WAAW;EAC9B,OAAO,UAAU,SAAS;EAC1B,UAAU,UAAU,YAAY;EAChC,aAAa,UAAU,eAAe;EACtC,aAAa,UAAU,eAAe;EACtC,aACG,UAAU,SAAS,YAA6C,SAChE,UAAU,YAA6C,QAAQ;EAClE,cAAc,UAAU,gBAAgB;EACxC,gBAAgB,UAAU,kBAAkB;EAC5C,OAAO,UAAU,SAAS;EAC1B,UAAU,UAAU,YAAY,EAAE;EACnC;GAEJ"}
@@ -3,8 +3,9 @@
3
3
  */
4
4
  import type { ChannelOutboundContext, ChannelOutboundPayloadContext, OutboundDeliveryResult } from '@xopcai/xopc/channels/plugin-types.js';
5
5
  import type { ChannelSendOptions, ChannelSendResult } from '@xopcai/xopc/channels/channel-domain.js';
6
+ import type { TelegramAccountManager } from '../account-manager.js';
6
7
  export declare function telegramTextChunker(text: string, limit: number): string[];
7
- export declare function createTelegramOutboundSendMethods(send: (options: ChannelSendOptions) => Promise<ChannelSendResult>): {
8
+ export declare function createTelegramOutboundSendMethods(send: (options: ChannelSendOptions) => Promise<ChannelSendResult>, accountManager?: TelegramAccountManager): {
8
9
  sendText: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;
9
10
  sendMedia: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;
10
11
  sendPayload: (ctx: ChannelOutboundPayloadContext) => Promise<OutboundDeliveryResult>;
@@ -1,4 +1,5 @@
1
1
  import { TELEGRAM_CHANNEL_DEFAULTS } from "../plugin-defaults.js";
2
+ import { telegramReplyTracker } from "../reply-params.js";
2
3
  //#region extensions/telegram/src/adapters/outbound-adapter.ts
3
4
  function telegramTextChunker(text, limit) {
4
5
  const chunks = [];
@@ -19,7 +20,20 @@ function toDelivery(r) {
19
20
  error: r.error
20
21
  };
21
22
  }
22
- function createTelegramOutboundSendMethods(send) {
23
+ function createTelegramOutboundSendMethods(send, accountManager) {
24
+ const resolveReply = (ctx) => {
25
+ if (ctx.replyToId != null && String(ctx.replyToId).trim()) return String(ctx.replyToId);
26
+ const accountId = ctx.accountId ?? "default";
27
+ const account = accountManager?.getAccount(accountId);
28
+ const meta = ctx.outboundMetadata;
29
+ const inboundMessageId = meta && typeof meta.inboundMessageId === "string" ? meta.inboundMessageId : void 0;
30
+ return telegramReplyTracker.resolveReplyToMessageId({
31
+ mode: account?.replyToMode,
32
+ inboundMessageId,
33
+ accountId,
34
+ chatId: ctx.to
35
+ });
36
+ };
23
37
  return {
24
38
  sendText: async (ctx) => {
25
39
  return toDelivery(await send({
@@ -27,7 +41,7 @@ function createTelegramOutboundSendMethods(send) {
27
41
  content: ctx.text,
28
42
  accountId: ctx.accountId,
29
43
  threadId: ctx.threadId?.toString(),
30
- replyToMessageId: ctx.replyToId?.toString(),
44
+ replyToMessageId: resolveReply(ctx),
31
45
  silent: ctx.silent
32
46
  }));
33
47
  },
@@ -39,7 +53,7 @@ function createTelegramOutboundSendMethods(send) {
39
53
  type: payload.type,
40
54
  accountId: ctx.accountId,
41
55
  threadId: ctx.threadId?.toString(),
42
- replyToMessageId: ctx.replyToId?.toString(),
56
+ replyToMessageId: resolveReply(ctx),
43
57
  silent: ctx.silent,
44
58
  mediaUrl: ctx.mediaUrl,
45
59
  audioAsVoice: ctx.audioAsVoice
@@ -58,7 +72,7 @@ function createTelegramOutboundSendMethods(send) {
58
72
  content: ctx.text ?? "",
59
73
  accountId: ctx.accountId,
60
74
  threadId: ctx.threadId?.toString(),
61
- replyToMessageId: ctx.replyToId?.toString(),
75
+ replyToMessageId: resolveReply(ctx),
62
76
  silent: ctx.silent,
63
77
  mediaUrl,
64
78
  mediaType: ctx.mediaType,
@@ -1 +1 @@
1
- {"version":3,"file":"outbound-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/outbound-adapter.ts"],"sourcesContent":["/**\n * Telegram outbound adapter: text chunker + sendText / sendMedia / sendPayload.\n */\n\nimport type {\n ChannelOutboundContext,\n ChannelOutboundPayloadContext,\n OutboundDeliveryResult,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport type { ChannelSendOptions, ChannelSendResult } from '@xopcai/xopc/channels/channel-domain.js';\nimport type { OutboundMessage } from '@xopcai/xopc/channels/transport-types.js';\nimport { TELEGRAM_CHANNEL_DEFAULTS } from '../plugin-defaults.js';\n\nexport function telegramTextChunker(text: string, limit: number): string[] {\n const chunks: string[] = [];\n const lines = text.split('\\n');\n let current = '';\n for (const line of lines) {\n if ((current + '\\n' + line).length > limit) {\n if (current) chunks.push(current);\n current = line;\n } else {\n current = current ? current + '\\n' + line : line;\n }\n }\n if (current) chunks.push(current);\n return chunks;\n}\n\nfunction toDelivery(r: ChannelSendResult): OutboundDeliveryResult {\n return {\n messageId: r.messageId,\n chatId: r.chatId,\n success: r.success,\n error: r.error,\n };\n}\n\nexport function createTelegramOutboundSendMethods(\n send: (options: ChannelSendOptions) => Promise<ChannelSendResult>,\n): {\n sendText: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;\n sendMedia: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;\n sendPayload: (ctx: ChannelOutboundPayloadContext) => Promise<OutboundDeliveryResult>;\n} {\n return {\n sendText: async (ctx: ChannelOutboundContext) => {\n const result = await send({\n chatId: ctx.to,\n content: ctx.text,\n accountId: ctx.accountId,\n threadId: ctx.threadId?.toString(),\n replyToMessageId: ctx.replyToId?.toString(),\n silent: ctx.silent,\n });\n return toDelivery(result);\n },\n\n sendPayload: async (ctx: ChannelOutboundContext & { payload: unknown }) => {\n const payload = ctx.payload as OutboundMessage;\n const result = await send({\n chatId: ctx.to,\n content: ctx.text,\n type: payload.type,\n accountId: ctx.accountId,\n threadId: ctx.threadId?.toString(),\n replyToMessageId: ctx.replyToId?.toString(),\n silent: ctx.silent,\n mediaUrl: ctx.mediaUrl,\n audioAsVoice: ctx.audioAsVoice,\n });\n return toDelivery(result);\n },\n\n sendMedia: async (ctx: ChannelOutboundContext) => {\n const mediaUrl = ctx.mediaUrl?.trim();\n if (!mediaUrl) {\n return { messageId: '', chatId: ctx.to, success: false, error: 'No media URL' };\n }\n const result = await send({\n chatId: ctx.to,\n content: ctx.text ?? '',\n accountId: ctx.accountId,\n threadId: ctx.threadId?.toString(),\n replyToMessageId: ctx.replyToId?.toString(),\n silent: ctx.silent,\n mediaUrl,\n mediaType: ctx.mediaType,\n audioAsVoice: ctx.audioAsVoice,\n });\n return toDelivery(result);\n },\n };\n}\n\nexport const TELEGRAM_OUTBOUND_DEFAULTS = {\n textChunkLimit: TELEGRAM_CHANNEL_DEFAULTS.outbound.textChunkLimit,\n} as const;\n"],"mappings":";;AAaA,SAAgB,oBAAoB,MAAc,OAAyB;CACzE,MAAM,SAAmB,EAAE;CAC3B,MAAM,QAAQ,KAAK,MAAM,KAAK;CAC9B,IAAI,UAAU;AACd,MAAK,MAAM,QAAQ,MACjB,MAAK,UAAU,OAAO,MAAM,SAAS,OAAO;AAC1C,MAAI,QAAS,QAAO,KAAK,QAAQ;AACjC,YAAU;OAEV,WAAU,UAAU,UAAU,OAAO,OAAO;AAGhD,KAAI,QAAS,QAAO,KAAK,QAAQ;AACjC,QAAO;;AAGT,SAAS,WAAW,GAA8C;AAChE,QAAO;EACL,WAAW,EAAE;EACb,QAAQ,EAAE;EACV,SAAS,EAAE;EACX,OAAO,EAAE;EACV;;AAGH,SAAgB,kCACd,MAKA;AACA,QAAO;EACL,UAAU,OAAO,QAAgC;AAS/C,UAAO,WAAW,MARG,KAAK;IACxB,QAAQ,IAAI;IACZ,SAAS,IAAI;IACb,WAAW,IAAI;IACf,UAAU,IAAI,UAAU,UAAU;IAClC,kBAAkB,IAAI,WAAW,UAAU;IAC3C,QAAQ,IAAI;IACb,CAAC,CACuB;;EAG3B,aAAa,OAAO,QAAuD;GACzE,MAAM,UAAU,IAAI;AAYpB,UAAO,WAAW,MAXG,KAAK;IACxB,QAAQ,IAAI;IACZ,SAAS,IAAI;IACb,MAAM,QAAQ;IACd,WAAW,IAAI;IACf,UAAU,IAAI,UAAU,UAAU;IAClC,kBAAkB,IAAI,WAAW,UAAU;IAC3C,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,cAAc,IAAI;IACnB,CAAC,CACuB;;EAG3B,WAAW,OAAO,QAAgC;GAChD,MAAM,WAAW,IAAI,UAAU,MAAM;AACrC,OAAI,CAAC,SACH,QAAO;IAAE,WAAW;IAAI,QAAQ,IAAI;IAAI,SAAS;IAAO,OAAO;IAAgB;AAajF,UAAO,WAAW,MAXG,KAAK;IACxB,QAAQ,IAAI;IACZ,SAAS,IAAI,QAAQ;IACrB,WAAW,IAAI;IACf,UAAU,IAAI,UAAU,UAAU;IAClC,kBAAkB,IAAI,WAAW,UAAU;IAC3C,QAAQ,IAAI;IACZ;IACA,WAAW,IAAI;IACf,cAAc,IAAI;IACnB,CAAC,CACuB;;EAE5B;;AAGH,MAAa,6BAA6B,EACxC,gBAAgB,0BAA0B,SAAS,gBACpD"}
1
+ {"version":3,"file":"outbound-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/outbound-adapter.ts"],"sourcesContent":["/**\n * Telegram outbound adapter: text chunker + sendText / sendMedia / sendPayload.\n */\n\nimport type {\n ChannelOutboundContext,\n ChannelOutboundPayloadContext,\n OutboundDeliveryResult,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport type { ChannelSendOptions, ChannelSendResult } from '@xopcai/xopc/channels/channel-domain.js';\nimport type { OutboundMessage } from '@xopcai/xopc/channels/transport-types.js';\nimport type { TelegramAccountManager } from '../account-manager.js';\nimport { telegramReplyTracker } from '../reply-params.js';\nimport { TELEGRAM_CHANNEL_DEFAULTS } from '../plugin-defaults.js';\n\nexport function telegramTextChunker(text: string, limit: number): string[] {\n const chunks: string[] = [];\n const lines = text.split('\\n');\n let current = '';\n for (const line of lines) {\n if ((current + '\\n' + line).length > limit) {\n if (current) chunks.push(current);\n current = line;\n } else {\n current = current ? current + '\\n' + line : line;\n }\n }\n if (current) chunks.push(current);\n return chunks;\n}\n\nfunction toDelivery(r: ChannelSendResult): OutboundDeliveryResult {\n return {\n messageId: r.messageId,\n chatId: r.chatId,\n success: r.success,\n error: r.error,\n };\n}\n\nexport function createTelegramOutboundSendMethods(\n send: (options: ChannelSendOptions) => Promise<ChannelSendResult>,\n accountManager?: TelegramAccountManager,\n): {\n sendText: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;\n sendMedia: (ctx: ChannelOutboundContext) => Promise<OutboundDeliveryResult>;\n sendPayload: (ctx: ChannelOutboundPayloadContext) => Promise<OutboundDeliveryResult>;\n} {\n const resolveReply = (ctx: ChannelOutboundContext): string | undefined => {\n if (ctx.replyToId != null && String(ctx.replyToId).trim()) {\n return String(ctx.replyToId);\n }\n const accountId = ctx.accountId ?? 'default';\n const account = accountManager?.getAccount(accountId);\n const meta = ctx.outboundMetadata;\n const inboundMessageId =\n meta && typeof meta.inboundMessageId === 'string' ? meta.inboundMessageId : undefined;\n return telegramReplyTracker.resolveReplyToMessageId({\n mode: account?.replyToMode,\n inboundMessageId,\n accountId,\n chatId: ctx.to,\n });\n };\n\n return {\n sendText: async (ctx: ChannelOutboundContext) => {\n const result = await send({\n chatId: ctx.to,\n content: ctx.text,\n accountId: ctx.accountId,\n threadId: ctx.threadId?.toString(),\n replyToMessageId: resolveReply(ctx),\n silent: ctx.silent,\n });\n return toDelivery(result);\n },\n\n sendPayload: async (ctx: ChannelOutboundContext & { payload: unknown }) => {\n const payload = ctx.payload as OutboundMessage;\n const result = await send({\n chatId: ctx.to,\n content: ctx.text,\n type: payload.type,\n accountId: ctx.accountId,\n threadId: ctx.threadId?.toString(),\n replyToMessageId: resolveReply(ctx),\n silent: ctx.silent,\n mediaUrl: ctx.mediaUrl,\n audioAsVoice: ctx.audioAsVoice,\n });\n return toDelivery(result);\n },\n\n sendMedia: async (ctx: ChannelOutboundContext) => {\n const mediaUrl = ctx.mediaUrl?.trim();\n if (!mediaUrl) {\n return { messageId: '', chatId: ctx.to, success: false, error: 'No media URL' };\n }\n const result = await send({\n chatId: ctx.to,\n content: ctx.text ?? '',\n accountId: ctx.accountId,\n threadId: ctx.threadId?.toString(),\n replyToMessageId: resolveReply(ctx),\n silent: ctx.silent,\n mediaUrl,\n mediaType: ctx.mediaType,\n audioAsVoice: ctx.audioAsVoice,\n });\n return toDelivery(result);\n },\n };\n}\n\nexport const TELEGRAM_OUTBOUND_DEFAULTS = {\n textChunkLimit: TELEGRAM_CHANNEL_DEFAULTS.outbound.textChunkLimit,\n} as const;\n"],"mappings":";;;AAeA,SAAgB,oBAAoB,MAAc,OAAyB;CACzE,MAAM,SAAmB,EAAE;CAC3B,MAAM,QAAQ,KAAK,MAAM,KAAK;CAC9B,IAAI,UAAU;AACd,MAAK,MAAM,QAAQ,MACjB,MAAK,UAAU,OAAO,MAAM,SAAS,OAAO;AAC1C,MAAI,QAAS,QAAO,KAAK,QAAQ;AACjC,YAAU;OAEV,WAAU,UAAU,UAAU,OAAO,OAAO;AAGhD,KAAI,QAAS,QAAO,KAAK,QAAQ;AACjC,QAAO;;AAGT,SAAS,WAAW,GAA8C;AAChE,QAAO;EACL,WAAW,EAAE;EACb,QAAQ,EAAE;EACV,SAAS,EAAE;EACX,OAAO,EAAE;EACV;;AAGH,SAAgB,kCACd,MACA,gBAKA;CACA,MAAM,gBAAgB,QAAoD;AACxE,MAAI,IAAI,aAAa,QAAQ,OAAO,IAAI,UAAU,CAAC,MAAM,CACvD,QAAO,OAAO,IAAI,UAAU;EAE9B,MAAM,YAAY,IAAI,aAAa;EACnC,MAAM,UAAU,gBAAgB,WAAW,UAAU;EACrD,MAAM,OAAO,IAAI;EACjB,MAAM,mBACJ,QAAQ,OAAO,KAAK,qBAAqB,WAAW,KAAK,mBAAmB,KAAA;AAC9E,SAAO,qBAAqB,wBAAwB;GAClD,MAAM,SAAS;GACf;GACA;GACA,QAAQ,IAAI;GACb,CAAC;;AAGJ,QAAO;EACL,UAAU,OAAO,QAAgC;AAS/C,UAAO,WAAW,MARG,KAAK;IACxB,QAAQ,IAAI;IACZ,SAAS,IAAI;IACb,WAAW,IAAI;IACf,UAAU,IAAI,UAAU,UAAU;IAClC,kBAAkB,aAAa,IAAI;IACnC,QAAQ,IAAI;IACb,CAAC,CACuB;;EAG3B,aAAa,OAAO,QAAuD;GACzE,MAAM,UAAU,IAAI;AAYpB,UAAO,WAAW,MAXG,KAAK;IACxB,QAAQ,IAAI;IACZ,SAAS,IAAI;IACb,MAAM,QAAQ;IACd,WAAW,IAAI;IACf,UAAU,IAAI,UAAU,UAAU;IAClC,kBAAkB,aAAa,IAAI;IACnC,QAAQ,IAAI;IACZ,UAAU,IAAI;IACd,cAAc,IAAI;IACnB,CAAC,CACuB;;EAG3B,WAAW,OAAO,QAAgC;GAChD,MAAM,WAAW,IAAI,UAAU,MAAM;AACrC,OAAI,CAAC,SACH,QAAO;IAAE,WAAW;IAAI,QAAQ,IAAI;IAAI,SAAS;IAAO,OAAO;IAAgB;AAajF,UAAO,WAAW,MAXG,KAAK;IACxB,QAAQ,IAAI;IACZ,SAAS,IAAI,QAAQ;IACrB,WAAW,IAAI;IACf,UAAU,IAAI,UAAU,UAAU;IAClC,kBAAkB,aAAa,IAAI;IACnC,QAAQ,IAAI;IACZ;IACA,WAAW,IAAI;IACf,cAAc,IAAI;IACnB,CAAC,CACuB;;EAE5B;;AAGH,MAAa,6BAA6B,EACxC,gBAAgB,0BAA0B,SAAS,gBACpD"}
@@ -24,7 +24,8 @@ function createTelegramSecurityAdapter() {
24
24
  dmPolicy: account.dmPolicy,
25
25
  groupPolicy: account.groupPolicy,
26
26
  allowFrom,
27
- groupAllowFrom: account.groupAllowFrom
27
+ groupAllowFrom: account.groupAllowFrom,
28
+ allowNameMatching: true
28
29
  });
29
30
  return {
30
31
  allowed: result.allowed,
@@ -1 +1 @@
1
- {"version":3,"file":"security-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/security-adapter.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type {\n ChannelSecurityAdapter,\n ChannelSecurityContext,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport { readAllowFromIdsSync, resolveStandardAllowFromPath } from '@xopcai/xopc/channels/pairing/index.js';\nimport { evaluateAccess, resolveDmPolicy, resolveGroupPolicy } from '@xopcai/xopc/channels/security.js';\nimport type { DmPolicy, GroupPolicy } from '@xopcai/xopc/channels/channel-domain.js';\nimport type { TelegramResolvedAccount } from './types.js';\n\nexport function createTelegramSecurityAdapter(): ChannelSecurityAdapter<TelegramResolvedAccount> {\n return {\n resolveDmPolicy: ({ account }) => resolveDmPolicy(account.dmPolicy as DmPolicy | undefined, 'pairing'),\n resolveGroupPolicy: ({ account }) =>\n resolveGroupPolicy(account.groupPolicy as GroupPolicy | undefined, 'open'),\n resolveAllowFrom: ({ account }) => account.allowFrom,\n checkAccess: (ctx: ChannelSecurityContext, account, _cfg: Config) => {\n const isGroup = ctx.isGroup;\n const storeAllow = !isGroup\n ? readAllowFromIdsSync(resolveStandardAllowFromPath('telegram', account.accountId))\n : [];\n const allowFrom = isGroup\n ? (account.groupAllowFrom ?? account.allowFrom ?? [])\n : [...(account.allowFrom ?? []), ...storeAllow];\n const result = evaluateAccess({\n context: {\n channel: 'telegram',\n accountId: account.accountId,\n chatId: ctx.chatId,\n senderId: ctx.senderId,\n senderName: ctx.senderName,\n isGroup,\n isDm: !isGroup,\n },\n dmPolicy: account.dmPolicy as DmPolicy | undefined,\n groupPolicy: account.groupPolicy as GroupPolicy | undefined,\n allowFrom,\n groupAllowFrom: account.groupAllowFrom,\n });\n return { allowed: result.allowed, reason: result.reason };\n },\n };\n}\n"],"mappings":";;;;AAUA,SAAgB,gCAAiF;AAC/F,QAAO;EACL,kBAAkB,EAAE,cAAc,gBAAgB,QAAQ,UAAkC,UAAU;EACtG,qBAAqB,EAAE,cACrB,mBAAmB,QAAQ,aAAwC,OAAO;EAC5E,mBAAmB,EAAE,cAAc,QAAQ;EAC3C,cAAc,KAA6B,SAAS,SAAiB;GACnE,MAAM,UAAU,IAAI;GACpB,MAAM,aAAa,CAAC,UAChB,qBAAqB,6BAA6B,YAAY,QAAQ,UAAU,CAAC,GACjF,EAAE;GACN,MAAM,YAAY,UACb,QAAQ,kBAAkB,QAAQ,aAAa,EAAE,GAClD,CAAC,GAAI,QAAQ,aAAa,EAAE,EAAG,GAAG,WAAW;GACjD,MAAM,SAAS,eAAe;IAC5B,SAAS;KACP,SAAS;KACT,WAAW,QAAQ;KACnB,QAAQ,IAAI;KACZ,UAAU,IAAI;KACd,YAAY,IAAI;KAChB;KACA,MAAM,CAAC;KACR;IACD,UAAU,QAAQ;IAClB,aAAa,QAAQ;IACrB;IACA,gBAAgB,QAAQ;IACzB,CAAC;AACF,UAAO;IAAE,SAAS,OAAO;IAAS,QAAQ,OAAO;IAAQ;;EAE5D"}
1
+ {"version":3,"file":"security-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/security-adapter.ts"],"sourcesContent":["import type { Config } from '@xopcai/xopc/config/index.js';\nimport type {\n ChannelSecurityAdapter,\n ChannelSecurityContext,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport { readAllowFromIdsSync, resolveStandardAllowFromPath } from '@xopcai/xopc/channels/pairing/index.js';\nimport { evaluateAccess, resolveDmPolicy, resolveGroupPolicy } from '@xopcai/xopc/channels/security.js';\nimport type { DmPolicy, GroupPolicy } from '@xopcai/xopc/channels/channel-domain.js';\nimport type { TelegramResolvedAccount } from './types.js';\n\nexport function createTelegramSecurityAdapter(): ChannelSecurityAdapter<TelegramResolvedAccount> {\n return {\n resolveDmPolicy: ({ account }) => resolveDmPolicy(account.dmPolicy as DmPolicy | undefined, 'pairing'),\n resolveGroupPolicy: ({ account }) =>\n resolveGroupPolicy(account.groupPolicy as GroupPolicy | undefined, 'open'),\n resolveAllowFrom: ({ account }) => account.allowFrom,\n checkAccess: (ctx: ChannelSecurityContext, account, _cfg: Config) => {\n const isGroup = ctx.isGroup;\n const storeAllow = !isGroup\n ? readAllowFromIdsSync(resolveStandardAllowFromPath('telegram', account.accountId))\n : [];\n const allowFrom = isGroup\n ? (account.groupAllowFrom ?? account.allowFrom ?? [])\n : [...(account.allowFrom ?? []), ...storeAllow];\n const result = evaluateAccess({\n context: {\n channel: 'telegram',\n accountId: account.accountId,\n chatId: ctx.chatId,\n senderId: ctx.senderId,\n senderName: ctx.senderName,\n isGroup,\n isDm: !isGroup,\n },\n dmPolicy: account.dmPolicy as DmPolicy | undefined,\n groupPolicy: account.groupPolicy as GroupPolicy | undefined,\n allowFrom,\n groupAllowFrom: account.groupAllowFrom,\n allowNameMatching: true,\n });\n return { allowed: result.allowed, reason: result.reason };\n },\n };\n}\n"],"mappings":";;;;AAUA,SAAgB,gCAAiF;AAC/F,QAAO;EACL,kBAAkB,EAAE,cAAc,gBAAgB,QAAQ,UAAkC,UAAU;EACtG,qBAAqB,EAAE,cACrB,mBAAmB,QAAQ,aAAwC,OAAO;EAC5E,mBAAmB,EAAE,cAAc,QAAQ;EAC3C,cAAc,KAA6B,SAAS,SAAiB;GACnE,MAAM,UAAU,IAAI;GACpB,MAAM,aAAa,CAAC,UAChB,qBAAqB,6BAA6B,YAAY,QAAQ,UAAU,CAAC,GACjF,EAAE;GACN,MAAM,YAAY,UACb,QAAQ,kBAAkB,QAAQ,aAAa,EAAE,GAClD,CAAC,GAAI,QAAQ,aAAa,EAAE,EAAG,GAAG,WAAW;GACjD,MAAM,SAAS,eAAe;IAC5B,SAAS;KACP,SAAS;KACT,WAAW,QAAQ;KACnB,QAAQ,IAAI;KACZ,UAAU,IAAI;KACd,YAAY,IAAI;KAChB;KACA,MAAM,CAAC;KACR;IACD,UAAU,QAAQ;IAClB,aAAa,QAAQ;IACrB;IACA,gBAAgB,QAAQ;IACxB,mBAAmB;IACpB,CAAC;AACF,UAAO;IAAE,SAAS,OAAO;IAAS,QAAQ,OAAO;IAAQ;;EAE5D"}
@@ -1,11 +1,18 @@
1
+ import { init_config_schema, resolveTelegramStreamingMode } from "../config-schema.js";
1
2
  import { createLogger } from "../../../../src/utils/logger/index.js";
2
3
  import { init_logger } from "../../../../src/utils/logger.js";
3
4
  import { renderTelegramHtmlText } from "../format.js";
5
+ import { telegramReplyTracker } from "../reply-params.js";
4
6
  import { createTelegramDraftStream } from "../draft-stream.js";
5
7
  //#region extensions/telegram/src/adapters/streaming-adapter.ts
6
8
  init_logger();
9
+ init_config_schema();
7
10
  const log = createLogger("TelegramStreaming");
8
11
  const DM_MIN_INITIAL_CHARS = 30;
12
+ const BLOCK_DEFAULT_COALESCE = {
13
+ minChars: 800,
14
+ idleMs: 1e3
15
+ };
9
16
  function isProbablyPrivateChat(chatId) {
10
17
  const n = Number(chatId);
11
18
  if (Number.isFinite(n) && n < 0) return false;
@@ -15,26 +22,38 @@ function createTelegramStreamingAdapter(deps) {
15
22
  const { accountManager } = deps;
16
23
  return { startStream(options) {
17
24
  const accountId = options.accountId ?? "default";
18
- const streamMode = accountManager.getAccount(accountId)?.streamMode ?? "partial";
19
- if (streamMode === "off" || streamMode === "block") return null;
25
+ const account = accountManager.getAccount(accountId);
26
+ const streamMode = account ? resolveTelegramStreamingMode(account) : "partial";
27
+ if (streamMode === "off") return null;
20
28
  const bot = accountManager.getBot(accountId);
21
29
  if (!bot) {
22
30
  log.warn({ accountId }, "Streaming skipped: bot not available");
23
31
  return null;
24
32
  }
25
33
  const chatId = options.chatId;
34
+ telegramReplyTracker.reset(accountId, chatId);
35
+ const replyToMessageId = telegramReplyTracker.resolveReplyToMessageId({
36
+ mode: account?.replyToMode,
37
+ explicitReplyTo: options.replyToMessageId,
38
+ inboundMessageId: options.replyToMessageId,
39
+ accountId,
40
+ chatId
41
+ });
26
42
  const threadParsed = options.threadId ? parseInt(options.threadId, 10) : NaN;
27
43
  const threadId = Number.isFinite(threadParsed) ? threadParsed : void 0;
28
- const replyParsed = options.replyToMessageId ? parseInt(options.replyToMessageId, 10) : NaN;
29
- const replyToMessageId = Number.isFinite(replyParsed) ? replyParsed : void 0;
44
+ const replyParsed = replyToMessageId ? parseInt(replyToMessageId, 10) : NaN;
45
+ const replyId = Number.isFinite(replyParsed) ? replyParsed : void 0;
30
46
  const isPrivate = isProbablyPrivateChat(chatId);
31
47
  const previewTransport = isPrivate ? "message" : "auto";
48
+ const blockCoalesce = account?.streaming?.block?.coalesce;
49
+ const throttleMs = streamMode === "block" ? Math.max(250, blockCoalesce?.idleMs ?? BLOCK_DEFAULT_COALESCE.idleMs) : void 0;
32
50
  const draft = createTelegramDraftStream({
33
51
  api: bot.api,
34
52
  chatId,
35
53
  threadId: Number.isFinite(threadId) ? threadId : void 0,
36
- replyToMessageId: Number.isFinite(replyToMessageId) ? replyToMessageId : void 0,
54
+ replyToMessageId: Number.isFinite(replyId) ? replyId : void 0,
37
55
  previewTransport,
56
+ throttleMs,
38
57
  minInitialChars: isPrivate ? DM_MIN_INITIAL_CHARS : void 0,
39
58
  renderText: (text) => ({
40
59
  text: renderTelegramHtmlText(text),
@@ -42,8 +61,37 @@ function createTelegramStreamingAdapter(deps) {
42
61
  }),
43
62
  warn: (m) => log.warn(m)
44
63
  });
64
+ let reasoningDraft = null;
65
+ let pendingBlockBuffer = "";
66
+ let blockFlushTimer;
67
+ const blockMinChars = blockCoalesce?.minChars ?? BLOCK_DEFAULT_COALESCE.minChars;
68
+ const blockIdleMs = blockCoalesce?.idleMs ?? BLOCK_DEFAULT_COALESCE.idleMs;
69
+ const flushBlockBuffer = () => {
70
+ if (!pendingBlockBuffer) return;
71
+ draft.update(pendingBlockBuffer);
72
+ pendingBlockBuffer = "";
73
+ };
74
+ const scheduleBlockFlush = () => {
75
+ if (blockFlushTimer) clearTimeout(blockFlushTimer);
76
+ blockFlushTimer = setTimeout(() => {
77
+ blockFlushTimer = void 0;
78
+ flushBlockBuffer();
79
+ }, blockIdleMs);
80
+ blockFlushTimer.unref?.();
81
+ };
45
82
  let skipFinalOutbound = false;
46
83
  const end = async () => {
84
+ if (streamMode === "block") {
85
+ if (blockFlushTimer) {
86
+ clearTimeout(blockFlushTimer);
87
+ blockFlushTimer = void 0;
88
+ }
89
+ flushBlockBuffer();
90
+ }
91
+ if (reasoningDraft) {
92
+ await reasoningDraft.stop();
93
+ reasoningDraft = null;
94
+ }
47
95
  if (draft.previewMode?.() === "draft" && typeof draft.materialize === "function") {
48
96
  skipFinalOutbound = typeof await draft.materialize() === "number";
49
97
  return;
@@ -53,11 +101,47 @@ function createTelegramStreamingAdapter(deps) {
53
101
  skipFinalOutbound = typeof draft.messageId() === "number";
54
102
  };
55
103
  const abort = async () => {
104
+ if (blockFlushTimer) {
105
+ clearTimeout(blockFlushTimer);
106
+ blockFlushTimer = void 0;
107
+ }
108
+ pendingBlockBuffer = "";
109
+ if (reasoningDraft) {
110
+ await reasoningDraft.clear();
111
+ reasoningDraft = null;
112
+ }
56
113
  await draft.clear();
57
114
  skipFinalOutbound = false;
58
115
  };
116
+ const update = (text) => {
117
+ if (streamMode === "block") {
118
+ pendingBlockBuffer = text;
119
+ if (text.length >= blockMinChars) {
120
+ flushBlockBuffer();
121
+ return;
122
+ }
123
+ scheduleBlockFlush();
124
+ return;
125
+ }
126
+ draft.update(text);
127
+ };
128
+ const updateReasoning = (text) => {
129
+ if (!reasoningDraft) reasoningDraft = createTelegramDraftStream({
130
+ api: bot.api,
131
+ chatId,
132
+ threadId: Number.isFinite(threadId) ? threadId : void 0,
133
+ previewTransport: "message",
134
+ renderText: (t) => ({
135
+ text: `💭 ${renderTelegramHtmlText(t)}`,
136
+ parseMode: "HTML"
137
+ }),
138
+ warn: (m) => log.warn(m)
139
+ });
140
+ reasoningDraft.update(text);
141
+ };
59
142
  return {
60
- update: (text) => draft.update(text),
143
+ update,
144
+ updateReasoning,
61
145
  updateProgress: (text, stage, detail) => draft.updateWithProgress(text, stage, detail),
62
146
  setProgress: (stage, detail) => draft.setProgress(stage, detail),
63
147
  end,
@@ -1 +1 @@
1
- {"version":3,"file":"streaming-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/streaming-adapter.ts"],"sourcesContent":["/**\n * Telegram channel streaming: live assistant text via draft stream.\n */\n\nimport type {\n ChannelStreamHandle,\n ChannelStreamingAdapter,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport type { ProgressStage } from '@xopcai/xopc/agent/lifecycle/progress.js';\nimport type { TelegramAccountManager } from '../account-manager.js';\nimport { createTelegramDraftStream } from '../draft-stream.js';\nimport { renderTelegramHtmlText } from '../format.js';\n\nconst log = createLogger('TelegramStreaming');\n\nconst DM_MIN_INITIAL_CHARS = 30;\n\nexport interface TelegramStreamingAdapterDeps {\n accountManager: TelegramAccountManager;\n}\n\nfunction isProbablyPrivateChat(chatId: string): boolean {\n const n = Number(chatId);\n if (Number.isFinite(n) && n < 0) {\n return false;\n }\n return true;\n}\n\nexport function createTelegramStreamingAdapter(\n deps: TelegramStreamingAdapterDeps,\n): ChannelStreamingAdapter {\n const { accountManager } = deps;\n\n return {\n startStream(options: {\n chatId: string;\n accountId?: string;\n threadId?: string;\n replyToMessageId?: string;\n parseMode?: 'Markdown' | 'HTML';\n }): ChannelStreamHandle | null {\n const accountId = options.accountId ?? 'default';\n const account = accountManager.getAccount(accountId);\n const streamMode = account?.streamMode ?? 'partial';\n\n if (streamMode === 'off' || streamMode === 'block') {\n return null;\n }\n\n const bot = accountManager.getBot(accountId);\n if (!bot) {\n log.warn({ accountId }, 'Streaming skipped: bot not available');\n return null;\n }\n\n const chatId = options.chatId;\n const threadParsed = options.threadId ? parseInt(options.threadId, 10) : NaN;\n const threadId = Number.isFinite(threadParsed) ? threadParsed : undefined;\n const replyParsed = options.replyToMessageId\n ? parseInt(options.replyToMessageId, 10)\n : NaN;\n const replyToMessageId = Number.isFinite(replyParsed) ? replyParsed : undefined;\n const isPrivate = isProbablyPrivateChat(chatId);\n\n // DM uses real message transport to avoid draft→materialize duplicate flash.\n const previewTransport = isPrivate ? ('message' as const) : ('auto' as const);\n\n const draft = createTelegramDraftStream({\n api: bot.api,\n chatId,\n threadId: Number.isFinite(threadId!) ? threadId : undefined,\n replyToMessageId: Number.isFinite(replyToMessageId!) ? replyToMessageId : undefined,\n previewTransport,\n minInitialChars: isPrivate ? DM_MIN_INITIAL_CHARS : undefined,\n renderText: (text) => ({\n text: renderTelegramHtmlText(text),\n parseMode: 'HTML',\n }),\n warn: (m) => log.warn(m),\n });\n\n let skipFinalOutbound = false;\n\n const end = async () => {\n if (draft.previewMode?.() === 'draft' && typeof draft.materialize === 'function') {\n const mid = await draft.materialize();\n skipFinalOutbound = typeof mid === 'number';\n return;\n }\n await draft.flush();\n await draft.stop();\n skipFinalOutbound = typeof draft.messageId() === 'number';\n };\n\n const abort = async () => {\n await draft.clear();\n skipFinalOutbound = false;\n };\n\n return {\n update: (text: string) => draft.update(text),\n updateProgress: (text, stage, detail) =>\n draft.updateWithProgress(text, stage as ProgressStage, detail),\n setProgress: (stage, detail) => draft.setProgress(stage as ProgressStage, detail),\n end,\n abort,\n messageId: () => draft.messageId(),\n skipFinalOutbound: () => skipFinalOutbound,\n };\n },\n };\n}\n"],"mappings":";;;;;aAQ4D;AAM5D,MAAM,MAAM,aAAa,oBAAoB;AAE7C,MAAM,uBAAuB;AAM7B,SAAS,sBAAsB,QAAyB;CACtD,MAAM,IAAI,OAAO,OAAO;AACxB,KAAI,OAAO,SAAS,EAAE,IAAI,IAAI,EAC5B,QAAO;AAET,QAAO;;AAGT,SAAgB,+BACd,MACyB;CACzB,MAAM,EAAE,mBAAmB;AAE3B,QAAO,EACL,YAAY,SAMmB;EAC7B,MAAM,YAAY,QAAQ,aAAa;EAEvC,MAAM,aADU,eAAe,WAAW,UAChB,EAAE,cAAc;AAE1C,MAAI,eAAe,SAAS,eAAe,QACzC,QAAO;EAGT,MAAM,MAAM,eAAe,OAAO,UAAU;AAC5C,MAAI,CAAC,KAAK;AACR,OAAI,KAAK,EAAE,WAAW,EAAE,uCAAuC;AAC/D,UAAO;;EAGT,MAAM,SAAS,QAAQ;EACvB,MAAM,eAAe,QAAQ,WAAW,SAAS,QAAQ,UAAU,GAAG,GAAG;EACzE,MAAM,WAAW,OAAO,SAAS,aAAa,GAAG,eAAe,KAAA;EAChE,MAAM,cAAc,QAAQ,mBACxB,SAAS,QAAQ,kBAAkB,GAAG,GACtC;EACJ,MAAM,mBAAmB,OAAO,SAAS,YAAY,GAAG,cAAc,KAAA;EACtE,MAAM,YAAY,sBAAsB,OAAO;EAG/C,MAAM,mBAAmB,YAAa,YAAuB;EAE7D,MAAM,QAAQ,0BAA0B;GACtC,KAAK,IAAI;GACT;GACA,UAAU,OAAO,SAAS,SAAU,GAAG,WAAW,KAAA;GAClD,kBAAkB,OAAO,SAAS,iBAAkB,GAAG,mBAAmB,KAAA;GAC1E;GACA,iBAAiB,YAAY,uBAAuB,KAAA;GACpD,aAAa,UAAU;IACrB,MAAM,uBAAuB,KAAK;IAClC,WAAW;IACZ;GACD,OAAO,MAAM,IAAI,KAAK,EAAE;GACzB,CAAC;EAEF,IAAI,oBAAoB;EAExB,MAAM,MAAM,YAAY;AACtB,OAAI,MAAM,eAAe,KAAK,WAAW,OAAO,MAAM,gBAAgB,YAAY;AAEhF,wBAAoB,OAAO,MADT,MAAM,aAAa,KACF;AACnC;;AAEF,SAAM,MAAM,OAAO;AACnB,SAAM,MAAM,MAAM;AAClB,uBAAoB,OAAO,MAAM,WAAW,KAAK;;EAGnD,MAAM,QAAQ,YAAY;AACxB,SAAM,MAAM,OAAO;AACnB,uBAAoB;;AAGtB,SAAO;GACL,SAAS,SAAiB,MAAM,OAAO,KAAK;GAC5C,iBAAiB,MAAM,OAAO,WAC5B,MAAM,mBAAmB,MAAM,OAAwB,OAAO;GAChE,cAAc,OAAO,WAAW,MAAM,YAAY,OAAwB,OAAO;GACjF;GACA;GACA,iBAAiB,MAAM,WAAW;GAClC,yBAAyB;GAC1B;IAEJ"}
1
+ {"version":3,"file":"streaming-adapter.js","names":[],"sources":["../../../../../extensions/telegram/src/adapters/streaming-adapter.ts"],"sourcesContent":["/**\n * Telegram channel streaming: live assistant text via draft stream.\n */\n\nimport type {\n ChannelStreamHandle,\n ChannelStreamingAdapter,\n} from '@xopcai/xopc/channels/plugin-types.js';\nimport { createLogger } from '@xopcai/xopc/utils/logger.js';\nimport type { ProgressStage } from '@xopcai/xopc/agent/lifecycle/progress.js';\nimport type { TelegramAccountManager } from '../account-manager.js';\nimport { createTelegramDraftStream } from '../draft-stream.js';\nimport { renderTelegramHtmlText } from '../format.js';\nimport { resolveTelegramStreamingMode } from '../config-schema.js';\nimport { telegramReplyTracker } from '../reply-params.js';\n\nconst log = createLogger('TelegramStreaming');\n\nconst DM_MIN_INITIAL_CHARS = 30;\nconst BLOCK_DEFAULT_COALESCE = { minChars: 800, idleMs: 1000 };\n\nexport interface TelegramStreamingAdapterDeps {\n accountManager: TelegramAccountManager;\n}\n\nfunction isProbablyPrivateChat(chatId: string): boolean {\n const n = Number(chatId);\n if (Number.isFinite(n) && n < 0) {\n return false;\n }\n return true;\n}\n\nexport function createTelegramStreamingAdapter(\n deps: TelegramStreamingAdapterDeps,\n): ChannelStreamingAdapter {\n const { accountManager } = deps;\n\n return {\n startStream(options: {\n chatId: string;\n accountId?: string;\n threadId?: string;\n replyToMessageId?: string;\n parseMode?: 'Markdown' | 'HTML';\n }): ChannelStreamHandle | null {\n const accountId = options.accountId ?? 'default';\n const account = accountManager.getAccount(accountId);\n const streamMode = account ? resolveTelegramStreamingMode(account) : 'partial';\n\n if (streamMode === 'off') {\n return null;\n }\n\n const bot = accountManager.getBot(accountId);\n if (!bot) {\n log.warn({ accountId }, 'Streaming skipped: bot not available');\n return null;\n }\n\n const chatId = options.chatId;\n telegramReplyTracker.reset(accountId, chatId);\n\n const replyToMessageId = telegramReplyTracker.resolveReplyToMessageId({\n mode: account?.replyToMode,\n explicitReplyTo: options.replyToMessageId,\n inboundMessageId: options.replyToMessageId,\n accountId,\n chatId,\n });\n\n const threadParsed = options.threadId ? parseInt(options.threadId, 10) : NaN;\n const threadId = Number.isFinite(threadParsed) ? threadParsed : undefined;\n const replyParsed = replyToMessageId ? parseInt(replyToMessageId, 10) : NaN;\n const replyId = Number.isFinite(replyParsed) ? replyParsed : undefined;\n const isPrivate = isProbablyPrivateChat(chatId);\n\n const previewTransport = isPrivate ? ('message' as const) : ('auto' as const);\n const blockCoalesce = account?.streaming?.block?.coalesce;\n const throttleMs =\n streamMode === 'block'\n ? Math.max(250, blockCoalesce?.idleMs ?? BLOCK_DEFAULT_COALESCE.idleMs)\n : undefined;\n\n const draft = createTelegramDraftStream({\n api: bot.api,\n chatId,\n threadId: Number.isFinite(threadId!) ? threadId : undefined,\n replyToMessageId: Number.isFinite(replyId!) ? replyId : undefined,\n previewTransport,\n throttleMs,\n minInitialChars: isPrivate ? DM_MIN_INITIAL_CHARS : undefined,\n renderText: (text) => ({\n text: renderTelegramHtmlText(text),\n parseMode: 'HTML',\n }),\n warn: (m) => log.warn(m),\n });\n\n let reasoningDraft: ReturnType<typeof createTelegramDraftStream> | null = null;\n let pendingBlockBuffer = '';\n let blockFlushTimer: ReturnType<typeof setTimeout> | undefined;\n const blockMinChars = blockCoalesce?.minChars ?? BLOCK_DEFAULT_COALESCE.minChars;\n const blockIdleMs = blockCoalesce?.idleMs ?? BLOCK_DEFAULT_COALESCE.idleMs;\n\n const flushBlockBuffer = () => {\n if (!pendingBlockBuffer) return;\n draft.update(pendingBlockBuffer);\n pendingBlockBuffer = '';\n };\n\n const scheduleBlockFlush = () => {\n if (blockFlushTimer) clearTimeout(blockFlushTimer);\n blockFlushTimer = setTimeout(() => {\n blockFlushTimer = undefined;\n flushBlockBuffer();\n }, blockIdleMs);\n blockFlushTimer.unref?.();\n };\n\n let skipFinalOutbound = false;\n\n const end = async () => {\n if (streamMode === 'block') {\n if (blockFlushTimer) {\n clearTimeout(blockFlushTimer);\n blockFlushTimer = undefined;\n }\n flushBlockBuffer();\n }\n if (reasoningDraft) {\n await reasoningDraft.stop();\n reasoningDraft = null;\n }\n if (draft.previewMode?.() === 'draft' && typeof draft.materialize === 'function') {\n const mid = await draft.materialize();\n skipFinalOutbound = typeof mid === 'number';\n return;\n }\n await draft.flush();\n await draft.stop();\n skipFinalOutbound = typeof draft.messageId() === 'number';\n };\n\n const abort = async () => {\n if (blockFlushTimer) {\n clearTimeout(blockFlushTimer);\n blockFlushTimer = undefined;\n }\n pendingBlockBuffer = '';\n if (reasoningDraft) {\n await reasoningDraft.clear();\n reasoningDraft = null;\n }\n await draft.clear();\n skipFinalOutbound = false;\n };\n\n const update = (text: string) => {\n if (streamMode === 'block') {\n pendingBlockBuffer = text;\n if (text.length >= blockMinChars) {\n flushBlockBuffer();\n return;\n }\n scheduleBlockFlush();\n return;\n }\n draft.update(text);\n };\n\n const updateReasoning = (text: string) => {\n if (!reasoningDraft) {\n reasoningDraft = createTelegramDraftStream({\n api: bot.api,\n chatId,\n threadId: Number.isFinite(threadId!) ? threadId : undefined,\n previewTransport: 'message',\n renderText: (t) => ({\n text: `💭 ${renderTelegramHtmlText(t)}`,\n parseMode: 'HTML',\n }),\n warn: (m) => log.warn(m),\n });\n }\n reasoningDraft.update(text);\n };\n\n return {\n update,\n updateReasoning,\n updateProgress: (text, stage, detail) =>\n draft.updateWithProgress(text, stage as ProgressStage, detail),\n setProgress: (stage, detail) => draft.setProgress(stage as ProgressStage, detail),\n end,\n abort,\n messageId: () => draft.messageId(),\n skipFinalOutbound: () => skipFinalOutbound,\n };\n },\n };\n}\n"],"mappings":";;;;;;;aAQ4D;oBAKO;AAGnE,MAAM,MAAM,aAAa,oBAAoB;AAE7C,MAAM,uBAAuB;AAC7B,MAAM,yBAAyB;CAAE,UAAU;CAAK,QAAQ;CAAM;AAM9D,SAAS,sBAAsB,QAAyB;CACtD,MAAM,IAAI,OAAO,OAAO;AACxB,KAAI,OAAO,SAAS,EAAE,IAAI,IAAI,EAC5B,QAAO;AAET,QAAO;;AAGT,SAAgB,+BACd,MACyB;CACzB,MAAM,EAAE,mBAAmB;AAE3B,QAAO,EACL,YAAY,SAMmB;EAC7B,MAAM,YAAY,QAAQ,aAAa;EACvC,MAAM,UAAU,eAAe,WAAW,UAAU;EACpD,MAAM,aAAa,UAAU,6BAA6B,QAAQ,GAAG;AAErE,MAAI,eAAe,MACjB,QAAO;EAGT,MAAM,MAAM,eAAe,OAAO,UAAU;AAC5C,MAAI,CAAC,KAAK;AACR,OAAI,KAAK,EAAE,WAAW,EAAE,uCAAuC;AAC/D,UAAO;;EAGT,MAAM,SAAS,QAAQ;AACvB,uBAAqB,MAAM,WAAW,OAAO;EAE7C,MAAM,mBAAmB,qBAAqB,wBAAwB;GACpE,MAAM,SAAS;GACf,iBAAiB,QAAQ;GACzB,kBAAkB,QAAQ;GAC1B;GACA;GACD,CAAC;EAEF,MAAM,eAAe,QAAQ,WAAW,SAAS,QAAQ,UAAU,GAAG,GAAG;EACzE,MAAM,WAAW,OAAO,SAAS,aAAa,GAAG,eAAe,KAAA;EAChE,MAAM,cAAc,mBAAmB,SAAS,kBAAkB,GAAG,GAAG;EACxE,MAAM,UAAU,OAAO,SAAS,YAAY,GAAG,cAAc,KAAA;EAC7D,MAAM,YAAY,sBAAsB,OAAO;EAE/C,MAAM,mBAAmB,YAAa,YAAuB;EAC7D,MAAM,gBAAgB,SAAS,WAAW,OAAO;EACjD,MAAM,aACJ,eAAe,UACX,KAAK,IAAI,KAAK,eAAe,UAAU,uBAAuB,OAAO,GACrE,KAAA;EAEN,MAAM,QAAQ,0BAA0B;GACtC,KAAK,IAAI;GACT;GACA,UAAU,OAAO,SAAS,SAAU,GAAG,WAAW,KAAA;GAClD,kBAAkB,OAAO,SAAS,QAAS,GAAG,UAAU,KAAA;GACxD;GACA;GACA,iBAAiB,YAAY,uBAAuB,KAAA;GACpD,aAAa,UAAU;IACrB,MAAM,uBAAuB,KAAK;IAClC,WAAW;IACZ;GACD,OAAO,MAAM,IAAI,KAAK,EAAE;GACzB,CAAC;EAEF,IAAI,iBAAsE;EAC1E,IAAI,qBAAqB;EACzB,IAAI;EACJ,MAAM,gBAAgB,eAAe,YAAY,uBAAuB;EACxE,MAAM,cAAc,eAAe,UAAU,uBAAuB;EAEpE,MAAM,yBAAyB;AAC7B,OAAI,CAAC,mBAAoB;AACzB,SAAM,OAAO,mBAAmB;AAChC,wBAAqB;;EAGvB,MAAM,2BAA2B;AAC/B,OAAI,gBAAiB,cAAa,gBAAgB;AAClD,qBAAkB,iBAAiB;AACjC,sBAAkB,KAAA;AAClB,sBAAkB;MACjB,YAAY;AACf,mBAAgB,SAAS;;EAG3B,IAAI,oBAAoB;EAExB,MAAM,MAAM,YAAY;AACtB,OAAI,eAAe,SAAS;AAC1B,QAAI,iBAAiB;AACnB,kBAAa,gBAAgB;AAC7B,uBAAkB,KAAA;;AAEpB,sBAAkB;;AAEpB,OAAI,gBAAgB;AAClB,UAAM,eAAe,MAAM;AAC3B,qBAAiB;;AAEnB,OAAI,MAAM,eAAe,KAAK,WAAW,OAAO,MAAM,gBAAgB,YAAY;AAEhF,wBAAoB,OAAO,MADT,MAAM,aAAa,KACF;AACnC;;AAEF,SAAM,MAAM,OAAO;AACnB,SAAM,MAAM,MAAM;AAClB,uBAAoB,OAAO,MAAM,WAAW,KAAK;;EAGnD,MAAM,QAAQ,YAAY;AACxB,OAAI,iBAAiB;AACnB,iBAAa,gBAAgB;AAC7B,sBAAkB,KAAA;;AAEpB,wBAAqB;AACrB,OAAI,gBAAgB;AAClB,UAAM,eAAe,OAAO;AAC5B,qBAAiB;;AAEnB,SAAM,MAAM,OAAO;AACnB,uBAAoB;;EAGtB,MAAM,UAAU,SAAiB;AAC/B,OAAI,eAAe,SAAS;AAC1B,yBAAqB;AACrB,QAAI,KAAK,UAAU,eAAe;AAChC,uBAAkB;AAClB;;AAEF,wBAAoB;AACpB;;AAEF,SAAM,OAAO,KAAK;;EAGpB,MAAM,mBAAmB,SAAiB;AACxC,OAAI,CAAC,eACH,kBAAiB,0BAA0B;IACzC,KAAK,IAAI;IACT;IACA,UAAU,OAAO,SAAS,SAAU,GAAG,WAAW,KAAA;IAClD,kBAAkB;IAClB,aAAa,OAAO;KAClB,MAAM,MAAM,uBAAuB,EAAE;KACrC,WAAW;KACZ;IACD,OAAO,MAAM,IAAI,KAAK,EAAE;IACzB,CAAC;AAEJ,kBAAe,OAAO,KAAK;;AAG7B,SAAO;GACL;GACA;GACA,iBAAiB,MAAM,OAAO,WAC5B,MAAM,mBAAmB,MAAM,OAAwB,OAAO;GAChE,cAAc,OAAO,WAAW,MAAM,YAAY,OAAwB,OAAO;GACjF;GACA;GACA,iBAAiB,MAAM,WAAW;GAClC,yBAAyB;GAC1B;IAEJ"}
@@ -6,11 +6,19 @@ export interface TelegramResolvedAccount {
6
6
  name?: string;
7
7
  enabled: boolean;
8
8
  botToken: string;
9
+ tokenFile?: string;
9
10
  apiRoot?: string;
11
+ proxy?: string;
10
12
  dmPolicy?: 'pairing' | 'allowlist' | 'open' | 'disabled';
11
13
  groupPolicy?: 'open' | 'disabled' | 'allowlist';
12
14
  allowFrom?: Array<string | number>;
13
15
  groupAllowFrom?: Array<string | number>;
14
16
  requireMention?: boolean;
15
- streamMode?: 'off' | 'partial' | 'block';
17
+ replyToMode?: 'off' | 'first' | 'all';
18
+ streaming?: import('../config-schema.js').TelegramStreamingConfig;
19
+ pollingStallThresholdMs?: number;
20
+ reactionLevel?: 'off' | 'ack' | 'minimal' | 'extensive';
21
+ reactionNotifications?: 'off' | 'own' | 'all';
22
+ ackReaction?: string;
23
+ groups?: Record<string, unknown>;
16
24
  }
@@ -0,0 +1,4 @@
1
+ export declare const DEFAULT_TELEGRAM_API_ROOT = "https://api.telegram.org";
2
+ /** Strip trailing `/bot<token>` from a misconfigured apiRoot URL. */
3
+ export declare function normalizeTelegramApiRoot(apiRoot?: string): string;
4
+ export declare function hasTelegramBotEndpointApiRoot(apiRoot: unknown): boolean;