@openclaw/slack 2026.7.1 → 2026.7.2-beta.1

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 (69) hide show
  1. package/dist/accounts.runtime-KvftRRek.js +2 -0
  2. package/dist/{action-runtime-DoQGk_8D.js → action-runtime-p6M2ULpv.js} +205 -29
  3. package/dist/action-runtime.runtime-DQstDkHG.js +2 -0
  4. package/dist/{actions-DMpDmKEA.js → actions-DkTcWmpT.js} +87 -138
  5. package/dist/{actions.runtime-C103_BPW.js → actions.runtime-BSxpwgUc.js} +1 -1
  6. package/dist/api.js +14 -13
  7. package/dist/{approval-handler.runtime-CIUbOt5T.js → approval-handler.runtime-UGbnz9OC.js} +3 -3
  8. package/dist/{channel-BjlsaGHn.js → channel-B0_j6C6z.js} +116 -140
  9. package/dist/channel-config-api.js +1 -1
  10. package/dist/channel-plugin-api.js +1 -1
  11. package/dist/channel-type-BpeTezY4.js +109 -0
  12. package/dist/{channel.setup-Dq6syTNU.js → channel.setup-BQFut21T.js} +2 -2
  13. package/dist/{client-DGxwSL7f.js → client-D2F6m8CP.js} +38 -2
  14. package/dist/config-api-Df9a1B8C.js +3 -0
  15. package/dist/{config-schema-BzqzFW__.js → config-schema-DYI01PV2.js} +20 -37
  16. package/dist/cursor-pages-DSmTg0su.js +13 -0
  17. package/dist/{directory-config-BZuS8141.js → directory-config-DRkFujwG.js} +2 -2
  18. package/dist/directory-contract-api.js +1 -1
  19. package/dist/{directory-live-BNsxCgqP.js → directory-live-DX7yFsM-.js} +2 -2
  20. package/dist/{doctor-contract-XL6HeNCb.js → doctor-contract-DddfkMlF.js} +25 -38
  21. package/dist/doctor-contract-api.js +1 -1
  22. package/dist/group-policy-C-b2ZnSl.js +2332 -0
  23. package/dist/{interactive-replies-CXpT-vA_.js → interactive-replies-BilWUdcI.js} +5 -1
  24. package/dist/interactive-replies-api.js +1 -1
  25. package/dist/{message-tool-api-BgWKyu2r.js → message-tool-api-CA9jZrCY.js} +1 -1
  26. package/dist/message-tool-api.js +1 -1
  27. package/dist/{monitor-Ux-wzUWI.js → monitor-BN_uuvrQ.js} +3 -3
  28. package/dist/outbound-adapter-ECl0go7d.js +228 -0
  29. package/dist/{pipeline.runtime-rpVpay59.js → pipeline.runtime-f0eJJoJL.js} +492 -178
  30. package/dist/{policy-Dj-puVPb.js → policy-f8b0edSi.js} +1 -1
  31. package/dist/preflight-audio.runtime-D5Bgags0.js +3 -0
  32. package/dist/{probe-CuwRDE5j.js → probe-CfALk0l4.js} +2 -2
  33. package/dist/{provider-C1-DFSpw.js → provider-Ds-y-imP.js} +658 -192
  34. package/dist/{relay-source-D2jv1iGg.js → relay-source-B-6LFUdz.js} +6 -17
  35. package/dist/replies-BMvf3ihj.js +420 -0
  36. package/dist/{resolve-channels-CstkChBE.js → resolve-channels-DOMgNCWb.js} +17 -6
  37. package/dist/{resolve-users-C3NP2c-Q.js → resolve-users-aL6-Ssee.js} +11 -6
  38. package/dist/{runtime-BOk7xkOl.js → runtime-CauEvswP.js} +1 -1
  39. package/dist/{runtime-api-CEmqYxR-.js → runtime-api-CVb6CQjX.js} +3 -3
  40. package/dist/runtime-api.js +11 -11
  41. package/dist/runtime-setter-api.js +1 -1
  42. package/dist/{scopes-DCWVD5-8.js → scopes-Dw8wbU0j.js} +2 -2
  43. package/dist/{secret-contract-C3ChHo5A.js → secret-contract-CMohXFWS.js} +18 -113
  44. package/dist/secret-contract-api.js +1 -1
  45. package/dist/{send-DKDXoeoV.js → send-NEfJ0GvM.js} +662 -325
  46. package/dist/{send.runtime-GPRa63l1.js → send.runtime-BkKpitPu.js} +1 -1
  47. package/dist/setup-plugin-api.js +1 -1
  48. package/dist/{setup-surface-Dv2fIJNB.js → setup-surface-BN2WeG5c.js} +3 -3
  49. package/dist/{shared-CosfcFri.js → shared-BLnB9R1T.js} +7 -5
  50. package/dist/{slash-dispatch.runtime-CcMbbT3_.js → slash-dispatch.runtime-C0Otuf_T.js} +1 -1
  51. package/dist/{streaming-compat-DjlgH-Be.js → streaming-compat-3_X-21wW.js} +1 -0
  52. package/dist/{target-parsing-3jYH8LfB.js → target-parsing-N6lHogYZ.js} +16 -3
  53. package/dist/{targets-Dll4NJgs.js → targets-KmjP2E8s.js} +1 -1
  54. package/node_modules/p-map/index.d.ts +155 -0
  55. package/node_modules/p-map/index.js +284 -0
  56. package/node_modules/p-map/license +9 -0
  57. package/node_modules/p-map/package.json +57 -0
  58. package/node_modules/p-map/readme.md +190 -0
  59. package/npm-shrinkwrap.json +16 -3
  60. package/openclaw.plugin.json +16 -0
  61. package/package.json +6 -4
  62. package/dist/accounts.runtime-DWvaCb-X.js +0 -2
  63. package/dist/action-runtime.runtime-BABj3aM-.js +0 -2
  64. package/dist/config-api-DnT9ohtE.js +0 -2
  65. package/dist/format-YCNoNkM2.js +0 -107
  66. package/dist/outbound-adapter-DVoBfBW5.js +0 -272
  67. package/dist/replies-DpF38e1y.js +0 -287
  68. package/dist/reply-blocks-BGQ6zSqM.js +0 -877
  69. package/dist/resolve-allowlist-common-CP8SH0Zf.js +0 -43
