Skip to content

FlowDrop Interrupt

Human-in-the-loop interrupt system that pauses workflows to request user input via confirmations, choices, text, or JSON schema forms.

Overview

The flowdrop_interrupt module enables workflows to pause execution and request user input. When a workflow reaches an interrupt node, it throws an InterruptRequiredException carrying a typed message DTO; a catch-side subscriber persists the interrupt entity, pauses the pipeline, and dispatches the message on the bus. Once resolved, the pipeline resumes from where it left off.

Four interrupt types are provided out of the box: confirmation (yes/no), choice selection, free-text input, and JSON schema-driven forms. The module integrates with both pipeline-based execution and session-based interactive workflows.

Since 1.4.0 the creation path is message-driven: node processors don't call the InterruptManager synchronously anymore — they throw InterruptRequiredException(new HitlInterruptMessage(...)) (or the linked / inward-signal variants), and JobInterruptCaughtSubscriber runs the persistence + bus dispatch on the catch side. Two new interrupt directions are first-class alongside the original outward HITL prompt:

Direction Message DTO Use case
Outward (HITL) HitlInterruptMessage Prompt the user for input (confirmation, choice, text, form).
Linked LinkedInterruptMessage Pause one pipeline until another resolves — e.g. WorkflowNode waiting for a sub-pipeline to complete asynchronously.
Inward signal InwardSignalMessage Carry an operator-initiated Cancel/Pause signal to a running pipeline; PipelineSignalPollEvent is the bridge the orchestrator polls between jobs.

Dependencies

Configuration

Permissions

Permission Description
administer flowdrop interrupts Full administrative access. Restricted.
view flowdrop interrupts View interrupt requests
resolve flowdrop interrupts Respond to interrupt requests
cancel flowdrop interrupts Cancel pending interrupt requests

Tips and Tricks

Interrupt Types

Type Use Case Node Processor
Confirmation Yes/No decisions (e.g., "Proceed with deletion?") ConfirmationNode
Choice Select from predefined options (single or multiple) ChoiceNode
Text Input Free-form text collection (e.g., "Enter a reason") TextInputNode
Form Input Structured data via JSON Schema forms FormInputNode

Interrupt Resolution Flow

Workflow reaches interrupt node
    → Node throws InterruptRequiredException(InterruptMessageInterface)
    → JobInterruptCaughtSubscriber catches it:
        ├── InterruptFactoryInterface::create(InterruptCreationData) persists entity
        └── InterruptMessageBus dispatches message to the registered handler
    → Pipeline pauses, job marked as interrupted (status: pending)
    → User resolves via API (POST /api/flowdrop/interrupts/{id})
    → InterruptResolvedSubscriber resets job to pending
    → Pipeline resumes execution

For backward compatibility the synchronous InterruptManagerInterface::createInterrupt() and the public InterruptRequiredException::$interrupt property are kept as deprecated shims for 1.3.x callers; both will be removed in 2.0.0. See #3591539.

Message Handlers

Handlers are attribute-discovered services tagged flowdrop_interrupt.message_handler and implement InterruptMessageHandlerInterface::supports() to claim one concrete message class. The InterruptMessageHandlerPass compiler pass fails the build if two handlers claim the same class or if a tagged service doesn't implement the interface — wiring errors surface at container compile, not at first dispatch.

Handler Persists
HitlInterruptMessageHandler HitlInterruptMessage (always stamps InterruptDirection::Outward).
LinkedInterruptMessageHandler LinkedInterruptMessage (linkage stored on the typed linked_interrupt_id column).
InwardSignalMessageHandler InwardSignalMessage (stamps initiator + targetPipelineId).
PipelineCompletionSentinelMessageHandler (in flowdrop_workflow_executor) PipelineCompletionSentinelMessage (sub-pipeline → parent linkage).

Session-Aware Interrupts

When interrupts occur within a session context, the SessionInterruptResolvedSubscriber handles additional session state updates and message creation, keeping the interactive UI in sync.

Developer API

Services

Service ID Class Description
flowdrop_interrupt.manager InterruptManager Resolves, cancels, and queries interrupt requests. The 11-parameter createInterrupt() is deprecated in 1.4.0; throw InterruptRequiredException or use InterruptFactoryInterface::create() instead.
flowdrop_interrupt.factory InterruptFactory (1.4.0+) Persists a new interrupt from an InterruptCreationData DTO. The JobInterruptCaughtSubscriber calls this on the catch side.
flowdrop_interrupt.message_bus InterruptMessageBus (1.4.0+) Dispatches an InterruptMessageInterface to its registered handler.
flowdrop_interrupt.interrupt_resolved_subscriber InterruptResolvedSubscriber Resets interrupted jobs and resumes pipeline execution
flowdrop_interrupt.session_interrupt_resolved_subscriber SessionInterruptResolvedSubscriber Session-aware interrupt resolution (higher priority)

Entities

FlowDropInterrupt (Content Entity)

Stores interrupt requests with the interrupt type, prompt/configuration, response data, and status (pending, resolved, cancelled).

API Endpoints

Method Path Description
GET /api/flowdrop/interrupts/{interrupt_id} Get interrupt details
POST /api/flowdrop/interrupts/{interrupt_id} Resolve an interrupt (submit response)
POST /api/flowdrop/interrupts/{interrupt_id}/cancel Cancel a pending interrupt
GET /api/flowdrop/playground/sessions/{session_id}/interrupts List interrupts for a session
GET /api/flowdrop/pipelines/{pipeline_id}/interrupts List interrupts for a pipeline

Node Processors

Plugin Description
ConfirmationNode Creates a yes/no confirmation interrupt
ChoiceNode Creates a choice selection interrupt
TextInputNode Creates a free-text input interrupt
FormInputNode Creates a JSON schema form interrupt

References