修复bug

This commit is contained in:
Liujian
2024-09-29 14:46:58 +08:00
parent 1c71a0b226
commit 9a2ba0943c
10 changed files with 200 additions and 44 deletions
+4 -5
View File
@@ -2,15 +2,14 @@ package model_runtime
import (
"embed"
"errors"
"fmt"
"github.com/eolinker/eosc"
"strings"
)
var (
ErrInvalidAPIKey = errors.New("invalid api key")
)
func init() {
Load()
}
type IConfig interface {
Check(cfg string) error
@@ -87,7 +86,7 @@ func ReadFile(dir embed.FS, name string) (eosc.Untyped[string, string], error) {
if file.IsDir() {
continue
}
if !strings.HasSuffix(file.Name(), ".yaml") {
if !strings.HasSuffix(file.Name(), ".yaml") && !strings.HasSuffix(file.Name(), ".svg") {
continue
}
data, err := dir.ReadFile(fmt.Sprintf("%s/%s", name, file.Name()))
+1 -1
View File
@@ -107,7 +107,7 @@ func NewModel(data string, logo string) (IModel, error) {
Required: p.Required,
})
}
dCfg, err := json.Marshal(defaultConfig)
dCfg, err := json.MarshalIndent(defaultConfig, "", " ")
if err != nil {
return nil, err
}
+3 -2
View File
@@ -68,7 +68,7 @@ func NewProvider(providerData string, modelContents map[string]eosc.Untyped[stri
}
defaultCfg[v.Variable] = v.Label[entity.LanguageEnglish]
}
defaultCfgByte, _ := json.Marshal(defaultCfg)
defaultCfgByte, _ := json.MarshalIndent(defaultCfg, "", " ")
provider.defaultConfig = string(defaultCfgByte)
provider.paramValidator = params
for name, f := range modelContents {
@@ -86,6 +86,7 @@ func NewProvider(providerData string, modelContents map[string]eosc.Untyped[stri
if model.ID() == defaultModel {
provider.SetDefaultModel(name, model)
}
models = append(models, model)
}
provider.SetModelsByType(name, models)
}
@@ -158,7 +159,7 @@ func (p *Provider) MaskConfig(cfg string) string {
}
for _, key := range p.maskKeys {
if v, ok := data[key]; ok {
data[key] = PartialMasking(v, 0, -1)
data[key] = PartialMasking(v, 4, -1)
}
}
result, _ := json.Marshal(data)
+62 -3
View File
@@ -1,9 +1,15 @@
package service
import (
"fmt"
"github.com/APIParkLab/APIPark/module/ai"
ai_api "github.com/APIParkLab/APIPark/module/ai-api"
ai_api_dto "github.com/APIParkLab/APIPark/module/ai-api/dto"
"github.com/APIParkLab/APIPark/module/service"
service_dto "github.com/APIParkLab/APIPark/module/service/dto"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"strings"
)
var (
@@ -13,14 +19,67 @@ var (
)
type imlServiceController struct {
module service.IServiceModule `autowired:""`
docModule service.IServiceDocModule `autowired:""`
module service.IServiceModule `autowired:""`
docModule service.IServiceDocModule `autowired:""`
aiAPIModule ai_api.IAPIModule `autowired:""`
providerModule ai.IProviderModule `autowired:""`
}
func (i *imlServiceController) CreateAIService(ctx *gin.Context, teamID string, input *service_dto.CreateService) (*service_dto.Service, error) {
kind := "ai"
input.Kind = &kind
return i.module.Create(ctx, teamID, input)
if input.Provider == nil {
return nil, fmt.Errorf("provider is required")
}
p, err := i.providerModule.Provider(ctx, *input.Provider)
if err != nil {
return nil, err
}
if input.Id == "" {
input.Id = uuid.New().String()
}
if input.Prefix == "" {
if len(input.Id) < 9 {
input.Prefix = input.Id
} else {
input.Prefix = input.Id[:8]
}
}
info, err := i.module.Create(ctx, teamID, input)
if err != nil {
return nil, err
}
_, err = i.aiAPIModule.Create(
ctx,
info.Id,
&ai_api_dto.CreateAPI{
Name: "Default API",
Path: fmt.Sprintf("/%s", strings.Trim(input.Prefix, "/")),
Description: "Default API for service",
Disable: false,
AiPrompt: &ai_api_dto.AiPrompt{
Variables: []*ai_api_dto.AiPromptVariable{
{
Key: "Query",
Description: "",
Require: true,
},
},
Prompt: "{{Query}}",
},
AiModel: &ai_api_dto.AiModel{
Id: p.DefaultLLM,
Config: p.DefaultLLMConfig,
},
Timeout: 300000,
Retry: 0,
},
)
if err != nil {
i.module.Delete(ctx, info.Id, "ai")
return nil, err
}
return info, nil
}
func (i *imlServiceController) DeleteAIService(ctx *gin.Context, id string) error {
+66 -2
View File
@@ -8,6 +8,7 @@ import (
model_runtime "github.com/APIParkLab/APIPark/ai-provider/model-runtime"
ai_api_dto "github.com/APIParkLab/APIPark/module/ai-api/dto"
ai_api "github.com/APIParkLab/APIPark/service/ai-api"
"github.com/APIParkLab/APIPark/service/api"
api_doc "github.com/APIParkLab/APIPark/service/api-doc"
"github.com/APIParkLab/APIPark/service/service"
"github.com/eolinker/go-common/auto"
@@ -17,6 +18,7 @@ import (
"github.com/google/uuid"
"gorm.io/gorm"
"net/http"
"strings"
)
var _ IAPIModule = (*imlAPIModule)(nil)
@@ -29,6 +31,7 @@ type imlAPIModule struct {
serviceService service.IServiceService `autowired:""`
apiDocService api_doc.IAPIDocService `autowired:""`
aiAPIService ai_api.IAPIService `autowired:""`
apiService api.IAPIService `autowired:""`
transaction store.ITransaction `autowired:""`
}
@@ -95,7 +98,30 @@ func (i *imlAPIModule) Create(ctx context.Context, serviceId string, input *ai_a
input.Id = uuid.New().String()
}
err = i.transaction.Transaction(ctx, func(txCtx context.Context) error {
err := i.updateAPIDoc(ctx, serviceId, input.Path, input.Description, input.AiPrompt)
err = i.apiService.Exist(ctx, "", &api.Exist{Path: input.Path, Methods: []string{http.MethodPost}})
if err != nil {
return err
}
err = i.apiService.Create(ctx, &api.Create{
UUID: input.Id,
Description: input.Description,
Service: serviceId,
Team: info.Team,
Methods: []string{
http.MethodPost,
},
Protocols: []string{
"http",
"https",
},
Disable: false,
Path: input.Path,
Match: "{}",
})
if err != nil {
return err
}
err = i.updateAPIDoc(ctx, serviceId, input.Path, input.Description, input.AiPrompt)
if err != nil {
return err
}
@@ -137,6 +163,26 @@ func (i *imlAPIModule) Edit(ctx context.Context, serviceId string, apiId string,
}
if input.Path != nil {
apiInfo.Path = *input.Path
prefix, err := i.Prefix(ctx, serviceId)
if err != nil {
return err
}
if !strings.HasSuffix(apiInfo.Path, prefix) {
if apiInfo.Path[0] != '/' {
apiInfo.Path = fmt.Sprintf("/%s", apiInfo.Path)
}
apiInfo.Path = fmt.Sprintf("%s%s", prefix, apiInfo.Path)
err := i.apiService.Exist(ctx, apiId, &api.Exist{Path: apiInfo.Path, Methods: []string{http.MethodPost}})
if err != nil {
return err
}
err = i.apiService.Save(ctx, apiId, &api.Edit{
Path: &apiInfo.Path,
})
if err != nil {
return err
}
}
}
if input.Description != nil {
apiInfo.Description = *input.Description
@@ -181,7 +227,11 @@ func (i *imlAPIModule) Delete(ctx context.Context, serviceId string, apiId strin
return fmt.Errorf("service kind is not ai service")
}
return i.transaction.Transaction(ctx, func(txCtx context.Context) error {
err = i.deleteAPIDoc(ctx, serviceId, apiId)
apiInfo, err := i.aiAPIService.Get(ctx, apiId)
if err != nil {
return err
}
err = i.deleteAPIDoc(ctx, serviceId, apiInfo.Path)
if err != nil {
return err
}
@@ -276,3 +326,17 @@ func ConvertStruct[T any](data interface{}) (*T, error) {
}
return &t, nil
}
func (i *imlAPIModule) Prefix(ctx context.Context, serviceId string) (string, error) {
pInfo, err := i.serviceService.Check(ctx, serviceId, map[string]bool{"as_server": true})
if err != nil {
return "", err
}
if pInfo.Prefix != "" {
if pInfo.Prefix[0] != '/' {
pInfo.Prefix = fmt.Sprintf("/%s", strings.TrimSuffix(pInfo.Prefix, "/"))
}
}
return strings.TrimSuffix(pInfo.Prefix, "/"), nil
}
+1
View File
@@ -51,6 +51,7 @@ func genRequestBodySchema(variables []*ai_api_dto.AiPromptVariable) *openapi3.Sc
required := make([]string, 0, len(variables))
for _, v := range variables {
val := openapi3.NewStringSchema()
val.Example = ""
val.Description = v.Description
if v.Require {
required = append(required, v.Key)
+15 -10
View File
@@ -1,19 +1,24 @@
package ai_dto
import "time"
type Provider struct {
Id string `json:"id"`
Name string `json:"name"`
Config string `json:"config"`
GetAPIKeyUrl string `json:"get_apikey_url"`
Id string `json:"id"`
Name string `json:"name"`
Config string `json:"config"`
GetAPIKeyUrl string `json:"get_apikey_url"`
DefaultLLM string `json:"-"`
DefaultLLMConfig string `json:"-"`
}
type ProviderItem struct {
Id string `json:"id"`
Name string `json:"name"`
DefaultLLM string `json:"default_llm"`
DefaultLLMLogo string `json:"default_llm_logo"`
Logo string `json:"logo"`
Configured bool `json:"configured"`
Id string `json:"id"`
Name string `json:"name"`
DefaultLLM string `json:"default_llm"`
DefaultLLMLogo string `json:"default_llm_logo"`
Logo string `json:"logo"`
Configured bool `json:"configured"`
UpdateTime time.Time `json:"-"`
}
type SimpleProviderItem struct {
+39 -21
View File
@@ -9,6 +9,7 @@ import (
"github.com/APIParkLab/APIPark/service/ai"
"github.com/eolinker/go-common/utils"
"gorm.io/gorm"
"sort"
)
var _ IProviderModule = (*imlProviderModule)(nil)
@@ -58,17 +59,22 @@ func (i *imlProviderModule) Providers(ctx context.Context) ([]*ai_dto.ProviderIt
continue
}
item := &ai_dto.ProviderItem{
Id: v.ID(),
Name: v.Name(),
Logo: v.Logo(),
DefaultLLM: defaultLLM.ID(),
DefaultLLMLogo: defaultLLM.Logo(),
Id: v.ID(),
Name: v.Name(),
Logo: v.Logo(),
}
if _, has = providerMap[v.ID()]; has {
if info, has := providerMap[v.ID()]; has {
item.Configured = true
item.DefaultLLM = defaultLLM.ID()
item.DefaultLLMLogo = defaultLLM.Logo()
item.UpdateTime = info.UpdateAt
}
items = append(items, item)
}
sort.SliceIsSorted(items, func(i, j int) bool {
return items[i].UpdateTime.After(items[j].UpdateTime)
})
return items, nil
}
@@ -82,19 +88,30 @@ func (i *imlProviderModule) Provider(ctx context.Context, id string) (*ai_dto.Pr
if !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, err
}
defaultLLM, has := p.DefaultModel(model_runtime.ModelTypeLLM)
if !has {
return nil, fmt.Errorf("ai provider llm not found")
}
return &ai_dto.Provider{
Id: p.ID(),
Name: p.Name(),
Config: p.DefaultConfig(),
GetAPIKeyUrl: p.HelpUrl(),
Id: p.ID(),
Name: p.Name(),
Config: p.DefaultConfig(),
GetAPIKeyUrl: p.HelpUrl(),
DefaultLLM: defaultLLM.ID(),
DefaultLLMConfig: defaultLLM.Logo(),
}, nil
}
defaultLLM, has := p.GetModel(info.DefaultLLM)
if !has {
return nil, fmt.Errorf("ai provider llm not found")
}
return &ai_dto.Provider{
Id: info.Id,
Name: info.Name,
Config: p.MaskConfig(info.Config),
GetAPIKeyUrl: p.HelpUrl(),
Id: info.Id,
Name: info.Name,
Config: p.MaskConfig(info.Config),
GetAPIKeyUrl: p.HelpUrl(),
DefaultLLM: defaultLLM.ID(),
DefaultLLMConfig: defaultLLM.DefaultConfig(),
}, nil
}
@@ -114,7 +131,7 @@ func (i *imlProviderModule) LLMs(ctx context.Context, driver string) ([]*ai_dto.
items = append(items, &ai_dto.LLMItem{
Id: v.ID(),
Logo: v.Logo(),
Config: p.DefaultConfig(),
Config: v.DefaultConfig(),
Scopes: []string{
"chat",
},
@@ -130,11 +147,12 @@ func (i *imlProviderModule) LLMs(ctx context.Context, driver string) ([]*ai_dto.
return nil, nil, fmt.Errorf("ai provider default llm not found")
}
return items, &ai_dto.ProviderItem{
Id: p.ID(),
Name: p.Name(),
DefaultLLM: defaultLLM.ID(),
Logo: p.Logo(),
Configured: false,
Id: p.ID(),
Name: p.Name(),
DefaultLLM: defaultLLM.ID(),
DefaultLLMLogo: defaultLLM.Logo(),
Logo: p.Logo(),
Configured: false,
}, err
}
+7
View File
@@ -261,6 +261,7 @@ func (i *imlRouterModule) Create(ctx context.Context, serviceId string, dto *rou
Service: serviceId,
Team: info.Team,
Methods: dto.Methods,
Protocols: dto.Protocols,
Path: path,
Match: string(match),
})
@@ -278,6 +279,12 @@ func (i *imlRouterModule) Edit(ctx context.Context, serviceId string, apiId stri
}
err = i.transaction.Transaction(ctx, func(ctx context.Context) error {
if dto.Path != nil {
err = i.apiService.Exist(ctx, "", &api.Exist{Path: *dto.Path, Methods: *dto.Methods})
if err != nil {
return err
}
}
if dto.Proxy != nil {
err = i.apiService.SaveProxy(ctx, apiId, router_dto.ToServiceProxy(dto.Proxy))
if err != nil {
+2
View File
@@ -71,6 +71,8 @@ func FromEntityInfo(e *api.Info) *Info {
}
}
type Kind string
type Create struct {
UUID string
Description string