haystack-experimental 0.17.0__tar.gz → 0.19.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/PKG-INFO +24 -27
  2. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/README.md +23 -25
  3. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/agents/agent.py +75 -143
  4. haystack_experimental-0.19.0/haystack_experimental/components/agents/human_in_the_loop/__init__.py +22 -0
  5. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/agents/human_in_the_loop/breakpoint.py +1 -2
  6. haystack_experimental-0.19.0/haystack_experimental/components/agents/human_in_the_loop/strategies.py +128 -0
  7. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/dataclasses/breakpoints.py +3 -4
  8. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/pyproject.toml +2 -2
  9. haystack_experimental-0.17.0/haystack_experimental/components/agents/human_in_the_loop/__init__.py +0 -35
  10. haystack_experimental-0.17.0/haystack_experimental/components/agents/human_in_the_loop/dataclasses.py +0 -72
  11. haystack_experimental-0.17.0/haystack_experimental/components/agents/human_in_the_loop/policies.py +0 -78
  12. haystack_experimental-0.17.0/haystack_experimental/components/agents/human_in_the_loop/strategies.py +0 -672
  13. haystack_experimental-0.17.0/haystack_experimental/components/agents/human_in_the_loop/types.py +0 -124
  14. haystack_experimental-0.17.0/haystack_experimental/components/agents/human_in_the_loop/user_interfaces.py +0 -209
  15. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/.gitignore +0 -0
  16. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/LICENSE +0 -0
  17. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/LICENSE-MIT.txt +0 -0
  18. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/__init__.py +0 -0
  19. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/chat_message_stores/__init__.py +0 -0
  20. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/chat_message_stores/in_memory.py +0 -0
  21. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/chat_message_stores/types.py +0 -0
  22. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/__init__.py +0 -0
  23. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/agents/__init__.py +0 -0
  24. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/agents/human_in_the_loop/errors.py +0 -0
  25. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/embedders/__init__.py +0 -0
  26. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/embedders/types/__init__.py +0 -0
  27. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/embedders/types/protocol.py +0 -0
  28. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/generators/__init__.py +0 -0
  29. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/generators/chat/__init__.py +0 -0
  30. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/generators/chat/openai.py +0 -0
  31. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/preprocessors/__init__.py +0 -0
  32. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/preprocessors/md_header_level_inferrer.py +0 -0
  33. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/retrievers/__init__.py +0 -0
  34. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/retrievers/chat_message_retriever.py +0 -0
  35. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/retrievers/types/__init__.py +0 -0
  36. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/retrievers/types/protocol.py +0 -0
  37. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/summarizers/__init__.py +0 -0
  38. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/summarizers/llm_summarizer.py +0 -0
  39. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/writers/__init__.py +0 -0
  40. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/components/writers/chat_message_writer.py +0 -0
  41. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/core/__init__.py +0 -0
  42. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/core/pipeline/__init__.py +0 -0
  43. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/core/pipeline/breakpoint.py +0 -0
  44. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/dataclasses/__init__.py +0 -0
  45. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/memory_stores/__init__.py +0 -0
  46. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/memory_stores/mem0/__init__.py +0 -0
  47. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/memory_stores/mem0/memory_store.py +0 -0
  48. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/memory_stores/types/__init__.py +0 -0
  49. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/memory_stores/types/protocol.py +0 -0
  50. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/utils/__init__.py +0 -0
  51. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/utils/hallucination_risk_calculator/__init__.py +0 -0
  52. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/utils/hallucination_risk_calculator/core_math.py +0 -0
  53. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/utils/hallucination_risk_calculator/dataclasses.py +0 -0
  54. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/utils/hallucination_risk_calculator/openai_planner.py +0 -0
  55. {haystack_experimental-0.17.0 → haystack_experimental-0.19.0}/haystack_experimental/utils/hallucination_risk_calculator/skeletonization.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haystack-experimental
3
- Version: 0.17.0
3
+ Version: 0.19.0
4
4
  Summary: Experimental components and features for the Haystack LLM framework.
5
5
  Project-URL: CI: GitHub, https://github.com/deepset-ai/haystack-experimental/actions
6
6
  Project-URL: GitHub: issues, https://github.com/deepset-ai/haystack-experimental/issues
@@ -24,7 +24,6 @@ Classifier: Programming Language :: Python :: 3.13
24
24
  Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
25
  Requires-Python: >=3.10
26
26
  Requires-Dist: haystack-ai
27
- Requires-Dist: rich
28
27
  Description-Content-Type: text/markdown
29
28
 
