@openclaw/slack 2026.5.14-beta.1 → 2026.5.16-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/{action-runtime-gtC-RM3r.js → action-runtime-p39JLqwf.js} +4 -4
  2. package/dist/action-runtime.runtime-BzrPV3EA.js +2 -0
  3. package/dist/{media-B-nNpS2G.js → actions-BCRbHv1Q.js} +309 -3
  4. package/dist/{actions.runtime-DD6hfFCA.js → actions.runtime-CpywQR3D.js} +1 -1
  5. package/dist/api.js +16 -16
  6. package/dist/{approval-handler.runtime-DeYBuIaU.js → approval-handler.runtime-DXrdRbkT.js} +3 -4
  7. package/dist/{blocks-render-BdLueE_v.js → blocks-render-BAVfd6r0.js} +1 -1
  8. package/dist/{channel-CC04F-xs.js → channel-CVSopl66.js} +23 -27
  9. package/dist/channel-config-api.js +1 -1
  10. package/dist/channel-plugin-api.js +1 -1
  11. package/dist/{channel.setup-jzYjY634.js → channel.setup-DknBgufI.js} +3 -3
  12. package/dist/{client-8r7r7aZ3.js → client-C_IaJbi5.js} +20 -1
  13. package/dist/{config-schema-Bueih4yH.js → config-schema-CNRousxw.js} +1 -1
  14. package/dist/contract-api.js +4 -4
  15. package/dist/directory-contract-api.js +1 -1
  16. package/dist/{directory-live-CuaWaGnM.js → directory-live-CZPzpQZF.js} +1 -1
  17. package/dist/{doctor-contract-DCkS8eNN.js → doctor-contract-B8QIWMs1.js} +1 -1
  18. package/dist/doctor-contract-api.js +1 -1
  19. package/dist/http-routes-api.js +1 -1
  20. package/dist/inbound-contract-test-api.js +2 -2
  21. package/dist/interactive-replies-api.js +1 -1
  22. package/dist/{message-tool-api-B_bKUmP0.js → message-tool-api-C7gc7goF.js} +1 -1
  23. package/dist/message-tool-api.js +1 -1
  24. package/dist/{monitor-B3QB1ysK.js → monitor-CdVxsuHi.js} +3 -3
  25. package/dist/{outbound-adapter-DsAvCwpZ.js → outbound-adapter-CHm6e-0Q.js} +4 -5
  26. package/dist/outbound-payload-test-api.js +1 -1
  27. package/dist/{outbound-payload.test-harness-DM9ZdY2f.js → outbound-payload.test-harness-C0CW7_CE.js} +2 -2
  28. package/dist/{pipeline.runtime-D-YJZZaI.js → pipeline.runtime-CakcaQh9.js} +119 -143
  29. package/dist/{plugin-routes-Dt_jh9W8.js → plugin-routes-CRnfsTTX.js} +1 -1
  30. package/dist/{prepare-CXI8nHbJ.js → prepare-DSRUr44d.js} +223 -85
  31. package/dist/{prepare.test-helpers-BhFHtbz3.js → prepare.test-helpers-CU1qB54Q.js} +1 -1
  32. package/dist/{probe-D1wYA05H.js → probe-FL4sUJsH.js} +2 -2
  33. package/dist/{provider-Ut7IF0Mn.js → provider-bKg1hkf5.js} +158 -24
  34. package/dist/{replies-CzfjCaLG.js → replies-Fg1T3ZzU.js} +4 -4
  35. package/dist/reply-blocks-BFaJ_ejG.js +134 -0
  36. package/dist/{resolve-channels-BiVxSLVm.js → resolve-channels-B_eKaOkE.js} +2 -2
  37. package/dist/{resolve-users-CcpSlYw-.js → resolve-users-BzBAJwvq.js} +2 -2
  38. package/dist/{room-context-D0hGOp8m.js → room-context-Cd8jFpS-.js} +2 -2
  39. package/dist/{runtime-api-D8wiG9BS.js → runtime-api-B5HGOzX3.js} +2 -2
  40. package/dist/runtime-api.js +12 -12
  41. package/dist/runtime-setter-api.js +1 -1
  42. package/dist/{scopes-BTkB8PPE.js → scopes-Bvg_ZzqZ.js} +2 -2
  43. package/dist/secret-contract-api.js +1 -1
  44. package/dist/security-contract-api.js +1 -1
  45. package/dist/{send-ioky2Xpy.js → send-CxXFbqN1.js} +5 -6
  46. package/dist/send.runtime-BHCPpSj_.js +2 -0
  47. package/dist/send.runtime-CDG5AgU3.js +2 -0
  48. package/dist/{setup-core-DgLJ7dQY.js → setup-core-B7pou7oe.js} +23 -22
  49. package/dist/setup-plugin-api.js +1 -1
  50. package/dist/{setup-surface-B6w9gtds.js → setup-surface-D6LLzeRz.js} +16 -15
  51. package/dist/{shared-CSiHkaVO.js → shared-7Vi9j4aV.js} +7 -7
  52. package/dist/{slash-dispatch.runtime-DNr1EDON.js → slash-dispatch.runtime-Cg7uU92H.js} +1 -1
  53. package/dist/test-api.js +7 -7
  54. package/dist/thread-ts-As_dcNbD.js +52 -0
  55. package/package.json +5 -5
  56. package/dist/action-runtime.runtime-DbVd7_Na.js +0 -2
  57. package/dist/actions-Cqyj7oRr.js +0 -309
  58. package/dist/approval-auth-D3xf0sS6.js +0 -28
  59. package/dist/blocks-input-BJZ8vv03.js +0 -29
  60. package/dist/channel-api-BfBK89IN.js +0 -20
  61. package/dist/exec-approvals-BLn4Zx7V.js +0 -58
  62. package/dist/group-policy-utF2iWnE.js +0 -41
  63. package/dist/mrkdwn-18IzcEAY.js +0 -6
  64. package/dist/reply-blocks-DWoZrUll.js +0 -14
  65. package/dist/send.runtime-5Kl3Wzbf.js +0 -2
  66. package/dist/send.runtime-DoifekaA.js +0 -2
  67. package/dist/thread-ts-o-QBwB3k.js +0 -24
  68. /package/dist/{accounts.runtime-CkfFIisb.js → accounts.runtime-BhbEu1ZK.js} +0 -0
  69. /package/dist/{allow-list-T7ZDpUsF.js → allow-list-nwXs_eCP.js} +0 -0
  70. /package/dist/{config-api-B48Z4H47.js → config-api-CmgE_ORg.js} +0 -0
  71. /package/dist/{directory-config-BKKNBkCq.js → directory-config-CMvFiswf.js} +0 -0
  72. /package/dist/{errors-BrtayXHa.js → errors-C_sW0Zgl.js} +0 -0
  73. /package/dist/{interactive-replies-CawNPL-h.js → interactive-replies-BSg5hXhj.js} +0 -0
  74. /package/dist/{magic-string.es-BLAi6qQC.js → magic-string.es-9lw4MGoF.js} +0 -0
  75. /package/dist/{registry-BdfKYina.js → registry-D2cWOLZV.js} +0 -0
  76. /package/dist/{resolve-allowlist-common-rhfyDyWi.js → resolve-allowlist-common-DLub2I2i.js} +0 -0
  77. /package/dist/{runtime--VlVtTPu.js → runtime-DQxkf7k2.js} +0 -0
  78. /package/dist/{secret-contract-BurGIyhv.js → secret-contract-0TL3L5Kb.js} +0 -0
  79. /package/dist/{security-audit-DvOpSaZM.js → security-audit-BJzADAw3.js} +0 -0
  80. /package/dist/{slash-commands.runtime-DRkNgIQ2.js → slash-commands.runtime-bcDwsGnu.js} +0 -0
  81. /package/dist/{slash-plugin-commands.runtime-Dj5h8hmv.js → slash-plugin-commands.runtime-DBHGUSj2.js} +0 -0
  82. /package/dist/{slash-skill-commands.runtime-B-_KAk0C.js → slash-skill-commands.runtime-rrY2hXvN.js} +0 -0
  83. /package/dist/{streaming-compat-C6rySwiD.js → streaming-compat-eu5Rj5gj.js} +0 -0
