feat: adopt directory-based docs versioning with Edge channel

Switch docs.crewai.com from navigation-only versioning (every version
selector entry rendered the same docs/<lang>/* source files) to
Mintlify's directory-based versioning so each version selector entry
renders its own snapshot. Add an "Edge" channel under docs/edge/<lang>/*
that always reflects main HEAD for unreleased work, eliminating
pre-release leakage onto frozen release labels. External links to
canonical /<lang>/* URLs are preserved via wildcard redirects that
always land on the current default version.

Layout:
- docs/edge/<lang>/*         rolling source (you edit here)
- docs/edge/enterprise-api.*.yaml
- docs/v<X.Y.Z>/<lang>/*     frozen, immutable snapshots
- docs/v<X.Y.Z>/enterprise-api.*.yaml
- docs/images/               shared, append-only
- docs/docs.json             nav + redirects

URLs follow the Mintlify-idiomatic shape: /edge/<lang>/<page> for
Edge, /v<X.Y.Z>/<lang>/<page> for every frozen snapshot. The wildcard
redirects /<lang>/:slug* -> /<default>/<lang>/:slug* keep stale links
working, and every freeze rewrites them (plus all per-section/per-page
redirects) so destinations always resolve to the current default
without depending on a second redirect hop.

Release flow integration (devtools release):
- New module crewai_devtools.docs_versioning.freeze() materialises
  docs/v<X.Y.Z>/ from docs/edge/, rewrites openapi: refs inside the
  snapshot, inserts the version into every language block in
  docs.json, and refreshes all redirect destinations.
- _update_docs_and_create_pr() in cli.py now calls that freeze during
  Phase 2 of devtools release. Edge changelogs are updated first (so
  the snapshot freeze picks them up), then the snapshot is staged
  alongside docs.json, branched as docs/freeze-v<X.Y.Z>, and the PR
  is titled [docs-freeze] docs: snapshot and changelog for v<X.Y.Z>
  — the title prefix the new CI guard reads.
- The PR still gates tag, GitHub release, PyPI publish, and the
  enterprise release as before; no new PRs are added.
- Pre-releases (1.X.YaN, 1.X.YbN, ...) skip the snapshot — they ride
  Edge — and the docs PR title omits the [docs-freeze] prefix.
- docs_check (AI-generated docs scaffolding) writes to
  docs/edge/<lang>/* so newly-generated unreleased docs land in Edge
  and never accidentally touch a frozen snapshot.

Migration scripts (one-shot):
- scripts/docs/freeze_historical_versions.py reconstructs all 16
  historical snapshots (v1.10.0 .. v1.14.7) from git tags via
  git archive | tar, rewriting openapi: MDX refs so each snapshot
  reads its own enterprise-api YAML rather than the live one.
- scripts/docs/prefix_version_paths.py one-shot-migrates docs.json:
  rewrites every page path in 16 versioned blocks to point under
  docs/v<X.Y.Z>/, inserts a new Edge entry per language, tags
  v1.14.7 as Latest (default), prunes pages whose target file
  doesn't exist in the snapshot (e.g. docs/ar/ didn't exist before
  v1.12.0), and writes the wildcard + per-section redirects.
- scripts/docs/freeze_current_edge.py is now a thin CLI wrapper
  around docs_versioning.freeze for manual one-off freezes (e.g.
  retroactively snapshotting a forgotten release).

CI guards (.github/workflows/docs-snapshots.yml):
- Frozen snapshots under docs/v[0-9]*/ are immutable; only PRs whose
  title contains [docs-freeze] (i.e. release-cut PRs generated by
  devtools release or the manual wrapper) may modify them.
- Images under docs/images/ are append-only since snapshots share a
  single image directory. Deleting or renaming an image breaks every
  historical snapshot that still references it.

Restored docs/images/crewai-otel-export.png from PR #3673; it was
deleted in PR #4908 but v1.10.0 / v1.10.1 snapshots still reference
it. Restoring instead of editing the snapshots preserves historical
rendering fidelity and validates the new append-only rule
retroactively.

Tests:
- lib/devtools/tests/test_docs_versioning.py covers the freeze: file
  copy, openapi rewrite, version insertion, default demotion, redirect
  upserts, per-section redirect rewriting, idempotency, and invalid
  inputs.

Verified locally with mintlify broken-links: 0 broken links across
the full site (Edge + 16 frozen versions, 4 locales).

AGENTS.md (repo root) is the contributor guide for the new model;
RELEASING.md is the release-cut runbook; README's Contribution
section links to both.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Lucas Gomide
2026-06-17 09:33:56 -03:00
parent 7bb9bc7e1a
commit 93dafe2637
15793 changed files with 3237032 additions and 16873 deletions

View File

@@ -0,0 +1,169 @@
---
title: MongoDB Vector Search Tool
description: The `MongoDBVectorSearchTool` performs vector search on MongoDB Atlas with optional indexing helpers.
icon: "leaf"
mode: "wide"
---
# `MongoDBVectorSearchTool`
## Description
Perform vector similarity queries on MongoDB Atlas collections. Supports index creation helpers and bulk insert of embedded texts.
MongoDB Atlas supports native vector search. Learn more:
https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-overview/
## Installation
Install with the MongoDB extra:
```shell
pip install crewai-tools[mongodb]
```
or
```shell
uv add crewai-tools --extra mongodb
```
## Parameters
### Initialization
- `connection_string` (str, required)
- `database_name` (str, required)
- `collection_name` (str, required)
- `vector_index_name` (str, default `vector_index`)
- `text_key` (str, default `text`)
- `embedding_key` (str, default `embedding`)
- `dimensions` (int, default `1536`)
### Run Parameters
- `query` (str, required): Natural language query to embed and search.
## Quick start
```python Code
from crewai_tools import MongoDBVectorSearchTool
tool = MongoDBVectorSearchTool(
connection_string="mongodb+srv://...",
database_name="mydb",
collection_name="docs",
)
print(tool.run(query="how to create vector index"))
```
## Index creation helpers
Use `create_vector_search_index(...)` to provision an Atlas Vector Search index with the correct dimensions and similarity.
## Common issues
- Authentication failures: ensure your Atlas IP Access List allows your runner and the connection string includes credentials.
- Index not found: create the vector index first; name must match `vector_index_name`.
- Dimensions mismatch: align embedding model dimensions with `dimensions`.
## More examples
### Basic initialization
```python Code
from crewai_tools import MongoDBVectorSearchTool
tool = MongoDBVectorSearchTool(
database_name="example_database",
collection_name="example_collection",
connection_string="<your_mongodb_connection_string>",
)
```
### Custom query configuration
```python Code
from crewai_tools import MongoDBVectorSearchConfig, MongoDBVectorSearchTool
query_config = MongoDBVectorSearchConfig(limit=10, oversampling_factor=2)
tool = MongoDBVectorSearchTool(
database_name="example_database",
collection_name="example_collection",
connection_string="<your_mongodb_connection_string>",
query_config=query_config,
vector_index_name="my_vector_index",
)
rag_agent = Agent(
name="rag_agent",
role="You are a helpful assistant that can answer questions with the help of the MongoDBVectorSearchTool.",
goal="...",
backstory="...",
tools=[tool],
)
```
### Preloading the database and creating the index
```python Code
import os
from crewai_tools import MongoDBVectorSearchTool
tool = MongoDBVectorSearchTool(
database_name="example_database",
collection_name="example_collection",
connection_string="<your_mongodb_connection_string>",
)
# Load text content from a local folder and add to MongoDB
texts = []
for fname in os.listdir("knowledge"):
path = os.path.join("knowledge", fname)
if os.path.isfile(path):
with open(path, "r", encoding="utf-8") as f:
texts.append(f.read())
tool.add_texts(texts)
# Create the Atlas Vector Search index (e.g., 3072 dims for text-embedding-3-large)
tool.create_vector_search_index(dimensions=3072)
```
## Example
```python Code
from crewai import Agent, Task, Crew
from crewai_tools import MongoDBVectorSearchTool
tool = MongoDBVectorSearchTool(
connection_string="mongodb+srv://...",
database_name="mydb",
collection_name="docs",
)
agent = Agent(
role="RAG Agent",
goal="Answer using MongoDB vector search",
backstory="Knowledge retrieval specialist",
tools=[tool],
verbose=True,
)
task = Task(
description="Find relevant content for 'indexing guidance'",
expected_output="A concise answer citing the most relevant matches",
agent=agent,
)
crew = Crew(
agents=[agent],
tasks=[task],
verbose=True,
)
result = crew.kickoff()
```

View File

@@ -0,0 +1,70 @@
---
title: MySQL RAG Search
description: The `MySQLSearchTool` is designed to search MySQL databases and return the most relevant results.
icon: database
mode: "wide"
---
## Overview
This tool is designed to facilitate semantic searches within MySQL database tables. Leveraging the RAG (Retrieve and Generate) technology,
the MySQLSearchTool provides users with an efficient means of querying database table content, specifically tailored for MySQL databases.
It simplifies the process of finding relevant data through semantic search queries, making it an invaluable resource for users needing
to perform advanced queries on extensive datasets within a MySQL database.
## Installation
To install the `crewai_tools` package and utilize the MySQLSearchTool, execute the following command in your terminal:
```shell
pip install 'crewai[tools]'
```
## Example
Below is an example showcasing how to use the MySQLSearchTool to conduct a semantic search on a table within a MySQL database:
```python Code
from crewai_tools import MySQLSearchTool
# Initialize the tool with the database URI and the target table name
tool = MySQLSearchTool(
db_uri='mysql://user:password@localhost:3306/mydatabase',
table_name='employees'
)
```
## Arguments
The MySQLSearchTool requires the following arguments for its operation:
- `db_uri`: A string representing the URI of the MySQL database to be queried. This argument is mandatory and must include the necessary authentication details and the location of the database.
- `table_name`: A string specifying the name of the table within the database on which the semantic search will be performed. This argument is mandatory.
## Custom model and embeddings
By default, the tool uses OpenAI for both embeddings and summarization. To customize the model, you can use a config dictionary as follows:
```python Code
tool = MySQLSearchTool(
config=dict(
llm=dict(
provider="ollama", # or google, openai, anthropic, llama2, ...
config=dict(
model="llama2",
# temperature=0.5,
# top_p=1,
# stream=true,
),
),
embedder=dict(
provider="google-generativeai",
config=dict(
model_name="gemini-embedding-001",
task_type="RETRIEVAL_DOCUMENT",
# title="Embeddings",
),
),
)
)
```

View File

@@ -0,0 +1,175 @@
---
title: NL2SQL Tool
description: The `NL2SQLTool` is designed to convert natural language to SQL queries.
icon: language
mode: "wide"
---
## Overview
This tool is used to convert natural language to SQL queries. When passed to the agent it will generate queries and then use them to interact with the database.
This enables multiple workflows like having an Agent to access the database fetch information based on the goal and then use the information to generate a response, report or any other output.
Along with that provides the ability for the Agent to update the database based on its goal.
**Attention**: By default the tool is read-only (SELECT/SHOW/DESCRIBE/EXPLAIN only). Write operations require `allow_dml=True` or the `CREWAI_NL2SQL_ALLOW_DML=true` environment variable. When write access is enabled, make sure the Agent uses a scoped database user or a read replica where possible.
## Security Model
`NL2SQLTool` is an execution-capable tool. It runs model-generated SQL directly against the configured database connection.
This means risk depends on your deployment choices:
- Which credentials you provide in `db_uri`
- Whether untrusted input can influence prompts
- Whether you add tool-call guardrails before execution
If you route untrusted input to agents using this tool, treat it as a high-risk integration.
## Hardening Recommendations
Use all of the following in production:
- Use a read-only database user whenever possible
- Prefer a read replica for analytics/retrieval workloads
- Grant least privilege (no superuser/admin roles, no file/system-level capabilities)
- Apply database-side resource limits (statement timeout, lock timeout, cost/row limits)
- Add `before_tool_call` hooks to enforce allowed query patterns
- Enable query logging and alerting for destructive statements
## Read-Only Mode & DML Configuration
`NL2SQLTool` operates in **read-only mode by default**. Only the following statement types are permitted without additional configuration:
- `SELECT`
- `SHOW`
- `DESCRIBE`
- `EXPLAIN`
Any attempt to execute a write operation (`INSERT`, `UPDATE`, `DELETE`, `DROP`, `CREATE`, `ALTER`, `TRUNCATE`, etc.) will raise an error unless DML is explicitly enabled.
Multi-statement queries containing semicolons (e.g. `SELECT 1; DROP TABLE users`) are also blocked in read-only mode to prevent injection attacks.
### Enabling Write Operations
You can enable DML (Data Manipulation Language) in two ways:
**Option 1 — constructor parameter:**
```python
from crewai_tools import NL2SQLTool
nl2sql = NL2SQLTool(
db_uri="postgresql://example@localhost:5432/test_db",
allow_dml=True,
)
```
**Option 2 — environment variable:**
```bash
CREWAI_NL2SQL_ALLOW_DML=true
```
```python
from crewai_tools import NL2SQLTool
# DML enabled via environment variable
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")
```
### Usage Examples
**Read-only (default) — safe for analytics and reporting:**
```python
from crewai_tools import NL2SQLTool
# Only SELECT/SHOW/DESCRIBE/EXPLAIN are permitted
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")
```
**DML enabled — required for write workloads:**
```python
from crewai_tools import NL2SQLTool
# INSERT, UPDATE, DELETE, DROP, etc. are permitted
nl2sql = NL2SQLTool(
db_uri="postgresql://example@localhost:5432/test_db",
allow_dml=True,
)
```
<Warning>
Enabling DML gives the agent the ability to modify or destroy data. Only enable this when your use case explicitly requires write access, and ensure the database credentials are scoped to the minimum required privileges.
</Warning>
## Requirements
- SqlAlchemy
- Any DB compatible library (e.g. psycopg2, mysql-connector-python)
## Installation
Install the crewai_tools package
```shell
pip install 'crewai[tools]'
```
## Usage
In order to use the NL2SQLTool, you need to pass the database URI to the tool. The URI should be in the format `dialect+driver://username:password@host:port/database`.
```python Code
from crewai_tools import NL2SQLTool
# psycopg2 was installed to run this example with PostgreSQL
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")
@agent
def researcher(self) -> Agent:
return Agent(
config=self.agents_config["researcher"],
allow_delegation=False,
tools=[nl2sql]
)
```
## Example
The primary task goal was:
"Retrieve the average, maximum, and minimum monthly revenue for each city, but only include cities that have more than one user. Also, count the number of user in each city and
sort the results by the average monthly revenue in descending order"
So the Agent tried to get information from the DB, the first one is wrong so the Agent tries again and gets the correct information and passes to the next agent.
![alt text](https://github.com/crewAIInc/crewAI-tools/blob/main/crewai_tools/tools/nl2sql/images/image-2.png?raw=true)
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-3.png)
The second task goal was:
"Review the data and create a detailed report, and then create the table on the database with the fields based on the data provided.
Include information on the average, maximum, and minimum monthly revenue for each city, but only include cities that have more than one user. Also, count the number of users in each city and sort the results by the average monthly revenue in descending order."
Now things start to get interesting, the Agent generates the SQL query to not only create the table but also insert the data into the table. And in the end the Agent still returns the final report which is exactly what was in the database.
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-4.png)
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-5.png)
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-9.png)
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-7.png)
This is a simple example of how the NL2SQLTool can be used to interact with the database and generate reports based on the data in the database.
The Tool provides endless possibilities on the logic of the Agent and how it can interact with the database.
```md
DB -> Agent -> ... -> Agent -> DB
```

