mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 20:40:43 +00:00
refactor: remove remaining extension core imports
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
|||||||
baseRuntime,
|
baseRuntime,
|
||||||
getProviderMonitorTestMocks,
|
getProviderMonitorTestMocks,
|
||||||
resetDiscordProviderMonitorMocks,
|
resetDiscordProviderMonitorMocks,
|
||||||
} from "./provider.test-support.js";
|
} from "../../../test-utils/discord-provider.test-support.js";
|
||||||
|
|
||||||
const { createDiscordNativeCommandMock, clientHandleDeployRequestMock, monitorLifecycleMock } =
|
const { createDiscordNativeCommandMock, clientHandleDeployRequestMock, monitorLifecycleMock } =
|
||||||
getProviderMonitorTestMocks();
|
getProviderMonitorTestMocks();
|
||||||
|
|||||||
@@ -1,459 +1 @@
|
|||||||
import type { Mock } from "vitest";
|
export * from "../../../test-utils/discord-provider.test-support.js";
|
||||||
import { expect, vi } from "vitest";
|
|
||||||
import type { OpenClawConfig } from "../../../../src/config/config.js";
|
|
||||||
import type { RuntimeEnv } from "../../../../src/runtime.js";
|
|
||||||
|
|
||||||
export type NativeCommandSpecMock = {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
acceptsArgs: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PluginCommandSpecMock = {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
acceptsArgs: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type ProviderMonitorTestMocks = {
|
|
||||||
clientHandleDeployRequestMock: Mock<() => Promise<void>>;
|
|
||||||
clientFetchUserMock: Mock<(target: string) => Promise<{ id: string }>>;
|
|
||||||
clientGetPluginMock: Mock<(name: string) => unknown>;
|
|
||||||
clientConstructorOptionsMock: Mock<(options?: unknown) => void>;
|
|
||||||
createDiscordAutoPresenceControllerMock: Mock<() => unknown>;
|
|
||||||
createDiscordNativeCommandMock: Mock<(params?: { command?: { name?: string } }) => unknown>;
|
|
||||||
createDiscordMessageHandlerMock: Mock<() => unknown>;
|
|
||||||
createNoopThreadBindingManagerMock: Mock<() => { stop: ReturnType<typeof vi.fn> }>;
|
|
||||||
createThreadBindingManagerMock: Mock<() => { stop: ReturnType<typeof vi.fn> }>;
|
|
||||||
reconcileAcpThreadBindingsOnStartupMock: Mock<() => unknown>;
|
|
||||||
createdBindingManagers: Array<{ stop: ReturnType<typeof vi.fn> }>;
|
|
||||||
getAcpSessionStatusMock: Mock<
|
|
||||||
(params: {
|
|
||||||
cfg: OpenClawConfig;
|
|
||||||
sessionKey: string;
|
|
||||||
signal?: AbortSignal;
|
|
||||||
}) => Promise<{ state: string }>
|
|
||||||
>;
|
|
||||||
getPluginCommandSpecsMock: Mock<() => PluginCommandSpecMock[]>;
|
|
||||||
listNativeCommandSpecsForConfigMock: Mock<() => NativeCommandSpecMock[]>;
|
|
||||||
listSkillCommandsForAgentsMock: Mock<() => unknown[]>;
|
|
||||||
monitorLifecycleMock: Mock<(params: { threadBindings: { stop: () => void } }) => Promise<void>>;
|
|
||||||
resolveDiscordAccountMock: Mock<() => unknown>;
|
|
||||||
resolveDiscordAllowlistConfigMock: Mock<() => Promise<unknown>>;
|
|
||||||
resolveNativeCommandsEnabledMock: Mock<() => boolean>;
|
|
||||||
resolveNativeSkillsEnabledMock: Mock<() => boolean>;
|
|
||||||
isVerboseMock: Mock<() => boolean>;
|
|
||||||
shouldLogVerboseMock: Mock<() => boolean>;
|
|
||||||
voiceRuntimeModuleLoadedMock: Mock<() => void>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function baseDiscordAccountConfig() {
|
|
||||||
return {
|
|
||||||
commands: { native: true, nativeSkills: false },
|
|
||||||
voice: { enabled: false },
|
|
||||||
agentComponents: { enabled: false },
|
|
||||||
execApprovals: { enabled: false },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const providerMonitorTestMocks: ProviderMonitorTestMocks = vi.hoisted(() => {
|
|
||||||
const createdBindingManagers: Array<{ stop: ReturnType<typeof vi.fn> }> = [];
|
|
||||||
const isVerboseMock = vi.fn(() => false);
|
|
||||||
const shouldLogVerboseMock = vi.fn(() => false);
|
|
||||||
|
|
||||||
return {
|
|
||||||
clientHandleDeployRequestMock: vi.fn(async () => undefined),
|
|
||||||
clientFetchUserMock: vi.fn(async (_target: string) => ({ id: "bot-1" })),
|
|
||||||
clientGetPluginMock: vi.fn<(_name: string) => unknown>(() => undefined),
|
|
||||||
clientConstructorOptionsMock: vi.fn(),
|
|
||||||
createDiscordAutoPresenceControllerMock: vi.fn(() => ({
|
|
||||||
enabled: false,
|
|
||||||
start: vi.fn(),
|
|
||||||
stop: vi.fn(),
|
|
||||||
refresh: vi.fn(),
|
|
||||||
runNow: vi.fn(),
|
|
||||||
})),
|
|
||||||
createDiscordNativeCommandMock: vi.fn((params?: { command?: { name?: string } }) => ({
|
|
||||||
name: params?.command?.name ?? "mock-command",
|
|
||||||
})),
|
|
||||||
createDiscordMessageHandlerMock: vi.fn(() =>
|
|
||||||
Object.assign(
|
|
||||||
vi.fn(async () => undefined),
|
|
||||||
{
|
|
||||||
deactivate: vi.fn(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
createNoopThreadBindingManagerMock: vi.fn(() => {
|
|
||||||
const manager = { stop: vi.fn() };
|
|
||||||
createdBindingManagers.push(manager);
|
|
||||||
return manager;
|
|
||||||
}),
|
|
||||||
createThreadBindingManagerMock: vi.fn(() => {
|
|
||||||
const manager = { stop: vi.fn() };
|
|
||||||
createdBindingManagers.push(manager);
|
|
||||||
return manager;
|
|
||||||
}),
|
|
||||||
reconcileAcpThreadBindingsOnStartupMock: vi.fn(() => ({
|
|
||||||
checked: 0,
|
|
||||||
removed: 0,
|
|
||||||
staleSessionKeys: [],
|
|
||||||
})),
|
|
||||||
createdBindingManagers,
|
|
||||||
getAcpSessionStatusMock: vi.fn(
|
|
||||||
async (_params: { cfg: OpenClawConfig; sessionKey: string; signal?: AbortSignal }) => ({
|
|
||||||
state: "idle",
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
getPluginCommandSpecsMock: vi.fn<() => PluginCommandSpecMock[]>(() => []),
|
|
||||||
listNativeCommandSpecsForConfigMock: vi.fn<() => NativeCommandSpecMock[]>(() => [
|
|
||||||
{ name: "cmd", description: "built-in", acceptsArgs: false },
|
|
||||||
]),
|
|
||||||
listSkillCommandsForAgentsMock: vi.fn(() => []),
|
|
||||||
monitorLifecycleMock: vi.fn(async (params: { threadBindings: { stop: () => void } }) => {
|
|
||||||
params.threadBindings.stop();
|
|
||||||
}),
|
|
||||||
resolveDiscordAccountMock: vi.fn(() => ({
|
|
||||||
accountId: "default",
|
|
||||||
token: "cfg-token",
|
|
||||||
config: baseDiscordAccountConfig(),
|
|
||||||
})),
|
|
||||||
resolveDiscordAllowlistConfigMock: vi.fn(async () => ({
|
|
||||||
guildEntries: undefined,
|
|
||||||
allowFrom: undefined,
|
|
||||||
})),
|
|
||||||
resolveNativeCommandsEnabledMock: vi.fn(() => true),
|
|
||||||
resolveNativeSkillsEnabledMock: vi.fn(() => false),
|
|
||||||
isVerboseMock,
|
|
||||||
shouldLogVerboseMock,
|
|
||||||
voiceRuntimeModuleLoadedMock: vi.fn(),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
|
||||||
clientHandleDeployRequestMock,
|
|
||||||
clientFetchUserMock,
|
|
||||||
clientGetPluginMock,
|
|
||||||
clientConstructorOptionsMock,
|
|
||||||
createDiscordAutoPresenceControllerMock,
|
|
||||||
createDiscordNativeCommandMock,
|
|
||||||
createDiscordMessageHandlerMock,
|
|
||||||
createNoopThreadBindingManagerMock,
|
|
||||||
createThreadBindingManagerMock,
|
|
||||||
reconcileAcpThreadBindingsOnStartupMock,
|
|
||||||
createdBindingManagers,
|
|
||||||
getAcpSessionStatusMock,
|
|
||||||
getPluginCommandSpecsMock,
|
|
||||||
listNativeCommandSpecsForConfigMock,
|
|
||||||
listSkillCommandsForAgentsMock,
|
|
||||||
monitorLifecycleMock,
|
|
||||||
resolveDiscordAccountMock,
|
|
||||||
resolveDiscordAllowlistConfigMock,
|
|
||||||
resolveNativeCommandsEnabledMock,
|
|
||||||
resolveNativeSkillsEnabledMock,
|
|
||||||
isVerboseMock,
|
|
||||||
shouldLogVerboseMock,
|
|
||||||
voiceRuntimeModuleLoadedMock,
|
|
||||||
} = providerMonitorTestMocks;
|
|
||||||
|
|
||||||
export function getProviderMonitorTestMocks(): typeof providerMonitorTestMocks {
|
|
||||||
return providerMonitorTestMocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mockResolvedDiscordAccountConfig(overrides: Record<string, unknown>) {
|
|
||||||
resolveDiscordAccountMock.mockImplementation(() => ({
|
|
||||||
accountId: "default",
|
|
||||||
token: "cfg-token",
|
|
||||||
config: {
|
|
||||||
...baseDiscordAccountConfig(),
|
|
||||||
...overrides,
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getFirstDiscordMessageHandlerParams<T extends object>() {
|
|
||||||
expect(createDiscordMessageHandlerMock).toHaveBeenCalledTimes(1);
|
|
||||||
const firstCall = createDiscordMessageHandlerMock.mock.calls.at(0) as [T] | undefined;
|
|
||||||
return firstCall?.[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resetDiscordProviderMonitorMocks(params?: {
|
|
||||||
nativeCommands?: NativeCommandSpecMock[];
|
|
||||||
}) {
|
|
||||||
clientHandleDeployRequestMock.mockClear().mockResolvedValue(undefined);
|
|
||||||
clientFetchUserMock.mockClear().mockResolvedValue({ id: "bot-1" });
|
|
||||||
clientGetPluginMock.mockClear().mockReturnValue(undefined);
|
|
||||||
clientConstructorOptionsMock.mockClear();
|
|
||||||
createDiscordAutoPresenceControllerMock.mockClear().mockImplementation(() => ({
|
|
||||||
enabled: false,
|
|
||||||
start: vi.fn(),
|
|
||||||
stop: vi.fn(),
|
|
||||||
refresh: vi.fn(),
|
|
||||||
runNow: vi.fn(),
|
|
||||||
}));
|
|
||||||
createDiscordNativeCommandMock.mockClear().mockImplementation((input) => ({
|
|
||||||
name: input?.command?.name ?? "mock-command",
|
|
||||||
}));
|
|
||||||
createDiscordMessageHandlerMock.mockClear().mockImplementation(() =>
|
|
||||||
Object.assign(
|
|
||||||
vi.fn(async () => undefined),
|
|
||||||
{
|
|
||||||
deactivate: vi.fn(),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
createNoopThreadBindingManagerMock.mockClear();
|
|
||||||
createThreadBindingManagerMock.mockClear();
|
|
||||||
reconcileAcpThreadBindingsOnStartupMock.mockClear().mockReturnValue({
|
|
||||||
checked: 0,
|
|
||||||
removed: 0,
|
|
||||||
staleSessionKeys: [],
|
|
||||||
});
|
|
||||||
createdBindingManagers.length = 0;
|
|
||||||
getAcpSessionStatusMock.mockClear().mockResolvedValue({ state: "idle" });
|
|
||||||
getPluginCommandSpecsMock.mockClear().mockReturnValue([]);
|
|
||||||
listNativeCommandSpecsForConfigMock
|
|
||||||
.mockClear()
|
|
||||||
.mockReturnValue(
|
|
||||||
params?.nativeCommands ?? [{ name: "cmd", description: "built-in", acceptsArgs: false }],
|
|
||||||
);
|
|
||||||
listSkillCommandsForAgentsMock.mockClear().mockReturnValue([]);
|
|
||||||
monitorLifecycleMock.mockClear().mockImplementation(async (monitorParams) => {
|
|
||||||
monitorParams.threadBindings.stop();
|
|
||||||
});
|
|
||||||
resolveDiscordAccountMock.mockClear().mockReturnValue({
|
|
||||||
accountId: "default",
|
|
||||||
token: "cfg-token",
|
|
||||||
config: baseDiscordAccountConfig(),
|
|
||||||
});
|
|
||||||
resolveDiscordAllowlistConfigMock.mockClear().mockResolvedValue({
|
|
||||||
guildEntries: undefined,
|
|
||||||
allowFrom: undefined,
|
|
||||||
});
|
|
||||||
resolveNativeCommandsEnabledMock.mockClear().mockReturnValue(true);
|
|
||||||
resolveNativeSkillsEnabledMock.mockClear().mockReturnValue(false);
|
|
||||||
isVerboseMock.mockClear().mockReturnValue(false);
|
|
||||||
shouldLogVerboseMock.mockClear().mockReturnValue(false);
|
|
||||||
voiceRuntimeModuleLoadedMock.mockClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
export const baseRuntime = (): RuntimeEnv => ({
|
|
||||||
log: vi.fn(),
|
|
||||||
error: vi.fn(),
|
|
||||||
exit: vi.fn(),
|
|
||||||
});
|
|
||||||
|
|
||||||
export const baseConfig = (): OpenClawConfig =>
|
|
||||||
({
|
|
||||||
channels: {
|
|
||||||
discord: {
|
|
||||||
accounts: {
|
|
||||||
default: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}) as OpenClawConfig;
|
|
||||||
|
|
||||||
vi.mock("@buape/carbon", () => {
|
|
||||||
class ReadyListener {}
|
|
||||||
class RateLimitError extends Error {
|
|
||||||
status = 429;
|
|
||||||
discordCode?: number;
|
|
||||||
retryAfter: number;
|
|
||||||
scope: string | null;
|
|
||||||
bucket: string | null;
|
|
||||||
constructor(
|
|
||||||
response: Response,
|
|
||||||
body: { message: string; retry_after: number; global: boolean },
|
|
||||||
) {
|
|
||||||
super(body.message);
|
|
||||||
this.retryAfter = body.retry_after;
|
|
||||||
this.scope = body.global ? "global" : response.headers.get("X-RateLimit-Scope");
|
|
||||||
this.bucket = response.headers.get("X-RateLimit-Bucket");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
class Client {
|
|
||||||
listeners: unknown[];
|
|
||||||
rest: { put: ReturnType<typeof vi.fn> };
|
|
||||||
options: unknown;
|
|
||||||
constructor(options: unknown, handlers: { listeners?: unknown[] }) {
|
|
||||||
this.options = options;
|
|
||||||
this.listeners = handlers.listeners ?? [];
|
|
||||||
this.rest = { put: vi.fn(async () => undefined) };
|
|
||||||
clientConstructorOptionsMock(options);
|
|
||||||
}
|
|
||||||
async handleDeployRequest() {
|
|
||||||
return await clientHandleDeployRequestMock();
|
|
||||||
}
|
|
||||||
async fetchUser(target: string) {
|
|
||||||
return await clientFetchUserMock(target);
|
|
||||||
}
|
|
||||||
getPlugin(name: string) {
|
|
||||||
return clientGetPluginMock(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { Client, RateLimitError, ReadyListener };
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.mock("@buape/carbon/gateway", () => ({
|
|
||||||
GatewayCloseCodes: { DisallowedIntents: 4014 },
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("@buape/carbon/voice", () => ({
|
|
||||||
VoicePlugin: class VoicePlugin {},
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/acp/control-plane/manager.js", () => ({
|
|
||||||
getAcpSessionManager: () => ({
|
|
||||||
getSessionStatus: getAcpSessionStatusMock,
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/auto-reply/chunk.js", () => ({
|
|
||||||
resolveTextChunkLimit: () => 2000,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/auto-reply/commands-registry.js", () => ({
|
|
||||||
listNativeCommandSpecsForConfig: listNativeCommandSpecsForConfigMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/auto-reply/skill-commands.js", () => ({
|
|
||||||
listSkillCommandsForAgents: listSkillCommandsForAgentsMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/config/commands.js", () => ({
|
|
||||||
isNativeCommandsExplicitlyDisabled: () => false,
|
|
||||||
resolveNativeCommandsEnabled: resolveNativeCommandsEnabledMock,
|
|
||||||
resolveNativeSkillsEnabled: resolveNativeSkillsEnabledMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/config/config.js", () => ({
|
|
||||||
loadConfig: () => ({}),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/globals.js", () => ({
|
|
||||||
danger: (value: string) => value,
|
|
||||||
isVerbose: isVerboseMock,
|
|
||||||
logVerbose: vi.fn(),
|
|
||||||
shouldLogVerbose: shouldLogVerboseMock,
|
|
||||||
warn: (value: string) => value,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/infra/errors.js", () => ({
|
|
||||||
formatErrorMessage: (error: unknown) => String(error),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/infra/retry-policy.js", () => ({
|
|
||||||
createDiscordRetryRunner: () => async (run: () => Promise<unknown>) => run(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/logging/subsystem.js", () => ({
|
|
||||||
createSubsystemLogger: () => {
|
|
||||||
const logger = {
|
|
||||||
child: vi.fn(() => logger),
|
|
||||||
info: vi.fn(),
|
|
||||||
error: vi.fn(),
|
|
||||||
warn: vi.fn(),
|
|
||||||
debug: vi.fn(),
|
|
||||||
};
|
|
||||||
return logger;
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../../../../src/runtime.js", () => ({
|
|
||||||
createNonExitingRuntime: () => ({ log: vi.fn(), error: vi.fn(), exit: vi.fn() }),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../accounts.js", () => ({
|
|
||||||
resolveDiscordAccount: resolveDiscordAccountMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../probe.js", () => ({
|
|
||||||
fetchDiscordApplicationId: async () => "app-1",
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../token.js", () => ({
|
|
||||||
normalizeDiscordToken: (value?: string) => value,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("../voice/command.js", () => ({
|
|
||||||
createDiscordVoiceCommand: () => ({ name: "voice-command" }),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./agent-components.js", () => ({
|
|
||||||
createAgentComponentButton: () => ({ id: "btn" }),
|
|
||||||
createAgentSelectMenu: () => ({ id: "menu" }),
|
|
||||||
createDiscordComponentButton: () => ({ id: "btn2" }),
|
|
||||||
createDiscordComponentChannelSelect: () => ({ id: "channel" }),
|
|
||||||
createDiscordComponentMentionableSelect: () => ({ id: "mentionable" }),
|
|
||||||
createDiscordComponentModal: () => ({ id: "modal" }),
|
|
||||||
createDiscordComponentRoleSelect: () => ({ id: "role" }),
|
|
||||||
createDiscordComponentStringSelect: () => ({ id: "string" }),
|
|
||||||
createDiscordComponentUserSelect: () => ({ id: "user" }),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./auto-presence.js", () => ({
|
|
||||||
createDiscordAutoPresenceController: createDiscordAutoPresenceControllerMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./commands.js", () => ({
|
|
||||||
resolveDiscordSlashCommandConfig: () => ({ ephemeral: false }),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./exec-approvals.js", () => ({
|
|
||||||
createExecApprovalButton: () => ({ id: "exec-approval" }),
|
|
||||||
DiscordExecApprovalHandler: class DiscordExecApprovalHandler {
|
|
||||||
async start() {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
async stop() {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./gateway-plugin.js", () => ({
|
|
||||||
createDiscordGatewayPlugin: () => ({ id: "gateway-plugin" }),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./listeners.js", () => ({
|
|
||||||
DiscordMessageListener: class DiscordMessageListener {},
|
|
||||||
DiscordPresenceListener: class DiscordPresenceListener {},
|
|
||||||
DiscordReactionListener: class DiscordReactionListener {},
|
|
||||||
DiscordReactionRemoveListener: class DiscordReactionRemoveListener {},
|
|
||||||
DiscordThreadUpdateListener: class DiscordThreadUpdateListener {},
|
|
||||||
registerDiscordListener: vi.fn(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./message-handler.js", () => ({
|
|
||||||
createDiscordMessageHandler: createDiscordMessageHandlerMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./native-command.js", () => ({
|
|
||||||
createDiscordCommandArgFallbackButton: () => ({ id: "arg-fallback" }),
|
|
||||||
createDiscordModelPickerFallbackButton: () => ({ id: "model-fallback-btn" }),
|
|
||||||
createDiscordModelPickerFallbackSelect: () => ({ id: "model-fallback-select" }),
|
|
||||||
createDiscordNativeCommand: createDiscordNativeCommandMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./presence.js", () => ({
|
|
||||||
resolveDiscordPresenceUpdate: () => undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./provider.allowlist.js", () => ({
|
|
||||||
resolveDiscordAllowlistConfig: resolveDiscordAllowlistConfigMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./provider.lifecycle.js", () => ({
|
|
||||||
runDiscordGatewayLifecycle: monitorLifecycleMock,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./rest-fetch.js", () => ({
|
|
||||||
resolveDiscordRestFetch: () => async () => undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
vi.mock("./thread-bindings.js", () => ({
|
|
||||||
createNoopThreadBindingManager: createNoopThreadBindingManagerMock,
|
|
||||||
createThreadBindingManager: createThreadBindingManagerMock,
|
|
||||||
reconcileAcpThreadBindingsOnStartup: reconcileAcpThreadBindingsOnStartupMock,
|
|
||||||
}));
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
getProviderMonitorTestMocks,
|
getProviderMonitorTestMocks,
|
||||||
mockResolvedDiscordAccountConfig,
|
mockResolvedDiscordAccountConfig,
|
||||||
resetDiscordProviderMonitorMocks,
|
resetDiscordProviderMonitorMocks,
|
||||||
} from "./provider.test-support.js";
|
} from "../../../test-utils/discord-provider.test-support.js";
|
||||||
|
|
||||||
const {
|
const {
|
||||||
clientConstructorOptionsMock,
|
clientConstructorOptionsMock,
|
||||||
@@ -37,9 +37,15 @@ const {
|
|||||||
voiceRuntimeModuleLoadedMock,
|
voiceRuntimeModuleLoadedMock,
|
||||||
} = getProviderMonitorTestMocks();
|
} = getProviderMonitorTestMocks();
|
||||||
|
|
||||||
vi.mock("../../../../src/plugins/commands.js", () => ({
|
vi.mock("openclaw/plugin-sdk/plugin-runtime", async () => {
|
||||||
getPluginCommandSpecs: getPluginCommandSpecsMock,
|
const actual = await vi.importActual<typeof import("openclaw/plugin-sdk/plugin-runtime")>(
|
||||||
}));
|
"openclaw/plugin-sdk/plugin-runtime",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
getPluginCommandSpecs: getPluginCommandSpecsMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
vi.mock("../voice/manager.runtime.js", () => {
|
vi.mock("../voice/manager.runtime.js", () => {
|
||||||
voiceRuntimeModuleLoadedMock();
|
voiceRuntimeModuleLoadedMock();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { DiscordGuildEntry } from "openclaw/plugin-sdk/config-runtime";
|
|||||||
import {
|
import {
|
||||||
DEFAULT_ACCOUNT_ID,
|
DEFAULT_ACCOUNT_ID,
|
||||||
createEnvPatchedAccountSetupAdapter,
|
createEnvPatchedAccountSetupAdapter,
|
||||||
|
formatDocsLink,
|
||||||
noteChannelLookupFailure,
|
noteChannelLookupFailure,
|
||||||
noteChannelLookupSummary,
|
noteChannelLookupSummary,
|
||||||
parseMentionOrPrefixedId,
|
parseMentionOrPrefixedId,
|
||||||
@@ -16,7 +17,6 @@ import {
|
|||||||
type ChannelSetupDmPolicy,
|
type ChannelSetupDmPolicy,
|
||||||
type ChannelSetupWizard,
|
type ChannelSetupWizard,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import { inspectDiscordAccount } from "./account-inspect.js";
|
import { inspectDiscordAccount } from "./account-inspect.js";
|
||||||
import { listDiscordAccountIds, resolveDiscordAccount } from "./accounts.js";
|
import { listDiscordAccountIds, resolveDiscordAccount } from "./accounts.js";
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {
|
import {
|
||||||
|
formatDocsLink,
|
||||||
type OpenClawConfig,
|
type OpenClawConfig,
|
||||||
promptLegacyChannelAllowFrom,
|
promptLegacyChannelAllowFrom,
|
||||||
resolveSetupAccountId,
|
resolveSetupAccountId,
|
||||||
type WizardPrompter,
|
type WizardPrompter,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
import { type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import { resolveDefaultDiscordAccountId, resolveDiscordAccount } from "./accounts.js";
|
import { resolveDefaultDiscordAccountId, resolveDiscordAccount } from "./accounts.js";
|
||||||
import { normalizeDiscordSlug } from "./monitor/allow-list.js";
|
import { normalizeDiscordSlug } from "./monitor/allow-list.js";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ import {
|
|||||||
createScopedAccountConfigAccessors,
|
createScopedAccountConfigAccessors,
|
||||||
createScopedChannelConfigBase,
|
createScopedChannelConfigBase,
|
||||||
} from "openclaw/plugin-sdk/channel-config-helpers";
|
} from "openclaw/plugin-sdk/channel-config-helpers";
|
||||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
import {
|
||||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
buildChannelConfigSchema,
|
||||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
DiscordConfigSchema,
|
||||||
import { DiscordConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
|
getChatChannelMeta,
|
||||||
|
type ChannelPlugin,
|
||||||
|
} from "openclaw/plugin-sdk/discord";
|
||||||
import { inspectDiscordAccount } from "./account-inspect.js";
|
import { inspectDiscordAccount } from "./account-inspect.js";
|
||||||
import {
|
import {
|
||||||
listDiscordAccountIds,
|
listDiscordAccountIds,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
createPatchedAccountSetupAdapter,
|
createPatchedAccountSetupAdapter,
|
||||||
|
formatDocsLink,
|
||||||
parseSetupEntriesAllowingWildcard,
|
parseSetupEntriesAllowingWildcard,
|
||||||
promptParsedAllowFromForScopedChannel,
|
promptParsedAllowFromForScopedChannel,
|
||||||
setChannelDmPolicyWithAllowFrom,
|
setChannelDmPolicyWithAllowFrom,
|
||||||
@@ -13,7 +14,6 @@ import type {
|
|||||||
ChannelSetupWizard,
|
ChannelSetupWizard,
|
||||||
ChannelSetupWizardTextInput,
|
ChannelSetupWizardTextInput,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import {
|
import {
|
||||||
listIMessageAccountIds,
|
listIMessageAccountIds,
|
||||||
resolveDefaultIMessageAccountId,
|
resolveDefaultIMessageAccountId,
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import { setSetupChannelEnabled, type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
import {
|
||||||
import { detectBinary } from "../../../src/plugins/setup-binary.js";
|
detectBinary,
|
||||||
|
setSetupChannelEnabled,
|
||||||
|
type ChannelSetupWizard,
|
||||||
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { listIMessageAccountIds, resolveIMessageAccount } from "./accounts.js";
|
import { listIMessageAccountIds, resolveIMessageAccount } from "./accounts.js";
|
||||||
import {
|
import {
|
||||||
createIMessageCliPathTextInput,
|
createIMessageCliPathTextInput,
|
||||||
|
|||||||
@@ -3,19 +3,17 @@ import {
|
|||||||
collectAllowlistProviderRestrictSendersWarnings,
|
collectAllowlistProviderRestrictSendersWarnings,
|
||||||
} from "openclaw/plugin-sdk/channel-policy";
|
} from "openclaw/plugin-sdk/channel-policy";
|
||||||
import {
|
import {
|
||||||
|
buildChannelConfigSchema,
|
||||||
|
DEFAULT_ACCOUNT_ID,
|
||||||
deleteAccountFromConfigSection,
|
deleteAccountFromConfigSection,
|
||||||
setAccountEnabledInConfigSection,
|
|
||||||
} from "../../../src/channels/plugins/config-helpers.js";
|
|
||||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
|
||||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
|
||||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
|
||||||
import { IMessageConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
|
|
||||||
import {
|
|
||||||
formatTrimmedAllowFromEntries,
|
formatTrimmedAllowFromEntries,
|
||||||
|
getChatChannelMeta,
|
||||||
|
IMessageConfigSchema,
|
||||||
resolveIMessageConfigAllowFrom,
|
resolveIMessageConfigAllowFrom,
|
||||||
resolveIMessageConfigDefaultTo,
|
resolveIMessageConfigDefaultTo,
|
||||||
} from "../../../src/plugin-sdk/channel-config-helpers.js";
|
setAccountEnabledInConfigSection,
|
||||||
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
|
type ChannelPlugin,
|
||||||
|
} from "openclaw/plugin-sdk/imessage";
|
||||||
import {
|
import {
|
||||||
listIMessageAccountIds,
|
listIMessageAccountIds,
|
||||||
resolveDefaultIMessageAccountId,
|
resolveDefaultIMessageAccountId,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
createPatchedAccountSetupAdapter,
|
createPatchedAccountSetupAdapter,
|
||||||
|
formatCliCommand,
|
||||||
|
formatDocsLink,
|
||||||
normalizeE164,
|
normalizeE164,
|
||||||
parseSetupEntriesAllowingWildcard,
|
parseSetupEntriesAllowingWildcard,
|
||||||
promptParsedAllowFromForScopedChannel,
|
promptParsedAllowFromForScopedChannel,
|
||||||
@@ -14,8 +16,6 @@ import type {
|
|||||||
ChannelSetupWizard,
|
ChannelSetupWizard,
|
||||||
ChannelSetupWizardTextInput,
|
ChannelSetupWizardTextInput,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { formatCliCommand } from "../../../src/cli/command-format.js";
|
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import {
|
import {
|
||||||
listSignalAccountIds,
|
listSignalAccountIds,
|
||||||
resolveDefaultSignalAccountId,
|
resolveDefaultSignalAccountId,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { setSetupChannelEnabled, type ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
import {
|
||||||
import { detectBinary } from "../../../src/plugins/setup-binary.js";
|
detectBinary,
|
||||||
import { installSignalCli } from "../../../src/plugins/signal-cli-install.js";
|
installSignalCli,
|
||||||
|
setSetupChannelEnabled,
|
||||||
|
type ChannelSetupWizard,
|
||||||
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { listSignalAccountIds, resolveSignalAccount } from "./accounts.js";
|
import { listSignalAccountIds, resolveSignalAccount } from "./accounts.js";
|
||||||
import {
|
import {
|
||||||
createSignalCliPathTextInput,
|
createSignalCliPathTextInput,
|
||||||
|
|||||||
@@ -4,15 +4,15 @@ import {
|
|||||||
collectAllowlistProviderRestrictSendersWarnings,
|
collectAllowlistProviderRestrictSendersWarnings,
|
||||||
} from "openclaw/plugin-sdk/channel-policy";
|
} from "openclaw/plugin-sdk/channel-policy";
|
||||||
import {
|
import {
|
||||||
|
buildChannelConfigSchema,
|
||||||
|
DEFAULT_ACCOUNT_ID,
|
||||||
deleteAccountFromConfigSection,
|
deleteAccountFromConfigSection,
|
||||||
|
getChatChannelMeta,
|
||||||
|
normalizeE164,
|
||||||
setAccountEnabledInConfigSection,
|
setAccountEnabledInConfigSection,
|
||||||
} from "../../../src/channels/plugins/config-helpers.js";
|
SignalConfigSchema,
|
||||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
type ChannelPlugin,
|
||||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
} from "openclaw/plugin-sdk/signal";
|
||||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
|
||||||
import { SignalConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
|
|
||||||
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
|
|
||||||
import { normalizeE164 } from "../../../src/utils.js";
|
|
||||||
import {
|
import {
|
||||||
listSignalAccountIds,
|
listSignalAccountIds,
|
||||||
resolveDefaultSignalAccountId,
|
resolveDefaultSignalAccountId,
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ import {
|
|||||||
resolveConfiguredFromRequiredCredentialStatuses,
|
resolveConfiguredFromRequiredCredentialStatuses,
|
||||||
resolveSlackGroupRequireMention,
|
resolveSlackGroupRequireMention,
|
||||||
resolveSlackGroupToolPolicy,
|
resolveSlackGroupToolPolicy,
|
||||||
|
createSlackActions,
|
||||||
type ChannelPlugin,
|
type ChannelPlugin,
|
||||||
type OpenClawConfig,
|
type OpenClawConfig,
|
||||||
|
type SlackActionContext,
|
||||||
} from "openclaw/plugin-sdk/slack";
|
} from "openclaw/plugin-sdk/slack";
|
||||||
import type { SlackActionContext } from "../../../src/agents/tools/slack-actions.js";
|
|
||||||
import { createSlackActions } from "../../../src/channels/plugins/slack.actions.js";
|
|
||||||
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
|
import { buildPassiveProbedChannelStatusSummary } from "../../shared/channel-status-summary.js";
|
||||||
import {
|
import {
|
||||||
listEnabledSlackAccounts,
|
listEnabledSlackAccounts,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
createAllowlistSetupWizardProxy,
|
createAllowlistSetupWizardProxy,
|
||||||
DEFAULT_ACCOUNT_ID,
|
DEFAULT_ACCOUNT_ID,
|
||||||
createEnvPatchedAccountSetupAdapter,
|
createEnvPatchedAccountSetupAdapter,
|
||||||
|
formatDocsLink,
|
||||||
hasConfiguredSecretInput,
|
hasConfiguredSecretInput,
|
||||||
type OpenClawConfig,
|
type OpenClawConfig,
|
||||||
noteChannelLookupFailure,
|
noteChannelLookupFailure,
|
||||||
@@ -18,7 +19,6 @@ import {
|
|||||||
type ChannelSetupWizard,
|
type ChannelSetupWizard,
|
||||||
type ChannelSetupWizardAllowFromEntry,
|
type ChannelSetupWizardAllowFromEntry,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import { inspectSlackAccount } from "./account-inspect.js";
|
import { inspectSlackAccount } from "./account-inspect.js";
|
||||||
import { listSlackAccountIds, resolveSlackAccount, type ResolvedSlackAccount } from "./accounts.js";
|
import { listSlackAccountIds, resolveSlackAccount, type ResolvedSlackAccount } from "./accounts.js";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
formatDocsLink,
|
||||||
noteChannelLookupFailure,
|
noteChannelLookupFailure,
|
||||||
noteChannelLookupSummary,
|
noteChannelLookupSummary,
|
||||||
type OpenClawConfig,
|
type OpenClawConfig,
|
||||||
@@ -11,7 +12,6 @@ import type {
|
|||||||
ChannelSetupWizard,
|
ChannelSetupWizard,
|
||||||
ChannelSetupWizardAllowFromEntry,
|
ChannelSetupWizardAllowFromEntry,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import { resolveDefaultSlackAccountId, resolveSlackAccount } from "./accounts.js";
|
import { resolveDefaultSlackAccountId, resolveSlackAccount } from "./accounts.js";
|
||||||
import { resolveSlackChannelAllowlist } from "./resolve-channels.js";
|
import { resolveSlackChannelAllowlist } from "./resolve-channels.js";
|
||||||
import { resolveSlackUserAllowlist } from "./resolve-users.js";
|
import { resolveSlackUserAllowlist } from "./resolve-users.js";
|
||||||
|
|||||||
@@ -3,14 +3,18 @@ import {
|
|||||||
createScopedAccountConfigAccessors,
|
createScopedAccountConfigAccessors,
|
||||||
createScopedChannelConfigBase,
|
createScopedChannelConfigBase,
|
||||||
} from "openclaw/plugin-sdk/channel-config-helpers";
|
} from "openclaw/plugin-sdk/channel-config-helpers";
|
||||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
import {
|
||||||
import { patchChannelConfigForAccount } from "../../../src/channels/plugins/setup-wizard-helpers.js";
|
formatDocsLink,
|
||||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
hasConfiguredSecretInput,
|
||||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
patchChannelConfigForAccount,
|
||||||
import type { OpenClawConfig } from "../../../src/config/config.js";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import { hasConfiguredSecretInput } from "../../../src/config/types.secrets.js";
|
import {
|
||||||
import { SlackConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
|
buildChannelConfigSchema,
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
getChatChannelMeta,
|
||||||
|
SlackConfigSchema,
|
||||||
|
type ChannelPlugin,
|
||||||
|
type OpenClawConfig,
|
||||||
|
} from "openclaw/plugin-sdk/slack";
|
||||||
import { inspectSlackAccount } from "./account-inspect.js";
|
import { inspectSlackAccount } from "./account-inspect.js";
|
||||||
import {
|
import {
|
||||||
listSlackAccountIds,
|
listSlackAccountIds,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import {
|
import {
|
||||||
createEnvPatchedAccountSetupAdapter,
|
createEnvPatchedAccountSetupAdapter,
|
||||||
DEFAULT_ACCOUNT_ID,
|
DEFAULT_ACCOUNT_ID,
|
||||||
|
formatCliCommand,
|
||||||
|
formatDocsLink,
|
||||||
patchChannelConfigForAccount,
|
patchChannelConfigForAccount,
|
||||||
promptResolvedAllowFrom,
|
promptResolvedAllowFrom,
|
||||||
splitSetupEntries,
|
splitSetupEntries,
|
||||||
@@ -8,8 +10,6 @@ import {
|
|||||||
type WizardPrompter,
|
type WizardPrompter,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import type { ChannelSetupAdapter, ChannelSetupDmPolicy } from "openclaw/plugin-sdk/setup";
|
import type { ChannelSetupAdapter, ChannelSetupDmPolicy } from "openclaw/plugin-sdk/setup";
|
||||||
import { formatCliCommand } from "../../../src/cli/command-format.js";
|
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import { resolveDefaultTelegramAccountId, resolveTelegramAccount } from "./accounts.js";
|
import { resolveDefaultTelegramAccountId, resolveTelegramAccount } from "./accounts.js";
|
||||||
import { fetchTelegramChatId } from "./api-fetch.js";
|
import { fetchTelegramChatId } from "./api-fetch.js";
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ import {
|
|||||||
createScopedAccountConfigAccessors,
|
createScopedAccountConfigAccessors,
|
||||||
createScopedChannelConfigBase,
|
createScopedChannelConfigBase,
|
||||||
} from "openclaw/plugin-sdk/channel-config-helpers";
|
} from "openclaw/plugin-sdk/channel-config-helpers";
|
||||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
import {
|
||||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
buildChannelConfigSchema,
|
||||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
getChatChannelMeta,
|
||||||
import type { OpenClawConfig } from "../../../src/config/config.js";
|
normalizeAccountId,
|
||||||
import { TelegramConfigSchema } from "../../../src/config/zod-schema.providers-core.js";
|
TelegramConfigSchema,
|
||||||
import { normalizeAccountId } from "../../../src/routing/session-key.js";
|
type ChannelPlugin,
|
||||||
|
type OpenClawConfig,
|
||||||
|
} from "openclaw/plugin-sdk/telegram";
|
||||||
import { inspectTelegramAccount } from "./account-inspect.js";
|
import { inspectTelegramAccount } from "./account-inspect.js";
|
||||||
import {
|
import {
|
||||||
listTelegramAccountIds,
|
listTelegramAccountIds,
|
||||||
|
|||||||
472
extensions/test-utils/discord-provider.test-support.ts
Normal file
472
extensions/test-utils/discord-provider.test-support.ts
Normal file
@@ -0,0 +1,472 @@
|
|||||||
|
import type { OpenClawConfig } from "openclaw/plugin-sdk/discord";
|
||||||
|
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
|
||||||
|
import type { Mock } from "vitest";
|
||||||
|
import { expect, vi } from "vitest";
|
||||||
|
|
||||||
|
export type NativeCommandSpecMock = {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
acceptsArgs: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PluginCommandSpecMock = {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
acceptsArgs: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ProviderMonitorTestMocks = {
|
||||||
|
clientHandleDeployRequestMock: Mock<() => Promise<void>>;
|
||||||
|
clientFetchUserMock: Mock<(target: string) => Promise<{ id: string }>>;
|
||||||
|
clientGetPluginMock: Mock<(name: string) => unknown>;
|
||||||
|
clientConstructorOptionsMock: Mock<(options?: unknown) => void>;
|
||||||
|
createDiscordAutoPresenceControllerMock: Mock<() => unknown>;
|
||||||
|
createDiscordNativeCommandMock: Mock<(params?: { command?: { name?: string } }) => unknown>;
|
||||||
|
createDiscordMessageHandlerMock: Mock<() => unknown>;
|
||||||
|
createNoopThreadBindingManagerMock: Mock<() => { stop: ReturnType<typeof vi.fn> }>;
|
||||||
|
createThreadBindingManagerMock: Mock<() => { stop: ReturnType<typeof vi.fn> }>;
|
||||||
|
reconcileAcpThreadBindingsOnStartupMock: Mock<() => unknown>;
|
||||||
|
createdBindingManagers: Array<{ stop: ReturnType<typeof vi.fn> }>;
|
||||||
|
getAcpSessionStatusMock: Mock<
|
||||||
|
(params: {
|
||||||
|
cfg: OpenClawConfig;
|
||||||
|
sessionKey: string;
|
||||||
|
signal?: AbortSignal;
|
||||||
|
}) => Promise<{ state: string }>
|
||||||
|
>;
|
||||||
|
getPluginCommandSpecsMock: Mock<() => PluginCommandSpecMock[]>;
|
||||||
|
listNativeCommandSpecsForConfigMock: Mock<() => NativeCommandSpecMock[]>;
|
||||||
|
listSkillCommandsForAgentsMock: Mock<() => unknown[]>;
|
||||||
|
monitorLifecycleMock: Mock<(params: { threadBindings: { stop: () => void } }) => Promise<void>>;
|
||||||
|
resolveDiscordAccountMock: Mock<() => unknown>;
|
||||||
|
resolveDiscordAllowlistConfigMock: Mock<() => Promise<unknown>>;
|
||||||
|
resolveNativeCommandsEnabledMock: Mock<() => boolean>;
|
||||||
|
resolveNativeSkillsEnabledMock: Mock<() => boolean>;
|
||||||
|
isVerboseMock: Mock<() => boolean>;
|
||||||
|
shouldLogVerboseMock: Mock<() => boolean>;
|
||||||
|
voiceRuntimeModuleLoadedMock: Mock<() => void>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function baseDiscordAccountConfig() {
|
||||||
|
return {
|
||||||
|
commands: { native: true, nativeSkills: false },
|
||||||
|
voice: { enabled: false },
|
||||||
|
agentComponents: { enabled: false },
|
||||||
|
execApprovals: { enabled: false },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const providerMonitorTestMocks: ProviderMonitorTestMocks = vi.hoisted(() => {
|
||||||
|
const createdBindingManagers: Array<{ stop: ReturnType<typeof vi.fn> }> = [];
|
||||||
|
const isVerboseMock = vi.fn(() => false);
|
||||||
|
const shouldLogVerboseMock = vi.fn(() => false);
|
||||||
|
|
||||||
|
return {
|
||||||
|
clientHandleDeployRequestMock: vi.fn(async () => undefined),
|
||||||
|
clientFetchUserMock: vi.fn(async (_target: string) => ({ id: "bot-1" })),
|
||||||
|
clientGetPluginMock: vi.fn<(_name: string) => unknown>(() => undefined),
|
||||||
|
clientConstructorOptionsMock: vi.fn(),
|
||||||
|
createDiscordAutoPresenceControllerMock: vi.fn(() => ({
|
||||||
|
enabled: false,
|
||||||
|
start: vi.fn(),
|
||||||
|
stop: vi.fn(),
|
||||||
|
refresh: vi.fn(),
|
||||||
|
runNow: vi.fn(),
|
||||||
|
})),
|
||||||
|
createDiscordNativeCommandMock: vi.fn((params?: { command?: { name?: string } }) => ({
|
||||||
|
name: params?.command?.name ?? "mock-command",
|
||||||
|
})),
|
||||||
|
createDiscordMessageHandlerMock: vi.fn(() =>
|
||||||
|
Object.assign(
|
||||||
|
vi.fn(async () => undefined),
|
||||||
|
{
|
||||||
|
deactivate: vi.fn(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
createNoopThreadBindingManagerMock: vi.fn(() => {
|
||||||
|
const manager = { stop: vi.fn() };
|
||||||
|
createdBindingManagers.push(manager);
|
||||||
|
return manager;
|
||||||
|
}),
|
||||||
|
createThreadBindingManagerMock: vi.fn(() => {
|
||||||
|
const manager = { stop: vi.fn() };
|
||||||
|
createdBindingManagers.push(manager);
|
||||||
|
return manager;
|
||||||
|
}),
|
||||||
|
reconcileAcpThreadBindingsOnStartupMock: vi.fn(() => ({
|
||||||
|
checked: 0,
|
||||||
|
removed: 0,
|
||||||
|
staleSessionKeys: [],
|
||||||
|
})),
|
||||||
|
createdBindingManagers,
|
||||||
|
getAcpSessionStatusMock: vi.fn(
|
||||||
|
async (_params: { cfg: OpenClawConfig; sessionKey: string; signal?: AbortSignal }) => ({
|
||||||
|
state: "idle",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
getPluginCommandSpecsMock: vi.fn<() => PluginCommandSpecMock[]>(() => []),
|
||||||
|
listNativeCommandSpecsForConfigMock: vi.fn<() => NativeCommandSpecMock[]>(() => [
|
||||||
|
{ name: "cmd", description: "built-in", acceptsArgs: false },
|
||||||
|
]),
|
||||||
|
listSkillCommandsForAgentsMock: vi.fn(() => []),
|
||||||
|
monitorLifecycleMock: vi.fn(async (params: { threadBindings: { stop: () => void } }) => {
|
||||||
|
params.threadBindings.stop();
|
||||||
|
}),
|
||||||
|
resolveDiscordAccountMock: vi.fn(() => ({
|
||||||
|
accountId: "default",
|
||||||
|
token: "cfg-token",
|
||||||
|
config: baseDiscordAccountConfig(),
|
||||||
|
})),
|
||||||
|
resolveDiscordAllowlistConfigMock: vi.fn(async () => ({
|
||||||
|
guildEntries: undefined,
|
||||||
|
allowFrom: undefined,
|
||||||
|
})),
|
||||||
|
resolveNativeCommandsEnabledMock: vi.fn(() => true),
|
||||||
|
resolveNativeSkillsEnabledMock: vi.fn(() => false),
|
||||||
|
isVerboseMock,
|
||||||
|
shouldLogVerboseMock,
|
||||||
|
voiceRuntimeModuleLoadedMock: vi.fn(),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
clientHandleDeployRequestMock,
|
||||||
|
clientFetchUserMock,
|
||||||
|
clientGetPluginMock,
|
||||||
|
clientConstructorOptionsMock,
|
||||||
|
createDiscordAutoPresenceControllerMock,
|
||||||
|
createDiscordNativeCommandMock,
|
||||||
|
createDiscordMessageHandlerMock,
|
||||||
|
createNoopThreadBindingManagerMock,
|
||||||
|
createThreadBindingManagerMock,
|
||||||
|
reconcileAcpThreadBindingsOnStartupMock,
|
||||||
|
createdBindingManagers,
|
||||||
|
getAcpSessionStatusMock,
|
||||||
|
getPluginCommandSpecsMock,
|
||||||
|
listNativeCommandSpecsForConfigMock,
|
||||||
|
listSkillCommandsForAgentsMock,
|
||||||
|
monitorLifecycleMock,
|
||||||
|
resolveDiscordAccountMock,
|
||||||
|
resolveDiscordAllowlistConfigMock,
|
||||||
|
resolveNativeCommandsEnabledMock,
|
||||||
|
resolveNativeSkillsEnabledMock,
|
||||||
|
isVerboseMock,
|
||||||
|
shouldLogVerboseMock,
|
||||||
|
voiceRuntimeModuleLoadedMock,
|
||||||
|
} = providerMonitorTestMocks;
|
||||||
|
|
||||||
|
export function getProviderMonitorTestMocks(): typeof providerMonitorTestMocks {
|
||||||
|
return providerMonitorTestMocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mockResolvedDiscordAccountConfig(overrides: Record<string, unknown>) {
|
||||||
|
resolveDiscordAccountMock.mockImplementation(() => ({
|
||||||
|
accountId: "default",
|
||||||
|
token: "cfg-token",
|
||||||
|
config: {
|
||||||
|
...baseDiscordAccountConfig(),
|
||||||
|
...overrides,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getFirstDiscordMessageHandlerParams<T extends object>() {
|
||||||
|
expect(createDiscordMessageHandlerMock).toHaveBeenCalledTimes(1);
|
||||||
|
const firstCall = createDiscordMessageHandlerMock.mock.calls.at(0) as [T] | undefined;
|
||||||
|
return firstCall?.[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetDiscordProviderMonitorMocks(params?: {
|
||||||
|
nativeCommands?: NativeCommandSpecMock[];
|
||||||
|
}) {
|
||||||
|
clientHandleDeployRequestMock.mockClear().mockResolvedValue(undefined);
|
||||||
|
clientFetchUserMock.mockClear().mockResolvedValue({ id: "bot-1" });
|
||||||
|
clientGetPluginMock.mockClear().mockReturnValue(undefined);
|
||||||
|
clientConstructorOptionsMock.mockClear();
|
||||||
|
createDiscordAutoPresenceControllerMock.mockClear().mockImplementation(() => ({
|
||||||
|
enabled: false,
|
||||||
|
start: vi.fn(),
|
||||||
|
stop: vi.fn(),
|
||||||
|
refresh: vi.fn(),
|
||||||
|
runNow: vi.fn(),
|
||||||
|
}));
|
||||||
|
createDiscordNativeCommandMock.mockClear().mockImplementation((input) => ({
|
||||||
|
name: input?.command?.name ?? "mock-command",
|
||||||
|
}));
|
||||||
|
createDiscordMessageHandlerMock.mockClear().mockImplementation(() =>
|
||||||
|
Object.assign(
|
||||||
|
vi.fn(async () => undefined),
|
||||||
|
{
|
||||||
|
deactivate: vi.fn(),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
createNoopThreadBindingManagerMock.mockClear();
|
||||||
|
createThreadBindingManagerMock.mockClear();
|
||||||
|
reconcileAcpThreadBindingsOnStartupMock.mockClear().mockReturnValue({
|
||||||
|
checked: 0,
|
||||||
|
removed: 0,
|
||||||
|
staleSessionKeys: [],
|
||||||
|
});
|
||||||
|
createdBindingManagers.length = 0;
|
||||||
|
getAcpSessionStatusMock.mockClear().mockResolvedValue({ state: "idle" });
|
||||||
|
getPluginCommandSpecsMock.mockClear().mockReturnValue([]);
|
||||||
|
listNativeCommandSpecsForConfigMock
|
||||||
|
.mockClear()
|
||||||
|
.mockReturnValue(
|
||||||
|
params?.nativeCommands ?? [{ name: "cmd", description: "built-in", acceptsArgs: false }],
|
||||||
|
);
|
||||||
|
listSkillCommandsForAgentsMock.mockClear().mockReturnValue([]);
|
||||||
|
monitorLifecycleMock.mockClear().mockImplementation(async (monitorParams) => {
|
||||||
|
monitorParams.threadBindings.stop();
|
||||||
|
});
|
||||||
|
resolveDiscordAccountMock.mockClear().mockReturnValue({
|
||||||
|
accountId: "default",
|
||||||
|
token: "cfg-token",
|
||||||
|
config: baseDiscordAccountConfig(),
|
||||||
|
});
|
||||||
|
resolveDiscordAllowlistConfigMock.mockClear().mockResolvedValue({
|
||||||
|
guildEntries: undefined,
|
||||||
|
allowFrom: undefined,
|
||||||
|
});
|
||||||
|
resolveNativeCommandsEnabledMock.mockClear().mockReturnValue(true);
|
||||||
|
resolveNativeSkillsEnabledMock.mockClear().mockReturnValue(false);
|
||||||
|
isVerboseMock.mockClear().mockReturnValue(false);
|
||||||
|
shouldLogVerboseMock.mockClear().mockReturnValue(false);
|
||||||
|
voiceRuntimeModuleLoadedMock.mockClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const baseRuntime = (): RuntimeEnv => ({
|
||||||
|
log: vi.fn(),
|
||||||
|
error: vi.fn(),
|
||||||
|
exit: vi.fn(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const baseConfig = (): OpenClawConfig =>
|
||||||
|
({
|
||||||
|
channels: {
|
||||||
|
discord: {
|
||||||
|
accounts: {
|
||||||
|
default: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}) as OpenClawConfig;
|
||||||
|
|
||||||
|
vi.mock("@buape/carbon", () => {
|
||||||
|
class ReadyListener {}
|
||||||
|
class RateLimitError extends Error {
|
||||||
|
status = 429;
|
||||||
|
discordCode?: number;
|
||||||
|
retryAfter: number;
|
||||||
|
scope: string | null;
|
||||||
|
bucket: string | null;
|
||||||
|
constructor(
|
||||||
|
response: Response,
|
||||||
|
body: { message: string; retry_after: number; global: boolean },
|
||||||
|
) {
|
||||||
|
super(body.message);
|
||||||
|
this.retryAfter = body.retry_after;
|
||||||
|
this.scope = body.global ? "global" : response.headers.get("X-RateLimit-Scope");
|
||||||
|
this.bucket = response.headers.get("X-RateLimit-Bucket");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Client {
|
||||||
|
listeners: unknown[];
|
||||||
|
rest: { put: ReturnType<typeof vi.fn> };
|
||||||
|
options: unknown;
|
||||||
|
constructor(options: unknown, handlers: { listeners?: unknown[] }) {
|
||||||
|
this.options = options;
|
||||||
|
this.listeners = handlers.listeners ?? [];
|
||||||
|
this.rest = { put: vi.fn(async () => undefined) };
|
||||||
|
clientConstructorOptionsMock(options);
|
||||||
|
}
|
||||||
|
async handleDeployRequest() {
|
||||||
|
return await clientHandleDeployRequestMock();
|
||||||
|
}
|
||||||
|
async fetchUser(target: string) {
|
||||||
|
return await clientFetchUserMock(target);
|
||||||
|
}
|
||||||
|
getPlugin(name: string) {
|
||||||
|
return clientGetPluginMock(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { Client, RateLimitError, ReadyListener };
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock("@buape/carbon/gateway", () => ({
|
||||||
|
GatewayCloseCodes: { DisallowedIntents: 4014 },
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("@buape/carbon/voice", () => ({
|
||||||
|
VoicePlugin: class VoicePlugin {},
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("openclaw/plugin-sdk/acp-runtime", async () => {
|
||||||
|
const actual = await vi.importActual<typeof import("openclaw/plugin-sdk/acp-runtime")>(
|
||||||
|
"openclaw/plugin-sdk/acp-runtime",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
getAcpSessionManager: () => ({
|
||||||
|
getSessionStatus: getAcpSessionStatusMock,
|
||||||
|
}),
|
||||||
|
isAcpRuntimeError: (error: unknown): error is { code: string } =>
|
||||||
|
error instanceof Error && "code" in error,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock("openclaw/plugin-sdk/reply-runtime", async () => {
|
||||||
|
const actual = await vi.importActual<typeof import("openclaw/plugin-sdk/reply-runtime")>(
|
||||||
|
"openclaw/plugin-sdk/reply-runtime",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
resolveTextChunkLimit: () => 2000,
|
||||||
|
listNativeCommandSpecsForConfig: listNativeCommandSpecsForConfigMock,
|
||||||
|
listSkillCommandsForAgents: listSkillCommandsForAgentsMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock("openclaw/plugin-sdk/config-runtime", async () => {
|
||||||
|
const actual = await vi.importActual<typeof import("openclaw/plugin-sdk/config-runtime")>(
|
||||||
|
"openclaw/plugin-sdk/config-runtime",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
isNativeCommandsExplicitlyDisabled: () => false,
|
||||||
|
loadConfig: () => ({}),
|
||||||
|
resolveNativeCommandsEnabled: resolveNativeCommandsEnabledMock,
|
||||||
|
resolveNativeSkillsEnabled: resolveNativeSkillsEnabledMock,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock("openclaw/plugin-sdk/runtime-env", async () => {
|
||||||
|
const actual = await vi.importActual<typeof import("openclaw/plugin-sdk/runtime-env")>(
|
||||||
|
"openclaw/plugin-sdk/runtime-env",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
danger: (value: string) => value,
|
||||||
|
isVerbose: isVerboseMock,
|
||||||
|
logVerbose: vi.fn(),
|
||||||
|
shouldLogVerbose: shouldLogVerboseMock,
|
||||||
|
warn: (value: string) => value,
|
||||||
|
createSubsystemLogger: () => {
|
||||||
|
const logger = {
|
||||||
|
child: vi.fn(() => logger),
|
||||||
|
info: vi.fn(),
|
||||||
|
error: vi.fn(),
|
||||||
|
warn: vi.fn(),
|
||||||
|
debug: vi.fn(),
|
||||||
|
};
|
||||||
|
return logger;
|
||||||
|
},
|
||||||
|
createNonExitingRuntime: () => ({ log: vi.fn(), error: vi.fn(), exit: vi.fn() }),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock("openclaw/plugin-sdk/infra-runtime", async () => {
|
||||||
|
const actual = await vi.importActual<typeof import("openclaw/plugin-sdk/infra-runtime")>(
|
||||||
|
"openclaw/plugin-sdk/infra-runtime",
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...actual,
|
||||||
|
formatErrorMessage: (error: unknown) => String(error),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
vi.mock("../discord/src/accounts.js", () => ({
|
||||||
|
resolveDiscordAccount: resolveDiscordAccountMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/probe.js", () => ({
|
||||||
|
fetchDiscordApplicationId: async () => "app-1",
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/token.js", () => ({
|
||||||
|
normalizeDiscordToken: (value?: string) => value,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/voice/command.js", () => ({
|
||||||
|
createDiscordVoiceCommand: () => ({ name: "voice-command" }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/agent-components.js", () => ({
|
||||||
|
createAgentComponentButton: () => ({ id: "btn" }),
|
||||||
|
createAgentSelectMenu: () => ({ id: "menu" }),
|
||||||
|
createDiscordComponentButton: () => ({ id: "btn2" }),
|
||||||
|
createDiscordComponentChannelSelect: () => ({ id: "channel" }),
|
||||||
|
createDiscordComponentMentionableSelect: () => ({ id: "mentionable" }),
|
||||||
|
createDiscordComponentModal: () => ({ id: "modal" }),
|
||||||
|
createDiscordComponentRoleSelect: () => ({ id: "role" }),
|
||||||
|
createDiscordComponentStringSelect: () => ({ id: "string" }),
|
||||||
|
createDiscordComponentUserSelect: () => ({ id: "user" }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/auto-presence.js", () => ({
|
||||||
|
createDiscordAutoPresenceController: createDiscordAutoPresenceControllerMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/commands.js", () => ({
|
||||||
|
resolveDiscordSlashCommandConfig: () => ({ ephemeral: false }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/exec-approvals.js", () => ({
|
||||||
|
createExecApprovalButton: () => ({ id: "exec-approval" }),
|
||||||
|
DiscordExecApprovalHandler: class DiscordExecApprovalHandler {
|
||||||
|
async start() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
async stop() {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/gateway-plugin.js", () => ({
|
||||||
|
createDiscordGatewayPlugin: () => ({ id: "gateway-plugin" }),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/listeners.js", () => ({
|
||||||
|
DiscordMessageListener: class DiscordMessageListener {},
|
||||||
|
DiscordPresenceListener: class DiscordPresenceListener {},
|
||||||
|
DiscordReactionListener: class DiscordReactionListener {},
|
||||||
|
DiscordReactionRemoveListener: class DiscordReactionRemoveListener {},
|
||||||
|
DiscordThreadUpdateListener: class DiscordThreadUpdateListener {},
|
||||||
|
registerDiscordListener: vi.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/message-handler.js", () => ({
|
||||||
|
createDiscordMessageHandler: createDiscordMessageHandlerMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/native-command.js", () => ({
|
||||||
|
createDiscordCommandArgFallbackButton: () => ({ id: "arg-fallback" }),
|
||||||
|
createDiscordModelPickerFallbackButton: () => ({ id: "model-fallback-btn" }),
|
||||||
|
createDiscordModelPickerFallbackSelect: () => ({ id: "model-fallback-select" }),
|
||||||
|
createDiscordNativeCommand: createDiscordNativeCommandMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/presence.js", () => ({
|
||||||
|
resolveDiscordPresenceUpdate: () => undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/provider.allowlist.js", () => ({
|
||||||
|
resolveDiscordAllowlistConfig: resolveDiscordAllowlistConfigMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/provider.lifecycle.js", () => ({
|
||||||
|
runDiscordGatewayLifecycle: monitorLifecycleMock,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/rest-fetch.js", () => ({
|
||||||
|
resolveDiscordRestFetch: () => async () => undefined,
|
||||||
|
}));
|
||||||
|
|
||||||
|
vi.mock("../discord/src/monitor/thread-bindings.js", () => ({
|
||||||
|
createNoopThreadBindingManager: createNoopThreadBindingManagerMock,
|
||||||
|
createThreadBindingManager: createThreadBindingManagerMock,
|
||||||
|
reconcileAcpThreadBindingsOnStartup: reconcileAcpThreadBindingsOnStartupMock,
|
||||||
|
}));
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import {
|
import {
|
||||||
DEFAULT_ACCOUNT_ID,
|
DEFAULT_ACCOUNT_ID,
|
||||||
|
formatCliCommand,
|
||||||
|
formatDocsLink,
|
||||||
normalizeAccountId,
|
normalizeAccountId,
|
||||||
normalizeAllowFromEntries,
|
normalizeAllowFromEntries,
|
||||||
normalizeE164,
|
normalizeE164,
|
||||||
@@ -11,8 +13,6 @@ import {
|
|||||||
type OpenClawConfig,
|
type OpenClawConfig,
|
||||||
} from "openclaw/plugin-sdk/setup";
|
} from "openclaw/plugin-sdk/setup";
|
||||||
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
import type { ChannelSetupWizard } from "openclaw/plugin-sdk/setup";
|
||||||
import { formatCliCommand } from "../../../src/cli/command-format.js";
|
|
||||||
import { formatDocsLink } from "../../../src/terminal/links.js";
|
|
||||||
import { listWhatsAppAccountIds, resolveWhatsAppAuthDir } from "./accounts.js";
|
import { listWhatsAppAccountIds, resolveWhatsAppAuthDir } from "./accounts.js";
|
||||||
import { loginWeb } from "./login.js";
|
import { loginWeb } from "./login.js";
|
||||||
import { whatsappSetupAdapter } from "./setup-core.js";
|
import { whatsappSetupAdapter } from "./setup-core.js";
|
||||||
|
|||||||
@@ -3,22 +3,20 @@ import {
|
|||||||
collectAllowlistProviderGroupPolicyWarnings,
|
collectAllowlistProviderGroupPolicyWarnings,
|
||||||
collectOpenGroupPolicyRouteAllowlistWarnings,
|
collectOpenGroupPolicyRouteAllowlistWarnings,
|
||||||
} from "openclaw/plugin-sdk/channel-policy";
|
} from "openclaw/plugin-sdk/channel-policy";
|
||||||
import { buildChannelConfigSchema } from "../../../src/channels/plugins/config-schema.js";
|
|
||||||
import {
|
|
||||||
resolveWhatsAppGroupRequireMention,
|
|
||||||
resolveWhatsAppGroupToolPolicy,
|
|
||||||
} from "../../../src/channels/plugins/group-mentions.js";
|
|
||||||
import type { ChannelPlugin } from "../../../src/channels/plugins/types.plugin.js";
|
|
||||||
import { resolveWhatsAppGroupIntroHint } from "../../../src/channels/plugins/whatsapp-shared.js";
|
|
||||||
import { getChatChannelMeta } from "../../../src/channels/registry.js";
|
|
||||||
import { WhatsAppConfigSchema } from "../../../src/config/zod-schema.providers-whatsapp.js";
|
|
||||||
import {
|
import {
|
||||||
|
buildChannelConfigSchema,
|
||||||
|
DEFAULT_ACCOUNT_ID,
|
||||||
formatWhatsAppConfigAllowFromEntries,
|
formatWhatsAppConfigAllowFromEntries,
|
||||||
|
getChatChannelMeta,
|
||||||
|
normalizeE164,
|
||||||
resolveWhatsAppConfigAllowFrom,
|
resolveWhatsAppConfigAllowFrom,
|
||||||
resolveWhatsAppConfigDefaultTo,
|
resolveWhatsAppConfigDefaultTo,
|
||||||
} from "../../../src/plugin-sdk/channel-config-helpers.js";
|
resolveWhatsAppGroupIntroHint,
|
||||||
import { DEFAULT_ACCOUNT_ID } from "../../../src/routing/session-key.js";
|
resolveWhatsAppGroupRequireMention,
|
||||||
import { normalizeE164 } from "../../../src/utils.js";
|
resolveWhatsAppGroupToolPolicy,
|
||||||
|
WhatsAppConfigSchema,
|
||||||
|
type ChannelPlugin,
|
||||||
|
} from "openclaw/plugin-sdk/whatsapp";
|
||||||
import {
|
import {
|
||||||
listWhatsAppAccountIds,
|
listWhatsAppAccountIds,
|
||||||
resolveDefaultWhatsAppAccountId,
|
resolveDefaultWhatsAppAccountId,
|
||||||
|
|||||||
@@ -81,3 +81,5 @@ export {
|
|||||||
} from "../../extensions/slack/src/actions.js";
|
} from "../../extensions/slack/src/actions.js";
|
||||||
export { recordSlackThreadParticipation } from "../../extensions/slack/src/sent-thread-cache.js";
|
export { recordSlackThreadParticipation } from "../../extensions/slack/src/sent-thread-cache.js";
|
||||||
export { handleSlackMessageAction } from "./slack-message-actions.js";
|
export { handleSlackMessageAction } from "./slack-message-actions.js";
|
||||||
|
export { createSlackActions } from "../channels/plugins/slack.actions.js";
|
||||||
|
export type { SlackActionContext } from "../agents/tools/slack-actions.js";
|
||||||
|
|||||||
Reference in New Issue
Block a user