@poolzin/pool-bot 2026.2.23 → 2026.2.25

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 (235) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/acp/client.js +207 -18
  3. package/dist/acp/secret-file.js +22 -0
  4. package/dist/agents/agent-scope.js +10 -0
  5. package/dist/agents/bash-process-registry.test-helpers.js +29 -0
  6. package/dist/agents/bash-tools.exec-approval-request.js +20 -0
  7. package/dist/agents/bash-tools.exec-host-gateway.js +230 -0
  8. package/dist/agents/bash-tools.exec-host-node.js +235 -0
  9. package/dist/agents/bash-tools.exec-types.js +1 -0
  10. package/dist/agents/bash-tools.process.js +224 -218
  11. package/dist/agents/content-blocks.js +16 -0
  12. package/dist/agents/model-fallback.js +96 -101
  13. package/dist/agents/models-config.providers.js +299 -182
  14. package/dist/agents/pi-embedded-payloads.js +1 -0
  15. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +34 -0
  16. package/dist/agents/skills.test-helpers.js +13 -0
  17. package/dist/agents/stable-stringify.js +12 -0
  18. package/dist/agents/subagent-registry.mocks.shared.js +12 -0
  19. package/dist/agents/test-helpers/assistant-message-fixtures.js +29 -0
  20. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +27 -0
  21. package/dist/agents/tool-policy-shared.js +108 -0
  22. package/dist/agents/tools/browser-tool.js +160 -54
  23. package/dist/agents/tools/cron-tool.test-helpers.js +12 -0
  24. package/dist/agents/tools/discord-actions-moderation-shared.js +27 -0
  25. package/dist/agents/tools/image-tool.js +214 -99
  26. package/dist/agents/tools/sessions-history-tool.js +140 -108
  27. package/dist/agents/workspace.js +222 -46
  28. package/dist/auto-reply/commands-registry.js +15 -18
  29. package/dist/auto-reply/fallback-state.js +114 -0
  30. package/dist/auto-reply/model-runtime.js +68 -0
  31. package/dist/auto-reply/reply/agent-runner-execution.js +36 -4
  32. package/dist/auto-reply/reply/agent-runner.js +165 -39
  33. package/dist/auto-reply/reply/commands-setunset-standard.js +13 -0
  34. package/dist/browser/config.js +26 -0
  35. package/dist/browser/navigation-guard.js +31 -0
  36. package/dist/browser/routes/agent.act.js +431 -424
  37. package/dist/browser/routes/agent.shared.js +47 -3
  38. package/dist/browser/routes/agent.snapshot.js +122 -116
  39. package/dist/browser/routes/agent.storage.js +303 -297
  40. package/dist/browser/routes/tabs.js +154 -100
  41. package/dist/browser/server-lifecycle.js +37 -0
  42. package/dist/build-info.json +3 -3
  43. package/dist/channels/allow-from.js +25 -0
  44. package/dist/channels/plugins/account-action-gate.js +13 -0
  45. package/dist/channels/plugins/message-actions.js +10 -0
  46. package/dist/channels/telegram/api.js +18 -0
  47. package/dist/cli/argv.js +84 -21
  48. package/dist/cli/banner.js +2 -1
  49. package/dist/cli/exec-approvals-cli.js +92 -124
  50. package/dist/cli/memory-cli.js +158 -61
  51. package/dist/cli/nodes-cli/register.push.js +63 -0
  52. package/dist/cli/nodes-media-utils.js +21 -0
  53. package/dist/cli/plugins-cli.js +245 -61
  54. package/dist/cli/program/build-program.js +3 -1
  55. package/dist/cli/program/command-registry.js +223 -136
  56. package/dist/cli/program/help.js +43 -12
  57. package/dist/cli/route.js +1 -1
  58. package/dist/cli/test-runtime-capture.js +24 -0
  59. package/dist/commands/agent.js +163 -87
  60. package/dist/commands/channels.mock-harness.js +23 -0
  61. package/dist/commands/daemon-install-runtime-warning.js +11 -0
  62. package/dist/commands/onboard-helpers.js +4 -4
  63. package/dist/commands/sessions.test-helpers.js +61 -0
  64. package/dist/compat/legacy-names.js +2 -2
  65. package/dist/config/commands.js +3 -0
  66. package/dist/config/config.js +1 -1
  67. package/dist/config/env-substitution.js +62 -34
  68. package/dist/config/env-vars.js +9 -0
  69. package/dist/config/io.js +571 -171
  70. package/dist/config/merge-patch.js +50 -4
  71. package/dist/config/redact-snapshot.js +404 -76
  72. package/dist/config/schema.js +58 -570
  73. package/dist/config/validation.js +140 -85
  74. package/dist/config/zod-schema.hooks.js +40 -11
  75. package/dist/config/zod-schema.installs.js +20 -0
  76. package/dist/config/zod-schema.js +8 -7
  77. package/dist/control-ui/assets/{index-HRr1grwl.js → index-Dvkl4Xlx.js} +2 -1
  78. package/dist/control-ui/assets/{index-HRr1grwl.js.map → index-Dvkl4Xlx.js.map} +1 -1
  79. package/dist/control-ui/index.html +1 -1
  80. package/dist/daemon/cmd-argv.js +21 -0
  81. package/dist/daemon/cmd-set.js +58 -0
  82. package/dist/daemon/service-types.js +1 -0
  83. package/dist/discord/monitor/exec-approvals.js +357 -162
  84. package/dist/gateway/auth.js +38 -3
  85. package/dist/gateway/call.js +149 -68
  86. package/dist/gateway/canvas-capability.js +75 -0
  87. package/dist/gateway/control-plane-audit.js +28 -0
  88. package/dist/gateway/control-plane-rate-limit.js +53 -0
  89. package/dist/gateway/events.js +1 -0
  90. package/dist/gateway/hooks.js +109 -54
  91. package/dist/gateway/http-common.js +22 -0
  92. package/dist/gateway/method-scopes.js +169 -0
  93. package/dist/gateway/net.js +23 -0
  94. package/dist/gateway/openresponses-http.js +120 -110
  95. package/dist/gateway/probe-auth.js +2 -0
  96. package/dist/gateway/protocol/index.js +3 -2
  97. package/dist/gateway/protocol/schema/protocol-schemas.js +2 -0
  98. package/dist/gateway/protocol/schema/push.js +18 -0
  99. package/dist/gateway/protocol/schema.js +1 -0
  100. package/dist/gateway/server-http.js +236 -52
  101. package/dist/gateway/server-methods/agent.js +162 -24
  102. package/dist/gateway/server-methods/chat.js +461 -130
  103. package/dist/gateway/server-methods/config.js +193 -150
  104. package/dist/gateway/server-methods/nodes.helpers.js +12 -0
  105. package/dist/gateway/server-methods/nodes.js +251 -69
  106. package/dist/gateway/server-methods/push.js +53 -0
  107. package/dist/gateway/server-reload-handlers.js +2 -3
  108. package/dist/gateway/server-runtime-config.js +5 -0
  109. package/dist/gateway/server-runtime-state.js +2 -0
  110. package/dist/gateway/server-ws-runtime.js +1 -0
  111. package/dist/gateway/server.impl.js +296 -139
  112. package/dist/gateway/session-preview.test-helpers.js +11 -0
  113. package/dist/gateway/startup-auth.js +126 -0
  114. package/dist/gateway/test-helpers.agent-results.js +15 -0
  115. package/dist/gateway/test-helpers.mocks.js +37 -14
  116. package/dist/gateway/test-helpers.server.js +161 -77
  117. package/dist/hooks/bundled/session-memory/handler.js +165 -34
  118. package/dist/hooks/gmail-watcher-lifecycle.js +23 -0
  119. package/dist/infra/archive-path.js +49 -0
  120. package/dist/infra/device-pairing.js +148 -167
  121. package/dist/infra/exec-approvals-allowlist.js +19 -70
  122. package/dist/infra/exec-approvals-analysis.js +44 -17
  123. package/dist/infra/exec-safe-bin-policy.js +269 -0
  124. package/dist/infra/fixed-window-rate-limit.js +33 -0
  125. package/dist/infra/git-root.js +61 -0
  126. package/dist/infra/heartbeat-active-hours.js +2 -2
  127. package/dist/infra/heartbeat-reason.js +40 -0
  128. package/dist/infra/heartbeat-runner.js +72 -32
  129. package/dist/infra/install-source-utils.js +91 -7
  130. package/dist/infra/node-pairing.js +50 -105
  131. package/dist/infra/npm-integrity.js +45 -0
  132. package/dist/infra/npm-pack-install.js +40 -0
  133. package/dist/infra/outbound/channel-adapters.js +20 -7
  134. package/dist/infra/outbound/message-action-runner.js +107 -327
  135. package/dist/infra/outbound/message.js +59 -36
  136. package/dist/infra/outbound/outbound-policy.js +52 -25
  137. package/dist/infra/outbound/outbound-send-service.js +58 -71
  138. package/dist/infra/pairing-files.js +10 -0
  139. package/dist/infra/plain-object.js +9 -0
  140. package/dist/infra/push-apns.js +365 -0
  141. package/dist/infra/restart-sentinel.js +16 -1
  142. package/dist/infra/restart.js +229 -26
  143. package/dist/infra/scp-host.js +54 -0
  144. package/dist/infra/update-startup.js +86 -9
  145. package/dist/media/inbound-path-policy.js +114 -0
  146. package/dist/media/input-files.js +16 -0
  147. package/dist/memory/test-manager.js +8 -0
  148. package/dist/plugin-sdk/temp-path.js +47 -0
  149. package/dist/plugins/discovery.js +217 -23
  150. package/dist/plugins/hook-runner-global.js +16 -0
  151. package/dist/plugins/loader.js +192 -26
  152. package/dist/plugins/logger.js +8 -0
  153. package/dist/plugins/manifest-registry.js +3 -0
  154. package/dist/plugins/path-safety.js +34 -0
  155. package/dist/plugins/registry.js +5 -2
  156. package/dist/plugins/runtime/index.js +271 -206
  157. package/dist/providers/github-copilot-models.js +4 -1
  158. package/dist/security/audit-channel.js +8 -19
  159. package/dist/security/audit-extra.async.js +354 -182
  160. package/dist/security/audit-extra.js +11 -1
  161. package/dist/security/audit-extra.sync.js +340 -33
  162. package/dist/security/audit-fs.js +31 -13
  163. package/dist/security/audit.js +145 -371
  164. package/dist/security/dm-policy-shared.js +24 -0
  165. package/dist/security/external-content.js +20 -8
  166. package/dist/security/fix.js +49 -85
  167. package/dist/security/scan-paths.js +20 -0
  168. package/dist/security/secret-equal.js +3 -7
  169. package/dist/security/windows-acl.js +30 -15
  170. package/dist/shared/node-list-parse.js +13 -0
  171. package/dist/shared/operator-scope-compat.js +37 -0
  172. package/dist/shared/text-chunking.js +29 -0
  173. package/dist/slack/blocks.test-helpers.js +31 -0
  174. package/dist/slack/monitor/mrkdwn.js +8 -0
  175. package/dist/telegram/bot-message-dispatch.js +366 -164
  176. package/dist/telegram/draft-stream.js +30 -7
  177. package/dist/telegram/reasoning-lane-coordinator.js +128 -0
  178. package/dist/terminal/prompt-select-styled.js +9 -0
  179. package/dist/test-utils/command-runner.js +6 -0
  180. package/dist/test-utils/internal-hook-event-payload.js +10 -0
  181. package/dist/test-utils/model-auth-mock.js +12 -0
  182. package/dist/test-utils/provider-usage-fetch.js +14 -0
  183. package/dist/test-utils/temp-home.js +33 -0
  184. package/dist/tui/components/chat-log.js +9 -0
  185. package/dist/tui/tui-command-handlers.js +36 -27
  186. package/dist/tui/tui-event-handlers.js +122 -32
  187. package/dist/tui/tui.js +181 -45
  188. package/dist/utils/mask-api-key.js +10 -0
  189. package/dist/utils/run-with-concurrency.js +39 -0
  190. package/dist/web/media.js +4 -0
  191. package/docs/tools/slash-commands.md +5 -1
  192. package/extensions/bluebubbles/package.json +1 -1
  193. package/extensions/copilot-proxy/package.json +1 -1
  194. package/extensions/diagnostics-otel/package.json +1 -1
  195. package/extensions/discord/package.json +1 -1
  196. package/extensions/feishu/package.json +1 -1
  197. package/extensions/feishu/src/external-keys.ts +19 -0
  198. package/extensions/google-antigravity-auth/package.json +1 -1
  199. package/extensions/google-gemini-cli-auth/package.json +1 -1
  200. package/extensions/googlechat/package.json +1 -1
  201. package/extensions/imessage/package.json +1 -1
  202. package/extensions/irc/package.json +1 -1
  203. package/extensions/line/package.json +1 -1
  204. package/extensions/llm-task/package.json +1 -1
  205. package/extensions/lobster/package.json +1 -1
  206. package/extensions/lobster/src/windows-spawn.ts +193 -0
  207. package/extensions/matrix/CHANGELOG.md +5 -0
  208. package/extensions/matrix/package.json +1 -1
  209. package/extensions/matrix/src/matrix/actions/limits.ts +6 -0
  210. package/extensions/mattermost/package.json +1 -1
  211. package/extensions/mattermost/src/mattermost/reactions.test-helpers.ts +83 -0
  212. package/extensions/memory-core/package.json +1 -1
  213. package/extensions/memory-lancedb/package.json +1 -1
  214. package/extensions/minimax-portal-auth/package.json +1 -1
  215. package/extensions/msteams/CHANGELOG.md +5 -0
  216. package/extensions/msteams/package.json +1 -1
  217. package/extensions/nextcloud-talk/package.json +1 -1
  218. package/extensions/nostr/CHANGELOG.md +5 -0
  219. package/extensions/nostr/package.json +1 -1
  220. package/extensions/open-prose/package.json +1 -1
  221. package/extensions/openai-codex-auth/package.json +1 -1
  222. package/extensions/signal/package.json +1 -1
  223. package/extensions/slack/package.json +1 -1
  224. package/extensions/telegram/package.json +1 -1
  225. package/extensions/tlon/package.json +1 -1
  226. package/extensions/twitch/CHANGELOG.md +5 -0
  227. package/extensions/twitch/package.json +1 -1
  228. package/extensions/voice-call/CHANGELOG.md +5 -0
  229. package/extensions/voice-call/package.json +1 -1
  230. package/extensions/whatsapp/package.json +1 -1
  231. package/extensions/zalo/CHANGELOG.md +5 -0
  232. package/extensions/zalo/package.json +1 -1
  233. package/extensions/zalouser/CHANGELOG.md +5 -0
  234. package/extensions/zalouser/package.json +1 -1
  235. package/package.json +1 -1
