package bridge import ( "context" "encoding/json" "fmt" "io" "net/http" "strings" "time" ) // EngineEmbeddings reads templates from the local engine's API. type EngineEmbeddings struct { Base string User string Password string Client *http.Client } func NewEngineEmbeddings(base, user, password string) *EngineEmbeddings { return &EngineEmbeddings{ Base: strings.TrimRight(base, "/"), User: user, Password: password, Client: &http.Client{Timeout: 10 * time.Second}, } } func (e *EngineEmbeddings) Embedding(ctx context.Context, id int64) ([]float32, string, error) { url := fmt.Sprintf("%s/api/identities/%d/embedding", e.Base, id) req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) if err != nil { return nil, "", err } if e.User != "" { req.SetBasicAuth(e.User, e.Password) } resp, err := e.Client.Do(req) if err != nil { return nil, "", err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, "", fmt.Errorf("engine returned %s", resp.Status) } var body struct { Model string `json:"model"` Embedding []float32 `json:"embedding"` } if err := json.NewDecoder(io.LimitReader(resp.Body, 1<<20)).Decode(&body); err != nil { return nil, "", err } if len(body.Embedding) == 0 { return nil, "", fmt.Errorf("engine returned an empty embedding") } return body.Embedding, body.Model, nil }