perf(plugin-sdk): split web-search contract fields

This commit is contained in:
Vincent Koc
2026-04-08 09:57:59 +01:00
parent 092c56ce46
commit 7834140bf9
3 changed files with 116 additions and 86 deletions

View File

@@ -16,7 +16,7 @@ export {
setProviderWebSearchPluginConfigValue,
setTopLevelCredentialValue,
} from "../agents/tools/web-search-provider-config.js";
export { createWebSearchProviderContractFields } from "./provider-web-search-contract.js";
export { createBaseWebSearchProviderContractFields as createWebSearchProviderContractFields } from "./provider-web-search-contract-fields.js";
export type {
WebSearchCredentialResolutionSource,
WebSearchProviderSetupContext,

View File

@@ -0,0 +1,99 @@
import type { SearchConfigRecord } from "../agents/tools/web-search-provider-common.js";
import {
getScopedCredentialValue,
getTopLevelCredentialValue,
resolveProviderWebSearchPluginConfig,
setScopedCredentialValue,
setProviderWebSearchPluginConfigValue,
setTopLevelCredentialValue,
} from "../agents/tools/web-search-provider-config.js";
import type { OpenClawConfig } from "../config/config.js";
import type { WebSearchProviderPlugin } from "../plugins/types.js";
export type WebSearchProviderContractCredential =
| { type: "none" }
| { type: "top-level" }
| { type: "scoped"; scopeId: string };
export type WebSearchProviderConfiguredCredential = {
pluginId: string;
field?: string;
};
export type CreateWebSearchProviderContractFieldsOptions = {
credentialPath: string;
inactiveSecretPaths?: string[];
searchCredential: WebSearchProviderContractCredential;
configuredCredential?: WebSearchProviderConfiguredCredential;
};
export type WebSearchProviderContractFields = Pick<
WebSearchProviderPlugin,
"inactiveSecretPaths" | "getCredentialValue" | "setCredentialValue"
> &
Partial<
Pick<WebSearchProviderPlugin, "getConfiguredCredentialValue" | "setConfiguredCredentialValue">
>;
function createSearchCredentialFields(
credential: WebSearchProviderContractCredential,
): Pick<WebSearchProviderPlugin, "getCredentialValue" | "setCredentialValue"> {
switch (credential.type) {
case "scoped":
return {
getCredentialValue: (searchConfig?: SearchConfigRecord) =>
getScopedCredentialValue(searchConfig, credential.scopeId),
setCredentialValue: (searchConfigTarget: SearchConfigRecord, value: unknown) =>
setScopedCredentialValue(searchConfigTarget, credential.scopeId, value),
};
case "top-level":
return {
getCredentialValue: getTopLevelCredentialValue,
setCredentialValue: setTopLevelCredentialValue,
};
case "none":
return {
getCredentialValue: () => undefined,
setCredentialValue: () => {},
};
}
}
function createConfiguredCredentialFields(
configuredCredential?: WebSearchProviderConfiguredCredential,
): Pick<
WebSearchProviderPlugin,
"getConfiguredCredentialValue" | "setConfiguredCredentialValue"
> | null {
if (!configuredCredential) {
return null;
}
const field = configuredCredential.field ?? "apiKey";
return {
getConfiguredCredentialValue: (config?: OpenClawConfig) =>
resolveProviderWebSearchPluginConfig(config, configuredCredential.pluginId)?.[field],
setConfiguredCredentialValue: (configTarget: OpenClawConfig, value: unknown) => {
setProviderWebSearchPluginConfigValue(
configTarget,
configuredCredential.pluginId,
field,
value,
);
},
};
}
export function createBaseWebSearchProviderContractFields(
options: CreateWebSearchProviderContractFieldsOptions,
): WebSearchProviderContractFields {
const configuredCredentialFields = createConfiguredCredentialFields(options.configuredCredential);
return {
inactiveSecretPaths:
options.inactiveSecretPaths ?? (options.credentialPath ? [options.credentialPath] : []),
...createSearchCredentialFields(options.searchCredential),
...configuredCredentialFields,
};
}

View File

@@ -1,14 +1,5 @@
// Public contract-safe web-search registration helpers for provider plugins.
import type { SearchConfigRecord } from "../agents/tools/web-search-provider-common.js";
import {
getScopedCredentialValue,
getTopLevelCredentialValue,
resolveProviderWebSearchPluginConfig,
setScopedCredentialValue,
setProviderWebSearchPluginConfigValue,
setTopLevelCredentialValue,
} from "../agents/tools/web-search-provider-config.js";
import type { OpenClawConfig } from "../config/config.js";
import type {
WebSearchCredentialResolutionSource,
@@ -17,6 +8,10 @@ import type {
WebSearchProviderToolDefinition,
} from "../plugins/types.js";
import { enablePluginInConfig } from "./provider-enable-config.js";
import {
createBaseWebSearchProviderContractFields,
type CreateWebSearchProviderContractFieldsOptions,
} from "./provider-web-search-contract-fields.js";
export {
getScopedCredentialValue,
getTopLevelCredentialValue,
@@ -33,26 +28,20 @@ export type {
WebSearchProviderPlugin,
WebSearchProviderToolDefinition,
};
export type {
CreateWebSearchProviderContractFieldsOptions,
WebSearchProviderConfiguredCredential,
WebSearchProviderContractCredential,
WebSearchProviderContractFields,
} from "./provider-web-search-contract-fields.js";
type WebSearchProviderContractCredential =
| { type: "none" }
| { type: "top-level" }
| { type: "scoped"; scopeId: string };
type WebSearchProviderConfiguredCredential = {
pluginId: string;
field?: string;
};
type CreateWebSearchProviderContractFieldsOptions = {
credentialPath: string;
inactiveSecretPaths?: string[];
searchCredential: WebSearchProviderContractCredential;
configuredCredential?: WebSearchProviderConfiguredCredential;
type CreateWebSearchProviderSelectionOptions = CreateWebSearchProviderContractFieldsOptions & {
selectionPluginId?: string;
};
type WebSearchProviderContractFields = Pick<
export function createWebSearchProviderContractFields(
options: CreateWebSearchProviderSelectionOptions,
): Pick<
WebSearchProviderPlugin,
"inactiveSecretPaths" | "getCredentialValue" | "setCredentialValue"
> &
@@ -61,69 +50,11 @@ type WebSearchProviderContractFields = Pick<
WebSearchProviderPlugin,
"applySelectionConfig" | "getConfiguredCredentialValue" | "setConfiguredCredentialValue"
>
>;
function createSearchCredentialFields(
credential: WebSearchProviderContractCredential,
): Pick<WebSearchProviderPlugin, "getCredentialValue" | "setCredentialValue"> {
switch (credential.type) {
case "scoped":
return {
getCredentialValue: (searchConfig?: SearchConfigRecord) =>
getScopedCredentialValue(searchConfig, credential.scopeId),
setCredentialValue: (searchConfigTarget: SearchConfigRecord, value: unknown) =>
setScopedCredentialValue(searchConfigTarget, credential.scopeId, value),
};
case "top-level":
return {
getCredentialValue: getTopLevelCredentialValue,
setCredentialValue: setTopLevelCredentialValue,
};
case "none":
return {
getCredentialValue: () => undefined,
setCredentialValue: () => {},
};
}
}
function createConfiguredCredentialFields(
configuredCredential?: WebSearchProviderConfiguredCredential,
): Pick<
WebSearchProviderPlugin,
"getConfiguredCredentialValue" | "setConfiguredCredentialValue"
> | null {
if (!configuredCredential) {
return null;
}
const field = configuredCredential.field ?? "apiKey";
return {
getConfiguredCredentialValue: (config?: OpenClawConfig) =>
resolveProviderWebSearchPluginConfig(config, configuredCredential.pluginId)?.[field],
setConfiguredCredentialValue: (configTarget: OpenClawConfig, value: unknown) => {
setProviderWebSearchPluginConfigValue(
configTarget,
configuredCredential.pluginId,
field,
value,
);
},
};
}
export function createWebSearchProviderContractFields(
options: CreateWebSearchProviderContractFieldsOptions,
): WebSearchProviderContractFields {
const configuredCredentialFields = createConfiguredCredentialFields(options.configuredCredential);
> {
const selectionPluginId = options.selectionPluginId;
return {
inactiveSecretPaths:
options.inactiveSecretPaths ?? (options.credentialPath ? [options.credentialPath] : []),
...createSearchCredentialFields(options.searchCredential),
...configuredCredentialFields,
...createBaseWebSearchProviderContractFields(options),
...(selectionPluginId
? {
applySelectionConfig: (config: OpenClawConfig) =>