@@ -1,30 +1,29 @@
1
1
  import { createRequire } from "node:module";
2
+ import { resolveEffectiveMessagesConfig, resolveHumanDelayConfig } from "../../agents/identity.js";
3
+ import { createMemoryGetTool, createMemorySearchTool } from "../../agents/tools/memory-tool.js";
4
+ import { handleSlackAction } from "../../agents/tools/slack-actions.js";
2
5
  import { chunkByNewline, chunkMarkdownText, chunkMarkdownTextWithMode, chunkText, chunkTextWithMode, resolveChunkMode, resolveTextChunkLimit, } from "../../auto-reply/chunk.js";
3
6
  import { hasControlCommand, isControlCommandMessage, shouldComputeCommandAuthorized, } from "../../auto-reply/command-detection.js";
4
7
  import { shouldHandleTextCommands } from "../../auto-reply/commands-registry.js";
5
- import { createInboundDebouncer, resolveInboundDebounceMs, } from "../../auto-reply/inbound-debounce.js";
6
8
  import { formatAgentEnvelope, formatInboundEnvelope, resolveEnvelopeFormatOptions, } from "../../auto-reply/envelope.js";
9
+ import { createInboundDebouncer, resolveInboundDebounceMs, } from "../../auto-reply/inbound-debounce.js";
7
10
  import { dispatchReplyFromConfig } from "../../auto-reply/reply/dispatch-from-config.js";
