MindsDB 25.6.3.1__py3-none-any.whl → 25.6.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of MindsDB might be problematic. Click here for more details.
- mindsdb/__about__.py +1 -1
- mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +71 -43
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +16 -1
- mindsdb/api/executor/datahub/datanodes/project_datanode.py +1 -1
- mindsdb/api/executor/datahub/datanodes/system_tables.py +314 -1
- mindsdb/api/executor/planner/plan_join.py +1 -1
- mindsdb/api/executor/planner/query_planner.py +7 -1
- mindsdb/integrations/handlers/ludwig_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/salesforce_handler/salesforce_tables.py +2 -0
- mindsdb/integrations/libs/api_handler.py +6 -7
- mindsdb/interfaces/agents/constants.py +44 -0
- mindsdb/interfaces/agents/langchain_agent.py +8 -1
- mindsdb/interfaces/data_catalog/data_catalog_reader.py +19 -2
- mindsdb/interfaces/knowledge_base/controller.py +6 -13
- mindsdb/interfaces/knowledge_base/evaluate.py +3 -3
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +24 -22
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +40 -28
- mindsdb/interfaces/skills/skill_tool.py +91 -88
- {mindsdb-25.6.3.1.dist-info → mindsdb-25.6.4.0.dist-info}/METADATA +259 -257
- {mindsdb-25.6.3.1.dist-info → mindsdb-25.6.4.0.dist-info}/RECORD +23 -23
- {mindsdb-25.6.3.1.dist-info → mindsdb-25.6.4.0.dist-info}/WHEEL +0 -0
- {mindsdb-25.6.3.1.dist-info → mindsdb-25.6.4.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.6.3.1.dist-info → mindsdb-25.6.4.0.dist-info}/top_level.txt +0 -0
|
@@ -171,6 +171,8 @@ NVIDIA_NIM_CHAT_MODELS = (
|
|
|
171
171
|
)
|
|
172
172
|
|
|
173
173
|
GOOGLE_GEMINI_CHAT_MODELS = (
|
|
174
|
+
"gemini-2.5-pro",
|
|
175
|
+
"gemini-2.5-flash",
|
|
174
176
|
"gemini-2.5-pro-preview-03-25",
|
|
175
177
|
"gemini-2.0-flash",
|
|
176
178
|
"gemini-2.0-flash-lite",
|
|
@@ -228,3 +230,45 @@ You are an AI assistant powered by MindsDB. When answering questions, follow the
|
|
|
228
230
|
For factual questions, ALWAYS use the available tools to look up information rather than relying on your internal knowledge.
|
|
229
231
|
|
|
230
232
|
"""
|
|
233
|
+
|
|
234
|
+
MINDSDB_PREFIX = """You are an AI assistant powered by MindsDB. When answering questions, follow these guidelines:
|
|
235
|
+
|
|
236
|
+
1. For questions about database tables and their contents:
|
|
237
|
+
- Use the sql_db_query to query the tables directly
|
|
238
|
+
- You can join tables if needed to get comprehensive information
|
|
239
|
+
- You are running on a federated query engine, so joins across multiple databases are allowed and supported
|
|
240
|
+
- **Important Rule for SQL Queries:** If you formulate an SQL query as part of answering a user's question, you *must* then use the `sql_db_query` tool to execute that query and get its results. The SQL query string itself is NOT the final answer to the user unless the user has specifically asked for the query. Your final AI response should be based on the *results* obtained from executing the query.
|
|
241
|
+
|
|
242
|
+
2. For factual questions about specific topics, use the knowledge base tools, if available, in this sequence:
|
|
243
|
+
- First use kb_list_tool to see available knowledge bases
|
|
244
|
+
- Then use kb_info_tool to understand the structure of relevant knowledge bases
|
|
245
|
+
- Finally use kb_query_tool to query the knowledge base for specific information
|
|
246
|
+
|
|
247
|
+
For factual questions, ALWAYS use the available tools to look up information rather than relying on your internal knowledge.
|
|
248
|
+
|
|
249
|
+
Here is the user's question: {{question}}
|
|
250
|
+
|
|
251
|
+
TOOLS:
|
|
252
|
+
------
|
|
253
|
+
|
|
254
|
+
Assistant has access to the following tools:"""
|
|
255
|
+
|
|
256
|
+
EXPLICIT_FORMAT_INSTRUCTIONS = """
|
|
257
|
+
<< TOOL CALLING INSTRUCTIONS >>
|
|
258
|
+
|
|
259
|
+
**It is critical you use the following format to call a tool**
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
Thought: Do I need to use a tool? Yes
|
|
263
|
+
Action: the action to take, should be one of [{tool_names}]
|
|
264
|
+
Action Input: the input to the action
|
|
265
|
+
Observation: the result of the action
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
Thought: Do I need to use a tool? No
|
|
272
|
+
{ai_prefix}: [your response here]
|
|
273
|
+
```
|
|
274
|
+
"""
|
|
@@ -58,6 +58,8 @@ from mindsdb.interfaces.agents.constants import (
|
|
|
58
58
|
TRACE_ID_COLUMN,
|
|
59
59
|
DEFAULT_AGENT_SYSTEM_PROMPT,
|
|
60
60
|
WRITER_CHAT_MODELS,
|
|
61
|
+
MINDSDB_PREFIX,
|
|
62
|
+
EXPLICIT_FORMAT_INSTRUCTIONS,
|
|
61
63
|
)
|
|
62
64
|
from mindsdb.interfaces.skills.skill_tool import skill_tool, SkillData
|
|
63
65
|
from langchain_anthropic import ChatAnthropic
|
|
@@ -426,7 +428,12 @@ class LangchainAgent:
|
|
|
426
428
|
llm,
|
|
427
429
|
agent=agent_type,
|
|
428
430
|
# Use custom output parser to handle flaky LLMs that don't ALWAYS conform to output format.
|
|
429
|
-
agent_kwargs={
|
|
431
|
+
agent_kwargs={
|
|
432
|
+
"output_parser": SafeOutputParser(),
|
|
433
|
+
"prefix": MINDSDB_PREFIX, # Override default "Assistant is a large language model..." text
|
|
434
|
+
"format_instructions": EXPLICIT_FORMAT_INSTRUCTIONS, # More explicit tool calling instructions
|
|
435
|
+
"ai_prefix": "AI",
|
|
436
|
+
},
|
|
430
437
|
# Calls the agent's LLM Chain one final time to generate a final answer based on the previous steps
|
|
431
438
|
early_stopping_method="generate",
|
|
432
439
|
handle_parsing_errors=self._handle_parsing_errors,
|
|
@@ -11,8 +11,6 @@ class DataCatalogReader(BaseDataCatalog):
|
|
|
11
11
|
"""
|
|
12
12
|
Read the metadata from the data catalog and return it as a string.
|
|
13
13
|
"""
|
|
14
|
-
if not self.is_data_catalog_supported():
|
|
15
|
-
return f"Data catalog is not supported for database '{self.database_name}'."
|
|
16
14
|
tables = self._read_metadata()
|
|
17
15
|
if not tables:
|
|
18
16
|
self.logger.warning(f"No metadata found for database '{self.database_name}'")
|
|
@@ -26,10 +24,29 @@ class DataCatalogReader(BaseDataCatalog):
|
|
|
26
24
|
metadata_str += table.as_string() + "\n\n"
|
|
27
25
|
return metadata_str
|
|
28
26
|
|
|
27
|
+
def read_metadata_as_records(self) -> list:
|
|
28
|
+
"""
|
|
29
|
+
Read the metadata from the data catalog and return it as a list of database records.
|
|
30
|
+
"""
|
|
31
|
+
tables = self._read_metadata()
|
|
32
|
+
if not tables:
|
|
33
|
+
self.logger.warning(f"No metadata found for database '{self.database_name}'")
|
|
34
|
+
return []
|
|
35
|
+
return tables
|
|
36
|
+
|
|
37
|
+
def get_handler_info(self) -> str:
|
|
38
|
+
"""
|
|
39
|
+
Get the handler info for the database.
|
|
40
|
+
"""
|
|
41
|
+
return self.data_handler.meta_get_handler_info()
|
|
42
|
+
|
|
29
43
|
def _read_metadata(self) -> list:
|
|
30
44
|
"""
|
|
31
45
|
Read the metadata from the data catalog and return it in a structured format.
|
|
32
46
|
"""
|
|
47
|
+
if not self.is_data_catalog_supported():
|
|
48
|
+
return f"Data catalog is not supported for database '{self.database_name}'."
|
|
49
|
+
|
|
33
50
|
query = db.session.query(db.MetaTables).filter_by(integration_id=self.integration_id)
|
|
34
51
|
if self.table_names:
|
|
35
52
|
cleaned_table_names = [name.strip("`").split(".")[-1] for name in self.table_names]
|
|
@@ -53,18 +53,16 @@ def get_model_params(model_params: dict, default_config_key: str):
|
|
|
53
53
|
"""
|
|
54
54
|
Get model parameters by combining default config with user provided parameters.
|
|
55
55
|
"""
|
|
56
|
-
# If the default config key is for reranking and the switch to use the default LLM is enabled,
|
|
57
|
-
# switch to the default LLM model.
|
|
58
|
-
if default_config_key == "default_reranking_model" and config.get("default_reranking_model").get(
|
|
59
|
-
"use_default_llm", False
|
|
60
|
-
):
|
|
61
|
-
default_config_key = "default_llm_model"
|
|
62
|
-
|
|
63
56
|
combined_model_params = copy.deepcopy(config.get(default_config_key, {}))
|
|
64
57
|
|
|
65
58
|
if model_params:
|
|
59
|
+
if not isinstance(model_params, dict):
|
|
60
|
+
raise ValueError("Model parameters must be passed as a JSON object")
|
|
61
|
+
|
|
66
62
|
combined_model_params.update(model_params)
|
|
67
63
|
|
|
64
|
+
combined_model_params.pop("use_default_llm", None)
|
|
65
|
+
|
|
68
66
|
return combined_model_params
|
|
69
67
|
|
|
70
68
|
|
|
@@ -105,8 +103,6 @@ def get_reranking_model_from_params(reranking_model_params: dict):
|
|
|
105
103
|
params_copy["api_key"] = get_api_key(provider, params_copy, strict=False)
|
|
106
104
|
params_copy["model"] = params_copy.pop("model_name", None)
|
|
107
105
|
|
|
108
|
-
params_copy.pop("use_default_llm", None)
|
|
109
|
-
|
|
110
106
|
return BaseLLMReranker(**params_copy)
|
|
111
107
|
|
|
112
108
|
|
|
@@ -961,10 +957,7 @@ class KnowledgeBaseController:
|
|
|
961
957
|
# # it is params for model
|
|
962
958
|
# embedding_params.update(params["embedding_model"])
|
|
963
959
|
|
|
964
|
-
|
|
965
|
-
if not isinstance(params["embedding_model"], dict):
|
|
966
|
-
raise ValueError("embedding_model should be JSON object with model parameters.")
|
|
967
|
-
embedding_params.update(params["embedding_model"])
|
|
960
|
+
embedding_params = get_model_params(params.get("embedding_model", {}), "default_embedding_model")
|
|
968
961
|
|
|
969
962
|
# if model_name is None: # Legacy
|
|
970
963
|
model_name = self._create_embedding_model(
|
|
@@ -168,13 +168,13 @@ class EvaluateBase:
|
|
|
168
168
|
test_data = self.generate_test_data(gen_params)
|
|
169
169
|
|
|
170
170
|
self.save_to_table(test_table, test_data, is_replace=True)
|
|
171
|
-
else:
|
|
172
|
-
test_data = self.read_from_table(test_table)
|
|
173
171
|
|
|
174
172
|
if params.get("evaluate", True) is False:
|
|
175
173
|
# no evaluate is required
|
|
176
174
|
return pd.DataFrame()
|
|
177
175
|
|
|
176
|
+
test_data = self.read_from_table(test_table)
|
|
177
|
+
|
|
178
178
|
scores = self.evaluate(test_data)
|
|
179
179
|
scores["name"] = self.name
|
|
180
180
|
scores["created_at"] = dt.datetime.now()
|
|
@@ -511,6 +511,6 @@ class EvaluateDocID(EvaluateBase):
|
|
|
511
511
|
"total": total_questions,
|
|
512
512
|
"total_found": total_found,
|
|
513
513
|
"retrieved_in_top_10": accurate_in_top_10,
|
|
514
|
-
"cumulative_recall": cumulative_recall,
|
|
514
|
+
"cumulative_recall": json.dumps(cumulative_recall),
|
|
515
515
|
"avg_query_time": avg_query_time,
|
|
516
516
|
}
|
|
@@ -6,6 +6,27 @@ from langchain_core.tools import BaseTool
|
|
|
6
6
|
from mindsdb_sql_parser.ast import Describe, Select, Identifier, Constant, Star
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
def llm_str_strip(s):
|
|
10
|
+
length = -1
|
|
11
|
+
while length != len(s):
|
|
12
|
+
length = len(s)
|
|
13
|
+
|
|
14
|
+
# remove ```
|
|
15
|
+
if s.startswith("```"):
|
|
16
|
+
s = s[3:]
|
|
17
|
+
if s.endswith("```"):
|
|
18
|
+
s = s[:-3]
|
|
19
|
+
|
|
20
|
+
# remove trailing new lines
|
|
21
|
+
s = s.strip("\n")
|
|
22
|
+
|
|
23
|
+
# remove extra quotes
|
|
24
|
+
for q in ('"', "'", "`"):
|
|
25
|
+
if s.count(q) == 1:
|
|
26
|
+
s = s.strip(q)
|
|
27
|
+
return s
|
|
28
|
+
|
|
29
|
+
|
|
9
30
|
class KnowledgeBaseListToolInput(BaseModel):
|
|
10
31
|
tool_input: str = Field("", description="An empty string to list all knowledge bases.")
|
|
11
32
|
|
|
@@ -56,26 +77,6 @@ class KnowledgeBaseInfoTool(BaseTool):
|
|
|
56
77
|
except (json.JSONDecodeError, TypeError):
|
|
57
78
|
pass
|
|
58
79
|
|
|
59
|
-
def strip(s):
|
|
60
|
-
length = -1
|
|
61
|
-
while length != len(s):
|
|
62
|
-
length = len(s)
|
|
63
|
-
|
|
64
|
-
# remove ```
|
|
65
|
-
if s.startswith("```"):
|
|
66
|
-
s = s[3:]
|
|
67
|
-
if s.endswith("```"):
|
|
68
|
-
s = s[:-3]
|
|
69
|
-
|
|
70
|
-
# remove trailing new lines
|
|
71
|
-
s = s.strip("\n")
|
|
72
|
-
|
|
73
|
-
# remove extra quotes
|
|
74
|
-
for q in ('"', "'", "`"):
|
|
75
|
-
if s.count(q) == 1:
|
|
76
|
-
s = s.strip(q)
|
|
77
|
-
return s
|
|
78
|
-
|
|
79
80
|
# Finally, try the original regex pattern for $START$ and $STOP$ markers
|
|
80
81
|
match = re.search(r"\$START\$(.*?)\$STOP\$", tool_input, re.DOTALL)
|
|
81
82
|
if not match:
|
|
@@ -84,14 +85,14 @@ class KnowledgeBaseInfoTool(BaseTool):
|
|
|
84
85
|
return [kb.strip() for kb in tool_input.split(",")]
|
|
85
86
|
# If it's just a single string without formatting, return it as a single item
|
|
86
87
|
if tool_input.strip():
|
|
87
|
-
return [
|
|
88
|
+
return [llm_str_strip(tool_input)]
|
|
88
89
|
return []
|
|
89
90
|
|
|
90
91
|
# Extract and clean the knowledge base names
|
|
91
92
|
kb_names_str = match.group(1).strip()
|
|
92
93
|
kb_names = re.findall(r"`([^`]+)`", kb_names_str)
|
|
93
94
|
|
|
94
|
-
kb_names = [
|
|
95
|
+
kb_names = [llm_str_strip(n) for n in kb_names]
|
|
95
96
|
return kb_names
|
|
96
97
|
|
|
97
98
|
def _run(self, tool_input: str) -> str:
|
|
@@ -221,6 +222,7 @@ class KnowledgeBaseQueryTool(BaseTool):
|
|
|
221
222
|
|
|
222
223
|
try:
|
|
223
224
|
# Execute the query
|
|
225
|
+
query = llm_str_strip(query)
|
|
224
226
|
result = self.db.run_no_throw(query)
|
|
225
227
|
|
|
226
228
|
if not result:
|
|
@@ -10,25 +10,27 @@ from mindsdb.interfaces.skills.custom.text2sql.mindsdb_sql_tool import MindsDBSQ
|
|
|
10
10
|
from mindsdb.interfaces.skills.custom.text2sql.mindsdb_kb_tools import (
|
|
11
11
|
KnowledgeBaseListTool,
|
|
12
12
|
KnowledgeBaseInfoTool,
|
|
13
|
-
KnowledgeBaseQueryTool
|
|
13
|
+
KnowledgeBaseQueryTool,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
18
|
+
include_knowledge_base_tools: bool = True
|
|
18
19
|
|
|
19
|
-
def get_tools(self, prefix=
|
|
20
|
-
|
|
20
|
+
def get_tools(self, prefix="") -> List[BaseTool]:
|
|
21
21
|
current_date_time = datetime.now().strftime("%Y-%m-%d %H:%M")
|
|
22
22
|
|
|
23
23
|
"""Get the tools in the toolkit."""
|
|
24
24
|
list_sql_database_tool = ListSQLDatabaseTool(
|
|
25
|
-
name=f
|
|
25
|
+
name=f"sql_db_list_tables{prefix}",
|
|
26
26
|
db=self.db,
|
|
27
|
-
description=dedent(
|
|
27
|
+
description=dedent(
|
|
28
|
+
"""\n
|
|
28
29
|
Input is an empty string, output is a comma-separated list of tables in the database. Each table name is escaped using backticks.
|
|
29
30
|
Each table name in the list may be in one of two formats: database_name.`table_name` or database_name.schema_name.`table_name`.
|
|
30
31
|
Table names in response to the user must be escaped using backticks.
|
|
31
|
-
"""
|
|
32
|
+
"""
|
|
33
|
+
),
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
info_sql_database_tool_description = (
|
|
@@ -45,11 +47,11 @@ class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
|
45
47
|
" $START$ table1 table2 table3 $STOP$\n"
|
|
46
48
|
)
|
|
47
49
|
info_sql_database_tool = InfoSQLDatabaseTool(
|
|
48
|
-
name=f
|
|
49
|
-
db=self.db, description=info_sql_database_tool_description
|
|
50
|
+
name=f"sql_db_schema{prefix}", db=self.db, description=info_sql_database_tool_description
|
|
50
51
|
)
|
|
51
52
|
|
|
52
|
-
query_sql_database_tool_description = dedent(
|
|
53
|
+
query_sql_database_tool_description = dedent(
|
|
54
|
+
f"""\
|
|
53
55
|
Input: A detailed and well-structured SQL query. The query must be enclosed between the symbols $START$ and $STOP$.
|
|
54
56
|
Output: Database result or error message. For errors, rewrite and retry the query. For 'Unknown column' errors, use '{info_sql_database_tool.name}' to check table fields.
|
|
55
57
|
This system is a highly intelligent and reliable PostgreSQL SQL skill designed to work with databases.
|
|
@@ -93,11 +95,11 @@ class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
|
93
95
|
- When asked about yourself or your maker, state that you are a Data-Mind, created by MindsDB to help answer data questions.
|
|
94
96
|
- When asked about your purpose or how you can help, explore the available data sources and then explain that you can answer questions based on the connected data. Provide a few relevant example questions that you could answer for the user about their data.
|
|
95
97
|
Adhere to these guidelines for all queries and responses. Ask for clarification if needed.
|
|
96
|
-
"""
|
|
98
|
+
"""
|
|
99
|
+
)
|
|
97
100
|
|
|
98
101
|
query_sql_database_tool = QuerySQLDataBaseTool(
|
|
99
|
-
name=f
|
|
100
|
-
db=self.db, description=query_sql_database_tool_description
|
|
102
|
+
name=f"sql_db_query{prefix}", db=self.db, description=query_sql_database_tool_description
|
|
101
103
|
)
|
|
102
104
|
|
|
103
105
|
mindsdb_sql_parser_tool_description = (
|
|
@@ -108,15 +110,24 @@ class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
|
108
110
|
f"ALWAYS run this tool before executing a query with {query_sql_database_tool.name}. "
|
|
109
111
|
)
|
|
110
112
|
mindsdb_sql_parser_tool = MindsDBSQLParserTool(
|
|
111
|
-
name=f
|
|
112
|
-
description=mindsdb_sql_parser_tool_description
|
|
113
|
+
name=f"mindsdb_sql_parser_tool{prefix}", description=mindsdb_sql_parser_tool_description
|
|
113
114
|
)
|
|
114
115
|
|
|
116
|
+
sql_tools = [
|
|
117
|
+
query_sql_database_tool,
|
|
118
|
+
info_sql_database_tool,
|
|
119
|
+
list_sql_database_tool,
|
|
120
|
+
mindsdb_sql_parser_tool,
|
|
121
|
+
]
|
|
122
|
+
if not self.include_knowledge_base_tools:
|
|
123
|
+
return sql_tools
|
|
124
|
+
|
|
115
125
|
# Knowledge base tools
|
|
116
126
|
kb_list_tool = KnowledgeBaseListTool(
|
|
117
|
-
name=f
|
|
127
|
+
name=f"kb_list_tool{prefix}",
|
|
118
128
|
db=self.db,
|
|
119
|
-
description=dedent(
|
|
129
|
+
description=dedent(
|
|
130
|
+
"""\
|
|
120
131
|
Lists all available knowledge bases that can be queried.
|
|
121
132
|
Input: No input required, just call the tool directly.
|
|
122
133
|
Output: A table of all available knowledge bases with their names and creation dates.
|
|
@@ -125,13 +136,15 @@ class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
|
125
136
|
Each knowledge base name is escaped using backticks.
|
|
126
137
|
|
|
127
138
|
Example usage: kb_list_tool()
|
|
128
|
-
"""
|
|
139
|
+
"""
|
|
140
|
+
),
|
|
129
141
|
)
|
|
130
142
|
|
|
131
143
|
kb_info_tool = KnowledgeBaseInfoTool(
|
|
132
|
-
name=f
|
|
144
|
+
name=f"kb_info_tool{prefix}",
|
|
133
145
|
db=self.db,
|
|
134
|
-
description=dedent(
|
|
146
|
+
description=dedent(
|
|
147
|
+
f"""\
|
|
135
148
|
Gets detailed information about specific knowledge bases including their structure and metadata fields.
|
|
136
149
|
|
|
137
150
|
Input: A knowledge base name as a simple string.
|
|
@@ -143,13 +156,15 @@ class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
|
143
156
|
Example usage: kb_info_tool("kb_name")
|
|
144
157
|
|
|
145
158
|
Make sure the knowledge base exists by calling {kb_list_tool.name} first.
|
|
146
|
-
"""
|
|
159
|
+
"""
|
|
160
|
+
),
|
|
147
161
|
)
|
|
148
162
|
|
|
149
163
|
kb_query_tool = KnowledgeBaseQueryTool(
|
|
150
|
-
name=f
|
|
164
|
+
name=f"kb_query_tool{prefix}",
|
|
151
165
|
db=self.db,
|
|
152
|
-
description=dedent(
|
|
166
|
+
description=dedent(
|
|
167
|
+
f"""\
|
|
153
168
|
Queries knowledge bases using SQL syntax to retrieve relevant information.
|
|
154
169
|
|
|
155
170
|
Input: A SQL query string that targets a knowledge base.
|
|
@@ -192,15 +207,12 @@ class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
|
192
207
|
- Always include a semicolon at the end of your SQL query
|
|
193
208
|
|
|
194
209
|
For factual questions, use this tool to retrieve information rather than relying on the model's knowledge.
|
|
195
|
-
"""
|
|
210
|
+
"""
|
|
211
|
+
),
|
|
196
212
|
)
|
|
197
213
|
|
|
198
214
|
# Return standard SQL tools and knowledge base tools
|
|
199
|
-
return [
|
|
200
|
-
query_sql_database_tool,
|
|
201
|
-
info_sql_database_tool,
|
|
202
|
-
list_sql_database_tool,
|
|
203
|
-
mindsdb_sql_parser_tool,
|
|
215
|
+
return sql_tools + [
|
|
204
216
|
kb_list_tool,
|
|
205
217
|
kb_info_tool,
|
|
206
218
|
kb_query_tool,
|