datarobot-genai 0.1.66__tar.gz → 0.1.68__tar.gz
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-0.1.66 → datarobot_genai-0.1.68}/PKG-INFO +1 -1
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/pyproject.toml +1 -1
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/agents/base.py +7 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/custom_model.py +5 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/mcp/common.py +34 -11
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/crewai/base.py +1 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/crewai/mcp.py +5 -1
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_prompts/controllers.py +45 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/routes.py +14 -1
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/langgraph/agent.py +2 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/langgraph/mcp.py +7 -1
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/llama_index/base.py +1 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/llama_index/mcp.py +6 -1
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/.gitignore +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/AUTHORS +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/LICENSE +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/README.md +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/agents/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/chat/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/chat/auth.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/chat/client.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/chat/responses.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/cli/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/cli/agent_environment.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/cli/agent_kernel.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/mcp/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/telemetry_agent.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/utils/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/utils/auth.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/utils/urls.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/crewai/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/crewai/agent.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/crewai/events.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/auth.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/clients.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/config.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/config_utils.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/constants.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/credentials.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dr_mcp_server.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dr_mcp_server_logo.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_prompts/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_prompts/dr_lib.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_prompts/register.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_prompts/utils.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/base.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/default.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/drum.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/config.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/controllers.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/metadata.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/register.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/schemas/drum_agentic_fallback_schema.json +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/schemas/drum_prediction_fallback_schema.json +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/register.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dynamic_tools/schema.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/exceptions.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/logging.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/mcp_instance.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/mcp_server_tools.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/memory_management/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/memory_management/manager.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/memory_management/memory_tools.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/routes_utils.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/server_life_cycle.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/telemetry.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/tool_filter.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/utils.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/server.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/integration_mcp_server.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/mcp_utils_ete.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/mcp_utils_integration.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/openai_llm_mcp_client.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/tool_base_ete.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/utils.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/data.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/deployment.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/deployment_info.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/model.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/predict.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/predict_realtime.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/project.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/training.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/langgraph/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/llama_index/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/llama_index/agent.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/nat/__init__.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/nat/agent.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/nat/datarobot_llm_clients.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/nat/datarobot_llm_providers.py +0 -0
- {datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/py.typed +0 -0
|
@@ -52,6 +52,7 @@ class BaseAgent(Generic[TTool], abc.ABC):
|
|
|
52
52
|
verbose: bool | str | None = True,
|
|
53
53
|
timeout: int | None = 90,
|
|
54
54
|
authorization_context: dict[str, Any] | None = None,
|
|
55
|
+
forwarded_headers: dict[str, str] | None = None,
|
|
55
56
|
**_: Any,
|
|
56
57
|
) -> None:
|
|
57
58
|
self.api_key = api_key or os.environ.get("DATAROBOT_API_TOKEN")
|
|
@@ -68,6 +69,7 @@ class BaseAgent(Generic[TTool], abc.ABC):
|
|
|
68
69
|
self.verbose = bool(verbose)
|
|
69
70
|
self._mcp_tools: list[TTool] = []
|
|
70
71
|
self._authorization_context = authorization_context or {}
|
|
72
|
+
self._forwarded_headers: dict[str, str] = forwarded_headers or {}
|
|
71
73
|
|
|
72
74
|
def set_mcp_tools(self, tools: list[TTool]) -> None:
|
|
73
75
|
self._mcp_tools = tools
|
|
@@ -86,6 +88,11 @@ class BaseAgent(Generic[TTool], abc.ABC):
|
|
|
86
88
|
"""Return the authorization context for this agent."""
|
|
87
89
|
return self._authorization_context
|
|
88
90
|
|
|
91
|
+
@property
|
|
92
|
+
def forwarded_headers(self) -> dict[str, str]:
|
|
93
|
+
"""Return the forwarded headers for this agent."""
|
|
94
|
+
return self._forwarded_headers
|
|
95
|
+
|
|
89
96
|
def litellm_api_base(self, deployment_id: str | None) -> str:
|
|
90
97
|
return get_api_base(self.api_base, deployment_id)
|
|
91
98
|
|
|
@@ -139,6 +139,11 @@ def chat_entrypoint(
|
|
|
139
139
|
completion_create_params["authorization_context"] = resolve_authorization_context(
|
|
140
140
|
completion_create_params, **kwargs
|
|
141
141
|
)
|
|
142
|
+
# Keep only allowed headers from the forwarded_headers.
|
|
143
|
+
incoming_headers = kwargs.get("headers", {}) or {}
|
|
144
|
+
allowed_headers = {"x-datarobot-api-token", "x-datarobot-api-key"}
|
|
145
|
+
forwarded_headers = {k: v for k, v in incoming_headers.items() if k.lower() in allowed_headers}
|
|
146
|
+
completion_create_params["forwarded_headers"] = forwarded_headers
|
|
142
147
|
|
|
143
148
|
# Instantiate user agent with all supplied completion params including auth context
|
|
144
149
|
agent = agent_cls(**completion_create_params)
|
|
@@ -16,6 +16,7 @@ import json
|
|
|
16
16
|
import re
|
|
17
17
|
from typing import Any
|
|
18
18
|
from typing import Literal
|
|
19
|
+
from urllib.parse import urlparse
|
|
19
20
|
|
|
20
21
|
from datarobot.core.config import DataRobotAppFrameworkBaseSettings
|
|
21
22
|
from pydantic import field_validator
|
|
@@ -37,6 +38,7 @@ class MCPConfig(DataRobotAppFrameworkBaseSettings):
|
|
|
37
38
|
datarobot_endpoint: str | None = None
|
|
38
39
|
datarobot_api_token: str | None = None
|
|
39
40
|
authorization_context: dict[str, Any] | None = None
|
|
41
|
+
forwarded_headers: dict[str, str] | None = None
|
|
40
42
|
|
|
41
43
|
_auth_context_handler: AuthContextHeaderHandler | None = None
|
|
42
44
|
_server_config: dict[str, Any] | None = None
|
|
@@ -121,18 +123,33 @@ class MCPConfig(DataRobotAppFrameworkBaseSettings):
|
|
|
121
123
|
"""
|
|
122
124
|
if self.external_mcp_url:
|
|
123
125
|
# External MCP URL - no authentication needed
|
|
126
|
+
headers: dict[str, str] = {}
|
|
127
|
+
|
|
128
|
+
# Forward headers for localhost connections
|
|
129
|
+
if self.forwarded_headers:
|
|
130
|
+
try:
|
|
131
|
+
parsed_url = urlparse(self.external_mcp_url)
|
|
132
|
+
hostname = parsed_url.hostname or ""
|
|
133
|
+
# Check if hostname is localhost or 127.0.0.1
|
|
134
|
+
if hostname in ("localhost", "127.0.0.1", "::1"):
|
|
135
|
+
headers.update(self.forwarded_headers)
|
|
136
|
+
except Exception:
|
|
137
|
+
# If URL parsing fails, fall back to simple string check
|
|
138
|
+
if "localhost" in self.external_mcp_url or "127.0.0.1" in self.external_mcp_url:
|
|
139
|
+
headers.update(self.forwarded_headers)
|
|
140
|
+
|
|
141
|
+
# Merge external headers if provided
|
|
124
142
|
if self.external_mcp_headers:
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
headers = {}
|
|
143
|
+
external_headers = json.loads(self.external_mcp_headers)
|
|
144
|
+
headers.update(external_headers)
|
|
128
145
|
|
|
129
|
-
|
|
146
|
+
return {
|
|
130
147
|
"url": self.external_mcp_url.rstrip("/"),
|
|
131
148
|
"transport": self.external_mcp_transport,
|
|
132
149
|
"headers": headers,
|
|
133
150
|
}
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
|
|
152
|
+
if self.mcp_deployment_id:
|
|
136
153
|
# DataRobot deployment ID - requires authentication
|
|
137
154
|
if self.datarobot_endpoint is None:
|
|
138
155
|
raise ValueError(
|
|
@@ -142,15 +159,21 @@ class MCPConfig(DataRobotAppFrameworkBaseSettings):
|
|
|
142
159
|
raise ValueError(
|
|
143
160
|
"When using a DataRobot hosted MCP deployment, datarobot_api_token must be set."
|
|
144
161
|
)
|
|
162
|
+
|
|
145
163
|
base_url = self.datarobot_endpoint.rstrip("/")
|
|
146
164
|
if not base_url.endswith("/api/v2"):
|
|
147
|
-
base_url = base_url
|
|
165
|
+
base_url = f"{base_url}/api/v2"
|
|
166
|
+
|
|
148
167
|
url = f"{base_url}/deployments/{self.mcp_deployment_id}/directAccess/mcp"
|
|
149
168
|
|
|
150
|
-
headers
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
169
|
+
# Start with forwarded headers if available
|
|
170
|
+
headers = {}
|
|
171
|
+
if self.forwarded_headers:
|
|
172
|
+
headers.update(self.forwarded_headers)
|
|
173
|
+
|
|
174
|
+
# Add authentication headers
|
|
175
|
+
headers.update(self._authorization_bearer_header())
|
|
176
|
+
headers.update(self._authorization_context_header())
|
|
154
177
|
|
|
155
178
|
return {
|
|
156
179
|
"url": url,
|
|
@@ -93,6 +93,7 @@ class CrewAIAgent(BaseAgent[BaseTool], abc.ABC):
|
|
|
93
93
|
# Use MCP context manager to handle connection lifecycle
|
|
94
94
|
with mcp_tools_context(
|
|
95
95
|
authorization_context=self._authorization_context,
|
|
96
|
+
forwarded_headers=self.forwarded_headers,
|
|
96
97
|
) as mcp_tools:
|
|
97
98
|
# Set MCP tools for all agents if MCP is not configured this is effectively a no-op
|
|
98
99
|
self.set_mcp_tools(mcp_tools)
|
|
@@ -30,9 +30,13 @@ from datarobot_genai.core.mcp.common import MCPConfig
|
|
|
30
30
|
@contextmanager
|
|
31
31
|
def mcp_tools_context(
|
|
32
32
|
authorization_context: dict[str, Any] | None = None,
|
|
33
|
+
forwarded_headers: dict[str, str] | None = None,
|
|
33
34
|
) -> Generator[list[Any], None, None]:
|
|
34
35
|
"""Context manager for MCP tools that handles connection lifecycle."""
|
|
35
|
-
config = MCPConfig(
|
|
36
|
+
config = MCPConfig(
|
|
37
|
+
authorization_context=authorization_context,
|
|
38
|
+
forwarded_headers=forwarded_headers,
|
|
39
|
+
)
|
|
36
40
|
# If no MCP server configured, return empty tools list
|
|
37
41
|
if not config.server_config:
|
|
38
42
|
print("No MCP server configured, using empty tools list", flush=True)
|
|
@@ -18,6 +18,8 @@ from fastmcp.prompts.prompt import Prompt
|
|
|
18
18
|
|
|
19
19
|
from datarobot_genai.drmcp.core.dynamic_prompts.dr_lib import get_datarobot_prompt_template
|
|
20
20
|
from datarobot_genai.drmcp.core.dynamic_prompts.dr_lib import get_datarobot_prompt_template_version
|
|
21
|
+
from datarobot_genai.drmcp.core.dynamic_prompts.dr_lib import get_datarobot_prompt_template_versions
|
|
22
|
+
from datarobot_genai.drmcp.core.dynamic_prompts.dr_lib import get_datarobot_prompt_templates
|
|
21
23
|
from datarobot_genai.drmcp.core.dynamic_prompts.register import (
|
|
22
24
|
register_prompt_from_datarobot_prompt_management,
|
|
23
25
|
)
|
|
@@ -83,3 +85,46 @@ async def delete_registered_prompt_template(prompt_template_id: str) -> bool:
|
|
|
83
85
|
f"version {prompt_template_version_id}"
|
|
84
86
|
)
|
|
85
87
|
return True
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
async def refresh_registered_prompt_template() -> None:
|
|
91
|
+
"""Refresh all registered prompt templates in the MCP instance."""
|
|
92
|
+
prompt_templates = get_datarobot_prompt_templates()
|
|
93
|
+
prompt_templates_ids = {p.id for p in prompt_templates}
|
|
94
|
+
prompt_templates_versions = get_datarobot_prompt_template_versions(list(prompt_templates_ids))
|
|
95
|
+
|
|
96
|
+
mcp_prompt_templates_mappings = await mcp.get_prompt_mapping()
|
|
97
|
+
|
|
98
|
+
for prompt_template in prompt_templates:
|
|
99
|
+
prompt_template_versions = prompt_templates_versions.get(prompt_template.id)
|
|
100
|
+
if not prompt_template_versions:
|
|
101
|
+
continue
|
|
102
|
+
|
|
103
|
+
latest_version = max(prompt_template_versions, key=lambda v: v.version)
|
|
104
|
+
|
|
105
|
+
if prompt_template.id not in mcp_prompt_templates_mappings:
|
|
106
|
+
# New prompt template -> add
|
|
107
|
+
await register_prompt_from_datarobot_prompt_management(
|
|
108
|
+
prompt_template=prompt_template, prompt_template_version=latest_version
|
|
109
|
+
)
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
mcp_prompt_template_version, mcp_prompt = mcp_prompt_templates_mappings[prompt_template.id]
|
|
113
|
+
|
|
114
|
+
if mcp_prompt_template_version != latest_version:
|
|
115
|
+
# Current version saved in MCP is not the latest one => update it
|
|
116
|
+
await register_prompt_from_datarobot_prompt_management(
|
|
117
|
+
prompt_template=prompt_template, prompt_template_version=latest_version
|
|
118
|
+
)
|
|
119
|
+
continue
|
|
120
|
+
|
|
121
|
+
# Else => mcp_prompt_template_version == latest_version
|
|
122
|
+
# For now it means nothing changed as there's no possibility to edit promp template version.
|
|
123
|
+
|
|
124
|
+
for mcp_prompt_template_id, (
|
|
125
|
+
mcp_prompt_template_version_id,
|
|
126
|
+
_,
|
|
127
|
+
) in mcp_prompt_templates_mappings.items():
|
|
128
|
+
if mcp_prompt_template_id not in prompt_templates_ids:
|
|
129
|
+
# We need to also delete prompt templates that are
|
|
130
|
+
await mcp.remove_prompt_mapping(mcp_prompt_template_id, mcp_prompt_template_version_id)
|
|
@@ -19,6 +19,7 @@ from starlette.requests import Request
|
|
|
19
19
|
from starlette.responses import JSONResponse
|
|
20
20
|
|
|
21
21
|
from .dynamic_prompts.controllers import delete_registered_prompt_template
|
|
22
|
+
from .dynamic_prompts.controllers import refresh_registered_prompt_template
|
|
22
23
|
from .dynamic_prompts.controllers import register_prompt_from_prompt_template_id_and_version
|
|
23
24
|
from .dynamic_tools.deployment.controllers import delete_registered_tool_deployment
|
|
24
25
|
from .dynamic_tools.deployment.controllers import get_registered_tool_deployments
|
|
@@ -418,6 +419,18 @@ def register_routes(mcp: TaggedFastMCP) -> None:
|
|
|
418
419
|
)
|
|
419
420
|
except Exception as e:
|
|
420
421
|
return JSONResponse(
|
|
421
|
-
status_code=HTTPStatus.
|
|
422
|
+
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
422
423
|
content={"error": f"Failed to add prompt template: {str(e)}"},
|
|
423
424
|
)
|
|
425
|
+
|
|
426
|
+
@mcp.custom_route(prefix_mount_path("/registeredPrompts"), methods=["PUT"])
|
|
427
|
+
async def refresh_prompt_templates(_: Request) -> JSONResponse:
|
|
428
|
+
"""Refresh prompt templates."""
|
|
429
|
+
try:
|
|
430
|
+
await refresh_registered_prompt_template()
|
|
431
|
+
return JSONResponse(status_code=HTTPStatus.NO_CONTENT, content=None)
|
|
432
|
+
except Exception as e:
|
|
433
|
+
return JSONResponse(
|
|
434
|
+
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
|
435
|
+
content={"error": f"Failed to refresh prompt templates: {str(e)}"},
|
|
436
|
+
)
|
|
@@ -86,6 +86,7 @@ class LangGraphAgent(BaseAgent[BaseTool], abc.ABC):
|
|
|
86
86
|
]:
|
|
87
87
|
async with mcp_tools_context(
|
|
88
88
|
authorization_context=self._authorization_context,
|
|
89
|
+
forwarded_headers=self.forwarded_headers,
|
|
89
90
|
) as mcp_tools:
|
|
90
91
|
self.set_mcp_tools(mcp_tools)
|
|
91
92
|
result = await self._invoke(completion_create_params)
|
|
@@ -104,6 +105,7 @@ class LangGraphAgent(BaseAgent[BaseTool], abc.ABC):
|
|
|
104
105
|
# For non-streaming, use async with directly
|
|
105
106
|
async with mcp_tools_context(
|
|
106
107
|
authorization_context=self._authorization_context,
|
|
108
|
+
forwarded_headers=self.forwarded_headers,
|
|
107
109
|
) as mcp_tools:
|
|
108
110
|
self.set_mcp_tools(mcp_tools)
|
|
109
111
|
result = await self._invoke(completion_create_params)
|
|
@@ -28,6 +28,7 @@ from datarobot_genai.core.mcp.common import MCPConfig
|
|
|
28
28
|
@asynccontextmanager
|
|
29
29
|
async def mcp_tools_context(
|
|
30
30
|
authorization_context: dict[str, Any] | None = None,
|
|
31
|
+
forwarded_headers: dict[str, str] | None = None,
|
|
31
32
|
) -> AsyncGenerator[list[BaseTool], None]:
|
|
32
33
|
"""Yield a list of LangChain BaseTool instances loaded via MCP.
|
|
33
34
|
|
|
@@ -37,8 +38,13 @@ async def mcp_tools_context(
|
|
|
37
38
|
----------
|
|
38
39
|
authorization_context : dict[str, Any] | None
|
|
39
40
|
Authorization context to use for MCP connections
|
|
41
|
+
forwarded_headers : dict[str, str] | None
|
|
42
|
+
Forwarded headers, e.g. x-datarobot-api-key to use for MCP authentication
|
|
40
43
|
"""
|
|
41
|
-
mcp_config = MCPConfig(
|
|
44
|
+
mcp_config = MCPConfig(
|
|
45
|
+
authorization_context=authorization_context,
|
|
46
|
+
forwarded_headers=forwarded_headers,
|
|
47
|
+
)
|
|
42
48
|
server_config = mcp_config.server_config
|
|
43
49
|
|
|
44
50
|
if not server_config:
|
|
@@ -84,6 +84,7 @@ class LlamaIndexAgent(BaseAgent[BaseTool], abc.ABC):
|
|
|
84
84
|
# Load MCP tools (if configured) asynchronously before building workflow
|
|
85
85
|
mcp_tools = await load_mcp_tools(
|
|
86
86
|
authorization_context=self._authorization_context,
|
|
87
|
+
forwarded_headers=self.forwarded_headers,
|
|
87
88
|
)
|
|
88
89
|
self.set_mcp_tools(mcp_tools)
|
|
89
90
|
|
|
@@ -30,18 +30,23 @@ from datarobot_genai.core.mcp.common import MCPConfig
|
|
|
30
30
|
|
|
31
31
|
async def load_mcp_tools(
|
|
32
32
|
authorization_context: dict[str, Any] | None = None,
|
|
33
|
+
forwarded_headers: dict[str, str] | None = None,
|
|
33
34
|
) -> list[Any]:
|
|
34
35
|
"""
|
|
35
36
|
Asynchronously load MCP tools for LlamaIndex.
|
|
36
37
|
|
|
37
38
|
Args:
|
|
38
39
|
authorization_context: Optional authorization context for MCP connections
|
|
40
|
+
forwarded_headers: Optional forwarded headers, e.g. x-datarobot-api-key for MCP auth
|
|
39
41
|
|
|
40
42
|
Returns
|
|
41
43
|
-------
|
|
42
44
|
List of MCP tools, or empty list if no MCP configuration is present.
|
|
43
45
|
"""
|
|
44
|
-
config = MCPConfig(
|
|
46
|
+
config = MCPConfig(
|
|
47
|
+
authorization_context=authorization_context,
|
|
48
|
+
forwarded_headers=forwarded_headers,
|
|
49
|
+
)
|
|
45
50
|
server_params = config.server_config
|
|
46
51
|
|
|
47
52
|
if not server_params:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/agents/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/chat/responses.py
RENAMED
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/cli/agent_environment.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/cli/agent_kernel.py
RENAMED
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/telemetry_agent.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/core/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/config_utils.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/constants.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/credentials.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/dr_mcp_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/mcp_instance.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/mcp_server_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/routes_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/telemetry.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/core/tool_filter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/test_utils/utils.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/drmcp/tools/predictive/data.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/llama_index/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/nat/datarobot_llm_clients.py
RENAMED
|
File without changes
|
{datarobot_genai-0.1.66 → datarobot_genai-0.1.68}/src/datarobot_genai/nat/datarobot_llm_providers.py
RENAMED
|
File without changes
|
|
File without changes
|