diff --git a/src/plugins/registry-empty.ts b/src/plugins/registry-empty.ts index 108d8a07107..77e3c022768 100644 --- a/src/plugins/registry-empty.ts +++ b/src/plugins/registry-empty.ts @@ -1,4 +1,4 @@ -import type { PluginRegistry } from "./registry.js"; +import type { PluginRegistry } from "./registry-types.js"; export function createEmptyPluginRegistry(): PluginRegistry { return { diff --git a/src/plugins/registry-types.ts b/src/plugins/registry-types.ts new file mode 100644 index 00000000000..00f655d90d2 --- /dev/null +++ b/src/plugins/registry-types.ts @@ -0,0 +1,289 @@ +import type { ChannelPlugin } from "../channels/plugins/types.js"; +import type { OperatorScope } from "../gateway/method-scopes.js"; +import type { GatewayRequestHandlers } from "../gateway/server-methods/types.js"; +import type { HookEntry } from "../hooks/types.js"; +import type { PluginActivationSource } from "./config-state.js"; +import type { PluginManifestContracts } from "./manifest.js"; +import type { MemoryEmbeddingProviderAdapter } from "./memory-embedding-providers.js"; +import type { PluginRuntime } from "./runtime/types.js"; +import type { + CliBackendPlugin, + ImageGenerationProviderPlugin, + MediaUnderstandingProviderPlugin, + MusicGenerationProviderPlugin, + OpenClawPluginChannelRegistration, + OpenClawPluginCliCommandDescriptor, + OpenClawPluginCliRegistrar, + OpenClawPluginCommandDefinition, + OpenClawPluginHttpRouteAuth, + OpenClawPluginHttpRouteHandler, + OpenClawPluginHttpRouteMatch, + OpenClawPluginReloadRegistration, + OpenClawPluginSecurityAuditCollector, + OpenClawPluginService, + OpenClawPluginToolFactory, + PluginBundleFormat, + PluginConfigUiHint, + PluginConversationBindingResolvedEvent, + PluginDiagnostic, + PluginFormat, + PluginHookRegistration as TypedPluginHookRegistration, + PluginKind, + PluginLogger, + PluginOrigin, + ProviderPlugin, + RealtimeTranscriptionProviderPlugin, + RealtimeVoiceProviderPlugin, + SpeechProviderPlugin, + VideoGenerationProviderPlugin, + WebFetchProviderPlugin, + WebSearchProviderPlugin, +} from "./types.js"; + +export type PluginToolRegistration = { + pluginId: string; + pluginName?: string; + factory: OpenClawPluginToolFactory; + names: string[]; + optional: boolean; + source: string; + rootDir?: string; +}; + +export type PluginCliRegistration = { + pluginId: string; + pluginName?: string; + register: OpenClawPluginCliRegistrar; + commands: string[]; + descriptors: OpenClawPluginCliCommandDescriptor[]; + source: string; + rootDir?: string; +}; + +export type PluginHttpRouteRegistration = { + pluginId?: string; + path: string; + handler: OpenClawPluginHttpRouteHandler; + auth: OpenClawPluginHttpRouteAuth; + match: OpenClawPluginHttpRouteMatch; + source?: string; +}; + +export type PluginChannelRegistration = { + pluginId: string; + pluginName?: string; + plugin: ChannelPlugin; + source: string; + rootDir?: string; +}; + +export type PluginChannelSetupRegistration = { + pluginId: string; + pluginName?: string; + plugin: ChannelPlugin; + source: string; + enabled: boolean; + rootDir?: string; +}; + +export type PluginProviderRegistration = { + pluginId: string; + pluginName?: string; + provider: ProviderPlugin; + source: string; + rootDir?: string; +}; + +export type PluginCliBackendRegistration = { + pluginId: string; + pluginName?: string; + backend: CliBackendPlugin; + source: string; + rootDir?: string; +}; + +type PluginOwnedProviderRegistration = { + pluginId: string; + pluginName?: string; + provider: T; + source: string; + rootDir?: string; +}; + +export type PluginSpeechProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginRealtimeTranscriptionProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginRealtimeVoiceProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginMediaUnderstandingProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginImageGenerationProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginVideoGenerationProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginMusicGenerationProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginWebFetchProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginWebSearchProviderRegistration = + PluginOwnedProviderRegistration; +export type PluginMemoryEmbeddingProviderRegistration = + PluginOwnedProviderRegistration; + +export type PluginHookRegistration = { + pluginId: string; + entry: HookEntry; + events: string[]; + source: string; + rootDir?: string; +}; + +export type PluginServiceRegistration = { + pluginId: string; + pluginName?: string; + service: OpenClawPluginService; + source: string; + rootDir?: string; +}; + +export type PluginReloadRegistration = { + pluginId: string; + pluginName?: string; + registration: OpenClawPluginReloadRegistration; + source: string; + rootDir?: string; +}; + +export type PluginNodeHostCommandRegistration = { + pluginId: string; + pluginName?: string; + command: import("./types.js").OpenClawPluginNodeHostCommand; + source: string; + rootDir?: string; +}; + +export type PluginSecurityAuditCollectorRegistration = { + pluginId: string; + pluginName?: string; + collector: OpenClawPluginSecurityAuditCollector; + source: string; + rootDir?: string; +}; + +export type PluginCommandRegistration = { + pluginId: string; + pluginName?: string; + command: OpenClawPluginCommandDefinition; + source: string; + rootDir?: string; +}; + +export type PluginConversationBindingResolvedHandlerRegistration = { + pluginId: string; + pluginName?: string; + pluginRoot?: string; + handler: (event: PluginConversationBindingResolvedEvent) => void | Promise; + source: string; + rootDir?: string; +}; + +export type PluginRecord = { + id: string; + name: string; + version?: string; + description?: string; + format?: PluginFormat; + bundleFormat?: PluginBundleFormat; + bundleCapabilities?: string[]; + kind?: PluginKind | PluginKind[]; + source: string; + rootDir?: string; + origin: PluginOrigin; + workspaceDir?: string; + enabled: boolean; + explicitlyEnabled?: boolean; + activated?: boolean; + imported?: boolean; + activationSource?: PluginActivationSource; + activationReason?: string; + status: "loaded" | "disabled" | "error"; + error?: string; + failedAt?: Date; + failurePhase?: "validation" | "load" | "register"; + toolNames: string[]; + hookNames: string[]; + channelIds: string[]; + cliBackendIds: string[]; + providerIds: string[]; + speechProviderIds: string[]; + realtimeTranscriptionProviderIds: string[]; + realtimeVoiceProviderIds: string[]; + mediaUnderstandingProviderIds: string[]; + imageGenerationProviderIds: string[]; + videoGenerationProviderIds: string[]; + musicGenerationProviderIds: string[]; + webFetchProviderIds: string[]; + webSearchProviderIds: string[]; + memoryEmbeddingProviderIds: string[]; + gatewayMethods: string[]; + cliCommands: string[]; + services: string[]; + commands: string[]; + httpRoutes: number; + hookCount: number; + configSchema: boolean; + configUiHints?: Record; + configJsonSchema?: Record; + contracts?: PluginManifestContracts; + memorySlotSelected?: boolean; +}; + +export type PluginRegistry = { + plugins: PluginRecord[]; + tools: PluginToolRegistration[]; + hooks: PluginHookRegistration[]; + typedHooks: TypedPluginHookRegistration[]; + channels: PluginChannelRegistration[]; + channelSetups: PluginChannelSetupRegistration[]; + providers: PluginProviderRegistration[]; + cliBackends?: PluginCliBackendRegistration[]; + speechProviders: PluginSpeechProviderRegistration[]; + realtimeTranscriptionProviders: PluginRealtimeTranscriptionProviderRegistration[]; + realtimeVoiceProviders: PluginRealtimeVoiceProviderRegistration[]; + mediaUnderstandingProviders: PluginMediaUnderstandingProviderRegistration[]; + imageGenerationProviders: PluginImageGenerationProviderRegistration[]; + videoGenerationProviders: PluginVideoGenerationProviderRegistration[]; + musicGenerationProviders: PluginMusicGenerationProviderRegistration[]; + webFetchProviders: PluginWebFetchProviderRegistration[]; + webSearchProviders: PluginWebSearchProviderRegistration[]; + memoryEmbeddingProviders: PluginMemoryEmbeddingProviderRegistration[]; + gatewayHandlers: GatewayRequestHandlers; + gatewayMethodScopes?: Partial>; + httpRoutes: PluginHttpRouteRegistration[]; + cliRegistrars: PluginCliRegistration[]; + reloads?: PluginReloadRegistration[]; + nodeHostCommands?: PluginNodeHostCommandRegistration[]; + securityAuditCollectors?: PluginSecurityAuditCollectorRegistration[]; + services: PluginServiceRegistration[]; + commands: PluginCommandRegistration[]; + conversationBindingResolvedHandlers: PluginConversationBindingResolvedHandlerRegistration[]; + diagnostics: PluginDiagnostic[]; +}; + +export type PluginRegistryParams = { + logger: PluginLogger; + coreGatewayHandlers?: GatewayRequestHandlers; + runtime: PluginRuntime; + activateGlobalSideEffects?: boolean; +}; + +export type PluginRegistrationMode = import("./types.js").PluginRegistrationMode; +export type OpenClawPluginNodeHostCommand = import("./types.js").OpenClawPluginNodeHostCommand; +export type OpenClawPluginToolContext = import("./types.js").OpenClawPluginToolContext; +export type OpenClawPluginHttpRouteParams = import("./types.js").OpenClawPluginHttpRouteParams; +export type OpenClawPluginHookOptions = import("./types.js").OpenClawPluginHookOptions; +export type PluginHookHandlerMap = import("./types.js").PluginHookHandlerMap; +export type OpenClawPluginApi = import("./types.js").OpenClawPluginApi; +export type TypedPluginHook = TypedPluginHookRegistration; +export type OpenClawPluginChannelReg = OpenClawPluginChannelRegistration; diff --git a/src/plugins/registry.ts b/src/plugins/registry.ts index e152412be8d..0d55fe8831e 100644 --- a/src/plugins/registry.ts +++ b/src/plugins/registry.ts @@ -3,10 +3,7 @@ import type { AnyAgentTool } from "../agents/tools/common.js"; import type { ChannelPlugin } from "../channels/plugins/types.js"; import { registerContextEngineForOwner } from "../context-engine/registry.js"; import type { OperatorScope } from "../gateway/method-scopes.js"; -import type { - GatewayRequestHandler, - GatewayRequestHandlers, -} from "../gateway/server-methods/types.js"; +import type { GatewayRequestHandler } from "../gateway/server-methods/types.js"; import { registerInternalHook } from "../hooks/internal-hooks.js"; import type { HookEntry } from "../hooks/types.js"; import { @@ -26,14 +23,11 @@ import { getRegisteredCompactionProvider, registerCompactionProvider, } from "./compaction-provider.js"; -import type { PluginActivationSource } from "./config-state.js"; import { normalizePluginHttpPath } from "./http-path.js"; import { findOverlappingPluginHttpRoute } from "./http-route-overlap.js"; import { registerPluginInteractiveHandler } from "./interactive-registry.js"; -import type { PluginManifestContracts } from "./manifest.js"; import { getRegisteredMemoryEmbeddingProvider, - type MemoryEmbeddingProviderAdapter, registerMemoryEmbeddingProvider, } from "./memory-embedding-providers.js"; import { @@ -46,6 +40,23 @@ import { } from "./memory-state.js"; import { normalizeRegisteredProvider } from "./provider-validation.js"; import { createEmptyPluginRegistry } from "./registry-empty.js"; +import type { + PluginCliBackendRegistration, + PluginCliRegistration, + PluginCommandRegistration, + PluginConversationBindingResolvedHandlerRegistration, + PluginHookRegistration, + PluginHttpRouteRegistration, + PluginMemoryEmbeddingProviderRegistration, + PluginNodeHostCommandRegistration, + PluginProviderRegistration, + PluginRecord, + PluginRegistry, + PluginRegistryParams, + PluginReloadRegistration, + PluginSecurityAuditCollectorRegistration, + PluginServiceRegistration, +} from "./registry-types.js"; import { withPluginRuntimePluginIdScope } from "./runtime/gateway-request-scope.js"; import type { PluginRuntime } from "./runtime/types.js"; import { defaultSlotIdForKey, hasKind } from "./slots.js"; @@ -58,106 +69,36 @@ import type { CliBackendPlugin, ImageGenerationProviderPlugin, MusicGenerationProviderPlugin, - RealtimeTranscriptionProviderPlugin, OpenClawPluginApi, OpenClawPluginChannelRegistration, OpenClawPluginCliCommandDescriptor, OpenClawPluginCliRegistrar, OpenClawPluginCommandDefinition, PluginConversationBindingResolvedEvent, - OpenClawPluginHttpRouteAuth, - OpenClawPluginHttpRouteMatch, - OpenClawPluginHttpRouteHandler, OpenClawPluginHttpRouteParams, OpenClawPluginHookOptions, OpenClawPluginNodeHostCommand, OpenClawPluginReloadRegistration, OpenClawPluginSecurityAuditCollector, MediaUnderstandingProviderPlugin, - ProviderPlugin, - RealtimeVoiceProviderPlugin, OpenClawPluginService, OpenClawPluginToolContext, OpenClawPluginToolFactory, - PluginConfigUiHint, PluginDiagnostic, - PluginBundleFormat, - PluginFormat, - PluginLogger, - PluginOrigin, - PluginKind, - PluginRegistrationMode, - PluginHookName, PluginHookHandlerMap, + PluginHookName, PluginHookRegistration as TypedPluginHookRegistration, + PluginLogger, + PluginRegistrationMode, + ProviderPlugin, + RealtimeTranscriptionProviderPlugin, + RealtimeVoiceProviderPlugin, SpeechProviderPlugin, VideoGenerationProviderPlugin, WebFetchProviderPlugin, WebSearchProviderPlugin, } from "./types.js"; -export type PluginToolRegistration = { - pluginId: string; - pluginName?: string; - factory: OpenClawPluginToolFactory; - names: string[]; - optional: boolean; - source: string; - rootDir?: string; -}; - -export type PluginCliRegistration = { - pluginId: string; - pluginName?: string; - register: OpenClawPluginCliRegistrar; - commands: string[]; - descriptors: OpenClawPluginCliCommandDescriptor[]; - source: string; - rootDir?: string; -}; - -export type PluginHttpRouteRegistration = { - pluginId?: string; - path: string; - handler: OpenClawPluginHttpRouteHandler; - auth: OpenClawPluginHttpRouteAuth; - match: OpenClawPluginHttpRouteMatch; - source?: string; -}; - -export type PluginChannelRegistration = { - pluginId: string; - pluginName?: string; - plugin: ChannelPlugin; - source: string; - rootDir?: string; -}; - -export type PluginChannelSetupRegistration = { - pluginId: string; - pluginName?: string; - plugin: ChannelPlugin; - source: string; - enabled: boolean; - rootDir?: string; -}; - -export type PluginProviderRegistration = { - pluginId: string; - pluginName?: string; - provider: ProviderPlugin; - source: string; - rootDir?: string; -}; - -export type PluginCliBackendRegistration = { - pluginId: string; - pluginName?: string; - backend: CliBackendPlugin; - source: string; - rootDir?: string; -}; - type PluginOwnedProviderRegistration = { pluginId: string; pluginName?: string; @@ -166,175 +107,35 @@ type PluginOwnedProviderRegistration = { rootDir?: string; }; -export type PluginSpeechProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginRealtimeTranscriptionProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginRealtimeVoiceProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginMediaUnderstandingProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginImageGenerationProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginVideoGenerationProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginMusicGenerationProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginWebFetchProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginWebSearchProviderRegistration = - PluginOwnedProviderRegistration; -export type PluginMemoryEmbeddingProviderRegistration = - PluginOwnedProviderRegistration; - -export type PluginHookRegistration = { - pluginId: string; - entry: HookEntry; - events: string[]; - source: string; - rootDir?: string; -}; - -export type PluginServiceRegistration = { - pluginId: string; - pluginName?: string; - service: OpenClawPluginService; - source: string; - rootDir?: string; -}; - -export type PluginReloadRegistration = { - pluginId: string; - pluginName?: string; - registration: OpenClawPluginReloadRegistration; - source: string; - rootDir?: string; -}; - -export type PluginNodeHostCommandRegistration = { - pluginId: string; - pluginName?: string; - command: OpenClawPluginNodeHostCommand; - source: string; - rootDir?: string; -}; - -export type PluginSecurityAuditCollectorRegistration = { - pluginId: string; - pluginName?: string; - collector: OpenClawPluginSecurityAuditCollector; - source: string; - rootDir?: string; -}; - -export type PluginCommandRegistration = { - pluginId: string; - pluginName?: string; - command: OpenClawPluginCommandDefinition; - source: string; - rootDir?: string; -}; - -export type PluginConversationBindingResolvedHandlerRegistration = { - pluginId: string; - pluginName?: string; - pluginRoot?: string; - handler: (event: PluginConversationBindingResolvedEvent) => void | Promise; - source: string; - rootDir?: string; -}; - -export type PluginRecord = { - id: string; - name: string; - version?: string; - description?: string; - format?: PluginFormat; - bundleFormat?: PluginBundleFormat; - bundleCapabilities?: string[]; - kind?: PluginKind | PluginKind[]; - source: string; - rootDir?: string; - origin: PluginOrigin; - workspaceDir?: string; - enabled: boolean; - explicitlyEnabled?: boolean; - activated?: boolean; - imported?: boolean; - activationSource?: PluginActivationSource; - activationReason?: string; - status: "loaded" | "disabled" | "error"; - error?: string; - failedAt?: Date; - failurePhase?: "validation" | "load" | "register"; - toolNames: string[]; - hookNames: string[]; - channelIds: string[]; - cliBackendIds: string[]; - providerIds: string[]; - speechProviderIds: string[]; - realtimeTranscriptionProviderIds: string[]; - realtimeVoiceProviderIds: string[]; - mediaUnderstandingProviderIds: string[]; - imageGenerationProviderIds: string[]; - videoGenerationProviderIds: string[]; - musicGenerationProviderIds: string[]; - webFetchProviderIds: string[]; - webSearchProviderIds: string[]; - memoryEmbeddingProviderIds: string[]; - gatewayMethods: string[]; - cliCommands: string[]; - services: string[]; - commands: string[]; - httpRoutes: number; - hookCount: number; - configSchema: boolean; - configUiHints?: Record; - configJsonSchema?: Record; - contracts?: PluginManifestContracts; - memorySlotSelected?: boolean; -}; - -export type PluginRegistry = { - plugins: PluginRecord[]; - tools: PluginToolRegistration[]; - hooks: PluginHookRegistration[]; - typedHooks: TypedPluginHookRegistration[]; - channels: PluginChannelRegistration[]; - channelSetups: PluginChannelSetupRegistration[]; - providers: PluginProviderRegistration[]; - cliBackends?: PluginCliBackendRegistration[]; - speechProviders: PluginSpeechProviderRegistration[]; - realtimeTranscriptionProviders: PluginRealtimeTranscriptionProviderRegistration[]; - realtimeVoiceProviders: PluginRealtimeVoiceProviderRegistration[]; - mediaUnderstandingProviders: PluginMediaUnderstandingProviderRegistration[]; - imageGenerationProviders: PluginImageGenerationProviderRegistration[]; - videoGenerationProviders: PluginVideoGenerationProviderRegistration[]; - musicGenerationProviders: PluginMusicGenerationProviderRegistration[]; - webFetchProviders: PluginWebFetchProviderRegistration[]; - webSearchProviders: PluginWebSearchProviderRegistration[]; - memoryEmbeddingProviders: PluginMemoryEmbeddingProviderRegistration[]; - gatewayHandlers: GatewayRequestHandlers; - gatewayMethodScopes?: Partial>; - httpRoutes: PluginHttpRouteRegistration[]; - cliRegistrars: PluginCliRegistration[]; - reloads?: PluginReloadRegistration[]; - nodeHostCommands?: PluginNodeHostCommandRegistration[]; - securityAuditCollectors?: PluginSecurityAuditCollectorRegistration[]; - services: PluginServiceRegistration[]; - commands: PluginCommandRegistration[]; - conversationBindingResolvedHandlers: PluginConversationBindingResolvedHandlerRegistration[]; - diagnostics: PluginDiagnostic[]; -}; - -export type PluginRegistryParams = { - logger: PluginLogger; - coreGatewayHandlers?: GatewayRequestHandlers; - runtime: PluginRuntime; - // When false, keep registration local to the returned registry and avoid mutating - // process-global command/hook state during non-activating snapshot loads. - activateGlobalSideEffects?: boolean; -}; +export type { + PluginChannelRegistration, + PluginChannelSetupRegistration, + PluginCliBackendRegistration, + PluginCliRegistration, + PluginCommandRegistration, + PluginConversationBindingResolvedHandlerRegistration, + PluginHookRegistration, + PluginHttpRouteRegistration, + PluginMemoryEmbeddingProviderRegistration, + PluginNodeHostCommandRegistration, + PluginProviderRegistration, + PluginRecord, + PluginRegistry, + PluginRegistryParams, + PluginReloadRegistration, + PluginSecurityAuditCollectorRegistration, + PluginServiceRegistration, + PluginToolRegistration, + PluginSpeechProviderRegistration, + PluginRealtimeTranscriptionProviderRegistration, + PluginRealtimeVoiceProviderRegistration, + PluginMediaUnderstandingProviderRegistration, + PluginImageGenerationProviderRegistration, + PluginVideoGenerationProviderRegistration, + PluginMusicGenerationProviderRegistration, + PluginWebFetchProviderRegistration, + PluginWebSearchProviderRegistration, +} from "./registry-types.js"; type PluginTypedHookPolicy = { allowPromptInjection?: boolean;