import { expect, vi } from "vitest"; import type { OpenClawConfig } from "../../../src/config/config.js"; import type { TelegramAccountConfig } from "../../../src/config/types.js"; import type { RuntimeEnv } from "../../../src/runtime.js"; type NativeCommandBot = { api: { setMyCommands: ReturnType; sendMessage: ReturnType; }; command: ReturnType; }; type RegisterTelegramNativeCommandsParams = { bot: NativeCommandBot; cfg: OpenClawConfig; runtime: RuntimeEnv; accountId: string; telegramCfg: TelegramAccountConfig; allowFrom: string[]; groupAllowFrom: string[]; replyToMode: string; textLimit: number; useAccessGroups: boolean; nativeEnabled: boolean; nativeSkillsEnabled: boolean; nativeDisabledExplicit: boolean; resolveGroupPolicy: () => { allowlistEnabled: boolean; allowed: boolean }; resolveTelegramGroupConfig: () => { groupConfig: undefined; topicConfig: undefined; }; shouldSkipUpdate: () => boolean; opts: { token: string }; }; type RegisteredCommand = { command: string; description: string; }; const skillCommandMocks = vi.hoisted(() => ({ listSkillCommandsForAgents: vi.fn(() => []), })); const deliveryMocks = vi.hoisted(() => ({ deliverReplies: vi.fn(async () => ({ delivered: true })), })); export const listSkillCommandsForAgents = skillCommandMocks.listSkillCommandsForAgents; export const deliverReplies = deliveryMocks.deliverReplies; vi.mock("../../../src/auto-reply/skill-commands.js", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, listSkillCommandsForAgents, }; }); vi.mock("./bot/delivery.js", () => ({ deliverReplies, })); export async function waitForRegisteredCommands( setMyCommands: ReturnType, ): Promise { await vi.waitFor(() => { expect(setMyCommands).toHaveBeenCalled(); }); return setMyCommands.mock.calls[0]?.[0] as RegisteredCommand[]; } export function resetNativeCommandMenuMocks() { listSkillCommandsForAgents.mockClear(); listSkillCommandsForAgents.mockReturnValue([]); deliverReplies.mockClear(); deliverReplies.mockResolvedValue({ delivered: true }); } export function createCommandBot() { const commandHandlers = new Map Promise>(); const sendMessage = vi.fn().mockResolvedValue(undefined); const setMyCommands = vi.fn().mockResolvedValue(undefined); const bot = { api: { setMyCommands, sendMessage, }, command: vi.fn((name: string, cb: (ctx: unknown) => Promise) => { commandHandlers.set(name, cb); }), } as unknown as RegisterTelegramNativeCommandsParams["bot"]; return { bot, commandHandlers, sendMessage, setMyCommands }; } export function createNativeCommandTestParams( cfg: OpenClawConfig, params: Partial = {}, ): RegisterTelegramNativeCommandsParams { return { bot: params.bot ?? ({ api: { setMyCommands: vi.fn().mockResolvedValue(undefined), sendMessage: vi.fn().mockResolvedValue(undefined), }, command: vi.fn(), } as unknown as RegisterTelegramNativeCommandsParams["bot"]), cfg, runtime: params.runtime ?? ({} as RuntimeEnv), accountId: params.accountId ?? "default", telegramCfg: params.telegramCfg ?? ({} as TelegramAccountConfig), allowFrom: params.allowFrom ?? [], groupAllowFrom: params.groupAllowFrom ?? [], replyToMode: params.replyToMode ?? "off", textLimit: params.textLimit ?? 4000, useAccessGroups: params.useAccessGroups ?? false, nativeEnabled: params.nativeEnabled ?? true, nativeSkillsEnabled: params.nativeSkillsEnabled ?? true, nativeDisabledExplicit: params.nativeDisabledExplicit ?? false, resolveGroupPolicy: params.resolveGroupPolicy ?? (() => ({ allowlistEnabled: false, allowed: true, }) as ReturnType), resolveTelegramGroupConfig: params.resolveTelegramGroupConfig ?? (() => ({ groupConfig: undefined, topicConfig: undefined, })), shouldSkipUpdate: params.shouldSkipUpdate ?? (() => false), opts: params.opts ?? { token: "token" }, }; } export function createPrivateCommandContext(params?: { match?: string; messageId?: number; date?: number; chatId?: number; userId?: number; username?: string; }) { return { match: params?.match ?? "", message: { message_id: params?.messageId ?? 1, date: params?.date ?? Math.floor(Date.now() / 1000), chat: { id: params?.chatId ?? 123, type: "private" as const }, from: { id: params?.userId ?? 456, username: params?.username ?? "alice" }, }, }; }