@openclaw/discord 2026.9.1-beta.1 → 2026.9.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 (165) hide show
  1. package/dist/account-inspect-BY-ve3yH.js +45 -0
  2. package/dist/account-inspect-api.js +1 -1
  3. package/dist/{accounts-CfQ-vSyf.js → accounts-CwJQoLjM.js} +89 -45
  4. package/dist/action-runtime-api.js +1 -1
  5. package/dist/{activities-api-q-9PaaHH.js → activities-api-CTcGq3Hf.js} +30 -17
  6. package/dist/activities-api.js +1 -1
  7. package/dist/{allow-list-BDMimASD.js → allow-list-DBTtR2dz.js} +13 -35
  8. package/dist/{api-DNVbJyEy.js → api-BfmEP6wp.js} +6 -5
  9. package/dist/api.js +18 -18
  10. package/dist/{approval-handler.runtime-B7qhK3fR.js → approval-handler.runtime-DUSe5fyH.js} +19 -12
  11. package/dist/{audit-CBEv_ERu.js → audit-DpPfwoJM.js} +8 -7
  12. package/dist/{channel-Dx1tMTfx.js → channel-BHajPgwR.js} +29 -23
  13. package/dist/{channel-actions.runtime-CLWWu9nC.js → channel-actions.runtime-DS8pXo0S.js} +38 -38
  14. package/dist/channel-config-api.js +1 -1
  15. package/dist/channel-plugin-api.js +1 -1
  16. package/dist/{channel.setup-DOzXS2Pk.js → channel.setup-BWmMe1tT.js} +18 -18
  17. package/dist/command-owners-D78sAoOz.js +10 -0
  18. package/dist/{components-B9V5o361.js → components-BimX47Mq.js} +111 -149
  19. package/dist/{config-schema-BR13IAx6.js → config-schema-B797-Spt.js} +19 -12
  20. package/dist/{conversation-binding-route-DJYrY2TQ.js → conversation-binding-route-DuR5NGIx.js} +1 -1
  21. package/dist/{directory-config-BK6eqekJ.js → directory-config-CD2v2Szs.js} +2 -2
  22. package/dist/directory-contract-api.js +1 -1
  23. package/dist/{directory-live-DSAJSrJk.js → directory-live-DaJzWJ2N.js} +4 -4
  24. package/dist/{doctor-Cm7Y1pJ2.js → doctor-D4HH1inA.js} +9 -6
  25. package/dist/{doctor-contract-DsWvKIXF.js → doctor-contract-Co5vRCZ6.js} +9 -6
  26. package/dist/doctor-contract-api.js +31 -28
  27. package/dist/{handle-action.guild-admin-BdwCRHmm.js → handle-action.guild-admin-4We6wWQU.js} +6 -3
  28. package/dist/index.js +1 -1
  29. package/dist/ingress-identity-XNmW-mZS.js +60 -0
  30. package/dist/{message-handler-BXpWZyni.js → message-handler-DhgBabyU.js} +61 -70
  31. package/dist/{message-handler.preflight-Ba5LAY_X.js → message-handler.preflight-oZ7dQCd0.js} +41 -101
  32. package/dist/{message-handler.process-3HEzmemS.js → message-handler.process-BzCYf1pa.js} +82 -108
  33. package/dist/{message-text-aiwO5R2F.js → message-text-DK4NnBg-.js} +11 -6
  34. package/dist/{outbound-adapter-BE4jSq2d.js → outbound-adapter-CtggmGh9.js} +52 -67
  35. package/dist/{outbound-components-oLpg8Qzb.js → outbound-components-Dn8SJWMS.js} +5 -4
  36. package/dist/{outbound-session-route-Cg15ZFJd.js → outbound-session-route-Q_HEusBQ.js} +57 -15
  37. package/dist/{owner-access-UlYi9t0M.js → owner-access-Cp8r6Ipf.js} +9 -7
  38. package/dist/{pluralkit-Tiyl70dx.js → pluralkit-BY75YcK0.js} +2 -2
  39. package/dist/{probe-n6ZXxK8V.js → probe-3ovFAp3b.js} +3 -3
  40. package/dist/{probe.runtime-CN4bdPfZ.js → probe.runtime-BckHn3cJ.js} +1 -1
  41. package/dist/{provider-session.runtime-B9xe-Qaf.js → provider-session.runtime-BL2lHBH7.js} +3 -3
  42. package/dist/{provider-B11xwilq.js → provider-uKmmrDM4.js} +299 -136
  43. package/dist/provider.runtime-C-IkWF2w.js +2 -0
  44. package/dist/{realtime-session.runtime-CU8IQUS-.js → realtime-session.runtime-CGYm1t_0.js} +798 -448
  45. package/dist/{resolve-allowlist-common-BLoYaxEG.js → resolve-allowlist-common-sKIKy-cF.js} +3 -3
  46. package/dist/{resolve-channels-C2sT_n67.js → resolve-channels-CoiMlWy0.js} +4 -4
  47. package/dist/{resolve-users-CzpjLwjy.js → resolve-users-DJpiokfW.js} +5 -4
  48. package/dist/{retry-Cv4jCU5Z.js → retry-DQt1zDgH.js} +356 -214
  49. package/dist/{retry-after-DdLPmPoa.js → retry-after-BrLjLUJi.js} +2 -1
  50. package/dist/{runtime-CY4PRMF-.js → runtime-BHsdEdr5.js} +2 -2
  51. package/dist/{runtime-BHrTlFkf.js → runtime-Ghtfh5ZA.js} +151 -109
  52. package/dist/runtime-api.js +20 -20
  53. package/dist/{secret-config-contract-B3i6WxV5.js → secret-config-contract-DFu9hfU8.js} +14 -6
  54. package/dist/secret-contract-api.js +1 -1
  55. package/dist/{security-audit-BfJhAXZp.js → security-audit-DKfK-iPY.js} +10 -11
  56. package/dist/security-audit-contract-api.js +1 -1
  57. package/dist/{security-audit.runtime-BVKF9VtY.js → security-audit.runtime-sKZyKgpx.js} +1 -1
  58. package/dist/{send-C49MFF9j.js → send-CZeWKUiA.js} +132 -100
  59. package/dist/{send.components-DKKAw5VX.js → send.components-BG5IDABj.js} +21 -15
  60. package/dist/{send.outbound-zam0TrZx.js → send.outbound-DHuFUL6W.js} +42 -63
  61. package/dist/{send.shared-JjljcV4O.js → send.shared-B0n_fWzu.js} +77 -149
  62. package/dist/{sender-identity-BJtfyise.js → sender-identity-B8Ncfi63.js} +1 -1
  63. package/dist/setup-plugin-api.js +1 -1
  64. package/dist/{shared-_5EcP4jW.js → shared-C3dKun_X.js} +24 -15
  65. package/dist/{subagent-hooks-DQzvOptn.js → subagent-hooks-ZoQXEI1E.js} +2 -2
  66. package/dist/subagent-hooks-api.js +1 -1
  67. package/dist/{system-events-C7yxaHWP.js → system-events-DFF_awl7.js} +2 -2
  68. package/dist/{target-resolver-vxIh6O3-.js → target-resolver-DLtHDwMK.js} +6 -5
  69. package/dist/targets-BObRyaKX.js +3 -0
  70. package/dist/{thread-bindings-DW5F9vat.js → thread-bindings-DKvsNjQR.js} +7 -6
  71. package/dist/{thread-bindings.manager-ByOtwjo_.js → thread-bindings.manager-pbbRT5gb.js} +38 -29
  72. package/dist/{thread-bindings.session-updates-CJb-BpPL.js → thread-bindings.session-updates-t6jeFB1-.js} +3 -2
  73. package/dist/{thread-bindings.state-D8OMdk4O.js → thread-bindings.state-DtgOqsbX.js} +34 -1
  74. package/dist/{threading-agH1T_6s.js → threading-BCx49X-6.js} +8 -6
  75. package/dist/{timeouts-B9cy6RvQ.js → timeouts-D86uWLt_.js} +1 -1
  76. package/dist/{transcripts-source-BR11iHA4.js → transcripts-source-Dc6Nnli5.js} +55 -7
  77. package/dist/transcripts-source-api.js +1 -1
  78. package/dist/{typing-Dc_YMY2e.js → typing-CuopV-Hi.js} +2 -2
  79. package/dist/{voice-runtime-DIeaa8fJ.js → voice-runtime-BQnILUbG.js} +492 -105
  80. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/README.md +1 -1
  81. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/conforms.d.ts +2 -0
  82. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/package.json +3 -3
  83. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/stubArray.d.ts +2 -0
  84. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/stubObject.d.ts +2 -0
  85. package/node_modules/@discord/embedded-app-sdk/node_modules/@types/lodash/stubString.d.ts +2 -0
  86. package/node_modules/@discordjs/voice/node_modules/@types/node/README.md +1 -1
  87. package/node_modules/@discordjs/voice/node_modules/@types/node/buffer.buffer.d.ts +5 -5
  88. package/node_modules/@discordjs/voice/node_modules/@types/node/crypto.d.ts +2 -2
  89. package/node_modules/@discordjs/voice/node_modules/@types/node/http.d.ts +16 -0
  90. package/node_modules/@discordjs/voice/node_modules/@types/node/http2.d.ts +10 -2
  91. package/node_modules/@discordjs/voice/node_modules/@types/node/package.json +2 -2
  92. package/node_modules/@discordjs/voice/node_modules/@types/node/process.d.ts +52 -0
  93. package/node_modules/@discordjs/voice/node_modules/@types/node/quic.d.ts +210 -28
  94. package/node_modules/@discordjs/voice/node_modules/@types/node/sqlite.d.ts +6 -2
  95. package/node_modules/@discordjs/voice/node_modules/@types/node/test.d.ts +36 -0
  96. package/node_modules/typebox/build/format/email.mjs +1 -1
  97. package/node_modules/typebox/build/format/idna/idn-hostname.mjs +19 -1
  98. package/node_modules/typebox/build/format/json_pointer.d.mts +2 -2
  99. package/node_modules/typebox/build/format/json_pointer.mjs +2 -2
  100. package/node_modules/typebox/build/format/json_pointer_uri_fragment.d.mts +2 -2
  101. package/node_modules/typebox/build/format/json_pointer_uri_fragment.mjs +2 -2
  102. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  103. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  104. package/node_modules/typebox/build/system/memory/assign.mjs +2 -1
  105. package/node_modules/typebox/build/system/memory/create.mjs +3 -4
  106. package/node_modules/typebox/build/system/memory/discard.mjs +2 -2
  107. package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
  108. package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
  109. package/node_modules/typebox/build/system/memory/update.mjs +3 -2
  110. package/node_modules/typebox/package.json +1 -1
  111. package/node_modules/undici/docs/docs/api/Client.md +4 -0
  112. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +3 -2
  113. package/node_modules/undici/docs/docs/api/EventSource.md +4 -0
  114. package/node_modules/undici/docs/docs/api/Interceptors.md +7 -3
  115. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +7 -1
  116. package/node_modules/undici/lib/cache/memory-cache-store.js +2 -2
  117. package/node_modules/undici/lib/core/symbols.js +2 -0
  118. package/node_modules/undici/lib/dispatcher/agent.js +7 -2
  119. package/node_modules/undici/lib/dispatcher/balanced-pool.js +7 -4
  120. package/node_modules/undici/lib/dispatcher/client-h1.js +12 -4
  121. package/node_modules/undici/lib/dispatcher/client-h2.js +43 -3
  122. package/node_modules/undici/lib/dispatcher/client.js +3 -2
  123. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +13 -1
  124. package/node_modules/undici/lib/dispatcher/dispatcher.js +15 -1
  125. package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +3 -0
  126. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +10 -3
  127. package/node_modules/undici/lib/dispatcher/proxy-agent.js +18 -1
  128. package/node_modules/undici/lib/dispatcher/retry-agent.js +3 -0
  129. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +1 -1
  130. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +91 -21
  131. package/node_modules/undici/lib/handler/cache-handler.js +29 -5
  132. package/node_modules/undici/lib/handler/decorator-handler.js +7 -1
  133. package/node_modules/undici/lib/handler/deduplication-handler.js +12 -6
  134. package/node_modules/undici/lib/handler/redirect-handler.js +21 -4
  135. package/node_modules/undici/lib/handler/retry-handler.js +148 -30
  136. package/node_modules/undici/lib/interceptor/cache.js +65 -12
  137. package/node_modules/undici/lib/interceptor/decompress.js +115 -13
  138. package/node_modules/undici/lib/interceptor/deduplicate.js +5 -4
  139. package/node_modules/undici/lib/interceptor/dns.js +7 -0
  140. package/node_modules/undici/lib/interceptor/dump.js +10 -23
  141. package/node_modules/undici/lib/mock/mock-agent.js +13 -1
  142. package/node_modules/undici/lib/mock/mock-utils.js +11 -10
  143. package/node_modules/undici/lib/util/cache.js +45 -3
  144. package/node_modules/undici/lib/web/cookies/parse.js +150 -147
  145. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +28 -1
  146. package/node_modules/undici/lib/web/eventsource/eventsource.js +13 -3
  147. package/node_modules/undici/lib/web/fetch/index.js +6 -0
  148. package/node_modules/undici/lib/web/fetch/request.js +2 -3
  149. package/node_modules/undici/lib/web/fetch/util.js +6 -1
  150. package/node_modules/undici/lib/web/webidl/index.js +3 -3
  151. package/node_modules/undici/lib/web/websocket/connection.js +1 -1
  152. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +5 -0
  153. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +8 -10
  154. package/node_modules/undici/package.json +3 -3
  155. package/node_modules/undici/types/client.d.ts +10 -0
  156. package/node_modules/undici/types/interceptors.d.ts +2 -0
  157. package/node_modules/undici/types/mock-agent.d.ts +11 -10
  158. package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -0
  159. package/openclaw.plugin.json +15 -8
  160. package/package.json +7 -6
  161. package/skills/discord/SKILL.md +1 -1
  162. package/dist/account-inspect-BDfKyuvL.js +0 -89
  163. package/dist/provider.runtime-DiYaHvOz.js +0 -2
  164. package/dist/sdk-runtime-4geQHtXc.js +0 -338
  165. package/dist/targets-CtTKvntJ.js +0 -3
