@@ -1205,6 +1205,9 @@ function M:handle_chat_content_received(params)
12051205 if content .state == " finished" then
12061206 self :_finalize_streaming_response ()
12071207 self :_update_input_display ()
1208+ elseif content .text == " Waiting for tool call approval" then
1209+ -- Handle implicit approval flow when toolCallPrepare was already received
1210+ self :render_tool_call (content , chat_id )
12081211 end
12091212 elseif content .type == " toolCallPrepare" then
12101213 self :_finalize_streaming_response ()
@@ -1375,13 +1378,49 @@ function M:handle_chat_content_received(params)
13751378end
13761379
13771380function M :render_tool_call (tool_content , chat_id )
1381+ -- Handle explicit manual approval (toolCallRun with manualApproval flag)
13781382 if tool_content .type == " toolCallRun" and tool_content .manualApproval then
1383+ -- Mark as shown to prevent duplicate approval dialogs from implicit flow
1384+ if self ._current_tool_call then
1385+ self ._current_tool_call .approval_shown = true
1386+ end
13791387 return require (" eca.approve" ).approve_tool_call (tool_content , function ()
13801388 self .mediator :send (" chat/toolCallApprove" , { chatId = chat_id , toolCallId = tool_content .id }, nil )
13811389 end , function ()
13821390 self .mediator :send (" chat/toolCallReject" , { chatId = chat_id , toolCallId = tool_content .id }, nil )
13831391 end )
13841392 end
1393+
1394+ -- Handle implicit approval flow: progress message "Waiting for tool call approval"
1395+ -- with a previously prepared tool call (toolCallPrepare stored in _current_tool_call)
1396+ if tool_content .type == " progress"
1397+ and tool_content .text == " Waiting for tool call approval"
1398+ and self ._current_tool_call
1399+ and self ._current_tool_call .id
1400+ and not self ._current_tool_call .approval_shown then
1401+ -- Mark as shown to avoid duplicate approval dialogs
1402+ self ._current_tool_call .approval_shown = true
1403+
1404+ -- Store the tool call id in a local variable to avoid closure issues
1405+ local tool_call_id = self ._current_tool_call .id
1406+
1407+ -- Build tool content from the prepared tool call for the approval dialog
1408+ -- Using field names expected by approve.lua
1409+ local prepared_tool_call = {
1410+ id = tool_call_id ,
1411+ name = self ._current_tool_call .name or " Tool call" ,
1412+ summary = self ._current_tool_call .summary ,
1413+ arguments = self ._current_tool_call .arguments or " " ,
1414+ origin = " eca" , -- default origin for implicit approval
1415+ details = self ._current_tool_call .details ,
1416+ }
1417+
1418+ return require (" eca.approve" ).approve_tool_call (prepared_tool_call , function ()
1419+ self .mediator :send (" chat/toolCallApprove" , { chatId = chat_id , toolCallId = tool_call_id }, nil )
1420+ end , function ()
1421+ self .mediator :send (" chat/toolCallReject" , { chatId = chat_id , toolCallId = tool_call_id }, nil )
1422+ end )
1423+ end
13851424end
13861425
13871426--- @param text string
@@ -1811,6 +1850,7 @@ function M:_handle_tool_call_prepare(content)
18111850 arguments = " " ,
18121851 details = {},
18131852 outputs = " " ,
1853+ approval_shown = false ,
18141854 }
18151855 end
18161856
0 commit comments