Intermediate~40 minHazelJS
Add Human Approval Without Breaking the Run
Pause AgentRuntime with durableSuspend, notify approvers, and continue via approveAndResume without losing checkpoints.
- Authors
- editorial-team
- Published
- Last reviewed
- Durable run store available (file or SQL)
- /patterns/human-approval-gate concepts
- Configure durableSuspend + createDurableRunStore on AgentRuntime
- Resume safely with approveAndResume after PolicyEngine require_approval
- Avoid blocking HTTP workers and leaking secrets in approval channels
On this page
Goal
Add HITL so high-impact tools suspend the AgentRun durably, survive process restarts, and resume only after an authenticated approval—without turning your API worker into a long poll.
Pattern: /patterns/human-approval-gate. Docs: Agent OS.
Step 1Durable store + durableSuspend
import {
AgentRuntime,
PolicyEngine,
createDurableRunStore,
defaultPiiMaskPolicies,
} from '@hazeljs/agent';
const store = createDurableRunStore('./.hazel/runs');
// Production: createSqlDurableRunStore(prisma) where documented
const runtime = new AgentRuntime({
llmProvider,
durableSuspend: true,
runRepository: store.runRepository,
checkpointService: store.checkpointService,
humanTaskService: store.humanTaskService,
policyEngine: new PolicyEngine([
...defaultPiiMaskPolicies(),
{
id: 'refund-needs-approval',
tool: 'processRefund',
effect: 'require_approval',
priority: 20,
},
]),
});
Step 2Execute and return waiting state
const waiting = await runtime.execute('order-desk', 'Refund ORD-100');
// waiting status indicates suspension — return executionId to the client/ops UI
// Do not block the HTTP request until a human clicks approve
Notify approvers with redacted args (tool name, amount, order id)—never raw secrets.
Step 3Approve or reject
const done = await runtime.approveAndResume(waiting.executionId, {
approved: true,
approvedBy: 'ops@example.com',
});
// reject → cancel without executing the gated tool
Write tools must be idempotent so a double-click approve cannot double-charge (/patterns/idempotent-tool-execution).
Step 4CLI / ops note
hazel agent runs resume|approve against a file store records HITL intent; app code must still call approveAndResume for the runtime to continue. Lesson: /learn/agentic-development/hazel-cli-agent-ops.
Step 5Verify
- Kill Node mid-SUSPENDED; restart; approve still works
- Reject leaves no side effect
- Approval channel redacts PII
- Metrics: approval latency, stuck SUSPENDED alert
- describeAgent / integration test covers gated path