@@ -1,8 +1,9 @@
1
- import { c as resolveDiscordAccount, d as resolveDiscordAccountDisabledReason, f as resolveDiscordAccountDmPolicy, l as resolveDiscordAccountAllowFrom, n as isDiscordAccountEnabledForRuntime, o as mergeDiscordAccountConfig, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId } from "./accounts-CfQ-vSyf.js";
2
- import { t as inspectDiscordAccount } from "./account-inspect-BDfKyuvL.js";
3
- import { t as DiscordChannelConfigSchema } from "./config-schema-BR13IAx6.js";
4
- import { n as normalizeCompatibilityConfig } from "./doctor-contract-DsWvKIXF.js";
5
- import { r as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-B3i6WxV5.js";
1
+ import { c as resolveDiscordAccount, d as resolveDiscordAccountDisabledReason, f as resolveDiscordAccountDmPolicy, l as resolveDiscordAccountAllowFrom, n as isDiscordAccountEnabledForRuntime, o as mergeDiscordAccountConfig, r as listDiscordAccountIds, s as resolveDefaultDiscordAccountId } from "./accounts-CwJQoLjM.js";
2
+ import { t as inspectDiscordAccount } from "./account-inspect-BY-ve3yH.js";
3
+ import { t as discordIngressIdentity } from "./ingress-identity-XNmW-mZS.js";
4
+ import { t as DiscordChannelConfigSchema } from "./config-schema-B797-Spt.js";
5
+ import { n as normalizeCompatibilityConfig } from "./doctor-contract-Co5vRCZ6.js";
6
+ import { r as secretTargetRegistryEntries, t as collectRuntimeConfigAssignments } from "./secret-config-contract-DFu9hfU8.js";
6
7
  import { n as unsupportedSecretRefSurfacePatterns, t as collectUnsupportedSecretRefConfigCandidates } from "./security-contract-DSHk7I2w.js";
7
8
  import { t as deriveLegacySessionChatType } from "./session-contract-BO5tlIdl.js";
8
9
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
@@ -12,6 +13,7 @@ import { PAIRING_APPROVED_MESSAGE, buildTokenChannelStatusSummary, projectCreden
12
13
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
13
14
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
14
15
  import { createConditionalWarningCollector, createOpenProviderConfiguredRouteWarningCollector } from "openclaw/plugin-sdk/channel-policy";
16
+ import { identityEntryAuthenticationClassifier } from "openclaw/plugin-sdk/channel-ingress-runtime";
15
17
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
16
18
  import { createEnvPatchedAccountSetupAdapter } from "openclaw/plugin-sdk/setup-runtime";
17
19
  //#region extensions/discord/src/channel-api.ts
@@ -48,6 +50,7 @@ const resolveDiscordDmPolicy = createScopedDmSecurityResolver({
48
50
  })
49
51
  }),
