@openclaw/slack 2026.5.16-beta.3 → 2026.5.16-beta.5

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 (60) hide show
  1. package/dist/account-inspect-api.js +1 -1
  2. package/dist/{account-inspect-BJyQLSkN.js → account-inspect-uMPQ6wIu.js} +1 -1
  3. package/dist/{accounts-yk5K3wQU.js → accounts-Cbw3i3Sa.js} +7 -2
  4. package/dist/accounts.runtime-z3fshUeC.js +2 -0
  5. package/dist/{action-runtime-p39JLqwf.js → action-runtime-DgzkekLM.js} +3 -3
  6. package/dist/action-runtime.runtime-CGEyxfMu.js +2 -0
  7. package/dist/{actions-BCRbHv1Q.js → actions-vFq9T_Kd.js} +3 -3
  8. package/dist/{actions.runtime-CpywQR3D.js → actions.runtime-3XZA8-ot.js} +1 -1
  9. package/dist/api.js +14 -14
  10. package/dist/{approval-handler.runtime-DXrdRbkT.js → approval-handler.runtime-C_hfvcRd.js} +4 -4
  11. package/dist/{blocks-render-BAVfd6r0.js → blocks-render-ziYgM0qF.js} +74 -3
  12. package/dist/{channel-DoFtZGpw.js → channel-D9Wzqu3W.js} +21 -21
  13. package/dist/channel-config-api.js +1 -1
  14. package/dist/channel-plugin-api.js +1 -1
  15. package/dist/{channel.setup-BDL4qn9U.js → channel.setup-C2_IZ9It.js} +4 -4
  16. package/dist/{client-C_IaJbi5.js → client-Dr7pteMR.js} +4 -2
  17. package/dist/{config-schema-CNRousxw.js → config-schema-C8tW0Db0.js} +4 -0
  18. package/dist/contract-api.js +1 -1
  19. package/dist/{directory-config-CMvFiswf.js → directory-config-qDXRTCcs.js} +1 -1
  20. package/dist/directory-contract-api.js +1 -1
  21. package/dist/{directory-live-CZPzpQZF.js → directory-live-BnN4Zawp.js} +2 -2
  22. package/dist/http-routes-api.js +1 -1
  23. package/dist/inbound-contract-test-api.js +2 -2
  24. package/dist/{interactive-replies-BSg5hXhj.js → interactive-replies-B1wwXeVn.js} +10 -1
  25. package/dist/interactive-replies-api.js +1 -1
  26. package/dist/{message-tool-api-C7gc7goF.js → message-tool-api-DRSTJhP8.js} +2 -2
  27. package/dist/message-tool-api.js +1 -1
  28. package/dist/{monitor-Djnd8pGL.js → monitor-beou_Rl6.js} +3 -3
  29. package/dist/{outbound-adapter-CHm6e-0Q.js → outbound-adapter-Dcy9jZv1.js} +26 -6
  30. package/dist/outbound-payload-test-api.js +1 -1
  31. package/dist/{outbound-payload.test-harness-C0CW7_CE.js → outbound-payload.test-harness-B8N8U_AA.js} +1 -1
  32. package/dist/{pipeline.runtime-DJcwOZky.js → pipeline.runtime-COwSmZG5.js} +131 -46
  33. package/dist/{plugin-routes-CRnfsTTX.js → plugin-routes-hrKOqBIn.js} +1 -1
  34. package/dist/{prepare-Or_6_XXl.js → prepare-BjlcuiLr.js} +132 -24
  35. package/dist/{prepare.test-helpers-CU1qB54Q.js → prepare.test-helpers-D807wdul.js} +1 -1
  36. package/dist/{probe-FL4sUJsH.js → probe-DDef8MfR.js} +1 -1
  37. package/dist/{provider-3Y7c15_J.js → provider-C7uiI7hL.js} +120 -9
  38. package/dist/{replies-Fg1T3ZzU.js → replies-ClYRn89v.js} +9 -6
  39. package/dist/{reply-blocks-BFaJ_ejG.js → reply-blocks-DgUdywKU.js} +9 -4
  40. package/dist/{resolve-channels-B_eKaOkE.js → resolve-channels-gx65A1PR.js} +1 -1
  41. package/dist/{resolve-users-BzBAJwvq.js → resolve-users-OknHaiRY.js} +1 -1
  42. package/dist/{room-context-Cd8jFpS-.js → room-context-BI26wVBb.js} +83 -2
  43. package/dist/{runtime-api-B5HGOzX3.js → runtime-api-D3pvtood.js} +1 -1
  44. package/dist/runtime-api.js +12 -12
  45. package/dist/{scopes-Bvg_ZzqZ.js → scopes-vRHcdO0m.js} +1 -1
  46. package/dist/{send-CxXFbqN1.js → send-Br_H5f6H.js} +8 -3
  47. package/dist/send.runtime-Cj0cqt6C.js +2 -0
  48. package/dist/send.runtime-CjgsYARn.js +2 -0
  49. package/dist/{setup-core-B7pou7oe.js → setup-core-BRD65LS_.js} +23 -4
  50. package/dist/setup-plugin-api.js +1 -1
  51. package/dist/{setup-surface-CJS-L7PA.js → setup-surface-DpNyddrJ.js} +5 -5
  52. package/dist/{shared-BEabCPK3.js → shared-DdgQfBV9.js} +6 -6
  53. package/dist/{slash-dispatch.runtime-Cg7uU92H.js → slash-dispatch.runtime-DYm6lWN8.js} +1 -1
  54. package/dist/test-api.js +6 -6
  55. package/openclaw.plugin.json +14 -0
  56. package/package.json +4 -4
  57. package/dist/accounts.runtime-BhbEu1ZK.js +0 -2
  58. package/dist/action-runtime.runtime-BzrPV3EA.js +0 -2
  59. package/dist/send.runtime-BHCPpSj_.js +0 -2
  60. package/dist/send.runtime-CDG5AgU3.js +0 -2
