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.

Files changed (310) hide show
  1. mindsdb/__about__.py +1 -1
  2. mindsdb/__main__.py +127 -79
  3. mindsdb/api/a2a/__init__.py +0 -0
  4. mindsdb/api/a2a/__main__.py +114 -0
  5. mindsdb/api/a2a/a2a_client.py +439 -0
  6. mindsdb/api/a2a/agent.py +308 -0
  7. mindsdb/api/a2a/common/__init__.py +0 -0
  8. mindsdb/api/a2a/common/client/__init__.py +4 -0
  9. mindsdb/api/a2a/common/client/card_resolver.py +21 -0
  10. mindsdb/api/a2a/common/client/client.py +86 -0
  11. mindsdb/api/a2a/common/server/__init__.py +4 -0
  12. mindsdb/api/a2a/common/server/server.py +164 -0
  13. mindsdb/api/a2a/common/server/task_manager.py +287 -0
  14. mindsdb/api/a2a/common/server/utils.py +28 -0
  15. mindsdb/api/a2a/common/types.py +365 -0
  16. mindsdb/api/a2a/constants.py +9 -0
  17. mindsdb/api/a2a/run_a2a.py +129 -0
  18. mindsdb/api/a2a/task_manager.py +594 -0
  19. mindsdb/api/executor/command_executor.py +47 -27
  20. mindsdb/api/executor/datahub/classes/response.py +5 -2
  21. mindsdb/api/executor/datahub/datanodes/integration_datanode.py +39 -72
  22. mindsdb/api/executor/planner/query_planner.py +10 -1
  23. mindsdb/api/executor/sql_query/result_set.py +185 -52
  24. mindsdb/api/executor/sql_query/sql_query.py +1 -1
  25. mindsdb/api/executor/sql_query/steps/apply_predictor_step.py +9 -12
  26. mindsdb/api/executor/sql_query/steps/fetch_dataframe.py +8 -10
  27. mindsdb/api/executor/sql_query/steps/fetch_dataframe_partition.py +5 -44
  28. mindsdb/api/executor/sql_query/steps/insert_step.py +24 -15
  29. mindsdb/api/executor/sql_query/steps/join_step.py +1 -1
  30. mindsdb/api/executor/sql_query/steps/project_step.py +1 -1
  31. mindsdb/api/executor/sql_query/steps/sql_steps.py +1 -1
  32. mindsdb/api/executor/sql_query/steps/subselect_step.py +4 -8
  33. mindsdb/api/executor/sql_query/steps/union_step.py +1 -3
  34. mindsdb/api/http/initialize.py +99 -83
  35. mindsdb/api/http/namespaces/analysis.py +3 -3
  36. mindsdb/api/http/namespaces/file.py +8 -2
  37. mindsdb/api/http/namespaces/sql.py +13 -27
  38. mindsdb/api/mcp/start.py +42 -5
  39. mindsdb/api/mysql/mysql_proxy/data_types/mysql_packet.py +0 -1
  40. mindsdb/api/mysql/mysql_proxy/data_types/mysql_packets/binary_resultset_row_package.py +52 -19
  41. mindsdb/api/mysql/mysql_proxy/executor/mysql_executor.py +8 -10
  42. mindsdb/api/mysql/mysql_proxy/libs/constants/mysql.py +54 -38
  43. mindsdb/api/mysql/mysql_proxy/mysql_proxy.py +82 -115
  44. mindsdb/api/mysql/mysql_proxy/utilities/dump.py +351 -0
  45. mindsdb/api/postgres/postgres_proxy/executor/executor.py +1 -1
  46. mindsdb/api/postgres/postgres_proxy/postgres_proxy.py +5 -6
  47. mindsdb/integrations/handlers/altibase_handler/altibase_handler.py +26 -27
  48. mindsdb/integrations/handlers/altibase_handler/connection_args.py +13 -13
  49. mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler.py +8 -8
  50. mindsdb/integrations/handlers/altibase_handler/tests/test_altibase_handler_dsn.py +13 -13
  51. mindsdb/integrations/handlers/anthropic_handler/__init__.py +2 -2
  52. mindsdb/integrations/handlers/anthropic_handler/anthropic_handler.py +1 -3
  53. mindsdb/integrations/handlers/aurora_handler/aurora_handler.py +1 -0
  54. mindsdb/integrations/handlers/autosklearn_handler/autosklearn_handler.py +1 -1
  55. mindsdb/integrations/handlers/autosklearn_handler/config.py +0 -1
  56. mindsdb/integrations/handlers/bigquery_handler/bigquery_handler.py +1 -1
  57. mindsdb/integrations/handlers/bigquery_handler/tests/test_bigquery_handler.py +1 -1
  58. mindsdb/integrations/handlers/binance_handler/binance_handler.py +1 -0
  59. mindsdb/integrations/handlers/binance_handler/binance_tables.py +3 -4
  60. mindsdb/integrations/handlers/byom_handler/__init__.py +0 -1
  61. mindsdb/integrations/handlers/ckan_handler/ckan_handler.py +3 -0
  62. mindsdb/integrations/handlers/clickhouse_handler/__init__.py +1 -1
  63. mindsdb/integrations/handlers/cloud_spanner_handler/tests/test_cloud_spanner_handler.py +0 -2
  64. mindsdb/integrations/handlers/cloud_sql_handler/cloud_sql_handler.py +0 -1
  65. mindsdb/integrations/handlers/cohere_handler/__init__.py +1 -1
  66. mindsdb/integrations/handlers/cohere_handler/cohere_handler.py +11 -13
  67. mindsdb/integrations/handlers/confluence_handler/confluence_tables.py +6 -0
  68. mindsdb/integrations/handlers/databend_handler/connection_args.py +1 -1
  69. mindsdb/integrations/handlers/databend_handler/databend_handler.py +4 -4
  70. mindsdb/integrations/handlers/databend_handler/tests/__init__.py +0 -1
  71. mindsdb/integrations/handlers/databend_handler/tests/test_databend_handler.py +1 -1
  72. mindsdb/integrations/handlers/derby_handler/connection_args.py +1 -1
  73. mindsdb/integrations/handlers/derby_handler/derby_handler.py +14 -22
  74. mindsdb/integrations/handlers/derby_handler/tests/test_derby_handler.py +6 -6
  75. mindsdb/integrations/handlers/discord_handler/discord_handler.py +5 -5
  76. mindsdb/integrations/handlers/discord_handler/discord_tables.py +3 -3
  77. mindsdb/integrations/handlers/discord_handler/tests/test_discord.py +5 -3
  78. mindsdb/integrations/handlers/dockerhub_handler/dockerhub.py +3 -3
  79. mindsdb/integrations/handlers/dockerhub_handler/dockerhub_handler.py +2 -2
  80. mindsdb/integrations/handlers/dockerhub_handler/dockerhub_tables.py +57 -54
  81. mindsdb/integrations/handlers/dremio_handler/__init__.py +2 -2
  82. mindsdb/integrations/handlers/druid_handler/__init__.py +1 -1
  83. mindsdb/integrations/handlers/druid_handler/druid_handler.py +2 -2
  84. mindsdb/integrations/handlers/edgelessdb_handler/tests/test_edgelessdb_handler.py +9 -9
  85. mindsdb/integrations/handlers/email_handler/email_client.py +1 -1
  86. mindsdb/integrations/handlers/email_handler/email_ingestor.py +1 -1
  87. mindsdb/integrations/handlers/email_handler/email_tables.py +0 -1
  88. mindsdb/integrations/handlers/email_handler/settings.py +0 -1
  89. mindsdb/integrations/handlers/eventstoredb_handler/eventstoredb_handler.py +2 -1
  90. mindsdb/integrations/handlers/firebird_handler/firebird_handler.py +1 -1
  91. mindsdb/integrations/handlers/flaml_handler/flaml_handler.py +9 -9
  92. mindsdb/integrations/handlers/frappe_handler/frappe_client.py +5 -5
  93. mindsdb/integrations/handlers/frappe_handler/frappe_handler.py +6 -5
  94. mindsdb/integrations/handlers/frappe_handler/frappe_tables.py +2 -2
  95. mindsdb/integrations/handlers/github_handler/connection_args.py +2 -2
  96. mindsdb/integrations/handlers/github_handler/github_handler.py +1 -8
  97. mindsdb/integrations/handlers/github_handler/github_tables.py +13 -24
  98. mindsdb/integrations/handlers/gitlab_handler/gitlab_handler.py +2 -1
  99. mindsdb/integrations/handlers/gitlab_handler/gitlab_tables.py +1 -4
  100. mindsdb/integrations/handlers/gmail_handler/gmail_handler.py +6 -13
  101. mindsdb/integrations/handlers/google_books_handler/google_books_handler.py +2 -1
  102. mindsdb/integrations/handlers/google_books_handler/google_books_tables.py +0 -3
  103. mindsdb/integrations/handlers/google_calendar_handler/google_calendar_handler.py +4 -4
  104. mindsdb/integrations/handlers/google_calendar_handler/google_calendar_tables.py +2 -6
  105. mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_handler.py +3 -2
  106. mindsdb/integrations/handlers/google_content_shopping_handler/google_content_shopping_tables.py +0 -3
  107. mindsdb/integrations/handlers/google_fit_handler/google_fit_handler.py +10 -12
  108. mindsdb/integrations/handlers/google_fit_handler/google_fit_tables.py +11 -13
  109. mindsdb/integrations/handlers/google_search_handler/google_search_handler.py +2 -1
  110. mindsdb/integrations/handlers/google_search_handler/google_search_tables.py +0 -3
  111. mindsdb/integrations/handlers/groq_handler/__init__.py +3 -3
  112. mindsdb/integrations/handlers/hackernews_handler/hn_handler.py +5 -7
  113. mindsdb/integrations/handlers/hackernews_handler/hn_table.py +6 -7
  114. mindsdb/integrations/handlers/hive_handler/tests/test_hive_handler.py +1 -1
  115. mindsdb/integrations/handlers/hsqldb_handler/connection_args.py +6 -6
  116. mindsdb/integrations/handlers/hsqldb_handler/hsqldb_handler.py +4 -3
  117. mindsdb/integrations/handlers/huggingface_api_handler/exceptions.py +1 -1
  118. mindsdb/integrations/handlers/huggingface_api_handler/huggingface_api_handler.py +1 -8
  119. mindsdb/integrations/handlers/huggingface_handler/huggingface_handler.py +6 -6
  120. mindsdb/integrations/handlers/huggingface_handler/requirements.txt +1 -1
  121. mindsdb/integrations/handlers/huggingface_handler/requirements_cpu.txt +1 -1
  122. mindsdb/integrations/handlers/ignite_handler/ignite_handler.py +2 -1
  123. mindsdb/integrations/handlers/impala_handler/impala_handler.py +9 -12
  124. mindsdb/integrations/handlers/impala_handler/tests/test_impala_handler.py +11 -11
  125. mindsdb/integrations/handlers/influxdb_handler/influxdb_handler.py +10 -13
  126. mindsdb/integrations/handlers/influxdb_handler/influxdb_tables.py +20 -20
  127. mindsdb/integrations/handlers/informix_handler/__about__.py +8 -8
  128. mindsdb/integrations/handlers/informix_handler/__init__.py +12 -5
  129. mindsdb/integrations/handlers/informix_handler/informix_handler.py +99 -133
  130. mindsdb/integrations/handlers/informix_handler/tests/test_informix_handler.py +13 -11
  131. mindsdb/integrations/handlers/ingres_handler/__about__.py +0 -1
  132. mindsdb/integrations/handlers/ingres_handler/ingres_handler.py +1 -0
  133. mindsdb/integrations/handlers/jira_handler/jira_handler.py +4 -4
  134. mindsdb/integrations/handlers/jira_handler/jira_tables.py +9 -9
  135. mindsdb/integrations/handlers/kinetica_handler/__init__.py +0 -1
  136. mindsdb/integrations/handlers/langchain_handler/langchain_handler.py +4 -4
  137. mindsdb/integrations/handlers/langchain_handler/tools.py +9 -10
  138. mindsdb/integrations/handlers/leonardoai_handler/__init__.py +1 -1
  139. mindsdb/integrations/handlers/lightwood_handler/functions.py +2 -2
  140. mindsdb/integrations/handlers/lightwood_handler/lightwood_handler.py +0 -1
  141. mindsdb/integrations/handlers/lightwood_handler/tests/test_lightwood_handler.py +11 -11
  142. mindsdb/integrations/handlers/llama_index_handler/llama_index_handler.py +4 -4
  143. mindsdb/integrations/handlers/llama_index_handler/settings.py +10 -9
  144. mindsdb/integrations/handlers/materialize_handler/tests/test_materialize_handler.py +8 -10
  145. mindsdb/integrations/handlers/matrixone_handler/matrixone_handler.py +4 -4
  146. mindsdb/integrations/handlers/matrixone_handler/tests/test_matrixone_handler.py +8 -9
  147. mindsdb/integrations/handlers/maxdb_handler/connection_args.py +25 -25
  148. mindsdb/integrations/handlers/maxdb_handler/maxdb_handler.py +1 -0
  149. mindsdb/integrations/handlers/mediawiki_handler/mediawiki_handler.py +3 -2
  150. mindsdb/integrations/handlers/mediawiki_handler/mediawiki_tables.py +1 -1
  151. mindsdb/integrations/handlers/mendeley_handler/__about__.py +1 -1
  152. mindsdb/integrations/handlers/mendeley_handler/__init__.py +2 -2
  153. mindsdb/integrations/handlers/mendeley_handler/mendeley_handler.py +48 -56
  154. mindsdb/integrations/handlers/mendeley_handler/mendeley_tables.py +24 -29
  155. mindsdb/integrations/handlers/mendeley_handler/tests/test_mendeley_handler.py +19 -17
  156. mindsdb/integrations/handlers/merlion_handler/merlion_handler.py +5 -4
  157. mindsdb/integrations/handlers/minds_endpoint_handler/__init__.py +3 -3
  158. mindsdb/integrations/handlers/mlflow_handler/mlflow_handler.py +58 -36
  159. mindsdb/integrations/handlers/monetdb_handler/__about__.py +8 -8
  160. mindsdb/integrations/handlers/monetdb_handler/__init__.py +15 -5
  161. mindsdb/integrations/handlers/monetdb_handler/connection_args.py +17 -18
  162. mindsdb/integrations/handlers/monetdb_handler/monetdb_handler.py +40 -57
  163. mindsdb/integrations/handlers/monetdb_handler/tests/test_monetdb_handler.py +7 -8
  164. mindsdb/integrations/handlers/monetdb_handler/utils/monet_get_id.py +13 -14
  165. mindsdb/integrations/handlers/monkeylearn_handler/__about__.py +1 -1
  166. mindsdb/integrations/handlers/monkeylearn_handler/__init__.py +1 -1
  167. mindsdb/integrations/handlers/monkeylearn_handler/monkeylearn_handler.py +2 -5
  168. mindsdb/integrations/handlers/ms_one_drive_handler/ms_graph_api_one_drive_client.py +1 -0
  169. mindsdb/integrations/handlers/ms_one_drive_handler/ms_one_drive_handler.py +1 -1
  170. mindsdb/integrations/handlers/ms_teams_handler/ms_graph_api_teams_client.py +23 -23
  171. mindsdb/integrations/handlers/ms_teams_handler/ms_teams_handler.py +3 -3
  172. mindsdb/integrations/handlers/ms_teams_handler/ms_teams_tables.py +10 -5
  173. mindsdb/integrations/handlers/mssql_handler/mssql_handler.py +73 -8
  174. mindsdb/integrations/handlers/mysql_handler/__about__.py +8 -8
  175. mindsdb/integrations/handlers/mysql_handler/__init__.py +15 -5
  176. mindsdb/integrations/handlers/mysql_handler/connection_args.py +43 -47
  177. mindsdb/integrations/handlers/mysql_handler/mysql_handler.py +101 -34
  178. mindsdb/integrations/handlers/mysql_handler/settings.py +15 -13
  179. mindsdb/integrations/handlers/neuralforecast_handler/neuralforecast_handler.py +1 -1
  180. mindsdb/integrations/handlers/newsapi_handler/newsapi_handler.py +1 -1
  181. mindsdb/integrations/handlers/newsapi_handler/tests/test_newsapi_handler.py +4 -4
  182. mindsdb/integrations/handlers/nuo_jdbc_handler/connection_args.py +2 -2
  183. mindsdb/integrations/handlers/nuo_jdbc_handler/nuo_jdbc_handler.py +28 -36
  184. mindsdb/integrations/handlers/nuo_jdbc_handler/tests/test_nuo_handler.py +5 -5
  185. mindsdb/integrations/handlers/oceanbase_handler/oceanbase_handler.py +0 -1
  186. mindsdb/integrations/handlers/oceanbase_handler/tests/test_oceanbase_handler.py +8 -10
  187. mindsdb/integrations/handlers/ollama_handler/ollama_handler.py +3 -3
  188. mindsdb/integrations/handlers/opengauss_handler/tests/test_opengauss_handler.py +1 -2
  189. mindsdb/integrations/handlers/openstreetmap_handler/__init__.py +7 -7
  190. mindsdb/integrations/handlers/oracle_handler/connection_args.py +6 -0
  191. mindsdb/integrations/handlers/oracle_handler/oracle_handler.py +77 -11
  192. mindsdb/integrations/handlers/orioledb_handler/tests/test_orioledb_handler.py +8 -10
  193. mindsdb/integrations/handlers/palm_handler/__about__.py +1 -1
  194. mindsdb/integrations/handlers/palm_handler/__init__.py +1 -1
  195. mindsdb/integrations/handlers/palm_handler/palm_handler.py +1 -3
  196. mindsdb/integrations/handlers/paypal_handler/paypal_handler.py +2 -2
  197. mindsdb/integrations/handlers/paypal_handler/paypal_tables.py +15 -14
  198. mindsdb/integrations/handlers/pgvector_handler/pgvector_handler.py +53 -10
  199. mindsdb/integrations/handlers/phoenix_handler/__init__.py +1 -1
  200. mindsdb/integrations/handlers/phoenix_handler/phoenix_handler.py +1 -0
  201. mindsdb/integrations/handlers/pinot_handler/__init__.py +1 -1
  202. mindsdb/integrations/handlers/pinot_handler/pinot_handler.py +3 -2
  203. mindsdb/integrations/handlers/plaid_handler/plaid_handler.py +13 -13
  204. mindsdb/integrations/handlers/plaid_handler/plaid_tables.py +10 -12
  205. mindsdb/integrations/handlers/plaid_handler/utils.py +4 -6
  206. mindsdb/integrations/handlers/planetscale_handler/planetscale_handler.py +1 -4
  207. mindsdb/integrations/handlers/portkey_handler/__init__.py +2 -2
  208. mindsdb/integrations/handlers/postgres_handler/postgres_handler.py +105 -24
  209. mindsdb/integrations/handlers/postgres_handler/tests/test_postgres_handler.py +11 -6
  210. mindsdb/integrations/handlers/questdb_handler/questdb_handler.py +1 -2
  211. mindsdb/integrations/handlers/questdb_handler/tests/test_questdb_handler.py +2 -3
  212. mindsdb/integrations/handlers/quickbooks_handler/quickbooks_handler.py +6 -8
  213. mindsdb/integrations/handlers/quickbooks_handler/quickbooks_table.py +10 -10
  214. mindsdb/integrations/handlers/rag_handler/ingest.py +2 -2
  215. mindsdb/integrations/handlers/rag_handler/rag_handler.py +1 -1
  216. mindsdb/integrations/handlers/rag_handler/settings.py +1 -1
  217. mindsdb/integrations/handlers/reddit_handler/reddit_handler.py +2 -7
  218. mindsdb/integrations/handlers/reddit_handler/reddit_tables.py +2 -3
  219. mindsdb/integrations/handlers/replicate_handler/replicate_handler.py +6 -6
  220. mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_handler.py +1 -2
  221. mindsdb/integrations/handlers/rocket_chat_handler/rocket_chat_tables.py +0 -3
  222. mindsdb/integrations/handlers/rockset_handler/connection_args.py +14 -14
  223. mindsdb/integrations/handlers/rockset_handler/tests/test_rockset_handler.py +1 -0
  224. mindsdb/integrations/handlers/scylla_handler/scylla_handler.py +6 -5
  225. mindsdb/integrations/handlers/sendinblue_handler/sendinblue_handler.py +2 -1
  226. mindsdb/integrations/handlers/sendinblue_handler/sendinblue_tables.py +16 -16
  227. mindsdb/integrations/handlers/sentence_transformers_handler/__init__.py +1 -1
  228. mindsdb/integrations/handlers/sheets_handler/connection_args.py +1 -1
  229. mindsdb/integrations/handlers/shopify_handler/shopify_handler.py +7 -6
  230. mindsdb/integrations/handlers/shopify_handler/shopify_tables.py +38 -41
  231. mindsdb/integrations/handlers/singlestore_handler/__about__.py +1 -1
  232. mindsdb/integrations/handlers/singlestore_handler/__init__.py +0 -1
  233. mindsdb/integrations/handlers/singlestore_handler/singlestore_handler.py +1 -0
  234. mindsdb/integrations/handlers/singlestore_handler/tests/test_singlestore_handler.py +3 -3
  235. mindsdb/integrations/handlers/slack_handler/__init__.py +3 -3
  236. mindsdb/integrations/handlers/snowflake_handler/snowflake_handler.py +100 -6
  237. mindsdb/integrations/handlers/solr_handler/connection_args.py +7 -7
  238. mindsdb/integrations/handlers/solr_handler/solr_handler.py +2 -1
  239. mindsdb/integrations/handlers/solr_handler/tests/test_solr_handler.py +2 -1
  240. mindsdb/integrations/handlers/sqlany_handler/sqlany_handler.py +3 -2
  241. mindsdb/integrations/handlers/sqlite_handler/sqlite_handler.py +1 -0
  242. mindsdb/integrations/handlers/sqreamdb_handler/connection_args.py +1 -1
  243. mindsdb/integrations/handlers/sqreamdb_handler/sqreamdb_handler.py +15 -20
  244. mindsdb/integrations/handlers/sqreamdb_handler/tests/test_sqreamdb_handler.py +4 -4
  245. mindsdb/integrations/handlers/stabilityai_handler/__init__.py +1 -1
  246. mindsdb/integrations/handlers/starrocks_handler/starrocks_handler.py +0 -1
  247. mindsdb/integrations/handlers/starrocks_handler/tests/test_starrocks_handler.py +8 -10
  248. mindsdb/integrations/handlers/statsforecast_handler/statsforecast_handler.py +2 -2
  249. mindsdb/integrations/handlers/strava_handler/strava_handler.py +4 -8
  250. mindsdb/integrations/handlers/strava_handler/strava_tables.py +22 -30
  251. mindsdb/integrations/handlers/stripe_handler/stripe_handler.py +3 -2
  252. mindsdb/integrations/handlers/stripe_handler/stripe_tables.py +11 -27
  253. mindsdb/integrations/handlers/supabase_handler/tests/test_supabase_handler.py +1 -1
  254. mindsdb/integrations/handlers/surrealdb_handler/surrealdb_handler.py +4 -4
  255. mindsdb/integrations/handlers/tdengine_handler/tdengine_handler.py +25 -27
  256. mindsdb/integrations/handlers/tdengine_handler/tests/test_tdengine_handler.py +8 -8
  257. mindsdb/integrations/handlers/tidb_handler/tests/test_tidb_handler.py +1 -2
  258. mindsdb/integrations/handlers/timegpt_handler/timegpt_handler.py +5 -5
  259. mindsdb/integrations/handlers/tpot_handler/tpot_handler.py +21 -26
  260. mindsdb/integrations/handlers/trino_handler/trino_handler.py +14 -14
  261. mindsdb/integrations/handlers/twitter_handler/twitter_handler.py +2 -4
  262. mindsdb/integrations/handlers/unify_handler/tests/test_unify_handler.py +7 -8
  263. mindsdb/integrations/handlers/unify_handler/unify_handler.py +9 -9
  264. mindsdb/integrations/handlers/vertex_handler/vertex_client.py +1 -1
  265. mindsdb/integrations/handlers/vertica_handler/tests/test_vertica_handler.py +11 -11
  266. mindsdb/integrations/handlers/vertica_handler/vertica_handler.py +11 -14
  267. mindsdb/integrations/handlers/vitess_handler/tests/test_vitess_handler.py +9 -11
  268. mindsdb/integrations/handlers/vitess_handler/vitess_handler.py +0 -1
  269. mindsdb/integrations/handlers/web_handler/web_handler.py +1 -0
  270. mindsdb/integrations/handlers/whatsapp_handler/__init__.py +3 -3
  271. mindsdb/integrations/handlers/writer_handler/evaluate.py +1 -1
  272. mindsdb/integrations/handlers/writer_handler/settings.py +0 -1
  273. mindsdb/integrations/handlers/writer_handler/writer_handler.py +1 -0
  274. mindsdb/integrations/handlers/youtube_handler/youtube_handler.py +5 -5
  275. mindsdb/integrations/handlers/youtube_handler/youtube_tables.py +26 -27
  276. mindsdb/integrations/handlers/yugabyte_handler/tests/test_yugabyte_handler.py +3 -3
  277. mindsdb/integrations/handlers/yugabyte_handler/yugabyte_handler.py +0 -6
  278. mindsdb/integrations/libs/response.py +67 -52
  279. mindsdb/integrations/libs/vectordatabase_handler.py +6 -0
  280. mindsdb/integrations/utilities/handler_utils.py +15 -3
  281. mindsdb/integrations/utilities/handlers/api_utilities/__init__.py +0 -1
  282. mindsdb/integrations/utilities/handlers/auth_utilities/__init__.py +0 -2
  283. mindsdb/integrations/utilities/utils.py +3 -3
  284. mindsdb/interfaces/agents/agents_controller.py +164 -1
  285. mindsdb/interfaces/agents/constants.py +15 -0
  286. mindsdb/interfaces/agents/langchain_agent.py +16 -4
  287. mindsdb/interfaces/agents/mindsdb_database_agent.py +101 -2
  288. mindsdb/interfaces/knowledge_base/controller.py +25 -0
  289. mindsdb/interfaces/knowledge_base/preprocessing/document_preprocessor.py +13 -10
  290. mindsdb/interfaces/knowledge_base/preprocessing/json_chunker.py +434 -0
  291. mindsdb/interfaces/knowledge_base/preprocessing/models.py +54 -0
  292. mindsdb/interfaces/query_context/context_controller.py +66 -10
  293. mindsdb/interfaces/skills/custom/text2sql/mindsdb_kb_tools.py +190 -0
  294. mindsdb/interfaces/skills/custom/text2sql/mindsdb_sql_toolkit.py +92 -0
  295. mindsdb/interfaces/skills/skill_tool.py +202 -57
  296. mindsdb/interfaces/skills/sql_agent.py +205 -17
  297. mindsdb/interfaces/storage/fs.py +1 -0
  298. mindsdb/interfaces/variables/__init__.py +0 -0
  299. mindsdb/interfaces/variables/variables_controller.py +97 -0
  300. mindsdb/migrations/env.py +5 -7
  301. mindsdb/migrations/migrate.py +47 -7
  302. mindsdb/migrations/versions/2025-05-21_9f150e4f9a05_checkpoint_1.py +360 -0
  303. mindsdb/utilities/config.py +331 -219
  304. mindsdb/utilities/starters.py +13 -0
  305. {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/METADATA +641 -695
  306. {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/RECORD +309 -288
  307. {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/WHEEL +1 -1
  308. mindsdb/integrations/handlers/monkeylearn_handler/requirements.txt +0 -1
  309. {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/licenses/LICENSE +0 -0
  310. {mindsdb-25.5.3.0.dist-info → mindsdb-25.5.4.0.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,9 @@ from appdirs import user_data_dir
15
15
  def _merge_key_recursive(target_dict, source_dict, key):
16
16
  if key not in target_dict:
17
17
  target_dict[key] = source_dict[key]
18
- elif not isinstance(target_dict[key], dict) or not isinstance(source_dict[key], dict):
18
+ elif not isinstance(target_dict[key], dict) or not isinstance(
19
+ source_dict[key], dict
20
+ ):
19
21
  target_dict[key] = source_dict[key]
20
22
  else:
21
23
  for k in list(source_dict[key].keys()):
@@ -45,14 +47,10 @@ def create_data_dir(path: Path) -> None:
45
47
  try:
46
48
  path.mkdir(mode=0o777, exist_ok=True, parents=True)
47
49
  except Exception as e:
48
- raise Exception(
49
- "MindsDB storage directory could not be created"
50
- ) from e
50
+ raise Exception("MindsDB storage directory could not be created") from e
51
51
 
52
52
  if not os.access(path, os.W_OK):
53
- raise PermissionError(
54
- f"The directory is not allowed for writing: {path}"
55
- )
53
+ raise PermissionError(f"The directory is not allowed for writing: {path}")
56
54
 
57
55
 
58
56
  class Config:
@@ -79,7 +77,8 @@ class Config:
79
77
  _cmd_args (argparse.Namespace): cmd args
80
78
  use_docker_env (bool): is the app run in docker env
81
79
  """
82
- __instance: 'Config' = None
80
+
81
+ __instance: "Config" = None
83
82
 
84
83
  _config: dict = None
85
84
  _user_config: dict = None
@@ -91,11 +90,10 @@ class Config:
91
90
  auto_config_path: Path = None
92
91
  auto_config_mtime: float = 0
93
92
  _cmd_args: argparse.Namespace = None
94
- use_docker_env: bool = os.environ.get('MINDSDB_DOCKER_ENV', False) is not False
93
+ use_docker_env: bool = os.environ.get("MINDSDB_DOCKER_ENV", False) is not False
95
94
 
96
- def __new__(cls, *args, **kwargs) -> 'Config':
97
- """Make class singletone and initialize config.
98
- """
95
+ def __new__(cls, *args, **kwargs) -> "Config":
96
+ """Make class singletone and initialize config."""
99
97
  if cls.__instance is not None:
100
98
  return cls.__instance
101
99
 
@@ -106,14 +104,13 @@ class Config:
106
104
 
107
105
  # region determine root path
108
106
  if self.storage_root_path is None:
109
- if isinstance(os.environ.get('MINDSDB_STORAGE_DIR'), str):
110
- self.storage_root_path = os.environ['MINDSDB_STORAGE_DIR']
111
- elif 'root' in self._user_config.get('paths', {}):
112
- self.storage_root_path = self.user_config['paths']['root']
107
+ if isinstance(os.environ.get("MINDSDB_STORAGE_DIR"), str):
108
+ self.storage_root_path = os.environ["MINDSDB_STORAGE_DIR"]
109
+ elif "root" in self._user_config.get("paths", {}):
110
+ self.storage_root_path = self.user_config["paths"]["root"]
113
111
  else:
114
112
  self.storage_root_path = os.path.join(
115
- user_data_dir("mindsdb", "mindsdb"),
116
- "var/"
113
+ user_data_dir("mindsdb", "mindsdb"), "var/"
117
114
  )
118
115
  self.storage_root_path = Path(self.storage_root_path)
119
116
  create_data_dir(self.storage_root_path)
@@ -122,49 +119,45 @@ class Config:
122
119
  # region prepare default config
123
120
  api_host = "127.0.0.1" if not self.use_docker_env else "0.0.0.0"
124
121
  self._default_config = {
125
- 'permanent_storage': {
126
- 'location': 'absent'
127
- },
122
+ "permanent_storage": {"location": "absent"},
128
123
  "storage_db": (
129
- 'sqlite:///'
130
- + str(self.storage_root_path / 'mindsdb.sqlite3.db')
131
- + '?check_same_thread=False&timeout=30'
124
+ "sqlite:///"
125
+ + str(self.storage_root_path / "mindsdb.sqlite3.db")
126
+ + "?check_same_thread=False&timeout=30"
132
127
  ),
133
- 'paths': {
134
- 'root': self.storage_root_path,
135
- 'content': self.storage_root_path / 'content',
136
- 'storage': self.storage_root_path / 'storage',
137
- 'static': self.storage_root_path / 'static',
138
- 'tmp': self.storage_root_path / 'tmp',
139
- 'log': self.storage_root_path / 'log',
140
- 'cache': self.storage_root_path / 'cache',
141
- 'locks': self.storage_root_path / 'locks',
128
+ "paths": {
129
+ "root": self.storage_root_path,
130
+ "content": self.storage_root_path / "content",
131
+ "storage": self.storage_root_path / "storage",
132
+ "static": self.storage_root_path / "static",
133
+ "tmp": self.storage_root_path / "tmp",
134
+ "log": self.storage_root_path / "log",
135
+ "cache": self.storage_root_path / "cache",
136
+ "locks": self.storage_root_path / "locks",
142
137
  },
143
- 'auth': {
144
- 'http_auth_enabled': False,
138
+ "auth": {
139
+ "http_auth_enabled": False,
145
140
  "http_permanent_session_lifetime": datetime.timedelta(days=31),
146
141
  "username": "mindsdb",
147
- "password": ""
142
+ "password": "",
148
143
  },
149
144
  "logging": {
150
145
  "handlers": {
151
146
  "console": {
152
147
  "enabled": True,
153
148
  "formatter": "default",
154
- "level": "INFO" # MINDSDB_CONSOLE_LOG_LEVEL or MINDSDB_LOG_LEVEL (obsolete)
149
+ "level": "INFO", # MINDSDB_CONSOLE_LOG_LEVEL or MINDSDB_LOG_LEVEL (obsolete)
155
150
  },
156
151
  "file": {
157
152
  "enabled": False,
158
- "level": "INFO", # MINDSDB_FILE_LOG_LEVEL
153
+ "level": "INFO", # MINDSDB_FILE_LOG_LEVEL
159
154
  "filename": "app.log",
160
- "maxBytes": 1 << 19, # 0.5 Mb
161
- "backupCount": 3
162
- }
155
+ "maxBytes": 1 << 19, # 0.5 Mb
156
+ "backupCount": 3,
157
+ },
163
158
  }
164
159
  },
165
- "gui": {
166
- "autoupdate": True
167
- },
160
+ "gui": {"autoupdate": True},
168
161
  "debug": False,
169
162
  "environment": "local",
170
163
  "integrations": {},
@@ -176,13 +169,13 @@ class Config:
176
169
  "max_restart_count": 1,
177
170
  "max_restart_interval_seconds": 60,
178
171
  "server": {
179
- "type": "waitress", # MINDSDB_HTTP_SERVER_TYPE MINDSDB_DEFAULT_SERVER
172
+ "type": "waitress", # MINDSDB_HTTP_SERVER_TYPE MINDSDB_DEFAULT_SERVER
180
173
  "config": {
181
174
  "threads": 16,
182
- "max_request_body_size": (1 << 30) * 10, # 10GB
183
- "inbuf_overflow": (1 << 30) * 10
184
- }
185
- }
175
+ "max_request_body_size": (1 << 30) * 10, # 10GB
176
+ "inbuf_overflow": (1 << 30) * 10,
177
+ },
178
+ },
186
179
  },
187
180
  "mysql": {
188
181
  "host": api_host,
@@ -191,57 +184,49 @@ class Config:
191
184
  "ssl": True,
192
185
  "restart_on_failure": True,
193
186
  "max_restart_count": 1,
194
- "max_restart_interval_seconds": 60
195
- },
196
- "mongodb": {
197
- "host": api_host,
198
- "port": "47336",
199
- "database": "mindsdb"
200
- },
201
- "postgres": {
202
- "host": api_host,
203
- "port": "55432",
204
- "database": "mindsdb"
187
+ "max_restart_interval_seconds": 60,
205
188
  },
189
+ "mongodb": {"host": api_host, "port": "47336", "database": "mindsdb"},
190
+ "postgres": {"host": api_host, "port": "55432", "database": "mindsdb"},
206
191
  "mcp": {
207
192
  "host": api_host,
208
193
  "port": "47337",
209
194
  "enabled": True,
210
195
  "restart_on_failure": True,
211
196
  "max_restart_count": 1,
212
- "max_restart_interval_seconds": 60
197
+ "max_restart_interval_seconds": 60,
213
198
  },
214
199
  "litellm": {
215
200
  "host": "0.0.0.0", # API server binds to all interfaces by default
216
- "port": "8000"
217
- }
218
- },
219
- "cache": {
220
- "type": "local"
221
- },
222
- 'ml_task_queue': {
223
- 'type': 'local'
201
+ "port": "8000",
202
+ },
224
203
  },
204
+ "cache": {"type": "local"},
205
+ "ml_task_queue": {"type": "local"},
225
206
  "file_upload_domains": [],
226
207
  "web_crawling_allowed_sites": [],
227
208
  "cloud": False,
228
- "jobs": {
229
- "disable": False
230
- },
231
- "tasks": {
232
- "disable": False
233
- },
209
+ "jobs": {"disable": False},
210
+ "tasks": {"disable": False},
234
211
  "default_project": "mindsdb",
235
212
  "default_llm": {},
236
- "default_embedding_model": {}
213
+ "default_embedding_model": {},
214
+ "a2a": {
215
+ "host": "localhost",
216
+ "port": 10002,
217
+ "mindsdb_host": "localhost",
218
+ "mindsdb_port": 47334,
219
+ "agent_name": "my_agent",
220
+ "project_name": "mindsdb",
221
+ },
237
222
  }
238
223
  # endregion
239
224
 
240
225
  # region find 'auto' config file, create if not exists
241
- auto_config_name = 'config.auto.json'
226
+ auto_config_name = "config.auto.json"
242
227
  auto_config_path = self.storage_root_path.joinpath(auto_config_name)
243
228
  if not auto_config_path.is_file():
244
- auto_config_path.write_text('{}')
229
+ auto_config_path.write_text("{}")
245
230
  self.auto_config_path = auto_config_path
246
231
  # endregion
247
232
 
@@ -253,163 +238,161 @@ class Config:
253
238
  return cls.__instance
254
239
 
255
240
  def prepare_env_config(self) -> None:
256
- """Collect config values from env vars to self._env_config
257
- """
241
+ """Collect config values from env vars to self._env_config"""
258
242
  self._env_config = {
259
- 'logging': {
260
- 'handlers': {
261
- 'console': {},
262
- 'file': {}
263
- }
264
- },
265
- "api": {
266
- "http": {
267
- "server": {}
268
- }
269
- },
270
- 'auth': {},
271
- 'paths': {},
272
- 'permanent_storage': {},
273
- 'ml_task_queue': {}
243
+ "logging": {"handlers": {"console": {}, "file": {}}},
244
+ "api": {"http": {"server": {}}},
245
+ "auth": {},
246
+ "paths": {},
247
+ "permanent_storage": {},
248
+ "ml_task_queue": {},
249
+ "a2a": {},
274
250
  }
275
251
 
276
252
  # region storage root path
277
- if os.environ.get('MINDSDB_STORAGE_DIR', '') != '':
278
- self._env_config['paths'] = {
279
- 'root': Path(os.environ['MINDSDB_STORAGE_DIR'])
253
+ if os.environ.get("MINDSDB_STORAGE_DIR", "") != "":
254
+ self._env_config["paths"] = {
255
+ "root": Path(os.environ["MINDSDB_STORAGE_DIR"])
280
256
  }
281
257
  # endregion
282
258
 
283
259
  # region vars: permanent storage disabled?
284
- if os.environ.get('MINDSDB_STORAGE_BACKUP_DISABLED', '').lower() in ('1', 'true'):
285
- self._env_config['permanent_storage'] = {
286
- 'location': 'absent'
287
- }
260
+ if os.environ.get("MINDSDB_STORAGE_BACKUP_DISABLED", "").lower() in (
261
+ "1",
262
+ "true",
263
+ ):
264
+ self._env_config["permanent_storage"] = {"location": "absent"}
288
265
  # endregion
289
266
 
290
267
  # region vars: ml queue
291
- if os.environ.get('MINDSDB_ML_QUEUE_TYPE', '').lower() == 'redis':
292
- self._env_config['ml_task_queue'] = {
293
- 'type': 'redis',
294
- 'host': os.environ.get('MINDSDB_ML_QUEUE_HOST', 'localhost'),
295
- 'port': int(os.environ.get('MINDSDB_ML_QUEUE_PORT', 6379)),
296
- 'db': int(os.environ.get('MINDSDB_ML_QUEUE_DB', 0)),
297
- 'username': os.environ.get('MINDSDB_ML_QUEUE_USERNAME'),
298
- 'password': os.environ.get('MINDSDB_ML_QUEUE_PASSWORD')
268
+ if os.environ.get("MINDSDB_ML_QUEUE_TYPE", "").lower() == "redis":
269
+ self._env_config["ml_task_queue"] = {
270
+ "type": "redis",
271
+ "host": os.environ.get("MINDSDB_ML_QUEUE_HOST", "localhost"),
272
+ "port": int(os.environ.get("MINDSDB_ML_QUEUE_PORT", 6379)),
273
+ "db": int(os.environ.get("MINDSDB_ML_QUEUE_DB", 0)),
274
+ "username": os.environ.get("MINDSDB_ML_QUEUE_USERNAME"),
275
+ "password": os.environ.get("MINDSDB_ML_QUEUE_PASSWORD"),
299
276
  }
300
277
  # endregion
301
278
 
302
279
  # region vars: username and password
303
- http_username = os.environ.get('MINDSDB_USERNAME')
304
- http_password = os.environ.get('MINDSDB_PASSWORD')
280
+ http_username = os.environ.get("MINDSDB_USERNAME")
281
+ http_password = os.environ.get("MINDSDB_PASSWORD")
305
282
 
306
283
  if bool(http_username) != bool(http_password):
307
- raise ValueError('Both MINDSDB_USERNAME and MINDSDB_PASSWORD must be set together and must be non-empty strings.')
284
+ raise ValueError(
285
+ "Both MINDSDB_USERNAME and MINDSDB_PASSWORD must be set together and must be non-empty strings."
286
+ )
308
287
 
309
288
  # If both username and password are set, enable HTTP auth.
310
289
  if http_username and http_password:
311
- self._env_config['auth']['http_auth_enabled'] = True
312
- self._env_config['auth']['username'] = http_username
313
- self._env_config['auth']['password'] = http_password
290
+ self._env_config["auth"]["http_auth_enabled"] = True
291
+ self._env_config["auth"]["username"] = http_username
292
+ self._env_config["auth"]["password"] = http_password
314
293
  # endregion
315
294
 
316
295
  # region permanent session lifetime
317
- for env_name in ('MINDSDB_HTTP_PERMANENT_SESSION_LIFETIME', 'FLASK_PERMANENT_SESSION_LIFETIME'):
296
+ for env_name in (
297
+ "MINDSDB_HTTP_PERMANENT_SESSION_LIFETIME",
298
+ "FLASK_PERMANENT_SESSION_LIFETIME",
299
+ ):
318
300
  env_value = os.environ.get(env_name)
319
301
  if isinstance(env_value, str):
320
302
  try:
321
303
  permanent_session_lifetime = int(env_value)
322
304
  except Exception:
323
- raise ValueError(f'Warning: Can\'t cast env var {env_name} value to int: {env_value}')
324
- self._env_config['auth']['http_permanent_session_lifetime'] = permanent_session_lifetime
305
+ raise ValueError(
306
+ f"Warning: Can't cast env var {env_name} value to int: {env_value}"
307
+ )
308
+ self._env_config["auth"][
309
+ "http_permanent_session_lifetime"
310
+ ] = permanent_session_lifetime
325
311
  break
326
312
  # endregion
327
313
 
328
314
  # region logging
329
- if os.environ.get('MINDSDB_LOG_LEVEL', '') != '':
330
- self._env_config['logging']['handlers']['console']['level'] = os.environ['MINDSDB_LOG_LEVEL']
331
- self._env_config['logging']['handlers']['console']['enabled'] = True
332
- if os.environ.get('MINDSDB_CONSOLE_LOG_LEVEL', '') != '':
333
- self._env_config['logging']['handlers']['console']['level'] = os.environ['MINDSDB_LOG_LEVEL']
334
- self._env_config['logging']['handlers']['console']['enabled'] = True
335
- if os.environ.get('MINDSDB_FILE_LOG_LEVEL', '') != '':
336
- self._env_config['logging']['handlers']['file']['level'] = os.environ['MINDSDB_FILE_LOG_LEVEL']
337
- self._env_config['logging']['handlers']['file']['enabled'] = True
315
+ if os.environ.get("MINDSDB_LOG_LEVEL", "") != "":
316
+ self._env_config["logging"]["handlers"]["console"]["level"] = os.environ[
317
+ "MINDSDB_LOG_LEVEL"
318
+ ]
319
+ self._env_config["logging"]["handlers"]["console"]["enabled"] = True
320
+ if os.environ.get("MINDSDB_CONSOLE_LOG_LEVEL", "") != "":
321
+ self._env_config["logging"]["handlers"]["console"]["level"] = os.environ[
322
+ "MINDSDB_LOG_LEVEL"
323
+ ]
324
+ self._env_config["logging"]["handlers"]["console"]["enabled"] = True
325
+ if os.environ.get("MINDSDB_FILE_LOG_LEVEL", "") != "":
326
+ self._env_config["logging"]["handlers"]["file"]["level"] = os.environ[
327
+ "MINDSDB_FILE_LOG_LEVEL"
328
+ ]
329
+ self._env_config["logging"]["handlers"]["file"]["enabled"] = True
338
330
  # endregion
339
331
 
340
332
  # region server type
341
- server_type = os.environ.get('MINDSDB_HTTP_SERVER_TYPE', '').lower()
342
- if server_type == '':
343
- server_type = os.environ.get('MINDSDB_DEFAULT_SERVER', '').lower()
344
- if server_type != '':
345
- if server_type == 'waitress':
346
- self._env_config['api']['http']['server']['type'] = 'waitress'
347
- self._default_config['api']['http']['server']['config'] = {}
348
- self._env_config['api']['http']['server']['config'] = {
333
+ server_type = os.environ.get("MINDSDB_HTTP_SERVER_TYPE", "").lower()
334
+ if server_type == "":
335
+ server_type = os.environ.get("MINDSDB_DEFAULT_SERVER", "").lower()
336
+ if server_type != "":
337
+ if server_type == "waitress":
338
+ self._env_config["api"]["http"]["server"]["type"] = "waitress"
339
+ self._default_config["api"]["http"]["server"]["config"] = {}
340
+ self._env_config["api"]["http"]["server"]["config"] = {
349
341
  "threads": 16,
350
- "max_request_body_size": (1 << 30) * 10, # 10GB
351
- "inbuf_overflow": (1 << 30) * 10
342
+ "max_request_body_size": (1 << 30) * 10, # 10GB
343
+ "inbuf_overflow": (1 << 30) * 10,
352
344
  }
353
- elif server_type == 'flask':
354
- self._env_config['api']['http']['server']['type'] = 'flask'
355
- self._default_config['api']['http']['server']['config'] = {}
356
- self._env_config['api']['http']['server']['config'] = {}
357
- elif server_type == 'gunicorn':
358
- self._env_config['api']['http']['server']['type'] = 'gunicorn'
359
- self._default_config['api']['http']['server']['config'] = {}
360
- self._env_config['api']['http']['server']['config'] = {
361
- 'workers': min(mp.cpu_count(), 4),
362
- 'timeout': 600,
363
- 'reuse_port': True,
364
- 'preload_app': True,
365
- 'threads': 4
345
+ elif server_type == "flask":
346
+ self._env_config["api"]["http"]["server"]["type"] = "flask"
347
+ self._default_config["api"]["http"]["server"]["config"] = {}
348
+ self._env_config["api"]["http"]["server"]["config"] = {}
349
+ elif server_type == "gunicorn":
350
+ self._env_config["api"]["http"]["server"]["type"] = "gunicorn"
351
+ self._default_config["api"]["http"]["server"]["config"] = {}
352
+ self._env_config["api"]["http"]["server"]["config"] = {
353
+ "workers": min(mp.cpu_count(), 4),
354
+ "timeout": 600,
355
+ "reuse_port": True,
356
+ "preload_app": True,
357
+ "threads": 4,
366
358
  }
367
359
  # endregion
368
360
 
369
- if os.environ.get('MINDSDB_DB_CON', '') != '':
370
- self._env_config['storage_db'] = os.environ['MINDSDB_DB_CON']
361
+ if os.environ.get("MINDSDB_DB_CON", "") != "":
362
+ self._env_config["storage_db"] = os.environ["MINDSDB_DB_CON"]
371
363
 
372
- if os.environ.get('MINDSDB_DEFAULT_PROJECT', '') != '':
373
- self._env_config['default_project'] = os.environ['MINDSDB_DEFAULT_PROJECT'].lower()
364
+ if os.environ.get("MINDSDB_DEFAULT_PROJECT", "") != "":
365
+ self._env_config["default_project"] = os.environ[
366
+ "MINDSDB_DEFAULT_PROJECT"
367
+ ].lower()
374
368
 
375
- if os.environ.get('MINDSDB_DEFAULT_LLM_API_KEY', '') != '':
376
- self._env_config['default_llm'] = {
377
- 'api_key': os.environ['MINDSDB_DEFAULT_LLM_API_KEY']
369
+ if os.environ.get("MINDSDB_DEFAULT_LLM_API_KEY", "") != "":
370
+ self._env_config["default_llm"] = {
371
+ "api_key": os.environ["MINDSDB_DEFAULT_LLM_API_KEY"]
378
372
  }
379
- if os.environ.get('MINDSDB_DEFAULT_EMBEDDING_MODEL_API_KEY', '') != '':
380
- self._env_config['default_embedding_model'] = {
381
- 'api_key': os.environ['MINDSDB_DEFAULT_EMBEDDING_MODEL_API_KEY']
373
+ if os.environ.get("MINDSDB_DEFAULT_EMBEDDING_MODEL_API_KEY", "") != "":
374
+ self._env_config["default_embedding_model"] = {
375
+ "api_key": os.environ["MINDSDB_DEFAULT_EMBEDDING_MODEL_API_KEY"]
382
376
  }
383
377
 
384
- def parse_cmd_args(self) -> None:
385
- """Collect cmd args to self._cmd_args (accessable as self.cmd_args)
386
- """
387
- if self._cmd_args is not None:
388
- return
389
-
390
- # if it is not mindsdb run, then set args to empty
391
- if (
392
- (sys.modules['__main__'].__package__ or '').lower() != 'mindsdb'
393
- and os.environ.get('MINDSDB_RUNTIME') != "1"
394
- ):
395
- self._cmd_args = argparse.Namespace(
396
- api=None, config=None, install_handlers=None, verbose=False,
397
- no_studio=False, version=False, ml_task_queue_consumer=None,
398
- agent=None, project=None
399
- )
400
- return
401
-
402
- parser = argparse.ArgumentParser(description='CL argument for mindsdb server')
403
- parser.add_argument('--api', type=str, default=None)
404
- parser.add_argument('--config', type=str, default=None)
405
- parser.add_argument('--install-handlers', type=str, default=None)
406
- parser.add_argument('--verbose', action='store_true')
407
- parser.add_argument('--no_studio', action='store_true')
408
- parser.add_argument('-v', '--version', action='store_true')
409
- parser.add_argument('--ml_task_queue_consumer', action='store_true', default=None)
410
- parser.add_argument('--agent', type=str, default=None, help='Name of the agent to use with litellm APIs')
411
- parser.add_argument('--project', type=str, default=None, help='Project containing the agent (default: mindsdb)')
412
- self._cmd_args = parser.parse_args()
378
+ # region vars: a2a configuration
379
+ a2a_config = {}
380
+ if os.environ.get("MINDSDB_A2A_HOST"):
381
+ a2a_config["host"] = os.environ.get("MINDSDB_A2A_HOST")
382
+ if os.environ.get("MINDSDB_A2A_PORT"):
383
+ a2a_config["port"] = int(os.environ.get("MINDSDB_A2A_PORT"))
384
+ if os.environ.get("MINDSDB_HOST"):
385
+ a2a_config["mindsdb_host"] = os.environ.get("MINDSDB_HOST")
386
+ if os.environ.get("MINDSDB_PORT"):
387
+ a2a_config["mindsdb_port"] = int(os.environ.get("MINDSDB_PORT"))
388
+ if os.environ.get("MINDSDB_AGENT_NAME"):
389
+ a2a_config["agent_name"] = os.environ.get("MINDSDB_AGENT_NAME")
390
+ if os.environ.get("MINDSDB_PROJECT_NAME"):
391
+ a2a_config["project_name"] = os.environ.get("MINDSDB_PROJECT_NAME")
392
+
393
+ if a2a_config:
394
+ self._env_config["a2a"] = a2a_config
395
+ # endregion
413
396
 
414
397
  def fetch_auto_config(self) -> bool:
415
398
  """Load dict readed from config.auto.json to `auto_config`.
@@ -423,7 +406,9 @@ class Config:
423
406
  try:
424
407
  self._auto_config = json.loads(self.auto_config_path.read_text())
425
408
  except json.JSONDecodeError as e:
426
- raise ValueError(f"The 'auto' configuration file ({self.auto_config_path}) contains invalid JSON: {e}")
409
+ raise ValueError(
410
+ f"The 'auto' configuration file ({self.auto_config_path}) contains invalid JSON: {e}"
411
+ )
427
412
  self.auto_config_mtime = self.auto_config_path.stat().st_mtime
428
413
  return True
429
414
  return False
@@ -438,45 +423,102 @@ class Config:
438
423
  cmd_args_config = self.cmd_args.config
439
424
  if isinstance(cmd_args_config, str):
440
425
  self.config_path = cmd_args_config
441
- elif isinstance(os.environ.get('MINDSDB_CONFIG_PATH'), str):
442
- self.config_path = os.environ['MINDSDB_CONFIG_PATH']
443
- if self.config_path == 'absent':
426
+ elif isinstance(os.environ.get("MINDSDB_CONFIG_PATH"), str):
427
+ self.config_path = os.environ["MINDSDB_CONFIG_PATH"]
428
+ if self.config_path == "absent":
444
429
  self.config_path = None
445
430
  if isinstance(self.config_path, str):
446
431
  self.config_path = Path(self.config_path)
447
432
  if not self.config_path.is_file():
448
- raise FileNotFoundError(f'The configuration file was not found at the path: {self.config_path}')
433
+ raise FileNotFoundError(
434
+ f"The configuration file was not found at the path: {self.config_path}"
435
+ )
449
436
  try:
450
437
  self._user_config = json.loads(self.config_path.read_text())
451
438
  except json.JSONDecodeError as e:
452
- raise ValueError(f'The configuration file ({self.config_path}) contains invalid JSON: {e}')
439
+ raise ValueError(
440
+ f"The configuration file ({self.config_path}) contains invalid JSON: {e}"
441
+ )
453
442
  else:
454
443
  self._user_config = {}
455
444
  return True
456
445
  return False
457
446
 
458
447
  def ensure_auto_config_is_relevant(self) -> None:
459
- """Check if auto config has not been changed. If changed - reload main config.
460
- """
448
+ """Check if auto config has not been changed. If changed - reload main config."""
461
449
  updated = self.fetch_auto_config()
462
450
  if updated:
463
451
  self.merge_configs()
464
452
 
465
453
  def merge_configs(self) -> None:
466
- """Merge multiple configs to one.
467
- """
454
+ """Merge multiple configs to one."""
468
455
  new_config = deepcopy(self._default_config)
469
456
  _merge_configs(new_config, self._user_config)
470
457
  _merge_configs(new_config, self._auto_config)
471
458
  _merge_configs(new_config, self._env_config)
472
459
 
460
+ # Apply command-line arguments for A2A
461
+ cmd_args_config = {}
462
+
463
+ # Check for A2A command-line arguments
464
+ if hasattr(self.cmd_args, "a2a_host") and self.cmd_args.a2a_host is not None:
465
+ if "a2a" not in cmd_args_config:
466
+ cmd_args_config["a2a"] = {}
467
+ cmd_args_config["a2a"]["host"] = self.cmd_args.a2a_host
468
+
469
+ if hasattr(self.cmd_args, "a2a_port") and self.cmd_args.a2a_port is not None:
470
+ if "a2a" not in cmd_args_config:
471
+ cmd_args_config["a2a"] = {}
472
+ cmd_args_config["a2a"]["port"] = self.cmd_args.a2a_port
473
+
474
+ if (
475
+ hasattr(self.cmd_args, "mindsdb_host")
476
+ and self.cmd_args.mindsdb_host is not None
477
+ ):
478
+ if "a2a" not in cmd_args_config:
479
+ cmd_args_config["a2a"] = {}
480
+ cmd_args_config["a2a"]["mindsdb_host"] = self.cmd_args.mindsdb_host
481
+
482
+ if (
483
+ hasattr(self.cmd_args, "mindsdb_port")
484
+ and self.cmd_args.mindsdb_port is not None
485
+ ):
486
+ if "a2a" not in cmd_args_config:
487
+ cmd_args_config["a2a"] = {}
488
+ cmd_args_config["a2a"]["mindsdb_port"] = self.cmd_args.mindsdb_port
489
+
490
+ if (
491
+ hasattr(self.cmd_args, "agent_name")
492
+ and self.cmd_args.agent_name is not None
493
+ ):
494
+ if "a2a" not in cmd_args_config:
495
+ cmd_args_config["a2a"] = {}
496
+ cmd_args_config["a2a"]["agent_name"] = self.cmd_args.agent_name
497
+
498
+ if (
499
+ hasattr(self.cmd_args, "project_name")
500
+ and self.cmd_args.project_name is not None
501
+ ):
502
+ if "a2a" not in cmd_args_config:
503
+ cmd_args_config["a2a"] = {}
504
+ cmd_args_config["a2a"]["project_name"] = self.cmd_args.project_name
505
+
506
+ # Merge command-line args config with highest priority
507
+ if cmd_args_config:
508
+ _merge_configs(new_config, cmd_args_config)
509
+
510
+ # Ensure A2A port is never 0, which would prevent the A2A API from starting
511
+ if "a2a" in new_config and isinstance(new_config["a2a"], dict):
512
+ if "port" in new_config["a2a"] and (new_config["a2a"]["port"] == 0 or new_config["a2a"]["port"] is None):
513
+ new_config["a2a"]["port"] = 10002 # Use the default port value
514
+
473
515
  # region create dirs
474
- for key, value in new_config['paths'].items():
516
+ for key, value in new_config["paths"].items():
475
517
  if isinstance(value, str):
476
- new_config['paths'][key] = Path(value)
518
+ new_config["paths"][key] = Path(value)
477
519
  elif isinstance(value, Path) is False:
478
520
  raise ValueError(f"Unexpected path value: {value}")
479
- create_data_dir(new_config['paths'][key])
521
+ create_data_dir(new_config["paths"][key])
480
522
  # endregion
481
523
 
482
524
  self._config = new_config
@@ -494,39 +536,39 @@ class Config:
494
536
  return self._config
495
537
 
496
538
  def update(self, data: dict) -> None:
497
- """Update calues in `auto` config
498
- """
539
+ """Update calues in `auto` config"""
499
540
  self.ensure_auto_config_is_relevant()
500
541
 
501
542
  _merge_configs(self._auto_config, data)
502
543
 
503
- self.auto_config_path.write_text(
504
- json.dumps(self._auto_config, indent=4)
505
- )
544
+ self.auto_config_path.write_text(json.dumps(self._auto_config, indent=4))
506
545
 
507
546
  self.auto_config_mtime = self.auto_config_path.stat().st_mtime
508
547
 
509
548
  self.merge_configs()
510
549
 
511
550
  def raise_warnings(self, logger) -> None:
512
- """Show warnings about config options
513
- """
551
+ """Show warnings about config options"""
514
552
 
515
- if 'storage_dir' in self._config:
516
- logger.warning("The 'storage_dir' config option is no longer supported. Use 'paths.root' instead.")
553
+ if "storage_dir" in self._config:
554
+ logger.warning(
555
+ "The 'storage_dir' config option is no longer supported. Use 'paths.root' instead."
556
+ )
517
557
 
518
- if 'log' in self._config:
519
- logger.warning("The 'log' config option is no longer supported. Use 'logging' instead.")
558
+ if "log" in self._config:
559
+ logger.warning(
560
+ "The 'log' config option is no longer supported. Use 'logging' instead."
561
+ )
520
562
 
521
- if os.environ.get('MINDSDB_DEFAULT_SERVER', '') != '':
563
+ if os.environ.get("MINDSDB_DEFAULT_SERVER", "") != "":
522
564
  logger.warning(
523
565
  "Env variable 'MINDSDB_DEFAULT_SERVER' is going to be deprecated soon. "
524
566
  "Use 'MINDSDB_HTTP_SERVER_TYPE' instead."
525
567
  )
526
568
 
527
- for env_name in ('MINDSDB_HTTP_SERVER_TYPE', 'MINDSDB_DEFAULT_SERVER'):
528
- env_value = os.environ.get(env_name, '')
529
- if env_value.lower() not in ('waitress', 'flask', 'gunicorn', ''):
569
+ for env_name in ("MINDSDB_HTTP_SERVER_TYPE", "MINDSDB_DEFAULT_SERVER"):
570
+ env_value = os.environ.get(env_name, "")
571
+ if env_value.lower() not in ("waitress", "flask", "gunicorn", ""):
530
572
  logger.warning(
531
573
  f"The value '{env_value}' of the environment variable {env_name} is not valid. "
532
574
  "It must be one of the following: 'waitress', 'flask', or 'gunicorn'."
@@ -538,9 +580,79 @@ class Config:
538
580
  self.parse_cmd_args()
539
581
  return self._cmd_args
540
582
 
583
+ def parse_cmd_args(self) -> None:
584
+ """Collect cmd args to self._cmd_args (accessable as self.cmd_args)"""
585
+ if self._cmd_args is not None:
586
+ return
587
+
588
+ # if it is not mindsdb run, then set args to empty
589
+ if (
590
+ sys.modules["__main__"].__package__ or ""
591
+ ).lower() != "mindsdb" and os.environ.get("MINDSDB_RUNTIME") != "1":
592
+ self._cmd_args = argparse.Namespace(
593
+ api=None,
594
+ config=None,
595
+ install_handlers=None,
596
+ verbose=False,
597
+ no_studio=False,
598
+ version=False,
599
+ ml_task_queue_consumer=None,
600
+ agent=None,
601
+ project=None,
602
+ )
603
+ return
604
+
605
+ parser = argparse.ArgumentParser(description="CL argument for mindsdb server")
606
+ parser.add_argument("--api", type=str, default=None)
607
+ parser.add_argument("--config", type=str, default=None)
608
+ parser.add_argument("--install-handlers", type=str, default=None)
609
+ parser.add_argument("--verbose", action="store_true")
610
+ parser.add_argument("--no_studio", action="store_true")
611
+ parser.add_argument("-v", "--version", action="store_true")
612
+ parser.add_argument(
613
+ "--ml_task_queue_consumer", action="store_true", default=None
614
+ )
615
+ parser.add_argument(
616
+ "--agent",
617
+ type=str,
618
+ default=None,
619
+ help="Name of the agent to use with litellm APIs",
620
+ )
621
+ parser.add_argument(
622
+ "--project",
623
+ type=str,
624
+ default=None,
625
+ help="Project containing the agent (default: mindsdb)",
626
+ )
627
+
628
+ # A2A specific arguments
629
+ parser.add_argument(
630
+ "--a2a-host", type=str, default=None, help="A2A server host"
631
+ )
632
+ parser.add_argument(
633
+ "--a2a-port", type=int, default=None, help="A2A server port"
634
+ )
635
+ parser.add_argument(
636
+ "--mindsdb-host", type=str, default=None, help="MindsDB server host"
637
+ )
638
+ parser.add_argument(
639
+ "--mindsdb-port", type=int, default=None, help="MindsDB server port"
640
+ )
641
+ parser.add_argument(
642
+ "--agent-name",
643
+ type=str,
644
+ default=None,
645
+ help="MindsDB agent name to connect to",
646
+ )
647
+ parser.add_argument(
648
+ "--project-name", type=str, default=None, help="MindsDB project name"
649
+ )
650
+
651
+ self._cmd_args = parser.parse_args()
652
+
541
653
  @property
542
654
  def paths(self):
543
- return self._config['paths']
655
+ return self._config["paths"]
544
656
 
545
657
  @property
546
658
  def user_config(self):