@@ -272,10 +272,13 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
272 currentContent := ""
272 currentContent := ""
273 toolCalls := make([]message.ToolCall, 0)
273 toolCalls := make([]message.ToolCall, 0)
275+ var currentToolCallID string
276+ var currentToolCall openai.ChatCompletionMessageToolCall
277+ var msgToolCalls []openai.ChatCompletionMessageToolCall
275 for openaiStream.Next() {
278 for openaiStream.Next() {
276 chunk := openaiStream.Current()
279 chunk := openaiStream.Current()
277 acc.AddChunk(chunk)
280 acc.AddChunk(chunk)
278−
281+ // This fixes multiple tool calls for some providers
279 for _, choice := range chunk.Choices {
282 for _, choice := range chunk.Choices {
280 if choice.Delta.Content != "" {
283 if choice.Delta.Content != "" {
281 eventChan <- ProviderEvent{
284 eventChan <- ProviderEvent{
@@ -283,6 +286,45 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
283 Content: choice.Delta.Content,
286 Content: choice.Delta.Content,
285 currentContent += choice.Delta.Content
288 currentContent += choice.Delta.Content
289+ } else if len(choice.Delta.ToolCalls) > 0 {
290+ toolCall := choice.Delta.ToolCalls[0]
291+ // Detect tool use start
292+ if currentToolCallID == "" {
293+ if toolCall.ID != "" {
294+ currentToolCallID = toolCall.ID
295+ currentToolCall = openai.ChatCompletionMessageToolCall{
298+ Function: openai.ChatCompletionMessageToolCallFunction{
299+ Name: toolCall.Function.Name,
300+ Arguments: toolCall.Function.Arguments,
306+ if toolCall.ID == "" {
307+ currentToolCall.Function.Arguments += toolCall.Function.Arguments
309+ // Detect new tool use
310+ if toolCall.ID != currentToolCallID {
311+ msgToolCalls = append(msgToolCalls, currentToolCall)
312+ currentToolCallID = toolCall.ID
313+ currentToolCall = openai.ChatCompletionMessageToolCall{
316+ Function: openai.ChatCompletionMessageToolCallFunction{
317+ Name: toolCall.Function.Name,
318+ Arguments: toolCall.Function.Arguments,
325+ if choice.FinishReason == "tool_calls" {
326+ msgToolCalls = append(msgToolCalls, currentToolCall)
327+ acc.Choices[0].Message.ToolCalls = msgToolCalls
@@ -293,6 +335,7 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
293 jsonData, _ := json.Marshal(acc.ChatCompletion)
335 jsonData, _ := json.Marshal(acc.ChatCompletion)
294 slog.Debug("Response", "messages", string(jsonData))
336 slog.Debug("Response", "messages", string(jsonData))
296 resultFinishReason := acc.ChatCompletion.Choices[0].FinishReason
339 resultFinishReason := acc.ChatCompletion.Choices[0].FinishReason
297 if resultFinishReason == "" {
340 if resultFinishReason == "" {
298 // If the finish reason is empty, we assume it was a successful completion
341 // If the finish reason is empty, we assume it was a successful completion