Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions lua/CopilotChat/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -445,12 +445,22 @@ function Client:ask(opts)

if out.tool_calls then
for _, tool_call in ipairs(out.tool_calls) do
local key = tool_call.id or tool_call.index
local val = tool_calls:get(key)
if not val then
local key = tool_call.id or tool_call.index or tool_call.name or (#tool_calls:values() + 1)
local existing = tool_calls:get(key)

if not existing then
tool_calls:set(key, tool_call)
else
val.arguments = val.arguments .. tool_call.arguments
existing.arguments = existing.arguments .. tool_call.arguments
if tool_call.id then
existing.id = tool_call.id
end
if tool_call.index then
existing.index = tool_call.index
end
if tool_call.name then
existing.name = tool_call.name
end
end
end
end
Expand Down Expand Up @@ -597,12 +607,17 @@ function Client:ask(opts)
response_reasoning = response_reasoning_buffer:tostring()
end

-- Filter out tool calls that don't have names (streaming deltas used only for accumulation)
local final_tool_calls = vim.tbl_filter(function(tc)
return tc.name ~= nil
end, tool_calls:values())

return {
message = {
role = constants.ROLE.ASSISTANT,
content = response_text,
reasoning = response_reasoning,
tool_calls = #tool_calls:values() > 0 and tool_calls:values() or nil,
tool_calls = #final_tool_calls > 0 and final_tool_calls or nil,
model = out_model,
},
token_count = token_count,
Expand Down
18 changes: 7 additions & 11 deletions lua/CopilotChat/config/providers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -397,14 +397,12 @@ local function prepare_responses_output(output)
content = output.delta.text
end
elseif output.type == 'response.output_item.done' then
-- Complete output item (including tool calls)
local item = output.item
if item and item.type == 'function_call' then
local index = output.output_index or (#tool_calls + 1)
table.insert(tool_calls, {
id = item.call_id or ('tooluse_' .. index),
index = index,
name = item.name or '',
id = item.call_id,
index = output.output_index,
name = item.name,
arguments = item.arguments or '',
})
end
Expand Down Expand Up @@ -436,9 +434,9 @@ local function prepare_responses_output(output)
if msg.tool_calls then
for i, tool_call in ipairs(msg.tool_calls) do
table.insert(tool_calls, {
id = tool_call.call_id or ('tooluse_' .. i),
id = tool_call.call_id,
index = i,
name = tool_call.name or '',
name = tool_call.name,
arguments = tool_call.arguments or '',
})
end
Expand Down Expand Up @@ -481,11 +479,9 @@ local function prepare_chat_output(output)
for i, tool_call in ipairs(message.tool_calls) do
local fn = tool_call['function']
if fn then
local index = tool_call.index or i
local id = utils.empty(tool_call.id) and ('tooluse_' .. index) or tool_call.id
table.insert(tool_calls, {
id = id,
index = index,
id = tool_call.id,
index = tool_call.index or i,
name = fn.name,
arguments = fn.arguments or '',
})
Expand Down
1 change: 1 addition & 0 deletions lua/CopilotChat/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ function M.ask(prompt, config)
M.chat:add_message(response, true)
M.chat.token_count = token_count
M.chat.token_max_count = token_max_count

finish()
end
end))
Expand Down
Loading