diff --git a/docs-website/reference/haystack-api/connectors_api.md b/docs-website/reference/haystack-api/connectors_api.md
index 0aa612fd28f..665d9cad77e 100644
--- a/docs-website/reference/haystack-api/connectors_api.md
+++ b/docs-website/reference/haystack-api/connectors_api.md
@@ -121,11 +121,11 @@ Sends an HTTP request as described by this path.
- **data** (Any | None) – The request body to send.
- **parameters** (dict\[str, Any\] | None) – The parameters used to create the path.
- **raw_response** (bool) – If true, return the raw response instead of validating
- and exterpolating it.
+ and extrapolating it.
- **security** (dict\[str, str\] | None) – The security scheme to use, and the values it needs to
process successfully.
- **session** (Any | None) – A persistent request session.
-- **verify** (bool | str) – If we should do an ssl verification on the request or not.
+- **verify** (bool | str) – If we should do an SSL verification on the request or not.
In case str was provided, will use that as the CA.
**Returns:**
diff --git a/docs-website/reference/haystack-api/converters_api.md b/docs-website/reference/haystack-api/converters_api.md
index 0a8a5ed7755..9c7bece1642 100644
--- a/docs-website/reference/haystack-api/converters_api.md
+++ b/docs-website/reference/haystack-api/converters_api.md
@@ -147,6 +147,7 @@ It can attach metadata to the resulting documents.
```python
from haystack.components.converters.csv import CSVToDocument
+from datetime import datetime
converter = CSVToDocument()
results = converter.run(sources=["sample.csv"], meta={"date_added": datetime.now().isoformat()})
documents = results["documents"]
@@ -1836,7 +1837,6 @@ Converts text files to documents.
### XLSXToDocument
-````
Converts XLSX (Excel) files into Documents.
Supports reading data from specific sheets or all sheets in the Excel file. If all sheets are read, a Document is
@@ -1846,18 +1846,14 @@ created for each sheet. The content of the Document is the table which can be sa
```python
from haystack.components.converters.xlsx import XLSXToDocument
+from datetime import datetime
converter = XLSXToDocument()
results = converter.run(sources=["sample.xlsx"], meta={"date_added": datetime.now().isoformat()})
documents = results["documents"]
print(documents[0].content)
-# ",A,B
-````
-
-1,col_a,col_b
-2,1.5,test
-"
-\`\`\`
+# ",A,B\n1,col_a,col_b\n2,1.5,test\n"
+```
#### __init__
diff --git a/docs-website/reference/haystack-api/document_stores_api.md b/docs-website/reference/haystack-api/document_stores_api.md
index 0b6afe50bad..635ffe2a63b 100644
--- a/docs-website/reference/haystack-api/document_stores_api.md
+++ b/docs-website/reference/haystack-api/document_stores_api.md
@@ -483,6 +483,57 @@ Returns the number of unique values for each specified metadata field from docum
- dict\[str, int\] – A dictionary mapping each metadata field name (without "meta." prefix)
to the count of its unique values among the filtered documents.
+#### get_metadata_fields_info_async
+
+```python
+get_metadata_fields_info_async() -> dict[str, dict[str, str]]
+```
+
+Returns information about the metadata fields present in the stored documents.
+
+Types are inferred from the stored values (keyword, int, float, boolean).
+
+**Returns:**
+
+- dict\[str, dict\[str, str\]\] – A dictionary mapping each metadata field name to a dict with a "type" key.
+
+#### get_metadata_field_min_max_async
+
+```python
+get_metadata_field_min_max_async(metadata_field: str) -> dict[str, Any]
+```
+
+Returns the minimum and maximum values for the given metadata field across all documents.
+
+**Parameters:**
+
+- **metadata_field** (str) – The metadata field name. Can include or omit the "meta." prefix.
+
+**Returns:**
+
+- dict\[str, Any\] – A dictionary with "min" and "max" keys. Returns `{"min": None, "max": None}`
+ if the field is missing or has no values.
+
+#### get_metadata_field_unique_values_async
+
+```python
+get_metadata_field_unique_values_async(
+ metadata_field: str, search_term: str | None = None
+) -> tuple[list[str], int]
+```
+
+Returns unique values for a metadata field, optionally filtered by a search term in content.
+
+**Parameters:**
+
+- **metadata_field** (str) – The metadata field name. Can include or omit the "meta." prefix.
+- **search_term** (str | None) – If set, only documents whose content contains this term (case-insensitive)
+ are considered.
+
+**Returns:**
+
+- tuple\[list\[str\], int\] – A tuple of (list of unique values, total count of unique values).
+
#### delete_all_documents_async
```python
diff --git a/docs-website/reference/haystack-api/evaluators_api.md b/docs-website/reference/haystack-api/evaluators_api.md
index b7f42f77d7d..19b5589d358 100644
--- a/docs-website/reference/haystack-api/evaluators_api.md
+++ b/docs-website/reference/haystack-api/evaluators_api.md
@@ -635,7 +635,7 @@ print(result["score"])
# 0.5
print(result["results"])
# [{'statements': ['Python is a high-level general-purpose programming language.',
-'Python was created by George Lucas.'], 'statement_scores': [1, 0], 'score': 0.5}]
+# 'Python was created by George Lucas.'], 'statement_scores': [1, 0], 'score': 0.5}]
```
#### __init__
diff --git a/docs-website/reference/haystack-api/generators_api.md b/docs-website/reference/haystack-api/generators_api.md
index af7c5a5dd7b..cfb12bbcb11 100644
--- a/docs-website/reference/haystack-api/generators_api.md
+++ b/docs-website/reference/haystack-api/generators_api.md
@@ -746,7 +746,7 @@ print(result)
#### With paid inference endpoints
-````python
+```python
from haystack.components.generators.chat import HuggingFaceAPIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.utils import Secret
@@ -760,6 +760,7 @@ generator = HuggingFaceAPIChatGenerator(api_type="inference_endpoints",
result = generator.run(messages)
print(result)
+```
#### With self-hosted text generation inference
@@ -775,7 +776,7 @@ generator = HuggingFaceAPIChatGenerator(api_type="text_generation_inference",
result = generator.run(messages)
print(result)
-````
+```
#### __init__
@@ -2140,11 +2141,11 @@ client = OpenAIGenerator()
response = client.run("What's Natural Language Processing? Be brief.")
print(response)
->> {'replies': ['Natural Language Processing (NLP) is a branch of artificial intelligence that focuses on
->> the interaction between computers and human language. It involves enabling computers to understand, interpret,
->> and respond to natural human language in a way that is both meaningful and useful.'], 'meta': [{'model':
->> 'gpt-5-mini', 'index': 0, 'finish_reason': 'stop', 'usage': {'prompt_tokens': 16,
->> 'completion_tokens': 49, 'total_tokens': 65}}]}
+# >> {'replies': ['Natural Language Processing (NLP) is a branch of artificial intelligence that focuses on
+# >> the interaction between computers and human language. It involves enabling computers to understand, interpret,
+# >> and respond to natural human language in a way that is both meaningful and useful.'], 'meta': [{'model':
+# >> 'gpt-5-mini', 'index': 0, 'finish_reason': 'stop', 'usage': {'prompt_tokens': 16,
+# >> 'completion_tokens': 49, 'total_tokens': 65}}]}
```
#### __init__
diff --git a/docs-website/reference/haystack-api/joiners_api.md b/docs-website/reference/haystack-api/joiners_api.md
index 04f472b417c..26a98dd893f 100644
--- a/docs-website/reference/haystack-api/joiners_api.md
+++ b/docs-website/reference/haystack-api/joiners_api.md
@@ -199,8 +199,8 @@ result = pipe.run(
print(json.loads(result["validator"]["validated"][0].text))
->> {'first_name': 'Peter', 'last_name': 'Parker', 'nationality': 'American', 'name': 'Spider-Man', 'occupation':
->> 'Superhero', 'age': 23, 'location': 'New York City'}
+# >> {'first_name': 'Peter', 'last_name': 'Parker', 'nationality': 'American', 'name': 'Spider-Man', 'occupation':
+# >> 'Superhero', 'age': 23, 'location': 'New York City'}
```
Note that `BranchJoiner` can manage only one data type at a time. In this case, `BranchJoiner` is created for
@@ -545,7 +545,7 @@ pipeline.connect("prompt_builder_2.prompt", "string_joiner.strings")
print(pipeline.run(data={"prompt_builder_1": {"query": string_1}, "prompt_builder_2": {"query": string_2}}))
->> {"string_joiner": {"strings": ["Builder 1: What's Natural Language Processing?", "Builder 2: What is life?"]}}
+# >> {"string_joiner": {"strings": ["Builder 1: What's Natural Language Processing?", "Builder 2: What is life?"]}}
```
#### run
diff --git a/docs-website/reference/haystack-api/pipeline_api.md b/docs-website/reference/haystack-api/pipeline_api.md
index b5e289761fd..a2b70a80de9 100644
--- a/docs-website/reference/haystack-api/pipeline_api.md
+++ b/docs-website/reference/haystack-api/pipeline_api.md
@@ -420,6 +420,7 @@ Answer:
retriever = InMemoryBM25Retriever(document_store=document_store)
prompt_builder = PromptBuilder(template=prompt_template)
+api_key = "your-openai-api-key"
llm = OpenAIGenerator(api_key=Secret.from_token(api_key))
rag_pipeline = Pipeline()
diff --git a/docs-website/reference/haystack-api/preprocessors_api.md b/docs-website/reference/haystack-api/preprocessors_api.md
index d844a7fabf0..221ed9bf98a 100644
--- a/docs-website/reference/haystack-api/preprocessors_api.md
+++ b/docs-website/reference/haystack-api/preprocessors_api.md
@@ -861,12 +861,12 @@ AI technology is widely used throughout industry, government, and science. Some
doc = Document(content=text)
doc_chunks = chunker.run([doc])
print(doc_chunks["documents"])
->[
->Document(id=..., content: 'Artificial intelligence (AI) - Introduction\n\n', meta: {'original_id': '...', 'split_id': 0, 'split_idx_start': 0, '_split_overlap': []})
->Document(id=..., content: 'AI, in its broadest sense, is intelligence exhibited by machines, particularly computer systems.\n', meta: {'original_id': '...', 'split_id': 1, 'split_idx_start': 45, '_split_overlap': []})
->Document(id=..., content: 'AI technology is widely used throughout industry, government, and science.', meta: {'original_id': '...', 'split_id': 2, 'split_idx_start': 142, '_split_overlap': []})
->Document(id=..., content: ' Some high-profile applications include advanced web search engines; recommendation systems; interac...', meta: {'original_id': '...', 'split_id': 3, 'split_idx_start': 216, '_split_overlap': []})
->]
+# [
+# Document(id=..., content: 'Artificial intelligence (AI) - Introduction\n\n', meta: {'original_id': '...', 'split_id': 0, 'split_idx_start': 0, '_split_overlap': []})
+# Document(id=..., content: 'AI, in its broadest sense, is intelligence exhibited by machines, particularly computer systems.\n', meta: {'original_id': '...', 'split_id': 1, 'split_idx_start': 45, '_split_overlap': []})
+# Document(id=..., content: 'AI technology is widely used throughout industry, government, and science.', meta: {'original_id': '...', 'split_id': 2, 'split_idx_start': 142, '_split_overlap': []})
+# Document(id=..., content: ' Some high-profile applications include advanced web search engines; recommendation systems; interac...', meta: {'original_id': '...', 'split_id': 3, 'split_idx_start': 216, '_split_overlap': []})
+# ]
```
#### __init__
diff --git a/docs-website/reference/haystack-api/routers_api.md b/docs-website/reference/haystack-api/routers_api.md
index 15e7f799898..6f7eb0101c2 100644
--- a/docs-website/reference/haystack-api/routers_api.md
+++ b/docs-website/reference/haystack-api/routers_api.md
@@ -516,12 +516,12 @@ Categorize files or byte streams according to their MIME types.
### LLMMessagesRouter
-````
Routes Chat Messages to different connections using a generative Language Model to perform classification.
This component can be used with general-purpose LLMs and with specialized LLMs for moderation like Llama Guard.
### Usage example
+
```python
from haystack.components.generators.chat import HuggingFaceAPIChatGenerator
from haystack.components.routers.llm_messages_router import LLMMessagesRouter
@@ -541,20 +541,17 @@ router = LLMMessagesRouter(chat_generator=chat_generator,
print(router.run([ChatMessage.from_user("How to rob a bank?")]))
# {
-# 'chat_generator_text': 'unsafe
-````
-
-S2',
-\# 'unsafe': \[
-\# ChatMessage(
-\# \_role=\,
-\# \_content=[TextContent(text='How to rob a bank?')],
-\# \_name=None,
-\# \_meta={}
-\# )
-\# \]
-\# }
-\`\`\`
+# 'chat_generator_text': 'unsafe\nS2',
+# 'unsafe': [
+# ChatMessage(
+# _role=,
+# _content=[TextContent(text='How to rob a bank?')],
+# _name=None,
+# _meta={}
+# )
+# ]
+# }
+```
#### __init__
diff --git a/docs-website/reference/haystack-api/tools_api.md b/docs-website/reference/haystack-api/tools_api.md
index a391f7b2586..258547651c6 100644
--- a/docs-website/reference/haystack-api/tools_api.md
+++ b/docs-website/reference/haystack-api/tools_api.md
@@ -662,8 +662,10 @@ from haystack.tools import Tool, SearchableToolset
# Create a catalog of tools
catalog = [
- Tool(name="get_weather", description="Get weather for a city", ...),
- Tool(name="search_web", description="Search the web", ...),
+ Tool(name="get_weather", description="Get weather for a city",
+ parameters={}, function=lambda: None),
+ Tool(name="search_web", description="Search the web",
+ parameters={}, function=lambda: None),
# ... 100s more tools
]
toolset = SearchableToolset(catalog=catalog)
@@ -918,116 +920,116 @@ Toolset serves two main purposes:
Example:
- ```python
- from haystack.tools import Tool, Toolset
- from haystack.components.tools import ToolInvoker
-
- # Define math functions
- def add_numbers(a: int, b: int) -> int:
- return a + b
-
- def subtract_numbers(a: int, b: int) -> int:
- return a - b
-
- # Create tools with proper schemas
- add_tool = Tool(
- name="add",
- description="Add two numbers",
- parameters={
- "type": "object",
- "properties": {
- "a": {"type": "integer"},
- "b": {"type": "integer"}
- },
- "required": ["a", "b"]
- },
- function=add_numbers
- )
-
- subtract_tool = Tool(
- name="subtract",
- description="Subtract b from a",
- parameters={
- "type": "object",
- "properties": {
- "a": {"type": "integer"},
- "b": {"type": "integer"}
- },
- "required": ["a", "b"]
- },
- function=subtract_numbers
- )
-
- # Create a toolset with the math tools
- math_toolset = Toolset([add_tool, subtract_tool])
-
- # Use the toolset with a ToolInvoker or ChatGenerator component
- invoker = ToolInvoker(tools=math_toolset)
- ```
+```python
+from haystack.tools import Tool, Toolset
+from haystack.components.tools import ToolInvoker
+
+# Define math functions
+def add_numbers(a: int, b: int) -> int:
+ return a + b
+
+def subtract_numbers(a: int, b: int) -> int:
+ return a - b
+
+# Create tools with proper schemas
+add_tool = Tool(
+ name="add",
+ description="Add two numbers",
+ parameters={
+ "type": "object",
+ "properties": {
+ "a": {"type": "integer"},
+ "b": {"type": "integer"}
+ },
+ "required": ["a", "b"]
+ },
+ function=add_numbers
+)
+
+subtract_tool = Tool(
+ name="subtract",
+ description="Subtract b from a",
+ parameters={
+ "type": "object",
+ "properties": {
+ "a": {"type": "integer"},
+ "b": {"type": "integer"}
+ },
+ "required": ["a", "b"]
+ },
+ function=subtract_numbers
+)
+
+# Create a toolset with the math tools
+math_toolset = Toolset([add_tool, subtract_tool])
-1. Base class for dynamic tool loading:
+# Use the toolset with a ToolInvoker or ChatGenerator component
+invoker = ToolInvoker(tools=math_toolset)
+```
+
+2. Base class for dynamic tool loading:
By subclassing Toolset, you can create implementations that dynamically load tools
from external sources like OpenAPI URLs, MCP servers, or other resources.
Example:
- ```python
- from haystack.core.serialization import generate_qualified_class_name
- from haystack.tools import Tool, Toolset
- from haystack.components.tools import ToolInvoker
-
- class CalculatorToolset(Toolset):
- '''A toolset for calculator operations.'''
-
- def __init__(self) -> None:
- tools = self._create_tools()
- super().__init__(tools)
-
- def _create_tools(self):
- # These Tool instances are obviously defined statically and for illustration purposes only.
- # In a real-world scenario, you would dynamically load tools from an external source here.
- tools = []
- add_tool = Tool(
- name="add",
- description="Add two numbers",
- parameters={
- "type": "object",
- "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}},
- "required": ["a", "b"],
- },
- function=lambda a, b: a + b,
- )
-
- multiply_tool = Tool(
- name="multiply",
- description="Multiply two numbers",
- parameters={
- "type": "object",
- "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}},
- "required": ["a", "b"],
- },
- function=lambda a, b: a * b,
- )
-
- tools.append(add_tool)
- tools.append(multiply_tool)
-
- return tools
-
- def to_dict(self):
- return {
- "type": generate_qualified_class_name(type(self)),
- "data": {}, # no data to serialize as we define the tools dynamically
- }
-
- @classmethod
- def from_dict(cls, data):
- return cls() # Recreate the tools dynamically during deserialization
-
- # Create the dynamic toolset and use it with ToolInvoker
- calculator_toolset = CalculatorToolset()
- invoker = ToolInvoker(tools=calculator_toolset)
- ```
+```python
+from haystack.core.serialization import generate_qualified_class_name
+from haystack.tools import Tool, Toolset
+from haystack.components.tools import ToolInvoker
+
+class CalculatorToolset(Toolset):
+ '''A toolset for calculator operations.'''
+
+ def __init__(self) -> None:
+ tools = self._create_tools()
+ super().__init__(tools)
+
+ def _create_tools(self):
+ # These Tool instances are obviously defined statically and for illustration purposes only.
+ # In a real-world scenario, you would dynamically load tools from an external source here.
+ tools = []
+ add_tool = Tool(
+ name="add",
+ description="Add two numbers",
+ parameters={
+ "type": "object",
+ "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}},
+ "required": ["a", "b"],
+ },
+ function=lambda a, b: a + b,
+ )
+
+ multiply_tool = Tool(
+ name="multiply",
+ description="Multiply two numbers",
+ parameters={
+ "type": "object",
+ "properties": {"a": {"type": "integer"}, "b": {"type": "integer"}},
+ "required": ["a", "b"],
+ },
+ function=lambda a, b: a * b,
+ )
+
+ tools.append(add_tool)
+ tools.append(multiply_tool)
+
+ return tools
+
+ def to_dict(self):
+ return {
+ "type": generate_qualified_class_name(type(self)),
+ "data": {}, # no data to serialize as we define the tools dynamically
+ }
+
+ @classmethod
+ def from_dict(cls, data):
+ return cls() # Recreate the tools dynamically during deserialization
+
+# Create the dynamic toolset and use it with ToolInvoker
+calculator_toolset = CalculatorToolset()
+invoker = ToolInvoker(tools=calculator_toolset)
+```
Toolset implements the collection interface (__iter__, __contains__, __len__, __getitem__),
making it behave like a list of Tools. This makes it compatible with components that expect