mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 22:54:33 +00:00
fix(discord): harden slash command routing
This commit is contained in:
@@ -11,6 +11,7 @@ import { GatewayCloseCodes, type GatewayPlugin } from "@buape/carbon/gateway";
|
||||
import { VoicePlugin } from "@buape/carbon/voice";
|
||||
import { Routes } from "discord-api-types/v10";
|
||||
import { resolveTextChunkLimit } from "../../auto-reply/chunk.js";
|
||||
import type { NativeCommandSpec } from "../../auto-reply/commands-registry.js";
|
||||
import { listNativeCommandSpecsForConfig } from "../../auto-reply/commands-registry.js";
|
||||
import type { HistoryEntry } from "../../auto-reply/reply/history.js";
|
||||
import { listSkillCommandsForAgents } from "../../auto-reply/skill-commands.js";
|
||||
@@ -37,6 +38,7 @@ import { danger, logVerbose, shouldLogVerbose, warn } from "../../globals.js";
|
||||
import { formatErrorMessage } from "../../infra/errors.js";
|
||||
import { createDiscordRetryRunner } from "../../infra/retry-policy.js";
|
||||
import { createSubsystemLogger } from "../../logging/subsystem.js";
|
||||
import { getPluginCommandSpecs } from "../../plugins/commands.js";
|
||||
import { createNonExitingRuntime, type RuntimeEnv } from "../../runtime.js";
|
||||
import { resolveDiscordAccount } from "../accounts.js";
|
||||
import { fetchDiscordApplicationId } from "../probe.js";
|
||||
@@ -141,6 +143,37 @@ function dedupeSkillCommandsForDiscord(
|
||||
return deduped;
|
||||
}
|
||||
|
||||
function appendPluginCommandSpecs(params: {
|
||||
commandSpecs: NativeCommandSpec[];
|
||||
runtime: RuntimeEnv;
|
||||
}): NativeCommandSpec[] {
|
||||
const merged = [...params.commandSpecs];
|
||||
const existingNames = new Set(
|
||||
merged.map((spec) => spec.name.trim().toLowerCase()).filter(Boolean),
|
||||
);
|
||||
for (const pluginCommand of getPluginCommandSpecs()) {
|
||||
const normalizedName = pluginCommand.name.trim().toLowerCase();
|
||||
if (!normalizedName) {
|
||||
continue;
|
||||
}
|
||||
if (existingNames.has(normalizedName)) {
|
||||
params.runtime.error?.(
|
||||
danger(
|
||||
`discord: plugin command "/${normalizedName}" duplicates an existing native command. Skipping.`,
|
||||
),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
existingNames.add(normalizedName);
|
||||
merged.push({
|
||||
name: pluginCommand.name,
|
||||
description: pluginCommand.description,
|
||||
acceptsArgs: pluginCommand.acceptsArgs,
|
||||
});
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
async function deployDiscordCommands(params: {
|
||||
client: Client;
|
||||
runtime: RuntimeEnv;
|
||||
@@ -317,10 +350,14 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
|
||||
let commandSpecs = nativeEnabled
|
||||
? listNativeCommandSpecsForConfig(cfg, { skillCommands, provider: "discord" })
|
||||
: [];
|
||||
if (nativeEnabled) {
|
||||
commandSpecs = appendPluginCommandSpecs({ commandSpecs, runtime });
|
||||
}
|
||||
const initialCommandCount = commandSpecs.length;
|
||||
if (nativeEnabled && nativeSkillsEnabled && commandSpecs.length > maxDiscordCommands) {
|
||||
skillCommands = [];
|
||||
commandSpecs = listNativeCommandSpecsForConfig(cfg, { skillCommands: [], provider: "discord" });
|
||||
commandSpecs = appendPluginCommandSpecs({ commandSpecs, runtime });
|
||||
runtime.log?.(
|
||||
warn(
|
||||
`discord: ${initialCommandCount} commands exceeds limit; removing per-skill commands and keeping /skill.`,
|
||||
|
||||
Reference in New Issue
Block a user