package openaicompat import ( "errors" "strings" "github.com/QuantumNous/new-api/dto" ) func ResponsesResponseToChatCompletionsResponse(resp *dto.OpenAIResponsesResponse, id string) (*dto.OpenAITextResponse, *dto.Usage, error) { if resp == nil { return nil, nil, errors.New("response is nil") } text := ExtractOutputTextFromResponses(resp) usage := &dto.Usage{} if resp.Usage != nil { if resp.Usage.InputTokens != 0 { usage.PromptTokens = resp.Usage.InputTokens usage.InputTokens = resp.Usage.InputTokens } if resp.Usage.OutputTokens != 0 { usage.CompletionTokens = resp.Usage.OutputTokens usage.OutputTokens = resp.Usage.OutputTokens } if resp.Usage.TotalTokens != 0 { usage.TotalTokens = resp.Usage.TotalTokens } else { usage.TotalTokens = usage.PromptTokens + usage.CompletionTokens } if resp.Usage.InputTokensDetails != nil { usage.PromptTokensDetails.CachedTokens = resp.Usage.InputTokensDetails.CachedTokens usage.PromptTokensDetails.ImageTokens = resp.Usage.InputTokensDetails.ImageTokens usage.PromptTokensDetails.AudioTokens = resp.Usage.InputTokensDetails.AudioTokens } if resp.Usage.CompletionTokenDetails.ReasoningTokens != 0 { usage.CompletionTokenDetails.ReasoningTokens = resp.Usage.CompletionTokenDetails.ReasoningTokens } } created := resp.CreatedAt var toolCalls []dto.ToolCallResponse if text == "" && len(resp.Output) > 0 { for _, out := range resp.Output { if out.Type != "function_call" { continue } name := strings.TrimSpace(out.Name) if name == "" { continue } callId := strings.TrimSpace(out.CallId) if callId == "" { callId = strings.TrimSpace(out.ID) } toolCalls = append(toolCalls, dto.ToolCallResponse{ ID: callId, Type: "function", Function: dto.FunctionResponse{ Name: name, Arguments: out.Arguments, }, }) } } finishReason := "stop" if len(toolCalls) > 0 { finishReason = "tool_calls" } msg := dto.Message{ Role: "assistant", Content: text, } if len(toolCalls) > 0 { msg.SetToolCalls(toolCalls) msg.Content = "" } out := &dto.OpenAITextResponse{ Id: id, Object: "chat.completion", Created: created, Model: resp.Model, Choices: []dto.OpenAITextResponseChoice{ { Index: 0, Message: msg, FinishReason: finishReason, }, }, Usage: *usage, } return out, usage, nil } func ExtractOutputTextFromResponses(resp *dto.OpenAIResponsesResponse) string { if resp == nil || len(resp.Output) == 0 { return "" } var sb strings.Builder // Prefer assistant message outputs. for _, out := range resp.Output { if out.Type != "message" { continue } if out.Role != "" && out.Role != "assistant" { continue } for _, c := range out.Content { if c.Type == "output_text" && c.Text != "" { sb.WriteString(c.Text) } } } if sb.Len() > 0 { return sb.String() } for _, out := range resp.Output { for _, c := range out.Content { if c.Text != "" { sb.WriteString(c.Text) } } } return sb.String() }