MindsDB 25.5.4.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/api/a2a/__main__.py +38 -8
- mindsdb/api/a2a/run_a2a.py +10 -53
- mindsdb/api/a2a/task_manager.py +19 -53
- mindsdb/api/executor/command_executor.py +147 -291
- mindsdb/api/http/namespaces/config.py +61 -86
- mindsdb/integrations/handlers/byom_handler/requirements.txt +1 -2
- mindsdb/integrations/handlers/lancedb_handler/requirements.txt +0 -1
- mindsdb/integrations/handlers/litellm_handler/litellm_handler.py +37 -20
- mindsdb/integrations/libs/llm/config.py +13 -0
- mindsdb/integrations/libs/llm/utils.py +37 -65
- mindsdb/integrations/utilities/rag/rerankers/base_reranker.py +230 -227
- mindsdb/interfaces/agents/constants.py +17 -13
- mindsdb/interfaces/agents/langchain_agent.py +93 -94
- mindsdb/interfaces/knowledge_base/controller.py +230 -221
- mindsdb/utilities/config.py +43 -84
- {mindsdb-25.5.4.0.dist-info → mindsdb-25.5.4.1.dist-info}/METADATA +261 -259
- {mindsdb-25.5.4.0.dist-info → mindsdb-25.5.4.1.dist-info}/RECORD +21 -25
- mindsdb/api/a2a/a2a_client.py +0 -439
- mindsdb/api/a2a/common/client/__init__.py +0 -4
- mindsdb/api/a2a/common/client/card_resolver.py +0 -21
- mindsdb/api/a2a/common/client/client.py +0 -86
- {mindsdb-25.5.4.0.dist-info → mindsdb-25.5.4.1.dist-info}/WHEEL +0 -0
- {mindsdb-25.5.4.0.dist-info → mindsdb-25.5.4.1.dist-info}/licenses/LICENSE +0 -0
- {mindsdb-25.5.4.0.dist-info → mindsdb-25.5.4.1.dist-info}/top_level.txt +0 -0
mindsdb/__about__.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
__title__ =
|
|
2
|
-
__package_name__ =
|
|
3
|
-
__version__ =
|
|
1
|
+
__title__ = "MindsDB"
|
|
2
|
+
__package_name__ = "mindsdb"
|
|
3
|
+
__version__ = "25.5.4.1"
|
|
4
4
|
__description__ = "MindsDB's AI SQL Server enables developers to build AI tools that need access to real-time data to perform their tasks"
|
|
5
5
|
__email__ = "jorge@mindsdb.com"
|
|
6
|
-
__author__ =
|
|
7
|
-
__github__ =
|
|
8
|
-
__pypi__ =
|
|
9
|
-
__license__ =
|
|
10
|
-
__copyright__ =
|
|
6
|
+
__author__ = "MindsDB Inc"
|
|
7
|
+
__github__ = "https://github.com/mindsdb/mindsdb"
|
|
8
|
+
__pypi__ = "https://pypi.org/project/mindsdb/"
|
|
9
|
+
__license__ = "Elastic License 2.0"
|
|
10
|
+
__copyright__ = "Copyright(c) 2018 MindsDB, Inc"
|
mindsdb/api/a2a/__main__.py
CHANGED
|
@@ -4,15 +4,15 @@ import click
|
|
|
4
4
|
from dotenv import load_dotenv
|
|
5
5
|
|
|
6
6
|
# A2A specific imports
|
|
7
|
-
from .common.types import (
|
|
7
|
+
from mindsdb.api.a2a.common.types import (
|
|
8
8
|
AgentCard,
|
|
9
9
|
AgentCapabilities,
|
|
10
10
|
AgentSkill,
|
|
11
11
|
MissingAPIKeyError,
|
|
12
12
|
)
|
|
13
|
-
from .common.server.server import A2AServer
|
|
14
|
-
from .task_manager import AgentTaskManager
|
|
15
|
-
from .agent import MindsDBAgent
|
|
13
|
+
from mindsdb.api.a2a.common.server.server import A2AServer
|
|
14
|
+
from mindsdb.api.a2a.task_manager import AgentTaskManager
|
|
15
|
+
from mindsdb.api.a2a.agent import MindsDBAgent
|
|
16
16
|
|
|
17
17
|
logger = logging.getLogger(__name__)
|
|
18
18
|
logging.basicConfig(
|
|
@@ -73,10 +73,7 @@ def main(
|
|
|
73
73
|
|
|
74
74
|
agent_card = AgentCard(
|
|
75
75
|
name="MindsDB Agent Connector",
|
|
76
|
-
description=(
|
|
77
|
-
"A2A connector that proxies requests to MindsDB agents "
|
|
78
|
-
f"in project '{project_name}'."
|
|
79
|
-
),
|
|
76
|
+
description=(f"A2A connector that proxies requests to MindsDB agents in project '{project_name}'."),
|
|
80
77
|
url=f"http://{host}:{port}",
|
|
81
78
|
version="1.0.0",
|
|
82
79
|
defaultInputModes=MindsDBAgent.SUPPORTED_CONTENT_TYPES,
|
|
@@ -110,5 +107,38 @@ def main(
|
|
|
110
107
|
sys.exit(1)
|
|
111
108
|
|
|
112
109
|
|
|
110
|
+
# This function is called by mindsdb/api/a2a/run_a2a.py
|
|
111
|
+
def main_with_config(config=None, *args, **kwargs):
|
|
112
|
+
"""
|
|
113
|
+
Alternative entry point that accepts configuration as a dictionary.
|
|
114
|
+
This is used when A2A is started as a subprocess of the main MindsDB process.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
config (dict): Configuration dictionary
|
|
118
|
+
args: Additional positional arguments
|
|
119
|
+
kwargs: Additional keyword arguments
|
|
120
|
+
"""
|
|
121
|
+
if config is None:
|
|
122
|
+
config = {}
|
|
123
|
+
|
|
124
|
+
# Extract configuration values with fallbacks to default values
|
|
125
|
+
host = config.get("host", "localhost")
|
|
126
|
+
port = int(config.get("port", 47338))
|
|
127
|
+
mindsdb_host = config.get("mindsdb_host", "localhost")
|
|
128
|
+
mindsdb_port = int(config.get("mindsdb_port", 47334))
|
|
129
|
+
project_name = config.get("project_name", "mindsdb")
|
|
130
|
+
log_level = config.get("log_level", "INFO")
|
|
131
|
+
|
|
132
|
+
# Call the main function with the extracted configuration
|
|
133
|
+
main.callback(
|
|
134
|
+
host=host,
|
|
135
|
+
port=port,
|
|
136
|
+
mindsdb_host=mindsdb_host,
|
|
137
|
+
mindsdb_port=mindsdb_port,
|
|
138
|
+
project_name=project_name,
|
|
139
|
+
log_level=log_level,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
113
143
|
if __name__ == "__main__":
|
|
114
144
|
main()
|
mindsdb/api/a2a/run_a2a.py
CHANGED
|
@@ -6,9 +6,7 @@ from dotenv import load_dotenv
|
|
|
6
6
|
from typing import Dict, Any, Optional
|
|
7
7
|
|
|
8
8
|
# Configure logging
|
|
9
|
-
logging.basicConfig(
|
|
10
|
-
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
|
11
|
-
)
|
|
9
|
+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
|
12
10
|
logger = logging.getLogger(__name__)
|
|
13
11
|
|
|
14
12
|
|
|
@@ -22,9 +20,7 @@ def setup_python_path():
|
|
|
22
20
|
this_file_dir = os.path.dirname(os.path.abspath(__file__))
|
|
23
21
|
|
|
24
22
|
# Walk three levels up: a2a/ -> api/ -> mindsdb/ -> <repo_root>
|
|
25
|
-
repo_root = os.path.abspath(
|
|
26
|
-
os.path.join(this_file_dir, os.pardir, os.pardir, os.pardir)
|
|
27
|
-
)
|
|
23
|
+
repo_root = os.path.abspath(os.path.join(this_file_dir, os.pardir, os.pardir, os.pardir))
|
|
28
24
|
|
|
29
25
|
# Prepend to PYTHONPATH if not already present
|
|
30
26
|
if repo_root not in sys.path:
|
|
@@ -54,65 +50,26 @@ def main(config_override: Optional[Dict[str, Any]] = None, *args, **kwargs):
|
|
|
54
50
|
load_dotenv()
|
|
55
51
|
|
|
56
52
|
try:
|
|
57
|
-
# Import the
|
|
58
|
-
from mindsdb.api.a2a.__main__ import
|
|
53
|
+
# Import the main_with_config function from __main__.py
|
|
54
|
+
from mindsdb.api.a2a.__main__ import main_with_config
|
|
59
55
|
from mindsdb.utilities.config import config
|
|
60
56
|
|
|
61
57
|
logger.info("Successfully imported a2a module")
|
|
62
58
|
|
|
63
59
|
# Get configuration from config system or use provided override
|
|
64
|
-
a2a_config = config_override if config_override is not None else config.get(
|
|
60
|
+
a2a_config = config_override if config_override is not None else config.get("a2a", {})
|
|
65
61
|
|
|
66
62
|
# Set log level if specified
|
|
67
|
-
if a2a_config.get(
|
|
68
|
-
log_level = getattr(logging, a2a_config[
|
|
63
|
+
if a2a_config.get("log_level"):
|
|
64
|
+
log_level = getattr(logging, a2a_config["log_level"].upper(), None)
|
|
69
65
|
if log_level:
|
|
70
66
|
logger.setLevel(log_level)
|
|
71
67
|
logger.info(f"Set log level to {a2a_config['log_level'].upper()}")
|
|
72
68
|
|
|
73
|
-
|
|
74
|
-
sys_argv = [] # Start with an empty list instead of copying sys.argv
|
|
69
|
+
logger.info(f"Starting A2A with configuration: {a2a_config}")
|
|
75
70
|
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
sys_argv.extend(['--host', a2a_config['host']])
|
|
79
|
-
|
|
80
|
-
if a2a_config.get('port'):
|
|
81
|
-
sys_argv.extend(['--port', str(a2a_config['port'])])
|
|
82
|
-
|
|
83
|
-
if a2a_config.get('mindsdb_host'):
|
|
84
|
-
sys_argv.extend(['--mindsdb-host', a2a_config['mindsdb_host']])
|
|
85
|
-
|
|
86
|
-
if a2a_config.get('mindsdb_port'):
|
|
87
|
-
sys_argv.extend(['--mindsdb-port', str(a2a_config['mindsdb_port'])])
|
|
88
|
-
|
|
89
|
-
if a2a_config.get('project_name'):
|
|
90
|
-
sys_argv.extend(['--project-name', a2a_config['project_name']])
|
|
91
|
-
|
|
92
|
-
if a2a_config.get('log_level'):
|
|
93
|
-
sys_argv.extend(['--log-level', a2a_config['log_level']])
|
|
94
|
-
|
|
95
|
-
logger.info(f"Starting A2A with arguments: {' '.join(sys_argv)}")
|
|
96
|
-
|
|
97
|
-
# Temporarily replace sys.argv with our constructed arguments
|
|
98
|
-
original_argv = sys.argv
|
|
99
|
-
sys.argv = [sys.argv[0]] + sys_argv
|
|
100
|
-
|
|
101
|
-
# Run the main function with the configured arguments
|
|
102
|
-
a2a_args = []
|
|
103
|
-
for arg in sys_argv:
|
|
104
|
-
# Skip the --api argument and its value
|
|
105
|
-
if arg.startswith('--api=') or arg == '--api':
|
|
106
|
-
continue
|
|
107
|
-
# Skip the value of --api if the previous arg was --api
|
|
108
|
-
if arg.startswith('--') and sys_argv[sys_argv.index(arg) - 1] == '--api':
|
|
109
|
-
continue
|
|
110
|
-
a2a_args.append(arg)
|
|
111
|
-
|
|
112
|
-
a2a_main(a2a_args)
|
|
113
|
-
|
|
114
|
-
# Restore original sys.argv
|
|
115
|
-
sys.argv = original_argv
|
|
71
|
+
# Call the main_with_config function with the configuration
|
|
72
|
+
main_with_config(a2a_config, *args, **kwargs)
|
|
116
73
|
|
|
117
74
|
except ImportError as e:
|
|
118
75
|
logger.error(f"Error importing a2a module: {e}")
|
mindsdb/api/a2a/task_manager.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from typing import AsyncIterable
|
|
2
|
-
from .common.types import (
|
|
2
|
+
from mindsdb.api.a2a.common.types import (
|
|
3
3
|
SendTaskRequest,
|
|
4
4
|
TaskSendParams,
|
|
5
5
|
Message,
|
|
@@ -16,8 +16,8 @@ from .common.types import (
|
|
|
16
16
|
SendTaskStreamingResponse,
|
|
17
17
|
InvalidRequestError,
|
|
18
18
|
)
|
|
19
|
-
from .common.server.task_manager import InMemoryTaskManager
|
|
20
|
-
from .agent import MindsDBAgent
|
|
19
|
+
from mindsdb.api.a2a.common.server.task_manager import InMemoryTaskManager
|
|
20
|
+
from mindsdb.api.a2a.agent import MindsDBAgent
|
|
21
21
|
|
|
22
22
|
from typing import Union
|
|
23
23
|
import logging
|
|
@@ -27,7 +27,6 @@ logger = logging.getLogger(__name__)
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
class AgentTaskManager(InMemoryTaskManager):
|
|
30
|
-
|
|
31
30
|
def __init__(
|
|
32
31
|
self,
|
|
33
32
|
project_name: str,
|
|
@@ -46,9 +45,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
46
45
|
def _create_agent(self, agent_name: str = None) -> MindsDBAgent:
|
|
47
46
|
"""Create a new MindsDBAgent instance for the given agent name."""
|
|
48
47
|
if not agent_name:
|
|
49
|
-
raise ValueError(
|
|
50
|
-
"Agent name is required but was not provided in the request"
|
|
51
|
-
)
|
|
48
|
+
raise ValueError("Agent name is required but was not provided in the request")
|
|
52
49
|
|
|
53
50
|
return MindsDBAgent(
|
|
54
51
|
agent_name=agent_name,
|
|
@@ -57,9 +54,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
57
54
|
port=self.mindsdb_port,
|
|
58
55
|
)
|
|
59
56
|
|
|
60
|
-
async def _stream_generator(
|
|
61
|
-
self, request: SendTaskStreamingRequest
|
|
62
|
-
) -> AsyncIterable[SendTaskStreamingResponse]:
|
|
57
|
+
async def _stream_generator(self, request: SendTaskStreamingRequest) -> AsyncIterable[SendTaskStreamingResponse]:
|
|
63
58
|
task_send_params: TaskSendParams = request.params
|
|
64
59
|
query = self._get_user_query(task_send_params)
|
|
65
60
|
params = self._get_task_params(task_send_params)
|
|
@@ -112,9 +107,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
112
107
|
# Yield the artifact update
|
|
113
108
|
yield SendTaskStreamingResponse(
|
|
114
109
|
id=request.id,
|
|
115
|
-
result=TaskArtifactUpdateEvent(
|
|
116
|
-
id=task_send_params.id, artifact=artifact
|
|
117
|
-
),
|
|
110
|
+
result=TaskArtifactUpdateEvent(id=task_send_params.id, artifact=artifact),
|
|
118
111
|
)
|
|
119
112
|
|
|
120
113
|
# Yield the final status update
|
|
@@ -169,9 +162,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
169
162
|
# Include SQL queries
|
|
170
163
|
tool_input = action.get("tool_input", "")
|
|
171
164
|
if "$START$" in tool_input and "$STOP$" in tool_input:
|
|
172
|
-
sql = tool_input.replace("$START$", "").replace(
|
|
173
|
-
"$STOP$", ""
|
|
174
|
-
)
|
|
165
|
+
sql = tool_input.replace("$START$", "").replace("$STOP$", "")
|
|
175
166
|
parts.append(
|
|
176
167
|
{
|
|
177
168
|
"type": "text",
|
|
@@ -227,17 +218,13 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
227
218
|
if "metadata" in part:
|
|
228
219
|
new_part["metadata"] = part["metadata"]
|
|
229
220
|
else:
|
|
230
|
-
new_part["metadata"] = {
|
|
231
|
-
"thought_type": part.get("type", "text")
|
|
232
|
-
}
|
|
221
|
+
new_part["metadata"] = {"thought_type": part.get("type", "text")}
|
|
233
222
|
|
|
234
223
|
parts.append(new_part)
|
|
235
224
|
|
|
236
225
|
# Try to determine the type from parts for the thought dictionary
|
|
237
226
|
for part in item["parts"]:
|
|
238
|
-
if part.get("type") == "text" and part.get(
|
|
239
|
-
"text", ""
|
|
240
|
-
).startswith("$START$"):
|
|
227
|
+
if part.get("type") == "text" and part.get("text", "").startswith("$START$"):
|
|
241
228
|
thought_dict["type"] = "sql"
|
|
242
229
|
thought_dict["query"] = part.get("text")
|
|
243
230
|
else:
|
|
@@ -300,9 +287,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
300
287
|
status=task_status,
|
|
301
288
|
final=False,
|
|
302
289
|
)
|
|
303
|
-
yield SendTaskStreamingResponse(
|
|
304
|
-
id=request.id, result=task_update_event
|
|
305
|
-
)
|
|
290
|
+
yield SendTaskStreamingResponse(id=request.id, result=task_update_event)
|
|
306
291
|
|
|
307
292
|
# If this is the final chunk, send a completion message
|
|
308
293
|
if is_task_complete:
|
|
@@ -311,13 +296,9 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
311
296
|
task_status = TaskStatus(state=task_state)
|
|
312
297
|
yield SendTaskStreamingResponse(
|
|
313
298
|
id=request.id,
|
|
314
|
-
result=TaskArtifactUpdateEvent(
|
|
315
|
-
id=task_send_params.id, artifact=artifact
|
|
316
|
-
),
|
|
317
|
-
)
|
|
318
|
-
await self._update_store(
|
|
319
|
-
task_send_params.id, task_status, [artifact]
|
|
299
|
+
result=TaskArtifactUpdateEvent(id=task_send_params.id, artifact=artifact),
|
|
320
300
|
)
|
|
301
|
+
await self._update_store(task_send_params.id, task_status, [artifact])
|
|
321
302
|
yield SendTaskStreamingResponse(
|
|
322
303
|
id=request.id,
|
|
323
304
|
result=TaskStatusUpdateEvent(
|
|
@@ -338,9 +319,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
338
319
|
artifact = Artifact(parts=parts, index=0, append=False)
|
|
339
320
|
yield SendTaskStreamingResponse(
|
|
340
321
|
id=request.id,
|
|
341
|
-
result=TaskArtifactUpdateEvent(
|
|
342
|
-
id=task_send_params.id, artifact=artifact
|
|
343
|
-
),
|
|
322
|
+
result=TaskArtifactUpdateEvent(id=task_send_params.id, artifact=artifact),
|
|
344
323
|
)
|
|
345
324
|
|
|
346
325
|
# Then mark the task as completed with an error
|
|
@@ -415,10 +394,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
415
394
|
)
|
|
416
395
|
|
|
417
396
|
# Check if the message has metadata
|
|
418
|
-
if (
|
|
419
|
-
not hasattr(request.params.message, "metadata")
|
|
420
|
-
or not request.params.message.metadata
|
|
421
|
-
):
|
|
397
|
+
if not hasattr(request.params.message, "metadata") or not request.params.message.metadata:
|
|
422
398
|
return JSONRPCResponse(
|
|
423
399
|
id=request.id,
|
|
424
400
|
error=InvalidRequestError(message="Missing metadata in message"),
|
|
@@ -462,14 +438,10 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
462
438
|
logger.error(f"Error in on_send_task_subscribe: {str(e)}")
|
|
463
439
|
yield SendTaskStreamingResponse(
|
|
464
440
|
id=request.id,
|
|
465
|
-
error=InternalError(
|
|
466
|
-
message=f"Error processing streaming request: {str(e)}"
|
|
467
|
-
),
|
|
441
|
+
error=InternalError(message=f"Error processing streaming request: {str(e)}"),
|
|
468
442
|
)
|
|
469
443
|
|
|
470
|
-
async def _update_store(
|
|
471
|
-
self, task_id: str, status: TaskStatus, artifacts: list[Artifact]
|
|
472
|
-
) -> Task:
|
|
444
|
+
async def _update_store(self, task_id: str, status: TaskStatus, artifacts: list[Artifact]) -> Task:
|
|
473
445
|
async with self.lock:
|
|
474
446
|
try:
|
|
475
447
|
task = self.tasks[task_id]
|
|
@@ -544,9 +516,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
544
516
|
# For streaming mode, we'll use the streaming endpoint instead
|
|
545
517
|
# Just create a minimal response to acknowledge the request
|
|
546
518
|
task_state = TaskState.WORKING
|
|
547
|
-
task = await self._update_store(
|
|
548
|
-
task_send_params.id, TaskStatus(state=task_state), []
|
|
549
|
-
)
|
|
519
|
+
task = await self._update_store(task_send_params.id, TaskStatus(state=task_state), [])
|
|
550
520
|
return SendTaskResponse(id=request.id, result=task)
|
|
551
521
|
else:
|
|
552
522
|
# For non-streaming mode, collect all chunks into a single response
|
|
@@ -571,9 +541,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
571
541
|
task_send_params.id,
|
|
572
542
|
TaskStatus(
|
|
573
543
|
state=task_state,
|
|
574
|
-
message=Message(
|
|
575
|
-
role="agent", parts=all_parts, metadata=final_metadata
|
|
576
|
-
),
|
|
544
|
+
message=Message(role="agent", parts=all_parts, metadata=final_metadata),
|
|
577
545
|
),
|
|
578
546
|
[Artifact(parts=all_parts)],
|
|
579
547
|
)
|
|
@@ -586,9 +554,7 @@ class AgentTaskManager(InMemoryTaskManager):
|
|
|
586
554
|
task_state = TaskState.FAILED
|
|
587
555
|
task = await self._update_store(
|
|
588
556
|
task_send_params.id,
|
|
589
|
-
TaskStatus(
|
|
590
|
-
state=task_state, message=Message(role="agent", parts=parts)
|
|
591
|
-
),
|
|
557
|
+
TaskStatus(state=task_state, message=Message(role="agent", parts=parts)),
|
|
592
558
|
[Artifact(parts=parts)],
|
|
593
559
|
)
|
|
594
560
|
return SendTaskResponse(id=request.id, result=task)
|