11
+ import { finalizeInboundContext } from "../../auto-reply/reply/inbound-context.js";
8
12
  import { buildMentionRegexes, matchesMentionPatterns, matchesMentionWithExplicit, } from "../../auto-reply/reply/mentions.js";
9
13
  import { dispatchReplyWithBufferedBlockDispatcher } from "../../auto-reply/reply/provider-dispatcher.js";
10
14
  import { createReplyDispatcherWithTyping } from "../../auto-reply/reply/reply-dispatcher.js";
11
- import { finalizeInboundContext } from "../../auto-reply/reply/inbound-context.js";
12
- import { resolveEffectiveMessagesConfig, resolveHumanDelayConfig } from "../../agents/identity.js";
13
- import { createMemoryGetTool, createMemorySearchTool } from "../../agents/tools/memory-tool.js";
14
- import { handleSlackAction } from "../../agents/tools/slack-actions.js";
15
- import { handleWhatsAppAction } from "../../agents/tools/whatsapp-actions.js";
16
15
  import { removeAckReactionAfterReply, shouldAckReaction } from "../../channels/ack-reactions.js";
17
16
  import { resolveCommandAuthorizedFromAuthorizers } from "../../channels/command-gating.js";
18
- import { recordInboundSession } from "../../channels/session.js";
19
17
  import { discordMessageActions } from "../../channels/plugins/actions/discord.js";
