datarobot-genai 0.2.26__py3-none-any.whl → 0.2.28__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.
@@ -0,0 +1,198 @@
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
+ """Microsoft Graph MCP tools for searching SharePoint and OneDrive content."""
16
+
17
+ import logging
18
+ from typing import Annotated
19
+
20
+ from fastmcp.exceptions import ToolError
21
+ from fastmcp.tools.tool import ToolResult
22
+
23
+ from datarobot_genai.drmcp.core.mcp_instance import dr_mcp_tool
24
+ from datarobot_genai.drmcp.tools.clients.microsoft_graph import MicrosoftGraphClient
25
+ from datarobot_genai.drmcp.tools.clients.microsoft_graph import MicrosoftGraphError
26
+ from datarobot_genai.drmcp.tools.clients.microsoft_graph import get_microsoft_graph_access_token
27
+ from datarobot_genai.drmcp.tools.clients.microsoft_graph import validate_site_url
28
+
29
+ logger = logging.getLogger(__name__)
30
+
31
+
32
+ @dr_mcp_tool(
33
+ tags={
34
+ "microsoft",
35
+ "graph api",
36
+ "sharepoint",
37
+ "drive",
38
+ "list",
39
+ "search",
40
+ "files",
41
+ "find",
42
+ "contents",
43
+ }
44
+ )
45
+ async def microsoft_graph_search_content(
46
+ *,
47
+ search_query: Annotated[str, "The search string to find files, folders, or list items."],
48
+ site_url: Annotated[
49
+ str | None,
50
+ "Optional SharePoint site URL to scope the search "
51
+ "(e.g., https://tenant.sharepoint.com/sites/sitename). "
52
+ "If not provided, searches across all accessible sites.",
53
+ ] = None,
54
+ site_id: Annotated[
55
+ str | None,
56
+ "Optional ID of the site to scope the search. If provided, takes precedence over site_url.",
57
+ ] = None,
58
+ from_offset: Annotated[
59
+ int,
60
+ "The zero-based index of the first result to return. Use this for pagination. "
61
+ "Default: 0 (start from the beginning). To get the next page, increment by the size "
62
+ "value (e.g., first page: from=0 size=250, second page: from=250 size=250, "
63
+ "third page: from=500 size=250).",
64
+ ] = 0,
65
+ size: Annotated[
66
+ int,
67
+ "Maximum number of results to return in this request. Default is 250, max is 250. "
68
+ "The LLM should control pagination by making multiple calls with different 'from' values.",
69
+ ] = 250,
70
+ entity_types: Annotated[
71
+ list[str] | None,
72
+ "Optional list of entity types to search. Valid values: 'driveItem', 'listItem', "
73
+ "'site', 'list', 'drive'. Default: ['driveItem', 'listItem']. "
74
+ "Multiple types can be specified.",
75
+ ] = None,
76
+ filters: Annotated[
77
+ list[str] | None,
78
+ "Optional list of KQL filter expressions to refine search results "
79
+ "(e.g., ['fileType:docx', 'size>1000']).",
80
+ ] = None,
81
+ include_hidden_content: Annotated[
82
+ bool,
83
+ "Whether to include hidden content in search results. Only works with delegated "
84
+ "permissions, not application permissions. Default: False.",
85
+ ] = False,
86
+ region: Annotated[
87
+ str | None,
88
+ "Optional region code for application permissions (e.g., 'NAM', 'EUR', 'APC'). "
89
+ "Required when using application permissions to search SharePoint content in "
90
+ "specific regions.",
91
+ ] = None,
92
+ ) -> ToolResult | ToolError:
93
+ """
94
+ Search for SharePoint and OneDrive content using Microsoft Graph Search API.
95
+
96
+ Search Scope:
97
+ - When site_url or site_id is provided: searches within the specified SharePoint site
98
+ - When neither is provided: searches across all accessible SharePoint sites and OneDrive
99
+
100
+ Supported Entity Types:
101
+ - driveItem: Files and folders in document libraries and OneDrive
102
+ - listItem: Items in SharePoint lists
103
+ - site: SharePoint sites
104
+ - list: SharePoint lists
105
+ - drive: Document libraries/drives
106
+
107
+ Filtering:
108
+ - Filters use KQL (Keyword Query Language) syntax
109
+ - Multiple filters are combined with AND operators
110
+ - Examples: ['fileType:docx', 'size>1000', 'lastModifiedTime>2024-01-01']
111
+ - Filters are applied in addition to the search query
112
+
113
+ Pagination:
114
+ - Controlled via from_offset (zero-based index) and size parameters
115
+ - Maximum size per request: 250 results
116
+ - To paginate: increment from_offset by size value for each subsequent page
117
+ - Example pagination sequence:
118
+ * Page 1: from_offset=0, size=250 (returns results 0-249)
119
+ * Page 2: from_offset=250, size=250 (returns results 250-499)
120
+ * Page 3: from_offset=500, size=250 (returns results 500-749)
121
+
122
+ API Reference:
123
+ - Endpoint: POST /search/query
124
+ - Documentation: https://learn.microsoft.com/en-us/graph/api/search-query
125
+ - Search concepts: https://learn.microsoft.com/en-us/graph/search-concept-files
126
+
127
+ Permissions:
128
+ - Requires Sites.Read.All or Sites.Search.All permission
129
+ - include_hidden_content only works with delegated permissions
130
+ - region parameter is required for application permissions in multi-region environments
131
+ """
132
+ if not search_query:
133
+ raise ToolError("Argument validation error: 'search_query' cannot be empty.")
134
+
135
+ # Validate site_url if provided
136
+ if site_url:
137
+ validation_error = validate_site_url(site_url)
138
+ if validation_error:
139
+ raise ToolError(validation_error)
140
+
141
+ access_token = await get_microsoft_graph_access_token()
142
+ if isinstance(access_token, ToolError):
143
+ raise access_token
144
+
145
+ try:
146
+ async with MicrosoftGraphClient(access_token=access_token, site_url=site_url) as client:
147
+ items = await client.search_content(
148
+ search_query=search_query,
149
+ site_id=site_id,
150
+ from_offset=from_offset,
151
+ size=size,
152
+ entity_types=entity_types,
153
+ filters=filters,
154
+ include_hidden_content=include_hidden_content,
155
+ region=region,
156
+ )
157
+ except MicrosoftGraphError as e:
158
+ logger.error(f"Microsoft Graph error searching content: {e}")
159
+ raise ToolError(str(e))
160
+ except Exception as e:
161
+ logger.error(f"Unexpected error searching Microsoft Graph content: {e}", exc_info=True)
162
+ raise ToolError(
163
+ f"An unexpected error occurred while searching Microsoft Graph content: {str(e)}"
164
+ )
165
+
166
+ results = []
167
+ for item in items:
168
+ result_dict = {
169
+ "id": item.id, # Unique ID of the file, folder, or list item
170
+ "name": item.name,
171
+ "webUrl": item.web_url,
172
+ "size": item.size,
173
+ "createdDateTime": item.created_datetime,
174
+ "lastModifiedDateTime": item.last_modified_datetime,
175
+ "isFolder": item.is_folder,
176
+ "mimeType": item.mime_type,
177
+ # Document library/drive ID (driveId in Microsoft Graph API)
178
+ "documentLibraryId": item.drive_id,
179
+ "parentFolderId": item.parent_folder_id, # Parent folder ID
180
+ }
181
+ results.append(result_dict)
182
+
183
+ n = len(results)
184
+ return ToolResult(
185
+ content=(
186
+ f"Successfully searched Microsoft Graph and retrieved {n} result(s) for "
187
+ f"'{search_query}' (from={from_offset}, size={size})."
188
+ ),
189
+ structured_content={
190
+ "query": search_query,
191
+ "siteUrl": site_url,
192
+ "siteId": site_id,
193
+ "from": from_offset,
194
+ "size": size,
195
+ "results": results,
196
+ "count": n,
197
+ },
198
+ )
@@ -12,6 +12,7 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ import json
15
16
  import logging
