mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-13 15:47:28 +00:00
build(discord): skip native opus builds by default (#80071)
This commit is contained in:
committed by
GitHub
parent
048ca8c765
commit
487687a6f0
@@ -7,6 +7,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Changes
|
||||
|
||||
- Talk: add `talk.realtime.instructions` so operators can append realtime voice style instructions while preserving OpenClaw's built-in agent-consult guidance. (#79081) Thanks @VACInc.
|
||||
- Discord/voice: default test and source installs to the pure-JS `opusscript` decoder by ignoring optional native `@discordjs/opus` builds, avoiding slow native addon compiles outside dedicated voice-performance lanes.
|
||||
- Gateway/skills: add an opt-in private skill archive upload install path gated by `skills.install.allowUploadedArchives`, so trusted Gateway clients can stage and install zip-backed skills only when operators explicitly enable the code-install surface. (#74430) Thanks @samzong.
|
||||
- Dependencies: refresh workspace pins and patch targets, including ACPX `@agentclientprotocol/claude-agent-acp` `0.33.1`, Codex ACP `0.14.0`, Baileys `7.0.0-rc10`, Google GenAI `2.0.1`, OpenAI `6.37.0`, AWS SDK `3.1045.0`, Kysely `0.29.0`, Tlon skill `0.3.6`, Aimock `1.19.5`, and tsdown `0.22.0`.
|
||||
- Agents/compaction: preserve scoped background exec/process session references across embedded compaction and after-turn runtime contexts without exposing sessions from unrelated scopes. Fixes #79284. (#79307) Thanks @TurboTheTurtle.
|
||||
|
||||
@@ -1213,6 +1213,7 @@ Notes:
|
||||
- If `voice.autoJoin` has multiple entries for the same guild, OpenClaw joins the last configured channel for that guild.
|
||||
- `voice.daveEncryption` and `voice.decryptionFailureTolerance` pass through to `@discordjs/voice` join options.
|
||||
- `@discordjs/voice` defaults are `daveEncryption=true` and `decryptionFailureTolerance=24` if unset.
|
||||
- OpenClaw defaults to the pure-JS `opusscript` decoder for Discord voice receive. The optional native `@discordjs/opus` package is ignored by the repo pnpm install policy so normal installs and tests do not compile a native addon; only opt into a native opus build in a dedicated voice-performance or live-lane environment.
|
||||
- `voice.connectTimeoutMs` controls the initial `@discordjs/voice` Ready wait for `/vc join` and auto-join attempts. Default: `30000`.
|
||||
- `voice.reconnectGraceMs` controls how long OpenClaw waits for a disconnected voice session to begin reconnecting before destroying it. Default: `15000`.
|
||||
- In `stt-tts` mode, voice playback does not stop just because another user starts speaking. To avoid feedback loops, OpenClaw ignores new voice capture while TTS is playing; speak after playback finishes for the next turn. Realtime modes forward speaker starts as barge-in signals to the realtime provider.
|
||||
|
||||
@@ -443,6 +443,11 @@ Think of the suites as "increasing realism" (and increasing flakiness/cost):
|
||||
real bundled plugin source APIs. Real plugin API loads belong in
|
||||
plugin-owned contract/integration suites.
|
||||
|
||||
Native dependency policy:
|
||||
|
||||
- Default test installs skip optional native Discord opus builds. Discord voice receive uses the pure-JS `opusscript` decoder, and `@discordjs/opus` stays in `ignoredBuiltDependencies` so local tests and Testbox lanes do not compile the native addon.
|
||||
- Use a dedicated Discord voice performance or live lane if you intentionally need to compare a native opus build. Do not add `@discordjs/opus` back to the default `onlyBuiltDependencies`; that makes unrelated install/test loops compile native code.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Projects, shards, and scoped lanes">
|
||||
|
||||
|
||||
19
extensions/discord/src/voice/audio.test.ts
Normal file
19
extensions/discord/src/voice/audio.test.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Readable } from "node:stream";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { decodeOpusStream } from "./audio.js";
|
||||
|
||||
describe("discord voice opus decoder selection", () => {
|
||||
it("prefers the pure-JS opusscript decoder over optional native opus", async () => {
|
||||
const verbose: string[] = [];
|
||||
const warnings: string[] = [];
|
||||
|
||||
const decoded = await decodeOpusStream(Readable.from([]), {
|
||||
onVerbose: (message) => verbose.push(message),
|
||||
onWarn: (message) => warnings.push(message),
|
||||
});
|
||||
|
||||
expect(decoded.length).toBe(0);
|
||||
expect(verbose).toContain("opus decoder: opusscript");
|
||||
expect(warnings).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -48,6 +48,16 @@ function resolveOpusDecoderFactory(params: {
|
||||
onWarn: (message: string) => void;
|
||||
}): OpusDecoderFactory | null {
|
||||
const factories: OpusDecoderFactory[] = [
|
||||
{
|
||||
name: "opusscript",
|
||||
load: () => {
|
||||
const OpusScript = require("opusscript") as {
|
||||
new (sampleRate: number, channels: number, application: number): OpusDecoder;
|
||||
Application: { AUDIO: number };
|
||||
};
|
||||
return new OpusScript(SAMPLE_RATE, CHANNELS, OpusScript.Application.AUDIO);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "@discordjs/opus",
|
||||
load: () => {
|
||||
@@ -62,16 +72,6 @@ function resolveOpusDecoderFactory(params: {
|
||||
return new DiscordOpus.OpusEncoder(SAMPLE_RATE, CHANNELS);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "opusscript",
|
||||
load: () => {
|
||||
const OpusScript = require("opusscript") as {
|
||||
new (sampleRate: number, channels: number, application: number): OpusDecoder;
|
||||
Application: { AUDIO: number };
|
||||
};
|
||||
return new OpusScript(SAMPLE_RATE, CHANNELS, OpusScript.Application.AUDIO);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const failures: string[] = [];
|
||||
|
||||
@@ -1820,7 +1820,6 @@
|
||||
},
|
||||
"onlyBuiltDependencies": [
|
||||
"@openclaw/fs-safe",
|
||||
"@discordjs/opus",
|
||||
"@google/genai",
|
||||
"@lydell/node-pty",
|
||||
"@matrix-org/matrix-sdk-crypto-nodejs",
|
||||
@@ -1835,6 +1834,7 @@
|
||||
"sharp"
|
||||
],
|
||||
"ignoredBuiltDependencies": [
|
||||
"@discordjs/opus",
|
||||
"koffi",
|
||||
"tree-sitter-bash"
|
||||
],
|
||||
|
||||
@@ -34,7 +34,6 @@ minimumReleaseAgeExclude:
|
||||
|
||||
onlyBuiltDependencies:
|
||||
- "@openclaw/fs-safe"
|
||||
- "@discordjs/opus"
|
||||
- "@google/genai"
|
||||
- "@lydell/node-pty"
|
||||
- "@matrix-org/matrix-sdk-crypto-nodejs"
|
||||
@@ -49,5 +48,6 @@ onlyBuiltDependencies:
|
||||
- sharp
|
||||
|
||||
ignoredBuiltDependencies:
|
||||
- "@discordjs/opus"
|
||||
- koffi
|
||||
- tree-sitter-bash
|
||||
|
||||
30
test/package-manager-config.test.ts
Normal file
30
test/package-manager-config.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import fs from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { parse } from "yaml";
|
||||
|
||||
type PnpmBuildConfig = {
|
||||
ignoredBuiltDependencies?: string[];
|
||||
onlyBuiltDependencies?: string[];
|
||||
};
|
||||
|
||||
type RootPackageJson = {
|
||||
pnpm?: PnpmBuildConfig;
|
||||
};
|
||||
|
||||
type WorkspaceConfig = PnpmBuildConfig;
|
||||
|
||||
function readJson<T>(filePath: string): T {
|
||||
return JSON.parse(fs.readFileSync(filePath, "utf8")) as T;
|
||||
}
|
||||
|
||||
describe("package manager build policy", () => {
|
||||
it("keeps optional native Discord opus builds disabled by default", () => {
|
||||
const packageJson = readJson<RootPackageJson>("package.json");
|
||||
const workspace = parse(fs.readFileSync("pnpm-workspace.yaml", "utf8")) as WorkspaceConfig;
|
||||
|
||||
for (const config of [packageJson.pnpm, workspace]) {
|
||||
expect(config?.ignoredBuiltDependencies ?? []).toContain("@discordjs/opus");
|
||||
expect(config?.onlyBuiltDependencies ?? []).not.toContain("@discordjs/opus");
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user