@@ -1,12 +1,12 @@
1
- import { l as resolveSlackReplyToMode } from "./accounts-yk5K3wQU.js";
1
+ import { l as resolveSlackReplyToMode } from "./accounts-Cbw3i3Sa.js";
2
2
  import { r as parseSlackTarget } from "./target-parsing-CQmv-iSm.js";
3
3
  import "./targets-B1tYCAr6.js";
4
4
  import { i as normalizeSlackAllowOwnerEntry, o as resolveSlackAllowListMatch, r as normalizeAllowListLower } from "./allow-list-nwXs_eCP.js";
5
- import { i as hasSlackThreadParticipationWithPersistence, t as sendMessageSlack } from "./send-CxXFbqN1.js";
6
- import { _ as resolveSlackThreadStarter, g as resolveSlackThreadHistory, l as reactSlackMessage, y as formatSlackFileReference } from "./actions-BCRbHv1Q.js";
5
+ import { i as hasSlackThreadParticipationWithPersistence, t as sendMessageSlack } from "./send-Br_H5f6H.js";
6
+ import { _ as resolveSlackThreadStarter, g as resolveSlackThreadHistory, l as reactSlackMessage, y as formatSlackFileReference } from "./actions-vFq9T_Kd.js";
7
7
  import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
8
- import { b as readSessionUpdatedAt, c as authorizeSlackBotRoomMessage, d as resolveSlackEffectiveAllowFrom, g as resolveSlackChannelConfig, h as resolveSlackChatType, k as stripSlackMentionsForCommandDetection, m as normalizeSlackChannelType, n as authorizeSlackDirectMessage, o as resolveConversationLabel$1, t as resolveSlackRoomContextHints, u as resolveSlackCommandIngress, w as resolveStorePath, x as resolveChannelContextVisibilityMode } from "./room-context-Cd8jFpS-.js";
9
- import "./send.runtime-BHCPpSj_.js";
8
+ import { C as resolveChannelContextVisibilityMode, E as resolveStorePath, S as readSessionUpdatedAt, _ as resolveSlackChatType, c as authorizeSlackBotRoomMessage, d as resolveSlackEffectiveAllowFrom, f as buildSlackAssistantThreadMetadata, g as normalizeSlackChannelType, j as stripSlackMentionsForCommandDetection, m as parseSlackAssistantThreadMetadata, n as authorizeSlackDirectMessage, o as resolveConversationLabel$1, t as resolveSlackRoomContextHints, u as resolveSlackCommandIngress, v as resolveSlackChannelConfig } from "./room-context-BI26wVBb.js";
9
+ import "./send.runtime-CjgsYARn.js";
10
10
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
11
11
  import { resolveAgentRoute, resolveInboundLastRouteSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
12
12
  import { resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-message";
@@ -15,10 +15,11 @@ import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
15
15
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
16
16
  import { createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
17
17
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
18
- import { buildChannelTurnContext, buildMentionRegexes, formatInboundEnvelope, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, resolveEnvelopeFormatOptions, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
18
+ import { buildChannelInboundEventContext, buildMentionRegexes, classifyChannelInboundEvent, formatInboundEnvelope, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, resolveEnvelopeFormatOptions, resolveUnmentionedGroupInboundPolicy, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
19
19
  import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist, shouldIncludeSupplementalContext } from "openclaw/plugin-sdk/security-runtime";
20
20
  import { resolveAckReaction, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
21
21
  import { hasControlCommand } from "openclaw/plugin-sdk/command-detection";
22
+ import { isAbortRequestText } from "openclaw/plugin-sdk/command-primitives-runtime";
22
23
  import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
23
24
  import { recordDroppedChannelTurnHistory } from "openclaw/plugin-sdk/inbound-reply-dispatch";
24
25
  import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
@@ -29,7 +30,7 @@ const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
29
30
  const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
30
31
  let slackMediaModulePromise$1;
31
32
  function loadSlackMediaModule$1() {
32
- slackMediaModulePromise$1 ??= import("./actions-BCRbHv1Q.js").then((n) => n.h);
33
+ slackMediaModulePromise$1 ??= import("./actions-vFq9T_Kd.js").then((n) => n.h);
33
34
  return slackMediaModulePromise$1;
34
35
  }
35
36
  function collectUniqueSlackMentionIds$1(texts) {
@@ -442,7 +443,7 @@ function resolveSlackInitialAgentRoute(params) {
442
443
  });
443
444
  }
444
445
  function resolveSlackRoutingContext(params) {
445
- const { ctx, account, message, isDirectMessage, isGroupDm, isRoom, isRoomish, seedTopLevelRoomThread } = params;
446
+ const { ctx, account, message, isDirectMessage, isGroupDm, isRoom, isRoomish, seedTopLevelRoomThread, assistantThreadTs } = params;
446
447
  let route = resolveSlackInitialAgentRoute({
447
448
  ctx,
448
449
  account,
@@ -460,7 +461,7 @@ function resolveSlackRoutingContext(params) {
460
461
  const isThreadReply = threadContext.isThreadReply;
461
462
  const autoThreadId = !isThreadReply && replyToMode === "all" && threadContext.messageTs ? threadContext.messageTs : void 0;
462
463
  const seedCandidateThreadId = threadContext.incomingThreadTs ?? threadContext.messageTs;
463
- const routedThreadId = (isDirectMessage ? void 0 : isRoomish ? isThreadReply && threadTs ? threadTs : void 0 : isThreadReply ? threadTs : autoThreadId) ?? (isRoomish ? !isThreadReply && isRoom && seedTopLevelRoomThread && replyToMode !== "off" && seedCandidateThreadId ? seedCandidateThreadId : void 0 : void 0);
464
+ const routedThreadId = (isDirectMessage ? assistantThreadTs : isRoomish ? isThreadReply && threadTs ? threadTs : void 0 : isThreadReply ? threadTs : autoThreadId) ?? (isRoomish ? !isThreadReply && isRoom && seedTopLevelRoomThread && replyToMode !== "off" && seedCandidateThreadId ? seedCandidateThreadId : void 0 : void 0);
464
465
  const baseConversationId = resolveSlackBaseConversationId({
465
466
  message,
466
467
  isDirectMessage
@@ -577,7 +578,7 @@ function formatSlackBotStarterThreadLabel(params) {
577
578
  //#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
578
579
  let slackMediaModulePromise;
579
580
  function loadSlackMediaModule() {
580
- slackMediaModulePromise ??= import("./actions-BCRbHv1Q.js").then((n) => n.h);
581
+ slackMediaModulePromise ??= import("./actions-vFq9T_Kd.js").then((n) => n.h);
581
582
  return slackMediaModulePromise;
582
583
  }
583
584
  const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
@@ -849,6 +850,76 @@ const SLACK_HISTORY_MEDIA_MAX_ATTACHMENTS = 4;
849
850
  const SLACK_HISTORY_MEDIA_MAX_BYTES = 10 * 1024 * 1024;
850
851
  const SLACK_HISTORY_MEDIA_IDLE_TIMEOUT_MS = 1e3;
851
852
  const SLACK_HISTORY_MEDIA_TOTAL_TIMEOUT_MS = 3e3;
853
+ function asRecord(value) {
854
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
855
+ }
856
+ function recordString(record, key) {
857
+ return normalizeOptionalString(record?.[key]);
858
+ }
859
+ function recordNullableString(record, key) {
860
+ if (!record || !(key in record)) return;
861
+ if (record[key] === null) return null;
862
+ return normalizeOptionalString(record[key]);
863
+ }
864
+ function mergeSlackAssistantThreadContext(primary, fallback) {
865
+ if (!primary) return fallback;
866
+ if (!fallback) return primary;
867
+ return {
868
+ assistantChannelId: primary.assistantChannelId || fallback.assistantChannelId,
869
+ threadTs: primary.threadTs || fallback.threadTs,
870
+ userId: primary.userId ?? fallback.userId,
871
+ channelId: primary.channelId ?? fallback.channelId,
872
+ teamId: primary.teamId ?? fallback.teamId,
873
+ enterpriseId: primary.enterpriseId !== void 0 ? primary.enterpriseId : fallback.enterpriseId
874
+ };
875
+ }
876
+ function hasSlackAssistantThreadMetadata(context) {
877
+ return Boolean(context?.channelId || context?.teamId || context?.enterpriseId !== void 0);
878
+ }
879
+ function resolveSlackMessageAssistantThreadContext(message) {
880
+ const thread = asRecord(message.assistant_thread);
881
+ if (!thread) return;
882
+ const context = asRecord(thread.context);
883
+ const assistantChannelId = recordString(thread, "channel_id") ?? message.channel;
884
+ const threadTs = recordString(thread, "thread_ts") ?? message.thread_ts ?? message.ts;
885
+ if (!assistantChannelId || !threadTs) return;
886
+ return {
887
+ assistantChannelId,
888
+ threadTs,
889
+ userId: recordString(thread, "user_id") ?? message.user,
890
+ channelId: recordString(context, "channel_id"),
891
+ teamId: recordString(context, "team_id"),
892
+ enterpriseId: recordNullableString(context, "enterprise_id")
893
+ };
894
+ }
895
+ async function restoreSlackAssistantThreadContextFromMetadata(params) {
896
+ const threadTs = params.message.thread_ts;
897
+ const parentUserId = params.message.parent_user_id?.trim();
898
+ if (!params.message.channel || !threadTs || !parentUserId || parentUserId !== params.ctx.botUserId && parentUserId !== params.ctx.botId) return;
899
+ try {
900
+ const response = await params.ctx.app.client.conversations.replies({
901
+ channel: params.message.channel,
902
+ ts: threadTs,
903
+ oldest: threadTs,
904
+ include_all_metadata: true,
905
+ limit: 4
906
+ });
907
+ for (const message of response.messages ?? []) {
908
+ const context = parseSlackAssistantThreadMetadata(message.metadata);
909
+ if (!context) continue;
910
+ return {
911
+ assistantChannelId: params.message.channel,
912
+ threadTs,
913
+ userId: params.message.user,
914
+ channelId: context.channelId,
915
+ teamId: context.teamId,
916
+ enterpriseId: context.enterpriseId
917
+ };
918
+ }
919
+ } catch (err) {
920
+ logVerbose(`slack assistant context restore failed channel=${params.message.channel} ts=${threadTs}: ${formatErrorMessage(err)}`);
921
+ }
922
+ }
852
923
  function resolveCachedMentionRegexes(ctx, agentId) {
853
924
  const key = normalizeOptionalString(agentId) ?? "__default__";
854
925
  let byAgent = mentionRegexCache.get(ctx);
@@ -1093,7 +1164,19 @@ async function prepareSlackMessage(params) {
1093
1164
  source: opts.source
1094
1165
  });
1095
1166
  const channelRequireMention = channelConfig?.requireMention ?? ctx.defaultRequireMention ?? true;
1096
- const willImplicitlyThreadReply = isRoom && !channelRequireMention && resolveSlackReplyToMode(account, isDirectMessage ? "direct" : isGroupDm ? "group" : "channel") !== "off";
1167
+ const channelChatType = isDirectMessage ? "direct" : isGroupDm ? "group" : "channel";
1168
+ const messageAssistantThreadContext = resolveSlackMessageAssistantThreadContext(message);
1169
+ const assistantContextLookupChannelId = messageAssistantThreadContext?.assistantChannelId ?? message.channel;
1170
+ const assistantContextLookupThreadTs = messageAssistantThreadContext?.threadTs ?? message.thread_ts ?? message.ts;
1171
+ const cachedAssistantThreadContext = isDirectMessage ? ctx.getSlackAssistantThreadContext(assistantContextLookupChannelId, assistantContextLookupThreadTs) : void 0;
1172
+ const restoredAssistantThreadContext = isDirectMessage && !cachedAssistantThreadContext && !hasSlackAssistantThreadMetadata(messageAssistantThreadContext) ? await restoreSlackAssistantThreadContextFromMetadata({
1173
+ ctx,
1174
+ message
1175
+ }) : void 0;
1176
+ const assistantThreadContext = mergeSlackAssistantThreadContext(messageAssistantThreadContext, cachedAssistantThreadContext ?? restoredAssistantThreadContext);
1177
+ const assistantThreadContextToCache = messageAssistantThreadContext || restoredAssistantThreadContext ? assistantThreadContext : void 0;
1178
+ if (assistantThreadContextToCache) ctx.saveSlackAssistantThreadContext(assistantThreadContextToCache);
1179
+ const willImplicitlyThreadReply = isRoom && !channelRequireMention && resolveSlackReplyToMode(account, channelChatType) !== "off";
1097
1180
  const seedTopLevelRoomThreadBySource = opts.source === "app_mention" || opts.wasMentioned === true || explicitlyMentioned || willImplicitlyThreadReply;
1098
1181
  let routing = resolveSlackRoutingContext({
1099
1182
  ctx,
@@ -1103,7 +1186,8 @@ async function prepareSlackMessage(params) {
1103
1186
  isGroupDm,
1104
1187
  isRoom,
1105
1188
  isRoomish,
1106
- seedTopLevelRoomThread: seedTopLevelRoomThreadBySource
1189
+ seedTopLevelRoomThread: seedTopLevelRoomThreadBySource,
1190
+ assistantThreadTs: assistantThreadContext?.threadTs
1107
1191
  });
1108
1192
  const resolveWasMentioned = (mentionRegexes) => opts.wasMentioned ?? (!isDirectMessage && matchesMentionWithExplicit({
1109
1193
  text: messageText,
@@ -1126,7 +1210,8 @@ async function prepareSlackMessage(params) {
1126
1210
  isGroupDm,
1127
1211
  isRoom,
1128
1212
  isRoomish,
1129
- seedTopLevelRoomThread: true
1213
+ seedTopLevelRoomThread: true,
1214
+ assistantThreadTs: assistantThreadContext?.threadTs
1130
1215
  });
1131
1216
  mentionRegexes = resolveCachedMentionRegexes(ctx, routing.route.agentId);
1132
1217
  wasMentioned = resolveWasMentioned(mentionRegexes);
@@ -1151,7 +1236,7 @@ async function prepareSlackMessage(params) {
1151
1236
  return null;
1152
1237
  }
1153
1238
  }
1154
- const directThreadRoutedToDmSession = isDirectMessage && isThreadReply && threadTs && runtimeBinding?.conversation.conversationId !== threadTs;
1239
+ const directThreadRoutedToDmSession = !assistantThreadContext && isDirectMessage && isThreadReply && threadTs && runtimeBinding?.conversation.conversationId !== threadTs;
1155
1240
  let implicitMentionKinds = [];
1156
1241
  if (!isDirectMessage && ctx.botUserId && message.thread_ts && !ctx.threadRequireExplicitMention && !wasMentioned) {
1157
1242
  const replyToBotKinds = implicitMentionKindWhen("reply_to_bot", message.parent_user_id === ctx.botUserId);
@@ -1191,6 +1276,7 @@ async function prepareSlackMessage(params) {
1191
1276
  const canDetectMention = Boolean(ctx.botUserId) || mentionRegexes.length > 0;
1192
1277
  const textForCommandDetection = stripSlackMentionsForCommandDetection(message.text ?? "");
1193
1278
  const hasControlCommandInMessage = hasControlCommand(textForCommandDetection, cfg);
1279
+ const hasAbortRequest = isAbortRequestText(textForCommandDetection);
1194
1280
  const channelUsersAllowlistConfigured = isRoom && Array.isArray(channelConfig?.users) && channelConfig.users.length > 0;
1195
1281
  const messageIngress = await resolveSlackCommandIngress({
1196
1282
  ctx,
@@ -1332,6 +1418,16 @@ async function prepareSlackMessage(params) {
1332
1418
  if (!resolvedMessageContent) return null;
1333
1419
  const { rawBody, effectiveDirectMedia } = resolvedMessageContent;
1334
1420
  const chatType = resolveSlackChatType(conversation.resolvedChannelType);
1421
+ const inboundEventKind = classifyChannelInboundEvent({
1422
+ conversation: { kind: chatType },
1423
+ unmentionedGroupPolicy: resolveUnmentionedGroupInboundPolicy({
1424
+ cfg,
1425
+ agentId: route.agentId
1426
+ }),
1427
+ wasMentioned: effectiveWasMentioned,
1428
+ hasControlCommand: hasControlCommandInMessage,
1429
+ hasAbortRequest
1430
+ });
1335
1431
  const ackReaction = resolveAckReaction(cfg, route.agentId, {
1336
1432
  channel: "slack",
1337
1433
  accountId: account.accountId
@@ -1339,7 +1435,10 @@ async function prepareSlackMessage(params) {
1339
1435
  const ackReactionValue = ackReaction ?? "";
1340
1436
  const sourceRepliesAreToolOnly = resolveChannelMessageSourceReplyDeliveryMode({
1341
1437
  cfg,
1342
- ctx: { ChatType: chatType }
1438
+ ctx: {
1439
+ ChatType: chatType,
1440
+ InboundEventKind: inboundEventKind
1441
+ }
1343
1442
  }) === "message_tool_only";
1344
1443
  const statusReactionsExplicitlyEnabled = cfg.messages?.statusReactions?.enabled === true;
1345
1444
  const shouldAckReaction$1 = () => Boolean(ackReaction && shouldAckReaction({
@@ -1462,7 +1561,8 @@ async function prepareSlackMessage(params) {
1462
1561
  }) : dmHistoryContext.inboundHistory;
1463
1562
  const commandBody = textForCommandDetection.trim();
1464
1563
  const supplementalThreadHistoryBody = directThreadRoutedToDmSession && !threadHistoryBody ? threadStarterBody : threadHistoryBody;
1465
- const ctxPayload = buildChannelTurnContext({
1564
+ const effectiveMessageThreadId = assistantThreadContext?.threadTs ?? threadContext.messageThreadId;
1565
+ const ctxPayload = buildChannelInboundEventContext({
1466
1566
  channel: "slack",
1467
1567
  provider: "slack",
1468
1568
  surface: "slack",
@@ -1480,7 +1580,7 @@ async function prepareSlackMessage(params) {
1480
1580
  id: message.channel,
1481
1581
  label: envelopeFrom,
1482
1582
  spaceId: ctx.teamId || void 0,
1483
- threadId: directThreadRoutedToDmSession ? void 0 : threadContext.messageThreadId,
1583
+ threadId: directThreadRoutedToDmSession ? void 0 : effectiveMessageThreadId,
1484
1584
  nativeChannelId: message.channel,
1485
1585
  routePeer: {
1486
1586
  kind: chatType,
@@ -1497,10 +1597,11 @@ async function prepareSlackMessage(params) {
1497
1597
  to: slackTo,
1498
1598
  originatingTo: slackTo,
1499
1599
  replyToId: threadContext.replyToId,
1500
- messageThreadId: directThreadRoutedToDmSession ? void 0 : threadContext.messageThreadId,
1600
+ messageThreadId: directThreadRoutedToDmSession ? void 0 : effectiveMessageThreadId,
1501
1601
  nativeChannelId: message.channel
1502
1602
  },
1503
1603
  message: {
1604
+ inboundEventKind,
1504
1605
  body: combinedBody,
1505
1606
  bodyForAgent: rawBody,
1506
1607
  rawBody,
@@ -1537,6 +1638,10 @@ async function prepareSlackMessage(params) {
1537
1638
  GroupSubject: isRoomish ? roomLabel : void 0,
1538
1639
  UntrustedContext: untrustedChannelMetadata ? [untrustedChannelMetadata] : void 0,
1539
1640
  TransportThreadId: directThreadRoutedToDmSession ? threadContext.messageThreadId : void 0,
1641
+ SlackAssistantThread: assistantThreadContext ? true : void 0,
1642
+ SlackAssistantThreadContextChannelId: assistantThreadContext?.channelId,
1643
+ SlackAssistantThreadContextTeamId: assistantThreadContext?.teamId,
1644
+ SlackAssistantThreadContextEnterpriseId: assistantThreadContext?.enterpriseId ?? void 0,
1540
1645
  IsFirstThreadTurn: isThreadReply && threadTs && !directThreadRoutedToDmSession && !threadSessionPreviousTimestamp ? true : void 0,
1541
1646
  ...buildSlackMentionContextPayload({
1542
1647
  isRoomish,
@@ -1567,6 +1672,10 @@ async function prepareSlackMessage(params) {
1567
1672
  const replyTarget = isDirectMessage ? `channel:${message.channel}` : ctxPayload.To ?? void 0;
1568
1673
  if (!replyTarget) return null;
1569
1674
  if (shouldLogVerbose()) logVerbose(`slack inbound: channel=${message.channel} from=${slackFrom} preview="${preview}"`);
1675
+ const updateLastRouteSessionKey = resolveInboundLastRouteSessionKey({
1676
+ route,
1677
+ sessionKey
1678
+ });
1570
1679
  return {
1571
1680
  ctx,
1572
1681
  account,
@@ -1579,15 +1688,12 @@ async function prepareSlackMessage(params) {
1579
1688
  storePath,
1580
1689
  record: {
1581
1690
  updateLastRoute: isDirectMessage ? {
1582
- sessionKey: resolveInboundLastRouteSessionKey({
1583
- route,
1584
- sessionKey
1585
- }),
1691
+ sessionKey: updateLastRouteSessionKey,
1586
1692
  channel: "slack",
1587
1693
  to: `user:${message.user}`,
1588
1694
  accountId: route.accountId,
1589
- threadId: threadContext.messageThreadId,
1590
- mainDmOwnerPin: pinnedMainDmOwner && message.user ? {
1695
+ threadId: effectiveMessageThreadId,
1696
+ mainDmOwnerPin: updateLastRouteSessionKey === route.mainSessionKey && pinnedMainDmOwner && message.user ? {
1591
1697
  ownerRecipient: pinnedMainDmOwner,
1592
1698
  senderRecipient: normalizeLowercaseStringOrEmpty(message.user),
1593
1699
  onSkip: ({ ownerRecipient, senderRecipient }) => {
@@ -1611,6 +1717,8 @@ async function prepareSlackMessage(params) {
1611
1717
  } : void 0
1612
1718
  },
1613
1719
  replyToMode,
1720
+ ...assistantThreadContext?.threadTs ? { forcedReplyThreadTs: assistantThreadContext.threadTs } : {},
1721
+ ...assistantThreadContext ? { slackMessageMetadata: buildSlackAssistantThreadMetadata(assistantThreadContext) } : {},
1614
1722
  requireMention: shouldRequireMention,
1615
1723
  isDirectMessage,
1616
1724
  isRoomish,
@@ -1,4 +1,4 @@
1
- import { f as createSlackMonitorContext } from "./room-context-Cd8jFpS-.js";
1
+ import { p as createSlackMonitorContext } from "./room-context-BI26wVBb.js";
2
2
  import "openclaw/plugin-sdk/temp-path";
3
3
  //#region extensions/slack/src/monitor/message-handler/prepare.test-helpers.ts
4
4
  function createInboundSlackTestContext(params) {
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { r as createSlackWebClient } from "./client-C_IaJbi5.js";
2
+ import { r as createSlackWebClient } from "./client-Dr7pteMR.js";
3
3
  import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
4
4
  import { withTimeout } from "openclaw/plugin-sdk/text-utility-runtime";
5
5
  //#region extensions/slack/src/probe.ts
@@ -1,14 +1,14 @@
1
- import { a as resolveSlackAccount, d as resolveSlackBotToken, o as resolveSlackAccountAllowFrom, s as resolveSlackAccountDmPolicy, u as resolveSlackAppToken } from "./accounts-yk5K3wQU.js";
2
- import { i as isSlackApprovalAuthorizedSender, o as isSlackExecApprovalAuthorizedSender, s as isSlackExecApprovalClientEnabled } from "./reply-blocks-BFaJ_ejG.js";
3
- import "./blocks-render-BAVfd6r0.js";
1
+ import { a as resolveSlackAccount, d as resolveSlackBotToken, o as resolveSlackAccountAllowFrom, s as resolveSlackAccountDmPolicy, u as resolveSlackAppToken } from "./accounts-Cbw3i3Sa.js";
2
+ import { i as isSlackApprovalAuthorizedSender, o as isSlackExecApprovalAuthorizedSender, s as isSlackExecApprovalClientEnabled } from "./reply-blocks-DgUdywKU.js";
3
+ import "./blocks-render-ziYgM0qF.js";
4
4
  import { o as SLACK_TEXT_LIMIT, s as truncateSlackText } from "./thread-ts-As_dcNbD.js";
5
- import { c as resolveSlackWebClientOptions } from "./client-C_IaJbi5.js";
5
+ import { c as resolveSlackWebClientOptions } from "./client-Dr7pteMR.js";
6
6
  import { n as normalizeAllowList, r as normalizeAllowListLower, t as allowListMatches } from "./allow-list-nwXs_eCP.js";
7
7
  import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath } from "./registry-D2cWOLZV.js";
8
8
  import { t as formatSlackError } from "./errors-C_sW0Zgl.js";
9
- import { t as resolveSlackChannelAllowlist } from "./resolve-channels-B_eKaOkE.js";
10
- import { t as resolveSlackUserAllowlist } from "./resolve-users-BzBAJwvq.js";
11
- import { C as resolveOpenProviderRuntimeGroupPolicy, D as buildSlackSlashCommandMatcher, E as warnMissingProviderGroupPolicyFallbackOnce, O as resolveSlackSlashCommandConfig, S as resolveDefaultGroupPolicy, _ as resolveSlackChannelLabel, d as resolveSlackEffectiveAllowFrom, f as createSlackMonitorContext, g as resolveSlackChannelConfig, h as resolveSlackChatType, i as parsePluginBindingApprovalCustomId, k as stripSlackMentionsForCommandDetection, l as authorizeSlackSystemEventSender, m as normalizeSlackChannelType, n as authorizeSlackDirectMessage, p as isSlackChannelAllowedByPolicy, r as buildPluginBindingResolvedText, s as resolvePluginConversationBindingApproval, t as resolveSlackRoomContextHints, u as resolveSlackCommandIngress, v as getRuntimeConfig$1, y as isDangerousNameMatchingEnabled } from "./room-context-Cd8jFpS-.js";
9
+ import { t as resolveSlackChannelAllowlist } from "./resolve-channels-gx65A1PR.js";
10
+ import { t as resolveSlackUserAllowlist } from "./resolve-users-OknHaiRY.js";
11
+ import { A as resolveSlackSlashCommandConfig, O as warnMissingProviderGroupPolicyFallbackOnce, T as resolveOpenProviderRuntimeGroupPolicy, _ as resolveSlackChatType, b as getRuntimeConfig$1, d as resolveSlackEffectiveAllowFrom, f as buildSlackAssistantThreadMetadata, g as normalizeSlackChannelType, h as isSlackChannelAllowedByPolicy, i as parsePluginBindingApprovalCustomId, j as stripSlackMentionsForCommandDetection, k as buildSlackSlashCommandMatcher, l as authorizeSlackSystemEventSender, n as authorizeSlackDirectMessage, p as createSlackMonitorContext, r as buildPluginBindingResolvedText, s as resolvePluginConversationBindingApproval, t as resolveSlackRoomContextHints, u as resolveSlackCommandIngress, v as resolveSlackChannelConfig, w as resolveDefaultGroupPolicy, x as isDangerousNameMatchingEnabled, y as resolveSlackChannelLabel } from "./room-context-BI26wVBb.js";
12
12
  import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
13
13
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
14
14
  import { normalizeAccountId, normalizeMainKey } from "openclaw/plugin-sdk/routing";
@@ -37,6 +37,112 @@ import { requestHeartbeat } from "openclaw/plugin-sdk/heartbeat-runtime";
37
37
  import { createInteractiveConversationBindingHelpers, dispatchPluginInteractiveHandler } from "openclaw/plugin-sdk/plugin-runtime";
38
38
  import { createChannelInboundDebouncer, shouldDebounceTextInbound } from "openclaw/plugin-sdk/channel-inbound";
39
39
  import { generateSecureToken } from "openclaw/plugin-sdk/secure-random-runtime";
40
+ //#region extensions/slack/src/monitor/events/assistant.ts
41
+ const DEFAULT_ASSISTANT_PROMPTS = [
42
+ {
43
+ title: "What can you do?",
44
+ message: "What can you help me with?"
45
+ },
46
+ {
47
+ title: "Summarize this channel",
48
+ message: "Summarize the recent activity in this channel."
49
+ },
50
+ {
51
+ title: "Draft a reply",
52
+ message: "Help me draft a reply."
53
+ }
54
+ ];
55
+ function normalizeAssistantThread(event, getPrevious) {
56
+ const thread = event.assistant_thread;
57
+ if (!thread) return null;
58
+ const channelId = thread.channel_id?.trim();
59
+ const threadTs = thread.thread_ts?.trim();
60
+ if (!channelId || !threadTs) return null;
61
+ const previous = getPrevious?.(channelId, threadTs);
62
+ const threadContext = thread.context;
63
+ const eventContext = event.context;
64
+ const resolveContextString = (key, previousValue) => threadContext?.[key]?.trim() || eventContext?.[key]?.trim() || previousValue;
65
+ const enterpriseId = (() => {
66
+ if (threadContext && "enterprise_id" in threadContext) return threadContext.enterprise_id === null ? null : threadContext.enterprise_id?.trim() || previous?.enterpriseId;
67
+ if (eventContext && "enterprise_id" in eventContext) return eventContext.enterprise_id === null ? null : eventContext.enterprise_id?.trim() || previous?.enterpriseId;
68
+ return previous?.enterpriseId;
69
+ })();
70
+ return {
71
+ assistantChannelId: channelId,
72
+ threadTs,
73
+ userId: thread.user_id?.trim() || previous?.userId,
74
+ channelId: resolveContextString("channel_id", previous?.channelId),
75
+ teamId: resolveContextString("team_id", previous?.teamId),
76
+ enterpriseId
77
+ };
78
+ }
79
+ async function persistAssistantThreadMetadata(params) {
80
+ const { ctx, assistantThread } = params;
81
+ try {
82
+ const initialMessage = ((await ctx.app.client.conversations.replies({
83
+ token: ctx.botToken,
84
+ channel: assistantThread.assistantChannelId,
85
+ ts: assistantThread.threadTs,
86
+ oldest: assistantThread.threadTs,
87
+ include_all_metadata: true,
88
+ limit: 4
89
+ })).messages ?? []).find((message) => !message.subtype && message.user === ctx.botUserId && message.ts);
90
+ if (!initialMessage?.ts) return;
91
+ await ctx.app.client.chat.update({
92
+ token: ctx.botToken,
93
+ channel: assistantThread.assistantChannelId,
94
+ ts: initialMessage.ts,
95
+ text: initialMessage.text ?? "",
96
+ blocks: Array.isArray(initialMessage.blocks) ? initialMessage.blocks : [],
97
+ metadata: buildSlackAssistantThreadMetadata(assistantThread)
98
+ });
99
+ } catch (err) {
100
+ logVerbose(`slack assistant thread metadata persist failed for channel ${assistantThread.assistantChannelId}: ${formatErrorMessage(err)}`);
101
+ }
102
+ }
103
+ function registerSlackAssistantEvents(params) {
104
+ const { ctx, trackEvent } = params;
105
+ const slackApp = ctx.app;
106
+ slackApp.event("assistant_thread_started", async ({ event, body }) => {
107
+ try {
108
+ if (ctx.shouldDropMismatchedSlackEvent(body)) return;
109
+ trackEvent?.();
110
+ const assistantThread = normalizeAssistantThread(event, ctx.getSlackAssistantThreadContext);
111
+ if (!assistantThread) {
112
+ logVerbose("slack assistant_thread_started dropped: missing assistant thread channel/thread");
113
+ return;
114
+ }
115
+ ctx.saveSlackAssistantThreadContext(assistantThread);
116
+ await ctx.setSlackAssistantSuggestedPrompts({
117
+ channelId: assistantThread.assistantChannelId,
118
+ threadTs: assistantThread.threadTs,
119
+ title: "Try asking",
120
+ prompts: DEFAULT_ASSISTANT_PROMPTS
121
+ });
122
+ } catch (err) {
123
+ ctx.runtime.error?.(danger(`slack assistant_thread_started handler failed: ${formatErrorMessage(err)}`));
124
+ }
125
+ });
126
+ slackApp.event("assistant_thread_context_changed", async ({ event, body }) => {
127
+ try {
128
+ if (ctx.shouldDropMismatchedSlackEvent(body)) return;
129
+ trackEvent?.();
130
+ const assistantThread = normalizeAssistantThread(event, ctx.getSlackAssistantThreadContext);
131
+ if (!assistantThread) {
132
+ logVerbose("slack assistant_thread_context_changed dropped: missing assistant thread channel/thread");
133
+ return;
134
+ }
135
+ ctx.saveSlackAssistantThreadContext(assistantThread);
136
+ await persistAssistantThreadMetadata({
137
+ ctx,
138
+ assistantThread
139
+ });
140
+ } catch (err) {
141
+ ctx.runtime.error?.(danger(`slack assistant_thread_context_changed handler failed: ${formatErrorMessage(err)}`));
142
+ }
143
+ });
144
+ }
145
+ //#endregion
40
146
  //#region extensions/slack/src/channel-migration.ts
41
147
  function resolveAccountChannels(cfg, accountId) {
42
148
  if (!accountId) return {};
@@ -1431,6 +1537,7 @@ function resolveAssistantMessageChangedInbound(params) {
1431
1537
  ts: asString(message.ts) ?? asString(changed.event_ts),
1432
1538
  thread_ts: asString(message.thread_ts),
1433
1539
  event_ts: changed.event_ts,
1540
+ assistant_thread: asRecord$1(message.assistant_thread) ?? asRecord$1(changed.assistant_thread),
1434
1541
  files: Array.isArray(message.files) ? message.files : void 0,
1435
1542
  attachments: Array.isArray(message.attachments) ? message.attachments : void 0
1436
1543
  };
@@ -1645,6 +1752,10 @@ function registerSlackMonitorEvents(params) {
1645
1752
  ctx: params.ctx,
1646
1753
  trackEvent: params.trackEvent
1647
1754
  });
1755
+ registerSlackAssistantEvents({
1756
+ ctx: params.ctx,
1757
+ trackEvent: params.trackEvent
1758
+ });
1648
1759
  }
1649
1760
  //#endregion
1650
1761
  //#region extensions/slack/src/monitor/message-handler/debounce-key.ts
@@ -1764,7 +1875,7 @@ function createSlackThreadTsResolver(params) {
1764
1875
  //#region extensions/slack/src/monitor/message-handler.ts
1765
1876
  let slackMessagePipelinePromise;
1766
1877
  function loadSlackMessagePipeline() {
1767
- slackMessagePipelinePromise ??= import("./pipeline.runtime-DJcwOZky.js");
1878
+ slackMessagePipelinePromise ??= import("./pipeline.runtime-COwSmZG5.js");
1768
1879
  return slackMessagePipelinePromise;
1769
1880
  }
1770
1881
  const APP_MENTION_RETRY_TTL_MS = 6e4;
@@ -2306,7 +2417,7 @@ function loadSlashCommandsRuntime() {
2306
2417
  return slashCommandsRuntimePromise;
2307
2418
  }
2308
2419
  function loadSlashDispatchRuntime() {
2309
- slashDispatchRuntimePromise ??= import("./slash-dispatch.runtime-Cg7uU92H.js");
2420
+ slashDispatchRuntimePromise ??= import("./slash-dispatch.runtime-DYm6lWN8.js");
2310
2421
  return slashDispatchRuntimePromise;
2311
2422
  }
2312
2423
  function loadSlackPluginCommandsRuntime() {
@@ -1,7 +1,7 @@
1
- import { t as resolveSlackReplyBlocks } from "./reply-blocks-BFaJ_ejG.js";
1
+ import { t as resolveSlackReplyBlocks } from "./reply-blocks-DgUdywKU.js";
2
2
  import { o as SLACK_TEXT_LIMIT } from "./thread-ts-As_dcNbD.js";
3
- import { o as markdownToSlackMrkdwnChunks, t as sendMessageSlack } from "./send-CxXFbqN1.js";
4
- import "./send.runtime-BHCPpSj_.js";
3
+ import { o as markdownToSlackMrkdwnChunks, t as sendMessageSlack } from "./send-Br_H5f6H.js";
4
+ import "./send.runtime-CjgsYARn.js";
5
5
  import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-reference";
6
6
  import { SILENT_REPLY_TOKEN, chunkMarkdownTextWithMode, isSilentReplyText } from "openclaw/plugin-sdk/reply-chunking";
7
7
  import { deliverTextOrMediaReply, resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
@@ -32,7 +32,8 @@ async function deliverReplies(params) {
32
32
  threadTs,
33
33
  accountId: params.accountId,
34
34
  ...slackBlocks?.length ? { blocks: slackBlocks } : {},
35
- ...params.identity ? { identity: params.identity } : {}
35
+ ...params.identity ? { identity: params.identity } : {},
36
+ ...params.metadata ? { metadata: params.metadata } : {}
36
37
  });
37
38
  params.runtime.log?.(`delivered reply to ${params.target}`);
38
39
  continue;
@@ -51,7 +52,8 @@ async function deliverReplies(params) {
51
52
  token: params.token,
52
53
  threadTs,
53
54
  accountId: params.accountId,
54
- ...params.identity ? { identity: params.identity } : {}
55
+ ...params.identity ? { identity: params.identity } : {},
56
+ ...params.metadata ? { metadata: params.metadata } : {}
55
57
  });
56
58
  },
57
59
  sendMedia: async ({ mediaUrl, caption }) => {
@@ -61,7 +63,8 @@ async function deliverReplies(params) {
61
63
  mediaUrl,
62
64
  threadTs,
63
65
  accountId: params.accountId,
64
- ...params.identity ? { identity: params.identity } : {}
66
+ ...params.identity ? { identity: params.identity } : {},
67
+ ...params.metadata ? { metadata: params.metadata } : {}
65
68
  });
66
69
  }
67
70
  }) !== "empty") params.runtime.log?.(`delivered reply to ${params.target}`);
@@ -1,5 +1,5 @@
1
- import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-yk5K3wQU.js";
2
- import { t as buildSlackInteractiveBlocks } from "./blocks-render-BAVfd6r0.js";
1
+ import { a as resolveSlackAccount, i as resolveDefaultSlackAccountId, o as resolveSlackAccountAllowFrom, r as mergeSlackAccountConfig } from "./accounts-Cbw3i3Sa.js";
2
+ import { n as buildSlackPresentationBlocks, r as resolveSlackInteractiveBlockOffsets, t as buildSlackInteractiveBlocks } from "./blocks-render-ziYgM0qF.js";
3
3
  import { i as parseSlackBlocksInput } from "./thread-ts-As_dcNbD.js";
4
4
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
5
5
  import { normalizeStringifiedOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -123,10 +123,15 @@ function resolveSlackGroupToolPolicy(params) {
123
123
  //#region extensions/slack/src/reply-blocks.ts
124
124
  function resolveSlackReplyBlocks(payload) {
125
125
  const slackData = payload.channelData?.slack;
126
- const interactiveBlocks = buildSlackInteractiveBlocks(payload.interactive);
127
126
  let channelBlocks = [];
128
127
  if (slackData && typeof slackData === "object" && !Array.isArray(slackData)) channelBlocks = parseSlackBlocksInput(slackData.blocks) ?? [];
129
- const blocks = [...channelBlocks, ...interactiveBlocks];
128
+ const presentationBlocks = buildSlackPresentationBlocks(payload.presentation, resolveSlackInteractiveBlockOffsets(channelBlocks));
129
+ const interactiveBlocks = buildSlackInteractiveBlocks(payload.interactive, resolveSlackInteractiveBlockOffsets([...channelBlocks, ...presentationBlocks]));
130
+ const blocks = [
131
+ ...channelBlocks,
132
+ ...presentationBlocks,
133
+ ...interactiveBlocks
134
+ ];
130
135
  if (blocks.length > 50) throw new Error(`Slack blocks cannot exceed 50 items after interactive render`);
131
136
  return blocks.length > 0 ? blocks : void 0;
132
137
  }
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { r as createSlackWebClient } from "./client-C_IaJbi5.js";
2
+ import { r as createSlackWebClient } from "./client-Dr7pteMR.js";
3
3
  import { n as resolveSlackAllowlistEntries, t as collectSlackCursorItems } from "./resolve-allowlist-common-DLub2I2i.js";
4
4
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  //#region extensions/slack/src/resolve-channels.ts
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { r as createSlackWebClient } from "./client-C_IaJbi5.js";
2
+ import { r as createSlackWebClient } from "./client-Dr7pteMR.js";
3
3
  import { n as resolveSlackAllowlistEntries, t as collectSlackCursorItems } from "./resolve-allowlist-common-DLub2I2i.js";
4
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
5
  //#region extensions/slack/src/resolve-users.ts