50
52
  policyPathSuffix: "dmPolicy",
53
+ classifyEntryAuthentication: identityEntryAuthenticationClassifier(discordIngressIdentity),
51
54
  normalizeEntry: (raw) => raw.trim().replace(/^(discord|user):/i, "").replace(/^<@!?(\d+)>$/, "$1")
52
55
  });
53
56
  const collectDiscordSecurityWarnings = createOpenProviderConfiguredRouteWarningCollector({
@@ -72,12 +75,21 @@ const collectDiscordSecurityFindings = createConditionalWarningCollector.finding
72
75
  severity: "critical",
73
76
  title: "Discord security warning"
74
77
  });
75
- const loadDiscordSecurityAuditModule = createLazyRuntimeModule(() => import("./security-audit.runtime-BVKF9VtY.js"));
78
+ const loadDiscordSecurityAuditModule = createLazyRuntimeModule(() => import("./security-audit.runtime-sKZyKgpx.js"));
76
79
  const discordSecurityAdapter = {
77
80
  resolveDmPolicy: resolveDiscordDmPolicy,
78
81
  collectWarnings: collectDiscordSecurityFindings,
79
82
  collectAuditFindings: async (params) => (await loadDiscordSecurityAuditModule()).collectDiscordSecurityAuditFindings(params)
80
83
  };
