@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,7 +1,6 @@
1
1
  import { resolveAgentDir } from "../agents/agent-scope.js";
2
2
  import { findModelInCatalog, loadModelCatalog, modelSupportsVision, } from "../agents/model-catalog.js";
3
3
  import { resolveDefaultModelForAgent } from "../agents/model-selection.js";
4
- import { EmbeddedBlockChunker } from "../agents/pi-embedded-block-chunker.js";
5
4
  import { resolveChunkMode } from "../auto-reply/chunk.js";
6
5
  import { clearHistoryEntriesIfEnabled } from "../auto-reply/reply/history.js";
7
6
  import { dispatchReplyWithBufferedBlockDispatcher } from "../auto-reply/reply/provider-dispatcher.js";
@@ -14,7 +13,6 @@ import { loadSessionStore, resolveStorePath } from "../config/sessions.js";
14
13
  import { danger, logVerbose } from "../globals.js";
15
14
  import { getAgentScopedMediaLocalRoots } from "../media/local-roots.js";
16
15
  import { deliverReplies } from "./bot/delivery.js";
17
- import { resolveTelegramDraftStreamingChunking } from "./draft-chunking.js";
18
16
  import { createTelegramDraftStream } from "./draft-stream.js";
19
17
  import { renderTelegramHtmlText } from "./format.js";
20
18
  import { createTelegramReasoningStepState, splitTelegramReasoningText, } from "./reasoning-lane-coordinator.js";
@@ -57,7 +55,7 @@ function resolveTelegramReasoningLevel(params) {
57
55
  return "off";
58
56
  }
59
57
  export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, replyToMode, streamMode, textLimit, telegramCfg, opts, }) => {
60
- const { ctxPayload, msg, chatId, isGroup, threadSpec, historyKey, historyLimit, groupHistories, route, skillFilter, sendTyping, sendRecordVoice, ackReactionPromise, reactionApi, removeAckAfterReply, } = context;
58
+ const { ctxPayload, msg, chatId, isGroup, threadSpec, historyKey, historyLimit, groupHistories, route, skillFilter, sendTyping, sendRecordVoice, ackReactionPromise, reactionApi, removeAckAfterReply, statusReactionController, } = context;
61
59
  const draftMaxChars = Math.min(textLimit, 4096);
62
60
  const tableMode = resolveMarkdownTableMode({
63
61
  cfg,
@@ -78,12 +76,15 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
78
76
  });
79
77
  const forceBlockStreamingForReasoning = resolvedReasoningLevel === "on";
80
78
  const streamReasoningDraft = resolvedReasoningLevel === "stream";
81
- const canStreamAnswerDraft = streamMode !== "off" && !accountBlockStreamingEnabled && !forceBlockStreamingForReasoning;
79
+ const previewStreamingEnabled = streamMode !== "off";
80
+ const canStreamAnswerDraft = previewStreamingEnabled && !accountBlockStreamingEnabled && !forceBlockStreamingForReasoning;
82
81
  const canStreamReasoningDraft = canStreamAnswerDraft || streamReasoningDraft;
83
82
  const draftReplyToMessageId = replyToMode !== "off" && typeof msg.message_id === "number" ? msg.message_id : undefined;
84
- const draftMinInitialChars = streamMode === "partial" || streamReasoningDraft ? 1 : DRAFT_MIN_INITIAL_CHARS;
83
+ const draftMinInitialChars = DRAFT_MIN_INITIAL_CHARS;
85
84
  const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, route.agentId);
