@poolzin/pool-bot 2026.2.25 → 2026.2.26

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 (506) hide show
  1. package/dist/acp/event-mapper.js +87 -22
  2. package/dist/acp/meta.js +12 -6
  3. package/dist/agents/agent-paths.js +8 -9
  4. package/dist/agents/agent-scope.js +7 -5
  5. package/dist/agents/auth-profiles/oauth.js +148 -64
  6. package/dist/agents/auth-profiles/session-override.js +13 -7
  7. package/dist/agents/bash-tools.exec-host-gateway.js +14 -4
  8. package/dist/agents/bash-tools.exec-runtime.js +2 -25
  9. package/dist/agents/bedrock-discovery.js +3 -1
  10. package/dist/agents/byteplus-models.js +97 -0
  11. package/dist/agents/chutes-oauth.js +1 -0
  12. package/dist/agents/cli-runner/helpers.js +4 -0
  13. package/dist/agents/compaction.js +41 -14
  14. package/dist/agents/doubao-models.js +121 -0
  15. package/dist/agents/failover-error.js +2 -0
  16. package/dist/agents/huggingface-models.js +5 -3
  17. package/dist/agents/live-model-filter.js +5 -0
  18. package/dist/agents/minimax-vlm.js +10 -8
  19. package/dist/agents/model-auth.js +6 -0
  20. package/dist/agents/model-catalog.js +3 -1
  21. package/dist/agents/model-selection.js +7 -1
  22. package/dist/agents/models-config.providers.js +93 -11
  23. package/dist/agents/ollama-stream.js +117 -4
  24. package/dist/agents/opencode-zen-models.js +22 -11
  25. package/dist/agents/pi-embedded-helpers/errors.js +55 -33
  26. package/dist/agents/pi-embedded-helpers/messaging-dedupe.js +10 -5
  27. package/dist/agents/pi-embedded-helpers/thinking.js +10 -5
  28. package/dist/agents/pi-embedded-helpers.js +1 -1
  29. package/dist/agents/pi-embedded-runner/compact.js +29 -7
  30. package/dist/agents/pi-embedded-runner/extensions.js +28 -26
  31. package/dist/agents/pi-embedded-runner/google.js +20 -8
  32. package/dist/agents/pi-embedded-runner/run/attempt.js +95 -36
  33. package/dist/agents/pi-embedded-runner/run.js +71 -12
  34. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +11 -2
  35. package/dist/agents/pi-embedded-runner/session-manager-cache.js +11 -7
  36. package/dist/agents/pi-embedded-runner/system-prompt.js +2 -0
  37. package/dist/agents/pi-embedded-runner/thinking.js +42 -0
  38. package/dist/agents/pi-embedded-runner/tool-name-allowlist.js +19 -0
  39. package/dist/agents/pi-embedded-runner/utils.js +7 -10
  40. package/dist/agents/pi-embedded-subscribe.handlers.lifecycle.js +45 -56
  41. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +2 -2
  42. package/dist/agents/pi-embedded-subscribe.js +9 -4
  43. package/dist/agents/pi-embedded-subscribe.tools.js +68 -14
  44. package/dist/agents/pi-embedded-utils.js +3 -0
  45. package/dist/agents/pi-extensions/compaction-safeguard-runtime.js +4 -20
  46. package/dist/agents/pi-extensions/compaction-safeguard.js +75 -33
  47. package/dist/agents/pi-settings.js +40 -0
  48. package/dist/agents/pi-tools.policy.js +2 -1
  49. package/dist/agents/provider/config-loader.js +1 -1
  50. package/dist/agents/sandbox/browser.js +170 -33
  51. package/dist/agents/sandbox/config-hash.js +14 -27
  52. package/dist/agents/sandbox/config.js +21 -2
  53. package/dist/agents/sandbox/constants.js +2 -0
  54. package/dist/agents/sandbox/docker.js +16 -2
  55. package/dist/agents/sandbox/novnc-auth.js +62 -0
  56. package/dist/agents/sandbox/sanitize-env-vars.js +1 -1
  57. package/dist/agents/sandbox/shared.js +10 -6
  58. package/dist/agents/sandbox-paths.js +24 -11
  59. package/dist/agents/schema/clean-for-gemini.js +132 -85
  60. package/dist/agents/session-slug.js +10 -5
  61. package/dist/agents/session-tool-result-guard-wrapper.js +1 -0
  62. package/dist/agents/session-tool-result-guard.js +3 -1
  63. package/dist/agents/session-transcript-repair.js +40 -6
  64. package/dist/agents/skills/bundled-dir.js +19 -5
  65. package/dist/agents/skills/env-overrides.js +124 -43
  66. package/dist/agents/skills/frontmatter.js +6 -6
  67. package/dist/agents/skills/plugin-skills.js +14 -7
  68. package/dist/agents/skills/workspace.js +1 -0
  69. package/dist/agents/subagent-announce.js +251 -49
  70. package/dist/agents/subagent-lifecycle-events.js +19 -0
  71. package/dist/agents/subagent-registry-cleanup.js +31 -0
  72. package/dist/agents/subagent-registry-completion.js +68 -0
  73. package/dist/agents/subagent-registry-queries.js +117 -0
  74. package/dist/agents/subagent-registry-state.js +46 -0
  75. package/dist/agents/subagent-registry.js +252 -221
  76. package/dist/agents/subagent-registry.store.js +1 -0
  77. package/dist/agents/subagent-registry.types.js +1 -0
  78. package/dist/agents/subagent-spawn.js +195 -7
  79. package/dist/agents/system-prompt.js +22 -6
  80. package/dist/agents/test-helpers/fast-coding-tools.js +1 -18
  81. package/dist/agents/test-helpers/fast-core-tools.js +1 -17
  82. package/dist/agents/timeout.js +18 -6
  83. package/dist/agents/tool-call-id.js +1 -1
  84. package/dist/agents/tool-display-common.js +162 -29
  85. package/dist/agents/tool-images.js +82 -9
  86. package/dist/agents/tool-policy.js +51 -26
  87. package/dist/agents/tools/browser-tool.js +2 -2
  88. package/dist/agents/tools/canvas-tool.js +27 -1
  89. package/dist/agents/tools/common.js +45 -0
  90. package/dist/agents/tools/discord-actions-guild.js +4 -1
  91. package/dist/agents/tools/gateway-tool.js +3 -1
  92. package/dist/agents/tools/nodes-utils.js +1 -10
  93. package/dist/agents/tools/sessions-send-helpers.js +12 -6
  94. package/dist/agents/tools/sessions-spawn-tool.js +8 -2
  95. package/dist/agents/tools/subagents-tool.js +2 -1
  96. package/dist/agents/tools/whatsapp-actions.js +10 -2
  97. package/dist/agents/tools/whatsapp-target-auth.js +18 -0
  98. package/dist/agents/transcript-policy.js +22 -8
  99. package/dist/agents/venice-models.js +11 -3
  100. package/dist/auto-reply/commands-registry.data.js +51 -0
  101. package/dist/auto-reply/commands-registry.js +4 -3
  102. package/dist/auto-reply/group-activation.js +10 -5
  103. package/dist/auto-reply/inbound-debounce.js +10 -5
  104. package/dist/auto-reply/reply/abort.js +1 -1
  105. package/dist/auto-reply/reply/agent-runner-execution.js +4 -1
  106. package/dist/auto-reply/reply/bash-command.js +41 -39
  107. package/dist/auto-reply/reply/command-gates.js +25 -0
  108. package/dist/auto-reply/reply/commands-allowlist.js +111 -72
  109. package/dist/auto-reply/reply/commands-bash.js +6 -5
  110. package/dist/auto-reply/reply/commands-config.js +30 -28
  111. package/dist/auto-reply/reply/commands-core.js +2 -1
  112. package/dist/auto-reply/reply/commands-info.js +1 -0
  113. package/dist/auto-reply/reply/commands-models.js +65 -14
  114. package/dist/auto-reply/reply/commands-session.js +237 -82
  115. package/dist/auto-reply/reply/commands-setunset.js +45 -0
  116. package/dist/auto-reply/reply/commands-subagents/action-agents.js +44 -0
  117. package/dist/auto-reply/reply/commands-subagents/action-focus.js +64 -0
  118. package/dist/auto-reply/reply/commands-subagents/action-help.js +4 -0
  119. package/dist/auto-reply/reply/commands-subagents/action-info.js +45 -0
  120. package/dist/auto-reply/reply/commands-subagents/action-kill.js +60 -0
  121. package/dist/auto-reply/reply/commands-subagents/action-list.js +44 -0
  122. package/dist/auto-reply/reply/commands-subagents/action-log.js +29 -0
  123. package/dist/auto-reply/reply/commands-subagents/action-send.js +119 -0
  124. package/dist/auto-reply/reply/commands-subagents/action-spawn.js +52 -0
  125. package/dist/auto-reply/reply/commands-subagents/action-unfocus.js +30 -0
  126. package/dist/auto-reply/reply/commands-subagents/shared.js +303 -0
  127. package/dist/auto-reply/reply/commands-subagents.js +51 -587
  128. package/dist/auto-reply/reply/commands-tts.js +10 -5
  129. package/dist/auto-reply/reply/config-value.js +10 -5
  130. package/dist/auto-reply/reply/directive-handling.model-picker.js +12 -6
  131. package/dist/auto-reply/reply/directive-handling.persist.js +9 -21
  132. package/dist/auto-reply/reply/directive-handling.shared.js +24 -4
  133. package/dist/auto-reply/reply/followup-runner.js +1 -0
  134. package/dist/auto-reply/reply/get-reply-directives-utils.js +23 -14
  135. package/dist/auto-reply/reply/get-reply-directives.js +17 -28
  136. package/dist/auto-reply/reply/get-reply-inline-actions.js +1 -0
  137. package/dist/auto-reply/reply/get-reply.js +71 -12
  138. package/dist/auto-reply/reply/model-selection.js +80 -39
  139. package/dist/auto-reply/reply/queue/enqueue.js +10 -5
  140. package/dist/auto-reply/reply/queue/state.js +13 -12
  141. package/dist/auto-reply/reply/reply-payloads.js +67 -36
  142. package/dist/auto-reply/reply/reply-reference.js +9 -8
  143. package/dist/auto-reply/reply/route-reply.js +15 -8
  144. package/dist/auto-reply/reply/session-reset-prompt.js +1 -1
  145. package/dist/auto-reply/reply/session.js +22 -6
  146. package/dist/auto-reply/reply/strip-inbound-meta.js +147 -0
  147. package/dist/auto-reply/reply/subagents-utils.js +56 -30
  148. package/dist/auto-reply/reply/typing.js +46 -21
  149. package/dist/auto-reply/send-policy.js +14 -7
  150. package/dist/auto-reply/status.js +140 -16
  151. package/dist/auto-reply/templating.js +10 -5
  152. package/dist/auto-reply/thinking.js +7 -16
  153. package/dist/auto-reply/tokens.js +21 -5
  154. package/dist/browser/bridge-server.js +36 -20
  155. package/dist/browser/cdp.helpers.js +7 -14
  156. package/dist/browser/cdp.js +35 -15
  157. package/dist/browser/chrome.profile-decoration.js +7 -4
  158. package/dist/browser/config.js +4 -0
  159. package/dist/browser/extension-relay-auth.js +55 -0
  160. package/dist/browser/extension-relay.js +74 -29
  161. package/dist/browser/navigation-guard.js +9 -1
  162. package/dist/browser/paths.js +77 -0
  163. package/dist/browser/profiles.js +13 -8
  164. package/dist/browser/pw-ai-module.js +10 -5
  165. package/dist/browser/pw-session.js +76 -39
  166. package/dist/browser/pw-tools-core.interactions.js +14 -7
  167. package/dist/browser/pw-tools-core.state.js +12 -6
  168. package/dist/browser/routes/agent.act.js +2 -2
  169. package/dist/browser/server-context.js +7 -0
  170. package/dist/build-info.json +3 -3
  171. package/dist/channels/allow-from.js +2 -1
  172. package/dist/channels/allowlists/resolve-utils.js +43 -19
  173. package/dist/channels/channel-config.js +14 -7
  174. package/dist/channels/draft-stream-loop.js +7 -0
  175. package/dist/channels/model-overrides.js +82 -0
  176. package/dist/channels/plugins/normalize/imessage.js +14 -7
  177. package/dist/channels/plugins/normalize/slack.js +10 -5
  178. package/dist/channels/plugins/normalize/telegram.js +14 -7
  179. package/dist/channels/plugins/outbound/discord.js +80 -8
  180. package/dist/channels/plugins/outbound/signal.js +11 -11
  181. package/dist/channels/plugins/setup-helpers.js +10 -5
  182. package/dist/channels/sender-label.js +14 -7
  183. package/dist/channels/session.js +4 -2
  184. package/dist/channels/status-reactions.js +297 -0
  185. package/dist/cli/banner.js +1 -1
  186. package/dist/cli/browser-cli-actions-input/register.files-downloads.js +65 -56
  187. package/dist/cli/cli-name.js +11 -11
  188. package/dist/cli/cli-utils.js +13 -3
  189. package/dist/cli/command-format.js +1 -1
  190. package/dist/cli/config-cli.js +1 -1
  191. package/dist/cli/daemon-cli/lifecycle-core.js +31 -19
  192. package/dist/cli/daemon-cli/lifecycle.js +64 -2
  193. package/dist/cli/daemon-cli/restart-health.js +126 -0
  194. package/dist/cli/daemon-cli/status.gather.js +9 -13
  195. package/dist/cli/daemon-cli/status.print.js +2 -10
  196. package/dist/cli/deps.js +27 -22
  197. package/dist/cli/gateway-cli/run-loop.js +23 -5
  198. package/dist/cli/node-cli/register.js +14 -5
  199. package/dist/cli/nodes-media-utils.js +7 -2
  200. package/dist/cli/outbound-send-deps.js +2 -9
  201. package/dist/cli/outbound-send-mapping.js +11 -0
  202. package/dist/cli/pairing-cli.js +40 -14
  203. package/dist/cli/plugins-cli.js +34 -41
  204. package/dist/cli/ports.js +11 -10
  205. package/dist/cli/program/command-registry.js +2 -11
  206. package/dist/cli/program/command-tree.js +16 -0
  207. package/dist/cli/program/preaction.js +13 -9
  208. package/dist/cli/program/register.configure.js +3 -18
  209. package/dist/cli/program/register.maintenance.js +2 -2
  210. package/dist/cli/program/register.onboard.js +2 -0
  211. package/dist/cli/program/register.status-health-sessions.js +16 -17
  212. package/dist/cli/program/register.subclis.js +93 -52
  213. package/dist/cli/route.js +11 -7
  214. package/dist/cli/system-cli.js +36 -46
  215. package/dist/cli/update-cli/shared.js +22 -9
  216. package/dist/cli/update-cli/update-command.js +89 -14
  217. package/dist/cli/update-cli/wizard.js +6 -12
  218. package/dist/commands/agent/run-context.js +18 -5
  219. package/dist/commands/agent/session-store.js +17 -4
  220. package/dist/commands/agent.js +22 -2
  221. package/dist/commands/agents.bindings.js +14 -7
  222. package/dist/commands/agents.commands.add.js +13 -9
  223. package/dist/commands/agents.commands.identity.js +12 -6
  224. package/dist/commands/agents.commands.list.js +11 -6
  225. package/dist/commands/agents.config.js +8 -10
  226. package/dist/commands/agents.providers.js +12 -6
  227. package/dist/commands/auth-choice-options.js +103 -75
  228. package/dist/commands/auth-choice.apply.byteplus.js +55 -0
  229. package/dist/commands/auth-choice.apply.js +4 -0
  230. package/dist/commands/auth-choice.apply.minimax.js +61 -13
  231. package/dist/commands/auth-choice.apply.openai.js +3 -1
  232. package/dist/commands/auth-choice.apply.volcengine.js +55 -0
  233. package/dist/commands/auth-choice.preferred-provider.js +2 -0
  234. package/dist/commands/channels/remove.js +13 -6
  235. package/dist/commands/channels/shared.js +4 -14
  236. package/dist/commands/configure.commands.js +14 -0
  237. package/dist/commands/configure.gateway.js +2 -4
  238. package/dist/commands/configure.js +1 -1
  239. package/dist/commands/configure.shared.js +11 -0
  240. package/dist/commands/daemon-install-helpers.js +2 -2
  241. package/dist/commands/dashboard.js +12 -10
  242. package/dist/commands/docs.js +14 -8
  243. package/dist/commands/doctor-config-flow.js +11 -9
  244. package/dist/commands/doctor-legacy-config.js +281 -0
  245. package/dist/commands/doctor-state-integrity.js +99 -23
  246. package/dist/commands/doctor-update.js +12 -9
  247. package/dist/commands/models/list.list-command.js +7 -5
  248. package/dist/commands/models/set-image.js +2 -21
  249. package/dist/commands/node-daemon-install-helpers.js +10 -8
  250. package/dist/commands/onboard-auth.config-minimax.js +54 -80
  251. package/dist/commands/onboard-auth.config-opencode.js +2 -18
  252. package/dist/commands/onboard-auth.credentials.js +90 -13
  253. package/dist/commands/onboard-auth.js +1 -1
  254. package/dist/commands/onboard-auth.models.js +6 -5
  255. package/dist/commands/onboard-hooks.js +1 -1
  256. package/dist/commands/onboard-non-interactive/api-keys.js +14 -7
  257. package/dist/commands/onboard-non-interactive/local/auth-choice.js +64 -49
  258. package/dist/commands/onboard-provider-auth-flags.js +14 -0
  259. package/dist/commands/onboard-remote.js +14 -7
  260. package/dist/commands/onboard.js +11 -13
  261. package/dist/commands/sandbox-display.js +6 -5
  262. package/dist/commands/status-all/diagnosis.js +14 -10
  263. package/dist/commands/status-all/format.js +1 -0
  264. package/dist/commands/status.gateway-probe.js +1 -16
  265. package/dist/commands/systemd-linger.js +12 -6
  266. package/dist/config/agent-limits.js +2 -0
  267. package/dist/config/commands.js +30 -16
  268. package/dist/config/config-paths.js +9 -11
  269. package/dist/config/defaults.js +22 -2
  270. package/dist/config/discord-preview-streaming.js +104 -0
  271. package/dist/config/env-vars.js +37 -8
  272. package/dist/config/includes.js +4 -0
  273. package/dist/config/io.js +97 -12
  274. package/dist/config/legacy.migrations.part-1.js +189 -78
  275. package/dist/config/legacy.shared.js +3 -1
  276. package/dist/config/merge-patch.js +4 -0
  277. package/dist/config/prototype-keys.js +4 -0
  278. package/dist/config/schema.help.js +44 -7
  279. package/dist/config/schema.labels.js +38 -6
  280. package/dist/config/sessions/delivery-info.js +10 -3
  281. package/dist/config/sessions/main-session.js +10 -5
  282. package/dist/config/sessions/session-file.js +33 -0
  283. package/dist/config/sessions/session-key.js +10 -5
  284. package/dist/config/sessions/store.js +1 -1
  285. package/dist/config/sessions.js +1 -0
  286. package/dist/config/zod-schema.agent-runtime.js +11 -0
  287. package/dist/config/zod-schema.js +148 -13
  288. package/dist/config/zod-schema.providers-core.js +78 -4
  289. package/dist/config/zod-schema.providers.js +6 -1
  290. package/dist/config/zod-schema.session.js +41 -2
  291. package/dist/cron/run-log.js +3 -0
  292. package/dist/cron/schedule.js +21 -10
  293. package/dist/cron/service/ops.js +35 -21
  294. package/dist/cron/service/timer.js +116 -16
  295. package/dist/cron/stagger.js +3 -1
  296. package/dist/discord/api.js +12 -6
  297. package/dist/discord/draft-chunking.js +22 -0
  298. package/dist/discord/draft-stream.js +124 -0
  299. package/dist/discord/monitor/agent-components.js +1 -1
  300. package/dist/discord/monitor/commands.js +5 -0
  301. package/dist/discord/monitor/gateway-plugin.js +2 -1
  302. package/dist/discord/monitor/listeners.js +37 -27
  303. package/dist/discord/monitor/message-handler.js +4 -1
  304. package/dist/discord/monitor/message-handler.preflight.js +65 -8
  305. package/dist/discord/monitor/message-handler.process.js +246 -217
  306. package/dist/discord/monitor/message-utils.js +143 -6
  307. package/dist/discord/monitor/model-picker-preferences.js +143 -0
  308. package/dist/discord/monitor/model-picker.js +651 -0
  309. package/dist/discord/monitor/native-command.js +573 -16
  310. package/dist/discord/monitor/provider.allowlist.js +223 -0
  311. package/dist/discord/monitor/provider.js +275 -347
  312. package/dist/discord/monitor/provider.lifecycle.js +100 -0
  313. package/dist/discord/monitor/reply-delivery.js +123 -16
  314. package/dist/discord/monitor/thread-bindings.discord-api.js +215 -0
  315. package/dist/discord/monitor/thread-bindings.js +4 -0
  316. package/dist/discord/monitor/thread-bindings.lifecycle.js +177 -0
  317. package/dist/discord/monitor/thread-bindings.manager.js +423 -0
  318. package/dist/discord/monitor/thread-bindings.messages.js +55 -0
  319. package/dist/discord/monitor/thread-bindings.state.js +358 -0
  320. package/dist/discord/monitor/thread-bindings.types.js +6 -0
  321. package/dist/discord/resolve-users.js +33 -21
  322. package/dist/discord/send.channels.js +15 -0
  323. package/dist/discord/send.js +3 -2
  324. package/dist/discord/send.outbound.js +82 -26
  325. package/dist/discord/send.permissions.js +83 -30
  326. package/dist/discord/send.reactions.js +8 -4
  327. package/dist/discord/token.js +10 -5
  328. package/dist/discord/voice/command.js +263 -0
  329. package/dist/discord/voice/manager.js +531 -0
  330. package/dist/gateway/auth.js +34 -10
  331. package/dist/gateway/call.js +4 -16
  332. package/dist/gateway/client.js +28 -4
  333. package/dist/gateway/config-reload.js +3 -4
  334. package/dist/gateway/control-ui.js +219 -96
  335. package/dist/gateway/hooks-mapping.js +88 -38
  336. package/dist/gateway/http-auth-helpers.js +3 -2
  337. package/dist/gateway/http-endpoint-helpers.js +1 -0
  338. package/dist/gateway/net.js +54 -12
  339. package/dist/gateway/node-invoke-system-run-approval.js +14 -35
  340. package/dist/gateway/node-registry.js +10 -5
  341. package/dist/gateway/openai-http.js +1 -0
  342. package/dist/gateway/openresponses-http.js +1 -0
  343. package/dist/gateway/origin-check.js +1 -18
  344. package/dist/gateway/protocol/index.js +4 -3
  345. package/dist/gateway/protocol/schema/cron.js +1 -0
  346. package/dist/gateway/protocol/schema/devices.js +1 -0
  347. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -1
  348. package/dist/gateway/protocol/schema/sessions.js +6 -0
  349. package/dist/gateway/role-policy.js +17 -0
  350. package/dist/gateway/server/ws-connection/connect-policy.js +37 -0
  351. package/dist/gateway/server/ws-connection/message-handler.js +175 -148
  352. package/dist/gateway/server-chat.js +83 -25
  353. package/dist/gateway/server-constants.js +10 -9
  354. package/dist/gateway/server-cron.js +1 -0
  355. package/dist/gateway/server-http.js +16 -7
  356. package/dist/gateway/server-maintenance.js +20 -5
  357. package/dist/gateway/server-methods/chat.js +10 -6
  358. package/dist/gateway/server-methods/config.js +12 -14
  359. package/dist/gateway/server-methods/devices.js +17 -3
  360. package/dist/gateway/server-methods/models.js +11 -1
  361. package/dist/gateway/server-methods/sessions.js +64 -8
  362. package/dist/gateway/server-methods/usage.js +162 -75
  363. package/dist/gateway/server-node-events.js +29 -0
  364. package/dist/gateway/server-runtime-config.js +34 -13
  365. package/dist/gateway/server-startup-memory.js +17 -11
  366. package/dist/gateway/session-utils.fs.js +32 -34
  367. package/dist/gateway/sessions-resolve.js +17 -5
  368. package/dist/gateway/test-helpers.openai-mock.js +14 -7
  369. package/dist/gateway/tools-invoke-http.js +21 -10
  370. package/dist/hooks/bundled/bootstrap-extra-files/handler.js +3 -1
  371. package/dist/hooks/bundled/command-logger/handler.js +7 -2
  372. package/dist/hooks/bundled/session-memory/handler.js +6 -5
  373. package/dist/hooks/frontmatter.js +6 -6
  374. package/dist/hooks/gmail-watcher.js +11 -6
  375. package/dist/hooks/internal-hooks.js +11 -1
  376. package/dist/hooks/llm-slug-generator.js +4 -1
  377. package/dist/hooks/workspace.js +47 -17
  378. package/dist/imessage/accounts.js +9 -20
  379. package/dist/imessage/monitor/inbound-processing.js +2 -1
  380. package/dist/infra/archive.js +174 -73
  381. package/dist/infra/control-ui-assets.js +14 -6
  382. package/dist/infra/device-pairing.js +108 -29
  383. package/dist/infra/env.js +10 -5
  384. package/dist/infra/exec-approvals-allowlist.js +122 -0
  385. package/dist/infra/exec-approvals-analysis.js +34 -3
  386. package/dist/infra/exec-approvals.js +5 -17
  387. package/dist/infra/exec-safe-bin-policy.js +53 -45
  388. package/dist/infra/fs-safe.js +71 -39
  389. package/dist/infra/gateway-lock.js +6 -2
  390. package/dist/infra/heartbeat-wake.js +6 -12
  391. package/dist/infra/host-env-security-policy.json +19 -0
  392. package/dist/infra/host-env-security.js +66 -0
  393. package/dist/infra/net/ssrf.js +131 -38
  394. package/dist/infra/outbound/bound-delivery-router.js +88 -0
  395. package/dist/infra/outbound/channel-selection.js +12 -6
  396. package/dist/infra/outbound/envelope.js +1 -1
  397. package/dist/infra/outbound/format.js +12 -6
  398. package/dist/infra/outbound/payloads.js +14 -7
  399. package/dist/infra/outbound/session-binding-service.js +123 -0
  400. package/dist/infra/path-guards.js +25 -0
  401. package/dist/infra/provider-usage.fetch.codex.js +7 -15
  402. package/dist/infra/provider-usage.fetch.gemini.js +14 -11
  403. package/dist/infra/provider-usage.fetch.shared.js +30 -1
  404. package/dist/infra/provider-usage.fetch.zai.js +10 -9
  405. package/dist/infra/retry-policy.js +4 -2
  406. package/dist/infra/retry.js +9 -5
  407. package/dist/infra/session-cost-usage.js +107 -59
  408. package/dist/infra/session-maintenance-warning.js +3 -1
  409. package/dist/infra/shell-env.js +98 -34
  410. package/dist/infra/ssh-config.js +12 -6
  411. package/dist/infra/system-run-command.js +49 -4
  412. package/dist/infra/update-channels.js +10 -5
  413. package/dist/line/accounts.js +5 -7
  414. package/dist/line/bot-access.js +8 -20
  415. package/dist/line/bot-handlers.js +3 -1
  416. package/dist/link-understanding/detect.js +15 -7
  417. package/dist/media/constants.js +15 -6
  418. package/dist/media/image-ops.js +7 -0
  419. package/dist/media/local-roots.js +3 -2
  420. package/dist/media-understanding/apply.js +4 -1
  421. package/dist/media-understanding/concurrency.js +8 -20
  422. package/dist/memory/backend-config.js +45 -6
  423. package/dist/memory/embeddings.js +10 -4
  424. package/dist/memory/fs-utils.js +23 -0
  425. package/dist/memory/manager-search.js +12 -6
  426. package/dist/memory/manager-sync-ops.js +12 -2
  427. package/dist/memory/qmd-manager.js +466 -53
  428. package/dist/memory/query-expansion.js +167 -3
  429. package/dist/memory/status-format.js +10 -5
  430. package/dist/memory/sync-memory-files.js +1 -1
  431. package/dist/node-host/invoke-system-run.js +281 -0
  432. package/dist/node-host/invoke.js +55 -337
  433. package/dist/pairing/pairing-store.js +22 -0
  434. package/dist/plugin-sdk/allow-from.js +1 -1
  435. package/dist/plugin-sdk/command-auth.js +3 -1
  436. package/dist/plugin-sdk/index.js +6 -3
  437. package/dist/plugin-sdk/webhook-targets.js +32 -0
  438. package/dist/plugins/bundled-dir.js +9 -6
  439. package/dist/plugins/hooks.js +50 -0
  440. package/dist/plugins/install.js +28 -16
  441. package/dist/plugins/runtime.js +3 -17
  442. package/dist/plugins/update.js +78 -12
  443. package/dist/process/spawn-utils.js +14 -7
  444. package/dist/providers/github-copilot-token.js +11 -6
  445. package/dist/providers/qwen-portal-oauth.js +14 -6
  446. package/dist/routing/account-id.js +30 -0
  447. package/dist/routing/resolve-route.js +3 -7
  448. package/dist/routing/session-key.js +2 -16
  449. package/dist/security/audit-channel.js +93 -2
  450. package/dist/security/audit-extra.async.js +159 -5
  451. package/dist/security/audit-extra.js +1 -1
  452. package/dist/security/audit-extra.sync.js +85 -6
  453. package/dist/security/audit.js +40 -4
  454. package/dist/security/dm-policy-shared.js +44 -0
  455. package/dist/security/external-content.js +26 -6
  456. package/dist/shared/entry-status.js +6 -0
  457. package/dist/shared/frontmatter.js +5 -5
  458. package/dist/shared/node-match.js +11 -4
  459. package/dist/shared/operator-scope-compat.js +8 -3
  460. package/dist/signal/accounts.js +7 -20
  461. package/dist/signal/monitor/event-handler.js +3 -1
  462. package/dist/slack/accounts.js +6 -19
  463. package/dist/slack/actions.js +11 -3
  464. package/dist/slack/monitor/auth.js +1 -1
  465. package/dist/slack/monitor/message-handler/dispatch.js +50 -29
  466. package/dist/slack/monitor/replies.js +15 -7
  467. package/dist/slack/monitor/slash.js +22 -13
  468. package/dist/slack/resolve-channels.js +10 -5
  469. package/dist/slack/send.js +102 -12
  470. package/dist/slack/stream-mode.js +10 -0
  471. package/dist/slack/streaming.js +4 -2
  472. package/dist/telegram/accounts.js +19 -14
  473. package/dist/telegram/bot/helpers.js +3 -5
  474. package/dist/telegram/bot-access.js +35 -36
  475. package/dist/telegram/bot-handlers.js +120 -148
  476. package/dist/telegram/bot-message-context.js +68 -9
  477. package/dist/telegram/bot-message-dispatch.js +155 -90
  478. package/dist/telegram/bot-native-commands.js +16 -0
  479. package/dist/telegram/draft-stream.js +14 -1
  480. package/dist/telegram/inline-buttons.js +5 -15
  481. package/dist/telegram/monitor.js +11 -7
  482. package/dist/telegram/network-config.js +19 -7
  483. package/dist/telegram/send.js +3 -2
  484. package/dist/telegram/sent-message-cache.js +5 -6
  485. package/dist/telegram/status-reaction-variants.js +208 -0
  486. package/dist/telegram/sticker-cache.js +11 -9
  487. package/dist/terminal/theme.js +12 -12
  488. package/dist/tts/tts.js +80 -567
  489. package/dist/tui/components/chat-log.js +41 -8
  490. package/dist/tui/theme/theme.js +10 -12
  491. package/dist/tui/tui-local-shell.js +16 -6
  492. package/dist/tui/tui.js +58 -6
  493. package/dist/utils/account-id.js +2 -4
  494. package/dist/utils/boolean.js +10 -5
  495. package/dist/utils/directive-tags.js +11 -0
  496. package/dist/utils/queue-helpers.js +67 -12
  497. package/dist/web/auto-reply/deliver-reply.js +8 -4
  498. package/dist/web/auto-reply/mentions.js +10 -5
  499. package/dist/web/auto-reply/monitor/group-members.js +14 -7
  500. package/dist/web/auto-reply/monitor/process-message.js +45 -24
  501. package/dist/web/inbound/access-control.js +5 -2
  502. package/dist/web/login-qr.js +12 -6
  503. package/dist/web/media.js +123 -16
  504. package/extensions/bluebubbles/src/monitor-processing.ts +580 -139
  505. package/extensions/bluebubbles/src/monitor.ts +208 -1950
  506. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
