datarobot-genai 0.2.1__tar.gz → 0.2.3__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.
Files changed (101) hide show
  1. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/PKG-INFO +2 -1
  2. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/pyproject.toml +2 -1
  3. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dr_mcp_server.py +34 -0
  4. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/mcp_instance.py +36 -1
  5. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/.gitignore +0 -0
  6. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/AUTHORS +0 -0
  7. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/LICENSE +0 -0
  8. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/README.md +0 -0
  9. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/__init__.py +0 -0
  10. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/__init__.py +0 -0
  11. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/agents/__init__.py +0 -0
  12. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/agents/base.py +0 -0
  13. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/chat/__init__.py +0 -0
  14. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/chat/auth.py +0 -0
  15. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/chat/client.py +0 -0
  16. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/chat/responses.py +0 -0
  17. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/cli/__init__.py +0 -0
  18. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/cli/agent_environment.py +0 -0
  19. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/cli/agent_kernel.py +0 -0
  20. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/custom_model.py +0 -0
  21. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/mcp/__init__.py +0 -0
  22. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/mcp/common.py +0 -0
  23. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/telemetry_agent.py +0 -0
  24. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/utils/__init__.py +0 -0
  25. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/utils/auth.py +0 -0
  26. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/core/utils/urls.py +0 -0
  27. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/crewai/__init__.py +0 -0
  28. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/crewai/agent.py +0 -0
  29. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/crewai/base.py +0 -0
  30. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/crewai/events.py +0 -0
  31. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/crewai/mcp.py +0 -0
  32. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/__init__.py +0 -0
  33. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/__init__.py +0 -0
  34. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/auth.py +0 -0
  35. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/clients.py +0 -0
  36. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/config.py +0 -0
  37. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/config_utils.py +0 -0
  38. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/constants.py +0 -0
  39. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/credentials.py +0 -0
  40. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dr_mcp_server_logo.py +0 -0
  41. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_prompts/__init__.py +0 -0
  42. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_prompts/controllers.py +0 -0
  43. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_prompts/dr_lib.py +0 -0
  44. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_prompts/register.py +0 -0
  45. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_prompts/utils.py +0 -0
  46. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/__init__.py +0 -0
  47. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/__init__.py +0 -0
  48. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/__init__.py +0 -0
  49. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/base.py +0 -0
  50. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/default.py +0 -0
  51. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/drum.py +0 -0
  52. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/config.py +0 -0
  53. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/controllers.py +0 -0
  54. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/metadata.py +0 -0
  55. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/register.py +0 -0
  56. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/schemas/drum_agentic_fallback_schema.json +0 -0
  57. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/schemas/drum_prediction_fallback_schema.json +0 -0
  58. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/register.py +0 -0
  59. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/dynamic_tools/schema.py +0 -0
  60. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/exceptions.py +0 -0
  61. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/logging.py +0 -0
  62. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/mcp_server_tools.py +0 -0
  63. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/memory_management/__init__.py +0 -0
  64. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/memory_management/manager.py +0 -0
  65. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/memory_management/memory_tools.py +0 -0
  66. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/routes.py +0 -0
  67. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/routes_utils.py +0 -0
  68. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/server_life_cycle.py +0 -0
  69. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/telemetry.py +0 -0
  70. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/tool_filter.py +0 -0
  71. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/core/utils.py +0 -0
  72. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/server.py +0 -0
  73. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/test_utils/__init__.py +0 -0
  74. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/test_utils/integration_mcp_server.py +0 -0
  75. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/test_utils/mcp_utils_ete.py +0 -0
  76. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/test_utils/mcp_utils_integration.py +0 -0
  77. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/test_utils/openai_llm_mcp_client.py +0 -0
  78. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/test_utils/tool_base_ete.py +0 -0
  79. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/test_utils/utils.py +0 -0
  80. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/__init__.py +0 -0
  81. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/__init__.py +0 -0
  82. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/data.py +0 -0
  83. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/deployment.py +0 -0
  84. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/deployment_info.py +0 -0
  85. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/model.py +0 -0
  86. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/predict.py +0 -0
  87. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/predict_realtime.py +0 -0
  88. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/project.py +0 -0
  89. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/drmcp/tools/predictive/training.py +0 -0
  90. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/langgraph/__init__.py +0 -0
  91. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/langgraph/agent.py +0 -0
  92. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/langgraph/mcp.py +0 -0
  93. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/llama_index/__init__.py +0 -0
  94. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/llama_index/agent.py +0 -0
  95. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/llama_index/base.py +0 -0
  96. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/llama_index/mcp.py +0 -0
  97. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/nat/__init__.py +0 -0
  98. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/nat/agent.py +0 -0
  99. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/nat/datarobot_llm_clients.py +0 -0
  100. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/nat/datarobot_llm_providers.py +0 -0
  101. {datarobot_genai-0.2.1 → datarobot_genai-0.2.3}/src/datarobot_genai/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datarobot-genai
3
- Version: 0.2.1
3
+ Version: 0.2.3
4
4
  Summary: Generic helpers for GenAI
5
5
  Project-URL: Homepage, https://github.com/datarobot-oss/datarobot-genai
6
6
  Author: DataRobot, Inc.
@@ -17,6 +17,7 @@ Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0
17
17
  Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0
18
18
  Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5
19
19
  Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0
20
+ Requires-Dist: opentelemetry-instrumentation-threading<1.0.0,>=0.43b0
20
21
  Requires-Dist: pandas<3.0.0,>=2.2.3
21
22
  Requires-Dist: pyjwt<3.0.0,>=2.10.1
22
23
  Requires-Dist: pypdf<7.0.0,>=6.1.3
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "datarobot-genai"
7
- version = "0.2.1"
7
+ version = "0.2.3"
8
8
  description = "Generic helpers for GenAI"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10, <3.13"
