From 5ee4f346241746285364948e4907864b8f826b54 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Mon, 17 Feb 2025 15:23:57 +0800 Subject: [PATCH 1/7] fix: ai deploy bug --- controller/ai-local/iml.go | 160 +++++++++++++++++------------------- module/ai-api/schema.go | 8 +- module/ai-local/iml.go | 63 ++++++++------ service/ai-local/iml.go | 4 + service/ai-local/service.go | 1 + service/api/iml.go | 3 +- service/api/model.go | 2 +- stores/api/model.go | 2 +- stores/service/model.go | 2 +- 9 files changed, 126 insertions(+), 119 deletions(-) diff --git a/controller/ai-local/iml.go b/controller/ai-local/iml.go index 4ba66ca7..10a6e860 100644 --- a/controller/ai-local/iml.go +++ b/controller/ai-local/iml.go @@ -6,14 +6,9 @@ import ( "fmt" "io" "math" - "net/http" - "strings" "github.com/APIParkLab/APIPark/module/router" - "github.com/APIParkLab/APIPark/model/plugin_model" - "github.com/APIParkLab/APIPark/service/api" - ai_api "github.com/APIParkLab/APIPark/module/ai-api" "github.com/APIParkLab/APIPark/module/catalogue" @@ -24,9 +19,6 @@ import ( service_dto "github.com/APIParkLab/APIPark/module/service/dto" - ai_api_dto "github.com/APIParkLab/APIPark/module/ai-api/dto" - router_dto "github.com/APIParkLab/APIPark/module/router/dto" - ai_provider_local "github.com/APIParkLab/APIPark/ai-provider/local" "github.com/eolinker/eosc/log" @@ -199,7 +191,7 @@ func (i *imlLocalModelController) initAILocalService(ctx context.Context, model serviceId := uuid.NewString() prefix := fmt.Sprintf("/%s", serviceId[:8]) providerId := "ollama" - info, err := i.serviceModule.Create(ctx, teamID, &service_dto.CreateService{ + _, err = i.serviceModule.Create(ctx, teamID, &service_dto.CreateService{ Id: serviceId, Name: model, Prefix: prefix, @@ -214,83 +206,81 @@ func (i *imlLocalModelController) initAILocalService(ctx context.Context, model if err != nil { return err } - err = i.module.SaveCache(ctx, model, serviceId) - if err != nil { - return err - } - path := fmt.Sprintf("/%s/chat", strings.Trim(prefix, "/")) - timeout := 300000 - retry := 0 - aiPrompt := &ai_api_dto.AiPrompt{ - Variables: []*ai_api_dto.AiPromptVariable{}, - Prompt: "", - } - aiModel := &ai_api_dto.AiModel{ - Id: model, - Config: ai_provider_local.OllamaConfig, - Provider: providerId, - Type: "local", - } - name := "Demo AI API" - description := "A demo that shows you how to use a e a Chat API." - apiId := uuid.NewString() - 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.module.SaveCache(ctx, model, serviceId) - return i.docModule.SaveServiceDoc(ctx, info.Id, &service_dto.SaveServiceDoc{ - Doc: "", - }) + //path := fmt.Sprintf("/%s/chat", strings.Trim(prefix, "/")) + //timeout := 300000 + //retry := 0 + //aiPrompt := &ai_api_dto.AiPrompt{ + // Variables: []*ai_api_dto.AiPromptVariable{}, + // Prompt: "", + //} + //aiModel := &ai_api_dto.AiModel{ + // Id: model, + // Config: ai_provider_local.OllamaConfig, + // Provider: providerId, + // Type: "local", + //} + //name := "Demo AI API" + //description := "A demo that shows you how to use a e a Chat API." + //apiId := uuid.NewString() + //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: "", + //}) }) return err diff --git a/module/ai-api/schema.go b/module/ai-api/schema.go index 2511d0ab..5c7c7c5c 100644 --- a/module/ai-api/schema.go +++ b/module/ai-api/schema.go @@ -72,9 +72,13 @@ func genResponse() *openapi3.ResponseRef { func genRequestBodySchema(variables []*ai_api_dto.AiPromptVariable) *openapi3.Schema { result := openapi3.NewObjectSchema() - result.WithProperty("variables", genVariableSchema(variables)) + if len(variables) > 0 { + result.WithProperty("variables", genVariableSchema(variables)) + result.WithRequired([]string{"variables", "messages"}) + } + result.WithPropertyRef("messages", messagesSchemaRef) - result.WithRequired([]string{"variables", "messages"}) + return result } diff --git a/module/ai-local/iml.go b/module/ai-local/iml.go index f6606b75..b32395be 100644 --- a/module/ai-local/iml.go +++ b/module/ai-local/iml.go @@ -130,34 +130,41 @@ func (i *imlLocalModel) Search(ctx context.Context, keyword string) ([]*ai_local } func (i *imlLocalModel) ListCanInstall(ctx context.Context, keyword string) ([]*ai_local_dto.LocalModelPackageItem, error) { - list, err := i.localModelPackageService.Search(ctx, keyword, nil) - if err != nil { - return nil, err - } - if keyword != "" { + + if keyword == "" { + list, err := i.localModelPackageService.Search(ctx, keyword, nil) + if err != nil { + return nil, err + } + return utils.SliceToSlice(list, func(s *ai_local.LocalModelPackage) *ai_local_dto.LocalModelPackageItem { + return &ai_local_dto.LocalModelPackageItem{ + Id: s.Id, + Name: s.Name, + Size: s.Size, + IsPopular: s.IsPopular, + } + }), nil + } else { + info, err := i.localModelPackageService.Get(ctx, keyword) + if err != nil { + return nil, err + } result := make([]*ai_local_dto.LocalModelPackageItem, 0) - for _, v := range list { - models := ai_provider_local.ModelsCanInstallById(v.Id) - for _, model := range models { - result = append(result, &ai_local_dto.LocalModelPackageItem{ - Id: model.Id, - Name: model.Name, - Size: model.Size, - IsPopular: model.IsPopular, - }) - } + //for _, v := range list { + models := ai_provider_local.ModelsCanInstallById(info.Id) + for _, model := range models { + result = append(result, &ai_local_dto.LocalModelPackageItem{ + Id: model.Id, + Name: model.Name, + Size: model.Size, + IsPopular: model.IsPopular, + }) } + //} return result, nil } - return utils.SliceToSlice(list, func(s *ai_local.LocalModelPackage) *ai_local_dto.LocalModelPackageItem { - return &ai_local_dto.LocalModelPackageItem{ - Id: s.Id, - Name: s.Name, - Size: s.Size, - IsPopular: s.IsPopular, - } - }), nil + } func (i *imlLocalModel) pullHook() func(msg ai_provider_local.PullMessage) error { @@ -292,7 +299,7 @@ func (i *imlLocalModel) syncGateway(ctx context.Context, clusterId string, relea 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 { - _, err := i.localModelService.Get(ctx, model) + info, err := i.localModelService.Get(ctx, model) if err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { return err @@ -305,8 +312,10 @@ func (i *imlLocalModel) Deploy(ctx context.Context, model string, session string }) } else { - state := ai_local_dto.LocalModelStateDeploying.Int() - err = i.localModelService.Save(ctx, model, &ai_local.EditLocalModel{State: &state}) + if info.State == ai_local_dto.LocalModelStateDeployingError.Int() { + state := ai_local_dto.LocalModelStateDeploying.Int() + err = i.localModelService.Save(ctx, model, &ai_local.EditLocalModel{State: &state}) + } } if err != nil { return err @@ -428,6 +437,7 @@ func (i *imlLocalModel) OnInit() { }) models, version := ai_provider_local.ModelsCanInstall() for _, model := range models { + delete(oldModels, model.Id) if v, ok := oldModels[model.Id]; ok { if v.Version == version { continue @@ -456,7 +466,6 @@ func (i *imlLocalModel) OnInit() { return } } - delete(oldModels, model.Id) } for id := range oldModels { err = i.localModelPackageService.Delete(ctx, id) diff --git a/service/ai-local/iml.go b/service/ai-local/iml.go index a970ba9d..e037d0a8 100644 --- a/service/ai-local/iml.go +++ b/service/ai-local/iml.go @@ -66,6 +66,10 @@ func (i *imlLocalModelService) fromEntity(e *ai.LocalModel) *LocalModel { } } +var ( + _ ILocalModelPackageService = &imlLocalModelPackageService{} +) + type imlLocalModelPackageService struct { store ai.ILocalModelPackageStore `autowired:""` universally.IServiceGet[LocalModelPackage] diff --git a/service/ai-local/service.go b/service/ai-local/service.go index 276cec8c..260d3029 100644 --- a/service/ai-local/service.go +++ b/service/ai-local/service.go @@ -20,6 +20,7 @@ type ILocalModelPackageService interface { universally.IServiceCreate[CreateLocalModelPackage] universally.IServiceEdit[EditLocalModelPackage] universally.IServiceDelete + //SearchByModel(ctx context.Context, model string) ([]*LocalModelPackage, error) } type ILocalModelInstallStateService interface { diff --git a/service/api/iml.go b/service/api/iml.go index 19117a72..a784fed5 100644 --- a/service/api/iml.go +++ b/service/api/iml.go @@ -42,10 +42,9 @@ type imlAPIService struct { } func (i *imlAPIService) DeleteByService(ctx context.Context, serviceId string) error { - _, err := i.store.DeleteWhere(ctx, map[string]interface{}{ + return i.store.SoftDelete(ctx, map[string]interface{}{ "service": serviceId, }) - return err } func (i *imlAPIService) ListForServices(ctx context.Context, serviceIds ...string) ([]*API, error) { diff --git a/service/api/model.go b/service/api/model.go index e4d5e662..4254f94a 100644 --- a/service/api/model.go +++ b/service/api/model.go @@ -48,7 +48,7 @@ func FromEntity(e *api.API) *API { return &API{ UUID: e.UUID, CreateAt: e.CreateAt, - IsDelete: e.IsDelete != 0, + IsDelete: e.IsDelete, Service: e.Service, Team: e.Team, Creator: e.Creator, diff --git a/stores/api/model.go b/stores/api/model.go index ba72ffda..9447da32 100644 --- a/stores/api/model.go +++ b/stores/api/model.go @@ -12,10 +12,10 @@ type API struct { Upstream string `gorm:"size:36;not null;column:upstream;comment:上游;index:upstream"` // 上游ID Creator string `gorm:"size:36;not null;column:creator;comment:创建人;index:creator" aovalue:"creator"` // 创建人 CreateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP;column:create_at;comment:创建时间"` - IsDelete int `gorm:"type:tinyint(1);not null;column:is_delete;comment:是否删除 0:未删除 1:已删除"` Method []string `gorm:"size:255;not null;column:method;comment:请求方法;serializer:json"` Protocol []string `gorm:"type:text;not null;column:protocol;comment:协议;serializer:json"` Path string `gorm:"size:255;not null;column:path;comment:请求路径"` + IsDelete bool `gorm:"type:tinyint(1);not null;column:is_delete;comment:是否删除 0:未删除 1:已删除"` } type Info struct { Id int64 `gorm:"column:id;type:BIGINT(20);NOT NULL;comment:id;primary_key;comment:主键ID;"` diff --git a/stores/service/model.go b/stores/service/model.go index eafc2933..d0d42d30 100644 --- a/stores/service/model.go +++ b/stores/service/model.go @@ -15,7 +15,7 @@ type Service struct { Catalogue string `gorm:"type:text;not null;column:catalogue;comment:目录"` CreateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP;column:create_at;comment:创建时间"` UpdateAt time.Time `gorm:"type:timestamp;NOT NULL;DEFAULT:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;column:update_at;comment:修改时间"` - IsDelete int `gorm:"type:tinyint(1);not null;column:is_delete;comment:是否删除"` + IsDelete bool `gorm:"type:tinyint(1);not null;column:is_delete;comment:是否删除"` Kind int `gorm:"type:tinyint(4);not null;column:kind;comment:服务种类,0:Rest服务,1:AI服务"` State int `gorm:"type:tinyint(4);not null;column:state;comment:状态"` AdditionalConfig string `gorm:"type:text;not null;column:additional_config;comment:额外配置"` From 0fa8f6e6e4ba8cca64a8471fd3fc8ca50fa72511 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Mon, 17 Feb 2025 16:12:21 +0800 Subject: [PATCH 2/7] Fix: Service List AI Entry Error --- controller/ai-local/iml.go | 14 ++++---------- module/ai-local/dto/input.go | 5 +++-- module/ai-local/iml.go | 9 +++++++++ service/ai-local/iml.go | 12 ++++++++++++ service/ai-local/service.go | 1 + 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/controller/ai-local/iml.go b/controller/ai-local/iml.go index 10a6e860..f6a4c825 100644 --- a/controller/ai-local/iml.go +++ b/controller/ai-local/iml.go @@ -83,15 +83,8 @@ func (i *imlLocalModelController) Deploy(ctx *gin.Context) { "code": -1, "msg": "model is required", "success": "fail", }) return - } - //err = i.initAILocalService(ctx, input.Model, input.Team) - //if err != nil { - // ctx.JSON(200, gin.H{ - // "code": -1, "msg": err.Error(), "success": "fail", - // }) - // return - //} + id := uuid.NewString() p, err := i.module.Deploy(ctx, input.Model, id) if err != nil { @@ -105,10 +98,11 @@ func (i *imlLocalModelController) Deploy(ctx *gin.Context) { go func() { select { case <-ctx.Writer.CloseNotify(): - log.Info("client closed connection,close pipeline") - ai_provider_local.CancelPipeline(input.Model, id) + case <-done: + } + ai_provider_local.CancelPipeline(input.Model, id) }() var complete int64 var total int64 diff --git a/module/ai-local/dto/input.go b/module/ai-local/dto/input.go index b7a3ac98..28ac175f 100644 --- a/module/ai-local/dto/input.go +++ b/module/ai-local/dto/input.go @@ -9,6 +9,7 @@ type CancelDeploy struct { } type DeployInput struct { - Model string `json:"model"` - Team string `json:"team"` + Model string `json:"model"` + Service string `json:"service"` + Team string `json:"team"` } diff --git a/module/ai-local/iml.go b/module/ai-local/iml.go index b32395be..da22e6b6 100644 --- a/module/ai-local/iml.go +++ b/module/ai-local/iml.go @@ -299,6 +299,15 @@ func (i *imlLocalModel) syncGateway(ctx context.Context, clusterId string, relea 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 { + item, err := i.localModelCacheService.GetByTarget(ctx, ai_local.CacheTypeService, model) + if err != nil { + if !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + + } else { + model = item.Model + } info, err := i.localModelService.Get(ctx, model) if err != nil { if !errors.Is(err, gorm.ErrRecordNotFound) { diff --git a/service/ai-local/iml.go b/service/ai-local/iml.go index e037d0a8..7c992c36 100644 --- a/service/ai-local/iml.go +++ b/service/ai-local/iml.go @@ -201,6 +201,18 @@ type imlLocalModelCacheService struct { store ai.ILocalModelCacheStore `autowired:""` } +func (i *imlLocalModelCacheService) GetByTarget(ctx context.Context, typ CacheType, target string) (*LocalModelCache, error) { + item, err := i.store.First(ctx, map[string]interface{}{"target": target, "type": typ.Int()}) + if err != nil { + return nil, err + } + return &LocalModelCache{ + Model: item.Model, + Target: item.Target, + Type: CacheType(item.Type), + }, nil +} + func (i *imlLocalModelCacheService) List(ctx context.Context, model string, typ CacheType) ([]*LocalModelCache, error) { list, err := i.store.List(ctx, map[string]interface{}{"model": model, "type": typ.Int()}) if err != nil { diff --git a/service/ai-local/service.go b/service/ai-local/service.go index 260d3029..e32458ea 100644 --- a/service/ai-local/service.go +++ b/service/ai-local/service.go @@ -34,6 +34,7 @@ type ILocalModelCacheService interface { List(ctx context.Context, model string, typ CacheType) ([]*LocalModelCache, error) Delete(ctx context.Context, model string) error Save(ctx context.Context, model string, typ CacheType, target string) error + GetByTarget(ctx context.Context, typ CacheType, target string) (*LocalModelCache, error) } func init() { From 50faa4af80966e4a29db6e321cee8696fee9ed19 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Mon, 17 Feb 2025 17:21:48 +0800 Subject: [PATCH 3/7] fix: bug --- controller/ai-local/iml.go | 180 +++++++++++++++++++------------------ module/ai-local/iml.go | 12 ++- module/ai-local/module.go | 2 +- 3 files changed, 104 insertions(+), 90 deletions(-) diff --git a/controller/ai-local/iml.go b/controller/ai-local/iml.go index f6a4c825..1966bf92 100644 --- a/controller/ai-local/iml.go +++ b/controller/ai-local/iml.go @@ -6,6 +6,14 @@ import ( "fmt" "io" "math" + "net/http" + "strings" + + "github.com/APIParkLab/APIPark/model/plugin_model" + "github.com/APIParkLab/APIPark/service/api" + + ai_api_dto "github.com/APIParkLab/APIPark/module/ai-api/dto" + router_dto "github.com/APIParkLab/APIPark/module/router/dto" "github.com/APIParkLab/APIPark/module/router" @@ -163,12 +171,12 @@ func (i *imlLocalModelController) Deploy(ctx *gin.Context) { } func (i *imlLocalModelController) DeployStart(ctx *gin.Context, input *ai_local_dto.DeployInput) error { - err := i.initAILocalService(ctx, input.Model, input.Team) + fn, err := i.initAILocalService(ctx, input.Model, input.Team) if err != nil { return err } id := uuid.NewString() - _, err = i.module.Deploy(ctx, input.Model, id) + _, err = i.module.Deploy(ctx, input.Model, id, fn) if err != nil { return err } @@ -176,15 +184,15 @@ func (i *imlLocalModelController) DeployStart(ctx *gin.Context, input *ai_local_ return nil } -func (i *imlLocalModelController) initAILocalService(ctx context.Context, model string, teamID string) error { - err := i.transaction.Transaction(ctx, func(ctx context.Context) error { - catalogueInfo, err := i.catalogueModule.DefaultCatalogue(ctx) - if err != nil { - return err - } - serviceId := uuid.NewString() - prefix := fmt.Sprintf("/%s", serviceId[:8]) - providerId := "ollama" +func (i *imlLocalModelController) initAILocalService(ctx context.Context, model string, teamID string) (func() error, error) { + catalogueInfo, err := i.catalogueModule.DefaultCatalogue(ctx) + if err != nil { + return nil, err + } + serviceId := uuid.NewString() + prefix := fmt.Sprintf("/%s", serviceId[:8]) + providerId := "ollama" + err = i.transaction.Transaction(ctx, func(ctx context.Context) error { _, err = i.serviceModule.Create(ctx, teamID, &service_dto.CreateService{ Id: serviceId, Name: model, @@ -201,83 +209,83 @@ func (i *imlLocalModelController) initAILocalService(ctx context.Context, model return err } return i.module.SaveCache(ctx, model, serviceId) - - //path := fmt.Sprintf("/%s/chat", strings.Trim(prefix, "/")) - //timeout := 300000 - //retry := 0 - //aiPrompt := &ai_api_dto.AiPrompt{ - // Variables: []*ai_api_dto.AiPromptVariable{}, - // Prompt: "", - //} - //aiModel := &ai_api_dto.AiModel{ - // Id: model, - // Config: ai_provider_local.OllamaConfig, - // Provider: providerId, - // Type: "local", - //} - //name := "Demo AI API" - //description := "A demo that shows you how to use a e a Chat API." - //apiId := uuid.NewString() - //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: "", - //}) }) - return err + return func() error { + path := fmt.Sprintf("/%s/chat", strings.Trim(prefix, "/")) + timeout := 300000 + retry := 0 + aiPrompt := &ai_api_dto.AiPrompt{ + Variables: []*ai_api_dto.AiPromptVariable{}, + Prompt: "", + } + aiModel := &ai_api_dto.AiModel{ + Id: model, + Config: ai_provider_local.OllamaConfig, + Provider: providerId, + Type: "local", + } + name := "Demo AI API" + description := "A demo that shows you how to use a e a Chat API." + apiId := uuid.NewString() + err = i.aiAPIModule.Create( + ctx, + serviceId, + &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": providerId, + "config": aiModel.Config, + }, + } + _, err = i.routerModule.Create(ctx, serviceId, &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, serviceId, &service_dto.SaveServiceDoc{ + Doc: "", + }) + }, err } func (i *imlLocalModelController) Search(ctx *gin.Context, keyword string) ([]*ai_local_dto.LocalModelItem, error) { diff --git a/module/ai-local/iml.go b/module/ai-local/iml.go index da22e6b6..d3dcabeb 100644 --- a/module/ai-local/iml.go +++ b/module/ai-local/iml.go @@ -167,7 +167,7 @@ func (i *imlLocalModel) ListCanInstall(ctx context.Context, keyword string) ([]* } -func (i *imlLocalModel) pullHook() func(msg ai_provider_local.PullMessage) error { +func (i *imlLocalModel) pullHook(fn ...func() error) 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 { @@ -240,6 +240,12 @@ func (i *imlLocalModel) pullHook() func(msg ai_provider_local.PullMessage) error return err } if state == ai_local_dto.DeployStateFinish.Int() { + for _, f := range fn { + err = f() + if err != nil { + return err + } + } cfg := make(map[string]interface{}) cfg["provider"] = "ollama" cfg["model"] = msg.Model @@ -296,7 +302,7 @@ func (i *imlLocalModel) syncGateway(ctx context.Context, clusterId string, relea return nil } -func (i *imlLocalModel) Deploy(ctx context.Context, model string, session string) (*ai_provider_local.Pipeline, error) { +func (i *imlLocalModel) Deploy(ctx context.Context, model string, session string, fn ...func() error) (*ai_provider_local.Pipeline, error) { var p *ai_provider_local.Pipeline err := i.transaction.Transaction(ctx, func(txCtx context.Context) error { item, err := i.localModelCacheService.GetByTarget(ctx, ai_local.CacheTypeService, model) @@ -329,7 +335,7 @@ func (i *imlLocalModel) Deploy(ctx context.Context, model string, session string if err != nil { return err } - p, err = ai_provider_local.PullModel(model, session, i.pullHook()) + p, err = ai_provider_local.PullModel(model, session, i.pullHook(fn...)) if err != nil { return err } diff --git a/module/ai-local/module.go b/module/ai-local/module.go index 58362d16..38330029 100644 --- a/module/ai-local/module.go +++ b/module/ai-local/module.go @@ -16,7 +16,7 @@ import ( type ILocalModelModule interface { Search(ctx context.Context, keyword string) ([]*ai_local_dto.LocalModelItem, error) ListCanInstall(ctx context.Context, keyword string) ([]*ai_local_dto.LocalModelPackageItem, error) - Deploy(ctx context.Context, model string, session string) (*ai_provider_local.Pipeline, error) + Deploy(ctx context.Context, model string, session string, fn ...func() error) (*ai_provider_local.Pipeline, error) CancelDeploy(ctx context.Context, model string) error RemoveModel(ctx context.Context, model string) error Enable(ctx context.Context, model string) error From 4371715b32a409075609fbd9aa474de00a29cdeb Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Mon, 17 Feb 2025 18:08:29 +0800 Subject: [PATCH 4/7] init service consumer --- controller/ai-local/iml.go | 17 +++++++++++++++-- controller/service/iml.go | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/controller/ai-local/iml.go b/controller/ai-local/iml.go index 1966bf92..c46b4083 100644 --- a/controller/ai-local/iml.go +++ b/controller/ai-local/iml.go @@ -9,6 +9,9 @@ import ( "net/http" "strings" + "github.com/APIParkLab/APIPark/module/subscribe" + subscribe_dto "github.com/APIParkLab/APIPark/module/subscribe/dto" + "github.com/APIParkLab/APIPark/model/plugin_model" "github.com/APIParkLab/APIPark/service/api" @@ -44,7 +47,9 @@ type imlLocalModelController struct { serviceModule service.IServiceModule `autowired:""` catalogueModule catalogue.ICatalogueModule `autowired:""` aiAPIModule ai_api.IAPIModule `autowired:""` + appModule service.IAppModule `autowired:""` routerModule router.IRouterModule `autowired:""` + subscribeModule subscribe.ISubscribeModule `autowired:""` docModule service.IServiceDocModule `autowired:""` transaction store.ITransaction `autowired:""` } @@ -226,7 +231,7 @@ func (i *imlLocalModelController) initAILocalService(ctx context.Context, model Type: "local", } name := "Demo AI API" - description := "A demo that shows you how to use a e a Chat API." + description := "This is a demo that shows you how to use a Chat API." apiId := uuid.NewString() err = i.aiAPIModule.Create( ctx, @@ -281,7 +286,15 @@ func (i *imlLocalModelController) initAILocalService(ctx context.Context, model 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, serviceId, &subscribe_dto.AddSubscriber{ + Application: app.Id, + }) + } return i.docModule.SaveServiceDoc(ctx, serviceId, &service_dto.SaveServiceDoc{ Doc: "", }) diff --git a/controller/service/iml.go b/controller/service/iml.go index c21ecb88..310b5876 100644 --- a/controller/service/iml.go +++ b/controller/service/iml.go @@ -386,7 +386,7 @@ func (i *imlServiceController) createAIService(ctx *gin.Context, teamID string, Type: modelType, } name := "Demo AI API " - description := "A demo that shows you how to use Chat API." + description := "This is a demo that shows you how to use a Chat API." apiId := uuid.New().String() err = i.aiAPIModule.Create( ctx, From ecf259a9e77feb19bd1f3555d6e4736d6bd23565 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Mon, 17 Feb 2025 18:12:47 +0800 Subject: [PATCH 5/7] init service consumer --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 88137b31..d8314486 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ variables: VIEW_ADDR: http://172.18.166.219:8288 SAVE_DIR: /opt/${APP} NODE_OPTIONS: --max_old_space_size=8192 + APIPARK_OLLAMA_BASE: http://127.0.0.1:11434 stages: - notice From 3132d488133e5708e1a3f9ed137b6acf4b54e929 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Mon, 17 Feb 2025 18:31:05 +0800 Subject: [PATCH 6/7] update service list sort --- module/service/iml.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module/service/iml.go b/module/service/iml.go index a0eb81d5..60324a44 100644 --- a/module/service/iml.go +++ b/module/service/iml.go @@ -125,7 +125,7 @@ func (i *imlServiceModule) searchMyServices(ctx context.Context, teamId string, return nil, err } condition["team"] = teamId - return i.serviceService.Search(ctx, keyword, condition, "update_at desc") + return i.serviceService.Search(ctx, keyword, condition, "create_at desc") } else { membersForUser, err := i.teamMemberService.FilterMembersForUser(ctx, userID) if err != nil { @@ -133,7 +133,7 @@ func (i *imlServiceModule) searchMyServices(ctx context.Context, teamId string, } teamIds := membersForUser[userID] condition["team"] = teamIds - return i.serviceService.Search(ctx, keyword, condition, "update_at desc") + return i.serviceService.Search(ctx, keyword, condition, "create_at desc") } } @@ -235,9 +235,9 @@ func (i *imlServiceModule) Search(ctx context.Context, teamID string, keyword st if err != nil { return nil, err } - list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"team": teamID, "as_server": true}, "update_at desc") + list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"team": teamID, "as_server": true}, "create_at desc") } else { - list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"as_server": true}, "update_at desc") + list, err = i.serviceService.Search(ctx, keyword, map[string]interface{}{"as_server": true}, "create_at desc") } if err != nil { return nil, err From 1011302721e1e2e47f6adfe2105aae774e2fbb2c Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Tue, 18 Feb 2025 10:20:33 +0800 Subject: [PATCH 7/7] fix: cancel deploy error --- go.mod | 5 ++--- module/ai-local/iml.go | 9 +++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e5baca0e..d7878223 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,6 @@ go 1.23.4 toolchain go1.23.6 -//toolchain go1.21.1 - require ( github.com/eolinker/ap-account v1.0.15 github.com/eolinker/eosc v0.18.3 @@ -83,6 +81,7 @@ require ( // github.com/eolinker/eosc => ../../eolinker/eosc //) -//replace github.com/eolinker/ap-account => ../aoaccount +//replace github.com/eolinker/ap-account => ../../eolinker/ap-account + // //replace github.com/eolinker/go-common => ../../eolinker/go-common diff --git a/module/ai-local/iml.go b/module/ai-local/iml.go index d3dcabeb..913c8ef5 100644 --- a/module/ai-local/iml.go +++ b/module/ai-local/iml.go @@ -354,6 +354,15 @@ func (i *imlLocalModel) SaveCache(ctx context.Context, model string, target stri func (i *imlLocalModel) CancelDeploy(ctx context.Context, model string) error { return i.transaction.Transaction(ctx, func(txCtx context.Context) error { + item, err := i.localModelCacheService.GetByTarget(ctx, ai_local.CacheTypeService, model) + if err != nil { + if !errors.Is(err, gorm.ErrRecordNotFound) { + return err + } + + } else { + model = item.Model + } list, err := i.localModelCacheService.List(ctx, model, ai_local.CacheTypeService) if err != nil { return err