MindsDB 25.3.2.0__py3-none-any.whl → 25.3.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/__main__.py +0 -1
- mindsdb/api/executor/datahub/datanodes/information_schema_datanode.py +2 -6
- mindsdb/api/executor/datahub/datanodes/mindsdb_tables.py +1 -1
- mindsdb/api/http/namespaces/agents.py +9 -5
- mindsdb/api/http/namespaces/chatbots.py +6 -5
- mindsdb/api/http/namespaces/databases.py +5 -6
- mindsdb/api/http/namespaces/skills.py +5 -4
- mindsdb/api/http/namespaces/views.py +6 -7
- mindsdb/integrations/handlers/chromadb_handler/chromadb_handler.py +23 -2
- mindsdb/integrations/handlers/dummy_data_handler/dummy_data_handler.py +16 -6
- mindsdb/integrations/handlers/file_handler/tests/test_file_handler.py +64 -83
- mindsdb/integrations/handlers/github_handler/generate_api.py +228 -0
- mindsdb/integrations/handlers/github_handler/github_handler.py +15 -8
- mindsdb/integrations/handlers/github_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/huggingface_handler/requirements.txt +5 -4
- mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +5 -5
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_graph_api_one_drive_client.py +1 -1
- mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +278 -0
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +114 -70
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +431 -0
- mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +18 -4
- mindsdb/integrations/handlers/redshift_handler/redshift_handler.py +1 -0
- mindsdb/integrations/handlers/salesforce_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/salesforce_handler/salesforce_handler.py +20 -25
- mindsdb/integrations/handlers/salesforce_handler/salesforce_tables.py +2 -2
- mindsdb/integrations/handlers/timescaledb_handler/timescaledb_handler.py +11 -6
- mindsdb/integrations/libs/ml_handler_process/learn_process.py +9 -3
- mindsdb/integrations/libs/vectordatabase_handler.py +2 -2
- mindsdb/integrations/utilities/files/file_reader.py +3 -3
- mindsdb/integrations/utilities/handlers/api_utilities/microsoft/ms_graph_api_utilities.py +36 -2
- mindsdb/integrations/utilities/rag/settings.py +1 -0
- mindsdb/interfaces/chatbot/chatbot_controller.py +6 -4
- mindsdb/interfaces/jobs/jobs_controller.py +1 -4
- mindsdb/interfaces/knowledge_base/controller.py +9 -28
- mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +1 -1
- mindsdb/interfaces/skills/skills_controller.py +8 -7
- mindsdb/utilities/render/sqlalchemy_render.py +11 -5
- {mindsdb-25.3.2.0.dist-info → mindsdb-25.3.4.0.dist-info}/METADATA +236 -233
- {mindsdb-25.3.2.0.dist-info → mindsdb-25.3.4.0.dist-info}/RECORD +43 -42
- {mindsdb-25.3.2.0.dist-info → mindsdb-25.3.4.0.dist-info}/WHEEL +1 -1
- mindsdb/integrations/handlers/timescaledb_handler/tests/__init__.py +0 -0
- mindsdb/integrations/handlers/timescaledb_handler/tests/test_timescaledb_handler.py +0 -47
- {mindsdb-25.3.2.0.dist-info → mindsdb-25.3.4.0.dist-info/licenses}/LICENSE +0 -0
- {mindsdb-25.3.2.0.dist-info → mindsdb-25.3.4.0.dist-info}/top_level.txt +0 -0
|
@@ -87,7 +87,7 @@ class MSGraphAPIBaseClient:
|
|
|
87
87
|
|
|
88
88
|
return response
|
|
89
89
|
|
|
90
|
-
def fetch_paginated_data(self, endpoint: Text, params: Optional[Dict] =
|
|
90
|
+
def fetch_paginated_data(self, endpoint: Text, params: Optional[Dict] = None) -> Generator:
|
|
91
91
|
"""
|
|
92
92
|
Fetches data from the Microsoft Graph API by making the specified request and handling pagination.
|
|
93
93
|
|
|
@@ -98,6 +98,8 @@ class MSGraphAPIBaseClient:
|
|
|
98
98
|
Yields:
|
|
99
99
|
List: The data fetched from the Microsoft Graph API.
|
|
100
100
|
"""
|
|
101
|
+
if params is None:
|
|
102
|
+
params = {}
|
|
101
103
|
api_url = self._get_api_url(endpoint)
|
|
102
104
|
|
|
103
105
|
# Add the pagination count to the request parameters.
|
|
@@ -115,7 +117,7 @@ class MSGraphAPIBaseClient:
|
|
|
115
117
|
api_url = response_json.get("@odata.nextLink", "")
|
|
116
118
|
yield value
|
|
117
119
|
|
|
118
|
-
def
|
|
120
|
+
def _fetch_data(self, endpoint: str, params: Optional[Dict] = {}) -> Union[List, Dict, bytes]:
|
|
119
121
|
"""
|
|
120
122
|
Fetches data from the Microsoft Graph API by making the specified request.
|
|
121
123
|
|
|
@@ -129,4 +131,36 @@ class MSGraphAPIBaseClient:
|
|
|
129
131
|
api_url = self._get_api_url(endpoint)
|
|
130
132
|
|
|
131
133
|
response = self._make_request(api_url, params)
|
|
134
|
+
return response
|
|
135
|
+
|
|
136
|
+
def fetch_data_content(self, endpoint: str, params: Optional[Dict] = {}) -> bytes:
|
|
137
|
+
"""
|
|
138
|
+
Fetches data content from the Microsoft Graph API by making the specified request.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
endpoint (str): The endpoint of the Microsoft Graph API to fetch data from.
|
|
142
|
+
params (Optional[Dict]): The parameters to include in the request.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
bytes: The data content fetched from the Microsoft Graph API.
|
|
146
|
+
"""
|
|
147
|
+
response = self._fetch_data(endpoint, params)
|
|
132
148
|
return response.content
|
|
149
|
+
|
|
150
|
+
def fetch_data_json(self, endpoint: str, params: Optional[Dict] = {}) -> Union[List, Dict]:
|
|
151
|
+
"""
|
|
152
|
+
Fetches data from the Microsoft Graph API by making the specified request and returns the JSON response.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
endpoint (str): The endpoint of the Microsoft Graph API to fetch data from.
|
|
156
|
+
params (Optional[Dict]): The parameters to include in the request.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
Union[List, Dict]: The JSON response fetched from the Microsoft Graph API.
|
|
160
|
+
"""
|
|
161
|
+
response = self._fetch_data(endpoint, params)
|
|
162
|
+
response_json = response.json()
|
|
163
|
+
|
|
164
|
+
if "value" in response_json:
|
|
165
|
+
return response_json["value"]
|
|
166
|
+
return response_json
|
|
@@ -551,6 +551,7 @@ class ColumnSchema(BaseModel):
|
|
|
551
551
|
Dict[Union[str, int, float], ValueSchema],
|
|
552
552
|
]
|
|
553
553
|
] = Field(
|
|
554
|
+
default=None,
|
|
554
555
|
description="One of the following. A dict or ordered dict of {schema_value: ValueSchema, ...}, where schema value is the name given for this value description in the schema."
|
|
555
556
|
)
|
|
556
557
|
example_questions: Optional[List[LLMExample]] = Field(
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
from typing import Dict, List
|
|
2
2
|
|
|
3
|
+
from mindsdb.api.executor.controllers.session_controller import SessionController
|
|
3
4
|
from mindsdb.interfaces.agents.agents_controller import AgentsController
|
|
4
5
|
from mindsdb.interfaces.chatbot.chatbot_task import ChatBotTask
|
|
5
6
|
from mindsdb.interfaces.database.projects import ProjectController
|
|
6
7
|
from mindsdb.interfaces.storage import db
|
|
7
8
|
from mindsdb.interfaces.model.functions import get_project_records
|
|
8
|
-
|
|
9
|
+
from mindsdb.utilities.exception import EntityNotExistsError
|
|
9
10
|
from mindsdb.utilities.context import context as ctx
|
|
10
|
-
|
|
11
|
-
from mindsdb.api.executor.controllers.session_controller import SessionController
|
|
12
11
|
from mindsdb.utilities.config import config
|
|
13
12
|
|
|
14
13
|
|
|
@@ -126,7 +125,7 @@ class ChatBotController:
|
|
|
126
125
|
Gets all chatbots in a project.
|
|
127
126
|
|
|
128
127
|
Parameters:
|
|
129
|
-
project_name (str): The name of the containing project
|
|
128
|
+
project_name (str): The name of the containing project. If None, then return from all projects
|
|
130
129
|
|
|
131
130
|
Returns:
|
|
132
131
|
all_bots (List[db.ChatBots]): List of database chatbot object
|
|
@@ -138,6 +137,9 @@ class ChatBotController:
|
|
|
138
137
|
continue
|
|
139
138
|
project_names[project.id] = project.name
|
|
140
139
|
|
|
140
|
+
if project_name is not None and project_name not in project_names.values():
|
|
141
|
+
raise EntityNotExistsError(f'Project {project_name} not found')
|
|
142
|
+
|
|
141
143
|
query = db.session.query(
|
|
142
144
|
db.ChatBots, db.Tasks
|
|
143
145
|
).join(
|
|
@@ -340,10 +340,7 @@ class JobsController:
|
|
|
340
340
|
data, columns = logs_db_controller.query(query)
|
|
341
341
|
|
|
342
342
|
names = [i['name'] for i in columns]
|
|
343
|
-
|
|
344
|
-
for row in data:
|
|
345
|
-
records.append(dict(zip(names, row)))
|
|
346
|
-
return records
|
|
343
|
+
return data[names].to_dict(orient='records')
|
|
347
344
|
|
|
348
345
|
|
|
349
346
|
class JobsExecutor:
|
|
@@ -26,9 +26,7 @@ from mindsdb.integrations.libs.vectordatabase_handler import (
|
|
|
26
26
|
)
|
|
27
27
|
from mindsdb.integrations.utilities.rag.rag_pipeline_builder import RAG
|
|
28
28
|
from mindsdb.integrations.utilities.rag.config_loader import load_rag_config
|
|
29
|
-
|
|
30
|
-
extract_comparison_conditions, filter_dataframe, FilterCondition, FilterOperator
|
|
31
|
-
)
|
|
29
|
+
|
|
32
30
|
from mindsdb.interfaces.agents.constants import DEFAULT_EMBEDDINGS_MODEL_CLASS
|
|
33
31
|
from mindsdb.interfaces.agents.langchain_agent import create_chat_model, get_llm_provider
|
|
34
32
|
from mindsdb.interfaces.database.projects import ProjectController
|
|
@@ -105,19 +103,9 @@ class KnowledgeBaseTable:
|
|
|
105
103
|
db_handler = self.get_vector_db()
|
|
106
104
|
logger.debug(f"Using vector db handler: {type(db_handler)}")
|
|
107
105
|
|
|
108
|
-
|
|
109
|
-
# update vector handlers, mark conditions as applied inside
|
|
110
|
-
for op, arg1, arg2 in extract_comparison_conditions(query.where):
|
|
111
|
-
condition = FilterCondition(arg1, FilterOperator(op.upper()), arg2)
|
|
112
|
-
if arg1 in (TableField.ID.value, TableField.CONTENT.value, TableField.EMBEDDINGS.value):
|
|
113
|
-
vector_filters.append(condition)
|
|
114
|
-
else:
|
|
115
|
-
outer_filters.append([op, arg1, arg2])
|
|
116
|
-
|
|
117
|
-
df = db_handler.dispatch_select(query, conditions=vector_filters)
|
|
106
|
+
df = db_handler.dispatch_select(query)
|
|
118
107
|
|
|
119
108
|
if df is not None:
|
|
120
|
-
df = filter_dataframe(df, outer_filters)
|
|
121
109
|
|
|
122
110
|
logger.debug(f"Query returned {len(df)} rows")
|
|
123
111
|
logger.debug(f"Columns in response: {df.columns.tolist()}")
|
|
@@ -229,7 +217,7 @@ class KnowledgeBaseTable:
|
|
|
229
217
|
|
|
230
218
|
# send to vectordb
|
|
231
219
|
db_handler = self.get_vector_db()
|
|
232
|
-
db_handler.
|
|
220
|
+
db_handler.dispatch_delete(query)
|
|
233
221
|
|
|
234
222
|
def hybrid_search(
|
|
235
223
|
self,
|
|
@@ -293,7 +281,6 @@ class KnowledgeBaseTable:
|
|
|
293
281
|
**base_metadata,
|
|
294
282
|
'original_row_id': str(row_id),
|
|
295
283
|
'content_column': col,
|
|
296
|
-
'content_type': col.split('_')[-1] if '_' in col else 'text'
|
|
297
284
|
}
|
|
298
285
|
|
|
299
286
|
raw_documents.append(Document(
|
|
@@ -364,7 +351,7 @@ class KnowledgeBaseTable:
|
|
|
364
351
|
logger.debug(f"Added IDs: {df_out[TableField.ID.value].tolist()}")
|
|
365
352
|
|
|
366
353
|
# -- prepare content and metadata --
|
|
367
|
-
content_columns = params.get('content_columns')
|
|
354
|
+
content_columns = params.get('content_columns', [TableField.CONTENT.value])
|
|
368
355
|
metadata_columns = params.get('metadata_columns')
|
|
369
356
|
|
|
370
357
|
logger.debug(f"Processing with: content_columns={content_columns}, metadata_columns={metadata_columns}")
|
|
@@ -399,17 +386,6 @@ class KnowledgeBaseTable:
|
|
|
399
386
|
# all the rest columns
|
|
400
387
|
metadata_columns = list(set(columns).difference(content_columns))
|
|
401
388
|
|
|
402
|
-
elif metadata_columns is not None:
|
|
403
|
-
metadata_columns = list(set(metadata_columns).intersection(columns))
|
|
404
|
-
# use all unused columns is content
|
|
405
|
-
content_columns = list(set(columns).difference(metadata_columns))
|
|
406
|
-
elif TableField.METADATA.value in columns:
|
|
407
|
-
metadata_columns = [TableField.METADATA.value]
|
|
408
|
-
content_columns = list(set(columns).difference(metadata_columns))
|
|
409
|
-
else:
|
|
410
|
-
# all columns go to content
|
|
411
|
-
content_columns = columns
|
|
412
|
-
|
|
413
389
|
# Add content columns directly (don't combine them)
|
|
414
390
|
for col in content_columns:
|
|
415
391
|
df_out[col] = df[col]
|
|
@@ -429,6 +405,9 @@ class KnowledgeBaseTable:
|
|
|
429
405
|
value = float(value)
|
|
430
406
|
elif pd.api.types.is_bool_dtype(value):
|
|
431
407
|
value = bool(value)
|
|
408
|
+
elif isinstance(value, dict):
|
|
409
|
+
metadata.update(value)
|
|
410
|
+
continue
|
|
432
411
|
else:
|
|
433
412
|
value = str(value)
|
|
434
413
|
metadata[col] = value
|
|
@@ -852,6 +831,8 @@ class KnowledgeBaseController:
|
|
|
852
831
|
# drop objects if they were created automatically
|
|
853
832
|
if 'default_vector_storage' in kb.params:
|
|
854
833
|
try:
|
|
834
|
+
handler = self.session.datahub.get(kb.params['default_vector_storage']).integration_handler
|
|
835
|
+
handler.drop_table(kb.vector_database_table)
|
|
855
836
|
self.session.integration_controller.delete(kb.params['default_vector_storage'])
|
|
856
837
|
except EntityNotExistsError:
|
|
857
838
|
pass
|
|
@@ -98,7 +98,7 @@ class DocumentPreprocessor:
|
|
|
98
98
|
provided_id: str = None,
|
|
99
99
|
) -> str:
|
|
100
100
|
"""Generate deterministic ID for a chunk"""
|
|
101
|
-
base_id =
|
|
101
|
+
base_id = provided_id
|
|
102
102
|
chunk_id = (
|
|
103
103
|
f"{base_id}_chunk_{chunk_index}" if chunk_index is not None else base_id
|
|
104
104
|
)
|
|
@@ -42,12 +42,12 @@ class SkillsController:
|
|
|
42
42
|
db.Skills.deleted_at == null()
|
|
43
43
|
).first()
|
|
44
44
|
|
|
45
|
-
def get_skills(self, project_name: str) -> List[dict]:
|
|
45
|
+
def get_skills(self, project_name: Optional[str]) -> List[dict]:
|
|
46
46
|
'''
|
|
47
47
|
Gets all skills in a project.
|
|
48
48
|
|
|
49
49
|
Parameters:
|
|
50
|
-
project_name (str): The name of the containing project
|
|
50
|
+
project_name (Optional[str]): The name of the containing project
|
|
51
51
|
|
|
52
52
|
Returns:
|
|
53
53
|
all_skills (List[db.Skills]): List of database skill object
|
|
@@ -56,11 +56,12 @@ class SkillsController:
|
|
|
56
56
|
ValueError: If `project_name` does not exist
|
|
57
57
|
'''
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
if project_name is None:
|
|
60
|
+
projects = self.project_controller.get_list()
|
|
61
|
+
project_ids = list([p.id for p in projects])
|
|
62
|
+
else:
|
|
63
|
+
project = self.project_controller.get(name=project_name)
|
|
64
|
+
project_ids = [project.id]
|
|
64
65
|
|
|
65
66
|
query = (
|
|
66
67
|
db.session.query(db.Skills)
|
|
@@ -483,7 +483,7 @@ class SqlalchemyRender:
|
|
|
483
483
|
|
|
484
484
|
return schema, table_name
|
|
485
485
|
|
|
486
|
-
def to_table(self, node):
|
|
486
|
+
def to_table(self, node, is_lateral=False):
|
|
487
487
|
if isinstance(node, ast.Identifier):
|
|
488
488
|
schema, table_name = self.get_table_name(node)
|
|
489
489
|
|
|
@@ -497,7 +497,10 @@ class SqlalchemyRender:
|
|
|
497
497
|
alias = None
|
|
498
498
|
if node.alias:
|
|
499
499
|
alias = self.get_alias(node.alias)
|
|
500
|
-
|
|
500
|
+
if is_lateral:
|
|
501
|
+
table = sub_stmt.lateral(alias)
|
|
502
|
+
else:
|
|
503
|
+
table = sub_stmt.subquery(alias)
|
|
501
504
|
|
|
502
505
|
else:
|
|
503
506
|
# TODO tests are failing
|
|
@@ -526,8 +529,11 @@ class SqlalchemyRender:
|
|
|
526
529
|
|
|
527
530
|
query = query.add_cte(stmt.cte(self.get_alias(alias), nesting=True))
|
|
528
531
|
|
|
529
|
-
if node.distinct:
|
|
532
|
+
if node.distinct is True:
|
|
530
533
|
query = query.distinct()
|
|
534
|
+
elif isinstance(node.distinct, list):
|
|
535
|
+
columns = [self.to_expression(c) for c in node.distinct]
|
|
536
|
+
query = query.distinct(*columns)
|
|
531
537
|
|
|
532
538
|
if node.from_table is not None:
|
|
533
539
|
from_table = node.from_table
|
|
@@ -541,7 +547,8 @@ class SqlalchemyRender:
|
|
|
541
547
|
# other tables
|
|
542
548
|
has_explicit_join = False
|
|
543
549
|
for item in join_list[1:]:
|
|
544
|
-
|
|
550
|
+
join_type = item['join_type']
|
|
551
|
+
table = self.to_table(item['table'], is_lateral=('LATERAL' in join_type))
|
|
545
552
|
if item['is_implicit']:
|
|
546
553
|
# add to from clause
|
|
547
554
|
if has_explicit_join:
|
|
@@ -558,7 +565,6 @@ class SqlalchemyRender:
|
|
|
558
565
|
else:
|
|
559
566
|
condition = self.to_expression(item['condition'])
|
|
560
567
|
|
|
561
|
-
join_type = item['join_type']
|
|
562
568
|
if 'ASOF' in join_type:
|
|
563
569
|
raise NotImplementedError(f'Unsupported join type: {join_type}')
|
|
564
570
|
method = 'join'
|