fix(secrets): use bundled web search fast path during reload
This commit is contained in:
parent
2d24f35016
commit
218f8d74b6
@ -12,7 +12,12 @@ const { resolvePluginWebSearchProvidersMock } = vi.hoisted(() => ({
|
||||
resolvePluginWebSearchProvidersMock: vi.fn(() => buildTestWebSearchProviders()),
|
||||
}));
|
||||
|
||||
const { resolveBundledPluginWebSearchProvidersMock } = vi.hoisted(() => ({
|
||||
resolveBundledPluginWebSearchProvidersMock: vi.fn(() => buildTestWebSearchProviders()),
|
||||
}));
|
||||
|
||||
vi.mock("../plugins/web-search-providers.js", () => ({
|
||||
resolveBundledPluginWebSearchProviders: resolveBundledPluginWebSearchProvidersMock,
|
||||
resolvePluginWebSearchProviders: resolvePluginWebSearchProvidersMock,
|
||||
}));
|
||||
|
||||
@ -177,6 +182,7 @@ function expectInactiveFirecrawlSecretRef(params: {
|
||||
describe("runtime web tools resolution", () => {
|
||||
beforeEach(() => {
|
||||
vi.mocked(webSearchProviders.resolvePluginWebSearchProviders).mockClear();
|
||||
vi.mocked(webSearchProviders.resolveBundledPluginWebSearchProviders).mockClear();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@ -531,6 +537,48 @@ describe("runtime web tools resolution", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("uses bundled provider resolution for configured bundled providers", async () => {
|
||||
const bundledSpy = vi.mocked(webSearchProviders.resolveBundledPluginWebSearchProviders);
|
||||
const genericSpy = vi.mocked(webSearchProviders.resolvePluginWebSearchProviders);
|
||||
|
||||
const { metadata } = await runRuntimeWebTools({
|
||||
config: asConfig({
|
||||
tools: {
|
||||
web: {
|
||||
search: {
|
||||
enabled: true,
|
||||
provider: "gemini",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
entries: {
|
||||
google: {
|
||||
enabled: true,
|
||||
config: {
|
||||
webSearch: {
|
||||
apiKey: { source: "env", provider: "default", id: "GEMINI_PROVIDER_REF" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
env: {
|
||||
GEMINI_PROVIDER_REF: "gemini-provider-key",
|
||||
},
|
||||
});
|
||||
|
||||
expect(metadata.search.selectedProvider).toBe("gemini");
|
||||
expect(bundledSpy).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
bundledAllowlistCompat: true,
|
||||
onlyPluginIds: ["google"],
|
||||
}),
|
||||
);
|
||||
expect(genericSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not resolve Firecrawl SecretRef when Firecrawl is inactive", async () => {
|
||||
const resolveSpy = vi.spyOn(secretResolve, "resolveSecretRefValues");
|
||||
const { metadata, context } = await runRuntimeWebTools({
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { resolveSecretInputRef } from "../config/types.secrets.js";
|
||||
import {
|
||||
BUNDLED_WEB_SEARCH_PLUGIN_IDS,
|
||||
resolveBundledWebSearchPluginId,
|
||||
} from "../plugins/bundled-web-search.js";
|
||||
import type {
|
||||
PluginWebSearchProviderEntry,
|
||||
WebSearchCredentialResolutionSource,
|
||||
} from "../plugins/types.js";
|
||||
import { resolvePluginWebSearchProviders } from "../plugins/web-search-providers.js";
|
||||
import {
|
||||
resolveBundledPluginWebSearchProviders,
|
||||
resolvePluginWebSearchProviders,
|
||||
} from "../plugins/web-search-providers.js";
|
||||
import { normalizeSecretInput } from "../utils/normalize-secret-input.js";
|
||||
import { secretRefKey } from "./ref-contract.js";
|
||||
import { resolveSecretRefValues } from "./resolve.js";
|
||||
@ -65,6 +72,33 @@ function normalizeProvider(
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function hasCustomWebSearchPluginRisk(config: OpenClawConfig): boolean {
|
||||
const plugins = config.plugins;
|
||||
if (!plugins) {
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(plugins.load?.paths) && plugins.load.paths.length > 0) {
|
||||
return true;
|
||||
}
|
||||
if (plugins.installs && Object.keys(plugins.installs).length > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const bundledPluginIds = new Set<string>(BUNDLED_WEB_SEARCH_PLUGIN_IDS);
|
||||
const hasNonBundledPluginId = (pluginId: string) => !bundledPluginIds.has(pluginId.trim());
|
||||
if (Array.isArray(plugins.allow) && plugins.allow.some(hasNonBundledPluginId)) {
|
||||
return true;
|
||||
}
|
||||
if (Array.isArray(plugins.deny) && plugins.deny.some(hasNonBundledPluginId)) {
|
||||
return true;
|
||||
}
|
||||
if (plugins.entries && Object.keys(plugins.entries).some(hasNonBundledPluginId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function readNonEmptyEnvValue(
|
||||
env: NodeJS.ProcessEnv,
|
||||
names: string[],
|
||||
@ -261,12 +295,28 @@ export async function resolveRuntimeWebTools(params: {
|
||||
const tools = isRecord(params.sourceConfig.tools) ? params.sourceConfig.tools : undefined;
|
||||
const web = isRecord(tools?.web) ? tools.web : undefined;
|
||||
const search = isRecord(web?.search) ? web.search : undefined;
|
||||
const rawProvider =
|
||||
typeof search?.provider === "string" ? search.provider.trim().toLowerCase() : "";
|
||||
const configuredBundledPluginId = resolveBundledWebSearchPluginId(rawProvider);
|
||||
const providers = search
|
||||
? resolvePluginWebSearchProviders({
|
||||
config: params.sourceConfig,
|
||||
env: { ...process.env, ...params.context.env },
|
||||
bundledAllowlistCompat: true,
|
||||
})
|
||||
? configuredBundledPluginId
|
||||
? resolveBundledPluginWebSearchProviders({
|
||||
config: params.sourceConfig,
|
||||
env: { ...process.env, ...params.context.env },
|
||||
bundledAllowlistCompat: true,
|
||||
onlyPluginIds: [configuredBundledPluginId],
|
||||
})
|
||||
: !hasCustomWebSearchPluginRisk(params.sourceConfig)
|
||||
? resolveBundledPluginWebSearchProviders({
|
||||
config: params.sourceConfig,
|
||||
env: { ...process.env, ...params.context.env },
|
||||
bundledAllowlistCompat: true,
|
||||
})
|
||||
: resolvePluginWebSearchProviders({
|
||||
config: params.sourceConfig,
|
||||
env: { ...process.env, ...params.context.env },
|
||||
bundledAllowlistCompat: true,
|
||||
})
|
||||
: [];
|
||||
|
||||
const searchMetadata: RuntimeWebSearchMetadata = {
|
||||
@ -275,8 +325,6 @@ export async function resolveRuntimeWebTools(params: {
|
||||
};
|
||||
|
||||
const searchEnabled = search?.enabled !== false;
|
||||
const rawProvider =
|
||||
typeof search?.provider === "string" ? search.provider.trim().toLowerCase() : "";
|
||||
const configuredProvider = normalizeProvider(rawProvider, providers);
|
||||
|
||||
if (rawProvider && !configuredProvider) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user