@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
@@ -151,7 +151,6 @@ function resolveFallbackCandidates(params) {
151
151
  }
152
152
  const lastProbeAttempt = new Map();
153
153
  const MIN_PROBE_INTERVAL_MS = 30_000; // 30 seconds between probes per key
154
- const PROBE_MARGIN_MS = 2 * 60 * 1000;
155
154
  const PROBE_SCOPE_DELIMITER = "::";
156
155
  function resolveProbeThrottleKey(provider, agentDir) {
157
156
  const scope = String(agentDir ?? "").trim();
@@ -169,14 +168,16 @@ function shouldProbePrimaryDuringCooldown(params) {
169
168
  if (soonest === null || !Number.isFinite(soonest)) {
170
169
  return true;
171
170
  }
172
- // Probe when cooldown already expired or within the configured margin.
173
- return params.now >= soonest - PROBE_MARGIN_MS;
171
+ // FIX: Only probe when cooldown has actually expired.
172
+ // Previously we probed 2 minutes early (PROBE_MARGIN_MS), but this caused
173
+ // probes to fail and increase the cooldown, creating a vicious cycle where
174
+ // providers never recovered from cooldown.
175
+ return params.now >= soonest;
174
176
  }
175
177
  /** @internal – exposed for unit tests only */
176
178
  export const _probeThrottleInternals = {
177
179
  lastProbeAttempt,
178
180
  MIN_PROBE_INTERVAL_MS,
179
- PROBE_MARGIN_MS,
180
181
  resolveProbeThrottleKey,
181
182
  };
182
183
  export async function runWithModelFallback(params) {
@@ -1,209 +1,24 @@
1
- import fs from "node:fs/promises";
2
- import { detectMime } from "../../media/mime.js";
3
- import { sanitizeToolResultImages } from "../tool-images.js";
4
- export const OWNER_ONLY_TOOL_ERROR = "Tool restricted to owner senders.";
5
- export class ToolInputError extends Error {
6
- status = 400;
7
- constructor(message) {
8
- super(message);
9
- this.name = "ToolInputError";
10
- }
11
- }
12
- export class ToolAuthorizationError extends ToolInputError {
13
- status = 403;
14
- constructor(message) {
15
- super(message);
16
- this.name = "ToolAuthorizationError";
17
- }
18
- }
19
- export function createActionGate(actions) {
20
- return (key, defaultValue = true) => {
21
- const value = actions?.[key];
22
- if (value === undefined) {
23
- return defaultValue;
24
- }
25
- return value !== false;
26
- };
27
- }
28
- export function readStringParam(params, key, options = {}) {
29
- const { required = false, trim = true, label = key, allowEmpty = false } = options;
30
- const raw = params[key];
31
- if (typeof raw !== "string") {
32
- if (required) {
33
- throw new ToolInputError(`${label} required`);
34
- }
1
+ // Stub for agents/tools/common.js
2
+ export function readNumberParam(params, key, opts) {
3
+ const val = params[key];
4
+ if (typeof val !== "number")
35
5
  return undefined;
36
- }
37
- const value = trim ? raw.trim() : raw;
38
- if (!value && !allowEmpty) {
39
- if (required) {
40
- throw new ToolInputError(`${label} required`);
41
- }
6
+ if (opts?.integer && !Number.isInteger(val))
42
7
  return undefined;
43
- }
44
- return value;
45
- }
46
- export function readStringOrNumberParam(params, key, options = {}) {
47
- const { required = false, label = key } = options;
48
- const raw = params[key];
49
- if (typeof raw === "number" && Number.isFinite(raw)) {
50
- return String(raw);
51
- }
52
- if (typeof raw === "string") {
53
- const value = raw.trim();
54
- if (value) {
55
- return value;
56
- }
57
- }
58
- if (required) {
59
- throw new ToolInputError(`${label} required`);
60
- }
61
- return undefined;
62
- }
63
- export function readNumberParam(params, key, options = {}) {
64
- const { required = false, label = key, integer = false } = options;
65
- const raw = params[key];
66
- let value;
67
- if (typeof raw === "number" && Number.isFinite(raw)) {
68
- value = raw;
69
- }
70
- else if (typeof raw === "string") {
71
- const trimmed = raw.trim();
72
- if (trimmed) {
73
- const parsed = Number.parseFloat(trimmed);
74
- if (Number.isFinite(parsed)) {
75
- value = parsed;
76
- }
77
- }
78
- }
79
- if (value === undefined) {
80
- if (required) {
81
- throw new ToolInputError(`${label} required`);
82
- }
83
- return undefined;
84
- }
85
- return integer ? Math.trunc(value) : value;
86
- }
87
- export function readStringArrayParam(params, key, options = {}) {
88
- const { required = false, label = key } = options;
89
- const raw = params[key];
90
- if (Array.isArray(raw)) {
91
- const values = raw
92
- .filter((entry) => typeof entry === "string")
93
- .map((entry) => entry.trim())
94
- .filter(Boolean);
95
- if (values.length === 0) {
96
- if (required) {
97
- throw new ToolInputError(`${label} required`);
98
- }
99
- return undefined;
100
- }
101
- return values;
102
- }
103
- if (typeof raw === "string") {
104
- const value = raw.trim();
105
- if (!value) {
106
- if (required) {
107
- throw new ToolInputError(`${label} required`);
108
- }
109
- return undefined;
110
- }
111
- return [value];
112
- }
113
- if (required) {
114
- throw new ToolInputError(`${label} required`);
115
- }
116
- return undefined;
117
- }
118
- export function readReactionParams(params, options) {
119
- const emojiKey = options.emojiKey ?? "emoji";
120
- const removeKey = options.removeKey ?? "remove";
121
- const remove = typeof params[removeKey] === "boolean" ? params[removeKey] : false;
122
- const emoji = readStringParam(params, emojiKey, {
123
- required: true,
124
- allowEmpty: true,
125
- });
126
- if (remove && !emoji) {
127
- throw new ToolInputError(options.removeErrorMessage);
128
- }
129
- return { emoji, remove, isEmpty: !emoji };
130
- }
131
- export function jsonResult(payload) {
132
- return {
133
- content: [
134
- {
135
- type: "text",
136
- text: JSON.stringify(payload, null, 2),
137
- },
138
- ],
139
- details: payload,
140
- };
141
- }
142
- export function wrapOwnerOnlyToolExecution(tool, senderIsOwner) {
143
- if (tool.ownerOnly !== true || senderIsOwner || !tool.execute) {
144
- return tool;
145
- }
146
- return {
147
- ...tool,
148
- execute: async () => {
149
- throw new Error(OWNER_ONLY_TOOL_ERROR);
150
- },
151
- };
152
- }
153
- export async function imageResult(params) {
154
- const content = [
155
- {
156
- type: "text",
157
- text: params.extraText ?? `MEDIA:${params.path}`,
158
- },
159
- {
160
- type: "image",
161
- data: params.base64,
162
- mimeType: params.mimeType,
163
- },
164
- ];
165
- const result = {
166
- content,
167
- details: { path: params.path, ...params.details },
168
- };
169
- return await sanitizeToolResultImages(result, params.label, params.imageSanitization);
170
- }
171
- export async function imageResultFromFile(params) {
172
- const buf = await fs.readFile(params.path);
173
- const mimeType = (await detectMime({ buffer: buf.slice(0, 256) })) ?? "image/png";
174
- return await imageResult({
175
- label: params.label,
176
- path: params.path,
177
- base64: buf.toString("base64"),
178
- mimeType,
179
- extraText: params.extraText,
180
- details: params.details,
181
- imageSanitization: params.imageSanitization,
182
- });
8
+ return val;
183
9
  }
184
- /**
185
- * Validate and parse an `availableTags` parameter from untrusted input.
186
- * Returns `undefined` when the value is missing or not an array.
187
- * Entries that lack a string `name` are silently dropped.
188
- */
189
- export function parseAvailableTags(raw) {
190
- if (raw === undefined || raw === null) {
10
+ export function readStringParam(params, key, opts) {
11
+ const val = params[key];
12
+ if (typeof val !== "string") {
13
+ if (opts?.required)
14
+ throw new Error(`Missing required param: ${key}`);
191
15
  return undefined;
192
16
  }
193
- if (!Array.isArray(raw)) {
17
+ const trimmed = opts?.trim !== false ? val.trim() : val;
18
+ if (!trimmed && !opts?.allowEmpty) {
19
+ if (opts?.required)
20
+ throw new Error(`Missing required param: ${key}`);
194
21
  return undefined;
195
22
  }
196
- const result = raw
197
- .filter((t) => typeof t === "object" && t !== null && typeof t.name === "string")
198
- .map((t) => ({
199
- ...(t.id !== undefined && typeof t.id === "string" ? { id: t.id } : {}),
200
- name: t.name,
201
- ...(typeof t.moderated === "boolean" ? { moderated: t.moderated } : {}),
202
- ...(t.emoji_id === null || typeof t.emoji_id === "string" ? { emoji_id: t.emoji_id } : {}),
203
- ...(t.emoji_name === null || typeof t.emoji_name === "string"
204
- ? { emoji_name: t.emoji_name }
205
- : {}),
206
- }));
207
- // Return undefined instead of empty array to avoid accidentally clearing all tags
208
- return result.length ? result : undefined;
23
+ return trimmed;
209
24
  }