@openclaw/discord 2026.10.5 → 2026.10.10-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/.setup/{approval-handler.runtime-D88-QVlO.mjs → approval-handler.runtime-BvF8oUpa.mjs} +9 -9
  2. package/dist/.setup/{approval-message-updates-CIGByUcE.mjs → approval-message-updates-wbUqLtLI.mjs} +2 -2
  3. package/dist/.setup/{audit-TGIPL0f_.mjs → audit-UwzCdDJk.mjs} +3 -3
  4. package/dist/.setup/{channel-C24afwHP.mjs → channel-BlvyeRAu.mjs} +72 -49
  5. package/dist/.setup/{channel.setup-B3KEh05g.mjs → channel.setup-By7wNopw.mjs} +1 -1
  6. package/dist/.setup/{command-owners-C7rUdqUX.mjs → command-owners-D78sAoOz.mjs} +1 -1
  7. package/dist/.setup/{components-HN9052L1.mjs → components-C_cuoW1q.mjs} +1 -1
  8. package/dist/.setup/conversation-binding-route-fdYsXexV.mjs +68 -0
  9. package/dist/.setup/{discord-BGqgx-yd.mjs → discord-Cl2OPTZ6.mjs} +18 -14
  10. package/dist/.setup/{doctor-9Ka20lDD.mjs → doctor-94GSI6lY.mjs} +2 -2
  11. package/dist/.setup/{handle-action-CsQmpfGZ.mjs → handle-action-0-FZD3Am.mjs} +7 -7
  12. package/dist/.setup/{handle-action.guild-admin-Aw-vutu3.mjs → handle-action.guild-admin-DfAWANBE.mjs} +2 -2
  13. package/dist/.setup/{message-handler-C_BQFYCW.mjs → message-handler-CtR2w7W_.mjs} +4 -4
  14. package/dist/.setup/{message-handler.preflight-C_xFOxPN.mjs → message-handler.preflight-BqUw7LWb.mjs} +11 -10
  15. package/dist/.setup/{message-handler.preflight-pluralkit-CfRsEwg4.mjs → message-handler.preflight-pluralkit-BU9I_X-b.mjs} +4 -6
  16. package/dist/.setup/{message-handler.process-_np9if7z.mjs → message-handler.process-BZeWmSNC.mjs} +40 -50
  17. package/dist/.setup/{outbound-adapter-L3UDoMOG.mjs → outbound-adapter-DBwgKemw.mjs} +5 -5
  18. package/dist/.setup/{outbound-session-route-iwnu6IK8.mjs → outbound-session-route-CsHHPxsQ.mjs} +24 -7
  19. package/dist/.setup/{provider-CbmXLYrW.mjs → provider-DUTsZJHz.mjs} +230 -205
  20. package/dist/.setup/{provider-session.runtime-BMOuDbod.mjs → provider-session.runtime-Ucr3XodI.mjs} +3 -3
  21. package/dist/.setup/provider.runtime-J8NuMCNs.mjs +1 -0
  22. package/dist/.setup/{realtime-session.runtime-YCumnRSE.mjs → realtime-session.runtime-bNnPOKP_.mjs} +161 -150
  23. package/dist/.setup/{receive-recovery-eVmK2_hl.mjs → receive-recovery-CKvaG2Hf.mjs} +4 -25
  24. package/dist/.setup/{runtime-DPm3gZXk.mjs → runtime-Cg5pIBm_.mjs} +1 -1
  25. package/dist/.setup/{runtime-CRTkKU1G.mjs → runtime-DE6W14G3.mjs} +7 -7
  26. package/dist/.setup/{send-DbILKgcm.mjs → send-yR1hfybW.mjs} +26 -12
  27. package/dist/.setup/{send.components-FxOS3CeP.mjs → send.components--dxMjc2O.mjs} +5 -5
  28. package/dist/.setup/{send.outbound-_jx4Xpd3.mjs → send.outbound-B5vQwgUK.mjs} +10 -4
  29. package/dist/.setup/{send.receipt-BAlzXd8e.mjs → send.receipt-eE3zLTDH.mjs} +3 -9
  30. package/dist/.setup/{send.shared-CjQ4jbMA.mjs → send.shared-iGf1rqAm.mjs} +4 -3
  31. package/dist/.setup/setup-plugin-api-DVpA_yqS.mjs +2 -0
  32. package/dist/.setup/{shared-C027f-lL.mjs → shared-DgzLizSt.mjs} +1 -1
  33. package/dist/.setup/{subagent-hooks-CME7dSGf.mjs → subagent-hooks-tBtaqWkD.mjs} +21 -12
  34. package/dist/.setup/{system-events-BwwSDCw4.mjs → system-events-DGsxf-l9.mjs} +1 -1
  35. package/dist/.setup/{target-resolver-Bse8fuTi.mjs → target-resolver-BFOKmBni.mjs} +1 -1
  36. package/dist/.setup/{targets-DZJjkzwv.mjs → targets-UbCpek5o.mjs} +1 -1
  37. package/dist/.setup/{thread-bindings-0hPTSK14.mjs → thread-bindings-Dsc3zsrI.mjs} +29 -7
  38. package/dist/.setup/{thread-bindings.manager-CdNa6UIs.mjs → thread-bindings.manager-BMpmKLQh.mjs} +63 -19
  39. package/dist/.setup/{thread-bindings.session-updates-DGSljVf6.mjs → thread-bindings.session-updates-BMdJeJMc.mjs} +39 -122
  40. package/dist/.setup/{threading-BWz5lW0p.mjs → threading-Cg_QRc8s.mjs} +2 -2
  41. package/dist/.setup/{transcripts-source-EMrQb132.mjs → transcripts-source-fRvFsZng.mjs} +12 -17
  42. package/dist/.setup/{voice-runtime-BFEBhf2B.mjs → voice-runtime-DHDNu0fz.mjs} +73 -120
  43. package/dist/action-runtime-api.js +1 -1
  44. package/dist/activities-api.js +3 -3
  45. package/dist/api.js +11 -11
  46. package/dist/channel-plugin-api.js +1 -1
  47. package/dist/runtime-api.js +15 -15
  48. package/dist/setup-entry.js +1 -1
  49. package/dist/setup-plugin-api.js +1 -1
  50. package/dist/src/voice/audio-worker.runtime.js +8 -11
  51. package/dist/subagent-hooks-api.js +1 -1
  52. package/dist/transcripts-source-api.js +1 -1
  53. package/node_modules/mdast-util-from-markdown/dev/lib/index.js +152 -45
  54. package/node_modules/mdast-util-from-markdown/dev/lib/types.d.ts +26 -0
  55. package/node_modules/mdast-util-from-markdown/lib/index.js +133 -40
  56. package/node_modules/mdast-util-from-markdown/lib/types.d.ts +26 -0
  57. package/node_modules/mdast-util-from-markdown/package.json +6 -7
  58. package/node_modules/mdast-util-from-markdown/readme.md +15 -1
  59. package/node_modules/typebox/build/value/clean/from_object.mjs +1 -1
  60. package/node_modules/typebox/package.json +1 -1
  61. package/package.json +6 -6
  62. package/dist/.setup/conversation-binding-route-r4XyytCE.mjs +0 -51
  63. package/dist/.setup/provider.runtime-1yN_05AK.mjs +0 -1
  64. package/dist/.setup/setup-plugin-api-BFl2FljJ.mjs +0 -2
@@ -1,28 +1,28 @@
1
1
  import { g as resolveDiscordToken, h as normalizeDiscordToken, l as resolveDiscordAccount, m as resolveDiscordMaxLinesPerMessage, p as resolveDiscordAccountDmPolicy, s as mergeDiscordAccountConfig, u as resolveDiscordAccountAllowFrom } from "./accounts-ljrzXBJi.mjs";
2
2
  import { A as isDiscordThreadChannelType, D as getDiscordEndpointRuntime, E as assertDiscordEndpointGatewayUrl, S as formatDiscordUserTag, _ as resolveDiscordOwnerAllowFrom, a as normalizeDiscordDisplaySlug, b as shouldEmitDiscordReactionNotification, c as resolveDiscordChannelConfig, f as resolveDiscordGuildEntry, g as resolveDiscordOwnerAccess, i as normalizeDiscordAllowList, l as resolveDiscordChannelConfigWithFallback, m as resolveDiscordMemberAllowed, n as hasConfiguredDiscordChannels, o as normalizeDiscordSlug, p as resolveDiscordMemberAccessState, r as isDiscordGroupAllowedByPolicy, s as resolveDiscordAllowListMatch, u as resolveDiscordChannelPolicyCommandAuthorizer, w as resolveTimestampMs, x as formatDiscordReactionEmoji, y as resolveGroupDmAllow } from "./allow-list-B_ToXtew.mjs";
3
- import { B as validateDiscordProxyUrl, C as hasAnyChannelPermissionDiscord, G as unregisterGateway, P as createDiscordRestClient, R as DISCORD_REST_TIMEOUT_MS, V as withValidatedDiscordProxy, W as registerGateway, y as canViewDiscordGuildChannel } from "./send.shared-CjQ4jbMA.mjs";
3
+ import { B as validateDiscordProxyUrl, C as hasAnyChannelPermissionDiscord, G as unregisterGateway, P as createDiscordRestClient, R as DISCORD_REST_TIMEOUT_MS, V as withValidatedDiscordProxy, W as registerGateway, y as canViewDiscordGuildChannel } from "./send.shared-iGf1rqAm.mjs";
4
4
  import { i as setPresence, t as clearPresences } from "./presence-cache-DCeTsL73.mjs";
