Discord: consolidate message tool discovery

This commit is contained in:
Gustavo Madeira Santana
2026-03-18 00:06:55 +00:00
parent c9ba985839
commit 0a0ca804aa
2 changed files with 105 additions and 96 deletions

View File

@@ -6,6 +6,7 @@ import {
import type {
ChannelMessageActionAdapter,
ChannelMessageActionName,
ChannelMessageToolDiscovery,
} from "openclaw/plugin-sdk/channel-runtime";
import type { DiscordActionConfig } from "openclaw/plugin-sdk/config-runtime";
import { createDiscordActionGate, listEnabledDiscordAccounts } from "./accounts.js";
@@ -28,103 +29,109 @@ function resolveDiscordActionDiscovery(cfg: Parameters<typeof listEnabledDiscord
};
}
function describeDiscordMessageTool({
cfg,
}: Parameters<
NonNullable<ChannelMessageActionAdapter["describeMessageTool"]>
>[0]): ChannelMessageToolDiscovery {
const discovery = resolveDiscordActionDiscovery(cfg);
if (!discovery) {
return {
actions: [],
capabilities: [],
schema: null,
};
}
const actions = new Set<ChannelMessageActionName>(["send"]);
if (discovery.isEnabled("polls")) {
actions.add("poll");
}
if (discovery.isEnabled("reactions")) {
actions.add("react");
actions.add("reactions");
actions.add("emoji-list");
}
if (discovery.isEnabled("messages")) {
actions.add("read");
actions.add("edit");
actions.add("delete");
}
if (discovery.isEnabled("pins")) {
actions.add("pin");
actions.add("unpin");
actions.add("list-pins");
}
if (discovery.isEnabled("permissions")) {
actions.add("permissions");
}
if (discovery.isEnabled("threads")) {
actions.add("thread-create");
actions.add("thread-list");
actions.add("thread-reply");
}
if (discovery.isEnabled("search")) {
actions.add("search");
}
if (discovery.isEnabled("stickers")) {
actions.add("sticker");
}
if (discovery.isEnabled("memberInfo")) {
actions.add("member-info");
}
if (discovery.isEnabled("roleInfo")) {
actions.add("role-info");
}
if (discovery.isEnabled("emojiUploads")) {
actions.add("emoji-upload");
}
if (discovery.isEnabled("stickerUploads")) {
actions.add("sticker-upload");
}
if (discovery.isEnabled("roles", false)) {
actions.add("role-add");
actions.add("role-remove");
}
if (discovery.isEnabled("channelInfo")) {
actions.add("channel-info");
actions.add("channel-list");
}
if (discovery.isEnabled("channels")) {
actions.add("channel-create");
actions.add("channel-edit");
actions.add("channel-delete");
actions.add("channel-move");
actions.add("category-create");
actions.add("category-edit");
actions.add("category-delete");
}
if (discovery.isEnabled("voiceStatus")) {
actions.add("voice-status");
}
if (discovery.isEnabled("events")) {
actions.add("event-list");
actions.add("event-create");
}
if (discovery.isEnabled("moderation", false)) {
actions.add("timeout");
actions.add("kick");
actions.add("ban");
}
if (discovery.isEnabled("presence", false)) {
actions.add("set-presence");
}
return {
actions: Array.from(actions),
capabilities: ["interactive", "components"],
schema: {
properties: {
components: createDiscordMessageToolComponentsSchema(),
},
},
};
}
export const discordMessageActions: ChannelMessageActionAdapter = {
listActions: ({ cfg }) => {
const discovery = resolveDiscordActionDiscovery(cfg);
if (!discovery) {
return [];
}
const actions = new Set<ChannelMessageActionName>(["send"]);
if (discovery.isEnabled("polls")) {
actions.add("poll");
}
if (discovery.isEnabled("reactions")) {
actions.add("react");
actions.add("reactions");
}
if (discovery.isEnabled("messages")) {
actions.add("read");
actions.add("edit");
actions.add("delete");
}
if (discovery.isEnabled("pins")) {
actions.add("pin");
actions.add("unpin");
actions.add("list-pins");
}
if (discovery.isEnabled("permissions")) {
actions.add("permissions");
}
if (discovery.isEnabled("threads")) {
actions.add("thread-create");
actions.add("thread-list");
actions.add("thread-reply");
}
if (discovery.isEnabled("search")) {
actions.add("search");
}
if (discovery.isEnabled("stickers")) {
actions.add("sticker");
}
if (discovery.isEnabled("memberInfo")) {
actions.add("member-info");
}
if (discovery.isEnabled("roleInfo")) {
actions.add("role-info");
}
if (discovery.isEnabled("reactions")) {
actions.add("emoji-list");
}
if (discovery.isEnabled("emojiUploads")) {
actions.add("emoji-upload");
}
if (discovery.isEnabled("stickerUploads")) {
actions.add("sticker-upload");
}
if (discovery.isEnabled("roles", false)) {
actions.add("role-add");
actions.add("role-remove");
}
if (discovery.isEnabled("channelInfo")) {
actions.add("channel-info");
actions.add("channel-list");
}
if (discovery.isEnabled("channels")) {
actions.add("channel-create");
actions.add("channel-edit");
actions.add("channel-delete");
actions.add("channel-move");
actions.add("category-create");
actions.add("category-edit");
actions.add("category-delete");
}
if (discovery.isEnabled("voiceStatus")) {
actions.add("voice-status");
}
if (discovery.isEnabled("events")) {
actions.add("event-list");
actions.add("event-create");
}
if (discovery.isEnabled("moderation", false)) {
actions.add("timeout");
actions.add("kick");
actions.add("ban");
}
if (discovery.isEnabled("presence", false)) {
actions.add("set-presence");
}
return Array.from(actions);
},
getCapabilities: ({ cfg }) =>
resolveDiscordActionDiscovery(cfg) ? (["interactive", "components"] as const) : [],
getToolSchema: ({ cfg }) =>
resolveDiscordActionDiscovery(cfg)
? {
properties: {
components: createDiscordMessageToolComponentsSchema(),
},
}
: null,
describeMessageTool: describeDiscordMessageTool,
extractToolSend: ({ args }) => {
const action = typeof args.action === "string" ? args.action.trim() : "";
if (action === "sendMessage") {

View File

@@ -77,6 +77,8 @@ function formatDiscordIntents(intents?: {
}
const discordMessageActions: ChannelMessageActionAdapter = {
describeMessageTool: (ctx) =>
getDiscordRuntime().channel.discord.messageActions?.describeMessageTool?.(ctx) ?? null,
listActions: (ctx) =>
getDiscordRuntime().channel.discord.messageActions?.listActions?.(ctx) ?? [],
getCapabilities: (ctx) =>