Discord: move action runtime into extension
This commit is contained in:
parent
4c36436fb4
commit
9df3e9b617
@ -1,4 +1,7 @@
|
||||
export * from "./src/audit.js";
|
||||
export * from "./src/actions/runtime.js";
|
||||
export * from "./src/actions/runtime.moderation-shared.js";
|
||||
export * from "./src/actions/runtime.shared.js";
|
||||
export * from "./src/channel-actions.js";
|
||||
export * from "./src/directory-live.js";
|
||||
export * from "./src/monitor.js";
|
||||
|
||||
@ -5,12 +5,12 @@ import {
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-runtime";
|
||||
import { handleDiscordAction } from "./runtime.js";
|
||||
import {
|
||||
isDiscordModerationAction,
|
||||
readDiscordModerationCommand,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import { handleDiscordAction } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-runtime";
|
||||
} from "./runtime.moderation-shared.js";
|
||||
|
||||
type Ctx = Pick<
|
||||
ChannelMessageActionContext,
|
||||
|
||||
@ -4,8 +4,6 @@ import {
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "openclaw/plugin-sdk/agent-runtime";
|
||||
import { readDiscordParentIdParam } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import { handleDiscordAction } from "openclaw/plugin-sdk/agent-runtime";
|
||||
import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
|
||||
import { resolveReactionMessageId } from "openclaw/plugin-sdk/channel-runtime";
|
||||
import type { ChannelMessageActionContext } from "openclaw/plugin-sdk/channel-runtime";
|
||||
@ -13,6 +11,8 @@ import { normalizeInteractiveReply } from "openclaw/plugin-sdk/channel-runtime";
|
||||
import { buildDiscordInteractiveComponents } from "../shared-interactive.js";
|
||||
import { resolveDiscordChannelId } from "../targets.js";
|
||||
import { tryHandleDiscordMessageActionGuildAdmin } from "./handle-action.guild-admin.js";
|
||||
import { handleDiscordAction } from "./runtime.js";
|
||||
import { readDiscordParentIdParam } from "./runtime.shared.js";
|
||||
|
||||
const providerId = "discord";
|
||||
|
||||
|
||||
@ -1,5 +1,14 @@
|
||||
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||
import type { DiscordActionConfig } from "../../config/config.js";
|
||||
import {
|
||||
type ActionGate,
|
||||
jsonResult,
|
||||
parseAvailableTags,
|
||||
readNumberParam,
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "../../../../src/agents/tools/common.js";
|
||||
import type { DiscordActionConfig } from "../../../../src/config/types.discord.js";
|
||||
import { getPresence } from "../monitor/presence-cache.js";
|
||||
import {
|
||||
addRoleDiscord,
|
||||
createChannelDiscord,
|
||||
@ -19,17 +28,29 @@ import {
|
||||
setChannelPermissionDiscord,
|
||||
uploadEmojiDiscord,
|
||||
uploadStickerDiscord,
|
||||
} from "../../plugin-sdk/discord.js";
|
||||
import { getPresence } from "../../plugin-sdk/discord.js";
|
||||
import {
|
||||
type ActionGate,
|
||||
jsonResult,
|
||||
parseAvailableTags,
|
||||
readNumberParam,
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "./common.js";
|
||||
import { readDiscordParentIdParam } from "./discord-actions-shared.js";
|
||||
} from "../send.js";
|
||||
import { readDiscordParentIdParam } from "./runtime.shared.js";
|
||||
|
||||
export const discordGuildActionRuntime = {
|
||||
addRoleDiscord,
|
||||
createChannelDiscord,
|
||||
createScheduledEventDiscord,
|
||||
deleteChannelDiscord,
|
||||
editChannelDiscord,
|
||||
fetchChannelInfoDiscord,
|
||||
fetchMemberInfoDiscord,
|
||||
fetchRoleInfoDiscord,
|
||||
fetchVoiceStatusDiscord,
|
||||
listGuildChannelsDiscord,
|
||||
listGuildEmojisDiscord,
|
||||
listScheduledEventsDiscord,
|
||||
moveChannelDiscord,
|
||||
removeChannelPermissionDiscord,
|
||||
removeRoleDiscord,
|
||||
setChannelPermissionDiscord,
|
||||
uploadEmojiDiscord,
|
||||
uploadStickerDiscord,
|
||||
};
|
||||
|
||||
type DiscordRoleMutation = (params: {
|
||||
guildId: string;
|
||||
@ -85,8 +106,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const member = accountId
|
||||
? await fetchMemberInfoDiscord(guildId, userId, { accountId })
|
||||
: await fetchMemberInfoDiscord(guildId, userId);
|
||||
? await discordGuildActionRuntime.fetchMemberInfoDiscord(guildId, userId, { accountId })
|
||||
: await discordGuildActionRuntime.fetchMemberInfoDiscord(guildId, userId);
|
||||
const presence = getPresence(accountId, userId);
|
||||
const activities = presence?.activities ?? undefined;
|
||||
const status = presence?.status ?? undefined;
|
||||
@ -100,8 +121,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const roles = accountId
|
||||
? await fetchRoleInfoDiscord(guildId, { accountId })
|
||||
: await fetchRoleInfoDiscord(guildId);
|
||||
? await discordGuildActionRuntime.fetchRoleInfoDiscord(guildId, { accountId })
|
||||
: await discordGuildActionRuntime.fetchRoleInfoDiscord(guildId);
|
||||
return jsonResult({ ok: true, roles });
|
||||
}
|
||||
case "emojiList": {
|
||||
@ -112,8 +133,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const emojis = accountId
|
||||
? await listGuildEmojisDiscord(guildId, { accountId })
|
||||
: await listGuildEmojisDiscord(guildId);
|
||||
? await discordGuildActionRuntime.listGuildEmojisDiscord(guildId, { accountId })
|
||||
: await discordGuildActionRuntime.listGuildEmojisDiscord(guildId);
|
||||
return jsonResult({ ok: true, emojis });
|
||||
}
|
||||
case "emojiUpload": {
|
||||
@ -129,7 +150,7 @@ export async function handleDiscordGuildAction(
|
||||
});
|
||||
const roleIds = readStringArrayParam(params, "roleIds");
|
||||
const emoji = accountId
|
||||
? await uploadEmojiDiscord(
|
||||
? await discordGuildActionRuntime.uploadEmojiDiscord(
|
||||
{
|
||||
guildId,
|
||||
name,
|
||||
@ -138,7 +159,7 @@ export async function handleDiscordGuildAction(
|
||||
},
|
||||
{ accountId },
|
||||
)
|
||||
: await uploadEmojiDiscord({
|
||||
: await discordGuildActionRuntime.uploadEmojiDiscord({
|
||||
guildId,
|
||||
name,
|
||||
mediaUrl,
|
||||
@ -162,7 +183,7 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const sticker = accountId
|
||||
? await uploadStickerDiscord(
|
||||
? await discordGuildActionRuntime.uploadStickerDiscord(
|
||||
{
|
||||
guildId,
|
||||
name,
|
||||
@ -172,7 +193,7 @@ export async function handleDiscordGuildAction(
|
||||
},
|
||||
{ accountId },
|
||||
)
|
||||
: await uploadStickerDiscord({
|
||||
: await discordGuildActionRuntime.uploadStickerDiscord({
|
||||
guildId,
|
||||
name,
|
||||
description,
|
||||
@ -185,14 +206,22 @@ export async function handleDiscordGuildAction(
|
||||
if (!isActionEnabled("roles", false)) {
|
||||
throw new Error("Discord role changes are disabled.");
|
||||
}
|
||||
await runRoleMutation({ accountId, values: params, mutate: addRoleDiscord });
|
||||
await runRoleMutation({
|
||||
accountId,
|
||||
values: params,
|
||||
mutate: discordGuildActionRuntime.addRoleDiscord,
|
||||
});
|
||||
return jsonResult({ ok: true });
|
||||
}
|
||||
case "roleRemove": {
|
||||
if (!isActionEnabled("roles", false)) {
|
||||
throw new Error("Discord role changes are disabled.");
|
||||
}
|
||||
await runRoleMutation({ accountId, values: params, mutate: removeRoleDiscord });
|
||||
await runRoleMutation({
|
||||
accountId,
|
||||
values: params,
|
||||
mutate: discordGuildActionRuntime.removeRoleDiscord,
|
||||
});
|
||||
return jsonResult({ ok: true });
|
||||
}
|
||||
case "channelInfo": {
|
||||
@ -203,8 +232,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const channel = accountId
|
||||
? await fetchChannelInfoDiscord(channelId, { accountId })
|
||||
: await fetchChannelInfoDiscord(channelId);
|
||||
? await discordGuildActionRuntime.fetchChannelInfoDiscord(channelId, { accountId })
|
||||
: await discordGuildActionRuntime.fetchChannelInfoDiscord(channelId);
|
||||
return jsonResult({ ok: true, channel });
|
||||
}
|
||||
case "channelList": {
|
||||
@ -215,8 +244,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const channels = accountId
|
||||
? await listGuildChannelsDiscord(guildId, { accountId })
|
||||
: await listGuildChannelsDiscord(guildId);
|
||||
? await discordGuildActionRuntime.listGuildChannelsDiscord(guildId, { accountId })
|
||||
: await discordGuildActionRuntime.listGuildChannelsDiscord(guildId);
|
||||
return jsonResult({ ok: true, channels });
|
||||
}
|
||||
case "voiceStatus": {
|
||||
@ -230,8 +259,10 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const voice = accountId
|
||||
? await fetchVoiceStatusDiscord(guildId, userId, { accountId })
|
||||
: await fetchVoiceStatusDiscord(guildId, userId);
|
||||
? await discordGuildActionRuntime.fetchVoiceStatusDiscord(guildId, userId, {
|
||||
accountId,
|
||||
})
|
||||
: await discordGuildActionRuntime.fetchVoiceStatusDiscord(guildId, userId);
|
||||
return jsonResult({ ok: true, voice });
|
||||
}
|
||||
case "eventList": {
|
||||
@ -242,8 +273,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const events = accountId
|
||||
? await listScheduledEventsDiscord(guildId, { accountId })
|
||||
: await listScheduledEventsDiscord(guildId);
|
||||
? await discordGuildActionRuntime.listScheduledEventsDiscord(guildId, { accountId })
|
||||
: await discordGuildActionRuntime.listScheduledEventsDiscord(guildId);
|
||||
return jsonResult({ ok: true, events });
|
||||
}
|
||||
case "eventCreate": {
|
||||
@ -274,8 +305,10 @@ export async function handleDiscordGuildAction(
|
||||
privacy_level: 2,
|
||||
};
|
||||
const event = accountId
|
||||
? await createScheduledEventDiscord(guildId, payload, { accountId })
|
||||
: await createScheduledEventDiscord(guildId, payload);
|
||||
? await discordGuildActionRuntime.createScheduledEventDiscord(guildId, payload, {
|
||||
accountId,
|
||||
})
|
||||
: await discordGuildActionRuntime.createScheduledEventDiscord(guildId, payload);
|
||||
return jsonResult({ ok: true, event });
|
||||
}
|
||||
case "channelCreate": {
|
||||
@ -290,7 +323,7 @@ export async function handleDiscordGuildAction(
|
||||
const position = readNumberParam(params, "position", { integer: true });
|
||||
const nsfw = params.nsfw as boolean | undefined;
|
||||
const channel = accountId
|
||||
? await createChannelDiscord(
|
||||
? await discordGuildActionRuntime.createChannelDiscord(
|
||||
{
|
||||
guildId,
|
||||
name,
|
||||
@ -302,7 +335,7 @@ export async function handleDiscordGuildAction(
|
||||
},
|
||||
{ accountId },
|
||||
)
|
||||
: await createChannelDiscord({
|
||||
: await discordGuildActionRuntime.createChannelDiscord({
|
||||
guildId,
|
||||
name,
|
||||
type: type ?? undefined,
|
||||
@ -348,8 +381,8 @@ export async function handleDiscordGuildAction(
|
||||
availableTags,
|
||||
};
|
||||
const channel = accountId
|
||||
? await editChannelDiscord(editPayload, { accountId })
|
||||
: await editChannelDiscord(editPayload);
|
||||
? await discordGuildActionRuntime.editChannelDiscord(editPayload, { accountId })
|
||||
: await discordGuildActionRuntime.editChannelDiscord(editPayload);
|
||||
return jsonResult({ ok: true, channel });
|
||||
}
|
||||
case "channelDelete": {
|
||||
@ -360,8 +393,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const result = accountId
|
||||
? await deleteChannelDiscord(channelId, { accountId })
|
||||
: await deleteChannelDiscord(channelId);
|
||||
? await discordGuildActionRuntime.deleteChannelDiscord(channelId, { accountId })
|
||||
: await discordGuildActionRuntime.deleteChannelDiscord(channelId);
|
||||
return jsonResult(result);
|
||||
}
|
||||
case "channelMove": {
|
||||
@ -375,7 +408,7 @@ export async function handleDiscordGuildAction(
|
||||
const parentId = readDiscordParentIdParam(params);
|
||||
const position = readNumberParam(params, "position", { integer: true });
|
||||
if (accountId) {
|
||||
await moveChannelDiscord(
|
||||
await discordGuildActionRuntime.moveChannelDiscord(
|
||||
{
|
||||
guildId,
|
||||
channelId,
|
||||
@ -385,7 +418,7 @@ export async function handleDiscordGuildAction(
|
||||
{ accountId },
|
||||
);
|
||||
} else {
|
||||
await moveChannelDiscord({
|
||||
await discordGuildActionRuntime.moveChannelDiscord({
|
||||
guildId,
|
||||
channelId,
|
||||
parentId,
|
||||
@ -402,7 +435,7 @@ export async function handleDiscordGuildAction(
|
||||
const name = readStringParam(params, "name", { required: true });
|
||||
const position = readNumberParam(params, "position", { integer: true });
|
||||
const channel = accountId
|
||||
? await createChannelDiscord(
|
||||
? await discordGuildActionRuntime.createChannelDiscord(
|
||||
{
|
||||
guildId,
|
||||
name,
|
||||
@ -411,7 +444,7 @@ export async function handleDiscordGuildAction(
|
||||
},
|
||||
{ accountId },
|
||||
)
|
||||
: await createChannelDiscord({
|
||||
: await discordGuildActionRuntime.createChannelDiscord({
|
||||
guildId,
|
||||
name,
|
||||
type: 4,
|
||||
@ -429,7 +462,7 @@ export async function handleDiscordGuildAction(
|
||||
const name = readStringParam(params, "name");
|
||||
const position = readNumberParam(params, "position", { integer: true });
|
||||
const channel = accountId
|
||||
? await editChannelDiscord(
|
||||
? await discordGuildActionRuntime.editChannelDiscord(
|
||||
{
|
||||
channelId: categoryId,
|
||||
name: name ?? undefined,
|
||||
@ -437,7 +470,7 @@ export async function handleDiscordGuildAction(
|
||||
},
|
||||
{ accountId },
|
||||
)
|
||||
: await editChannelDiscord({
|
||||
: await discordGuildActionRuntime.editChannelDiscord({
|
||||
channelId: categoryId,
|
||||
name: name ?? undefined,
|
||||
position: position ?? undefined,
|
||||
@ -452,8 +485,8 @@ export async function handleDiscordGuildAction(
|
||||
required: true,
|
||||
});
|
||||
const result = accountId
|
||||
? await deleteChannelDiscord(categoryId, { accountId })
|
||||
: await deleteChannelDiscord(categoryId);
|
||||
? await discordGuildActionRuntime.deleteChannelDiscord(categoryId, { accountId })
|
||||
: await discordGuildActionRuntime.deleteChannelDiscord(categoryId);
|
||||
return jsonResult(result);
|
||||
}
|
||||
case "channelPermissionSet": {
|
||||
@ -468,7 +501,7 @@ export async function handleDiscordGuildAction(
|
||||
const allow = readStringParam(params, "allow");
|
||||
const deny = readStringParam(params, "deny");
|
||||
if (accountId) {
|
||||
await setChannelPermissionDiscord(
|
||||
await discordGuildActionRuntime.setChannelPermissionDiscord(
|
||||
{
|
||||
channelId,
|
||||
targetId,
|
||||
@ -479,7 +512,7 @@ export async function handleDiscordGuildAction(
|
||||
{ accountId },
|
||||
);
|
||||
} else {
|
||||
await setChannelPermissionDiscord({
|
||||
await discordGuildActionRuntime.setChannelPermissionDiscord({
|
||||
channelId,
|
||||
targetId,
|
||||
targetType,
|
||||
@ -495,9 +528,11 @@ export async function handleDiscordGuildAction(
|
||||
}
|
||||
const { channelId, targetId } = readChannelPermissionTarget(params);
|
||||
if (accountId) {
|
||||
await removeChannelPermissionDiscord(channelId, targetId, { accountId });
|
||||
await discordGuildActionRuntime.removeChannelPermissionDiscord(channelId, targetId, {
|
||||
accountId,
|
||||
});
|
||||
} else {
|
||||
await removeChannelPermissionDiscord(channelId, targetId);
|
||||
await discordGuildActionRuntime.removeChannelPermissionDiscord(channelId, targetId);
|
||||
}
|
||||
return jsonResult({ ok: true });
|
||||
}
|
||||
@ -1,7 +1,19 @@
|
||||
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||
import type { DiscordActionConfig } from "../../config/config.js";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { readBooleanParam } from "../../plugin-sdk/boolean-param.js";
|
||||
import { readBooleanParam } from "openclaw/plugin-sdk/boolean-param";
|
||||
import { withNormalizedTimestamp } from "../../../../src/agents/date-time.js";
|
||||
import { assertMediaNotDataUrl } from "../../../../src/agents/sandbox-paths.js";
|
||||
import {
|
||||
type ActionGate,
|
||||
jsonResult,
|
||||
readNumberParam,
|
||||
readReactionParams,
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "../../../../src/agents/tools/common.js";
|
||||
import type { OpenClawConfig } from "../../../../src/config/config.js";
|
||||
import type { DiscordActionConfig } from "../../../../src/config/types.discord.js";
|
||||
import { resolvePollMaxSelections } from "../../../../src/polls.js";
|
||||
import { readDiscordComponentSpec } from "../components.js";
|
||||
import {
|
||||
createThreadDiscord,
|
||||
deleteMessageDiscord,
|
||||
@ -23,20 +35,34 @@ import {
|
||||
sendStickerDiscord,
|
||||
sendVoiceMessageDiscord,
|
||||
unpinMessageDiscord,
|
||||
} from "../../plugin-sdk/discord.js";
|
||||
import type { DiscordSendComponents, DiscordSendEmbeds } from "../../plugin-sdk/discord.js";
|
||||
import { readDiscordComponentSpec, resolveDiscordChannelId } from "../../plugin-sdk/discord.js";
|
||||
import { resolvePollMaxSelections } from "../../polls.js";
|
||||
import { withNormalizedTimestamp } from "../date-time.js";
|
||||
import { assertMediaNotDataUrl } from "../sandbox-paths.js";
|
||||
import {
|
||||
type ActionGate,
|
||||
jsonResult,
|
||||
readNumberParam,
|
||||
readReactionParams,
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "./common.js";
|
||||
} from "../send.js";
|
||||
import type { DiscordSendComponents, DiscordSendEmbeds } from "../send.shared.js";
|
||||
import { resolveDiscordChannelId } from "../targets.js";
|
||||
|
||||
export const discordMessagingActionRuntime = {
|
||||
createThreadDiscord,
|
||||
deleteMessageDiscord,
|
||||
editMessageDiscord,
|
||||
fetchChannelPermissionsDiscord,
|
||||
fetchMessageDiscord,
|
||||
fetchReactionsDiscord,
|
||||
listPinsDiscord,
|
||||
listThreadsDiscord,
|
||||
pinMessageDiscord,
|
||||
reactMessageDiscord,
|
||||
readDiscordComponentSpec,
|
||||
readMessagesDiscord,
|
||||
removeOwnReactionsDiscord,
|
||||
removeReactionDiscord,
|
||||
resolveDiscordChannelId,
|
||||
searchMessagesDiscord,
|
||||
sendDiscordComponentMessage,
|
||||
sendMessageDiscord,
|
||||
sendPollDiscord,
|
||||
sendStickerDiscord,
|
||||
sendVoiceMessageDiscord,
|
||||
unpinMessageDiscord,
|
||||
};
|
||||
|
||||
function parseDiscordMessageLink(link: string) {
|
||||
const normalized = link.trim();
|
||||
@ -65,7 +91,7 @@ export async function handleDiscordMessagingAction(
|
||||
cfg?: OpenClawConfig,
|
||||
): Promise<AgentToolResult<unknown>> {
|
||||
const resolveChannelId = () =>
|
||||
resolveDiscordChannelId(
|
||||
discordMessagingActionRuntime.resolveDiscordChannelId(
|
||||
readStringParam(params, "channelId", {
|
||||
required: true,
|
||||
}),
|
||||
@ -95,28 +121,45 @@ export async function handleDiscordMessagingAction(
|
||||
});
|
||||
if (remove) {
|
||||
if (accountId) {
|
||||
await removeReactionDiscord(channelId, messageId, emoji, {
|
||||
await discordMessagingActionRuntime.removeReactionDiscord(channelId, messageId, emoji, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
});
|
||||
} else {
|
||||
await removeReactionDiscord(channelId, messageId, emoji, cfgOptions);
|
||||
await discordMessagingActionRuntime.removeReactionDiscord(
|
||||
channelId,
|
||||
messageId,
|
||||
emoji,
|
||||
cfgOptions,
|
||||
);
|
||||
}
|
||||
return jsonResult({ ok: true, removed: emoji });
|
||||
}
|
||||
if (isEmpty) {
|
||||
const removed = accountId
|
||||
? await removeOwnReactionsDiscord(channelId, messageId, { ...cfgOptions, accountId })
|
||||
: await removeOwnReactionsDiscord(channelId, messageId, cfgOptions);
|
||||
? await discordMessagingActionRuntime.removeOwnReactionsDiscord(channelId, messageId, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
})
|
||||
: await discordMessagingActionRuntime.removeOwnReactionsDiscord(
|
||||
channelId,
|
||||
messageId,
|
||||
cfgOptions,
|
||||
);
|
||||
return jsonResult({ ok: true, removed: removed.removed });
|
||||
}
|
||||
if (accountId) {
|
||||
await reactMessageDiscord(channelId, messageId, emoji, {
|
||||
await discordMessagingActionRuntime.reactMessageDiscord(channelId, messageId, emoji, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
});
|
||||
} else {
|
||||
await reactMessageDiscord(channelId, messageId, emoji, cfgOptions);
|
||||
await discordMessagingActionRuntime.reactMessageDiscord(
|
||||
channelId,
|
||||
messageId,
|
||||
emoji,
|
||||
cfgOptions,
|
||||
);
|
||||
}
|
||||
return jsonResult({ ok: true, added: emoji });
|
||||
}
|
||||
@ -129,11 +172,15 @@ export async function handleDiscordMessagingAction(
|
||||
required: true,
|
||||
});
|
||||
const limit = readNumberParam(params, "limit");
|
||||
const reactions = await fetchReactionsDiscord(channelId, messageId, {
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
limit,
|
||||
});
|
||||
const reactions = await discordMessagingActionRuntime.fetchReactionsDiscord(
|
||||
channelId,
|
||||
messageId,
|
||||
{
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
limit,
|
||||
},
|
||||
);
|
||||
return jsonResult({ ok: true, reactions });
|
||||
}
|
||||
case "sticker": {
|
||||
@ -146,7 +193,7 @@ export async function handleDiscordMessagingAction(
|
||||
required: true,
|
||||
label: "stickerIds",
|
||||
});
|
||||
await sendStickerDiscord(to, stickerIds, {
|
||||
await discordMessagingActionRuntime.sendStickerDiscord(to, stickerIds, {
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
content,
|
||||
@ -169,7 +216,7 @@ export async function handleDiscordMessagingAction(
|
||||
const allowMultiselect = readBooleanParam(params, "allowMultiselect");
|
||||
const durationHours = readNumberParam(params, "durationHours");
|
||||
const maxSelections = resolvePollMaxSelections(answers.length, allowMultiselect);
|
||||
await sendPollDiscord(
|
||||
await discordMessagingActionRuntime.sendPollDiscord(
|
||||
to,
|
||||
{ question, options: answers, maxSelections, durationHours },
|
||||
{ ...cfgOptions, ...(accountId ? { accountId } : {}), content },
|
||||
@ -182,8 +229,11 @@ export async function handleDiscordMessagingAction(
|
||||
}
|
||||
const channelId = resolveChannelId();
|
||||
const permissions = accountId
|
||||
? await fetchChannelPermissionsDiscord(channelId, { ...cfgOptions, accountId })
|
||||
: await fetchChannelPermissionsDiscord(channelId, cfgOptions);
|
||||
? await discordMessagingActionRuntime.fetchChannelPermissionsDiscord(channelId, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
})
|
||||
: await discordMessagingActionRuntime.fetchChannelPermissionsDiscord(channelId, cfgOptions);
|
||||
return jsonResult({ ok: true, permissions });
|
||||
}
|
||||
case "fetchMessage": {
|
||||
@ -206,8 +256,11 @@ export async function handleDiscordMessagingAction(
|
||||
);
|
||||
}
|
||||
const message = accountId
|
||||
? await fetchMessageDiscord(channelId, messageId, { ...cfgOptions, accountId })
|
||||
: await fetchMessageDiscord(channelId, messageId, cfgOptions);
|
||||
? await discordMessagingActionRuntime.fetchMessageDiscord(channelId, messageId, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
})
|
||||
: await discordMessagingActionRuntime.fetchMessageDiscord(channelId, messageId, cfgOptions);
|
||||
return jsonResult({
|
||||
ok: true,
|
||||
message: normalizeMessage(message),
|
||||
@ -228,8 +281,11 @@ export async function handleDiscordMessagingAction(
|
||||
around: readStringParam(params, "around"),
|
||||
};
|
||||
const messages = accountId
|
||||
? await readMessagesDiscord(channelId, query, { ...cfgOptions, accountId })
|
||||
: await readMessagesDiscord(channelId, query, cfgOptions);
|
||||
? await discordMessagingActionRuntime.readMessagesDiscord(channelId, query, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
})
|
||||
: await discordMessagingActionRuntime.readMessagesDiscord(channelId, query, cfgOptions);
|
||||
return jsonResult({
|
||||
ok: true,
|
||||
messages: messages.map((message) => normalizeMessage(message)),
|
||||
@ -245,7 +301,7 @@ export async function handleDiscordMessagingAction(
|
||||
const rawComponents = params.components;
|
||||
const componentSpec =
|
||||
rawComponents && typeof rawComponents === "object" && !Array.isArray(rawComponents)
|
||||
? readDiscordComponentSpec(rawComponents)
|
||||
? discordMessagingActionRuntime.readDiscordComponentSpec(rawComponents)
|
||||
: null;
|
||||
const components: DiscordSendComponents | undefined =
|
||||
Array.isArray(rawComponents) || typeof rawComponents === "function"
|
||||
@ -279,16 +335,20 @@ export async function handleDiscordMessagingAction(
|
||||
const payload = componentSpec.text
|
||||
? componentSpec
|
||||
: { ...componentSpec, text: normalizedContent };
|
||||
const result = await sendDiscordComponentMessage(to, payload, {
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
silent,
|
||||
replyTo: replyTo ?? undefined,
|
||||
sessionKey: sessionKey ?? undefined,
|
||||
agentId: agentId ?? undefined,
|
||||
mediaUrl: mediaUrl ?? undefined,
|
||||
filename: filename ?? undefined,
|
||||
});
|
||||
const result = await discordMessagingActionRuntime.sendDiscordComponentMessage(
|
||||
to,
|
||||
payload,
|
||||
{
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
silent,
|
||||
replyTo: replyTo ?? undefined,
|
||||
sessionKey: sessionKey ?? undefined,
|
||||
agentId: agentId ?? undefined,
|
||||
mediaUrl: mediaUrl ?? undefined,
|
||||
filename: filename ?? undefined,
|
||||
},
|
||||
);
|
||||
return jsonResult({ ok: true, result, components: true });
|
||||
}
|
||||
|
||||
@ -305,7 +365,7 @@ export async function handleDiscordMessagingAction(
|
||||
);
|
||||
}
|
||||
assertMediaNotDataUrl(mediaUrl);
|
||||
const result = await sendVoiceMessageDiscord(to, mediaUrl, {
|
||||
const result = await discordMessagingActionRuntime.sendVoiceMessageDiscord(to, mediaUrl, {
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
replyTo,
|
||||
@ -314,7 +374,7 @@ export async function handleDiscordMessagingAction(
|
||||
return jsonResult({ ok: true, result, voiceMessage: true });
|
||||
}
|
||||
|
||||
const result = await sendMessageDiscord(to, content ?? "", {
|
||||
const result = await discordMessagingActionRuntime.sendMessageDiscord(to, content ?? "", {
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
mediaUrl,
|
||||
@ -338,8 +398,18 @@ export async function handleDiscordMessagingAction(
|
||||
required: true,
|
||||
});
|
||||
const message = accountId
|
||||
? await editMessageDiscord(channelId, messageId, { content }, { ...cfgOptions, accountId })
|
||||
: await editMessageDiscord(channelId, messageId, { content }, cfgOptions);
|
||||
? await discordMessagingActionRuntime.editMessageDiscord(
|
||||
channelId,
|
||||
messageId,
|
||||
{ content },
|
||||
{ ...cfgOptions, accountId },
|
||||
)
|
||||
: await discordMessagingActionRuntime.editMessageDiscord(
|
||||
channelId,
|
||||
messageId,
|
||||
{ content },
|
||||
cfgOptions,
|
||||
);
|
||||
return jsonResult({ ok: true, message });
|
||||
}
|
||||
case "deleteMessage": {
|
||||
@ -351,9 +421,12 @@ export async function handleDiscordMessagingAction(
|
||||
required: true,
|
||||
});
|
||||
if (accountId) {
|
||||
await deleteMessageDiscord(channelId, messageId, { ...cfgOptions, accountId });
|
||||
await discordMessagingActionRuntime.deleteMessageDiscord(channelId, messageId, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
});
|
||||
} else {
|
||||
await deleteMessageDiscord(channelId, messageId, cfgOptions);
|
||||
await discordMessagingActionRuntime.deleteMessageDiscord(channelId, messageId, cfgOptions);
|
||||
}
|
||||
return jsonResult({ ok: true });
|
||||
}
|
||||
@ -375,8 +448,11 @@ export async function handleDiscordMessagingAction(
|
||||
appliedTags: appliedTags ?? undefined,
|
||||
};
|
||||
const thread = accountId
|
||||
? await createThreadDiscord(channelId, payload, { ...cfgOptions, accountId })
|
||||
: await createThreadDiscord(channelId, payload, cfgOptions);
|
||||
? await discordMessagingActionRuntime.createThreadDiscord(channelId, payload, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
})
|
||||
: await discordMessagingActionRuntime.createThreadDiscord(channelId, payload, cfgOptions);
|
||||
return jsonResult({ ok: true, thread });
|
||||
}
|
||||
case "threadList": {
|
||||
@ -391,7 +467,7 @@ export async function handleDiscordMessagingAction(
|
||||
const before = readStringParam(params, "before");
|
||||
const limit = readNumberParam(params, "limit");
|
||||
const threads = accountId
|
||||
? await listThreadsDiscord(
|
||||
? await discordMessagingActionRuntime.listThreadsDiscord(
|
||||
{
|
||||
guildId,
|
||||
channelId,
|
||||
@ -401,7 +477,7 @@ export async function handleDiscordMessagingAction(
|
||||
},
|
||||
{ ...cfgOptions, accountId },
|
||||
)
|
||||
: await listThreadsDiscord(
|
||||
: await discordMessagingActionRuntime.listThreadsDiscord(
|
||||
{
|
||||
guildId,
|
||||
channelId,
|
||||
@ -423,13 +499,17 @@ export async function handleDiscordMessagingAction(
|
||||
});
|
||||
const mediaUrl = readStringParam(params, "mediaUrl");
|
||||
const replyTo = readStringParam(params, "replyTo");
|
||||
const result = await sendMessageDiscord(`channel:${channelId}`, content, {
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
mediaUrl,
|
||||
mediaLocalRoots: options?.mediaLocalRoots,
|
||||
replyTo,
|
||||
});
|
||||
const result = await discordMessagingActionRuntime.sendMessageDiscord(
|
||||
`channel:${channelId}`,
|
||||
content,
|
||||
{
|
||||
...cfgOptions,
|
||||
...(accountId ? { accountId } : {}),
|
||||
mediaUrl,
|
||||
mediaLocalRoots: options?.mediaLocalRoots,
|
||||
replyTo,
|
||||
},
|
||||
);
|
||||
return jsonResult({ ok: true, result });
|
||||
}
|
||||
case "pinMessage": {
|
||||
@ -441,9 +521,12 @@ export async function handleDiscordMessagingAction(
|
||||
required: true,
|
||||
});
|
||||
if (accountId) {
|
||||
await pinMessageDiscord(channelId, messageId, { ...cfgOptions, accountId });
|
||||
await discordMessagingActionRuntime.pinMessageDiscord(channelId, messageId, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
});
|
||||
} else {
|
||||
await pinMessageDiscord(channelId, messageId, cfgOptions);
|
||||
await discordMessagingActionRuntime.pinMessageDiscord(channelId, messageId, cfgOptions);
|
||||
}
|
||||
return jsonResult({ ok: true });
|
||||
}
|
||||
@ -456,9 +539,12 @@ export async function handleDiscordMessagingAction(
|
||||
required: true,
|
||||
});
|
||||
if (accountId) {
|
||||
await unpinMessageDiscord(channelId, messageId, { ...cfgOptions, accountId });
|
||||
await discordMessagingActionRuntime.unpinMessageDiscord(channelId, messageId, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
});
|
||||
} else {
|
||||
await unpinMessageDiscord(channelId, messageId, cfgOptions);
|
||||
await discordMessagingActionRuntime.unpinMessageDiscord(channelId, messageId, cfgOptions);
|
||||
}
|
||||
return jsonResult({ ok: true });
|
||||
}
|
||||
@ -468,8 +554,11 @@ export async function handleDiscordMessagingAction(
|
||||
}
|
||||
const channelId = resolveChannelId();
|
||||
const pins = accountId
|
||||
? await listPinsDiscord(channelId, { ...cfgOptions, accountId })
|
||||
: await listPinsDiscord(channelId, cfgOptions);
|
||||
? await discordMessagingActionRuntime.listPinsDiscord(channelId, {
|
||||
...cfgOptions,
|
||||
accountId,
|
||||
})
|
||||
: await discordMessagingActionRuntime.listPinsDiscord(channelId, cfgOptions);
|
||||
return jsonResult({ ok: true, pins: pins.map((pin) => normalizeMessage(pin)) });
|
||||
}
|
||||
case "searchMessages": {
|
||||
@ -490,7 +579,7 @@ export async function handleDiscordMessagingAction(
|
||||
const channelIdList = [...(channelIds ?? []), ...(channelId ? [channelId] : [])];
|
||||
const authorIdList = [...(authorIds ?? []), ...(authorId ? [authorId] : [])];
|
||||
const results = accountId
|
||||
? await searchMessagesDiscord(
|
||||
? await discordMessagingActionRuntime.searchMessagesDiscord(
|
||||
{
|
||||
guildId,
|
||||
content,
|
||||
@ -500,7 +589,7 @@ export async function handleDiscordMessagingAction(
|
||||
},
|
||||
{ ...cfgOptions, accountId },
|
||||
)
|
||||
: await searchMessagesDiscord(
|
||||
: await discordMessagingActionRuntime.searchMessagesDiscord(
|
||||
{
|
||||
guildId,
|
||||
content,
|
||||
@ -1,5 +1,5 @@
|
||||
import { PermissionFlagsBits } from "discord-api-types/v10";
|
||||
import { readNumberParam, readStringParam } from "./common.js";
|
||||
import { readNumberParam, readStringParam } from "../../../../src/agents/tools/common.js";
|
||||
|
||||
export type DiscordModerationAction = "timeout" | "kick" | "ban";
|
||||
|
||||
@ -1,25 +1,30 @@
|
||||
import { PermissionFlagsBits } from "discord-api-types/v10";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { DiscordActionConfig } from "../../config/config.js";
|
||||
import { handleDiscordModerationAction } from "./discord-actions-moderation.js";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { DiscordActionConfig } from "../../../../src/config/types.discord.js";
|
||||
import {
|
||||
discordModerationActionRuntime,
|
||||
handleDiscordModerationAction,
|
||||
} from "./runtime.moderation.js";
|
||||
|
||||
const discordSendMocks = vi.hoisted(() => ({
|
||||
banMemberDiscord: vi.fn(async () => ({ ok: true })),
|
||||
kickMemberDiscord: vi.fn(async () => ({ ok: true })),
|
||||
timeoutMemberDiscord: vi.fn(async () => ({ id: "user-1" })),
|
||||
hasAnyGuildPermissionDiscord: vi.fn(async () => false),
|
||||
}));
|
||||
|
||||
const { banMemberDiscord, kickMemberDiscord, timeoutMemberDiscord, hasAnyGuildPermissionDiscord } =
|
||||
discordSendMocks;
|
||||
|
||||
vi.mock("../../../extensions/discord/src/send.js", () => ({
|
||||
...discordSendMocks,
|
||||
}));
|
||||
const originalDiscordModerationActionRuntime = { ...discordModerationActionRuntime };
|
||||
const banMemberDiscord = vi.fn(async () => ({ ok: true }));
|
||||
const kickMemberDiscord = vi.fn(async () => ({ ok: true }));
|
||||
const timeoutMemberDiscord = vi.fn(async () => ({ id: "user-1" }));
|
||||
const hasAnyGuildPermissionDiscord = vi.fn(async () => false);
|
||||
|
||||
const enableAllActions = (_key: keyof DiscordActionConfig, _defaultValue = true) => true;
|
||||
|
||||
describe("discord moderation sender authorization", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
Object.assign(discordModerationActionRuntime, originalDiscordModerationActionRuntime, {
|
||||
banMemberDiscord,
|
||||
kickMemberDiscord,
|
||||
timeoutMemberDiscord,
|
||||
hasAnyGuildPermissionDiscord,
|
||||
});
|
||||
});
|
||||
|
||||
it("rejects ban when sender lacks BAN_MEMBERS", async () => {
|
||||
hasAnyGuildPermissionDiscord.mockResolvedValueOnce(false);
|
||||
|
||||
@ -1,17 +1,28 @@
|
||||
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||
import type { DiscordActionConfig } from "../../config/config.js";
|
||||
import {
|
||||
type ActionGate,
|
||||
jsonResult,
|
||||
readStringParam,
|
||||
} from "../../../../src/agents/tools/common.js";
|
||||
import type { DiscordActionConfig } from "../../../../src/config/types.discord.js";
|
||||
import {
|
||||
banMemberDiscord,
|
||||
hasAnyGuildPermissionDiscord,
|
||||
kickMemberDiscord,
|
||||
timeoutMemberDiscord,
|
||||
} from "../../plugin-sdk/discord.js";
|
||||
import { type ActionGate, jsonResult, readStringParam } from "./common.js";
|
||||
} from "../send.js";
|
||||
import {
|
||||
isDiscordModerationAction,
|
||||
readDiscordModerationCommand,
|
||||
requiredGuildPermissionForModerationAction,
|
||||
} from "./discord-actions-moderation-shared.js";
|
||||
} from "./runtime.moderation-shared.js";
|
||||
|
||||
export const discordModerationActionRuntime = {
|
||||
banMemberDiscord,
|
||||
hasAnyGuildPermissionDiscord,
|
||||
kickMemberDiscord,
|
||||
timeoutMemberDiscord,
|
||||
};
|
||||
|
||||
async function verifySenderModerationPermission(params: {
|
||||
guildId: string;
|
||||
@ -23,7 +34,7 @@ async function verifySenderModerationPermission(params: {
|
||||
if (!params.senderUserId) {
|
||||
return;
|
||||
}
|
||||
const hasPermission = await hasAnyGuildPermissionDiscord(
|
||||
const hasPermission = await discordModerationActionRuntime.hasAnyGuildPermissionDiscord(
|
||||
params.guildId,
|
||||
params.senderUserId,
|
||||
[params.requiredPermission],
|
||||
@ -57,7 +68,7 @@ export async function handleDiscordModerationAction(
|
||||
switch (command.action) {
|
||||
case "timeout": {
|
||||
const member = accountId
|
||||
? await timeoutMemberDiscord(
|
||||
? await discordModerationActionRuntime.timeoutMemberDiscord(
|
||||
{
|
||||
guildId: command.guildId,
|
||||
userId: command.userId,
|
||||
@ -67,7 +78,7 @@ export async function handleDiscordModerationAction(
|
||||
},
|
||||
{ accountId },
|
||||
)
|
||||
: await timeoutMemberDiscord({
|
||||
: await discordModerationActionRuntime.timeoutMemberDiscord({
|
||||
guildId: command.guildId,
|
||||
userId: command.userId,
|
||||
durationMinutes: command.durationMinutes,
|
||||
@ -78,7 +89,7 @@ export async function handleDiscordModerationAction(
|
||||
}
|
||||
case "kick": {
|
||||
if (accountId) {
|
||||
await kickMemberDiscord(
|
||||
await discordModerationActionRuntime.kickMemberDiscord(
|
||||
{
|
||||
guildId: command.guildId,
|
||||
userId: command.userId,
|
||||
@ -87,7 +98,7 @@ export async function handleDiscordModerationAction(
|
||||
{ accountId },
|
||||
);
|
||||
} else {
|
||||
await kickMemberDiscord({
|
||||
await discordModerationActionRuntime.kickMemberDiscord({
|
||||
guildId: command.guildId,
|
||||
userId: command.userId,
|
||||
reason: command.reason,
|
||||
@ -97,7 +108,7 @@ export async function handleDiscordModerationAction(
|
||||
}
|
||||
case "ban": {
|
||||
if (accountId) {
|
||||
await banMemberDiscord(
|
||||
await discordModerationActionRuntime.banMemberDiscord(
|
||||
{
|
||||
guildId: command.guildId,
|
||||
userId: command.userId,
|
||||
@ -107,7 +118,7 @@ export async function handleDiscordModerationAction(
|
||||
{ accountId },
|
||||
);
|
||||
} else {
|
||||
await banMemberDiscord({
|
||||
await discordModerationActionRuntime.banMemberDiscord({
|
||||
guildId: command.guildId,
|
||||
userId: command.userId,
|
||||
reason: command.reason,
|
||||
@ -1,12 +1,9 @@
|
||||
import type { GatewayPlugin } from "@buape/carbon/gateway";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
clearGateways,
|
||||
registerGateway,
|
||||
} from "../../../extensions/discord/src/monitor/gateway-registry.js";
|
||||
import type { DiscordActionConfig } from "../../config/config.js";
|
||||
import type { ActionGate } from "./common.js";
|
||||
import { handleDiscordPresenceAction } from "./discord-actions-presence.js";
|
||||
import type { ActionGate } from "../../../../src/agents/tools/common.js";
|
||||
import type { DiscordActionConfig } from "../../../../src/config/types.discord.js";
|
||||
import { clearGateways, registerGateway } from "../monitor/gateway-registry.js";
|
||||
import { handleDiscordPresenceAction } from "./runtime.presence.js";
|
||||
|
||||
const mockUpdatePresence = vi.fn();
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
import type { Activity, UpdatePresenceData } from "@buape/carbon/gateway";
|
||||
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||
import type { DiscordActionConfig } from "../../config/config.js";
|
||||
import { getGateway } from "../../plugin-sdk/discord.js";
|
||||
import { type ActionGate, jsonResult, readStringParam } from "./common.js";
|
||||
import {
|
||||
type ActionGate,
|
||||
jsonResult,
|
||||
readStringParam,
|
||||
} from "../../../../src/agents/tools/common.js";
|
||||
import type { DiscordActionConfig } from "../../../../src/config/types.discord.js";
|
||||
import { getGateway } from "../monitor/gateway-registry.js";
|
||||
|
||||
const ACTIVITY_TYPE_MAP: Record<string, number> = {
|
||||
playing: 0,
|
||||
@ -1,4 +1,4 @@
|
||||
import { readStringParam } from "./common.js";
|
||||
import { readStringParam } from "../../../../src/agents/tools/common.js";
|
||||
|
||||
export function readDiscordParentIdParam(
|
||||
params: Record<string, unknown>,
|
||||
@ -1,11 +1,22 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { DiscordActionConfig, OpenClawConfig } from "../../config/config.js";
|
||||
import { handleDiscordGuildAction } from "./discord-actions-guild.js";
|
||||
import { handleDiscordMessagingAction } from "./discord-actions-messaging.js";
|
||||
import { handleDiscordModerationAction } from "./discord-actions-moderation.js";
|
||||
import { handleDiscordAction } from "./discord-actions.js";
|
||||
import type { OpenClawConfig } from "../../../../src/config/config.js";
|
||||
import type { DiscordActionConfig } from "../../../../src/config/types.discord.js";
|
||||
import { discordGuildActionRuntime, handleDiscordGuildAction } from "./runtime.guild.js";
|
||||
import { handleDiscordAction } from "./runtime.js";
|
||||
import {
|
||||
discordMessagingActionRuntime,
|
||||
handleDiscordMessagingAction,
|
||||
} from "./runtime.messaging.js";
|
||||
import {
|
||||
discordModerationActionRuntime,
|
||||
handleDiscordModerationAction,
|
||||
} from "./runtime.moderation.js";
|
||||
|
||||
const discordSendMocks = vi.hoisted(() => ({
|
||||
const originalDiscordMessagingActionRuntime = { ...discordMessagingActionRuntime };
|
||||
const originalDiscordGuildActionRuntime = { ...discordGuildActionRuntime };
|
||||
const originalDiscordModerationActionRuntime = { ...discordModerationActionRuntime };
|
||||
|
||||
const discordSendMocks = {
|
||||
banMemberDiscord: vi.fn(async () => ({})),
|
||||
createChannelDiscord: vi.fn(async () => ({
|
||||
id: "new-channel",
|
||||
@ -42,7 +53,7 @@ const discordSendMocks = vi.hoisted(() => ({
|
||||
setChannelPermissionDiscord: vi.fn(async () => ({ ok: true })),
|
||||
timeoutMemberDiscord: vi.fn(async () => ({})),
|
||||
unpinMessageDiscord: vi.fn(async () => ({})),
|
||||
}));
|
||||
};
|
||||
|
||||
const {
|
||||
createChannelDiscord,
|
||||
@ -67,21 +78,28 @@ const {
|
||||
timeoutMemberDiscord,
|
||||
} = discordSendMocks;
|
||||
|
||||
vi.mock("../../../extensions/discord/src/send.js", () => ({
|
||||
...discordSendMocks,
|
||||
}));
|
||||
|
||||
const enableAllActions = () => true;
|
||||
|
||||
const disabledActions = (key: keyof DiscordActionConfig) => key !== "reactions";
|
||||
const channelInfoEnabled = (key: keyof DiscordActionConfig) => key === "channelInfo";
|
||||
const moderationEnabled = (key: keyof DiscordActionConfig) => key === "moderation";
|
||||
|
||||
describe("handleDiscordMessagingAction", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
Object.assign(
|
||||
discordMessagingActionRuntime,
|
||||
originalDiscordMessagingActionRuntime,
|
||||
discordSendMocks,
|
||||
);
|
||||
Object.assign(discordGuildActionRuntime, originalDiscordGuildActionRuntime, discordSendMocks);
|
||||
Object.assign(
|
||||
discordModerationActionRuntime,
|
||||
originalDiscordModerationActionRuntime,
|
||||
discordSendMocks,
|
||||
);
|
||||
});
|
||||
|
||||
describe("handleDiscordMessagingAction", () => {
|
||||
it.each([
|
||||
{
|
||||
name: "without account",
|
||||
@ -1,11 +1,11 @@
|
||||
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
|
||||
import type { OpenClawConfig } from "../../config/config.js";
|
||||
import { createDiscordActionGate } from "../../plugin-sdk/discord.js";
|
||||
import { readStringParam } from "./common.js";
|
||||
import { handleDiscordGuildAction } from "./discord-actions-guild.js";
|
||||
import { handleDiscordMessagingAction } from "./discord-actions-messaging.js";
|
||||
import { handleDiscordModerationAction } from "./discord-actions-moderation.js";
|
||||
import { handleDiscordPresenceAction } from "./discord-actions-presence.js";
|
||||
import { readStringParam } from "../../../../src/agents/tools/common.js";
|
||||
import type { OpenClawConfig } from "../../../../src/config/config.js";
|
||||
import { createDiscordActionGate } from "../accounts.js";
|
||||
import { handleDiscordGuildAction } from "./runtime.guild.js";
|
||||
import { handleDiscordMessagingAction } from "./runtime.messaging.js";
|
||||
import { handleDiscordModerationAction } from "./runtime.moderation.js";
|
||||
import { handleDiscordPresenceAction } from "./runtime.presence.js";
|
||||
|
||||
const messagingActions = new Set([
|
||||
"react",
|
||||
@ -1,4 +1,5 @@
|
||||
import {
|
||||
createLegacyMessageToolDiscoveryMethods,
|
||||
createDiscordMessageToolComponentsSchema,
|
||||
createUnionActionGate,
|
||||
listTokenSourcedAccounts,
|
||||
@ -132,6 +133,7 @@ function describeDiscordMessageTool({
|
||||
|
||||
export const discordMessageActions: ChannelMessageActionAdapter = {
|
||||
describeMessageTool: describeDiscordMessageTool,
|
||||
...createLegacyMessageToolDiscoveryMethods(describeDiscordMessageTool),
|
||||
extractToolSend: ({ args }) => {
|
||||
const action = typeof args.action === "string" ? args.action.trim() : "";
|
||||
if (action === "sendMessage") {
|
||||
|
||||
@ -16,14 +16,18 @@ export * from "../agents/provider-id.js";
|
||||
export * from "../agents/schema/typebox.js";
|
||||
export * from "../agents/sglang-defaults.js";
|
||||
export * from "../agents/tools/common.js";
|
||||
export * from "../agents/tools/discord-actions-shared.js";
|
||||
export * from "../agents/tools/discord-actions.js";
|
||||
export * from "../agents/tools/telegram-actions.js";
|
||||
export * from "../agents/tools/web-guarded-fetch.js";
|
||||
export * from "../agents/tools/web-shared.js";
|
||||
export * from "../agents/tools/discord-actions-moderation-shared.js";
|
||||
export * from "../agents/tools/web-fetch-utils.js";
|
||||
export * from "../agents/vllm-defaults.js";
|
||||
// Intentional public runtime surface: channel plugins use ingress agent helpers directly.
|
||||
export * from "../agents/agent-command.js";
|
||||
export * from "../tts/tts.js";
|
||||
// Legacy channel action runtime re-exports. New bundled plugin code should use
|
||||
// local extension-owned modules instead of adding more public SDK surface here.
|
||||
export {
|
||||
handleDiscordAction,
|
||||
readDiscordParentIdParam,
|
||||
isDiscordModerationAction,
|
||||
readDiscordModerationCommand,
|
||||
} from "../../extensions/discord/runtime-api.js";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user