Skip to content

Commit 49b0219

Browse files
authored
Merge pull request #57 from editor-code-assistant/implicit-manual-approval
Handle implicit manual approval flow
2 parents cfbb271 + 73f8c9c commit 49b0219

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

lua/eca/approve.lua

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,24 @@ local M = {}
22

33
---@param tool_call eca.ToolCallRun
44
function M.get_preview_lines(tool_call)
5-
if not tool_call.details then
6-
local arguments = vim.split(vim.inspect(tool_call.arguments), "\n")
5+
-- If no details or details without diff, show tool call info
6+
if not tool_call.details or not tool_call.details.diff then
7+
local arguments_text = tool_call.arguments or ""
8+
local arguments = vim.split(vim.inspect(arguments_text), "\n")
79
local messages = {}
810
if tool_call.summary then
911
table.insert(messages, "Summary: " .. tool_call.summary)
1012
end
11-
table.insert(messages, "Tool Name: " .. tool_call.name)
12-
table.insert(messages, "Tool Type: " .. tool_call.origin)
13+
table.insert(messages, "Tool Name: " .. (tool_call.name or "unknown"))
14+
table.insert(messages, "Tool Type: " .. (tool_call.origin or "unknown"))
1315
table.insert(messages, "Tool Arguments: ")
1416
for _, v in pairs(arguments) do
1517
table.insert(messages, v)
1618
end
1719
return messages
1820
end
1921
local lines = vim.split(tool_call.details.diff, "\n")
20-
return { tool_call.details.path, unpack(lines) }
22+
return { tool_call.details.path or "", unpack(lines) }
2123
end
2224

2325
---@param lines string[]

lua/eca/sidebar.lua

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
13751378
end
13761379

13771380
function 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
13851424
end
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

Comments
 (0)