uipath 2.1.99__py3-none-any.whl → 2.1.101__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.
Potentially problematic release.
This version of uipath might be problematic. Click here for more details.
- uipath/_cli/__init__.py +0 -2
- uipath/_cli/_push/sw_file_handler.py +186 -75
- uipath/_cli/_utils/_project_files.py +72 -14
- uipath/_cli/cli_init.py +4 -1
- uipath/_cli/cli_pull.py +14 -7
- uipath/_cli/cli_push.py +33 -16
- uipath/_uipath.py +2 -1
- uipath/_utils/_logs.py +6 -7
- uipath/agent/_utils.py +0 -9
- uipath/agent/models/agent.py +4 -33
- uipath/models/exceptions.py +9 -5
- uipath/models/guardrails.py +469 -0
- {uipath-2.1.99.dist-info → uipath-2.1.101.dist-info}/METADATA +1 -1
- {uipath-2.1.99.dist-info → uipath-2.1.101.dist-info}/RECORD +17 -16
- {uipath-2.1.99.dist-info → uipath-2.1.101.dist-info}/WHEEL +0 -0
- {uipath-2.1.99.dist-info → uipath-2.1.101.dist-info}/entry_points.txt +0 -0
- {uipath-2.1.99.dist-info → uipath-2.1.101.dist-info}/licenses/LICENSE +0 -0
uipath/_cli/cli_pull.py
CHANGED
|
@@ -19,7 +19,7 @@ import click
|
|
|
19
19
|
from ..telemetry import track
|
|
20
20
|
from ._utils._console import ConsoleLogger
|
|
21
21
|
from ._utils._constants import UIPATH_PROJECT_ID
|
|
22
|
-
from ._utils._project_files import pull_project
|
|
22
|
+
from ._utils._project_files import ProjectPullError, pull_project
|
|
23
23
|
|
|
24
24
|
console = ConsoleLogger()
|
|
25
25
|
|
|
@@ -63,18 +63,25 @@ def pull(root: Path) -> None:
|
|
|
63
63
|
$ uipath pull
|
|
64
64
|
$ uipath pull /path/to/project
|
|
65
65
|
"""
|
|
66
|
-
|
|
66
|
+
project_id = os.getenv(UIPATH_PROJECT_ID)
|
|
67
|
+
if not project_id:
|
|
67
68
|
console.error("UIPATH_PROJECT_ID environment variable not found.")
|
|
68
69
|
|
|
69
70
|
default_download_configuration = {
|
|
70
71
|
"source_code": root,
|
|
71
72
|
"evals": root / "evals",
|
|
72
73
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
|
|
75
|
+
async def pull_with_updates():
|
|
76
|
+
try:
|
|
77
|
+
async for update in pull_project(
|
|
76
78
|
project_id,
|
|
77
79
|
default_download_configuration,
|
|
78
80
|
InteractiveConflictHandler(console),
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
+
):
|
|
82
|
+
console.info(update.message)
|
|
83
|
+
except ProjectPullError as e:
|
|
84
|
+
console.error(e.message, include_traceback=True)
|
|
85
|
+
|
|
86
|
+
with console.spinner("Pulling UiPath project files..."):
|
|
87
|
+
asyncio.run(pull_with_updates())
|
uipath/_cli/cli_push.py
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# type: ignore
|
|
2
2
|
import asyncio
|
|
3
3
|
import os
|
|
4
|
-
from typing import Any, Optional
|
|
4
|
+
from typing import Any, AsyncIterator, Optional
|
|
5
5
|
from urllib.parse import urlparse
|
|
6
6
|
|
|
7
7
|
import click
|
|
8
8
|
|
|
9
|
+
from uipath.models.exceptions import EnrichedException
|
|
10
|
+
|
|
9
11
|
from ..telemetry import track
|
|
10
|
-
from ._push.sw_file_handler import SwFileHandler
|
|
12
|
+
from ._push.sw_file_handler import FileOperationUpdate, SwFileHandler
|
|
11
13
|
from ._utils._console import ConsoleLogger
|
|
12
14
|
from ._utils._constants import (
|
|
13
15
|
UIPATH_PROJECT_ID,
|
|
@@ -35,14 +37,20 @@ async def upload_source_files_to_project(
|
|
|
35
37
|
settings: Optional[dict[str, Any]],
|
|
36
38
|
directory: str,
|
|
37
39
|
include_uv_lock: bool = True,
|
|
38
|
-
) ->
|
|
39
|
-
"""Upload source files to UiPath project.
|
|
40
|
+
) -> AsyncIterator[FileOperationUpdate]:
|
|
41
|
+
"""Upload source files to UiPath project, yielding progress updates.
|
|
40
42
|
|
|
41
43
|
This function handles the pushing of local files to the remote project:
|
|
42
44
|
- Updates existing files that have changed
|
|
43
45
|
- Uploads new files that don't exist remotely
|
|
44
46
|
- Deletes remote files that no longer exist locally
|
|
45
47
|
- Optionally includes the UV lock file
|
|
48
|
+
|
|
49
|
+
Yields:
|
|
50
|
+
FileOperationUpdate: Progress updates for each file operation
|
|
51
|
+
|
|
52
|
+
Raises:
|
|
53
|
+
ProjectPushError: If the push operation fails
|
|
46
54
|
"""
|
|
47
55
|
sw_file_handler = SwFileHandler(
|
|
48
56
|
project_id=project_id,
|
|
@@ -50,7 +58,8 @@ async def upload_source_files_to_project(
|
|
|
50
58
|
include_uv_lock=include_uv_lock,
|
|
51
59
|
)
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
async for update in sw_file_handler.upload_source_files(settings):
|
|
62
|
+
yield update
|
|
54
63
|
|
|
55
64
|
|
|
56
65
|
@click.command()
|
|
@@ -88,21 +97,29 @@ def push(root: str, nolock: bool) -> None:
|
|
|
88
97
|
config = get_project_config(root)
|
|
89
98
|
validate_config(config)
|
|
90
99
|
|
|
91
|
-
|
|
100
|
+
project_id = os.getenv(UIPATH_PROJECT_ID)
|
|
101
|
+
if not project_id:
|
|
92
102
|
console.error("UIPATH_PROJECT_ID environment variable not found.")
|
|
93
103
|
|
|
94
|
-
|
|
104
|
+
async def push_with_updates():
|
|
105
|
+
"""Wrapper to handle async iteration and display updates."""
|
|
106
|
+
async for update in upload_source_files_to_project(
|
|
107
|
+
project_id,
|
|
108
|
+
config.get("settings", {}),
|
|
109
|
+
root,
|
|
110
|
+
include_uv_lock=not nolock,
|
|
111
|
+
):
|
|
112
|
+
console.info(update.message)
|
|
113
|
+
|
|
114
|
+
with console.spinner("Pushing UiPath project to Studio Web..."):
|
|
95
115
|
try:
|
|
96
116
|
if not nolock:
|
|
97
117
|
handle_uv_operations(root)
|
|
98
118
|
|
|
99
|
-
asyncio.run(
|
|
100
|
-
|
|
101
|
-
os.getenv(UIPATH_PROJECT_ID),
|
|
102
|
-
config.get("settings", {}),
|
|
103
|
-
root,
|
|
104
|
-
include_uv_lock=not nolock,
|
|
105
|
-
)
|
|
106
|
-
)
|
|
119
|
+
asyncio.run(push_with_updates())
|
|
120
|
+
|
|
107
121
|
except Exception as e:
|
|
108
|
-
console.error(
|
|
122
|
+
console.error(
|
|
123
|
+
f"Failed to push UiPath project: {e}",
|
|
124
|
+
include_traceback=not isinstance(e, EnrichedException),
|
|
125
|
+
)
|
uipath/_uipath.py
CHANGED
|
@@ -22,6 +22,7 @@ from ._services import (
|
|
|
22
22
|
UiPathOpenAIService,
|
|
23
23
|
)
|
|
24
24
|
from ._utils._auth import resolve_config
|
|
25
|
+
from ._utils._logs import setup_logging
|
|
25
26
|
from .models.errors import BaseUrlMissingError, SecretMissingError
|
|
26
27
|
|
|
27
28
|
|
|
@@ -54,7 +55,7 @@ class UiPath:
|
|
|
54
55
|
self._buckets_service: Optional[BucketsService] = None
|
|
55
56
|
self._attachments_service: Optional[AttachmentsService] = None
|
|
56
57
|
self._connections_service: Optional[ConnectionsService] = None
|
|
57
|
-
|
|
58
|
+
setup_logging(should_debug=debug)
|
|
58
59
|
self._execution_context = ExecutionContext()
|
|
59
60
|
|
|
60
61
|
@property
|
uipath/_utils/_logs.py
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
import sys
|
|
3
2
|
from typing import Optional
|
|
4
3
|
|
|
5
4
|
logger: logging.Logger = logging.getLogger("uipath")
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
def setup_logging(should_debug: Optional[bool] = None) -> None:
|
|
9
|
-
logging.
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
if not logging.root.handlers and not logger.handlers:
|
|
9
|
+
logging.basicConfig(
|
|
10
|
+
format="%(message)s",
|
|
11
|
+
datefmt="%Y-%m-%d %H:%M:%S",
|
|
12
|
+
)
|
|
13
|
+
logger.setLevel(logging.DEBUG if should_debug else logging.INFO)
|
uipath/agent/_utils.py
CHANGED
|
@@ -8,7 +8,6 @@ from uipath._cli._evals._models._evaluation_set import (
|
|
|
8
8
|
InputMockingStrategy,
|
|
9
9
|
LLMMockingStrategy,
|
|
10
10
|
)
|
|
11
|
-
from uipath._cli._push.sw_file_handler import SwFileHandler
|
|
12
11
|
from uipath._cli._utils._studio_project import (
|
|
13
12
|
ProjectFile,
|
|
14
13
|
ProjectFolder,
|
|
@@ -38,14 +37,6 @@ async def create_agent_project(solution_id: str, project_name: str) -> str:
|
|
|
38
37
|
return project["id"]
|
|
39
38
|
|
|
40
39
|
|
|
41
|
-
async def upload_project_files(project_id: str, root: str) -> None:
|
|
42
|
-
sw_file_handler = SwFileHandler(
|
|
43
|
-
project_id=project_id,
|
|
44
|
-
directory=root,
|
|
45
|
-
)
|
|
46
|
-
await sw_file_handler.upload_source_files({})
|
|
47
|
-
|
|
48
|
-
|
|
49
40
|
async def load_agent_definition(project_id: str) -> AgentDefinition:
|
|
50
41
|
studio_client = StudioClient(project_id=project_id)
|
|
51
42
|
project_structure = await studio_client.get_project_structure_async()
|
uipath/agent/models/agent.py
CHANGED
|
@@ -6,6 +6,7 @@ from typing import Annotated, Any, Dict, List, Literal, Optional, Union
|
|
|
6
6
|
from pydantic import BaseModel, ConfigDict, Discriminator, Field, Tag, field_validator
|
|
7
7
|
|
|
8
8
|
from uipath.models import Connection
|
|
9
|
+
from uipath.models.guardrails import AgentEscalationRecipient, Guardrail
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class AgentResourceType(str, Enum):
|
|
@@ -305,39 +306,6 @@ class AgentMcpResourceConfig(BaseAgentResourceConfig):
|
|
|
305
306
|
)
|
|
306
307
|
|
|
307
308
|
|
|
308
|
-
class AgentEscalationRecipientType(str, Enum):
|
|
309
|
-
"""Enum for escalation recipient types."""
|
|
310
|
-
|
|
311
|
-
USER_ID = "UserId"
|
|
312
|
-
GROUP_ID = "GroupId"
|
|
313
|
-
USER_EMAIL = "UserEmail"
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
class AgentEscalationRecipient(BaseModel):
|
|
317
|
-
"""Recipient for escalation."""
|
|
318
|
-
|
|
319
|
-
type: Union[AgentEscalationRecipientType, str] = Field(..., alias="type")
|
|
320
|
-
value: str = Field(..., alias="value")
|
|
321
|
-
display_name: Optional[str] = Field(default=None, alias="displayName")
|
|
322
|
-
|
|
323
|
-
@field_validator("type", mode="before")
|
|
324
|
-
@classmethod
|
|
325
|
-
def normalize_type(cls, v: Any) -> str:
|
|
326
|
-
"""Normalize recipient type from int (1=UserId, 2=GroupId, 3=UserEmail) or string. Unknown integers are converted to string."""
|
|
327
|
-
if isinstance(v, int):
|
|
328
|
-
mapping = {
|
|
329
|
-
1: AgentEscalationRecipientType.USER_ID,
|
|
330
|
-
2: AgentEscalationRecipientType.GROUP_ID,
|
|
331
|
-
3: AgentEscalationRecipientType.USER_EMAIL,
|
|
332
|
-
}
|
|
333
|
-
return mapping.get(v, str(v))
|
|
334
|
-
return v
|
|
335
|
-
|
|
336
|
-
model_config = ConfigDict(
|
|
337
|
-
validate_by_name=True, validate_by_alias=True, extra="allow"
|
|
338
|
-
)
|
|
339
|
-
|
|
340
|
-
|
|
341
309
|
class AgentEscalationChannelProperties(BaseResourceProperties):
|
|
342
310
|
"""Agent escalation channel properties."""
|
|
343
311
|
|
|
@@ -508,6 +476,9 @@ class BaseAgentDefinition(BaseModel):
|
|
|
508
476
|
output_schema: Dict[str, Any] = Field(
|
|
509
477
|
..., alias="outputSchema", description="JSON schema for output arguments"
|
|
510
478
|
)
|
|
479
|
+
guardrails: Optional[List[Guardrail]] = Field(
|
|
480
|
+
None, description="List of agent guardrails"
|
|
481
|
+
)
|
|
511
482
|
|
|
512
483
|
model_config = ConfigDict(
|
|
513
484
|
validate_by_name=True, validate_by_alias=True, extra="allow"
|
uipath/models/exceptions.py
CHANGED
|
@@ -25,11 +25,15 @@ class EnrichedException(Exception):
|
|
|
25
25
|
if error.request and error.request.method
|
|
26
26
|
else "Unknown"
|
|
27
27
|
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
max_content_length = 200
|
|
29
|
+
if error.response and error.response.content:
|
|
30
|
+
content = error.response.content.decode("utf-8")
|
|
31
|
+
if len(content) > max_content_length:
|
|
32
|
+
self.response_content = content[:max_content_length] + "... (truncated)"
|
|
33
|
+
else:
|
|
34
|
+
self.response_content = content
|
|
35
|
+
else:
|
|
36
|
+
self.response_content = "No content"
|
|
33
37
|
|
|
34
38
|
enriched_message = (
|
|
35
39
|
f"\nRequest URL: {self.url}"
|