on main help sign in
fix: handle providers that do not send the right index
2b1d87dKujtim Hoxha
internal/llm/provider/openai.go+11−1
@@ -325,6 +325,7 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
325 currentContent := ""
325 currentContent := ""
326 toolCalls := make([]message.ToolCall, 0)
326 toolCalls := make([]message.ToolCall, 0)
327 msgToolCalls := make(map[int64]openai.ChatCompletionMessageToolCall)
327 msgToolCalls := make(map[int64]openai.ChatCompletionMessageToolCall)
328+ toolMap := make(map[string]openai.ChatCompletionMessageToolCall)
328 for openaiStream.Next() {
329 for openaiStream.Next() {
329 chunk := openaiStream.Current()
330 chunk := openaiStream.Current()
330 // Kujtim: this is an issue with openrouter qwen, its sending -1 for the tool index
331 // Kujtim: this is an issue with openrouter qwen, its sending -1 for the tool index
@@ -332,7 +333,7 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
332 chunk.Choices[0].Delta.ToolCalls[0].Index = 0
333 chunk.Choices[0].Delta.ToolCalls[0].Index = 0
333 }
334 }
334 acc.AddChunk(chunk)
335 acc.AddChunk(chunk)
335− for _, choice := range chunk.Choices {
336+ for i, choice := range chunk.Choices {
336 reasoning, ok := choice.Delta.JSON.ExtraFields["reasoning"]
337 reasoning, ok := choice.Delta.JSON.ExtraFields["reasoning"]
337 if ok && reasoning.Raw() != "" {
338 if ok && reasoning.Raw() != "" {
338 reasoningStr := ""
339 reasoningStr := ""
@@ -361,6 +362,7 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
361 if tool.ID == toolCall.ID {
362 if tool.ID == toolCall.ID {
362 existingToolCall.Function.Arguments += toolCall.Function.Arguments
363 existingToolCall.Function.Arguments += toolCall.Function.Arguments
363 msgToolCalls[toolCall.Index] = existingToolCall
364 msgToolCalls[toolCall.Index] = existingToolCall
365+ toolMap[existingToolCall.ID] = existingToolCall
364 found = true
366 found = true
365 }
367 }
366 }
368 }
@@ -370,6 +372,7 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
370 } else {
372 } else {
371 existingToolCall.Function.Arguments += toolCall.Function.Arguments
373 existingToolCall.Function.Arguments += toolCall.Function.Arguments
372 msgToolCalls[toolCall.Index] = existingToolCall
374 msgToolCalls[toolCall.Index] = existingToolCall
375+ toolMap[existingToolCall.ID] = existingToolCall
373 }
376 }
374 } else {
377 } else {
375 newToolCall = true
378 newToolCall = true
@@ -394,7 +397,14 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
394 Arguments: toolCall.Function.Arguments,
397 Arguments: toolCall.Function.Arguments,
395 },
398 },
396 }
399 }
400+ toolMap[toolCall.ID] = msgToolCalls[toolCall.Index]
401+
402+ }
403+ toolCalls := []openai.ChatCompletionMessageToolCall{}
404+ for _, tc := range toolMap {
405+ toolCalls = append(toolCalls, tc)
397 }
406 }
407+ acc.Choices[i].Message.ToolCalls = toolCalls
398 }
408 }
399 }
409 }
400 }
410 }