From 15f803a5113088602950aa4a8c3f4a88cfe6d95b Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Fri, 14 Mar 2025 15:51:33 +0800 Subject: [PATCH 1/4] fix bug --- .../model-providers/bailian/bailian.yaml | 2 +- controller/system/iml.go | 42 +++++++++---------- module/ai-balance/iml.go | 10 ++++- module/ai-local/iml.go | 3 +- module/service/iml.go | 2 +- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/ai-provider/model-runtime/model-providers/bailian/bailian.yaml b/ai-provider/model-runtime/model-providers/bailian/bailian.yaml index 9b213760..93bd6a02 100644 --- a/ai-provider/model-runtime/model-providers/bailian/bailian.yaml +++ b/ai-provider/model-runtime/model-providers/bailian/bailian.yaml @@ -1,7 +1,7 @@ provider: bailian label: zh_Hans: 阿里云百炼 - en_US: bailian + en_US: BaiLian icon_small: en_US: icon_s_en.svg icon_large: diff --git a/controller/system/iml.go b/controller/system/iml.go index 44f9e37e..749e73b0 100644 --- a/controller/system/iml.go +++ b/controller/system/iml.go @@ -395,36 +395,36 @@ func (i *imlInitController) createAIService(ctx context.Context, teamID string, if err != nil { return err } - path := fmt.Sprintf("/%s/demo_translation_api", strings.Trim(input.Prefix, "/")) + path := fmt.Sprintf("/%s/chat/completions", strings.Trim(input.Prefix, "/")) timeout := 300000 retry := 0 aiPrompt := &ai_api_dto.AiPrompt{ - Variables: []*ai_api_dto.AiPromptVariable{ - { - Key: "source_lang", - Description: "", - Require: true, - }, - { - Key: "target_lang", - Description: "", - Require: true, - }, - { - Key: "text", - Description: "", - Require: true, - }, - }, - Prompt: "You need to translate {{source_lang}} into {{target_lang}}, and the following is the content that needs to be translated.\n---\n{{text}}", + //Variables: []*ai_api_dto.AiPromptVariable{ + // { + // Key: "source_lang", + // Description: "", + // Require: true, + // }, + // { + // Key: "target_lang", + // Description: "", + // Require: true, + // }, + // { + // Key: "text", + // Description: "", + // Require: true, + // }, + //}, + //Prompt: "You need to translate {{source_lang}} into {{target_lang}}, and the following is the content that needs to be translated.\n---\n{{text}}", } aiModel := &ai_api_dto.AiModel{ Id: m.ID(), Config: m.DefaultConfig(), Provider: providerId, } - name := "Demo Translation API" - description := "A demo that shows you how to use a prompt to create a Translation API." + name := "Demo Chat API" + description := "A demo that shows you how to use a prompt to create a Chat API." apiId := uuid.New().String() err = i.aiAPIModule.Create( ctx, diff --git a/module/ai-balance/iml.go b/module/ai-balance/iml.go index 81d0c655..aab4c9a0 100644 --- a/module/ai-balance/iml.go +++ b/module/ai-balance/iml.go @@ -268,7 +268,8 @@ func (i *imlBalanceModule) getLocalBalances(ctx context.Context, v string) ([]*g var has bool v, has = i.settingService.Get(ctx, "system.ai_model.ollama_address") if !has { - return nil, fmt.Errorf("ollama address not found") + //return nil, fmt.Errorf("ollama address not found") + return nil, nil } } @@ -294,7 +295,8 @@ func (i *imlBalanceModule) getBalances(ctx context.Context) ([]*gateway.DynamicR } v, has := i.settingService.Get(ctx, "system.ai_model.ollama_address") if !has { - return nil, fmt.Errorf("ollama address not found") + //return nil, fmt.Errorf("ollama address not found") + return nil, nil } releases := make([]*gateway.DynamicRelease, 0, len(balances)) for _, item := range balances { @@ -305,6 +307,10 @@ func (i *imlBalanceModule) getBalances(ctx context.Context) ([]*gateway.DynamicR continue } base = fmt.Sprintf("%s://%s%s", p.URI().Scheme(), p.URI().Host(), p.URI().Path()) + } else { + if v == "" { + continue + } } releases = append(releases, newRelease(item, base)) } diff --git a/module/ai-local/iml.go b/module/ai-local/iml.go index 3547c84b..c61d3977 100644 --- a/module/ai-local/iml.go +++ b/module/ai-local/iml.go @@ -614,7 +614,8 @@ func (i *imlLocalModel) getLocalModels(ctx context.Context, v string) ([]*gatewa var has bool v, has = i.settingService.Get(ctx, "system.ai_model.ollama_address") if !has { - return nil, errors.New("ollama_address not set") + //return nil, errors.New("ollama_address not set") + return nil, nil } } provider := ai_provider_local.ProviderLocal diff --git a/module/service/iml.go b/module/service/iml.go index 841e2a09..636b7515 100644 --- a/module/service/iml.go +++ b/module/service/iml.go @@ -473,7 +473,7 @@ func (i *imlServiceModule) Edit(ctx context.Context, id string, input *service_d } } - if input.ModelMapping != nil { + if input.ModelMapping != nil && *input.ModelMapping != "" { m := make(map[string]string) err = json.Unmarshal([]byte(*input.ModelMapping), &m) if err != nil { From da85269c9f18e802c892588606b978dd62cb5e57 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Fri, 14 Mar 2025 18:02:28 +0800 Subject: [PATCH 2/4] Add supplier differentiation, custom or built-in --- app/ai-event-handler/nsq.go | 2 +- module/ai/dto/input.go | 1 + module/ai/iml.go | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/ai-event-handler/nsq.go b/app/ai-event-handler/nsq.go index 3f891490..be133e6e 100644 --- a/app/ai-event-handler/nsq.go +++ b/app/ai-event-handler/nsq.go @@ -81,7 +81,7 @@ func convertInt(value interface{}) int { func genAIKey(key string, provider string) string { keys := strings.Split(key, "@") - return strings.TrimSuffix(keys[0], fmt.Sprintf("-%s", provider)) + return strings.TrimPrefix(keys[0], fmt.Sprintf("%s-", provider)) } // HandleMessage 处理从 NSQ 读取的消息 diff --git a/module/ai/dto/input.go b/module/ai/dto/input.go index adeb7286..45f8468f 100644 --- a/module/ai/dto/input.go +++ b/module/ai/dto/input.go @@ -17,4 +17,5 @@ type Sort struct { type NewProvider struct { Name string `json:"name"` + Type string `json:"type"` } diff --git a/module/ai/iml.go b/module/ai/iml.go index d92682d4..f09c8be5 100644 --- a/module/ai/iml.go +++ b/module/ai/iml.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "sort" + "strings" "time" ai_model "github.com/APIParkLab/APIPark/service/ai-model" @@ -200,6 +201,13 @@ func (i *imlProviderModule) Delete(ctx context.Context, id string) error { } func (i *imlProviderModule) AddProvider(ctx context.Context, input *ai_dto.NewProvider) (*ai_dto.SimpleProvider, error) { + switch input.Type { + case "customize": + _, has := model_runtime.GetProvider(strings.ToLower(input.Name)) + if has { + return nil, fmt.Errorf("provider `%s` duplicate", input.Name) + } + } // uuid = name if has := i.providerService.CheckUuidDuplicate(ctx, input.Name); has { return nil, fmt.Errorf("provider `%s` duplicate", input.Name) From 1564bd977ec52f8b055f48685f27e5b8e623b416 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Fri, 14 Mar 2025 19:13:58 +0800 Subject: [PATCH 3/4] Fix the issue of duplicate custom suppliers and built-in suppliers --- controller/ai-local/iml.go | 2 +- module/ai-api/schema.go | 20 ++++++++++++++++++++ module/ai/dto/input.go | 1 - module/ai/iml.go | 11 ++++------- module/service/iml.go | 33 +++++++++++++++++++++++++++------ 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/controller/ai-local/iml.go b/controller/ai-local/iml.go index f2c13487..a34d4a9b 100644 --- a/controller/ai-local/iml.go +++ b/controller/ai-local/iml.go @@ -267,7 +267,7 @@ func (i *imlLocalModelController) initAILocalService(ctx context.Context, model }) return func() error { - path := fmt.Sprintf("/%s/chat", strings.Trim(prefix, "/")) + path := fmt.Sprintf("/%s/chat/completions", strings.Trim(prefix, "/")) timeout := 300000 retry := 0 aiPrompt := &ai_api_dto.AiPrompt{ diff --git a/module/ai-api/schema.go b/module/ai-api/schema.go index 5c7c7c5c..b510f044 100644 --- a/module/ai-api/schema.go +++ b/module/ai-api/schema.go @@ -23,12 +23,32 @@ func genOperation(summary string, description string, variables []*ai_api_dto.Ai operation := openapi3.NewOperation() operation.Summary = summary operation.Description = description + operation.AddParameter(&openapi3.Parameter{ + Name: "Authorization", + In: "header", + Required: true, + Example: "Bearer {your_apipark_apikey}", + }) operation.RequestBody = genRequestBody(variables) operation.Responses = &openapi3.Responses{} operation.Responses.Set("200", genResponse()) return operation } +func genRequestHeaders() openapi3.Parameters { + return openapi3.Parameters{ + { + Value: &openapi3.Parameter{ + Name: "Authorization", + In: "header", + Description: "your_apipark_apikey", // 替换Prompt的变量列表 + Required: true, + Example: "your_apipark_apikey", + }, + }, + } +} + func genRequestParameters(variables []*ai_api_dto.AiPromptVariable) openapi3.Parameters { return openapi3.Parameters{ { diff --git a/module/ai/dto/input.go b/module/ai/dto/input.go index 45f8468f..adeb7286 100644 --- a/module/ai/dto/input.go +++ b/module/ai/dto/input.go @@ -17,5 +17,4 @@ type Sort struct { type NewProvider struct { Name string `json:"name"` - Type string `json:"type"` } diff --git a/module/ai/iml.go b/module/ai/iml.go index f09c8be5..d3d9b535 100644 --- a/module/ai/iml.go +++ b/module/ai/iml.go @@ -201,12 +201,9 @@ func (i *imlProviderModule) Delete(ctx context.Context, id string) error { } func (i *imlProviderModule) AddProvider(ctx context.Context, input *ai_dto.NewProvider) (*ai_dto.SimpleProvider, error) { - switch input.Type { - case "customize": - _, has := model_runtime.GetProvider(strings.ToLower(input.Name)) - if has { - return nil, fmt.Errorf("provider `%s` duplicate", input.Name) - } + _, has := model_runtime.GetProvider(strings.ToLower(input.Name)) + if has { + return nil, fmt.Errorf("provider `%s` duplicate", input.Name) } // uuid = name if has := i.providerService.CheckUuidDuplicate(ctx, input.Name); has { @@ -249,7 +246,7 @@ func (i *imlProviderModule) SimpleProvider(ctx context.Context, id string) (*ai_ func (i *imlProviderModule) ConfiguredProviders(ctx context.Context, keyword string) ([]*ai_dto.ConfiguredProviderItem, error) { // 获取已配置的AI服务商 - list, err := i.providerService.Search(ctx, keyword, nil, "update_at") + list, err := i.providerService.Search(ctx, keyword, nil, "update_at desc") if err != nil { return nil, fmt.Errorf("get provider list error:%v", err) } diff --git a/module/service/iml.go b/module/service/iml.go index 636b7515..5da979b2 100644 --- a/module/service/iml.go +++ b/module/service/iml.go @@ -396,15 +396,36 @@ func (i *imlServiceModule) Create(ctx context.Context, teamID string, input *ser } } } - - err := i.serviceModelMappingService.Save(ctx, &service_model_mapping.Save{ - Sid: input.Id, - Content: input.ModelMapping, - }) + err := i.serviceService.Create(ctx, mo) if err != nil { return err } - return i.serviceService.Create(ctx, mo) + if input.ModelMapping != "" { + m := make(map[string]string) + err = json.Unmarshal([]byte(input.ModelMapping), &m) + if err != nil { + return err + } + err = i.serviceModelMappingService.Save(ctx, &service_model_mapping.Save{ + Sid: input.Id, + Content: input.ModelMapping, + }) + if err != nil { + return err + } + client, err := i.clusterService.GatewayClient(ctx, cluster.DefaultClusterID) + if err != nil { + return err + } + err = client.Hash().Online(ctx, &gateway.HashRelease{ + HashKey: fmt.Sprintf("%s:%s", gateway.KeyServiceMapping, input.Id), + HashMap: m, + }) + if err != nil { + return err + } + } + return nil }) if err != nil { return nil, err From 2574b2814bf9a8785ba1becf6bc162c5587e88d2 Mon Sep 17 00:00:00 2001 From: Liujian <824010343@qq.com> Date: Fri, 14 Mar 2025 19:16:31 +0800 Subject: [PATCH 4/4] update ai api schema --- module/ai-api/schema.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/ai-api/schema.go b/module/ai-api/schema.go index b510f044..fc69b83c 100644 --- a/module/ai-api/schema.go +++ b/module/ai-api/schema.go @@ -27,7 +27,7 @@ func genOperation(summary string, description string, variables []*ai_api_dto.Ai Name: "Authorization", In: "header", Required: true, - Example: "Bearer {your_apipark_apikey}", + Example: "{your_apipark_apikey}", }) operation.RequestBody = genRequestBody(variables) operation.Responses = &openapi3.Responses{}