⭐️ Highlights
🖼️ Image support for several model providers
Following the introduction of image support in Haystack 2.16.0, we've expanded this to more model providers in Haystack and Haystack Core integrations.
Now supported: Amazon Bedrock, Anthropic, Azure, Google, Hugging Face API, Meta Llama API, Mistral, Nvidia, Ollama, OpenAI, OpenRouter, STACKIT.
🧩 Extended components
We've improved several components to make them more flexible:
MetadataRouter
, which is used to routeDocuments
based on metadata, has been extended to also support routingByteStream
objects.- The
SentenceWindowRetriever
, which retrieves neighboring sentences around relevantDocuments
to provide full context, is now more flexible. Previously, itssource_id_meta_field
parameter accepted only a single field containing the ID of the original document. It now also accepts a list of fields, so that only documents matching all of the specified meta fields will be retrieved.
⬆️ Upgrade Notes
-
MultiFileConverter
outputs a new keyfailed
in the result dictionary, which contains a list of files that failed to convert. Thedocuments
output is included only if at least one file is successfully converted. Previously,documents
could still be present but empty if a file with a supported MIME type was provided but did not actually exist. -
The
finish_reason
field behavior inHuggingFaceAPIChatGenerator
has been updated. Previously, the newfinish_reason
mapping (introduced in Haystack 2.15.0 release) was only applied when streaming was enabled. When streaming was disabled, the oldfinish_reason
was still returned. This change ensures the updatedfinish_reason
values are consistently returned regardless of streaming mode.How to know if you're affected: If you rely on
finish_reason
in responses fromHuggingFaceAPIChatGenerator
with streaming disabled, you may see different values after this upgrade.What to do: Review the updated mapping:
length
→length
eos_token
→stop
stop_sequence
→stop
- If tool calls are present →
tool_calls
🚀 New Features
- Add support for ByteStream objects in MetadataRouter. It can now be used to route
list[Documents]
orlist[ByteStream]
based on metadata. - Add support for the union type operator
|
(added in python 3.10) inserialize_type
andPipeline.connect()
. These functions support both thetyping.Union
and|
operators and mixtures of them for backwards compatibility. - Added
ReasoningContent
as a new content part to theChatMessage
dataclass. This allows storing model reasoning text and additional metadata in assistant messages. Assistant messages can now include reasoning content using thereasoning
parameter inChatMessage.from_assistant()
. We will progressively update the implementations for Chat Generators with LLMs that support reasoning to use this new content part. - Updated
SentenceWindowRetriever
's source_id_meta_field parameter to also accept a list of strings. If a list of fields are provided, then only documents matching both fields will be retrieved.
⚡️ Enhancement Notes
- Added multimodal support to
HuggingFaceAPIChatGenerator
to enable vision-language model (VLM) usage with images and text. Users can now send both text and images to VLM models through Hugging Face APIs. The implementation follows the HF VLM API format specification and maintains full backward compatibility with text-only messages. - Added serialization/deserialization methods for
TextContent
andImageContent
parts ofChatMessage
. - Made the lazy import error message clearer explaining that the optional dependency is missing.
- Adopted modern type hinting syntax using PEP 585 throughout the codebase. This improves readability and removes unnecessary imports from the
typing
module. - Support subclasses of
ChatMessage
in Agent state schema validation. The validation now checks forissubclass(args[0], ChatMessage)
instead of requiring exact type equality, allowing custom ChatMessage subclasses to be used in the messages field. - The
ToolInvoker
run
method now accepts a list of tools. When provided, this list overrides the tools set in the constructor, allowing you to switch tools at runtime in previously built pipelines.
🐛 Bug Fixes
-
The English and German abbreviation files used by the
SentenceSplitter
are now included in the distribution. They were previously missing due to a config in the.gitignore
file. -
Add encoding format keyword argument to OpenAI client when creating embeddings.
-
Addressed incorrect assumptions in the
ChatMessage
class that raised errors in valid usage scenario.-
ChatMessage.from_user
withcontent_parts
: Previously, at least one text part was required, even though some model providers support messages with only image parts. This restriction has been removed. If a provider has such a limitation, it should now be enforced in the provider's implementation. -
ChatMessage.to_openai_dict_format
: Messages containing multiple text parts weren't supported, despite this being allowed by the OpenAI API. This has now been corrected.
-
-
Improved validation in the
ChatMessage.from_user
class method. The method now raises an error if neithertext
norcontent_parts
are provided. It does not raise an error iftext
is an empty string. -
Ensure that the
score
field inSentenceTransformersSimilarityRanker
is returned as a Pythonfloat
instead ofnumpy.float32
. This prevents potential serialization issues in downstream integrations. -
Raise a
RuntimeError
whenAsyncPipeline.run
is called from within an async context, indicating thatrun_async
should be used instead. -
Prevented in-place mutation of input
Document
objects in allExtractor
andClassifier
components by creating copies withdataclasses.replace
before processing. -
Prevented in-place mutation of input
Document
objects in allDocumentEmbedder
components by creating copies withdataclasses.replace
before processing. -
FileTypeRouter
has a new parameterraise_on_failure
with default value toFalse
. When set toTrue
,FileNotFoundError
is always raised for non-existent files. Previously, this exception was raised only when processing a non-existent file and themeta
parameter was provided torun()
. -
Return a more informative error message when attempting to connect two components and the sender component does not have any OutputSockets defined.
-
Fix tracing context not propagated to tools when running via ToolInvoker.run_async
-
Ensure consistent behavior in
SentenceTransformersDiversityRanker
. Like other rankers, it now returns all documents instead of raising an error whentop_k
exceeds the number of available documents.
💙 Big thank you to everyone who contributed to this release!
@abdokaseb @Amnah199 @anakin87 @bilgeyucel @ChinmayBansal @datbth @davidsbatista @dfokina @LastRemote
@mpangrazzi @RafaelJohn9 @rolshoven @SaraCalla @SaurabhLingam @sjrl