@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,13 +1,12 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-B4FMCO8f.mjs";
2
- import { _ as restoreDiscordAudioError, f as writeVoiceWavFile, i as noteVoiceDecryptFailure, n as analyzeVoiceReceiveError, o as resetVoiceReceiveRecoveryState, t as DECRYPT_FAILURE_WINDOW_MS } from "./receive-recovery-eVmK2_hl.mjs";
2
+ import { f as writeVoiceWavFile, h as restoreDiscordAudioError, i as noteVoiceDecryptFailure, n as analyzeVoiceReceiveError, o as resetVoiceReceiveRecoveryState, t as DECRYPT_FAILURE_WINDOW_MS } from "./receive-recovery-CKvaG2Hf.mjs";
3
3
  import { S as formatDiscordUserTag, g as resolveDiscordOwnerAccess, o as normalizeDiscordSlug } from "./allow-list-B_ToXtew.mjs";
4
- import { f as VoiceStateUpdateListener, t as discord_exports, vt as getGuildVoiceState, z as isUnknownDiscordVoiceStateError } from "./discord-BGqgx-yd.mjs";
4
+ import { B as isUnknownDiscordVoiceStateError, f as VoiceStateUpdateListener, t as discord_exports, yt as getGuildVoiceState } from "./discord-Cl2OPTZ6.mjs";
5
5
  import { t as parseDiscordTarget } from "./target-parsing-C-HyNxcE.mjs";
6
- import { o as formatMention } from "./send.outbound-_jx4Xpd3.mjs";
6
+ import { s as formatMention } from "./send.outbound-B5vQwgUK.mjs";
7
7
  import { t as getDiscordRuntime } from "./runtime-DgnVQ7zW.mjs";
8
- import { C as buildDiscordGroupSystemPrompt, _ as isDiscordRealtimeVoiceMode, b as resolveDiscordVoiceMode, g as VOICE_RECONNECT_GRACE_MS, h as VOICE_CONNECT_READY_TIMEOUT_MS, m as MIN_SEGMENT_SECONDS, p as CAPTURE_FINALIZE_GRACE_MS, v as isVoiceChannel, x as resolveVoiceTimeoutMs, y as logVoiceVerbose } from "./provider-CbmXLYrW.mjs";
9
- import { a as authorizeDiscordVoiceIngress, c as resolveDiscordVoiceEnabled, o as resolveDiscordVoiceAccess, r as resolveDiscordTranscriptsCapture, s as resolveDiscordVoiceAccessTarget, t as bindDiscordCaptureReceipts } from "./transcripts-source-EMrQb132.mjs";
10
- import { Worker } from "node:worker_threads";
8
+ import { C as buildDiscordGroupSystemPrompt, _ as isDiscordRealtimeVoiceMode, b as resolveDiscordVoiceMode, g as VOICE_RECONNECT_GRACE_MS, h as VOICE_CONNECT_READY_TIMEOUT_MS, m as MIN_SEGMENT_SECONDS, p as CAPTURE_FINALIZE_GRACE_MS, v as isVoiceChannel, x as resolveVoiceTimeoutMs, y as logVoiceVerbose } from "./provider-DUTsZJHz.mjs";
9
+ import { a as authorizeDiscordVoiceIngress, c as resolveDiscordVoiceEnabled, o as resolveDiscordVoiceAccess, r as resolveDiscordTranscriptsCapture, s as resolveDiscordVoiceAccessTarget, t as bindDiscordCaptureReceipts } from "./transcripts-source-fRvFsZng.mjs";
11
10
  import { PassThrough, Readable } from "node:stream";
12
11
  import { formatErrorMessage, readErrorName, toErrorObject, toStringifiedError } from "openclaw/plugin-sdk/error-runtime";
13
12
  import { createSubsystemLogger, logVerbose } from "openclaw/plugin-sdk/runtime-env";
@@ -15,7 +14,6 @@ import { resolveAgentRoute } from "openclaw/plugin-sdk/routing";
15
14
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
16
15
  import { unlinkIfExists } from "openclaw/plugin-sdk/media-runtime";
17
16
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
18
- import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
19
17
  import { stripInlineDirectiveTagsForDisplay } from "openclaw/plugin-sdk/text-chunking";
20
18
  import { randomUUID } from "node:crypto";
21
19
  import { formatErrorMessage as formatErrorMessage$1 } from "openclaw/plugin-sdk/ssrf-runtime";
@@ -25,10 +23,8 @@ import { resolveAgentDir } from "openclaw/plugin-sdk/agent-scope-runtime";
25
23
  import { enqueueRoutedSystemEvent } from "openclaw/plugin-sdk/system-event-runtime";
26
24
  import { EventEmitter } from "node:events";
27
25
  import { controlRealtimeVoiceAgentRun, parseRealtimeVoiceAgentControlToolArgs, shouldAutoControlRealtimeVoiceAgentText } from "openclaw/plugin-sdk/realtime-voice";
