Skip to content

Commit 1372a57

Browse files
authored
fix(provider,client): improve tool call merging and filtering (#1552)
- Refactor tool call merging logic to use id, index, or name as key, ensuring more robust accumulation of streaming tool call deltas. - Update tool call filtering to exclude entries without a name, preventing incomplete tool calls from being returned. - Remove fallback default values for id, index, and name in provider output, ensuring only valid tool call data is included. - Minor formatting adjustment in init.lua. Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
1 parent 4f643c7 commit 1372a57

3 files changed

Lines changed: 28 additions & 16 deletions

File tree

lua/CopilotChat/client.lua

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -445,12 +445,22 @@ function Client:ask(opts)
445445

446446
if out.tool_calls then
447447
for _, tool_call in ipairs(out.tool_calls) do
448-
local key = tool_call.id or tool_call.index
449-
local val = tool_calls:get(key)
450-
if not val then
448+
local key = tool_call.id or tool_call.index or tool_call.name or (#tool_calls:values() + 1)
449+
local existing = tool_calls:get(key)
450+
451+
if not existing then
451452
tool_calls:set(key, tool_call)
452453
else
453-
val.arguments = val.arguments .. tool_call.arguments
454+
existing.arguments = existing.arguments .. tool_call.arguments
455+
if tool_call.id then
456+
existing.id = tool_call.id
457+
end
458+
if tool_call.index then
459+
existing.index = tool_call.index
460+
end
461+
if tool_call.name then
462+
existing.name = tool_call.name
463+
end
454464
end
455465
end
456466
end
@@ -597,12 +607,17 @@ function Client:ask(opts)
597607
response_reasoning = response_reasoning_buffer:tostring()
598608
end
599609

610+
-- Filter out tool calls that don't have names (streaming deltas used only for accumulation)
611+
local final_tool_calls = vim.tbl_filter(function(tc)
612+
return tc.name ~= nil
613+
end, tool_calls:values())
614+
600615
return {
601616
message = {
602617
role = constants.ROLE.ASSISTANT,
603618
content = response_text,
604619
reasoning = response_reasoning,
605-
tool_calls = #tool_calls:values() > 0 and tool_calls:values() or nil,
620+
tool_calls = #final_tool_calls > 0 and final_tool_calls or nil,
606621
model = out_model,
607622
},
608623
token_count = token_count,

lua/CopilotChat/config/providers.lua

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -397,14 +397,12 @@ local function prepare_responses_output(output)
397397
content = output.delta.text
398398
end
399399
elseif output.type == 'response.output_item.done' then
400-
-- Complete output item (including tool calls)
401400
local item = output.item
402401
if item and item.type == 'function_call' then
403-
local index = output.output_index or (#tool_calls + 1)
404402
table.insert(tool_calls, {
405-
id = item.call_id or ('tooluse_' .. index),
406-
index = index,
407-
name = item.name or '',
403+
id = item.call_id,
404+
index = output.output_index,
405+
name = item.name,
408406
arguments = item.arguments or '',
409407
})
410408
end
@@ -436,9 +434,9 @@ local function prepare_responses_output(output)
436434
if msg.tool_calls then
437435
for i, tool_call in ipairs(msg.tool_calls) do
438436
table.insert(tool_calls, {
439-
id = tool_call.call_id or ('tooluse_' .. i),
437+
id = tool_call.call_id,
440438
index = i,
441-
name = tool_call.name or '',
439+
name = tool_call.name,
442440
arguments = tool_call.arguments or '',
443441
})
444442
end
@@ -481,11 +479,9 @@ local function prepare_chat_output(output)
481479
for i, tool_call in ipairs(message.tool_calls) do
482480
local fn = tool_call['function']
483481
if fn then
484-
local index = tool_call.index or i
485-
local id = utils.empty(tool_call.id) and ('tooluse_' .. index) or tool_call.id
486482
table.insert(tool_calls, {
487-
id = id,
488-
index = index,
483+
id = tool_call.id,
484+
index = tool_call.index or i,
489485
name = fn.name,
490486
arguments = fn.arguments or '',
491487
})

lua/CopilotChat/init.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ function M.ask(prompt, config)
546546
M.chat:add_message(response, true)
547547
M.chat.token_count = token_count
548548
M.chat.token_max_count = token_max_count
549+
549550
finish()
550551
end
551552
end))

0 commit comments

Comments
 (0)