Files
crewAI/crewai_tools/tools/ai_mind_tool/ai_mind_tool.py
Greyson Lalonde e16606672a Squashed 'packages/tools/' content from commit 78317b9c
git-subtree-dir: packages/tools
git-subtree-split: 78317b9c127f18bd040c1d77e3c0840cdc9a5b38
2025-09-12 21:58:02 -04:00

92 lines
3.2 KiB
Python

import os
import secrets
from typing import Any, Dict, List, Optional, Type
from crewai.tools import BaseTool, EnvVar
from openai import OpenAI
from pydantic import BaseModel, Field
class AIMindToolConstants:
MINDS_API_BASE_URL = "https://mdb.ai/"
MIND_NAME_PREFIX = "crwai_mind_"
DATASOURCE_NAME_PREFIX = "crwai_ds_"
class AIMindToolInputSchema(BaseModel):
"""Input for AIMind Tool."""
query: str = Field(description="Question in natural language to ask the AI-Mind")
class AIMindTool(BaseTool):
name: str = "AIMind Tool"
description: str = (
"A wrapper around [AI-Minds](https://mindsdb.com/minds). "
"Useful for when you need answers to questions from your data, stored in "
"data sources including PostgreSQL, MySQL, MariaDB, ClickHouse, Snowflake "
"and Google BigQuery. "
"Input should be a question in natural language."
)
args_schema: Type[BaseModel] = AIMindToolInputSchema
api_key: Optional[str] = None
datasources: Optional[List[Dict[str, Any]]] = None
mind_name: Optional[str] = None
package_dependencies: List[str] = ["minds-sdk"]
env_vars: List[EnvVar] = [
EnvVar(name="MINDS_API_KEY", description="API key for AI-Minds", required=True),
]
def __init__(self, api_key: Optional[str] = None, **kwargs):
super().__init__(**kwargs)
self.api_key = api_key or os.getenv("MINDS_API_KEY")
if not self.api_key:
raise ValueError("API key must be provided either through constructor or MINDS_API_KEY environment variable")
try:
from minds.client import Client # type: ignore
from minds.datasources import DatabaseConfig # type: ignore
except ImportError:
raise ImportError(
"`minds_sdk` package not found, please run `pip install minds-sdk`"
)
minds_client = Client(api_key=self.api_key)
# Convert the datasources to DatabaseConfig objects.
datasources = []
for datasource in self.datasources:
config = DatabaseConfig(
name=f"{AIMindToolConstants.DATASOURCE_NAME_PREFIX}_{secrets.token_hex(5)}",
engine=datasource["engine"],
description=datasource["description"],
connection_data=datasource["connection_data"],
tables=datasource["tables"],
)
datasources.append(config)
# Generate a random name for the Mind.
name = f"{AIMindToolConstants.MIND_NAME_PREFIX}_{secrets.token_hex(5)}"
mind = minds_client.minds.create(
name=name, datasources=datasources, replace=True
)
self.mind_name = mind.name
def _run(
self,
query: str
):
# Run the query on the AI-Mind.
# The Minds API is OpenAI compatible and therefore, the OpenAI client can be used.
openai_client = OpenAI(base_url=AIMindToolConstants.MINDS_API_BASE_URL, api_key=self.api_key)
completion = openai_client.chat.completions.create(
model=self.mind_name,
messages=[{"role": "user", "content": query}],
stream=False,
)
return completion.choices[0].message.content