feat: pluginize cli inference backends

This commit is contained in:
Peter Steinberger
2026-03-26 15:09:01 +00:00
parent 24dd7aec90
commit a4a00aa1da
49 changed files with 657 additions and 248 deletions

View File

@@ -25,6 +25,7 @@ import {
stripPromptMutationFieldsFromLegacyHookResult,
} from "./types.js";
import type {
CliBackendPlugin,
ImageGenerationProviderPlugin,
OpenClawPluginApi,
OpenClawPluginChannelRegistration,
@@ -109,6 +110,14 @@ export type PluginProviderRegistration = {
rootDir?: string;
};
export type PluginCliBackendRegistration = {
pluginId: string;
pluginName?: string;
backend: CliBackendPlugin;
source: string;
rootDir?: string;
};
type PluginOwnedProviderRegistration<T extends { id: string }> = {
pluginId: string;
pluginName?: string;
@@ -178,6 +187,7 @@ export type PluginRecord = {
toolNames: string[];
hookNames: string[];
channelIds: string[];
cliBackendIds: string[];
providerIds: string[];
speechProviderIds: string[];
mediaUnderstandingProviderIds: string[];
@@ -202,6 +212,7 @@ export type PluginRegistry = {
channels: PluginChannelRegistration[];
channelSetups: PluginChannelSetupRegistration[];
providers: PluginProviderRegistration[];
cliBackends?: PluginCliBackendRegistration[];
speechProviders: PluginSpeechProviderRegistration[];
mediaUnderstandingProviders: PluginMediaUnderstandingProviderRegistration[];
imageGenerationProviders: PluginImageGenerationProviderRegistration[];
@@ -565,6 +576,40 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
});
};
const registerCliBackend = (record: PluginRecord, backend: CliBackendPlugin) => {
const id = backend.id.trim();
if (!id) {
pushDiagnostic({
level: "error",
pluginId: record.id,
source: record.source,
message: "cli backend registration missing id",
});
return;
}
const existing = (registry.cliBackends ?? []).find((entry) => entry.backend.id === id);
if (existing) {
pushDiagnostic({
level: "error",
pluginId: record.id,
source: record.source,
message: `cli backend already registered: ${id} (${existing.pluginId})`,
});
return;
}
(registry.cliBackends ??= []).push({
pluginId: record.id,
pluginName: record.name,
backend: {
...backend,
id,
},
source: record.source,
rootDir: record.rootDir,
});
record.cliBackendIds.push(id);
};
const registerUniqueProviderLike = <
T extends { id: string },
R extends PluginOwnedProviderRegistration<T>,
@@ -932,6 +977,8 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
: () => {},
registerService:
registrationMode === "full" ? (service) => registerService(record, service) : () => {},
registerCliBackend:
registrationMode === "full" ? (backend) => registerCliBackend(record, backend) : () => {},
registerInteractiveHandler:
registrationMode === "full"
? (registration) => {
@@ -1010,6 +1057,7 @@ export function createPluginRegistry(registryParams: PluginRegistryParams) {
registerTool,
registerChannel,
registerProvider,
registerCliBackend,
registerSpeechProvider,
registerMediaUnderstandingProvider,
registerImageGenerationProvider,