mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 21:21:10 +00:00
refactor(web-search): share scoped provider config plumbing
This commit is contained in:
@@ -71,6 +71,37 @@ export function setScopedCredentialValue(
|
||||
(scoped as Record<string, unknown>).apiKey = value;
|
||||
}
|
||||
|
||||
export function mergeScopedSearchConfig(
|
||||
searchConfig: Record<string, unknown> | undefined,
|
||||
key: string,
|
||||
pluginConfig: Record<string, unknown> | undefined,
|
||||
options?: { mirrorApiKeyToTopLevel?: boolean },
|
||||
): Record<string, unknown> | undefined {
|
||||
if (!pluginConfig) {
|
||||
return searchConfig;
|
||||
}
|
||||
|
||||
const currentScoped =
|
||||
searchConfig?.[key] &&
|
||||
typeof searchConfig[key] === "object" &&
|
||||
!Array.isArray(searchConfig[key])
|
||||
? (searchConfig[key] as Record<string, unknown>)
|
||||
: {};
|
||||
const next: Record<string, unknown> = {
|
||||
...searchConfig,
|
||||
[key]: {
|
||||
...currentScoped,
|
||||
...pluginConfig,
|
||||
},
|
||||
};
|
||||
|
||||
if (options?.mirrorApiKeyToTopLevel && pluginConfig.apiKey !== undefined) {
|
||||
next.apiKey = pluginConfig.apiKey;
|
||||
}
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
export function resolveSearchConfig(cfg?: OpenClawConfig): WebSearchConfig {
|
||||
const search = cfg?.tools?.web?.search;
|
||||
if (!search || typeof search !== "object") {
|
||||
|
||||
@@ -3,7 +3,10 @@ import { __testing as braveTesting } from "../../../extensions/brave/src/brave-w
|
||||
import { __testing as moonshotTesting } from "../../../extensions/moonshot/src/kimi-web-search-provider.js";
|
||||
import { __testing as perplexityTesting } from "../../../extensions/perplexity/web-search-provider.js";
|
||||
import { __testing as xaiTesting } from "../../../extensions/xai/src/grok-web-search-provider.js";
|
||||
import { buildUnsupportedSearchFilterResponse } from "../../plugin-sdk/provider-web-search.js";
|
||||
import {
|
||||
buildUnsupportedSearchFilterResponse,
|
||||
mergeScopedSearchConfig,
|
||||
} from "../../plugin-sdk/provider-web-search.js";
|
||||
import { withEnv } from "../../test-utils/env.js";
|
||||
const {
|
||||
inferPerplexityBaseUrlFromApiKey,
|
||||
@@ -223,6 +226,40 @@ describe("web_search unsupported filter response", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("web_search scoped config merge", () => {
|
||||
it("returns the original config when no plugin config exists", () => {
|
||||
const searchConfig = { provider: "grok", grok: { model: "grok-4-1-fast" } };
|
||||
expect(mergeScopedSearchConfig(searchConfig, "grok", undefined)).toBe(searchConfig);
|
||||
});
|
||||
|
||||
it("merges plugin config into the scoped provider object", () => {
|
||||
expect(
|
||||
mergeScopedSearchConfig({ provider: "grok", grok: { model: "old-model" } }, "grok", {
|
||||
model: "new-model",
|
||||
apiKey: "xai-test-key",
|
||||
}),
|
||||
).toEqual({
|
||||
provider: "grok",
|
||||
grok: { model: "new-model", apiKey: "xai-test-key" },
|
||||
});
|
||||
});
|
||||
|
||||
it("can mirror the plugin apiKey to the top level config", () => {
|
||||
expect(
|
||||
mergeScopedSearchConfig(
|
||||
{ provider: "brave", brave: { count: 5 } },
|
||||
"brave",
|
||||
{ apiKey: "brave-test-key" },
|
||||
{ mirrorApiKeyToTopLevel: true },
|
||||
),
|
||||
).toEqual({
|
||||
provider: "brave",
|
||||
apiKey: "brave-test-key",
|
||||
brave: { count: 5, apiKey: "brave-test-key" },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("web_search kimi config resolution", () => {
|
||||
it("uses config apiKey when provided", () => {
|
||||
expect(resolveKimiApiKey({ apiKey: "kimi-test-key" })).toBe("kimi-test-key");
|
||||
|
||||
@@ -30,6 +30,7 @@ export {
|
||||
export {
|
||||
getScopedCredentialValue,
|
||||
getTopLevelCredentialValue,
|
||||
mergeScopedSearchConfig,
|
||||
resolveProviderWebSearchPluginConfig,
|
||||
setScopedCredentialValue,
|
||||
setProviderWebSearchPluginConfigValue,
|
||||
|
||||
Reference in New Issue
Block a user