View File

@@ -0,0 +1,66 @@
---
title: "Overview"
description: "Connect to databases, vector stores, and data warehouses for comprehensive data access"
icon: "face-smile"
mode: "wide"
---
These tools enable your agents to interact with various database systems, from traditional SQL databases to modern vector stores and data warehouses.
## **Available Tools**
<CardGroup cols={2}>
<Card title="MySQL Tool" icon="database" href="/en/tools/database-data/mysqltool">
Connect to and query MySQL databases with SQL operations.
</Card>
<Card title="PostgreSQL Search" icon="elephant" href="/en/tools/database-data/pgsearchtool">
Search and query PostgreSQL databases efficiently.
</Card>
<Card title="Snowflake Search" icon="snowflake" href="/en/tools/database-data/snowflakesearchtool">
Access Snowflake data warehouse for analytics and reporting.
</Card>
<Card title="NL2SQL Tool" icon="language" href="/en/tools/database-data/nl2sqltool">
Convert natural language queries to SQL statements automatically.
</Card>
<Card title="Qdrant Vector Search" icon="vector-square" href="/en/tools/database-data/qdrantvectorsearchtool">
Search vector embeddings using Qdrant vector database.
</Card>
<Card title="Weaviate Vector Search" icon="network-wired" href="/en/tools/database-data/weaviatevectorsearchtool">
Perform semantic search with Weaviate vector database.
</Card>
<Card title="MongoDB Vector Search" icon="leaf" href="/en/tools/database-data/mongodbvectorsearchtool">
Vector similarity search on MongoDB Atlas with indexing helpers.
</Card>
<Card title="SingleStore Search" icon="database" href="/en/tools/database-data/singlestoresearchtool">
Safe SELECT/SHOW queries on SingleStore with pooling and validation.
</Card>
</CardGroup>
## **Common Use Cases**
- **Data Analysis**: Query databases for business intelligence and reporting
- **Vector Search**: Find similar content using semantic embeddings
- **ETL Operations**: Extract, transform, and load data between systems
- **Real-time Analytics**: Access live data for decision making
```python
from crewai_tools import MySQLTool, QdrantVectorSearchTool, NL2SQLTool
# Create database tools
mysql_db = MySQLTool()
vector_search = QdrantVectorSearchTool()
nl_to_sql = NL2SQLTool()
# Add to your agent
agent = Agent(
role="Data Analyst",
tools=[mysql_db, vector_search, nl_to_sql],
goal="Extract insights from various data sources"
)

View File

@@ -0,0 +1,83 @@
---
title: PG RAG Search
description: The `PGSearchTool` is designed to search PostgreSQL databases and return the most relevant results.
icon: elephant
mode: "wide"
---
## Overview
<Note>
The PGSearchTool is currently under development. This document outlines the intended functionality and interface.
As development progresses, please be aware that some features may not be available or could change.
</Note>
## Description
The PGSearchTool is envisioned as a powerful tool for facilitating semantic searches within PostgreSQL database tables. By leveraging advanced Retrieve and Generate (RAG) technology,
it aims to provide an efficient means for querying database table content, specifically tailored for PostgreSQL databases.
The tool's goal is to simplify the process of finding relevant data through semantic search queries, offering a valuable resource for users needing to conduct advanced queries on
extensive datasets within a PostgreSQL environment.
## Installation
The `crewai_tools` package, which will include the PGSearchTool upon its release, can be installed using the following command:
```shell
pip install 'crewai[tools]'
```
<Note>
The PGSearchTool is not yet available in the current version of the `crewai_tools` package. This installation command will be updated once the tool is released.
</Note>
## Example Usage
Below is a proposed example showcasing how to use the PGSearchTool for conducting a semantic search on a table within a PostgreSQL database:
```python Code
from crewai_tools import PGSearchTool
# Initialize the tool with the database URI and the target table name
tool = PGSearchTool(
db_uri='postgresql://user:password@localhost:5432/mydatabase',
table_name='employees'
)
```
## Arguments
The PGSearchTool is designed to require the following arguments for its operation:
| Argument | Type | Description |
|:---------------|:---------|:-------------------------------------------------------------------------------------------------------------------------------------|
| **db_uri** | `string` | **Mandatory**. A string representing the URI of the PostgreSQL database to be queried. This argument will be mandatory and must include the necessary authentication details and the location of the database. |
| **table_name** | `string` | **Mandatory**. A string specifying the name of the table within the database on which the semantic search will be performed. This argument will also be mandatory. |
## Custom Model and Embeddings
The tool intends to use OpenAI for both embeddings and summarization by default. Users will have the option to customize the model using a config dictionary as follows:
```python Code
tool = PGSearchTool(
config=dict(
llm=dict(
provider="ollama", # or google, openai, anthropic, llama2, ...
config=dict(
model="llama2",
# temperature=0.5,
# top_p=1,
# stream=true,
),
),
embedder=dict(
provider="google-generativeai", # or openai, ollama, ...
config=dict(
model_name="gemini-embedding-001",
task_type="RETRIEVAL_DOCUMENT",
# title="Embeddings",
),
),
)
)
```

View File

@@ -0,0 +1,343 @@
---
title: 'Qdrant Vector Search Tool'
description: 'Semantic search capabilities for CrewAI agents using Qdrant vector database'
icon: vector-square
mode: "wide"
---
## Overview
The Qdrant Vector Search Tool enables semantic search capabilities in your CrewAI agents by leveraging [Qdrant](https://qdrant.tech/), a vector similarity search engine. This tool allows your agents to search through documents stored in a Qdrant collection using semantic similarity.
## Installation
Install the required packages:
```bash
uv add qdrant-client
```
## Basic Usage
Here's a minimal example of how to use the tool:
```python
from crewai import Agent
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
# Initialize the tool with QdrantConfig
qdrant_tool = QdrantVectorSearchTool(
qdrant_config=QdrantConfig(
qdrant_url="your_qdrant_url",
qdrant_api_key="your_qdrant_api_key",
collection_name="your_collection"
)
)
# Create an agent that uses the tool
agent = Agent(
role="Research Assistant",
goal="Find relevant information in documents",
tools=[qdrant_tool]
)
# The tool will automatically use OpenAI embeddings
# and return the 3 most relevant results with scores > 0.35
```
## Complete Working Example
Here's a complete example showing how to:
1. Extract text from a PDF
2. Generate embeddings using OpenAI
3. Store in Qdrant
4. Create a CrewAI agentic RAG workflow for semantic search
```python
import os
import uuid
import pdfplumber
from openai import OpenAI
from dotenv import load_dotenv
from crewai import Agent, Task, Crew, Process, LLM
from crewai_tools import QdrantVectorSearchTool
from qdrant_client import QdrantClient
from qdrant_client.models import PointStruct, Distance, VectorParams
# Load environment variables
load_dotenv()
# Initialize OpenAI client
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# Extract text from PDF
def extract_text_from_pdf(pdf_path):
text = []
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
page_text = page.extract_text()
if page_text:
text.append(page_text.strip())
return text
# Generate OpenAI embeddings
def get_openai_embedding(text):
response = client.embeddings.create(
input=text,
model="text-embedding-3-large"
)
return response.data[0].embedding
# Store text and embeddings in Qdrant
def load_pdf_to_qdrant(pdf_path, qdrant, collection_name):
# Extract text from PDF
text_chunks = extract_text_from_pdf(pdf_path)
# Create Qdrant collection
if qdrant.collection_exists(collection_name):
qdrant.delete_collection(collection_name)
qdrant.create_collection(
collection_name=collection_name,
vectors_config=VectorParams(size=3072, distance=Distance.COSINE)
)
# Store embeddings
points = []
for chunk in text_chunks:
embedding = get_openai_embedding(chunk)
points.append(PointStruct(
id=str(uuid.uuid4()),
vector=embedding,
payload={"text": chunk}
))
qdrant.upsert(collection_name=collection_name, points=points)
# Initialize Qdrant client and load data
qdrant = QdrantClient(
url=os.getenv("QDRANT_URL"),
api_key=os.getenv("QDRANT_API_KEY")
)
collection_name = "example_collection"
pdf_path = "path/to/your/document.pdf"
load_pdf_to_qdrant(pdf_path, qdrant, collection_name)
# Initialize Qdrant search tool
from crewai_tools import QdrantConfig
qdrant_tool = QdrantVectorSearchTool(
qdrant_config=QdrantConfig(
qdrant_url=os.getenv("QDRANT_URL"),
qdrant_api_key=os.getenv("QDRANT_API_KEY"),
collection_name=collection_name,
limit=3,
score_threshold=0.35
)
)
# Create CrewAI agents
search_agent = Agent(
role="Senior Semantic Search Agent",
goal="Find and analyze documents based on semantic search",
backstory="""You are an expert research assistant who can find relevant
information using semantic search in a Qdrant database.""",
tools=[qdrant_tool],
verbose=True
)
answer_agent = Agent(
role="Senior Answer Assistant",
goal="Generate answers to questions based on the context provided",
backstory="""You are an expert answer assistant who can generate
answers to questions based on the context provided.""",
tools=[qdrant_tool],
verbose=True
)
# Define tasks
search_task = Task(
description="""Search for relevant documents about the {query}.
Your final answer should include:
- The relevant information found
- The similarity scores of the results
- The metadata of the relevant documents""",
agent=search_agent
)
answer_task = Task(
description="""Given the context and metadata of relevant documents,
generate a final answer based on the context.""",
agent=answer_agent
)
# Run CrewAI workflow
crew = Crew(
agents=[search_agent, answer_agent],
tasks=[search_task, answer_task],
process=Process.sequential,
verbose=True
)
result = crew.kickoff(
inputs={"query": "What is the role of X in the document?"}
)
print(result)
```
## Tool Parameters
### Required Parameters
- `qdrant_config` (QdrantConfig): Configuration object containing all Qdrant settings
### QdrantConfig Parameters
- `qdrant_url` (str): The URL of your Qdrant server
- `qdrant_api_key` (str, optional): API key for authentication with Qdrant
- `collection_name` (str): Name of the Qdrant collection to search
- `limit` (int): Maximum number of results to return (default: 3)
- `score_threshold` (float): Minimum similarity score threshold (default: 0.35)
- `filter` (Any, optional): Qdrant Filter instance for advanced filtering (default: None)
### Optional Tool Parameters
- `custom_embedding_fn` (Callable[[str], list[float]]): Custom function for text vectorization
- `qdrant_package` (str): Base package path for Qdrant (default: "qdrant_client")
- `client` (Any): Pre-initialized Qdrant client (optional)
## Advanced Filtering
The QdrantVectorSearchTool supports powerful filtering capabilities to refine your search results:
### Dynamic Filtering
Use `filter_by` and `filter_value` parameters in your search to filter results on-the-fly:
```python
# Agent will use these parameters when calling the tool
# The tool schema accepts filter_by and filter_value
# Example: search with category filter
# Results will be filtered where category == "technology"
```
### Preset Filters with QdrantConfig
For complex filtering, use Qdrant Filter instances in your configuration:
```python
from qdrant_client.http import models as qmodels
from crewai_tools import QdrantVectorSearchTool, QdrantConfig
# Create a filter for specific conditions
preset_filter = qmodels.Filter(
must=[
qmodels.FieldCondition(
key="category",
match=qmodels.MatchValue(value="research")
),
qmodels.FieldCondition(
key="year",
match=qmodels.MatchValue(value=2024)
)
]
)
# Initialize tool with preset filter
qdrant_tool = QdrantVectorSearchTool(
qdrant_config=QdrantConfig(
qdrant_url="your_url",
qdrant_api_key="your_key",
collection_name="your_collection",
filter=preset_filter # Preset filter applied to all searches
)
)
```
### Combining Filters
The tool automatically combines preset filters from `QdrantConfig` with dynamic filters from `filter_by` and `filter_value`:
```python
# If QdrantConfig has a preset filter for category="research"
# And the search uses filter_by="year", filter_value=2024
# Both filters will be combined (AND logic)
```
## Search Parameters
The tool accepts these parameters in its schema:
- `query` (str): The search query to find similar documents
- `filter_by` (str, optional): Metadata field to filter on
- `filter_value` (Any, optional): Value to filter by
## Return Format
The tool returns results in JSON format:
```json
[
{
"metadata": {
// Any metadata stored with the document
},
"context": "The actual text content of the document",
"distance": 0.95 // Similarity score
}
]
```
## Default Embedding
By default, the tool uses OpenAI's `text-embedding-3-large` model for vectorization. This requires:
- OpenAI API key set in environment: `OPENAI_API_KEY`
## Custom Embeddings
Instead of using the default embedding model, you might want to use your own embedding function in cases where you:
1. Want to use a different embedding model (e.g., Cohere, HuggingFace, Ollama models)
2. Need to reduce costs by using open-source embedding models
3. Have specific requirements for vector dimensions or embedding quality
4. Want to use domain-specific embeddings (e.g., for medical or legal text)
Here's an example using a HuggingFace model:
```python
from transformers import AutoTokenizer, AutoModel
import torch
# Load model and tokenizer
tokenizer = AutoTokenizer.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
model = AutoModel.from_pretrained('sentence-transformers/all-MiniLM-L6-v2')
def custom_embeddings(text: str) -> list[float]:
# Tokenize and get model outputs
inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
outputs = model(**inputs)
# Use mean pooling to get text embedding
embeddings = outputs.last_hidden_state.mean(dim=1)
# Convert to list of floats and return
return embeddings[0].tolist()
# Use custom embeddings with the tool
from crewai_tools import QdrantConfig
tool = QdrantVectorSearchTool(
qdrant_config=QdrantConfig(
qdrant_url="your_url",
qdrant_api_key="your_key",
collection_name="your_collection"
),
custom_embedding_fn=custom_embeddings # Pass your custom function
)
```
## Error Handling
The tool handles these specific errors:
- Raises ImportError if `qdrant-client` is not installed (with option to auto-install)
- Raises ValueError if `QDRANT_URL` is not set
- Prompts to install `qdrant-client` if missing using `uv add qdrant-client`
## Environment Variables
Required environment variables:
```bash
export QDRANT_URL="your_qdrant_url" # If not provided in constructor
export QDRANT_API_KEY="your_api_key" # If not provided in constructor
export OPENAI_API_KEY="your_openai_key" # If using default embeddings

