11"""Chat runtime implementation."""
22
33import logging
4+ from datetime import datetime , timezone
45from typing import Any , AsyncGenerator , cast
56
6- from uipath .core .triggers import UiPathResumeTriggerType
7+ from uipath .core .chat import (
8+ UiPathConversationMessageEvent ,
9+ UiPathConversationToolCallEvent ,
10+ UiPathConversationToolCallStartEvent ,
11+ )
12+ from uipath .core .triggers import UiPathResumeTrigger , UiPathResumeTriggerType
713
814from uipath .runtime .base import (
915 UiPathExecuteOptions ,
@@ -41,6 +47,7 @@ def __init__(
4147 super ().__init__ ()
4248 self .delegate = delegate
4349 self .chat_bridge = chat_bridge
50+ self ._current_message_id : str | None = None
4451
4552 async def execute (
4653 self ,
@@ -80,6 +87,7 @@ async def stream(
8087 ):
8188 if isinstance (event , UiPathRuntimeMessageEvent ):
8289 if event .payload :
90+ self ._current_message_id = event .payload .message_id
8391 await self .chat_bridge .emit_message_event (event .payload )
8492
8593 if isinstance (event , UiPathRuntimeResult ):
@@ -103,6 +111,10 @@ async def stream(
103111
104112 resume_data = await self .chat_bridge .wait_for_resume ()
105113
114+ await self ._emit_start_tool_call_on_approval (
115+ trigger , resume_data
116+ )
117+
106118 assert trigger .interrupt_id is not None , (
107119 "Trigger interrupt_id cannot be None"
108120 )
@@ -122,6 +134,36 @@ async def stream(
122134 else :
123135 yield event
124136
137+ async def _emit_start_tool_call_on_approval (
138+ self , trigger : UiPathResumeTrigger , resume_data : dict [str , Any ]
139+ ) -> None :
140+ """Emit a startToolCall event when a HITL tool call confirmation is approved."""
141+ if self ._current_message_id is None or trigger .api_resume is None :
142+ return
143+
144+ request = trigger .api_resume .request or {}
145+ value = resume_data .get ("value" ) or {}
146+ tool_input = value .get ("input" )
147+
148+ tool_call_start_event = UiPathConversationMessageEvent (
149+ message_id = self ._current_message_id ,
150+ tool_call = UiPathConversationToolCallEvent (
151+ tool_call_id = request .get ("toolCallId" ),
152+ start = UiPathConversationToolCallStartEvent (
153+ tool_name = request .get ("toolName" ),
154+ timestamp = datetime .now (timezone .utc )
155+ .isoformat (timespec = "milliseconds" )
156+ .replace ("+00:00" , "Z" ),
157+ input = tool_input ,
158+ ),
159+ ),
160+ )
161+
162+ try :
163+ await self .chat_bridge .emit_message_event (tool_call_start_event )
164+ except Exception as e :
165+ logger .warning (f"Error emitting startToolCall on approval: { e } " )
166+
125167 async def get_schema (self ) -> UiPathRuntimeSchema :
126168 """Get schema from the delegate runtime."""
127169 return await self .delegate .get_schema ()
0 commit comments