2023-07-14 23:19:43 +00:00
|
|
|
package grpc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
2023-08-18 23:49:33 +00:00
|
|
|
"sync"
|
2023-07-14 23:19:43 +00:00
|
|
|
"time"
|
|
|
|
|
2024-06-23 08:24:36 +00:00
|
|
|
pb "github.com/mudler/LocalAI/pkg/grpc/proto"
|
2023-07-14 23:19:43 +00:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Client struct {
|
2023-11-16 21:20:16 +00:00
|
|
|
address string
|
|
|
|
busy bool
|
|
|
|
parallel bool
|
2023-08-18 23:49:33 +00:00
|
|
|
sync.Mutex
|
2023-11-16 21:20:16 +00:00
|
|
|
opMutex sync.Mutex
|
2023-11-26 17:36:23 +00:00
|
|
|
wd WatchDog
|
2023-07-14 23:19:43 +00:00
|
|
|
}
|
|
|
|
|
2023-11-26 17:36:23 +00:00
|
|
|
type WatchDog interface {
|
|
|
|
Mark(address string)
|
|
|
|
UnMark(address string)
|
|
|
|
}
|
|
|
|
|
2023-08-18 23:49:33 +00:00
|
|
|
func (c *Client) IsBusy() bool {
|
|
|
|
c.Lock()
|
|
|
|
defer c.Unlock()
|
|
|
|
return c.busy
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) setBusy(v bool) {
|
|
|
|
c.Lock()
|
|
|
|
c.busy = v
|
|
|
|
c.Unlock()
|
|
|
|
}
|
|
|
|
|
2024-08-25 12:36:09 +00:00
|
|
|
func (c *Client) wdMark() {
|
|
|
|
if c.wd != nil {
|
|
|
|
c.wd.Mark(c.address)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) wdUnMark() {
|
|
|
|
if c.wd != nil {
|
|
|
|
c.wd.UnMark(c.address)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-01-07 23:37:02 +00:00
|
|
|
func (c *Client) HealthCheck(ctx context.Context) (bool, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
2024-01-07 23:37:02 +00:00
|
|
|
return false, err
|
2023-07-14 23:19:43 +00:00
|
|
|
}
|
|
|
|
defer conn.Close()
|
2023-07-14 23:19:43 +00:00
|
|
|
client := pb.NewBackendClient(conn)
|
2023-07-14 23:19:43 +00:00
|
|
|
|
|
|
|
// The healthcheck call shouldn't take long time
|
|
|
|
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
res, err := client.Health(ctx, &pb.HealthMessage{})
|
|
|
|
if err != nil {
|
2024-01-07 23:37:02 +00:00
|
|
|
return false, err
|
2023-07-14 23:19:43 +00:00
|
|
|
}
|
|
|
|
|
2023-07-27 16:41:04 +00:00
|
|
|
if string(res.Message) == "OK" {
|
2024-01-07 23:37:02 +00:00
|
|
|
return true, nil
|
2023-07-14 23:19:43 +00:00
|
|
|
}
|
2024-01-07 23:37:02 +00:00
|
|
|
|
|
|
|
return false, fmt.Errorf("health check failed: %s", res.Message)
|
2023-07-14 23:19:43 +00:00
|
|
|
}
|
|
|
|
|
2023-07-14 23:19:43 +00:00
|
|
|
func (c *Client) Embeddings(ctx context.Context, in *pb.PredictOptions, opts ...grpc.CallOption) (*pb.EmbeddingResult, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
2023-07-14 23:19:43 +00:00
|
|
|
client := pb.NewBackendClient(conn)
|
2023-07-14 23:19:43 +00:00
|
|
|
|
|
|
|
return client.Embedding(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
2023-07-14 23:19:43 +00:00
|
|
|
func (c *Client) Predict(ctx context.Context, in *pb.PredictOptions, opts ...grpc.CallOption) (*pb.Reply, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
2023-07-14 23:19:43 +00:00
|
|
|
client := pb.NewBackendClient(conn)
|
2023-07-14 23:19:43 +00:00
|
|
|
|
|
|
|
return client.Predict(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) LoadModel(ctx context.Context, in *pb.ModelOptions, opts ...grpc.CallOption) (*pb.Result, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
2023-07-14 23:19:43 +00:00
|
|
|
client := pb.NewBackendClient(conn)
|
2023-07-14 23:19:43 +00:00
|
|
|
return client.LoadModel(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
2024-12-18 08:48:50 +00:00
|
|
|
func (c *Client) PredictStream(ctx context.Context, in *pb.PredictOptions, f func(reply *pb.Reply), opts ...grpc.CallOption) error {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
2023-07-14 23:19:43 +00:00
|
|
|
client := pb.NewBackendClient(conn)
|
2023-07-14 23:19:43 +00:00
|
|
|
|
|
|
|
stream, err := client.PredictStream(ctx, in, opts...)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for {
|
2024-12-18 08:48:50 +00:00
|
|
|
reply, err := stream.Recv()
|
2023-07-14 23:19:43 +00:00
|
|
|
if err == io.EOF {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println("Error", err)
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
2024-12-18 08:48:50 +00:00
|
|
|
f(reply)
|
2023-07-14 23:19:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2023-07-14 23:19:43 +00:00
|
|
|
|
|
|
|
func (c *Client) GenerateImage(ctx context.Context, in *pb.GenerateImageRequest, opts ...grpc.CallOption) (*pb.Result, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.GenerateImage(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) TTS(ctx context.Context, in *pb.TTSRequest, opts ...grpc.CallOption) (*pb.Result, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.TTS(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
2024-08-24 00:20:28 +00:00
|
|
|
func (c *Client) SoundGeneration(ctx context.Context, in *pb.SoundGenerationRequest, opts ...grpc.CallOption) (*pb.Result, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2024-08-24 00:20:28 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.SoundGeneration(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
2024-09-02 13:48:53 +00:00
|
|
|
func (c *Client) AudioTranscription(ctx context.Context, in *pb.TranscriptRequest, opts ...grpc.CallOption) (*pb.TranscriptResult, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-07-14 23:19:43 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
2024-09-02 13:48:53 +00:00
|
|
|
return client.AudioTranscription(ctx, in, opts...)
|
2023-07-14 23:19:43 +00:00
|
|
|
}
|
2023-08-18 19:23:14 +00:00
|
|
|
|
|
|
|
func (c *Client) TokenizeString(ctx context.Context, in *pb.PredictOptions, opts ...grpc.CallOption) (*pb.TokenizationResponse, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2023-08-18 19:23:14 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
|
|
|
|
res, err := client.TokenizeString(ctx, in, opts...)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return res, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) Status(ctx context.Context) (*pb.StatusResponse, error) {
|
2023-11-16 21:20:16 +00:00
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2023-08-18 23:49:33 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2023-08-18 19:23:14 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.Status(ctx, &pb.HealthMessage{})
|
|
|
|
}
|
2024-03-22 20:14:04 +00:00
|
|
|
|
|
|
|
func (c *Client) StoresSet(ctx context.Context, in *pb.StoresSetOptions, opts ...grpc.CallOption) (*pb.Result, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2024-03-22 20:14:04 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.StoresSet(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) StoresDelete(ctx context.Context, in *pb.StoresDeleteOptions, opts ...grpc.CallOption) (*pb.Result, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2024-03-22 20:14:04 +00:00
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.StoresDelete(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) StoresGet(ctx context.Context, in *pb.StoresGetOptions, opts ...grpc.CallOption) (*pb.StoresGetResult, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2024-03-22 20:14:04 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.StoresGet(ctx, in, opts...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Client) StoresFind(ctx context.Context, in *pb.StoresFindOptions, opts ...grpc.CallOption) (*pb.StoresFindResult, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2024-03-22 20:14:04 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.StoresFind(ctx, in, opts...)
|
|
|
|
}
|
2024-04-24 22:19:02 +00:00
|
|
|
|
|
|
|
func (c *Client) Rerank(ctx context.Context, in *pb.RerankRequest, opts ...grpc.CallOption) (*pb.RerankResult, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
2024-08-25 12:36:09 +00:00
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
2024-04-24 22:19:02 +00:00
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.Rerank(ctx, in, opts...)
|
|
|
|
}
|
2024-10-01 12:41:20 +00:00
|
|
|
|
|
|
|
func (c *Client) GetTokenMetrics(ctx context.Context, in *pb.MetricsRequest, opts ...grpc.CallOption) (*pb.MetricsResponse, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.GetMetrics(ctx, in, opts...)
|
|
|
|
}
|
2024-11-20 13:48:40 +00:00
|
|
|
|
|
|
|
func (c *Client) VAD(ctx context.Context, in *pb.VADRequest, opts ...grpc.CallOption) (*pb.VADResponse, error) {
|
|
|
|
if !c.parallel {
|
|
|
|
c.opMutex.Lock()
|
|
|
|
defer c.opMutex.Unlock()
|
|
|
|
}
|
|
|
|
c.setBusy(true)
|
|
|
|
defer c.setBusy(false)
|
|
|
|
c.wdMark()
|
|
|
|
defer c.wdUnMark()
|
|
|
|
conn, err := grpc.Dial(c.address, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer conn.Close()
|
|
|
|
client := pb.NewBackendClient(conn)
|
|
|
|
return client.VAD(ctx, in, opts...)
|
|
|
|
}
|