@kodelyth/discord 2026.5.39 → 2026.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/account-inspect-Dqw-enky.js +81 -0
- package/dist/account-inspect-api.js +10 -0
- package/dist/accounts-B7OBFePq.js +224 -0
- package/dist/action-runtime-api.js +2 -0
- package/dist/agent-components.runtime-DVY_1VB4.js +4 -0
- package/dist/allow-list-B0s7evD7.js +354 -0
- package/dist/api-CXAcv9nZ.js +130 -0
- package/dist/api.js +23 -0
- package/dist/approval-handler.runtime-B9xUAF3n.js +426 -0
- package/dist/audit-DoiK49WO.js +24 -0
- package/dist/audit-core-BGrq3G7r.js +105 -0
- package/dist/channel-U_aeoFwW.js +795 -0
- package/dist/channel-actions-BxEBnEuv.js +173 -0
- package/dist/channel-actions.runtime-CPtpH-yl.js +263 -0
- package/dist/channel-api-BfjklLby.js +21 -0
- package/dist/channel-config-api.js +2 -0
- package/dist/channel-plugin-api.js +2 -0
- package/dist/channel.setup-BUSC0apv.js +337 -0
- package/dist/components-luonoe13.js +909 -0
- package/dist/config-api-DSYGqaLQ.js +2 -0
- package/dist/config-schema-DIqJBGwC.js +357 -0
- package/dist/configured-state.js +6 -0
- package/dist/contract-api.js +8 -0
- package/dist/conversation-identity-DXAm0_Mk.js +270 -0
- package/dist/directory-config-CYbuMmPS.js +49 -0
- package/dist/directory-contract-api.js +2 -0
- package/dist/directory-live-DX4dLRpJ.js +159 -0
- package/dist/doctor-bbKSvGVD.js +244 -0
- package/dist/doctor-contract-Btjt6NJD.js +383 -0
- package/dist/doctor-contract-api.js +2 -0
- package/dist/gateway-registry-BKSpa4GB.js +74 -0
- package/dist/handle-action.guild-admin-B5BArS2n.js +286 -0
- package/dist/inbound-context-WAOqhGlT.js +48 -0
- package/dist/inbound-event-delivery-C-1Ji3WP.js +65 -0
- package/dist/index.js +26 -0
- package/dist/manager.runtime-DXHynKE4.js +2356 -0
- package/dist/message-handler-mXzc3tA_.js +381 -0
- package/dist/message-handler.preflight-BPD1a347.js +1113 -0
- package/dist/message-handler.process-GUa3aV8z.js +1438 -0
- package/dist/message-utils-dUbem16p.js +549 -0
- package/dist/outbound-adapter-C18OAc1y.js +536 -0
- package/dist/pluralkit-D1Q2x0w5.js +22 -0
- package/dist/preflight-audio-CZtpWcIm.js +72 -0
- package/dist/preflight-audio.runtime-Brx_0_xW.js +7 -0
- package/dist/preview-streaming-D_slNIiO.js +8 -0
- package/dist/probe-D--Ca4JF.js +139 -0
- package/dist/probe.runtime-DQBchZzv.js +2 -0
- package/dist/provider-B2-31CIT.js +9565 -0
- package/dist/provider-session.runtime-BwzzSsrH.js +6 -0
- package/dist/provider.runtime-CP3oHLls.js +2 -0
- package/dist/resolve-allowlist-common-CqxPLcJO.js +34 -0
- package/dist/resolve-channels-0LX4pUbB.js +265 -0
- package/dist/resolve-users-CztOv0Qs.js +120 -0
- package/dist/runtime-DUaw66V_.js +1073 -0
- package/dist/runtime-api.actions.js +3 -0
- package/dist/runtime-api.js +30 -0
- package/dist/runtime-api.lookup.js +7 -0
- package/dist/runtime-api.monitor-CvVKvEXW.js +5 -0
- package/dist/runtime-api.monitor.js +8 -0
- package/dist/runtime-api.send.js +6 -0
- package/dist/runtime-api.threads.js +6 -0
- package/dist/runtime-fC6f4UF2.js +8 -0
- package/dist/runtime-setter-api.js +2 -0
- package/dist/secret-config-contract-B6WW5V88.js +115 -0
- package/dist/secret-contract-api.js +2 -0
- package/dist/security-audit-CnyIQKz6.js +120 -0
- package/dist/security-audit-contract-api.js +2 -0
- package/dist/security-audit.runtime-CQSkjNLu.js +2 -0
- package/dist/security-contract-DLvYOgLM.js +26 -0
- package/dist/security-contract-api.js +2 -0
- package/dist/security-doctor-DepqtNCI.js +18 -0
- package/dist/send-DCtPCHGk.js +881 -0
- package/dist/send.components-Bcgxvm52.js +474 -0
- package/dist/send.outbound-S9t0UuHc.js +330 -0
- package/dist/send.receipt-CDn3GBWC.js +3119 -0
- package/dist/send.shared-D4iBnAmn.js +669 -0
- package/dist/sender-identity-CxCe3_1a.js +43 -0
- package/dist/session-contract-Dwhw3RTY.js +6 -0
- package/dist/session-key-api.js +2 -0
- package/dist/session-key-normalization-CP8dPUid.js +23 -0
- package/dist/setup-entry.js +11 -0
- package/dist/setup-plugin-api.js +2 -0
- package/dist/shared-AIlvuZXt.js +171 -0
- package/dist/subagent-hooks-8bK-mgiU.js +120 -0
- package/dist/subagent-hooks-api.js +22 -0
- package/dist/system-events-Ba1TklaL.js +34 -0
- package/dist/target-resolver-BrtFQtoK.js +82 -0
- package/dist/targets-DWLLZE2l.js +3 -0
- package/dist/test-api.js +45 -0
- package/dist/thread-binding-api.js +4 -0
- package/dist/thread-bindings-9aKRmZv0.js +255 -0
- package/dist/thread-bindings.discord-api-ssGH5wc2.js +244 -0
- package/dist/thread-bindings.manager-0YBHGemk.js +534 -0
- package/dist/thread-bindings.session-updates-DJZGIwaU.js +54 -0
- package/dist/thread-bindings.state-eTFl-PqJ.js +318 -0
- package/dist/timeouts-CEwuGaWT.js +52 -0
- package/dist/timeouts.js +2 -0
- package/dist/typing-BmJKRpCS.js +14 -0
- package/package.json +19 -7
- package/account-inspect-api.js +0 -7
- package/action-runtime-api.js +0 -7
- package/api.js +0 -7
- package/channel-config-api.js +0 -7
- package/channel-plugin-api.js +0 -7
- package/configured-state.js +0 -7
- package/contract-api.js +0 -7
- package/directory-contract-api.js +0 -7
- package/doctor-contract-api.js +0 -7
- package/index.js +0 -7
- package/runtime-api.actions.js +0 -7
- package/runtime-api.js +0 -7
- package/runtime-api.lookup.js +0 -7
- package/runtime-api.monitor.js +0 -7
- package/runtime-api.send.js +0 -7
- package/runtime-api.threads.js +0 -7
- package/runtime-setter-api.js +0 -7
- package/secret-contract-api.js +0 -7
- package/security-audit-contract-api.js +0 -7
- package/security-contract-api.js +0 -7
- package/session-key-api.js +0 -7
- package/setup-entry.js +0 -7
- package/setup-plugin-api.js +0 -7
- package/subagent-hooks-api.js +0 -7
- package/test-api.js +0 -7
- package/thread-binding-api.js +0 -7
- package/timeouts.js +0 -7
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
import { t as resolveDiscordPreviewStreamMode } from "./preview-streaming-D_slNIiO.js";
|
|
2
|
+
import { asObjectRecord, normalizeLegacyChannelAliases } from "klaw/plugin-sdk/runtime-doctor";
|
|
3
|
+
//#region extensions/discord/src/doctor-contract.ts
|
|
4
|
+
const LEGACY_TTS_PROVIDER_KEYS = [
|
|
5
|
+
"openai",
|
|
6
|
+
"elevenlabs",
|
|
7
|
+
"microsoft",
|
|
8
|
+
"edge"
|
|
9
|
+
];
|
|
10
|
+
function hasLegacyTtsProviderKeys(value) {
|
|
11
|
+
const tts = asObjectRecord(value);
|
|
12
|
+
if (!tts) return false;
|
|
13
|
+
return LEGACY_TTS_PROVIDER_KEYS.some((key) => Object.prototype.hasOwnProperty.call(tts, key));
|
|
14
|
+
}
|
|
15
|
+
function hasLegacyDiscordAccountTtsProviderKeys(value) {
|
|
16
|
+
const accounts = asObjectRecord(value);
|
|
17
|
+
if (!accounts) return false;
|
|
18
|
+
return Object.values(accounts).some((accountValue) => {
|
|
19
|
+
return hasLegacyTtsProviderKeys(asObjectRecord(asObjectRecord(accountValue)?.voice)?.tts);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function hasLegacyDiscordGuildChannelAllowAlias(value) {
|
|
23
|
+
const guilds = asObjectRecord(asObjectRecord(value)?.guilds);
|
|
24
|
+
if (!guilds) return false;
|
|
25
|
+
return Object.values(guilds).some((guildValue) => {
|
|
26
|
+
const channels = asObjectRecord(asObjectRecord(guildValue)?.channels);
|
|
27
|
+
if (!channels) return false;
|
|
28
|
+
return Object.values(channels).some((channel) => Object.prototype.hasOwnProperty.call(asObjectRecord(channel) ?? {}, "allow"));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function hasLegacyDiscordGuildChannelAgentId(value) {
|
|
32
|
+
const guilds = asObjectRecord(asObjectRecord(value)?.guilds);
|
|
33
|
+
if (!guilds) return false;
|
|
34
|
+
return Object.values(guilds).some((guildValue) => {
|
|
35
|
+
const channels = asObjectRecord(asObjectRecord(guildValue)?.channels);
|
|
36
|
+
if (!channels) return false;
|
|
37
|
+
return Object.values(channels).some((channel) => Object.prototype.hasOwnProperty.call(asObjectRecord(channel) ?? {}, "agentId"));
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function hasLegacyDiscordAccountGuildChannelAllowAlias(value) {
|
|
41
|
+
const accounts = asObjectRecord(value);
|
|
42
|
+
if (!accounts) return false;
|
|
43
|
+
return Object.values(accounts).some((account) => hasLegacyDiscordGuildChannelAllowAlias(account));
|
|
44
|
+
}
|
|
45
|
+
function hasLegacyDiscordAccountGuildChannelAgentId(value) {
|
|
46
|
+
const accounts = asObjectRecord(value);
|
|
47
|
+
if (!accounts) return false;
|
|
48
|
+
return Object.values(accounts).some((account) => hasLegacyDiscordGuildChannelAgentId(account));
|
|
49
|
+
}
|
|
50
|
+
function mergeMissing(target, source) {
|
|
51
|
+
for (const [key, value] of Object.entries(source)) {
|
|
52
|
+
if (value === void 0) continue;
|
|
53
|
+
const existing = target[key];
|
|
54
|
+
if (existing === void 0) {
|
|
55
|
+
target[key] = value;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (existing && typeof existing === "object" && !Array.isArray(existing) && value && typeof value === "object" && !Array.isArray(value)) mergeMissing(existing, value);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function getOrCreateTtsProviders(tts) {
|
|
62
|
+
const providers = asObjectRecord(tts.providers) ?? {};
|
|
63
|
+
tts.providers = providers;
|
|
64
|
+
return providers;
|
|
65
|
+
}
|
|
66
|
+
function mergeLegacyTtsProviderConfig(tts, legacyKey, providerId) {
|
|
67
|
+
const legacyValue = asObjectRecord(tts[legacyKey]);
|
|
68
|
+
if (!legacyValue) return false;
|
|
69
|
+
const providers = getOrCreateTtsProviders(tts);
|
|
70
|
+
const existing = asObjectRecord(providers[providerId]) ?? {};
|
|
71
|
+
const merged = structuredClone(existing);
|
|
72
|
+
mergeMissing(merged, legacyValue);
|
|
73
|
+
providers[providerId] = merged;
|
|
74
|
+
delete tts[legacyKey];
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
function migrateLegacyTtsConfig(tts, pathLabel, changes) {
|
|
78
|
+
if (!tts) return false;
|
|
79
|
+
let changed = false;
|
|
80
|
+
if (mergeLegacyTtsProviderConfig(tts, "openai", "openai")) {
|
|
81
|
+
changes.push(`Moved ${pathLabel}.openai → ${pathLabel}.providers.openai.`);
|
|
82
|
+
changed = true;
|
|
83
|
+
}
|
|
84
|
+
if (mergeLegacyTtsProviderConfig(tts, "elevenlabs", "elevenlabs")) {
|
|
85
|
+
changes.push(`Moved ${pathLabel}.elevenlabs → ${pathLabel}.providers.elevenlabs.`);
|
|
86
|
+
changed = true;
|
|
87
|
+
}
|
|
88
|
+
if (mergeLegacyTtsProviderConfig(tts, "microsoft", "microsoft")) {
|
|
89
|
+
changes.push(`Moved ${pathLabel}.microsoft → ${pathLabel}.providers.microsoft.`);
|
|
90
|
+
changed = true;
|
|
91
|
+
}
|
|
92
|
+
if (mergeLegacyTtsProviderConfig(tts, "edge", "microsoft")) {
|
|
93
|
+
changes.push(`Moved ${pathLabel}.edge → ${pathLabel}.providers.microsoft.`);
|
|
94
|
+
changed = true;
|
|
95
|
+
}
|
|
96
|
+
return changed;
|
|
97
|
+
}
|
|
98
|
+
function normalizeDiscordGuildChannelAllowAliases(params) {
|
|
99
|
+
const guilds = asObjectRecord(params.entry.guilds);
|
|
100
|
+
if (!guilds) return {
|
|
101
|
+
entry: params.entry,
|
|
102
|
+
changed: false
|
|
103
|
+
};
|
|
104
|
+
let changed = false;
|
|
105
|
+
const nextGuilds = { ...guilds };
|
|
106
|
+
for (const [guildId, guildValue] of Object.entries(guilds)) {
|
|
107
|
+
const guild = asObjectRecord(guildValue);
|
|
108
|
+
const channels = asObjectRecord(guild?.channels);
|
|
109
|
+
if (!guild || !channels) continue;
|
|
110
|
+
let channelsChanged = false;
|
|
111
|
+
const nextChannels = { ...channels };
|
|
112
|
+
for (const [channelId, channelValue] of Object.entries(channels)) {
|
|
113
|
+
const channel = asObjectRecord(channelValue);
|
|
114
|
+
if (!channel || !Object.prototype.hasOwnProperty.call(channel, "allow")) continue;
|
|
115
|
+
const nextChannel = { ...channel };
|
|
116
|
+
if (nextChannel.enabled === void 0) {
|
|
117
|
+
nextChannel.enabled = channel.allow;
|
|
118
|
+
params.changes.push(`Moved ${params.pathPrefix}.guilds.${guildId}.channels.${channelId}.allow → ${params.pathPrefix}.guilds.${guildId}.channels.${channelId}.enabled.`);
|
|
119
|
+
} else params.changes.push(`Removed ${params.pathPrefix}.guilds.${guildId}.channels.${channelId}.allow (${params.pathPrefix}.guilds.${guildId}.channels.${channelId}.enabled already set).`);
|
|
120
|
+
delete nextChannel.allow;
|
|
121
|
+
nextChannels[channelId] = nextChannel;
|
|
122
|
+
channelsChanged = true;
|
|
123
|
+
}
|
|
124
|
+
if (!channelsChanged) continue;
|
|
125
|
+
nextGuilds[guildId] = {
|
|
126
|
+
...guild,
|
|
127
|
+
channels: nextChannels
|
|
128
|
+
};
|
|
129
|
+
changed = true;
|
|
130
|
+
}
|
|
131
|
+
return changed ? {
|
|
132
|
+
entry: {
|
|
133
|
+
...params.entry,
|
|
134
|
+
guilds: nextGuilds
|
|
135
|
+
},
|
|
136
|
+
changed: true
|
|
137
|
+
} : {
|
|
138
|
+
entry: params.entry,
|
|
139
|
+
changed: false
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function isDiscordChannelAgentBinding(value, match) {
|
|
143
|
+
const binding = asObjectRecord(value);
|
|
144
|
+
const bindingMatch = asObjectRecord(binding?.match);
|
|
145
|
+
const peer = asObjectRecord(bindingMatch?.peer);
|
|
146
|
+
if (!binding || !bindingMatch || !peer) return false;
|
|
147
|
+
return bindingMatch.channel === "discord" && bindingMatch.guildId === match.guildId && (match.accountId === void 0 || bindingMatch.accountId === match.accountId) && peer.kind === "channel" && peer.id === match.channelId;
|
|
148
|
+
}
|
|
149
|
+
function normalizeDiscordGuildChannelAgentIds(params) {
|
|
150
|
+
const guilds = asObjectRecord(params.entry.guilds);
|
|
151
|
+
if (!guilds) return {
|
|
152
|
+
entry: params.entry,
|
|
153
|
+
changed: false
|
|
154
|
+
};
|
|
155
|
+
const existingBindings = Array.isArray(params.cfg.bindings) ? params.cfg.bindings : [];
|
|
156
|
+
let changed = false;
|
|
157
|
+
const nextGuilds = { ...guilds };
|
|
158
|
+
for (const [guildId, guildValue] of Object.entries(guilds)) {
|
|
159
|
+
const guild = asObjectRecord(guildValue);
|
|
160
|
+
const channels = asObjectRecord(guild?.channels);
|
|
161
|
+
if (!guild || !channels) continue;
|
|
162
|
+
let channelsChanged = false;
|
|
163
|
+
const nextChannels = { ...channels };
|
|
164
|
+
for (const [channelId, channelValue] of Object.entries(channels)) {
|
|
165
|
+
const channel = asObjectRecord(channelValue);
|
|
166
|
+
if (!channel || !Object.prototype.hasOwnProperty.call(channel, "agentId")) continue;
|
|
167
|
+
const nextChannel = { ...channel };
|
|
168
|
+
const rawAgentId = nextChannel.agentId;
|
|
169
|
+
delete nextChannel.agentId;
|
|
170
|
+
nextChannels[channelId] = nextChannel;
|
|
171
|
+
channelsChanged = true;
|
|
172
|
+
const path = `${params.pathPrefix}.guilds.${guildId}.channels.${channelId}.agentId`;
|
|
173
|
+
const agentId = typeof rawAgentId === "string" ? rawAgentId.trim() : "";
|
|
174
|
+
if (!agentId) {
|
|
175
|
+
params.changes.push(`Removed ${path}; configure top-level bindings[] for per-channel Discord agent routing.`);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const match = {
|
|
179
|
+
accountId: params.accountId,
|
|
180
|
+
guildId,
|
|
181
|
+
channelId
|
|
182
|
+
};
|
|
183
|
+
if (existingBindings.find((binding) => isDiscordChannelAgentBinding(binding, match))) {
|
|
184
|
+
params.changes.push(`Removed ${path}; a matching top-level bindings[] route already exists for Discord channel ${channelId}.`);
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const bindingMatch = {
|
|
188
|
+
channel: "discord",
|
|
189
|
+
guildId,
|
|
190
|
+
peer: {
|
|
191
|
+
kind: "channel",
|
|
192
|
+
id: channelId
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
if (params.accountId) bindingMatch.accountId = params.accountId;
|
|
196
|
+
params.bindingsToAdd.push({
|
|
197
|
+
agentId,
|
|
198
|
+
match: bindingMatch
|
|
199
|
+
});
|
|
200
|
+
params.changes.push(`Moved ${path} → top-level bindings[] route for Discord channel ${channelId}.`);
|
|
201
|
+
}
|
|
202
|
+
if (!channelsChanged) continue;
|
|
203
|
+
nextGuilds[guildId] = {
|
|
204
|
+
...guild,
|
|
205
|
+
channels: nextChannels
|
|
206
|
+
};
|
|
207
|
+
changed = true;
|
|
208
|
+
}
|
|
209
|
+
return changed ? {
|
|
210
|
+
entry: {
|
|
211
|
+
...params.entry,
|
|
212
|
+
guilds: nextGuilds
|
|
213
|
+
},
|
|
214
|
+
changed: true
|
|
215
|
+
} : {
|
|
216
|
+
entry: params.entry,
|
|
217
|
+
changed: false
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
const legacyConfigRules = [
|
|
221
|
+
{
|
|
222
|
+
path: [
|
|
223
|
+
"channels",
|
|
224
|
+
"discord",
|
|
225
|
+
"voice",
|
|
226
|
+
"tts"
|
|
227
|
+
],
|
|
228
|
+
message: "channels.discord.voice.tts.<provider> keys (openai/elevenlabs/microsoft/edge) are legacy; use channels.discord.voice.tts.providers.<provider>. Run \"klaw doctor --fix\".",
|
|
229
|
+
match: hasLegacyTtsProviderKeys
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
path: [
|
|
233
|
+
"channels",
|
|
234
|
+
"discord",
|
|
235
|
+
"accounts"
|
|
236
|
+
],
|
|
237
|
+
message: "channels.discord.accounts.<id>.voice.tts.<provider> keys (openai/elevenlabs/microsoft/edge) are legacy; use channels.discord.accounts.<id>.voice.tts.providers.<provider>. Run \"klaw doctor --fix\".",
|
|
238
|
+
match: hasLegacyDiscordAccountTtsProviderKeys
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
path: ["channels", "discord"],
|
|
242
|
+
message: "channels.discord.guilds.<id>.channels.<id>.allow is legacy; use channels.discord.guilds.<id>.channels.<id>.enabled instead. Run \"klaw doctor --fix\".",
|
|
243
|
+
match: hasLegacyDiscordGuildChannelAllowAlias
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
path: [
|
|
247
|
+
"channels",
|
|
248
|
+
"discord",
|
|
249
|
+
"accounts"
|
|
250
|
+
],
|
|
251
|
+
message: "channels.discord.accounts.<id>.guilds.<id>.channels.<id>.allow is legacy; use channels.discord.accounts.<id>.guilds.<id>.channels.<id>.enabled instead. Run \"klaw doctor --fix\".",
|
|
252
|
+
match: hasLegacyDiscordAccountGuildChannelAllowAlias
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
path: ["channels", "discord"],
|
|
256
|
+
message: "channels.discord.guilds.<id>.channels.<id>.agentId is legacy; use top-level bindings[] for per-channel Discord agent routing. Run \"klaw doctor --fix\".",
|
|
257
|
+
match: hasLegacyDiscordGuildChannelAgentId
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
path: [
|
|
261
|
+
"channels",
|
|
262
|
+
"discord",
|
|
263
|
+
"accounts"
|
|
264
|
+
],
|
|
265
|
+
message: "channels.discord.accounts.<id>.guilds.<id>.channels.<id>.agentId is legacy; use top-level bindings[] with match.accountId for per-channel Discord agent routing. Run \"klaw doctor --fix\".",
|
|
266
|
+
match: hasLegacyDiscordAccountGuildChannelAgentId
|
|
267
|
+
}
|
|
268
|
+
];
|
|
269
|
+
function normalizeCompatibilityConfig({ cfg }) {
|
|
270
|
+
const rawEntry = asObjectRecord(cfg.channels?.discord);
|
|
271
|
+
if (!rawEntry) return {
|
|
272
|
+
config: cfg,
|
|
273
|
+
changes: []
|
|
274
|
+
};
|
|
275
|
+
const changes = [];
|
|
276
|
+
let updated = rawEntry;
|
|
277
|
+
let changed = false;
|
|
278
|
+
const bindingsToAdd = [];
|
|
279
|
+
const aliases = normalizeLegacyChannelAliases({
|
|
280
|
+
entry: rawEntry,
|
|
281
|
+
pathPrefix: "channels.discord",
|
|
282
|
+
changes,
|
|
283
|
+
normalizeDm: true,
|
|
284
|
+
normalizeAccountDm: true,
|
|
285
|
+
resolveStreamingOptions: (entry) => ({
|
|
286
|
+
resolvedMode: resolveDiscordPreviewStreamMode(entry),
|
|
287
|
+
includePreviewChunk: true
|
|
288
|
+
}),
|
|
289
|
+
normalizeAccountExtra: ({ account, pathPrefix }) => {
|
|
290
|
+
const accountVoice = asObjectRecord(account.voice);
|
|
291
|
+
if (!accountVoice || !migrateLegacyTtsConfig(asObjectRecord(accountVoice.tts), `${pathPrefix}.voice.tts`, changes)) return {
|
|
292
|
+
entry: account,
|
|
293
|
+
changed: false
|
|
294
|
+
};
|
|
295
|
+
return {
|
|
296
|
+
entry: {
|
|
297
|
+
...account,
|
|
298
|
+
voice: accountVoice
|
|
299
|
+
},
|
|
300
|
+
changed: true
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
updated = aliases.entry;
|
|
305
|
+
changed = aliases.changed;
|
|
306
|
+
const guildAliases = normalizeDiscordGuildChannelAllowAliases({
|
|
307
|
+
entry: updated,
|
|
308
|
+
pathPrefix: "channels.discord",
|
|
309
|
+
changes
|
|
310
|
+
});
|
|
311
|
+
updated = guildAliases.entry;
|
|
312
|
+
changed = changed || guildAliases.changed;
|
|
313
|
+
const channelAgentIds = normalizeDiscordGuildChannelAgentIds({
|
|
314
|
+
cfg,
|
|
315
|
+
entry: updated,
|
|
316
|
+
pathPrefix: "channels.discord",
|
|
317
|
+
changes,
|
|
318
|
+
bindingsToAdd
|
|
319
|
+
});
|
|
320
|
+
updated = channelAgentIds.entry;
|
|
321
|
+
changed = changed || channelAgentIds.changed;
|
|
322
|
+
const accounts = asObjectRecord(updated.accounts);
|
|
323
|
+
if (accounts) {
|
|
324
|
+
let accountsChanged = false;
|
|
325
|
+
const nextAccounts = { ...accounts };
|
|
326
|
+
for (const [accountId, accountValue] of Object.entries(accounts)) {
|
|
327
|
+
const account = asObjectRecord(accountValue);
|
|
328
|
+
if (!account) continue;
|
|
329
|
+
const normalized = normalizeDiscordGuildChannelAllowAliases({
|
|
330
|
+
entry: account,
|
|
331
|
+
pathPrefix: `channels.discord.accounts.${accountId}`,
|
|
332
|
+
changes
|
|
333
|
+
});
|
|
334
|
+
let nextAccount = normalized.entry;
|
|
335
|
+
let accountChanged = normalized.changed;
|
|
336
|
+
const normalizedAgentIds = normalizeDiscordGuildChannelAgentIds({
|
|
337
|
+
cfg,
|
|
338
|
+
entry: nextAccount,
|
|
339
|
+
pathPrefix: `channels.discord.accounts.${accountId}`,
|
|
340
|
+
accountId,
|
|
341
|
+
changes,
|
|
342
|
+
bindingsToAdd
|
|
343
|
+
});
|
|
344
|
+
nextAccount = normalizedAgentIds.entry;
|
|
345
|
+
accountChanged = accountChanged || normalizedAgentIds.changed;
|
|
346
|
+
if (!accountChanged) continue;
|
|
347
|
+
nextAccounts[accountId] = nextAccount;
|
|
348
|
+
accountsChanged = true;
|
|
349
|
+
}
|
|
350
|
+
if (accountsChanged) {
|
|
351
|
+
updated = {
|
|
352
|
+
...updated,
|
|
353
|
+
accounts: nextAccounts
|
|
354
|
+
};
|
|
355
|
+
changed = true;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
const voice = asObjectRecord(updated.voice);
|
|
359
|
+
if (voice && migrateLegacyTtsConfig(asObjectRecord(voice.tts), "channels.discord.voice.tts", changes)) {
|
|
360
|
+
updated = {
|
|
361
|
+
...updated,
|
|
362
|
+
voice
|
|
363
|
+
};
|
|
364
|
+
changed = true;
|
|
365
|
+
}
|
|
366
|
+
if (!changed) return {
|
|
367
|
+
config: cfg,
|
|
368
|
+
changes: []
|
|
369
|
+
};
|
|
370
|
+
return {
|
|
371
|
+
config: {
|
|
372
|
+
...cfg,
|
|
373
|
+
channels: {
|
|
374
|
+
...cfg.channels,
|
|
375
|
+
discord: updated
|
|
376
|
+
},
|
|
377
|
+
bindings: bindingsToAdd.length > 0 ? [...cfg.bindings ?? [], ...bindingsToAdd] : cfg.bindings
|
|
378
|
+
},
|
|
379
|
+
changes
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
//#endregion
|
|
383
|
+
export { normalizeCompatibilityConfig as n, legacyConfigRules as t };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
//#region extensions/discord/src/monitor/presence-cache.ts
|
|
2
|
+
/**
|
|
3
|
+
* In-memory cache of Discord user presence data.
|
|
4
|
+
* Populated by PRESENCE_UPDATE gateway events when the GuildPresences intent is enabled.
|
|
5
|
+
* Per-account maps are capped to prevent unbounded growth (#4948).
|
|
6
|
+
*/
|
|
7
|
+
const MAX_PRESENCE_PER_ACCOUNT = 5e3;
|
|
8
|
+
const presenceCache = /* @__PURE__ */ new Map();
|
|
9
|
+
function resolveAccountKey$1(accountId) {
|
|
10
|
+
return accountId ?? "default";
|
|
11
|
+
}
|
|
12
|
+
/** Update cached presence for a user. */
|
|
13
|
+
function setPresence(accountId, userId, data) {
|
|
14
|
+
const accountKey = resolveAccountKey$1(accountId);
|
|
15
|
+
let accountCache = presenceCache.get(accountKey);
|
|
16
|
+
if (!accountCache) {
|
|
17
|
+
accountCache = /* @__PURE__ */ new Map();
|
|
18
|
+
presenceCache.set(accountKey, accountCache);
|
|
19
|
+
}
|
|
20
|
+
accountCache.set(userId, data);
|
|
21
|
+
if (accountCache.size > MAX_PRESENCE_PER_ACCOUNT) {
|
|
22
|
+
const oldest = accountCache.keys().next().value;
|
|
23
|
+
if (oldest !== void 0) accountCache.delete(oldest);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/** Get cached presence for a user. Returns undefined if not cached. */
|
|
27
|
+
function getPresence(accountId, userId) {
|
|
28
|
+
return presenceCache.get(resolveAccountKey$1(accountId))?.get(userId);
|
|
29
|
+
}
|
|
30
|
+
/** Clear cached presence data. */
|
|
31
|
+
function clearPresences(accountId) {
|
|
32
|
+
if (accountId) {
|
|
33
|
+
presenceCache.delete(resolveAccountKey$1(accountId));
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
presenceCache.clear();
|
|
37
|
+
}
|
|
38
|
+
/** Get the number of cached presence entries. */
|
|
39
|
+
function presenceCacheSize() {
|
|
40
|
+
let total = 0;
|
|
41
|
+
for (const accountCache of presenceCache.values()) total += accountCache.size;
|
|
42
|
+
return total;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region extensions/discord/src/monitor/gateway-registry.ts
|
|
46
|
+
/**
|
|
47
|
+
* Module-level registry of active Discord GatewayPlugin instances.
|
|
48
|
+
* Bridges the gap between agent tool handlers (which only have REST access)
|
|
49
|
+
* and the gateway WebSocket (needed for operations like updatePresence).
|
|
50
|
+
* Follows the same pattern as presence-cache.ts.
|
|
51
|
+
*/
|
|
52
|
+
const gatewayRegistry = /* @__PURE__ */ new Map();
|
|
53
|
+
const DEFAULT_ACCOUNT_KEY = "\0__default__";
|
|
54
|
+
function resolveAccountKey(accountId) {
|
|
55
|
+
return accountId ?? DEFAULT_ACCOUNT_KEY;
|
|
56
|
+
}
|
|
57
|
+
/** Register a GatewayPlugin instance for an account. */
|
|
58
|
+
function registerGateway(accountId, gateway) {
|
|
59
|
+
gatewayRegistry.set(resolveAccountKey(accountId), gateway);
|
|
60
|
+
}
|
|
61
|
+
/** Unregister a GatewayPlugin instance for an account. */
|
|
62
|
+
function unregisterGateway(accountId) {
|
|
63
|
+
gatewayRegistry.delete(resolveAccountKey(accountId));
|
|
64
|
+
}
|
|
65
|
+
/** Get the GatewayPlugin for an account. Returns undefined if not registered. */
|
|
66
|
+
function getGateway(accountId) {
|
|
67
|
+
return gatewayRegistry.get(resolveAccountKey(accountId));
|
|
68
|
+
}
|
|
69
|
+
/** Clear all registered gateways (for testing). */
|
|
70
|
+
function clearGateways() {
|
|
71
|
+
gatewayRegistry.clear();
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { clearPresences as a, setPresence as c, unregisterGateway as i, getGateway as n, getPresence as o, registerGateway as r, presenceCacheSize as s, clearGateways as t };
|