- import { resolveDefaultAgentId } from "../agents/agent-scope.js";
1
+ import { resolveAgentDir, resolveDefaultAgentId } from "../agents/agent-scope.js";
2
2
  import { hasControlCommand } from "../auto-reply/command-detection.js";
3
3
  import { createInboundDebouncer, resolveInboundDebounceMs, } from "../auto-reply/inbound-debounce.js";
4
4
  import { buildCommandsPaginationKeyboard } from "../auto-reply/reply/commands-info.js";
5
- import { buildModelsProviderData } from "../auto-reply/reply/commands-models.js";
5
+ import { buildModelsProviderData, formatModelsAvailableHeader, } from "../auto-reply/reply/commands-models.js";
6
6
  import { resolveStoredModelOverride } from "../auto-reply/reply/model-selection.js";
7
7
  import { listSkillCommandsForAgents } from "../auto-reply/skill-commands.js";
8
8
  import { buildCommandsMessagePaginated } from "../auto-reply/status.js";
@@ -16,8 +16,8 @@ import { readChannelAllowFromStore } from "../pairing/pairing-store.js";
16
16
  import { resolveAgentRoute } from "../routing/resolve-route.js";
17
17
  import { resolveThreadSessionKeys } from "../routing/session-key.js";
18
18
  import { withTelegramApiErrorLogging } from "./api-logging.js";