86
- const createDraftLane = (enabled) => {
85
+ const archivedAnswerPreviews = [];
86
+ const archivedReasoningPreviewIds = [];
87
+ const createDraftLane = (laneName, enabled) => {
87
88
  const stream = enabled
88
89
  ? createTelegramDraftStream({
89
90
  api: bot.api,
@@ -93,24 +94,33 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
93
94
  replyToMessageId: draftReplyToMessageId,
94
95
  minInitialChars: draftMinInitialChars,
95
96
  renderText: renderDraftPreview,
97
+ onSupersededPreview: laneName === "answer" || laneName === "reasoning"
98
+ ? (preview) => {
99
+ if (laneName === "reasoning") {
100
+ if (!archivedReasoningPreviewIds.includes(preview.messageId)) {
101
+ archivedReasoningPreviewIds.push(preview.messageId);
102
+ }
103
+ return;
104
+ }
105
+ archivedAnswerPreviews.push({
106
+ messageId: preview.messageId,
107
+ textSnapshot: preview.textSnapshot,
108
+ });
109
+ }
110
+ : undefined,
96
111
  log: logVerbose,
97
112
  warn: logVerbose,
98
113
  })
99
114
  : undefined;
100
- const chunker = stream && streamMode === "block"
101
- ? new EmbeddedBlockChunker(resolveTelegramDraftStreamingChunking(cfg, route.accountId))
102
- : undefined;
103
115
  return {
104
116
  stream,
105
117
  lastPartialText: "",
106
- draftText: "",
107
118
  hasStreamedMessage: false,
108
- chunker,
109
119
  };
110
120
  };
111
121
  const lanes = {
112
- answer: createDraftLane(canStreamAnswerDraft),
113
- reasoning: createDraftLane(canStreamReasoningDraft),
122
+ answer: createDraftLane("answer", canStreamAnswerDraft),
123
+ reasoning: createDraftLane("reasoning", canStreamReasoningDraft),
114
124
  };
115
125
  const answerLane = lanes.answer;
116
126
  const reasoningLane = lanes.reasoning;
@@ -129,9 +139,7 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
129
139
  };
130
140
  const resetDraftLaneState = (lane) => {
131
141
  lane.lastPartialText = "";
132
- lane.draftText = "";
133
142
  lane.hasStreamedMessage = false;
134
- lane.chunker?.reset();
135
143
  };
136
144
  const updateDraftFromPartial = (lane, text) => {
137
145
  const laneStream = lane.stream;
@@ -143,45 +151,16 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
143
151
  }
144
152
  // Mark that we've received streaming content (for forceNewMessage decision).
145
153
  lane.hasStreamedMessage = true;
146
- if (streamMode === "partial") {
147
- // Some providers briefly emit a shorter prefix snapshot (for example
148
- // "Sure." -> "Sure" -> "Sure."). Keep the longer preview to avoid
149
- // visible punctuation flicker.
150
- if (lane.lastPartialText &&
151
- lane.lastPartialText.startsWith(text) &&
152
- text.length < lane.lastPartialText.length) {
153
- return;
154
- }
155
- lane.lastPartialText = text;
156
- laneStream.update(text);
154
+ // Some providers briefly emit a shorter prefix snapshot (for example
155
+ // "Sure." -> "Sure" -> "Sure."). Keep the longer preview to avoid
156
+ // visible punctuation flicker.
157
+ if (lane.lastPartialText &&
158
+ lane.lastPartialText.startsWith(text) &&
159
+ text.length < lane.lastPartialText.length) {
157
160
  return;
158
161
  }
159
- let delta = text;
160
- if (text.startsWith(lane.lastPartialText)) {
161
- delta = text.slice(lane.lastPartialText.length);
162
- }
163
- else {
164
- // Streaming buffer reset (or non-monotonic stream). Start fresh.
165
- lane.chunker?.reset();
166
- lane.draftText = "";
167
- }
168
162
  lane.lastPartialText = text;
169
- if (!delta) {
170
- return;
171
- }
172
- if (!lane.chunker) {
173
- lane.draftText = text;
174
- laneStream.update(lane.draftText);
175
- return;
176
- }
177
- lane.chunker.append(delta);
178
- lane.chunker.drain({
179
- force: false,
180
- emit: (chunk) => {
181
- lane.draftText += chunk;
182
- laneStream.update(lane.draftText);
183
- },
184
- });
163
+ laneStream.update(text);
185
164
  };
