From 25ac0333c752bbe5c0550d7248d8bffb6c5009f8 Mon Sep 17 00:00:00 2001 From: GabrielVasilescu04 Date: Thu, 5 Mar 2026 11:18:40 +0200 Subject: [PATCH] feat: add index_ingestion_raw and deep_rag_raw triggers --- packages/uipath-platform/pyproject.toml | 4 +- .../src/uipath/platform/common/__init__.py | 8 + .../platform/common/interrupt_models.py | 26 +- .../_context_grounding_service.py | 2 +- .../context_grounding/context_grounding.py | 2 + .../platform/resume_triggers/_protocol.py | 21 +- .../test_context_grounding_service.py | 12 +- .../tests/services/test_hitl.py | 384 ++++++++++++++++++ packages/uipath-platform/uv.lock | 4 +- 9 files changed, 452 insertions(+), 11 deletions(-) diff --git a/packages/uipath-platform/pyproject.toml b/packages/uipath-platform/pyproject.toml index 62804ccb1..aa19f56bd 100644 --- a/packages/uipath-platform/pyproject.toml +++ b/packages/uipath-platform/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uipath-platform" -version = "0.0.14" +version = "0.0.15" description = "HTTP client library for programmatic access to UiPath Platform" readme = { file = "README.md", content-type = "text/markdown" } requires-python = ">=3.11" @@ -8,7 +8,7 @@ dependencies = [ "httpx>=0.28.1", "tenacity>=9.0.0", "truststore>=0.10.1", - "uipath-core>=0.5.3, <0.6.0", + "uipath-core>=0.5.4, <0.6.0", "pydantic-function-models>=0.1.11", ] classifiers = [ diff --git a/packages/uipath-platform/src/uipath/platform/common/__init__.py b/packages/uipath-platform/src/uipath/platform/common/__init__.py index a9692c819..f0a82f355 100644 --- a/packages/uipath-platform/src/uipath/platform/common/__init__.py +++ b/packages/uipath-platform/src/uipath/platform/common/__init__.py @@ -29,7 +29,9 @@ from .interrupt_models import ( CreateBatchTransform, CreateDeepRag, + CreateDeepRagRaw, CreateEphemeralIndex, + CreateEphemeralIndexRaw, CreateEscalation, CreateTask, DocumentExtraction, @@ -39,9 +41,11 @@ InvokeSystemAgent, WaitBatchTransform, WaitDeepRag, + WaitDeepRagRaw, WaitDocumentExtraction, WaitDocumentExtractionValidation, WaitEphemeralIndex, + WaitEphemeralIndexRaw, WaitEscalation, WaitJob, WaitJobRaw, @@ -69,7 +73,9 @@ "WaitJobRaw", "PagedResult", "CreateDeepRag", + "CreateDeepRagRaw", "WaitDeepRag", + "WaitDeepRagRaw", "CreateBatchTransform", "WaitBatchTransform", "DocumentExtraction", @@ -77,7 +83,9 @@ "InvokeSystemAgent", "WaitSystemAgent", "CreateEphemeralIndex", + "CreateEphemeralIndexRaw", "WaitEphemeralIndex", + "WaitEphemeralIndexRaw", "DocumentExtractionValidation", "WaitDocumentExtractionValidation", "RequestSpec", diff --git a/packages/uipath-platform/src/uipath/platform/common/interrupt_models.py b/packages/uipath-platform/src/uipath/platform/common/interrupt_models.py index d406f3c38..100b601bd 100644 --- a/packages/uipath-platform/src/uipath/platform/common/interrupt_models.py +++ b/packages/uipath-platform/src/uipath/platform/common/interrupt_models.py @@ -118,6 +118,12 @@ def validate_ephemeral_index_requires_index_id(self) -> "CreateDeepRag": return self +class CreateDeepRagRaw(CreateDeepRag): + """Model representing a Deep RAG task creation (returns the deep_rag without status validation).""" + + pass + + class WaitDeepRag(BaseModel): """Model representing a wait Deep RAG task.""" @@ -126,19 +132,37 @@ class WaitDeepRag(BaseModel): index_folder_key: str | None = None +class WaitDeepRagRaw(WaitDeepRag): + """Model representing a wait Deep RAG task (returns the deep_rag without status validation).""" + + pass + + class CreateEphemeralIndex(BaseModel): - """Model representing a Ephemeral Index task creation.""" + """Model representing an Ephemeral Index task creation.""" usage: EphemeralIndexUsage attachments: list[str] +class CreateEphemeralIndexRaw(CreateEphemeralIndex): + """Model representing an Ephemeral Index task creation (returns the ephemeral index without status validation).""" + + pass + + class WaitEphemeralIndex(BaseModel): """Model representing a wait Ephemeral Index task.""" index: ContextGroundingIndex +class WaitEphemeralIndexRaw(WaitEphemeralIndex): + """Model representing a wait Ephemeral Index task (returns the ephemeral index without status validation).""" + + pass + + class CreateBatchTransform(BaseModel): """Model representing a Batch Transform task creation.""" diff --git a/packages/uipath-platform/src/uipath/platform/context_grounding/_context_grounding_service.py b/packages/uipath-platform/src/uipath/platform/context_grounding/_context_grounding_service.py index 27111b787..d1d473128 100644 --- a/packages/uipath-platform/src/uipath/platform/context_grounding/_context_grounding_service.py +++ b/packages/uipath-platform/src/uipath/platform/context_grounding/_context_grounding_service.py @@ -1808,7 +1808,7 @@ def _deep_rag_retrieve_spec( endpoint=Endpoint(f"/ecs_/v2/deeprag/{id}"), params={ "$expand": "content", - "$select": "content,name,createdDate,lastDeepRagStatus", + "$select": "id,content,name,createdDate,lastDeepRagStatus,failureReason", }, ) diff --git a/packages/uipath-platform/src/uipath/platform/context_grounding/context_grounding.py b/packages/uipath-platform/src/uipath/platform/context_grounding/context_grounding.py index 851e2a81a..8d72c8cca 100644 --- a/packages/uipath-platform/src/uipath/platform/context_grounding/context_grounding.py +++ b/packages/uipath-platform/src/uipath/platform/context_grounding/context_grounding.py @@ -99,10 +99,12 @@ class DeepRagResponse(BaseModel): arbitrary_types_allowed=True, extra="allow", ) + id: str name: str created_date: str = Field(alias="createdDate") last_deep_rag_status: DeepRagStatus = Field(alias="lastDeepRagStatus") content: DeepRagContent | None = Field(alias="content") + failure_reason: str | None = Field(alias="failureReason") class BatchTransformStatus(str, Enum): diff --git a/packages/uipath-platform/src/uipath/platform/resume_triggers/_protocol.py b/packages/uipath-platform/src/uipath/platform/resume_triggers/_protocol.py index 8a8544ccc..e52dfa641 100644 --- a/packages/uipath-platform/src/uipath/platform/resume_triggers/_protocol.py +++ b/packages/uipath-platform/src/uipath/platform/resume_triggers/_protocol.py @@ -25,7 +25,9 @@ from uipath.platform.common.interrupt_models import ( CreateBatchTransform, CreateDeepRag, + CreateDeepRagRaw, CreateEphemeralIndex, + CreateEphemeralIndexRaw, CreateEscalation, CreateTask, DocumentExtraction, @@ -35,9 +37,11 @@ InvokeSystemAgent, WaitBatchTransform, WaitDeepRag, + WaitDeepRagRaw, WaitDocumentExtraction, WaitDocumentExtractionValidation, WaitEphemeralIndex, + WaitEphemeralIndexRaw, WaitEscalation, WaitJob, WaitJobRaw, @@ -246,6 +250,9 @@ async def read_trigger(self, trigger: UiPathResumeTrigger) -> Any | None: f"DeepRag is not finished yet. Current status: {deep_rag_status}", ) + if trigger.trigger_name == UiPathResumeTriggerName.DEEP_RAG_RAW: + return deep_rag + if deep_rag_status != DeepRagStatus.SUCCESSFUL: raise UiPathFaultedTriggerError( ErrorCategory.USER, @@ -285,6 +292,12 @@ async def read_trigger(self, trigger: UiPathResumeTrigger) -> Any | None: f"Index ingestion is not finished yet. Current status: {ephemeral_index_status}", ) + if ( + trigger.trigger_name + == UiPathResumeTriggerName.INDEX_INGESTION_RAW + ): + return ephemeral_index + if ephemeral_index_status != IndexStatus.SUCCESSFUL: raise UiPathFaultedTriggerError( ErrorCategory.USER, @@ -512,7 +525,9 @@ def _determine_trigger_type(self, value: Any) -> UiPathResumeTriggerType: ), ): return UiPathResumeTriggerType.JOB - if isinstance(value, (CreateDeepRag, WaitDeepRag)): + if isinstance( + value, (CreateDeepRag, CreateDeepRagRaw, WaitDeepRag, WaitDeepRagRaw) + ): return UiPathResumeTriggerType.DEEP_RAG if isinstance(value, (CreateEphemeralIndex, WaitEphemeralIndex)): return UiPathResumeTriggerType.INDEX_INGESTION @@ -546,8 +561,12 @@ def _determine_trigger_name(self, value: Any) -> UiPathResumeTriggerName: value, (InvokeProcess, WaitJob, InvokeSystemAgent, WaitSystemAgent) ): return UiPathResumeTriggerName.JOB + if isinstance(value, (CreateDeepRagRaw, WaitDeepRagRaw)): + return UiPathResumeTriggerName.DEEP_RAG_RAW if isinstance(value, (CreateDeepRag, WaitDeepRag)): return UiPathResumeTriggerName.DEEP_RAG + if isinstance(value, (CreateEphemeralIndexRaw, WaitEphemeralIndexRaw)): + return UiPathResumeTriggerName.INDEX_INGESTION_RAW if isinstance(value, (CreateEphemeralIndex, WaitEphemeralIndex)): return UiPathResumeTriggerName.INDEX_INGESTION if isinstance(value, (CreateBatchTransform, WaitBatchTransform)): diff --git a/packages/uipath-platform/tests/services/test_context_grounding_service.py b/packages/uipath-platform/tests/services/test_context_grounding_service.py index 16560e315..f5aeec11f 100644 --- a/packages/uipath-platform/tests/services/test_context_grounding_service.py +++ b/packages/uipath-platform/tests/services/test_context_grounding_service.py @@ -987,9 +987,10 @@ def test_retrieve_deep_rag( ) -> None: citation = Citation(ordinal=1, page_number=1, source="abc", reference="abc") httpx_mock.add_response( - url=f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?$expand=content&$select=content,name,createdDate,lastDeepRagStatus", + url=f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?$expand=content&$select=id,content,name,createdDate,lastDeepRagStatus,failureReason", status_code=200, json={ + "id": "test-task-id", "name": "test-deep-rag-task", "createdDate": "2024-01-15T10:30:00Z", "lastDeepRagStatus": "Successful", @@ -997,6 +998,7 @@ def test_retrieve_deep_rag( "text": "This is the deep RAG response text.", "citations": [citation.model_dump()], }, + "failureReason": None, }, ) @@ -1017,7 +1019,7 @@ def test_retrieve_deep_rag( assert sent_requests[0].method == "GET" assert ( sent_requests[0].url - == f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?%24expand=content&%24select=content%2Cname%2CcreatedDate%2ClastDeepRagStatus" + == f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?%24expand=content&%24select=id%2Ccontent%2Cname%2CcreatedDate%2ClastDeepRagStatus%2CfailureReason" ) assert HEADER_USER_AGENT in sent_requests[0].headers @@ -1039,9 +1041,10 @@ async def test_retrieve_deep_rag_async( citation = Citation(ordinal=1, page_number=1, source="abc", reference="abc") httpx_mock.add_response( - url=f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?$expand=content&$select=content,name,createdDate,lastDeepRagStatus", + url=f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?$expand=content&$select=id,content,name,createdDate,lastDeepRagStatus,failureReason", status_code=200, json={ + "id": "test-task-id", "name": "test-deep-rag-task", "createdDate": "2024-01-15T10:30:00Z", "lastDeepRagStatus": "Successful", @@ -1049,6 +1052,7 @@ async def test_retrieve_deep_rag_async( "text": "This is the deep RAG response text.", "citations": [citation.model_dump()], }, + "failureReason": None, }, ) @@ -1069,7 +1073,7 @@ async def test_retrieve_deep_rag_async( assert sent_requests[0].method == "GET" assert ( sent_requests[0].url - == f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?%24expand=content&%24select=content%2Cname%2CcreatedDate%2ClastDeepRagStatus" + == f"{base_url}{org}{tenant}/ecs_/v2/deeprag/test-task-id?%24expand=content&%24select=id%2Ccontent%2Cname%2CcreatedDate%2ClastDeepRagStatus%2CfailureReason" ) assert HEADER_USER_AGENT in sent_requests[0].headers diff --git a/packages/uipath-platform/tests/services/test_hitl.py b/packages/uipath-platform/tests/services/test_hitl.py index 89cb6c4c3..f6fb71c5c 100644 --- a/packages/uipath-platform/tests/services/test_hitl.py +++ b/packages/uipath-platform/tests/services/test_hitl.py @@ -17,17 +17,23 @@ from uipath.platform.common import ( CreateBatchTransform, CreateDeepRag, + CreateDeepRagRaw, CreateEphemeralIndex, + CreateEphemeralIndexRaw, CreateTask, DocumentExtraction, DocumentExtractionValidation, InvokeProcess, + InvokeProcessRaw, InvokeSystemAgent, WaitBatchTransform, WaitDeepRag, + WaitDeepRagRaw, WaitDocumentExtractionValidation, WaitEphemeralIndex, + WaitEphemeralIndexRaw, WaitJob, + WaitJobRaw, WaitSystemAgent, WaitTask, ) @@ -343,6 +349,71 @@ async def test_read_job_trigger_failed( process_name="process_name", ) + @pytest.mark.anyio + async def test_read_job_raw_trigger_pending( + self, + setup_test_env: None, + ) -> None: + """Test reading a pending job raw trigger still raises pending error.""" + from uipath.core.errors import UiPathPendingTriggerError + + job_key = "test-job-key" + mock_job = Job( + id=1234, + key=job_key, + state=JobState.RUNNING.value, + folder_key="d0e09040-5997-44e1-93b7-4087689521b7", + ) + mock_retrieve_async = AsyncMock(return_value=mock_job) + + with patch( + "uipath.platform.orchestrator._jobs_service.JobsService.retrieve_async", + new=mock_retrieve_async, + ): + resume_trigger = UiPathResumeTrigger( + trigger_type=UiPathResumeTriggerType.JOB, + trigger_name=UiPathResumeTriggerName.JOB_RAW, + item_key=job_key, + folder_key="test-folder", + folder_path="test-path", + ) + + with pytest.raises(UiPathPendingTriggerError): + reader = UiPathResumeTriggerReader() + await reader.read_trigger(resume_trigger) + + @pytest.mark.anyio + async def test_read_job_raw_trigger_faulted( + self, + setup_test_env: None, + ) -> None: + """Test reading a faulted job raw trigger returns the raw job without raising.""" + job_key = "test-job-key" + job_error_info = JobErrorInfo(code="error code") + mock_job = Job( + id=1234, + key=job_key, + state="Faulted", + job_error=job_error_info, + folder_key="d0e09040-5997-44e1-93b7-4087689521b7", + ) + mock_retrieve_async = AsyncMock(return_value=mock_job) + + with patch( + "uipath.platform.orchestrator._jobs_service.JobsService.retrieve_async", + new=mock_retrieve_async, + ): + resume_trigger = UiPathResumeTrigger( + trigger_type=UiPathResumeTriggerType.JOB, + trigger_name=UiPathResumeTriggerName.JOB_RAW, + item_key=job_key, + folder_key="test-folder", + folder_path="test-path", + ) + reader = UiPathResumeTriggerReader() + result = await reader.read_trigger(resume_trigger) + assert result == mock_job + @pytest.mark.anyio async def test_read_system_agent_job_trigger_successful( self, @@ -456,10 +527,12 @@ async def test_read_deep_rag_trigger_successful( ], ) mock_deep_rag = DeepRagResponse( + id=task_id, name="test-deep-rag", created_date="2024-01-01", last_deep_rag_status=DeepRagStatus.SUCCESSFUL, content=content, + failure_reason=None, ) mock_retrieve_async = AsyncMock(return_value=mock_deep_rag) @@ -496,10 +569,12 @@ async def test_read_deep_rag_trigger_pending( task_id = "test-deep-rag-id" mock_deep_rag = DeepRagResponse( + id=task_id, name="test-deep-rag", created_date="2024-01-01", last_deep_rag_status=DeepRagStatus.QUEUED, content=None, + failure_reason=None, ) mock_retrieve_async = AsyncMock(return_value=mock_deep_rag) @@ -528,10 +603,12 @@ async def test_read_deep_rag_trigger_failed( task_id = "test-deep-rag-id" mock_deep_rag = DeepRagResponse( + id=task_id, name="test-deep-rag", created_date="2024-01-01", last_deep_rag_status=DeepRagStatus.FAILED, content=None, + failure_reason="An error ocurred during the deepRAG processing", ) mock_retrieve_async = AsyncMock(return_value=mock_deep_rag) @@ -561,10 +638,12 @@ async def test_read_deep_rag_trigger_empty_response( task_id = "test-deep-rag-id" mock_deep_rag = DeepRagResponse( + id=task_id, name="test-deep-rag", created_date="2024-01-01", last_deep_rag_status=DeepRagStatus.SUCCESSFUL, content=None, + failure_reason=None, ) mock_retrieve_async = AsyncMock(return_value=mock_deep_rag) @@ -585,6 +664,77 @@ async def test_read_deep_rag_trigger_empty_response( PropertyName.INTERNAL.value: TriggerMarker.NO_CONTENT.value, } + @pytest.mark.anyio + async def test_read_deep_rag_raw_trigger_pending( + self, + setup_test_env: None, + ) -> None: + """Test reading a pending deep rag raw trigger still raises pending error.""" + from uipath.core.errors import UiPathPendingTriggerError + + from uipath.platform.context_grounding import DeepRagResponse + + task_id = "test-deep-rag-id" + mock_deep_rag = DeepRagResponse( + id=task_id, + name="test-deep-rag", + created_date="2024-01-01", + last_deep_rag_status=DeepRagStatus.QUEUED, + content=None, + failure_reason=None, + ) + mock_retrieve_async = AsyncMock(return_value=mock_deep_rag) + + with patch( + "uipath.platform.context_grounding._context_grounding_service.ContextGroundingService.retrieve_deep_rag_async", + new=mock_retrieve_async, + ): + resume_trigger = UiPathResumeTrigger( + trigger_type=UiPathResumeTriggerType.DEEP_RAG, + trigger_name=UiPathResumeTriggerName.DEEP_RAG_RAW, + item_key=task_id, + folder_key="test-folder", + folder_path="test-path", + ) + + with pytest.raises(UiPathPendingTriggerError): + reader = UiPathResumeTriggerReader() + await reader.read_trigger(resume_trigger) + + @pytest.mark.anyio + async def test_read_deep_rag_raw_trigger_failed( + self, + setup_test_env: None, + ) -> None: + """Test reading a failed deep rag raw trigger returns the raw response without raising.""" + from uipath.platform.context_grounding import DeepRagResponse + + task_id = "test-deep-rag-id" + mock_deep_rag = DeepRagResponse( + id=task_id, + name="test-deep-rag", + created_date="2024-01-01", + last_deep_rag_status=DeepRagStatus.FAILED, + content=None, + failure_reason="An error occurred during the deepRAG processing", + ) + mock_retrieve_async = AsyncMock(return_value=mock_deep_rag) + + with patch( + "uipath.platform.context_grounding._context_grounding_service.ContextGroundingService.retrieve_deep_rag_async", + new=mock_retrieve_async, + ): + resume_trigger = UiPathResumeTrigger( + trigger_type=UiPathResumeTriggerType.DEEP_RAG, + trigger_name=UiPathResumeTriggerName.DEEP_RAG_RAW, + item_key=task_id, + folder_key="test-folder", + folder_path="test-path", + ) + reader = UiPathResumeTriggerReader() + result = await reader.read_trigger(resume_trigger) + assert result == mock_deep_rag + @pytest.mark.anyio async def test_read_batch_rag_trigger_successful( self, @@ -748,6 +898,70 @@ async def test_read_ephemeral_index_trigger_failed( await reader.read_trigger(resume_trigger) assert exc_info.value.category == ErrorCategory.USER + @pytest.mark.anyio + async def test_read_ephemeral_index_raw_trigger_pending( + self, + setup_test_env: None, + ) -> None: + """Test reading a pending ephemeral index raw trigger still raises pending error.""" + from uipath.core.errors import UiPathPendingTriggerError + + index_id = "test-ephemeral-index-id" + index_data = { + "id": index_id, + "name": "test-index", + "lastIngestionStatus": IndexStatus.IN_PROGRESS.value, + } + + mock_retrieve_by_id = AsyncMock(return_value=index_data) + + with patch( + "uipath.platform.context_grounding._context_grounding_service.ContextGroundingService.retrieve_by_id_async", + new=mock_retrieve_by_id, + ): + resume_trigger = UiPathResumeTrigger( + trigger_type=UiPathResumeTriggerType.INDEX_INGESTION, + trigger_name=UiPathResumeTriggerName.INDEX_INGESTION_RAW, + item_key=index_id, + ) + + with pytest.raises(UiPathPendingTriggerError): + reader = UiPathResumeTriggerReader() + await reader.read_trigger(resume_trigger) + + @pytest.mark.anyio + async def test_read_ephemeral_index_raw_trigger_failed( + self, + setup_test_env: None, + ) -> None: + """Test reading a failed ephemeral index raw trigger returns the raw response without raising.""" + from uipath.platform.context_grounding.context_grounding_index import ( + ContextGroundingIndex, + ) + + index_id = "test-ephemeral-index-id" + index_data = { + "id": index_id, + "name": "test-index", + "lastIngestionStatus": IndexStatus.FAILED.value, + } + + mock_retrieve_by_id = AsyncMock(return_value=index_data) + + with patch( + "uipath.platform.context_grounding._context_grounding_service.ContextGroundingService.retrieve_by_id_async", + new=mock_retrieve_by_id, + ): + resume_trigger = UiPathResumeTrigger( + trigger_type=UiPathResumeTriggerType.INDEX_INGESTION, + trigger_name=UiPathResumeTriggerName.INDEX_INGESTION_RAW, + item_key=index_id, + ) + reader = UiPathResumeTriggerReader() + result = await reader.read_trigger(resume_trigger) + assert isinstance(result, ContextGroundingIndex) + assert result.last_ingestion_status == IndexStatus.FAILED + @pytest.mark.anyio async def test_read_ixp_vs_escalation_trigger_successful( self, @@ -999,6 +1213,56 @@ async def test_create_resume_trigger_wait_job( assert resume_trigger.item_key == job_key assert resume_trigger.folder_path == wait_job.process_folder_path + @pytest.mark.anyio + async def test_create_resume_trigger_invoke_process_raw( + self, + setup_test_env: None, + ) -> None: + """Test creating a resume trigger for InvokeProcessRaw sets the raw trigger name.""" + job_key = "test-job-key" + invoke_process_raw = InvokeProcessRaw( + name="TestProcess", + process_folder_path="/test/path", + input_arguments={"key": "value"}, + ) + + mock_job = Job( + id=1234, key=job_key, folder_key="d0e09040-5997-44e1-93b7-4087689521b7" + ) + mock_invoke = AsyncMock(return_value=mock_job) + + with patch( + "uipath.platform.orchestrator._processes_service.ProcessesService.invoke_async", + new=mock_invoke, + ): + processor = UiPathResumeTriggerCreator() + resume_trigger = await processor.create_trigger(invoke_process_raw) + + assert resume_trigger is not None + assert resume_trigger.trigger_type == UiPathResumeTriggerType.JOB + assert resume_trigger.trigger_name == UiPathResumeTriggerName.JOB_RAW + assert resume_trigger.item_key == job_key + + @pytest.mark.anyio + async def test_create_resume_trigger_wait_job_raw( + self, + setup_test_env: None, + ) -> None: + """Test creating a resume trigger for WaitJobRaw sets the raw trigger name.""" + job_key = "test-job-key" + job = Job( + id=1234, key=job_key, folder_key="d0e09040-5997-44e1-93b7-4087689521b7" + ) + wait_job_raw = WaitJobRaw(job=job, process_folder_path="/test/path") + + processor = UiPathResumeTriggerCreator() + resume_trigger = await processor.create_trigger(wait_job_raw) + + assert resume_trigger is not None + assert resume_trigger.trigger_type == UiPathResumeTriggerType.JOB + assert resume_trigger.trigger_name == UiPathResumeTriggerName.JOB_RAW + assert resume_trigger.item_key == job_key + @pytest.mark.anyio async def test_create_resume_trigger_invoke_system_agent( self, @@ -1140,6 +1404,65 @@ async def test_create_resume_trigger_wait_deep_rag( assert resume_trigger.trigger_type == UiPathResumeTriggerType.DEEP_RAG assert resume_trigger.item_key == deep_rag_id + @pytest.mark.anyio + async def test_create_resume_trigger_create_deep_rag_raw( + self, + setup_test_env: None, + ) -> None: + """Test creating a resume trigger for CreateDeepRagRaw sets the raw trigger name.""" + deep_rag_id = "test-deep-rag-id" + create_deep_rag_raw = CreateDeepRagRaw( + name="test-deep-rag", + index_name="test-index", + prompt="test prompt", + glob_pattern="**/*.pdf", + citation_mode=CitationMode.INLINE, + index_folder_path="/test/path", + ) + + mock_deep_rag = DeepRagCreationResponse( + id=deep_rag_id, + last_deep_rag_status=DeepRagStatus.QUEUED, + created_date="2024-01-01", + ) + mock_start_deep_rag_async = AsyncMock(return_value=mock_deep_rag) + + with patch( + "uipath.platform.context_grounding._context_grounding_service.ContextGroundingService.start_deep_rag_async", + new=mock_start_deep_rag_async, + ): + processor = UiPathResumeTriggerCreator() + resume_trigger = await processor.create_trigger(create_deep_rag_raw) + + assert resume_trigger is not None + assert resume_trigger.trigger_type == UiPathResumeTriggerType.DEEP_RAG + assert resume_trigger.trigger_name == UiPathResumeTriggerName.DEEP_RAG_RAW + assert resume_trigger.item_key == deep_rag_id + + @pytest.mark.anyio + async def test_create_resume_trigger_wait_deep_rag_raw( + self, + setup_test_env: None, + ) -> None: + """Test creating a resume trigger for WaitDeepRagRaw sets the raw trigger name.""" + deep_rag_id = "test-deep-rag-id" + deep_rag = DeepRagCreationResponse( + id=deep_rag_id, + last_deep_rag_status=DeepRagStatus.IN_PROGRESS, + created_date="2024-01-01", + ) + wait_deep_rag_raw = WaitDeepRagRaw( + deep_rag=deep_rag, index_folder_path="/test/path" + ) + + processor = UiPathResumeTriggerCreator() + resume_trigger = await processor.create_trigger(wait_deep_rag_raw) + + assert resume_trigger is not None + assert resume_trigger.trigger_type == UiPathResumeTriggerType.DEEP_RAG + assert resume_trigger.trigger_name == UiPathResumeTriggerName.DEEP_RAG_RAW + assert resume_trigger.item_key == deep_rag_id + @pytest.mark.anyio async def test_create_resume_trigger_create_batch_transform( self, @@ -1267,6 +1590,67 @@ async def test_create_resume_trigger_wait_ephemeral_index( assert resume_trigger.trigger_type == UiPathResumeTriggerType.INDEX_INGESTION assert resume_trigger.item_key == index_id + @pytest.mark.anyio + async def test_create_resume_trigger_create_ephemeral_index_raw( + self, + setup_test_env: None, + ) -> None: + """Test creating a resume trigger for CreateEphemeralIndexRaw sets the raw trigger name.""" + index_id = "test-ephemeral-index-id" + attachments = ["attachment-uuid-1", "attachment-uuid-2"] + create_ephemeral_index_raw = CreateEphemeralIndexRaw( + usage=EphemeralIndexUsage.DEEP_RAG, + attachments=attachments, + ) + + mock_index = ContextGroundingIndex( + id=index_id, + name="ephemeral-index", + last_ingestion_status=IndexStatus.QUEUED.value, + ) + mock_create_ephemeral_index = AsyncMock(return_value=mock_index) + + with patch( + "uipath.platform.context_grounding._context_grounding_service.ContextGroundingService.create_ephemeral_index_async", + new=mock_create_ephemeral_index, + ): + processor = UiPathResumeTriggerCreator() + resume_trigger = await processor.create_trigger(create_ephemeral_index_raw) + + assert resume_trigger is not None + assert ( + resume_trigger.trigger_type == UiPathResumeTriggerType.INDEX_INGESTION + ) + assert ( + resume_trigger.trigger_name + == UiPathResumeTriggerName.INDEX_INGESTION_RAW + ) + assert resume_trigger.item_key == index_id + + @pytest.mark.anyio + async def test_create_resume_trigger_wait_ephemeral_index_raw( + self, + setup_test_env: None, + ) -> None: + """Test creating a resume trigger for WaitEphemeralIndexRaw sets the raw trigger name.""" + index_id = "test-ephemeral-index-id" + ephemeral_index = ContextGroundingIndex( + id=index_id, + name="ephemeral-index", + last_ingestion_status=IndexStatus.IN_PROGRESS.value, + ) + wait_ephemeral_index_raw = WaitEphemeralIndexRaw(index=ephemeral_index) + + processor = UiPathResumeTriggerCreator() + resume_trigger = await processor.create_trigger(wait_ephemeral_index_raw) + + assert resume_trigger is not None + assert resume_trigger.trigger_type == UiPathResumeTriggerType.INDEX_INGESTION + assert ( + resume_trigger.trigger_name == UiPathResumeTriggerName.INDEX_INGESTION_RAW + ) + assert resume_trigger.item_key == index_id + @pytest.mark.anyio async def test_create_resume_trigger_document_extraction_validation( self, diff --git a/packages/uipath-platform/uv.lock b/packages/uipath-platform/uv.lock index 86db34b70..4a3b65e0e 100644 --- a/packages/uipath-platform/uv.lock +++ b/packages/uipath-platform/uv.lock @@ -1061,7 +1061,7 @@ wheels = [ [[package]] name = "uipath-platform" -version = "0.0.14" +version = "0.0.15" source = { editable = "." } dependencies = [ { name = "httpx" }, @@ -1092,7 +1092,7 @@ requires-dist = [ { name = "pydantic-function-models", specifier = ">=0.1.11" }, { name = "tenacity", specifier = ">=9.0.0" }, { name = "truststore", specifier = ">=0.10.1" }, - { name = "uipath-core", specifier = ">=0.5.3,<0.6.0" }, + { name = "uipath-core", specifier = ">=0.5.4,<0.6.0" }, ] [package.metadata.requires-dev]