@openclaw/slack 2026.9.7 → 2026.10.1-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.
- package/dist/.setup/{account-inspect-DWBXpER6.mjs → account-inspect-Cs-7DXXW.mjs} +1 -1
- package/dist/.setup/{accounts-D_N9IqNA.mjs → accounts-CDgkV7Cm.mjs} +4 -16
- package/dist/.setup/{action-runtime-DfWvuiZd.mjs → action-runtime-DJ1daRAZ.mjs} +5 -7
- package/dist/.setup/action-runtime.runtime-CdWL2mLC.mjs +2 -0
- package/dist/.setup/{actions-Df0CzcDl.mjs → actions-DDoAJnrH.mjs} +16 -35
- package/dist/.setup/{approval-handler.runtime-Ed6Sw5VK.mjs → approval-handler.runtime-BcE_shWc.mjs} +5 -5
- package/dist/.setup/{approval-message-updates-BadvtA7R.mjs → approval-message-updates-EgKGmFXx.mjs} +1 -1
- package/dist/.setup/{channel-C7bgPSTE.mjs → channel-DgKSu8Iv.mjs} +46 -48
- package/dist/.setup/{channel-type-ClOttrZ5.mjs → channel-type-B9zYYzBU.mjs} +4 -4
- package/dist/.setup/{channel.setup-Dh2jzAjN.mjs → channel.setup-BYIlwbQ7.mjs} +27 -27
- package/dist/.setup/{config-schema-BZCxmHKG.mjs → config-schema-BH0K9-Um.mjs} +4 -0
- package/dist/.setup/{directory-config-BOUWH3hR.mjs → directory-config-B_by7zrc.mjs} +2 -2
- package/dist/.setup/{directory-live-B2O4B_Ho.mjs → directory-live-C48wazJt.mjs} +3 -3
- package/dist/.setup/{doctor-contract-CRN1Z_c7.mjs → doctor-contract-Cd4-VzIM.mjs} +28 -28
- package/dist/.setup/{message-tool-api-Cu4lwlGy.mjs → message-tool-api-CcjLPN3v.mjs} +2 -2
- package/dist/.setup/{monitor-BPVfkumU.mjs → monitor-BuYBDmm7.mjs} +190 -315
- package/dist/.setup/{outbound-adapter-Bv48XUjq.mjs → outbound-adapter-BZFkK-mw.mjs} +6 -17
- package/dist/.setup/{pipeline.runtime-B1H63Frf.mjs → pipeline.runtime-CIepKmZt.mjs} +241 -247
- package/dist/.setup/{policy-D-jfM174.mjs → policy-KKTqEiDv.mjs} +12 -22
- package/dist/.setup/{probe-B2Y9qc_z.mjs → probe-BVlJ3dp0.mjs} +4 -7
- package/dist/.setup/{relay-source-BpKdjsll.mjs → relay-source-CC3h6M7y.mjs} +2 -2
- package/dist/.setup/{replies-BAnUtr2f.mjs → replies-DHbuthIR.mjs} +12 -26
- package/dist/.setup/{reply-blocks-SE1kTE3I.mjs → reply-blocks-CKnO4BSG.mjs} +4 -29
- package/dist/.setup/{resolve-channels-XXBn8UU_.mjs → resolve-channels-HR0TgArR.mjs} +2 -2
- package/dist/.setup/{resolve-users-DW0ngD03.mjs → resolve-users-BNYBhF0q.mjs} +4 -4
- package/dist/.setup/rolldown-runtime-B4FMCO8f.mjs +28 -0
- package/dist/.setup/{scopes-CasuDvaa.mjs → scopes-DrDbyUH2.mjs} +1 -1
- package/dist/.setup/secret-contract-B-Qm6aQQ.mjs +65 -0
- package/dist/.setup/{secret-contract-api-Dp6290Vg.mjs → secret-contract-api-DmUVxIRs.mjs} +1 -1
- package/dist/.setup/{security-audit-BqDc-6VL.mjs → security-audit-C1nOGzJa.mjs} +1 -1
- package/dist/.setup/{send-BOVLQi3n.mjs → send-CgPI3Zj8.mjs} +22 -53
- package/dist/.setup/{session-status-DscajIsd.mjs → session-status-D46GHwOV.mjs} +39 -49
- package/dist/.setup/{setup-plugin-api-DTtbTKNk.mjs → setup-plugin-api-ZrHs0N4U.mjs} +1 -1
- package/dist/.setup/{setup-surface-Dn7QgWRE.mjs → setup-surface-83lxvE2y.mjs} +10 -13
- package/dist/.setup/{shared-qau-uDGl.mjs → shared-VtmYNj-v.mjs} +53 -57
- package/dist/.setup/{slash-dispatch.runtime--AEzLVBF.mjs → slash-dispatch.runtime-gBj_uaLM.mjs} +1 -1
- package/dist/account-inspect-api.js +1 -1
- package/dist/api.js +13 -13
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/control-ui/2f4b1e827be6b68ced2ea0d8b7da8529a4eafbe72be27ee37e1064bdd530ec10/index.js +1 -0
- package/dist/directory-contract-api.js +1 -1
- package/dist/doctor-contract-api.js +1 -1
- package/dist/message-tool-api.js +1 -1
- package/dist/runtime-api.js +10 -10
- package/dist/secret-contract-api.js +1 -1
- package/dist/security-contract-api.js +1 -1
- package/dist/setup-entry.js +2 -2
- package/dist/setup-plugin-api.js +1 -1
- package/node_modules/undici/README.md +10 -1
- package/node_modules/undici/docs/docs/api/Agent.md +8 -8
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +9 -6
- package/node_modules/undici/docs/docs/api/Dispatcher.md +9 -0
- package/node_modules/undici/docs/docs/api/Errors.md +25 -0
- package/node_modules/undici/docs/docs/api/Fetch.md +10 -0
- package/node_modules/undici/docs/docs/api/Interceptors.md +4 -3
- package/node_modules/undici/docs/docs/api/Pool.md +5 -6
- package/node_modules/undici/docs/docs/index.md +10 -1
- package/node_modules/undici/lib/api/readable.js +1 -2
- package/node_modules/undici/lib/core/request.js +23 -2
- package/node_modules/undici/lib/core/util.js +0 -39
- package/node_modules/undici/lib/dispatcher/client-h1.js +11 -4
- package/node_modules/undici/lib/dispatcher/client-h2.js +52 -8
- package/node_modules/undici/lib/dispatcher/client.js +6 -1
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +21 -6
- package/node_modules/undici/lib/dispatcher/pool-base.js +63 -2
- package/node_modules/undici/lib/dispatcher/pool.js +90 -7
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +16 -3
- package/node_modules/undici/lib/handler/deduplication-handler.js +24 -11
- package/node_modules/undici/lib/handler/redirect-handler.js +5 -0
- package/node_modules/undici/lib/handler/retry-handler.js +72 -13
- package/node_modules/undici/lib/interceptor/cache.js +4 -1
- package/node_modules/undici/lib/interceptor/decompress.js +236 -69
- package/node_modules/undici/lib/web/cache/cache.js +17 -8
- package/node_modules/undici/lib/web/cache/cachestorage.js +11 -5
- package/node_modules/undici/lib/web/cookies/index.js +19 -7
- package/node_modules/undici/lib/web/cookies/util.js +3 -1
- package/node_modules/undici/lib/web/eventsource/eventsource.js +25 -1
- package/node_modules/undici/lib/web/fetch/body.js +22 -15
- package/node_modules/undici/lib/web/fetch/data-url.js +6 -6
- package/node_modules/undici/lib/web/fetch/formdata.js +30 -36
- package/node_modules/undici/lib/web/fetch/headers.js +34 -31
- package/node_modules/undici/lib/web/fetch/index.js +46 -25
- package/node_modules/undici/lib/web/fetch/request.js +74 -79
- package/node_modules/undici/lib/web/fetch/response.js +43 -44
- package/node_modules/undici/lib/web/fetch/util.js +7 -7
- package/node_modules/undici/lib/web/infra/index.js +16 -1
- package/node_modules/undici/lib/web/webidl/index.js +2 -14
- package/node_modules/undici/lib/web/websocket/connection.js +33 -12
- package/node_modules/undici/lib/web/websocket/events.js +43 -26
- package/node_modules/undici/lib/web/websocket/receiver.js +2 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +13 -10
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +19 -4
- package/node_modules/undici/lib/web/websocket/websocket.js +44 -41
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/diagnostics-channel.d.ts +2 -1
- package/node_modules/undici/types/interceptors.d.ts +1 -1
- package/node_modules/undici/types/webidl.d.ts +13 -7
- package/openclaw.plugin.json +4 -1
- package/package.json +14 -6
- package/dist/.setup/action-runtime.runtime-Ck4bAWOX.mjs +0 -2
- package/dist/.setup/secret-contract-BaZcu6P_.mjs +0 -82
- package/dist/.setup/streaming-compat-C5Wut626.mjs +0 -62
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { f as resolveSlackReplyToMode } from "./accounts-
|
|
1
|
+
import { n as __reExport, t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
|
|
2
|
+
import { f as resolveSlackReplyToMode } from "./accounts-CDgkV7Cm.mjs";
|
|
3
3
|
import { n as formatSlackTarget } from "./target-parsing-FFE26kOV.mjs";
|
|
4
|
-
import { A as countSlackTextUtf8Bytes, C as buildSlackBlocksFallbackText, E as SLACK_EDIT_TEXT_MAX_BYTES,
|
|
5
|
-
import { D as normalizeSlackAllowOwnerEntry, j as resolveSlackUserAllowed, o as formatSlackError, v as readLruMapEntry, y as writeLruMapEntry } from "./probe-
|
|
6
|
-
import { a as prepareSlackReply, l as resolveSlackReplyRenderPlan, s as resolveSlackReplyBlocks } from "./reply-blocks-
|
|
4
|
+
import { A as countSlackTextUtf8Bytes, C as buildSlackBlocksFallbackText, E as SLACK_EDIT_TEXT_MAX_BYTES, M as truncateSlackTextByUtf8Bytes, Y as normalizeSlackOutboundText, c as qualifySlackRoutePeerId, j as truncateSlackText, k as SLACK_TEXT_LIMIT, ot as escapeSlackMrkdwn, v as hasSlackNativeDataBlock, w as buildSlackCompleteBlocksFallbackText, z as SLACK_SESSION_LINK_ACTION_ID } from "./session-status-D46GHwOV.mjs";
|
|
5
|
+
import { D as normalizeSlackAllowOwnerEntry, j as resolveSlackUserAllowed, o as formatSlackError, v as readLruMapEntry, y as writeLruMapEntry } from "./probe-BVlJ3dp0.mjs";
|
|
6
|
+
import { a as prepareSlackReply, l as resolveSlackReplyRenderPlan, s as resolveSlackReplyBlocks } from "./reply-blocks-CKnO4BSG.mjs";
|
|
7
7
|
import { n as resolveSlackReplyThreadTs } from "./thread-ts-Cvt7WD6B.mjs";
|
|
8
|
-
import { C as hasSlackTableBlock, D as buildSlackEditTextPayload, E as resolveSlackMessageText$1, T as resolveSlackBlocksText, a as editSlackRenderedMessage, b as formatSlackFileReference, d as reactSlackMessage, i as editSlackMessage, m as removeSlackReaction, n as deleteSlackMessage, w as isSlackUnfurlAttachment, x as formatSlackFileReferenceList } from "./actions-
|
|
9
|
-
import { c as hasSlackThreadParticipationWithPersistence, i as clearSlackThreadFailureNotice, l as recordSlackThreadFailureNotice, o as hasSlackThreadFailureNotice, p as
|
|
10
|
-
import { n as resolveSlackChannelConfig } from "./policy-
|
|
11
|
-
import { C as resolveSlackChatType, E as stripSlackMentionsForCommandDetection, S as normalizeSlackChannelType, T as readSlackAssistantThreadContext, _ as appendSlackStream, b as stopSlackStream, c as resolveSlackRoutingContext, g as SlackStreamNotDeliveredError, h as resolveSlackEffectiveAllowFrom, i as resolveSlackRoomContextHints, l as registerSlackSessionRun, m as resolveSlackCommandIngress, p as authorizeSlackBotRoomMessage, r as trackSlackDraftMessage, s as authorizeSlackDirectMessage, u as resolveSlackThreadContext, v as markSlackStreamFallbackDelivered, w as buildSlackAssistantThreadMetadata, y as startSlackStream } from "./monitor-
|
|
12
|
-
import { a as emitSlackMessageSentHooks, i as sanitizeSlackMonitorReplyPayload, n as deliverReplies, t as createSlackReplyDeliveryPlan } from "./replies-
|
|
8
|
+
import { C as hasSlackTableBlock, D as buildSlackEditTextPayload, E as resolveSlackMessageText$1, T as resolveSlackBlocksText, a as editSlackRenderedMessage, b as formatSlackFileReference, d as reactSlackMessage, i as editSlackMessage, m as removeSlackReaction, n as deleteSlackMessage, w as isSlackUnfurlAttachment, x as formatSlackFileReferenceList } from "./actions-DDoAJnrH.mjs";
|
|
9
|
+
import { c as hasSlackThreadParticipationWithPersistence, i as clearSlackThreadFailureNotice, l as recordSlackThreadFailureNotice, m as buildSlackNativeDataDeliveryPlan, o as hasSlackThreadFailureNotice, p as hasSlackMessageIdentity, s as hasSlackThreadParticipation, t as sendMessageSlack, u as recordSlackThreadParticipation } from "./send-CgPI3Zj8.mjs";
|
|
10
|
+
import { n as resolveSlackChannelConfig } from "./policy-KKTqEiDv.mjs";
|
|
11
|
+
import { C as resolveSlackChatType, E as stripSlackMentionsForCommandDetection, S as normalizeSlackChannelType, T as readSlackAssistantThreadContext, _ as appendSlackStream, b as stopSlackStream, c as resolveSlackRoutingContext, g as SlackStreamNotDeliveredError, h as resolveSlackEffectiveAllowFrom, i as resolveSlackRoomContextHints, l as registerSlackSessionRun, m as resolveSlackCommandIngress, p as authorizeSlackBotRoomMessage, r as trackSlackDraftMessage, s as authorizeSlackDirectMessage, u as resolveSlackThreadContext, v as markSlackStreamFallbackDelivered, w as buildSlackAssistantThreadMetadata, y as startSlackStream } from "./monitor-BuYBDmm7.mjs";
|
|
12
|
+
import { a as emitSlackMessageSentHooks, i as sanitizeSlackMonitorReplyPayload, n as deliverReplies, t as createSlackReplyDeliveryPlan } from "./replies-DHbuthIR.mjs";
|
|
13
13
|
import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readNonBlankString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
14
14
|
import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
|
|
15
|
-
import { buildChannelProgressDraftLine, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createChannelProgressWorkCounter, createDraftStreamLoop, createFinalizableDraftLifecycle, createLivePreviewLifecycle, createMessageReceiptFromOutboundResults,
|
|
15
|
+
import { buildChannelProgressDraftLine, compactChannelProgressDraftLine, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createChannelProgressWorkCounter, createDraftStreamLoop, createFinalizableDraftLifecycle, createLivePreviewLifecycle, createMessageReceiptFromOutboundResults, resolveAgentOutboundIdentity, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelProgressDraftConfig, resolveChannelProgressDraftMaxLineChars, resolveChannelStreamingBlockEnabled, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages, selectPlanChecklistSteps } from "openclaw/plugin-sdk/channel-outbound";
|
|
16
16
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
17
17
|
import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
|
18
18
|
import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
|
|
@@ -29,7 +29,7 @@ import fs from "node:fs/promises";
|
|
|
29
29
|
import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
|
|
30
30
|
import { formatErrorMessage, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
31
31
|
import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist, shouldIncludeSupplementalContext } from "openclaw/plugin-sdk/security-runtime";
|
|
32
|
-
import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
|
|
32
|
+
import { mimeTypeFromFilePath, normalizeMimeType } from "openclaw/plugin-sdk/media-mime";
|
|
33
33
|
import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
|
|
34
34
|
import { getSessionEntry, readSessionUpdatedAt, resolveChannelResetConfig, resolveStorePath, updateLastRoute } from "openclaw/plugin-sdk/session-store-runtime";
|
|
35
35
|
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
|
|
@@ -80,10 +80,6 @@ function isSlackStreamingEnabled(params) {
|
|
|
80
80
|
if (params.mode === "progress") return params.nativeStreaming && params.nativeProgressTaskCards === true;
|
|
81
81
|
return false;
|
|
82
82
|
}
|
|
83
|
-
function resolveSlackDisableBlockStreaming(params) {
|
|
84
|
-
if (params.useStreaming || params.shouldUseDraftStream) return true;
|
|
85
|
-
return typeof params.blockStreamingEnabled === "boolean" ? !params.blockStreamingEnabled : void 0;
|
|
86
|
-
}
|
|
87
83
|
function resolveExplicitSlackProgressTitle(entry) {
|
|
88
84
|
const label = resolveChannelProgressDraftConfig(entry).label;
|
|
89
85
|
if (typeof label !== "string") return;
|
|
@@ -135,14 +131,6 @@ function createSlackEventDeliveryTracker() {
|
|
|
135
131
|
}
|
|
136
132
|
};
|
|
137
133
|
}
|
|
138
|
-
function shouldUseStreaming(params) {
|
|
139
|
-
if (!params.streamingEnabled) return false;
|
|
140
|
-
if (!params.threadTs) {
|
|
141
|
-
logVerbose("slack-stream: streaming disabled — no reply thread target available");
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
return true;
|
|
145
|
-
}
|
|
146
134
|
async function resolveSlackStreamRecipientTeamId(params) {
|
|
147
135
|
const cacheKey = params.fallbackTeamId && params.userId ? `${params.fallbackTeamId}:${params.userId}` : void 0;
|
|
148
136
|
const cache = cacheKey ? getSlackStreamRecipientTeamCache(params.client) : void 0;
|
|
@@ -173,7 +161,6 @@ function createSlackDraftStream(params) {
|
|
|
173
161
|
const edit = params.edit ?? editSlackMessage;
|
|
174
162
|
const remove = params.remove ?? deleteSlackMessage;
|
|
175
163
|
let streamMessage;
|
|
176
|
-
let streamGeneration = 0;
|
|
177
164
|
let cleanupGeneration = -1;
|
|
178
165
|
let untrackConversationBoundary;
|
|
179
166
|
let lastVisibleUpdate;
|
|
@@ -190,7 +177,6 @@ function createSlackDraftStream(params) {
|
|
|
190
177
|
lastSentKey = "";
|
|
191
178
|
};
|
|
192
179
|
const sendOrEditStreamMessage = async (pending) => {
|
|
193
|
-
if (streamState.stopped) return;
|
|
194
180
|
const update = normalizeUpdate(pending);
|
|
195
181
|
const trimmed = update.text.trimEnd();
|
|
196
182
|
if (!trimmed) return;
|
|
@@ -204,7 +190,7 @@ function createSlackDraftStream(params) {
|
|
|
204
190
|
const sentKey = `${trimmed}\n${blocks ? JSON.stringify(blocks) : ""}`;
|
|
205
191
|
if (sentKey === lastSentKey) return;
|
|
206
192
|
lastSentKey = sentKey;
|
|
207
|
-
const generation =
|
|
193
|
+
const generation = lifecycle.generation;
|
|
208
194
|
try {
|
|
209
195
|
if (streamMessage) {
|
|
210
196
|
const message = streamMessage;
|
|
@@ -222,58 +208,54 @@ function createSlackDraftStream(params) {
|
|
|
222
208
|
return;
|
|
223
209
|
}
|
|
224
210
|
const threadTs = params.resolveThreadTs?.();
|
|
225
|
-
const
|
|
211
|
+
const trackMessage = (channelId, messageTs) => trackSlackDraftMessage({
|
|
226
212
|
accountId: params.accountId,
|
|
227
213
|
teamId: params.eventScope?.teamId,
|
|
228
|
-
channelId
|
|
214
|
+
channelId,
|
|
229
215
|
threadTs,
|
|
216
|
+
messageTs,
|
|
230
217
|
onInterveningMessage: () => forceNewMessage("human")
|
|
231
|
-
}) : void 0;
|
|
232
|
-
untrackConversationBoundary = pendingBoundary?.stop;
|
|
233
|
-
const sent = await send(params.target, trimmed, {
|
|
234
|
-
cfg: params.cfg,
|
|
235
|
-
token: params.token,
|
|
236
|
-
accountId: params.accountId,
|
|
237
|
-
threadTs,
|
|
238
|
-
identity: params.identity,
|
|
239
|
-
eventScope: params.eventScope,
|
|
240
|
-
...params.metadata ? { metadata: params.metadata } : {},
|
|
241
|
-
...blocks ? { blocks } : {}
|
|
242
218
|
});
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (sent.channelId && sent.messageId) lifecycle.retire(sentMessage, { defer: true });
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
if (!sent.channelId || !sent.messageId) {
|
|
253
|
-
stopTrackingConversationBoundary();
|
|
254
|
-
streamState.stopped = true;
|
|
255
|
-
params.warn?.("slack stream preview stopped (missing identifiers from sendMessage)");
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
258
|
-
streamMessage = sentMessage;
|
|
259
|
-
lastVisibleUpdate = {
|
|
260
|
-
text: trimmed,
|
|
261
|
-
...blocks ? { blocks } : {}
|
|
262
|
-
};
|
|
263
|
-
if (pendingBoundary && params.conversationChannelId === streamMessage.channelId) pendingBoundary.setMessageTs(streamMessage.messageId);
|
|
264
|
-
else {
|
|
265
|
-
stopTrackingConversationBoundary();
|
|
266
|
-
untrackConversationBoundary = trackSlackDraftMessage({
|
|
219
|
+
const pendingBoundary = params.conversationChannelId ? trackMessage(params.conversationChannelId) : void 0;
|
|
220
|
+
untrackConversationBoundary = pendingBoundary?.stop;
|
|
221
|
+
await lifecycle.createMessage(async () => {
|
|
222
|
+
const sent = await send(params.target, trimmed, {
|
|
223
|
+
cfg: params.cfg,
|
|
224
|
+
token: params.token,
|
|
267
225
|
accountId: params.accountId,
|
|
268
|
-
teamId: params.eventScope?.teamId,
|
|
269
|
-
channelId: streamMessage.channelId,
|
|
270
226
|
threadTs,
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
227
|
+
identity: params.identity,
|
|
228
|
+
eventScope: params.eventScope,
|
|
229
|
+
...params.metadata ? { metadata: params.metadata } : {},
|
|
230
|
+
...blocks ? { blocks } : {}
|
|
231
|
+
});
|
|
232
|
+
return sent.channelId && sent.messageId ? {
|
|
233
|
+
channelId: sent.channelId,
|
|
234
|
+
messageId: sent.messageId,
|
|
235
|
+
generation
|
|
236
|
+
} : void 0;
|
|
237
|
+
}, (sentMessage) => {
|
|
238
|
+
if (!sentMessage) {
|
|
239
|
+
stopTrackingConversationBoundary();
|
|
240
|
+
streamState.stopped = true;
|
|
241
|
+
params.warn?.("slack stream preview stopped (missing identifiers from sendMessage)");
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
const { channelId, messageId } = sentMessage;
|
|
245
|
+
streamMessage = sentMessage;
|
|
246
|
+
lastVisibleUpdate = {
|
|
247
|
+
text: trimmed,
|
|
248
|
+
...blocks ? { blocks } : {}
|
|
249
|
+
};
|
|
250
|
+
if (pendingBoundary && params.conversationChannelId === channelId) pendingBoundary.setMessageTs(messageId);
|
|
251
|
+
else {
|
|
252
|
+
stopTrackingConversationBoundary();
|
|
253
|
+
untrackConversationBoundary = trackMessage(channelId, messageId).stop;
|
|
254
|
+
}
|
|
255
|
+
return true;
|
|
256
|
+
}, { defer: true });
|
|
275
257
|
} catch (err) {
|
|
276
|
-
if (generation ===
|
|
258
|
+
if (generation === lifecycle.generation) {
|
|
277
259
|
stopTrackingConversationBoundary();
|
|
278
260
|
streamState.stopped = true;
|
|
279
261
|
}
|
|
@@ -308,24 +290,24 @@ function createSlackDraftStream(params) {
|
|
|
308
290
|
untrackConversationBoundary = void 0;
|
|
309
291
|
};
|
|
310
292
|
const dropDetachedMessages = () => {
|
|
311
|
-
const generation =
|
|
293
|
+
const generation = lifecycle.generation;
|
|
312
294
|
return lifecycle.cleanupPending(() => {
|
|
313
295
|
preserveHumanReplies = false;
|
|
314
296
|
cleanupGeneration = generation;
|
|
315
297
|
});
|
|
316
298
|
};
|
|
317
299
|
const discardPendingAndStopTracking = async () => {
|
|
318
|
-
const generation =
|
|
300
|
+
const generation = lifecycle.generation;
|
|
319
301
|
await discardPending();
|
|
320
|
-
if (generation ===
|
|
302
|
+
if (generation === lifecycle.generation) stopTrackingConversationBoundary();
|
|
321
303
|
};
|
|
322
304
|
const clear = async (options) => {
|
|
323
|
-
const generation =
|
|
305
|
+
const generation = lifecycle.generation;
|
|
324
306
|
let clearingMessage = streamMessage;
|
|
325
307
|
await lifecycle.clearWithStop(async () => {
|
|
326
|
-
if (generation ===
|
|
308
|
+
if (generation === lifecycle.generation) {
|
|
327
309
|
await discardPendingAndStopTracking();
|
|
328
|
-
if (generation ===
|
|
310
|
+
if (generation === lifecycle.generation) {
|
|
329
311
|
clearingMessage = streamMessage;
|
|
330
312
|
clearMessageId();
|
|
331
313
|
}
|
|
@@ -341,17 +323,15 @@ function createSlackDraftStream(params) {
|
|
|
341
323
|
};
|
|
342
324
|
const forceNewMessage = (reason = "turn") => {
|
|
343
325
|
stopTrackingConversationBoundary();
|
|
344
|
-
if (reason === "turn") {
|
|
345
|
-
streamState.stopped = false;
|
|
346
|
-
streamGeneration += 1;
|
|
347
|
-
}
|
|
348
|
-
streamState.final = false;
|
|
349
326
|
if (streamMessage && !streamMessage.retained) {
|
|
350
327
|
streamMessage.detachedByHuman = reason === "human";
|
|
351
328
|
lifecycle.retire(streamMessage, { defer: true });
|
|
352
329
|
}
|
|
353
|
-
|
|
354
|
-
|
|
330
|
+
if (reason === "turn") lifecycle.reset("discard", "keep");
|
|
331
|
+
else {
|
|
332
|
+
streamState.final = false;
|
|
333
|
+
lifecycle.resetMessage("keep");
|
|
334
|
+
}
|
|
355
335
|
};
|
|
356
336
|
const finalizeMessage = async (messageId, editFinal) => {
|
|
357
337
|
const currentMessage = streamMessage;
|
|
@@ -395,8 +375,8 @@ function createSlackDraftStream(params) {
|
|
|
395
375
|
//#region extensions/slack/src/stream-mode.ts
|
|
396
376
|
function resolveSlackStreamingConfig(params) {
|
|
397
377
|
return {
|
|
398
|
-
mode:
|
|
399
|
-
nativeStreaming:
|
|
378
|
+
mode: params.streaming?.mode ?? "progress",
|
|
379
|
+
nativeStreaming: params.streaming?.nativeTransport ?? true
|
|
400
380
|
};
|
|
401
381
|
}
|
|
402
382
|
function applyAppendOnlyStreamUpdate(params) {
|
|
@@ -512,12 +492,6 @@ function renderProgressCardText(text, enclosingStyle) {
|
|
|
512
492
|
function lineDetailParts(line) {
|
|
513
493
|
return [line.detail, line.status && line.status !== "completed" && !line.detail?.includes(line.status) ? line.status : void 0].map((part) => part?.trim()).filter((part) => Boolean(part));
|
|
514
494
|
}
|
|
515
|
-
function activityLineDetail(line, maxChars) {
|
|
516
|
-
const detail = lineDetailParts(line).join(" · ");
|
|
517
|
-
if (detail) return escapeSlackMrkdwn(compactDetail(detail, maxChars));
|
|
518
|
-
const text = line.text.replace(/^(?:🧠|💬)\s+/u, "").trim();
|
|
519
|
-
return line.kind === "item" && !line.toolName && text && text !== line.label ? renderProgressCardText(compactDetail(text, maxChars)) : "—";
|
|
520
|
-
}
|
|
521
495
|
function lineTaskTitle(line) {
|
|
522
496
|
const label = line.label.replace(/\s+/g, " ").trim() || line.toolName || line.kind || "Update";
|
|
523
497
|
const fallback = line.text.replace(/\s+/g, " ").trim();
|
|
@@ -660,53 +634,63 @@ function joinRecentProgressRows(rows) {
|
|
|
660
634
|
}
|
|
661
635
|
function buildActivityText(lines, maxLineChars) {
|
|
662
636
|
return joinRecentProgressRows(lines.slice(-50).map((line) => {
|
|
663
|
-
|
|
637
|
+
if (line.kind === "item" && !line.toolName) return `_${renderProgressCardText(compactDetail(line.text, maxLineChars), "italic")}_`;
|
|
638
|
+
const detail = compactDetail(lineDetailParts(line).join(" · "), maxLineChars);
|
|
639
|
+
return escapeSlackMrkdwn(detail ? `${line.label} — ${detail}` : line.label);
|
|
664
640
|
}));
|
|
665
641
|
}
|
|
666
642
|
function buildSlackProgressCardBlocks(params) {
|
|
667
643
|
const maxLineChars = resolveMaxLineChars(params.maxLineChars, DEFAULT_SLACK_PROGRESS_DETAIL_MAX_CHARS);
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
text
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
const diffStat =
|
|
644
|
+
const selected = selectPlanChecklistSteps(params.detailed ? params.plan ?? [] : [], { maxLines: 50 });
|
|
645
|
+
const planLines = [...selected.summary ? [selected.summary] : [], ...selected.steps.map(({ step, status }) => `${status === "completed" ? "✓" : status === "in_progress" ? "▸" : "▢"} ${step}`)].map((line) => compactChannelProgressDraftLine(line, maxLineChars));
|
|
646
|
+
const narration = /* @__PURE__ */ new Map();
|
|
647
|
+
for (const part of params.narration ?? []) {
|
|
648
|
+
const text = part.text.replace(/\s+/g, " ").trim();
|
|
649
|
+
if (text) narration.set(text, part.format ?? narration.get(text));
|
|
650
|
+
}
|
|
651
|
+
const lines = params.lines.filter((line) => line.kind === "item" && !line.toolName ? !narration.has(line.text.replace(/^_(.*)_$/gmu, "$1").replace(/\s+/g, " ").trim()) : params.detailed || line.kind === "approval");
|
|
652
|
+
const { diffStat: diff, toolCalls, elapsedSeconds } = params;
|
|
653
|
+
const diffStat = diff && (diff.files || diff.added || diff.removed) ? [
|
|
654
|
+
`${diff.files} ${diff.files === 1 ? "file" : "files"}`,
|
|
655
|
+
...diff.added > 0 ? [`+${diff.added}`] : [],
|
|
656
|
+
...diff.removed > 0 ? [`−${diff.removed}`] : []
|
|
657
|
+
].join(" ") : void 0;
|
|
677
658
|
const workingFooter = [
|
|
678
|
-
...
|
|
659
|
+
...toolCalls && toolCalls > 0 ? [`${toolCalls} ${toolCalls === 1 ? "tool" : "tools"}`] : [],
|
|
679
660
|
...diffStat ? [diffStat] : [],
|
|
680
|
-
...
|
|
661
|
+
...elapsedSeconds && elapsedSeconds > 0 ? [`${elapsedSeconds}s`] : []
|
|
681
662
|
].join(" · ");
|
|
682
663
|
const footer = params.state === "working" ? workingFooter : diffStat;
|
|
683
|
-
const icon = params.state === "working" ? "🔄" : params.state === "success" ? "✅" : "❌";
|
|
684
664
|
const finalStatus = params.state === "working" ? void 0 : params.state === "success" ? "complete" : "error";
|
|
685
|
-
const attention =
|
|
665
|
+
const attention = lines.flatMap((line) => {
|
|
686
666
|
const title = formatProgressAttentionTitle(line, finalStatus);
|
|
687
667
|
return title === void 0 ? [] : [escapeSlackMrkdwn(title)];
|
|
688
668
|
});
|
|
689
669
|
const sections = [
|
|
690
670
|
planLines.map((line) => renderProgressCardText(line)).join("\n"),
|
|
691
|
-
buildActivityText(
|
|
671
|
+
buildActivityText(lines.filter((line) => line.kind !== "approval" && lineTaskStatus(line) !== "error"), maxLineChars),
|
|
692
672
|
joinRecentProgressRows(attention)
|
|
693
673
|
];
|
|
694
|
-
const title = params.title?.trim()
|
|
674
|
+
const title = params.title?.trim();
|
|
695
675
|
const blocks = [
|
|
696
|
-
params.
|
|
697
|
-
text:
|
|
676
|
+
...params.state === "error" ? [progressTextSection({
|
|
677
|
+
text: "Failed",
|
|
698
678
|
format: "plain"
|
|
699
|
-
}) :
|
|
700
|
-
|
|
701
|
-
text:
|
|
702
|
-
|
|
703
|
-
|
|
679
|
+
})] : [],
|
|
680
|
+
...title ? [progressTextSection({
|
|
681
|
+
text: title,
|
|
682
|
+
format: "plain"
|
|
683
|
+
})] : [],
|
|
684
|
+
...[...narration].map(([text, format]) => progressTextSection({
|
|
685
|
+
text,
|
|
686
|
+
format
|
|
687
|
+
}, "italic")),
|
|
704
688
|
...sections.filter(Boolean).map((text) => ({
|
|
705
689
|
type: "section",
|
|
706
690
|
text: field(text)
|
|
707
691
|
}))
|
|
708
692
|
];
|
|
709
|
-
if (footer) blocks.push({
|
|
693
|
+
if (params.detailed && footer) blocks.push({
|
|
710
694
|
type: "context",
|
|
711
695
|
elements: [field(footer)]
|
|
712
696
|
});
|
|
@@ -989,54 +973,63 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
989
973
|
}];
|
|
990
974
|
};
|
|
991
975
|
const resolvePresentation = (snapshot, state) => {
|
|
992
|
-
const
|
|
993
|
-
|
|
994
|
-
const narration = params.explicitTitle ? snapshot.statusHeadlineFormat === "plain" || snapshot.planExplanationFormat === "plain" ? [...snapshot.statusHeadline && (snapshot.statusHeadline !== snapshot.planExplanation || snapshot.statusHeadlineFormat !== snapshot.planExplanationFormat) ? [{
|
|
995
|
-
text: snapshot.statusHeadline,
|
|
976
|
+
const narration = [{
|
|
977
|
+
text: snapshot.statusHeadline ?? "",
|
|
996
978
|
format: snapshot.statusHeadlineFormat
|
|
997
|
-
}
|
|
998
|
-
text: snapshot.planExplanation,
|
|
999
|
-
format: snapshot.planExplanationFormat
|
|
1000
|
-
}] : []] : combineProgressHeadlineAndExplanation(snapshot.statusHeadline, snapshot.planExplanation) : snapshot.planExplanation && (snapshot.planExplanation !== title || snapshot.planExplanationFormat !== titleFormat) ? [{
|
|
1001
|
-
text: snapshot.planExplanation,
|
|
979
|
+
}, {
|
|
980
|
+
text: snapshot.planExplanation ?? "",
|
|
1002
981
|
format: snapshot.planExplanationFormat
|
|
1003
|
-
}]
|
|
1004
|
-
const workCounter = state === "working" ? params.progressWorkCounter : void 0;
|
|
1005
|
-
const sessionLinks = state === "working" ? [] : resolveSessionLinks();
|
|
982
|
+
}];
|
|
1006
983
|
return buildSlackProgressCardBlocks({
|
|
1007
984
|
state,
|
|
1008
|
-
|
|
1009
|
-
|
|
985
|
+
detailed: params.detailed,
|
|
986
|
+
title: params.explicitTitle,
|
|
1010
987
|
narration,
|
|
1011
988
|
plan: snapshot.plan,
|
|
1012
989
|
lines: resolveStructuredProgressLines(snapshot.lines),
|
|
1013
990
|
maxLineChars: params.maxLineChars,
|
|
1014
991
|
diffStat: snapshot.diffStat,
|
|
1015
|
-
toolCalls:
|
|
1016
|
-
elapsedSeconds:
|
|
1017
|
-
sessionLinks
|
|
992
|
+
toolCalls: params.progressWorkCounter?.toolCalls,
|
|
993
|
+
elapsedSeconds: params.progressWorkCounter?.elapsedSeconds,
|
|
994
|
+
sessionLinks: state === "working" ? [] : resolveSessionLinks()
|
|
1018
995
|
});
|
|
1019
996
|
};
|
|
1020
|
-
const
|
|
997
|
+
const resolveCardText = (blocks) => truncateSlackText(buildSlackCompleteBlocksFallbackText(blocks), Math.min(ctx.textLimit, SLACK_TEXT_LIMIT));
|
|
998
|
+
const finalize = async (status, options = {}) => {
|
|
1021
999
|
if (!params.draftStream || !params.enabled) return false;
|
|
1022
1000
|
await params.draftStream.dropDetachedMessages();
|
|
1023
1001
|
const terminalStatus = finalStatus === "error" || status === "error" ? "error" : "success";
|
|
1024
1002
|
if (finalStatus === terminalStatus) return true;
|
|
1025
1003
|
await params.draftStream.flush();
|
|
1026
|
-
const
|
|
1027
|
-
|
|
1004
|
+
const snapshot = options.snapshot ?? params.getSnapshot();
|
|
1005
|
+
let channelId = params.draftStream.channelId();
|
|
1006
|
+
let messageId = params.draftStream.messageId();
|
|
1007
|
+
const blocks = resolvePresentation(snapshot, terminalStatus);
|
|
1008
|
+
if ((!channelId || !messageId) && terminalStatus === "error" && options.postIfMissing) {
|
|
1009
|
+
params.draftStream.update({
|
|
1010
|
+
text: resolveCardText(blocks),
|
|
1011
|
+
blocks
|
|
1012
|
+
});
|
|
1013
|
+
await params.draftStream.flush();
|
|
1014
|
+
channelId = params.draftStream.channelId();
|
|
1015
|
+
messageId = params.draftStream.messageId();
|
|
1016
|
+
}
|
|
1028
1017
|
if (!channelId || !messageId) return false;
|
|
1018
|
+
if (blocks.length === 0) {
|
|
1019
|
+
await params.draftStream.clear();
|
|
1020
|
+
finalStatus = terminalStatus;
|
|
1021
|
+
return true;
|
|
1022
|
+
}
|
|
1029
1023
|
await params.draftStream.seal();
|
|
1030
1024
|
try {
|
|
1031
1025
|
const finalized = await params.draftStream.finalizeMessage(messageId, async () => {
|
|
1032
|
-
const blocks = resolvePresentation(snapshot, terminalStatus);
|
|
1033
1026
|
await finalizeSlackPreviewEdit({
|
|
1034
1027
|
client: slackClient,
|
|
1035
1028
|
token: ctx.botToken,
|
|
1036
1029
|
accountId: account.accountId,
|
|
1037
1030
|
channelId,
|
|
1038
1031
|
messageId,
|
|
1039
|
-
text:
|
|
1032
|
+
text: resolveCardText(blocks),
|
|
1040
1033
|
blocks,
|
|
1041
1034
|
threadTs: params.getThreadTs()
|
|
1042
1035
|
});
|
|
@@ -1054,6 +1047,7 @@ function createSlackDraftProgressCardRuntime(params) {
|
|
|
1054
1047
|
for (const session of sessions) if (!visibleWorkSessions.has(session.sessionKey)) visibleWorkSessions.set(session.sessionKey, session);
|
|
1055
1048
|
},
|
|
1056
1049
|
resolvePresentation,
|
|
1050
|
+
resolveCardText,
|
|
1057
1051
|
finalize,
|
|
1058
1052
|
get hasTerminalized() {
|
|
1059
1053
|
return finalStatus !== void 0;
|
|
@@ -1172,6 +1166,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1172
1166
|
let appendRenderedText = "";
|
|
1173
1167
|
let appendSourceText = "";
|
|
1174
1168
|
let nativeProgressCompletionSent = false;
|
|
1169
|
+
let cardPostRequested = false;
|
|
1175
1170
|
let nativeProgressTerminalStatus = "complete";
|
|
1176
1171
|
let nativeNarrationRenderedText = "";
|
|
1177
1172
|
let nativeNarrationSourceText = "";
|
|
@@ -1197,6 +1192,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1197
1192
|
},
|
|
1198
1193
|
draftStream,
|
|
1199
1194
|
enabled: useDraftProgressCard,
|
|
1195
|
+
detailed: previewToolProgressEnabled,
|
|
1200
1196
|
progressWorkCounter: previewToolProgressEnabled ? progressWorkCounter : void 0,
|
|
1201
1197
|
explicitTitle: explicitProgressTitle,
|
|
1202
1198
|
maxLineChars: progressDraftMaxLineChars,
|
|
@@ -1325,6 +1321,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1325
1321
|
});
|
|
1326
1322
|
const resetProgressTurnState = () => {
|
|
1327
1323
|
progressWorkCounter.reset();
|
|
1324
|
+
cardPostRequested = false;
|
|
1328
1325
|
nativeNarrationRenderedText = "";
|
|
1329
1326
|
nativeNarrationSourceText = "";
|
|
1330
1327
|
};
|
|
@@ -1351,17 +1348,27 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1351
1348
|
const snapshot = options.snapshot;
|
|
1352
1349
|
const latestLine = snapshot.lines.at(-1);
|
|
1353
1350
|
if (preambleOnlyProgress && typeof latestLine === "object" && latestLine.complete === false) return false;
|
|
1351
|
+
const cardBlocks = useDraftProgressCard ? progressCard.resolvePresentation(snapshot, "working") : void 0;
|
|
1352
|
+
if (cardBlocks?.length === 0) {
|
|
1353
|
+
if (cardPostRequested || draftStream.messageId()) {
|
|
1354
|
+
cardPostRequested = false;
|
|
1355
|
+
await draftStream.clear();
|
|
1356
|
+
draftStream.forceNewMessage();
|
|
1357
|
+
}
|
|
1358
|
+
return false;
|
|
1359
|
+
}
|
|
1354
1360
|
draftStream.update(preambleOnlyProgress ? {
|
|
1355
1361
|
text: previewText,
|
|
1356
1362
|
allowNewMessage: typeof latestLine !== "object" || latestLine.complete !== false,
|
|
1357
1363
|
...snapshot.preparedBlocks ? { blocks: buildSlackProgressTextBlocks(snapshot.preparedBlocks) } : {}
|
|
1358
|
-
} :
|
|
1359
|
-
text:
|
|
1360
|
-
blocks:
|
|
1364
|
+
} : cardBlocks ? {
|
|
1365
|
+
text: progressCard.resolveCardText(cardBlocks),
|
|
1366
|
+
blocks: cardBlocks
|
|
1361
1367
|
} : snapshot.preparedBlocks ? {
|
|
1362
1368
|
text: previewText,
|
|
1363
1369
|
blocks: buildSlackProgressTextBlocks(snapshot.preparedBlocks)
|
|
1364
1370
|
} : previewText);
|
|
1371
|
+
if (cardBlocks) cardPostRequested = true;
|
|
1365
1372
|
if (options?.flush) await draftStream.flush();
|
|
1366
1373
|
return Boolean(draftStream.messageId() && draftStream.channelId());
|
|
1367
1374
|
},
|
|
@@ -1370,6 +1377,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1370
1377
|
nativeUpdates.update(true);
|
|
1371
1378
|
await nativeUpdates.flush();
|
|
1372
1379
|
} else {
|
|
1380
|
+
cardPostRequested = false;
|
|
1373
1381
|
await draftStream?.clear();
|
|
1374
1382
|
draftStream?.forceNewMessage();
|
|
1375
1383
|
}
|
|
@@ -1513,7 +1521,7 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1513
1521
|
if (!progressDraft.beginNewTurn(options)) return false;
|
|
1514
1522
|
if (useNativeProgressStreaming) await finishNativeProgressTurn(completionChunks);
|
|
1515
1523
|
else {
|
|
1516
|
-
await progressCard.finalize("success", priorSnapshot);
|
|
1524
|
+
await progressCard.finalize("success", { snapshot: priorSnapshot });
|
|
1517
1525
|
await previewLifecycle.cleanup();
|
|
1518
1526
|
draftStream?.forceNewMessage();
|
|
1519
1527
|
await dropDetachedProgressCards();
|
|
@@ -1572,7 +1580,6 @@ function createSlackProgressRuntime(runtimeParams) {
|
|
|
1572
1580
|
useDraftProgressCard,
|
|
1573
1581
|
useNativeProgressStreaming,
|
|
1574
1582
|
progressDraftActive,
|
|
1575
|
-
previewToolProgressEnabled,
|
|
1576
1583
|
preambleOnlyProgress,
|
|
1577
1584
|
suppressDefaultToolProgressMessages,
|
|
1578
1585
|
progressDraft,
|
|
@@ -1805,15 +1812,14 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1805
1812
|
const modifyingHooksRegistered = (hookRunner?.hasHooks("reply_payload_sending") ?? false) || (hookRunner?.hasHooks("message_sending") ?? false);
|
|
1806
1813
|
const allowPreHookProviderStreaming = !prepared.ctxPayload.GroupThread && !modifyingHooksRegistered;
|
|
1807
1814
|
const previewStreamingEnabled = allowPreHookProviderStreaming && !sourceRepliesAreToolOnly && !quietProgress && slackStreaming.mode !== "off";
|
|
1808
|
-
const hasSlackCustomIdentity =
|
|
1809
|
-
const
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
nativeProgressTaskCards: resolveSlackNativeProgressTaskCards(account.config, slackProgressStyle)
|
|
1814
|
-
}),
|
|
1815
|
-
threadTs: streamThreadHint
|
|
1815
|
+
const hasSlackCustomIdentity = hasSlackMessageIdentity(slackIdentity);
|
|
1816
|
+
const streamingEnabled = !prepared.ctxPayload.GroupThread && !sourceRepliesAreToolOnly && (allowPreHookProviderStreaming || slackStreaming.mode !== "progress") && isSlackStreamingEnabled({
|
|
1817
|
+
mode: slackStreaming.mode,
|
|
1818
|
+
nativeStreaming: slackStreaming.nativeStreaming,
|
|
1819
|
+
nativeProgressTaskCards: resolveSlackNativeProgressTaskCards(account.config, slackProgressStyle)
|
|
1816
1820
|
});
|
|
1821
|
+
const useStreaming = streamingEnabled && Boolean(streamThreadHint);
|
|
1822
|
+
if (streamingEnabled && !streamThreadHint) logVerbose("slack-stream: streaming disabled — no reply thread target available");
|
|
1817
1823
|
const shouldUseDraftStream = previewStreamingEnabled && !useStreaming;
|
|
1818
1824
|
const blockStreamingEnabled = resolveChannelStreamingBlockEnabled(account.config);
|
|
1819
1825
|
return {
|
|
@@ -1852,11 +1858,7 @@ async function createSlackDispatchSetup(prepared) {
|
|
|
1852
1858
|
previewStreamingEnabled,
|
|
1853
1859
|
hasSlackCustomIdentity,
|
|
1854
1860
|
shouldUseDraftStream,
|
|
1855
|
-
disableBlockStreaming: sourceRepliesAreToolOnly || quietProgress ? true :
|
|
1856
|
-
useStreaming,
|
|
1857
|
-
shouldUseDraftStream,
|
|
1858
|
-
blockStreamingEnabled
|
|
1859
|
-
}),
|
|
1861
|
+
disableBlockStreaming: sourceRepliesAreToolOnly || quietProgress || useStreaming || shouldUseDraftStream ? true : typeof blockStreamingEnabled === "boolean" ? !blockStreamingEnabled : void 0,
|
|
1860
1862
|
useStreaming
|
|
1861
1863
|
};
|
|
1862
1864
|
}
|
|
@@ -2473,7 +2475,7 @@ async function dispatchSlackMessageWithSetup(setup, beginSessionRun, turnAdoptio
|
|
|
2473
2475
|
}
|
|
2474
2476
|
await previewLifecycle.cleanup({ failed: Boolean(dispatchError || agentRunFailed) });
|
|
2475
2477
|
if (pendingFailureNotice && anyReplyDelivered) recordSlackThreadFailureNotice(pendingFailureNotice);
|
|
2476
|
-
if (dispatchError || agentRunFailed) await progress.finalizeDraftProgressCard("error");
|
|
2478
|
+
if (dispatchError || agentRunFailed) await progress.finalizeDraftProgressCard("error", { postIfMissing: !anyReplyDelivered });
|
|
2477
2479
|
await progress.dropDetachedProgressCards();
|
|
2478
2480
|
if (statusReactionsEnabled) {
|
|
2479
2481
|
if (dispatchError || agentRunFailed) {
|
|
@@ -2786,7 +2788,7 @@ const SLACK_MENTION_RESOLUTION_CONCURRENCY = 4;
|
|
|
2786
2788
|
const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
|
|
2787
2789
|
const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
|
|
2788
2790
|
const MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS = 2e3;
|
|
2789
|
-
const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-
|
|
2791
|
+
const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-DDoAJnrH.mjs").then((n) => n._));
|
|
2790
2792
|
function formatSlackUnavailableMedia(params) {
|
|
2791
2793
|
let fileReferences = params.files?.map((file) => `${formatSlackFileReference(file)} unavailable (${file.reason})`).join(", ");
|
|
2792
2794
|
if (fileReferences && fileReferences.length > MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS) fileReferences = `${truncateUtf16Safe(fileReferences, MAX_SLACK_UNAVAILABLE_FILE_TEXT_CHARS)}; … (file references truncated)`;
|
|
@@ -2915,9 +2917,13 @@ async function resolveSlackDmHistoryContext(params) {
|
|
|
2915
2917
|
inclusive: true
|
|
2916
2918
|
} : {},
|
|
2917
2919
|
limit: maxMessages + 1
|
|
2918
|
-
})).messages ?? []).
|
|
2919
|
-
if (params.currentMessageTs && message.ts === params.currentMessageTs) return
|
|
2920
|
-
|
|
2920
|
+
})).messages ?? []).flatMap((message) => {
|
|
2921
|
+
if (params.currentMessageTs && message.ts === params.currentMessageTs) return [];
|
|
2922
|
+
const body = normalizeOptionalString(message.text);
|
|
2923
|
+
return body ? [{
|
|
2924
|
+
message,
|
|
2925
|
+
body
|
|
2926
|
+
}] : [];
|
|
2921
2927
|
}).slice(0, maxMessages).toReversed();
|
|
2922
2928
|
if (messages.length === 0) return {
|
|
2923
2929
|
body: void 0,
|
|
@@ -2933,9 +2939,7 @@ async function resolveSlackDmHistoryContext(params) {
|
|
|
2933
2939
|
};
|
|
2934
2940
|
const entries = [];
|
|
2935
2941
|
const formatted = [];
|
|
2936
|
-
for (const message of messages) {
|
|
2937
|
-
const body = normalizeOptionalString(message.text);
|
|
2938
|
-
if (!body) continue;
|
|
2942
|
+
for (const { message, body } of messages) {
|
|
2939
2943
|
const isCurrentBot = params.ctx.botUserId && message.user === params.ctx.botUserId || params.ctx.botId && message.bot_id === params.ctx.botId;
|
|
2940
2944
|
const role = isCurrentBot || message.bot_id ? "assistant" : "user";
|
|
2941
2945
|
const sender = `${isCurrentBot ? "Assistant" : message.user ? await resolveUserLabel(message.user) : normalizeOptionalString(message.username) ?? (message.bot_id ? "Bot" : "Unknown")} (${role})`;
|
|
@@ -2955,8 +2959,8 @@ async function resolveSlackDmHistoryContext(params) {
|
|
|
2955
2959
|
}));
|
|
2956
2960
|
}
|
|
2957
2961
|
return {
|
|
2958
|
-
body: formatted.
|
|
2959
|
-
inboundHistory: entries
|
|
2962
|
+
body: formatted.join("\n\n"),
|
|
2963
|
+
inboundHistory: entries
|
|
2960
2964
|
};
|
|
2961
2965
|
} catch (err) {
|
|
2962
2966
|
logVerbose(`slack: failed to fetch DM history for channel ${params.channelId}: ${formatErrorMessage(err)}`);
|
|
@@ -3073,8 +3077,7 @@ async function resolveSlackRoomHistory(params) {
|
|
|
3073
3077
|
}
|
|
3074
3078
|
}
|
|
3075
3079
|
function isSlackImageFileCandidate(file) {
|
|
3076
|
-
|
|
3077
|
-
return Boolean(mimeTypeFromFilePath(file.name)?.startsWith("image/"));
|
|
3080
|
+
return Boolean(normalizeMimeType(file.mimetype)?.startsWith("image/") || mimeTypeFromFilePath(file.name)?.startsWith("image/"));
|
|
3078
3081
|
}
|
|
3079
3082
|
function sliceSlackImageFileCandidates(files, limit) {
|
|
3080
3083
|
if (limit <= 0 || !files?.length) return [];
|
|
@@ -3098,27 +3101,20 @@ function sliceSlackHistoryAttachmentCandidates(attachments, limit) {
|
|
|
3098
3101
|
}
|
|
3099
3102
|
return out;
|
|
3100
3103
|
}
|
|
3101
|
-
function buildSlackHistoryMediaCandidateMessage(message, maxAttachments) {
|
|
3102
|
-
const files = sliceSlackImageFileCandidates(message.files, maxAttachments);
|
|
3103
|
-
const attachments = sliceSlackHistoryAttachmentCandidates(message.attachments, Math.max(0, maxAttachments - files.length));
|
|
3104
|
-
if (files.length === 0 && attachments.length === 0) return null;
|
|
3105
|
-
return {
|
|
3106
|
-
message: {
|
|
3107
|
-
...message,
|
|
3108
|
-
files,
|
|
3109
|
-
attachments
|
|
3110
|
-
},
|
|
3111
|
-
attempted: files.length + attachments.reduce((count, attachment) => count + (normalizeOptionalString(attachment.image_url) ? 1 : 0) + (attachment.files?.length ?? 0), 0)
|
|
3112
|
-
};
|
|
3113
|
-
}
|
|
3114
3104
|
async function resolveSlackHistoryMedia(params) {
|
|
3115
|
-
const
|
|
3116
|
-
|
|
3105
|
+
const files = sliceSlackImageFileCandidates(params.message.files, params.maxAttachments);
|
|
3106
|
+
const attachments = sliceSlackHistoryAttachmentCandidates(params.message.attachments, Math.max(0, params.maxAttachments - files.length));
|
|
3107
|
+
if (files.length === 0 && attachments.length === 0) return {
|
|
3117
3108
|
media: [],
|
|
3118
3109
|
attempted: 0
|
|
3119
3110
|
};
|
|
3111
|
+
const attempted = files.length + attachments.reduce((count, attachment) => count + (normalizeOptionalString(attachment.image_url) ? 1 : 0) + (attachment.files?.length ?? 0), 0);
|
|
3120
3112
|
const content = await resolveSlackMessageContent({
|
|
3121
|
-
message:
|
|
3113
|
+
message: {
|
|
3114
|
+
...params.message,
|
|
3115
|
+
files,
|
|
3116
|
+
attachments
|
|
3117
|
+
},
|
|
3122
3118
|
isThreadReply: false,
|
|
3123
3119
|
threadStarter: null,
|
|
3124
3120
|
isBotMessage: Boolean(params.message.bot_id),
|
|
@@ -3135,12 +3131,35 @@ async function resolveSlackHistoryMedia(params) {
|
|
|
3135
3131
|
kind: "image",
|
|
3136
3132
|
messageId: params.message.ts
|
|
3137
3133
|
}),
|
|
3138
|
-
attempted
|
|
3134
|
+
attempted
|
|
3135
|
+
};
|
|
3136
|
+
}
|
|
3137
|
+
//#endregion
|
|
3138
|
+
//#region extensions/slack/src/monitor/message-handler/prepare-session-presentation.ts
|
|
3139
|
+
function resolveSlackGroupSessionSubject(params) {
|
|
3140
|
+
const channelName = normalizeOptionalString(params.channelName);
|
|
3141
|
+
const workspaceName = normalizeOptionalString(params.installationIdentity?.kind === "workspace" && params.installationIdentity.teamId === params.workspaceId ? params.installationIdentity.teamName : void 0);
|
|
3142
|
+
if (channelName && workspaceName) return `${workspaceName} #${channelName}`;
|
|
3143
|
+
return `Slack Channel (Workspace ID: ${params.workspaceId}, Channel ID: ${params.channelId})`;
|
|
3144
|
+
}
|
|
3145
|
+
function resolveSlackConversationLink(params) {
|
|
3146
|
+
if (params.existingLink) return params.existingLink;
|
|
3147
|
+
const teamId = normalizeOptionalString(params.teamId);
|
|
3148
|
+
let apiHost = "";
|
|
3149
|
+
try {
|
|
3150
|
+
apiHost = params.slackApiUrl ? new URL(params.slackApiUrl).hostname.toLowerCase() : "";
|
|
3151
|
+
} catch {}
|
|
3152
|
+
const url = new URL(`https://${apiHost === "slack-gov.com" ? "slack-gov.com" : "slack.com"}/app_redirect`);
|
|
3153
|
+
url.searchParams.set("channel", params.channelId);
|
|
3154
|
+
if (teamId) url.searchParams.set("team", teamId);
|
|
3155
|
+
return {
|
|
3156
|
+
url: url.href,
|
|
3157
|
+
label: "Slack"
|
|
3139
3158
|
};
|
|
3140
3159
|
}
|
|
3141
3160
|
//#endregion
|
|
3142
3161
|
//#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
|
|
3143
|
-
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-
|
|
3162
|
+
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-DDoAJnrH.mjs").then((n) => n._));
|
|
3144
3163
|
const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
|
|
3145
3164
|
function formatSlackThreadLabelSnippet(text) {
|
|
3146
3165
|
return truncateUtf16Safe(text.replace(/\s+/g, " "), 80);
|
|
@@ -3488,12 +3507,6 @@ const SLACK_USER_MENTION_RE = /<@([^>|]+)(?:\|[^>]+)?>/g;
|
|
|
3488
3507
|
const SLACK_SUBTEAM_MENTION_RE = /<!subteam\^([^>|]+)(?:\|[^>]+)?>/g;
|
|
3489
3508
|
const SLACK_SUBTEAM_MENTION_MARKER = "<!subteam^";
|
|
3490
3509
|
const SLACK_CHANNEL_ACCESS_DOCS_URL = "https://docs.openclaw.ai/channels/slack#access-control-and-routing";
|
|
3491
|
-
function resolveSlackGroupSessionSubject(params) {
|
|
3492
|
-
const channelName = normalizeOptionalString(params.channelName);
|
|
3493
|
-
const workspaceName = normalizeOptionalString(params.workspaceName);
|
|
3494
|
-
if (channelName && workspaceName) return `${workspaceName} #${channelName}`;
|
|
3495
|
-
return `Slack Channel (Workspace ID: ${params.workspaceId}, Channel ID: ${params.channelId})`;
|
|
3496
|
-
}
|
|
3497
3510
|
function mergeSlackAssistantThreadContext(primary, fallback) {
|
|
3498
3511
|
if (!primary) return fallback;
|
|
3499
3512
|
if (!fallback) return primary;
|
|
@@ -3608,7 +3621,7 @@ async function resolveSlackConversationContext(params) {
|
|
|
3608
3621
|
channelInfo = await ctx.resolveChannelName(message.channel, params.eventScope);
|
|
3609
3622
|
resolvedChannelType = normalizeSlackChannelType(message.channel_type ?? channelInfo.type ?? ctx.recallSlackChannelType(message.channel, params.eventScope), message.channel);
|
|
3610
3623
|
}
|
|
3611
|
-
const channelName = channelInfo
|
|
3624
|
+
const channelName = channelInfo.name;
|
|
3612
3625
|
const isDirectMessage = resolvedChannelType === "im";
|
|
3613
3626
|
const isGroupDm = resolvedChannelType === "mpim";
|
|
3614
3627
|
const isRoom = resolvedChannelType === "channel" || resolvedChannelType === "group";
|
|
@@ -3811,10 +3824,7 @@ async function prepareSlackMessage(params) {
|
|
|
3811
3824
|
ctx,
|
|
3812
3825
|
account,
|
|
3813
3826
|
message,
|
|
3814
|
-
|
|
3815
|
-
isGroupDm,
|
|
3816
|
-
isRoom,
|
|
3817
|
-
isRoomish,
|
|
3827
|
+
chatType,
|
|
3818
3828
|
channelConfig,
|
|
3819
3829
|
seedTopLevelRoomThread,
|
|
3820
3830
|
assistantThreadTs: assistantThreadContext?.threadTs,
|
|
@@ -3877,16 +3887,7 @@ async function prepareSlackMessage(params) {
|
|
|
3877
3887
|
return drop("configured-binding-unavailable");
|
|
3878
3888
|
}
|
|
3879
3889
|
}
|
|
3880
|
-
const senderNameForAuthPromise = ctx.allowNameMatching ? resolveSenderName()
|
|
3881
|
-
ok: true,
|
|
3882
|
-
name
|
|
3883
|
-
}), (error) => ({
|
|
3884
|
-
ok: false,
|
|
3885
|
-
error
|
|
3886
|
-
})) : Promise.resolve({
|
|
3887
|
-
ok: true,
|
|
3888
|
-
name: void 0
|
|
3889
|
-
});
|
|
3890
|
+
const senderNameForAuthPromise = ctx.allowNameMatching ? resolveSenderName() : void 0;
|
|
3890
3891
|
let threadStarterPromise;
|
|
3891
3892
|
const getThreadStarter = () => {
|
|
3892
3893
|
threadStarterPromise ??= isThreadReply && threadTs ? resolveSlackThreadStarter({
|
|
@@ -3910,14 +3911,7 @@ async function prepareSlackMessage(params) {
|
|
|
3910
3911
|
preloadedMedia
|
|
3911
3912
|
}));
|
|
3912
3913
|
let preloadedDirectMedia;
|
|
3913
|
-
|
|
3914
|
-
const getMessageContent = () => {
|
|
3915
|
-
messageContentPromise ??= resolveMessageContent(message, preloadedDirectMedia);
|
|
3916
|
-
return messageContentPromise;
|
|
3917
|
-
};
|
|
3918
|
-
const senderNameForAuthResult = await senderNameForAuthPromise;
|
|
3919
|
-
if (!senderNameForAuthResult.ok) throw senderNameForAuthResult.error;
|
|
3920
|
-
const senderNameForAuth = senderNameForAuthResult.name;
|
|
3914
|
+
const senderNameForAuth = await senderNameForAuthPromise;
|
|
3921
3915
|
const allowTextCommands = shouldHandleTextCommands({
|
|
3922
3916
|
cfg,
|
|
3923
3917
|
surface: "slack"
|
|
@@ -4111,7 +4105,7 @@ async function prepareSlackMessage(params) {
|
|
|
4111
4105
|
hasAbortRequest
|
|
4112
4106
|
});
|
|
4113
4107
|
const threadStarter = await getThreadStarter();
|
|
4114
|
-
const resolvedMessageContent = await
|
|
4108
|
+
const resolvedMessageContent = await resolveMessageContent(message, preloadedDirectMedia);
|
|
4115
4109
|
opts.abortSignal?.throwIfAborted();
|
|
4116
4110
|
if (opts.isRuntimePolicyCurrent?.() === false) return drop("final-route-denied");
|
|
4117
4111
|
if (!resolvedMessageContent) return drop("empty-content");
|
|
@@ -4156,16 +4150,14 @@ async function prepareSlackMessage(params) {
|
|
|
4156
4150
|
}) : statusReactionsWillHandle ? Promise.resolve(true) : null;
|
|
4157
4151
|
const roomLabel = channelName ? `#${channelName}` : `#${message.channel}`;
|
|
4158
4152
|
const workspaceId = opts.eventScope?.teamId || ctx.teamId;
|
|
4159
|
-
const workspaceName = ctx.installationIdentity?.kind === "workspace" && ctx.installationIdentity.teamId === workspaceId ? ctx.installationIdentity.teamName : void 0;
|
|
4160
4153
|
const groupSessionSubject = isRoomish ? resolveSlackGroupSessionSubject({
|
|
4161
4154
|
channelId: message.channel,
|
|
4162
4155
|
channelName,
|
|
4163
4156
|
workspaceId,
|
|
4164
|
-
|
|
4157
|
+
installationIdentity: ctx.installationIdentity
|
|
4165
4158
|
}) : void 0;
|
|
4166
4159
|
const senderName = await resolveSenderName();
|
|
4167
4160
|
const conversationAvatar = isDirectMessage && message.user ? ctx.resolveUserAvatar(message.user, opts.eventScope) : void 0;
|
|
4168
|
-
const preview = truncateUtf16Safe(bodyForAgent.replace(/\s+/g, " "), 160);
|
|
4169
4161
|
const inboundLabel = isDirectMessage ? `Slack DM from ${senderName}` : `Slack message in ${roomLabel} from ${senderName}`;
|
|
4170
4162
|
const slackFrom = isDirectMessage ? `slack:${message.user}` : isRoom ? `slack:channel:${message.channel}` : `slack:group:${message.channel}`;
|
|
4171
4163
|
enqueueRoutedSystemEvent(inboundLabel, {
|
|
@@ -4196,6 +4188,12 @@ async function prepareSlackMessage(params) {
|
|
|
4196
4188
|
storePath,
|
|
4197
4189
|
sessionKey
|
|
4198
4190
|
});
|
|
4191
|
+
const conversationLink = resolveSlackConversationLink({
|
|
4192
|
+
channelId: message.channel,
|
|
4193
|
+
teamId: opts.eventScope?.teamId ?? ctx.teamId,
|
|
4194
|
+
slackApiUrl: slackClient.slackApiUrl,
|
|
4195
|
+
existingLink: sessionEntry?.conversationLink
|
|
4196
|
+
});
|
|
4199
4197
|
const previousTimestamp = sessionEntry?.updatedAt;
|
|
4200
4198
|
const excludedMessageIds = new Set(opts.sourceMessageIds);
|
|
4201
4199
|
if (message.ts) excludedMessageIds.add(message.ts);
|
|
@@ -4350,7 +4348,8 @@ async function prepareSlackMessage(params) {
|
|
|
4350
4348
|
spaceId: opts.eventScope?.teamId || ctx.teamId || void 0,
|
|
4351
4349
|
threadId: boundMessageThreadId,
|
|
4352
4350
|
nativeChannelId: message.channel,
|
|
4353
|
-
avatar: conversationAvatar
|
|
4351
|
+
avatar: conversationAvatar,
|
|
4352
|
+
link: conversationLink
|
|
4354
4353
|
},
|
|
4355
4354
|
route: {
|
|
4356
4355
|
...route,
|
|
@@ -4459,39 +4458,34 @@ async function prepareSlackMessage(params) {
|
|
|
4459
4458
|
replyTarget,
|
|
4460
4459
|
ctxPayload,
|
|
4461
4460
|
sessionDisplayName: sessionEntry?.displayName,
|
|
4462
|
-
turn: {
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
sessionKey
|
|
4484
|
-
}, "failed updating session meta");
|
|
4485
|
-
}
|
|
4461
|
+
turn: { record: {
|
|
4462
|
+
updateLastRoute: isDirectMessage || opts.eventScope ? {
|
|
4463
|
+
sessionKey: updateLastRouteSessionKey,
|
|
4464
|
+
channel: "slack",
|
|
4465
|
+
to: replyRouteTarget,
|
|
4466
|
+
accountId: route.accountId,
|
|
4467
|
+
threadId: effectiveMessageThreadId,
|
|
4468
|
+
mainDmOwnerPin: isDirectMessage && updateLastRouteSessionKey === route.mainSessionKey && pinnedMainDmOwner && message.user ? {
|
|
4469
|
+
ownerRecipient: pinnedMainDmOwner,
|
|
4470
|
+
senderRecipient: normalizeLowercaseStringOrEmpty(message.user),
|
|
4471
|
+
onSkip: ({ ownerRecipient, senderRecipient }) => {
|
|
4472
|
+
logVerbose(`slack: skip main-session last route for ${senderRecipient} (pinned owner ${ownerRecipient})`);
|
|
4473
|
+
}
|
|
4474
|
+
} : void 0
|
|
4475
|
+
} : void 0,
|
|
4476
|
+
onRecordError: (err) => {
|
|
4477
|
+
ctx.logger.warn({
|
|
4478
|
+
error: formatErrorMessage(err),
|
|
4479
|
+
storePath,
|
|
4480
|
+
sessionKey
|
|
4481
|
+
}, "failed updating session meta");
|
|
4486
4482
|
}
|
|
4487
|
-
},
|
|
4483
|
+
} },
|
|
4488
4484
|
replyToMode,
|
|
4489
4485
|
...forcedReplyThreadTs ? { forcedReplyThreadTs } : {},
|
|
4490
4486
|
...assistantThreadContext ? { slackMessageMetadata: buildSlackAssistantThreadMetadata(assistantThreadContext) } : {},
|
|
4491
|
-
requireMention: shouldRequireMention,
|
|
4492
4487
|
isDirectMessage,
|
|
4493
4488
|
isRoomish,
|
|
4494
|
-
preview,
|
|
4495
4489
|
ackReactionMessageTs,
|
|
4496
4490
|
ackReactionValue,
|
|
4497
4491
|
ackReactionPromise
|