Files
jules/llm/deepseek/deepseek.go
T

88 lines
1.6 KiB
Go

package deepseek
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"time"
)
const BaseURL = "https://api.deepseek.com"
type Client struct {
apiKey string
baseURL string
httpClient *http.Client
}
func New(apiKey, baseURL string) *Client {
return &Client{
apiKey: apiKey,
baseURL: baseURL,
httpClient: &http.Client{
Timeout: time.Minute,
},
}
}
type request struct {
Model string `json:"model"`
Messages []message `json:"messages"`
}
type message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type response struct {
Choices []choice `json:"choices"`
}
type choice struct {
Message message `json:"message"`
}
func (c *Client) Process(ctx context.Context, prompt string) (string, error) {
reqBody := request{
Model: "deepseek-reasoner",
Messages: []message{{Role: "user", Content: prompt}},
}
body, _ := json.Marshal(reqBody)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+"/v1/chat/completions", bytes.NewReader(body))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer "+c.apiKey)
resp, err := c.httpClient.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
errBody, _ := io.ReadAll(resp.Body)
return "", fmt.Errorf("status %d: %s", resp.StatusCode, errBody)
}
var result response
if err = json.NewDecoder(resp.Body).Decode(&result); err != nil {
return "", err
}
if len(result.Choices) == 0 {
return "", errors.New("no choices in response")
}
return result.Choices[0].Message.Content, nil
}