5
- import { $ as BaseMessageInteractiveComponent, A as StringSelectMenu, D as Row, F as Plugin, G as hasDiscordV2Components, J as Command, P as Client, Q as User, R as RateLimitError, X as Guild, Y as CommandWithSubcommands, Z as Message, a as MessageCreateListener, c as PresenceUpdateListener, d as ThreadUpdateListener, h as Modal, i as InteractionCreateListener, j as TextDisplay, k as Separator, l as ReadyListener, n as GuildCreateListener, o as MessageReactionAddListener, r as GuildDeleteListener, s as MessageReactionRemoveListener, t as discord_exports, u as ThreadDeleteListener, x as Container, y as Button } from "./discord-BGqgx-yd.mjs";
6
- import { v as chunkDiscordTextWithMode } from "./send.receipt-BAlzXd8e.mjs";
5
+ import { $ as User, A as StringSelectMenu, D as Row, F as Plugin, K as hasDiscordV2Components, P as Client, Q as Message, R as RateLimitError, X as CommandWithSubcommands, Y as Command, Z as Guild, a as MessageCreateListener, c as PresenceUpdateListener, d as ThreadUpdateListener, et as BaseMessageInteractiveComponent, h as Modal, i as InteractionCreateListener, j as TextDisplay, k as Separator, l as ReadyListener, n as GuildCreateListener, o as MessageReactionAddListener, r as GuildDeleteListener, s as MessageReactionRemoveListener, t as discord_exports, u as ThreadDeleteListener, x as Container, y as Button } from "./discord-Cl2OPTZ6.mjs";
6
+ import { v as chunkDiscordTextWithMode } from "./send.receipt-eE3zLTDH.mjs";
7
7
  import { a as isDiscordRateLimitResponseBody, s as summarizeDiscordResponseBody } from "./api-CtmE1OUN.mjs";
8
- import { _ as readMessagesDiscord, s as sendVoiceMessageDiscord } from "./send-DbILKgcm.mjs";
9
- import { o as formatMention, t as sendMessageDiscord } from "./send.outbound-_jx4Xpd3.mjs";
8
+ import { _ as readMessagesDiscord, s as sendVoiceMessageDiscord } from "./send-yR1hfybW.mjs";
9
+ import { s as formatMention, t as sendMessageDiscord } from "./send.outbound-B5vQwgUK.mjs";
10
10
  import { l as withAbortTimeout } from "./timeouts-CuNARfyw.mjs";