19
- import { firstDefined, isSenderAllowed, normalizeAllowFromWithStore, } from "./bot-access.js";
20
- import { MEDIA_GROUP_TIMEOUT_MS } from "./bot-updates.js";
19
+ import { isSenderAllowed, normalizeAllowFromWithStore, } from "./bot-access.js";
20
+ import { MEDIA_GROUP_TIMEOUT_MS, } from "./bot-updates.js";
21
21
  import { resolveMedia } from "./bot/delivery.js";
22
22
  import { buildTelegramGroupPeerId, buildTelegramParentPeer, resolveTelegramForumThreadId, resolveTelegramGroupAllowFromContext, } from "./bot/helpers.js";
23
23
  import { evaluateTelegramGroupBaseAccess, evaluateTelegramGroupPolicyAccess, } from "./group-access.js";
@@ -103,7 +103,7 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
103
103
  runtime.error?.(danger(`telegram debounce flush failed: ${String(err)}`));
104
104
  },
105
105
  });
106
- const resolveTelegramSessionModel = (params) => {
106
+ const resolveTelegramSessionState = (params) => {
107
107
  const resolvedThreadId = params.resolvedThreadId ??
108
108
  resolveTelegramForumThreadId({
109
109
  isForum: params.isForum,
@@ -142,17 +142,29 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
142
142
  sessionKey,
143
143
  });
144
144
  if (storedOverride) {
145
- return storedOverride.provider
146
- ? `${storedOverride.provider}/${storedOverride.model}`
147
- : storedOverride.model;
145
+ return {
146
+ agentId: route.agentId,
147
+ sessionEntry: entry,
148
+ model: storedOverride.provider
149
+ ? `${storedOverride.provider}/${storedOverride.model}`
150
+ : storedOverride.model,
151
+ };
148
152
  }
149
153
  const provider = entry?.modelProvider?.trim();
150
154
  const model = entry?.model?.trim();
151
155
  if (provider && model) {
152
- return `${provider}/${model}`;
156
+ return {
157
+ agentId: route.agentId,
158
+ sessionEntry: entry,
159
+ model: `${provider}/${model}`,
160
+ };
153
161
  }
154
162
  const modelCfg = cfg.agents?.defaults?.model;
155
- return typeof modelCfg === "string" ? modelCfg : modelCfg?.primary;
163
+ return {
164
+ agentId: route.agentId,
165
+ sessionEntry: entry,
166
+ model: typeof modelCfg === "string" ? modelCfg : modelCfg?.primary,
167
+ };
156
168
  };
157
169
  const processMediaGroup = async (entry) => {
158
170
  try {
@@ -385,7 +397,7 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
385
397
  const processInboundMessage = async (params) => {
386
398
  const { ctx, msg, chatId, resolvedThreadId, storeAllowFrom, sendOversizeWarning, oversizeLogMessage, } = params;
387
399
  // Text fragment handling - Telegram splits long pastes into multiple inbound messages (~4096 chars).
388
- // We buffer near-limit messages and append immediately-following parts.
400
+ // We buffer "near-limit" messages and append immediately-following parts.
389
401
  const text = typeof msg.text === "string" ? msg.text : undefined;
390
402
  const isCommandLike = (text ?? "").trim().startsWith("/");
391
403
  if (text && !isCommandLike) {
@@ -585,17 +597,19 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
585
597
  const groupAllowContext = await resolveTelegramGroupAllowFromContext({
586
598
  chatId,
587
599
  accountId,
600
+ dmPolicy: telegramCfg.dmPolicy ?? "pairing",
588
601
  isForum,
589
602
  messageThreadId,
590
603
  groupAllowFrom,
591
604
  resolveTelegramGroupConfig,
592
605
  });
593
606
  const { resolvedThreadId, storeAllowFrom, groupConfig, topicConfig, effectiveGroupAllow, hasGroupAllowOverride, } = groupAllowContext;
607
+ const dmPolicy = telegramCfg.dmPolicy ?? "pairing";
594
608
  const effectiveDmAllow = normalizeAllowFromWithStore({
595
609
  allowFrom: telegramCfg.allowFrom,
596
610
  storeAllowFrom,
611
+ dmPolicy,
597
612
  });
598
- const dmPolicy = telegramCfg.dmPolicy ?? "pairing";
599
613
  const senderId = callback.from?.id ? String(callback.from.id) : "";
600
614
  const senderUsername = callback.from?.username ?? "";
601
615
  if (shouldSkipGroupMessage({
@@ -719,13 +733,14 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
719
733
  const totalPages = calculateTotalPages(models.length, pageSize);
720
734
  const safePage = Math.max(1, Math.min(page, totalPages));
721
735
  // Resolve current model from session (prefer overrides)
722
- const currentModel = resolveTelegramSessionModel({
736
+ const sessionState = resolveTelegramSessionState({
723
737
  chatId,
724
738
  isGroup,
725
739
  isForum,
726
740
  messageThreadId,
727
741
  resolvedThreadId,
728
742
  });
743
+ const currentModel = sessionState.model;
729
744
  const buttons = buildModelsKeyboard({
730
745
  provider,
731
746
  models,
@@ -734,7 +749,13 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
734
749
  totalPages,
735
750
  pageSize,
736
751
  });
737
- const text = `Models (${provider}) — ${models.length} available`;
752
+ const text = formatModelsAvailableHeader({
753
+ provider,
754
+ total: models.length,
755
+ cfg,
756
+ agentDir: resolveAgentDir(cfg, sessionState.agentId),
757
+ sessionEntry: sessionState.sessionEntry,
758
+ });
738
759
  await editMessageWithButtons(text, buttons);
739
760
  return;
740
761
  }
@@ -811,37 +832,32 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
811
832
  runtime.error?.(danger(`[telegram] Group migration handler failed: ${String(err)}`));
812
833
  }
813
834
  });
814
- bot.on("message", async (ctx) => {
835
+ const handleInboundMessageLike = async (event) => {
815
836
  try {
816
- const msg = ctx.message;
817
- if (!msg) {
837
+ if (shouldSkipUpdate(event.ctxForDedupe)) {
818
838
  return;
819
839
  }
820
- if (shouldSkipUpdate(ctx)) {
821
- return;
822
- }
823
- const chatId = msg.chat.id;
824
- const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup";
825
- const messageThreadId = msg.message_thread_id;
826
- const isForum = msg.chat.is_forum === true;
827
840
  const groupAllowContext = await resolveTelegramGroupAllowFromContext({
828
- chatId,
841
+ chatId: event.chatId,
829
842
  accountId,
830
- isForum,
831
- messageThreadId,
843
+ dmPolicy: telegramCfg.dmPolicy ?? "pairing",
844
+ isForum: event.isForum,
845
+ messageThreadId: event.messageThreadId,
832
846
  groupAllowFrom,
833
847
  resolveTelegramGroupConfig,
834
848
  });
835
849
  const { resolvedThreadId, storeAllowFrom, groupConfig, topicConfig, effectiveGroupAllow, hasGroupAllowOverride, } = groupAllowContext;
836
- const senderId = msg.from?.id != null ? String(msg.from.id) : "";
837
- const senderUsername = msg.from?.username ?? "";
850
+ if (event.requireConfiguredGroup && (!groupConfig || groupConfig.enabled === false)) {
851
+ logVerbose(`Blocked telegram channel ${event.chatId} (channel disabled)`);
852
+ return;
853
+ }
838
854
  if (shouldSkipGroupMessage({
839
- isGroup,
840
- chatId,
841
- chatTitle: msg.chat.title,
855
+ isGroup: event.isGroup,
856
+ chatId: event.chatId,
857
+ chatTitle: event.msg.chat.title,
842
858
  resolvedThreadId,
843
- senderId,
844
- senderUsername,
859
+ senderId: event.senderId,
860
+ senderUsername: event.senderUsername,
845
861
  effectiveGroupAllow,
846
862
  hasGroupAllowOverride,
847
863
  groupConfig,
@@ -850,131 +866,87 @@ export const registerTelegramHandlers = ({ cfg, accountId, bot, opts, runtime, m
850
866
  return;
851
867
  }
852
868
  await processInboundMessage({
853
- ctx,
854
- msg,
855
- chatId,
869
+ ctx: event.ctx,
870
+ msg: event.msg,
871
+ chatId: event.chatId,
856
872
  resolvedThreadId,
857
873
  storeAllowFrom,
858
- sendOversizeWarning: true,
859
- oversizeLogMessage: "media exceeds size limit",
874
+ sendOversizeWarning: event.sendOversizeWarning,
875
+ oversizeLogMessage: event.oversizeLogMessage,
860
876
  });
861
877
  }
862
878
  catch (err) {
863
- runtime.error?.(danger(`handler failed: ${String(err)}`));
879
+ runtime.error?.(danger(`${event.errorMessage}: ${String(err)}`));
864
880
  }
881
+ };
882
+ bot.on("message", async (ctx) => {
883
+ const msg = ctx.message;
884
+ if (!msg) {
885
+ return;
886
+ }
887
+ await handleInboundMessageLike({
888
+ ctxForDedupe: ctx,
889
+ ctx: buildSyntheticContext(ctx, msg),
890
+ msg,
891
+ chatId: msg.chat.id,
892
+ isGroup: msg.chat.type === "group" || msg.chat.type === "supergroup",
893
+ isForum: msg.chat.is_forum === true,
894
+ messageThreadId: msg.message_thread_id,
895
+ senderId: msg.from?.id != null ? String(msg.from.id) : "",
896
+ senderUsername: msg.from?.username ?? "",
897
+ requireConfiguredGroup: false,
898
+ sendOversizeWarning: true,
899
+ oversizeLogMessage: "media exceeds size limit",
900
+ errorMessage: "handler failed",
901
+ });
865
902
  });
866
903
  // Handle channel posts — enables bot-to-bot communication via Telegram channels.
867
904
  // Telegram bots cannot see other bot messages in groups, but CAN in channels.
868
905
  // This handler normalizes channel_post updates into the standard message pipeline.
869
906
  bot.on("channel_post", async (ctx) => {
870
- try {
871
- const post = ctx.channelPost;
872
- if (!post) {
873
- return;
874
- }
875
- // Deduplication check — same as the regular message handler
876
- if (shouldSkipUpdate(ctx)) {
877
- return;
878
- }
879
- const chatId = post.chat.id;
880
- // Use the full group allow-from context for access control (same as message handler)
881
- const groupAllowContext = await resolveTelegramGroupAllowFromContext({
882
- chatId,
883
- accountId,
884
- isForum: false,
885
- messageThreadId: undefined,
886
- groupAllowFrom,
887
- resolveTelegramGroupConfig,
888
- });
889
- const { storeAllowFrom, groupConfig, effectiveGroupAllow, hasGroupAllowOverride } = groupAllowContext;
890
- // Check group allowlist (channels use the same groups config)
891
- const groupAllowlist = resolveGroupPolicy(chatId);
892
- if (groupAllowlist.allowlistEnabled && !groupAllowlist.allowed) {
893
- return;
894
- }
895
- if (!groupConfig || groupConfig.enabled === false) {
896
- logVerbose(`Blocked telegram channel ${chatId} (channel disabled)`);
897
- return;
898
- }
899
- // Group policy filtering (same as message handler)
900
- const defaultGroupPolicy = cfg.channels?.defaults?.groupPolicy;
901
- const groupPolicy = firstDefined(groupConfig?.groupPolicy, telegramCfg.groupPolicy, defaultGroupPolicy, "open");
902
- if (groupPolicy === "disabled") {
903
- logVerbose(`Blocked telegram channel message (groupPolicy: disabled)`);
904
- return;
905
- }
906
- if (hasGroupAllowOverride) {
907
- const senderId = post.sender_chat?.id ?? post.from?.id;
908
- const senderUsername = post.sender_chat?.username ?? post.from?.username ?? "";
909
- const allowed = senderId != null &&
910
- isSenderAllowed({
911
- allow: effectiveGroupAllow,
912
- senderId: String(senderId),
913
- senderUsername,
914
- });
915
- if (!allowed) {
916
- logVerbose(`Blocked telegram channel sender ${senderId ?? "unknown"} (group allowFrom override)`);
917
- return;
918
- }
919
- }
920
- if (groupPolicy === "allowlist") {
921
- const senderId = post.sender_chat?.id ?? post.from?.id;
922
- if (senderId == null) {
923
- logVerbose(`Blocked telegram channel message (no sender ID, groupPolicy: allowlist)`);
924
- return;
925
- }
926
- if (!effectiveGroupAllow.hasEntries) {
927
- logVerbose("Blocked telegram channel message (groupPolicy: allowlist, no allowlist entries)");
928
- return;
929
- }
930
- const senderUsername = post.sender_chat?.username ?? post.from?.username ?? "";
931
- if (!isSenderAllowed({
932
- allow: effectiveGroupAllow,
933
- senderId: String(senderId),
934
- senderUsername,
935
- })) {
936
- logVerbose(`Blocked telegram channel message from ${senderId} (groupPolicy: allowlist)`);
937
- return;
938
- }
939
- }
940
- // Build a synthetic `from` field since channel posts may not have one.
941
- // Use sender_chat (the bot/user that posted) if available.
942
- const syntheticFrom = post.sender_chat
943
- ? {
944
- id: post.sender_chat.id,
945
- is_bot: true,
946
- first_name: post.sender_chat.title || "Channel",
947
- username: post.sender_chat.username,
948
- }
949
- : {
950
- id: chatId,
951
- is_bot: true,
952
- first_name: post.chat.title || "Channel",
953
- username: post.chat.username,
954
- };
955
- const syntheticMsg = {
956
- ...post,
957
- from: post.from ?? syntheticFrom,
958
- chat: {
959
- ...post.chat,
960
- type: "supergroup",
961
- },
962
- };
963
- const syntheticCtx = Object.create(ctx, {
964
- message: { value: syntheticMsg, writable: true, enumerable: true },
965
- });
966
- await processInboundMessage({
967
- ctx: syntheticCtx,
968
- msg: syntheticMsg,
969
- chatId,
970
- resolvedThreadId: undefined,
971
- storeAllowFrom,
972
- sendOversizeWarning: false,
973
- oversizeLogMessage: "channel post media exceeds size limit",
974
- });
975
- }
976
- catch (err) {
977
- runtime.error?.(danger(`channel_post handler failed: ${String(err)}`));
907
+ const post = ctx.channelPost;
908
+ if (!post) {
909
+ return;
978
910
  }
911
+ const chatId = post.chat.id;
912
+ const syntheticFrom = post.sender_chat
913
+ ? {
914
+ id: post.sender_chat.id,
915
+ is_bot: true,
916
+ first_name: post.sender_chat.title || "Channel",
917
+ username: post.sender_chat.username,
918
+ }
919
+ : {
920
+ id: chatId,
921
+ is_bot: true,
922
+ first_name: post.chat.title || "Channel",
923
+ username: post.chat.username,
924
+ };
925
+ const syntheticMsg = {
926
+ ...post,
927
+ from: post.from ?? syntheticFrom,
928
+ chat: {
929
+ ...post.chat,
930
+ type: "supergroup",
931
+ },
932
+ };
933
+ await handleInboundMessageLike({
934
+ ctxForDedupe: ctx,
935
+ ctx: buildSyntheticContext(ctx, syntheticMsg),
936
+ msg: syntheticMsg,
937
+ chatId,
938
+ isGroup: true,
939
+ isForum: false,
940
+ senderId: post.sender_chat?.id != null
941
+ ? String(post.sender_chat.id)
942
+ : post.from?.id != null
943
+ ? String(post.from.id)
944
+ : "",
945
+ senderUsername: post.sender_chat?.username ?? post.from?.username ?? "",
946
+ requireConfiguredGroup: true,
947
+ sendOversizeWarning: false,
948
+ oversizeLogMessage: "channel post media exceeds size limit",
949
+ errorMessage: "channel_post handler failed",
950
+ });
979
951
  });
980
952
  };
@@ -13,6 +13,7 @@ import { formatLocationText, toLocationContext } from "../channels/location.js";
13
13
  import { logInboundDrop } from "../channels/logging.js";
14
14
  import { resolveMentionGatingWithBypass } from "../channels/mention-gating.js";
15
15
  import { recordInboundSession } from "../channels/session.js";
16
+ import { createStatusReactionController, } from "../channels/status-reactions.js";
16
17
  import { loadConfig } from "../config/config.js";
17
18
  import { readSessionUpdatedAt, resolveStorePath } from "../config/sessions.js";
18
19
  import { logVerbose, shouldLogVerbose } from "../globals.js";
@@ -25,6 +26,7 @@ import { withTelegramApiErrorLogging } from "./api-logging.js";
25
26
  import { firstDefined, isSenderAllowed, normalizeAllowFromWithStore, resolveSenderAllowMatch, } from "./bot-access.js";
26
27
  import { buildGroupLabel, buildSenderLabel, buildSenderName, buildTelegramGroupFrom, buildTelegramGroupPeerId, buildTelegramParentPeer, buildTypingThreadParams, resolveTelegramMediaPlaceholder, expandTextLinks, normalizeForwardedContext, describeReplyTarget, extractTelegramLocation, hasBotMention, resolveTelegramThreadSpec, } from "./bot/helpers.js";
27
28
  import { evaluateTelegramGroupBaseAccess } from "./group-access.js";
29
+ import { buildTelegramStatusReactionVariants, resolveTelegramAllowedEmojiReactions, resolveTelegramReactionVariant, resolveTelegramStatusReactionEmojis, } from "./status-reaction-variants.js";
28
30
  async function resolveStickerVisionSupport(params) {
29
31
  try {
30
32
  const catalog = await loadModelCatalog({ config: params.cfg });
@@ -82,11 +84,12 @@ export const buildTelegramMessageContext = async ({ primaryCtx, allMedia, storeA
82
84
  : null;
83
85
  const sessionKey = threadKeys?.sessionKey ?? baseSessionKey;
84
86
  const mentionRegexes = buildMentionRegexes(cfg, route.agentId);
85
- const effectiveDmAllow = normalizeAllowFromWithStore({ allowFrom, storeAllowFrom });
87
+ const effectiveDmAllow = normalizeAllowFromWithStore({ allowFrom, storeAllowFrom, dmPolicy });
86
88
  const groupAllowOverride = firstDefined(topicConfig?.allowFrom, groupConfig?.allowFrom);
87
89
  const effectiveGroupAllow = normalizeAllowFromWithStore({
88
90
  allowFrom: groupAllowOverride ?? groupAllowFrom,
89
91
  storeAllowFrom,
92
+ dmPolicy,
90
93
  });
91
94
  const hasGroupAllowOverride = typeof groupAllowOverride !== "undefined";
92
95
  const senderId = msg.from?.id ? String(msg.from.id) : "";
@@ -363,15 +366,70 @@ export const buildTelegramMessageContext = async ({ primaryCtx, allMedia, storeA
363
366
  }));
364
367
  const api = bot.api;
365
368
  const reactionApi = typeof api.setMessageReaction === "function" ? api.setMessageReaction.bind(api) : null;
366
- const ackReactionPromise = shouldAckReaction() && msg.message_id && reactionApi
367
- ? withTelegramApiErrorLogging({
368
- operation: "setMessageReaction",
369
- fn: () => reactionApi(chatId, msg.message_id, [{ type: "emoji", emoji: ackReaction }]),
370
- }).then(() => true, (err) => {
371
- logVerbose(`telegram react failed for chat ${chatId}: ${String(err)}`);
372
- return false;
369
+ const getChatApi = typeof api.getChat === "function" ? api.getChat.bind(api) : null;
370
+ // Status Reactions controller (lifecycle reactions)
371
+ const statusReactionsConfig = cfg.messages?.statusReactions;
372
+ const statusReactionsEnabled = statusReactionsConfig?.enabled === true && Boolean(reactionApi) && shouldAckReaction();
373
+ const resolvedStatusReactionEmojis = resolveTelegramStatusReactionEmojis({
374
+ initialEmoji: ackReaction,
375
+ overrides: statusReactionsConfig?.emojis,
376
+ });
377
+ const statusReactionVariantsByEmoji = buildTelegramStatusReactionVariants(resolvedStatusReactionEmojis);
378
+ let allowedStatusReactionEmojisPromise = null;
379
+ const statusReactionController = statusReactionsEnabled && msg.message_id
380
+ ? createStatusReactionController({
381
+ enabled: true,
382
+ adapter: {
383
+ setReaction: async (emoji) => {
384
+ if (reactionApi) {
385
+ if (!allowedStatusReactionEmojisPromise) {
386
+ allowedStatusReactionEmojisPromise = resolveTelegramAllowedEmojiReactions({
387
+ chat: msg.chat,
388
+ chatId,
389
+ getChat: getChatApi ?? undefined,
390
+ }).catch((err) => {
391
+ logVerbose(`telegram status-reaction available_reactions lookup failed for chat ${chatId}: ${String(err)}`);
392
+ return null;
393
+ });
394
+ }
395
+ const allowedStatusReactionEmojis = await allowedStatusReactionEmojisPromise;
396
+ const resolvedEmoji = resolveTelegramReactionVariant({
397
+ requestedEmoji: emoji,
398
+ variantsByRequestedEmoji: statusReactionVariantsByEmoji,
399
+ allowedEmojiReactions: allowedStatusReactionEmojis,
400
+ });
401
+ if (!resolvedEmoji) {
402
+ return;
403
+ }
404
+ await reactionApi(chatId, msg.message_id, [
405
+ { type: "emoji", emoji: resolvedEmoji },
406
+ ]);
407
+ }
408
+ },
409
+ // Telegram replaces atomically — no removeReaction needed
410
+ },
411
+ initialEmoji: ackReaction,
412
+ emojis: resolvedStatusReactionEmojis,
413
+ timing: statusReactionsConfig?.timing,
414
+ onError: (err) => {
415
+ logVerbose(`telegram status-reaction error for chat ${chatId}: ${String(err)}`);
416
+ },
373
417
  })
374
418
  : null;
419
+ // When status reactions are enabled, setQueued() replaces the simple ack reaction
420
+ const ackReactionPromise = statusReactionController
421
+ ? shouldAckReaction()
422
+ ? Promise.resolve(statusReactionController.setQueued()).then(() => true, () => false)
423
+ : null
424
+ : shouldAckReaction() && msg.message_id && reactionApi
425
+ ? withTelegramApiErrorLogging({
426
+ operation: "setMessageReaction",
427
+ fn: () => reactionApi(chatId, msg.message_id, [{ type: "emoji", emoji: ackReaction }]),
428
+ }).then(() => true, (err) => {
429
+ logVerbose(`telegram react failed for chat ${chatId}: ${String(err)}`);
430
+ return false;
431
+ })
432
+ : null;
375
433
  const replyTarget = describeReplyTarget(msg);
376
434
  const forwardOrigin = normalizeForwardedContext(msg);
377
435
  const replySuffix = replyTarget
@@ -514,7 +572,7 @@ export const buildTelegramMessageContext = async ({ primaryCtx, allMedia, storeA
514
572
  ? {
515
573
  sessionKey: route.mainSessionKey,
516
574
  channel: "telegram",
517
- to: String(chatId),
575
+ to: `telegram:${chatId}`,
518
576
  accountId: route.accountId,
519
577
  // Preserve DM topic threadId for replies (fixes #8891)
520
578
  threadId: dmThreadId != null ? String(dmThreadId) : undefined,
@@ -557,6 +615,7 @@ export const buildTelegramMessageContext = async ({ primaryCtx, allMedia, storeA
557
615
  ackReactionPromise,
558
616
  reactionApi,
559
617
  removeAckAfterReply,
618
+ statusReactionController,
560
619
  accountId: account.accountId,
561
620
  };
562
621
  };