@poolzin/pool-bot 2026.3.25 → 2026.3.27

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 +32 -257
  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,227 @@
1
+ import crypto from "node:crypto";
2
+ import { resolveAgentModelFallbacksOverride } from "../../agents/agent-scope.js";
3
+ import { lookupContextTokens } from "../../agents/context.js";
4
+ import { DEFAULT_CONTEXT_TOKENS } from "../../agents/defaults.js";
5
+ import { runWithModelFallback } from "../../agents/model-fallback.js";
6
+ import { runEmbeddedPiAgent } from "../../agents/pi-embedded.js";
7
+ import { resolveAgentIdFromSessionKey } from "../../config/sessions.js";
8
+ import { logVerbose } from "../../globals.js";
9
+ import { registerAgentRunContext } from "../../infra/agent-events.js";
10
+ import { defaultRuntime } from "../../runtime.js";
11
+ import { stripHeartbeatToken } from "../heartbeat.js";
12
+ import { isSilentReplyText, SILENT_REPLY_TOKEN } from "../tokens.js";
13
+ import { applyReplyThreading, filterMessagingToolDuplicates, shouldSuppressMessagingToolReplies, } from "./reply-payloads.js";
14
+ import { resolveReplyToMode } from "./reply-threading.js";
15
+ import { isRoutableChannel, routeReply } from "./route-reply.js";
16
+ import { persistSessionUsageUpdate } from "./session-usage.js";
17
+ import { incrementCompactionCount } from "./session-updates.js";
18
+ import { createTypingSignaler } from "./typing-mode.js";
19
+ export function createFollowupRunner(params) {
20
+ const { opts, typing, typingMode, sessionEntry, sessionStore, sessionKey, storePath, defaultModel, agentCfgContextTokens, } = params;
21
+ const typingSignals = createTypingSignaler({
22
+ typing,
23
+ mode: typingMode,
24
+ isHeartbeat: opts?.isHeartbeat === true,
25
+ });
26
+ /**
27
+ * Sends followup payloads, routing to the originating channel if set.
28
+ *
29
+ * When originatingChannel/originatingTo are set on the queued run,
30
+ * replies are routed directly to that provider instead of using the
31
+ * session's current dispatcher. This ensures replies go back to
32
+ * where the message originated.
33
+ */
34
+ const sendFollowupPayloads = async (payloads, queued) => {
35
+ // Check if we should route to originating channel.
36
+ const { originatingChannel, originatingTo } = queued;
37
+ const shouldRouteToOriginating = isRoutableChannel(originatingChannel) && originatingTo;
38
+ if (!shouldRouteToOriginating && !opts?.onBlockReply) {
39
+ logVerbose("followup queue: no onBlockReply handler; dropping payloads");
40
+ return;
41
+ }
42
+ for (const payload of payloads) {
43
+ if (!payload?.text && !payload?.mediaUrl && !payload?.mediaUrls?.length) {
44
+ continue;
45
+ }
46
+ if (isSilentReplyText(payload.text, SILENT_REPLY_TOKEN) &&
47
+ !payload.mediaUrl &&
48
+ !payload.mediaUrls?.length) {
49
+ continue;
50
+ }
51
+ await typingSignals.signalTextDelta(payload.text);
52
+ // Route to originating channel if set, otherwise fall back to dispatcher.
53
+ if (shouldRouteToOriginating) {
54
+ const result = await routeReply({
55
+ payload,
56
+ channel: originatingChannel,
57
+ to: originatingTo,
58
+ sessionKey: queued.run.sessionKey,
59
+ accountId: queued.originatingAccountId,
60
+ threadId: queued.originatingThreadId,
61
+ cfg: queued.run.config,
62
+ });
63
+ if (!result.ok) {
64
+ // Log error and fall back to dispatcher if available.
65
+ const errorMsg = result.error ?? "unknown error";
66
+ logVerbose(`followup queue: route-reply failed: ${errorMsg}`);
67
+ // Fallback: try the dispatcher if routing failed.
68
+ if (opts?.onBlockReply) {
69
+ await opts.onBlockReply(payload);
70
+ }
71
+ }
72
+ }
73
+ else if (opts?.onBlockReply) {
74
+ await opts.onBlockReply(payload);
75
+ }
76
+ }
77
+ };
78
+ return async (queued) => {
79
+ try {
80
+ const runId = crypto.randomUUID();
81
+ if (queued.run.sessionKey) {
82
+ registerAgentRunContext(runId, {
83
+ sessionKey: queued.run.sessionKey,
84
+ verboseLevel: queued.run.verboseLevel,
85
+ });
86
+ }
87
+ let autoCompactionCompleted = false;
88
+ let runResult;
89
+ let fallbackProvider = queued.run.provider;
90
+ let fallbackModel = queued.run.model;
91
+ try {
92
+ const fallbackResult = await runWithModelFallback({
93
+ cfg: queued.run.config,
94
+ provider: queued.run.provider,
95
+ model: queued.run.model,
96
+ agentDir: queued.run.agentDir,
97
+ fallbacksOverride: resolveAgentModelFallbacksOverride(queued.run.config, resolveAgentIdFromSessionKey(queued.run.sessionKey)),
98
+ run: (provider, model) => {
99
+ const authProfileId = provider === queued.run.provider ? queued.run.authProfileId : undefined;
100
+ return runEmbeddedPiAgent({
101
+ sessionId: queued.run.sessionId,
102
+ sessionKey: queued.run.sessionKey,
103
+ messageProvider: queued.run.messageProvider,
104
+ agentAccountId: queued.run.agentAccountId,
105
+ messageTo: queued.originatingTo,
106
+ messageThreadId: queued.originatingThreadId,
107
+ groupId: queued.run.groupId,
108
+ groupChannel: queued.run.groupChannel,
109
+ groupSpace: queued.run.groupSpace,
110
+ senderId: queued.run.senderId,
111
+ senderName: queued.run.senderName,
112
+ senderUsername: queued.run.senderUsername,
113
+ senderE164: queued.run.senderE164,
114
+ senderIsOwner: queued.run.senderIsOwner,
115
+ sessionFile: queued.run.sessionFile,
116
+ workspaceDir: queued.run.workspaceDir,
117
+ config: queued.run.config,
118
+ skillsSnapshot: queued.run.skillsSnapshot,
119
+ prompt: queued.prompt,
120
+ extraSystemPrompt: queued.run.extraSystemPrompt,
121
+ ownerNumbers: queued.run.ownerNumbers,
122
+ enforceFinalTag: queued.run.enforceFinalTag,
123
+ provider,
124
+ model,
125
+ authProfileId,
126
+ authProfileIdSource: authProfileId ? queued.run.authProfileIdSource : undefined,
127
+ thinkLevel: queued.run.thinkLevel,
128
+ verboseLevel: queued.run.verboseLevel,
129
+ reasoningLevel: queued.run.reasoningLevel,
130
+ execOverrides: queued.run.execOverrides,
131
+ bashElevated: queued.run.bashElevated,
132
+ timeoutMs: queued.run.timeoutMs,
133
+ runId,
134
+ blockReplyBreak: queued.run.blockReplyBreak,
135
+ onAgentEvent: (evt) => {
136
+ if (evt.stream !== "compaction")
137
+ return;
138
+ const phase = typeof evt.data.phase === "string" ? evt.data.phase : "";
139
+ const willRetry = Boolean(evt.data.willRetry);
140
+ if (phase === "end" && !willRetry) {
141
+ autoCompactionCompleted = true;
142
+ }
143
+ },
144
+ });
145
+ },
146
+ });
147
+ runResult = fallbackResult.result;
148
+ fallbackProvider = fallbackResult.provider;
149
+ fallbackModel = fallbackResult.model;
150
+ }
151
+ catch (err) {
152
+ const message = err instanceof Error ? err.message : String(err);
153
+ defaultRuntime.error?.(`Followup agent failed before reply: ${message}`);
154
+ return;
155
+ }
156
+ if (storePath && sessionKey) {
157
+ const usage = runResult.meta.agentMeta?.usage;
158
+ const modelUsed = runResult.meta.agentMeta?.model ?? fallbackModel ?? defaultModel;
159
+ const contextTokensUsed = agentCfgContextTokens ??
160
+ lookupContextTokens(modelUsed) ??
161
+ sessionEntry?.contextTokens ??
162
+ DEFAULT_CONTEXT_TOKENS;
163
+ await persistSessionUsageUpdate({
164
+ storePath,
165
+ sessionKey,
166
+ usage,
167
+ modelUsed,
168
+ providerUsed: fallbackProvider,
169
+ contextTokensUsed,
170
+ logLabel: "followup",
171
+ });
172
+ }
173
+ const payloadArray = runResult.payloads ?? [];
174
+ if (payloadArray.length === 0)
175
+ return;
176
+ const sanitizedPayloads = payloadArray.flatMap((payload) => {
177
+ const text = payload.text;
178
+ if (!text || !text.includes("HEARTBEAT_OK"))
179
+ return [payload];
180
+ const stripped = stripHeartbeatToken(text, { mode: "message" });
181
+ const hasMedia = Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0;
182
+ if (stripped.shouldSkip && !hasMedia)
183
+ return [];
184
+ return [{ ...payload, text: stripped.text }];
185
+ });
186
+ const replyToChannel = queued.originatingChannel ??
187
+ queued.run.messageProvider?.toLowerCase();
188
+ const replyToMode = resolveReplyToMode(queued.run.config, replyToChannel, queued.originatingAccountId, queued.originatingChatType);
189
+ const replyTaggedPayloads = applyReplyThreading({
190
+ payloads: sanitizedPayloads,
191
+ replyToMode,
192
+ replyToChannel,
193
+ });
194
+ const dedupedPayloads = filterMessagingToolDuplicates({
195
+ payloads: replyTaggedPayloads,
196
+ sentTexts: runResult.messagingToolSentTexts ?? [],
197
+ });
198
+ const suppressMessagingToolReplies = shouldSuppressMessagingToolReplies({
199
+ messageProvider: queued.run.messageProvider,
200
+ messagingToolSentTargets: runResult.messagingToolSentTargets,
201
+ originatingTo: queued.originatingTo,
202
+ accountId: queued.run.agentAccountId,
203
+ });
204
+ const finalPayloads = suppressMessagingToolReplies ? [] : dedupedPayloads;
205
+ if (finalPayloads.length === 0)
206
+ return;
207
+ if (autoCompactionCompleted) {
208
+ const count = await incrementCompactionCount({
209
+ sessionEntry,
210
+ sessionStore,
211
+ sessionKey,
212
+ storePath,
213
+ });
214
+ if (queued.run.verboseLevel && queued.run.verboseLevel !== "off") {
215
+ const suffix = typeof count === "number" ? ` (count ${count})` : "";
216
+ finalPayloads.unshift({
217
+ text: `🧹 Auto-compaction complete${suffix}.`,
218
+ });
219
+ }
220
+ }
221
+ await sendFollowupPayloads(finalPayloads, queued);
222
+ }
223
+ finally {
224
+ typing.markRunComplete();
225
+ }
226
+ };
227
+ }
@@ -0,0 +1,201 @@
1
+ import { buildStatusReply } from "./commands.js";
2
+ import { applyInlineDirectivesFastLane, handleDirectiveOnly, isDirectiveOnly, persistInlineDirectives, } from "./directive-handling.js";
3
+ export async function applyInlineDirectiveOverrides(params) {
4
+ const { ctx, cfg, agentId, agentDir, agentCfg, sessionEntry, sessionStore, sessionKey, storePath, sessionScope, isGroup, allowTextCommands, command, messageProviderKey, elevatedEnabled, elevatedAllowed, elevatedFailures, defaultProvider, defaultModel, aliasIndex, modelState, initialModelLabel, formatModelSwitchEvent, resolvedElevatedLevel, defaultActivation, typing, effectiveModelDirective, } = params;
5
+ let { directives } = params;
6
+ let { provider, model } = params;
7
+ let { contextTokens } = params;
8
+ let directiveAck;
9
+ if (!command.isAuthorizedSender) {
10
+ directives = {
11
+ ...directives,
12
+ hasThinkDirective: false,
13
+ hasVerboseDirective: false,
14
+ hasReasoningDirective: false,
15
+ hasElevatedDirective: false,
16
+ hasExecDirective: false,
17
+ execHost: undefined,
18
+ execSecurity: undefined,
19
+ execAsk: undefined,
20
+ execNode: undefined,
21
+ rawExecHost: undefined,
22
+ rawExecSecurity: undefined,
23
+ rawExecAsk: undefined,
24
+ rawExecNode: undefined,
25
+ hasExecOptions: false,
26
+ invalidExecHost: false,
27
+ invalidExecSecurity: false,
28
+ invalidExecAsk: false,
29
+ invalidExecNode: false,
30
+ hasStatusDirective: false,
31
+ hasModelDirective: false,
32
+ hasQueueDirective: false,
33
+ queueReset: false,
34
+ };
35
+ }
36
+ if (isDirectiveOnly({
37
+ directives,
38
+ cleanedBody: directives.cleaned,
39
+ ctx,
40
+ cfg,
41
+ agentId,
42
+ isGroup,
43
+ })) {
44
+ if (!command.isAuthorizedSender) {
45
+ typing.cleanup();
46
+ return { kind: "reply", reply: undefined };
47
+ }
48
+ const resolvedDefaultThinkLevel = sessionEntry?.thinkingLevel ??
49
+ agentCfg?.thinkingDefault ??
50
+ (await modelState.resolveDefaultThinkingLevel());
51
+ const currentThinkLevel = resolvedDefaultThinkLevel;
52
+ const currentVerboseLevel = sessionEntry?.verboseLevel ??
53
+ agentCfg?.verboseDefault;
54
+ const currentReasoningLevel = sessionEntry?.reasoningLevel ?? "off";
55
+ const currentElevatedLevel = sessionEntry?.elevatedLevel ??
56
+ agentCfg?.elevatedDefault;
57
+ const directiveReply = await handleDirectiveOnly({
58
+ cfg,
59
+ directives,
60
+ sessionEntry,
61
+ sessionStore,
62
+ sessionKey,
63
+ storePath,
64
+ elevatedEnabled,
65
+ elevatedAllowed,
66
+ elevatedFailures,
67
+ messageProviderKey,
68
+ defaultProvider,
69
+ defaultModel,
70
+ aliasIndex,
71
+ allowedModelKeys: modelState.allowedModelKeys,
72
+ allowedModelCatalog: modelState.allowedModelCatalog,
73
+ resetModelOverride: modelState.resetModelOverride,
74
+ provider,
75
+ model,
76
+ initialModelLabel,
77
+ formatModelSwitchEvent,
78
+ currentThinkLevel,
79
+ currentVerboseLevel,
80
+ currentReasoningLevel,
81
+ currentElevatedLevel,
82
+ });
83
+ let statusReply;
84
+ if (directives.hasStatusDirective && allowTextCommands && command.isAuthorizedSender) {
85
+ statusReply = await buildStatusReply({
86
+ cfg,
87
+ command,
88
+ sessionEntry,
89
+ sessionKey,
90
+ sessionScope,
91
+ provider,
92
+ model,
93
+ contextTokens,
94
+ resolvedThinkLevel: resolvedDefaultThinkLevel,
95
+ resolvedVerboseLevel: (currentVerboseLevel ?? "off"),
96
+ resolvedReasoningLevel: (currentReasoningLevel ?? "off"),
97
+ resolvedElevatedLevel,
98
+ resolveDefaultThinkingLevel: async () => resolvedDefaultThinkLevel,
99
+ isGroup,
100
+ defaultGroupActivation: defaultActivation,
101
+ mediaDecisions: ctx.MediaUnderstandingDecisions,
102
+ });
103
+ }
104
+ typing.cleanup();
105
+ if (statusReply?.text && directiveReply?.text) {
106
+ return {
107
+ kind: "reply",
108
+ reply: { text: `${directiveReply.text}\n${statusReply.text}` },
109
+ };
110
+ }
111
+ return { kind: "reply", reply: statusReply ?? directiveReply };
112
+ }
113
+ const hasAnyDirective = directives.hasThinkDirective ||
114
+ directives.hasVerboseDirective ||
115
+ directives.hasReasoningDirective ||
116
+ directives.hasElevatedDirective ||
117
+ directives.hasExecDirective ||
118
+ directives.hasModelDirective ||
119
+ directives.hasQueueDirective ||
120
+ directives.hasStatusDirective;
121
+ if (hasAnyDirective && command.isAuthorizedSender) {
122
+ const fastLane = await applyInlineDirectivesFastLane({
123
+ directives,
124
+ commandAuthorized: command.isAuthorizedSender,
125
+ ctx,
126
+ cfg,
127
+ agentId,
128
+ isGroup,
129
+ sessionEntry,
130
+ sessionStore,
131
+ sessionKey,
132
+ storePath,
133
+ elevatedEnabled,
134
+ elevatedAllowed,
135
+ elevatedFailures,
136
+ messageProviderKey,
137
+ defaultProvider,
138
+ defaultModel,
139
+ aliasIndex,
140
+ allowedModelKeys: modelState.allowedModelKeys,
141
+ allowedModelCatalog: modelState.allowedModelCatalog,
142
+ resetModelOverride: modelState.resetModelOverride,
143
+ provider,
144
+ model,
145
+ initialModelLabel,
146
+ formatModelSwitchEvent,
147
+ agentCfg,
148
+ modelState: {
149
+ resolveDefaultThinkingLevel: modelState.resolveDefaultThinkingLevel,
150
+ allowedModelKeys: modelState.allowedModelKeys,
151
+ allowedModelCatalog: modelState.allowedModelCatalog,
152
+ resetModelOverride: modelState.resetModelOverride,
153
+ },
154
+ });
155
+ directiveAck = fastLane.directiveAck;
156
+ provider = fastLane.provider;
157
+ model = fastLane.model;
158
+ }
159
+ const persisted = await persistInlineDirectives({
160
+ directives,
161
+ effectiveModelDirective,
162
+ cfg,
163
+ agentDir,
164
+ sessionEntry,
165
+ sessionStore,
166
+ sessionKey,
167
+ storePath,
168
+ elevatedEnabled,
169
+ elevatedAllowed,
170
+ defaultProvider,
171
+ defaultModel,
172
+ aliasIndex,
173
+ allowedModelKeys: modelState.allowedModelKeys,
174
+ provider,
175
+ model,
176
+ initialModelLabel,
177
+ formatModelSwitchEvent,
178
+ agentCfg,
179
+ });
180
+ provider = persisted.provider;
181
+ model = persisted.model;
182
+ contextTokens = persisted.contextTokens;
183
+ const perMessageQueueMode = directives.hasQueueDirective && !directives.queueReset ? directives.queueMode : undefined;
184
+ const perMessageQueueOptions = directives.hasQueueDirective && !directives.queueReset
185
+ ? {
186
+ debounceMs: directives.debounceMs,
187
+ cap: directives.cap,
188
+ dropPolicy: directives.dropPolicy,
189
+ }
190
+ : undefined;
191
+ return {
192
+ kind: "continue",
193
+ directives,
194
+ provider,
195
+ model,
196
+ contextTokens,
197
+ directiveAck,
198
+ perMessageQueueMode,
199
+ perMessageQueueOptions,
200
+ };
201
+ }
@@ -0,0 +1,54 @@
1
+ const CLEARED_EXEC_FIELDS = {
2
+ hasExecDirective: false,
3
+ execHost: undefined,
4
+ execSecurity: undefined,
5
+ execAsk: undefined,
6
+ execNode: undefined,
7
+ rawExecHost: undefined,
8
+ rawExecSecurity: undefined,
9
+ rawExecAsk: undefined,
10
+ rawExecNode: undefined,
11
+ hasExecOptions: false,
12
+ invalidExecHost: false,
13
+ invalidExecSecurity: false,
14
+ invalidExecAsk: false,
15
+ invalidExecNode: false,
16
+ };
17
+ export function clearInlineDirectives(cleaned) {
18
+ return {
19
+ cleaned,
20
+ hasThinkDirective: false,
21
+ thinkLevel: undefined,
22
+ rawThinkLevel: undefined,
23
+ hasVerboseDirective: false,
24
+ verboseLevel: undefined,
25
+ rawVerboseLevel: undefined,
26
+ hasReasoningDirective: false,
27
+ reasoningLevel: undefined,
28
+ rawReasoningLevel: undefined,
29
+ hasElevatedDirective: false,
30
+ elevatedLevel: undefined,
31
+ rawElevatedLevel: undefined,
32
+ ...CLEARED_EXEC_FIELDS,
33
+ hasStatusDirective: false,
34
+ hasModelDirective: false,
35
+ rawModelDirective: undefined,
36
+ hasQueueDirective: false,
37
+ queueMode: undefined,
38
+ queueReset: false,
39
+ rawQueueMode: undefined,
40
+ debounceMs: undefined,
41
+ cap: undefined,
42
+ dropPolicy: undefined,
43
+ rawDebounce: undefined,
44
+ rawCap: undefined,
45
+ rawDrop: undefined,
46
+ hasQueueOptions: false,
47
+ };
48
+ }
49
+ export function clearExecInlineDirectives(directives) {
50
+ return {
51
+ ...directives,
52
+ ...CLEARED_EXEC_FIELDS,
53
+ };
54
+ }