package friendli
import (
"context"
"encoding/json"
"fmt"
"io"
)
// ChatService handles chat completion operations
type ChatService struct {
client *Client
}
// CreateCompletion creates a non-streaming chat completion
func (s *ChatService) CreateCompletion(ctx context.Context, req *ChatCompletionRequest) (*ChatCompletionResponse, error) {
// Validate request
if err := validateChatCompletionRequest(req); err != nil {
return nil, err
}
// Ensure streaming is disabled
stream := false
req.Stream = &stream
resp, err := s.client.doRequest(ctx, "POST", "/chat/completions", req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
var completion ChatCompletionResponse
if err := json.Unmarshal(body, &completion); err != nil {
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
}
return &completion, nil
}
// CreateCompletionStream creates a streaming chat completion
func (s *ChatService) CreateCompletionStream(ctx context.Context, req *ChatCompletionRequest) (*ChatCompletionStream, error) {
// Validate request
if err := validateChatCompletionRequest(req); err != nil {
return nil, err
}
// Ensure streaming is enabled
stream := true
req.Stream = &stream
resp, err := s.client.doStreamingRequest(ctx, "POST", "/chat/completions", req)
if err != nil {
return nil, err
}
return newChatCompletionStream(resp), nil
}
// validateChatCompletionRequest validates the chat completion request
func validateChatCompletionRequest(req *ChatCompletionRequest) error {
if req.Model == "" {
return ErrMissingModel
}
if len(req.Messages) == 0 {
return ErrEmptyMessages
}
return nil
}