datarobot-genai 0.1.55__tar.gz → 0.1.64__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.55 → datarobot_genai-0.1.64}/PKG-INFO +47 -47
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/pyproject.toml +47 -47
- datarobot_genai-0.1.64/src/datarobot_genai/core/mcp/common.py +161 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/telemetry_agent.py +14 -1
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/utils/auth.py +64 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/crewai/base.py +0 -2
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/crewai/mcp.py +2 -9
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/auth.py +28 -25
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/clients.py +67 -3
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/config.py +12 -8
- datarobot_genai-0.1.64/src/datarobot_genai/drmcp/core/dynamic_prompts/controllers.py +85 -0
- datarobot_genai-0.1.64/src/datarobot_genai/drmcp/core/dynamic_prompts/dr_lib.py +128 -0
- datarobot_genai-0.1.64/src/datarobot_genai/drmcp/core/dynamic_prompts/register.py +206 -0
- datarobot_genai-0.1.64/src/datarobot_genai/drmcp/core/dynamic_prompts/utils.py +33 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/mcp_instance.py +85 -3
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/routes.py +112 -28
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/langgraph/agent.py +3 -6
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/langgraph/mcp.py +1 -9
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/llama_index/base.py +0 -2
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/llama_index/mcp.py +1 -7
- datarobot_genai-0.1.64/src/datarobot_genai/nat/agent.py +258 -0
- datarobot_genai-0.1.55/src/datarobot_genai/core/mcp/common.py +0 -107
- datarobot_genai-0.1.55/src/datarobot_genai/drmcp/core/dynamic_prompts/dr_lib.py +0 -91
- datarobot_genai-0.1.55/src/datarobot_genai/drmcp/core/dynamic_prompts/register.py +0 -121
- datarobot_genai-0.1.55/src/datarobot_genai/drmcp/test_utils/prompt_management.py +0 -84
- datarobot_genai-0.1.55/src/datarobot_genai/nat/agent.py +0 -137
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/.gitignore +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/AUTHORS +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/LICENSE +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/README.md +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/agents/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/agents/base.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/chat/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/chat/auth.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/chat/client.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/chat/responses.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/cli/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/cli/agent_environment.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/cli/agent_kernel.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/custom_model.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/mcp/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/utils/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/utils/urls.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/crewai/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/crewai/agent.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/crewai/events.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/config_utils.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/constants.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/credentials.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dr_mcp_server.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dr_mcp_server_logo.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_prompts/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/base.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/default.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/adapters/drum.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/config.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/controllers.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/metadata.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/register.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/schemas/drum_agentic_fallback_schema.json +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/deployment/schemas/drum_prediction_fallback_schema.json +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/register.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/dynamic_tools/schema.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/exceptions.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/logging.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/mcp_server_tools.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/memory_management/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/memory_management/manager.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/memory_management/memory_tools.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/routes_utils.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/server_life_cycle.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/telemetry.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/tool_filter.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/core/utils.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/server.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/test_utils/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/test_utils/integration_mcp_server.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/test_utils/mcp_utils_ete.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/test_utils/mcp_utils_integration.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/test_utils/openai_llm_mcp_client.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/test_utils/tool_base_ete.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/test_utils/utils.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/data.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/deployment.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/deployment_info.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/model.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/predict.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/predict_realtime.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/project.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/drmcp/tools/predictive/training.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/langgraph/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/llama_index/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/llama_index/agent.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/nat/__init__.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/nat/datarobot_llm_clients.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/nat/datarobot_llm_providers.py +0 -0
- {datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/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.1.
|
|
3
|
+
Version: 0.1.64
|
|
4
4
|
Summary: Generic helpers for GenAI
|
|
5
5
|
Project-URL: Homepage, https://github.com/datarobot-oss/datarobot-genai
|
|
6
6
|
Author: DataRobot, Inc.
|
|
@@ -8,65 +8,65 @@ License: Apache-2.0
|
|
|
8
8
|
License-File: AUTHORS
|
|
9
9
|
License-File: LICENSE
|
|
10
10
|
Requires-Python: <3.13,>=3.10
|
|
11
|
-
Requires-Dist: datarobot-drum
|
|
12
|
-
Requires-Dist: datarobot-predict
|
|
13
|
-
Requires-Dist: datarobot
|
|
14
|
-
Requires-Dist: openai
|
|
15
|
-
Requires-Dist: opentelemetry-instrumentation-aiohttp-client
|
|
16
|
-
Requires-Dist: opentelemetry-instrumentation-httpx
|
|
17
|
-
Requires-Dist: opentelemetry-instrumentation-openai
|
|
18
|
-
Requires-Dist: opentelemetry-instrumentation-requests
|
|
19
|
-
Requires-Dist: pandas
|
|
20
|
-
Requires-Dist: pyjwt
|
|
21
|
-
Requires-Dist: pypdf
|
|
22
|
-
Requires-Dist: ragas
|
|
23
|
-
Requires-Dist: requests
|
|
11
|
+
Requires-Dist: datarobot-drum<2.0.0,>=1.17.5
|
|
12
|
+
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2
|
|
13
|
+
Requires-Dist: datarobot<4.0.0,>=3.9.1
|
|
14
|
+
Requires-Dist: openai<2.0.0,>=1.76.2
|
|
15
|
+
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0
|
|
16
|
+
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0
|
|
17
|
+
Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5
|
|
18
|
+
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0
|
|
19
|
+
Requires-Dist: pandas<3.0.0,>=2.2.3
|
|
20
|
+
Requires-Dist: pyjwt<3.0.0,>=2.10.1
|
|
21
|
+
Requires-Dist: pypdf<7.0.0,>=6.1.3
|
|
22
|
+
Requires-Dist: ragas<0.4.0,>=0.3.8
|
|
23
|
+
Requires-Dist: requests<3.0.0,>=2.32.4
|
|
24
24
|
Provides-Extra: crewai
|
|
25
|
-
Requires-Dist: crewai-tools[mcp]
|
|
26
|
-
Requires-Dist: crewai
|
|
27
|
-
Requires-Dist: opentelemetry-instrumentation-crewai
|
|
28
|
-
Requires-Dist: pybase64
|
|
25
|
+
Requires-Dist: crewai-tools[mcp]<0.77.0,>=0.69.0; extra == 'crewai'
|
|
26
|
+
Requires-Dist: crewai<1.0.0,>=0.193.2; extra == 'crewai'
|
|
27
|
+
Requires-Dist: opentelemetry-instrumentation-crewai<1.0.0,>=0.40.5; extra == 'crewai'
|
|
28
|
+
Requires-Dist: pybase64<2.0.0,>=1.4.2; extra == 'crewai'
|
|
29
29
|
Provides-Extra: drmcp
|
|
30
|
-
Requires-Dist: aiohttp-retry
|
|
31
|
-
Requires-Dist: aiohttp
|
|
32
|
-
Requires-Dist: aiosignal
|
|
33
|
-
Requires-Dist: boto3
|
|
34
|
-
Requires-Dist: datarobot-asgi-middleware
|
|
30
|
+
Requires-Dist: aiohttp-retry<3.0.0,>=2.8.3; extra == 'drmcp'
|
|
31
|
+
Requires-Dist: aiohttp<4.0.0,>=3.9.0; extra == 'drmcp'
|
|
32
|
+
Requires-Dist: aiosignal<2.0.0,>=1.3.1; extra == 'drmcp'
|
|
33
|
+
Requires-Dist: boto3<2.0.0,>=1.34.0; extra == 'drmcp'
|
|
34
|
+
Requires-Dist: datarobot-asgi-middleware<1.0.0,>=0.2.0; extra == 'drmcp'
|
|
35
35
|
Requires-Dist: fastmcp==2.13.0.2; extra == 'drmcp'
|
|
36
|
-
Requires-Dist: httpx
|
|
37
|
-
Requires-Dist: opentelemetry-api
|
|
38
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-http
|
|
39
|
-
Requires-Dist: opentelemetry-exporter-otlp
|
|
40
|
-
Requires-Dist: opentelemetry-sdk
|
|
41
|
-
Requires-Dist: pydantic-settings
|
|
42
|
-
Requires-Dist: pydantic
|
|
43
|
-
Requires-Dist: python-dotenv
|
|
36
|
+
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == 'drmcp'
|
|
37
|
+
Requires-Dist: opentelemetry-api<2.0.0,>=1.22.0; extra == 'drmcp'
|
|
38
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0.0,>=1.22.0; extra == 'drmcp'
|
|
39
|
+
Requires-Dist: opentelemetry-exporter-otlp<2.0.0,>=1.22.0; extra == 'drmcp'
|
|
40
|
+
Requires-Dist: opentelemetry-sdk<2.0.0,>=1.22.0; extra == 'drmcp'
|
|
41
|
+
Requires-Dist: pydantic-settings<3.0.0,>=2.1.0; extra == 'drmcp'
|
|
42
|
+
Requires-Dist: pydantic<3.0.0,>=2.6.1; extra == 'drmcp'
|
|
43
|
+
Requires-Dist: python-dotenv<2.0.0,>=1.1.0; extra == 'drmcp'
|
|
44
44
|
Provides-Extra: langgraph
|
|
45
|
-
Requires-Dist: langchain-mcp-adapters
|
|
46
|
-
Requires-Dist: langgraph-prebuilt
|
|
47
|
-
Requires-Dist: langgraph
|
|
48
|
-
Requires-Dist: opentelemetry-instrumentation-langchain
|
|
45
|
+
Requires-Dist: langchain-mcp-adapters<0.2.0,>=0.1.12; extra == 'langgraph'
|
|
46
|
+
Requires-Dist: langgraph-prebuilt<0.7.0,>=0.2.3; extra == 'langgraph'
|
|
47
|
+
Requires-Dist: langgraph<0.7.0,>=0.4.10; extra == 'langgraph'
|
|
48
|
+
Requires-Dist: opentelemetry-instrumentation-langchain<1.0.0,>=0.40.5; extra == 'langgraph'
|
|
49
49
|
Provides-Extra: llamaindex
|
|
50
50
|
Requires-Dist: llama-index-core<0.14.0,>=0.13.6; extra == 'llamaindex'
|
|
51
|
-
Requires-Dist: llama-index-llms-langchain
|
|
52
|
-
Requires-Dist: llama-index-llms-litellm
|
|
53
|
-
Requires-Dist: llama-index-llms-openai
|
|
54
|
-
Requires-Dist: llama-index-tools-mcp
|
|
51
|
+
Requires-Dist: llama-index-llms-langchain<0.8.0,>=0.6.1; extra == 'llamaindex'
|
|
52
|
+
Requires-Dist: llama-index-llms-litellm<0.7.0,>=0.4.1; extra == 'llamaindex'
|
|
53
|
+
Requires-Dist: llama-index-llms-openai<0.6.0,>=0.3.38; extra == 'llamaindex'
|
|
54
|
+
Requires-Dist: llama-index-tools-mcp<0.5.0,>=0.1.0; extra == 'llamaindex'
|
|
55
55
|
Requires-Dist: llama-index<0.14.0,>=0.13.6; extra == 'llamaindex'
|
|
56
|
-
Requires-Dist: opentelemetry-instrumentation-llamaindex
|
|
57
|
-
Requires-Dist: pypdf
|
|
56
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex<1.0.0,>=0.40.5; extra == 'llamaindex'
|
|
57
|
+
Requires-Dist: pypdf<7.0.0,>=6.0.0; extra == 'llamaindex'
|
|
58
58
|
Provides-Extra: nat
|
|
59
|
-
Requires-Dist: llama-index-llms-litellm
|
|
59
|
+
Requires-Dist: llama-index-llms-litellm<0.7.0,>=0.4.1; extra == 'nat'
|
|
60
60
|
Requires-Dist: nvidia-nat-crewai==1.3.0; (python_version >= '3.11') and extra == 'nat'
|
|
61
61
|
Requires-Dist: nvidia-nat-langchain==1.3.0; (python_version >= '3.11') and extra == 'nat'
|
|
62
62
|
Requires-Dist: nvidia-nat-opentelemetry==1.3.0; (python_version >= '3.11') and extra == 'nat'
|
|
63
63
|
Requires-Dist: nvidia-nat==1.3.0; (python_version >= '3.11') and extra == 'nat'
|
|
64
|
-
Requires-Dist: opentelemetry-instrumentation-crewai
|
|
65
|
-
Requires-Dist: opentelemetry-instrumentation-langchain
|
|
66
|
-
Requires-Dist: opentelemetry-instrumentation-llamaindex
|
|
64
|
+
Requires-Dist: opentelemetry-instrumentation-crewai<1.0.0,>=0.40.5; extra == 'nat'
|
|
65
|
+
Requires-Dist: opentelemetry-instrumentation-langchain<1.0.0,>=0.40.5; extra == 'nat'
|
|
66
|
+
Requires-Dist: opentelemetry-instrumentation-llamaindex<1.0.0,>=0.40.5; extra == 'nat'
|
|
67
67
|
Provides-Extra: pydanticai
|
|
68
|
-
Requires-Dist: logfire
|
|
69
|
-
Requires-Dist: pydantic-ai
|
|
68
|
+
Requires-Dist: logfire<5.0.0,>=4.6.0; extra == 'pydanticai'
|
|
69
|
+
Requires-Dist: pydantic-ai<1.9.0,>=1.0.5; extra == 'pydanticai'
|
|
70
70
|
Description-Content-Type: text/markdown
|
|
71
71
|
|
|
72
72
|
<p align="center">
|
|
@@ -4,26 +4,26 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "datarobot-genai"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.64"
|
|
8
8
|
description = "Generic helpers for GenAI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10, <3.13"
|
|
11
11
|
license = { text = "Apache-2.0" }
|
|
12
12
|
authors = [{ name = "DataRobot, Inc." }]
|
|
13
13
|
dependencies = [
|
|
14
|
-
"requests>=2.32.4",
|
|
15
|
-
"datarobot>=3.9.1",
|
|
16
|
-
"datarobot-predict>=1.13.2",
|
|
17
|
-
"openai>=1.76.2",
|
|
18
|
-
"pandas>=2.2.3",
|
|
19
|
-
"ragas>=0.3.8",
|
|
20
|
-
"pyjwt>=2.10.1",
|
|
21
|
-
"pypdf>=6.1.3", # CVE BUZZOK-28182
|
|
22
|
-
"datarobot-drum>=1.17.5",
|
|
23
|
-
"opentelemetry-instrumentation-requests>=0.43b0",
|
|
24
|
-
"opentelemetry-instrumentation-aiohttp-client>=0.43b0",
|
|
25
|
-
"opentelemetry-instrumentation-httpx>=0.43b0",
|
|
26
|
-
"opentelemetry-instrumentation-openai>=0.40.5",
|
|
14
|
+
"requests>=2.32.4,<3.0.0",
|
|
15
|
+
"datarobot>=3.9.1,<4.0.0",
|
|
16
|
+
"datarobot-predict>=1.13.2,<2.0.0",
|
|
17
|
+
"openai>=1.76.2,<2.0.0",
|
|
18
|
+
"pandas>=2.2.3,<3.0.0",
|
|
19
|
+
"ragas>=0.3.8,<0.4.0",
|
|
20
|
+
"pyjwt>=2.10.1,<3.0.0",
|
|
21
|
+
"pypdf>=6.1.3,<7.0.0", # CVE BUZZOK-28182
|
|
22
|
+
"datarobot-drum>=1.17.5,<2.0.0",
|
|
23
|
+
"opentelemetry-instrumentation-requests>=0.43b0,<1.0.0",
|
|
24
|
+
"opentelemetry-instrumentation-aiohttp-client>=0.43b0,<1.0.0",
|
|
25
|
+
"opentelemetry-instrumentation-httpx>=0.43b0,<1.0.0",
|
|
26
|
+
"opentelemetry-instrumentation-openai>=0.40.5,<1.0.0",
|
|
27
27
|
]
|
|
28
28
|
|
|
29
29
|
[project.urls]
|
|
@@ -35,55 +35,55 @@ datarobot_llm_clients = "datarobot_genai.nat.datarobot_llm_clients"
|
|
|
35
35
|
|
|
36
36
|
[project.optional-dependencies]
|
|
37
37
|
crewai = [
|
|
38
|
-
"crewai>=0.193.2",
|
|
39
|
-
"crewai-tools[mcp]>=0.69.0",
|
|
40
|
-
"opentelemetry-instrumentation-crewai>=0.40.5",
|
|
41
|
-
"pybase64>=1.4.2",
|
|
38
|
+
"crewai>=0.193.2,<1.0.0",
|
|
39
|
+
"crewai-tools[mcp]>=0.69.0,<0.77.0",
|
|
40
|
+
"opentelemetry-instrumentation-crewai>=0.40.5,<1.0.0",
|
|
41
|
+
"pybase64>=1.4.2,<2.0.0",
|
|
42
42
|
]
|
|
43
43
|
langgraph = [
|
|
44
|
-
"langchain-mcp-adapters>=0.1.12",
|
|
45
|
-
"langgraph>=0.4.10",
|
|
46
|
-
"langgraph-prebuilt>=0.2.3",
|
|
47
|
-
"opentelemetry-instrumentation-langchain>=0.40.5",
|
|
44
|
+
"langchain-mcp-adapters>=0.1.12,<0.2.0",
|
|
45
|
+
"langgraph>=0.4.10,<0.7.0",
|
|
46
|
+
"langgraph-prebuilt>=0.2.3,<0.7.0",
|
|
47
|
+
"opentelemetry-instrumentation-langchain>=0.40.5,<1.0.0",
|
|
48
48
|
]
|
|
49
49
|
llamaindex = [
|
|
50
50
|
"llama-index>=0.13.6,<0.14.0",
|
|
51
51
|
"llama-index-core>=0.13.6,<0.14.0",
|
|
52
|
-
"llama-index-llms-langchain>=0.6.1",
|
|
53
|
-
"llama-index-llms-litellm>=0.4.1", # Sync nat dependency if possible too
|
|
54
|
-
"llama-index-llms-openai>=0.3.38",
|
|
55
|
-
"llama-index-tools-mcp>=0.1.0",
|
|
56
|
-
"opentelemetry-instrumentation-llamaindex>=0.40.5",
|
|
57
|
-
"pypdf>=6.0.0",
|
|
52
|
+
"llama-index-llms-langchain>=0.6.1,<0.8.0",
|
|
53
|
+
"llama-index-llms-litellm>=0.4.1,<0.7.0", # Sync nat dependency if possible too
|
|
54
|
+
"llama-index-llms-openai>=0.3.38,<0.6.0",
|
|
55
|
+
"llama-index-tools-mcp>=0.1.0,<0.5.0",
|
|
56
|
+
"opentelemetry-instrumentation-llamaindex>=0.40.5,<1.0.0",
|
|
57
|
+
"pypdf>=6.0.0,<7.0.0",
|
|
58
58
|
]
|
|
59
59
|
nat = [
|
|
60
60
|
"nvidia-nat==1.3.0; python_version >= '3.11'",
|
|
61
61
|
"nvidia-nat-opentelemetry==1.3.0; python_version >= '3.11'",
|
|
62
62
|
"nvidia-nat-crewai==1.3.0; python_version >= '3.11'",
|
|
63
63
|
"nvidia-nat-langchain==1.3.0; python_version >= '3.11'",
|
|
64
|
-
"llama-index-llms-litellm>=0.4.1", # Need this to support datarobot-llm plugin
|
|
65
|
-
"opentelemetry-instrumentation-crewai>=0.40.5",
|
|
66
|
-
"opentelemetry-instrumentation-llamaindex>=0.40.5",
|
|
67
|
-
"opentelemetry-instrumentation-langchain>=0.40.5",
|
|
64
|
+
"llama-index-llms-litellm>=0.4.1,<0.7.0", # Need this to support datarobot-llm plugin
|
|
65
|
+
"opentelemetry-instrumentation-crewai>=0.40.5,<1.0.0",
|
|
66
|
+
"opentelemetry-instrumentation-llamaindex>=0.40.5,<1.0.0",
|
|
67
|
+
"opentelemetry-instrumentation-langchain>=0.40.5,<1.0.0",
|
|
68
68
|
]
|
|
69
69
|
pydanticai = [
|
|
70
|
-
"logfire>=4.6.0",
|
|
71
|
-
"pydantic-ai>=1.0.5",
|
|
70
|
+
"logfire>=4.6.0,<5.0.0",
|
|
71
|
+
"pydantic-ai>=1.0.5,<1.9.0",
|
|
72
72
|
]
|
|
73
73
|
drmcp = [
|
|
74
|
-
"datarobot-asgi-middleware>=0.2.0",
|
|
75
|
-
"python-dotenv>=1.1.0",
|
|
76
|
-
"boto3>=1.34.0",
|
|
77
|
-
"httpx>=0.28.1",
|
|
78
|
-
"pydantic>=2.6.1",
|
|
79
|
-
"pydantic-settings>=2.1.0",
|
|
80
|
-
"opentelemetry-api>=1.22.0",
|
|
81
|
-
"opentelemetry-sdk>=1.22.0",
|
|
82
|
-
"opentelemetry-exporter-otlp>=1.22.0",
|
|
83
|
-
"opentelemetry-exporter-otlp-proto-http>=1.22.0",
|
|
84
|
-
"aiohttp>=3.9.0",
|
|
85
|
-
"aiohttp-retry>=2.8.3",
|
|
86
|
-
"aiosignal>=1.3.1",
|
|
74
|
+
"datarobot-asgi-middleware>=0.2.0,<1.0.0",
|
|
75
|
+
"python-dotenv>=1.1.0,<2.0.0",
|
|
76
|
+
"boto3>=1.34.0,<2.0.0",
|
|
77
|
+
"httpx>=0.28.1,<1.0.0",
|
|
78
|
+
"pydantic>=2.6.1,<3.0.0",
|
|
79
|
+
"pydantic-settings>=2.1.0,<3.0.0",
|
|
80
|
+
"opentelemetry-api>=1.22.0,<2.0.0",
|
|
81
|
+
"opentelemetry-sdk>=1.22.0,<2.0.0",
|
|
82
|
+
"opentelemetry-exporter-otlp>=1.22.0,<2.0.0",
|
|
83
|
+
"opentelemetry-exporter-otlp-proto-http>=1.22.0,<2.0.0",
|
|
84
|
+
"aiohttp>=3.9.0,<4.0.0",
|
|
85
|
+
"aiohttp-retry>=2.8.3,<3.0.0",
|
|
86
|
+
"aiosignal>=1.3.1,<2.0.0",
|
|
87
87
|
"fastmcp==2.13.0.2",
|
|
88
88
|
]
|
|
89
89
|
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Copyright 2025 DataRobot, Inc. and its affiliates.
|
|
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
|
+
import json
|
|
16
|
+
import re
|
|
17
|
+
from typing import Any
|
|
18
|
+
from typing import Literal
|
|
19
|
+
|
|
20
|
+
from datarobot.core.config import DataRobotAppFrameworkBaseSettings
|
|
21
|
+
from pydantic import field_validator
|
|
22
|
+
|
|
23
|
+
from datarobot_genai.core.utils.auth import AuthContextHeaderHandler
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class MCPConfig(DataRobotAppFrameworkBaseSettings):
|
|
27
|
+
"""Configuration for MCP server connection.
|
|
28
|
+
|
|
29
|
+
Derived values are exposed as properties rather than stored, avoiding
|
|
30
|
+
Pydantic field validation/serialization concerns for internal helpers.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
external_mcp_url: str | None = None
|
|
34
|
+
external_mcp_headers: str | None = None
|
|
35
|
+
external_mcp_transport: Literal["sse", "streamable-http"] = "streamable-http"
|
|
36
|
+
mcp_deployment_id: str | None = None
|
|
37
|
+
datarobot_endpoint: str | None = None
|
|
38
|
+
datarobot_api_token: str | None = None
|
|
39
|
+
authorization_context: dict[str, Any] | None = None
|
|
40
|
+
|
|
41
|
+
_auth_context_handler: AuthContextHeaderHandler | None = None
|
|
42
|
+
_server_config: dict[str, Any] | None = None
|
|
43
|
+
|
|
44
|
+
@field_validator("external_mcp_headers", mode="before")
|
|
45
|
+
@classmethod
|
|
46
|
+
def validate_external_mcp_headers(cls, value: str | None) -> str | None:
|
|
47
|
+
if value is None:
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
if not isinstance(value, str):
|
|
51
|
+
msg = "external_mcp_headers must be a JSON string"
|
|
52
|
+
raise TypeError(msg)
|
|
53
|
+
|
|
54
|
+
candidate = value.strip()
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
json.loads(candidate)
|
|
58
|
+
except json.JSONDecodeError as exc:
|
|
59
|
+
msg = "external_mcp_headers must be valid JSON"
|
|
60
|
+
raise ValueError(msg) from exc
|
|
61
|
+
|
|
62
|
+
return candidate
|
|
63
|
+
|
|
64
|
+
@field_validator("mcp_deployment_id", mode="before")
|
|
65
|
+
@classmethod
|
|
66
|
+
def validate_mcp_deployment_id(cls, value: str | None) -> str | None:
|
|
67
|
+
if value is None:
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
if not isinstance(value, str):
|
|
71
|
+
msg = "mcp_deployment_id must be a string"
|
|
72
|
+
raise TypeError(msg)
|
|
73
|
+
|
|
74
|
+
candidate = value.strip()
|
|
75
|
+
|
|
76
|
+
if not re.fullmatch(r"[0-9a-fA-F]{24}", candidate):
|
|
77
|
+
msg = "mcp_deployment_id must be a valid 24-character hex ID"
|
|
78
|
+
raise ValueError(msg)
|
|
79
|
+
|
|
80
|
+
return candidate
|
|
81
|
+
|
|
82
|
+
def _authorization_bearer_header(self) -> dict[str, str]:
|
|
83
|
+
"""Return Authorization header with Bearer token or empty dict."""
|
|
84
|
+
if not self.datarobot_api_token:
|
|
85
|
+
return {}
|
|
86
|
+
auth = (
|
|
87
|
+
self.datarobot_api_token
|
|
88
|
+
if self.datarobot_api_token.startswith("Bearer ")
|
|
89
|
+
else f"Bearer {self.datarobot_api_token}"
|
|
90
|
+
)
|
|
91
|
+
return {"Authorization": auth}
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def auth_context_handler(self) -> AuthContextHeaderHandler:
|
|
95
|
+
if self._auth_context_handler is None:
|
|
96
|
+
self._auth_context_handler = AuthContextHeaderHandler()
|
|
97
|
+
return self._auth_context_handler
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def server_config(self) -> dict[str, Any] | None:
|
|
101
|
+
if self._server_config is None:
|
|
102
|
+
self._server_config = self._build_server_config()
|
|
103
|
+
return self._server_config
|
|
104
|
+
|
|
105
|
+
def _authorization_context_header(self) -> dict[str, str]:
|
|
106
|
+
"""Return X-DataRobot-Authorization-Context header or empty dict."""
|
|
107
|
+
try:
|
|
108
|
+
return self.auth_context_handler.get_header(self.authorization_context)
|
|
109
|
+
except (LookupError, RuntimeError):
|
|
110
|
+
# Authorization context not available (e.g., in tests)
|
|
111
|
+
return {}
|
|
112
|
+
|
|
113
|
+
def _build_server_config(self) -> dict[str, Any] | None:
|
|
114
|
+
"""
|
|
115
|
+
Get MCP server configuration.
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
Server configuration dict with url, transport, and optional headers,
|
|
120
|
+
or None if not configured.
|
|
121
|
+
"""
|
|
122
|
+
if self.external_mcp_url:
|
|
123
|
+
# External MCP URL - no authentication needed
|
|
124
|
+
if self.external_mcp_headers:
|
|
125
|
+
headers = json.loads(self.external_mcp_headers)
|
|
126
|
+
else:
|
|
127
|
+
headers = {}
|
|
128
|
+
|
|
129
|
+
config = {
|
|
130
|
+
"url": self.external_mcp_url.rstrip("/"),
|
|
131
|
+
"transport": self.external_mcp_transport,
|
|
132
|
+
"headers": headers,
|
|
133
|
+
}
|
|
134
|
+
return config
|
|
135
|
+
elif self.mcp_deployment_id:
|
|
136
|
+
# DataRobot deployment ID - requires authentication
|
|
137
|
+
if self.datarobot_endpoint is None:
|
|
138
|
+
raise ValueError(
|
|
139
|
+
"When using a DataRobot hosted MCP deployment, datarobot_endpoint must be set."
|
|
140
|
+
)
|
|
141
|
+
if self.datarobot_api_token is None:
|
|
142
|
+
raise ValueError(
|
|
143
|
+
"When using a DataRobot hosted MCP deployment, datarobot_api_token must be set."
|
|
144
|
+
)
|
|
145
|
+
base_url = self.datarobot_endpoint.rstrip("/")
|
|
146
|
+
if not base_url.endswith("/api/v2"):
|
|
147
|
+
base_url = base_url + "/api/v2"
|
|
148
|
+
url = f"{base_url}/deployments/{self.mcp_deployment_id}/directAccess/mcp"
|
|
149
|
+
|
|
150
|
+
headers = {
|
|
151
|
+
**self._authorization_bearer_header(),
|
|
152
|
+
**self._authorization_context_header(),
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
"url": url,
|
|
157
|
+
"transport": "streamable-http",
|
|
158
|
+
"headers": headers,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return None
|
{datarobot_genai-0.1.55 → datarobot_genai-0.1.64}/src/datarobot_genai/core/telemetry_agent.py
RENAMED
|
@@ -28,10 +28,22 @@ logging.getLogger("opentelemetry.instrumentation.instrumentor").setLevel(logging
|
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
29
29
|
|
|
30
30
|
# Internal instrumentation state to avoid 'global' mutation warnings
|
|
31
|
-
_INSTRUMENTATION_STATE = {"http": False, "openai": False}
|
|
31
|
+
_INSTRUMENTATION_STATE = {"http": False, "openai": False, "threading": False}
|
|
32
32
|
_INSTRUMENTED_FRAMEWORKS: set[str] = set()
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
def _instrument_threading() -> None:
|
|
36
|
+
if _INSTRUMENTATION_STATE["threading"]:
|
|
37
|
+
return
|
|
38
|
+
try:
|
|
39
|
+
threading_module = importlib.import_module("opentelemetry.instrumentation.threading")
|
|
40
|
+
threading_instrumentor = getattr(threading_module, "ThreadingInstrumentor")
|
|
41
|
+
threading_instrumentor().instrument()
|
|
42
|
+
_INSTRUMENTATION_STATE["threading"] = True
|
|
43
|
+
except Exception as e:
|
|
44
|
+
logger.debug(f"threading instrumentation skipped: {e}")
|
|
45
|
+
|
|
46
|
+
|
|
35
47
|
def _instrument_http_clients() -> None:
|
|
36
48
|
if _INSTRUMENTATION_STATE["http"]:
|
|
37
49
|
return
|
|
@@ -107,6 +119,7 @@ def instrument(
|
|
|
107
119
|
os.environ.setdefault("RAGAS_DO_NOT_TRACK", "true")
|
|
108
120
|
os.environ.setdefault("DEEPEVAL_TELEMETRY_OPT_OUT", "YES")
|
|
109
121
|
|
|
122
|
+
_instrument_threading()
|
|
110
123
|
_instrument_http_clients()
|
|
111
124
|
_instrument_openai()
|
|
112
125
|
if framework:
|
|
@@ -16,9 +16,14 @@ import warnings
|
|
|
16
16
|
from typing import Any
|
|
17
17
|
|
|
18
18
|
import jwt
|
|
19
|
+
from datarobot.auth.datarobot.oauth import AsyncOAuth as DatarobotAsyncOAuthClient
|
|
20
|
+
from datarobot.auth.identity import Identity
|
|
21
|
+
from datarobot.auth.oauth import AsyncOAuthComponent
|
|
19
22
|
from datarobot.auth.session import AuthCtx
|
|
20
23
|
from datarobot.core.config import DataRobotAppFrameworkBaseSettings
|
|
24
|
+
from datarobot.models.genai.agent.auth import ToolAuth
|
|
21
25
|
from datarobot.models.genai.agent.auth import get_authorization_context
|
|
26
|
+
from pydantic import BaseModel
|
|
22
27
|
|
|
23
28
|
logger = logging.getLogger(__name__)
|
|
24
29
|
|
|
@@ -27,6 +32,13 @@ class AuthContextConfig(DataRobotAppFrameworkBaseSettings):
|
|
|
27
32
|
session_secret_key: str = ""
|
|
28
33
|
|
|
29
34
|
|
|
35
|
+
class DRAppCtx(BaseModel):
|
|
36
|
+
"""DataRobot application context from authorization metadata."""
|
|
37
|
+
|
|
38
|
+
email: str | None = None
|
|
39
|
+
api_key: str | None = None
|
|
40
|
+
|
|
41
|
+
|
|
30
42
|
class AuthContextHeaderHandler:
|
|
31
43
|
"""Manages encoding and decoding of authorization context into JWT tokens.
|
|
32
44
|
|
|
@@ -146,6 +158,7 @@ class AuthContextHeaderHandler:
|
|
|
146
158
|
|
|
147
159
|
auth_ctx_dict = self.decode(token)
|
|
148
160
|
if not auth_ctx_dict:
|
|
161
|
+
logger.debug("Failed to decode auth context from token")
|
|
149
162
|
return None
|
|
150
163
|
|
|
151
164
|
try:
|
|
@@ -153,3 +166,54 @@ class AuthContextHeaderHandler:
|
|
|
153
166
|
except Exception as e:
|
|
154
167
|
logger.error(f"Failed to create AuthCtx from decoded token: {e}", exc_info=True)
|
|
155
168
|
return None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class AsyncOAuthTokenProvider:
|
|
172
|
+
"""Manages OAuth access tokens using generic OAuth client."""
|
|
173
|
+
|
|
174
|
+
def __init__(self, auth_ctx: AuthCtx) -> None:
|
|
175
|
+
self.auth_ctx = auth_ctx
|
|
176
|
+
self.oauth_client = self._create_oauth_client()
|
|
177
|
+
|
|
178
|
+
def _get_identity(self, provider_type: str | None) -> Identity:
|
|
179
|
+
"""Retrieve the appropriate identity from the authentication context."""
|
|
180
|
+
identities = [x for x in self.auth_ctx.identities if x.provider_identity_id is not None]
|
|
181
|
+
|
|
182
|
+
if not identities:
|
|
183
|
+
raise ValueError("No identities found in authorization context.")
|
|
184
|
+
|
|
185
|
+
if provider_type is None:
|
|
186
|
+
if len(identities) > 1:
|
|
187
|
+
raise ValueError(
|
|
188
|
+
"Multiple identities found. Please specify 'provider_type' parameter."
|
|
189
|
+
)
|
|
190
|
+
return identities[0]
|
|
191
|
+
|
|
192
|
+
identity = next((id for id in identities if id.provider_type == provider_type), None)
|
|
193
|
+
|
|
194
|
+
if identity is None:
|
|
195
|
+
raise ValueError(f"No identity found for provider '{provider_type}'.")
|
|
196
|
+
|
|
197
|
+
return identity
|
|
198
|
+
|
|
199
|
+
async def get_token(self, auth_type: ToolAuth, provider_type: str | None = None) -> str:
|
|
200
|
+
"""Get OAuth access token using the specified method."""
|
|
201
|
+
if auth_type != ToolAuth.OBO:
|
|
202
|
+
raise ValueError(
|
|
203
|
+
f"Unsupported auth type: {auth_type}. Only {ToolAuth.OBO} is supported."
|
|
204
|
+
)
|
|
205
|
+
|
|
206
|
+
identity = self._get_identity(provider_type)
|
|
207
|
+
token_data = await self.oauth_client.refresh_access_token(
|
|
208
|
+
identity_id=identity.provider_identity_id
|
|
209
|
+
)
|
|
210
|
+
return token_data.access_token
|
|
211
|
+
|
|
212
|
+
def _create_oauth_client(self) -> AsyncOAuthComponent:
|
|
213
|
+
"""Create either DataRobot or Authlib OAuth client based on
|
|
214
|
+
authorization context.
|
|
215
|
+
|
|
216
|
+
Note: at the moment, only DataRobot OAuth client is supported.
|
|
217
|
+
"""
|
|
218
|
+
logger.debug("Using DataRobot OAuth client")
|
|
219
|
+
return DatarobotAsyncOAuthClient()
|
|
@@ -92,8 +92,6 @@ class CrewAIAgent(BaseAgent[BaseTool], abc.ABC):
|
|
|
92
92
|
|
|
93
93
|
# Use MCP context manager to handle connection lifecycle
|
|
94
94
|
with mcp_tools_context(
|
|
95
|
-
api_base=self.api_base,
|
|
96
|
-
api_key=self.api_key,
|
|
97
95
|
authorization_context=self._authorization_context,
|
|
98
96
|
) as mcp_tools:
|
|
99
97
|
# Set MCP tools for all agents if MCP is not configured this is effectively a no-op
|
|
@@ -29,15 +29,10 @@ from datarobot_genai.core.mcp.common import MCPConfig
|
|
|
29
29
|
|
|
30
30
|
@contextmanager
|
|
31
31
|
def mcp_tools_context(
|
|
32
|
-
api_base: str | None = None,
|
|
33
|
-
api_key: str | None = None,
|
|
34
32
|
authorization_context: dict[str, Any] | None = None,
|
|
35
33
|
) -> Generator[list[Any], None, None]:
|
|
36
34
|
"""Context manager for MCP tools that handles connection lifecycle."""
|
|
37
|
-
config = MCPConfig(
|
|
38
|
-
api_base=api_base, api_key=api_key, authorization_context=authorization_context
|
|
39
|
-
)
|
|
40
|
-
|
|
35
|
+
config = MCPConfig(authorization_context=authorization_context)
|
|
41
36
|
# If no MCP server configured, return empty tools list
|
|
42
37
|
if not config.server_config:
|
|
43
38
|
print("No MCP server configured, using empty tools list", flush=True)
|
|
@@ -47,10 +42,8 @@ def mcp_tools_context(
|
|
|
47
42
|
print(f"Connecting to MCP server: {config.server_config['url']}", flush=True)
|
|
48
43
|
|
|
49
44
|
# Use MCPServerAdapter as context manager with the server config
|
|
50
|
-
adapter_setting = config.server_config.copy()
|
|
51
|
-
adapter_setting["transport"] = "streamable-http"
|
|
52
45
|
try:
|
|
53
|
-
with MCPServerAdapter(
|
|
46
|
+
with MCPServerAdapter(config.server_config) as tools:
|
|
54
47
|
print(
|
|
55
48
|
f"Successfully connected to MCP server, got {len(tools)} tools",
|
|
56
49
|
flush=True,
|