20
18
  import { signalMessageActions } from "../../channels/plugins/actions/signal.js";
21
19
  import { telegramMessageActions } from "../../channels/plugins/actions/telegram.js";
22
20
  import { createWhatsAppLoginTool } from "../../channels/plugins/agent-tools/whatsapp-login.js";
23
- import { monitorWebChannel } from "../../channels/web/index.js";
21
+ import { recordInboundSession } from "../../channels/session.js";
22
+ import { registerMemoryCli } from "../../cli/memory-cli.js";
23
+ import { loadConfig, writeConfigFile } from "../../config/config.js";
24
24
  import { resolveChannelGroupPolicy, resolveChannelGroupRequireMention, } from "../../config/group-policy.js";
25
25
  import { resolveMarkdownTableMode } from "../../config/markdown-tables.js";
26
26
  import { resolveStateDir } from "../../config/paths.js";
27
- import { loadConfig, writeConfigFile } from "../../config/config.js";
28
27
  import { readSessionUpdatedAt, recordSessionMetaFromInbound, resolveStorePath, updateLastRoute, } from "../../config/sessions.js";
29
28
  import { auditDiscordChannelPermissions } from "../../discord/audit.js";
30
29
  import { listDiscordDirectoryGroupsLive, listDiscordDirectoryPeersLive, } from "../../discord/directory-live.js";
@@ -33,15 +32,20 @@ import { probeDiscord } from "../../discord/probe.js";
33
32
  import { resolveDiscordChannelAllowlist } from "../../discord/resolve-channels.js";
34
33
  import { resolveDiscordUserAllowlist } from "../../discord/resolve-users.js";
35
34
  import { sendMessageDiscord, sendPollDiscord } from "../../discord/send.js";
36
- import { getChannelActivity, recordChannelActivity } from "../../infra/channel-activity.js";
37
- import { enqueueSystemEvent } from "../../infra/system-events.js";
35
+ import { shouldLogVerbose } from "../../globals.js";
38
36
  import { monitorIMessageProvider } from "../../imessage/monitor.js";
39
37
  import { probeIMessage } from "../../imessage/probe.js";
40
38
  import { sendMessageIMessage } from "../../imessage/send.js";
41
- import { shouldLogVerbose } from "../../globals.js";
42
- import { convertMarkdownTables } from "../../markdown/tables.js";
39
+ import { getChannelActivity, recordChannelActivity } from "../../infra/channel-activity.js";
40
+ import { enqueueSystemEvent } from "../../infra/system-events.js";
41
+ import { listLineAccountIds, normalizeAccountId as normalizeLineAccountId, resolveDefaultLineAccountId, resolveLineAccount, } from "../../line/accounts.js";
42
+ import { monitorLineProvider } from "../../line/monitor.js";
43
+ import { probeLineBot } from "../../line/probe.js";
44
+ import { createQuickReplyItems, pushMessageLine, pushMessagesLine, pushFlexMessage, pushTemplateMessage, pushLocationMessage, pushTextMessageWithQuickReplies, sendMessageLine, } from "../../line/send.js";
45
+ import { buildTemplateMessageFromPayload } from "../../line/template-messages.js";
43
46
  import { getChildLogger } from "../../logging.js";
44
47
  import { normalizeLogLevel } from "../../logging/levels.js";
48
+ import { convertMarkdownTables } from "../../markdown/tables.js";
45
49
  import { isVoiceCompatibleAudio } from "../../media/audio.js";
46
50
  import { mediaKindFromMime } from "../../media/constants.js";
47
51
  import { fetchRemoteMedia } from "../../media/fetch.js";
@@ -55,8 +59,8 @@ import { resolveAgentRoute } from "../../routing/resolve-route.js";
55
59
  import { monitorSignalProvider } from "../../signal/index.js";
56
60
  import { probeSignal } from "../../signal/probe.js";
57
61
  import { sendMessageSignal } from "../../signal/send.js";
58
- import { monitorSlackProvider } from "../../slack/index.js";
59
62
  import { listSlackDirectoryGroupsLive, listSlackDirectoryPeersLive, } from "../../slack/directory-live.js";
63
+ import { monitorSlackProvider } from "../../slack/index.js";
60
64
  import { probeSlack } from "../../slack/probe.js";
61
65
  import { resolveSlackChannelAllowlist } from "../../slack/resolve-channels.js";
62
66
  import { resolveSlackUserAllowlist } from "../../slack/resolve-users.js";
@@ -64,26 +68,18 @@ import { sendMessageSlack } from "../../slack/send.js";
64
68
  import { auditTelegramGroupMembership, collectTelegramUnmentionedGroupIds, } from "../../telegram/audit.js";
