Human-in-the-Loop (SDK)
The HITL (Human-in-the-Loop) module lets you route agent decisions to human reviewers based on confidence scoring, task type, or explicit configuration. This ensures that high-stakes outputs are verified before being acted upon.
approveTask
Approve a task that is waiting for human review.
await client.approveTask(
taskId: string,
options?: ApproveOptions
): Promise<Task>;Parameters
interface ApproveOptions {
/** Reviewer notes or feedback. */
comment?: string;
/** Modified output (if the reviewer edited the agent's response). */
modifiedOutput?: string;
/** Reviewer identity. */
reviewerId?: string;
}Example
const task = await client.approveTask('dt_task_abc123', {
comment: 'Looks good. Minor formatting fix applied.',
modifiedOutput: 'Corrected version of the output...',
reviewerId: 'reviewer_jane',
});
console.log(task.status); // 'completed'rejectTask
Reject a task and optionally provide feedback for retry.
await client.rejectTask(
taskId: string,
options?: RejectOptions
): Promise<Task>;Parameters
interface RejectOptions {
/** Reason for rejection. */
reason: string;
/** Whether to retry the task with the rejection feedback. Default: false */
retry?: boolean;
/** Modified prompt for the retry attempt. */
retryPrompt?: string;
/** Reviewer identity. */
reviewerId?: string;
}Example
await client.rejectTask('dt_task_abc123', {
reason: 'The risk analysis missed Section 4.2 indemnification clause.',
retry: true,
retryPrompt: 'Re-analyze risks, paying special attention to Section 4.2 indemnification.',
reviewerId: 'reviewer_jane',
});getPendingApprovals
List all tasks currently awaiting human review.
const pending = await client.getPendingApprovals(
options?: PendingApprovalsOptions
): Promise<PendingApprovalList>;Parameters
interface PendingApprovalsOptions {
/** Filter by queue. */
queue?: string;
/** Filter by tags. */
tags?: string[];
/** Filter by assigned reviewer. */
reviewerId?: string;
/** Include tasks past their timeout. */
includeExpired?: boolean;
limit?: number;
offset?: number;
}Example
const { approvals, total } = await client.getPendingApprovals({
tags: ['legal'],
limit: 10,
});
console.log(`${total} tasks awaiting approval`);
for (const approval of approvals) {
console.log(`Task ${approval.taskId}:`);
console.log(` Model: ${approval.model}`);
console.log(` Confidence: ${(approval.confidence * 100).toFixed(1)}%`);
console.log(` Waiting: ${approval.waitingMs / 1000}s`);
console.log(` Summary: ${approval.summary}`);
console.log(` Output preview: ${approval.output.slice(0, 200)}...`);
}Return Value
interface PendingApproval {
taskId: string;
planExecutionId?: string;
stepId?: string;
model: string;
queue: string;
confidence: number; // 0.0 to 1.0
summary: string; // AI-generated summary of the output
output: string; // Full agent output
prompt: string; // Original prompt
tags: string[];
createdAt: string;
waitingMs: number; // Time spent waiting for approval
timeoutAt?: string; // When auto-escalation triggers
assignedTo?: string; // Reviewer ID
escalatedFrom?: string; // Previous reviewer (if escalated)
}Confidence Scoring
When HITL is configured with a confidenceThreshold, the orchestrator evaluates the agent's response and assigns a confidence score:
| Score Range | Behavior |
|---|---|
| >= threshold | Auto-approved, task completes immediately |
| < threshold | Paused for human review |
| 0.0 | Always requires review (task explicitly flagged) |
const execution = await client.executePlan(planId, {
hitl: {
requiredFor: ['analyze-risk'],
confidenceThreshold: 0.85,
timeoutMs: 3600_000,
},
});Confidence scoring uses a lightweight meta-model that evaluates factual consistency, prompt adherence, and output completeness. It is not a guarantee of correctness -- it is a triage signal for human reviewers.
WebSocket Notifications
Subscribe to HITL events in real time:
client.subscribe('hitl:pending', (event) => {
console.log('New approval request:', event.taskId);
console.log('Confidence:', event.confidence);
console.log('Summary:', event.summary);
});
client.subscribe('hitl:approved', (event) => {
console.log('Approved:', event.taskId, 'by', event.reviewerId);
});
client.subscribe('hitl:rejected', (event) => {
console.log('Rejected:', event.taskId, 'reason:', event.reason);
});
client.subscribe('hitl:escalated', (event) => {
console.log('Escalated:', event.taskId, 'to', event.escalatedTo);
});Next Steps
- HITL Guide -- Comprehensive guide to HITL patterns
- Templates -- Deploy templates with HITL built in