mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 13:10:43 +00:00
perf(matrix): narrow register-time runtime surface (#69782)
Merged via squash.
Prepared head SHA: ec32828b52
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
committed by
GitHub
parent
acb27bac3a
commit
13636c4521
@@ -22,7 +22,7 @@ vi.mock("./src/cli.js", () => {
|
||||
});
|
||||
|
||||
vi.mock("./plugin-entry.handlers.runtime.js", () => runtimeMocks);
|
||||
vi.mock("./runtime-api.js", () => ({ setMatrixRuntime: runtimeMocks.setMatrixRuntime }));
|
||||
vi.mock("./runtime-setter-api.js", () => ({ setMatrixRuntime: runtimeMocks.setMatrixRuntime }));
|
||||
|
||||
describe("matrix plugin", () => {
|
||||
it("registers matrix CLI through a descriptor-backed lazy registrar", async () => {
|
||||
@@ -66,6 +66,7 @@ describe("matrix plugin", () => {
|
||||
expect(entry.kind).toBe("bundled-channel-entry");
|
||||
expect(entry.id).toBe("matrix");
|
||||
expect(entry.name).toBe("Matrix");
|
||||
expect(entry.setChannelRuntime).toEqual(expect.any(Function));
|
||||
});
|
||||
|
||||
it("registers subagent lifecycle hooks during full runtime registration", () => {
|
||||
|
||||
@@ -77,7 +77,7 @@ export default defineBundledChannelEntry({
|
||||
exportName: "channelSecrets",
|
||||
},
|
||||
runtime: {
|
||||
specifier: "./runtime-api.js",
|
||||
specifier: "./runtime-setter-api.js",
|
||||
exportName: "setMatrixRuntime",
|
||||
},
|
||||
registerCliMetadata: registerMatrixCliMetadata,
|
||||
|
||||
3
extensions/matrix/runtime-setter-api.ts
Normal file
3
extensions/matrix/runtime-setter-api.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
// Narrow entry point for setMatrixRuntime. The full runtime-api barrel is kept
|
||||
// for external/runtime callers, but bundled plugin register only needs this.
|
||||
export { setMatrixRuntime } from "./src/runtime.js";
|
||||
@@ -11,7 +11,7 @@ export default defineBundledChannelSetupEntry({
|
||||
exportName: "channelSecrets",
|
||||
},
|
||||
runtime: {
|
||||
specifier: "./runtime-api.js",
|
||||
specifier: "./runtime-setter-api.js",
|
||||
exportName: "setMatrixRuntime",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import { Type } from "@sinclair/typebox";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
|
||||
import { requiresExplicitMatrixDefaultAccount } from "./account-selection.js";
|
||||
import { resolveDefaultMatrixAccountId, resolveMatrixAccount } from "./matrix/accounts.js";
|
||||
import {
|
||||
createActionGate,
|
||||
readNumberParam,
|
||||
readStringParam,
|
||||
ToolAuthorizationError,
|
||||
type ChannelMessageActionAdapter,
|
||||
type ChannelMessageActionContext,
|
||||
type ChannelMessageActionName,
|
||||
type ChannelMessageToolDiscovery,
|
||||
} from "./runtime-api.js";
|
||||
} from "openclaw/plugin-sdk/channel-actions";
|
||||
import type {
|
||||
ChannelMessageActionAdapter,
|
||||
ChannelMessageActionContext,
|
||||
ChannelMessageActionName,
|
||||
ChannelMessageToolDiscovery,
|
||||
} from "openclaw/plugin-sdk/channel-contract";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { extractToolSend } from "openclaw/plugin-sdk/tool-send";
|
||||
import { requiresExplicitMatrixDefaultAccount } from "./account-selection.js";
|
||||
import { resolveDefaultMatrixAccountId, resolveMatrixAccount } from "./matrix/accounts.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
|
||||
const MATRIX_PLUGIN_HANDLED_ACTIONS = new Set<ChannelMessageActionName>([
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
createScopedDmSecurityResolver,
|
||||
} from "openclaw/plugin-sdk/channel-config-helpers";
|
||||
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/channel-config-primitives";
|
||||
import type { ChannelDoctorAdapter } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { createChatChannelPlugin, type ChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
||||
import {
|
||||
createAllowlistProviderOpenWarningCollector,
|
||||
@@ -15,7 +16,6 @@ import {
|
||||
createResolvedDirectoryEntriesLister,
|
||||
createRuntimeDirectoryLiveAdapter,
|
||||
} from "openclaw/plugin-sdk/directory-runtime";
|
||||
import { buildTrafficStatusSummary } from "openclaw/plugin-sdk/extension-shared";
|
||||
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
|
||||
import { createRuntimeOutboundDelegates } from "openclaw/plugin-sdk/outbound-runtime";
|
||||
import {
|
||||
@@ -34,7 +34,10 @@ import { matrixApprovalCapability } from "./approval-native.js";
|
||||
import { createMatrixPairingText, createMatrixProbeAccount } from "./channel-account-paths.js";
|
||||
import { DEFAULT_ACCOUNT_ID, matrixConfigAdapter } from "./config-adapter.js";
|
||||
import { MatrixConfigSchema } from "./config-schema.js";
|
||||
import { matrixDoctor } from "./doctor.js";
|
||||
import {
|
||||
legacyConfigRules as MATRIX_LEGACY_CONFIG_RULES,
|
||||
normalizeCompatibilityConfig as normalizeMatrixCompatibilityConfig,
|
||||
} from "./doctor-contract.js";
|
||||
import { shouldSuppressLocalMatrixExecApprovalPrompt } from "./exec-approvals.js";
|
||||
import {
|
||||
resolveMatrixGroupRequireMention,
|
||||
@@ -64,14 +67,17 @@ import {
|
||||
resolveSingleAccountPromotionTarget,
|
||||
singleAccountKeysToMove,
|
||||
} from "./setup-contract.js";
|
||||
import { matrixSetupAdapter } from "./setup-core.js";
|
||||
import { matrixSetupWizard } from "./setup-surface.js";
|
||||
import { createMatrixSetupWizardProxy, matrixSetupAdapter } from "./setup-core.js";
|
||||
import { runMatrixStartupMaintenance } from "./startup-maintenance.js";
|
||||
import { resolveMatrixInboundConversation } from "./thread-binding-api.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
// Mutex for serializing account startup (workaround for concurrent dynamic import race condition)
|
||||
let matrixStartupLock: Promise<void> = Promise.resolve();
|
||||
|
||||
const loadMatrixSetupWizard = createLazyRuntimeNamedExport(
|
||||
() => import("./setup-surface.js"),
|
||||
"matrixSetupWizard",
|
||||
);
|
||||
const loadMatrixChannelRuntime = createLazyRuntimeNamedExport(
|
||||
() => import("./channel.runtime.js"),
|
||||
"matrixChannelRuntime",
|
||||
@@ -88,6 +94,31 @@ const meta = {
|
||||
quickstartAllowFrom: true,
|
||||
};
|
||||
|
||||
function buildMatrixTrafficStatusSummary(
|
||||
snapshot?: {
|
||||
lastInboundAt?: number | null;
|
||||
lastOutboundAt?: number | null;
|
||||
} | null,
|
||||
) {
|
||||
return {
|
||||
lastInboundAt: snapshot?.lastInboundAt ?? null,
|
||||
lastOutboundAt: snapshot?.lastOutboundAt ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
const matrixDoctor: ChannelDoctorAdapter = {
|
||||
dmAllowFromMode: "nestedOnly",
|
||||
groupModel: "sender",
|
||||
groupAllowFromFallbackToAllowFrom: false,
|
||||
warnOnEmptyGroupSenderAllowlist: true,
|
||||
legacyConfigRules: MATRIX_LEGACY_CONFIG_RULES,
|
||||
normalizeCompatibilityConfig: normalizeMatrixCompatibilityConfig,
|
||||
runConfigSequence: async ({ cfg, env, shouldRepair }) =>
|
||||
await (await import("./doctor.js")).runMatrixDoctorSequence({ cfg, env, shouldRepair }),
|
||||
cleanStaleConfig: async ({ cfg }) =>
|
||||
await (await import("./doctor.js")).cleanStaleMatrixPluginConfig(cfg),
|
||||
};
|
||||
|
||||
const listMatrixDirectoryPeersFromConfig =
|
||||
createResolvedDirectoryEntriesLister<ResolvedMatrixAccount>({
|
||||
kind: "user",
|
||||
@@ -294,7 +325,9 @@ export const matrixPlugin: ChannelPlugin<ResolvedMatrixAccount, MatrixProbe> =
|
||||
base: {
|
||||
id: "matrix",
|
||||
meta,
|
||||
setupWizard: matrixSetupWizard,
|
||||
setupWizard: createMatrixSetupWizardProxy(async () => ({
|
||||
matrixSetupWizard: await loadMatrixSetupWizard(),
|
||||
})),
|
||||
capabilities: {
|
||||
chatTypes: ["direct", "group", "thread"],
|
||||
polls: true,
|
||||
@@ -432,7 +465,7 @@ export const matrixPlugin: ChannelPlugin<ResolvedMatrixAccount, MatrixProbe> =
|
||||
extra: {
|
||||
baseUrl: account.homeserver,
|
||||
lastProbeAt: runtime?.lastProbeAt ?? null,
|
||||
...buildTrafficStatusSummary(runtime),
|
||||
...buildMatrixTrafficStatusSummary(runtime),
|
||||
},
|
||||
}),
|
||||
}),
|
||||
|
||||
@@ -5,7 +5,6 @@ import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime";
|
||||
import {
|
||||
type ChannelSetupDmPolicy,
|
||||
type ChannelSetupWizardAdapter,
|
||||
addWildcardAllowFrom,
|
||||
formatDocsLink,
|
||||
hasConfiguredSecretInput,
|
||||
mergeAllowFromEntries,
|
||||
@@ -36,6 +35,7 @@ import {
|
||||
import { resolveMatrixConfigFieldPath, updateMatrixAccountConfig } from "./matrix/config-update.js";
|
||||
import { ensureMatrixSdkInstalled, isMatrixSdkAvailable } from "./matrix/deps.js";
|
||||
import { moveSingleMatrixAccountConfigToNamedAccount } from "./setup-config.js";
|
||||
import { resolveMatrixSetupDmAllowFrom } from "./setup-dm-policy.js";
|
||||
import type { CoreConfig, MatrixConfig } from "./types.js";
|
||||
|
||||
const channel = "matrix" as const;
|
||||
@@ -84,12 +84,12 @@ function setMatrixDmPolicy(cfg: CoreConfig, policy: DmPolicy, accountId?: string
|
||||
cfg,
|
||||
accountId: resolvedAccountId,
|
||||
});
|
||||
const allowFrom = policy === "open" ? addWildcardAllowFrom(existing.dm?.allowFrom) : undefined;
|
||||
const allowFrom = resolveMatrixSetupDmAllowFrom(policy, existing.dm?.allowFrom);
|
||||
return updateMatrixAccountConfig(cfg, resolvedAccountId, {
|
||||
dm: {
|
||||
...existing.dm,
|
||||
policy,
|
||||
...(allowFrom ? { allowFrom } : {}),
|
||||
allowFrom,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { matrixSetupAdapter } from "./setup-core.js";
|
||||
import type { ChannelSetupWizardAdapter } from "openclaw/plugin-sdk/setup";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { createMatrixSetupWizardProxy, matrixSetupAdapter } from "./setup-core.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
|
||||
function applyOpsAccountConfig(cfg: CoreConfig): CoreConfig {
|
||||
@@ -35,6 +36,138 @@ function expectOpsAccount(next: CoreConfig): void {
|
||||
});
|
||||
}
|
||||
|
||||
function makeFakeSetupWizard(
|
||||
overrides: Partial<ChannelSetupWizardAdapter> = {},
|
||||
): ChannelSetupWizardAdapter {
|
||||
return {
|
||||
channel: "matrix",
|
||||
getStatus: vi.fn(async () => ({
|
||||
channel: "matrix",
|
||||
configured: false,
|
||||
statusLines: [],
|
||||
})),
|
||||
configure: vi.fn(async ({ cfg }) => ({ cfg })),
|
||||
...overrides,
|
||||
} as ChannelSetupWizardAdapter;
|
||||
}
|
||||
|
||||
describe("createMatrixSetupWizardProxy", () => {
|
||||
it("does not load the setup surface when constructing the proxy", () => {
|
||||
const loader = vi.fn(async () => ({ matrixSetupWizard: makeFakeSetupWizard() }));
|
||||
|
||||
const proxy = createMatrixSetupWizardProxy(loader);
|
||||
|
||||
expect(proxy.channel).toBe("matrix");
|
||||
expect(loader).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("loads the setup surface when setup status is requested", async () => {
|
||||
const status = {
|
||||
channel: "matrix" as const,
|
||||
configured: true,
|
||||
statusLines: ["Matrix: configured"],
|
||||
};
|
||||
const getStatus = vi.fn(async () => status);
|
||||
const configure = vi.fn(async ({ cfg }) => ({ cfg }));
|
||||
const loader = vi.fn(async () => ({
|
||||
matrixSetupWizard: makeFakeSetupWizard({ configure, getStatus }),
|
||||
}));
|
||||
const proxy = createMatrixSetupWizardProxy(loader);
|
||||
const cfg = { channels: { matrix: {} } } as CoreConfig;
|
||||
|
||||
const result = await proxy.getStatus({ cfg, accountOverrides: {} });
|
||||
const configured = await proxy.configure({
|
||||
cfg,
|
||||
runtime: {} as never,
|
||||
prompter: {} as never,
|
||||
forceAllowFrom: false,
|
||||
accountOverrides: {},
|
||||
shouldPromptAccountIds: false,
|
||||
});
|
||||
|
||||
expect(loader).toHaveBeenCalledTimes(1);
|
||||
expect(getStatus).toHaveBeenCalledWith({ cfg, accountOverrides: {} });
|
||||
expect(configure).toHaveBeenCalledTimes(1);
|
||||
expect(result).toBe(status);
|
||||
expect(configured).toEqual({ cfg });
|
||||
});
|
||||
|
||||
it("keeps sync dmPolicy helpers local and lazy-loads only promptAllowFrom", async () => {
|
||||
const promptAllowFrom = vi.fn(async ({ cfg }) => cfg);
|
||||
const loader = vi.fn(async () => ({
|
||||
matrixSetupWizard: makeFakeSetupWizard({
|
||||
dmPolicy: {
|
||||
label: "Matrix",
|
||||
channel: "matrix",
|
||||
policyKey: "unused",
|
||||
allowFromKey: "unused",
|
||||
getCurrent: () => "pairing",
|
||||
setPolicy: (cfg) => cfg,
|
||||
promptAllowFrom,
|
||||
},
|
||||
}),
|
||||
}));
|
||||
const proxy = createMatrixSetupWizardProxy(loader);
|
||||
const cfg = {
|
||||
channels: {
|
||||
matrix: {
|
||||
accounts: {
|
||||
ops: {
|
||||
dm: {
|
||||
allowFrom: [" @ops:example.org ", "", "*"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as CoreConfig;
|
||||
|
||||
expect(proxy.dmPolicy?.getCurrent(cfg, "ops")).toBe("pairing");
|
||||
const next = proxy.dmPolicy?.setPolicy(cfg, "open", "ops") as CoreConfig;
|
||||
|
||||
expect(next.channels?.matrix?.accounts?.ops?.dm).toMatchObject({
|
||||
policy: "open",
|
||||
allowFrom: ["@ops:example.org", "*"],
|
||||
});
|
||||
expect(loader).not.toHaveBeenCalled();
|
||||
|
||||
await proxy.dmPolicy?.promptAllowFrom?.({
|
||||
cfg,
|
||||
prompter: {} as never,
|
||||
});
|
||||
|
||||
expect(loader).toHaveBeenCalledTimes(1);
|
||||
expect(promptAllowFrom).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("removes wildcard allowFrom when switching from open to a restrictive policy", () => {
|
||||
const loader = vi.fn(async () => ({ matrixSetupWizard: makeFakeSetupWizard() }));
|
||||
const proxy = createMatrixSetupWizardProxy(loader);
|
||||
const cfg = {
|
||||
channels: {
|
||||
matrix: {
|
||||
accounts: {
|
||||
ops: {
|
||||
dm: {
|
||||
policy: "open",
|
||||
allowFrom: ["*", " @ops:example.org "],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} as CoreConfig;
|
||||
|
||||
const next = proxy.dmPolicy?.setPolicy(cfg, "allowlist", "ops") as CoreConfig;
|
||||
|
||||
expect(next.channels?.matrix?.accounts?.ops?.dm).toMatchObject({
|
||||
policy: "allowlist",
|
||||
allowFrom: ["@ops:example.org"],
|
||||
});
|
||||
expect(loader).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("matrixSetupAdapter", () => {
|
||||
it("moves legacy default config before writing a named account", () => {
|
||||
const cfg = {
|
||||
|
||||
@@ -1,18 +1,114 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
||||
import {
|
||||
DEFAULT_ACCOUNT_ID,
|
||||
type DmPolicy,
|
||||
normalizeAccountId,
|
||||
prepareScopedSetupConfig,
|
||||
type ChannelSetupAdapter,
|
||||
type ChannelSetupWizardAdapter,
|
||||
} from "openclaw/plugin-sdk/setup";
|
||||
import { resolveDefaultMatrixAccountId, resolveMatrixAccountConfig } from "./matrix/accounts.js";
|
||||
import { resolveMatrixConfigFieldPath, updateMatrixAccountConfig } from "./matrix/config-update.js";
|
||||
import { applyMatrixSetupAccountConfig, validateMatrixSetupInput } from "./setup-config.js";
|
||||
import { resolveMatrixSetupDmAllowFrom } from "./setup-dm-policy.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
|
||||
const channel = "matrix" as const;
|
||||
type MatrixSetupWizardModule = { matrixSetupWizard: ChannelSetupWizardAdapter };
|
||||
|
||||
function resolveMatrixSetupAccountId(params: { accountId?: string; name?: string }): string {
|
||||
return normalizeAccountId(params.accountId?.trim() || params.name?.trim() || DEFAULT_ACCOUNT_ID);
|
||||
}
|
||||
|
||||
function resolveMatrixSetupWizardAccountId(cfg: CoreConfig, accountId?: string): string {
|
||||
return normalizeAccountId(
|
||||
accountId?.trim() || resolveDefaultMatrixAccountId(cfg) || DEFAULT_ACCOUNT_ID,
|
||||
);
|
||||
}
|
||||
|
||||
function setMatrixDmPolicy(cfg: CoreConfig, policy: DmPolicy, accountId?: string): CoreConfig {
|
||||
const resolvedAccountId = resolveMatrixSetupWizardAccountId(cfg, accountId);
|
||||
const existing = resolveMatrixAccountConfig({
|
||||
cfg,
|
||||
accountId: resolvedAccountId,
|
||||
});
|
||||
const allowFrom = resolveMatrixSetupDmAllowFrom(policy, existing.dm?.allowFrom);
|
||||
return updateMatrixAccountConfig(cfg, resolvedAccountId, {
|
||||
dm: {
|
||||
...existing.dm,
|
||||
policy,
|
||||
allowFrom,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function createMatrixSetupWizardProxy(
|
||||
loadWizardModule: () => Promise<MatrixSetupWizardModule>,
|
||||
): ChannelSetupWizardAdapter {
|
||||
let wizardPromise: Promise<ChannelSetupWizardAdapter> | null = null;
|
||||
const loadWizard = () => {
|
||||
wizardPromise ??= loadWizardModule().then((module) => module.matrixSetupWizard);
|
||||
return wizardPromise;
|
||||
};
|
||||
return {
|
||||
channel,
|
||||
getStatus: async (ctx) => await (await loadWizard()).getStatus(ctx),
|
||||
configure: async (ctx) => await (await loadWizard()).configure(ctx),
|
||||
configureInteractive: async (ctx) => {
|
||||
const wizard = await loadWizard();
|
||||
return await (wizard.configureInteractive ?? wizard.configure)(ctx);
|
||||
},
|
||||
configureWhenConfigured: async (ctx) => {
|
||||
const wizard = await loadWizard();
|
||||
return await (
|
||||
wizard.configureWhenConfigured ??
|
||||
wizard.configureInteractive ??
|
||||
wizard.configure
|
||||
)(ctx);
|
||||
},
|
||||
afterConfigWritten: async (ctx) => await (await loadWizard()).afterConfigWritten?.(ctx),
|
||||
dmPolicy: {
|
||||
label: "Matrix",
|
||||
channel,
|
||||
policyKey: "channels.matrix.dm.policy",
|
||||
allowFromKey: "channels.matrix.dm.allowFrom",
|
||||
resolveConfigKeys: (cfg, accountId) => {
|
||||
const resolvedAccountId = resolveMatrixSetupWizardAccountId(cfg as CoreConfig, accountId);
|
||||
return {
|
||||
policyKey: resolveMatrixConfigFieldPath(
|
||||
cfg as CoreConfig,
|
||||
resolvedAccountId,
|
||||
"dm.policy",
|
||||
),
|
||||
allowFromKey: resolveMatrixConfigFieldPath(
|
||||
cfg as CoreConfig,
|
||||
resolvedAccountId,
|
||||
"dm.allowFrom",
|
||||
),
|
||||
};
|
||||
},
|
||||
getCurrent: (cfg, accountId) =>
|
||||
resolveMatrixAccountConfig({
|
||||
cfg: cfg as CoreConfig,
|
||||
accountId: resolveMatrixSetupWizardAccountId(cfg as CoreConfig, accountId),
|
||||
}).dm?.policy ?? "pairing",
|
||||
setPolicy: (cfg, policy, accountId) =>
|
||||
setMatrixDmPolicy(cfg as CoreConfig, policy, accountId) as OpenClawConfig,
|
||||
promptAllowFrom: async (params) => {
|
||||
const promptAllowFrom = (await loadWizard()).dmPolicy?.promptAllowFrom;
|
||||
return promptAllowFrom ? await promptAllowFrom(params) : params.cfg;
|
||||
},
|
||||
},
|
||||
disable: (cfg) => ({
|
||||
...(cfg as CoreConfig),
|
||||
channels: {
|
||||
...(cfg as CoreConfig).channels,
|
||||
matrix: { ...(cfg as CoreConfig).channels?.matrix, enabled: false },
|
||||
},
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export const matrixSetupAdapter: ChannelSetupAdapter = {
|
||||
resolveAccountId: ({ accountId, input }) =>
|
||||
resolveMatrixSetupAccountId({
|
||||
|
||||
15
extensions/matrix/src/setup-dm-policy.ts
Normal file
15
extensions/matrix/src/setup-dm-policy.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { DmPolicy } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { addWildcardAllowFrom, normalizeAllowFromEntries } from "openclaw/plugin-sdk/setup";
|
||||
import type { MatrixConfig } from "./types.js";
|
||||
|
||||
type MatrixDmAllowFrom = NonNullable<MatrixConfig["dm"]>["allowFrom"];
|
||||
|
||||
export function resolveMatrixSetupDmAllowFrom(
|
||||
policy: DmPolicy,
|
||||
allowFrom: MatrixDmAllowFrom,
|
||||
): string[] {
|
||||
if (policy === "open") {
|
||||
return addWildcardAllowFrom(allowFrom);
|
||||
}
|
||||
return normalizeAllowFromEntries(allowFrom ?? []).filter((entry) => entry !== "*");
|
||||
}
|
||||
Reference in New Issue
Block a user