Skip to content

Commit 0e7732c

Browse files
add create ephemeral index
1 parent 4224bc1 commit 0e7732c

File tree

6 files changed

+101
-62
lines changed

6 files changed

+101
-62
lines changed

src/uipath/platform/common/interrupt_models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ class WaitDeepRag(BaseModel):
8484
index_folder_key: str | None = None
8585

8686

87+
class CreateEphemeralIndex(BaseModel):
88+
"""Model representing a Jit Index task creation."""
89+
90+
usage: str
91+
attachments: list[str]
92+
93+
94+
class WaitEphemeralIndex(BaseModel):
95+
"""Model representing a wait Jit Index task."""
96+
97+
id: str
98+
99+
87100
class CreateBatchTransform(BaseModel):
88101
"""Model representing a Batch Transform task creation."""
89102

src/uipath/platform/context_grounding/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
DeepRagCreationResponse,
1313
DeepRagResponse,
1414
DeepRagStatus,
15+
IndexStatus,
1516
)
1617
from .context_grounding_index import ContextGroundingIndex
1718
from .context_grounding_payloads import (
@@ -52,6 +53,7 @@
5253
"DeepRagCreationResponse",
5354
"DeepRagResponse",
5455
"DeepRagStatus",
56+
"IndexStatus",
5557
"DropboxDataSource",
5658
"DropboxSourceConfig",
5759
"GoogleDriveDataSource",

src/uipath/platform/context_grounding/_context_grounding_service.py

Lines changed: 18 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
import httpx
66
from pydantic import Field, TypeAdapter
7-
from typing_extensions import deprecated
87

98
from ..._utils import Endpoint, RequestSpec, header_folder, resource_override
109
from ..._utils._ssl_context import get_httpx_client_kwargs
@@ -39,8 +38,8 @@
3938
BucketSourceConfig,
4039
ConfluenceDataSource,
4140
ConfluenceSourceConfig,
41+
CreateEphemeralIndexPayload,
4242
CreateIndexPayload,
43-
CreateJitIndexPayload,
4443
DropboxDataSource,
4544
DropboxSourceConfig,
4645
GoogleDriveDataSource,
@@ -279,31 +278,19 @@ async def retrieve_async(
279278
raise Exception("ContextGroundingIndex not found") from e
280279

281280
@traced(name="contextgrounding_retrieve_by_id", run_type="uipath")
282-
@deprecated("Use retrieve instead")
283-
def retrieve_by_id(
284-
self,
285-
id: str,
286-
folder_key: Optional[str] = None,
287-
folder_path: Optional[str] = None,
288-
) -> Any:
281+
def retrieve_by_id(self, id: str) -> Any:
289282
"""Retrieve context grounding index information by its ID.
290283
291284
This method provides direct access to a context index using its unique
292285
identifier, which can be more efficient than searching by name.
293286
294287
Args:
295288
id (str): The unique identifier of the context index.
296-
folder_key (Optional[str]): The key of the folder where the index resides.
297-
folder_path (Optional[str]): The path of the folder where the index resides.
298289
299290
Returns:
300291
Any: The index information, including its configuration and metadata.
301292
"""
302-
spec = self._retrieve_by_id_spec(
303-
id,
304-
folder_key=folder_key,
305-
folder_path=folder_path,
306-
)
293+
spec = self._retrieve_by_id_spec(id)
307294

308295
return self.request(
309296
spec.method,
@@ -312,31 +299,19 @@ def retrieve_by_id(
312299
).json()
313300

314301
@traced(name="contextgrounding_retrieve_by_id", run_type="uipath")
315-
@deprecated("Use retrieve_async instead")
316-
async def retrieve_by_id_async(
317-
self,
318-
id: str,
319-
folder_key: Optional[str] = None,
320-
folder_path: Optional[str] = None,
321-
) -> Any:
302+
async def retrieve_by_id_async(self, id: str) -> Any:
322303
"""Retrieve asynchronously context grounding index information by its ID.
323304
324305
This method provides direct access to a context index using its unique
325306
identifier, which can be more efficient than searching by name.
326307
327308
Args:
328309
id (str): The unique identifier of the context index.
329-
folder_key (Optional[str]): The key of the folder where the index resides.
330-
folder_path (Optional[str]): The path of the folder where the index resides.
331310
332311
Returns:
333312
Any: The index information, including its configuration and metadata.
334313
"""
335-
spec = self._retrieve_by_id_spec(
336-
id,
337-
folder_key=folder_key,
338-
folder_path=folder_path,
339-
)
314+
spec = self._retrieve_by_id_spec(id)
340315

341316
response = await self.request_async(
342317
spec.method,
@@ -402,20 +377,16 @@ def create_index(
402377
return ContextGroundingIndex.model_validate(response.json())
403378

404379
@resource_override(resource_type="index")
405-
@traced(name="contextgrounding_create_jit_index", run_type="uipath")
406-
def create_jit_index(
380+
@traced(name="contextgrounding_create_ephemeral_index", run_type="uipath")
381+
def create_ephemeral_index(
407382
self,
408383
usage: str,
409384
attachments: list[uuid.UUID],
410-
folder_key: Optional[str] = None,
411-
folder_path: Optional[str] = None,
412385
) -> ContextGroundingIndex:
413-
"""Create a new context jit grounding index."""
414-
spec = self._create_jit_spec(
386+
"""Create a new context ephemeral grounding index."""
387+
spec = self._create_ephemeral_spec(
415388
usage,
416389
attachments,
417-
folder_path=folder_path,
418-
folder_key=folder_key,
419390
)
420391

421392
response = self.request(
@@ -1226,19 +1197,15 @@ def _create_spec(
12261197
},
12271198
)
12281199

1229-
def _create_jit_spec(
1200+
def _create_ephemeral_spec(
12301201
self,
12311202
usage: str,
12321203
attachments: list[uuid.UUID] = None,
1233-
folder_key: Optional[str] = None,
1234-
folder_path: Optional[str] = None,
12351204
) -> RequestSpec:
12361205
"""Create request spec for index creation."""
1237-
folder_key = self._resolve_folder_key(folder_key, folder_path)
1206+
data_source_dict = self._build_ephemeral_data_source(attachments)
12381207

1239-
data_source_dict = self._build_jit_data_source(attachments)
1240-
1241-
payload = CreateJitIndexPayload(
1208+
payload = CreateEphemeralIndexPayload(
12421209
usage=usage,
12431210
data_source=data_source_dict,
12441211
)
@@ -1247,12 +1214,12 @@ def _create_jit_spec(
12471214
method="POST",
12481215
endpoint=Endpoint("/ecs_/v2/indexes/createephemeral"),
12491216
json=payload.model_dump(by_alias=True, exclude_none=True),
1250-
headers={
1251-
**header_folder(folder_key, None),
1252-
},
1217+
headers={},
12531218
)
12541219

1255-
def _build_jit_data_source(self, attachments: list[uuid.UUID]) -> Dict[str, Any]:
1220+
def _build_ephemeral_data_source(
1221+
self, attachments: list[uuid.UUID]
1222+
) -> Dict[str, Any]:
12561223
data_source: AttachmentsDataSource
12571224
data_source = AttachmentsDataSource(attachments=attachments)
12581225
return data_source.model_dump(
@@ -1329,20 +1296,11 @@ def _build_data_source(self, source: SourceConfig) -> Dict[str, Any]:
13291296

13301297
return data_source.model_dump(by_alias=True, exclude_none=True)
13311298

1332-
def _retrieve_by_id_spec(
1333-
self,
1334-
id: str,
1335-
folder_key: Optional[str] = None,
1336-
folder_path: Optional[str] = None,
1337-
) -> RequestSpec:
1338-
folder_key = self._resolve_folder_key(folder_key, folder_path)
1339-
1299+
def _retrieve_by_id_spec(self, id: str) -> RequestSpec:
13401300
return RequestSpec(
13411301
method="GET",
13421302
endpoint=Endpoint(f"/ecs_/v2/indexes/{id}"),
1343-
headers={
1344-
**header_folder(folder_key, None),
1345-
},
1303+
headers={},
13461304
)
13471305

13481306
def _delete_by_id_spec(

src/uipath/platform/context_grounding/context_grounding.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ class DeepRagStatus(str, Enum):
4141
FAILED = "Failed"
4242

4343

44+
class IndexStatus(str, Enum):
45+
"""Enum representing possible index tasks status."""
46+
47+
QUEUED = "Queued"
48+
IN_PROGRESS = "InProgress"
49+
SUCCESSFUL = "Successful"
50+
FAILED = "Failed"
51+
52+
4453
class Citation(BaseModel):
4554
"""Model representing a deep RAG citation."""
4655

src/uipath/platform/context_grounding/context_grounding_payloads.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ class CreateIndexPayload(BaseModel):
141141
model_config = ConfigDict(populate_by_name=True)
142142

143143

144-
class CreateJitIndexPayload(BaseModel):
144+
class CreateEphemeralIndexPayload(BaseModel):
145145
""" """
146146

147147
usage: str = Field(description="Index usage")

src/uipath/platform/resume_triggers/_protocol.py

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,14 @@
3535
WaitJob,
3636
WaitTask,
3737
)
38-
from uipath.platform.context_grounding import DeepRagStatus
38+
from uipath.platform.common.interrupt_models import (
39+
CreateEphemeralIndex,
40+
WaitEphemeralIndex,
41+
)
42+
from uipath.platform.context_grounding import DeepRagStatus, IndexStatus
43+
from uipath.platform.context_grounding.context_grounding_index import (
44+
ContextGroundingIndex,
45+
)
3946
from uipath.platform.errors import (
4047
BatchTransformNotCompleteException,
4148
ExtractionNotCompleteException,
@@ -226,6 +233,33 @@ async def read_trigger(self, trigger: UiPathResumeTrigger) -> Any | None:
226233

227234
return trigger_response
228235

236+
case UiPathResumeTriggerType.EPHEMERAL_INDEX:
237+
if trigger.item_key:
238+
index = uipath.context_grounding.retrieve_by_id(trigger.item_key)
239+
240+
ephemeral_index = ContextGroundingIndex(**index)
241+
242+
ephemeral_index_status = ephemeral_index.last_ingestion_status
243+
244+
if ephemeral_index_status in (
245+
IndexStatus.QUEUED,
246+
IndexStatus.IN_PROGRESS,
247+
):
248+
raise UiPathPendingTriggerError(
249+
ErrorCategory.SYSTEM,
250+
f"Index ingestion is not finished yet. Current status: {ephemeral_index_status}",
251+
)
252+
253+
if ephemeral_index_status != IndexStatus.SUCCESSFUL:
254+
raise UiPathFaultedTriggerError(
255+
ErrorCategory.USER,
256+
f"Index ingestion '{ephemeral_index.name}' did not finish successfully.",
257+
)
258+
259+
trigger_response = ephemeral_index
260+
261+
return trigger_response
262+
229263
case UiPathResumeTriggerType.BATCH_RAG:
230264
if trigger.item_key:
231265
destination_path = self._extract_field(
@@ -354,6 +388,10 @@ async def create_trigger(self, suspend_value: Any) -> UiPathResumeTrigger:
354388
await self._handle_deep_rag_job_trigger(
355389
suspend_value, resume_trigger, uipath
356390
)
391+
case UiPathResumeTriggerType.EPHEMERAL_INDEX:
392+
await self._handle_ephemeral_index_job_trigger(
393+
suspend_value, resume_trigger, uipath
394+
)
357395
case UiPathResumeTriggerType.BATCH_RAG:
358396
await self._handle_batch_rag_job_trigger(
359397
suspend_value, resume_trigger, uipath
@@ -391,6 +429,8 @@ def _determine_trigger_type(self, value: Any) -> UiPathResumeTriggerType:
391429
return UiPathResumeTriggerType.JOB
392430
if isinstance(value, (CreateDeepRag, WaitDeepRag)):
393431
return UiPathResumeTriggerType.DEEP_RAG
432+
if isinstance(value, (CreateEphemeralIndex, WaitEphemeralIndex)):
433+
return UiPathResumeTriggerType.EPHEMERAL_INDEX
394434
if isinstance(value, (CreateBatchTransform, WaitBatchTransform)):
395435
return UiPathResumeTriggerType.BATCH_RAG
396436
if isinstance(value, (DocumentExtraction, WaitDocumentExtraction)):
@@ -415,6 +455,8 @@ def _determine_trigger_name(self, value: Any) -> UiPathResumeTriggerName:
415455
return UiPathResumeTriggerName.JOB
416456
if isinstance(value, (CreateDeepRag, WaitDeepRag)):
417457
return UiPathResumeTriggerName.DEEP_RAG
458+
if isinstance(value, (CreateEphemeralIndex, WaitEphemeralIndex)):
459+
return UiPathResumeTriggerName.EPHEMERAL_INDEX
418460
if isinstance(value, (CreateBatchTransform, WaitBatchTransform)):
419461
return UiPathResumeTriggerName.BATCH_RAG
420462
if isinstance(value, (DocumentExtraction, WaitDocumentExtraction)):
@@ -479,6 +521,21 @@ async def _handle_deep_rag_job_trigger(
479521
raise Exception("Failed to start deep rag")
480522
resume_trigger.item_key = deep_rag.id
481523

524+
async def _handle_ephemeral_index_job_trigger(
525+
self, value: Any, resume_trigger: UiPathResumeTrigger, uipath: UiPath
526+
) -> None:
527+
"""Handle ephemeral index"""
528+
if isinstance(value, WaitEphemeralIndex):
529+
resume_trigger.item_key = value.ephemeral_index.id
530+
elif isinstance(value, CreateEphemeralIndex):
531+
ephemeral_index = uipath.context_grounding.create_ephemeral_index(
532+
usage=value.usage,
533+
attachments=value.attachments,
534+
)
535+
if not ephemeral_index:
536+
raise Exception("Failed to start ephemeral index")
537+
resume_trigger.item_key = ephemeral_index.id
538+
482539
async def _handle_batch_rag_job_trigger(
483540
self, value: Any, resume_trigger: UiPathResumeTrigger, uipath: UiPath
484541
) -> None:

0 commit comments

Comments
 (0)