30
29
  [![PyPI - Version](https://img.shields.io/pypi/v/haystack-experimental.svg)](https://pypi.org/project/haystack-experimental)
@@ -70,14 +69,14 @@ that includes it. Once it reaches the end of its lifespan, the experiment will b
70
69
 
71
70
  ### Active experiments
72
71
 
73
- | Name | Type | Expected End Date | Dependencies | Cookbook | Discussion |
74
- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------|-------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
75
- | [`OpenAIChatGenerator`][9] | Chat Generator Component | November 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/hallucination_score_calculator.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][10] |
76
- | [`MarkdownHeaderLevelInferrer`][15] | Preprocessor | January 2025 | None | None | [Discuss][16] |
77
- | [`Agent`][17]; [Confirmation Policies][18]; [ConfirmationUIs][19]; [ConfirmationStrategies][20]; [`ConfirmationUIResult` and `ToolExecutionDecision`][21] [HITLBreakpointException][22] | Human in the Loop | December 2025 | rich | None | [Discuss][23] |
78
- | [`LLMSummarizer`][24] | Document Summarizer | January 2025 | None | None | [Discuss][25] |
79
- | [`InMemoryChatMessageStore`][1]; [`ChatMessageRetriever`][2]; [`ChatMessageWriter`][3] | Chat Message Store, Retriever, Writer | February 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/conversational_rag_using_memory.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][4] |
80
- | [`Mem0MemoryStore`][26] | MemoryStore | February 2025 | mem0ai | None | -- |
72
+ | Name | Type | Expected End Date | Dependencies | Cookbook | Discussion |
73
+ |----------------------------------------------------------------------------------------|---------------------------------------|-------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
74
+ | [`OpenAIChatGenerator`][9] | Chat Generator Component | November 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/hallucination_score_calculator.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][10] |
75
+ | [`MarkdownHeaderLevelInferrer`][15] | Preprocessor | January 2025 | None | None | [Discuss][16] |
76
+ | [`Agent`][17]; [`BreakpointConfirmationStrategy`][20]; [`HITLBreakpointException`][22] | Human in the Loop via Breakpoints | December 2025 | None | None | [Discuss][23] |
77
+ | [`LLMSummarizer`][24] | Document Summarizer | January 2025 | None | None | [Discuss][25] |
78
+ | [`InMemoryChatMessageStore`][1]; [`ChatMessageRetriever`][2]; [`ChatMessageWriter`][3] | Chat Message Store, Retriever, Writer | February 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/conversational_rag_using_memory.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][4] |
79
+ | [`Mem0MemoryStore`][26] | MemoryStore | April 2025 | mem0ai | None | -- |
81
80
 
82
81
  [1]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/chat_message_stores/in_memory.py
83
82
  [2]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/retrievers/chat_message_retriever.py
@@ -88,10 +87,7 @@ that includes it. Once it reaches the end of its lifespan, the experiment will b
88
87
  [15]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/preprocessors/md_header_level_inferrer.py
89
88
  [16]: https://github.com/deepset-ai/haystack-experimental/discussions/376
90
89
  [17]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/agent.py
91
- [18]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/policies.py
92
- [19]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/user_interfaces.py
93
90
  [20]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/strategies.py
94
- [21]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/dataclasses.py
95
91
  [22]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/errors.py
96
92
  [23]: https://github.com/deepset-ai/haystack-experimental/discussions/381
97
93
  [24]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/sumarizers/llm_summarizer.py
@@ -99,20 +95,21 @@ that includes it. Once it reaches the end of its lifespan, the experiment will b
99
95
  [26]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/memory_stores/mem0/memory_store.py
100
96
 
101
97
  ### Adopted experiments
