mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-04 10:13:53 +08:00
fix:bug
This commit is contained in:
@@ -48,10 +48,14 @@ func (i *imlAPIController) Create(ctx *gin.Context, serviceId string, input *ai_
|
||||
}
|
||||
}
|
||||
if input.AiModel != nil {
|
||||
provider := "ollama"
|
||||
if input.AiModel.Type != "local" {
|
||||
provider = input.AiModel.Provider
|
||||
}
|
||||
plugins["ai_formatter"] = api.PluginSetting{
|
||||
Config: plugin_model.ConfigType{
|
||||
"model": input.AiModel.Id,
|
||||
"provider": input.AiModel.Provider,
|
||||
"provider": provider,
|
||||
"config": input.AiModel.Config,
|
||||
},
|
||||
}
|
||||
@@ -102,10 +106,14 @@ func (i *imlAPIController) Edit(ctx *gin.Context, serviceId string, apiId string
|
||||
}
|
||||
//var upstream *string
|
||||
if input.AiModel != nil {
|
||||
provider := "ollama"
|
||||
if input.AiModel.Type != "local" {
|
||||
provider = input.AiModel.Provider
|
||||
}
|
||||
proxy.Plugins["ai_formatter"] = api.PluginSetting{
|
||||
Config: plugin_model.ConfigType{
|
||||
"model": input.AiModel.Id,
|
||||
"provider": input.AiModel.Provider,
|
||||
"provider": provider,
|
||||
"config": input.AiModel.Config,
|
||||
},
|
||||
}
|
||||
|
||||
+123
-89
@@ -8,6 +8,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
subscribe_dto "github.com/APIParkLab/APIPark/module/subscribe/dto"
|
||||
|
||||
"github.com/APIParkLab/APIPark/module/subscribe"
|
||||
|
||||
ai_local "github.com/APIParkLab/APIPark/module/ai-local"
|
||||
|
||||
ai_dto "github.com/APIParkLab/APIPark/module/ai/dto"
|
||||
@@ -64,11 +68,13 @@ var (
|
||||
type imlServiceController struct {
|
||||
module service.IServiceModule `autowired:""`
|
||||
docModule service.IServiceDocModule `autowired:""`
|
||||
subscribeModule subscribe.ISubscribeModule `autowired:""`
|
||||
aiAPIModule ai_api.IAPIModule `autowired:""`
|
||||
routerModule router.IRouterModule `autowired:""`
|
||||
apiDocModule api_doc.IAPIDocModule `autowired:""`
|
||||
providerModule ai.IProviderModule `autowired:""`
|
||||
aiLocalModel ai_local.ILocalModelModule `autowired:""`
|
||||
appModule service.IAppModule `autowired:""`
|
||||
upstreamModule upstream.IUpstreamModule `autowired:""`
|
||||
settingModule system.ISettingModule `autowired:""`
|
||||
teamModule team.ITeamModule `autowired:""`
|
||||
@@ -86,27 +92,26 @@ func (i *imlServiceController) QuickCreateAIService(ctx *gin.Context, input *ser
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pv, err := i.providerModule.Provider(ctx, input.Provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p, has := model_runtime.GetProvider(input.Provider)
|
||||
if !has {
|
||||
return fmt.Errorf("provider not found")
|
||||
}
|
||||
m, has := p.GetModel(pv.DefaultLLM)
|
||||
if !has {
|
||||
return fmt.Errorf("model %s not found", pv.DefaultLLM)
|
||||
}
|
||||
//pv, err := i.providerModule.Provider(ctx, input.Provider)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//p, has := model_runtime.GetProvider(input.Provider)
|
||||
//if !has {
|
||||
// return fmt.Errorf("provider not found")
|
||||
//}
|
||||
//m, has := p.GetModel(pv.DefaultLLM)
|
||||
//if !has {
|
||||
// return fmt.Errorf("model %s not found", pv.DefaultLLM)
|
||||
//}
|
||||
|
||||
var info *service_dto.Service
|
||||
id := uuid.NewString()
|
||||
prefix := fmt.Sprintf("/%s", id[:8])
|
||||
catalogueInfo, err := i.catalogueModule.DefaultCatalogue(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err = i.module.Create(ctx, input.Team, &service_dto.CreateService{
|
||||
_, err = i.createAIService(ctx, input.Team, &service_dto.CreateService{
|
||||
Id: uuid.NewString(),
|
||||
Name: input.Provider + " AI Service",
|
||||
Prefix: prefix,
|
||||
@@ -118,82 +123,92 @@ func (i *imlServiceController) QuickCreateAIService(ctx *gin.Context, input *ser
|
||||
Provider: &input.Provider,
|
||||
Kind: "ai",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
//info, err = i.module.Create(ctx, input.Team, &service_dto.CreateService{
|
||||
// Id: uuid.NewString(),
|
||||
// Name: input.Provider + " AI Service",
|
||||
// Prefix: prefix,
|
||||
// Description: "Quick create by AI provider",
|
||||
// ServiceType: "public",
|
||||
// State: "normal",
|
||||
// Catalogue: catalogueInfo.Id,
|
||||
// ApprovalType: "auto",
|
||||
// Provider: &input.Provider,
|
||||
// Kind: "ai",
|
||||
//})
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//path := fmt.Sprintf("%s/chat", prefix)
|
||||
//timeout := 300000
|
||||
//retry := 0
|
||||
//aiPrompt := &ai_api_dto.AiPrompt{
|
||||
// Variables: []*ai_api_dto.AiPromptVariable{},
|
||||
// Prompt: "",
|
||||
//}
|
||||
//aiModel := &ai_api_dto.AiModel{
|
||||
// Id: m.ID(),
|
||||
// Config: m.DefaultConfig(),
|
||||
// Provider: input.Provider,
|
||||
//}
|
||||
//name := "Demo AI API"
|
||||
//description := "A demo that shows you how to use a e a Chat"
|
||||
//apiId := uuid.New().String()
|
||||
//err = i.aiAPIModule.Create(
|
||||
// ctx,
|
||||
// info.Id,
|
||||
// &ai_api_dto.CreateAPI{
|
||||
// Id: apiId,
|
||||
// Name: name,
|
||||
// Path: path,
|
||||
// Description: description,
|
||||
// Disable: false,
|
||||
// AiPrompt: aiPrompt,
|
||||
// AiModel: aiModel,
|
||||
// Timeout: timeout,
|
||||
// Retry: retry,
|
||||
// },
|
||||
//)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//plugins := make(map[string]api.PluginSetting)
|
||||
//plugins["ai_prompt"] = api.PluginSetting{
|
||||
// Config: plugin_model.ConfigType{
|
||||
// "prompt": aiPrompt.Prompt,
|
||||
// "variables": aiPrompt.Variables,
|
||||
// },
|
||||
//}
|
||||
//plugins["ai_formatter"] = api.PluginSetting{
|
||||
// Config: plugin_model.ConfigType{
|
||||
// "model": aiModel.Id,
|
||||
// "provider": info.Provider.Id,
|
||||
// "config": aiModel.Config,
|
||||
// },
|
||||
//}
|
||||
//_, err = i.routerModule.Create(ctx, info.Id, &router_dto.Create{
|
||||
// Id: apiId,
|
||||
// Name: name,
|
||||
// Path: path,
|
||||
// Methods: []string{
|
||||
// http.MethodPost,
|
||||
// },
|
||||
// Description: description,
|
||||
// Protocols: []string{"http", "https"},
|
||||
// MatchRules: nil,
|
||||
// Proxy: &router_dto.InputProxy{
|
||||
// Path: path,
|
||||
// Timeout: timeout,
|
||||
// Retry: retry,
|
||||
// Plugins: plugins,
|
||||
// },
|
||||
// Disable: false,
|
||||
//})
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
|
||||
path := fmt.Sprintf("%s/chat", prefix)
|
||||
timeout := 300000
|
||||
retry := 0
|
||||
aiPrompt := &ai_api_dto.AiPrompt{
|
||||
Variables: []*ai_api_dto.AiPromptVariable{},
|
||||
Prompt: "",
|
||||
}
|
||||
aiModel := &ai_api_dto.AiModel{
|
||||
Id: m.ID(),
|
||||
Config: m.DefaultConfig(),
|
||||
Provider: input.Provider,
|
||||
}
|
||||
name := "Demo AI API"
|
||||
description := "A demo that shows you how to use a e a Chat"
|
||||
apiId := uuid.New().String()
|
||||
err = i.aiAPIModule.Create(
|
||||
ctx,
|
||||
info.Id,
|
||||
&ai_api_dto.CreateAPI{
|
||||
Id: apiId,
|
||||
Name: name,
|
||||
Path: path,
|
||||
Description: description,
|
||||
Disable: false,
|
||||
AiPrompt: aiPrompt,
|
||||
AiModel: aiModel,
|
||||
Timeout: timeout,
|
||||
Retry: retry,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
plugins := make(map[string]api.PluginSetting)
|
||||
plugins["ai_prompt"] = api.PluginSetting{
|
||||
Config: plugin_model.ConfigType{
|
||||
"prompt": aiPrompt.Prompt,
|
||||
"variables": aiPrompt.Variables,
|
||||
},
|
||||
}
|
||||
plugins["ai_formatter"] = api.PluginSetting{
|
||||
Config: plugin_model.ConfigType{
|
||||
"model": aiModel.Id,
|
||||
"provider": info.Provider.Id,
|
||||
"config": aiModel.Config,
|
||||
},
|
||||
}
|
||||
_, err = i.routerModule.Create(ctx, info.Id, &router_dto.Create{
|
||||
Id: apiId,
|
||||
Name: name,
|
||||
Path: path,
|
||||
Methods: []string{
|
||||
http.MethodPost,
|
||||
},
|
||||
Description: description,
|
||||
Protocols: []string{"http", "https"},
|
||||
MatchRules: nil,
|
||||
Proxy: &router_dto.InputProxy{
|
||||
Path: path,
|
||||
Timeout: timeout,
|
||||
Retry: retry,
|
||||
Plugins: plugins,
|
||||
},
|
||||
Disable: false,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return i.docModule.SaveServiceDoc(ctx, info.Id, &service_dto.SaveServiceDoc{
|
||||
Doc: "",
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -264,6 +279,16 @@ func (i *imlServiceController) QuickCreateRestfulService(ctx *gin.Context) error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apps, err := i.appModule.Search(ctx, teamId, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, app := range apps {
|
||||
i.subscribeModule.AddSubscriber(ctx, id, &subscribe_dto.AddSubscriber{
|
||||
Application: app.Id,
|
||||
})
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -512,6 +537,15 @@ func (i *imlServiceController) createAIService(ctx *gin.Context, teamID string,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
apps, err := i.appModule.Search(ctx, info.Team.Id, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, app := range apps {
|
||||
i.subscribeModule.AddSubscriber(ctx, info.Id, &subscribe_dto.AddSubscriber{
|
||||
Application: app.Id,
|
||||
})
|
||||
}
|
||||
|
||||
return i.docModule.SaveServiceDoc(ctx, info.Id, &service_dto.SaveServiceDoc{
|
||||
Doc: "",
|
||||
|
||||
+69
-15
@@ -39,6 +39,13 @@ type imlBalanceModule struct {
|
||||
}
|
||||
|
||||
func (i *imlBalanceModule) Create(ctx context.Context, input *ai_balance_dto.Create) error {
|
||||
has, err := i.balanceService.Exist(ctx, input.Provider, input.Model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if has {
|
||||
return fmt.Errorf("model already exists")
|
||||
}
|
||||
priority, err := i.balanceService.MaxPriority(ctx)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -64,19 +71,52 @@ func (i *imlBalanceModule) Create(ctx context.Context, input *ai_balance_dto.Cre
|
||||
providerName = "Ollama"
|
||||
modelName = input.Model
|
||||
}
|
||||
return i.balanceService.Create(ctx, &ai_balance.Create{
|
||||
Id: input.Id,
|
||||
Priority: priority + 1,
|
||||
Provider: input.Provider,
|
||||
ProviderName: providerName,
|
||||
Model: input.Model,
|
||||
ModelName: modelName,
|
||||
Type: ai_balance_dto.ModelType(input.Type).Int(),
|
||||
return i.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
err = i.balanceService.Create(ctx, &ai_balance.Create{
|
||||
Id: input.Id,
|
||||
Priority: priority + 1,
|
||||
Provider: input.Provider,
|
||||
ProviderName: providerName,
|
||||
Model: input.Model,
|
||||
ModelName: modelName,
|
||||
Type: ai_balance_dto.ModelType(input.Type).Int(),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
item, err := i.balanceService.Get(ctx, input.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return i.syncGateway(ctx, cluster.DefaultClusterID, []*gateway.DynamicRelease{newRelease(item)}, true)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
var (
|
||||
ollamaConfig = "{\n \"mirostat\": 0,\n \"mirostat_eta\": 0.1,\n \"mirostat_tau\": 5.0,\n \"num_ctx\": 4096,\n \"repeat_last_n\":64,\n \"repeat_penalty\": 1.1,\n \"temperature\": 0.7,\n \"seed\": 42,\n \"num_predict\": 42,\n \"top_k\": 40,\n \"top_p\": 0.9,\n \"min_p\": 0.5\n}\n"
|
||||
ollamaBase = "http://apipark-ollama:11434"
|
||||
)
|
||||
|
||||
func newRelease(item *ai_balance.Balance) *gateway.DynamicRelease {
|
||||
return &gateway.DynamicRelease{}
|
||||
|
||||
cfg := make(map[string]interface{})
|
||||
cfg["provider"] = item.Id
|
||||
cfg["model"] = item.Model
|
||||
cfg["model_config"] = ollamaConfig
|
||||
cfg["base"] = ollamaBase
|
||||
return &gateway.DynamicRelease{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: item.Id,
|
||||
Description: item.ModelName,
|
||||
Resource: "ai-provider",
|
||||
Version: item.UpdateAt.Format("20060102150405"),
|
||||
MatchLabels: map[string]string{
|
||||
"module": "ai-provider",
|
||||
},
|
||||
},
|
||||
Attr: cfg,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *imlBalanceModule) Sort(ctx context.Context, input *ai_balance_dto.Sort) error {
|
||||
@@ -91,11 +131,13 @@ func (i *imlBalanceModule) Sort(ctx context.Context, input *ai_balance_dto.Sort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
releases := make([]*gateway.DynamicRelease, 0, len(list))
|
||||
for _, item := range list {
|
||||
err = i.syncGateway(ctx, cluster.DefaultClusterID, []*gateway.DynamicRelease{newRelease(item)}, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
releases = append(releases, newRelease(item))
|
||||
}
|
||||
err = i.syncGateway(ctx, cluster.DefaultClusterID, releases, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -140,11 +182,23 @@ func (i *imlBalanceModule) List(ctx context.Context, keyword string) ([]*ai_bala
|
||||
}
|
||||
|
||||
func (i *imlBalanceModule) Delete(ctx context.Context, id string) error {
|
||||
return i.balanceService.Delete(ctx, id)
|
||||
return i.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
err := i.balanceService.Delete(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return i.syncGateway(ctx, cluster.DefaultClusterID, []*gateway.DynamicRelease{
|
||||
{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: id,
|
||||
},
|
||||
},
|
||||
}, false)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (i *imlBalanceModule) syncGateway(ctx context.Context, clusterId string, releases []*gateway.DynamicRelease, online bool) error {
|
||||
return nil
|
||||
client, err := i.clusterService.GatewayClient(ctx, clusterId)
|
||||
if err != nil {
|
||||
log.Errorf("get apinto client error: %v", err)
|
||||
|
||||
+140
-16
@@ -4,8 +4,16 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/eolinker/eosc/env"
|
||||
|
||||
"github.com/APIParkLab/APIPark/gateway"
|
||||
"github.com/eolinker/eosc/log"
|
||||
|
||||
"github.com/APIParkLab/APIPark/service/cluster"
|
||||
|
||||
"github.com/APIParkLab/APIPark/service/service"
|
||||
|
||||
"github.com/eolinker/go-common/auto"
|
||||
@@ -35,6 +43,7 @@ type imlLocalModel struct {
|
||||
localModelService ai_local.ILocalModelService `autowired:""`
|
||||
localModelPackageService ai_local.ILocalModelPackageService `autowired:""`
|
||||
localModelStateService ai_local.ILocalModelInstallStateService `autowired:""`
|
||||
clusterService cluster.IClusterService `autowired:""`
|
||||
aiAPIService ai_api.IAPIService `autowired:""`
|
||||
serviceService service.IServiceService `autowired:""`
|
||||
transaction store.ITransaction `autowired:""`
|
||||
@@ -42,8 +51,21 @@ type imlLocalModel struct {
|
||||
|
||||
var (
|
||||
ollamaConfig = "{\n \"mirostat\": 0,\n \"mirostat_eta\": 0.1,\n \"mirostat_tau\": 5.0,\n \"num_ctx\": 4096,\n \"repeat_last_n\":64,\n \"repeat_penalty\": 1.1,\n \"temperature\": 0.7,\n \"seed\": 42,\n \"num_predict\": 42,\n \"top_k\": 40,\n \"top_p\": 0.9,\n \"min_p\": 0.5\n}\n"
|
||||
ollamaBase = "http://apipark-ollama:11434"
|
||||
)
|
||||
|
||||
func init() {
|
||||
base, has := env.GetEnv("OLLAMA_BASE")
|
||||
if !has {
|
||||
return
|
||||
}
|
||||
_, err := url.Parse(base)
|
||||
if err == nil {
|
||||
ollamaBase = base
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (i *imlLocalModel) SimpleList(ctx context.Context) ([]*ai_local_dto.SimpleItem, error) {
|
||||
list, err := i.localModelService.List(ctx)
|
||||
if err != nil {
|
||||
@@ -135,6 +157,7 @@ func (i *imlLocalModel) ListCanInstall(ctx context.Context, keyword string) ([]*
|
||||
func (i *imlLocalModel) pullHook() func(msg ai_provider_local.PullMessage) error {
|
||||
return func(msg ai_provider_local.PullMessage) error {
|
||||
return i.transaction.Transaction(context.Background(), func(ctx context.Context) error {
|
||||
|
||||
state := ai_local_dto.DeployStateFinish.Int()
|
||||
modelState := ai_local_dto.LocalModelStateNormal.Int()
|
||||
if msg.Status == "error" {
|
||||
@@ -151,7 +174,7 @@ func (i *imlLocalModel) pullHook() func(msg ai_provider_local.PullMessage) error
|
||||
return err
|
||||
}
|
||||
|
||||
return i.localModelStateService.Create(ctx, &ai_local.CreateLocalModelInstallState{
|
||||
err = i.localModelStateService.Create(ctx, &ai_local.CreateLocalModelInstallState{
|
||||
Id: msg.Model,
|
||||
Complete: msg.Completed,
|
||||
Total: msg.Total,
|
||||
@@ -159,30 +182,83 @@ func (i *imlLocalModel) pullHook() func(msg ai_provider_local.PullMessage) error
|
||||
Msg: msg.Msg,
|
||||
})
|
||||
|
||||
}
|
||||
if info.Complete < msg.Completed {
|
||||
info.Complete = msg.Completed
|
||||
} else {
|
||||
if info.Complete < msg.Completed {
|
||||
info.Complete = msg.Completed
|
||||
|
||||
}
|
||||
if info.Total < msg.Total {
|
||||
info.Total = msg.Total
|
||||
}
|
||||
if msg.Msg != "" {
|
||||
info.Msg = msg.Msg
|
||||
}
|
||||
err = i.localModelStateService.Save(ctx, msg.Model, &ai_local.EditLocalModelInstallState{State: &state, Complete: &info.Complete, Total: &info.Total, Msg: &info.Msg})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serviceState := 0
|
||||
if msg.Status == "error" {
|
||||
state = 2
|
||||
}
|
||||
err = i.serviceService.Save(ctx, msg.Model, &service.Edit{State: &serviceState})
|
||||
}
|
||||
if info.Total < msg.Total {
|
||||
info.Total = msg.Total
|
||||
}
|
||||
if msg.Msg != "" {
|
||||
info.Msg = msg.Msg
|
||||
}
|
||||
err = i.localModelStateService.Save(ctx, msg.Model, &ai_local.EditLocalModelInstallState{State: &state, Complete: &info.Complete, Total: &info.Total, Msg: &info.Msg})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
serviceState := 0
|
||||
if msg.Status == "error" {
|
||||
state = 2
|
||||
}
|
||||
return i.serviceService.Save(ctx, msg.Model, &service.Edit{State: &serviceState})
|
||||
cfg := make(map[string]interface{})
|
||||
cfg["provider"] = "ollama"
|
||||
cfg["model"] = msg.Model
|
||||
cfg["model_config"] = ollamaConfig
|
||||
cfg["priority"] = 0
|
||||
cfg["base"] = ollamaBase
|
||||
return i.syncGateway(ctx, cluster.DefaultClusterID, []*gateway.DynamicRelease{
|
||||
{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: msg.Model,
|
||||
Description: msg.Model,
|
||||
Resource: "ai-provider",
|
||||
Version: info.UpdateAt.Format("20060102150405"),
|
||||
MatchLabels: map[string]string{
|
||||
"module": "ai-provider",
|
||||
},
|
||||
},
|
||||
Attr: cfg,
|
||||
}}, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (i *imlLocalModel) syncGateway(ctx context.Context, clusterId string, releases []*gateway.DynamicRelease, online bool) error {
|
||||
client, err := i.clusterService.GatewayClient(ctx, clusterId)
|
||||
if err != nil {
|
||||
log.Errorf("get apinto client error: %v", err)
|
||||
return nil
|
||||
}
|
||||
defer func() {
|
||||
err := client.Close(ctx)
|
||||
if err != nil {
|
||||
log.Warn("close apinto client:", err)
|
||||
}
|
||||
}()
|
||||
for _, releaseInfo := range releases {
|
||||
dynamicClient, err := client.Dynamic(releaseInfo.Resource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if online {
|
||||
err = dynamicClient.Online(ctx, releaseInfo)
|
||||
} else {
|
||||
err = dynamicClient.Offline(ctx, releaseInfo)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *imlLocalModel) Deploy(ctx context.Context, model string, session string) (*ai_provider_local.Pipeline, error) {
|
||||
var p *ai_provider_local.Pipeline
|
||||
err := i.transaction.Transaction(ctx, func(txCtx context.Context) error {
|
||||
@@ -341,3 +417,51 @@ func (i *imlLocalModel) OnInit() {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (i *imlLocalModel) getLocalModels(ctx context.Context) ([]*gateway.DynamicRelease, error) {
|
||||
list, err := i.localModelService.List(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
releases := make([]*gateway.DynamicRelease, 0, len(list))
|
||||
for _, l := range list {
|
||||
cfg := make(map[string]interface{})
|
||||
cfg["provider"] = "ollama"
|
||||
cfg["model"] = l.Id
|
||||
cfg["model_config"] = ollamaConfig
|
||||
cfg["base"] = ollamaBase
|
||||
releases = append(releases, &gateway.DynamicRelease{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: l.Id,
|
||||
Description: l.Name,
|
||||
Resource: "ai-provider",
|
||||
Version: l.UpdateAt.Format("20060102150405"),
|
||||
MatchLabels: map[string]string{
|
||||
"module": "ai-provider",
|
||||
},
|
||||
},
|
||||
Attr: cfg,
|
||||
})
|
||||
}
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func (i *imlLocalModel) initGateway(ctx context.Context, clusterId string, clientDriver gateway.IClientDriver) error {
|
||||
releases, err := i.getLocalModels(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, p := range releases {
|
||||
client, err := clientDriver.Dynamic(p.Resource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = client.Online(ctx, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/APIParkLab/APIPark/gateway"
|
||||
|
||||
"github.com/eolinker/go-common/autowire"
|
||||
|
||||
ai_provider_local "github.com/APIParkLab/APIPark/ai-provider/local"
|
||||
@@ -24,7 +26,9 @@ type ILocalModelModule interface {
|
||||
}
|
||||
|
||||
func init() {
|
||||
localModel := new(imlLocalModel)
|
||||
autowire.Auto[ILocalModelModule](func() reflect.Value {
|
||||
return reflect.ValueOf(&imlLocalModel{})
|
||||
gateway.RegisterInitHandleFunc(localModel.initGateway)
|
||||
return reflect.ValueOf(localModel)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -129,74 +129,6 @@ func (i *imlProviderModule) SimpleProvider(ctx context.Context, id string) (*ai_
|
||||
}, nil
|
||||
}
|
||||
|
||||
//func (i *imlProviderModule) Sort(ctx context.Context, input *ai_dto.Sort) error {
|
||||
// return i.transaction.Transaction(ctx, func(txCtx context.Context) error {
|
||||
// list, err := i.providerService.List(ctx)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// providerMap := utils.SliceToMap(list, func(e *ai.Provider) string {
|
||||
// return e.Id
|
||||
// })
|
||||
// releases := make([]*gateway.DynamicRelease, 0, len(list))
|
||||
// offlineReleases := make([]*gateway.DynamicRelease, 0, len(list))
|
||||
// for index, id := range input.Providers {
|
||||
// p, has := model_runtime.GetProvider(id)
|
||||
// if !has {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// l, has := providerMap[id]
|
||||
// if !has {
|
||||
// continue
|
||||
// }
|
||||
// model, has := p.GetModel(l.DefaultLLM)
|
||||
// if !has {
|
||||
// continue
|
||||
// }
|
||||
// priority := index + 1
|
||||
// err = i.providerService.Save(txCtx, id, &ai.SetProvider{
|
||||
// Priority: &priority,
|
||||
// })
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// if ai_dto.ToProviderStatus(l.Status) == ai_dto.ProviderDisabled {
|
||||
// offlineReleases = append(offlineReleases, &gateway.DynamicRelease{
|
||||
// BasicItem: &gateway.BasicItem{
|
||||
// ID: l.Id,
|
||||
// Resource: "ai-provider",
|
||||
// }})
|
||||
// } else {
|
||||
// cfg := make(map[string]interface{})
|
||||
// cfg["provider"] = l.Id
|
||||
// cfg["model"] = l.DefaultLLM
|
||||
// cfg["model_config"] = model.DefaultConfig()
|
||||
// cfg["priority"] = l.Priority
|
||||
// cfg["base"] = fmt.Sprintf("%s://%s", p.URI().Scheme(), p.URI().Host())
|
||||
// releases = append(releases, &gateway.DynamicRelease{
|
||||
// BasicItem: &gateway.BasicItem{
|
||||
// ID: l.Id,
|
||||
// Description: l.Name,
|
||||
// Resource: "ai-provider",
|
||||
// Version: l.UpdateAt.Format("20060102150405"),
|
||||
// MatchLabels: map[string]string{
|
||||
// "module": "ai-provider",
|
||||
// },
|
||||
// },
|
||||
// Attr: cfg,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// err = i.syncGateway(ctx, cluster.DefaultClusterID, releases, true)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// return i.syncGateway(ctx, cluster.DefaultClusterID, offlineReleases, false)
|
||||
//
|
||||
// })
|
||||
//}
|
||||
|
||||
func (i *imlProviderModule) ConfiguredProviders(ctx context.Context, keyword string) ([]*ai_dto.ConfiguredProviderItem, error) {
|
||||
// 获取已配置的AI服务商
|
||||
list, err := i.providerService.Search(ctx, keyword, nil, "update_at")
|
||||
@@ -611,7 +543,6 @@ func (i *imlProviderModule) UpdateProviderConfig(ctx context.Context, id string,
|
||||
cfg["provider"] = info.Id
|
||||
cfg["model"] = info.DefaultLLM
|
||||
cfg["model_config"] = model.DefaultConfig()
|
||||
cfg["priority"] = info.Priority
|
||||
cfg["base"] = fmt.Sprintf("%s://%s", p.URI().Scheme(), p.URI().Host())
|
||||
return i.syncGateway(txCtx, cluster.DefaultClusterID, []*gateway.DynamicRelease{
|
||||
{
|
||||
@@ -652,7 +583,6 @@ func (i *imlProviderModule) getAiProviders(ctx context.Context) ([]*gateway.Dyna
|
||||
cfg["provider"] = l.Id
|
||||
cfg["model"] = l.DefaultLLM
|
||||
cfg["model_config"] = model.DefaultConfig()
|
||||
cfg["priority"] = l.Priority
|
||||
providers = append(providers, &gateway.DynamicRelease{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: l.Id,
|
||||
|
||||
@@ -31,7 +31,7 @@ type EditService struct {
|
||||
Catalogue *string `json:"catalogue"`
|
||||
Logo *string `json:"logo"`
|
||||
Tags *[]string `json:"tags"`
|
||||
Provider *string `json:"provider" aocheck:"ai_provider"`
|
||||
Provider *string `json:"provider"`
|
||||
ApprovalType *string `json:"approval_type"`
|
||||
State *string `json:"state"`
|
||||
}
|
||||
|
||||
@@ -2,10 +2,13 @@ package ai_balance
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/eolinker/go-common/store"
|
||||
|
||||
"github.com/APIParkLab/APIPark/service/universally"
|
||||
@@ -23,6 +26,17 @@ type imlBalanceService struct {
|
||||
universally.IServiceDelete
|
||||
}
|
||||
|
||||
func (i *imlBalanceService) Exist(ctx context.Context, provider string, model string) (bool, error) {
|
||||
_, err := i.store.First(ctx, map[string]interface{}{"provider": provider, "model": model})
|
||||
if err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (i *imlBalanceService) OnComplete() {
|
||||
i.IServiceGet = universally.NewGet[Balance, ai.Balance](i.store, FromEntity)
|
||||
i.IServiceCreate = universally.NewCreator[Create, ai.Balance](i.store, "ai_balance", createEntityHandler, uniquestHandler, labelHandler)
|
||||
|
||||
@@ -17,6 +17,7 @@ type IBalanceService interface {
|
||||
MaxPriority(ctx context.Context) (int, error)
|
||||
SortBefore(ctx context.Context, originID string, targetID string) ([]*Balance, error)
|
||||
SortAfter(ctx context.Context, originID string, targetID string) ([]*Balance, error)
|
||||
Exist(ctx context.Context, provider string, model string) (bool, error)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
Reference in New Issue
Block a user