haystack-experimental 0.16.0__py3-none-any.whl → 0.18.0__py3-none-any.whl

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 (19) hide show
  1. haystack_experimental/components/agents/agent.py +135 -124
  2. haystack_experimental/components/agents/human_in_the_loop/__init__.py +2 -15
  3. haystack_experimental/components/agents/human_in_the_loop/breakpoint.py +1 -2
  4. haystack_experimental/components/agents/human_in_the_loop/strategies.py +4 -548
  5. haystack_experimental/dataclasses/breakpoints.py +3 -4
  6. haystack_experimental/memory_stores/__init__.py +7 -0
  7. haystack_experimental/memory_stores/mem0/__init__.py +16 -0
  8. haystack_experimental/memory_stores/mem0/memory_store.py +323 -0
  9. haystack_experimental/memory_stores/types/__init__.py +7 -0
  10. haystack_experimental/memory_stores/types/protocol.py +94 -0
  11. {haystack_experimental-0.16.0.dist-info → haystack_experimental-0.18.0.dist-info}/METADATA +25 -26
  12. {haystack_experimental-0.16.0.dist-info → haystack_experimental-0.18.0.dist-info}/RECORD +15 -14
  13. haystack_experimental/components/agents/human_in_the_loop/dataclasses.py +0 -72
  14. haystack_experimental/components/agents/human_in_the_loop/policies.py +0 -78
  15. haystack_experimental/components/agents/human_in_the_loop/types.py +0 -124
  16. haystack_experimental/components/agents/human_in_the_loop/user_interfaces.py +0 -209
  17. {haystack_experimental-0.16.0.dist-info → haystack_experimental-0.18.0.dist-info}/WHEEL +0 -0
  18. {haystack_experimental-0.16.0.dist-info → haystack_experimental-0.18.0.dist-info}/licenses/LICENSE +0 -0
  19. {haystack_experimental-0.16.0.dist-info → haystack_experimental-0.18.0.dist-info}/licenses/LICENSE-MIT.txt +0 -0
