MindsDB 25.5.3.0__py3-none-any.whl → 25.5.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 +127 -79
- mindsdb/api/a2a/__init__.py +0 -0
- mindsdb/api/a2a/__main__.py +114 -0
- mindsdb/api/a2a/a2a_client.py +439 -0
- mindsdb/api/a2a/agent.py +308 -0
- mindsdb/api/a2a/common/__init__.py +0 -0
- mindsdb/api/a2a/common/client/__init__.py +4 -0
- mindsdb/api/a2a/common/client/card_resolver.py +21 -0
- mindsdb/api/a2a/common/client/client.py +86 -0
- mindsdb/api/a2a/common/server/__init__.py +4 -0
- mindsdb/api/a2a/common/server/server.py +164 -0
- mindsdb/api/a2a/common/server/task_manager.py +287 -0
- mindsdb/api/a2a/common/server/utils.py +28 -0
- mindsdb/api/a2a/common/types.py +365 -0
- mindsdb/api/a2a/constants.py +9 -0
- mindsdb/api/a2a/run_a2a.py +129 -0
- mindsdb/api/a2a/task_manager.py +594 -0
- mindsdb/api/executor/command_executor.py +47 -27
- mindsdb/api/executor/datahub/classes/response.py +5 -2
- mindsdb/api/executor/datahub/datanodes/integration_datanode.py +39 -72
- mindsdb/api/executor/planner/query_planner.py +10 -1
- mindsdb/api/executor/sql_query/result_set.py +185 -52
- mindsdb/api/executor/sql_query/sql_query.py +1 -1
- mindsdb/api/executor/sql_query/steps/apply_predictor_step.py +9 -12
- mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +8 -10
- mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +5 -44
- mindsdb/api/executor/sql_query/steps/insert_step.py +24 -15
- mindsdb/api/executor/sql_query/steps/join_step.py +1 -1
- mindsdb/api/executor/sql_query/steps/project_step.py +1 -1
- mindsdb/api/executor/sql_query/steps/sql_steps.py +1 -1
- mindsdb/api/executor/sql_query/steps/subselect_step.py +4 -8
- mindsdb/api/executor/sql_query/steps/union_step.py +1 -3
- mindsdb/api/http/initialize.py +99 -83
- mindsdb/api/http/namespaces/analysis.py +3 -3
- mindsdb/api/http/namespaces/file.py +8 -2
- mindsdb/api/http/namespaces/sql.py +13 -27
- mindsdb/api/mcp/start.py +42 -5
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packet.py +0 -1
- mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/binary_resultset_row_package.py +52 -19
- mindsdb/api/mysql/mysql_proxy/executor/mysql_executor.py +8 -10
- mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +54 -38
- mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +82 -115
- mindsdb/api/mysql/mysql_proxy/utilities/dump.py +351 -0
- mindsdb/api/postgres/postgres_proxy/executor/executor.py +1 -1
- mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +5 -6
- mindsdb/integrations/handlers/altibase_handler/altibase_handler.py +26 -27
- mindsdb/integrations/handlers/altibase_handler/connection_args.py +13 -13
- mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler.py +8 -8
- mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler_dsn.py +13 -13
- mindsdb/integrations/handlers/anthropic_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/anthropic_handler/anthropic_handler.py +1 -3
- mindsdb/integrations/handlers/aurora_handler/aurora_handler.py +1 -0
- mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
- mindsdb/integrations/handlers/autosklearn_handler/config.py +0 -1
- mindsdb/integrations/handlers/bigquery_handler/bigquery_handler.py +1 -1
- mindsdb/integrations/handlers/bigquery_handler/tests/test_bigquery_handler.py +1 -1
- mindsdb/integrations/handlers/binance_handler/binance_handler.py +1 -0
- mindsdb/integrations/handlers/binance_handler/binance_tables.py +3 -4
- mindsdb/integrations/handlers/byom_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/ckan_handler/ckan_handler.py +3 -0
- mindsdb/integrations/handlers/clickhouse_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/cloud_spanner_handler/tests/test_cloud_spanner_handler.py +0 -2
- mindsdb/integrations/handlers/cloud_sql_handler/cloud_sql_handler.py +0 -1
- mindsdb/integrations/handlers/cohere_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/cohere_handler/cohere_handler.py +11 -13
- mindsdb/integrations/handlers/confluence_handler/confluence_tables.py +6 -0
- mindsdb/integrations/handlers/databend_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/databend_handler/databend_handler.py +4 -4
- mindsdb/integrations/handlers/databend_handler/tests/__init__.py +0 -1
- mindsdb/integrations/handlers/databend_handler/tests/test_databend_handler.py +1 -1
- mindsdb/integrations/handlers/derby_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/derby_handler/derby_handler.py +14 -22
- mindsdb/integrations/handlers/derby_handler/tests/test_derby_handler.py +6 -6
- mindsdb/integrations/handlers/discord_handler/discord_handler.py +5 -5
- mindsdb/integrations/handlers/discord_handler/discord_tables.py +3 -3
- mindsdb/integrations/handlers/discord_handler/tests/test_discord.py +5 -3
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub.py +3 -3
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub_handler.py +2 -2
- mindsdb/integrations/handlers/dockerhub_handler/dockerhub_tables.py +57 -54
- mindsdb/integrations/handlers/dremio_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/druid_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/druid_handler/druid_handler.py +2 -2
- mindsdb/integrations/handlers/edgelessdb_handler/tests/test_edgelessdb_handler.py +9 -9
- mindsdb/integrations/handlers/email_handler/email_client.py +1 -1
- mindsdb/integrations/handlers/email_handler/email_ingestor.py +1 -1
- mindsdb/integrations/handlers/email_handler/email_tables.py +0 -1
- mindsdb/integrations/handlers/email_handler/settings.py +0 -1
- mindsdb/integrations/handlers/eventstoredb_handler/eventstoredb_handler.py +2 -1
- mindsdb/integrations/handlers/firebird_handler/firebird_handler.py +1 -1
- mindsdb/integrations/handlers/flaml_handler/flaml_handler.py +9 -9
- mindsdb/integrations/handlers/frappe_handler/frappe_client.py +5 -5
- mindsdb/integrations/handlers/frappe_handler/frappe_handler.py +6 -5
- mindsdb/integrations/handlers/frappe_handler/frappe_tables.py +2 -2
- mindsdb/integrations/handlers/github_handler/connection_args.py +2 -2
- mindsdb/integrations/handlers/github_handler/github_handler.py +1 -8
- mindsdb/integrations/handlers/github_handler/github_tables.py +13 -24
- mindsdb/integrations/handlers/gitlab_handler/gitlab_handler.py +2 -1
- mindsdb/integrations/handlers/gitlab_handler/gitlab_tables.py +1 -4
- mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +6 -13
- mindsdb/integrations/handlers/google_books_handler/google_books_handler.py +2 -1
- mindsdb/integrations/handlers/google_books_handler/google_books_tables.py +0 -3
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +4 -4
- mindsdb/integrations/handlers/google_calendar_handler/google_calendar_tables.py +2 -6
- mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_handler.py +3 -2
- mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_tables.py +0 -3
- mindsdb/integrations/handlers/google_fit_handler/google_fit_handler.py +10 -12
- mindsdb/integrations/handlers/google_fit_handler/google_fit_tables.py +11 -13
- mindsdb/integrations/handlers/google_search_handler/google_search_handler.py +2 -1
- mindsdb/integrations/handlers/google_search_handler/google_search_tables.py +0 -3
- mindsdb/integrations/handlers/groq_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/hackernews_handler/hn_handler.py +5 -7
- mindsdb/integrations/handlers/hackernews_handler/hn_table.py +6 -7
- mindsdb/integrations/handlers/hive_handler/tests/test_hive_handler.py +1 -1
- mindsdb/integrations/handlers/hsqldb_handler/connection_args.py +6 -6
- mindsdb/integrations/handlers/hsqldb_handler/hsqldb_handler.py +4 -3
- mindsdb/integrations/handlers/huggingface_api_handler/exceptions.py +1 -1
- mindsdb/integrations/handlers/huggingface_api_handler/huggingface_api_handler.py +1 -8
- mindsdb/integrations/handlers/huggingface_handler/huggingface_handler.py +6 -6
- mindsdb/integrations/handlers/huggingface_handler/requirements.txt +1 -1
- mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +1 -1
- mindsdb/integrations/handlers/ignite_handler/ignite_handler.py +2 -1
- mindsdb/integrations/handlers/impala_handler/impala_handler.py +9 -12
- mindsdb/integrations/handlers/impala_handler/tests/test_impala_handler.py +11 -11
- mindsdb/integrations/handlers/influxdb_handler/influxdb_handler.py +10 -13
- mindsdb/integrations/handlers/influxdb_handler/influxdb_tables.py +20 -20
- mindsdb/integrations/handlers/informix_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/informix_handler/__init__.py +12 -5
- mindsdb/integrations/handlers/informix_handler/informix_handler.py +99 -133
- mindsdb/integrations/handlers/informix_handler/tests/test_informix_handler.py +13 -11
- mindsdb/integrations/handlers/ingres_handler/__about__.py +0 -1
- mindsdb/integrations/handlers/ingres_handler/ingres_handler.py +1 -0
- mindsdb/integrations/handlers/jira_handler/jira_handler.py +4 -4
- mindsdb/integrations/handlers/jira_handler/jira_tables.py +9 -9
- mindsdb/integrations/handlers/kinetica_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/langchain_handler/langchain_handler.py +4 -4
- mindsdb/integrations/handlers/langchain_handler/tools.py +9 -10
- mindsdb/integrations/handlers/leonardoai_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/lightwood_handler/functions.py +2 -2
- mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -1
- mindsdb/integrations/handlers/lightwood_handler/tests/test_lightwood_handler.py +11 -11
- mindsdb/integrations/handlers/llama_index_handler/llama_index_handler.py +4 -4
- mindsdb/integrations/handlers/llama_index_handler/settings.py +10 -9
- mindsdb/integrations/handlers/materialize_handler/tests/test_materialize_handler.py +8 -10
- mindsdb/integrations/handlers/matrixone_handler/matrixone_handler.py +4 -4
- mindsdb/integrations/handlers/matrixone_handler/tests/test_matrixone_handler.py +8 -9
- mindsdb/integrations/handlers/maxdb_handler/connection_args.py +25 -25
- mindsdb/integrations/handlers/maxdb_handler/maxdb_handler.py +1 -0
- mindsdb/integrations/handlers/mediawiki_handler/mediawiki_handler.py +3 -2
- mindsdb/integrations/handlers/mediawiki_handler/mediawiki_tables.py +1 -1
- mindsdb/integrations/handlers/mendeley_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/mendeley_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/mendeley_handler/mendeley_handler.py +48 -56
- mindsdb/integrations/handlers/mendeley_handler/mendeley_tables.py +24 -29
- mindsdb/integrations/handlers/mendeley_handler/tests/test_mendeley_handler.py +19 -17
- mindsdb/integrations/handlers/merlion_handler/merlion_handler.py +5 -4
- mindsdb/integrations/handlers/minds_endpoint_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/mlflow_handler/mlflow_handler.py +58 -36
- mindsdb/integrations/handlers/monetdb_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/monetdb_handler/__init__.py +15 -5
- mindsdb/integrations/handlers/monetdb_handler/connection_args.py +17 -18
- mindsdb/integrations/handlers/monetdb_handler/monetdb_handler.py +40 -57
- mindsdb/integrations/handlers/monetdb_handler/tests/test_monetdb_handler.py +7 -8
- mindsdb/integrations/handlers/monetdb_handler/utils/monet_get_id.py +13 -14
- mindsdb/integrations/handlers/monkeylearn_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/monkeylearn_handler.py +2 -5
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_graph_api_one_drive_client.py +1 -0
- mindsdb/integrations/handlers/ms_one_drive_handler/ms_one_drive_handler.py +1 -1
- mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +23 -23
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +3 -3
- mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +10 -5
- mindsdb/integrations/handlers/mssql_handler/mssql_handler.py +73 -8
- mindsdb/integrations/handlers/mysql_handler/__about__.py +8 -8
- mindsdb/integrations/handlers/mysql_handler/__init__.py +15 -5
- mindsdb/integrations/handlers/mysql_handler/connection_args.py +43 -47
- mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +101 -34
- mindsdb/integrations/handlers/mysql_handler/settings.py +15 -13
- mindsdb/integrations/handlers/neuralforecast_handler/neuralforecast_handler.py +1 -1
- mindsdb/integrations/handlers/newsapi_handler/newsapi_handler.py +1 -1
- mindsdb/integrations/handlers/newsapi_handler/tests/test_newsapi_handler.py +4 -4
- mindsdb/integrations/handlers/nuo_jdbc_handler/connection_args.py +2 -2
- mindsdb/integrations/handlers/nuo_jdbc_handler/nuo_jdbc_handler.py +28 -36
- mindsdb/integrations/handlers/nuo_jdbc_handler/tests/test_nuo_handler.py +5 -5
- mindsdb/integrations/handlers/oceanbase_handler/oceanbase_handler.py +0 -1
- mindsdb/integrations/handlers/oceanbase_handler/tests/test_oceanbase_handler.py +8 -10
- mindsdb/integrations/handlers/ollama_handler/ollama_handler.py +3 -3
- mindsdb/integrations/handlers/opengauss_handler/tests/test_opengauss_handler.py +1 -2
- mindsdb/integrations/handlers/openstreetmap_handler/__init__.py +7 -7
- mindsdb/integrations/handlers/oracle_handler/connection_args.py +6 -0
- mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +77 -11
- mindsdb/integrations/handlers/orioledb_handler/tests/test_orioledb_handler.py +8 -10
- mindsdb/integrations/handlers/palm_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/palm_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/palm_handler/palm_handler.py +1 -3
- mindsdb/integrations/handlers/paypal_handler/paypal_handler.py +2 -2
- mindsdb/integrations/handlers/paypal_handler/paypal_tables.py +15 -14
- mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +53 -10
- mindsdb/integrations/handlers/phoenix_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/phoenix_handler/phoenix_handler.py +1 -0
- mindsdb/integrations/handlers/pinot_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/pinot_handler/pinot_handler.py +3 -2
- mindsdb/integrations/handlers/plaid_handler/plaid_handler.py +13 -13
- mindsdb/integrations/handlers/plaid_handler/plaid_tables.py +10 -12
- mindsdb/integrations/handlers/plaid_handler/utils.py +4 -6
- mindsdb/integrations/handlers/planetscale_handler/planetscale_handler.py +1 -4
- mindsdb/integrations/handlers/portkey_handler/__init__.py +2 -2
- mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +105 -24
- mindsdb/integrations/handlers/postgres_handler/tests/test_postgres_handler.py +11 -6
- mindsdb/integrations/handlers/questdb_handler/questdb_handler.py +1 -2
- mindsdb/integrations/handlers/questdb_handler/tests/test_questdb_handler.py +2 -3
- mindsdb/integrations/handlers/quickbooks_handler/quickbooks_handler.py +6 -8
- mindsdb/integrations/handlers/quickbooks_handler/quickbooks_table.py +10 -10
- mindsdb/integrations/handlers/rag_handler/ingest.py +2 -2
- mindsdb/integrations/handlers/rag_handler/rag_handler.py +1 -1
- mindsdb/integrations/handlers/rag_handler/settings.py +1 -1
- mindsdb/integrations/handlers/reddit_handler/reddit_handler.py +2 -7
- mindsdb/integrations/handlers/reddit_handler/reddit_tables.py +2 -3
- mindsdb/integrations/handlers/replicate_handler/replicate_handler.py +6 -6
- mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_handler.py +1 -2
- mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_tables.py +0 -3
- mindsdb/integrations/handlers/rockset_handler/connection_args.py +14 -14
- mindsdb/integrations/handlers/rockset_handler/tests/test_rockset_handler.py +1 -0
- mindsdb/integrations/handlers/scylla_handler/scylla_handler.py +6 -5
- mindsdb/integrations/handlers/sendinblue_handler/sendinblue_handler.py +2 -1
- mindsdb/integrations/handlers/sendinblue_handler/sendinblue_tables.py +16 -16
- mindsdb/integrations/handlers/sentence_transformers_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/sheets_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/shopify_handler/shopify_handler.py +7 -6
- mindsdb/integrations/handlers/shopify_handler/shopify_tables.py +38 -41
- mindsdb/integrations/handlers/singlestore_handler/__about__.py +1 -1
- mindsdb/integrations/handlers/singlestore_handler/__init__.py +0 -1
- mindsdb/integrations/handlers/singlestore_handler/singlestore_handler.py +1 -0
- mindsdb/integrations/handlers/singlestore_handler/tests/test_singlestore_handler.py +3 -3
- mindsdb/integrations/handlers/slack_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +100 -6
- mindsdb/integrations/handlers/solr_handler/connection_args.py +7 -7
- mindsdb/integrations/handlers/solr_handler/solr_handler.py +2 -1
- mindsdb/integrations/handlers/solr_handler/tests/test_solr_handler.py +2 -1
- mindsdb/integrations/handlers/sqlany_handler/sqlany_handler.py +3 -2
- mindsdb/integrations/handlers/sqlite_handler/sqlite_handler.py +1 -0
- mindsdb/integrations/handlers/sqreamdb_handler/connection_args.py +1 -1
- mindsdb/integrations/handlers/sqreamdb_handler/sqreamdb_handler.py +15 -20
- mindsdb/integrations/handlers/sqreamdb_handler/tests/test_sqreamdb_handler.py +4 -4
- mindsdb/integrations/handlers/stabilityai_handler/__init__.py +1 -1
- mindsdb/integrations/handlers/starrocks_handler/starrocks_handler.py +0 -1
- mindsdb/integrations/handlers/starrocks_handler/tests/test_starrocks_handler.py +8 -10
- mindsdb/integrations/handlers/statsforecast_handler/statsforecast_handler.py +2 -2
- mindsdb/integrations/handlers/strava_handler/strava_handler.py +4 -8
- mindsdb/integrations/handlers/strava_handler/strava_tables.py +22 -30
- mindsdb/integrations/handlers/stripe_handler/stripe_handler.py +3 -2
- mindsdb/integrations/handlers/stripe_handler/stripe_tables.py +11 -27
- mindsdb/integrations/handlers/supabase_handler/tests/test_supabase_handler.py +1 -1
- mindsdb/integrations/handlers/surrealdb_handler/surrealdb_handler.py +4 -4
- mindsdb/integrations/handlers/tdengine_handler/tdengine_handler.py +25 -27
- mindsdb/integrations/handlers/tdengine_handler/tests/test_tdengine_handler.py +8 -8
- mindsdb/integrations/handlers/tidb_handler/tests/test_tidb_handler.py +1 -2
- mindsdb/integrations/handlers/timegpt_handler/timegpt_handler.py +5 -5
- mindsdb/integrations/handlers/tpot_handler/tpot_handler.py +21 -26
- mindsdb/integrations/handlers/trino_handler/trino_handler.py +14 -14
- mindsdb/integrations/handlers/twitter_handler/twitter_handler.py +2 -4
- mindsdb/integrations/handlers/unify_handler/tests/test_unify_handler.py +7 -8
- mindsdb/integrations/handlers/unify_handler/unify_handler.py +9 -9
- mindsdb/integrations/handlers/vertex_handler/vertex_client.py +1 -1
- mindsdb/integrations/handlers/vertica_handler/tests/test_vertica_handler.py +11 -11
- mindsdb/integrations/handlers/vertica_handler/vertica_handler.py +11 -14
- mindsdb/integrations/handlers/vitess_handler/tests/test_vitess_handler.py +9 -11
- mindsdb/integrations/handlers/vitess_handler/vitess_handler.py +0 -1
- mindsdb/integrations/handlers/web_handler/web_handler.py +1 -0
- mindsdb/integrations/handlers/whatsapp_handler/__init__.py +3 -3
- mindsdb/integrations/handlers/writer_handler/evaluate.py +1 -1
- mindsdb/integrations/handlers/writer_handler/settings.py +0 -1
- mindsdb/integrations/handlers/writer_handler/writer_handler.py +1 -0
- mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +5 -5
- mindsdb/integrations/handlers/youtube_handler/youtube_tables.py +26 -27
- mindsdb/integrations/handlers/yugabyte_handler/tests/test_yugabyte_handler.py +3 -3
- mindsdb/integrations/handlers/yugabyte_handler/yugabyte_handler.py +0 -6
- mindsdb/integrations/libs/response.py +67 -52
- mindsdb/integrations/libs/vectordatabase_handler.py +6 -0
- mindsdb/integrations/utilities/handler_utils.py +15 -3
- mindsdb/integrations/utilities/handlers/api_utilities/__init__.py +0 -1
- mindsdb/integrations/utilities/handlers/auth_utilities/__init__.py +0 -2
- mindsdb/integrations/utilities/utils.py +3 -3
- mindsdb/interfaces/agents/agents_controller.py +164 -1
- mindsdb/interfaces/agents/constants.py +15 -0
- mindsdb/interfaces/agents/langchain_agent.py +16 -4
- mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
- mindsdb/interfaces/knowledge_base/controller.py +25 -0
- mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +13 -10
- mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +434 -0
- mindsdb/interfaces/knowledge_base/preprocessing/models.py +54 -0
- mindsdb/interfaces/query_context/context_controller.py +66 -10
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +190 -0
- mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +92 -0
- mindsdb/interfaces/skills/skill_tool.py +202 -57
- mindsdb/interfaces/skills/sql_agent.py +205 -17
- mindsdb/interfaces/storage/fs.py +1 -0
- mindsdb/interfaces/variables/__init__.py +0 -0
- mindsdb/interfaces/variables/variables_controller.py +97 -0
- mindsdb/migrations/env.py +5 -7
- mindsdb/migrations/migrate.py +47 -7
- mindsdb/migrations/versions/2025-05-21_9f150e4f9a05_checkpoint_1.py +360 -0
- mindsdb/utilities/config.py +331 -219
- mindsdb/utilities/starters.py +13 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/METADATA +641 -695
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/RECORD +309 -288
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/WHEEL +1 -1
- mindsdb/integrations/handlers/monkeylearn_handler/requirements.txt +0 -1
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
from typing import Type, List, Any
|
|
2
|
+
import re
|
|
3
|
+
import json
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from langchain_core.tools import BaseTool
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class KnowledgeBaseListToolInput(BaseModel):
|
|
9
|
+
tool_input: str = Field(
|
|
10
|
+
"", description="An empty string to list all knowledge bases."
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class KnowledgeBaseListTool(BaseTool):
|
|
15
|
+
"""Tool for listing knowledge bases in MindsDB."""
|
|
16
|
+
|
|
17
|
+
name: str = "kb_list_tool"
|
|
18
|
+
description: str = "List all knowledge bases in MindsDB."
|
|
19
|
+
args_schema: Type[BaseModel] = KnowledgeBaseListToolInput
|
|
20
|
+
db: Any = None
|
|
21
|
+
|
|
22
|
+
def _run(self, tool_input: str) -> str:
|
|
23
|
+
"""List all knowledge bases."""
|
|
24
|
+
return self.db.get_usable_knowledge_base_names()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class KnowledgeBaseInfoToolInput(BaseModel):
|
|
28
|
+
tool_input: str = Field(
|
|
29
|
+
...,
|
|
30
|
+
description="A comma-separated list of knowledge base names enclosed between $START$ and $STOP$.",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class KnowledgeBaseInfoTool(BaseTool):
|
|
35
|
+
"""Tool for getting information about knowledge bases in MindsDB."""
|
|
36
|
+
|
|
37
|
+
name: str = "kb_info_tool"
|
|
38
|
+
description: str = "Get information about knowledge bases in MindsDB."
|
|
39
|
+
args_schema: Type[BaseModel] = KnowledgeBaseInfoToolInput
|
|
40
|
+
db: Any = None
|
|
41
|
+
|
|
42
|
+
def _extract_kb_names(self, tool_input: str) -> List[str]:
|
|
43
|
+
"""Extract knowledge base names from the tool input."""
|
|
44
|
+
match = re.search(r"\$START\$(.*?)\$STOP\$", tool_input, re.DOTALL)
|
|
45
|
+
if not match:
|
|
46
|
+
return []
|
|
47
|
+
|
|
48
|
+
# Extract and clean the knowledge base names
|
|
49
|
+
kb_names_str = match.group(1).strip()
|
|
50
|
+
kb_names = re.findall(r"`([^`]+)`", kb_names_str)
|
|
51
|
+
return kb_names
|
|
52
|
+
|
|
53
|
+
def _run(self, tool_input: str) -> str:
|
|
54
|
+
"""Get information about specified knowledge bases."""
|
|
55
|
+
kb_names = self._extract_kb_names(tool_input)
|
|
56
|
+
|
|
57
|
+
if not kb_names:
|
|
58
|
+
return "No valid knowledge base names provided. Please provide names enclosed in backticks between $START$ and $STOP$."
|
|
59
|
+
|
|
60
|
+
results = []
|
|
61
|
+
|
|
62
|
+
for kb_name in kb_names:
|
|
63
|
+
try:
|
|
64
|
+
# Get knowledge base schema
|
|
65
|
+
schema_result = self.db.run_no_throw(
|
|
66
|
+
f"DESCRIBE KNOWLEDGE_BASE `{kb_name}`;"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if not schema_result:
|
|
70
|
+
results.append(
|
|
71
|
+
f"Knowledge base `{kb_name}` not found or has no schema information."
|
|
72
|
+
)
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
# Get sample data
|
|
76
|
+
sample_data = self.db.run_no_throw(
|
|
77
|
+
f"SELECT * FROM `{kb_name}` LIMIT 10;"
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Format the results
|
|
81
|
+
kb_info = f"## Knowledge Base: `{kb_name}`\n\n"
|
|
82
|
+
|
|
83
|
+
# Schema information
|
|
84
|
+
kb_info += "### Schema Information:\n"
|
|
85
|
+
kb_info += "```\n"
|
|
86
|
+
for row in schema_result:
|
|
87
|
+
kb_info += f"{json.dumps(row, indent=2)}\n"
|
|
88
|
+
kb_info += "```\n\n"
|
|
89
|
+
|
|
90
|
+
# Sample data
|
|
91
|
+
kb_info += "### Sample Data:\n"
|
|
92
|
+
if sample_data:
|
|
93
|
+
# Extract column names
|
|
94
|
+
columns = list(sample_data[0].keys())
|
|
95
|
+
|
|
96
|
+
# Create markdown table header
|
|
97
|
+
kb_info += "| " + " | ".join(columns) + " |\n"
|
|
98
|
+
kb_info += "| " + " | ".join(["---" for _ in columns]) + " |\n"
|
|
99
|
+
|
|
100
|
+
# Add rows
|
|
101
|
+
for row in sample_data:
|
|
102
|
+
formatted_row = []
|
|
103
|
+
for col in columns:
|
|
104
|
+
cell_value = row[col]
|
|
105
|
+
if isinstance(cell_value, dict):
|
|
106
|
+
cell_value = json.dumps(cell_value, ensure_ascii=False)
|
|
107
|
+
formatted_row.append(str(cell_value).replace("|", "\\|"))
|
|
108
|
+
kb_info += "| " + " | ".join(formatted_row) + " |\n"
|
|
109
|
+
else:
|
|
110
|
+
kb_info += "No sample data available.\n"
|
|
111
|
+
|
|
112
|
+
results.append(kb_info)
|
|
113
|
+
|
|
114
|
+
except Exception as e:
|
|
115
|
+
results.append(
|
|
116
|
+
f"Error getting information for knowledge base `{kb_name}`: {str(e)}"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
return "\n\n".join(results)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class KnowledgeBaseQueryToolInput(BaseModel):
|
|
123
|
+
tool_input: str = Field(
|
|
124
|
+
...,
|
|
125
|
+
description="A SQL query for knowledge bases. Can be provided directly or enclosed between $START$ and $STOP$.",
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class KnowledgeBaseQueryTool(BaseTool):
|
|
130
|
+
"""Tool for querying knowledge bases in MindsDB."""
|
|
131
|
+
|
|
132
|
+
name: str = "kb_query_tool"
|
|
133
|
+
description: str = "Query knowledge bases in MindsDB."
|
|
134
|
+
args_schema: Type[BaseModel] = KnowledgeBaseQueryToolInput
|
|
135
|
+
db: Any = None
|
|
136
|
+
|
|
137
|
+
def _extract_query(self, tool_input: str) -> str:
|
|
138
|
+
"""Extract the SQL query from the tool input."""
|
|
139
|
+
# First check if the input is wrapped in $START$ and $STOP$
|
|
140
|
+
match = re.search(r"\$START\$(.*?)\$STOP\$", tool_input, re.DOTALL)
|
|
141
|
+
if match:
|
|
142
|
+
return match.group(1).strip()
|
|
143
|
+
|
|
144
|
+
# If not wrapped in delimiters, use the input directly
|
|
145
|
+
# Check for SQL keywords to validate it's likely a query
|
|
146
|
+
if re.search(
|
|
147
|
+
r"\b(SELECT|FROM|WHERE|LIMIT|ORDER BY)\b", tool_input, re.IGNORECASE
|
|
148
|
+
):
|
|
149
|
+
return tool_input.strip()
|
|
150
|
+
|
|
151
|
+
return ""
|
|
152
|
+
|
|
153
|
+
def _run(self, tool_input: str) -> str:
|
|
154
|
+
"""Execute a knowledge base query."""
|
|
155
|
+
query = self._extract_query(tool_input)
|
|
156
|
+
|
|
157
|
+
if not query:
|
|
158
|
+
return "No valid SQL query provided. Please provide a SQL query that includes SELECT, FROM, or other SQL keywords."
|
|
159
|
+
|
|
160
|
+
try:
|
|
161
|
+
# Execute the query
|
|
162
|
+
result = self.db.run_no_throw(query)
|
|
163
|
+
|
|
164
|
+
if not result:
|
|
165
|
+
return "Query executed successfully, but no results were returned."
|
|
166
|
+
|
|
167
|
+
# Format the results as a markdown table
|
|
168
|
+
if isinstance(result, list) and len(result) > 0:
|
|
169
|
+
# Extract column names
|
|
170
|
+
columns = list(result[0].keys())
|
|
171
|
+
|
|
172
|
+
# Create markdown table header
|
|
173
|
+
table = "| " + " | ".join(columns) + " |\n"
|
|
174
|
+
table += "| " + " | ".join(["---" for _ in columns]) + " |\n"
|
|
175
|
+
|
|
176
|
+
# Add rows
|
|
177
|
+
for row in result:
|
|
178
|
+
formatted_row = []
|
|
179
|
+
for col in columns:
|
|
180
|
+
cell_value = row[col]
|
|
181
|
+
if isinstance(cell_value, dict):
|
|
182
|
+
cell_value = json.dumps(cell_value, ensure_ascii=False)
|
|
183
|
+
formatted_row.append(str(cell_value).replace("|", "\\|"))
|
|
184
|
+
table += "| " + " | ".join(formatted_row) + " |\n"
|
|
185
|
+
|
|
186
|
+
return table
|
|
187
|
+
|
|
188
|
+
return result
|
|
189
|
+
except Exception as e:
|
|
190
|
+
return f"Error executing query: {str(e)}"
|
|
@@ -7,6 +7,11 @@ from langchain_community.tools import ListSQLDatabaseTool, InfoSQLDatabaseTool,
|
|
|
7
7
|
from langchain_core.tools import BaseTool
|
|
8
8
|
|
|
9
9
|
from mindsdb.interfaces.skills.custom.text2sql.mindsdb_sql_tool import MindsDBSQLParserTool
|
|
10
|
+
from mindsdb.interfaces.skills.custom.text2sql.mindsdb_kb_tools import (
|
|
11
|
+
KnowledgeBaseListTool,
|
|
12
|
+
KnowledgeBaseInfoTool,
|
|
13
|
+
KnowledgeBaseQueryTool
|
|
14
|
+
)
|
|
10
15
|
|
|
11
16
|
|
|
12
17
|
class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
@@ -107,9 +112,96 @@ class MindsDBSQLToolkit(SQLDatabaseToolkit):
|
|
|
107
112
|
description=mindsdb_sql_parser_tool_description
|
|
108
113
|
)
|
|
109
114
|
|
|
115
|
+
# Knowledge base tools
|
|
116
|
+
kb_list_tool = KnowledgeBaseListTool(
|
|
117
|
+
name=f'kb_list_tool{prefix}',
|
|
118
|
+
db=self.db,
|
|
119
|
+
description=dedent("""\
|
|
120
|
+
Lists all available knowledge bases that can be queried.
|
|
121
|
+
Input: No input required, just call the tool directly.
|
|
122
|
+
Output: A table of all available knowledge bases with their names and creation dates.
|
|
123
|
+
|
|
124
|
+
Use this tool first when answering factual questions to see what knowledge bases are available.
|
|
125
|
+
Each knowledge base name is escaped using backticks.
|
|
126
|
+
|
|
127
|
+
Example usage: kb_list_tool()
|
|
128
|
+
""")
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
kb_info_tool = KnowledgeBaseInfoTool(
|
|
132
|
+
name=f'kb_info_tool{prefix}',
|
|
133
|
+
db=self.db,
|
|
134
|
+
description=dedent(f"""\
|
|
135
|
+
Gets detailed information about specific knowledge bases including their structure and metadata fields.
|
|
136
|
+
|
|
137
|
+
Input: A knowledge base name as a simple string.
|
|
138
|
+
Output: Schema, metadata columns, and sample rows for the specified knowledge base.
|
|
139
|
+
|
|
140
|
+
Use this after kb_list_tool to understand what information is contained in the knowledge base
|
|
141
|
+
and what metadata fields are available for filtering.
|
|
142
|
+
|
|
143
|
+
Example usage: kb_info_tool("kb_name")
|
|
144
|
+
|
|
145
|
+
Make sure the knowledge base exists by calling {kb_list_tool.name} first.
|
|
146
|
+
""")
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
kb_query_tool = KnowledgeBaseQueryTool(
|
|
150
|
+
name=f'kb_query_tool{prefix}',
|
|
151
|
+
db=self.db,
|
|
152
|
+
description=dedent(f"""\
|
|
153
|
+
Queries knowledge bases using SQL syntax to retrieve relevant information.
|
|
154
|
+
|
|
155
|
+
Input: A SQL query string that targets a knowledge base.
|
|
156
|
+
Output: Knowledge base search results or error message.
|
|
157
|
+
|
|
158
|
+
This tool is designed for semantic search and metadata filtering in MindsDB knowledge bases.
|
|
159
|
+
|
|
160
|
+
Query Types and Examples:
|
|
161
|
+
1. Basic semantic search:
|
|
162
|
+
kb_query_tool("SELECT * FROM kb_name WHERE content = 'your search query';")
|
|
163
|
+
|
|
164
|
+
2. Metadata filtering:
|
|
165
|
+
kb_query_tool("SELECT * FROM kb_name WHERE metadata_field = 'value';")
|
|
166
|
+
|
|
167
|
+
3. Combined search:
|
|
168
|
+
kb_query_tool("SELECT * FROM kb_name WHERE content = 'query' AND metadata_field = 'value';")
|
|
169
|
+
|
|
170
|
+
4. Setting relevance threshold:
|
|
171
|
+
kb_query_tool("SELECT * FROM kb_name WHERE content = 'query' AND relevance_threshold = 0.7;")
|
|
172
|
+
|
|
173
|
+
5. Limiting results:
|
|
174
|
+
kb_query_tool("SELECT * FROM kb_name WHERE content = 'query' LIMIT 5;")
|
|
175
|
+
|
|
176
|
+
6. Getting sample data:
|
|
177
|
+
kb_query_tool("SELECT * FROM kb_name LIMIT 3;")
|
|
178
|
+
|
|
179
|
+
7. Don't use LIKE operator on content filter ie semantic search:
|
|
180
|
+
SELECT * FROM `test_kb` WHERE content LIKE '%population of New York%' $STOP$
|
|
181
|
+
|
|
182
|
+
Like is not supported, use the following instead:
|
|
183
|
+
SELECT * FROM `test_kb` WHERE content = 'population of New York'
|
|
184
|
+
|
|
185
|
+
Result Format:
|
|
186
|
+
- Results include: id, chunk_id, chunk_content, metadata, distance, and relevance columns
|
|
187
|
+
- The metadata column contains a JSON object with all metadata fields
|
|
188
|
+
|
|
189
|
+
Best Practices:
|
|
190
|
+
- Always check available knowledge bases with {kb_list_tool.name} first
|
|
191
|
+
- Use {kb_info_tool.name} to understand the structure and metadata fields
|
|
192
|
+
- Always include a semicolon at the end of your SQL query
|
|
193
|
+
|
|
194
|
+
For factual questions, use this tool to retrieve information rather than relying on the model's knowledge.
|
|
195
|
+
""")
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Return standard SQL tools and knowledge base tools
|
|
110
199
|
return [
|
|
111
200
|
query_sql_database_tool,
|
|
112
201
|
info_sql_database_tool,
|
|
113
202
|
list_sql_database_tool,
|
|
114
203
|
mindsdb_sql_parser_tool,
|
|
204
|
+
kb_list_tool,
|
|
205
|
+
kb_info_tool,
|
|
206
|
+
kb_query_tool,
|
|
115
207
|
]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import enum
|
|
2
2
|
import inspect
|
|
3
|
+
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from collections import defaultdict
|
|
5
6
|
from typing import List, Dict, Optional
|
|
@@ -14,7 +15,7 @@ from mindsdb.utilities.config import config
|
|
|
14
15
|
from mindsdb.interfaces.storage import db
|
|
15
16
|
from mindsdb.interfaces.skills.sql_agent import SQLAgent
|
|
16
17
|
from mindsdb.integrations.libs.vectordatabase_handler import TableField
|
|
17
|
-
|
|
18
|
+
from mindsdb.interfaces.agents.constants import DEFAULT_TEXT2SQL_DATABASE
|
|
18
19
|
|
|
19
20
|
_DEFAULT_TOP_K_SIMILARITY_SEARCH = 5
|
|
20
21
|
_MAX_CACHE_SIZE = 1000
|
|
@@ -120,7 +121,6 @@ class SkillToolController:
|
|
|
120
121
|
try:
|
|
121
122
|
from mindsdb.interfaces.agents.mindsdb_database_agent import MindsDBSQL
|
|
122
123
|
from mindsdb.interfaces.skills.custom.text2sql.mindsdb_sql_toolkit import MindsDBSQLToolkit
|
|
123
|
-
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
|
|
124
124
|
except ImportError:
|
|
125
125
|
raise ImportError(
|
|
126
126
|
'To use the text-to-SQL skill, please install langchain with `pip install mindsdb[langchain]`')
|
|
@@ -132,75 +132,220 @@ class SkillToolController:
|
|
|
132
132
|
return f'`{name}`'
|
|
133
133
|
|
|
134
134
|
tables_list = []
|
|
135
|
+
knowledge_bases_list = []
|
|
136
|
+
ignore_knowledge_bases_list = []
|
|
137
|
+
|
|
138
|
+
# Track databases extracted from dot notation
|
|
139
|
+
extracted_databases = set()
|
|
140
|
+
|
|
141
|
+
# Initialize knowledge_base_database with default value
|
|
142
|
+
knowledge_base_database = DEFAULT_TEXT2SQL_DATABASE # Default to mindsdb project
|
|
143
|
+
|
|
144
|
+
# First pass: collect all database and knowledge base parameters
|
|
135
145
|
for skill in skills:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
146
|
+
# Update knowledge_base_database if specified in any skill
|
|
147
|
+
if skill.params.get('knowledge_base_database'):
|
|
148
|
+
knowledge_base_database = skill.params.get('knowledge_base_database')
|
|
149
|
+
|
|
150
|
+
# Extract databases from include_tables with dot notation
|
|
151
|
+
if skill.params.get('include_tables'):
|
|
152
|
+
include_tables = skill.params.get('include_tables')
|
|
153
|
+
if isinstance(include_tables, str):
|
|
154
|
+
include_tables = [t.strip() for t in include_tables.split(',')]
|
|
155
|
+
|
|
156
|
+
# Extract database names from dot notation
|
|
157
|
+
for table in include_tables:
|
|
158
|
+
if '.' in table:
|
|
159
|
+
db_name = table.split('.')[0]
|
|
160
|
+
extracted_databases.add(db_name)
|
|
161
|
+
|
|
162
|
+
# Extract databases from include_knowledge_bases with dot notation
|
|
163
|
+
if skill.params.get('include_knowledge_bases'):
|
|
164
|
+
include_kbs = skill.params.get('include_knowledge_bases')
|
|
165
|
+
if isinstance(include_kbs, str):
|
|
166
|
+
include_kbs = [kb.strip() for kb in include_kbs.split(',')]
|
|
167
|
+
|
|
168
|
+
# Extract database names from dot notation
|
|
169
|
+
for kb in include_kbs:
|
|
170
|
+
if '.' in kb:
|
|
171
|
+
db_name = kb.split('.')[0]
|
|
172
|
+
if db_name != knowledge_base_database:
|
|
173
|
+
# Only update if it's different from the default
|
|
174
|
+
knowledge_base_database = db_name
|
|
175
|
+
|
|
176
|
+
# Second pass: collect all tables and knowledge base restrictions
|
|
177
|
+
for skill in skills:
|
|
178
|
+
# Get database for tables (this is an actual database connection)
|
|
179
|
+
database = skill.params.get('database', DEFAULT_TEXT2SQL_DATABASE)
|
|
180
|
+
|
|
181
|
+
# Add databases extracted from dot notation if no explicit database is provided
|
|
182
|
+
if not database and extracted_databases:
|
|
183
|
+
# Use the first extracted database if no explicit database is provided
|
|
184
|
+
database = next(iter(extracted_databases))
|
|
185
|
+
# Update the skill params with the extracted database
|
|
186
|
+
skill.params['database'] = database
|
|
187
|
+
|
|
188
|
+
# Extract knowledge base restrictions if they exist in the skill params
|
|
189
|
+
if skill.params.get('include_knowledge_bases'):
|
|
190
|
+
# Convert to list if it's a string
|
|
191
|
+
include_kbs = skill.params.get('include_knowledge_bases')
|
|
192
|
+
if isinstance(include_kbs, str):
|
|
193
|
+
include_kbs = [kb.strip() for kb in include_kbs.split(',')]
|
|
194
|
+
|
|
195
|
+
# Process each knowledge base name
|
|
196
|
+
for kb in include_kbs:
|
|
197
|
+
# If it doesn't have a dot, prefix it with the knowledge_base_database
|
|
198
|
+
if '.' not in kb:
|
|
199
|
+
knowledge_bases_list.append(f"{knowledge_base_database}.{kb}")
|
|
200
|
+
else:
|
|
201
|
+
knowledge_bases_list.append(kb)
|
|
202
|
+
|
|
203
|
+
# Collect ignore_knowledge_bases
|
|
204
|
+
if skill.params.get('ignore_knowledge_bases'):
|
|
205
|
+
# Convert to list if it's a string
|
|
206
|
+
ignore_kbs = skill.params.get('ignore_knowledge_bases')
|
|
207
|
+
if isinstance(ignore_kbs, str):
|
|
208
|
+
ignore_kbs = [kb.strip() for kb in ignore_kbs.split(',')]
|
|
209
|
+
|
|
210
|
+
# Process each knowledge base name to ignore
|
|
211
|
+
for kb in ignore_kbs:
|
|
212
|
+
# If it doesn't have a dot, prefix it with the knowledge_base_database
|
|
213
|
+
if '.' not in kb:
|
|
214
|
+
ignore_knowledge_bases_list.append(f"{knowledge_base_database}.{kb}")
|
|
215
|
+
else:
|
|
216
|
+
ignore_knowledge_bases_list.append(kb)
|
|
217
|
+
|
|
218
|
+
# Skip if no database specified
|
|
219
|
+
if not database:
|
|
154
220
|
continue
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
221
|
+
|
|
222
|
+
# Process include_tables with dot notation
|
|
223
|
+
if skill.params.get('include_tables'):
|
|
224
|
+
include_tables = skill.params.get('include_tables')
|
|
225
|
+
if isinstance(include_tables, str):
|
|
226
|
+
include_tables = [t.strip() for t in include_tables.split(',')]
|
|
227
|
+
|
|
228
|
+
for table in include_tables:
|
|
229
|
+
# If table already has a database prefix, use it as is
|
|
230
|
+
if '.' in table:
|
|
231
|
+
# Check if the table already has backticks
|
|
232
|
+
if '`' in table:
|
|
233
|
+
tables_list.append(table)
|
|
234
|
+
else:
|
|
235
|
+
# Apply escape_table_name only to the table part
|
|
236
|
+
parts = table.split('.')
|
|
237
|
+
if len(parts) == 2:
|
|
238
|
+
# Format: database.table
|
|
239
|
+
tables_list.append(f"{parts[0]}.{escape_table_name(parts[1])}")
|
|
240
|
+
elif len(parts) == 3:
|
|
241
|
+
# Format: database.schema.table
|
|
242
|
+
tables_list.append(f"{parts[0]}.{parts[1]}.{escape_table_name(parts[2])}")
|
|
243
|
+
else:
|
|
244
|
+
# Unusual format, escape the whole thing
|
|
245
|
+
tables_list.append(escape_table_name(table))
|
|
159
246
|
else:
|
|
160
|
-
|
|
247
|
+
# Otherwise, prefix with the database
|
|
248
|
+
tables_list.append(f"{database}.{escape_table_name(table)}")
|
|
249
|
+
|
|
250
|
+
# Skip further table processing if include_tables is specified
|
|
251
|
+
continue
|
|
252
|
+
|
|
253
|
+
restriction_on_tables = skill.restriction_on_tables
|
|
254
|
+
|
|
255
|
+
if restriction_on_tables is None and database:
|
|
256
|
+
try:
|
|
257
|
+
handler = command_executor.session.integration_controller.get_data_handler(database)
|
|
258
|
+
if 'all' in inspect.signature(handler.get_tables).parameters:
|
|
259
|
+
response = handler.get_tables(all=True)
|
|
260
|
+
else:
|
|
261
|
+
response = handler.get_tables()
|
|
262
|
+
# no restrictions
|
|
263
|
+
columns = [c.lower() for c in response.data_frame.columns]
|
|
264
|
+
name_idx = columns.index('table_name') if 'table_name' in columns else 0
|
|
265
|
+
|
|
266
|
+
if 'table_schema' in response.data_frame.columns:
|
|
267
|
+
for _, row in response.data_frame.iterrows():
|
|
268
|
+
tables_list.append(f"{database}.{row['table_schema']}.{escape_table_name(row[name_idx])}")
|
|
269
|
+
else:
|
|
270
|
+
for table_name in response.data_frame.iloc[:, name_idx]:
|
|
271
|
+
tables_list.append(f"{database}.{escape_table_name(table_name)}")
|
|
272
|
+
except Exception as e:
|
|
273
|
+
logger.warning(f"Could not get tables from database {database}: {str(e)}")
|
|
274
|
+
continue
|
|
275
|
+
|
|
276
|
+
# Handle table restrictions
|
|
277
|
+
if restriction_on_tables and database:
|
|
278
|
+
for schema_name, tables in restriction_on_tables.items():
|
|
279
|
+
for table in tables:
|
|
280
|
+
# Check if the table already has dot notation (e.g., 'postgresql_conn.home_rentals')
|
|
281
|
+
if '.' in table:
|
|
282
|
+
# Table already has database prefix, add it directly
|
|
283
|
+
tables_list.append(escape_table_name(table))
|
|
284
|
+
else:
|
|
285
|
+
# No dot notation, apply schema and database as needed
|
|
286
|
+
if schema_name is None:
|
|
287
|
+
tables_list.append(f'{database}.{escape_table_name(table)}')
|
|
288
|
+
else:
|
|
289
|
+
tables_list.append(f'{database}.{schema_name}.{escape_table_name(table)}')
|
|
290
|
+
continue
|
|
291
|
+
|
|
292
|
+
# Remove duplicates from lists
|
|
293
|
+
tables_list = list(set(tables_list))
|
|
294
|
+
knowledge_bases_list = list(set(knowledge_bases_list))
|
|
295
|
+
ignore_knowledge_bases_list = list(set(ignore_knowledge_bases_list))
|
|
296
|
+
|
|
297
|
+
# Determine knowledge base parameters to pass to SQLAgent
|
|
298
|
+
include_knowledge_bases = knowledge_bases_list if knowledge_bases_list else None
|
|
299
|
+
ignore_knowledge_bases = ignore_knowledge_bases_list if ignore_knowledge_bases_list else None
|
|
300
|
+
|
|
301
|
+
# If both include and ignore lists exist, include takes precedence
|
|
302
|
+
if include_knowledge_bases:
|
|
303
|
+
ignore_knowledge_bases = None
|
|
304
|
+
|
|
305
|
+
# # Get all databases from skills and extracted databases
|
|
306
|
+
# all_databases = list(set([s.params.get('database', DEFAULT_TEXT2SQL_DATABASE) for s in skills if s.params.get('database')] + list(extracted_databases)))
|
|
307
|
+
#
|
|
308
|
+
#
|
|
309
|
+
# # If no databases were specified or extracted, use 'mindsdb' as a default
|
|
310
|
+
# if not all_databases:
|
|
311
|
+
# all_databases = [DEFAULT_TEXT2SQL_DATABASE]
|
|
312
|
+
#
|
|
313
|
+
|
|
314
|
+
all_databases = []
|
|
315
|
+
# Filter out None values
|
|
316
|
+
all_databases = [db for db in all_databases if db is not None]
|
|
317
|
+
|
|
318
|
+
# Create a databases_struct dictionary that includes all extracted databases
|
|
319
|
+
databases_struct = {}
|
|
320
|
+
|
|
321
|
+
# First, add databases from skills with explicit database parameters
|
|
322
|
+
for skill in skills:
|
|
323
|
+
if skill.params.get('database'):
|
|
324
|
+
databases_struct[skill.params['database']] = skill.restriction_on_tables
|
|
325
|
+
|
|
326
|
+
# Then, add all extracted databases with no restrictions
|
|
327
|
+
for db_name in extracted_databases:
|
|
328
|
+
if db_name not in databases_struct:
|
|
329
|
+
databases_struct[db_name] = None
|
|
161
330
|
|
|
162
331
|
sql_agent = SQLAgent(
|
|
163
332
|
command_executor=command_executor,
|
|
164
|
-
databases=
|
|
165
|
-
databases_struct=
|
|
166
|
-
skill.params['database']: skill.restriction_on_tables
|
|
167
|
-
for skill in skills
|
|
168
|
-
},
|
|
333
|
+
databases=all_databases,
|
|
334
|
+
databases_struct=databases_struct,
|
|
169
335
|
include_tables=tables_list,
|
|
170
336
|
ignore_tables=None,
|
|
337
|
+
include_knowledge_bases=include_knowledge_bases,
|
|
338
|
+
ignore_knowledge_bases=ignore_knowledge_bases,
|
|
339
|
+
knowledge_base_database=knowledge_base_database,
|
|
171
340
|
sample_rows_in_table_info=3,
|
|
341
|
+
|
|
172
342
|
cache=get_cache('agent', max_size=_MAX_CACHE_SIZE)
|
|
173
343
|
)
|
|
174
344
|
db = MindsDBSQL.custom_init(
|
|
175
345
|
sql_agent=sql_agent
|
|
176
346
|
)
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
sql_database_tools = MindsDBSQLToolkit(db=db, llm=llm).get_tools()
|
|
180
|
-
descriptions = []
|
|
181
|
-
for skill in skills:
|
|
182
|
-
description = skill.params.get('description', '')
|
|
183
|
-
if description:
|
|
184
|
-
descriptions.append(description)
|
|
185
|
-
|
|
186
|
-
for i, tool in enumerate(sql_database_tools):
|
|
187
|
-
if isinstance(tool, QuerySQLDataBaseTool):
|
|
188
|
-
# Add our own custom description so our agent knows when to query this table.
|
|
189
|
-
original_description = tool.description
|
|
190
|
-
tool.description = ''
|
|
191
|
-
if len(descriptions) > 0:
|
|
192
|
-
tool.description += f'Use this tool if you need data about {" OR ".join(descriptions)}.\n'
|
|
193
|
-
tool.description += 'Use the conversation context to decide which table to query.\n'
|
|
194
|
-
if len(tables_list) > 0:
|
|
195
|
-
f'These are the available tables: {",".join(tables_list)}.\n'
|
|
196
|
-
tool.description += (
|
|
197
|
-
'ALWAYS consider these special cases:\n'
|
|
198
|
-
' - For TIMESTAMP type columns, make sure you include the time portion in your query (e.g. WHERE date_column = "2020-01-01 12:00:00")\n'
|
|
199
|
-
'Here are the rest of the instructions:\n'
|
|
200
|
-
f'{original_description}'
|
|
201
|
-
)
|
|
202
|
-
sql_database_tools[i] = tool
|
|
203
|
-
return sql_database_tools
|
|
347
|
+
toolkit = MindsDBSQLToolkit(db=db, llm=llm)
|
|
348
|
+
return toolkit.get_tools()
|
|
204
349
|
|
|
205
350
|
def _make_retrieval_tools(self, skill: db.Skills, llm, embedding_model):
|
|
206
351
|
"""
|