102
- | Name | Type | Final release |
103
- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|---------------|
104
- | `ChatMessage` refactoring; `Tool` class; tool support in ChatGenerators; `ToolInvoker` | Tool Calling support | 0.4.0 |
105
- | `AsyncPipeline`; `Pipeline` bug fixes and refactoring | AsyncPipeline execution | 0.7.0 |
106
- | `LLMMetadataExtractor` | Metadata extraction with LLM | 0.7.0 |
107
- | `Auto-Merging Retriever` & `HierarchicalDocumentSplitter` | Document Splitting & Retrieval Technique | 0.8.0 |
108
- | `Agent` | Simplify Agent development | 0.8.0 |
109
- | `SuperComponent` | Simplify Pipeline development | 0.8.0 |
110
- | `Pipeline` | Pipeline breakpoints for debugging | 0.12.0 |
111
- | `ImageContent`; Image Converters; multimodal support in `OpenAIChatGenerator` and `AmazonBedrockChatGenerator`; `ChatPromptBuilder` refactoring; `SentenceTransformersDocumentImageEmbedder`; `LLMDocumentContentExtractor`; new `Routers` | Multimodality | 0.12.0 |
112
- | `QueryExpander` | Query Expansion Component | 0.14.3 |
113
- | `MultiQueryEmbeddingRetriever` | MultiQueryEmbeddingRetriever | 0.14.3 |
114
- | `MultiQueryTextRetriever` | MultiQueryTextRetriever | 0.14.3 |
115
- | `EmbeddingBasedDocumentSplitter` | Document Splitting | 0.15.2 |
98
+ | Name | Type | Final release |
99
+ |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|---------------|
100
+ | `ChatMessage` refactoring; `Tool` class; tool support in ChatGenerators; `ToolInvoker` | Tool Calling support | 0.4.0 |
101
+ | `AsyncPipeline`; `Pipeline` bug fixes and refactoring | AsyncPipeline execution | 0.7.0 |
102
+ | `LLMMetadataExtractor` | Metadata extraction with LLM | 0.7.0 |
103
+ | `Auto-Merging Retriever` & `HierarchicalDocumentSplitter` | Document Splitting & Retrieval Technique | 0.8.0 |
104
+ | `Agent` | Simplify Agent development | 0.8.0 |
105
+ | `SuperComponent` | Simplify Pipeline development | 0.8.0 |
106
+ | `Pipeline` | Pipeline breakpoints for debugging | 0.12.0 |
107
+ | `ImageContent`; Image Converters; multimodal support in `OpenAIChatGenerator` and `AmazonBedrockChatGenerator`; `ChatPromptBuilder` refactoring; `SentenceTransformersDocumentImageEmbedder`; `LLMDocumentContentExtractor`; new `Routers` | Multimodality | 0.12.0 |
108
+ | `QueryExpander` | Query Expansion Component | 0.14.3 |
109
+ | `MultiQueryEmbeddingRetriever` | MultiQueryEmbeddingRetriever | 0.14.3 |
110
+ | `MultiQueryTextRetriever` | MultiQueryTextRetriever | 0.14.3 |
111
+ | `EmbeddingBasedDocumentSplitter` | Document Splitting | 0.15.2 |
112
+ | `Confirmation Policies`; `ConfirmationUIs`; `BlockingConfirmationStrategy`; `ConfirmationUIResult`; `ToolExecutionDecision` | Human in the Loop | 0.16.0 |
116
113
 
117
114
  ### Discontinued experiments
118
115
 
@@ -41,14 +41,14 @@ that includes it. Once it reaches the end of its lifespan, the experiment will b
41
41
 
42
42
  ### Active experiments
43
43
 
44
- | Name | Type | Expected End Date | Dependencies | Cookbook | Discussion |
45
- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------|-------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
46
- | [`OpenAIChatGenerator`][9] | Chat Generator Component | November 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/hallucination_score_calculator.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][10] |
47
- | [`MarkdownHeaderLevelInferrer`][15] | Preprocessor | January 2025 | None | None | [Discuss][16] |
48
- | [`Agent`][17]; [Confirmation Policies][18]; [ConfirmationUIs][19]; [ConfirmationStrategies][20]; [`ConfirmationUIResult` and `ToolExecutionDecision`][21] [HITLBreakpointException][22] | Human in the Loop | December 2025 | rich | None | [Discuss][23] |
49
- | [`LLMSummarizer`][24] | Document Summarizer | January 2025 | None | None | [Discuss][25] |
50
- | [`InMemoryChatMessageStore`][1]; [`ChatMessageRetriever`][2]; [`ChatMessageWriter`][3] | Chat Message Store, Retriever, Writer | February 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/conversational_rag_using_memory.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][4] |
51
- | [`Mem0MemoryStore`][26] | MemoryStore | February 2025 | mem0ai | None | -- |
44
+ | Name | Type | Expected End Date | Dependencies | Cookbook | Discussion |
45
+ |----------------------------------------------------------------------------------------|---------------------------------------|-------------------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|
46
+ | [`OpenAIChatGenerator`][9] | Chat Generator Component | November 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/hallucination_score_calculator.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][10] |
47
+ | [`MarkdownHeaderLevelInferrer`][15] | Preprocessor | January 2025 | None | None | [Discuss][16] |
48
+ | [`Agent`][17]; [`BreakpointConfirmationStrategy`][20]; [`HITLBreakpointException`][22] | Human in the Loop via Breakpoints | December 2025 | None | None | [Discuss][23] |
49
+ | [`LLMSummarizer`][24] | Document Summarizer | January 2025 | None | None | [Discuss][25] |
50
+ | [`InMemoryChatMessageStore`][1]; [`ChatMessageRetriever`][2]; [`ChatMessageWriter`][3] | Chat Message Store, Retriever, Writer | February 2025 | None | <a href="https://colab.research.google.com/github/deepset-ai/haystack-cookbook/blob/main/notebooks/conversational_rag_using_memory.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/> | [Discuss][4] |
51
+ | [`Mem0MemoryStore`][26] | MemoryStore | April 2025 | mem0ai | None | -- |
52
52
 
53
53
  [1]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/chat_message_stores/in_memory.py
54
54
  [2]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/retrievers/chat_message_retriever.py
@@ -59,10 +59,7 @@ that includes it. Once it reaches the end of its lifespan, the experiment will b
59
59
  [15]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/preprocessors/md_header_level_inferrer.py
60
60
  [16]: https://github.com/deepset-ai/haystack-experimental/discussions/376
61
61
  [17]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/agent.py
62
- [18]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/policies.py
63
- [19]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/user_interfaces.py
64
62
  [20]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/strategies.py
