feat(discord): add configurable ephemeral option for slash commands
This commit is contained in:
@@ -534,6 +534,10 @@ Use `bindings[].match.roles` to route Discord guild members to different agents
|
||||
|
||||
See [Slash commands](/tools/slash-commands) for command catalog and behavior.
|
||||
|
||||
Default slash command settings:
|
||||
|
||||
- `ephemeral: true`
|
||||
|
||||
## Feature details
|
||||
|
||||
<AccordionGroup>
|
||||
@@ -969,7 +973,7 @@ High-signal Discord fields:
|
||||
|
||||
- startup/auth: `enabled`, `token`, `accounts.*`, `allowBots`
|
||||
- policy: `groupPolicy`, `dm.*`, `guilds.*`, `guilds.*.channels.*`
|
||||
- command: `commands.native`, `commands.useAccessGroups`, `configWrites`
|
||||
- command: `commands.native`, `commands.useAccessGroups`, `configWrites`, `slashCommand.*`
|
||||
- reply/history: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit`
|
||||
- delivery: `textChunkLimit`, `chunkMode`, `maxLinesPerMessage`
|
||||
- streaming: `streamMode`, `draftChunk`, `blockStreaming`, `blockStreamingCoalesce`
|
||||
|
||||
@@ -142,6 +142,11 @@ export type DiscordUiConfig = {
|
||||
components?: DiscordUiComponentsConfig;
|
||||
};
|
||||
|
||||
export type DiscordSlashCommandConfig = {
|
||||
/** Reply ephemerally (default: true). */
|
||||
ephemeral?: boolean;
|
||||
};
|
||||
|
||||
export type DiscordAccountConfig = {
|
||||
/** Optional display name for this account (used in CLI/UI lists). */
|
||||
name?: string;
|
||||
@@ -226,6 +231,8 @@ export type DiscordAccountConfig = {
|
||||
agentComponents?: DiscordAgentComponentsConfig;
|
||||
/** Discord UI customization (components, modals, etc.). */
|
||||
ui?: DiscordUiConfig;
|
||||
/** Slash command configuration. */
|
||||
slashCommand?: DiscordSlashCommandConfig;
|
||||
/** Privileged Gateway Intents (must also be enabled in Discord Developer Portal). */
|
||||
intents?: DiscordIntentsConfig;
|
||||
/** Voice channel conversation settings. */
|
||||
|
||||
@@ -357,6 +357,12 @@ export const DiscordAccountSchema = z
|
||||
.strict()
|
||||
.optional(),
|
||||
ui: DiscordUiSchema,
|
||||
slashCommand: z
|
||||
.object({
|
||||
ephemeral: z.boolean().optional(),
|
||||
})
|
||||
.strict()
|
||||
.optional(),
|
||||
intents: z
|
||||
.object({
|
||||
presence: z.boolean().optional(),
|
||||
|
||||
24
src/discord/monitor/commands.test.ts
Normal file
24
src/discord/monitor/commands.test.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { resolveDiscordSlashCommandConfig } from "./commands.js";
|
||||
|
||||
describe("resolveDiscordSlashCommandConfig", () => {
|
||||
it("defaults ephemeral to true when undefined", () => {
|
||||
const result = resolveDiscordSlashCommandConfig(undefined);
|
||||
expect(result.ephemeral).toBe(true);
|
||||
});
|
||||
|
||||
it("defaults ephemeral to true when not explicitly false", () => {
|
||||
const result = resolveDiscordSlashCommandConfig({});
|
||||
expect(result.ephemeral).toBe(true);
|
||||
});
|
||||
|
||||
it("sets ephemeral to false when explicitly false", () => {
|
||||
const result = resolveDiscordSlashCommandConfig({ ephemeral: false });
|
||||
expect(result.ephemeral).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps ephemeral true when explicitly true", () => {
|
||||
const result = resolveDiscordSlashCommandConfig({ ephemeral: true });
|
||||
expect(result.ephemeral).toBe(true);
|
||||
});
|
||||
});
|
||||
9
src/discord/monitor/commands.ts
Normal file
9
src/discord/monitor/commands.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { DiscordSlashCommandConfig } from "../../config/types.discord.js";
|
||||
|
||||
export function resolveDiscordSlashCommandConfig(
|
||||
raw?: DiscordSlashCommandConfig,
|
||||
): Required<DiscordSlashCommandConfig> {
|
||||
return {
|
||||
ephemeral: raw?.ephemeral !== false,
|
||||
};
|
||||
}
|
||||
@@ -54,6 +54,7 @@ import {
|
||||
createDiscordComponentStringSelect,
|
||||
createDiscordComponentUserSelect,
|
||||
} from "./agent-components.js";
|
||||
import { resolveDiscordSlashCommandConfig } from "./commands.js";
|
||||
import { createExecApprovalButton, DiscordExecApprovalHandler } from "./exec-approvals.js";
|
||||
import { createDiscordGatewayPlugin } from "./gateway-plugin.js";
|
||||
import { registerGateway, unregisterGateway } from "./gateway-registry.js";
|
||||
@@ -246,8 +247,9 @@ export async function monitorDiscordProvider(opts: MonitorDiscordOpts = {}) {
|
||||
globalSetting: cfg.commands?.native,
|
||||
});
|
||||
const useAccessGroups = cfg.commands?.useAccessGroups !== false;
|
||||
const slashCommand = resolveDiscordSlashCommandConfig(discordCfg.slashCommand);
|
||||
const sessionPrefix = "discord:slash";
|
||||
const ephemeralDefault = true;
|
||||
const ephemeralDefault = slashCommand.ephemeral;
|
||||
const voiceEnabled = discordCfg.voice?.enabled !== false;
|
||||
|
||||
if (token) {
|
||||
|
||||
Reference in New Issue
Block a user