mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-10 16:51:13 +00:00
perf(memory): trim matrix and telegram runtime seams
This commit is contained in:
@@ -2,11 +2,14 @@ import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
||||
import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/account-id";
|
||||
import {
|
||||
listConfiguredAccountIds,
|
||||
resolveMergedAccountConfig,
|
||||
resolveNormalizedAccountEntry,
|
||||
} from "openclaw/plugin-sdk/account-resolution";
|
||||
import { hasConfiguredSecretInput } from "openclaw/plugin-sdk/secret-input";
|
||||
import type { CoreConfig, MatrixAccountConfig, MatrixConfig } from "../types.js";
|
||||
|
||||
type MatrixRoomEntries = Record<string, NonNullable<MatrixConfig["groups"]>[string]>;
|
||||
|
||||
export function resolveMatrixBaseConfig(cfg: CoreConfig): MatrixConfig {
|
||||
return cfg.channels?.matrix ?? {};
|
||||
}
|
||||
@@ -19,6 +22,51 @@ function resolveMatrixAccountsMap(cfg: CoreConfig): Readonly<Record<string, Matr
|
||||
return accounts;
|
||||
}
|
||||
|
||||
function selectInheritedMatrixRoomEntries(params: {
|
||||
entries: MatrixRoomEntries | undefined;
|
||||
accountId: string;
|
||||
}): MatrixRoomEntries | undefined {
|
||||
const entries = params.entries;
|
||||
if (!entries) {
|
||||
return undefined;
|
||||
}
|
||||
const selected = Object.fromEntries(
|
||||
Object.entries(entries).filter(([, value]) => {
|
||||
const scopedAccount =
|
||||
typeof value?.account === "string" ? normalizeAccountId(value.account) : undefined;
|
||||
return scopedAccount === undefined || scopedAccount === params.accountId;
|
||||
}),
|
||||
) as MatrixRoomEntries;
|
||||
return Object.keys(selected).length > 0 ? selected : undefined;
|
||||
}
|
||||
|
||||
function mergeMatrixRoomEntries(
|
||||
inherited: MatrixRoomEntries | undefined,
|
||||
accountEntries: MatrixRoomEntries | undefined,
|
||||
hasAccountOverride: boolean,
|
||||
): MatrixRoomEntries | undefined {
|
||||
if (!inherited && !accountEntries) {
|
||||
return undefined;
|
||||
}
|
||||
if (hasAccountOverride && Object.keys(accountEntries ?? {}).length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const merged: MatrixRoomEntries = {
|
||||
...(inherited ?? {}),
|
||||
};
|
||||
for (const [key, value] of Object.entries(accountEntries ?? {})) {
|
||||
const inheritedValue = merged[key];
|
||||
merged[key] =
|
||||
inheritedValue && value
|
||||
? {
|
||||
...inheritedValue,
|
||||
...value,
|
||||
}
|
||||
: (value ?? inheritedValue);
|
||||
}
|
||||
return Object.keys(merged).length > 0 ? merged : undefined;
|
||||
}
|
||||
|
||||
export function listNormalizedMatrixAccountIds(cfg: CoreConfig): string[] {
|
||||
return listConfiguredAccountIds({
|
||||
accounts: resolveMatrixAccountsMap(cfg),
|
||||
@@ -58,3 +106,45 @@ export function hasExplicitMatrixAccountConfig(cfg: CoreConfig, accountId: strin
|
||||
typeof matrix.avatarUrl === "string"
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveMatrixAccountConfig(params: {
|
||||
cfg: CoreConfig;
|
||||
accountId?: string | null;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): MatrixConfig {
|
||||
const accountId = normalizeAccountId(params.accountId);
|
||||
const base = resolveMatrixBaseConfig(params.cfg);
|
||||
const merged = resolveMergedAccountConfig<MatrixConfig>({
|
||||
channelConfig: base,
|
||||
accounts: params.cfg.channels?.matrix?.accounts as
|
||||
| Record<string, Partial<MatrixConfig>>
|
||||
| undefined,
|
||||
accountId,
|
||||
normalizeAccountId,
|
||||
nestedObjectKeys: ["dm", "actions"],
|
||||
});
|
||||
const accountConfig = findMatrixAccountConfig(params.cfg, accountId);
|
||||
const groups = mergeMatrixRoomEntries(
|
||||
selectInheritedMatrixRoomEntries({
|
||||
entries: base.groups,
|
||||
accountId,
|
||||
}),
|
||||
accountConfig?.groups,
|
||||
Boolean(accountConfig && Object.hasOwn(accountConfig, "groups")),
|
||||
);
|
||||
const rooms = mergeMatrixRoomEntries(
|
||||
selectInheritedMatrixRoomEntries({
|
||||
entries: base.rooms,
|
||||
accountId,
|
||||
}),
|
||||
accountConfig?.rooms,
|
||||
Boolean(accountConfig && Object.hasOwn(accountConfig, "rooms")),
|
||||
);
|
||||
// Room maps need custom scoping, so keep the generic merge for all other fields.
|
||||
const { groups: _ignoredGroups, rooms: _ignoredRooms, ...rest } = merged;
|
||||
return {
|
||||
...rest,
|
||||
...(groups ? { groups } : {}),
|
||||
...(rooms ? { rooms } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,62 +1,18 @@
|
||||
import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "openclaw/plugin-sdk/account-id";
|
||||
import { resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
|
||||
import { hasConfiguredSecretInput } from "openclaw/plugin-sdk/secret-input";
|
||||
import {
|
||||
resolveConfiguredMatrixAccountIds,
|
||||
resolveMatrixDefaultOrOnlyAccountId,
|
||||
} from "../account-selection.js";
|
||||
import type { CoreConfig, MatrixConfig } from "../types.js";
|
||||
import { findMatrixAccountConfig, resolveMatrixBaseConfig } from "./account-config.js";
|
||||
import {
|
||||
findMatrixAccountConfig,
|
||||
resolveMatrixAccountConfig,
|
||||
resolveMatrixBaseConfig,
|
||||
} from "./account-config.js";
|
||||
import { resolveMatrixConfigForAccount } from "./client.js";
|
||||
import { credentialsMatchConfig, loadMatrixCredentials } from "./credentials-read.js";
|
||||
|
||||
type MatrixRoomEntries = Record<string, NonNullable<MatrixConfig["groups"]>[string]>;
|
||||
|
||||
function selectInheritedMatrixRoomEntries(params: {
|
||||
entries: MatrixRoomEntries | undefined;
|
||||
accountId: string;
|
||||
}): MatrixRoomEntries | undefined {
|
||||
const entries = params.entries;
|
||||
if (!entries) {
|
||||
return undefined;
|
||||
}
|
||||
const selected = Object.fromEntries(
|
||||
Object.entries(entries).filter(([, value]) => {
|
||||
const scopedAccount =
|
||||
typeof value?.account === "string" ? normalizeAccountId(value.account) : undefined;
|
||||
return scopedAccount === undefined || scopedAccount === params.accountId;
|
||||
}),
|
||||
) as MatrixRoomEntries;
|
||||
return Object.keys(selected).length > 0 ? selected : undefined;
|
||||
}
|
||||
|
||||
function mergeMatrixRoomEntries(
|
||||
inherited: MatrixRoomEntries | undefined,
|
||||
accountEntries: MatrixRoomEntries | undefined,
|
||||
hasAccountOverride: boolean,
|
||||
): MatrixRoomEntries | undefined {
|
||||
if (!inherited && !accountEntries) {
|
||||
return undefined;
|
||||
}
|
||||
if (hasAccountOverride && Object.keys(accountEntries ?? {}).length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
const merged: MatrixRoomEntries = {
|
||||
...(inherited ?? {}),
|
||||
};
|
||||
for (const [key, value] of Object.entries(accountEntries ?? {})) {
|
||||
const inheritedValue = merged[key];
|
||||
merged[key] =
|
||||
inheritedValue && value
|
||||
? {
|
||||
...inheritedValue,
|
||||
...value,
|
||||
}
|
||||
: (value ?? inheritedValue);
|
||||
}
|
||||
return Object.keys(merged).length > 0 ? merged : undefined;
|
||||
}
|
||||
|
||||
export type ResolvedMatrixAccount = {
|
||||
accountId: string;
|
||||
enabled: boolean;
|
||||
@@ -177,45 +133,4 @@ export function resolveMatrixAccount(params: {
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveMatrixAccountConfig(params: {
|
||||
cfg: CoreConfig;
|
||||
accountId?: string | null;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
}): MatrixConfig {
|
||||
const env = params.env ?? process.env;
|
||||
const accountId = normalizeAccountId(params.accountId);
|
||||
const base = resolveMatrixBaseConfig(params.cfg);
|
||||
const merged = resolveMergedAccountConfig<MatrixConfig>({
|
||||
channelConfig: base,
|
||||
accounts: params.cfg.channels?.matrix?.accounts as
|
||||
| Record<string, Partial<MatrixConfig>>
|
||||
| undefined,
|
||||
accountId,
|
||||
normalizeAccountId,
|
||||
nestedObjectKeys: ["dm", "actions"],
|
||||
});
|
||||
const accountConfig = findMatrixAccountConfig(params.cfg, accountId);
|
||||
const groups = mergeMatrixRoomEntries(
|
||||
selectInheritedMatrixRoomEntries({
|
||||
entries: base.groups,
|
||||
accountId,
|
||||
}),
|
||||
accountConfig?.groups,
|
||||
Boolean(accountConfig && Object.hasOwn(accountConfig, "groups")),
|
||||
);
|
||||
const rooms = mergeMatrixRoomEntries(
|
||||
selectInheritedMatrixRoomEntries({
|
||||
entries: base.rooms,
|
||||
accountId,
|
||||
}),
|
||||
accountConfig?.rooms,
|
||||
Boolean(accountConfig && Object.hasOwn(accountConfig, "rooms")),
|
||||
);
|
||||
// Room maps need custom scoping, so keep the generic merge for all other fields.
|
||||
const { groups: _ignoredGroups, rooms: _ignoredRooms, ...rest } = merged;
|
||||
return {
|
||||
...rest,
|
||||
...(groups ? { groups } : {}),
|
||||
...(rooms ? { rooms } : {}),
|
||||
};
|
||||
}
|
||||
export { resolveMatrixAccountConfig } from "./account-config.js";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { CoreConfig } from "../../types.js";
|
||||
import { resolveMatrixAccountConfig } from "../accounts.js";
|
||||
import { resolveMatrixAccountConfig } from "../account-config.js";
|
||||
import { resolveAckReaction, type OpenClawConfig } from "./runtime-api.js";
|
||||
|
||||
type MatrixAckReactionScope = "group-mentions" | "group-all" | "direct" | "all" | "none" | "off";
|
||||
|
||||
@@ -177,7 +177,7 @@ vi.mock("../../runtime.js", () => ({
|
||||
config: {
|
||||
loadConfig: () => ({
|
||||
channels: {
|
||||
matrix: {},
|
||||
matrix: hoisted.accountConfig,
|
||||
},
|
||||
}),
|
||||
writeConfigFile: vi.fn(),
|
||||
|
||||
@@ -10,7 +10,8 @@ import {
|
||||
} from "../../runtime-api.js";
|
||||
import { getMatrixRuntime } from "../../runtime.js";
|
||||
import type { CoreConfig, ReplyToMode } from "../../types.js";
|
||||
import { resolveConfiguredMatrixBotUserIds, resolveMatrixAccount } from "../accounts.js";
|
||||
import { resolveConfiguredMatrixBotUserIds } from "../accounts.js";
|
||||
import { resolveMatrixAccountConfig } from "../account-config.js";
|
||||
import { setActiveMatrixClient } from "../active-client.js";
|
||||
import {
|
||||
isBunRuntime,
|
||||
@@ -82,8 +83,10 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
const effectiveAccountId = authContext.accountId;
|
||||
|
||||
// Resolve account-specific config for multi-account support
|
||||
const account = resolveMatrixAccount({ cfg, accountId: effectiveAccountId });
|
||||
const accountConfig = account.config;
|
||||
const accountConfig = resolveMatrixAccountConfig({
|
||||
cfg,
|
||||
accountId: effectiveAccountId,
|
||||
});
|
||||
|
||||
const allowlistOnly = accountConfig.allowlistOnly === true;
|
||||
const accountAllowBots = accountConfig.allowBots;
|
||||
@@ -179,7 +182,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
warnMissingProviderGroupPolicyFallbackOnce({
|
||||
providerMissingFallbackApplied,
|
||||
providerKey: "matrix",
|
||||
accountId: account.accountId,
|
||||
accountId: effectiveAccountId,
|
||||
blockedLabel: GROUP_POLICY_BLOCKED_LABEL.room,
|
||||
log: (message) => logVerboseMessage(message),
|
||||
});
|
||||
@@ -190,18 +193,18 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
const threadBindingIdleTimeoutMs = resolveThreadBindingIdleTimeoutMsForChannel({
|
||||
cfg,
|
||||
channel: "matrix",
|
||||
accountId: account.accountId,
|
||||
accountId: effectiveAccountId,
|
||||
});
|
||||
const threadBindingMaxAgeMs = resolveThreadBindingMaxAgeMsForChannel({
|
||||
cfg,
|
||||
channel: "matrix",
|
||||
accountId: account.accountId,
|
||||
accountId: effectiveAccountId,
|
||||
});
|
||||
const dmConfig = accountConfig.dm;
|
||||
const dmEnabled = dmConfig?.enabled ?? true;
|
||||
const dmPolicyRaw = dmConfig?.policy ?? "pairing";
|
||||
const dmPolicy = allowlistOnly && dmPolicyRaw !== "disabled" ? "allowlist" : dmPolicyRaw;
|
||||
const textLimit = core.channel.text.resolveTextChunkLimit(cfg, "matrix", account.accountId);
|
||||
const textLimit = core.channel.text.resolveTextChunkLimit(cfg, "matrix", effectiveAccountId);
|
||||
const globalGroupChatHistoryLimit = (
|
||||
cfg.messages as { groupChat?: { historyLimit?: number } } | undefined
|
||||
)?.groupChat?.historyLimit;
|
||||
@@ -252,7 +255,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
client,
|
||||
core,
|
||||
cfg,
|
||||
accountId: account.accountId,
|
||||
accountId: effectiveAccountId,
|
||||
runtime,
|
||||
logger,
|
||||
logVerboseMessage,
|
||||
@@ -291,7 +294,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
|
||||
try {
|
||||
threadBindingManager = await createMatrixThreadBindingManager({
|
||||
accountId: account.accountId,
|
||||
accountId: effectiveAccountId,
|
||||
auth,
|
||||
client,
|
||||
env: process.env,
|
||||
@@ -315,7 +318,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
.readAllowFromStore({
|
||||
channel: "matrix",
|
||||
env: process.env,
|
||||
accountId: account.accountId,
|
||||
accountId: effectiveAccountId,
|
||||
})
|
||||
.catch(() => []),
|
||||
directTracker,
|
||||
@@ -343,7 +346,7 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
await runMatrixStartupMaintenance({
|
||||
client,
|
||||
auth,
|
||||
accountId: account.accountId,
|
||||
accountId: effectiveAccountId,
|
||||
effectiveAccountId,
|
||||
accountConfig,
|
||||
logger,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-runtime";
|
||||
import type { CoreConfig } from "../../types.js";
|
||||
import { resolveMatrixAccountConfig } from "../accounts.js";
|
||||
import { resolveMatrixAccountConfig } from "../account-config.js";
|
||||
import { extractMatrixReactionAnnotation } from "../reaction-common.js";
|
||||
import type { MatrixClient } from "../sdk.js";
|
||||
import { resolveMatrixInboundRoute } from "./route.js";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getMatrixRuntime } from "../../runtime.js";
|
||||
import type { CoreConfig } from "../../types.js";
|
||||
import { resolveMatrixAccountConfig } from "../accounts.js";
|
||||
import { resolveMatrixAccountConfig } from "../account-config.js";
|
||||
import { withResolvedRuntimeMatrixClient } from "../client-bootstrap.js";
|
||||
import type { MatrixClient } from "../sdk.js";
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { loadConfig, resolveStorePath } from "openclaw/plugin-sdk/config-runtime
|
||||
import { loadSessionStore } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { readChannelAllowFromStore } from "openclaw/plugin-sdk/conversation-runtime";
|
||||
import { upsertChannelPairingRequest } from "openclaw/plugin-sdk/conversation-runtime";
|
||||
import { dispatchReplyWithBufferedBlockDispatcher } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { dispatchReplyWithBufferedBlockDispatcher } from "openclaw/plugin-sdk/reply-dispatch-runtime";
|
||||
import { loadWebMedia } from "openclaw/plugin-sdk/web-media";
|
||||
import { syncTelegramMenuCommands } from "./bot-native-command-menu.js";
|
||||
import { deliverReplies, emitInternalMessageSentHook } from "./bot/delivery.js";
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
} from "openclaw/plugin-sdk/conversation-runtime";
|
||||
import { formatUncaughtError } from "openclaw/plugin-sdk/error-runtime";
|
||||
import { DEFAULT_GROUP_HISTORY_LIMIT, type HistoryEntry } from "openclaw/plugin-sdk/reply-history";
|
||||
import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
|
||||
import { danger, logVerbose, shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { getChildLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
|
||||
Reference in New Issue
Block a user