@poolzin/pool-bot 2026.2.20 → 2026.2.22

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 (388) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/agents/api-key-rotation.js +47 -0
  3. package/dist/agents/apply-patch-update.js +19 -9
  4. package/dist/agents/apply-patch.js +72 -47
  5. package/dist/agents/bash-tools.exec.js +141 -559
  6. package/dist/agents/cli-backends.js +49 -6
  7. package/dist/agents/cli-runner/helpers.js +69 -152
  8. package/dist/agents/cli-runner.js +70 -19
  9. package/dist/agents/identity.js +20 -1
  10. package/dist/agents/image-sanitization.js +9 -0
  11. package/dist/agents/live-auth-keys.js +123 -26
  12. package/dist/agents/live-model-filter.js +13 -4
  13. package/dist/agents/model-auth.js +12 -0
  14. package/dist/agents/model-catalog.js +40 -9
  15. package/dist/agents/model-fallback.js +24 -0
  16. package/dist/agents/model-forward-compat.js +60 -23
  17. package/dist/agents/model-selection.js +134 -41
  18. package/dist/agents/pi-auth-json.js +2 -2
  19. package/dist/agents/pi-embedded-helpers/bootstrap.js +65 -15
  20. package/dist/agents/pi-embedded-helpers/errors.js +140 -15
  21. package/dist/agents/pi-embedded-helpers/images.js +22 -12
  22. package/dist/agents/pi-embedded-helpers.js +2 -2
  23. package/dist/agents/pi-embedded-runner/abort.js +10 -3
  24. package/dist/agents/pi-embedded-runner/compact.js +230 -32
  25. package/dist/agents/pi-embedded-runner/extra-params.js +203 -12
  26. package/dist/agents/pi-embedded-runner/google.js +109 -19
  27. package/dist/agents/pi-embedded-runner/history.js +35 -17
  28. package/dist/agents/pi-embedded-runner/run/attempt.js +386 -80
  29. package/dist/agents/pi-embedded-runner/run/images.js +81 -55
  30. package/dist/agents/pi-embedded-runner/run/payloads.js +89 -39
  31. package/dist/agents/pi-embedded-runner/run.js +193 -25
  32. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +2 -2
  33. package/dist/agents/pi-embedded-runner/runs.js +17 -8
  34. package/dist/agents/pi-embedded-runner/tool-result-context-guard.js +262 -0
  35. package/dist/agents/pi-embedded-runner.js +1 -1
  36. package/dist/agents/pi-embedded-subscribe.handlers.tools.js +180 -10
  37. package/dist/agents/pi-embedded-subscribe.js +37 -0
  38. package/dist/agents/pi-embedded-subscribe.tools.js +127 -30
  39. package/dist/agents/pi-model-discovery.js +9 -2
  40. package/dist/agents/pi-tool-definition-adapter.js +60 -8
  41. package/dist/agents/pi-tools.before-tool-call.js +1 -1
  42. package/dist/agents/pi-tools.js +113 -94
  43. package/dist/agents/pi-tools.read.js +337 -38
  44. package/dist/agents/poolbot-tools.js +14 -5
  45. package/dist/agents/provider/config-loader.js +76 -0
  46. package/dist/agents/provider/index.js +15 -0
  47. package/dist/agents/provider/integration.js +136 -0
  48. package/dist/agents/provider/models-dev.js +129 -0
  49. package/dist/agents/provider/rate-limits.js +458 -0
  50. package/dist/agents/provider/request-monitor.js +449 -0
  51. package/dist/agents/provider/session-binding.js +376 -0
  52. package/dist/agents/provider/token-pool.js +541 -0
  53. package/dist/agents/sandbox/docker.js +10 -5
  54. package/dist/agents/sandbox/registry.js +96 -46
  55. package/dist/agents/sandbox/sanitize-env-vars.js +82 -0
  56. package/dist/agents/sandbox-paths.js +43 -10
  57. package/dist/agents/session-tool-result-guard-wrapper.js +23 -11
  58. package/dist/agents/session-tool-result-guard.js +39 -39
  59. package/dist/agents/session-transcript-repair.js +36 -33
  60. package/dist/agents/session-write-lock.js +62 -44
  61. package/dist/agents/skills/frontmatter.js +49 -88
  62. package/dist/agents/skills/workspace.js +335 -28
  63. package/dist/agents/subagent-announce.js +508 -174
  64. package/dist/agents/subagent-registry.js +45 -4
  65. package/dist/agents/subagent-spawn.js +16 -33
  66. package/dist/agents/system-prompt-report.js +27 -10
  67. package/dist/agents/system-prompt.js +26 -32
  68. package/dist/agents/tool-call-id.js +69 -17
  69. package/dist/agents/tool-display-common.js +1 -1
  70. package/dist/agents/tool-images.js +64 -31
  71. package/dist/agents/tools/canvas-tool.js +17 -11
  72. package/dist/agents/tools/common.js +37 -19
  73. package/dist/agents/tools/cron-tool.js +40 -38
  74. package/dist/agents/tools/gateway.js +70 -2
  75. package/dist/agents/tools/message-tool.js +181 -40
  76. package/dist/agents/tools/nodes-tool.js +128 -36
  77. package/dist/agents/tools/nodes-utils.js +12 -38
  78. package/dist/agents/tools/session-status-tool.js +24 -71
  79. package/dist/agents/tools/sessions-helpers.js +38 -210
  80. package/dist/agents/tools/sessions-spawn-tool.js +28 -198
  81. package/dist/agents/tools/telegram-actions.js +58 -7
  82. package/dist/agents/tools/web-fetch-utils.js +112 -7
  83. package/dist/agents/tools/web-fetch.js +279 -175
  84. package/dist/agents/tools/web-shared.js +71 -8
  85. package/dist/agents/usage.js +25 -16
  86. package/dist/auto-reply/commands-registry.data.js +85 -11
  87. package/dist/auto-reply/dispatch.js +40 -21
  88. package/dist/auto-reply/reply/abort.js +102 -33
  89. package/dist/auto-reply/reply/commands-core.js +82 -33
  90. package/dist/auto-reply/reply/commands-export-session.js +1 -1
  91. package/dist/auto-reply/reply/commands-info.js +41 -12
  92. package/dist/auto-reply/reply/commands-subagents.js +352 -100
  93. package/dist/auto-reply/reply/commands-system-prompt.js +2 -2
  94. package/dist/auto-reply/reply/dispatch-from-config.js +100 -29
  95. package/dist/auto-reply/reply/elevated-unavailable.js +1 -1
  96. package/dist/auto-reply/reply/inbound-meta.js +12 -1
  97. package/dist/auto-reply/reply/mentions.js +18 -11
  98. package/dist/auto-reply/reply/normalize-reply.js +17 -8
  99. package/dist/auto-reply/reply/reply-dispatcher.js +62 -10
  100. package/dist/auto-reply/reply/session.js +102 -21
  101. package/dist/auto-reply/reply/streaming-directives.js +16 -5
  102. package/dist/auto-reply/status.js +73 -50
  103. package/dist/browser/extension-relay.js +3 -3
  104. package/dist/browser/http-auth.js +1 -1
  105. package/dist/browser/paths.js +2 -2
  106. package/dist/build-info.json +3 -3
  107. package/dist/channels/allowlist-match.js +20 -0
  108. package/dist/channels/allowlists/resolve-utils.js +65 -2
  109. package/dist/channels/chat-type.js +8 -4
  110. package/dist/channels/dock.js +127 -35
  111. package/dist/channels/draft-stream-loop.js +6 -2
  112. package/dist/channels/plugins/actions/telegram.js +42 -18
  113. package/dist/channels/plugins/allowlist-match.js +1 -1
  114. package/dist/channels/plugins/group-mentions.js +51 -41
  115. package/dist/channels/plugins/message-action-names.js +2 -0
  116. package/dist/channels/plugins/message-actions.js +24 -5
  117. package/dist/channels/plugins/normalize/discord.js +26 -4
  118. package/dist/channels/plugins/normalize/signal.js +35 -22
  119. package/dist/channels/plugins/onboarding/helpers.js +8 -26
  120. package/dist/channels/plugins/outbound/imessage.js +15 -14
  121. package/dist/channels/registry.js +20 -7
  122. package/dist/cli/acp-cli.js +7 -5
  123. package/dist/cli/browser-cli-extension.js +25 -12
  124. package/dist/cli/browser-cli-state.cookies-storage.js +25 -6
  125. package/dist/cli/browser-cli-state.js +101 -145
  126. package/dist/cli/command-options.js +28 -0
  127. package/dist/cli/completion-cli.js +6 -6
  128. package/dist/cli/cron-cli/register.cron-add.js +25 -1
  129. package/dist/cli/cron-cli/register.cron-edit.js +44 -0
  130. package/dist/cli/cron-cli/shared.js +7 -1
  131. package/dist/cli/daemon-cli/lifecycle-core.js +23 -21
  132. package/dist/cli/daemon-cli/lifecycle.js +23 -247
  133. package/dist/cli/daemon-cli/register-service-commands.js +25 -4
  134. package/dist/cli/daemon-cli.js +1 -0
  135. package/dist/cli/devices-cli.js +33 -20
  136. package/dist/cli/gateway-cli/register.js +37 -105
  137. package/dist/cli/gateway-cli/run.js +49 -11
  138. package/dist/cli/nodes-camera.js +59 -4
  139. package/dist/cli/nodes-cli/register.camera.js +27 -24
  140. package/dist/cli/nodes-cli/rpc.js +21 -38
  141. package/dist/cli/qr-cli.js +2 -2
  142. package/dist/cli/skills-cli.format.js +2 -2
  143. package/dist/cli/update-cli/progress.js +2 -2
  144. package/dist/cli/update-cli/restart-helper.js +28 -7
  145. package/dist/cli/update-cli/shared.js +7 -7
  146. package/dist/cli/update-cli/status.js +1 -1
  147. package/dist/cli/update-cli/update-command.js +14 -8
  148. package/dist/cli/update-cli/wizard.js +2 -2
  149. package/dist/cli/update-cli.js +21 -1027
  150. package/dist/commands/auth-choice.apply.anthropic.js +10 -2
  151. package/dist/commands/channels/add-mutators.js +3 -35
  152. package/dist/commands/channels/add.js +39 -51
  153. package/dist/commands/config-validation.js +1 -1
  154. package/dist/commands/configure.gateway-auth.js +52 -15
  155. package/dist/commands/configure.gateway.js +84 -40
  156. package/dist/commands/doctor-completion.js +3 -3
  157. package/dist/commands/doctor-config-flow.js +536 -16
  158. package/dist/commands/doctor-gateway-services.js +103 -79
  159. package/dist/commands/doctor-memory-search.js +9 -9
  160. package/dist/commands/doctor-platform-notes.js +57 -30
  161. package/dist/commands/doctor-prompter.js +26 -15
  162. package/dist/commands/doctor-session-locks.js +1 -1
  163. package/dist/commands/doctor.js +21 -9
  164. package/dist/commands/model-picker.js +120 -95
  165. package/dist/commands/models/set.js +2 -21
  166. package/dist/commands/models/shared.js +65 -37
  167. package/dist/commands/onboard-helpers.js +81 -39
  168. package/dist/commands/openai-codex-oauth.js +1 -1
  169. package/dist/commands/sessions.js +52 -53
  170. package/dist/commands/status.summary.js +52 -34
  171. package/dist/commands/test-wizard-helpers.js +2 -2
  172. package/dist/config/defaults.js +79 -42
  173. package/dist/config/group-policy.js +50 -18
  174. package/dist/config/includes.js +37 -10
  175. package/dist/config/schema.help.js +5 -4
  176. package/dist/config/schema.hints.js +2 -2
  177. package/dist/config/schema.labels.js +1 -0
  178. package/dist/config/sessions/group.js +12 -11
  179. package/dist/config/sessions/paths.js +137 -11
  180. package/dist/config/sessions/store.js +185 -65
  181. package/dist/config/sessions/types.js +15 -1
  182. package/dist/config/sessions.js +1 -0
  183. package/dist/config/telegram-custom-commands.js +3 -2
  184. package/dist/config/types.js +2 -0
  185. package/dist/config/zod-schema.agent-defaults.js +6 -27
  186. package/dist/config/zod-schema.agent-runtime.js +171 -79
  187. package/dist/config/zod-schema.providers-core.js +138 -65
  188. package/dist/config/zod-schema.session.js +49 -22
  189. package/dist/control-ui/assets/index-HRr1grwl.js.map +1 -1
  190. package/dist/cron/isolated-agent/run.js +224 -57
  191. package/dist/cron/normalize.js +48 -45
  192. package/dist/cron/run-log.js +14 -0
  193. package/dist/cron/service/jobs.js +190 -28
  194. package/dist/cron/service/normalize.js +29 -11
  195. package/dist/cron/service/store.js +30 -44
  196. package/dist/cron/service/timer.js +182 -96
  197. package/dist/cron/service.js +3 -0
  198. package/dist/cron/stagger.js +37 -0
  199. package/dist/daemon/inspect.js +132 -92
  200. package/dist/daemon/runtime-paths.js +25 -4
  201. package/dist/daemon/service-audit.js +47 -16
  202. package/dist/discord/accounts.js +23 -20
  203. package/dist/discord/monitor/agent-components.js +1115 -219
  204. package/dist/discord/monitor/allow-list.js +114 -34
  205. package/dist/discord/monitor/listeners.js +204 -97
  206. package/dist/discord/monitor/message-handler.js +21 -10
  207. package/dist/discord/monitor/message-handler.preflight.js +195 -101
  208. package/dist/discord/monitor/message-handler.process.js +384 -123
  209. package/dist/discord/monitor/message-utils.js +86 -23
  210. package/dist/discord/monitor/native-command.js +77 -57
  211. package/dist/discord/monitor/provider.js +122 -117
  212. package/dist/discord/monitor/reply-context.js +20 -16
  213. package/dist/discord/monitor/reply-delivery.js +40 -8
  214. package/dist/discord/monitor/rest-fetch.js +22 -0
  215. package/dist/discord/monitor/threading.js +117 -24
  216. package/dist/discord/send.js +2 -1
  217. package/dist/discord/send.outbound.js +124 -11
  218. package/dist/discord/send.shared.js +112 -72
  219. package/dist/discord/voice-message.js +3 -3
  220. package/dist/gateway/auth.js +119 -44
  221. package/dist/gateway/call.js +76 -34
  222. package/dist/gateway/channel-health-monitor.js +57 -50
  223. package/dist/gateway/client.js +63 -29
  224. package/dist/gateway/control-ui-contract.js +1 -1
  225. package/dist/gateway/gateway-config-prompts.shared.js +2 -2
  226. package/dist/gateway/net.js +109 -1
  227. package/dist/gateway/protocol/index.js +5 -8
  228. package/dist/gateway/protocol/schema/agent.js +19 -1
  229. package/dist/gateway/protocol/schema/channels.js +21 -0
  230. package/dist/gateway/protocol/schema/cron.js +43 -30
  231. package/dist/gateway/protocol/schema/protocol-schemas.js +6 -11
  232. package/dist/gateway/protocol/schema/sessions.js +5 -1
  233. package/dist/gateway/protocol/schema.js +0 -1
  234. package/dist/gateway/server/presence-events.js +12 -0
  235. package/dist/gateway/server/ws-connection/message-handler.js +203 -212
  236. package/dist/gateway/server/ws-connection.js +58 -21
  237. package/dist/gateway/server-broadcast.js +18 -13
  238. package/dist/gateway/server-cron.js +177 -10
  239. package/dist/gateway/server-methods/agent-job.js +131 -38
  240. package/dist/gateway/server-methods/send.js +60 -14
  241. package/dist/gateway/server-methods/sessions.js +160 -96
  242. package/dist/gateway/server-methods/system.js +5 -7
  243. package/dist/gateway/server-methods-list.js +8 -0
  244. package/dist/gateway/server-methods.js +24 -8
  245. package/dist/gateway/server-node-events.js +278 -68
  246. package/dist/gateway/session-utils.fs.js +316 -75
  247. package/dist/gateway/session-utils.js +224 -70
  248. package/dist/gateway/sessions-patch.js +63 -20
  249. package/dist/gateway/test-temp-config.js +1 -1
  250. package/dist/gateway/tools-invoke-http.js +118 -70
  251. package/dist/gateway/ws-log.js +135 -107
  252. package/dist/hooks/frontmatter.js +36 -82
  253. package/dist/hooks/install.js +149 -139
  254. package/dist/hooks/internal-hooks.js +29 -4
  255. package/dist/hooks/plugin-hooks.js +2 -1
  256. package/dist/imessage/monitor/deliver.js +10 -4
  257. package/dist/imessage/monitor/monitor-provider.js +138 -375
  258. package/dist/imessage/monitor/runtime.js +4 -8
  259. package/dist/imessage/send.js +65 -19
  260. package/dist/infra/exec-approvals-allowlist.js +7 -0
  261. package/dist/infra/exec-approvals.js +35 -920
  262. package/dist/infra/exec-safe-bin-trust.js +64 -0
  263. package/dist/infra/heartbeat-runner.js +207 -134
  264. package/dist/infra/heartbeat-wake.js +183 -22
  265. package/dist/infra/install-source-utils.js +47 -0
  266. package/dist/infra/net/ssrf.js +170 -36
  267. package/dist/infra/outbound/deliver.js +224 -58
  268. package/dist/infra/outbound/message-action-spec.js +12 -5
  269. package/dist/infra/outbound/outbound-session.js +27 -25
  270. package/dist/infra/poolbot-root.js +32 -22
  271. package/dist/infra/ports.js +14 -11
  272. package/dist/infra/skills-remote.js +48 -37
  273. package/dist/infra/system-events.js +25 -11
  274. package/dist/infra/system-presence.js +26 -33
  275. package/dist/infra/tmp-poolbot-dir.js +81 -2
  276. package/dist/infra/wsl.js +37 -1
  277. package/dist/line/bot-message-context.js +163 -191
  278. package/dist/logging/subsystem.js +59 -22
  279. package/dist/markdown/ir.js +124 -50
  280. package/dist/media/store.js +1 -1
  281. package/dist/media-understanding/runner.entries.js +42 -25
  282. package/dist/media-understanding/runner.js +53 -488
  283. package/dist/memory/embeddings-gemini.js +53 -38
  284. package/dist/memory/manager-embedding-ops.js +48 -69
  285. package/dist/pairing/pairing-store.js +178 -119
  286. package/dist/plugin-sdk/index.js +34 -6
  287. package/dist/plugins/hooks.js +135 -14
  288. package/dist/plugins/install.js +190 -152
  289. package/dist/polls.js +11 -0
  290. package/dist/routing/resolve-route.js +190 -56
  291. package/dist/routing/session-key.js +38 -22
  292. package/dist/runtime.js +35 -9
  293. package/dist/security/audit-channel.js +1 -1
  294. package/dist/sessions/session-key-utils.js +29 -11
  295. package/dist/shared/frontmatter.js +5 -5
  296. package/dist/shared/node-list-types.js +1 -0
  297. package/dist/shared/string-normalization.js +15 -0
  298. package/dist/signal/monitor/event-handler.js +68 -36
  299. package/dist/signal/send.js +29 -37
  300. package/dist/slack/monitor/allow-list.js +10 -11
  301. package/dist/slack/monitor/commands.js +14 -3
  302. package/dist/slack/monitor/events/interactions.js +4 -4
  303. package/dist/slack/monitor/media.js +224 -16
  304. package/dist/slack/monitor/message-handler/dispatch.js +247 -13
  305. package/dist/slack/monitor/message-handler/prepare.js +128 -45
  306. package/dist/slack/monitor/slash.js +357 -144
  307. package/dist/slack/streaming.js +77 -0
  308. package/dist/telegram/accounts.js +40 -13
  309. package/dist/telegram/allowed-updates.js +3 -0
  310. package/dist/telegram/bot/delivery.js +129 -66
  311. package/dist/telegram/bot/helpers.js +136 -122
  312. package/dist/telegram/bot-handlers.js +600 -339
  313. package/dist/telegram/bot-message-context.js +115 -73
  314. package/dist/telegram/bot-message-dispatch.js +235 -104
  315. package/dist/telegram/bot-native-command-menu.js +3 -1
  316. package/dist/telegram/bot-native-commands.js +213 -193
  317. package/dist/telegram/bot.js +24 -132
  318. package/dist/telegram/draft-stream.js +84 -75
  319. package/dist/telegram/format.js +150 -6
  320. package/dist/telegram/send.js +415 -255
  321. package/dist/telegram/targets.js +21 -2
  322. package/dist/telegram/update-offset-store.js +19 -3
  323. package/dist/terminal/restore.js +5 -2
  324. package/dist/test-utils/fetch-mock.js +5 -0
  325. package/dist/version.js +18 -5
  326. package/dist/web/auto-reply/monitor/broadcast.js +7 -3
  327. package/dist/web/auto-reply/monitor/on-message.js +6 -3
  328. package/dist/web/inbound/media.js +34 -8
  329. package/dist/web/inbound/monitor.js +34 -17
  330. package/dist/web/inbound/send-api.js +18 -17
  331. package/dist/web/outbound.js +12 -5
  332. package/dist/wizard/clack-prompter.js +40 -7
  333. package/extensions/bluebubbles/package.json +1 -1
  334. package/extensions/copilot-proxy/package.json +1 -1
  335. package/extensions/diagnostics-otel/package.json +1 -1
  336. package/extensions/discord/package.json +1 -1
  337. package/extensions/feishu/package.json +1 -1
  338. package/extensions/google-antigravity-auth/package.json +1 -1
  339. package/extensions/google-gemini-cli-auth/package.json +1 -1
  340. package/extensions/googlechat/package.json +1 -1
  341. package/extensions/imessage/package.json +1 -1
  342. package/extensions/irc/package.json +1 -1
  343. package/extensions/line/package.json +1 -1
  344. package/extensions/llm-task/package.json +1 -1
  345. package/extensions/lobster/package.json +1 -1
  346. package/extensions/matrix/CHANGELOG.md +5 -0
  347. package/extensions/matrix/package.json +1 -1
  348. package/extensions/mattermost/package.json +1 -1
  349. package/extensions/memory-core/package.json +1 -1
  350. package/extensions/memory-lancedb/package.json +1 -1
  351. package/extensions/minimax-portal-auth/package.json +1 -1
  352. package/extensions/msteams/CHANGELOG.md +5 -0
  353. package/extensions/msteams/package.json +1 -1
  354. package/extensions/nextcloud-talk/package.json +1 -1
  355. package/extensions/nostr/CHANGELOG.md +5 -0
  356. package/extensions/nostr/package.json +1 -1
  357. package/extensions/open-prose/package.json +1 -1
  358. package/extensions/openai-codex-auth/package.json +1 -1
  359. package/extensions/signal/package.json +1 -1
  360. package/extensions/slack/package.json +1 -1
  361. package/extensions/telegram/package.json +1 -1
  362. package/extensions/tlon/package.json +1 -1
  363. package/extensions/twitch/CHANGELOG.md +5 -0
  364. package/extensions/twitch/package.json +1 -1
  365. package/extensions/voice-call/CHANGELOG.md +5 -0
  366. package/extensions/voice-call/package.json +1 -1
  367. package/extensions/whatsapp/package.json +1 -1
  368. package/extensions/zalo/CHANGELOG.md +5 -0
  369. package/extensions/zalo/package.json +1 -1
  370. package/extensions/zalouser/CHANGELOG.md +5 -0
  371. package/extensions/zalouser/package.json +1 -1
  372. package/package.json +1 -1
  373. package/skills/apple-reminders/SKILL.md +100 -49
  374. package/skills/coding-agent/SKILL.md +34 -28
  375. package/skills/github/SKILL.md +131 -16
  376. package/skills/imsg/SKILL.md +112 -15
  377. package/skills/openhue/SKILL.md +101 -19
  378. package/skills/plcode-controller/SKILL.md +156 -0
  379. package/skills/plcode-controller/assets/operator-prompts.md +65 -0
  380. package/skills/plcode-controller/references/command-cheatsheet.md +53 -0
  381. package/skills/plcode-controller/references/failure-handling.md +60 -0
  382. package/skills/plcode-controller/references/model-selection.md +57 -0
  383. package/skills/plcode-controller/references/plan-vs-build.md +52 -0
  384. package/skills/plcode-controller/references/question-handling.md +40 -0
  385. package/skills/plcode-controller/references/session-management.md +63 -0
  386. package/skills/plcode-controller/references/workflow.md +35 -0
  387. package/skills/tmux/SKILL.md +111 -79
  388. package/skills/weather/SKILL.md +88 -25