65
- [21]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/dataclasses.py
66
63
  [22]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/errors.py
67
64
  [23]: https://github.com/deepset-ai/haystack-experimental/discussions/381
68
65
  [24]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/sumarizers/llm_summarizer.py
@@ -70,20 +67,21 @@ that includes it. Once it reaches the end of its lifespan, the experiment will b
70
67
  [26]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/memory_stores/mem0/memory_store.py
71
68
 
72
69
  ### Adopted experiments
73
- | Name | Type | Final release |
74
- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|---------------|
75
- | `ChatMessage` refactoring; `Tool` class; tool support in ChatGenerators; `ToolInvoker` | Tool Calling support | 0.4.0 |
76
- | `AsyncPipeline`; `Pipeline` bug fixes and refactoring | AsyncPipeline execution | 0.7.0 |
77
- | `LLMMetadataExtractor` | Metadata extraction with LLM | 0.7.0 |
78
- | `Auto-Merging Retriever` & `HierarchicalDocumentSplitter` | Document Splitting & Retrieval Technique | 0.8.0 |
79
- | `Agent` | Simplify Agent development | 0.8.0 |
80
- | `SuperComponent` | Simplify Pipeline development | 0.8.0 |
81
- | `Pipeline` | Pipeline breakpoints for debugging | 0.12.0 |
82
- | `ImageContent`; Image Converters; multimodal support in `OpenAIChatGenerator` and `AmazonBedrockChatGenerator`; `ChatPromptBuilder` refactoring; `SentenceTransformersDocumentImageEmbedder`; `LLMDocumentContentExtractor`; new `Routers` | Multimodality | 0.12.0 |
83
- | `QueryExpander` | Query Expansion Component | 0.14.3 |
84
- | `MultiQueryEmbeddingRetriever` | MultiQueryEmbeddingRetriever | 0.14.3 |
85
- | `MultiQueryTextRetriever` | MultiQueryTextRetriever | 0.14.3 |
86
- | `EmbeddingBasedDocumentSplitter` | Document Splitting | 0.15.2 |
70
+ | Name | Type | Final release |
71
+ |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------|---------------|
72
+ | `ChatMessage` refactoring; `Tool` class; tool support in ChatGenerators; `ToolInvoker` | Tool Calling support | 0.4.0 |
73
+ | `AsyncPipeline`; `Pipeline` bug fixes and refactoring | AsyncPipeline execution | 0.7.0 |
74
+ | `LLMMetadataExtractor` | Metadata extraction with LLM | 0.7.0 |
75
+ | `Auto-Merging Retriever` & `HierarchicalDocumentSplitter` | Document Splitting & Retrieval Technique | 0.8.0 |
76
+ | `Agent` | Simplify Agent development | 0.8.0 |
77
+ | `SuperComponent` | Simplify Pipeline development | 0.8.0 |
78
+ | `Pipeline` | Pipeline breakpoints for debugging | 0.12.0 |
79
+ | `ImageContent`; Image Converters; multimodal support in `OpenAIChatGenerator` and `AmazonBedrockChatGenerator`; `ChatPromptBuilder` refactoring; `SentenceTransformersDocumentImageEmbedder`; `LLMDocumentContentExtractor`; new `Routers` | Multimodality | 0.12.0 |
80
+ | `QueryExpander` | Query Expansion Component | 0.14.3 |
81
+ | `MultiQueryEmbeddingRetriever` | MultiQueryEmbeddingRetriever | 0.14.3 |
82
+ | `MultiQueryTextRetriever` | MultiQueryTextRetriever | 0.14.3 |
83
+ | `EmbeddingBasedDocumentSplitter` | Document Splitting | 0.15.2 |
84
+ | `Confirmation Policies`; `ConfirmationUIs`; `BlockingConfirmationStrategy`; `ConfirmationUIResult`; `ToolExecutionDecision` | Human in the Loop | 0.16.0 |
87
85
 
88
86
  ### Discontinued experiments
89
87
 
@@ -6,7 +6,6 @@
6
6
  # ruff: noqa: I001
7
7
 
8
8
  import inspect
9
- from dataclasses import dataclass
10
9
  from typing import Any
11
10
 
12
11
  # Monkey patch Haystack's AgentSnapshot with our extended version
@@ -22,11 +21,14 @@ import haystack_experimental.core.pipeline.breakpoint as exp_breakpoint
22
21
  hs_breakpoint._create_agent_snapshot = exp_breakpoint._create_agent_snapshot
23
22
  hs_breakpoint._create_pipeline_snapshot_from_tool_invoker = exp_breakpoint._create_pipeline_snapshot_from_tool_invoker # type: ignore[assignment]
24
23
 
