Commit Graph

358 Commits

Author SHA1 Message Date
Peter Steinberger
54a242eaad perf(test): gate monitor runtime logs during vitest 2026-02-14 01:14:56 +00:00
Peter Steinberger
d5e25e0ad8 refactor: centralize dispatcher lifecycle ownership 2026-02-14 00:41:37 +01:00
Peter Steinberger
6442512954 perf: reduce hotspot test startup and timeout costs 2026-02-13 20:03:01 +00:00
Peter Steinberger
f02247b6c5 fix(ci): fix discord proxy websocket binding and bluebubbles timeout status 2026-02-13 19:35:55 +00:00
Shadow
4b3c87b82d fix: finalize discord presence config (#10855) (thanks @h0tp-ftw) 2026-02-13 13:34:19 -06:00
Shadow
6acea69b20 Discord: refine presence config defaults (#10855) (thanks @h0tp-ftw) 2026-02-13 13:34:19 -06:00
h0tp
5d8c6ef91c feat(discord): add configurable presence (activity/status/type)
- Adds `activity`, `status`, `activityType`, and `activityUrl` to Discord provider config schema.
- Implements a `ReadyListener` in `DiscordProvider` to apply these settings on connection.
- Solves the issue where `@buape/carbon` ignores initial presence options in constructor.
- Validated manually and via existing test suite.
2026-02-13 13:34:19 -06:00
Shadow
5645f227f6 Discord: add gateway proxy docs and tests (#10400) (thanks @winter-loo) 2026-02-13 13:26:51 -06:00
ludd50155
e55431bf84 fix(discord): restore gateway reconnect maxAttempts to 50 2026-02-13 13:26:51 -06:00
ludd50155
5f0debdfb2 Fix: check cleanups 2026-02-13 13:26:51 -06:00
ludd50155
0cb69b0f28 Discord: add gateway proxy support
Conflicts:
	package.json
	pnpm-lock.yaml
	src/config/schema.ts
	src/discord/monitor/provider.ts
2026-02-13 13:26:51 -06:00
Mariano
7f0489e473 Security/Browser: constrain trace and download output paths to OpenClaw temp roots (#15652)
* Browser/Security: constrain trace and download output paths to temp roots

* Changelog: remove advisory ID from pre-public security note

* Browser/Security: constrain trace and download output paths to temp roots

* Changelog: remove advisory ID from pre-public security note

* test(bluebubbles): align timeout status expectation to 408

* test(discord): remove unused race-condition counter in threading test

* test(bluebubbles): align timeout status expectation to 408
2026-02-13 19:24:33 +00:00
Shadow
71939523a0 fix: normalize Discord autoThread reply target (#8302) (thanks @gavinbmoore) 2026-02-13 13:04:55 -06:00
Claw
e65b649993 fix(discord): ensure autoThread replies route to existing threads
Fixes #8278

When autoThread is enabled and a thread already exists (user continues
conversation in thread), replies were sometimes routing to the root
channel instead of the thread. This happened because the reply delivery
plan only explicitly set the thread target when a NEW thread was created
(createdThreadId), but not when the message was in an existing thread.

The fix adds a fallback case: when threadChannel is set (we're in an
existing thread) but no new thread was created, explicitly route to
the thread's channel ID. This ensures all thread replies go to the
correct destination.
2026-02-13 13:04:55 -06:00
Ramin Shirali Hossein Zade
1af0edf7ff fix: ensure exec approval is registered before returning (#2402) (#3357)
* feat(gateway): add register and awaitDecision methods to ExecApprovalManager

Separates registration (synchronous) from waiting (async) to allow callers
to confirm registration before the decision is made. Adds grace period for
resolved entries to prevent race conditions.

* feat(gateway): add two-phase response and waitDecision handler for exec approvals

Send immediate 'accepted' response after registration so callers can confirm
the approval ID is valid. Add exec.approval.waitDecision endpoint to wait for
decision on already-registered approvals.

* fix(exec): await approval registration before returning approval-pending

Ensures the approval ID is registered in the gateway before the tool returns.
Uses exec.approval.request with expectFinal:false for registration, then
fire-and-forget exec.approval.waitDecision for the decision phase.

Fixes #2402

* test(gateway): update exec-approval test for two-phase response

Add assertion for immediate 'accepted' response before final decision.

* test(exec): update approval-id test mocks for new two-phase flow

Mock both exec.approval.request (registration) and exec.approval.waitDecision
(decision) calls to match the new internal implementation.

* fix(lint): add cause to errors, use generics instead of type assertions

* fix(exec-approval): guard register() against duplicate IDs

* fix: remove unused timeoutMs param, guard register() against duplicates

* fix(exec-approval): throw on duplicate ID, capture entry in closure

* fix: return error on timeout, remove stale test mock branch

* fix: wrap register() in try/catch, make timeout handling consistent

* fix: update snapshot on timeout, make two-phase response opt-in

* fix: extend grace period to 15s, return 'expired' status

* fix: prevent double-resolve after timeout

* fix: make register() idempotent, capture snapshot before await

* fix(gateway): complete two-phase exec approval wiring

* fix: finalize exec approval race fix (openclaw#3357) thanks @ramin-shirali

* fix(protocol): regenerate exec approval request models (openclaw#3357) thanks @ramin-shirali

* fix(test): remove unused callCount in discord threading test

---------

Co-authored-by: rshirali <rshirali@rshirali-haga.local>
Co-authored-by: rshirali <rshirali@rshirali-haga-1.home>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-02-13 19:57:02 +01:00
Shadow
c87e481ec9 Discord: fix voice duration error handling 2026-02-13 12:44:14 -06:00
Shadow
1c9c01ff49 Discord: refine voice message handling 2026-02-13 12:44:14 -06:00
nyanjou
76ab377a19 style: use bit shift operators for Discord message flags 2026-02-13 12:44:14 -06:00
nyanjou
b4359c84f7 feat(discord): add silent support for voice messages
- Add silent flag to sendDiscordVoiceMessage
- Combines VOICE_MESSAGE (8192) + SUPPRESS_NOTIFICATIONS (4096) flags
- Pass silent through VoiceMessageOpts and action handlers
2026-02-13 12:44:14 -06:00
nyanjou
77df8b1104 feat(discord): add silent message support (SUPPRESS_NOTIFICATIONS flag)
- Add silent option to message tool for Discord
- Passes SUPPRESS_NOTIFICATIONS flag (4096) to Discord API
- Threads silent param through entire outbound chain:
  - message-action-runner.ts
  - outbound-send-service.ts
  - message.ts
  - deliver.ts
  - discord outbound adapter
  - send.outbound.ts
  - send.shared.ts

Usage: message tool with silent=true suppresses push/desktop notifications
2026-02-13 12:44:14 -06:00
nyanjou
b9da2c4679 fix: address code review feedback
- Remove unused ffmpeg astats command from generateWaveform()
- Use crypto.randomUUID() for temp file names to prevent collision
- Wrap upload URL request in retry runner for consistency
- Add validation: reject content with asVoice, require local file path
- Add clarifying comments for CDN upload behavior
2026-02-13 12:44:14 -06:00
nyanjou
36525a974e fix(discord): use fetch with proper headers for voice message upload
The @buape/carbon RequestClient wasn't setting Content-Type: application/json
for the attachments endpoint request. Use native fetch with explicit headers
for the upload URL request.

Also pass token through to sendDiscordVoiceMessage for authorization.
2026-02-13 12:44:14 -06:00
nyanjou
a09e4fac3f feat(discord): add voice message support
Adds support for sending Discord voice messages via the message tool
with asVoice: true parameter.

Voice messages require:
- OGG/Opus format (auto-converted if needed via ffmpeg)
- Waveform data (generated from audio samples)
- Duration in seconds
- Message flag 8192 (IS_VOICE_MESSAGE)

Implementation:
- New voice-message.ts with audio processing utilities
- getAudioDuration() using ffprobe
- generateWaveform() samples audio and creates base64 waveform
- ensureOggOpus() converts audio to required format
- sendDiscordVoiceMessage() handles 3-step Discord upload process

Usage:
message(action='send', channel='discord', target='...',
        path='/path/to/audio.mp3', asVoice=true)

Note: Voice messages cannot include text content (Discord limitation)
2026-02-13 12:44:14 -06:00
Hunter
f7e2b8ff5f fix(discord): autoThread race condition when multiple agents mentioned
When multiple agents with autoThread:true are @mentioned in the same
message, only the first agent successfully creates a thread. Subsequent
agents fail because Discord only allows one thread per message.

Previously, the failure was silently caught and the agent would fall
back to replying in the parent channel.

Now, when thread creation fails, the code re-fetches the message and
checks for an existing thread (created by another agent). If found,
the agent replies in that thread instead of falling back.

Fixes #7508
2026-02-13 12:39:11 -06:00
Clawdbot
42bfcd9c30 fix(discord): handle missing guild/channel data in link resolution
Add null checks for guild.id and guild.name when resolving Discord
entities. This prevents TypeError when processing invite links for
servers/channels the bot doesn't have cached.

Fixes #6606
2026-02-13 12:35:18 -06:00
headswim
f4e295a63b Discord: fix bare guild ID misrouted as channel ID in parser
The channel allowlist parser matches bare numeric strings as channel IDs
before checking for guild IDs, causing guild snowflakes to hit Discord's
/channels/ endpoint (404). Prefix guild-only entries with 'guild:' so the
parser routes them to the correct guild resolution path.

Fixes both the monitor provider and onboarding wizard call sites.
Adds regression tests.
2026-02-13 11:03:10 -06:00
Shadow
5325d2ca51 Discord: gate guild prefix to numeric keys 2026-02-13 10:57:29 -06:00
Peter Steinberger
9131b22a28 test: migrate suites to e2e coverage layout 2026-02-13 14:28:22 +00:00
Shadow
34c304727b Discord: honor Administrator in permission checks 2026-02-12 19:53:22 -06:00
Shadow
22fe30c1df fix: add discord role allowlists (#10650) (thanks @Minidoracat) 2026-02-12 19:52:24 -06:00
Minidoracat
e084f07420 fix: add missing role-based type definitions for RBAC routing 2026-02-12 19:52:24 -06:00
Minidoracat
ad508c8c89 fix: use member.roles as string[] per Discord API types 2026-02-12 19:52:24 -06:00
Minidoracat
334a291fb7 Discord: pass member role IDs to agent route resolution 2026-02-12 19:52:24 -06:00
Minidoracat
4c0ce46ac3 Discord: implement role allowlist with OR logic in preflight 2026-02-12 19:52:24 -06:00
CHISEN Kaoru
e25ae55879 fix(discord): replyToMode first behaviour 2026-02-12 18:50:36 -06:00
CHISEN Kaoru
4b3c9c9c5a fix(discord): respect replyToMode in thread channel 2026-02-12 18:50:36 -06:00
Shadow
fb8e6156ec fix: handle discord dm reaction allowlist 2026-02-12 16:47:39 -06:00
Marcus Castro
f8c7ae9b5e fix: use canonical 'direct' instead of 'dm' for DM peer kind (fixes TS2322) 2026-02-12 16:47:39 -06:00
Marcus Castro
ea3fb9570c fix: use proper LoadedConfig type in test mock 2026-02-12 16:47:39 -06:00
Marcus Castro
888f7dbbd8 fix: process Discord DM reactions instead of silently dropping them 2026-02-12 16:47:39 -06:00
Shadow
61d57be4c2 Discord: preserve media caption whitespace 2026-02-12 16:40:08 -06:00
Web Vijayi
4d0443391c fix: use iterator.done check for LRU eviction
Fixes edge case where empty string key would stop eviction early
2026-02-12 16:31:36 -06:00
Web Vijayi
5882cf2f5d fix(discord): add TTL and LRU eviction to thread starter cache
Fixes #5260

The DISCORD_THREAD_STARTER_CACHE Map was growing unbounded during
long-running gateway sessions, causing memory exhaustion.

This fix adds:
- 5-minute TTL expiry (thread starters rarely change)
- Max 500 entries with LRU eviction
- Same caching pattern used by Slack's thread resolver

The implementation mirrors src/slack/monitor/thread-resolution.ts
which already handles this correctly.
2026-02-12 16:31:36 -06:00
Shadow
149db5b2c2 Discord: handle thread edit params 2026-02-12 16:31:06 -06:00
Jake
a2ddcdadeb fix: fix: transcribe audio before mention check in groups with requireMention (openclaw#9973) thanks @mcinteerj
Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check
- pnpm test

Co-authored-by: mcinteerj <3613653+mcinteerj@users.noreply.github.com>
2026-02-12 09:58:01 -06:00
Claude Code
a67752e6be fix(discord): use partial mock for @buape/carbon in slash test
Replace the full manual mock with importOriginal spread so new SDK
exports are available automatically. Only ChannelType, MessageType,
and Client are overridden — the rest come from the real module.

Prevents CI breakage when @buape/carbon adds exports (e.g. the
recent StringSelectMenu failure that blocked unrelated PRs).

Closes #13244
2026-02-11 13:10:37 -06:00
Shadow
e95f41b5df Discord: honor explicit thread type 2026-02-11 11:23:19 -06:00
Rain
9e92fc8fa1 fix(discord): default standalone threads to public type (#14147)
When creating a Discord thread without a messageId (standalone thread),
the Discord API defaults to type 12 (private). Most users expect public.

- Default standalone non-forum threads to ChannelType.PublicThread (11)
- Add optional type field to DiscordThreadCreate for explicit control

Closes #14147
2026-02-11 11:23:19 -06:00
Rain
42f7538320 fix(discord): default standalone threads to public type (#14147)
When creating a Discord thread without a messageId, the API defaults
to type 12 (private thread) which is unexpected. This adds an explicit
type: PublicThread (11) for standalone thread creation in non-forum
channels, matching user expectations.

Closes #14147
2026-02-11 11:23:19 -06:00
Vignesh
ef4a0e92b7 fix(memory/qmd): scope query to managed collections (#11645) 2026-02-09 23:35:27 -08:00