Added call to embedding openai
This commit is contained in:
+133
@@ -0,0 +1,133 @@
|
||||
package llm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
config "git.estatecloud.org/radumaco/souvenir/config"
|
||||
)
|
||||
|
||||
const EMBEDDINGS_API = "/v1/embeddings"
|
||||
|
||||
type Embedder struct {
|
||||
Cfg config.EmbeddingConfig
|
||||
logger slog.Logger
|
||||
id string
|
||||
}
|
||||
|
||||
type EmbedRequest struct {
|
||||
Input []string `json:"input"`
|
||||
Model string `json:"model"`
|
||||
EncodingFormat string `json:"encoding_format"`
|
||||
}
|
||||
|
||||
type EmbedResponse struct {
|
||||
Data []Embedding `json:"data"`
|
||||
Model string `json:"model"`
|
||||
Object string `json:"object"`
|
||||
Usage Usage `json:"usage"`
|
||||
}
|
||||
|
||||
type Embedding struct {
|
||||
Embedding []float32 `json:"embeddgin"`
|
||||
Index int `json:"index"`
|
||||
Object string `json:"object"`
|
||||
}
|
||||
|
||||
func NewEmbedder(cfg config.EmbeddingConfig) *Embedder {
|
||||
return &Embedder{
|
||||
Cfg: cfg,
|
||||
logger: *slog.Default().With("Component", "Embedder"),
|
||||
}
|
||||
}
|
||||
|
||||
func (e Embedder) ID() string {
|
||||
if e.id == "" {
|
||||
e.id = strings.Map(func(r rune) rune {
|
||||
switch {
|
||||
case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r <= '0' && r <= '9':
|
||||
return r
|
||||
default:
|
||||
return '_'
|
||||
}
|
||||
}, e.Cfg.Model)
|
||||
}
|
||||
return e.id
|
||||
}
|
||||
|
||||
func (e Embedder) EmbedBatch(text []string) ([][]float32, error) {
|
||||
requestBody := EmbedRequest{
|
||||
Model: e.Cfg.Model,
|
||||
Input: text,
|
||||
EncodingFormat: "float",
|
||||
}
|
||||
serialized, err := json.Marshal(requestBody)
|
||||
if err != nil {
|
||||
e.logger.Error("There was an error marshelling the request body",
|
||||
"request", requestBody,
|
||||
"error", err)
|
||||
return [][]float32{}, err
|
||||
}
|
||||
body := bytes.NewBuffer(serialized)
|
||||
req, err := http.NewRequest("POST", e.Cfg.Url+EMBEDDINGS_API, body)
|
||||
if err != nil {
|
||||
e.logger.Error("There was an error creating the request", "error", err.Error())
|
||||
return [][]float32{}, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
if e.Cfg.Key != "" {
|
||||
req.Header.Set("Authorization", "Bearer "+e.Cfg.Key)
|
||||
}
|
||||
e.logger.Debug("Executing embedding call", "req", req)
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
defer resp.Body.Close()
|
||||
if err != nil {
|
||||
e.logger.Error("There was an error during http call", "error", err.Error())
|
||||
return [][]float32{}, err
|
||||
}
|
||||
|
||||
e.logger.Debug("LLM Call returned", "response", resp)
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
e.logger.Error("There was an error reading the response body", "error", err.Error())
|
||||
return [][]float32{}, err
|
||||
}
|
||||
if resp.StatusCode != 200 && resp.StatusCode != 202 {
|
||||
e.logger.Error("Call returned non 200 status",
|
||||
"statusCode", resp.StatusCode,
|
||||
"status", resp.Status)
|
||||
return [][]float32{},
|
||||
errors.New("Call returned invalid status " +
|
||||
resp.Status)
|
||||
}
|
||||
|
||||
e.logger.Debug("Received data", "data", data)
|
||||
var response EmbedResponse
|
||||
if err := json.Unmarshal(data, &response); err != nil {
|
||||
e.logger.Error("There was an error parsing the response", "error", err.Error())
|
||||
return [][]float32{}, err
|
||||
}
|
||||
|
||||
if len(response.Data) == 0 {
|
||||
e.logger.Error("The call returned empty data")
|
||||
return [][]float32{}, errors.New("The call returned empty data")
|
||||
}
|
||||
|
||||
result := make([][]float32, len(text))
|
||||
for _, embed := range response.Data {
|
||||
if embed.Index < 0 || embed.Index >= len(result) {
|
||||
return nil, fmt.Errorf("Embedding index out of range. Index:%d Length:%d",
|
||||
embed.Index, len(result))
|
||||
}
|
||||
e.logger.Debug("Appening embbeding", "embed", embed.Embedding)
|
||||
result[embed.Index] = embed.Embedding
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
Reference in New Issue
Block a user