@@ -1,27 +1,27 @@
1
1
  import { l as resolveSlackReplyToMode } from "./accounts-yk5K3wQU.js";
2
2
  import { r as parseSlackTarget } from "./target-parsing-CQmv-iSm.js";
3
3
  import "./targets-B1tYCAr6.js";
4
- import { i as normalizeSlackAllowOwnerEntry, o as resolveSlackAllowListMatch, r as normalizeAllowListLower } from "./allow-list-T7ZDpUsF.js";
5
- import { i as hasSlackThreadParticipationWithPersistence, t as sendMessageSlack } from "./send-ioky2Xpy.js";
6
- import { l as reactSlackMessage } from "./actions-Cqyj7oRr.js";
7
- import { i as resolveSlackThreadStarter, o as formatSlackFileReference, r as resolveSlackThreadHistory } from "./media-B-nNpS2G.js";
8
- import { t as formatSlackError } from "./errors-BrtayXHa.js";
9
- 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-D0hGOp8m.js";
10
- import "./send.runtime-DoifekaA.js";
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";
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";
11
10
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
12
11
  import { resolveAgentRoute, resolveInboundLastRouteSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
13
12
  import { resolveChannelMessageSourceReplyDeliveryMode } from "openclaw/plugin-sdk/channel-message";
14
13
  import { logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
15
14
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
16
15
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
17
- import { buildPendingHistoryContextFromMap, recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
16
+ import { createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
18
17
  import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
19
- import { buildMentionRegexes, formatInboundEnvelope, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, resolveEnvelopeFormatOptions } from "openclaw/plugin-sdk/channel-inbound";
18
+ import { buildChannelTurnContext, buildMentionRegexes, formatInboundEnvelope, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, resolveEnvelopeFormatOptions, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
20
19
  import { filterSupplementalContextItems, resolvePinnedMainDmOwnerFromAllowlist, shouldIncludeSupplementalContext } from "openclaw/plugin-sdk/security-runtime";
21
20
  import { resolveAckReaction, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
22
21
  import { hasControlCommand } from "openclaw/plugin-sdk/command-detection";
23
22
  import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
24
- import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-dispatch-runtime";
23
+ import { recordDroppedChannelTurnHistory } from "openclaw/plugin-sdk/inbound-reply-dispatch";
24
+ import { mimeTypeFromFilePath } from "openclaw/plugin-sdk/media-mime";
25
25
  import { runTasksWithConcurrency } from "openclaw/plugin-sdk/concurrency-runtime";
26
26
  //#region extensions/slack/src/monitor/message-handler/prepare-content.ts
27
27
  const SLACK_MENTION_RESOLUTION_CONCURRENCY = 4;
@@ -29,7 +29,7 @@ const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
29
29
  const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
30
30
  let slackMediaModulePromise$1;
31
31
  function loadSlackMediaModule$1() {
32
- slackMediaModulePromise$1 ??= import("./media-B-nNpS2G.js").then((n) => n.t);
32
+ slackMediaModulePromise$1 ??= import("./actions-BCRbHv1Q.js").then((n) => n.h);
33
33
  return slackMediaModulePromise$1;
34
34
  }
35
35
  function collectUniqueSlackMentionIds$1(texts) {
@@ -191,13 +191,19 @@ async function resolveSlackMessageContent(params) {
191
191
  files: ownFiles,
192
192
  client: params.client,
193
193
  token: params.botToken,
194
- maxBytes: params.mediaMaxBytes
194
+ maxBytes: params.mediaMaxBytes,
195
+ readIdleTimeoutMs: params.mediaReadIdleTimeoutMs,
196
+ totalTimeoutMs: params.mediaTotalTimeoutMs,
197
+ abortSignal: params.abortSignal
195
198
  })) : Promise.resolve(null);
196
199
  const attachmentContentPromise = params.message.attachments && params.message.attachments.length > 0 ? loadSlackMediaModule$1().then(({ resolveSlackAttachmentContent }) => resolveSlackAttachmentContent({
197
200
  attachments: params.message.attachments,
198
201
  client: params.client,
199
202
  token: params.botToken,
200
- maxBytes: params.mediaMaxBytes
203
+ maxBytes: params.mediaMaxBytes,
204
+ readIdleTimeoutMs: params.mediaReadIdleTimeoutMs,
205
+ totalTimeoutMs: params.mediaTotalTimeoutMs,
206
+ abortSignal: params.abortSignal
201
207
  })) : Promise.resolve(null);
202
208
  const [media, attachmentContent] = await Promise.all([mediaPromise, attachmentContentPromise]);
203
209
  const mergedMedia = [...media ?? [], ...attachmentContent?.media ?? []];
@@ -570,7 +576,7 @@ function formatSlackBotStarterThreadLabel(params) {
570
576
  //#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
571
577
  let slackMediaModulePromise;
572
578
  function loadSlackMediaModule() {
573
- slackMediaModulePromise ??= import("./media-B-nNpS2G.js").then((n) => n.t);
579
+ slackMediaModulePromise ??= import("./actions-BCRbHv1Q.js").then((n) => n.h);
574
580
  return slackMediaModulePromise;
575
581
  }
576
582
  const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
@@ -838,6 +844,10 @@ const SLACK_ANY_MENTION_RE = /<@[^>]+>|<!subteam\^[^>]+>/;
838
844
  const SLACK_USER_MENTION_RE = /<@([^>|]+)(?:\|[^>]+)?>/g;
839
845
  const SLACK_SUBTEAM_MENTION_RE = /<!subteam\^([^>|]+)(?:\|[^>]+)?>/g;
840
846
  const SLACK_SUBTEAM_MENTION_MARKER = "<!subteam^";
847
+ const SLACK_HISTORY_MEDIA_MAX_ATTACHMENTS = 4;
848
+ const SLACK_HISTORY_MEDIA_MAX_BYTES = 10 * 1024 * 1024;
849
+ const SLACK_HISTORY_MEDIA_IDLE_TIMEOUT_MS = 1e3;
850
+ const SLACK_HISTORY_MEDIA_TOTAL_TIMEOUT_MS = 3e3;
841
851
  function resolveCachedMentionRegexes(ctx, agentId) {
842
852
  const key = normalizeOptionalString(agentId) ?? "__default__";
843
853
  let byAgent = mentionRegexCache.get(ctx);
@@ -851,6 +861,60 @@ function resolveCachedMentionRegexes(ctx, agentId) {
851
861
  byAgent.set(key, built);
852
862
  return built;
853
863
  }
864
+ function isSlackImageFileCandidate(file) {
865
+ if ((file.mimetype?.split(";")[0]?.trim().toLowerCase())?.startsWith("image/")) return true;
866
+ return Boolean(mimeTypeFromFilePath(file.name)?.startsWith("image/"));
867
+ }
868
+ function sliceSlackImageFileCandidates(files, limit) {
869
+ if (limit <= 0 || !files?.length) return [];
870
+ return files.filter(isSlackImageFileCandidate).slice(0, limit);
871
+ }
872
+ function sliceSlackHistoryAttachmentCandidates(attachments, limit) {
873
+ if (limit <= 0 || !attachments?.length) return [];
874
+ const out = [];
875
+ let remaining = limit;
876
+ for (const attachment of attachments) {
877
+ if (attachment.is_share !== true) continue;
878
+ const hasImageUrl = Boolean(normalizeOptionalString(attachment.image_url));
879
+ const files = sliceSlackImageFileCandidates(attachment.files, remaining - (hasImageUrl ? 1 : 0));
880
+ if (!hasImageUrl && files.length === 0) continue;
881
+ out.push({
882
+ ...attachment,
883
+ files
884
+ });
885
+ remaining -= (hasImageUrl ? 1 : 0) + files.length;
886
+ if (remaining <= 0) break;
887
+ }
888
+ return out;
889
+ }
890
+ function buildSlackHistoryMediaCandidateMessage(message) {
891
+ const files = sliceSlackImageFileCandidates(message.files, SLACK_HISTORY_MEDIA_MAX_ATTACHMENTS);
892
+ const attachments = sliceSlackHistoryAttachmentCandidates(message.attachments, Math.max(0, SLACK_HISTORY_MEDIA_MAX_ATTACHMENTS - files.length));
893
+ if (files.length === 0 && attachments.length === 0) return null;
894
+ return {
895
+ ...message,
896
+ files,
897
+ attachments
898
+ };
899
+ }
900
+ async function resolveSlackHistoryMediaForPendingRecord(params) {
901
+ const mediaMessage = buildSlackHistoryMediaCandidateMessage(params.message);
902
+ if (!mediaMessage) return [];
903
+ return toInboundMediaFacts((await resolveSlackMessageContent({
904
+ message: mediaMessage,
905
+ isThreadReply: params.isThreadReply,
906
+ threadStarter: params.threadStarter,
907
+ isBotMessage: params.isBotMessage,
908
+ client: params.ctx.app.client,
909
+ botToken: params.ctx.botToken,
910
+ mediaMaxBytes: Math.min(params.ctx.mediaMaxBytes, SLACK_HISTORY_MEDIA_MAX_BYTES),
911
+ mediaReadIdleTimeoutMs: SLACK_HISTORY_MEDIA_IDLE_TIMEOUT_MS,
912
+ mediaTotalTimeoutMs: SLACK_HISTORY_MEDIA_TOTAL_TIMEOUT_MS
913
+ }))?.effectiveDirectMedia, {
914
+ kind: "image",
915
+ messageId: params.message.ts
916
+ });
917
+ }
854
918
  function collectUniqueSlackMentionIds(text, regex) {
855
919
  const ids = [];
856
920
  regex.lastIndex = 0;
@@ -1199,18 +1263,52 @@ async function prepareSlackMessage(params) {
1199
1263
  reason: "no-mention"
1200
1264
  }, "skipping channel message");
1201
1265
  const pendingText = (message.text ?? "").trim();
1266
+ const historyMediaCandidate = buildSlackHistoryMediaCandidateMessage(message);
1202
1267
  const fallbackFile = message.files?.length ? `[Slack file: ${formatSlackFileReference(message.files[0])}]` : "";
1203
- const pendingBody = pendingText || fallbackFile;
1204
- recordPendingHistoryEntryIfEnabled({
1205
- historyMap: ctx.channelHistories,
1206
- historyKey,
1207
- limit: ctx.historyLimit,
1208
- entry: pendingBody ? {
1209
- sender: await resolveSenderName(),
1210
- body: pendingBody,
1211
- timestamp: message.ts ? Math.round(Number(message.ts) * 1e3) : void 0,
1212
- messageId: message.ts
1213
- } : null
1268
+ const pendingBody = pendingText || fallbackFile || (!fallbackFile && historyMediaCandidate ? "[Slack media attachment]" : "");
1269
+ const skippedThreadStarter = historyMediaCandidate && isThreadReply && threadTs ? await resolveSlackThreadStarter({
1270
+ channelId: message.channel,
1271
+ threadTs,
1272
+ client: ctx.app.client
1273
+ }) : null;
1274
+ const timestamp = message.ts ? Math.round(Number(message.ts) * 1e3) : void 0;
1275
+ const senderName = pendingBody ? await resolveSenderName() : void 0;
1276
+ await recordDroppedChannelTurnHistory({
1277
+ input: {
1278
+ id: message.ts ?? `${message.channel}:${Date.now()}`,
1279
+ timestamp,
1280
+ rawText: pendingBody,
1281
+ textForAgent: pendingBody,
1282
+ raw: message
1283
+ },
1284
+ admission: {
1285
+ kind: "drop",
1286
+ reason: "slack-no-mention",
1287
+ recordHistory: true
1288
+ },
1289
+ preflight: {
1290
+ message: pendingBody ? {
1291
+ rawBody: pendingBody,
1292
+ body: pendingBody,
1293
+ bodyForAgent: pendingBody,
1294
+ senderLabel: senderName,
1295
+ envelopeFrom: senderName
1296
+ } : void 0,
1297
+ history: {
1298
+ key: historyKey,
1299
+ historyMap: ctx.channelHistories,
1300
+ limit: ctx.historyLimit,
1301
+ recordOnDrop: true,
1302
+ mediaLimit: SLACK_HISTORY_MEDIA_MAX_ATTACHMENTS
1303
+ },
1304
+ media: () => resolveSlackHistoryMediaForPendingRecord({
1305
+ ctx,
1306
+ message,
1307
+ isThreadReply,
1308
+ threadStarter: skippedThreadStarter,
1309
+ isBotMessage
1310
+ })
1311
+ }
1214
1312
  });
1215
1313
  return null;
1216
1314
  }
@@ -1271,6 +1369,7 @@ async function prepareSlackMessage(params) {
1271
1369
  enqueueSystemEvent(`${inboundLabel}: ${preview}`, {
1272
1370
  sessionKey,
1273
1371
  contextKey: `slack:message:${message.channel}:${message.ts ?? "unknown"}`,
1372
+ forceSenderIsOwnerFalse: true,
1274
1373
  trusted: false
1275
1374
  });
1276
1375
  const envelopeFrom = resolveConversationLabel$1({
@@ -1287,6 +1386,7 @@ async function prepareSlackMessage(params) {
1287
1386
  storePath,
1288
1387
  sessionKey
1289
1388
  });
1389
+ const channelHistory = createChannelHistoryWindow({ historyMap: ctx.channelHistories });
1290
1390
  const dmHistoryLimit = isDirectMessage ? resolveSlackDmHistoryLimit({
1291
1391
  account,
1292
1392
  userId: message.user,
@@ -1316,8 +1416,7 @@ async function prepareSlackMessage(params) {
1316
1416
  inboundHistory: void 0
1317
1417
  };
1318
1418
  if (dmHistoryContext.body) combinedBody = `${dmHistoryContext.body}\n\n${combinedBody}`;
1319
- if (isRoomish && ctx.historyLimit > 0) combinedBody = buildPendingHistoryContextFromMap({
1320
- historyMap: ctx.channelHistories,
1419
+ if (isRoomish && ctx.historyLimit > 0) combinedBody = channelHistory.buildPendingContext({
1321
1420
  historyKey,
1322
1421
  limit: ctx.historyLimit,
1323
1422
  currentMessage: combinedBody,
@@ -1354,65 +1453,98 @@ async function prepareSlackMessage(params) {
1354
1453
  effectiveDirectMedia
1355
1454
  });
1356
1455
  const effectiveMedia = effectiveDirectMedia ?? threadStarterMedia;
1357
- const firstMedia = effectiveMedia?.[0];
1358
- const inboundHistory = isRoomish && ctx.historyLimit > 0 ? (ctx.channelHistories.get(historyKey) ?? []).map((entry) => ({
1359
- sender: entry.sender,
1360
- body: entry.body,
1361
- timestamp: entry.timestamp
1362
- })) : dmHistoryContext.inboundHistory;
1456
+ const inboundHistory = isRoomish && ctx.historyLimit > 0 ? channelHistory.buildInboundHistory({
1457
+ historyKey,
1458
+ limit: ctx.historyLimit
1459
+ }) : dmHistoryContext.inboundHistory;
1363
1460
  const commandBody = textForCommandDetection.trim();
1364
- const ctxPayload = finalizeInboundContext({
1365
- Body: combinedBody,
1366
- BodyForAgent: rawBody,
1367
- InboundHistory: inboundHistory,
1368
- RawBody: rawBody,
1369
- CommandBody: commandBody,
1370
- BodyForCommands: commandBody,
1371
- From: slackFrom,
1372
- To: slackTo,
1373
- SessionKey: sessionKey,
1374
- AccountId: route.accountId,
1375
- ChatType: chatType,
1376
- ConversationLabel: envelopeFrom,
1377
- GroupSubject: isRoomish ? roomLabel : void 0,
1378
- GroupSpace: ctx.teamId || void 0,
1379
- GroupSystemPrompt: groupSystemPrompt,
1380
- UntrustedContext: untrustedChannelMetadata ? [untrustedChannelMetadata] : void 0,
1381
- SenderName: senderName,
1382
- SenderId: senderId,
1383
- Provider: "slack",
1384
- Surface: "slack",
1385
- MessageSid: message.ts,
1386
- ReplyToId: threadContext.replyToId,
1387
- MessageThreadId: threadContext.messageThreadId,
1388
- ParentSessionKey: threadKeys.parentSessionKey,
1389
- ThreadStarterBody: !threadSessionPreviousTimestamp ? threadStarterBody : void 0,
1390
- ThreadHistoryBody: threadHistoryBody,
1391
- IsFirstThreadTurn: isThreadReply && threadTs && !threadSessionPreviousTimestamp ? true : void 0,
1392
- ThreadLabel: threadLabel,
1393
- Timestamp: message.ts ? Math.round(Number(message.ts) * 1e3) : void 0,
1394
- ...buildSlackMentionContextPayload({
1395
- isRoomish,
1396
- effectiveWasMentioned,
1397
- explicitlyMentioned,
1398
- mentionedUserIds,
1399
- mentionedSubteamIds,
1400
- matchedImplicitMentionKinds,
1401
- mentionSource
1402
- }),
1403
- MediaPath: firstMedia?.path,
1404
- MediaType: firstMedia?.contentType,
1405
- MediaUrl: firstMedia?.path,
1406
- MediaPaths: effectiveMedia && effectiveMedia.length > 0 ? effectiveMedia.map((m) => m.path) : void 0,
1407
- MediaUrls: effectiveMedia && effectiveMedia.length > 0 ? effectiveMedia.map((m) => m.path) : void 0,
1408
- MediaTypes: effectiveMedia && effectiveMedia.length > 0 ? effectiveMedia.map((m) => m.contentType ?? "") : void 0,
1409
- CommandAuthorized: commandAuthorized,
1410
- OriginatingChannel: "slack",
1411
- OriginatingTo: slackTo,
1412
- NativeChannelId: message.channel
1461
+ const ctxPayload = buildChannelTurnContext({
1462
+ channel: "slack",
1463
+ provider: "slack",
1464
+ surface: "slack",
1465
+ accountId: route.accountId,
1466
+ messageId: message.ts,
1467
+ timestamp: message.ts ? Math.round(Number(message.ts) * 1e3) : void 0,
1468
+ from: slackFrom,
1469
+ sender: {
1470
+ id: senderId,
1471
+ name: senderName,
1472
+ displayLabel: senderName
1473
+ },
1474
+ conversation: {
1475
+ kind: chatType,
1476
+ id: message.channel,
1477
+ label: envelopeFrom,
1478
+ spaceId: ctx.teamId || void 0,
1479
+ threadId: threadContext.messageThreadId,
1480
+ nativeChannelId: message.channel,
1481
+ routePeer: {
1482
+ kind: chatType,
1483
+ id: message.channel
1484
+ }
1485
+ },
1486
+ route: {
1487
+ agentId: route.agentId,
1488
+ accountId: route.accountId,
1489
+ routeSessionKey: sessionKey,
1490
+ parentSessionKey: threadKeys.parentSessionKey
1491
+ },
1492
+ reply: {
1493
+ to: slackTo,
1494
+ originatingTo: slackTo,
1495
+ replyToId: threadContext.replyToId,
1496
+ messageThreadId: threadContext.messageThreadId,
1497
+ nativeChannelId: message.channel
1498
+ },
1499
+ message: {
1500
+ body: combinedBody,
1501
+ bodyForAgent: rawBody,
1502
+ rawBody,
1503
+ commandBody,
1504
+ envelopeFrom,
1505
+ inboundHistory
1506
+ },
1507
+ access: {
1508
+ mentions: {
1509
+ canDetectMention: isRoomish,
1510
+ wasMentioned: effectiveWasMentioned,
1511
+ hasAnyMention: explicitlyMentioned || mentionedSubteamIds.length > 0,
1512
+ implicitMentionKinds: matchedImplicitMentionKinds,
1513
+ requireMention: shouldRequireMention,
1514
+ effectiveWasMentioned
1515
+ },
1516
+ commands: {
1517
+ authorized: commandAuthorized,
1518
+ allowTextCommands,
1519
+ useAccessGroups: false,
1520
+ authorizers: []
1521
+ }
1522
+ },
1523
+ media: toInboundMediaFacts(effectiveMedia),
1524
+ supplemental: {
1525
+ thread: {
1526
+ starterBody: !threadSessionPreviousTimestamp ? threadStarterBody : void 0,
1527
+ historyBody: threadHistoryBody,
1528
+ label: threadLabel
1529
+ },
1530
+ groupSystemPrompt
1531
+ },
1532
+ extra: {
1533
+ GroupSubject: isRoomish ? roomLabel : void 0,
1534
+ UntrustedContext: untrustedChannelMetadata ? [untrustedChannelMetadata] : void 0,
1535
+ IsFirstThreadTurn: isThreadReply && threadTs && !threadSessionPreviousTimestamp ? true : void 0,
1536
+ ...buildSlackMentionContextPayload({
1537
+ isRoomish,
1538
+ effectiveWasMentioned,
1539
+ explicitlyMentioned,
1540
+ mentionedUserIds,
1541
+ mentionedSubteamIds,
1542
+ matchedImplicitMentionKinds,
1543
+ mentionSource
1544
+ })
1545
+ }
1413
1546
  });
1414
- if (isRoomish && !shouldRequireMention) recordPendingHistoryEntryIfEnabled({
1415
- historyMap: ctx.channelHistories,
1547
+ if (isRoomish && !shouldRequireMention) channelHistory.record({
1416
1548
  historyKey,
1417
1549
  limit: ctx.historyLimit,
1418
1550
  entry: {
@@ -1465,7 +1597,13 @@ async function prepareSlackMessage(params) {
1465
1597
  sessionKey
1466
1598
  }, "failed updating session meta");
1467
1599
  }
1468
- }
1600
+ },
1601
+ history: isRoomish && shouldRequireMention ? {
1602
+ isGroup: true,
1603
+ historyKey,
1604
+ historyMap: ctx.channelHistories,
1605
+ limit: ctx.historyLimit
1606
+ } : void 0
1469
1607
  },
1470
1608
  replyToMode,
1471
1609
  requireMention: shouldRequireMention,
@@ -1,4 +1,4 @@
1
- import { f as createSlackMonitorContext } from "./room-context-D0hGOp8m.js";
1
+ import { f as createSlackMonitorContext } from "./room-context-Cd8jFpS-.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,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
- import { r as createSlackWebClient } from "./client-8r7r7aZ3.js";
3
- import { t as formatSlackError } from "./errors-BrtayXHa.js";
2
+ import { r as createSlackWebClient } from "./client-C_IaJbi5.js";
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
6
6
  var probe_exports = /* @__PURE__ */ __exportAll({ probeSlack: () => probeSlack });