datarobot-genai 0.2.25__py3-none-any.whl → 0.2.27__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datarobot_genai/drmcp/core/mcp_instance.py +34 -15
- datarobot_genai/drmcp/tools/clients/gdrive.py +127 -0
- datarobot_genai/drmcp/tools/gdrive/tools.py +95 -2
- {datarobot_genai-0.2.25.dist-info → datarobot_genai-0.2.27.dist-info}/METADATA +1 -1
- {datarobot_genai-0.2.25.dist-info → datarobot_genai-0.2.27.dist-info}/RECORD +9 -9
- {datarobot_genai-0.2.25.dist-info → datarobot_genai-0.2.27.dist-info}/WHEEL +0 -0
- {datarobot_genai-0.2.25.dist-info → datarobot_genai-0.2.27.dist-info}/entry_points.txt +0 -0
- {datarobot_genai-0.2.25.dist-info → datarobot_genai-0.2.27.dist-info}/licenses/AUTHORS +0 -0
- {datarobot_genai-0.2.25.dist-info → datarobot_genai-0.2.27.dist-info}/licenses/LICENSE +0 -0
|
@@ -16,6 +16,7 @@ import logging
|
|
|
16
16
|
from collections.abc import Callable
|
|
17
17
|
from functools import wraps
|
|
18
18
|
from typing import Any
|
|
19
|
+
from typing import TypedDict
|
|
19
20
|
|
|
20
21
|
from fastmcp import Context
|
|
21
22
|
from fastmcp import FastMCP
|
|
@@ -26,6 +27,7 @@ from fastmcp.tools import Tool
|
|
|
26
27
|
from mcp.types import AnyFunction
|
|
27
28
|
from mcp.types import Tool as MCPTool
|
|
28
29
|
from mcp.types import ToolAnnotations
|
|
30
|
+
from typing_extensions import Unpack
|
|
29
31
|
|
|
30
32
|
from .config import MCPServerConfig
|
|
31
33
|
from .config import get_config
|
|
@@ -287,16 +289,37 @@ mcp = TaggedFastMCP(
|
|
|
287
289
|
)
|
|
288
290
|
|
|
289
291
|
|
|
292
|
+
class ToolKwargs(TypedDict, total=False):
|
|
293
|
+
"""Keyword arguments passed through to FastMCP's mcp.tool() decorator.
|
|
294
|
+
|
|
295
|
+
All parameters are optional and forwarded directly to FastMCP tool registration.
|
|
296
|
+
See FastMCP documentation for full details on each parameter.
|
|
297
|
+
"""
|
|
298
|
+
|
|
299
|
+
name: str | None
|
|
300
|
+
title: str | None
|
|
301
|
+
description: str | None
|
|
302
|
+
icons: list[Any] | None
|
|
303
|
+
tags: set[str] | None
|
|
304
|
+
output_schema: dict[str, Any] | None
|
|
305
|
+
annotations: Any | None
|
|
306
|
+
exclude_args: list[str] | None
|
|
307
|
+
meta: dict[str, Any] | None
|
|
308
|
+
enabled: bool | None
|
|
309
|
+
|
|
310
|
+
|
|
290
311
|
def dr_core_mcp_tool(
|
|
291
|
-
|
|
292
|
-
description: str | None = None,
|
|
293
|
-
tags: set[str] | None = None,
|
|
312
|
+
**kwargs: Unpack[ToolKwargs],
|
|
294
313
|
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
295
|
-
"""Combine decorator that includes mcp.tool() and dr_mcp_extras().
|
|
314
|
+
"""Combine decorator that includes mcp.tool() and dr_mcp_extras().
|
|
315
|
+
|
|
316
|
+
All keyword arguments are passed through to FastMCP's mcp.tool() decorator.
|
|
317
|
+
See ToolKwargs for available parameters.
|
|
318
|
+
"""
|
|
296
319
|
|
|
297
320
|
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
298
321
|
instrumented = dr_mcp_extras()(func)
|
|
299
|
-
mcp.tool(
|
|
322
|
+
mcp.tool(**kwargs)(instrumented)
|
|
300
323
|
return instrumented
|
|
301
324
|
|
|
302
325
|
return decorator
|
|
@@ -329,27 +352,23 @@ async def memory_aware_wrapper(func: Callable[..., Any], *args: Any, **kwargs: A
|
|
|
329
352
|
|
|
330
353
|
|
|
331
354
|
def dr_mcp_tool(
|
|
332
|
-
|
|
333
|
-
description: str | None = None,
|
|
334
|
-
tags: set[str] | None = None,
|
|
355
|
+
**kwargs: Unpack[ToolKwargs],
|
|
335
356
|
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
336
357
|
"""Combine decorator that includes mcp.tool(), dr_mcp_extras(), and capture memory ids from
|
|
337
358
|
the request headers if they exist.
|
|
338
359
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
description: Tool description
|
|
342
|
-
tags: Optional set of tags to apply to the tool
|
|
360
|
+
All keyword arguments are passed through to FastMCP's mcp.tool() decorator.
|
|
361
|
+
See ToolKwargs for available parameters.
|
|
343
362
|
"""
|
|
344
363
|
|
|
345
364
|
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
346
365
|
@wraps(func)
|
|
347
|
-
async def wrapper(*args: Any, **
|
|
348
|
-
return await memory_aware_wrapper(func, *args, **
|
|
366
|
+
async def wrapper(*args: Any, **inner_kwargs: Any) -> Any:
|
|
367
|
+
return await memory_aware_wrapper(func, *args, **inner_kwargs)
|
|
349
368
|
|
|
350
369
|
# Apply the MCP decorators
|
|
351
370
|
instrumented = dr_mcp_extras()(wrapper)
|
|
352
|
-
mcp.tool(
|
|
371
|
+
mcp.tool(**kwargs)(instrumented)
|
|
353
372
|
return instrumented
|
|
354
373
|
|
|
355
374
|
return decorator
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
"""Google Drive API Client and utilities for OAuth."""
|
|
16
16
|
|
|
17
17
|
import io
|
|
18
|
+
import json
|
|
18
19
|
import logging
|
|
20
|
+
import uuid
|
|
19
21
|
from typing import Annotated
|
|
20
22
|
from typing import Any
|
|
21
23
|
|
|
@@ -45,6 +47,12 @@ GOOGLE_WORKSPACE_EXPORT_MIMES: dict[str, str] = {
|
|
|
45
47
|
"application/vnd.google-apps.presentation": "text/plain",
|
|
46
48
|
}
|
|
47
49
|
|
|
50
|
+
# MIME type mappings for content conversion during upload to Google Workspace formats
|
|
51
|
+
UPLOAD_CONTENT_TYPES: dict[str, str] = {
|
|
52
|
+
"application/vnd.google-apps.document": "text/plain",
|
|
53
|
+
"application/vnd.google-apps.spreadsheet": "text/csv",
|
|
54
|
+
}
|
|
55
|
+
|
|
48
56
|
BINARY_MIME_PREFIXES = (
|
|
49
57
|
"image/",
|
|
50
58
|
"audio/",
|
|
@@ -599,6 +607,125 @@ class GoogleDriveClient:
|
|
|
599
607
|
web_view_link=file_metadata.web_view_link,
|
|
600
608
|
)
|
|
601
609
|
|
|
610
|
+
async def create_file(
|
|
611
|
+
self,
|
|
612
|
+
name: str,
|
|
613
|
+
mime_type: str,
|
|
614
|
+
parent_id: str | None = None,
|
|
615
|
+
initial_content: str | None = None,
|
|
616
|
+
) -> GoogleDriveFile:
|
|
617
|
+
"""Create a new file or folder in Google Drive.
|
|
618
|
+
|
|
619
|
+
Creates a new file with the specified name and MIME type. Optionally places
|
|
620
|
+
it in a specific folder and populates it with initial content.
|
|
621
|
+
|
|
622
|
+
For Google Workspace files (Docs, Sheets), the Drive API automatically
|
|
623
|
+
converts plain text content to the appropriate format.
|
|
624
|
+
|
|
625
|
+
Args:
|
|
626
|
+
name: The name for the new file or folder.
|
|
627
|
+
mime_type: The MIME type of the file (e.g., 'text/plain',
|
|
628
|
+
'application/vnd.google-apps.document',
|
|
629
|
+
'application/vnd.google-apps.folder').
|
|
630
|
+
parent_id: Optional ID of the parent folder. If not specified,
|
|
631
|
+
the file is created in the root of the user's Drive.
|
|
632
|
+
initial_content: Optional text content to populate the file.
|
|
633
|
+
Ignored for folders.
|
|
634
|
+
|
|
635
|
+
Returns
|
|
636
|
+
-------
|
|
637
|
+
GoogleDriveFile with the created file's metadata.
|
|
638
|
+
|
|
639
|
+
Raises
|
|
640
|
+
------
|
|
641
|
+
GoogleDriveError: If file creation fails (permission denied,
|
|
642
|
+
parent not found, rate limited, etc.).
|
|
643
|
+
"""
|
|
644
|
+
metadata: dict[str, Any] = {
|
|
645
|
+
"name": name,
|
|
646
|
+
"mimeType": mime_type,
|
|
647
|
+
}
|
|
648
|
+
if parent_id:
|
|
649
|
+
metadata["parents"] = [parent_id]
|
|
650
|
+
|
|
651
|
+
if mime_type == GOOGLE_DRIVE_FOLDER_MIME or not initial_content:
|
|
652
|
+
response = await self._client.post(
|
|
653
|
+
"/",
|
|
654
|
+
json=metadata,
|
|
655
|
+
params={"fields": SUPPORTED_FIELDS_STR, "supportsAllDrives": "true"},
|
|
656
|
+
)
|
|
657
|
+
else:
|
|
658
|
+
response = await self._create_file_with_content(
|
|
659
|
+
metadata=metadata,
|
|
660
|
+
content=initial_content,
|
|
661
|
+
target_mime_type=mime_type,
|
|
662
|
+
)
|
|
663
|
+
|
|
664
|
+
if response.status_code == 404:
|
|
665
|
+
raise GoogleDriveError(
|
|
666
|
+
f"Parent folder with ID '{parent_id}' not found."
|
|
667
|
+
if parent_id
|
|
668
|
+
else "Resource not found."
|
|
669
|
+
)
|
|
670
|
+
if response.status_code == 403:
|
|
671
|
+
raise GoogleDriveError(
|
|
672
|
+
"Permission denied: you don't have permission to create files in this location."
|
|
673
|
+
)
|
|
674
|
+
if response.status_code == 400:
|
|
675
|
+
raise GoogleDriveError(
|
|
676
|
+
f"Bad request: invalid parameters for file creation. "
|
|
677
|
+
f"Check that the MIME type '{mime_type}' is valid."
|
|
678
|
+
)
|
|
679
|
+
if response.status_code == 429:
|
|
680
|
+
raise GoogleDriveError("Rate limit exceeded. Please try again later.")
|
|
681
|
+
|
|
682
|
+
response.raise_for_status()
|
|
683
|
+
return GoogleDriveFile.from_api_response(response.json())
|
|
684
|
+
|
|
685
|
+
async def _create_file_with_content(
|
|
686
|
+
self,
|
|
687
|
+
metadata: dict[str, Any],
|
|
688
|
+
content: str,
|
|
689
|
+
target_mime_type: str,
|
|
690
|
+
) -> httpx.Response:
|
|
691
|
+
"""Create a file with content using multipart upload.
|
|
692
|
+
|
|
693
|
+
Args:
|
|
694
|
+
metadata: File metadata dictionary.
|
|
695
|
+
content: Text content for the file.
|
|
696
|
+
target_mime_type: The target MIME type for the file.
|
|
697
|
+
|
|
698
|
+
Returns
|
|
699
|
+
-------
|
|
700
|
+
The HTTP response from the upload.
|
|
701
|
+
"""
|
|
702
|
+
content_type = UPLOAD_CONTENT_TYPES.get(target_mime_type, "text/plain")
|
|
703
|
+
boundary = f"===gdrive_boundary_{uuid.uuid4().hex}==="
|
|
704
|
+
body_parts = [
|
|
705
|
+
f"--{boundary}",
|
|
706
|
+
"Content-Type: application/json; charset=UTF-8",
|
|
707
|
+
"",
|
|
708
|
+
json.dumps(metadata),
|
|
709
|
+
f"--{boundary}",
|
|
710
|
+
f"Content-Type: {content_type}",
|
|
711
|
+
"",
|
|
712
|
+
content,
|
|
713
|
+
f"--{boundary}--",
|
|
714
|
+
]
|
|
715
|
+
body = "\r\n".join(body_parts)
|
|
716
|
+
|
|
717
|
+
upload_url = "https://www.googleapis.com/upload/drive/v3/files"
|
|
718
|
+
return await self._client.post(
|
|
719
|
+
upload_url,
|
|
720
|
+
content=body.encode("utf-8"),
|
|
721
|
+
params={
|
|
722
|
+
"uploadType": "multipart",
|
|
723
|
+
"fields": SUPPORTED_FIELDS_STR,
|
|
724
|
+
"supportsAllDrives": "true",
|
|
725
|
+
},
|
|
726
|
+
headers={"Content-Type": f"multipart/related; boundary={boundary}"},
|
|
727
|
+
)
|
|
728
|
+
|
|
602
729
|
async def __aenter__(self) -> "GoogleDriveClient":
|
|
603
730
|
"""Async context manager entry."""
|
|
604
731
|
return self
|
|
@@ -21,6 +21,7 @@ from fastmcp.exceptions import ToolError
|
|
|
21
21
|
from fastmcp.tools.tool import ToolResult
|
|
22
22
|
|
|
23
23
|
from datarobot_genai.drmcp.core.mcp_instance import dr_mcp_tool
|
|
24
|
+
from datarobot_genai.drmcp.tools.clients.gdrive import GOOGLE_DRIVE_FOLDER_MIME
|
|
24
25
|
from datarobot_genai.drmcp.tools.clients.gdrive import LIMIT
|
|
25
26
|
from datarobot_genai.drmcp.tools.clients.gdrive import MAX_PAGE_SIZE
|
|
26
27
|
from datarobot_genai.drmcp.tools.clients.gdrive import SUPPORTED_FIELDS
|
|
@@ -60,7 +61,7 @@ async def gdrive_find_contents(
|
|
|
60
61
|
"Optional list of metadata fields to include. Ex. id, name, mimeType. "
|
|
61
62
|
f"Default = {SUPPORTED_FIELDS_STR}",
|
|
62
63
|
] = None,
|
|
63
|
-
) -> ToolResult
|
|
64
|
+
) -> ToolResult:
|
|
64
65
|
"""
|
|
65
66
|
Search or list files in the user's Google Drive with pagination and filtering support.
|
|
66
67
|
Use this tool to discover file names and IDs for use with other tools.
|
|
@@ -121,7 +122,7 @@ async def gdrive_read_content(
|
|
|
121
122
|
"(e.g., 'text/markdown' for Docs, 'text/csv' for Sheets). "
|
|
122
123
|
"If not specified, uses sensible defaults. Has no effect on regular files.",
|
|
123
124
|
] = None,
|
|
124
|
-
) -> ToolResult
|
|
125
|
+
) -> ToolResult:
|
|
125
126
|
"""
|
|
126
127
|
Retrieve the content of a specific file by its ID. Google Workspace files are
|
|
127
128
|
automatically exported to LLM-readable formats (Push-Down).
|
|
@@ -175,3 +176,95 @@ async def gdrive_read_content(
|
|
|
175
176
|
),
|
|
176
177
|
structured_content=file_content.as_flat_dict(),
|
|
177
178
|
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@dr_mcp_tool(tags={"google", "gdrive", "create", "write", "file", "folder"}, enabled=False)
|
|
182
|
+
async def gdrive_create_file(
|
|
183
|
+
*,
|
|
184
|
+
name: Annotated[str, "The name for the new file or folder."],
|
|
185
|
+
mime_type: Annotated[
|
|
186
|
+
str,
|
|
187
|
+
"The MIME type of the file (e.g., 'text/plain', "
|
|
188
|
+
"'application/vnd.google-apps.document', 'application/vnd.google-apps.folder').",
|
|
189
|
+
],
|
|
190
|
+
parent_id: Annotated[
|
|
191
|
+
str | None, "The ID of the parent folder where the file should be created."
|
|
192
|
+
] = None,
|
|
193
|
+
initial_content: Annotated[
|
|
194
|
+
str | None, "Text content to populate the new file, if applicable."
|
|
195
|
+
] = None,
|
|
196
|
+
) -> ToolResult:
|
|
197
|
+
"""
|
|
198
|
+
Create a new file or folder in Google Drive.
|
|
199
|
+
|
|
200
|
+
This tool is essential for an AI agent to generate new output (like reports or
|
|
201
|
+
documentation) directly into the Drive structure.
|
|
202
|
+
|
|
203
|
+
Usage:
|
|
204
|
+
- Create empty file: gdrive_create_file(name="report.txt", mime_type="text/plain")
|
|
205
|
+
- Create Google Doc: gdrive_create_file(
|
|
206
|
+
name="My Report",
|
|
207
|
+
mime_type="application/vnd.google-apps.document",
|
|
208
|
+
initial_content="# Report Title"
|
|
209
|
+
)
|
|
210
|
+
- Create folder: gdrive_create_file(
|
|
211
|
+
name="Reports",
|
|
212
|
+
mime_type="application/vnd.google-apps.folder"
|
|
213
|
+
)
|
|
214
|
+
- Create in subfolder: gdrive_create_file(
|
|
215
|
+
name="file.txt",
|
|
216
|
+
mime_type="text/plain",
|
|
217
|
+
parent_id="folder_id_here",
|
|
218
|
+
initial_content="File content"
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
Supported MIME types:
|
|
222
|
+
- text/plain: Plain text file
|
|
223
|
+
- application/vnd.google-apps.document: Google Doc (content auto-converted)
|
|
224
|
+
- application/vnd.google-apps.spreadsheet: Google Sheet (CSV content works best)
|
|
225
|
+
- application/vnd.google-apps.folder: Folder (initial_content is ignored)
|
|
226
|
+
|
|
227
|
+
Note: For Google Workspace files, the Drive API automatically converts plain text
|
|
228
|
+
content to the appropriate format.
|
|
229
|
+
"""
|
|
230
|
+
if not name or not name.strip():
|
|
231
|
+
raise ToolError("Argument validation error: 'name' cannot be empty.")
|
|
232
|
+
|
|
233
|
+
if not mime_type or not mime_type.strip():
|
|
234
|
+
raise ToolError("Argument validation error: 'mime_type' cannot be empty.")
|
|
235
|
+
|
|
236
|
+
access_token = await get_gdrive_access_token()
|
|
237
|
+
if isinstance(access_token, ToolError):
|
|
238
|
+
raise access_token
|
|
239
|
+
|
|
240
|
+
try:
|
|
241
|
+
async with GoogleDriveClient(access_token) as client:
|
|
242
|
+
created_file = await client.create_file(
|
|
243
|
+
name=name,
|
|
244
|
+
mime_type=mime_type,
|
|
245
|
+
parent_id=parent_id,
|
|
246
|
+
initial_content=initial_content,
|
|
247
|
+
)
|
|
248
|
+
except GoogleDriveError as e:
|
|
249
|
+
logger.error(f"Google Drive error creating file: {e}")
|
|
250
|
+
raise ToolError(str(e))
|
|
251
|
+
except Exception as e:
|
|
252
|
+
logger.error(f"Unexpected error creating Google Drive file: {e}")
|
|
253
|
+
raise ToolError(f"An unexpected error occurred while creating Google Drive file: {str(e)}")
|
|
254
|
+
|
|
255
|
+
# Build response message
|
|
256
|
+
file_type = "folder" if mime_type == GOOGLE_DRIVE_FOLDER_MIME else "file"
|
|
257
|
+
content_info = ""
|
|
258
|
+
if initial_content and mime_type != GOOGLE_DRIVE_FOLDER_MIME:
|
|
259
|
+
content_info = " with initial content"
|
|
260
|
+
|
|
261
|
+
return ToolResult(
|
|
262
|
+
content=f"Successfully created {file_type} '{created_file.name}'{content_info}.",
|
|
263
|
+
structured_content={
|
|
264
|
+
"id": created_file.id,
|
|
265
|
+
"name": created_file.name,
|
|
266
|
+
"mimeType": created_file.mime_type,
|
|
267
|
+
"webViewLink": created_file.web_view_link,
|
|
268
|
+
"createdTime": created_file.created_time,
|
|
269
|
+
},
|
|
270
|
+
)
|
|
@@ -35,7 +35,7 @@ datarobot_genai/drmcp/core/dr_mcp_server.py,sha256=czcjbwhZAeW9EtG_Bys0GARPOuQul
|
|
|
35
35
|
datarobot_genai/drmcp/core/dr_mcp_server_logo.py,sha256=hib-nfR1SNTW6CnpFsFCkL9H_OMwa4YYyinV7VNOuLk,4708
|
|
36
36
|
datarobot_genai/drmcp/core/exceptions.py,sha256=eqsGI-lxybgvWL5w4BFhbm3XzH1eU5tetwjnhJxelpc,905
|
|
37
37
|
datarobot_genai/drmcp/core/logging.py,sha256=Y_hig4eBWiXGaVV7B_3wBcaYVRNH4ydptbEQhrP9-mY,3414
|
|
38
|
-
datarobot_genai/drmcp/core/mcp_instance.py,sha256=
|
|
38
|
+
datarobot_genai/drmcp/core/mcp_instance.py,sha256=nt4gOlAQklMcqmohRIKovYcyhgLdb08NHMo28DBYmOk,18362
|
|
39
39
|
datarobot_genai/drmcp/core/routes.py,sha256=dqE2M0UzAyyN9vQjlyTjYW4rpju3LT039po5weuO__I,17936
|
|
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
|
|
@@ -78,13 +78,13 @@ datarobot_genai/drmcp/tools/__init__.py,sha256=0kq9vMkF7EBsS6lkEdiLibmUrghTQqosH
|
|
|
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=
|
|
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
83
|
datarobot_genai/drmcp/tools/clients/s3.py,sha256=GmwzvurFdNfvxOooA8g5S4osRysHYU0S9ypg_177Glg,953
|
|
84
84
|
datarobot_genai/drmcp/tools/confluence/__init__.py,sha256=0kq9vMkF7EBsS6lkEdiLibmUrghTQqosHbZ5k-V9a5g,578
|
|
85
85
|
datarobot_genai/drmcp/tools/confluence/tools.py,sha256=_-ws65WLK8KZP_mKkf4yJ7ZunR8qdyoiMwHQX47MSMw,12362
|
|
86
86
|
datarobot_genai/drmcp/tools/gdrive/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
87
|
-
datarobot_genai/drmcp/tools/gdrive/tools.py,sha256=
|
|
87
|
+
datarobot_genai/drmcp/tools/gdrive/tools.py,sha256=G8LlnGEINZqV83Q-b3ZliWkDjouhbozDam3w6GfA7s0,10711
|
|
88
88
|
datarobot_genai/drmcp/tools/jira/__init__.py,sha256=0kq9vMkF7EBsS6lkEdiLibmUrghTQqosHbZ5k-V9a5g,578
|
|
89
89
|
datarobot_genai/drmcp/tools/jira/tools.py,sha256=dfkqTU2HH-7n44hX80ODFacKq0p0LOchFcZtIIKFNMM,9687
|
|
90
90
|
datarobot_genai/drmcp/tools/predictive/__init__.py,sha256=WuOHlNNEpEmcF7gVnhckruJRKU2qtmJLE3E7zoCGLDo,1030
|
|
@@ -110,9 +110,9 @@ datarobot_genai/nat/datarobot_llm_clients.py,sha256=Yu208Ed_p_4P3HdpuM7fYnKcXtim
|
|
|
110
110
|
datarobot_genai/nat/datarobot_llm_providers.py,sha256=aDoQcTeGI-odqydPXEX9OGGNFbzAtpqzTvHHEkmJuEQ,4963
|
|
111
111
|
datarobot_genai/nat/datarobot_mcp_client.py,sha256=35FzilxNp4VqwBYI0NsOc91-xZm1C-AzWqrOdDy962A,9612
|
|
112
112
|
datarobot_genai/nat/helpers.py,sha256=Q7E3ADZdtFfS8E6OQPyw2wgA6laQ58N3bhLj5CBWwJs,3265
|
|
113
|
-
datarobot_genai-0.2.
|
|
114
|
-
datarobot_genai-0.2.
|
|
115
|
-
datarobot_genai-0.2.
|
|
116
|
-
datarobot_genai-0.2.
|
|
117
|
-
datarobot_genai-0.2.
|
|
118
|
-
datarobot_genai-0.2.
|
|
113
|
+
datarobot_genai-0.2.27.dist-info/METADATA,sha256=XfhoUrhYzD4u2Glt9HIR0AUEzlj170ct0ZkcSujc_W4,6301
|
|
114
|
+
datarobot_genai-0.2.27.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
115
|
+
datarobot_genai-0.2.27.dist-info/entry_points.txt,sha256=jEW3WxDZ8XIK9-ISmTyt5DbmBb047rFlzQuhY09rGrM,284
|
|
116
|
+
datarobot_genai-0.2.27.dist-info/licenses/AUTHORS,sha256=isJGUXdjq1U7XZ_B_9AH8Qf0u4eX0XyQifJZ_Sxm4sA,80
|
|
117
|
+
datarobot_genai-0.2.27.dist-info/licenses/LICENSE,sha256=U2_VkLIktQoa60Nf6Tbt7E4RMlfhFSjWjcJJfVC-YCE,11341
|
|
118
|
+
datarobot_genai-0.2.27.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|