View File

@@ -0,0 +1,62 @@
---
title: SingleStore Search Tool
description: The `SingleStoreSearchTool` safely executes SELECT/SHOW queries on SingleStore with pooling.
icon: circle
mode: "wide"
---
# `SingleStoreSearchTool`
## Description
Execute readonly queries (`SELECT`/`SHOW`) against SingleStore with connection pooling and input validation.
## Installation
```shell
uv add crewai-tools[singlestore]
```
## Environment Variables
Variables like `SINGLESTOREDB_HOST`, `SINGLESTOREDB_USER`, `SINGLESTOREDB_PASSWORD`, etc., can be used, or `SINGLESTOREDB_URL` as a single DSN.
Generate the API key from the SingleStore dashboard, [docs here](https://docs.singlestore.com/cloud/reference/management-api/#generate-an-api-key).
## Example
```python Code
from crewai import Agent, Task, Crew
from crewai_tools import SingleStoreSearchTool
tool = SingleStoreSearchTool(
tables=["products"],
host="host",
user="user",
password="pass",
database="db",
)
agent = Agent(
role="Analyst",
goal="Query SingleStore",
tools=[tool],
verbose=True,
)
task = Task(
description="List 5 products",
expected_output="5 rows as JSON/text",
agent=agent,
)
crew = Crew(
agents=[agent],
tasks=[task],
verbose=True,
)
result = crew.kickoff()
```

View File

@@ -0,0 +1,203 @@
---
title: Snowflake Search Tool
description: The `SnowflakeSearchTool` enables CrewAI agents to execute SQL queries and perform semantic search on Snowflake data warehouses.
icon: snowflake
mode: "wide"
---
# `SnowflakeSearchTool`
## Description
The `SnowflakeSearchTool` is designed to connect to Snowflake data warehouses and execute SQL queries with advanced features like connection pooling, retry logic, and asynchronous execution. This tool allows CrewAI agents to interact with Snowflake databases, making it ideal for data analysis, reporting, and business intelligence tasks that require access to enterprise data stored in Snowflake.
## Installation
To use this tool, you need to install the required dependencies:
```shell
uv add cryptography snowflake-connector-python snowflake-sqlalchemy
```
Or alternatively:
```shell
uv sync --extra snowflake
```
## Steps to Get Started
To effectively use the `SnowflakeSearchTool`, follow these steps:
1. **Install Dependencies**: Install the required packages using one of the commands above.
2. **Configure Snowflake Connection**: Create a `SnowflakeConfig` object with your Snowflake credentials.
3. **Initialize the Tool**: Create an instance of the tool with the necessary configuration.
4. **Execute Queries**: Use the tool to run SQL queries against your Snowflake database.
## Example
The following example demonstrates how to use the `SnowflakeSearchTool` to query data from a Snowflake database:
```python Code
from crewai import Agent, Task, Crew
from crewai_tools import SnowflakeSearchTool, SnowflakeConfig
# Create Snowflake configuration
config = SnowflakeConfig(
account="your_account",
user="your_username",
password="your_password",
warehouse="COMPUTE_WH",
database="your_database",
snowflake_schema="your_schema"
)
# Initialize the tool
snowflake_tool = SnowflakeSearchTool(config=config)
# Define an agent that uses the tool
data_analyst_agent = Agent(
role="Data Analyst",
goal="Analyze data from Snowflake database",
backstory="An expert data analyst who can extract insights from enterprise data.",
tools=[snowflake_tool],
verbose=True,
)
# Example task to query sales data
query_task = Task(
description="Query the sales data for the last quarter and summarize the top 5 products by revenue.",
expected_output="A summary of the top 5 products by revenue for the last quarter.",
agent=data_analyst_agent,
)
# Create and run the crew
crew = Crew(agents=[data_analyst_agent],
tasks=[query_task])
result = crew.kickoff()
```
You can also customize the tool with additional parameters:
```python Code
# Initialize the tool with custom parameters
snowflake_tool = SnowflakeSearchTool(
config=config,
pool_size=10,
max_retries=5,
retry_delay=2.0,
enable_caching=True
)
```
## Parameters
### SnowflakeConfig Parameters
The `SnowflakeConfig` class accepts the following parameters:
- **account**: Required. Snowflake account identifier.
- **user**: Required. Snowflake username.
- **password**: Optional*. Snowflake password.
- **private_key_path**: Optional*. Path to private key file (alternative to password).
- **warehouse**: Required. Snowflake warehouse name.
- **database**: Required. Default database.
- **snowflake_schema**: Required. Default schema.
- **role**: Optional. Snowflake role.
- **session_parameters**: Optional. Custom session parameters as a dictionary.
*Either `password` or `private_key_path` must be provided.
### SnowflakeSearchTool Parameters
The `SnowflakeSearchTool` accepts the following parameters during initialization:
- **config**: Required. A `SnowflakeConfig` object containing connection details.
- **pool_size**: Optional. Number of connections in the pool. Default is 5.
- **max_retries**: Optional. Maximum retry attempts for failed queries. Default is 3.
- **retry_delay**: Optional. Delay between retries in seconds. Default is 1.0.
- **enable_caching**: Optional. Whether to enable query result caching. Default is True.
## Usage
When using the `SnowflakeSearchTool`, you need to provide the following parameters:
- **query**: Required. The SQL query to execute.
- **database**: Optional. Override the default database specified in the config.
- **snowflake_schema**: Optional. Override the default schema specified in the config.
- **timeout**: Optional. Query timeout in seconds. Default is 300.
The tool will return the query results as a list of dictionaries, where each dictionary represents a row with column names as keys.
```python Code
# Example of using the tool with an agent
data_analyst = Agent(
role="Data Analyst",
goal="Analyze sales data from Snowflake",
backstory="An expert data analyst with experience in SQL and data visualization.",
tools=[snowflake_tool],
verbose=True
)
# The agent will use the tool with parameters like:
# query="SELECT product_name, SUM(revenue) as total_revenue FROM sales GROUP BY product_name ORDER BY total_revenue DESC LIMIT 5"
# timeout=600
# Create a task for the agent
analysis_task = Task(
description="Query the sales database and identify the top 5 products by revenue for the last quarter.",
expected_output="A detailed analysis of the top 5 products by revenue.",
agent=data_analyst
)
# Run the task
crew = Crew(
agents=[data_analyst],
tasks=[analysis_task]
)
result = crew.kickoff()
```
## Advanced Features
### Connection Pooling
The `SnowflakeSearchTool` implements connection pooling to improve performance by reusing database connections. You can control the pool size with the `pool_size` parameter.
### Automatic Retries
The tool automatically retries failed queries with exponential backoff. You can configure the retry behavior with the `max_retries` and `retry_delay` parameters.
### Query Result Caching
To improve performance for repeated queries, the tool can cache query results. This feature is enabled by default but can be disabled by setting `enable_caching=False`.
### Key-Pair Authentication
In addition to password authentication, the tool supports key-pair authentication for enhanced security:
```python Code
config = SnowflakeConfig(
account="your_account",
user="your_username",
private_key_path="/path/to/your/private/key.p8",
warehouse="COMPUTE_WH",
database="your_database",
snowflake_schema="your_schema"
)
```
## Error Handling
The `SnowflakeSearchTool` includes comprehensive error handling for common Snowflake issues:
- Connection failures
- Query timeouts
- Authentication errors
- Database and schema errors
When an error occurs, the tool will attempt to retry the operation (if configured) and provide detailed error information.
## Conclusion
The `SnowflakeSearchTool` provides a powerful way to integrate Snowflake data warehouses with CrewAI agents. With features like connection pooling, automatic retries, and query caching, it enables efficient and reliable access to enterprise data. This tool is particularly useful for data analysis, reporting, and business intelligence tasks that require access to structured data stored in Snowflake.

View File

@@ -0,0 +1,169 @@
---
title: Weaviate Vector Search
description: The `WeaviateVectorSearchTool` is designed to search a Weaviate vector database for semantically similar documents using hybrid search.
icon: network-wired
mode: "wide"
---
## Overview
The `WeaviateVectorSearchTool` is specifically crafted for conducting semantic searches within documents stored in a Weaviate vector database. This tool allows you to find semantically similar documents to a given query, leveraging the power of vector and keyword search for more accurate and contextually relevant search results.
[Weaviate](https://weaviate.io/) is a vector database that stores and queries vector embeddings, enabling semantic search capabilities.
## Installation
To incorporate this tool into your project, you need to install the Weaviate client:
```shell
uv add weaviate-client
```
## Steps to Get Started
To effectively use the `WeaviateVectorSearchTool`, follow these steps:
1. **Package Installation**: Confirm that the `crewai[tools]` and `weaviate-client` packages are installed in your Python environment.
2. **Weaviate Setup**: Set up a Weaviate cluster. You can follow the [Weaviate documentation](https://weaviate.io/developers/wcs/manage-clusters/connect) for instructions.
3. **API Keys**: Obtain your Weaviate cluster URL and API key.
4. **OpenAI API Key**: Ensure you have an OpenAI API key set in your environment variables as `OPENAI_API_KEY`.
## Example
The following example demonstrates how to initialize the tool and execute a search:
```python Code
from crewai_tools import WeaviateVectorSearchTool
# Initialize the tool
tool = WeaviateVectorSearchTool(
collection_name='example_collections',
limit=3,
alpha=0.75,
weaviate_cluster_url="https://your-weaviate-cluster-url.com",
weaviate_api_key="your-weaviate-api-key",
)
@agent
def search_agent(self) -> Agent:
'''
This agent uses the WeaviateVectorSearchTool to search for
semantically similar documents in a Weaviate vector database.
'''
return Agent(
config=self.agents_config["search_agent"],
tools=[tool]
)
```
## Parameters
The `WeaviateVectorSearchTool` accepts the following parameters:
- **collection_name**: Required. The name of the collection to search within.
- **weaviate_cluster_url**: Required. The URL of the Weaviate cluster.
- **weaviate_api_key**: Required. The API key for the Weaviate cluster.
- **limit**: Optional. The number of results to return. Default is `3`.
- **alpha**: Optional. Controls the weighting between vector and keyword (BM25) search. alpha = 0 -> BM25 only, alpha = 1 -> vector search only. Default is `0.75`.
- **vectorizer**: Optional. The vectorizer to use. If not provided, it will use `text2vec_openai` with the `nomic-embed-text` model.
- **generative_model**: Optional. The generative model to use. If not provided, it will use OpenAI's `gpt-4o`.
## Advanced Configuration
You can customize the vectorizer and generative model used by the tool:
```python Code
from crewai_tools import WeaviateVectorSearchTool
from weaviate.classes.config import Configure
# Setup custom model for vectorizer and generative model
tool = WeaviateVectorSearchTool(
collection_name='example_collections',
limit=3,
alpha=0.75,
vectorizer=Configure.Vectorizer.text2vec_openai(model="nomic-embed-text"),
generative_model=Configure.Generative.openai(model="gpt-4o-mini"),
weaviate_cluster_url="https://your-weaviate-cluster-url.com",
weaviate_api_key="your-weaviate-api-key",
)
```
## Preloading Documents
You can preload your Weaviate database with documents before using the tool:
```python Code
import os
from crewai_tools import WeaviateVectorSearchTool
import weaviate
from weaviate.classes.init import Auth
# Connect to Weaviate
client = weaviate.connect_to_weaviate_cloud(
cluster_url="https://your-weaviate-cluster-url.com",
auth_credentials=Auth.api_key("your-weaviate-api-key"),
headers={"X-OpenAI-Api-Key": "your-openai-api-key"}
)
# Get or create collection
test_docs = client.collections.get("example_collections")
if not test_docs:
test_docs = client.collections.create(
name="example_collections",
vectorizer_config=Configure.Vectorizer.text2vec_openai(model="nomic-embed-text"),
generative_config=Configure.Generative.openai(model="gpt-4o"),
)
# Load documents
docs_to_load = os.listdir("knowledge")
with test_docs.batch.dynamic() as batch:
for d in docs_to_load:
with open(os.path.join("knowledge", d), "r") as f:
content = f.read()
batch.add_object(
{
"content": content,
"year": d.split("_")[0],
}
)
# Initialize the tool
tool = WeaviateVectorSearchTool(
collection_name='example_collections',
limit=3,
alpha=0.75,
weaviate_cluster_url="https://your-weaviate-cluster-url.com",
weaviate_api_key="your-weaviate-api-key",
)
```
## Agent Integration Example
Here's how to integrate the `WeaviateVectorSearchTool` with a CrewAI agent:
```python Code
from crewai import Agent
from crewai_tools import WeaviateVectorSearchTool
# Initialize the tool
weaviate_tool = WeaviateVectorSearchTool(
collection_name='example_collections',
limit=3,
alpha=0.75,
weaviate_cluster_url="https://your-weaviate-cluster-url.com",
weaviate_api_key="your-weaviate-api-key",
)
# Create an agent with the tool
rag_agent = Agent(
name="rag_agent",
role="You are a helpful assistant that can answer questions with the help of the WeaviateVectorSearchTool.",
llm="gpt-4o-mini",
tools=[weaviate_tool],
)
```
## Conclusion
The `WeaviateVectorSearchTool` provides a powerful way to search for semantically similar documents in a Weaviate vector database. By leveraging vector embeddings, it enables more accurate and contextually relevant search results compared to traditional keyword-based searches. This tool is particularly useful for applications that require finding information based on meaning rather than exact matches.