person-circle-checkHuman in the Loop Approvals

Enable manual checkpoints for high-risk actions by routing agent decisions through an operator before execution. This guide outlines the end-to-end flow, where it fits in existing automation, and how to combine it with the SDK and CLI.

When to Use HITL

  • You need an audit trail for outbound actions (email, ticketing, CRM updates).

  • Teams want live visibility into agent decisions without disabling automation.

  • Regulatory or compliance policies require operator approval on sensitive steps.

Quick Start

Auto-Approval (Local Testing/CI)

import os
os.environ["GLAIP_HITL_AUTO_APPROVE"] = "true"

from glaip_sdk.agents import Agent
from tools import CalculatorTool  # Any LangChain BaseTool subclass.

# Local auto-approval uses LocalPromptHandler, injected when hitl_enabled is True.
agent = Agent(
    name="hitl_local_agent",
    instruction="Use the calculator tool when needed.",
    tools=[CalculatorTool],
    tool_configs={CalculatorTool: {"hitl": {"timeout_seconds": 30}}},
    agent_config={"hitl_enabled": True},
)

response = agent.run("Calculate 2 + 2", local=True)
# All HITL requests auto-approved.

Note: Local HITL prompts do not enforce timeouts; approval waits indefinitely.

Auto-Approval (Remote Testing/CI)

For remote runs, the env var is only read by RemoteHITLHandler. Make sure you pass one so HITL requests are actually resolved.

Custom Approval Logic

Note: Keep callbacks short and handle timeouts; for longer approvals, use the manual approval flow (hitl.list_pending + approve/reject) from another process. Log errors for operational visibility.

For the built-in interactive prompt, use RemoteHITLHandler(interactive=True).

Manual Approval (Separate Process)

Components

  • Approval-aware tool — Exposes a tool that records pending actions instead of executing them immediately.

  • HITL-enabled agent — Flags tools that require approval and pauses run execution until a decision arrives.

  • Operator console — Any surface (custom UI, CLI, or scripts) that calls the HITL REST endpoints to review and resolve requests.

Detecting Pauses in a Run

  • POST /agents/{agent_id}/run streams Server-Sent Events. When an approval is required the chunk includes metadata.hitl.

  • Capture the metadata.hitl.request_id and metadata.tool_info fields to populate the operator UI. metadata.hitl.decision moves from pending to approved, rejected, or timeout_skip once resolved.

  • Keep the stream open so follow-up tokens deliver the agent's response after the decision lands.

Typical Workflow

  1. Upload or register a tool that surfaces actions for approval.

  2. Create an agent with hitl_enabled set and map the tool to HITL settings and timeouts.

  3. Start a run and watch the SSE stream for metadata.hitl.decision == "pending" to know when to open an approval card.

  4. Let operators approve in your console by POSTing to /agents/hitl/decision using the streamed request_id.

  5. Optionally monitor /agents/hitl/pending for inbox-style dashboards or recovery from client restarts.

  6. Remove temporary agents, tools, or runs when tests finish.

Implementation Paths

Use RemoteHITLHandler for programmatic approval workflows:

Features:

  • Thread-based callback execution (non-blocking)

  • Timeout enforcement (80% of backend timeout)

  • Automatic retry on network/server errors

  • Error recovery (callback exceptions handled gracefully)

Decision precedence:

  • Auto-approve short-circuits interactive and callback handling.

  • Interactive prompt short-circuits the callback when enabled and a TTY is available.

  • If interactive is enabled but no TTY is detected, it is disabled and the callback is used if provided.

  • If none apply, requests are rejected. Patterns:

  1. Auto-approval: Set GLAIP_HITL_AUTO_APPROVE=true or auto_approve=True

  2. Conditional approval: Callback with business logic (safe/dangerous tools)

  3. Interactive approval: User prompts with timeout handling

  4. Logging-only: Auto-approve but log all requests for audit

  5. Manual approval: Separate process polling client.hitl.list_pending()

REST API

Follow the detailed payloads in the HITL REST Workflow Guidearrow-up-right for cURL-ready examples and sample SSE payloads.

CLI

Combine aip agents run with small scripts that invoke the HITL endpoints for approvals. Perfect for demos or manual QA.

Best Practices

  • Separate duties — Store approval history outside the agent payload so you can report on reviewer actions.

  • Define timeouts — Use tool_configs[tool_id].hitl.timeout_seconds to align with your SLA. Callbacks get 80% of this time (20% reserved for network).

  • Alerting — Hook pending requests into chat or incident systems to avoid stalled workflows. Use on_unrecoverable_error callback for critical alerts.

  • Testing — Include HITL runs in integration tests to ensure endpoints stay in sync across releases. Use auto-approval for CI/CD pipelines.

  • Error handling — Callbacks should complete quickly and handle exceptions internally. Callback exceptions are logged and treated as REJECTED.

  • Thread safety — If using custom BaseClient, ensure it's thread-safe or pass a dedicated client instance to RemoteHITLHandler.

Testing & Examples

With these pieces in place you can ship agents that stay fast for low-risk scenarios while keeping an operator in the loop for everything else.


API Reference

Decision Types

Decision
Code
Behavior

Approve

HITLDecision.APPROVED

Tool executes

Reject

HITLDecision.REJECTED

Tool blocked

Skip

HITLDecision.SKIPPED

Tool skipped

HITLRequest Fields

Example:

HITLResponse Fields

Examples:

RemoteHITLHandler Configuration

Parameters:

  • callback: Function (HITLRequest) -> HITLResponse

    • If None and auto_approve=False, requests will be rejected

  • client: BaseClient instance for posting decisions

  • auto_approve: Override GLAIP_HITL_AUTO_APPROVE env var

  • max_retries: Max retries for POST errors (default: 3)

  • on_unrecoverable_error: Called when both callback and POST fail

Manual Approval API

List Pending Requests:

Approve a Request:

Reject a Request:

Skip a Request:

Common Patterns

Conditional Approval

Interactive Approval

Logging + Auto-Approve

Error Handling

Error Handling Details

Callback Errors

Error
Behavior

Callback raises

Log error, reject request

Callback timeout

Log timeout, reject request

Invalid response

Log error, reject request

POST Errors

Error
Behavior

Network error

Retry 3x with delays (1s, 2s, 3s)

5xx server error

Retry 3x with delays

4xx client error

Fail immediately, no retry

404 (not found)

Treated as resolved, no retry

409 (already resolved)

Treated as resolved, no retry

Unrecoverable Errors

When both callback execution and fallback rejection POST fail:

  1. Error is logged

  2. on_unrecoverable_error callback is invoked (if provided)

  3. Backend will eventually timeout the request

Timeout Details

Callback Timeout:

  • Callbacks get 80% of backend timeout

  • 20% reserved for network/POST operations

Example:

  • Backend timeout: 60 seconds

  • Callback timeout: 48 seconds (80%)

  • Network buffer: 12 seconds (20%)

Source of truth: timeout_at field (ISO 8601 deadline) Fallback: timeout_seconds field (only if timeout_at parsing fails)

Environment Variables

Complete Example

Last updated