@@ -3,11 +3,13 @@ export function mergeAllowlist(params) {
3
3
  const merged = [];
4
4
  const push = (value) => {
5
5
  const normalized = value.trim();
6
- if (!normalized)
6
+ if (!normalized) {
7
7
  return;
8
+ }
8
9
  const key = normalized.toLowerCase();
9
- if (seen.has(key))
10
+ if (seen.has(key)) {
10
11
  return;
12
+ }
11
13
  seen.add(key);
12
14
  merged.push(normalized);
13
15
  };
@@ -19,6 +21,67 @@ export function mergeAllowlist(params) {
19
21
  }
20
22
  return merged;
21
23
  }
24
+ export function buildAllowlistResolutionSummary(resolvedUsers, opts) {
25
+ const resolvedMap = new Map(resolvedUsers.map((entry) => [entry.input, entry]));
26
+ const resolvedOk = (entry) => Boolean(entry.resolved && entry.id);
27
+ const formatResolved = opts?.formatResolved ?? ((entry) => `${entry.input}→${entry.id}`);
28
+ const mapping = resolvedUsers.filter(resolvedOk).map(formatResolved);
29
+ const additions = resolvedUsers
30
+ .filter(resolvedOk)
31
+ .map((entry) => entry.id)
32
+ .filter((entry) => Boolean(entry));
33
+ const unresolved = resolvedUsers
34
+ .filter((entry) => !resolvedOk(entry))
35
+ .map((entry) => entry.input);
36
+ return { resolvedMap, mapping, unresolved, additions };
37
+ }
38
+ export function resolveAllowlistIdAdditions(params) {
39
+ const additions = [];
40
+ for (const entry of params.existing) {
41
+ const trimmed = String(entry).trim();
42
+ const resolved = params.resolvedMap.get(trimmed);
43
+ if (resolved?.resolved && resolved.id) {
44
+ additions.push(resolved.id);
45
+ }
46
+ }
47
+ return additions;
48
+ }
49
+ export function patchAllowlistUsersInConfigEntries(params) {
50
+ const nextEntries = { ...params.entries };
51
+ for (const [entryKey, entryConfig] of Object.entries(params.entries)) {
52
+ if (!entryConfig || typeof entryConfig !== "object") {
53
+ continue;
54
+ }
55
+ const users = entryConfig.users;
56
+ if (!Array.isArray(users) || users.length === 0) {
57
+ continue;
58
+ }
59
+ const additions = resolveAllowlistIdAdditions({
60
+ existing: users,
61
+ resolvedMap: params.resolvedMap,
62
+ });
63
+ nextEntries[entryKey] = {
64
+ ...entryConfig,
65
+ users: mergeAllowlist({ existing: users, additions }),
66
+ };
67
+ }
68
+ return nextEntries;
69
+ }
70
+ export function addAllowlistUserEntriesFromConfigEntry(target, entry) {
71
+ if (!entry || typeof entry !== "object") {
72
+ return;
73
+ }
74
+ const users = entry.users;
75
+ if (!Array.isArray(users)) {
76
+ return;
77
+ }
78
+ for (const value of users) {
79
+ const trimmed = String(value).trim();
80
+ if (trimmed && trimmed !== "*") {
81
+ target.add(trimmed);
82
+ }
83
+ }
84
+ }
22
85
  export function summarizeMapping(label, mapping, unresolved, runtime) {
23
86
  const lines = [];
24
87
  if (mapping.length > 0) {
@@ -1,12 +1,16 @@
1
1
  export function normalizeChatType(raw) {
2
2
  const value = raw?.trim().toLowerCase();
3
- if (!value)
3
+ if (!value) {
4
4
  return undefined;
5
- if (value === "direct" || value === "dm")
5
+ }
6
+ if (value === "direct" || value === "dm") {
6
7
  return "direct";
7
- if (value === "group")
8
+ }
9
+ if (value === "group") {
8
10
  return "group";
9
- if (value === "channel")
11
+ }
12
+ if (value === "channel") {
10
13
  return "channel";
14
+ }
11
15
  return undefined;
12
16
  }
@@ -1,21 +1,55 @@
1
+ import { resolveChannelGroupRequireMention, resolveChannelGroupToolsPolicy, } from "../config/group-policy.js";
1
2
  import { resolveDiscordAccount } from "../discord/accounts.js";
2
3
  import { resolveIMessageAccount } from "../imessage/accounts.js";
4
+ import { requireActivePluginRegistry } from "../plugins/runtime.js";
5
+ import { normalizeAccountId } from "../routing/session-key.js";
3
6
  import { resolveSignalAccount } from "../signal/accounts.js";
4
7
  import { resolveSlackAccount, resolveSlackReplyToMode } from "../slack/accounts.js";
5
8
  import { buildSlackThreadingToolContext } from "../slack/threading-tool-context.js";
6
9
  import { resolveTelegramAccount } from "../telegram/accounts.js";
7
- import { normalizeAccountId } from "../routing/session-key.js";
8
- import { normalizeE164 } from "../utils.js";
10
+ import { escapeRegExp, normalizeE164 } from "../utils.js";
9
11
  import { resolveWhatsAppAccount } from "../web/accounts.js";
10
12
  import { normalizeWhatsAppTarget } from "../whatsapp/normalize.js";
11
- import { requireActivePluginRegistry } from "../plugins/runtime.js";
12
13
  import { resolveDiscordGroupRequireMention, resolveDiscordGroupToolPolicy, resolveGoogleChatGroupRequireMention, resolveGoogleChatGroupToolPolicy, resolveIMessageGroupRequireMention, resolveIMessageGroupToolPolicy, resolveSlackGroupRequireMention, resolveSlackGroupToolPolicy, resolveTelegramGroupRequireMention, resolveTelegramGroupToolPolicy, resolveWhatsAppGroupRequireMention, resolveWhatsAppGroupToolPolicy, } from "./plugins/group-mentions.js";
14
+ import { normalizeSignalMessagingTarget } from "./plugins/normalize/signal.js";
13
15
  import { CHAT_CHANNEL_ORDER, getChatChannelMeta } from "./registry.js";
14
16
  const formatLower = (allowFrom) => allowFrom
15
17
  .map((entry) => String(entry).trim())
16
18
  .filter(Boolean)
17
19
  .map((entry) => entry.toLowerCase());
18
- const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
20
+ const formatDiscordAllowFrom = (allowFrom) => allowFrom
21
+ .map((entry) => String(entry)
22
+ .trim()
23
+ .replace(/^<@!?/, "")
24
+ .replace(/>$/, "")
25
+ .replace(/^discord:/i, "")
26
+ .replace(/^user:/i, "")
27
+ .replace(/^pk:/i, "")
28
+ .trim()
29
+ .toLowerCase())
30
+ .filter(Boolean);
31
+ function resolveDirectOrGroupChannelId(context) {
32
+ const isDirect = context.ChatType?.toLowerCase() === "direct";
33
+ return (isDirect ? (context.From ?? context.To) : context.To)?.trim() || undefined;
34
+ }
35
+ function buildSignalThreadToolContext(params) {
36
+ const currentChannelIdRaw = resolveDirectOrGroupChannelId(params.context);
37
+ const currentChannelId = currentChannelIdRaw
38
+ ? (normalizeSignalMessagingTarget(currentChannelIdRaw) ?? currentChannelIdRaw.trim())
39
+ : undefined;
40
+ return {
41
+ currentChannelId,
42
+ currentThreadTs: params.context.ReplyToId,
43
+ hasRepliedRef: params.hasRepliedRef,
44
+ };
45
+ }
46
+ function buildIMessageThreadToolContext(params) {
47
+ return {
48
+ currentChannelId: resolveDirectOrGroupChannelId(params.context),
49
+ currentThreadTs: params.context.ReplyToId,
50
+ hasRepliedRef: params.hasRepliedRef,
51
+ };
52
+ }
19
53
  // Channel docks: lightweight channel metadata/behavior for shared code paths.
20
54
  //
21
55
  // Rules:
@@ -48,7 +82,7 @@ const DOCKS = {
48
82
  resolveToolPolicy: resolveTelegramGroupToolPolicy,
49
83
  },
50
84
  threading: {
51
- resolveReplyToMode: ({ cfg }) => cfg.channels?.telegram?.replyToMode ?? "first",
85
+ resolveReplyToMode: ({ cfg }) => cfg.channels?.telegram?.replyToMode ?? "off",
52
86
  buildToolContext: ({ context, hasRepliedRef }) => {
53
87
  const threadId = context.MessageThreadId ?? context.ReplyToId;
54
88
  return {
@@ -83,13 +117,14 @@ const DOCKS = {
83
117
  groups: {
84
118
  resolveRequireMention: resolveWhatsAppGroupRequireMention,
85
119
  resolveToolPolicy: resolveWhatsAppGroupToolPolicy,
86
- resolveGroupIntroHint: () => "WhatsApp IDs: SenderId is the participant JID; [message_id: ...] is the message id for reactions (use SenderId as participant).",
120
+ resolveGroupIntroHint: () => "WhatsApp IDs: SenderId is the participant JID (group participant id).",
87
121
  },
88
122
  mentions: {
89
123
  stripPatterns: ({ ctx }) => {
90
124
  const selfE164 = (ctx.To ?? "").replace(/^whatsapp:/, "");
91
- if (!selfE164)
125
+ if (!selfE164) {
92
126
  return [];
127
+ }
93
128
  const escaped = escapeRegExp(selfE164);
94
129
  return [escaped, `@${escaped}`];
95
130
  },
@@ -120,11 +155,14 @@ const DOCKS = {
120
155
  blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
121
156
  },
122
157
  elevated: {
123
- allowFromFallback: ({ cfg }) => cfg.channels?.discord?.dm?.allowFrom,
158
+ allowFromFallback: ({ cfg }) => cfg.channels?.discord?.allowFrom ?? cfg.channels?.discord?.dm?.allowFrom,
124
159
  },
125
160
  config: {
126
- resolveAllowFrom: ({ cfg, accountId }) => (resolveDiscordAccount({ cfg, accountId }).config.dm?.allowFrom ?? []).map((entry) => String(entry)),
127
- formatAllowFrom: ({ allowFrom }) => formatLower(allowFrom),
161
+ resolveAllowFrom: ({ cfg, accountId }) => {
162
+ const account = resolveDiscordAccount({ cfg, accountId });
163
+ return (account.config.allowFrom ?? account.config.dm?.allowFrom ?? []).map((entry) => String(entry));
164
+ },
165
+ formatAllowFrom: ({ allowFrom }) => formatDiscordAllowFrom(allowFrom),
128
166
  },
129
167
  groups: {
130
168
  resolveRequireMention: resolveDiscordGroupRequireMention,
@@ -142,6 +180,65 @@ const DOCKS = {
142
180
  }),
143
181
  },
144
182
  },
183
+ irc: {
184
+ id: "irc",
185
+ capabilities: {
186
+ chatTypes: ["direct", "group"],
187
+ media: true,
188
+ blockStreaming: true,
189
+ },
190
+ outbound: { textChunkLimit: 350 },
191
+ streaming: {
192
+ blockStreamingCoalesceDefaults: { minChars: 300, idleMs: 1000 },
193
+ },
194
+ config: {
195
+ resolveAllowFrom: ({ cfg, accountId }) => {
196
+ const channel = cfg.channels?.irc;
197
+ const normalized = normalizeAccountId(accountId);
198
+ const account = channel?.accounts?.[normalized] ??
199
+ channel?.accounts?.[Object.keys(channel?.accounts ?? {}).find((key) => key.toLowerCase() === normalized.toLowerCase()) ?? ""];
200
+ return (account?.allowFrom ?? channel?.allowFrom ?? []).map((entry) => String(entry));
201
+ },
202
+ formatAllowFrom: ({ allowFrom }) => allowFrom
203
+ .map((entry) => String(entry).trim())
204
+ .filter(Boolean)
205
+ .map((entry) => entry
206
+ .replace(/^irc:/i, "")
207
+ .replace(/^user:/i, "")
208
+ .toLowerCase()),
209
+ },
210
+ groups: {
211
+ resolveRequireMention: ({ cfg, accountId, groupId }) => {
212
+ if (!groupId) {
213
+ return true;
214
+ }
215
+ return resolveChannelGroupRequireMention({
216
+ cfg,
217
+ channel: "irc",
218
+ groupId,
219
+ accountId,
220
+ groupIdCaseInsensitive: true,
221
+ });
222
+ },
223
+ resolveToolPolicy: ({ cfg, accountId, groupId, senderId, senderName, senderUsername }) => {
224
+ if (!groupId) {
225
+ return undefined;
226
+ }
227
+ // IRC supports per-channel tool policies. Prefer the shared resolver so
228
+ // toolsBySender is honored consistently across surfaces.
229
+ return resolveChannelGroupToolsPolicy({
230
+ cfg,
231
+ channel: "irc",
232
+ groupId,
233
+ accountId,
234
+ groupIdCaseInsensitive: true,
235
+ senderId,
236
+ senderName,
237
+ senderUsername,
238
+ });
239
+ },
240
+ },
241
+ },
145
242
  googlechat: {
146
243
  id: "googlechat",
147
244
  capabilities: {
@@ -199,16 +296,22 @@ const DOCKS = {
199
296
  blockStreamingCoalesceDefaults: { minChars: 1500, idleMs: 1000 },
200
297
  },
201
298
  config: {
202
- resolveAllowFrom: ({ cfg, accountId }) => (resolveSlackAccount({ cfg, accountId }).dm?.allowFrom ?? []).map((entry) => String(entry)),
299
+ resolveAllowFrom: ({ cfg, accountId }) => {
300
+ const account = resolveSlackAccount({ cfg, accountId });
301
+ return (account.config.allowFrom ?? account.dm?.allowFrom ?? []).map((entry) => String(entry));
302
+ },
203
303
  formatAllowFrom: ({ allowFrom }) => formatLower(allowFrom),
204
304
  },
205
305
  groups: {
206
306
  resolveRequireMention: resolveSlackGroupRequireMention,
207
307
  resolveToolPolicy: resolveSlackGroupToolPolicy,
208
308
  },
309
+ mentions: {
310
+ stripPatterns: () => ["<@[^>]+>"],
311
+ },
209
312
  threading: {
210
313
  resolveReplyToMode: ({ cfg, accountId, chatType }) => resolveSlackReplyToMode(resolveSlackAccount({ cfg, accountId }), chatType),
211
- allowTagsWhenOff: true,
314
+ allowExplicitReplyTagsWhenOff: true,
212
315
  buildToolContext: (params) => buildSlackThreadingToolContext(params),
213
316
  },
214
317
  },
@@ -232,15 +335,7 @@ const DOCKS = {
232
335
  .filter(Boolean),
233
336
  },
234
337
  threading: {
235
- buildToolContext: ({ context, hasRepliedRef }) => {
236
- const isDirect = context.ChatType?.toLowerCase() === "direct";
237
- const channelId = (isDirect ? (context.From ?? context.To) : context.To)?.trim() || undefined;
238
- return {
239
- currentChannelId: channelId,
240
- currentThreadTs: context.ReplyToId,
241
- hasRepliedRef,
242
- };
243
- },
338
+ buildToolContext: ({ context, hasRepliedRef }) => buildSignalThreadToolContext({ context, hasRepliedRef }),
244
339
  },
245
340
  },
246
341
  imessage: {
@@ -260,15 +355,7 @@ const DOCKS = {
260
355
  resolveToolPolicy: resolveIMessageGroupToolPolicy,
261
356
  },
262
357
  threading: {
263
- buildToolContext: ({ context, hasRepliedRef }) => {
264
- const isDirect = context.ChatType?.toLowerCase() === "direct";
265
- const channelId = (isDirect ? (context.From ?? context.To) : context.To)?.trim() || undefined;
266
- return {
267
- currentChannelId: channelId,
268
- currentThreadTs: context.ReplyToId,
269
- hasRepliedRef,
270
- };
271
- },
358
+ buildToolContext: ({ context, hasRepliedRef }) => buildIMessageThreadToolContext({ context, hasRepliedRef }),
272
359
  },
273
360
  },
274
361
  };
@@ -303,11 +390,13 @@ function listPluginDockEntries() {
303
390
  for (const entry of registry.channels) {
304
391
  const plugin = entry.plugin;
305
392
  const id = String(plugin.id).trim();
306
- if (!id || seen.has(id))
393
+ if (!id || seen.has(id)) {
307
394
  continue;
395
+ }
308
396
  seen.add(id);
309
- if (CHAT_CHANNEL_ORDER.includes(plugin.id))
397
+ if (CHAT_CHANNEL_ORDER.includes(plugin.id)) {
310
398
  continue;
399
+ }
311
400
  const dock = entry.dock ?? buildDockFromPlugin(plugin);
312
401
  entries.push({ id: plugin.id, dock, order: plugin.meta.order });
313
402
  }
@@ -326,19 +415,22 @@ export function listChannelDocks() {
326
415
  const indexB = CHAT_CHANNEL_ORDER.indexOf(b.id);
327
416
  const orderA = a.order ?? (indexA === -1 ? 999 : indexA);
328
417
  const orderB = b.order ?? (indexB === -1 ? 999 : indexB);
329
- if (orderA !== orderB)
418
+ if (orderA !== orderB) {
330
419
  return orderA - orderB;
420
+ }
331
421
  return String(a.id).localeCompare(String(b.id));
332
422
  });
333
423
  return combined.map((entry) => entry.dock);
334
424
  }
335
425
  export function getChannelDock(id) {
336
426
  const core = DOCKS[id];
337
- if (core)
427
+ if (core) {
338
428
  return core;
429
+ }
339
430
  const registry = requireActivePluginRegistry();
340
431
  const pluginEntry = registry.channels.find((entry) => entry.plugin.id === id);
341
- if (!pluginEntry)
432
+ if (!pluginEntry) {
342
433
  return undefined;
434
+ }
343
435
  return pluginEntry.dock ?? buildDockFromPlugin(pluginEntry.plugin);
344
436
  }
@@ -19,14 +19,18 @@ export function createDraftStreamLoop(params) {
19
19
  return;
20
20
  }
21
21
  pendingText = "";
22
- lastSentAt = Date.now();
23
22
  const current = params.sendOrEditStreamMessage(text).finally(() => {
24
23
  if (inFlightPromise === current) {
25
24
  inFlightPromise = undefined;
26
25
  }
27
26
  });
28
27
  inFlightPromise = current;
29
- await current;
28
+ const sent = await current;
29
+ if (sent === false) {
30
+ pendingText = text;
31
+ return;
32
+ }
33
+ lastSentAt = Date.now();
30
34
  if (!pendingText) {
31
35
  return;
32
36
  }
@@ -1,6 +1,7 @@
1
- import { createActionGate, readNumberParam, readStringArrayParam, readStringOrNumberParam, readStringParam, } from "../../../agents/tools/common.js";
1
+ import { readNumberParam, readStringArrayParam, readStringOrNumberParam, readStringParam, } from "../../../agents/tools/common.js";
2
2
  import { handleTelegramAction } from "../../../agents/tools/telegram-actions.js";
3
- import { listEnabledTelegramAccounts } from "../../../telegram/accounts.js";
3
+ import { extractToolSend } from "../../../plugin-sdk/tool-send.js";
4
+ import { createTelegramActionGate, listEnabledTelegramAccounts, } from "../../../telegram/accounts.js";
4
5
  import { isTelegramInlineButtonsEnabled } from "../../../telegram/inline-buttons.js";
5
6
  const providerId = "telegram";
6
7
  function readTelegramSendParams(params) {
@@ -14,6 +15,7 @@ function readTelegramSendParams(params) {
14
15
  const buttons = params.buttons;
15
16
  const asVoice = typeof params.asVoice === "boolean" ? params.asVoice : undefined;
16
17
  const silent = typeof params.silent === "boolean" ? params.silent : undefined;
18
+ const quoteText = readStringParam(params, "quoteText");
17
19
  return {
18
20
  to,
19
21
  content,
@@ -23,42 +25,46 @@ function readTelegramSendParams(params) {
23
25
  buttons,
24
26
  asVoice,
25
27
  silent,
28
+ quoteText: quoteText ?? undefined,
26
29
  };
27
30
  }
28
31
  export const telegramMessageActions = {
29
32
  listActions: ({ cfg }) => {
30
33
  const accounts = listEnabledTelegramAccounts(cfg).filter((account) => account.tokenSource !== "none");
31
- if (accounts.length === 0)
34
+ if (accounts.length === 0) {
32
35
  return [];
33
- const gate = createActionGate(cfg.channels?.telegram?.actions);
36
+ }
37
+ // Union of all accounts' action gates (any account enabling an action makes it available)
38
+ const gates = accounts.map((account) => createTelegramActionGate({ cfg, accountId: account.accountId }));
39
+ const gate = (key, defaultValue = true) => gates.some((g) => g(key, defaultValue));
34
40
  const actions = new Set(["send"]);
35
- if (gate("reactions"))
41
+ if (gate("reactions")) {
36
42
  actions.add("react");
37
- if (gate("deleteMessage"))
43
+ }
44
+ if (gate("deleteMessage")) {
38
45
  actions.add("delete");
39
- if (gate("editMessage"))
46
+ }
47
+ if (gate("editMessage")) {
40
48
  actions.add("edit");
49
+ }
41
50
  if (gate("sticker", false)) {
42
51
  actions.add("sticker");
43
52
  actions.add("sticker-search");
44
53
  }
54
+ if (gate("createForumTopic")) {
55
+ actions.add("topic-create");
56
+ }
45
57
  return Array.from(actions);
46
58
  },
47
59
  supportsButtons: ({ cfg }) => {
48
60
  const accounts = listEnabledTelegramAccounts(cfg).filter((account) => account.tokenSource !== "none");
49
- if (accounts.length === 0)
61
+ if (accounts.length === 0) {
50
62
  return false;
63
+ }
51
64
  return accounts.some((account) => isTelegramInlineButtonsEnabled({ cfg, accountId: account.accountId }));
52
65
  },
53
66
  extractToolSend: ({ args }) => {
54
- const action = typeof args.action === "string" ? args.action.trim() : "";
55
- if (action !== "sendMessage")
56
- return null;
57
- const to = typeof args.to === "string" ? args.to : undefined;
58
- if (!to)
59
- return null;
60
- const accountId = typeof args.accountId === "string" ? args.accountId.trim() : undefined;
61
- return { to, accountId };
67
+ return extractToolSend(args, "sendMessage");
62
68
  },
63
69
  handleAction: async ({ action, params, cfg, accountId }) => {
64
70
  if (action === "send") {
@@ -70,14 +76,16 @@ export const telegramMessageActions = {
70
76
  }, cfg);
71
77
  }
72
78
  if (action === "react") {
73
- const messageId = readStringParam(params, "messageId", {
79
+ const messageId = readStringOrNumberParam(params, "messageId", {
74
80
  required: true,
75
81
  });
76
82
  const emoji = readStringParam(params, "emoji", { allowEmpty: true });
77
83
  const remove = typeof params.remove === "boolean" ? params.remove : undefined;
78
84
  return await handleTelegramAction({
79
85
  action: "react",
80
- chatId: readStringParam(params, "chatId") ?? readStringParam(params, "to", { required: true }),
86
+ chatId: readStringOrNumberParam(params, "chatId") ??
87
+ readStringOrNumberParam(params, "channelId") ??
88
+ readStringParam(params, "to", { required: true }),
81
89
  messageId,
82
90
  emoji,
83
91
  remove,
@@ -144,6 +152,22 @@ export const telegramMessageActions = {
144
152
  accountId: accountId ?? undefined,
145
153
  }, cfg);
146
154
  }
155
+ if (action === "topic-create") {
156
+ const chatId = readStringOrNumberParam(params, "chatId") ??
157
+ readStringOrNumberParam(params, "channelId") ??
158
+ readStringParam(params, "to", { required: true });
159
+ const name = readStringParam(params, "name", { required: true });
160
+ const iconColor = readNumberParam(params, "iconColor", { integer: true });
161
+ const iconCustomEmojiId = readStringParam(params, "iconCustomEmojiId");
162
+ return await handleTelegramAction({
163
+ action: "createForumTopic",
164
+ chatId,
165
+ name,
166
+ iconColor: iconColor ?? undefined,
167
+ iconCustomEmojiId: iconCustomEmojiId ?? undefined,
168
+ accountId: accountId ?? undefined,
169
+ }, cfg);
170
+ }
147
171
  throw new Error(`Action ${action} is not supported for provider ${providerId}.`);
148
172
  },
149
173
  };
@@ -1 +1 @@
1
- export { formatAllowlistMatchMeta } from "../allowlist-match.js";
1
+ export { formatAllowlistMatchMeta, resolveAllowlistMatchSimple } from "../allowlist-match.js";