84
+ //#endregion
85
+ //#region extensions/discord/src/setup-adapter.ts
86
+ const discordSetupAdapter = createEnvPatchedAccountSetupAdapter({
87
+ channelKey: "discord",
88
+ defaultAccountOnlyEnvError: "DISCORD_BOT_TOKEN can only be used for the default account.",
89
+ missingCredentialError: "Discord requires token (or --use-env).",
90
+ hasCredentials: (input) => Boolean(input.token),
91
+ buildPatch: (input) => input.token ? { token: input.token } : {}
92
+ });
81
93
  const discordSetupContract = defineChannelSetupContract({
82
94
  fields: {
83
95
  token: {
@@ -97,13 +109,7 @@ const discordSetupContract = defineChannelSetupContract({
97
109
  envVars: ["DISCORD_BOT_TOKEN"]
98
110
  }
99
111
  },
100
- legacyAdapter: createEnvPatchedAccountSetupAdapter({
101
- channelKey: "discord",
102
- defaultAccountOnlyEnvError: "DISCORD_BOT_TOKEN can only be used for the default account.",
103
- missingCredentialError: "Discord requires token (or --use-env).",
104
- hasCredentials: (input) => Boolean(input.token),
105
- buildPatch: (input) => input.token ? { token: input.token } : {}
106
- })
112
+ legacyAdapter: discordSetupAdapter
107
113
  });
108
114
  //#endregion
109
115
  //#region extensions/discord/src/doctor-shared.ts
@@ -111,7 +117,7 @@ const DISCORD_LEGACY_CONFIG_RULES = [];
111
117
  //#endregion
112
118
  //#region extensions/discord/src/shared.ts
113
119
  const DISCORD_CHANNEL = "discord";
114
- const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-Cm7Y1pJ2.js"));
120
+ const loadDiscordDoctorModule = createLazyRuntimeModule(() => import("./doctor-D4HH1inA.js"));
115
121
  const discordDoctor = {
116
122
  dmAllowFromMode: "topOnly",
117
123
  groupModel: "route",
@@ -178,7 +184,10 @@ function createDiscordPluginBase(params) {
178
184
  minChars: 1500,
179
185
  idleMs: 1e3
180
186
  } },
181
- reload: { configPrefixes: ["channels.discord"] },
187
+ reload: {
188
+ configPrefixes: ["channels.discord"],
189
+ noopPrefixes: ["messages.inbound", "messages.ackReactionScope"]
190
+ },
182
191
  configSchema: DiscordChannelConfigSchema,
183
192
  config: {
184
193
  ...discordConfigAdapter,
@@ -1,5 +1,5 @@
1
- import { on as __exportAll } from "./retry-Cv4jCU5Z.js";
2
- import { o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-DW5F9vat.js";
1
+ import { sn as __exportAll } from "./retry-DQt1zDgH.js";
2
+ import { o as unbindThreadBindingsBySessionKey, r as listThreadBindingsBySessionKey } from "./thread-bindings-DKvsNjQR.js";
3
3
  import { normalizeOptionalLowercaseString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  //#region extensions/discord/src/subagent-hooks.ts
5
5
  var subagent_hooks_exports = /* @__PURE__ */ __exportAll({
@@ -1,6 +1,6 @@
1
1
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
2
2
  //#region extensions/discord/subagent-hooks-api.ts
3
- const loadDiscordSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-DQzvOptn.js").then((n) => n.r));
3
+ const loadDiscordSubagentHooksModule = createLazyRuntimeModule(() => import("./subagent-hooks-ZoQXEI1E.js").then((n) => n.r));
4
4
  function registerDiscordSubagentHooks(api) {
5
5
  api.on("subagent_ended", async (event) => {
6
6
  const { handleDiscordSubagentEnded } = await loadDiscordSubagentHooksModule();
@@ -1,5 +1,5 @@
1
- import { y as discord_exports } from "./retry-Cv4jCU5Z.js";
2
- import { x as formatDiscordUserTag } from "./allow-list-BDMimASD.js";
1
+ import { b as discord_exports } from "./retry-DQt1zDgH.js";
2
+ import { b as formatDiscordUserTag } from "./allow-list-DBTtR2dz.js";
3
3
  //#region extensions/discord/src/monitor/system-events.ts
4
4
  function resolveDiscordSystemEvent(message, location) {
5
5
  switch (message.type) {
@@ -1,6 +1,6 @@
1
- import { _ as parseDiscordTarget, on as __exportAll, p as allowFromContainsDiscordUserId } from "./retry-Cv4jCU5Z.js";
2
- import { c as resolveDiscordAccount, l as resolveDiscordAccountAllowFrom } from "./accounts-CfQ-vSyf.js";
3
- import { a as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-DSAJSrJk.js";
1
+ import { m as allowFromContainsDiscordUserId, sn as __exportAll, v as parseDiscordTarget } from "./retry-DQt1zDgH.js";
2
+ import { c as resolveDiscordAccount, l as resolveDiscordAccountAllowFrom } from "./accounts-CwJQoLjM.js";
3
+ import { a as rememberDiscordDirectoryUser, r as listDiscordDirectoryPeersLive } from "./directory-live-DaJzWJ2N.js";
4
4
  import { buildMessagingTarget } from "openclaw/plugin-sdk/channel-targets";
5
5
  //#region extensions/discord/src/send-target-parsing.ts
6
6
  const parseDiscordSendTarget = (raw, options = {}) => parseDiscordTarget(raw, options);
@@ -62,10 +62,11 @@ function safeParseDiscordTarget(input, options) {
62
62
  }
63
63
  }
64
64
  function isConfiguredAllowedDiscordDmUser(input, options) {
65
- return allowFromContainsDiscordUserId(resolveDiscordAccountAllowFrom({
65
+ const allowFrom = resolveDiscordAccountAllowFrom({
66
66
  cfg: options.cfg,
67
67
  accountId: options.accountId
68
- }) ?? [], input);
68
+ }) ?? [];
69
+ return allowFromContainsDiscordUserId(allowFrom, input);
69
70
  }
70
71
  function isExplicitUserLookup(input, options) {
71
72
  if (/^<@!?(\d+)>$/.test(input)) return true;
@@ -0,0 +1,3 @@
1
+ import "./retry-DQt1zDgH.js";
2
+ import "./target-resolver-DLtHDwMK.js";
3
+ export {};
@@ -1,8 +1,8 @@
1
- import { _ as parseDiscordTarget, on as __exportAll } from "./retry-Cv4jCU5Z.js";
2
- import "./targets-CtTKvntJ.js";
3
- import { C as resolveThreadBindingMaxAgeExpiresAt, O as shouldPersistBindingMutations, S as resolveThreadBindingInactivityExpiresAt, T as saveBindingsToDisk, h as refreshUnboundThreadWebhookIdentity, m as normalizeThreadId, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, u as getThreadBindingToken, v as removeBindingRecord, w as resolveThreadBindingMaxAgeMs$1, x as resolveThreadBindingIdleTimeoutMs$1 } from "./thread-bindings.state-D8OMdk4O.js";
4
- import { n as setThreadBindingMaxAgeBySessionKey, r as resolveBindingIdsForTargetSession, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-CJb-BpPL.js";
5
- import { _ as resolveThreadBindingThreadName, g as resolveThreadBindingIntroText, h as formatThreadBindingDurationLabel, m as resolveThreadBindingPersonaFromRecord, n as createThreadBindingManager, o as resolveChannelIdForBinding, p as resolveThreadBindingPersona, r as getThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-ByOtwjo_.js";
1
+ import { sn as __exportAll, v as parseDiscordTarget } from "./retry-DQt1zDgH.js";
2
+ import "./targets-BObRyaKX.js";
3
+ import { S as saveBindingsToDisk, T as shouldPersistBindingMutations, b as resolveThreadBindingMaxAgeExpiresAt, c as getThreadBindingToken, d as normalizeThreadId, f as refreshUnboundThreadWebhookIdentity, h as removeBindingRecord, n as MANAGERS_BY_ACCOUNT_ID, t as BINDINGS_BY_THREAD_ID, v as resolveThreadBindingIdleTimeoutMs$1, x as resolveThreadBindingMaxAgeMs$1, y as resolveThreadBindingInactivityExpiresAt } from "./thread-bindings.state-DtgOqsbX.js";
4
+ import { n as setThreadBindingMaxAgeBySessionKey, r as resolveBindingIdsForTargetSession, t as setThreadBindingIdleTimeoutBySessionKey } from "./thread-bindings.session-updates-t6jeFB1-.js";
5
+ import { _ as resolveThreadBindingThreadName, g as resolveThreadBindingIntroText, h as formatThreadBindingDurationLabel, m as resolveThreadBindingPersonaFromRecord, n as createThreadBindingManager, o as resolveChannelIdForBinding, p as resolveThreadBindingPersona, r as getThreadBindingManager, t as createNoopThreadBindingManager } from "./thread-bindings.manager-pbbRT5gb.js";
6
6
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
7
7
  import { normalizeOptionalLowercaseString, normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { resolveThreadBindingIdleTimeoutMs, resolveThreadBindingMaxAgeMs, resolveThreadBindingsEnabled } from "openclaw/plugin-sdk/conversation-runtime";
@@ -141,7 +141,8 @@ async function reconcileAcpThreadBindingsOnStartup(params) {
141
141
  }
142
142
  const session = readAcpSessionEntry({
143
143
  cfg: params.cfg,
144
- sessionKey
144
+ sessionKey,
145
+ agentId: binding.agentId
145
146
  });
146
147
  if (!session) {
147
148
  staleBindings.push(binding);
@@ -1,18 +1,18 @@
1
- import { At as getChannel, on as __exportAll, v as resolveDiscordChannelId, vt as createChannelWebhook } from "./retry-Cv4jCU5Z.js";
2
- import { P as createDiscordRestClient } from "./send.shared-JjljcV4O.js";
3
- import { t as sendMessageDiscord } from "./send.outbound-zam0TrZx.js";
1
+ import { jt as getChannel, sn as __exportAll, t as canFallbackDiscordWebhookSend, y as resolveDiscordChannelId, yt as createChannelWebhook } from "./retry-DQt1zDgH.js";
2
+ import { P as createDiscordRestClient } from "./send.shared-B0n_fWzu.js";
3
+ import { t as sendMessageDiscord } from "./send.outbound-DHuFUL6W.js";
4
4
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
5
- import { c as sendWebhookMessageDiscord, u as createThreadDiscord } from "./send-C49MFF9j.js";
6
- import { A as toReusableWebhookKey, C as resolveThreadBindingMaxAgeExpiresAt, D as shouldDefaultPersist, E as setBindingRecord, S as resolveThreadBindingInactivityExpiresAt, T as saveBindingsToDisk, _ as rememberThreadBindingToken, b as resolveBindingRecordKey, c as ensureBindingsLoaded, f as normalizeTargetKind, g as rememberReusableWebhook, h as refreshUnboundThreadWebhookIdentity, i as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL, l as forgetThreadBindingToken, m as normalizeThreadId, n as MANAGERS_BY_ACCOUNT_ID, p as normalizeThreadBindingDurationMs, r as PERSIST_BY_ACCOUNT_ID, s as THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS, t as BINDINGS_BY_THREAD_ID, u as getThreadBindingToken, v as removeBindingRecord, w as resolveThreadBindingMaxAgeMs$1, x as resolveThreadBindingIdleTimeoutMs$1, y as resolveBindingIdsForSession } from "./thread-bindings.state-D8OMdk4O.js";
5
+ import { c as sendWebhookMessageDiscord, u as createThreadDiscord } from "./send-CZeWKUiA.js";
6
+ import { C as setBindingRecord, D as toReusableWebhookKey, S as saveBindingsToDisk, _ as resolveBindingRecordKey, a as THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS, b as resolveThreadBindingMaxAgeExpiresAt, c as getThreadBindingToken, d as normalizeThreadId, f as refreshUnboundThreadWebhookIdentity, g as resolveBindingIdsForSession, h as removeBindingRecord, i as REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL, l as normalizeTargetKind, m as rememberThreadBindingToken, n as MANAGERS_BY_ACCOUNT_ID, o as ensureBindingsLoaded, p as rememberReusableWebhook, r as PERSIST_BY_ACCOUNT_ID, s as forgetThreadBindingToken, t as BINDINGS_BY_THREAD_ID, u as normalizeThreadBindingDurationMs, v as resolveThreadBindingIdleTimeoutMs$1, w as shouldDefaultPersist, x as resolveThreadBindingMaxAgeMs$1, y as resolveThreadBindingInactivityExpiresAt } from "./thread-bindings.state-DtgOqsbX.js";
7
7
  import { parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
8
8
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
9
9
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
10
10
  import { getRuntimeConfigSnapshot } from "openclaw/plugin-sdk/runtime-config-snapshot";
11
- import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
11
+ import { createSubsystemLogger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
12
12
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
13
13
  import { SYSTEM_MARK } from "openclaw/plugin-sdk/text-chunking";
14
14
  import { formatThreadBindingDurationLabel, registerSessionBindingAdapter, resolveThreadBindingConversationIdFromBindingId, resolveThreadBindingFarewellText, resolveThreadBindingIntroText, resolveThreadBindingThreadName, unregisterSessionBindingAdapter } from "openclaw/plugin-sdk/conversation-runtime";
15
- import { resolveSessionAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
15
+ import { resolveSessionAgentIdStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
16
16
  //#region extensions/discord/src/monitor/thread-bindings.persona.ts
17
17
  const THREAD_BINDING_PERSONA_MAX_CHARS = 80;
18
18
  function normalizePersonaLabel(value) {
@@ -20,7 +20,8 @@ function normalizePersonaLabel(value) {
20
20
  return value.replace(/\s+/g, " ").trim() || void 0;
21
21
  }
22
22
  function resolveThreadBindingPersona(params) {
23
- return truncateUtf16Safe(`${SYSTEM_MARK} ${normalizePersonaLabel(params.label) || normalizePersonaLabel(params.agentId) || "agent"}`, THREAD_BINDING_PERSONA_MAX_CHARS);
23
+ const base = normalizePersonaLabel(params.label) || normalizePersonaLabel(params.agentId) || "agent";
24
+ return truncateUtf16Safe(`${SYSTEM_MARK} ${base}`, THREAD_BINDING_PERSONA_MAX_CHARS);
24
25
  }
25
26
  function resolveThreadBindingPersonaFromRecord(record) {
26
27
  return resolveThreadBindingPersona({
@@ -92,9 +93,10 @@ function resolveDiscordChannelInfoSafe(channel) {
92
93
  //#endregion
93
94
  //#region extensions/discord/src/monitor/thread-bindings.types.ts
94
95
  const THREAD_BINDINGS_SWEEP_INTERVAL_MS = 12e4;
95
- const DEFAULT_THREAD_BINDING_IDLE_TIMEOUT_MS = 1440 * 60 * 1e3;
96
+ const DEFAULT_THREAD_BINDING_IDLE_TIMEOUT_MS = 864e5;
96
97
  //#endregion
97
98
  //#region extensions/discord/src/monitor/thread-bindings.discord-api.ts
99
+ const log = createSubsystemLogger("discord/thread-bindings");
98
100
  function buildThreadTarget(threadId) {
99
101
  return /^(channel:|user:)/i.test(threadId) ? threadId : `channel:${threadId}`;
100
102
  }
@@ -154,7 +156,12 @@ async function maybeSendBindingMessage(params) {
154
156
  });
155
157
  return;
156
158
  } catch (err) {
157
- logVerbose(`discord thread binding webhook send failed: ${summarizeDiscordError(err)}`);
159
+ const fallbackToBot = canFallbackDiscordWebhookSend(err);
160
+ log.warn("discord thread binding webhook send failed", {
161
+ error: summarizeDiscordError(err),
162
+ fallbackToBot
163
+ });
164
+ if (!fallbackToBot) return;
158
165
  }
159
166
  try {
160
167
  await sendMessageDiscord(buildThreadTarget(record.threadId), text, {
@@ -232,11 +239,12 @@ async function resolveChannelIdForBinding(params) {
232
239
  }
233
240
  async function createThreadForBinding(params) {
234
241
  try {
235
- return (normalizeOptionalString((await createThreadDiscord(params.channelId, { name: params.threadName }, {
242
+ const created = await createThreadDiscord(params.channelId, { name: params.threadName }, {
236
243
  cfg: params.cfg,
237
244
  accountId: params.accountId,
238
245
  token: params.token
239
- }))?.id) ?? "") || null;
246
+ });
247
+ return (normalizeOptionalString(created?.id) ?? "") || null;
240
248
  } catch (err) {
241
249
  logVerbose(`discord thread binding auto-thread create failed for ${params.channelId}: ${summarizeDiscordError(err)}`);
242
250
  return null;
@@ -400,12 +408,6 @@ var thread_bindings_manager_exports = /* @__PURE__ */ __exportAll({
400
408
  createThreadBindingManager: () => createThreadBindingManager,
401
409
  getThreadBindingManager: () => getThreadBindingManager
402
410
  });
403
- function registerManager(manager) {
404
- MANAGERS_BY_ACCOUNT_ID.set(manager.accountId, manager);
405
- }
406
- function unregisterManager(accountId, manager) {
407
- if (MANAGERS_BY_ACCOUNT_ID.get(accountId) === manager) MANAGERS_BY_ACCOUNT_ID.delete(accountId);
408
- }
409
411
  function createNoopManager(accountIdRaw) {
410
412
  return {
411
413
  accountId: normalizeAccountId(accountIdRaw),
@@ -447,13 +449,14 @@ function createThreadBindingManager(params) {
447
449
  const maxAgeMs = normalizeThreadBindingDurationMs(params.maxAgeMs, 0);
448
450
  const resolveCurrentCfg = () => getRuntimeConfigSnapshot() ?? params.cfg;
449
451
  const resolveCurrentToken = () => getThreadBindingToken(accountId) ?? params.token;
452
+ const getCurrentBinding = (threadId) => MANAGERS_BY_ACCOUNT_ID.get(accountId) === manager ? manager.getByThreadId(threadId) : void 0;
450
453
  let sweepTimer = null;
451
454
  const runSweepOnce = async () => {
452
455
  const bindings = manager.listBindings();
453
456
  if (bindings.length === 0) return;
454
457
  let rest = null;
455
458
  for (const snapshotBinding of bindings) {
456
- const binding = manager.getByThreadId(snapshotBinding.threadId);
459
+ const binding = getCurrentBinding(snapshotBinding.threadId);
457
460
  if (!binding) continue;
458
461
  const now = Date.now();
459
462
  const inactivityExpiresAt = resolveThreadBindingInactivityExpiresAt({
@@ -496,8 +499,9 @@ function createThreadBindingManager(params) {
496
499
  }
497
500
  if (isDirectConversationBindingId(binding.threadId)) continue;
498
501
  if (!rest) try {
502
+ const cfg = resolveCurrentCfg();
499
503
  rest = createDiscordRestClient({
500
- cfg: resolveCurrentCfg(),
504
+ cfg,
501
505
  accountId,
502
506
  token: resolveCurrentToken()
503
507
  }).rest;
@@ -506,6 +510,7 @@ function createThreadBindingManager(params) {
506
510
  }
507
511
  try {
508
512
  const channel = await getChannel(rest, binding.threadId);
513
+ if (getCurrentBinding(binding.threadId) !== binding) continue;
509
514
  if (!channel || typeof channel !== "object") {
510
515
  logVerbose(`discord thread binding sweep probe returned invalid payload for ${binding.threadId}`);
511
516
  continue;
@@ -516,6 +521,7 @@ function createThreadBindingManager(params) {
516
521
  sendFarewell: true
517
522
  });
518
523
  } catch (err) {
524
+ if (getCurrentBinding(binding.threadId) !== binding) continue;
519
525
  if (isDiscordThreadGoneError(err)) {
520
526
  logVerbose(`discord thread binding sweep removing stale binding ${binding.threadId}: ${summarizeDiscordError(err)}`);
521
527
  manager.unbindThread({
@@ -604,6 +610,7 @@ function createThreadBindingManager(params) {
604
610
  const targetSessionKey = normalizeOptionalString(bindParams.targetSessionKey) ?? "";
605
611
  if (!targetSessionKey) return null;
606
612
  const targetKind = normalizeTargetKind(bindParams.targetKind, targetSessionKey);
613
+ const previous = existingValue?.targetSessionKey === targetSessionKey && existingValue.targetKind === targetKind ? existingValue : void 0;
607
614
  let webhookId = normalizeOptionalString(bindParams.webhookId) ?? normalizeOptionalString(existingValue?.webhookId) ?? "";
608
615
  let webhookToken = normalizeOptionalString(bindParams.webhookToken) ?? normalizeOptionalString(existingValue?.webhookToken) ?? "";
609
616
  if (!directConversationBinding && (!webhookId || !webhookToken)) {
@@ -631,22 +638,22 @@ function createThreadBindingManager(params) {
631
638
  threadId,
632
639
  targetKind,
633
640
  targetSessionKey,
634
- agentId: normalizeOptionalString(bindParams.agentId) ?? normalizeOptionalString(existingValue?.agentId) ?? resolveSessionAgentId({
641
+ agentId: normalizeOptionalString(bindParams.agentId) ?? normalizeOptionalString(previous?.agentId) ?? resolveSessionAgentIdStrict({
635
642
  config: cfg,
636
643
  sessionKey: targetSessionKey
637
644
  }),
638
- label: normalizeOptionalString(bindParams.label) ?? normalizeOptionalString(existingValue?.label),
645
+ label: normalizeOptionalString(bindParams.label) ?? normalizeOptionalString(previous?.label),
639
646
  webhookId: webhookId || void 0,
640
647
  webhookToken: webhookToken || void 0,
641
- boundBy: normalizeOptionalString(bindParams.boundBy) ?? normalizeOptionalString(existingValue?.boundBy) ?? "system",
648
+ boundBy: normalizeOptionalString(bindParams.boundBy) ?? normalizeOptionalString(previous?.boundBy) ?? "system",
642
649
  boundAt: now,
643
650
  lastActivityAt: now,
644
651
  idleTimeoutMs: typeof existingValue?.idleTimeoutMs === "number" ? existingValue.idleTimeoutMs : idleTimeoutMs,
645
652
  maxAgeMs: typeof existingValue?.maxAgeMs === "number" ? existingValue.maxAgeMs : maxAgeMs,
646
- metadata: bindParams.metadata && typeof bindParams.metadata === "object" ? {
647
- ...existingValue?.metadata,
653
+ metadata: {
654
+ ...previous?.metadata,
648
655
  ...bindParams.metadata
649
- } : existingValue?.metadata ? { ...existingValue.metadata } : void 0
656
+ }
650
657
  };
651
658
  setBindingRecord(record);
652
659
  if (persist) saveBindingsToDisk();
@@ -719,13 +726,15 @@ function createThreadBindingManager(params) {
719
726
  clearInterval(sweepTimer);
720
727
  sweepTimer = null;
721
728
  }
722
- unregisterManager(accountId, manager);
729
+ if (MANAGERS_BY_ACCOUNT_ID.get(accountId) === manager) {
730
+ MANAGERS_BY_ACCOUNT_ID.delete(accountId);
731
+ forgetThreadBindingToken(accountId);
732
+ }
723
733
  unregisterSessionBindingAdapter({
724
734
  channel: "discord",
725
735
  accountId,
726
736
  adapter: sessionBindingAdapter
727
737
  });
728
- forgetThreadBindingToken(accountId);
729
738
  }
730
739
  };
731
740
  if (params.enableSweeper !== false) {
@@ -745,7 +754,7 @@ function createThreadBindingManager(params) {
745
754
  resolveCurrentToken
746
755
  });
747
756
  registerSessionBindingAdapter(sessionBindingAdapter);
748
- registerManager(manager);
757
+ MANAGERS_BY_ACCOUNT_ID.set(accountId, manager);
749
758
  return manager;
750
759
  }
751
760
  function createNoopThreadBindingManager(accountId) {
@@ -1,4 +1,4 @@
1
- import { E as setBindingRecord, O as shouldPersistBindingMutations, T as saveBindingsToDisk, c as ensureBindingsLoaded, t as BINDINGS_BY_THREAD_ID, y as resolveBindingIdsForSession } from "./thread-bindings.state-D8OMdk4O.js";
1
+ import { C as setBindingRecord, S as saveBindingsToDisk, T as shouldPersistBindingMutations, g as resolveBindingIdsForSession, o as ensureBindingsLoaded, t as BINDINGS_BY_THREAD_ID } from "./thread-bindings.state-DtgOqsbX.js";
2
2
  import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
3
3
  //#region extensions/discord/src/monitor/thread-bindings.session-shared.ts
4
4
  function normalizeNonNegativeMs(raw) {
@@ -9,9 +9,10 @@ function resolveBindingIdsForTargetSession(params) {
9
9
  ensureBindingsLoaded();
10
10
  const targetSessionKey = params.targetSessionKey.trim();
11
11
  if (!targetSessionKey) return [];
12
+ const accountId = params.accountId ? normalizeAccountId(params.accountId) : void 0;
12
13
  return resolveBindingIdsForSession({
13
14
  targetSessionKey,
14
- accountId: params.accountId ? normalizeAccountId(params.accountId) : void 0,
15
+ accountId,
15
16
  targetKind: params.targetKind
16
17
  });
17
18
  }
@@ -1,8 +1,41 @@
1
+ import { sn as __exportAll } from "./retry-DQt1zDgH.js";
1
2
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.js";
2
3
  import { normalizeAccountId, resolveAgentIdFromSessionKey } from "openclaw/plugin-sdk/routing";
3
4
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
4
5
  import { recordOutboundMessageIdentity } from "openclaw/plugin-sdk/outbound-echo-runtime";
5
6
  //#region extensions/discord/src/monitor/thread-bindings.state.ts
7
+ var thread_bindings_state_exports = /* @__PURE__ */ __exportAll({
8
+ BINDINGS_BY_THREAD_ID: () => BINDINGS_BY_THREAD_ID,
9
+ MANAGERS_BY_ACCOUNT_ID: () => MANAGERS_BY_ACCOUNT_ID,
10
+ PERSIST_BY_ACCOUNT_ID: () => PERSIST_BY_ACCOUNT_ID,
11
+ REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL: () => REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL,
12
+ THREAD_BINDINGS_MAX_ENTRIES: () => THREAD_BINDINGS_MAX_ENTRIES,
13
+ THREAD_BINDINGS_NAMESPACE: () => THREAD_BINDINGS_NAMESPACE,
14
+ THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS: () => THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS,
15
+ ensureBindingsLoaded: () => ensureBindingsLoaded,
16
+ forgetThreadBindingToken: () => forgetThreadBindingToken,
17
+ getThreadBindingToken: () => getThreadBindingToken,
18
+ normalizePersistedBinding: () => normalizePersistedBinding,
19
+ normalizeTargetKind: () => normalizeTargetKind,
20
+ normalizeThreadBindingDurationMs: () => normalizeThreadBindingDurationMs,
21
+ normalizeThreadId: () => normalizeThreadId,
22
+ refreshUnboundThreadWebhookIdentity: () => refreshUnboundThreadWebhookIdentity,
23
+ rememberReusableWebhook: () => rememberReusableWebhook,
24
+ rememberThreadBindingToken: () => rememberThreadBindingToken,
25
+ removeBindingRecord: () => removeBindingRecord,
26
+ resolveBindingIdsForSession: () => resolveBindingIdsForSession,
27
+ resolveBindingRecordKey: () => resolveBindingRecordKey,
28
+ resolveThreadBindingIdleTimeoutMs: () => resolveThreadBindingIdleTimeoutMs,
29
+ resolveThreadBindingInactivityExpiresAt: () => resolveThreadBindingInactivityExpiresAt,
30
+ resolveThreadBindingMaxAgeExpiresAt: () => resolveThreadBindingMaxAgeExpiresAt,
31
+ resolveThreadBindingMaxAgeMs: () => resolveThreadBindingMaxAgeMs,
32
+ saveBindingsToDisk: () => saveBindingsToDisk,
33
+ setBindingRecord: () => setBindingRecord,
34
+ shouldDefaultPersist: () => shouldDefaultPersist,
35
+ shouldPersistBindingMutations: () => shouldPersistBindingMutations,
36
+ toBindingRecordKey: () => toBindingRecordKey,
37
+ toReusableWebhookKey: () => toReusableWebhookKey
38
+ });
6
39
  const THREAD_BINDINGS_STATE_KEY = Symbol.for("openclaw.discordThreadBindingsState");
7
40
  let threadBindingsState;
8
41
  function createThreadBindingsGlobalState() {
@@ -285,4 +318,4 @@ function resolveBindingIdsForSession(params) {
285
318
  return out;
286
319
  }
287
320
  //#endregion
288
- export { toReusableWebhookKey as A, resolveThreadBindingMaxAgeExpiresAt as C, shouldDefaultPersist as D, setBindingRecord as E, shouldPersistBindingMutations as O, resolveThreadBindingInactivityExpiresAt as S, saveBindingsToDisk as T, rememberThreadBindingToken as _, THREAD_BINDINGS_MAX_ENTRIES as a, resolveBindingRecordKey as b, ensureBindingsLoaded as c, normalizePersistedBinding as d, normalizeTargetKind as f, rememberReusableWebhook as g, refreshUnboundThreadWebhookIdentity as h, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as i, toBindingRecordKey as k, forgetThreadBindingToken as l, normalizeThreadId as m, MANAGERS_BY_ACCOUNT_ID as n, THREAD_BINDINGS_NAMESPACE as o, normalizeThreadBindingDurationMs as p, PERSIST_BY_ACCOUNT_ID as r, THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS as s, BINDINGS_BY_THREAD_ID as t, getThreadBindingToken as u, removeBindingRecord as v, resolveThreadBindingMaxAgeMs as w, resolveThreadBindingIdleTimeoutMs as x, resolveBindingIdsForSession as y };
321
+ export { setBindingRecord as C, toReusableWebhookKey as D, thread_bindings_state_exports as E, saveBindingsToDisk as S, shouldPersistBindingMutations as T, resolveBindingRecordKey as _, THREAD_BINDING_TOUCH_PERSIST_MIN_INTERVAL_MS as a, resolveThreadBindingMaxAgeExpiresAt as b, getThreadBindingToken as c, normalizeThreadId as d, refreshUnboundThreadWebhookIdentity as f, resolveBindingIdsForSession as g, removeBindingRecord as h, REUSABLE_WEBHOOKS_BY_ACCOUNT_CHANNEL as i, normalizeTargetKind as l, rememberThreadBindingToken as m, MANAGERS_BY_ACCOUNT_ID as n, ensureBindingsLoaded as o, rememberReusableWebhook as p, PERSIST_BY_ACCOUNT_ID as r, forgetThreadBindingToken as s, BINDINGS_BY_THREAD_ID as t, normalizeThreadBindingDurationMs as u, resolveThreadBindingIdleTimeoutMs as v, shouldDefaultPersist as w, resolveThreadBindingMaxAgeMs as x, resolveThreadBindingInactivityExpiresAt as y };
@@ -1,7 +1,7 @@
1
- import { F as DiscordError, Ot as editChannel, Tt as createThread, jt as getChannelMessage, on as __exportAll, y as discord_exports } from "./retry-Cv4jCU5Z.js";
1
+ import { Et as createThread, I as DiscordError, Mt as getChannelMessage, b as discord_exports, kt as editChannel, sn as __exportAll } from "./retry-DQt1zDgH.js";
2
2
  import { t as isDiscordThreadChannelType } from "./channel-type-CVLZyGYS.js";
3
- import { d as resolveDiscordChannelParentSafe, l as resolveDiscordChannelNameSafe, s as resolveDiscordChannelIdSafe, u as resolveDiscordChannelParentIdSafe } from "./thread-bindings.manager-ByOtwjo_.js";
4
- import { a as formatDiscordMediaText, f as resolveDiscordChannelInfo, n as resolveDiscordForwardedMessagesTextFromSnapshots, p as resolveDiscordMessageChannelId, t as resolveDiscordEmbedText } from "./message-text-aiwO5R2F.js";
3
+ import { d as resolveDiscordChannelParentSafe, l as resolveDiscordChannelNameSafe, s as resolveDiscordChannelIdSafe, u as resolveDiscordChannelParentIdSafe } from "./thread-bindings.manager-pbbRT5gb.js";
4
+ import { a as formatDiscordMediaText, h as resolveDiscordMessageChannelId, m as resolveDiscordChannelInfo, n as resolveDiscordForwardedMessagesTextFromSnapshots, t as resolveDiscordEmbedText } from "./message-text-DK4NnBg-.js";
5
5
  import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
6
6
  import { normalizeOptionalString, normalizeOptionalStringifiedId } from "openclaw/plugin-sdk/string-coerce-runtime";
7
7
  import { logVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -100,8 +100,8 @@ function normalizeTitleContextField(raw, maxChars) {
100
100
  }
101
101
  //#endregion
102
102
  //#region extensions/discord/src/monitor/threading.cache.ts
103
- const DISCORD_THREAD_STARTER_CACHE_TTL_MS = 300 * 1e3;
104
- const DISCORD_THREAD_STARTER_NEGATIVE_CACHE_TTL_MS = 30 * 1e3;
103
+ const DISCORD_THREAD_STARTER_CACHE_TTL_MS = 3e5;
104
+ const DISCORD_THREAD_STARTER_NEGATIVE_CACHE_TTL_MS = 3e4;
105
105
  const DISCORD_THREAD_STARTER_CACHE_MAX = 500;
106
106
  const DISCORD_THREAD_STARTER_CACHE = /* @__PURE__ */ new Map();
107
107
  function getCachedThreadStarter(key, now) {
@@ -266,7 +266,9 @@ function resolveDiscordReplyTarget(opts) {
266
266
  return opts.hasReplied ? void 0 : replyToId;
267
267
  }
268
268
  function sanitizeDiscordThreadName(rawName, fallbackId) {
269
- return truncateUtf16Safe(truncateUtf16Safe(rawName.replace(/<@!?\d+>/g, "").replace(/<@&\d+>/g, "").replace(/<#\d+>/g, "").replace(/\s+/g, " ").trim() || `Thread ${fallbackId}`, 80), 100) || `Thread ${fallbackId}`;
269
+ const baseSource = rawName.replace(/<@!?\d+>/g, "").replace(/<@&\d+>/g, "").replace(/<#\d+>/g, "").replace(/\s+/g, " ").trim() || `Thread ${fallbackId}`;
270
+ const base = truncateUtf16Safe(baseSource, 80);
271
+ return truncateUtf16Safe(base, 100) || `Thread ${fallbackId}`;
270
272
  }
271
273
  function resolveDiscordReplyDeliveryPlan(params) {
272
274
  const originalReplyTarget = params.replyTarget;
@@ -1,7 +1,7 @@
1
1
  import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
2
2
  //#region extensions/discord/src/monitor/timeouts.ts
3
3
  const DISCORD_DEFAULT_LISTENER_TIMEOUT_MS = 12e4;
4
- const DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS = 30 * 6e4;
4
+ const DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS = 18e5;
5
5
  const DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS = 6e4;
6
6
  const DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS = 12e4;
7
7
  /** @deprecated Discord listener timeouts are compatibility-only. */
@@ -1,6 +1,6 @@
1
- import { on as __exportAll } from "./retry-Cv4jCU5Z.js";
2
- import { a as listEnabledDiscordAccounts, c as resolveDiscordAccount } from "./accounts-CfQ-vSyf.js";
3
- import { n as resolveDiscordVoiceEnabled, r as authorizeDiscordVoiceIngress, t as resolveDiscordVoiceAccess } from "./owner-access-UlYi9t0M.js";
1
+ import { sn as __exportAll } from "./retry-DQt1zDgH.js";
2
+ import { a as listEnabledDiscordAccounts, c as resolveDiscordAccount } from "./accounts-CwJQoLjM.js";
3
+ import { n as resolveDiscordVoiceEnabled, r as authorizeDiscordVoiceIngress, t as resolveDiscordVoiceAccess } from "./owner-access-Cp8r6Ipf.js";
4
4
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
5
5
  import { summarizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
@@ -77,7 +77,7 @@ const resolveDiscordTranscriptsAccountId = ({ cfg, source }) => {
77
77
  async function waitForManager(request) {
78
78
  const accountResolution = resolveDiscordTranscriptsAccountId({
79
79
  cfg: request.cfg,
80
- source: request.session.source
80
+ source: request.source
81
81
  });
82
82
  if (!accountResolution.ok) return accountResolution;
83
83
  const accountId = accountResolution.value;
@@ -182,7 +182,7 @@ const discordVoiceTranscriptsSourceProvider = {
182
182
  },
183
183
  name: "Discord Voice",
184
184
  sourceKinds: ["live-audio"],
185
- async start(request) {
185
+ async watchOccupancy(request) {
186
186
  const managerResolution = await waitForManager(request);
187
187
  if (!managerResolution.ok) return managerResolution;
188
188
  const manager = managerResolution.value;
@@ -190,6 +190,45 @@ const discordVoiceTranscriptsSourceProvider = {
190
190
  ok: false,
191
191
  error: "Discord voice manager is not available."
192
192
  };
193
+ if (request.abortSignal?.aborted) return {
194
+ ok: false,
195
+ error: "Discord transcripts occupancy watch aborted."
196
+ };
197
+ const guildId = request.source.guildId?.trim();
198
+ const channelId = request.source.channelId?.trim();
199
+ if (!guildId || !channelId) return {
200
+ ok: false,
201
+ error: "Discord transcripts require guildId and channelId."
202
+ };
203
+ const unsubscribe = manager.watchChannelOccupancy({
204
+ guildId,
205
+ channelId
206
+ }, ({ occupied }) => {
207
+ if (occupied) request.onOccupied();
208
+ else request.onEmpty();
209
+ });
210
+ const stop = () => {
211
+ unsubscribe();
212
+ request.abortSignal?.removeEventListener("abort", stop);
213
+ };
214
+ request.abortSignal?.addEventListener("abort", stop, { once: true });
215
+ if (request.abortSignal?.aborted) stop();
216
+ return {
217
+ ok: true,
218
+ value: { stop }
219
+ };
220
+ },
221
+ async start(request) {
222
+ const managerResolution = await waitForManager({
223
+ ...request,
224
+ source: request.session.source
225
+ });
226
+ if (!managerResolution.ok) return managerResolution;
227
+ const manager = managerResolution.value;
228
+ if (!manager) return {
229
+ ok: false,
230
+ error: "Discord voice manager is not available."
231
+ };
193
232
  if (request.abortSignal?.aborted) return {
194
233
  ok: false,
195
234
  error: "Discord transcripts start aborted."
@@ -205,15 +244,24 @@ const discordVoiceTranscriptsSourceProvider = {
205
244
  channelId
206
245
  }, { transcripts: {
207
246
  sessionId: request.session.sessionId,
208
- onUtterance: request.onUtterance
247
+ onUtterance: request.onUtterance,
248
+ onStop: () => request.onStatus?.({
249
+ sessionId: request.session.sessionId,
250
+ active: false,
251
+ source: request.session.source
252
+ })
209
253
  } });
210
254
  if (!joined.ok) return {
211
255
  ok: false,
212
256
  error: joined.message
213
257
  };
258
+ const title = joined.channelName?.trim();
214
259
  return {
215
260
  ok: true,
216
- session: request.session
261
+ session: !request.session.title && title ? {
262
+ ...request.session,
263
+ title
264
+ } : request.session
217
265
  };
218
266
  },
219
267
  async stop(request) {
@@ -1,4 +1,4 @@
1
- import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-BR11iHA4.js";
1
+ import { t as discordVoiceTranscriptsSourceProvider } from "./transcripts-source-Dc6Nnli5.js";
2
2
  //#region extensions/discord/transcripts-source-api.ts
3
3
  function registerDiscordTranscriptSourceProvider(api) {
4
4
  api.registerTranscriptSourceProvider(discordVoiceTranscriptsSourceProvider);
@@ -1,5 +1,5 @@
1
- import { Rt as sendChannelTyping, on as __exportAll } from "./retry-Cv4jCU5Z.js";
2
- import { c as raceWithTimeout } from "./timeouts-B9cy6RvQ.js";
1
+ import { sn as __exportAll, zt as sendChannelTyping } from "./retry-DQt1zDgH.js";
2
+ import { c as raceWithTimeout } from "./timeouts-D86uWLt_.js";
3
3
  //#region extensions/discord/src/monitor/typing.ts
4
4
  var typing_exports = /* @__PURE__ */ __exportAll({ sendTyping: () => sendTyping });
5
5
  const DISCORD_TYPING_START_TIMEOUT_MS = 5e3;