@@ -1,272 +0,0 @@
1
- import { T as SLACK_SECTION_TEXT_MAX, _ as buildSlackPresentationBlocks, a as SLACK_TEXT_LIMIT, g as buildSlackInteractiveBlocks, r as parseSlackBlocksInput, v as canRenderSlackPresentation, w as SLACK_PRESENTATION_CAPABILITIES, y as resolveSlackInteractiveBlockOffsets } from "./reply-blocks-BGQ6zSqM.js";
2
- import { n as resolveSlackThreadTsValue } from "./thread-ts-DUGhaYKq.js";
3
- import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-CXpT-vA_.js";
4
- import { t as markdownToSlackMrkdwnChunks } from "./format-YCNoNkM2.js";
5
- import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
6
- import { resolveOutboundSendDep } from "openclaw/plugin-sdk/channel-outbound";
7
- import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
8
- import { renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
9
- import { resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
10
- import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
11
- //#region extensions/slack/src/outbound-adapter.ts
12
- const loadSlackSendRuntime = createLazyRuntimeModule(() => import("./send.runtime-GPRa63l1.js"));
13
- function resolveRenderedInteractiveBlocks(interactive, previousBlocks) {
14
- if (!interactive) return;
15
- const blocks = buildSlackInteractiveBlocks(interactive, resolveSlackInteractiveBlockOffsets(previousBlocks));
16
- return blocks.length > 0 ? blocks : void 0;
17
- }
18
- function resolveSlackSendIdentity(identity) {
19
- if (!identity) return;
20
- const username = normalizeOptionalString(identity.name);
21
- const iconUrl = normalizeOptionalString(identity.avatarUrl);
22
- const rawEmoji = normalizeOptionalString(identity.emoji);
23
- const iconEmoji = !iconUrl ? rawEmoji : void 0;
24
- if (!username && !iconUrl && !iconEmoji) return;
25
- return {
26
- username,
27
- iconUrl,
28
- iconEmoji
29
- };
30
- }
31
- function buildSlackTextSectionBlocks(text) {
32
- return markdownToSlackMrkdwnChunks(text.trim(), SLACK_SECTION_TEXT_MAX).map((chunk) => ({
33
- type: "section",
34
- text: {
35
- type: "mrkdwn",
36
- text: chunk
37
- }
38
- }));
39
- }
40
- function normalizeComparableSlackText(text) {
41
- return text.trim().replace(/\s+/g, " ");
42
- }
43
- function isPayloadTextRepresentedInInteractive(text, interactive) {
44
- const target = normalizeComparableSlackText(text);
45
- const fragments = interactive?.blocks.flatMap((block) => block.type === "text" ? [normalizeComparableSlackText(block.text)] : []) ?? [];
46
- for (let start = 0; start < fragments.length; start += 1) {
47
- let combined = "";
48
- for (let end = start; end < fragments.length; end += 1) {
49
- combined = normalizeComparableSlackText(`${combined} ${fragments[end]}`);
50
- if (combined === target) return true;
51
- if (combined.length > target.length) break;
52
- }
53
- }
54
- return false;
55
- }
56
- function buildSlackVisiblePayloadTextBlocks(payload) {
57
- const text = normalizeOptionalString(payload.text);
58
- if (!text || isPayloadTextRepresentedInInteractive(text, payload.interactive)) return [];
59
- return buildSlackTextSectionBlocks(text);
60
- }
61
- function buildSlackPresentationFallback(presentation) {
62
- const text = renderMessagePresentationFallbackText({ presentation }).trim();
63
- return {
64
- blocks: buildSlackTextSectionBlocks(text),
65
- text
66
- };
67
- }
68
- function withSlackPresentationData(payload, slackData, presentationData) {
69
- const { presentationBlocks: _presentationBlocks, presentationFallbackText: _presentationFallbackText, ...rest } = slackData ?? {};
70
- return {
71
- ...payload,
72
- channelData: {
73
- ...payload.channelData,
74
- slack: {
75
- ...rest,
76
- ...presentationData
77
- }
78
- }
79
- };
80
- }
81
- async function sendSlackOutboundMessage(params) {
82
- const send = resolveOutboundSendDep(params.deps, "slack") ?? (await loadSlackSendRuntime()).sendMessageSlack;
83
- const slackIdentity = resolveSlackSendIdentity(params.identity);
84
- const threadTs = resolveSlackThreadTsValue({
85
- replyToId: params.replyToId,
86
- threadId: params.threadId
87
- });
88
- return await send(params.to, params.text, {
89
- cfg: params.cfg,
90
- threadTs,
91
- accountId: params.accountId ?? void 0,
92
- ...params.mediaUrl ? {
93
- mediaUrl: params.mediaUrl,
94
- mediaAccess: params.mediaAccess,
95
- mediaLocalRoots: params.mediaLocalRoots,
96
- mediaReadFile: params.mediaReadFile
97
- } : {},
98
- ...params.blocks ? { blocks: params.blocks } : {},
99
- ...slackIdentity ? { identity: slackIdentity } : {},
100
- deliveryQueueId: params.deliveryQueueId,
101
- onPlatformSendDispatch: params.onPlatformSendDispatch,
102
- onDeliveryResult: params.onDeliveryResult ? async (progress) => {
103
- await params.onDeliveryResult?.(attachChannelToResult("slack", progress));
104
- } : void 0
105
- });
106
- }
107
- function resolveSlackBlocks(payload) {
108
- const slackData = payload.channelData?.slack;
109
- const nativeBlocks = parseSlackBlocksInput(slackData?.blocks);
110
- const renderedPresentation = slackData?.presentationBlocks ?? (payload.presentation ? [...buildSlackVisiblePayloadTextBlocks(payload), ...buildSlackPresentationBlocks(payload.presentation, resolveSlackInteractiveBlockOffsets(nativeBlocks))] : []);
111
- const previousBlocks = [...nativeBlocks ?? [], ...renderedPresentation];
112
- const renderedInteractive = resolveRenderedInteractiveBlocks(payload.interactive, previousBlocks);
113
- const mergedBlocks = [...previousBlocks, ...renderedInteractive ?? []];
114
- if (mergedBlocks.length === 0) return;
115
- if (mergedBlocks.length > 50) throw new Error(`Slack blocks cannot exceed 50 items after interactive render`);
116
- return mergedBlocks;
117
- }
118
- const slackOutbound = {
119
- deliveryMode: "direct",
120
- chunker: null,
121
- textChunkLimit: SLACK_TEXT_LIMIT,
122
- normalizePayload: ({ payload, cfg, accountId }) => isSlackInteractiveRepliesEnabled({
123
- cfg,
124
- accountId
125
- }) ? compileSlackInteractiveReplies(payload) : payload,
126
- presentationCapabilities: SLACK_PRESENTATION_CAPABILITIES,
127
- renderPresentation: ({ payload, presentation, ctx }) => {
128
- const payloadForBudget = isSlackInteractiveRepliesEnabled({
129
- cfg: ctx.cfg,
130
- accountId: ctx.accountId
131
- }) ? compileSlackInteractiveReplies(payload) : payload;
132
- const slackData = payload.channelData?.slack;
133
- const nativeBlocks = parseSlackBlocksInput(slackData?.blocks);
134
- const payloadTextBlocks = buildSlackVisiblePayloadTextBlocks(payloadForBudget);
135
- if (canRenderSlackPresentation(presentation)) {
136
- const presentationBlocks = [...payloadTextBlocks, ...buildSlackPresentationBlocks(presentation, resolveSlackInteractiveBlockOffsets(nativeBlocks))];
137
- const previousBlocks = [...nativeBlocks ?? [], ...presentationBlocks];
138
- const interactiveBlocks = resolveRenderedInteractiveBlocks(payloadForBudget.interactive, previousBlocks);
139
- if (presentationBlocks.length > 0 && previousBlocks.length + (interactiveBlocks?.length ?? 0) <= 50) return withSlackPresentationData(payloadForBudget, slackData, { presentationBlocks });
140
- }
141
- const baseInteractiveBlocks = resolveRenderedInteractiveBlocks(payloadForBudget.interactive, nativeBlocks);
142
- if ((nativeBlocks?.length ?? 0) + (baseInteractiveBlocks?.length ?? 0) === 0) return null;
143
- const fallback = buildSlackPresentationFallback(presentation);
144
- const fallbackBlocks = [...payloadTextBlocks, ...fallback.blocks];
145
- if (fallbackBlocks.length === 0) return null;
146
- const fallbackPayload = {
147
- ...payloadForBudget,
148
- text: renderMessagePresentationFallbackText({
149
- text: payloadForBudget.text,
150
- presentation
151
- })
152
- };
153
- const fallbackPreviousBlocks = [...nativeBlocks ?? [], ...fallbackBlocks];
154
- const fallbackInteractiveBlocks = resolveRenderedInteractiveBlocks(payloadForBudget.interactive, fallbackPreviousBlocks);
155
- if (fallbackPreviousBlocks.length + (fallbackInteractiveBlocks?.length ?? 0) <= 50) return withSlackPresentationData(fallbackPayload, slackData, { presentationBlocks: fallbackBlocks });
156
- const separateFallbackText = renderMessagePresentationFallbackText({
157
- text: payloadTextBlocks.length > 0 ? payloadForBudget.text : void 0,
158
- presentation
159
- });
160
- return withSlackPresentationData(payloadTextBlocks.length > 0 ? {
161
- ...payloadForBudget,
162
- text: void 0
163
- } : payloadForBudget, slackData, { presentationFallbackText: separateFallbackText });
164
- },
165
- sendPayload: async (ctx) => {
166
- const payload = {
167
- ...ctx.payload,
168
- text: resolveInteractiveTextFallback({
169
- text: ctx.payload.text,
170
- interactive: ctx.payload.interactive
171
- }) ?? ""
172
- };
173
- const slackData = payload.channelData?.slack;
174
- const presentationFallbackText = normalizeOptionalString(slackData?.presentationFallbackText);
175
- const blocks = resolveSlackBlocks(payload);
176
- if (!blocks) return await sendTextMediaPayload({
177
- channel: "slack",
178
- ctx: {
179
- ...ctx,
180
- payload: presentationFallbackText ? {
181
- ...payload,
182
- text: [normalizeOptionalString(payload.text), presentationFallbackText].filter((part) => Boolean(part)).join("\n\n")
183
- } : payload
184
- },
185
- adapter: slackOutbound
186
- });
187
- return attachChannelToResult("slack", await sendPayloadMediaSequenceAndFinalize({
188
- text: "",
189
- mediaUrls: resolvePayloadMediaUrls(payload),
190
- send: async ({ text, mediaUrl }) => await sendSlackOutboundMessage({
191
- cfg: ctx.cfg,
192
- to: ctx.to,
193
- text,
194
- mediaUrl,
195
- mediaAccess: ctx.mediaAccess,
196
- mediaLocalRoots: ctx.mediaLocalRoots,
197
- mediaReadFile: ctx.mediaReadFile,
198
- accountId: ctx.accountId,
199
- deps: ctx.deps,
200
- replyToId: ctx.replyToId,
201
- threadId: ctx.threadId,
202
- identity: ctx.identity,
203
- onDeliveryResult: ctx.onDeliveryResult
204
- }),
205
- finalize: async () => {
206
- const blockResult = await sendSlackOutboundMessage({
207
- cfg: ctx.cfg,
208
- to: ctx.to,
209
- text: payload.text ?? "",
210
- mediaAccess: ctx.mediaAccess,
211
- mediaLocalRoots: ctx.mediaLocalRoots,
212
- mediaReadFile: ctx.mediaReadFile,
213
- blocks,
214
- accountId: ctx.accountId,
215
- deps: ctx.deps,
216
- replyToId: ctx.replyToId,
217
- threadId: ctx.threadId,
218
- identity: ctx.identity,
219
- onDeliveryResult: ctx.onDeliveryResult
220
- });
221
- if (!presentationFallbackText) return blockResult;
222
- return await sendSlackOutboundMessage({
223
- cfg: ctx.cfg,
224
- to: ctx.to,
225
- text: presentationFallbackText,
226
- mediaAccess: ctx.mediaAccess,
227
- mediaLocalRoots: ctx.mediaLocalRoots,
228
- mediaReadFile: ctx.mediaReadFile,
229
- accountId: ctx.accountId,
230
- deps: ctx.deps,
231
- replyToId: ctx.replyToId,
232
- threadId: ctx.threadId,
233
- identity: ctx.identity,
234
- onDeliveryResult: ctx.onDeliveryResult
235
- });
236
- }
237
- }));
238
- },
239
- ...createAttachedChannelResultAdapter({
240
- channel: "slack",
241
- sendText: async ({ cfg, to, text, accountId, deps, replyToId, threadId, identity, deliveryQueueId, onPlatformSendDispatch, onDeliveryResult }) => await sendSlackOutboundMessage({
242
- cfg,
243
- to,
244
- text,
245
- accountId,
246
- deps,
247
- replyToId,
248
- threadId,
249
- identity,
250
- deliveryQueueId,
251
- onPlatformSendDispatch,
252
- onDeliveryResult
253
- }),
254
- sendMedia: async ({ cfg, to, text, mediaUrl, mediaAccess, mediaLocalRoots, mediaReadFile, accountId, deps, replyToId, threadId, identity, onDeliveryResult }) => await sendSlackOutboundMessage({
255
- cfg,
256
- to,
257
- text,
258
- mediaUrl,
259
- mediaAccess,
260
- mediaLocalRoots,
261
- mediaReadFile,
262
- accountId,
263
- deps,
264
- replyToId,
265
- threadId,
266
- identity,
267
- onDeliveryResult
268
- })
269
- })
270
- };
271
- //#endregion
272
- export { slackOutbound };
@@ -1,287 +0,0 @@
1
- import { a as SLACK_TEXT_LIMIT, t as resolveSlackReplyBlocks } from "./reply-blocks-BGQ6zSqM.js";
2
- import { r as sendMessageSlack } from "./send-DKDXoeoV.js";
3
- import { t as markdownToSlackMrkdwnChunks } from "./format-YCNoNkM2.js";
4
- import "./provider-C1-DFSpw.js";
5
- import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-reference";
6
- import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
7
- import { SILENT_REPLY_TOKEN, chunkMarkdownTextWithMode, isSilentReplyText } from "openclaw/plugin-sdk/reply-chunking";
8
- import { deliverTextOrMediaReply, getReplyPayloadTtsSupplement, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
9
- import { getGlobalHookRunner } from "openclaw/plugin-sdk/plugin-runtime";
10
- import { buildCanonicalSentMessageHookContext, createInternalHookEvent, fireAndForgetHook, toInternalMessageSentContext, toPluginMessageContext, toPluginMessageSentEvent, triggerInternalHook } from "openclaw/plugin-sdk/hook-runtime";
11
- //#region extensions/slack/src/message-sent-hook.ts
12
- /**
13
- * Slack-side emission of the `message_sent` plugin hook.
14
- *
15
- * Mirrors the Telegram pattern in `extensions/telegram/src/bot/delivery.replies.ts`
16
- * (`buildTelegramSentHookContext`, `emitMessageSentHooks`, `emitTelegramMessageSentHooks`).
17
- *
18
- * Without this, plugins observing `message_sent` see Telegram outbound but not
19
- * Slack outbound — even though `docs/plugins/hooks.md` documents the hook as
20
- * firing for all successful outbound deliveries.
21
- */
22
- function buildSlackSentHookContext(params) {
23
- return buildCanonicalSentMessageHookContext({
24
- to: params.to,
25
- content: params.content,
26
- success: params.success,
27
- error: params.error,
28
- channelId: "slack",
29
- accountId: params.accountId ?? void 0,
30
- conversationId: params.to,
31
- sessionKey: params.sessionKeyForInternalHooks,
32
- messageId: params.messageId,
33
- isGroup: params.isGroup,
34
- groupId: params.groupId
35
- });
36
- }
37
- function emitInternalSlackMessageSentHook(params) {
38
- if (!params.sessionKeyForInternalHooks) return;
39
- const canonical = buildSlackSentHookContext(params);
40
- fireAndForgetHook(triggerInternalHook(createInternalHookEvent("message", "sent", params.sessionKeyForInternalHooks, toInternalMessageSentContext(canonical))), "slack: message:sent internal hook failed");
41
- }
42
- function emitMessageSentHooks(params) {
43
- if (!params.enabled && !params.sessionKeyForInternalHooks) return;
44
- const canonical = buildSlackSentHookContext(params);
45
- if (params.enabled) fireAndForgetHook(Promise.resolve(params.hookRunner.runMessageSent(toPluginMessageSentEvent(canonical), toPluginMessageContext(canonical))), "slack: message_sent plugin hook failed");
46
- emitInternalSlackMessageSentHook(params);
47
- }
48
- /**
49
- * Fire both the plugin `message_sent` hook and (if a session key is supplied)
50
- * the internal `message:sent` hook for a successful or failed Slack outbound
51
- * delivery.
52
- *
53
- * Safe to call after every `chat.postMessage` — the function self-gates on
54
- * `hookRunner.hasHooks("message_sent")` so plugins not observing the hook
55
- * incur no cost.
56
- */
57
- function emitSlackMessageSentHooks(params) {
58
- const hookRunner = getGlobalHookRunner();
59
- emitMessageSentHooks({
60
- ...params,
61
- hookRunner,
62
- enabled: hookRunner?.hasHooks("message_sent") ?? false
63
- });
64
- }
65
- //#endregion
66
- //#region extensions/slack/src/monitor/replies.ts
67
- function readSlackReplyBlocks(payload) {
68
- return resolveSlackReplyBlocks(payload);
69
- }
70
- function resolveSlackMediaHookSpokenText(payload) {
71
- return (getReplyPayloadTtsSupplement(payload)?.spokenText ?? payload.spokenText)?.trim() || void 0;
72
- }
73
- function resolveDeliveredSlackReplyThreadTs(params) {
74
- return (params.replyToMode === "off" ? void 0 : params.payloadReplyToId) ?? params.replyThreadTs;
75
- }
76
- async function deliverReplies(params) {
77
- let latestResult;
78
- for (const payload of params.replies) {
79
- if (payload.isReasoning === true) continue;
80
- const threadTs = resolveDeliveredSlackReplyThreadTs({
81
- replyToMode: params.replyToMode,
82
- payloadReplyToId: payload.replyToId,
83
- replyThreadTs: params.replyThreadTs
84
- });
85
- const reply = resolveSendableOutboundReplyParts(payload);
86
- const slackBlocks = readSlackReplyBlocks(payload);
87
- if (!reply.hasContent && !slackBlocks?.length) continue;
88
- const emitSent = (content, result) => {
89
- if (params.deferMessageSentHooks) return;
90
- emitSlackMessageSentHooks({
91
- sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
92
- to: params.messageSentHookTarget ?? params.target,
93
- accountId: params.accountId,
94
- content,
95
- success: true,
96
- messageId: result?.messageId,
97
- isGroup: params.isGroup,
98
- groupId: params.groupId
99
- });
100
- };
101
- const emitFailed = (content, error) => {
102
- if (params.deferMessageSentHooks) return;
103
- emitSlackMessageSentHooks({
104
- sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
105
- to: params.messageSentHookTarget ?? params.target,
106
- accountId: params.accountId,
107
- content,
108
- success: false,
109
- error: formatErrorMessage(error),
110
- isGroup: params.isGroup,
111
- groupId: params.groupId
112
- });
113
- };
114
- if (!reply.hasMedia && slackBlocks?.length) {
115
- const trimmed = reply.trimmedText;
116
- if (!trimmed && !slackBlocks?.length) continue;
117
- if (trimmed && isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) continue;
118
- let result;
119
- try {
120
- result = await sendMessageSlack(params.target, trimmed, {
121
- cfg: params.cfg,
122
- token: params.token,
123
- threadTs,
124
- accountId: params.accountId,
125
- ...slackBlocks?.length ? { blocks: slackBlocks } : {},
126
- ...params.identity ? { identity: params.identity } : {},
127
- ...params.metadata ? { metadata: params.metadata } : {}
128
- });
129
- } catch (error) {
130
- emitFailed(trimmed, error);
131
- throw error;
132
- }
133
- emitSent(trimmed, result);
134
- latestResult = result;
135
- params.runtime.log?.(`delivered reply to ${params.target}`);
136
- continue;
137
- }
138
- const spokenText = resolveSlackMediaHookSpokenText(payload);
139
- const mediaHookContent = reply.hasText ? reply.text : spokenText || reply.text;
140
- const hookContent = reply.hasMedia ? mediaHookContent : reply.trimmedText;
141
- let lastResult;
142
- let delivered;
143
- try {
144
- delivered = await deliverTextOrMediaReply({
145
- payload,
146
- text: reply.text,
147
- chunkText: !reply.hasMedia ? (value) => {
148
- const trimmed = value.trim();
149
- if (!trimmed || isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) return [];
150
- return [trimmed];
151
- } : void 0,
152
- sendText: async (trimmed) => {
153
- lastResult = await sendMessageSlack(params.target, trimmed, {
154
- cfg: params.cfg,
155
- token: params.token,
156
- threadTs,
157
- accountId: params.accountId,
158
- ...params.identity ? { identity: params.identity } : {},
159
- ...params.metadata ? { metadata: params.metadata } : {}
160
- });
161
- },
162
- sendMedia: async ({ mediaUrl, caption }) => {
163
- lastResult = await sendMessageSlack(params.target, caption ?? "", {
164
- cfg: params.cfg,
165
- token: params.token,
166
- mediaUrl,
167
- threadTs,
168
- accountId: params.accountId,
169
- ...params.identity ? { identity: params.identity } : {},
170
- ...params.metadata ? { metadata: params.metadata } : {}
171
- });
172
- }
173
- });
174
- } catch (error) {
175
- emitFailed(hookContent, error);
176
- throw error;
177
- }
178
- if (delivered !== "empty") {
179
- emitSent(hookContent, reply.hasMedia ? void 0 : lastResult);
180
- latestResult = lastResult;
181
- params.runtime.log?.(`delivered reply to ${params.target}`);
182
- }
183
- }
184
- return latestResult;
185
- }
186
- /**
187
- * Compute effective threadTs for a Slack reply based on replyToMode.
188
- * - "off": stay in thread if already in one, otherwise main channel
189
- * - "first": first reply goes to thread, subsequent replies to main channel
190
- * - "all": all replies go to thread
191
- */
192
- function resolveSlackThreadTs(params) {
193
- return createSlackReplyReferencePlanner({
194
- replyToMode: params.replyToMode,
195
- incomingThreadTs: params.incomingThreadTs,
196
- messageTs: params.messageTs,
197
- hasReplied: params.hasReplied,
198
- isThreadReply: params.isThreadReply
199
- }).use();
200
- }
201
- function createSlackReplyReferencePlanner(params) {
202
- return createReplyReferencePlanner({
203
- replyToMode: params.isThreadReply ?? Boolean(params.incomingThreadTs && params.incomingThreadTs !== params.messageTs) ? "all" : params.replyToMode,
204
- existingId: params.incomingThreadTs,
205
- startId: params.messageTs,
206
- hasReplied: params.hasReplied
207
- });
208
- }
209
- function createSlackReplyDeliveryPlan(params) {
210
- const replyReference = createSlackReplyReferencePlanner({
211
- replyToMode: params.replyToMode,
212
- incomingThreadTs: params.incomingThreadTs,
213
- messageTs: params.messageTs,
214
- hasReplied: params.hasRepliedRef.value,
215
- isThreadReply: params.isThreadReply
216
- });
217
- return {
218
- peekThreadTs: () => replyReference.peek(),
219
- nextThreadTs: () => replyReference.use(),
220
- markSent: () => {
221
- replyReference.markSent();
222
- params.hasRepliedRef.value = replyReference.hasReplied();
223
- }
224
- };
225
- }
226
- async function deliverSlackSlashReplies(params) {
227
- const deliveries = [];
228
- const chunkLimit = Math.min(params.textLimit, SLACK_TEXT_LIMIT);
229
- for (const payload of params.replies) {
230
- if (payload.isReasoning === true) continue;
231
- const reply = resolveSendableOutboundReplyParts(payload);
232
- const slackBlocks = readSlackReplyBlocks(payload);
233
- const text = reply.hasText && !isSilentReplyText(reply.trimmedText, SILENT_REPLY_TOKEN) ? reply.trimmedText : void 0;
234
- if (slackBlocks?.length && !reply.hasMedia) {
235
- deliveries.push({
236
- hookContent: text ?? "",
237
- messages: [{
238
- text: text ?? "",
239
- blocks: slackBlocks
240
- }]
241
- });
242
- continue;
243
- }
244
- const combined = [text ?? "", ...reply.mediaUrls].filter(Boolean).join("\n");
245
- if (!combined) continue;
246
- const chunkMode = params.chunkMode ?? "length";
247
- const chunks = (chunkMode === "newline" ? chunkMarkdownTextWithMode(combined, chunkLimit, chunkMode) : [combined]).flatMap((markdown) => markdownToSlackMrkdwnChunks(markdown, chunkLimit, { tableMode: params.tableMode }));
248
- if (!chunks.length && combined) chunks.push(combined);
249
- deliveries.push({
250
- hookContent: text ?? resolveSlackMediaHookSpokenText(payload) ?? combined,
251
- messages: chunks.map((chunk) => ({ text: chunk }))
252
- });
253
- }
254
- if (deliveries.length === 0) return;
255
- const responseType = params.ephemeral ? "ephemeral" : "in_channel";
256
- for (const delivery of deliveries) {
257
- try {
258
- for (const message of delivery.messages) await params.respond({
259
- ...message,
260
- response_type: responseType
261
- });
262
- } catch (error) {
263
- if (params.messageSentHookTarget) emitSlackMessageSentHooks({
264
- sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
265
- to: params.messageSentHookTarget,
266
- accountId: params.accountId,
267
- content: delivery.hookContent,
268
- success: false,
269
- error: formatErrorMessage(error),
270
- isGroup: params.isGroup,
271
- groupId: params.groupId
272
- });
273
- throw error;
274
- }
275
- if (params.messageSentHookTarget) emitSlackMessageSentHooks({
276
- sessionKeyForInternalHooks: params.sessionKeyForInternalHooks,
277
- to: params.messageSentHookTarget,
278
- accountId: params.accountId,
279
- content: delivery.hookContent,
280
- success: true,
281
- isGroup: params.isGroup,
282
- groupId: params.groupId
283
- });
284
- }
285
- }
286
- //#endregion
287
- export { resolveDeliveredSlackReplyThreadTs as a, readSlackReplyBlocks as i, deliverReplies as n, resolveSlackThreadTs as o, deliverSlackSlashReplies as r, emitSlackMessageSentHooks as s, createSlackReplyDeliveryPlan as t };