mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-27 00:17:29 +00:00
fix: prevent matrix-js-sdk plugin load crash (#56273) (thanks @aquaright1)
* Fix matrix-js-sdk multiple entrypoint crash on plugin load * test(matrix): cover runtime bundle import regression * fix: prevent matrix-js-sdk plugin load crash (#56273) (thanks @aquaright1) * fix: widen matrix-js-sdk bundle import guard (#56273) (thanks @aquaright1) --------- Co-authored-by: Kenny Xie <kennyxie@Mac-mini-von-Kenny.local> Co-authored-by: Ayaan Zaidi <hi@obviy.us>
This commit is contained in:
@@ -74,6 +74,7 @@ Docs: https://docs.openclaw.ai
|
|||||||
- Feishu: use the original message `create_time` instead of `Date.now()` for inbound timestamps so offline-retried messages carry the correct authoring time, preventing mis-targeted agent actions on stale instructions. (#52809) Thanks @schumilin.
|
- Feishu: use the original message `create_time` instead of `Date.now()` for inbound timestamps so offline-retried messages carry the correct authoring time, preventing mis-targeted agent actions on stale instructions. (#52809) Thanks @schumilin.
|
||||||
- Control UI/Skills: open skill detail dialogs with the browser modal lifecycle so clicking a skill row keeps the panel centered instead of rendering it off-screen at the bottom of the page.
|
- Control UI/Skills: open skill detail dialogs with the browser modal lifecycle so clicking a skill row keeps the panel centered instead of rendering it off-screen at the bottom of the page.
|
||||||
- Matrix/replies: include quoted poll question/options in inbound reply context so the agent sees the original poll content when users reply to Matrix poll messages. (#55056) Thanks @alberthild.
|
- Matrix/replies: include quoted poll question/options in inbound reply context so the agent sees the original poll content when users reply to Matrix poll messages. (#55056) Thanks @alberthild.
|
||||||
|
- Matrix/plugins: keep plugin bootstrap from crashing when built runtime mixes bare and deep `matrix-js-sdk` entrypoints, so unrelated channels do not get taken down during plugin load. (#56273) Thanks @aquaright1.
|
||||||
- Agents/sandbox: honor `tools.sandbox.tools.alsoAllow`, let explicit sandbox re-allows remove matching built-in default-deny tools, and keep sandbox explain/error guidance aligned with the effective sandbox tool policy. (#54492) Thanks @ngutman.
|
- Agents/sandbox: honor `tools.sandbox.tools.alsoAllow`, let explicit sandbox re-allows remove matching built-in default-deny tools, and keep sandbox explain/error guidance aligned with the effective sandbox tool policy. (#54492) Thanks @ngutman.
|
||||||
- Agents/sandbox: make blocked-tool guidance glob-aware again, redact/sanitize session-specific explain hints for safer copy-paste, and avoid leaking control-character session keys in those hints. (#54684) Thanks @ngutman.
|
- Agents/sandbox: make blocked-tool guidance glob-aware again, redact/sanitize session-specific explain hints for safer copy-paste, and avoid leaking control-character session keys in those hints. (#54684) Thanks @ngutman.
|
||||||
- Agents/compaction: trigger timeout recovery compaction before retrying high-context LLM timeouts so embedded runs stop repeating oversized requests. (#46417) thanks @joeykrug.
|
- Agents/compaction: trigger timeout recovery compaction before retrying high-context LLM timeouts so embedded runs stop repeating oversized requests. (#46417) thanks @joeykrug.
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { readFileSync } from "node:fs";
|
|||||||
import fs from "node:fs/promises";
|
import fs from "node:fs/promises";
|
||||||
import {
|
import {
|
||||||
Category,
|
Category,
|
||||||
|
MemoryStore,
|
||||||
|
SyncAccumulator,
|
||||||
type ISyncData,
|
type ISyncData,
|
||||||
type IRooms,
|
type IRooms,
|
||||||
type ISyncResponse,
|
type ISyncResponse,
|
||||||
type IStoredClientOpts,
|
type IStoredClientOpts,
|
||||||
} from "matrix-js-sdk";
|
} from "matrix-js-sdk/lib/matrix.js";
|
||||||
import { MemoryStore } from "matrix-js-sdk/lib/store/memory.js";
|
|
||||||
import { SyncAccumulator } from "matrix-js-sdk/lib/sync-accumulator.js";
|
|
||||||
import { writeJsonFileAtomically } from "../../runtime-api.js";
|
import { writeJsonFileAtomically } from "../../runtime-api.js";
|
||||||
import { createAsyncLock } from "../async-lock.js";
|
import { createAsyncLock } from "../async-lock.js";
|
||||||
import { LogService } from "../sdk/logger.js";
|
import { LogService } from "../sdk/logger.js";
|
||||||
|
|||||||
@@ -175,8 +175,8 @@ function createMatrixJsClientStub(): MatrixJsClientStub {
|
|||||||
let matrixJsClient = createMatrixJsClientStub();
|
let matrixJsClient = createMatrixJsClientStub();
|
||||||
let lastCreateClientOpts: Record<string, unknown> | null = null;
|
let lastCreateClientOpts: Record<string, unknown> | null = null;
|
||||||
|
|
||||||
vi.mock("matrix-js-sdk", async (importOriginal) => {
|
vi.mock("matrix-js-sdk/lib/matrix.js", async (importOriginal) => {
|
||||||
const actual = await importOriginal<typeof import("matrix-js-sdk")>();
|
const actual = await importOriginal<typeof import("matrix-js-sdk/lib/matrix.js")>();
|
||||||
return {
|
return {
|
||||||
...actual,
|
...actual,
|
||||||
ClientEvent: { Event: "event", Room: "Room" },
|
ClientEvent: { Event: "event", Room: "Room" },
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
createClient as createMatrixJsClient,
|
createClient as createMatrixJsClient,
|
||||||
type MatrixClient as MatrixJsClient,
|
type MatrixClient as MatrixJsClient,
|
||||||
type MatrixEvent,
|
type MatrixEvent,
|
||||||
} from "matrix-js-sdk";
|
} from "matrix-js-sdk/lib/matrix.js";
|
||||||
import { VerificationMethod } from "matrix-js-sdk/lib/types.js";
|
import { VerificationMethod } from "matrix-js-sdk/lib/types.js";
|
||||||
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/core";
|
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/core";
|
||||||
import type { SsrFPolicy } from "../runtime-api.js";
|
import type { SsrFPolicy } from "../runtime-api.js";
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { MatrixEventEvent, type MatrixEvent } from "matrix-js-sdk";
|
|
||||||
import { CryptoEvent } from "matrix-js-sdk/lib/crypto-api/CryptoEvent.js";
|
import { CryptoEvent } from "matrix-js-sdk/lib/crypto-api/CryptoEvent.js";
|
||||||
|
import { MatrixEventEvent, type MatrixEvent } from "matrix-js-sdk/lib/matrix.js";
|
||||||
import { LogService, noop } from "./logger.js";
|
import { LogService, noop } from "./logger.js";
|
||||||
|
|
||||||
type MatrixDecryptIfNeededClient = {
|
type MatrixDecryptIfNeededClient = {
|
||||||
|
|||||||
@@ -8,7 +8,28 @@ import { buildPluginSdkEntrySources, pluginSdkEntrypoints } from "./entrypoints.
|
|||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
const tsdownModuleUrl = pathToFileURL(require.resolve("tsdown")).href;
|
const tsdownModuleUrl = pathToFileURL(require.resolve("tsdown")).href;
|
||||||
const bundledRepresentativeEntrypoints = ["matrix-runtime-heavy"] as const;
|
const bundledRepresentativeEntrypoints = ["matrix-runtime-heavy"] as const;
|
||||||
const bundledCoverageEntrySources = buildPluginSdkEntrySources(bundledRepresentativeEntrypoints);
|
const matrixRuntimeCoverageEntries = {
|
||||||
|
"matrix-runtime-sdk": "extensions/matrix/src/matrix/sdk.ts",
|
||||||
|
} as const;
|
||||||
|
const bundledCoverageEntrySources = {
|
||||||
|
...buildPluginSdkEntrySources(bundledRepresentativeEntrypoints),
|
||||||
|
...matrixRuntimeCoverageEntries,
|
||||||
|
};
|
||||||
|
const bareMatrixSdkImportPattern = /(?:from|require|import)\s*\(?\s*["']matrix-js-sdk["']/;
|
||||||
|
|
||||||
|
async function listBuiltJsFiles(rootDir: string): Promise<string[]> {
|
||||||
|
const entries = await fs.readdir(rootDir, { withFileTypes: true });
|
||||||
|
const nested = await Promise.all(
|
||||||
|
entries.map(async (entry) => {
|
||||||
|
const entryPath = path.join(rootDir, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
return await listBuiltJsFiles(entryPath);
|
||||||
|
}
|
||||||
|
return entry.isFile() && entry.name.endsWith(".js") ? [entryPath] : [];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return nested.flat();
|
||||||
|
}
|
||||||
|
|
||||||
describe("plugin-sdk bundled exports", () => {
|
describe("plugin-sdk bundled exports", () => {
|
||||||
it("emits importable bundled subpath entries", { timeout: 120_000 }, async () => {
|
it("emits importable bundled subpath entries", { timeout: 120_000 }, async () => {
|
||||||
@@ -34,7 +55,9 @@ describe("plugin-sdk bundled exports", () => {
|
|||||||
},
|
},
|
||||||
// Full plugin-sdk coverage belongs to `pnpm build`, package contract
|
// Full plugin-sdk coverage belongs to `pnpm build`, package contract
|
||||||
// guardrails, and `subpaths.test.ts`. This file only keeps the expensive
|
// guardrails, and `subpaths.test.ts`. This file only keeps the expensive
|
||||||
// bundler path honest across representative entrypoint families.
|
// bundler path honest across representative entrypoint families plus the
|
||||||
|
// Matrix SDK runtime import surface that historically crashed plugin
|
||||||
|
// loading when bare and deep SDK entrypoints mixed.
|
||||||
entry: bundledCoverageEntrySources,
|
entry: bundledCoverageEntrySources,
|
||||||
env: { NODE_ENV: "production" },
|
env: { NODE_ENV: "production" },
|
||||||
fixedExtension: false,
|
fixedExtension: false,
|
||||||
@@ -49,6 +72,21 @@ describe("plugin-sdk bundled exports", () => {
|
|||||||
await expect(fs.stat(path.join(outDir, `${entry}.js`))).resolves.toBeTruthy();
|
await expect(fs.stat(path.join(outDir, `${entry}.js`))).resolves.toBeTruthy();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
await Promise.all(
|
||||||
|
Object.keys(matrixRuntimeCoverageEntries).map(async (entry) => {
|
||||||
|
await expect(fs.stat(path.join(outDir, `${entry}.js`))).resolves.toBeTruthy();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
const builtJsFiles = await listBuiltJsFiles(outDir);
|
||||||
|
const filesWithBareMatrixSdkImports = (
|
||||||
|
await Promise.all(
|
||||||
|
builtJsFiles.map(async (filePath) => {
|
||||||
|
const contents = await fs.readFile(filePath, "utf8");
|
||||||
|
return bareMatrixSdkImportPattern.test(contents) ? filePath : null;
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
).filter((filePath): filePath is string => filePath !== null);
|
||||||
|
expect(filesWithBareMatrixSdkImports).toEqual([]);
|
||||||
|
|
||||||
// Export list and package-specifier coverage already live in
|
// Export list and package-specifier coverage already live in
|
||||||
// package-contract-guardrails.test.ts and subpaths.test.ts. Keep this file
|
// package-contract-guardrails.test.ts and subpaths.test.ts. Keep this file
|
||||||
|
|||||||
Reference in New Issue
Block a user