import { createProviderApiKeyAuthMethod } from "../plugins/provider-api-key-auth.js" ;
import type {
ProviderPlugin,
ProviderCatalogContext,
ProviderCatalogResult,
ProviderPluginCatalog,
ProviderPluginWizardSetup,
} from "../plugins/types.js" ;
import { definePluginEntry } from "./plugin-entry.js" ;
import type {
OpenClawPluginApi,
OpenClawPluginConfigSchema,
OpenClawPluginDefinition,
} from "./plugin-entry.js" ;
import { buildSingleProviderApiKeyCatalog } from "./provider-catalog-shared.js" ;
type ApiKeyAuthMethodOptions = Parameters<typeof createProviderApiKeyAuthMethod>[0 ];
export type SingleProviderPluginApiKeyAuthOptions = Omit<
ApiKeyAuthMethodOptions,
"providerId" | "expectedProviders" | "wizard"
> & {
expectedProviders?: string[];
wizard?: false | ProviderPluginWizardSetup;
};
export type SingleProviderPluginCatalogOptions =
| {
buildProvider: Parameters<typeof buildSingleProviderApiKeyCatalog>[0 ]["buildProvider" ];
buildStaticProvider?: Parameters<typeof buildSingleProviderApiKeyCatalog>[0 ]["buildProvider" ];
allowExplicitBaseUrl?: boolean ;
run?: never;
order?: never;
staticRun?: never;
}
| {
run: ProviderPluginCatalog["run" ];
staticRun?: ProviderPluginCatalog["run" ];
order?: ProviderPluginCatalog["order" ];
buildProvider?: never;
buildStaticProvider?: never;
allowExplicitBaseUrl?: never;
};
export type SingleProviderPluginOptions = {
id: string;
name: string;
description: string;
kind?: OpenClawPluginDefinition["kind" ];
configSchema?: OpenClawPluginConfigSchema | (() => OpenClawPluginConfigSchema);
provider?: {
id?: string;
label: string;
docsPath: string;
aliases?: string[];
envVars?: string[];
auth?: SingleProviderPluginApiKeyAuthOptions[];
catalog: SingleProviderPluginCatalogOptions;
} & Omit<
ProviderPlugin,
"id" | "label" | "docsPath" | "aliases" | "envVars" | "auth" | "catalog" | "staticCatalog"
>;
register?: (api: OpenClawPluginApi) => void ;
};
function resolveWizardSetup(params: {
providerId: string;
providerLabel: string;
auth: SingleProviderPluginApiKeyAuthOptions;
}): ProviderPluginWizardSetup | undefined {
if (params.auth.wizard === false ) {
return undefined;
}
const wizard = params.auth.wizard ?? {};
const methodId = params.auth.methodId.trim();
return {
choiceId: wizard.choiceId ?? `${params.providerId}-${methodId}`,
choiceLabel: wizard.choiceLabel ?? params.auth.label,
...(wizard.choiceHint ? { choiceHint: wizard.choiceHint } : {}),
groupId: wizard.groupId ?? params.providerId,
groupLabel: wizard.groupLabel ?? params.providerLabel,
...((wizard.groupHint ?? params.auth.hint)
? { groupHint: wizard.groupHint ?? params.auth.hint }
: {}),
methodId,
...(wizard.onboardingScopes ? { onboardingScopes: wizard.onboardingScopes } : {}),
...(wizard.modelAllowlist ? { modelAllowlist: wizard.modelAllowlist } : {}),
};
}
function resolveEnvVars(params: {
envVars?: string[];
auth?: SingleProviderPluginApiKeyAuthOptions[];
}): string[] | undefined {
const combined = [
...(params.envVars ?? []),
...(params.auth ?? []).map((entry) => entry.envVar).filter(Boolean ),
]
.map((value) => value.trim())
.filter(Boolean );
return combined.length > 0 ? [...new Set(combined)] : undefined;
}
export function defineSingleProviderPluginEntry(options: SingleProviderPluginOptions) {
return definePluginEntry({
id: options.id,
name: options.name,
description: options.description,
...(options.kind ? { kind: options.kind } : {}),
...(options.configSchema ? { configSchema: options.configSchema } : {}),
register(api) {
const provider = options.provider;
if (provider) {
const providerId = provider.id ?? options.id;
const envVars = resolveEnvVars({
envVars: provider.envVars,
auth: provider.auth,
});
const auth = (provider.auth ?? []).map((entry) => {
const { wizard: _wizard, ...authParams } = entry;
const wizard = resolveWizardSetup({
providerId,
providerLabel: provider.label,
auth: entry,
});
return createProviderApiKeyAuthMethod({
...authParams,
providerId,
expectedProviders: entry.expectedProviders ?? [providerId],
...(wizard ? { wizard } : {}),
});
});
let catalog: ProviderPluginCatalog;
if ("run" in provider.catalog) {
const catalogRun = provider.catalog.run;
catalog = {
order: provider.catalog.order ?? "simple" ,
run: catalogRun!,
};
} else {
const buildProvider = provider.catalog.buildProvider;
catalog = {
order: "simple" ,
run: (ctx: ProviderCatalogContext): Promise<ProviderCatalogResult> =>
buildSingleProviderApiKeyCatalog({
ctx,
providerId,
buildProvider,
...(provider.catalog.allowExplicitBaseUrl ? { allowExplicitBaseUrl: true } : {}),
}),
};
}
const staticCatalog: ProviderPluginCatalog | undefined =
"run" in provider.catalog
? provider.catalog.staticRun
? {
order: provider.catalog.order ?? "simple" ,
run: provider.catalog.staticRun,
}
: undefined
: provider.catalog.buildStaticProvider
? {
order: "simple" ,
run: async () => ({
provider: await provider.catalog.buildStaticProvider!(),
}),
}
: undefined;
api.registerProvider({
id: providerId,
label: provider.label,
docsPath: provider.docsPath,
...(provider.aliases ? { aliases: provider.aliases } : {}),
...(envVars ? { envVars } : {}),
auth,
catalog,
...(staticCatalog ? { staticCatalog } : {}),
...Object.fromEntries(
Object.entries(provider).filter(
([key]) =>
![
"id" ,
"label" ,
"docsPath" ,
"aliases" ,
"envVars" ,
"auth" ,
"catalog" ,
"staticCatalog" ,
].includes(key),
),
),
});
}
options.register?.(api);
},
});
}
Messung V0.5 in Prozent C=99 H=97 G=97
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland