mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 18:04:45 +00:00
fix: start configured web search providers
This commit is contained in:
committed by
Peter Steinberger
parent
4d2acd9481
commit
37f8507b4b
@@ -183,6 +183,17 @@ function createManifestRegistryFixture(): PluginManifestRegistry {
|
||||
musicGenerationProviders: ["google"],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "brave",
|
||||
channels: [],
|
||||
origin: "global",
|
||||
enabledByDefault: undefined,
|
||||
providers: [],
|
||||
cliBackends: [],
|
||||
contracts: {
|
||||
webSearchProviders: ["brave"],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: "codex",
|
||||
channels: [],
|
||||
@@ -819,6 +830,75 @@ describe("resolveGatewayStartupPluginIds", () => {
|
||||
} as OpenClawConfig,
|
||||
["browser", "memory-core"],
|
||||
],
|
||||
[
|
||||
"includes explicitly selected external web search providers at startup",
|
||||
{
|
||||
channels: {},
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
enabled: true,
|
||||
provider: "brave",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
allow: ["brave"],
|
||||
entries: {
|
||||
brave: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
["brave"],
|
||||
],
|
||||
[
|
||||
"honors disabled web search when selecting startup providers",
|
||||
{
|
||||
channels: {},
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
enabled: false,
|
||||
provider: "brave",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
allow: ["brave"],
|
||||
entries: {
|
||||
brave: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
[],
|
||||
],
|
||||
[
|
||||
"honors explicit plugin disablement for configured web search providers",
|
||||
{
|
||||
channels: {},
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
enabled: true,
|
||||
provider: "brave",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
allow: ["brave"],
|
||||
entries: {
|
||||
brave: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig,
|
||||
[],
|
||||
],
|
||||
[
|
||||
"keeps configured generation providers behind restrictive allowlists",
|
||||
{
|
||||
@@ -884,6 +964,40 @@ describe("resolveGatewayStartupPluginIds", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("includes auto-enabled external web search providers at startup", () => {
|
||||
const rawConfig = {
|
||||
channels: {},
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
enabled: true,
|
||||
provider: "brave",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
allow: ["browser"],
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
const effectiveConfig = {
|
||||
...rawConfig,
|
||||
plugins: {
|
||||
allow: ["browser", "brave"],
|
||||
entries: {
|
||||
brave: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
expectStartupPluginIdsCase({
|
||||
config: effectiveConfig,
|
||||
activationSourceConfig: rawConfig,
|
||||
expected: ["browser", "brave"],
|
||||
});
|
||||
});
|
||||
|
||||
it("does not let runtime-default plugin entries bypass the authored startup allowlist", () => {
|
||||
const activationSourceConfig = {
|
||||
channels: {},
|
||||
|
||||
@@ -214,6 +214,28 @@ function manifestOwnsConfiguredSpeechProvider(params: {
|
||||
});
|
||||
}
|
||||
|
||||
function collectConfiguredWebSearchProviderIds(config: OpenClawConfig): ReadonlySet<string> {
|
||||
const search = config.tools?.web?.search;
|
||||
if (search?.enabled === false || typeof search?.provider !== "string") {
|
||||
return new Set();
|
||||
}
|
||||
const providerId = normalizeOptionalLowercaseString(search.provider);
|
||||
return providerId ? new Set([providerId]) : new Set();
|
||||
}
|
||||
|
||||
function manifestOwnsConfiguredWebSearchProvider(params: {
|
||||
manifest: PluginManifestRecord | undefined;
|
||||
configuredWebSearchProviderIds: ReadonlySet<string>;
|
||||
}): boolean {
|
||||
if (params.configuredWebSearchProviderIds.size === 0) {
|
||||
return false;
|
||||
}
|
||||
return (params.manifest?.contracts?.webSearchProviders ?? []).some((providerId) => {
|
||||
const normalized = normalizeOptionalLowercaseString(providerId);
|
||||
return normalized ? params.configuredWebSearchProviderIds.has(normalized) : false;
|
||||
});
|
||||
}
|
||||
|
||||
function listModelProviderRefs(value: unknown): string[] {
|
||||
if (typeof value === "string") {
|
||||
return [value];
|
||||
@@ -433,6 +455,52 @@ function canStartConfiguredSpeechProviderPlugin(params: {
|
||||
return activationState.enabled && activationState.explicitlyEnabled;
|
||||
}
|
||||
|
||||
function canStartConfiguredWebSearchProviderPlugin(params: {
|
||||
plugin: InstalledPluginIndexRecord;
|
||||
manifest: PluginManifestRecord | undefined;
|
||||
config: OpenClawConfig;
|
||||
pluginsConfig: ReturnType<typeof normalizePluginsConfigWithRegistry>;
|
||||
activationSource: {
|
||||
plugins: ReturnType<typeof normalizePluginsConfigWithRegistry>;
|
||||
rootConfig?: OpenClawConfig;
|
||||
};
|
||||
configuredWebSearchProviderIds: ReadonlySet<string>;
|
||||
platform?: NodeJS.Platform;
|
||||
}): boolean {
|
||||
if (
|
||||
!manifestOwnsConfiguredWebSearchProvider({
|
||||
manifest: params.manifest,
|
||||
configuredWebSearchProviderIds: params.configuredWebSearchProviderIds,
|
||||
})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (!params.pluginsConfig.enabled || !params.activationSource.plugins.enabled) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
params.pluginsConfig.deny.includes(params.plugin.pluginId) ||
|
||||
params.activationSource.plugins.deny.includes(params.plugin.pluginId)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
params.pluginsConfig.entries[params.plugin.pluginId]?.enabled === false ||
|
||||
params.activationSource.plugins.entries[params.plugin.pluginId]?.enabled === false
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
const activationState = resolveEffectivePluginActivationState({
|
||||
id: params.plugin.pluginId,
|
||||
origin: params.plugin.origin,
|
||||
config: params.pluginsConfig,
|
||||
rootConfig: params.config,
|
||||
enabledByDefault: isPluginEnabledByDefaultForPlatform(params.plugin, params.platform),
|
||||
activationSource: params.activationSource,
|
||||
});
|
||||
return activationState.enabled;
|
||||
}
|
||||
|
||||
function canStartConfiguredRootPlugin(params: {
|
||||
plugin: InstalledPluginIndexRecord;
|
||||
manifest: PluginManifestRecord | undefined;
|
||||
@@ -693,6 +761,8 @@ export function resolveGatewayStartupPluginPlanFromRegistry(params: {
|
||||
const startupDreamingPluginIds = resolveGatewayStartupDreamingPluginIds(params.config);
|
||||
const manifestLookup = createManifestRegistryLookup(params.manifestRegistry);
|
||||
const configuredSpeechProviderIds = collectConfiguredSpeechProviderIds(activationSourceConfig);
|
||||
const configuredWebSearchProviderIds =
|
||||
collectConfiguredWebSearchProviderIds(activationSourceConfig);
|
||||
const configuredGenerationProviderIds =
|
||||
collectConfiguredGenerationProviderIds(activationSourceConfig);
|
||||
const normalizePluginId = createPluginRegistryIdNormalizer(params.index, {
|
||||
@@ -763,6 +833,19 @@ export function resolveGatewayStartupPluginPlanFromRegistry(params: {
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
canStartConfiguredWebSearchProviderPlugin({
|
||||
plugin,
|
||||
manifest,
|
||||
config: params.config,
|
||||
pluginsConfig,
|
||||
activationSource,
|
||||
configuredWebSearchProviderIds,
|
||||
platform: params.platform,
|
||||
})
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (
|
||||
canStartConfiguredGenerationProviderPlugin({
|
||||
plugin,
|
||||
|
||||
Reference in New Issue
Block a user