mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
Matrix: honor account-scoped status and chunk limits
This commit is contained in:
@@ -3,6 +3,9 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
|||||||
const hoisted = vi.hoisted(() => {
|
const hoisted = vi.hoisted(() => {
|
||||||
const callOrder: string[] = [];
|
const callOrder: string[] = [];
|
||||||
const client = { id: "matrix-client" };
|
const client = { id: "matrix-client" };
|
||||||
|
const resolveTextChunkLimit = vi.fn<
|
||||||
|
(cfg: unknown, channel: unknown, accountId?: unknown) => number
|
||||||
|
>(() => 4000);
|
||||||
const logger = {
|
const logger = {
|
||||||
info: vi.fn(),
|
info: vi.fn(),
|
||||||
warn: vi.fn(),
|
warn: vi.fn(),
|
||||||
@@ -14,6 +17,7 @@ const hoisted = vi.hoisted(() => {
|
|||||||
callOrder,
|
callOrder,
|
||||||
client,
|
client,
|
||||||
logger,
|
logger,
|
||||||
|
resolveTextChunkLimit,
|
||||||
stopThreadBindingManager,
|
stopThreadBindingManager,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -60,7 +64,8 @@ vi.mock("../../runtime.js", () => ({
|
|||||||
buildMentionRegexes: () => [],
|
buildMentionRegexes: () => [],
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
resolveTextChunkLimit: () => 4000,
|
resolveTextChunkLimit: (cfg: unknown, channel: unknown, accountId?: unknown) =>
|
||||||
|
hoisted.resolveTextChunkLimit(cfg, channel, accountId),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
system: {
|
system: {
|
||||||
@@ -186,6 +191,7 @@ describe("monitorMatrixProvider", () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.resetModules();
|
vi.resetModules();
|
||||||
hoisted.callOrder.length = 0;
|
hoisted.callOrder.length = 0;
|
||||||
|
hoisted.resolveTextChunkLimit.mockReset().mockReturnValue(4000);
|
||||||
hoisted.stopThreadBindingManager.mockReset();
|
hoisted.stopThreadBindingManager.mockReset();
|
||||||
Object.values(hoisted.logger).forEach((mock) => mock.mockReset());
|
Object.values(hoisted.logger).forEach((mock) => mock.mockReset());
|
||||||
});
|
});
|
||||||
@@ -205,4 +211,18 @@ describe("monitorMatrixProvider", () => {
|
|||||||
]);
|
]);
|
||||||
expect(hoisted.stopThreadBindingManager).toHaveBeenCalledTimes(1);
|
expect(hoisted.stopThreadBindingManager).toHaveBeenCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("resolves text chunk limit for the effective Matrix account", async () => {
|
||||||
|
const { monitorMatrixProvider } = await import("./index.js");
|
||||||
|
const abortController = new AbortController();
|
||||||
|
abortController.abort();
|
||||||
|
|
||||||
|
await monitorMatrixProvider({ abortSignal: abortController.signal });
|
||||||
|
|
||||||
|
expect(hoisted.resolveTextChunkLimit).toHaveBeenCalledWith(
|
||||||
|
expect.anything(),
|
||||||
|
"matrix",
|
||||||
|
"default",
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
|||||||
const dmEnabled = dmConfig?.enabled ?? true;
|
const dmEnabled = dmConfig?.enabled ?? true;
|
||||||
const dmPolicyRaw = dmConfig?.policy ?? "pairing";
|
const dmPolicyRaw = dmConfig?.policy ?? "pairing";
|
||||||
const dmPolicy = allowlistOnly && dmPolicyRaw !== "disabled" ? "allowlist" : dmPolicyRaw;
|
const dmPolicy = allowlistOnly && dmPolicyRaw !== "disabled" ? "allowlist" : dmPolicyRaw;
|
||||||
const textLimit = core.channel.text.resolveTextChunkLimit(cfg, "matrix");
|
const textLimit = core.channel.text.resolveTextChunkLimit(cfg, "matrix", account.accountId);
|
||||||
const mediaMaxMb = opts.mediaMaxMb ?? accountConfig.mediaMaxMb ?? DEFAULT_MEDIA_MAX_MB;
|
const mediaMaxMb = opts.mediaMaxMb ?? accountConfig.mediaMaxMb ?? DEFAULT_MEDIA_MAX_MB;
|
||||||
const mediaMaxBytes = Math.max(1, mediaMaxMb) * 1024 * 1024;
|
const mediaMaxBytes = Math.max(1, mediaMaxMb) * 1024 * 1024;
|
||||||
const startupMs = Date.now();
|
const startupMs = Date.now();
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ const loadWebMediaMock = vi.fn().mockResolvedValue({
|
|||||||
});
|
});
|
||||||
const getImageMetadataMock = vi.fn().mockResolvedValue(null);
|
const getImageMetadataMock = vi.fn().mockResolvedValue(null);
|
||||||
const resizeToJpegMock = vi.fn();
|
const resizeToJpegMock = vi.fn();
|
||||||
|
const resolveTextChunkLimitMock = vi.fn<
|
||||||
|
(cfg: unknown, channel: unknown, accountId?: unknown) => number
|
||||||
|
>(() => 4000);
|
||||||
|
|
||||||
const runtimeStub = {
|
const runtimeStub = {
|
||||||
config: {
|
config: {
|
||||||
@@ -24,7 +27,8 @@ const runtimeStub = {
|
|||||||
},
|
},
|
||||||
channel: {
|
channel: {
|
||||||
text: {
|
text: {
|
||||||
resolveTextChunkLimit: () => 4000,
|
resolveTextChunkLimit: (cfg: unknown, channel: unknown, accountId?: unknown) =>
|
||||||
|
resolveTextChunkLimitMock(cfg, channel, accountId),
|
||||||
resolveChunkMode: () => "length",
|
resolveChunkMode: () => "length",
|
||||||
chunkMarkdownText: (text: string) => (text ? [text] : []),
|
chunkMarkdownText: (text: string) => (text ? [text] : []),
|
||||||
chunkMarkdownTextWithMode: (text: string) => (text ? [text] : []),
|
chunkMarkdownTextWithMode: (text: string) => (text ? [text] : []),
|
||||||
@@ -70,6 +74,7 @@ describe("sendMessageMatrix media", () => {
|
|||||||
});
|
});
|
||||||
getImageMetadataMock.mockReset().mockResolvedValue(null);
|
getImageMetadataMock.mockReset().mockResolvedValue(null);
|
||||||
resizeToJpegMock.mockReset();
|
resizeToJpegMock.mockReset();
|
||||||
|
resolveTextChunkLimitMock.mockReset().mockReturnValue(4000);
|
||||||
setMatrixRuntime(runtimeStub);
|
setMatrixRuntime(runtimeStub);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -235,6 +240,17 @@ describe("sendMessageMatrix threads", () => {
|
|||||||
"m.in_reply_to": { event_id: "$thread" },
|
"m.in_reply_to": { event_id: "$thread" },
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("resolves text chunk limit using the active Matrix account", async () => {
|
||||||
|
const { client } = makeClient();
|
||||||
|
|
||||||
|
await sendMessageMatrix("room:!room:example", "hello", {
|
||||||
|
client,
|
||||||
|
accountId: "ops",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(resolveTextChunkLimitMock).toHaveBeenCalledWith(expect.anything(), "matrix", "ops");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("voteMatrixPoll", () => {
|
describe("voteMatrixPoll", () => {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export async function sendMessageMatrix(
|
|||||||
trimmedMessage,
|
trimmedMessage,
|
||||||
tableMode,
|
tableMode,
|
||||||
);
|
);
|
||||||
const textLimit = getCore().channel.text.resolveTextChunkLimit(cfg, "matrix");
|
const textLimit = getCore().channel.text.resolveTextChunkLimit(cfg, "matrix", opts.accountId);
|
||||||
const chunkLimit = Math.min(textLimit, MATRIX_TEXT_LIMIT);
|
const chunkLimit = Math.min(textLimit, MATRIX_TEXT_LIMIT);
|
||||||
const chunkMode = getCore().channel.text.resolveChunkMode(cfg, "matrix", opts.accountId);
|
const chunkMode = getCore().channel.text.resolveChunkMode(cfg, "matrix", opts.accountId);
|
||||||
const chunks = getCore().channel.text.chunkMarkdownTextWithMode(
|
const chunks = getCore().channel.text.chunkMarkdownTextWithMode(
|
||||||
|
|||||||
@@ -161,6 +161,35 @@ describe("matrix onboarding", () => {
|
|||||||
expect(noteText).toContain("MATRIX_<ACCOUNT_ID>_DEVICE_NAME");
|
expect(noteText).toContain("MATRIX_<ACCOUNT_ID>_DEVICE_NAME");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("resolves status using the overridden Matrix account", async () => {
|
||||||
|
const status = await matrixOnboardingAdapter.getStatus({
|
||||||
|
cfg: {
|
||||||
|
channels: {
|
||||||
|
matrix: {
|
||||||
|
defaultAccount: "default",
|
||||||
|
accounts: {
|
||||||
|
default: {
|
||||||
|
homeserver: "https://matrix.default.example.org",
|
||||||
|
},
|
||||||
|
ops: {
|
||||||
|
homeserver: "https://matrix.ops.example.org",
|
||||||
|
accessToken: "ops-token",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as CoreConfig,
|
||||||
|
options: undefined,
|
||||||
|
accountOverrides: {
|
||||||
|
matrix: "ops",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(status.configured).toBe(true);
|
||||||
|
expect(status.selectionHint).toBe("configured");
|
||||||
|
expect(status.statusLines).toEqual(["Matrix: configured"]);
|
||||||
|
});
|
||||||
|
|
||||||
it("writes allowlists and room access to the selected Matrix account", async () => {
|
it("writes allowlists and room access to the selected Matrix account", async () => {
|
||||||
setMatrixRuntime({
|
setMatrixRuntime({
|
||||||
state: {
|
state: {
|
||||||
|
|||||||
@@ -492,10 +492,10 @@ async function runMatrixConfigure(params: {
|
|||||||
|
|
||||||
export const matrixOnboardingAdapter: ChannelOnboardingAdapter = {
|
export const matrixOnboardingAdapter: ChannelOnboardingAdapter = {
|
||||||
channel,
|
channel,
|
||||||
getStatus: async ({ cfg }) => {
|
getStatus: async ({ cfg, accountOverrides }) => {
|
||||||
const account = resolveMatrixAccount({
|
const account = resolveMatrixAccount({
|
||||||
cfg: cfg as CoreConfig,
|
cfg: cfg as CoreConfig,
|
||||||
accountId: resolveMatrixOnboardingAccountId(cfg as CoreConfig),
|
accountId: resolveMatrixOnboardingAccountId(cfg as CoreConfig, accountOverrides[channel]),
|
||||||
});
|
});
|
||||||
const configured = account.configured;
|
const configured = account.configured;
|
||||||
const sdkReady = isMatrixSdkAvailable();
|
const sdkReady = isMatrixSdkAvailable();
|
||||||
|
|||||||
909
pnpm-lock.yaml
generated
909
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user