diff --git a/extensions/qqbot/src/utils/audio-convert.ts b/extensions/qqbot/src/utils/audio-convert.ts index 9225bf28eaa..d965d9edc91 100644 --- a/extensions/qqbot/src/utils/audio-convert.ts +++ b/extensions/qqbot/src/utils/audio-convert.ts @@ -6,16 +6,6 @@ import { decode, encode, isSilk } from "silk-wasm"; import { debugLog, debugError, debugWarn } from "./debug-log.js"; import { detectFfmpeg, isWindows } from "./platform.js"; -/** Detect whether a file contains SILK audio payloads. */ -function isSilkFile(filePath: string): boolean { - try { - const buf = fs.readFileSync(filePath); - return isSilk(new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength)); - } catch { - return false; - } -} - /** Wrap PCM s16le bytes in a WAV container. */ function pcmToWav( pcmData: Uint8Array, diff --git a/scripts/lib/bundled-plugin-build-entries.d.mts b/scripts/lib/bundled-plugin-build-entries.d.mts index 3455f3d84e4..b8d10c5e9c3 100644 --- a/scripts/lib/bundled-plugin-build-entries.d.mts +++ b/scripts/lib/bundled-plugin-build-entries.d.mts @@ -17,3 +17,6 @@ export function listBundledPluginBuildEntries( params?: BundledPluginBuildEntryParams, ): Record; export function listBundledPluginPackArtifacts(params?: BundledPluginBuildEntryParams): string[]; +export function listBundledPluginRuntimeDependencies( + params?: BundledPluginBuildEntryParams, +): string[]; diff --git a/scripts/lib/bundled-plugin-build-entries.d.ts b/scripts/lib/bundled-plugin-build-entries.d.ts index 3455f3d84e4..b8d10c5e9c3 100644 --- a/scripts/lib/bundled-plugin-build-entries.d.ts +++ b/scripts/lib/bundled-plugin-build-entries.d.ts @@ -17,3 +17,6 @@ export function listBundledPluginBuildEntries( params?: BundledPluginBuildEntryParams, ): Record; export function listBundledPluginPackArtifacts(params?: BundledPluginBuildEntryParams): string[]; +export function listBundledPluginRuntimeDependencies( + params?: BundledPluginBuildEntryParams, +): string[]; diff --git a/scripts/lib/bundled-plugin-build-entries.mjs b/scripts/lib/bundled-plugin-build-entries.mjs index cad8876a7f2..dccdec932e4 100644 --- a/scripts/lib/bundled-plugin-build-entries.mjs +++ b/scripts/lib/bundled-plugin-build-entries.mjs @@ -46,6 +46,10 @@ function collectPluginSourceEntries(packageJson) { return packageEntries.length > 0 ? packageEntries : ["./index.ts"]; } +function shouldStageBundledPluginRuntimeDependencies(packageJson) { + return packageJson?.openclaw?.bundle?.stageRuntimeDependencies === true; +} + function collectTopLevelPublicSurfaceEntries(pluginDir) { if (!fs.existsSync(pluginDir)) { return []; @@ -158,3 +162,23 @@ export function listBundledPluginPackArtifacts(params = {}) { return [...artifacts].toSorted((left, right) => left.localeCompare(right)); } + +export function listBundledPluginRuntimeDependencies(params = {}) { + const runtimeDependencies = new Set(); + + for (const { packageJson } of collectBundledPluginBuildEntries(params)) { + if (!shouldStageBundledPluginRuntimeDependencies(packageJson)) { + continue; + } + + for (const dependencyName of Object.keys(packageJson?.dependencies ?? {})) { + runtimeDependencies.add(dependencyName); + } + + for (const dependencyName of Object.keys(packageJson?.optionalDependencies ?? {})) { + runtimeDependencies.add(dependencyName); + } + } + + return [...runtimeDependencies].toSorted((left, right) => left.localeCompare(right)); +} diff --git a/src/infra/tsdown-config.test.ts b/src/infra/tsdown-config.test.ts index 49da95d5177..f9a49322e1f 100644 --- a/src/infra/tsdown-config.test.ts +++ b/src/infra/tsdown-config.test.ts @@ -3,6 +3,9 @@ import { bundledPluginRoot } from "../../test/helpers/bundled-plugin-paths.js"; import tsdownConfig from "../../tsdown.config.ts"; type TsdownConfigEntry = { + deps?: { + neverBundle?: string[]; + }; entry?: Record | string[]; outDir?: string; }; @@ -69,4 +72,11 @@ describe("tsdown config", () => { ), ).toBe(false); }); + + it("externalizes staged bundled plugin runtime dependencies", () => { + const configs = asConfigArray(tsdownConfig); + const unifiedGraph = configs.find((config) => entryKeys(config).includes("index")); + + expect(unifiedGraph?.deps?.neverBundle).toEqual(expect.arrayContaining(["silk-wasm", "ws"])); + }); }); diff --git a/tsdown.config.ts b/tsdown.config.ts index f6137126212..2b052c74c3d 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -1,7 +1,10 @@ import fs from "node:fs"; import path from "node:path"; import { defineConfig, type UserConfig } from "tsdown"; -import { listBundledPluginBuildEntries } from "./scripts/lib/bundled-plugin-build-entries.mjs"; +import { + listBundledPluginBuildEntries, + listBundledPluginRuntimeDependencies, +} from "./scripts/lib/bundled-plugin-build-entries.mjs"; import { buildPluginSdkEntrySources } from "./scripts/lib/plugin-sdk-entries.mjs"; type InputOptionsFactory = Extract, Function>; @@ -81,6 +84,7 @@ function nodeBuildConfig(config: UserConfig): UserConfig { } const bundledPluginBuildEntries = listBundledPluginBuildEntries(); +const bundledPluginRuntimeDependencies = listBundledPluginRuntimeDependencies(); function buildBundledHookEntries(): Record { const hooksRoot = path.join(process.cwd(), "src", "hooks", "bundled"); @@ -160,7 +164,12 @@ export default defineConfig([ // and bundled hooks in one graph so runtime singletons are emitted once. entry: buildUnifiedDistEntries(), deps: { - neverBundle: ["@lancedb/lancedb", "@matrix-org/matrix-sdk-crypto-nodejs", "matrix-js-sdk"], + neverBundle: [ + "@lancedb/lancedb", + "@matrix-org/matrix-sdk-crypto-nodejs", + "matrix-js-sdk", + ...bundledPluginRuntimeDependencies, + ], }, }), ]);