mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 00:00:46 +00:00
refactor: simplify channel doctor routing cleanup
This commit is contained in:
@@ -62,7 +62,6 @@ export async function runDoctorRepairSequence(params: {
|
||||
|
||||
const emptyAllowlistWarnings = scanEmptyAllowlistPolicyWarnings(state.candidate, {
|
||||
doctorFixCommand: params.doctorFixCommand,
|
||||
env,
|
||||
...createChannelDoctorEmptyAllowlistPolicyHooks({ cfg: state.candidate, env }),
|
||||
});
|
||||
if (emptyAllowlistWarnings.length > 0) {
|
||||
|
||||
@@ -41,9 +41,7 @@ const channelDoctorBooleanKeys = new Set<keyof ChannelDoctorAdapter>([
|
||||
"warnOnEmptyGroupSenderAllowlist",
|
||||
]);
|
||||
|
||||
const channelDoctorStringEnumValues: Partial<
|
||||
Record<keyof ChannelDoctorAdapter, ReadonlySet<string>>
|
||||
> = {
|
||||
const channelDoctorEnumValues: Partial<Record<keyof ChannelDoctorAdapter, ReadonlySet<string>>> = {
|
||||
dmAllowFromMode: new Set(["topOnly", "topOrNested", "nestedOnly"]),
|
||||
groupModel: new Set(["sender", "route", "hybrid"]),
|
||||
};
|
||||
@@ -106,36 +104,44 @@ function safeListReadOnlyChannelPlugins(context: ChannelDoctorLookupContext) {
|
||||
function mergeDoctorAdapters(
|
||||
adapters: Array<ChannelDoctorAdapter | undefined>,
|
||||
): ChannelDoctorAdapter | undefined {
|
||||
const merged: Record<string, unknown> = {};
|
||||
const merged: Partial<Record<keyof ChannelDoctorAdapter, unknown>> = {};
|
||||
for (const adapter of adapters) {
|
||||
if (!adapter) {
|
||||
continue;
|
||||
}
|
||||
for (const [key, value] of Object.entries(adapter)) {
|
||||
if (merged[key] === undefined && isValidChannelDoctorAdapterValue(key, value)) {
|
||||
merged[key] = value;
|
||||
for (const [key, value] of Object.entries(adapter) as Array<
|
||||
[keyof ChannelDoctorAdapter, unknown]
|
||||
>) {
|
||||
if (merged[key] !== undefined) {
|
||||
continue;
|
||||
}
|
||||
if (!isValidChannelDoctorAdapterValue(key, value)) {
|
||||
continue;
|
||||
}
|
||||
merged[key] = value;
|
||||
}
|
||||
}
|
||||
return Object.keys(merged).length > 0 ? (merged as ChannelDoctorAdapter) : undefined;
|
||||
}
|
||||
|
||||
function isValidChannelDoctorAdapterValue(key: string, value: unknown): boolean {
|
||||
function isValidChannelDoctorAdapterValue(
|
||||
key: keyof ChannelDoctorAdapter,
|
||||
value: unknown,
|
||||
): boolean {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
const typedKey = key as keyof ChannelDoctorAdapter;
|
||||
if (channelDoctorFunctionKeys.has(typedKey)) {
|
||||
if (channelDoctorFunctionKeys.has(key)) {
|
||||
return typeof value === "function";
|
||||
}
|
||||
if (channelDoctorBooleanKeys.has(typedKey)) {
|
||||
if (channelDoctorBooleanKeys.has(key)) {
|
||||
return typeof value === "boolean";
|
||||
}
|
||||
const enumValues = channelDoctorStringEnumValues[typedKey];
|
||||
const enumValues = channelDoctorEnumValues[key];
|
||||
if (enumValues) {
|
||||
return typeof value === "string" && enumValues.has(value);
|
||||
}
|
||||
if (typedKey === "legacyConfigRules") {
|
||||
if (key === "legacyConfigRules") {
|
||||
return Array.isArray(value);
|
||||
}
|
||||
return false;
|
||||
@@ -148,13 +154,14 @@ function listChannelDoctorEntries(
|
||||
if (channelIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
const byId = new Map<string, ChannelDoctorEntry>();
|
||||
const selectedIds = new Set(channelIds);
|
||||
const readOnlyPlugins = safeListReadOnlyChannelPlugins(context).filter((plugin) =>
|
||||
selectedIds.has(plugin.id),
|
||||
const readOnlyPluginsById = new Map(
|
||||
safeListReadOnlyChannelPlugins(context)
|
||||
.filter((plugin) => selectedIds.has(plugin.id))
|
||||
.map((plugin) => [plugin.id, plugin]),
|
||||
);
|
||||
const readOnlyPluginsById = new Map(readOnlyPlugins.map((plugin) => [plugin.id, plugin]));
|
||||
|
||||
const entries: ChannelDoctorEntry[] = [];
|
||||
for (const id of selectedIds) {
|
||||
const doctor = mergeDoctorAdapters([
|
||||
readOnlyPluginsById.get(id)?.doctor,
|
||||
@@ -165,12 +172,9 @@ function listChannelDoctorEntries(
|
||||
if (!doctor) {
|
||||
continue;
|
||||
}
|
||||
const existing = byId.get(id);
|
||||
if (!existing) {
|
||||
byId.set(id, { doctor });
|
||||
}
|
||||
entries.push({ doctor });
|
||||
}
|
||||
return [...byId.values()];
|
||||
return entries;
|
||||
}
|
||||
|
||||
function toPluginEmptyAllowlistContext({
|
||||
|
||||
@@ -4,19 +4,8 @@ import type { DoctorAccountRecord, DoctorAllowFromList } from "../types.js";
|
||||
import { collectEmptyAllowlistPolicyWarningsForAccount } from "./empty-allowlist-policy.js";
|
||||
import { asObjectRecord } from "./object.js";
|
||||
|
||||
export type EmptyAllowlistAccountScanParams = {
|
||||
account: DoctorAccountRecord;
|
||||
channelName: string;
|
||||
cfg: OpenClawConfig;
|
||||
dmPolicy?: string;
|
||||
effectiveAllowFrom?: DoctorAllowFromList;
|
||||
parent?: DoctorAccountRecord;
|
||||
prefix: string;
|
||||
};
|
||||
|
||||
type ScanEmptyAllowlistPolicyWarningsParams = {
|
||||
doctorFixCommand: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
extraWarningsForAccount?: (params: ChannelDoctorEmptyAllowlistAccountContext) => string[];
|
||||
shouldSkipDefaultEmptyGroupAllowlistWarning?: (
|
||||
params: ChannelDoctorEmptyAllowlistAccountContext,
|
||||
|
||||
@@ -164,7 +164,6 @@ export async function collectDoctorPreviewWarnings(params: {
|
||||
});
|
||||
const emptyAllowlistWarnings = scanEmptyAllowlistPolicyWarnings(params.cfg, {
|
||||
doctorFixCommand: params.doctorFixCommand,
|
||||
env,
|
||||
extraWarningsForAccount: emptyAllowlistHooks.extraWarningsForAccount,
|
||||
shouldSkipDefaultEmptyGroupAllowlistWarning:
|
||||
emptyAllowlistHooks.shouldSkipDefaultEmptyGroupAllowlistWarning,
|
||||
|
||||
Reference in New Issue
Block a user