MindsDB 25.5.3.0__py3-none-any.whl → 25.5.4.1__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 +8 -8
- mindsdb/__main__.py +127 -79
- mindsdb/api/a2a/__init__.py +0 -0
- mindsdb/api/a2a/__main__.py +144 -0
- mindsdb/api/a2a/agent.py +308 -0
- mindsdb/api/a2a/common/__init__.py +0 -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 +86 -0
- mindsdb/api/a2a/task_manager.py +560 -0
- mindsdb/api/executor/command_executor.py +185 -309
- 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/config.py +61 -86
- 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/byom_handler/requirements.txt +1 -2
- 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/lancedb_handler/requirements.txt +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/litellm_handler/litellm_handler.py +37 -20
- 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/llm/config.py +13 -0
- mindsdb/integrations/libs/llm/utils.py +37 -65
- 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/rag/rerankers/base_reranker.py +230 -227
- mindsdb/integrations/utilities/utils.py +3 -3
- mindsdb/interfaces/agents/agents_controller.py +164 -1
- mindsdb/interfaces/agents/constants.py +32 -13
- mindsdb/interfaces/agents/langchain_agent.py +106 -95
- mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
- mindsdb/interfaces/knowledge_base/controller.py +250 -216
- 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 +287 -216
- mindsdb/utilities/starters.py +13 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/METADATA +646 -698
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/RECORD +312 -295
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.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.1.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.1.dist-info}/top_level.txt +0 -0
|
@@ -11,10 +11,8 @@ import pandas as pd
|
|
|
11
11
|
from langchain.agents import AgentExecutor
|
|
12
12
|
from langchain.agents.initialize import initialize_agent
|
|
13
13
|
from langchain.chains.conversation.memory import ConversationSummaryBufferMemory
|
|
14
|
-
from langchain_community.chat_models import
|
|
15
|
-
|
|
16
|
-
ChatLiteLLM,
|
|
17
|
-
ChatOllama)
|
|
14
|
+
from langchain_community.chat_models import ChatAnyscale, ChatLiteLLM, ChatOllama
|
|
15
|
+
from langchain_writer import ChatWriter
|
|
18
16
|
from langchain_google_genai import ChatGoogleGenerativeAI
|
|
19
17
|
from langchain_core.agents import AgentAction, AgentStep
|
|
20
18
|
from langchain_core.callbacks.base import BaseCallbackHandler
|
|
@@ -27,7 +25,9 @@ from langchain_core.tools import Tool
|
|
|
27
25
|
from mindsdb.integrations.libs.llm.utils import get_llm_config
|
|
28
26
|
from mindsdb.integrations.utilities.handler_utils import get_api_key
|
|
29
27
|
from mindsdb.integrations.utilities.rag.settings import DEFAULT_RAG_PROMPT_TEMPLATE
|
|
30
|
-
from mindsdb.interfaces.agents.event_dispatch_callback_handler import
|
|
28
|
+
from mindsdb.interfaces.agents.event_dispatch_callback_handler import (
|
|
29
|
+
EventDispatchCallbackHandler,
|
|
30
|
+
)
|
|
31
31
|
from mindsdb.interfaces.agents.constants import AGENT_CHUNK_POLLING_INTERVAL_SECONDS
|
|
32
32
|
from mindsdb.utilities import log
|
|
33
33
|
from mindsdb.utilities.context_executor import ContextThreadPoolExecutor
|
|
@@ -54,7 +54,10 @@ from mindsdb.interfaces.agents.constants import (
|
|
|
54
54
|
NVIDIA_NIM_CHAT_MODELS,
|
|
55
55
|
USER_COLUMN,
|
|
56
56
|
ASSISTANT_COLUMN,
|
|
57
|
-
CONTEXT_COLUMN,
|
|
57
|
+
CONTEXT_COLUMN,
|
|
58
|
+
TRACE_ID_COLUMN,
|
|
59
|
+
DEFAULT_AGENT_SYSTEM_PROMPT,
|
|
60
|
+
WRITER_CHAT_MODELS,
|
|
58
61
|
)
|
|
59
62
|
from mindsdb.interfaces.skills.skill_tool import skill_tool, SkillData
|
|
60
63
|
from langchain_anthropic import ChatAnthropic
|
|
@@ -87,6 +90,9 @@ def get_llm_provider(args: Dict) -> str:
|
|
|
87
90
|
return "nvidia_nim"
|
|
88
91
|
if args["model_name"] in GOOGLE_GEMINI_CHAT_MODELS:
|
|
89
92
|
return "google"
|
|
93
|
+
# Check for writer models
|
|
94
|
+
if args["model_name"] in WRITER_CHAT_MODELS:
|
|
95
|
+
return "writer"
|
|
90
96
|
|
|
91
97
|
# For vLLM, require explicit provider specification
|
|
92
98
|
raise ValueError("Invalid model name. Please define a supported llm provider")
|
|
@@ -100,21 +106,21 @@ def get_embedding_model_provider(args: Dict) -> str:
|
|
|
100
106
|
# Check for explicit embedding model provider
|
|
101
107
|
if "embedding_model_provider" in args:
|
|
102
108
|
provider = args["embedding_model_provider"]
|
|
103
|
-
if provider ==
|
|
104
|
-
if not (args.get(
|
|
109
|
+
if provider == "vllm":
|
|
110
|
+
if not (args.get("openai_api_base") and args.get("model")):
|
|
105
111
|
raise ValueError(
|
|
106
112
|
"VLLM embeddings configuration error:\n"
|
|
107
113
|
"- Missing required parameters: 'openai_api_base' and/or 'model'\n"
|
|
108
114
|
"- Example: openai_api_base='http://localhost:8003/v1', model='your-model-name'"
|
|
109
115
|
)
|
|
110
116
|
logger.info("Using custom VLLMEmbeddings class")
|
|
111
|
-
return
|
|
117
|
+
return "vllm"
|
|
112
118
|
return provider
|
|
113
119
|
|
|
114
120
|
# Check if LLM provider is vLLM
|
|
115
|
-
llm_provider = args.get(
|
|
116
|
-
if llm_provider ==
|
|
117
|
-
if not (args.get(
|
|
121
|
+
llm_provider = args.get("provider", DEFAULT_EMBEDDINGS_MODEL_PROVIDER)
|
|
122
|
+
if llm_provider == "vllm":
|
|
123
|
+
if not (args.get("openai_api_base") and args.get("model")):
|
|
118
124
|
raise ValueError(
|
|
119
125
|
"VLLM embeddings configuration error:\n"
|
|
120
126
|
"- Missing required parameters: 'openai_api_base' and/or 'model'\n"
|
|
@@ -122,7 +128,7 @@ def get_embedding_model_provider(args: Dict) -> str:
|
|
|
122
128
|
"- Example: openai_api_base='http://localhost:8003/v1', model='your-model-name'"
|
|
123
129
|
)
|
|
124
130
|
logger.info("Using custom VLLMEmbeddings class")
|
|
125
|
-
return
|
|
131
|
+
return "vllm"
|
|
126
132
|
|
|
127
133
|
# Default to LLM provider
|
|
128
134
|
return llm_provider
|
|
@@ -131,14 +137,15 @@ def get_embedding_model_provider(args: Dict) -> str:
|
|
|
131
137
|
def get_chat_model_params(args: Dict) -> Dict:
|
|
132
138
|
model_config = args.copy()
|
|
133
139
|
# Include API keys.
|
|
134
|
-
model_config["api_keys"] = {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
llm_config = get_llm_config(
|
|
138
|
-
args.get("provider", get_llm_provider(args)), model_config
|
|
139
|
-
)
|
|
140
|
-
config_dict = llm_config.model_dump()
|
|
140
|
+
model_config["api_keys"] = {p: get_api_key(p, model_config, None, strict=False) for p in SUPPORTED_PROVIDERS}
|
|
141
|
+
llm_config = get_llm_config(args.get("provider", get_llm_provider(args)), model_config)
|
|
142
|
+
config_dict = llm_config.model_dump(by_alias=True)
|
|
141
143
|
config_dict = {k: v for k, v in config_dict.items() if v is not None}
|
|
144
|
+
|
|
145
|
+
# If provider is writer, ensure the API key is passed as 'api_key'
|
|
146
|
+
if args.get("provider") == "writer" and "writer_api_key" in config_dict:
|
|
147
|
+
config_dict["api_key"] = config_dict.pop("writer_api_key")
|
|
148
|
+
|
|
142
149
|
return config_dict
|
|
143
150
|
|
|
144
151
|
|
|
@@ -166,20 +173,26 @@ def create_chat_model(args: Dict):
|
|
|
166
173
|
return ChatNVIDIA(**model_kwargs)
|
|
167
174
|
if args["provider"] == "google":
|
|
168
175
|
return ChatGoogleGenerativeAI(**model_kwargs)
|
|
176
|
+
if args["provider"] == "writer":
|
|
177
|
+
return ChatWriter(**model_kwargs)
|
|
169
178
|
if args["provider"] == "mindsdb":
|
|
170
179
|
return ChatMindsdb(**model_kwargs)
|
|
171
|
-
raise ValueError(f
|
|
180
|
+
raise ValueError(f"Unknown provider: {args['provider']}")
|
|
172
181
|
|
|
173
182
|
|
|
174
183
|
def prepare_prompts(df, base_template, input_variables, user_column=USER_COLUMN):
|
|
175
184
|
empty_prompt_ids = np.where(df[input_variables].isna().all(axis=1).values)[0]
|
|
176
|
-
|
|
185
|
+
|
|
186
|
+
# Combine system prompt with user-provided template
|
|
187
|
+
base_template = f"{DEFAULT_AGENT_SYSTEM_PROMPT}\n\n{base_template}"
|
|
188
|
+
|
|
189
|
+
base_template = base_template.replace("{{", "{").replace("}}", "}")
|
|
177
190
|
prompts = []
|
|
178
191
|
|
|
179
192
|
for i, row in df.iterrows():
|
|
180
193
|
if i not in empty_prompt_ids:
|
|
181
194
|
prompt = PromptTemplate(input_variables=input_variables, template=base_template)
|
|
182
|
-
kwargs = {col: row[col] if row[col] is not None else
|
|
195
|
+
kwargs = {col: row[col] if row[col] is not None else "" for col in input_variables}
|
|
183
196
|
prompts.append(prompt.format(**kwargs))
|
|
184
197
|
elif row.get(user_column):
|
|
185
198
|
prompts.append(row[user_column])
|
|
@@ -194,8 +207,9 @@ def prepare_callbacks(self, args):
|
|
|
194
207
|
return callbacks, context_callback
|
|
195
208
|
|
|
196
209
|
|
|
197
|
-
def handle_agent_error(e):
|
|
198
|
-
error_message
|
|
210
|
+
def handle_agent_error(e, error_message=None):
|
|
211
|
+
if error_message is None:
|
|
212
|
+
error_message = f"An error occurred during agent execution: {str(e)}"
|
|
199
213
|
logger.error(error_message, exc_info=True)
|
|
200
214
|
return error_message
|
|
201
215
|
|
|
@@ -212,9 +226,7 @@ def process_chunk(chunk):
|
|
|
212
226
|
|
|
213
227
|
|
|
214
228
|
class LangchainAgent:
|
|
215
|
-
|
|
216
229
|
def __init__(self, agent: db.Agents, model: dict = None):
|
|
217
|
-
|
|
218
230
|
self.agent = agent
|
|
219
231
|
self.model = model
|
|
220
232
|
|
|
@@ -237,18 +249,14 @@ class LangchainAgent:
|
|
|
237
249
|
args = self.agent.params.copy()
|
|
238
250
|
args["model_name"] = self.agent.model_name
|
|
239
251
|
args["provider"] = self.agent.provider
|
|
240
|
-
args["embedding_model_provider"] = args.get(
|
|
241
|
-
"embedding_model", get_embedding_model_provider(args)
|
|
242
|
-
)
|
|
252
|
+
args["embedding_model_provider"] = args.get("embedding_model", get_embedding_model_provider(args))
|
|
243
253
|
|
|
244
254
|
# agent is using current langchain model
|
|
245
255
|
if self.agent.provider == "mindsdb":
|
|
246
256
|
args["model_name"] = self.agent.model_name
|
|
247
257
|
|
|
248
258
|
# get prompt
|
|
249
|
-
prompt_template = (
|
|
250
|
-
self.model["problem_definition"].get("using", {}).get("prompt_template")
|
|
251
|
-
)
|
|
259
|
+
prompt_template = self.model["problem_definition"].get("using", {}).get("prompt_template")
|
|
252
260
|
if prompt_template is not None:
|
|
253
261
|
# only update prompt_template if it is set on the model
|
|
254
262
|
args["prompt_template"] = prompt_template
|
|
@@ -257,24 +265,23 @@ class LangchainAgent:
|
|
|
257
265
|
if args.get("mode") == "retrieval":
|
|
258
266
|
args["prompt_template"] = DEFAULT_RAG_PROMPT_TEMPLATE
|
|
259
267
|
else:
|
|
260
|
-
raise ValueError(
|
|
261
|
-
"Please provide a `prompt_template` or set `mode=retrieval`"
|
|
262
|
-
)
|
|
268
|
+
raise ValueError("Please provide a `prompt_template` or set `mode=retrieval`")
|
|
263
269
|
|
|
264
270
|
return args
|
|
265
271
|
|
|
266
272
|
def get_metadata(self) -> Dict:
|
|
267
273
|
return {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
274
|
+
"provider": self.provider,
|
|
275
|
+
"model_name": self.args["model_name"],
|
|
276
|
+
"embedding_model_provider": self.args.get(
|
|
277
|
+
"embedding_model_provider", get_embedding_model_provider(self.args)
|
|
278
|
+
),
|
|
279
|
+
"skills": get_skills(self.agent),
|
|
280
|
+
"user_id": ctx.user_id,
|
|
281
|
+
"session_id": ctx.session_id,
|
|
282
|
+
"company_id": ctx.company_id,
|
|
283
|
+
"user_class": ctx.user_class,
|
|
284
|
+
"email_confirmed": ctx.email_confirmed,
|
|
278
285
|
}
|
|
279
286
|
|
|
280
287
|
def get_tags(self) -> List:
|
|
@@ -283,14 +290,13 @@ class LangchainAgent:
|
|
|
283
290
|
]
|
|
284
291
|
|
|
285
292
|
def get_completion(self, messages, stream: bool = False):
|
|
286
|
-
|
|
287
293
|
# Get metadata and tags to be used in the trace
|
|
288
294
|
metadata = self.get_metadata()
|
|
289
295
|
tags = self.get_tags()
|
|
290
296
|
|
|
291
297
|
# Set up trace for the API completion in Langfuse
|
|
292
298
|
self.langfuse_client_wrapper.setup_trace(
|
|
293
|
-
name=
|
|
299
|
+
name="api-completion",
|
|
294
300
|
input=messages,
|
|
295
301
|
tags=tags,
|
|
296
302
|
metadata=metadata,
|
|
@@ -299,9 +305,7 @@ class LangchainAgent:
|
|
|
299
305
|
)
|
|
300
306
|
|
|
301
307
|
# Set up trace for the run completion in Langfuse
|
|
302
|
-
self.run_completion_span = self.langfuse_client_wrapper.start_span(
|
|
303
|
-
name='run-completion',
|
|
304
|
-
input=messages)
|
|
308
|
+
self.run_completion_span = self.langfuse_client_wrapper.start_span(name="run-completion", input=messages)
|
|
305
309
|
|
|
306
310
|
if stream:
|
|
307
311
|
return self._get_completion_stream(messages)
|
|
@@ -339,7 +343,7 @@ class LangchainAgent:
|
|
|
339
343
|
|
|
340
344
|
df = pd.DataFrame(messages)
|
|
341
345
|
|
|
342
|
-
self.embedding_model_provider = args.get(
|
|
346
|
+
self.embedding_model_provider = args.get("embedding_model_provider", get_embedding_model_provider(args))
|
|
343
347
|
# Back compatibility for old models
|
|
344
348
|
self.provider = args.get("provider", get_llm_provider(args))
|
|
345
349
|
|
|
@@ -392,7 +396,7 @@ class LangchainAgent:
|
|
|
392
396
|
agent=agent_type,
|
|
393
397
|
# Use custom output parser to handle flaky LLMs that don't ALWAYS conform to output format.
|
|
394
398
|
agent_kwargs={"output_parser": SafeOutputParser()},
|
|
395
|
-
# Calls the agent
|
|
399
|
+
# Calls the agent's LLM Chain one final time to generate a final answer based on the previous steps
|
|
396
400
|
early_stopping_method="generate",
|
|
397
401
|
handle_parsing_errors=self._handle_parsing_errors,
|
|
398
402
|
# Timeout per agent invocation.
|
|
@@ -400,11 +404,9 @@ class LangchainAgent:
|
|
|
400
404
|
"timeout_seconds",
|
|
401
405
|
args.get("timeout_seconds", DEFAULT_AGENT_TIMEOUT_SECONDS),
|
|
402
406
|
),
|
|
403
|
-
max_iterations=args.get(
|
|
404
|
-
"max_iterations", args.get("max_iterations", DEFAULT_MAX_ITERATIONS)
|
|
405
|
-
),
|
|
407
|
+
max_iterations=args.get("max_iterations", args.get("max_iterations", DEFAULT_MAX_ITERATIONS)),
|
|
406
408
|
memory=memory,
|
|
407
|
-
verbose=args.get("verbose", args.get("verbose", False))
|
|
409
|
+
verbose=args.get("verbose", args.get("verbose", False)),
|
|
408
410
|
)
|
|
409
411
|
return agent_executor
|
|
410
412
|
|
|
@@ -416,7 +418,7 @@ class LangchainAgent:
|
|
|
416
418
|
type=rel.skill.type,
|
|
417
419
|
params=rel.skill.params,
|
|
418
420
|
project_id=rel.skill.project_id,
|
|
419
|
-
agent_tables_list=(rel.parameters or {}).get(
|
|
421
|
+
agent_tables_list=(rel.parameters or {}).get("tables"),
|
|
420
422
|
)
|
|
421
423
|
for rel in self.agent.skills_relationships
|
|
422
424
|
]
|
|
@@ -507,24 +509,34 @@ AI: {response}"""
|
|
|
507
509
|
return f"Agent failed with error:\n{str(error)}..."
|
|
508
510
|
|
|
509
511
|
def run_agent(self, df: pd.DataFrame, agent: AgentExecutor, args: Dict) -> pd.DataFrame:
|
|
510
|
-
base_template = args.get(
|
|
511
|
-
return_context = args.get(
|
|
512
|
+
base_template = args.get("prompt_template", args["prompt_template"])
|
|
513
|
+
return_context = args.get("return_context", True)
|
|
512
514
|
input_variables = re.findall(r"{{(.*?)}}", base_template)
|
|
513
515
|
|
|
514
|
-
prompts, empty_prompt_ids = prepare_prompts(
|
|
515
|
-
|
|
516
|
+
prompts, empty_prompt_ids = prepare_prompts(
|
|
517
|
+
df, base_template, input_variables, args.get("user_column", USER_COLUMN)
|
|
518
|
+
)
|
|
516
519
|
|
|
517
520
|
def _invoke_agent_executor_with_prompt(agent_executor, prompt):
|
|
518
521
|
if not prompt:
|
|
519
522
|
return {CONTEXT_COLUMN: [], ASSISTANT_COLUMN: ""}
|
|
520
523
|
try:
|
|
521
524
|
callbacks, context_callback = prepare_callbacks(self, args)
|
|
522
|
-
result = agent_executor.invoke(prompt, config={
|
|
525
|
+
result = agent_executor.invoke(prompt, config={"callbacks": callbacks})
|
|
523
526
|
captured_context = context_callback.get_contexts()
|
|
524
|
-
output = result[
|
|
527
|
+
output = result["output"] if isinstance(result, dict) and "output" in result else str(result)
|
|
525
528
|
return {CONTEXT_COLUMN: captured_context, ASSISTANT_COLUMN: output}
|
|
526
529
|
except Exception as e:
|
|
527
|
-
|
|
530
|
+
error_message = str(e)
|
|
531
|
+
# Special handling for API key errors
|
|
532
|
+
if "API key" in error_message and ("not found" in error_message or "missing" in error_message):
|
|
533
|
+
# Format API key error more clearly
|
|
534
|
+
logger.error(f"API Key Error: {error_message}")
|
|
535
|
+
error_message = f"API Key Error: {error_message}"
|
|
536
|
+
return {
|
|
537
|
+
CONTEXT_COLUMN: [],
|
|
538
|
+
ASSISTANT_COLUMN: handle_agent_error(e, error_message),
|
|
539
|
+
}
|
|
528
540
|
|
|
529
541
|
completions = []
|
|
530
542
|
contexts = []
|
|
@@ -533,10 +545,7 @@ AI: {response}"""
|
|
|
533
545
|
agent_timeout_seconds = args.get("timeout", DEFAULT_AGENT_TIMEOUT_SECONDS)
|
|
534
546
|
|
|
535
547
|
with ContextThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
536
|
-
futures = [
|
|
537
|
-
executor.submit(_invoke_agent_executor_with_prompt, agent, prompt)
|
|
538
|
-
for prompt in prompts
|
|
539
|
-
]
|
|
548
|
+
futures = [executor.submit(_invoke_agent_executor_with_prompt, agent, prompt) for prompt in prompts]
|
|
540
549
|
try:
|
|
541
550
|
for future in as_completed(futures, timeout=agent_timeout_seconds):
|
|
542
551
|
result = future.result()
|
|
@@ -550,9 +559,7 @@ AI: {response}"""
|
|
|
550
559
|
contexts.append(result[CONTEXT_COLUMN])
|
|
551
560
|
except TimeoutError:
|
|
552
561
|
timeout_message = "I'm sorry! I couldn't come up with a response in time. Please try again."
|
|
553
|
-
logger.warning(
|
|
554
|
-
f"Agent execution timed out after {agent_timeout_seconds} seconds"
|
|
555
|
-
)
|
|
562
|
+
logger.warning(f"Agent execution timed out after {agent_timeout_seconds} seconds")
|
|
556
563
|
for _ in range(len(futures) - len(completions)):
|
|
557
564
|
completions.append(timeout_message)
|
|
558
565
|
contexts.append([])
|
|
@@ -566,10 +573,8 @@ AI: {response}"""
|
|
|
566
573
|
pred_df = pd.DataFrame(
|
|
567
574
|
{
|
|
568
575
|
ASSISTANT_COLUMN: completions,
|
|
569
|
-
CONTEXT_COLUMN: [
|
|
570
|
-
|
|
571
|
-
], # Serialize context to JSON string
|
|
572
|
-
TRACE_ID_COLUMN: self.langfuse_client_wrapper.get_trace_id()
|
|
576
|
+
CONTEXT_COLUMN: [json.dumps(ctx) for ctx in contexts], # Serialize context to JSON string
|
|
577
|
+
TRACE_ID_COLUMN: self.langfuse_client_wrapper.get_trace_id(),
|
|
573
578
|
}
|
|
574
579
|
)
|
|
575
580
|
|
|
@@ -579,17 +584,22 @@ AI: {response}"""
|
|
|
579
584
|
return pred_df
|
|
580
585
|
|
|
581
586
|
def add_chunk_metadata(self, chunk: Dict) -> Dict:
|
|
582
|
-
logger.debug(f
|
|
583
|
-
logger.debug(f
|
|
587
|
+
logger.debug(f"Adding metadata to chunk: {chunk}")
|
|
588
|
+
logger.debug(f"Trace ID: {self.langfuse_client_wrapper.get_trace_id()}")
|
|
584
589
|
chunk["trace_id"] = self.langfuse_client_wrapper.get_trace_id()
|
|
585
590
|
return chunk
|
|
586
591
|
|
|
587
|
-
def _stream_agent_executor(
|
|
592
|
+
def _stream_agent_executor(
|
|
593
|
+
self,
|
|
594
|
+
agent_executor: AgentExecutor,
|
|
595
|
+
prompt: str,
|
|
596
|
+
callbacks: List[BaseCallbackHandler],
|
|
597
|
+
):
|
|
588
598
|
chunk_queue = queue.Queue()
|
|
589
599
|
# Add event dispatch callback handler only to streaming completions.
|
|
590
600
|
event_dispatch_callback_handler = EventDispatchCallbackHandler(chunk_queue)
|
|
591
601
|
callbacks.append(event_dispatch_callback_handler)
|
|
592
|
-
stream_iterator = agent_executor.stream(prompt, config={
|
|
602
|
+
stream_iterator = agent_executor.stream(prompt, config={"callbacks": callbacks})
|
|
593
603
|
|
|
594
604
|
agent_executor_finished_event = threading.Event()
|
|
595
605
|
|
|
@@ -604,7 +614,10 @@ AI: {response}"""
|
|
|
604
614
|
|
|
605
615
|
# Enqueue Langchain agent streaming chunks in a separate thread to not block event chunks.
|
|
606
616
|
executor_stream_thread = threading.Thread(
|
|
607
|
-
target=stream_worker,
|
|
617
|
+
target=stream_worker,
|
|
618
|
+
daemon=True,
|
|
619
|
+
args=(ctx.dump(),),
|
|
620
|
+
name="LangchainAgent.stream_worker",
|
|
608
621
|
)
|
|
609
622
|
executor_stream_thread.start()
|
|
610
623
|
|
|
@@ -613,24 +626,24 @@ AI: {response}"""
|
|
|
613
626
|
chunk = chunk_queue.get(block=True, timeout=AGENT_CHUNK_POLLING_INTERVAL_SECONDS)
|
|
614
627
|
except queue.Empty:
|
|
615
628
|
continue
|
|
616
|
-
logger.debug(f
|
|
629
|
+
logger.debug(f"Processing streaming chunk {chunk}")
|
|
617
630
|
processed_chunk = self.process_chunk(chunk)
|
|
618
|
-
logger.info(f
|
|
631
|
+
logger.info(f"Processed chunk: {processed_chunk}")
|
|
619
632
|
yield self.add_chunk_metadata(processed_chunk)
|
|
620
633
|
chunk_queue.task_done()
|
|
621
634
|
|
|
622
635
|
def stream_agent(self, df: pd.DataFrame, agent_executor: AgentExecutor, args: Dict) -> Iterable[Dict]:
|
|
623
|
-
base_template = args.get(
|
|
636
|
+
base_template = args.get("prompt_template", args["prompt_template"])
|
|
624
637
|
input_variables = re.findall(r"{{(.*?)}}", base_template)
|
|
625
|
-
return_context = args.get(
|
|
638
|
+
return_context = args.get("return_context", True)
|
|
626
639
|
|
|
627
|
-
prompts, _ = prepare_prompts(df, base_template, input_variables, args.get(
|
|
640
|
+
prompts, _ = prepare_prompts(df, base_template, input_variables, args.get("user_column", USER_COLUMN))
|
|
628
641
|
|
|
629
642
|
callbacks, context_callback = prepare_callbacks(self, args)
|
|
630
643
|
|
|
631
644
|
yield self.add_chunk_metadata({"type": "start", "prompt": prompts[0]})
|
|
632
645
|
|
|
633
|
-
if not hasattr(agent_executor,
|
|
646
|
+
if not hasattr(agent_executor, "stream") or not callable(agent_executor.stream):
|
|
634
647
|
raise AttributeError("The agent_executor does not have a 'stream' method")
|
|
635
648
|
|
|
636
649
|
stream_iterator = self._stream_agent_executor(agent_executor, prompts[0], callbacks)
|
|
@@ -659,21 +672,19 @@ AI: {response}"""
|
|
|
659
672
|
if isinstance(chunk, AgentAction):
|
|
660
673
|
# Format agent actions properly for streaming.
|
|
661
674
|
return {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
675
|
+
"tool": LangchainAgent.process_chunk(chunk.tool),
|
|
676
|
+
"tool_input": LangchainAgent.process_chunk(chunk.tool_input),
|
|
677
|
+
"log": LangchainAgent.process_chunk(chunk.log),
|
|
665
678
|
}
|
|
666
679
|
if isinstance(chunk, AgentStep):
|
|
667
680
|
# Format agent steps properly for streaming.
|
|
668
681
|
return {
|
|
669
|
-
|
|
670
|
-
|
|
682
|
+
"action": LangchainAgent.process_chunk(chunk.action),
|
|
683
|
+
"observation": LangchainAgent.process_chunk(chunk.observation) if chunk.observation else "",
|
|
671
684
|
}
|
|
672
685
|
if issubclass(chunk.__class__, BaseMessage):
|
|
673
686
|
# Extract content from message subclasses properly for streaming.
|
|
674
|
-
return {
|
|
675
|
-
'content': chunk.content
|
|
676
|
-
}
|
|
687
|
+
return {"content": chunk.content}
|
|
677
688
|
if isinstance(chunk, (str, int, float, bool, type(None))):
|
|
678
689
|
return chunk
|
|
679
690
|
return str(chunk)
|
|
@@ -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 []
|