| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | < 18 hours ago | 15.7 kB | |
| v2.25.0 source code.tar.gz | < 18 hours ago | 14.7 MB | |
| v2.25.0 source code.zip | < 18 hours ago | 19.2 MB | |
| Totals: 3 Items | 33.9 MB | 0 | |
Release Notes
v2.25.0
Upgrade Notes
-
Removed the deprecated
PipelineTemplateandPredefinedPipelineclasses, along with thePipeline.from_template()method. Users should migrate to Pipeline YAML files for similar functionality. See the [Serialization documentation](https://docs.haystack.deepset.ai/docs/serialization) for details on using YAML-based pipeline definitions. -
Default Hugging Face pipeline task updated to ``text-generation``
The default task used by HuggingFaceLocalGenerator has been changed from text2text-generation to text-generation and the default model has been changed from "google/flan-t5-base" to "Qwen/Qwen3-0.6B".
In transformers v5+, text2text-generation is no longer available as a valid pipeline task (see: https://github.com/huggingface/transformers/pull/43256). While parts of the implementation still exist internally, it is no longer supported as a straightforward pipeline option.
How to know if you are affected
- You are using
transformers>=5.0.0. - You explicitly set
task="text2text-generation"inHuggingFaceLocalGeneratororHuggingFaceLocalChatGenerator.
How to handle this change
- Replace
task="text2text-generation"withtask="text-generation". - Ensure that the selected model is compatible with the
text-generationpipeline (for example, causal language models). - If you rely on older behavior, pin
transformers<5. text2text-generationis now considered deprecated in Haystack and may be removed in a future release.
New Features
- Added
link_formatparameter toPPTXToDocumentandXLSXToDocumentconverters, allowing extraction of hyperlink addresses from PPTX and XLSX files.
Supported formats:
"markdown":[text](url)"plain":text (url)"none"(default): Only text is extracted, link addresses are ignored.
This follows the same pattern already available in DOCXToDocument.
- Added a new
LLMcomponent (haystack.components.generators.chat.LLM) that provides a simplified interface for text generation powered by a large language model. TheLLMcomponent is a streamlined version of theAgentthat focuses solely on single-turn text generation without tool usage. It supports system prompts, templated user prompts with required variables, streaming callbacks, and both synchronous (run) and asynchronous (run_async) execution.
Usage example: .. code:: python from haystack.components.generators.chat import LLM from haystack.components.generators.chat import OpenAIChatGenerator from haystack.dataclasses import ChatMessage
llm = LLM(
chat_generator=OpenAIChatGenerator(), system_prompt="You are a helpful translation assistant.", user_prompt="""{% message role="user"%}Summarize the following document: {{ document }} {% endmessage %}""", required_variables=["document"], )
result = llm.run(document="The weather is lovely today and the sun is shining. ") print(result["last_message"].text)
- Introduced the
MarkdownHeaderSplittercomponent: - Splits documents into chunks at Markdown headers (
#,##, etc.), preserving header hierarchy as metadata. - Supports secondary splitting (by word, passage, period, or line) for further chunking after header-based splitting using Haystack's
DocumentSplitter. - Preserves and propagates metadata such as parent headers and page numbers.
-
Handles edge cases such as documents with no headers, empty content, and non-text documents.
-
Added
SearchableToolsettohaystack.toolsmodule. This new toolset enables agents to dynamically discover tools from large catalogs using keyword-based (BM25) search. Instead of exposing all tools upfront (which can overwhelm LLMs with large tool definitions), agents start with a singlesearch_toolsfunction and progressively discover relevant tools as needed. For smaller catalogs, it operates in passthrough mode exposing all tools directly.
Key features include configurable search threshold for automatic passthrough mode and top-k result limiting.
Example usage:
``` python from haystack.components.agents import Agent from haystack.components.generators.chat import OpenAIChatGenerator from haystack.dataclasses import ChatMessage 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", ...), # ... 100s more tools ] toolset = SearchableToolset(catalog=catalog)
agent = Agent(chat_generator=OpenAIChatGenerator(), tools=toolset)
# The agent is initially provided only with the search_tools tool and will use it to find relevant tools. result = agent.run(messages=[ChatMessage.from_user("What's the weather in Milan?")]) ```
- Added
user_promptandrequired_variablesparameters to theAgentcomponent. You can now define a reusable Jinja2-templated user prompt at initialization or at runtime, so the Agent can be invoked with different inputs without manually constructingChatMessageobjects each time.
Example usage: .. code:: python agent = Agent( chat_generator=OpenAIChatGenerator(), tools=tools, system_prompt="You are a helpful translation assistant.", user_prompt="""{% message role="user"%} Translate the following document to {{ language }}: {{ document }} {% endmessage %}""", required_variables=["language", "document"], )
result = agent.run(language="French", document="The weather is lovely today.")
You can also combine messages with user_prompt. The rendered user prompt is appended to the provided messages, which is useful for passing prior conversation context alongside a new templated query: .. code:: python from haystack.dataclasses import ChatMessage
agent = Agent(
chat_generator=OpenAIChatGenerator(), tools=tools, system_prompt="You are a helpful translation assistant.", user_prompt="""{% message role="user"%} Now summarize the conversation in {{ language }}. {% endmessage %}""", required_variables=["language"],)
result = agent.run(
messages=[
ChatMessage.from_user("What are the main benefits of renewable energy?"), ChatMessage.from_assistant( "Renewable energy reduces greenhouse gas emissions, decreases dependence " "on fossil fuels, and can lower long-term energy costs." ),], language="Spanish",
)
- Added support for Chat Messages that include files using the
FileContentdataclass toOpenAIResponsesChatGeneratorandAzureOpenAIResponsesChatGenerator.
Users can now pass files such as PDFs when using Haystack Chat Generators based on the Responses API.
- User Chat Messages can now include files using the new
FileContentdataclass.
Most API-based LLMs support file inputs such as PDFs (and, for some models, additional file types).
For now, this feature is implemented for OpenAIChatGenerator and AzureOpenAIChatGenerator, with support for more model providers coming soon.
For advanced PDF handling, such as reducing image size or selecting specific page ranges, we recommend using the PDFToImageContent component instead.
FileContent example:
python
from haystack.components.generators.chat.openai import OpenAIChatGenerator
from haystack.dataclasses.chat_message import ChatMessage
from haystack.dataclasses.file_content import FileContent
file_content = FileContent.from_url("https://arxiv.org/pdf/2309.08632")
chat_message = ChatMessage.from_user(content_parts=[file_content, "Summarize this paper in 100 words."])
llm = OpenAIChatGenerator(model="gpt-4.1-mini")
response = llm.run(messages=[chat_message])
-
Added the
FileToFileContentcomponent, which converts local files intoFileContentobjects. These can be embedded intoChatMessageto pass to an LLM. -
Added
document_comparison_fieldparameter toDocumentMRREvaluator,DocumentMAPEvaluator, andDocumentRecallEvaluator.
This allows users to compare documents using fields other than content, such as id or metadata keys (via meta.<key> syntax).
Previously, all three evaluators hardcoded doc.content for comparison, which did not work well when documents were chunked or when ground truth was identified by custom metadata fields.
Enhancement Notes
-
The
LLMDocumentContentExtractornow extracts both content and metadata from image-based documents. When the LLM returns JSON,document_contentfills the document body and other keys are merged into metadata; plain text is still used as content. The fieldcontent_extraction_erroris no longer used and when an error occurs the fieldextraction_erroris added to metadata with the error message. -
Improved the deserialization error message for pipeline components to be more actionable and human-readable. The component data dictionary is now pretty-printed as formatted JSON, and the underlying error that caused the failure is explicitly surfaced, making it easier to quickly diagnose deserialization issues.
-
EmbeddingBasedDocumentSplitterandMultiQueryEmbeddingRetrievernow automatically invokewarm_up()whenrun()is called if they have not been warmed up yet. -
Resolve postponed type annotations (from
from __future__ import annotations) when creating component input sockets, so pipelines can correctly match compatible types. This fixes cases where connectingChatPromptBuildertoFallbackChatGeneratorfailed because the generator’s annotations were interpreted as strings (for example'list[ChatMessage]'), resulting in aPipelineConnectErrordue to mismatched socket types. -
Agent components allow grouping multiple tools under a single confirmation strategy.
Here is an example of how three tools can be grouped under a BlockingConfirmationStrategy:
python
confirmation_strategies = {
("tool1", "tool2", "tool3"): BlockingConfirmationStrategy()
}
instead of previously needing
python
confirmation_strategies = {
"tool1": BlockingConfirmationStrategy(),
"tool2": BlockingConfirmationStrategy(),
"tool3": BlockingConfirmationStrategy()
}
-
Improved
ComponentToolto correctly handle components whoserunmethod parameters are declared as top-levelOptionaltypes such aslist[ChatMessage] | None. The optional wrapper is now unwrapped before checking for afrom_dictmethod on the underlying type. As a result, when a parameter is typed aslist[ChatMessage] | Noneand receives a list of dictionaries,ComponentToolwill automatically coerce the input into a list ofChatMessageobjects usingChatMessage.from_dict. If the provided value isNone, the parameter is preserved asNone. -
Haystack now emits a
Warningwhen dataclass instances (e.g.Document,ChatMessage,StreamingChunk,ByteStream,SparseEmbedding) are mutated in place. Modifying shared instances can cause unexpected behavior in other parts of the pipeline. Usedataclasses.replaceto safely create updated copies instead.
Instead of modifying attributes in place:
``` python from haystack.dataclasses import Document
doc = Document(content="old text", meta={"key": "value"})
# Not recommended: can affect other parts of the pipeline doc.content = "new text" ```
Use dataclasses.replace to create a new instance with the updated values:
``` python from dataclasses import replace from haystack.dataclasses import Document
doc = Document(content="old text", meta={"key": "value"})
# Recommended: creates a new Document with updated content doc = replace(doc, content="new text") ```
Bug Fixes
-
Ensure
PipelineandAsyncPipelinedeep-copies component inputs before execution so mutable outputs (e.g.,Documentdataclasses) shared across multiple downstream components don't get mutated by reference. This prevents side effects where one component's in-place modifications could unexpectedly affect other branches in the pipeline. -
Fixed an issue in
OpenAIChatGeneratorandOpenAIResponsesChatGeneratorwhere passing aFileContentobject without a filename would raise an error. A fallback filename is now automatically used instead. -
Ensure type display works correctly for parameterized generics when tracing is enabled. Previously, the
haystack.component.input_specandhaystack.component.output_spectag would strip the arguments present within a container type (e.g.list[str]would become"list"). Now we properly keep the arguments representation (e.g.list[str]becomes"list[str]"). -
Fixed a bug in flexible Pipeline connections that prevented automatic value conversion when the receiving component expects a Union type. For example, connecting a component returning
ChatMessageto a receiver expectinglist[str] | list[ChatMessage]should have worked but did not. The conversion strategy now correctly evaluates each branch of a Union receiver and picks the best match. -
Previously, flexible pipeline connections were not robust when the sender component returned a list containing a union of types. In flexible pipeline connections, if the receiver type is
strorChatMessage, the first element of the list sent by the sender component is extracted and converted to the receiver type.
In the previous version, list[str | int] was considered compatible with str, which should not be the case. In fact, the sender component can legitimately return a list where the first element has type int, which the receiver cannot handle.
This is now fixed by ensuring that all possible element types of the sender list can be converted to the receiver type using the same conversion strategy.
- Improved device handling when loading Hugging Face models in
TransformersSimilarityRankerandExtractiveReader.
hf_device_map is not always present anymore and is now only set when mixed-device loading is explicitly configured. The code has been updated to:
- Check whether
hf_device_mapis available. - Fall back to the standard
deviceattribute when it is not.
This prevents attribute errors and ensures compatibility across different transformers configurations.
-
Updated failing unit tests to align with recent mocking and
transformersbehavior changes. -
PipelineRuntimeErrorraised byAgentnow provide clearer ownership by explicitly surfacing theAgentas the failing pipeline component.
As a result:
component_namenow resolves to the name of theAgentin the pipeline, instead of the underlyingchat_generatorortool_invoker.component_typenow resolves tohaystack.components.agents.agent.Agentinstead of the concrete generator class such ashaystack.components.generators.chat.openai.OpenAIChatGenerator.- The error message now includes an additional outer section for the
Agentcomponent.
Example of new error message:
The following component failed to run:
Component name: 'agent'
Component type: 'Agent'
Error: The following component failed to run:
Component name: 'chat_generator'
Component type: 'OpenAIChatGenerator'
Error: Error code: 404 - {'error': {'message': 'The model ``gpt-4.2-mini`` does not exist or you do not have access to it.', 'type': 'invalid_request_error', 'param': None, 'code': 'model_not_found'}}
💙 Big thank you to everyone who contributed to this release!
@agnieszka-m, @Amanbig, @anakin87, @bilgeyucel, @bogdankostic, @davidsbatista, @edwiniac, @julian-risch, @kacperlukawski, @marc-mrt, @OGuggenbuehl, @OiPunk, @sjrl, @srini047, @vblagoje, @yaowubarbara