@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
@@ -1,108 +0,0 @@
1
- const TOOL_NAME_ALIASES = {
2
- bash: "exec",
3
- "apply-patch": "apply_patch",
4
- };
5
- export const TOOL_GROUPS = {
6
- // NOTE: Keep canonical (lowercase) tool names here.
7
- "group:memory": ["memory_search", "memory_get"],
8
- "group:web": ["web_search", "web_fetch"],
9
- // Basic workspace/file tools
10
- "group:fs": ["read", "write", "edit", "apply_patch"],
11
- // Host/runtime execution tools
12
- "group:runtime": ["exec", "process"],
13
- // Session management tools
14
- "group:sessions": [
15
- "sessions_list",
16
- "sessions_history",
17
- "sessions_send",
18
- "sessions_spawn",
19
- "subagents",
20
- "session_status",
21
- ],
22
- // UI helpers
23
- "group:ui": ["browser", "canvas"],
24
- // Automation + infra
25
- "group:automation": ["cron", "gateway"],
26
- // Messaging surface
27
- "group:messaging": ["message"],
28
- // Nodes + device tools
29
- "group:nodes": ["nodes"],
30
- // All Pool Bot native tools (excludes provider plugins).
31
- "group:poolbot": [
32
- "browser",
33
- "canvas",
34
- "nodes",
35
- "cron",
36
- "message",
37
- "gateway",
38
- "agents_list",
39
- "sessions_list",
40
- "sessions_history",
41
- "sessions_send",
42
- "sessions_spawn",
43
- "subagents",
44
- "session_status",
45
- "memory_search",
46
- "memory_get",
47
- "web_search",
48
- "web_fetch",
49
- "image",
50
- ],
51
- };
52
- const TOOL_PROFILES = {
53
- minimal: {
54
- allow: ["session_status"],
55
- },
56
- coding: {
57
- allow: ["group:fs", "group:runtime", "group:sessions", "group:memory", "image"],
58
- },
59
- messaging: {
60
- allow: [
61
- "group:messaging",
62
- "sessions_list",
63
- "sessions_history",
64
- "sessions_send",
65
- "session_status",
66
- ],
67
- },
68
- full: {},
69
- };
70
- export function normalizeToolName(name) {
71
- const normalized = name.trim().toLowerCase();
72
- return TOOL_NAME_ALIASES[normalized] ?? normalized;
73
- }
74
- export function normalizeToolList(list) {
75
- if (!list) {
76
- return [];
77
- }
78
- return list.map(normalizeToolName).filter(Boolean);
79
- }
80
- export function expandToolGroups(list) {
81
- const normalized = normalizeToolList(list);
82
- const expanded = [];
83
- for (const value of normalized) {
84
- const group = TOOL_GROUPS[value];
85
- if (group) {
86
- expanded.push(...group);
87
- continue;
88
- }
89
- expanded.push(value);
90
- }
91
- return Array.from(new Set(expanded));
92
- }
93
- export function resolveToolProfilePolicy(profile) {
94
- if (!profile) {
95
- return undefined;
96
- }
97
- const resolved = TOOL_PROFILES[profile];
98
- if (!resolved) {
99
- return undefined;
100
- }
101
- if (!resolved.allow && !resolved.deny) {
102
- return undefined;
103
- }
104
- return {
105
- allow: resolved.allow ? [...resolved.allow] : undefined,
106
- deny: resolved.deny ? [...resolved.deny] : undefined,
107
- };
108
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Conformance snapshot for tool policy.
3
- *
4
- * Security note:
5
- * - This is static, build-time information (no runtime I/O, no network exposure).
6
- * - Intended for CI/tools to detect drift between the implementation policy and
7
- * the formal models/extractors.
8
- */
9
- import { TOOL_GROUPS } from "./tool-policy.js";
10
- // Tool name aliases are intentionally not exported from tool-policy today.
11
- // Keep the conformance snapshot focused on exported policy constants.
12
- export const TOOL_POLICY_CONFORMANCE = {
13
- toolGroups: TOOL_GROUPS,
14
- };
@@ -1,299 +0,0 @@
1
- /**
2
- * Tool Result Truncation & Context Pruning
3
- *
4
- * Implements:
5
- * - Head+tail truncation (preserves diagnostics)
6
- * - Context pruning for tool-results during soft-trim
7
- * - Preserve recent turns verbatim
8
- * - Multimodal + tool-result hints
9
- *
10
- * OpenClaw #32384, #30951
11
- */
12
- /**
13
- * Default truncation config
14
- * Head+tail approach preserves important diagnostics
15
- */
16
- export const DEFAULT_TRUNCATION_CONFIG = {
17
- maxToolResultChars: 50_000,
18
- headChars: 10_000,
19
- tailChars: 10_000,
20
- minCharsForTruncation: 20_000,
21
- preserveErrors: true,
22
- };
23
- /**
24
- * Truncate tool result content with head+tail strategy
25
- * OpenClaw #32384 - preserves diagnostic information
26
- */
27
- export function truncateToolResult(content, config = DEFAULT_TRUNCATION_CONFIG) {
28
- const originalLength = content.length;
29
- // Don't truncate if under threshold
30
- if (originalLength <= config.minCharsForTruncation) {
31
- return { truncated: content, wasTruncated: false, originalLength };
32
- }
33
- // Don't truncate if under max
34
- if (originalLength <= config.maxToolResultChars) {
35
- return { truncated: content, wasTruncated: false, originalLength };
36
- }
37
- // Head+tail truncation
38
- const head = content.slice(0, config.headChars);
39
- const tail = content.slice(-config.tailChars);
40
- const omitted = originalLength - config.headChars - config.tailChars;
41
- const truncated = `${head}\n\n[...${omitted.toLocaleString()} characters omitted...]\n\n${tail}`;
42
- return { truncated, wasTruncated: true, originalLength };
43
- }
44
- /**
45
- * Check if a message is a tool result
46
- */
47
- export function isToolResultMessage(message) {
48
- return message.role === "toolResult";
49
- }
50
- /**
51
- * Check if a tool result contains an error
52
- */
53
- export function isToolResultError(message) {
54
- if (!isToolResultMessage(message)) {
55
- return false;
56
- }
57
- return message.isError === true;
58
- }
59
- /**
60
- * Extract tool result content from message
61
- */
62
- export function extractToolResultContent(message) {
63
- const content = message.content;
64
- if (typeof content === "string") {
65
- return content;
66
- }
67
- if (content && typeof content === "object") {
68
- try {
69
- return JSON.stringify(content);
70
- }
71
- catch {
72
- return JSON.stringify({ error: "Failed to stringify content" });
73
- }
74
- }
75
- return "";
76
- }
77
- /**
78
- * Apply truncation to tool result messages
79
- * Preserves errors by default
80
- */
81
- export function truncateToolResultMessages(messages, config = DEFAULT_TRUNCATION_CONFIG) {
82
- return messages.map((message) => {
83
- if (!isToolResultMessage(message)) {
84
- return message;
85
- }
86
- // Preserve errors if configured
87
- if (config.preserveErrors && isToolResultError(message)) {
88
- return message;
89
- }
90
- const content = extractToolResultContent(message);
91
- const { truncated, wasTruncated } = truncateToolResult(content, config);
92
- if (!wasTruncated) {
93
- return message;
94
- }
95
- // Create new message with truncated content
96
- return {
97
- ...message,
98
- content: truncated,
99
- };
100
- });
101
- }
102
- /**
103
- * Default context pruning config
104
- */
105
- export const DEFAULT_CONTEXT_PRUNING_CONFIG = {
106
- keepRecentTurns: 10,
107
- pruneToolResultsOlderThan: 20,
108
- keepErrorToolResults: true,
109
- keepMultimodalContent: true,
110
- compressToolResults: false,
111
- };
112
- /**
113
- * Count turns in message history
114
- * A turn = user message + assistant response
115
- */
116
- export function countTurns(messages) {
117
- let turns = 0;
118
- let hasUserMessage = false;
119
- for (const message of messages) {
120
- const role = message.role;
121
- if (role === "user") {
122
- hasUserMessage = true;
123
- }
124
- else if (role === "assistant" && hasUserMessage) {
125
- turns += 1;
126
- hasUserMessage = false;
127
- }
128
- }
129
- // Count incomplete turn if there's a user message without response
130
- if (hasUserMessage) {
131
- turns += 1;
132
- }
133
- return turns;
134
- }
135
- /**
136
- * Prune context for soft-trim while preserving important information
137
- * OpenClaw #30951 - maintains diagnostic quality
138
- */
139
- export function pruneContextForSoftTrim(messages, config = DEFAULT_CONTEXT_PRUNING_CONFIG) {
140
- let currentTurn = 0;
141
- // Process messages in reverse to identify recent turns
142
- const reversedMessages = [...messages].reverse();
143
- const keptMessages = [];
144
- for (const message of reversedMessages) {
145
- const role = message.role;
146
- const isToolResult = isToolResultMessage(message);
147
- const isToolError = isToolResultError(message);
148
- const hasMultimodal = hasMultimodalContent(message);
149
- // Always keep user and assistant messages in recent turns
150
- if (role === "user" || role === "assistant") {
151
- if (currentTurn < config.keepRecentTurns) {
152
- keptMessages.unshift(message);
153
- if (role === "assistant") {
154
- currentTurn += 1;
155
- }
156
- }
157
- else {
158
- // Older turns: selectively prune
159
- if (!isToolResult) {
160
- keptMessages.unshift(message);
161
- }
162
- else if (config.keepErrorToolResults && isToolError) {
163
- keptMessages.unshift(message);
164
- }
165
- else if (config.keepMultimodalContent && hasMultimodal) {
166
- keptMessages.unshift(message);
167
- }
168
- else if (config.compressToolResults) {
169
- // Compress to summary instead of full content
170
- const compressed = compressToolResult(message);
171
- keptMessages.unshift(compressed);
172
- }
173
- }
174
- continue;
175
- }
176
- // Tool results: apply pruning rules
177
- if (isToolResult) {
178
- if (currentTurn < config.keepRecentTurns) {
179
- // Keep recent tool results
180
- keptMessages.unshift(message);
181
- }
182
- else if (config.keepErrorToolResults && isToolError) {
183
- // Always keep errors
184
- keptMessages.unshift(message);
185
- }
186
- else if (config.keepMultimodalContent && hasMultimodal) {
187
- // Keep multimodal content
188
- keptMessages.unshift(message);
189
- }
190
- else if (config.compressToolResults) {
191
- // Compress older tool results
192
- const compressed = compressToolResult(message);
193
- keptMessages.unshift(compressed);
194
- }
195
- // Otherwise: prune (don't add to keptMessages)
196
- }
197
- }
198
- return keptMessages;
199
- }
200
- /**
201
- * Check if a message has multimodal content (images, files, etc.)
202
- */
203
- export function hasMultimodalContent(message) {
204
- const content = message.content;
205
- if (!content) {
206
- return false;
207
- }
208
- if (Array.isArray(content)) {
209
- return content.some((item) => {
210
- if (!item || typeof item !== "object") {
211
- return false;
212
- }
213
- const record = item;
214
- return (typeof record.image === "string" ||
215
- typeof record.file === "string" ||
216
- typeof record.data === "string" ||
217
- typeof record.url === "string");
218
- });
219
- }
220
- return false;
221
- }
222
- /**
223
- * Compress tool result to summary (for context pruning)
224
- */
225
- export function compressToolResult(message) {
226
- if (!isToolResultMessage(message)) {
227
- return message;
228
- }
229
- const toolName = message.toolName;
230
- const toolNameStr = typeof toolName === "string" && toolName.trim() ? toolName : "unknown";
231
- const content = extractToolResultContent(message);
232
- // Create summary instead of full content
233
- const summary = `[Tool: ${toolNameStr}] - ${content.length.toLocaleString()} characters`;
234
- return {
235
- ...message,
236
- content: summary,
237
- };
238
- }
239
- /**
240
- * Audit compaction quality
241
- * OpenClaw #30951 - ensures compaction doesn't lose critical information
242
- */
243
- export function auditCompactionQuality(params) {
244
- const { originalMessages, compactedMessages, summary } = params;
245
- const issues = [];
246
- const recommendations = [];
247
- let score = 100;
248
- // Check 1: Tool errors preserved
249
- const originalErrors = originalMessages.filter(isToolResultError).length;
250
- const compactedErrors = compactedMessages.filter(isToolResultError).length;
251
- if (compactedErrors < originalErrors) {
252
- issues.push(`Lost ${originalErrors - compactedErrors} tool error messages`);
253
- recommendations.push("Preserve all tool errors during compaction");
254
- score -= 20;
255
- }
256
- // Check 2: Recent turns preserved
257
- const originalTurns = countTurns(originalMessages);
258
- const compactedTurns = countTurns(compactedMessages);
259
- if (compactedTurns < originalTurns * 0.3) {
260
- issues.push("Compaction ratio too aggressive (<30% of turns preserved)");
261
- recommendations.push("Keep at least 30% of recent turns verbatim");
262
- score -= 15;
263
- }
264
- // Check 3: Summary quality
265
- if (summary) {
266
- if (summary.length < 50) {
267
- issues.push("Summary too short (may lack detail)");
268
- recommendations.push("Generate more detailed summaries (min 50 chars)");
269
- score -= 10;
270
- }
271
- if (summary.length > 5000) {
272
- issues.push("Summary too long (defeats compaction purpose)");
273
- recommendations.push("Keep summaries concise (<5000 chars)");
274
- score -= 5;
275
- }
276
- }
277
- // Check 4: Multimodal content
278
- const originalMultimodal = originalMessages.filter(hasMultimodalContent).length;
279
- const compactedMultimodal = compactedMessages.filter(hasMultimodalContent).length;
280
- if (compactedMultimodal < originalMultimodal) {
281
- issues.push(`Lost ${originalMultimodal - compactedMultimodal} multimodal messages`);
282
- recommendations.push("Preserve multimodal content during compaction");
283
- score -= 15;
284
- }
285
- // Check 5: Message order
286
- const lastOriginalRole = originalMessages[originalMessages.length - 1]?.role;
287
- const lastCompactedRole = compactedMessages[compactedMessages.length - 1]?.role;
288
- if (lastOriginalRole !== lastCompactedRole) {
289
- issues.push("Message order may be incorrect (last message role mismatch)");
290
- recommendations.push("Verify message ordering after compaction");
291
- score -= 10;
292
- }
293
- return {
294
- score: Math.max(0, score),
295
- issues,
296
- recommendations,
297
- passed: score >= 70,
298
- };
299
- }
@@ -1,12 +0,0 @@
1
- import { vi } from "vitest";
2
- export const callGatewayMock = vi.fn();
3
- vi.mock("../../gateway/call.js", () => ({
4
- callGateway: (opts) => callGatewayMock(opts),
5
- }));
6
- vi.mock("../agent-scope.js", () => ({
7
- resolveSessionAgentId: () => "agent-123",
8
- }));
9
- export function resetCronToolGatewayMock() {
10
- callGatewayMock.mockReset();
11
- callGatewayMock.mockResolvedValue({ ok: true });
12
- }
@@ -1,27 +0,0 @@
1
- import { PermissionFlagsBits } from "discord-api-types/v10";
2
- import { readNumberParam, readStringParam } from "./common.js";
3
- const moderationPermissions = {
4
- timeout: PermissionFlagsBits.ModerateMembers,
5
- kick: PermissionFlagsBits.KickMembers,
6
- ban: PermissionFlagsBits.BanMembers,
7
- };
8
- export function isDiscordModerationAction(action) {
9
- return action === "timeout" || action === "kick" || action === "ban";
10
- }
11
- export function requiredGuildPermissionForModerationAction(action) {
12
- return moderationPermissions[action];
13
- }
14
- export function readDiscordModerationCommand(action, params) {
15
- if (!isDiscordModerationAction(action)) {
16
- throw new Error(`Unsupported Discord moderation action: ${action}`);
17
- }
18
- return {
19
- action,
20
- guildId: readStringParam(params, "guildId", { required: true }),
21
- userId: readStringParam(params, "userId", { required: true }),
22
- durationMinutes: readNumberParam(params, "durationMinutes", { integer: true }),
23
- until: readStringParam(params, "until"),
24
- reason: readStringParam(params, "reason"),
25
- deleteMessageDays: readNumberParam(params, "deleteMessageDays", { integer: true }),
26
- };
27
- }
@@ -1,78 +0,0 @@
1
- import { getGateway } from "../../discord/monitor/gateway-registry.js";
2
- import { jsonResult, readStringParam } from "./common.js";
3
- const ACTIVITY_TYPE_MAP = {
4
- playing: 0,
5
- streaming: 1,
6
- listening: 2,
7
- watching: 3,
8
- custom: 4,
9
- competing: 5,
10
- };
11
- const VALID_STATUSES = new Set(["online", "dnd", "idle", "invisible"]);
12
- export async function handleDiscordPresenceAction(action, params, isActionEnabled) {
13
- if (action !== "setPresence") {
14
- throw new Error(`Unknown presence action: ${action}`);
15
- }
16
- if (!isActionEnabled("presence", false)) {
17
- throw new Error("Discord presence changes are disabled.");
18
- }
19
- const accountId = readStringParam(params, "accountId");
20
- const gateway = getGateway(accountId);
21
- if (!gateway) {
22
- throw new Error(`Discord gateway not available${accountId ? ` for account "${accountId}"` : ""}. The bot may not be connected.`);
23
- }
24
- if (!gateway.isConnected) {
25
- throw new Error(`Discord gateway is not connected${accountId ? ` for account "${accountId}"` : ""}.`);
26
- }
27
- const statusRaw = readStringParam(params, "status") ?? "online";
28
- if (!VALID_STATUSES.has(statusRaw)) {
29
- throw new Error(`Invalid status "${statusRaw}". Must be one of: ${[...VALID_STATUSES].join(", ")}`);
30
- }
31
- const status = statusRaw;
32
- const activityTypeRaw = readStringParam(params, "activityType");
33
- const activityName = readStringParam(params, "activityName");
34
- const activities = [];
35
- if (activityTypeRaw || activityName) {
36
- if (!activityTypeRaw) {
37
- throw new Error("activityType is required when activityName is provided. " +
38
- `Valid types: ${Object.keys(ACTIVITY_TYPE_MAP).join(", ")}`);
39
- }
40
- const typeNum = ACTIVITY_TYPE_MAP[activityTypeRaw.toLowerCase()];
41
- if (typeNum === undefined) {
42
- throw new Error(`Invalid activityType "${activityTypeRaw}". Must be one of: ${Object.keys(ACTIVITY_TYPE_MAP).join(", ")}`);
43
- }
44
- const activity = {
45
- name: activityName ?? "",
46
- type: typeNum,
47
- };
48
- // Streaming URL (Twitch/YouTube). May not render for bots but is the correct payload shape.
49
- if (typeNum === 1) {
50
- const url = readStringParam(params, "activityUrl");
51
- if (url) {
52
- activity.url = url;
53
- }
54
- }
55
- const state = readStringParam(params, "activityState");
56
- if (state) {
57
- activity.state = state;
58
- }
59
- activities.push(activity);
60
- }
61
- const presenceData = {
62
- since: null,
63
- activities,
64
- status,
65
- afk: false,
66
- };
67
- gateway.updatePresence(presenceData);
68
- return jsonResult({
69
- ok: true,
70
- status,
71
- activities: activities.map((a) => ({
72
- type: a.type,
73
- name: a.name,
74
- ...(a.url ? { url: a.url } : {}),
75
- ...(a.state ? { state: a.state } : {}),
76
- })),
77
- });
78
- }