


























@@ -241,6 +241,43 @@ function collectRequestedSpeechProviderIds(cfg: OpenClawConfig | undefined): Set
241241return requested;
242242}
243243244+function addMediaModelProviders(target: Set<string>, value: unknown): void {
245+if (!Array.isArray(value)) {
246+return;
247+}
248+for (const entry of value) {
249+if (typeof entry === "object" && entry !== null) {
250+addStringValue(target, (entry as { provider?: unknown }).provider);
251+}
252+}
253+}
254+255+function collectRequestedMediaUnderstandingProviderIds(
256+cfg: OpenClawConfig | undefined,
257+): Set<string> {
258+const requested = new Set<string>();
259+const media = cfg?.tools?.media;
260+addMediaModelProviders(requested, media?.models);
261+addMediaModelProviders(requested, media?.image?.models);
262+addMediaModelProviders(requested, media?.audio?.models);
263+addMediaModelProviders(requested, media?.video?.models);
264+return requested;
265+}
266+267+function collectRequestedCapabilityProviderIds(params: {
268+key: CapabilityProviderRegistryKey;
269+cfg?: OpenClawConfig;
270+}): Set<string> | undefined {
271+switch (params.key) {
272+case "speechProviders":
273+return collectRequestedSpeechProviderIds(params.cfg);
274+case "mediaUnderstandingProviders":
275+return collectRequestedMediaUnderstandingProviderIds(params.cfg);
276+default:
277+return undefined;
278+}
279+}
280+244281function removeActiveProviderIds(requested: Set<string>, entries: readonly unknown[]): void {
245282for (const entry of entries as Array<{ provider: { id?: unknown; aliases?: unknown } }>) {
246283const provider = entry.provider as { id?: unknown; aliases?: unknown };
@@ -262,7 +299,7 @@ function filterLoadedProvidersForRequestedConfig<K extends CapabilityProviderReg
262299requested: Set<string>;
263300entries: PluginRegistry[K];
264301}): PluginRegistry[K] {
265-if (params.key !== "speechProviders") {
302+if (params.key !== "speechProviders" && params.key !== "mediaUnderstandingProviders") {
266303return [] as unknown as PluginRegistry[K];
267304}
268305if (params.requested.size === 0) {
@@ -341,23 +378,16 @@ export function resolvePluginCapabilityProviders<K extends CapabilityProviderReg
341378342379const activeRegistry = resolveRuntimePluginRegistry();
343380const activeProviders = activeRegistry?.[params.key] ?? [];
344-if (
345-activeProviders.length > 0 &&
346-params.key !== "memoryEmbeddingProviders" &&
347-params.key !== "speechProviders"
348-) {
349-return activeProviders.map((entry) => entry.provider) as CapabilityProviderForKey<K>[];
350-}
351-if (activeProviders.length > 0 && params.key === "speechProviders" && !params.cfg) {
352-return activeProviders.map((entry) => entry.provider) as CapabilityProviderForKey<K>[];
353-}
354-const missingRequestedSpeechProviders =
355-activeProviders.length > 0 && params.key === "speechProviders"
356- ? collectRequestedSpeechProviderIds(params.cfg)
381+const missingRequestedProviders =
382+activeProviders.length > 0
383+ ? collectRequestedCapabilityProviderIds({ key: params.key, cfg: params.cfg })
357384 : undefined;
358-if (missingRequestedSpeechProviders) {
359-removeActiveProviderIds(missingRequestedSpeechProviders, activeProviders);
360-if (missingRequestedSpeechProviders.size === 0) {
385+if (activeProviders.length > 0 && params.key !== "memoryEmbeddingProviders") {
386+if (!missingRequestedProviders) {
387+return activeProviders.map((entry) => entry.provider) as CapabilityProviderForKey<K>[];
388+}
389+removeActiveProviderIds(missingRequestedProviders, activeProviders);
390+if (missingRequestedProviders.size === 0) {
361391return activeProviders.map((entry) => entry.provider) as CapabilityProviderForKey<K>[];
362392}
363393}
@@ -390,7 +420,7 @@ export function resolvePluginCapabilityProviders<K extends CapabilityProviderReg
390420activeProviders.length > 0
391421 ? filterLoadedProvidersForRequestedConfig({
392422key: params.key,
393-requested: missingRequestedSpeechProviders ?? new Set(),
423+requested: missingRequestedProviders ?? new Set(),
394424entries: loadedProviders,
395425})
396426 : loadedProviders;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。