diff --git a/src/plugins/embedding-provider-runtime-shared.ts b/src/plugins/embedding-provider-runtime-shared.ts new file mode 100644 index 00000000000..3e17188215a --- /dev/null +++ b/src/plugins/embedding-provider-runtime-shared.ts @@ -0,0 +1,108 @@ +import { normalizeProviderId } from "../agents/provider-id.js"; +import type { OpenClawConfig } from "../config/types.openclaw.js"; +import { + resolvePluginCapabilityProvider, + resolvePluginCapabilityProviders, +} from "./capability-provider-runtime.js"; + +type EmbeddingProviderCapabilityKey = "embeddingProviders" | "memoryEmbeddingProviders"; +type RegisteredAdapterEntry = { + adapter: TAdapter; +}; +type ConfiguredModelProvider = NonNullable< + NonNullable["providers"] +>[string]; + +function resolveConfiguredProviderConfig( + providerId: string, + cfg?: OpenClawConfig, +): ConfiguredModelProvider | undefined { + const providers = cfg?.models?.providers; + if (!providers) { + return undefined; + } + const normalized = normalizeProviderId(providerId); + return ( + providers[providerId] ?? + Object.entries(providers).find( + ([candidateId]) => normalizeProviderId(candidateId) === normalized, + )?.[1] + ); +} + +export function readConfiguredProviderApiId(params: { + providerId: string; + cfg?: OpenClawConfig; + resolveApiProviderId?: (normalizedApiId: string) => string | undefined; + resolveMissingApiProviderId?: (providerConfig: ConfiguredModelProvider) => string | undefined; +}): string | undefined { + const providerConfig = resolveConfiguredProviderConfig(params.providerId, params.cfg); + if (!providerConfig) { + return undefined; + } + const normalized = normalizeProviderId(params.providerId); + const api = providerConfig.api?.trim(); + const resolvedProviderId = api + ? (params.resolveApiProviderId?.(normalizeProviderId(api)) ?? normalizeProviderId(api)) + : params.resolveMissingApiProviderId?.(providerConfig); + return resolvedProviderId && resolvedProviderId !== normalized ? resolvedProviderId : undefined; +} + +export function resolveRuntimeEmbeddingProviderLookupIds(params: { + id: string; + cfg?: OpenClawConfig; + resolveConfiguredProviderId: (id: string, cfg?: OpenClawConfig) => string | undefined; +}): string[] { + const ids = [params.id]; + const configuredProviderId = params.resolveConfiguredProviderId(params.id, params.cfg); + if ( + configuredProviderId && + !ids.some((candidate) => normalizeProviderId(candidate) === configuredProviderId) + ) { + ids.push(configuredProviderId); + } + return ids; +} + +export function listRuntimeEmbeddingProviderAdapters(params: { + key: EmbeddingProviderCapabilityKey; + cfg?: OpenClawConfig; + registered: TAdapter[]; +}): TAdapter[] { + const merged = new Map(params.registered.map((adapter) => [adapter.id, adapter])); + const capabilityAdapters = resolvePluginCapabilityProviders({ + key: params.key, + cfg: params.cfg, + }) as unknown as TAdapter[]; + for (const adapter of capabilityAdapters) { + if (!merged.has(adapter.id)) { + merged.set(adapter.id, adapter); + } + } + return [...merged.values()]; +} + +export function getRuntimeEmbeddingProviderAdapter(params: { + key: EmbeddingProviderCapabilityKey; + cfg?: OpenClawConfig; + lookupIds: string[]; + getRegisteredProvider: (id: string) => RegisteredAdapterEntry | undefined; +}): TAdapter | undefined { + for (const candidateId of params.lookupIds) { + const registered = params.getRegisteredProvider(candidateId); + if (registered) { + return registered.adapter; + } + } + for (const candidateId of params.lookupIds) { + const provider = resolvePluginCapabilityProvider({ + key: params.key, + providerId: candidateId, + cfg: params.cfg, + }) as TAdapter | undefined; + if (provider) { + return provider; + } + } + return undefined; +} diff --git a/src/plugins/embedding-provider-runtime.ts b/src/plugins/embedding-provider-runtime.ts index 9db189fa4bb..76ff0c70a84 100644 --- a/src/plugins/embedding-provider-runtime.ts +++ b/src/plugins/embedding-provider-runtime.ts @@ -1,9 +1,10 @@ -import { normalizeProviderId } from "../agents/provider-id.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { - resolvePluginCapabilityProvider, - resolvePluginCapabilityProviders, -} from "./capability-provider-runtime.js"; + getRuntimeEmbeddingProviderAdapter, + listRuntimeEmbeddingProviderAdapters, + readConfiguredProviderApiId, + resolveRuntimeEmbeddingProviderLookupIds, +} from "./embedding-provider-runtime-shared.js"; import { getRegisteredEmbeddingProvider, listRegisteredEmbeddingProviders, @@ -20,77 +21,47 @@ export function listRegisteredEmbeddingProviderAdapters(): EmbeddingProviderAdap } export function listEmbeddingProviders(cfg?: OpenClawConfig): EmbeddingProviderAdapter[] { - const registered = listRegisteredEmbeddingProviderAdapters(); - const merged = new Map(registered.map((adapter) => [adapter.id, adapter])); - for (const adapter of resolvePluginCapabilityProviders({ + return listRuntimeEmbeddingProviderAdapters({ key: "embeddingProviders", cfg, - })) { - if (!merged.has(adapter.id)) { - merged.set(adapter.id, adapter); - } - } - return [...merged.values()]; + registered: listRegisteredEmbeddingProviderAdapters(), + }); } -function readConfiguredProviderApiId(providerId: string, cfg?: OpenClawConfig): string | undefined { - const providers = cfg?.models?.providers; - if (!providers) { - return undefined; - } - const normalized = normalizeProviderId(providerId); - const providerConfig = - providers[providerId] ?? - Object.entries(providers).find( - ([candidateId]) => normalizeProviderId(candidateId) === normalized, - )?.[1]; - const api = providerConfig?.api?.trim(); - if (!api && providerConfig?.baseUrl?.trim()) { - return OPENAI_COMPATIBLE_EMBEDDING_PROVIDER_ID; - } - if (!api) { - return undefined; - } - const normalizedApi = normalizeProviderId(api); - const embeddingProviderId = OPENAI_COMPATIBLE_MODEL_APIS.has(normalizedApi) - ? OPENAI_COMPATIBLE_EMBEDDING_PROVIDER_ID - : normalizedApi; - return embeddingProviderId && embeddingProviderId !== normalized - ? embeddingProviderId - : undefined; +function resolveConfiguredEmbeddingProviderId( + providerId: string, + cfg?: OpenClawConfig, +): string | undefined { + return readConfiguredProviderApiId({ + providerId, + cfg, + resolveApiProviderId: (normalizedApiId) => + OPENAI_COMPATIBLE_MODEL_APIS.has(normalizedApiId) + ? OPENAI_COMPATIBLE_EMBEDDING_PROVIDER_ID + : normalizedApiId, + resolveMissingApiProviderId: (providerConfig) => + providerConfig.baseUrl?.trim() ? OPENAI_COMPATIBLE_EMBEDDING_PROVIDER_ID : undefined, + }); } function resolveEmbeddingProviderLookupIds(id: string, cfg?: OpenClawConfig): string[] { - const ids = [id]; - const apiId = readConfiguredProviderApiId(id, cfg); - if (apiId && !ids.some((candidate) => normalizeProviderId(candidate) === apiId)) { - ids.push(apiId); - } - return ids; + return resolveRuntimeEmbeddingProviderLookupIds({ + id, + cfg, + resolveConfiguredProviderId: resolveConfiguredEmbeddingProviderId, + }); } export function getEmbeddingProvider( id: string, cfg?: OpenClawConfig, ): EmbeddingProviderAdapter | undefined { - const ids = resolveEmbeddingProviderLookupIds(id, cfg); - for (const candidateId of ids) { - const registered = getRegisteredEmbeddingProvider(candidateId); - if (registered) { - return registered.adapter; - } - } - for (const candidateId of ids) { - const provider = resolvePluginCapabilityProvider({ - key: "embeddingProviders", - providerId: candidateId, - cfg, - }); - if (provider) { - return provider; - } - } - return undefined; + return getRuntimeEmbeddingProviderAdapter({ + key: "embeddingProviders", + cfg, + lookupIds: resolveEmbeddingProviderLookupIds(id, cfg), + getRegisteredProvider: getRegisteredEmbeddingProvider, + }); } export type { diff --git a/src/plugins/memory-embedding-provider-runtime.ts b/src/plugins/memory-embedding-provider-runtime.ts index dc1d4292608..ae1848ebd67 100644 --- a/src/plugins/memory-embedding-provider-runtime.ts +++ b/src/plugins/memory-embedding-provider-runtime.ts @@ -1,9 +1,10 @@ -import { normalizeProviderId } from "../agents/provider-id.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { - resolvePluginCapabilityProvider, - resolvePluginCapabilityProviders, -} from "./capability-provider-runtime.js"; + getRuntimeEmbeddingProviderAdapter, + listRuntimeEmbeddingProviderAdapters, + readConfiguredProviderApiId, + resolveRuntimeEmbeddingProviderLookupIds, +} from "./embedding-provider-runtime-shared.js"; import { getRegisteredMemoryEmbeddingProvider, listRegisteredMemoryEmbeddingProviders, @@ -18,67 +19,36 @@ export function listRegisteredMemoryEmbeddingProviderAdapters(): MemoryEmbedding export function listMemoryEmbeddingProviders( cfg?: OpenClawConfig, ): MemoryEmbeddingProviderAdapter[] { - const registered = listRegisteredMemoryEmbeddingProviderAdapters(); - const merged = new Map(registered.map((adapter) => [adapter.id, adapter])); - for (const adapter of resolvePluginCapabilityProviders({ + return listRuntimeEmbeddingProviderAdapters({ key: "memoryEmbeddingProviders", cfg, - })) { - if (!merged.has(adapter.id)) { - merged.set(adapter.id, adapter); - } - } - return [...merged.values()]; + registered: listRegisteredMemoryEmbeddingProviderAdapters(), + }); } -function readConfiguredProviderApiId(providerId: string, cfg?: OpenClawConfig): string | undefined { - const providers = cfg?.models?.providers; - if (!providers) { - return undefined; - } - const normalized = normalizeProviderId(providerId); - const providerConfig = - providers[providerId] ?? - Object.entries(providers).find( - ([candidateId]) => normalizeProviderId(candidateId) === normalized, - )?.[1]; - const api = providerConfig?.api?.trim(); - if (!api) { - return undefined; - } - const normalizedApi = normalizeProviderId(api); - return normalizedApi && normalizedApi !== normalized ? normalizedApi : undefined; +function resolveConfiguredMemoryEmbeddingProviderId( + providerId: string, + cfg?: OpenClawConfig, +): string | undefined { + return readConfiguredProviderApiId({ providerId, cfg }); } function resolveMemoryEmbeddingProviderLookupIds(id: string, cfg?: OpenClawConfig): string[] { - const ids = [id]; - const apiId = readConfiguredProviderApiId(id, cfg); - if (apiId && !ids.some((candidate) => normalizeProviderId(candidate) === apiId)) { - ids.push(apiId); - } - return ids; + return resolveRuntimeEmbeddingProviderLookupIds({ + id, + cfg, + resolveConfiguredProviderId: resolveConfiguredMemoryEmbeddingProviderId, + }); } export function getMemoryEmbeddingProvider( id: string, cfg?: OpenClawConfig, ): MemoryEmbeddingProviderAdapter | undefined { - const ids = resolveMemoryEmbeddingProviderLookupIds(id, cfg); - for (const candidateId of ids) { - const registered = getRegisteredMemoryEmbeddingProvider(candidateId); - if (registered) { - return registered.adapter; - } - } - for (const candidateId of ids) { - const provider = resolvePluginCapabilityProvider({ - key: "memoryEmbeddingProviders", - providerId: candidateId, - cfg, - }); - if (provider) { - return provider; - } - } - return undefined; + return getRuntimeEmbeddingProviderAdapter({ + key: "memoryEmbeddingProviders", + cfg, + lookupIds: resolveMemoryEmbeddingProviderLookupIds(id, cfg), + getRegisteredProvider: getRegisteredMemoryEmbeddingProvider, + }); }