func()

in openai/chat.go [30:97]


func (h *handlers) ChatCompletionsHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		internal.ErrorHandler(w, r, http.StatusMethodNotAllowed, "method not allowed")
		return
	}
	body, err := io.ReadAll(r.Body)
	if err != nil {
		internal.ErrorHandler(w, r, http.StatusInternalServerError, "failed to read request body: %v", err)
		return
	}
	defer r.Body.Close()

	var chatReq ChatCompletionRequest
	if err := json.Unmarshal(body, &chatReq); err != nil {
		internal.ErrorHandler(w, r, http.StatusInternalServerError, "failed to parse chat completions body: %v", err)
		return
	}

	model := h.geminiClient.GenerativeModel(chatReq.Model)
	model.GenerationConfig = genai.GenerationConfig{
		CandidateCount:   chatReq.N,
		StopSequences:    chatReq.Stop,
		ResponseMIMEType: "text/plain",
		MaxOutputTokens:  chatReq.MaxTokens,
		Temperature:      chatReq.Temperature,
		TopP:             chatReq.TopP,
	}

	chat := model.StartChat()
	var lastPart genai.Part
	for i, r := range chatReq.Messages {
		if r.Role == "system" {
			model.SystemInstruction = &genai.Content{
				Role:  r.Role,
				Parts: []genai.Part{genai.Text(r.Content)},
			}
			continue
		}
		if i == len(chatReq.Messages)-1 { // the last message
			// TODO(jbd): This hack strips away the role of the last message.
			// But Gemini API Go SDK doesn't give flexibility to call SendMessage
			// with a list of contents.
			lastPart = genai.Text(r.Content)
			break
		}
		chat.History = append(chat.History, &genai.Content{
			Role:  r.Role,
			Parts: []genai.Part{genai.Text(r.Content)},
		})
	}

	if chatReq.Stream {
		streamingChatCompletionsHandler(w, r, chatReq.Model, chat, lastPart)
		return
	}

	geminiResp, err := chat.SendMessage(r.Context(), lastPart)
	if err != nil {
		internal.ErrorHandler(w, r, http.StatusInternalServerError, "failed to generate content: %v", err)
		return
	}

	resp := toOpenAIResponse(geminiResp, "chat.completion", chatReq.Model)
	if err := json.NewEncoder(w).Encode(resp); err != nil {
		internal.ErrorHandler(w, r, http.StatusInternalServerError, "failed to encode chat completions response: %v", err)
		return
	}
}