@poolzin/pool-bot 2026.3.25 → 2026.3.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 (271) hide show
  1. package/dist/agents/model-fallback.js +5 -4
  2. package/dist/agents/tools/common.js +16 -201
  3. package/dist/auto-reply/auto-reply/reply/agent-runner-execution.js +502 -0
  4. package/dist/auto-reply/auto-reply/reply/agent-runner-helpers.js +65 -0
  5. package/dist/auto-reply/auto-reply/reply/agent-runner-memory.js +160 -0
  6. package/dist/auto-reply/auto-reply/reply/agent-runner-payloads.js +85 -0
  7. package/dist/auto-reply/auto-reply/reply/agent-runner-utils.js +101 -0
  8. package/dist/auto-reply/auto-reply/reply/bash-command.js +338 -0
  9. package/dist/auto-reply/auto-reply/reply/block-streaming.js +91 -0
  10. package/dist/auto-reply/auto-reply/reply/commands-approve.js +88 -0
  11. package/dist/auto-reply/auto-reply/reply/commands-bash.js +26 -0
  12. package/dist/auto-reply/auto-reply/reply/commands-compact.js +107 -0
  13. package/dist/auto-reply/auto-reply/reply/commands-config.js +241 -0
  14. package/dist/auto-reply/auto-reply/reply/commands-context-report.js +295 -0
  15. package/dist/auto-reply/auto-reply/reply/commands-context.js +30 -0
  16. package/dist/auto-reply/auto-reply/reply/commands-core.js +151 -0
  17. package/dist/auto-reply/auto-reply/reply/commands-export-session.js +163 -0
  18. package/dist/auto-reply/auto-reply/reply/commands-info.js +184 -0
  19. package/dist/auto-reply/auto-reply/reply/commands-models.js +299 -0
  20. package/dist/auto-reply/auto-reply/reply/commands-plugin.js +35 -0
  21. package/dist/auto-reply/auto-reply/reply/commands-ptt.js +171 -0
  22. package/dist/auto-reply/auto-reply/reply/commands-setunset-standard.js +13 -0
  23. package/dist/auto-reply/auto-reply/reply/commands-setunset.js +73 -0
  24. package/dist/auto-reply/auto-reply/reply/commands-slash-parse.js +31 -0
  25. package/dist/auto-reply/auto-reply/reply/commands-status.js +178 -0
  26. package/dist/auto-reply/auto-reply/reply/commands-subagents.js +73 -0
  27. package/dist/auto-reply/auto-reply/reply/commands-system-prompt.js +117 -0
  28. package/dist/auto-reply/auto-reply/reply/commands-tts.js +231 -0
  29. package/dist/auto-reply/auto-reply/reply/directive-handling.impl.js +380 -0
  30. package/dist/auto-reply/auto-reply/reply/followup-runner.js +227 -0
  31. package/dist/auto-reply/auto-reply/reply/get-reply-directives-apply.js +201 -0
  32. package/dist/auto-reply/auto-reply/reply/get-reply-directives-utils.js +54 -0
  33. package/dist/auto-reply/auto-reply/reply/get-reply-directives.js +332 -0
  34. package/dist/auto-reply/auto-reply/reply/get-reply-inline-actions.js +258 -0
  35. package/dist/auto-reply/auto-reply/reply/get-reply-run.js +297 -0
  36. package/dist/auto-reply/auto-reply/reply/groups.js +102 -0
  37. package/dist/auto-reply/auto-reply/reply/mentions.js +129 -0
  38. package/dist/auto-reply/auto-reply/reply/reply-delivery.js +92 -0
  39. package/dist/auto-reply/auto-reply/reply/reply-directives.js +30 -0
  40. package/dist/auto-reply/auto-reply/reply/reply-dispatcher.js +152 -0
  41. package/dist/auto-reply/auto-reply/reply/reply-elevated.js +166 -0
  42. package/dist/auto-reply/auto-reply/reply/reply-inline.js +28 -0
  43. package/dist/auto-reply/auto-reply/reply/reply-payloads.js +114 -0
  44. package/dist/auto-reply/auto-reply/reply/reply-reference.js +36 -0
  45. package/dist/auto-reply/auto-reply/reply/reply-tags.js +13 -0
  46. package/dist/auto-reply/auto-reply/reply/reply-threading.js +41 -0
  47. package/dist/auto-reply/auto-reply/reply/session-updates.js +233 -0
  48. package/dist/auto-reply/auto-reply/reply/stage-sandbox-media.js +146 -0
  49. package/dist/build-info.json +3 -3
  50. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  51. package/dist/canvas-host/a2ui/a2ui.bundle.js +2 -17772
  52. package/dist/canvas-host/a2ui/index.html +1 -307
  53. package/dist/channels/channels/directory-config.js +185 -0
  54. package/dist/channels/channels/discord/handle-action.guild-admin.js +332 -0
  55. package/dist/channels/channels/discord/handle-action.js +165 -0
  56. package/dist/channels/channels/discord.js +413 -0
  57. package/dist/channels/channels/dock.js +436 -0
  58. package/dist/channels/channels/index.js +51 -0
  59. package/dist/channels/channels/plugins/outbound/discord.js +101 -0
  60. package/dist/channels/channels/whatsapp.js +17 -0
  61. package/dist/channels/plugins/types.js +1 -1
  62. package/dist/channels/run-state-machine.js +7 -0
  63. package/dist/commands/models/auth.js +47 -1
  64. package/dist/commands-subagents/action-agents.js +44 -0
  65. package/dist/commands-subagents/action-focus.js +64 -0
  66. package/dist/commands-subagents/action-help.js +4 -0
  67. package/dist/commands-subagents/action-info.js +45 -0
  68. package/dist/commands-subagents/action-kill.js +60 -0
  69. package/dist/commands-subagents/action-list.js +44 -0
  70. package/dist/commands-subagents/action-log.js +29 -0
  71. package/dist/commands-subagents/action-send.js +119 -0
  72. package/dist/commands-subagents/action-spawn.js +52 -0
  73. package/dist/commands-subagents/action-unfocus.js +30 -0
  74. package/dist/commands-subagents/shared.js +303 -0
  75. package/dist/config/config.js +1 -8
  76. package/dist/config/types.secrets.js +61 -0
  77. package/dist/control-ui/assets/{index-D7shnQwQ.js → index-umCsvrWy.js} +884 -741
  78. package/dist/control-ui/assets/index-umCsvrWy.js.map +1 -0
  79. package/dist/control-ui/assets/pt-BR-DedEVAvY.js +2 -0
  80. package/dist/control-ui/assets/pt-BR-DedEVAvY.js.map +1 -0
  81. package/dist/control-ui/assets/zh-CN-CDzeklK-.js +2 -0
  82. package/dist/control-ui/assets/zh-CN-CDzeklK-.js.map +1 -0
  83. package/dist/control-ui/assets/zh-TW-BJCRYNWH.js +2 -0
  84. package/dist/control-ui/assets/zh-TW-BJCRYNWH.js.map +1 -0
  85. package/dist/control-ui/index.html +1 -1
  86. package/dist/gateway/method-scopes.js +9 -1
  87. package/dist/gateway/node-pending-work.js +142 -0
  88. package/dist/gateway/protocol/index.js +5 -1
  89. package/dist/gateway/protocol/schema/nodes.js +18 -0
  90. package/dist/gateway/server-methods/nodes-pending.js +96 -0
  91. package/dist/gateway/server-methods-list.js +4 -0
  92. package/dist/gateway/server-methods.js +2 -0
  93. package/dist/imessage/channel.js +253 -0
  94. package/dist/imessage/monitor/echo-cache.js +70 -0
  95. package/dist/imessage/monitor/loop-rate-limiter.js +51 -0
  96. package/dist/imessage/monitor/reflection-guard.js +50 -0
  97. package/dist/imessage/monitor/sanitize-outbound.js +25 -0
  98. package/dist/imessage/monitor/self-chat-cache.js +75 -0
  99. package/dist/imessage/runtime.js +3 -0
  100. package/dist/infra/exec-approval-reply.js +7 -0
  101. package/dist/infra/tmp-openclaw-dir.js +84 -0
  102. package/dist/pairing/pairing-challenge.js +15 -0
  103. package/dist/plugin-sdk/account-id.d.ts +1 -0
  104. package/dist/plugin-sdk/agent-media-payload.d.ts +12 -0
  105. package/dist/plugin-sdk/allow-from.d.ts +27 -0
  106. package/dist/plugin-sdk/command-auth.d.ts +25 -0
  107. package/dist/plugin-sdk/command-auth.js +3 -1
  108. package/dist/plugin-sdk/config-paths.d.ts +6 -0
  109. package/dist/plugin-sdk/file-lock.d.ts +16 -0
  110. package/dist/plugin-sdk/index.d.ts +428 -0
  111. package/dist/plugin-sdk/index.js +237 -103
  112. package/dist/plugin-sdk/json-store.d.ts +5 -0
  113. package/dist/plugin-sdk/keyed-async-queue.d.ts +12 -0
  114. package/dist/plugin-sdk/onboarding.d.ts +11 -0
  115. package/dist/plugin-sdk/provider-auth-result.d.ts +14 -0
  116. package/dist/plugin-sdk/slack-message-actions.d.ts +11 -0
  117. package/dist/plugin-sdk/status-helpers.d.ts +25 -0
  118. package/dist/plugin-sdk/temp-path.d.ts +12 -0
  119. package/dist/plugin-sdk/text-chunking.d.ts +1 -0
  120. package/dist/plugin-sdk/tool-send.d.ts +4 -0
  121. package/dist/plugin-sdk/webhook-path.d.ts +6 -0
  122. package/dist/plugin-sdk/webhook-targets.d.ts +23 -0
  123. package/dist/plugin-sdk/windows-spawn.d.ts +39 -0
  124. package/dist/plugin-sdk-internal/accounts.js +6 -0
  125. package/dist/plugin-sdk-internal/discord.js +23 -0
  126. package/dist/plugin-sdk-internal/imessage.js +13 -0
  127. package/dist/plugin-sdk-internal/setup.js +9 -0
  128. package/dist/plugin-sdk-internal/signal.js +13 -0
  129. package/dist/plugin-sdk-internal/slack.js +22 -0
  130. package/dist/plugin-sdk-internal/telegram.js +32 -0
  131. package/dist/plugin-sdk-internal/whatsapp.js +29 -0
  132. package/dist/routing/session-key.js +4 -185
  133. package/dist/shared/pid-alive.js +2 -61
  134. package/dist/shared/process-scoped-map.js +5 -7
  135. package/dist/signal/channel.js +264 -0
  136. package/dist/signal/monitor/access-policy.js +60 -0
  137. package/dist/signal/runtime.js +3 -0
  138. package/dist/slack/account-inspect.js +135 -0
  139. package/dist/slack/blocks-input.js +7 -38
  140. package/dist/slack/channel.js +394 -0
  141. package/dist/slack/interactive-replies.js +28 -0
  142. package/dist/slack/monitor/channel-type.js +31 -0
  143. package/dist/slack/monitor/dm-auth.js +49 -0
  144. package/dist/slack/monitor/events/interactions.modal.js +137 -0
  145. package/dist/slack/monitor/events/message-subtype-handlers.js +68 -0
  146. package/dist/slack/monitor/events/system-event-context.js +29 -0
  147. package/dist/slack/monitor/events/system-event-test-harness.js +41 -0
  148. package/dist/slack/monitor/external-arg-menu-store.js +46 -0
  149. package/dist/slack/monitor/message-handler/prepare-content.js +69 -0
  150. package/dist/slack/monitor/message-handler/prepare-thread-context.js +91 -0
  151. package/dist/slack/monitor/message-handler/prepare.test-helpers.js +55 -0
  152. package/dist/slack/monitor/reconnect-policy.js +78 -0
  153. package/dist/slack/monitor/slash-commands.runtime.js +1 -0
  154. package/dist/slack/monitor/slash-dispatch.runtime.js +9 -0
  155. package/dist/slack/monitor/slash-skill-commands.runtime.js +1 -0
  156. package/dist/slack/resolve-allowlist-common.js +36 -0
  157. package/dist/slack/runtime.js +3 -0
  158. package/dist/slack/sent-thread-cache.js +61 -0
  159. package/dist/slack/truncate.js +10 -0
  160. package/dist/telegram/account-inspect.js +175 -0
  161. package/dist/telegram/allow-from.js +10 -0
  162. package/dist/telegram/api-fetch.js +18 -0
  163. package/dist/telegram/approval-buttons.js +30 -0
  164. package/dist/telegram/audit-membership-runtime.js +61 -0
  165. package/dist/telegram/bot/delivery.replies.js +508 -0
  166. package/dist/telegram/bot/delivery.resolve-media.js +227 -0
  167. package/dist/telegram/bot/delivery.send.js +132 -0
  168. package/dist/telegram/bot/reply-threading.js +46 -0
  169. package/dist/telegram/bot-message-context.body.js +186 -0
  170. package/dist/telegram/bot-message-context.session.js +207 -0
  171. package/dist/telegram/bot-message-context.types.js +1 -0
  172. package/dist/telegram/bot-native-commands.test-helpers.js +117 -0
  173. package/dist/telegram/bot.media.e2e-harness.js +81 -0
  174. package/dist/telegram/bot.media.test-utils.js +81 -0
  175. package/dist/telegram/channel-actions.js +225 -0
  176. package/dist/telegram/channel.js +515 -0
  177. package/dist/telegram/conversation-route.js +107 -0
  178. package/dist/telegram/delivery.js +2 -0
  179. package/dist/telegram/delivery.replies.js +508 -0
  180. package/dist/telegram/dm-access.js +86 -0
  181. package/dist/telegram/draft-stream.test-helpers.js +62 -0
  182. package/dist/telegram/exec-approvals-handler.js +281 -0
  183. package/dist/telegram/exec-approvals.js +62 -0
  184. package/dist/telegram/forum-service-message.js +22 -0
  185. package/dist/telegram/group-config-helpers.js +10 -0
  186. package/dist/telegram/lane-delivery-state.js +19 -0
  187. package/dist/telegram/lane-delivery-text-deliverer.js +357 -0
  188. package/dist/telegram/lane-delivery.js +2 -0
  189. package/dist/telegram/normalize.js +37 -0
  190. package/dist/telegram/onboarding.js +192 -0
  191. package/dist/telegram/outbound-adapter.js +100 -0
  192. package/dist/telegram/polling-session.js +275 -0
  193. package/dist/telegram/runtime.js +3 -0
  194. package/dist/telegram/sendchataction-401-backoff.js +71 -0
  195. package/dist/telegram/sequential-key.js +46 -0
  196. package/dist/telegram/status-issues.js +105 -0
  197. package/dist/telegram/target-writeback.js +165 -0
  198. package/dist/telegram/thread-bindings.js +560 -0
  199. package/dist/utils.js +10 -276
  200. package/dist/wizard/prompts.js +5 -5
  201. package/extensions/feishu/src/policy.ts +1 -1
  202. package/extensions/firecrawl/index.test.ts +82 -0
  203. package/extensions/firecrawl/index.ts +20 -0
  204. package/extensions/firecrawl/openclaw.plugin.json +8 -0
  205. package/extensions/firecrawl/package.json +12 -0
  206. package/extensions/firecrawl/src/config.ts +159 -0
  207. package/extensions/firecrawl/src/firecrawl-client.ts +446 -0
  208. package/extensions/firecrawl/src/firecrawl-scrape-tool.ts +89 -0
  209. package/extensions/firecrawl/src/firecrawl-search-provider.ts +63 -0
  210. package/extensions/firecrawl/src/firecrawl-search-tool.ts +76 -0
  211. package/package.json +1 -1
  212. package/dist/.buildstamp +0 -1
  213. package/dist/acp/bindings-store.js +0 -209
  214. package/dist/acp/control-plane/runtime-cache.js +0 -54
  215. package/dist/acp/control-plane/runtime-options.js +0 -215
  216. package/dist/acp/control-plane/session-actor-queue.js +0 -36
  217. package/dist/acp/index.js +0 -2
  218. package/dist/acp/runtime/errors.js +0 -47
  219. package/dist/acp/runtime/registry.js +0 -86
  220. package/dist/acp/secret-file.js +0 -22
  221. package/dist/agents/auth-profiles.resolve-auth-profile-order.fixtures.js +0 -23
  222. package/dist/agents/bash-process-registry.test-helpers.js +0 -29
  223. package/dist/agents/bash-tools.exec-approval-request.js +0 -20
  224. package/dist/agents/bash-tools.exec-host-gateway.js +0 -240
  225. package/dist/agents/bash-tools.exec-host-node.js +0 -235
  226. package/dist/agents/checkpoint-manager.js +0 -290
  227. package/dist/agents/claude-cli-runner.js +0 -3
  228. package/dist/agents/error-classifier.js +0 -251
  229. package/dist/agents/live-model-filter.js +0 -84
  230. package/dist/agents/nvidia-models.js +0 -228
  231. package/dist/agents/pi-embedded-runner/run.overflow-compaction.fixture.js +0 -34
  232. package/dist/agents/pi-embedded-runner/run.overflow-compaction.mocks.shared.js +0 -156
  233. package/dist/agents/pi-embedded-subscribe.handlers.tools.media.test-helpers.js +0 -30
  234. package/dist/agents/provider/config-loader.js +0 -76
  235. package/dist/agents/provider/index.js +0 -15
  236. package/dist/agents/provider/models-dev.js +0 -129
  237. package/dist/agents/provider/session-binding.js +0 -376
  238. package/dist/agents/queued-file-writer.js +0 -22
  239. package/dist/agents/skills/bundled-context.js +0 -23
  240. package/dist/agents/skills/security.js +0 -211
  241. package/dist/agents/skills/tools-dir.js +0 -9
  242. package/dist/agents/skills-install-download.js +0 -290
  243. package/dist/agents/skills-install-output.js +0 -30
  244. package/dist/agents/skills-install.download-test-utils.js +0 -36
  245. package/dist/agents/skills.test-helpers.js +0 -13
  246. package/dist/agents/subagent-announce-reliability.js +0 -160
  247. package/dist/agents/subagent-registry.mocks.shared.js +0 -12
  248. package/dist/agents/test-helpers/assistant-message-fixtures.js +0 -29
  249. package/dist/agents/test-helpers/fast-coding-tools.js +0 -1
  250. package/dist/agents/test-helpers/fast-core-tools.js +0 -8
  251. package/dist/agents/test-helpers/fast-tool-stubs.js +0 -18
  252. package/dist/agents/test-helpers/host-sandbox-fs-bridge.js +0 -74
  253. package/dist/agents/test-helpers/pi-tools-sandbox-context.js +0 -27
  254. package/dist/agents/tool-display-common.js +0 -915
  255. package/dist/agents/tool-policy-shared.js +0 -108
  256. package/dist/agents/tool-policy.conformance.js +0 -14
  257. package/dist/agents/tool-result-truncation.js +0 -299
  258. package/dist/agents/tools/cron-tool.test-helpers.js +0 -12
  259. package/dist/agents/tools/discord-actions-moderation-shared.js +0 -27
  260. package/dist/agents/tools/discord-actions-presence.js +0 -78
  261. package/dist/control-ui/assets/index-D7shnQwQ.js.map +0 -1
  262. package/dist/discord/discord-improvements.js +0 -167
  263. package/dist/discord/index.js +0 -2
  264. package/dist/hooks/bundled/boot-md/HOOK.md +0 -19
  265. package/dist/hooks/bundled/command-logger/HOOK.md +0 -122
  266. package/dist/hooks/bundled/session-memory/HOOK.md +0 -86
  267. package/dist/hooks/bundled/soul-evil/HOOK.md +0 -71
  268. package/dist/whatsapp/normalize.js +0 -66
  269. package/dist/whatsapp/resolve-outbound-target.js +0 -42
  270. /package/dist/{acp/runtime/types.js → auto-reply/auto-reply/reply/commands-types.js} +0 -0
  271. /package/dist/{agents/pi-embedded-payloads.js → slack/account-surface-fields.js} +0 -0