@@ -0,0 +1,323 @@
1
+ # SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from typing import Any
6
+
7
+ from haystack import default_from_dict, default_to_dict, logging
8
+ from haystack.dataclasses.chat_message import ChatMessage
9
+ from haystack.lazy_imports import LazyImport
10
+ from haystack.utils import Secret, deserialize_secrets_inplace
11
+
12
+ with LazyImport(message="Run 'pip install mem0ai'") as mem0_import:
13
+ from mem0 import MemoryClient # pylint: disable=import-error
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+
18
+ class Mem0MemoryStore:
19
+ """
20
+ A memory store implementation using Mem0 as the backend.
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ *,
26
+ api_key: Secret = Secret.from_env_var("MEM0_API_KEY"),
27
+ ):
28
+ """
29
+ Initialize the Mem0 memory store.
30
+
31
+ :param api_key: The Mem0 API key. You can also set it using `MEM0_API_KEY` environment variable.
32
+ """
33
+
34
+ mem0_import.check()
35
+ self.api_key = api_key
36
+ self.client = MemoryClient(
37
+ api_key=self.api_key.resolve_value(),
38
+ )
39
+
40
+ def to_dict(self) -> dict[str, Any]:
41
+ """Serialize the store configuration to a dictionary."""
42
+ return default_to_dict(
43
+ self,
44
+ api_key=self.api_key.to_dict(),
45
+ )
46
+
47
+ @classmethod
48
+ def from_dict(cls, data: dict[str, Any]) -> "Mem0MemoryStore":
49
+ """Deserialize the store from a dictionary."""
50
+ deserialize_secrets_inplace(data["init_parameters"], keys=["api_key"])
51
+
52
+ return default_from_dict(cls, data)
53
+
54
+ def add_memories(
55
+ self,
56
+ *,
57
+ messages: list[ChatMessage],
58
+ infer: bool = True,
59
+ user_id: str | None = None,
60
+ run_id: str | None = None,
61
+ agent_id: str | None = None,
62
+ async_mode: bool = False,
63
+ **kwargs: Any,
64
+ ) -> list[dict[str, Any]]:
65
+ """
66
+ Add ChatMessage memories to Mem0.
67
+
68
+ :param messages: List of ChatMessage objects with memory metadata
69
+ :param infer: Whether to infer facts from the messages. If False, the whole message will
70
+ be added as a memory.
71
+ :param user_id: The user ID to to store and retrieve memories from the memory store.
72
+ :param run_id: The run ID to to store and retrieve memories from the memory store.
73
+ :param agent_id: The agent ID to to store and retrieve memories from the memory store.
74
+ If you want Mem0 to store chat messages from the assistant, you need to set the agent_id.
75
+ :param async_mode: Whether to add memories asynchronously.
76
+ If True, the method will return immediately and the memories will be added in the background.
77
+ :param kwargs: Additional keyword arguments to pass to the Mem0 client.add method.
78
+ Note: ChatMessage.meta in the list of messages will be ignored because Mem0 doesn't allow
79
+ passing metadata for each message in the list. You can pass metadata for the whole memory
80
+ by passing the `metadata` keyword argument to the method.
81
+ :returns: List of objects with the memory_id and the memory
82
+ """
83
+ added_ids = []
84
+ ids = self._get_ids(user_id, run_id, agent_id)
85
+ instructions = """
86
+ Store all memories from the user and suggestions from the assistant.
87
+ """
88
+
89
+ self.client.project.update(custom_instructions=instructions)
90
+ mem0_messages = []
91
+ for message in messages:
92
+ if not message.text:
93
+ continue
94
+ # we save the role of the message in the metadata
95
+ mem0_messages.append({"content": message.text, "role": message.role.value})
96
+ try:
97
+ status = self.client.add(messages=mem0_messages, infer=infer, **ids, async_mode=async_mode, **kwargs)
98
+ if status:
99
+ for result in status["results"]:
100
+ memory_id = {"memory_id": result.get("id"), "memory": result["memory"]}
101
+ added_ids.append(memory_id)
102
+ except Exception as e:
103
+ raise RuntimeError(f"Failed to add memory message: {e}") from e
104
+ return added_ids
105
+
106
+ def search_memories(
107
+ self,
108
+ *,
109
+ query: str | None = None,
110
+ filters: dict[str, Any] | None = None,
111
+ top_k: int = 5,
112
+ user_id: str | None = None,
113
+ run_id: str | None = None,
114
+ agent_id: str | None = None,
115
+ include_memory_metadata: bool = False,
116
+ **kwargs: Any,
117
+ ) -> list[ChatMessage]:
118
+ """
119
+ Search for memories in Mem0.
120
+
121
+ If filters are not provided, at least one of user_id, run_id, or agent_id must be set.
122
+ If filters are provided, the search will be scoped to the provided filters and the other ids will be ignored.
123
+ :param query: Text query to search for. If not provided, all memories will be returned.
124
+ :param filters: Haystack filters to apply on search. For more details on Haystack filters, see https://docs.haystack.deepset.ai/docs/metadata-filtering
125
+ :param top_k: Maximum number of results to return
126
+ :param user_id: The user ID to to store and retrieve memories from the memory store.
127
+ :param run_id: The run ID to to store and retrieve memories from the memory store.
128
+ :param agent_id: The agent ID to to store and retrieve memories from the memory store.
129
+ If you want Mem0 to store chat messages from the assistant, you need to set the agent_id.
130
+ :param include_memory_metadata: Whether to include the mem0 related metadata for the
131
+ retrieved memory in the ChatMessage.
132
+ If True, the metadata will include the mem0 related metadata i.e. memory_id, score, etc.
133
+ in the `mem0_memory_metadata` key.
134
+ If False, the `ChatMessage.meta` will only contain the user defined metadata.
135
+ :param kwargs: Additional keyword arguments to pass to the Mem0 client.
136
+ If query is passed, the kwargs will be passed to the Mem0 client.search method.
137
+ If query is not passed, the kwargs will be passed to the Mem0 client.get_all method.
138
+ :returns: List of ChatMessage memories matching the criteria
139
+ """
140
+ # Prepare filters for Mem0
141
+
142
+ if filters:
143
+ mem0_filters = self.normalize_filters(filters)
144
+ else:
145
+ ids = self._get_ids(user_id, run_id, agent_id)
146
+ if len(ids) == 1:
147
+ mem0_filters = dict(ids)
148
+ else:
149
+ mem0_filters = {"AND": [{key: value} for key, value in ids.items()]}
150
+ try:
151
+ if not query:
152
+ memories = self.client.get_all(filters=mem0_filters, **kwargs)
153
+ else:
154
+ memories = self.client.search(
155
+ query=query,
156
+ top_k=top_k,
157
+ filters=mem0_filters,
158
+ **kwargs,
159
+ )
160
+ messages = []
161
+ for memory in memories["results"]:
162
+ meta = memory["metadata"].copy() if memory["metadata"] else {}
163
+ # we also include the mem0 related metadata i.e. memory_id, score, etc.
164
+ if include_memory_metadata:
165
+ meta["retrieved_memory_metadata"] = memory.copy()
166
+ meta["retrieved_memory_metadata"].pop("memory")
167
+ messages.append(ChatMessage.from_system(text=memory["memory"], meta=meta))
168
+ return messages
169
+
170
+ except Exception as e:
171
+ raise RuntimeError(f"Failed to search memories: {e}") from e
172
+
173
+ def search_memories_as_single_message(
174
+ self,
175
+ *,
176
+ query: str | None = None,
177
+ filters: dict[str, Any] | None = None,
178
+ top_k: int = 5,
179
+ user_id: str | None = None,
180
+ run_id: str | None = None,
181
+ agent_id: str | None = None,
182
+ **kwargs: Any,
183
+ ) -> ChatMessage:
184
+ """
185
+ Search for memories in Mem0 and return a single ChatMessage object.
186
+
187
+ If filters are not provided, at least one of user_id, run_id, or agent_id must be set.
188
+ If filters are provided, the search will be scoped to the provided filters and the other ids will be ignored.
189
+ :param query: Text query to search for. If not provided, all memories will be returned.
190
+ :param filters: Additional filters to apply on search. For more details on mem0 filters, see https://mem0.ai/docs/search/
191
+ :param top_k: Maximum number of results to return
192
+ :param user_id: The user ID to to store and retrieve memories from the memory store.
193
+ :param run_id: The run ID to to store and retrieve memories from the memory store.
194
+ :param agent_id: The agent ID to to store and retrieve memories from the memory store.
195
+ If you want Mem0 to store chat messages from the assistant, you need to set the agent_id.
196
+ :param kwargs: Additional keyword arguments to pass to the Mem0 client.
197
+ If query is passed, the kwargs will be passed to the Mem0 client.search method.
198
+ If query is not passed, the kwargs will be passed to the Mem0 client.get_all method.
199
+ :returns: A single ChatMessage object with the memories matching the criteria
200
+ """
201
+ # Prepare filters for Mem0
202
+ if filters:
203
+ mem0_filters = self.normalize_filters(filters)
204
+ else:
205
+ ids = self._get_ids(user_id, run_id, agent_id)
206
+ if len(ids) == 1:
207
+ mem0_filters = dict(ids)
208
+ else:
209
+ mem0_filters = {"AND": [{key: value} for key, value in ids.items()]}
210
+
211
+ try:
212
+ if not query:
213
+ memories = self.client.get_all(filters=mem0_filters, **kwargs)
214
+ else:
215
+ memories = self.client.search(
216
+ query=query,
217
+ top_k=top_k,
218
+ filters=mem0_filters,
219
+ **kwargs,
220
+ )
221
+
222
+ # we combine the memories into a single string
223
+ combined_memory = "\n".join(
224
+ f"- MEMORY #{idx + 1}: {memory['memory']}" for idx, memory in enumerate(memories["results"])
225
+ )
226
+
227
+ return ChatMessage.from_system(text=combined_memory)
228
+
229
+ except Exception as e:
230
+ raise RuntimeError(f"Failed to search memories: {e}") from e
231
+
232
+ def delete_all_memories(
233
+ self,
234
+ *,
235
+ user_id: str | None = None,
236
+ run_id: str | None = None,
237
+ agent_id: str | None = None,
238
+ **kwargs: Any,
239
+ ) -> None:
240
+ """
241
+ Delete memory records from Mem0.
242
+
243
+ At least one of user_id, run_id, or agent_id must be set.
244
+ :param user_id: The user ID to delete memories from.
245
+ :param run_id: The run ID to delete memories from.
246
+ :param agent_id: The agent ID to delete memories from.
247
+ :param kwargs: Additional keyword arguments to pass to the Mem0 client.delete_all method.
248
+ """
249
+ ids = self._get_ids(user_id, run_id, agent_id)
250
+
251
+ try:
252
+ self.client.delete_all(**ids, **kwargs)
253
+ logger.info("All memories deleted successfully for scope {ids}", ids=ids)
254
+ except Exception as e:
255
+ raise RuntimeError(f"Failed to delete memories with scope {ids}: {e}") from e
256
+
257
+ def delete_memory(self, memory_id: str, **kwargs: Any) -> None:
258
+ """
259
+ Delete memory from Mem0.
260
+
261
+ :param memory_id: The ID of the memory to delete.
262
+ :param kwargs: Additional keyword arguments to pass to the Mem0 client.delete method.
263
+ """
264
+ try:
265
+ self.client.delete(memory_id=memory_id, **kwargs)
266
+ logger.info("Memory deleted successfully for memory_id {memory_id}", memory_id=memory_id)
267
+ except Exception as e:
268
+ raise RuntimeError(f"Failed to delete memory {memory_id}: {e}") from e
269
+
270
+ def _get_ids(
271
+ self, user_id: str | None = None, run_id: str | None = None, agent_id: str | None = None
272
+ ) -> dict[str, Any]:
273
+ """
274
+ Check that at least one of the ids is set.
275
+
276
+ Return the set ids as a dictionary.
277
+ """
278
+ if not user_id and not run_id and not agent_id:
279
+ raise ValueError("At least one of user_id, run_id, or agent_id must be set")
280
+ ids = {
281
+ "user_id": user_id,
282
+ "run_id": run_id,
283
+ "agent_id": agent_id,
284
+ }
285
+ return {key: value for key, value in ids.items() if value is not None}
286
+
287
+ @staticmethod
288
+ def normalize_filters(filters: dict[str, Any]) -> dict[str, Any]:
289
+ """
290
+ Convert Haystack filters to Mem0 filters.
291
+ """
292
+
293
+ def convert_comparison(condition: dict[str, Any]) -> dict[str, Any]:
294
+ operator_map = {
295
+ "==": lambda field, value: {field: value},
296
+ "!=": lambda field, value: {field: {"ne": value}},
297
+ ">": lambda field, value: {field: {"gt": value}},
298
+ ">=": lambda field, value: {field: {"gte": value}},
299
+ "<": lambda field, value: {field: {"lt": value}},
300
+ "<=": lambda field, value: {field: {"lte": value}},
301
+ "in": lambda field, value: {field: {"in": value if isinstance(value, list) else [value]}},
302
+ "not in": lambda field, value: {field: {"ne": value}},
303
+ }
304
+ field = condition["field"]
305
+ value = condition["value"]
306
+ operator = condition["operator"]
307
+ if operator not in operator_map:
308
+ raise ValueError(f"Unsupported operator {operator}")
309
+ return operator_map[operator](field, value)
310
+
311
+ def convert_logic(node: dict[str, Any]) -> dict[str, Any]:
312
+ operator = node["operator"].upper()
313
+ if operator not in ("AND", "OR", "NOT"):
314
+ raise ValueError(f"Unsupported logic operator {operator}")
315
+ mem0_conditions = [convert_node(cond) for cond in node["conditions"]]
316
+ return {operator: mem0_conditions}
317
+
318
+ def convert_node(node: dict[str, Any]) -> dict[str, Any]:
319
+ if "field" in node:
320
+ return convert_comparison(node)
321
+ return convert_logic(node)
322
+
323
+ return convert_node(filters)
@@ -0,0 +1,7 @@
1
+ # SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from .protocol import MemoryStore
6
+
7
+ __all__ = ["MemoryStore"]
@@ -0,0 +1,94 @@
1
+ # SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2
+ #
3
+ # SPDX-License-Identifier: Apache-2.0
4
+
5
+ from typing import Any, Protocol
6
+
7
+ from haystack.dataclasses import ChatMessage
8
+
9
+ # Ellipsis are needed for the type checker, it's safe to disable module-wide
10
+ # pylint: disable=unnecessary-ellipsis
11
+
12
+
13
+ class MemoryStore(Protocol):
14
+ """
15
+ Stores ChatMessage-based memories to be used by agents and components.
16
+
17
+ Implementations typically persist user- and agent-specific memories and
18
+ support adding, searching, and deleting memories.
19
+ """
20
+
21
+ def to_dict(self) -> dict[str, Any]:
22
+ """
23
+ Serializes this memory store to a dictionary.
24
+ """
25
+ ...
26
+
27
+ @classmethod
28
+ def from_dict(cls, data: dict[str, Any]) -> "MemoryStore":
29
+ """
30
+ Deserializes the memory store from a dictionary.
31
+ """
32
+ ...
33
+
34
+ def add_memories(
35
+ self,
36
+ *,
37
+ messages: list[ChatMessage],
38
+ user_id: str | None = None,
39
+ **kwargs: Any,
40
+ ) -> None:
41
+ """
42
+ Add ChatMessage memories to the store.
43
+
44
+ :param messages: List of ChatMessage objects with memory metadata.
45
+ :param user_id: User ID to scope memories.
46
+ :param kwargs: Additional keyword arguments to pass to the add method.
47
+ """
48
+ ...
49
+
50
+ def search_memories(
51
+ self,
52
+ *,
53
+ query: str | None = None,
54
+ filters: dict[str, Any] | None = None,
55
+ top_k: int = 5,
56
+ user_id: str | None = None,
57
+ **kwargs: Any,
58
+ ) -> list[ChatMessage]:
59
+ """
60
+ Search for memories in the store.
61
+
62
+ :param query: Text query to search for. If not provided, all memories may be returned.
63
+ :param filters: Haystack filters to apply on search.
64
+ :param top_k: Maximum number of results to return.
65
+ :param user_id: User ID to scope memories.
66
+ :param kwargs: Additional keyword arguments to pass to the search method.
67
+
68
+ :returns: List of ChatMessage memories matching the criteria.
69
+ """
70
+ ...
71
+
72
+ def delete_all_memories(
73
+ self,
74
+ *,
75
+ user_id: str | None = None,
76
+ **kwargs: Any,
77
+ ) -> None:
78
+ """
79
+ Delete all memories in the given scope.
80
+
81
+ In case of multiple optional ids, one of the ids must be set.
82
+ :param user_id: User ID to delete memories.
83
+ :param kwargs: Additional keyword arguments to pass to the delete method.
84
+ """
85
+ ...
86
+
87
+ def delete_memory(self, memory_id: str, **kwargs: Any) -> None:
88
+ """
89
+ Delete a single memory by its ID.
90
+
91
+ :param memory_id: The ID of the memory to delete.
92
+ :param kwargs: Additional keyword arguments to pass to the delete method.
93
+ """
94
+ ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: haystack-experimental
3
- Version: 0.16.0
3
+ Version: 0.18.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,13 +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] |
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 | -- |
80
80
 
81
81
  [1]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/chat_message_stores/in_memory.py
82
82
  [2]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/retrievers/chat_message_retriever.py
@@ -87,30 +87,29 @@ that includes it. Once it reaches the end of its lifespan, the experiment will b
87
87
  [15]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/preprocessors/md_header_level_inferrer.py
88
88
  [16]: https://github.com/deepset-ai/haystack-experimental/discussions/376
89
89
  [17]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/agent.py
90
- [18]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/policies.py
91
- [19]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/user_interfaces.py
92
90
  [20]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/strategies.py
93
- [21]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/dataclasses.py
94
91
  [22]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/agents/human_in_the_loop/errors.py
95
92
  [23]: https://github.com/deepset-ai/haystack-experimental/discussions/381
96
93
  [24]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/components/sumarizers/llm_summarizer.py
97
94
  [25]: https://github.com/deepset-ai/haystack-experimental/discussions/382
95
+ [26]: https://github.com/deepset-ai/haystack-experimental/blob/main/haystack_experimental/memory_stores/mem0/memory_store.py
98
96
 
99
97
  ### Adopted experiments
100
- | Name | Type | Final release |
101
- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|---------------|
102
- | `ChatMessage` refactoring; `Tool` class; tool support in ChatGenerators; `ToolInvoker` | Tool Calling support | 0.4.0 |
103
- | `AsyncPipeline`; `Pipeline` bug fixes and refactoring | AsyncPipeline execution | 0.7.0 |
104
- | `LLMMetadataExtractor` | Metadata extraction with LLM | 0.7.0 |
105
- | `Auto-Merging Retriever` & `HierarchicalDocumentSplitter` | Document Splitting & Retrieval Technique | 0.8.0 |
106
- | `Agent` | Simplify Agent development | 0.8.0 |
107
- | `SuperComponent` | Simplify Pipeline development | 0.8.0 |
108
- | `Pipeline` | Pipeline breakpoints for debugging | 0.12.0 |
109
- | `ImageContent`; Image Converters; multimodal support in `OpenAIChatGenerator` and `AmazonBedrockChatGenerator`; `ChatPromptBuilder` refactoring; `SentenceTransformersDocumentImageEmbedder`; `LLMDocumentContentExtractor`; new `Routers` | Multimodality | 0.12.0 |
110
- | `QueryExpander` | Query Expansion Component | 0.14.3 |
111
- | `MultiQueryEmbeddingRetriever` | MultiQueryEmbeddingRetriever | 0.14.3 |
112
- | `MultiQueryTextRetriever` | MultiQueryTextRetriever | 0.14.3 |
113
- | `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 |
114
113
 
115
114
  ### Discontinued experiments
116
115
 
@@ -4,15 +4,11 @@ haystack_experimental/chat_message_stores/in_memory.py,sha256=Dw5N9l8qk-RONEVVJb
4
4
  haystack_experimental/chat_message_stores/types.py,sha256=BHpk36OesvAxMgu6iOOYt4gmqw_cIE4nFDVgiutCguA,2726
5
5
  haystack_experimental/components/__init__.py,sha256=eHD7xrty2PCky_gG3ty19rpM4WfV32TyytM7gJODwl4,110
6
6
  haystack_experimental/components/agents/__init__.py,sha256=Sxu9LxPpQ5cljgoTgUeNC0GY8CwUdiSy1JWkd_-RRJ4,414
7
- haystack_experimental/components/agents/agent.py,sha256=n76MmXq_P0TAuFxHwNe5FC1iBAIjKbs8xOoZioyaypY,45651
8
- haystack_experimental/components/agents/human_in_the_loop/__init__.py,sha256=xLr1G9pNWMmCpKN9mbv6yqeFfwMcbZyaVfCkzlwMxhY,1674
9
- haystack_experimental/components/agents/human_in_the_loop/breakpoint.py,sha256=K5rU61821uXjXkcXuXkN3p1_9Boq7FhJK1GOcAz7C0g,2939
10
- haystack_experimental/components/agents/human_in_the_loop/dataclasses.py,sha256=qQG4yRlzzcNeBlWagnZpjeJKZ2v_n2_9V9W0ZvsgBn4,2538
7
+ haystack_experimental/components/agents/agent.py,sha256=KKVQe6JAsy6TE8vS22xyMcLXP2Ds8JVLXdkL9wM2jYM,46801
8
+ haystack_experimental/components/agents/human_in_the_loop/__init__.py,sha256=NAVRXBjgLXn734XPr208WSjqAinSkkgM4LTpr1cZZ8k,746
9
+ haystack_experimental/components/agents/human_in_the_loop/breakpoint.py,sha256=P94JmVgu2B5spUPu4dMltleOdG7qsoSiJxnxkGGvKrY,2907
11
10
  haystack_experimental/components/agents/human_in_the_loop/errors.py,sha256=Mgn8HWx-3AqTFHu5ZY9PWWb_brMsO1xtdrOFzHzbXRI,1020
12
- haystack_experimental/components/agents/human_in_the_loop/policies.py,sha256=nzblePptT4Fg2GFHa4_SDIK_d7hZ_70qPhkteZBRXWk,3172
13
- haystack_experimental/components/agents/human_in_the_loop/strategies.py,sha256=b9oJgXJ805VMljm55i1S2j2wQ-2-bPxkn5oWG5Vx9RU,28608
14
- haystack_experimental/components/agents/human_in_the_loop/types.py,sha256=Fu6LR67GOimGhzEgJOnpU4pb14zEfk1JtBrDFwTuLk8,4582
15
- haystack_experimental/components/agents/human_in_the_loop/user_interfaces.py,sha256=LHHZc0JljvnzoQaNgFGiAoJyWDYFWeYFPE2khZ4z-x4,8694
11
+ haystack_experimental/components/agents/human_in_the_loop/strategies.py,sha256=027sKjy8oe1tSTBRi9XNpHqJlr5k8IHJRYrfUqFNeRg,4863
16
12
  haystack_experimental/components/embedders/__init__.py,sha256=eHD7xrty2PCky_gG3ty19rpM4WfV32TyytM7gJODwl4,110
17
13
  haystack_experimental/components/embedders/types/__init__.py,sha256=HGR8aavwIEx7v-8nm5JxFIw47EWn7vAUmywhakTNDCo,182
18
14
  haystack_experimental/components/embedders/types/protocol.py,sha256=nVMo2x_sFP9T_DN-q-_HKGrLRd3rj27m7ZLxtigY4UQ,1026
@@ -33,15 +29,20 @@ haystack_experimental/core/__init__.py,sha256=eHD7xrty2PCky_gG3ty19rpM4WfV32Tyyt
33
29
  haystack_experimental/core/pipeline/__init__.py,sha256=eHD7xrty2PCky_gG3ty19rpM4WfV32TyytM7gJODwl4,110
34
30
  haystack_experimental/core/pipeline/breakpoint.py,sha256=NcagwEJupIZ_Mp20YLmJyeqTZe8qwo6LfuB7OTXnlXk,5214
35
31
  haystack_experimental/dataclasses/__init__.py,sha256=eHD7xrty2PCky_gG3ty19rpM4WfV32TyytM7gJODwl4,110
36
- haystack_experimental/dataclasses/breakpoints.py,sha256=JevVOYiUMAsdg0QmSGiF_6aPveO83q47U-v-8Vd4nd0,2082
32
+ haystack_experimental/dataclasses/breakpoints.py,sha256=ZeSjfb72UwGDW9P5sTC59gyEXSobwDtdTus0vMJMuIM,2026
33
+ haystack_experimental/memory_stores/__init__.py,sha256=xkSdV7qQ_e1kNO4PrXW37CIJMGavYiwbPtsfeSHQaQ4,169
34
+ haystack_experimental/memory_stores/mem0/__init__.py,sha256=pntAgiFC6jXvzyHUQUNPtyChlys69jLa6rTVbClTb9I,458
35
+ haystack_experimental/memory_stores/mem0/memory_store.py,sha256=PkDMVRWXooorTpHtnMRHZLgsxokJR8DlnV7vgedhPyk,14148
36
+ haystack_experimental/memory_stores/types/__init__.py,sha256=7Sgg1w9bSGXDQkFXjmB4G4PGCBW7hDIYXItad7UxW4M,172
37
+ haystack_experimental/memory_stores/types/protocol.py,sha256=LG0oK5jAJiVivtzQV7GacyikCDuZZQRQtPtkoJLCDj8,2761
37
38
  haystack_experimental/utils/__init__.py,sha256=eHD7xrty2PCky_gG3ty19rpM4WfV32TyytM7gJODwl4,110
38
39
  haystack_experimental/utils/hallucination_risk_calculator/__init__.py,sha256=kCd-qceud_T8P1XJHgRMaOnljyDjfFQ5UIdxEb5t6V0,219
39
40
  haystack_experimental/utils/hallucination_risk_calculator/core_math.py,sha256=8XIa2gX1B7U400KutPgxfIUHrOggkBPAm9gIkwhF7UM,4079
40
41
  haystack_experimental/utils/hallucination_risk_calculator/dataclasses.py,sha256=8HQL-ktwoog0WZlFz3-NQhhmVMjzMIrRjRoYuYXmorE,2284
41
42
  haystack_experimental/utils/hallucination_risk_calculator/openai_planner.py,sha256=Vt0icGcrPtTRywh9L2YfwB62a7pDynrm5-qlKaLHLsA,11381
42
43
  haystack_experimental/utils/hallucination_risk_calculator/skeletonization.py,sha256=KYdBDw5LcRtw8cmKW4aNGOKh3YrA17CPmcRE-FG6kSA,5466
43
- haystack_experimental-0.16.0.dist-info/METADATA,sha256=C6Dzv_tSvCuvTNMBEgfvdX9nMiZ026jbgNU1AvzXx1w,17078
44
- haystack_experimental-0.16.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
45
- haystack_experimental-0.16.0.dist-info/licenses/LICENSE,sha256=93_5nS97uHxptHvK9E8BZgKxLGeIS-rBWT2swIv-X5Y,11368
46
- haystack_experimental-0.16.0.dist-info/licenses/LICENSE-MIT.txt,sha256=knmLkIKj_6tTrTSVRg9Tq88Kww4UCPLt2I1RGXJv9sQ,1037
47
- haystack_experimental-0.16.0.dist-info/RECORD,,
44
+ haystack_experimental-0.18.0.dist-info/METADATA,sha256=z0FIckGo2ezlyJ5uUjkjonjpJWWT7HQjEL1gKjCOml8,16826
45
+ haystack_experimental-0.18.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
46
+ haystack_experimental-0.18.0.dist-info/licenses/LICENSE,sha256=93_5nS97uHxptHvK9E8BZgKxLGeIS-rBWT2swIv-X5Y,11368
47
+ haystack_experimental-0.18.0.dist-info/licenses/LICENSE-MIT.txt,sha256=knmLkIKj_6tTrTSVRg9Tq88Kww4UCPLt2I1RGXJv9sQ,1037
48
+ haystack_experimental-0.18.0.dist-info/RECORD,,
@@ -1,72 +0,0 @@
1
- # SPDX-FileCopyrightText: 2022-present deepset GmbH <info@deepset.ai>
2
- #
3
- # SPDX-License-Identifier: Apache-2.0
4
-
5
- from dataclasses import asdict, dataclass
6
- from typing import Any
7
-
8
-
9
- @dataclass
10
- class ConfirmationUIResult:
11
- """
12
- Result of the confirmation UI interaction.
13
-
14
- :param action:
15
- The action taken by the user such as "confirm", "reject", or "modify".
16
- This action type is not enforced to allow for custom actions to be implemented.
17
- :param feedback:
18
- Optional feedback message from the user. For example, if the user rejects the tool execution,
19
- they might provide a reason for the rejection.
20
- :param new_tool_params:
21
- Optional set of new parameters for the tool. For example, if the user chooses to modify the tool parameters,
22
- they can provide a new set of parameters here.
23
- """
24
-
25
- action: str # "confirm", "reject", "modify"
26
- feedback: str | None = None
27
- new_tool_params: dict[str, Any] | None = None
28
-
29
-
30
- @dataclass
31
- class ToolExecutionDecision:
32
- """
33
- Decision made regarding tool execution.
34
-
35
- :param tool_name:
36
- The name of the tool to be executed.
37
- :param execute:
38
- A boolean indicating whether to execute the tool with the provided parameters.
39
- :param tool_call_id:
40
- Optional unique identifier for the tool call. This can be used to track and correlate the decision with a
41
- specific tool invocation.
42
- :param feedback:
43
- Optional feedback message.
44
- For example, if the tool execution is rejected, this can contain the reason. Or if the tool parameters were
45
- modified, this can contain the modification details.
46
- :param final_tool_params:
47
- Optional final parameters for the tool if execution is confirmed or modified.
48
- """
49
-
50
- tool_name: str
51
- execute: bool
52
- tool_call_id: str | None = None
53
- feedback: str | None = None
54
- final_tool_params: dict[str, Any] | None = None
55
-
56
- def to_dict(self) -> dict[str, Any]:
57
- """
58
- Convert the ToolExecutionDecision to a dictionary representation.
59
-
60
- :return: A dictionary containing the tool execution decision details.
61
- """
62
- return asdict(self)
63
-
64
- @classmethod
65
- def from_dict(cls, data: dict[str, Any]) -> "ToolExecutionDecision":
66
- """
67
- Populate the ToolExecutionDecision from a dictionary representation.
68
-
69
- :param data: A dictionary containing the tool execution decision details.
70
- :return: An instance of ToolExecutionDecision.
71
- """
72
- return cls(**data)