@openclaw/slack 2026.7.2-beta.2 → 2026.7.2-beta.3
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/{account-configured-DzC407uv.js → account-configured-BwfXBo_F.js} +1 -1
- package/dist/{account-inspect-Di7ditqZ.js → account-inspect-Bvbtu3iH.js} +9 -2
- package/dist/account-inspect-api.js +1 -1
- package/dist/{accounts-BOJJiHSr.js → accounts-DQEbYKh9.js} +9 -0
- package/dist/accounts.runtime-BIKmJdtJ.js +2 -0
- package/dist/{action-runtime-Cee2ih0s.js → action-runtime-DqkRwO3Z.js} +10 -16
- package/dist/action-runtime.runtime-DEWOcFM4.js +2 -0
- package/dist/{actions-BZiuSTIq.js → actions-CF0tUY5q.js} +4 -4
- package/dist/{actions.runtime-DoD0-gxw.js → actions.runtime-hCbx4RXg.js} +1 -1
- package/dist/api.js +13 -14
- package/dist/{approval-handler.runtime-CUPtIM4k.js → approval-handler.runtime-Em8I1-8-.js} +2 -2
- package/dist/{channel-DaIiGUOp.js → channel-4-TRi1D6.js} +72 -40
- package/dist/channel-config-api.js +1 -1
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel-type-Cfm6_6n1.js → channel-type-Cu1yjNg2.js} +3 -3
- package/dist/{channel.setup-C-mLz50O.js → channel.setup-CgkADtZg.js} +6 -4
- package/dist/{config-schema-xPSnK2VK.js → config-schema-XjJGfwQC.js} +6 -5
- package/dist/{directory-config-DRkFujwG.js → directory-config-Bv0lcUlH.js} +1 -1
- package/dist/directory-contract-api.js +1 -1
- package/dist/{directory-live-D_yZhjgp.js → directory-live-CzUIB7th.js} +2 -2
- package/dist/{doctor-contract-DddfkMlF.js → doctor-contract-DKpe5VBr.js} +80 -12
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{group-policy-85UWiriS.js → group-policy-Bw-65m3V.js} +67 -121
- package/dist/{interactive-replies-BilWUdcI.js → interactive-replies-Dm_t2R9S.js} +1 -1
- package/dist/interactive-replies-api.js +1 -1
- package/dist/{message-tool-api-CA9jZrCY.js → message-tool-api-C2pcf5du.js} +3 -3
- package/dist/message-tool-api.js +1 -1
- package/dist/{monitor-CalGciTs.js → monitor-CNFeF30h.js} +3 -3
- package/dist/{outbound-adapter-BiLKcnyH.js → outbound-adapter-CVi2uok0.js} +49 -5
- package/dist/{pipeline.runtime-DofAvTtb.js → pipeline.runtime-CTvokbty.js} +391 -279
- package/dist/{policy-BVs4LiSa.js → policy-b_dOPDCq.js} +1 -1
- package/dist/probe-Borhn9PQ.js +340 -0
- package/dist/{provider-CmeoUiIM.js → provider-B-HVL5ZE.js} +573 -306
- package/dist/{relay-source-DMmgtvg4.js → relay-source-Ea_P9VcO.js} +6 -11
- package/dist/{replies-CJJCp6qz.js → replies-B4bOdrYb.js} +3 -3
- package/dist/{resolve-channels-Rfts6POK.js → resolve-channels-KTc568SU.js} +1 -1
- package/dist/{resolve-users-y6wAxR8E.js → resolve-users-DeGJf1yp.js} +1 -1
- package/dist/{runtime-api-BGDyOt1D.js → runtime-api-BFfNpzDe.js} +1 -1
- package/dist/runtime-api.js +11 -11
- package/dist/{scopes-CuxNQZ6v.js → scopes-lx08L56K.js} +1 -2
- package/dist/{secret-contract-CMohXFWS.js → secret-contract-DxmvbxBF.js} +1 -0
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-DYp8ca-l.js → send-KuTDky7i.js} +28 -11
- package/dist/send.runtime-CXyxws1D.js +2 -0
- package/dist/{setup-core-CkwVLzFO.js → setup-core-CeiAVwQ3.js} +218 -53
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-oSd3NX9J.js → setup-surface-DLA0vHXp.js} +23 -13
- package/dist/{shared-D9yz5Otg.js → shared-C4yVB0Q-.js} +55 -9
- package/dist/{slash-dispatch.runtime-CSja9VuD.js → slash-dispatch.runtime-BT-mMm-f.js} +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/openclaw.plugin.json +66 -10
- package/package.json +4 -4
- package/dist/accounts.runtime-KvftRRek.js +0 -2
- package/dist/action-runtime.runtime-DZfd7IFr.js +0 -2
- package/dist/client-WIPAS3Yr.js +0 -160
- package/dist/probe-CN0ssfLN.js +0 -48
- package/dist/send.runtime-CJLxAt26.js +0 -2
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { u as resolveSlackReplyToMode } from "./accounts-
|
|
1
|
+
import { u as resolveSlackReplyToMode } from "./accounts-DQEbYKh9.js";
|
|
2
2
|
import { i as parseSlackTarget } from "./target-parsing-N6lHogYZ.js";
|
|
3
3
|
import "./targets-KmjP2E8s.js";
|
|
4
|
-
import {
|
|
5
|
-
import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-
|
|
4
|
+
import { C as hasSlackNativeDataBlock, F as SLACK_TEXT_LIMIT, N as SLACK_EDIT_TEXT_LIMIT, O as normalizeSlackOutboundText, Y as escapeSlackMrkdwn, _ as resolveSlackReplyRenderPlan, c as normalizeSlackAllowOwnerEntry, k as buildSlackBlocksFallbackText, s as normalizeAllowListLower, u as resolveSlackAllowListMatch, z as truncateSlackText } from "./group-policy-Bw-65m3V.js";
|
|
5
|
+
import { n as isSlackInteractiveRepliesEnabled, t as compileSlackInteractiveReplies } from "./interactive-replies-Dm_t2R9S.js";
|
|
6
|
+
import { r as formatSlackError } from "./probe-Borhn9PQ.js";
|
|
6
7
|
import { n as resolveSlackNativeStreaming, r as resolveSlackStreamingMode, t as mapStreamingModeToSlackLegacyDraftStreamMode } from "./streaming-compat-3_X-21wW.js";
|
|
7
|
-
import { S as buildSlackEditTextPayload, _ as resolveSlackThreadHistory, b as resolveSlackBlocksText, f as removeSlackReaction, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage, v as resolveSlackThreadStarter, x as formatSlackFileReference, y as chooseSlackPrimaryText } from "./actions-
|
|
8
|
-
import { c as
|
|
9
|
-
import {
|
|
10
|
-
import { n as resolveSlackChannelConfig } from "./policy-
|
|
11
|
-
import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, s as emitSlackMessageSentHooks, t as createSlackReplyDeliveryPlan } from "./replies-
|
|
8
|
+
import { S as buildSlackEditTextPayload, _ as resolveSlackThreadHistory, b as resolveSlackBlocksText, f as removeSlackReaction, l as reactSlackMessage, r as editSlackMessage, t as deleteSlackMessage, v as resolveSlackThreadStarter, x as formatSlackFileReference, y as chooseSlackPrimaryText } from "./actions-CF0tUY5q.js";
|
|
9
|
+
import { c as hasSlackThreadParticipationWithPersistence, l as recordSlackThreadParticipation, r as sendMessageSlack, u as buildSlackNativeDataDeliveryPlan } from "./send-KuTDky7i.js";
|
|
10
|
+
import { C as stripSlackMentionsForCommandDetection, _ as readSessionUpdatedAt, b as resolveStorePath, d as resolveSlackCommandIngress, f as resolveSlackEffectiveAllowFrom, g as resolveSlackChatType, h as normalizeSlackChannelType, l as resolveConversationLabel$1, m as parseSlackAssistantThreadMetadata, o as authorizeSlackDirectMessage, p as buildSlackAssistantThreadMetadata, r as resolveSlackRoomContextHints, u as authorizeSlackBotRoomMessage, v as resolveChannelContextVisibilityMode, x as updateLastRoute, y as resolveChannelResetConfig } from "./provider-B-HVL5ZE.js";
|
|
11
|
+
import { n as resolveSlackChannelConfig } from "./policy-b_dOPDCq.js";
|
|
12
|
+
import { a as resolveDeliveredSlackReplyThreadTs, i as readSlackReplyBlocks, n as deliverReplies, o as resolveSlackThreadTs, s as emitSlackMessageSentHooks, t as createSlackReplyDeliveryPlan } from "./replies-B4bOdrYb.js";
|
|
12
13
|
import { asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
13
14
|
import { resolveAgentRoute, resolveInboundLastRouteSessionKey, resolveThreadSessionKeys } from "openclaw/plugin-sdk/routing";
|
|
14
|
-
import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline,
|
|
15
|
+
import { buildChannelProgressDraftLine, buildChannelProgressDraftLineForEntry, createChannelMessageReplyPipeline, createChannelProgressDraftCompositor, createChannelProgressReceiptTracker, createDraftStreamLoop, defineFinalizableLivePreviewAdapter, deliverWithFinalizableLivePreviewAdapter, formatChannelProgressDraftText, formatPlanChecklistLines, isChannelProgressDraftWorkToolName, mergeChannelProgressDraftLine, resolveAgentOutboundIdentity, resolveChannelMessageSourceReplyDeliveryMode, resolveChannelProgressDraftConfig, resolveChannelProgressDraftMaxLineChars, resolveChannelProgressDraftMaxLines, resolveChannelProgressDraftRender, resolveChannelStreamingBlockEnabled, resolveChannelStreamingNativeTransport, resolveChannelStreamingPreviewToolProgress, resolveChannelStreamingSuppressDefaultToolProgressMessages } from "openclaw/plugin-sdk/channel-outbound";
|
|
15
16
|
import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
|
16
17
|
import { danger, logVerbose, shouldLogVerbose, sleep } from "openclaw/plugin-sdk/runtime-env";
|
|
17
|
-
import { stripReasoningTagsFromText } from "openclaw/plugin-sdk/text-chunking";
|
|
18
18
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
19
19
|
import { createHash } from "node:crypto";
|
|
20
20
|
import fs from "node:fs/promises";
|
|
@@ -27,9 +27,9 @@ import { createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
|
27
27
|
import { resolveHumanDelayConfig } from "openclaw/plugin-sdk/agent-runtime";
|
|
28
28
|
import { mergePairLoopGuardConfig } from "openclaw/plugin-sdk/pair-loop-guard-runtime";
|
|
29
29
|
import { enqueueSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
|
|
30
|
-
import {
|
|
30
|
+
import { resolveChannelImplicitMentions } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
31
|
+
import { buildChannelInboundEventContext, buildMentionRegexes, classifyChannelInboundEvent, dispatchChannelInboundTurn, formatInboundEnvelope, hasVisibleInboundReplyDispatch, implicitMentionKindWhen, logInboundDrop, matchesMentionWithExplicit, recordDroppedChannelInboundHistory, resolveEnvelopeFormatOptions, resolveInboundMentionDecision, resolveInboundSupplementalSenderAllowed, resolveUnmentionedGroupInboundPolicy, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
|
|
31
32
|
import { DEFAULT_TIMING, createStatusReactionController, logAckFailure, logTypingFailure, removeAckReactionAfterReply, resolveAckReaction, shouldAckReaction } from "openclaw/plugin-sdk/channel-feedback";
|
|
32
|
-
import { dispatchReplyWithBufferedBlockDispatcher } from "openclaw/plugin-sdk/reply-runtime";
|
|
33
33
|
import { hasControlCommand } from "openclaw/plugin-sdk/command-detection";
|
|
34
34
|
import { isAbortRequestText } from "openclaw/plugin-sdk/command-primitives-runtime";
|
|
35
35
|
import { shouldHandleTextCommands } from "openclaw/plugin-sdk/command-surface";
|
|
@@ -216,9 +216,24 @@ function lineTaskStatus(line) {
|
|
|
216
216
|
function slugTaskIdPart(value) {
|
|
217
217
|
return value?.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "task";
|
|
218
218
|
}
|
|
219
|
-
function stableTaskIdPart(value) {
|
|
219
|
+
function stableTaskIdPart(value, slugValue = value) {
|
|
220
220
|
const suffix = createHash("sha256").update(value).digest("hex").slice(0, 8);
|
|
221
|
-
return `${slugTaskIdPart(
|
|
221
|
+
return `${slugTaskIdPart(slugValue).slice(0, 48)}_${suffix}`;
|
|
222
|
+
}
|
|
223
|
+
function resolveLineTaskIdentity(line) {
|
|
224
|
+
if (line.id?.trim()) return {
|
|
225
|
+
id: stableTaskIdPart(line.id),
|
|
226
|
+
contentDerived: false
|
|
227
|
+
};
|
|
228
|
+
return {
|
|
229
|
+
id: stableTaskIdPart([
|
|
230
|
+
line.kind,
|
|
231
|
+
line.toolName,
|
|
232
|
+
line.label,
|
|
233
|
+
line.text
|
|
234
|
+
].join("\0"), line.toolName ?? line.kind ?? line.label),
|
|
235
|
+
contentDerived: true
|
|
236
|
+
};
|
|
222
237
|
}
|
|
223
238
|
function buildPlanTasks(params) {
|
|
224
239
|
if (params.plan) return params.plan.slice(-50).map((entry, index) => ({
|
|
@@ -227,11 +242,23 @@ function buildPlanTasks(params) {
|
|
|
227
242
|
status: entry.status === "completed" ? "complete" : entry.status
|
|
228
243
|
}));
|
|
229
244
|
const maxLineChars = resolveMaxLineChars(params.maxLineChars, DEFAULT_SLACK_PROGRESS_TASK_DETAIL_MAX_CHARS);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
245
|
+
const lines = params.lines.slice(-50);
|
|
246
|
+
const identities = lines.map(resolveLineTaskIdentity);
|
|
247
|
+
const contentIdOccurrences = /* @__PURE__ */ new Map();
|
|
248
|
+
return lines.map((line, index) => {
|
|
249
|
+
const identity = identities[index];
|
|
250
|
+
let id = identity.id;
|
|
251
|
+
if (identity.contentDerived) {
|
|
252
|
+
const occurrence = (contentIdOccurrences.get(id) ?? 0) + 1;
|
|
253
|
+
contentIdOccurrences.set(id, occurrence);
|
|
254
|
+
id = `${id}_${occurrence}`;
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
id,
|
|
258
|
+
title: lineTaskTitle(line, maxLineChars),
|
|
259
|
+
status: lineTaskStatus(line)
|
|
260
|
+
};
|
|
261
|
+
});
|
|
235
262
|
}
|
|
236
263
|
function resolvePlanTitle(params) {
|
|
237
264
|
return compactChunkText(params.title?.trim() || params.label?.trim() || params.tasks.at(-1)?.title || SLACK_PROGRESS_PLAN_FALLBACK_TITLE);
|
|
@@ -242,7 +269,13 @@ function buildSlackProgressStreamChunks(params) {
|
|
|
242
269
|
plan: params.plan,
|
|
243
270
|
maxLineChars: params.maxLineChars
|
|
244
271
|
});
|
|
245
|
-
if (tasks.length === 0)
|
|
272
|
+
if (tasks.length === 0) {
|
|
273
|
+
const title = params.title?.trim() || params.label?.trim();
|
|
274
|
+
return title ? [{
|
|
275
|
+
type: "plan_update",
|
|
276
|
+
title: compactChunkText(title)
|
|
277
|
+
}] : void 0;
|
|
278
|
+
}
|
|
246
279
|
return [{
|
|
247
280
|
type: "plan_update",
|
|
248
281
|
title: resolvePlanTitle({
|
|
@@ -710,15 +743,6 @@ function resolveSlackTimestampMs(ts) {
|
|
|
710
743
|
}
|
|
711
744
|
//#endregion
|
|
712
745
|
//#region extensions/slack/src/monitor/message-handler/dispatch.ts
|
|
713
|
-
const SLACK_REASONING_TAG_RE = /<\s*(\/?)\s*(?:(?:antml:|mm:)?(?:think(?:ing)?|thought)|antthinking)\b[^<>]*>/gi;
|
|
714
|
-
const SLACK_REASONING_LABEL_PREFIX_RE = /^\s*(?:>\s*)?Reasoning:\s*/iu;
|
|
715
|
-
const SLACK_THINKING_LABEL_PREFIX_RE = /^\s*(?:>\s*)?Thinking\.{0,3}(?=\s*(?:\n|_))/iu;
|
|
716
|
-
const SLACK_THREAD_LOADING_MESSAGES = [
|
|
717
|
-
"Reading the thread...",
|
|
718
|
-
"Checking context...",
|
|
719
|
-
"Working through the request...",
|
|
720
|
-
"Putting it all together..."
|
|
721
|
-
];
|
|
722
746
|
function resolveSlackMessageTimestampMs(message) {
|
|
723
747
|
return resolveSlackTimestampMs(message.event_ts ?? message.ts);
|
|
724
748
|
}
|
|
@@ -820,43 +844,6 @@ function rememberSlackStreamRecipientTeam(params) {
|
|
|
820
844
|
if (oldest) cache.delete(oldest);
|
|
821
845
|
}
|
|
822
846
|
}
|
|
823
|
-
function normalizeSlackReasoningProgressLine(text) {
|
|
824
|
-
return (extractSlackReasoningTagText(text) || stripReasoningTagsFromText(text, {
|
|
825
|
-
mode: "strict",
|
|
826
|
-
trim: "both"
|
|
827
|
-
})).replace(SLACK_REASONING_LABEL_PREFIX_RE, "").replace(SLACK_THINKING_LABEL_PREFIX_RE, "").split(/\r?\n/u).map((line) => stripSimpleItalicMarkers(line)).filter(Boolean).join(" ").replace(/\s+/g, " ").trim();
|
|
828
|
-
}
|
|
829
|
-
function extractSlackReasoningTagText(text) {
|
|
830
|
-
if (!text) return "";
|
|
831
|
-
let result = "";
|
|
832
|
-
let lastIndex = 0;
|
|
833
|
-
let inReasoning = false;
|
|
834
|
-
SLACK_REASONING_TAG_RE.lastIndex = 0;
|
|
835
|
-
for (const match of text.matchAll(SLACK_REASONING_TAG_RE)) {
|
|
836
|
-
const index = match.index ?? 0;
|
|
837
|
-
if (inReasoning) result += text.slice(lastIndex, index);
|
|
838
|
-
inReasoning = match[1] !== "/";
|
|
839
|
-
lastIndex = index + match[0].length;
|
|
840
|
-
}
|
|
841
|
-
if (inReasoning) result += text.slice(lastIndex);
|
|
842
|
-
return result.trim();
|
|
843
|
-
}
|
|
844
|
-
function stripSimpleItalicMarkers(line) {
|
|
845
|
-
const trimmed = line.trim();
|
|
846
|
-
if (trimmed.length >= 2 && trimmed.startsWith("_") && trimmed.endsWith("_")) return trimmed.slice(1, -1).trim();
|
|
847
|
-
return trimmed;
|
|
848
|
-
}
|
|
849
|
-
function mergeSlackReasoningProgressText(current, incoming, options) {
|
|
850
|
-
if (!current) return incoming;
|
|
851
|
-
const normalizedCurrent = normalizeSlackReasoningProgressLine(current);
|
|
852
|
-
const normalizedIncoming = normalizeSlackReasoningProgressLine(incoming);
|
|
853
|
-
if (!normalizedIncoming || normalizedIncoming === normalizedCurrent) return current;
|
|
854
|
-
if (options?.snapshot === true || isSlackReasoningSnapshotText(incoming) || normalizedIncoming.startsWith(normalizedCurrent)) return incoming;
|
|
855
|
-
return `${current}${incoming}`;
|
|
856
|
-
}
|
|
857
|
-
function isSlackReasoningSnapshotText(text) {
|
|
858
|
-
return SLACK_REASONING_LABEL_PREFIX_RE.test(text) || SLACK_THINKING_LABEL_PREFIX_RE.test(text);
|
|
859
|
-
}
|
|
860
847
|
function createSlackEventDeliveryTracker() {
|
|
861
848
|
const deliveredKeys = /* @__PURE__ */ new Set();
|
|
862
849
|
return {
|
|
@@ -1036,7 +1023,6 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1036
1023
|
channelId: message.channel,
|
|
1037
1024
|
threadTs: statusThreadTs,
|
|
1038
1025
|
status: "is typing...",
|
|
1039
|
-
loadingMessages: SLACK_THREAD_LOADING_MESSAGES,
|
|
1040
1026
|
eventScope: prepared.eventScope
|
|
1041
1027
|
});
|
|
1042
1028
|
if (typingReaction && message.ts) await reactSlackMessage(message.channel, message.ts, typingReaction, {
|
|
@@ -1156,6 +1142,11 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1156
1142
|
delivery.outcome = "success";
|
|
1157
1143
|
}
|
|
1158
1144
|
};
|
|
1145
|
+
const acknowledgeStoppedStreamedDeliveries = (session, messageId) => {
|
|
1146
|
+
refreshStreamedAcknowledgements(session);
|
|
1147
|
+
for (const delivery of streamedDeliveries) delivery.acknowledged = true;
|
|
1148
|
+
emitAcknowledgedStreamedDeliveries(messageId);
|
|
1149
|
+
};
|
|
1159
1150
|
const emitFailedPendingStreamedDeliveries = (error) => {
|
|
1160
1151
|
for (const delivery of streamedDeliveries) {
|
|
1161
1152
|
if (delivery.acknowledged || delivery.outcome) continue;
|
|
@@ -1209,8 +1200,7 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1209
1200
|
session,
|
|
1210
1201
|
...slackMessageMetadata ? { metadata: slackMessageMetadata } : {}
|
|
1211
1202
|
});
|
|
1212
|
-
|
|
1213
|
-
emitAcknowledgedStreamedDeliveries(stopResult.messageId);
|
|
1203
|
+
acknowledgeStoppedStreamedDeliveries(session, stopResult.messageId);
|
|
1214
1204
|
observedReplyDelivery = true;
|
|
1215
1205
|
usedReplyThreadTs ??= session.threadTs;
|
|
1216
1206
|
return true;
|
|
@@ -1319,6 +1309,24 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1319
1309
|
rememberDeliveredThreadTs(params.kind, params.session.threadTs);
|
|
1320
1310
|
return true;
|
|
1321
1311
|
};
|
|
1312
|
+
const appendNativeProgressCompletion = async (isError) => {
|
|
1313
|
+
const session = streamSession;
|
|
1314
|
+
if (isError) nativeProgressTerminalStatus = "error";
|
|
1315
|
+
if (!session || nativeProgressCompletionSent) return;
|
|
1316
|
+
const chunks = buildNativeProgressCompletionChunks(isError ? "error" : "complete");
|
|
1317
|
+
if (!chunks?.length) return;
|
|
1318
|
+
try {
|
|
1319
|
+
await appendSlackStream({
|
|
1320
|
+
session,
|
|
1321
|
+
chunks
|
|
1322
|
+
});
|
|
1323
|
+
nativeProgressCompletionSent = true;
|
|
1324
|
+
observedReplyDelivery ||= session.delivered;
|
|
1325
|
+
} catch (err) {
|
|
1326
|
+
streamFailed = true;
|
|
1327
|
+
runtime.error?.(danger(`slack-stream: native progress completion failed: ${formatSlackError(err)}`));
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1322
1330
|
const deliverWithStreaming = async (params) => {
|
|
1323
1331
|
if (params.payload.isReasoning === true) return;
|
|
1324
1332
|
const reply = resolveSendableOutboundReplyParts(params.payload);
|
|
@@ -1344,13 +1352,6 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1344
1352
|
});
|
|
1345
1353
|
return;
|
|
1346
1354
|
}
|
|
1347
|
-
if (useNativeProgressStreaming && !streamSession) {
|
|
1348
|
-
await deliverNormally({
|
|
1349
|
-
payload: params.payload,
|
|
1350
|
-
kind: params.kind
|
|
1351
|
-
});
|
|
1352
|
-
return;
|
|
1353
|
-
}
|
|
1354
1355
|
if (!streamSession) {
|
|
1355
1356
|
const streamThreadTs = replyPlan.nextThreadTs();
|
|
1356
1357
|
plannedThreadTs = streamThreadTs;
|
|
@@ -1411,40 +1412,12 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1411
1412
|
logVerbose("slack-stream: suppressed duplicate append payload");
|
|
1412
1413
|
return;
|
|
1413
1414
|
}
|
|
1414
|
-
const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent && (previewToolProgressLines.length > 0 || Boolean(latestPlan?.length) || Boolean(latestPlanExplanation) || [...nativeTaskState.values()].some((task) => task.status !== "complete" && task.status !== "error")) ? reconcileSlackNativeTaskChunks({
|
|
1415
|
-
previousTasks: nativeTaskState,
|
|
1416
|
-
chunks: buildSlackProgressStreamCompletionChunks({
|
|
1417
|
-
title: resolveNativeProgressTitle(),
|
|
1418
|
-
lines: resolveNativeProgressLines(),
|
|
1419
|
-
plan: resolveNativeProgressPlan(),
|
|
1420
|
-
maxLineChars: progressDraftMaxLineChars,
|
|
1421
|
-
finalInProgressStatus: params.payload.isError ? "error" : "complete"
|
|
1422
|
-
})
|
|
1423
|
-
}).chunks : void 0;
|
|
1424
|
-
if (useNativeProgressStreaming) {
|
|
1425
|
-
if (completionChunks?.length) {
|
|
1426
|
-
await appendSlackStream({
|
|
1427
|
-
session: streamSession,
|
|
1428
|
-
chunks: completionChunks
|
|
1429
|
-
});
|
|
1430
|
-
nativeProgressCompletionSent = true;
|
|
1431
|
-
if (streamSession.delivered) observedReplyDelivery = true;
|
|
1432
|
-
}
|
|
1433
|
-
await deliverNormally({
|
|
1434
|
-
payload: params.payload,
|
|
1435
|
-
kind: params.kind,
|
|
1436
|
-
forcedThreadTs: streamSession.threadTs
|
|
1437
|
-
});
|
|
1438
|
-
return;
|
|
1439
|
-
}
|
|
1440
1415
|
if (text) recordStreamedDelivery(params.kind, text);
|
|
1441
1416
|
await appendSlackStream({
|
|
1442
1417
|
session: streamSession,
|
|
1443
|
-
text: "\n" + text
|
|
1444
|
-
chunks: completionChunks
|
|
1418
|
+
text: "\n" + text
|
|
1445
1419
|
});
|
|
1446
1420
|
refreshStreamedAcknowledgements(streamSession);
|
|
1447
|
-
if (completionChunks?.length) nativeProgressCompletionSent = true;
|
|
1448
1421
|
if (streamSession.delivered) {
|
|
1449
1422
|
observedReplyDelivery = true;
|
|
1450
1423
|
if (params.kind === "final") observedFinalReplyDelivery = true;
|
|
@@ -1491,13 +1464,59 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1491
1464
|
await deliverNormally({
|
|
1492
1465
|
payload: params.payload,
|
|
1493
1466
|
kind: params.kind,
|
|
1494
|
-
forcedThreadTs: streamSession?.threadTs ?? plannedThreadTs
|
|
1467
|
+
forcedThreadTs: streamSession?.threadTs ?? nativeProgressStreamThreadTs ?? plannedThreadTs
|
|
1495
1468
|
});
|
|
1496
1469
|
}
|
|
1497
1470
|
};
|
|
1498
1471
|
let draftPreviewCommitted = false;
|
|
1499
1472
|
const deliverSlackPayload = async (payload, info) => {
|
|
1500
1473
|
if (payload.isReasoning === true) return { visibleReplySent: false };
|
|
1474
|
+
if (info.kind === "final" && slackStreaming.mode === "progress" && streamMode === "status_final") {
|
|
1475
|
+
const hadProgressDraft = progressDraft.hasStarted;
|
|
1476
|
+
progressDraft.markFinalReplyStarted();
|
|
1477
|
+
if (useNativeProgressStreaming) {
|
|
1478
|
+
await waitForNativeProgressStreamStart();
|
|
1479
|
+
const finalThreadTs = streamSession?.threadTs ?? nativeProgressStreamThreadTs;
|
|
1480
|
+
await deliverNormally({
|
|
1481
|
+
payload,
|
|
1482
|
+
kind: info.kind,
|
|
1483
|
+
forcedThreadTs: finalThreadTs
|
|
1484
|
+
});
|
|
1485
|
+
await appendNativeProgressCompletion(payload.isError === true);
|
|
1486
|
+
progressDraft.markFinalReplyDelivered();
|
|
1487
|
+
if (!payload.isError && hadProgressDraft && streamSession) pendingNativeProgressReceipt = progressReceipt.buildSummaryLine();
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
if (hadProgressDraft) try {
|
|
1491
|
+
await draftStream?.flush();
|
|
1492
|
+
} catch (err) {
|
|
1493
|
+
logVerbose(`slack: progress draft flush before final failed (${formatSlackError(err)})`);
|
|
1494
|
+
}
|
|
1495
|
+
const receiptChannelId = hadProgressDraft ? draftStream?.channelId() : void 0;
|
|
1496
|
+
const receiptMessageId = hadProgressDraft ? draftStream?.messageId() : void 0;
|
|
1497
|
+
const draftThreadTs = hadProgressDraft ? usedReplyThreadTs ?? statusThreadTs : void 0;
|
|
1498
|
+
await deliverNormally({
|
|
1499
|
+
payload,
|
|
1500
|
+
kind: info.kind,
|
|
1501
|
+
...draftThreadTs ? { forcedThreadTs: draftThreadTs } : {}
|
|
1502
|
+
});
|
|
1503
|
+
progressDraft.markFinalReplyDelivered();
|
|
1504
|
+
if (!payload.isError && receiptChannelId && receiptMessageId && !progressReceiptCollapsed) await collapseProgressReceipt({
|
|
1505
|
+
channelId: receiptChannelId,
|
|
1506
|
+
messageId: receiptMessageId,
|
|
1507
|
+
text: progressReceipt.buildSummaryLine(),
|
|
1508
|
+
threadTs: usedReplyThreadTs ?? statusThreadTs
|
|
1509
|
+
});
|
|
1510
|
+
return;
|
|
1511
|
+
}
|
|
1512
|
+
if (useNativeProgressStreaming) {
|
|
1513
|
+
await deliverNormally({
|
|
1514
|
+
payload,
|
|
1515
|
+
kind: info.kind,
|
|
1516
|
+
forcedThreadTs: streamSession?.threadTs ?? nativeProgressStreamThreadTs
|
|
1517
|
+
});
|
|
1518
|
+
return;
|
|
1519
|
+
}
|
|
1501
1520
|
if (useStreaming) {
|
|
1502
1521
|
await deliverWithStreaming({
|
|
1503
1522
|
payload,
|
|
@@ -1688,8 +1707,6 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1688
1707
|
const useNativeProgressStreaming = useStreaming && slackStreaming.mode === "progress";
|
|
1689
1708
|
const progressDraftActive = Boolean(draftStream) || useNativeProgressStreaming;
|
|
1690
1709
|
const previewToolProgressEnabled = progressDraftActive && resolveChannelStreamingPreviewToolProgress(account.config);
|
|
1691
|
-
const commentaryProgressEnabled = progressDraftActive && resolveChannelStreamingProgressCommentary(account.config);
|
|
1692
|
-
const commentaryDraftEnabled = progressDraftActive && (slackStreaming.mode === "progress" ? resolveChannelStreamingProgressCommentary(account.config, previewToolProgressEnabled) : previewToolProgressEnabled);
|
|
1693
1710
|
let shouldYieldDraftProgress = () => false;
|
|
1694
1711
|
const suppressDefaultToolProgressMessages = resolveChannelStreamingSuppressDefaultToolProgressMessages(account.config, {
|
|
1695
1712
|
draftStreamActive: Boolean(draftStream) || useNativeProgressStreaming,
|
|
@@ -1697,46 +1714,20 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1697
1714
|
previewStreamingEnabled
|
|
1698
1715
|
});
|
|
1699
1716
|
let previewToolProgressSuppressed = false;
|
|
1700
|
-
let
|
|
1701
|
-
let lastNonEmptyPreviewToolProgressLines = [];
|
|
1702
|
-
let latestPlan;
|
|
1703
|
-
let latestPlanExplanation;
|
|
1717
|
+
let legacyPreviewToolProgressLines = [];
|
|
1704
1718
|
let nativeTaskState = /* @__PURE__ */ new Map();
|
|
1705
1719
|
let appendRenderedText = "";
|
|
1706
1720
|
let appendSourceText = "";
|
|
1707
|
-
let reasoningProgressRawText = "";
|
|
1708
|
-
let statusUpdateCount = 0;
|
|
1709
1721
|
let nativeProgressCompletionSent = false;
|
|
1722
|
+
let nativeProgressTerminalStatus = "complete";
|
|
1710
1723
|
let nativeProgressChunkKey;
|
|
1724
|
+
const progressReceipt = createChannelProgressReceiptTracker();
|
|
1725
|
+
let progressReceiptCollapsed = false;
|
|
1726
|
+
let pendingNativeProgressReceipt;
|
|
1711
1727
|
const progressSeed = `${account.accountId}:${message.channel}`;
|
|
1712
1728
|
const useRichProgressDraft = streamMode === "status_final" && resolveChannelProgressDraftRender(account.config) === "rich";
|
|
1713
1729
|
const explicitProgressTitle = resolveExplicitSlackProgressTitle(account.config);
|
|
1714
1730
|
const progressDraftMaxLineChars = resolveChannelProgressDraftMaxLineChars(account.config);
|
|
1715
|
-
const renderProgressDraft = () => {
|
|
1716
|
-
if (!draftStream || streamMode !== "status_final") return;
|
|
1717
|
-
const progressLines = previewToolProgressLines.length === 0 ? lastNonEmptyPreviewToolProgressLines : previewToolProgressLines;
|
|
1718
|
-
const previewText = formatChannelProgressDraftText({
|
|
1719
|
-
entry: account.config,
|
|
1720
|
-
lines: progressLines,
|
|
1721
|
-
seed: progressSeed,
|
|
1722
|
-
formatLine: escapeSlackMrkdwn,
|
|
1723
|
-
narration: latestPlanExplanation,
|
|
1724
|
-
plan: latestPlan
|
|
1725
|
-
});
|
|
1726
|
-
if (!previewText) return;
|
|
1727
|
-
const richProgressBlocks = useRichProgressDraft ? buildSlackProgressDraftBlocks({
|
|
1728
|
-
title: explicitProgressTitle,
|
|
1729
|
-
lines: progressLines,
|
|
1730
|
-
plan: latestPlan,
|
|
1731
|
-
narration: latestPlanExplanation,
|
|
1732
|
-
maxLineChars: resolveChannelProgressDraftMaxLineChars(account.config)
|
|
1733
|
-
}) : void 0;
|
|
1734
|
-
draftStream.update(useRichProgressDraft && richProgressBlocks ? {
|
|
1735
|
-
text: previewText,
|
|
1736
|
-
blocks: richProgressBlocks
|
|
1737
|
-
} : previewText);
|
|
1738
|
-
hasStreamedMessage = true;
|
|
1739
|
-
};
|
|
1740
1731
|
const waitForNativeProgressStreamStart = async () => {
|
|
1741
1732
|
if (streamSession || !nativeProgressStreamStartPromise) return true;
|
|
1742
1733
|
try {
|
|
@@ -1747,26 +1738,40 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1747
1738
|
}
|
|
1748
1739
|
return !streamFailed;
|
|
1749
1740
|
};
|
|
1750
|
-
const
|
|
1751
|
-
|
|
1752
|
-
|
|
1741
|
+
const resolveStructuredProgressLines = (lines) => lines.map((line) => {
|
|
1742
|
+
if (typeof line !== "string") return line;
|
|
1743
|
+
const reasoning = line.startsWith("🧠 ");
|
|
1744
|
+
const text = line.replace(/^(?:🧠|💬)\s+/u, "").replace(/^_(.*)_$/su, "$1").trim();
|
|
1745
|
+
return {
|
|
1746
|
+
...reasoning ? { id: "reasoning" } : {},
|
|
1747
|
+
kind: "item",
|
|
1748
|
+
text,
|
|
1749
|
+
label: reasoning ? "Reasoning" : "Update",
|
|
1750
|
+
prefix: false
|
|
1751
|
+
};
|
|
1752
|
+
});
|
|
1753
|
+
const resolveNativeProgressPlan = (snapshot) => snapshot.plan?.length ? snapshot.plan : void 0;
|
|
1754
|
+
const resolveNativeProgressLines = (snapshot) => {
|
|
1755
|
+
const lines = resolveStructuredProgressLines(snapshot.lines);
|
|
1756
|
+
if (snapshot.plan?.length || !snapshot.planExplanation) return lines;
|
|
1753
1757
|
const explanationLine = buildChannelProgressDraftLine({
|
|
1754
1758
|
event: "plan",
|
|
1755
1759
|
phase: "update",
|
|
1756
|
-
explanation:
|
|
1760
|
+
explanation: snapshot.planExplanation
|
|
1757
1761
|
});
|
|
1758
|
-
return explanationLine ? [...
|
|
1762
|
+
return explanationLine ? [...lines, explanationLine] : lines;
|
|
1759
1763
|
};
|
|
1760
|
-
const
|
|
1761
|
-
const
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1764
|
+
const combineProgressHeadlineAndExplanation = (headline, explanation) => headline && explanation && headline !== explanation ? `${headline} — ${explanation}` : headline ?? explanation;
|
|
1765
|
+
const resolveNativeProgressTitle = (snapshot) => combineProgressHeadlineAndExplanation(explicitProgressTitle ?? snapshot.statusHeadline, snapshot.planExplanation);
|
|
1766
|
+
const buildNativeProgressChunks = (snapshot) => streamSession ? buildSlackProgressStreamUpdateChunks({
|
|
1767
|
+
title: resolveNativeProgressTitle(snapshot),
|
|
1768
|
+
lines: resolveNativeProgressLines(snapshot),
|
|
1769
|
+
plan: resolveNativeProgressPlan(snapshot),
|
|
1765
1770
|
maxLineChars: progressDraftMaxLineChars
|
|
1766
1771
|
}) : buildSlackProgressStreamStartChunks({
|
|
1767
|
-
title: resolveNativeProgressTitle(),
|
|
1768
|
-
lines: resolveNativeProgressLines(),
|
|
1769
|
-
plan: resolveNativeProgressPlan(),
|
|
1772
|
+
title: resolveNativeProgressTitle(snapshot),
|
|
1773
|
+
lines: resolveNativeProgressLines(snapshot),
|
|
1774
|
+
plan: resolveNativeProgressPlan(snapshot),
|
|
1770
1775
|
maxLineChars: progressDraftMaxLineChars
|
|
1771
1776
|
});
|
|
1772
1777
|
const markNativeProgressDelivered = (session, threadTs) => {
|
|
@@ -1824,12 +1829,14 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1824
1829
|
nativeProgressChunkKey = chunkKey;
|
|
1825
1830
|
};
|
|
1826
1831
|
const updateNativeProgressStream = async () => {
|
|
1832
|
+
const snapshot = progressDraft.getSnapshot();
|
|
1833
|
+
const progressLines = resolveNativeProgressLines(snapshot);
|
|
1827
1834
|
const hasRetirableNativeTasks = [...nativeTaskState.values()].some((task) => task.status !== "complete" && task.status !== "error");
|
|
1828
|
-
if (!useNativeProgressStreaming || streamFailed ||
|
|
1835
|
+
if (!useNativeProgressStreaming || streamFailed || progressLines.length === 0 && !snapshot.plan?.length && !snapshot.statusHeadline && !explicitProgressTitle && !hasRetirableNativeTasks) return;
|
|
1829
1836
|
if (!await waitForNativeProgressStreamStart()) return;
|
|
1830
1837
|
const reconciled = reconcileSlackNativeTaskChunks({
|
|
1831
1838
|
previousTasks: nativeTaskState,
|
|
1832
|
-
chunks: buildNativeProgressChunks()
|
|
1839
|
+
chunks: buildNativeProgressChunks(snapshot)
|
|
1833
1840
|
});
|
|
1834
1841
|
const chunks = reconciled.chunks;
|
|
1835
1842
|
if (!chunks?.length) return;
|
|
@@ -1844,85 +1851,154 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1844
1851
|
streamFailed = true;
|
|
1845
1852
|
}
|
|
1846
1853
|
};
|
|
1847
|
-
const
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
plan: latestPlan
|
|
1854
|
+
const resetProgressTurnState = () => {
|
|
1855
|
+
progressReceipt.reset();
|
|
1856
|
+
progressReceiptCollapsed = false;
|
|
1857
|
+
pendingNativeProgressReceipt = void 0;
|
|
1858
|
+
};
|
|
1859
|
+
const collapseProgressReceipt = async (params) => {
|
|
1860
|
+
const { botToken: token } = ctx;
|
|
1861
|
+
try {
|
|
1862
|
+
await finalizeSlackPreviewEdit({
|
|
1863
|
+
client: slackClient,
|
|
1864
|
+
token,
|
|
1865
|
+
accountId: account.accountId,
|
|
1866
|
+
...params
|
|
1861
1867
|
});
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1868
|
+
progressReceiptCollapsed = true;
|
|
1869
|
+
} catch (err) {
|
|
1870
|
+
logVerbose(`slack: progress receipt edit failed (${formatSlackError(err)})`);
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
const progressDraft = createChannelProgressDraftCompositor({
|
|
1874
|
+
entry: account.config,
|
|
1875
|
+
mode: slackStreaming.mode,
|
|
1876
|
+
active: progressDraftActive && streamMode === "status_final",
|
|
1877
|
+
seed: progressSeed,
|
|
1878
|
+
formatLine: escapeSlackMrkdwn,
|
|
1879
|
+
reasoningLinePrefix: "🧠 ",
|
|
1880
|
+
commentaryLinePrefix: "💬 ",
|
|
1881
|
+
reasoningGate: previewToolProgressEnabled,
|
|
1882
|
+
commentaryItalics: false,
|
|
1883
|
+
updateOnLineChange: useNativeProgressStreaming || useRichProgressDraft,
|
|
1884
|
+
update: async (previewText, options) => {
|
|
1885
|
+
if (useNativeProgressStreaming) {
|
|
1886
|
+
await updateNativeProgressStream();
|
|
1887
|
+
return;
|
|
1865
1888
|
}
|
|
1866
|
-
return;
|
|
1889
|
+
if (!draftStream) return;
|
|
1890
|
+
const snapshot = progressDraft.getSnapshot();
|
|
1891
|
+
const structuredLines = resolveStructuredProgressLines(options?.lines ?? snapshot.lines);
|
|
1892
|
+
const richNarration = combineProgressHeadlineAndExplanation(snapshot.statusHeadline, snapshot.planExplanation);
|
|
1893
|
+
const richProgressBlocks = useRichProgressDraft ? buildSlackProgressDraftBlocks({
|
|
1894
|
+
title: explicitProgressTitle,
|
|
1895
|
+
lines: structuredLines,
|
|
1896
|
+
plan: snapshot.plan,
|
|
1897
|
+
narration: richNarration,
|
|
1898
|
+
maxLineChars: progressDraftMaxLineChars
|
|
1899
|
+
}) : void 0;
|
|
1900
|
+
draftStream.update(useRichProgressDraft && richProgressBlocks ? {
|
|
1901
|
+
text: previewText,
|
|
1902
|
+
blocks: richProgressBlocks
|
|
1903
|
+
} : previewText);
|
|
1904
|
+
hasStreamedMessage = true;
|
|
1905
|
+
if (options?.flush) await draftStream.flush();
|
|
1867
1906
|
}
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1907
|
+
});
|
|
1908
|
+
const commentaryProgressEnabled = progressDraft.commentaryProgressEnabled;
|
|
1909
|
+
const buildNativeProgressCompletionChunks = (finalInProgressStatus) => {
|
|
1910
|
+
const snapshot = progressDraft.getSnapshot();
|
|
1911
|
+
const lines = resolveNativeProgressLines(snapshot);
|
|
1912
|
+
const hasRetirableNativeTasks = [...nativeTaskState.values()].some((task) => task.status !== "complete" && task.status !== "error");
|
|
1913
|
+
if (lines.length === 0 && !snapshot.plan?.length && !hasRetirableNativeTasks) return;
|
|
1914
|
+
return reconcileSlackNativeTaskChunks({
|
|
1915
|
+
previousTasks: nativeTaskState,
|
|
1916
|
+
chunks: buildSlackProgressStreamCompletionChunks({
|
|
1917
|
+
title: resolveNativeProgressTitle(snapshot),
|
|
1918
|
+
lines,
|
|
1919
|
+
plan: resolveNativeProgressPlan(snapshot),
|
|
1920
|
+
maxLineChars: progressDraftMaxLineChars,
|
|
1921
|
+
finalInProgressStatus
|
|
1922
|
+
})
|
|
1923
|
+
}).chunks;
|
|
1871
1924
|
};
|
|
1872
|
-
const
|
|
1873
|
-
if (
|
|
1874
|
-
|
|
1925
|
+
const finishNativeProgressTurn = async (completionChunks) => {
|
|
1926
|
+
if (nativeProgressStreamStartPromise) await nativeProgressStreamStartPromise.catch(() => null);
|
|
1927
|
+
const session = streamSession;
|
|
1928
|
+
if (session && !session.stopped) try {
|
|
1929
|
+
if (completionChunks?.length) nativeProgressCompletionSent = true;
|
|
1930
|
+
const stopResult = await stopSlackStream({
|
|
1931
|
+
session,
|
|
1932
|
+
...completionChunks?.length ? { chunks: completionChunks } : {},
|
|
1933
|
+
...slackMessageMetadata ? { metadata: slackMessageMetadata } : {}
|
|
1934
|
+
});
|
|
1935
|
+
acknowledgeStoppedStreamedDeliveries(session, stopResult?.messageId);
|
|
1936
|
+
if (pendingNativeProgressReceipt && stopResult?.messageId) await collapseProgressReceipt({
|
|
1937
|
+
channelId: session.channel,
|
|
1938
|
+
messageId: stopResult.messageId,
|
|
1939
|
+
text: pendingNativeProgressReceipt,
|
|
1940
|
+
threadTs: session.threadTs
|
|
1941
|
+
});
|
|
1942
|
+
} catch (err) {
|
|
1943
|
+
const error = formatSlackError(err);
|
|
1944
|
+
emitAcknowledgedStreamedDeliveries();
|
|
1945
|
+
emitFailedPendingStreamedDeliveries(error);
|
|
1946
|
+
logVerbose(`slack-stream: failed to rotate native progress stream (${error})`);
|
|
1947
|
+
}
|
|
1948
|
+
streamSession = null;
|
|
1949
|
+
nativeProgressStreamStartPromise = null;
|
|
1950
|
+
nativeProgressStreamThreadTs = void 0;
|
|
1951
|
+
streamFailed = false;
|
|
1875
1952
|
};
|
|
1876
|
-
const
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
if (!draftStream && !useNativeProgressStreaming) return;
|
|
1880
|
-
if (lane === "commentary" && commentaryProgressEnabled && shouldYieldDraftProgress()) return;
|
|
1881
|
-
if (options?.toolName !== void 0 && !isChannelProgressDraftWorkToolName(options.toolName)) return;
|
|
1882
|
-
const normalized = line?.text.replace(/\s+/g, " ").trim();
|
|
1883
|
-
if (!line || !normalized) {
|
|
1884
|
-
if (streamMode !== "status_final") return;
|
|
1885
|
-
const alreadyStarted = progressDraftGate.hasStarted;
|
|
1886
|
-
const progressActive = await progressDraftGate.noteWork();
|
|
1887
|
-
if ((alreadyStarted || progressActive) && progressDraftGate.hasStarted) await refreshStartedProgressDraft();
|
|
1953
|
+
const pushPlanProgress = async (steps, explanation) => {
|
|
1954
|
+
if (streamMode === "status_final") {
|
|
1955
|
+
await progressDraft.pushPlanProgress(steps, { explanation });
|
|
1888
1956
|
return;
|
|
1889
1957
|
}
|
|
1890
|
-
if (
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1958
|
+
if (previewToolProgressSuppressed || !draftStream) return;
|
|
1959
|
+
const text = formatChannelProgressDraftText({
|
|
1960
|
+
entry: account.config,
|
|
1961
|
+
lines: legacyPreviewToolProgressLines,
|
|
1962
|
+
seed: progressSeed,
|
|
1963
|
+
formatLine: escapeSlackMrkdwn,
|
|
1964
|
+
narration: explanation,
|
|
1965
|
+
plan: steps
|
|
1966
|
+
});
|
|
1967
|
+
if (text) {
|
|
1968
|
+
draftStream.update(text);
|
|
1901
1969
|
hasStreamedMessage = true;
|
|
1902
|
-
return;
|
|
1903
|
-
}
|
|
1904
|
-
if (progressEnabled && !previewToolProgressSuppressed) {
|
|
1905
|
-
previewToolProgressLines = mergeChannelProgressDraftLine(previewToolProgressLines, line, { maxLines: resolveChannelProgressDraftMaxLines(account.config) });
|
|
1906
|
-
if (previewToolProgressLines.length > 0) lastNonEmptyPreviewToolProgressLines = previewToolProgressLines;
|
|
1907
1970
|
}
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1971
|
+
};
|
|
1972
|
+
const pushPreviewProgress = async (line, options) => {
|
|
1973
|
+
if (!draftStream && !useNativeProgressStreaming) return;
|
|
1974
|
+
if (options?.toolName !== void 0 && !isChannelProgressDraftWorkToolName(options.toolName)) return;
|
|
1975
|
+
const normalized = line?.text.replace(/\s+/g, " ").trim();
|
|
1976
|
+
if (streamMode === "status_final") {
|
|
1977
|
+
if (!line || !normalized) {
|
|
1978
|
+
await progressDraft.noteActivity();
|
|
1979
|
+
return;
|
|
1913
1980
|
}
|
|
1981
|
+
await progressDraft.pushToolProgress(line, options);
|
|
1914
1982
|
return;
|
|
1915
1983
|
}
|
|
1916
|
-
|
|
1917
|
-
const
|
|
1918
|
-
if (
|
|
1984
|
+
if (!line || !normalized || !draftStream || !previewToolProgressEnabled || previewToolProgressSuppressed) return;
|
|
1985
|
+
const nextLines = mergeChannelProgressDraftLine(legacyPreviewToolProgressLines, line, { maxLines: resolveChannelProgressDraftMaxLines(account.config) });
|
|
1986
|
+
if (nextLines === legacyPreviewToolProgressLines) return;
|
|
1987
|
+
legacyPreviewToolProgressLines = nextLines;
|
|
1988
|
+
draftStream.update(formatChannelProgressDraftText({
|
|
1989
|
+
entry: account.config,
|
|
1990
|
+
lines: legacyPreviewToolProgressLines,
|
|
1991
|
+
seed: progressSeed,
|
|
1992
|
+
formatLine: escapeSlackMrkdwn
|
|
1993
|
+
}));
|
|
1994
|
+
hasStreamedMessage = true;
|
|
1919
1995
|
};
|
|
1920
1996
|
const updateDraftFromPartial = (text) => {
|
|
1921
1997
|
const trimmed = text?.trimEnd();
|
|
1922
1998
|
if (!trimmed) return;
|
|
1923
1999
|
if (streamMode === "append") {
|
|
1924
2000
|
previewToolProgressSuppressed = true;
|
|
1925
|
-
|
|
2001
|
+
legacyPreviewToolProgressLines = [];
|
|
1926
2002
|
const next = applyAppendOnlyStreamUpdate({
|
|
1927
2003
|
incoming: trimmed,
|
|
1928
2004
|
rendered: appendRenderedText,
|
|
@@ -1935,74 +2011,86 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
1935
2011
|
hasStreamedMessage = true;
|
|
1936
2012
|
return;
|
|
1937
2013
|
}
|
|
1938
|
-
if (streamMode === "status_final")
|
|
1939
|
-
if (!progressDraftGate.hasStarted) return;
|
|
1940
|
-
statusUpdateCount += 1;
|
|
1941
|
-
if (statusUpdateCount > 1 && statusUpdateCount % 4 !== 0) return;
|
|
1942
|
-
renderProgressDraft();
|
|
1943
|
-
return;
|
|
1944
|
-
}
|
|
2014
|
+
if (streamMode === "status_final") return;
|
|
1945
2015
|
previewToolProgressSuppressed = true;
|
|
1946
|
-
|
|
2016
|
+
legacyPreviewToolProgressLines = [];
|
|
1947
2017
|
draftStream?.update(trimmed);
|
|
1948
2018
|
hasStreamedMessage = true;
|
|
1949
2019
|
};
|
|
1950
2020
|
const pushReasoningProgress = async (payload) => {
|
|
1951
2021
|
if (!payload?.text) return;
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2022
|
+
if (streamMode !== "status_final") {
|
|
2023
|
+
const normalized = progressDraft.mergeReasoningProgress(payload.text, { snapshot: payload.isReasoningSnapshot === true }).replace(/^_(.*)_$/su, "$1").trim();
|
|
2024
|
+
if (!normalized) return;
|
|
2025
|
+
await pushPreviewProgress({
|
|
2026
|
+
id: "reasoning",
|
|
2027
|
+
kind: "item",
|
|
2028
|
+
text: normalized,
|
|
2029
|
+
label: "Reasoning"
|
|
2030
|
+
});
|
|
2031
|
+
return;
|
|
2032
|
+
}
|
|
2033
|
+
progressReceipt.noteReasoning();
|
|
2034
|
+
await progressDraft.pushReasoningProgress(payload.text, { snapshot: payload.isReasoningSnapshot === true });
|
|
1961
2035
|
};
|
|
1962
2036
|
const resetDraftDeliveryState = () => {
|
|
1963
2037
|
hasStreamedMessage = false;
|
|
1964
2038
|
appendRenderedText = "";
|
|
1965
2039
|
appendSourceText = "";
|
|
1966
|
-
statusUpdateCount = 0;
|
|
1967
2040
|
};
|
|
1968
2041
|
const resetDraftProgressState = () => {
|
|
1969
|
-
|
|
2042
|
+
progressDraft.resetReasoningProgress();
|
|
1970
2043
|
previewToolProgressSuppressed = false;
|
|
1971
|
-
|
|
2044
|
+
legacyPreviewToolProgressLines = [];
|
|
2045
|
+
};
|
|
2046
|
+
const beginNewProgressTurn = async (options) => {
|
|
2047
|
+
const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent ? buildNativeProgressCompletionChunks(nativeProgressTerminalStatus) : void 0;
|
|
2048
|
+
if (!progressDraft.beginNewTurn(options)) return false;
|
|
2049
|
+
if (useNativeProgressStreaming) await finishNativeProgressTurn(completionChunks);
|
|
2050
|
+
else draftStream?.forceNewMessage();
|
|
2051
|
+
resetProgressTurnState();
|
|
2052
|
+
nativeTaskState = /* @__PURE__ */ new Map();
|
|
2053
|
+
nativeProgressCompletionSent = false;
|
|
2054
|
+
nativeProgressTerminalStatus = "complete";
|
|
2055
|
+
nativeProgressChunkKey = void 0;
|
|
2056
|
+
draftPreviewCommitted = false;
|
|
2057
|
+
observedFinalReplyDelivery = false;
|
|
2058
|
+
deliveryTracker = createSlackEventDeliveryTracker();
|
|
2059
|
+
progressReceiptCollapsed = false;
|
|
2060
|
+
return true;
|
|
1972
2061
|
};
|
|
1973
|
-
const onDraftBoundary = !shouldUseDraftStream ? void 0 : async () => {
|
|
1974
|
-
if (
|
|
1975
|
-
|
|
1976
|
-
|
|
2062
|
+
const onDraftBoundary = !shouldUseDraftStream && !useNativeProgressStreaming ? void 0 : async () => {
|
|
2063
|
+
if (streamMode === "status_final") {
|
|
2064
|
+
await beginNewProgressTurn();
|
|
2065
|
+
return;
|
|
1977
2066
|
}
|
|
2067
|
+
if (hasStreamedMessage) draftStream?.forceNewMessage();
|
|
2068
|
+
resetDraftDeliveryState();
|
|
1978
2069
|
resetDraftProgressState();
|
|
1979
2070
|
};
|
|
1980
|
-
const onQueuedFollowupAdmitted = !shouldUseDraftStream ? void 0 : async () => {
|
|
2071
|
+
const onQueuedFollowupAdmitted = !shouldUseDraftStream && !useNativeProgressStreaming ? void 0 : async () => {
|
|
1981
2072
|
await draftStream?.flush();
|
|
1982
|
-
draftStream?.forceNewMessage();
|
|
1983
2073
|
draftPreviewCommitted = false;
|
|
1984
2074
|
observedFinalReplyDelivery = false;
|
|
2075
|
+
if (streamMode === "status_final") await beginNewProgressTurn({ force: true });
|
|
2076
|
+
else draftStream?.forceNewMessage();
|
|
1985
2077
|
deliveryTracker = createSlackEventDeliveryTracker();
|
|
1986
2078
|
resetDraftDeliveryState();
|
|
1987
2079
|
resetDraftProgressState();
|
|
1988
|
-
latestPlan = void 0;
|
|
1989
|
-
latestPlanExplanation = void 0;
|
|
1990
|
-
nativeTaskState = /* @__PURE__ */ new Map();
|
|
1991
2080
|
};
|
|
1992
2081
|
let dispatchError;
|
|
1993
2082
|
let queuedFinal = false;
|
|
1994
2083
|
let counts = {};
|
|
1995
2084
|
try {
|
|
1996
|
-
const turnResult = await
|
|
2085
|
+
const turnResult = await dispatchChannelInboundTurn({
|
|
1997
2086
|
cfg,
|
|
1998
2087
|
channel: "slack",
|
|
1999
2088
|
accountId: route.accountId,
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2089
|
+
route: {
|
|
2090
|
+
agentId: route.agentId,
|
|
2091
|
+
sessionKey: route.sessionKey
|
|
2092
|
+
},
|
|
2003
2093
|
ctxPayload: prepared.ctxPayload,
|
|
2004
|
-
recordInboundSession,
|
|
2005
|
-
dispatchReplyWithBufferedBlockDispatcher,
|
|
2006
2094
|
dispatcherOptions: {
|
|
2007
2095
|
...replyPipeline,
|
|
2008
2096
|
humanDelay: resolveHumanDelayConfig(cfg, route.agentId)
|
|
@@ -2015,6 +2103,7 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2015
2103
|
history: prepared.turn.history,
|
|
2016
2104
|
botLoopProtection: resolveSlackBotLoopProtection(prepared),
|
|
2017
2105
|
replyOptions: {
|
|
2106
|
+
...prepared.turnAdoptionLifecycle ? { turnAdoptionLifecycle: prepared.turnAdoptionLifecycle } : {},
|
|
2018
2107
|
skillFilter: prepared.channelConfig?.skills,
|
|
2019
2108
|
sourceReplyDeliveryMode,
|
|
2020
2109
|
suppressTyping: suppressRoomEventTyping ? true : void 0,
|
|
@@ -2023,6 +2112,8 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2023
2112
|
onModelSelected,
|
|
2024
2113
|
suppressDefaultToolProgressMessages: suppressDefaultToolProgressMessages ? true : void 0,
|
|
2025
2114
|
commentaryProgressEnabled: commentaryProgressEnabled ? true : void 0,
|
|
2115
|
+
progressPreambleEnabled: progressDraftActive && slackStreaming.mode === "progress" ? true : void 0,
|
|
2116
|
+
commentaryPayloadsEnabled: commentaryProgressEnabled ? true : void 0,
|
|
2026
2117
|
onVerboseProgressVisibility: commentaryProgressEnabled ? (isActive) => {
|
|
2027
2118
|
shouldYieldDraftProgress = isActive;
|
|
2028
2119
|
} : void 0,
|
|
@@ -2032,7 +2123,10 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2032
2123
|
updateDraftFromPartial(payload.text);
|
|
2033
2124
|
},
|
|
2034
2125
|
onAssistantMessageStart: onDraftBoundary,
|
|
2035
|
-
onReasoningEnd:
|
|
2126
|
+
onReasoningEnd: async () => {
|
|
2127
|
+
progressReceipt.closeReasoning();
|
|
2128
|
+
await onDraftBoundary?.();
|
|
2129
|
+
},
|
|
2036
2130
|
onQueuedFollowupAdmitted,
|
|
2037
2131
|
onReasoningStream: statusReactionsEnabled || previewToolProgressEnabled ? async (payload) => {
|
|
2038
2132
|
await pushReasoningProgress(payload);
|
|
@@ -2041,6 +2135,7 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2041
2135
|
} : void 0,
|
|
2042
2136
|
onToolStart: async (payload) => {
|
|
2043
2137
|
if (statusReactionsEnabled) await statusReactions.setTool(payload.name);
|
|
2138
|
+
if (payload.phase === "start") progressReceipt.noteToolCall(payload.name);
|
|
2044
2139
|
await pushPreviewProgress(buildChannelProgressDraftLineForEntry(account.config, {
|
|
2045
2140
|
event: "tool",
|
|
2046
2141
|
itemId: payload.itemId,
|
|
@@ -2051,6 +2146,14 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2051
2146
|
}, payload.detailMode ? { detailMode: payload.detailMode } : void 0), { toolName: payload.name });
|
|
2052
2147
|
},
|
|
2053
2148
|
onItemEvent: async (payload) => {
|
|
2149
|
+
if (streamMode === "status_final" && payload.kind === "preamble") {
|
|
2150
|
+
if (shouldYieldDraftProgress()) return;
|
|
2151
|
+
await progressDraft.pushPreambleHeadline(payload.progressText, { itemId: payload.itemId });
|
|
2152
|
+
if (commentaryProgressEnabled) {
|
|
2153
|
+
if (await progressDraft.pushCommentaryProgress(payload.progressText, { itemId: payload.itemId })) progressReceipt.noteCommentary(payload.itemId, payload.progressText);
|
|
2154
|
+
}
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
2054
2157
|
await pushPreviewProgress(buildChannelProgressDraftLineForEntry(account.config, {
|
|
2055
2158
|
event: "item",
|
|
2056
2159
|
itemId: payload.itemId,
|
|
@@ -2063,11 +2166,11 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2063
2166
|
summary: payload.summary,
|
|
2064
2167
|
progressText: payload.progressText,
|
|
2065
2168
|
meta: payload.meta
|
|
2066
|
-
})
|
|
2169
|
+
}));
|
|
2067
2170
|
},
|
|
2068
2171
|
onPlanUpdate: async (payload) => {
|
|
2069
2172
|
if (payload.phase !== "update") return;
|
|
2070
|
-
await pushPlanProgress(payload.
|
|
2173
|
+
await pushPlanProgress(payload.steps, payload.explanation);
|
|
2071
2174
|
},
|
|
2072
2175
|
onApprovalEvent: async (payload) => {
|
|
2073
2176
|
if (payload.phase !== "requested") return;
|
|
@@ -2118,30 +2221,26 @@ async function dispatchPreparedSlackMessage(prepared) {
|
|
|
2118
2221
|
} catch (err) {
|
|
2119
2222
|
dispatchError = err;
|
|
2120
2223
|
} finally {
|
|
2121
|
-
|
|
2224
|
+
progressDraft.cancel();
|
|
2122
2225
|
await draftStream?.discardPending();
|
|
2123
2226
|
}
|
|
2124
2227
|
let streamFallbackDelivered = false;
|
|
2125
2228
|
const finalStream = streamSession;
|
|
2126
2229
|
if (finalStream && !finalStream.stopped) try {
|
|
2127
|
-
const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent
|
|
2128
|
-
previousTasks: nativeTaskState,
|
|
2129
|
-
chunks: buildSlackProgressStreamCompletionChunks({
|
|
2130
|
-
title: resolveNativeProgressTitle(),
|
|
2131
|
-
lines: resolveNativeProgressLines(),
|
|
2132
|
-
plan: resolveNativeProgressPlan(),
|
|
2133
|
-
maxLineChars: progressDraftMaxLineChars,
|
|
2134
|
-
finalInProgressStatus: dispatchError ? "error" : "complete"
|
|
2135
|
-
})
|
|
2136
|
-
}).chunks : void 0;
|
|
2230
|
+
const completionChunks = useNativeProgressStreaming && !nativeProgressCompletionSent ? buildNativeProgressCompletionChunks(dispatchError ? "error" : nativeProgressTerminalStatus) : void 0;
|
|
2137
2231
|
if (completionChunks?.length) nativeProgressCompletionSent = true;
|
|
2138
2232
|
const stopResult = await stopSlackStream({
|
|
2139
2233
|
session: finalStream,
|
|
2140
2234
|
...completionChunks?.length ? { chunks: completionChunks } : {},
|
|
2141
2235
|
...slackMessageMetadata ? { metadata: slackMessageMetadata } : {}
|
|
2142
2236
|
});
|
|
2143
|
-
|
|
2144
|
-
|
|
2237
|
+
acknowledgeStoppedStreamedDeliveries(finalStream, stopResult?.messageId);
|
|
2238
|
+
if (pendingNativeProgressReceipt && stopResult?.messageId && !progressReceiptCollapsed) await collapseProgressReceipt({
|
|
2239
|
+
channelId: finalStream.channel,
|
|
2240
|
+
messageId: stopResult.messageId,
|
|
2241
|
+
text: pendingNativeProgressReceipt,
|
|
2242
|
+
threadTs: finalStream.threadTs
|
|
2243
|
+
});
|
|
2145
2244
|
} catch (err) {
|
|
2146
2245
|
if (err instanceof SlackStreamNotDeliveredError) {
|
|
2147
2246
|
streamFallbackDelivered = await deliverPendingStreamFallback(finalStream, err);
|
|
@@ -2321,7 +2420,7 @@ async function discardSlackPreflightMedia(media) {
|
|
|
2321
2420
|
const SLACK_MENTION_RESOLUTION_CONCURRENCY = 4;
|
|
2322
2421
|
const SLACK_MENTION_RESOLUTION_MAX_LOOKUPS_PER_MESSAGE = 20;
|
|
2323
2422
|
const SLACK_USER_MENTION_RE$1 = /<@([A-Z0-9]+)(?:\|[^>]+)?>/gi;
|
|
2324
|
-
const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-
|
|
2423
|
+
const loadSlackMediaModule$1 = createLazyRuntimeModule(() => import("./actions-CF0tUY5q.js").then((n) => n.g));
|
|
2325
2424
|
function collectUniqueSlackMentionIds$1(texts) {
|
|
2326
2425
|
const seen = /* @__PURE__ */ new Set();
|
|
2327
2426
|
const mentionIds = [];
|
|
@@ -2743,7 +2842,7 @@ function formatSlackThreadLabelSnippet(text) {
|
|
|
2743
2842
|
}
|
|
2744
2843
|
//#endregion
|
|
2745
2844
|
//#region extensions/slack/src/monitor/message-handler/prepare-thread-context.ts
|
|
2746
|
-
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-
|
|
2845
|
+
const loadSlackMediaModule = createLazyRuntimeModule(() => import("./actions-CF0tUY5q.js").then((n) => n.g));
|
|
2747
2846
|
const SLACK_THREAD_CONTEXT_USER_LOOKUP_CONCURRENCY = 4;
|
|
2748
2847
|
function resolveSlackThreadSessionFreshness(params) {
|
|
2749
2848
|
return params.ctx.channelRuntime?.session?.resolveEntryResetFreshness?.({
|
|
@@ -2758,14 +2857,21 @@ function resolveSlackThreadSessionFreshness(params) {
|
|
|
2758
2857
|
});
|
|
2759
2858
|
}
|
|
2760
2859
|
function isSlackThreadContextSenderAllowed(params) {
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2860
|
+
return resolveInboundSupplementalSenderAllowed({
|
|
2861
|
+
isGroup: true,
|
|
2862
|
+
groupPolicy: params.allowFromLower.length === 0 ? "open" : "allowlist",
|
|
2863
|
+
allowFrom: params.allowFromLower,
|
|
2864
|
+
isSenderAllowed: (allowFrom) => {
|
|
2865
|
+
if (params.botId) return true;
|
|
2866
|
+
if (!params.userId) return false;
|
|
2867
|
+
return resolveSlackAllowListMatch({
|
|
2868
|
+
allowList: allowFrom,
|
|
2869
|
+
id: params.userId,
|
|
2870
|
+
name: params.userName,
|
|
2871
|
+
allowNameMatching: params.allowNameMatching
|
|
2872
|
+
}).allowed;
|
|
2873
|
+
}
|
|
2874
|
+
});
|
|
2769
2875
|
}
|
|
2770
2876
|
async function resolveSlackThreadUserMap(params) {
|
|
2771
2877
|
const uniqueUserIds = [];
|
|
@@ -3458,7 +3564,7 @@ async function prepareSlackMessage(params) {
|
|
|
3458
3564
|
name: void 0
|
|
3459
3565
|
});
|
|
3460
3566
|
let implicitMentionKinds = [];
|
|
3461
|
-
if (!isDirectMessage && ctx.botUserId && message.thread_ts && !
|
|
3567
|
+
if (!isDirectMessage && ctx.botUserId && message.thread_ts && !wasMentioned) {
|
|
3462
3568
|
const replyToBotKinds = implicitMentionKindWhen("reply_to_bot", message.parent_user_id === ctx.botUserId);
|
|
3463
3569
|
implicitMentionKinds = replyToBotKinds.length > 0 ? replyToBotKinds : implicitMentionKindWhen("bot_thread_participant", await hasSlackThreadParticipationWithPersistence({
|
|
3464
3570
|
accountId: account.accountId,
|
|
@@ -3554,6 +3660,11 @@ async function prepareSlackMessage(params) {
|
|
|
3554
3660
|
surface: "slack"
|
|
3555
3661
|
});
|
|
3556
3662
|
const shouldRequireMention = isRoom ? channelConfig?.requireMention ?? ctx.defaultRequireMention : false;
|
|
3663
|
+
const implicitMentions = resolveChannelImplicitMentions({
|
|
3664
|
+
cfg,
|
|
3665
|
+
channel: "slack",
|
|
3666
|
+
accountId: account.accountId
|
|
3667
|
+
});
|
|
3557
3668
|
if (message["_ambiguousThreadReply"]) {
|
|
3558
3669
|
ctx.logger.info({
|
|
3559
3670
|
channel: message.channel,
|
|
@@ -3586,7 +3697,7 @@ async function prepareSlackMessage(params) {
|
|
|
3586
3697
|
activation: {
|
|
3587
3698
|
requireMention: shouldRequireMention,
|
|
3588
3699
|
allowTextCommands,
|
|
3589
|
-
|
|
3700
|
+
implicitMentions
|
|
3590
3701
|
}
|
|
3591
3702
|
});
|
|
3592
3703
|
const senderGate = messageIngress.senderAccess.gate;
|
|
@@ -3698,7 +3809,7 @@ async function prepareSlackMessage(params) {
|
|
|
3698
3809
|
allowTextCommands,
|
|
3699
3810
|
hasControlCommand: hasControlCommandInMessage,
|
|
3700
3811
|
commandAuthorized,
|
|
3701
|
-
|
|
3812
|
+
implicitMentions
|
|
3702
3813
|
}
|
|
3703
3814
|
});
|
|
3704
3815
|
const effectiveWasMentioned = mentionDecision.effectiveWasMentioned;
|
|
@@ -3926,6 +4037,7 @@ async function prepareSlackMessage(params) {
|
|
|
3926
4037
|
},
|
|
3927
4038
|
route: {
|
|
3928
4039
|
agentId: route.agentId,
|
|
4040
|
+
dmScope: route.dmScope,
|
|
3929
4041
|
accountId: route.accountId,
|
|
3930
4042
|
routeSessionKey: sessionKey,
|
|
3931
4043
|
parentSessionKey: threadKeys.parentSessionKey
|