Skip to content

Proposal: Production-Ready Human-In-The-Loop (HITL) Gateway #111

@garythomasgeorge

Description

@garythomasgeorge

The Problem

Google ADK's natively built-in TOOL_CONFIRMATION feature (v1.14.0+) works well for local debugging, but it presents several structural blockers that prevent teams from deploying human-in-the-loop (HITL) agent flows in persistent production environments:

  1. Session Service Incompatibility: The native confirmation feature relies heavily on in-memory blocking. It explicitly does not support DatabaseSessionService or VertexAiSessionService—the very two persistence backends critically required for production.
  2. Missing Persistence & Auditability: There is no structured data contract out-of-the-box. Approvals leave zero permanent audit logs.
  3. Boundary Failures: The native interceptor does not reliably trigger inside AgentTool definitions or securely cross Agent-to-Agent (A2A) orchestration boundaries.
  4. Lack of Supervisor UI: Teams must currently rely on the primary chatting interface for approvals rather than a dedicated supervisor dashboard.

(Related community issues: #1797, #1851, #2645, #3276, #3567)

Proposed Solution

We need a session-agnostic HITL approval gateway that surgically decouples approval-state persistence from ADK's native context window session.

By pushing the approval payload into a dedicated local persistence layer (like SQLite) via an API, agents can pause their executions naturally while human supervisors use a completely separate UI (like Streamlit) to review, edit, and approve the blocked execution contexts.

Architecture Overview

  1. The Wrapper: A @hitl_tool decorator that wraps standard asynchronous python functions before they are passed into FunctionTool. This decorator intercepts the LLM tool execution natively.
  2. The Backend: A fast REST API (FastAPI) backed by an independent database (SQLite) that handles the ApprovalRequest data contract, persisting the payload alongside comprehensive reviewer notes and timestamps.
  3. The UX: An external dashboard (Streamlit) that streams the approval queue from the backend and allows dedicated supervisors to govern the agent execution.

Expected Behavior

Instead of freezing the agent runner locally, the @hitl_tool decorator automatically POSTs the tool parameters to the FastAPI backend and begins asynchronously polling the API. Meanwhile, the reviewer securely clicks "Approve" in the Streamlit dashboard, updating the SQLite row. The proxy instantly detects the status change, unblocks the thread, wraps the supervisor's decision into the return payload, and natively hands execution back to the LLM.

Implementation Plan

  • Create the ApprovalRequest and ApprovalDecision strictly-typed Pydantic contracts.
  • Implement the hitl_tool execution proxy in tools/hitl/gateway.py alongside an ADK 1.x Event adapter pattern.
  • Launch the standalone FastAPI Service queue manager.
  • Publish a verified end-to-end sample implementation (contributing/samples/hitl_approval) featuring a Credit Agent, a Streamlit Dashboard, and automated unit tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions