Skip to content

Commit 94c30aa

Browse files
feat: add ecs jit sdk
1 parent 46d6ff2 commit 94c30aa

File tree

10 files changed

+511
-21
lines changed

10 files changed

+511
-21
lines changed

src/uipath/platform/common/interrupt_models.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44

55
from pydantic import BaseModel, ConfigDict, Field, model_validator
66

7+
from uipath.platform.context_grounding.context_grounding_index import (
8+
ContextGroundingIndex,
9+
)
10+
711
from ..action_center.tasks import Task, TaskRecipient
812
from ..context_grounding import (
913
BatchTransformCreationResponse,
1014
BatchTransformOutputColumn,
1115
CitationMode,
1216
DeepRagCreationResponse,
17+
EphemeralIndexUsage,
1318
)
1419
from ..documents import FileContent, StartExtractionResponse
1520
from ..orchestrator.job import Job
@@ -85,6 +90,19 @@ class WaitDeepRag(BaseModel):
8590
index_folder_key: str | None = None
8691

8792

93+
class CreateEphemeralIndex(BaseModel):
94+
"""Model representing a Ephemeral Index task creation."""
95+
96+
usage: EphemeralIndexUsage
97+
attachments: list[str]
98+
99+
100+
class WaitEphemeralIndex(BaseModel):
101+
"""Model representing a wait Ephemeral Index task."""
102+
103+
index: ContextGroundingIndex
104+
105+
88106
class CreateBatchTransform(BaseModel):
89107
"""Model representing a Batch Transform task creation."""
90108