16
17
  import os
17
18
  from typing import Annotated
@@ -28,6 +29,7 @@ logger = logging.getLogger(__name__)
28
29
 
29
30
  @dr_mcp_tool(tags={"predictive", "data", "write", "upload", "catalog"})
30
31
  async def upload_dataset_to_ai_catalog(
32
+ *,
31
33
  file_path: Annotated[str, "The path to the dataset file to upload."] | None = None,
32
34
  file_url: Annotated[str, "The URL to the dataset file to upload."] | None = None,
33
35
  ) -> ToolError | ToolResult:
@@ -80,11 +82,17 @@ async def list_ai_catalog_items() -> ToolResult:
80
82
  structured_content={"datasets": []},
81
83
  )
82
84
 
85
+ datasets_dict = {ds.id: ds.name for ds in datasets}
86
+ datasets_count = len(datasets)
87
+
83
88
  return ToolResult(
84
- content=f"Found {len(datasets)} AI Catalog items.",
89
+ content=(
90
+ f"Found {datasets_count} AI Catalog items, here are the details:\n"
91
+ f"{json.dumps(datasets_dict, indent=2)}"
92
+ ),
85
93
  structured_content={
86
- "datasets": [{"id": ds.id, "name": ds.name} for ds in datasets],
87
- "count": len(datasets),
94
+ "datasets": datasets_dict,
95
+ "count": datasets_count,
88
96
  },
89
97
  )
