# Node Processor Plugin API

!!! info "Stable API"
    Classes on this page are marked `@api` and are guaranteed backward compatible in the 1.x release line.
    See the [BC Policy](bc-policy.md) for details.

The FlowDropNodeProcessor plugin system is the primary extension point for FlowDrop. Use these classes to create custom node types that appear in the visual workflow editor.

## Overview

| Class | Type | Description |
|-------|------|-------------|
| [`FlowDropNodeProcessor`](#flowdropnodeprocessor-attribute) | final class | Attribute for FlowDropNode plugins. |
| [`FlowDropNodeProcessorInterface`](#flowdropnodeprocessorinterface) | interface | Interface for FlowDropNodeProcessor plugins. |
| [`AbstractFlowDropNodeProcessor`](#abstractflowdropnodeprocessor) | abstract class | Abstract base class for FlowDropNode plugins. |
| [`NodeExecutorInterface`](#nodeexecutorinterface) | interface | Interface for node executors. |
| [`ConfigEditProviderInterface`](#configeditproviderinterface) | interface | Interface for node processors that provide dynamic configuration editing. |
| [`ExecutionContextAwareInterface`](#executioncontextawareinterface) | interface | Interface for processors that need access to execution context. |
| [`TriggerNodeProcessorInterface`](#triggernodeprocessorinterface) | interface | Marker interface for trigger node processors. |
| [`FlowDropNodeProcessorPluginManager`](#flowdropnodeprocessorpluginmanager) | class | Plugin manager for FlowDropNode plugins using attribute-based discovery. |

## FlowDropNodeProcessor (Attribute)

**Namespace:** `Drupal\flowdrop\Attribute`  
**Type:** final class  
**Extends:** `Plugin`  
**Source:** `src/Attribute/FlowDropNodeProcessor.php`  

Attribute for FlowDropNode plugins.

This attribute provides plugin discovery metadata
for FlowDrop node processors.
Parameters are defined via getParameterSchema()
method, not in this attribute.
Category, tags, and visual type are managed by the config entity,
not by the plugin attribute.

### Constructor Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `$id` | `string` | — | The plugin ID. |
| `$label` | `TranslatableMarkup` | — | The human-readable label. |
| `$description` | `string` | "" | The component description. |
| `$version` | `string` | "1.0.0" | The component version. |
| `$deriver` | `?string` | NULL | (optional) The deriver class. |

---

## FlowDropNodeProcessorInterface

**Namespace:** `Drupal\flowdrop\Plugin\FlowDropNodeProcessor`  
**Type:** interface  
**Extends:** `NodeExecutorInterface`  
**Source:** `src/Plugin/FlowDropNodeProcessor/FlowDropNodeProcessorInterface.php`  

Interface for FlowDropNodeProcessor plugins.

This interface defines the contract for node processor plugins in FlowDrop.
Plugins must implement the Unified Parameter System via getParameterSchema().

Note: Visual type is managed by the config entity (FlowDropNodeType),
not by the plugin. This allows site builders to choose the visual format.

### Methods

#### `getId(): string`

Get the component ID.

#### `getName(): string`

Get the component name.

#### `getDescription(): string`

Get the component description.

#### `getVersion(): string`

Get the component version.

#### `validateParams(array $params): ValidationResult`

Validate parameters for the node.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$params` | `array` | The parameters to validate. |

#### `getOutputSchema(): array`

Get the output schema for this node.

#### `getParameterSchema(): array`

Get the parameter schema for this node.

---

## AbstractFlowDropNodeProcessor

**Namespace:** `Drupal\flowdrop\Plugin\FlowDropNodeProcessor`  
**Type:** abstract class  
**Extends:** `PluginBase`  
**Implements:** `FlowDropNodeProcessorInterface`, `ContainerFactoryPluginInterface`  
**Source:** `src/Plugin/FlowDropNodeProcessor/AbstractFlowDropNodeProcessor.php`  

Abstract base class for FlowDropNode plugins.

This class provides common functionality for FlowDropNode plugins and
implements default behavior for the FlowDropNodeProcessorInterface methods.

All plugins must implement:
- getParameterSchema(): Define the data contract (types, defaults,
  constraints)
- process(ParameterBagInterface $params): The main processing logic

LOGGING POLICY:
- Routine logging (start, complete, input/output) is handled by the
  orchestration layer via ExecutionLogger.
- Processors should ONLY log exceptional events worth flagging:
  - External service retries/failures
  - Fallback usage
  - Rate limits
  - Unexpected data shapes
- For such exceptional logging, inject LoggerChannelFactoryInterface
  in the concrete processor that needs it.

Note: UI/workflow behavior (connectable, configurable, required) is
controlled entirely by the config entity, not by the plugin schema.

### Methods

#### `getOutputSchema(): array`

#### `getParameterSchema(): array`

Default implementation returns an empty schema.
Subclasses should override this to define their parameters.

#### `getId(): string`

#### `getName(): string`

#### `getDescription(): string`

#### `getVersion(): string`

#### `validateParams(array $params): ValidationResult`

---

## NodeExecutorInterface

**Namespace:** `Drupal\flowdrop\Plugin\FlowDropNodeProcessor`  
**Type:** interface  
**Source:** `src/Plugin/FlowDropNodeProcessor/NodeExecutorInterface.php`  

Interface for node executors.

This interface defines the contract for node processors that
execute workflow nodes using the Unified Parameter System.

### Methods

#### `process(ParameterBagInterface $params): array`

Execute a node with resolved parameters.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$params` | `ParameterBagInterface` | The resolved parameters (merged from config, workflow values, and inputs). |

**Throws:** `Exception`

---

## ConfigEditProviderInterface

**Namespace:** `Drupal\flowdrop\Plugin\FlowDropNodeProcessor`  
**Type:** interface  
**Source:** `src/Plugin/FlowDropNodeProcessor/ConfigEditProviderInterface.php`  

Interface for node processors that provide dynamic configuration editing.

Implement this interface on your FlowDropNodeProcessor plugin to indicate
that the node supports dynamic configuration editing. This allows:

- Dynamic schema fetching from REST endpoints at runtime
- External edit links to admin forms or third-party configuration UIs
- API endpoints for CRUD operations on configuration entities

When a plugin implements this interface, the FlowDrop frontend will
use the provided configuration to render appropriate UI controls
for editing the node's configuration.

Example implementation:

### Methods

#### `getConfigEdit(): ConfigEdit`

Get the configuration edit options for this node processor.

---

## ExecutionContextAwareInterface

**Namespace:** `Drupal\flowdrop\Plugin\FlowDropNodeProcessor`  
**Type:** interface  
**Source:** `src/Plugin/FlowDropNodeProcessor/ExecutionContextAwareInterface.php`  

Interface for processors that need access to execution context.

Implement this interface when your processor needs access to:
- Initial workflow data (trigger payload, input data)
- Workflow, pipeline, or execution identifiers
- Execution metadata.

The runtime will automatically inject the ExecutionContextDTO before
calling execute() on processors that implement this interface.

Example usage:

### Methods

#### `setExecutionContext(ExecutionContextDTO $context): void`

Sets the execution context for this processor.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$context` | `ExecutionContextDTO` | The execution context containing workflow data and identifiers. |

---

## TriggerNodeProcessorInterface

**Namespace:** `Drupal\flowdrop\Plugin\FlowDropNodeProcessor`  
**Type:** interface  
**Source:** `src/Plugin/FlowDropNodeProcessor/TriggerNodeProcessorInterface.php`  

Marker interface for trigger node processors.

Processors that implement this interface are considered trigger nodes,
which can initiate workflow executions. When a workflow is triggered
by an event, only the trigger node that fired the event should be
executed, while all other trigger nodes in the workflow should be excluded.

This interface is intentionally empty. It serves as a type marker used by
JobGenerationService::isTriggerNodeProcessor() to identify trigger nodes
during job generation — trigger nodes are excluded from the pipeline unless
they are the specific trigger that fired the workflow.

Using instanceof/is_subclass_of checks with this marker interface provides
compile-time safety that attribute-based detection would not.

---

## FlowDropNodeProcessorPluginManager

**Namespace:** `Drupal\flowdrop\Service`  
**Type:** class  
**Extends:** `DefaultPluginManager`  
**Source:** `src/Service/FlowDropNodeProcessorPluginManager.php`  

Plugin manager for FlowDropNode plugins using attribute-based discovery.

This manager automatically namespaces plugin IDs with their provider module
to prevent ID collisions when multiple modules define plugins with the same
base ID. For example, a plugin with `id: "chat_model"` from module
`flowdrop_ai_provider` becomes `flowdrop_ai_provider:chat_model`.

The namespacing format is: `{provider}:{original_id}`

Supports plugin derivers via DerivativeDiscoveryDecorator, enabling modules
to dynamically generate multiple plugin instances from a single base plugin.
Derivative plugins (e.g., `tool_api:entity_save`) are also namespaced with
their provider to ensure uniqueness across modules.

### Constants

| Constant | Value | Description |
|----------|-------|-------------|
| `NAMESPACE_SEPARATOR` | ":" | The separator used between provider and plugin ID. |

### Methods

#### `processDefinition(array<string,mixed> $definition, string $plugin_id): void`

Processes plugin definitions to add provider-based namespacing.

This method prefixes each plugin ID with its provider module name,
ensuring unique IDs across all contributing modules. The original
(non-prefixed) ID is preserved in the 'original_id' property.

For derivative plugins (e.g., `tool_api:entity_save`), the full composite
ID is namespaced with the provider to ensure unique IDs across modules.
The derivative's ":" separator is distinct from the provider namespace.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$definition` | `array<string,mixed>` | The plugin definition to process. |
| `$plugin_id` | `string` | The plugin ID. |

#### `protected findDefinitions(): array`

Re-keys definitions by their namespaced IDs after processing.

#### `buildNamespacedId(string $provider, string $originalId): string`

Builds a namespaced plugin ID from provider and original ID.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$provider` | `string` | The provider module name. |
| `$originalId` | `string` | The original plugin ID. |

#### `isNamespaced(string $pluginId): bool`

Checks if a plugin ID contains a namespace separator.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$pluginId` | `string` | The plugin ID to check. |

#### `isProviderNamespaced(string $pluginId, string $provider): bool`

Checks if a plugin ID is already namespaced with a specific provider.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$pluginId` | `string` | The plugin ID to check. |
| `$provider` | `string` | The provider module name to check for. |

#### `getProviderFromNamespacedId(string $pluginId): ?string`

Extracts the provider from a namespaced plugin ID.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$pluginId` | `string` | The namespaced plugin ID. |

#### `getOriginalIdFromNamespacedId(string $pluginId): string`

Extracts the original ID from a namespaced plugin ID.

| Parameter | Type | Description |
|-----------|------|-------------|
| `$pluginId` | `string` | The namespaced plugin ID. |

---

## See Also

- [Create a Node Processor](../../development/quick-reference/define-node.md) — step-by-step tutorial
- [Node Processor Concepts](../../development/flowdrop-node-processor.md) — deep dive into the plugin system
- [BC Policy](bc-policy.md) — backward compatibility guarantees

---

*This page was auto-generated from source code PHPDoc annotations. Run `php scripts/generate-api-docs.php` to regenerate.*
