datarobot-genai 0.2.29__py3-none-any.whl → 0.2.37__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.
- datarobot_genai/core/cli/agent_kernel.py +4 -1
- datarobot_genai/drmcp/__init__.py +2 -2
- datarobot_genai/drmcp/core/exceptions.py +0 -4
- datarobot_genai/drmcp/core/logging.py +2 -2
- datarobot_genai/drmcp/test_utils/clients/__init__.py +0 -0
- datarobot_genai/drmcp/test_utils/clients/anthropic.py +68 -0
- datarobot_genai/drmcp/test_utils/{openai_llm_mcp_client.py → clients/base.py} +38 -40
- datarobot_genai/drmcp/test_utils/clients/dr_gateway.py +58 -0
- datarobot_genai/drmcp/test_utils/clients/openai.py +68 -0
- datarobot_genai/drmcp/test_utils/mcp_utils_ete.py +20 -0
- datarobot_genai/drmcp/test_utils/test_interactive.py +16 -16
- datarobot_genai/drmcp/test_utils/tool_base_ete.py +1 -1
- datarobot_genai/drmcp/test_utils/utils.py +1 -1
- datarobot_genai/drmcp/tools/clients/gdrive.py +187 -1
- datarobot_genai/drmcp/tools/clients/microsoft_graph.py +126 -0
- datarobot_genai/drmcp/tools/gdrive/tools.py +186 -10
- datarobot_genai/drmcp/tools/microsoft_graph/tools.py +79 -0
- datarobot_genai/drmcp/tools/predictive/data.py +5 -5
- datarobot_genai/drmcp/tools/predictive/deployment.py +52 -46
- datarobot_genai/drmcp/tools/predictive/model.py +87 -52
- datarobot_genai/drmcp/tools/predictive/project.py +2 -2
- datarobot_genai/drmcp/tools/predictive/training.py +52 -24
- {datarobot_genai-0.2.29.dist-info → datarobot_genai-0.2.37.dist-info}/METADATA +1 -1
- {datarobot_genai-0.2.29.dist-info → datarobot_genai-0.2.37.dist-info}/RECORD +28 -24
- {datarobot_genai-0.2.29.dist-info → datarobot_genai-0.2.37.dist-info}/WHEEL +0 -0
- {datarobot_genai-0.2.29.dist-info → datarobot_genai-0.2.37.dist-info}/entry_points.txt +0 -0
- {datarobot_genai-0.2.29.dist-info → datarobot_genai-0.2.37.dist-info}/licenses/AUTHORS +0 -0
- {datarobot_genai-0.2.29.dist-info → datarobot_genai-0.2.37.dist-info}/licenses/LICENSE +0 -0
|
@@ -107,7 +107,10 @@ class AgentKernel:
|
|
|
107
107
|
stream: bool = False,
|
|
108
108
|
config: Any | None = None,
|
|
109
109
|
) -> ChatCompletion | Stream[ChatCompletionChunk]:
|
|
110
|
-
|
|
110
|
+
if config is not None:
|
|
111
|
+
chat_api_url = f"http://localhost:{config.local_dev_port}"
|
|
112
|
+
else:
|
|
113
|
+
chat_api_url = self.base_url
|
|
111
114
|
print(chat_api_url)
|
|
112
115
|
|
|
113
116
|
return self._do_chat_completion(chat_api_url, user_prompt, completion_json, stream=stream)
|
|
@@ -19,11 +19,11 @@ A reusable library for building Model Context Protocol (MCP) servers with DataRo
|
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
# Export main server components
|
|
22
|
+
from datarobot_genai.drmcp.test_utils.clients.openai import OpenAILLMMCPClient
|
|
22
23
|
from datarobot_genai.drmcp.test_utils.mcp_utils_ete import ete_test_mcp_session
|
|
23
24
|
from datarobot_genai.drmcp.test_utils.mcp_utils_ete import get_dr_mcp_server_url
|
|
24
25
|
from datarobot_genai.drmcp.test_utils.mcp_utils_ete import get_headers
|
|
25
26
|
from datarobot_genai.drmcp.test_utils.mcp_utils_integration import integration_test_mcp_session
|
|
26
|
-
from datarobot_genai.drmcp.test_utils.openai_llm_mcp_client import LLMMCPClient
|
|
27
27
|
from datarobot_genai.drmcp.test_utils.tool_base_ete import ETETestExpectations
|
|
28
28
|
from datarobot_genai.drmcp.test_utils.tool_base_ete import ToolBaseE2E
|
|
29
29
|
from datarobot_genai.drmcp.test_utils.tool_base_ete import ToolCallTestExpectations
|
|
@@ -70,7 +70,7 @@ __all__ = [
|
|
|
70
70
|
"get_dr_mcp_server_url",
|
|
71
71
|
"get_headers",
|
|
72
72
|
"ete_test_mcp_session",
|
|
73
|
-
"
|
|
73
|
+
"OpenAILLMMCPClient",
|
|
74
74
|
"ETETestExpectations",
|
|
75
75
|
"ToolBaseE2E",
|
|
76
76
|
"ToolCallTestExpectations",
|
|
@@ -20,7 +20,7 @@ from collections.abc import Callable
|
|
|
20
20
|
from typing import Any
|
|
21
21
|
from typing import TypeVar
|
|
22
22
|
|
|
23
|
-
from .exceptions import
|
|
23
|
+
from fastmcp.exceptions import ToolError
|
|
24
24
|
|
|
25
25
|
# Secret patterns to redact from logs
|
|
26
26
|
SECRET_PATTERNS = [
|
|
@@ -93,6 +93,6 @@ def log_execution(func: F) -> F:
|
|
|
93
93
|
return result
|
|
94
94
|
except Exception as e:
|
|
95
95
|
error_msg = _log_error(logger, func.__name__, e, args=args, kwargs=kwargs)
|
|
96
|
-
raise
|
|
96
|
+
raise ToolError(error_msg)
|
|
97
97
|
|
|
98
98
|
return wrapper # type: ignore[return-value]
|
|
File without changes
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Copyright 2026 DataRobot, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""Anthropic LLM MCP Client implementation (example).
|
|
16
|
+
|
|
17
|
+
This is an example implementation showing how easy it is to add a new LLM provider.
|
|
18
|
+
Anthropic's API is OpenAI-compatible, so we can use the OpenAI SDK with their endpoint.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import openai
|
|
22
|
+
|
|
23
|
+
from .base import BaseLLMMCPClient
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class AnthropicMCPClient(BaseLLMMCPClient):
|
|
27
|
+
"""
|
|
28
|
+
Client for interacting with LLMs via MCP using Anthropic Claude.
|
|
29
|
+
|
|
30
|
+
Note: Elicitation is handled at the protocol level by FastMCP's ctx.elicit().
|
|
31
|
+
Tools using FastMCP's built-in elicitation will work automatically.
|
|
32
|
+
|
|
33
|
+
Example:
|
|
34
|
+
```python
|
|
35
|
+
config = {
|
|
36
|
+
"anthropic_api_key": "sk-ant-...",
|
|
37
|
+
"model": "claude-3-5-sonnet-20241022",
|
|
38
|
+
}
|
|
39
|
+
client = AnthropicMCPClient(str(config))
|
|
40
|
+
```
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
config: str | dict,
|
|
46
|
+
):
|
|
47
|
+
"""
|
|
48
|
+
Initialize the LLM MCP client.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
config: Configuration string or dict with:
|
|
52
|
+
- anthropic_api_key: Anthropic API key
|
|
53
|
+
- model: Model name (default: "claude-3-5-sonnet-20241022")
|
|
54
|
+
- save_llm_responses: Whether to save responses (default: True)
|
|
55
|
+
"""
|
|
56
|
+
super().__init__(config)
|
|
57
|
+
|
|
58
|
+
def _create_llm_client(self, config_dict: dict) -> tuple[openai.OpenAI, str]:
|
|
59
|
+
"""Create the LLM client for Anthropic (OpenAI-compatible endpoint)."""
|
|
60
|
+
anthropic_api_key = config_dict.get("anthropic_api_key")
|
|
61
|
+
model = config_dict.get("model", "claude-3-5-sonnet-20241022")
|
|
62
|
+
|
|
63
|
+
# Anthropic provides an OpenAI-compatible endpoint
|
|
64
|
+
client = openai.OpenAI(
|
|
65
|
+
api_key=anthropic_api_key,
|
|
66
|
+
base_url="https://api.anthropic.com/v1",
|
|
67
|
+
)
|
|
68
|
+
return client, model
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2026 DataRobot, Inc.
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -12,7 +12,11 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
"""Base classes for LLM MCP clients."""
|
|
16
|
+
|
|
15
17
|
import json
|
|
18
|
+
from abc import ABC
|
|
19
|
+
from abc import abstractmethod
|
|
16
20
|
from ast import literal_eval
|
|
17
21
|
from typing import Any
|
|
18
22
|
|
|
@@ -23,7 +27,7 @@ from mcp.types import ListToolsResult
|
|
|
23
27
|
from mcp.types import TextContent
|
|
24
28
|
from openai.types.chat.chat_completion import ChatCompletion
|
|
25
29
|
|
|
26
|
-
from .utils import save_response_to_file
|
|
30
|
+
from datarobot_genai.drmcp.test_utils.utils import save_response_to_file
|
|
27
31
|
|
|
28
32
|
|
|
29
33
|
class ToolCall:
|
|
@@ -44,9 +48,9 @@ class LLMResponse:
|
|
|
44
48
|
self.tool_results = tool_results
|
|
45
49
|
|
|
46
50
|
|
|
47
|
-
class
|
|
51
|
+
class BaseLLMMCPClient(ABC):
|
|
48
52
|
"""
|
|
49
|
-
|
|
53
|
+
Base class for LLM MCP clients.
|
|
50
54
|
|
|
51
55
|
Note: Elicitation is handled at the protocol level by FastMCP's ctx.elicit().
|
|
52
56
|
Tools using FastMCP's built-in elicitation will work automatically.
|
|
@@ -54,54 +58,48 @@ class LLMMCPClient:
|
|
|
54
58
|
|
|
55
59
|
def __init__(
|
|
56
60
|
self,
|
|
57
|
-
config: str,
|
|
61
|
+
config: str | dict,
|
|
58
62
|
):
|
|
59
63
|
"""
|
|
60
64
|
Initialize the LLM MCP client.
|
|
61
65
|
|
|
62
66
|
Args:
|
|
63
|
-
config: Configuration string or dict with
|
|
64
|
-
- openai_api_key: OpenAI API key
|
|
65
|
-
- openai_api_base: Optional Azure OpenAI endpoint
|
|
66
|
-
- openai_api_deployment_id: Optional Azure deployment ID
|
|
67
|
-
- openai_api_version: Optional Azure API version
|
|
68
|
-
- model: Model name (default: "gpt-3.5-turbo")
|
|
69
|
-
- save_llm_responses: Whether to save responses (default: True)
|
|
67
|
+
config: Configuration string or dict with provider-specific keys.
|
|
70
68
|
"""
|
|
71
|
-
|
|
69
|
+
config_dict = self._parse_config(config)
|
|
70
|
+
self.openai_client, self.model = self._create_llm_client(config_dict)
|
|
71
|
+
self.save_llm_responses = config_dict.get("save_llm_responses", True)
|
|
72
|
+
self.available_tools: list[dict[str, Any]] = []
|
|
73
|
+
self.available_prompts: list[dict[str, Any]] = []
|
|
74
|
+
self.available_resources: list[dict[str, Any]] = []
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def _parse_config(config: str | dict) -> dict:
|
|
78
|
+
"""Parse config string to dict."""
|
|
72
79
|
if isinstance(config, str):
|
|
73
80
|
# Try JSON first (safer), fall back to literal_eval for Python dict strings
|
|
74
81
|
try:
|
|
75
|
-
|
|
82
|
+
return json.loads(config)
|
|
76
83
|
except json.JSONDecodeError:
|
|
77
84
|
# Fall back to literal_eval for Python dict literal strings
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
config_dict = config
|
|
81
|
-
|
|
82
|
-
openai_api_key = config_dict.get("openai_api_key")
|
|
83
|
-
openai_api_base = config_dict.get("openai_api_base")
|
|
84
|
-
openai_api_deployment_id = config_dict.get("openai_api_deployment_id")
|
|
85
|
-
model = config_dict.get("model", "gpt-3.5-turbo")
|
|
86
|
-
save_llm_responses = config_dict.get("save_llm_responses", True)
|
|
87
|
-
|
|
88
|
-
if openai_api_base and openai_api_deployment_id:
|
|
89
|
-
# Azure OpenAI
|
|
90
|
-
self.openai_client = openai.AzureOpenAI(
|
|
91
|
-
api_key=openai_api_key,
|
|
92
|
-
azure_endpoint=openai_api_base,
|
|
93
|
-
api_version=config_dict.get("openai_api_version", "2024-02-15-preview"),
|
|
94
|
-
)
|
|
95
|
-
self.model = openai_api_deployment_id
|
|
96
|
-
else:
|
|
97
|
-
# Regular OpenAI
|
|
98
|
-
self.openai_client = openai.OpenAI(api_key=openai_api_key) # type: ignore[assignment]
|
|
99
|
-
self.model = model
|
|
85
|
+
return literal_eval(config)
|
|
86
|
+
return config
|
|
100
87
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
self
|
|
104
|
-
|
|
88
|
+
@abstractmethod
|
|
89
|
+
def _create_llm_client(
|
|
90
|
+
self, config_dict: dict
|
|
91
|
+
) -> tuple[openai.OpenAI | openai.AzureOpenAI, str]:
|
|
92
|
+
"""
|
|
93
|
+
Create the LLM client.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
config_dict: Parsed configuration dictionary
|
|
97
|
+
|
|
98
|
+
Returns
|
|
99
|
+
-------
|
|
100
|
+
Tuple of (LLM client instance, model name)
|
|
101
|
+
"""
|
|
102
|
+
pass
|
|
105
103
|
|
|
106
104
|
async def _add_mcp_tool_to_available_tools(self, mcp_session: ClientSession) -> None:
|
|
107
105
|
"""Add a tool to the available tools."""
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Copyright 2026 DataRobot, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""DataRobot LLM Gateway MCP Client implementation."""
|
|
16
|
+
|
|
17
|
+
import openai
|
|
18
|
+
|
|
19
|
+
from .base import BaseLLMMCPClient
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DRLLMGatewayMCPClient(BaseLLMMCPClient):
|
|
23
|
+
"""
|
|
24
|
+
Client for interacting with LLMs via MCP using DataRobot LLM Gateway.
|
|
25
|
+
|
|
26
|
+
Note: Elicitation is handled at the protocol level by FastMCP's ctx.elicit().
|
|
27
|
+
Tools using FastMCP's built-in elicitation will work automatically.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
config: str | dict,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Initialize the LLM MCP client.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
config: Configuration string or dict with:
|
|
39
|
+
- datarobot_api_token: DataRobot API token
|
|
40
|
+
- datarobot_endpoint: DataRobot endpoint URL (default: "https://app.datarobot.com/api/v2")
|
|
41
|
+
- model: Model name (default: "gpt-4o-mini")
|
|
42
|
+
- save_llm_responses: Whether to save responses (default: True)
|
|
43
|
+
"""
|
|
44
|
+
super().__init__(config)
|
|
45
|
+
|
|
46
|
+
def _create_llm_client(self, config_dict: dict) -> tuple[openai.OpenAI, str]:
|
|
47
|
+
"""Create the LLM client for DataRobot LLM Gateway."""
|
|
48
|
+
datarobot_api_token = config_dict.get("datarobot_api_token")
|
|
49
|
+
datarobot_endpoint = config_dict.get(
|
|
50
|
+
"datarobot_endpoint", "https://app.datarobot.com/api/v2"
|
|
51
|
+
)
|
|
52
|
+
model = config_dict.get("model", "gpt-4o-mini")
|
|
53
|
+
|
|
54
|
+
# Build gateway URL: {endpoint}/genai/llmgw
|
|
55
|
+
gateway_url = datarobot_endpoint.rstrip("/") + "/genai/llmgw"
|
|
56
|
+
|
|
57
|
+
client = openai.OpenAI(api_key=datarobot_api_token, base_url=gateway_url)
|
|
58
|
+
return client, model
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Copyright 2026 DataRobot, Inc.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
"""OpenAI LLM MCP Client implementation."""
|
|
16
|
+
|
|
17
|
+
import openai
|
|
18
|
+
|
|
19
|
+
from .base import BaseLLMMCPClient
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class OpenAILLMMCPClient(BaseLLMMCPClient):
|
|
23
|
+
"""
|
|
24
|
+
Client for interacting with LLMs via MCP using OpenAI or Azure OpenAI.
|
|
25
|
+
|
|
26
|
+
Note: Elicitation is handled at the protocol level by FastMCP's ctx.elicit().
|
|
27
|
+
Tools using FastMCP's built-in elicitation will work automatically.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(
|
|
31
|
+
self,
|
|
32
|
+
config: str | dict,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Initialize the LLM MCP client.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
config: Configuration string or dict with:
|
|
39
|
+
- openai_api_key: OpenAI API key
|
|
40
|
+
- openai_api_base: Optional Azure OpenAI endpoint
|
|
41
|
+
- openai_api_deployment_id: Optional Azure deployment ID
|
|
42
|
+
- openai_api_version: Optional Azure API version
|
|
43
|
+
- model: Model name (default: "gpt-3.5-turbo")
|
|
44
|
+
- save_llm_responses: Whether to save responses (default: True)
|
|
45
|
+
"""
|
|
46
|
+
super().__init__(config)
|
|
47
|
+
|
|
48
|
+
def _create_llm_client(
|
|
49
|
+
self, config_dict: dict
|
|
50
|
+
) -> tuple[openai.OpenAI | openai.AzureOpenAI, str]:
|
|
51
|
+
"""Create the LLM client for OpenAI or Azure OpenAI."""
|
|
52
|
+
openai_api_key = config_dict.get("openai_api_key")
|
|
53
|
+
openai_api_base = config_dict.get("openai_api_base")
|
|
54
|
+
openai_api_deployment_id = config_dict.get("openai_api_deployment_id")
|
|
55
|
+
model = config_dict.get("model", "gpt-3.5-turbo")
|
|
56
|
+
|
|
57
|
+
if openai_api_base and openai_api_deployment_id:
|
|
58
|
+
# Azure OpenAI
|
|
59
|
+
client = openai.AzureOpenAI(
|
|
60
|
+
api_key=openai_api_key,
|
|
61
|
+
azure_endpoint=openai_api_base,
|
|
62
|
+
api_version=config_dict.get("openai_api_version", "2024-02-15-preview"),
|
|
63
|
+
)
|
|
64
|
+
return client, openai_api_deployment_id
|
|
65
|
+
else:
|
|
66
|
+
# Regular OpenAI
|
|
67
|
+
client = openai.OpenAI(api_key=openai_api_key) # type: ignore[assignment]
|
|
68
|
+
return client, model
|
|
@@ -68,6 +68,26 @@ def get_openai_llm_client_config() -> dict[str, str]:
|
|
|
68
68
|
return config
|
|
69
69
|
|
|
70
70
|
|
|
71
|
+
def get_dr_llm_gateway_client_config() -> dict[str, str]:
|
|
72
|
+
"""Get DataRobot LLM Gateway client configuration."""
|
|
73
|
+
datarobot_api_token = os.environ.get("DATAROBOT_API_TOKEN")
|
|
74
|
+
datarobot_endpoint = os.environ.get("DATAROBOT_ENDPOINT")
|
|
75
|
+
save_llm_responses = os.environ.get("SAVE_LLM_RESPONSES", "false").lower() == "true"
|
|
76
|
+
|
|
77
|
+
if not datarobot_api_token:
|
|
78
|
+
raise ValueError("Missing required environment variable: DATAROBOT_API_TOKEN")
|
|
79
|
+
|
|
80
|
+
config: dict[str, str] = {
|
|
81
|
+
"datarobot_api_token": datarobot_api_token,
|
|
82
|
+
"save_llm_responses": str(save_llm_responses),
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if datarobot_endpoint:
|
|
86
|
+
config["datarobot_endpoint"] = datarobot_endpoint
|
|
87
|
+
|
|
88
|
+
return config
|
|
89
|
+
|
|
90
|
+
|
|
71
91
|
def get_headers() -> dict[str, str]:
|
|
72
92
|
# When the MCP server is deployed in DataRobot, we have to include the API token in headers for
|
|
73
93
|
# authentication.
|
|
@@ -40,40 +40,40 @@ from mcp.types import ElicitResult
|
|
|
40
40
|
|
|
41
41
|
from datarobot_genai.drmcp import get_dr_mcp_server_url
|
|
42
42
|
from datarobot_genai.drmcp import get_headers
|
|
43
|
-
from datarobot_genai.drmcp.test_utils.
|
|
44
|
-
from datarobot_genai.drmcp.test_utils.
|
|
45
|
-
from datarobot_genai.drmcp.test_utils.
|
|
43
|
+
from datarobot_genai.drmcp.test_utils.clients.base import LLMResponse
|
|
44
|
+
from datarobot_genai.drmcp.test_utils.clients.base import ToolCall
|
|
45
|
+
from datarobot_genai.drmcp.test_utils.clients.dr_gateway import DRLLMGatewayMCPClient
|
|
46
46
|
|
|
47
47
|
# Re-export for backwards compatibility
|
|
48
|
-
__all__ = ["
|
|
48
|
+
__all__ = ["DRLLMGatewayMCPClient", "LLMResponse", "ToolCall", "test_mcp_interactive"]
|
|
49
49
|
|
|
50
50
|
|
|
51
51
|
async def test_mcp_interactive() -> None:
|
|
52
52
|
"""Test the MCP server interactively with LLM agent."""
|
|
53
53
|
# Check for required environment variables
|
|
54
|
-
|
|
55
|
-
if not
|
|
56
|
-
print("❌ Error:
|
|
54
|
+
datarobot_api_token = os.environ.get("DATAROBOT_API_TOKEN")
|
|
55
|
+
if not datarobot_api_token:
|
|
56
|
+
print("❌ Error: DATAROBOT_API_TOKEN environment variable is required")
|
|
57
57
|
print("Please set it in your .env file or export it")
|
|
58
58
|
return
|
|
59
59
|
|
|
60
|
-
# Optional
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
openai_api_version = os.environ.get("OPENAI_API_VERSION")
|
|
60
|
+
# Optional DataRobot settings
|
|
61
|
+
datarobot_endpoint = os.environ.get("DATAROBOT_ENDPOINT")
|
|
62
|
+
model = os.environ.get("MODEL")
|
|
64
63
|
|
|
65
64
|
print("🤖 Initializing LLM MCP Client...")
|
|
66
65
|
|
|
67
66
|
# Initialize the LLM client with elicitation handler
|
|
68
67
|
config = {
|
|
69
|
-
"
|
|
70
|
-
"openai_api_base": openai_api_base,
|
|
71
|
-
"openai_api_deployment_id": openai_api_deployment_id,
|
|
72
|
-
"openai_api_version": openai_api_version,
|
|
68
|
+
"datarobot_api_token": datarobot_api_token,
|
|
73
69
|
"save_llm_responses": False,
|
|
74
70
|
}
|
|
71
|
+
if datarobot_endpoint:
|
|
72
|
+
config["datarobot_endpoint"] = datarobot_endpoint
|
|
73
|
+
if model:
|
|
74
|
+
config["model"] = model
|
|
75
75
|
|
|
76
|
-
llm_client =
|
|
76
|
+
llm_client = DRLLMGatewayMCPClient(str(config))
|
|
77
77
|
|
|
78
78
|
# Get MCP server URL
|
|
79
79
|
mcp_server_url = get_dr_mcp_server_url()
|