Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@ agent = Agent(

**Why:** Confirmation was a one-off, before-tool interception bolted onto the Agent. Hooks generalize that seam, so HITL becomes one application of a single, uniform extension point instead of a parallel concept with its own serialization and run plumbing.

The Human-in-the-Loop module has also moved from `haystack.human_in_the_loop` to `haystack.hooks.human_in_the_loop`, so that it lives alongside the other built-in hooks (such as tool result offloading). Update your imports to the new location.

**How to migrate:**

Before (v2.x):
Expand All @@ -661,7 +663,7 @@ agent.run(messages=[...], confirmation_strategy_context={"websocket": ws})
After (v3.0):
```python
from haystack.components.agents import Agent
from haystack.human_in_the_loop import (
from haystack.hooks.human_in_the_loop import (
BlockingConfirmationStrategy,
AlwaysAskPolicy,
ConfirmationHook,
Expand Down
6 changes: 3 additions & 3 deletions docs-website/docs/pipeline-components/agents-1/hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ print(result["last_message"].text)

## Ready-made hooks

Haystack ships two ready-made hooks:
Haystack ships two ready-made hooks, each in its own submodule of `haystack.hooks`:

- `ConfirmationHook`: A `before_tool` hook that applies Human-in-the-Loop confirmation strategies to pending tool calls — a human can confirm, modify, or reject the tool calls the model requested before they run. See [Human in the Loop](./human-in-the-loop.mdx).
- `ToolResultOffloadHook`: An `after_tool` hook that offloads tool results to a `ToolResultStore` (such as `FileSystemToolResultStore`) and replaces them in the conversation with a compact pointer, so the next LLM call sees a reference instead of the full result. Per-tool policies (`AlwaysOffload`, `NeverOffload`, `OffloadOverChars`) control which results are offloaded. See [Tool Result Offloading](./tool-result-offloading.mdx).
- `ConfirmationHook` (from `haystack.hooks.human_in_the_loop`): A `before_tool` hook that applies Human-in-the-Loop confirmation strategies to pending tool calls — a human can confirm, modify, or reject the tool calls the model requested before they run. See [Human in the Loop](./human-in-the-loop.mdx).
- `ToolResultOffloadHook` (from `haystack.hooks.tool_result_offloading`): An `after_tool` hook that offloads tool results to a `ToolResultStore` (such as `FileSystemToolResultStore`) and replaces them in the conversation with a compact pointer, so the next LLM call sees a reference instead of the full result. Per-tool policies (`AlwaysOffload`, `NeverOffload`, `OffloadOverChars`) control which results are offloaded. See [Tool Result Offloading](./tool-result-offloading.mdx).
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ This is useful for high-stakes operations - such as sending emails, modifying da
| --- | --- |
| **Configured on** | The [`Agent`](./agent.mdx) component, as a `ConfirmationHook` registered under the `before_tool` [hook point](./hooks.mdx) |
| **Key classes** | `ConfirmationHook`, `BlockingConfirmationStrategy`, `AlwaysAskPolicy`, `AskOncePolicy`, `NeverAskPolicy`, `RichConsoleUI`, `SimpleConsoleUI` |
| **Import path** | `haystack.human_in_the_loop` |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/human_in_the_loop/ |
| **Import path** | `haystack.hooks.human_in_the_loop` |
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/hooks/human_in_the_loop/ |
| **Package name** | `haystack-ai` |

</div>
Expand Down Expand Up @@ -56,7 +56,7 @@ from typing import Annotated
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.human_in_the_loop import (
from haystack.hooks.human_in_the_loop import (
AlwaysAskPolicy,
BlockingConfirmationStrategy,
ConfirmationHook,
Expand Down Expand Up @@ -118,7 +118,7 @@ pip install rich
```

```python
from haystack.human_in_the_loop import RichConsoleUI
from haystack.hooks.human_in_the_loop import RichConsoleUI

strategy = BlockingConfirmationStrategy(
confirmation_policy=AlwaysAskPolicy(),
Expand Down Expand Up @@ -202,10 +202,13 @@ Policies control *when* the human is asked.

### Custom policy

You can implement your own policy by subclassing `ConfirmationPolicy` from `haystack.human_in_the_loop.types`:
You can implement your own policy by subclassing `ConfirmationPolicy` from `haystack.hooks.human_in_the_loop.types`:

```python
from haystack.human_in_the_loop.types import ConfirmationPolicy, ConfirmationUIResult
from haystack.hooks.human_in_the_loop.types import (
ConfirmationPolicy,
ConfirmationUIResult,
)
from typing import Any


Expand All @@ -227,8 +230,8 @@ It is called after the user responds and receives the full `ConfirmationUIResult
The following policy asks once per tool name and skips re-asking for any tool the user has already confirmed:

```python
from haystack.human_in_the_loop.types import ConfirmationPolicy
from haystack.human_in_the_loop import ConfirmationUIResult
from haystack.hooks.human_in_the_loop.types import ConfirmationPolicy
from haystack.hooks.human_in_the_loop import ConfirmationUIResult
from typing import Any


Expand Down Expand Up @@ -295,11 +298,11 @@ This is a good reference if you need non-blocking HITL in a web or server enviro

## Custom UI

Implement `ConfirmationUI` from `haystack.human_in_the_loop.types` to build your own interface - for example, a web-based approval queue:
Implement `ConfirmationUI` from `haystack.hooks.human_in_the_loop.types` to build your own interface - for example, a web-based approval queue:

```python
from haystack.human_in_the_loop.types import ConfirmationUI
from haystack.human_in_the_loop import ConfirmationUIResult
from haystack.hooks.human_in_the_loop.types import ConfirmationUI
from haystack.hooks.human_in_the_loop import ConfirmationUIResult
from typing import Any


Expand Down
Loading
Loading