fix(discord): keep audio voice replies threaded#95978
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 25, 2026, 4:32 AM ET / 08:32 UTC. Summary PR surface: Source +4, Tests +25. Total +29 across 2 files. Reproducibility: yes. source-level: current main calls the stateful single-use reply supplier separately for each Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Next step before merge
Security Review detailsBest possible solution: Land this narrow Discord plugin fix after normal maintainer merge checks, preserving the existing single-use fanout contract for ordinary multi-send payloads. Do we have a high-confidence way to reproduce the issue? Yes, source-level: current main calls the stateful single-use reply supplier separately for each Is this the best way to solve the issue? Yes. Capturing the resolved reply target only inside the AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against c030b305a444. Label changesLabel justifications:
Evidence reviewedPR surface: Source +4, Tests +25. Total +29 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
dc87507 to
8a78fa6
Compare
|
Merged via squash.
|
* fix(discord): keep audio voice replies threaded * chore: retrigger CI after base recovery
* fix(discord): keep audio voice replies threaded * chore: retrigger CI after base recovery
What Problem This Solves
Fixes #95977.
Fixes an issue where Discord
audioAsVoicepayloads with text or additional media would only thread the first internal voice send whenreplyToModewas single-use. The follow-up text and media sends belong to the same logical voice reply, but they resolvedreplyToafter the implicit reply target had already been consumed.Why This Change Was Made
The Discord
audioAsVoicebranch now captures the resolved reply target once before sending the voice payload, then reuses that captured value for the voice send, the text follow-up, and additional media sends. The normal non-audioAsVoicehelper paths still resolve reply targets per send, so existing single-use behavior for ordinary multi-send payloads is unchanged.User Impact
Discord voice replies with accompanying text or extra media stay threaded to the source message instead of leaving follow-up sends unthreaded. Regular Discord payloads still only use an implicit single-use reply target on the first delivered message.
Evidence
audioAsVoiceregression expectation, the current source failed because the text follow-up receivedreplyTo: undefinedinstead of"reply-1".oc-audio-replyto-2026-06-23T03-28-44-084Z-1dde4ee6sent a real seed message, thendiscordOutbound.sendPayloaddelivered real voice, text, and image follow-up messages. Independent Discord API readback confirmed all three payload messages referenced the seed; a redacted local artifact contains no token, channel id, or raw message ids.node scripts/run-vitest.mjs extensions/discord/src/outbound-adapter.test.ts -t audioAsVoicenode scripts/run-vitest.mjs extensions/discord/src/outbound-adapter.test.tsnode scripts/run-oxlint.mjs extensions/discord/src/outbound-payload.ts extensions/discord/src/outbound-adapter.test.tsnode_modules/.bin/oxfmt --check --threads=1 extensions/discord/src/outbound-payload.ts extensions/discord/src/outbound-adapter.test.tsnode scripts/run-tsgo.mjs -p extensions/discord/tsconfig.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/discord-extension.tsbuildinfogit diff --checkReal behavior proof
Behavior or issue addressed:
Discord
audioAsVoicepayload sends use multiple internal Discord send calls for one logical response. With an implicit single-use reply target, resolvingreplyToseparately at each internal send caused the text follow-up and extra media send to lose the reply target after the voice send consumed it.Real environment tested:
Local OpenClaw checkout using the Discord outbound adapter test harness, the repository's Vitest wrapper, and a live sandbox Discord text channel. Unit tests inspect the production outbound option objects directly; the live run sends through
discordOutbound.sendPayloadand confirms Discord API message references after delivery.Exact steps or command run after this patch:
Observed result after fix:
The
audioAsVoiceregressions now assert the voice send, text follow-up, and extra media send all carryreplyTo: "reply-1"for both single-use modes (firstandbatched). The live Discord sandbox run confirmed the same shape after real delivery: voice, text, and image follow-up messages all referenced the seed message. The same file still covers ordinary non-audioAsVoicesingle-use behavior with["reply-1", undefined]for chunked approval payload fallbacks.What was not tested:
No non-sandbox Discord channel or production user workflow was used. The live proof was limited to a sandbox Discord text channel plus local automated API readback.
AI-assisted; contributor manually reviewed and is responsible for the change.