Merge pull request #11893 from deepset-ai/merge-main-into-v3

chore: Merge main into v3
This commit is contained in:
Sebastian Husch Lee
2026-07-07 08:29:37 +02:00
committed by GitHub
148 changed files with 7559 additions and 22109 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
# Pinned by digest for supply-chain integrity. Bump periodically (the OSS-Fuzz
# base-builder is updated frequently with toolchain fixes); resolve a fresh digest with:
# docker buildx imagetools inspect gcr.io/oss-fuzz-base/base-builder-python:latest --format '{{.Manifest.Digest}}'
FROM gcr.io/oss-fuzz-base/base-builder-python@sha256:e0e18dea5d2e4107a4f5d04652e6c278fbea32dc6d6861ee8de29402d0916746
FROM gcr.io/oss-fuzz-base/base-builder-python@sha256:6768b69b56e3c6e654742e5109559fc37601b45d0cfe2e15ecb8e14f0e941a57
COPY . $SRC/haystack
WORKDIR $SRC/haystack
@@ -3,8 +3,8 @@
#
# Requires: VERSION, RUN_URL, HAS_FAILURE, GH_TOKEN, GITHUB_REPOSITORY
# Optional: IS_RC, IS_FIRST_RC, MAJOR_MINOR, GITHUB_URL, PYPI_URL, DOCKER_URL,
# BUMP_VERSION_PR_URL, DC_PIPELINE_TEMPLATES_PR_URL, CUSTOM_NODES_PR_URL,
# DC_PIPELINE_IMAGES_PR_URL (haystack-runtime bump PR), GITHUB_WORKSPACE
# BUMP_VERSION_PR_URL, DC_PIPELINE_TEMPLATES_PR_URL, DC_CUSTOM_NODES_PR_URL,
# HAYSTACK_RUNTIME_PR_URL, GITHUB_WORKSPACE
# Output: slack_payload.json
#
# This script is used in the release.yml workflow to prepare the notification payload
@@ -64,7 +64,7 @@ if [[ "${IS_RC:-}" == "true" ]]; then
PLATFORM_PRS=""
[[ -n "${DC_PIPELINE_TEMPLATES_PR_URL:-}" ]] && PLATFORM_PRS+=$'\n'"- <${DC_PIPELINE_TEMPLATES_PR_URL}|dc-pipeline-templates>"
[[ -n "${DC_CUSTOM_NODES_PR_URL:-}" ]] && PLATFORM_PRS+=$'\n'"- <${DC_CUSTOM_NODES_PR_URL}|deepset-cloud-custom-nodes>"
[[ -n "${DC_PIPELINE_IMAGES_PR_URL:-}" ]] && PLATFORM_PRS+=$'\n'"- <${DC_PIPELINE_IMAGES_PR_URL}|haystack-runtime>"
[[ -n "${HAYSTACK_RUNTIME_PR_URL:-}" ]] && PLATFORM_PRS+=$'\n'"- <${HAYSTACK_RUNTIME_PR_URL}|haystack-runtime>"
if [[ -n "${PLATFORM_PRS}" ]]; then
TXT+=$'\n\n'":factory: *Test PRs opened on Platform:*${PLATFORM_PRS}"
fi
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@521136812280ae7ef256e06045655b9da02793f0 # v1.0.158
uses: anthropics/claude-code-action@6c0083bb7289c31716797a039b6367b3079cc46e # v1.0.162
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY_PR_REVIEWS_PUBLIC_REPOS }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
+1 -1
View File
@@ -57,7 +57,7 @@ jobs:
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@521136812280ae7ef256e06045655b9da02793f0 # v1.0.158
uses: anthropics/claude-code-action@6c0083bb7289c31716797a039b6367b3079cc46e # v1.0.162
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY_PR_REVIEWS_PUBLIC_REPOS }}
additional_permissions: |
+3 -3
View File
@@ -36,10 +36,10 @@ jobs:
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- name: Login to DockerHub
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
uses: docker/login-action@c99871dec2022cc055c062a10cc1a1310835ceb4 # v4.3.0
with:
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
@@ -59,7 +59,7 @@ jobs:
echo "Not a stable version"
fi
- name: Build base images
uses: docker/bake-action@6614cfa25eff9a0b2b2697efb0b6159e7680d584 # v7.2.0
uses: docker/bake-action@d3418bd7d0e9324001bca92fa8ba175ea7e6dc9b # v7.3.0
env:
IMAGE_TAG_SUFFIX: ${{ steps.meta.outputs.version }}
HAYSTACK_VERSION: ${{ steps.meta.outputs.version }}
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
- name: Install Docusaurus and build docs-website
working-directory: docs-website
run: |
npm ci --ignore-scripts
npm install --ignore-scripts
npm rebuild sharp
npm run build
+3 -2
View File
@@ -57,7 +57,8 @@ jobs:
id: parse-validate
env:
GH_TOKEN: ${{ github.token }}
run: .github/utils/parse_validate_version.sh "${{ inputs.version }}"
VERSION: ${{ inputs.version }}
run: .github/utils/parse_validate_version.sh "$VERSION"
branch-off:
needs: ["parse-validate-version"]
@@ -290,7 +291,7 @@ jobs:
BUMP_VERSION_PR_URL: ${{ needs.branch-off.outputs.bump_version_pr_url }}
DC_PIPELINE_TEMPLATES_PR_URL: ${{ needs.bump-dc-pipeline-templates.outputs.pr_url }}
DC_CUSTOM_NODES_PR_URL: ${{ needs.bump-deepset-cloud-custom-nodes.outputs.pr_url }}
DC_PIPELINE_IMAGES_PR_URL: ${{ needs.bump-haystack-runtime.outputs.pr_url }}
HAYSTACK_RUNTIME_PR_URL: ${{ needs.bump-haystack-runtime.outputs.pr_url }}
run: .github/utils/prepare_release_notification.sh
- name: Send release notification to Slack
+1 -1
View File
@@ -61,6 +61,6 @@ jobs:
retention-days: 5
- name: Upload to code-scanning
uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2
uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
with:
sarif_file: results.sarif
+2 -2
View File
@@ -148,7 +148,7 @@ jobs:
- name: Run
run: hatch run test:unit
- uses: actions/cache/save@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
- uses: actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
id: cache
if: matrix.os == 'macos-latest'
with:
@@ -265,7 +265,7 @@ jobs:
pip install hatch==${{ env.HATCH_VERSION }} --uploaded-prior-to=P1D
echo "env=$(hatch env find test)" >> "$GITHUB_OUTPUT"
- uses: actions/cache/restore@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
- uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
id: cache
with:
path: ${{ steps.hatch.outputs.env }}
@@ -0,0 +1,99 @@
name: Update Platform Components Table
on:
push:
branches:
- main
workflow_dispatch:
concurrency:
group: update-platform-components
cancel-in-progress: false
env:
PYTHON_VERSION: "3.11"
OUTPUT_FILE: docs-website/docs/overview/platform-components.mdx
permissions:
contents: read
jobs:
update:
runs-on: ubuntu-slim
steps:
- name: Checkout deepset-ai/haystack
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
token: ${{ secrets.HAYSTACK_BOT_TOKEN }}
# Full history so git diff against HEAD works correctly
fetch-depth: 0
- name: Checkout deepset-ai/haystack-core-integrations
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: deepset-ai/haystack-core-integrations
path: haystack-core-integrations
fetch-depth: 1
sparse-checkout: integrations
sparse-checkout-cone-mode: true
- name: Checkout platform repo (sparse — schema file only)
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
repository: ${{ secrets.SCHEMA_REPO }}
token: ${{ secrets.PLATFORM_REPO_PAT }}
path: platform-repo
sparse-checkout: |
${{ secrets.SCHEMA_REPO_PATH }}
sparse-checkout-cone-mode: false
- name: Set up Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: Generate platform components table
run: |
python scripts/generate_platform_components_table.py \
--haystack-src . \
--integrations-src ./haystack-core-integrations \
--schema ./platform-repo/${{ secrets.SCHEMA_REPO_PATH }} \
--output ./${{ env.OUTPUT_FILE }}
- name: Compute PR body
id: pr_body
run: |
FILE="${{ env.OUTPUT_FILE }}"
if git ls-files --error-unmatch "$FILE" 2>/dev/null; then
ADDED=$(git diff HEAD -- "$FILE" | grep -cE '^\+\| `' || true)
REMOVED=$(git diff HEAD -- "$FILE" | grep -cE '^\-\| `' || true)
SUMMARY="Component rows changed: **+${ADDED}** added, **-${REMOVED}** removed."
else
SUMMARY="Initial generation of the platform components table."
fi
{
echo "body<<EOF"
echo "## Platform Components Table Update"
echo ""
echo "${SUMMARY}"
echo ""
echo "_Auto-generated by the [update-platform-components](https://github.com/deepset-ai/haystack/actions/workflows/update-platform-components.yml) workflow._"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Open or update pull request
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with:
token: ${{ secrets.HAYSTACK_BOT_TOKEN }}
commit-message: "chore: update platform components table"
branch: chore/update-platform-components
base: main
title: "chore: update platform components table"
add-paths: |
${{ env.OUTPUT_FILE }}
body: ${{ steps.pr_body.outputs.body }}
labels: |
documentation
ignore-for-release-notes
+1
View File
@@ -9,6 +9,7 @@
node_modules
.yarn
package-lock.json
.eslintcache
+7 -1
View File
@@ -76,11 +76,17 @@ export OPENAI_API_KEY=<your-openai-key>
export SERPERDEV_API_KEY=<your-serperdev-key>
```
The examples on this page use SerperDev web search component that have moved to the `serperdev-haystack` package. Install it to run the examples:
```shell
pip install serperdev-haystack
```
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.generators.utils import print_streaming_chunk
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool
@@ -31,6 +31,12 @@ Wrapping an agent inside a `@tool` function gives you full control over what the
This approach works better with smaller LLMs because the tool has a clean, minimal signature.
The coordinator only needs to provide a query string - all the `ChatMessage` construction and result unpacking is hidden inside the function.
The examples on this page use SerperDev web search component that have moved to the `serperdev-haystack` package. Install it to run the examples:
```shell
pip install serperdev-haystack
```
```python
from typing import Annotated
from haystack.components.agents import Agent
@@ -38,7 +44,7 @@ from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.generators.utils import print_streaming_chunk
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool, tool
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
@@ -198,7 +204,7 @@ components:
exclude_subdomains: false
search_params: {}
top_k: 3
type: haystack.components.websearch.serper_dev.SerperDevWebSearch
type: haystack_integrations.components.websearch.serperdev.websearch.SerperDevWebSearch
description: Search the web for current information on any topic
inputs_from_state: null
name: web_search
@@ -254,7 +260,7 @@ from haystack.components.converters import HTMLToDocument
from haystack.components.fetchers.link_content import LinkContentFetcher
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.generators.utils import print_streaming_chunk
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool, tool
from haystack.utils import Secret
+9 -1
View File
@@ -45,9 +45,17 @@ Returns a list of Documents ranked by their similarity to the given query.
Components that use heavy resources, like LLMs or embedding models, have a `warm_up()` method that loads the necessary resources (such as models) into memory. This method is automatically called the first time the component runs, so you can use components directly without explicitly calling `warm_up()`:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
doc = Document(content="I love pizza!")
doc_embedder = SentenceTransformersDocumentEmbedder()
@@ -19,12 +19,20 @@ With this decorator, the `to_dict` and `from_dict` serialization is optional, as
The custom HybridRetriever example SuperComponent below turns your query into embeddings, then runs both a BM25 search and an embedding-based search at the same time. It finally merges those two result sets and returns the combined documents.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
# pip install haystack-ai datasets "sentence-transformers>=3.0.0"
# pip install haystack-ai datasets sentence-transformers-haystack
from haystack import Document, Pipeline, super_component
from haystack.components.joiners import DocumentJoiner
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
)
from haystack.components.retrievers import (
InMemoryBM25Retriever,
InMemoryEmbeddingRetriever,
@@ -50,12 +50,18 @@ You can find more details in our [API Reference](/reference/pipeline-api#asyncpi
## Example
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
import asyncio
from haystack import AsyncPipeline, Document
from haystack.components.builders import ChatPromptBuilder
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -75,7 +81,6 @@ documents = [
]
docs_embedder = SentenceTransformersDocumentEmbedder()
docs_embedder.warm_up()
document_store = InMemoryDocumentStore()
document_store.write_documents(docs_embedder.run(documents=documents)["documents"])
@@ -26,10 +26,18 @@ For each component you want to use in your pipeline, you must know the names of
Import all the dependencies, like pipeline, documents, Document Store, and all the components you want to use in your pipeline.
For example, to create a semantic document search pipelines, you need the `Document` object, the pipeline, the Document Store, Embedders, and a Retriever:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
)
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
```
@@ -25,6 +25,12 @@ It stores documents alongside dense vector embeddings in a native `VECTOR` colum
pip install oracle-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Connection
`OracleDocumentStore` connects to Oracle using the `OracleConnectionConfig` dataclass, which supports two connection modes:
@@ -108,7 +114,7 @@ document_store = OracleDocumentStore(
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -146,7 +152,6 @@ documents = [
doc_embedder = SentenceTransformersDocumentEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
)
doc_embedder.warm_up()
embedded_docs = doc_embedder.run(documents)["documents"]
document_store.write_documents(embedded_docs, policy=DuplicatePolicy.OVERWRITE)
@@ -27,6 +27,12 @@ description: "Use Supabase as a document store in Haystack, with vector search (
pip install supabase-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## SupabasePgvectorDocumentStore
`SupabasePgvectorDocumentStore` is a thin wrapper around [`PgvectorDocumentStore`](./pgvectordocumentstore.mdx) with Supabase-specific defaults:
@@ -70,7 +76,7 @@ To learn more about the initialization parameters, see the [API docs](/reference
```python
from haystack import Document, Pipeline
from haystack.document_stores.types.policy import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -28,6 +28,12 @@ You can install the Valkey Haystack integration with:
pip install valkey-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Initialization
To use Valkey as your data storage for Haystack pipelines, you need a Valkey server with the search module running. Initialize a `ValkeyDocumentStore` like this:
@@ -65,7 +71,9 @@ To write documents to your `ValkeyDocumentStore`, create an indexing pipeline or
from haystack import Pipeline
from haystack.components.converters import MarkdownToDocument
from haystack.components.writers import DocumentWriter
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
from haystack.components.preprocessors import DocumentSplitter
from haystack_integrations.document_stores.valkey import ValkeyDocumentStore
@@ -99,7 +107,9 @@ Once documents are in your `ValkeyDocumentStore`, you can use [`ValkeyEmbeddingR
from haystack import Pipeline
from haystack.utils import Secret
from haystack.dataclasses import ChatMessage
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
)
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack_integrations.document_stores.valkey import ValkeyDocumentStore
@@ -28,6 +28,12 @@ Many embedding retrievers generalize poorly to new, unseen domains. This approac
First, prepare all the components that you would need:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
import os
from numpy import array, mean
@@ -37,7 +43,9 @@ from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.builders import ChatPromptBuilder
from haystack import component, Document
from haystack.components.converters import OutputAdapter
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
from haystack.dataclasses import ChatMessage
# We need to ensure we have the OpenAI API key in our environment variables
@@ -69,7 +77,6 @@ adapter = OutputAdapter(
embedder = SentenceTransformersDocumentEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
)
embedder.warm_up()
# Adding one custom component that returns one, "average" embedding from multiple (hypothetical) document embeddings
+19 -9
View File
@@ -88,11 +88,19 @@ print(results["llm"]["replies"])
</TabItem>
<TabItem value="huggingface" label="Hugging Face">
[HuggingFaceAPIChatGenerator](../pipeline-components/generators/huggingfaceapichatgenerator.mdx) is included in the `haystack-ai` package. You can get a [free Hugging Face token](https://huggingface.co/settings/tokens) to use the Serverless Inference API.
[HuggingFaceAPIChatGenerator](../pipeline-components/generators/huggingfaceapichatgenerator.mdx) is included in the `huggingface-api-haystack` package. You can get a [free Hugging Face token](https://huggingface.co/settings/tokens) to use the Serverless Inference API.
The examples on this page use the Hugging Face API components and the SerperDev web search component, which have moved to the `huggingface-api-haystack` and `serperdev-haystack` packages. Install them to run the examples:
```shell
pip install huggingface-api-haystack serperdev-haystack
```
```python
from haystack import Pipeline, Document
from haystack.components.generators.chat import HuggingFaceAPIChatGenerator
from haystack_integrations.components.generators.huggingface_api import (
HuggingFaceAPIChatGenerator,
)
from haystack.components.retrievers import InMemoryBM25Retriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.builders import ChatPromptBuilder
@@ -389,7 +397,7 @@ from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
search_tool = ComponentTool(component=SerperDevWebSearch())
@@ -411,14 +419,16 @@ print(result["last_message"].text)
</TabItem>
<TabItem value="huggingface" label="Hugging Face">
[HuggingFaceAPIChatGenerator](../pipeline-components/generators/huggingfaceapichatgenerator.mdx) is included in the `haystack-ai` package. You can get a [free Hugging Face token](https://huggingface.co/settings/tokens) to use the Serverless Inference API.
[HuggingFaceAPIChatGenerator](../pipeline-components/generators/huggingfaceapichatgenerator.mdx) is included in the `huggingface-api-haystack` package. You can get a [free Hugging Face token](https://huggingface.co/settings/tokens) to use the Serverless Inference API.
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import HuggingFaceAPIChatGenerator
from haystack_integrations.components.generators.huggingface_api import (
HuggingFaceAPIChatGenerator,
)
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
search_tool = ComponentTool(component=SerperDevWebSearch())
@@ -454,7 +464,7 @@ from haystack.components.agents import Agent
from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
search_tool = ComponentTool(component=SerperDevWebSearch())
@@ -492,7 +502,7 @@ from haystack_integrations.components.generators.amazon_bedrock import (
)
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
os.environ["AWS_ACCESS_KEY_ID"] = "YOUR_AWS_ACCESS_KEY_ID"
os.environ["AWS_SECRET_ACCESS_KEY"] = "YOUR_AWS_SECRET_ACCESS_KEY"
@@ -531,7 +541,7 @@ from haystack_integrations.components.generators.google_genai import (
)
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
search_tool = ComponentTool(component=SerperDevWebSearch())
@@ -459,11 +459,11 @@ Both frameworks offer in-memory stores for prototyping and a wide range of produ
<div className="code-comparison">
<div className="code-comparison__column">
<CodeBlock language="python" title="Haystack">{`# pip install haystack-ai sentence-transformers
<CodeBlock language="python" title="Haystack">{`# pip install haystack-ai sentence-transformers-haystack
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
# Embed and write documents to the document store
document_store = InMemoryDocumentStore()
@@ -505,7 +505,7 @@ vectorstore.add_documents([
<div className="code-comparison">
<div className="code-comparison__column">
<CodeBlock language="python" title="Haystack">{`from haystack import Pipeline
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.components.builders import ChatPromptBuilder
from haystack.dataclasses import ChatMessage
@@ -0,0 +1,514 @@
---
title: "Haystack Enterprise Components"
id: platform-components
slug: "/platform-components"
description: "A complete list of Haystack components available on the Haystack Enterprise Platform, grouped by integration partner."
---
# Haystack Enterprise Components
The Haystack Enterprise Platform currently supports **224 components** and **55 integrations**. The following table lists them grouped by integration partner.
## Core Components
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [Agent](https://docs.haystack.deepset.ai/docs/agent) | Component | ✅ Available |
| [AnswerBuilder](https://docs.haystack.deepset.ai/docs/answerbuilder) | Builder | ✅ Available |
| [AnswerJoiner](https://docs.haystack.deepset.ai/docs/answerjoiner) | Joiner | ✅ Available |
| [AutoMergingRetriever](https://docs.haystack.deepset.ai/docs/automergingretriever) | Retriever | ✅ Available |
| [AzureOCRDocumentConverter](https://docs.haystack.deepset.ai/docs/azureocrdocumentconverter) | Converter | ✅ Available |
| [AzureOpenAIChatGenerator](https://docs.haystack.deepset.ai/docs/azureopenaichatgenerator) | Generator | ✅ Available |
| [AzureOpenAIDocumentEmbedder](https://docs.haystack.deepset.ai/docs/azureopenaidocumentembedder) | Embedder | ✅ Available |
| [AzureOpenAIResponsesChatGenerator](https://docs.haystack.deepset.ai/docs/azureopenairesponseschatgenerator) | Generator | ✅ Available |
| [AzureOpenAITextEmbedder](https://docs.haystack.deepset.ai/docs/azureopenaitextembedder) | Embedder | ✅ Available |
| [BranchJoiner](https://docs.haystack.deepset.ai/docs/branchjoiner) | Joiner | ✅ Available |
| [CacheChecker](https://docs.haystack.deepset.ai/docs/cachechecker) | Component | ✅ Available |
| [ChatPromptBuilder](https://docs.haystack.deepset.ai/docs/chatpromptbuilder) | Builder | ✅ Available |
| [ConditionalRouter](https://docs.haystack.deepset.ai/docs/conditionalrouter) | Router | ✅ Available |
| [CSVDocumentCleaner](https://docs.haystack.deepset.ai/docs/csvdocumentcleaner) | Preprocessor | ✅ Available |
| [CSVDocumentSplitter](https://docs.haystack.deepset.ai/docs/csvdocumentsplitter) | Preprocessor | ✅ Available |
| [CSVToDocument](https://docs.haystack.deepset.ai/docs/csvtodocument) | Converter | ✅ Available |
| [DocumentCleaner](https://docs.haystack.deepset.ai/docs/documentcleaner) | Preprocessor | ✅ Available |
| [DocumentJoiner](https://docs.haystack.deepset.ai/docs/documentjoiner) | Joiner | ✅ Available |
| [DocumentLanguageClassifier](https://docs.haystack.deepset.ai/docs/documentlanguageclassifier) | Classifier | ✅ Available |
| [DocumentLengthRouter](https://docs.haystack.deepset.ai/docs/documentlengthrouter) | Router | ✅ Available |
| [DocumentPreprocessor](https://docs.haystack.deepset.ai/docs/documentpreprocessor) | Preprocessor | ✅ Available |
| [DocumentSplitter](https://docs.haystack.deepset.ai/docs/documentsplitter) | Preprocessor | ✅ Available |
| [DocumentToImageContent](https://docs.haystack.deepset.ai/docs/documenttoimagecontent) | Converter | ✅ Available |
| [DocumentTypeRouter](https://docs.haystack.deepset.ai/docs/documenttyperouter) | Router | ✅ Available |
| [DocumentWriter](https://docs.haystack.deepset.ai/docs/documentwriter) | Writer | ✅ Available |
| [DOCXToDocument](https://docs.haystack.deepset.ai/docs/docxtodocument) | Converter | ✅ Available |
| [EmbeddingBasedDocumentSplitter](https://docs.haystack.deepset.ai/docs/embeddingbaseddocumentsplitter) | Preprocessor | ✅ Available |
| [ExtractiveReader](https://docs.haystack.deepset.ai/docs/extractivereader) | Reader | ✅ Available |
| [FallbackChatGenerator](https://docs.haystack.deepset.ai/docs/fallbackchatgenerator) | Generator | ✅ Available |
| [FileToFileContent](https://docs.haystack.deepset.ai/docs/filetofilecontent) | Converter | ✅ Available |
| [FileTypeRouter](https://docs.haystack.deepset.ai/docs/filetyperouter) | Router | ✅ Available |
| [FilterRetriever](https://docs.haystack.deepset.ai/docs/filterretriever) | Retriever | ✅ Available |
| [HierarchicalDocumentSplitter](https://docs.haystack.deepset.ai/docs/hierarchicaldocumentsplitter) | Preprocessor | ✅ Available |
| [HTMLToDocument](https://docs.haystack.deepset.ai/docs/htmltodocument) | Converter | ✅ Available |
| [HuggingFaceAPIChatGenerator](https://docs.haystack.deepset.ai/docs/huggingfaceapichatgenerator) | Generator | ✅ Available |
| [HuggingFaceAPIDocumentEmbedder](https://docs.haystack.deepset.ai/docs/huggingfaceapidocumentembedder) | Embedder | ✅ Available |
| [HuggingFaceAPITextEmbedder](https://docs.haystack.deepset.ai/docs/huggingfaceapitextembedder) | Embedder | ✅ Available |
| [HuggingFaceLocalChatGenerator](https://docs.haystack.deepset.ai/docs/huggingfacelocalchatgenerator) | Generator | ✅ Available |
| [HuggingFaceTEIRanker](https://docs.haystack.deepset.ai/docs/huggingfaceteiranker) | Ranker | ✅ Available |
| [ImageFileToDocument](https://docs.haystack.deepset.ai/docs/imagefiletodocument) | Converter | ✅ Available |
| [ImageFileToImageContent](https://docs.haystack.deepset.ai/docs/imagefiletoimagecontent) | Converter | ✅ Available |
| [JSONConverter](https://docs.haystack.deepset.ai/docs/jsonconverter) | Converter | ✅ Available |
| [JsonSchemaValidator](https://docs.haystack.deepset.ai/docs/jsonschemavalidator) | Validator | ✅ Available |
| [LinkContentFetcher](https://docs.haystack.deepset.ai/docs/linkcontentfetcher) | Fetcher | ✅ Available |
| [ListJoiner](https://docs.haystack.deepset.ai/docs/listjoiner) | Joiner | ✅ Available |
| [LLMDocumentContentExtractor](https://docs.haystack.deepset.ai/docs/llmdocumentcontentextractor) | Extractor | ✅ Available |
| [LLMMessagesRouter](https://docs.haystack.deepset.ai/docs/llmmessagesrouter) | Router | ✅ Available |
| [LLMMetadataExtractor](https://docs.haystack.deepset.ai/docs/llmmetadataextractor) | Extractor | ✅ Available |
| [LLMRanker](https://docs.haystack.deepset.ai/docs/llmranker) | Ranker | ✅ Available |
| [LostInTheMiddleRanker](https://docs.haystack.deepset.ai/docs/lostinthemiddleranker) | Ranker | ✅ Available |
| [MarkdownHeaderSplitter](https://docs.haystack.deepset.ai/docs/markdownheadersplitter) | Preprocessor | ✅ Available |
| [MarkdownToDocument](https://docs.haystack.deepset.ai/docs/markdowntodocument) | Converter | ✅ Available |
| [MetadataRouter](https://docs.haystack.deepset.ai/docs/metadatarouter) | Router | ✅ Available |
| [MetaFieldGroupingRanker](https://docs.haystack.deepset.ai/docs/metafieldgroupingranker) | Ranker | ✅ Available |
| [MetaFieldRanker](https://docs.haystack.deepset.ai/docs/metafieldranker) | Ranker | ✅ Available |
| [MSGToDocument](https://docs.haystack.deepset.ai/docs/msgtodocument) | Converter | ✅ Available |
| [MultiFileConverter](https://docs.haystack.deepset.ai/docs/multifileconverter) | Converter | ✅ Available |
| [MultiQueryEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/multiqueryembeddingretriever) | Retriever | ✅ Available |
| [MultiQueryTextRetriever](https://docs.haystack.deepset.ai/docs/multiquerytextretriever) | Retriever | ✅ Available |
| [MultiRetriever](https://docs.haystack.deepset.ai/docs/multiretriever) | Retriever | ✅ Available |
| [NamedEntityExtractor](https://docs.haystack.deepset.ai/docs/namedentityextractor) | Extractor | ✅ Available |
| [OpenAIChatGenerator](https://docs.haystack.deepset.ai/docs/openaichatgenerator) | Generator | ✅ Available |
| [OpenAIDocumentEmbedder](https://docs.haystack.deepset.ai/docs/openaidocumentembedder) | Embedder | ✅ Available |
| [OpenAIResponsesChatGenerator](https://docs.haystack.deepset.ai/docs/openairesponseschatgenerator) | Generator | ✅ Available |
| [OpenAITextEmbedder](https://docs.haystack.deepset.ai/docs/openaitextembedder) | Embedder | ✅ Available |
| [OpenAPIConnector](https://docs.haystack.deepset.ai/docs/openapiconnector) | Connector | ✅ Available |
| [OpenAPIServiceConnector](https://docs.haystack.deepset.ai/docs/openapiserviceconnector) | Connector | ✅ Available |
| [OpenAPIServiceToFunctions](https://docs.haystack.deepset.ai/docs/openapiservicetofunctions) | Converter | ✅ Available |
| [OutputAdapter](https://docs.haystack.deepset.ai/docs/outputadapter) | Converter | ✅ Available |
| [PDFMinerToDocument](https://docs.haystack.deepset.ai/docs/pdfminertodocument) | Converter | ✅ Available |
| [PDFToImageContent](https://docs.haystack.deepset.ai/docs/pdftoimagecontent) | Converter | ✅ Available |
| [PPTXToDocument](https://docs.haystack.deepset.ai/docs/pptxtodocument) | Converter | ✅ Available |
| [PromptBuilder](https://docs.haystack.deepset.ai/docs/promptbuilder) | Builder | ✅ Available |
| [PyPDFToDocument](https://docs.haystack.deepset.ai/docs/pypdftodocument) | Converter | ✅ Available |
| [PythonCodeSplitter](https://docs.haystack.deepset.ai/docs/pythoncodesplitter) | Preprocessor | ✅ Available |
| [QueryExpander](https://docs.haystack.deepset.ai/docs/queryexpander) | Component | ✅ Available |
| [RecursiveDocumentSplitter](https://docs.haystack.deepset.ai/docs/recursivesplitter) | Preprocessor | ✅ Available |
| [RegexTextExtractor](https://docs.haystack.deepset.ai/docs/regextextextractor) | Extractor | ✅ Available |
| [RemoteWhisperTranscriber](https://docs.haystack.deepset.ai/docs/remotewhispertranscriber) | Audio | ✅ Available |
| [SearchApiWebSearch](https://docs.haystack.deepset.ai/docs/searchapiwebsearch) | Component | ✅ Available |
| [SentenceTransformersDiversityRanker](https://docs.haystack.deepset.ai/docs/sentencetransformersdiversityranker) | Ranker | ✅ Available |
| [SentenceTransformersDocumentEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformersdocumentembedder) | Embedder | ✅ Available |
| [SentenceTransformersDocumentImageEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformersdocumentimageembedder) | Embedder | ✅ Available |
| [SentenceTransformersSimilarityRanker](https://docs.haystack.deepset.ai/docs/sentencetransformerssimilarityranker) | Ranker | ✅ Available |
| [SentenceTransformersSparseDocumentEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformerssparsedocumentembedder) | Embedder | ✅ Available |
| [SentenceTransformersSparseTextEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformerssparsetextembedder) | Embedder | ✅ Available |
| [SentenceTransformersTextEmbedder](https://docs.haystack.deepset.ai/docs/sentencetransformerstextembedder) | Embedder | ✅ Available |
| [SentenceWindowRetriever](https://docs.haystack.deepset.ai/docs/sentencewindowretriever) | Retriever | ✅ Available |
| [SerperDevWebSearch](https://docs.haystack.deepset.ai/docs/serperdevwebsearch) | Component | ✅ Available |
| [StringJoiner](https://docs.haystack.deepset.ai/docs/stringjoiner) | Joiner | ✅ Available |
| [TextCleaner](https://docs.haystack.deepset.ai/docs/textcleaner) | Preprocessor | ✅ Available |
| [TextEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/textembeddingretriever) | Retriever | ✅ Available |
| [TextFileToDocument](https://docs.haystack.deepset.ai/docs/textfiletodocument) | Converter | ✅ Available |
| [TextLanguageRouter](https://docs.haystack.deepset.ai/docs/textlanguagerouter) | Router | ✅ Available |
| [TikaDocumentConverter](https://docs.haystack.deepset.ai/docs/tikadocumentconverter) | Converter | ✅ Available |
| [ToolInvoker](https://docs.haystack.deepset.ai/docs/toolinvoker) | Component | ✅ Available |
| [TopPSampler](https://docs.haystack.deepset.ai/docs/toppsampler) | Sampler | ✅ Available |
| [TransformersSimilarityRanker](https://docs.haystack.deepset.ai/docs/transformerssimilarityranker) | Ranker | ✅ Available |
| [TransformersTextRouter](https://docs.haystack.deepset.ai/docs/transformerstextrouter) | Router | ✅ Available |
| [TransformersZeroShotDocumentClassifier](https://docs.haystack.deepset.ai/docs/transformerszeroshotdocumentclassifier) | Classifier | ✅ Available |
| [TransformersZeroShotTextRouter](https://docs.haystack.deepset.ai/docs/transformerszeroshottextrouter) | Router | ✅ Available |
| [XLSXToDocument](https://docs.haystack.deepset.ai/docs/xlsxtodocument) | Converter | ✅ Available |
## AIML API
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AIMLAPIChatGenerator](https://docs.haystack.deepset.ai/docs/aimllapichatgenerator) | Generator | ✅ Available |
## AlloyDB
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AlloyDBEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/alloydbembeddingretriever) | Retriever | ✅ Available |
| [AlloyDBKeywordRetriever](https://docs.haystack.deepset.ai/docs/alloydbkeywordretriever) | Retriever | ✅ Available |
## Amazon Bedrock
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AmazonBedrockChatGenerator](https://docs.haystack.deepset.ai/docs/amazonbedrockchatgenerator) | Generator | ✅ Available |
| [AmazonBedrockDocumentEmbedder](https://docs.haystack.deepset.ai/docs/amazonbedrockdocumentembedder) | Embedder | ✅ Available |
| [AmazonBedrockDocumentImageEmbedder](https://docs.haystack.deepset.ai/docs/amazonbedrockdocumentimageembedder) | Embedder | ✅ Available |
| [AmazonBedrockRanker](https://docs.haystack.deepset.ai/docs/amazonbedrockranker) | Ranker | ✅ Available |
| [AmazonBedrockTextEmbedder](https://docs.haystack.deepset.ai/docs/amazonbedrocktextembedder) | Embedder | ✅ Available |
## Amazon S3
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [S3Downloader](https://docs.haystack.deepset.ai/docs/s3downloader) | Component | ✅ Available |
## Amazon Textract
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AmazonTextractConverter](https://docs.haystack.deepset.ai/docs/amazontextractconverter) | Converter | ✅ Available |
## Anthropic
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AnthropicChatGenerator](https://docs.haystack.deepset.ai/docs/anthropicchatgenerator) | Generator | ✅ Available |
| [AnthropicFoundryChatGenerator](https://docs.haystack.deepset.ai/docs/anthropicfoundrychatgenerator) | Generator | ✅ Available |
| [AnthropicVertexChatGenerator](https://docs.haystack.deepset.ai/docs/anthropicvertexchatgenerator) | Generator | ✅ Available |
## ArcadeDB
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [ArcadeDBEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/arcadedbembeddingretriever) | Retriever | ✅ Available |
## Astra
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AstraEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/astraretriever) | Retriever | ✅ Available |
## Azure AI Search
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AzureAISearchBM25Retriever](https://docs.haystack.deepset.ai/docs/azureaisearchbm25retriever) | Retriever | ✅ Available |
| [AzureAISearchEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/azureaisearchembeddingretriever) | Retriever | ✅ Available |
| [AzureAISearchHybridRetriever](https://docs.haystack.deepset.ai/docs/azureaisearchhybridretriever) | Retriever | ✅ Available |
## Azure Document Intelligence
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [AzureDocumentIntelligenceConverter](https://docs.haystack.deepset.ai/docs/azuredocumentintelligenceconverter) | Converter | ✅ Available |
## Brave
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [BraveWebSearch](https://docs.haystack.deepset.ai/docs/bravewebsearch) | Component | ✅ Available |
## Chroma
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [ChromaEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/chromaembeddingretriever) | Retriever | ✅ Available |
| [ChromaQueryTextRetriever](https://docs.haystack.deepset.ai/docs/chromaqueryretriever) | Retriever | ✅ Available |
## Cohere
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [CohereChatGenerator](https://docs.haystack.deepset.ai/docs/coherechatgenerator) | Generator | ✅ Available |
| [CohereDocumentEmbedder](https://docs.haystack.deepset.ai/docs/coheredocumentembedder) | Embedder | ✅ Available |
| [CohereRanker](https://docs.haystack.deepset.ai/docs/cohereranker) | Ranker | ✅ Available |
| [CohereTextEmbedder](https://docs.haystack.deepset.ai/docs/coheretextembedder) | Embedder | ✅ Available |
## Docling
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [DoclingConverter](https://docs.haystack.deepset.ai/docs/doclingconverter) | Converter | ✅ Available |
| [DoclingServeConverter](https://docs.haystack.deepset.ai/docs/doclingserveconverter) | Converter | ✅ Available |
## Elasticsearch
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [ElasticsearchBM25Retriever](https://docs.haystack.deepset.ai/docs/elasticsearchbm25retriever) | Retriever | ✅ Available |
| [ElasticsearchEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/elasticsearchembeddingretriever) | Retriever | ✅ Available |
| [ElasticsearchHybridRetriever](https://docs.haystack.deepset.ai/docs/elasticsearchhybridretriever) | Retriever | ✅ Available |
| [ElasticsearchSQLRetriever](https://docs.haystack.deepset.ai/docs/elasticsearchsqlretriever) | Retriever | ✅ Available |
## FalkorDB
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [FalkorDBCypherRetriever](https://docs.haystack.deepset.ai/docs/falkordbcypherretriever) | Retriever | ✅ Available |
| [FalkorDBEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/falkordbembeddingretriever) | Retriever | ✅ Available |
## FastEmbed
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [FastembedDocumentEmbedder](https://docs.haystack.deepset.ai/docs/fastembeddocumentembedder) | Embedder | ✅ Available |
| [FastembedRanker](https://docs.haystack.deepset.ai/docs/fastembedranker) | Ranker | ✅ Available |
| [FastembedSparseDocumentEmbedder](https://docs.haystack.deepset.ai/docs/fastembedsparsedocumentembedder) | Embedder | ✅ Available |
| [FastembedSparseTextEmbedder](https://docs.haystack.deepset.ai/docs/fastembedsparsetextembedder) | Embedder | ✅ Available |
| [FastembedTextEmbedder](https://docs.haystack.deepset.ai/docs/fastembedtextembedder) | Embedder | ✅ Available |
## Firecrawl
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [FirecrawlCrawler](https://docs.haystack.deepset.ai/docs/firecrawlcrawler) | Fetcher | ✅ Available |
| [FirecrawlWebSearch](https://docs.haystack.deepset.ai/docs/firecrawlwebsearch) | Component | ✅ Available |
## GitHub
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [GitHubFileEditor](https://docs.haystack.deepset.ai/docs/githubfileeditor) | Connector | ✅ Available |
| [GitHubIssueCommenter](https://docs.haystack.deepset.ai/docs/githubissuecommenter) | Connector | ✅ Available |
| [GitHubIssueViewer](https://docs.haystack.deepset.ai/docs/githubissueviewer) | Connector | ✅ Available |
| [GitHubPRCreator](https://docs.haystack.deepset.ai/docs/githubprcreator) | Connector | ✅ Available |
| [GitHubRepoForker](https://docs.haystack.deepset.ai/docs/githubrepoforker) | Connector | ✅ Available |
| [GitHubRepoViewer](https://docs.haystack.deepset.ai/docs/githubrepoviewer) | Connector | ✅ Available |
## Google Generative AI
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [GoogleGenAIChatGenerator](https://docs.haystack.deepset.ai/docs/googlegenaichatgenerator) | Generator | ✅ Available |
| [GoogleGenAIDocumentEmbedder](https://docs.haystack.deepset.ai/docs/googlegenaidocumentembedder) | Embedder | ✅ Available |
| [GoogleGenAITextEmbedder](https://docs.haystack.deepset.ai/docs/googlegenaitextembedder) | Embedder | ✅ Available |
## Hugging Face API
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [HuggingFaceAPIChatGenerator](https://docs.haystack.deepset.ai/docs/huggingfaceapichatgenerator) | Generator | ✅ Available |
| [HuggingFaceAPIDocumentEmbedder](https://docs.haystack.deepset.ai/docs/huggingfaceapidocumentembedder) | Embedder | ✅ Available |
| [HuggingFaceAPITextEmbedder](https://docs.haystack.deepset.ai/docs/huggingfaceapitextembedder) | Embedder | ✅ Available |
| [HuggingFaceTEIRanker](https://docs.haystack.deepset.ai/docs/huggingfaceteiranker) | Ranker | ✅ Available |
## Jina AI
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [JinaDocumentEmbedder](https://docs.haystack.deepset.ai/docs/jinadocumentembedder) | Embedder | ✅ Available |
| [JinaRanker](https://docs.haystack.deepset.ai/docs/jinaranker) | Ranker | ✅ Available |
| [JinaReaderConnector](https://docs.haystack.deepset.ai/docs/jinareaderconnector) | Connector | ✅ Available |
| [JinaTextEmbedder](https://docs.haystack.deepset.ai/docs/jinatextembedder) | Embedder | ✅ Available |
## Langfuse
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [LangfuseConnector](https://docs.haystack.deepset.ai/docs/langfuseconnector) | Connector | ✅ Available |
## Lara
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [LaraDocumentTranslator](https://docs.haystack.deepset.ai/docs/laradocumenttranslator) | Component | ✅ Available |
## LiteLLM
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [LiteLLMChatGenerator](https://docs.haystack.deepset.ai/docs/litellmchatgenerator) | Generator | ✅ Available |
## Llama Stack
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [LlamaStackChatGenerator](https://docs.haystack.deepset.ai/docs/llamastackchatgenerator) | Generator | ✅ Available |
## Llama.cpp
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [LlamaCppChatGenerator](https://docs.haystack.deepset.ai/docs/llamacppchatgenerator) | Generator | ✅ Available |
## MarkItDown
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [MarkItDownConverter](https://docs.haystack.deepset.ai/docs/markitdownconverter) | Converter | ✅ Available |
## Mem0
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [Mem0MemoryRetriever](https://docs.haystack.deepset.ai/docs/mem0memoryretriever) | Retriever | ✅ Available |
| [Mem0MemoryWriter](https://docs.haystack.deepset.ai/docs/mem0memorywriter) | Writer | ✅ Available |
## Meta Llama
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [MetaLlamaChatGenerator](https://docs.haystack.deepset.ai/docs/metallamachatgenerator) | Generator | ✅ Available |
## Mistral
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [MistralChatGenerator](https://docs.haystack.deepset.ai/docs/mistralchatgenerator) | Generator | ✅ Available |
| [MistralDocumentEmbedder](https://docs.haystack.deepset.ai/docs/mistraldocumentembedder) | Embedder | ✅ Available |
| [MistralOCRDocumentConverter](https://docs.haystack.deepset.ai/docs/mistralocrdocumentconverter) | Converter | ✅ Available |
| [MistralTextEmbedder](https://docs.haystack.deepset.ai/docs/mistraltextembedder) | Embedder | ✅ Available |
## MongoDB Atlas
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [MongoDBAtlasEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/mongodbatlasembeddingretriever) | Retriever | ✅ Available |
| [MongoDBAtlasFullTextRetriever](https://docs.haystack.deepset.ai/docs/mongodbatlasfulltextretriever) | Retriever | ✅ Available |
## NVIDIA
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [NvidiaChatGenerator](https://docs.haystack.deepset.ai/docs/nvidiachatgenerator) | Generator | ✅ Available |
| [NvidiaDocumentEmbedder](https://docs.haystack.deepset.ai/docs/nvidiadocumentembedder) | Embedder | ✅ Available |
| [NvidiaRanker](https://docs.haystack.deepset.ai/docs/nvidiaranker) | Ranker | ✅ Available |
| [NvidiaTextEmbedder](https://docs.haystack.deepset.ai/docs/nvidiatextembedder) | Embedder | ✅ Available |
## Ollama
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [OllamaChatGenerator](https://docs.haystack.deepset.ai/docs/ollamachatgenerator) | Generator | ✅ Available |
| [OllamaDocumentEmbedder](https://docs.haystack.deepset.ai/docs/ollamadocumentembedder) | Embedder | ✅ Available |
| [OllamaTextEmbedder](https://docs.haystack.deepset.ai/docs/ollamatextembedder) | Embedder | ✅ Available |
## OpenRouter
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [OpenRouterChatGenerator](https://docs.haystack.deepset.ai/docs/openrouterchatgenerator) | Generator | ✅ Available |
## OpenSearch
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [OpenSearchBM25Retriever](https://docs.haystack.deepset.ai/docs/opensearchbm25retriever) | Retriever | ✅ Available |
| [OpenSearchEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/opensearchembeddingretriever) | Retriever | ✅ Available |
| [OpenSearchHybridRetriever](https://docs.haystack.deepset.ai/docs/opensearchhybridretriever) | Retriever | ✅ Available |
| [OpenSearchMetadataRetriever](https://docs.haystack.deepset.ai/docs/opensearchmetadataretriever) | Retriever | ✅ Available |
| [OpenSearchSQLRetriever](https://docs.haystack.deepset.ai/docs/opensearchsqlretriever) | Retriever | ✅ Available |
## Oracle
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [OracleEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/oracleembeddingretriever) | Retriever | ✅ Available |
| [OracleKeywordRetriever](https://docs.haystack.deepset.ai/docs/oraclekeywordretriever) | Retriever | ✅ Available |
## Perplexity
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [PerplexityChatGenerator](https://docs.haystack.deepset.ai/docs/perplexitychatgenerator) | Generator | ✅ Available |
| [PerplexityDocumentEmbedder](https://docs.haystack.deepset.ai/docs/perplexitydocumentembedder) | Embedder | ✅ Available |
| [PerplexityTextEmbedder](https://docs.haystack.deepset.ai/docs/perplexitytextembedder) | Embedder | ✅ Available |
| [PerplexityWebSearch](https://docs.haystack.deepset.ai/docs/perplexitywebsearch) | Component | ✅ Available |
## pgvector
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [PgvectorEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/pgvectorembeddingretriever) | Retriever | ✅ Available |
| [PgvectorKeywordRetriever](https://docs.haystack.deepset.ai/docs/pgvectorkeywordretriever) | Retriever | ✅ Available |
## Pinecone
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [PineconeEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/pineconedenseretriever) | Retriever | ✅ Available |
## Presidio
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [PresidioDocumentCleaner](https://docs.haystack.deepset.ai/docs/presidiodocumentcleaner) | Preprocessor | ✅ Available |
| [PresidioEntityExtractor](https://docs.haystack.deepset.ai/docs/presidioentityextractor) | Extractor | ✅ Available |
| [PresidioTextCleaner](https://docs.haystack.deepset.ai/docs/presidiotextcleaner) | Preprocessor | ✅ Available |
## Pyversity
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [PyversityRanker](https://docs.haystack.deepset.ai/docs/pyversityranker) | Ranker | ✅ Available |
## Qdrant
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [QdrantEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/qdrantembeddingretriever) | Retriever | ✅ Available |
| [QdrantHybridRetriever](https://docs.haystack.deepset.ai/docs/qdranthybridretriever) | Retriever | ✅ Available |
| [QdrantSparseEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/qdrantsparseembeddingretriever) | Retriever | ✅ Available |
## Snowflake
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [SnowflakeTableRetriever](https://docs.haystack.deepset.ai/docs/snowflaketableretriever) | Retriever | ✅ Available |
## SQLAlchemy
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| SQLAlchemyTableRetriever | Retriever | ✅ Available |
## STACKIT
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [STACKITChatGenerator](https://docs.haystack.deepset.ai/docs/stackitchatgenerator) | Generator | ✅ Available |
| [STACKITDocumentEmbedder](https://docs.haystack.deepset.ai/docs/stackitdocumentembedder) | Embedder | ✅ Available |
| [STACKITTextEmbedder](https://docs.haystack.deepset.ai/docs/stackittextembedder) | Embedder | ✅ Available |
## Supabase
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [SupabasePgvectorEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/supabasepgvectorembeddingretriever) | Retriever | ✅ Available |
| [SupabasePgvectorKeywordRetriever](https://docs.haystack.deepset.ai/docs/supabasepgvectorkeywordretriever) | Retriever | ✅ Available |
## Tavily
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [TavilyWebSearch](https://docs.haystack.deepset.ai/docs/tavilywebsearch) | Component | ✅ Available |
## TogetherAI
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [TogetherAIChatGenerator](https://docs.haystack.deepset.ai/docs/togetheraichatgenerator) | Generator | ✅ Available |
## Unstructured
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [UnstructuredFileConverter](https://docs.haystack.deepset.ai/docs/unstructuredfileconverter) | Converter | ✅ Available |
## Valkey
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [ValkeyEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/valkeyembeddingretriever) | Retriever | ✅ Available |
## Vespa
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [VespaEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/vespaembeddingretriever) | Retriever | ✅ Available |
| [VespaKeywordRetriever](https://docs.haystack.deepset.ai/docs/vespakeywordretriever) | Retriever | ✅ Available |
## vLLM
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [VLLMChatGenerator](https://docs.haystack.deepset.ai/docs/vllmchatgenerator) | Generator | ✅ Available |
| [VLLMDocumentEmbedder](https://docs.haystack.deepset.ai/docs/vllmdocumentembedder) | Embedder | ✅ Available |
| [VLLMRanker](https://docs.haystack.deepset.ai/docs/vllmranker) | Ranker | ✅ Available |
| [VLLMTextEmbedder](https://docs.haystack.deepset.ai/docs/vllmtextembedder) | Embedder | ✅ Available |
## Weaviate
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [WeaviateBM25Retriever](https://docs.haystack.deepset.ai/docs/weaviatebm25retriever) | Retriever | ✅ Available |
| [WeaviateEmbeddingRetriever](https://docs.haystack.deepset.ai/docs/weaviateembeddingretriever) | Retriever | ✅ Available |
## Weights & Biases (Weave)
| Component | Type | Haystack Enterprise Platform |
|-----------|------|------------------------------|
| [WeaveConnector](https://docs.haystack.deepset.ai/docs/weaveconnector) | Connector | ✅ Available |
@@ -250,7 +250,7 @@ components:
exclude_subdomains: false
search_params: {}
top_k: 3
type: haystack.components.websearch.serper_dev.SerperDevWebSearch
type: haystack_integrations.components.websearch.serperdev.websearch.SerperDevWebSearch
description: Search the web for current information on any topic
inputs_from_state: null
name: web_search
@@ -27,7 +27,7 @@ Transcribe audio files to Haystack Documents using FunASR — a local, open-sour
The default model is `iic/SenseVoiceSmall`, a multilingual model supporting 50+ languages that is 5–10x faster than Whisper. Models are downloaded from ModelScope on first use and cached in `~/.cache/modelscope`.
The component accepts audio file paths (`str` or `Path`) as well as `ByteStream` objects. Call `warm_up()` before running in a pipeline to load the model into memory.
The component accepts audio file paths (`str` or `Path`) as well as `ByteStream` objects. The model is loaded into memory automatically the first time the component runs.
## Usage
@@ -37,7 +37,6 @@ The component accepts audio file paths (`str` or `Path`) as well as `ByteStream`
from haystack_integrations.components.audio.funasr import FunASRTranscriber
transcriber = FunASRTranscriber()
transcriber.warm_up()
result = transcriber.run(sources=["speech.wav"])
print(result["documents"][0].content)
@@ -61,7 +60,7 @@ result = pipe.run(
"fetcher": {
"urls": ["https://example.com/interview.wav"],
},
}
},
)
print(result["transcriber"]["documents"][0].content)
```
@@ -44,6 +44,12 @@ pip install langdetect-haystack
Below, we are using the `DocumentLanguageClassifier` to classify English and German documents:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack_integrations.components.classifiers.langdetect import (
DocumentLanguageClassifier,
@@ -74,7 +80,9 @@ from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack_integrations.components.classifiers.langdetect import (
DocumentLanguageClassifier,
)
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
from haystack.components.writers import DocumentWriter
from haystack.components.routers import MetadataRouter
@@ -72,7 +72,6 @@ from haystack_integrations.components.converters.amazon_textract import (
)
converter = AmazonTextractConverter(feature_types=["TABLES", "FORMS"])
converter.warm_up()
result = converter.run(sources=["invoice.pdf"])
documents = result["documents"]
raw_responses = result["raw_textract_response"]
@@ -64,10 +64,16 @@ print(documents)
In the following Pipeline, image documents are created using the `ImageFileToDocument` component, then they are enriched with image embeddings and saved in the Document Store.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Pipeline
from haystack.components.converters.image import ImageFileToDocument
from haystack.components.embedders.image import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentImageEmbedder,
)
from haystack.components.writers.document_writer import DocumentWriter
@@ -15,6 +15,7 @@ Generators are responsible for generating text after you give them a prompt. The
| [AmazonBedrockGenerator](generators/amazonbedrockgenerator.mdx) | Enables text generation using models through Amazon Bedrock service. | ✅ |
| [AIMLAPIChatGenerator](generators/aimllapichatgenerator.mdx) | Enables chat completion using AI models through the AIMLAPI. | ✅ |
| [AnthropicChatGenerator](generators/anthropicchatgenerator.mdx) | This component enables chat completions using Anthropic large language models (LLMs). | ✅ |
| [AnthropicFoundryChatGenerator](generators/anthropicfoundrychatgenerator.mdx) | This component enables chat completions using Anthropic models served through Azure Foundry. | ✅ |
| [AnthropicVertexChatGenerator](generators/anthropicvertexchatgenerator.mdx) | This component enables chat completions using AnthropicVertex API. | ✅ |
| [AnthropicGenerator](generators/anthropicgenerator.mdx) | This component enables text completions using Anthropic large language models (LLMs). | ✅ |
| [AzureOpenAIChatGenerator](generators/azureopenaichatgenerator.mdx) | Enables chat completion using OpenAI's LLMs through Azure services. | ✅ |
@@ -0,0 +1,173 @@
---
title: "AnthropicFoundryChatGenerator"
id: anthropicfoundrychatgenerator
slug: "/anthropicfoundrychatgenerator"
description: "This component enables chat completions using Anthropic models served through Azure Foundry."
---
# AnthropicFoundryChatGenerator
This component enables chat completions using Anthropic models served through Azure Foundry.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | After a [`ChatPromptBuilder`](../builders/chatpromptbuilder.mdx) |
| **Mandatory init variables** | `api_key`: Your Azure Foundry API key. Can be set with the `ANTHROPIC_FOUNDRY_API_KEY` env var. Alternatively, pass an `azure_ad_token_provider` callable. <br /> <br />`resource`: Your Azure Foundry resource name. Can be set with the `ANTHROPIC_FOUNDRY_RESOURCE` env var. Alternatively, pass a full `endpoint` URL. |
| **Mandatory run variables** | `messages`: A list of [`ChatMessage`](../../concepts/data-classes/chatmessage.mdx) objects |
| **Output variables** | `replies`: A list of [`ChatMessage`](../../concepts/data-classes/chatmessage.mdx) objects <br /> <br />`meta`: A dictionary on each reply with metadata such as the model name, finish reason, and token usage |
| **API reference** | [Anthropic](/reference/integrations-anthropic) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/anthropic |
| **Package name** | `anthropic-haystack` |
</div>
## Overview
`AnthropicFoundryChatGenerator` lets you call Anthropic's Claude models through an [Azure Foundry](https://learn.microsoft.com/en-us/azure/ai-foundry/) deployment. It is a thin subclass of [`AnthropicChatGenerator`](anthropicchatgenerator.mdx) — the request and response shapes match the Anthropic Messages API, but the traffic flows through your Azure resource instead of `api.anthropic.com`.
Use this generator when your organization standardizes on Azure for model hosting (billing, networking, compliance) but still wants to work against Claude. If you don't need Azure, prefer `AnthropicChatGenerator`.
The default model is `claude-sonnet-4-5`. Other models known to work include `claude-opus-4-6`, `claude-sonnet-4-6`, `claude-opus-4-5`, `claude-opus-4-1`, and `claude-haiku-4-5`. This list is not exhaustive — the actual catalog depends on what is deployed in your Foundry resource. See the [Anthropic model overview](https://docs.anthropic.com/en/docs/about-claude/models) for guidance on picking a model.
### Parameters
`AnthropicFoundryChatGenerator` needs two things to talk to Azure: credentials and an endpoint.
**Credentials.** Pick one of:
- The `ANTHROPIC_FOUNDRY_API_KEY` environment variable (recommended).
- The `api_key` init parameter using the Haystack [Secret](../../concepts/secret-management.mdx) API: `Secret.from_token("your-api-key-here")`.
- A callable passed as `azure_ad_token_provider` that returns a fresh Azure AD token on demand. Use this for Entra ID / managed-identity setups where a static key isn't appropriate.
**Endpoint.** Pick one of:
- The `resource` init parameter (or the `ANTHROPIC_FOUNDRY_RESOURCE` environment variable) — the short Foundry resource name, used to derive the URL.
- The `endpoint` init parameter — a full URL, useful for custom domains or non-standard routes.
Once configured, pass any text-generation parameter supported by the Anthropic [Messages API](https://docs.anthropic.com/en/api/messages) through `generation_kwargs`, either at init or per call. Common keys include `system`, `max_tokens`, `temperature`, `top_p`, `top_k`, `stop_sequences`, `metadata`, and `extra_headers`. You can also tune `timeout` and `max_retries` to control client-side resilience.
The component takes a list of `ChatMessage` objects. `ChatMessage` is a data class that holds a message, a role (`user`, `assistant`, `system`, or `function`), and optional metadata. Only text input is supported.
### Tool Support
`AnthropicFoundryChatGenerator` supports function calling through the `tools` parameter, which accepts:
- **A list of Tool objects**: Pass individual tools as a list.
- **A single Toolset**: Pass an entire Toolset directly.
- **Mixed Tools and Toolsets**: Combine multiple Toolsets with standalone tools in a single list.
```python
from haystack.tools import Tool, Toolset
from haystack_integrations.components.generators.anthropic import AnthropicFoundryChatGenerator
weather_tool = Tool(name="weather", description="Get weather info", ...)
math_toolset = Toolset([add_tool, subtract_tool, multiply_tool])
generator = AnthropicFoundryChatGenerator(
resource="my-resource",
tools=[math_toolset, weather_tool],
)
```
Tools passed to `run()` override any tools set at init time. For more details, see the [Tool](../../tools/tool.mdx) and [Toolset](../../tools/toolset.mdx) documentation.
### Streaming
You can stream output as it's generated. Pass a callback to `streaming_callback`. The built-in `print_streaming_chunk` prints text tokens and tool events to stdout.
```python
from haystack.components.generators.utils import print_streaming_chunk
from haystack.dataclasses import ChatMessage
from haystack_integrations.components.generators.anthropic import AnthropicFoundryChatGenerator
generator = AnthropicFoundryChatGenerator(
resource="my-resource",
streaming_callback=print_streaming_chunk,
)
generator.run([ChatMessage.from_user("Your question here")])
```
:::info
Streaming works only with a single response. If a provider supports multiple candidates, set `n=1`.
:::
See [Streaming Support](guides-to-generators/choosing-the-right-generator.mdx#streaming-support) for how `StreamingChunk` works and how to write a custom callback. Prefer `print_streaming_chunk` unless you need a specific transport (such as SSE or WebSocket) or custom UI formatting.
### Async
`run_async` mirrors `run` and is wired up automatically — useful inside an async pipeline or web handler.
```python
import asyncio
from haystack.dataclasses import ChatMessage
from haystack_integrations.components.generators.anthropic import AnthropicFoundryChatGenerator
async def main():
generator = AnthropicFoundryChatGenerator(resource="my-resource")
result = await generator.run_async([ChatMessage.from_user("Hello!")])
print(result["replies"][0].text)
asyncio.run(main())
```
## Usage
Install the `anthropic-haystack` package to use the `AnthropicFoundryChatGenerator`:
```shell
pip install anthropic-haystack
```
### On its own
```python
from haystack.dataclasses import ChatMessage
from haystack.utils import Secret
from haystack_integrations.components.generators.anthropic import AnthropicFoundryChatGenerator
generator = AnthropicFoundryChatGenerator(
model="claude-sonnet-4-5",
api_key=Secret.from_env_var("ANTHROPIC_FOUNDRY_API_KEY"),
resource="my-resource",
)
response = generator.run([ChatMessage.from_user("What's Natural Language Processing?")])
print(response)
```
### In a pipeline
```python
from haystack import Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.dataclasses import ChatMessage
from haystack_integrations.components.generators.anthropic import AnthropicFoundryChatGenerator
pipe = Pipeline()
pipe.add_component("prompt_builder", ChatPromptBuilder())
pipe.add_component(
"llm",
AnthropicFoundryChatGenerator(resource="my-resource"),
)
pipe.connect("prompt_builder", "llm")
country = "Germany"
messages = [
ChatMessage.from_system(
"You are an assistant giving out valuable information to language learners.",
),
ChatMessage.from_user("What's the official language of {{ country }}?"),
]
res = pipe.run(
data={
"prompt_builder": {
"template_variables": {"country": country},
"template": messages,
},
},
)
print(res)
```
@@ -82,6 +82,12 @@ CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python
pip install llama-cpp-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
1. Download the GGUF version of the desired LLM. The GGUF versions of popular models can be downloaded from [Hugging Face](https://huggingface.co/models?library=gguf).
@@ -97,7 +103,6 @@ generator = LlamaCppChatGenerator(
model_kwargs={"n_gpu_layers": -1},
generation_kwargs={"max_tokens": 128, "temperature": 0.1},
)
generator.warm_up()
messages = [ChatMessage.from_user("Who is the best American actor?")]
result = generator.run(messages)
```
@@ -209,7 +214,7 @@ from datasets import load_dataset
from haystack import Document, Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders import ChatPromptBuilder
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -240,7 +245,7 @@ Index the documents to the `InMemoryDocumentStore` using the `SentenceTransforme
```python
doc_store = InMemoryDocumentStore(embedding_similarity_function="cosine")
# Install sentence transformers using "pip install sentence-transformers"
# Install the Sentence Transformers embedders using "pip install sentence-transformers-haystack"
doc_embedder = SentenceTransformersDocumentEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
)
@@ -52,6 +52,12 @@ CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python
pip install llama-cpp-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
1. You need to download the GGUF version of the desired LLM. The GGUF versions of popular models can be downloaded from [Hugging Face](https://huggingface.co/models?library=gguf).
@@ -67,7 +73,6 @@ generator = LlamaCppGenerator(
model_kwargs={"n_gpu_layers": -1},
generation_kwargs={"max_tokens": 128, "temperature": 0.1},
)
generator.warm_up()
prompt = f"Who is the best American actor?"
result = generator.run(prompt)
```
@@ -147,7 +152,7 @@ from datasets import load_dataset
from haystack import Document, Pipeline
from haystack.components.builders.answer_builder import AnswerBuilder
from haystack.components.builders.prompt_builder import PromptBuilder
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -130,6 +130,12 @@ print(json.loads(result["validator"]["validated"][0].text))
In this example, the `TextLanguageRouter` component directs the query to one of three language-specific Retrievers. The next component would be a `PromptBuilder`, but we cannot connect multiple Retrievers to a single `PromptBuilder` directly. Instead, we connect all the Retrievers to the `BranchJoiner` component. The `BranchJoiner` then takes the output from the Retriever that was actually called and passes it as a single list of documents to the `PromptBuilder`. The `BranchJoiner` ensures that the pipeline can handle multiple languages seamlessly by consolidating different outputs from the Retrievers into a unified connection for further processing.
The examples on this page use language classification components that have moved to the `langdetect-haystack` package. Install it to run the examples:
```shell
pip install langdetect-haystack
```
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
@@ -137,7 +143,7 @@ from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.components.joiners import BranchJoiner
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.routers import TextLanguageRouter
from haystack_integrations.components.routers.langdetect import TextLanguageRouter
from haystack.dataclasses import ChatMessage
prompt_template = [
@@ -63,6 +63,12 @@ joiner.run(documents=[docs_1, docs_2])
Below is an example of a hybrid retrieval pipeline that retrieves documents from an `InMemoryDocumentStore` based on keyword search (using `InMemoryBM25Retriever`) and embedding search (using `InMemoryEmbeddingRetriever`). It then uses the `DocumentJoiner` with its default join mode to concatenate the retrieved documents into one list. The Document Store must contain documents with embeddings, otherwise the `InMemoryEmbeddingRetriever` will not return any documents.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack.components.joiners.document_joiner import DocumentJoiner
from haystack import Pipeline
@@ -71,7 +77,9 @@ from haystack.components.retrievers.in_memory import (
InMemoryBM25Retriever,
InMemoryEmbeddingRetriever,
)
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
)
document_store = InMemoryDocumentStore()
p = Pipeline()
@@ -111,7 +119,9 @@ from haystack.components.converters import (
from haystack.components.preprocessors import DocumentSplitter, DocumentCleaner
from haystack.components.routers import FileTypeRouter
from haystack.components.joiners import DocumentJoiner
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
from haystack import Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from pathlib import Path
@@ -144,7 +144,6 @@ def custom_split(text: str) -> list[str]:
doc = Document(content="第一段,第二段,第三段,第四段")
splitter = ChineseDocumentSplitter(split_by="function", splitting_function=custom_split)
splitter.warm_up()
result = splitter.run(documents=[doc])
print(result["documents"])
```
@@ -36,10 +36,18 @@ This component is inspired by [5 Levels of Text Splitting](https://github.com/Fu
### On its own
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
from haystack.components.preprocessors import EmbeddingBasedDocumentSplitter
# Create a document with content that has a clear topic shift
@@ -55,14 +55,22 @@ result = cleaner.run(texts=[text_to_clean])
### In a pipeline
In this example, we are using `TextCleaner` after an `ExtractiveReader` and an `OutputAdapter` to remove the punctuation in texts. Then, our custom-made `ExactMatchEvaluator` component compares the retrieved answer to the ground truth answer.
In this example, we are using `TextCleaner` after a `TransformersExtractiveReader` and an `OutputAdapter` to remove the punctuation in texts. Then, our custom-made `ExactMatchEvaluator` component compares the retrieved answer to the ground truth answer.
The examples on this page use Transformers components that have moved to the `transformers-haystack` package. Install it to run the examples:
```shell
pip install transformers-haystack
```
```python
from typing import List
from haystack import component, Document, Pipeline
from haystack.components.converters import OutputAdapter
from haystack.components.preprocessors import TextCleaner
from haystack.components.readers import ExtractiveReader
from haystack_integrations.components.readers.transformers import (
TransformersExtractiveReader,
)
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
@@ -96,7 +104,7 @@ adapter = OutputAdapter(
p = Pipeline()
p.add_component("retriever", InMemoryBM25Retriever(document_store=document_store))
p.add_component("reader", ExtractiveReader())
p.add_component("reader", TransformersExtractiveReader())
p.add_component("adapter", adapter)
p.add_component("cleaner", TextCleaner(remove_punctuation=True))
p.add_component("evaluator", ExactMatchEvaluator())
@@ -95,19 +95,27 @@ print(result["documents"][0].content)
Below is an example of a full RAG pipeline that retrieves documents using embedding similarity, reranks them with `FastembedLateInteractionRanker`, and generates an answer with an LLM.
This example uses the `HuggingFaceLocalChatGenerator`, which requires additional packages:
This example uses the `TransformersChatGenerator`, which requires additional packages:
```shell
pip install "transformers[torch]"
```
The examples on this page use Transformers components that have moved to the `transformers-haystack` package. Install it to run the examples:
```shell
pip install transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.components.builders.chat_prompt_builder import ChatPromptBuilder
from haystack.components.generators.chat import HuggingFaceLocalChatGenerator
from haystack_integrations.components.generators.transformers import (
TransformersChatGenerator,
)
from haystack.components.writers import DocumentWriter
from haystack.dataclasses import ChatMessage
from haystack_integrations.components.rankers.fastembed import (
@@ -162,7 +170,7 @@ rag.add_component(
)
rag.add_component(
"llm",
HuggingFaceLocalChatGenerator(model="HuggingFaceTB/SmolLM2-360M-Instruct"),
TransformersChatGenerator(model="HuggingFaceTB/SmolLM2-360M-Instruct"),
)
rag.connect("text_embedder.embedding", "retriever.query_embedding")
@@ -96,9 +96,15 @@ Below is an example of a pipeline that embeds documents and stores them in an `I
Note that the retriever must be configured with `return_embedding=True` so that documents have embeddings available for the ranker.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -167,6 +167,7 @@ For details on how to initialize and use a Retriever in a pipeline, see the docu
| [CogneeRetriever](retrievers/cogneeretriever.mdx) | Retrieves memories from a CogneeMemoryStore and returns them as system ChatMessage objects. |
| [ElasticsearchEmbeddingRetriever](retrievers/elasticsearchembeddingretriever.mdx) | An embedding-based Retriever compatible with the Elasticsearch Document Store. |
| [ElasticsearchBM25Retriever](retrievers/elasticsearchbm25retriever.mdx) | A keyword-based Retriever that fetches Documents matching a query from the Elasticsearch Document Store. |
| [ElasticsearchHybridRetriever](retrievers/elasticsearchhybridretriever.mdx) | A SuperComponent that combines BM25 and embedding-based retrieval from the Elasticsearch Document Store. |
| [ElasticsearchSQLRetriever](retrievers/elasticsearchsqlretriever.mdx) | Executes raw Elasticsearch SQL queries against an Elasticsearch Document Store and returns the raw JSON response. |
| [FAISSEmbeddingRetriever](retrievers/faissembeddingretriever.mdx) | An embedding-based Retriever compatible with the FAISSDocumentStore. |
| [FalkorDBCypherRetriever](retrievers/falkordbcypherretriever.mdx) | A Retriever that executes arbitrary OpenCypher queries against a FalkorDB Document Store. |
@@ -185,6 +186,7 @@ For details on how to initialize and use a Retriever in a pipeline, see the docu
| [OpenSearchBM25Retriever](retrievers/opensearchbm25retriever.mdx) | A keyword-based Retriever that fetches Documents matching a query from an OpenSearch Document Store. |
| [OpenSearchEmbeddingRetriever](retrievers/opensearchembeddingretriever.mdx) | An embedding-based Retriever compatible with the OpenSearch Document Store. |
| [OpenSearchHybridRetriever](retrievers/opensearchhybridretriever.mdx) | A SuperComponent that implements a Hybrid Retriever in a single component, relying on OpenSearch as the backend Document Store. |
| [OpenSearchMetadataRetriever](retrievers/opensearchmetadataretriever.mdx) | Searches and ranks the metadata fields of documents stored in an OpenSearch Document Store and returns the matching metadata values. |
| [OpenSearchSQLRetriever](retrievers/opensearchsqlretriever.mdx) | Executes raw OpenSearch SQL queries against an OpenSearch Document Store and returns the raw JSON response. |
| [OracleEmbeddingRetriever](retrievers/oracleembeddingretriever.mdx) | An embedding-based Retriever compatible with the Oracle Document Store. |
| [OracleKeywordRetriever](retrievers/oraclekeywordretriever.mdx) | A keyword-based Retriever that fetches Documents matching a query from the Oracle Document Store. |
@@ -194,7 +196,7 @@ For details on how to initialize and use a Retriever in a pipeline, see the docu
| [QdrantEmbeddingRetriever](retrievers/qdrantembeddingretriever.mdx) | An embedding-based Retriever compatible with the Qdrant Document Store. |
| [QdrantSparseEmbeddingRetriever](retrievers/qdrantsparseembeddingretriever.mdx) | A sparse embedding-based Retriever compatible with the Qdrant Document Store. |
| [QdrantHybridRetriever](retrievers/qdranthybridretriever.mdx) | A Retriever based both on dense and sparse embeddings, compatible with the Qdrant Document Store. |
| [SentenceWindowRetriever](retrievers/sentencewindowretrieval.mdx) | Retrieves neighboring sentences around relevant sentences to get the full context. |
| [SentenceWindowRetriever](retrievers/sentencewindowretriever.mdx) | Retrieves neighboring sentences around relevant sentences to get the full context. |
| [SnowflakeTableRetriever](retrievers/snowflaketableretriever.mdx) | Connects to a Snowflake database to execute an SQL query. |
| [SupabaseGroongaBM25Retriever](retrievers/supabasegroongabm25retriever.mdx) | A full-text Retriever that fetches documents from the SupabaseGroongaDocumentStore using PGroonga search. |
| [SupabasePgvectorEmbeddingRetriever](retrievers/supabasepgvectorembeddingretriever.mdx) | An embedding-based Retriever compatible with the SupabasePgvectorDocumentStore. |
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the AlloyDB Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of an [AlloyDBDocumentStore](../../document-stores/alloydbdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -43,6 +43,12 @@ pip install alloydb-haystack
To set up an AlloyDB cluster and instance, follow the [AlloyDB quickstart](https://cloud.google.com/alloydb/docs/quickstart).
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -69,7 +75,7 @@ retriever.run(query_embedding=[0.1] * 768)
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -45,6 +45,12 @@ docker run -d -p 8529:8529 \
arangodb:3.12 arangod --vector-index
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -84,7 +90,7 @@ print(result["documents"][0].content)
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -35,6 +35,12 @@ pip install arcadedb-haystack
Ensure ArcadeDB is running, for example via Docker, and credentials are set (`ARCADEDB_USERNAME`, `ARCADEDB_PASSWORD`).
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -63,7 +69,7 @@ for doc in result["documents"]:
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -13,7 +13,7 @@ This is an embedding-based Retriever compatible with the Astra Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline <br /> 2. The last component in the semantic search pipeline <br /> 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline <br /> 2. The last component in the semantic search pipeline <br /> 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [AstraDocumentStore](../../document-stores/astradocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -43,10 +43,10 @@ From the configuration in AstraDB’s web UI, you need the database ID and a gen
You will additionally need a collection name and a namespace. When you create the collection name, you also need to set the embedding dimensions and the similarity metric. The namespace organizes data in a database and is called a keyspace in Apache Cassandra.
Then, optionally, install sentence-transformers as well to run the example below:
Then, optionally, install the `sentence-transformers-haystack` package as well to run the example below:
```shell
pip install sentence-transformers
pip install sentence-transformers-haystack
```
## Usage
@@ -59,7 +59,7 @@ Use this Retriever in a query pipeline like this:
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -15,7 +15,7 @@ This Retriever accepts the embeddings of a single query as input and returns a l
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the embedding retrieval pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the embedding retrieval pipeline 3. After a Text Embedder and before an [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [`AzureAISearchDocumentStore`](../../document-stores/azureaisearchdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -80,9 +80,15 @@ In the indexing pipeline, the documents are passed to the Document Embedder and
Then, in the querying pipeline, we use a Text Embedder to get the vector representation of the input query that will be then passed to the `AzureAISearchEmbeddingRetriever` to get the results.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -15,7 +15,7 @@ This Retriever combines embedding-based retrieval and BM25 text search search to
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a TextEmbedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a TextEmbedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a TextEmbedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a TextEmbedder and before an [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [`AzureAISearchDocumentStore`](../../document-stores/azureaisearchdocumentstore.mdx) |
| **Mandatory run variables** | `query`: A string <br /> <br />`query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents (matching the query) |
@@ -84,9 +84,15 @@ retriever.run(
The following example demonstrates using the `AzureAISearchHybridRetriever` in a pipeline. An indexing pipeline is responsible for indexing and storing documents with embeddings in the `AzureAISearchDocumentStore`, while the query pipeline uses hybrid retrieval to fetch relevant documents based on a given query.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -13,7 +13,7 @@ This is an embedding Retriever compatible with the Chroma Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [ChromaDocumentStore](../../document-stores/chromadocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -65,8 +65,8 @@ from haystack import Pipeline
from haystack.dataclasses import Document
from haystack.components.writers import DocumentWriter
# Note: the following requires a "pip install sentence-transformers"
from haystack.components.embedders import (
# Note: the following requires a "pip install sentence-transformers-haystack"
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the Elasticsearch Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [ElasticsearchDocumentStore](../../document-stores/elasticsearch-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -58,6 +58,12 @@ Once you have a running Elasticsearch instance, install the `elasticsearch-hayst
pip install elasticsearch-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### In a pipeline
@@ -74,7 +80,7 @@ from haystack_integrations.document_stores.elasticsearch import (
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -0,0 +1,214 @@
---
title: "ElasticsearchHybridRetriever"
id: elasticsearchhybridretriever
slug: "/elasticsearchhybridretriever"
description: "This is a SuperComponent that implements a Hybrid Retriever in a single component, relying on Elasticsearch as the backend Document Store."
---
# ElasticsearchHybridRetriever
This is a [SuperComponent](../../concepts/components/supercomponents.mdx) that implements a Hybrid Retriever in a single component, relying on Elasticsearch as the backend Document Store.
A Hybrid Retriever uses both traditional keyword-based search (BM25) and embedding-based search to retrieve documents, combining the strengths of both approaches. The Retriever then merges and re-ranks the results from both methods.
<div className="key-value-table">
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a TextEmbedder and before a PromptBuilder in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a TextEmbedder and before an ExtractiveReader in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of [`ElasticsearchDocumentStore`](../../document-stores/elasticsearch-document-store.mdx) <br /> <br />`embedder`: Any [Embedder](../embedders.mdx) implementing the `TextEmbedder` protocol |
| **Mandatory run variables** | `query`: A query string |
| **Output variables** | `documents`: A list of documents matching the query |
| **API reference** | [Elasticsearch](/reference/integrations-elasticsearch) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/elasticsearch |
| **Package name** | `elasticsearch-haystack` |
</div>
## Overview
The `ElasticsearchHybridRetriever` combines two retrieval methods:
1. **BM25 Retrieval**: A keyword-based search that uses the BM25 algorithm to find documents based on term frequency and inverse document frequency. It's based on the [`ElasticsearchBM25Retriever`](elasticsearchbm25retriever.mdx) component and is suitable for finding exact matches to names, IDs, or well-defined terms.
2. **Embedding-based Retrieval**: A semantic search that uses vector similarity to find documents that are semantically similar to the query. It's based on the [`ElasticsearchEmbeddingRetriever`](elasticsearchembeddingretriever.mdx) component and is suitable for semantic search.
The component automatically handles:
- Converting the query into an embedding using the provided embedder,
- Running both retrieval methods in parallel,
- Merging and re-ranking the results using the specified join mode (default: Reciprocal Rank Fusion).
### Installation
[Install](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html) Elasticsearch and then [start](https://www.elastic.co/guide/en/elasticsearch/reference/current/starting-elasticsearch.html) an instance. Haystack supports Elasticsearch 8.
If you have Docker set up, we recommend pulling the Docker image and running it.
```shell
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.11.1
docker run -p 9200:9200 -e "discovery.type=single-node" -e "ES_JAVA_OPTS=-Xms1024m -Xmx1024m" -e "xpack.security.enabled=false" elasticsearch:8.11.1
```
As an alternative, you can go to the [Elasticsearch integration GitHub](https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/elasticsearch) and start a Docker container running Elasticsearch using the provided `docker-compose.yml`:
```shell
docker compose up
```
Once you have a running Elasticsearch instance, install the `elasticsearch-haystack` integration:
```shell
pip install elasticsearch-haystack
```
### Optional Parameters
This Retriever accepts various optional parameters. You can verify the most up-to-date list of parameters in our [API Reference](/reference/integrations-elasticsearch).
You can pass additional parameters to the underlying BM25 and embedding retriever components using the `top_k_bm25`, `fuzziness`, `filters_bm25`, `scale_score`, `filter_policy_bm25`, `top_k_embedding`, `filters_embedding`, `num_candidates`, and `filter_policy_embedding` parameters.
The `DocumentJoiner` parameters (`join_mode`, `weights`, `top_k`, and `sort_by_score`) are all exposed directly on the `ElasticsearchHybridRetriever` class.
## Usage
### On its own
This Retriever needs the `ElasticsearchDocumentStore` populated with documents (including embeddings) to run.
```python
from haystack import Document
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
from haystack_integrations.components.retrievers.elasticsearch import (
ElasticsearchHybridRetriever,
)
from haystack_integrations.document_stores.elasticsearch import (
ElasticsearchDocumentStore,
)
document_store = ElasticsearchDocumentStore(hosts="http://localhost:9200/")
model = "sentence-transformers/all-MiniLM-L6-v2"
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
doc_embedder = SentenceTransformersDocumentEmbedder(model=model)
docs_with_embeddings = doc_embedder.run(documents)
document_store.write_documents(docs_with_embeddings["documents"])
embedder = SentenceTransformersTextEmbedder(model=model)
retriever = ElasticsearchHybridRetriever(
document_store=document_store,
embedder=embedder,
)
results = retriever.run(query="How many languages are spoken around the world today?")
print(results["documents"])
```
### In a pipeline
Here's a full example that uses an indexing pipeline to store documents with embeddings, and a query pipeline that uses `ElasticsearchHybridRetriever` for hybrid retrieval.
Set your `OPENAI_API_KEY` as an environment variable and then run the following code:
```python
from haystack import Document, Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
from haystack.components.writers import DocumentWriter
from haystack.dataclasses import ChatMessage
from haystack.document_stores.types import DuplicatePolicy
from haystack_integrations.components.retrievers.elasticsearch import (
ElasticsearchHybridRetriever,
)
from haystack_integrations.document_stores.elasticsearch import (
ElasticsearchDocumentStore,
)
document_store = ElasticsearchDocumentStore(hosts="http://localhost:9200/")
model = "sentence-transformers/all-MiniLM-L6-v2"
documents = [
Document(content="There are over 7,000 languages spoken around the world today."),
Document(
content="Elephants have been observed to behave in a way that indicates a high level of self-awareness, such as recognizing themselves in mirrors.",
),
Document(
content="In certain parts of the world, like the Maldives, Puerto Rico, and San Diego, you can witness the phenomenon of bioluminescent waves.",
),
]
# Indexing Pipeline
indexing_pipeline = Pipeline()
indexing_pipeline.add_component(
"doc_embedder",
SentenceTransformersDocumentEmbedder(model=model),
)
indexing_pipeline.add_component(
"doc_writer",
DocumentWriter(document_store=document_store, policy=DuplicatePolicy.SKIP),
)
indexing_pipeline.connect("doc_embedder", "doc_writer")
indexing_pipeline.run({"doc_embedder": {"documents": documents}})
# Query Pipeline
prompt_template = [
ChatMessage.from_user(
"""
Given these documents, answer the question.\nDocuments:
{% for doc in documents %}
{{ doc.content }}
{% endfor %}
\nQuestion: {{question}}
\nAnswer:
""",
),
]
embedder = SentenceTransformersTextEmbedder(model=model)
retriever = ElasticsearchHybridRetriever(
document_store=document_store,
embedder=embedder,
top_k_bm25=3,
top_k_embedding=3,
join_mode="reciprocal_rank_fusion",
)
query_pipeline = Pipeline()
query_pipeline.add_component("retriever", retriever)
query_pipeline.add_component(
"prompt_builder",
ChatPromptBuilder(template=prompt_template, required_variables="*"),
)
query_pipeline.add_component("llm", OpenAIChatGenerator())
query_pipeline.connect("retriever.documents", "prompt_builder.documents")
query_pipeline.connect("prompt_builder.prompt", "llm.messages")
question = "How many languages are spoken around the world today?"
result = query_pipeline.run(
{
"retriever": {"query": question},
"prompt_builder": {"question": question},
},
)
print(result["llm"]["replies"][0].text)
```
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the FAISSDocumentStore.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [`FAISSDocumentStore`](../../document-stores/faissdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -54,9 +54,15 @@ print(result["documents"])
### In a pipeline
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -45,6 +45,12 @@ Ensure FalkorDB is running, for example via Docker:
docker run -d -p 6379:6379 falkordb/falkordb:latest
```
The examples on this page use Transformers components that have moved to the `transformers-haystack` package. Install it to run the examples:
```shell
pip install transformers-haystack
```
## Usage
### On its own
@@ -85,7 +91,9 @@ print(result["documents"][0].content)
```python
from haystack import Document, Pipeline
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import HuggingFaceLocalChatGenerator
from haystack_integrations.components.generators.transformers import (
TransformersChatGenerator,
)
from haystack.dataclasses import ChatMessage
from haystack_integrations.document_stores.falkordb import FalkorDBDocumentStore
from haystack_integrations.components.retrievers.falkordb import FalkorDBCypherRetriever
@@ -130,7 +138,7 @@ pipeline.add_component(
pipeline.add_component("prompt_builder", ChatPromptBuilder(template=prompt_template))
pipeline.add_component(
"llm",
HuggingFaceLocalChatGenerator(model="HuggingFaceTB/SmolLM2-135M-Instruct"),
TransformersChatGenerator(model="HuggingFaceTB/SmolLM2-135M-Instruct"),
)
pipeline.connect("retriever.documents", "prompt_builder.documents")
pipeline.connect("prompt_builder.prompt", "llm.messages")
@@ -43,6 +43,12 @@ Ensure FalkorDB is running, for example via Docker:
docker run -d -p 6379:6379 falkordb/falkordb:latest
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -83,7 +89,7 @@ print(result["documents"][0].content)
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -112,7 +118,6 @@ documents = [
document_embedder = SentenceTransformersDocumentEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
)
document_embedder.warm_up()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
@@ -13,7 +13,7 @@ Use this Retriever with the InMemoryDocumentStore if you're looking for embeddin
| | |
| --- | --- |
| **Most common position in a pipeline** | In query pipelines: <br />In a RAG pipeline, before a [`PromptBuilder`](../builders/promptbuilder.mdx) <br />In a semantic search pipeline, as the last component <br />In an extractive QA pipeline, after a Tex tEmbedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) |
| **Most common position in a pipeline** | In query pipelines: <br />In a RAG pipeline, before a [`PromptBuilder`](../builders/promptbuilder.mdx) <br />In a semantic search pipeline, as the last component <br />In an extractive QA pipeline, after a Tex tEmbedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) |
| **Mandatory init variables** | `document_store`: An instance of [InMemoryDocumentStore](../../document-stores/inmemorydocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floating point numbers |
| **Output variables** | `documents`: A list of documents |
@@ -39,10 +39,16 @@ The `embedding_similarity_function` to use for embedding retrieval must be defi
Use this Retriever in a query pipeline like this:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -13,7 +13,7 @@ This is an embedding Retriever compatible with the MongoDB Atlas Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [MongoDBAtlasDocumentStore](../../document-stores/mongodbatlasdocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -63,6 +63,12 @@ retriever.run(query_embedding=[0.1] * 384)
### In a Pipeline
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Pipeline, Document
from haystack.document_stores.types import DuplicatePolicy
@@ -70,7 +76,7 @@ from haystack.components.writers import DocumentWriter
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.builders import ChatPromptBuilder
from haystack.dataclasses import ChatMessage
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -13,7 +13,7 @@ This is a full-text search Retriever compatible with the MongoDB Atlas Document
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. Before a [ChatPromptBuilder](../builders/chatpromptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before an [ExtractiveReader](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. Before a [ChatPromptBuilder](../builders/chatpromptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. Before a [TransformersExtractiveReader](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [MongoDBAtlasDocumentStore](../../document-stores/mongodbatlasdocumentstore.mdx) |
| **Mandatory run variables** | `query`: A query string to search for. If the query contains multiple terms, Atlas Search evaluates each term separately for matches. |
| **Output variables** | `documents`: A list of documents |
@@ -69,11 +69,17 @@ print(results["documents"])
Here's a Hybrid Retrieval pipeline example that makes use of both available MongoDB Atlas Retrievers:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Pipeline, Document
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.writers import DocumentWriter
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -64,10 +64,16 @@ Before running the pipeline, documents must be embedded using a Document Embedde
<Tabs>
<TabItem value="python" label="Python" default>
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -138,7 +144,7 @@ components:
init_parameters: {}
top_k: 2
query_embedder:
type: haystack.components.embedders.sentence_transformers_text_embedder.SentenceTransformersTextEmbedder
type: haystack_integrations.components.embedders.sentence_transformers.sentence_transformers_text_embedder.SentenceTransformersTextEmbedder
init_parameters:
model: sentence-transformers/all-MiniLM-L6-v2
@@ -54,11 +54,17 @@ The `join_mode` parameter controls how results from multiple retrievers are merg
This example sets up a `MultiRetriever` combining a BM25 retriever and an embedding-based retriever (wrapped with `TextEmbeddingRetriever`). Both are queried in parallel and the results are merged using reciprocal rank fusion.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -126,7 +132,7 @@ from haystack import Document, Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.builders import ChatPromptBuilder
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the OpenSearch Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of an [OpenSearchDocumentStore](../../document-stores/opensearch-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -62,6 +62,12 @@ pip install opensearch-haystack
Use this Retriever in a query Pipeline like this:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack_integrations.components.retrievers.opensearch import (
OpenSearchEmbeddingRetriever,
@@ -71,7 +77,7 @@ from haystack_integrations.document_stores.opensearch import OpenSearchDocumentS
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -15,7 +15,7 @@ A Hybrid Retriever uses both traditional keyword-based search (such as BM25) and
| | |
| --- | --- |
| Most common position in a pipeline | After an [OpenSearchDocumentStore](../../document-stores/opensearch-document-store.mdx) |
| Most common position in a pipeline | 1. After a TextEmbedder and before a PromptBuilder in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a TextEmbedder and before a TransformersExtractiveReader in an extractive QA pipeline |
| Mandatory init variables | `document_store`: An instance of `OpenSearchDocumentStore` to use for retrieval <br /> <br />`embedder`: Any [Embedder](../embedders.mdx) implementing the `TextEmbedder` protocol |
| Mandatory run variables | `query`: A query string |
| Output variables | `documents`: A list of documents matching the query |
@@ -83,9 +83,15 @@ docker run -d \\
opensearchproject/opensearch:2.12.0
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document
from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
from haystack_integrations.components.retrievers.opensearch import OpenSearchHybridRetriever
from haystack_integrations.document_stores.opensearch import OpenSearchDocumentStore
@@ -0,0 +1,184 @@
---
title: OpenSearchMetadataRetriever
id: opensearchmetadataretriever
slug: /opensearchmetadataretriever
description: Searches and ranks the metadata fields of documents stored in an OpenSearch Document Store and returns the matching metadata values.
---
# OpenSearchMetadataRetriever
Searches and ranks the metadata fields of documents stored in an OpenSearch Document Store and returns the matching metadata values.
<div className="key-value-table">
| | |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| **Most common position in a pipeline** | The last component in a metadata lookup pipeline, or wherever you need other structured data from an OpenSearchDocumentStore index |
| **Mandatory init variables** | `document_store`: An instance of `OpenSearchDocumentStore`; `metadata_fields`: List of metadata field names to search and return |
| **Mandatory run variables** | `query`: A search query string (may contain comma-separated parts) |
| **Output variables** | `metadata`: A list of dictionaries containing only the requested metadata fields |
| **API reference** | [OpenSearch](/reference/integrations-opensearch) |
| **GitHub link** | https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/opensearch |
| **Package name** | `opensearch-haystack` |
</div>
## Overview
`OpenSearchMetadataRetriever` searches the metadata of documents stored in an `OpenSearchDocumentStore` and returns the matching metadata values, not the documents themselves. It is useful when the metadata is the answer: for example, listing the categories or tags that match a partial query, building a metadata autocomplete, or surfacing the structured side of an index without pulling back document content.
Unlike the other OpenSearch retrievers (`OpenSearchBM25Retriever`, `OpenSearchEmbeddingRetriever`, `OpenSearchHybridRetriever`), this component does not return `Document` objects. The output is a list under `metadata`, where each entry is a dictionary containing only the fields you listed in `metadata_fields`. Document content and any other metadata are excluded from the result.
The retriever supports two search modes:
- `strict` uses prefix and wildcard matching on the configured metadata fields.
- `fuzzy` (the default) uses fuzzy matching with `dis_max` queries, allowing typos and partial matches.
In both modes, candidate documents are scored server-side with Jaccard similarity on character n-grams (the `jaccard_n` parameter controls the n-gram size), and exact matches receive an additional boost controlled by `exact_match_weight`. Up to 1000 hits are fetched from OpenSearch, and the top `top_k` results are returned.
Both a synchronous `run` method and an asynchronous `run_async` method are available with the same parameters.
### Field types
The matching engine only operates on metadata fields that OpenSearch indexes as text or keyword values. Numeric, boolean, and array-of-non-strings fields are not valid search targets, because prefix, wildcard, and full-text matching do not apply to them. Mixed-type fields, such as a list that combines strings and numbers, are also not supported.
## Installation
If you have Docker set up, the easiest way to run OpenSearch is to pull and run the Docker image.
```bash
docker pull opensearchproject/opensearch:2
docker run -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" -e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password>" opensearchproject/opensearch:2
```
As an alternative, you can go to the [OpenSearch integration GitHub](https://github.com/deepset-ai/haystack-core-integrations/tree/main/integrations/opensearch) and start a Docker container using the provided `docker-compose.yml`:
```bash
docker compose up
```
Once you have a running OpenSearch instance, install the `opensearch-haystack` integration:
```bash
pip install opensearch-haystack
```
## Usage
### On its own
This Retriever needs an `OpenSearchDocumentStore` with indexed documents. The example below writes three documents with simple categorical metadata and queries the `category` and `status` fields:
```python
from haystack import Document
from haystack_integrations.components.retrievers.opensearch import (
OpenSearchMetadataRetriever,
)
from haystack_integrations.document_stores.opensearch import OpenSearchDocumentStore
from haystack.document_stores.types import DuplicatePolicy
document_store = OpenSearchDocumentStore(
hosts="http://localhost:9200",
index="my_index",
)
documents = [
Document(
content="Python programming guide",
meta={
"category": "Python",
"status": "active",
"priority": 1,
"author": "John Doe",
},
),
Document(
content="Java tutorial",
meta={
"category": "Java",
"status": "active",
"priority": 2,
"author": "Jane Smith",
},
),
Document(
content="Python advanced topics",
meta={
"category": "Python",
"status": "inactive",
"priority": 3,
"author": "John Doe",
},
),
]
document_store.write_documents(documents=documents, policy=DuplicatePolicy.SKIP)
retriever = OpenSearchMetadataRetriever(
document_store=document_store,
metadata_fields=["category", "status"],
top_k=10,
)
result = retriever.run(query="Python")
print(result)
# {
# "metadata": [
# {"category": "Python", "status": "active"},
# {"category": "Python", "status": "inactive"},
# ]
# }
```
Only the fields listed in `metadata_fields` appear in each result dictionary. The `author` metadata and the document content are excluded.
### Multi-part queries
The `query` string can contain several comma-separated parts. Each part is searched across every field listed in `metadata_fields`, and a document that matches multiple parts is ranked higher (controlled by `exact_match_weight`).
```python
result = retriever.run(query="Python, active")
# Returns the metadata of documents whose fields match both "Python" and "active".
```
### Strict mode
By default the retriever runs in `fuzzy` mode, which tolerates typos and partial matches. For lookups where you only want prefix or wildcard matches and no edit-distance tolerance, switch to `strict`:
```python
retriever = OpenSearchMetadataRetriever(
document_store=document_store,
metadata_fields=["category"],
mode="strict",
)
result = retriever.run(query="Pyth")
# Matches "Python" through prefix matching, but not transposed-letter variants.
```
The fuzzy-mode parameters (`fuzziness`, `prefix_length`, `max_expansions`, `tie_breaker`) only take effect when `mode="fuzzy"`.
### Combining with filters
You can narrow the candidate set before scoring by passing standard Haystack `filters` at run time. The filters are applied in a `bool` `filter` context, so they exclude non-matching documents without affecting scores:
```python
result = retriever.run(
query="Python",
filters={"field": "status", "operator": "==", "value": "active"},
)
```
### Asynchronous execution
For pipelines that mix synchronous and asynchronous components, the retriever exposes `run_async` with the same signature:
```python
result = await retriever.run_async(query="Python, active")
```
### Error handling
By default, a failed OpenSearch request raises an exception. To treat a failure as an empty result instead — for example, when the retriever sits behind a forgiving API — initialize the component with `raise_on_failure=False`. The error is then logged as a warning and `metadata` is returned as an empty list.
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the Oracle Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of an [OracleDocumentStore](../../document-stores/oracledocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -48,6 +48,12 @@ Install the Oracle integration for Haystack:
pip install oracle-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -82,7 +88,7 @@ retriever.run(query_embedding=[0.1] * 768)
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -116,7 +122,6 @@ documents = [
document_embedder = SentenceTransformersDocumentEmbedder(
model="sentence-transformers/all-MiniLM-L6-v2",
)
document_embedder.warm_up()
documents_with_embeddings = document_embedder.run(documents)
document_store.write_documents(
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the Pgvector Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [PgvectorDocumentStore](../../document-stores/pgvectordocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -49,6 +49,12 @@ To use pgvector with Haystack, install the `pgvector-haystack` integration:
pip install pgvector-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -77,7 +83,7 @@ retriever.run(query_embedding=[0.1] * 768)
import os
from haystack.document_stores import DuplicatePolicy
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the Pinecone Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [PineconeDocumentStore](../../document-stores/pinecone-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -64,7 +64,7 @@ Install the dependencies you’ll need:
```shell
pip install pinecone-haystack
pip install sentence-transformers
pip install sentence-transformers-haystack
```
Use this Retriever in a query Pipeline like this:
@@ -73,7 +73,7 @@ Use this Retriever in a query Pipeline like this:
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the Qdrant Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1\. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG Pipeline <br /> <br />2. The last component in the semantic search pipeline <br />3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1\. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG Pipeline <br /> <br />2. The last component in the semantic search pipeline <br />3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [QdrantDocumentStore](../../document-stores/qdrant-document-store.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -65,11 +65,17 @@ retriever.run(query_embedding=[0.1] * 768)
#### In a Pipeline
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -1,7 +1,7 @@
---
title: "SentenceWindowRetriever"
id: sentencewindowretrieval
slug: "/sentencewindowretrieval"
id: sentencewindowretriever
slug: "/sentencewindowretriever"
description: "Use this component to retrieve neighboring sentences around relevant sentences to get the full context."
---
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the SupabasePgvectorDocumentStore.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [SupabasePgvectorDocumentStore](../../document-stores/supabasedocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -39,6 +39,12 @@ Some relevant parameters that impact embedding retrieval must be defined when th
pip install supabase-haystack
```
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -65,7 +71,7 @@ retriever.run(query_embedding=[0.1] * 768)
```python
from haystack import Document, Pipeline
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -33,11 +33,17 @@ You can use it anywhere an embedding-based retriever fits: in RAG pipelines befo
### On its own
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -86,7 +92,9 @@ for doc in result["documents"]:
`TextEmbeddingRetriever` is most commonly used as one of the retrievers inside a [`MultiRetriever`](multiretriever.mdx):
```python
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
)
from haystack.components.retrievers import (
InMemoryBM25Retriever,
InMemoryEmbeddingRetriever,
@@ -13,7 +13,7 @@ This is an embedding Retriever compatible with the Valkey Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`ChatPromptBuilder`](../builders/chatpromptbuilder.mdx) or [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`ChatPromptBuilder`](../builders/chatpromptbuilder.mdx) or [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [ValkeyDocumentStore](../../document-stores/valkeydocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -66,9 +66,15 @@ retriever.run(query_embedding=[0.1] * 768)
### In a Pipeline
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -13,7 +13,7 @@ An embedding-based Retriever compatible with the Vespa Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [VespaDocumentStore](../../document-stores/vespadocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A vector representing the query (a list of floats) |
| **Output variables** | `documents`: A list of documents |
@@ -48,6 +48,12 @@ pip install vespa-haystack
To run Vespa locally, see the [Vespa quick start](https://docs.vespa.ai/en/vespa-quick-start.html).
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
## Usage
### On its own
@@ -71,7 +77,7 @@ retriever.run(query_embedding=[0.1] * 768)
```python
from haystack import Document, Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
SentenceTransformersTextEmbedder,
)
@@ -13,7 +13,7 @@ This is an embedding Retriever compatible with the Weaviate Document Store.
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in the semantic search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [WeaviateDocumentStore](../../document-stores/weaviatedocumentstore.mdx) |
| **Mandatory run variables** | `query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents |
@@ -69,11 +69,17 @@ retriever.run(query_embedding=[0.1] * 768)
### In a Pipeline
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -13,7 +13,7 @@ A Retriever that combines BM25 keyword search and vector similarity to fetch doc
| | |
| --- | --- |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a Text Embedder and before an [`ExtractiveReader`](../readers/extractivereader.mdx) in an extractive QA pipeline |
| **Most common position in a pipeline** | 1. After a Text Embedder and before a [`PromptBuilder`](../builders/promptbuilder.mdx) in a RAG pipeline 2. The last component in a hybrid search pipeline 3. After a Text Embedder and before a [`TransformersExtractiveReader`](../readers/transformersextractivereader.mdx) in an extractive QA pipeline |
| **Mandatory init variables** | `document_store`: An instance of a [WeaviateDocumentStore](../../document-stores/weaviatedocumentstore.mdx) |
| **Mandatory run variables** | `query`: A string <br /> <br />`query_embedding`: A list of floats |
| **Output variables** | `documents`: A list of documents (matching the query) |
@@ -75,11 +75,17 @@ retriever.run(query="How many languages are there?", query_embedding=[0.1] * 768
### In a pipeline
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack.document_stores.types import DuplicatePolicy
from haystack import Document
from haystack import Pipeline
from haystack.components.embedders import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
SentenceTransformersDocumentEmbedder,
)
@@ -49,8 +49,16 @@ Below is an example of using `LLMMessagesRouter` to route Chat Messages to two
We use Llama Guard 4 for content moderation. To use this model with the Hugging Face API, you need to [request access](https://huggingface.co/meta-llama/Llama-Guard-4-12B) and set the `HF_TOKEN` environment variable.
The examples on this page use Hugging Face API components that have moved to the `huggingface-api-haystack` package. Install it to run the examples:
```shell
pip install huggingface-api-haystack
```
```python
from haystack.components.generators.chat import HuggingFaceAPIChatGenerator
from haystack_integrations.components.generators.huggingface_api import (
HuggingFaceAPIChatGenerator,
)
from haystack.components.routers.llm_messages_router import LLMMessagesRouter
from haystack.dataclasses import ChatMessage
@@ -129,9 +137,9 @@ from haystack import Document, Pipeline
from haystack.dataclasses import ChatMessage
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.builders import ChatPromptBuilder
from haystack.components.generators.chat import (
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack_integrations.components.generators.huggingface_api import (
HuggingFaceAPIChatGenerator,
OpenAIChatGenerator,
)
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.components.routers import LLMMessagesRouter
@@ -80,10 +80,18 @@ result = router.run(documents=streams)
Below is an example of an indexing pipeline that converts text files to documents and uses the `DocumentLanguageClassifier` to detect the language of the text and add it to the documents' metadata. It then uses the `MetadataRouter` to forward only English language documents to the `DocumentWriter`. Documents of other languages will not be added to the `DocumentStore`.
The examples on this page use language classification components that have moved to the `langdetect-haystack` package. Install it to run the examples:
```shell
pip install langdetect-haystack
```
```python
from haystack import Pipeline
from haystack.components.file_converters import TextFileToDocument
from haystack.components.classifiers import DocumentLanguageClassifier
from haystack_integrations.components.classifiers.langdetect import (
DocumentLanguageClassifier,
)
from haystack.components.routers import MetadataRouter
from haystack.components.writers import DocumentWriter
from haystack.document_stores.in_memory import InMemoryDocumentStore
@@ -55,12 +55,18 @@ We then create a retrieving pipeline with the `TransformersZeroShotTextRouter` t
Finally, the pipeline is executed with a sample text: "What is the capital of Germany?” which categorizes this input text as “query” and routes it to Query Embedder and subsequently Query Retriever to return the relevant results.
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.core.pipeline import Pipeline
from haystack_integrations.components.routers.transformers import TransformersZeroShotTextRouter
from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
from haystack.components.retrievers import InMemoryEmbeddingRetriever
document_store = InMemoryDocumentStore()
@@ -54,6 +54,12 @@ print(docs)
To best understand how can you use a `TopPSampler` and which components to pair it with, explore the following example.
The examples on this page use Sentence Transformers rankers and SerperDev web search component that have moved to the `sentence-transformers-haystack` and `serperdev-haystack` packages. Install them to run the examples:
```shell
pip install sentence-transformers-haystack serperdev-haystack
```
```python
# import necessary dependencies
from haystack import Pipeline
@@ -62,10 +68,12 @@ from haystack.components.fetchers import LinkContentFetcher
from haystack.components.converters import HTMLToDocument
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.preprocessors import DocumentSplitter
from haystack.components.rankers import SentenceTransformersSimilarityRanker
from haystack_integrations.components.rankers.sentence_transformers import (
SentenceTransformersSimilarityRanker,
)
from haystack.components.routers.file_type_router import FileTypeRouter
from haystack.components.samplers import TopPSampler
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
from haystack.dataclasses import ChatMessage
@@ -63,11 +63,19 @@ document_writer.run(documents=documents)
Below is an example of an indexing pipeline that first uses the `SentenceTransformersDocumentEmbedder` to create embeddings of documents and then use the `DocumentWriter` to write the documents to an `InMemoryDocumentStore`:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack.pipeline import Pipeline
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersDocumentEmbedder,
)
from haystack.components.writers import DocumentWriter
documents = [
+8 -2
View File
@@ -50,12 +50,18 @@ The recommended way to use `ComponentTool` in Haystack is with the [`Agent`](../
### With the Agent Component
The examples on this page use SerperDev web search component that have moved to the `serperdev-haystack` package. Install it to run the examples:
```shell
pip install serperdev-haystack
```
```python
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.tools import ComponentTool
from haystack.components.agents import Agent
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
# Create a SerperDev search component
@@ -88,7 +94,7 @@ You can also wire `ComponentTool` into a pipeline manually with `ChatGenerator`
```python
from haystack import Pipeline
from haystack.tools import ComponentTool
from haystack.components.websearch import SerperDevWebSearch
from haystack_integrations.components.websearch.serperdev import SerperDevWebSearch
from haystack.utils import Secret
from haystack.components.tools.tool_invoker import ToolInvoker
from haystack.components.generators.chat import OpenAIChatGenerator
+9 -8
View File
@@ -51,11 +51,17 @@ The recommended way to use `PipelineTool` in Haystack is with the [`Agent`](../p
You can create a `PipelineTool` from any existing Haystack pipeline:
The examples on this page use Sentence Transformers embedders that have moved to the `sentence-transformers-haystack` package. Install it to run the examples:
```shell
pip install sentence-transformers-haystack
```
```python
from haystack import Document, Pipeline
from haystack.tools import PipelineTool
from haystack.components.retrievers.in_memory import InMemoryBM25Retriever
from haystack.components.rankers.sentence_transformers_similarity import (
from haystack_integrations.components.rankers.sentence_transformers import (
SentenceTransformersSimilarityRanker,
)
from haystack.document_stores.in_memory import InMemoryDocumentStore
@@ -105,10 +111,8 @@ print(retrieval_tool)
from haystack import Document, Pipeline
from haystack.tools import PipelineTool
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders.sentence_transformers_text_embedder import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
)
from haystack.components.embedders.sentence_transformers_document_embedder import (
SentenceTransformersDocumentEmbedder,
)
from haystack.components.retrievers import InMemoryEmbeddingRetriever
@@ -173,10 +177,8 @@ You can also wire `PipelineTool` into a pipeline manually with `ChatGenerator` a
from haystack import Document, Pipeline
from haystack.tools import PipelineTool
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders.sentence_transformers_text_embedder import (
from haystack_integrations.components.embedders.sentence_transformers import (
SentenceTransformersTextEmbedder,
)
from haystack.components.embedders.sentence_transformers_document_embedder import (
SentenceTransformersDocumentEmbedder,
)
from haystack.components.retrievers import InMemoryEmbeddingRetriever
@@ -197,7 +199,6 @@ documents = [
content="He is best known for his contributions to the design of the modern alternating current (AC) electricity supply system.",
),
]
document_embedder.warm_up()
docs_with_embeddings = document_embedder.run(documents=documents)["documents"]
document_store.write_documents(docs_with_embeddings)
-21731
View File
File diff suppressed because it is too large Load Diff
@@ -446,6 +446,7 @@ print(documents[0].content)
__init__(
extraction_kwargs: dict[str, Any] | None = None,
store_full_path: bool = False,
encoding: str = "utf-8",
) -> None
```
@@ -458,6 +459,8 @@ Create an HTMLToDocument component.
the [Trafilatura documentation](https://trafilatura.readthedocs.io/en/latest/corefunctions.html#extract).
- **store_full_path** (<code>bool</code>) – If True, the full path of the file is stored in the metadata of the document.
If False, only the file name is stored.
- **encoding** (<code>str</code>) – The default encoding to use when converting HTML files. If the encoding is specified in the metadata of a
source ByteStream, it overrides this value.
#### to_dict
@@ -1060,6 +1063,7 @@ __init__(
table_to_single_line: bool = False,
progress_bar: bool = True,
store_full_path: bool = False,
encoding: str = "utf-8",
*,
extract_frontmatter: bool = False
) -> None
@@ -1073,6 +1077,8 @@ Create a MarkdownToDocument component.
- **progress_bar** (<code>bool</code>) – If True shows a progress bar when running.
- **store_full_path** (<code>bool</code>) – If True, the full path of the file is stored in the metadata of the document.
If False, only the file name is stored.
- **encoding** (<code>str</code>) – The default encoding to use when converting Markdown files. If the encoding is specified in the metadata
of a source ByteStream, it overrides this value.
- **extract_frontmatter** (<code>bool</code>) – If True, YAML frontmatter at the beginning of the Markdown file is
removed from the document content and added to the document metadata.
@@ -609,7 +609,7 @@ Creates an instance of FallbackChatGenerator.
to_dict() -> dict[str, Any]
```
Serialize the component, including nested chat generators when they support serialization.
Serialize the component, including nested chat generators.
#### from_dict
@@ -299,7 +299,9 @@ It supports different join modes:
```python
from haystack import Pipeline, Document
from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
# Requires: pip install sentence-transformers-haystack
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
from haystack.components.joiners import DocumentJoiner
from haystack.components.retrievers import InMemoryBM25Retriever
from haystack.components.retrievers import InMemoryEmbeddingRetriever
@@ -488,7 +488,8 @@ This component is inspired by [5 Levels of Text Splitting](https://github.com/Fu
```python
from haystack import Document
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
# Requires: pip install sentence-transformers-haystack
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
from haystack.components.preprocessors import EmbeddingBasedDocumentSplitter
# Create a document with content that has a clear topic shift
@@ -408,7 +408,9 @@ In query pipelines, use a TextEmbedder to embed queries and send them to the ret
```python
from haystack import Document
from haystack.components.embedders import SentenceTransformersDocumentEmbedder, SentenceTransformersTextEmbedder
# Requires: pip install sentence-transformers-haystack
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.document_stores.in_memory import InMemoryDocumentStore
@@ -575,8 +577,9 @@ The results are combined and sorted by relevance score.
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import SentenceTransformersTextEmbedder
from haystack.components.embedders import SentenceTransformersDocumentEmbedder
# Requires: pip install sentence-transformers-haystack
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
from haystack.components.retrievers import InMemoryEmbeddingRetriever
from haystack.components.writers import DocumentWriter
from haystack.components.retrievers import MultiQueryEmbeddingRetriever
@@ -878,7 +881,9 @@ from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.retrievers import InMemoryBM25Retriever, InMemoryEmbeddingRetriever
from haystack.components.retrievers import TextEmbeddingRetriever, MultiRetriever
from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
# Requires: pip install sentence-transformers-haystack
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
from haystack.components.writers import DocumentWriter
documents = [
@@ -922,7 +927,8 @@ __init__(
*,
retrievers: dict[str, TextRetriever],
filters: dict[str, Any] | None = None,
top_k: int = 10,
top_k_per_retriever: int | None = None,
top_k: int | None = None,
max_workers: int = 4,
join_mode: Literal[
"concatenate", "reciprocal_rank_fusion"
@@ -937,7 +943,12 @@ Create the MultiRetriever component.
- **retrievers** (<code>dict\[str, TextRetriever\]</code>) – A dictionary mapping names to text retrievers (implementing the `TextRetriever` protocol) to run in
parallel.
- **filters** (<code>dict\[str, Any\] | None</code>) – A dictionary of filters to apply when retrieving documents.
- **top_k** (<code>int</code>) – The maximum number of documents to return per retriever.
- **top_k_per_retriever** (<code>int | None</code>) – The maximum number of documents to return per retriever. If set, this will override the `top_k`
parameter for each retriever. If None, the `top_k` parameter of retrievers will be used.
- **top_k** (<code>int | None</code>) – The maximum number of documents to return overall, extracted from the combined results of all
retrievers. When set, the results are always merged using reciprocal rank fusion (regardless of
`join_mode`) so that the combined list has a consistent global ranking before it is truncated to
`top_k`. If None, all results are returned.
- **max_workers** (<code>int</code>) – The maximum number of threads to use for parallel retrieval.
- **join_mode** (<code>Literal['concatenate', 'reciprocal_rank_fusion']</code>) – How to merge results from multiple retrievers. Available modes:
- `concatenate`: Combines all results into a single list and deduplicates.
@@ -957,6 +968,7 @@ Warm up the retrievers if any has a warm_up method.
run(
query: str,
filters: dict[str, Any] | None = None,
top_k_per_retriever: int | None = None,
top_k: int | None = None,
*,
active_retrievers: list[str] | None = None
@@ -969,7 +981,13 @@ Runs retrievers in parallel on the given query and returns deduplicated results.
- **query** (<code>str</code>) – The query to run the retrievers on.
- **filters** (<code>dict\[str, Any\] | None</code>) – Filters to apply. Defaults to the value set at initialization.
- **top_k** (<code>int | None</code>) – Maximum documents to return per retriever. Defaults to the value set at initialization.
- **top_k_per_retriever** (<code>int | None</code>) – The maximum number of documents to return per retriever. When set, this will override the `top_k`
parameter for each retriever. If None, the `top_k` parameter set for retrievers will be used.
Defaults to the value set at initialization.
- **top_k** (<code>int | None</code>) – The maximum number of documents to return overall, extracted from the combined results of all
retrievers. When set, the results are always merged using reciprocal rank fusion (regardless of
`join_mode`) so that the combined list has a consistent global ranking before it is truncated to
`top_k`. If None, all results are returned. Defaults to the value set at initialization.
- **active_retrievers** (<code>list\[str\] | None</code>) – Names of retrievers to run. Defaults to all. Must match keys in the `retrievers` dictionary.
**Returns:**
@@ -987,6 +1005,7 @@ Runs retrievers in parallel on the given query and returns deduplicated results.
run_async(
query: str,
filters: dict[str, Any] | None = None,
top_k_per_retriever: int | None = None,
top_k: int | None = None,
*,
active_retrievers: list[str] | None = None
@@ -1001,7 +1020,13 @@ Uses each retriever's `run_async` method if available, otherwise runs `run` in a
- **query** (<code>str</code>) – The query to run the retrievers on.
- **filters** (<code>dict\[str, Any\] | None</code>) – Filters to apply. Defaults to the value set at initialization.
- **top_k** (<code>int | None</code>) – Maximum documents to return per retriever. Defaults to the value set at initialization.
- **top_k_per_retriever** (<code>int | None</code>) – The maximum number of documents to return per retriever. When set, this will override the `top_k`
parameter for each retriever. If None, the `top_k` parameter set for retrievers will be used.
Defaults to the value set at initialization.
- **top_k** (<code>int | None</code>) – The maximum number of documents to return overall, extracted from the combined results of all
retrievers. When set, the results are always merged using reciprocal rank fusion (regardless of
`join_mode`) so that the combined list has a consistent global ranking before it is truncated to
`top_k`. If None, all results are returned. Defaults to the value set at initialization.
- **active_retrievers** (<code>list\[str\] | None</code>) – Names of retrievers to run. Defaults to all. Must match keys in the `retrievers` dictionary.
**Returns:**
@@ -1249,7 +1274,9 @@ The results are sorted by relevance score.
from haystack import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.document_stores.types import DuplicatePolicy
from haystack.components.embedders import SentenceTransformersTextEmbedder, SentenceTransformersDocumentEmbedder
# Requires: pip install sentence-transformers-haystack
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
from haystack.components.retrievers import InMemoryEmbeddingRetriever, TextEmbeddingRetriever
from haystack.components.writers import DocumentWriter
@@ -446,10 +446,9 @@ Below is an example of creating a PipelineTool
from haystack import Document, Pipeline
from haystack.dataclasses import ChatMessage
from haystack.document_stores.in_memory import InMemoryDocumentStore
from haystack.components.embedders.sentence_transformers_text_embedder import SentenceTransformersTextEmbedder
from haystack.components.embedders.sentence_transformers_document_embedder import (
SentenceTransformersDocumentEmbedder
)
# Requires: pip install sentence-transformers-haystack
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersTextEmbedder
from haystack_integrations.components.embedders.sentence_transformers import SentenceTransformersDocumentEmbedder
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.components.retrievers import InMemoryEmbeddingRetriever
from haystack.components.agents import Agent
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).
@@ -0,0 +1,288 @@
---
title: "Mirage"
id: integrations-mirage
description: "Mirage integration for Haystack"
slug: "/integrations-mirage"
---
## haystack_integrations.tools.mirage.shell_tool
### MirageShellTool
Bases: <code>Tool</code>
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
model.
### Security model
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
Agent can do:
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
should not change as read-only.
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
enforced against every command Mirage would execute, including commands nested inside
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
### Usage example
```python
from haystack.components.agents import Agent
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
workspace = MirageWorkspace([
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
])
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
print(result["messages"][-1].text)
```
#### __init__
```python
__init__(
workspace: MirageWorkspace,
*,
name: str = "mirage_shell",
description: str | None = None,
invocation_timeout: float = 60.0,
max_output_chars: int = 20000,
allowed_commands: list[str] | None = None,
denied_paths: list[str] | None = None
) -> None
```
Initialize the Mirage shell tool.
**Parameters:**
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
- **name** (<code>str</code>) – Tool name exposed to the LLM.
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
Mirage would execute -- including commands nested in substitutions/subshells -- so
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
virtual commands to steer the Agent, not a security sandbox; the write boundary is
per-mount `read_only` (see the class "Security model" section). If None, any command is
allowed (not recommended for untrusted/hosted use).
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
#### warm_up
```python
warm_up() -> None
```
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageShellTool
```
Deserialize the tool from a dictionary.
#### close
```python
close() -> None
```
Close the underlying workspace.
## haystack_integrations.tools.mirage.workspace
### MirageMount
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
and *how* to configure it (`config`).
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
live workspace is built.
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
```python
from haystack.utils import Secret
MirageMount(path="/data", resource="ram") # in-memory scratch
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
MirageMount(
path="/drive",
resource="gdrive",
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
read_only=True,
)
```
**Parameters:**
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
an OAuth token source that is turned into a token-provider callable when the workspace is built.
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
Mirage itself.
#### available_resources
```python
available_resources() -> list[str]
```
Return the Mirage registry names usable as `resource`.
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
config class.
### MirageWorkspace
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
build time), and constructs the live workspace on first use via Mirage's resource registry.
### Usage example
```python
from haystack.utils import Secret
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
ws = MirageWorkspace(
mounts=[
MirageMount(path="/data", resource="ram"),
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
]
)
print(ws.run("ls /s3"))
```
#### __init__
```python
__init__(
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
) -> None
```
Initialize the workspace description.
**Parameters:**
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
**Raises:**
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
#### warm_up
```python
warm_up() -> None
```
Build the live `mirage.Workspace` eagerly. Idempotent.
#### close
```python
close() -> None
```
Close the live workspace and release its resources, if it was built. Thread-safe.
#### run
```python
run(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Run a bash `command` against the mount tree from a synchronous context and return its output.
**Parameters:**
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
**Returns:**
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
#### run_async
```python
run_async(
command: str, *, timeout: float = 60.0, max_chars: int | None = None
) -> str
```
Async counterpart of :meth:`run`.
#### to_dict
```python
to_dict() -> dict[str, Any]
```
Serialize the workspace description to a dictionary (Secret-safe).
#### from_dict
```python
from_dict(data: dict[str, Any]) -> MirageWorkspace
```
Deserialize a workspace description from a dictionary.
#### describe
```python
describe() -> str
```
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).

Some files were not shown because too many files have changed in this diff Show More