mirror of
https://github.com/moltbot/moltbot.git
synced 2026-04-25 23:47:20 +00:00
161 lines
4.4 KiB
TypeScript
161 lines
4.4 KiB
TypeScript
import type { OpenClawConfig } from "../config/config.js";
|
|
import { resolveOwningPluginIdsForProvider } from "../plugins/providers.js";
|
|
import {
|
|
normalizeLowercaseStringOrEmpty,
|
|
normalizeOptionalLowercaseString,
|
|
} from "../shared/string-coerce.js";
|
|
import { normalizeProviderId } from "./provider-id.js";
|
|
|
|
type ModelTarget = {
|
|
raw: string;
|
|
provider?: string;
|
|
modelId: string;
|
|
};
|
|
|
|
function normalizeCsvSet(values: Set<string> | null): Set<string> | null {
|
|
if (!values) {
|
|
return null;
|
|
}
|
|
const normalized = new Set<string>();
|
|
for (const value of values) {
|
|
const trimmed = value.trim();
|
|
if (!trimmed) {
|
|
continue;
|
|
}
|
|
normalized.add(trimmed);
|
|
}
|
|
return normalized.size > 0 ? normalized : null;
|
|
}
|
|
|
|
function parseModelTarget(raw: string): ModelTarget | null {
|
|
const trimmed = raw.trim();
|
|
if (!trimmed) {
|
|
return null;
|
|
}
|
|
const slash = trimmed.indexOf("/");
|
|
if (slash === -1) {
|
|
return {
|
|
raw: trimmed,
|
|
modelId: normalizeLowercaseStringOrEmpty(trimmed),
|
|
};
|
|
}
|
|
const provider = normalizeProviderId(trimmed.slice(0, slash));
|
|
const modelId = normalizeLowercaseStringOrEmpty(trimmed.slice(slash + 1));
|
|
if (!provider || !modelId) {
|
|
return null;
|
|
}
|
|
return {
|
|
raw: trimmed,
|
|
provider,
|
|
modelId,
|
|
};
|
|
}
|
|
|
|
function hasSharedOwner(
|
|
left: string,
|
|
right: string,
|
|
params: {
|
|
config?: OpenClawConfig;
|
|
workspaceDir?: string;
|
|
env?: NodeJS.ProcessEnv;
|
|
ownerCache: Map<string, readonly string[]>;
|
|
},
|
|
): boolean {
|
|
const resolveOwners = (provider: string): readonly string[] => {
|
|
const normalized = normalizeProviderId(provider);
|
|
const cached = params.ownerCache.get(normalized);
|
|
if (cached) {
|
|
return cached;
|
|
}
|
|
const owners =
|
|
resolveOwningPluginIdsForProvider({
|
|
provider: normalized,
|
|
config: params.config,
|
|
workspaceDir: params.workspaceDir,
|
|
env: params.env,
|
|
}) ?? [];
|
|
params.ownerCache.set(normalized, owners);
|
|
return owners;
|
|
};
|
|
|
|
const leftOwners = resolveOwners(left);
|
|
const rightOwners = resolveOwners(right);
|
|
return leftOwners.some((owner) => rightOwners.includes(owner));
|
|
}
|
|
|
|
export function createLiveTargetMatcher(params: {
|
|
providerFilter: Set<string> | null;
|
|
modelFilter: Set<string> | null;
|
|
config?: OpenClawConfig;
|
|
workspaceDir?: string;
|
|
env?: NodeJS.ProcessEnv;
|
|
}) {
|
|
const providerFilter = normalizeCsvSet(params.providerFilter);
|
|
const modelTargets = [...(normalizeCsvSet(params.modelFilter) ?? [])]
|
|
.map((value) => parseModelTarget(value))
|
|
.filter((value): value is ModelTarget => value !== null);
|
|
const ownerCache = new Map<string, readonly string[]>();
|
|
|
|
return {
|
|
matchesProvider(provider: string): boolean {
|
|
if (!providerFilter) {
|
|
return true;
|
|
}
|
|
const normalizedProvider = normalizeProviderId(provider);
|
|
for (const requested of providerFilter) {
|
|
const normalizedRequested = normalizeProviderId(requested);
|
|
if (normalizedRequested === normalizedProvider) {
|
|
return true;
|
|
}
|
|
if (
|
|
hasSharedOwner(normalizedRequested, normalizedProvider, {
|
|
config: params.config,
|
|
workspaceDir: params.workspaceDir,
|
|
env: params.env,
|
|
ownerCache,
|
|
})
|
|
) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
matchesModel(provider: string, modelId: string): boolean {
|
|
if (modelTargets.length === 0) {
|
|
return true;
|
|
}
|
|
const normalizedProvider = normalizeProviderId(provider);
|
|
const normalizedModelId = normalizeOptionalLowercaseString(modelId);
|
|
if (!normalizedModelId) {
|
|
return false;
|
|
}
|
|
const directRef = `${normalizedProvider}/${normalizedModelId}`;
|
|
for (const target of modelTargets) {
|
|
if (normalizeOptionalLowercaseString(target.raw) === directRef) {
|
|
return true;
|
|
}
|
|
if (target.modelId !== normalizedModelId) {
|
|
continue;
|
|
}
|
|
if (!target.provider) {
|
|
return true;
|
|
}
|
|
if (target.provider === normalizedProvider) {
|
|
return true;
|
|
}
|
|
if (
|
|
hasSharedOwner(target.provider, normalizedProvider, {
|
|
config: params.config,
|
|
workspaceDir: params.workspaceDir,
|
|
env: params.env,
|
|
ownerCache,
|
|
})
|
|
) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
},
|
|
};
|
|
}
|