65
69
  import { monitorTelegramProvider } from "../../telegram/monitor.js";
66
70
  import { probeTelegram } from "../../telegram/probe.js";
67
- import { sendMessageTelegram } from "../../telegram/send.js";
71
+ import { sendMessageTelegram, sendPollTelegram } from "../../telegram/send.js";
68
72
  import { resolveTelegramToken } from "../../telegram/token.js";
69
- import { loadWebMedia } from "../../web/media.js";
73
+ import { textToSpeechTelephony } from "../../tts/tts.js";
70
74
  import { getActiveWebListener } from "../../web/active-listener.js";
71
75
  import { getWebAuthAgeMs, logoutWeb, logWebSelfId, readWebSelfId, webAuthExists, } from "../../web/auth-store.js";
72
- import { loginWeb } from "../../web/login.js";
73
- import { startWebLoginWithQr, waitForWebLogin } from "../../web/login-qr.js";
74
- import { sendMessageWhatsApp, sendPollWhatsApp } from "../../web/outbound.js";
75
- import { registerMemoryCli } from "../../cli/memory-cli.js";
76
+ import { loadWebMedia } from "../../web/media.js";
76
77
  import { formatNativeDependencyHint } from "./native-deps.js";
77
- import { textToSpeechTelephony } from "../../tts/tts.js";
78
- import { listLineAccountIds, normalizeAccountId as normalizeLineAccountId, resolveDefaultLineAccountId, resolveLineAccount, } from "../../line/accounts.js";
79
- import { probeLineBot } from "../../line/probe.js";
80
- import { createQuickReplyItems, pushMessageLine, pushMessagesLine, pushFlexMessage, pushTemplateMessage, pushLocationMessage, pushTextMessageWithQuickReplies, sendMessageLine, } from "../../line/send.js";
81
- import { monitorLineProvider } from "../../line/monitor.js";
82
- import { buildTemplateMessageFromPayload } from "../../line/template-messages.js";
83
78
  let cachedVersion = null;
