Skip to content

Add Human-in-the-Loop (HITL) Support to DurableAgent #162

@bibryam

Description

@bibryam

Description:
Introduce a pattern in DurableAgent to allow human approval at critical decision points. The agent should pause and wait for external input before proceeding. This is essential for high-stakes workflows requiring manual oversight. Behind the scene, this will pause workflow execution and wait for an external event

Example: Human Approval Loop

This is a conceptual example to illustrate intent. Implementation may vary.

@tool(wait_for="approval_received")
async def dangerous_task(approval_event: ExternalEvent) -> str:
    if approval_event.response.strip().lower() == "yes":
        return "Dangerous task completed successfully."
    else:
        return "Dangerous task aborted."

durable_agent = DurableAgent(
    name="HumanApprovalBot",
    role="Human-in-the-loop Operations Coordinator",
    instructions=[
        "Handle critical workflows that require explicit human approval",
        "Pause and wait for human input before continuing risky operations",
        "Retain all state, inputs, and decisions across restarts or delays",
    ],
    llm=DaprChatClient(conversation_component="openai"),
    tools=[dangerous_task, mcp_tool_with_human_approval],
    memory=ConversationDaprStateMemory(store_name="statestore"),
    durable_execution=DaprWorkflowDurableExecution(
        state_store_name="statestore",
        state_key="human_approval_workflow",
    ),
)

Event Loop Example

async for event in durable_agent.ctx.stream_events():
    if isinstance(event, ExternalEventRequired):
        response = input(event.prefix)
        durable_agent.ctx.raise_event(
            instance_id=event.instance_id,
            event_name="approval_received",
            event_data=asdict(response),
        )

response = durable_agent.run_async(user_msg="Proceed with this dangerous task.")

Open Questions

  1. How should users define when human-in-the-loop is triggered: is it tool-only, or pre-LLM, post-LLM calls?
  2. What is the best way to notify or signal the human? Can the agent emit events during specific lifecycle stages as described in Callback Hooks for Dapr Agents #132 ?

There are different ways of doing HITL with agents

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