25
- from haystack import DeserializationError, logging
26
- from haystack.components.agents.agent import Agent as HaystackAgent
27
- from haystack.components.agents.agent import _ExecutionContext as Haystack_ExecutionContext
28
- from haystack.components.agents.agent import _schema_from_dict
29
- from haystack.components.agents.state import replace_values, State
24
+ from haystack import component, logging
25
+ from haystack.components.agents.agent import Agent as HaystackAgent, _ExecutionContext, _schema_from_dict
26
+ from haystack.human_in_the_loop.strategies import (
27
+ ConfirmationStrategy,
28
+ _process_confirmation_strategies,
29
+ _process_confirmation_strategies_async,
30
+ )
31
+ from haystack.components.agents.state import replace_values
30
32
  from haystack.components.generators.chat.types import ChatGenerator
31
33
  from haystack.core.errors import BreakpointException, PipelineRuntimeError
32
34
  from haystack.core.pipeline import AsyncPipeline, Pipeline
@@ -37,24 +39,16 @@ from haystack.core.pipeline.breakpoint import (
37
39
  _should_trigger_tool_invoker_breakpoint,
38
40
  )
39
41
  from haystack.core.pipeline.utils import _deepcopy_with_exceptions
40
- from haystack.core.serialization import default_from_dict, import_class_by_name
41
- from haystack.dataclasses import ChatMessage, ChatRole
42
+ from haystack.core.serialization import default_from_dict
43
+ from haystack.dataclasses import ChatMessage
42
44
  from haystack.dataclasses.breakpoints import AgentBreakpoint, ToolBreakpoint
43
- from haystack.dataclasses.streaming_chunk import StreamingCallbackT, select_streaming_callback
45
+ from haystack.dataclasses.streaming_chunk import StreamingCallbackT
44
46
  from haystack.tools import ToolsType, deserialize_tools_or_toolset_inplace
45
47
  from haystack.utils.callable_serialization import deserialize_callable
46
- from haystack.utils.deserialization import deserialize_chatgenerator_inplace
48
+ from haystack.utils.deserialization import deserialize_component_inplace
47
49
 
48
50
  from haystack_experimental.chat_message_stores.types import ChatMessageStore
49
- from haystack_experimental.components.agents.human_in_the_loop import (
50
- ConfirmationStrategy,
51
- ToolExecutionDecision,
52
- HITLBreakpointException,
53
- )
54
- from haystack_experimental.components.agents.human_in_the_loop.strategies import (
55
- _process_confirmation_strategies,
56
- _process_confirmation_strategies_async,
57
- )
51
+ from haystack_experimental.components.agents.human_in_the_loop import HITLBreakpointException
58
52
  from haystack_experimental.components.retrievers import ChatMessageRetriever
59
53
  from haystack_experimental.components.writers import ChatMessageWriter
60
54
  from haystack_experimental.memory_stores.types import MemoryStore
@@ -62,26 +56,7 @@ from haystack_experimental.memory_stores.types import MemoryStore
62
56
  logger = logging.getLogger(__name__)
63
57
 
64
58
 
65
- @dataclass
66
- class _ExecutionContext(Haystack_ExecutionContext):
67
- """
68
- Execution context for the Agent component
69
-
70
- Extends Haystack's _ExecutionContext to include tool execution decisions for human-in-the-loop strategies.
71
-
72
- :param tool_execution_decisions: Optional list of ToolExecutionDecision objects to use instead of prompting
73
- the user. This is useful when restarting from a snapshot where tool execution decisions were already made.
74
- :param confirmation_strategy_context: Optional dictionary for passing request-scoped resources
75
- to confirmation strategies. In web/server environments, this enables passing per-request
76
- objects (e.g., WebSocket connections, async queues, or pub/sub clients) that strategies can use for
77
- non-blocking user interaction. This is passed directly to strategies via the `confirmation_strategy_context`
78
- parameter in their `run()` and `run_async()` methods.
79
- """
80
-
81
- tool_execution_decisions: list[ToolExecutionDecision] | None = None
82
- confirmation_strategy_context: dict[str, Any] | None = None
83
-
84
-
59
+ @component
85
60
  class Agent(HaystackAgent):
86
61
  """
87
62
  A Haystack component that implements a tool-using agent with provider-agnostic chat model support.
@@ -182,8 +157,8 @@ class Agent(HaystackAgent):
182
157
  streaming_callback=streaming_callback,
183
158
  raise_on_tool_invocation_failure=raise_on_tool_invocation_failure,
184
159
  tool_invoker_kwargs=tool_invoker_kwargs,
160
+ confirmation_strategies=confirmation_strategies,
185
161
  )
186
- self._confirmation_strategies = confirmation_strategies or {}
187
162
  self._chat_message_store = chat_message_store
188
163
  self._chat_message_retriever = (
189
164
  ChatMessageRetriever(chat_message_store=chat_message_store) if chat_message_store else None
@@ -226,79 +201,57 @@ class Agent(HaystackAgent):
226
201
  For example, it can include the `chat_history_id` and `last_k` parameters for retrieving chat history.
227
202
  :param kwargs: Additional data to pass to the State used by the Agent.
228
203
  """