84
79
  function resolveVersion() {
85
- if (cachedVersion)
80
+ if (cachedVersion) {
86
81
  return cachedVersion;
82
+ }
87
83
  try {
88
84
  const require = createRequire(import.meta.url);
89
85
  const pkg = require("../../../package.json");
@@ -95,196 +91,265 @@ function resolveVersion() {
95
91
  return cachedVersion;
96
92
  }
97
93
  }
94
+ const sendMessageWhatsAppLazy = async (...args) => {
95
+ const { sendMessageWhatsApp } = await loadWebOutbound();
96
+ return sendMessageWhatsApp(...args);
97
+ };
98
+ const sendPollWhatsAppLazy = async (...args) => {
99
+ const { sendPollWhatsApp } = await loadWebOutbound();
100
+ return sendPollWhatsApp(...args);
101
+ };
102
+ const loginWebLazy = async (...args) => {
103
+ const { loginWeb } = await loadWebLogin();
104
+ return loginWeb(...args);
105
+ };
106
+ const startWebLoginWithQrLazy = async (...args) => {
107
+ const { startWebLoginWithQr } = await loadWebLoginQr();
108
+ return startWebLoginWithQr(...args);
109
+ };
110
+ const waitForWebLoginLazy = async (...args) => {
111
+ const { waitForWebLogin } = await loadWebLoginQr();
112
+ return waitForWebLogin(...args);
113
+ };
114
+ const monitorWebChannelLazy = async (...args) => {
115
+ const { monitorWebChannel } = await loadWebChannel();
116
+ return monitorWebChannel(...args);
117
+ };
118
+ const handleWhatsAppActionLazy = async (...args) => {
119
+ const { handleWhatsAppAction } = await loadWhatsAppActions();
120
+ return handleWhatsAppAction(...args);
121
+ };
122
+ let webOutboundPromise = null;
123
+ let webLoginPromise = null;
124
+ let webLoginQrPromise = null;
125
+ let webChannelPromise = null;
126
+ let whatsappActionsPromise = null;
127
+ function loadWebOutbound() {
128
+ webOutboundPromise ??= import("../../web/outbound.js");
129
+ return webOutboundPromise;
130
+ }
131
+ function loadWebLogin() {
132
+ webLoginPromise ??= import("../../web/login.js");
133
+ return webLoginPromise;
134
+ }
135
+ function loadWebLoginQr() {
136
+ webLoginQrPromise ??= import("../../web/login-qr.js");
137
+ return webLoginQrPromise;
138
+ }
139
+ function loadWebChannel() {
140
+ webChannelPromise ??= import("../../channels/web/index.js");
141
+ return webChannelPromise;
142
+ }
143
+ function loadWhatsAppActions() {
144
+ whatsappActionsPromise ??= import("../../agents/tools/whatsapp-actions.js");
145
+ return whatsappActionsPromise;
146
+ }
98
147
  export function createPluginRuntime() {
99
148
  return {
100
149
  version: resolveVersion(),
101
- config: {
102
- loadConfig,
103
- writeConfigFile,
150
+ config: createRuntimeConfig(),
151
+ system: createRuntimeSystem(),
152
+ media: createRuntimeMedia(),
153
+ tts: { textToSpeechTelephony },
154
+ tools: createRuntimeTools(),
155
+ channel: createRuntimeChannel(),
156
+ logging: createRuntimeLogging(),
157
+ state: { resolveStateDir },
158
+ };
159
+ }
160
+ function createRuntimeConfig() {
161
+ return {
162
+ loadConfig,
163
+ writeConfigFile,
164
+ };
165
+ }
166
+ function createRuntimeSystem() {
167
+ return {
168
+ enqueueSystemEvent,
169
+ runCommandWithTimeout,
170
+ formatNativeDependencyHint,
171
+ };
172
+ }
173
+ function createRuntimeMedia() {
174
+ return {
175
+ loadWebMedia,
176
+ detectMime,
177
+ mediaKindFromMime,
178
+ isVoiceCompatibleAudio,
179
+ getImageMetadata,
180
+ resizeToJpeg,
181
+ };
182
+ }
183
+ function createRuntimeTools() {
184
+ return {
185
+ createMemoryGetTool,
186
+ createMemorySearchTool,
187
+ registerMemoryCli,
188
+ };
189
+ }
190
+ function createRuntimeChannel() {
191
+ return {
192
+ text: {
193
+ chunkByNewline,
194
+ chunkMarkdownText,
195
+ chunkMarkdownTextWithMode,
196
+ chunkText,
197
+ chunkTextWithMode,
198
+ resolveChunkMode,
199
+ resolveTextChunkLimit,
200
+ hasControlCommand,
201
+ resolveMarkdownTableMode,
202
+ convertMarkdownTables,
203
+ },
204
+ reply: {
205
+ dispatchReplyWithBufferedBlockDispatcher,
206
+ createReplyDispatcherWithTyping,
207
+ resolveEffectiveMessagesConfig,
208
+ resolveHumanDelayConfig,
209
+ dispatchReplyFromConfig,
210
+ finalizeInboundContext,
211
+ formatAgentEnvelope,
212
+ /** @deprecated Prefer `BodyForAgent` + structured user-context blocks (do not build plaintext envelopes for prompts). */
213
+ formatInboundEnvelope,
214
+ resolveEnvelopeFormatOptions,
104
215
  },
105
- system: {
106
- enqueueSystemEvent,
107
- runCommandWithTimeout,
108
- formatNativeDependencyHint,
216
+ routing: {
217
+ resolveAgentRoute,
218
+ },
219
+ pairing: {
220
+ buildPairingReply,
221
+ readAllowFromStore: readChannelAllowFromStore,
222
+ upsertPairingRequest: upsertChannelPairingRequest,
109
223
  },
110
224
  media: {
111
- loadWebMedia,
112
- detectMime,
113
- mediaKindFromMime,
114
- isVoiceCompatibleAudio,
115
- getImageMetadata,
116
- resizeToJpeg,
225
+ fetchRemoteMedia,
226
+ saveMediaBuffer,
227
+ },
228
+ activity: {
229
+ record: recordChannelActivity,
230
+ get: getChannelActivity,
231
+ },
232
+ session: {
233
+ resolveStorePath,
234
+ readSessionUpdatedAt,
235
+ recordSessionMetaFromInbound,
236
+ recordInboundSession,
237
+ updateLastRoute,
238
+ },
239
+ mentions: {
240
+ buildMentionRegexes,
241
+ matchesMentionPatterns,
242
+ matchesMentionWithExplicit,
243
+ },
244
+ reactions: {
245
+ shouldAckReaction,
246
+ removeAckReactionAfterReply,
117
247
  },
118
- tts: {
119
- textToSpeechTelephony,
248
+ groups: {
249
+ resolveGroupPolicy: resolveChannelGroupPolicy,
250
+ resolveRequireMention: resolveChannelGroupRequireMention,
120
251
  },
121
- tools: {
122
- createMemoryGetTool,
123
- createMemorySearchTool,
124
- registerMemoryCli,
252
+ debounce: {
253
+ createInboundDebouncer,
254
+ resolveInboundDebounceMs,
125
255
  },
126
- channel: {
127
- text: {
128
- chunkByNewline,
129
- chunkMarkdownText,
130
- chunkMarkdownTextWithMode,
131
- chunkText,
132
- chunkTextWithMode,
133
- resolveChunkMode,
134
- resolveTextChunkLimit,
135
- hasControlCommand,
136
- resolveMarkdownTableMode,
137
- convertMarkdownTables,
138
- },
139
- reply: {
140
- dispatchReplyWithBufferedBlockDispatcher,
141
- createReplyDispatcherWithTyping,
142
- resolveEffectiveMessagesConfig,
143
- resolveHumanDelayConfig,
144
- dispatchReplyFromConfig,
145
- finalizeInboundContext,
146
- formatAgentEnvelope,
147
- formatInboundEnvelope,
148
- resolveEnvelopeFormatOptions,
149
- },
150
- routing: {
151
- resolveAgentRoute,
152
- },
153
- pairing: {
154
- buildPairingReply,
155
- readAllowFromStore: readChannelAllowFromStore,
156
- upsertPairingRequest: upsertChannelPairingRequest,
157
- },
158
- media: {
159
- fetchRemoteMedia,
160
- saveMediaBuffer,
161
- },
162
- activity: {
163
- record: recordChannelActivity,
164
- get: getChannelActivity,
165
- },
166
- session: {
167
- resolveStorePath,
168
- readSessionUpdatedAt,
169
- recordSessionMetaFromInbound,
170
- recordInboundSession,
171
- updateLastRoute,
172
- },
173
- mentions: {
174
- buildMentionRegexes,
175
- matchesMentionPatterns,
176
- matchesMentionWithExplicit,
177
- },
178
- reactions: {
179
- shouldAckReaction,
180
- removeAckReactionAfterReply,
181
- },
182
- groups: {
183
- resolveGroupPolicy: resolveChannelGroupPolicy,
184
- resolveRequireMention: resolveChannelGroupRequireMention,
185
- },
186
- debounce: {
187
- createInboundDebouncer,
188
- resolveInboundDebounceMs,
189
- },
190
- commands: {
191
- resolveCommandAuthorizedFromAuthorizers,
192
- isControlCommandMessage,
193
- shouldComputeCommandAuthorized,
194
- shouldHandleTextCommands,
195
- },
196
- discord: {
197
- messageActions: discordMessageActions,
198
- auditChannelPermissions: auditDiscordChannelPermissions,
199
- listDirectoryGroupsLive: listDiscordDirectoryGroupsLive,
200
- listDirectoryPeersLive: listDiscordDirectoryPeersLive,
201
- probeDiscord,
202
- resolveChannelAllowlist: resolveDiscordChannelAllowlist,
203
- resolveUserAllowlist: resolveDiscordUserAllowlist,
204
- sendMessageDiscord,
205
- sendPollDiscord,
206
- monitorDiscordProvider,
207
- },
208
- slack: {
209
- listDirectoryGroupsLive: listSlackDirectoryGroupsLive,
210
- listDirectoryPeersLive: listSlackDirectoryPeersLive,
211
- probeSlack,
212
- resolveChannelAllowlist: resolveSlackChannelAllowlist,
213
- resolveUserAllowlist: resolveSlackUserAllowlist,
214
- sendMessageSlack,
215
- monitorSlackProvider,
216
- handleSlackAction,
217
- },
218
- telegram: {
219
- auditGroupMembership: auditTelegramGroupMembership,
220
- collectUnmentionedGroupIds: collectTelegramUnmentionedGroupIds,
221
- probeTelegram,
222
- resolveTelegramToken,
223
- sendMessageTelegram,
224
- monitorTelegramProvider,
225
- messageActions: telegramMessageActions,
226
- },
227
- signal: {
228
- probeSignal,
229
- sendMessageSignal,
230
- monitorSignalProvider,
231
- messageActions: signalMessageActions,
232
- },
233
- imessage: {
234
- monitorIMessageProvider,
235
- probeIMessage,
236
- sendMessageIMessage,
237
- },
238
- whatsapp: {
239
- getActiveWebListener,
240
- getWebAuthAgeMs,
241
- logoutWeb,
242
- logWebSelfId,
243
- readWebSelfId,
244
- webAuthExists,
245
- sendMessageWhatsApp,
246
- sendPollWhatsApp,
247
- loginWeb,
248
- startWebLoginWithQr,
249
- waitForWebLogin,
250
- monitorWebChannel,
251
- handleWhatsAppAction,
252
- createLoginTool: createWhatsAppLoginTool,
253
- },
254
- line: {
255
- listLineAccountIds,
256
- resolveDefaultLineAccountId,
257
- resolveLineAccount,
258
- normalizeAccountId: normalizeLineAccountId,
259
- probeLineBot,
260
- sendMessageLine,
261
- pushMessageLine,
262
- pushMessagesLine,
263
- pushFlexMessage,
264
- pushTemplateMessage,
265
- pushLocationMessage,
266
- pushTextMessageWithQuickReplies,
267
- createQuickReplyItems,
268
- buildTemplateMessageFromPayload,
269
- monitorLineProvider,
270
- },
256
+ commands: {
257
+ resolveCommandAuthorizedFromAuthorizers,
258
+ isControlCommandMessage,
259
+ shouldComputeCommandAuthorized,
260
+ shouldHandleTextCommands,
271
261
  },
272
- logging: {
273
- shouldLogVerbose,
274
- getChildLogger: (bindings, opts) => {
275
- const logger = getChildLogger(bindings, {
276
- level: opts?.level ? normalizeLogLevel(opts.level) : undefined,
277
- });
278
- return {
279
- debug: (message) => logger.debug?.(message),
280
- info: (message) => logger.info(message),
281
- warn: (message) => logger.warn(message),
282
- error: (message) => logger.error(message),
283
- };
284
- },
262
+ discord: {
263
+ messageActions: discordMessageActions,
264
+ auditChannelPermissions: auditDiscordChannelPermissions,
265
+ listDirectoryGroupsLive: listDiscordDirectoryGroupsLive,
266
+ listDirectoryPeersLive: listDiscordDirectoryPeersLive,
267
+ probeDiscord,
268
+ resolveChannelAllowlist: resolveDiscordChannelAllowlist,
269
+ resolveUserAllowlist: resolveDiscordUserAllowlist,
270
+ sendMessageDiscord,
271
+ sendPollDiscord,
272
+ monitorDiscordProvider,
285
273
  },
286
- state: {
287
- resolveStateDir,
274
+ slack: {
275
+ listDirectoryGroupsLive: listSlackDirectoryGroupsLive,
276
+ listDirectoryPeersLive: listSlackDirectoryPeersLive,
277
+ probeSlack,
278
+ resolveChannelAllowlist: resolveSlackChannelAllowlist,
279
+ resolveUserAllowlist: resolveSlackUserAllowlist,
280
+ sendMessageSlack,
281
+ monitorSlackProvider,
282
+ handleSlackAction,
283
+ },
284
+ telegram: {
285
+ auditGroupMembership: auditTelegramGroupMembership,
286
+ collectUnmentionedGroupIds: collectTelegramUnmentionedGroupIds,
287
+ probeTelegram,
288
+ resolveTelegramToken,
289
+ sendMessageTelegram,
290
+ sendPollTelegram,
291
+ monitorTelegramProvider,
292
+ messageActions: telegramMessageActions,
293
+ },
294
+ signal: {
295
+ probeSignal,
296
+ sendMessageSignal,
297
+ monitorSignalProvider,
298
+ messageActions: signalMessageActions,
299
+ },
300
+ imessage: {
301
+ monitorIMessageProvider,
302
+ probeIMessage,
303
+ sendMessageIMessage,
304
+ },
305
+ whatsapp: {
306
+ getActiveWebListener,
307
+ getWebAuthAgeMs,
308
+ logoutWeb,
309
+ logWebSelfId,
310
+ readWebSelfId,
311
+ webAuthExists,
312
+ sendMessageWhatsApp: sendMessageWhatsAppLazy,
313
+ sendPollWhatsApp: sendPollWhatsAppLazy,
314
+ loginWeb: loginWebLazy,
315
+ startWebLoginWithQr: startWebLoginWithQrLazy,
316
+ waitForWebLogin: waitForWebLoginLazy,
317
+ monitorWebChannel: monitorWebChannelLazy,
318
+ handleWhatsAppAction: handleWhatsAppActionLazy,
319
+ createLoginTool: createWhatsAppLoginTool,
320
+ },
321
+ line: {
322
+ listLineAccountIds,
323
+ resolveDefaultLineAccountId,
324
+ resolveLineAccount,
325
+ normalizeAccountId: normalizeLineAccountId,
326
+ probeLineBot,
327
+ sendMessageLine,
328
+ pushMessageLine,
329
+ pushMessagesLine,
330
+ pushFlexMessage,
331
+ pushTemplateMessage,
332
+ pushLocationMessage,
333
+ pushTextMessageWithQuickReplies,
334
+ createQuickReplyItems,
335
+ buildTemplateMessageFromPayload,
336
+ monitorLineProvider,
337
+ },
338
+ };
339
+ }
340
+ function createRuntimeLogging() {
341
+ return {
342
+ shouldLogVerbose,
343
+ getChildLogger: (bindings, opts) => {
344
+ const logger = getChildLogger(bindings, {
345
+ level: opts?.level ? normalizeLogLevel(opts.level) : undefined,
346
+ });
347
+ return {
348
+ debug: (message) => logger.debug?.(message),
349
+ info: (message) => logger.info(message),
350
+ warn: (message) => logger.warn(message),
351
+ error: (message) => logger.error(message),
352
+ };
288
353
  },
289
354
  };
290
355
  }
@@ -4,6 +4,8 @@ const DEFAULT_MAX_TOKENS = 8192;
4
4
  // We keep this list intentionally broad; if a model isn't available Copilot will
5
5
  // return an error and users can remove it from their config.
6
6
  const DEFAULT_MODEL_IDS = [
7
+ "claude-sonnet-4.6",
8
+ "claude-sonnet-4.5",
7
9
  "gpt-4o",
8
10
  "gpt-4.1",
9
11
  "gpt-4.1-mini",
@@ -17,8 +19,9 @@ export function getDefaultCopilotModelIds() {
17
19
  }
18
20
  export function buildCopilotModelDefinition(modelId) {
19
21
  const id = modelId.trim();
20
- if (!id)
22
+ if (!id) {
21
23
  throw new Error("Model id required");
24
+ }
22
25
  return {
23
26
  id,
24
27
  name: id,
@@ -3,11 +3,10 @@ import { isNumericTelegramUserId, normalizeTelegramAllowFromEntry, } from "../ch
3
3
  import { formatCliCommand } from "../cli/command-format.js";
4
4
  import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "../config/commands.js";
5
5
  import { readChannelAllowFromStore } from "../pairing/pairing-store.js";
6
+ import { normalizeStringEntries } from "../shared/string-normalization.js";
7
+ import { resolveDmAllowState } from "./dm-policy-shared.js";
6
8
  function normalizeAllowFromList(list) {
7
- if (!Array.isArray(list)) {
8
- return [];
9
- }
10
- return list.map((v) => String(v).trim()).filter(Boolean);
9
+ return normalizeStringEntries(Array.isArray(list) ? list : undefined);
11
10
  }
12
11
  function classifyChannelWarningSeverity(message) {
13
12
  const s = message.toLowerCase();
@@ -40,22 +39,12 @@ export async function collectChannelSecurityFindings(params) {
40
39
  };
41
40
  const warnDmPolicy = async (input) => {
42
41
  const policyPath = input.policyPath ?? `${input.allowFromPath}policy`;
43
- const configAllowFrom = normalizeAllowFromList(input.allowFrom);
44
- const hasWildcard = configAllowFrom.includes("*");
42
+ const { hasWildcard, isMultiUserDm } = await resolveDmAllowState({
43
+ provider: input.provider,
44
+ allowFrom: input.allowFrom,
45
+ normalizeEntry: input.normalizeEntry,
46
+ });
45
47
  const dmScope = params.cfg.session?.dmScope ?? "main";
46
- const storeAllowFrom = await readChannelAllowFromStore(input.provider).catch(() => []);
47
- const normalizeEntry = input.normalizeEntry ?? ((value) => value);
48
- const normalizedCfg = configAllowFrom
49
- .filter((value) => value !== "*")
50
- .map((value) => normalizeEntry(value))
51
- .map((value) => value.trim())
52
- .filter(Boolean);
53
- const normalizedStore = storeAllowFrom
54
- .map((value) => normalizeEntry(value))
55
- .map((value) => value.trim())
56
- .filter(Boolean);
57
- const allowCount = Array.from(new Set([...normalizedCfg, ...normalizedStore])).length;
58
- const isMultiUserDm = hasWildcard || allowCount > 1;
59
48
  if (input.dmPolicy === "open") {
60
49
  const allowFromKey = `${input.allowFromPath}allowFrom`;
61
50
  findings.push({