Skip to content

Commit 0617dee

Browse files
feat: add group name support for escalations recipients
1 parent 34471f2 commit 0617dee

File tree

2 files changed

+65
-90
lines changed

2 files changed

+65
-90
lines changed

src/uipath/agent/models/agent.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class AgentEscalationRecipientType(str, Enum):
6161
GROUP_ID = "GroupId"
6262
USER_EMAIL = "UserEmail"
6363
ASSET_USER_EMAIL = "AssetUserEmail"
64+
GROUP_NAME = "GroupName"
65+
ASSET_GROUP_NAME = "AssetGroupName"
6466

6567

6668
class AgentContextRetrievalMode(str, Enum):
@@ -240,6 +242,8 @@ def _normalize_recipient_type(recipient: Any) -> Any:
240242
2: AgentEscalationRecipientType.GROUP_ID,
241243
3: AgentEscalationRecipientType.USER_EMAIL,
242244
4: AgentEscalationRecipientType.ASSET_USER_EMAIL,
245+
5: AgentEscalationRecipientType.GROUP_NAME,
246+
6: AgentEscalationRecipientType.ASSET_GROUP_NAME,
243247
}
244248
recipient["type"] = type_mapping.get(recipient_type, str(recipient_type))
245249

@@ -253,23 +257,25 @@ class BaseEscalationRecipient(BaseCfg):
253257

254258

255259
class StandardRecipient(BaseEscalationRecipient):
256-
"""Standard recipient with value field (for UserId, GroupId, UserEmail)."""
260+
"""Standard recipient with value field."""
257261

258262
type: Literal[
259263
AgentEscalationRecipientType.USER_ID,
260264
AgentEscalationRecipientType.GROUP_ID,
261265
AgentEscalationRecipientType.USER_EMAIL,
266+
AgentEscalationRecipientType.GROUP_NAME,
262267
] = Field(..., alias="type")
263268
value: str = Field(..., alias="value")
264269
display_name: Optional[str] = Field(default=None, alias="displayName")
265270

266271

267272
class AssetRecipient(BaseEscalationRecipient):
268-
"""Asset recipient with assetName and folderPath (for AssetUserEmail)."""
273+
"""Asset recipient with assetName and folderPath."""
269274

270-
type: Literal[AgentEscalationRecipientType.ASSET_USER_EMAIL] = Field(
271-
..., alias="type"
272-
)
275+
type: Literal[
276+
AgentEscalationRecipientType.ASSET_USER_EMAIL,
277+
AgentEscalationRecipientType.ASSET_GROUP_NAME,
278+
] = Field(..., alias="type")
273279
asset_name: str = Field(..., alias="assetName")
274280
folder_path: str = Field(..., alias="folderPath")
275281

tests/agent/models/test_agent.py