11
- import { C as parseDiscordActivityCustomIdForInteraction, D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, O as decodeCustomIdComponent, T as parseDiscordComponentCustomIdForInteraction, c as parseExecApprovalData, d as buildDiscordComponentMessage, k as encodeCustomIdComponent, o as parseDiscordQuestionData, w as parseDiscordComponentCustomId, y as buildDiscordActivityCustomId } from "./components-HN9052L1.mjs";
12
- import { a as registerDiscordComponentEntries, o as resolveDiscordComponentEntryWithPersistence, s as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components-FxOS3CeP.mjs";
11
+ import { C as parseDiscordActivityCustomIdForInteraction, D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, O as decodeCustomIdComponent, T as parseDiscordComponentCustomIdForInteraction, c as parseExecApprovalData, d as buildDiscordComponentMessage, k as encodeCustomIdComponent, o as parseDiscordQuestionData, w as parseDiscordComponentCustomId, y as buildDiscordActivityCustomId } from "./components-C_cuoW1q.mjs";
12
+ import { a as registerDiscordComponentEntries, o as resolveDiscordComponentEntryWithPersistence, s as resolveDiscordModalEntryWithPersistence, t as editDiscordComponentMessage } from "./send.components--dxMjc2O.mjs";
13
13
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.mjs";
14
- import { n as getDiscordActivitiesRuntime } from "./runtime-DPm3gZXk.mjs";
15
- import { t as resolveDiscordCommandOwnerAllowFrom } from "./command-owners-C7rUdqUX.mjs";
16
- import { D as isDiscordExecApprovalClientEnabled, T as getDiscordExecApprovalApprovers, a as resolveDiscordComponentSpec, c as formatDiscordApprovalDisplayValue, d as resolveDiscordBoundConversationRoute, h as resolveDiscordConversationIdentity, l as buildDiscordConversationRouteContext, n as DISCORD_PRESENTATION_CAPABILITIES, p as resolveDiscordEffectiveRoute, r as buildDiscordPresentationPayload, s as DISCORD_APPROVAL_ALLOWED_MENTIONS, u as buildDiscordRoutePeer } from "./outbound-session-route-iwnu6IK8.mjs";
14
+ import { n as getDiscordActivitiesRuntime } from "./runtime-Cg5pIBm_.mjs";
15
+ import { t as resolveDiscordCommandOwnerAllowFrom } from "./command-owners-D78sAoOz.mjs";
16
+ import { A as isDiscordExecApprovalClientEnabled, O as getDiscordExecApprovalApprovers, a as resolveDiscordComponentSpec, c as formatDiscordApprovalDisplayValue, d as setDiscordChannelPolicyBindings, f as buildDiscordConversationRouteContext, g as resolveDiscordEffectiveRoute, m as resolveDiscordBoundConversationRoute, n as DISCORD_PRESENTATION_CAPABILITIES, p as buildDiscordRoutePeer, r as buildDiscordPresentationPayload, s as DISCORD_APPROVAL_ALLOWED_MENTIONS, v as resolveDiscordConversationIdentity } from "./outbound-session-route-CsHHPxsQ.mjs";
17
17
  import { n as discordIngressIdentity, t as selectDiscordLivePolicyConfig } from "./live-policy-config-BPoB3eQi.mjs";
18
18
  import { t as resolveDiscordChannelAllowlist } from "./resolve-channels-UdT38DzU.mjs";
19
19
  import { t as resolveDiscordUserAllowlist } from "./resolve-users-DnCsrXZ_.mjs";
20
- import { a as isThreadArchived, n as getThreadBindingManager } from "./thread-bindings.manager-CdNa6UIs.mjs";
20
+ import { a as isThreadArchived, n as getThreadBindingManager } from "./thread-bindings.manager-BMpmKLQh.mjs";
21
21
  import { n as resolveDiscordChannelInfoSafe, o as resolveDiscordChannelTopicSafe, r as resolveDiscordChannelNameSafe } from "./channel-access-DasWY_OV.mjs";
22
22
  import { a as probeDiscordApplicationId, r as parseApplicationIdFromToken } from "./probe-D3P1x4aN.mjs";
23
- import { O as resolveDiscordReferencedReplyMessage, a as authorizeDiscordVoiceIngress, c as resolveDiscordVoiceEnabled, i as setDiscordTranscriptsVoiceManager, k as resolveDiscordReferencedReplyMessageId, l as resolveDiscordThreadLikeChannelContext, o as resolveDiscordVoiceAccess, u as resolveFetchedDiscordThreadLikeChannelContext } from "./transcripts-source-EMrQb132.mjs";
23
+ import { O as resolveDiscordReferencedReplyMessage, a as authorizeDiscordVoiceIngress, c as resolveDiscordVoiceEnabled, i as setDiscordTranscriptsVoiceManager, k as resolveDiscordReferencedReplyMessageId, l as resolveDiscordThreadLikeChannelContext, o as resolveDiscordVoiceAccess, u as resolveFetchedDiscordThreadLikeChannelContext } from "./transcripts-source-fRvFsZng.mjs";
24
24
  import { t as resolveDiscordSenderIdentity } from "./sender-identity-BNBvGt1l.mjs";
25
- import { n as hasDiscordApprovalControl, t as discordApprovalMessageUpdates } from "./approval-message-updates-CIGByUcE.mjs";
25
+ import { n as hasDiscordApprovalControl, t as discordApprovalMessageUpdates } from "./approval-message-updates-wbUqLtLI.mjs";
26
26
  import { createRequire } from "node:module";
27
27
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
28
28
  import { PlatformMessageNotDispatchedError, formatErrorMessage, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
@@ -30,7 +30,7 @@ import { createNonExitingRuntime, createSubsystemLogger, danger, formatDurationS
30
30
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
31
31
  import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
32
32
  import { asFiniteNumber, asOptionalRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, normalizeStringEntries, parseFiniteNumber, parseStrictNonNegativeInteger, readNonBlankString, summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
33
- import { createRuntimeConfigReader, getRuntimeConfig, getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
33
+ import { captureRuntimeConfigAsyncReader, createRuntimeConfigReader, getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
34
34
  import { ApplicationCommandOptionType, ButtonStyle, ChannelType, ComponentType, GatewayCloseCodes, GatewayCloseCodes as GatewayCloseCodes$1, GatewayDispatchEvents, GatewayIntentBits, GatewayOpcodes, PermissionFlagsBits } from "discord-api-types/v10";
35
35
  import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
36
36
  import { getAgentScopedMediaLocalRoots } from "openclaw/plugin-sdk/media-runtime";
@@ -39,8 +39,7 @@ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
39
39
  import { MAX_DATE_TIMESTAMP_MS, MAX_TIMER_TIMEOUT_MS, asDateTimestampMs, asSafeIntegerInRange, parseStrictInteger, parseStrictPositiveInteger, resolveDateTimestampMs, resolvePromptHistoryLimit, resolveTimestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
40
40
  import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
41
41
  import { chunkItems, findCodeRegions, sanitizeAssistantVisibleText, sanitizeAssistantVisibleTextWithProfile } from "openclaw/plugin-sdk/text-chunking";
42
- import * as fetchRuntimeSdk from "openclaw/plugin-sdk/fetch-runtime";
43
- import { createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAgent, resolveEnvHttpProxyAgentOptions, wrapFetchWithAbortSignal } from "openclaw/plugin-sdk/fetch-runtime";
42
+ import { createHttp1Agent, createHttp1EnvHttpProxyAgent, createHttp1ProxyAgent, createNodeProxyAgent, resolveEnvHttpProxyAgentOptions, wrapFetchWithAbortSignal } from "openclaw/plugin-sdk/fetch-runtime";
44
43
  import { Type } from "typebox";
45
44
  import { Check, Errors } from "typebox/value";
46
45
  import { createHash, randomUUID } from "node:crypto";
@@ -68,20 +67,20 @@ import { isDangerousNameMatchingEnabled } from "openclaw/plugin-sdk/dangerous-na
68
67
  import { resolveNativeCommandsEnabled, resolveNativeSkillsEnabled } from "openclaw/plugin-sdk/native-command-config-runtime";
69
68
  import { requestHeartbeat } from "openclaw/plugin-sdk/heartbeat-runtime";
70
69
  import { enqueueRoutedSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
71
- import { clearExpiredCooldowns, ensureAuthProfileStore, formatReasoningMessage, getPreparedModelCatalogSnapshot, isProfileInCooldown, listAgentIds, loadPreparedModelCatalog, resolveAgentAvatar, resolveAgentDir, resolveDefaultModelForAgent, resolveHumanDelayConfig, resolveProfilesUnavailableReason } from "openclaw/plugin-sdk/agent-runtime";
72
- import { deleteSessionEntry, getSessionEntry, listSessionEntries, readSessionUpdatedAtAsync, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
70
+ import { clearExpiredCooldowns, ensureAuthProfileStoreAsync, formatReasoningMessage, getPreparedModelCatalogSnapshot, isProfileInCooldown, listAgentIds, loadPreparedModelCatalog, resolveAgentAvatar, resolveAgentDir, resolveDefaultModelForAgent, resolveHumanDelayConfig, resolveProfilesUnavailableReason } from "openclaw/plugin-sdk/agent-runtime";
71
+ import { deleteSessionEntry, getSessionEntryAsync, listSessionEntriesAsync, readSessionUpdatedAtAsync, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
73
72
  import { buildChannelInboundEventContext, createChannelPartialDeliveryError, createCommandTurnContext, dispatchChannelInboundTurn, formatInboundEnvelope, hasVisibleInboundReplyDispatch, isChannelPartialDeliveryError, resolveEnvelopeFormatOptions, resolveInboundSupplementalSenderAllowed, runChannelInboundEvent } from "openclaw/plugin-sdk/channel-inbound";
74
- import * as proxyCaptureSdk from "openclaw/plugin-sdk/proxy-capture";
75
- import { resolveDebugProxySettings, resolveEffectiveDebugProxyUrl } from "openclaw/plugin-sdk/proxy-capture";
73
+ import { captureHttpExchangeAsync, captureWsEventAsync, resolveDebugProxySettings, resolveEffectiveDebugProxyUrl } from "openclaw/plugin-sdk/proxy-capture";
76
74
  import { resolveRequestUrl } from "openclaw/plugin-sdk/request-url";
77
75
  import { fetchWithRuntimeDispatcher } from "openclaw/plugin-sdk/runtime-fetch";
78
76
  import * as dns from "node:dns";
79
77
  import { resolveDirectStatusReplyForSession } from "openclaw/plugin-sdk/command-status-runtime";
80
- import { buildCommandTextFromArgs, findCommandByNativeName, mergeNativeCommandSpecs, parseCommandArgs, resolveCommandArgChoices, resolveCommandArgMenu, serializeCommandArgs } from "openclaw/plugin-sdk/native-command-registry";
78
+ import { buildCommandTextFromArgs, findCommandByNativeName, mergeNativeCommandSpecs, parseCommandArgs, resolveCommandArgChoices, resolveCommandArgMenuAsync, serializeCommandArgs } from "openclaw/plugin-sdk/native-command-registry";
79
+ import { recordDeliveredCommandExchange } from "openclaw/plugin-sdk/session-transcript-runtime";
81
80
  import { PLUGIN_COMMAND_DISPATCH } from "openclaw/plugin-sdk/plugin-command-runtime";
82
- import { buildCommandTextFromArgs as buildCommandTextFromArgs$1, findCommandByNativeName as findCommandByNativeName$1, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, listSkillCommandsForAgents, resolveCommandAuthorization, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverride, serializeCommandArgs as serializeCommandArgs$1 } from "openclaw/plugin-sdk/command-auth-native";
81
+ import { buildCommandTextFromArgs as buildCommandTextFromArgs$1, findCommandByNativeName as findCommandByNativeName$1, formatCommandArgMenuTitle, listChatCommands, listNativeCommandSpecsForConfig, prepareSkillCommandsForAgents, resolveCommandAuthorization, resolveCommandAuthorizationAsync, resolveCommandAuthorizedFromAuthorizers, resolveEffectiveAgentRuntime, resolveNativeCommandSessionTargets, resolveStoredModelOverrideAsync, serializeCommandArgs as serializeCommandArgs$1 } from "openclaw/plugin-sdk/command-auth-native";
82
+ import { MODEL_PICKER_CHANGED_MESSAGE, getModelsRuntimeChoices } from "openclaw/plugin-sdk/models-provider-runtime";
83
83
  import { normalizeProviderId } from "openclaw/plugin-sdk/model-ref-parse";
84
- import * as modelsProviderRuntime from "openclaw/plugin-sdk/models-provider-runtime";
85
84
  import { normalizeProviderId as normalizeProviderId$1 } from "openclaw/plugin-sdk/provider-model-shared";
86
85
  import { EventEmitter } from "node:events";
87
86
  import { channelReadyPatch, createTransportActivityStatusPatch } from "openclaw/plugin-sdk/gateway-runtime";
@@ -324,10 +323,9 @@ async function closeDiscordThreadSessions(params) {
324
323
  let resetCount = 0;
325
324
  for (const agentId of listAgentIds(cfg)) {
326
325
  const storePath = resolveStorePath(cfg.session?.store, { agentId });
327
- for (const { sessionKey, entry } of listSessionEntries({
326
+ for (const { sessionKey, entry } of await listSessionEntriesAsync({
328
327
  agentId,
329
- storePath,
330
- readOnly: true
328
+ storePath
331
329
  })) {
332
330
  if (!segmentRe.test(sessionKey)) continue;
333
331
  if (await deleteSessionEntry({
@@ -1273,6 +1271,11 @@ async function resolveGuildEntriesByChannelAllowlist(params) {
1273
1271
  unresolved.push(formatDiscordChannelUnresolved(entry));
1274
1272
  continue;
1275
1273
  }
1274
+ if (source.channelKey && entry.channelId && source.channelKey !== entry.channelId) params.channelPolicyBindings.push({
1275
+ guildKey: source.guildKey,
1276
+ channelKey: source.channelKey,
1277
+ channelId: entry.channelId
1278
+ });
1276
1279
  const target = entry.channelId ? `${entry.guildId}/${entry.channelId}` : entry.guildId;
1277
1280
  const existingGroup = mappingByTarget.get(target) ?? {
1278
1281
  target,
@@ -1349,10 +1352,13 @@ function collectGuildUserEntries(guildEntries) {
1349
1352
  async function resolveDiscordAllowlistConfig(params) {
1350
1353
  let guildEntries = toGuildEntries(params.guildEntries);
1351
1354
  let allowFrom = toAllowlistEntries(params.allowFrom);
1355
+ const channelPolicyBindings = [];
1352
1356
  if (hasGuildEntries(guildEntries)) guildEntries = await resolveGuildEntriesByChannelAllowlist({
1353
1357
  ...params,
1354
- guildEntries
1358
+ guildEntries,
1359
+ channelPolicyBindings
1355
1360
  });
1361
+ setDiscordChannelPolicyBindings(params.accountId, channelPolicyBindings);
1356
1362
  if (isDangerousNameMatchingEnabled(params.discordConfig)) {
1357
1363
  allowFrom = await resolveUserAllowlist(params, allowFrom, (allowFrom ?? []).filter((entry) => entry !== "*"), "user", (existing, resolvedMap) => canonicalizeAllowlistWithResolvedIds({
1358
1364
  existing,
@@ -1439,8 +1445,6 @@ function createDiscordEndpointDnsLookup(endpointHostname) {
1439
1445
  }
1440
1446
  //#endregion
1441
1447
  //#region extensions/discord/src/monitor/rest-fetch.ts
1442
- const captureSdk$2 = proxyCaptureSdk;
1443
- const fetchSdk = fetchRuntimeSdk;
1444
1448
  const discordDnsLookup$1 = createDiscordDnsLookup();
1445
1449
  function createEnvProxyDiscordRestDispatcher(runtime) {
1446
1450
  const envProxyOptions = resolveEnvHttpProxyAgentOptions();
@@ -1460,7 +1464,7 @@ function createDiscordRestFetchWithDispatcher(dispatcher) {
1460
1464
  ...init,
1461
1465
  dispatcher
1462
1466
  }).then((response) => {
1463
- captureSdk$2.captureHttpExchangeAsync?.({
1467
+ captureHttpExchangeAsync({
1464
1468
  url: resolveRequestUrl(input),
1465
1469
  method: init?.method ?? "GET",
1466
1470
  requestHeaders: init?.headers,
@@ -1480,12 +1484,7 @@ function resolveDiscordRestFetch(proxyUrl, runtime) {
1480
1484
  runtime.log?.("discord: rest proxy enabled");
1481
1485
  return fetcher;
1482
1486
  }
1483
- return createDiscordRestFetchWithDispatcher(createEnvProxyDiscordRestDispatcher(runtime) ?? fetchSdk.createHttp1Agent?.({ connect: { lookup: discordDnsLookup$1 } }) ?? createHttp1EnvHttpProxyAgent({
1484
- httpProxy: "",
1485
- httpsProxy: "",
1486
- noProxy: "*",
1487
- connect: { lookup: discordDnsLookup$1 }
1488
- }));
1487
+ return createDiscordRestFetchWithDispatcher(createEnvProxyDiscordRestDispatcher(runtime) ?? createHttp1Agent({ connect: { lookup: discordDnsLookup$1 } }));
1489
1488
  }
1490
1489
  //#endregion
1491
1490
  //#region extensions/discord/src/monitor/live-policy.ts
@@ -1539,6 +1538,7 @@ function createDiscordLivePolicyReader(params) {
1539
1538
  if (!resolution || key !== resolutionKey) {
1540
1539
  resolutionKey = key;
1541
1540
  resolution = resolveDiscordAllowlistConfig({
1541
+ accountId: params.accountId,
1542
1542
  token,
1543
1543
  guildEntries: discordConfig.guilds,
1544
1544
  allowFrom,
@@ -1630,6 +1630,18 @@ async function readDiscordInteractionPolicy(readPolicy) {
1630
1630
  //#endregion
1631
1631
  //#region extensions/discord/src/monitor/native-command-reply.ts
1632
1632
  const DISCORD_EMPTY_VISIBLE_REPLY_WARNING = "⚠️ Command produced no visible reply.";
1633
+ /** Retain visible component text, not interaction IDs or option values. */
1634
+ function formatDiscordCommandComponents(components) {
1635
+ const text = [];
1636
+ const visit = (value) => {
1637
+ if (!value || typeof value !== "object") return;
1638
+ for (const [key, field] of Object.entries(value)) if ((key === "content" || key === "label" || key === "description" || key === "placeholder") && typeof field === "string") text.push(field);
1639
+ else if ((key === "components" || key === "options") && Array.isArray(field)) field.forEach(visit);
1640
+ else if (key === "accessory") visit(field);
1641
+ };
1642
+ components.forEach((component) => visit("serialize" in component ? component.serialize() : component));
1643
+ return text.join("\n");
1644
+ }
1633
1645
  function resolveDiscordInteractionReplyOptions(params) {
1634
1646
  return {
1635
1647
  textLimit: resolveTextChunkLimit(params.cfg, "discord", params.accountId, { fallbackLimit: 2e3 }),
@@ -1692,6 +1704,7 @@ async function deliverDiscordInteractionReply(params) {
1692
1704
  const firstMessageEmbeds = messageParts.embeds;
1693
1705
  const hasFirstMessageParts = Boolean(firstMessageComponents || firstMessageEmbeds);
1694
1706
  let payloadDelivered = false;
1707
+ const deliveredText = params.onDelivered ? [] : void 0;
1695
1708
  const sendMessage = async (content, files) => {
1696
1709
  const firstMessage = !payloadDelivered;
1697
1710
  const components = firstMessage ? firstMessageComponents : void 0;
@@ -1717,6 +1730,17 @@ async function deliverDiscordInteractionReply(params) {
1717
1730
  });
1718
1731
  }
1719
1732
  }) === null) throw new PlatformMessageNotDispatchedError("Discord interaction expired before message dispatch", { cause: /* @__PURE__ */ new Error("Unknown interaction") });
1733
+ if (deliveredText) {
1734
+ if (payloadLocal.content) deliveredText.push(payloadLocal.content);
1735
+ if (payloadLocal.components) deliveredText.push(formatDiscordCommandComponents(payloadLocal.components));
1736
+ for (const embed of payloadLocal.embeds ?? []) deliveredText.push([
1737
+ embed.title,
1738
+ embed.description,
1739
+ embed.author?.name,
1740
+ ...(embed.fields ?? []).flatMap((field) => [field.name, field.value]),
1741
+ embed.footer?.text
1742
+ ].filter(Boolean).join("\n"));
1743
+ }
1720
1744
  } catch (error) {
1721
1745
  if (!payloadDelivered) throw error;
1722
1746
  throw createChannelPartialDeliveryError(error, { visibleReplySent: true });
@@ -1742,6 +1766,7 @@ async function deliverDiscordInteractionReply(params) {
1742
1766
  if (!chunk.trim() && !chunkFiles && (payloadDelivered || !hasFirstMessageParts)) continue;
1743
1767
  await sendMessage(chunk, chunkFiles);
1744
1768
  }
1769
+ if (payloadDelivered && params.onDelivered) await params.onDelivered(deliveredText?.filter(Boolean).join("\n") ?? "");
1745
1770
  return payloadDelivered;
1746
1771
  }
1747
1772
  //#endregion
@@ -2178,8 +2203,8 @@ function resolveDiscordNativePolicyReader(params) {
2178
2203
  }
2179
2204
  });
2180
2205
  }
2181
- function createDiscordNativeCommandAuthority(params) {
2182
- const assertAdmittedOwner = resolveCommandAuthorization(params).assertOwnerCurrent;
2206
+ async function createDiscordNativeCommandAuthority(params) {
2207
+ const assertAdmittedOwner = (await resolveCommandAuthorizationAsync(params)).assertOwnerCurrent;
2183
2208
  const readAuthorization = () => {
2184
2209
  const cfg = getRuntimeConfigSnapshot() ?? params.cfg;
2185
2210
  const owners = resolveDiscordCommandOwnerAllowFrom(cfg);
@@ -2445,11 +2470,11 @@ async function resolveDiscordNativeAutocompleteAuthorized(params) {
2445
2470
  prompt: "",
2446
2471
  commandArgs: {}
2447
2472
  });
2448
- if (!resolveCommandAuthorization({
2473
+ if (!(await resolveCommandAuthorizationAsync({
2449
2474
  ctx: ctxPayload,
2450
2475
  cfg,
2451
2476
  commandAuthorized: true
2452
- }).senderIsOwner) return false;
2477
+ })).senderIsOwner) return false;
2453
2478
  }
2454
2479
  return params.isPolicyCurrent?.() !== false;
2455
2480
  }
@@ -2589,16 +2614,6 @@ async function recordDiscordModelPickerRecentModel(params) {
2589
2614
  } catch {}
2590
2615
  }
2591
2616
  //#endregion
2592
- //#region extensions/discord/src/monitor/model-picker.runtime.ts
2593
- const hostSdk = modelsProviderRuntime;
2594
- const MODEL_PICKER_CHANGED_MESSAGE = hostSdk.MODEL_PICKER_CHANGED_MESSAGE ?? "Available models changed. Open /models and choose again.";
2595
- function supportsDiscordModelPickerRuntimeChoices() {
2596
- return hostSdk.getModelsRuntimeChoices !== void 0;
2597
- }
2598
- function getDiscordModelPickerRuntimeChoices(...args) {
2599
- return hostSdk.getModelsRuntimeChoices?.(...args);
2600
- }
2601
- //#endregion
2602
2617
  //#region extensions/discord/src/monitor/model-picker.state.ts
2603
2618
  const DISCORD_MODEL_PICKER_CUSTOM_ID_KEY = "mdlpk";
2604
2619
  const DISCORD_CUSTOM_ID_MAX_CHARS = 100;
@@ -2991,12 +3006,12 @@ function buildModelRows(params) {
2991
3006
  providerBucket: activeProviderBucket
2992
3007
  }));
2993
3008
  const runtimeModel = parseCurrentModelRef(params.pendingModel ?? params.currentModel);
2994
- const runtimeChoices = getDiscordModelPickerRuntimeChoices(params.data, params.modelPage.provider, runtimeModel?.provider === normalizeProviderId$1(params.modelPage.provider) ? runtimeModel.model : void 0);
3009
+ const runtimeChoices = getModelsRuntimeChoices(params.data, params.modelPage.provider, runtimeModel?.provider === normalizeProviderId$1(params.modelPage.provider) ? runtimeModel.model : void 0);
2995
3010
  const currentRuntime = parsedCurrentModel?.provider === params.modelPage.provider ? params.currentRuntime : void 0;
2996
3011
  const runtime = params.pendingRuntime?.trim() || currentRuntime?.trim();
2997
3012
  const explicitRuntime = runtime && runtime !== "auto" && runtime !== "default" ? runtime : void 0;
2998
3013
  const selectedRuntime = explicitRuntime ? runtimeChoices?.find((choice) => choice.id === explicitRuntime)?.id : runtimeChoices?.[0]?.id;
2999
- const compactRuntime = supportsDiscordModelPickerRuntimeChoices() && explicitRuntime ? { runtimeToken: createDiscordModelPickerRuntimeToken(explicitRuntime) } : {};
3014
+ const compactRuntime = explicitRuntime ? { runtimeToken: createDiscordModelPickerRuntimeToken(explicitRuntime) } : {};
3000
3015
  const modelViewState = {
3001
3016
  command: params.command,
3002
3017
  userId: params.userId,
@@ -3075,7 +3090,7 @@ function buildModelRows(params) {
3075
3090
  modelToken: pendingModelToken
3076
3091
  }, {
3077
3092
  style: ButtonStyle.Primary,
3078
- disabled: !hasPendingSelection || supportsDiscordModelPickerRuntimeChoices() && selectedRuntime === void 0
3093
+ disabled: !hasPendingSelection || selectedRuntime === void 0
3079
3094
  }));
3080
3095
  return {
3081
3096
  rows,
@@ -3173,7 +3188,7 @@ function renderDiscordModelPickerModelsView(params) {
3173
3188
  });
3174
3189
  const defaultModel = `${params.data.resolvedDefault.provider}/${params.data.resolvedDefault.model}`;
3175
3190
  const selectedRuntimeLabel = choices?.find((choice) => choice.id === selectedRuntime)?.label;
3176
- const pendingLine = !params.pendingModel ? "Select a model, then press Submit." : !supportsDiscordModelPickerRuntimeChoices() ? `Selected: ${params.pendingModel} (press Submit)` : choices === void 0 ? "Could not confirm how to run this model. Open /models to try again." : choices.length === 0 ? "This model cannot run with your current connections. Choose another model." : selectedRuntimeLabel ? `Selected: ${params.pendingModel} · ${selectedRuntimeLabel} (press Submit)` : "Choose how to run this model, then press Submit.";
3191
+ const pendingLine = !params.pendingModel ? "Select a model, then press Submit." : choices === void 0 ? "Could not confirm how to run this model. Open /models to try again." : choices.length === 0 ? "This model cannot run with your current connections. Choose another model." : selectedRuntimeLabel ? `Selected: ${params.pendingModel} · ${selectedRuntimeLabel} (press Submit)` : "Choose how to run this model, then press Submit.";
3177
3192
  const detailLines = [formatCurrentModelLine(params.currentModel), `Default: ${defaultModel}`];
3178
3193
  if (modelPage.totalPages > 1) detailLines.push(`${modelPage.provider}: page ${modelPage.page}/${modelPage.totalPages} · ${modelPage.totalItems} models`);
3179
3194
  return buildRenderedShell({
@@ -3250,8 +3265,7 @@ async function applyDiscordModelPickerSelection(params) {
3250
3265
  if (params.settleMs > 0) await new Promise((resolve) => {
3251
3266
  setTimeout(resolve, params.settleMs);
3252
3267
  });
3253
- const effectiveModelRef = params.resolveCurrentModel(effectiveRoute);
3254
- const effectiveRuntime = params.resolveCurrentRuntime(effectiveRoute);
3268
+ const { modelRef: effectiveModelRef, runtime: effectiveRuntime } = await params.resolveCurrentSelection(effectiveRoute);
3255
3269
  const currentSelection = `Current selection: ${effectiveModelRef} with runtime ${effectiveRuntime}.`;
3256
3270
  if (hiddenFinalReply?.isError) return {
3257
3271
  status: "rejected",
@@ -3285,7 +3299,8 @@ async function applyDiscordModelPickerSelection(params) {
3285
3299
  //#region extensions/discord/src/monitor/native-command-model-picker-ui.ts
3286
3300
  function createDiscordModelPickerSessionReader(params, readConsistency) {
3287
3301
  const storePath = resolveStorePath(params.cfg.session?.store, { agentId: params.route.agentId });
3288
- return (sessionKey = params.route.sessionKey) => getSessionEntry({
3302
+ return (sessionKey = params.route.sessionKey) => getSessionEntryAsync({
3303
+ agentId: params.route.agentId,
3289
3304
  storePath,
3290
3305
  sessionKey,
3291
3306
  ...readConsistency ? { readConsistency } : {}
@@ -3340,8 +3355,8 @@ async function resolveDiscordNativeChoiceContext(params) {
3340
3355
  ...params,
3341
3356
  route
3342
3357
  });
3343
- const sessionEntry = loadSessionEntry();
3344
- const override = resolveStoredModelOverride({
3358
+ const sessionEntry = await loadSessionEntry();
3359
+ const override = await resolveStoredModelOverrideAsync({
3345
3360
  sessionEntry,
3346
3361
  loadSessionEntry,
3347
3362
  sessionKey: route.sessionKey,
@@ -3366,12 +3381,12 @@ async function resolveDiscordNativeChoiceContext(params) {
3366
3381
  return null;
3367
3382
  }
3368
3383
  }
3369
- function resolveDiscordModelPickerCurrentModel(params) {
3384
+ async function resolveDiscordModelPickerCurrentModel(params) {
3370
3385
  const fallback = `${params.data.resolvedDefault.provider}/${params.data.resolvedDefault.model}`;
3371
3386
  try {
3372
3387
  const loadSessionEntry = createDiscordModelPickerSessionReader(params, "latest");
3373
- const override = resolveStoredModelOverride({
3374
- sessionEntry: loadSessionEntry(),
3388
+ const override = await resolveStoredModelOverrideAsync({
3389
+ sessionEntry: params.sessionEntry,
3375
3390
  loadSessionEntry,
3376
3391
  sessionKey: params.route.sessionKey,
3377
3392
  defaultProvider: params.data.resolvedDefault.provider
@@ -3385,15 +3400,11 @@ function resolveDiscordModelPickerCurrentModel(params) {
3385
3400
  }
3386
3401
  }
3387
3402
  function resolveDiscordModelPickerCurrentRuntime(params) {
3388
- try {
3389
- const sessionRuntime = normalizeOptionalString(createDiscordModelPickerSessionReader(params, "latest")()?.agentRuntimeOverride);
3390
- if (sessionRuntime) return sessionRuntime;
3391
- } catch {}
3392
- return "auto";
3403
+ return normalizeOptionalString(params.sessionEntry?.agentRuntimeOverride) ?? "auto";
3393
3404
  }
3394
3405
  async function replyWithDiscordModelPickerProviders(params) {
3395
3406
  const route = await resolveDiscordModelPickerRoute(params);
3396
- const sessionEntry = createDiscordModelPickerSessionReader({
3407
+ const sessionEntry = await createDiscordModelPickerSessionReader({
3397
3408
  ...params,
3398
3409
  route
3399
3410
  }, "latest")();
@@ -3401,9 +3412,10 @@ async function replyWithDiscordModelPickerProviders(params) {
3401
3412
  const modelContext = {
3402
3413
  cfg: params.cfg,
3403
3414
  route,
3404
- data
3415
+ data,
3416
+ sessionEntry
3405
3417
  };
3406
- const currentModel = resolveDiscordModelPickerCurrentModel(modelContext);
3418
+ const currentModel = await resolveDiscordModelPickerCurrentModel(modelContext);
3407
3419
  const currentRuntime = resolveDiscordModelPickerCurrentRuntime(modelContext);
3408
3420
  const quickModels = await readDiscordModelPickerRecentModels({
3409
3421
  scope: resolveDiscordModelPickerPreferenceScope(params),
@@ -3418,24 +3430,34 @@ async function replyWithDiscordModelPickerProviders(params) {
3418
3430
  model: parsedCurrentRef.model
3419
3431
  }) : { page: 1 };
3420
3432
  const initialProviderLocation = findProviderBucketLocation(data, initialProvider);
3433
+ const rendered = renderDiscordModelPickerModelsView({
3434
+ command: params.command,
3435
+ userId: params.userId,
3436
+ data,
3437
+ provider: initialProvider,
3438
+ page: initialResolved.page,
3439
+ providerPage: initialProviderLocation?.page ?? 1,
3440
+ providerBucket: initialProviderLocation?.bucket,
3441
+ modelBucket: initialResolved.bucket,
3442
+ currentModel,
3443
+ currentRuntime,
3444
+ quickModels
3445
+ });
3421
3446
  const payload = {
3422
- ...renderDiscordModelPickerModelsView({
3423
- command: params.command,
3424
- userId: params.userId,
3425
- data,
3426
- provider: initialProvider,
3427
- page: initialResolved.page,
3428
- providerPage: initialProviderLocation?.page ?? 1,
3429
- providerBucket: initialProviderLocation?.bucket,
3430
- modelBucket: initialResolved.bucket,
3431
- currentModel,
3432
- currentRuntime,
3433
- quickModels
3434
- }),
3447
+ ...rendered,
3435
3448
  ephemeral: true
3436
3449
  };
3437
- await params.safeInteractionCall("model picker reply", async () => {
3450
+ if (await params.safeInteractionCall("model picker reply", async () => {
3438
3451
  await params.interaction[params.preferFollowUp ? "followUp" : "reply"](payload);
3452
+ }) !== null) await recordDeliveredCommandExchange({
3453
+ config: params.cfg,
3454
+ agentId: route.agentId,
3455
+ sessionKey: route.sessionKey,
3456
+ expectedSessionId: sessionEntry?.sessionId,
3457
+ commandText: `/${params.command}`,
3458
+ commandId: `discord:${params.accountId}:${route.sessionKey}:${params.interaction.id}`,
3459
+ replyId: "model-picker",
3460
+ replyText: formatDiscordCommandComponents(rendered.components)
3439
3461
  });
3440
3462
  }
3441
3463
  //#endregion
@@ -3523,7 +3545,7 @@ async function handleDiscordModelPickerInteraction(params) {
3523
3545
  accountId: ctx.accountId,
3524
3546
  threadBindings: ctx.threadBindings
3525
3547
  });
3526
- const sessionEntry = createDiscordModelPickerSessionReader({
3548
+ const sessionEntry = await createDiscordModelPickerSessionReader({
3527
3549
  cfg,
3528
3550
  route
3529
3551
  }, "latest")();
@@ -3533,12 +3555,13 @@ async function handleDiscordModelPickerInteraction(params) {
3533
3555
  const modelContext = {
3534
3556
  cfg,
3535
3557
  route,
3536
- data: pickerData
3558
+ data: pickerData,
3559
+ sessionEntry
3537
3560
  };
3538
- const currentModelRef = resolveDiscordModelPickerCurrentModel(modelContext);
3561
+ const currentModelRef = await resolveDiscordModelPickerCurrentModel(modelContext);
3539
3562
  const currentModel = splitDiscordModelRef(currentModelRef);
3540
3563
  const browseProvider = parsedProvider ?? currentModel?.provider ?? pickerData.resolvedDefault.provider;
3541
- const resolvePendingRuntime = (provider) => parsed.runtime ?? resolveRuntimeToken(getDiscordModelPickerRuntimeChoices(pickerData, provider), parsed.runtimeToken);
3564
+ const resolvePendingRuntime = (provider) => parsed.runtime ?? resolveRuntimeToken(getModelsRuntimeChoices(pickerData, provider), parsed.runtimeToken);
3542
3565
  const currentRuntime = resolveDiscordModelPickerCurrentRuntime(modelContext);
3543
3566
  const allowedModelRefs = buildDiscordModelPickerAllowedModelRefs(pickerData);
3544
3567
  const preferenceScope = resolveDiscordModelPickerPreferenceScope({
@@ -3551,8 +3574,22 @@ async function handleDiscordModelPickerInteraction(params) {
3551
3574
  allowedModelRefs,
3552
3575
  limit: 5
3553
3576
  });
3554
- const updatePicker = async (payload) => await params.safeInteractionCall("model picker update", () => interaction.editReply(payload));
3555
- const showNotice = async (message) => await updatePicker(buildDiscordModelPickerNoticePayload(message));
3577
+ const recordReply = async (commandText, replyText, replyId) => await recordDeliveredCommandExchange({
3578
+ config: cfg,
3579
+ agentId: route.agentId,
3580
+ sessionKey: route.sessionKey,
3581
+ expectedSessionId: sessionEntry?.sessionId,
3582
+ commandText,
3583
+ commandId: `discord:${ctx.accountId}:${route.sessionKey}:${interaction.id}`,
3584
+ replyId,
3585
+ replyText
3586
+ });
3587
+ const updatePicker = async (payload, capture = true) => {
3588
+ const delivered = await params.safeInteractionCall("model picker update", () => interaction.editReply(payload));
3589
+ if (delivered !== null && capture) await recordReply(`/${parsed.command}`, typeof payload === "string" ? payload : [payload.content, formatDiscordCommandComponents(payload.components ?? [])].filter(Boolean).join("\n"), "picker-update");
3590
+ return delivered;
3591
+ };
3592
+ const showNotice = async (message, capture = true) => await updatePicker(buildDiscordModelPickerNoticePayload(message), capture);
3556
3593
  const renderContext = {
3557
3594
  command: parsed.command,
3558
3595
  userId: parsed.userId,
@@ -3655,7 +3692,7 @@ async function handleDiscordModelPickerInteraction(params) {
3655
3692
  if (selectingRuntime) {
3656
3693
  const selectedRuntime = resolveModelPickerSelectionValue(interaction) ?? parsed.runtime;
3657
3694
  const runtimeModel = selectedModel ?? (currentModel?.provider === provider ? currentModel.model : void 0);
3658
- const choices = getDiscordModelPickerRuntimeChoices(pickerData, provider, runtimeModel);
3695
+ const choices = getModelsRuntimeChoices(pickerData, provider, runtimeModel);
3659
3696
  if (!selectedRuntime || !choices?.some((choice) => choice.id === selectedRuntime)) {
3660
3697
  await showNotice("That runtime is not available for this model. Choose a runtime again.");
3661
3698
  return;
@@ -3695,37 +3732,8 @@ async function handleDiscordModelPickerInteraction(params) {
3695
3732
  return;
3696
3733
  }
3697
3734
  const resolvedModelRef = `${parsedModelRef.provider}/${parsedModelRef.model}`;
3698
- const choices = getDiscordModelPickerRuntimeChoices(pickerData, parsedModelRef.provider, parsedModelRef.model);
3699
- const modelOnlyHost = !supportsDiscordModelPickerRuntimeChoices();
3700
- const supportsModelOnlySelection = () => {
3701
- const currentEntry = createDiscordModelPickerSessionReader({
3702
- cfg,
3703
- route
3704
- }, "latest")();
3705
- const override = currentEntry?.agentRuntimeOverride?.trim();
3706
- if (override && ![
3707
- "auto",
3708
- "default",
3709
- "openclaw"
3710
- ].includes(override)) return false;
3711
- const model = pickerData.modelCatalog?.find((entry) => entry.provider === parsedModelRef.provider && entry.id === parsedModelRef.model);
3712
- return resolveEffectiveAgentRuntime({
3713
- cfg,
3714
- provider: parsedModelRef.provider,
3715
- modelId: parsedModelRef.model,
3716
- modelApi: model?.api,
3717
- modelBaseUrl: model?.baseUrl,
3718
- agentId: route.agentId,
3719
- sessionKey: route.sessionKey,
3720
- sessionEntry: currentEntry
3721
- }) === "openclaw";
3722
- };
3723
- const legacyRuntimeNotice = "This OpenClaw version supports model-only selection here. Update OpenClaw to change runtimes in the picker.";
3724
- if (modelOnlyHost && (parsed.runtime || parsed.runtimeToken || !supportsModelOnlySelection())) {
3725
- await showNotice(legacyRuntimeNotice);
3726
- return;
3727
- }
3728
- if (!modelOnlyHost && choices === void 0) {
3735
+ const choices = getModelsRuntimeChoices(pickerData, parsedModelRef.provider, parsedModelRef.model);
3736
+ if (choices === void 0) {
3729
3737
  await showNotice("Runtime availability is not confirmed. Reopen /model to try again.");
3730
3738
  return;
3731
3739
  }
@@ -3742,15 +3750,11 @@ async function handleDiscordModelPickerInteraction(params) {
3742
3750
  await showNotice("Sorry, /model is unavailable right now.");
3743
3751
  return;
3744
3752
  }
3745
- if (await showNotice(`Applying model change to ${resolvedModelRef}...`) === null) return;
3753
+ if (await showNotice(`Applying model change to ${resolvedModelRef}...`, false) === null) return;
3746
3754
  if (pickerData.isCurrent?.() === false) {
3747
3755
  await showNotice("That model picker expired. Reopen /model to try again.");
3748
3756
  return;
3749
3757
  }
3750
- if (modelOnlyHost && !supportsModelOnlySelection()) {
3751
- await showNotice(legacyRuntimeNotice);
3752
- return;
3753
- }
3754
3758
  const applyResult = await applyDiscordModelPickerSelection({
3755
3759
  ...ctx,
3756
3760
  interaction,
@@ -3762,19 +3766,26 @@ async function handleDiscordModelPickerInteraction(params) {
3762
3766
  selectedRuntime,
3763
3767
  preferenceScope,
3764
3768
  settleMs: ctx.postApplySettleMs ?? 250,
3765
- resolveCurrentModel: (currentRoute) => resolveDiscordModelPickerCurrentModel({
3766
- ...modelContext,
3767
- route: currentRoute
3768
- }),
3769
- resolveCurrentRuntime: (currentRoute) => resolveDiscordModelPickerCurrentRuntime({
3770
- cfg,
3771
- route: currentRoute
3772
- })
3769
+ resolveCurrentSelection: async (currentRoute) => {
3770
+ const currentEntry = await createDiscordModelPickerSessionReader({
3771
+ cfg,
3772
+ route: currentRoute
3773
+ })();
3774
+ const currentContext = {
3775
+ ...modelContext,
3776
+ route: currentRoute,
3777
+ sessionEntry: currentEntry
3778
+ };
3779
+ return {
3780
+ modelRef: await resolveDiscordModelPickerCurrentModel(currentContext),
3781
+ runtime: resolveDiscordModelPickerCurrentRuntime(currentContext)
3782
+ };
3783
+ }
3773
3784
  });
3774
- await params.safeInteractionCall("model picker follow-up", () => interaction.followUp({
3785
+ if (await params.safeInteractionCall("model picker follow-up", () => interaction.followUp({
3775
3786
  ...buildDiscordModelPickerNoticePayload(applyResult.noticeMessage),
3776
3787
  ephemeral: true
3777
- }));
3788
+ })) !== null) await recordReply(selectionCommand.prompt, applyResult.noticeMessage, "selection");
3778
3789
  return;
3779
3790
  }
3780
3791
  if (parsed.action === "cancel") await showNotice(`ℹ️ Model kept as ${currentModelRef}.`);
@@ -3825,15 +3836,27 @@ async function maybeDeliverDiscordDirectStatus(params) {
3825
3836
  isGroup: params.isGroup,
3826
3837
  defaultGroupActivation: params.defaultGroupActivation
3827
3838
  });
3839
+ const recordReply = async (replyText) => {
3840
+ await recordDeliveredCommandExchange({
3841
+ config: params.cfg,
3842
+ agentId: params.effectiveRoute.agentId,
3843
+ sessionKey: params.commandTargetSessionKey?.trim() || params.sessionKey,
3844
+ commandText: "/status",
3845
+ commandId: `discord:${params.accountId}:${params.commandTargetSessionKey?.trim() || params.sessionKey}:${params.interaction.id}`,
3846
+ replyId: "status",
3847
+ replyText
3848
+ });
3849
+ };
3828
3850
  if (statusReply && hasRenderableReplyPayload(statusReply)) await deliverDiscordInteractionReply({
3829
3851
  interaction: params.interaction,
3830
3852
  payload: statusReply,
3831
3853
  mediaLocalRoots: params.mediaLocalRoots,
3832
3854
  ...resolveDiscordInteractionReplyOptions(params),
3833
3855
  preferFollowUp: params.preferFollowUp,
3834
- responseEphemeral: params.responseEphemeral
3856
+ responseEphemeral: params.responseEphemeral,
3857
+ onDelivered: recordReply
3835
3858
  });
3836
- else await params.respond("Status unavailable.");
3859
+ else if (await params.respond("Status unavailable.")) await recordReply("Status unavailable.");
3837
3860
  return {
3838
3861
  accepted: true,
3839
3862
  effectiveRoute: params.effectiveRoute
@@ -4036,9 +4059,9 @@ async function dispatchDiscordCommandInteraction(params) {
4036
4059
  content,
4037
4060
  ...ephemeral !== void 0 ? { ephemeral } : {}
4038
4061
  };
4039
- await safeDiscordInteractionCall("interaction reply", async () => {
4062
+ return await safeDiscordInteractionCall("interaction reply", async () => {
4040
4063
  await interaction[preferFollowUp ? "followUp" : "reply"](payload);
4041
- });
4064
+ }) !== null;
4042
4065
  };
4043
4066
  const reject = async (content, ephemeral) => {
4044
4067
  await respond(content, { ephemeral });
@@ -4164,7 +4187,7 @@ async function dispatchDiscordCommandInteraction(params) {
4164
4187
  });
4165
4188
  const mediaLocalRoots = getAgentScopedMediaLocalRoots(cfg, effectiveRoute.agentId);
4166
4189
  if (policy?.isCurrent() === false) return reject("Access policy changed. Try this interaction again.", true);
4167
- const authority = createDiscordNativeCommandAuthority({
4190
+ const authority = await createDiscordNativeCommandAuthority({
4168
4191
  cfg,
4169
4192
  ctx: ctxPayload,
4170
4193
  commandAuthorized,
@@ -4201,7 +4224,7 @@ async function dispatchDiscordCommandInteraction(params) {
4201
4224
  } : {},
4202
4225
  readOnly: true
4203
4226
  }) : void 0;
4204
- const menu = command.key === "verbose" && bindingReadiness?.ok === false ? null : resolveCommandArgMenu({
4227
+ const menu = command.key === "verbose" && bindingReadiness?.ok === false ? null : await resolveCommandArgMenuAsync({
4205
4228
  command,
4206
4229
  args: commandArgs,
4207
4230
  cfg,
@@ -4229,11 +4252,19 @@ async function dispatchDiscordCommandInteraction(params) {
4229
4252
  safeInteractionCall: safeDiscordInteractionCall,
4230
4253
  dispatchCommandInteraction: dispatchDiscordCommandInteraction
4231
4254
  });
4232
- await safeDiscordInteractionCall(preferFollowUp ? "interaction follow-up" : "interaction reply", () => interaction[preferFollowUp ? "followUp" : "reply"]({
4255
+ if (await safeDiscordInteractionCall(preferFollowUp ? "interaction follow-up" : "interaction reply", () => interaction[preferFollowUp ? "followUp" : "reply"]({
4233
4256
  content: menuPayload.content,
4234
4257
  components: menuPayload.components,
4235
4258
  ephemeral: true
4236
- }));
4259
+ })) !== null) await recordDeliveredCommandExchange({
4260
+ config: cfg,
4261
+ agentId: effectiveRoute.agentId,
4262
+ sessionKey: commandTargetSessionKey?.trim() || effectiveRoute.sessionKey,
4263
+ commandText: prompt,
4264
+ commandId: `discord:${accountId}:${channelId}:${interaction.id}`,
4265
+ replyId: "argument-menu",
4266
+ replyText: `${menuPayload.content}\n${menu.choices.map((choice) => choice.label).join(", ")}`
4267
+ });
4237
4268
  return { accepted: true };
4238
4269
  }
4239
4270
  if (params.pluginCommandDispatch.kind === "plugin" && commandName !== "status") {
@@ -4244,7 +4275,7 @@ async function dispatchDiscordCommandInteraction(params) {
4244
4275
  const messageThreadId = !isDirectMessage && isThreadChannel ? channelId : void 0;
4245
4276
  const pluginThreadParentId = !isDirectMessage && isThreadChannel ? threadParentId : void 0;
4246
4277
  const pluginCommandAgentId = (isThreadChannel ? threadBindings.getByThreadId(rawChannelId)?.agentId : void 0) || routeState.configuredBinding?.statefulTarget.agentId || effectiveRoute.agentId;
4247
- const targetSessionEntry = getSessionEntry({
4278
+ const targetSessionEntry = await getSessionEntryAsync({
4248
4279
  agentId: pluginCommandAgentId,
4249
4280
  sessionKey: effectiveRoute.sessionKey
4250
4281
  });
@@ -4275,14 +4306,19 @@ async function dispatchDiscordCommandInteraction(params) {
4275
4306
  effectiveRoute
4276
4307
  };
4277
4308
  }
4278
- if (!hasRenderableReplyPayload(pluginReply)) {
4279
- await respond(DISCORD_EMPTY_VISIBLE_REPLY_WARNING);
4280
- return {
4281
- accepted: true,
4282
- effectiveRoute
4283
- };
4284
- }
4285
- await deliverDiscordInteractionReply({
4309
+ const recordReply = async (replyText) => {
4310
+ await recordDeliveredCommandExchange({
4311
+ config: cfg,
4312
+ agentId: pluginCommandAgentId,
4313
+ sessionKey: effectiveRoute.sessionKey,
4314
+ expectedSessionId: targetSessionEntry?.sessionId,
4315
+ commandText: prompt,
4316
+ commandId: `discord:${accountId}:${channelId}:${interaction.id}`,
4317
+ replyId: "plugin-reply",
4318
+ replyText
4319
+ });
4320
+ };
4321
+ if (hasRenderableReplyPayload(pluginReply)) await deliverDiscordInteractionReply({
4286
4322
  interaction,
4287
4323
  payload: pluginReply,
4288
4324
  ...resolveDiscordInteractionReplyOptions({
@@ -4291,8 +4327,10 @@ async function dispatchDiscordCommandInteraction(params) {
4291
4327
  accountId
4292
4328
  }),
4293
4329
  preferFollowUp,
4294
- responseEphemeral
4330
+ responseEphemeral,
4331
+ onDelivered: recordReply
4295
4332
  });
4333
+ else if (await respond("⚠️ Command produced no visible reply.")) await recordReply(DISCORD_EMPTY_VISIBLE_REPLY_WARNING);
4296
4334
  return {
4297
4335
  accepted: true,
4298
4336
  effectiveRoute
@@ -4407,20 +4445,15 @@ const IDENTIFY_WINDOW_MS = 5e3;
4407
4445
  var GatewayIdentifyLimiter = class {
4408
4446
  async wait() {
4409
4447
  const now = Date.now();
4410
- const state = this.state;
4411
- const clockMovedBackward = state !== void 0 && now < state.lastObservedAt;
4412
- const nextAllowedAt = state === void 0 ? now : clockMovedBackward ? now + IDENTIFY_WINDOW_MS : state.nextAllowedAt;
4448
+ const nextAllowedAt = this.nextAllowedAt ?? now;
4413
4449
  const waitMs = Math.max(0, nextAllowedAt - now);
4414
- this.state = {
4415
- lastObservedAt: now,
4416
- nextAllowedAt: Math.max(now, nextAllowedAt) + IDENTIFY_WINDOW_MS
4417
- };
4450
+ this.nextAllowedAt = Math.max(now, nextAllowedAt) + IDENTIFY_WINDOW_MS;
4418
4451
  if (waitMs > 0) await new Promise((resolve) => {
4419
4452
  setTimeout(resolve, waitMs).unref?.();
4420
4453
  });
4421
4454
  }
4422
4455
  reset() {
4423
- this.state = void 0;
4456
+ this.nextAllowedAt = void 0;
4424
4457
  }
4425
4458
  };
4426
4459
  const sharedGatewayIdentifyLimiter = new GatewayIdentifyLimiter();
@@ -4998,12 +5031,11 @@ function removeDiscordGatewayLateErrorGuard(emitter) {
4998
5031
  }
4999
5032
  function ensureDiscordGatewayLateErrorGuard(emitter) {
5000
5033
  if (emitter.listenerCount("error") > 0) return;
5001
- const seenMessages = /* @__PURE__ */ new Set();
5034
+ let logged = false;
5002
5035
  const guard = (err) => {
5003
- const message = formatDiscordGatewayErrorMessage(err);
5004
- if (seenMessages.has(message)) return;
5005
- seenMessages.add(message);
5006
- discordGatewayLog.error(`suppressed late gateway error after dispose: ${message}`);
5036
+ if (logged) return;
5037
+ logged = true;
5038
+ discordGatewayLog.error(`suppressed late gateway error after dispose: ${formatDiscordGatewayErrorMessage(err)}`);
5007
5039
  };
5008
5040
  discordGatewayLateErrorGuards.set(emitter, guard);
5009
5041
  emitter.on("error", guard);
@@ -5048,22 +5080,19 @@ function createDiscordGatewaySupervisor(params) {
5048
5080
  };
5049
5081
  let lifecycleHandler;
5050
5082
  let phase = "buffering";
5051
- const seenLateEventKeys = /* @__PURE__ */ new Set();
5052
- const logLateEvent = (state, event) => {
5053
- const key = `${state}:${event.type}:${event.message}`;
5054
- if (seenLateEventKeys.has(key)) return;
5055
- seenLateEventKeys.add(key);
5056
- params.runtime.error?.(danger(`discord: suppressed late gateway ${event.type} error ${state === "disposed" ? "after dispose" : "during teardown"}: ${event.message}`));
5057
- };
5083
+ let loggedLateError = false;
5058
5084
  const onGatewayError = (err) => {
5059
5085
  const event = classifyDiscordGatewayEvent({
5060
5086
  err,
5061
5087
  isDisallowedIntentsError: params.isDisallowedIntentsError
5062
5088
  });
5063
5089
  switch (phase) {
5064
- case "disposed":
5090
+ case "disposed": return;
5065
5091
  case "teardown":
5066
- logLateEvent(phase, event);
5092
+ if (!loggedLateError) {
5093
+ loggedLateError = true;
5094
+ params.runtime.error?.(danger(`discord: suppressed late gateway ${event.type} error during teardown: ${event.message}`));
5095
+ }
5067
5096
  return;
5068
5097
  case "active":
5069
5098
  lifecycleHandler?.(event);
@@ -5532,14 +5561,14 @@ const discordProviderRuntime = {
5532
5561
  probeDiscordApplicationId,
5533
5562
  createDiscordNativeCommand,
5534
5563
  runDiscordGatewayLifecycle,
5535
- loadDiscordVoiceRuntime: () => import("./voice-runtime-BFEBhf2B.mjs").then((n) => n.t),
5536
- loadDiscordProviderSessionRuntime: () => import("./provider-session.runtime-BMOuDbod.mjs"),
5564
+ loadDiscordVoiceRuntime: () => import("./voice-runtime-DHDNu0fz.mjs").then((n) => n.t),
5565
+ loadDiscordProviderSessionRuntime: () => import("./provider-session.runtime-Ucr3XodI.mjs"),
5537
5566
  createClient: (...args) => new Client(...args),
5538
5567
  resolveDiscordAccount,
5539
5568
  resolveNativeCommandsEnabled,
5540
5569
  resolveNativeSkillsEnabled,
5541
5570
  listNativeCommandSpecsForConfig,
5542
- listSkillCommandsForAgents,
5571
+ prepareSkillCommandsForAgents,
5543
5572
  isVerbose,
5544
5573
  shouldLogVerbose
5545
5574
  };
@@ -5834,7 +5863,7 @@ function createDiscordVoiceCommand(startupParams) {
5834
5863
  //#region extensions/discord/src/monitor/provider.commands.ts
5835
5864
  const loadPluginCommandRuntime = createLazyRuntimeModule(() => import("openclaw/plugin-sdk/plugin-command-runtime"));
5836
5865
  async function resolveDiscordProviderCommandSpecs(params) {
5837
- const listSkillCommands = params.listSkillCommandsForAgents ?? listSkillCommandsForAgents;
5866
+ const listSkillCommands = params.prepareSkillCommandsForAgents ?? prepareSkillCommandsForAgents;
5838
5867
  const listNativeCommandSpecs = params.listNativeCommandSpecsForConfig ?? listNativeCommandSpecsForConfig;
5839
5868
  const maxDiscordCommands = params.maxDiscordCommands ?? 100;
5840
5869
  const pluginCommandSpecs = params.nativeEnabled ? (await loadPluginCommandRuntime()).createPluginCommandRuntime().listNativeCandidates("discord") : [];
@@ -5856,7 +5885,7 @@ async function resolveDiscordProviderCommandSpecs(params) {
5856
5885
  return [...standardSpecs.filter((spec) => normalizeLowercaseStringOrEmpty(spec.name) !== voiceName), DISCORD_VOICE_COMMAND_SPEC];
5857
5886
  };
5858
5887
  const provisionalCollisions = [];
5859
- let skillCommands = params.nativeEnabled && params.nativeSkillsEnabled ? listSkillCommands({ cfg: params.cfg }) : [];
5888
+ let skillCommands = params.nativeEnabled && params.nativeSkillsEnabled ? await listSkillCommands({ cfg: params.cfg }) : [];
5860
5889
  let commandSpecs = params.nativeEnabled ? mergePluginCommandSpecs(listPrimaryCommandSpecs(skillCommands), (normalizedName) => provisionalCollisions.push(normalizedName)) : [];
5861
5890
  const initialCommandCount = commandSpecs.length;
5862
5891
  if (params.nativeEnabled && params.nativeSkillsEnabled && commandSpecs.length > maxDiscordCommands) {
@@ -6157,10 +6186,9 @@ async function replySilently(interaction, params, onError) {
6157
6186
  const REGISTRATION_WIDGET_ID = "AAAAAAAAAAAAAAAAAAAAAA";
6158
6187
  const PENDING_LAUNCH_WRITE_BUDGET_MS = 250;
6159
6188
  var DiscordActivityButton = class extends Button {
6160
- constructor(ctx, deps) {
6189
+ constructor(ctx) {
6161
6190
  super();
6162
6191
  this.ctx = ctx;
6163
- this.deps = deps;
6164
6192
  this.label = "Open widget";
6165
6193
  this.customId = buildDiscordActivityCustomId(REGISTRATION_WIDGET_ID);
6166
6194
  this.customIdParser = parseDiscordActivityCustomIdForInteraction;
@@ -6169,11 +6197,11 @@ var DiscordActivityButton = class extends Button {
6169
6197
  logPendingLaunchFailure(error) {
6170
6198
  if (this.pendingLaunchFailureLogged) return;
6171
6199
  this.pendingLaunchFailureLogged = true;
6172
- this.deps.logError(`discord activity: failed to record pending launch: ${String(error)}`);
6200
+ logError(`discord activity: failed to record pending launch: ${String(error)}`);
6173
6201
  }
6174
6202
  async run(interaction, data) {
6175
6203
  if (typeof data.widgetId !== "string") {
6176
- await this.deps.reply(interaction, {
6204
+ await replySilently(interaction, {
6177
6205
  content: "This widget is no longer valid.",
6178
6206
  ephemeral: true
6179
6207
  });
@@ -6199,15 +6227,12 @@ var DiscordActivityButton = class extends Button {
6199
6227
  await interaction.launchActivity();
6200
6228
  }
6201
6229
  };
6202
- function createDiscordActivityButton(ctx, applicationId, deps = {}) {
6230
+ function createDiscordActivityButton(ctx, applicationId) {
6203
6231
  const runtime = getDiscordActivitiesRuntime();
6204
6232
  if (!runtime) return null;
6205
6233
  if (applicationId) runtime.registerApplicationId(ctx.accountId, applicationId);
6206
6234
  if (!runtime.resolveAccount(ctx.accountId, ctx.cfg)) return null;
6207
- return new DiscordActivityButton(ctx, {
6208
- reply: deps.reply ?? replySilently,
6209
- logError: deps.logError ?? logError
6210
- });
6235
+ return new DiscordActivityButton(ctx);
6211
6236
  }
6212
6237
  //#endregion
6213
6238
  //#region extensions/discord/src/monitor/agent-components-context.ts
@@ -7255,7 +7280,7 @@ async function dispatchPluginDiscordInteractiveEvent(params) {
7255
7280
  }
7256
7281
  //#endregion
7257
7282
  //#region extensions/discord/src/monitor/agent-components.handlers.ts
7258
- const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-HN9052L1.mjs").then((n) => n.t));
7283
+ const loadComponentsRuntime = createLazyRuntimeModule(() => import("./components-C_cuoW1q.mjs").then((n) => n.t));
7259
7284
  async function resolveAuthorizedComponentEntry(params) {
7260
7285
  const entry = params.entry ?? await params.resolve(false);
7261
7286
  if (!entry) {
@@ -7636,7 +7661,7 @@ function buildTerminalPayload(params) {
7636
7661
  allowed_mentions: DISCORD_APPROVAL_ALLOWED_MENTIONS,
7637
7662
  components: [new Container([
7638
7663
  new TextDisplay(params.applied ? "## Approval resolved" : "## Approval already resolved"),
7639
- new TextDisplay(`Canonical result: **${label}**`),
7664
+ new TextDisplay(`Recorded result: **${label}**`),
7640
7665
  new Separator({
7641
7666
  divider: false,
7642
7667
  spacing: "small"
@@ -8033,19 +8058,19 @@ function stablePresenceSignature(payload) {
8033
8058
  }
8034
8059
  function createDiscordAutoPresenceController(params) {
8035
8060
  const autoCfg = resolveAutoPresenceConfig(params.discordConfig.autoPresence);
8036
- const loadAuthStore = params.loadAuthStore ?? (() => ensureAuthProfileStore());
8061
+ const loadAuthStore = params.loadAuthStore ?? (() => ensureAuthProfileStoreAsync());
8037
8062
  const now = params.scheduler.now;
8038
8063
  const scheduler = params.scheduler.scope();
8039
8064
  let started = false;
8040
8065
  let lastAppliedSignature = null;
8041
8066
  let lastAppliedAt = 0;
8042
- const runEvaluation = (options) => {
8067
+ const runEvaluation = async (options) => {
8043
8068
  if (!autoCfg.enabled || scheduler.signal.aborted) return;
8044
8069
  let presence;
8045
8070
  try {
8046
8071
  presence = resolveDiscordAutoPresenceUpdate({
8047
8072
  discordConfig: params.discordConfig,
8048
- authStore: loadAuthStore(),
8073
+ authStore: await loadAuthStore(),
8049
8074
  gatewayConnected: params.gateway.isConnected,
8050
8075
  now: now()
8051
8076
  });
@@ -8053,7 +8078,7 @@ function createDiscordAutoPresenceController(params) {
8053
8078
  params.log?.(warn(`discord: auto-presence evaluation failed for account ${params.accountId}: ${String(err)}`));
8054
8079
  return;
8055
8080
  }
8056
- if (!params.gateway.isConnected) return;
8081
+ if (scheduler.signal.aborted || !params.gateway.isConnected) return;
8057
8082
  const forceApply = options?.force === true;
8058
8083
  const ts = now();
8059
8084
  const signature = stablePresenceSignature(presence);
@@ -8066,23 +8091,23 @@ function createDiscordAutoPresenceController(params) {
8066
8091
  return {
8067
8092
  enabled: autoCfg.enabled,
8068
8093
  refresh: () => runEvaluation({ force: true }),
8069
- start: () => {
8094
+ start: async () => {
8070
8095
  if (!autoCfg.enabled || started || scheduler.signal.aborted) return;
8071
8096
  started = true;
8072
- runEvaluation({ force: true });
8097
+ const initialEvaluation = runEvaluation({ force: true });
8073
8098
  scheduler.schedule({
8074
8099
  id: "presence",
8075
8100
  delayMs: autoCfg.intervalMs,
8076
8101
  everyMs: autoCfg.intervalMs,
8077
8102
  run: () => runEvaluation()
8078
8103
  });
8104
+ await initialEvaluation;
8079
8105
  },
8080
8106
  stop: () => scheduler.stop()
8081
8107
  };
8082
8108
  }
8083
8109
  //#endregion
8084
8110
  //#region extensions/discord/src/monitor/gateway-metadata.ts
8085
- const captureSdk$1 = proxyCaptureSdk;
8086
8111
  const DISCORD_GATEWAY_BOT_URL = "https://discord.com/api/v10/gateway/bot";
8087
8112
  const DISCORD_API_HOST = "discord.com";
8088
8113
  const DEFAULT_DISCORD_GATEWAY_URL = "wss://gateway.discord.gg/";
@@ -8239,7 +8264,7 @@ async function fetchDiscordGatewayMetadataGuarded(input, init, options) {
8239
8264
  } finally {
8240
8265
  await guarded.release();
8241
8266
  }
8242
- if (options?.capture) captureSdk$1.captureHttpExchangeAsync?.({
8267
+ if (options?.capture) captureHttpExchangeAsync({
8243
8268
  url: input,
8244
8269
  method: init?.method ?? "GET",
8245
8270
  requestHeaders: init?.headers,
@@ -8252,7 +8277,6 @@ async function fetchDiscordGatewayMetadataGuarded(input, init, options) {
8252
8277
  }
8253
8278
  //#endregion
8254
8279
  //#region extensions/discord/src/monitor/gateway-plugin.ts
8255
- const captureSdk = proxyCaptureSdk;
8256
8280
  const DISCORD_GATEWAY_POLICY_VIOLATION_CLOSE_CODE = 1008;
8257
8281
  const DISCORD_GATEWAY_WS_RECEIVER_LIMIT_CODE = "WS_ERR_TOO_MANY_BUFFERED_PARTS";
8258
8282
  const DISCORD_GATEWAY_CLOSE_REASON_LOG_MAX_CHARS = 240;
@@ -8367,7 +8391,7 @@ function createGatewayPlugin(params) {
8367
8391
  this.emitter.emit(DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT, { at: Date.now() });
8368
8392
  };
8369
8393
  const captureEvent = (event) => {
8370
- captureSdk.captureWsEventAsync?.({
8394
+ captureWsEventAsync({
8371
8395
  url,
8372
8396
  ...event(),
8373
8397
  flowId: wsFlowId,
@@ -8816,7 +8840,7 @@ function isDiscordDisallowedIntentsError(err) {
8816
8840
  async function monitorDiscordProvider(opts) {
8817
8841
  const { scheduler } = opts;
8818
8842
  const startupStartedAt = Date.now();
8819
- const cfg = opts.config ?? getRuntimeConfig();
8843
+ const cfg = opts.config ?? await captureRuntimeConfigAsyncReader()();
8820
8844
  const readConfig = opts.readConfig ?? createRuntimeConfigReader(cfg);
8821
8845
  const account = discordProviderRuntime.resolveDiscordAccount({
8822
8846
  cfg,
@@ -8902,6 +8926,7 @@ async function monitorDiscordProvider(opts) {
8902
8926
  const voiceEnabled = resolveDiscordVoiceEnabled(discordCfg.voice);
8903
8927
  if (voiceEnabled && getDiscordEndpointRuntime()) throw new Error("Discord voice transport is unavailable while DISCORD_API_URL is configured");
8904
8928
  const allowlistResolved = await resolveDiscordAllowlistConfig({
8929
+ accountId: account.accountId,
8905
8930
  token,
8906
8931
  guildEntries,
8907
8932
  allowFrom,
@@ -8966,7 +8991,7 @@ async function monitorDiscordProvider(opts) {
8966
8991
  nativeEnabled,
8967
8992
  nativeSkillsEnabled,
8968
8993
  voiceEnabled,
8969
- listSkillCommandsForAgents: discordProviderRuntime.listSkillCommandsForAgents,
8994
+ prepareSkillCommandsForAgents: discordProviderRuntime.prepareSkillCommandsForAgents,
8970
8995
  listNativeCommandSpecsForConfig: discordProviderRuntime.listNativeCommandSpecsForConfig
8971
8996
  });
8972
8997
  const voiceManagerRef = { current: null };