on main help sign in
chore: fix openrouter issues

- this fixes the case where the model sends -1 for indes - this also adds events for loading tools - this also fixes the finish reason for some providers

commit30b508fc5d167d4eacd9c81defbef02f0407a1aa authorKujtim Hoxha <kujtimii.h@gmail.com> dateWed 30 Jul 2025, 13:58 (1 year ago) parent34e68ac
1 file changed+25−2
internal/llm/provider/openai.go+25−2
internal/llm/provider/openai.go+25−2
@@ -331,8 +331,14 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
331331 var currentToolCallID string
332332 var currentToolCall openai.ChatCompletionMessageToolCall
333333 var msgToolCalls []openai.ChatCompletionMessageToolCall
334+ currentToolIndex := 0
334335 for openaiStream.Next() {
335336 chunk := openaiStream.Current()
337+ // Kujtim: this is an issue with openrouter qwen, its sending -1 for the tool index
338+ if len(chunk.Choices) > 0 && len(chunk.Choices[0].Delta.ToolCalls) > 0 && chunk.Choices[0].Delta.ToolCalls[0].Index == -1 {
339+ chunk.Choices[0].Delta.ToolCalls[0].Index = int64(currentToolIndex)
340+ currentToolIndex++
341+ }
336342 acc.AddChunk(chunk)
337343 // This fixes multiple tool calls for some providers
338344 for _, choice := range chunk.Choices {
@@ -348,6 +354,14 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
348354 if currentToolCallID == "" {
349355 if toolCall.ID != "" {
350356 currentToolCallID = toolCall.ID
357+ eventChan <- ProviderEvent{
358+ Type: EventToolUseStart,
359+ ToolCall: &message.ToolCall{
360+ ID: toolCall.ID,
361+ Name: toolCall.Function.Name,
362+ Finished: false,
363+ },
364+ }
351365 currentToolCall = openai.ChatCompletionMessageToolCall{
352366 ID: toolCall.ID,
353367 Type: "function",
@@ -359,13 +373,21 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
359373 }
360374 } else {
361375 // Delta tool use
362− if toolCall.ID == "" {
376+ if toolCall.ID == "" || toolCall.ID == currentToolCallID {
363377 currentToolCall.Function.Arguments += toolCall.Function.Arguments
364378 } else {
365379 // Detect new tool use
366380 if toolCall.ID != currentToolCallID {
367381 msgToolCalls = append(msgToolCalls, currentToolCall)
368382 currentToolCallID = toolCall.ID
383+ eventChan <- ProviderEvent{
384+ Type: EventToolUseStart,
385+ ToolCall: &message.ToolCall{
386+ ID: toolCall.ID,
387+ Name: toolCall.Function.Name,
388+ Finished: false,
389+ },
390+ }
369391 currentToolCall = openai.ChatCompletionMessageToolCall{
370392 ID: toolCall.ID,
371393 Type: "function",
@@ -378,7 +400,8 @@ func (o *openaiClient) stream(ctx context.Context, messages []message.Message, t
378400 }
379401 }
380402 }
381− if choice.FinishReason == "tool_calls" {
403+ // Kujtim: some models send finish stop even for tool calls
404+ if choice.FinishReason == "tool_calls" || (choice.FinishReason == "stop" && currentToolCallID != "") {
382405 msgToolCalls = append(msgToolCalls, currentToolCall)
383406 if len(acc.Choices) > 0 {
384407 acc.Choices[0].Message.ToolCalls = msgToolCalls