diff --git a/pyproject.toml b/pyproject.toml index 217c57e1..76739577 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "uipath-langchain" -version = "0.4.4" +version = "0.4.5" description = "Python SDK that enables developers to build and deploy LangGraph agents to the UiPath Cloud Platform" readme = { file = "README.md", content-type = "text/markdown" } requires-python = ">=3.11" diff --git a/src/uipath_langchain/agent/guardrails/actions/escalate_action.py b/src/uipath_langchain/agent/guardrails/actions/escalate_action.py index a3e79d20..07307a63 100644 --- a/src/uipath_langchain/agent/guardrails/actions/escalate_action.py +++ b/src/uipath_langchain/agent/guardrails/actions/escalate_action.py @@ -7,7 +7,8 @@ from langchain_core.messages import AIMessage, AnyMessage, BaseMessage, ToolMessage from langgraph.types import Command, interrupt -from uipath.platform.common import CreateEscalation +from uipath._utils import UiPathUrl +from uipath.platform.common import CreateEscalation, UiPathConfig from uipath.platform.guardrails import ( BaseGuardrail, GuardrailScope, @@ -85,6 +86,12 @@ async def _node( "GuardrailResult": state.guardrail_validation_result, } + # Add tenant and trace URL if base_url is configured + cloud_base_url = UiPathConfig.base_url + if cloud_base_url is not None: + data["TenantName"] = _get_tenant_name(cloud_base_url) + data["AgentTrace"] = _get_agent_execution_viewer_url(cloud_base_url) + # Add stage-specific fields if execution_stage == ExecutionStage.PRE_EXECUTION: # PRE_EXECUTION: Only Inputs field from last message @@ -624,3 +631,45 @@ def _execution_stage_to_string( if execution_stage == ExecutionStage.PRE_EXECUTION: return "PreExecution" return "PostExecution" + + +def _get_tenant_name(cloud_base_url: str) -> str: + """Extract the tenant name from the UiPath base URL. + + Args: + cloud_base_url: The UiPath cloud base URL to extract tenant name from. + + Returns: + str: The tenant name extracted from the base URL. + """ + uiPath_Url = UiPathUrl(cloud_base_url) + return uiPath_Url.tenant_name + + +def _get_agent_execution_viewer_url(cloud_base_url: str) -> str: + """Generate the agent execution viewer URL based on execution context. + + Constructs the appropriate URL for viewing agent execution traces. The URL format + depends on whether the agent is running in a studio project (development) or + deployed (production) context. + + Args: + cloud_base_url: The UiPath cloud base URL to use for constructing the viewer URL. + + Returns: + str: The constructed agent execution viewer URL. + """ + uiPath_Url = UiPathUrl(cloud_base_url) + organization_id = UiPathConfig.organization_id + agent_id = UiPathConfig.project_id + + # Route to appropriate URL based on source + if UiPathConfig.is_studio_project: + return f"{uiPath_Url.base_url}/{organization_id}/studio_/designer/{agent_id}" + else: + execution_folder_id = UiPathConfig.folder_key + process_uuid = UiPathConfig.process_uuid + trace_id = UiPathConfig.trace_id + package_version = UiPathConfig.process_version + + return f"{uiPath_Url.base_url}/{organization_id}/agents_/deployed/{execution_folder_id}/{process_uuid}/{agent_id}/{package_version}/traces/{trace_id}" diff --git a/uv.lock b/uv.lock index 0b5ca9e4..8d54c2bb 100644 --- a/uv.lock +++ b/uv.lock @@ -3297,7 +3297,7 @@ wheels = [ [[package]] name = "uipath-langchain" -version = "0.4.4" +version = "0.4.5" source = { editable = "." } dependencies = [ { name = "aiosqlite" },