mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 11:08:37 +00:00
perf(runtime): reduce hot-path config and routing overhead
This commit is contained in:
@@ -229,8 +229,8 @@ function validateConfigObjectWithPluginsBase(
|
|||||||
|
|
||||||
type RegistryInfo = {
|
type RegistryInfo = {
|
||||||
registry: ReturnType<typeof loadPluginManifestRegistry>;
|
registry: ReturnType<typeof loadPluginManifestRegistry>;
|
||||||
knownIds: Set<string>;
|
knownIds?: Set<string>;
|
||||||
normalizedPlugins: ReturnType<typeof normalizePluginsConfig>;
|
normalizedPlugins?: ReturnType<typeof normalizePluginsConfig>;
|
||||||
};
|
};
|
||||||
|
|
||||||
let registryInfo: RegistryInfo | null = null;
|
let registryInfo: RegistryInfo | null = null;
|
||||||
@@ -245,8 +245,6 @@ function validateConfigObjectWithPluginsBase(
|
|||||||
config,
|
config,
|
||||||
workspaceDir: workspaceDir ?? undefined,
|
workspaceDir: workspaceDir ?? undefined,
|
||||||
});
|
});
|
||||||
const knownIds = new Set(registry.plugins.map((record) => record.id));
|
|
||||||
const normalizedPlugins = normalizePluginsConfig(config.plugins);
|
|
||||||
|
|
||||||
for (const diag of registry.diagnostics) {
|
for (const diag of registry.diagnostics) {
|
||||||
let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
|
let path = diag.pluginId ? `plugins.entries.${diag.pluginId}` : "plugins";
|
||||||
@@ -262,10 +260,26 @@ function validateConfigObjectWithPluginsBase(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
registryInfo = { registry, knownIds, normalizedPlugins };
|
registryInfo = { registry };
|
||||||
return registryInfo;
|
return registryInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ensureKnownIds = (): Set<string> => {
|
||||||
|
const info = ensureRegistry();
|
||||||
|
if (!info.knownIds) {
|
||||||
|
info.knownIds = new Set(info.registry.plugins.map((record) => record.id));
|
||||||
|
}
|
||||||
|
return info.knownIds;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ensureNormalizedPlugins = (): ReturnType<typeof normalizePluginsConfig> => {
|
||||||
|
const info = ensureRegistry();
|
||||||
|
if (!info.normalizedPlugins) {
|
||||||
|
info.normalizedPlugins = normalizePluginsConfig(config.plugins);
|
||||||
|
}
|
||||||
|
return info.normalizedPlugins;
|
||||||
|
};
|
||||||
|
|
||||||
const allowedChannels = new Set<string>(["defaults", "modelByChannel", ...CHANNEL_IDS]);
|
const allowedChannels = new Set<string>(["defaults", "modelByChannel", ...CHANNEL_IDS]);
|
||||||
|
|
||||||
if (config.channels && isRecord(config.channels)) {
|
if (config.channels && isRecord(config.channels)) {
|
||||||
@@ -346,7 +360,9 @@ function validateConfigObjectWithPluginsBase(
|
|||||||
return { ok: true, config, warnings };
|
return { ok: true, config, warnings };
|
||||||
}
|
}
|
||||||
|
|
||||||
const { registry, knownIds, normalizedPlugins } = ensureRegistry();
|
const { registry } = ensureRegistry();
|
||||||
|
const knownIds = ensureKnownIds();
|
||||||
|
const normalizedPlugins = ensureNormalizedPlugins();
|
||||||
const pushMissingPluginIssue = (
|
const pushMissingPluginIssue = (
|
||||||
path: string,
|
path: string,
|
||||||
pluginId: string,
|
pluginId: string,
|
||||||
|
|||||||
@@ -1,17 +1,45 @@
|
|||||||
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
|
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
|
||||||
import type { ChannelId } from "../../channels/plugins/types.js";
|
import type { ChannelId } from "../../channels/plugins/types.js";
|
||||||
|
import { getActivePluginRegistryVersion } from "../../plugins/runtime.js";
|
||||||
|
|
||||||
export function normalizeChannelTargetInput(raw: string): string {
|
export function normalizeChannelTargetInput(raw: string): string {
|
||||||
return raw.trim();
|
return raw.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TargetNormalizer = ((raw: string) => string | undefined) | undefined;
|
||||||
|
type TargetNormalizerCacheEntry = {
|
||||||
|
version: number;
|
||||||
|
normalizer: TargetNormalizer;
|
||||||
|
};
|
||||||
|
|
||||||
|
const targetNormalizerCacheByChannelId = new Map<string, TargetNormalizerCacheEntry>();
|
||||||
|
|
||||||
|
function resolveTargetNormalizer(channelId: ChannelId): TargetNormalizer {
|
||||||
|
const version = getActivePluginRegistryVersion();
|
||||||
|
const cached = targetNormalizerCacheByChannelId.get(channelId);
|
||||||
|
if (cached?.version === version) {
|
||||||
|
return cached.normalizer;
|
||||||
|
}
|
||||||
|
const plugin = getChannelPlugin(channelId);
|
||||||
|
const normalizer = plugin?.messaging?.normalizeTarget;
|
||||||
|
targetNormalizerCacheByChannelId.set(channelId, {
|
||||||
|
version,
|
||||||
|
normalizer,
|
||||||
|
});
|
||||||
|
return normalizer;
|
||||||
|
}
|
||||||
|
|
||||||
export function normalizeTargetForProvider(provider: string, raw?: string): string | undefined {
|
export function normalizeTargetForProvider(provider: string, raw?: string): string | undefined {
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
const fallback = raw.trim() || undefined;
|
||||||
|
if (!fallback) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
const providerId = normalizeChannelId(provider);
|
const providerId = normalizeChannelId(provider);
|
||||||
const plugin = providerId ? getChannelPlugin(providerId) : undefined;
|
const normalizer = providerId ? resolveTargetNormalizer(providerId) : undefined;
|
||||||
const normalized = plugin?.messaging?.normalizeTarget?.(raw) ?? (raw.trim() || undefined);
|
const normalized = normalizer?.(raw) ?? fallback;
|
||||||
return normalized || undefined;
|
return normalized || undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -448,6 +448,35 @@ function formatRouteCachePeer(peer: RoutePeer | null): string {
|
|||||||
return `${peer.kind}:${peer.id}`;
|
return `${peer.kind}:${peer.id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatRoleIdsCacheKey(roleIds: string[]): string {
|
||||||
|
const count = roleIds.length;
|
||||||
|
if (count === 0) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
if (count === 1) {
|
||||||
|
return roleIds[0] ?? "-";
|
||||||
|
}
|
||||||
|
if (count === 2) {
|
||||||
|
const first = roleIds[0] ?? "";
|
||||||
|
const second = roleIds[1] ?? "";
|
||||||
|
return first <= second ? `${first},${second}` : `${second},${first}`;
|
||||||
|
}
|
||||||
|
return roleIds.toSorted().join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildResolvedRouteCacheKey(params: {
|
||||||
|
channel: string;
|
||||||
|
accountId: string;
|
||||||
|
peer: RoutePeer | null;
|
||||||
|
parentPeer: RoutePeer | null;
|
||||||
|
guildId: string;
|
||||||
|
teamId: string;
|
||||||
|
memberRoleIds: string[];
|
||||||
|
dmScope: string;
|
||||||
|
}): string {
|
||||||
|
return `${params.channel}\t${params.accountId}\t${formatRouteCachePeer(params.peer)}\t${formatRouteCachePeer(params.parentPeer)}\t${params.guildId || "-"}\t${params.teamId || "-"}\t${formatRoleIdsCacheKey(params.memberRoleIds)}\t${params.dmScope}`;
|
||||||
|
}
|
||||||
|
|
||||||
function hasGuildConstraint(match: NormalizedBindingMatch): boolean {
|
function hasGuildConstraint(match: NormalizedBindingMatch): boolean {
|
||||||
return Boolean(match.guildId);
|
return Boolean(match.guildId);
|
||||||
}
|
}
|
||||||
@@ -524,16 +553,16 @@ export function resolveAgentRoute(input: ResolveAgentRouteInput): ResolvedAgentR
|
|||||||
const routeCache =
|
const routeCache =
|
||||||
!shouldLogDebug && !identityLinks ? resolveRouteCacheForConfig(input.cfg) : null;
|
!shouldLogDebug && !identityLinks ? resolveRouteCacheForConfig(input.cfg) : null;
|
||||||
const routeCacheKey = routeCache
|
const routeCacheKey = routeCache
|
||||||
? [
|
? buildResolvedRouteCacheKey({
|
||||||
channel,
|
channel,
|
||||||
accountId,
|
accountId,
|
||||||
formatRouteCachePeer(peer),
|
peer,
|
||||||
formatRouteCachePeer(parentPeer),
|
parentPeer,
|
||||||
guildId || "-",
|
guildId,
|
||||||
teamId || "-",
|
teamId,
|
||||||
memberRoleIds.length > 0 ? memberRoleIds.toSorted().join(",") : "-",
|
memberRoleIds,
|
||||||
dmScope,
|
dmScope,
|
||||||
].join("\t")
|
})
|
||||||
: "";
|
: "";
|
||||||
if (routeCache && routeCacheKey) {
|
if (routeCache && routeCacheKey) {
|
||||||
const cachedRoute = routeCache.get(routeCacheKey);
|
const cachedRoute = routeCache.get(routeCacheKey);
|
||||||
|
|||||||
Reference in New Issue
Block a user