mirror of https://github.com/openclaw/openclaw.git
221 lines
7.8 KiB
TypeScript
221 lines
7.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { bundledWebSearchPluginRegistrations } from "../bundled-web-search-registry.js";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import { BUNDLED_WEB_SEARCH_PLUGIN_IDS } from "./bundled-web-search-ids.js";
|
|
import { resolveBundledWebSearchPluginId } from "./bundled-web-search-provider-ids.js";
|
|
import {
|
|
listBundledWebSearchProviders,
|
|
resolveBundledWebSearchPluginIds,
|
|
} from "./bundled-web-search.js";
|
|
import { webSearchProviderContractRegistry } from "./contracts/registry.js";
|
|
|
|
describe("bundled web search metadata", () => {
|
|
function toComparableEntry(params: {
|
|
pluginId: string;
|
|
provider: {
|
|
id: string;
|
|
label: string;
|
|
hint: string;
|
|
envVars: string[];
|
|
placeholder: string;
|
|
signupUrl: string;
|
|
docsUrl?: string;
|
|
autoDetectOrder?: number;
|
|
requiresCredential?: boolean;
|
|
credentialPath: string;
|
|
inactiveSecretPaths?: string[];
|
|
getConfiguredCredentialValue?: unknown;
|
|
setConfiguredCredentialValue?: unknown;
|
|
applySelectionConfig?: unknown;
|
|
resolveRuntimeMetadata?: unknown;
|
|
};
|
|
}) {
|
|
return {
|
|
pluginId: params.pluginId,
|
|
id: params.provider.id,
|
|
label: params.provider.label,
|
|
hint: params.provider.hint,
|
|
envVars: params.provider.envVars,
|
|
placeholder: params.provider.placeholder,
|
|
signupUrl: params.provider.signupUrl,
|
|
docsUrl: params.provider.docsUrl,
|
|
autoDetectOrder: params.provider.autoDetectOrder,
|
|
requiresCredential: params.provider.requiresCredential,
|
|
credentialPath: params.provider.credentialPath,
|
|
inactiveSecretPaths: params.provider.inactiveSecretPaths,
|
|
hasConfiguredCredentialAccessors:
|
|
typeof params.provider.getConfiguredCredentialValue === "function" &&
|
|
typeof params.provider.setConfiguredCredentialValue === "function",
|
|
hasApplySelectionConfig: typeof params.provider.applySelectionConfig === "function",
|
|
hasResolveRuntimeMetadata: typeof params.provider.resolveRuntimeMetadata === "function",
|
|
};
|
|
}
|
|
|
|
function sortComparableEntries<
|
|
T extends {
|
|
autoDetectOrder?: number;
|
|
id: string;
|
|
pluginId: string;
|
|
},
|
|
>(entries: T[]): T[] {
|
|
return [...entries].toSorted((left, right) => {
|
|
const leftOrder = left.autoDetectOrder ?? Number.MAX_SAFE_INTEGER;
|
|
const rightOrder = right.autoDetectOrder ?? Number.MAX_SAFE_INTEGER;
|
|
return (
|
|
leftOrder - rightOrder ||
|
|
left.id.localeCompare(right.id) ||
|
|
left.pluginId.localeCompare(right.pluginId)
|
|
);
|
|
});
|
|
}
|
|
|
|
it("keeps bundled web search compat ids aligned with bundled manifests", () => {
|
|
expect(resolveBundledWebSearchPluginIds({})).toEqual([
|
|
"brave",
|
|
"duckduckgo",
|
|
"exa",
|
|
"firecrawl",
|
|
"google",
|
|
"moonshot",
|
|
"perplexity",
|
|
"tavily",
|
|
"xai",
|
|
]);
|
|
});
|
|
|
|
it("keeps bundled web search fast-path ids aligned with the registry", () => {
|
|
expect([...BUNDLED_WEB_SEARCH_PLUGIN_IDS]).toEqual(
|
|
bundledWebSearchPluginRegistrations
|
|
.map(({ plugin }) => plugin.id)
|
|
.toSorted((left, right) => left.localeCompare(right)),
|
|
);
|
|
});
|
|
|
|
it("keeps bundled web search provider-to-plugin ids aligned with bundled contracts", () => {
|
|
expect(resolveBundledWebSearchPluginId("brave")).toBe("brave");
|
|
expect(resolveBundledWebSearchPluginId("exa")).toBe("exa");
|
|
expect(resolveBundledWebSearchPluginId("firecrawl")).toBe("firecrawl");
|
|
expect(resolveBundledWebSearchPluginId("gemini")).toBe("google");
|
|
expect(resolveBundledWebSearchPluginId("kimi")).toBe("moonshot");
|
|
expect(resolveBundledWebSearchPluginId("perplexity")).toBe("perplexity");
|
|
expect(resolveBundledWebSearchPluginId("tavily")).toBe("tavily");
|
|
expect(resolveBundledWebSearchPluginId("grok")).toBe("xai");
|
|
});
|
|
|
|
it("keeps fast-path bundled provider metadata aligned with bundled plugin contracts", async () => {
|
|
const fastPathProviders = listBundledWebSearchProviders();
|
|
|
|
expect(
|
|
sortComparableEntries(
|
|
fastPathProviders.map((provider) =>
|
|
toComparableEntry({
|
|
pluginId: provider.pluginId,
|
|
provider,
|
|
}),
|
|
),
|
|
),
|
|
).toEqual(
|
|
sortComparableEntries(
|
|
webSearchProviderContractRegistry.map(({ pluginId, provider }) =>
|
|
toComparableEntry({
|
|
pluginId,
|
|
provider,
|
|
}),
|
|
),
|
|
),
|
|
);
|
|
|
|
for (const fastPathProvider of fastPathProviders) {
|
|
const contractEntry = webSearchProviderContractRegistry.find(
|
|
(entry) =>
|
|
entry.pluginId === fastPathProvider.pluginId && entry.provider.id === fastPathProvider.id,
|
|
);
|
|
expect(contractEntry).toBeDefined();
|
|
const contractProvider = contractEntry!.provider;
|
|
|
|
const fastSearchConfig: Record<string, unknown> = {};
|
|
const contractSearchConfig: Record<string, unknown> = {};
|
|
fastPathProvider.setCredentialValue(fastSearchConfig, "test-key");
|
|
contractProvider.setCredentialValue(contractSearchConfig, "test-key");
|
|
expect(fastSearchConfig).toEqual(contractSearchConfig);
|
|
expect(fastPathProvider.getCredentialValue(fastSearchConfig)).toEqual(
|
|
contractProvider.getCredentialValue(contractSearchConfig),
|
|
);
|
|
|
|
const fastConfig = {} as OpenClawConfig;
|
|
const contractConfig = {} as OpenClawConfig;
|
|
fastPathProvider.setConfiguredCredentialValue?.(fastConfig, "test-key");
|
|
contractProvider.setConfiguredCredentialValue?.(contractConfig, "test-key");
|
|
expect(fastConfig).toEqual(contractConfig);
|
|
expect(fastPathProvider.getConfiguredCredentialValue?.(fastConfig)).toEqual(
|
|
contractProvider.getConfiguredCredentialValue?.(contractConfig),
|
|
);
|
|
|
|
if (fastPathProvider.applySelectionConfig || contractProvider.applySelectionConfig) {
|
|
expect(fastPathProvider.applySelectionConfig?.({} as OpenClawConfig)).toEqual(
|
|
contractProvider.applySelectionConfig?.({} as OpenClawConfig),
|
|
);
|
|
}
|
|
|
|
if (fastPathProvider.resolveRuntimeMetadata || contractProvider.resolveRuntimeMetadata) {
|
|
const metadataCases = [
|
|
{
|
|
searchConfig: fastSearchConfig,
|
|
resolvedCredential: {
|
|
value: "pplx-test",
|
|
source: "secretRef" as const,
|
|
fallbackEnvVar: undefined,
|
|
},
|
|
},
|
|
{
|
|
searchConfig: fastSearchConfig,
|
|
resolvedCredential: {
|
|
value: undefined,
|
|
source: "env" as const,
|
|
fallbackEnvVar: "OPENROUTER_API_KEY",
|
|
},
|
|
},
|
|
{
|
|
searchConfig: {
|
|
...fastSearchConfig,
|
|
perplexity: {
|
|
...(fastSearchConfig.perplexity as Record<string, unknown> | undefined),
|
|
model: "custom-model",
|
|
},
|
|
},
|
|
resolvedCredential: {
|
|
value: "pplx-test",
|
|
source: "secretRef" as const,
|
|
fallbackEnvVar: undefined,
|
|
},
|
|
},
|
|
];
|
|
|
|
for (const testCase of metadataCases) {
|
|
expect(
|
|
await fastPathProvider.resolveRuntimeMetadata?.({
|
|
config: fastConfig,
|
|
searchConfig: testCase.searchConfig,
|
|
runtimeMetadata: {
|
|
diagnostics: [],
|
|
providerSource: "configured",
|
|
},
|
|
resolvedCredential: testCase.resolvedCredential,
|
|
}),
|
|
).toEqual(
|
|
await contractProvider.resolveRuntimeMetadata?.({
|
|
config: contractConfig,
|
|
searchConfig: testCase.searchConfig,
|
|
runtimeMetadata: {
|
|
diagnostics: [],
|
|
providerSource: "configured",
|
|
},
|
|
resolvedCredential: testCase.resolvedCredential,
|
|
}),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|