Skip to content

Commit 0702234

Browse files
Merge branch 'main' into feature/add-list-models-command
2 parents 41c49bf + cc24c8e commit 0702234

9 files changed

Lines changed: 113 additions & 18 deletions

File tree

packages/uipath-platform/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath-platform"
3-
version = "0.1.36"
3+
version = "0.1.38"
44
description = "HTTP client library for programmatic access to UiPath Platform"
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.11"

packages/uipath-platform/src/uipath/platform/context_grounding/_context_grounding_service.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ORCHESTRATOR_STORAGE_BUCKET_DATA_SOURCE,
1818
)
1919
from ..errors import (
20+
BatchTransformFailedException,
2021
BatchTransformNotCompleteException,
2122
IngestionInProgressException,
2223
UnsupportedDataSourceException,
@@ -1050,6 +1051,10 @@ def download_batch_transform_result(
10501051
batch_transform = self.retrieve_batch_transform(
10511052
id=id, index_name=index_name
10521053
)
1054+
if batch_transform.last_batch_rag_status == BatchTransformStatus.FAILED:
1055+
raise BatchTransformFailedException(
1056+
batch_transform_id=id,
1057+
)
10531058
if batch_transform.last_batch_rag_status != BatchTransformStatus.SUCCESSFUL:
10541059
raise BatchTransformNotCompleteException(
10551060
batch_transform_id=id,
@@ -1109,6 +1114,10 @@ async def download_batch_transform_result_async(
11091114
batch_transform = await self.retrieve_batch_transform_async(
11101115
id=id, index_name=index_name
11111116
)
1117+
if batch_transform.last_batch_rag_status == BatchTransformStatus.FAILED:
1118+
raise BatchTransformFailedException(
1119+
batch_transform_id=id,
1120+
)
11121121
if batch_transform.last_batch_rag_status != BatchTransformStatus.SUCCESSFUL:
11131122
raise BatchTransformNotCompleteException(
11141123
batch_transform_id=id,

packages/uipath-platform/src/uipath/platform/errors/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
- FolderNotFoundException: Raised when a folder cannot be found
99
- UnsupportedDataSourceException: Raised when an operation is attempted on an unsupported data source type
1010
- IngestionInProgressException: Raised when a search is attempted on an index during ingestion
11+
- BatchTransformFailedException: Raised when a batch transform has failed
1112
- BatchTransformNotCompleteException: Raised when attempting to get results from an incomplete batch transform
1213
- OperationNotCompleteException: Raised when attempting to get results from an incomplete operation
1314
- OperationFailedException: Raised when an operation has failed
1415
- EnrichedException: Enriched HTTP error with detailed request/response information
1516
"""
1617

1718
from ._base_url_missing_error import BaseUrlMissingError
19+
from ._batch_transform_failed_exception import BatchTransformFailedException
1820
from ._batch_transform_not_complete_exception import BatchTransformNotCompleteException
1921
from ._enriched_exception import EnrichedException, ExtractedErrorInfo
2022
from ._folder_not_found_exception import FolderNotFoundException
@@ -26,6 +28,7 @@
2628

2729
__all__ = [
2830
"BaseUrlMissingError",
31+
"BatchTransformFailedException",
2932
"BatchTransformNotCompleteException",
3033
"EnrichedException",
3134
"ExtractedErrorInfo",
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class BatchTransformFailedException(Exception):
2+
"""Raised when a batch transform has failed.
3+
4+
This exception is raised when a batch transform task has completed
5+
with a failed status, as opposed to still being in progress.
6+
"""
7+
8+
def __init__(self, batch_transform_id: str):
9+
self.message = f"Batch transform '{batch_transform_id}' failed."
10+
super().__init__(self.message)

packages/uipath-platform/src/uipath/platform/memory/_memory_service.py

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from uipath.core.tracing import traced
1111

1212
from ..common._base_service import BaseService
13+
from ..common._bindings import resource_override
1314
from ..common._config import UiPathApiConfig
1415
from ..common._execution_context import UiPathExecutionContext
1516
from ..common._folder_context import FolderContext, header_folder
@@ -50,13 +51,15 @@ def __init__(
5051

5152
# ── Memory space operations (ECS) ──────────────────────────────────
5253

54+
@resource_override(resource_type="memorySpace")
5355
@traced(name="memory_create", run_type="uipath")
5456
def create(
5557
self,
5658
name: str,
5759
description: Optional[str] = None,
5860
is_encrypted: Optional[bool] = None,
5961
folder_key: Optional[str] = None,
62+
folder_path: Optional[str] = None,
6063
) -> MemorySpace:
6164
"""Create a new memory space.
6265
@@ -65,11 +68,14 @@ def create(
6568
description: Optional description (max 1024 chars).
6669
is_encrypted: Whether the memory space should be encrypted.
6770
folder_key: The folder key for the operation.
71+
folder_path: The folder path for the operation.
6872
6973
Returns:
7074
MemorySpace: The created memory space.
7175
"""
72-
spec = self._create_spec(name, description, is_encrypted, folder_key)
76+
spec = self._create_spec(
77+
name, description, is_encrypted, folder_key, folder_path
78+
)
7379
response = self.request(
7480
spec.method,
7581
spec.endpoint,
@@ -78,13 +84,15 @@ def create(
7884
).json()
7985
return MemorySpace.model_validate(response)
8086

87+
@resource_override(resource_type="memorySpace")
8188
@traced(name="memory_create", run_type="uipath")
8289
async def create_async(
8390
self,
8491
name: str,
8592
description: Optional[str] = None,
8693
is_encrypted: Optional[bool] = None,
8794
folder_key: Optional[str] = None,
95+
folder_path: Optional[str] = None,
8896
) -> MemorySpace:
8997
"""Asynchronously create a new memory space.
9098
@@ -93,11 +101,14 @@ async def create_async(
93101
description: Optional description (max 1024 chars).
94102
is_encrypted: Whether the memory space should be encrypted.
95103
folder_key: The folder key for the operation.
104+
folder_path: The folder path for the operation.
96105
97106
Returns:
98107
MemorySpace: The created memory space.
99108
"""
100-
spec = self._create_spec(name, description, is_encrypted, folder_key)
109+
spec = self._create_spec(
110+
name, description, is_encrypted, folder_key, folder_path
111+
)
101112
response = (
102113
await self.request_async(
103114
spec.method,
@@ -116,6 +127,7 @@ def list(
116127
top: Optional[int] = None,
117128
skip: Optional[int] = None,
118129
folder_key: Optional[str] = None,
130+
folder_path: Optional[str] = None,
119131
) -> MemorySpaceListResponse:
120132
"""List memory spaces with optional OData query parameters.
121133
@@ -125,11 +137,12 @@ def list(
125137
top: Maximum number of results.
126138
skip: Number of results to skip.
127139
folder_key: The folder key for the operation.
140+
folder_path: The folder path for the operation.
128141
129142
Returns:
130143
MemorySpaceListResponse: The list of memory spaces.
131144
"""
132-
spec = self._list_spec(filter, orderby, top, skip, folder_key)
145+
spec = self._list_spec(filter, orderby, top, skip, folder_key, folder_path)
133146
response = self.request(
134147
spec.method,
135148
spec.endpoint,
@@ -146,6 +159,7 @@ async def list_async(
146159
top: Optional[int] = None,
147160
skip: Optional[int] = None,
148161
folder_key: Optional[str] = None,
162+
folder_path: Optional[str] = None,
149163
) -> MemorySpaceListResponse:
150164
"""Asynchronously list memory spaces.
151165
@@ -155,11 +169,12 @@ async def list_async(
155169
top: Maximum number of results.
156170
skip: Number of results to skip.
157171
folder_key: The folder key for the operation.
172+
folder_path: The folder path for the operation.
158173
159174
Returns:
160175
MemorySpaceListResponse: The list of memory spaces.
161176
"""
162-
spec = self._list_spec(filter, orderby, top, skip, folder_key)
177+
spec = self._list_spec(filter, orderby, top, skip, folder_key, folder_path)
163178
response = (
164179
await self.request_async(
165180
spec.method,
@@ -178,6 +193,7 @@ def search(
178193
memory_space_id: str,
179194
request: MemorySearchRequest,
180195
folder_key: Optional[str] = None,
196+
folder_path: Optional[str] = None,
181197
) -> MemorySearchResponse:
182198
"""Search a memory space via LLMOps.
183199
@@ -188,11 +204,12 @@ def search(
188204
memory_space_id: The GUID of the memory space.
189205
request: The search request payload.
190206
folder_key: The folder key for the operation.
207+
folder_path: The folder path for the operation.
191208
192209
Returns:
193210
MemorySearchResponse: Results, metadata, and system prompt injection.
194211
"""
195-
spec = self._search_spec(memory_space_id, folder_key)
212+
spec = self._search_spec(memory_space_id, folder_key, folder_path)
196213
response = self.request(
197214
spec.method,
198215
spec.endpoint,
@@ -207,6 +224,7 @@ async def search_async(
207224
memory_space_id: str,
208225
request: MemorySearchRequest,
209226
folder_key: Optional[str] = None,
227+
folder_path: Optional[str] = None,
210228
) -> MemorySearchResponse:
211229
"""Asynchronously search a memory space via LLMOps.
212230
@@ -217,11 +235,12 @@ async def search_async(
217235
memory_space_id: The GUID of the memory space.
218236
request: The search request payload.
219237
folder_key: The folder key for the operation.
238+
folder_path: The folder path for the operation.
220239
221240
Returns:
222241
MemorySearchResponse: Results, metadata, and system prompt injection.
223242
"""
224-
spec = self._search_spec(memory_space_id, folder_key)
243+
spec = self._search_spec(memory_space_id, folder_key, folder_path)
225244
response = (
226245
await self.request_async(
227246
spec.method,
@@ -240,6 +259,7 @@ def escalation_search(
240259
memory_space_id: str,
241260
request: MemorySearchRequest,
242261
folder_key: Optional[str] = None,
262+
folder_path: Optional[str] = None,
243263
) -> EscalationMemorySearchResponse:
244264
"""Search escalation memory for previously resolved outcomes.
245265
@@ -250,11 +270,12 @@ def escalation_search(
250270
memory_space_id: The GUID of the memory space.
251271
request: The search request payload (same as regular search).
252272
folder_key: The folder key for the operation.
273+
folder_path: The folder path for the operation.
253274
254275
Returns:
255276
EscalationMemorySearchResponse: Matched escalation outcomes.
256277
"""
257-
spec = self._escalation_search_spec(memory_space_id, folder_key)
278+
spec = self._escalation_search_spec(memory_space_id, folder_key, folder_path)
258279
response = self.request(
259280
spec.method,
260281
spec.endpoint,
@@ -269,6 +290,7 @@ async def escalation_search_async(
269290
memory_space_id: str,
270291
request: MemorySearchRequest,
271292
folder_key: Optional[str] = None,
293+
folder_path: Optional[str] = None,
272294
) -> EscalationMemorySearchResponse:
273295
"""Asynchronously search escalation memory for previously resolved outcomes.
274296
@@ -279,11 +301,12 @@ async def escalation_search_async(
279301
memory_space_id: The GUID of the memory space.
280302
request: The search request payload (same as regular search).
281303
folder_key: The folder key for the operation.
304+
folder_path: The folder path for the operation.
282305
283306
Returns:
284307
EscalationMemorySearchResponse: Matched escalation outcomes.
285308
"""
286-
spec = self._escalation_search_spec(memory_space_id, folder_key)
309+
spec = self._escalation_search_spec(memory_space_id, folder_key, folder_path)
287310
response = (
288311
await self.request_async(
289312
spec.method,
@@ -300,6 +323,7 @@ def escalation_ingest(
300323
memory_space_id: str,
301324
request: EscalationMemoryIngestRequest,
302325
folder_key: Optional[str] = None,
326+
folder_path: Optional[str] = None,
303327
) -> None:
304328
"""Ingest a resolved escalation outcome into memory.
305329
@@ -310,8 +334,9 @@ def escalation_ingest(
310334
memory_space_id: The GUID of the memory space.
311335
request: The escalation ingest payload.
312336
folder_key: The folder key for the operation.
337+
folder_path: The folder path for the operation.
313338
"""
314-
spec = self._escalation_ingest_spec(memory_space_id, folder_key)
339+
spec = self._escalation_ingest_spec(memory_space_id, folder_key, folder_path)
315340
self.request(
316341
spec.method,
317342
spec.endpoint,
@@ -325,6 +350,7 @@ async def escalation_ingest_async(
325350
memory_space_id: str,
326351
request: EscalationMemoryIngestRequest,
327352
folder_key: Optional[str] = None,
353+
folder_path: Optional[str] = None,
328354
) -> None:
329355
"""Asynchronously ingest a resolved escalation outcome into memory.
330356
@@ -335,8 +361,9 @@ async def escalation_ingest_async(
335361
memory_space_id: The GUID of the memory space.
336362
request: The escalation ingest payload.
337363
folder_key: The folder key for the operation.
364+
folder_path: The folder path for the operation.
338365
"""
339-
spec = self._escalation_ingest_spec(memory_space_id, folder_key)
366+
spec = self._escalation_ingest_spec(memory_space_id, folder_key, folder_path)
340367
await self.request_async(
341368
spec.method,
342369
spec.endpoint,
@@ -379,8 +406,9 @@ def _create_spec(
379406
description: Optional[str],
380407
is_encrypted: Optional[bool],
381408
folder_key: Optional[str] = None,
409+
folder_path: Optional[str] = None,
382410
) -> RequestSpec:
383-
folder_key = self._resolve_folder(folder_key)
411+
folder_key = self._resolve_folder(folder_key, folder_path)
384412
body = MemorySpaceCreateRequest(
385413
name=name,
386414
description=description,
@@ -400,8 +428,9 @@ def _list_spec(
400428
top: Optional[int],
401429
skip: Optional[int],
402430
folder_key: Optional[str] = None,
431+
folder_path: Optional[str] = None,
403432
) -> RequestSpec:
404-
folder_key = self._resolve_folder(folder_key)
433+
folder_key = self._resolve_folder(folder_key, folder_path)
405434
params: dict[str, Any] = {}
406435
if filter is not None:
407436
params["$filter"] = filter
@@ -424,8 +453,9 @@ def _search_spec(
424453
self,
425454
memory_space_id: str,
426455
folder_key: Optional[str] = None,
456+
folder_path: Optional[str] = None,
427457
) -> RequestSpec:
428-
folder_key = self._resolve_folder(folder_key)
458+
folder_key = self._resolve_folder(folder_key, folder_path)
429459
return RequestSpec(
430460
method="POST",
431461
endpoint=Endpoint(f"{_LLMOPS_AGENT_BASE}/{memory_space_id}/search"),
@@ -436,8 +466,9 @@ def _escalation_search_spec(
436466
self,
437467
memory_space_id: str,
438468
folder_key: Optional[str] = None,
469+
folder_path: Optional[str] = None,
439470
) -> RequestSpec:
440-
folder_key = self._resolve_folder(folder_key)
471+
folder_key = self._resolve_folder(folder_key, folder_path)
441472
return RequestSpec(
442473
method="POST",
443474
endpoint=Endpoint(
@@ -450,8 +481,9 @@ def _escalation_ingest_spec(
450481
self,
451482
memory_space_id: str,
452483
folder_key: Optional[str] = None,
484+
folder_path: Optional[str] = None,
453485
) -> RequestSpec:
454-
folder_key = self._resolve_folder(folder_key)
486+
folder_key = self._resolve_folder(folder_key, folder_path)
455487
return RequestSpec(
456488
method="POST",
457489
endpoint=Endpoint(

packages/uipath-platform/src/uipath/platform/resume_triggers/_protocol.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
ContextGroundingIndex,
5454
)
5555
from uipath.platform.errors import (
56+
BatchTransformFailedException,
5657
BatchTransformNotCompleteException,
5758
OperationNotCompleteException,
5859
)
@@ -323,6 +324,11 @@ async def read_trigger(self, trigger: UiPathResumeTrigger) -> Any | None:
323324
"index_name", trigger.payload
324325
),
325326
)
327+
except BatchTransformFailedException as e:
328+
raise UiPathFaultedTriggerError(
329+
ErrorCategory.SYSTEM,
330+
f"{e.message}",
331+
) from e
326332
except BatchTransformNotCompleteException as e:
327333
raise UiPathPendingTriggerError(
328334
ErrorCategory.SYSTEM,

0 commit comments

Comments
 (0)