Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
[project]
name = "uipath-langchain"
version = "0.3.2"
version = "0.3.3"
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"
dependencies = [
"uipath>=2.4.0, <2.5.0",
"uipath>=2.4.11, <2.5.0",
"uipath-runtime>=0.4.0, <0.5.0",
"langgraph>=1.0.0, <2.0.0",
"langchain-core>=1.2.5, <2.0.0",
Expand Down
43 changes: 42 additions & 1 deletion src/uipath_langchain/agent/guardrails/actions/escalate_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -76,10 +77,13 @@ async def _node(
# Validate message count based on execution stage
_validate_message_count(state, execution_stage)

(redirect_url, tenant_name) = _get_agent_execution_viewer_url()
# Build base data dictionary with common fields
data: Dict[str, Any] = {
"GuardrailName": guardrail.name,
"GuardrailDescription": guardrail.description,
"TenantName": tenant_name,
"AgentTrace": redirect_url,
"Component": scope.name.lower(),
"ExecutionStage": _execution_stage_to_string(execution_stage),
"GuardrailResult": state.guardrail_validation_result,
Expand Down Expand Up @@ -624,3 +628,40 @@ def _execution_stage_to_string(
if execution_stage == ExecutionStage.PRE_EXECUTION:
return "PreExecution"
return "PostExecution"


def _get_agent_execution_viewer_url() -> tuple[str, str]:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have 2 different functions for url and tenant name? Currently it's a bit hidden that this func returns the tenant name too

"""Generate the agent execution viewer URL based on execution context.

Args:
cloud_base_url: Optional cloud base URL. If not provided, will be extracted from environment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is outdated, right?


Returns:
The constructed viewer URL for the agent execution.

Note:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and this note as well - please update these docs

Currently uses hardcoded values for agentId and packageVersion.
These should be made configurable in the future.
"""
cloud_base_url = UiPathConfig.base_url
uiPath_Url = UiPathUrl(cloud_base_url)
tenant_name = uiPath_Url.tenant_name
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}",
tenant_name,
)
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}",
tenant_name,
)
20 changes: 15 additions & 5 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading