fix: drop discord opus dependency
This commit is contained in:
@@ -20,6 +20,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Discord/presence defaults: send an online presence update on ready when no custom presence is configured so bots no longer appear offline by default. Thanks @thewilloftheshadow.
|
||||
- Discord/typing cleanup: stop typing indicators after silent/NO_REPLY runs by marking the run complete before dispatch idle cleanup. Thanks @thewilloftheshadow.
|
||||
- Discord/voice messages: request upload slots with JSON fetch calls so voice message uploads no longer fail with content-type errors. Thanks @thewilloftheshadow.
|
||||
- Discord/voice decoder fallback: drop the native Opus dependency and use opusscript for voice decoding to avoid native-opus installs. Thanks @thewilloftheshadow.
|
||||
- Discord/auto presence health signal: add runtime availability-driven presence updates plus connected-state reporting to improve health monitoring and operator visibility. (#33277) Thanks @thewilloftheshadow.
|
||||
- Telegram/DM draft finalization reliability: require verified final-text draft emission before treating preview finalization as delivered, and fall back to normal payload send when final draft delivery is not confirmed (preventing missing final responses and preserving media/button delivery). (#32118) Thanks @OpenCils.
|
||||
- Telegram/draft preview boundary + silent-token reliability: stabilize answer-lane message boundaries across late-partial/message-start races, preserve/reset finalized preview state at the correct boundaries, and suppress `NO_REPLY` lead-fragment leaks without broad heartbeat-prefix false positives. (#33169) Thanks @obviyus.
|
||||
@@ -914,7 +915,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Agents/Kimi: classify Moonshot `Your request exceeded model token limit` failures as context overflows so auto-compaction and user-facing overflow recovery trigger correctly instead of surfacing raw invalid-request errors. (#9562) Thanks @danilofalcao.
|
||||
- Providers/Moonshot: mark Kimi K2.5 as image-capable in implicit + onboarding model definitions, and refresh stale explicit provider capability fields (`input`/`reasoning`/context limits) from implicit catalogs so existing configs pick up Moonshot vision support without manual model rewrites. (#13135, #4459) Thanks @manikv12.
|
||||
- Agents/Transcript: enable consecutive-user turn merging for strict non-OpenAI `openai-completions` providers (for example Moonshot/Kimi), reducing `roles must alternate` ordering failures on OpenAI-compatible endpoints while preserving current OpenRouter/Opencode behavior. (#7693) Thanks @steipete.
|
||||
- Install/Discord Voice: make `@discordjs/opus` an optional dependency so `openclaw` install/update no longer hard-fails when native Opus builds fail, while keeping `opusscript` as the runtime fallback decoder for Discord voice flows. (#23737, #23733, #23703) Thanks @jeadland, @Sheetaa, and @Breakyman.
|
||||
- Install/Discord Voice: make the native Opus decoder optional so `openclaw` install/update no longer hard-fails when native builds fail, while keeping `opusscript` as the runtime fallback decoder for Discord voice flows. (#23737, #23733, #23703) Thanks @jeadland, @Sheetaa, and @Breakyman.
|
||||
- Docker/Setup: precreate `$OPENCLAW_CONFIG_DIR/identity` during `docker-setup.sh` so CLI commands that need device identity (for example `devices list`) avoid `EACCES ... /home/node/.openclaw/identity` failures on restrictive bind mounts. (#23948) Thanks @ackson-beep.
|
||||
- Exec/Background: stop applying the default exec timeout to background sessions (`background: true` or explicit `yieldMs`) when no explicit timeout is set, so long-running background jobs are no longer terminated at the default timeout boundary. (#23303) Thanks @steipete.
|
||||
- Slack/Threading: sessions: keep parent-session forking and thread-history context active beyond first turn by removing first-turn-only gates in session init, thread-history fetch, and reply prompt context injection. (#23843, #23090) Thanks @vincentkoc and @Taskle.
|
||||
|
||||
@@ -247,9 +247,6 @@
|
||||
"@napi-rs/canvas": "^0.1.89",
|
||||
"node-llama-cpp": "3.16.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@discordjs/opus": "^0.10.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22.12.0"
|
||||
},
|
||||
|
||||
43
pnpm-lock.yaml
generated
43
pnpm-lock.yaml
generated
@@ -29,13 +29,13 @@ importers:
|
||||
version: 3.1000.0
|
||||
'@buape/carbon':
|
||||
specifier: 0.0.0-beta-20260216184201
|
||||
version: 0.0.0-beta-20260216184201(@discordjs/opus@0.10.0)(hono@4.11.10)(opusscript@0.1.1)
|
||||
version: 0.0.0-beta-20260216184201(hono@4.11.10)(opusscript@0.1.1)
|
||||
'@clack/prompts':
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
'@discordjs/voice':
|
||||
specifier: ^0.19.0
|
||||
version: 0.19.0(@discordjs/opus@0.10.0)(opusscript@0.1.1)
|
||||
version: 0.19.0(opusscript@0.1.1)
|
||||
'@grammyjs/runner':
|
||||
specifier: ^2.0.3
|
||||
version: 2.0.3(grammy@1.41.0)
|
||||
@@ -253,10 +253,6 @@ importers:
|
||||
vitest:
|
||||
specifier: ^4.0.18
|
||||
version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.3.3)(@vitest/browser-playwright@4.0.18)(jiti@2.6.1)(lightningcss@1.30.2)(tsx@4.21.0)(yaml@2.8.2)
|
||||
optionalDependencies:
|
||||
'@discordjs/opus':
|
||||
specifier: ^0.10.0
|
||||
version: 0.10.0
|
||||
|
||||
extensions/acpx:
|
||||
dependencies:
|
||||
@@ -929,10 +925,6 @@ packages:
|
||||
resolution: {integrity: sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==}
|
||||
hasBin: true
|
||||
|
||||
'@discordjs/opus@0.10.0':
|
||||
resolution: {integrity: sha512-HHEnSNrSPmFEyndRdQBJN2YE6egyXS9JUnJWyP6jficK0Y+qKMEZXyYTgmzpjrxXP1exM/hKaNP7BRBUEWkU5w==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
'@discordjs/voice@0.19.0':
|
||||
resolution: {integrity: sha512-UyX6rGEXzVyPzb1yvjHtPfTlnLvB5jX/stAMdiytHhfoydX+98hfympdOwsnTktzr+IRvphxTbdErgYDJkEsvw==}
|
||||
engines: {node: '>=22.12.0'}
|
||||
@@ -5193,13 +5185,10 @@ packages:
|
||||
prism-media@1.3.5:
|
||||
resolution: {integrity: sha512-IQdl0Q01m4LrkN1EGIE9lphov5Hy7WWlH6ulf5QdGePLlPas9p2mhgddTEHrlaXYjjFToM1/rWuwF37VF4taaA==}
|
||||
peerDependencies:
|
||||
'@discordjs/opus': '>=0.8.0 <1.0.0'
|
||||
ffmpeg-static: ^5.0.2 || ^4.2.7 || ^3.0.0 || ^2.4.0
|
||||
node-opus: ^0.3.3
|
||||
opusscript: ^0.0.8
|
||||
peerDependenciesMeta:
|
||||
'@discordjs/opus':
|
||||
optional: true
|
||||
ffmpeg-static:
|
||||
optional: true
|
||||
node-opus:
|
||||
@@ -6824,19 +6813,18 @@ snapshots:
|
||||
|
||||
'@borewit/text-codec@0.2.1': {}
|
||||
|
||||
'@buape/carbon@0.0.0-beta-20260216184201(@discordjs/opus@0.10.0)(hono@4.11.10)(opusscript@0.1.1)':
|
||||
'@buape/carbon@0.0.0-beta-20260216184201(hono@4.11.10)(opusscript@0.1.1)':
|
||||
dependencies:
|
||||
'@types/node': 25.3.3
|
||||
discord-api-types: 0.38.37
|
||||
optionalDependencies:
|
||||
'@cloudflare/workers-types': 4.20260120.0
|
||||
'@discordjs/voice': 0.19.0(@discordjs/opus@0.10.0)(opusscript@0.1.1)
|
||||
'@discordjs/voice': 0.19.0(opusscript@0.1.1)
|
||||
'@hono/node-server': 1.19.9(hono@4.11.10)
|
||||
'@types/bun': 1.3.9
|
||||
'@types/ws': 8.18.1
|
||||
ws: 8.19.0
|
||||
transitivePeerDependencies:
|
||||
- '@discordjs/opus'
|
||||
- bufferutil
|
||||
- ffmpeg-static
|
||||
- hono
|
||||
@@ -6971,24 +6959,14 @@ snapshots:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
'@discordjs/opus@0.10.0':
|
||||
dependencies:
|
||||
'@discordjs/node-pre-gyp': 0.4.5
|
||||
node-addon-api: 8.5.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
'@discordjs/voice@0.19.0(@discordjs/opus@0.10.0)(opusscript@0.1.1)':
|
||||
'@discordjs/voice@0.19.0(opusscript@0.1.1)':
|
||||
dependencies:
|
||||
'@types/ws': 8.18.1
|
||||
discord-api-types: 0.38.40
|
||||
prism-media: 1.3.5(@discordjs/opus@0.10.0)(opusscript@0.1.1)
|
||||
prism-media: 1.3.5(opusscript@0.1.1)
|
||||
tslib: 2.8.1
|
||||
ws: 8.19.0
|
||||
transitivePeerDependencies:
|
||||
- '@discordjs/opus'
|
||||
- bufferutil
|
||||
- ffmpeg-static
|
||||
- node-opus
|
||||
@@ -11197,9 +11175,9 @@ snapshots:
|
||||
dependencies:
|
||||
'@agentclientprotocol/sdk': 0.14.1(zod@4.3.6)
|
||||
'@aws-sdk/client-bedrock': 3.1000.0
|
||||
'@buape/carbon': 0.0.0-beta-20260216184201(@discordjs/opus@0.10.0)(hono@4.11.10)(opusscript@0.1.1)
|
||||
'@buape/carbon': 0.0.0-beta-20260216184201(hono@4.11.10)(opusscript@0.1.1)
|
||||
'@clack/prompts': 1.0.1
|
||||
'@discordjs/voice': 0.19.0(@discordjs/opus@0.10.0)(opusscript@0.1.1)
|
||||
'@discordjs/voice': 0.19.0(opusscript@0.1.1)
|
||||
'@grammyjs/runner': 2.0.3(grammy@1.41.0)
|
||||
'@grammyjs/transformer-throttler': 1.2.1(grammy@1.41.0)
|
||||
'@homebridge/ciao': 1.3.5
|
||||
@@ -11254,8 +11232,6 @@ snapshots:
|
||||
ws: 8.19.0
|
||||
yaml: 2.8.2
|
||||
zod: 4.3.6
|
||||
optionalDependencies:
|
||||
'@discordjs/opus': 0.10.0
|
||||
transitivePeerDependencies:
|
||||
- '@modelcontextprotocol/sdk'
|
||||
- '@types/express'
|
||||
@@ -11509,9 +11485,8 @@ snapshots:
|
||||
dependencies:
|
||||
parse-ms: 4.0.0
|
||||
|
||||
prism-media@1.3.5(@discordjs/opus@0.10.0)(opusscript@0.1.1):
|
||||
prism-media@1.3.5(opusscript@0.1.1):
|
||||
optionalDependencies:
|
||||
'@discordjs/opus': 0.10.0
|
||||
opusscript: 0.1.1
|
||||
|
||||
process-nextick-args@2.0.1: {}
|
||||
|
||||
@@ -36,11 +36,8 @@ describe("inferUpdateFailureHints", () => {
|
||||
expect(hints.join("\n")).toContain("npm config set prefix ~/.local");
|
||||
});
|
||||
|
||||
it("returns native optional dependency hint for node-gyp/opus failures", () => {
|
||||
const result = makeResult(
|
||||
"global update",
|
||||
"node-pre-gyp ERR!\n@discordjs/opus\nnode-gyp rebuild failed",
|
||||
);
|
||||
it("returns native optional dependency hint for node-gyp failures", () => {
|
||||
const result = makeResult("global update", "node-pre-gyp ERR!\nnode-gyp rebuild failed");
|
||||
const hints = inferUpdateFailureHints(result);
|
||||
expect(hints.join("\n")).toContain("--omit=optional");
|
||||
});
|
||||
|
||||
@@ -57,12 +57,10 @@ export function inferUpdateFailureHints(result: UpdateRunResult): string[] {
|
||||
|
||||
if (
|
||||
failedStep.name.startsWith("global update") &&
|
||||
(stderr.includes("node-gyp") ||
|
||||
stderr.includes("@discordjs/opus") ||
|
||||
stderr.includes("prebuild"))
|
||||
(stderr.includes("node-gyp") || stderr.includes("prebuild"))
|
||||
) {
|
||||
hints.push(
|
||||
"Detected native optional dependency build failure (e.g. opus). The updater retries with --omit=optional automatically.",
|
||||
"Detected native optional dependency build failure. The updater retries with --omit=optional automatically.",
|
||||
);
|
||||
hints.push("If it still fails: npm i -g openclaw@latest --omit=optional");
|
||||
}
|
||||
|
||||
@@ -157,32 +157,22 @@ type OpusDecoder = {
|
||||
decode: (buffer: Buffer) => Buffer;
|
||||
};
|
||||
|
||||
let warnedOpusFallback = false;
|
||||
let warnedOpusMissing = false;
|
||||
|
||||
function createOpusDecoder(): { decoder: OpusDecoder; name: string } | null {
|
||||
try {
|
||||
const { OpusEncoder } = require("@discordjs/opus") as {
|
||||
OpusEncoder: new (sampleRate: number, channels: number) => OpusDecoder;
|
||||
const OpusScript = require("opusscript") as {
|
||||
new (sampleRate: number, channels: number, application: number): OpusDecoder;
|
||||
Application: { AUDIO: number };
|
||||
};
|
||||
const decoder = new OpusEncoder(SAMPLE_RATE, CHANNELS);
|
||||
return { decoder, name: "@discordjs/opus" };
|
||||
} catch (nativeErr) {
|
||||
try {
|
||||
const OpusScript = require("opusscript") as {
|
||||
new (sampleRate: number, channels: number, application: number): OpusDecoder;
|
||||
Application: { AUDIO: number };
|
||||
};
|
||||
const decoder = new OpusScript(SAMPLE_RATE, CHANNELS, OpusScript.Application.AUDIO);
|
||||
if (!warnedOpusFallback) {
|
||||
warnedOpusFallback = true;
|
||||
logger.warn(
|
||||
`discord voice: @discordjs/opus unavailable (${formatErrorMessage(nativeErr)}); using opusscript fallback`,
|
||||
);
|
||||
}
|
||||
return { decoder, name: "opusscript" };
|
||||
} catch (jsErr) {
|
||||
logger.warn(`discord voice: opus decoder init failed: ${formatErrorMessage(nativeErr)}`);
|
||||
logger.warn(`discord voice: opusscript init failed: ${formatErrorMessage(jsErr)}`);
|
||||
const decoder = new OpusScript(SAMPLE_RATE, CHANNELS, OpusScript.Application.AUDIO);
|
||||
return { decoder, name: "opusscript" };
|
||||
} catch (err) {
|
||||
if (!warnedOpusMissing) {
|
||||
warnedOpusMissing = true;
|
||||
logger.warn(
|
||||
`discord voice: opusscript unavailable (${formatErrorMessage(err)}); cannot decode voice audio`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user