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
|
@@ -43,6 +43,11 @@ def get_api_key(
|
|
|
43
43
|
if f"{api_name.lower()}_api_key" in create_args:
|
|
44
44
|
return create_args[f"{api_name.lower()}_api_key"]
|
|
45
45
|
|
|
46
|
+
# 2.5 - Check in params dictionary if it exists (for agents)
|
|
47
|
+
if "params" in create_args and create_args["params"] is not None:
|
|
48
|
+
if f"{api_name.lower()}_api_key" in create_args["params"]:
|
|
49
|
+
return create_args["params"][f"{api_name.lower()}_api_key"]
|
|
50
|
+
|
|
46
51
|
# 3
|
|
47
52
|
if engine_storage is not None:
|
|
48
53
|
connection_args = engine_storage.get_connection_args()
|
|
@@ -68,7 +73,14 @@ def get_api_key(
|
|
|
68
73
|
return create_args['api_keys'][api_name]
|
|
69
74
|
|
|
70
75
|
if strict:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
76
|
+
provider_upper = api_name.upper()
|
|
77
|
+
api_key_env_var = f"{provider_upper}_API_KEY"
|
|
78
|
+
api_key_arg = f"{api_name.lower()}_api_key"
|
|
79
|
+
error_message = (
|
|
80
|
+
f"API key for {api_name} not found. Please provide it using one of the following methods:\n"
|
|
81
|
+
f"1. Set the {api_key_env_var} environment variable\n"
|
|
82
|
+
f"2. Provide it as '{api_key_arg}' parameter when creating an agent using the CREATE AGENT syntax\n"
|
|
83
|
+
f" Example: CREATE AGENT my_agent USING model='gpt-4', provider='{api_name}', {api_key_arg}='your-api-key';\n"
|
|
84
|
+
)
|
|
85
|
+
raise Exception(error_message)
|
|
74
86
|
return None
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
from .microsoft import MSGraphAPIBaseClient
|
|
@@ -8,7 +8,7 @@ def format_exception_error(exception):
|
|
|
8
8
|
exception_type, _exception_object, exception_traceback = sys.exc_info()
|
|
9
9
|
filename = exception_traceback.tb_frame.f_code.co_filename
|
|
10
10
|
line_number = exception_traceback.tb_lineno
|
|
11
|
-
error_message = f
|
|
11
|
+
error_message = f"{exception_type.__name__}: {exception}, raised at: {filename}#{line_number}"
|
|
12
12
|
except Exception:
|
|
13
13
|
error_message = str(exception)
|
|
14
14
|
return error_message
|
|
@@ -26,7 +26,7 @@ def dict_to_yaml(d, indent=0):
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
# Mocks won't always have 'name' attribute.
|
|
29
|
-
def get_class_name(instance: Any, default: str =
|
|
30
|
-
if hasattr(instance.__class__,
|
|
29
|
+
def get_class_name(instance: Any, default: str = "unknown"):
|
|
30
|
+
if hasattr(instance.__class__, "name"):
|
|
31
31
|
return instance.__class__.name
|
|
32
32
|
return default
|
|
@@ -19,9 +19,10 @@ from mindsdb.utilities.exception import EntityExistsError, EntityNotExistsError
|
|
|
19
19
|
from .constants import ASSISTANT_COLUMN, SUPPORTED_PROVIDERS, PROVIDER_TO_MODELS
|
|
20
20
|
from .langchain_agent import get_llm_provider
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
default_project = config.get('default_project')
|
|
24
23
|
|
|
24
|
+
DEFAULT_TEXT2SQL_DATABASE = 'mindsdb'
|
|
25
|
+
|
|
25
26
|
|
|
26
27
|
class AgentsController:
|
|
27
28
|
'''Handles CRUD operations at the database level for Agents'''
|
|
@@ -158,6 +159,13 @@ class AgentsController:
|
|
|
158
159
|
with one of keys is "name", and other is additional parameters for relationship agent<>skill
|
|
159
160
|
provider (str): The provider of the model
|
|
160
161
|
params (Dict[str, str]): Parameters to use when running the agent
|
|
162
|
+
database: The database to use for text2sql skills (default is 'mindsdb')
|
|
163
|
+
knowledge_base_database: The database to use for knowledge base queries (default is 'mindsdb')
|
|
164
|
+
include_tables: List of tables to include for text2sql skills
|
|
165
|
+
ignore_tables: List of tables to ignore for text2sql skills
|
|
166
|
+
include_knowledge_bases: List of knowledge bases to include for text2sql skills
|
|
167
|
+
ignore_knowledge_bases: List of knowledge bases to ignore for text2sql skills
|
|
168
|
+
<provider>_api_key: API key for the provider (e.g., openai_api_key)
|
|
161
169
|
|
|
162
170
|
Returns:
|
|
163
171
|
agent (db.Agents): The created agent
|
|
@@ -176,6 +184,128 @@ class AgentsController:
|
|
|
176
184
|
|
|
177
185
|
_, provider = self.check_model_provider(model_name, provider)
|
|
178
186
|
|
|
187
|
+
# Extract API key if provided in the format <provider>_api_key
|
|
188
|
+
provider_api_key_param = f"{provider.lower()}_api_key"
|
|
189
|
+
if provider_api_key_param in params:
|
|
190
|
+
# Keep the API key in params for the agent to use
|
|
191
|
+
# It will be picked up by get_api_key() in handler_utils.py
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
# Extract table and knowledge base parameters from params
|
|
195
|
+
database = params.pop('database', None)
|
|
196
|
+
knowledge_base_database = params.pop('knowledge_base_database', DEFAULT_TEXT2SQL_DATABASE)
|
|
197
|
+
include_tables = params.pop('include_tables', None)
|
|
198
|
+
ignore_tables = params.pop('ignore_tables', None)
|
|
199
|
+
include_knowledge_bases = params.pop('include_knowledge_bases', None)
|
|
200
|
+
ignore_knowledge_bases = params.pop('ignore_knowledge_bases', None)
|
|
201
|
+
|
|
202
|
+
# Save the extracted parameters back to params for API responses only if they were explicitly provided
|
|
203
|
+
# or if they're needed for skills
|
|
204
|
+
need_params = include_tables or ignore_tables or include_knowledge_bases or ignore_knowledge_bases
|
|
205
|
+
|
|
206
|
+
if 'database' in params or need_params:
|
|
207
|
+
params['database'] = database
|
|
208
|
+
|
|
209
|
+
if 'knowledge_base_database' in params or include_knowledge_bases or ignore_knowledge_bases:
|
|
210
|
+
params['knowledge_base_database'] = knowledge_base_database
|
|
211
|
+
|
|
212
|
+
if include_tables is not None:
|
|
213
|
+
params['include_tables'] = include_tables
|
|
214
|
+
if ignore_tables is not None:
|
|
215
|
+
params['ignore_tables'] = ignore_tables
|
|
216
|
+
if include_knowledge_bases is not None:
|
|
217
|
+
params['include_knowledge_bases'] = include_knowledge_bases
|
|
218
|
+
if ignore_knowledge_bases is not None:
|
|
219
|
+
params['ignore_knowledge_bases'] = ignore_knowledge_bases
|
|
220
|
+
|
|
221
|
+
# Convert string parameters to lists if needed
|
|
222
|
+
if isinstance(include_tables, str):
|
|
223
|
+
include_tables = [t.strip() for t in include_tables.split(',')]
|
|
224
|
+
if isinstance(ignore_tables, str):
|
|
225
|
+
ignore_tables = [t.strip() for t in ignore_tables.split(',')]
|
|
226
|
+
if isinstance(include_knowledge_bases, str):
|
|
227
|
+
include_knowledge_bases = [kb.strip() for kb in include_knowledge_bases.split(',')]
|
|
228
|
+
if isinstance(ignore_knowledge_bases, str):
|
|
229
|
+
ignore_knowledge_bases = [kb.strip() for kb in ignore_knowledge_bases.split(',')]
|
|
230
|
+
|
|
231
|
+
# Auto-create SQL skill if no skills are provided but include_tables or include_knowledge_bases params are provided
|
|
232
|
+
if not skills and (include_tables or include_knowledge_bases):
|
|
233
|
+
# Determine database to use (default to 'mindsdb')
|
|
234
|
+
db_name = database
|
|
235
|
+
kb_db_name = knowledge_base_database
|
|
236
|
+
|
|
237
|
+
# If database is not explicitly provided but tables are, try to extract the database name from the first table
|
|
238
|
+
if not database and include_tables and len(include_tables) > 0:
|
|
239
|
+
parts = include_tables[0].split('.')
|
|
240
|
+
if len(parts) >= 2:
|
|
241
|
+
db_name = parts[0]
|
|
242
|
+
elif not database and ignore_tables and len(ignore_tables) > 0:
|
|
243
|
+
parts = ignore_tables[0].split('.')
|
|
244
|
+
if len(parts) >= 2:
|
|
245
|
+
db_name = parts[0]
|
|
246
|
+
|
|
247
|
+
# Create a default SQL skill
|
|
248
|
+
skill_name = f"{name}_sql_skill"
|
|
249
|
+
skill_params = {
|
|
250
|
+
'type': 'sql',
|
|
251
|
+
'database': db_name,
|
|
252
|
+
'description': f'Auto-generated SQL skill for agent {name}'
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
# Add knowledge base database if provided
|
|
256
|
+
if knowledge_base_database:
|
|
257
|
+
skill_params['knowledge_base_database'] = knowledge_base_database
|
|
258
|
+
|
|
259
|
+
# Add knowledge base parameters if provided
|
|
260
|
+
if include_knowledge_bases:
|
|
261
|
+
skill_params['include_knowledge_bases'] = include_knowledge_bases
|
|
262
|
+
if ignore_knowledge_bases:
|
|
263
|
+
skill_params['ignore_knowledge_bases'] = ignore_knowledge_bases
|
|
264
|
+
|
|
265
|
+
try:
|
|
266
|
+
# Check if skill already exists
|
|
267
|
+
existing_skill = self.skills_controller.get_skill(skill_name, project_name)
|
|
268
|
+
if existing_skill is None:
|
|
269
|
+
# Create the skill
|
|
270
|
+
skill_type = skill_params.pop('type')
|
|
271
|
+
self.skills_controller.add_skill(
|
|
272
|
+
name=skill_name,
|
|
273
|
+
project_name=project_name,
|
|
274
|
+
type=skill_type,
|
|
275
|
+
params=skill_params
|
|
276
|
+
)
|
|
277
|
+
else:
|
|
278
|
+
# Update the skill if parameters have changed
|
|
279
|
+
params_changed = False
|
|
280
|
+
|
|
281
|
+
# Check if database has changed
|
|
282
|
+
if existing_skill.params.get('database') != db_name:
|
|
283
|
+
existing_skill.params['database'] = db_name
|
|
284
|
+
params_changed = True
|
|
285
|
+
|
|
286
|
+
# Check if knowledge base database has changed
|
|
287
|
+
if knowledge_base_database and existing_skill.params.get('knowledge_base_database') != kb_db_name:
|
|
288
|
+
existing_skill.params['knowledge_base_database'] = kb_db_name
|
|
289
|
+
params_changed = True
|
|
290
|
+
|
|
291
|
+
# Check if knowledge base parameters have changed
|
|
292
|
+
if include_knowledge_bases and existing_skill.params.get('include_knowledge_bases') != include_knowledge_bases:
|
|
293
|
+
existing_skill.params['include_knowledge_bases'] = include_knowledge_bases
|
|
294
|
+
params_changed = True
|
|
295
|
+
|
|
296
|
+
if ignore_knowledge_bases and existing_skill.params.get('ignore_knowledge_bases') != ignore_knowledge_bases:
|
|
297
|
+
existing_skill.params['ignore_knowledge_bases'] = ignore_knowledge_bases
|
|
298
|
+
params_changed = True
|
|
299
|
+
|
|
300
|
+
# Update the skill if needed
|
|
301
|
+
if params_changed:
|
|
302
|
+
flag_modified(existing_skill, 'params')
|
|
303
|
+
db.session.commit()
|
|
304
|
+
|
|
305
|
+
skills = [skill_name]
|
|
306
|
+
except Exception as e:
|
|
307
|
+
raise ValueError(f"Failed to auto-create or update SQL skill: {str(e)}")
|
|
308
|
+
|
|
179
309
|
agent = db.Agents(
|
|
180
310
|
name=name,
|
|
181
311
|
project_id=project.id,
|
|
@@ -193,10 +323,43 @@ class AgentsController:
|
|
|
193
323
|
else:
|
|
194
324
|
parameters = skill.copy()
|
|
195
325
|
skill_name = parameters.pop('name')
|
|
326
|
+
|
|
196
327
|
existing_skill = self.skills_controller.get_skill(skill_name, project_name)
|
|
197
328
|
if existing_skill is None:
|
|
198
329
|
db.session.rollback()
|
|
199
330
|
raise ValueError(f'Skill with name does not exist: {skill_name}')
|
|
331
|
+
|
|
332
|
+
# Add table restrictions if this is a text2sql skill
|
|
333
|
+
if existing_skill.type == 'sql' and (include_tables or ignore_tables):
|
|
334
|
+
parameters['tables'] = include_tables or ignore_tables
|
|
335
|
+
|
|
336
|
+
# Add knowledge base restrictions if this is a text2sql skill
|
|
337
|
+
if existing_skill.type == 'sql':
|
|
338
|
+
# Pass database parameter if provided
|
|
339
|
+
if database and 'database' not in parameters:
|
|
340
|
+
parameters['database'] = database
|
|
341
|
+
|
|
342
|
+
# Pass knowledge base database parameter if provided
|
|
343
|
+
if knowledge_base_database and 'knowledge_base_database' not in parameters:
|
|
344
|
+
parameters['knowledge_base_database'] = knowledge_base_database
|
|
345
|
+
|
|
346
|
+
# Add knowledge base parameters to both the skill and the association parameters
|
|
347
|
+
if include_knowledge_bases:
|
|
348
|
+
parameters['include_knowledge_bases'] = include_knowledge_bases
|
|
349
|
+
if 'include_knowledge_bases' not in existing_skill.params:
|
|
350
|
+
existing_skill.params['include_knowledge_bases'] = include_knowledge_bases
|
|
351
|
+
flag_modified(existing_skill, 'params')
|
|
352
|
+
elif ignore_knowledge_bases:
|
|
353
|
+
parameters['ignore_knowledge_bases'] = ignore_knowledge_bases
|
|
354
|
+
if 'ignore_knowledge_bases' not in existing_skill.params:
|
|
355
|
+
existing_skill.params['ignore_knowledge_bases'] = ignore_knowledge_bases
|
|
356
|
+
flag_modified(existing_skill, 'params')
|
|
357
|
+
|
|
358
|
+
# Ensure knowledge_base_database is set in the skill's params
|
|
359
|
+
if knowledge_base_database and 'knowledge_base_database' not in existing_skill.params:
|
|
360
|
+
existing_skill.params['knowledge_base_database'] = knowledge_base_database
|
|
361
|
+
flag_modified(existing_skill, 'params')
|
|
362
|
+
|
|
200
363
|
association = db.AgentSkillsAssociation(
|
|
201
364
|
parameters=parameters,
|
|
202
365
|
agent=agent,
|
|
@@ -202,3 +202,18 @@ DEFAULT_EMBEDDINGS_MODEL_PROVIDER = "openai"
|
|
|
202
202
|
DEFAULT_EMBEDDINGS_MODEL_CLASS = OpenAIEmbeddings
|
|
203
203
|
DEFAULT_TIKTOKEN_MODEL_NAME = os.getenv('DEFAULT_TIKTOKEN_MODEL_NAME', 'gpt-4')
|
|
204
204
|
AGENT_CHUNK_POLLING_INTERVAL_SECONDS = os.getenv('AGENT_CHUNK_POLLING_INTERVAL_SECONDS', 1.0)
|
|
205
|
+
DEFAULT_TEXT2SQL_DATABASE = "mindsdb"
|
|
206
|
+
DEFAULT_AGENT_SYSTEM_PROMPT = """
|
|
207
|
+
You are an AI assistant powered by MindsDB. When answering questions, follow these guidelines:
|
|
208
|
+
|
|
209
|
+
1. For factual questions about specific topics, use the knowledge base tools in this sequence:
|
|
210
|
+
- First use kb_list_tool to see available knowledge bases
|
|
211
|
+
- Then use kb_info_tool to understand the structure of relevant knowledge bases
|
|
212
|
+
- Finally use kb_query_tool to query the knowledge base for specific information
|
|
213
|
+
|
|
214
|
+
2. For questions about database tables and their contents:
|
|
215
|
+
- Use the sql_tool to query the tables directly
|
|
216
|
+
- You can join tables if needed to get comprehensive information
|
|
217
|
+
|
|
218
|
+
For factual questions, ALWAYS use the available tools to look up information rather than relying on your internal knowledge.
|
|
219
|
+
"""
|
|
@@ -54,7 +54,8 @@ from mindsdb.interfaces.agents.constants import (
|
|
|
54
54
|
NVIDIA_NIM_CHAT_MODELS,
|
|
55
55
|
USER_COLUMN,
|
|
56
56
|
ASSISTANT_COLUMN,
|
|
57
|
-
CONTEXT_COLUMN, TRACE_ID_COLUMN
|
|
57
|
+
CONTEXT_COLUMN, TRACE_ID_COLUMN,
|
|
58
|
+
DEFAULT_AGENT_SYSTEM_PROMPT
|
|
58
59
|
)
|
|
59
60
|
from mindsdb.interfaces.skills.skill_tool import skill_tool, SkillData
|
|
60
61
|
from langchain_anthropic import ChatAnthropic
|
|
@@ -173,6 +174,10 @@ def create_chat_model(args: Dict):
|
|
|
173
174
|
|
|
174
175
|
def prepare_prompts(df, base_template, input_variables, user_column=USER_COLUMN):
|
|
175
176
|
empty_prompt_ids = np.where(df[input_variables].isna().all(axis=1).values)[0]
|
|
177
|
+
|
|
178
|
+
# Combine system prompt with user-provided template
|
|
179
|
+
base_template = f"{DEFAULT_AGENT_SYSTEM_PROMPT}\n\n{base_template}"
|
|
180
|
+
|
|
176
181
|
base_template = base_template.replace('{{', '{').replace('}}', '}')
|
|
177
182
|
prompts = []
|
|
178
183
|
|
|
@@ -194,8 +199,9 @@ def prepare_callbacks(self, args):
|
|
|
194
199
|
return callbacks, context_callback
|
|
195
200
|
|
|
196
201
|
|
|
197
|
-
def handle_agent_error(e):
|
|
198
|
-
error_message
|
|
202
|
+
def handle_agent_error(e, error_message=None):
|
|
203
|
+
if error_message is None:
|
|
204
|
+
error_message = f"An error occurred during agent execution: {str(e)}"
|
|
199
205
|
logger.error(error_message, exc_info=True)
|
|
200
206
|
return error_message
|
|
201
207
|
|
|
@@ -524,7 +530,13 @@ AI: {response}"""
|
|
|
524
530
|
output = result['output'] if isinstance(result, dict) and 'output' in result else str(result)
|
|
525
531
|
return {CONTEXT_COLUMN: captured_context, ASSISTANT_COLUMN: output}
|
|
526
532
|
except Exception as e:
|
|
527
|
-
|
|
533
|
+
error_message = str(e)
|
|
534
|
+
# Special handling for API key errors
|
|
535
|
+
if "API key" in error_message and ("not found" in error_message or "missing" in error_message):
|
|
536
|
+
# Format API key error more clearly
|
|
537
|
+
logger.error(f"API Key Error: {error_message}")
|
|
538
|
+
error_message = f"API Key Error: {error_message}"
|
|
539
|
+
return {CONTEXT_COLUMN: [], ASSISTANT_COLUMN: handle_agent_error(e, error_message)}
|
|
528
540
|
|
|
529
541
|
completions = []
|
|
530
542
|
contexts = []
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Wrapper around MindsDB's executor and integration controller following the implementation of the original
|
|
3
3
|
langchain.sql_database.SQLDatabase class to partly replicate its behavior.
|
|
4
4
|
"""
|
|
5
|
+
import traceback
|
|
5
6
|
from typing import Any, Iterable, List, Optional
|
|
6
7
|
|
|
7
8
|
from mindsdb.utilities import log
|
|
@@ -57,8 +58,20 @@ class MindsDBSQL(SQLDatabase):
|
|
|
57
58
|
"""Information about all tables in the database."""
|
|
58
59
|
return self._sql_agent.get_table_info()
|
|
59
60
|
|
|
61
|
+
@property
|
|
62
|
+
def kb_info(self) -> str:
|
|
63
|
+
"""Information about all knowledge bases in the database."""
|
|
64
|
+
return self._sql_agent.get_knowledge_base_info()
|
|
65
|
+
|
|
60
66
|
def get_usable_table_names(self) -> Iterable[str]:
|
|
61
|
-
|
|
67
|
+
"""Information about all tables in the database."""
|
|
68
|
+
try:
|
|
69
|
+
return self._sql_agent.get_usable_table_names()
|
|
70
|
+
except Exception as e:
|
|
71
|
+
# If there's an error accessing tables through the integration, handle it gracefully
|
|
72
|
+
logger.warning(f"Error getting usable table names: {str(e)}")
|
|
73
|
+
# Return an empty list instead of raising an exception
|
|
74
|
+
return []
|
|
62
75
|
|
|
63
76
|
def get_table_info_no_throw(self, table_names: Optional[List[str]] = None) -> str:
|
|
64
77
|
for i in range(len(table_names)):
|
|
@@ -66,5 +79,91 @@ class MindsDBSQL(SQLDatabase):
|
|
|
66
79
|
return self._sql_agent.get_table_info_safe(table_names)
|
|
67
80
|
|
|
68
81
|
def run_no_throw(self, command: str, fetch: str = "all") -> str:
|
|
82
|
+
"""Execute a SQL command and return the result as a string.
|
|
83
|
+
|
|
84
|
+
This method catches any exceptions and returns an error message instead of raising an exception.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
command: The SQL command to execute
|
|
88
|
+
fetch: Whether to fetch 'all' results or just 'one'
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
A string representation of the result or an error message
|
|
92
|
+
"""
|
|
69
93
|
command = extract_essential(command)
|
|
70
|
-
|
|
94
|
+
|
|
95
|
+
try:
|
|
96
|
+
|
|
97
|
+
# Log the query for debugging
|
|
98
|
+
logger.info(f"Executing SQL query: {command}")
|
|
99
|
+
|
|
100
|
+
# remove backticks
|
|
101
|
+
command = command.replace('`', '')
|
|
102
|
+
|
|
103
|
+
# Parse the SQL string to an AST object first
|
|
104
|
+
from mindsdb_sql_parser import parse_sql
|
|
105
|
+
ast_query = parse_sql(command)
|
|
106
|
+
|
|
107
|
+
# Now execute the parsed query
|
|
108
|
+
result = self._sql_agent.skill_tool.get_command_executor().execute_command(ast_query, database_name="mindsdb")
|
|
109
|
+
|
|
110
|
+
# Convert ExecuteAnswer to a DataFrame for easier manipulation
|
|
111
|
+
df = None
|
|
112
|
+
if hasattr(result, 'data') and hasattr(result.data, 'data_frame'):
|
|
113
|
+
df = result.data.data_frame
|
|
114
|
+
else:
|
|
115
|
+
# Fallback to to_df when data_frame attr not available
|
|
116
|
+
try:
|
|
117
|
+
df = result.data.to_df()
|
|
118
|
+
except Exception:
|
|
119
|
+
df = None
|
|
120
|
+
|
|
121
|
+
# Default behaviour (string)
|
|
122
|
+
if df is not None:
|
|
123
|
+
if not df.empty:
|
|
124
|
+
return df.to_string(index=False)
|
|
125
|
+
else:
|
|
126
|
+
return "Query executed successfully, but returned no data."
|
|
127
|
+
|
|
128
|
+
return str(result)
|
|
129
|
+
|
|
130
|
+
except Exception as e:
|
|
131
|
+
logger.error(f"Error executing SQL command: {str(e)}\n{traceback.format_exc()}")
|
|
132
|
+
# If this is a knowledge base query, provide a more helpful error message
|
|
133
|
+
if "knowledge_base" in command.lower() or any(kb in command for kb in self._sql_agent.get_usable_knowledge_base_names()):
|
|
134
|
+
return f"Error executing knowledge base query: {str(e)}. Please check that the knowledge base exists and your query syntax is correct."
|
|
135
|
+
return f"Error: {str(e)}"
|
|
136
|
+
|
|
137
|
+
# def run_no_throw(self, command: str, fetch: str = "all") -> str:
|
|
138
|
+
# """Execute a SQL command and return the result as a string.
|
|
139
|
+
#
|
|
140
|
+
# This method catches any exceptions and returns an error message instead of raising an exception.
|
|
141
|
+
#
|
|
142
|
+
# Args:
|
|
143
|
+
# command: The SQL command to execute
|
|
144
|
+
# fetch: Whether to fetch 'all' results or just 'one'
|
|
145
|
+
#
|
|
146
|
+
# Returns:
|
|
147
|
+
# A string representation of the result or an error message
|
|
148
|
+
# """
|
|
149
|
+
# command = extract_essential(command)
|
|
150
|
+
# try:
|
|
151
|
+
# return self._sql_agent.query_safe(command)
|
|
152
|
+
# except Exception as e:
|
|
153
|
+
# logger.error(f"Error executing SQL command: {str(e)}")
|
|
154
|
+
# # If this is a knowledge base query, provide a more helpful error message
|
|
155
|
+
# if "knowledge_base" in command.lower() or any(kb in command for kb in self._sql_agent.get_usable_knowledge_base_names()):
|
|
156
|
+
# return f"Error executing knowledge base query: {str(e)}. Please check that the knowledge base exists and your query syntax is correct."
|
|
157
|
+
# return f"Error: {str(e)}"
|
|
158
|
+
|
|
159
|
+
def get_usable_knowledge_base_names(self) -> List[str]:
|
|
160
|
+
"""Get a list of usable knowledge base names.
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
A list of knowledge base names that can be used in queries
|
|
164
|
+
"""
|
|
165
|
+
try:
|
|
166
|
+
return self._sql_agent.get_usable_knowledge_base_names()
|
|
167
|
+
except Exception as e:
|
|
168
|
+
logger.error(f"Error getting usable knowledge base names: {str(e)}")
|
|
169
|
+
return []
|
|
@@ -32,6 +32,7 @@ from mindsdb.integrations.handlers.langchain_embedding_handler.langchain_embeddi
|
|
|
32
32
|
from mindsdb.interfaces.agents.constants import DEFAULT_EMBEDDINGS_MODEL_CLASS
|
|
33
33
|
from mindsdb.interfaces.agents.langchain_agent import create_chat_model, get_llm_provider
|
|
34
34
|
from mindsdb.interfaces.database.projects import ProjectController
|
|
35
|
+
from mindsdb.interfaces.variables.variables_controller import variables_controller
|
|
35
36
|
from mindsdb.interfaces.knowledge_base.preprocessing.models import PreprocessingConfig, Document
|
|
36
37
|
from mindsdb.interfaces.knowledge_base.preprocessing.document_preprocessor import PreprocessorFactory
|
|
37
38
|
from mindsdb.interfaces.model.functions import PredictorRecordNotFound
|
|
@@ -125,6 +126,11 @@ class KnowledgeBaseTable:
|
|
|
125
126
|
logger.debug(f"Configuring preprocessing with config: {config}")
|
|
126
127
|
self.document_preprocessor = None # Reset existing preprocessor
|
|
127
128
|
if config is not None:
|
|
129
|
+
# Ensure content_column is set for JSON chunking if not already specified
|
|
130
|
+
if config.get('type') == 'json_chunking' and config.get('json_chunking_config'):
|
|
131
|
+
if 'content_column' not in config['json_chunking_config']:
|
|
132
|
+
config['json_chunking_config']['content_column'] = 'content'
|
|
133
|
+
|
|
128
134
|
preprocessing_config = PreprocessingConfig(**config)
|
|
129
135
|
self.document_preprocessor = PreprocessorFactory.create_preprocessor(preprocessing_config)
|
|
130
136
|
logger.debug(f"Created preprocessor of type: {type(self.document_preprocessor)}")
|
|
@@ -820,6 +826,15 @@ class KnowledgeBaseTable:
|
|
|
820
826
|
# Convert everything else to string
|
|
821
827
|
return str(value)
|
|
822
828
|
|
|
829
|
+
def create_index(self):
|
|
830
|
+
"""
|
|
831
|
+
Create an index on the knowledge base table
|
|
832
|
+
:param index_name: name of the index
|
|
833
|
+
:param params: parameters for the index
|
|
834
|
+
"""
|
|
835
|
+
db_handler = self.get_vector_db()
|
|
836
|
+
db_handler.create_index(self._kb.vector_database_table)
|
|
837
|
+
|
|
823
838
|
|
|
824
839
|
class KnowledgeBaseController:
|
|
825
840
|
"""
|
|
@@ -846,6 +861,9 @@ class KnowledgeBaseController:
|
|
|
846
861
|
:param is_sparse: Whether to use sparse vectors for embeddings
|
|
847
862
|
:param vector_size: Optional size specification for vectors, required when is_sparse=True
|
|
848
863
|
"""
|
|
864
|
+
# fill variables
|
|
865
|
+
params = variables_controller.fill_parameters(params)
|
|
866
|
+
|
|
849
867
|
# Validate preprocessing config first if provided
|
|
850
868
|
if preprocessing_config is not None:
|
|
851
869
|
PreprocessingConfig(**preprocessing_config) # Validate before storing
|
|
@@ -1016,6 +1034,8 @@ class KnowledgeBaseController:
|
|
|
1016
1034
|
params['question_column'] = 'content'
|
|
1017
1035
|
if api_key:
|
|
1018
1036
|
params[f"{engine}_api_key"] = api_key
|
|
1037
|
+
if 'api_key' in params:
|
|
1038
|
+
params.pop('api_key')
|
|
1019
1039
|
if 'base_url' in params:
|
|
1020
1040
|
params['api_base'] = params.pop('base_url')
|
|
1021
1041
|
|
|
@@ -1153,6 +1173,11 @@ class KnowledgeBaseController:
|
|
|
1153
1173
|
|
|
1154
1174
|
return data
|
|
1155
1175
|
|
|
1176
|
+
def create_index(self, table_name, project_name):
|
|
1177
|
+
project_id = self.session.database_controller.get_project(project_name).id
|
|
1178
|
+
kb_table = self.get_table(table_name, project_id)
|
|
1179
|
+
kb_table.create_index()
|
|
1180
|
+
|
|
1156
1181
|
def update(self, name: str, project_id: int, **kwargs) -> db.KnowledgeBase:
|
|
1157
1182
|
"""
|
|
1158
1183
|
Update a knowledge base record
|
|
@@ -377,18 +377,21 @@ class PreprocessorFactory:
|
|
|
377
377
|
) -> DocumentPreprocessor:
|
|
378
378
|
"""
|
|
379
379
|
Create appropriate preprocessor based on configuration
|
|
380
|
-
:
|
|
381
|
-
:
|
|
382
|
-
:
|
|
380
|
+
:param config: Preprocessing configuration
|
|
381
|
+
:return: Configured preprocessor instance
|
|
382
|
+
:raises ValueError: If unknown preprocessor type specified
|
|
383
383
|
"""
|
|
384
384
|
if config is None:
|
|
385
|
+
# Default to text chunking if no config provided
|
|
385
386
|
return TextChunkingPreprocessor()
|
|
386
387
|
|
|
387
|
-
if config.type == PreprocessorType.
|
|
388
|
-
return ContextualPreprocessor(
|
|
389
|
-
config.contextual_config or ContextualConfig()
|
|
390
|
-
)
|
|
391
|
-
elif config.type == PreprocessorType.TEXT_CHUNKING:
|
|
388
|
+
if config.type == PreprocessorType.TEXT_CHUNKING:
|
|
392
389
|
return TextChunkingPreprocessor(config.text_chunking_config)
|
|
393
|
-
|
|
394
|
-
|
|
390
|
+
elif config.type == PreprocessorType.CONTEXTUAL:
|
|
391
|
+
return ContextualPreprocessor(config.contextual_config)
|
|
392
|
+
elif config.type == PreprocessorType.JSON_CHUNKING:
|
|
393
|
+
# Import here to avoid circular imports
|
|
394
|
+
from mindsdb.interfaces.knowledge_base.preprocessing.json_chunker import JSONChunkingPreprocessor
|
|
395
|
+
return JSONChunkingPreprocessor(config.json_chunking_config)
|
|
396
|
+
else:
|
|
397
|
+
raise ValueError(f"Unknown preprocessor type: {config.type}")
|