28
- import * as realtimeBootstrapSdk from "openclaw/plugin-sdk/realtime-bootstrap-context";
29
- import { resolveRealtimeBootstrapContextInstructions } from "openclaw/plugin-sdk/realtime-bootstrap-context";
30
- import * as processRuntimeSdk from "openclaw/plugin-sdk/process-runtime";
31
- import { resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "openclaw/plugin-sdk/process-runtime";
26
+ import { resolveRealtimeVoiceAgentContextInstructions } from "openclaw/plugin-sdk/realtime-bootstrap-context";
27
+ import { createCpuTrackedWorker, resolveRuntimeWorkerArgv, resolveRuntimeWorkerUrl } from "openclaw/plugin-sdk/process-runtime";
32
28
  //#region extensions/discord/src/voice/log-preview.ts
33
29
  const DISCORD_VOICE_LOG_PREVIEW_CHARS = 500;
34
30
  function formatVoiceLogPreview(text) {
@@ -330,7 +326,6 @@ var DiscordRealtimeRecording = class {
330
326
  //#region extensions/discord/src/voice/ingress.ts
331
327
  const DISCORD_VOICE_MESSAGE_PROVIDER = "discord-voice";
332
328
  const logger$9 = createSubsystemLogger("discord/voice");
333
- const contextSdk = realtimeBootstrapSdk;
334
329
  function summarizeAgentTurnPayloads(payloads) {
335
330
  const nonEmptyTextPayloads = payloads.filter((payload) => payload.text.trim()).length;
336
331
  const errorPayloads = payloads.filter((payload) => payload.isError === true).length;
@@ -418,17 +413,7 @@ async function resolveDiscordVoiceRealtimeAgentContext(params) {
418
413
  files: params.discordConfig.voice?.realtime?.bootstrapContextFiles,
419
414
  warn: (message) => logger$9.warn(`discord voice: realtime agent context: ${message}`)
420
415
  };
421
- if (contextSdk.resolveRealtimeVoiceAgentContextInstructions) return await contextSdk.resolveRealtimeVoiceAgentContextInstructions(contextParams);
422
- if (contextParams.files?.length === 0) return;
423
- try {
424
- return await resolveRealtimeBootstrapContextInstructions({
425
- ...contextParams,
426
- warn: (message) => logger$9.warn(`discord voice: realtime bootstrap context: ${message}`)
427
- });
428
- } catch (error) {
429
- logger$9.warn(`discord voice: realtime bootstrap context unavailable: ${error instanceof Error ? error.message : String(error)}`);
430
- return;
431
- }
416
+ return await resolveRealtimeVoiceAgentContextInstructions(contextParams);
432
417
  }
433
418
  //#endregion
434
419
  //#region extensions/discord/src/voice/participant-context.ts
@@ -737,9 +722,7 @@ var DiscordVoiceSpeakerContextResolver = class {
737
722
  const key = `${guildId}:${userId}`;
738
723
  const cached = this.cache.get(key);
739
724
  if (cached) {
740
- const now = asDateTimestampMs(Date.now());
741
- const expiresAt = asDateTimestampMs(cached.expiresAt);
742
- if (now !== void 0 && expiresAt !== void 0 && expiresAt > now) return { ...cached.context };
725
+ if (cached.expiresAt > Date.now()) return { ...cached.context };
743
726
  this.cache.delete(key);
744
727
  }
745
728
  const identity = await this.resolveIdentity(guildId, userId);
@@ -754,10 +737,9 @@ var DiscordVoiceSpeakerContextResolver = class {
754
737
  allowNameMatching: false
755
738
  }).ownerAllowed
756
739
  };
757
- const expiresAt = resolveExpiresAtMsFromDurationMs(SPEAKER_CONTEXT_CACHE_TTL_MS);
758
- if (expiresAt !== void 0) this.cache.set(key, {
740
+ this.cache.set(key, {
759
741
  context: { ...context },
760
- expiresAt
742
+ expiresAt: Date.now() + SPEAKER_CONTEXT_CACHE_TTL_MS
761
743
  });
762
744
  return context;
763
745
  }
@@ -820,19 +802,13 @@ function logFollowUserReconcileVerbose(reason, message) {
820
802
  }
821
803
  logVoiceVerbose(message);
822
804
  }
823
- function cyclicId(ids, index, label) {
824
- return expectDefined(ids[index % ids.length], label);
825
- }
826
805
  var DiscordVoiceFollowing = class {
827
806
  constructor(params) {
828
807
  this.params = params;
829
808
  this.followedUserChannels = /* @__PURE__ */ new Map();
830
809
  this.followedVoiceGuilds = /* @__PURE__ */ new Set();
831
810
  this.followUsersReconcileTask = null;
832
- this.followUsersReconcileGuildCursor = 0;
833
- this.followUsersReconcileBotGuildCursor = 0;
834
- this.followUsersReconcileUserCursors = /* @__PURE__ */ new Map();
835
- this.followEventGenerations = /* @__PURE__ */ new Map();
811
+ this.reconcileCursor = 0;
836
812
  this.scheduler = params.scheduler.scope();
837
813
  this.followUserIds = params.discordConfig.voice?.followUsersEnabled !== false ? normalizeDiscordUserIds(params.discordConfig.voice?.followUsers) : /* @__PURE__ */ new Set();
838
814
  }
@@ -882,9 +858,6 @@ var DiscordVoiceFollowing = class {
882
858
  if (!this.params.voiceEnabled || this.scheduler.signal.aborted) return;
883
859
  const { guildId, channelId, userId } = params;
884
860
  const followKey = `${guildId}:${userId}`;
885
- const eventGeneration = (this.followEventGenerations.get(followKey) ?? 0) + 1;
886
- this.followEventGenerations.set(followKey, eventGeneration);
887
- const isCurrentEvent = () => this.followEventGenerations.get(followKey) === eventGeneration;
888
861
  const previousFollowedChannelId = this.followedUserChannels.get(followKey)?.channelId;
889
862
  const existing = this.params.getSession(guildId);
890
863
  const wasFollowedVoiceSession = this.followedUserChannels.has(followKey) || this.followedVoiceGuilds.has(guildId);
@@ -903,10 +876,11 @@ var DiscordVoiceFollowing = class {
903
876
  else if (!channelId && !existing && wasFollowedVoiceSession && this.params.hasVoiceLifecycle(guildId)) await this.params.leave({ guildId });
904
877
  return;
905
878
  }
906
- this.followedUserChannels.set(followKey, {
879
+ const followedChannel = {
907
880
  guildId,
908
881
  channelId
909
- });
882
+ };
883
+ this.followedUserChannels.set(followKey, followedChannel);
910
884
  if (existing?.channelId === channelId) {
911
885
  this.followedVoiceGuilds.add(guildId);
912
886
  return;
@@ -924,7 +898,7 @@ var DiscordVoiceFollowing = class {
924
898
  guildId,
925
899
  channelId
926
900
  }, { preserveFollowState: true });
927
- if (!isCurrentEvent()) return;
901
+ if (this.followedUserChannels.get(followKey) !== followedChannel) return;
928
902
  if (!result.ok) {
929
903
  if (this.params.getSession(guildId)?.channelId === channelId) this.followedVoiceGuilds.add(guildId);
930
904
  else this.followedUserChannels.delete(followKey);
@@ -938,7 +912,6 @@ var DiscordVoiceFollowing = class {
938
912
  await this.followUsersReconcileTask;
939
913
  this.followedUserChannels.clear();
940
914
  this.followedVoiceGuilds.clear();
941
- this.followEventGenerations.clear();
942
915
  }
943
916
  isFollowOwnedGuild(guildId) {
944
917
  return this.followedVoiceGuilds.has(guildId) || Array.from(this.followedUserChannels.values()).some((entry) => entry.guildId === guildId);
@@ -972,79 +945,35 @@ var DiscordVoiceFollowing = class {
972
945
  return;
973
946
  }
974
947
  logFollowUserReconcileVerbose(reason, `follow user reconcile reason=${reason}: ${this.followUserIds.size} users across ${guildIds.length} guilds`);
975
- const plans = this.selectFollowUserReconcilePlans(guildIds, reason);
976
- for (const plan of plans) {
977
- for (const userId of plan.userIds) {
978
- const voiceState = await this.readReconcileVoiceState(plan.guildId, userId, reason);
979
- if (this.scheduler.signal.aborted) return;
980
- if (voiceState === "transient-error") continue;
981
- const channelId = voiceState?.channel_id?.trim();
982
- await this.handleFollowedUserVoiceStateUpdate({
983
- guildId: plan.guildId,
984
- channelId,
985
- userId
986
- });
987
- }
988
- if (plan.checkBotVoiceState) {
989
- if (this.scheduler.signal.aborted) return;
948
+ const userIds = [...this.followUserIds];
949
+ const slotsPerGuild = userIds.length + (this.params.botUserId() ? 1 : 0);
950
+ const totalSlots = guildIds.length * slotsPerGuild;
951
+ const start = this.reconcileCursor % totalSlots;
952
+ const visitedGuilds = /* @__PURE__ */ new Set();
953
+ for (let offset = 0; offset < Math.min(totalSlots, FOLLOW_USERS_RECONCILE_MAX_REST_LOOKUPS_PER_RUN); offset += 1) {
954
+ if (this.scheduler.signal.aborted) return;
955
+ const slot = (start + offset) % totalSlots;
956
+ const guildId = expectDefined(guildIds[Math.floor(slot / slotsPerGuild)], "voice reconciliation guild");
957
+ if (!visitedGuilds.has(guildId) && visitedGuilds.size >= FOLLOW_USERS_RECONCILE_MAX_GUILDS_PER_RUN) break;
958
+ visitedGuilds.add(guildId);
959
+ this.reconcileCursor = (slot + 1) % totalSlots;
960
+ const userIndex = slot % slotsPerGuild;
961
+ if (userIndex === userIds.length) {
990
962
  await this.disconnectStaleFollowedBotVoiceState({
991
- guildId: plan.guildId,
963
+ guildId,
992
964
  reason
993
965
  });
966
+ continue;
994
967
  }
995
- }
996
- }
997
- selectFollowUserReconcilePlans(guildIds, reason) {
998
- const followedUserIds = Array.from(this.followUserIds);
999
- if (followedUserIds.length === 0) return [];
1000
- let remainingLookups = FOLLOW_USERS_RECONCILE_MAX_REST_LOOKUPS_PER_RUN;
1001
- const guildLimit = Math.min(guildIds.length, FOLLOW_USERS_RECONCILE_MAX_GUILDS_PER_RUN);
1002
- const start = this.followUsersReconcileGuildCursor % guildIds.length;
1003
- const plans = [];
1004
- for (let offset = 0; offset < guildLimit && remainingLookups > 0; offset += 1) {
1005
- if (this.params.botUserId() && remainingLookups === 1) break;
1006
- const guildId = cyclicId(guildIds, start + offset, "voice reconciliation guild index");
1007
- let userLimit = Math.min(followedUserIds.length, remainingLookups);
1008
- if (this.params.botUserId() && followedUserIds.length > userLimit && remainingLookups > 1) userLimit = remainingLookups - 1;
1009
- if (userLimit <= 0) break;
1010
- const selection = this.selectFollowUserReconcileUserIds(guildId, followedUserIds, userLimit);
1011
- plans.push({
968
+ const userId = expectDefined(userIds[userIndex], "voice reconciliation user");
969
+ const voiceState = await this.readReconcileVoiceState(guildId, userId, reason);
970
+ if (this.scheduler.signal.aborted) return;
971
+ if (voiceState !== "transient-error") await this.handleFollowedUserVoiceStateUpdate({
1012
972
  guildId,
1013
- userIds: selection.userIds,
1014
- checkedAllUsers: selection.completedCycle,
1015
- checkBotVoiceState: false
973
+ channelId: voiceState?.channel_id?.trim(),
974
+ userId
1016
975
  });
1017
- remainingLookups -= selection.userIds.length;
1018
- }
1019
- this.followUsersReconcileGuildCursor = (start + plans.length) % guildIds.length;
1020
- this.assignFollowUserReconcileBotChecks(guildIds, plans, remainingLookups);
1021
- if (plans.length < guildIds.length || plans.some((plan) => plan.userIds.length < followedUserIds.length)) logVoiceVerbose(`follow user reconcile reason=${reason}: sampling ${plans.length}/${guildIds.length} guilds and up to ${FOLLOW_USERS_RECONCILE_MAX_REST_LOOKUPS_PER_RUN} REST lookups`);
1022
- return plans;
1023
- }
1024
- assignFollowUserReconcileBotChecks(guildIds, plans, remainingLookups) {
1025
- if (!this.params.botUserId() || remainingLookups <= 0 || plans.length === 0) return;
1026
- const plansByGuild = new Map(plans.map((plan) => [plan.guildId, plan]));
1027
- const start = this.followUsersReconcileBotGuildCursor % guildIds.length;
1028
- let scanned = 0;
1029
- let assigned = 0;
1030
- for (; scanned < guildIds.length && assigned < remainingLookups; scanned += 1) {
1031
- const guildId = cyclicId(guildIds, start + scanned, "bot voice reconciliation guild index");
1032
- const plan = plansByGuild.get(guildId);
1033
- if (!plan?.checkedAllUsers) continue;
1034
- plan.checkBotVoiceState = true;
1035
- assigned += 1;
1036
- }
1037
- this.followUsersReconcileBotGuildCursor = (start + scanned) % guildIds.length;
1038
- }
1039
- selectFollowUserReconcileUserIds(guildId, followedUserIds, limit) {
1040
- const start = followedUserIds.length <= limit ? 0 : this.followUsersReconcileUserCursors.get(guildId) ?? 0;
1041
- const selected = Array.from({ length: Math.min(Math.ceil(limit), followedUserIds.length) }, (_, offset) => cyclicId(followedUserIds, start + offset, "followed user selection index"));
1042
- const completedCycle = start + selected.length >= followedUserIds.length;
1043
- this.followUsersReconcileUserCursors.set(guildId, (start + selected.length) % followedUserIds.length);
1044
- return {
1045
- userIds: selected,
1046
- completedCycle
1047
- };
976
+ }
1048
977
  }
1049
978
  hasFollowedUserInChannel(entry) {
1050
979
  return Array.from(this.followedUserChannels.values()).some((candidate) => candidate.guildId === entry.guildId && candidate.channelId === entry.channelId);
@@ -1857,7 +1786,6 @@ var DiscordVoiceReceive = class {
1857
1786
  };
1858
1787
  //#endregion
1859
1788
  //#region extensions/discord/src/voice/audio-worker-thread.ts
1860
- const workerSdk = processRuntimeSdk;
1861
1789
  /** Source, core-bundled and standalone plugin workers use the same launch owner. */
1862
1790
  function createDiscordAudioWorkerThread(options) {
1863
1791
  const url = resolveRuntimeWorkerUrl({
@@ -1873,7 +1801,7 @@ function createDiscordAudioWorkerThread(options) {
1873
1801
  workerData: options,
1874
1802
  execArgv: resolveRuntimeWorkerArgv(url).slice(0, -1)
1875
1803
  };
1876
- return workerSdk.createCpuTrackedWorker ? workerSdk.createCpuTrackedWorker(url, workerOptions) : new Worker(url, workerOptions);
1804
+ return createCpuTrackedWorker(url, workerOptions);
1877
1805
  }
1878
1806
  //#endregion
1879
1807
  //#region extensions/discord/src/voice/audio-transport.ts
@@ -2473,7 +2401,10 @@ var DiscordVoiceSessions = class {
2473
2401
  }
2474
2402
  if (existing) {
2475
2403
  logVoiceVerbose(`join: replacing existing session for guild ${guildId}`);
2476
- await this.leave({ guildId }, { preserveFollowState: options?.preserveFollowState });
2404
+ await this.leave({ guildId }, {
2405
+ preserveFollowState: options?.preserveFollowState,
2406
+ disposition: "abort"
2407
+ });
2477
2408
  }
2478
2409
  const resolved = await this.resolveChannel(params);
2479
2410
  if (authority && !authority.isCurrent()) return failedJoinResult("Discord voice join was cancelled.");
@@ -2535,7 +2466,7 @@ var DiscordVoiceSessions = class {
2535
2466
  const { route, voiceRoute, agentSessionMode, agentSessionTarget } = routeInfo;
2536
2467
  logger$2.info(`discord voice: joining guild=${guildId} channel=${channelId} mode=${voiceMode} agent=${route.agentId} voiceSession=${voiceRoute.sessionKey} supervisorSession=${route.sessionKey} agentSessionMode=${agentSessionMode}${agentSessionTarget ? ` agentSessionTarget=${agentSessionTarget}` : ""} voiceModel=${voiceConfig?.model ?? "route-default"} realtimeProvider=${voiceConfig?.realtime?.provider ?? "auto"} realtimeModel=${voiceConfig?.realtime?.model ?? "provider-default"} realtimeVoice=${voiceConfig?.realtime?.speakerVoice ?? voiceConfig?.realtime?.speakerVoiceId ?? "provider-default"}`);
2537
2468
  let stopCompletion;
2538
- const stopEntry = (reason) => {
2469
+ const stopEntry = (reason, disposition = "abort") => {
2539
2470
  if (entry.sessionLifecycle.status === "stopped") return stopCompletion;
2540
2471
  entry.sessionLifecycle = {
2541
2472
  status: "stopped",
@@ -2554,7 +2485,7 @@ var DiscordVoiceSessions = class {
2554
2485
  };
2555
2486
  let realtimeCompletion = void 0;
2556
2487
  try {
2557
- if (realtimeLifecycle.status === "starting" || realtimeLifecycle.status === "active") realtimeCompletion = realtimeLifecycle.instance.close();
2488
+ if (realtimeLifecycle.status === "starting" || realtimeLifecycle.status === "active") realtimeCompletion = realtimeLifecycle.instance.close(disposition);
2558
2489
  } catch (error) {
2559
2490
  logger$2.warn(`discord voice: realtime close failed: ${formatErrorMessage$1(error)}`);
2560
2491
  }
@@ -2606,8 +2537,8 @@ var DiscordVoiceSessions = class {
2606
2537
  status: "inactive",
2607
2538
  generation: 0
2608
2539
  },
2609
- stop(reason) {
2610
- return stopEntry(reason ?? `stop guild ${guildId} channel ${channelId}`);
2540
+ stop(reason, disposition) {
2541
+ return stopEntry(reason ?? `stop guild ${guildId} channel ${channelId}`, disposition);
2611
2542
  }
2612
2543
  };
2613
2544
  const speakingHandler = (userId, speaking) => {
@@ -2617,7 +2548,7 @@ var DiscordVoiceSessions = class {
2617
2548
  else this.params.receive.scheduleCaptureFinalize(entry, userId);
2618
2549
  };
2619
2550
  const destroyedHandler = () => {
2620
- stopEntry("audio worker stopped");
2551
+ stopEntry("audio worker stopped", "text-fallback");
2621
2552
  };
2622
2553
  audio.on("stopped", destroyedHandler);
2623
2554
  if (!entry.captureOnly && isDiscordRealtimeVoiceMode(voiceMode)) {
@@ -2655,7 +2586,7 @@ var DiscordVoiceSessions = class {
2655
2586
  ok: false,
2656
2587
  message: "Not connected to that voice channel."
2657
2588
  };
2658
- const stopped = entry.stop();
2589
+ const stopped = entry.stop(void 0, options?.disposition ?? "text-fallback");
2659
2590
  if (!entry.receiveRecovery.decryptRecoveryInFlight) this.params.receive.daveRecoveryAttempts.delete(guildId);
2660
2591
  if (!options?.preserveFollowState) this.params.onLeaveFollowState(guildId);
2661
2592
  await stopped;
@@ -2677,7 +2608,7 @@ var DiscordVoiceSessions = class {
2677
2608
  ok: false,
2678
2609
  message: "Discord realtime voice session stopped before startup completed."
2679
2610
  };
2680
- const { DiscordRealtimeVoiceSession } = await import("./realtime-session.runtime-YCumnRSE.mjs");
2611
+ const { DiscordRealtimeVoiceSession } = await import("./realtime-session.runtime-bNnPOKP_.mjs");
2681
2612
  const realtime = new DiscordRealtimeVoiceSession({
2682
2613
  ...this.params,
2683
2614
  bootstrapContextInstructions,
@@ -2700,6 +2631,24 @@ var DiscordVoiceSessions = class {
2700
2631
  ...turn,
2701
2632
  entry
2702
2633
  }),
2634
+ deliverText: async (turn, text, signal) => {
2635
+ try {
2636
+ const context = await this.params.receive.resolveDiscordVoiceIngressContext(entry, turn.userId);
2637
+ const assertCurrent = () => {
2638
+ signal.throwIfAborted();
2639
+ if (!this.params.isSessionGenerationCurrent(entry) || !context || context.isCurrent?.() === false || context.senderIsOwner !== turn.context.senderIsOwner) throw new Error("Discord voice reply authorization is no longer current");
2640
+ };
2641
+ assertCurrent();
2642
+ const { sendMessageDiscord } = await import("./send.outbound-B5vQwgUK.mjs").then((n) => n.i);
2643
+ await sendMessageDiscord(`channel:${entry.channelId}`, text, {
2644
+ cfg: this.params.cfg,
2645
+ accountId: this.params.accountId,
2646
+ assertPlatformSendAuthorized: assertCurrent
2647
+ });
2648
+ } catch (error) {
2649
+ logger$2.warn(`discord voice: text fallback dropped guild=${entry.guildId} channel=${entry.channelId}: ${formatErrorMessage$1(error)}`);
2650
+ }
2651
+ },
2703
2652
  resolveSpeakerContext: (userId) => this.params.receive.resolveDiscordVoiceIngressContext(entry, userId)
2704
2653
  });
2705
2654
  const generation = entry.realtimeLifecycle.generation + 1;
@@ -2813,6 +2762,7 @@ var DiscordVoiceManager = class {
2813
2762
  this.fatalAutoJoinFailures = /* @__PURE__ */ new Map();
2814
2763
  this.occupancyWatchers = /* @__PURE__ */ new Set();
2815
2764
  this.destroyed = false;
2765
+ this.abort = new AbortController();
2816
2766
  this.client = params.client;
2817
2767
  this.readPolicy = params.readPolicy;
2818
2768
  this.botUserId = params.botUserId;
@@ -2869,6 +2819,8 @@ var DiscordVoiceManager = class {
2869
2819
  });
2870
2820
  this.voiceSessions = new DiscordVoiceSessions({
2871
2821
  ...params,
2822
+ signal: this.abort.signal,
2823
+ isSessionGenerationCurrent: (entry) => this.guildLifecycles.get(entry.guildId)?.generation === entry.generation,
2872
2824
  botUserId: () => this.botUserId,
2873
2825
  destroyed: () => this.destroyed,
2874
2826
  getTranscripts: this.getTranscripts,
@@ -3202,6 +3154,7 @@ var DiscordVoiceManager = class {
3202
3154
  }
3203
3155
  async destroy() {
3204
3156
  this.destroyed = true;
3157
+ this.abort.abort(/* @__PURE__ */ new Error("Discord voice manager stopped"));
3205
3158
  this.occupancyWatchers.clear();
3206
3159
  const followingStopped = this.following.destroy();
3207
3160
  for (const entry of this.sessions.values()) entry.stop();
@@ -1 +1 @@
1
- export { t as handleDiscordAction } from "./.setup/runtime-CRTkKU1G.mjs";
1
+ export { t as handleDiscordAction } from "./.setup/runtime-DE6W14G3.mjs";
@@ -1,9 +1,9 @@
1
1
  import { l as resolveDiscordAccount } from "./.setup/accounts-ljrzXBJi.mjs";
2
2
  import { D as getDiscordEndpointRuntime } from "./.setup/allow-list-B_ToXtew.mjs";
3
3
  import { n as resolveDiscordChannelId$1 } from "./.setup/target-parsing-C-HyNxcE.mjs";
4
- import { S as parseDiscordActivityCustomId, i as buildDiscordPresentationComponents } from "./.setup/components-HN9052L1.mjs";
5
- import { r as sendDiscordComponentMessage } from "./.setup/send.components-FxOS3CeP.mjs";
6
- import { r as setDiscordActivitiesRuntime, t as DiscordActivitiesRuntime } from "./.setup/runtime-DPm3gZXk.mjs";
4
+ import { S as parseDiscordActivityCustomId, i as buildDiscordPresentationComponents } from "./.setup/components-C_cuoW1q.mjs";
5
+ import { r as sendDiscordComponentMessage } from "./.setup/send.components--dxMjc2O.mjs";
6
+ import { r as setDiscordActivitiesRuntime, t as DiscordActivitiesRuntime } from "./.setup/runtime-Cg5pIBm_.mjs";
7
7
  import { asOptionalRecord, normalizeBoundedOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
8
8
  import { randomBytes } from "node:crypto";
9
9
  import { fetchWithSsrFGuard as fetchWithSsrFGuard$1 } from "openclaw/plugin-sdk/ssrf-runtime";
package/dist/api.js CHANGED
@@ -1,25 +1,25 @@
1
1
  import { c as resolveDefaultDiscordAccountId, d as resolveDiscordAccountConfig, i as listDiscordAccountIds, l as resolveDiscordAccount, m as resolveDiscordMaxLinesPerMessage, o as listEnabledDiscordAccounts, s as mergeDiscordAccountConfig, t as createDiscordActionGate } from "./.setup/accounts-ljrzXBJi.mjs";
2
2
  import { t as inspectDiscordAccount } from "./.setup/account-inspect-8cCu6uPG.mjs";
3
- import { d as normalizeDiscordMessagingTarget, f as normalizeDiscordOutboundTarget, l as looksLikeDiscordTargetId } from "./.setup/send.receipt-BAlzXd8e.mjs";
3
+ import { d as normalizeDiscordMessagingTarget, f as normalizeDiscordOutboundTarget, l as looksLikeDiscordTargetId } from "./.setup/send.receipt-eE3zLTDH.mjs";
4
4
  import { i as requestDiscord, n as DiscordApiError, r as fetchDiscord } from "./.setup/api-CtmE1OUN.mjs";
5
5
  import { n as resolveDiscordChannelId, t as parseDiscordTarget } from "./.setup/target-parsing-C-HyNxcE.mjs";
6
- import { n as resolveDiscordTarget } from "./.setup/target-resolver-Bse8fuTi.mjs";
6
+ import { n as resolveDiscordTarget } from "./.setup/target-resolver-BFOKmBni.mjs";
7
7
  import { i as DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, r as DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./.setup/timeouts-CuNARfyw.mjs";
8
- import "./.setup/targets-DZJjkzwv.mjs";
9
- import { D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, T as parseDiscordComponentCustomIdForInteraction, _ as DISCORD_COMPONENT_CUSTOM_ID_KEY, b as buildDiscordComponentCustomId, d as buildDiscordComponentMessage, f as buildDiscordComponentMessageFlags, g as resolveDiscordComponentAttachmentName, h as readDiscordComponentSpec, l as DiscordFormModal, n as formatDiscordComponentEventText, p as DISCORD_COMPONENT_ATTACHMENT_PREFIX, r as buildDiscordInteractiveComponents, u as createDiscordFormModal, v as DISCORD_MODAL_CUSTOM_ID_KEY, w as parseDiscordComponentCustomId, x as buildDiscordModalCustomId } from "./.setup/components-HN9052L1.mjs";
10
- import { D as isDiscordExecApprovalClientEnabled, E as isDiscordExecApprovalApprover, O as shouldSuppressLocalDiscordExecApprovalPrompt, T as getDiscordExecApprovalApprovers } from "./.setup/outbound-session-route-iwnu6IK8.mjs";
11
- import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./.setup/channel-C24afwHP.mjs";
8
+ import "./.setup/targets-UbCpek5o.mjs";
9
+ import { D as parseDiscordModalCustomIdForInteraction, E as parseDiscordModalCustomId, T as parseDiscordComponentCustomIdForInteraction, _ as DISCORD_COMPONENT_CUSTOM_ID_KEY, b as buildDiscordComponentCustomId, d as buildDiscordComponentMessage, f as buildDiscordComponentMessageFlags, g as resolveDiscordComponentAttachmentName, h as readDiscordComponentSpec, l as DiscordFormModal, n as formatDiscordComponentEventText, p as DISCORD_COMPONENT_ATTACHMENT_PREFIX, r as buildDiscordInteractiveComponents, u as createDiscordFormModal, v as DISCORD_MODAL_CUSTOM_ID_KEY, w as parseDiscordComponentCustomId, x as buildDiscordModalCustomId } from "./.setup/components-C_cuoW1q.mjs";
10
+ import { A as isDiscordExecApprovalClientEnabled, O as getDiscordExecApprovalApprovers, j as shouldSuppressLocalDiscordExecApprovalPrompt, k as isDiscordExecApprovalApprover } from "./.setup/outbound-session-route-CsHHPxsQ.mjs";
11
+ import { i as resolveDiscordGroupToolPolicy, n as collectDiscordStatusIssues, r as resolveDiscordGroupRequireMention, t as discordPlugin } from "./.setup/channel-BlvyeRAu.mjs";
12
12
  import { t as normalizeExplicitDiscordSessionKey } from "./.setup/session-key-normalization-CCHGNSQw.mjs";
13
- import { t as discordSetupPlugin } from "./.setup/channel.setup-B3KEh05g.mjs";
14
- import { n as handleDiscordSubagentEnded, t as handleDiscordSubagentDeliveryTarget } from "./.setup/subagent-hooks-CME7dSGf.mjs";
15
- import { t as tryHandleDiscordMessageActionGuildAdmin } from "./.setup/handle-action.guild-admin-Aw-vutu3.mjs";
13
+ import { t as discordSetupPlugin } from "./.setup/channel.setup-By7wNopw.mjs";
14
+ import { n as handleDiscordSubagentDeliveryTargetAsync, r as handleDiscordSubagentEnded, t as handleDiscordSubagentDeliveryTarget } from "./.setup/subagent-hooks-tBtaqWkD.mjs";
15
+ import { t as tryHandleDiscordMessageActionGuildAdmin } from "./.setup/handle-action.guild-admin-DfAWANBE.mjs";
16
16
  import { n as listDiscordDirectoryGroupsFromConfig, r as listDiscordDirectoryPeersFromConfig } from "./.setup/directory-config-3iVub-3m.mjs";
17
17
  import { t as fetchPluralKitMessageInfo } from "./.setup/pluralkit-B64dfq_j.mjs";
18
18
  import { i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, s as resolveDiscordPrivilegedIntentsFromFlags, t as fetchDiscordApplicationId } from "./.setup/probe-D3P1x4aN.mjs";
19
19
  import { t as collectDiscordSecurityAuditFindings } from "./.setup/security-audit-BFT84Uny.mjs";
20
20
  import { resolveOpenProviderRuntimeGroupPolicy as resolveDiscordRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
21
21
  //#region extensions/discord/api.ts
22
- const handleDiscordMessageAction = async (...args) => (await import("./.setup/handle-action-CsQmpfGZ.mjs")).handleDiscordMessageAction(...args);
22
+ const handleDiscordMessageAction = async (...args) => (await import("./.setup/handle-action-0-FZD3Am.mjs")).handleDiscordMessageAction(...args);
23
23
  /**
24
24
  * @deprecated Shipped `@openclaw/discord/api` compatibility only. Use native
25
25
  * `AbortSignal.any` after filtering optional signals. Removal with the next
@@ -30,4 +30,4 @@ function mergeAbortSignals(signals) {
30
30
  return activeSignals.length > 1 ? AbortSignal.any(activeSignals) : activeSignals[0];
31
31
  }
32
32
  //#endregion
33
- export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_COMPONENT_ATTACHMENT_PREFIX, DISCORD_COMPONENT_CUSTOM_ID_KEY, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_MODAL_CUSTOM_ID_KEY, DiscordApiError, DiscordFormModal, buildDiscordComponentCustomId, buildDiscordComponentMessage, buildDiscordComponentMessageFlags, buildDiscordInteractiveComponents, buildDiscordModalCustomId, collectDiscordSecurityAuditFindings, collectDiscordStatusIssues, createDiscordActionGate, createDiscordFormModal, discordPlugin, discordSetupPlugin, fetchDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchPluralKitMessageInfo, formatDiscordComponentEventText, getDiscordExecApprovalApprovers, handleDiscordMessageAction, handleDiscordSubagentDeliveryTarget, handleDiscordSubagentEnded, inspectDiscordAccount, isDiscordExecApprovalApprover, isDiscordExecApprovalClientEnabled, listDiscordAccountIds, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, listEnabledDiscordAccounts, looksLikeDiscordTargetId, mergeAbortSignals, mergeDiscordAccountConfig, normalizeDiscordMessagingTarget, normalizeDiscordOutboundTarget, normalizeExplicitDiscordSessionKey, parseApplicationIdFromToken, parseDiscordComponentCustomId, parseDiscordComponentCustomIdForInteraction as parseDiscordComponentCustomIdForCarbon, parseDiscordComponentCustomIdForInteraction, parseDiscordModalCustomId, parseDiscordModalCustomIdForInteraction as parseDiscordModalCustomIdForCarbon, parseDiscordModalCustomIdForInteraction, parseDiscordTarget as parseDiscordSendTarget, parseDiscordTarget, probeDiscord, readDiscordComponentSpec, requestDiscord, resolveDefaultDiscordAccountId, resolveDiscordAccount, resolveDiscordAccountConfig, resolveDiscordChannelId, resolveDiscordComponentAttachmentName, resolveDiscordGroupRequireMention, resolveDiscordGroupToolPolicy, resolveDiscordMaxLinesPerMessage, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordRuntimeGroupPolicy, resolveDiscordTarget, shouldSuppressLocalDiscordExecApprovalPrompt, tryHandleDiscordMessageActionGuildAdmin };
33
+ export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_COMPONENT_ATTACHMENT_PREFIX, DISCORD_COMPONENT_CUSTOM_ID_KEY, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DISCORD_MODAL_CUSTOM_ID_KEY, DiscordApiError, DiscordFormModal, buildDiscordComponentCustomId, buildDiscordComponentMessage, buildDiscordComponentMessageFlags, buildDiscordInteractiveComponents, buildDiscordModalCustomId, collectDiscordSecurityAuditFindings, collectDiscordStatusIssues, createDiscordActionGate, createDiscordFormModal, discordPlugin, discordSetupPlugin, fetchDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchPluralKitMessageInfo, formatDiscordComponentEventText, getDiscordExecApprovalApprovers, handleDiscordMessageAction, handleDiscordSubagentDeliveryTarget, handleDiscordSubagentDeliveryTargetAsync, handleDiscordSubagentEnded, inspectDiscordAccount, isDiscordExecApprovalApprover, isDiscordExecApprovalClientEnabled, listDiscordAccountIds, listDiscordDirectoryGroupsFromConfig, listDiscordDirectoryPeersFromConfig, listEnabledDiscordAccounts, looksLikeDiscordTargetId, mergeAbortSignals, mergeDiscordAccountConfig, normalizeDiscordMessagingTarget, normalizeDiscordOutboundTarget, normalizeExplicitDiscordSessionKey, parseApplicationIdFromToken, parseDiscordComponentCustomId, parseDiscordComponentCustomIdForInteraction as parseDiscordComponentCustomIdForCarbon, parseDiscordComponentCustomIdForInteraction, parseDiscordModalCustomId, parseDiscordModalCustomIdForInteraction as parseDiscordModalCustomIdForCarbon, parseDiscordModalCustomIdForInteraction, parseDiscordTarget as parseDiscordSendTarget, parseDiscordTarget, probeDiscord, readDiscordComponentSpec, requestDiscord, resolveDefaultDiscordAccountId, resolveDiscordAccount, resolveDiscordAccountConfig, resolveDiscordChannelId, resolveDiscordComponentAttachmentName, resolveDiscordGroupRequireMention, resolveDiscordGroupToolPolicy, resolveDiscordMaxLinesPerMessage, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordRuntimeGroupPolicy, resolveDiscordTarget, shouldSuppressLocalDiscordExecApprovalPrompt, tryHandleDiscordMessageActionGuildAdmin };
@@ -1 +1 @@
1
- export { t as discordPlugin } from "./.setup/channel-C24afwHP.mjs";
1
+ export { t as discordPlugin } from "./.setup/channel-BlvyeRAu.mjs";
@@ -1,23 +1,23 @@
1
1
  import { b as shouldEmitDiscordReactionNotification, c as resolveDiscordChannelConfig, d as resolveDiscordCommandAuthorized, f as resolveDiscordGuildEntry, i as normalizeDiscordAllowList, l as resolveDiscordChannelConfigWithFallback, o as normalizeDiscordSlug, r as isDiscordGroupAllowedByPolicy, t as allowListMatches, v as resolveDiscordShouldRequireMention, y as resolveGroupDmAllow } from "./.setup/allow-list-B_ToXtew.mjs";
2
- import { G as unregisterGateway, H as clearGateways, S as hasAllGuildPermissionsDiscord, U as getGateway, W as registerGateway, b as fetchChannelPermissionsDiscord, g as DiscordSendError, w as hasAnyGuildPermissionDiscord, x as fetchMemberGuildPermissionsDiscord } from "./.setup/send.shared-CjQ4jbMA.mjs";
2
+ import { G as unregisterGateway, H as clearGateways, S as hasAllGuildPermissionsDiscord, U as getGateway, W as registerGateway, b as fetchChannelPermissionsDiscord, g as DiscordSendError, w as hasAnyGuildPermissionDiscord, x as fetchMemberGuildPermissionsDiscord } from "./.setup/send.shared-iGf1rqAm.mjs";
3
3
  import { i as setPresence, n as getPresence, r as presenceCacheSize, t as clearPresences } from "./.setup/presence-cache-DCeTsL73.mjs";
4
4
  import { n as listDiscordDirectoryGroupsLive, r as listDiscordDirectoryPeersLive } from "./.setup/directory-live-DLygQVtW.mjs";
5
- import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, c as sendWebhookMessageDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, m as listPinsDiscord, n as fetchReactionsDiscord, o as sendTypingDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./.setup/send-DbILKgcm.mjs";
6
- import { n as sendPollDiscord, r as sendStickerDiscord, t as sendMessageDiscord } from "./.setup/send.outbound-_jx4Xpd3.mjs";
5
+ import { A as listScheduledEventsDiscord, B as moveChannelDiscord, C as fetchChannelInfoDiscord, D as fetchVoiceStatusDiscord, E as fetchRoleInfoDiscord, F as uploadEmojiDiscord, H as setChannelPermissionDiscord, I as uploadStickerDiscord, L as createChannelDiscord, M as resolveEventCoverImage, N as timeoutMemberDiscord, O as kickMemberDiscord, P as listGuildEmojisDiscord, R as deleteChannelDiscord, S as createScheduledEventDiscord, T as fetchMemberInfoDiscord, V as removeChannelPermissionDiscord, _ as readMessagesDiscord, a as removeReactionDiscord, b as addRoleDiscord, c as sendWebhookMessageDiscord, d as deleteMessageDiscord, f as editMessageDiscord, g as pinMessageDiscord, h as listThreadsDiscord, i as removeOwnReactionsDiscord, j as removeRoleDiscord, k as listGuildChannelsDiscord, m as listPinsDiscord, n as fetchReactionsDiscord, o as sendTypingDiscord, p as fetchMessageDiscord, r as reactMessageDiscord, s as sendVoiceMessageDiscord, u as createThreadDiscord, v as searchMessagesDiscord, x as banMemberDiscord, y as unpinMessageDiscord, z as editChannelDiscord } from "./.setup/send-yR1hfybW.mjs";
6
+ import { n as sendPollDiscord, r as sendStickerDiscord, t as sendMessageDiscord } from "./.setup/send.outbound-B5vQwgUK.mjs";
7
7
  import { a as isAbortError, c as runDiscordTaskWithTimeout, i as DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, n as DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, o as normalizeDiscordInboundWorkerTimeoutMs, r as DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, s as normalizeDiscordListenerTimeoutMs, t as DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS } from "./.setup/timeouts-CuNARfyw.mjs";
8
- import { c as readDiscordChannelMoveParams, i as requiredGuildPermissionForModerationAction, l as readDiscordParentIdParam, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./.setup/runtime-CRTkKU1G.mjs";
9
- import { n as registerBuiltDiscordComponentMessage, r as sendDiscordComponentMessage, t as editDiscordComponentMessage } from "./.setup/send.components-FxOS3CeP.mjs";
8
+ import { c as readDiscordChannelMoveParams, i as requiredGuildPermissionForModerationAction, l as readDiscordParentIdParam, n as isDiscordModerationAction, o as readDiscordChannelCreateParams, r as readDiscordModerationCommand, s as readDiscordChannelEditParams, t as handleDiscordAction } from "./.setup/runtime-DE6W14G3.mjs";
9
+ import { n as registerBuiltDiscordComponentMessage, r as sendDiscordComponentMessage, t as editDiscordComponentMessage } from "./.setup/send.components--dxMjc2O.mjs";
10
10
  import { r as setDiscordRuntime } from "./.setup/runtime-DgnVQ7zW.mjs";
11
- import { t as resolveDiscordOutboundSessionRoute, v as discordMessageActions } from "./.setup/outbound-session-route-iwnu6IK8.mjs";
12
- import { F as resolveThreadBindingMaxAgeMs, M as resolveThreadBindingIdleTimeoutMs, N as resolveThreadBindingInactivityExpiresAt, P as resolveThreadBindingMaxAgeExpiresAt, r as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./.setup/thread-bindings.session-updates-DGSljVf6.mjs";
11
+ import { t as resolveDiscordOutboundSessionRoute, x as discordMessageActions } from "./.setup/outbound-session-route-CsHHPxsQ.mjs";
12
+ import { F as resolveThreadBindingMaxAgeExpiresAt, I as resolveThreadBindingMaxAgeMs, N as resolveThreadBindingIdleTimeoutMs, P as resolveThreadBindingInactivityExpiresAt, i as setThreadBindingMaxAgeBySessionKeyAsync, n as setThreadBindingIdleTimeoutBySessionKeyAsync, r as setThreadBindingMaxAgeBySessionKey, t as setThreadBindingIdleTimeoutBySessionKey } from "./.setup/thread-bindings.session-updates-BMdJeJMc.mjs";
13
13
  import { t as resolveDiscordChannelAllowlist } from "./.setup/resolve-channels-UdT38DzU.mjs";
14
14
  import { t as resolveDiscordUserAllowlist } from "./.setup/resolve-users-DnCsrXZ_.mjs";
15
- import { c as resolveThreadBindingPersonaFromRecord, i as createNoopThreadBindingManager, n as getThreadBindingManager, s as resolveThreadBindingPersona, t as createThreadBindingManager } from "./.setup/thread-bindings.manager-CdNa6UIs.mjs";
16
- import { a as autoBindSpawnedDiscordSubagent, c as reconcileAcpThreadBindingsOnStartup, d as resolveDiscordThreadBindingIdleTimeoutMs, f as resolveDiscordThreadBindingMaxAgeMs, l as unbindThreadBindingsBySessionKey, n as resolveThreadBindingIntroText, o as listThreadBindingsBySessionKey, p as resolveThreadBindingsEnabled, r as resolveThreadBindingThreadName, s as listThreadBindingsForAccount, t as formatThreadBindingDurationLabel } from "./.setup/thread-bindings-0hPTSK14.mjs";
15
+ import { c as resolveThreadBindingPersonaFromRecord, i as createNoopThreadBindingManager, n as getThreadBindingManager, s as resolveThreadBindingPersona, t as createThreadBindingManager } from "./.setup/thread-bindings.manager-BMpmKLQh.mjs";
16
+ import { a as autoBindSpawnedDiscordSubagent, c as listThreadBindingsForAccount, d as unbindThreadBindingsBySessionKeyAsync, f as resolveDiscordThreadBindingIdleTimeoutMs, l as reconcileAcpThreadBindingsOnStartup, m as resolveThreadBindingsEnabled, n as resolveThreadBindingIntroText, o as listThreadBindingsBySessionKey, p as resolveDiscordThreadBindingMaxAgeMs, r as resolveThreadBindingThreadName, s as listThreadBindingsBySessionKeyAsync, t as formatThreadBindingDurationLabel, u as unbindThreadBindingsBySessionKey } from "./.setup/thread-bindings-Dsc3zsrI.mjs";
17
17
  import { i as probeDiscord, n as fetchDiscordApplicationSummary, r as parseApplicationIdFromToken, s as resolveDiscordPrivilegedIntentsFromFlags, t as fetchDiscordApplicationId } from "./.setup/probe-D3P1x4aN.mjs";
18
- import { r as collectDiscordAuditChannelIds, t as auditDiscordChannelPermissions } from "./.setup/audit-TGIPL0f_.mjs";
19
- import { S as createDiscordNativeCommand, a as waitForDiscordGatewayPluginRegistration, i as resolveDiscordGatewayIntents, k as registerDiscordListener, r as createDiscordGatewayPlugin, t as monitorDiscordProvider } from "./.setup/provider-CbmXLYrW.mjs";
20
- import { f as resolveDiscordReplyTarget, g as sanitizeDiscordThreadName } from "./.setup/transcripts-source-EMrQb132.mjs";
21
- import { t as createDiscordMessageHandler } from "./.setup/message-handler-C_BQFYCW.mjs";
22
- import "./.setup/threading-BWz5lW0p.mjs";
23
- export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DiscordSendError, addRoleDiscord, allowListMatches, auditDiscordChannelPermissions, autoBindSpawnedDiscordSubagent, banMemberDiscord, clearGateways, clearPresences, collectDiscordAuditChannelIds, createChannelDiscord, createDiscordGatewayPlugin, createDiscordMessageHandler, createDiscordNativeCommand, createNoopThreadBindingManager, createScheduledEventDiscord, createThreadBindingManager, createThreadDiscord, deleteChannelDiscord, deleteMessageDiscord, discordMessageActions, editChannelDiscord, editDiscordComponentMessage, editMessageDiscord, fetchChannelInfoDiscord, fetchChannelPermissionsDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchMemberGuildPermissionsDiscord, fetchMemberInfoDiscord, fetchMessageDiscord, fetchReactionsDiscord, fetchRoleInfoDiscord, fetchVoiceStatusDiscord, formatThreadBindingDurationLabel, getGateway, getPresence, getThreadBindingManager, handleDiscordAction, hasAllGuildPermissionsDiscord, hasAnyGuildPermissionDiscord, isAbortError, isDiscordGroupAllowedByPolicy, isDiscordModerationAction, kickMemberDiscord, listDiscordDirectoryGroupsLive, listDiscordDirectoryPeersLive, listGuildChannelsDiscord, listGuildEmojisDiscord, listPinsDiscord, listScheduledEventsDiscord, listThreadBindingsBySessionKey, listThreadBindingsForAccount, listThreadsDiscord, monitorDiscordProvider, moveChannelDiscord, normalizeDiscordAllowList, normalizeDiscordInboundWorkerTimeoutMs, normalizeDiscordListenerTimeoutMs, normalizeDiscordSlug, parseApplicationIdFromToken, pinMessageDiscord, presenceCacheSize, probeDiscord, reactMessageDiscord, readDiscordChannelCreateParams, readDiscordChannelEditParams, readDiscordChannelMoveParams, readDiscordModerationCommand, readDiscordParentIdParam, readMessagesDiscord, reconcileAcpThreadBindingsOnStartup, registerBuiltDiscordComponentMessage, registerDiscordListener, registerGateway, removeChannelPermissionDiscord, removeOwnReactionsDiscord, removeReactionDiscord, removeRoleDiscord, requiredGuildPermissionForModerationAction, resolveDiscordChannelAllowlist, resolveDiscordChannelConfig, resolveDiscordChannelConfigWithFallback, resolveDiscordCommandAuthorized, resolveDiscordGatewayIntents, resolveDiscordGuildEntry, resolveDiscordOutboundSessionRoute, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordReplyTarget, resolveDiscordShouldRequireMention, resolveDiscordThreadBindingIdleTimeoutMs, resolveDiscordThreadBindingMaxAgeMs, resolveDiscordUserAllowlist, resolveEventCoverImage, resolveGroupDmAllow, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingInactivityExpiresAt, resolveThreadBindingIntroText, resolveThreadBindingMaxAgeExpiresAt, resolveThreadBindingMaxAgeMs, resolveThreadBindingPersona, resolveThreadBindingPersonaFromRecord, resolveThreadBindingThreadName, resolveThreadBindingsEnabled, runDiscordTaskWithTimeout, sanitizeDiscordThreadName, searchMessagesDiscord, sendDiscordComponentMessage, sendMessageDiscord, sendPollDiscord, sendStickerDiscord, sendTypingDiscord, sendVoiceMessageDiscord, sendWebhookMessageDiscord, setChannelPermissionDiscord, setDiscordRuntime, setPresence, setThreadBindingIdleTimeoutBySessionKey, setThreadBindingMaxAgeBySessionKey, shouldEmitDiscordReactionNotification, timeoutMemberDiscord, unbindThreadBindingsBySessionKey, unpinMessageDiscord, unregisterGateway, uploadEmojiDiscord, uploadStickerDiscord, waitForDiscordGatewayPluginRegistration };
18
+ import { r as collectDiscordAuditChannelIds, t as auditDiscordChannelPermissions } from "./.setup/audit-UwzCdDJk.mjs";
19
+ import { S as createDiscordNativeCommand, a as waitForDiscordGatewayPluginRegistration, i as resolveDiscordGatewayIntents, k as registerDiscordListener, r as createDiscordGatewayPlugin, t as monitorDiscordProvider } from "./.setup/provider-DUTsZJHz.mjs";
20
+ import { f as resolveDiscordReplyTarget, g as sanitizeDiscordThreadName } from "./.setup/transcripts-source-fRvFsZng.mjs";
21
+ import { t as createDiscordMessageHandler } from "./.setup/message-handler-CtR2w7W_.mjs";
22
+ import "./.setup/threading-Cg_QRc8s.mjs";
23
+ export { DISCORD_ATTACHMENT_IDLE_TIMEOUT_MS, DISCORD_ATTACHMENT_TOTAL_TIMEOUT_MS, DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS, DISCORD_DEFAULT_LISTENER_TIMEOUT_MS, DiscordSendError, addRoleDiscord, allowListMatches, auditDiscordChannelPermissions, autoBindSpawnedDiscordSubagent, banMemberDiscord, clearGateways, clearPresences, collectDiscordAuditChannelIds, createChannelDiscord, createDiscordGatewayPlugin, createDiscordMessageHandler, createDiscordNativeCommand, createNoopThreadBindingManager, createScheduledEventDiscord, createThreadBindingManager, createThreadDiscord, deleteChannelDiscord, deleteMessageDiscord, discordMessageActions, editChannelDiscord, editDiscordComponentMessage, editMessageDiscord, fetchChannelInfoDiscord, fetchChannelPermissionsDiscord, fetchDiscordApplicationId, fetchDiscordApplicationSummary, fetchMemberGuildPermissionsDiscord, fetchMemberInfoDiscord, fetchMessageDiscord, fetchReactionsDiscord, fetchRoleInfoDiscord, fetchVoiceStatusDiscord, formatThreadBindingDurationLabel, getGateway, getPresence, getThreadBindingManager, handleDiscordAction, hasAllGuildPermissionsDiscord, hasAnyGuildPermissionDiscord, isAbortError, isDiscordGroupAllowedByPolicy, isDiscordModerationAction, kickMemberDiscord, listDiscordDirectoryGroupsLive, listDiscordDirectoryPeersLive, listGuildChannelsDiscord, listGuildEmojisDiscord, listPinsDiscord, listScheduledEventsDiscord, listThreadBindingsBySessionKey, listThreadBindingsBySessionKeyAsync, listThreadBindingsForAccount, listThreadsDiscord, monitorDiscordProvider, moveChannelDiscord, normalizeDiscordAllowList, normalizeDiscordInboundWorkerTimeoutMs, normalizeDiscordListenerTimeoutMs, normalizeDiscordSlug, parseApplicationIdFromToken, pinMessageDiscord, presenceCacheSize, probeDiscord, reactMessageDiscord, readDiscordChannelCreateParams, readDiscordChannelEditParams, readDiscordChannelMoveParams, readDiscordModerationCommand, readDiscordParentIdParam, readMessagesDiscord, reconcileAcpThreadBindingsOnStartup, registerBuiltDiscordComponentMessage, registerDiscordListener, registerGateway, removeChannelPermissionDiscord, removeOwnReactionsDiscord, removeReactionDiscord, removeRoleDiscord, requiredGuildPermissionForModerationAction, resolveDiscordChannelAllowlist, resolveDiscordChannelConfig, resolveDiscordChannelConfigWithFallback, resolveDiscordCommandAuthorized, resolveDiscordGatewayIntents, resolveDiscordGuildEntry, resolveDiscordOutboundSessionRoute, resolveDiscordPrivilegedIntentsFromFlags, resolveDiscordReplyTarget, resolveDiscordShouldRequireMention, resolveDiscordThreadBindingIdleTimeoutMs, resolveDiscordThreadBindingMaxAgeMs, resolveDiscordUserAllowlist, resolveEventCoverImage, resolveGroupDmAllow, resolveThreadBindingIdleTimeoutMs, resolveThreadBindingInactivityExpiresAt, resolveThreadBindingIntroText, resolveThreadBindingMaxAgeExpiresAt, resolveThreadBindingMaxAgeMs, resolveThreadBindingPersona, resolveThreadBindingPersonaFromRecord, resolveThreadBindingThreadName, resolveThreadBindingsEnabled, runDiscordTaskWithTimeout, sanitizeDiscordThreadName, searchMessagesDiscord, sendDiscordComponentMessage, sendMessageDiscord, sendPollDiscord, sendStickerDiscord, sendTypingDiscord, sendVoiceMessageDiscord, sendWebhookMessageDiscord, setChannelPermissionDiscord, setDiscordRuntime, setPresence, setThreadBindingIdleTimeoutBySessionKey, setThreadBindingIdleTimeoutBySessionKeyAsync, setThreadBindingMaxAgeBySessionKey, setThreadBindingMaxAgeBySessionKeyAsync, shouldEmitDiscordReactionNotification, timeoutMemberDiscord, unbindThreadBindingsBySessionKey, unbindThreadBindingsBySessionKeyAsync, unpinMessageDiscord, unregisterGateway, uploadEmojiDiscord, uploadStickerDiscord, waitForDiscordGatewayPluginRegistration };
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
4
4
  var setup_entry_default = defineBundledChannelSetupEntry({
5
5
  importMetaUrl: import.meta.url,
6
6
  plugin: {
7
- specifier: fileURLToPath(new URL(".setup/setup-plugin-api-BFl2FljJ.mjs", import.meta.url).href),
7
+ specifier: fileURLToPath(new URL(".setup/setup-plugin-api-DVpA_yqS.mjs", import.meta.url).href),
8
8
  exportName: "discordSetupPlugin"
9
9
  }
10
10
  });
@@ -1 +1 @@
1
- export { t as discordSetupPlugin } from "./.setup/channel.setup-B3KEh05g.mjs";
1
+ export { t as discordSetupPlugin } from "./.setup/channel.setup-By7wNopw.mjs";
@@ -1,4 +1,4 @@
1
- import { a as recoverDaveZeroTransition, b as setDiscordAudioOutputStatus, c as createDiscordOpusPlaybackStream, d as decodeOpusStreamChunks, g as releaseDiscordAudioInput, h as getDiscordAudioOutputStatus, n as analyzeVoiceReceiveError, p as DiscordAudioOutputStatus, r as enableDaveReceivePassthrough, s as DiscordOpusEncodeStream, u as createRealtimePcmToDiscordConverter, v as retireDiscordAudioOutput, y as serializeDiscordAudioError } from "../../.setup/receive-recovery-eVmK2_hl.mjs";
1
+ import { _ as setDiscordAudioOutputStatus, a as recoverDaveZeroTransition, c as createDiscordOpusPlaybackStream, d as decodeOpusStreamChunks, g as serializeDiscordAudioError, m as getDiscordAudioOutputStatus, n as analyzeVoiceReceiveError, p as DiscordAudioOutputStatus, r as enableDaveReceivePassthrough, s as DiscordOpusEncodeStream, u as createRealtimePcmToDiscordConverter } from "../../.setup/receive-recovery-CKvaG2Hf.mjs";
2
2
  import { t as resolveDiscordOutputAudioDelta } from "../../.setup/output-activity-uBpMSX75.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { parentPort, workerData } from "node:worker_threads";
@@ -159,13 +159,6 @@ var DiscordRealtimeOutput = class {
159
159
  this.startupTimer.unref?.();
160
160
  }
161
161
  }
162
- appendAdmitted(sourcePcm, audible) {
163
- try {
164
- this.append(sourcePcm, audible);
165
- } finally {
166
- releaseDiscordAudioInput(this.params.clock);
167
- }
168
- }
169
162
  writeConverted(pcm) {
170
163
  if (pcm.length === 0 || this.closed) return;
171
164
  if (this.activity.snapshot().playbackStarted && !this.drainHandler) {
@@ -250,7 +243,11 @@ var DiscordRealtimeOutput = class {
250
243
  if (!this.drainHandler) this.stream.end();
251
244
  }
252
245
  },
253
- onRetiring: () => this.activity.snapshot().sinkAudioBytes <= this.playedPcmBytes && retireDiscordAudioOutput(this.params.clock),
246
+ onRetiring: () => {
247
+ if (this.activity.snapshot().sinkAudioBytes > this.playedPcmBytes) return false;
248
+ this.publishRetiring();
249
+ return true;
250
+ },
254
251
  onIdle: () => this.close(this.failed ? "output-pipeline-error" : "player-idle"),
255
252
  onError: this.params.onError
256
253
  };
@@ -319,7 +316,7 @@ var DiscordRealtimeOutput = class {
319
316
  if (activity.sinkAudioBytes <= this.lastAudiblePcmEndBytes || this.silenceTimer) return;
320
317
  this.silenceTimer = setTimeout(() => {
321
318
  this.silenceTimer = void 0;
322
- if (!this.closed && !this.activity.snapshot().streamEnding && !this.hasUnplayedAudibleAudio() && retireDiscordAudioOutput(this.params.clock)) this.finish("continuous-idle", true);
319
+ if (!this.closed && !this.activity.snapshot().streamEnding && !this.hasUnplayedAudibleAudio()) this.finish("continuous-idle", true);
323
320
  }, Math.max(0, DISCORD_REALTIME_PLAYBACK_IDLE_MS - (performance.now() - this.silentSince)));
324
321
  this.silenceTimer.unref?.();
325
322
  }
@@ -677,7 +674,7 @@ var DiscordAudioWorker = class {
677
674
  break;
678
675
  }
679
676
  case "output-audio":
680
- this.outputs.get(command.id)?.appendAdmitted(Buffer.from(command.audio), command.audible);
677
+ this.outputs.get(command.id)?.append(Buffer.from(command.audio), command.audible);
681
678
  break;
682
679
  case "output-mark":
683
680
  this.outputs.get(command.id)?.markPlayback(() => this.post({
@@ -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("./.setup/subagent-hooks-CME7dSGf.mjs").then((n) => n.r));
3
+ const loadDiscordSubagentHooksModule = createLazyRuntimeModule(() => import("./.setup/subagent-hooks-tBtaqWkD.mjs").then((n) => n.i));
4
4
  function registerDiscordSubagentHooks(api) {
5
5
  api.on("subagent_ended", async (event) => {
6
6
  const { handleDiscordSubagentEnded } = await loadDiscordSubagentHooksModule();
@@ -1,4 +1,4 @@
1
- import { n as discordVoiceTranscriptsSourceProvider } from "./.setup/transcripts-source-EMrQb132.mjs";
1
+ import { n as discordVoiceTranscriptsSourceProvider } from "./.setup/transcripts-source-fRvFsZng.mjs";
2
2
  //#region extensions/discord/transcripts-source-api.ts
3
3
  function registerDiscordTranscriptSourceProvider(api) {
4
4
  api.registerTranscriptSourceProvider(discordVoiceTranscriptsSourceProvider);