mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 15:50:43 +00:00
163 lines
5.6 KiB
TypeScript
163 lines
5.6 KiB
TypeScript
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
|
import {
|
|
withBundledPluginAllowlistCompat,
|
|
withBundledPluginEnablementCompat,
|
|
withBundledPluginVitestCompat,
|
|
} from "./bundled-compat.js";
|
|
import { resolveRuntimePluginRegistry } from "./loader.js";
|
|
import { loadPluginManifestRegistry } from "./manifest-registry.js";
|
|
import type { PluginRegistry } from "./registry-types.js";
|
|
|
|
type CapabilityProviderRegistryKey =
|
|
| "memoryEmbeddingProviders"
|
|
| "speechProviders"
|
|
| "realtimeTranscriptionProviders"
|
|
| "realtimeVoiceProviders"
|
|
| "mediaUnderstandingProviders"
|
|
| "imageGenerationProviders"
|
|
| "videoGenerationProviders"
|
|
| "musicGenerationProviders";
|
|
|
|
type CapabilityContractKey =
|
|
| "memoryEmbeddingProviders"
|
|
| "speechProviders"
|
|
| "realtimeTranscriptionProviders"
|
|
| "realtimeVoiceProviders"
|
|
| "mediaUnderstandingProviders"
|
|
| "imageGenerationProviders"
|
|
| "videoGenerationProviders"
|
|
| "musicGenerationProviders";
|
|
|
|
type CapabilityProviderForKey<K extends CapabilityProviderRegistryKey> =
|
|
PluginRegistry[K][number] extends { provider: infer T } ? T : never;
|
|
|
|
const CAPABILITY_CONTRACT_KEY: Record<CapabilityProviderRegistryKey, CapabilityContractKey> = {
|
|
memoryEmbeddingProviders: "memoryEmbeddingProviders",
|
|
speechProviders: "speechProviders",
|
|
realtimeTranscriptionProviders: "realtimeTranscriptionProviders",
|
|
realtimeVoiceProviders: "realtimeVoiceProviders",
|
|
mediaUnderstandingProviders: "mediaUnderstandingProviders",
|
|
imageGenerationProviders: "imageGenerationProviders",
|
|
videoGenerationProviders: "videoGenerationProviders",
|
|
musicGenerationProviders: "musicGenerationProviders",
|
|
};
|
|
|
|
function resolveBundledCapabilityCompatPluginIds(params: {
|
|
key: CapabilityProviderRegistryKey;
|
|
cfg?: OpenClawConfig;
|
|
providerId?: string;
|
|
}): string[] {
|
|
const contractKey = CAPABILITY_CONTRACT_KEY[params.key];
|
|
return loadPluginManifestRegistry({
|
|
config: params.cfg,
|
|
env: process.env,
|
|
})
|
|
.plugins.filter(
|
|
(plugin) =>
|
|
plugin.origin === "bundled" &&
|
|
(plugin.contracts?.[contractKey]?.length ?? 0) > 0 &&
|
|
(!params.providerId || (plugin.contracts?.[contractKey] ?? []).includes(params.providerId)),
|
|
)
|
|
.map((plugin) => plugin.id)
|
|
.toSorted((left, right) => left.localeCompare(right));
|
|
}
|
|
|
|
function resolveCapabilityProviderConfig(params: {
|
|
key: CapabilityProviderRegistryKey;
|
|
cfg?: OpenClawConfig;
|
|
pluginIds?: string[];
|
|
}) {
|
|
const pluginIds = params.pluginIds ?? resolveBundledCapabilityCompatPluginIds(params);
|
|
const allowlistCompat = withBundledPluginAllowlistCompat({
|
|
config: params.cfg,
|
|
pluginIds,
|
|
});
|
|
const enablementCompat = withBundledPluginEnablementCompat({
|
|
config: allowlistCompat,
|
|
pluginIds,
|
|
});
|
|
return withBundledPluginVitestCompat({
|
|
config: enablementCompat,
|
|
pluginIds,
|
|
env: process.env,
|
|
});
|
|
}
|
|
|
|
function findProviderById<K extends CapabilityProviderRegistryKey>(
|
|
entries: PluginRegistry[K],
|
|
providerId: string,
|
|
): CapabilityProviderForKey<K> | undefined {
|
|
const providerEntries = entries as unknown as Array<{
|
|
provider: CapabilityProviderForKey<K> & { id?: unknown };
|
|
}>;
|
|
for (const entry of providerEntries) {
|
|
if (entry.provider.id === providerId) {
|
|
return entry.provider;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function resolvePluginCapabilityProvider<K extends CapabilityProviderRegistryKey>(params: {
|
|
key: K;
|
|
providerId: string;
|
|
cfg?: OpenClawConfig;
|
|
}): CapabilityProviderForKey<K> | undefined {
|
|
const activeRegistry = resolveRuntimePluginRegistry();
|
|
const activeProvider = findProviderById(activeRegistry?.[params.key] ?? [], params.providerId);
|
|
if (activeProvider) {
|
|
return activeProvider;
|
|
}
|
|
|
|
const pluginIds = resolveBundledCapabilityCompatPluginIds({
|
|
key: params.key,
|
|
cfg: params.cfg,
|
|
providerId: params.providerId,
|
|
});
|
|
if (pluginIds.length === 0) {
|
|
return undefined;
|
|
}
|
|
|
|
const compatConfig = resolveCapabilityProviderConfig({
|
|
key: params.key,
|
|
cfg: params.cfg,
|
|
pluginIds,
|
|
});
|
|
const loadOptions = compatConfig === undefined ? undefined : { config: compatConfig };
|
|
const registry = resolveRuntimePluginRegistry(loadOptions);
|
|
return findProviderById(registry?.[params.key] ?? [], params.providerId);
|
|
}
|
|
|
|
export function resolvePluginCapabilityProviders<K extends CapabilityProviderRegistryKey>(params: {
|
|
key: K;
|
|
cfg?: OpenClawConfig;
|
|
}): CapabilityProviderForKey<K>[] {
|
|
const activeRegistry = resolveRuntimePluginRegistry();
|
|
const activeProviders = activeRegistry?.[params.key] ?? [];
|
|
if (activeProviders.length > 0 && params.key !== "memoryEmbeddingProviders") {
|
|
return activeProviders.map((entry) => entry.provider) as CapabilityProviderForKey<K>[];
|
|
}
|
|
const compatConfig = resolveCapabilityProviderConfig({ key: params.key, cfg: params.cfg });
|
|
const loadOptions = compatConfig === undefined ? undefined : { config: compatConfig };
|
|
const registry = resolveRuntimePluginRegistry(loadOptions);
|
|
if (params.key !== "memoryEmbeddingProviders") {
|
|
return (registry?.[params.key] ?? []).map(
|
|
(entry) => entry.provider,
|
|
) as CapabilityProviderForKey<K>[];
|
|
}
|
|
const merged = new Map<string, CapabilityProviderForKey<K>>();
|
|
for (const entry of activeProviders) {
|
|
const provider = entry.provider as CapabilityProviderForKey<K> & { id?: string };
|
|
if (provider.id) {
|
|
merged.set(provider.id, provider);
|
|
}
|
|
}
|
|
for (const entry of registry?.[params.key] ?? []) {
|
|
const provider = entry.provider as CapabilityProviderForKey<K> & { id?: string };
|
|
if (provider.id && !merged.has(provider.id)) {
|
|
merged.set(provider.id, provider);
|
|
}
|
|
}
|
|
return [...merged.values()];
|
|
}
|