Class PluginService
- All Implemented Interfaces:
ai.nervemind.common.service.PluginServiceInterface
This service is the core implementation of the NerveMind plugin system. It handles the complete plugin lifecycle from discovery to enabling/disabling at runtime.
Plugin Discovery Sources
Plugins are discovered from two sources during application startup:
- Classpath plugins - Bundled JAR dependencies discovered
via
ServiceLoader. These are declared inbuild.gradleas runtime dependencies. - External plugins - JAR files placed in the
plugins/directory, loaded dynamically viaPluginLoader.
Architecture
┌──────────────────────────────────┐
│ PluginService │
│ (Spring @Service singleton) │
└──────────────────────────────────┘
│
┌──────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
│ ServiceLoader │ │ PluginLoader │ │ SettingsService │
│ (Classpath JARs) │ │ (External JARs) │ │ (Persistence) │
└────────────────────┘ └────────────────────┘ └────────────────────┘
Plugin State Management
The service maintains two categories of plugin registries:
- Discovered plugins (
discoveredTriggers,discoveredActions) - All plugins found during discovery, regardless of enabled state. - Enabled plugins (
enabledTriggers,enabledActions) - Only plugins that are currently enabled and available for use.
Thread Safety
This service uses ConcurrentHashMap for all
plugin registries to support safe concurrent access from HTTP request
threads,
workflow execution threads, and the UI thread.
Usage Example
@Autowired
private PluginService pluginService;
// Get all available (enabled) triggers
Collection<TriggerProvider> triggers = pluginService.getTriggerProviders();
// Get a specific trigger's executor for workflow execution
Optional<NodeExecutor> executor = pluginService.getExecutor("ai.nervemind.plugin.filewatcher");
executor.ifPresent(exec -> exec.execute(context));
- Since:
- 1.0.0
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface ai.nervemind.common.service.PluginServiceInterface
ai.nervemind.common.service.PluginServiceInterface.ContextMenuAction, ai.nervemind.common.service.PluginServiceInterface.HandleInfo, ai.nervemind.common.service.PluginServiceInterface.MenuContribution, ai.nervemind.common.service.PluginServiceInterface.MenuLocation, ai.nervemind.common.service.PluginServiceInterface.PanelPosition, ai.nervemind.common.service.PluginServiceInterface.PluginInfo, ai.nervemind.common.service.PluginServiceInterface.SidePanelContribution -
Constructor Summary
ConstructorsConstructorDescriptionPluginService(ai.nervemind.common.service.SettingsServiceInterface settingsService, PluginLoader pluginLoader) Constructs the PluginService with required dependencies. -
Method Summary
Modifier and TypeMethodDescriptionvoiddisablePlugin(String pluginId) Disable a plugin.voidDiscovers and registers all available plugins at application startup.voidenablePlugin(String pluginId) Enable a plugin.Optional<ai.nervemind.plugin.api.ActionProvider> Gets the action provider for the specified node type.Collection<ai.nervemind.plugin.api.ActionProvider> Gets all enabled action providers.List<ai.nervemind.common.service.PluginServiceInterface.PluginInfo> List<ai.nervemind.common.service.PluginServiceInterface.MenuContribution> Gets all menu contributions from enabled plugins.Collection<ai.nervemind.plugin.api.NodeDescriptor> Gets all enabled node descriptors.List<ai.nervemind.common.service.PluginServiceInterface.SidePanelContribution> Gets all side panel contributions from enabled plugins.getCustomNodeView(String nodeType, String nodeId, String displayName, Map<String, Object> settings, boolean selected, boolean executing, boolean error) Gets a custom node view from a PluginProvider, if available.Optional<ai.nervemind.plugin.api.NodeExecutor> getExecutor(String nodeType) Gets the executor for the specified node type.List<ai.nervemind.common.service.PluginServiceInterface.HandleInfo> getHandleDefinitions(String nodeType) Gets the handle definitions for a node type.Get information about loaded plugin JARs.Optional<ai.nervemind.plugin.api.NodeDescriptor> Gets the node descriptor for the specified node type.Gets all node descriptors grouped by category.Optional<ai.nervemind.plugin.api.PluginProvider> getPluginProvider(String nodeType) Get a specific PluginProvider by node type.getPluginProviderInstance(String pluginId) Collection<ai.nervemind.plugin.api.PluginProvider> Get all enabled PluginProvider implementations.Get the plugins directory path.List<ai.nervemind.plugin.api.PropertyDefinition> getProperties(String nodeType) Gets the property definitions for the specified node type.Optional<ai.nervemind.plugin.api.TriggerProvider> getTrigger(String nodeType) Gets the trigger provider for the specified node type.Collection<ai.nervemind.plugin.api.TriggerProvider> Gets all enabled trigger providers.booleanisPluginEnabled(String pluginId) Check if a plugin is enabled.voidnotifyConnectionCreated(Object connectionContext) voidReload all plugins (classpath + external JARs).booleanrequiresBackgroundService(String nodeType) Checks if the specified node type requires a background service.voidsetPluginEnabled(String pluginId, boolean enabled) Set enabled state for a plugin.
-
Constructor Details
-
PluginService
public PluginService(ai.nervemind.common.service.SettingsServiceInterface settingsService, PluginLoader pluginLoader) Constructs the PluginService with required dependencies.This constructor is called by Spring's dependency injection. The actual plugin discovery occurs in
discoverPlugins()which is annotated withPostConstruct.- Parameters:
settingsService- service for persisting plugin enabled statespluginLoader- loader for external plugin JARs
-
-
Method Details
-
discoverPlugins
@PostConstruct public void discoverPlugins()Discovers and registers all available plugins at application startup.This method is automatically called by Spring after dependency injection via the
PostConstructannotation. It performs a complete plugin discovery from all sources.Discovery Order
- Classpath plugins - Bundled plugins are discovered first
- External plugins - Plugins from the
plugins/directory are loaded and may override classpath versions - Enable state - Previously enabled plugins are restored from settings
After this method completes, use
getAllDiscoveredPlugins()to get the complete list of available plugins, orgetTriggerProviders()andgetActionProviders()to get only enabled plugins.- See Also:
-
getAllDiscoveredPlugins
public List<ai.nervemind.common.service.PluginServiceInterface.PluginInfo> getAllDiscoveredPlugins()- Specified by:
getAllDiscoveredPluginsin interfaceai.nervemind.common.service.PluginServiceInterface
-
isPluginEnabled
Check if a plugin is enabled.- Specified by:
isPluginEnabledin interfaceai.nervemind.common.service.PluginServiceInterface
-
enablePlugin
Enable a plugin.- Specified by:
enablePluginin interfaceai.nervemind.common.service.PluginServiceInterface
-
disablePlugin
Disable a plugin.- Specified by:
disablePluginin interfaceai.nervemind.common.service.PluginServiceInterface
-
setPluginEnabled
Set enabled state for a plugin.- Specified by:
setPluginEnabledin interfaceai.nervemind.common.service.PluginServiceInterface
-
getTriggerProviders
Gets all enabled trigger providers.- Returns:
- an unmodifiable collection of enabled trigger providers
-
getActionProviders
Gets all enabled action providers.- Returns:
- an unmodifiable collection of enabled action providers
-
getAllNodes
Gets all enabled node descriptors.- Returns:
- an unmodifiable collection of enabled node descriptors
-
getTrigger
-
getAction
-
getNode
-
getExecutor
-
getProperties
-
requiresBackgroundService
Checks if the specified node type requires a background service.- Parameters:
nodeType- the node type to check- Returns:
- true if the node type requires a background service
-
getNodesByCategory
-
reloadPlugins
public void reloadPlugins()Reload all plugins (classpath + external JARs). Useful after adding new plugin JARs to the plugins directory. -
getLoadedPluginJars
Get information about loaded plugin JARs.- Returns:
- a list of information about loaded plugin JARs
-
getPluginsDirectory
Get the plugins directory path.- Returns:
- the path to the plugins directory
-
getPluginProviders
Get all enabled PluginProvider implementations.- Returns:
- unmodifiable collection of enabled plugin providers
-
getPluginProvider
-
getPluginProviderInstance
-
getHandleDefinitions
public List<ai.nervemind.common.service.PluginServiceInterface.HandleInfo> getHandleDefinitions(String nodeType) Gets the handle definitions for a node type.If the node type is from a PluginProvider, returns its custom handle definitions. Otherwise, returns the default handles (1 input left, 1 output right).
- Specified by:
getHandleDefinitionsin interfaceai.nervemind.common.service.PluginServiceInterface- Parameters:
nodeType- the node type identifier- Returns:
- list of handle info records
-
getCustomNodeView
public Object getCustomNodeView(String nodeType, String nodeId, String displayName, Map<String, Object> settings, boolean selected, boolean executing, boolean error) Gets a custom node view from a PluginProvider, if available.- Specified by:
getCustomNodeViewin interfaceai.nervemind.common.service.PluginServiceInterface- Parameters:
nodeType- the node type identifiernodeId- the instance node IDdisplayName- the display name of the nodesettings- the node's current settingsselected- whether the node is selectedexecuting- whether the node is executingerror- whether the node has an error- Returns:
- the custom JavaFX node, or null to use default rendering
-
getAllMenuContributions
public List<ai.nervemind.common.service.PluginServiceInterface.MenuContribution> getAllMenuContributions()Gets all menu contributions from enabled plugins.Aggregates menu contributions from all currently enabled PluginProvider implementations. Each contribution is tagged with the source plugin ID.
- Specified by:
getAllMenuContributionsin interfaceai.nervemind.common.service.PluginServiceInterface- Returns:
- list of menu contributions from all enabled plugins
-
getAllSidePanelContributions
public List<ai.nervemind.common.service.PluginServiceInterface.SidePanelContribution> getAllSidePanelContributions()Gets all side panel contributions from enabled plugins.Aggregates side panel contributions from all currently enabled PluginProvider implementations. Each contribution is tagged with the source plugin ID.
- Specified by:
getAllSidePanelContributionsin interfaceai.nervemind.common.service.PluginServiceInterface- Returns:
- list of side panel contributions from all enabled plugins
-
notifyConnectionCreated
- Specified by:
notifyConnectionCreatedin interfaceai.nervemind.common.service.PluginServiceInterface
-