UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

412 lines (411 loc) 21.2 kB
import { r as buildChannelConfigSchema } from "./config-schema-CO2ikh7C.js"; import { r as DiscordConfigSchema } from "./bundled-channel-config-schema-DwZyvOaO.js"; import "./config-api-CO6ylNeg.js"; //#endregion //#region extensions/discord/src/config-schema.ts const DiscordChannelConfigSchema = buildChannelConfigSchema(DiscordConfigSchema, { uiHints: { "": { label: "Discord", help: "Discord channel provider configuration for bot auth, retry policy, streaming, thread bindings, and optional voice capabilities. Keep privileged intents and advanced features disabled unless needed." }, dmPolicy: { label: "Discord DM Policy", help: "Direct message access control (\"pairing\" recommended). \"open\" requires channels.discord.allowFrom=[\"*\"]." }, "dm.policy": { label: "Discord DM Policy", help: "Direct message access control (\"pairing\" recommended). \"open\" requires channels.discord.allowFrom=[\"*\"] (legacy: channels.discord.dm.allowFrom)." }, configWrites: { label: "Discord Config Writes", help: "Allow Discord to write config in response to channel events/commands (default: true)." }, mentionPatterns: { label: "Discord Mention Pattern Policy", help: "Scopes configured groupChat mentionPatterns to selected Discord channel IDs. Native Discord @mentions still trigger even when regex patterns are denied." }, "mentionPatterns.mode": { label: "Discord Mention Pattern Mode", help: "\"allow\" enables configured regex mention patterns unless denyIn matches; \"deny\" disables them unless allowIn matches." }, "mentionPatterns.allowIn": { label: "Discord Mention Pattern Allowlist", help: "Discord channel IDs where configured regex mention patterns are enabled when mode is deny." }, "mentionPatterns.denyIn": { label: "Discord Mention Pattern Denylist", help: "Discord channel IDs where configured regex mention patterns are disabled. Native @mentions still trigger." }, proxy: { label: "Discord Proxy URL", help: "Proxy URL for Discord gateway + API requests (app-id lookup and allowlist resolution). Set per account via channels.discord.accounts.<id>.proxy." }, "commands.native": { label: "Discord Native Commands", help: "Override native commands for Discord (bool or \"auto\")." }, "commands.nativeSkills": { label: "Discord Native Skill Commands", help: "Override native skill commands for Discord (bool or \"auto\")." }, streaming: { label: "Discord Streaming Mode", help: "Unified Discord stream preview mode: \"off\" | \"partial\" | \"block\" | \"progress\". \"progress\" keeps a single editable progress draft until final delivery. Legacy boolean/streamMode keys are auto-mapped." }, "streaming.mode": { label: "Discord Streaming Mode", help: "Canonical Discord preview mode: \"off\" | \"partial\" | \"block\" | \"progress\"." }, "streaming.chunkMode": { label: "Discord Chunk Mode", help: "Chunking mode for outbound Discord text delivery: \"length\" (default) or \"newline\"." }, "streaming.block.enabled": { label: "Discord Block Streaming Enabled", help: "Enable chunked block-style Discord preview delivery when channels.discord.streaming.mode=\"block\"." }, "streaming.block.coalesce": { label: "Discord Block Streaming Coalesce", help: "Merge streamed Discord block replies before final delivery." }, "streaming.preview.chunk.minChars": { label: "Discord Draft Chunk Min Chars", help: "Minimum chars before emitting a Discord stream preview update when channels.discord.streaming.mode=\"block\" (default: 200)." }, "streaming.preview.chunk.maxChars": { label: "Discord Draft Chunk Max Chars", help: "Target max size for a Discord stream preview chunk when channels.discord.streaming.mode=\"block\" (default: 800; clamped to channels.discord.textChunkLimit)." }, "streaming.preview.chunk.breakPreference": { label: "Discord Draft Chunk Break Preference", help: "Preferred breakpoints for Discord draft chunks (paragraph | newline | sentence). Default: paragraph." }, "streaming.preview.toolProgress": { label: "Discord Draft Tool Progress", help: "Show tool/progress activity in the live draft preview message (default: true). Set false to hide interim tool updates while the draft preview stays active." }, "streaming.preview.commandText": { label: "Discord Draft Command Text", help: "Command/exec detail in preview tool-progress lines: \"raw\" preserves released behavior; \"status\" shows only the tool label." }, "streaming.progress.label": { label: "Discord Progress Label", help: "Initial progress draft title. Use \"auto\" for built-in single-word labels, a custom string, or false to hide the title." }, "streaming.progress.labels": { label: "Discord Progress Label Pool", help: "Candidate labels for streaming.progress.label=\"auto\". Leave unset to use OpenClaw built-in progress labels." }, "streaming.progress.maxLines": { label: "Discord Progress Max Lines", help: "Maximum number of compact progress lines to keep below the draft label (default: 8)." }, "streaming.progress.maxLineChars": { label: "Discord Progress Max Line Chars", help: "Maximum characters per compact progress line before truncation (default: 120). Prose cuts at word boundaries; commands and paths keep useful suffixes." }, "streaming.progress.toolProgress": { label: "Discord Progress Tool Lines", help: "Show compact tool/progress lines in progress draft mode (default: true). Set false to keep only the label until final delivery." }, "streaming.progress.commentary": { label: "Discord Progress Commentary", help: "Show assistant commentary/preamble text in the temporary progress draft. Final answer delivery is unchanged." }, "streaming.progress.commandText": { label: "Discord Progress Command Text", help: "Command/exec detail in progress draft lines: \"raw\" preserves released behavior; \"status\" shows only the tool label." }, "retry.attempts": { label: "Discord Retry Attempts", help: "Max retry attempts for outbound Discord API calls (default: 3)." }, "retry.minDelayMs": { label: "Discord Retry Min Delay (ms)", help: "Minimum retry delay in ms for Discord outbound calls." }, "retry.maxDelayMs": { label: "Discord Retry Max Delay (ms)", help: "Maximum retry delay cap in ms for Discord outbound calls." }, "retry.jitter": { label: "Discord Retry Jitter", help: "Jitter factor (0-1) applied to Discord retry delays." }, maxLinesPerMessage: { label: "Discord Max Lines Per Message", help: "Soft max line count per Discord message (default: 17)." }, suppressEmbeds: { label: "Discord Suppress Link Embeds", help: "Suppress Discord-generated link embeds on outbound messages by default. Explicit embeds still send normally. Default: true." }, "thread.inheritParent": { label: "Discord Thread Parent Inheritance", help: "If true, Discord thread sessions inherit the parent channel transcript (default: false)." }, "eventQueue.listenerTimeout": { label: "Discord EventQueue Listener Timeout (ms)", help: "Canonical Discord listener timeout control in ms for gateway normalization/enqueue handlers. Default is 120000 in OpenClaw; set per account via channels.discord.accounts.<id>.eventQueue.listenerTimeout." }, "eventQueue.maxQueueSize": { label: "Discord EventQueue Max Queue Size", help: "Optional Discord EventQueue capacity override (max queued events before backpressure). Set per account via channels.discord.accounts.<id>.eventQueue.maxQueueSize." }, "eventQueue.maxConcurrency": { label: "Discord EventQueue Max Concurrency", help: "Optional Discord EventQueue concurrency override (max concurrent handler executions). Set per account via channels.discord.accounts.<id>.eventQueue.maxConcurrency." }, "threadBindings.enabled": { label: "Discord Thread Binding Enabled", help: "Enable Discord thread binding features (/focus, bound-thread routing/delivery, and thread-bound subagent sessions). Overrides session.threadBindings.enabled when set." }, "threadBindings.idleHours": { label: "Discord Thread Binding Idle Timeout (hours)", help: "Inactivity window in hours for Discord thread-bound sessions (/focus and spawned thread sessions). Set 0 to disable idle auto-unfocus (default: 24). Overrides session.threadBindings.idleHours when set." }, "threadBindings.maxAgeHours": { label: "Discord Thread Binding Max Age (hours)", help: "Optional hard max age in hours for Discord thread-bound sessions. Set 0 to disable hard cap (default: 0). Overrides session.threadBindings.maxAgeHours when set." }, "threadBindings.spawnSessions": { label: "Discord Thread-Bound Session Spawn", help: "Allow sessions_spawn(thread=true) and ACP thread spawns to auto-create and bind Discord threads (default: true). Set false to disable for this account/channel." }, "threadBindings.defaultSpawnContext": { label: "Discord Thread Spawn Context", help: "Default native subagent context for thread-bound spawns. \"fork\" starts from the requester transcript; \"isolated\" starts clean. Default: \"fork\"." }, "ui.components.accentColor": { label: "Discord Component Accent Color", help: "Accent color for Discord component containers (hex). Set per account via channels.discord.accounts.<id>.ui.components.accentColor." }, "agentComponents.ttlMs": { label: "Discord Component TTL (ms)", help: "How long sent Discord component callbacks remain registered. Default is 1800000 (30 minutes); maximum is 86400000 (24 hours)." }, "intents.presence": { label: "Discord Presence Intent", help: "Enable the Guild Presences privileged intent. Must also be enabled in the Discord Developer Portal. Allows tracking user activities (e.g. Spotify). Default: false." }, "intents.guildMembers": { label: "Discord Guild Members Intent", help: "Enable the Guild Members privileged intent. Must also be enabled in the Discord Developer Portal. Default: false." }, "intents.voiceStates": { label: "Discord Voice States Intent", help: "Enable the Guild Voice States intent. Defaults to the effective Discord voice setting; set true only for Discord voice channel conversations." }, gatewayInfoTimeoutMs: { label: "Discord Gateway Metadata Timeout (ms)", help: "Timeout for Discord /gateway/bot metadata lookup before falling back to the default gateway URL. Default is 30000; OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS can override when config is unset." }, gatewayReadyTimeoutMs: { label: "Discord Gateway READY Timeout (ms)", help: "Startup wait for the Discord gateway READY event before restarting the socket. Default is 15000; OPENCLAW_DISCORD_READY_TIMEOUT_MS can override when config is unset." }, gatewayRuntimeReadyTimeoutMs: { label: "Discord Gateway Runtime READY Timeout (ms)", help: "Runtime reconnect wait for the Discord gateway READY event before force-stopping the lifecycle. Default is 30000; OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS can override when config is unset." }, "voice.enabled": { label: "Discord Voice Enabled", help: "Enable Discord voice channel conversations. Text-only Discord configs leave voice off by default; set true to enable /vc commands and the Guild Voice States intent." }, "voice.model": { label: "Discord Voice Model", help: "Optional LLM model override for Discord voice channel responses and realtime agent consults (for example openai/gpt-5.5). Leave unset to inherit the routed agent model." }, "voice.mode": { label: "Discord Voice Mode", help: "Conversation mode: agent-proxy (default) uses realtime voice as the microphone/speaker for the routed OpenClaw agent, stt-tts uses batch speech-to-text plus TTS, and bidi lets the realtime provider converse directly with the OpenClaw consult tool." }, "voice.agentSession": { label: "Discord Voice Agent Session", help: "Controls which OpenClaw conversation receives voice turns. Leave unset for the voice channel session, or set mode=\"target\" with a Discord target such as channel:123 to make voice an extension of an existing text channel session." }, "voice.agentSession.target": { label: "Discord Voice Agent Session Target", help: "Discord target used when voice.agentSession.mode=\"target\", for example channel:123." }, "voice.followUsersEnabled": { label: "Discord Voice Follow Users Enabled", help: "Toggle Discord voice follow-users behavior without removing the saved voice.followUsers list. Defaults to true when followUsers is configured." }, "voice.followUsers": { label: "Discord Voice Follow Users", help: "Discord user IDs to follow into voice channels. The bot joins when a followed user joins or moves, and leaves when that user disconnects." }, "voice.realtime.provider": { label: "Discord Realtime Provider", help: "Realtime voice provider for agent-proxy or bidi Discord voice modes, such as openai." }, "voice.realtime.model": { label: "Discord Realtime Model", help: "Provider realtime session model, such as gpt-realtime-2. This is separate from voice.model, which remains the OpenClaw agent brain model." }, "voice.realtime.speakerVoice": { label: "Discord Realtime Speaker Voice", help: "Provider realtime output voice name, such as cedar." }, "voice.realtime.speakerVoiceId": { label: "Discord Realtime Speaker Voice ID", help: "Provider realtime output voice id." }, "voice.realtime.voice": { label: "Discord Realtime Voice", help: "Deprecated provider realtime output voice. Use voice.realtime.speakerVoice." }, "voice.realtime.toolPolicy": { label: "Discord Realtime Tool Policy", help: "Tool policy for the OpenClaw agent consult tool in realtime voice modes: safe-read-only, owner, or none. Default is owner for agent-proxy and safe-read-only for bidi." }, "voice.realtime.consultPolicy": { label: "Discord Realtime Consult Policy", help: "Use always to strongly prefer the OpenClaw agent brain for substantive realtime turns. agent-proxy defaults to always." }, "voice.realtime.requireWakeName": { label: "Discord Realtime Require Wake Name", help: "Require a configured wake name before OpenAI agent-proxy Discord realtime voice responds. If wakeNames is unset, the routed agent name is used, falling back to the agent id." }, "voice.realtime.wakeNames": { label: "Discord Realtime Wake Names", help: "One- or two-word activation names that allow OpenAI agent-proxy Discord realtime voice to respond when requireWakeName is enabled." }, "voice.realtime.bootstrapContextFiles": { label: "Discord Realtime Bootstrap Context Files", help: "Agent profile bootstrap files included in realtime provider instructions for direct voice identity/persona grounding. Defaults to IDENTITY.md, USER.md, and SOUL.md; set [] to disable." }, "voice.realtime.bargeIn": { label: "Discord Realtime Barge-In", help: "Allow Discord speaker-start events to interrupt active realtime playback. Set true to keep manual interruption when provider input-audio interruption is disabled for echo control." }, "voice.realtime.minBargeInAudioEndMs": { label: "Discord Realtime Minimum Barge-In Audio (ms)", help: "Minimum assistant playback duration before a Discord barge-in truncates realtime audio. Default: 250; set 0 for immediate interruption in low-echo rooms." }, "voice.realtime.providers": { label: "Discord Realtime Provider Settings", help: "Provider-specific realtime voice settings keyed by provider id.", advanced: true }, "voice.autoJoin": { label: "Discord Voice Auto-Join", help: "Voice channels to auto-join on startup (list of guildId/channelId entries)." }, "voice.allowedChannels": { label: "Discord Voice Allowed Channels", help: "Optional voice channel residency allowlist. When set, /vc join, auto-join, and bot voice-state moves are restricted to these guildId/channelId entries. Leave unset to allow any voice channel." }, "voice.daveEncryption": { label: "Discord Voice DAVE Encryption", help: "Toggle DAVE end-to-end encryption for Discord voice joins (default: true in @discordjs/voice; Discord may require this)." }, "voice.decryptionFailureTolerance": { label: "Discord Voice Decrypt Failure Tolerance", help: "Consecutive decrypt failures before DAVE attempts session recovery (passed to @discordjs/voice; default: 24)." }, "voice.connectTimeoutMs": { label: "Discord Voice Connect Timeout (ms)", help: "Initial @discordjs/voice Ready wait before a join is treated as failed. Default: 30000." }, "voice.reconnectGraceMs": { label: "Discord Voice Reconnect Grace (ms)", help: "Grace period for a disconnected Discord voice session to enter Signalling or Connecting before OpenClaw destroys it. Default: 15000." }, "voice.captureSilenceGraceMs": { label: "Discord Voice Capture Silence Grace (ms)", help: "Silence window after Discord reports a speaker ended before OpenClaw finalizes the audio segment for transcription. Default: 2000." }, "voice.tts": { label: "Discord Voice Text-to-Speech", help: "Optional TTS overrides for Discord voice playback (merged with messages.tts)." }, "pluralkit.enabled": { label: "Discord PluralKit Enabled", help: "Resolve PluralKit proxied messages and treat system members as distinct senders." }, "pluralkit.token": { label: "Discord PluralKit Token", help: "Optional PluralKit token for resolving private systems or members." }, activity: { label: "Discord Presence Activity", help: "Discord presence activity text (defaults to custom status)." }, status: { label: "Discord Presence Status", help: "Discord presence status (online, dnd, idle, invisible)." }, "autoPresence.enabled": { label: "Discord Auto Presence Enabled", help: "Enable automatic Discord bot presence updates based on runtime/model availability signals. When enabled: healthy=>online, degraded/unknown=>idle, exhausted/unavailable=>dnd." }, "autoPresence.intervalMs": { label: "Discord Auto Presence Check Interval (ms)", help: "How often to evaluate Discord auto-presence state in milliseconds (default: 30000)." }, "autoPresence.minUpdateIntervalMs": { label: "Discord Auto Presence Min Update Interval (ms)", help: "Minimum time between actual Discord presence update calls in milliseconds (default: 15000). Prevents status spam on noisy state changes." }, "autoPresence.healthyText": { label: "Discord Auto Presence Healthy Text", help: "Optional custom status text while runtime is healthy (online). If omitted, falls back to static channels.discord.activity when set." }, "autoPresence.degradedText": { label: "Discord Auto Presence Degraded Text", help: "Optional custom status text while runtime/model availability is degraded or unknown (idle)." }, "autoPresence.exhaustedText": { label: "Discord Auto Presence Exhausted Text", help: "Optional custom status text while runtime detects exhausted/unavailable model quota (dnd). Supports {reason} template placeholder." }, activityType: { label: "Discord Presence Activity Type", help: "Discord presence activity type (0=Playing,1=Streaming,2=Listening,3=Watching,4=Custom,5=Competing)." }, activityUrl: { label: "Discord Presence Activity URL", help: "Discord presence streaming URL (required for activityType=1)." }, allowBots: { label: "Discord Allow Bot Messages", help: "Allow bot-authored messages to trigger Discord replies (default: false). Set \"mentions\" to only accept bot messages that mention the bot." }, botLoopProtection: { label: "Discord Bot Loop Protection", help: "Sliding-window guard for bot-to-bot Discord loops. Default is enabled whenever allowBots lets bot-authored messages reach dispatch." }, "botLoopProtection.enabled": { label: "Discord Bot Loop Protection Enabled", help: "Enable the bot-pair loop guard. Defaults to true when allowBots is true or \"mentions\", and false when bot messages are ignored." }, "botLoopProtection.maxEventsPerWindow": { label: "Discord Bot Pair Events Per Window", help: "Maximum messages a single Discord bot pair may exchange in the configured window before suppression starts. Default: 20." }, "botLoopProtection.windowSeconds": { label: "Discord Bot Loop Window Seconds", help: "Sliding window length in seconds for Discord bot-pair loop budgets. Default: 60." }, "botLoopProtection.cooldownSeconds": { label: "Discord Bot Loop Cooldown Seconds", help: "Seconds to suppress a Discord bot pair after it exceeds the loop budget. Default: 60." }, mentionAliases: { label: "Discord Mention Aliases", help: "Map outbound @handle text to stable Discord user IDs before sending. Set per account via channels.discord.accounts.<id>.mentionAliases." }, token: { label: "Discord Bot Token", help: "Discord bot token used for gateway and REST API authentication for this provider account. Keep this secret out of committed config and rotate immediately after any leak.", sensitive: true }, applicationId: { label: "Discord Application ID", help: "Optional Discord application/client ID. Set this when hosted environments cannot reach Discord's application lookup endpoint during startup." } } }); //#endregion export { DiscordChannelConfigSchema as t };