186
165
  const ingestDraftLaneSegments = (text) => {
187
166
  for (const segment of splitTextIntoLaneSegments(text)) {
@@ -196,21 +175,9 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
196
175
  if (!lane.stream) {
197
176
  return;
198
177
  }
199
- if (lane.chunker?.hasBuffered()) {
200
- lane.chunker.drain({
201
- force: true,
202
- emit: (chunk) => {
203
- lane.draftText += chunk;
204
- },
205
- });
206
- lane.chunker.reset();
207
- if (lane.draftText) {
208
- lane.stream.update(lane.draftText);
209
- }
210
- }
211
178
  await lane.stream.flush();
212
179
  };
213
- const disableBlockStreaming = streamMode === "off"
180
+ const disableBlockStreaming = !previewStreamingEnabled
214
181
  ? true
215
182
  : forceBlockStreamingForReasoning
216
183
  ? false
@@ -309,21 +276,24 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
309
276
  linkPreview: telegramCfg.linkPreview,
310
277
  replyQuoteText,
311
278
  };
312
- const getLanePreviewText = (lane) => streamMode === "block" ? lane.draftText : lane.lastPartialText;
279
+ const getLanePreviewText = (lane) => lane.lastPartialText;
313
280
  const tryUpdatePreviewForLane = async (params) => {
314
- const { lane, laneName, text, previewButtons, stopBeforeEdit = false, updateLaneSnapshot = false, skipRegressive, context, } = params;
281
+ const { lane, laneName, text, previewButtons, stopBeforeEdit = false, updateLaneSnapshot = false, skipRegressive, context, previewMessageId: previewMessageIdOverride, previewTextSnapshot, } = params;
315
282
  if (!lane.stream) {
316
283
  return false;
317
284
  }
318
- const hadPreviewMessage = typeof lane.stream.messageId() === "number";
285
+ const lanePreviewMessageId = lane.stream.messageId();
286
+ const hadPreviewMessage = typeof previewMessageIdOverride === "number" || typeof lanePreviewMessageId === "number";
319
287
  if (stopBeforeEdit) {
320
288
  await lane.stream.stop();
321
289
  }
322
- const previewMessageId = lane.stream.messageId();
290
+ const previewMessageId = typeof previewMessageIdOverride === "number"
291
+ ? previewMessageIdOverride
292
+ : lane.stream.messageId();
323
293
  if (typeof previewMessageId !== "number") {
324
294
  return false;
325
295
  }
326
- const currentPreviewText = getLanePreviewText(lane);
296
+ const currentPreviewText = previewTextSnapshot ?? getLanePreviewText(lane);
327
297
  const shouldSkipRegressive = Boolean(currentPreviewText) &&
328
298
  currentPreviewText.startsWith(text) &&
329
299
  text.length < currentPreviewText.length &&
@@ -343,7 +313,6 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
343
313
  });
344
314
  if (updateLaneSnapshot) {
345
315
  lane.lastPartialText = text;
346
- lane.draftText = text;
347
316
  }
348
317
  deliveryState.delivered = true;
349
318
  return true;
@@ -370,14 +339,68 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
370
339
  }
371
340
  return result.delivered;
372
341
  };