@@ -24,6 +24,7 @@ dependencies = [
24
24
  "opentelemetry-instrumentation-aiohttp-client>=0.43b0,<1.0.0",
25
25
  "opentelemetry-instrumentation-httpx>=0.43b0,<1.0.0",
26
26
  "opentelemetry-instrumentation-openai>=0.40.5,<1.0.0",
27
+ "opentelemetry-instrumentation-threading>=0.43b0,<1.0.0",
27
28
  "ag-ui-protocol>=0.1.9,<0.2.0",
28
29
  ]
29
30
 
@@ -115,6 +115,9 @@ class DataRobotMCPServer:
115
115
  self._mcp = mcp
116
116
  self._mcp_transport = transport
117
117
 
118
+ # Configure MCP server capabilities
119
+ self._configure_mcp_capabilities()
120
+
118
121
  # Initialize telemetry
119
122
  initialize_telemetry(mcp)
120
123
 
@@ -163,6 +166,37 @@ class DataRobotMCPServer:
163
166
  if transport == "streamable-http":
164
167
  register_routes(self._mcp)
165
168
 
169
+ def _configure_mcp_capabilities(self) -> None:
170
+ """Configure MCP capabilities that FastMCP doesn't expose directly.
171
+
172
+ See: https://github.com/modelcontextprotocol/python-sdk/issues/1126
173
+ """
174
+ server = self._mcp._mcp_server
175
+
176
+ # Declare prompts_changed capability (capabilities.prompts.listChanged: true)
177
+ server.notification_options.prompts_changed = True
178
+
179
+ # Declare experimental capabilities ( experimental.dynamic_prompts: true)
180
+ server.experimental_capabilities = {"dynamic_prompts": {"enabled": True}}
181
+
182
+ # Patch to include experimental_capabilities (FastMCP doesn't expose this)
183
+ original = server.create_initialization_options
184
+
185
+ def patched(
186
+ notification_options: Any = None,
187
+ experimental_capabilities: dict[str, dict[str, Any]] | None = None,
188
+ **kwargs: Any,
189
+ ) -> Any:
190
+ if experimental_capabilities is None:
191
+ experimental_capabilities = getattr(server, "experimental_capabilities", None)
192
+ return original(
193
+ notification_options=notification_options,
194
+ experimental_capabilities=experimental_capabilities,
195
+ **kwargs,
196
+ )
197
+
198
+ server.create_initialization_options = patched
199
+
166
200
  def run(self, show_banner: bool = False) -> None:
167
201
  """Run the DataRobot MCP server synchronously."""
168
202
  try:
@@ -22,6 +22,7 @@ from fastmcp import Context
22
22
  from fastmcp import FastMCP
23
23
  from fastmcp.exceptions import NotFoundError
24
24
  from fastmcp.prompts.prompt import Prompt
25
+ from fastmcp.server.dependencies import get_context
25
26
  from fastmcp.tools import FunctionTool
26
27
  from fastmcp.tools import Tool
27
28
  from fastmcp.utilities.types import NotSet
@@ -91,6 +92,34 @@ class TaggedFastMCP(FastMCP):
91
92
  self._deployments_map: dict[str, str] = {}
92
93
  self._prompts_map: dict[str, tuple[str, str]] = {}
93
94
 
95
+ async def notify_prompts_changed(self) -> None:
96
+ """
97
+ Notify connected clients that the prompt list has changed.
98
+
99
+ This method attempts to send a prompts/list_changed notification to inform
100
+ clients that they should refresh their prompt list.
101
+
102
+ Note: In stateless HTTP mode (default for this server), notifications may not
103
+ reach clients since each request is independent. This method still logs the
104
+ change for auditing purposes and will work if the server is configured for
105
+ stateful connections.
106
+
107
+ See: https://github.com/modelcontextprotocol/python-sdk/issues/710
108
+ """
109
+ logger.info("Prompt list changed - attempting to notify connected clients")
110
+
111
+ # Try to use FastMCP's built-in notification mechanism if in an MCP context
112
+ try:
113
+ context = get_context()
114
+ context._queue_prompt_list_changed()
115
+ logger.debug("Queued prompts_changed notification via MCP context")
116
+ except RuntimeError:
117
+ # No active MCP context - this is expected when called from REST API
118
+ logger.debug(
119
+ "No active MCP context for notification. "
120
+ "In stateless mode, clients will see changes on next request."
121
+ )
122
+
94
123
  @overload
95
124
  def tool(
96
125
  self,
@@ -311,7 +340,7 @@ class TaggedFastMCP(FastMCP):
311
340
  f"skipping removal."
312
341
  )
313
342
  else:
314
- prompts_d = await mcp.get_prompts()
343
+ prompts_d = await self.get_prompts()
315
344
  for prompt in prompts_d.values():
316
345
  if (
317
346
  prompt.meta is not None
@@ -322,6 +351,9 @@ class TaggedFastMCP(FastMCP):
322
351
  prompt.disable()
323
352
 
324
353
  self._prompts_map.pop(prompt_template_id, None)
354
+
355
+ # Notify clients that the prompt list has changed
356
+ await self.notify_prompts_changed()
325
357
  else:
326
358
  logger.debug(
327
359
  f"Do not found prompt template with id = {prompt_template_id} in registry, "
@@ -543,4 +575,7 @@ async def register_prompt(
543
575
  raise RuntimeError(f"Prompt {prompt_name_no_duplicate} was not registered successfully")
544
576
  logger.info(f"Registered prompts: {len(prompts)}")
545
577
 
578
+ # Notify clients that the prompt list has changed
579
+ await mcp.notify_prompts_changed()
580
+
546
581
  return registered_prompt
File without changes
File without changes