229
- system_prompt = system_prompt or self.system_prompt
230
- retrieved_memory = None
231
- updated_system_prompt = system_prompt
204
+ exe_context = super(Agent, self)._initialize_fresh_execution(
205
+ messages=messages,
206
+ streaming_callback=streaming_callback,
207
+ requires_async=requires_async,
208
+ system_prompt=system_prompt,
209
+ generation_kwargs=generation_kwargs,
210
+ tools=tools,
211
+ confirmation_strategy_context=confirmation_strategy_context,
212
+ chat_message_store_kwargs=chat_message_store_kwargs,
213
+ **kwargs,
214
+ )
232
215
 
233
- # Retrieve memories from the memory store
216
+ # NOTE: difference with parent method to add memory retrieval
234
217
  if self._memory_store:
235
- retrieved_memories = self._memory_store.search_memories(query=messages[-1].text, **memory_store_kwargs) # type: ignore[arg-type]
236
-
218
+ retrieved_memories = self._memory_store.search_memories(
219
+ query=messages[-1].text, **memory_store_kwargs if memory_store_kwargs else {}
220
+ )
237
221
  # we combine the memories into a single string
238
222
  combined_memory = "\n".join(
239
223
  f"- MEMORY #{idx + 1}: {memory.text}" for idx, memory in enumerate(retrieved_memories)
240
224
  )
241
225
  retrieved_memory = ChatMessage.from_system(text=combined_memory)
242
-
243
- if retrieved_memory:
244
226
  memory_instruction = (
245
- "\n\nWhen messages start with `[MEMORY]`, treat them as long-term "
246
- "context and use them to guide the response if relevant."
227
+ "\n\nWhen messages start with `[MEMORY]`, treat them as long-term context and use them to guide the "
228
+ "response if relevant."
247
229
  )
248
- updated_system_prompt = f"{system_prompt}{memory_instruction}"
249
-
250
- memory_text = f"Here are the relevant memories for the user's query: {retrieved_memory.text}"
251
- print(memory_text)
252
- updated_memory = ChatMessage.from_system(text=memory_text)
253
- else:
254
- updated_memory = None
255
-
256
- combined_messages = messages + [updated_memory] if updated_memory else messages
257
- if updated_system_prompt is not None:
258
- combined_messages = [ChatMessage.from_system(updated_system_prompt)] + combined_messages
230
+ new_system_message = ChatMessage.from_system(text=f"{system_prompt}{memory_instruction}")
231
+ memory_system_message = ChatMessage.from_system(
232
+ text=f"Here are the relevant memories for the user's query: {retrieved_memory.text}"
233
+ )
234
+ new_chat_history = [new_system_message] + messages + [memory_system_message]
235
+ # We replace the messages in state with the new chat history including memories
236
+ exe_context.state.set("messages", new_chat_history, handler_override=replace_values)
259
237
 
260
238
  # NOTE: difference with parent method to add chat message retrieval
261
239
  if self._chat_message_retriever:
262
240
  retriever_kwargs = _select_kwargs(self._chat_message_retriever, chat_message_store_kwargs or {})
263
241
  if "chat_history_id" in retriever_kwargs:
