1111 AgentEscalationRecipient ,
1212 AgentEscalationRecipientType ,
1313 AgentEscalationResourceConfig ,
14+ ArgumentEmailRecipient ,
15+ ArgumentGroupNameRecipient ,
1416 AssetRecipient ,
1517 StandardRecipient ,
1618)
19+ from uipath .agent .utils .text_tokens import safe_get_nested
1720from uipath .eval .mocks import mockable
1821from uipath .platform import UiPath
1922from uipath .platform .action_center .tasks import TaskRecipient , TaskRecipientType
@@ -46,6 +49,7 @@ class EscalationAction(str, Enum):
4649
4750async def resolve_recipient_value (
4851 recipient : AgentEscalationRecipient ,
52+ input_args : dict [str , Any ] | None = None ,
4953) -> TaskRecipient | None :
5054 """Resolve recipient value based on recipient type."""
5155 if isinstance (recipient , AssetRecipient ):
@@ -57,6 +61,26 @@ async def resolve_recipient_value(
5761 type = TaskRecipientType .GROUP_NAME
5862 return TaskRecipient (value = value , type = type , displayName = value )
5963
64+ if isinstance (recipient , ArgumentEmailRecipient ):
65+ value = safe_get_nested (input_args or {}, recipient .argument_path )
66+ if value is None :
67+ raise ValueError (
68+ f"Argument '{ recipient .argument_path } ' has no value in agent input."
69+ )
70+ return TaskRecipient (
71+ value = value , type = TaskRecipientType .EMAIL , displayName = value
72+ )
73+
74+ if isinstance (recipient , ArgumentGroupNameRecipient ):
75+ value = safe_get_nested (input_args or {}, recipient .argument_path )
76+ if value is None :
77+ raise ValueError (
78+ f"Argument '{ recipient .argument_path } ' has no value in agent input."
79+ )
80+ return TaskRecipient (
81+ value = value , type = TaskRecipientType .GROUP_NAME , displayName = value
82+ )
83+
6084 if isinstance (recipient , StandardRecipient ):
6185 type = TaskRecipientType (recipient .type )
6286 if recipient .type == AgentEscalationRecipientType .USER_EMAIL :
@@ -156,8 +180,11 @@ class EscalationToolOutput(BaseModel):
156180 _bts_context : dict [str , Any ] = {}
157181
158182 async def escalation_tool_fn (** kwargs : Any ) -> dict [str , Any ]:
183+ agent_input : dict [str , Any ] = (
184+ tool .metadata .get ("agent_input" ) if tool .metadata else None
185+ ) or {}
159186 recipient : TaskRecipient | None = (
160- await resolve_recipient_value (channel .recipients [0 ])
187+ await resolve_recipient_value (channel .recipients [0 ], input_args = agent_input )
161188 if channel .recipients
162189 else None
163190 )
@@ -249,11 +276,16 @@ async def escalation_wrapper(
249276 if tool .metadata is None :
250277 raise RuntimeError ("Tool metadata is required for task_title resolution" )
251278
279+ state_dict = sanitize_dict_for_serialization (dict (state ))
252280 tool .metadata ["task_title" ] = resolve_task_title (
253281 channel .task_title ,
254- sanitize_dict_for_serialization ( dict ( state )) ,
282+ state_dict ,
255283 default_title = "Escalation Task" ,
256284 )
285+ internal_fields = set (AgentGraphState .model_fields .keys ())
286+ tool .metadata ["agent_input" ] = {
287+ k : v for k , v in state_dict .items () if k not in internal_fields
288+ }
257289
258290 tool .metadata ["_call_id" ] = call .get ("id" )
259291 tool .metadata ["_call_args" ] = dict (call .get ("args" , {}))
0 commit comments