Discord: add component v2 UI tool support (#17419)

This commit is contained in:
Shadow
2026-02-15 21:19:25 -06:00
committed by GitHub
parent b4a9eacd76
commit a61c2dc4bd
15 changed files with 2893 additions and 43 deletions

View File

@@ -1,6 +1,7 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core";
import type { DiscordActionConfig } from "../../config/config.js";
import type { DiscordSendComponents, DiscordSendEmbeds } from "../../discord/send.shared.js";
import { readDiscordComponentSpec } from "../../discord/components.js";
import {
createThreadDiscord,
deleteMessageDiscord,
@@ -16,6 +17,7 @@ import {
removeOwnReactionsDiscord,
removeReactionDiscord,
searchMessagesDiscord,
sendDiscordComponentMessage,
sendMessageDiscord,
sendPollDiscord,
sendStickerDiscord,
@@ -233,24 +235,54 @@ export async function handleDiscordMessagingAction(
const to = readStringParam(params, "to", { required: true });
const asVoice = params.asVoice === true;
const silent = params.silent === true;
const rawComponents = params.components;
const componentSpec =
rawComponents && typeof rawComponents === "object" && !Array.isArray(rawComponents)
? readDiscordComponentSpec(rawComponents)
: null;
const components: DiscordSendComponents | undefined =
Array.isArray(rawComponents) || typeof rawComponents === "function"
? (rawComponents as DiscordSendComponents)
: undefined;
const content = readStringParam(params, "content", {
required: !asVoice,
required: !asVoice && !componentSpec && !components,
allowEmpty: true,
});
const mediaUrl =
readStringParam(params, "mediaUrl", { trim: false }) ??
readStringParam(params, "path", { trim: false }) ??
readStringParam(params, "filePath", { trim: false });
const filename = readStringParam(params, "filename");
const replyTo = readStringParam(params, "replyTo");
const rawComponents = params.components;
const components: DiscordSendComponents | undefined =
Array.isArray(rawComponents) || typeof rawComponents === "function"
? (rawComponents as DiscordSendComponents)
: undefined;
const rawEmbeds = params.embeds;
const embeds: DiscordSendEmbeds | undefined = Array.isArray(rawEmbeds)
? (rawEmbeds as DiscordSendEmbeds)
: undefined;
const sessionKey = readStringParam(params, "__sessionKey");
const agentId = readStringParam(params, "__agentId");
if (componentSpec) {
if (asVoice) {
throw new Error("Discord components cannot be sent as voice messages.");
}
if (embeds?.length) {
throw new Error("Discord components cannot include embeds.");
}
const normalizedContent = content?.trim() ? content : undefined;
const payload = componentSpec.text
? componentSpec
: { ...componentSpec, text: normalizedContent };
const result = await sendDiscordComponentMessage(to, payload, {
...(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 });
}
// Handle voice message sending
if (asVoice) {