@openclaw/slack 2026.10.5-beta.3 → 2026.10.10-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.setup/{account-inspect-D58VVDjk.mjs → account-inspect-CmkKiSb9.mjs} +1 -1
- package/dist/.setup/{accounts-BMg9YLIv.mjs → accounts-msihSF3-.mjs} +1 -1
- package/dist/.setup/{action-runtime-BiRZNsIG.mjs → action-runtime-CgYsBWl6.mjs} +5 -5
- package/dist/.setup/action-runtime.runtime-WS3mGjut.mjs +1 -0
- package/dist/.setup/{actions-KGKwTAKO.mjs → actions-CafoV8hS.mjs} +4 -4
- package/dist/.setup/{approval-handler.runtime-DYrsG2Ox.mjs → approval-handler.runtime-Pty8hAZ9.mjs} +8 -8
- package/dist/.setup/{approval-message-updates-CwdDew9i.mjs → approval-message-updates-DCnXFLf3.mjs} +1 -1
- package/dist/.setup/{channel-C7MY-Hhg.mjs → channel-B-jnk0Gl.mjs} +51 -55
- package/dist/.setup/{channel-type-NjX2SwvS.mjs → channel-type-BrbGGbzI.mjs} +3 -3
- package/dist/.setup/{channel.setup-BFpQowO3.mjs → channel.setup-u6QQdbTa.mjs} +4 -4
- package/dist/.setup/{config-schema-BH0K9-Um.mjs → config-schema-DNnh6bWU.mjs} +1 -1
- package/dist/.setup/{directory-config-BEDZPfDn.mjs → directory-config-Cjj0N8R0.mjs} +1 -1
- package/dist/.setup/{directory-live-FipfeCwt.mjs → directory-live-BIKD-5B_.mjs} +2 -2
- package/dist/.setup/http-C9sM-FXe.mjs +2 -0
- package/dist/.setup/{message-tool-api-C7im5ETh.mjs → message-tool-api-BS5ekEA_.mjs} +2 -2
- package/dist/.setup/{monitor-BnN2px0N.mjs → monitor-DmJ-Qbx4.mjs} +181 -145
- package/dist/.setup/{outbound-adapter-4HdGq-8r.mjs → outbound-adapter-BlN9vmT-.mjs} +4 -4
- package/dist/.setup/{pipeline.runtime-ByPbC6MN.mjs → pipeline.runtime-DOf1Ghcz.mjs} +66 -129
- package/dist/.setup/{plugin-routes-B8tooDLj.mjs → plugin-routes-D4qozHVn.mjs} +1 -1
- package/dist/.setup/{policy-BaY9_eh1.mjs → policy-D4eNyn8m.mjs} +2 -2
- package/dist/.setup/{probe-CyX52GtD.mjs → probe-IiHogLQN.mjs} +3 -9
- package/dist/.setup/{registry-CIbMfuf8.mjs → registry-DizWcnNp.mjs} +4 -11
- package/dist/.setup/{relay-source-CVfH-fBO.mjs → relay-source-CUVJNz6R.mjs} +2 -2
- package/dist/.setup/{replies-WmfwvQxc.mjs → replies-Cs9SqIIs.mjs} +4 -4
- package/dist/.setup/{reply-blocks-rqHQ_3pr.mjs → reply-blocks-CoZ_dGM_.mjs} +1 -1
- package/dist/.setup/{resolve-channels-B96cgprw.mjs → resolve-channels-DRRhElwz.mjs} +1 -1
- package/dist/.setup/{resolve-users-Xz9aPdns.mjs → resolve-users-Cz8e17ky.mjs} +1 -1
- package/dist/.setup/runtime-setter-api-Cx_PV-xu.mjs +2 -0
- package/dist/.setup/{scopes-aMcMHhXk.mjs → scopes-DfQVi8Jw.mjs} +1 -1
- package/dist/.setup/secret-contract-api-DB6CMdgc.mjs +2 -0
- package/dist/.setup/{send-CLmsR42r.mjs → send-pi6r24yv.mjs} +5 -5
- package/dist/.setup/{session-status-CcXe10zN.mjs → session-status-DQY4hZLd.mjs} +73 -29
- package/dist/.setup/setup-plugin-api-B18kDKtr.mjs +2 -0
- package/dist/.setup/{setup-surface-368jx6Uc.mjs → setup-surface-9WVQgYCT.mjs} +6 -6
- package/dist/.setup/{shared-CtprVh_G.mjs → shared-DpHCoKy2.mjs} +7 -6
- package/dist/.setup/{slash-dispatch.runtime-Dzwj6TPI.mjs → slash-dispatch.runtime-BlBuHX9x.mjs} +3 -2
- package/dist/account-inspect-api.js +1 -1
- package/dist/api.js +15 -14
- package/dist/channel-config-api.js +1 -2
- package/dist/channel-plugin-api.js +1 -2
- package/dist/directory-contract-api.js +1 -2
- package/dist/doctor-contract-api.js +1 -2
- package/dist/http-routes-api.js +1 -2
- package/dist/index.js +1 -1
- package/dist/message-tool-api.js +1 -2
- package/dist/runtime-api.js +11 -11
- package/dist/runtime-setter-api.js +1 -2
- package/dist/secret-contract-api.js +1 -2
- package/dist/security-contract-api.js +1 -2
- package/dist/setup-entry.js +3 -3
- package/dist/setup-plugin-api.js +1 -2
- package/node_modules/typebox/build/value/clean/from_object.mjs +1 -1
- package/node_modules/typebox/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +5 -5
- package/dist/.setup/action-runtime.runtime-C5xceJoS.mjs +0 -2
- package/dist/.setup/runtime-setter-api-CMFvhrAr.mjs +0 -3
- package/dist/.setup/secret-contract-api-DmUVxIRs.mjs +0 -3
- package/dist/.setup/setup-plugin-api-D92P5p51.mjs +0 -3
- package/dist/.setup/{security-audit-C1nOGzJa.mjs → security-audit-DFGiFLqd.mjs} +1 -1
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
|
|
2
|
-
import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath } from "./registry-
|
|
3
|
-
import { a as mergeSlackAccountConfig, c as resolveSlackAccountAllowFrom, f as resolveSlackReplyToMode, h as resolveSlackBotToken, l as resolveSlackAccountDmPolicy, m as resolveSlackAppToken, o as resolveDefaultSlackAccountId, p as formatSlackBotTokenIdentityWarning, s as resolveSlackAccount } from "./accounts-
|
|
2
|
+
import { n as registerSlackHttpHandler, r as normalizeSlackWebhookPath } from "./registry-DizWcnNp.mjs";
|
|
3
|
+
import { a as mergeSlackAccountConfig, c as resolveSlackAccountAllowFrom, f as resolveSlackReplyToMode, h as resolveSlackBotToken, l as resolveSlackAccountDmPolicy, m as resolveSlackAppToken, o as resolveDefaultSlackAccountId, p as formatSlackBotTokenIdentityWarning, s as resolveSlackAccount } from "./accounts-msihSF3-.mjs";
|
|
4
4
|
import { a as parseSlackTarget, n as formatSlackTarget } from "./target-parsing-FFE26kOV.mjs";
|
|
5
|
-
import {
|
|
6
|
-
import { A as resolveSlackAllowListMatch, C as resolveSlackLookupClientOptions, D as allowListMatches, O as normalizeSlackAllowOwnerEntry, T as resolveSlackWebClientOptions, a as slackIngressIdentity, b as writeLruMapEntry, c as collectSlackCursorPages, f as createSlackStartupAuthClient, g as getSlackListenerWriteClient, i as createSlackIngressSubject, j as resolveSlackUserAllowListForTeam, k as normalizeSlackSlug, m as createSlackWebClient, o as formatSlackError, v as pruneExpiredMapEntries, w as resolveSlackMonitorDispatchers, y as readLruMapEntry } from "./probe-
|
|
5
|
+
import { D as buildSlackCompleteBlocksFallbackText, Ft as isSlackExecApprovalAuthorizedSender, G as isSlackQuestionActionId, M as SLACK_TEXT_LIMIT, Nt as registerSlackInstallationState, P as truncateSlackText, U as isSlackApprovalActionId, W as isSlackCallbackActionId, Y as resolveSlackQuestionAction, _t as isSlackAnyNativeApprovalClientEnabled, c as qualifySlackConversationId, d as normalizeSlackRouteBindingConfig, kt as isSlackPluginApprovalAuthorizedSender, l as qualifySlackRoutePeerId, lt as decodeSlackApprovalAction, n as setSlackSessionStatus, p as resolveSlackConversationBindingRouteAsync, q as decodeSlackQuestionAction, r as buildSlackChannelIdCandidates, s as setSlackChannelPolicyBindings, st as escapeSlackMrkdwn, t as renameSlackSession, u as resolveSlackAgentRoute } from "./session-status-DQY4hZLd.mjs";
|
|
6
|
+
import { A as resolveSlackAllowListMatch, C as resolveSlackLookupClientOptions, D as allowListMatches, O as normalizeSlackAllowOwnerEntry, T as resolveSlackWebClientOptions, a as slackIngressIdentity, b as writeLruMapEntry, c as collectSlackCursorPages, f as createSlackStartupAuthClient, g as getSlackListenerWriteClient, i as createSlackIngressSubject, j as resolveSlackUserAllowListForTeam, k as normalizeSlackSlug, m as createSlackWebClient, o as formatSlackError, v as pruneExpiredMapEntries, w as resolveSlackMonitorDispatchers, y as readLruMapEntry } from "./probe-IiHogLQN.mjs";
|
|
7
7
|
import { n as getSlackRuntime, t as getOptionalSlackRuntime } from "./runtime-JSVZSWAj.mjs";
|
|
8
8
|
import { t as DEFAULT_SLACK_SUGGESTED_PROMPTS } from "./channel-meta-C443t-lI.mjs";
|
|
9
|
-
import { S as hasSlackMessageTableBlock, f as readSlackMessages, v as isGovSlackClient, y as saveRemoteMedia } from "./actions-
|
|
10
|
-
import { d as requireSlackPostMessageTimestamp, f as buildSlackMessageIdentityPayload, r as setSlackDefaultSendIdentity } from "./send-
|
|
11
|
-
import
|
|
12
|
-
import { t as
|
|
13
|
-
import { t as
|
|
14
|
-
import {
|
|
9
|
+
import { S as hasSlackMessageTableBlock, f as readSlackMessages, v as isGovSlackClient, y as saveRemoteMedia } from "./actions-CafoV8hS.mjs";
|
|
10
|
+
import { d as requireSlackPostMessageTimestamp, f as buildSlackMessageIdentityPayload, r as setSlackDefaultSendIdentity } from "./send-pi6r24yv.mjs";
|
|
11
|
+
import "./http-C9sM-FXe.mjs";
|
|
12
|
+
import { n as resolveSlackChannelConfig, r as resolveSlackChannelLabel, t as isSlackChannelAllowedByPolicy } from "./policy-D4eNyn8m.mjs";
|
|
13
|
+
import { t as resolveSlackChannelAllowlist } from "./resolve-channels-DRRhElwz.mjs";
|
|
14
|
+
import { t as resolveSlackUserAllowlist } from "./resolve-users-Cz8e17ky.mjs";
|
|
15
|
+
import { n as runSlackApprovalMessageUpdate, t as hasSlackApprovalControl } from "./approval-message-updates-DCnXFLf3.mjs";
|
|
15
16
|
import { normalizeAccountId } from "openclaw/plugin-sdk/account-resolution";
|
|
16
17
|
import { normalizeResolvedSecretInputString } from "openclaw/plugin-sdk/secret-input";
|
|
17
18
|
import { asNonArrayRecord, asOptionalObjectRecord, asOptionalRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, normalizeUniqueTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
@@ -30,23 +31,24 @@ import { parseExecApprovalCommandText } from "openclaw/plugin-sdk/approval-reply
|
|
|
30
31
|
import { asDateTimestampMs, parseStrictFiniteNumber, resolveExpiresAtMsFromDurationMs, resolvePromptHistoryLimit, timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
31
32
|
import { WebAPIHTTPError, WebAPIPlatformError, WebAPIRateLimitedError, WebAPIRequestError, WebClient } from "@slack/web-api";
|
|
32
33
|
import { classifyTransientNetworkErrorCode } from "openclaw/plugin-sdk/retry-runtime";
|
|
33
|
-
import {
|
|
34
|
+
import { resolveRuntimeConversationBindingRouteAsync } from "openclaw/plugin-sdk/conversation-binding-runtime";
|
|
34
35
|
import { readChannelIngressStoreAllowFromForDmPolicy } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
35
36
|
import { collectErrorGraphCandidates, extractErrorCode, formatErrorMessage, isApprovalNotFoundError, readErrorName, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
36
37
|
import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
|
|
37
38
|
import { buildChannelMetadata } from "openclaw/plugin-sdk/security-runtime";
|
|
38
39
|
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
39
40
|
import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
|
|
41
|
+
import { buildPluginBindingResolvedText, parsePluginBindingApprovalCustomId, resolvePluginConversationBindingApproval, upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
|
40
42
|
import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
|
|
41
43
|
import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
42
|
-
import {
|
|
44
|
+
import { captureRuntimeConfigAsyncReader, createRuntimeConfigReader } from "openclaw/plugin-sdk/runtime-config-snapshot";
|
|
43
45
|
import { registerChannelRuntimeContext } from "openclaw/plugin-sdk/channel-runtime-context";
|
|
44
46
|
import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-name-runtime";
|
|
45
47
|
import { channelBlockedPatch, channelReadyPatch } from "openclaw/plugin-sdk/gateway-runtime";
|
|
46
|
-
import {
|
|
47
|
-
import {
|
|
48
|
+
import { getConversationSessionAsync, getSessionEntryAsync, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
49
|
+
import { captureSessionEntryCurrentCheckAsync } from "openclaw/plugin-sdk/session-binding-runtime";
|
|
48
50
|
import { loadPreparedModelCatalog, resolveAgentDir, resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
49
|
-
import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listNativeCommandSpecsForConfig,
|
|
51
|
+
import { buildCommandTextFromArgs, findCommandByNativeName, formatCommandArgMenuTitle, listNativeCommandSpecsForConfig, parseCommandArgs, prepareSkillCommandsForAgents, resolveCommandArgMenuAsync, resolveCommandAuthorizationAsync, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverrideAsync } from "openclaw/plugin-sdk/command-auth-native";
|
|
50
52
|
import { mergeNativeCommandSpecs } from "openclaw/plugin-sdk/native-command-registry";
|
|
51
53
|
import { generateSecureToken } from "openclaw/plugin-sdk/secure-random-runtime";
|
|
52
54
|
import { resolveChannelConfigWrites } from "openclaw/plugin-sdk/channel-config-writes";
|
|
@@ -522,7 +524,7 @@ function formatSlackSocketModeSharedConnectionWarning(activeConnections) {
|
|
|
522
524
|
return [
|
|
523
525
|
`slack socket mode reports ${activeConnections} active connections for this Slack app`,
|
|
524
526
|
"Slack may deliver each event to any one connection",
|
|
525
|
-
"
|
|
527
|
+
"check that every OpenClaw gateway sharing this app has equivalent routing and authorization, or use a separate Slack app per gateway, one relay ingress, or HTTP Request URLs behind a load balancer",
|
|
526
528
|
`See ${SLACK_SOCKET_SHARED_CONNECTION_DOCS_URL}`
|
|
527
529
|
].join("; ");
|
|
528
530
|
}
|
|
@@ -879,7 +881,7 @@ function formatSlackUserResolved(entry) {
|
|
|
879
881
|
//#endregion
|
|
880
882
|
//#region extensions/slack/src/monitor/system-event-session.ts
|
|
881
883
|
function createSlackSystemEventRouteResolver(params) {
|
|
882
|
-
return (event) => {
|
|
884
|
+
return async (event) => {
|
|
883
885
|
const channelId = normalizeOptionalString(event.channelId) ?? "";
|
|
884
886
|
const senderId = normalizeOptionalString(event.senderId) ?? "";
|
|
885
887
|
const channelType = normalizeSlackChannelType(event.channelType ?? params.recallSlackChannelType(channelId, event.eventScope), channelId);
|
|
@@ -907,7 +909,7 @@ function createSlackSystemEventRouteResolver(params) {
|
|
|
907
909
|
});
|
|
908
910
|
const threadTs = normalizeOptionalString(event.threadTs);
|
|
909
911
|
const baseConversationId = qualifySlackConversationId(isDirectMessage ? `user:${senderId}` : channelId, event.eventScope);
|
|
910
|
-
const threadBindingRoute = !event.eventScope && threadTs ?
|
|
912
|
+
const threadBindingRoute = !event.eventScope && threadTs ? await resolveRuntimeConversationBindingRouteAsync({
|
|
911
913
|
route,
|
|
912
914
|
conversation: {
|
|
913
915
|
channel: "slack",
|
|
@@ -920,7 +922,7 @@ function createSlackSystemEventRouteResolver(params) {
|
|
|
920
922
|
route,
|
|
921
923
|
bindingRecord: null,
|
|
922
924
|
boundSessionKey: void 0
|
|
923
|
-
} : threadBindingRoute?.boundSessionKey || threadBindingRoute?.bindingRecord ? threadBindingRoute :
|
|
925
|
+
} : threadBindingRoute?.boundSessionKey || threadBindingRoute?.bindingRecord ? threadBindingRoute : await resolveRuntimeConversationBindingRouteAsync({
|
|
924
926
|
route,
|
|
925
927
|
conversation: {
|
|
926
928
|
channel: "slack",
|
|
@@ -1032,6 +1034,8 @@ function resolveStableSlackUserIdEntry(raw) {
|
|
|
1032
1034
|
return /^[UW][A-Z0-9]+$/i.test(trimmed) ? trimmed.toUpperCase() : void 0;
|
|
1033
1035
|
}
|
|
1034
1036
|
async function resolveWorkspacePolicy(ctx, resolveToken) {
|
|
1037
|
+
const channelBindings = /* @__PURE__ */ new Map();
|
|
1038
|
+
if (ctx.installationIdentity.kind !== "workspace") setSlackChannelPolicyBindings(ctx.accountId, channelBindings);
|
|
1035
1039
|
if (ctx.installationIdentity.kind === "enterprise") {
|
|
1036
1040
|
assertEnterpriseSlackPolicyConfig({
|
|
1037
1041
|
config: mergeSlackAccountConfig(ctx.cfg, ctx.accountId),
|
|
@@ -1068,6 +1072,7 @@ async function resolveWorkspacePolicy(ctx, resolveToken) {
|
|
|
1068
1072
|
...source,
|
|
1069
1073
|
...existing
|
|
1070
1074
|
};
|
|
1075
|
+
channelBindings.set(entry.input, entry.id);
|
|
1071
1076
|
}
|
|
1072
1077
|
channelsConfig = nextChannels;
|
|
1073
1078
|
ctx.channelsConfig = nextChannels;
|
|
@@ -1076,6 +1081,7 @@ async function resolveWorkspacePolicy(ctx, resolveToken) {
|
|
|
1076
1081
|
} catch (err) {
|
|
1077
1082
|
runtime.log?.(`slack channel resolve failed; using config entries. ${formatSlackError(err)}`);
|
|
1078
1083
|
}
|
|
1084
|
+
if (ctx.isRuntimePolicyCurrent()) setSlackChannelPolicyBindings(ctx.accountId, channelBindings);
|
|
1079
1085
|
const dmEntries = new Set(allowFrom.filter((entry) => entry !== "*"));
|
|
1080
1086
|
const userEntries = new Set(dmEntries);
|
|
1081
1087
|
for (const channel of Object.values(channelsConfig ?? {})) addAllowlistUserEntriesFromConfigEntry(userEntries, channel);
|
|
@@ -1669,8 +1675,7 @@ function createSlackThreadTsResolver(params) {
|
|
|
1669
1675
|
const getCached = (key, now) => {
|
|
1670
1676
|
const entry = cache.get(key);
|
|
1671
1677
|
if (!entry) return;
|
|
1672
|
-
|
|
1673
|
-
if (normalizedNow === void 0 || entry.expiresAt <= normalizedNow) {
|
|
1678
|
+
if (entry.expiresAt <= now) {
|
|
1674
1679
|
cache.delete(key);
|
|
1675
1680
|
return;
|
|
1676
1681
|
}
|
|
@@ -1679,15 +1684,10 @@ function createSlackThreadTsResolver(params) {
|
|
|
1679
1684
|
return entry.threadTs;
|
|
1680
1685
|
};
|
|
1681
1686
|
const setCached = (key, threadTs, now) => {
|
|
1682
|
-
const expiresAt = resolveExpiresAtMsFromDurationMs(DEFAULT_THREAD_TS_CACHE_TTL_MS, { nowMs: now });
|
|
1683
|
-
if (expiresAt === void 0) {
|
|
1684
|
-
cache.delete(key);
|
|
1685
|
-
return;
|
|
1686
|
-
}
|
|
1687
1687
|
cache.delete(key);
|
|
1688
1688
|
cache.set(key, {
|
|
1689
1689
|
threadTs,
|
|
1690
|
-
expiresAt
|
|
1690
|
+
expiresAt: now + DEFAULT_THREAD_TS_CACHE_TTL_MS
|
|
1691
1691
|
});
|
|
1692
1692
|
pruneMapToMaxSize(cache, DEFAULT_THREAD_TS_CACHE_MAX);
|
|
1693
1693
|
};
|
|
@@ -2467,13 +2467,12 @@ function resolveSlackThreadContext(params) {
|
|
|
2467
2467
|
//#endregion
|
|
2468
2468
|
//#region extensions/slack/src/monitor/session-run-targets.ts
|
|
2469
2469
|
async function captureSlackSessionTargetGuard(ctx, route, isActive) {
|
|
2470
|
-
|
|
2470
|
+
return captureSessionEntryCurrentCheckAsync({
|
|
2471
2471
|
agentId: route.agentId,
|
|
2472
2472
|
sessionKey: route.sessionKey,
|
|
2473
2473
|
storePath: resolveStorePath(ctx.cfg.session?.store, { agentId: route.agentId }),
|
|
2474
2474
|
isActive
|
|
2475
2475
|
});
|
|
2476
|
-
return isCurrent;
|
|
2477
2476
|
}
|
|
2478
2477
|
const runs = /* @__PURE__ */ new WeakMap();
|
|
2479
2478
|
function addressKey(address) {
|
|
@@ -2510,7 +2509,7 @@ function getSlackSessionRuns(ctx, address) {
|
|
|
2510
2509
|
}
|
|
2511
2510
|
//#endregion
|
|
2512
2511
|
//#region extensions/slack/src/monitor/message-handler/prepare-routing.ts
|
|
2513
|
-
function resolveSlackRoutingContext(params) {
|
|
2512
|
+
async function resolveSlackRoutingContext(params) {
|
|
2514
2513
|
const { ctx, account, message, chatType, channelConfig, seedTopLevelRoomThread, assistantThreadTs, agentViewThreadTs, eventScope } = params;
|
|
2515
2514
|
const isDirectMessage = chatType === "direct";
|
|
2516
2515
|
const isRoom = chatType === "channel";
|
|
@@ -2526,7 +2525,7 @@ function resolveSlackRoutingContext(params) {
|
|
|
2526
2525
|
const routedThreadId = isDirectMessage ? assistantThreadTs ?? agentViewThreadTs : (isThreadReply && threadTs ? threadTs : void 0) ?? (!isThreadReply && isRoom && seedTopLevelRoomThread && replyToMode !== "off" && seedCandidateThreadId ? seedCandidateThreadId : void 0);
|
|
2527
2526
|
const baseConversationId = qualifySlackConversationId(isDirectMessage ? `user:${message.user ?? "unknown"}` : message.channel, eventScope);
|
|
2528
2527
|
const runtimeBindingThreadId = routedThreadId ?? (isDirectMessage && isThreadReply ? threadTs : void 0);
|
|
2529
|
-
const bindingRoute =
|
|
2528
|
+
const bindingRoute = await resolveSlackConversationBindingRouteAsync({
|
|
2530
2529
|
cfg: ctx.cfg,
|
|
2531
2530
|
resolveRoute: ({ boundAgentId, bindingOwnerAvailable }) => resolveSlackAgentRoute({
|
|
2532
2531
|
cfg: boundAgentId || !bindingOwnerAvailable ? { session: ctx.cfg.session } : normalizeSlackRouteBindingConfig(ctx.cfg),
|
|
@@ -2575,7 +2574,7 @@ function resolveSlackRoutingContext(params) {
|
|
|
2575
2574
|
async function resolveSlackSessionEventRoutingContext(params) {
|
|
2576
2575
|
const { ctx, message, eventScope } = params;
|
|
2577
2576
|
const threadTs = message.thread_ts;
|
|
2578
|
-
const routing = resolveSlackRoutingContext(params);
|
|
2577
|
+
const routing = await resolveSlackRoutingContext(params);
|
|
2579
2578
|
const address = {
|
|
2580
2579
|
agentId: routing.route.agentId,
|
|
2581
2580
|
storePath: resolveStorePath(ctx.cfg.session?.store, { agentId: routing.route.agentId }),
|
|
@@ -2598,8 +2597,8 @@ async function resolveSlackSessionEventRoutingContext(params) {
|
|
|
2598
2597
|
eventScope
|
|
2599
2598
|
};
|
|
2600
2599
|
let allowDirectParent = false;
|
|
2601
|
-
const readOwner = () => {
|
|
2602
|
-
const recorded =
|
|
2600
|
+
const readOwner = async () => {
|
|
2601
|
+
const recorded = await getConversationSessionAsync(threadAddress);
|
|
2603
2602
|
if (recorded) return {
|
|
2604
2603
|
route: {
|
|
2605
2604
|
...routing.route,
|
|
@@ -2613,7 +2612,7 @@ async function resolveSlackSessionEventRoutingContext(params) {
|
|
|
2613
2612
|
source: "live",
|
|
2614
2613
|
isActive: live.isActive
|
|
2615
2614
|
};
|
|
2616
|
-
const parent = allowDirectParent ?
|
|
2615
|
+
const parent = allowDirectParent ? await getConversationSessionAsync(address) : void 0;
|
|
2617
2616
|
return parent ? {
|
|
2618
2617
|
route: {
|
|
2619
2618
|
...routing.route,
|
|
@@ -2622,8 +2621,7 @@ async function resolveSlackSessionEventRoutingContext(params) {
|
|
|
2622
2621
|
source: "parent"
|
|
2623
2622
|
} : void 0;
|
|
2624
2623
|
};
|
|
2625
|
-
let owner = readOwner();
|
|
2626
|
-
if (owner?.source === "live" && params.chatType === "direct") allowDirectParent = getConversationSession(address)?.sessionKey === owner.route.sessionKey;
|
|
2624
|
+
let owner = await readOwner();
|
|
2627
2625
|
if (!owner && params.chatType === "direct" && threadTs) {
|
|
2628
2626
|
const assistantContext = ctx.getSlackAssistantThreadContext(message.channel, threadTs, eventScope);
|
|
2629
2627
|
const managedThread = !eventScope && (await ctx.isSlackManagedViewThread(message.channel, threadTs) || await ctx.isSlackAgentView());
|
|
@@ -2633,36 +2631,46 @@ async function resolveSlackSessionEventRoutingContext(params) {
|
|
|
2633
2631
|
threadTs,
|
|
2634
2632
|
userId: message.user
|
|
2635
2633
|
}))) && !managedThread;
|
|
2636
|
-
owner = readOwner();
|
|
2634
|
+
owner = await readOwner();
|
|
2637
2635
|
}
|
|
2638
2636
|
if (!owner) throw new Error("No recorded session owns this Slack conversation");
|
|
2639
2637
|
const { route } = owner;
|
|
2638
|
+
const ownerAddress = {
|
|
2639
|
+
...address,
|
|
2640
|
+
agentId: route.agentId,
|
|
2641
|
+
storePath: resolveStorePath(ctx.cfg.session?.store, { agentId: route.agentId })
|
|
2642
|
+
};
|
|
2643
|
+
const ownerThreadAddress = {
|
|
2644
|
+
...ownerAddress,
|
|
2645
|
+
threadId: threadTs
|
|
2646
|
+
};
|
|
2647
|
+
if (owner.source === "live" && params.chatType === "direct") allowDirectParent = (await getConversationSessionAsync(ownerAddress))?.sessionKey === route.sessionKey;
|
|
2640
2648
|
const readLiveOwner = () => getSlackSessionRuns(ctx, liveAddress).at(-1);
|
|
2641
|
-
const current = await
|
|
2649
|
+
const current = await captureSessionEntryCurrentCheckAsync({
|
|
2642
2650
|
agentId: route.agentId,
|
|
2643
2651
|
sessionKey: route.sessionKey,
|
|
2644
|
-
storePath:
|
|
2652
|
+
storePath: ownerAddress.storePath,
|
|
2645
2653
|
isActive: params.intent === "stop" ? owner.isActive : void 0,
|
|
2646
2654
|
matchGeneration: params.intent === "stop",
|
|
2647
2655
|
errorMessage: params.intent === "title" ? "Slack conversation owner changed before the title update" : "The selected session changed before it could be stopped.",
|
|
2648
2656
|
alternatives: [
|
|
2649
2657
|
{ conversations: [{
|
|
2650
|
-
...
|
|
2658
|
+
...ownerThreadAddress,
|
|
2651
2659
|
sessionKey: route.sessionKey
|
|
2652
2660
|
}] },
|
|
2653
2661
|
{
|
|
2654
2662
|
conversations: [{
|
|
2655
|
-
...
|
|
2663
|
+
...ownerThreadAddress,
|
|
2656
2664
|
sessionKey: null
|
|
2657
2665
|
}],
|
|
2658
2666
|
isActive: () => readLiveOwner()?.route.sessionKey === route.sessionKey
|
|
2659
2667
|
},
|
|
2660
2668
|
...allowDirectParent ? [{
|
|
2661
2669
|
conversations: [{
|
|
2662
|
-
...
|
|
2670
|
+
...ownerThreadAddress,
|
|
2663
2671
|
sessionKey: null
|
|
2664
2672
|
}, {
|
|
2665
|
-
...
|
|
2673
|
+
...ownerAddress,
|
|
2666
2674
|
sessionKey: route.sessionKey
|
|
2667
2675
|
}],
|
|
2668
2676
|
isActive: () => !readLiveOwner()
|
|
@@ -2674,7 +2682,8 @@ async function resolveSlackSessionEventRoutingContext(params) {
|
|
|
2674
2682
|
route,
|
|
2675
2683
|
sessionKey: route.sessionKey,
|
|
2676
2684
|
isCurrentSession: current.isCurrent,
|
|
2677
|
-
|
|
2685
|
+
sessionSource: current.source,
|
|
2686
|
+
release: current.release
|
|
2678
2687
|
};
|
|
2679
2688
|
}
|
|
2680
2689
|
//#endregion
|
|
@@ -2767,11 +2776,10 @@ function createSlackExternalArgMenuStore() {
|
|
|
2767
2776
|
create(params, now = Date.now()) {
|
|
2768
2777
|
pruneExpiredMapEntries(store, now);
|
|
2769
2778
|
const token = createSlackExternalArgMenuToken(store);
|
|
2770
|
-
|
|
2771
|
-
if (expiresAt !== void 0) store.set(token, {
|
|
2779
|
+
store.set(token, {
|
|
2772
2780
|
choices: params.choices,
|
|
2773
2781
|
userId: params.userId,
|
|
2774
|
-
expiresAt
|
|
2782
|
+
expiresAt: now + SLACK_EXTERNAL_ARG_MENU_TTL_MS
|
|
2775
2783
|
});
|
|
2776
2784
|
return token;
|
|
2777
2785
|
},
|
|
@@ -2815,24 +2823,8 @@ function resolveSlackRoomContextHints(params) {
|
|
|
2815
2823
|
};
|
|
2816
2824
|
}
|
|
2817
2825
|
//#endregion
|
|
2818
|
-
//#region extensions/slack/src/monitor/slash.ts
|
|
2819
|
-
|
|
2820
|
-
const SLACK_COMMAND_ARG_ACTION_LISTENER = /^openclaw_cmdarg/;
|
|
2821
|
-
const SLACK_COMMAND_ARG_VALUE_PREFIX = "cmdarg";
|
|
2822
|
-
const SLACK_COMMAND_ARG_BUTTON_ROW_SIZE = 5;
|
|
2823
|
-
const SLACK_COMMAND_ARG_OVERFLOW_MIN = 3;
|
|
2824
|
-
const SLACK_COMMAND_ARG_OVERFLOW_MAX = 5;
|
|
2825
|
-
const SLACK_COMMAND_ARG_SELECT_OPTIONS_MAX = 100;
|
|
2826
|
-
const SLACK_COMMAND_ARG_SELECT_OPTION_TEXT_MAX = 75;
|
|
2827
|
-
const SLACK_COMMAND_ARG_SELECT_OPTION_VALUE_MAX = 150;
|
|
2828
|
-
const SLACK_COMMAND_ARG_BUTTON_TEXT_MAX = 75;
|
|
2829
|
-
const SLACK_COMMAND_ARG_BUTTON_VALUE_MAX = 2e3;
|
|
2830
|
-
const SLACK_COMMAND_ARG_CONFIRM_TEXT_MAX = 300;
|
|
2831
|
-
const SLACK_HEADER_TEXT_MAX = 150;
|
|
2832
|
-
const SLACK_COMMAND_ARG_ACTION_BLOCKS_MAX = 47;
|
|
2833
|
-
const loadSlashDispatchRuntime = createLazyRuntimeModule(() => import("./slash-dispatch.runtime-Dzwj6TPI.mjs"));
|
|
2834
|
-
const loadPluginCommandRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/plugin-command-runtime"));
|
|
2835
|
-
function resolveSlackCommandMenuModelContext(params) {
|
|
2826
|
+
//#region extensions/slack/src/monitor/slash-menu-model-context.ts
|
|
2827
|
+
async function resolveSlackCommandMenuModelContext(params) {
|
|
2836
2828
|
if (!params.sessionKey.trim()) return {};
|
|
2837
2829
|
try {
|
|
2838
2830
|
const defaultModel = resolveDefaultModelForAgent({
|
|
@@ -2840,7 +2832,8 @@ function resolveSlackCommandMenuModelContext(params) {
|
|
|
2840
2832
|
agentId: params.agentId
|
|
2841
2833
|
});
|
|
2842
2834
|
const storePath = resolveStorePath(params.cfg.session?.store, { agentId: params.agentId });
|
|
2843
|
-
const entry =
|
|
2835
|
+
const entry = await getSessionEntryAsync({
|
|
2836
|
+
agentId: params.agentId,
|
|
2844
2837
|
storePath,
|
|
2845
2838
|
sessionKey: params.sessionKey
|
|
2846
2839
|
});
|
|
@@ -2850,14 +2843,15 @@ function resolveSlackCommandMenuModelContext(params) {
|
|
|
2850
2843
|
provider = defaultModel.provider;
|
|
2851
2844
|
model = defaultModel.model;
|
|
2852
2845
|
} else {
|
|
2853
|
-
const override =
|
|
2846
|
+
const override = await resolveStoredModelOverrideAsync({
|
|
2854
2847
|
sessionEntry: entry,
|
|
2855
|
-
|
|
2848
|
+
sessionKey: params.sessionKey,
|
|
2849
|
+
defaultProvider: defaultModel.provider,
|
|
2850
|
+
loadSessionEntry: (sessionKey) => getSessionEntryAsync({
|
|
2851
|
+
agentId: params.agentId,
|
|
2856
2852
|
storePath,
|
|
2857
2853
|
sessionKey
|
|
2858
|
-
})
|
|
2859
|
-
sessionKey: params.sessionKey,
|
|
2860
|
-
defaultProvider: defaultModel.provider
|
|
2854
|
+
})
|
|
2861
2855
|
});
|
|
2862
2856
|
provider = override?.model ? override.provider || defaultModel.provider : normalizeOptionalString(entry?.providerOverride) ?? normalizeOptionalString(entry?.modelProvider);
|
|
2863
2857
|
model = override?.model ? override.model : normalizeOptionalString(entry?.modelOverride) ?? normalizeOptionalString(entry?.model);
|
|
@@ -2878,6 +2872,24 @@ function resolveSlackCommandMenuModelContext(params) {
|
|
|
2878
2872
|
return {};
|
|
2879
2873
|
}
|
|
2880
2874
|
}
|
|
2875
|
+
//#endregion
|
|
2876
|
+
//#region extensions/slack/src/monitor/slash.ts
|
|
2877
|
+
const SLACK_COMMAND_ARG_ACTION_ID = "openclaw_cmdarg";
|
|
2878
|
+
const SLACK_COMMAND_ARG_ACTION_LISTENER = /^openclaw_cmdarg/;
|
|
2879
|
+
const SLACK_COMMAND_ARG_VALUE_PREFIX = "cmdarg";
|
|
2880
|
+
const SLACK_COMMAND_ARG_BUTTON_ROW_SIZE = 5;
|
|
2881
|
+
const SLACK_COMMAND_ARG_OVERFLOW_MIN = 3;
|
|
2882
|
+
const SLACK_COMMAND_ARG_OVERFLOW_MAX = 5;
|
|
2883
|
+
const SLACK_COMMAND_ARG_SELECT_OPTIONS_MAX = 100;
|
|
2884
|
+
const SLACK_COMMAND_ARG_SELECT_OPTION_TEXT_MAX = 75;
|
|
2885
|
+
const SLACK_COMMAND_ARG_SELECT_OPTION_VALUE_MAX = 150;
|
|
2886
|
+
const SLACK_COMMAND_ARG_BUTTON_TEXT_MAX = 75;
|
|
2887
|
+
const SLACK_COMMAND_ARG_BUTTON_VALUE_MAX = 2e3;
|
|
2888
|
+
const SLACK_COMMAND_ARG_CONFIRM_TEXT_MAX = 300;
|
|
2889
|
+
const SLACK_HEADER_TEXT_MAX = 150;
|
|
2890
|
+
const SLACK_COMMAND_ARG_ACTION_BLOCKS_MAX = 47;
|
|
2891
|
+
const loadSlashDispatchRuntime = createLazyRuntimeModule(() => import("./slash-dispatch.runtime-BlBuHX9x.mjs"));
|
|
2892
|
+
const loadPluginCommandRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/plugin-command-runtime"));
|
|
2881
2893
|
const slackExternalArgMenuStore = createSlackExternalArgMenuStore();
|
|
2882
2894
|
function buildSlackArgMenuConfirm(params) {
|
|
2883
2895
|
const command = escapeSlackMrkdwn(params.command);
|
|
@@ -3036,6 +3048,7 @@ function createSlackCommandHandler(params) {
|
|
|
3036
3048
|
response_type: "ephemeral"
|
|
3037
3049
|
});
|
|
3038
3050
|
let cfg = monitor.cfg;
|
|
3051
|
+
let releaseSessionTarget;
|
|
3039
3052
|
try {
|
|
3040
3053
|
if (monitor.shouldDropMismatchedSlackEvent?.(body)) {
|
|
3041
3054
|
await ack();
|
|
@@ -3144,13 +3157,16 @@ function createSlackCommandHandler(params) {
|
|
|
3144
3157
|
});
|
|
3145
3158
|
const routingTeamId = (eventScope?.teamId ?? ctx.teamId) || void 0;
|
|
3146
3159
|
let resolvedSlashRoute;
|
|
3147
|
-
|
|
3160
|
+
const sessionTarget = { isCurrent: p.isSessionTargetCurrent };
|
|
3148
3161
|
const resolveSlashRoute = async () => {
|
|
3149
3162
|
if (resolvedSlashRoute) return resolvedSlashRoute;
|
|
3150
3163
|
if (p.threadTs) {
|
|
3151
3164
|
if (p.sessionTarget) {
|
|
3152
3165
|
resolvedSlashRoute = p.sessionTarget;
|
|
3153
|
-
|
|
3166
|
+
const current = await captureSlackSessionTargetGuard(ctx, p.sessionTarget, p.isSessionTargetCurrent);
|
|
3167
|
+
sessionTarget.isCurrent = current.isCurrent;
|
|
3168
|
+
sessionTarget.source = current.source;
|
|
3169
|
+
releaseSessionTarget = current.release;
|
|
3154
3170
|
return resolvedSlashRoute;
|
|
3155
3171
|
}
|
|
3156
3172
|
const routing = await resolveSlackSessionEventRoutingContext({
|
|
@@ -3169,7 +3185,9 @@ function createSlackCommandHandler(params) {
|
|
|
3169
3185
|
eventScope
|
|
3170
3186
|
});
|
|
3171
3187
|
resolvedSlashRoute = routing.route;
|
|
3172
|
-
|
|
3188
|
+
sessionTarget.isCurrent = routing.isCurrentSession;
|
|
3189
|
+
sessionTarget.source = routing.sessionSource;
|
|
3190
|
+
releaseSessionTarget = routing.release;
|
|
3173
3191
|
return resolvedSlashRoute;
|
|
3174
3192
|
}
|
|
3175
3193
|
const { resolveAgentRoute } = await loadSlashDispatchRuntime();
|
|
@@ -3188,7 +3206,7 @@ function createSlackCommandHandler(params) {
|
|
|
3188
3206
|
if (commandDefinition && supportsInteractiveArgMenus) {
|
|
3189
3207
|
const menuNeedsModelContext = !(commandArgs?.raw && !commandArgs.values) && commandDefinition.args?.some((arg) => typeof arg.choices === "function" && commandArgs?.values?.[arg.name] == null);
|
|
3190
3208
|
const menuRoute = menuNeedsModelContext || commandDefinition.key === "verbose" ? await resolveSlashRoute() : void 0;
|
|
3191
|
-
const menuModelContext = menuNeedsModelContext && menuRoute ? resolveSlackCommandMenuModelContext({
|
|
3209
|
+
const menuModelContext = menuNeedsModelContext && menuRoute ? await resolveSlackCommandMenuModelContext({
|
|
3192
3210
|
cfg,
|
|
3193
3211
|
agentId: menuRoute.agentId,
|
|
3194
3212
|
sessionKey: menuRoute.sessionKey
|
|
@@ -3201,7 +3219,7 @@ function createSlackCommandHandler(params) {
|
|
|
3201
3219
|
} : {},
|
|
3202
3220
|
readOnly: true
|
|
3203
3221
|
}) : void 0;
|
|
3204
|
-
const menu =
|
|
3222
|
+
const menu = await resolveCommandArgMenuAsync({
|
|
3205
3223
|
command: commandDefinition,
|
|
3206
3224
|
args: commandArgs,
|
|
3207
3225
|
cfg,
|
|
@@ -3210,27 +3228,46 @@ function createSlackCommandHandler(params) {
|
|
|
3210
3228
|
catalog: menuModelCatalog
|
|
3211
3229
|
});
|
|
3212
3230
|
if (menu) {
|
|
3231
|
+
const route = menuRoute ?? await resolveSlashRoute();
|
|
3213
3232
|
const commandLabel = commandDefinition.nativeName ?? commandDefinition.key;
|
|
3214
3233
|
const title = formatCommandArgMenuTitle({
|
|
3215
3234
|
command: commandDefinition,
|
|
3216
3235
|
menu
|
|
3217
3236
|
});
|
|
3237
|
+
const blocks = buildSlackCommandArgMenuBlocks({
|
|
3238
|
+
title,
|
|
3239
|
+
command: commandLabel,
|
|
3240
|
+
arg: menu.arg.name,
|
|
3241
|
+
choices: menu.choices,
|
|
3242
|
+
userId: command.user_id,
|
|
3243
|
+
supportsExternalSelect: params.supportsExternalArgMenus?.() ?? false,
|
|
3244
|
+
createExternalMenuToken: (choices) => slackExternalArgMenuStore.create({
|
|
3245
|
+
choices,
|
|
3246
|
+
userId: command.user_id
|
|
3247
|
+
})
|
|
3248
|
+
});
|
|
3218
3249
|
await respond({
|
|
3219
3250
|
text: title,
|
|
3220
|
-
blocks
|
|
3221
|
-
title,
|
|
3222
|
-
command: commandLabel,
|
|
3223
|
-
arg: menu.arg.name,
|
|
3224
|
-
choices: menu.choices,
|
|
3225
|
-
userId: command.user_id,
|
|
3226
|
-
supportsExternalSelect: params.supportsExternalArgMenus?.() ?? false,
|
|
3227
|
-
createExternalMenuToken: (choices) => slackExternalArgMenuStore.create({
|
|
3228
|
-
choices,
|
|
3229
|
-
userId: command.user_id
|
|
3230
|
-
})
|
|
3231
|
-
}),
|
|
3251
|
+
blocks,
|
|
3232
3252
|
response_type: "ephemeral"
|
|
3233
3253
|
});
|
|
3254
|
+
const commandId = p.eventTs ?? command.trigger_id;
|
|
3255
|
+
if (commandId) {
|
|
3256
|
+
const { recordDeliveredCommandExchange } = await loadSlashDispatchRuntime();
|
|
3257
|
+
await recordDeliveredCommandExchange({
|
|
3258
|
+
config: cfg,
|
|
3259
|
+
agentId: route.agentId,
|
|
3260
|
+
sessionKey: route.sessionKey,
|
|
3261
|
+
assertCurrent: sessionTarget.source,
|
|
3262
|
+
commandText: prompt,
|
|
3263
|
+
commandId: `slack:${account.accountId}:${routeTarget.peerId}:${commandId}`,
|
|
3264
|
+
replyId: "argument-menu",
|
|
3265
|
+
replyText: buildSlackCompleteBlocksFallbackText(blocks, {
|
|
3266
|
+
includeSelectOptions: true,
|
|
3267
|
+
nativeDataFormat: "plain"
|
|
3268
|
+
})
|
|
3269
|
+
});
|
|
3270
|
+
}
|
|
3234
3271
|
return false;
|
|
3235
3272
|
}
|
|
3236
3273
|
}
|
|
@@ -3326,7 +3363,7 @@ function createSlackCommandHandler(params) {
|
|
|
3326
3363
|
const shouldDeliverBlockImmediately = commandDefinition?.key === "login";
|
|
3327
3364
|
const builtInDispatch = p.builtInCommand ? { [(await loadPluginCommandRuntime()).PLUGIN_COMMAND_DISPATCH]: NON_PLUGIN_COMMAND_DISPATCH } : void 0;
|
|
3328
3365
|
if (commandAuthorized) {
|
|
3329
|
-
if (
|
|
3366
|
+
if (await sessionTarget.isCurrent?.() === false || p.onAdmitted?.() === false) {
|
|
3330
3367
|
await respondEphemeral("The selected run has already finished.");
|
|
3331
3368
|
return false;
|
|
3332
3369
|
}
|
|
@@ -3388,7 +3425,7 @@ function createSlackCommandHandler(params) {
|
|
|
3388
3425
|
}
|
|
3389
3426
|
},
|
|
3390
3427
|
replyOptions: {
|
|
3391
|
-
isCommandTargetCurrent:
|
|
3428
|
+
isCommandTargetCurrent: sessionTarget.isCurrent,
|
|
3392
3429
|
skillFilter: channelConfig?.skills,
|
|
3393
3430
|
...pluginCommandReplyOptions,
|
|
3394
3431
|
...builtInDispatch
|
|
@@ -3398,6 +3435,8 @@ function createSlackCommandHandler(params) {
|
|
|
3398
3435
|
} catch (err) {
|
|
3399
3436
|
runtime.error?.(danger(`slack slash handler failed: ${formatErrorMessage(err)}`));
|
|
3400
3437
|
if (!(err instanceof SlackResponseAlreadyReportedError) && responseBudget.remaining() !== 0) await respondEphemeral("Sorry, something went wrong handling that command.");
|
|
3438
|
+
} finally {
|
|
3439
|
+
releaseSessionTarget?.();
|
|
3401
3440
|
}
|
|
3402
3441
|
return false;
|
|
3403
3442
|
};
|
|
@@ -3463,7 +3502,7 @@ async function registerSlackMonitorSlashCommands(params) {
|
|
|
3463
3502
|
providerId: "slack",
|
|
3464
3503
|
providerSetting: account.config.commands?.nativeSkills,
|
|
3465
3504
|
globalSetting: startupCfg.commands?.nativeSkills
|
|
3466
|
-
}) ?
|
|
3505
|
+
}) ? await prepareSkillCommandsForAgents({ cfg: startupCfg }) : [];
|
|
3467
3506
|
nativeCommands = listNativeCommandSpecsForConfig(startupCfg, {
|
|
3468
3507
|
skillCommands,
|
|
3469
3508
|
provider: "slack"
|
|
@@ -3762,20 +3801,27 @@ function registerSlackAgentEvents(params) {
|
|
|
3762
3801
|
chatType: resolveSlackChatType(auth.channelType),
|
|
3763
3802
|
eventScope
|
|
3764
3803
|
});
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
title
|
|
3777
|
-
|
|
3778
|
-
|
|
3804
|
+
try {
|
|
3805
|
+
if (!await getSlackRuntime().agent.session.prepareSessionEntryPatch({
|
|
3806
|
+
agentId: routing.route.agentId,
|
|
3807
|
+
storePath: resolveStorePath(runtimeContext.cfg.session?.store, { agentId: routing.route.agentId }),
|
|
3808
|
+
sessionKey: routing.sessionKey,
|
|
3809
|
+
preserveActivity: true,
|
|
3810
|
+
authority: {
|
|
3811
|
+
kind: "source",
|
|
3812
|
+
source: routing.sessionSource
|
|
3813
|
+
},
|
|
3814
|
+
prepare: () => ({ displayName: event.title })
|
|
3815
|
+
})) throw new Error("Slack conversation session disappeared before the title update");
|
|
3816
|
+
runtimeContext.recordSlackSessionTitle({
|
|
3817
|
+
channelId: event.channel,
|
|
3818
|
+
threadTs: event.thread_ts,
|
|
3819
|
+
title: event.title,
|
|
3820
|
+
eventScope
|
|
3821
|
+
});
|
|
3822
|
+
} finally {
|
|
3823
|
+
routing.release();
|
|
3824
|
+
}
|
|
3779
3825
|
} catch (error) {
|
|
3780
3826
|
runtimeContext.runtime.error?.(`slack session title update failed: ${formatErrorMessage(error)}`);
|
|
3781
3827
|
}
|
|
@@ -3925,7 +3971,7 @@ function registerSlackChannelEvents(params) {
|
|
|
3925
3971
|
channelId,
|
|
3926
3972
|
channelName
|
|
3927
3973
|
});
|
|
3928
|
-
const route = runtimeContext.resolveSlackSystemEventRoute({
|
|
3974
|
+
const route = await runtimeContext.resolveSlackSystemEventRoute({
|
|
3929
3975
|
channelId,
|
|
3930
3976
|
channelType: "channel",
|
|
3931
3977
|
eventScope
|
|
@@ -4277,8 +4323,6 @@ function summarizeSlackViewState(values) {
|
|
|
4277
4323
|
}
|
|
4278
4324
|
return entries;
|
|
4279
4325
|
}
|
|
4280
|
-
//#endregion
|
|
4281
|
-
//#region extensions/slack/src/monitor/events/interactions.block-actions.ts
|
|
4282
4326
|
function formatInteractionSelectionLabel(params) {
|
|
4283
4327
|
if (params.summary.actionType === "button" && params.buttonText?.trim()) return params.buttonText.trim();
|
|
4284
4328
|
const selected = params.summary.selectedLabels?.length ? params.summary.selectedLabels : params.summary.selectedValues;
|
|
@@ -4293,6 +4337,8 @@ function formatInteractionSelectionLabel(params) {
|
|
|
4293
4337
|
if (params.summary.value?.trim()) return params.summary.value.trim();
|
|
4294
4338
|
return params.actionId;
|
|
4295
4339
|
}
|
|
4340
|
+
//#endregion
|
|
4341
|
+
//#region extensions/slack/src/monitor/events/interactions.block-actions.ts
|
|
4296
4342
|
function resolveSlackActionValue(summary) {
|
|
4297
4343
|
return normalizeOptionalString(summary.value) ?? summary.selectedValues?.[0];
|
|
4298
4344
|
}
|
|
@@ -4461,7 +4507,7 @@ async function handleSlackApprovalInteraction(params) {
|
|
|
4461
4507
|
channelId,
|
|
4462
4508
|
messageTs
|
|
4463
4509
|
}, async () => {
|
|
4464
|
-
const { readSlackMessages } = await import("./actions-
|
|
4510
|
+
const { readSlackMessages } = await import("./actions-CafoV8hS.mjs").then((n) => n.t);
|
|
4465
4511
|
const { messages } = await readSlackMessages(channelId, {
|
|
4466
4512
|
client: params.eventScope?.client ?? params.ctx.app.client,
|
|
4467
4513
|
messageId: messageTs,
|
|
@@ -4589,7 +4635,7 @@ async function dispatchSlackPluginInteraction(params) {
|
|
|
4589
4635
|
}
|
|
4590
4636
|
async function resolveSlackBlockActionCommandAuthorized(params) {
|
|
4591
4637
|
const commandsAllowFrom = params.ctx.cfg.commands?.allowFrom;
|
|
4592
|
-
if (commandsAllowFrom != null && typeof commandsAllowFrom === "object" && (Array.isArray(commandsAllowFrom.slack) || Array.isArray(commandsAllowFrom["*"]))) return
|
|
4638
|
+
if (commandsAllowFrom != null && typeof commandsAllowFrom === "object" && (Array.isArray(commandsAllowFrom.slack) || Array.isArray(commandsAllowFrom["*"]))) return (await resolveCommandAuthorizationAsync({
|
|
4593
4639
|
ctx: {
|
|
4594
4640
|
Provider: "slack",
|
|
4595
4641
|
Surface: "slack",
|
|
@@ -4601,7 +4647,7 @@ async function resolveSlackBlockActionCommandAuthorized(params) {
|
|
|
4601
4647
|
},
|
|
4602
4648
|
cfg: params.ctx.cfg,
|
|
4603
4649
|
commandAuthorized: false
|
|
4604
|
-
}).isAuthorizedSender;
|
|
4650
|
+
})).isAuthorizedSender;
|
|
4605
4651
|
const isDirectMessage = params.auth.channelType === "im";
|
|
4606
4652
|
const isRoom = params.auth.channelType === "channel" || params.auth.channelType === "group";
|
|
4607
4653
|
const allowFromLower = await resolveSlackEffectiveAllowFrom(params.ctx, {
|
|
@@ -4638,7 +4684,7 @@ async function resolveSlackBlockActionCommandAuthorized(params) {
|
|
|
4638
4684
|
modeWhenAccessGroupsOff: "configured"
|
|
4639
4685
|
})).commandAccess.authorized;
|
|
4640
4686
|
}
|
|
4641
|
-
function enqueueSlackBlockActionEvent(params) {
|
|
4687
|
+
async function enqueueSlackBlockActionEvent(params) {
|
|
4642
4688
|
const targetKind = params.auth.channelType === "im" ? "user" : "channel";
|
|
4643
4689
|
const targetId = targetKind === "user" ? params.parsed.userId : params.parsed.channelId;
|
|
4644
4690
|
const deferredTarget = targetId ? resolveSlackDeferredActionTarget({
|
|
@@ -4660,7 +4706,7 @@ function enqueueSlackBlockActionEvent(params) {
|
|
|
4660
4706
|
threadTs: params.parsed.threadTs
|
|
4661
4707
|
};
|
|
4662
4708
|
params.ctx.runtime.log?.(`slack:interaction action=${params.parsed.actionId} type=${params.parsed.actionSummary.actionType ?? "unknown"} user=${params.parsed.userId} channel=${params.parsed.channelId}`);
|
|
4663
|
-
enqueueSlackInteractionEvent(eventPayload, params.ctx.resolveSlackSystemEventRoute({
|
|
4709
|
+
enqueueSlackInteractionEvent(eventPayload, await params.ctx.resolveSlackSystemEventRoute({
|
|
4664
4710
|
channelId: params.parsed.channelId,
|
|
4665
4711
|
channelType: params.auth.channelType,
|
|
4666
4712
|
senderId: params.parsed.userId,
|
|
@@ -4808,7 +4854,7 @@ function registerSlackBlockActionHandler(params) {
|
|
|
4808
4854
|
channelType: auth.channelType
|
|
4809
4855
|
})) return;
|
|
4810
4856
|
}
|
|
4811
|
-
enqueueSlackBlockActionEvent({
|
|
4857
|
+
await enqueueSlackBlockActionEvent({
|
|
4812
4858
|
...actionContext,
|
|
4813
4859
|
teamId: args.context.teamId,
|
|
4814
4860
|
auth
|
|
@@ -4857,7 +4903,7 @@ function resolveSlackPluginSystemEventPayload(result) {
|
|
|
4857
4903
|
if (systemEvent.data && typeof systemEvent.data === "object" && !Array.isArray(systemEvent.data)) output.data = systemEvent.data;
|
|
4858
4904
|
return Object.keys(output).length > 0 ? output : void 0;
|
|
4859
4905
|
}
|
|
4860
|
-
function resolveModalSessionRouting(params) {
|
|
4906
|
+
async function resolveModalSessionRouting(params) {
|
|
4861
4907
|
const metadata = params.metadata;
|
|
4862
4908
|
const metadataAgentId = metadata.sessionKey ? resolveAgentIdFromSessionKey(metadata.sessionKey) : void 0;
|
|
4863
4909
|
if (metadata.sessionKey && metadataAgentId && !params.eventScope) return {
|
|
@@ -4867,7 +4913,7 @@ function resolveModalSessionRouting(params) {
|
|
|
4867
4913
|
channelType: metadata.channelType
|
|
4868
4914
|
};
|
|
4869
4915
|
const routing = {
|
|
4870
|
-
...params.ctx.resolveSlackSystemEventRoute({
|
|
4916
|
+
...await params.ctx.resolveSlackSystemEventRoute({
|
|
4871
4917
|
...metadata.channelId ? {
|
|
4872
4918
|
channelId: metadata.channelId,
|
|
4873
4919
|
channelType: metadata.channelType
|
|
@@ -4892,7 +4938,7 @@ async function emitSlackModalLifecycleEvent(params) {
|
|
|
4892
4938
|
const userId = params.body.user?.id ?? "unknown";
|
|
4893
4939
|
const viewId = params.body.view?.id;
|
|
4894
4940
|
const inputs = summarizeSlackViewState(params.body.view?.state?.values);
|
|
4895
|
-
const sessionRouting = resolveModalSessionRouting({
|
|
4941
|
+
const sessionRouting = await resolveModalSessionRouting({
|
|
4896
4942
|
ctx: params.ctx,
|
|
4897
4943
|
metadata,
|
|
4898
4944
|
userId,
|
|
@@ -5135,7 +5181,7 @@ function registerSlackShortcutHandler(params) {
|
|
|
5135
5181
|
messageText: messageBody?.message.text,
|
|
5136
5182
|
responseUrl: messageBody?.response_url
|
|
5137
5183
|
};
|
|
5138
|
-
const route = runtimeContext.resolveSlackSystemEventRoute({
|
|
5184
|
+
const route = await runtimeContext.resolveSlackSystemEventRoute({
|
|
5139
5185
|
channelId,
|
|
5140
5186
|
channelType: auth.channelType,
|
|
5141
5187
|
senderId: userId,
|
|
@@ -5198,7 +5244,7 @@ async function authorizeAndResolveSlackSystemEventContext(params) {
|
|
|
5198
5244
|
channelId,
|
|
5199
5245
|
channelName: auth.channelName
|
|
5200
5246
|
}),
|
|
5201
|
-
route: ctx.resolveSlackSystemEventRoute({
|
|
5247
|
+
route: await ctx.resolveSlackSystemEventRoute({
|
|
5202
5248
|
channelId,
|
|
5203
5249
|
channelType: auth.channelType,
|
|
5204
5250
|
senderId,
|
|
@@ -5245,7 +5291,7 @@ function registerSlackMemberEvents(params) {
|
|
|
5245
5291
|
accountId: runtimeContext.accountId,
|
|
5246
5292
|
conversationId: channelId,
|
|
5247
5293
|
deliverTo: `channel:${channelId}`,
|
|
5248
|
-
route: runtimeContext.resolveSlackSystemEventRoute({
|
|
5294
|
+
route: await runtimeContext.resolveSlackSystemEventRoute({
|
|
5249
5295
|
channelId,
|
|
5250
5296
|
channelType: roomType,
|
|
5251
5297
|
eventScope
|
|
@@ -5800,13 +5846,8 @@ function buildSlackDebounceKey(message, accountId, teamId) {
|
|
|
5800
5846
|
}
|
|
5801
5847
|
//#endregion
|
|
5802
5848
|
//#region extensions/slack/src/monitor/message-handler.ts
|
|
5803
|
-
const loadSlackMessagePipeline = createLazyRuntimeModule(() => import("./pipeline.runtime-
|
|
5849
|
+
const loadSlackMessagePipeline = createLazyRuntimeModule(() => import("./pipeline.runtime-DOf1Ghcz.mjs"));
|
|
5804
5850
|
const RETRYABLE_FLUSH_MAX_ATTEMPTS = 3;
|
|
5805
|
-
const RETRYABLE_FLUSH_RETRY_DELAY_MS = 1e3;
|
|
5806
|
-
const REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE = /reply session initialization conflicted for \S+/u;
|
|
5807
|
-
function isRetryableSlackInboundError(error) {
|
|
5808
|
-
return collectErrorGraphCandidates(error, (current) => [current.cause, current.error]).some((candidate) => candidate instanceof SlackMessageDispatchRetryError || REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE.test(formatErrorMessage(candidate)));
|
|
5809
|
-
}
|
|
5810
5851
|
function shouldDebounceSlackMessage(message, cfg) {
|
|
5811
5852
|
const textForCommandDetection = stripSlackMentionsForCommandDetection(message.text ?? "");
|
|
5812
5853
|
return shouldDebounceTextInbound({
|
|
@@ -5832,7 +5873,7 @@ function createSlackMessageHandler(params) {
|
|
|
5832
5873
|
const completions = entries.map((entry) => entry.opts.dispatchCompletion).filter((completion) => completion !== void 0);
|
|
5833
5874
|
const retry = entries.find((entry) => entry.retry)?.retry;
|
|
5834
5875
|
let admittedContext = retry?.runtimeContext;
|
|
5835
|
-
|
|
5876
|
+
try {
|
|
5836
5877
|
const runtimeContext = admittedContext ??= await ctx.readRuntimeContext();
|
|
5837
5878
|
admissionLifecycle.abortSignal.throwIfAborted();
|
|
5838
5879
|
await (async () => {
|
|
@@ -5994,22 +6035,17 @@ function createSlackMessageHandler(params) {
|
|
|
5994
6035
|
}
|
|
5995
6036
|
})();
|
|
5996
6037
|
for (const completion of completions) completion.resolve();
|
|
5997
|
-
break;
|
|
5998
6038
|
} catch (error) {
|
|
5999
6039
|
const runtimeContext = admittedContext;
|
|
6000
|
-
if (runtimeContext &&
|
|
6001
|
-
await
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
})));
|
|
6010
|
-
return;
|
|
6011
|
-
}
|
|
6012
|
-
continue;
|
|
6040
|
+
if (runtimeContext && (retry?.attempt ?? 0) < RETRYABLE_FLUSH_MAX_ATTEMPTS && error instanceof SlackMessageDispatchRetryError && !entries.some((entry) => entry.opts.eventScope || entry.opts.dispatchCompletion)) {
|
|
6041
|
+
await Promise.all(entries.map((entry) => debouncer.enqueue({
|
|
6042
|
+
...entry,
|
|
6043
|
+
retry: {
|
|
6044
|
+
attempt: (retry?.attempt ?? 0) + 1,
|
|
6045
|
+
runtimeContext
|
|
6046
|
+
}
|
|
6047
|
+
})));
|
|
6048
|
+
return;
|
|
6013
6049
|
}
|
|
6014
6050
|
for (const completion of completions) completion.reject(error);
|
|
6015
6051
|
throw error;
|
|
@@ -6345,7 +6381,7 @@ async function getSlackBoltInterop() {
|
|
|
6345
6381
|
}
|
|
6346
6382
|
return slackBoltInterop;
|
|
6347
6383
|
}
|
|
6348
|
-
const loadSlackRelaySource = createLazyRuntimeModule(() => import("./relay-source-
|
|
6384
|
+
const loadSlackRelaySource = createLazyRuntimeModule(() => import("./relay-source-CUVJNz6R.mjs"));
|
|
6349
6385
|
function resolveSlackRuntimeIdentity(params) {
|
|
6350
6386
|
const botUserId = normalizeOptionalString(params.botUserId);
|
|
6351
6387
|
const botId = normalizeOptionalString(params.botId);
|
|
@@ -6404,7 +6440,7 @@ function resolveSlackRelayConfig(params) {
|
|
|
6404
6440
|
}
|
|
6405
6441
|
async function monitorSlackProvider(opts) {
|
|
6406
6442
|
const { scheduler } = opts;
|
|
6407
|
-
const cfg = opts.config ??
|
|
6443
|
+
const cfg = opts.config ?? await captureRuntimeConfigAsyncReader()();
|
|
6408
6444
|
const runtime = opts.runtime ?? createNonExitingRuntime();
|
|
6409
6445
|
const account = resolveSlackAccount({
|
|
6410
6446
|
cfg,
|
|
@@ -6556,7 +6592,7 @@ async function monitorSlackProvider(opts) {
|
|
|
6556
6592
|
const apiAppId = installationIdentity.kind === "degraded" ? "" : installationIdentity.apiAppId ?? "";
|
|
6557
6593
|
if (authTestError !== void 0) {
|
|
6558
6594
|
const identityFailureDetail = account.identity === "user" ? "explicit self-mention detection will be disabled while the user identity is unresolved" : "explicit bot-mention detection will be disabled while the bot identity is unresolved";
|
|
6559
|
-
runtime.log?.(warn(`[${account.accountId}] slack auth.test failed at boot (${authTestError}); ${identityFailureDetail}; required-mention channels will
|
|
6595
|
+
runtime.log?.(warn(`[${account.accountId}] slack auth.test failed at boot (${authTestError}); ${identityFailureDetail}; required-mention channels will ignore messages without another trusted activation signal`));
|
|
6560
6596
|
}
|
|
6561
6597
|
if (authIdentityWarning) runtime.log?.(warn(authIdentityWarning));
|
|
6562
6598
|
const identityHealth = resolveSlackIdentityHealth({
|