diff --git a/extensions/discord/npm-shrinkwrap.json b/extensions/discord/npm-shrinkwrap.json index d02e2c61c10..398411f50df 100644 --- a/extensions/discord/npm-shrinkwrap.json +++ b/extensions/discord/npm-shrinkwrap.json @@ -11,7 +11,7 @@ "@discordjs/voice": "0.19.2", "discord-api-types": "0.38.48", "https-proxy-agent": "9.0.0", - "libopus-wasm": "0.0.1", + "libopus-wasm": "0.1.0", "prism-media": "1.3.5", "typebox": "1.1.38", "undici": "8.3.0", @@ -424,9 +424,9 @@ } }, "node_modules/libopus-wasm": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/libopus-wasm/-/libopus-wasm-0.0.1.tgz", - "integrity": "sha512-w//dxORfJfLl4quaA5nEA0xZlbbtS/Gba+NrZyCDPmAQh2THX4KI6aI600f+jpxf6v3p9ApGCx0/DCCe4Xftug==", + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/libopus-wasm/-/libopus-wasm-0.1.0.tgz", + "integrity": "sha512-/aurGcAVgy0GcBEUzFaX9pm9qv7zYcy8W5hBXFiK+cyqOXAX4lOS6rlFogkY9CcSIajhjnuXyixsbmziSHCDMQ==", "license": "MIT", "engines": { "node": ">=20" diff --git a/extensions/discord/package.json b/extensions/discord/package.json index 1e767127b9f..b1d0493c8fe 100644 --- a/extensions/discord/package.json +++ b/extensions/discord/package.json @@ -11,7 +11,7 @@ "@discordjs/voice": "0.19.2", "discord-api-types": "0.38.48", "https-proxy-agent": "9.0.0", - "libopus-wasm": "0.0.1", + "libopus-wasm": "0.1.0", "prism-media": "1.3.5", "typebox": "1.1.38", "undici": "8.3.0", diff --git a/extensions/discord/src/voice/receive-recovery.test.ts b/extensions/discord/src/voice/receive-recovery.test.ts index d052269c530..ad11d4371c1 100644 --- a/extensions/discord/src/voice/receive-recovery.test.ts +++ b/extensions/discord/src/voice/receive-recovery.test.ts @@ -29,6 +29,15 @@ describe("voice receive recovery", () => { }); }); + it("treats premature stream close as an expected receive end", () => { + expect(analyzeVoiceReceiveError(new Error("Premature close"))).toEqual({ + message: "Premature close", + isAbortLike: true, + shouldAttemptPassthrough: false, + countsAsDecryptFailure: false, + }); + }); + it("gates recovery after repeated decrypt failures in the same window", () => { const state = createVoiceReceiveRecoveryState(); diff --git a/extensions/discord/src/voice/receive-recovery.ts b/extensions/discord/src/voice/receive-recovery.ts index 2379c02e761..87d45c3dc3b 100644 --- a/extensions/discord/src/voice/receive-recovery.ts +++ b/extensions/discord/src/voice/receive-recovery.ts @@ -74,6 +74,7 @@ function isAbortLikeReceiveError(err: unknown): boolean { : ""; return ( name === "AbortError" || + message === "Premature close" || message.includes("The operation was aborted") || message.includes("aborted") ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de5a80017c6..d5748782f77 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -616,8 +616,8 @@ importers: specifier: 9.0.0 version: 9.0.0 libopus-wasm: - specifier: 0.0.1 - version: 0.0.1 + specifier: 0.1.0 + version: 0.1.0 prism-media: specifier: 1.3.5 version: 1.3.5 @@ -5479,8 +5479,8 @@ packages: resolution: {integrity: sha512-s6WVJyEZrbm6jhBpiKHsGHyePMrVQKJ85wZCFCr9W4QHv6WTjWIrdvTmO9hDEA3bNK0xkrE2DqrHsXMLWuZpQg==} engines: {node: '>=22.0.0'} - libopus-wasm@0.0.1: - resolution: {integrity: sha512-w//dxORfJfLl4quaA5nEA0xZlbbtS/Gba+NrZyCDPmAQh2THX4KI6aI600f+jpxf6v3p9ApGCx0/DCCe4Xftug==} + libopus-wasm@0.1.0: + resolution: {integrity: sha512-/aurGcAVgy0GcBEUzFaX9pm9qv7zYcy8W5hBXFiK+cyqOXAX4lOS6rlFogkY9CcSIajhjnuXyixsbmziSHCDMQ==} engines: {node: '>=20'} libsignal@6.0.0: @@ -11294,7 +11294,7 @@ snapshots: kysely@0.29.2: {} - libopus-wasm@0.0.1: {} + libopus-wasm@0.1.0: {} libsignal@6.0.0: dependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f523226c1af..d4531db9539 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -16,7 +16,7 @@ minimumReleaseAgeExclude: - "basic-ftp" - "baileys@7.0.0-rc13" - "hono" - - "libopus-wasm@0.0.1" + - "libopus-wasm@0.1.0" - "libsignal@6.0.0" - "openclaw" - "protobufjs"