152 lines
5.1 KiB
TypeScript
152 lines
5.1 KiB
TypeScript
import { createFirecrawlWebSearchProvider } from "../../extensions/firecrawl/src/firecrawl-search-provider.js";
|
|
import {
|
|
createPluginBackedWebSearchProvider,
|
|
getScopedCredentialValue,
|
|
getTopLevelCredentialValue,
|
|
setScopedCredentialValue,
|
|
setTopLevelCredentialValue,
|
|
} from "../agents/tools/web-search-plugin-factory.js";
|
|
import {
|
|
withBundledPluginAllowlistCompat,
|
|
withBundledPluginEnablementCompat,
|
|
} from "./bundled-compat.js";
|
|
import { normalizePluginsConfig, resolveEffectiveEnableState } from "./config-state.js";
|
|
import type { PluginLoadOptions } from "./loader.js";
|
|
import type { WebSearchProviderPlugin } from "./types.js";
|
|
|
|
const BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS = [
|
|
"brave",
|
|
"firecrawl",
|
|
"google",
|
|
"moonshot",
|
|
"perplexity",
|
|
"xai",
|
|
] as const;
|
|
|
|
const BUNDLED_WEB_SEARCH_PROVIDER_REGISTRY = [
|
|
{
|
|
pluginId: "brave",
|
|
provider: createPluginBackedWebSearchProvider({
|
|
id: "brave",
|
|
label: "Brave Search",
|
|
hint: "Structured results · country/language/time filters",
|
|
envVars: ["BRAVE_API_KEY"],
|
|
placeholder: "BSA...",
|
|
signupUrl: "https://brave.com/search/api/",
|
|
docsUrl: "https://docs.openclaw.ai/brave-search",
|
|
autoDetectOrder: 10,
|
|
getCredentialValue: getTopLevelCredentialValue,
|
|
setCredentialValue: setTopLevelCredentialValue,
|
|
}),
|
|
},
|
|
{
|
|
pluginId: "google",
|
|
provider: createPluginBackedWebSearchProvider({
|
|
id: "gemini",
|
|
label: "Gemini (Google Search)",
|
|
hint: "Google Search grounding · AI-synthesized",
|
|
envVars: ["GEMINI_API_KEY"],
|
|
placeholder: "AIza...",
|
|
signupUrl: "https://aistudio.google.com/apikey",
|
|
docsUrl: "https://docs.openclaw.ai/tools/web",
|
|
autoDetectOrder: 20,
|
|
getCredentialValue: (searchConfig) => getScopedCredentialValue(searchConfig, "gemini"),
|
|
setCredentialValue: (searchConfigTarget, value) =>
|
|
setScopedCredentialValue(searchConfigTarget, "gemini", value),
|
|
}),
|
|
},
|
|
{
|
|
pluginId: "xai",
|
|
provider: createPluginBackedWebSearchProvider({
|
|
id: "grok",
|
|
label: "Grok (xAI)",
|
|
hint: "xAI web-grounded responses",
|
|
envVars: ["XAI_API_KEY"],
|
|
placeholder: "xai-...",
|
|
signupUrl: "https://console.x.ai/",
|
|
docsUrl: "https://docs.openclaw.ai/tools/web",
|
|
autoDetectOrder: 30,
|
|
getCredentialValue: (searchConfig) => getScopedCredentialValue(searchConfig, "grok"),
|
|
setCredentialValue: (searchConfigTarget, value) =>
|
|
setScopedCredentialValue(searchConfigTarget, "grok", value),
|
|
}),
|
|
},
|
|
{
|
|
pluginId: "moonshot",
|
|
provider: createPluginBackedWebSearchProvider({
|
|
id: "kimi",
|
|
label: "Kimi (Moonshot)",
|
|
hint: "Moonshot web search",
|
|
envVars: ["KIMI_API_KEY", "MOONSHOT_API_KEY"],
|
|
placeholder: "sk-...",
|
|
signupUrl: "https://platform.moonshot.cn/",
|
|
docsUrl: "https://docs.openclaw.ai/tools/web",
|
|
autoDetectOrder: 40,
|
|
getCredentialValue: (searchConfig) => getScopedCredentialValue(searchConfig, "kimi"),
|
|
setCredentialValue: (searchConfigTarget, value) =>
|
|
setScopedCredentialValue(searchConfigTarget, "kimi", value),
|
|
}),
|
|
},
|
|
{
|
|
pluginId: "perplexity",
|
|
provider: createPluginBackedWebSearchProvider({
|
|
id: "perplexity",
|
|
label: "Perplexity Search",
|
|
hint: "Structured results · domain/country/language/time filters",
|
|
envVars: ["PERPLEXITY_API_KEY", "OPENROUTER_API_KEY"],
|
|
placeholder: "pplx-...",
|
|
signupUrl: "https://www.perplexity.ai/settings/api",
|
|
docsUrl: "https://docs.openclaw.ai/perplexity",
|
|
autoDetectOrder: 50,
|
|
getCredentialValue: (searchConfig) => getScopedCredentialValue(searchConfig, "perplexity"),
|
|
setCredentialValue: (searchConfigTarget, value) =>
|
|
setScopedCredentialValue(searchConfigTarget, "perplexity", value),
|
|
}),
|
|
},
|
|
{
|
|
pluginId: "firecrawl",
|
|
provider: createFirecrawlWebSearchProvider(),
|
|
},
|
|
] as const;
|
|
|
|
export function resolvePluginWebSearchProviders(params: {
|
|
config?: PluginLoadOptions["config"];
|
|
workspaceDir?: string;
|
|
env?: PluginLoadOptions["env"];
|
|
bundledAllowlistCompat?: boolean;
|
|
}): WebSearchProviderPlugin[] {
|
|
const allowlistCompat = params.bundledAllowlistCompat
|
|
? withBundledPluginAllowlistCompat({
|
|
config: params.config,
|
|
pluginIds: BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS,
|
|
})
|
|
: params.config;
|
|
const config = withBundledPluginEnablementCompat({
|
|
config: allowlistCompat,
|
|
pluginIds: BUNDLED_WEB_SEARCH_ALLOWLIST_COMPAT_PLUGIN_IDS,
|
|
});
|
|
const normalizedPlugins = normalizePluginsConfig(config?.plugins);
|
|
|
|
return BUNDLED_WEB_SEARCH_PROVIDER_REGISTRY.filter(
|
|
({ pluginId }) =>
|
|
resolveEffectiveEnableState({
|
|
id: pluginId,
|
|
origin: "bundled",
|
|
config: normalizedPlugins,
|
|
rootConfig: config,
|
|
}).enabled,
|
|
)
|
|
.map((entry) => ({
|
|
...entry.provider,
|
|
pluginId: entry.pluginId,
|
|
}))
|
|
.toSorted((a, b) => {
|
|
const aOrder = a.autoDetectOrder ?? Number.MAX_SAFE_INTEGER;
|
|
const bOrder = b.autoDetectOrder ?? Number.MAX_SAFE_INTEGER;
|
|
if (aOrder !== bOrder) {
|
|
return aOrder - bOrder;
|
|
}
|
|
return a.id.localeCompare(b.id);
|
|
});
|
|
}
|