๐Ÿ’ผ Announcing Haystack Enterprise: Best Practices and Support

Haystack 2.17.0

Check on Github

โญ๏ธ 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 route Documents based on metadata, has been extended to also support routing ByteStream objects.
  • The SentenceWindowRetriever, which retrieves neighboring sentences around relevant Documents to provide full context, is now more flexible. Previously, its source_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 key failed in the result dictionary, which contains a list of files that failed to convert. The documents 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 in HuggingFaceAPIChatGenerator has been updated. Previously, the new finish_reason mapping (introduced in Haystack 2.15.0 release) was only applied when streaming was enabled. When streaming was disabled, the old finish_reason was still returned. This change ensures the updated finish_reason values are consistently returned regardless of streaming mode.

    How to know if you’re affected: If you rely on finish_reason in responses from HuggingFaceAPIChatGenerator 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] or list[ByteStream] based on metadata.
  • Add support for the union type operator | (added in python 3.10) in serialize_type and Pipeline.connect(). These functions support both the typing.Union and | operators and mixtures of them for backwards compatibility.
  • Added ReasoningContent as a new content part to the ChatMessage dataclass. This allows storing model reasoning text and additional metadata in assistant messages. Assistant messages can now include reasoning content using the reasoning parameter in ChatMessage.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 and ImageContent parts of ChatMessage.
  • 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 for issubclass(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.

    1. ChatMessage.from_user with content_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.

    2. 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 neither text nor content_parts are provided. It does not raise an error if text is an empty string.

  • Ensure that the score field in SentenceTransformersSimilarityRanker is returned as a Python float instead of numpy.float32. This prevents potential serialization issues in downstream integrations.

  • Raise a RuntimeError when AsyncPipeline.run is called from within an async context, indicating that run_async should be used instead.

  • Prevented in-place mutation of input Document objects in all Extractor and Classifier components by creating copies with dataclasses.replace before processing.

  • Prevented in-place mutation of input Document objects in all DocumentEmbedder components by creating copies with dataclasses.replace before processing.

  • FileTypeRouter has a new parameter raise_on_failure with default value to False. When set to True, FileNotFoundError is always raised for non-existent files. Previously, this exception was raised only when processing a non-existent file and the meta parameter was provided to run().

  • 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 when top_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