@@ -0,0 +1,332 @@
1
+ import { resolveSandboxRuntimeStatus } from "../../agents/sandbox.js";
2
+ import { listChatCommands, shouldHandleTextCommands } from "../commands-registry.js";
3
+ import { listSkillCommandsForWorkspace } from "../skill-commands.js";
4
+ import { resolveBlockStreamingChunking } from "./block-streaming.js";
5
+ import { buildCommandContext } from "./commands.js";
6
+ import { parseInlineDirectives } from "./directive-handling.js";
7
+ import { applyInlineDirectiveOverrides } from "./get-reply-directives-apply.js";
8
+ import { clearExecInlineDirectives, clearInlineDirectives } from "./get-reply-directives-utils.js";
9
+ import { defaultGroupActivation, resolveGroupRequireMention } from "./groups.js";
10
+ import { CURRENT_MESSAGE_MARKER, stripMentions, stripStructuralPrefixes } from "./mentions.js";
11
+ import { createModelSelectionState, resolveContextTokens } from "./model-selection.js";
12
+ import { formatElevatedUnavailableMessage, resolveElevatedPermissions } from "./reply-elevated.js";
13
+ import { stripInlineStatus } from "./reply-inline.js";
14
+ function resolveExecOverrides(params) {
15
+ const host = params.directives.execHost ?? params.sessionEntry?.execHost;
16
+ const security = params.directives.execSecurity ??
17
+ params.sessionEntry?.execSecurity;
18
+ const ask = params.directives.execAsk ?? params.sessionEntry?.execAsk;
19
+ const node = params.directives.execNode ?? params.sessionEntry?.execNode;
20
+ if (!host && !security && !ask && !node) {
21
+ return undefined;
22
+ }
23
+ return { host, security, ask, node };
24
+ }
25
+ export async function resolveReplyDirectives(params) {
26
+ const { ctx, cfg, agentId, agentCfg, agentDir, workspaceDir, sessionCtx, sessionEntry, sessionStore, sessionKey, storePath, sessionScope, groupResolution, isGroup, triggerBodyNormalized, commandAuthorized, defaultProvider, defaultModel, provider: initialProvider, model: initialModel, hasResolvedHeartbeatModelOverride, typing, opts, skillFilter, } = params;
27
+ let provider = initialProvider;
28
+ let model = initialModel;
29
+ // Prefer CommandBody/RawBody (clean message without structural context) for directive parsing.
30
+ // Keep `Body`/`BodyStripped` as the best-available prompt text (may include context).
31
+ const commandSource = sessionCtx.BodyForCommands ??
32
+ sessionCtx.CommandBody ??
33
+ sessionCtx.RawBody ??
34
+ sessionCtx.Transcript ??
35
+ sessionCtx.BodyStripped ??
36
+ sessionCtx.Body ??
37
+ ctx.BodyForCommands ??
38
+ ctx.CommandBody ??
39
+ ctx.RawBody ??
40
+ "";
41
+ const promptSource = sessionCtx.BodyForAgent ?? sessionCtx.BodyStripped ?? sessionCtx.Body ?? "";
42
+ const commandText = commandSource || promptSource;
43
+ const command = buildCommandContext({
44
+ ctx,
45
+ cfg,
46
+ agentId,
47
+ sessionKey,
48
+ isGroup,
49
+ triggerBodyNormalized,
50
+ commandAuthorized,
51
+ });
52
+ const allowTextCommands = shouldHandleTextCommands({
53
+ cfg,
54
+ surface: command.surface,
55
+ commandSource: ctx.CommandSource,
56
+ });
57
+ const reservedCommands = new Set(listChatCommands().flatMap((cmd) => cmd.textAliases.map((a) => a.replace(/^\//, "").toLowerCase())));
58
+ const rawAliases = Object.values(cfg.agents?.defaults?.models ?? {})
59
+ .map((entry) => entry.alias?.trim())
60
+ .filter((alias) => Boolean(alias))
61
+ .filter((alias) => !reservedCommands.has(alias.toLowerCase()));
62
+ // Only load workspace skill commands when we actually need them to filter aliases.
63
+ // This avoids scanning skills for messages that only use inline directives like /think:/verbose:.
64
+ const skillCommands = allowTextCommands && rawAliases.length > 0
65
+ ? listSkillCommandsForWorkspace({
66
+ workspaceDir,
67
+ cfg,
68
+ skillFilter,
69
+ })
70
+ : [];
71
+ for (const command of skillCommands) {
72
+ reservedCommands.add(command.name.toLowerCase());
73
+ }
74
+ const configuredAliases = rawAliases.filter((alias) => !reservedCommands.has(alias.toLowerCase()));
75
+ const allowStatusDirective = allowTextCommands && command.isAuthorizedSender;
76
+ let parsedDirectives = parseInlineDirectives(commandText, {
77
+ modelAliases: configuredAliases,
78
+ allowStatusDirective,
79
+ });
80
+ const hasInlineStatus = parsedDirectives.hasStatusDirective && parsedDirectives.cleaned.trim().length > 0;
81
+ if (hasInlineStatus) {
82
+ parsedDirectives = {
83
+ ...parsedDirectives,
84
+ hasStatusDirective: false,
85
+ };
86
+ }
87
+ if (isGroup && ctx.WasMentioned !== true && parsedDirectives.hasElevatedDirective) {
88
+ if (parsedDirectives.elevatedLevel !== "off") {
89
+ parsedDirectives = {
90
+ ...parsedDirectives,
91
+ hasElevatedDirective: false,
92
+ elevatedLevel: undefined,
93
+ rawElevatedLevel: undefined,
94
+ };
95
+ }
96
+ }
97
+ if (isGroup && ctx.WasMentioned !== true && parsedDirectives.hasExecDirective) {
98
+ if (parsedDirectives.execSecurity !== "deny") {
99
+ parsedDirectives = clearExecInlineDirectives(parsedDirectives);
100
+ }
101
+ }
102
+ const hasInlineDirective = parsedDirectives.hasThinkDirective ||
103
+ parsedDirectives.hasVerboseDirective ||
104
+ parsedDirectives.hasReasoningDirective ||
105
+ parsedDirectives.hasElevatedDirective ||
106
+ parsedDirectives.hasExecDirective ||
107
+ parsedDirectives.hasModelDirective ||
108
+ parsedDirectives.hasQueueDirective;
109
+ if (hasInlineDirective) {
110
+ const stripped = stripStructuralPrefixes(parsedDirectives.cleaned);
111
+ const noMentions = isGroup ? stripMentions(stripped, ctx, cfg, agentId) : stripped;
112
+ if (noMentions.trim().length > 0) {
113
+ const directiveOnlyCheck = parseInlineDirectives(noMentions, {
114
+ modelAliases: configuredAliases,
115
+ });
116
+ if (directiveOnlyCheck.cleaned.trim().length > 0) {
117
+ const allowInlineStatus = parsedDirectives.hasStatusDirective && allowTextCommands && command.isAuthorizedSender;
118
+ parsedDirectives = allowInlineStatus
119
+ ? {
120
+ ...clearInlineDirectives(parsedDirectives.cleaned),
121
+ hasStatusDirective: true,
122
+ }
123
+ : clearInlineDirectives(parsedDirectives.cleaned);
124
+ }
125
+ }
126
+ }
127
+ let directives = commandAuthorized
128
+ ? parsedDirectives
129
+ : {
130
+ ...parsedDirectives,
131
+ hasThinkDirective: false,
132
+ hasVerboseDirective: false,
133
+ hasReasoningDirective: false,
134
+ hasStatusDirective: false,
135
+ hasModelDirective: false,
136
+ hasQueueDirective: false,
137
+ queueReset: false,
138
+ };
139
+ const existingBody = sessionCtx.BodyStripped ?? sessionCtx.Body ?? "";
140
+ let cleanedBody = (() => {
141
+ if (!existingBody) {
142
+ return parsedDirectives.cleaned;
143
+ }
144
+ if (!sessionCtx.CommandBody && !sessionCtx.RawBody) {
145
+ return parseInlineDirectives(existingBody, {
146
+ modelAliases: configuredAliases,
147
+ allowStatusDirective,
148
+ }).cleaned;
149
+ }
150
+ const markerIndex = existingBody.indexOf(CURRENT_MESSAGE_MARKER);
151
+ if (markerIndex < 0) {
152
+ return parseInlineDirectives(existingBody, {
153
+ modelAliases: configuredAliases,
154
+ allowStatusDirective,
155
+ }).cleaned;
156
+ }
157
+ const head = existingBody.slice(0, markerIndex + CURRENT_MESSAGE_MARKER.length);
158
+ const tail = existingBody.slice(markerIndex + CURRENT_MESSAGE_MARKER.length);
159
+ const cleanedTail = parseInlineDirectives(tail, {
160
+ modelAliases: configuredAliases,
161
+ allowStatusDirective,
162
+ }).cleaned;
163
+ return `${head}${cleanedTail}`;
164
+ })();
165
+ if (allowStatusDirective) {
166
+ cleanedBody = stripInlineStatus(cleanedBody).cleaned;
167
+ }
168
+ sessionCtx.BodyForAgent = cleanedBody;
169
+ sessionCtx.Body = cleanedBody;
170
+ sessionCtx.BodyStripped = cleanedBody;
171
+ const messageProviderKey = sessionCtx.Provider?.trim().toLowerCase() ?? ctx.Provider?.trim().toLowerCase() ?? "";
172
+ const elevated = resolveElevatedPermissions({
173
+ cfg,
174
+ agentId,
175
+ ctx,
176
+ provider: messageProviderKey,
177
+ });
178
+ const elevatedEnabled = elevated.enabled;
179
+ const elevatedAllowed = elevated.allowed;
180
+ const elevatedFailures = elevated.failures;
181
+ if (directives.hasElevatedDirective && (!elevatedEnabled || !elevatedAllowed)) {
182
+ typing.cleanup();
183
+ const runtimeSandboxed = resolveSandboxRuntimeStatus({
184
+ cfg,
185
+ sessionKey: ctx.SessionKey,
186
+ }).sandboxed;
187
+ return {
188
+ kind: "reply",
189
+ reply: {
190
+ text: formatElevatedUnavailableMessage({
191
+ runtimeSandboxed,
192
+ failures: elevatedFailures,
193
+ sessionKey: ctx.SessionKey,
194
+ }),
195
+ },
196
+ };
197
+ }
198
+ const requireMention = resolveGroupRequireMention({
199
+ cfg,
200
+ ctx: sessionCtx,
201
+ groupResolution,
202
+ });
203
+ const defaultActivation = defaultGroupActivation(requireMention);
204
+ const resolvedThinkLevel = directives.thinkLevel ??
205
+ sessionEntry?.thinkingLevel ??
206
+ agentCfg?.thinkingDefault;
207
+ const resolvedVerboseLevel = directives.verboseLevel ??
208
+ sessionEntry?.verboseLevel ??
209
+ agentCfg?.verboseDefault;
210
+ const resolvedReasoningLevel = directives.reasoningLevel ??
211
+ sessionEntry?.reasoningLevel ??
212
+ "off";
213
+ const resolvedElevatedLevel = elevatedAllowed
214
+ ? (directives.elevatedLevel ??
215
+ sessionEntry?.elevatedLevel ??
216
+ agentCfg?.elevatedDefault ??
217
+ "on")
218
+ : "off";
219
+ const resolvedBlockStreaming = opts?.disableBlockStreaming === true
220
+ ? "off"
221
+ : opts?.disableBlockStreaming === false
222
+ ? "on"
223
+ : agentCfg?.blockStreamingDefault === "on"
224
+ ? "on"
225
+ : "off";
226
+ const resolvedBlockStreamingBreak = agentCfg?.blockStreamingBreak === "message_end" ? "message_end" : "text_end";
227
+ const blockStreamingEnabled = resolvedBlockStreaming === "on" && opts?.disableBlockStreaming !== true;
228
+ const blockReplyChunking = blockStreamingEnabled
229
+ ? resolveBlockStreamingChunking(cfg, sessionCtx.Provider, sessionCtx.AccountId)
230
+ : undefined;
231
+ const modelState = await createModelSelectionState({
232
+ cfg,
233
+ agentCfg,
234
+ sessionEntry,
235
+ sessionStore,
236
+ sessionKey,
237
+ parentSessionKey: ctx.ParentSessionKey,
238
+ storePath,
239
+ defaultProvider,
240
+ defaultModel,
241
+ provider,
242
+ model,
243
+ hasModelDirective: directives.hasModelDirective,
244
+ hasResolvedHeartbeatModelOverride,
245
+ });
246
+ provider = modelState.provider;
247
+ model = modelState.model;
248
+ let contextTokens = resolveContextTokens({
249
+ agentCfg,
250
+ model,
251
+ });
252
+ const initialModelLabel = `${provider}/${model}`;
253
+ const formatModelSwitchEvent = (label, alias) => alias ? `Model switched to ${alias} (${label}).` : `Model switched to ${label}.`;
254
+ const isModelListAlias = directives.hasModelDirective &&
255
+ ["status", "list"].includes(directives.rawModelDirective?.trim().toLowerCase() ?? "");
256
+ const effectiveModelDirective = isModelListAlias ? undefined : directives.rawModelDirective;
257
+ const inlineStatusRequested = hasInlineStatus && allowTextCommands && command.isAuthorizedSender;
258
+ const applyResult = await applyInlineDirectiveOverrides({
259
+ ctx,
260
+ cfg,
261
+ agentId,
262
+ agentDir,
263
+ agentCfg,
264
+ sessionEntry,
265
+ sessionStore,
266
+ sessionKey,
267
+ storePath,
268
+ sessionScope,
269
+ isGroup,
270
+ allowTextCommands,
271
+ command,
272
+ directives,
273
+ messageProviderKey,
274
+ elevatedEnabled,
275
+ elevatedAllowed,
276
+ elevatedFailures,
277
+ defaultProvider,
278
+ defaultModel,
279
+ aliasIndex: params.aliasIndex,
280
+ provider,
281
+ model,
282
+ modelState,
283
+ initialModelLabel,
284
+ formatModelSwitchEvent,
285
+ resolvedElevatedLevel,
286
+ defaultActivation: () => defaultActivation,
287
+ contextTokens,
288
+ effectiveModelDirective,
289
+ typing,
290
+ });
291
+ if (applyResult.kind === "reply") {
292
+ return { kind: "reply", reply: applyResult.reply };
293
+ }
294
+ directives = applyResult.directives;
295
+ provider = applyResult.provider;
296
+ model = applyResult.model;
297
+ contextTokens = applyResult.contextTokens;
298
+ const { directiveAck, perMessageQueueMode, perMessageQueueOptions } = applyResult;
299
+ const execOverrides = resolveExecOverrides({ directives, sessionEntry });
300
+ return {
301
+ kind: "continue",
302
+ result: {
303
+ commandSource: commandText,
304
+ command,
305
+ allowTextCommands,
306
+ skillCommands,
307
+ directives,
308
+ cleanedBody,
309
+ messageProviderKey,
310
+ elevatedEnabled,
311
+ elevatedAllowed,
312
+ elevatedFailures,
313
+ defaultActivation,
314
+ resolvedThinkLevel,
315
+ resolvedVerboseLevel,
316
+ resolvedReasoningLevel,
317
+ resolvedElevatedLevel,
318
+ execOverrides,
319
+ blockStreamingEnabled,
320
+ blockReplyChunking,
321
+ resolvedBlockStreamingBreak,
322
+ provider,
323
+ model,
324
+ modelState,
325
+ contextTokens,
326
+ inlineStatusRequested,
327
+ directiveAck,
328
+ perMessageQueueMode,
329
+ perMessageQueueOptions,
330
+ },
331
+ };
332
+ }
@@ -0,0 +1,258 @@
1
+ import { getChannelDock } from "../../channels/dock.js";
2
+ import { getAbortMemory } from "./abort.js";
3
+ import { buildStatusReply, handleCommands } from "./commands.js";
4
+ import { isDirectiveOnly } from "./directive-handling.js";
5
+ import { extractInlineSimpleCommand } from "./reply-inline.js";
6
+ import { listSkillCommandsForWorkspace, resolveSkillCommandInvocation } from "../skill-commands.js";
7
+ import { logVerbose } from "../../globals.js";
8
+ import { createPoolBotTools } from "../../agents/poolbot-tools.js";
9
+ import { resolveGatewayMessageChannel } from "../../utils/message-channel.js";
10
+ function extractTextFromToolResult(result) {
11
+ if (!result || typeof result !== "object")
12
+ return null;
13
+ const content = result.content;
14
+ if (typeof content === "string") {
15
+ const trimmed = content.trim();
16
+ return trimmed ? trimmed : null;
17
+ }
18
+ if (!Array.isArray(content))
19
+ return null;
20
+ const parts = [];
21
+ for (const block of content) {
22
+ if (!block || typeof block !== "object")
23
+ continue;
24
+ const rec = block;
25
+ if (rec.type === "text" && typeof rec.text === "string") {
26
+ parts.push(rec.text);
27
+ }
28
+ }
29
+ const out = parts.join("");
30
+ const trimmed = out.trim();
31
+ return trimmed ? trimmed : null;
32
+ }
33
+ export async function handleInlineActions(params) {
34
+ const { ctx, sessionCtx, cfg, agentId, agentDir, sessionEntry, previousSessionEntry, sessionStore, sessionKey, storePath, sessionScope, workspaceDir, isGroup, opts, typing, allowTextCommands, inlineStatusRequested, command, directives: initialDirectives, cleanedBody: initialCleanedBody, elevatedEnabled, elevatedAllowed, elevatedFailures, defaultActivation, resolvedThinkLevel, resolvedVerboseLevel, resolvedReasoningLevel, resolvedElevatedLevel, resolveDefaultThinkingLevel, provider, model, contextTokens, directiveAck, abortedLastRun: initialAbortedLastRun, skillFilter, } = params;
35
+ let directives = initialDirectives;
36
+ let cleanedBody = initialCleanedBody;
37
+ const shouldLoadSkillCommands = command.commandBodyNormalized.startsWith("/");
38
+ const skillCommands = shouldLoadSkillCommands && params.skillCommands
39
+ ? params.skillCommands
40
+ : shouldLoadSkillCommands
41
+ ? listSkillCommandsForWorkspace({
42
+ workspaceDir,
43
+ cfg,
44
+ skillFilter,
45
+ })
46
+ : [];
47
+ const skillInvocation = allowTextCommands && skillCommands.length > 0
48
+ ? resolveSkillCommandInvocation({
49
+ commandBodyNormalized: command.commandBodyNormalized,
50
+ skillCommands,
51
+ })
52
+ : null;
53
+ if (skillInvocation) {
54
+ if (!command.isAuthorizedSender) {
55
+ logVerbose(`Ignoring /${skillInvocation.command.name} from unauthorized sender: ${command.senderId || "<unknown>"}`);
56
+ typing.cleanup();
57
+ return { kind: "reply", reply: undefined };
58
+ }
59
+ const dispatch = skillInvocation.command.dispatch;
60
+ if (dispatch?.kind === "tool") {
61
+ const rawArgs = (skillInvocation.args ?? "").trim();
62
+ const channel = resolveGatewayMessageChannel(ctx.Surface) ??
63
+ resolveGatewayMessageChannel(ctx.Provider) ??
64
+ undefined;
65
+ const tools = createPoolBotTools({
66
+ agentSessionKey: sessionKey,
67
+ agentChannel: channel,
68
+ agentAccountId: ctx.AccountId,
69
+ agentTo: ctx.OriginatingTo ?? ctx.To,
70
+ agentThreadId: ctx.MessageThreadId ?? undefined,
71
+ agentDir,
72
+ workspaceDir,
73
+ config: cfg,
74
+ });
75
+ const tool = tools.find((candidate) => candidate.name === dispatch.toolName);
76
+ if (!tool) {
77
+ typing.cleanup();
78
+ return { kind: "reply", reply: { text: `❌ Tool not available: ${dispatch.toolName}` } };
79
+ }
80
+ const toolCallId = `cmd_${Date.now()}_${Math.random().toString(16).slice(2)}`;
81
+ try {
82
+ const result = await tool.execute(toolCallId, {
83
+ command: rawArgs,
84
+ commandName: skillInvocation.command.name,
85
+ skillName: skillInvocation.command.skillName,
86
+ });
87
+ const text = extractTextFromToolResult(result) ?? "✅ Done.";
88
+ typing.cleanup();
89
+ return { kind: "reply", reply: { text } };
90
+ }
91
+ catch (err) {
92
+ const message = err instanceof Error ? err.message : String(err);
93
+ typing.cleanup();
94
+ return { kind: "reply", reply: { text: `❌ ${message}` } };
95
+ }
96
+ }
97
+ const promptParts = [
98
+ `Use the "${skillInvocation.command.skillName}" skill for this request.`,
99
+ skillInvocation.args ? `User input:\n${skillInvocation.args}` : null,
100
+ ].filter((entry) => Boolean(entry));
101
+ const rewrittenBody = promptParts.join("\n\n");
102
+ ctx.Body = rewrittenBody;
103
+ ctx.BodyForAgent = rewrittenBody;
104
+ sessionCtx.Body = rewrittenBody;
105
+ sessionCtx.BodyForAgent = rewrittenBody;
106
+ sessionCtx.BodyStripped = rewrittenBody;
107
+ cleanedBody = rewrittenBody;
108
+ }
109
+ const sendInlineReply = async (reply) => {
110
+ if (!reply)
111
+ return;
112
+ if (!opts?.onBlockReply)
113
+ return;
114
+ await opts.onBlockReply(reply);
115
+ };
116
+ const inlineCommand = allowTextCommands && command.isAuthorizedSender
117
+ ? extractInlineSimpleCommand(cleanedBody)
118
+ : null;
119
+ if (inlineCommand) {
120
+ cleanedBody = inlineCommand.cleaned;
121
+ sessionCtx.Body = cleanedBody;
122
+ sessionCtx.BodyForAgent = cleanedBody;
123
+ sessionCtx.BodyStripped = cleanedBody;
124
+ }
125
+ const handleInlineStatus = !isDirectiveOnly({
126
+ directives,
127
+ cleanedBody: directives.cleaned,
128
+ ctx,
129
+ cfg,
130
+ agentId,
131
+ isGroup,
132
+ }) && inlineStatusRequested;
133
+ if (handleInlineStatus) {
134
+ const inlineStatusReply = await buildStatusReply({
135
+ cfg,
136
+ command,
137
+ sessionEntry,
138
+ sessionKey,
139
+ parentSessionKey: ctx.ParentSessionKey,
140
+ sessionScope,
141
+ provider,
142
+ model,
143
+ contextTokens,
144
+ resolvedThinkLevel,
145
+ resolvedVerboseLevel: resolvedVerboseLevel ?? "off",
146
+ resolvedReasoningLevel,
147
+ resolvedElevatedLevel,
148
+ resolveDefaultThinkingLevel,
149
+ isGroup,
150
+ defaultGroupActivation: defaultActivation,
151
+ mediaDecisions: ctx.MediaUnderstandingDecisions,
152
+ });
153
+ await sendInlineReply(inlineStatusReply);
154
+ directives = { ...directives, hasStatusDirective: false };
155
+ }
156
+ if (inlineCommand) {
157
+ const inlineCommandContext = {
158
+ ...command,
159
+ rawBodyNormalized: inlineCommand.command,
160
+ commandBodyNormalized: inlineCommand.command,
161
+ };
162
+ const inlineResult = await handleCommands({
163
+ ctx,
164
+ cfg,
165
+ command: inlineCommandContext,
166
+ agentId,
167
+ directives,
168
+ elevated: {
169
+ enabled: elevatedEnabled,
170
+ allowed: elevatedAllowed,
171
+ failures: elevatedFailures,
172
+ },
173
+ sessionEntry,
174
+ previousSessionEntry,
175
+ sessionStore,
176
+ sessionKey,
177
+ storePath,
178
+ sessionScope,
179
+ workspaceDir,
180
+ defaultGroupActivation: defaultActivation,
181
+ resolvedThinkLevel,
182
+ resolvedVerboseLevel: resolvedVerboseLevel ?? "off",
183
+ resolvedReasoningLevel,
184
+ resolvedElevatedLevel,
185
+ resolveDefaultThinkingLevel,
186
+ provider,
187
+ model,
188
+ contextTokens,
189
+ isGroup,
190
+ skillCommands,
191
+ });
192
+ if (inlineResult.reply) {
193
+ if (!inlineCommand.cleaned) {
194
+ typing.cleanup();
195
+ return { kind: "reply", reply: inlineResult.reply };
196
+ }
197
+ await sendInlineReply(inlineResult.reply);
198
+ }
199
+ }
200
+ if (directiveAck) {
201
+ await sendInlineReply(directiveAck);
202
+ }
203
+ const isEmptyConfig = Object.keys(cfg).length === 0;
204
+ const skipWhenConfigEmpty = command.channelId
205
+ ? Boolean(getChannelDock(command.channelId)?.commands?.skipWhenConfigEmpty)
206
+ : false;
207
+ if (skipWhenConfigEmpty &&
208
+ isEmptyConfig &&
209
+ command.from &&
210
+ command.to &&
211
+ command.from !== command.to) {
212
+ typing.cleanup();
213
+ return { kind: "reply", reply: undefined };
214
+ }
215
+ let abortedLastRun = initialAbortedLastRun;
216
+ if (!sessionEntry && command.abortKey) {
217
+ abortedLastRun = getAbortMemory(command.abortKey) ?? false;
218
+ }
219
+ const commandResult = await handleCommands({
220
+ ctx,
221
+ cfg,
222
+ command,
223
+ agentId,
224
+ directives,
225
+ elevated: {
226
+ enabled: elevatedEnabled,
227
+ allowed: elevatedAllowed,
228
+ failures: elevatedFailures,
229
+ },
230
+ sessionEntry,
231
+ previousSessionEntry,
232
+ sessionStore,
233
+ sessionKey,
234
+ storePath,
235
+ sessionScope,
236
+ workspaceDir,
237
+ defaultGroupActivation: defaultActivation,
238
+ resolvedThinkLevel,
239
+ resolvedVerboseLevel: resolvedVerboseLevel ?? "off",
240
+ resolvedReasoningLevel,
241
+ resolvedElevatedLevel,
242
+ resolveDefaultThinkingLevel,
243
+ provider,
244
+ model,
245
+ contextTokens,
246
+ isGroup,
247
+ skillCommands,
248
+ });
249
+ if (!commandResult.shouldContinue) {
250
+ typing.cleanup();
251
+ return { kind: "reply", reply: commandResult.reply };
252
+ }
253
+ return {
254
+ kind: "continue",
255
+ directives,
256
+ abortedLastRun,
257
+ };
258
+ }