Lines changed: 54 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,9 +1890,10 @@ def test_mcp_resource_with_output_schema(self):
18901890
(1, "user-123", AgentEscalationRecipientType.USER_ID),
18911891
(2, "group-456", AgentEscalationRecipientType.GROUP_ID),
18921892
(3, "user@example.com", AgentEscalationRecipientType.USER_EMAIL),
1893+
(5, "Test Group", AgentEscalationRecipientType.GROUP_NAME),
18931894
],
18941895
)
1895-
def test_escalation_recipient_type_normalization_from_int(
1896+
def test_escalation_standard_recipient_type_normalization(
18961897
self, recipient_type_int, value, expected_type
18971898
):
18981899
"""Test that escalation recipient types are normalized from integers to enum strings."""
@@ -1954,8 +1955,17 @@ def test_escalation_recipient_type_normalization_from_int(
19541955
assert channel.recipients[0].type == expected_type
19551956
assert channel.recipients[0].value == value
19561957

1957-
def test_escalation_recipient_asset_type_normalization(self):
1958-
"""Test that AssetUserEmail recipient type (int 4) is normalized correctly."""
1958+
@pytest.mark.parametrize(
1959+
"recipient_type_int,asset_name,folder_path,expected_type",
1960+
[
1961+
(4, "email_asset", "Shared", AgentEscalationRecipientType.ASSET_USER_EMAIL),
1962+
(6, "group_asset", "Shared", AgentEscalationRecipientType.ASSET_GROUP_NAME),
1963+
],
1964+
)
1965+
def test_escalation_asset_recipient_type_normalization_from_int(
1966+
self, recipient_type_int, asset_name, folder_path, expected_type
1967+
):
1968+
"""Test that escalation asset recipient types are normalized from integers to enum strings."""
19591969

19601970
json_data = {
19611971
"id": "test-asset-recipient",
@@ -1987,9 +1997,9 @@ def test_escalation_recipient_asset_type_normalization(self):
19871997
},
19881998
"recipients": [
19891999
{
1990-
"type": 4, # ASSET_USER_EMAIL as integer
1991-
"assetName": "EmailAsset",
1992-
"folderPath": "Shared",
2000+
"type": recipient_type_int,
2001+
"assetName": asset_name,
2002+
"folderPath": folder_path,
19932003
}
19942004
],
19952005
}
@@ -2013,22 +2023,24 @@ def test_escalation_recipient_asset_type_normalization(self):
20132023
recipient = channel.recipients[0]
20142024
assert isinstance(recipient, AssetRecipient)
20152025

2016-
# Verify integer type 4 was normalized to ASSET_USER_EMAIL enum
2017-
assert recipient.type == AgentEscalationRecipientType.ASSET_USER_EMAIL
2018-
assert recipient.asset_name == "EmailAsset"
2019-
assert recipient.folder_path == "Shared"
2026+
# Verify integer types were normalized to enum strings
2027+
assert recipient.type == expected_type
2028+
assert recipient.asset_name == asset_name
2029+
assert recipient.folder_path == folder_path
20202030

20212031
@pytest.mark.parametrize(
2022-
"recipient_type_int,value,display_name,expected_type",
2032+
"recipient_type_int,value,expected_type",
20232033
[
2024-
(1, "user-123", "User Name", AgentEscalationRecipientType.USER_ID),
2025-
(2, "group-456", "Group Name", AgentEscalationRecipientType.GROUP_ID),
2034+
(1, "user-123", AgentEscalationRecipientType.USER_ID),
2035+
(2, "group-456", AgentEscalationRecipientType.GROUP_ID),
2036+
(3, "user@example.com", AgentEscalationRecipientType.USER_EMAIL),
2037+
(5, "Test Group", AgentEscalationRecipientType.GROUP_NAME),
20262038
],
20272039
)
20282040
def test_standard_recipient_discrimination(
2029-
self, recipient_type_int, value, display_name, expected_type
2041+
self, recipient_type_int, value, expected_type
20302042
):
2031-
"""Test that StandardRecipient is correctly discriminated for USER_ID, GROUP_ID."""
2043+
"""Test that StandardRecipient is correctly discriminated."""
20322044

20332045
json_data = {
20342046
"id": "test-standard-recipient",
@@ -2062,7 +2074,6 @@ def test_standard_recipient_discrimination(
20622074
{
20632075
"type": recipient_type_int,
20642076
"value": value,
2065-
"displayName": display_name,
20662077
}
20672078
],
20682079
}
@@ -2087,70 +2098,18 @@ def test_standard_recipient_discrimination(
20872098
assert isinstance(channel.recipients[0], StandardRecipient)
20882099
assert channel.recipients[0].type == expected_type
20892100
assert channel.recipients[0].value == value
2090-
assert channel.recipients[0].display_name == display_name
2091-
2092-
def test_standard_recipient_discrimination_user_email(self):
2093-
"""Test that StandardRecipient is correctly discriminated for USER_EMAIL."""
2094-
2095-
json_data = {
2096-
"id": "test-standard-recipient",
2097-
"name": "Agent with Standard Recipients",
2098-
"version": "1.0.0",
2099-
"settings": {
2100-
"model": "gpt-4o-2024-11-20",
2101-
"maxTokens": 16384,
2102-
"temperature": 0,
2103-
"engine": "basic-v1",
2104-
},
2105-
"inputSchema": {"type": "object", "properties": {}},
2106-
"outputSchema": {"type": "object", "properties": {}},
2107-
"resources": [
2108-
{
2109-
"$resourceType": "escalation",
2110-
"channels": [
2111-
{
2112-
"name": "Test Channel",
2113-
"description": "Test",
2114-
"type": "ActionCenter",
2115-
"inputSchema": {"type": "object", "properties": {}},
2116-
"outputSchema": {"type": "object", "properties": {}},
2117-
"properties": {
2118-
"appName": "TestApp",
2119-
"appVersion": 1,
2120-
"folderName": "TestFolder",
2121-
"resourceKey": "test-key",
2122-
},
2123-
"recipients": [
2124-
{
2125-
"type": 3,
2126-
"value": "user@example.com",
2127-
}
2128-
],
2129-
}
2130-
],
2131-
"name": "Test Escalation",
2132-
"description": "Test",
2133-
}
2134-
],
2135-
"messages": [{"role": "system", "content": "Test"}],
2136-
}
2137-
2138-
config: AgentDefinition = TypeAdapter(AgentDefinition).validate_python(
2139-
json_data
2140-
)
2141-
2142-
escalation = config.resources[0]
2143-
assert isinstance(escalation, AgentEscalationResourceConfig)
2144-
2145-
channel = escalation.channels[0]
2146-
2147-
# All should be StandardRecipient instances
2148-
assert isinstance(channel.recipients[0], StandardRecipient)
2149-
assert channel.recipients[0].type == AgentEscalationRecipientType.USER_EMAIL
2150-
assert channel.recipients[0].value == "user@example.com"
21512101

2152-
def test_asset_recipient_discrimination(self):
2153-
"""Test that AssetRecipient is correctly discriminated for ASSET_USER_EMAIL type."""
2102+
@pytest.mark.parametrize(
2103+
"recipient_type_int,asset_name,folder_path,expected_type",
2104+
[
2105+
(4, "email_asset", "Shared", AgentEscalationRecipientType.ASSET_USER_EMAIL),
2106+
(6, "group_asset", "Shared", AgentEscalationRecipientType.ASSET_GROUP_NAME),
2107+
],
2108+
)
2109+
def test_asset_recipient_discrimination(
2110+
self, recipient_type_int, asset_name, folder_path, expected_type
2111+
):
2112+
"""Test that AssetRecipient is correctly discriminated."""
21542113

21552114
json_data = {
21562115
"id": "test-asset-recipient-discrimination",
@@ -2182,9 +2141,9 @@ def test_asset_recipient_discrimination(self):
21822141
},
21832142
"recipients": [
21842143
{
2185-
"type": 4,
2186-
"assetName": "NotificationEmail",
2187-
"folderPath": "Production/Notifications",
2144+
"type": recipient_type_int,
2145+
"assetName": asset_name,
2146+
"folderPath": folder_path,
21882147
}
21892148
],
21902149
}
@@ -2209,9 +2168,9 @@ def test_asset_recipient_discrimination(self):
22092168
assert isinstance(recipient, AssetRecipient)
22102169

22112170
# Should be AssetRecipient instance
2212-
assert recipient.type == AgentEscalationRecipientType.ASSET_USER_EMAIL
2213-
assert recipient.asset_name == "NotificationEmail"
2214-
assert recipient.folder_path == "Production/Notifications"
2171+
assert recipient.type == expected_type
2172+
assert recipient.asset_name == asset_name
2173+
assert recipient.folder_path == folder_path
22152174

22162175
@pytest.mark.parametrize(
22172176
"recipient_data,expected_type,recipient_class",
@@ -2236,6 +2195,16 @@ def test_asset_recipient_discrimination(self):
22362195
AgentEscalationRecipientType.ASSET_USER_EMAIL,
22372196
AssetRecipient,
22382197
),
2198+
(
2199+
{"type": 5, "value": "User Test Group"},
2200+
AgentEscalationRecipientType.GROUP_NAME,
2201+
StandardRecipient,
2202+
),
2203+
(
2204+
{"type": 6, "assetName": "GroupAsset", "folderPath": "Shared"},
2205+
AgentEscalationRecipientType.ASSET_GROUP_NAME,
2206+
AssetRecipient,
2207+
),
22392208
],
22402209
)
22412210
def test_direct_recipient_instantiation(

0 commit comments

Comments
 (0)