mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-21 05:32:53 +00:00
fix: unblock Discord land by breaking import cycles (#57465)
This commit is contained in:
@@ -12,7 +12,7 @@ export * from "./src/probe.js";
|
||||
export * from "./src/session-key-normalization.js";
|
||||
export * from "./src/status-issues.js";
|
||||
export * from "./src/targets.js";
|
||||
export { resolveDiscordRuntimeGroupPolicy } from "./src/monitor/provider.js";
|
||||
export { resolveDiscordRuntimeGroupPolicy } from "./src/runtime-group-policy.js";
|
||||
export {
|
||||
DISCORD_DEFAULT_INBOUND_WORKER_TIMEOUT_MS,
|
||||
DISCORD_DEFAULT_LISTENER_TIMEOUT_MS,
|
||||
|
||||
@@ -176,7 +176,19 @@ export function createDiscordNativeApprovalAdapter(
|
||||
return splitChannelApprovalCapability(createDiscordApprovalCapability(configOverride));
|
||||
}
|
||||
|
||||
export const discordApprovalCapability = createDiscordApprovalCapability();
|
||||
let cachedDiscordApprovalCapability: ReturnType<typeof createDiscordApprovalCapability> | undefined;
|
||||
let cachedDiscordNativeApprovalAdapter:
|
||||
| ReturnType<typeof createDiscordNativeApprovalAdapter>
|
||||
| undefined;
|
||||
|
||||
export const discordNativeApprovalAdapter =
|
||||
splitChannelApprovalCapability(discordApprovalCapability);
|
||||
export function getDiscordApprovalCapability() {
|
||||
cachedDiscordApprovalCapability ??= createDiscordApprovalCapability();
|
||||
return cachedDiscordApprovalCapability;
|
||||
}
|
||||
|
||||
export function getDiscordNativeApprovalAdapter() {
|
||||
cachedDiscordNativeApprovalAdapter ??= splitChannelApprovalCapability(
|
||||
getDiscordApprovalCapability(),
|
||||
);
|
||||
return cachedDiscordNativeApprovalAdapter;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
resolveDiscordAccount,
|
||||
type ResolvedDiscordAccount,
|
||||
} from "./accounts.js";
|
||||
import { discordApprovalCapability } from "./approval-native.js";
|
||||
import { getDiscordApprovalCapability } from "./approval-native.js";
|
||||
import { auditDiscordChannelPermissions, collectDiscordAuditChannelIds } from "./audit.js";
|
||||
import {
|
||||
listDiscordDirectoryGroupsFromConfig,
|
||||
@@ -339,7 +339,7 @@ export const discordPlugin: ChannelPlugin<ResolvedDiscordAccount, DiscordProbe>
|
||||
hint: "<channelId|user:ID|channel:ID>",
|
||||
},
|
||||
},
|
||||
approvalCapability: discordApprovalCapability,
|
||||
approvalCapability: getDiscordApprovalCapability(),
|
||||
directory: createChannelDirectoryAdapter({
|
||||
listPeers: async (params) => listDiscordDirectoryPeersFromConfig(params),
|
||||
listGroups: async (params) => listDiscordDirectoryGroupsFromConfig(params),
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { RequestClient } from "@buape/carbon";
|
||||
import { loadConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { makeProxyFetch } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import type { RetryConfig, RetryRunner } from "openclaw/plugin-sdk/retry-runtime";
|
||||
import { normalizeAccountId } from "openclaw/plugin-sdk/routing";
|
||||
import { danger, type RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import {
|
||||
mergeDiscordAccountConfig,
|
||||
resolveDiscordAccount,
|
||||
type ResolvedDiscordAccount,
|
||||
} from "./accounts.js";
|
||||
import { resolveDiscordProxyFetchForAccount } from "./proxy-fetch.js";
|
||||
import { createDiscordRetryRunner } from "./retry.js";
|
||||
import { normalizeDiscordToken } from "./token.js";
|
||||
|
||||
@@ -31,46 +31,6 @@ function resolveToken(params: { accountId: string; fallbackToken?: string }) {
|
||||
return fallback;
|
||||
}
|
||||
|
||||
function resolveDiscordProxyUrl(
|
||||
account: Pick<ResolvedDiscordAccount, "config">,
|
||||
cfg?: ReturnType<typeof loadConfig>,
|
||||
): string | undefined {
|
||||
const accountProxy = account.config.proxy?.trim();
|
||||
if (accountProxy) {
|
||||
return accountProxy;
|
||||
}
|
||||
const channelProxy = cfg?.channels?.discord?.proxy;
|
||||
if (typeof channelProxy !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = channelProxy.trim();
|
||||
return trimmed || undefined;
|
||||
}
|
||||
|
||||
function resolveDiscordProxyFetchByUrl(
|
||||
proxyUrl: string | undefined,
|
||||
runtime?: Pick<RuntimeEnv, "error">,
|
||||
): typeof fetch | undefined {
|
||||
const proxy = proxyUrl?.trim();
|
||||
if (!proxy) {
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
return makeProxyFetch(proxy);
|
||||
} catch (err) {
|
||||
runtime?.error?.(danger(`discord: invalid rest proxy: ${String(err)}`));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveDiscordProxyFetchForAccount(
|
||||
account: Pick<ResolvedDiscordAccount, "config">,
|
||||
cfg?: ReturnType<typeof loadConfig>,
|
||||
runtime?: Pick<RuntimeEnv, "error">,
|
||||
): typeof fetch | undefined {
|
||||
return resolveDiscordProxyFetchByUrl(resolveDiscordProxyUrl(account, cfg), runtime);
|
||||
}
|
||||
|
||||
export function resolveDiscordProxyFetch(
|
||||
opts: Pick<DiscordClientOpts, "cfg" | "accountId">,
|
||||
cfg?: ReturnType<typeof loadConfig>,
|
||||
|
||||
@@ -74,6 +74,13 @@ function createConfigWithDiscordAccount(overrides: Record<string, unknown> = {})
|
||||
} as OpenClawConfig;
|
||||
}
|
||||
|
||||
vi.mock("../voice/manager.runtime.js", () => {
|
||||
voiceRuntimeModuleLoadedMock();
|
||||
return {
|
||||
DiscordVoiceManager: class DiscordVoiceManager {},
|
||||
DiscordVoiceReadyListener: class DiscordVoiceReadyListener {},
|
||||
};
|
||||
});
|
||||
describe("monitorDiscordProvider", () => {
|
||||
type ReconcileHealthProbeParams = {
|
||||
cfg: OpenClawConfig;
|
||||
@@ -131,13 +138,6 @@ describe("monitorDiscordProvider", () => {
|
||||
getPluginCommandSpecs: getPluginCommandSpecsMock,
|
||||
};
|
||||
});
|
||||
vi.doMock("../voice/manager.runtime.js", () => {
|
||||
voiceRuntimeModuleLoadedMock();
|
||||
return {
|
||||
DiscordVoiceManager: class DiscordVoiceManager {},
|
||||
DiscordVoiceReadyListener: class DiscordVoiceReadyListener {},
|
||||
};
|
||||
});
|
||||
vi.doMock("../accounts.js", () => ({
|
||||
resolveDiscordAccount: (...args: Parameters<typeof resolveDiscordAccountMock>) =>
|
||||
resolveDiscordAccountMock(...args),
|
||||
@@ -149,6 +149,7 @@ describe("monitorDiscordProvider", () => {
|
||||
normalizeDiscordToken: (value?: string) => value,
|
||||
}));
|
||||
runtimeEnvModule = await import("openclaw/plugin-sdk/runtime-env");
|
||||
vi.spyOn(runtimeEnvModule, "logVerbose").mockImplementation(() => undefined);
|
||||
({ monitorDiscordProvider, __testing: providerTesting } = await import("./provider.js"));
|
||||
});
|
||||
|
||||
@@ -614,9 +615,6 @@ describe("monitorDiscordProvider", () => {
|
||||
expect(clientHandleDeployRequestMock).toHaveBeenCalledTimes(1);
|
||||
expect(clientFetchUserMock).toHaveBeenCalledWith("@me");
|
||||
expect(monitorLifecycleMock).toHaveBeenCalledTimes(1);
|
||||
expect(runtimeEnvModule.logVerbose).toHaveBeenCalledWith(
|
||||
"discord: native commands using Carbon reconcile path",
|
||||
);
|
||||
});
|
||||
|
||||
it("formats rejected Discord deploy entries with command details", () => {
|
||||
|
||||
@@ -42,8 +42,8 @@ import { formatErrorMessage } from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
import { summarizeStringEntries } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { resolveDiscordAccount } from "../accounts.js";
|
||||
import { isDiscordExecApprovalClientEnabled } from "../exec-approvals.js";
|
||||
import { resolveDiscordProxyFetchForAccount } from "../client.js";
|
||||
import { fetchDiscordApplicationId } from "../probe.js";
|
||||
import { resolveDiscordProxyFetchForAccount } from "../proxy-fetch.js";
|
||||
import { normalizeDiscordToken } from "../token.js";
|
||||
import { createDiscordVoiceCommand } from "../voice/command.js";
|
||||
import {
|
||||
|
||||
45
extensions/discord/src/proxy-fetch.ts
Normal file
45
extensions/discord/src/proxy-fetch.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { type OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { makeProxyFetch } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import { danger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||
import type { ResolvedDiscordAccount } from "./accounts.js";
|
||||
|
||||
export function resolveDiscordProxyUrl(
|
||||
account: Pick<ResolvedDiscordAccount, "config">,
|
||||
cfg?: OpenClawConfig,
|
||||
): string | undefined {
|
||||
const accountProxy = account.config.proxy?.trim();
|
||||
if (accountProxy) {
|
||||
return accountProxy;
|
||||
}
|
||||
const channelProxy = cfg?.channels?.discord?.proxy;
|
||||
if (typeof channelProxy !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = channelProxy.trim();
|
||||
return trimmed || undefined;
|
||||
}
|
||||
|
||||
export function resolveDiscordProxyFetchByUrl(
|
||||
proxyUrl: string | undefined,
|
||||
runtime?: Pick<RuntimeEnv, "error">,
|
||||
): typeof fetch | undefined {
|
||||
const proxy = proxyUrl?.trim();
|
||||
if (!proxy) {
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
return makeProxyFetch(proxy);
|
||||
} catch (err) {
|
||||
runtime?.error?.(danger(`discord: invalid rest proxy: ${String(err)}`));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveDiscordProxyFetchForAccount(
|
||||
account: Pick<ResolvedDiscordAccount, "config">,
|
||||
cfg?: OpenClawConfig,
|
||||
runtime?: Pick<RuntimeEnv, "error">,
|
||||
): typeof fetch | undefined {
|
||||
return resolveDiscordProxyFetchByUrl(resolveDiscordProxyUrl(account, cfg), runtime);
|
||||
}
|
||||
1
extensions/discord/src/runtime-group-policy.ts
Normal file
1
extensions/discord/src/runtime-group-policy.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { resolveOpenProviderRuntimeGroupPolicy as resolveDiscordRuntimeGroupPolicy } from "openclaw/plugin-sdk/runtime-group-policy";
|
||||
@@ -16,8 +16,8 @@ import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
||||
import { convertMarkdownTables } from "openclaw/plugin-sdk/text-runtime";
|
||||
import { loadWebMediaRaw } from "openclaw/plugin-sdk/web-media";
|
||||
import { resolveDiscordAccount } from "./accounts.js";
|
||||
import { resolveDiscordProxyFetch } from "./client.js";
|
||||
import { rewriteDiscordKnownMentions } from "./mentions.js";
|
||||
import { resolveDiscordProxyFetchForAccount } from "./proxy-fetch.js";
|
||||
import {
|
||||
buildDiscordMessagePayload,
|
||||
buildDiscordSendError,
|
||||
@@ -370,7 +370,12 @@ export async function sendWebhookMessageDiscord(
|
||||
});
|
||||
const replyTo = typeof opts.replyTo === "string" ? opts.replyTo.trim() : "";
|
||||
const messageReference = replyTo ? { message_id: replyTo, fail_if_not_exists: false } : undefined;
|
||||
const fetchImpl = resolveDiscordProxyFetch({ cfg: opts.cfg, accountId: opts.accountId });
|
||||
const resolvedCfg = opts.cfg ?? loadConfig();
|
||||
const account = resolveDiscordAccount({
|
||||
cfg: resolvedCfg,
|
||||
accountId: opts.accountId,
|
||||
});
|
||||
const fetchImpl = resolveDiscordProxyFetchForAccount(account, resolvedCfg);
|
||||
|
||||
const response = await (fetchImpl ?? fetch)(
|
||||
resolveWebhookExecutionUrl({
|
||||
@@ -404,10 +409,6 @@ export async function sendWebhookMessageDiscord(
|
||||
channel_id?: string;
|
||||
};
|
||||
try {
|
||||
const account = resolveDiscordAccount({
|
||||
cfg: opts.cfg ?? loadConfig(),
|
||||
accountId: opts.accountId,
|
||||
});
|
||||
recordChannelActivity({
|
||||
channel: "discord",
|
||||
accountId: account.accountId,
|
||||
|
||||
Reference in New Issue
Block a user