342
+ const consumeArchivedAnswerPreviewForFinal = async (params) => {
343
+ const archivedPreview = archivedAnswerPreviews.shift();
344
+ if (!archivedPreview) {
345
+ return undefined;
346
+ }
347
+ if (params.canEditViaPreview) {
348
+ const finalized = await tryUpdatePreviewForLane({
349
+ lane: params.lane,
350
+ laneName: "answer",
351
+ text: params.text,
352
+ previewButtons: params.previewButtons,
353
+ stopBeforeEdit: false,
354
+ skipRegressive: "existingOnly",
355
+ context: "final",
356
+ previewMessageId: archivedPreview.messageId,
357
+ previewTextSnapshot: archivedPreview.textSnapshot,
358
+ });
359
+ if (finalized) {
360
+ return "preview-finalized";
361
+ }
362
+ }
363
+ try {
364
+ await bot.api.deleteMessage(chatId, archivedPreview.messageId);
365
+ }
366
+ catch (err) {
367
+ logVerbose(`telegram: archived answer preview cleanup failed (${archivedPreview.messageId}): ${String(err)}`);
368
+ }
369
+ const delivered = await sendPayload(applyTextToPayload(params.payload, params.text));
370
+ return delivered ? "sent" : "skipped";
371
+ };
373
372
  const deliverLaneText = async (params) => {
374
373
  const { laneName, text, payload, infoKind, previewButtons, allowPreviewUpdateForNonFinal = false, } = params;
375
374
  const lane = lanes[laneName];
376
375
  const hasMedia = Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0;
377
376
  const canEditViaPreview = !hasMedia && text.length > 0 && text.length <= draftMaxChars && !payload.isError;
378
377
  if (infoKind === "final") {
378
+ if (laneName === "answer") {
379
+ const archivedResult = await consumeArchivedAnswerPreviewForFinal({
380
+ lane,
381
+ text,
382
+ payload,
383
+ previewButtons,
384
+ canEditViaPreview,
385
+ });
386
+ if (archivedResult) {
387
+ return archivedResult;
388
+ }
389
+ }
379
390
  if (canEditViaPreview && !finalizedPreviewByLane[laneName]) {
380
391
  await flushDraftLane(lane);
392
+ if (laneName === "answer") {
393
+ const archivedResultAfterFlush = await consumeArchivedAnswerPreviewForFinal({
394
+ lane,
395
+ text,
396
+ payload,
397
+ previewButtons,
398
+ canEditViaPreview,
399
+ });
400
+ if (archivedResultAfterFlush) {
401
+ return archivedResultAfterFlush;
402
+ }
403
+ }
381
404
  const finalized = await tryUpdatePreviewForLane({
382
405
  lane,
383
406
  laneName,
@@ -418,6 +441,9 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
418
441
  return delivered ? "sent" : "skipped";
419
442
  };
420
443
  let queuedFinal = false;
444
+ if (statusReactionController) {
445
+ void statusReactionController.setThinking();
446
+ }
421
447
  try {
422
448
  ({ queuedFinal } = await dispatchReplyWithBufferedBlockDispatcher({
423
449
  ctx: ctxPayload,
@@ -536,10 +562,16 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
536
562
  }
537
563
  : undefined,
538
564
  onAssistantMessageStart: answerLane.stream
539
- ? () => {
565
+ ? async () => {
540
566
  reasoningStepState.resetForNextStep();
541
- // Keep answer blocks separated in block mode; partial mode keeps one answer lane.
542
- if (streamMode === "block" && answerLane.hasStreamedMessage) {
567
+ if (answerLane.hasStreamedMessage) {
568
+ const previewMessageId = answerLane.stream?.messageId();
569
+ if (typeof previewMessageId === "number") {
570
+ archivedAnswerPreviews.push({
571
+ messageId: previewMessageId,
572
+ textSnapshot: answerLane.lastPartialText,
573
+ });
574
+ }
543
575
  answerLane.stream?.forceNewMessage();
544
576
  }
545
577
  resetDraftLaneState(answerLane);
@@ -551,6 +583,11 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
551
583
  splitReasoningOnNextStream = reasoningLane.hasStreamedMessage;
552
584
  }
553
585
  : undefined,
586
+ onToolStart: statusReactionController
587
+ ? async (payload) => {
588
+ await statusReactionController.setTool(payload.name);
589
+ }
590
+ : undefined,
554
591
  onModelSelected,
555
592
  },
556
593
  }));
@@ -581,6 +618,22 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
581
618
  await stream.clear();
582
619
  }
583
620
  }
621
+ for (const archivedPreview of archivedAnswerPreviews) {
622
+ try {
623
+ await bot.api.deleteMessage(chatId, archivedPreview.messageId);
624
+ }
625
+ catch (err) {
626
+ logVerbose(`telegram: archived answer preview cleanup failed (${archivedPreview.messageId}): ${String(err)}`);
627
+ }
628
+ }
629
+ for (const messageId of archivedReasoningPreviewIds) {
630
+ try {
631
+ await bot.api.deleteMessage(chatId, messageId);
632
+ }
633
+ catch (err) {
634
+ logVerbose(`telegram: archived reasoning preview cleanup failed (${messageId}): ${String(err)}`);
635
+ }
636
+ }
584
637
  }
585
638
  let sentFallback = false;
586
639
  if (!deliveryState.delivered &&
@@ -592,26 +645,38 @@ export const dispatchTelegramMessage = async ({ context, bot, cfg, runtime, repl
592
645
  sentFallback = result.delivered;
593
646
  }
594
647
  const hasFinalResponse = queuedFinal || sentFallback;
648
+ if (statusReactionController && !hasFinalResponse) {
649
+ void statusReactionController.setError().catch((err) => {
650
+ logVerbose(`telegram: status reaction error finalize failed: ${String(err)}`);
651
+ });
652
+ }
595
653
  if (!hasFinalResponse) {
596
654
  clearGroupHistory();
597
655
  return;
598
656
  }
599
- removeAckReactionAfterReply({
600
- removeAfterReply: removeAckAfterReply,
601
- ackReactionPromise,
602
- ackReactionValue: ackReactionPromise ? "ack" : null,
603
- remove: () => reactionApi?.(chatId, msg.message_id ?? 0, []) ?? Promise.resolve(),
604
- onError: (err) => {
605
- if (!msg.message_id) {
606
- return;
607
- }
608
- logAckFailure({
609
- log: logVerbose,
610
- channel: "telegram",
611
- target: `${chatId}/${msg.message_id}`,
612
- error: err,
613
- });
614
- },
615
- });
657
+ if (statusReactionController) {
658
+ void statusReactionController.setDone().catch((err) => {
659
+ logVerbose(`telegram: status reaction finalize failed: ${String(err)}`);
660
+ });
661
+ }
662
+ else {
663
+ removeAckReactionAfterReply({
664
+ removeAfterReply: removeAckAfterReply,
665
+ ackReactionPromise,
666
+ ackReactionValue: ackReactionPromise ? "ack" : null,
667
+ remove: () => reactionApi?.(chatId, msg.message_id ?? 0, []) ?? Promise.resolve(),
668
+ onError: (err) => {
669
+ if (!msg.message_id) {
670
+ return;
671
+ }
672
+ logAckFailure({
673
+ log: logVerbose,
674
+ channel: "telegram",
675
+ target: `${chatId}/${msg.message_id}`,
676
+ error: err,
677
+ });
678
+ },
679
+ });
680
+ }
616
681
  clearGroupHistory();
617
682
  };
@@ -6,6 +6,7 @@ import { listSkillCommandsForAgents } from "../auto-reply/skill-commands.js";
6
6
  import { resolveCommandAuthorizedFromAuthorizers } from "../channels/command-gating.js";
7
7
  import { createReplyPrefixOptions } from "../channels/reply-prefix.js";
8
8
  import { resolveMarkdownTableMode } from "../config/markdown-tables.js";
9
+ import { recordSessionMetaFromInbound, resolveStorePath } from "../config/sessions.js";
9
10
  import { normalizeTelegramCommandName, resolveTelegramCustomCommands, TELEGRAM_COMMAND_NAME_PATTERN, } from "../config/telegram-custom-commands.js";
10
11
  import { danger, logVerbose } from "../globals.js";
11
12
  import { getAgentScopedMediaLocalRoots } from "../media/local-roots.js";
@@ -29,6 +30,7 @@ async function resolveTelegramCommandAuth(params) {
29
30
  const groupAllowContext = await resolveTelegramGroupAllowFromContext({
30
31
  chatId,
31
32
  accountId,
33
+ dmPolicy: telegramCfg.dmPolicy ?? "pairing",
32
34
  isForum,
33
35
  messageThreadId,
34
36
  groupAllowFrom,
@@ -100,6 +102,7 @@ async function resolveTelegramCommandAuth(params) {
100
102
  const dmAllow = normalizeAllowFromWithStore({
101
103
  allowFrom: allowFrom,
102
104
  storeAllowFrom,
105
+ dmPolicy: telegramCfg.dmPolicy ?? "pairing",
103
106
  });
104
107
  const senderAllowed = isSenderAllowed({
105
108
  allow: dmAllow,
@@ -377,6 +380,19 @@ export const registerTelegramNativeCommands = ({ bot, cfg, runtime, accountId, t
377
380
  OriginatingChannel: "telegram",
378
381
  OriginatingTo: `telegram:${chatId}`,
379
382
  });
383
+ const storePath = resolveStorePath(cfg.session?.store, {
384
+ agentId: route.agentId,
385
+ });
386
+ try {
387
+ await recordSessionMetaFromInbound({
388
+ storePath,
389
+ sessionKey: ctxPayload.SessionKey ?? route.sessionKey,
390
+ ctx: ctxPayload,
391
+ });
392
+ }
393
+ catch (err) {
394
+ runtime.error?.(danger(`telegram slash: failed updating session meta: ${String(err)}`));
395
+ }
380
396
  const disableBlockStreaming = typeof telegramCfg.blockStreaming === "boolean"
381
397
  ? !telegramCfg.blockStreaming
382
398
  : undefined;
@@ -16,6 +16,7 @@ export function createTelegramDraftStream(params) {
16
16
  let lastSentParseMode;
17
17
  let stopped = false;
18
18
  let isFinal = false;
19
+ let generation = 0;
19
20
  const sendOrEditStreamMessage = async (text) => {
20
21
  // Allow final flush even if stopped (e.g., after clear()).
21
22
  if (stopped && !isFinal) {
@@ -41,6 +42,7 @@ export function createTelegramDraftStream(params) {
41
42
  if (renderedText === lastSentText && renderedParseMode === lastSentParseMode) {
42
43
  return true;
43
44
  }
45
+ const sendGeneration = generation;
44
46
  // Debounce first preview send for better push notification quality.
45
47
  if (typeof streamMessageId !== "number" && minInitialChars != null && !isFinal) {
46
48
  if (renderedText.length < minInitialChars) {
@@ -74,7 +76,16 @@ export function createTelegramDraftStream(params) {
74
76
  params.warn?.("telegram stream preview stopped (missing message id from sendMessage)");
75
77
  return false;
76
78
  }
77
- streamMessageId = Math.trunc(sentMessageId);
79
+ const normalizedMessageId = Math.trunc(sentMessageId);
80
+ if (sendGeneration !== generation) {
81
+ params.onSupersededPreview?.({
82
+ messageId: normalizedMessageId,
83
+ textSnapshot: renderedText,
84
+ parseMode: renderedParseMode,
85
+ });
86
+ return true;
87
+ }
88
+ streamMessageId = normalizedMessageId;
78
89
  return true;
79
90
  }
80
91
  catch (err) {
@@ -116,10 +127,12 @@ export function createTelegramDraftStream(params) {
116
127
  }
117
128
  };
118
129
  const forceNewMessage = () => {
130
+ generation += 1;
119
131
  streamMessageId = undefined;
120
132
  lastSentText = "";
121
133
  lastSentParseMode = undefined;
122
134
  loop.resetPending();
135
+ loop.resetThrottleWindow();
123
136
  };
124
137
  params.log?.(`telegram stream preview ready (maxChars=${maxChars}, throttleMs=${throttleMs})`);
125
138
  return {
@@ -1,9 +1,9 @@
1
1
  import { listTelegramAccountIds, resolveTelegramAccount } from "./accounts.js";
2
- import { parseTelegramTarget } from "./targets.js";
3
2
  const DEFAULT_INLINE_BUTTONS_SCOPE = "allowlist";
4
3
  function normalizeInlineButtonsScope(value) {
5
- if (typeof value !== "string")
4
+ if (typeof value !== "string") {
6
5
  return undefined;
6
+ }
7
7
  const trimmed = value.trim().toLowerCase();
8
8
  if (trimmed === "off" ||
9
9
  trimmed === "dm" ||
@@ -15,8 +15,9 @@ function normalizeInlineButtonsScope(value) {
15
15
  return undefined;
16
16
  }
17
17
  function resolveInlineButtonsScopeFromCapabilities(capabilities) {
18
- if (!capabilities)
18
+ if (!capabilities) {
19
19
  return DEFAULT_INLINE_BUTTONS_SCOPE;
20
+ }
20
21
  if (Array.isArray(capabilities)) {
21
22
  const enabled = capabilities.some((entry) => String(entry).trim().toLowerCase() === "inlinebuttons");
22
23
  return enabled ? "all" : "off";
@@ -41,15 +42,4 @@ export function isTelegramInlineButtonsEnabled(params) {
41
42
  }
42
43
  return accountIds.some((accountId) => resolveTelegramInlineButtonsScope({ cfg: params.cfg, accountId }) !== "off");
43
44
  }
44
- export function resolveTelegramTargetChatType(target) {
45
- if (!target.trim())
46
- return "unknown";
47
- const parsed = parseTelegramTarget(target);
48
- const chatId = parsed.chatId.trim();
49
- if (!chatId)
50
- return "unknown";
51
- if (/^-?\d+$/.test(chatId)) {
52
- return chatId.startsWith("-") ? "group" : "direct";
53
- }
54
- return "unknown";
55
- }
45
+ export { resolveTelegramTargetChatType } from "./targets.js";
@@ -39,12 +39,14 @@ const TELEGRAM_POLL_RESTART_POLICY = {
39
39
  jitter: 0.25,
40
40
  };
41
41
  const isGetUpdatesConflict = (err) => {
42
- if (!err || typeof err !== "object")
42
+ if (!err || typeof err !== "object") {
43
43
  return false;
44
+ }
44
45
  const typed = err;
45
46
  const errorCode = typed.error_code ?? typed.errorCode;
46
- if (errorCode !== 409)
47
+ if (errorCode !== 409) {
47
48
  return false;
49
+ }
48
50
  const haystack = [typed.method, typed.description, typed.message]
49
51
  .filter((value) => typeof value === "string")
50
52
  .join(" ")
@@ -81,14 +83,14 @@ export async function monitorTelegramProvider(opts = {}) {
81
83
  if (!token) {
82
84
  throw new Error(`Telegram bot token missing for account "${account.accountId}" (set channels.telegram.accounts.${account.accountId}.botToken/tokenFile or TELEGRAM_BOT_TOKEN for default).`);
83
85
  }
84
- const proxyFetch = opts.proxyFetch ??
85
- (account.config.proxy ? makeProxyFetch(account.config.proxy) : undefined);
86
+ const proxyFetch = opts.proxyFetch ?? (account.config.proxy ? makeProxyFetch(account.config.proxy) : undefined);
86
87
  let lastUpdateId = await readTelegramUpdateOffset({
87
88
  accountId: account.accountId,
88
89
  });
89
90
  const persistUpdateId = async (updateId) => {
90
- if (lastUpdateId !== null && updateId <= lastUpdateId)
91
+ if (lastUpdateId !== null && updateId <= lastUpdateId) {
91
92
  return;
93
+ }
92
94
  lastUpdateId = updateId;
93
95
  try {
94
96
  await writeTelegramUpdateOffset({
@@ -118,7 +120,8 @@ export async function monitorTelegramProvider(opts = {}) {
118
120
  config: cfg,
119
121
  path: opts.webhookPath,
120
122
  port: opts.webhookPort,
121
- secret: opts.webhookSecret,
123
+ secret: opts.webhookSecret ?? account.config.webhookSecret,
124
+ host: opts.webhookHost ?? account.config.webhookHost,
122
125
  runtime: opts.runtime,
123
126
  fetch: proxyFetch,
124
127
  abortSignal: opts.abortSignal,
@@ -159,8 +162,9 @@ export async function monitorTelegramProvider(opts = {}) {
159
162
  await sleepWithAbort(delayMs, opts.abortSignal);
160
163
  }
161
164
  catch (sleepErr) {
162
- if (opts.abortSignal?.aborted)
165
+ if (opts.abortSignal?.aborted) {
163
166
  return;
167
+ }
164
168
  throw sleepErr;
165
169
  }
166
170
  }
@@ -1,27 +1,39 @@
1
1
  import process from "node:process";
2
2
  import { isTruthyEnvValue } from "../infra/env.js";
3
+ import { isWSL2Sync } from "../infra/wsl.js";
3
4
  export const TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV = "POOLBOT_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY";
4
5
  export const TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV = "POOLBOT_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY";
5
- const TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV_LEGACY = "CLAWDBOT_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY";
6
- const TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV_LEGACY = "CLAWDBOT_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY";
6
+ let wsl2SyncCache;
7
+ function isWSL2SyncCached() {
8
+ if (typeof wsl2SyncCache === "boolean") {
9
+ return wsl2SyncCache;
10
+ }
11
+ wsl2SyncCache = isWSL2Sync();
12
+ return wsl2SyncCache;
13
+ }
7
14
  export function resolveTelegramAutoSelectFamilyDecision(params) {
8
15
  const env = params?.env ?? process.env;
9
16
  const nodeMajor = typeof params?.nodeMajor === "number"
10
17
  ? params.nodeMajor
11
18
  : Number(process.versions.node.split(".")[0]);
12
- if (isTruthyEnvValue(env[TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV]) ||
13
- isTruthyEnvValue(env[TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV_LEGACY])) {
19
+ if (isTruthyEnvValue(env[TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV])) {
14
20
  return { value: true, source: `env:${TELEGRAM_ENABLE_AUTO_SELECT_FAMILY_ENV}` };
15
21
  }
16
- if (isTruthyEnvValue(env[TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV]) ||
17
- isTruthyEnvValue(env[TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV_LEGACY])) {
22
+ if (isTruthyEnvValue(env[TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV])) {
18
23
  return { value: false, source: `env:${TELEGRAM_DISABLE_AUTO_SELECT_FAMILY_ENV}` };
19
24
  }
20
25
  if (typeof params?.network?.autoSelectFamily === "boolean") {
21
26
  return { value: params.network.autoSelectFamily, source: "config" };
22
27
  }
28
+ // WSL2 has unstable IPv6 connectivity; disable autoSelectFamily to use IPv4 directly
29
+ if (isWSL2SyncCached()) {
30
+ return { value: false, source: "default-wsl2" };
31
+ }
23
32
  if (Number.isFinite(nodeMajor) && nodeMajor >= 22) {
24
- return { value: false, source: "default-node22" };
33
+ return { value: true, source: "default-node22" };
25
34
  }
26
35
  return { value: null };
27
36
  }
37
+ export function resetTelegramNetworkConfigStateForTests() {
38
+ wsl2SyncCache = undefined;
39
+ }
@@ -27,6 +27,7 @@ const PARSE_ERR_RE = /can't parse entities|parse entities|find end of the entity
27
27
  const THREAD_NOT_FOUND_RE = /400:\s*Bad Request:\s*message thread not found/i;
28
28
  const MESSAGE_NOT_MODIFIED_RE = /400:\s*Bad Request:\s*message is not modified|MESSAGE_NOT_MODIFIED/i;
29
29
  const CHAT_NOT_FOUND_RE = /400: Bad Request: chat not found/i;
30
+ const sendLogger = createSubsystemLogger("telegram/send");
30
31
  const diagLogger = createSubsystemLogger("telegram/diagnostic");
31
32
  function createTelegramHttpLogger(cfg) {
32
33
  const enabled = isDiagnosticFlagEnabled("telegram.http", cfg);
@@ -176,7 +177,7 @@ async function withTelegramHtmlParseFallback(params) {
176
177
  throw err;
177
178
  }
178
179
  if (params.verbose) {
179
- console.warn(`telegram ${params.label} failed with HTML parse error, retrying as plain text: ${formatErrorMessage(err)}`);
180
+ sendLogger.warn(`telegram ${params.label} failed with HTML parse error, retrying as plain text: ${formatErrorMessage(err)}`);
180
181
  }
181
182
  return await params.requestPlain(`${params.label}-plain`);
182
183
  }
@@ -236,7 +237,7 @@ async function withTelegramThreadFallback(params, label, verbose, attempt) {
236
237
  throw err;
237
238
  }
238
239
  if (verbose) {
239
- console.warn(`telegram ${label} failed with message_thread_id, retrying without thread: ${formatErrorMessage(err)}`);
240
+ sendLogger.warn(`telegram ${label} failed with message_thread_id, retrying without thread: ${formatErrorMessage(err)}`);
240
241
  }
241
242
  const retriedParams = removeMessageThreadIdParam(params);
242
243
  return await attempt(retriedParams, `${label}-threadless`);