import { Client, GatewayIntentBits, Partials } from "discord.js"; import type { PlatformAdapter, SurfaceCapabilities, IngressSink, InteractionEvent, RunRenderer, ReplyTarget as BotReplyTarget, ConversationStore, MessageRef, ProviderActor, UserQuery, CommandSpec, NativePayload } from "@copilotkit/channels-core"; import type { ChannelNode, ThreadMessage, EmojiValue, EphemeralResult } from "@copilotkit/channels-ui"; import type { RestLike } from "./commands.js"; export interface DiscordAdapterOptions { botToken: string; appId: string; /** When set, slash commands register to this guild instantly (dev); else global. */ guildId?: string; interruptEventNames?: ReadonlySet; } /** * Default Gateway intents for the bot. * * - `Guilds`, `GuildMessages`, `MessageContent`, `DirectMessages` — message ingress. * - `GuildMembers` — privileged; backs `lookup_discord_user` / `thread.lookupUser`. * Must be toggled on in the Discord Developer Portal (Bot → Privileged Gateway Intents). * - `GuildMessageReactions` — non-privileged; no portal toggle needed. * Required to receive reaction add/remove events in guild channels. * - `DirectMessageReactions` — non-privileged; required to receive reaction * add/remove events in DMs. Distinct from `GuildMessageReactions` in discord.js v14. */ export declare const DISCORD_DEFAULT_INTENTS: readonly [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.DirectMessages, GatewayIntentBits.GuildMembers, GatewayIntentBits.GuildMessageReactions, GatewayIntentBits.DirectMessageReactions]; /** * Default partials for the bot. * * - `Channel` — needed to receive DMs. * - `Message` + `Reaction` — required to receive reactions on uncached messages. * Discord only delivers partial reaction events when the reacted-to message is not * in the client's cache; without these partials those events are silently dropped. */ export declare const DISCORD_DEFAULT_PARTIALS: readonly [Partials.Channel, Partials.Message, Partials.Reaction]; export declare class DiscordAdapter implements PlatformAdapter { private readonly opts; readonly platform = "discord"; readonly capabilities: SurfaceCapabilities; readonly ackDeadlineMs = 3000; private readonly client; private readonly rest; private readonly store; private botUserId; private isReady; private pendingCommands; private readonly userCache; /** * Tracks live component interactions so a handler can open a modal (which * must be the interaction's INITIAL response, within ~3s) before the adapter * auto-defers. Constructed in `start()`. Used by `openModal` (Task D4). */ private pending; /** * Tracks live slash-command interactions (a command's initial response is a * reply, not a component update, so it needs its own registry). `openModal` * consults this too, so a command handler can `showModal` before the adapter * auto-defers. Constructed in `start()`. */ private commandPending; constructor(opts: DiscordAdapterOptions, injected?: { client?: Client; rest?: RestLike; }); registerCommands(commands: readonly CommandSpec[]): void; /** * Publish the registered commands. Guards against an empty list: an empty * `setMyCommands`/`PUT` CLEARS all of the bot's commands, so a race where * `ready` fires before commands are stashed must not wipe them. */ private publishCommands; start(sink: IngressSink): Promise; stop(): Promise; render(ir: ChannelNode[]): import("discord.js").ContainerBuilder; post(target: BotReplyTarget, ir: ChannelNode[]): Promise; update(ref: MessageRef, ir: ChannelNode[]): Promise; stream(target: BotReplyTarget, chunks: AsyncIterable): Promise; delete(ref: MessageRef): Promise; createRunRenderer(target: BotReplyTarget): RunRenderer; decodeInteraction(raw: unknown): InteractionEvent | undefined; lookupUser(q: UserQuery): Promise; get conversationStore(): ConversationStore; getMessages(target: BotReplyTarget): Promise; postFile(target: BotReplyTarget, args: { bytes: Uint8Array; filename: string; title?: string; altText?: string; }): Promise<{ ok: boolean; fileId?: string; error?: string; }>; addReaction(target: BotReplyTarget, messageRef: MessageRef, emoji: EmojiValue): Promise<{ ok: boolean; error?: string; }>; removeReaction(target: BotReplyTarget, messageRef: MessageRef, emoji: EmojiValue): Promise<{ ok: boolean; error?: string; }>; postEphemeral(_target: BotReplyTarget, user: ProviderActor | string, ir: ChannelNode[], opts: { fallbackToDM: boolean; }): Promise; renderModal(ir: ChannelNode[]): NativePayload; openModal(_target: BotReplyTarget, triggerId: string, ir: ChannelNode[]): Promise<{ ok: boolean; error?: string; }>; resolveUser(userId: string): Promise; private identityContext; private channelIdOf; private fetchSendable; /** * Fetch the channel's recent messages OLDEST→NEWEST, normalized for the * conversation store's history reconstruction. Best-effort: on any fetch * error returns [] (bot-slack's fetchHistory does the same). */ private fetchHistory; } export declare function discord(opts: DiscordAdapterOptions): DiscordAdapter; //# sourceMappingURL=adapter.d.ts.map