Skip to content

Commit 86d4697

Browse files
authored
chore: Move HITL to underneath the Hooks module (#11974)
1 parent 6b37974 commit 86d4697

24 files changed

Lines changed: 95 additions & 554 deletions

MIGRATION.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,8 @@ agent = Agent(
639639

640640
**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.
641641

642+
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.
643+
642644
**How to migrate:**
643645

644646
Before (v2.x):
@@ -661,7 +663,7 @@ agent.run(messages=[...], confirmation_strategy_context={"websocket": ws})
661663
After (v3.0):
662664
```python
663665
from haystack.components.agents import Agent
664-
from haystack.human_in_the_loop import (
666+
from haystack.hooks.human_in_the_loop import (
665667
BlockingConfirmationStrategy,
666668
AlwaysAskPolicy,
667669
ConfirmationHook,

docs-website/docs/pipeline-components/agents-1/hooks.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ print(result["last_message"].text)
196196

197197
## Ready-made hooks
198198

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

201-
- `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).
202-
- `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).
201+
- `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).
202+
- `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).

docs-website/docs/pipeline-components/agents-1/human-in-the-loop.mdx

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ This is useful for high-stakes operations - such as sending emails, modifying da
1717
| --- | --- |
1818
| **Configured on** | The [`Agent`](./agent.mdx) component, as a `ConfirmationHook` registered under the `before_tool` [hook point](./hooks.mdx) |
1919
| **Key classes** | `ConfirmationHook`, `BlockingConfirmationStrategy`, `AlwaysAskPolicy`, `AskOncePolicy`, `NeverAskPolicy`, `RichConsoleUI`, `SimpleConsoleUI` |
20-
| **Import path** | `haystack.human_in_the_loop` |
21-
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/human_in_the_loop/ |
20+
| **Import path** | `haystack.hooks.human_in_the_loop` |
21+
| **GitHub link** | https://github.com/deepset-ai/haystack/blob/main/haystack/hooks/human_in_the_loop/ |
2222
| **Package name** | `haystack-ai` |
2323

2424
</div>
@@ -56,7 +56,7 @@ from typing import Annotated
5656
from haystack.components.agents import Agent
5757
from haystack.components.generators.chat import OpenAIChatGenerator
5858
from haystack.dataclasses import ChatMessage
59-
from haystack.human_in_the_loop import (
59+
from haystack.hooks.human_in_the_loop import (
6060
AlwaysAskPolicy,
6161
BlockingConfirmationStrategy,
6262
ConfirmationHook,
@@ -118,7 +118,7 @@ pip install rich
118118
```
119119

120120
```python
121-
from haystack.human_in_the_loop import RichConsoleUI
121+
from haystack.hooks.human_in_the_loop import RichConsoleUI
122122

123123
strategy = BlockingConfirmationStrategy(
124124
confirmation_policy=AlwaysAskPolicy(),
@@ -202,10 +202,13 @@ Policies control *when* the human is asked.
202202

203203
### Custom policy
204204

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

207207
```python
208-
from haystack.human_in_the_loop.types import ConfirmationPolicy, ConfirmationUIResult
208+
from haystack.hooks.human_in_the_loop.types import (
209+
ConfirmationPolicy,
210+
ConfirmationUIResult,
211+
)
209212
from typing import Any
210213

211214

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

229232
```python
230-
from haystack.human_in_the_loop.types import ConfirmationPolicy
231-
from haystack.human_in_the_loop import ConfirmationUIResult
233+
from haystack.hooks.human_in_the_loop.types import ConfirmationPolicy
234+
from haystack.hooks.human_in_the_loop import ConfirmationUIResult
232235
from typing import Any
233236

234237

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

296299
## Custom UI
297300

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

300303
```python
301-
from haystack.human_in_the_loop.types import ConfirmationUI
302-
from haystack.human_in_the_loop import ConfirmationUIResult
304+
from haystack.hooks.human_in_the_loop.types import ConfirmationUI
305+
from haystack.hooks.human_in_the_loop import ConfirmationUIResult
303306
from typing import Any
304307

305308

0 commit comments

Comments
 (0)