90
98
 
@@ -617,6 +617,7 @@ async def get_model_feature_impact(
617
617
 
618
618
  @dr_mcp_tool(tags={"predictive", "training", "read", "model", "evaluation"})
619
619
  async def get_model_lift_chart(
620
+ *,
620
621
  project_id: Annotated[str, "The ID of the DataRobot project"] | None = None,
621
622
  model_id: Annotated[str, "The ID of the model to analyze"] | None = None,
622
623
  source: Annotated[
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datarobot-genai
3
- Version: 0.2.26
3
+ Version: 0.2.28
4
4
  Summary: Generic helpers for GenAI
5
5
  Project-URL: Homepage, https://github.com/datarobot-oss/datarobot-genai
6
6
  Author: DataRobot, Inc.
@@ -27,7 +27,7 @@ datarobot_genai/drmcp/server.py,sha256=KE4kjS5f9bfdYftG14HBHrfvxDfCD4pwCXePfvl1O
27
27
  datarobot_genai/drmcp/core/__init__.py,sha256=y4yapzp3KnFMzSR6HlNDS4uSuyNT7I1iPBvaCLsS0sU,577
28
28
  datarobot_genai/drmcp/core/auth.py,sha256=E-5wrGbBFEBlD5377g6Exddrc7HsazamwX8tWr2RLXY,5815
29
29
  datarobot_genai/drmcp/core/clients.py,sha256=y-yG8617LbmiZ_L7FWfMrk4WjIekyr76u_Q80aLqGpI,5524
30
- datarobot_genai/drmcp/core/config.py,sha256=69QDsVVSvjzv1uIHOjtQGzdg7_Ic4sA3vLA6ZbZJ1Ok,12674
30
+ datarobot_genai/drmcp/core/config.py,sha256=SWLhVKoqI4vmA-04TFKpKm1_G2yEMEN1e_8cv8d_XRM,13774
31
31
  datarobot_genai/drmcp/core/config_utils.py,sha256=U-aieWw7MyP03cGDFIp97JH99ZUfr3vD9uuTzBzxn7w,6428
32
32
  datarobot_genai/drmcp/core/constants.py,sha256=lUwoW_PTrbaBGqRJifKqCn3EoFacoEgdO-CpoFVrUoU,739
33
33
  datarobot_genai/drmcp/core/credentials.py,sha256=PYEUDNMVw1BoMzZKLkPVTypNkVevEPtmk3scKnE-zYg,6706
@@ -40,7 +40,7 @@ datarobot_genai/drmcp/core/routes.py,sha256=dqE2M0UzAyyN9vQjlyTjYW4rpju3LT039po5
40
40
  datarobot_genai/drmcp/core/routes_utils.py,sha256=vSseXWlplMSnRgoJgtP_rHxWSAVYcx_tpTv4lyTpQoc,944
41
41
  datarobot_genai/drmcp/core/server_life_cycle.py,sha256=WKGJWGxalvqxupzJ2y67Kklc_9PgpZT0uyjlv_sr5wc,3419
42
42
  datarobot_genai/drmcp/core/telemetry.py,sha256=NEkSTC1w6uQgtukLHI-sWvR4EMgInysgATcvfQ5CplM,15378
43
- datarobot_genai/drmcp/core/tool_config.py,sha256=5JCWO70ZH-K-34yS7vYJG2nl4i9UO_q_W9NCoWSXXno,3271
43
+ datarobot_genai/drmcp/core/tool_config.py,sha256=izUdM6dN3GRBzSBs-OagggM2dX5PGBnDbVv4N5bfWFI,3668
44
44
  datarobot_genai/drmcp/core/tool_filter.py,sha256=yKQlEtzyIeXGxZJkHbK36QI19vmgQkvqmfx5cTo2pp4,3156
45
45
  datarobot_genai/drmcp/core/utils.py,sha256=EvfpqKZ3tECMoxpIQ_tA_3rOgy6KJEYKC0lWZo_Daag,4517
46
46
  datarobot_genai/drmcp/core/dynamic_prompts/__init__.py,sha256=y4yapzp3KnFMzSR6HlNDS4uSuyNT7I1iPBvaCLsS0sU,577
@@ -72,30 +72,33 @@ datarobot_genai/drmcp/test_utils/mcp_utils_ete.py,sha256=46rH0fYYmUj7ygf968iRbdS
72
72
  datarobot_genai/drmcp/test_utils/mcp_utils_integration.py,sha256=sHA_BWtpgIAFp9IXiNkUeBartBMjLAauqkV9bYtCr-g,3874
73
73
  datarobot_genai/drmcp/test_utils/openai_llm_mcp_client.py,sha256=YgyqHK09MB-PBaqT34heqvmvYYFtLpzzSJt7xuTJmDg,11224
74
74
  datarobot_genai/drmcp/test_utils/test_interactive.py,sha256=guXvR8q2H6VUdmvIjEJcElQJCC6lQ-oTrzbD2EkHeCs,8025
75
- datarobot_genai/drmcp/test_utils/tool_base_ete.py,sha256=wmI-xcL0rSr56-ZoGNB8np0CZHAU583o8-Kw7fRwtMw,6232
75
+ datarobot_genai/drmcp/test_utils/tool_base_ete.py,sha256=3yMfOsz3LdHYywuE5BhdJDpTUowx37HsFSsMdBTxA80,9337
76
76
  datarobot_genai/drmcp/test_utils/utils.py,sha256=esGKFv8aO31-Qg3owayeWp32BYe1CdYOEutjjdbweCw,3048
77
77
  datarobot_genai/drmcp/tools/__init__.py,sha256=0kq9vMkF7EBsS6lkEdiLibmUrghTQqosHbZ5k-V9a5g,578
78
78
  datarobot_genai/drmcp/tools/clients/__init__.py,sha256=0kq9vMkF7EBsS6lkEdiLibmUrghTQqosHbZ5k-V9a5g,578
79
79
  datarobot_genai/drmcp/tools/clients/atlassian.py,sha256=__M_uz7FrcbKCYRzeMn24DCEYD6OmFx_LuywHCxgXsA,6472
80
80
  datarobot_genai/drmcp/tools/clients/confluence.py,sha256=h_G0By_kDnJeWDT_d-IREsaZ5-0xB5GoLXOqblYP5MA,20706
81
- datarobot_genai/drmcp/tools/clients/gdrive.py,sha256=e28XwX0C8E3nql85-_NbUEMB-4s0lsQ2f5spj9BgsgM,21455
81
+ datarobot_genai/drmcp/tools/clients/gdrive.py,sha256=8GztWTdpJ7Ir3NIvIoOHPzDscoR1Ui7Ct2IiKmuUzIc,26012
82
82
  datarobot_genai/drmcp/tools/clients/jira.py,sha256=Rm91JAyrNIqxu66-9rU1YqoRXVnWbEy-Ahvy6f6HlVg,9823
83
+ datarobot_genai/drmcp/tools/clients/microsoft_graph.py,sha256=PASGThDPE8zkBZqach8lurJL1y47DWUPLwvf9N6uLGM,19234
83
84
  datarobot_genai/drmcp/tools/clients/s3.py,sha256=GmwzvurFdNfvxOooA8g5S4osRysHYU0S9ypg_177Glg,953
84
85
  datarobot_genai/drmcp/tools/confluence/__init__.py,sha256=0kq9vMkF7EBsS6lkEdiLibmUrghTQqosHbZ5k-V9a5g,578
85
86
  datarobot_genai/drmcp/tools/confluence/tools.py,sha256=_-ws65WLK8KZP_mKkf4yJ7ZunR8qdyoiMwHQX47MSMw,12362
86
87
  datarobot_genai/drmcp/tools/gdrive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- datarobot_genai/drmcp/tools/gdrive/tools.py,sha256=EvoEr3AEI-xRldwCTZHiQfBRHQfLtgHuojTx8mXhlU4,7074
88
+ datarobot_genai/drmcp/tools/gdrive/tools.py,sha256=G8LlnGEINZqV83Q-b3ZliWkDjouhbozDam3w6GfA7s0,10711
88
89
  datarobot_genai/drmcp/tools/jira/__init__.py,sha256=0kq9vMkF7EBsS6lkEdiLibmUrghTQqosHbZ5k-V9a5g,578
89
90
  datarobot_genai/drmcp/tools/jira/tools.py,sha256=dfkqTU2HH-7n44hX80ODFacKq0p0LOchFcZtIIKFNMM,9687
91
+ datarobot_genai/drmcp/tools/microsoft_graph/__init__.py,sha256=CuOaMt1AJo7cHx_GuhO3s_aqxZas_wlDsoBorBsvbeU,577
92
+ datarobot_genai/drmcp/tools/microsoft_graph/tools.py,sha256=zJ-UA1TMhPOYcExvgWv0YBjDsSIDPA-U1SEbBrVfAc8,7744
90
93
  datarobot_genai/drmcp/tools/predictive/__init__.py,sha256=WuOHlNNEpEmcF7gVnhckruJRKU2qtmJLE3E7zoCGLDo,1030
91
- datarobot_genai/drmcp/tools/predictive/data.py,sha256=mt3PvIel4IUAZo0HLIs6QsTtRkuzX1qg-5PHI3IJ7E8,4455
94
+ datarobot_genai/drmcp/tools/predictive/data.py,sha256=sSFAmO6x0DSuolw8urhMaOj5PwfUH29oc2mEOZI3YU4,4631
92
95
  datarobot_genai/drmcp/tools/predictive/deployment.py,sha256=lm02Ayuo11L1hP41fgi3QpR1Eyty-Wc16rM0c8SgliM,3277
93
96
  datarobot_genai/drmcp/tools/predictive/deployment_info.py,sha256=BGEF_dmbxOBJR0n1Tt9TO2-iNTQSBTr-oQUyaxLZ0ZI,15297
94
97
  datarobot_genai/drmcp/tools/predictive/model.py,sha256=Yih5-KedJ-1yupPLXCJsCXOdyWWi9pRvgapXDlgXWJA,4891
95
98
  datarobot_genai/drmcp/tools/predictive/predict.py,sha256=Qoob2_t2crfWtyPzkXMRz2ITZumnczU6Dq4C7q9RBMI,9370
96
99
  datarobot_genai/drmcp/tools/predictive/predict_realtime.py,sha256=urq6rPyZFsAP-bPyclSNzrkvb6FTamdlFau8q0IWWJ0,13472
97
100
  datarobot_genai/drmcp/tools/predictive/project.py,sha256=xC52UdYvuFeNZC7Y5MfXcvzTL70WwAacQXESr6rqN6s,3255
98
- datarobot_genai/drmcp/tools/predictive/training.py,sha256=S9V7AlO6mAgIAJNww0g5agFOw4YqRiCsIGaRDJcOe4A,23991
101
+ datarobot_genai/drmcp/tools/predictive/training.py,sha256=LzMxbBT8wxKYDrRlVElfmTUrzpmGvwrR-mTGf6YUnIA,23998
99
102
  datarobot_genai/langgraph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
100
103
  datarobot_genai/langgraph/agent.py,sha256=DRnywmS9KDywyChtuIZZwNKbJs8BpC259EG_kxYbiQ8,15828
101
104
  datarobot_genai/langgraph/mcp.py,sha256=iA2_j46mZAaNaL7ntXT-LW6C-NMJkzr3VfKDDfe7mh8,2851
@@ -110,9 +113,9 @@ datarobot_genai/nat/datarobot_llm_clients.py,sha256=Yu208Ed_p_4P3HdpuM7fYnKcXtim
110
113
  datarobot_genai/nat/datarobot_llm_providers.py,sha256=aDoQcTeGI-odqydPXEX9OGGNFbzAtpqzTvHHEkmJuEQ,4963
111
114
  datarobot_genai/nat/datarobot_mcp_client.py,sha256=35FzilxNp4VqwBYI0NsOc91-xZm1C-AzWqrOdDy962A,9612
112
115
  datarobot_genai/nat/helpers.py,sha256=Q7E3ADZdtFfS8E6OQPyw2wgA6laQ58N3bhLj5CBWwJs,3265
113
- datarobot_genai-0.2.26.dist-info/METADATA,sha256=7DMbKQ_9IV0Hmg8xCubJfPJ37C-TZ1-hr0RMgnsUUOQ,6301
114
- datarobot_genai-0.2.26.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
115
- datarobot_genai-0.2.26.dist-info/entry_points.txt,sha256=jEW3WxDZ8XIK9-ISmTyt5DbmBb047rFlzQuhY09rGrM,284
116
- datarobot_genai-0.2.26.dist-info/licenses/AUTHORS,sha256=isJGUXdjq1U7XZ_B_9AH8Qf0u4eX0XyQifJZ_Sxm4sA,80
117
- datarobot_genai-0.2.26.dist-info/licenses/LICENSE,sha256=U2_VkLIktQoa60Nf6Tbt7E4RMlfhFSjWjcJJfVC-YCE,11341
118
- datarobot_genai-0.2.26.dist-info/RECORD,,
116
+ datarobot_genai-0.2.28.dist-info/METADATA,sha256=4BXiWsOeKBshX05-9fayxuNDKjA6ova0H2CbrQILvCQ,6301
117
+ datarobot_genai-0.2.28.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
118
+ datarobot_genai-0.2.28.dist-info/entry_points.txt,sha256=jEW3WxDZ8XIK9-ISmTyt5DbmBb047rFlzQuhY09rGrM,284
119
+ datarobot_genai-0.2.28.dist-info/licenses/AUTHORS,sha256=isJGUXdjq1U7XZ_B_9AH8Qf0u4eX0XyQifJZ_Sxm4sA,80
120
+ datarobot_genai-0.2.28.dist-info/licenses/LICENSE,sha256=U2_VkLIktQoa60Nf6Tbt7E4RMlfhFSjWjcJJfVC-YCE,11341
121
+ datarobot_genai-0.2.28.dist-info/RECORD,,