264
- messages = self._chat_message_retriever.run(
265
- current_messages=combined_messages,
242
+ updated_messages = self._chat_message_retriever.run(
243
+ current_messages=exe_context.state.get("messages", []),
266
244
  **retriever_kwargs,
267
245
  )["messages"]
268
- combined_messages = messages
246
+ # We replace the messages in state with the updated messages including chat history
247
+ exe_context.state.set("messages", updated_messages, handler_override=replace_values)
269
248
 
270
- if all(m.is_from(ChatRole.SYSTEM) for m in combined_messages):
271
- logger.warning("All messages provided to the Agent component are system messages. This is not recommended.")
272
-
273
- state = State(schema=self.state_schema, data=kwargs)
274
- state.set("messages", combined_messages)
275
-
276
- streaming_callback = select_streaming_callback( # type: ignore[call-overload]
277
- init_callback=self.streaming_callback, runtime_callback=streaming_callback, requires_async=requires_async
278
- )
279
-
280
- selected_tools = self._select_tools(tools)
281
- tool_invoker_inputs: dict[str, Any] = {"tools": selected_tools}
282
- generator_inputs: dict[str, Any] = {"tools": selected_tools}
283
- if streaming_callback is not None:
284
- tool_invoker_inputs["streaming_callback"] = streaming_callback
285
- generator_inputs["streaming_callback"] = streaming_callback
286
- if generation_kwargs is not None:
287
- generator_inputs["generation_kwargs"] = generation_kwargs
288
-
289
- # NOTE: difference with parent method to add this to tool_invoker_inputs
290
- if self._tool_invoker:
291
- tool_invoker_inputs["enable_streaming_callback_passthrough"] = (
292
- self._tool_invoker.enable_streaming_callback_passthrough
293
- )
294
-
295
- # NOTE: difference is to use the extended _ExecutionContext with confirmation_strategy_context
296
249
  return _ExecutionContext(
297
- state=state,
298
- component_visits=dict.fromkeys(["chat_generator", "tool_invoker"], 0),
299
- chat_generator_inputs=generator_inputs,
300
- tool_invoker_inputs=tool_invoker_inputs,
301
- confirmation_strategy_context=confirmation_strategy_context,
250
+ state=exe_context.state,
251
+ component_visits=exe_context.component_visits,
252
+ chat_generator_inputs=exe_context.chat_generator_inputs,
253
+ tool_invoker_inputs=exe_context.tool_invoker_inputs,
254
+ confirmation_strategy_context=exe_context.confirmation_strategy_context,
302
255
  )
303
256
 
304
257
  def _initialize_from_snapshot( # type: ignore[override]
@@ -324,28 +277,15 @@ class Agent(HaystackAgent):
324
277
  :param confirmation_strategy_context: Optional dictionary for passing request-scoped resources
325
278
  to confirmation strategies.
326
279
  """
327
- # The PR https://github.com/deepset-ai/haystack/pull/9616 added the generation_kwargs parameter to
328
- # _initialize_from_snapshot. This change has been released in Haystack 2.20.0.
329
- # To maintain compatibility with Haystack 2.19 we check the number of parameters and call accordingly.
330
- if inspect.signature(super(Agent, self)._initialize_from_snapshot).parameters.get("generation_kwargs"):
331
- exe_context = super(Agent, self)._initialize_from_snapshot( # type: ignore[call-arg]
332
- snapshot=snapshot,
333
- streaming_callback=streaming_callback,
334
- requires_async=requires_async,
335
- generation_kwargs=generation_kwargs,
336
- tools=tools,
337
- )
338
- else:
339
- exe_context = super(Agent, self)._initialize_from_snapshot(
340
- snapshot=snapshot, streaming_callback=streaming_callback, requires_async=requires_async, tools=tools
341
- )
342
- # NOTE: 1st difference with parent method to add this to tool_invoker_inputs
343
- if self._tool_invoker:
344
- exe_context.tool_invoker_inputs["enable_streaming_callback_passthrough"] = (
345
- self._tool_invoker.enable_streaming_callback_passthrough
346
- )
347
- # NOTE: 2nd difference is to use the extended _ExecutionContext
348
- # and add tool_execution_decisions + confirmation_strategy_context
280
+ exe_context = super(Agent, self)._initialize_from_snapshot(
281
+ snapshot=snapshot,
282
+ streaming_callback=streaming_callback,
283
+ requires_async=requires_async,
284
+ generation_kwargs=generation_kwargs,
285
+ tools=tools,
286
+ confirmation_strategy_context=confirmation_strategy_context,
287
+ )
288
+ # NOTE: Only difference is to use pass tool_execution_decisions to _ExecutionContext
349
289
  return _ExecutionContext(
350
290
  state=exe_context.state,
351
291
  component_visits=exe_context.component_visits,
@@ -353,8 +293,8 @@ class Agent(HaystackAgent):
353
293
  tool_invoker_inputs=exe_context.tool_invoker_inputs,
354
294
  counter=exe_context.counter,
355
295
  skip_chat_generator=exe_context.skip_chat_generator,
296
+ confirmation_strategy_context=exe_context.confirmation_strategy_context,
356
297
  tool_execution_decisions=snapshot.tool_execution_decisions,
357
- confirmation_strategy_context=confirmation_strategy_context,
358
298
  )
359
299
 
360
300
  def run( # type: ignore[override] # noqa: PLR0915 PLR0912
@@ -515,8 +455,9 @@ class Agent(HaystackAgent):
515
455
  resolved_break_point = break_point
516
456
  break_point_to_pass = resolved_break_point.break_point
517
457
 
518
- # Apply confirmation strategies and update State and messages sent to ToolInvoker
458
+ # NOTE: difference with parent method to add support HITLBreakpointException
519
459
  try:
460
+ # Apply confirmation strategies and update State and messages sent to ToolInvoker
520
461
  # Run confirmation strategies to get updated tool call messages and modified chat history
521
462
  modified_tool_call_messages, new_chat_history = _process_confirmation_strategies(
522
463
  confirmation_strategies=self._confirmation_strategies,
@@ -772,8 +713,9 @@ class Agent(HaystackAgent):
772
713
  resolved_break_point = break_point
773
714
  break_point_to_pass = resolved_break_point.break_point
774
715
 
775
- # Apply confirmation strategies and update State and messages sent to ToolInvoker
716
+ # NOTE: difference with parent method to add support HITLBreakpointException
776
717
  try:
718
+ # Apply confirmation strategies and update State and messages sent to ToolInvoker
777
719
  # Run confirmation strategies to get updated tool call messages and modified chat history (async)
778
720
  modified_tool_call_messages, new_chat_history = await _process_confirmation_strategies_async(
779
721
  confirmation_strategies=self._confirmation_strategies,
@@ -873,14 +815,13 @@ class Agent(HaystackAgent):
873
815
  :return: Dictionary with serialized data
874
816
  """
875
817
  data = super(Agent, self).to_dict()
876
- data["init_parameters"]["confirmation_strategies"] = (
877
- {name: strategy.to_dict() for name, strategy in self._confirmation_strategies.items()}
878
- if self._confirmation_strategies
879
- else None
880
- )
818
+ # NOTE: This is different from the base Agent class to handle ChatMessageStore serialization
881
819
  data["init_parameters"]["chat_message_store"] = (
882
820
  self._chat_message_store.to_dict() if self._chat_message_store is not None else None
883
821
  )
822
+ data["init_parameters"]["memory_store"] = (
823
+ self._memory_store.to_dict() if self._memory_store is not None else None
824
+ )
884
825
  return data
885
826
 
886
827
  @classmethod
@@ -893,9 +834,9 @@ class Agent(HaystackAgent):
893
834
  """
894
835
  init_params = data.get("init_parameters", {})
895
836
 
896
- deserialize_chatgenerator_inplace(init_params, key="chat_generator")
837
+ deserialize_component_inplace(init_params, key="chat_generator")
897
838
 
898
- if "state_schema" in init_params:
839
+ if init_params.get("state_schema") is not None:
899
840
  init_params["state_schema"] = _schema_from_dict(init_params["state_schema"])
900
841
 
901
842
  if init_params.get("streaming_callback") is not None:
@@ -904,24 +845,15 @@ class Agent(HaystackAgent):
904
845
  deserialize_tools_or_toolset_inplace(init_params, key="tools")
905
846
 
906
847
  if "confirmation_strategies" in init_params and init_params["confirmation_strategies"] is not None:
907
- for name, strategy_dict in init_params["confirmation_strategies"].items():
908
- try:
909
- strategy_class = import_class_by_name(strategy_dict["type"])
910
- except ImportError as e:
911
- raise DeserializationError(f"Class '{strategy_dict['type']}' not correctly imported") from e
912
- if not hasattr(strategy_class, "from_dict"):
913
- raise DeserializationError(f"{strategy_class} does not have from_dict method implemented.")
914
- init_params["confirmation_strategies"][name] = strategy_class.from_dict(strategy_dict)
848
+ for name in init_params["confirmation_strategies"]:
849
+ deserialize_component_inplace(init_params["confirmation_strategies"], key=name)
915
850
 
851
+ # NOTE: This is different from the base Agent class to handle ChatMessageStore deserialization
916
852
  if "chat_message_store" in init_params and init_params["chat_message_store"] is not None:
917
- cms_data = init_params["chat_message_store"]
918
- try:
919
- cms_class = import_class_by_name(cms_data["type"])
920
- except ImportError as e:
921
- raise DeserializationError(f"Class '{cms_data['type']}' not correctly imported") from e
922
- if not hasattr(cms_class, "from_dict"):
923
- raise DeserializationError(f"{cms_class} does not have from_dict method implemented.")
924
- init_params["chat_message_store"] = cms_class.from_dict(cms_data)
853
+ deserialize_component_inplace(init_params, key="chat_message_store")
854
+
855
+ if "memory_store" in init_params and init_params["memory_store"] is not None:
856
+ deserialize_component_inplace(init_params, key="memory_store")
925
857
 
926
858
  return default_from_dict(cls, data)
927
859
 
@@ -0,0 +1,22 @@
1
+ # SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ import sys
6
+ from typing import TYPE_CHECKING
7
+
8
+ from lazy_imports import LazyImporter
9
+
10
+ _import_structure = {
11
+ "dataclasses": ["ToolExecutionDecision"],
12
+ "errors": ["HITLBreakpointException"],
13
+ "strategies": ["BreakpointConfirmationStrategy"],
14
+ }
15
+
16
+ if TYPE_CHECKING:
17
+ from .dataclasses import ToolExecutionDecision as ToolExecutionDecision
18
+ from .errors import HITLBreakpointException as HITLBreakpointException
19
+ from .strategies import BreakpointConfirmationStrategy as BreakpointConfirmationStrategy
20
+
21
+ else:
22
+ sys.modules[__name__] = LazyImporter(name=__name__, module_file=__file__, import_structure=_import_structure)
@@ -5,10 +5,9 @@
5
5
  from copy import deepcopy
6
6
 
7
7
  from haystack.dataclasses.breakpoints import AgentSnapshot, ToolBreakpoint
8
+ from haystack.human_in_the_loop.strategies import _prepare_tool_args
8
9
  from haystack.utils import _deserialize_value_with_schema
9
10
 
10
- from haystack_experimental.components.agents.human_in_the_loop.strategies import _prepare_tool_args
11
-
12
11
 
13
12
  def get_tool_calls_and_descriptions_from_snapshot(
14
13
  agent_snapshot: AgentSnapshot, breakpoint_tool_only: bool = True