From 7c18b765e82b6ffd2a432468ccccc71c26a20114 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 24 Apr 2026 03:27:29 +0100 Subject: [PATCH] perf: reduce discord provider test imports --- .../discord/src/monitor/provider.test.ts | 37 ++++++++++++++++--- extensions/discord/src/monitor/provider.ts | 27 +++++++++----- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/extensions/discord/src/monitor/provider.test.ts b/extensions/discord/src/monitor/provider.test.ts index 9e4ceb4904a..272e9c5afc6 100644 --- a/extensions/discord/src/monitor/provider.test.ts +++ b/extensions/discord/src/monitor/provider.test.ts @@ -1,9 +1,8 @@ import { EventEmitter } from "node:events"; import { RateLimitError } from "@buape/carbon"; -import { AcpRuntimeError } from "openclaw/plugin-sdk/acp-runtime"; +import type { ChannelRuntimeSurface } from "openclaw/plugin-sdk/channel-contract"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { createRuntimeChannel } from "../../../../src/plugins/runtime/runtime-channel.js"; import { baseConfig, baseRuntime, @@ -41,6 +40,34 @@ let monitorDiscordProvider: typeof import("./provider.js").monitorDiscordProvide let providerTesting: typeof import("./provider.js").__testing; let runtimeEnvModule: typeof import("openclaw/plugin-sdk/runtime-env"); +function createAcpRuntimeError(code: string, message: string): Error & { code: string } { + return Object.assign(new Error(message), { code }); +} + +function createTestChannelRuntime(): ChannelRuntimeSurface { + const contexts = new Map(); + const keyFor = (params: { channelId: string; accountId?: string | null; capability: string }) => + `${params.channelId}:${params.accountId ?? ""}:${params.capability}`; + const runtimeContexts: ChannelRuntimeSurface["runtimeContexts"] = { + register(params) { + contexts.set(keyFor(params), params.context); + return { + dispose: () => { + contexts.delete(keyFor(params)); + }, + }; + }, + get: ((params: { channelId: string; accountId?: string | null; capability: string }) => + contexts.get(keyFor(params))) as ChannelRuntimeSurface["runtimeContexts"]["get"], + watch() { + return () => {}; + }, + }; + return { + runtimeContexts, + }; +} + function createCompatRateLimitError( response: Response, body: { message: string; retry_after: number; global: boolean }, @@ -348,7 +375,7 @@ describe("monitorDiscordProvider", () => { }); it("registers the native approval runtime context when exec approvals are enabled", async () => { - const channelRuntime = createRuntimeChannel(); + const channelRuntime = createTestChannelRuntime(); const execApprovalsConfig = { enabled: true, approvers: ["123"] }; resolveDiscordAccountMock.mockReturnValue({ accountId: "default", @@ -408,7 +435,7 @@ describe("monitorDiscordProvider", () => { it("classifies typed ACP session init failures as stale", async () => { getAcpSessionStatusMock.mockRejectedValue( - new AcpRuntimeError("ACP_SESSION_INIT_FAILED", "missing ACP metadata"), + createAcpRuntimeError("ACP_SESSION_INIT_FAILED", "missing ACP metadata"), ); await monitorDiscordProvider({ @@ -437,7 +464,7 @@ describe("monitorDiscordProvider", () => { it("classifies typed non-init ACP errors as uncertain when not stale-running", async () => { getAcpSessionStatusMock.mockRejectedValue( - new AcpRuntimeError("ACP_BACKEND_UNAVAILABLE", "runtime unavailable"), + createAcpRuntimeError("ACP_BACKEND_UNAVAILABLE", "runtime unavailable"), ); await monitorDiscordProvider({ diff --git a/extensions/discord/src/monitor/provider.ts b/extensions/discord/src/monitor/provider.ts index d28b0cd0082..f731968b325 100644 --- a/extensions/discord/src/monitor/provider.ts +++ b/extensions/discord/src/monitor/provider.ts @@ -24,7 +24,6 @@ import { import type { OpenClawConfig, ReplyToMode } from "openclaw/plugin-sdk/config-runtime"; import { loadConfig } from "openclaw/plugin-sdk/config-runtime"; import { createConnectedChannelStatusPatch } from "openclaw/plugin-sdk/gateway-runtime"; -import { getPluginCommandSpecs } from "openclaw/plugin-sdk/plugin-runtime"; import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking"; import { danger, @@ -110,9 +109,12 @@ type DiscordVoiceManager = import("../voice/manager.js").DiscordVoiceManager; type DiscordVoiceRuntimeModule = typeof import("../voice/manager.runtime.js"); type DiscordProviderSessionRuntimeModule = typeof import("./provider-session.runtime.js"); +type GetPluginCommandSpecs = + typeof import("openclaw/plugin-sdk/plugin-runtime").getPluginCommandSpecs; let discordVoiceRuntimePromise: Promise | undefined; let discordProviderSessionRuntimePromise: Promise | undefined; +let pluginRuntimePromise: Promise | undefined; let fetchDiscordApplicationIdForTesting: typeof fetchDiscordApplicationId | undefined; let createDiscordNativeCommandForTesting: typeof createDiscordNativeCommand | undefined; @@ -130,7 +132,7 @@ let createClientForTesting: plugins: ConstructorParameters[2], ) => Client) | undefined; -let getPluginCommandSpecsForTesting: typeof getPluginCommandSpecs | undefined; +let getPluginCommandSpecsForTesting: GetPluginCommandSpecs | undefined; let resolveDiscordAccountForTesting: typeof resolveDiscordAccount | undefined; let resolveNativeCommandsEnabledForTesting: typeof resolveNativeCommandsEnabled | undefined; let resolveNativeSkillsEnabledForTesting: typeof resolveNativeSkillsEnabled | undefined; @@ -155,6 +157,11 @@ async function loadDiscordProviderSessionRuntime(): Promise { const merged = [...params.commandSpecs]; const existingNames = new Set( merged.map((spec) => normalizeLowercaseStringOrEmpty(spec.name)).filter(Boolean), ); - for (const pluginCommand of (getPluginCommandSpecsForTesting ?? getPluginCommandSpecs)( - "discord", - )) { + const getPluginCommandSpecs = + getPluginCommandSpecsForTesting ?? (await loadPluginRuntime()).getPluginCommandSpecs; + for (const pluginCommand of getPluginCommandSpecs("discord")) { const normalizedName = normalizeLowercaseStringOrEmpty(pluginCommand.name); if (!normalizedName) { continue; @@ -740,7 +747,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { }) : []; if (nativeEnabled) { - commandSpecs = appendPluginCommandSpecs({ commandSpecs, runtime }); + commandSpecs = await appendPluginCommandSpecs({ commandSpecs, runtime }); } const initialCommandCount = commandSpecs.length; if (nativeEnabled && nativeSkillsEnabled && commandSpecs.length > maxDiscordCommands) { @@ -749,7 +756,7 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) { cfg, { skillCommands: [], provider: "discord" }, ); - commandSpecs = appendPluginCommandSpecs({ commandSpecs, runtime }); + commandSpecs = await appendPluginCommandSpecs({ commandSpecs, runtime }); runtime.log?.( warn( `discord: ${initialCommandCount} commands exceeds limit; removing per-skill commands and keeping /skill.`, @@ -1201,7 +1208,7 @@ export const __testing = { ) { createClientForTesting = mock; }, - setGetPluginCommandSpecs(mock?: typeof getPluginCommandSpecs) { + setGetPluginCommandSpecs(mock?: GetPluginCommandSpecs) { getPluginCommandSpecsForTesting = mock; }, setResolveDiscordAccount(mock?: typeof resolveDiscordAccount) {