src/uipath/platform/context_grounding/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
DeepRagCreationResponse,
1313
DeepRagResponse,
1414
DeepRagStatus,
15+
EphemeralIndexUsage,
16+
IndexStatus,
1517
)
1618
from .context_grounding_index import ContextGroundingIndex
1719
from .context_grounding_payloads import (
@@ -52,8 +54,10 @@
5254
"DeepRagCreationResponse",
5355
"DeepRagResponse",
5456
"DeepRagStatus",
57+
"IndexStatus",
5558
"DropboxDataSource",
5659
"DropboxSourceConfig",
60+
"EphemeralIndexUsage",
5761
"GoogleDriveDataSource",
5862
"GoogleDriveSourceConfig",
5963
"Indexer",

src/uipath/platform/context_grounding/_context_grounding_service.py

Lines changed: 109 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
import httpx
55
from pydantic import Field, TypeAdapter
6-
from typing_extensions import deprecated
76

87
from ..._utils import Endpoint, RequestSpec, header_folder, resource_override
98
from ..._utils._ssl_context import get_httpx_client_kwargs
@@ -30,13 +29,16 @@
3029
ContextGroundingQueryResponse,
3130
DeepRagCreationResponse,
3231
DeepRagResponse,
32+
EphemeralIndexUsage,
3333
)
3434
from .context_grounding_index import ContextGroundingIndex
3535
from .context_grounding_payloads import (
36+
AttachmentsDataSource,
3637
BucketDataSource,
3738
BucketSourceConfig,
3839
ConfluenceDataSource,
3940
ConfluenceSourceConfig,
41+
CreateEphemeralIndexPayload,
4042
CreateIndexPayload,
4143
DropboxDataSource,
4244
DropboxSourceConfig,
@@ -276,7 +278,6 @@ async def retrieve_async(
276278
raise Exception("ContextGroundingIndex not found") from e
277279

278280
@traced(name="contextgrounding_retrieve_by_id", run_type="uipath")
279-
@deprecated("Use retrieve instead")
280281
def retrieve_by_id(
281282
self,
282283
id: str,
@@ -296,11 +297,7 @@ def retrieve_by_id(
296297
Returns:
297298
Any: The index information, including its configuration and metadata.
298299
"""
299-
spec = self._retrieve_by_id_spec(
300-
id,
301-
folder_key=folder_key,
302-
folder_path=folder_path,
303-
)
300+
spec = self._retrieve_by_id_spec(id)
304301

305302
return self.request(
306303
spec.method,
@@ -309,7 +306,6 @@ def retrieve_by_id(
309306
).json()
310307

311308
@traced(name="contextgrounding_retrieve_by_id", run_type="uipath")
312-
@deprecated("Use retrieve_async instead")
313309
async def retrieve_by_id_async(
314310
self,
315311
id: str,
@@ -329,11 +325,7 @@ async def retrieve_by_id_async(
329325
Returns:
330326
Any: The index information, including its configuration and metadata.
331327
"""
332-
spec = self._retrieve_by_id_spec(
333-
id,
334-
folder_key=folder_key,
335-
folder_path=folder_path,
336-
)
328+
spec = self._retrieve_by_id_spec(id)
337329

338330
response = await self.request_async(
339331
spec.method,
@@ -453,6 +445,66 @@ async def create_index_async(
453445

454446
return ContextGroundingIndex.model_validate(response.json())
455447

448+
@resource_override(resource_type="index")
449+
@traced(name="contextgrounding_create_ephemeral_index", run_type="uipath")
450+
def create_ephemeral_index(
451+
self,
452+
usage: EphemeralIndexUsage,
453+
attachments: list[str],
454+
) -> ContextGroundingIndex:
455+
"""Create a new ephemeral context grounding index.
456+
457+
Args:
458+
usage (EphemeralIndexUsage): The task type for the ephemeral index (DeepRAG or BatchRAG)
459+
attachments (list[str]): The list of attachments ids from which the ephemeral index will be created
460+
461+
Returns:
462+
ContextGroundingIndex: The created index information.
463+
"""
464+
spec = self._create_ephemeral_spec(
465+
usage,
466+
attachments,
467+
)
468+
469+
response = self.request(
470+
spec.method,
471+
spec.endpoint,
472+
json=spec.json,
473+
headers=spec.headers,
474+
)
475+
476+
return ContextGroundingIndex.model_validate(response.json())
477+
478+
@resource_override(resource_type="index")
479+
@traced(name="contextgrounding_create_ephemeral_index", run_type="uipath")
480+
async def create_ephemeral_index_async(
481+
self,
482+
usage: EphemeralIndexUsage,
483+
attachments: list[str],
484+
) -> ContextGroundingIndex:
485+
"""Create a new ephemeral context grounding index.
486+
487+
Args:
488+
usage (EphemeralIndexUsage): The task type for the ephemeral index (DeepRAG or BatchRAG)
489+
attachments (list[str]): The list of attachments ids from which the ephemeral index will be created
490+
491+
Returns:
492+
ContextGroundingIndex: The created index information.
493+
"""
494+
spec = self._create_ephemeral_spec(
495+
usage,
496+
attachments,
497+
)
498+
499+
response = await self.request_async(
500+
spec.method,
501+
spec.endpoint,
502+
json=spec.json,
503+
headers=spec.headers,
504+
)
505+
506+
return ContextGroundingIndex.model_validate(response.json())
507+
456508
@resource_override(resource_type="index", resource_identifier="index_name")
457509
@traced(name="contextgrounding_retrieve_deep_rag", run_type="uipath")
458510
def retrieve_deep_rag(
@@ -1197,6 +1249,34 @@ def _create_spec(
11971249
},
11981250
)
11991251

1252+
def _create_ephemeral_spec(
1253+
self,
1254+
usage: str,
1255+
attachments: list[str],
1256+
) -> RequestSpec:
1257+
"""Create request spec for ephemeral index creation.
1258+
1259+
Args:
1260+
usage (str): The task in which the ephemeral index will be used for
1261+
attachments (list[str]): The list of attachments ids from which the ephemeral index will be created
1262+
1263+
Returns:
1264+
RequestSpec for the create index request
1265+
"""
1266+
data_source_dict = self._build_ephemeral_data_source(attachments)
1267+
1268+
payload = CreateEphemeralIndexPayload(
1269+
usage=usage,
1270+
data_source=data_source_dict,
1271+
)
1272+
1273+
return RequestSpec(
1274+
method="POST",
1275+
endpoint=Endpoint("/ecs_/v2/indexes/createephemeral"),
1276+
json=payload.model_dump(by_alias=True, exclude_none=True),
1277+
headers={},
1278+
)
1279+
12001280
def _build_data_source(self, source: SourceConfig) -> Dict[str, Any]:
12011281
"""Build data source configuration from typed source config.
12021282
@@ -1265,14 +1345,29 @@ def _build_data_source(self, source: SourceConfig) -> Dict[str, Any]:
12651345

12661346
return data_source.model_dump(by_alias=True, exclude_none=True)
12671347

1348+
def _build_ephemeral_data_source(self, attachments: list[str]) -> Dict[str, Any]:
1349+
"""Build data source configuration from typed source config.
1350+
1351+
Args:
1352+
attachments (list[str]): The list of attachments ids from which the ephemeral index will be created
1353+
1354+
Returns:
1355+
Dictionary with data source configuration for API
1356+
"""
1357+
data_source = AttachmentsDataSource(attachments=attachments)
1358+
return data_source.model_dump(
1359+
by_alias=True,
1360+
exclude_none=True,
1361+
mode="json",
1362+
)
1363+
12681364
def _retrieve_by_id_spec(
12691365
self,
12701366
id: str,
12711367
folder_key: Optional[str] = None,
12721368
folder_path: Optional[str] = None,
12731369
) -> RequestSpec:
12741370
folder_key = self._resolve_folder_key(folder_key, folder_path)
1275-
12761371
return RequestSpec(
12771372
method="GET",
12781373
endpoint=Endpoint(f"/ecs_/v2/indexes/{id}"),
@@ -1422,9 +1517,6 @@ def _resolve_folder_key(self, folder_key, folder_path):
14221517
else None
14231518
)
14241519

1425-
if folder_key is None:
1426-
raise ValueError("ContextGrounding: Failed to resolve folder key")
1427-
14281520
return folder_key
14291521

14301522
def _extract_bucket_info(self, index: ContextGroundingIndex) -> Tuple[str, str]:

src/uipath/platform/context_grounding/context_grounding.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ class CitationMode(str, Enum):
3232
INLINE = "Inline"
3333

3434

35+
class EphemeralIndexUsage(str, Enum):
36+
"""Enum representing possible ephemeral index usage types."""
37+
38+
DEEP_RAG = "DeepRAG"
39+
BATCH_RAG = "BatchRAG"
40+
41+
3542
class DeepRagStatus(str, Enum):
3643
"""Enum representing possible deep RAG tasks status."""
3744

@@ -41,6 +48,15 @@ class DeepRagStatus(str, Enum):
4148
FAILED = "Failed"
4249

4350

51+
class IndexStatus(str, Enum):
52+
"""Enum representing possible index tasks status."""
53+
54+
QUEUED = "Queued"
55+
IN_PROGRESS = "InProgress"
56+
SUCCESSFUL = "Successful"
57+
FAILED = "Failed"
58+
59+
4460
class Citation(BaseModel):
4561
"""Model representing a deep RAG citation."""
4662

src/uipath/platform/context_grounding/context_grounding_index.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ class ContextGroundingIndex(BaseModel):
4444
extra="allow",
4545
)
4646

47-
@field_serializer("last_ingested", "last_queried", when_used="json")
47+
@field_serializer("last_ingested", "last_queried")
4848
def serialize_datetime(self, value):
49-
"""Serialize datetime fields to ISO 8601 format for JSON output."""
49+
"""Serialize datetime fields to ISO 8601 format."""
5050
if isinstance(value, datetime):
5151
return value.isoformat() if value else None
5252
return value

src/uipath/platform/context_grounding/context_grounding_payloads.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ class ConfluenceDataSource(DataSourceBase):
8282
space_id: str = Field(alias="spaceId", description="Space ID")
8383

8484

85+
class AttachmentsDataSource(BaseModel):
86+
"""Data source configuration for Attachments."""
87+
88+
attachments: list[str] = Field(description="List of attachment ids")
89+
90+
8591
class Indexer(BaseModel):
8692
"""Configuration for periodic indexing of data sources."""
8793

@@ -136,6 +142,23 @@ class CreateIndexPayload(BaseModel):
136142
model_config = ConfigDict(populate_by_name=True)
137143

138144

145+
class CreateEphemeralIndexPayload(BaseModel):
146+
"""Payload for creating an ephemeral context grounding index.
147+
148+
Note: data_source is Dict[str, Any] because it may contain additional
149+
fields like 'indexer' that are added dynamically based on configuration.
150+
The data source is still validated through the _build_data_source method
151+
which uses typed models internally.
152+
"""
153+
154+
usage: str = Field(description="Index usage")
155+
data_source: Dict[str, Any] = Field(
156+
alias="dataSource", description="Data source configuration"
157+
)
158+
159+
model_config = ConfigDict(populate_by_name=True)
160+
161+
139162
# user-facing source configuration models
140163
class BaseSourceConfig(BaseModel):
141164
"""Base configuration for all source types."""

0 commit comments

Comments
 (0)