|
| 1 | +--- |
| 2 | +title: Human in the Loop |
| 3 | +--- |
| 4 | + |
| 5 | +import { Callout } from 'fumadocs-ui/components/callout' |
| 6 | +import { Step, Steps } from 'fumadocs-ui/components/steps' |
| 7 | +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' |
| 8 | +import { Image } from '@/components/ui/image' |
| 9 | + |
| 10 | +The Human in the Loop block pauses workflow execution and waits for human intervention before continuing. Use it to add approval gates, collect feedback, enable manual review, or gather additional input at critical decision points in your workflow. |
| 11 | + |
| 12 | +<div className="flex justify-center"> |
| 13 | + <Image |
| 14 | + src="/static/blocks/hitl-1.png" |
| 15 | + alt="Human in the Loop Block Configuration" |
| 16 | + width={500} |
| 17 | + height={400} |
| 18 | + className="my-6" |
| 19 | + /> |
| 20 | +</div> |
| 21 | + |
| 22 | +<Callout type="info"> |
| 23 | + When execution reaches this block, the workflow pauses and waits indefinitely until a human approver provides input or approval through one of the available interfaces. |
| 24 | +</Callout> |
| 25 | + |
| 26 | +## Overview |
| 27 | + |
| 28 | +The Human in the Loop block enables you to: |
| 29 | + |
| 30 | +<Steps> |
| 31 | + <Step> |
| 32 | + <strong>Pause Workflow Execution</strong>: Stop the workflow at a critical point and wait for human input |
| 33 | + </Step> |
| 34 | + <Step> |
| 35 | + <strong>Display Context</strong>: Show relevant workflow data to the approver for informed decision-making |
| 36 | + </Step> |
| 37 | + <Step> |
| 38 | + <strong>Collect Feedback</strong>: Gather approval decisions, comments, edits, or additional data from humans |
| 39 | + </Step> |
| 40 | + <Step> |
| 41 | + <strong>Notify Stakeholders</strong>: Send alerts via Slack, Gmail, or other channels when approval is needed |
| 42 | + </Step> |
| 43 | + <Step> |
| 44 | + <strong>Resume with Input</strong>: Continue workflow execution with the human-provided data |
| 45 | + </Step> |
| 46 | +</Steps> |
| 47 | + |
| 48 | +## How It Works |
| 49 | + |
| 50 | +The Human in the Loop block creates a pause-and-resume flow: |
| 51 | + |
| 52 | +1. **Workflow Pauses** - Execution stops when it reaches the Human in the Loop block |
| 53 | +2. **Context Displayed** - Configured data is shown to the approver through the approval portal |
| 54 | +3. **Notifications Sent** - Alerts are dispatched via configured channels (Slack, email, etc.) |
| 55 | +4. **Human Reviews** - Approver examines the data and provides input or approval |
| 56 | +5. **Workflow Resumes** - Execution continues with the human-provided data available to downstream blocks |
| 57 | + |
| 58 | +<div className="flex justify-center"> |
| 59 | + <Image |
| 60 | + src="/static/blocks/hitl-2.png" |
| 61 | + alt="Human in the Loop Approval Portal" |
| 62 | + width={700} |
| 63 | + height={500} |
| 64 | + className="my-6" |
| 65 | + /> |
| 66 | +</div> |
| 67 | + |
| 68 | +## Configuration Options |
| 69 | + |
| 70 | +### Paused Output |
| 71 | + |
| 72 | +The Paused Output defines what data is displayed to the approver when the workflow pauses. Think of this as the "context" you're providing to help them make an informed decision. |
| 73 | + |
| 74 | +**Use Cases:** |
| 75 | +- Display extracted data for verification: "Is this customer information correct?" |
| 76 | +- Show AI-generated content for approval: "Review this email draft before sending" |
| 77 | +- Present analysis results for validation: "Confirm these findings before proceeding" |
| 78 | +- Expose workflow variables for review: "Check these values before final processing" |
| 79 | + |
| 80 | +**Configuration:** |
| 81 | +Use the visual builder or JSON editor to define the structure of data shown to approvers. Reference workflow variables using `<blockName.output>` syntax. |
| 82 | + |
| 83 | +```json |
| 84 | +{ |
| 85 | + "customerName": "<agent1.content.name>", |
| 86 | + "proposedAction": "<router1.selectedPath>", |
| 87 | + "confidenceScore": "<evaluator1.score>", |
| 88 | + "generatedEmail": "<agent2.content>" |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +### Notification |
| 93 | + |
| 94 | +The Notification section configures how approvers are alerted when the workflow pauses and requires their attention. |
| 95 | + |
| 96 | +**Supported Channels:** |
| 97 | +- **Slack**: Send messages to channels or direct messages with approval links |
| 98 | +- **Gmail**: Email approvers with context and links to the approval portal |
| 99 | +- **Microsoft Teams**: Notify team members through Teams channels |
| 100 | +- **Custom Webhooks**: Trigger your own notification systems |
| 101 | +- **SMS**: Send text message alerts via Twilio |
| 102 | + |
| 103 | +**Configuration:** |
| 104 | +Add notification tools and configure them with the relevant details: |
| 105 | +- For Slack: Select channel and compose message with approval link |
| 106 | +- For Gmail: Specify recipients, subject, and email body |
| 107 | +- For Teams: Choose team and channel for notifications |
| 108 | + |
| 109 | +<Callout type="tip"> |
| 110 | + Include the approval URL (`<approval1.url>`) in your notification messages so approvers can quickly access the approval portal. |
| 111 | +</Callout> |
| 112 | + |
| 113 | +### Resume Input |
| 114 | + |
| 115 | +The Resume Input defines what fields the approver can fill in when reviewing the paused workflow. This is the data that will be collected from the human and made available to downstream blocks. |
| 116 | + |
| 117 | +**Use Cases:** |
| 118 | +- **Binary Approval**: Simple approved/rejected boolean field |
| 119 | +- **Feedback Collection**: Text field for comments or explanations |
| 120 | +- **Data Editing**: Fields for modifying AI-generated content |
| 121 | +- **Multi-field Forms**: Complex approval forms with multiple input types |
| 122 | + |
| 123 | +**Configuration:** |
| 124 | +Define input fields with names, types, and validation rules: |
| 125 | + |
| 126 | +```json |
| 127 | +{ |
| 128 | + "approved": { |
| 129 | + "type": "boolean", |
| 130 | + "description": "Approve or reject this request" |
| 131 | + }, |
| 132 | + "comments": { |
| 133 | + "type": "string", |
| 134 | + "description": "Optional feedback or explanation" |
| 135 | + }, |
| 136 | + "modifiedEmail": { |
| 137 | + "type": "string", |
| 138 | + "description": "Edit the email content if needed" |
| 139 | + } |
| 140 | +} |
| 141 | +``` |
| 142 | + |
| 143 | +**Accessing Resume Data:** |
| 144 | +After the workflow resumes, access the human-provided input using `<approval1.resumeInput.fieldName>` in downstream blocks. |
| 145 | + |
| 146 | +## Approval Methods |
| 147 | + |
| 148 | +The Human in the Loop block supports multiple ways for approvers to interact with paused workflows: |
| 149 | + |
| 150 | +<Tabs items={['Approval Portal', 'API', 'Webhook']}> |
| 151 | + <Tab> |
| 152 | + ### Approval Portal (Web UI) |
| 153 | + |
| 154 | + Every Human in the Loop block generates a unique approval portal URL accessible via the `url` output. |
| 155 | + |
| 156 | + **Features:** |
| 157 | + - Visual interface showing all Paused Output data |
| 158 | + - Form fields for Resume Input |
| 159 | + - Mobile-responsive design |
| 160 | + - Secure, time-limited access |
| 161 | + |
| 162 | + **Usage:** |
| 163 | + ``` |
| 164 | + Access URL: <approval1.url> |
| 165 | + ``` |
| 166 | + |
| 167 | + Share this URL in notifications or embed it in your application for approvers to review and respond. |
| 168 | + </Tab> |
| 169 | + <Tab> |
| 170 | + ### REST API |
| 171 | + |
| 172 | + Programmatically resume workflows by calling the approval API endpoint. |
| 173 | + |
| 174 | + **Endpoint:** |
| 175 | + ```bash |
| 176 | + POST /api/workflows/{workflowId}/executions/{executionId}/resume/{blockId} |
| 177 | + Content-Type: application/json |
| 178 | + |
| 179 | + { |
| 180 | + "approved": true, |
| 181 | + "comments": "Looks good to proceed", |
| 182 | + "modifiedEmail": "Updated email content..." |
| 183 | + } |
| 184 | + ``` |
| 185 | + |
| 186 | + **Use Cases:** |
| 187 | + - Build custom approval UIs |
| 188 | + - Integrate with existing approval systems |
| 189 | + - Automate approvals based on external logic |
| 190 | + </Tab> |
| 191 | + <Tab> |
| 192 | + ### Webhook Listener |
| 193 | + |
| 194 | + Configure external systems to listen for approval requests via webhooks. |
| 195 | + |
| 196 | + **Setup:** |
| 197 | + 1. Add a webhook tool to the Notification section |
| 198 | + 2. Configure your webhook endpoint |
| 199 | + 3. Receive approval request payloads |
| 200 | + 4. Respond to resume the workflow |
| 201 | + |
| 202 | + **Use Cases:** |
| 203 | + - Integrate with ticketing systems (Jira, ServiceNow) |
| 204 | + - Connect to approval workflow platforms |
| 205 | + - Build custom notification pipelines |
| 206 | + </Tab> |
| 207 | +</Tabs> |
| 208 | + |
| 209 | +## Common Use Cases |
| 210 | + |
| 211 | +### Content Approval Workflow |
| 212 | + |
| 213 | +Pause before publishing AI-generated content: |
| 214 | + |
| 215 | +``` |
| 216 | +Agent (Generate) → Human in the Loop (Review) → API (Publish) |
| 217 | +``` |
| 218 | + |
| 219 | +**Paused Output:** Generated article, metadata, SEO analysis |
| 220 | +**Resume Input:** approved (boolean), edits (text), publishDate (date) |
| 221 | + |
| 222 | +### Multi-Stage Approval Pipeline |
| 223 | + |
| 224 | +Require multiple approvals for high-stakes decisions: |
| 225 | + |
| 226 | +``` |
| 227 | +Agent (Analyze) → Human in the Loop (Manager) → Human in the Loop (Director) → API (Execute) |
| 228 | +``` |
| 229 | + |
| 230 | +**Use Case:** Financial transactions, contract approvals, policy changes |
| 231 | + |
| 232 | +### Data Validation Gate |
| 233 | + |
| 234 | +Verify extracted data before processing: |
| 235 | + |
| 236 | +``` |
| 237 | +Agent (Extract) → Human in the Loop (Validate) → Function (Process) → Database (Store) |
| 238 | +``` |
| 239 | + |
| 240 | +**Paused Output:** Extracted fields from documents |
| 241 | +**Resume Input:** confirmed (boolean), corrections (object) |
| 242 | + |
| 243 | +### Quality Control Check |
| 244 | + |
| 245 | +Review AI outputs before sending to customers: |
| 246 | + |
| 247 | +``` |
| 248 | +Agent (Generate Response) → Human in the Loop (QA) → Gmail (Send) |
| 249 | +``` |
| 250 | + |
| 251 | +**Paused Output:** Generated email, customer context |
| 252 | +**Resume Input:** approved (boolean), modifications (text) |
| 253 | + |
| 254 | +## Block Outputs |
| 255 | + |
| 256 | +The Human in the Loop block provides the following outputs: |
| 257 | + |
| 258 | +**`url`** (string) |
| 259 | +The unique URL for the approval portal where humans can review and respond to the paused workflow. |
| 260 | + |
| 261 | +**`resumeInput.*`** (dynamic) |
| 262 | +All fields defined in the Resume Input section become available as outputs after the workflow resumes. Access them using `<blockId.resumeInput.fieldName>`. |
| 263 | + |
| 264 | +## Best Practices |
| 265 | + |
| 266 | +<Steps> |
| 267 | + <Step> |
| 268 | + <strong>Provide Clear Context</strong>: Include all relevant data in Paused Output so approvers can make informed decisions |
| 269 | + </Step> |
| 270 | + <Step> |
| 271 | + <strong>Use Multiple Notification Channels</strong>: Don't rely on a single notification method—add Slack and email for redundancy |
| 272 | + </Step> |
| 273 | + <Step> |
| 274 | + <strong>Set Timeout Policies</strong>: Consider adding workflow-level timeouts to handle abandoned approvals |
| 275 | + </Step> |
| 276 | + <Step> |
| 277 | + <strong>Include Instructions</strong>: Add description fields to Resume Input to guide approvers |
| 278 | + </Step> |
| 279 | + <Step> |
| 280 | + <strong>Track Approval History</strong>: Log approval decisions and comments for audit trails |
| 281 | + </Step> |
| 282 | + <Step> |
| 283 | + <strong>Test Portal Access</strong>: Verify that approvers can access the portal URL from their devices |
| 284 | + </Step> |
| 285 | +</Steps> |
| 286 | + |
| 287 | +<Callout type="warning"> |
| 288 | + Paused workflows consume execution state resources. Implement timeout mechanisms or periodic cleanup for abandoned approvals to avoid accumulating paused executions. |
| 289 | +</Callout> |
| 290 | + |
| 291 | +## Example Configuration |
| 292 | + |
| 293 | +Here's a complete example of a Human in the Loop block configured for content approval: |
| 294 | + |
| 295 | +**Paused Output:** |
| 296 | +```json |
| 297 | +{ |
| 298 | + "title": "<agent1.content.title>", |
| 299 | + "body": "<agent1.content.body>", |
| 300 | + "targetAudience": "<router1.selectedPath>", |
| 301 | + "qualityScore": "<evaluator1.score>", |
| 302 | + "generatedAt": "<function1.output.timestamp>" |
| 303 | +} |
| 304 | +``` |
| 305 | + |
| 306 | +**Notification:** |
| 307 | +- **Slack**: Channel: #content-review, Message: "New article ready for review: `<approval1.url>`" |
| 308 | +- **Gmail**: To: editors@company.com, Subject: "Article Approval Required" |
| 309 | + |
| 310 | +**Resume Input:** |
| 311 | +```json |
| 312 | +{ |
| 313 | + "decision": { |
| 314 | + "type": "boolean", |
| 315 | + "description": "Approve this article for publication?" |
| 316 | + }, |
| 317 | + "feedback": { |
| 318 | + "type": "string", |
| 319 | + "description": "Provide feedback or request changes" |
| 320 | + }, |
| 321 | + "publishDate": { |
| 322 | + "type": "string", |
| 323 | + "description": "Scheduled publish date (YYYY-MM-DD)" |
| 324 | + } |
| 325 | +} |
| 326 | +``` |
| 327 | + |
| 328 | +**Downstream Usage:** |
| 329 | +```javascript |
| 330 | +// In a Condition block: |
| 331 | +if (<approval1.resumeInput.decision> === true) { |
| 332 | + // Proceed to publish |
| 333 | +} else { |
| 334 | + // Route to revision workflow |
| 335 | +} |
| 336 | +``` |
| 337 | + |
| 338 | +## Related Blocks |
| 339 | + |
| 340 | +- **[Response](/blocks/response)**: Return workflow results to API callers |
| 341 | +- **[Condition](/blocks/condition)**: Branch based on approval decisions |
| 342 | +- **[Variables](/blocks/variables)**: Store approval history and metadata |
| 343 | +- **[Wait](/blocks/wait)**: Add time delays before or after approvals |
| 344 | + |
0 commit comments