Files
deepset-ai--haystack/docs-website/reference/haystack-api/human_in_the_loop_api.md
T
wehub-resource-sync c56bef871b
Sync docs with Docusaurus / sync (push) Waiting to run
Tests / Check if changed (push) Waiting to run
Tests / format (push) Blocked by required conditions
Tests / check-imports (push) Blocked by required conditions
Tests / Unit / macos-latest (push) Blocked by required conditions
Tests / Unit / ubuntu-latest (push) Blocked by required conditions
Tests / Unit / windows-latest (push) Blocked by required conditions
Tests / mypy (push) Blocked by required conditions
Tests / Integration / ubuntu-latest (push) Blocked by required conditions
Tests / Integration / macos-latest (push) Blocked by required conditions
Tests / Integration / windows-latest (push) Blocked by required conditions
Tests / notify-slack-on-failure (push) Blocked by required conditions
Tests / Mark tests as completed (push) Blocked by required conditions
Docker image release / Build base image (push) Waiting to run
CodeQL / Analyze (python) (push) Has been cancelled
Update Platform Components Table / update (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:22:28 +08:00

14 KiB
Raw Blame History

title, id, description, slug
title id description slug
Human-in-the-Loop human-in-the-loop-api Abstractions for integrating human feedback and interaction into Agent workflows. /human-in-the-loop-api

dataclasses

ConfirmationUIResult

Result of the confirmation UI interaction.

Parameters:

  • action (str) The action taken by the user such as "confirm", "reject", or "modify". This action type is not enforced to allow for custom actions to be implemented.
  • feedback (str | None) Optional feedback message from the user. For example, if the user rejects the tool execution, they might provide a reason for the rejection.
  • new_tool_params (dict[str, Any] | None) Optional set of new parameters for the tool. For example, if the user chooses to modify the tool parameters, they can provide a new set of parameters here.

ToolExecutionDecision

Decision made regarding tool execution.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • execute (bool) A boolean indicating whether to execute the tool with the provided parameters.
  • tool_call_id (str | None) Optional unique identifier for the tool call. This can be used to track and correlate the decision with a specific tool invocation.
  • feedback (str | None) Optional feedback message. For example, if the tool execution is rejected, this can contain the reason. Or if the tool parameters were modified, this can contain the modification details.
  • final_tool_params (dict[str, Any] | None) Optional final parameters for the tool if execution is confirmed or modified.

to_dict

to_dict() -> dict[str, Any]

Convert the ToolExecutionDecision to a dictionary representation.

Returns:

  • dict[str, Any] A dictionary containing the tool execution decision details.

from_dict

from_dict(data: dict[str, Any]) -> ToolExecutionDecision

Populate the ToolExecutionDecision from a dictionary representation.

Parameters:

  • data (dict[str, Any]) A dictionary containing the tool execution decision details.

Returns:

  • ToolExecutionDecision An instance of ToolExecutionDecision.

hooks

ConfirmationHook

A before_tool Agent hook that applies Human-in-the-Loop confirmation strategies to pending tool calls.

Register it on an Agent to confirm, modify, or reject tool calls before they run:

from haystack.components.agents import Agent
from haystack.human_in_the_loop import (
    AlwaysAskPolicy,
    BlockingConfirmationStrategy,
    ConfirmationHook,
    NeverAskPolicy,
    RichConsoleUI,
    SimpleConsoleUI,
)

hook = ConfirmationHook(
    confirmation_strategies={
        "my_tool": BlockingConfirmationStrategy(
            confirmation_policy=NeverAskPolicy(), confirmation_ui=SimpleConsoleUI()
        )
    }
)
agent = Agent(chat_generator=..., tools=[...], hooks={"before_tool": [hook]})

A key may be a single tool name, a tuple of tool names sharing one strategy, or the wildcard "*" which applies to any tool without a more specific entry. More specific keys win, so you can set a default for all tools and override individual ones:

hook = ConfirmationHook(
    confirmation_strategies={
        "delete_file": BlockingConfirmationStrategy(
            confirmation_policy=AlwaysAskPolicy(), confirmation_ui=RichConsoleUI()
        ),
        "*": BlockingConfirmationStrategy(
            confirmation_policy=NeverAskPolicy(), confirmation_ui=SimpleConsoleUI()
        ),
    }
)

Request-scoped resources for the strategies (e.g. a WebSocket or queue) are passed per run via the Agent's hook_context argument (agent.run(messages=[...], hook_context={...})) and read by the hook with state.data.get("hook_context").

This hook only makes sense at the before_tool hook point, where the pending tool calls exist (between the model requesting tools and those tools running); the Agent enforces this and raises if it is registered elsewhere. Use a single ConfirmationHook with one entry per tool (or per tuple of tools) in confirmation_strategies rather than registering several hooks.

init

__init__(
    confirmation_strategies: dict[str | tuple[str, ...], ConfirmationStrategy],
) -> None

Initialize the hook with its per-tool confirmation strategies.

Parameters:

  • confirmation_strategies (dict[str | tuple[str, ...], ConfirmationStrategy]) Mapping of tool name (or a tuple of tool names) to its ConfirmationStrategy. The wildcard key "*" applies to any tool without a more specific entry.

run

run(state: State) -> None

Confirm the pending tool calls, rewriting the messages in state to reflect modifications and rejections.

Parameters:

  • state (State) The Agent's live State. Reads the available tools (state.data.get("tools")) and the per-run context (state.data.get("hook_context")), and the pending tool calls from the last message; writes the updated conversation back to messages. Reads go through state.data rather than state.get, which deep-copies and would break non-copyable resources (e.g. a WebSocket or client) in hook_context.

run_async

run_async(state: State) -> None

Async version of run.

to_dict

to_dict() -> dict[str, Any]

Serialize the hook, including its confirmation strategies (tuple keys become JSON-array strings).

from_dict

from_dict(data: dict[str, Any]) -> ConfirmationHook

Deserialize the hook, reconstructing its confirmation strategies.

policies

AlwaysAskPolicy

Bases: ConfirmationPolicy

Always ask for confirmation.

should_ask

should_ask(
    tool_name: str, tool_description: str, tool_params: dict[str, Any]
) -> bool

Always ask for confirmation before executing the tool.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters to be passed to the tool.

Returns:

  • bool Always returns True, indicating confirmation is needed.

NeverAskPolicy

Bases: ConfirmationPolicy

Never ask for confirmation.

should_ask

should_ask(
    tool_name: str, tool_description: str, tool_params: dict[str, Any]
) -> bool

Never ask for confirmation, always proceed with tool execution.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters to be passed to the tool.

Returns:

  • bool Always returns False, indicating no confirmation is needed.

AskOncePolicy

Bases: ConfirmationPolicy

Ask only once per tool with specific parameters.

init

__init__() -> None

Creates an instance of AskOncePolicy.

should_ask

should_ask(
    tool_name: str, tool_description: str, tool_params: dict[str, Any]
) -> bool

Ask for confirmation only once per tool with specific parameters.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters to be passed to the tool.

Returns:

  • bool True if confirmation is needed, False if already asked with the same parameters.

update_after_confirmation

update_after_confirmation(
    tool_name: str,
    tool_description: str,
    tool_params: dict[str, Any],
    confirmation_result: ConfirmationUIResult,
) -> None

Store the tool and parameters if the action was "confirm" to avoid asking again.

This method updates the internal state to remember that the user has already confirmed the execution of the tool with the given parameters.

Parameters:

  • tool_name (str) The name of the tool that was executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters that were passed to the tool.
  • confirmation_result (ConfirmationUIResult) The result from the confirmation UI.

strategies

BlockingConfirmationStrategy

Confirmation strategy that blocks execution to gather user feedback.

init

__init__(
    *,
    confirmation_policy: ConfirmationPolicy,
    confirmation_ui: ConfirmationUI,
    reject_template: str = REJECTION_FEEDBACK_TEMPLATE,
    modify_template: str = MODIFICATION_FEEDBACK_TEMPLATE,
    user_feedback_template: str = USER_FEEDBACK_TEMPLATE
) -> None

Initialize the BlockingConfirmationStrategy with a confirmation policy and UI.

Parameters:

  • confirmation_policy (ConfirmationPolicy) The confirmation policy to determine when to ask for user confirmation.
  • confirmation_ui (ConfirmationUI) The user interface to interact with the user for confirmation.
  • reject_template (str) Template for rejection feedback messages. It should include a {tool_name} placeholder.
  • modify_template (str) Template for modification feedback messages. It should include {tool_name} and {final_tool_params} placeholders.
  • user_feedback_template (str) Template for user feedback messages. It should include a {feedback} placeholder.

run

run(
    *,
    tool_name: str,
    tool_description: str,
    tool_params: dict[str, Any],
    tool_call_id: str | None = None,
    confirmation_strategy_context: dict[str, Any] | None = None
) -> ToolExecutionDecision

Run the human-in-the-loop strategy for a given tool and its parameters.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters to be passed to the tool.
  • tool_call_id (str | None) Optional unique identifier for the tool call. This can be used to track and correlate the decision with a specific tool invocation.
  • confirmation_strategy_context (dict[str, Any] | None) Optional dictionary for passing request-scoped resources. Useful in web/server environments to provide per-request objects (e.g., WebSocket connections, async queues, Redis pub/sub clients) that strategies can use for non-blocking user interaction.

Returns:

  • ToolExecutionDecision A ToolExecutionDecision indicating whether to execute the tool with the given parameters, or a feedback message if rejected.

run_async

run_async(
    *,
    tool_name: str,
    tool_description: str,
    tool_params: dict[str, Any],
    tool_call_id: str | None = None,
    confirmation_strategy_context: dict[str, Any] | None = None
) -> ToolExecutionDecision

Async version of run. Calls the sync run() method by default.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters to be passed to the tool.
  • tool_call_id (str | None) Optional unique identifier for the tool call.
  • confirmation_strategy_context (dict[str, Any] | None) Optional dictionary for passing request-scoped resources.

Returns:

  • ToolExecutionDecision A ToolExecutionDecision indicating whether to execute the tool with the given parameters.

to_dict

to_dict() -> dict[str, Any]

Serializes the BlockingConfirmationStrategy to a dictionary.

Returns:

  • dict[str, Any] Dictionary with serialized data.

from_dict

from_dict(data: dict[str, Any]) -> BlockingConfirmationStrategy

Deserializes the BlockingConfirmationStrategy from a dictionary.

Parameters:

  • data (dict[str, Any]) Dictionary to deserialize from.

Returns:

  • BlockingConfirmationStrategy Deserialized BlockingConfirmationStrategy.

user_interfaces

RichConsoleUI

Bases: ConfirmationUI

Rich console interface for user interaction.

init

__init__(console: Console | None = None) -> None

Creates an instance of RichConsoleUI.

get_user_confirmation

get_user_confirmation(
    tool_name: str, tool_description: str, tool_params: dict[str, Any]
) -> ConfirmationUIResult

Get user confirmation for tool execution via rich console prompts.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters to be passed to the tool.

Returns:

  • ConfirmationUIResult ConfirmationUIResult based on user input.

to_dict

to_dict() -> dict[str, Any]

Serializes the RichConsoleConfirmationUI to a dictionary.

Returns:

  • dict[str, Any] Dictionary with serialized data.

SimpleConsoleUI

Bases: ConfirmationUI

Simple console interface using standard input/output.

get_user_confirmation

get_user_confirmation(
    tool_name: str, tool_description: str, tool_params: dict[str, Any]
) -> ConfirmationUIResult

Get user confirmation for tool execution via simple console prompts.

Parameters:

  • tool_name (str) The name of the tool to be executed.
  • tool_description (str) The description of the tool.
  • tool_params (dict[str, Any]) The parameters to be passed to the tool.